@aidc-toolkit/gs1 0.9.7-beta → 0.9.8-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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aidc-toolkit/gs1",
3
- "version": "0.9.7-beta",
3
+ "version": "0.9.8-beta",
4
4
  "description": "GS1 AIDC Toolkit",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -25,16 +25,17 @@
25
25
  "test": "vitest run"
26
26
  },
27
27
  "devDependencies": {
28
- "@aidc-toolkit/dev": "^0.9.7-beta",
28
+ "@aidc-toolkit/dev": "^0.9.8-beta",
29
29
  "eslint": "^9.16.0",
30
+ "i18next": "^24.1.0",
30
31
  "ts-node": "^10.9.2",
31
32
  "tsup": "^8.3.5",
32
33
  "typescript": "^5.7.2",
33
34
  "vitest": "^2.1.8"
34
35
  },
35
36
  "dependencies": {
36
- "@aidc-toolkit/core": "^0.9.7-beta",
37
- "@aidc-toolkit/utility": "^0.9.7-beta",
37
+ "@aidc-toolkit/core": "^0.9.8-beta",
38
+ "@aidc-toolkit/utility": "^0.9.8-beta",
38
39
  "@rollup/rollup-linux-x64-gnu": "^4.28.1",
39
40
  "ts-mixer": "^6.0.4"
40
41
  }
package/src/check.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { NUMERIC_CREATOR } from "@aidc-toolkit/utility";
2
- import { AI82_CREATOR } from "./character_set.js";
3
- import i18next, { gs1NS } from "./locale/i18n.js";
1
+ import { NUMERIC_CREATOR, utilityNS } from "@aidc-toolkit/utility";
2
+ import { AI82_CREATOR } from "./character-set.js";
3
+ import { i18nextGS1 } from "./locale/i18n.js";
4
4
 
5
5
  /**
6
6
  * Results of multiplying digits by 3.
@@ -57,7 +57,11 @@ export function checkDigitSum(exchangeWeights: boolean, s: string): number {
57
57
  // Calculate sum of each character value multiplied by the weight at its position.
58
58
  return NUMERIC_CREATOR.characterIndexes(s).reduce<number>((accumulator, characterIndex, index) => {
59
59
  if (characterIndex === undefined) {
60
- throw new RangeError(`Invalid character '${s.charAt(index)}' at position ${index + 1}`);
60
+ throw new RangeError(i18nextGS1.t("CharacterSetValidator.invalidCharacterAtPosition", {
61
+ ns: utilityNS,
62
+ c: s.charAt(index),
63
+ position: index + 1
64
+ }));
61
65
  }
62
66
 
63
67
  weight3 = !weight3;
@@ -109,7 +113,10 @@ export function hasValidCheckDigit(s: string): boolean {
109
113
  */
110
114
  function priceWeightSum(weightsResults: ReadonlyArray<readonly number[]>, s: string): number {
111
115
  if (s.length !== weightsResults.length) {
112
- throw new RangeError(`String for price or weight sum must be exactly ${weightsResults.length} characters`);
116
+ throw new RangeError(i18nextGS1.t("Check.lengthOfStringForPriceOrWeightMustBeExactly", {
117
+ length: s.length,
118
+ exactLength: weightsResults.length
119
+ }));
113
120
  }
114
121
 
115
122
  // The value of each character is its index in the character set.
@@ -118,7 +125,12 @@ function priceWeightSum(weightsResults: ReadonlyArray<readonly number[]>, s: str
118
125
  // Calculate sum of each weight result for each digit at its position.
119
126
  return characterIndexes.reduce<number>((accumulator, characterIndex, index) => {
120
127
  if (characterIndex === undefined) {
121
- throw new RangeError(`Invalid character '${s.charAt(index)}' at position ${index + 1}`);
128
+ throw new RangeError(i18nextGS1.t("CharacterSetValidator.invalidCharacterAtPositionOfComponent", {
129
+ ns: utilityNS,
130
+ c: s.charAt(index),
131
+ position: index + 1,
132
+ component: i18nextGS1.t("Check.priceOrWeightComponent")
133
+ }));
122
134
  }
123
135
 
124
136
  // Add the weight result of the character index to the accumulator.
@@ -184,8 +196,7 @@ export function checkCharacterPair(s: string): string {
184
196
  const weightIndexStart = CHECK_CHARACTER_WEIGHTS.length - s.length;
185
197
 
186
198
  if (weightIndexStart < 0) {
187
- throw new RangeError(i18next.t("Check.lengthOfStringForCheckCharacterPairMustBeLessThanOrEqualTo", {
188
- ns: gs1NS,
199
+ throw new RangeError(i18nextGS1.t("Check.lengthOfStringForCheckCharacterPairMustBeLessThanOrEqualTo", {
189
200
  length: s.length,
190
201
  maximumLength: CHECK_CHARACTER_WEIGHTS.length
191
202
  }));
@@ -194,7 +205,11 @@ export function checkCharacterPair(s: string): string {
194
205
  // Calculate sum of each character value multiplied by the weight at its position, mod 1021.
195
206
  const checkCharacterPairSum = AI82_CREATOR.characterIndexes(s).reduce<number>((accumulator, characterIndex, index) => {
196
207
  if (characterIndex === undefined) {
197
- throw new RangeError(`Invalid character '${s.charAt(index)}' at position ${index + 1}`);
208
+ throw new RangeError(i18nextGS1.t("CharacterSetValidator.invalidCharacterAtPosition", {
209
+ ns: utilityNS,
210
+ c: s.charAt(index),
211
+ position: index + 1
212
+ }));
198
213
  }
199
214
 
200
215
  return accumulator + characterIndex * CHECK_CHARACTER_WEIGHTS[weightIndexStart + index];
package/src/idkey.ts CHANGED
@@ -2,16 +2,16 @@ import {
2
2
  CharacterSetCreator,
3
3
  type CharacterSetValidation,
4
4
  Exclusion,
5
- IteratorProxy,
6
5
  NUMERIC_CREATOR,
7
6
  RegExpValidator,
8
7
  type StringValidation,
9
8
  type StringValidator,
10
9
  type TransformerInput,
11
- type TransformerOutput
10
+ type TransformerOutput,
11
+ transformIterable
12
12
  } from "@aidc-toolkit/utility";
13
13
  import { Mixin } from "ts-mixer";
14
- import { AI39_CREATOR, AI82_CREATOR } from "./character_set.js";
14
+ import { AI39_CREATOR, AI82_CREATOR } from "./character-set.js";
15
15
  import {
16
16
  checkCharacterPair,
17
17
  checkDigit,
@@ -19,7 +19,7 @@ import {
19
19
  hasValidCheckCharacterPair,
20
20
  hasValidCheckDigit
21
21
  } from "./check.js";
22
- import i18next, { gs1NS } from "./locale/i18n.js";
22
+ import { i18nextGS1 } from "./locale/i18n.js";
23
23
 
24
24
  /**
25
25
  * Identification key type.
@@ -409,8 +409,7 @@ abstract class AbstractNumericIdentificationKeyValidator extends AbstractIdentif
409
409
 
410
410
  // Validate the length.
411
411
  if (identificationKey.length !== this.length) {
412
- throw new RangeError(i18next.t("IdentificationKey.identificationKeyTypeLength", {
413
- ns: gs1NS,
412
+ throw new RangeError(i18nextGS1.t("IdentificationKey.identificationKeyTypeLength", {
414
413
  identificationKeyType: this.identificationKeyType,
415
414
  length: this.length
416
415
  }));
@@ -418,9 +417,7 @@ abstract class AbstractNumericIdentificationKeyValidator extends AbstractIdentif
418
417
 
419
418
  // Validating the check digit will also validate the characters.
420
419
  if (!hasValidCheckDigit(this.padIdentificationKey(identificationKey, validation))) {
421
- throw new RangeError(i18next.t("IdentificationKey.invalidCheckDigit", {
422
- ns: gs1NS
423
- }));
420
+ throw new RangeError(i18nextGS1.t("IdentificationKey.invalidCheckDigit"));
424
421
  }
425
422
  }
426
423
  }
@@ -560,9 +557,7 @@ export class GTINValidator extends AbstractNumericIdentificationKeyValidator {
560
557
  }
561
558
 
562
559
  if (gtin12 === undefined) {
563
- throw new RangeError(i18next.t("IdentificationKey.invalidZeroSuppressedGTIN12", {
564
- ns: gs1NS
565
- }));
560
+ throw new RangeError(i18nextGS1.t("IdentificationKey.invalidZeroSuppressedGTIN12"));
566
561
  }
567
562
 
568
563
  // Make sure that resulting GTIN-12 is valid.
@@ -589,9 +584,7 @@ export class GTINValidator extends AbstractNumericIdentificationKeyValidator {
589
584
  switch (gtin.length) {
590
585
  case GTINType.GTIN13 as number:
591
586
  if (gtin.startsWith("0")) {
592
- throw new RangeError(i18next.t("IdentificationKey.invalidGTIN13AtRetail", {
593
- ns: gs1NS
594
- }));
587
+ throw new RangeError(i18nextGS1.t("IdentificationKey.invalidGTIN13AtRetail"));
595
588
  }
596
589
 
597
590
  // Validate prefix requiring exact match for prefix type.
@@ -627,23 +620,17 @@ export class GTINValidator extends AbstractNumericIdentificationKeyValidator {
627
620
  break;
628
621
 
629
622
  default:
630
- throw new RangeError(i18next.t("IdentificationKey.invalidGTINLength", {
631
- ns: gs1NS
632
- }));
623
+ throw new RangeError(i18nextGS1.t("IdentificationKey.invalidGTINLength"));
633
624
  }
634
625
 
635
626
  // Validating the check digit will also validate the characters.
636
627
  if (!hasValidCheckDigit(lengthValidatedGTIN)) {
637
- throw new RangeError(i18next.t("IdentificationKey.invalidCheckDigit", {
638
- ns: gs1NS
639
- }));
628
+ throw new RangeError(i18nextGS1.t("IdentificationKey.invalidCheckDigit"));
640
629
  }
641
630
 
642
631
  // Validate against level if required.
643
632
  if (gtinLevel !== GTINLevel.Any && gtinLevelRestriction !== GTINLevel.Any && gtinLevelRestriction !== gtinLevel) {
644
- throw new RangeError(i18next.t(gtinLevel === GTINLevel.RetailConsumer ? "IdentificationKey.invalidGTINAtRetail" : "IdentificationKey.invalidGTINAtOtherThanRetail", {
645
- ns: gs1NS
646
- }));
633
+ throw new RangeError(i18nextGS1.t(gtinLevel === GTINLevel.RetailConsumer ? "IdentificationKey.invalidGTINAtRetail" : "IdentificationKey.invalidGTINAtOtherThanRetail"));
647
634
  }
648
635
  }
649
636
 
@@ -655,9 +642,7 @@ export class GTINValidator extends AbstractNumericIdentificationKeyValidator {
655
642
  */
656
643
  static validateGTIN14(gtin14: string): void {
657
644
  if (gtin14.length as GTINType !== GTINType.GTIN14) {
658
- throw new RangeError(i18next.t("IdentificationKey.invalidGTIN14Length", {
659
- ns: gs1NS
660
- }));
645
+ throw new RangeError(i18nextGS1.t("IdentificationKey.invalidGTIN14Length"));
661
646
  }
662
647
 
663
648
  GTINCreator.validateAny(gtin14);
@@ -734,9 +719,7 @@ export class SerializableNumericIdentificationKeyValidator extends NonGTINNumeri
734
719
  this._serialComponentValidation = {
735
720
  minimumLength: 1,
736
721
  maximumLength: serialComponentLength,
737
- component: () => i18next.t("IdentificationKey.serialComponent", {
738
- ns: gs1NS
739
- })
722
+ component: () => i18nextGS1.t("IdentificationKey.serialComponent")
740
723
  };
741
724
 
742
725
  this._serialComponentCreator = SerializableNumericIdentificationKeyValidator.creatorFor(serialComponentCharacterSet);
@@ -805,9 +788,7 @@ export class NonNumericIdentificationKeyValidator extends AbstractIdentification
805
788
  * @inheritDoc
806
789
  */
807
790
  protected override createErrorMessage(_s: string): string {
808
- return i18next.t("IdentificationKey.referenceCantBeAllNumeric", {
809
- ns: gs1NS
810
- });
791
+ return i18nextGS1.t("IdentificationKey.referenceCantBeAllNumeric");
811
792
  }
812
793
  }(/\D/);
813
794
 
@@ -865,9 +846,7 @@ export class NonNumericIdentificationKeyValidator extends AbstractIdentification
865
846
  });
866
847
  // Validating the check character pair will also validate the characters.
867
848
  } else if (!hasValidCheckCharacterPair(this.padIdentificationKey(identificationKey, validation))) {
868
- throw new RangeError(i18next.t("IdentificationKey.invalidCheckCharacterPair", {
869
- ns: gs1NS
870
- }));
849
+ throw new RangeError(i18nextGS1.t("IdentificationKey.invalidCheckCharacterPair"));
871
850
  }
872
851
 
873
852
  // Check for all-numeric identification key (minus check character pair) if excluded.
@@ -1074,13 +1053,14 @@ export interface NumericIdentificationKeyCreator extends NumericIdentificationKe
1074
1053
  /**
1075
1054
  * Create all identification keys for the prefix from `0` to `capacity - 1`.
1076
1055
  *
1077
- * The implementation creates the strings as needed using an internal generator function, so the values are created
1078
- * only as needed.
1056
+ * The implementation creates the strings only as needed using an internal generator function. Although the result
1057
+ * is equivalent to calling `creator.create(new Sequencer(0, creator.capacity - 1))`, this method is significantly
1058
+ * faster.
1079
1059
  *
1080
1060
  * @returns
1081
- * Iterable iterator over created identification keys.
1061
+ * All identification keys for the prefix.
1082
1062
  */
1083
- createAll: () => IterableIterator<string>;
1063
+ createAll: () => Iterable<string>;
1084
1064
  }
1085
1065
 
1086
1066
  /**
@@ -1213,15 +1193,21 @@ abstract class AbstractNumericIdentificationKeyCreator extends AbstractIdentific
1213
1193
  /**
1214
1194
  * @inheritDoc
1215
1195
  */
1216
- createAll(): IterableIterator<string> {
1196
+ createAll(): Iterable<string> {
1217
1197
  const hasExtensionDigit = this.leaderType === LeaderType.ExtensionDigit;
1218
1198
  const prefix = this.prefix;
1199
+ const length = this.length;
1219
1200
  const referenceLength = this.referenceLength;
1220
1201
 
1221
1202
  // Start weight is for reference excluding extension digit, which has its weight calculated separately.
1222
1203
  const startWeight = 3 - 2 * ((referenceLength + 1 - Number(hasExtensionDigit)) % 2);
1223
1204
 
1224
- return AbstractNumericIdentificationKeyCreator.createAllPartial(prefix, referenceLength, hasExtensionDigit ? 3 - 2 * this.length % 2 : 0, startWeight, checkDigitSum(startWeight === 3, prefix));
1205
+ // Returning separate Iterable object makes iteration repeatable.
1206
+ return {
1207
+ [Symbol.iterator]() {
1208
+ return AbstractNumericIdentificationKeyCreator.createAllPartial(prefix, referenceLength, hasExtensionDigit ? 3 - 2 * length % 2 : 0, startWeight, checkDigitSum(startWeight === 3, prefix));
1209
+ }
1210
+ };
1225
1211
  }
1226
1212
  }
1227
1213
 
@@ -1235,9 +1221,7 @@ export class GTINCreator extends Mixin(GTINValidator, AbstractNumericIdentificat
1235
1221
  private static readonly REQUIRED_INDICATOR_DIGIT_VALIDATION: CharacterSetValidation = {
1236
1222
  minimumLength: 1,
1237
1223
  maximumLength: 1,
1238
- component: () => i18next.t("IdentificationKey.indicatorDigit", {
1239
- ns: gs1NS
1240
- })
1224
+ component: () => i18nextGS1.t("IdentificationKey.indicatorDigit")
1241
1225
  };
1242
1226
 
1243
1227
  /**
@@ -1246,9 +1230,7 @@ export class GTINCreator extends Mixin(GTINValidator, AbstractNumericIdentificat
1246
1230
  private static readonly OPTIONAL_INDICATOR_DIGIT_VALIDATION: CharacterSetValidation = {
1247
1231
  minimumLength: 0,
1248
1232
  maximumLength: 1,
1249
- component: () => i18next.t("IdentificationKey.indicatorDigit", {
1250
- ns: gs1NS
1251
- })
1233
+ component: () => i18nextGS1.t("IdentificationKey.indicatorDigit")
1252
1234
  };
1253
1235
 
1254
1236
  /**
@@ -1330,9 +1312,7 @@ export class GTINCreator extends Mixin(GTINValidator, AbstractNumericIdentificat
1330
1312
  }
1331
1313
 
1332
1314
  if (zeroSuppressedGTIN12 === undefined) {
1333
- throw new RangeError(i18next.t("IdentificationKey.invalidZeroSuppressibleGTIN12", {
1334
- ns: gs1NS
1335
- }));
1315
+ throw new RangeError(i18nextGS1.t("IdentificationKey.invalidZeroSuppressibleGTIN12"));
1336
1316
  }
1337
1317
 
1338
1318
  return zeroSuppressedGTIN12;
@@ -1400,9 +1380,7 @@ export class GTINCreator extends Mixin(GTINValidator, AbstractNumericIdentificat
1400
1380
  // GTIN is GTIN-8.
1401
1381
  normalizedGTIN = gtin.substring(5);
1402
1382
  } else {
1403
- throw new RangeError(i18next.t("IdentificationKey.invalidZeroSuppressedGTIN12AsGTIN13", {
1404
- ns: gs1NS
1405
- }));
1383
+ throw new RangeError(i18nextGS1.t("IdentificationKey.invalidZeroSuppressedGTIN12AsGTIN13"));
1406
1384
  }
1407
1385
  break;
1408
1386
 
@@ -1435,16 +1413,12 @@ export class GTINCreator extends Mixin(GTINValidator, AbstractNumericIdentificat
1435
1413
  // GTIN is GTIN-8.
1436
1414
  normalizedGTIN = gtin.substring(6);
1437
1415
  } else {
1438
- throw new RangeError(i18next.t("IdentificationKey.invalidZeroSuppressedGTIN12AsGTIN14", {
1439
- ns: gs1NS
1440
- }));
1416
+ throw new RangeError(i18nextGS1.t("IdentificationKey.invalidZeroSuppressedGTIN12AsGTIN14"));
1441
1417
  }
1442
1418
  break;
1443
1419
 
1444
1420
  default:
1445
- throw new RangeError(i18next.t("IdentificationKey.invalidGTINLength", {
1446
- ns: gs1NS
1447
- }));
1421
+ throw new RangeError(i18nextGS1.t("IdentificationKey.invalidGTINLength"));
1448
1422
  }
1449
1423
 
1450
1424
  // Validation applies to the normalized GTIN.
@@ -1524,7 +1498,7 @@ export class SerializableNumericIdentificationKeyCreator extends Mixin(Serializa
1524
1498
  */
1525
1499
  private concatenateValidated<T extends TransformerInput<string>>(baseIdentificationKey: string, serialComponentOrComponents: T): TransformerOutput<T, string> {
1526
1500
  // TODO Refactor type when https://github.com/microsoft/TypeScript/pull/56941 released.
1527
- let result: string | IterableIterator<string>;
1501
+ let result: string | Iterable<string>;
1528
1502
 
1529
1503
  const serialComponentCreator = this.serialComponentCreator;
1530
1504
  const serialComponentValidation = this.serialComponentValidation;
@@ -1547,7 +1521,7 @@ export class SerializableNumericIdentificationKeyCreator extends Mixin(Serializa
1547
1521
  if (typeof serialComponentOrComponents !== "object") {
1548
1522
  result = validateAndConcatenate(serialComponentOrComponents);
1549
1523
  } else {
1550
- result = IteratorProxy.from(serialComponentOrComponents).map(validateAndConcatenate);
1524
+ result = transformIterable(serialComponentOrComponents, validateAndConcatenate);
1551
1525
  }
1552
1526
 
1553
1527
  return result as TransformerOutput<T, string>;
@@ -1629,9 +1603,7 @@ export class NonNumericIdentificationKeyCreator extends Mixin(NonNumericIdentifi
1629
1603
  minimumLength: 1,
1630
1604
  // Maximum reference length has to account for prefix and check character pair.
1631
1605
  maximumLength: this.referenceLength,
1632
- component: () => i18next.t("IdentificationKey.reference", {
1633
- ns: gs1NS
1634
- })
1606
+ component: () => i18nextGS1.t("IdentificationKey.reference")
1635
1607
  };
1636
1608
  }
1637
1609
 
@@ -1653,7 +1625,7 @@ export class NonNumericIdentificationKeyCreator extends Mixin(NonNumericIdentifi
1653
1625
  */
1654
1626
  create<T extends TransformerInput<string>>(referenceOrReferences: T): TransformerOutput<T, string> {
1655
1627
  // TODO Refactor type when https://github.com/microsoft/TypeScript/pull/56941 released.
1656
- let result: string | IterableIterator<string>;
1628
+ let result: string | Iterable<string>;
1657
1629
 
1658
1630
  const referenceCreator = this.referenceCreator;
1659
1631
  const referenceValidation = this.referenceValidation;
@@ -1680,7 +1652,7 @@ export class NonNumericIdentificationKeyCreator extends Mixin(NonNumericIdentifi
1680
1652
  if (typeof referenceOrReferences !== "object") {
1681
1653
  result = validateAndCreate(referenceOrReferences);
1682
1654
  } else {
1683
- result = IteratorProxy.from(referenceOrReferences).map(validateAndCreate);
1655
+ result = transformIterable(referenceOrReferences, validateAndCreate);
1684
1656
  }
1685
1657
 
1686
1658
  return result as TransformerOutput<T, string>;
@@ -1770,9 +1742,7 @@ export class PrefixManager {
1770
1742
  private static readonly GS1_COMPANY_PREFIX_VALIDATION: PrefixValidation = {
1771
1743
  minimumLength: PrefixManager.GS1_COMPANY_PREFIX_MINIMUM_LENGTH,
1772
1744
  maximumLength: PrefixManager.GS1_COMPANY_PREFIX_MAXIMUM_LENGTH,
1773
- component: () => i18next.t("Prefix.gs1CompanyPrefix", {
1774
- ns: gs1NS
1775
- })
1745
+ component: () => i18nextGS1.t("Prefix.gs1CompanyPrefix")
1776
1746
  };
1777
1747
 
1778
1748
  /**
@@ -1781,9 +1751,7 @@ export class PrefixManager {
1781
1751
  private static readonly UPC_COMPANY_PREFIX_AS_GS1_COMPANY_PREFIX_VALIDATION: PrefixValidation = {
1782
1752
  minimumLength: PrefixManager.UPC_COMPANY_PREFIX_MINIMUM_LENGTH + 1,
1783
1753
  maximumLength: PrefixManager.UPC_COMPANY_PREFIX_MAXIMUM_LENGTH + 1,
1784
- component: () => i18next.t("Prefix.gs1CompanyPrefix", {
1785
- ns: gs1NS
1786
- })
1754
+ component: () => i18nextGS1.t("Prefix.gs1CompanyPrefix")
1787
1755
  };
1788
1756
 
1789
1757
  /**
@@ -1792,9 +1760,7 @@ export class PrefixManager {
1792
1760
  private static readonly GS1_8_PREFIX_AS_GS1_COMPANY_PREFIX_VALIDATION: PrefixValidation = {
1793
1761
  minimumLength: PrefixManager.GS1_8_PREFIX_MINIMUM_LENGTH + 5,
1794
1762
  maximumLength: PrefixManager.GS1_8_PREFIX_MAXIMUM_LENGTH + 5,
1795
- component: () => i18next.t("Prefix.gs1CompanyPrefix", {
1796
- ns: gs1NS
1797
- })
1763
+ component: () => i18nextGS1.t("Prefix.gs1CompanyPrefix")
1798
1764
  };
1799
1765
 
1800
1766
  /**
@@ -1803,9 +1769,7 @@ export class PrefixManager {
1803
1769
  private static readonly UPC_COMPANY_PREFIX_VALIDATION: PrefixValidation = {
1804
1770
  minimumLength: PrefixManager.UPC_COMPANY_PREFIX_MINIMUM_LENGTH,
1805
1771
  maximumLength: PrefixManager.UPC_COMPANY_PREFIX_MAXIMUM_LENGTH,
1806
- component: () => i18next.t("Prefix.upcCompanyPrefix", {
1807
- ns: gs1NS
1808
- })
1772
+ component: () => i18nextGS1.t("Prefix.upcCompanyPrefix")
1809
1773
  };
1810
1774
 
1811
1775
  /**
@@ -1814,9 +1778,7 @@ export class PrefixManager {
1814
1778
  private static readonly GS1_8_PREFIX_VALIDATION: PrefixValidation = {
1815
1779
  minimumLength: PrefixManager.GS1_8_PREFIX_MINIMUM_LENGTH,
1816
1780
  maximumLength: PrefixManager.GS1_8_PREFIX_MAXIMUM_LENGTH,
1817
- component: () => i18next.t("Prefix.gs18Prefix", {
1818
- ns: gs1NS
1819
- })
1781
+ component: () => i18nextGS1.t("Prefix.gs18Prefix")
1820
1782
  };
1821
1783
 
1822
1784
  /**
@@ -2054,32 +2016,24 @@ export class PrefixManager {
2054
2016
  baseValidation = PrefixManager.GS1_COMPANY_PREFIX_VALIDATION;
2055
2017
  } else if (!prefix.startsWith("00000")) {
2056
2018
  if (!allowUPCCompanyPrefix) {
2057
- throw new RangeError(i18next.t("Prefix.gs1CompanyPrefixCantStartWith0", {
2058
- ns: gs1NS
2059
- }));
2019
+ throw new RangeError(i18nextGS1.t("Prefix.gs1CompanyPrefixCantStartWith0"));
2060
2020
  }
2061
2021
 
2062
2022
  baseValidation = PrefixManager.UPC_COMPANY_PREFIX_AS_GS1_COMPANY_PREFIX_VALIDATION;
2063
2023
  } else if (!prefix.startsWith("000000")) {
2064
2024
  if (!allowGS18Prefix) {
2065
- throw new RangeError(i18next.t("Prefix.gs1CompanyPrefixCantStartWith00000", {
2066
- ns: gs1NS
2067
- }));
2025
+ throw new RangeError(i18nextGS1.t("Prefix.gs1CompanyPrefixCantStartWith00000"));
2068
2026
  }
2069
2027
 
2070
2028
  baseValidation = PrefixManager.GS1_8_PREFIX_AS_GS1_COMPANY_PREFIX_VALIDATION;
2071
2029
  } else {
2072
- throw new RangeError(i18next.t("Prefix.gs1CompanyPrefixCantStartWith000000", {
2073
- ns: gs1NS
2074
- }));
2030
+ throw new RangeError(i18nextGS1.t("Prefix.gs1CompanyPrefixCantStartWith000000"));
2075
2031
  }
2076
2032
  break;
2077
2033
 
2078
2034
  case PrefixType.UPCCompanyPrefix:
2079
2035
  if (prefix.startsWith("0000")) {
2080
- throw new RangeError(i18next.t("Prefix.upcCompanyPrefixCantStartWith0000", {
2081
- ns: gs1NS
2082
- }));
2036
+ throw new RangeError(i18nextGS1.t("Prefix.upcCompanyPrefixCantStartWith0000"));
2083
2037
  }
2084
2038
 
2085
2039
  baseValidation = PrefixManager.UPC_COMPANY_PREFIX_VALIDATION;
@@ -2087,9 +2041,7 @@ export class PrefixManager {
2087
2041
 
2088
2042
  case PrefixType.GS18Prefix:
2089
2043
  if (prefix.startsWith("0")) {
2090
- throw new RangeError(i18next.t("Prefix.gs18PrefixCantStartWith0", {
2091
- ns: gs1NS
2092
- }));
2044
+ throw new RangeError(i18nextGS1.t("Prefix.gs18PrefixCantStartWith0"));
2093
2045
  }
2094
2046
 
2095
2047
  baseValidation = PrefixManager.GS1_8_PREFIX_VALIDATION;
@@ -2127,8 +2079,7 @@ export class PrefixManager {
2127
2079
 
2128
2080
  if (creator === undefined) {
2129
2081
  if (this.prefixType === PrefixType.GS18Prefix && identificationKeyType !== IdentificationKeyType.GTIN) {
2130
- throw new RangeError(i18next.t("Prefix.identificationKeyTypeNotSupportedByGS18Prefix", {
2131
- ns: gs1NS,
2082
+ throw new RangeError(i18nextGS1.t("Prefix.identificationKeyTypeNotSupportedByGS18Prefix", {
2132
2083
  identificationKeyType
2133
2084
  }));
2134
2085
  }
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { gs1NS } from "./locale/i18n.js";
2
- export * from "./character_set.js";
1
+ export * from "./locale/i18n.js";
2
+ export * from "./character-set.js";
3
3
  export * from "./check.js";
4
4
  export * from "./idkey.js";
@@ -1,5 +1,7 @@
1
1
  export const localeStrings = {
2
2
  Check: {
3
+ lengthOfStringForPriceOrWeightMustBeExactly: "Length {{length}} of string for price or weight sum must be exactly {{exactLength}}",
4
+ priceOrWeightComponent: "price or weight",
3
5
  lengthOfStringForCheckCharacterPairMustBeLessThanOrEqualTo: "Length {{length}} of string for check character pair must be less than or equal to {{maximumLength}}"
4
6
  },
5
7
  IdentificationKey: {
@@ -1,5 +1,7 @@
1
1
  export const localeStrings = {
2
2
  Check: {
3
+ lengthOfStringForPriceOrWeightMustBeExactly: "La longueur {{longueur}} de la chaîne pour le prix ou la somme du poids doit être exactement {{exactLength}}",
4
+ priceOrWeightComponent: "prix ou poids",
3
5
  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
6
  },
5
7
  IdentificationKey: {
@@ -1,12 +1,45 @@
1
- import { i18nAddResourceBundle, i18nAssertValidResources, i18next } from "@aidc-toolkit/core";
2
- import { localeStrings as enLocaleStrings } from "./en/locale_strings.js";
3
- import { localeStrings as frLocaleStrings } from "./fr/locale_strings.js";
1
+ import { i18nAssertValidResources, i18nCoreInit, type I18NEnvironment } from "@aidc-toolkit/core";
2
+ import { i18nUtilityInit, utilityResources } from "@aidc-toolkit/utility";
3
+ import i18next from "i18next";
4
+ import { localeStrings as enLocaleStrings } from "./en/locale-strings.js";
5
+ import { localeStrings as frLocaleStrings } from "./fr/locale-strings.js";
4
6
 
5
7
  export const gs1NS = "aidct_gs1";
6
8
 
9
+ /**
10
+ * Locale strings type is extracted from the English locale strings object.
11
+ */
12
+ export type GS1LocaleStrings = typeof enLocaleStrings;
13
+
7
14
  i18nAssertValidResources(enLocaleStrings, "fr", frLocaleStrings);
8
15
 
9
- i18nAddResourceBundle("en", gs1NS, enLocaleStrings);
10
- i18nAddResourceBundle("fr", gs1NS, frLocaleStrings);
16
+ /**
17
+ * GS1 resources.
18
+ */
19
+ export const gs1Resources = {
20
+ en: {
21
+ aidct_gs1: enLocaleStrings
22
+ },
23
+ fr: {
24
+ aidct_gs1: frLocaleStrings
25
+ }
26
+ };
27
+
28
+ export const i18nextGS1 = i18next.createInstance();
11
29
 
12
- export default i18next;
30
+ /**
31
+ * Initialize internationalization.
32
+ *
33
+ * @param environment
34
+ * Environment in which the application is running.
35
+ *
36
+ * @param debug
37
+ * Debug setting.
38
+ *
39
+ * @returns
40
+ * Void promise.
41
+ */
42
+ export async function i18nGS1Init(environment: I18NEnvironment, debug = false): Promise<void> {
43
+ await i18nUtilityInit(environment, debug);
44
+ await i18nCoreInit(i18nextGS1, environment, debug, gs1NS, utilityResources, gs1Resources);
45
+ }
@@ -1,4 +1,5 @@
1
- import type { localeStrings } from "./en/locale_strings.js";
1
+ import type { UtilityLocaleStrings } from "@aidc-toolkit/utility";
2
+ import type { GS1LocaleStrings } from "./i18n.js";
2
3
 
3
4
  /**
4
5
  * Internationalization module.
@@ -8,9 +9,10 @@ declare module "i18next" {
8
9
  * Custom type options for this package.
9
10
  */
10
11
  interface CustomTypeOptions {
12
+ defaultNS: "aidct_gs1";
11
13
  resources: {
12
- // Extract the type from the English locale strings object.
13
- aidct_gs1: typeof localeStrings;
14
+ aidct_utility: UtilityLocaleStrings;
15
+ aidct_gs1: GS1LocaleStrings;
14
16
  };
15
17
  }
16
18
  }
@@ -1,4 +1,4 @@
1
- import { I18NEnvironment, i18nInit } from "@aidc-toolkit/core";
1
+ import { I18NEnvironment } from "@aidc-toolkit/core";
2
2
  import { NUMERIC_CREATOR } from "@aidc-toolkit/utility";
3
3
  import { describe, expect, test } from "vitest";
4
4
  import {
@@ -8,10 +8,11 @@ import {
8
8
  fiveDigitPriceWeightCheckDigit,
9
9
  fourDigitPriceWeightCheckDigit,
10
10
  hasValidCheckCharacterPair,
11
- hasValidCheckDigit
11
+ hasValidCheckDigit,
12
+ i18nGS1Init
12
13
  } from "../src/index.js";
13
14
 
14
- await i18nInit(I18NEnvironment.CLI);
15
+ await i18nGS1Init(I18NEnvironment.CLI, true);
15
16
 
16
17
  describe("Check digit", () => {
17
18
  const testNumericString = "1234567890";
@@ -93,8 +94,8 @@ describe("Price/weight check digit", () => {
93
94
  testFourDigitPriceWeightCheckDigit("9012");
94
95
 
95
96
  expect(() => fourDigitPriceWeightCheckDigit("l234")).toThrow("Invalid character 'l' at position 1");
96
- expect(() => fourDigitPriceWeightCheckDigit("123")).toThrow("String for price or weight sum must be exactly 4 characters");
97
- expect(() => fourDigitPriceWeightCheckDigit("12345")).toThrow("String for price or weight sum must be exactly 4 characters");
97
+ expect(() => fourDigitPriceWeightCheckDigit("123")).toThrow("Length 3 of string for price or weight sum must be exactly 4");
98
+ expect(() => fourDigitPriceWeightCheckDigit("12345")).toThrow("Length 5 of string for price or weight sum must be exactly 4");
98
99
  });
99
100
 
100
101
  test("Five-digit", () => {
@@ -109,9 +110,9 @@ describe("Price/weight check digit", () => {
109
110
  testFiveDigitPriceWeightCheckDigit("89012");
110
111
  testFiveDigitPriceWeightCheckDigit("90123");
111
112
 
112
- expect(() => fiveDigitPriceWeightCheckDigit("l2345")).toThrow("Invalid character 'l' at position 1");
113
- expect(() => fiveDigitPriceWeightCheckDigit("1234")).toThrow("String for price or weight sum must be exactly 5 characters");
114
- expect(() => fiveDigitPriceWeightCheckDigit("123456")).toThrow("String for price or weight sum must be exactly 5 characters");
113
+ expect(() => fiveDigitPriceWeightCheckDigit("l2345")).toThrow("Invalid character 'l' at position 1 of price or weight");
114
+ expect(() => fiveDigitPriceWeightCheckDigit("1234")).toThrow("Length 4 of string for price or weight sum must be exactly 5");
115
+ expect(() => fiveDigitPriceWeightCheckDigit("123456")).toThrow("Length 6 of string for price or weight sum must be exactly 5");
115
116
  });
116
117
  });
117
118