@aidc-toolkit/utility 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aidc-toolkit/utility",
3
- "version": "0.9.7-beta",
3
+ "version": "0.9.9-beta",
4
4
  "description": "Foundational utilities for AIDC Toolkit",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -20,20 +20,21 @@
20
20
  },
21
21
  "scripts": {
22
22
  "lint": "eslint .",
23
- "build": "tsup src/index.ts --clean --format cjs,esm --dts",
24
- "build-doc": "npm run build && tsc src/index.ts --outDir dist --target esnext --moduleResolution nodenext --module nodenext --emitDeclarationOnly --declaration --declarationMap",
23
+ "build-dist": "tsup src/index.ts --clean --format cjs,esm --dts",
24
+ "build-doc": "npm run build-dist && 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.7-beta",
29
- "eslint": "^9.16.0",
28
+ "@aidc-toolkit/dev": "^0.9.9-beta",
29
+ "eslint": "^9.17.0",
30
30
  "ts-node": "^10.9.2",
31
31
  "tsup": "^8.3.5",
32
32
  "typescript": "^5.7.2",
33
33
  "vitest": "^2.1.8"
34
34
  },
35
35
  "dependencies": {
36
- "@aidc-toolkit/core": "^0.9.7-beta",
37
- "@rollup/rollup-linux-x64-gnu": "^4.28.1"
36
+ "@aidc-toolkit/core": "^0.9.9-beta",
37
+ "@rollup/rollup-linux-x64-gnu": "^4.29.1",
38
+ "i18next": "^24.2.0"
38
39
  }
39
40
  }
@@ -1,8 +1,7 @@
1
- import i18next, { utilityNS } from "./locale/i18n.js";
2
- import { RegExpValidator } from "./reg_exp.js";
1
+ import { i18nextUtility } from "./locale/i18n.js";
2
+ import { RegExpValidator } from "./reg-exp.js";
3
3
  import type { StringValidation, StringValidator } from "./string.js";
4
- import { Transformer } from "./transformer.js";
5
- import type { TransformerCallback, TransformerInput, TransformerOutput } from "./types.js";
4
+ import { Transformer, type TransformerCallback, type TransformerInput, type TransformerOutput } from "./transformer.js";
6
5
 
7
6
  /**
8
7
  * Exclusion options for validating and creating strings based on character sets.
@@ -72,9 +71,7 @@ export class CharacterSetValidator implements StringValidator<CharacterSetValida
72
71
  * Error message.
73
72
  */
74
73
  protected override createErrorMessage(_s: string): string {
75
- return i18next.t("CharacterSetValidator.stringMustNotBeAllNumeric", {
76
- ns: utilityNS
77
- });
74
+ return i18nextUtility.t("CharacterSetValidator.stringMustNotBeAllNumeric");
78
75
  }
79
76
  }(/\D/);
80
77
 
@@ -200,8 +197,7 @@ export class CharacterSetValidator implements StringValidator<CharacterSetValida
200
197
  */
201
198
  protected validateExclusion(exclusion: Exclusion): void {
202
199
  if (exclusion !== Exclusion.None && !this._exclusionSupport.includes(exclusion)) {
203
- throw new RangeError(i18next.t("CharacterSetValidator.exclusionNotSupported", {
204
- ns: utilityNS,
200
+ throw new RangeError(i18nextUtility.t("CharacterSetValidator.exclusionNotSupported", {
205
201
  exclusion
206
202
  }));
207
203
  }
@@ -227,15 +223,13 @@ export class CharacterSetValidator implements StringValidator<CharacterSetValida
227
223
  let errorMessage: string;
228
224
 
229
225
  if (maximumLength !== undefined && maximumLength === minimumLength) {
230
- errorMessage = i18next.t(validation?.component === undefined ? "CharacterSetValidator.lengthMustBeEqualTo" : "CharacterSetValidator.lengthOfComponentMustBeEqualTo", {
231
- ns: utilityNS,
226
+ errorMessage = i18nextUtility.t(validation?.component === undefined ? "CharacterSetValidator.lengthMustBeEqualTo" : "CharacterSetValidator.lengthOfComponentMustBeEqualTo", {
232
227
  component: CharacterSetValidator.componentToString(validation?.component),
233
228
  length,
234
229
  exactLength: minimumLength
235
230
  });
236
231
  } else {
237
- errorMessage = i18next.t(validation?.component === undefined ? "CharacterSetValidator.lengthMustBeGreaterThanOrEqualTo" : "CharacterSetValidator.lengthOfComponentMustBeGreaterThanOrEqualTo", {
238
- ns: utilityNS,
232
+ errorMessage = i18nextUtility.t(validation?.component === undefined ? "CharacterSetValidator.lengthMustBeGreaterThanOrEqualTo" : "CharacterSetValidator.lengthOfComponentMustBeGreaterThanOrEqualTo", {
239
233
  component: CharacterSetValidator.componentToString(validation?.component),
240
234
  length,
241
235
  minimumLength
@@ -246,8 +240,7 @@ export class CharacterSetValidator implements StringValidator<CharacterSetValida
246
240
  }
247
241
 
248
242
  if (maximumLength !== undefined && length > maximumLength) {
249
- throw new RangeError(i18next.t(validation?.component === undefined ? "CharacterSetValidator.lengthMustBeLessThanOrEqualTo" : "CharacterSetValidator.lengthOfComponentMustBeLessThanOrEqualTo", {
250
- ns: utilityNS,
243
+ throw new RangeError(i18nextUtility.t(validation?.component === undefined ? "CharacterSetValidator.lengthMustBeLessThanOrEqualTo" : "CharacterSetValidator.lengthOfComponentMustBeLessThanOrEqualTo", {
251
244
  component: CharacterSetValidator.componentToString(validation?.component),
252
245
  length,
253
246
  maximumLength
@@ -258,8 +251,7 @@ export class CharacterSetValidator implements StringValidator<CharacterSetValida
258
251
  const index = this.characterIndexes(s).findIndex(characterIndex => characterIndex === undefined);
259
252
 
260
253
  if (index !== -1) {
261
- throw new RangeError(i18next.t(validation?.component === undefined ? "CharacterSetValidator.invalidCharacterAtPosition" : "CharacterSetValidator.invalidCharacterAtPositionOfComponent", {
262
- ns: utilityNS,
254
+ throw new RangeError(i18nextUtility.t(validation?.component === undefined ? "CharacterSetValidator.invalidCharacterAtPosition" : "CharacterSetValidator.invalidCharacterAtPositionOfComponent", {
263
255
  component: CharacterSetValidator.componentToString(validation?.component),
264
256
  c: s.charAt(index),
265
257
  position: index + (validation?.positionOffset ?? 0) + 1
@@ -275,8 +267,7 @@ export class CharacterSetValidator implements StringValidator<CharacterSetValida
275
267
 
276
268
  case Exclusion.FirstZero:
277
269
  if (s.startsWith("0")) {
278
- throw new RangeError(i18next.t(validation.component === undefined ? "CharacterSetValidator.invalidCharacterAtPosition" : "CharacterSetValidator.invalidCharacterAtPositionOfComponent", {
279
- ns: utilityNS,
270
+ throw new RangeError(i18nextUtility.t(validation.component === undefined ? "CharacterSetValidator.invalidCharacterAtPosition" : "CharacterSetValidator.invalidCharacterAtPositionOfComponent", {
280
271
  component: CharacterSetValidator.componentToString(validation.component),
281
272
  c: "0",
282
273
  position: (validation.positionOffset ?? 0) + 1
@@ -384,9 +375,7 @@ export class CharacterSetCreator extends CharacterSetValidator {
384
375
 
385
376
  if (exclusionSupport.includes(Exclusion.FirstZero)) {
386
377
  if (characterSet[0] !== "0") {
387
- throw new RangeError(i18next.t("CharacterSetValidator.firstZeroFirstCharacter", {
388
- ns: utilityNS
389
- }));
378
+ throw new RangeError(i18nextUtility.t("CharacterSetValidator.firstZeroFirstCharacter"));
390
379
  }
391
380
 
392
381
  const exclusionFirstZeroDomains = new Array<bigint>(CharacterSetCreator.MAXIMUM_STRING_LENGTH + 1);
@@ -417,9 +406,7 @@ export class CharacterSetCreator extends CharacterSetValidator {
417
406
  // Make sure that all numeric characters are present and in sequence.
418
407
  for (const numberIndex of numberIndexes) {
419
408
  if (numberIndex === undefined || numberIndex !== expectedNumberIndex) {
420
- throw new RangeError(i18next.t("CharacterSetValidator.allNumericAllNumericCharacters", {
421
- ns: utilityNS
422
- }));
409
+ throw new RangeError(i18nextUtility.t("CharacterSetValidator.allNumericAllNumericCharacters"));
423
410
  }
424
411
 
425
412
  expectedNumberIndex = numberIndex + 1;
@@ -491,9 +478,7 @@ export class CharacterSetCreator extends CharacterSetValidator {
491
478
  if (length === 0) {
492
479
  if (!shiftForward && value < 10n) {
493
480
  // If calculation gets this far, string is all-numeric.
494
- throw new RangeError(i18next.t("CharacterSetValidator.stringMustNotBeAllNumeric", {
495
- ns: utilityNS
496
- }));
481
+ throw new RangeError(i18nextUtility.t("CharacterSetValidator.stringMustNotBeAllNumeric"));
497
482
  }
498
483
 
499
484
  // Now dealing with individual characters; shift by 10 to skip numeric characters.
@@ -528,16 +513,14 @@ export class CharacterSetCreator extends CharacterSetValidator {
528
513
  */
529
514
  private validateLength(length: number): void {
530
515
  if (length < 0) {
531
- throw new RangeError(i18next.t("CharacterSetValidator.lengthMustBeGreaterThanOrEqualTo", {
532
- ns: utilityNS,
516
+ throw new RangeError(i18nextUtility.t("CharacterSetValidator.lengthMustBeGreaterThanOrEqualTo", {
533
517
  length,
534
518
  minimumLength: 0
535
519
  }));
536
520
  }
537
521
 
538
522
  if (length > CharacterSetCreator.MAXIMUM_STRING_LENGTH) {
539
- throw new RangeError(i18next.t("CharacterSetValidator.lengthMustBeLessThanOrEqualTo", {
540
- ns: utilityNS,
523
+ throw new RangeError(i18nextUtility.t("CharacterSetValidator.lengthMustBeLessThanOrEqualTo", {
541
524
  length,
542
525
  maximumLength: CharacterSetCreator.MAXIMUM_STRING_LENGTH
543
526
  }));
@@ -602,7 +585,7 @@ export class CharacterSetCreator extends CharacterSetValidator {
602
585
  s = this.character(exclusion === Exclusion.FirstZero ? Number(convertValue % this._characterSetSizeMinusOneN) + 1 : Number(convertValue % this._characterSetSizeN)) + s;
603
586
  }
604
587
 
605
- return creatorCallback !== undefined ? creatorCallback(s, index) : s;
588
+ return creatorCallback === undefined ? s : creatorCallback(s, index);
606
589
  });
607
590
  }
608
591
 
@@ -633,8 +616,7 @@ export class CharacterSetCreator extends CharacterSetValidator {
633
616
  // Convert string to its value character by character.
634
617
  let value = this.characterIndexes(s).reduce((accumulator, characterIndex, index) => {
635
618
  if (characterIndex === undefined) {
636
- throw new RangeError(i18next.t("CharacterSetValidator.invalidCharacterAtPosition", {
637
- ns: utilityNS,
619
+ throw new RangeError(i18nextUtility.t("CharacterSetValidator.invalidCharacterAtPosition", {
638
620
  c: s.charAt(index),
639
621
  position: index + 1
640
622
  }));
@@ -644,8 +626,7 @@ export class CharacterSetCreator extends CharacterSetValidator {
644
626
 
645
627
  if (index === 0 && exclusion === Exclusion.FirstZero) {
646
628
  if (characterIndex === 0) {
647
- throw new RangeError(i18next.t("CharacterSetValidator.invalidCharacterAtPosition", {
648
- ns: utilityNS,
629
+ throw new RangeError(i18nextUtility.t("CharacterSetValidator.invalidCharacterAtPosition", {
649
630
  c: "0",
650
631
  position: 1
651
632
  }));
package/src/index.ts CHANGED
@@ -1,9 +1,23 @@
1
- export { utilityNS } from "./locale/i18n.js";
2
- export type * from "./types.js";
3
- export * from "./iterator_proxy.js";
4
- export * from "./sequencer.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 "./sequence.js";
5
19
  export * from "./transformer.js";
6
20
  export type * from "./string.js";
7
- export * from "./reg_exp.js";
21
+ export * from "./reg-exp.js";
8
22
  export * from "./record.js";
9
- export * from "./character_set.js";
23
+ export * from "./character-set.js";
@@ -4,8 +4,8 @@ export const localeStrings = {
4
4
  tweakMustBeGreaterThanOrEqualToZero: "Tweak {{tweak}} must be greater than or equal to 0",
5
5
  valueMustBeGreaterThanOrEqualToZero: "Value {{value}} must be greater than or equal to 0",
6
6
  valueMustBeLessThan: "Value {{value}} must be less than {{domain}}",
7
- minValueMustBeGreaterThanOrEqualToZero: "Minimum value {{minValue}} must be greater than or equal to 0",
8
- maxValueMustBeLessThan: "Maximum value {{maxValue}} must be less than {{domain}}"
7
+ minimumValueMustBeGreaterThanOrEqualToZero: "Minimum value {{minimumValue}} must be greater than or equal to 0",
8
+ maximumValueMustBeLessThan: "Maximum value {{maximumValue}} must be less than {{domain}}"
9
9
  },
10
10
  RegExpValidator: {
11
11
  stringDoesNotMatchPattern: "String {{s}} does not match pattern"
@@ -4,8 +4,8 @@ export const localeStrings = {
4
4
  tweakMustBeGreaterThanOrEqualToZero: "Le réglage {{tweak}} doit être supérieur ou égal à 0",
5
5
  valueMustBeGreaterThanOrEqualToZero: "La valeur {{value}} doit être supérieure ou égale à 0",
6
6
  valueMustBeLessThan: "La valeur {{value}} doit être inférieure à {{domain}}",
7
- minValueMustBeGreaterThanOrEqualToZero: "La valeur minimale {{minValue}} doit être supérieure ou égale à 0",
8
- maxValueMustBeLessThan: "La valeur maximale {{maxValue}} doit être inférieure à {{domain}}"
7
+ minimumValueMustBeGreaterThanOrEqualToZero: "La valeur minimale {{minimumValue}} doit être supérieure ou égale à 0",
8
+ maximumValueMustBeLessThan: "La valeur maximale {{maximumValue}} doit être inférieure à {{domain}}"
9
9
  },
10
10
  RegExpValidator: {
11
11
  stringDoesNotMatchPattern: "La chaîne {{s}} ne correspond pas au modèle"
@@ -1,12 +1,44 @@
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 i18next, { type i18n, type Resource } from "i18next";
3
+ import { localeStrings as enLocaleStrings } from "./en/locale-strings.js";
4
+ import { localeStrings as frLocaleStrings } from "./fr/locale-strings.js";
4
5
 
5
6
  export const utilityNS = "aidct_utility";
6
7
 
8
+ /**
9
+ * Locale strings type is extracted from the English locale strings object.
10
+ */
11
+ export type UtilityLocaleStrings = typeof enLocaleStrings;
12
+
7
13
  i18nAssertValidResources(enLocaleStrings, "fr", frLocaleStrings);
8
14
 
9
- i18nAddResourceBundle("en", utilityNS, enLocaleStrings);
10
- i18nAddResourceBundle("fr", utilityNS, frLocaleStrings);
15
+ /**
16
+ * Utility resources.
17
+ */
18
+ export const utilityResources: Resource = {
19
+ en: {
20
+ aidct_utility: enLocaleStrings
21
+ },
22
+ fr: {
23
+ aidct_utility: frLocaleStrings
24
+ }
25
+ };
26
+
27
+ // Explicit type is necessary to work around bug in type discovery with linked packages.
28
+ export const i18nextUtility: i18n = 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 i18nUtilityInit(environment: I18NEnvironment, debug = false): Promise<void> {
43
+ await i18nCoreInit(i18nextUtility, environment, debug, utilityNS, utilityResources);
44
+ }
@@ -1,4 +1,4 @@
1
- import type { localeStrings } from "./en/locale_strings.js";
1
+ import type { UtilityLocaleStrings } from "./i18n.js";
2
2
 
3
3
  /**
4
4
  * Internationalization module.
@@ -8,9 +8,9 @@ declare module "i18next" {
8
8
  * Custom type options for this package.
9
9
  */
10
10
  interface CustomTypeOptions {
11
+ defaultNS: "aidct_utility";
11
12
  resources: {
12
- // Extract the type from the English locale strings object.
13
- aidct_utility: typeof localeStrings;
13
+ aidct_utility: UtilityLocaleStrings;
14
14
  };
15
15
  }
16
16
  }
package/src/record.ts CHANGED
@@ -1,4 +1,4 @@
1
- import i18next, { utilityNS } from "./locale/i18n.js";
1
+ import { i18nextUtility } from "./locale/i18n.js";
2
2
  import type { StringValidator } from "./string.js";
3
3
 
4
4
  /**
@@ -51,9 +51,8 @@ export class RecordValidator<T> implements StringValidator {
51
51
  * Record key.
52
52
  */
53
53
  validate(key: string): void {
54
- if (this.record[key] === undefined) {
55
- throw new RangeError(i18next.t("RecordValidator.typeNameKeyNotFound", {
56
- ns: utilityNS,
54
+ if (!(key in this.record)) {
55
+ throw new RangeError(i18nextUtility.t("RecordValidator.typeNameKeyNotFound", {
57
56
  typeName: this.typeName,
58
57
  key
59
58
  }));
@@ -1,4 +1,4 @@
1
- import i18next, { utilityNS } from "./locale/i18n.js";
1
+ import { i18nextUtility } from "./locale/i18n.js";
2
2
  import type { StringValidator } from "./string.js";
3
3
 
4
4
  /**
@@ -44,8 +44,7 @@ export class RegExpValidator implements StringValidator {
44
44
  * Error message.
45
45
  */
46
46
  protected createErrorMessage(s: string): string {
47
- return i18next.t("RegExpValidator.stringDoesNotMatchPattern", {
48
- ns: utilityNS,
47
+ return i18nextUtility.t("RegExpValidator.stringDoesNotMatchPattern", {
49
48
  s
50
49
  });
51
50
  }
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Sequence. Defines an ascending or descending sequence of big integers implemented as an iterable.
3
+ */
4
+ export class Sequence implements Iterable<bigint> {
5
+ /**
6
+ * Start value (inclusive).
7
+ */
8
+ private readonly _startValue: bigint;
9
+
10
+ /**
11
+ * End value (exclusive).
12
+ */
13
+ private readonly _endValue: bigint;
14
+
15
+ /**
16
+ * Count of values.
17
+ */
18
+ private readonly _count: number;
19
+
20
+ /**
21
+ * Delta to the next value; equal to the sign of the count.
22
+ */
23
+ private readonly _nextDelta: 1n | -1n;
24
+
25
+ /**
26
+ * Minimum value (inclusive).
27
+ */
28
+ private readonly _minimumValue: bigint;
29
+
30
+ /**
31
+ * Maximum value (inclusive).
32
+ */
33
+ private readonly _maximumValue: bigint;
34
+
35
+ /**
36
+ * Constructor.
37
+ *
38
+ * @param startValue
39
+ * Start value.
40
+ *
41
+ * @param count
42
+ * Count of values. If count is zero or positive, iteration ascends from start value, otherwise it descends from
43
+ * start value.
44
+ */
45
+ constructor(startValue: number | bigint, count: number) {
46
+ this._startValue = BigInt(startValue);
47
+ this._endValue = this._startValue + BigInt(count);
48
+ this._count = count;
49
+
50
+ if (count >= 0) {
51
+ this._nextDelta = 1n;
52
+ this._minimumValue = this._startValue;
53
+ this._maximumValue = this._endValue - 1n;
54
+ } else {
55
+ this._nextDelta = -1n;
56
+ this._minimumValue = this._endValue + 1n;
57
+ this._maximumValue = this._startValue;
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Get the start value (inclusive).
63
+ */
64
+ get startValue(): bigint {
65
+ return this._startValue;
66
+ }
67
+
68
+ /**
69
+ * Get the end value (exclusive).
70
+ */
71
+ get endValue(): bigint {
72
+ return this._endValue;
73
+ }
74
+
75
+ /**
76
+ * Get the count of values.
77
+ */
78
+ get count(): number {
79
+ return this._count;
80
+ }
81
+
82
+ /**
83
+ * Get the minimum value (inclusive).
84
+ */
85
+ get minimumValue(): bigint {
86
+ return this._minimumValue;
87
+ }
88
+
89
+ /**
90
+ * Get the maximum value (inclusive).
91
+ */
92
+ get maximumValue(): bigint {
93
+ return this._maximumValue;
94
+ }
95
+
96
+ /**
97
+ * Iterable implementation.
98
+ *
99
+ * @yields
100
+ * Next value in sequence.
101
+ */
102
+ * [Symbol.iterator](): Generator<bigint> {
103
+ for (let value = this._startValue; value !== this._endValue; value += this._nextDelta) {
104
+ yield value;
105
+ }
106
+ }
107
+ }