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.
@@ -1,352 +1,352 @@
1
- /**
2
- * Validator - Data validation for different barcode types
3
- */
4
-
5
- const { BarcodeTypes } = require('../types/BarcodeTypes');
6
-
7
- class Validator {
8
- constructor() {
9
- this.patterns = {
10
- // Numeric patterns
11
- numeric: /^[0-9]+$/,
12
- // Alphanumeric patterns
13
- alphanumeric: /^[A-Za-z0-9]+$/,
14
- // Code 39 pattern
15
- code39: /^[A-Z0-9\s\-\.\$\/\+\%]+$/,
16
- // Code 39 extended pattern
17
- code39extended: /^[\x00-\x7F]+$/,
18
- // EAN/UPC patterns
19
- ean13: /^[0-9]{12,13}$/,
20
- ean8: /^[0-9]{7,8}$/,
21
- upca: /^[0-9]{11,12}$/,
22
- upce: /^[0-9]{6,8}$/,
23
- // QR Code pattern (supports Unicode)
24
- qrcode: /^[\s\S]+$/,
25
- // Data Matrix pattern
26
- datamatrix: /^[\s\S]+$/,
27
- // PDF417 pattern
28
- pdf417: /^[\s\S]+$/,
29
- };
30
- }
31
-
32
- /**
33
- * Validate data for a specific barcode type
34
- * @param {string} data - The data to validate
35
- * @param {string} type - The barcode type
36
- * @returns {Object} Validation result
37
- */
38
- validate(data, type) {
39
- if (!data || typeof data !== 'string') {
40
- return {
41
- valid: false,
42
- error: 'Data must be a non-empty string',
43
- };
44
- }
45
-
46
- if (!BarcodeTypes.isValid(type)) {
47
- return {
48
- valid: false,
49
- error: `Invalid barcode type: ${type}`,
50
- };
51
- }
52
-
53
- // Get configuration for the barcode type
54
- const config = BarcodeTypes.getConfig(type);
55
-
56
- // Check length constraints
57
- if (data.length < config.minLength) {
58
- return {
59
- valid: false,
60
- error: `Data too short. Minimum length: ${config.minLength}`,
61
- };
62
- }
63
-
64
- if (data.length > config.maxLength) {
65
- return {
66
- valid: false,
67
- error: `Data too long. Maximum length: ${config.maxLength}`,
68
- };
69
- }
70
-
71
- // Type-specific validation
72
- const validationResult = this.validateByType(data, type);
73
- if (!validationResult.valid) {
74
- return validationResult;
75
- }
76
-
77
- return {
78
- valid: true,
79
- data,
80
- type,
81
- length: data.length,
82
- charset: config.charset,
83
- };
84
- }
85
-
86
- /**
87
- * Validate data by barcode type
88
- * @param {string} data - The data to validate
89
- * @param {string} type - The barcode type
90
- * @returns {Object} Validation result
91
- */
92
- validateByType(data, type) {
93
- switch (type) {
94
- case 'code128':
95
- case 'code128a':
96
- case 'code128b':
97
- case 'code128c':
98
- case 'code128auto':
99
- return this.validateCode128(data, type);
100
-
101
- case 'code39':
102
- case 'code39extended':
103
- case 'code39checksum':
104
- case 'code39auto':
105
- return this.validateCode39(data, type);
106
-
107
- case 'code93':
108
- return this.validateCode93(data);
109
-
110
- case 'ean13':
111
- return this.validateEAN13(data);
112
-
113
- case 'ean8':
114
- return this.validateEAN8(data);
115
-
116
- case 'upca':
117
- return this.validateUPCA(data);
118
-
119
- case 'upce':
120
- return this.validateUPCE(data);
121
-
122
- case 'qrcode':
123
- return this.validateQRCode(data);
124
-
125
- case 'datamatrix':
126
- return this.validateDataMatrix(data);
127
-
128
- case 'pdf417':
129
- return this.validatePDF417(data);
130
-
131
- default:
132
- // For other types, just check if data is not empty
133
- return {
134
- valid: data.length > 0,
135
- error: data.length === 0 ? 'Data cannot be empty' : null,
136
- };
137
- }
138
- }
139
-
140
- /**
141
- * Validate Code 128 data
142
- * @param {string} data - The data to validate
143
- * @param {string} type - The Code 128 variant
144
- * @returns {Object} Validation result
145
- */
146
- validateCode128(data) {
147
- // Code 128 supports ASCII characters
148
- if (!/^[\x00-\x7F]+$/.test(data)) {
149
- return {
150
- valid: false,
151
- error: 'Code 128 supports ASCII characters only',
152
- };
153
- }
154
-
155
- return { valid: true };
156
- }
157
-
158
- /**
159
- * Validate Code 39 data
160
- * @param {string} data - The data to validate
161
- * @param {string} type - The Code 39 variant
162
- * @returns {Object} Validation result
163
- */
164
- validateCode39(data, type) {
165
- if (type === 'code39extended') {
166
- // Extended Code 39 supports full ASCII
167
- if (!/^[\x00-\x7F]+$/.test(data)) {
168
- return {
169
- valid: false,
170
- error: 'Extended Code 39 supports ASCII characters only',
171
- };
172
- }
173
- } else {
174
- // Standard Code 39 supports limited character set
175
- if (!this.patterns.code39.test(data)) {
176
- return {
177
- valid: false,
178
- error: 'Code 39 supports characters: A-Z, 0-9, space, -.$/+%',
179
- };
180
- }
181
- }
182
-
183
- return { valid: true };
184
- }
185
-
186
- /**
187
- * Validate Code 93 data
188
- * @param {string} data - The data to validate
189
- * @returns {Object} Validation result
190
- */
191
- validateCode93(data) {
192
- if (!this.patterns.alphanumeric.test(data)) {
193
- return {
194
- valid: false,
195
- error: 'Code 93 supports alphanumeric characters only',
196
- };
197
- }
198
-
199
- return { valid: true };
200
- }
201
-
202
- /**
203
- * Validate EAN-13 data
204
- * @param {string} data - The data to validate
205
- * @returns {Object} Validation result
206
- */
207
- validateEAN13(data) {
208
- if (!this.patterns.ean13.test(data)) {
209
- return {
210
- valid: false,
211
- error: 'EAN-13 must be 12 or 13 digits',
212
- };
213
- }
214
-
215
- // Validate check digit if 13 digits provided
216
- if (data.length === 13) {
217
- const checkDigit = this.calculateEANCheckDigit(data.substring(0, 12));
218
- if (parseInt(data[12]) !== checkDigit) {
219
- return {
220
- valid: false,
221
- error: 'Invalid EAN-13 check digit',
222
- };
223
- }
224
- }
225
-
226
- return { valid: true };
227
- }
228
-
229
- /**
230
- * Validate EAN-8 data
231
- * @param {string} data - The data to validate
232
- * @returns {Object} Validation result
233
- */
234
- validateEAN8(data) {
235
- if (!this.patterns.ean8.test(data)) {
236
- return {
237
- valid: false,
238
- error: 'EAN-8 must be 7 or 8 digits',
239
- };
240
- }
241
-
242
- // Validate check digit if 8 digits provided
243
- if (data.length === 8) {
244
- const checkDigit = this.calculateEANCheckDigit(data.substring(0, 7));
245
- if (parseInt(data[7]) !== checkDigit) {
246
- return {
247
- valid: false,
248
- error: 'Invalid EAN-8 check digit',
249
- };
250
- }
251
- }
252
-
253
- return { valid: true };
254
- }
255
-
256
- /**
257
- * Validate UPC-A data
258
- * @param {string} data - The data to validate
259
- * @returns {Object} Validation result
260
- */
261
- validateUPCA(data) {
262
- if (!this.patterns.upca.test(data)) {
263
- return {
264
- valid: false,
265
- error: 'UPC-A must be 11 or 12 digits',
266
- };
267
- }
268
-
269
- return { valid: true };
270
- }
271
-
272
- /**
273
- * Validate UPC-E data
274
- * @param {string} data - The data to validate
275
- * @returns {Object} Validation result
276
- */
277
- validateUPCE(data) {
278
- if (!this.patterns.upce.test(data)) {
279
- return {
280
- valid: false,
281
- error: 'UPC-E must be 6 to 8 digits',
282
- };
283
- }
284
-
285
- return { valid: true };
286
- }
287
-
288
- /**
289
- * Validate QR Code data
290
- * @param {string} data - The data to validate
291
- * @returns {Object} Validation result
292
- */
293
- validateQRCode(data) {
294
- // QR Code supports Unicode, so we just check if it's not empty
295
- if (data.length === 0) {
296
- return {
297
- valid: false,
298
- error: 'QR Code data cannot be empty',
299
- };
300
- }
301
-
302
- return { valid: true };
303
- }
304
-
305
- /**
306
- * Validate Data Matrix data
307
- * @param {string} data - The data to validate
308
- * @returns {Object} Validation result
309
- */
310
- validateDataMatrix(data) {
311
- if (data.length === 0) {
312
- return {
313
- valid: false,
314
- error: 'Data Matrix data cannot be empty',
315
- };
316
- }
317
-
318
- return { valid: true };
319
- }
320
-
321
- /**
322
- * Validate PDF417 data
323
- * @param {string} data - The data to validate
324
- * @returns {Object} Validation result
325
- */
326
- validatePDF417(data) {
327
- if (data.length === 0) {
328
- return {
329
- valid: false,
330
- error: 'PDF417 data cannot be empty',
331
- };
332
- }
333
-
334
- return { valid: true };
335
- }
336
-
337
- /**
338
- * Calculate EAN check digit
339
- * @param {string} data - The data without check digit
340
- * @returns {number} Check digit
341
- */
342
- calculateEANCheckDigit(data) {
343
- let sum = 0;
344
- for (let i = 0; i < data.length; i++) {
345
- const digit = parseInt(data[i]);
346
- sum += i % 2 === 0 ? digit : digit * 3;
347
- }
348
- return (10 - (sum % 10)) % 10;
349
- }
350
- }
351
-
352
- module.exports = { Validator };
1
+ /**
2
+ * Validator - Data validation for different barcode types
3
+ */
4
+
5
+ const { BarcodeTypes } = require('../types/BarcodeTypes');
6
+
7
+ class Validator {
8
+ constructor() {
9
+ this.patterns = {
10
+ // Numeric patterns
11
+ numeric: /^[0-9]+$/,
12
+ // Alphanumeric patterns
13
+ alphanumeric: /^[A-Za-z0-9]+$/,
14
+ // Code 39 pattern
15
+ code39: /^[A-Z0-9\s\-\.\$\/\+\%]+$/,
16
+ // Code 39 extended pattern
17
+ code39extended: /^[\x00-\x7F]+$/,
18
+ // EAN/UPC patterns
19
+ ean13: /^[0-9]{12,13}$/,
20
+ ean8: /^[0-9]{7,8}$/,
21
+ upca: /^[0-9]{11,12}$/,
22
+ upce: /^[0-9]{6,8}$/,
23
+ // QR Code pattern (supports Unicode)
24
+ qrcode: /^[\s\S]+$/,
25
+ // Data Matrix pattern
26
+ datamatrix: /^[\s\S]+$/,
27
+ // PDF417 pattern
28
+ pdf417: /^[\s\S]+$/,
29
+ };
30
+ }
31
+
32
+ /**
33
+ * Validate data for a specific barcode type
34
+ * @param {string} data - The data to validate
35
+ * @param {string} type - The barcode type
36
+ * @returns {Object} Validation result
37
+ */
38
+ validate(data, type) {
39
+ if (!data || typeof data !== 'string') {
40
+ return {
41
+ valid: false,
42
+ error: 'Data must be a non-empty string',
43
+ };
44
+ }
45
+
46
+ if (!BarcodeTypes.isValid(type)) {
47
+ return {
48
+ valid: false,
49
+ error: `Invalid barcode type: ${type}`,
50
+ };
51
+ }
52
+
53
+ // Get configuration for the barcode type
54
+ const config = BarcodeTypes.getConfig(type);
55
+
56
+ // Check length constraints
57
+ if (data.length < config.minLength) {
58
+ return {
59
+ valid: false,
60
+ error: `Data too short. Minimum length: ${config.minLength}`,
61
+ };
62
+ }
63
+
64
+ if (data.length > config.maxLength) {
65
+ return {
66
+ valid: false,
67
+ error: `Data too long. Maximum length: ${config.maxLength}`,
68
+ };
69
+ }
70
+
71
+ // Type-specific validation
72
+ const validationResult = this.validateByType(data, type);
73
+ if (!validationResult.valid) {
74
+ return validationResult;
75
+ }
76
+
77
+ return {
78
+ valid: true,
79
+ data,
80
+ type,
81
+ length: data.length,
82
+ charset: config.charset,
83
+ };
84
+ }
85
+
86
+ /**
87
+ * Validate data by barcode type
88
+ * @param {string} data - The data to validate
89
+ * @param {string} type - The barcode type
90
+ * @returns {Object} Validation result
91
+ */
92
+ validateByType(data, type) {
93
+ switch (type) {
94
+ case 'code128':
95
+ case 'code128a':
96
+ case 'code128b':
97
+ case 'code128c':
98
+ case 'code128auto':
99
+ return this.validateCode128(data, type);
100
+
101
+ case 'code39':
102
+ case 'code39extended':
103
+ case 'code39checksum':
104
+ case 'code39auto':
105
+ return this.validateCode39(data, type);
106
+
107
+ case 'code93':
108
+ return this.validateCode93(data);
109
+
110
+ case 'ean13':
111
+ return this.validateEAN13(data);
112
+
113
+ case 'ean8':
114
+ return this.validateEAN8(data);
115
+
116
+ case 'upca':
117
+ return this.validateUPCA(data);
118
+
119
+ case 'upce':
120
+ return this.validateUPCE(data);
121
+
122
+ case 'qrcode':
123
+ return this.validateQRCode(data);
124
+
125
+ case 'datamatrix':
126
+ return this.validateDataMatrix(data);
127
+
128
+ case 'pdf417':
129
+ return this.validatePDF417(data);
130
+
131
+ default:
132
+ // For other types, just check if data is not empty
133
+ return {
134
+ valid: data.length > 0,
135
+ error: data.length === 0 ? 'Data cannot be empty' : null,
136
+ };
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Validate Code 128 data
142
+ * @param {string} data - The data to validate
143
+ * @param {string} type - The Code 128 variant
144
+ * @returns {Object} Validation result
145
+ */
146
+ validateCode128(data) {
147
+ // Code 128 supports ASCII characters
148
+ if (!/^[\x00-\x7F]+$/.test(data)) {
149
+ return {
150
+ valid: false,
151
+ error: 'Code 128 supports ASCII characters only',
152
+ };
153
+ }
154
+
155
+ return { valid: true };
156
+ }
157
+
158
+ /**
159
+ * Validate Code 39 data
160
+ * @param {string} data - The data to validate
161
+ * @param {string} type - The Code 39 variant
162
+ * @returns {Object} Validation result
163
+ */
164
+ validateCode39(data, type) {
165
+ if (type === 'code39extended') {
166
+ // Extended Code 39 supports full ASCII
167
+ if (!/^[\x00-\x7F]+$/.test(data)) {
168
+ return {
169
+ valid: false,
170
+ error: 'Extended Code 39 supports ASCII characters only',
171
+ };
172
+ }
173
+ } else {
174
+ // Standard Code 39 supports limited character set
175
+ if (!this.patterns.code39.test(data)) {
176
+ return {
177
+ valid: false,
178
+ error: 'Code 39 supports characters: A-Z, 0-9, space, -.$/+%',
179
+ };
180
+ }
181
+ }
182
+
183
+ return { valid: true };
184
+ }
185
+
186
+ /**
187
+ * Validate Code 93 data
188
+ * @param {string} data - The data to validate
189
+ * @returns {Object} Validation result
190
+ */
191
+ validateCode93(data) {
192
+ if (!this.patterns.alphanumeric.test(data)) {
193
+ return {
194
+ valid: false,
195
+ error: 'Code 93 supports alphanumeric characters only',
196
+ };
197
+ }
198
+
199
+ return { valid: true };
200
+ }
201
+
202
+ /**
203
+ * Validate EAN-13 data
204
+ * @param {string} data - The data to validate
205
+ * @returns {Object} Validation result
206
+ */
207
+ validateEAN13(data) {
208
+ if (!this.patterns.ean13.test(data)) {
209
+ return {
210
+ valid: false,
211
+ error: 'EAN-13 must be 12 or 13 digits',
212
+ };
213
+ }
214
+
215
+ // Validate check digit if 13 digits provided
216
+ if (data.length === 13) {
217
+ const checkDigit = this.calculateEANCheckDigit(data.substring(0, 12));
218
+ if (parseInt(data[12]) !== checkDigit) {
219
+ return {
220
+ valid: false,
221
+ error: 'Invalid EAN-13 check digit',
222
+ };
223
+ }
224
+ }
225
+
226
+ return { valid: true };
227
+ }
228
+
229
+ /**
230
+ * Validate EAN-8 data
231
+ * @param {string} data - The data to validate
232
+ * @returns {Object} Validation result
233
+ */
234
+ validateEAN8(data) {
235
+ if (!this.patterns.ean8.test(data)) {
236
+ return {
237
+ valid: false,
238
+ error: 'EAN-8 must be 7 or 8 digits',
239
+ };
240
+ }
241
+
242
+ // Validate check digit if 8 digits provided
243
+ if (data.length === 8) {
244
+ const checkDigit = this.calculateEANCheckDigit(data.substring(0, 7));
245
+ if (parseInt(data[7]) !== checkDigit) {
246
+ return {
247
+ valid: false,
248
+ error: 'Invalid EAN-8 check digit',
249
+ };
250
+ }
251
+ }
252
+
253
+ return { valid: true };
254
+ }
255
+
256
+ /**
257
+ * Validate UPC-A data
258
+ * @param {string} data - The data to validate
259
+ * @returns {Object} Validation result
260
+ */
261
+ validateUPCA(data) {
262
+ if (!this.patterns.upca.test(data)) {
263
+ return {
264
+ valid: false,
265
+ error: 'UPC-A must be 11 or 12 digits',
266
+ };
267
+ }
268
+
269
+ return { valid: true };
270
+ }
271
+
272
+ /**
273
+ * Validate UPC-E data
274
+ * @param {string} data - The data to validate
275
+ * @returns {Object} Validation result
276
+ */
277
+ validateUPCE(data) {
278
+ if (!this.patterns.upce.test(data)) {
279
+ return {
280
+ valid: false,
281
+ error: 'UPC-E must be 6 to 8 digits',
282
+ };
283
+ }
284
+
285
+ return { valid: true };
286
+ }
287
+
288
+ /**
289
+ * Validate QR Code data
290
+ * @param {string} data - The data to validate
291
+ * @returns {Object} Validation result
292
+ */
293
+ validateQRCode(data) {
294
+ // QR Code supports Unicode, so we just check if it's not empty
295
+ if (data.length === 0) {
296
+ return {
297
+ valid: false,
298
+ error: 'QR Code data cannot be empty',
299
+ };
300
+ }
301
+
302
+ return { valid: true };
303
+ }
304
+
305
+ /**
306
+ * Validate Data Matrix data
307
+ * @param {string} data - The data to validate
308
+ * @returns {Object} Validation result
309
+ */
310
+ validateDataMatrix(data) {
311
+ if (data.length === 0) {
312
+ return {
313
+ valid: false,
314
+ error: 'Data Matrix data cannot be empty',
315
+ };
316
+ }
317
+
318
+ return { valid: true };
319
+ }
320
+
321
+ /**
322
+ * Validate PDF417 data
323
+ * @param {string} data - The data to validate
324
+ * @returns {Object} Validation result
325
+ */
326
+ validatePDF417(data) {
327
+ if (data.length === 0) {
328
+ return {
329
+ valid: false,
330
+ error: 'PDF417 data cannot be empty',
331
+ };
332
+ }
333
+
334
+ return { valid: true };
335
+ }
336
+
337
+ /**
338
+ * Calculate EAN check digit
339
+ * @param {string} data - The data without check digit
340
+ * @returns {number} Check digit
341
+ */
342
+ calculateEANCheckDigit(data) {
343
+ let sum = 0;
344
+ for (let i = 0; i < data.length; i++) {
345
+ const digit = parseInt(data[i]);
346
+ sum += i % 2 === 0 ? digit : digit * 3;
347
+ }
348
+ return (10 - (sum % 10)) % 10;
349
+ }
350
+ }
351
+
352
+ module.exports = { Validator };