@qr-styled/node 1.0.0

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.
Files changed (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +691 -0
  3. package/dist/cli/index.d.ts +29 -0
  4. package/dist/cli/index.d.ts.map +1 -0
  5. package/dist/cli/index.js +126 -0
  6. package/dist/cli/index.js.map +1 -0
  7. package/dist/index.d.ts +15 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +14 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/lib/QRGenerator.d.ts +53 -0
  12. package/dist/lib/QRGenerator.d.ts.map +1 -0
  13. package/dist/lib/QRGenerator.js +150 -0
  14. package/dist/lib/QRGenerator.js.map +1 -0
  15. package/dist/lib/QRGenerator.new-features.test.d.ts +2 -0
  16. package/dist/lib/QRGenerator.new-features.test.d.ts.map +1 -0
  17. package/dist/lib/QRGenerator.new-features.test.js +235 -0
  18. package/dist/lib/QRGenerator.new-features.test.js.map +1 -0
  19. package/dist/lib/QRGenerator.test.d.ts +2 -0
  20. package/dist/lib/QRGenerator.test.d.ts.map +1 -0
  21. package/dist/lib/QRGenerator.test.js +39 -0
  22. package/dist/lib/QRGenerator.test.js.map +1 -0
  23. package/dist/lib/renderers/BackgroundRenderer.d.ts +23 -0
  24. package/dist/lib/renderers/BackgroundRenderer.d.ts.map +1 -0
  25. package/dist/lib/renderers/BackgroundRenderer.js +48 -0
  26. package/dist/lib/renderers/BackgroundRenderer.js.map +1 -0
  27. package/dist/lib/renderers/GradientRenderer.d.ts +19 -0
  28. package/dist/lib/renderers/GradientRenderer.d.ts.map +1 -0
  29. package/dist/lib/renderers/GradientRenderer.js +44 -0
  30. package/dist/lib/renderers/GradientRenderer.js.map +1 -0
  31. package/dist/lib/renderers/LogoRenderer.d.ts +23 -0
  32. package/dist/lib/renderers/LogoRenderer.d.ts.map +1 -0
  33. package/dist/lib/renderers/LogoRenderer.js +72 -0
  34. package/dist/lib/renderers/LogoRenderer.js.map +1 -0
  35. package/dist/lib/renderers/ModuleRenderer.d.ts +45 -0
  36. package/dist/lib/renderers/ModuleRenderer.d.ts.map +1 -0
  37. package/dist/lib/renderers/ModuleRenderer.js +162 -0
  38. package/dist/lib/renderers/ModuleRenderer.js.map +1 -0
  39. package/dist/lib/renderers/SVGRenderer.d.ts +23 -0
  40. package/dist/lib/renderers/SVGRenderer.d.ts.map +1 -0
  41. package/dist/lib/renderers/SVGRenderer.js +74 -0
  42. package/dist/lib/renderers/SVGRenderer.js.map +1 -0
  43. package/dist/lib/utils/formatters.d.ts +26 -0
  44. package/dist/lib/utils/formatters.d.ts.map +1 -0
  45. package/dist/lib/utils/formatters.js +107 -0
  46. package/dist/lib/utils/formatters.js.map +1 -0
  47. package/dist/lib/utils/formatters.test.d.ts +2 -0
  48. package/dist/lib/utils/formatters.test.d.ts.map +1 -0
  49. package/dist/lib/utils/formatters.test.js +190 -0
  50. package/dist/lib/utils/formatters.test.js.map +1 -0
  51. package/dist/lib/utils/types.d.ts +120 -0
  52. package/dist/lib/utils/types.d.ts.map +1 -0
  53. package/dist/lib/utils/types.js +35 -0
  54. package/dist/lib/utils/types.js.map +1 -0
  55. package/dist/lib/utils/validators.d.ts +11 -0
  56. package/dist/lib/utils/validators.d.ts.map +1 -0
  57. package/dist/lib/utils/validators.js +127 -0
  58. package/dist/lib/utils/validators.js.map +1 -0
  59. package/dist/lib/utils/validators.test.d.ts +2 -0
  60. package/dist/lib/utils/validators.test.d.ts.map +1 -0
  61. package/dist/lib/utils/validators.test.js +62 -0
  62. package/dist/lib/utils/validators.test.js.map +1 -0
  63. package/package.json +87 -0
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+ import yargs from 'yargs';
3
+ interface CLIArguments {
4
+ url: string;
5
+ out: string;
6
+ size: number;
7
+ color: string;
8
+ logo: string;
9
+ rounded: boolean;
10
+ moduleRadius: number;
11
+ logoPadding: number;
12
+ logoShape: 'circle' | 'square';
13
+ logoRadius: number;
14
+ gradient: boolean;
15
+ gradientColors: string;
16
+ gradientAngle: number;
17
+ padding: number;
18
+ cornerRadius: number;
19
+ }
20
+ /**
21
+ * CLI argument parser configuration
22
+ */
23
+ export declare function buildCLI(): yargs.Argv<CLIArguments>;
24
+ /**
25
+ * Executes the CLI command
26
+ */
27
+ export declare function runCLI(): Promise<void>;
28
+ export {};
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,UAAU,YAAY;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,QAAQ,IA2FP,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CACxC;AAED;;GAEG;AACH,wBAAsB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAkB5C"}
@@ -0,0 +1,126 @@
1
+ #!/usr/bin/env node
2
+ import yargs from 'yargs';
3
+ import { hideBin } from 'yargs/helpers';
4
+ import { QRGenerator } from '../lib/QRGenerator.js';
5
+ import chalk from 'chalk';
6
+ /**
7
+ * CLI argument parser configuration
8
+ */
9
+ export function buildCLI() {
10
+ return yargs(hideBin(process.argv))
11
+ .usage('Usage: $0 --url <text> [options]')
12
+ .option('url', {
13
+ type: 'string',
14
+ demandOption: true,
15
+ describe: 'URL or text for the QR code',
16
+ alias: 'u'
17
+ })
18
+ .option('out', {
19
+ type: 'string',
20
+ default: 'qr.png',
21
+ describe: 'Output file path',
22
+ alias: 'o'
23
+ })
24
+ .option('size', {
25
+ type: 'number',
26
+ default: 600,
27
+ describe: 'Canvas size in pixels'
28
+ })
29
+ .option('color', {
30
+ type: 'string',
31
+ default: '#000000',
32
+ describe: 'QR code color (hex format)',
33
+ alias: 'c'
34
+ })
35
+ .option('logo', {
36
+ type: 'string',
37
+ default: '',
38
+ describe: 'Logo image path or URL',
39
+ alias: 'l'
40
+ })
41
+ .option('rounded', {
42
+ type: 'boolean',
43
+ default: true,
44
+ describe: 'Use rounded module corners'
45
+ })
46
+ .option('moduleRadius', {
47
+ type: 'number',
48
+ default: 0.35,
49
+ describe: 'Module corner radius (0.0 - 0.5)'
50
+ })
51
+ .option('logoPadding', {
52
+ type: 'number',
53
+ default: 10,
54
+ describe: 'Padding around logo'
55
+ })
56
+ .option('logoShape', {
57
+ type: 'string',
58
+ default: 'circle',
59
+ choices: ['circle', 'square'],
60
+ describe: 'Logo background shape'
61
+ })
62
+ .option('logoRadius', {
63
+ type: 'number',
64
+ default: 20,
65
+ describe: 'Corner radius for square logo background'
66
+ })
67
+ .option('gradient', {
68
+ type: 'boolean',
69
+ default: false,
70
+ describe: 'Use gradient colors',
71
+ alias: 'g'
72
+ })
73
+ .option('gradientColors', {
74
+ type: 'string',
75
+ default: '#FEDA75,#FA7E1E,#D62976,#962FBF,#4F5BD5',
76
+ describe: 'Comma-separated gradient colors'
77
+ })
78
+ .option('gradientAngle', {
79
+ type: 'number',
80
+ default: 45,
81
+ describe: 'Gradient angle in degrees (0-360)'
82
+ })
83
+ .option('padding', {
84
+ type: 'number',
85
+ default: 40,
86
+ describe: 'Padding around QR code'
87
+ })
88
+ .option('cornerRadius', {
89
+ type: 'number',
90
+ default: 60,
91
+ describe: 'Background corner radius'
92
+ })
93
+ .example('$0 --url "https://example.com"', 'Generate basic QR code')
94
+ .example('$0 --url "https://example.com" --gradient', 'QR with gradient')
95
+ .example('$0 --url "https://example.com" --logo ./logo.png', 'QR with logo')
96
+ .help('h')
97
+ .alias('h', 'help')
98
+ .version()
99
+ .alias('v', 'version')
100
+ .strict();
101
+ }
102
+ /**
103
+ * Executes the CLI command
104
+ */
105
+ export async function runCLI() {
106
+ try {
107
+ const argv = await buildCLI().argv;
108
+ // Extract output path and create options object for generator
109
+ const { out, ...options } = argv;
110
+ console.log(chalk.blue('🔄 Generating QR code...'));
111
+ const generator = new QRGenerator(options);
112
+ await generator.generateToFile(out);
113
+ console.log(chalk.green(`✅ QR code generated successfully: ${out}`));
114
+ }
115
+ catch (error) {
116
+ const errorMessage = error instanceof Error ? error.message : String(error);
117
+ console.error(chalk.red('❌ Error generating QR code:'), errorMessage);
118
+ process.exit(1);
119
+ }
120
+ }
121
+ // Run CLI if this file is executed directly
122
+ const isMainModule = process.argv[1] === new URL(import.meta.url).pathname;
123
+ if (isMainModule) {
124
+ runCLI();
125
+ }
126
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @module qr-generator-styled
3
+ * @description A professional QR code generator library with advanced styling options
4
+ */
5
+ export { QRGenerator, generateQR, generateQRToFile } from './lib/QRGenerator.js';
6
+ export { DEFAULT_OPTIONS, VALID_LOGO_SHAPES, VALID_ERROR_CORRECTION_LEVELS } from './lib/utils/types.js';
7
+ export type { QROptions, QRDataType, VCardData, WiFiData, EmailData, SMSData, GeoData, LogoShape, ErrorCorrectionLevel } from './lib/utils/types.js';
8
+ export { validateOptions, normalizeOptions } from './lib/utils/validators.js';
9
+ export { formatVCard, formatWiFi, formatEmail, formatSMS, formatGeo, formatQRData } from './lib/utils/formatters.js';
10
+ export { BackgroundRenderer } from './lib/renderers/BackgroundRenderer.js';
11
+ export { GradientRenderer } from './lib/renderers/GradientRenderer.js';
12
+ export { ModuleRenderer } from './lib/renderers/ModuleRenderer.js';
13
+ export { LogoRenderer } from './lib/renderers/LogoRenderer.js';
14
+ export { SVGRenderer } from './lib/renderers/SVGRenderer.js';
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,WAAW,EACX,UAAU,EACV,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,6BAA6B,EAC9B,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EACV,SAAS,EACT,UAAU,EACV,SAAS,EACT,QAAQ,EACR,SAAS,EACT,OAAO,EACP,OAAO,EACP,SAAS,EACT,oBAAoB,EACrB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAE9E,OAAO,EACL,WAAW,EACX,UAAU,EACV,WAAW,EACX,SAAS,EACT,SAAS,EACT,YAAY,EACb,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @module qr-generator-styled
3
+ * @description A professional QR code generator library with advanced styling options
4
+ */
5
+ export { QRGenerator, generateQR, generateQRToFile } from './lib/QRGenerator.js';
6
+ export { DEFAULT_OPTIONS, VALID_LOGO_SHAPES, VALID_ERROR_CORRECTION_LEVELS } from './lib/utils/types.js';
7
+ export { validateOptions, normalizeOptions } from './lib/utils/validators.js';
8
+ export { formatVCard, formatWiFi, formatEmail, formatSMS, formatGeo, formatQRData } from './lib/utils/formatters.js';
9
+ export { BackgroundRenderer } from './lib/renderers/BackgroundRenderer.js';
10
+ export { GradientRenderer } from './lib/renderers/GradientRenderer.js';
11
+ export { ModuleRenderer } from './lib/renderers/ModuleRenderer.js';
12
+ export { LogoRenderer } from './lib/renderers/LogoRenderer.js';
13
+ export { SVGRenderer } from './lib/renderers/SVGRenderer.js';
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,WAAW,EACX,UAAU,EACV,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,6BAA6B,EAC9B,MAAM,sBAAsB,CAAC;AAc9B,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAE9E,OAAO,EACL,WAAW,EACX,UAAU,EACV,WAAW,EACX,SAAS,EACT,SAAS,EACT,YAAY,EACb,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC"}
@@ -0,0 +1,53 @@
1
+ import { Canvas } from 'canvas';
2
+ import { QROptions } from './utils/types.js';
3
+ /**
4
+ * QR Code Generator with advanced styling options
5
+ */
6
+ export declare class QRGenerator {
7
+ private options;
8
+ /**
9
+ * Creates a new QR generator instance
10
+ */
11
+ constructor(options: QROptions);
12
+ /**
13
+ * Generates QR code content from options
14
+ */
15
+ private getQRContent;
16
+ /**
17
+ * Generates QR code and returns the canvas
18
+ */
19
+ generate(): Promise<Canvas>;
20
+ /**
21
+ * Generates QR code and saves to file
22
+ */
23
+ generateToFile(outputPath: string): Promise<void>;
24
+ /**
25
+ * Generates QR code and returns buffer
26
+ */
27
+ generateToBuffer(format?: 'png' | 'jpeg'): Promise<Buffer>;
28
+ /**
29
+ * Generates QR code and returns data URL
30
+ */
31
+ generateToDataURL(format?: 'png' | 'jpeg'): Promise<string>;
32
+ /**
33
+ * Generates QR code as SVG string
34
+ */
35
+ generateToSVG(): Promise<string>;
36
+ /**
37
+ * Generates QR code as SVG and saves to file
38
+ */
39
+ generateToSVGFile(outputPath: string): Promise<void>;
40
+ /**
41
+ * Updates generator options
42
+ */
43
+ updateOptions(options: Partial<QROptions>): void;
44
+ }
45
+ /**
46
+ * Helper function to quickly generate a QR code
47
+ */
48
+ export declare function generateQR(options: QROptions): Promise<Canvas>;
49
+ /**
50
+ * Helper function to quickly generate and save a QR code
51
+ */
52
+ export declare function generateQRToFile(options: QROptions, outputPath: string): Promise<void>;
53
+ //# sourceMappingURL=QRGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QRGenerator.d.ts","sourceRoot":"","sources":["../../src/lib/QRGenerator.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,MAAM,EAAE,MAAM,QAAQ,CAAC;AAO9C,OAAO,EAAE,SAAS,EAAmB,MAAM,kBAAkB,CAAC;AAI9D;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAsB;IAErC;;OAEG;gBACS,OAAO,EAAE,SAAS;IAc9B;;OAEG;IACH,OAAO,CAAC,YAAY;IAOpB;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAmDjC;;OAEG;IACG,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvD;;OAEG;IACG,gBAAgB,CAAC,MAAM,GAAE,KAAK,GAAG,MAAc,GAAG,OAAO,CAAC,MAAM,CAAC;IAMvE;;OAEG;IACG,iBAAiB,CAAC,MAAM,GAAE,KAAK,GAAG,MAAc,GAAG,OAAO,CAAC,MAAM,CAAC;IAQxE;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAgBtC;;OAEG;IACG,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK1D;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI;CAajD;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAGpE;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,SAAS,EAClB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAGf"}
@@ -0,0 +1,150 @@
1
+ import QRCode from 'qrcode';
2
+ import { createCanvas } from 'canvas';
3
+ import fs from 'fs';
4
+ import { BackgroundRenderer } from './renderers/BackgroundRenderer.js';
5
+ import { GradientRenderer } from './renderers/GradientRenderer.js';
6
+ import { ModuleRenderer } from './renderers/ModuleRenderer.js';
7
+ import { LogoRenderer } from './renderers/LogoRenderer.js';
8
+ import { SVGRenderer } from './renderers/SVGRenderer.js';
9
+ import { DEFAULT_OPTIONS } from './utils/types.js';
10
+ import { validateOptions, normalizeOptions } from './utils/validators.js';
11
+ import { formatQRData } from './utils/formatters.js';
12
+ /**
13
+ * QR Code Generator with advanced styling options
14
+ */
15
+ export class QRGenerator {
16
+ /**
17
+ * Creates a new QR generator instance
18
+ */
19
+ constructor(options) {
20
+ this.options = normalizeOptions(options, DEFAULT_OPTIONS);
21
+ // Support deprecated 'color' field with backward compatibility
22
+ if (options.color && !options.foregroundColor) {
23
+ this.options.foregroundColor = options.color;
24
+ }
25
+ validateOptions(this.options);
26
+ }
27
+ /**
28
+ * Generates QR code content from options
29
+ */
30
+ getQRContent() {
31
+ const { type, url, data } = this.options;
32
+ // Use formatter to handle different data types
33
+ return formatQRData(type, url, data);
34
+ }
35
+ /**
36
+ * Generates QR code and returns the canvas
37
+ */
38
+ async generate() {
39
+ const { errorCorrectionLevel, size, padding, foregroundColor } = this.options;
40
+ const qrSize = size - padding * 2;
41
+ // Get formatted content based on type
42
+ const content = this.getQRContent();
43
+ // Generate QR data
44
+ const qrData = await QRCode.create(content, {
45
+ errorCorrectionLevel
46
+ }); // margin option not in types but works
47
+ const modules = qrData.modules;
48
+ const moduleCount = modules.size;
49
+ const moduleSize = qrSize / moduleCount;
50
+ // Create canvas
51
+ const canvas = createCanvas(size, size);
52
+ const ctx = canvas.getContext('2d');
53
+ // Render background
54
+ const backgroundRenderer = new BackgroundRenderer(ctx, this.options);
55
+ backgroundRenderer.render();
56
+ backgroundRenderer.applyClipping();
57
+ // Create fill style (gradient or solid)
58
+ const gradientRenderer = new GradientRenderer(ctx, this.options);
59
+ const fillStyle = gradientRenderer.getFillStyle();
60
+ // Render QR modules with eye customization support
61
+ const moduleRenderer = new ModuleRenderer(ctx, modules, {
62
+ ...this.options,
63
+ color: foregroundColor, // Use new foregroundColor
64
+ moduleCount,
65
+ moduleSize
66
+ });
67
+ moduleRenderer.render(fillStyle);
68
+ backgroundRenderer.restoreClipping();
69
+ // Render logo if provided
70
+ if (this.options.logo) {
71
+ const logoRenderer = new LogoRenderer(ctx, this.options);
72
+ await logoRenderer.render(this.options.logo);
73
+ }
74
+ return canvas;
75
+ }
76
+ /**
77
+ * Generates QR code and saves to file
78
+ */
79
+ async generateToFile(outputPath) {
80
+ const canvas = await this.generate();
81
+ const buffer = canvas.toBuffer('image/png');
82
+ fs.writeFileSync(outputPath, buffer);
83
+ }
84
+ /**
85
+ * Generates QR code and returns buffer
86
+ */
87
+ async generateToBuffer(format = 'png') {
88
+ const canvas = await this.generate();
89
+ const mimeType = format === 'jpeg' ? 'image/jpeg' : 'image/png';
90
+ return canvas.toBuffer(mimeType);
91
+ }
92
+ /**
93
+ * Generates QR code and returns data URL
94
+ */
95
+ async generateToDataURL(format = 'png') {
96
+ const canvas = await this.generate();
97
+ if (format === 'jpeg') {
98
+ return canvas.toDataURL('image/jpeg');
99
+ }
100
+ return canvas.toDataURL('image/png');
101
+ }
102
+ /**
103
+ * Generates QR code as SVG string
104
+ */
105
+ async generateToSVG() {
106
+ const { errorCorrectionLevel, size } = this.options;
107
+ // Get formatted content based on type
108
+ const content = this.getQRContent();
109
+ // Generate QR data
110
+ const qrData = await QRCode.create(content, {
111
+ errorCorrectionLevel
112
+ });
113
+ // Use SVG renderer
114
+ const svgRenderer = new SVGRenderer(qrData, this.options, size);
115
+ return svgRenderer.generate();
116
+ }
117
+ /**
118
+ * Generates QR code as SVG and saves to file
119
+ */
120
+ async generateToSVGFile(outputPath) {
121
+ const svg = await this.generateToSVG();
122
+ fs.writeFileSync(outputPath, svg, 'utf-8');
123
+ }
124
+ /**
125
+ * Updates generator options
126
+ */
127
+ updateOptions(options) {
128
+ this.options = normalizeOptions({ ...this.options, ...options }, DEFAULT_OPTIONS);
129
+ // Support deprecated 'color' field
130
+ if (options.color && !options.foregroundColor) {
131
+ this.options.foregroundColor = options.color;
132
+ }
133
+ validateOptions(this.options);
134
+ }
135
+ }
136
+ /**
137
+ * Helper function to quickly generate a QR code
138
+ */
139
+ export async function generateQR(options) {
140
+ const generator = new QRGenerator(options);
141
+ return generator.generate();
142
+ }
143
+ /**
144
+ * Helper function to quickly generate and save a QR code
145
+ */
146
+ export async function generateQRToFile(options, outputPath) {
147
+ const generator = new QRGenerator(options);
148
+ return generator.generateToFile(outputPath);
149
+ }
150
+ //# sourceMappingURL=QRGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QRGenerator.js","sourceRoot":"","sources":["../../src/lib/QRGenerator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=QRGenerator.new-features.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QRGenerator.new-features.test.d.ts","sourceRoot":"","sources":["../../src/lib/QRGenerator.new-features.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,235 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { QRGenerator } from './QRGenerator.js';
3
+ describe('QRGenerator - New Features', () => {
4
+ describe('Specialized QR Types', () => {
5
+ it('should generate vCard QR code', async () => {
6
+ const generator = new QRGenerator({
7
+ type: 'vcard',
8
+ data: {
9
+ firstName: 'John',
10
+ lastName: 'Doe',
11
+ phone: '+1234567890',
12
+ email: 'john@example.com'
13
+ },
14
+ size: 300
15
+ });
16
+ const buffer = await generator.generateToBuffer();
17
+ expect(buffer).toBeInstanceOf(Buffer);
18
+ expect(buffer.length).toBeGreaterThan(0);
19
+ });
20
+ it('should generate WiFi QR code', async () => {
21
+ const generator = new QRGenerator({
22
+ type: 'wifi',
23
+ data: {
24
+ ssid: 'MyNetwork',
25
+ password: 'SecurePass123',
26
+ encryption: 'WPA'
27
+ },
28
+ size: 300
29
+ });
30
+ const buffer = await generator.generateToBuffer();
31
+ expect(buffer).toBeInstanceOf(Buffer);
32
+ expect(buffer.length).toBeGreaterThan(0);
33
+ });
34
+ it('should generate email QR code', async () => {
35
+ const generator = new QRGenerator({
36
+ type: 'email',
37
+ data: {
38
+ email: 'contact@example.com',
39
+ subject: 'Hello',
40
+ body: 'Test message'
41
+ },
42
+ size: 300
43
+ });
44
+ const buffer = await generator.generateToBuffer();
45
+ expect(buffer).toBeInstanceOf(Buffer);
46
+ expect(buffer.length).toBeGreaterThan(0);
47
+ });
48
+ it('should generate SMS QR code', async () => {
49
+ const generator = new QRGenerator({
50
+ type: 'sms',
51
+ data: {
52
+ phone: '+1234567890',
53
+ message: 'Hello from QR'
54
+ },
55
+ size: 300
56
+ });
57
+ const buffer = await generator.generateToBuffer();
58
+ expect(buffer).toBeInstanceOf(Buffer);
59
+ expect(buffer.length).toBeGreaterThan(0);
60
+ });
61
+ it('should generate geo location QR code', async () => {
62
+ const generator = new QRGenerator({
63
+ type: 'geo',
64
+ data: {
65
+ latitude: 40.7128,
66
+ longitude: -74.006
67
+ },
68
+ size: 300
69
+ });
70
+ const buffer = await generator.generateToBuffer();
71
+ expect(buffer).toBeInstanceOf(Buffer);
72
+ expect(buffer.length).toBeGreaterThan(0);
73
+ });
74
+ });
75
+ describe('SVG Generation', () => {
76
+ it('should generate SVG QR code', async () => {
77
+ const generator = new QRGenerator({
78
+ url: 'https://example.com',
79
+ size: 300
80
+ });
81
+ const svg = await generator.generateToSVG();
82
+ expect(svg).toContain('<?xml');
83
+ expect(svg).toContain('<svg');
84
+ expect(svg).toContain('</svg>');
85
+ expect(svg).toContain('xmlns="http://www.w3.org/2000/svg"');
86
+ });
87
+ it('should include correct dimensions in SVG', async () => {
88
+ const generator = new QRGenerator({
89
+ url: 'https://test.com',
90
+ size: 500
91
+ });
92
+ const svg = await generator.generateToSVG();
93
+ expect(svg).toContain('width="500"');
94
+ expect(svg).toContain('height="500"');
95
+ expect(svg).toContain('viewBox="0 0 500 500"');
96
+ });
97
+ it('should apply colors in SVG', async () => {
98
+ const generator = new QRGenerator({
99
+ url: 'https://test.com',
100
+ size: 300,
101
+ foregroundColor: '#FF0000',
102
+ backgroundColor: '#FFFFFF'
103
+ });
104
+ const svg = await generator.generateToSVG();
105
+ expect(svg).toContain('#FF0000');
106
+ expect(svg).toContain('#FFFFFF');
107
+ });
108
+ });
109
+ describe('New Options', () => {
110
+ it('should support margin option', async () => {
111
+ const generator = new QRGenerator({
112
+ url: 'https://example.com',
113
+ size: 300,
114
+ margin: 2
115
+ });
116
+ const buffer = await generator.generateToBuffer();
117
+ expect(buffer).toBeInstanceOf(Buffer);
118
+ });
119
+ it('should support foregroundColor', async () => {
120
+ const generator = new QRGenerator({
121
+ url: 'https://example.com',
122
+ size: 300,
123
+ foregroundColor: '#0000FF'
124
+ });
125
+ const buffer = await generator.generateToBuffer();
126
+ expect(buffer).toBeInstanceOf(Buffer);
127
+ });
128
+ it('should support eye customization', async () => {
129
+ const generator = new QRGenerator({
130
+ url: 'https://example.com',
131
+ size: 300,
132
+ eyeColor: '#FF0000',
133
+ eyeRadius: 0.3
134
+ });
135
+ const buffer = await generator.generateToBuffer();
136
+ expect(buffer).toBeInstanceOf(Buffer);
137
+ });
138
+ it('should maintain backward compatibility with color option', async () => {
139
+ const generator = new QRGenerator({
140
+ url: 'https://example.com',
141
+ size: 300,
142
+ color: '#00FF00'
143
+ });
144
+ const buffer = await generator.generateToBuffer();
145
+ expect(buffer).toBeInstanceOf(Buffer);
146
+ });
147
+ it('should support logoSize and logoBackgroundColor', async () => {
148
+ const generator = new QRGenerator({
149
+ url: 'https://example.com',
150
+ size: 300,
151
+ logoSize: 80,
152
+ logoBackgroundColor: '#FFFFFF'
153
+ });
154
+ const buffer = await generator.generateToBuffer();
155
+ expect(buffer).toBeInstanceOf(Buffer);
156
+ });
157
+ });
158
+ describe('Validation', () => {
159
+ it('should reject vCard without name', () => {
160
+ expect(() => {
161
+ new QRGenerator({
162
+ type: 'vcard',
163
+ data: {} // No firstName or lastName
164
+ });
165
+ }).toThrow('vCard requires at least a first name or last name');
166
+ });
167
+ it('should reject WiFi without SSID', () => {
168
+ expect(() => {
169
+ new QRGenerator({
170
+ type: 'wifi',
171
+ data: {
172
+ password: 'test'
173
+ }
174
+ });
175
+ }).toThrow('WiFi QR code requires SSID');
176
+ });
177
+ it('should reject email without email address', () => {
178
+ expect(() => {
179
+ new QRGenerator({
180
+ type: 'email',
181
+ data: {}
182
+ });
183
+ }).toThrow('Email QR code requires email address');
184
+ });
185
+ it('should reject SMS without phone number', () => {
186
+ expect(() => {
187
+ new QRGenerator({
188
+ type: 'sms',
189
+ data: {}
190
+ });
191
+ }).toThrow('SMS QR code requires phone number');
192
+ });
193
+ it('should reject geo without coordinates', () => {
194
+ expect(() => {
195
+ new QRGenerator({
196
+ type: 'geo',
197
+ data: {}
198
+ });
199
+ }).toThrow('Geo QR code requires latitude and longitude');
200
+ });
201
+ it('should reject invalid margin', () => {
202
+ expect(() => {
203
+ new QRGenerator({
204
+ url: 'https://test.com',
205
+ margin: -1
206
+ });
207
+ }).toThrow('Margin must be between 0 and 10 modules');
208
+ });
209
+ it('should reject invalid eyeRadius', () => {
210
+ expect(() => {
211
+ new QRGenerator({
212
+ url: 'https://test.com',
213
+ eyeRadius: 1.5
214
+ });
215
+ }).toThrow('Eye radius must be between 0.0 and 0.5');
216
+ });
217
+ it('should reject invalid logoSize', () => {
218
+ expect(() => {
219
+ new QRGenerator({
220
+ url: 'https://test.com',
221
+ logoSize: 600
222
+ });
223
+ }).toThrow('Logo size must be between 50 and 500 pixels');
224
+ });
225
+ it('should reject specialized type without data', () => {
226
+ expect(() => {
227
+ new QRGenerator({
228
+ type: 'wifi'
229
+ // Missing data
230
+ });
231
+ }).toThrow('URL, text content, or structured data is required');
232
+ });
233
+ });
234
+ });
235
+ //# sourceMappingURL=QRGenerator.new-features.test.js.map