isahaq-barcode 1.9.0 → 2.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.
- package/CHANGELOG.md +107 -0
- package/LICENSE +21 -0
- package/README.md +317 -553
- package/bin/generate.js +171 -134
- package/browser.js +163 -170
- package/index.d.ts +497 -0
- package/index.js +119 -51
- package/package.json +69 -41
- package/src/builders/QrCodeBuilder.js +328 -165
- package/src/encoders/BarcodeEncoder.js +260 -0
- package/src/renderers/HTMLRenderer.js +36 -169
- package/src/renderers/PDFRenderer.js +108 -130
- package/src/renderers/PNGRenderer.js +7 -83
- package/src/renderers/RenderFormats.js +89 -38
- package/src/renderers/SVGRenderer.js +8 -182
- package/src/services/BarcodeService.js +96 -36
- package/src/types/BarcodeTypes.js +535 -144
- package/src/validators/Validator.js +140 -122
- package/.eslintrc.js +0 -29
- package/.prettierignore +0 -11
- package/.prettierrc +0 -11
- package/eslint.config.js +0 -67
- package/examples/basic-usage.js +0 -58
- package/examples/batch-example.json +0 -56
- package/examples/express-server.js +0 -163
- package/jest.config.js +0 -13
- package/tests/BarcodeGenerator.test.js +0 -187
- package/tests/BarcodeService.test.js +0 -76
- package/tests/QrCodeBuilder.test.js +0 -130
- package/tests/setup.js +0 -59
- package/webpack.config.js +0 -26
package/browser.js
CHANGED
|
@@ -1,228 +1,221 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Browser
|
|
3
|
-
*
|
|
2
|
+
* Browser build of Isahaq Barcode Generator
|
|
3
|
+
*
|
|
4
|
+
* Uses the same encoder and type registry as the Node.js build, so a barcode
|
|
5
|
+
* rendered in the browser is identical to one rendered on the server. Node-only
|
|
6
|
+
* outputs (PDF, file writing) are not available here.
|
|
4
7
|
*/
|
|
5
8
|
|
|
6
|
-
|
|
9
|
+
const bwipjs = require('bwip-js');
|
|
7
10
|
const QRCode = require('qrcode');
|
|
11
|
+
const { BarcodeEncoder } = require('./src/encoders/BarcodeEncoder');
|
|
12
|
+
const { BarcodeTypes } = require('./src/types/BarcodeTypes');
|
|
13
|
+
const { RenderFormats } = require('./src/renderers/RenderFormats');
|
|
14
|
+
const { Validator } = require('./src/validators/Validator');
|
|
8
15
|
|
|
9
|
-
|
|
10
|
-
|
|
16
|
+
const validator = new Validator();
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Assert that a DOM is available before touching document
|
|
20
|
+
* @param {string} feature - Feature name used in the error message
|
|
21
|
+
*/
|
|
22
|
+
function requireDom(feature) {
|
|
23
|
+
if (typeof document === 'undefined') {
|
|
24
|
+
throw new Error(`${feature} requires a browser environment with a DOM`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
11
27
|
|
|
12
28
|
class BrowserBarcodeGenerator {
|
|
13
29
|
/**
|
|
14
|
-
* Generate
|
|
30
|
+
* Generate a barcode as SVG markup
|
|
15
31
|
* @param {string} data - Data to encode
|
|
16
32
|
* @param {string} type - Barcode type
|
|
17
33
|
* @param {Object} options - Options
|
|
18
|
-
* @returns {
|
|
34
|
+
* @returns {string} SVG markup
|
|
19
35
|
*/
|
|
20
|
-
static
|
|
21
|
-
|
|
22
|
-
// Create a canvas element
|
|
23
|
-
const canvas = document.createElement('canvas');
|
|
24
|
-
|
|
25
|
-
// Generate barcode using jsbarcode
|
|
26
|
-
JsBarcode(canvas, data, {
|
|
27
|
-
format: type.toUpperCase(),
|
|
28
|
-
width: options.width || 2,
|
|
29
|
-
height: options.height || 100,
|
|
30
|
-
displayValue: options.displayValue !== false,
|
|
31
|
-
fontSize: options.fontSize || 20,
|
|
32
|
-
textAlign: options.textAlign || 'center',
|
|
33
|
-
textPosition: options.textPosition || 'bottom',
|
|
34
|
-
textMargin: options.textMargin || 2,
|
|
35
|
-
background: options.background || '#ffffff',
|
|
36
|
-
lineColor: options.lineColor || '#000000',
|
|
37
|
-
margin: options.margin || 10,
|
|
38
|
-
...options,
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
// Convert canvas to blob
|
|
42
|
-
return new Promise(resolve => {
|
|
43
|
-
canvas.toBlob(blob => {
|
|
44
|
-
const reader = new FileReader();
|
|
45
|
-
reader.onload = () => resolve(Buffer.from(reader.result));
|
|
46
|
-
reader.readAsArrayBuffer(blob);
|
|
47
|
-
}, 'image/png');
|
|
48
|
-
});
|
|
49
|
-
} catch (error) {
|
|
50
|
-
throw new Error(`Failed to generate PNG barcode: ${error.message}`);
|
|
51
|
-
}
|
|
36
|
+
static svg(data, type = 'code128', options = {}) {
|
|
37
|
+
return BarcodeEncoder.toSvg(data, type, options);
|
|
52
38
|
}
|
|
53
39
|
|
|
54
40
|
/**
|
|
55
|
-
* Generate
|
|
41
|
+
* Generate a barcode as SVG markup (alias of svg, mirrors the Node.js API)
|
|
56
42
|
* @param {string} data - Data to encode
|
|
57
43
|
* @param {string} type - Barcode type
|
|
58
44
|
* @param {Object} options - Options
|
|
59
|
-
* @returns {string} SVG
|
|
45
|
+
* @returns {string} SVG markup
|
|
60
46
|
*/
|
|
61
|
-
static
|
|
62
|
-
|
|
63
|
-
// Create a temporary div to hold the SVG
|
|
64
|
-
const tempDiv = document.createElement('div');
|
|
65
|
-
|
|
66
|
-
// Generate barcode using jsbarcode
|
|
67
|
-
JsBarcode(tempDiv, data, {
|
|
68
|
-
format: type.toUpperCase(),
|
|
69
|
-
width: options.width || 2,
|
|
70
|
-
height: options.height || 100,
|
|
71
|
-
displayValue: options.displayValue !== false,
|
|
72
|
-
fontSize: options.fontSize || 20,
|
|
73
|
-
textAlign: options.textAlign || 'center',
|
|
74
|
-
textPosition: options.textPosition || 'bottom',
|
|
75
|
-
textMargin: options.textMargin || 2,
|
|
76
|
-
background: options.background || '#ffffff',
|
|
77
|
-
lineColor: options.lineColor || '#000000',
|
|
78
|
-
margin: options.margin || 10,
|
|
79
|
-
xmlDocument: document,
|
|
80
|
-
...options,
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
return tempDiv.innerHTML;
|
|
84
|
-
} catch (error) {
|
|
85
|
-
throw new Error(`Failed to generate SVG barcode: ${error.message}`);
|
|
86
|
-
}
|
|
47
|
+
static svgSync(data, type = 'code128', options = {}) {
|
|
48
|
+
return BarcodeEncoder.toSvg(data, type, options);
|
|
87
49
|
}
|
|
88
50
|
|
|
89
51
|
/**
|
|
90
|
-
* Generate
|
|
52
|
+
* Generate a barcode as an HTML fragment containing an inline SVG
|
|
91
53
|
* @param {string} data - Data to encode
|
|
92
54
|
* @param {string} type - Barcode type
|
|
93
55
|
* @param {Object} options - Options
|
|
94
|
-
* @returns {string} HTML
|
|
56
|
+
* @returns {string} HTML markup
|
|
95
57
|
*/
|
|
96
58
|
static html(data, type = 'code128', options = {}) {
|
|
97
|
-
const svg =
|
|
98
|
-
return `<div class="barcode-
|
|
59
|
+
const svg = BarcodeEncoder.toSvg(data, type, options);
|
|
60
|
+
return `<div class="barcode" data-barcode-type="${type}">${svg}</div>`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Generate a barcode as an HTML fragment (alias of html)
|
|
65
|
+
* @param {string} data - Data to encode
|
|
66
|
+
* @param {string} type - Barcode type
|
|
67
|
+
* @param {Object} options - Options
|
|
68
|
+
* @returns {string} HTML markup
|
|
69
|
+
*/
|
|
70
|
+
static htmlSync(data, type = 'code128', options = {}) {
|
|
71
|
+
return this.html(data, type, options);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Draw a barcode onto an existing canvas element
|
|
76
|
+
* @param {HTMLCanvasElement} canvas - Target canvas
|
|
77
|
+
* @param {string} data - Data to encode
|
|
78
|
+
* @param {string} type - Barcode type
|
|
79
|
+
* @param {Object} options - Options
|
|
80
|
+
* @returns {HTMLCanvasElement} The canvas that was drawn on
|
|
81
|
+
*/
|
|
82
|
+
static toCanvas(canvas, data, type = 'code128', options = {}) {
|
|
83
|
+
return bwipjs.toCanvas(
|
|
84
|
+
canvas,
|
|
85
|
+
BarcodeEncoder.buildOptions(data, type, options)
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Generate a barcode as a PNG blob
|
|
91
|
+
* @param {string} data - Data to encode
|
|
92
|
+
* @param {string} type - Barcode type
|
|
93
|
+
* @param {Object} options - Options
|
|
94
|
+
* @returns {Promise<Blob>} PNG blob
|
|
95
|
+
*/
|
|
96
|
+
static png(data, type = 'code128', options = {}) {
|
|
97
|
+
requireDom('PNG generation');
|
|
98
|
+
|
|
99
|
+
const canvas = document.createElement('canvas');
|
|
100
|
+
this.toCanvas(canvas, data, type, options);
|
|
101
|
+
|
|
102
|
+
return new Promise((resolve, reject) => {
|
|
103
|
+
canvas.toBlob(blob => {
|
|
104
|
+
if (blob) {
|
|
105
|
+
resolve(blob);
|
|
106
|
+
} else {
|
|
107
|
+
reject(new Error('Failed to generate PNG blob'));
|
|
108
|
+
}
|
|
109
|
+
}, 'image/png');
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Generate a barcode as a data URL
|
|
115
|
+
* @param {string} data - Data to encode
|
|
116
|
+
* @param {string} type - Barcode type
|
|
117
|
+
* @param {Object} options - Options
|
|
118
|
+
* @returns {string} Data URL
|
|
119
|
+
*/
|
|
120
|
+
static dataUrl(data, type = 'code128', options = {}) {
|
|
121
|
+
requireDom('Data URL generation');
|
|
122
|
+
|
|
123
|
+
const canvas = document.createElement('canvas');
|
|
124
|
+
this.toCanvas(canvas, data, type, options);
|
|
125
|
+
return canvas.toDataURL('image/png');
|
|
99
126
|
}
|
|
100
127
|
|
|
101
128
|
/**
|
|
102
|
-
* Generate QR code
|
|
129
|
+
* Generate a QR code as a data URL
|
|
103
130
|
* @param {string} data - Data to encode
|
|
104
131
|
* @param {Object} options - Options
|
|
105
|
-
* @returns {Promise<
|
|
132
|
+
* @returns {Promise<string>} Data URL
|
|
106
133
|
*/
|
|
107
134
|
static async qrCode(data, options = {}) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
135
|
+
return QRCode.toDataURL(data, {
|
|
136
|
+
width: options.size || 300,
|
|
137
|
+
margin: options.margin === undefined ? 1 : options.margin,
|
|
138
|
+
errorCorrectionLevel: options.errorCorrectionLevel || 'M',
|
|
139
|
+
color: {
|
|
140
|
+
dark: options.foregroundColor || '#000000',
|
|
141
|
+
light: options.backgroundColor || '#ffffff',
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Generate a QR code as SVG markup
|
|
148
|
+
* @param {string} data - Data to encode
|
|
149
|
+
* @param {Object} options - Options
|
|
150
|
+
* @returns {Promise<string>} SVG markup
|
|
151
|
+
*/
|
|
152
|
+
static async qrCodeSvg(data, options = {}) {
|
|
153
|
+
return QRCode.toString(data, {
|
|
154
|
+
type: 'svg',
|
|
155
|
+
width: options.size || 300,
|
|
156
|
+
margin: options.margin === undefined ? 1 : options.margin,
|
|
157
|
+
errorCorrectionLevel: options.errorCorrectionLevel || 'M',
|
|
158
|
+
color: {
|
|
159
|
+
dark: options.foregroundColor || '#000000',
|
|
160
|
+
light: options.backgroundColor || '#ffffff',
|
|
161
|
+
},
|
|
162
|
+
});
|
|
131
163
|
}
|
|
132
164
|
|
|
133
165
|
/**
|
|
134
|
-
* Validate barcode data
|
|
166
|
+
* Validate barcode data
|
|
135
167
|
* @param {string} data - Data to validate
|
|
136
168
|
* @param {string} type - Barcode type
|
|
137
169
|
* @returns {Object} Validation result
|
|
138
170
|
*/
|
|
139
171
|
static validate(data, type) {
|
|
140
|
-
|
|
141
|
-
return {
|
|
142
|
-
valid: false,
|
|
143
|
-
error: 'Data must be a non-empty string',
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// Basic validation for common barcode types
|
|
148
|
-
switch (type.toLowerCase()) {
|
|
149
|
-
case 'code128':
|
|
150
|
-
if (!/^[\x00-\x7F]+$/.test(data)) {
|
|
151
|
-
return {
|
|
152
|
-
valid: false,
|
|
153
|
-
error: 'Code 128 supports ASCII characters only',
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
break;
|
|
157
|
-
case 'code39':
|
|
158
|
-
if (!/^[A-Z0-9\s\-\.\$\/\+\%]+$/.test(data)) {
|
|
159
|
-
return {
|
|
160
|
-
valid: false,
|
|
161
|
-
error: 'Code 39 supports characters: A-Z, 0-9, space, -.$/+%',
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
break;
|
|
165
|
-
case 'ean13':
|
|
166
|
-
if (!/^\d{12,13}$/.test(data)) {
|
|
167
|
-
return {
|
|
168
|
-
valid: false,
|
|
169
|
-
error: 'EAN-13 must be 12 or 13 digits',
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
break;
|
|
173
|
-
case 'qrcode':
|
|
174
|
-
if (data.length === 0) {
|
|
175
|
-
return {
|
|
176
|
-
valid: false,
|
|
177
|
-
error: 'QR Code data cannot be empty',
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
break;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return { valid: true };
|
|
172
|
+
return validator.validate(data, type);
|
|
184
173
|
}
|
|
185
174
|
|
|
186
175
|
/**
|
|
187
176
|
* Get supported barcode types
|
|
188
|
-
* @returns {
|
|
177
|
+
* @returns {string[]} Array of supported types
|
|
189
178
|
*/
|
|
190
179
|
static getBarcodeTypes() {
|
|
191
|
-
return
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
'code93',
|
|
202
|
-
'ean13',
|
|
203
|
-
'ean8',
|
|
204
|
-
'upca',
|
|
205
|
-
'upce',
|
|
206
|
-
'codabar',
|
|
207
|
-
'code11',
|
|
208
|
-
'msi',
|
|
209
|
-
'pharmazentral',
|
|
210
|
-
'interleaved25',
|
|
211
|
-
'standard25',
|
|
212
|
-
'qrcode',
|
|
213
|
-
'datamatrix',
|
|
214
|
-
'pdf417',
|
|
215
|
-
'aztec',
|
|
216
|
-
];
|
|
180
|
+
return BarcodeTypes.getAll();
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Get barcode type information
|
|
185
|
+
* @param {string} type - Barcode type
|
|
186
|
+
* @returns {Object|null} Type information
|
|
187
|
+
*/
|
|
188
|
+
static getBarcodeTypeInfo(type) {
|
|
189
|
+
return BarcodeTypes.getTypeInfo(type);
|
|
217
190
|
}
|
|
218
191
|
|
|
219
192
|
/**
|
|
220
|
-
* Get supported
|
|
221
|
-
* @returns {
|
|
193
|
+
* Get supported output formats for the browser build
|
|
194
|
+
* @returns {string[]} Array of supported formats
|
|
222
195
|
*/
|
|
223
196
|
static getRenderFormats() {
|
|
224
197
|
return ['png', 'svg', 'html'];
|
|
225
198
|
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Get information about an output format
|
|
202
|
+
* @param {string} format - Output format
|
|
203
|
+
* @returns {Object|null} Format information
|
|
204
|
+
*/
|
|
205
|
+
static getRenderFormatInfo(format) {
|
|
206
|
+
return RenderFormats.getFormatInfo(format);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Get the default render options
|
|
211
|
+
* @returns {Object} Default options
|
|
212
|
+
*/
|
|
213
|
+
static getDefaultOptions() {
|
|
214
|
+
return BarcodeEncoder.getDefaultOptions();
|
|
215
|
+
}
|
|
226
216
|
}
|
|
227
217
|
|
|
218
|
+
BrowserBarcodeGenerator.BarcodeTypes = BarcodeTypes;
|
|
219
|
+
BrowserBarcodeGenerator.BarcodeEncoder = BarcodeEncoder;
|
|
220
|
+
|
|
228
221
|
module.exports = BrowserBarcodeGenerator;
|