@aidc-toolkit/gs1 0.9.7-beta → 0.9.9-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/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 Sequence(0, creator.capacity))`, 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,9 +1521,10 @@ 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
 
1527
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Type determination is handled above.
1553
1528
  return result as TransformerOutput<T, string>;
1554
1529
  }
1555
1530
 
@@ -1629,9 +1604,7 @@ export class NonNumericIdentificationKeyCreator extends Mixin(NonNumericIdentifi
1629
1604
  minimumLength: 1,
1630
1605
  // Maximum reference length has to account for prefix and check character pair.
1631
1606
  maximumLength: this.referenceLength,
1632
- component: () => i18next.t("IdentificationKey.reference", {
1633
- ns: gs1NS
1634
- })
1607
+ component: () => i18nextGS1.t("IdentificationKey.reference")
1635
1608
  };
1636
1609
  }
1637
1610
 
@@ -1653,7 +1626,7 @@ export class NonNumericIdentificationKeyCreator extends Mixin(NonNumericIdentifi
1653
1626
  */
1654
1627
  create<T extends TransformerInput<string>>(referenceOrReferences: T): TransformerOutput<T, string> {
1655
1628
  // TODO Refactor type when https://github.com/microsoft/TypeScript/pull/56941 released.
1656
- let result: string | IterableIterator<string>;
1629
+ let result: string | Iterable<string>;
1657
1630
 
1658
1631
  const referenceCreator = this.referenceCreator;
1659
1632
  const referenceValidation = this.referenceValidation;
@@ -1680,9 +1653,10 @@ export class NonNumericIdentificationKeyCreator extends Mixin(NonNumericIdentifi
1680
1653
  if (typeof referenceOrReferences !== "object") {
1681
1654
  result = validateAndCreate(referenceOrReferences);
1682
1655
  } else {
1683
- result = IteratorProxy.from(referenceOrReferences).map(validateAndCreate);
1656
+ result = transformIterable(referenceOrReferences, validateAndCreate);
1684
1657
  }
1685
1658
 
1659
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Type determination is handled above.
1686
1660
  return result as TransformerOutput<T, string>;
1687
1661
  }
1688
1662
  }
@@ -1770,9 +1744,7 @@ export class PrefixManager {
1770
1744
  private static readonly GS1_COMPANY_PREFIX_VALIDATION: PrefixValidation = {
1771
1745
  minimumLength: PrefixManager.GS1_COMPANY_PREFIX_MINIMUM_LENGTH,
1772
1746
  maximumLength: PrefixManager.GS1_COMPANY_PREFIX_MAXIMUM_LENGTH,
1773
- component: () => i18next.t("Prefix.gs1CompanyPrefix", {
1774
- ns: gs1NS
1775
- })
1747
+ component: () => i18nextGS1.t("Prefix.gs1CompanyPrefix")
1776
1748
  };
1777
1749
 
1778
1750
  /**
@@ -1781,9 +1753,7 @@ export class PrefixManager {
1781
1753
  private static readonly UPC_COMPANY_PREFIX_AS_GS1_COMPANY_PREFIX_VALIDATION: PrefixValidation = {
1782
1754
  minimumLength: PrefixManager.UPC_COMPANY_PREFIX_MINIMUM_LENGTH + 1,
1783
1755
  maximumLength: PrefixManager.UPC_COMPANY_PREFIX_MAXIMUM_LENGTH + 1,
1784
- component: () => i18next.t("Prefix.gs1CompanyPrefix", {
1785
- ns: gs1NS
1786
- })
1756
+ component: () => i18nextGS1.t("Prefix.gs1CompanyPrefix")
1787
1757
  };
1788
1758
 
1789
1759
  /**
@@ -1792,9 +1762,7 @@ export class PrefixManager {
1792
1762
  private static readonly GS1_8_PREFIX_AS_GS1_COMPANY_PREFIX_VALIDATION: PrefixValidation = {
1793
1763
  minimumLength: PrefixManager.GS1_8_PREFIX_MINIMUM_LENGTH + 5,
1794
1764
  maximumLength: PrefixManager.GS1_8_PREFIX_MAXIMUM_LENGTH + 5,
1795
- component: () => i18next.t("Prefix.gs1CompanyPrefix", {
1796
- ns: gs1NS
1797
- })
1765
+ component: () => i18nextGS1.t("Prefix.gs1CompanyPrefix")
1798
1766
  };
1799
1767
 
1800
1768
  /**
@@ -1803,9 +1771,7 @@ export class PrefixManager {
1803
1771
  private static readonly UPC_COMPANY_PREFIX_VALIDATION: PrefixValidation = {
1804
1772
  minimumLength: PrefixManager.UPC_COMPANY_PREFIX_MINIMUM_LENGTH,
1805
1773
  maximumLength: PrefixManager.UPC_COMPANY_PREFIX_MAXIMUM_LENGTH,
1806
- component: () => i18next.t("Prefix.upcCompanyPrefix", {
1807
- ns: gs1NS
1808
- })
1774
+ component: () => i18nextGS1.t("Prefix.upcCompanyPrefix")
1809
1775
  };
1810
1776
 
1811
1777
  /**
@@ -1814,9 +1780,7 @@ export class PrefixManager {
1814
1780
  private static readonly GS1_8_PREFIX_VALIDATION: PrefixValidation = {
1815
1781
  minimumLength: PrefixManager.GS1_8_PREFIX_MINIMUM_LENGTH,
1816
1782
  maximumLength: PrefixManager.GS1_8_PREFIX_MAXIMUM_LENGTH,
1817
- component: () => i18next.t("Prefix.gs18Prefix", {
1818
- ns: gs1NS
1819
- })
1783
+ component: () => i18nextGS1.t("Prefix.gs18Prefix")
1820
1784
  };
1821
1785
 
1822
1786
  /**
@@ -2054,32 +2018,24 @@ export class PrefixManager {
2054
2018
  baseValidation = PrefixManager.GS1_COMPANY_PREFIX_VALIDATION;
2055
2019
  } else if (!prefix.startsWith("00000")) {
2056
2020
  if (!allowUPCCompanyPrefix) {
2057
- throw new RangeError(i18next.t("Prefix.gs1CompanyPrefixCantStartWith0", {
2058
- ns: gs1NS
2059
- }));
2021
+ throw new RangeError(i18nextGS1.t("Prefix.gs1CompanyPrefixCantStartWith0"));
2060
2022
  }
2061
2023
 
2062
2024
  baseValidation = PrefixManager.UPC_COMPANY_PREFIX_AS_GS1_COMPANY_PREFIX_VALIDATION;
2063
2025
  } else if (!prefix.startsWith("000000")) {
2064
2026
  if (!allowGS18Prefix) {
2065
- throw new RangeError(i18next.t("Prefix.gs1CompanyPrefixCantStartWith00000", {
2066
- ns: gs1NS
2067
- }));
2027
+ throw new RangeError(i18nextGS1.t("Prefix.gs1CompanyPrefixCantStartWith00000"));
2068
2028
  }
2069
2029
 
2070
2030
  baseValidation = PrefixManager.GS1_8_PREFIX_AS_GS1_COMPANY_PREFIX_VALIDATION;
2071
2031
  } else {
2072
- throw new RangeError(i18next.t("Prefix.gs1CompanyPrefixCantStartWith000000", {
2073
- ns: gs1NS
2074
- }));
2032
+ throw new RangeError(i18nextGS1.t("Prefix.gs1CompanyPrefixCantStartWith000000"));
2075
2033
  }
2076
2034
  break;
2077
2035
 
2078
2036
  case PrefixType.UPCCompanyPrefix:
2079
2037
  if (prefix.startsWith("0000")) {
2080
- throw new RangeError(i18next.t("Prefix.upcCompanyPrefixCantStartWith0000", {
2081
- ns: gs1NS
2082
- }));
2038
+ throw new RangeError(i18nextGS1.t("Prefix.upcCompanyPrefixCantStartWith0000"));
2083
2039
  }
2084
2040
 
2085
2041
  baseValidation = PrefixManager.UPC_COMPANY_PREFIX_VALIDATION;
@@ -2087,9 +2043,7 @@ export class PrefixManager {
2087
2043
 
2088
2044
  case PrefixType.GS18Prefix:
2089
2045
  if (prefix.startsWith("0")) {
2090
- throw new RangeError(i18next.t("Prefix.gs18PrefixCantStartWith0", {
2091
- ns: gs1NS
2092
- }));
2046
+ throw new RangeError(i18nextGS1.t("Prefix.gs18PrefixCantStartWith0"));
2093
2047
  }
2094
2048
 
2095
2049
  baseValidation = PrefixManager.GS1_8_PREFIX_VALIDATION;
@@ -2123,12 +2077,12 @@ export class PrefixManager {
2123
2077
  * Identification key creator.
2124
2078
  */
2125
2079
  private getIdentificationKeyCreator<T extends IdentificationKeyCreator>(identificationKeyType: IdentificationKeyType, constructorCallback: () => T): T {
2080
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Type is paired with constructor callback.
2126
2081
  let creator = this._identificationKeyCreatorsMap.get(identificationKeyType) as (T | undefined);
2127
2082
 
2128
2083
  if (creator === undefined) {
2129
2084
  if (this.prefixType === PrefixType.GS18Prefix && identificationKeyType !== IdentificationKeyType.GTIN) {
2130
- throw new RangeError(i18next.t("Prefix.identificationKeyTypeNotSupportedByGS18Prefix", {
2131
- ns: gs1NS,
2085
+ throw new RangeError(i18nextGS1.t("Prefix.identificationKeyTypeNotSupportedByGS18Prefix", {
2132
2086
  identificationKeyType
2133
2087
  }));
2134
2088
  }
package/src/index.ts CHANGED
@@ -1,4 +1,20 @@
1
- export { gs1NS } from "./locale/i18n.js";
2
- export * from "./character_set.js";
1
+ /*!
2
+ * Copyright © 2024-2025 Dolphin Data Development Ltd. and AIDC Toolkit
3
+ * contributors
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * https://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ export * from "./locale/i18n.js";
18
+ export * from "./character-set.js";
3
19
  export * from "./check.js";
4
20
  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,46 @@
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, { type i18n } 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
+ // Explicit type is necessary to work around bug in type discovery with linked packages.
29
+ export const i18nextGS1: i18n = i18next.createInstance();
11
30
 
12
- export default i18next;
31
+ /**
32
+ * Initialize internationalization.
33
+ *
34
+ * @param environment
35
+ * Environment in which the application is running.
36
+ *
37
+ * @param debug
38
+ * Debug setting.
39
+ *
40
+ * @returns
41
+ * Void promise.
42
+ */
43
+ export async function i18nGS1Init(environment: I18NEnvironment, debug = false): Promise<void> {
44
+ await i18nUtilityInit(environment, debug);
45
+ await i18nCoreInit(i18nextGS1, environment, debug, gs1NS, utilityResources, gs1Resources);
46
+ }
@@ -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