@aidc-toolkit/gs1 0.9.20-beta → 0.9.21-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.
Files changed (131) hide show
  1. package/dist/character-set.d.ts +4 -4
  2. package/dist/character-set.d.ts.map +1 -1
  3. package/dist/character-set.js +7 -7
  4. package/dist/character-set.js.map +1 -1
  5. package/dist/gtin-creator.d.ts +68 -0
  6. package/dist/gtin-creator.d.ts.map +1 -0
  7. package/dist/gtin-creator.js +158 -0
  8. package/dist/gtin-creator.js.map +1 -0
  9. package/dist/gtin-validator.d.ts +202 -0
  10. package/dist/gtin-validator.d.ts.map +1 -0
  11. package/dist/gtin-validator.js +470 -0
  12. package/dist/gtin-validator.js.map +1 -0
  13. package/dist/identifier-creator.d.ts +72 -0
  14. package/dist/identifier-creator.d.ts.map +1 -0
  15. package/dist/identifier-creator.js +50 -0
  16. package/dist/identifier-creator.js.map +1 -0
  17. package/dist/identifier-type.d.ts +58 -0
  18. package/dist/identifier-type.d.ts.map +1 -0
  19. package/dist/identifier-type.js +54 -0
  20. package/dist/identifier-type.js.map +1 -0
  21. package/dist/identifier-validator.d.ts +174 -0
  22. package/dist/identifier-validator.d.ts.map +1 -0
  23. package/dist/identifier-validator.js +145 -0
  24. package/dist/identifier-validator.js.map +1 -0
  25. package/dist/index.d.ts +16 -1
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +16 -1
  28. package/dist/index.js.map +1 -1
  29. package/dist/locale/en/locale-strings.d.ts +3 -3
  30. package/dist/locale/en/locale-strings.js +3 -3
  31. package/dist/locale/en/locale-strings.js.map +1 -1
  32. package/dist/locale/fr/locale-strings.d.ts +3 -3
  33. package/dist/locale/fr/locale-strings.js +3 -3
  34. package/dist/locale/fr/locale-strings.js.map +1 -1
  35. package/dist/non-gtin-numeric-identifier-creator.d.ts +30 -0
  36. package/dist/non-gtin-numeric-identifier-creator.d.ts.map +1 -0
  37. package/dist/non-gtin-numeric-identifier-creator.js +30 -0
  38. package/dist/non-gtin-numeric-identifier-creator.js.map +1 -0
  39. package/dist/non-gtin-numeric-identifier-validator.d.ts +41 -0
  40. package/dist/non-gtin-numeric-identifier-validator.d.ts.map +1 -0
  41. package/dist/non-gtin-numeric-identifier-validator.js +40 -0
  42. package/dist/non-gtin-numeric-identifier-validator.js.map +1 -0
  43. package/dist/non-numeric-identifier-creator.d.ts +55 -0
  44. package/dist/non-numeric-identifier-creator.d.ts.map +1 -0
  45. package/dist/non-numeric-identifier-creator.js +93 -0
  46. package/dist/non-numeric-identifier-creator.js.map +1 -0
  47. package/dist/non-numeric-identifier-validator.d.ts +78 -0
  48. package/dist/non-numeric-identifier-validator.d.ts.map +1 -0
  49. package/dist/non-numeric-identifier-validator.js +95 -0
  50. package/dist/non-numeric-identifier-validator.js.map +1 -0
  51. package/dist/numeric-identifier-creator.d.ts +121 -0
  52. package/dist/numeric-identifier-creator.d.ts.map +1 -0
  53. package/dist/numeric-identifier-creator.js +135 -0
  54. package/dist/numeric-identifier-creator.js.map +1 -0
  55. package/dist/numeric-identifier-validator.d.ts +76 -0
  56. package/dist/numeric-identifier-validator.d.ts.map +1 -0
  57. package/dist/numeric-identifier-validator.js +84 -0
  58. package/dist/numeric-identifier-validator.js.map +1 -0
  59. package/dist/prefix-manager.d.ts +224 -0
  60. package/dist/prefix-manager.d.ts.map +1 -0
  61. package/dist/prefix-manager.js +369 -0
  62. package/dist/prefix-manager.js.map +1 -0
  63. package/dist/prefix-provider.d.ts +27 -0
  64. package/dist/prefix-provider.d.ts.map +1 -0
  65. package/dist/prefix-provider.js +2 -0
  66. package/dist/prefix-provider.js.map +1 -0
  67. package/dist/prefix-type.d.ts +22 -0
  68. package/dist/prefix-type.d.ts.map +1 -0
  69. package/dist/prefix-type.js +18 -0
  70. package/dist/prefix-type.js.map +1 -0
  71. package/dist/prefix-validator.d.ts +58 -0
  72. package/dist/prefix-validator.d.ts.map +1 -0
  73. package/dist/prefix-validator.js +154 -0
  74. package/dist/prefix-validator.js.map +1 -0
  75. package/dist/serializable-numeric-identifier-creator.d.ts +86 -0
  76. package/dist/serializable-numeric-identifier-creator.d.ts.map +1 -0
  77. package/dist/serializable-numeric-identifier-creator.js +116 -0
  78. package/dist/serializable-numeric-identifier-creator.js.map +1 -0
  79. package/dist/serializable-numeric-identifier-validator.d.ts +79 -0
  80. package/dist/serializable-numeric-identifier-validator.d.ts.map +1 -0
  81. package/dist/serializable-numeric-identifier-validator.js +99 -0
  82. package/dist/serializable-numeric-identifier-validator.js.map +1 -0
  83. package/gs1.iml +4 -1
  84. package/package.json +2 -3
  85. package/src/character-set.ts +7 -7
  86. package/src/gtin-creator.ts +195 -0
  87. package/src/gtin-validator.ts +564 -0
  88. package/src/identifier-creator.ts +97 -0
  89. package/src/identifier-type.ts +69 -0
  90. package/src/identifier-validator.ts +235 -0
  91. package/src/index.ts +16 -1
  92. package/src/locale/en/locale-strings.ts +3 -3
  93. package/src/locale/fr/locale-strings.ts +3 -3
  94. package/src/non-gtin-numeric-identifier-creator.ts +33 -0
  95. package/src/non-gtin-numeric-identifier-validator.ts +54 -0
  96. package/src/non-numeric-identifier-creator.ts +111 -0
  97. package/src/non-numeric-identifier-validator.ts +128 -0
  98. package/src/numeric-identifier-creator.ts +200 -0
  99. package/src/numeric-identifier-validator.ts +128 -0
  100. package/src/prefix-manager.ts +446 -0
  101. package/src/prefix-provider.ts +31 -0
  102. package/src/prefix-type.ts +24 -0
  103. package/src/prefix-validator.ts +191 -0
  104. package/src/serializable-numeric-identifier-creator.ts +128 -0
  105. package/src/serializable-numeric-identifier-validator.ts +124 -0
  106. package/test/check.test.ts +0 -4
  107. package/test/creator.test.ts +30 -0
  108. package/test/gtin-creator.ts +239 -0
  109. package/test/gtin-validator.test.ts +149 -0
  110. package/test/identifier-creator.ts +84 -0
  111. package/test/identifier-validator.ts +8 -0
  112. package/test/non-gtin-numeric-identifier-creator.ts +98 -0
  113. package/test/non-gtin-numeric-identifier-validator.ts +6 -0
  114. package/test/non-numeric-identifier-validator.ts +24 -0
  115. package/test/numeric-identifier-creator.ts +132 -0
  116. package/test/numeric-identifier-validator.ts +23 -0
  117. package/test/prefix-manager.test.ts +112 -0
  118. package/test/serializable-numeric-identifier-creator.ts +56 -0
  119. package/test/serializable-numeric-identifier-validator.ts +24 -0
  120. package/test/setup.ts +4 -0
  121. package/test/sparse.test.ts +56 -0
  122. package/test/utility.ts +22 -0
  123. package/test/validator.test.ts +52 -0
  124. package/test/variable-measure-rcn.test.ts +201 -0
  125. package/vitest.config.ts +7 -0
  126. package/dist/idkey.d.ts +0 -1346
  127. package/dist/idkey.d.ts.map +0 -1
  128. package/dist/idkey.js +0 -2024
  129. package/dist/idkey.js.map +0 -1
  130. package/src/idkey.ts +0 -2532
  131. package/test/idkey.test.ts +0 -1247
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Identifier types.
3
+ */
4
+ export const IdentifierTypes = {
5
+ /**
6
+ * Global Trade Item Number.
7
+ */
8
+ GTIN: "GTIN",
9
+
10
+ /**
11
+ * Global Location Number.
12
+ */
13
+ GLN: "GLN",
14
+
15
+ /**
16
+ * Serial Shipping Container Code.
17
+ */
18
+ SSCC: "SSCC",
19
+
20
+ /**
21
+ * Global Returnable Asset Identifier.
22
+ */
23
+ GRAI: "GRAI",
24
+
25
+ /**
26
+ * Global Individual Asset Identifier.
27
+ */
28
+ GIAI: "GIAI",
29
+
30
+ /**
31
+ * Global Service Relation Number.
32
+ */
33
+ GSRN: "GSRN",
34
+
35
+ /**
36
+ * Global Document Type Identifier.
37
+ */
38
+ GDTI: "GDTI",
39
+
40
+ /**
41
+ * Global Identification Number for Consignment.
42
+ */
43
+ GINC: "GINC",
44
+
45
+ /**
46
+ * Global Shipment Identification Number.
47
+ */
48
+ GSIN: "GSIN",
49
+
50
+ /**
51
+ * Global Coupon Number.
52
+ */
53
+ GCN: "GCN",
54
+
55
+ /**
56
+ * Component/Part Identifier.
57
+ */
58
+ CPID: "CPID",
59
+
60
+ /**
61
+ * Global Model Number.
62
+ */
63
+ GMN: "GMN"
64
+ } as const;
65
+
66
+ /**
67
+ * Identifier type.
68
+ */
69
+ export type IdentifierType = typeof IdentifierTypes[keyof typeof IdentifierTypes];
@@ -0,0 +1,235 @@
1
+ import {
2
+ type CharacterSetCreator,
3
+ NUMERIC_CREATOR,
4
+ type StringValidation,
5
+ type StringValidator
6
+ } from "@aidc-toolkit/utility";
7
+ import { AI39_CREATOR, AI82_CREATOR } from "./character-set.js";
8
+ import type { IdentifierType } from "./identifier-type.js";
9
+ import type { PrefixType } from "./prefix-type.js";
10
+ import { PrefixValidator } from "./prefix-validator.js";
11
+
12
+ /**
13
+ * Character sets supported by the reference portion of an identifier or the serial component of a numeric identifier.
14
+ */
15
+ export const ContentCharacterSets = {
16
+ /**
17
+ * Numeric.
18
+ */
19
+ Numeric: "Numeric",
20
+
21
+ /**
22
+ * GS1 AI encodable character set 82.
23
+ */
24
+ AI82: "AI82",
25
+
26
+ /**
27
+ * GS1 AI encodable character set 39.
28
+ */
29
+ AI39: "AI39"
30
+ } as const;
31
+
32
+ /**
33
+ * Content character set.
34
+ */
35
+ export type ContentCharacterSet = typeof ContentCharacterSets[keyof typeof ContentCharacterSets];
36
+
37
+ /**
38
+ * Identifier validation parameters.
39
+ */
40
+ export interface IdentifierValidation extends StringValidation {
41
+ /**
42
+ * Position offset within a larger string. Strings are sometimes composed of multiple substrings; this parameter
43
+ * ensures that the error notes the proper position in the string.
44
+ */
45
+ positionOffset?: number | undefined;
46
+ }
47
+
48
+ /**
49
+ * Identifier validator. Validates an identifier against its definition in section 3 of the {@link
50
+ * https://www.gs1.org/genspecs | GS1 General Specifications}.
51
+ *
52
+ * @template TIdentifierValidation
53
+ * Identifier validation type.
54
+ */
55
+ export interface IdentifierValidator<TIdentifierValidation extends IdentifierValidation = IdentifierValidation> extends StringValidator<TIdentifierValidation> {
56
+ /**
57
+ * Get the identifier type. Per the GS1 General Specifications, the identifier type determines the remaining
58
+ * properties.
59
+ */
60
+ get identifierType(): IdentifierType;
61
+
62
+ /**
63
+ * Get the prefix type supported by the identifier type. For all identifier types except the GTIN, this is
64
+ * {@linkcode PrefixTypes.GS1CompanyPrefix}. For the GTIN, the prefix type determines the length.
65
+ */
66
+ get prefixType(): PrefixType;
67
+
68
+ /**
69
+ * Get the length. For numeric identifier types, the length is fixed; for alphanumeric identifier types, the length
70
+ * is the maximum.
71
+ */
72
+ get length(): number;
73
+
74
+ /**
75
+ * Get the reference character set.
76
+ */
77
+ get referenceCharacterSet(): ContentCharacterSet;
78
+
79
+ /**
80
+ * Get the reference creator.
81
+ */
82
+ get referenceCreator(): CharacterSetCreator;
83
+
84
+ /**
85
+ * Validate an identifier and throw an error if validation fails.
86
+ *
87
+ * @param identifier
88
+ * Identifier.
89
+ *
90
+ * @param validation
91
+ * Identifier validation parameters.
92
+ */
93
+ validate: (identifier: string, validation?: TIdentifierValidation) => void;
94
+ }
95
+
96
+ /**
97
+ * Abstract identifier validator. Implements common functionality for an identifier validator.
98
+ */
99
+ export abstract class AbstractIdentifierValidator<TIdentifierValidation extends IdentifierValidation = IdentifierValidation> implements IdentifierValidator<TIdentifierValidation> {
100
+ private static readonly CHARACTER_SET_CREATORS: Record<ContentCharacterSet, CharacterSetCreator> = {
101
+ [ContentCharacterSets.Numeric]: NUMERIC_CREATOR,
102
+ [ContentCharacterSets.AI82]: AI82_CREATOR,
103
+ [ContentCharacterSets.AI39]: AI39_CREATOR
104
+ };
105
+
106
+ /**
107
+ * Identifier type.
108
+ */
109
+ private readonly _identifierType: IdentifierType;
110
+
111
+ /**
112
+ * Prefix type.
113
+ */
114
+ private readonly _prefixType: PrefixType;
115
+
116
+ /**
117
+ * Length.
118
+ */
119
+ private readonly _length: number;
120
+
121
+ /**
122
+ * Reference character set.
123
+ */
124
+ private readonly _referenceCharacterSet: ContentCharacterSet;
125
+
126
+ /**
127
+ * Reference creator.
128
+ */
129
+ private readonly _referenceCreator: CharacterSetCreator;
130
+
131
+ /**
132
+ * Get the character set creator for a character set.
133
+ *
134
+ * @param characterSet
135
+ * Character set.
136
+ *
137
+ * @returns
138
+ * Character set creator.
139
+ */
140
+ protected static creatorFor(characterSet: ContentCharacterSet): CharacterSetCreator {
141
+ return AbstractIdentifierValidator.CHARACTER_SET_CREATORS[characterSet];
142
+ }
143
+
144
+ /**
145
+ * Constructor.
146
+ *
147
+ * @param identifierType
148
+ * Identifier type.
149
+ *
150
+ * @param prefixType
151
+ * Prefix type.
152
+ *
153
+ * @param length
154
+ * Length.
155
+ *
156
+ * @param referenceCharacterSet
157
+ * Reference character set.
158
+ */
159
+ protected constructor(identifierType: IdentifierType, prefixType: PrefixType, length: number, referenceCharacterSet: ContentCharacterSet) {
160
+ this._identifierType = identifierType;
161
+ this._prefixType = prefixType;
162
+ this._length = length;
163
+ this._referenceCharacterSet = referenceCharacterSet;
164
+ this._referenceCreator = AbstractIdentifierValidator.creatorFor(referenceCharacterSet);
165
+ }
166
+
167
+ /**
168
+ * @inheritDoc
169
+ */
170
+ get identifierType(): IdentifierType {
171
+ return this._identifierType;
172
+ }
173
+
174
+ /**
175
+ * @inheritDoc
176
+ */
177
+ get prefixType(): PrefixType {
178
+ return this._prefixType;
179
+ }
180
+
181
+ /**
182
+ * @inheritDoc
183
+ */
184
+ get length(): number {
185
+ return this._length;
186
+ }
187
+
188
+ /**
189
+ * @inheritDoc
190
+ */
191
+ get referenceCharacterSet(): ContentCharacterSet {
192
+ return this._referenceCharacterSet;
193
+ }
194
+
195
+ /**
196
+ * @inheritDoc
197
+ */
198
+ get referenceCreator(): CharacterSetCreator {
199
+ return this._referenceCreator;
200
+ }
201
+
202
+ /**
203
+ * Pad an identifier on the left with zero-value character for validation purposes. This is done to align an
204
+ * identifier with a position offset for any error message that may be thrown by the reference validator.
205
+ *
206
+ * @param identifier
207
+ * Identifier.
208
+ *
209
+ * @param validation
210
+ * Identifier validation parameters.
211
+ *
212
+ * @returns
213
+ * Padded identifier.
214
+ */
215
+ protected padIdentifier(identifier: string, validation: IdentifierValidation | undefined): string {
216
+ // Identifier is returned as is if position offset is undefined.
217
+ return validation?.positionOffset === undefined ? identifier : this.referenceCreator.character(0).repeat(validation.positionOffset).concat(identifier);
218
+ }
219
+
220
+ /**
221
+ * Validate the prefix within an identifier.
222
+ *
223
+ * @param partialIdentifier
224
+ * Partial identifier.
225
+ *
226
+ * @param positionOffset
227
+ * Position offset within a larger string.
228
+ */
229
+ protected validatePrefix(partialIdentifier: string, positionOffset?: number): void {
230
+ // Delegate to prefix validator with support for U.P.C. Company Prefix but not GS1-8 Prefix.
231
+ PrefixValidator.validate(this.prefixType, true, false, partialIdentifier, true, this.referenceCharacterSet === ContentCharacterSets.Numeric, positionOffset);
232
+ }
233
+
234
+ abstract validate(identifier: string, validation?: TIdentifierValidation): void;
235
+ }
package/src/index.ts CHANGED
@@ -17,4 +17,19 @@
17
17
  export * from "./locale/i18n.js";
18
18
  export * from "./character-set.js";
19
19
  export * from "./check.js";
20
- export * from "./idkey.js";
20
+ export * from "./prefix-type.js";
21
+ export * from "./prefix-validator.js";
22
+ export * from "./identifier-type.js";
23
+ export * from "./identifier-validator.js";
24
+ export * from "./numeric-identifier-validator.js";
25
+ export * from "./gtin-validator.js";
26
+ export * from "./non-gtin-numeric-identifier-validator.js";
27
+ export * from "./serializable-numeric-identifier-validator.js";
28
+ export * from "./non-numeric-identifier-validator.js";
29
+ export * from "./identifier-creator.js";
30
+ export * from "./numeric-identifier-creator.js";
31
+ export * from "./gtin-creator.js";
32
+ export * from "./non-gtin-numeric-identifier-creator.js";
33
+ export * from "./serializable-numeric-identifier-creator.js";
34
+ export * from "./non-numeric-identifier-creator.js";
35
+ export * from "./prefix-manager.js";
@@ -4,8 +4,8 @@ export const localeStrings = {
4
4
  priceOrWeightComponent: "price or weight",
5
5
  lengthOfStringForCheckCharacterPairMustBeLessThanOrEqualTo: "Length {{length, number}} of string for check character pair must be less than or equal to {{maximumLength, number}}"
6
6
  },
7
- IdentificationKey: {
8
- identificationKeyTypeLength: "{{identificationKeyType}} must be {{length, number}} digits long",
7
+ Identifier: {
8
+ identifierTypeLength: "{{identifierType}} must be {{length, number}} digits long",
9
9
  invalidCheckDigit: "Invalid check digit",
10
10
  invalidGTINLength: "GTIN must be 13, 12, 8, or 14 digits long",
11
11
  invalidGTIN14Length: "GTIN must be 14 digits long",
@@ -36,6 +36,6 @@ export const localeStrings = {
36
36
  gs1CompanyPrefixCantStartWith000000: "GS1 Company Prefix can't start with \"000000\"",
37
37
  upcCompanyPrefixCantStartWith0000: "U.P.C. Company Prefix can't start with \"0000\"",
38
38
  gs18PrefixCantStartWith0: "GS1-8 Prefix can't start with \"0\"",
39
- identificationKeyTypeNotSupportedByGS18Prefix: "{{identificationKeyType}} not supported by GS1-8 Prefix"
39
+ identifierTypeNotSupportedByGS18Prefix: "{{identifierType}} not supported by GS1-8 Prefix"
40
40
  }
41
41
  } as const;
@@ -4,8 +4,8 @@ export const localeStrings = {
4
4
  priceOrWeightComponent: "prix ou poids",
5
5
  lengthOfStringForCheckCharacterPairMustBeLessThanOrEqualTo: "La longueur {{length, number}} de la chaîne pour la paire de caractères de vérification doit être inférieure ou égale à {{maximum Length}}"
6
6
  },
7
- IdentificationKey: {
8
- identificationKeyTypeLength: "{{identificationKeyType}} doit comporter {{length, number}} chiffres",
7
+ Identifier: {
8
+ identifierTypeLength: "{{identifierType}} doit comporter {{length, number}} chiffres",
9
9
  invalidCheckDigit: "Chiffre de contrôle non valide",
10
10
  invalidGTINLength: "Le GTIN doit comporter 13, 12, 8 ou 14 chiffres",
11
11
  invalidGTIN14Length: "Le GTIN doit comporter 14 chiffres",
@@ -36,6 +36,6 @@ export const localeStrings = {
36
36
  gs1CompanyPrefixCantStartWith000000: "Le préfixe de l'entreprise GS1 ne peut pas commencer par \"000000\"",
37
37
  upcCompanyPrefixCantStartWith0000: "Le préfixe de l'entreprise U.P.C. ne peut pas commencer par \"0000\"",
38
38
  gs18PrefixCantStartWith0: "Le préfixe GS1-8 ne peut pas commencer par \"0\"",
39
- identificationKeyTypeNotSupportedByGS18Prefix: "{{identificationKeyType}} non pris en charge par le préfixe GS1-8"
39
+ identifierTypeNotSupportedByGS18Prefix: "{{identifierType}} non pris en charge par le préfixe GS1-8"
40
40
  }
41
41
  } as const;
@@ -0,0 +1,33 @@
1
+ import { Mixin } from "ts-mixer";
2
+ import type { IdentifierType } from "./identifier-type.js";
3
+ import { NonGTINNumericIdentifierValidator } from "./non-gtin-numeric-identifier-validator.js";
4
+ import { AbstractNumericIdentifierCreator } from "./numeric-identifier-creator.js";
5
+ import { type LeaderType, LeaderTypes } from "./numeric-identifier-validator.js";
6
+ import type { PrefixProvider } from "./prefix-provider";
7
+
8
+ /**
9
+ * Non-GTIN numeric identifier creator.
10
+ */
11
+ export class NonGTINNumericIdentifierCreator extends Mixin(NonGTINNumericIdentifierValidator, AbstractNumericIdentifierCreator) {
12
+ /**
13
+ * Constructor. Typically called internally by a prefix manager but may be called by other code with another prefix
14
+ * provider type.
15
+ *
16
+ * @param prefixProvider
17
+ * Prefix provider.
18
+ *
19
+ * @param identifierType
20
+ * Identifier type.
21
+ *
22
+ * @param length
23
+ * Length.
24
+ *
25
+ * @param leaderType
26
+ * Leader type.
27
+ */
28
+ constructor(prefixProvider: PrefixProvider, identifierType: IdentifierType, length: number, leaderType: LeaderType = LeaderTypes.None) {
29
+ super(identifierType, length, leaderType);
30
+
31
+ this.init(prefixProvider, prefixProvider.gs1CompanyPrefix);
32
+ }
33
+ }
@@ -0,0 +1,54 @@
1
+ import { type IdentifierType, IdentifierTypes } from "./identifier-type.js";
2
+ import {
3
+ AbstractNumericIdentifierValidator,
4
+ type LeaderType,
5
+ LeaderTypes,
6
+ type NumericIdentifierType
7
+ } from "./numeric-identifier-validator.js";
8
+ import { PrefixTypes } from "./prefix-type.js";
9
+
10
+ /**
11
+ * Non-GTIN numeric identifier type.
12
+ */
13
+ export type NonGTINNumericIdentifierType = Exclude<NumericIdentifierType, typeof IdentifierTypes.GTIN>;
14
+
15
+ /**
16
+ * Non-GTIN numeric identifier validator.
17
+ */
18
+ export class NonGTINNumericIdentifierValidator extends AbstractNumericIdentifierValidator {
19
+ /**
20
+ * Constructor.
21
+ *
22
+ * @param identifierType
23
+ * Identifier type.
24
+ *
25
+ * @param length
26
+ * Length.
27
+ *
28
+ * @param leaderType
29
+ * Leader type.
30
+ */
31
+ constructor(identifierType: IdentifierType, length: number, leaderType: LeaderType = LeaderTypes.None) {
32
+ super(identifierType, PrefixTypes.GS1CompanyPrefix, length, leaderType);
33
+ }
34
+ }
35
+
36
+ /**
37
+ * GLN validator.
38
+ */
39
+ export const GLN_VALIDATOR = new NonGTINNumericIdentifierValidator(IdentifierTypes.GLN, 13);
40
+
41
+ /**
42
+ * SSCC validator.
43
+ */
44
+ export const SSCC_VALIDATOR = new NonGTINNumericIdentifierValidator(IdentifierTypes.SSCC, 18, LeaderTypes.ExtensionDigit);
45
+
46
+ /**
47
+ * GSRN validator.
48
+ */
49
+ export const GSRN_VALIDATOR = new NonGTINNumericIdentifierValidator(IdentifierTypes.GSRN, 18);
50
+
51
+ /**
52
+ * GSIN validator.
53
+ */
54
+ export const GSIN_VALIDATOR = new NonGTINNumericIdentifierValidator(IdentifierTypes.GSIN, 17);
@@ -0,0 +1,111 @@
1
+ import {
2
+ type CharacterSetValidation,
3
+ mapIterable,
4
+ type TransformerInput,
5
+ type TransformerOutput
6
+ } from "@aidc-toolkit/utility";
7
+ import { Mixin } from "ts-mixer";
8
+ import { checkCharacterPair } from "./check.js";
9
+ import { AbstractIdentifierCreator } from "./identifier-creator.js";
10
+ import type { IdentifierType } from "./identifier-type.js";
11
+ import type { ContentCharacterSet } from "./identifier-validator.js";
12
+ import { i18nextGS1 } from "./locale/i18n.js";
13
+ import { NonNumericIdentifierValidator } from "./non-numeric-identifier-validator.js";
14
+ import type { PrefixProvider } from "./prefix-provider";
15
+
16
+ /**
17
+ * Non-numeric identifier creator.
18
+ */
19
+ export class NonNumericIdentifierCreator extends Mixin(NonNumericIdentifierValidator, AbstractIdentifierCreator) {
20
+ /**
21
+ * Reference validation parameters.
22
+ */
23
+ private readonly _referenceValidation: CharacterSetValidation;
24
+
25
+ /**
26
+ * Constructor. Typically called internally by a prefix manager but may be called by other code with another prefix
27
+ * provider type.
28
+ *
29
+ * @param prefixProvider
30
+ * Prefix provider.
31
+ *
32
+ * @param identifierType
33
+ * Identifier type.
34
+ *
35
+ * @param length
36
+ * Length.
37
+ *
38
+ * @param referenceCharacterSet
39
+ * Reference character set.
40
+ *
41
+ * @param requiresCheckCharacterPair
42
+ * True if the identifier requires a check character pair.
43
+ */
44
+ constructor(prefixProvider: PrefixProvider, identifierType: IdentifierType, length: number, referenceCharacterSet: ContentCharacterSet, requiresCheckCharacterPair = false) {
45
+ super(identifierType, length, referenceCharacterSet, requiresCheckCharacterPair);
46
+
47
+ this.init(prefixProvider, prefixProvider.gs1CompanyPrefix, 2 * Number(requiresCheckCharacterPair));
48
+
49
+ this._referenceValidation = {
50
+ minimumLength: 1,
51
+ // Maximum reference length has to account for prefix and check character pair.
52
+ maximumLength: this.referenceLength,
53
+ component: () => i18nextGS1.t("Identifier.reference")
54
+ };
55
+ }
56
+
57
+ /**
58
+ * Get the reference validation parameters.
59
+ */
60
+ protected get referenceValidation(): CharacterSetValidation {
61
+ return this._referenceValidation;
62
+ }
63
+
64
+ /**
65
+ * Create identifier(s) with reference(s).
66
+ *
67
+ * @template TTransformerInput
68
+ * Transformer input type.
69
+ *
70
+ * @param referenceOrReferences
71
+ * Reference(s).
72
+ *
73
+ * @returns
74
+ * Identifier(s).
75
+ */
76
+ create<TTransformerInput extends TransformerInput<string>>(referenceOrReferences: TTransformerInput): TransformerOutput<TTransformerInput, string> {
77
+ // TODO Refactor type when https://github.com/microsoft/TypeScript/pull/56941 released.
78
+ let result: string | Iterable<string>;
79
+
80
+ const referenceCreator = this.referenceCreator;
81
+ const referenceValidation = this.referenceValidation;
82
+ const prefix = this.prefix;
83
+ const requiresCheckCharacterPair = this.requiresCheckCharacterPair;
84
+
85
+ /**
86
+ * Validate a reference and create an identifier.
87
+ *
88
+ * @param reference
89
+ * Reference.
90
+ *
91
+ * @returns
92
+ * Identifier.
93
+ */
94
+ function validateAndCreate(reference: string): string {
95
+ referenceCreator.validate(reference, referenceValidation);
96
+
97
+ const partialIdentifier = prefix + reference;
98
+
99
+ return requiresCheckCharacterPair ? partialIdentifier + checkCharacterPair(partialIdentifier) : partialIdentifier;
100
+ }
101
+
102
+ if (typeof referenceOrReferences !== "object") {
103
+ result = validateAndCreate(referenceOrReferences);
104
+ } else {
105
+ result = mapIterable(referenceOrReferences, validateAndCreate);
106
+ }
107
+
108
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Type determination is handled above.
109
+ return result as TransformerOutput<TTransformerInput, string>;
110
+ }
111
+ }
@@ -0,0 +1,128 @@
1
+ import { Exclusions, RegExpValidator } from "@aidc-toolkit/utility";
2
+ import { hasValidCheckCharacterPair } from "./check.js";
3
+ import { type IdentifierType, IdentifierTypes } from "./identifier-type.js";
4
+ import {
5
+ AbstractIdentifierValidator,
6
+ type ContentCharacterSet,
7
+ ContentCharacterSets,
8
+ type IdentifierValidation
9
+ } from "./identifier-validator.js";
10
+ import { i18nextGS1 } from "./locale/i18n.js";
11
+ import type { NumericIdentifierType } from "./numeric-identifier-validator.js";
12
+ import { PrefixTypes } from "./prefix-type.js";
13
+
14
+ /**
15
+ * Non-numeric identifier type.
16
+ */
17
+ export type NonNumericIdentifierType = Exclude<IdentifierType, NumericIdentifierType>;
18
+
19
+ /**
20
+ * Non-numeric identifier validation parameters.
21
+ */
22
+ export interface NonNumericIdentifierValidation extends IdentifierValidation {
23
+ /**
24
+ * Exclusion support for reference. Prevents non-numeric identifier from being mistaken for numeric
25
+ * identifier.
26
+ */
27
+ exclusion?: typeof Exclusions.None | typeof Exclusions.AllNumeric | undefined;
28
+ }
29
+
30
+ /**
31
+ * Non-numeric identifier validator.
32
+ */
33
+ export class NonNumericIdentifierValidator extends AbstractIdentifierValidator<NonNumericIdentifierValidation> {
34
+ /**
35
+ * Validator to ensure that an identifier (minus check character pair) is not all numeric.
36
+ */
37
+ private static readonly NOT_ALL_NUMERIC_VALIDATOR = new class extends RegExpValidator {
38
+ /**
39
+ * @inheritDoc
40
+ */
41
+ protected override createErrorMessage(_s: string): string {
42
+ return i18nextGS1.t("Identifier.referenceCantBeAllNumeric");
43
+ }
44
+ }(/\D/);
45
+
46
+ /**
47
+ * True if the identifier requires a check character pair.
48
+ */
49
+ private readonly _requiresCheckCharacterPair: boolean;
50
+
51
+ /**
52
+ * Constructor.
53
+ *
54
+ * @param identifierType
55
+ * Identifier type.
56
+ *
57
+ * @param length
58
+ * Length.
59
+ *
60
+ * @param referenceCharacterSet
61
+ * Reference character set.
62
+ *
63
+ * @param requiresCheckCharacterPair
64
+ * True if the identifier requires a check character pair.
65
+ */
66
+ constructor(identifierType: IdentifierType, length: number, referenceCharacterSet: ContentCharacterSet, requiresCheckCharacterPair = false) {
67
+ super(identifierType, PrefixTypes.GS1CompanyPrefix, length, referenceCharacterSet);
68
+
69
+ this._requiresCheckCharacterPair = requiresCheckCharacterPair;
70
+ }
71
+
72
+ /**
73
+ * Determine if the identifier requires a check character pair.
74
+ */
75
+ get requiresCheckCharacterPair(): boolean {
76
+ return this._requiresCheckCharacterPair;
77
+ }
78
+
79
+ /**
80
+ * Validate a non-numeric identifier and throw an error if validation fails.
81
+ *
82
+ * @param identifier
83
+ * Identifier.
84
+ *
85
+ * @param validation
86
+ * Validation parameters.
87
+ */
88
+ validate(identifier: string, validation?: NonNumericIdentifierValidation): void {
89
+ const partialIdentifier = this.requiresCheckCharacterPair ? identifier.substring(0, identifier.length - 2) : identifier;
90
+
91
+ super.validatePrefix(partialIdentifier, validation?.positionOffset);
92
+
93
+ if (!this.requiresCheckCharacterPair) {
94
+ this.referenceCreator.validate(identifier, {
95
+ maximumLength: this.length,
96
+ positionOffset: validation?.positionOffset
97
+ });
98
+ // Validating the check character pair will also validate the characters.
99
+ } else if (!hasValidCheckCharacterPair(this.padIdentifier(identifier, validation))) {
100
+ throw new RangeError(i18nextGS1.t("Identifier.invalidCheckCharacterPair"));
101
+ }
102
+
103
+ // Check for all-numeric identifier (minus check character pair) if excluded.
104
+ if (validation?.exclusion === Exclusions.AllNumeric) {
105
+ NonNumericIdentifierValidator.NOT_ALL_NUMERIC_VALIDATOR.validate(partialIdentifier);
106
+ }
107
+ }
108
+ }
109
+
110
+ /**
111
+ * GIAI validator.
112
+ */
113
+ export const GIAI_VALIDATOR = new NonNumericIdentifierValidator(IdentifierTypes.GIAI, 30, ContentCharacterSets.AI82);
114
+
115
+ /**
116
+ * GINC validator.
117
+ */
118
+ export const GINC_VALIDATOR = new NonNumericIdentifierValidator(IdentifierTypes.GINC, 30, ContentCharacterSets.AI82);
119
+
120
+ /**
121
+ * CPID validator.
122
+ */
123
+ export const CPID_VALIDATOR = new NonNumericIdentifierValidator(IdentifierTypes.CPID, 30, ContentCharacterSets.AI39);
124
+
125
+ /**
126
+ * GMN validator.
127
+ */
128
+ export const GMN_VALIDATOR = new NonNumericIdentifierValidator(IdentifierTypes.GMN, 25, ContentCharacterSets.AI82, true);