@aidc-toolkit/gs1 1.0.32-beta → 1.0.34-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/README.md +290 -21
- package/dist/character-set.d.ts.map +1 -1
- package/dist/character-set.js +44 -11
- package/dist/character-set.js.map +1 -1
- package/dist/gcp-length-cache.d.ts +54 -15
- package/dist/gcp-length-cache.d.ts.map +1 -1
- package/dist/gcp-length-cache.js +181 -45
- package/dist/gcp-length-cache.js.map +1 -1
- package/dist/gcp-length-data.d.ts +74 -20
- package/dist/gcp-length-data.d.ts.map +1 -1
- package/dist/gcp-length-data.js +39 -15
- package/dist/gcp-length-data.js.map +1 -1
- package/dist/gcp-length.d.ts +1 -1
- package/dist/gcp-length.d.ts.map +1 -1
- package/dist/gcp-length.js +5 -6
- package/dist/gcp-length.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/locale/en/locale-resources.d.ts +39 -36
- package/dist/locale/en/locale-resources.d.ts.map +1 -1
- package/dist/locale/en/locale-resources.js +4 -1
- package/dist/locale/en/locale-resources.js.map +1 -1
- package/dist/locale/fr/locale-resources.d.ts +39 -36
- package/dist/locale/fr/locale-resources.d.ts.map +1 -1
- package/dist/locale/fr/locale-resources.js +4 -1
- package/dist/locale/fr/locale-resources.js.map +1 -1
- package/dist/locale/i18n.d.ts +6 -3
- package/dist/locale/i18n.d.ts.map +1 -1
- package/dist/locale/i18n.js +8 -6
- package/dist/locale/i18n.js.map +1 -1
- package/dist/numeric-identifier-validator.d.ts.map +1 -1
- package/dist/numeric-identifier-validator.js.map +1 -1
- package/dist/variable-measure.d.ts +4 -4
- package/dist/variable-measure.js +4 -4
- package/package.json +12 -10
- package/src/character-set.ts +55 -11
- package/src/gcp-length-cache.ts +208 -54
- package/src/gcp-length-data.ts +95 -27
- package/src/gcp-length.ts +5 -43
- package/src/index.ts +2 -1
- package/src/locale/en/locale-resources.ts +5 -2
- package/src/locale/fr/locale-resources.ts +5 -2
- package/src/locale/i18n.ts +9 -7
- package/src/locale/i18next.d.ts +2 -0
- package/src/numeric-identifier-validator.ts +1 -1
- package/src/variable-measure.ts +4 -4
- package/test/character-set.test.ts +46 -0
- package/test/gcp-length.test.ts +179 -240
- package/tsconfig-src.tsbuildinfo +1 -1
package/src/variable-measure.ts
CHANGED
|
@@ -37,12 +37,12 @@ export class VariableMeasure {
|
|
|
37
37
|
*
|
|
38
38
|
* Some examples:
|
|
39
39
|
*
|
|
40
|
-
* - 2IIIIIVPPPPC - RCN-12 with a five-digit item reference, a price or weight check digit, and a four-digit price
|
|
40
|
+
* - `2IIIIIVPPPPC` - RCN-12 with a five-digit item reference, a price or weight check digit, and a four-digit price
|
|
41
41
|
* or weight.
|
|
42
|
-
* - 23IIIIVPPPPPC - RCN-13 with a four-digit item reference, a price or weight check digit, and a five-digit price
|
|
42
|
+
* - `23IIIIVPPPPPC` - RCN-13 with a four-digit item reference, a price or weight check digit, and a five-digit price
|
|
43
43
|
* or weight.
|
|
44
|
-
* - 2IIIIIIPPPPC - RCN-12 with a six-digit item reference and a four-digit price or eight.
|
|
45
|
-
* - 29IIIIIPPPPPC - RCN-13 with a five-digit item reference and a five-digit price or weight.
|
|
44
|
+
* - `2IIIIIIPPPPC` - RCN-12 with a six-digit item reference and a four-digit price or eight.
|
|
45
|
+
* - `29IIIIIPPPPPC` - RCN-13 with a five-digit item reference and a five-digit price or weight.
|
|
46
46
|
*
|
|
47
47
|
* @param format
|
|
48
48
|
* Format.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import { AI64_VALIDATOR } from "../src/index.js";
|
|
3
|
+
|
|
4
|
+
describe("AI 64 character set validator", () => {
|
|
5
|
+
test("Character set", () => {
|
|
6
|
+
expect(() => {
|
|
7
|
+
AI64_VALIDATOR.validate("-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz");
|
|
8
|
+
}).not.toThrow(RangeError);
|
|
9
|
+
|
|
10
|
+
expect(() => {
|
|
11
|
+
AI64_VALIDATOR.validate("-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxy");
|
|
12
|
+
}).toThrow("Length 63 must be a multiple of 4");
|
|
13
|
+
|
|
14
|
+
expect(() => {
|
|
15
|
+
AI64_VALIDATOR.validate("-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwx");
|
|
16
|
+
}).toThrow("Length 62 must be a multiple of 4");
|
|
17
|
+
|
|
18
|
+
expect(() => {
|
|
19
|
+
AI64_VALIDATOR.validate("-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvw");
|
|
20
|
+
}).toThrow("Length 61 must be a multiple of 4");
|
|
21
|
+
|
|
22
|
+
expect(() => {
|
|
23
|
+
AI64_VALIDATOR.validate("-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyzABC=");
|
|
24
|
+
}).not.toThrow(RangeError);
|
|
25
|
+
|
|
26
|
+
expect(() => {
|
|
27
|
+
AI64_VALIDATOR.validate("-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyzAB==");
|
|
28
|
+
}).not.toThrow(RangeError);
|
|
29
|
+
|
|
30
|
+
expect(() => {
|
|
31
|
+
AI64_VALIDATOR.validate("-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyzA===");
|
|
32
|
+
}).toThrow("Invalid character '=' at position 65");
|
|
33
|
+
|
|
34
|
+
expect(() => {
|
|
35
|
+
AI64_VALIDATOR.validate("-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz====");
|
|
36
|
+
}).toThrow("Invalid character '=' at position 64");
|
|
37
|
+
|
|
38
|
+
expect(() => {
|
|
39
|
+
AI64_VALIDATOR.validate("=-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxy");
|
|
40
|
+
}).toThrow("Invalid character '=' at position 0");
|
|
41
|
+
|
|
42
|
+
expect(() => {
|
|
43
|
+
AI64_VALIDATOR.validate("-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ=_abcdefghijklmnopqrstuvwxy");
|
|
44
|
+
}).toThrow("Invalid character '=' at position 37");
|
|
45
|
+
});
|
|
46
|
+
});
|
package/test/gcp-length.test.ts
CHANGED
|
@@ -1,163 +1,107 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type AppDataStorage, LocalAppDataStorage } from "@aidc-toolkit/core";
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
-
import { describe, expect, test } from "vitest";
|
|
4
|
+
import { afterAll, beforeAll, describe, expect, test } from "vitest";
|
|
5
5
|
import * as GCPLength from "../src/gcp-length.js";
|
|
6
6
|
import {
|
|
7
7
|
GCPLengthCache,
|
|
8
8
|
type GCPLengthData,
|
|
9
|
+
type GCPLengthHeader,
|
|
10
|
+
type GCPLengthSourceJSON,
|
|
9
11
|
IdentifierTypes,
|
|
12
|
+
isGCPLengthHeader,
|
|
13
|
+
isGCPLengthSourceJSON,
|
|
10
14
|
PrefixManager,
|
|
11
15
|
PrefixTypes,
|
|
12
|
-
PrefixValidator
|
|
16
|
+
PrefixValidator,
|
|
17
|
+
RemoteGCPLengthCache
|
|
13
18
|
} from "../src/index.js";
|
|
14
19
|
|
|
15
|
-
|
|
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
|
-
}
|
|
20
|
+
const DATA_DIRECTORY = "test/data";
|
|
26
21
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
read(): T {
|
|
30
|
-
const t = storage.read();
|
|
22
|
+
class GCPLengthCacheJSONSource extends GCPLengthCache {
|
|
23
|
+
readonly #pathKey: string;
|
|
31
24
|
|
|
32
|
-
|
|
33
|
-
throw new Error("Storage has no data");
|
|
34
|
-
}
|
|
25
|
+
#gcpLengthSourceJSON!: GCPLengthSourceJSON;
|
|
35
26
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
};
|
|
39
|
-
}
|
|
27
|
+
constructor(appDataStorage: AppDataStorage<boolean>, index: number) {
|
|
28
|
+
super(appDataStorage);
|
|
40
29
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
read(): NonNullable<T> {
|
|
44
|
-
const t = storage.read();
|
|
30
|
+
this.#pathKey = `gcpprefixformatlist-${index}`;
|
|
31
|
+
}
|
|
45
32
|
|
|
46
|
-
|
|
47
|
-
|
|
33
|
+
get sourceDateTime(): Promise<Date> {
|
|
34
|
+
return this.appDataStorage.read(this.#pathKey).then((appData) => {
|
|
35
|
+
if (!isGCPLengthSourceJSON(appData)) {
|
|
36
|
+
throw new Error(`File ${this.#pathKey}.json has invalid content`);
|
|
48
37
|
}
|
|
49
38
|
|
|
50
|
-
|
|
51
|
-
},
|
|
39
|
+
this.#gcpLengthSourceJSON = appData;
|
|
52
40
|
|
|
53
|
-
|
|
54
|
-
|
|
41
|
+
return new Date(appData.GCPPrefixFormatList.date);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
get sourceData(): GCPLengthSourceJSON {
|
|
46
|
+
return this.#gcpLengthSourceJSON;
|
|
47
|
+
}
|
|
55
48
|
}
|
|
56
49
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
get nextCheckDateTime(): Promisable<Date | undefined> {
|
|
60
|
-
return nextCheckDateTimeStorage.read();
|
|
61
|
-
}
|
|
50
|
+
class GCPLengthCacheBinarySource extends GCPLengthCache {
|
|
51
|
+
readonly #headerPathKey: string;
|
|
62
52
|
|
|
63
|
-
|
|
64
|
-
return cacheDataStorage.read()?.dateTime;
|
|
65
|
-
}
|
|
53
|
+
readonly #dataPathKey: string;
|
|
66
54
|
|
|
67
|
-
|
|
68
|
-
return makeRequired(cacheDataStorage).read();
|
|
69
|
-
}
|
|
55
|
+
#gcpLengthHeader!: GCPLengthHeader;
|
|
70
56
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
57
|
+
constructor(appDataStorage: AppDataStorage<boolean>, index: number) {
|
|
58
|
+
super(appDataStorage);
|
|
74
59
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
60
|
+
this.#headerPathKey = `${GCPLengthCache.HEADER_STORAGE_KEY}-${index}`;
|
|
61
|
+
this.#dataPathKey = `${GCPLengthCache.DATA_STORAGE_KEY}-${index}`;
|
|
62
|
+
}
|
|
78
63
|
|
|
79
|
-
|
|
80
|
-
|
|
64
|
+
get sourceDateTime(): Promise<Date> {
|
|
65
|
+
return this.appDataStorage.read(this.#headerPathKey).then((appData) => {
|
|
66
|
+
if (!isGCPLengthHeader(appData)) {
|
|
67
|
+
throw new Error(`File ${this.#headerPathKey}.json not found or has invalid content`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
this.#gcpLengthHeader = appData;
|
|
71
|
+
|
|
72
|
+
return appData.dateTime;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
81
75
|
|
|
82
|
-
|
|
83
|
-
|
|
76
|
+
get sourceData(): Promise<GCPLengthData> {
|
|
77
|
+
return this.appDataStorage.read(this.#dataPathKey, true).then((appData) => {
|
|
78
|
+
if (!(appData instanceof Uint8Array)) {
|
|
79
|
+
throw new Error(`File ${this.#dataPathKey}.bin not found or has invalid content`);
|
|
84
80
|
}
|
|
85
|
-
|
|
86
|
-
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
...this.#gcpLengthHeader,
|
|
84
|
+
data: appData
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
}
|
|
87
88
|
}
|
|
88
89
|
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
const BINARY_1_HEADER_PATH = path.resolve(DATA_DIRECTORY, "gcp-length-header-1.txt");
|
|
90
|
+
const NEXT_CHECK_DATE_TIME_PATH = path.resolve(DATA_DIRECTORY, "gcp-length-next-check-date-time.json");
|
|
92
91
|
|
|
93
|
-
const
|
|
92
|
+
const BINARY_HEADER_PATH = path.resolve(DATA_DIRECTORY, "gcp-length-header.json");
|
|
94
93
|
|
|
95
|
-
const
|
|
94
|
+
const BINARY_DATA_PATH = path.resolve(DATA_DIRECTORY, "gcp-length-data.bin");
|
|
96
95
|
|
|
97
|
-
const
|
|
96
|
+
const BINARY_1_HEADER_PATH = path.resolve(DATA_DIRECTORY, "gcp-length-header-1.json");
|
|
98
97
|
|
|
99
|
-
const
|
|
98
|
+
const BINARY_1_DATA_PATH = path.resolve(DATA_DIRECTORY, "gcp-length-data-1.bin");
|
|
100
99
|
|
|
101
|
-
const
|
|
100
|
+
const BINARY_2_HEADER_PATH = path.resolve(DATA_DIRECTORY, "gcp-length-header-2.json");
|
|
102
101
|
|
|
103
|
-
|
|
104
|
-
_disclaimer: string[];
|
|
105
|
-
GCPPrefixFormatList: {
|
|
106
|
-
date: string;
|
|
107
|
-
entry: Array<{
|
|
108
|
-
prefix: string;
|
|
109
|
-
gcpLength: number;
|
|
110
|
-
}>;
|
|
111
|
-
};
|
|
112
|
-
}
|
|
102
|
+
const BINARY_2_DATA_PATH = path.resolve(DATA_DIRECTORY, "gcp-length-data-2.bin");
|
|
113
103
|
|
|
114
104
|
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
105
|
function verifyEqual(prefix: string, node1: GCPLength.Node | undefined, node2: GCPLength.Node | undefined): void {
|
|
162
106
|
if (node1 !== undefined) {
|
|
163
107
|
if (node2 === undefined) {
|
|
@@ -184,123 +128,113 @@ describe("GS1 Company Prefix length", () => {
|
|
|
184
128
|
}
|
|
185
129
|
}
|
|
186
130
|
|
|
187
|
-
function
|
|
188
|
-
|
|
189
|
-
fs.
|
|
131
|
+
function rm(...paths: string[]): void {
|
|
132
|
+
for (const path of paths) {
|
|
133
|
+
fs.rmSync(path, {
|
|
134
|
+
force: true
|
|
135
|
+
});
|
|
190
136
|
}
|
|
191
137
|
}
|
|
192
138
|
|
|
193
|
-
function
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
139
|
+
function rmCache(): void {
|
|
140
|
+
rm(NEXT_CHECK_DATE_TIME_PATH,
|
|
141
|
+
BINARY_HEADER_PATH, BINARY_DATA_PATH,
|
|
142
|
+
BINARY_1_HEADER_PATH, BINARY_1_DATA_PATH,
|
|
143
|
+
BINARY_2_HEADER_PATH, BINARY_2_DATA_PATH
|
|
144
|
+
);
|
|
198
145
|
}
|
|
199
146
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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
|
-
};
|
|
147
|
+
function save(fileName: string, index: number): void {
|
|
148
|
+
fs.renameSync(fileName, fileName.replace(".", `-${index}.`));
|
|
149
|
+
}
|
|
215
150
|
|
|
216
|
-
|
|
217
|
-
|
|
151
|
+
function saveBinary(index: number): void {
|
|
152
|
+
save(BINARY_HEADER_PATH, index);
|
|
153
|
+
save(BINARY_DATA_PATH, index);
|
|
154
|
+
}
|
|
218
155
|
|
|
219
|
-
|
|
156
|
+
function restore(fileName: string, index: number): void {
|
|
157
|
+
fs.renameSync(fileName.replace(".", `-${index}.`), fileName);
|
|
158
|
+
}
|
|
220
159
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
160
|
+
function restoreBinary(index: number): void {
|
|
161
|
+
restore(BINARY_HEADER_PATH, index);
|
|
162
|
+
restore(BINARY_DATA_PATH, index);
|
|
163
|
+
}
|
|
225
164
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
}
|
|
229
|
-
};
|
|
165
|
+
beforeAll(rmCache);
|
|
166
|
+
afterAll(rmCache);
|
|
230
167
|
|
|
231
|
-
|
|
232
|
-
const
|
|
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");
|
|
168
|
+
test("Load", async () => {
|
|
169
|
+
const appDataStorage = new (await LocalAppDataStorage)(DATA_DIRECTORY);
|
|
242
170
|
|
|
243
|
-
|
|
171
|
+
const gcpLengthCacheJSON1Source = new GCPLengthCacheJSONSource(appDataStorage, 1);
|
|
172
|
+
const gcpLengthCacheJSON2Source = new GCPLengthCacheJSONSource(appDataStorage, 2);
|
|
173
|
+
const gcpLengthCacheBinary1Source = new GCPLengthCacheBinarySource(appDataStorage, 1);
|
|
174
|
+
const gcpLengthCacheBinary2Source = new GCPLengthCacheBinarySource(appDataStorage, 2);
|
|
244
175
|
|
|
245
176
|
let root1: GCPLength.Root | undefined;
|
|
177
|
+
let root2: GCPLength.Root | undefined;
|
|
178
|
+
let nextCheckDateTime: Date | undefined;
|
|
246
179
|
|
|
247
|
-
// Binary
|
|
248
|
-
await expect((
|
|
249
|
-
root1 =
|
|
250
|
-
})
|
|
180
|
+
// Binary not available, JSON 1 available.
|
|
181
|
+
await expect(GCPLength.loadData(gcpLengthCacheJSON1Source).then((root) => {
|
|
182
|
+
root1 = root;
|
|
183
|
+
})).resolves.not.toThrowError(RangeError);
|
|
251
184
|
|
|
252
|
-
|
|
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);
|
|
185
|
+
nextCheckDateTime = await gcpLengthCacheJSON1Source.nextCheckDateTime;
|
|
256
186
|
|
|
257
187
|
expect(root1).not.toBeUndefined();
|
|
188
|
+
expect(nextCheckDateTime).not.toBeUndefined();
|
|
258
189
|
|
|
259
|
-
|
|
190
|
+
// Check next check date/time is a day from now.
|
|
191
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- Known to be defined.
|
|
192
|
+
expect(new Date().getTime() + 24 * 60 * 60 * 1000 - nextCheckDateTime!.getTime()).toBeLessThan(10000);
|
|
260
193
|
|
|
261
|
-
// Binary
|
|
262
|
-
await expect((
|
|
263
|
-
root2 =
|
|
264
|
-
})
|
|
194
|
+
// Binary available, binary 1 not available but not in next check date/time window.
|
|
195
|
+
await expect(GCPLength.loadData(gcpLengthCacheBinary1Source).then((root) => {
|
|
196
|
+
root2 = root;
|
|
197
|
+
})).resolves.not.toThrowError(RangeError);
|
|
265
198
|
|
|
266
199
|
expect(root2).not.toBeUndefined();
|
|
267
200
|
|
|
268
|
-
// Load from JSON 1 equal to load from binary
|
|
201
|
+
// Load from JSON 1 equal to load from binary.
|
|
269
202
|
expect(() => {
|
|
270
203
|
verifyEqual("", root1, root2);
|
|
271
204
|
}).not.toThrow(RangeError);
|
|
272
205
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
root2 = undefined;
|
|
206
|
+
saveBinary(1);
|
|
207
|
+
rm(NEXT_CHECK_DATE_TIME_PATH);
|
|
276
208
|
|
|
277
|
-
// Binary
|
|
278
|
-
await expect((
|
|
279
|
-
root2 =
|
|
280
|
-
})
|
|
209
|
+
// Binary not available, JSON 2 available.
|
|
210
|
+
await expect(GCPLength.loadData(gcpLengthCacheJSON2Source).then((root) => {
|
|
211
|
+
root2 = root;
|
|
212
|
+
})).resolves.not.toThrowError(RangeError);
|
|
213
|
+
|
|
214
|
+
nextCheckDateTime = await gcpLengthCacheJSON2Source.nextCheckDateTime;
|
|
281
215
|
|
|
282
|
-
expect(nextCheckDateTime).not.toBeUndefined();
|
|
283
216
|
expect(root2).not.toBeUndefined();
|
|
217
|
+
expect(nextCheckDateTime).not.toBeUndefined();
|
|
284
218
|
|
|
285
|
-
|
|
219
|
+
saveBinary(2);
|
|
220
|
+
restoreBinary(1);
|
|
286
221
|
|
|
287
|
-
// Binary
|
|
288
|
-
await expect((
|
|
289
|
-
root2 =
|
|
290
|
-
})
|
|
222
|
+
// Binary available, binary 2 available and more recent but not in next check date/time window.
|
|
223
|
+
await expect(GCPLength.loadData(gcpLengthCacheBinary2Source).then((root) => {
|
|
224
|
+
root2 = root;
|
|
225
|
+
})).resolves.not.toThrowError(RangeError);
|
|
291
226
|
|
|
292
227
|
// No change.
|
|
293
228
|
expect(() => {
|
|
294
229
|
verifyEqual("", root1, root2);
|
|
295
230
|
}).not.toThrow(RangeError);
|
|
296
231
|
|
|
297
|
-
|
|
298
|
-
nextCheckDateTime = new Date();
|
|
232
|
+
await gcpLengthCacheBinary2Source.update(new Date());
|
|
299
233
|
|
|
300
234
|
// Binary 1 available, binary 2 available and more recent and in next check date/time window.
|
|
301
|
-
await expect((
|
|
302
|
-
root2 =
|
|
303
|
-
})
|
|
235
|
+
await expect(GCPLength.loadData(gcpLengthCacheBinary2Source).then((root) => {
|
|
236
|
+
root2 = root;
|
|
237
|
+
})).resolves.not.toThrowError(RangeError);
|
|
304
238
|
|
|
305
239
|
expect(root2).not.toBeUndefined();
|
|
306
240
|
|
|
@@ -308,12 +242,24 @@ describe("GS1 Company Prefix length", () => {
|
|
|
308
242
|
expect(() => {
|
|
309
243
|
verifyEqual("", root1, root2);
|
|
310
244
|
}).toThrow(RangeError);
|
|
311
|
-
|
|
312
|
-
unlinkBinaries();
|
|
313
245
|
});
|
|
314
246
|
|
|
315
247
|
test("Identifiers", async () => {
|
|
316
|
-
const
|
|
248
|
+
const gcpLengthCacheJSON2Source = new class extends GCPLengthCacheJSONSource {
|
|
249
|
+
override get nextCheckDateTime(): Promise<Date | undefined> {
|
|
250
|
+
return Promise.resolve(undefined);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
override get cacheDateTime(): Promise<Date | undefined> {
|
|
254
|
+
return Promise.resolve(undefined);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
override async update(): Promise<void> {
|
|
258
|
+
return Promise.resolve();
|
|
259
|
+
}
|
|
260
|
+
}(new (await LocalAppDataStorage)(DATA_DIRECTORY), 2);
|
|
261
|
+
|
|
262
|
+
const tempRoot = await GCPLength.loadData(gcpLengthCacheJSON2Source);
|
|
317
263
|
|
|
318
264
|
expect(tempRoot).not.toBeUndefined();
|
|
319
265
|
|
|
@@ -333,7 +279,7 @@ describe("GS1 Company Prefix length", () => {
|
|
|
333
279
|
}
|
|
334
280
|
}
|
|
335
281
|
|
|
336
|
-
const gcpLengthJSON =
|
|
282
|
+
const gcpLengthJSON = gcpLengthCacheJSON2Source.sourceData;
|
|
337
283
|
const entries = gcpLengthJSON.GCPPrefixFormatList.entry;
|
|
338
284
|
|
|
339
285
|
for (let i = 0; i < 1000; i++) {
|
|
@@ -366,40 +312,33 @@ describe("GS1 Company Prefix length", () => {
|
|
|
366
312
|
}
|
|
367
313
|
});
|
|
368
314
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
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
|
-
// });
|
|
315
|
+
test("Remote", async () => {
|
|
316
|
+
let savedNextCheckDateTime: Date | undefined = undefined;
|
|
317
|
+
let savedCacheDateTime: Date | undefined = undefined;
|
|
318
|
+
let savedCacheData: GCPLengthData | undefined = undefined;
|
|
319
|
+
|
|
320
|
+
const gcpLengthCache = new class extends RemoteGCPLengthCache {
|
|
321
|
+
override get nextCheckDateTime(): Promise<Date | undefined> {
|
|
322
|
+
return Promise.resolve(savedNextCheckDateTime);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
override get cacheDateTime(): Promise<Date | undefined> {
|
|
326
|
+
return Promise.resolve(savedCacheDateTime);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
override async update(nextCheckDateTime: Date, cacheDateTime?: Date, cacheData?: GCPLengthData): Promise<void> {
|
|
330
|
+
savedNextCheckDateTime = nextCheckDateTime;
|
|
331
|
+
savedCacheDateTime = cacheDateTime;
|
|
332
|
+
savedCacheData = cacheData;
|
|
333
|
+
|
|
334
|
+
return Promise.resolve();
|
|
335
|
+
}
|
|
336
|
+
}(new (await LocalAppDataStorage)(DATA_DIRECTORY));
|
|
337
|
+
|
|
338
|
+
await expect(GCPLength.loadData(gcpLengthCache)).resolves.not.toThrowError(RangeError);
|
|
339
|
+
|
|
340
|
+
expect(savedNextCheckDateTime).not.toBeUndefined();
|
|
341
|
+
expect(savedCacheDateTime).not.toBeUndefined();
|
|
342
|
+
expect(savedCacheData).not.toBeUndefined();
|
|
343
|
+
});
|
|
405
344
|
});
|