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/browser.js CHANGED
@@ -1,228 +1,221 @@
1
1
  /**
2
- * Browser-compatible version of Isahaq Barcode Generator
3
- * This version uses client-side libraries instead of Node.js modules
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
- // Browser-compatible QR code generation
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
- // Browser-compatible barcode generation using jsbarcode
10
- const JsBarcode = require('jsbarcode');
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 PNG barcode (browser-compatible)
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 {Promise<Buffer>} PNG buffer
34
+ * @returns {string} SVG markup
19
35
  */
20
- static async png(data, type = 'code128', options = {}) {
21
- try {
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 SVG barcode (browser-compatible)
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 string
45
+ * @returns {string} SVG markup
60
46
  */
61
- static svg(data, type = 'code128', options = {}) {
62
- try {
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 HTML barcode (browser-compatible)
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 string
56
+ * @returns {string} HTML markup
95
57
  */
96
58
  static html(data, type = 'code128', options = {}) {
97
- const svg = this.svg(data, type, options);
98
- return `<div class="barcode-container">${svg}</div>`;
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 (browser-compatible)
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<Buffer>} PNG buffer
132
+ * @returns {Promise<string>} Data URL
106
133
  */
107
134
  static async qrCode(data, options = {}) {
108
- try {
109
- const canvas = document.createElement('canvas');
110
- await QRCode.toCanvas(canvas, data, {
111
- width: options.size || 300,
112
- margin: options.margin || 10,
113
- color: {
114
- dark: options.foregroundColor || '#000000',
115
- light: options.backgroundColor || '#FFFFFF',
116
- },
117
- errorCorrectionLevel: options.errorCorrectionLevel || 'M',
118
- ...options,
119
- });
120
-
121
- return new Promise(resolve => {
122
- canvas.toBlob(blob => {
123
- const reader = new FileReader();
124
- reader.onload = () => resolve(Buffer.from(reader.result));
125
- reader.readAsArrayBuffer(blob);
126
- }, 'image/png');
127
- });
128
- } catch (error) {
129
- throw new Error(`Failed to generate QR code: ${error.message}`);
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 (browser-compatible)
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
- if (!data || typeof data !== 'string') {
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 {Array} Array of supported types
177
+ * @returns {string[]} Array of supported types
189
178
  */
190
179
  static getBarcodeTypes() {
191
- return [
192
- 'code128',
193
- 'code128a',
194
- 'code128b',
195
- 'code128c',
196
- 'code128auto',
197
- 'code39',
198
- 'code39extended',
199
- 'code39checksum',
200
- 'code39auto',
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 render formats
221
- * @returns {Array} Array of supported formats
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;