ts-fortress 1.0.0
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/LICENSE +201 -0
- package/README.md +324 -0
- package/dist/array/array-of-length.d.mts +6 -0
- package/dist/array/array-of-length.d.mts.map +1 -0
- package/dist/array/array-of-length.mjs +50 -0
- package/dist/array/array-of-length.mjs.map +1 -0
- package/dist/array/array.d.mts +6 -0
- package/dist/array/array.d.mts.map +1 -0
- package/dist/array/array.mjs +39 -0
- package/dist/array/array.mjs.map +1 -0
- package/dist/array/index.d.mts +5 -0
- package/dist/array/index.d.mts.map +1 -0
- package/dist/array/index.mjs +5 -0
- package/dist/array/index.mjs.map +1 -0
- package/dist/array/non-empty-array.d.mts +6 -0
- package/dist/array/non-empty-array.d.mts.map +1 -0
- package/dist/array/non-empty-array.mjs +46 -0
- package/dist/array/non-empty-array.mjs.map +1 -0
- package/dist/array/tuple.d.mts +9 -0
- package/dist/array/tuple.d.mts.map +1 -0
- package/dist/array/tuple.mjs +47 -0
- package/dist/array/tuple.mjs.map +1 -0
- package/dist/branded/brand.d.mts +11 -0
- package/dist/branded/brand.d.mts.map +1 -0
- package/dist/branded/brand.mjs +29 -0
- package/dist/branded/brand.mjs.map +1 -0
- package/dist/branded/index.d.mts +5 -0
- package/dist/branded/index.d.mts.map +1 -0
- package/dist/branded/index.mjs +20 -0
- package/dist/branded/index.mjs.map +1 -0
- package/dist/branded/number/finite-number.d.mts +3 -0
- package/dist/branded/number/finite-number.d.mts.map +1 -0
- package/dist/branded/number/finite-number.mjs +14 -0
- package/dist/branded/number/finite-number.mjs.map +1 -0
- package/dist/branded/number/index.d.mts +17 -0
- package/dist/branded/number/index.d.mts.map +1 -0
- package/dist/branded/number/index.mjs +17 -0
- package/dist/branded/number/index.mjs.map +1 -0
- package/dist/branded/number/int.d.mts +3 -0
- package/dist/branded/number/int.d.mts.map +1 -0
- package/dist/branded/number/int.mjs +14 -0
- package/dist/branded/number/int.mjs.map +1 -0
- package/dist/branded/number/int16.d.mts +3 -0
- package/dist/branded/number/int16.d.mts.map +1 -0
- package/dist/branded/number/int16.mjs +26 -0
- package/dist/branded/number/int16.mjs.map +1 -0
- package/dist/branded/number/int32.d.mts +3 -0
- package/dist/branded/number/int32.d.mts.map +1 -0
- package/dist/branded/number/int32.mjs +22 -0
- package/dist/branded/number/int32.mjs.map +1 -0
- package/dist/branded/number/non-negative-finite-number.d.mts +3 -0
- package/dist/branded/number/non-negative-finite-number.d.mts.map +1 -0
- package/dist/branded/number/non-negative-finite-number.mjs +14 -0
- package/dist/branded/number/non-negative-finite-number.mjs.map +1 -0
- package/dist/branded/number/non-zero-finite-number.d.mts +3 -0
- package/dist/branded/number/non-zero-finite-number.d.mts.map +1 -0
- package/dist/branded/number/non-zero-finite-number.mjs +14 -0
- package/dist/branded/number/non-zero-finite-number.mjs.map +1 -0
- package/dist/branded/number/non-zero-int.d.mts +3 -0
- package/dist/branded/number/non-zero-int.d.mts.map +1 -0
- package/dist/branded/number/non-zero-int.mjs +14 -0
- package/dist/branded/number/non-zero-int.mjs.map +1 -0
- package/dist/branded/number/non-zero-safe-int.d.mts +3 -0
- package/dist/branded/number/non-zero-safe-int.d.mts.map +1 -0
- package/dist/branded/number/non-zero-safe-int.mjs +14 -0
- package/dist/branded/number/non-zero-safe-int.mjs.map +1 -0
- package/dist/branded/number/positive-finite-number.d.mts +3 -0
- package/dist/branded/number/positive-finite-number.d.mts.map +1 -0
- package/dist/branded/number/positive-finite-number.mjs +22 -0
- package/dist/branded/number/positive-finite-number.mjs.map +1 -0
- package/dist/branded/number/positive-int.d.mts +3 -0
- package/dist/branded/number/positive-int.d.mts.map +1 -0
- package/dist/branded/number/positive-int.mjs +23 -0
- package/dist/branded/number/positive-int.mjs.map +1 -0
- package/dist/branded/number/positive-safe-int.d.mts +3 -0
- package/dist/branded/number/positive-safe-int.d.mts.map +1 -0
- package/dist/branded/number/positive-safe-int.mjs +24 -0
- package/dist/branded/number/positive-safe-int.mjs.map +1 -0
- package/dist/branded/number/safe-int.d.mts +3 -0
- package/dist/branded/number/safe-int.d.mts.map +1 -0
- package/dist/branded/number/safe-int.mjs +14 -0
- package/dist/branded/number/safe-int.mjs.map +1 -0
- package/dist/branded/number/safe-uint.d.mts +3 -0
- package/dist/branded/number/safe-uint.d.mts.map +1 -0
- package/dist/branded/number/safe-uint.mjs +23 -0
- package/dist/branded/number/safe-uint.mjs.map +1 -0
- package/dist/branded/number/uint.d.mts +3 -0
- package/dist/branded/number/uint.d.mts.map +1 -0
- package/dist/branded/number/uint.mjs +22 -0
- package/dist/branded/number/uint.mjs.map +1 -0
- package/dist/branded/number/uint16.d.mts +3 -0
- package/dist/branded/number/uint16.d.mts.map +1 -0
- package/dist/branded/number/uint16.mjs +26 -0
- package/dist/branded/number/uint16.mjs.map +1 -0
- package/dist/branded/number/uint32.d.mts +3 -0
- package/dist/branded/number/uint32.d.mts.map +1 -0
- package/dist/branded/number/uint32.mjs +24 -0
- package/dist/branded/number/uint32.mjs.map +1 -0
- package/dist/branded/simple-branded-number.d.mts +3 -0
- package/dist/branded/simple-branded-number.d.mts.map +1 -0
- package/dist/branded/simple-branded-number.mjs +15 -0
- package/dist/branded/simple-branded-number.mjs.map +1 -0
- package/dist/branded/simple-branded-string.d.mts +3 -0
- package/dist/branded/simple-branded-string.d.mts.map +1 -0
- package/dist/branded/simple-branded-string.mjs +15 -0
- package/dist/branded/simple-branded-string.mjs.map +1 -0
- package/dist/compose/index.d.mts +4 -0
- package/dist/compose/index.d.mts.map +1 -0
- package/dist/compose/index.mjs +4 -0
- package/dist/compose/index.mjs.map +1 -0
- package/dist/compose/intersection.d.mts +19 -0
- package/dist/compose/intersection.d.mts.map +1 -0
- package/dist/compose/intersection.mjs +38 -0
- package/dist/compose/intersection.mjs.map +1 -0
- package/dist/compose/merge-records.d.mts +15 -0
- package/dist/compose/merge-records.d.mts.map +1 -0
- package/dist/compose/merge-records.mjs +48 -0
- package/dist/compose/merge-records.mjs.map +1 -0
- package/dist/compose/union.d.mts +14 -0
- package/dist/compose/union.d.mts.map +1 -0
- package/dist/compose/union.mjs +33 -0
- package/dist/compose/union.mjs.map +1 -0
- package/dist/enum/enum.d.mts +6 -0
- package/dist/enum/enum.d.mts.map +1 -0
- package/dist/enum/enum.mjs +34 -0
- package/dist/enum/enum.mjs.map +1 -0
- package/dist/enum/index.d.mts +3 -0
- package/dist/enum/index.d.mts.map +1 -0
- package/dist/enum/index.mjs +3 -0
- package/dist/enum/index.mjs.map +1 -0
- package/dist/enum/uint-range.d.mts +8 -0
- package/dist/enum/uint-range.d.mts.map +1 -0
- package/dist/enum/uint-range.mjs +40 -0
- package/dist/enum/uint-range.mjs.map +1 -0
- package/dist/globals.d.mts +3 -0
- package/dist/index.d.mts +10 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +50 -0
- package/dist/index.mjs.map +1 -0
- package/dist/primitives/bigint.d.mts +4 -0
- package/dist/primitives/bigint.d.mts.map +1 -0
- package/dist/primitives/bigint.mjs +12 -0
- package/dist/primitives/bigint.mjs.map +1 -0
- package/dist/primitives/boolean.d.mts +4 -0
- package/dist/primitives/boolean.d.mts.map +1 -0
- package/dist/primitives/boolean.mjs +12 -0
- package/dist/primitives/boolean.mjs.map +1 -0
- package/dist/primitives/index.d.mts +8 -0
- package/dist/primitives/index.d.mts.map +1 -0
- package/dist/primitives/index.mjs +8 -0
- package/dist/primitives/index.mjs.map +1 -0
- package/dist/primitives/null.d.mts +3 -0
- package/dist/primitives/null.d.mts.map +1 -0
- package/dist/primitives/null.mjs +11 -0
- package/dist/primitives/null.mjs.map +1 -0
- package/dist/primitives/number.d.mts +4 -0
- package/dist/primitives/number.d.mts.map +1 -0
- package/dist/primitives/number.mjs +12 -0
- package/dist/primitives/number.mjs.map +1 -0
- package/dist/primitives/string.d.mts +4 -0
- package/dist/primitives/string.d.mts.map +1 -0
- package/dist/primitives/string.mjs +12 -0
- package/dist/primitives/string.mjs.map +1 -0
- package/dist/primitives/symbol.d.mts +3 -0
- package/dist/primitives/symbol.d.mts.map +1 -0
- package/dist/primitives/symbol.mjs +11 -0
- package/dist/primitives/symbol.mjs.map +1 -0
- package/dist/primitives/undefined.d.mts +3 -0
- package/dist/primitives/undefined.d.mts.map +1 -0
- package/dist/primitives/undefined.mjs +11 -0
- package/dist/primitives/undefined.mjs.map +1 -0
- package/dist/record/index.d.mts +8 -0
- package/dist/record/index.d.mts.map +1 -0
- package/dist/record/index.mjs +8 -0
- package/dist/record/index.mjs.map +1 -0
- package/dist/record/key-value-record.d.mts +7 -0
- package/dist/record/key-value-record.d.mts.map +1 -0
- package/dist/record/key-value-record.mjs +52 -0
- package/dist/record/key-value-record.mjs.map +1 -0
- package/dist/record/keyof.d.mts +7 -0
- package/dist/record/keyof.d.mts.map +1 -0
- package/dist/record/keyof.mjs +15 -0
- package/dist/record/keyof.mjs.map +1 -0
- package/dist/record/omit.d.mts +8 -0
- package/dist/record/omit.d.mts.map +1 -0
- package/dist/record/omit.mjs +39 -0
- package/dist/record/omit.mjs.map +1 -0
- package/dist/record/optional.d.mts +5 -0
- package/dist/record/optional.d.mts.map +1 -0
- package/dist/record/optional.mjs +8 -0
- package/dist/record/optional.mjs.map +1 -0
- package/dist/record/partial.d.mts +13 -0
- package/dist/record/partial.d.mts.map +1 -0
- package/dist/record/partial.mjs +128 -0
- package/dist/record/partial.mjs.map +1 -0
- package/dist/record/pick.d.mts +8 -0
- package/dist/record/pick.d.mts.map +1 -0
- package/dist/record/pick.mjs +39 -0
- package/dist/record/pick.mjs.map +1 -0
- package/dist/record/record.d.mts +21 -0
- package/dist/record/record.d.mts.map +1 -0
- package/dist/record/record.mjs +53 -0
- package/dist/record/record.mjs.map +1 -0
- package/dist/tsconfig.json +1 -0
- package/dist/type.d.mts +27 -0
- package/dist/type.d.mts.map +1 -0
- package/dist/type.mjs +2 -0
- package/dist/type.mjs.map +1 -0
- package/dist/types.d.mts +2 -0
- package/dist/unknown.d.mts +3 -0
- package/dist/unknown.d.mts.map +1 -0
- package/dist/unknown.mjs +18 -0
- package/dist/unknown.mjs.map +1 -0
- package/dist/utils/create-assert-fn.d.mts +3 -0
- package/dist/utils/create-assert-fn.d.mts.map +1 -0
- package/dist/utils/create-assert-fn.mjs +12 -0
- package/dist/utils/create-assert-fn.mjs.map +1 -0
- package/dist/utils/create-cast-fn.d.mts +3 -0
- package/dist/utils/create-cast-fn.d.mts.map +1 -0
- package/dist/utils/create-cast-fn.mjs +13 -0
- package/dist/utils/create-cast-fn.mjs.map +1 -0
- package/dist/utils/create-is-fn.d.mts +3 -0
- package/dist/utils/create-is-fn.d.mts.map +1 -0
- package/dist/utils/create-is-fn.mjs +6 -0
- package/dist/utils/create-is-fn.mjs.map +1 -0
- package/dist/utils/create-primitive-type.d.mts +7 -0
- package/dist/utils/create-primitive-type.d.mts.map +1 -0
- package/dist/utils/create-primitive-type.mjs +24 -0
- package/dist/utils/create-primitive-type.mjs.map +1 -0
- package/dist/utils/create-type.d.mts +8 -0
- package/dist/utils/create-type.d.mts.map +1 -0
- package/dist/utils/create-type.mjs +19 -0
- package/dist/utils/create-type.mjs.map +1 -0
- package/dist/utils/index.d.mts +7 -0
- package/dist/utils/index.d.mts.map +1 -0
- package/dist/utils/index.mjs +7 -0
- package/dist/utils/index.mjs.map +1 -0
- package/dist/utils/validation-error-message.d.mts +2 -0
- package/dist/utils/validation-error-message.d.mts.map +1 -0
- package/dist/utils/validation-error-message.mjs +13 -0
- package/dist/utils/validation-error-message.mjs.map +1 -0
- package/package.json +102 -0
- package/src/array/array-of-length.mts +76 -0
- package/src/array/array-of-length.test.mts +113 -0
- package/src/array/array.mts +62 -0
- package/src/array/array.test.mts +84 -0
- package/src/array/index.mts +4 -0
- package/src/array/non-empty-array.mts +70 -0
- package/src/array/non-empty-array.test.mts +113 -0
- package/src/array/tuple.mts +72 -0
- package/src/array/tuple.test.mts +122 -0
- package/src/branded/brand.mts +70 -0
- package/src/branded/index.mts +4 -0
- package/src/branded/number/finite-number.mts +15 -0
- package/src/branded/number/index.mts +16 -0
- package/src/branded/number/int.mts +13 -0
- package/src/branded/number/int16.mts +25 -0
- package/src/branded/number/int32.mts +21 -0
- package/src/branded/number/non-negative-finite-number.mts +18 -0
- package/src/branded/number/non-zero-finite-number.mts +15 -0
- package/src/branded/number/non-zero-int.mts +15 -0
- package/src/branded/number/non-zero-safe-int.mts +15 -0
- package/src/branded/number/positive-finite-number.mts +23 -0
- package/src/branded/number/positive-int.mts +24 -0
- package/src/branded/number/positive-safe-int.mts +25 -0
- package/src/branded/number/safe-int.mts +13 -0
- package/src/branded/number/safe-uint.mts +24 -0
- package/src/branded/number/uint.mts +21 -0
- package/src/branded/number/uint16.mts +25 -0
- package/src/branded/number/uint32.mts +23 -0
- package/src/branded/simple-branded-number.mts +18 -0
- package/src/branded/simple-branded-string.mts +18 -0
- package/src/combination.test.mts +287 -0
- package/src/compose/index.mts +3 -0
- package/src/compose/intersection.mts +206 -0
- package/src/compose/intersection.test.mts +231 -0
- package/src/compose/merge-records.mts +218 -0
- package/src/compose/merge-records.test.mts +90 -0
- package/src/compose/union.mts +77 -0
- package/src/compose/union.test.mts +92 -0
- package/src/enum/enum.mts +53 -0
- package/src/enum/enum.test.mts +63 -0
- package/src/enum/index.mts +2 -0
- package/src/enum/uint-range.mts +63 -0
- package/src/enum/uint-range.test.mts +66 -0
- package/src/globals.d.mts +3 -0
- package/src/index.mts +9 -0
- package/src/primitives/bigint.mts +13 -0
- package/src/primitives/boolean.mts +13 -0
- package/src/primitives/index.mts +7 -0
- package/src/primitives/null.mts +9 -0
- package/src/primitives/number.mts +13 -0
- package/src/primitives/string.mts +13 -0
- package/src/primitives/symbol.mts +10 -0
- package/src/primitives/undefined.mts +9 -0
- package/src/record/index.mts +7 -0
- package/src/record/key-value-record.mts +84 -0
- package/src/record/key-value-record.test.mts +96 -0
- package/src/record/keyof.mts +31 -0
- package/src/record/keyof.test.mts +73 -0
- package/src/record/omit.mts +94 -0
- package/src/record/omit.test.mts +116 -0
- package/src/record/optional.mts +16 -0
- package/src/record/partial.mts +186 -0
- package/src/record/partial.test.mts +261 -0
- package/src/record/pick.mts +98 -0
- package/src/record/pick.test.mts +116 -0
- package/src/record/record.mts +105 -0
- package/src/record/record.test.mts +253 -0
- package/src/type.mts +30 -0
- package/src/unknown.mts +17 -0
- package/src/utils/create-assert-fn.mts +14 -0
- package/src/utils/create-cast-fn.mts +15 -0
- package/src/utils/create-is-fn.mts +7 -0
- package/src/utils/create-primitive-type.mts +35 -0
- package/src/utils/create-type.mts +28 -0
- package/src/utils/index.mts +6 -0
- package/src/utils/validation-error-message.mts +17 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { expectType } from 'ts-data-forge';
|
|
2
|
+
import { number, numberLiteral, stringLiteral } from '../primitives/index.mjs';
|
|
3
|
+
import { record } from '../record/index.mjs';
|
|
4
|
+
import { type TypeOf } from '../type.mjs';
|
|
5
|
+
import { tuple } from './tuple.mjs';
|
|
6
|
+
|
|
7
|
+
describe('tuple', () => {
|
|
8
|
+
describe('arg patterns', () => {
|
|
9
|
+
test('without explicit default value', () => {
|
|
10
|
+
expect(
|
|
11
|
+
tuple([numberLiteral(1), numberLiteral(2), numberLiteral(3)])
|
|
12
|
+
.defaultValue,
|
|
13
|
+
).toStrictEqual([1, 2, 3]);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('with explicit default value', () => {
|
|
17
|
+
expect(
|
|
18
|
+
tuple([numberLiteral(1), numberLiteral(2), numberLiteral(3)], {
|
|
19
|
+
typeName: 'tpl',
|
|
20
|
+
}).typeName,
|
|
21
|
+
).toBe('tpl');
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const targetType = tuple([
|
|
26
|
+
record({ x: number(0), y: number(0) }),
|
|
27
|
+
numberLiteral(3),
|
|
28
|
+
stringLiteral('2'),
|
|
29
|
+
]);
|
|
30
|
+
|
|
31
|
+
type TargetType = TypeOf<typeof targetType>;
|
|
32
|
+
|
|
33
|
+
expectType<
|
|
34
|
+
TargetType,
|
|
35
|
+
readonly [
|
|
36
|
+
Readonly<{
|
|
37
|
+
x: number;
|
|
38
|
+
y: number;
|
|
39
|
+
}>,
|
|
40
|
+
3,
|
|
41
|
+
'2',
|
|
42
|
+
]
|
|
43
|
+
>('=');
|
|
44
|
+
|
|
45
|
+
expectType<typeof targetType.defaultValue, TargetType>('=');
|
|
46
|
+
|
|
47
|
+
describe('is', () => {
|
|
48
|
+
test('truthy case', () => {
|
|
49
|
+
const x: unknown = [{ x: 1, y: 2 }, 3, '2'];
|
|
50
|
+
|
|
51
|
+
if (targetType.is(x)) {
|
|
52
|
+
expectType<typeof x, TargetType>('=');
|
|
53
|
+
} else {
|
|
54
|
+
expectType<typeof x, unknown>('=');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
expect(targetType.is(x)).toBe(true);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('falsy case', () => {
|
|
61
|
+
const x: unknown = [{ x: 'str', y: 'str' }, 3, '2'];
|
|
62
|
+
|
|
63
|
+
if (targetType.is(x)) {
|
|
64
|
+
expectType<typeof x, TargetType>('=');
|
|
65
|
+
} else {
|
|
66
|
+
expectType<typeof x, unknown>('=');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
expect(targetType.is(x)).toBe(false);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe('validate', () => {
|
|
74
|
+
test('falsy case', () => {
|
|
75
|
+
const x: unknown = [{ x: 'str', y: 'str' }, 3, '2'];
|
|
76
|
+
|
|
77
|
+
expect(targetType.validate(x).value).toStrictEqual([
|
|
78
|
+
`The tuple element at 0 is expected to be <{ x: number, y: number }>, but it is actually '{"x":"str","y":"str"}'.`,
|
|
79
|
+
`The value at record key "x" is expected to be <number>, but it is actually '"str"'.`,
|
|
80
|
+
`The value is expected to be <number>, but it is actually '"str"'.`,
|
|
81
|
+
]);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
describe('fill', () => {
|
|
86
|
+
test('noop', () => {
|
|
87
|
+
const x: unknown = [{ x: 1, y: 2 }, 3, '2'];
|
|
88
|
+
|
|
89
|
+
expect(targetType.fill(x)).toStrictEqual([{ x: 1, y: 2 }, 3, '2']);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test('fill with the default value', () => {
|
|
93
|
+
const x: unknown = 5;
|
|
94
|
+
|
|
95
|
+
expect(targetType.fill(x)).toStrictEqual([{ x: 0, y: 0 }, 3, '2']);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test('fill only the first element with the default value, case 1', () => {
|
|
99
|
+
const x: unknown = [123, 3, '2'];
|
|
100
|
+
|
|
101
|
+
expect(targetType.fill(x)).toStrictEqual([{ x: 0, y: 0 }, 3, '2']);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('fill only the first element with the default value, case 2', () => {
|
|
105
|
+
const x: unknown = [{ z: 5 }, 3, '2'];
|
|
106
|
+
|
|
107
|
+
expect(targetType.fill(x)).toStrictEqual([{ x: 0, y: 0 }, 3, '2']);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test('fill only the second element with the default value', () => {
|
|
111
|
+
const x: unknown = [{ x: 1, y: 2 }, 0, '2'];
|
|
112
|
+
|
|
113
|
+
expect(targetType.fill(x)).toStrictEqual([{ x: 1, y: 2 }, 3, '2']);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test('fill only the third element with the default value', () => {
|
|
117
|
+
const x: unknown = [{ x: 1, y: 2 }, 3, 999];
|
|
118
|
+
|
|
119
|
+
expect(targetType.fill(x)).toStrictEqual([{ x: 1, y: 2 }, 3, '2']);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { pipe, Result } from 'ts-data-forge';
|
|
2
|
+
import { type Type } from '../type.mjs';
|
|
3
|
+
import { createType, validationErrorMessage } from '../utils/index.mjs';
|
|
4
|
+
|
|
5
|
+
type ArrayToUnion<A extends readonly unknown[]> = A extends readonly []
|
|
6
|
+
? never
|
|
7
|
+
: A[number];
|
|
8
|
+
|
|
9
|
+
export const brand = <
|
|
10
|
+
const A extends Primitive,
|
|
11
|
+
const BrandTrueKeys extends readonly string[],
|
|
12
|
+
const BrandFalseKeys extends readonly string[] = [],
|
|
13
|
+
>({
|
|
14
|
+
codec,
|
|
15
|
+
is,
|
|
16
|
+
brandKeys,
|
|
17
|
+
brandFalseKeys,
|
|
18
|
+
defaultValue,
|
|
19
|
+
}: Readonly<{
|
|
20
|
+
codec: Type<A>;
|
|
21
|
+
is: (
|
|
22
|
+
a: A,
|
|
23
|
+
) => a is Brand<A, ArrayToUnion<BrandTrueKeys>, ArrayToUnion<BrandFalseKeys>>;
|
|
24
|
+
brandKeys: BrandTrueKeys;
|
|
25
|
+
brandFalseKeys?: BrandFalseKeys;
|
|
26
|
+
defaultValue: Brand<
|
|
27
|
+
A,
|
|
28
|
+
ArrayToUnion<BrandTrueKeys>,
|
|
29
|
+
ArrayToUnion<BrandFalseKeys>
|
|
30
|
+
>;
|
|
31
|
+
}>): Type<
|
|
32
|
+
Brand<A, ArrayToUnion<BrandTrueKeys>, ArrayToUnion<BrandFalseKeys>>
|
|
33
|
+
> => {
|
|
34
|
+
type T = Brand<A, ArrayToUnion<BrandTrueKeys>, ArrayToUnion<BrandFalseKeys>>;
|
|
35
|
+
|
|
36
|
+
const brandKeysStr = [
|
|
37
|
+
...brandKeys,
|
|
38
|
+
...(brandFalseKeys?.map((s) => `not(${s})`) ?? []),
|
|
39
|
+
].join(' & ');
|
|
40
|
+
|
|
41
|
+
const validate: Type<T>['validate'] = (a) =>
|
|
42
|
+
pipe(a)
|
|
43
|
+
.map(codec.validate)
|
|
44
|
+
.map(
|
|
45
|
+
(v): Result<T, readonly string[]> =>
|
|
46
|
+
Result.isErr(v)
|
|
47
|
+
? v
|
|
48
|
+
: is(v.value)
|
|
49
|
+
? Result.ok(v.value)
|
|
50
|
+
: Result.err([
|
|
51
|
+
validationErrorMessage(
|
|
52
|
+
v.value,
|
|
53
|
+
`The value must satisfy the constraint corresponding to the brand keys: <${brandKeysStr}>`,
|
|
54
|
+
),
|
|
55
|
+
]),
|
|
56
|
+
).value;
|
|
57
|
+
|
|
58
|
+
const fill: Type<T>['fill'] = (a) =>
|
|
59
|
+
Result.unwrapOkOr(
|
|
60
|
+
validate(a) satisfies Result<T, unknown>,
|
|
61
|
+
defaultValue satisfies T,
|
|
62
|
+
) satisfies T;
|
|
63
|
+
|
|
64
|
+
return createType({
|
|
65
|
+
typeName: brandKeysStr,
|
|
66
|
+
defaultValue,
|
|
67
|
+
validate,
|
|
68
|
+
fill,
|
|
69
|
+
});
|
|
70
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { asFiniteNumber, FiniteNumber } from 'ts-data-forge';
|
|
2
|
+
import { number } from '../../primitives/index.mjs';
|
|
3
|
+
import { type Type } from '../../type.mjs';
|
|
4
|
+
import { brand } from '../brand.mjs';
|
|
5
|
+
|
|
6
|
+
export const finiteNumber = (
|
|
7
|
+
defaultValue: FiniteNumber = asFiniteNumber(0),
|
|
8
|
+
): Type<FiniteNumber> =>
|
|
9
|
+
brand({
|
|
10
|
+
codec: number(defaultValue),
|
|
11
|
+
is: FiniteNumber.is,
|
|
12
|
+
defaultValue,
|
|
13
|
+
brandKeys: ['Finite'],
|
|
14
|
+
brandFalseKeys: ['NaNValue'],
|
|
15
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export * from './finite-number.mjs';
|
|
2
|
+
export * from './int.mjs';
|
|
3
|
+
export * from './int16.mjs';
|
|
4
|
+
export * from './int32.mjs';
|
|
5
|
+
export * from './non-negative-finite-number.mjs';
|
|
6
|
+
export * from './non-zero-finite-number.mjs';
|
|
7
|
+
export * from './non-zero-int.mjs';
|
|
8
|
+
export * from './non-zero-safe-int.mjs';
|
|
9
|
+
export * from './positive-finite-number.mjs';
|
|
10
|
+
export * from './positive-int.mjs';
|
|
11
|
+
export * from './positive-safe-int.mjs';
|
|
12
|
+
export * from './safe-int.mjs';
|
|
13
|
+
export * from './safe-uint.mjs';
|
|
14
|
+
export * from './uint.mjs';
|
|
15
|
+
export * from './uint16.mjs';
|
|
16
|
+
export * from './uint32.mjs';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { asInt, Int } from 'ts-data-forge';
|
|
2
|
+
import { number } from '../../primitives/index.mjs';
|
|
3
|
+
import { type Type } from '../../type.mjs';
|
|
4
|
+
import { brand } from '../brand.mjs';
|
|
5
|
+
|
|
6
|
+
export const int = (defaultValue: Int = asInt(0)): Type<Int> =>
|
|
7
|
+
brand({
|
|
8
|
+
codec: number(defaultValue),
|
|
9
|
+
is: Int.is,
|
|
10
|
+
defaultValue,
|
|
11
|
+
brandKeys: ['Finite', 'Int'],
|
|
12
|
+
brandFalseKeys: ['NaNValue'],
|
|
13
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { asInt16, isInt16 } from 'ts-data-forge';
|
|
2
|
+
import { number } from '../../primitives/index.mjs';
|
|
3
|
+
import { type Type } from '../../type.mjs';
|
|
4
|
+
import { brand } from '../brand.mjs';
|
|
5
|
+
|
|
6
|
+
export const int16 = (defaultValue: Int16 = asInt16(0)): Type<Int16> =>
|
|
7
|
+
brand({
|
|
8
|
+
codec: number(defaultValue),
|
|
9
|
+
is: isInt16,
|
|
10
|
+
defaultValue,
|
|
11
|
+
brandKeys: [
|
|
12
|
+
'Finite',
|
|
13
|
+
'Int',
|
|
14
|
+
'SafeInt',
|
|
15
|
+
'> -2^32',
|
|
16
|
+
'>= -2^31',
|
|
17
|
+
'< 2^32',
|
|
18
|
+
'< 2^31',
|
|
19
|
+
'< 2^15',
|
|
20
|
+
'< 2^16',
|
|
21
|
+
'> -2^16',
|
|
22
|
+
'>= -2^15',
|
|
23
|
+
],
|
|
24
|
+
brandFalseKeys: ['NaNValue'],
|
|
25
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { asInt32, isInt32 } from 'ts-data-forge';
|
|
2
|
+
import { number } from '../../primitives/index.mjs';
|
|
3
|
+
import { type Type } from '../../type.mjs';
|
|
4
|
+
import { brand } from '../brand.mjs';
|
|
5
|
+
|
|
6
|
+
export const int32 = (defaultValue: Int32 = asInt32(0)): Type<Int32> =>
|
|
7
|
+
brand({
|
|
8
|
+
codec: number(defaultValue),
|
|
9
|
+
is: isInt32,
|
|
10
|
+
defaultValue,
|
|
11
|
+
brandKeys: [
|
|
12
|
+
'Finite',
|
|
13
|
+
'Int',
|
|
14
|
+
'SafeInt',
|
|
15
|
+
'> -2^32',
|
|
16
|
+
'>= -2^31',
|
|
17
|
+
'< 2^32',
|
|
18
|
+
'< 2^31',
|
|
19
|
+
],
|
|
20
|
+
brandFalseKeys: ['NaNValue'],
|
|
21
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
asNonNegativeFiniteNumber,
|
|
3
|
+
isNonNegativeFiniteNumber,
|
|
4
|
+
} from 'ts-data-forge';
|
|
5
|
+
import { number } from '../../primitives/index.mjs';
|
|
6
|
+
import { type Type } from '../../type.mjs';
|
|
7
|
+
import { brand } from '../brand.mjs';
|
|
8
|
+
|
|
9
|
+
export const nonNegativeFiniteNumber = (
|
|
10
|
+
defaultValue: NonNegativeFiniteNumber = asNonNegativeFiniteNumber(0),
|
|
11
|
+
): Type<NonNegativeFiniteNumber> =>
|
|
12
|
+
brand({
|
|
13
|
+
codec: number(defaultValue),
|
|
14
|
+
is: isNonNegativeFiniteNumber,
|
|
15
|
+
defaultValue,
|
|
16
|
+
brandKeys: ['>=0', '> -2^16', '> -2^32', '>= -2^15', '>= -2^31', 'Finite'],
|
|
17
|
+
brandFalseKeys: ['NaNValue'],
|
|
18
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { isNonZeroFiniteNumber } from 'ts-data-forge';
|
|
2
|
+
import { number } from '../../primitives/index.mjs';
|
|
3
|
+
import { type Type } from '../../type.mjs';
|
|
4
|
+
import { brand } from '../brand.mjs';
|
|
5
|
+
|
|
6
|
+
export const nonZeroFiniteNumber = (
|
|
7
|
+
defaultValue: NonZeroFiniteNumber,
|
|
8
|
+
): Type<NonZeroFiniteNumber> =>
|
|
9
|
+
brand({
|
|
10
|
+
codec: number(defaultValue),
|
|
11
|
+
is: isNonZeroFiniteNumber,
|
|
12
|
+
defaultValue,
|
|
13
|
+
brandKeys: ['!=0', 'Finite'],
|
|
14
|
+
brandFalseKeys: ['NaNValue'],
|
|
15
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { asNonZeroInt, isNonZeroInt } from 'ts-data-forge';
|
|
2
|
+
import { number } from '../../primitives/index.mjs';
|
|
3
|
+
import { type Type } from '../../type.mjs';
|
|
4
|
+
import { brand } from '../brand.mjs';
|
|
5
|
+
|
|
6
|
+
export const nonZeroInt = (
|
|
7
|
+
defaultValue: NonZeroInt = asNonZeroInt(0),
|
|
8
|
+
): Type<NonZeroInt> =>
|
|
9
|
+
brand({
|
|
10
|
+
codec: number(defaultValue),
|
|
11
|
+
is: isNonZeroInt,
|
|
12
|
+
defaultValue,
|
|
13
|
+
brandKeys: ['Finite', 'Int', '!=0'],
|
|
14
|
+
brandFalseKeys: ['NaNValue'],
|
|
15
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { isNonZeroSafeInt } from 'ts-data-forge';
|
|
2
|
+
import { number } from '../../primitives/index.mjs';
|
|
3
|
+
import { type Type } from '../../type.mjs';
|
|
4
|
+
import { brand } from '../brand.mjs';
|
|
5
|
+
|
|
6
|
+
export const nonZeroSafeInt = (
|
|
7
|
+
defaultValue: NonZeroSafeInt,
|
|
8
|
+
): Type<NonZeroSafeInt> =>
|
|
9
|
+
brand({
|
|
10
|
+
codec: number(defaultValue),
|
|
11
|
+
is: isNonZeroSafeInt,
|
|
12
|
+
defaultValue,
|
|
13
|
+
brandKeys: ['Finite', 'Int', 'SafeInt', '!=0'],
|
|
14
|
+
brandFalseKeys: ['NaNValue'],
|
|
15
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { isPositiveFiniteNumber } from 'ts-data-forge';
|
|
2
|
+
import { number } from '../../primitives/index.mjs';
|
|
3
|
+
import { type Type } from '../../type.mjs';
|
|
4
|
+
import { brand } from '../brand.mjs';
|
|
5
|
+
|
|
6
|
+
export const positiveFiniteNumber = (
|
|
7
|
+
defaultValue: PositiveFiniteNumber,
|
|
8
|
+
): Type<PositiveFiniteNumber> =>
|
|
9
|
+
brand({
|
|
10
|
+
codec: number(defaultValue),
|
|
11
|
+
is: isPositiveFiniteNumber,
|
|
12
|
+
defaultValue,
|
|
13
|
+
brandKeys: [
|
|
14
|
+
'>=0',
|
|
15
|
+
'> -2^16',
|
|
16
|
+
'> -2^32',
|
|
17
|
+
'>= -2^15',
|
|
18
|
+
'>= -2^31',
|
|
19
|
+
'Finite',
|
|
20
|
+
'!=0',
|
|
21
|
+
],
|
|
22
|
+
brandFalseKeys: ['NaNValue'],
|
|
23
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { asPositiveInt, isPositiveInt } from 'ts-data-forge';
|
|
2
|
+
import { number } from '../../primitives/index.mjs';
|
|
3
|
+
import { type Type } from '../../type.mjs';
|
|
4
|
+
import { brand } from '../brand.mjs';
|
|
5
|
+
|
|
6
|
+
export const positiveInt = (
|
|
7
|
+
defaultValue: PositiveInt = asPositiveInt(1),
|
|
8
|
+
): Type<PositiveInt> =>
|
|
9
|
+
brand({
|
|
10
|
+
codec: number(defaultValue),
|
|
11
|
+
is: isPositiveInt,
|
|
12
|
+
defaultValue,
|
|
13
|
+
brandKeys: [
|
|
14
|
+
'Finite',
|
|
15
|
+
'Int',
|
|
16
|
+
'> -2^32',
|
|
17
|
+
'>= -2^31',
|
|
18
|
+
'> -2^16',
|
|
19
|
+
'>= -2^15',
|
|
20
|
+
'>=0',
|
|
21
|
+
'!=0',
|
|
22
|
+
],
|
|
23
|
+
brandFalseKeys: ['NaNValue'],
|
|
24
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { asPositiveSafeInt, isPositiveSafeInt } from 'ts-data-forge';
|
|
2
|
+
import { number } from '../../primitives/index.mjs';
|
|
3
|
+
import { type Type } from '../../type.mjs';
|
|
4
|
+
import { brand } from '../brand.mjs';
|
|
5
|
+
|
|
6
|
+
export const positiveSafeInt = (
|
|
7
|
+
defaultValue: PositiveSafeInt = asPositiveSafeInt(1),
|
|
8
|
+
): Type<PositiveSafeInt> =>
|
|
9
|
+
brand({
|
|
10
|
+
codec: number(defaultValue),
|
|
11
|
+
is: isPositiveSafeInt,
|
|
12
|
+
defaultValue,
|
|
13
|
+
brandKeys: [
|
|
14
|
+
'Finite',
|
|
15
|
+
'Int',
|
|
16
|
+
'SafeInt',
|
|
17
|
+
'> -2^32',
|
|
18
|
+
'>= -2^31',
|
|
19
|
+
'> -2^16',
|
|
20
|
+
'>= -2^15',
|
|
21
|
+
'>=0',
|
|
22
|
+
'!=0',
|
|
23
|
+
],
|
|
24
|
+
brandFalseKeys: ['NaNValue'],
|
|
25
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { asSafeInt, SafeInt } from 'ts-data-forge';
|
|
2
|
+
import { number } from '../../primitives/index.mjs';
|
|
3
|
+
import { type Type } from '../../type.mjs';
|
|
4
|
+
import { brand } from '../brand.mjs';
|
|
5
|
+
|
|
6
|
+
export const safeInt = (defaultValue: SafeInt = asSafeInt(0)): Type<SafeInt> =>
|
|
7
|
+
brand({
|
|
8
|
+
codec: number(defaultValue),
|
|
9
|
+
is: SafeInt.is,
|
|
10
|
+
defaultValue,
|
|
11
|
+
brandKeys: ['Finite', 'Int', 'SafeInt'],
|
|
12
|
+
brandFalseKeys: ['NaNValue'],
|
|
13
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { asSafeUint, isSafeUint } from 'ts-data-forge';
|
|
2
|
+
import { number } from '../../primitives/index.mjs';
|
|
3
|
+
import { type Type } from '../../type.mjs';
|
|
4
|
+
import { brand } from '../brand.mjs';
|
|
5
|
+
|
|
6
|
+
export const safeUint = (
|
|
7
|
+
defaultValue: SafeUint = asSafeUint(0),
|
|
8
|
+
): Type<SafeUint> =>
|
|
9
|
+
brand({
|
|
10
|
+
codec: number(defaultValue),
|
|
11
|
+
is: isSafeUint,
|
|
12
|
+
defaultValue,
|
|
13
|
+
brandKeys: [
|
|
14
|
+
'Finite',
|
|
15
|
+
'Int',
|
|
16
|
+
'SafeInt',
|
|
17
|
+
'> -2^16',
|
|
18
|
+
'> -2^32',
|
|
19
|
+
'>= -2^15',
|
|
20
|
+
'>= -2^31',
|
|
21
|
+
'>=0',
|
|
22
|
+
],
|
|
23
|
+
brandFalseKeys: ['NaNValue'],
|
|
24
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { asUint, isUint } from 'ts-data-forge';
|
|
2
|
+
import { number } from '../../primitives/index.mjs';
|
|
3
|
+
import { type Type } from '../../type.mjs';
|
|
4
|
+
import { brand } from '../brand.mjs';
|
|
5
|
+
|
|
6
|
+
export const uint = (defaultValue: Uint = asUint(0)): Type<Uint> =>
|
|
7
|
+
brand({
|
|
8
|
+
codec: number(defaultValue),
|
|
9
|
+
is: isUint,
|
|
10
|
+
defaultValue,
|
|
11
|
+
brandKeys: [
|
|
12
|
+
'Finite',
|
|
13
|
+
'Int',
|
|
14
|
+
'> -2^32',
|
|
15
|
+
'>= -2^31',
|
|
16
|
+
'> -2^16',
|
|
17
|
+
'>= -2^15',
|
|
18
|
+
'>=0',
|
|
19
|
+
],
|
|
20
|
+
brandFalseKeys: ['NaNValue'],
|
|
21
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { asUint16, isUint16 } from 'ts-data-forge';
|
|
2
|
+
import { number } from '../../primitives/index.mjs';
|
|
3
|
+
import { type Type } from '../../type.mjs';
|
|
4
|
+
import { brand } from '../brand.mjs';
|
|
5
|
+
|
|
6
|
+
export const uint16 = (defaultValue: Uint16 = asUint16(0)): Type<Uint16> =>
|
|
7
|
+
brand({
|
|
8
|
+
codec: number(defaultValue),
|
|
9
|
+
is: isUint16,
|
|
10
|
+
defaultValue,
|
|
11
|
+
brandKeys: [
|
|
12
|
+
'Finite',
|
|
13
|
+
'Int',
|
|
14
|
+
'SafeInt',
|
|
15
|
+
'> -2^16',
|
|
16
|
+
'> -2^32',
|
|
17
|
+
'>= -2^15',
|
|
18
|
+
'>= -2^31',
|
|
19
|
+
'>=0',
|
|
20
|
+
'< 2^32',
|
|
21
|
+
'< 2^16',
|
|
22
|
+
'< 2^31',
|
|
23
|
+
],
|
|
24
|
+
brandFalseKeys: ['NaNValue'],
|
|
25
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { asUint32, isUint32 } from 'ts-data-forge';
|
|
2
|
+
import { number } from '../../primitives/index.mjs';
|
|
3
|
+
import { type Type } from '../../type.mjs';
|
|
4
|
+
import { brand } from '../brand.mjs';
|
|
5
|
+
|
|
6
|
+
export const uint32 = (defaultValue: Uint32 = asUint32(0)): Type<Uint32> =>
|
|
7
|
+
brand({
|
|
8
|
+
codec: number(defaultValue),
|
|
9
|
+
is: isUint32,
|
|
10
|
+
defaultValue,
|
|
11
|
+
brandKeys: [
|
|
12
|
+
'Finite',
|
|
13
|
+
'Int',
|
|
14
|
+
'SafeInt',
|
|
15
|
+
'> -2^16',
|
|
16
|
+
'> -2^32',
|
|
17
|
+
'>= -2^15',
|
|
18
|
+
'>= -2^31',
|
|
19
|
+
'>=0',
|
|
20
|
+
'< 2^32',
|
|
21
|
+
],
|
|
22
|
+
brandFalseKeys: ['NaNValue'],
|
|
23
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { number } from '../primitives/index.mjs';
|
|
2
|
+
import { type Type } from '../type.mjs';
|
|
3
|
+
import { brand } from './brand.mjs';
|
|
4
|
+
|
|
5
|
+
export const simpleBrandedNumber = <S extends string>(
|
|
6
|
+
typeName: S,
|
|
7
|
+
defaultValue: number = 0,
|
|
8
|
+
): Type<Brand<number, S>> =>
|
|
9
|
+
brand({
|
|
10
|
+
codec: number(defaultValue),
|
|
11
|
+
|
|
12
|
+
defaultValue:
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
14
|
+
defaultValue as Brand<number, S>,
|
|
15
|
+
|
|
16
|
+
is: (_id: number): _id is Brand<number, S> => true,
|
|
17
|
+
brandKeys: [typeName],
|
|
18
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { string } from '../primitives/index.mjs';
|
|
2
|
+
import { type Type } from '../type.mjs';
|
|
3
|
+
import { brand } from './brand.mjs';
|
|
4
|
+
|
|
5
|
+
export const simpleBrandedString = <S extends string>(
|
|
6
|
+
typeName: S,
|
|
7
|
+
defaultValue: string = '',
|
|
8
|
+
): Type<Brand<string, S>> =>
|
|
9
|
+
brand({
|
|
10
|
+
codec: string(defaultValue),
|
|
11
|
+
|
|
12
|
+
defaultValue:
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
14
|
+
defaultValue as Brand<string, S>,
|
|
15
|
+
|
|
16
|
+
is: (_id: string): _id is Brand<string, S> => true,
|
|
17
|
+
brandKeys: [typeName],
|
|
18
|
+
});
|