btrz-liquid-templates 1.10.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/docs/index.md +6 -3
- package/package.json +11 -11
- package/src/barcode-generator.js +20 -0
- package/src/barcode-types.js +133 -0
- package/src/barcode.js +8 -13
- package/test/barcode-equivalence-test.js +63 -0
- package/test/barcode-test.js +44 -0
- package/test/barcode-types-test.js +61 -0
- package/test/fixtures/barcode-sample-content.js +100 -0
- package/test/fixtures/generate-legacy-barcodes.js +158 -0
- package/test/fixtures/legacy-barcodes/azrune-1.png +0 -0
- package/test/fixtures/legacy-barcodes/aztec-AZTEC.png +0 -0
- package/test/fixtures/legacy-barcodes/c25iata-1234567.png +0 -0
- package/test/fixtures/legacy-barcodes/c25ind-1234567.png +0 -0
- package/test/fixtures/legacy-barcodes/c25inter-1234567890.png +0 -0
- package/test/fixtures/legacy-barcodes/c25logic-1234567.png +0 -0
- package/test/fixtures/legacy-barcodes/c25matrix-1234567.png +0 -0
- package/test/fixtures/legacy-barcodes/channel-01.png +0 -0
- package/test/fixtures/legacy-barcodes/codabar-A123456A.png +0 -0
- package/test/fixtures/legacy-barcodes/codablockf-CODABLOCK.png +0 -0
- package/test/fixtures/legacy-barcodes/code11-1234.png +0 -0
- package/test/fixtures/legacy-barcodes/code128-1234.png +0 -0
- package/test/fixtures/legacy-barcodes/code128b-1234.png +0 -0
- package/test/fixtures/legacy-barcodes/code16k-1234.png +0 -0
- package/test/fixtures/legacy-barcodes/code32-12345678.png +0 -0
- package/test/fixtures/legacy-barcodes/code39-ABC123.png +0 -0
- package/test/fixtures/legacy-barcodes/code49-1234.png +0 -0
- package/test/fixtures/legacy-barcodes/code93-1234.png +0 -0
- package/test/fixtures/legacy-barcodes/codeone-1234.png +0 -0
- package/test/fixtures/legacy-barcodes/daft-DAFT.png +0 -0
- package/test/fixtures/legacy-barcodes/datamatrix-DATAMATRIX.png +0 -0
- package/test/fixtures/legacy-barcodes/dotcode-DOTCODE.png +0 -0
- package/test/fixtures/legacy-barcodes/dpident-12345678901.png +0 -0
- package/test/fixtures/legacy-barcodes/dpleit-1234567890123.png +0 -0
- package/test/fixtures/legacy-barcodes/ean128-_01_09501101530003.png +0 -0
- package/test/fixtures/legacy-barcodes/ean14-1234567890123.png +0 -0
- package/test/fixtures/legacy-barcodes/eanx-5901234123457.png +0 -0
- package/test/fixtures/legacy-barcodes/eanx_chk-5901234123457.png +0 -0
- package/test/fixtures/legacy-barcodes/excode39-ABC_123.png +0 -0
- package/test/fixtures/legacy-barcodes/flat-1.png +0 -0
- package/test/fixtures/legacy-barcodes/generation-failures.json +1 -0
- package/test/fixtures/legacy-barcodes/hanxin-HANXIN.png +0 -0
- package/test/fixtures/legacy-barcodes/hibc_128-_ABC1234ABC1234_0123456789012.png +0 -0
- package/test/fixtures/legacy-barcodes/hibc_39-_ABC1234ABC1234_0123456789012.png +0 -0
- package/test/fixtures/legacy-barcodes/hibc_aztec-_ABC1234ABC1234_0123456789012.png +0 -0
- package/test/fixtures/legacy-barcodes/hibc_dm-_ABC1234ABC1234_0123456789012.png +0 -0
- package/test/fixtures/legacy-barcodes/hibc_micpdf-_ABC1234ABC1234_0123456789012.png +0 -0
- package/test/fixtures/legacy-barcodes/hibc_pdf-_ABC1234ABC1234_0123456789012.png +0 -0
- package/test/fixtures/legacy-barcodes/hibc_qr-_ABC1234ABC1234_0123456789012.png +0 -0
- package/test/fixtures/legacy-barcodes/isbnx-9780306406157.png +0 -0
- package/test/fixtures/legacy-barcodes/itf14-1234567890123.png +0 -0
- package/test/fixtures/legacy-barcodes/japanpost-12345678901.png +0 -0
- package/test/fixtures/legacy-barcodes/kix-15400171583802.png +0 -0
- package/test/fixtures/legacy-barcodes/logmars-ABC123.png +0 -0
- package/test/fixtures/legacy-barcodes/manifest.json +1142 -0
- package/test/fixtures/legacy-barcodes/maxicode-1234567890123456789012345678901234.png +0 -0
- package/test/fixtures/legacy-barcodes/micropdf417-MICROPDF.png +0 -0
- package/test/fixtures/legacy-barcodes/microqr-MICROQR.png +0 -0
- package/test/fixtures/legacy-barcodes/msi_plessey-123456.png +0 -0
- package/test/fixtures/legacy-barcodes/nve18-12345678901234567.png +0 -0
- package/test/fixtures/legacy-barcodes/pdf417-PDF417.png +0 -0
- package/test/fixtures/legacy-barcodes/pdf417trunc-PDF417.png +0 -0
- package/test/fixtures/legacy-barcodes/pharma-123.png +0 -0
- package/test/fixtures/legacy-barcodes/pharma_two-123456.png +0 -0
- package/test/fixtures/legacy-barcodes/planet-01234567890.png +0 -0
- package/test/fixtures/legacy-barcodes/plessey-1234567890.png +0 -0
- package/test/fixtures/legacy-barcodes/postnet-01234.png +0 -0
- package/test/fixtures/legacy-barcodes/pzn-123456.png +0 -0
- package/test/fixtures/legacy-barcodes/qrcode-hello_world.png +0 -0
- package/test/fixtures/legacy-barcodes/rm4scc-W1J0TRQ.png +0 -0
- package/test/fixtures/legacy-barcodes/rss14-0123456789051.png +0 -0
- package/test/fixtures/legacy-barcodes/rss14stack-0123456789051.png +0 -0
- package/test/fixtures/legacy-barcodes/rss14stack_omni-0123456789051.png +0 -0
- package/test/fixtures/legacy-barcodes/rss_exp-_01_09501101530003.png +0 -0
- package/test/fixtures/legacy-barcodes/rss_ltd-0123456789051.png +0 -0
- package/test/fixtures/legacy-barcodes/telepen-Telepen.png +0 -0
- package/test/fixtures/legacy-barcodes/telepen_num-123456.png +0 -0
- package/test/fixtures/legacy-barcodes/ultra-ULTRA.png +0 -0
- package/test/fixtures/legacy-barcodes/upca-012345678905.png +0 -0
- package/test/fixtures/legacy-barcodes/upca_chk-012345678905.png +0 -0
- package/test/fixtures/legacy-barcodes/upce-0123456.png +0 -0
- package/test/fixtures/symbology-type-names.js +95 -0
- package/test/helpers/barcode-decode.js +30 -0
- package/test/helpers/generate-bwip-test-png.js +21 -0
- package/test/index-test.js +59 -41
package/docs/index.md
CHANGED
|
@@ -5,7 +5,7 @@ layout: default
|
|
|
5
5
|
|
|
6
6
|
Create pdf documents from liquid templates.
|
|
7
7
|
|
|
8
|
-
This library uses [LiquidJS](https://liquidjs.com/), [
|
|
8
|
+
This library uses [LiquidJS](https://liquidjs.com/), [bwip-js](https://github.com/metafloor/bwip-js), [Bz-Date](https://www.npmjs.com/package/bz-date), [btrz-formatter](https://www.npmjs.com/package/btrz-formatter) and link them together while adding some helpers to easily generate PDFs from templates.
|
|
9
9
|
|
|
10
10
|
The vesion of PDFMake has been inlined and modified to allow for text rotation.
|
|
11
11
|
|
|
@@ -286,8 +286,11 @@ It will use the value given and use generate a 'code11' barcode with a height of
|
|
|
286
286
|
|
|
287
287
|
### Supported types
|
|
288
288
|
|
|
289
|
-
|
|
290
|
-
|
|
289
|
+
The `{% barcode %}` tag accepts legacy Symbology-style type names and maps them to [bwip-js](https://github.com/metafloor/bwip-js) barcode identifiers. Common examples include `code128`, `code11`, `code39`, `qrcode`, `pdf417`, and `datamatrix`.
|
|
290
|
+
|
|
291
|
+
The following legacy type names are not supported and will throw an explicit error: `gridmatrix`, `koreapost`, `upnqr`, and `vin`.
|
|
292
|
+
|
|
293
|
+
While barcode generation supports QR codes, PDFMake also had support for QR natively and we recommend it for QR-specific use cases.
|
|
291
294
|
|
|
292
295
|
* ## httpImg
|
|
293
296
|
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "btrz-liquid-templates",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Extension and helpers for liquid templates to deal with our data and other things we need to encapsulate",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"tdd": "node --test --watch test
|
|
8
|
-
"test": "node --test test
|
|
7
|
+
"tdd": "node --test --watch test/*-test.js",
|
|
8
|
+
"test": "node --test test/*-test.js",
|
|
9
9
|
"preversion": "npm test",
|
|
10
10
|
"postversion": "git push origin main && git push --tags",
|
|
11
11
|
"version": "git tag $1"
|
|
@@ -21,17 +21,17 @@
|
|
|
21
21
|
},
|
|
22
22
|
"homepage": "https://github.com/Betterez/btrz-liquid-templates#readme",
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"axios": "1.
|
|
25
|
-
"btrz-formatter": "1.
|
|
26
|
-
"
|
|
27
|
-
"
|
|
24
|
+
"axios": "1.18.1",
|
|
25
|
+
"btrz-formatter": "1.7.0",
|
|
26
|
+
"bwip-js": "^4.11.2",
|
|
27
|
+
"bz-date": "2.2.0",
|
|
28
|
+
"liquidjs": "10.27.1",
|
|
28
29
|
"moment": "2.30.1",
|
|
29
|
-
"moment-timezone": "0.6.
|
|
30
|
-
"symbology": "4.0.2",
|
|
30
|
+
"moment-timezone": "0.6.2",
|
|
31
31
|
"written-number": "0.11.1"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"
|
|
35
|
-
"
|
|
34
|
+
"@undecaf/zbar-wasm": "^0.11.0",
|
|
35
|
+
"pngjs": "^7.0.0"
|
|
36
36
|
}
|
|
37
37
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const bwipjs = require("bwip-js");
|
|
2
|
+
const {resolveBarcodeType} = require("./barcode-types.js");
|
|
3
|
+
|
|
4
|
+
async function generateBarcodePng({type, content, height}) {
|
|
5
|
+
const bcid = resolveBarcodeType(type);
|
|
6
|
+
const pngBuffer = await bwipjs.toBuffer({
|
|
7
|
+
bcid,
|
|
8
|
+
text: String(content),
|
|
9
|
+
scale: 2,
|
|
10
|
+
height: Number(height) || 30,
|
|
11
|
+
includetext: false,
|
|
12
|
+
backgroundcolor: "FFFFFF"
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
return `data:image/png;base64,${pngBuffer.toString("base64")}`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = {
|
|
19
|
+
generateBarcodePng
|
|
20
|
+
};
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
const UNSUPPORTED_TYPES = new Set([
|
|
2
|
+
"GRIDMATRIX",
|
|
3
|
+
"KOREAPOST",
|
|
4
|
+
"UPNQR",
|
|
5
|
+
"VIN"
|
|
6
|
+
]);
|
|
7
|
+
|
|
8
|
+
const SYMBLOGY_TO_BWIP = {
|
|
9
|
+
AUSPOST: "auspost",
|
|
10
|
+
AUSREDIRECT: "auspost",
|
|
11
|
+
AUSREPLY: "auspost",
|
|
12
|
+
AUSROUTE: "auspost",
|
|
13
|
+
AZRUNE: "aztecrune",
|
|
14
|
+
AZTEC: "azteccode",
|
|
15
|
+
C25IATA: "iata2of5",
|
|
16
|
+
C25IND: "industrial2of5",
|
|
17
|
+
C25INTER: "interleaved2of5",
|
|
18
|
+
C25LOGIC: "datalogic2of5",
|
|
19
|
+
C25MATRIX: "matrix2of5",
|
|
20
|
+
CHANNEL: "channelcode",
|
|
21
|
+
CODABAR: "rationalizedCodabar",
|
|
22
|
+
CODABLOCKF: "codablockf",
|
|
23
|
+
CODE11: "code11",
|
|
24
|
+
CODE128: "code128",
|
|
25
|
+
CODE128B: "code128",
|
|
26
|
+
CODE16K: "code16k",
|
|
27
|
+
CODE32: "code32",
|
|
28
|
+
CODE39: "code39",
|
|
29
|
+
CODE49: "code49",
|
|
30
|
+
CODE93: "code93",
|
|
31
|
+
CODEONE: "codeone",
|
|
32
|
+
DAFT: "daft",
|
|
33
|
+
DATAMATRIX: "datamatrix",
|
|
34
|
+
DOTCODE: "dotcode",
|
|
35
|
+
DPIDENT: "identcode",
|
|
36
|
+
DPLEIT: "leitcode",
|
|
37
|
+
EAN128: "gs1-128",
|
|
38
|
+
EAN128_CC: "gs1-128composite",
|
|
39
|
+
EAN14: "ean14",
|
|
40
|
+
EANX: "ean13",
|
|
41
|
+
EANX_CC: "ean13composite",
|
|
42
|
+
EANX_CHK: "ean13",
|
|
43
|
+
EXCODE39: "code39ext",
|
|
44
|
+
FIM: "flattermarken",
|
|
45
|
+
FLAT: "flattermarken",
|
|
46
|
+
HANXIN: "hanxin",
|
|
47
|
+
HIBC_128: "hibccode128",
|
|
48
|
+
HIBC_39: "hibccode39",
|
|
49
|
+
HIBC_AZTEC: "hibcazteccode",
|
|
50
|
+
HIBC_DM: "hibcdatamatrix",
|
|
51
|
+
HIBC_MICPDF: "hibcmicropdf417",
|
|
52
|
+
HIBC_PDF: "hibcpdf417",
|
|
53
|
+
HIBC_QR: "hibcqrcode",
|
|
54
|
+
ISBNX: "isbn",
|
|
55
|
+
ITF14: "itf14",
|
|
56
|
+
JAPANPOST: "japanpost",
|
|
57
|
+
KIX: "kix",
|
|
58
|
+
LOGMARS: "code39",
|
|
59
|
+
MAILMARK: "mailmark",
|
|
60
|
+
MAXICODE: "maxicode",
|
|
61
|
+
MICROPDF417: "micropdf417",
|
|
62
|
+
MICROQR: "microqrcode",
|
|
63
|
+
MSI_PLESSEY: "msi",
|
|
64
|
+
NVE18: "sscc18",
|
|
65
|
+
ONECODE: "onecode",
|
|
66
|
+
PDF417: "pdf417",
|
|
67
|
+
PDF417TRUNC: "pdf417compact",
|
|
68
|
+
PHARMA: "pharmacode",
|
|
69
|
+
PHARMA_TWO: "pharmacode2",
|
|
70
|
+
PLANET: "planet",
|
|
71
|
+
PLESSEY: "plessey",
|
|
72
|
+
POSTNET: "postnet",
|
|
73
|
+
PZN: "pzn",
|
|
74
|
+
QRCODE: "qrcode",
|
|
75
|
+
RM4SCC: "royalmail",
|
|
76
|
+
RSS14: "databaromni",
|
|
77
|
+
RSS14STACK: "databarstacked",
|
|
78
|
+
RSS14STACK_CC: "databarstackedcomposite",
|
|
79
|
+
RSS14STACK_OMNI: "databarstackedomni",
|
|
80
|
+
RSS14_CC: "databaromnicomposite",
|
|
81
|
+
RSS14_OMNI_CC: "databarstackedomnicomposite",
|
|
82
|
+
RSS_EXP: "databarexpanded",
|
|
83
|
+
RSS_EXPSTACK: "databarexpandedstacked",
|
|
84
|
+
RSS_EXPSTACK_CC: "databarexpandedstackedcomposite",
|
|
85
|
+
RSS_EXP_CC: "databarexpandedcomposite",
|
|
86
|
+
RSS_LTD: "databarlimited",
|
|
87
|
+
RSS_LTD_CC: "databarlimitedcomposite",
|
|
88
|
+
TELEPEN: "telepen",
|
|
89
|
+
TELEPEN_NUM: "telepennumeric",
|
|
90
|
+
ULTRA: "ultracode",
|
|
91
|
+
UPCA: "upca",
|
|
92
|
+
UPCA_CC: "upcacomposite",
|
|
93
|
+
UPCA_CHK: "upca",
|
|
94
|
+
UPCE: "upce",
|
|
95
|
+
UPCE_CC: "upcecomposite",
|
|
96
|
+
UPCE_CHK: "upce"
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
function normalizeBarcodeType(type) {
|
|
100
|
+
return String(type || "code128").toUpperCase();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function resolveBarcodeType(type) {
|
|
104
|
+
const normalized = normalizeBarcodeType(type);
|
|
105
|
+
|
|
106
|
+
if (UNSUPPORTED_TYPES.has(normalized)) {
|
|
107
|
+
throw new Error(`Unsupported barcode type: ${normalized}`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const bcid = SYMBLOGY_TO_BWIP[normalized];
|
|
111
|
+
if (!bcid) {
|
|
112
|
+
throw new Error(`Unsupported barcode type: ${normalized}`);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return bcid;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function listSupportedSymbologyTypes() {
|
|
119
|
+
return Object.keys(SYMBLOGY_TO_BWIP).sort();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function listUnsupportedSymbologyTypes() {
|
|
123
|
+
return [...UNSUPPORTED_TYPES].sort();
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
module.exports = {
|
|
127
|
+
UNSUPPORTED_TYPES,
|
|
128
|
+
SYMBLOGY_TO_BWIP,
|
|
129
|
+
normalizeBarcodeType,
|
|
130
|
+
resolveBarcodeType,
|
|
131
|
+
listSupportedSymbologyTypes,
|
|
132
|
+
listUnsupportedSymbologyTypes
|
|
133
|
+
};
|
package/src/barcode.js
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
const {
|
|
2
|
-
|
|
3
|
-
function getCode(code) {
|
|
4
|
-
return SymbologyType[code.toUpperCase()];
|
|
5
|
-
}
|
|
1
|
+
const {generateBarcodePng} = require("./barcode-generator.js");
|
|
6
2
|
|
|
7
3
|
function Barcode(engine) {
|
|
8
4
|
this.registerTag("barcode", {
|
|
@@ -23,13 +19,12 @@ function Barcode(engine) {
|
|
|
23
19
|
}
|
|
24
20
|
},
|
|
25
21
|
render: async function(ctx) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}, String(content), OutputType.PNG);
|
|
22
|
+
const content = await this.liquid.evalValue(this.content, ctx) || this.content;
|
|
23
|
+
const image = await generateBarcodePng({
|
|
24
|
+
type: this.type,
|
|
25
|
+
content,
|
|
26
|
+
height: this.height
|
|
27
|
+
});
|
|
33
28
|
let margin = [0,0,0,0];
|
|
34
29
|
try {
|
|
35
30
|
margin = this.margin.split(",").map((i) => {
|
|
@@ -43,7 +38,7 @@ function Barcode(engine) {
|
|
|
43
38
|
margin = [0,0,0,0];
|
|
44
39
|
}
|
|
45
40
|
return `{
|
|
46
|
-
"image": "${
|
|
41
|
+
"image": "${image}",
|
|
47
42
|
"width": ${this.width || 200},
|
|
48
43
|
"margin": [${margin.join(",")}]
|
|
49
44
|
}`;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const assert = require("node:assert/strict");
|
|
2
|
+
const fs = require("node:fs");
|
|
3
|
+
const path = require("node:path");
|
|
4
|
+
const {describe, it} = require("node:test");
|
|
5
|
+
const {listSupportedSymbologyTypes} = require("../src/barcode-types.js");
|
|
6
|
+
const {decodePngDataUri, isValidPngDataUri} = require("./helpers/barcode-decode.js");
|
|
7
|
+
const {generateBwipTestPng} = require("./helpers/generate-bwip-test-png.js");
|
|
8
|
+
|
|
9
|
+
const FIXTURE_DIR = path.join(__dirname, "fixtures/legacy-barcodes");
|
|
10
|
+
const manifest = JSON.parse(fs.readFileSync(path.join(FIXTURE_DIR, "manifest.json"), "utf8"));
|
|
11
|
+
const manifestByType = new Map(manifest.map((entry) => [entry.type, entry]));
|
|
12
|
+
|
|
13
|
+
function legacyFixtureToDataUri(filename) {
|
|
14
|
+
const pngBuffer = fs.readFileSync(path.join(FIXTURE_DIR, filename));
|
|
15
|
+
return `data:image/png;base64,${pngBuffer.toString("base64")}`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
describe("barcode equivalence", () => {
|
|
19
|
+
it("should include a manifest entry for every supported symbology type", () => {
|
|
20
|
+
for (const type of listSupportedSymbologyTypes()) {
|
|
21
|
+
assert.ok(manifestByType.has(type.toLowerCase()), `Missing manifest entry for ${type}`);
|
|
22
|
+
}
|
|
23
|
+
assert.equal(manifest.length, listSupportedSymbologyTypes().length);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
for (const testCase of manifest) {
|
|
27
|
+
it(`should support ${testCase.type} with bwip-js`, async () => {
|
|
28
|
+
const nextImage = await generateBwipTestPng({
|
|
29
|
+
type: testCase.type,
|
|
30
|
+
content: testCase.bwipContent || testCase.content,
|
|
31
|
+
height: testCase.height,
|
|
32
|
+
bwipOptions: testCase.bwipOptions || {}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
assert.match(nextImage, /^data:image\/png;base64,/);
|
|
36
|
+
assert.equal(isValidPngDataUri(nextImage), true);
|
|
37
|
+
assert.equal(testCase.bwipGenerated, true);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
if (testCase.legacyGenerated) {
|
|
41
|
+
it(`should match legacy ${testCase.type} decoded payload when scannable`, async () => {
|
|
42
|
+
const legacyImage = legacyFixtureToDataUri(testCase.file);
|
|
43
|
+
const nextImage = await generateBwipTestPng({
|
|
44
|
+
type: testCase.type,
|
|
45
|
+
content: testCase.bwipContent || testCase.content,
|
|
46
|
+
height: testCase.height,
|
|
47
|
+
bwipOptions: testCase.bwipOptions || {}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
if (!testCase.decodable) {
|
|
51
|
+
assert.equal(isValidPngDataUri(legacyImage), true);
|
|
52
|
+
assert.equal(isValidPngDataUri(nextImage), true);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const legacyDecoded = await decodePngDataUri(legacyImage);
|
|
57
|
+
const nextDecoded = await decodePngDataUri(nextImage);
|
|
58
|
+
|
|
59
|
+
assert.equal(nextDecoded, legacyDecoded);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const assert = require("node:assert/strict");
|
|
2
|
+
const {describe, it} = require("node:test");
|
|
3
|
+
const {generateBarcodePng} = require("../src/barcode-generator.js");
|
|
4
|
+
const {decodePngDataUri, isValidPngDataUri} = require("./helpers/barcode-decode.js");
|
|
5
|
+
|
|
6
|
+
describe("barcode-generator.js", () => {
|
|
7
|
+
it("should generate a valid PNG data URI for code128", async () => {
|
|
8
|
+
const image = await generateBarcodePng({
|
|
9
|
+
type: "code128",
|
|
10
|
+
content: "1234",
|
|
11
|
+
height: 10
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
assert.match(image, /^data:image\/png;base64,/);
|
|
15
|
+
assert.equal(isValidPngDataUri(image), true);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("should decode generated code128 barcodes to the original payload", async () => {
|
|
19
|
+
const image = await generateBarcodePng({
|
|
20
|
+
type: "code128",
|
|
21
|
+
content: "1234",
|
|
22
|
+
height: 10
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
assert.equal(await decodePngDataUri(image), "1234");
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("should decode generated eanx barcodes to the original payload", async () => {
|
|
29
|
+
const image = await generateBarcodePng({
|
|
30
|
+
type: "eanx",
|
|
31
|
+
content: "5901234123457",
|
|
32
|
+
height: 10
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
assert.equal(await decodePngDataUri(image), "5901234123457");
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("should reject unsupported symbology formats", async () => {
|
|
39
|
+
await assert.rejects(
|
|
40
|
+
() => generateBarcodePng({type: "gridmatrix", content: "1234", height: 10}),
|
|
41
|
+
/Unsupported barcode type: GRIDMATRIX/
|
|
42
|
+
);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const assert = require("node:assert/strict");
|
|
2
|
+
const {describe, it} = require("node:test");
|
|
3
|
+
const SYMBOLOGY_TYPE_NAMES = require("./fixtures/symbology-type-names.js");
|
|
4
|
+
const {
|
|
5
|
+
resolveBarcodeType,
|
|
6
|
+
listSupportedSymbologyTypes,
|
|
7
|
+
listUnsupportedSymbologyTypes,
|
|
8
|
+
UNSUPPORTED_TYPES,
|
|
9
|
+
SYMBLOGY_TO_BWIP
|
|
10
|
+
} = require("../src/barcode-types.js");
|
|
11
|
+
|
|
12
|
+
describe("barcode-types.js", () => {
|
|
13
|
+
it("should map every symbology enum name except unsupported ones", () => {
|
|
14
|
+
const expectedSupported = SYMBOLOGY_TYPE_NAMES
|
|
15
|
+
.filter((type) => !UNSUPPORTED_TYPES.has(type))
|
|
16
|
+
.sort();
|
|
17
|
+
|
|
18
|
+
assert.deepStrictEqual(listSupportedSymbologyTypes(), expectedSupported);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("should expose unsupported symbology formats", () => {
|
|
22
|
+
assert.deepStrictEqual(listUnsupportedSymbologyTypes(), [
|
|
23
|
+
"GRIDMATRIX",
|
|
24
|
+
"KOREAPOST",
|
|
25
|
+
"UPNQR",
|
|
26
|
+
"VIN"
|
|
27
|
+
]);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("should resolve known aliases to bwip-js bcid values", () => {
|
|
31
|
+
assert.equal(resolveBarcodeType("code128"), "code128");
|
|
32
|
+
assert.equal(resolveBarcodeType("CODE11"), "code11");
|
|
33
|
+
assert.equal(resolveBarcodeType("qrcode"), "qrcode");
|
|
34
|
+
assert.equal(resolveBarcodeType("EAN128"), "gs1-128");
|
|
35
|
+
assert.equal(resolveBarcodeType("RM4SCC"), "royalmail");
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("should throw for unsupported symbology formats", () => {
|
|
39
|
+
for (const type of listUnsupportedSymbologyTypes()) {
|
|
40
|
+
assert.throws(
|
|
41
|
+
() => resolveBarcodeType(type),
|
|
42
|
+
(err) => err.message === `Unsupported barcode type: ${type}`
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("should throw for unknown symbology formats", () => {
|
|
48
|
+
assert.throws(
|
|
49
|
+
() => resolveBarcodeType("not-a-real-format"),
|
|
50
|
+
/Unsupported barcode type: NOT-A-REAL-FORMAT/
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("should map every supported symbology type to a non-empty bcid", () => {
|
|
55
|
+
for (const type of listSupportedSymbologyTypes()) {
|
|
56
|
+
const bcid = SYMBLOGY_TO_BWIP[type];
|
|
57
|
+
assert.ok(bcid, `Expected bcid mapping for ${type}`);
|
|
58
|
+
assert.equal(typeof bcid, "string");
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
});
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Sample payloads per legacy Symbology type. Values prefer content that works in both
|
|
2
|
+
// Symbology 4.0.2 and bwip-js where possible; `bwipContent` overrides bwip-only cases.
|
|
3
|
+
module.exports = {
|
|
4
|
+
AUSPOST: {content: "62123456789"},
|
|
5
|
+
AUSREDIRECT: {content: "62123456789"},
|
|
6
|
+
AUSREPLY: {content: "62123456789"},
|
|
7
|
+
AUSROUTE: {content: "62123456789"},
|
|
8
|
+
AZRUNE: {content: "1"},
|
|
9
|
+
AZTEC: {content: "AZTEC"},
|
|
10
|
+
C25IATA: {content: "1234567"},
|
|
11
|
+
C25IND: {content: "1234567"},
|
|
12
|
+
C25INTER: {content: "1234567890"},
|
|
13
|
+
C25LOGIC: {content: "1234567"},
|
|
14
|
+
C25MATRIX: {content: "1234567"},
|
|
15
|
+
CHANNEL: {content: "01"},
|
|
16
|
+
CODABAR: {content: "A123456A"},
|
|
17
|
+
CODABLOCKF: {content: "CODABLOCK"},
|
|
18
|
+
CODE11: {content: "1234"},
|
|
19
|
+
CODE128: {content: "1234"},
|
|
20
|
+
CODE128B: {content: "1234"},
|
|
21
|
+
CODE16K: {content: "1234"},
|
|
22
|
+
CODE32: {content: "12345678"},
|
|
23
|
+
CODE39: {content: "ABC123"},
|
|
24
|
+
CODE49: {content: "1234"},
|
|
25
|
+
CODE93: {content: "1234"},
|
|
26
|
+
CODEONE: {content: "1234"},
|
|
27
|
+
DAFT: {content: "DAFT"},
|
|
28
|
+
DATAMATRIX: {content: "DATAMATRIX"},
|
|
29
|
+
DOTCODE: {content: "DOTCODE"},
|
|
30
|
+
DPIDENT: {content: "12345678901"},
|
|
31
|
+
DPLEIT: {content: "1234567890123"},
|
|
32
|
+
EAN128: {content: "[01]09501101530003", bwipContent: "(01)09501101530003"},
|
|
33
|
+
EAN128_CC: {content: "(01)09501101530003|99TEST", bwipContent: "(01)09501101530003|(10)ABC"},
|
|
34
|
+
EAN14: {content: "1234567890123", bwipContent: "(01)09501101530003", bwipOptions: {parse: true}},
|
|
35
|
+
EANX: {content: "5901234123457"},
|
|
36
|
+
EANX_CC: {content: "5901234123457|99TEST", bwipContent: "5901234123457|(10)ABC"},
|
|
37
|
+
EANX_CHK: {content: "5901234123457"},
|
|
38
|
+
EXCODE39: {content: "ABC-123"},
|
|
39
|
+
FIM: {content: "1"},
|
|
40
|
+
FLAT: {content: "1"},
|
|
41
|
+
HANXIN: {content: "HANXIN"},
|
|
42
|
+
HIBC_128: {content: "+ABC1234ABC1234/$$0123456789012"},
|
|
43
|
+
HIBC_39: {content: "+ABC1234ABC1234/$$0123456789012"},
|
|
44
|
+
HIBC_AZTEC: {content: "+ABC1234ABC1234/$$0123456789012"},
|
|
45
|
+
HIBC_DM: {content: "+ABC1234ABC1234/$$0123456789012"},
|
|
46
|
+
HIBC_MICPDF: {content: "+ABC1234ABC1234/$$0123456789012"},
|
|
47
|
+
HIBC_PDF: {content: "+ABC1234ABC1234/$$0123456789012"},
|
|
48
|
+
HIBC_QR: {content: "+ABC1234ABC1234/$$0123456789012"},
|
|
49
|
+
ISBNX: {content: "9780306406157", bwipContent: "978-0-306-40615-7"},
|
|
50
|
+
ITF14: {content: "1234567890123"},
|
|
51
|
+
JAPANPOST: {content: "12345678901"},
|
|
52
|
+
KIX: {content: "15400171583802"},
|
|
53
|
+
LOGMARS: {content: "ABC123"},
|
|
54
|
+
MAILMARK: {
|
|
55
|
+
content: "AV11HX7TCH",
|
|
56
|
+
bwipContent: `JGB ${"X".repeat(41)}`,
|
|
57
|
+
bwipOptions: {type: 9}
|
|
58
|
+
},
|
|
59
|
+
MAXICODE: {content: "1234567890123456789012345678901234"},
|
|
60
|
+
MICROPDF417: {content: "MICROPDF"},
|
|
61
|
+
MICROQR: {content: "MICROQR"},
|
|
62
|
+
MSI_PLESSEY: {content: "123456"},
|
|
63
|
+
NVE18: {
|
|
64
|
+
content: "12345678901234567",
|
|
65
|
+
bwipContent: "(00)12345678901234567",
|
|
66
|
+
bwipOptions: {parse: true, includecheck: true}
|
|
67
|
+
},
|
|
68
|
+
ONECODE: {content: "01234567890501234567890501", bwipContent: "01234567890501234567890501234"},
|
|
69
|
+
PDF417: {content: "PDF417"},
|
|
70
|
+
PDF417TRUNC: {content: "PDF417"},
|
|
71
|
+
PHARMA: {content: "123"},
|
|
72
|
+
PHARMA_TWO: {content: "123456"},
|
|
73
|
+
PLANET: {content: "01234567890"},
|
|
74
|
+
PLESSEY: {content: "1234567890"},
|
|
75
|
+
POSTNET: {content: "01234"},
|
|
76
|
+
PZN: {content: "123456"},
|
|
77
|
+
QRCODE: {content: "hello-world"},
|
|
78
|
+
RM4SCC: {content: "W1J0TRQ"},
|
|
79
|
+
RSS14: {content: "0123456789051", bwipContent: "(01)09501101530003", bwipOptions: {parse: true}},
|
|
80
|
+
RSS14STACK: {content: "0123456789051", bwipContent: "(01)09501101530003", bwipOptions: {parse: true}},
|
|
81
|
+
RSS14STACK_CC: {content: "0123456789051|99TEST", bwipContent: "(01)09501101530003|(10)ABC"},
|
|
82
|
+
RSS14STACK_OMNI: {content: "0123456789051", bwipContent: "(01)09501101530003", bwipOptions: {parse: true}},
|
|
83
|
+
RSS14_CC: {content: "012345678905|99TEST", bwipContent: "(01)09501101530003|(10)ABC"},
|
|
84
|
+
RSS14_OMNI_CC: {content: "0123456789051|99TEST", bwipContent: "(01)09501101530003|(10)ABC"},
|
|
85
|
+
RSS_EXP: {content: "[01]09501101530003", bwipContent: "(01)09501101530003"},
|
|
86
|
+
RSS_EXPSTACK: {content: "(01)09501101530003"},
|
|
87
|
+
RSS_EXPSTACK_CC: {content: "(01)09501101530003|99TEST", bwipContent: "(01)09501101530003|(10)ABC"},
|
|
88
|
+
RSS_EXP_CC: {content: "(01)09501101530003|99TEST", bwipContent: "(01)09501101530003|(10)ABC"},
|
|
89
|
+
RSS_LTD: {content: "0123456789051", bwipContent: "(01)09501101530003", bwipOptions: {parse: true}},
|
|
90
|
+
RSS_LTD_CC: {content: "0123456789051|99TEST", bwipContent: "(01)09501101530003|(10)ABC"},
|
|
91
|
+
TELEPEN: {content: "Telepen"},
|
|
92
|
+
TELEPEN_NUM: {content: "123456"},
|
|
93
|
+
ULTRA: {content: "ULTRA"},
|
|
94
|
+
UPCA: {content: "012345678905"},
|
|
95
|
+
UPCA_CC: {content: "012345678905|99TEST", bwipContent: "012345678905|(10)ABC"},
|
|
96
|
+
UPCA_CHK: {content: "012345678905"},
|
|
97
|
+
UPCE: {content: "0123456"},
|
|
98
|
+
UPCE_CC: {content: "0123456|99TEST", bwipContent: "0123456|(10)ABC"},
|
|
99
|
+
UPCE_CHK: {content: "0123456"}
|
|
100
|
+
};
|