@mostajs/qrpanel 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +159 -45
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +70 -0
- package/dist/cli.js.map +1 -0
- package/dist/composer.d.ts +43 -0
- package/dist/composer.d.ts.map +1 -0
- package/dist/composer.js +123 -0
- package/dist/composer.js.map +1 -0
- package/dist/config.d.ts +62 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +113 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +36 -21
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +88 -30
- package/dist/server.js.map +1 -1
- package/dist/themes.d.ts +55 -0
- package/dist/themes.d.ts.map +1 -0
- package/dist/themes.js +189 -0
- package/dist/themes.js.map +1 -0
- package/package.json +22 -5
package/dist/config.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// @mostajs/qrpanel/config — runtime config layer
|
|
2
|
+
// Author: Dr Hamid MADANI <drmdh@msn.com>
|
|
3
|
+
//
|
|
4
|
+
// Cascade :
|
|
5
|
+
// 1. defaults compilés (ce fichier)
|
|
6
|
+
// 2. .qrconfig.json (ou .qrconfig.js / .qrconfig) à process.cwd()
|
|
7
|
+
// 3. options passées explicitement à l'appel generateQr* (highest)
|
|
8
|
+
//
|
|
9
|
+
// Cache : la lecture du fichier est cachée en mémoire avec invalidation
|
|
10
|
+
// par mtime — édite le fichier, le prochain appel le relit. Pas de
|
|
11
|
+
// watcher (overkill pour ce cas d'usage).
|
|
12
|
+
import { readFileSync, existsSync, statSync, writeFileSync } from 'node:fs';
|
|
13
|
+
import { join, resolve } from 'node:path';
|
|
14
|
+
// ─── Defaults ──────────────────────────────────────────────────────
|
|
15
|
+
export const DEFAULT_CONFIG = {
|
|
16
|
+
default: {
|
|
17
|
+
genimage: true,
|
|
18
|
+
format: 'svg',
|
|
19
|
+
width: 600,
|
|
20
|
+
margin: 2,
|
|
21
|
+
errorCorrectionLevel: 'H',
|
|
22
|
+
darkColor: '#0f172a',
|
|
23
|
+
lightColor: '#ffffff',
|
|
24
|
+
theme: 'random',
|
|
25
|
+
themePool: [
|
|
26
|
+
'baby', 'animals', 'science', 'physics', 'chemistry', 'math',
|
|
27
|
+
'nature', 'tech', 'space', 'music', 'book', 'health',
|
|
28
|
+
],
|
|
29
|
+
framePadding: 0.5,
|
|
30
|
+
centerWhiteRatio: 0.62,
|
|
31
|
+
themeOpacity: 1.0,
|
|
32
|
+
themeColor: '#1e293b',
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
// ─── Lookup file paths ─────────────────────────────────────────────
|
|
36
|
+
const CONFIG_FILES = ['.qrconfig.json', '.qrconfig.js', '.qrconfig'];
|
|
37
|
+
/** Cherche le fichier config existant à `cwd`, retourne le path absolu ou null. */
|
|
38
|
+
function findConfigFile(cwd) {
|
|
39
|
+
for (const name of CONFIG_FILES) {
|
|
40
|
+
const p = join(cwd, name);
|
|
41
|
+
if (existsSync(p))
|
|
42
|
+
return p;
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
const _cache = new Map();
|
|
47
|
+
// ─── Readers ───────────────────────────────────────────────────────
|
|
48
|
+
/**
|
|
49
|
+
* Lit la config depuis `cwd` (default `process.cwd()`).
|
|
50
|
+
* Retourne `DEFAULT_CONFIG` si aucun fichier trouvé.
|
|
51
|
+
* Cache invalidé par mtime du fichier.
|
|
52
|
+
*/
|
|
53
|
+
export function loadQrConfig(cwd = process.cwd()) {
|
|
54
|
+
const path = findConfigFile(cwd);
|
|
55
|
+
if (!path)
|
|
56
|
+
return DEFAULT_CONFIG;
|
|
57
|
+
const stat = statSync(path);
|
|
58
|
+
const cached = _cache.get(path);
|
|
59
|
+
if (cached && cached.mtimeMs === stat.mtimeMs) {
|
|
60
|
+
return cached.config;
|
|
61
|
+
}
|
|
62
|
+
let parsed;
|
|
63
|
+
try {
|
|
64
|
+
if (path.endsWith('.js')) {
|
|
65
|
+
// require() interop pour .js — sync, pas d'import dynamique
|
|
66
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
67
|
+
const mod = (require)(path);
|
|
68
|
+
parsed = (mod.default ?? mod);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
const raw = readFileSync(path, 'utf-8');
|
|
72
|
+
parsed = JSON.parse(raw);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch (e) {
|
|
76
|
+
throw new Error(`[qrpanel] failed to parse ${path}: ${e.message}`);
|
|
77
|
+
}
|
|
78
|
+
const merged = {
|
|
79
|
+
default: { ...DEFAULT_CONFIG.default, ...(parsed.default ?? {}) },
|
|
80
|
+
customThemes: parsed.customThemes,
|
|
81
|
+
};
|
|
82
|
+
_cache.set(path, { mtimeMs: stat.mtimeMs, config: merged });
|
|
83
|
+
return merged;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Crée `.qrconfig.json` à `cwd` s'il n'existe pas. Idempotent.
|
|
87
|
+
* Retourne le path écrit (ou path existant si déjà là).
|
|
88
|
+
*
|
|
89
|
+
* @param overrides — valeurs par défaut à patcher dans le fichier généré.
|
|
90
|
+
*/
|
|
91
|
+
export function ensureQrConfig(cwd = process.cwd(), overrides = {}) {
|
|
92
|
+
const existing = findConfigFile(cwd);
|
|
93
|
+
if (existing)
|
|
94
|
+
return existing;
|
|
95
|
+
const path = join(resolve(cwd), '.qrconfig.json');
|
|
96
|
+
const config = {
|
|
97
|
+
default: { ...DEFAULT_CONFIG.default, ...overrides },
|
|
98
|
+
};
|
|
99
|
+
const header = '// @mostajs/qrpanel — édite ce fichier pour piloter la génération QR.\n'
|
|
100
|
+
+ '// Le master toggle "genimage": false bypass tout le pipeline thématique.\n'
|
|
101
|
+
+ '// "theme": "random" tire dans themePool ; figer un thème = "theme": "science" par exemple.\n';
|
|
102
|
+
const body = JSON.stringify(config, null, 2) + '\n';
|
|
103
|
+
// JSON pur (pas de commentaire dans .qrconfig.json) — header en commentaire
|
|
104
|
+
// de fichier .json est invalide, on l'ignore. On garde juste le JSON.
|
|
105
|
+
void header;
|
|
106
|
+
writeFileSync(path, body, { mode: 0o644 });
|
|
107
|
+
return path;
|
|
108
|
+
}
|
|
109
|
+
/** Vide le cache mémoire (utile pour les tests). */
|
|
110
|
+
export function clearConfigCache() {
|
|
111
|
+
_cache.clear();
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export * from './server.js';
|
|
2
2
|
export * from './client.js';
|
|
3
|
+
export { type ThemeKey, type ThemeAsset, THEME_KEYS, listThemes, getTheme, } from './themes.js';
|
|
4
|
+
export { type QrConfig, type QrConfigDefaults, type QrFormat, type QrEcc, DEFAULT_CONFIG, loadQrConfig, ensureQrConfig, clearConfigCache, } from './config.js';
|
|
3
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,OAAO,EACL,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,GACjE,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,KAAK,QAAQ,EAAE,KAAK,gBAAgB,EAAE,KAAK,QAAQ,EAAE,KAAK,KAAK,EAC/D,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,gBAAgB,GAC/D,MAAM,aAAa,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -6,4 +6,6 @@
|
|
|
6
6
|
// éviter d'inclure React côté serveur ou qrcode côté client.
|
|
7
7
|
export * from './server.js';
|
|
8
8
|
export * from './client.js';
|
|
9
|
+
export { THEME_KEYS, listThemes, getTheme, } from './themes.js';
|
|
10
|
+
export { DEFAULT_CONFIG, loadQrConfig, ensureQrConfig, clearConfigCache, } from './config.js';
|
|
9
11
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,0CAA0C;AAC1C,EAAE;AACF,0EAA0E;AAC1E,sEAAsE;AACtE,6DAA6D;AAE7D,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,0CAA0C;AAC1C,EAAE;AACF,0EAA0E;AAC1E,sEAAsE;AACtE,6DAA6D;AAE7D,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,OAAO,EAC2B,UAAU,EAAE,UAAU,EAAE,QAAQ,GACjE,MAAM,aAAa,CAAA;AACpB,OAAO,EAEL,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,gBAAgB,GAC/D,MAAM,aAAa,CAAA"}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,28 +1,50 @@
|
|
|
1
|
+
import type { ThemeKey } from './themes.js';
|
|
1
2
|
export interface QrOptions {
|
|
2
|
-
/** Largeur/hauteur de l'image en pixels. Default 600. */
|
|
3
|
+
/** Largeur/hauteur de l'image en pixels. Default 600 (ou config). */
|
|
3
4
|
width?: number;
|
|
4
|
-
/** Marge blanche autour du QR (en modules). Default 2. */
|
|
5
|
+
/** Marge blanche autour du QR (en modules). Default 2 (ou config). */
|
|
5
6
|
margin?: number;
|
|
6
7
|
/**
|
|
7
|
-
* Niveau de correction d'erreur
|
|
8
|
-
*
|
|
9
|
-
* L = 7 % (default qrcode lib)
|
|
10
|
-
* M = 15 % (recommandé pour usage écran)
|
|
11
|
-
* Q = 25 %
|
|
12
|
-
* H = 30 % (recommandé si logo overlay)
|
|
8
|
+
* Niveau de correction d'erreur :
|
|
9
|
+
* L = 7 % | M = 15 % | Q = 25 % | H = 30 % (recommandé pour overlay)
|
|
13
10
|
*/
|
|
14
11
|
errorCorrectionLevel?: 'L' | 'M' | 'Q' | 'H';
|
|
15
|
-
/** Couleur des modules sombres. Default '#0f172a'
|
|
12
|
+
/** Couleur des modules sombres. Default '#0f172a'. */
|
|
16
13
|
darkColor?: string;
|
|
17
14
|
/** Couleur du fond. Default '#ffffff'. */
|
|
18
15
|
lightColor?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Master toggle. `false` court-circuite tout le pipeline thématique
|
|
18
|
+
* et retombe sur le QR pur (comportement v0.2.x). Override de la
|
|
19
|
+
* valeur config.
|
|
20
|
+
*/
|
|
21
|
+
genimage?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Thème à appliquer en cadre (4 motifs aux coins). Pris dans le
|
|
24
|
+
* registry natif (12 thèmes). 'random' tire dans `themePool`.
|
|
25
|
+
* 'none' désactive le composite ponctuellement.
|
|
26
|
+
* Objet `{ svg }` → motif custom inline.
|
|
27
|
+
*/
|
|
28
|
+
theme?: ThemeKey | 'random' | 'none' | {
|
|
29
|
+
svg: string;
|
|
30
|
+
label?: string;
|
|
31
|
+
};
|
|
32
|
+
/** Sous-set des thèmes pour le tirage 'random'. Default = tous. */
|
|
33
|
+
themePool?: ThemeKey[];
|
|
34
|
+
/** Marge cadre image / canvas (proportion). Default 0.13. */
|
|
35
|
+
framePadding?: number;
|
|
36
|
+
/** Taille du cartouche blanc central (proportion 0..1). Default 0.62. */
|
|
37
|
+
centerWhiteRatio?: number;
|
|
38
|
+
/** Opacité du cadre image (0..1). Default 1. */
|
|
39
|
+
themeOpacity?: number;
|
|
40
|
+
/** Couleur monochrome du cadre image. Default '#1e293b'. */
|
|
41
|
+
themeColor?: string;
|
|
19
42
|
}
|
|
20
43
|
/** Génère un PNG (Buffer) d'un QR code encodant `text`. */
|
|
21
44
|
export declare function generateQrPng(text: string, opts?: QrOptions): Promise<Buffer>;
|
|
22
45
|
/** Génère un SVG (string) d'un QR code encodant `text`. */
|
|
23
46
|
export declare function generateQrSvg(text: string, opts?: QrOptions): Promise<string>;
|
|
24
|
-
/** Génère un Data URL `data:image/png;base64,...`
|
|
25
|
-
* embarquer directement dans une balise `<img src>` sans endpoint dédié. */
|
|
47
|
+
/** Génère un Data URL `data:image/png;base64,...` */
|
|
26
48
|
export declare function generateQrDataUrl(text: string, opts?: QrOptions): Promise<string>;
|
|
27
49
|
export interface BuildInviteUrlsOptions {
|
|
28
50
|
/** Base absolue (https://app.example.com), sans slash final. */
|
|
@@ -35,7 +57,7 @@ export interface BuildInviteUrlsOptions {
|
|
|
35
57
|
inviteId: string;
|
|
36
58
|
/** TTL en ms (default 60 jours). */
|
|
37
59
|
ttlMs?: number;
|
|
38
|
-
/** Path du callback invite (default '/invite').
|
|
60
|
+
/** Path du callback invite (default '/invite'). */
|
|
39
61
|
invitePath?: string;
|
|
40
62
|
/** Meta libre encodée dans le token. */
|
|
41
63
|
inviteMeta?: Record<string, string | number | boolean>;
|
|
@@ -51,15 +73,8 @@ export interface InviteUrls {
|
|
|
51
73
|
/**
|
|
52
74
|
* Helper combiné — signe un invite-token et construit la paire d'URLs
|
|
53
75
|
* (direct + invite) prête à passer à `<QrPanel>` côté client.
|
|
54
|
-
*
|
|
55
|
-
* @example
|
|
56
|
-
* const { directUrl, inviteUrl } = buildInviteUrls({
|
|
57
|
-
* baseUrl: 'https://app.example.com',
|
|
58
|
-
* directPath: `/${project.slug}`,
|
|
59
|
-
* inviteSecret: process.env.INVITE_SECRET!,
|
|
60
|
-
* inviteId: project.id,
|
|
61
|
-
* inviteMeta: { kind: 'cohort-invite' },
|
|
62
|
-
* })
|
|
63
76
|
*/
|
|
64
77
|
export declare function buildInviteUrls(opts: BuildInviteUrlsOptions): InviteUrls;
|
|
78
|
+
export { listThemes, THEME_KEYS, THEMES, getTheme, type ThemeKey, type ThemeAsset } from './themes.js';
|
|
79
|
+
export { loadQrConfig, ensureQrConfig, DEFAULT_CONFIG, type QrConfig } from './config.js';
|
|
65
80
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAI3C,MAAM,WAAW,SAAS;IACxB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,oBAAoB,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;IAC5C,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAA;IAGnB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACtE,mEAAmE;IACnE,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAA;IACtB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gDAAgD;IAChD,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAuCD,2DAA2D;AAC3D,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,SAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBvF;AAED,2DAA2D;AAC3D,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,SAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBvF;AAED,qDAAqD;AACrD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,SAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAe3F;AAID,MAAM,WAAW,sBAAsB;IACrC,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAA;IACf,sEAAsE;IACtE,UAAU,EAAE,MAAM,CAAA;IAClB,+CAA+C;IAC/C,YAAY,EAAE,MAAM,GAAG,MAAM,CAAA;IAC7B,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAA;IAChB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAA;CACvD;AAED,MAAM,WAAW,UAAU;IACzB,0DAA0D;IAC1D,SAAS,EAAE,MAAM,CAAA;IACjB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAA;IACjB,oDAAoD;IACpD,WAAW,EAAE,MAAM,CAAA;CACpB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,sBAAsB,GAAG,UAAU,CAUxE;AAID,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AACtG,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAA"}
|
package/dist/server.js
CHANGED
|
@@ -1,62 +1,117 @@
|
|
|
1
1
|
// @mostajs/qrpanel/server — server-side QR generation (Node)
|
|
2
2
|
// Author: Dr Hamid MADANI <drmdh@msn.com>
|
|
3
3
|
//
|
|
4
|
-
// Wrap minimaliste de la lib `qrcode` (npm)
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
4
|
+
// Wrap minimaliste de la lib `qrcode` (npm) + extension thématique
|
|
5
|
+
// pilotée par .qrconfig.json (chargée à process.cwd() au runtime, cache
|
|
6
|
+
// invalidé par mtime).
|
|
7
|
+
//
|
|
8
|
+
// Cross-OS natif (Linux, macOS, Windows) — qrcode est pure-JS, et la
|
|
9
|
+
// rasterization PNG composite passe par @resvg/resvg-js (rust prebuilt
|
|
10
|
+
// binaries cross-OS, pas de chromium ni puppeteer).
|
|
11
|
+
//
|
|
12
|
+
// API legacy 100% rétro-compatible :
|
|
13
|
+
// - generateQrPng/Svg/DataUrl(text, opts) marchent comme en 0.2.x
|
|
14
|
+
// si .qrconfig.json est absent ET opts.genimage non-précisé.
|
|
15
|
+
// - Le master toggle genimage=false (config ou opts) court-circuite
|
|
16
|
+
// toute la chaîne thématique.
|
|
8
17
|
import QRCode from 'qrcode';
|
|
9
18
|
import { signInviteToken } from '@mostajs/auth/lib/invite-token';
|
|
19
|
+
import { loadQrConfig, } from './config.js';
|
|
20
|
+
import { composeThemedSvg, composeThemedPng, composeThemedDataUrl, mergeComposeOpts, } from './composer.js';
|
|
21
|
+
// ─── Internal helpers ──────────────────────────────────────────────
|
|
22
|
+
/**
|
|
23
|
+
* Décide si on bascule sur le pipeline composite ou le legacy.
|
|
24
|
+
* Order : opts.genimage > config.default.genimage. theme='none' force legacy.
|
|
25
|
+
*/
|
|
26
|
+
function shouldComposite(opts, cfg) {
|
|
27
|
+
if (opts.genimage === false)
|
|
28
|
+
return false;
|
|
29
|
+
if (opts.genimage === true) {
|
|
30
|
+
// explicit on : ne respecte pas theme=none ? Si l'app dit explicitement
|
|
31
|
+
// genimage=true mais theme=none, on respecte theme=none (QR pur ponctuel).
|
|
32
|
+
const theme = opts.theme ?? cfg.theme;
|
|
33
|
+
return theme !== 'none';
|
|
34
|
+
}
|
|
35
|
+
// Pas d'override opts → suit la config
|
|
36
|
+
if (cfg.genimage === false)
|
|
37
|
+
return false;
|
|
38
|
+
const theme = opts.theme ?? cfg.theme;
|
|
39
|
+
return theme !== 'none';
|
|
40
|
+
}
|
|
41
|
+
function composeOptsFromQrOptions(opts, cfg) {
|
|
42
|
+
return mergeComposeOpts(cfg, {
|
|
43
|
+
width: opts.width,
|
|
44
|
+
errorCorrectionLevel: opts.errorCorrectionLevel,
|
|
45
|
+
darkColor: opts.darkColor,
|
|
46
|
+
lightColor: opts.lightColor,
|
|
47
|
+
theme: opts.theme,
|
|
48
|
+
themePool: opts.themePool,
|
|
49
|
+
framePadding: opts.framePadding,
|
|
50
|
+
centerWhiteRatio: opts.centerWhiteRatio,
|
|
51
|
+
themeOpacity: opts.themeOpacity,
|
|
52
|
+
themeColor: opts.themeColor,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
// ─── Public API : 3 generators ─────────────────────────────────────
|
|
10
56
|
/** Génère un PNG (Buffer) d'un QR code encodant `text`. */
|
|
11
|
-
export function generateQrPng(text, opts = {}) {
|
|
57
|
+
export async function generateQrPng(text, opts = {}) {
|
|
58
|
+
const cfg = loadQrConfig().default;
|
|
59
|
+
if (shouldComposite(opts, cfg)) {
|
|
60
|
+
const composed = await composeThemedPng(text, composeOptsFromQrOptions(opts, cfg));
|
|
61
|
+
if (composed)
|
|
62
|
+
return composed;
|
|
63
|
+
}
|
|
64
|
+
// Legacy QR pur (qrcode lib direct)
|
|
12
65
|
return QRCode.toBuffer(text, {
|
|
13
|
-
width: opts.width ??
|
|
66
|
+
width: opts.width ?? cfg.width,
|
|
14
67
|
margin: opts.margin ?? 2,
|
|
15
|
-
errorCorrectionLevel: opts.errorCorrectionLevel ??
|
|
68
|
+
errorCorrectionLevel: opts.errorCorrectionLevel ?? cfg.errorCorrectionLevel,
|
|
16
69
|
color: {
|
|
17
|
-
dark: opts.darkColor ??
|
|
18
|
-
light: opts.lightColor ??
|
|
70
|
+
dark: opts.darkColor ?? cfg.darkColor,
|
|
71
|
+
light: opts.lightColor ?? cfg.lightColor,
|
|
19
72
|
},
|
|
20
73
|
});
|
|
21
74
|
}
|
|
22
75
|
/** Génère un SVG (string) d'un QR code encodant `text`. */
|
|
23
|
-
export function generateQrSvg(text, opts = {}) {
|
|
76
|
+
export async function generateQrSvg(text, opts = {}) {
|
|
77
|
+
const cfg = loadQrConfig().default;
|
|
78
|
+
if (shouldComposite(opts, cfg)) {
|
|
79
|
+
const composed = await composeThemedSvg(text, composeOptsFromQrOptions(opts, cfg));
|
|
80
|
+
if (composed)
|
|
81
|
+
return composed;
|
|
82
|
+
}
|
|
24
83
|
return QRCode.toString(text, {
|
|
25
84
|
type: 'svg',
|
|
26
|
-
width: opts.width ??
|
|
85
|
+
width: opts.width ?? cfg.width,
|
|
27
86
|
margin: opts.margin ?? 2,
|
|
28
|
-
errorCorrectionLevel: opts.errorCorrectionLevel ??
|
|
87
|
+
errorCorrectionLevel: opts.errorCorrectionLevel ?? cfg.errorCorrectionLevel,
|
|
29
88
|
color: {
|
|
30
|
-
dark: opts.darkColor ??
|
|
31
|
-
light: opts.lightColor ??
|
|
89
|
+
dark: opts.darkColor ?? cfg.darkColor,
|
|
90
|
+
light: opts.lightColor ?? cfg.lightColor,
|
|
32
91
|
},
|
|
33
92
|
});
|
|
34
93
|
}
|
|
35
|
-
/** Génère un Data URL `data:image/png;base64,...`
|
|
36
|
-
|
|
37
|
-
|
|
94
|
+
/** Génère un Data URL `data:image/png;base64,...` */
|
|
95
|
+
export async function generateQrDataUrl(text, opts = {}) {
|
|
96
|
+
const cfg = loadQrConfig().default;
|
|
97
|
+
if (shouldComposite(opts, cfg)) {
|
|
98
|
+
const composed = await composeThemedDataUrl(text, composeOptsFromQrOptions(opts, cfg));
|
|
99
|
+
if (composed)
|
|
100
|
+
return composed;
|
|
101
|
+
}
|
|
38
102
|
return QRCode.toDataURL(text, {
|
|
39
|
-
width: opts.width ??
|
|
103
|
+
width: opts.width ?? cfg.width,
|
|
40
104
|
margin: opts.margin ?? 2,
|
|
41
|
-
errorCorrectionLevel: opts.errorCorrectionLevel ??
|
|
105
|
+
errorCorrectionLevel: opts.errorCorrectionLevel ?? cfg.errorCorrectionLevel,
|
|
42
106
|
color: {
|
|
43
|
-
dark: opts.darkColor ??
|
|
44
|
-
light: opts.lightColor ??
|
|
107
|
+
dark: opts.darkColor ?? cfg.darkColor,
|
|
108
|
+
light: opts.lightColor ?? cfg.lightColor,
|
|
45
109
|
},
|
|
46
110
|
});
|
|
47
111
|
}
|
|
48
112
|
/**
|
|
49
113
|
* Helper combiné — signe un invite-token et construit la paire d'URLs
|
|
50
114
|
* (direct + invite) prête à passer à `<QrPanel>` côté client.
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* const { directUrl, inviteUrl } = buildInviteUrls({
|
|
54
|
-
* baseUrl: 'https://app.example.com',
|
|
55
|
-
* directPath: `/${project.slug}`,
|
|
56
|
-
* inviteSecret: process.env.INVITE_SECRET!,
|
|
57
|
-
* inviteId: project.id,
|
|
58
|
-
* inviteMeta: { kind: 'cohort-invite' },
|
|
59
|
-
* })
|
|
60
115
|
*/
|
|
61
116
|
export function buildInviteUrls(opts) {
|
|
62
117
|
const base = String(opts.baseUrl).replace(/\/+$/, '');
|
|
@@ -69,4 +124,7 @@ export function buildInviteUrls(opts) {
|
|
|
69
124
|
inviteToken,
|
|
70
125
|
};
|
|
71
126
|
}
|
|
127
|
+
// ─── Re-exports utiles côté serveur ────────────────────────────────
|
|
128
|
+
export { listThemes, THEME_KEYS, THEMES, getTheme } from './themes.js';
|
|
129
|
+
export { loadQrConfig, ensureQrConfig, DEFAULT_CONFIG } from './config.js';
|
|
72
130
|
//# sourceMappingURL=server.js.map
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,0CAA0C;AAC1C,EAAE;AACF,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/themes.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export type ThemeKey = 'baby' | 'animals' | 'science' | 'physics' | 'chemistry' | 'math' | 'nature' | 'tech' | 'space' | 'music' | 'book' | 'health';
|
|
2
|
+
export interface ThemeAsset {
|
|
3
|
+
key: ThemeKey;
|
|
4
|
+
label: string;
|
|
5
|
+
/** Fragment SVG (sans <svg> wrapper) — un motif centré sur (0,0). */
|
|
6
|
+
motif: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const THEMES: Record<ThemeKey, ThemeAsset>;
|
|
9
|
+
/** Liste des clés thèmes natifs (ordre fixe pour itération déterministe). */
|
|
10
|
+
export declare const THEME_KEYS: ThemeKey[];
|
|
11
|
+
/** Renvoie la liste des clés thèmes natifs. */
|
|
12
|
+
export declare function listThemes(): ThemeKey[];
|
|
13
|
+
/** Récupère un thème par clé. Lance si inconnu. */
|
|
14
|
+
export declare function getTheme(key: ThemeKey): ThemeAsset;
|
|
15
|
+
/**
|
|
16
|
+
* Tire un thème au hasard dans le pool fourni (ou tous les thèmes si pool absent).
|
|
17
|
+
* Utilise Math.random() — pas de seed (déterminisme = à la charge du caller s'il
|
|
18
|
+
* en a besoin).
|
|
19
|
+
*/
|
|
20
|
+
export declare function pickRandomTheme(pool?: ThemeKey[]): ThemeKey;
|
|
21
|
+
/**
|
|
22
|
+
* Construit le fragment SVG du cadre thématique :
|
|
23
|
+
* 4 instances du motif aux 4 coins, monochrome via CSS color, opacité.
|
|
24
|
+
*
|
|
25
|
+
* Le fragment est destiné à être inséré dans un SVG composite global
|
|
26
|
+
* (viewBox 0 0 width width). Coordonnées dans l'espace [0..width].
|
|
27
|
+
*/
|
|
28
|
+
export interface BuildFrameOpts {
|
|
29
|
+
/** Largeur du canvas SVG englobant en unités utilisateur. */
|
|
30
|
+
width: number;
|
|
31
|
+
/** Couleur monochrome appliquée via CSS. Default '#1e293b'. */
|
|
32
|
+
color?: string;
|
|
33
|
+
/** Opacité 0..1. Default 1. */
|
|
34
|
+
opacity?: number;
|
|
35
|
+
/**
|
|
36
|
+
* Proportion du cartouche blanc central / canvas (0..1). Détermine la
|
|
37
|
+
* largeur de la zone-marge où sont placés les motifs.
|
|
38
|
+
* Default 0.62.
|
|
39
|
+
*/
|
|
40
|
+
centerWhiteRatio?: number;
|
|
41
|
+
/**
|
|
42
|
+
* Position du motif dans la zone-marge (0..1) :
|
|
43
|
+
* 0 = motif collé au bord du canvas
|
|
44
|
+
* 0.5 = motif centré dans la zone-marge (default, optimal)
|
|
45
|
+
* 1 = motif collé contre le cartouche blanc
|
|
46
|
+
*/
|
|
47
|
+
framePadding?: number;
|
|
48
|
+
/**
|
|
49
|
+
* Échelle du motif (override de l'auto-calc).
|
|
50
|
+
* Auto = (marginZone × 0.65 / 14) où 14 ≈ envergure locale du motif.
|
|
51
|
+
*/
|
|
52
|
+
motifScale?: number;
|
|
53
|
+
}
|
|
54
|
+
export declare function buildThemeFrameSvg(theme: ThemeAsset, opts: BuildFrameOpts): string;
|
|
55
|
+
//# sourceMappingURL=themes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"themes.d.ts","sourceRoot":"","sources":["../src/themes.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,QAAQ,GAChB,MAAM,GACN,SAAS,GACT,SAAS,GACT,SAAS,GACT,WAAW,GACX,MAAM,GACN,QAAQ,GACR,MAAM,GACN,OAAO,GACP,OAAO,GACP,MAAM,GACN,QAAQ,CAAA;AAEZ,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,QAAQ,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAA;CACd;AAMD,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,UAAU,CA4I/C,CAAA;AAED,6EAA6E;AAC7E,eAAO,MAAM,UAAU,EAAE,QAAQ,EAGhC,CAAA;AAED,+CAA+C;AAC/C,wBAAgB,UAAU,IAAI,QAAQ,EAAE,CAEvC;AAED,mDAAmD;AACnD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,QAAQ,GAAG,UAAU,CAIlD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAG3D;AAED;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAA;IACb,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAKD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,GAAG,MAAM,CAsBlF"}
|