@aidc-toolkit/gs1 0.9.1 → 0.9.3
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/.idea/runConfigurations/eslint.xml +12 -0
- package/eslint.config.js +1 -16
- package/package.json +10 -14
- package/src/check.ts +9 -15
- package/src/idkey.ts +62 -63
- package/src/locale/fr/locale_strings.ts +34 -0
- package/src/locale/i18n.ts +5 -1
- package/src/locale/i18next.d.ts +6 -0
- package/test/check.test.ts +6 -12
- package/test/idkey.test.ts +32 -20
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<component name="ProjectRunConfigurationManager">
|
|
2
|
+
<configuration default="false" name="eslint" type="js.build_tools.npm" nameIsGenerated="true">
|
|
3
|
+
<package-json value="$PROJECT_DIR$/package.json" />
|
|
4
|
+
<command value="run" />
|
|
5
|
+
<scripts>
|
|
6
|
+
<script value="eslint" />
|
|
7
|
+
</scripts>
|
|
8
|
+
<node-interpreter value="project" />
|
|
9
|
+
<envs />
|
|
10
|
+
<method v="2" />
|
|
11
|
+
</configuration>
|
|
12
|
+
</component>
|
package/eslint.config.js
CHANGED
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
import tseslint from "typescript-eslint";
|
|
2
|
-
import js from "@eslint/js";
|
|
3
|
-
import stylistic from "@stylistic/eslint-plugin";
|
|
4
|
-
import jsdoc from "eslint-plugin-jsdoc";
|
|
5
|
-
import esLintConfigLove from "eslint-config-love";
|
|
6
1
|
import { esLintConfigAIDCToolkit } from "@aidc-toolkit/dev";
|
|
7
2
|
|
|
8
|
-
export default
|
|
9
|
-
{
|
|
10
|
-
ignores: ["eslint.config.js", "dist"]
|
|
11
|
-
},
|
|
12
|
-
js.configs.recommended,
|
|
13
|
-
...tseslint.configs.strictTypeChecked,
|
|
14
|
-
stylistic.configs["recommended-flat"],
|
|
15
|
-
jsdoc.configs["flat/recommended-typescript"],
|
|
16
|
-
esLintConfigLove,
|
|
17
|
-
esLintConfigAIDCToolkit
|
|
18
|
-
);
|
|
3
|
+
export default esLintConfigAIDCToolkit;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aidc-toolkit/gs1",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.3",
|
|
4
4
|
"description": "GS1 AIDC Toolkit",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -21,25 +21,21 @@
|
|
|
21
21
|
"scripts": {
|
|
22
22
|
"eslint": "eslint .",
|
|
23
23
|
"build": "tsup src/index.ts --clean --format cjs,esm --dts",
|
|
24
|
-
"build-
|
|
24
|
+
"build-doc": "npm run build && tsc src/index.ts --outDir dist --target esnext --moduleResolution nodenext --module nodenext --emitDeclarationOnly --declaration --declarationMap",
|
|
25
25
|
"test": "vitest run"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@aidc-toolkit/dev": "^0.9.
|
|
29
|
-
"
|
|
30
|
-
"@stylistic/eslint-plugin": "^2.8.0",
|
|
31
|
-
"eslint-config-love": "^71.0.0",
|
|
32
|
-
"eslint-plugin-jsdoc": "^50.3.0",
|
|
28
|
+
"@aidc-toolkit/dev": "^0.9.3",
|
|
29
|
+
"eslint": "^9.14.0",
|
|
33
30
|
"ts-node": "^10.9.2",
|
|
34
|
-
"tsup": "^8.3.
|
|
35
|
-
"typescript": "^5.6.
|
|
36
|
-
"
|
|
37
|
-
"vitest": "^2.1.1"
|
|
31
|
+
"tsup": "^8.3.5",
|
|
32
|
+
"typescript": "^5.6.3",
|
|
33
|
+
"vitest": "^2.1.5"
|
|
38
34
|
},
|
|
39
35
|
"dependencies": {
|
|
40
|
-
"@aidc-toolkit/core": "^0.9.
|
|
41
|
-
"@aidc-toolkit/utility": "^0.9.
|
|
42
|
-
"i18next": "^23.
|
|
36
|
+
"@aidc-toolkit/core": "^0.9.3",
|
|
37
|
+
"@aidc-toolkit/utility": "^0.9.3",
|
|
38
|
+
"i18next": "^23.16.5",
|
|
43
39
|
"ts-mixer": "^6.0.4"
|
|
44
40
|
}
|
|
45
41
|
}
|
package/src/check.ts
CHANGED
|
@@ -55,17 +55,15 @@ export function checkDigitSum(exchangeWeights: boolean, s: string): number {
|
|
|
55
55
|
let weight3 = (s.length + Number(exchangeWeights)) % 2 === 0;
|
|
56
56
|
|
|
57
57
|
// Calculate sum of each character value multiplied by the weight at its position.
|
|
58
|
-
|
|
59
|
-
return NUMERIC_CREATOR.characterIndexes(s).reduce((accumulator, characterIndex, index) => {
|
|
58
|
+
return NUMERIC_CREATOR.characterIndexes(s).reduce<number>((accumulator, characterIndex, index) => {
|
|
60
59
|
if (characterIndex === undefined) {
|
|
61
60
|
throw new RangeError(`Invalid character '${s.charAt(index)}' at position ${index + 1}`);
|
|
62
61
|
}
|
|
63
62
|
|
|
64
63
|
weight3 = !weight3;
|
|
65
64
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}, 0)!;
|
|
65
|
+
return accumulator + (weight3 ? THREE_WEIGHT_RESULTS[characterIndex] : characterIndex);
|
|
66
|
+
}, 0);
|
|
69
67
|
}
|
|
70
68
|
|
|
71
69
|
/**
|
|
@@ -118,16 +116,14 @@ function priceWeightSum(weightsResults: ReadonlyArray<readonly number[]>, s: str
|
|
|
118
116
|
const characterIndexes = NUMERIC_CREATOR.characterIndexes(s);
|
|
119
117
|
|
|
120
118
|
// Calculate sum of each weight result for each digit at its position.
|
|
121
|
-
|
|
122
|
-
return characterIndexes.reduce((accumulator, characterIndex, index) => {
|
|
119
|
+
return characterIndexes.reduce<number>((accumulator, characterIndex, index) => {
|
|
123
120
|
if (characterIndex === undefined) {
|
|
124
121
|
throw new RangeError(`Invalid character '${s.charAt(index)}' at position ${index + 1}`);
|
|
125
122
|
}
|
|
126
123
|
|
|
127
124
|
// Add the weight result of the character index to the accumulator.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}, 0)!;
|
|
125
|
+
return accumulator + weightsResults[index][characterIndex];
|
|
126
|
+
}, 0);
|
|
131
127
|
}
|
|
132
128
|
|
|
133
129
|
/**
|
|
@@ -196,15 +192,13 @@ export function checkCharacterPair(s: string): string {
|
|
|
196
192
|
}
|
|
197
193
|
|
|
198
194
|
// Calculate sum of each character value multiplied by the weight at its position, mod 1021.
|
|
199
|
-
|
|
200
|
-
const checkCharacterPairSum = AI82_CREATOR.characterIndexes(s).reduce((accumulator, characterIndex, index) => {
|
|
195
|
+
const checkCharacterPairSum = AI82_CREATOR.characterIndexes(s).reduce<number>((accumulator, characterIndex, index) => {
|
|
201
196
|
if (characterIndex === undefined) {
|
|
202
197
|
throw new RangeError(`Invalid character '${s.charAt(index)}' at position ${index + 1}`);
|
|
203
198
|
}
|
|
204
199
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}, 0)! % 1021;
|
|
200
|
+
return accumulator + characterIndex * CHECK_CHARACTER_WEIGHTS[weightIndexStart + index];
|
|
201
|
+
}, 0) % 1021;
|
|
208
202
|
|
|
209
203
|
const checkCharacterPairSumMod32 = checkCharacterPairSum % 32;
|
|
210
204
|
|
package/src/idkey.ts
CHANGED
|
@@ -131,7 +131,7 @@ export enum CharacterSet {
|
|
|
131
131
|
export interface IdentificationKeyValidation extends StringValidation {
|
|
132
132
|
/**
|
|
133
133
|
* Position offset within a larger string. Strings are sometimes composed of multiple substrings; this parameter
|
|
134
|
-
* ensures that the
|
|
134
|
+
* ensures that the error notes the proper position in the string.
|
|
135
135
|
*/
|
|
136
136
|
positionOffset?: number | undefined;
|
|
137
137
|
}
|
|
@@ -170,7 +170,7 @@ export interface IdentificationKeyValidator<V extends IdentificationKeyValidatio
|
|
|
170
170
|
get referenceValidator(): CharacterSetValidator;
|
|
171
171
|
|
|
172
172
|
/**
|
|
173
|
-
* Validate an identification key and throw an
|
|
173
|
+
* Validate an identification key and throw an error if validation fails.
|
|
174
174
|
*
|
|
175
175
|
* @param identificationKey
|
|
176
176
|
* Identification key.
|
|
@@ -185,6 +185,10 @@ export interface IdentificationKeyValidator<V extends IdentificationKeyValidatio
|
|
|
185
185
|
* Abstract identification key validator. Implements common functionality for an identification key validator.
|
|
186
186
|
*/
|
|
187
187
|
abstract class AbstractIdentificationKeyValidator<V extends IdentificationKeyValidation = IdentificationKeyValidation> implements IdentificationKeyValidator<V> {
|
|
188
|
+
private static readonly CHARACTER_SET_CREATORS = [
|
|
189
|
+
NUMERIC_CREATOR, AI82_CREATOR, AI39_CREATOR
|
|
190
|
+
];
|
|
191
|
+
|
|
188
192
|
/**
|
|
189
193
|
* Identification key type.
|
|
190
194
|
*/
|
|
@@ -206,7 +210,7 @@ abstract class AbstractIdentificationKeyValidator<V extends IdentificationKeyVal
|
|
|
206
210
|
private readonly _referenceCharacterSet: CharacterSet;
|
|
207
211
|
|
|
208
212
|
/**
|
|
209
|
-
*
|
|
213
|
+
* Reference validator.
|
|
210
214
|
*/
|
|
211
215
|
private readonly _referenceValidator: CharacterSetValidator;
|
|
212
216
|
|
|
@@ -220,23 +224,7 @@ abstract class AbstractIdentificationKeyValidator<V extends IdentificationKeyVal
|
|
|
220
224
|
* Character set validator.
|
|
221
225
|
*/
|
|
222
226
|
protected static validatorFor(characterSet: CharacterSet): CharacterSetValidator {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
switch (characterSet) {
|
|
226
|
-
case CharacterSet.Numeric:
|
|
227
|
-
characterSetValidator = NUMERIC_CREATOR;
|
|
228
|
-
break;
|
|
229
|
-
|
|
230
|
-
case CharacterSet.AI82:
|
|
231
|
-
characterSetValidator = AI82_CREATOR;
|
|
232
|
-
break;
|
|
233
|
-
|
|
234
|
-
case CharacterSet.AI39:
|
|
235
|
-
characterSetValidator = AI39_CREATOR;
|
|
236
|
-
break;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
return characterSetValidator;
|
|
227
|
+
return AbstractIdentificationKeyValidator.CHARACTER_SET_CREATORS[characterSet];
|
|
240
228
|
}
|
|
241
229
|
|
|
242
230
|
/**
|
|
@@ -298,7 +286,7 @@ abstract class AbstractIdentificationKeyValidator<V extends IdentificationKeyVal
|
|
|
298
286
|
}
|
|
299
287
|
|
|
300
288
|
/**
|
|
301
|
-
* Pad an identification key on the left with
|
|
289
|
+
* Pad an identification key on the left with zero-value character for validation purposes. This is done to align an
|
|
302
290
|
* identification key with a position offset for any error message that may be thrown by the reference validator.
|
|
303
291
|
*
|
|
304
292
|
* @param identificationKey
|
|
@@ -310,9 +298,9 @@ abstract class AbstractIdentificationKeyValidator<V extends IdentificationKeyVal
|
|
|
310
298
|
* @returns
|
|
311
299
|
* Padded identification key.
|
|
312
300
|
*/
|
|
313
|
-
protected
|
|
301
|
+
protected padIdentificationKey(identificationKey: string, validation: IdentificationKeyValidation | undefined): string {
|
|
314
302
|
// Identification key is returned as is if position offset is undefined.
|
|
315
|
-
return validation?.positionOffset === undefined ? identificationKey :
|
|
303
|
+
return validation?.positionOffset === undefined ? identificationKey : this.referenceValidator.character(0).repeat(validation.positionOffset).concat(identificationKey);
|
|
316
304
|
}
|
|
317
305
|
|
|
318
306
|
/**
|
|
@@ -427,7 +415,7 @@ abstract class AbstractNumericIdentificationKeyValidator extends AbstractIdentif
|
|
|
427
415
|
}
|
|
428
416
|
|
|
429
417
|
// Validating the check digit will also validate the characters.
|
|
430
|
-
if (!hasValidCheckDigit(
|
|
418
|
+
if (!hasValidCheckDigit(this.padIdentificationKey(identificationKey, validation))) {
|
|
431
419
|
throw new RangeError(i18next.t("IdentificationKey.invalidCheckDigit", {
|
|
432
420
|
ns: gs1NS
|
|
433
421
|
}));
|
|
@@ -711,7 +699,7 @@ export class SerializableNumericIdentificationKeyValidator extends NonGTINNumeri
|
|
|
711
699
|
private readonly _serialComponentCharacterSet: CharacterSet;
|
|
712
700
|
|
|
713
701
|
/**
|
|
714
|
-
* Serial component
|
|
702
|
+
* Serial component validation parameters.
|
|
715
703
|
*/
|
|
716
704
|
private readonly _serialComponentValidation: CharacterSetValidation;
|
|
717
705
|
|
|
@@ -855,7 +843,7 @@ export class NonNumericIdentificationKeyValidator extends AbstractIdentification
|
|
|
855
843
|
}
|
|
856
844
|
|
|
857
845
|
/**
|
|
858
|
-
* Validate a non-numeric identification key and throw an
|
|
846
|
+
* Validate a non-numeric identification key and throw an error if validation fails.
|
|
859
847
|
*
|
|
860
848
|
* @param identificationKey
|
|
861
849
|
* Identification key.
|
|
@@ -874,7 +862,7 @@ export class NonNumericIdentificationKeyValidator extends AbstractIdentification
|
|
|
874
862
|
positionOffset: validation?.positionOffset
|
|
875
863
|
});
|
|
876
864
|
// Validating the check character pair will also validate the characters.
|
|
877
|
-
} else if (!hasValidCheckCharacterPair(
|
|
865
|
+
} else if (!hasValidCheckCharacterPair(this.padIdentificationKey(identificationKey, validation))) {
|
|
878
866
|
throw new RangeError(i18next.t("IdentificationKey.invalidCheckCharacterPair", {
|
|
879
867
|
ns: gs1NS
|
|
880
868
|
}));
|
|
@@ -1002,12 +990,12 @@ abstract class AbstractIdentificationKeyCreator implements IdentificationKeyCrea
|
|
|
1002
990
|
/**
|
|
1003
991
|
* Prefix manager.
|
|
1004
992
|
*/
|
|
1005
|
-
private _prefixManager
|
|
993
|
+
private _prefixManager!: PrefixManager;
|
|
1006
994
|
|
|
1007
995
|
/**
|
|
1008
996
|
* Reference length.
|
|
1009
997
|
*/
|
|
1010
|
-
private _referenceLength
|
|
998
|
+
private _referenceLength!: number;
|
|
1011
999
|
|
|
1012
1000
|
/**
|
|
1013
1001
|
* Initialize the prefix manager. This method is in lieu of a constructor due to the mixin architecture.
|
|
@@ -1022,12 +1010,6 @@ abstract class AbstractIdentificationKeyCreator implements IdentificationKeyCrea
|
|
|
1022
1010
|
* Number of characters to allow for check digit or check character pair.
|
|
1023
1011
|
*/
|
|
1024
1012
|
protected init(prefixManager: PrefixManager, prefix: string, checkAllowance: number): void {
|
|
1025
|
-
// Verify that prefix manager has not already been assigned.
|
|
1026
|
-
if (this._prefixManager !== undefined) {
|
|
1027
|
-
// Should never get here.
|
|
1028
|
-
throw new Error("Not supported");
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
1013
|
this._prefixManager = prefixManager;
|
|
1032
1014
|
|
|
1033
1015
|
// Reference length allows for prefix and optionally check digit or check character pair.
|
|
@@ -1055,9 +1037,7 @@ abstract class AbstractIdentificationKeyCreator implements IdentificationKeyCrea
|
|
|
1055
1037
|
* @inheritDoc
|
|
1056
1038
|
*/
|
|
1057
1039
|
get prefixManager(): PrefixManager {
|
|
1058
|
-
|
|
1059
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1060
|
-
return this._prefixManager!;
|
|
1040
|
+
return this._prefixManager;
|
|
1061
1041
|
}
|
|
1062
1042
|
|
|
1063
1043
|
/**
|
|
@@ -1071,8 +1051,7 @@ abstract class AbstractIdentificationKeyCreator implements IdentificationKeyCrea
|
|
|
1071
1051
|
* @inheritDoc
|
|
1072
1052
|
*/
|
|
1073
1053
|
get referenceLength(): number {
|
|
1074
|
-
|
|
1075
|
-
return this._referenceLength!;
|
|
1054
|
+
return this._referenceLength;
|
|
1076
1055
|
}
|
|
1077
1056
|
|
|
1078
1057
|
abstract validate(identificationKey: string, validation?: IdentificationKeyValidation): void;
|
|
@@ -1138,7 +1117,7 @@ abstract class AbstractNumericIdentificationKeyCreator extends AbstractIdentific
|
|
|
1138
1117
|
/**
|
|
1139
1118
|
* Capacity.
|
|
1140
1119
|
*/
|
|
1141
|
-
private _capacity
|
|
1120
|
+
private _capacity!: number;
|
|
1142
1121
|
|
|
1143
1122
|
/**
|
|
1144
1123
|
* Tweak for sparse creation.
|
|
@@ -1167,8 +1146,7 @@ abstract class AbstractNumericIdentificationKeyCreator extends AbstractIdentific
|
|
|
1167
1146
|
* @inheritDoc
|
|
1168
1147
|
*/
|
|
1169
1148
|
get capacity(): number {
|
|
1170
|
-
|
|
1171
|
-
return this._capacity!;
|
|
1149
|
+
return this._capacity;
|
|
1172
1150
|
}
|
|
1173
1151
|
|
|
1174
1152
|
/**
|
|
@@ -1210,7 +1188,7 @@ abstract class AbstractNumericIdentificationKeyCreator extends AbstractIdentific
|
|
|
1210
1188
|
*/
|
|
1211
1189
|
create(values: Iterable<number | bigint>, sparse?: boolean): IterableIterator<string>;
|
|
1212
1190
|
|
|
1213
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
1191
|
+
// eslint-disable-next-line jsdoc/require-jsdoc -- Implementation of overloaded signatures.
|
|
1214
1192
|
create(valueOrValues: number | bigint | Iterable<number | bigint>, sparse = false): string | IterableIterator<string> {
|
|
1215
1193
|
return NUMERIC_CREATOR.create(this.referenceLength, valueOrValues, Exclusion.None, sparse ? this.tweak : undefined, reference => this.buildIdentificationKey(reference));
|
|
1216
1194
|
}
|
|
@@ -1368,7 +1346,7 @@ export class GTINCreator extends Mixin(GTINValidator, AbstractNumericIdentificat
|
|
|
1368
1346
|
*/
|
|
1369
1347
|
createGTIN14(indicatorDigit: string, values: Iterable<number | bigint>, sparse?: boolean): IterableIterator<string>;
|
|
1370
1348
|
|
|
1371
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
1349
|
+
// eslint-disable-next-line jsdoc/require-jsdoc -- Implementation of overloaded signatures.
|
|
1372
1350
|
createGTIN14(indicatorDigit: string, valueOrValues: number | bigint | Iterable<number | bigint>, sparse = false): string | IterableIterator<string> {
|
|
1373
1351
|
NUMERIC_CREATOR.validate(indicatorDigit, GTINCreator.REQUIRED_INDICATOR_DIGIT_VALIDATION);
|
|
1374
1352
|
|
|
@@ -1492,7 +1470,7 @@ export class GTINCreator extends Mixin(GTINValidator, AbstractNumericIdentificat
|
|
|
1492
1470
|
break;
|
|
1493
1471
|
|
|
1494
1472
|
case GTINType.GTIN8 as number:
|
|
1495
|
-
if (gtin.
|
|
1473
|
+
if (!gtin.startsWith("0")) {
|
|
1496
1474
|
// GTIN is GTIN-8.
|
|
1497
1475
|
normalizedGTIN = gtin;
|
|
1498
1476
|
} else {
|
|
@@ -1625,7 +1603,7 @@ export class SerializableNumericIdentificationKeyCreator extends Mixin(Serializa
|
|
|
1625
1603
|
*/
|
|
1626
1604
|
private concatenateValidated(baseIdentificationKey: string, serialComponents: Iterable<string>): IterableIterator<string>;
|
|
1627
1605
|
|
|
1628
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
1606
|
+
// eslint-disable-next-line jsdoc/require-jsdoc -- Implementation of overloaded signatures.
|
|
1629
1607
|
private concatenateValidated(baseIdentificationKey: string, serialComponent: string | Iterable<string>): string | IterableIterator<string> {
|
|
1630
1608
|
let result: string | IterableIterator<string>;
|
|
1631
1609
|
|
|
@@ -1676,7 +1654,7 @@ export class SerializableNumericIdentificationKeyCreator extends Mixin(Serializa
|
|
|
1676
1654
|
*/
|
|
1677
1655
|
createSerialized(value: number, serialComponents: Iterable<string>, sparse?: boolean): IterableIterator<string>;
|
|
1678
1656
|
|
|
1679
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
1657
|
+
// eslint-disable-next-line jsdoc/require-jsdoc -- Implementation of overloaded signatures.
|
|
1680
1658
|
createSerialized(value: number, serialComponent: string | Iterable<string>, sparse = false): string | IterableIterator<string> {
|
|
1681
1659
|
return this.concatenateValidated(this.create(value, sparse), serialComponent);
|
|
1682
1660
|
}
|
|
@@ -1709,7 +1687,7 @@ export class SerializableNumericIdentificationKeyCreator extends Mixin(Serializa
|
|
|
1709
1687
|
*/
|
|
1710
1688
|
concatenate(baseIdentificationKey: string, serialComponents: Iterable<string>): IterableIterator<string>;
|
|
1711
1689
|
|
|
1712
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
1690
|
+
// eslint-disable-next-line jsdoc/require-jsdoc -- Implementation of overloaded signatures.
|
|
1713
1691
|
concatenate(baseIdentificationKey: string, serialComponent: string | Iterable<string>): string | IterableIterator<string> {
|
|
1714
1692
|
this.validate(baseIdentificationKey);
|
|
1715
1693
|
|
|
@@ -1722,7 +1700,7 @@ export class SerializableNumericIdentificationKeyCreator extends Mixin(Serializa
|
|
|
1722
1700
|
*/
|
|
1723
1701
|
export class NonNumericIdentificationKeyCreator extends Mixin(NonNumericIdentificationKeyValidator, AbstractIdentificationKeyCreator) {
|
|
1724
1702
|
/**
|
|
1725
|
-
* Reference
|
|
1703
|
+
* Reference validation parameters.
|
|
1726
1704
|
*/
|
|
1727
1705
|
private readonly _referenceValidation: CharacterSetValidation;
|
|
1728
1706
|
|
|
@@ -1782,7 +1760,7 @@ export class NonNumericIdentificationKeyCreator extends Mixin(NonNumericIdentifi
|
|
|
1782
1760
|
*/
|
|
1783
1761
|
create(references: Iterable<string>): IterableIterator<string>;
|
|
1784
1762
|
|
|
1785
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
1763
|
+
// eslint-disable-next-line jsdoc/require-jsdoc -- Implementation of overloaded signatures.
|
|
1786
1764
|
create(referenceOrReferences: string | Iterable<string>): string | IterableIterator<string> {
|
|
1787
1765
|
let result: string | IterableIterator<string>;
|
|
1788
1766
|
|
|
@@ -1800,6 +1778,26 @@ export class NonNumericIdentificationKeyCreator extends Mixin(NonNumericIdentifi
|
|
|
1800
1778
|
}
|
|
1801
1779
|
}
|
|
1802
1780
|
|
|
1781
|
+
/**
|
|
1782
|
+
* Prefix validation parameters.
|
|
1783
|
+
*/
|
|
1784
|
+
interface PrefixValidation extends CharacterSetValidation {
|
|
1785
|
+
/**
|
|
1786
|
+
* Minimum length.
|
|
1787
|
+
*/
|
|
1788
|
+
minimumLength: number;
|
|
1789
|
+
|
|
1790
|
+
/**
|
|
1791
|
+
* Maximum length.
|
|
1792
|
+
*/
|
|
1793
|
+
maximumLength: number;
|
|
1794
|
+
|
|
1795
|
+
/**
|
|
1796
|
+
* Callback to localized prefix type name.
|
|
1797
|
+
*/
|
|
1798
|
+
component: () => string;
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1803
1801
|
/**
|
|
1804
1802
|
* Prefix manager. This is the core class for identification key creation.
|
|
1805
1803
|
*
|
|
@@ -1860,7 +1858,7 @@ export class PrefixManager {
|
|
|
1860
1858
|
/**
|
|
1861
1859
|
* Validation parameters for GS1 Company Prefix.
|
|
1862
1860
|
*/
|
|
1863
|
-
private static readonly GS1_COMPANY_PREFIX_VALIDATION:
|
|
1861
|
+
private static readonly GS1_COMPANY_PREFIX_VALIDATION: PrefixValidation = {
|
|
1864
1862
|
minimumLength: PrefixManager.GS1_COMPANY_PREFIX_MINIMUM_LENGTH,
|
|
1865
1863
|
maximumLength: PrefixManager.GS1_COMPANY_PREFIX_MAXIMUM_LENGTH,
|
|
1866
1864
|
component: () => i18next.t("Prefix.gs1CompanyPrefix", {
|
|
@@ -1871,7 +1869,7 @@ export class PrefixManager {
|
|
|
1871
1869
|
/**
|
|
1872
1870
|
* Validation parameters for U.P.C. Company Prefix expressed as GS1 Company Prefix.
|
|
1873
1871
|
*/
|
|
1874
|
-
private static readonly UPC_COMPANY_PREFIX_AS_GS1_COMPANY_PREFIX_VALIDATION:
|
|
1872
|
+
private static readonly UPC_COMPANY_PREFIX_AS_GS1_COMPANY_PREFIX_VALIDATION: PrefixValidation = {
|
|
1875
1873
|
minimumLength: PrefixManager.UPC_COMPANY_PREFIX_MINIMUM_LENGTH + 1,
|
|
1876
1874
|
maximumLength: PrefixManager.UPC_COMPANY_PREFIX_MAXIMUM_LENGTH + 1,
|
|
1877
1875
|
component: () => i18next.t("Prefix.gs1CompanyPrefix", {
|
|
@@ -1882,7 +1880,7 @@ export class PrefixManager {
|
|
|
1882
1880
|
/**
|
|
1883
1881
|
* Validation parameters for GS1-8 Prefix expressed as GS1 Company Prefix.
|
|
1884
1882
|
*/
|
|
1885
|
-
private static readonly GS1_8_PREFIX_AS_GS1_COMPANY_PREFIX_VALIDATION:
|
|
1883
|
+
private static readonly GS1_8_PREFIX_AS_GS1_COMPANY_PREFIX_VALIDATION: PrefixValidation = {
|
|
1886
1884
|
minimumLength: PrefixManager.GS1_8_PREFIX_MINIMUM_LENGTH + 5,
|
|
1887
1885
|
maximumLength: PrefixManager.GS1_8_PREFIX_MAXIMUM_LENGTH + 5,
|
|
1888
1886
|
component: () => i18next.t("Prefix.gs1CompanyPrefix", {
|
|
@@ -1893,7 +1891,7 @@ export class PrefixManager {
|
|
|
1893
1891
|
/**
|
|
1894
1892
|
* Validation parameters for U.P.C. Company Prefix.
|
|
1895
1893
|
*/
|
|
1896
|
-
private static readonly UPC_COMPANY_PREFIX_VALIDATION:
|
|
1894
|
+
private static readonly UPC_COMPANY_PREFIX_VALIDATION: PrefixValidation = {
|
|
1897
1895
|
minimumLength: PrefixManager.UPC_COMPANY_PREFIX_MINIMUM_LENGTH,
|
|
1898
1896
|
maximumLength: PrefixManager.UPC_COMPANY_PREFIX_MAXIMUM_LENGTH,
|
|
1899
1897
|
component: () => i18next.t("Prefix.upcCompanyPrefix", {
|
|
@@ -1904,7 +1902,7 @@ export class PrefixManager {
|
|
|
1904
1902
|
/**
|
|
1905
1903
|
* Validation parameters for GS1-8 Prefix.
|
|
1906
1904
|
*/
|
|
1907
|
-
private static readonly GS1_8_PREFIX_VALIDATION:
|
|
1905
|
+
private static readonly GS1_8_PREFIX_VALIDATION: PrefixValidation = {
|
|
1908
1906
|
minimumLength: PrefixManager.GS1_8_PREFIX_MINIMUM_LENGTH,
|
|
1909
1907
|
maximumLength: PrefixManager.GS1_8_PREFIX_MAXIMUM_LENGTH,
|
|
1910
1908
|
component: () => i18next.t("Prefix.gs18Prefix", {
|
|
@@ -1916,7 +1914,7 @@ export class PrefixManager {
|
|
|
1916
1914
|
* Creator tweak factors. Different numeric identification key types have different tweak factors so that sparse
|
|
1917
1915
|
* creation generates different sequences for each.
|
|
1918
1916
|
*/
|
|
1919
|
-
private static readonly CREATOR_TWEAK_FACTORS_MAP
|
|
1917
|
+
private static readonly CREATOR_TWEAK_FACTORS_MAP: ReadonlyMap<IdentificationKeyType, bigint> = new Map([
|
|
1920
1918
|
[IdentificationKeyType.GTIN, 1987n],
|
|
1921
1919
|
[IdentificationKeyType.GLN, 4241n],
|
|
1922
1920
|
[IdentificationKeyType.SSCC, 8087n],
|
|
@@ -2058,9 +2056,9 @@ export class PrefixManager {
|
|
|
2058
2056
|
if (this._tweakFactor !== tweakFactor) {
|
|
2059
2057
|
this._tweakFactor = tweakFactor;
|
|
2060
2058
|
|
|
2061
|
-
this._identificationKeyCreatorsMap.
|
|
2059
|
+
for (const creator of this._identificationKeyCreatorsMap.values()) {
|
|
2062
2060
|
this.setCreatorTweak(creator);
|
|
2063
|
-
}
|
|
2061
|
+
}
|
|
2064
2062
|
}
|
|
2065
2063
|
}
|
|
2066
2064
|
|
|
@@ -2138,7 +2136,7 @@ export class PrefixManager {
|
|
|
2138
2136
|
* Position offset within a larger string.
|
|
2139
2137
|
*/
|
|
2140
2138
|
static validatePrefix(prefixType: PrefixType, allowUPCCompanyPrefix: boolean, allowGS18Prefix: boolean, prefix: string, isFromIdentificationKey = false, isNumericIdentificationKey = false, positionOffset?: number): void {
|
|
2141
|
-
let baseValidation:
|
|
2139
|
+
let baseValidation: PrefixValidation;
|
|
2142
2140
|
|
|
2143
2141
|
// Validate the prefix type and determine the prefix validation parameters.
|
|
2144
2142
|
switch (prefixType) {
|
|
@@ -2189,7 +2187,7 @@ export class PrefixManager {
|
|
|
2189
2187
|
break;
|
|
2190
2188
|
}
|
|
2191
2189
|
|
|
2192
|
-
const mergedValidation:
|
|
2190
|
+
const mergedValidation: PrefixValidation = {
|
|
2193
2191
|
...baseValidation,
|
|
2194
2192
|
positionOffset
|
|
2195
2193
|
};
|
|
@@ -2199,8 +2197,7 @@ export class PrefixManager {
|
|
|
2199
2197
|
NUMERIC_CREATOR.validate(prefix, mergedValidation);
|
|
2200
2198
|
} else if (!isNumericIdentificationKey) {
|
|
2201
2199
|
// Validate only the minimum length, allowing at least one character for the (possibly non-numeric) reference.
|
|
2202
|
-
|
|
2203
|
-
NUMERIC_CREATOR.validate(prefix.substring(0, Math.min(mergedValidation.minimumLength!, prefix.length - 1)), mergedValidation);
|
|
2200
|
+
NUMERIC_CREATOR.validate(prefix.substring(0, Math.min(mergedValidation.minimumLength, prefix.length - 1)), mergedValidation);
|
|
2204
2201
|
}
|
|
2205
2202
|
}
|
|
2206
2203
|
|
|
@@ -2230,6 +2227,8 @@ export class PrefixManager {
|
|
|
2230
2227
|
creator = constructorCallback();
|
|
2231
2228
|
|
|
2232
2229
|
this.setCreatorTweak(creator);
|
|
2230
|
+
|
|
2231
|
+
this._identificationKeyCreatorsMap.set(identificationKeyType, creator);
|
|
2233
2232
|
}
|
|
2234
2233
|
|
|
2235
2234
|
return creator;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export const localeStrings = {
|
|
2
|
+
Check: {
|
|
3
|
+
lengthOfStringForCheckCharacterPairMustBeLessThanOrEqualTo: "La longueur {{length}} de la chaîne pour la paire de caractères de vérification doit être inférieure ou égale à {{maximum Length}}"
|
|
4
|
+
},
|
|
5
|
+
IdentificationKey: {
|
|
6
|
+
identificationKeyTypeLength: "{{identificationKeyType}} doit comporter {{length}} chiffres",
|
|
7
|
+
invalidCheckDigit: "Chiffre de contrôle non valide",
|
|
8
|
+
invalidGTINLength: "Le GTIN doit comporter 13, 12, 8 ou 14 chiffres",
|
|
9
|
+
invalidGTIN14Length: "Le GTIN doit comporter 14 chiffres",
|
|
10
|
+
invalidZeroSuppressedGTIN12: "Code GTIN-12 non valide avec zéro supprimé",
|
|
11
|
+
invalidZeroSuppressibleGTIN12: "Le GTIN-12 ne peut pas être supprimé par zéro",
|
|
12
|
+
invalidZeroSuppressedGTIN12AsGTIN13: "GTIN-12 non valide avec zéro supprimé en tant que GTIN-13",
|
|
13
|
+
invalidZeroSuppressedGTIN12AsGTIN14: "GTIN-12 non valide avec zéro supprimé en tant que GTIN-14",
|
|
14
|
+
invalidGTIN13AtRetail: "Le GTIN-13 au niveau des articles de consommation au détail ne peut pas commencer par zéro",
|
|
15
|
+
invalidGTINAtRetail: "Le GTIN n'est pas pris en charge au niveau des articles de consommation au détail",
|
|
16
|
+
invalidGTINAtOtherThanRetail: "Le GTIN n'est pas pris en charge à d'autres niveaux que ceux des articles de consommation au détail",
|
|
17
|
+
indicatorDigit: "chiffre indicateur",
|
|
18
|
+
serialComponent: "composant série",
|
|
19
|
+
reference: "référence",
|
|
20
|
+
referenceCantBeAllNumeric: "La référence ne peut pas être entièrement numérique",
|
|
21
|
+
invalidCheckCharacterPair: "Paire de caractères de contrôle non valide"
|
|
22
|
+
},
|
|
23
|
+
Prefix: {
|
|
24
|
+
gs1CompanyPrefix: "Préfixe de l'entreprise GS1",
|
|
25
|
+
upcCompanyPrefix: "Préfixe de l'entreprise U.P.C.",
|
|
26
|
+
gs18Prefix: "Préfixe GS1-8",
|
|
27
|
+
gs1CompanyPrefixCantStartWith0: "Le préfixe de l'entreprise GS1 ne peut pas commencer par \"0\"",
|
|
28
|
+
gs1CompanyPrefixCantStartWith00000: "Le préfixe de l'entreprise GS1 ne peut pas commencer par \"00000\"",
|
|
29
|
+
gs1CompanyPrefixCantStartWith000000: "Le préfixe de l'entreprise GS1 ne peut pas commencer par \"000000\"",
|
|
30
|
+
upcCompanyPrefixCantStartWith0000: "Le préfixe de l'entreprise U.P.C. ne peut pas commencer par \"0000\"",
|
|
31
|
+
gs18PrefixCantStartWith0: "Le préfixe GS1-8 ne peut pas commencer par \"0\"",
|
|
32
|
+
identificationKeyTypeNotSupportedByGS18Prefix: "{{identificationKeyType}} non pris en charge par le préfixe GS1-8"
|
|
33
|
+
}
|
|
34
|
+
} as const;
|
package/src/locale/i18n.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import { i18nAddResourceBundle, i18next } from "@aidc-toolkit/core";
|
|
1
|
+
import { i18nAddResourceBundle, i18nAssertValidResources, i18next } from "@aidc-toolkit/core";
|
|
2
2
|
import { localeStrings as enLocaleStrings } from "./en/locale_strings.js";
|
|
3
|
+
import { localeStrings as frLocaleStrings } from "./fr/locale_strings.js";
|
|
3
4
|
|
|
4
5
|
export const gs1NS = "aidct_gs1";
|
|
5
6
|
|
|
7
|
+
i18nAssertValidResources(enLocaleStrings, "fr", frLocaleStrings);
|
|
8
|
+
|
|
6
9
|
i18nAddResourceBundle("en", gs1NS, enLocaleStrings);
|
|
10
|
+
i18nAddResourceBundle("fr", gs1NS, frLocaleStrings);
|
|
7
11
|
|
|
8
12
|
export default i18next;
|
package/src/locale/i18next.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import type { localeStrings } from "./en/locale_strings.js";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Internationalization module.
|
|
5
|
+
*/
|
|
3
6
|
declare module "i18next" {
|
|
7
|
+
/**
|
|
8
|
+
* Custom type options for this package.
|
|
9
|
+
*/
|
|
4
10
|
interface CustomTypeOptions {
|
|
5
11
|
resources: {
|
|
6
12
|
// Extract the type from the English locale strings object.
|
package/test/check.test.ts
CHANGED
|
@@ -40,48 +40,42 @@ describe("Check digit", () => {
|
|
|
40
40
|
});
|
|
41
41
|
|
|
42
42
|
describe("Price/weight check digit", () => {
|
|
43
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
44
43
|
function weight2Minus(characterIndex: number): number {
|
|
45
44
|
const product = characterIndex * 2;
|
|
46
45
|
|
|
47
46
|
return (product - Math.trunc(product / 10)) % 10;
|
|
48
47
|
}
|
|
49
48
|
|
|
50
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
51
49
|
function weight3(characterIndex: number): number {
|
|
52
50
|
return characterIndex * 3 % 10;
|
|
53
51
|
}
|
|
54
52
|
|
|
55
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
56
53
|
function weight5Plus(characterIndex: number): number {
|
|
57
54
|
const product = characterIndex * 5;
|
|
58
55
|
|
|
59
56
|
return (product + Math.trunc(product / 10)) % 10;
|
|
60
57
|
}
|
|
61
58
|
|
|
62
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
63
59
|
function weight5Minus(characterIndex: number): number {
|
|
64
60
|
const product = characterIndex * 5;
|
|
65
61
|
|
|
66
62
|
return (product - Math.trunc(product / 10)) % 10;
|
|
67
63
|
}
|
|
68
64
|
|
|
69
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
70
65
|
function testFourDigitPriceWeightCheckDigit(s: string): void {
|
|
71
|
-
|
|
66
|
+
// All character indexes are known to be defined.
|
|
67
|
+
const characterIndexes = NUMERIC_CREATOR.characterIndexes(s) as number[];
|
|
72
68
|
|
|
73
|
-
|
|
74
|
-
const sum = weight2Minus(characterIndexes[0]!) + weight2Minus(characterIndexes[1]!) + weight3(characterIndexes[2]!) + weight5Minus(characterIndexes[3]!);
|
|
69
|
+
const sum = weight2Minus(characterIndexes[0]) + weight2Minus(characterIndexes[1]) + weight3(characterIndexes[2]) + weight5Minus(characterIndexes[3]);
|
|
75
70
|
|
|
76
71
|
expect(fourDigitPriceWeightCheckDigit(s)).toBe(NUMERIC_CREATOR.character(sum * 3 % 10));
|
|
77
72
|
}
|
|
78
73
|
|
|
79
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
80
74
|
function testFiveDigitPriceWeightCheckDigit(s: string): void {
|
|
81
|
-
|
|
75
|
+
// All character indexes are known to be defined.
|
|
76
|
+
const characterIndexes = NUMERIC_CREATOR.characterIndexes(s) as number[];
|
|
82
77
|
|
|
83
|
-
|
|
84
|
-
const sum = weight5Plus(characterIndexes[0]!) + weight2Minus(characterIndexes[1]!) + weight5Minus(characterIndexes[2]!) + weight5Plus(characterIndexes[3]!) + weight2Minus(characterIndexes[4]!);
|
|
78
|
+
const sum = weight5Plus(characterIndexes[0]) + weight2Minus(characterIndexes[1]) + weight5Minus(characterIndexes[2]) + weight5Plus(characterIndexes[3]) + weight2Minus(characterIndexes[4]);
|
|
85
79
|
|
|
86
80
|
expect(weight5Minus(Number(fiveDigitPriceWeightCheckDigit(s)))).toBe(9 - (sum + 9) % 10);
|
|
87
81
|
}
|
package/test/idkey.test.ts
CHANGED
|
@@ -17,7 +17,8 @@ import {
|
|
|
17
17
|
GSRN_VALIDATOR,
|
|
18
18
|
GTIN12_VALIDATOR,
|
|
19
19
|
GTIN13_VALIDATOR,
|
|
20
|
-
GTIN8_VALIDATOR,
|
|
20
|
+
GTIN8_VALIDATOR,
|
|
21
|
+
GTIN_VALIDATORS,
|
|
21
22
|
GTINCreator,
|
|
22
23
|
GTINLevel,
|
|
23
24
|
GTINType,
|
|
@@ -42,7 +43,6 @@ import {
|
|
|
42
43
|
|
|
43
44
|
await i18nInit(I18NEnvironment.CLI, true);
|
|
44
45
|
|
|
45
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
46
46
|
function creatorFor(characterSet: CharacterSet): CharacterSetCreator {
|
|
47
47
|
let creator: CharacterSetCreator;
|
|
48
48
|
|
|
@@ -63,14 +63,12 @@ function creatorFor(characterSet: CharacterSet): CharacterSetCreator {
|
|
|
63
63
|
return creator;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
67
66
|
function validateIdentificationKeyValidator(creator: IdentificationKeyValidator, identificationKeyType: IdentificationKeyType, prefixType: PrefixType, length: number): void {
|
|
68
67
|
expect(creator.identificationKeyType).toBe(identificationKeyType);
|
|
69
68
|
expect(creator.prefixType).toBe(prefixType);
|
|
70
69
|
expect(creator.length).toBe(length);
|
|
71
70
|
}
|
|
72
71
|
|
|
73
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
74
72
|
function validateNumericIdentificationKeyValidator(validator: NumericIdentificationKeyValidator, isCreator: boolean, identificationKeyType: IdentificationKeyType, prefixType: PrefixType, length: number, leaderType: LeaderType): void {
|
|
75
73
|
validateIdentificationKeyValidator(validator, identificationKeyType, prefixType, length);
|
|
76
74
|
|
|
@@ -83,7 +81,6 @@ function validateNumericIdentificationKeyValidator(validator: NumericIdentificat
|
|
|
83
81
|
}
|
|
84
82
|
}
|
|
85
83
|
|
|
86
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
87
84
|
function validateGTINValidator(validator: GTINValidator, isCreator: boolean, gtinType: GTINType): void {
|
|
88
85
|
let prefixType: PrefixType;
|
|
89
86
|
|
|
@@ -109,12 +106,10 @@ function validateGTINValidator(validator: GTINValidator, isCreator: boolean, gti
|
|
|
109
106
|
expect(validator.gtinType).toBe(gtinType);
|
|
110
107
|
}
|
|
111
108
|
|
|
112
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
113
109
|
function validateNonGTINNumericIdentificationKeyValidator<T extends NonGTINNumericIdentificationKeyValidator>(validator: T, isCreator: boolean, identificationKeyType: IdentificationKeyType, length: number, leaderType: LeaderType): void {
|
|
114
110
|
validateNumericIdentificationKeyValidator(validator, isCreator, identificationKeyType, PrefixType.GS1CompanyPrefix, length, leaderType);
|
|
115
111
|
}
|
|
116
112
|
|
|
117
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
118
113
|
function validateSerializableNumericIdentificationKeyValidator(validator: SerializableNumericIdentificationKeyValidator, isCreator: boolean, identificationKeyType: IdentificationKeyType, length: number, leaderType: LeaderType, serialLength: number, serialCharacterSet: CharacterSet): void {
|
|
119
114
|
validateNonGTINNumericIdentificationKeyValidator(validator, isCreator, identificationKeyType, length, leaderType);
|
|
120
115
|
|
|
@@ -129,7 +124,6 @@ function validateSerializableNumericIdentificationKeyValidator(validator: Serial
|
|
|
129
124
|
}
|
|
130
125
|
}
|
|
131
126
|
|
|
132
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
133
127
|
function validateNonNumericIdentificationKeyValidator(validator: NonNumericIdentificationKeyValidator, isCreator: boolean, identificationKeyType: IdentificationKeyType, length: number, referenceCharacterSet: CharacterSet, requiresCheckCharacterPair: boolean): void {
|
|
134
128
|
validateIdentificationKeyValidator(validator, identificationKeyType, PrefixType.GS1CompanyPrefix, length);
|
|
135
129
|
|
|
@@ -169,7 +163,6 @@ describe("Validators", () => {
|
|
|
169
163
|
});
|
|
170
164
|
});
|
|
171
165
|
|
|
172
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
173
166
|
function validateIdentificationKeyCreators(prefixManager: PrefixManager): void {
|
|
174
167
|
let gtinType: GTINType;
|
|
175
168
|
|
|
@@ -190,9 +183,23 @@ function validateIdentificationKeyCreators(prefixManager: PrefixManager): void {
|
|
|
190
183
|
break;
|
|
191
184
|
}
|
|
192
185
|
|
|
186
|
+
expect(prefixManager.gtinCreator).toBe(prefixManager.gtinCreator);
|
|
187
|
+
|
|
193
188
|
validateGTINValidator(prefixManager.gtinCreator, true, gtinType);
|
|
194
189
|
|
|
195
190
|
if (prefixManager.prefixType !== PrefixType.GS18Prefix) {
|
|
191
|
+
expect(prefixManager.glnCreator).toBe(prefixManager.glnCreator);
|
|
192
|
+
expect(prefixManager.ssccCreator).toBe(prefixManager.ssccCreator);
|
|
193
|
+
expect(prefixManager.graiCreator).toBe(prefixManager.graiCreator);
|
|
194
|
+
expect(prefixManager.giaiCreator).toBe(prefixManager.giaiCreator);
|
|
195
|
+
expect(prefixManager.gsrnCreator).toBe(prefixManager.gsrnCreator);
|
|
196
|
+
expect(prefixManager.gdtiCreator).toBe(prefixManager.gdtiCreator);
|
|
197
|
+
expect(prefixManager.gincCreator).toBe(prefixManager.gincCreator);
|
|
198
|
+
expect(prefixManager.gsinCreator).toBe(prefixManager.gsinCreator);
|
|
199
|
+
expect(prefixManager.gcnCreator).toBe(prefixManager.gcnCreator);
|
|
200
|
+
expect(prefixManager.cpidCreator).toBe(prefixManager.cpidCreator);
|
|
201
|
+
expect(prefixManager.gmnCreator).toBe(prefixManager.gmnCreator);
|
|
202
|
+
|
|
196
203
|
validateNonGTINNumericIdentificationKeyValidator(prefixManager.glnCreator, true, IdentificationKeyType.GLN, 13, LeaderType.None);
|
|
197
204
|
validateNonGTINNumericIdentificationKeyValidator(prefixManager.ssccCreator, true, IdentificationKeyType.SSCC, 18, LeaderType.ExtensionDigit);
|
|
198
205
|
validateSerializableNumericIdentificationKeyValidator(prefixManager.graiCreator, true, IdentificationKeyType.GRAI, 13, LeaderType.None, 16, CharacterSet.AI82);
|
|
@@ -222,7 +229,6 @@ function validateIdentificationKeyCreators(prefixManager: PrefixManager): void {
|
|
|
222
229
|
describe("Prefix manager", () => {
|
|
223
230
|
let prefixManager: PrefixManager;
|
|
224
231
|
|
|
225
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
226
232
|
function validateGTINStartsWithPrefix(length: number): void {
|
|
227
233
|
expect(prefixManager.gtinCreator.length).toBe(length);
|
|
228
234
|
|
|
@@ -237,7 +243,6 @@ describe("Prefix manager", () => {
|
|
|
237
243
|
expect(gtin14.length).toBe(14);
|
|
238
244
|
}
|
|
239
245
|
|
|
240
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
241
246
|
function validateNonGTINStartsWithGS1CompanyPrefix(): void {
|
|
242
247
|
const gln = prefixManager.glnCreator.create(0);
|
|
243
248
|
|
|
@@ -383,14 +388,12 @@ describe("Sparse creation", () => {
|
|
|
383
388
|
prefixManager.resetTweakFactor();
|
|
384
389
|
});
|
|
385
390
|
|
|
386
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
387
391
|
function testIdentificationKeyCreatorCallback(callback?: () => void): void {
|
|
388
392
|
if (callback !== undefined) {
|
|
389
393
|
callback();
|
|
390
394
|
}
|
|
391
395
|
}
|
|
392
396
|
|
|
393
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
394
397
|
function testNumericIdentificationKeyCreator(creator: NumericIdentificationKeyCreator, preTestCallback?: () => void, postTestCallback?: () => void): void {
|
|
395
398
|
describe(creator.identificationKeyType === IdentificationKeyType.GTIN ? `${creator.identificationKeyType}-${creator.length}` : creator.identificationKeyType, () => {
|
|
396
399
|
testIdentificationKeyCreatorCallback(preTestCallback);
|
|
@@ -405,7 +408,6 @@ function testNumericIdentificationKeyCreator(creator: NumericIdentificationKeyCr
|
|
|
405
408
|
const referenceSubstringStart = prefixSubstringEnd;
|
|
406
409
|
const referenceSubstringEnd = referenceSubstringStart + referenceLength - prefixSubstringStart;
|
|
407
410
|
|
|
408
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
409
411
|
function validate(identificationKey: string, index: number, sparse: boolean): void {
|
|
410
412
|
expect(() => {
|
|
411
413
|
creator.validate(identificationKey);
|
|
@@ -505,11 +507,18 @@ function testNumericIdentificationKeyCreator(creator: NumericIdentificationKeyCr
|
|
|
505
507
|
}).toThrow("Invalid character 'O' at position 3");
|
|
506
508
|
});
|
|
507
509
|
|
|
510
|
+
test("Position offset", () => {
|
|
511
|
+
expect(() => {
|
|
512
|
+
creator.validate(creator.create(0), {
|
|
513
|
+
positionOffset: 4
|
|
514
|
+
});
|
|
515
|
+
}).not.toThrow(RangeError);
|
|
516
|
+
});
|
|
517
|
+
|
|
508
518
|
testIdentificationKeyCreatorCallback(postTestCallback);
|
|
509
519
|
});
|
|
510
520
|
}
|
|
511
521
|
|
|
512
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
513
522
|
function testGTINCreator(creator: GTINCreator): void {
|
|
514
523
|
testNumericIdentificationKeyCreator(creator, () => {
|
|
515
524
|
test("Length", () => {
|
|
@@ -538,7 +547,6 @@ function testGTINCreator(creator: GTINCreator): void {
|
|
|
538
547
|
const referenceSubstringStart = prefixSubstringEnd;
|
|
539
548
|
const referenceSubstringEnd = referenceSubstringStart + referenceLength;
|
|
540
549
|
|
|
541
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
542
550
|
function validate(gtin: string, index: number, sparse: boolean): void {
|
|
543
551
|
expect(() => {
|
|
544
552
|
GTINCreator.validateGTIN14(gtin);
|
|
@@ -746,7 +754,6 @@ function testGTINCreator(creator: GTINCreator): void {
|
|
|
746
754
|
});
|
|
747
755
|
}
|
|
748
756
|
|
|
749
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
750
757
|
function testGTINValidationAndNormalization(): void {
|
|
751
758
|
describe("GTIN validation and normalization", () => {
|
|
752
759
|
test("Validation", () => {
|
|
@@ -861,12 +868,10 @@ function testGTINValidationAndNormalization(): void {
|
|
|
861
868
|
});
|
|
862
869
|
}
|
|
863
870
|
|
|
864
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
865
871
|
function testNonGTINNumericIdentificationKeyCreator(creator: NonGTINNumericIdentificationKeyCreator, preTestCallback?: () => void, postTestCallback?: () => void): void {
|
|
866
872
|
testNumericIdentificationKeyCreator(creator, preTestCallback, postTestCallback);
|
|
867
873
|
}
|
|
868
874
|
|
|
869
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
870
875
|
function testSerializableNumericIdentificationKeyCreator(creator: SerializableNumericIdentificationKeyCreator): void {
|
|
871
876
|
testNonGTINNumericIdentificationKeyCreator(creator, undefined, () => {
|
|
872
877
|
test("Serialization", () => {
|
|
@@ -922,7 +927,6 @@ function testSerializableNumericIdentificationKeyCreator(creator: SerializableNu
|
|
|
922
927
|
|
|
923
928
|
const TEST_REFERENCE_LENGTH = 2;
|
|
924
929
|
|
|
925
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
926
930
|
function testNonNumericIdentificationKeyCreator<T extends NonNumericIdentificationKeyCreator>(creator: T): void {
|
|
927
931
|
describe(creator.identificationKeyType, () => {
|
|
928
932
|
const prefix = creator.prefix;
|
|
@@ -983,6 +987,14 @@ function testNonNumericIdentificationKeyCreator<T extends NonNumericIdentificati
|
|
|
983
987
|
expect(sequenceCount).toBe(referenceCount);
|
|
984
988
|
});
|
|
985
989
|
|
|
990
|
+
test("Position offset", () => {
|
|
991
|
+
expect(() => {
|
|
992
|
+
creator.validate(creator.create("ABC123"), {
|
|
993
|
+
positionOffset: 4
|
|
994
|
+
});
|
|
995
|
+
}).not.toThrow(RangeError);
|
|
996
|
+
});
|
|
997
|
+
|
|
986
998
|
test("Not all numeric", () => {
|
|
987
999
|
expect(() => {
|
|
988
1000
|
creator.validate(creator.create("01234"), {
|