@aidc-toolkit/utility 0.9.1 → 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/eslint.config.js CHANGED
@@ -1,18 +1,3 @@
1
- import tseslint from "typescript-eslint";
2
- import js from "@eslint/js";
3
- import stylistic from "@stylistic/eslint-plugin";
4
- import jsdoc from "eslint-plugin-jsdoc";
5
- import esLintConfigLove from "eslint-config-love";
6
1
  import { esLintConfigAIDCToolkit } from "@aidc-toolkit/dev";
7
2
 
8
- export default tseslint.config(
9
- {
10
- ignores: ["eslint.config.js", "dist"]
11
- },
12
- js.configs.recommended,
13
- ...tseslint.configs.strictTypeChecked,
14
- stylistic.configs["recommended-flat"],
15
- jsdoc.configs["flat/recommended-typescript"],
16
- esLintConfigLove,
17
- esLintConfigAIDCToolkit
18
- );
3
+ export default esLintConfigAIDCToolkit;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aidc-toolkit/utility",
3
- "version": "0.9.1",
3
+ "version": "0.9.3",
4
4
  "description": "Foundational utilities for AIDC Toolkit",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -21,23 +21,19 @@
21
21
  "scripts": {
22
22
  "eslint": "eslint .",
23
23
  "build": "tsup src/index.ts --clean --format cjs,esm --dts",
24
- "build-dev": "npm run build && tsc src/index.ts --outDir dist --target esnext --moduleResolution nodenext --module nodenext --emitDeclarationOnly --declaration --declarationMap",
24
+ "build-doc": "npm run build && tsc src/index.ts --outDir dist --target esnext --moduleResolution nodenext --module nodenext --emitDeclarationOnly --declaration --declarationMap",
25
25
  "test": "vitest run"
26
26
  },
27
27
  "devDependencies": {
28
- "@aidc-toolkit/dev": "^0.9.1",
29
- "@eslint/js": "^9.11.1",
30
- "@stylistic/eslint-plugin": "^2.8.0",
31
- "eslint-config-love": "^71.0.0",
32
- "eslint-plugin-jsdoc": "^50.3.0",
28
+ "@aidc-toolkit/dev": "^0.9.3",
29
+ "eslint": "^9.14.0",
33
30
  "ts-node": "^10.9.2",
34
- "tsup": "^8.3.0",
35
- "typescript": "^5.6.2",
36
- "typescript-eslint": "^8.7.0",
37
- "vitest": "^2.1.1"
31
+ "tsup": "^8.3.5",
32
+ "typescript": "^5.6.3",
33
+ "vitest": "^2.1.5"
38
34
  },
39
35
  "dependencies": {
40
- "@aidc-toolkit/core": "^0.9.1",
41
- "i18next": "^23.15.1"
36
+ "@aidc-toolkit/core": "^0.9.3",
37
+ "i18next": "^23.16.5"
42
38
  }
43
39
  }
@@ -28,29 +28,29 @@ export enum Exclusion {
28
28
  */
29
29
  export interface CharacterSetValidation extends StringValidation {
30
30
  /**
31
- * Minimum length. If defined and the string is less than this length, an exception is thrown.
31
+ * Minimum length. If defined and the string is less than this length, an error is thrown.
32
32
  */
33
33
  minimumLength?: number | undefined;
34
34
 
35
35
  /**
36
- * Maximum length. If defined and the string is greater than this length, an exception is thrown.
36
+ * Maximum length. If defined and the string is greater than this length, an error is thrown.
37
37
  */
38
38
  maximumLength?: number | undefined;
39
39
 
40
40
  /**
41
- * Exclusion from the string. If defined and the string is within the exclusion range, an exception is thrown.
41
+ * Exclusion from the string. If defined and the string is within the exclusion range, an error is thrown.
42
42
  */
43
43
  exclusion?: Exclusion | undefined;
44
44
 
45
45
  /**
46
46
  * Position offset within a larger string. Strings are sometimes composed of multiple substrings; this parameter
47
- * ensures that the exception notes the proper position in the string.
47
+ * ensures that the error notes the proper position in the string.
48
48
  */
49
49
  positionOffset?: number | undefined;
50
50
 
51
51
  /**
52
52
  * Name of component, typically but not exclusively within a larger string. This parameter ensure that the
53
- * exception notes the component that triggered it. Value may be a string or a callback that returns a string, the
53
+ * error notes the component that triggered it. Value may be a string or a callback that returns a string, the
54
54
  * latter allowing for localization changes.
55
55
  */
56
56
  component?: string | (() => string) | undefined;
@@ -86,7 +86,7 @@ export class CharacterSetValidator implements StringValidator<CharacterSetValida
86
86
  * Character set map, mapping each character in the character set to its index such that
87
87
  * `_characterSetMap.get(_characterSet[index]) === index`.
88
88
  */
89
- private readonly _characterSetMap: Map<string, number>;
89
+ private readonly _characterSetMap: ReadonlyMap<string, number>;
90
90
 
91
91
  /**
92
92
  * Exclusions supported by the character set.
@@ -106,7 +106,13 @@ export class CharacterSetValidator implements StringValidator<CharacterSetValida
106
106
  constructor(characterSet: readonly string[], ...exclusionSupport: readonly Exclusion[]) {
107
107
  this._characterSet = characterSet;
108
108
 
109
- this._characterSetMap = new Map(characterSet.map((c, index) => [c, index]));
109
+ const characterSetMap = new Map<string, number>();
110
+
111
+ characterSet.forEach((c, index) => {
112
+ characterSetMap.set(c, index);
113
+ });
114
+
115
+ this._characterSetMap = characterSetMap;
110
116
 
111
117
  this._exclusionSupport = exclusionSupport;
112
118
  }
@@ -186,7 +192,7 @@ export class CharacterSetValidator implements StringValidator<CharacterSetValida
186
192
  }
187
193
 
188
194
  /**
189
- * Validate that an exclusion is supported. If not, an exception is thrown.
195
+ * Validate that an exclusion is supported. If not, an error is thrown.
190
196
  *
191
197
  * @param exclusion
192
198
  * Exclusion.
@@ -202,7 +208,7 @@ export class CharacterSetValidator implements StringValidator<CharacterSetValida
202
208
 
203
209
  /**
204
210
  * Validate a string. If the string violates the character set or any of the character set validation parameters, an
205
- * exception is thrown.
211
+ * error is thrown.
206
212
  *
207
213
  * @param s
208
214
  * String.
@@ -263,6 +269,9 @@ export class CharacterSetValidator implements StringValidator<CharacterSetValida
263
269
  this.validateExclusion(validation.exclusion);
264
270
 
265
271
  switch (validation.exclusion) {
272
+ case Exclusion.None:
273
+ break;
274
+
266
275
  case Exclusion.FirstZero:
267
276
  if (s.startsWith("0")) {
268
277
  throw new RangeError(i18next.t(validation.component === undefined ? "CharacterSetValidator.invalidCharacterAtPosition" : "CharacterSetValidator.invalidCharacterAtPositionOfComponent", {
@@ -357,12 +366,12 @@ export class CharacterSetCreator extends CharacterSetValidator {
357
366
  /**
358
367
  * Domains for every length for every supported {@link Exclusion}.
359
368
  */
360
- private readonly _exclusionDomains: ReadonlyArray<readonly bigint[] | undefined>;
369
+ private readonly _exclusionDomains: ReadonlyArray<readonly bigint[]>;
361
370
 
362
371
  /**
363
372
  * Values that would generate all zeros in the created string.
364
373
  */
365
- private readonly _allZerosValues: readonly bigint[] | undefined;
374
+ private readonly _allZerosValues: readonly bigint[];
366
375
 
367
376
  /**
368
377
  * Constructor.
@@ -380,12 +389,20 @@ export class CharacterSetCreator extends CharacterSetValidator {
380
389
  this._characterSetSizeN = BigInt(this.characterSetSize);
381
390
  this._characterSetSizeMinusOneN = BigInt(this.characterSetSize - 1);
382
391
 
392
+ const exclusionDomains: Array<readonly bigint[]> = [];
393
+
383
394
  const exclusionNoneDomains = CharacterSetCreator.createPowersOf(this.characterSetSize);
384
395
 
385
- let exclusionFirstZeroDomains: bigint[] | undefined;
396
+ exclusionDomains[Exclusion.None] = exclusionNoneDomains;
386
397
 
387
398
  if (exclusionSupport.includes(Exclusion.FirstZero)) {
388
- exclusionFirstZeroDomains = new Array<bigint>(CharacterSetCreator.MAXIMUM_STRING_LENGTH + 1);
399
+ if (characterSet[0] !== "0") {
400
+ throw new RangeError(i18next.t("CharacterSetValidator.firstZeroFirstCharacter", {
401
+ ns: utilityNS
402
+ }));
403
+ }
404
+
405
+ const exclusionFirstZeroDomains = new Array<bigint>(CharacterSetCreator.MAXIMUM_STRING_LENGTH + 1);
389
406
 
390
407
  // Exclusion of first zero mathematically prohibits length of 0.
391
408
  exclusionFirstZeroDomains[0] = 0n;
@@ -394,16 +411,30 @@ export class CharacterSetCreator extends CharacterSetValidator {
394
411
  // Domain excludes zero as the first character and so works with previous exclusion none domain.
395
412
  exclusionFirstZeroDomains[index] = this._characterSetSizeMinusOneN * exclusionNoneDomains[index - 1];
396
413
  }
397
- }
398
414
 
399
- let exclusionAllNumericDomains: bigint[] | undefined;
415
+ exclusionDomains[Exclusion.FirstZero] = exclusionFirstZeroDomains;
416
+ }
400
417
 
401
418
  if (exclusionSupport.includes(Exclusion.AllNumeric)) {
402
- exclusionAllNumericDomains = new Array<bigint>(CharacterSetCreator.MAXIMUM_STRING_LENGTH + 1);
419
+ const exclusionAllNumericDomains = new Array<bigint>(CharacterSetCreator.MAXIMUM_STRING_LENGTH + 1);
420
+
421
+ const numberIndexes = this.characterIndexes("0123456789");
422
+
423
+ let expectedNumberIndex = numberIndexes[0];
424
+
425
+ // Make sure that all numeric characters are present and in sequence.
426
+ for (const numberIndex of numberIndexes) {
427
+ if (numberIndex === undefined || numberIndex !== expectedNumberIndex) {
428
+ throw new RangeError(i18next.t("CharacterSetValidator.allNumericAllNumericCharacters", {
429
+ ns: utilityNS
430
+ }));
431
+ }
432
+
433
+ expectedNumberIndex = numberIndex + 1;
434
+ }
403
435
 
404
436
  // Zero index is the all-zero value for a single-character string.
405
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
406
- const zeroIndex = BigInt(this.characterIndex("0")!);
437
+ const zeroIndex = BigInt((numberIndexes as number[])[0]);
407
438
 
408
439
  const allZerosValues = new Array<bigint>(CharacterSetCreator.MAXIMUM_STRING_LENGTH + 1);
409
440
  let allZerosValue = 0n;
@@ -419,13 +450,14 @@ export class CharacterSetCreator extends CharacterSetValidator {
419
450
  }
420
451
 
421
452
  this._allZerosValues = allZerosValues;
453
+
454
+ exclusionDomains[Exclusion.AllNumeric] = exclusionAllNumericDomains;
455
+ } else {
456
+ // Empty array obviates need for non-null assertion while still forcing error if indexed due to a bug.
457
+ this._allZerosValues = [];
422
458
  }
423
459
 
424
- this._exclusionDomains = [
425
- exclusionNoneDomains,
426
- exclusionFirstZeroDomains,
427
- exclusionAllNumericDomains
428
- ];
460
+ this._exclusionDomains = exclusionDomains;
429
461
  }
430
462
 
431
463
  /**
@@ -438,8 +470,7 @@ export class CharacterSetCreator extends CharacterSetValidator {
438
470
  * `characterSetSize**power`.
439
471
  */
440
472
  private powerOfSize(power: number): bigint {
441
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
442
- return this._exclusionDomains[Exclusion.None]![power];
473
+ return this._exclusionDomains[Exclusion.None][power];
443
474
  }
444
475
 
445
476
  /**
@@ -493,7 +524,7 @@ export class CharacterSetCreator extends CharacterSetValidator {
493
524
  }
494
525
 
495
526
  /**
496
- * Validate that a length is less than or equal to {@link MAXIMUM_STRING_LENGTH}. If not, an exception is thrown.
527
+ * Validate that a length is less than or equal to {@link MAXIMUM_STRING_LENGTH}. If not, an error is thrown.
497
528
  *
498
529
  * @param length
499
530
  * Length.
@@ -584,16 +615,15 @@ export class CharacterSetCreator extends CharacterSetValidator {
584
615
  */
585
616
  create(length: number, valueOrValues: number | bigint | Iterable<number | bigint>, exclusion?: Exclusion, tweak?: number | bigint, creationCallback?: CreationCallback): string | IterableIterator<string>;
586
617
 
587
- // eslint-disable-next-line jsdoc/require-jsdoc
618
+ // eslint-disable-next-line jsdoc/require-jsdoc -- Implementation of overloaded signatures.
588
619
  create(length: number, valueOrValues: number | bigint | Iterable<number | bigint>, exclusion: Exclusion = Exclusion.None, tweak?: number | bigint, creationCallback?: CreationCallback): string | IterableIterator<string> {
589
620
  this.validateLength(length);
590
621
  this.validateExclusion(exclusion);
591
622
 
592
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
593
- const allZerosValue = exclusion === Exclusion.AllNumeric ? this._allZerosValues![length] : undefined;
623
+ // Zero value obviates need for non-null assertion.
624
+ const allZerosValue = exclusion === Exclusion.AllNumeric ? this._allZerosValues[length] : 0n;
594
625
 
595
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
596
- const transformer = Transformer.get(this._exclusionDomains[exclusion]![length], tweak);
626
+ const transformer = Transformer.get(this._exclusionDomains[exclusion][length], tweak);
597
627
 
598
628
  return transformer.forward(valueOrValues, (transformedValue, index) => {
599
629
  let s = "";
@@ -602,11 +632,9 @@ export class CharacterSetCreator extends CharacterSetValidator {
602
632
  if (length !== 0) {
603
633
  let convertValue = transformedValue;
604
634
 
605
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
606
- if (exclusion === Exclusion.AllNumeric && convertValue >= allZerosValue!) {
635
+ if (exclusion === Exclusion.AllNumeric && convertValue >= allZerosValue) {
607
636
  // Value to convert is shifted by the number of all-numeric strings that occur at or prior to it.
608
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
609
- convertValue = convertValue + this.allNumericShift(true, length, convertValue - allZerosValue!);
637
+ convertValue = convertValue + this.allNumericShift(true, length, convertValue - allZerosValue);
610
638
  }
611
639
 
612
640
  // Build string from right to left excluding the first character.
@@ -682,8 +710,7 @@ export class CharacterSetCreator extends CharacterSetValidator {
682
710
  }, 0n);
683
711
 
684
712
  if (exclusion === Exclusion.AllNumeric) {
685
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
686
- const allZerosValue = this._allZerosValues![length];
713
+ const allZerosValue = this._allZerosValues[length];
687
714
 
688
715
  if (value >= allZerosValue) {
689
716
  // Call will ensure that string is not all-numeric.
@@ -691,8 +718,7 @@ export class CharacterSetCreator extends CharacterSetValidator {
691
718
  }
692
719
  }
693
720
 
694
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
695
- return Transformer.get(this._exclusionDomains[exclusion]![length], tweak).reverse(value);
721
+ return Transformer.get(this._exclusionDomains[exclusion][length], tweak).reverse(value);
696
722
  }
697
723
  }
698
724
 
@@ -11,6 +11,8 @@ export const localeStrings = {
11
11
  stringDoesNotMatchPattern: "String {{s}} does not match pattern"
12
12
  },
13
13
  CharacterSetValidator: {
14
+ firstZeroFirstCharacter: "Character set must support zero as first character",
15
+ allNumericAllNumericCharacters: "Character set must support all numeric characters in sequence",
14
16
  stringMustNotBeAllNumeric: "String must not be all numeric",
15
17
  lengthMustBeGreaterThanOrEqualTo: "Length {{length}} must be greater than or equal to {{minimumLength}}",
16
18
  lengthMustBeLessThanOrEqualTo: "Length {{length}} must be less than or equal to {{maximumLength}}",
@@ -0,0 +1,32 @@
1
+ export const localeStrings = {
2
+ Transformer: {
3
+ domainMustBeGreaterThanZero: "Le domaine {{domain}} doit être supérieur à 0",
4
+ tweakMustBeGreaterThanOrEqualToZero: "Le réglage {{tweak}} doit être supérieur ou égal à 0",
5
+ valueMustBeGreaterThanOrEqualToZero: "La valeur {{value}} doit être supérieure ou égale à 0",
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}}"
9
+ },
10
+ RegExpValidator: {
11
+ stringDoesNotMatchPattern: "La chaîne {{s}} ne correspond pas au modèle"
12
+ },
13
+ CharacterSetValidator: {
14
+ firstZeroFirstCharacter: "Le jeu de caractères doit prendre en charge zéro comme premier caractère",
15
+ allNumericAllNumericCharacters: "Le jeu de caractères doit prendre en charge tous les caractères numériques en séquence",
16
+ stringMustNotBeAllNumeric: "La chaîne ne doit pas être entièrement numérique",
17
+ lengthMustBeGreaterThanOrEqualTo: "La longueur {{length}} doit être supérieure ou égale à {{minimumLength}}",
18
+ lengthMustBeLessThanOrEqualTo: "La longueur {{length}} doit être inférieure ou égale à {{maximumLength}}",
19
+ lengthMustBeEqualTo: "La longueur {{length}} doit être égale à {{exactLength}}",
20
+ lengthOfComponentMustBeGreaterThanOrEqualTo: "La longueur {{length}} de {{component}} doit être supérieure ou égale à {{minimumLength}}",
21
+ lengthOfComponentMustBeLessThanOrEqualTo: "La longueur {{length}} de {{component}} doit être inférieure ou égale à {{maximumLength}}",
22
+ lengthOfComponentMustBeEqualTo: "La longueur {{length}} de {{component}} doit être égale à {{exactLength}}",
23
+ invalidCharacterAtPosition: "Caractère non valide '{{c}}' à la position {{position}}",
24
+ invalidCharacterAtPositionOfComponent: "Caractère non valide '{{c}}' à la position {{position}} de {{component}}",
25
+ exclusionNotSupported: "La valeur d'exclusion de {{exclusion}} n'est pas prise en charge",
26
+ invalidTweakWithAllNumericExclusion: "Le réglage ne doit pas être utilisé avec une exclusion entièrement numérique",
27
+ endSequenceValueMustBeLessThanOrEqualTo: "La valeur de la séquence de fin (valeur de la séquence de début + nombre - 1) doit être inférieure à {{domaine}}"
28
+ },
29
+ RecordValidator: {
30
+ typeNameKeyNotFound: "{{typeName}} \"{{key}}\" introuvable"
31
+ }
32
+ } as const;
@@ -1,8 +1,12 @@
1
- import { i18nAddResourceBundle, i18next } from "@aidc-toolkit/core";
1
+ import { i18nAddResourceBundle, i18nAssertValidResources, i18next } from "@aidc-toolkit/core";
2
2
  import { localeStrings as enLocaleStrings } from "./en/locale_strings.js";
3
+ import { localeStrings as frLocaleStrings } from "./fr/locale_strings.js";
3
4
 
4
5
  export const utilityNS = "aidct_utility";
5
6
 
7
+ i18nAssertValidResources(enLocaleStrings, "fr", frLocaleStrings);
8
+
6
9
  i18nAddResourceBundle("en", utilityNS, enLocaleStrings);
10
+ i18nAddResourceBundle("fr", utilityNS, frLocaleStrings);
7
11
 
8
12
  export default i18next;
package/src/record.ts CHANGED
@@ -2,8 +2,8 @@ import i18next, { utilityNS } from "./locale/i18n.js";
2
2
  import type { StringValidator } from "./string.js";
3
3
 
4
4
  /**
5
- * Record validator. Validation is performed against a record with a string key type and throws an exception if the key
6
- * is not found.
5
+ * Record validator. Validation is performed against a record with a string key type and throws an error if the key is
6
+ * not found.
7
7
  */
8
8
  export class RecordValidator<T> implements StringValidator {
9
9
  /**
package/src/string.ts CHANGED
@@ -10,7 +10,7 @@ export interface StringValidation {
10
10
  */
11
11
  export interface StringValidator<V extends StringValidation = StringValidation> {
12
12
  /**
13
- * Validate a string and throw an exception if validation fails.
13
+ * Validate a string and throw an error if validation fails.
14
14
  *
15
15
  * @param s
16
16
  * String.
@@ -513,9 +513,7 @@ export class EncryptionTransformer extends Transformer {
513
513
  * Value.
514
514
  */
515
515
  private static bytesToValue(bytes: Uint8Array): bigint {
516
- return bytes.reduce((accumulator, byte) => {
517
- return accumulator << 8n | BigInt(byte);
518
- }, 0n);
516
+ return bytes.reduce((accumulator, byte) => accumulator << 8n | BigInt(byte), 0n);
519
517
  }
520
518
 
521
519
  /**
@@ -2,16 +2,16 @@ import { I18NEnvironment, i18nInit } from "@aidc-toolkit/core";
2
2
  import { describe, expect, test } from "vitest";
3
3
  import {
4
4
  ALPHABETIC_CREATOR,
5
- ALPHANUMERIC_CREATOR, Sequencer,
5
+ ALPHANUMERIC_CREATOR,
6
6
  CharacterSetCreator,
7
7
  Exclusion,
8
8
  HEXADECIMAL_CREATOR,
9
- NUMERIC_CREATOR
9
+ NUMERIC_CREATOR,
10
+ Sequencer
10
11
  } from "../src/index.js";
11
12
 
12
13
  await i18nInit(I18NEnvironment.CLI, true);
13
14
 
14
- // eslint-disable-next-line jsdoc/require-jsdoc
15
15
  function testCharacterSetCreator(name: string, characterSetCreator: CharacterSetCreator, characterSetSize: number, length: number, excludeFirstZero: boolean, excludeAllNumeric: boolean): void {
16
16
  describe(name, () => {
17
17
  test("Character set", () => {
@@ -45,7 +45,6 @@ function testCharacterSetCreator(name: string, characterSetCreator: CharacterSet
45
45
  expect(characterSetCreator.exclusionSupport.includes(Exclusion.AllNumeric)).toBe(excludeAllNumeric);
46
46
  });
47
47
 
48
- // eslint-disable-next-line jsdoc/require-jsdoc
49
48
  function testCreate(exclusion: Exclusion): void {
50
49
  let domain: number;
51
50
 
@@ -154,17 +153,41 @@ function testCharacterSetCreator(name: string, characterSetCreator: CharacterSet
154
153
  test("Create sequence, exclude all numeric", () => {
155
154
  testCreate(Exclusion.AllNumeric);
156
155
 
156
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- Nine is known to be present in the character set.
157
+ const afterNine = characterSetCreator.character(characterSetCreator.characterIndex("9")! + 1);
158
+
157
159
  expect(() => characterSetCreator.valueFor("0000", Exclusion.AllNumeric)).toThrow("String must not be all numeric");
158
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
159
- expect(() => characterSetCreator.valueFor("000" + characterSetCreator.character(characterSetCreator.characterIndex("9")! + 1), Exclusion.AllNumeric)).not.toThrow(RangeError);
160
+ expect(() => characterSetCreator.valueFor(`000${afterNine}`, Exclusion.AllNumeric)).not.toThrow(RangeError);
160
161
  expect(() => characterSetCreator.valueFor("9999", Exclusion.AllNumeric)).toThrow("String must not be all numeric");
161
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
162
- expect(() => characterSetCreator.valueFor("999" + characterSetCreator.character(characterSetCreator.characterIndex("9")! + 1), Exclusion.AllNumeric)).not.toThrow(RangeError);
162
+ expect(() => characterSetCreator.valueFor(`999${afterNine}`, Exclusion.AllNumeric)).not.toThrow(RangeError);
163
163
  });
164
164
  }
165
165
  });
166
166
  }
167
167
 
168
+ describe("Exclusion", () => {
169
+ test("First zero", () => {
170
+ expect(() => new CharacterSetCreator([
171
+ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
172
+ ], Exclusion.FirstZero)).not.toThrow(RangeError);
173
+ expect(() => new CharacterSetCreator([
174
+ "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"
175
+ ], Exclusion.FirstZero)).toThrow("Character set must support zero as first character");
176
+ });
177
+
178
+ test("All numeric", () => {
179
+ expect(() => new CharacterSetCreator([
180
+ "!", "#", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D"
181
+ ], Exclusion.AllNumeric)).not.toThrow(RangeError);
182
+ expect(() => new CharacterSetCreator([
183
+ "!", "#", "/", "0", "1", "2", "3", "A", "B", "C", "D"
184
+ ], Exclusion.AllNumeric)).toThrow("Character set must support all numeric characters in sequence");
185
+ expect(() => new CharacterSetCreator([
186
+ "!", "#", "/", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "A", "B", "C", "D"
187
+ ], Exclusion.AllNumeric)).toThrow("Character set must support all numeric characters in sequence");
188
+ });
189
+ });
190
+
168
191
  testCharacterSetCreator("Numeric", NUMERIC_CREATOR, 10, 4, true, false);
169
192
  testCharacterSetCreator("Hexadecimal", HEXADECIMAL_CREATOR, 16, 4, true, true);
170
193
  testCharacterSetCreator("Alphabetic", ALPHABETIC_CREATOR, 26, 3, false, false);
@@ -5,7 +5,6 @@ import { RecordValidator } from "../src/index.js";
5
5
  await i18nInit(I18NEnvironment.CLI, true);
6
6
 
7
7
  describe("Record validator", () => {
8
- // eslint-disable-next-line jsdoc/require-jsdoc
9
8
  enum StringEnum {
10
9
  ValueA = "A",
11
10
  ValueB = "B",
@@ -34,7 +34,6 @@ describe("Regular expression validator", () => {
34
34
  test("Error message", () => {
35
35
  expect(() => {
36
36
  new class extends RegExpValidator {
37
- // eslint-disable-next-line jsdoc/require-jsdoc
38
37
  protected override createErrorMessage(s: string): string {
39
38
  return `Failed to validate "${s}"`;
40
39
  }
@@ -1,10 +1,9 @@
1
1
  import { I18NEnvironment, i18nInit } from "@aidc-toolkit/core";
2
2
  import { describe, expect, test } from "vitest";
3
- import { Sequencer, EncryptionTransformer, IdentityTransformer, Transformer } from "../src/index.js";
3
+ import { EncryptionTransformer, IdentityTransformer, Sequencer, Transformer } from "../src/index.js";
4
4
 
5
5
  await i18nInit(I18NEnvironment.CLI, true);
6
6
 
7
- // eslint-disable-next-line jsdoc/require-jsdoc
8
7
  function testTransformer(domain: number, tweak?: number, callback?: (value: bigint, forwardValue: bigint) => void): void {
9
8
  const transformer = Transformer.get(domain, tweak);
10
9
 
@@ -120,13 +119,9 @@ describe("Encryption", () => {
120
119
  });
121
120
 
122
121
  test("Byte boundary", () => {
123
- // eslint-disable-next-line @typescript-eslint/dot-notation
124
122
  expect((Transformer.get(256n, 1n) as EncryptionTransformer)["_domainBytes"]).toBe(1);
125
- // eslint-disable-next-line @typescript-eslint/dot-notation
126
123
  expect((Transformer.get(257n, 1n) as EncryptionTransformer)["_domainBytes"]).toBe(2);
127
- // eslint-disable-next-line @typescript-eslint/dot-notation
128
124
  expect((Transformer.get(65536n, 1n) as EncryptionTransformer)["_domainBytes"]).toBe(2);
129
- // eslint-disable-next-line @typescript-eslint/dot-notation
130
125
  expect((Transformer.get(65537n, 1n) as EncryptionTransformer)["_domainBytes"]).toBe(3);
131
126
 
132
127
  testTransformer(256, 1);