@aidc-toolkit/utility 0.9.3 → 0.9.5

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/dist/index.cjs ADDED
@@ -0,0 +1,1714 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ ALPHABETIC_CREATOR: () => ALPHABETIC_CREATOR,
24
+ ALPHANUMERIC_CREATOR: () => ALPHANUMERIC_CREATOR,
25
+ CharacterSetCreator: () => CharacterSetCreator,
26
+ CharacterSetValidator: () => CharacterSetValidator,
27
+ EncryptionTransformer: () => EncryptionTransformer,
28
+ Exclusion: () => Exclusion,
29
+ HEXADECIMAL_CREATOR: () => HEXADECIMAL_CREATOR,
30
+ IdentityTransformer: () => IdentityTransformer,
31
+ IteratorProxy: () => IteratorProxy,
32
+ NUMERIC_CREATOR: () => NUMERIC_CREATOR,
33
+ RecordValidator: () => RecordValidator,
34
+ RegExpValidator: () => RegExpValidator,
35
+ Sequencer: () => Sequencer,
36
+ Transformer: () => Transformer
37
+ });
38
+ module.exports = __toCommonJS(src_exports);
39
+
40
+ // src/iterator_proxy.ts
41
+ var IteratorProxyBase = class _IteratorProxyBase {
42
+ /**
43
+ * Convert an iteration source to an iterable.
44
+ *
45
+ * @param iterationSource
46
+ * Iteration source.
47
+ *
48
+ * @returns
49
+ * Iteration source if it is already an iterable, otherwise iteration source wrapped in an iterable.
50
+ */
51
+ static toIterable(iterationSource) {
52
+ return Symbol.iterator in iterationSource ? iterationSource : {
53
+ [Symbol.iterator]() {
54
+ return iterationSource;
55
+ }
56
+ };
57
+ }
58
+ /**
59
+ * Initial iterable.
60
+ */
61
+ _initialIterable;
62
+ /**
63
+ * Initial iterator.
64
+ */
65
+ _initialIterator;
66
+ /**
67
+ * Constructor.
68
+ *
69
+ * @param initialIterationSource
70
+ * Initial iteration source.
71
+ */
72
+ constructor(initialIterationSource) {
73
+ this._initialIterable = _IteratorProxyBase.toIterable(initialIterationSource);
74
+ }
75
+ /**
76
+ * Get the initial iterable.
77
+ */
78
+ get initialIterable() {
79
+ return this._initialIterable;
80
+ }
81
+ /**
82
+ * Get the initial iterator.
83
+ */
84
+ get initialIterator() {
85
+ if (this._initialIterator === void 0) {
86
+ this._initialIterator = this.initialIterable[Symbol.iterator]();
87
+ }
88
+ return this._initialIterator;
89
+ }
90
+ /**
91
+ * @inheritDoc
92
+ */
93
+ get [Symbol.toStringTag]() {
94
+ return "IteratorProxy";
95
+ }
96
+ /**
97
+ * @inheritDoc
98
+ */
99
+ [Symbol.dispose]() {
100
+ }
101
+ /**
102
+ * @inheritDoc
103
+ */
104
+ [Symbol.iterator]() {
105
+ return this;
106
+ }
107
+ /**
108
+ * Get the next result from the initial iterator.
109
+ *
110
+ * @param value
111
+ * Tuple value to be passed to Iterator.next().
112
+ *
113
+ * @returns
114
+ * Next result from the initial iterator.
115
+ */
116
+ initialNext(...value) {
117
+ return this.initialIterator.next(...value);
118
+ }
119
+ /**
120
+ * @inheritDoc
121
+ */
122
+ map(callback) {
123
+ return new IteratorMapProxy(this, callback);
124
+ }
125
+ /**
126
+ * @inheritDoc
127
+ */
128
+ flatMap(callback) {
129
+ return new IteratorFlatMapProxy(this, callback);
130
+ }
131
+ /**
132
+ * @inheritDoc
133
+ */
134
+ filter(predicate) {
135
+ return new IteratorFilterProxy(this, predicate, true);
136
+ }
137
+ /**
138
+ * @inheritDoc
139
+ */
140
+ take(limit) {
141
+ return new IteratorTakeProxy(this, limit);
142
+ }
143
+ /**
144
+ * @inheritDoc
145
+ */
146
+ drop(count) {
147
+ return new IteratorDropProxy(this, count);
148
+ }
149
+ /**
150
+ * @inheritDoc
151
+ */
152
+ reduce(callback, initialValue) {
153
+ let index = 0;
154
+ let result = initialValue;
155
+ for (const value of this) {
156
+ if (index === 0 && arguments.length === 1) {
157
+ result = value;
158
+ } else {
159
+ result = callback(result, value, index);
160
+ }
161
+ index++;
162
+ }
163
+ if (index === 0 && arguments.length === 1) {
164
+ throw new Error("reduce() of empty iterator with no initial value");
165
+ }
166
+ return result;
167
+ }
168
+ /**
169
+ * @inheritDoc
170
+ */
171
+ toArray() {
172
+ return Array.from(this);
173
+ }
174
+ /**
175
+ * @inheritDoc
176
+ */
177
+ forEach(callback) {
178
+ let index = 0;
179
+ for (const element of this) {
180
+ callback(element, index++);
181
+ }
182
+ }
183
+ /**
184
+ * @inheritDoc
185
+ */
186
+ some(predicate) {
187
+ return new IteratorFilterProxy(this, predicate, true).next().done !== true;
188
+ }
189
+ /**
190
+ * @inheritDoc
191
+ */
192
+ every(predicate) {
193
+ return new IteratorFilterProxy(this, predicate, false).next().done === true;
194
+ }
195
+ /**
196
+ * @inheritDoc
197
+ */
198
+ find(predicate) {
199
+ return new IteratorFilterProxy(this, predicate, true).next().value;
200
+ }
201
+ };
202
+ var IteratorProxyObject = class extends IteratorProxyBase {
203
+ /**
204
+ * @inheritDoc
205
+ */
206
+ next(...value) {
207
+ return this.initialNext(...value);
208
+ }
209
+ };
210
+ var IteratorMapProxyBase = class extends IteratorProxyBase {
211
+ /**
212
+ * Callback.
213
+ */
214
+ _callback;
215
+ /**
216
+ * Index into initial iteration source.
217
+ */
218
+ _index;
219
+ /**
220
+ * Constructor.
221
+ *
222
+ * @param initialIterationSource
223
+ * Initial iteration source.
224
+ *
225
+ * @param callback
226
+ * Callback.
227
+ */
228
+ constructor(initialIterationSource, callback) {
229
+ super(initialIterationSource);
230
+ this._callback = callback;
231
+ this._index = 0;
232
+ }
233
+ /**
234
+ * Get the next result from the intermediate iterator.
235
+ *
236
+ * @param value
237
+ * Tuple value to be passed to Iterator.next().
238
+ *
239
+ * @returns
240
+ * Next result from the intermediate iterator.
241
+ */
242
+ intermediateNext(...value) {
243
+ const initialResult = this.initialNext(...value);
244
+ return initialResult.done !== true ? {
245
+ value: this._callback(initialResult.value, this._index++)
246
+ } : {
247
+ done: true,
248
+ value: void 0
249
+ };
250
+ }
251
+ };
252
+ var IteratorMapProxy = class extends IteratorMapProxyBase {
253
+ /**
254
+ * @inheritDoc
255
+ */
256
+ next(...value) {
257
+ return this.intermediateNext(...value);
258
+ }
259
+ };
260
+ var IteratorFlatMapProxy = class extends IteratorMapProxyBase {
261
+ _intermediateIterator;
262
+ /**
263
+ * @inheritDoc
264
+ */
265
+ next(...value) {
266
+ let finalResult = void 0;
267
+ do {
268
+ if (this._intermediateIterator === void 0) {
269
+ const intermediateResult = this.intermediateNext(...value);
270
+ if (intermediateResult.done === true) {
271
+ finalResult = intermediateResult;
272
+ } else {
273
+ this._intermediateIterator = IteratorProxyBase.toIterable(intermediateResult.value)[Symbol.iterator]();
274
+ }
275
+ } else {
276
+ const pendingFinalResult = this._intermediateIterator.next();
277
+ if (pendingFinalResult.done === true) {
278
+ this._intermediateIterator = void 0;
279
+ } else {
280
+ finalResult = pendingFinalResult;
281
+ }
282
+ }
283
+ } while (finalResult === void 0);
284
+ return finalResult;
285
+ }
286
+ };
287
+ var IteratorFilterProxy = class extends IteratorProxyBase {
288
+ /**
289
+ * Predicate.
290
+ */
291
+ _predicate;
292
+ /**
293
+ * Expected truthy result of the predicate.
294
+ */
295
+ _expectedTruthy;
296
+ /**
297
+ * Index into iteration source.
298
+ */
299
+ _index;
300
+ /**
301
+ * Constructor.
302
+ *
303
+ * @param iterationSource
304
+ * Iteration source.
305
+ *
306
+ * @param predicate
307
+ * Predicate.
308
+ *
309
+ * @param expectedTruthy
310
+ * Expected truthy result of the predicate.
311
+ */
312
+ constructor(iterationSource, predicate, expectedTruthy) {
313
+ super(iterationSource);
314
+ this._predicate = predicate;
315
+ this._expectedTruthy = expectedTruthy;
316
+ this._index = 0;
317
+ }
318
+ /**
319
+ * @inheritDoc
320
+ */
321
+ next(...value) {
322
+ let result;
323
+ const expectedTruthy = this._expectedTruthy;
324
+ do {
325
+ result = this.initialNext(...value);
326
+ } while (result.done !== true && Boolean(this._predicate(result.value, this._index++)) !== expectedTruthy);
327
+ return result;
328
+ }
329
+ };
330
+ var IteratorCountProxyBase = class extends IteratorProxyObject {
331
+ /**
332
+ * Count.
333
+ */
334
+ _count;
335
+ /**
336
+ * Constructor.
337
+ *
338
+ * @param initialIterationSource
339
+ * Initial iteration source.
340
+ *
341
+ * @param count
342
+ * Count.
343
+ */
344
+ constructor(initialIterationSource, count) {
345
+ super(initialIterationSource);
346
+ if (!Number.isInteger(count) || count < 0) {
347
+ throw new RangeError("Count must be a positive integer");
348
+ }
349
+ this._count = count;
350
+ }
351
+ /**
352
+ * Determine if iterator is exhausted (by count or by iterator itself).
353
+ */
354
+ get exhausted() {
355
+ return this._count <= 0;
356
+ }
357
+ /**
358
+ * @inheritDoc
359
+ */
360
+ next(...value) {
361
+ const result = super.next(...value);
362
+ if (result.done !== true) {
363
+ this._count--;
364
+ } else {
365
+ this._count = 0;
366
+ }
367
+ return result;
368
+ }
369
+ };
370
+ var IteratorTakeProxy = class extends IteratorCountProxyBase {
371
+ /**
372
+ * @inheritDoc
373
+ */
374
+ next(...value) {
375
+ return !this.exhausted ? super.next(...value) : {
376
+ done: true,
377
+ value: void 0
378
+ };
379
+ }
380
+ };
381
+ var IteratorDropProxy = class extends IteratorCountProxyBase {
382
+ /**
383
+ * @inheritDoc
384
+ */
385
+ next(...value) {
386
+ while (!this.exhausted) {
387
+ super.next(...value);
388
+ }
389
+ return super.next(...value);
390
+ }
391
+ };
392
+ function iteratorProxy() {
393
+ let supported;
394
+ try {
395
+ supported = process.env["NODE_ENV"] !== "test";
396
+ } catch (_e) {
397
+ supported = true;
398
+ }
399
+ if (supported) {
400
+ try {
401
+ Iterator.from([]);
402
+ } catch (_e) {
403
+ supported = false;
404
+ }
405
+ }
406
+ return supported ? Iterator : {
407
+ /**
408
+ * @inheritDoc
409
+ */
410
+ from(value) {
411
+ return value instanceof IteratorProxyBase ? value : new IteratorProxyObject(value);
412
+ }
413
+ };
414
+ }
415
+ var IteratorProxy = iteratorProxy();
416
+
417
+ // src/sequencer.ts
418
+ var Sequencer = class {
419
+ /**
420
+ * Start value (inclusive).
421
+ */
422
+ _startValue;
423
+ /**
424
+ * End value (exclusive).
425
+ */
426
+ _endValue;
427
+ /**
428
+ * Count of values.
429
+ */
430
+ _count;
431
+ /**
432
+ * Delta to the next value; equal to the sign of the count.
433
+ */
434
+ _nextDelta;
435
+ /**
436
+ * Minimum value (inclusive).
437
+ */
438
+ _minValue;
439
+ /**
440
+ * Maximum value (inclusive).
441
+ */
442
+ _maxValue;
443
+ /**
444
+ * Next value.
445
+ */
446
+ _nextValue;
447
+ /**
448
+ * Constructor.
449
+ *
450
+ * @param startValue
451
+ * Start value.
452
+ *
453
+ * @param count
454
+ * Count of values. If count is zero or positive, iteration ascends from start value, otherwise it descends from
455
+ * start value.
456
+ */
457
+ constructor(startValue, count) {
458
+ this._startValue = BigInt(startValue);
459
+ this._endValue = this._startValue + BigInt(count);
460
+ this._count = count;
461
+ const ascending = count >= 0;
462
+ if (ascending) {
463
+ this._nextDelta = 1n;
464
+ this._minValue = this._startValue;
465
+ this._maxValue = this._endValue - 1n;
466
+ } else {
467
+ this._nextDelta = -1n;
468
+ this._minValue = this._endValue + 1n;
469
+ this._maxValue = this._startValue;
470
+ }
471
+ this._nextValue = this._startValue;
472
+ }
473
+ /**
474
+ * Get the start value (inclusive).
475
+ */
476
+ get startValue() {
477
+ return this._startValue;
478
+ }
479
+ /**
480
+ * Get the end value (exclusive).
481
+ */
482
+ get endValue() {
483
+ return this._endValue;
484
+ }
485
+ /**
486
+ * Get the count of values.
487
+ */
488
+ get count() {
489
+ return this._count;
490
+ }
491
+ /**
492
+ * Get the minimum value (inclusive).
493
+ */
494
+ get minValue() {
495
+ return this._minValue;
496
+ }
497
+ /**
498
+ * Get the maximum value (inclusive).
499
+ */
500
+ get maxValue() {
501
+ return this._maxValue;
502
+ }
503
+ /**
504
+ * Iterable implementation.
505
+ *
506
+ * @returns
507
+ * this
508
+ */
509
+ [Symbol.iterator]() {
510
+ return this;
511
+ }
512
+ /**
513
+ * Iterator implementation.
514
+ *
515
+ * @returns
516
+ * Iterator result. If iterator is exhausted, the value is absolute value of the count.
517
+ */
518
+ next() {
519
+ const done = this._nextValue === this._endValue;
520
+ let result;
521
+ if (!done) {
522
+ result = {
523
+ value: this._nextValue
524
+ };
525
+ this._nextValue += this._nextDelta;
526
+ } else {
527
+ result = {
528
+ done: true,
529
+ value: Math.abs(this._count)
530
+ };
531
+ }
532
+ return result;
533
+ }
534
+ /**
535
+ * Reset the iterator.
536
+ */
537
+ reset() {
538
+ this._nextValue = this._startValue;
539
+ }
540
+ };
541
+
542
+ // src/locale/i18n.ts
543
+ var import_core = require("@aidc-toolkit/core");
544
+
545
+ // src/locale/en/locale_strings.ts
546
+ var localeStrings = {
547
+ Transformer: {
548
+ domainMustBeGreaterThanZero: "Domain {{domain}} must be greater than 0",
549
+ tweakMustBeGreaterThanOrEqualToZero: "Tweak {{tweak}} must be greater than or equal to 0",
550
+ valueMustBeGreaterThanOrEqualToZero: "Value {{value}} must be greater than or equal to 0",
551
+ valueMustBeLessThan: "Value {{value}} must be less than {{domain}}",
552
+ minValueMustBeGreaterThanOrEqualToZero: "Minimum value {{minValue}} must be greater than or equal to 0",
553
+ maxValueMustBeLessThan: "Maximum value {{maxValue}} must be less than {{domain}}"
554
+ },
555
+ RegExpValidator: {
556
+ stringDoesNotMatchPattern: "String {{s}} does not match pattern"
557
+ },
558
+ CharacterSetValidator: {
559
+ firstZeroFirstCharacter: "Character set must support zero as first character",
560
+ allNumericAllNumericCharacters: "Character set must support all numeric characters in sequence",
561
+ stringMustNotBeAllNumeric: "String must not be all numeric",
562
+ lengthMustBeGreaterThanOrEqualTo: "Length {{length}} must be greater than or equal to {{minimumLength}}",
563
+ lengthMustBeLessThanOrEqualTo: "Length {{length}} must be less than or equal to {{maximumLength}}",
564
+ lengthMustBeEqualTo: "Length {{length}} must be equal to {{exactLength}}",
565
+ lengthOfComponentMustBeGreaterThanOrEqualTo: "Length {{length}} of {{component}} must be greater than or equal to {{minimumLength}}",
566
+ lengthOfComponentMustBeLessThanOrEqualTo: "Length {{length}} of {{component}} must be less than or equal to {{maximumLength}}",
567
+ lengthOfComponentMustBeEqualTo: "Length {{length}} of {{component}} must be equal to {{exactLength}}",
568
+ invalidCharacterAtPosition: "Invalid character '{{c}}' at position {{position}}",
569
+ invalidCharacterAtPositionOfComponent: "Invalid character '{{c}}' at position {{position}} of {{component}}",
570
+ exclusionNotSupported: "Exclusion value of {{exclusion}} is not supported",
571
+ invalidTweakWithAllNumericExclusion: "Tweak must not be used with all-numeric exclusion",
572
+ endSequenceValueMustBeLessThanOrEqualTo: "End sequence value (start sequence value + count - 1) must be less than {{domain}}"
573
+ },
574
+ RecordValidator: {
575
+ typeNameKeyNotFound: '{{typeName}} "{{key}}" not found'
576
+ }
577
+ };
578
+
579
+ // src/locale/fr/locale_strings.ts
580
+ var localeStrings2 = {
581
+ Transformer: {
582
+ domainMustBeGreaterThanZero: "Le domaine {{domain}} doit \xEAtre sup\xE9rieur \xE0 0",
583
+ tweakMustBeGreaterThanOrEqualToZero: "Le r\xE9glage {{tweak}} doit \xEAtre sup\xE9rieur ou \xE9gal \xE0 0",
584
+ valueMustBeGreaterThanOrEqualToZero: "La valeur {{value}} doit \xEAtre sup\xE9rieure ou \xE9gale \xE0 0",
585
+ valueMustBeLessThan: "La valeur {{value}} doit \xEAtre inf\xE9rieure \xE0 {{domain}}",
586
+ minValueMustBeGreaterThanOrEqualToZero: "La valeur minimale {{minValue}} doit \xEAtre sup\xE9rieure ou \xE9gale \xE0 0",
587
+ maxValueMustBeLessThan: "La valeur maximale {{maxValue}} doit \xEAtre inf\xE9rieure \xE0 {{domain}}"
588
+ },
589
+ RegExpValidator: {
590
+ stringDoesNotMatchPattern: "La cha\xEEne {{s}} ne correspond pas au mod\xE8le"
591
+ },
592
+ CharacterSetValidator: {
593
+ firstZeroFirstCharacter: "Le jeu de caract\xE8res doit prendre en charge z\xE9ro comme premier caract\xE8re",
594
+ allNumericAllNumericCharacters: "Le jeu de caract\xE8res doit prendre en charge tous les caract\xE8res num\xE9riques en s\xE9quence",
595
+ stringMustNotBeAllNumeric: "La cha\xEEne ne doit pas \xEAtre enti\xE8rement num\xE9rique",
596
+ lengthMustBeGreaterThanOrEqualTo: "La longueur {{length}} doit \xEAtre sup\xE9rieure ou \xE9gale \xE0 {{minimumLength}}",
597
+ lengthMustBeLessThanOrEqualTo: "La longueur {{length}} doit \xEAtre inf\xE9rieure ou \xE9gale \xE0 {{maximumLength}}",
598
+ lengthMustBeEqualTo: "La longueur {{length}} doit \xEAtre \xE9gale \xE0 {{exactLength}}",
599
+ lengthOfComponentMustBeGreaterThanOrEqualTo: "La longueur {{length}} de {{component}} doit \xEAtre sup\xE9rieure ou \xE9gale \xE0 {{minimumLength}}",
600
+ lengthOfComponentMustBeLessThanOrEqualTo: "La longueur {{length}} de {{component}} doit \xEAtre inf\xE9rieure ou \xE9gale \xE0 {{maximumLength}}",
601
+ lengthOfComponentMustBeEqualTo: "La longueur {{length}} de {{component}} doit \xEAtre \xE9gale \xE0 {{exactLength}}",
602
+ invalidCharacterAtPosition: "Caract\xE8re non valide '{{c}}' \xE0 la position {{position}}",
603
+ invalidCharacterAtPositionOfComponent: "Caract\xE8re non valide '{{c}}' \xE0 la position {{position}} de {{component}}",
604
+ exclusionNotSupported: "La valeur d'exclusion de {{exclusion}} n'est pas prise en charge",
605
+ invalidTweakWithAllNumericExclusion: "Le r\xE9glage ne doit pas \xEAtre utilis\xE9 avec une exclusion enti\xE8rement num\xE9rique",
606
+ endSequenceValueMustBeLessThanOrEqualTo: "La valeur de la s\xE9quence de fin (valeur de la s\xE9quence de d\xE9but + nombre - 1) doit \xEAtre inf\xE9rieure \xE0 {{domaine}}"
607
+ },
608
+ RecordValidator: {
609
+ typeNameKeyNotFound: '{{typeName}} "{{key}}" introuvable'
610
+ }
611
+ };
612
+
613
+ // src/locale/i18n.ts
614
+ var utilityNS = "aidct_utility";
615
+ (0, import_core.i18nAssertValidResources)(localeStrings, "fr", localeStrings2);
616
+ (0, import_core.i18nAddResourceBundle)("en", utilityNS, localeStrings);
617
+ (0, import_core.i18nAddResourceBundle)("fr", utilityNS, localeStrings2);
618
+ var i18n_default = import_core.i18next;
619
+
620
+ // src/transformer.ts
621
+ var Transformer = class _Transformer {
622
+ /**
623
+ * Transformers cache, mapping a domain to another map, which maps an optional tweak to a transformer.
624
+ */
625
+ static TRANSFORMER_MAPS_MAP = /* @__PURE__ */ new Map();
626
+ /**
627
+ * Domain.
628
+ */
629
+ _domain;
630
+ /**
631
+ * Constructor.
632
+ *
633
+ * @param domain
634
+ * Domain.
635
+ */
636
+ constructor(domain) {
637
+ this._domain = BigInt(domain);
638
+ if (this._domain <= 0n) {
639
+ throw new RangeError(i18n_default.t("Transformer.domainMustBeGreaterThanZero", {
640
+ ns: utilityNS,
641
+ domain
642
+ }));
643
+ }
644
+ }
645
+ /**
646
+ * Get a transformer, constructing it if necessary. The type returned is {@link IdentityTransformer} if tweak is
647
+ * undefined, {@link EncryptionTransformer} if tweak is defined. Note that although an {@link EncryptionTransformer}
648
+ * with a zero tweak operates as an {@link IdentityTransformer}, {@link EncryptionTransformer} is still the type
649
+ * returned if a zero tweak is explicitly specified.
650
+ *
651
+ * @param domain
652
+ * Domain.
653
+ *
654
+ * @param tweak
655
+ * Tweak.
656
+ *
657
+ * @returns
658
+ * {@link IdentityTransformer} if tweak is undefined, {@link EncryptionTransformer} if tweak is defined.
659
+ */
660
+ static get(domain, tweak) {
661
+ const domainN = BigInt(domain);
662
+ let transformersMap = _Transformer.TRANSFORMER_MAPS_MAP.get(domainN);
663
+ if (transformersMap === void 0) {
664
+ transformersMap = /* @__PURE__ */ new Map();
665
+ _Transformer.TRANSFORMER_MAPS_MAP.set(domainN, transformersMap);
666
+ }
667
+ const tweakN = tweak === void 0 ? void 0 : BigInt(tweak);
668
+ let transformer = transformersMap.get(tweakN);
669
+ if (transformer === void 0) {
670
+ transformer = tweakN === void 0 ? new IdentityTransformer(domainN) : new EncryptionTransformer(domainN, tweakN);
671
+ transformersMap.set(tweakN, transformer);
672
+ }
673
+ return transformer;
674
+ }
675
+ /**
676
+ * Get the domain.
677
+ */
678
+ get domain() {
679
+ return this._domain;
680
+ }
681
+ /**
682
+ * Validate that a value is within the domain.
683
+ *
684
+ * @param value
685
+ * Value.
686
+ */
687
+ validate(value) {
688
+ if (value < 0n) {
689
+ throw new RangeError(i18n_default.t("Transformer.valueMustBeGreaterThanOrEqualToZero", {
690
+ ns: utilityNS,
691
+ value
692
+ }));
693
+ }
694
+ if (value >= this.domain) {
695
+ throw new RangeError(i18n_default.t("Transformer.valueMustBeLessThan", {
696
+ ns: utilityNS,
697
+ value,
698
+ domain: this.domain
699
+ }));
700
+ }
701
+ }
702
+ /**
703
+ * Transform a value or values forward.
704
+ *
705
+ * @template T
706
+ * Type returned by transformation callback.
707
+ *
708
+ * @param valueOrValues
709
+ * Value(s).
710
+ *
711
+ * @param transformationCallback
712
+ * Called after value(s) is/are transformed to convert it/them to its/their final value(s).
713
+ *
714
+ * @returns
715
+ * Value(s) transformed into object(s).
716
+ */
717
+ forward(valueOrValues, transformationCallback) {
718
+ let result;
719
+ if (typeof valueOrValues !== "object") {
720
+ const valueN = BigInt(valueOrValues);
721
+ this.validate(valueN);
722
+ const transformedValue = this.doForward(valueN);
723
+ result = transformationCallback === void 0 ? transformedValue : transformationCallback(transformedValue, 0);
724
+ } else if (valueOrValues instanceof Sequencer) {
725
+ if (valueOrValues.minValue < 0n) {
726
+ throw new RangeError(i18n_default.t("Transformer.minValueMustBeGreaterThanOrEqualToZero", {
727
+ ns: utilityNS,
728
+ minValue: valueOrValues.minValue
729
+ }));
730
+ }
731
+ if (valueOrValues.maxValue >= this.domain) {
732
+ throw new RangeError(i18n_default.t("Transformer.maxValueMustBeLessThan", {
733
+ ns: utilityNS,
734
+ maxValue: valueOrValues.maxValue,
735
+ domain: this.domain
736
+ }));
737
+ }
738
+ result = transformationCallback === void 0 ? IteratorProxy.from(valueOrValues).map((value) => this.doForward(value)) : IteratorProxy.from(valueOrValues).map((value, index) => transformationCallback(this.doForward(value), index));
739
+ } else {
740
+ result = transformationCallback === void 0 ? IteratorProxy.from(valueOrValues).map((value) => {
741
+ const valueN = BigInt(value);
742
+ this.validate(valueN);
743
+ return this.doForward(valueN);
744
+ }) : IteratorProxy.from(valueOrValues).map((value, index) => {
745
+ const valueN = BigInt(value);
746
+ this.validate(valueN);
747
+ return transformationCallback(this.doForward(valueN), index);
748
+ });
749
+ }
750
+ return result;
751
+ }
752
+ /**
753
+ * Transform a value in reverse.
754
+ *
755
+ * @param transformedValue
756
+ * Transformed value.
757
+ *
758
+ * @returns
759
+ * Value.
760
+ */
761
+ reverse(transformedValue) {
762
+ const transformedValueN = BigInt(transformedValue);
763
+ this.validate(transformedValueN);
764
+ return this.doReverse(transformedValueN);
765
+ }
766
+ };
767
+ var IdentityTransformer = class extends Transformer {
768
+ /**
769
+ * @inheritDoc
770
+ */
771
+ doForward(value) {
772
+ return value;
773
+ }
774
+ /**
775
+ * @inheritDoc
776
+ */
777
+ doReverse(transformedValue) {
778
+ return transformedValue;
779
+ }
780
+ };
781
+ var EncryptionTransformer = class _EncryptionTransformer extends Transformer {
782
+ /**
783
+ * Individual bits, pre-calculated for performance.
784
+ */
785
+ static BITS = new Uint8Array([
786
+ 1,
787
+ 2,
788
+ 4,
789
+ 8,
790
+ 16,
791
+ 32,
792
+ 64,
793
+ 128
794
+ ]);
795
+ /**
796
+ * Inverse individual bits, pre-calculated for performance.
797
+ */
798
+ static INVERSE_BITS = new Uint8Array([
799
+ 254,
800
+ 253,
801
+ 251,
802
+ 247,
803
+ 239,
804
+ 223,
805
+ 191,
806
+ 127
807
+ ]);
808
+ /**
809
+ * Number of bytes covered by the domain.
810
+ */
811
+ _domainBytes;
812
+ /**
813
+ * Tweak.
814
+ */
815
+ _tweak;
816
+ /**
817
+ * Xor bytes array generated from the domain and tweak.
818
+ */
819
+ _xorBytes;
820
+ /**
821
+ * Bits array generated from the domain and tweak.
822
+ */
823
+ _bits;
824
+ /**
825
+ * Inverse bits array generated from the domain and tweak.
826
+ */
827
+ _inverseBits;
828
+ /**
829
+ * Number of rounds (length of arrays) generated from the domain and tweak.
830
+ */
831
+ _rounds;
832
+ /**
833
+ * Constructor.
834
+ *
835
+ * @param domain
836
+ * Domain.
837
+ *
838
+ * @param tweak
839
+ * Tweak.
840
+ */
841
+ constructor(domain, tweak) {
842
+ super(domain);
843
+ if (tweak < 0n) {
844
+ throw new RangeError(i18n_default.t("Transformer.tweakMustBeGreaterThanOrEqualToZero", {
845
+ ns: utilityNS,
846
+ tweak
847
+ }));
848
+ }
849
+ let domainBytes = 0;
850
+ for (let reducedDomainMinusOne = this.domain - 1n; reducedDomainMinusOne !== 0n; reducedDomainMinusOne = reducedDomainMinusOne >> 8n) {
851
+ domainBytes++;
852
+ }
853
+ this._domainBytes = domainBytes;
854
+ this._tweak = BigInt(tweak);
855
+ const xorBytes = new Array();
856
+ const bits = new Array();
857
+ const inverseBits = new Array();
858
+ for (let reducedKey = this.domain * this.tweak * 603868999n; reducedKey !== 0n; reducedKey = reducedKey >> 8n) {
859
+ const keyByte = Number(reducedKey & 0xFFn);
860
+ xorBytes.unshift(keyByte);
861
+ const bitNumber = keyByte & 7;
862
+ bits.push(_EncryptionTransformer.BITS[bitNumber]);
863
+ inverseBits.push(_EncryptionTransformer.INVERSE_BITS[bitNumber]);
864
+ }
865
+ if (domainBytes === 1) {
866
+ const domainMask = _EncryptionTransformer.BITS.filter((bit) => bit < domain).reduce((accumulator, bit) => accumulator | bit, 0);
867
+ this._xorBytes = new Uint8Array([xorBytes.reduce((accumulator, xorByte) => accumulator ^ xorByte, 0) & domainMask]);
868
+ this._bits = new Uint8Array([_EncryptionTransformer.BITS[0]]);
869
+ this._inverseBits = new Uint8Array([_EncryptionTransformer.INVERSE_BITS[0]]);
870
+ this._rounds = 1;
871
+ } else {
872
+ this._xorBytes = new Uint8Array(xorBytes);
873
+ this._bits = new Uint8Array(bits);
874
+ this._inverseBits = new Uint8Array(inverseBits);
875
+ this._rounds = xorBytes.length;
876
+ }
877
+ }
878
+ /**
879
+ * Get the tweak.
880
+ */
881
+ get tweak() {
882
+ return this._tweak;
883
+ }
884
+ /**
885
+ * Convert a value to a byte array big enough to handle the entire domain.
886
+ *
887
+ * @param value
888
+ * Value.
889
+ *
890
+ * @returns
891
+ * Big-endian byte array equivalent to the value.
892
+ */
893
+ valueToBytes(value) {
894
+ const bytes = new Uint8Array(this._domainBytes);
895
+ let reducedValue = value;
896
+ for (let index = this._domainBytes - 1; index >= 0; index--) {
897
+ bytes[index] = Number(reducedValue & 0xFFn);
898
+ reducedValue = reducedValue >> 8n;
899
+ }
900
+ return bytes;
901
+ }
902
+ /**
903
+ * Convert a byte array to a value.
904
+ *
905
+ * @param bytes
906
+ * Big-endian byte array equivalent to the value.
907
+ *
908
+ * @returns
909
+ * Value.
910
+ */
911
+ static bytesToValue(bytes) {
912
+ return bytes.reduce((accumulator, byte) => accumulator << 8n | BigInt(byte), 0n);
913
+ }
914
+ /**
915
+ * Shuffle a byte array.
916
+ *
917
+ * The input array to the forward operation (output from the reverse operation) is `bytes` and the output array from
918
+ * the forward operation (input to the reverse operation) is `bytes'`.
919
+ *
920
+ * The shuffle operation starts by testing the bit at `bits[round]` for each `byte` in `bytes`. The indexes for all
921
+ * bytes with that bit set are put into one array (`shuffleIndexes1`) and the rest are put into another
922
+ * (`shuffleIndexes0`). The two arrays are concatenated and used to shuffle the input array, using their values
923
+ * (`shuffleIndex`) and the indexes of those values (`index`) in the concatenated array.
924
+ *
925
+ * Forward shuffling moves the entry at `shuffleIndex` to the `index` position.
926
+ *
927
+ * Reverse shuffling moves the entry at `index` to the `shuffleIndex` position.
928
+ *
929
+ * As each byte is moved, the bit at `bits[round]` is preserved in its original position. This ensures that the
930
+ * process is reversible.
931
+ *
932
+ * @param bytes
933
+ * Byte array.
934
+ *
935
+ * @param round
936
+ * Round number.
937
+ *
938
+ * @param forward
939
+ * True if operating forward (encrypting), false if operating in reverse (decrypting).
940
+ *
941
+ * @returns
942
+ * Shuffled byte array.
943
+ */
944
+ shuffle(bytes, round, forward) {
945
+ const bytesLength = bytes.length;
946
+ const determinants = new Uint8Array(bytesLength);
947
+ const shuffleIndexes1 = new Array();
948
+ const shuffleIndexes0 = new Array();
949
+ const bit = this._bits[round];
950
+ bytes.forEach((byte, index) => {
951
+ const determinant = byte & bit;
952
+ determinants[index] = determinant;
953
+ (determinant !== 0 ? shuffleIndexes1 : shuffleIndexes0).push(index);
954
+ });
955
+ const inverseBit = this._inverseBits[round];
956
+ const shuffleBytes = new Uint8Array(bytesLength);
957
+ [...shuffleIndexes1, ...shuffleIndexes0].forEach((shuffleIndex, index) => {
958
+ if (forward) {
959
+ shuffleBytes[index] = bytes[shuffleIndex] & inverseBit | determinants[index];
960
+ } else {
961
+ shuffleBytes[shuffleIndex] = bytes[index] & inverseBit | determinants[shuffleIndex];
962
+ }
963
+ });
964
+ return shuffleBytes;
965
+ }
966
+ /**
967
+ * Xor a byte array.
968
+ *
969
+ * The input array to the forward operation (output from the reverse operation) is `bytes` and the output array from
970
+ * the forward operation (input to the reverse operation) is `bytes'`.
971
+ *
972
+ * Forward:
973
+ * - `bytes'[0] = bytes[0] ^ xorBytes[round]`
974
+ * - `bytes'[1] = bytes[1] ^ bytes'[0]`
975
+ * - `bytes'[2] = bytes[2] ^ bytes'[1]`
976
+ * - `...`
977
+ * - `bytes'[domainBytes - 1] = bytes[domainBytes - 1] ^ bytes'[domainBytes - 2]`
978
+ *
979
+ * Reverse:
980
+ * - `bytes[0] = bytes'[0] ^ xorBytes[round]`
981
+ * - `bytes[1] = bytes'[1] ^ bytes'[0]`
982
+ * - `bytes[2] = bytes'[2] ^ bytes'[1]`
983
+ * - `...`
984
+ * - `bytes[domainBytes - 1] = bytes'[domainBytes - 1] ^ bytes'[domainBytes - 2]`
985
+ *
986
+ * @param bytes
987
+ * Byte array.
988
+ *
989
+ * @param round
990
+ * Round number.
991
+ *
992
+ * @param forward
993
+ * True if operating forward (encrypting), false if operating in reverse (decrypting).
994
+ *
995
+ * @returns
996
+ * Xored byte array.
997
+ */
998
+ xor(bytes, round, forward) {
999
+ let cumulativeXorByte = this._xorBytes[round];
1000
+ return bytes.map((byte) => {
1001
+ const xorByte = byte ^ cumulativeXorByte;
1002
+ cumulativeXorByte = forward ? xorByte : byte;
1003
+ return xorByte;
1004
+ });
1005
+ }
1006
+ /**
1007
+ * @inheritDoc
1008
+ */
1009
+ doForward(value) {
1010
+ let bytes = this.valueToBytes(value);
1011
+ let transformedValue;
1012
+ do {
1013
+ for (let round = 0; round < this._rounds; round++) {
1014
+ bytes = this.xor(this.shuffle(bytes, round, true), round, true);
1015
+ }
1016
+ transformedValue = _EncryptionTransformer.bytesToValue(bytes);
1017
+ } while (transformedValue >= this.domain);
1018
+ return transformedValue;
1019
+ }
1020
+ /**
1021
+ * @inheritDoc
1022
+ */
1023
+ doReverse(transformedValue) {
1024
+ let bytes = this.valueToBytes(transformedValue);
1025
+ let value;
1026
+ do {
1027
+ for (let round = this._rounds - 1; round >= 0; round--) {
1028
+ bytes = this.shuffle(this.xor(bytes, round, false), round, false);
1029
+ }
1030
+ value = _EncryptionTransformer.bytesToValue(bytes);
1031
+ } while (value >= this.domain);
1032
+ return value;
1033
+ }
1034
+ };
1035
+
1036
+ // src/reg_exp.ts
1037
+ var RegExpValidator = class {
1038
+ /**
1039
+ * Regular expression.
1040
+ */
1041
+ _regExp;
1042
+ /**
1043
+ * Constructor.
1044
+ *
1045
+ * @param regExp
1046
+ * Regular expression. See {@link RegExpValidator | class documentation} for notes.
1047
+ */
1048
+ constructor(regExp) {
1049
+ this._regExp = regExp;
1050
+ }
1051
+ /**
1052
+ * Get the regular expression.
1053
+ */
1054
+ get regExp() {
1055
+ return this._regExp;
1056
+ }
1057
+ /**
1058
+ * Create an error message for a string. The generic error message is sufficient for many use cases but a more
1059
+ * domain-specific error message, possibly including the pattern itself, is often required.
1060
+ *
1061
+ * @param s
1062
+ * String.
1063
+ *
1064
+ * @returns
1065
+ * Error message.
1066
+ */
1067
+ createErrorMessage(s) {
1068
+ return i18n_default.t("RegExpValidator.stringDoesNotMatchPattern", {
1069
+ ns: utilityNS,
1070
+ s
1071
+ });
1072
+ }
1073
+ /**
1074
+ * @inheritDoc
1075
+ */
1076
+ validate(s) {
1077
+ if (!this._regExp.test(s)) {
1078
+ throw new RangeError(this.createErrorMessage(s));
1079
+ }
1080
+ }
1081
+ };
1082
+
1083
+ // src/record.ts
1084
+ var RecordValidator = class {
1085
+ /**
1086
+ * Type name for error message.
1087
+ */
1088
+ _typeName;
1089
+ /**
1090
+ * Record in which to look up keys.
1091
+ */
1092
+ _record;
1093
+ /**
1094
+ * Constructor.
1095
+ *
1096
+ * @param typeName
1097
+ * Type name for error message.
1098
+ *
1099
+ * @param record
1100
+ * Record in which to look up keys.
1101
+ */
1102
+ constructor(typeName, record) {
1103
+ this._typeName = typeName;
1104
+ this._record = record;
1105
+ }
1106
+ /**
1107
+ * Get the type name.
1108
+ */
1109
+ get typeName() {
1110
+ return this._typeName;
1111
+ }
1112
+ /**
1113
+ * Get the record.
1114
+ */
1115
+ get record() {
1116
+ return this._record;
1117
+ }
1118
+ /**
1119
+ * Validate a key by looking it up in the record.
1120
+ *
1121
+ * @param key
1122
+ * Record key.
1123
+ */
1124
+ validate(key) {
1125
+ if (this.record[key] === void 0) {
1126
+ throw new RangeError(i18n_default.t("RecordValidator.typeNameKeyNotFound", {
1127
+ ns: utilityNS,
1128
+ typeName: this.typeName,
1129
+ key
1130
+ }));
1131
+ }
1132
+ }
1133
+ };
1134
+
1135
+ // src/character_set.ts
1136
+ var Exclusion = /* @__PURE__ */ ((Exclusion2) => {
1137
+ Exclusion2[Exclusion2["None"] = 0] = "None";
1138
+ Exclusion2[Exclusion2["FirstZero"] = 1] = "FirstZero";
1139
+ Exclusion2[Exclusion2["AllNumeric"] = 2] = "AllNumeric";
1140
+ return Exclusion2;
1141
+ })(Exclusion || {});
1142
+ var CharacterSetValidator = class _CharacterSetValidator {
1143
+ static NOT_ALL_NUMERIC_VALIDATOR = new class extends RegExpValidator {
1144
+ /**
1145
+ * Create an error message for an all-numeric string.
1146
+ *
1147
+ * @param _s
1148
+ * String.
1149
+ *
1150
+ * @returns
1151
+ * Error message.
1152
+ */
1153
+ createErrorMessage(_s) {
1154
+ return i18n_default.t("CharacterSetValidator.stringMustNotBeAllNumeric", {
1155
+ ns: utilityNS
1156
+ });
1157
+ }
1158
+ }(/\D/);
1159
+ /**
1160
+ * Character set.
1161
+ */
1162
+ _characterSet;
1163
+ /**
1164
+ * Character set map, mapping each character in the character set to its index such that
1165
+ * `_characterSetMap.get(_characterSet[index]) === index`.
1166
+ */
1167
+ _characterSetMap;
1168
+ /**
1169
+ * Exclusions supported by the character set.
1170
+ */
1171
+ _exclusionSupport;
1172
+ /**
1173
+ * Constructor.
1174
+ *
1175
+ * @param characterSet
1176
+ * Character set. Each element is a single-character string, unique within the array, that defines the character
1177
+ * set.
1178
+ *
1179
+ * @param exclusionSupport
1180
+ * Exclusions supported by the character set. All character sets implicitly support {@link Exclusion.None}.
1181
+ */
1182
+ constructor(characterSet, ...exclusionSupport) {
1183
+ this._characterSet = characterSet;
1184
+ const characterSetMap = /* @__PURE__ */ new Map();
1185
+ characterSet.forEach((c, index) => {
1186
+ characterSetMap.set(c, index);
1187
+ });
1188
+ this._characterSetMap = characterSetMap;
1189
+ this._exclusionSupport = exclusionSupport;
1190
+ }
1191
+ /**
1192
+ * Get the character set.
1193
+ */
1194
+ get characterSet() {
1195
+ return this._characterSet;
1196
+ }
1197
+ /**
1198
+ * Get the character set size.
1199
+ */
1200
+ get characterSetSize() {
1201
+ return this._characterSet.length;
1202
+ }
1203
+ /**
1204
+ * Get the exclusions supported by the character set.
1205
+ */
1206
+ get exclusionSupport() {
1207
+ return this._exclusionSupport;
1208
+ }
1209
+ /**
1210
+ * Get the character at an index.
1211
+ *
1212
+ * @param index
1213
+ * Index into the character set.
1214
+ *
1215
+ * @returns
1216
+ * Character at the index.
1217
+ */
1218
+ character(index) {
1219
+ return this._characterSet[index];
1220
+ }
1221
+ /**
1222
+ * Get the index for a character.
1223
+ *
1224
+ * @param c
1225
+ * Character.
1226
+ *
1227
+ * @returns
1228
+ * Index for the character or undefined if the character is not in the character set.
1229
+ */
1230
+ characterIndex(c) {
1231
+ return this._characterSetMap.get(c);
1232
+ }
1233
+ /**
1234
+ * Get the indexes for all characters in a string.
1235
+ *
1236
+ * @param s
1237
+ * String.
1238
+ *
1239
+ * @returns
1240
+ * Array of indexes for each character or undefined if the character is not in the character set.
1241
+ */
1242
+ characterIndexes(s) {
1243
+ return [...s].map((c) => this._characterSetMap.get(c));
1244
+ }
1245
+ /**
1246
+ * Convert a component definition to a string or undefined. Checks the type of the component and makes the callback
1247
+ * if required.
1248
+ *
1249
+ * @param component
1250
+ * Component definition as a string, callback, or undefined.
1251
+ *
1252
+ * @returns
1253
+ * Component as a string or undefined.
1254
+ */
1255
+ static componentToString(component) {
1256
+ return typeof component === "function" ? component() : component;
1257
+ }
1258
+ /**
1259
+ * Validate that an exclusion is supported. If not, an error is thrown.
1260
+ *
1261
+ * @param exclusion
1262
+ * Exclusion.
1263
+ */
1264
+ validateExclusion(exclusion) {
1265
+ if (exclusion !== 0 /* None */ && !this._exclusionSupport.includes(exclusion)) {
1266
+ throw new RangeError(i18n_default.t("CharacterSetValidator.exclusionNotSupported", {
1267
+ ns: utilityNS,
1268
+ exclusion
1269
+ }));
1270
+ }
1271
+ }
1272
+ /**
1273
+ * Validate a string. If the string violates the character set or any of the character set validation parameters, an
1274
+ * error is thrown.
1275
+ *
1276
+ * @param s
1277
+ * String.
1278
+ *
1279
+ * @param validation
1280
+ * Character set validation parameters.
1281
+ */
1282
+ validate(s, validation) {
1283
+ const length = s.length;
1284
+ const minimumLength = validation?.minimumLength;
1285
+ const maximumLength = validation?.maximumLength;
1286
+ if (minimumLength !== void 0 && length < minimumLength) {
1287
+ let errorMessage;
1288
+ if (maximumLength !== void 0 && maximumLength === minimumLength) {
1289
+ errorMessage = i18n_default.t(validation?.component === void 0 ? "CharacterSetValidator.lengthMustBeEqualTo" : "CharacterSetValidator.lengthOfComponentMustBeEqualTo", {
1290
+ ns: utilityNS,
1291
+ component: _CharacterSetValidator.componentToString(validation?.component),
1292
+ length,
1293
+ exactLength: minimumLength
1294
+ });
1295
+ } else {
1296
+ errorMessage = i18n_default.t(validation?.component === void 0 ? "CharacterSetValidator.lengthMustBeGreaterThanOrEqualTo" : "CharacterSetValidator.lengthOfComponentMustBeGreaterThanOrEqualTo", {
1297
+ ns: utilityNS,
1298
+ component: _CharacterSetValidator.componentToString(validation?.component),
1299
+ length,
1300
+ minimumLength
1301
+ });
1302
+ }
1303
+ throw new RangeError(errorMessage);
1304
+ }
1305
+ if (maximumLength !== void 0 && length > maximumLength) {
1306
+ throw new RangeError(i18n_default.t(validation?.component === void 0 ? "CharacterSetValidator.lengthMustBeLessThanOrEqualTo" : "CharacterSetValidator.lengthOfComponentMustBeLessThanOrEqualTo", {
1307
+ ns: utilityNS,
1308
+ component: _CharacterSetValidator.componentToString(validation?.component),
1309
+ length,
1310
+ maximumLength
1311
+ }));
1312
+ }
1313
+ const index = this.characterIndexes(s).findIndex((characterIndex) => characterIndex === void 0);
1314
+ if (index !== -1) {
1315
+ throw new RangeError(i18n_default.t(validation?.component === void 0 ? "CharacterSetValidator.invalidCharacterAtPosition" : "CharacterSetValidator.invalidCharacterAtPositionOfComponent", {
1316
+ ns: utilityNS,
1317
+ component: _CharacterSetValidator.componentToString(validation?.component),
1318
+ c: s.charAt(index),
1319
+ position: index + (validation?.positionOffset ?? 0) + 1
1320
+ }));
1321
+ }
1322
+ if (validation?.exclusion !== void 0) {
1323
+ this.validateExclusion(validation.exclusion);
1324
+ switch (validation.exclusion) {
1325
+ case 0 /* None */:
1326
+ break;
1327
+ case 1 /* FirstZero */:
1328
+ if (s.startsWith("0")) {
1329
+ throw new RangeError(i18n_default.t(validation.component === void 0 ? "CharacterSetValidator.invalidCharacterAtPosition" : "CharacterSetValidator.invalidCharacterAtPositionOfComponent", {
1330
+ ns: utilityNS,
1331
+ component: _CharacterSetValidator.componentToString(validation.component),
1332
+ c: "0",
1333
+ position: (validation.positionOffset ?? 0) + 1
1334
+ }));
1335
+ }
1336
+ break;
1337
+ case 2 /* AllNumeric */:
1338
+ _CharacterSetValidator.NOT_ALL_NUMERIC_VALIDATOR.validate(s);
1339
+ break;
1340
+ }
1341
+ }
1342
+ }
1343
+ };
1344
+ var CharacterSetCreator = class _CharacterSetCreator extends CharacterSetValidator {
1345
+ /**
1346
+ * Maximum string length supported.
1347
+ */
1348
+ static MAXIMUM_STRING_LENGTH = 40;
1349
+ /**
1350
+ * Powers of 10 from 1 (`10**0`) to `10**MAXIMUM_STRING_LENGTH`.
1351
+ */
1352
+ static _powersOf10 = _CharacterSetCreator.createPowersOf(10);
1353
+ /**
1354
+ * Create powers of a given base from 1 (`base**0`) to `base**MAXIMUM_STRING_LENGTH`.
1355
+ *
1356
+ * @param base
1357
+ * Number base.
1358
+ *
1359
+ * @returns
1360
+ * Array of powers of base.
1361
+ */
1362
+ static createPowersOf(base) {
1363
+ const powersOf = new Array(this.MAXIMUM_STRING_LENGTH + 1);
1364
+ const baseN = BigInt(base);
1365
+ for (let index = 0, powerOf = 1n; index <= this.MAXIMUM_STRING_LENGTH; index++, powerOf *= baseN) {
1366
+ powersOf[index] = powerOf;
1367
+ }
1368
+ return powersOf;
1369
+ }
1370
+ /**
1371
+ * Get a power of 10.
1372
+ *
1373
+ * @param power
1374
+ * Power.
1375
+ *
1376
+ * @returns
1377
+ * `10**power`.
1378
+ */
1379
+ static powerOf10(power) {
1380
+ return this._powersOf10[power];
1381
+ }
1382
+ /**
1383
+ * Character set size as big integer, cached for performance purposes.
1384
+ */
1385
+ _characterSetSizeN;
1386
+ /**
1387
+ * Character set size minus 1 as big integer, cached for performance purposes.
1388
+ */
1389
+ _characterSetSizeMinusOneN;
1390
+ /**
1391
+ * Domains for every length for every supported {@link Exclusion}.
1392
+ */
1393
+ _exclusionDomains;
1394
+ /**
1395
+ * Values that would generate all zeros in the created string.
1396
+ */
1397
+ _allZerosValues;
1398
+ /**
1399
+ * Constructor.
1400
+ *
1401
+ * @param characterSet
1402
+ * Character set. Each element is a single-character string, unique within the array, that defines the character
1403
+ * set.
1404
+ *
1405
+ * @param exclusionSupport
1406
+ * Exclusions supported by the character set. All character sets implicitly support {@link Exclusion.None}.
1407
+ */
1408
+ constructor(characterSet, ...exclusionSupport) {
1409
+ super(characterSet, ...exclusionSupport);
1410
+ this._characterSetSizeN = BigInt(this.characterSetSize);
1411
+ this._characterSetSizeMinusOneN = BigInt(this.characterSetSize - 1);
1412
+ const exclusionDomains = [];
1413
+ const exclusionNoneDomains = _CharacterSetCreator.createPowersOf(this.characterSetSize);
1414
+ exclusionDomains[0 /* None */] = exclusionNoneDomains;
1415
+ if (exclusionSupport.includes(1 /* FirstZero */)) {
1416
+ if (characterSet[0] !== "0") {
1417
+ throw new RangeError(i18n_default.t("CharacterSetValidator.firstZeroFirstCharacter", {
1418
+ ns: utilityNS
1419
+ }));
1420
+ }
1421
+ const exclusionFirstZeroDomains = new Array(_CharacterSetCreator.MAXIMUM_STRING_LENGTH + 1);
1422
+ exclusionFirstZeroDomains[0] = 0n;
1423
+ for (let index = 1; index <= _CharacterSetCreator.MAXIMUM_STRING_LENGTH; index++) {
1424
+ exclusionFirstZeroDomains[index] = this._characterSetSizeMinusOneN * exclusionNoneDomains[index - 1];
1425
+ }
1426
+ exclusionDomains[1 /* FirstZero */] = exclusionFirstZeroDomains;
1427
+ }
1428
+ if (exclusionSupport.includes(2 /* AllNumeric */)) {
1429
+ const exclusionAllNumericDomains = new Array(_CharacterSetCreator.MAXIMUM_STRING_LENGTH + 1);
1430
+ const numberIndexes = this.characterIndexes("0123456789");
1431
+ let expectedNumberIndex = numberIndexes[0];
1432
+ for (const numberIndex of numberIndexes) {
1433
+ if (numberIndex === void 0 || numberIndex !== expectedNumberIndex) {
1434
+ throw new RangeError(i18n_default.t("CharacterSetValidator.allNumericAllNumericCharacters", {
1435
+ ns: utilityNS
1436
+ }));
1437
+ }
1438
+ expectedNumberIndex = numberIndex + 1;
1439
+ }
1440
+ const zeroIndex = BigInt(numberIndexes[0]);
1441
+ const allZerosValues = new Array(_CharacterSetCreator.MAXIMUM_STRING_LENGTH + 1);
1442
+ let allZerosValue = 0n;
1443
+ for (let index = 0; index <= _CharacterSetCreator.MAXIMUM_STRING_LENGTH; index++) {
1444
+ exclusionAllNumericDomains[index] = exclusionNoneDomains[index] - _CharacterSetCreator.powerOf10(index);
1445
+ allZerosValues[index] = allZerosValue;
1446
+ allZerosValue = allZerosValue * this._characterSetSizeN + zeroIndex;
1447
+ }
1448
+ this._allZerosValues = allZerosValues;
1449
+ exclusionDomains[2 /* AllNumeric */] = exclusionAllNumericDomains;
1450
+ } else {
1451
+ this._allZerosValues = [];
1452
+ }
1453
+ this._exclusionDomains = exclusionDomains;
1454
+ }
1455
+ /**
1456
+ * Get a power of character set size.
1457
+ *
1458
+ * @param power
1459
+ * Power.
1460
+ *
1461
+ * @returns
1462
+ * `characterSetSize**power`.
1463
+ */
1464
+ powerOfSize(power) {
1465
+ return this._exclusionDomains[0 /* None */][power];
1466
+ }
1467
+ /**
1468
+ * Determine the shift required to skip all all-numeric strings up to the value.
1469
+ *
1470
+ * @param shiftForward
1471
+ * True to shift forward (value to string), false to shift backward (string to value).
1472
+ *
1473
+ * @param length
1474
+ * Length of string for which to get the all-numeric shift.
1475
+ *
1476
+ * @param value
1477
+ * Value for which to get the all-numeric shift.
1478
+ *
1479
+ * @returns
1480
+ * Shift required to skip all all-numeric strings.
1481
+ */
1482
+ allNumericShift(shiftForward, length, value) {
1483
+ let shift;
1484
+ if (length === 0) {
1485
+ if (!shiftForward && value < 10n) {
1486
+ throw new RangeError(i18n_default.t("CharacterSetValidator.stringMustNotBeAllNumeric", {
1487
+ ns: utilityNS
1488
+ }));
1489
+ }
1490
+ shift = 10n;
1491
+ } else {
1492
+ const powerOfSize = this.powerOfSize(length);
1493
+ const powerOf10 = _CharacterSetCreator.powerOf10(length);
1494
+ const gap = shiftForward ? powerOfSize - powerOf10 : powerOfSize;
1495
+ const gaps = value / gap;
1496
+ if (gaps >= 10n) {
1497
+ shift = _CharacterSetCreator.powerOf10(length + 1);
1498
+ } else {
1499
+ shift = gaps * powerOf10 + this.allNumericShift(shiftForward, length - 1, value - gaps * gap);
1500
+ }
1501
+ }
1502
+ return shift;
1503
+ }
1504
+ /**
1505
+ * Validate that a length is less than or equal to {@link MAXIMUM_STRING_LENGTH}. If not, an error is thrown.
1506
+ *
1507
+ * @param length
1508
+ * Length.
1509
+ */
1510
+ validateLength(length) {
1511
+ if (length < 0) {
1512
+ throw new RangeError(i18n_default.t("CharacterSetValidator.lengthMustBeGreaterThanOrEqualTo", {
1513
+ ns: utilityNS,
1514
+ length,
1515
+ minimumLength: 0
1516
+ }));
1517
+ }
1518
+ if (length > _CharacterSetCreator.MAXIMUM_STRING_LENGTH) {
1519
+ throw new RangeError(i18n_default.t("CharacterSetValidator.lengthMustBeLessThanOrEqualTo", {
1520
+ ns: utilityNS,
1521
+ length,
1522
+ maximumLength: _CharacterSetCreator.MAXIMUM_STRING_LENGTH
1523
+ }));
1524
+ }
1525
+ }
1526
+ // eslint-disable-next-line jsdoc/require-jsdoc -- Implementation of overloaded signatures.
1527
+ create(length, valueOrValues, exclusion = 0 /* None */, tweak, creationCallback) {
1528
+ this.validateLength(length);
1529
+ this.validateExclusion(exclusion);
1530
+ const allZerosValue = exclusion === 2 /* AllNumeric */ ? this._allZerosValues[length] : 0n;
1531
+ const transformer = Transformer.get(this._exclusionDomains[exclusion][length], tweak);
1532
+ return transformer.forward(valueOrValues, (transformedValue, index) => {
1533
+ let s = "";
1534
+ if (length !== 0) {
1535
+ let convertValue = transformedValue;
1536
+ if (exclusion === 2 /* AllNumeric */ && convertValue >= allZerosValue) {
1537
+ convertValue = convertValue + this.allNumericShift(true, length, convertValue - allZerosValue);
1538
+ }
1539
+ for (let position = length - 1; position > 0; position--) {
1540
+ const nextConvertValue = convertValue / this._characterSetSizeN;
1541
+ s = this.character(Number(convertValue - nextConvertValue * this._characterSetSizeN)) + s;
1542
+ convertValue = nextConvertValue;
1543
+ }
1544
+ s = this.character(exclusion === 1 /* FirstZero */ ? Number(convertValue % this._characterSetSizeMinusOneN) + 1 : Number(convertValue % this._characterSetSizeN)) + s;
1545
+ }
1546
+ return creationCallback !== void 0 ? creationCallback(s, index) : s;
1547
+ });
1548
+ }
1549
+ /**
1550
+ * Determine the value for a string.
1551
+ *
1552
+ * @param s
1553
+ * String.
1554
+ *
1555
+ * @param exclusion
1556
+ * Strings excluded from the range of inputs. See {@link Exclusion} for possible values and their meaning.
1557
+ *
1558
+ * @param tweak
1559
+ * If provided, the numerical value of the string was "tweaked" using an {@link EncryptionTransformer | encryption
1560
+ * transformer}.
1561
+ *
1562
+ * @returns
1563
+ * Numeric value of the string.
1564
+ */
1565
+ valueFor(s, exclusion = 0 /* None */, tweak) {
1566
+ const length = s.length;
1567
+ this.validateLength(length);
1568
+ this.validateExclusion(exclusion);
1569
+ const characterSetSizeN = BigInt(this.characterSetSize);
1570
+ let value = this.characterIndexes(s).reduce((accumulator, characterIndex, index) => {
1571
+ if (characterIndex === void 0) {
1572
+ throw new RangeError(i18n_default.t("CharacterSetValidator.invalidCharacterAtPosition", {
1573
+ ns: utilityNS,
1574
+ c: s.charAt(index),
1575
+ position: index + 1
1576
+ }));
1577
+ }
1578
+ let value2;
1579
+ if (index === 0 && exclusion === 1 /* FirstZero */) {
1580
+ if (characterIndex === 0) {
1581
+ throw new RangeError(i18n_default.t("CharacterSetValidator.invalidCharacterAtPosition", {
1582
+ ns: utilityNS,
1583
+ c: "0",
1584
+ position: 1
1585
+ }));
1586
+ }
1587
+ value2 = BigInt(characterIndex - 1);
1588
+ } else {
1589
+ value2 = accumulator * characterSetSizeN + BigInt(characterIndex);
1590
+ }
1591
+ return value2;
1592
+ }, 0n);
1593
+ if (exclusion === 2 /* AllNumeric */) {
1594
+ const allZerosValue = this._allZerosValues[length];
1595
+ if (value >= allZerosValue) {
1596
+ value -= this.allNumericShift(false, length, value - allZerosValue);
1597
+ }
1598
+ }
1599
+ return Transformer.get(this._exclusionDomains[exclusion][length], tweak).reverse(value);
1600
+ }
1601
+ };
1602
+ var NUMERIC_CREATOR = new CharacterSetCreator([
1603
+ "0",
1604
+ "1",
1605
+ "2",
1606
+ "3",
1607
+ "4",
1608
+ "5",
1609
+ "6",
1610
+ "7",
1611
+ "8",
1612
+ "9"
1613
+ ], 1 /* FirstZero */);
1614
+ var HEXADECIMAL_CREATOR = new CharacterSetCreator([
1615
+ "0",
1616
+ "1",
1617
+ "2",
1618
+ "3",
1619
+ "4",
1620
+ "5",
1621
+ "6",
1622
+ "7",
1623
+ "8",
1624
+ "9",
1625
+ "A",
1626
+ "B",
1627
+ "C",
1628
+ "D",
1629
+ "E",
1630
+ "F"
1631
+ ], 1 /* FirstZero */, 2 /* AllNumeric */);
1632
+ var ALPHABETIC_CREATOR = new CharacterSetCreator([
1633
+ "A",
1634
+ "B",
1635
+ "C",
1636
+ "D",
1637
+ "E",
1638
+ "F",
1639
+ "G",
1640
+ "H",
1641
+ "I",
1642
+ "J",
1643
+ "K",
1644
+ "L",
1645
+ "M",
1646
+ "N",
1647
+ "O",
1648
+ "P",
1649
+ "Q",
1650
+ "R",
1651
+ "S",
1652
+ "T",
1653
+ "U",
1654
+ "V",
1655
+ "W",
1656
+ "X",
1657
+ "Y",
1658
+ "Z"
1659
+ ]);
1660
+ var ALPHANUMERIC_CREATOR = new CharacterSetCreator([
1661
+ "0",
1662
+ "1",
1663
+ "2",
1664
+ "3",
1665
+ "4",
1666
+ "5",
1667
+ "6",
1668
+ "7",
1669
+ "8",
1670
+ "9",
1671
+ "A",
1672
+ "B",
1673
+ "C",
1674
+ "D",
1675
+ "E",
1676
+ "F",
1677
+ "G",
1678
+ "H",
1679
+ "I",
1680
+ "J",
1681
+ "K",
1682
+ "L",
1683
+ "M",
1684
+ "N",
1685
+ "O",
1686
+ "P",
1687
+ "Q",
1688
+ "R",
1689
+ "S",
1690
+ "T",
1691
+ "U",
1692
+ "V",
1693
+ "W",
1694
+ "X",
1695
+ "Y",
1696
+ "Z"
1697
+ ], 1 /* FirstZero */, 2 /* AllNumeric */);
1698
+ // Annotate the CommonJS export names for ESM import in node:
1699
+ 0 && (module.exports = {
1700
+ ALPHABETIC_CREATOR,
1701
+ ALPHANUMERIC_CREATOR,
1702
+ CharacterSetCreator,
1703
+ CharacterSetValidator,
1704
+ EncryptionTransformer,
1705
+ Exclusion,
1706
+ HEXADECIMAL_CREATOR,
1707
+ IdentityTransformer,
1708
+ IteratorProxy,
1709
+ NUMERIC_CREATOR,
1710
+ RecordValidator,
1711
+ RegExpValidator,
1712
+ Sequencer,
1713
+ Transformer
1714
+ });