isahaq-barcode 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.
@@ -0,0 +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();
@@ -0,0 +1,68 @@
1
+ module.exports = [
2
+ {
3
+ files: ['**/*.js'],
4
+ languageOptions: {
5
+ ecmaVersion: 2022,
6
+ sourceType: 'module',
7
+ globals: {
8
+ console: 'readonly',
9
+ process: 'readonly',
10
+ Buffer: 'readonly',
11
+ __dirname: 'readonly',
12
+ __filename: 'readonly',
13
+ global: 'readonly',
14
+ module: 'readonly',
15
+ require: 'readonly',
16
+ exports: 'readonly',
17
+ document: 'readonly'
18
+ }
19
+ },
20
+ rules: {
21
+ 'indent': ['error', 2],
22
+ 'quotes': ['error', 'single'],
23
+ 'semi': ['error', 'always'],
24
+ 'no-unused-vars': 'warn',
25
+ 'no-console': 'off',
26
+ 'no-undef': 'error',
27
+ 'no-trailing-spaces': 'error',
28
+ 'eol-last': 'error'
29
+ }
30
+ },
31
+ {
32
+ files: ['tests/**/*.js', '**/*.test.js'],
33
+ languageOptions: {
34
+ ecmaVersion: 2022,
35
+ sourceType: 'module',
36
+ globals: {
37
+ console: 'readonly',
38
+ process: 'readonly',
39
+ Buffer: 'readonly',
40
+ __dirname: 'readonly',
41
+ __filename: 'readonly',
42
+ global: 'readonly',
43
+ module: 'readonly',
44
+ require: 'readonly',
45
+ exports: 'readonly',
46
+ describe: 'readonly',
47
+ test: 'readonly',
48
+ it: 'readonly',
49
+ expect: 'readonly',
50
+ beforeEach: 'readonly',
51
+ afterEach: 'readonly',
52
+ beforeAll: 'readonly',
53
+ afterAll: 'readonly',
54
+ jest: 'readonly'
55
+ }
56
+ },
57
+ rules: {
58
+ 'indent': ['error', 2],
59
+ 'quotes': ['error', 'single'],
60
+ 'semi': ['error', 'always'],
61
+ 'no-unused-vars': 'warn',
62
+ 'no-console': 'off',
63
+ 'no-undef': 'error',
64
+ 'no-trailing-spaces': 'error',
65
+ 'eol-last': 'error'
66
+ }
67
+ }
68
+ ];
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Basic usage examples for Isahaq Barcode Generator
3
+ */
4
+
5
+ const BarcodeGenerator = require('../index');
6
+
7
+ async function basicExamples() {
8
+ console.log('🚀 Basic Barcode Generation Examples\n');
9
+
10
+ // 1. Generate PNG barcode
11
+ console.log('1. Generating PNG barcode...');
12
+ const pngBuffer = BarcodeGenerator.png('1234567890', 'code128');
13
+ console.log(` PNG buffer size: ${pngBuffer.length} bytes`);
14
+
15
+ // 2. Generate SVG barcode
16
+ console.log('2. Generating SVG barcode...');
17
+ const svgString = BarcodeGenerator.svg('1234567890', 'ean13');
18
+ console.log(` SVG length: ${svgString.length} characters`);
19
+
20
+ // 3. Generate HTML barcode
21
+ console.log('3. Generating HTML barcode...');
22
+ const htmlString = BarcodeGenerator.html('1234567890', 'code39');
23
+ console.log(` HTML length: ${htmlString.length} characters`);
24
+
25
+ // 4. Generate PDF barcode
26
+ console.log('4. Generating PDF barcode...');
27
+ const pdfBuffer = await BarcodeGenerator.pdf('1234567890', 'code128');
28
+ console.log(` PDF buffer size: ${pdfBuffer.length} bytes`);
29
+
30
+ // 5. Generate QR code
31
+ console.log('5. Generating QR code...');
32
+ const qrCode = BarcodeGenerator.modernQr({
33
+ data: 'https://example.com',
34
+ size: 300,
35
+ margin: 10,
36
+ });
37
+ const qrBuffer = await qrCode.generate();
38
+ console.log(` QR code buffer size: ${qrBuffer.length} bytes`);
39
+
40
+ // 6. Generate QR code with logo
41
+ console.log('6. Generating QR code with logo...');
42
+ const qrWithLogo = BarcodeGenerator.modernQr({
43
+ data: 'https://example.com',
44
+ size: 300,
45
+ logoPath: 'path/to/logo.png',
46
+ logoSize: 60,
47
+ label: 'Scan me!',
48
+ });
49
+ const qrWithLogoBuffer = await qrWithLogo.generate();
50
+ console.log(
51
+ ` QR code with logo buffer size: ${qrWithLogoBuffer.length} bytes`
52
+ );
53
+
54
+ console.log('\n✅ All examples completed successfully!');
55
+ }
56
+
57
+ // Run examples
58
+ basicExamples().catch(console.error);
@@ -0,0 +1,56 @@
1
+ [
2
+ {
3
+ "data": "1234567890",
4
+ "type": "code128",
5
+ "format": "png",
6
+ "options": {
7
+ "width": 3,
8
+ "height": 150,
9
+ "displayValue": true
10
+ }
11
+ },
12
+ {
13
+ "data": "9876543210",
14
+ "type": "code39",
15
+ "format": "svg",
16
+ "options": {
17
+ "width": 2,
18
+ "height": 100,
19
+ "displayValue": false
20
+ }
21
+ },
22
+ {
23
+ "data": "1234567890123",
24
+ "type": "ean13",
25
+ "format": "png",
26
+ "options": {
27
+ "width": 2,
28
+ "height": 120,
29
+ "displayValue": true
30
+ }
31
+ },
32
+ {
33
+ "data": "https://example.com",
34
+ "type": "qrcode",
35
+ "format": "png",
36
+ "options": {
37
+ "size": 300,
38
+ "margin": 10,
39
+ "logoPath": "path/to/logo.png",
40
+ "logoSize": 60,
41
+ "label": "Scan me!"
42
+ }
43
+ },
44
+ {
45
+ "data": "https://github.com",
46
+ "type": "qrcode",
47
+ "format": "png",
48
+ "options": {
49
+ "size": 400,
50
+ "margin": 15,
51
+ "watermark": "GitHub",
52
+ "watermarkPosition": "center",
53
+ "errorCorrectionLevel": "H"
54
+ }
55
+ }
56
+ ]
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Express.js server example for Isahaq Barcode Generator
3
+ */
4
+
5
+ const express = require('express');
6
+ const BarcodeGenerator = require('../index');
7
+
8
+ const app = express();
9
+ const PORT = process.env.PORT || 3000;
10
+
11
+ // Middleware
12
+ app.use(express.json());
13
+ app.use(express.static('public'));
14
+
15
+ // Barcode generation endpoint
16
+ app.get('/barcode/:data', async (req, res) => {
17
+ const { data } = req.params;
18
+ const { type = 'code128', format = 'png', width, height } = req.query;
19
+
20
+ try {
21
+ const options = {};
22
+ if (width) options.width = parseInt(width);
23
+ if (height) options.height = parseInt(height);
24
+
25
+ let result;
26
+ let contentType;
27
+
28
+ switch (format) {
29
+ case 'png':
30
+ result = BarcodeGenerator.png(data, type, options);
31
+ contentType = 'image/png';
32
+ break;
33
+ case 'svg':
34
+ result = BarcodeGenerator.svg(data, type, options);
35
+ contentType = 'image/svg+xml';
36
+ break;
37
+ case 'html':
38
+ result = BarcodeGenerator.html(data, type, options);
39
+ contentType = 'text/html';
40
+ break;
41
+ case 'pdf':
42
+ result = await BarcodeGenerator.pdf(data, type, options);
43
+ contentType = 'application/pdf';
44
+ break;
45
+ default:
46
+ throw new Error(`Unsupported format: ${format}`);
47
+ }
48
+
49
+ res.set('Content-Type', contentType);
50
+ res.send(result);
51
+ } catch (error) {
52
+ res.status(400).json({ error: error.message });
53
+ }
54
+ });
55
+
56
+ // QR code generation endpoint
57
+ app.get('/qr/:data', async (req, res) => {
58
+ const { data } = req.params;
59
+ const {
60
+ size = 300,
61
+ logo,
62
+ label,
63
+ watermark,
64
+ watermarkPosition = 'center',
65
+ errorCorrection = 'M'
66
+ } = req.query;
67
+
68
+ try {
69
+ const qrOptions = {
70
+ data: decodeURIComponent(data),
71
+ size: parseInt(size),
72
+ errorCorrectionLevel: errorCorrection
73
+ };
74
+
75
+ if (logo) qrOptions.logoPath = logo;
76
+ if (label) qrOptions.label = label;
77
+ if (watermark) {
78
+ qrOptions.watermark = watermark;
79
+ qrOptions.watermarkPosition = watermarkPosition;
80
+ }
81
+
82
+ const qrCode = BarcodeGenerator.modernQr(qrOptions);
83
+ const result = await qrCode.generate();
84
+
85
+ res.set('Content-Type', 'image/png');
86
+ res.send(result);
87
+ } catch (error) {
88
+ res.status(400).json({ error: error.message });
89
+ }
90
+ });
91
+
92
+ // Batch generation endpoint
93
+ app.post('/batch', async (req, res) => {
94
+ try {
95
+ const { items } = req.body;
96
+
97
+ if (!Array.isArray(items)) {
98
+ throw new Error('Items must be an array');
99
+ }
100
+
101
+ const results = BarcodeGenerator.batch(items);
102
+ res.json({ results });
103
+ } catch (error) {
104
+ res.status(400).json({ error: error.message });
105
+ }
106
+ });
107
+
108
+ // Validation endpoint
109
+ app.get('/validate/:data/:type', (req, res) => {
110
+ const { data, type } = req.params;
111
+
112
+ try {
113
+ const validation = BarcodeGenerator.validate(data, type);
114
+ res.json(validation);
115
+ } catch (error) {
116
+ res.status(400).json({ error: error.message });
117
+ }
118
+ });
119
+
120
+ // Get supported types
121
+ app.get('/types', (req, res) => {
122
+ const types = BarcodeGenerator.getBarcodeTypes();
123
+ res.json({ types });
124
+ });
125
+
126
+ // Get supported formats
127
+ app.get('/formats', (req, res) => {
128
+ const formats = BarcodeGenerator.getRenderFormats();
129
+ res.json({ formats });
130
+ });
131
+
132
+ // Get watermark positions
133
+ app.get('/watermark-positions', (req, res) => {
134
+ const positions = BarcodeGenerator.getWatermarkPositions();
135
+ res.json({ positions });
136
+ });
137
+
138
+ // Health check
139
+ app.get('/health', (req, res) => {
140
+ res.json({ status: 'OK', timestamp: new Date().toISOString() });
141
+ });
142
+
143
+ // Error handling middleware
144
+ app.use((error, req, res) => {
145
+ console.error('Error:', error);
146
+ res.status(500).json({ error: 'Internal server error' });
147
+ });
148
+
149
+ // Start server
150
+ app.listen(PORT, () => {
151
+ console.log(`🚀 Server running on http://localhost:${PORT}`);
152
+ console.log(`📊 Health check: http://localhost:${PORT}/health`);
153
+ console.log(`🔗 Barcode endpoint: http://localhost:${PORT}/barcode/{data}?type=code128&format=png`);
154
+ console.log(`🔗 QR code endpoint: http://localhost:${PORT}/qr/{data}?size=300`);
155
+ console.log(`🔗 Types endpoint: http://localhost:${PORT}/types`);
156
+ console.log(`🔗 Formats endpoint: http://localhost:${PORT}/formats`);
157
+ });
158
+
159
+ module.exports = app;