@aidc-toolkit/gs1 1.0.31-beta → 1.0.32-beta
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/dist/gcp-length-cache.d.ts +42 -0
- package/dist/gcp-length-cache.d.ts.map +1 -0
- package/dist/gcp-length-cache.js +96 -0
- package/dist/gcp-length-cache.js.map +1 -0
- package/dist/gcp-length-data.d.ts +54 -0
- package/dist/gcp-length-data.d.ts.map +1 -0
- package/dist/gcp-length-data.js +29 -0
- package/dist/gcp-length-data.js.map +1 -0
- package/dist/gcp-length.d.ts +61 -0
- package/dist/gcp-length.d.ts.map +1 -0
- package/dist/gcp-length.js +301 -0
- package/dist/gcp-length.js.map +1 -0
- package/dist/gtin-creator.d.ts +0 -17
- package/dist/gtin-creator.d.ts.map +1 -1
- package/dist/gtin-creator.js +1 -93
- package/dist/gtin-creator.js.map +1 -1
- package/dist/gtin-validator.d.ts +1 -46
- package/dist/gtin-validator.d.ts.map +1 -1
- package/dist/gtin-validator.js +31 -125
- package/dist/gtin-validator.js.map +1 -1
- package/dist/identifier-validator.d.ts +1 -4
- package/dist/identifier-validator.d.ts.map +1 -1
- package/dist/identifier-validator.js +2 -5
- package/dist/identifier-validator.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/locale/en/locale-resources.d.ts +2 -1
- package/dist/locale/en/locale-resources.d.ts.map +1 -1
- package/dist/locale/en/locale-resources.js +3 -2
- package/dist/locale/en/locale-resources.js.map +1 -1
- package/dist/locale/fr/locale-resources.d.ts +2 -1
- package/dist/locale/fr/locale-resources.d.ts.map +1 -1
- package/dist/locale/fr/locale-resources.js +3 -2
- package/dist/locale/fr/locale-resources.js.map +1 -1
- package/dist/locale/i18n.d.ts +0 -3
- package/dist/locale/i18n.d.ts.map +1 -1
- package/dist/locale/i18n.js +2 -5
- package/dist/locale/i18n.js.map +1 -1
- package/dist/non-numeric-identifier-validator.js +1 -1
- package/dist/non-numeric-identifier-validator.js.map +1 -1
- package/dist/numeric-identifier-validator.js +2 -2
- package/dist/numeric-identifier-validator.js.map +1 -1
- package/dist/prefix-manager.d.ts +35 -0
- package/dist/prefix-manager.d.ts.map +1 -1
- package/dist/prefix-manager.js +56 -0
- package/dist/prefix-manager.js.map +1 -1
- package/dist/prefix-validator.d.ts +5 -4
- package/dist/prefix-validator.d.ts.map +1 -1
- package/dist/prefix-validator.js +18 -22
- package/dist/prefix-validator.js.map +1 -1
- package/dist/serializable-numeric-identifier-validator.d.ts +26 -0
- package/dist/serializable-numeric-identifier-validator.d.ts.map +1 -1
- package/dist/serializable-numeric-identifier-validator.js +19 -0
- package/dist/serializable-numeric-identifier-validator.js.map +1 -1
- package/dist/variable-measure.d.ts +68 -0
- package/dist/variable-measure.d.ts.map +1 -0
- package/dist/variable-measure.js +210 -0
- package/dist/variable-measure.js.map +1 -0
- package/dist/verified-by-gs1.d.ts +22 -0
- package/dist/verified-by-gs1.d.ts.map +1 -0
- package/dist/verified-by-gs1.js +46 -0
- package/dist/verified-by-gs1.js.map +1 -0
- package/package.json +8 -8
- package/src/gcp-length-cache.ts +117 -0
- package/src/gcp-length-data.ts +68 -0
- package/src/gcp-length.ts +418 -0
- package/src/gtin-creator.ts +1 -117
- package/src/gtin-validator.ts +42 -173
- package/src/identifier-validator.ts +2 -5
- package/src/index.ts +7 -1
- package/src/locale/en/locale-resources.ts +3 -2
- package/src/locale/fr/locale-resources.ts +3 -2
- package/src/locale/i18n.ts +2 -5
- package/src/non-numeric-identifier-validator.ts +1 -1
- package/src/numeric-identifier-validator.ts +2 -2
- package/src/prefix-manager.ts +65 -0
- package/src/prefix-validator.ts +19 -23
- package/src/serializable-numeric-identifier-validator.ts +36 -0
- package/src/variable-measure.ts +268 -0
- package/src/verified-by-gs1.ts +54 -0
- package/test/creator.test.ts +5 -5
- package/test/data/gcpprefixformatlist-1.json +662625 -0
- package/test/data/gcpprefixformatlist-2.json +735431 -0
- package/test/gcp-length.test.ts +405 -0
- package/test/gtin-creator.ts +4 -4
- package/test/gtin-validator.test.ts +205 -113
- package/test/gtin-validator.ts +30 -0
- package/test/identifier-creator.ts +6 -6
- package/test/non-numeric-identifier-creator.ts +0 -8
- package/test/non-serializable-numeric-identifier-creator.ts +4 -54
- package/test/numeric-identifier-creator.ts +4 -4
- package/test/prefix-manager.test.ts +5 -5
- package/test/serializable-numeric-identifier-creator.ts +32 -19
- package/test/validator.test.ts +6 -6
- package/test/variable-measure-rcn.test.ts +63 -68
- package/test/verified-by-gs1.test.ts +55 -0
- package/tsconfig-src.json +7 -1
- package/tsconfig-src.tsbuildinfo +1 -0
- package/tsconfig-tsup.json +7 -0
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
import type { Promisable } from "@aidc-toolkit/core";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { describe, expect, test } from "vitest";
|
|
5
|
+
import * as GCPLength from "../src/gcp-length.js";
|
|
6
|
+
import {
|
|
7
|
+
GCPLengthCache,
|
|
8
|
+
type GCPLengthData,
|
|
9
|
+
IdentifierTypes,
|
|
10
|
+
PrefixManager,
|
|
11
|
+
PrefixTypes,
|
|
12
|
+
PrefixValidator
|
|
13
|
+
} from "../src/index.js";
|
|
14
|
+
|
|
15
|
+
interface ReadonlyStorage<T> {
|
|
16
|
+
read: () => T;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface Storage<T> extends ReadonlyStorage<T> {
|
|
20
|
+
write: (value: NonNullable<T>) => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface RequiredStorage<T> extends Storage<T> {
|
|
24
|
+
read: () => NonNullable<T>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function makeReadonly<T>(storage: Storage<T | undefined>): ReadonlyStorage<T> {
|
|
28
|
+
return {
|
|
29
|
+
read(): T {
|
|
30
|
+
const t = storage.read();
|
|
31
|
+
|
|
32
|
+
if (t === undefined) {
|
|
33
|
+
throw new Error("Storage has no data");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return t;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function makeRequired<T>(storage: Storage<T | undefined>): RequiredStorage<T> {
|
|
42
|
+
return {
|
|
43
|
+
read(): NonNullable<T> {
|
|
44
|
+
const t = storage.read();
|
|
45
|
+
|
|
46
|
+
if (t === undefined || t === null) {
|
|
47
|
+
throw new Error("Storage has no data");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return t;
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
write: storage.write
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function createGCPLengthCache(nextCheckDateTimeStorage: Storage<Date | undefined>, cacheDataStorage: Storage<GCPLengthData | undefined>, sourceDateTimeStorage: ReadonlyStorage<Date>, sourceDataStorage: ReadonlyStorage<GCPLengthData> | ReadonlyStorage<string>): GCPLengthCache {
|
|
58
|
+
return new class extends GCPLengthCache {
|
|
59
|
+
get nextCheckDateTime(): Promisable<Date | undefined> {
|
|
60
|
+
return nextCheckDateTimeStorage.read();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
get cacheDateTime(): Date | undefined {
|
|
64
|
+
return cacheDataStorage.read()?.dateTime;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
get cacheData(): GCPLengthData {
|
|
68
|
+
return makeRequired(cacheDataStorage).read();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
get sourceDateTime(): Date {
|
|
72
|
+
return sourceDateTimeStorage.read();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
get sourceData(): GCPLengthData | string {
|
|
76
|
+
return sourceDataStorage.read();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
update(nextCheckDateTime: Date, _cacheDateTime?: Date, cacheData?: GCPLengthData): void {
|
|
80
|
+
nextCheckDateTimeStorage.write(nextCheckDateTime);
|
|
81
|
+
|
|
82
|
+
if (cacheData !== undefined) {
|
|
83
|
+
cacheDataStorage.write(cacheData);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const DATA_DIRECTORY = "test/data";
|
|
90
|
+
|
|
91
|
+
const BINARY_1_HEADER_PATH = path.resolve(DATA_DIRECTORY, "gcp-length-header-1.txt");
|
|
92
|
+
|
|
93
|
+
const BINARY_1_DATA_PATH = path.resolve(DATA_DIRECTORY, "gcp-length-data-1.bin");
|
|
94
|
+
|
|
95
|
+
const BINARY_2_HEADER_PATH = path.resolve(DATA_DIRECTORY, "gcp-length-header-2.txt");
|
|
96
|
+
|
|
97
|
+
const BINARY_2_DATA_PATH = path.resolve(DATA_DIRECTORY, "gcp-length-data-2.bin");
|
|
98
|
+
|
|
99
|
+
const JSON_1_DATA_PATH = path.resolve(DATA_DIRECTORY, "gcpprefixformatlist-1.json");
|
|
100
|
+
|
|
101
|
+
const JSON_2_DATA_PATH = path.resolve(DATA_DIRECTORY, "gcpprefixformatlist-2.json");
|
|
102
|
+
|
|
103
|
+
interface GCPLengthJSON {
|
|
104
|
+
_disclaimer: string[];
|
|
105
|
+
GCPPrefixFormatList: {
|
|
106
|
+
date: string;
|
|
107
|
+
entry: Array<{
|
|
108
|
+
prefix: string;
|
|
109
|
+
gcpLength: number;
|
|
110
|
+
}>;
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
describe("GS1 Company Prefix length", () => {
|
|
115
|
+
function binaryDataStorage(binaryHeaderPath: string, binaryDataPath: string): Storage<GCPLengthData | undefined> {
|
|
116
|
+
return {
|
|
117
|
+
read(): GCPLengthData | undefined {
|
|
118
|
+
let header: string[] | undefined;
|
|
119
|
+
let data: Uint8Array | undefined;
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
header = fs.readFileSync(binaryHeaderPath).toString().split("\n");
|
|
123
|
+
data = fs.readFileSync(binaryDataPath);
|
|
124
|
+
} catch {
|
|
125
|
+
header = undefined;
|
|
126
|
+
data = undefined;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return header !== undefined && data !== undefined ?
|
|
130
|
+
{
|
|
131
|
+
dateTime: new Date(header[0]),
|
|
132
|
+
disclaimer: `${header.slice(1).join("\n")}\n`,
|
|
133
|
+
data
|
|
134
|
+
} :
|
|
135
|
+
undefined;
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
write(value: GCPLengthData): void {
|
|
139
|
+
fs.writeFileSync(binaryHeaderPath, `${value.dateTime.toISOString()}\n${value.disclaimer}`);
|
|
140
|
+
fs.writeFileSync(binaryDataPath, value.data);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function jsonDateTimeStorage(jsonDateTimePath: string): ReadonlyStorage<Date> {
|
|
146
|
+
return {
|
|
147
|
+
read(): Date {
|
|
148
|
+
return new Date((JSON.parse(fs.readFileSync(jsonDateTimePath).toString()) as GCPLengthJSON).GCPPrefixFormatList.date);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function jsonDataStorage(jsonDataPath: string): ReadonlyStorage<string> {
|
|
154
|
+
return {
|
|
155
|
+
read(): string {
|
|
156
|
+
return fs.readFileSync(jsonDataPath).toString();
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function verifyEqual(prefix: string, node1: GCPLength.Node | undefined, node2: GCPLength.Node | undefined): void {
|
|
162
|
+
if (node1 !== undefined) {
|
|
163
|
+
if (node2 === undefined) {
|
|
164
|
+
throw new RangeError(`Prefix ${prefix}: node1 defined, node2 undefined`);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (GCPLength.isLeaf(node1)) {
|
|
168
|
+
if (!GCPLength.isLeaf(node2)) {
|
|
169
|
+
throw new RangeError(`Prefix ${prefix}: node1 is leaf, node2 is branch`);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (node1.length !== node2.length) {
|
|
173
|
+
throw new RangeError(`Prefix ${prefix}: node1.length = ${node1.length}, node2.length = ${node2.length}`);
|
|
174
|
+
}
|
|
175
|
+
} else if (!GCPLength.isLeaf(node2)) {
|
|
176
|
+
for (let index = 0; index < 10; index++) {
|
|
177
|
+
verifyEqual(`${prefix}${index}`, node1.childNodes[index], (node2 as GCPLength.Branch).childNodes[index]);
|
|
178
|
+
}
|
|
179
|
+
} else {
|
|
180
|
+
throw new RangeError(`Prefix ${prefix}: node1 is branch, node2 is leaf`);
|
|
181
|
+
}
|
|
182
|
+
} else if (node2 !== undefined) {
|
|
183
|
+
throw new RangeError(`Prefix ${prefix}: node1 undefined, node2 defined`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function unlink(path: string): void {
|
|
188
|
+
if (fs.existsSync(path)) {
|
|
189
|
+
fs.unlinkSync(path);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function unlinkBinaries(): void {
|
|
194
|
+
unlink(BINARY_1_HEADER_PATH);
|
|
195
|
+
unlink(BINARY_1_DATA_PATH);
|
|
196
|
+
unlink(BINARY_2_HEADER_PATH);
|
|
197
|
+
unlink(BINARY_2_DATA_PATH);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const binary1DataStorage = binaryDataStorage(BINARY_1_HEADER_PATH, BINARY_1_DATA_PATH);
|
|
201
|
+
const binary2DataStorage = binaryDataStorage(BINARY_2_HEADER_PATH, BINARY_2_DATA_PATH);
|
|
202
|
+
const json1DateTimeStorage = jsonDateTimeStorage(JSON_1_DATA_PATH);
|
|
203
|
+
const json1DataStorage = jsonDataStorage(JSON_1_DATA_PATH);
|
|
204
|
+
const json2DateTimeStorage = jsonDateTimeStorage(JSON_2_DATA_PATH);
|
|
205
|
+
const json2DataStorage = jsonDataStorage(JSON_2_DATA_PATH);
|
|
206
|
+
|
|
207
|
+
const emptyStorage: Storage<Date | undefined> & Storage<string | undefined> & Storage<GCPLengthData | undefined> = {
|
|
208
|
+
read(): undefined {
|
|
209
|
+
return undefined;
|
|
210
|
+
},
|
|
211
|
+
|
|
212
|
+
write() {
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
test("Load", async () => {
|
|
217
|
+
unlinkBinaries();
|
|
218
|
+
|
|
219
|
+
let nextCheckDateTime: Date | undefined = undefined;
|
|
220
|
+
|
|
221
|
+
const nextCheckDateTimeStorage: Storage<Date | undefined> = {
|
|
222
|
+
read(): Date | undefined {
|
|
223
|
+
return nextCheckDateTime;
|
|
224
|
+
},
|
|
225
|
+
|
|
226
|
+
write(value: Date): void {
|
|
227
|
+
nextCheckDateTime = value;
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
const binary2DataReadonlyStorage = makeReadonly(binary2DataStorage);
|
|
232
|
+
const binary2DateTimeReadonlyStorage: ReadonlyStorage<Date> = {
|
|
233
|
+
read(): Date {
|
|
234
|
+
return binary2DataReadonlyStorage.read().dateTime;
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
// Neither binary available.
|
|
239
|
+
await expect((async () => {
|
|
240
|
+
await GCPLength.loadData(createGCPLengthCache(nextCheckDateTimeStorage, binary1DataStorage, binary2DateTimeReadonlyStorage, binary2DataReadonlyStorage));
|
|
241
|
+
})()).rejects.toThrowError("Storage has no data");
|
|
242
|
+
|
|
243
|
+
expect(nextCheckDateTime).toBeUndefined();
|
|
244
|
+
|
|
245
|
+
let root1: GCPLength.Root | undefined;
|
|
246
|
+
|
|
247
|
+
// Binary 1 not available, JSON 1 available.
|
|
248
|
+
await expect((async () => {
|
|
249
|
+
root1 = await GCPLength.loadData(createGCPLengthCache(nextCheckDateTimeStorage, binary1DataStorage, json1DateTimeStorage, json1DataStorage));
|
|
250
|
+
})()).resolves.not.toThrowError(RangeError);
|
|
251
|
+
|
|
252
|
+
expect(nextCheckDateTime).not.toBeUndefined();
|
|
253
|
+
|
|
254
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- Known not to be undefined.
|
|
255
|
+
expect(new Date().getTime() + 24 * 60 * 60 * 1000 - nextCheckDateTime!.getTime()).toBeLessThan(10000);
|
|
256
|
+
|
|
257
|
+
expect(root1).not.toBeUndefined();
|
|
258
|
+
|
|
259
|
+
let root2: GCPLength.Root | undefined;
|
|
260
|
+
|
|
261
|
+
// Binary 1 available, binary 2 not available but not in next check date/time window.
|
|
262
|
+
await expect((async () => {
|
|
263
|
+
root2 = await GCPLength.loadData(createGCPLengthCache(nextCheckDateTimeStorage, binary1DataStorage, binary2DateTimeReadonlyStorage, binary2DataReadonlyStorage));
|
|
264
|
+
})()).resolves.not.toThrowError(RangeError);
|
|
265
|
+
|
|
266
|
+
expect(root2).not.toBeUndefined();
|
|
267
|
+
|
|
268
|
+
// Load from JSON 1 equal to load from binary 1.
|
|
269
|
+
expect(() => {
|
|
270
|
+
verifyEqual("", root1, root2);
|
|
271
|
+
}).not.toThrow(RangeError);
|
|
272
|
+
|
|
273
|
+
// eslint-disable-next-line require-atomic-updates -- No rance condition.
|
|
274
|
+
nextCheckDateTime = undefined;
|
|
275
|
+
root2 = undefined;
|
|
276
|
+
|
|
277
|
+
// Binary 2 not available, JSON 2 available.
|
|
278
|
+
await expect((async () => {
|
|
279
|
+
root2 = await GCPLength.loadData(createGCPLengthCache(nextCheckDateTimeStorage, binary2DataStorage, json2DateTimeStorage, json2DataStorage));
|
|
280
|
+
})()).resolves.not.toThrowError(RangeError);
|
|
281
|
+
|
|
282
|
+
expect(nextCheckDateTime).not.toBeUndefined();
|
|
283
|
+
expect(root2).not.toBeUndefined();
|
|
284
|
+
|
|
285
|
+
root2 = undefined;
|
|
286
|
+
|
|
287
|
+
// Binary 1 available, binary 2 available and more recent but not in next check date/time window.
|
|
288
|
+
await expect((async () => {
|
|
289
|
+
root2 = await GCPLength.loadData(createGCPLengthCache(nextCheckDateTimeStorage, binary1DataStorage, binary2DateTimeReadonlyStorage, binary2DataReadonlyStorage));
|
|
290
|
+
})()).resolves.not.toThrowError(RangeError);
|
|
291
|
+
|
|
292
|
+
// No change.
|
|
293
|
+
expect(() => {
|
|
294
|
+
verifyEqual("", root1, root2);
|
|
295
|
+
}).not.toThrow(RangeError);
|
|
296
|
+
|
|
297
|
+
// eslint-disable-next-line require-atomic-updates -- No rance condition.
|
|
298
|
+
nextCheckDateTime = new Date();
|
|
299
|
+
|
|
300
|
+
// Binary 1 available, binary 2 available and more recent and in next check date/time window.
|
|
301
|
+
await expect((async () => {
|
|
302
|
+
root2 = await GCPLength.loadData(createGCPLengthCache(nextCheckDateTimeStorage, binary1DataStorage, binary2DateTimeReadonlyStorage, binary2DataReadonlyStorage));
|
|
303
|
+
})()).resolves.not.toThrowError(RangeError);
|
|
304
|
+
|
|
305
|
+
expect(root2).not.toBeUndefined();
|
|
306
|
+
|
|
307
|
+
// Load from binary 1 not equal to load from binary 2.
|
|
308
|
+
expect(() => {
|
|
309
|
+
verifyEqual("", root1, root2);
|
|
310
|
+
}).toThrow(RangeError);
|
|
311
|
+
|
|
312
|
+
unlinkBinaries();
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
test("Identifiers", async () => {
|
|
316
|
+
const tempRoot = await GCPLength.loadData(createGCPLengthCache(emptyStorage, emptyStorage, json1DateTimeStorage, json1DataStorage));
|
|
317
|
+
|
|
318
|
+
expect(tempRoot).not.toBeUndefined();
|
|
319
|
+
|
|
320
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- Known to be defined.
|
|
321
|
+
const root = tempRoot!;
|
|
322
|
+
|
|
323
|
+
function testIdentifiers(prefixManager: PrefixManager, prefixLength: number): void {
|
|
324
|
+
expect(GCPLength.getFor(root, IdentifierTypes.GTIN, prefixManager.gtinCreator.create(0, true))).toBe(prefixLength);
|
|
325
|
+
expect(GCPLength.getFor(root, IdentifierTypes.GTIN, prefixManager.gtinCreator.createGTIN14("4", 0, true))).toBe(prefixLength);
|
|
326
|
+
|
|
327
|
+
if (prefixManager.prefixType !== PrefixTypes.GS18Prefix) {
|
|
328
|
+
expect(GCPLength.getFor(root, IdentifierTypes.GLN, prefixManager.glnCreator.create(0, true))).toBe(prefixLength);
|
|
329
|
+
expect(GCPLength.getFor(root, IdentifierTypes.SSCC, prefixManager.ssccCreator.create(0, true))).toBe(prefixLength);
|
|
330
|
+
expect(GCPLength.getFor(root, IdentifierTypes.GRAI, prefixManager.graiCreator.create(0, true))).toBe(prefixLength);
|
|
331
|
+
expect(GCPLength.getFor(root, IdentifierTypes.GRAI, prefixManager.graiCreator.createSerialized(0, "ABCD1234", true))).toBe(prefixLength);
|
|
332
|
+
expect(GCPLength.getFor(root, IdentifierTypes.GIAI, prefixManager.giaiCreator.create("EFGH5678"))).toBe(prefixLength);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const gcpLengthJSON = JSON.parse(json1DataStorage.read()) as GCPLengthJSON;
|
|
337
|
+
const entries = gcpLengthJSON.GCPPrefixFormatList.entry;
|
|
338
|
+
|
|
339
|
+
for (let i = 0; i < 1000; i++) {
|
|
340
|
+
const entryIndex = Math.floor(Math.random() * entries.length);
|
|
341
|
+
const gcpLengthJSONEntry = entries[entryIndex];
|
|
342
|
+
const prefixLength = gcpLengthJSONEntry.gcpLength;
|
|
343
|
+
const testPrefixLength = prefixLength !== 0 ? prefixLength : Math.max(PrefixValidator.GS1_COMPANY_PREFIX_MINIMUM_LENGTH, PrefixValidator.UPC_COMPANY_PREFIX_MINIMUM_LENGTH + 1, PrefixValidator.GS1_8_PREFIX_MINIMUM_LENGTH + 5);
|
|
344
|
+
|
|
345
|
+
let prefix = gcpLengthJSONEntry.prefix;
|
|
346
|
+
|
|
347
|
+
while (prefix.length !== testPrefixLength) {
|
|
348
|
+
prefix = `${prefix}${Math.floor(Math.random() * 10)}`;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
testIdentifiers(PrefixManager.get(PrefixTypes.GS1CompanyPrefix, prefix), prefixLength);
|
|
352
|
+
|
|
353
|
+
if (entryIndex !== entries.length - 1) {
|
|
354
|
+
const nextGCPLengthJSONEntry = entries[entryIndex + 1];
|
|
355
|
+
|
|
356
|
+
if (nextGCPLengthJSONEntry.prefix.length === gcpLengthJSONEntry.prefix.length && Number(nextGCPLengthJSONEntry.prefix) - Number(gcpLengthJSONEntry.prefix) !== 1) {
|
|
357
|
+
let nextPrefix = String(Number(gcpLengthJSONEntry.prefix) + 1).padStart(gcpLengthJSONEntry.prefix.length, "0");
|
|
358
|
+
|
|
359
|
+
while (nextPrefix.length !== testPrefixLength) {
|
|
360
|
+
nextPrefix = `${nextPrefix}${Math.floor(Math.random() * 10)}`;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
testIdentifiers(PrefixManager.get(PrefixTypes.GS1CompanyPrefix, nextPrefix), -1);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
// test("Remote", async () => {
|
|
370
|
+
// const gcpLengthCache = new class extends RemoteGCPLengthCache {
|
|
371
|
+
// #nextCheckDateTime: Date | undefined = undefined;
|
|
372
|
+
//
|
|
373
|
+
// #cacheData: GCPLengthData | undefined = undefined;
|
|
374
|
+
//
|
|
375
|
+
// get nextCheckDateTime(): Date | undefined {
|
|
376
|
+
// return this.#nextCheckDateTime;
|
|
377
|
+
// }
|
|
378
|
+
//
|
|
379
|
+
// get cacheDateTime(): Date | undefined {
|
|
380
|
+
// return this.#cacheData?.dateTime;
|
|
381
|
+
// }
|
|
382
|
+
//
|
|
383
|
+
// get cacheData(): GCPLengthData {
|
|
384
|
+
// // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- Method will be called only if cache date/time is defined.
|
|
385
|
+
// return this.#cacheData!;
|
|
386
|
+
// }
|
|
387
|
+
//
|
|
388
|
+
// update(nextCheckDateTime: Date, _cacheDateTime?: Date, cacheData?: GCPLengthData): Promisable<void> {
|
|
389
|
+
// this.#nextCheckDateTime = nextCheckDateTime;
|
|
390
|
+
//
|
|
391
|
+
// if (cacheData !== undefined) {
|
|
392
|
+
// this.#cacheData = cacheData;
|
|
393
|
+
// }
|
|
394
|
+
// }
|
|
395
|
+
// }();
|
|
396
|
+
//
|
|
397
|
+
// await expect((async () => {
|
|
398
|
+
// await GCPLength.loadData(gcpLengthCache);
|
|
399
|
+
// })()).resolves.not.toThrowError(RangeError);
|
|
400
|
+
//
|
|
401
|
+
// expect(gcpLengthCache.nextCheckDateTime).not.toBeUndefined();
|
|
402
|
+
// expect(gcpLengthCache.cacheDateTime).not.toBeUndefined();
|
|
403
|
+
// expect(gcpLengthCache.cacheData).not.toBeUndefined();
|
|
404
|
+
// });
|
|
405
|
+
});
|
package/test/gtin-creator.ts
CHANGED
|
@@ -68,8 +68,8 @@ export function testGTINCreator(creator: GTINCreator): void {
|
|
|
68
68
|
|
|
69
69
|
expect(index).toBe(referenceCount);
|
|
70
70
|
|
|
71
|
-
const randomValues =
|
|
72
|
-
const identifiers =
|
|
71
|
+
const randomValues: number[] = [];
|
|
72
|
+
const identifiers: string[] = [];
|
|
73
73
|
|
|
74
74
|
for (let i = 0; i < 1000; i++) {
|
|
75
75
|
const randomValue = Math.floor(Math.random() * creator.capacity);
|
|
@@ -105,8 +105,8 @@ export function testGTINCreator(creator: GTINCreator): void {
|
|
|
105
105
|
expect(sequential).toBe(false);
|
|
106
106
|
expect(index).toBe(sparseReferenceCount);
|
|
107
107
|
|
|
108
|
-
const randomValues =
|
|
109
|
-
const identifiers =
|
|
108
|
+
const randomValues: number[] = [];
|
|
109
|
+
const identifiers: string[] = [];
|
|
110
110
|
|
|
111
111
|
for (let i = 0; i < 1000; i++) {
|
|
112
112
|
const randomValue = Math.floor(Math.random() * creator.capacity);
|