feat(cli): add command to show qr code (#2518)

* refactor cli, add commands

* add docs

* improve

* fix ec mode order
This commit is contained in:
Bernd Storath
2026-03-05 11:53:27 +01:00
committed by GitHub
parent 47f81dd66a
commit 5228734c98
10 changed files with 292 additions and 94 deletions
+1 -19
View File
@@ -1,6 +1,5 @@
import fs from 'node:fs/promises';
import debug from 'debug';
import { encodeQR } from 'qr';
import type { InterfaceType } from '#db/repositories/interface/types';
const WG_DEBUG = debug('WireGuard');
@@ -181,24 +180,7 @@ class WireGuard {
async getClientQRCodeSVG({ clientId }: { clientId: ID }) {
const config = await this.getClientConfiguration({ clientId });
const ECMode = ['high', 'quartile', 'medium', 'low'] as const;
for (const ecc of ECMode) {
try {
return encodeQR(config, 'svg', {
ecc,
scale: 2,
encoding: 'byte',
});
} catch (err) {
if (!(err instanceof Error && err.message === 'Capacity overflow')) {
throw err;
}
// retry with lower ecc
}
}
throw new Error(
'Failed to generate QR code: Capacity overflow at all ECC levels'
);
return encodeQRCode(config);
}
cleanClientFilename(name: string): string {
+41
View File
@@ -0,0 +1,41 @@
// ! Auto Imports are not supported in this file
import type { ErrorCorrection } from 'qr';
import { encodeQR } from 'qr';
export function encodeQRCode(config: string): string {
return tryECCModes((ecc) => {
return encodeQR(config, 'svg', {
ecc,
scale: 2,
encoding: 'byte',
});
});
}
export function encodeQRCodeTerm(config: string): string {
return tryECCModes((ecc) => {
return encodeQR(config, 'term', {
ecc,
encoding: 'byte',
});
});
}
function tryECCModes<T>(callback: (ecc: ErrorCorrection) => T): T {
// defined manually, as qr's ECMode is in wrong order
const ECMode = ['high', 'quartile', 'medium', 'low'] as const;
for (const ecc of ECMode) {
try {
return callback(ecc);
} catch (err) {
if (!(err instanceof Error && err.message === 'Capacity overflow')) {
throw err;
}
// retry with lower ecc
}
}
throw new Error(
'Failed to generate QR code: Capacity overflow at all ECC levels'
);
}
+3 -1
View File
@@ -9,7 +9,9 @@ type Options = {
enableIpv6?: boolean;
};
const wgExecutable = WG_ENV.WG_EXECUTABLE;
// needed to support cli
const wgExecutable =
typeof WG_ENV !== 'undefined' ? WG_ENV.WG_EXECUTABLE : 'dev';
export const wg = {
generateServerPeer: (