isahaq-barcode 1.0.0 → 1.2.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.
package/bin/generate.js CHANGED
@@ -1,274 +1,274 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * CLI for Isahaq Barcode Generator
5
- */
6
-
7
- const { Command } = require('commander');
8
- const chalk = require('chalk');
9
- const ora = require('ora');
10
- const fs = require('fs').promises;
11
- const path = require('path');
12
- const BarcodeGenerator = require('../index');
13
-
14
- const program = new Command();
15
-
16
- program
17
- .name('barcode-generate')
18
- .description('Generate barcodes and QR codes from command line')
19
- .version('1.0.0');
20
-
21
- // Barcode generation command
22
- program
23
- .command('barcode')
24
- .description('Generate a barcode')
25
- .requiredOption('-d, --data <data>', 'Data to encode')
26
- .option('-t, --type <type>', 'Barcode type', 'code128')
27
- .option('-f, --format <format>', 'Output format (png, svg, html, pdf)', 'png')
28
- .option('-o, --output <file>', 'Output file path')
29
- .option('-w, --width <width>', 'Barcode width', '2')
30
- .option('-h, --height <height>', 'Barcode height', '100')
31
- .option('--no-text', 'Hide text below barcode')
32
- .option('--foreground <color>', 'Foreground color (hex)', '#000000')
33
- .option('--background <color>', 'Background color (hex)', '#ffffff')
34
- .action(async (options) => {
35
- const spinner = ora('Generating barcode...').start();
36
-
37
- try {
38
- const renderOptions = {
39
- width: parseInt(options.width),
40
- height: parseInt(options.height),
41
- displayValue: options.text,
42
- lineColor: options.foreground,
43
- background: options.background,
44
- };
45
-
46
- let result;
47
- switch (options.format) {
48
- case 'png':
49
- result = BarcodeGenerator.png(
50
- options.data,
51
- options.type,
52
- renderOptions
53
- );
54
- break;
55
- case 'svg':
56
- result = BarcodeGenerator.svg(
57
- options.data,
58
- options.type,
59
- renderOptions
60
- );
61
- break;
62
- case 'html':
63
- result = BarcodeGenerator.html(
64
- options.data,
65
- options.type,
66
- renderOptions
67
- );
68
- break;
69
- case 'pdf':
70
- result = BarcodeGenerator.pdf(
71
- options.data,
72
- options.type,
73
- renderOptions
74
- );
75
- break;
76
- default:
77
- throw new Error(`Unsupported format: ${options.format}`);
78
- }
79
-
80
- if (options.output) {
81
- await fs.writeFile(options.output, result);
82
- spinner.succeed(`Barcode saved to ${options.output}`);
83
- } else {
84
- // Output to stdout (for base64 encoding)
85
- if (Buffer.isBuffer(result)) {
86
- console.log(result.toString('base64'));
87
- } else {
88
- console.log(result);
89
- }
90
- }
91
- } catch (error) {
92
- spinner.fail(`Error: ${error.message}`);
93
- process.exit(1);
94
- }
95
- });
96
-
97
- // QR code generation command
98
- program
99
- .command('qr')
100
- .description('Generate a QR code')
101
- .requiredOption('-d, --data <data>', 'Data to encode')
102
- .option('-s, --size <size>', 'QR code size', '300')
103
- .option('-f, --format <format>', 'Output format (png, svg, jpg)', 'png')
104
- .option('-o, --output <file>', 'Output file path')
105
- .option('-m, --margin <margin>', 'Margin size', '10')
106
- .option(
107
- '-e, --error-correction <level>',
108
- 'Error correction level (L, M, Q, H)',
109
- 'M'
110
- )
111
- .option('--foreground <color>', 'Foreground color (hex)', '#000000')
112
- .option('--background <color>', 'Background color (hex)', '#ffffff')
113
- .option('--logo <path>', 'Logo image path')
114
- .option('--logo-size <size>', 'Logo size percentage', '60')
115
- .option('--label <text>', 'Label text')
116
- .option('--watermark <text>', 'Watermark text')
117
- .option('--watermark-position <position>', 'Watermark position', 'center')
118
- .action(async (options) => {
119
- const spinner = ora('Generating QR code...').start();
120
-
121
- try {
122
- const qrOptions = {
123
- data: options.data,
124
- size: parseInt(options.size),
125
- margin: parseInt(options.margin),
126
- errorCorrectionLevel: options.errorCorrection,
127
- foregroundColor: hexToRgb(options.foreground),
128
- backgroundColor: hexToRgb(options.background),
129
- format: options.format,
130
- };
131
-
132
- if (options.logo) {
133
- qrOptions.logoPath = options.logo;
134
- qrOptions.logoSize = parseInt(options.logoSize);
135
- }
136
-
137
- if (options.label) {
138
- qrOptions.label = options.label;
139
- }
140
-
141
- if (options.watermark) {
142
- qrOptions.watermark = options.watermark;
143
- qrOptions.watermarkPosition = options.watermarkPosition;
144
- }
145
-
146
- const qrCode = BarcodeGenerator.modernQr(qrOptions);
147
- const result = await qrCode.generate();
148
-
149
- if (options.output) {
150
- await fs.writeFile(options.output, result);
151
- spinner.succeed(`QR code saved to ${options.output}`);
152
- } else {
153
- // Output to stdout (for base64 encoding)
154
- console.log(result.toString('base64'));
155
- }
156
- } catch (error) {
157
- spinner.fail(`Error: ${error.message}`);
158
- process.exit(1);
159
- }
160
- });
161
-
162
- // Batch generation command
163
- program
164
- .command('batch')
165
- .description('Generate multiple barcodes from a JSON file')
166
- .requiredOption('-i, --input <file>', 'Input JSON file')
167
- .option('-o, --output-dir <dir>', 'Output directory', './output')
168
- .action(async (options) => {
169
- const spinner = ora('Processing batch generation...').start();
170
-
171
- try {
172
- const inputData = JSON.parse(await fs.readFile(options.input, 'utf8'));
173
-
174
- if (!Array.isArray(inputData)) {
175
- throw new Error(
176
- 'Input file must contain an array of barcode configurations'
177
- );
178
- }
179
-
180
- // Create output directory if it doesn't exist
181
- await fs.mkdir(options.outputDir, { recursive: true });
182
-
183
- const results = BarcodeGenerator.batch(inputData);
184
-
185
- let successCount = 0;
186
- let errorCount = 0;
187
-
188
- for (const result of results) {
189
- if (result.success) {
190
- const filename = `barcode_${result.index}.${result.format}`;
191
- const filepath = path.join(options.outputDir, filename);
192
- await fs.writeFile(filepath, result.result);
193
- successCount++;
194
- } else {
195
- errorCount++;
196
- console.error(
197
- chalk.red(`Error in item ${result.index}: ${result.error}`)
198
- );
199
- }
200
- }
201
-
202
- spinner.succeed(
203
- `Batch generation completed: ${successCount} successful, ${errorCount} errors`
204
- );
205
- } catch (error) {
206
- spinner.fail(`Error: ${error.message}`);
207
- process.exit(1);
208
- }
209
- });
210
-
211
- // List supported types command
212
- program
213
- .command('types')
214
- .description('List supported barcode types')
215
- .action(() => {
216
- const types = BarcodeGenerator.getBarcodeTypes();
217
- console.log(chalk.blue('Supported barcode types:'));
218
- types.forEach((type) => {
219
- console.log(` - ${type}`);
220
- });
221
- });
222
-
223
- // List supported formats command
224
- program
225
- .command('formats')
226
- .description('List supported output formats')
227
- .action(() => {
228
- const formats = BarcodeGenerator.getRenderFormats();
229
- console.log(chalk.blue('Supported output formats:'));
230
- formats.forEach((format) => {
231
- console.log(` - ${format}`);
232
- });
233
- });
234
-
235
- // Validate data command
236
- program
237
- .command('validate')
238
- .description('Validate data for a specific barcode type')
239
- .requiredOption('-d, --data <data>', 'Data to validate')
240
- .requiredOption('-t, --type <type>', 'Barcode type')
241
- .action((options) => {
242
- try {
243
- const validation = BarcodeGenerator.validate(options.data, options.type);
244
-
245
- if (validation.valid) {
246
- console.log(chalk.green('✓ Data is valid'));
247
- console.log(` Type: ${validation.type}`);
248
- console.log(` Length: ${validation.length}`);
249
- console.log(` Charset: ${validation.charset}`);
250
- } else {
251
- console.log(chalk.red('✗ Data is invalid'));
252
- console.log(` Error: ${validation.error}`);
253
- process.exit(1);
254
- }
255
- } catch (error) {
256
- console.error(chalk.red(`Validation error: ${error.message}`));
257
- process.exit(1);
258
- }
259
- });
260
-
261
- // Helper function to convert hex to RGB
262
- function hexToRgb(hex) {
263
- const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
264
- return result
265
- ? [
266
- parseInt(result[1], 16),
267
- parseInt(result[2], 16),
268
- parseInt(result[3], 16),
269
- ]
270
- : [0, 0, 0];
271
- }
272
-
273
- // Parse command line arguments
274
- program.parse();
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * CLI for Isahaq Barcode Generator
5
+ */
6
+
7
+ const { Command } = require('commander');
8
+ const chalk = require('chalk');
9
+ const ora = require('ora');
10
+ const fs = require('fs').promises;
11
+ const path = require('path');
12
+ const BarcodeGenerator = require('../index');
13
+
14
+ const program = new Command();
15
+
16
+ program
17
+ .name('barcode-generate')
18
+ .description('Generate barcodes and QR codes from command line')
19
+ .version('1.0.0');
20
+
21
+ // Barcode generation command
22
+ program
23
+ .command('barcode')
24
+ .description('Generate a barcode')
25
+ .requiredOption('-d, --data <data>', 'Data to encode')
26
+ .option('-t, --type <type>', 'Barcode type', 'code128')
27
+ .option('-f, --format <format>', 'Output format (png, svg, html, pdf)', 'png')
28
+ .option('-o, --output <file>', 'Output file path')
29
+ .option('-w, --width <width>', 'Barcode width', '2')
30
+ .option('-h, --height <height>', 'Barcode height', '100')
31
+ .option('--no-text', 'Hide text below barcode')
32
+ .option('--foreground <color>', 'Foreground color (hex)', '#000000')
33
+ .option('--background <color>', 'Background color (hex)', '#ffffff')
34
+ .action(async options => {
35
+ const spinner = ora('Generating barcode...').start();
36
+
37
+ try {
38
+ const renderOptions = {
39
+ width: parseInt(options.width),
40
+ height: parseInt(options.height),
41
+ displayValue: options.text,
42
+ lineColor: options.foreground,
43
+ background: options.background,
44
+ };
45
+
46
+ let result;
47
+ switch (options.format) {
48
+ case 'png':
49
+ result = BarcodeGenerator.png(
50
+ options.data,
51
+ options.type,
52
+ renderOptions
53
+ );
54
+ break;
55
+ case 'svg':
56
+ result = BarcodeGenerator.svg(
57
+ options.data,
58
+ options.type,
59
+ renderOptions
60
+ );
61
+ break;
62
+ case 'html':
63
+ result = BarcodeGenerator.html(
64
+ options.data,
65
+ options.type,
66
+ renderOptions
67
+ );
68
+ break;
69
+ case 'pdf':
70
+ result = BarcodeGenerator.pdf(
71
+ options.data,
72
+ options.type,
73
+ renderOptions
74
+ );
75
+ break;
76
+ default:
77
+ throw new Error(`Unsupported format: ${options.format}`);
78
+ }
79
+
80
+ if (options.output) {
81
+ await fs.writeFile(options.output, result);
82
+ spinner.succeed(`Barcode saved to ${options.output}`);
83
+ } else {
84
+ // Output to stdout (for base64 encoding)
85
+ if (Buffer.isBuffer(result)) {
86
+ console.log(result.toString('base64'));
87
+ } else {
88
+ console.log(result);
89
+ }
90
+ }
91
+ } catch (error) {
92
+ spinner.fail(`Error: ${error.message}`);
93
+ process.exit(1);
94
+ }
95
+ });
96
+
97
+ // QR code generation command
98
+ program
99
+ .command('qr')
100
+ .description('Generate a QR code')
101
+ .requiredOption('-d, --data <data>', 'Data to encode')
102
+ .option('-s, --size <size>', 'QR code size', '300')
103
+ .option('-f, --format <format>', 'Output format (png, svg, jpg)', 'png')
104
+ .option('-o, --output <file>', 'Output file path')
105
+ .option('-m, --margin <margin>', 'Margin size', '10')
106
+ .option(
107
+ '-e, --error-correction <level>',
108
+ 'Error correction level (L, M, Q, H)',
109
+ 'M'
110
+ )
111
+ .option('--foreground <color>', 'Foreground color (hex)', '#000000')
112
+ .option('--background <color>', 'Background color (hex)', '#ffffff')
113
+ .option('--logo <path>', 'Logo image path')
114
+ .option('--logo-size <size>', 'Logo size percentage', '60')
115
+ .option('--label <text>', 'Label text')
116
+ .option('--watermark <text>', 'Watermark text')
117
+ .option('--watermark-position <position>', 'Watermark position', 'center')
118
+ .action(async options => {
119
+ const spinner = ora('Generating QR code...').start();
120
+
121
+ try {
122
+ const qrOptions = {
123
+ data: options.data,
124
+ size: parseInt(options.size),
125
+ margin: parseInt(options.margin),
126
+ errorCorrectionLevel: options.errorCorrection,
127
+ foregroundColor: hexToRgb(options.foreground),
128
+ backgroundColor: hexToRgb(options.background),
129
+ format: options.format,
130
+ };
131
+
132
+ if (options.logo) {
133
+ qrOptions.logoPath = options.logo;
134
+ qrOptions.logoSize = parseInt(options.logoSize);
135
+ }
136
+
137
+ if (options.label) {
138
+ qrOptions.label = options.label;
139
+ }
140
+
141
+ if (options.watermark) {
142
+ qrOptions.watermark = options.watermark;
143
+ qrOptions.watermarkPosition = options.watermarkPosition;
144
+ }
145
+
146
+ const qrCode = BarcodeGenerator.modernQr(qrOptions);
147
+ const result = await qrCode.generate();
148
+
149
+ if (options.output) {
150
+ await fs.writeFile(options.output, result);
151
+ spinner.succeed(`QR code saved to ${options.output}`);
152
+ } else {
153
+ // Output to stdout (for base64 encoding)
154
+ console.log(result.toString('base64'));
155
+ }
156
+ } catch (error) {
157
+ spinner.fail(`Error: ${error.message}`);
158
+ process.exit(1);
159
+ }
160
+ });
161
+
162
+ // Batch generation command
163
+ program
164
+ .command('batch')
165
+ .description('Generate multiple barcodes from a JSON file')
166
+ .requiredOption('-i, --input <file>', 'Input JSON file')
167
+ .option('-o, --output-dir <dir>', 'Output directory', './output')
168
+ .action(async options => {
169
+ const spinner = ora('Processing batch generation...').start();
170
+
171
+ try {
172
+ const inputData = JSON.parse(await fs.readFile(options.input, 'utf8'));
173
+
174
+ if (!Array.isArray(inputData)) {
175
+ throw new Error(
176
+ 'Input file must contain an array of barcode configurations'
177
+ );
178
+ }
179
+
180
+ // Create output directory if it doesn't exist
181
+ await fs.mkdir(options.outputDir, { recursive: true });
182
+
183
+ const results = BarcodeGenerator.batch(inputData);
184
+
185
+ let successCount = 0;
186
+ let errorCount = 0;
187
+
188
+ for (const result of results) {
189
+ if (result.success) {
190
+ const filename = `barcode_${result.index}.${result.format}`;
191
+ const filepath = path.join(options.outputDir, filename);
192
+ await fs.writeFile(filepath, result.result);
193
+ successCount++;
194
+ } else {
195
+ errorCount++;
196
+ console.error(
197
+ chalk.red(`Error in item ${result.index}: ${result.error}`)
198
+ );
199
+ }
200
+ }
201
+
202
+ spinner.succeed(
203
+ `Batch generation completed: ${successCount} successful, ${errorCount} errors`
204
+ );
205
+ } catch (error) {
206
+ spinner.fail(`Error: ${error.message}`);
207
+ process.exit(1);
208
+ }
209
+ });
210
+
211
+ // List supported types command
212
+ program
213
+ .command('types')
214
+ .description('List supported barcode types')
215
+ .action(() => {
216
+ const types = BarcodeGenerator.getBarcodeTypes();
217
+ console.log(chalk.blue('Supported barcode types:'));
218
+ types.forEach(type => {
219
+ console.log(` - ${type}`);
220
+ });
221
+ });
222
+
223
+ // List supported formats command
224
+ program
225
+ .command('formats')
226
+ .description('List supported output formats')
227
+ .action(() => {
228
+ const formats = BarcodeGenerator.getRenderFormats();
229
+ console.log(chalk.blue('Supported output formats:'));
230
+ formats.forEach(format => {
231
+ console.log(` - ${format}`);
232
+ });
233
+ });
234
+
235
+ // Validate data command
236
+ program
237
+ .command('validate')
238
+ .description('Validate data for a specific barcode type')
239
+ .requiredOption('-d, --data <data>', 'Data to validate')
240
+ .requiredOption('-t, --type <type>', 'Barcode type')
241
+ .action(options => {
242
+ try {
243
+ const validation = BarcodeGenerator.validate(options.data, options.type);
244
+
245
+ if (validation.valid) {
246
+ console.log(chalk.green('✓ Data is valid'));
247
+ console.log(` Type: ${validation.type}`);
248
+ console.log(` Length: ${validation.length}`);
249
+ console.log(` Charset: ${validation.charset}`);
250
+ } else {
251
+ console.log(chalk.red('✗ Data is invalid'));
252
+ console.log(` Error: ${validation.error}`);
253
+ process.exit(1);
254
+ }
255
+ } catch (error) {
256
+ console.error(chalk.red(`Validation error: ${error.message}`));
257
+ process.exit(1);
258
+ }
259
+ });
260
+
261
+ // Helper function to convert hex to RGB
262
+ function hexToRgb(hex) {
263
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
264
+ return result
265
+ ? [
266
+ parseInt(result[1], 16),
267
+ parseInt(result[2], 16),
268
+ parseInt(result[3], 16),
269
+ ]
270
+ : [0, 0, 0];
271
+ }
272
+
273
+ // Parse command line arguments
274
+ program.parse();