typesea 0.1.0 → 0.3.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/CHANGELOG.md +85 -6
- package/README.md +143 -28
- package/dist/adapters/index.d.ts +50 -8
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +169 -48
- package/dist/aot/index.d.ts +19 -3
- package/dist/aot/index.d.ts.map +1 -1
- package/dist/aot/index.js +115 -17
- package/dist/async/index.d.ts +28 -56
- package/dist/async/index.d.ts.map +1 -1
- package/dist/async/index.js +94 -37
- package/dist/builders/composite.d.ts +43 -9
- package/dist/builders/composite.d.ts.map +1 -1
- package/dist/builders/composite.js +100 -17
- package/dist/builders/index.d.ts +8 -5
- package/dist/builders/index.d.ts.map +1 -1
- package/dist/builders/index.js +7 -4
- package/dist/builders/modifier.d.ts +36 -5
- package/dist/builders/modifier.d.ts.map +1 -1
- package/dist/builders/modifier.js +52 -5
- package/dist/builders/object/guard.d.ts +72 -24
- package/dist/builders/object/guard.d.ts.map +1 -1
- package/dist/builders/object/guard.js +139 -29
- package/dist/builders/object/index.d.ts +4 -2
- package/dist/builders/object/index.d.ts.map +1 -1
- package/dist/builders/object/index.js +3 -1
- package/dist/builders/object/schema.d.ts +88 -11
- package/dist/builders/object/schema.d.ts.map +1 -1
- package/dist/builders/object/schema.js +290 -23
- package/dist/builders/object/types.d.ts +20 -31
- package/dist/builders/object/types.d.ts.map +1 -1
- package/dist/builders/object/types.js +2 -0
- package/dist/builders/runtime.d.ts +40 -0
- package/dist/builders/runtime.d.ts.map +1 -0
- package/dist/builders/runtime.js +150 -0
- package/dist/builders/scalar.d.ts +49 -9
- package/dist/builders/scalar.d.ts.map +1 -1
- package/dist/builders/scalar.js +87 -9
- package/dist/builders/table.d.ts +35 -5
- package/dist/builders/table.d.ts.map +1 -1
- package/dist/builders/table.js +35 -5
- package/dist/builders/types.d.ts +20 -4
- package/dist/builders/types.d.ts.map +1 -1
- package/dist/builders/types.js +2 -0
- package/dist/compile/check-composite.d.ts +25 -2
- package/dist/compile/check-composite.d.ts.map +1 -1
- package/dist/compile/check-composite.js +699 -27
- package/dist/compile/check-scalar.d.ts +88 -0
- package/dist/compile/check-scalar.d.ts.map +1 -1
- package/dist/compile/check-scalar.js +570 -3
- package/dist/compile/check.d.ts +12 -0
- package/dist/compile/check.d.ts.map +1 -1
- package/dist/compile/check.js +62 -3
- package/dist/compile/context.d.ts +47 -9
- package/dist/compile/context.d.ts.map +1 -1
- package/dist/compile/context.js +53 -8
- package/dist/compile/first.d.ts +26 -0
- package/dist/compile/first.d.ts.map +1 -0
- package/dist/compile/first.js +850 -0
- package/dist/compile/graph-predicate.d.ts +4 -2
- package/dist/compile/graph-predicate.d.ts.map +1 -1
- package/dist/compile/graph-predicate.js +2272 -165
- package/dist/compile/guard.d.ts +16 -24
- package/dist/compile/guard.d.ts.map +1 -1
- package/dist/compile/guard.js +202 -72
- package/dist/compile/index.d.ts +3 -1
- package/dist/compile/index.d.ts.map +1 -1
- package/dist/compile/index.js +2 -0
- package/dist/compile/issue.d.ts +110 -0
- package/dist/compile/issue.d.ts.map +1 -1
- package/dist/compile/issue.js +184 -1
- package/dist/compile/names.d.ts +12 -2
- package/dist/compile/names.d.ts.map +1 -1
- package/dist/compile/names.js +19 -3
- package/dist/compile/predicate.d.ts +24 -0
- package/dist/compile/predicate.d.ts.map +1 -1
- package/dist/compile/predicate.js +287 -10
- package/dist/compile/runtime.d.ts +100 -13
- package/dist/compile/runtime.d.ts.map +1 -1
- package/dist/compile/runtime.js +56 -6
- package/dist/compile/source.d.ts +10 -2
- package/dist/compile/source.d.ts.map +1 -1
- package/dist/compile/source.js +385 -26
- package/dist/compile/types.d.ts +22 -0
- package/dist/compile/types.d.ts.map +1 -1
- package/dist/compile/types.js +2 -0
- package/dist/decoder/index.d.ts +92 -46
- package/dist/decoder/index.d.ts.map +1 -1
- package/dist/decoder/index.js +266 -39
- package/dist/evaluate/check-composite.d.ts +111 -2
- package/dist/evaluate/check-composite.d.ts.map +1 -1
- package/dist/evaluate/check-composite.js +343 -8
- package/dist/evaluate/check-scalar.d.ts +25 -0
- package/dist/evaluate/check-scalar.d.ts.map +1 -1
- package/dist/evaluate/check-scalar.js +124 -3
- package/dist/evaluate/check.d.ts +7 -0
- package/dist/evaluate/check.d.ts.map +1 -1
- package/dist/evaluate/check.js +62 -4
- package/dist/evaluate/index.d.ts +2 -0
- package/dist/evaluate/index.d.ts.map +1 -1
- package/dist/evaluate/index.js +2 -0
- package/dist/evaluate/issue.d.ts +11 -1
- package/dist/evaluate/issue.d.ts.map +1 -1
- package/dist/evaluate/issue.js +15 -1
- package/dist/evaluate/predicate.d.ts +16 -5
- package/dist/evaluate/predicate.d.ts.map +1 -1
- package/dist/evaluate/predicate.js +20 -5
- package/dist/evaluate/shared.d.ts +78 -13
- package/dist/evaluate/shared.d.ts.map +1 -1
- package/dist/evaluate/shared.js +101 -8
- package/dist/evaluate/state.d.ts +35 -13
- package/dist/evaluate/state.d.ts.map +1 -1
- package/dist/evaluate/state.js +35 -2
- package/dist/guard/array.d.ts +48 -0
- package/dist/guard/array.d.ts.map +1 -0
- package/dist/guard/array.js +84 -0
- package/dist/guard/base.d.ts +111 -31
- package/dist/guard/base.d.ts.map +1 -1
- package/dist/guard/base.js +165 -32
- package/dist/guard/date.d.ts +34 -0
- package/dist/guard/date.d.ts.map +1 -0
- package/dist/guard/date.js +60 -0
- package/dist/guard/error.d.ts +10 -5
- package/dist/guard/error.d.ts.map +1 -1
- package/dist/guard/error.js +10 -5
- package/dist/guard/index.d.ts +4 -0
- package/dist/guard/index.d.ts.map +1 -1
- package/dist/guard/index.js +4 -0
- package/dist/guard/number.d.ts +86 -11
- package/dist/guard/number.d.ts.map +1 -1
- package/dist/guard/number.js +159 -11
- package/dist/guard/props.d.ts +27 -3
- package/dist/guard/props.d.ts.map +1 -1
- package/dist/guard/props.js +27 -3
- package/dist/guard/read.d.ts +115 -10
- package/dist/guard/read.d.ts.map +1 -1
- package/dist/guard/read.js +185 -10
- package/dist/guard/registry.d.ts +12 -2
- package/dist/guard/registry.d.ts.map +1 -1
- package/dist/guard/registry.js +15 -3
- package/dist/guard/string.d.ts +115 -13
- package/dist/guard/string.d.ts.map +1 -1
- package/dist/guard/string.js +250 -13
- package/dist/guard/types.d.ts +110 -40
- package/dist/guard/types.d.ts.map +1 -1
- package/dist/guard/types.js +2 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/internal/index.d.ts +42 -6
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +51 -8
- package/dist/ir/builder.d.ts +17 -127
- package/dist/ir/builder.d.ts.map +1 -1
- package/dist/ir/builder.js +80 -137
- package/dist/ir/freeze.d.ts +4 -0
- package/dist/ir/freeze.d.ts.map +1 -1
- package/dist/ir/freeze.js +66 -0
- package/dist/ir/index.d.ts +3 -1
- package/dist/ir/index.d.ts.map +1 -1
- package/dist/ir/index.js +2 -0
- package/dist/ir/regexp.d.ts +2 -0
- package/dist/ir/regexp.d.ts.map +1 -1
- package/dist/ir/regexp.js +2 -0
- package/dist/ir/types.d.ts +94 -56
- package/dist/ir/types.d.ts.map +1 -1
- package/dist/ir/types.js +2 -0
- package/dist/ir/validate.d.ts +8 -1
- package/dist/ir/validate.d.ts.map +1 -1
- package/dist/ir/validate.js +511 -61
- package/dist/issue/index.d.ts +42 -10
- package/dist/issue/index.d.ts.map +1 -1
- package/dist/issue/index.js +65 -11
- package/dist/json-schema/emit-combinator.d.ts +44 -4
- package/dist/json-schema/emit-combinator.d.ts.map +1 -1
- package/dist/json-schema/emit-combinator.js +44 -4
- package/dist/json-schema/emit-composite.d.ts +16 -2
- package/dist/json-schema/emit-composite.d.ts.map +1 -1
- package/dist/json-schema/emit-composite.js +81 -13
- package/dist/json-schema/emit-scalar.d.ts +26 -3
- package/dist/json-schema/emit-scalar.d.ts.map +1 -1
- package/dist/json-schema/emit-scalar.js +124 -10
- package/dist/json-schema/emit-types.d.ts +11 -1
- package/dist/json-schema/emit-types.d.ts.map +1 -1
- package/dist/json-schema/emit-types.js +2 -0
- package/dist/json-schema/emit.d.ts +12 -1
- package/dist/json-schema/emit.d.ts.map +1 -1
- package/dist/json-schema/emit.js +23 -3
- package/dist/json-schema/freeze.d.ts +13 -2
- package/dist/json-schema/freeze.d.ts.map +1 -1
- package/dist/json-schema/freeze.js +41 -8
- package/dist/json-schema/index.d.ts +16 -2
- package/dist/json-schema/index.d.ts.map +1 -1
- package/dist/json-schema/index.js +23 -3
- package/dist/json-schema/issue.d.ts +4 -1
- package/dist/json-schema/issue.d.ts.map +1 -1
- package/dist/json-schema/issue.js +4 -1
- package/dist/json-schema/read.d.ts +24 -3
- package/dist/json-schema/read.d.ts.map +1 -1
- package/dist/json-schema/read.js +59 -12
- package/dist/json-schema/types.d.ts +45 -16
- package/dist/json-schema/types.d.ts.map +1 -1
- package/dist/json-schema/types.js +2 -0
- package/dist/kind/index.d.ts +40 -28
- package/dist/kind/index.d.ts.map +1 -1
- package/dist/kind/index.js +41 -13
- package/dist/lower/index.d.ts +6 -1
- package/dist/lower/index.d.ts.map +1 -1
- package/dist/lower/index.js +462 -46
- package/dist/message/index.d.ts +64 -10
- package/dist/message/index.d.ts.map +1 -1
- package/dist/message/index.js +155 -17
- package/dist/optimize/algebraic.d.ts +54 -0
- package/dist/optimize/algebraic.d.ts.map +1 -0
- package/dist/optimize/algebraic.js +314 -0
- package/dist/optimize/compact.d.ts +8 -1
- package/dist/optimize/compact.d.ts.map +1 -1
- package/dist/optimize/compact.js +13 -2
- package/dist/optimize/domain.d.ts +16 -0
- package/dist/optimize/domain.d.ts.map +1 -0
- package/dist/optimize/domain.js +619 -0
- package/dist/optimize/fold-boolean.d.ts +17 -2
- package/dist/optimize/fold-boolean.d.ts.map +1 -1
- package/dist/optimize/fold-boolean.js +59 -14
- package/dist/optimize/fold-common.d.ts +43 -8
- package/dist/optimize/fold-common.d.ts.map +1 -1
- package/dist/optimize/fold-common.js +37 -6
- package/dist/optimize/fold-constraints.d.ts +33 -0
- package/dist/optimize/fold-constraints.d.ts.map +1 -0
- package/dist/optimize/fold-constraints.js +484 -0
- package/dist/optimize/fold-scalar.d.ts +98 -13
- package/dist/optimize/fold-scalar.d.ts.map +1 -1
- package/dist/optimize/fold-scalar.js +98 -13
- package/dist/optimize/fold.d.ts +8 -1
- package/dist/optimize/fold.d.ts.map +1 -1
- package/dist/optimize/fold.js +22 -2
- package/dist/optimize/index.d.ts +9 -1
- package/dist/optimize/index.d.ts.map +1 -1
- package/dist/optimize/index.js +18 -3
- package/dist/optimize/map-node.d.ts +3 -1
- package/dist/optimize/map-node.d.ts.map +1 -1
- package/dist/optimize/map-node.js +48 -3
- package/dist/optimize/peephole.d.ts +16 -0
- package/dist/optimize/peephole.d.ts.map +1 -0
- package/dist/optimize/peephole.js +254 -0
- package/dist/optimize/remap.d.ts +2 -0
- package/dist/optimize/remap.d.ts.map +1 -1
- package/dist/optimize/remap.js +2 -0
- package/dist/optimize/rewrite.d.ts +13 -8
- package/dist/optimize/rewrite.d.ts.map +1 -1
- package/dist/optimize/rewrite.js +13 -8
- package/dist/plan/cache.d.ts +9 -3
- package/dist/plan/cache.d.ts.map +1 -1
- package/dist/plan/cache.js +34 -6
- package/dist/plan/index.d.ts +2 -0
- package/dist/plan/index.d.ts.map +1 -1
- package/dist/plan/index.js +2 -0
- package/dist/plan/predicate.d.ts +2 -0
- package/dist/plan/predicate.d.ts.map +1 -1
- package/dist/plan/predicate.js +298 -29
- package/dist/plan/schema-predicate.d.ts +6 -0
- package/dist/plan/schema-predicate.d.ts.map +1 -1
- package/dist/plan/schema-predicate.js +382 -19
- package/dist/plan/types.d.ts +2 -0
- package/dist/plan/types.d.ts.map +1 -1
- package/dist/plan/types.js +2 -0
- package/dist/result/index.d.ts +19 -5
- package/dist/result/index.d.ts.map +1 -1
- package/dist/result/index.js +10 -2
- package/dist/schema/common.d.ts +69 -6
- package/dist/schema/common.d.ts.map +1 -1
- package/dist/schema/common.js +104 -10
- package/dist/schema/freeze.d.ts +4 -0
- package/dist/schema/freeze.d.ts.map +1 -1
- package/dist/schema/freeze.js +40 -0
- package/dist/schema/index.d.ts +5 -2
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +4 -1
- package/dist/schema/lazy.d.ts +4 -0
- package/dist/schema/lazy.d.ts.map +1 -1
- package/dist/schema/lazy.js +4 -0
- package/dist/schema/literal.d.ts +7 -1
- package/dist/schema/literal.d.ts.map +1 -1
- package/dist/schema/literal.js +7 -1
- package/dist/schema/types.d.ts +109 -100
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +13 -2
- package/dist/schema/undefined.d.ts +17 -0
- package/dist/schema/undefined.d.ts.map +1 -0
- package/dist/schema/undefined.js +77 -0
- package/dist/schema/validate.d.ts +8 -1
- package/dist/schema/validate.d.ts.map +1 -1
- package/dist/schema/validate.js +255 -57
- package/docs/api.md +128 -8
- package/docs/assets/benchmark-headline.svg +163 -0
- package/docs/engine-notes.md +62 -15
- package/docs/index.html +1340 -702
- package/docs/ko/api.md +375 -0
- package/docs/ko/engine-notes.md +156 -0
- package/docs/ko/readme.md +378 -0
- package/package.json +66 -65
|
@@ -1,59 +1,124 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file shared.ts
|
|
3
3
|
* @brief Shared scalar helpers for schema evaluation.
|
|
4
|
+
* @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
|
|
5
|
+
* aligned with compiled behavior.
|
|
4
6
|
*/
|
|
5
7
|
import type { DiscriminatedUnionCase, LiteralValue, ObjectKeyLookup, Schema } from "../schema/index.js";
|
|
6
8
|
/**
|
|
7
|
-
* @brief
|
|
9
|
+
* @brief Object shape accepted by object and record validators.
|
|
10
|
+
* @details Values stay indexed by string keys only after the caller proves the
|
|
11
|
+
* input is not null and not an array.
|
|
8
12
|
*/
|
|
9
13
|
export type UnknownRecord = Readonly<Record<string, unknown>>;
|
|
10
14
|
/**
|
|
11
|
-
* @brief
|
|
12
|
-
* @details
|
|
15
|
+
* @brief Descriptor subset safe for validation reads.
|
|
16
|
+
* @details Only data descriptors are accepted because accessor descriptors can
|
|
17
|
+
* execute user code and can return different values across reads.
|
|
13
18
|
* @invariant Accessor descriptors never match this contract.
|
|
14
19
|
*/
|
|
15
20
|
export interface DataPropertyDescriptor {
|
|
16
21
|
/**
|
|
17
|
-
* @brief value.
|
|
18
|
-
* @details The
|
|
22
|
+
* @brief Captured property value.
|
|
23
|
+
* @details The value remains unknown until a schema-specific validator consumes it.
|
|
19
24
|
* @invariant Accessing this field does not execute user getter code.
|
|
20
25
|
*/
|
|
21
26
|
readonly value: unknown;
|
|
22
27
|
}
|
|
23
28
|
/**
|
|
24
|
-
* @brief
|
|
29
|
+
* @brief Check membership in an object schema key lookup.
|
|
30
|
+
* @param keyLookup Null-prototype lookup generated by object schema construction.
|
|
31
|
+
* @param key Candidate own key.
|
|
32
|
+
* @returns True when the key belongs to the schema shape.
|
|
33
|
+
* @details The lookup is used instead of `in` so prototype pollution cannot make
|
|
34
|
+
* an undeclared key appear valid.
|
|
25
35
|
*/
|
|
26
36
|
export declare function hasObjectKey(keyLookup: ObjectKeyLookup, key: string): boolean;
|
|
27
37
|
/**
|
|
28
|
-
* @brief
|
|
38
|
+
* @brief Read one own data property from a runtime object.
|
|
29
39
|
* @details Reads one own property through its descriptor so getters are not executed.
|
|
40
|
+
* @param record Plain object being validated.
|
|
41
|
+
* @param key Own key to inspect.
|
|
30
42
|
* @returns Own data descriptor, or undefined for missing/accessor properties.
|
|
31
43
|
*/
|
|
32
44
|
export declare function readOwnDataProperty(record: UnknownRecord, key: string): DataPropertyDescriptor | undefined;
|
|
33
45
|
/**
|
|
34
|
-
* @brief
|
|
46
|
+
* @brief Select a discriminated-union branch by its literal tag value.
|
|
47
|
+
* @details The case list is already builder-validated for unique literals, so a
|
|
48
|
+
* linear scan is enough for interpreter diagnostics while preserving declaration
|
|
49
|
+
* order and avoiding a per-schema map allocation.
|
|
50
|
+
* @param cases Closed discriminated union case list.
|
|
51
|
+
* @param value Discriminant string read from input.
|
|
52
|
+
* @returns Matching case schema, or undefined when the value is unknown.
|
|
35
53
|
*/
|
|
36
54
|
export declare function findDiscriminatedUnionCase(cases: readonly DiscriminatedUnionCase[], value: string): Schema | undefined;
|
|
37
55
|
/**
|
|
38
|
-
* @brief
|
|
56
|
+
* @brief Test for the only accepted refinement success value.
|
|
57
|
+
* @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
|
|
58
|
+
* aligned with compiled behavior.
|
|
59
|
+
* @param value Predicate return value.
|
|
60
|
+
* @returns True only for the boolean literal true.
|
|
39
61
|
*/
|
|
40
62
|
export declare function isStrictTrue(value: unknown): boolean;
|
|
41
63
|
/**
|
|
42
|
-
* @brief
|
|
64
|
+
* @brief Test whether a value can host object-schema properties.
|
|
65
|
+
* @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
|
|
66
|
+
* aligned with compiled behavior.
|
|
67
|
+
* @param value Candidate runtime value.
|
|
68
|
+
* @returns True for non-array object values.
|
|
43
69
|
*/
|
|
44
70
|
export declare function isPlainRecord(value: unknown): value is UnknownRecord;
|
|
45
71
|
/**
|
|
46
|
-
* @brief
|
|
72
|
+
* @brief Test whether a descriptor carries a stable data slot.
|
|
47
73
|
* @details Checks that a descriptor contains a data value instead of getter/setter code.
|
|
74
|
+
* @param descriptor Descriptor returned by Object.getOwnPropertyDescriptor.
|
|
48
75
|
* @returns True when the descriptor has a stable value slot.
|
|
49
76
|
*/
|
|
50
77
|
export declare function isDataPropertyDescriptor(descriptor: PropertyDescriptor): descriptor is DataPropertyDescriptor;
|
|
51
78
|
/**
|
|
52
|
-
* @brief
|
|
79
|
+
* @brief Test whether a property name is an in-bounds array index.
|
|
80
|
+
* @details Array validation ignores non-index own properties exactly as indexed
|
|
81
|
+
* loops do, but this helper lets sparse arrays avoid scanning every hole.
|
|
82
|
+
* @param key Own property name returned from an array object.
|
|
83
|
+
* @param length Current array length used as the upper bound.
|
|
84
|
+
* @returns True for canonical own array-index names below the current length.
|
|
85
|
+
* @invariant The result matches the indexes visited by a `0..length` loop.
|
|
86
|
+
*/
|
|
87
|
+
export declare function isArrayIndexKey(key: string, length: number): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* @brief Convert a runtime value into TypeSea's diagnostic type label.
|
|
90
|
+
* @details JavaScript reports null as object and NaN as number. Diagnostics use
|
|
91
|
+
* more precise labels so failure reports describe the actual value shape seen by
|
|
92
|
+
* validators.
|
|
93
|
+
* @param value Candidate runtime value.
|
|
94
|
+
* @returns Stable diagnostic type label.
|
|
53
95
|
*/
|
|
54
96
|
export declare function actualType(value: unknown): string;
|
|
55
97
|
/**
|
|
56
|
-
* @brief
|
|
98
|
+
* @brief Validate a Date object without reading user-overridable methods.
|
|
99
|
+
* @param value Candidate runtime value.
|
|
100
|
+
* @returns True when value is a Date with a finite time value.
|
|
101
|
+
*/
|
|
102
|
+
export declare function isValidDateObject(value: unknown): value is Date;
|
|
103
|
+
/**
|
|
104
|
+
* @brief Read a Date object's time value through the intrinsic method.
|
|
105
|
+
* @param value Date object already accepted by isValidDateObject.
|
|
106
|
+
* @returns Epoch millisecond value.
|
|
107
|
+
*/
|
|
108
|
+
export declare function readDateTime(value: Date): number;
|
|
109
|
+
/**
|
|
110
|
+
* @brief Execute ordinary instanceof without invoking custom hasInstance hooks.
|
|
111
|
+
* @param value Candidate runtime value.
|
|
112
|
+
* @param constructor Constructor function stored in the schema.
|
|
113
|
+
* @returns True when the ordinary prototype-chain check accepts the value.
|
|
114
|
+
*/
|
|
115
|
+
export declare function ordinaryHasInstance(value: unknown, constructor: abstract new (...args: never[]) => unknown): boolean;
|
|
116
|
+
/**
|
|
117
|
+
* @brief Render a literal schema value for the `expected` diagnostic field.
|
|
118
|
+
* @details String values are JSON-quoted and negative zero is preserved because
|
|
119
|
+
* both cases are otherwise easy to misread in generated messages.
|
|
120
|
+
* @param value Literal value from a schema.
|
|
121
|
+
* @returns Stable expected-value label for diagnostics.
|
|
57
122
|
*/
|
|
58
123
|
export declare function literalToExpected(value: LiteralValue): string;
|
|
59
124
|
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/evaluate/shared.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/evaluate/shared.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACR,sBAAsB,EACtB,YAAY,EACZ,eAAe,EACf,MAAM,EACT,MAAM,oBAAoB,CAAC;AAI5B;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IAEnC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAE7E;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAC/B,MAAM,EAAE,aAAa,EACrB,GAAG,EAAE,MAAM,GACZ,sBAAsB,GAAG,SAAS,CAMpC;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACtC,KAAK,EAAE,SAAS,sBAAsB,EAAE,EACxC,KAAK,EAAE,MAAM,GACd,MAAM,GAAG,SAAS,CAQpB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEpD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAEpE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACpC,UAAU,EAAE,kBAAkB,GAC/B,UAAU,IAAI,sBAAsB,CAEtC;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAcpE;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CA0BjD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,IAAI,CAG/D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,CAEhD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAC/B,KAAK,EAAE,OAAO,EACd,WAAW,EAAE,QAAQ,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,GACxD,OAAO,CAET;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAiB7D"}
|
package/dist/evaluate/shared.js
CHANGED
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file shared.ts
|
|
3
3
|
* @brief Shared scalar helpers for schema evaluation.
|
|
4
|
+
* @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
|
|
5
|
+
* aligned with compiled behavior.
|
|
4
6
|
*/
|
|
7
|
+
const MAX_ARRAY_INDEX = 4_294_967_294;
|
|
5
8
|
/**
|
|
6
|
-
* @brief
|
|
9
|
+
* @brief Check membership in an object schema key lookup.
|
|
10
|
+
* @param keyLookup Null-prototype lookup generated by object schema construction.
|
|
11
|
+
* @param key Candidate own key.
|
|
12
|
+
* @returns True when the key belongs to the schema shape.
|
|
13
|
+
* @details The lookup is used instead of `in` so prototype pollution cannot make
|
|
14
|
+
* an undeclared key appear valid.
|
|
7
15
|
*/
|
|
8
16
|
export function hasObjectKey(keyLookup, key) {
|
|
9
17
|
return Object.prototype.hasOwnProperty.call(keyLookup, key);
|
|
10
18
|
}
|
|
11
19
|
/**
|
|
12
|
-
* @brief
|
|
20
|
+
* @brief Read one own data property from a runtime object.
|
|
13
21
|
* @details Reads one own property through its descriptor so getters are not executed.
|
|
22
|
+
* @param record Plain object being validated.
|
|
23
|
+
* @param key Own key to inspect.
|
|
14
24
|
* @returns Own data descriptor, or undefined for missing/accessor properties.
|
|
15
25
|
*/
|
|
16
26
|
export function readOwnDataProperty(record, key) {
|
|
@@ -21,7 +31,13 @@ export function readOwnDataProperty(record, key) {
|
|
|
21
31
|
return descriptor;
|
|
22
32
|
}
|
|
23
33
|
/**
|
|
24
|
-
* @brief
|
|
34
|
+
* @brief Select a discriminated-union branch by its literal tag value.
|
|
35
|
+
* @details The case list is already builder-validated for unique literals, so a
|
|
36
|
+
* linear scan is enough for interpreter diagnostics while preserving declaration
|
|
37
|
+
* order and avoiding a per-schema map allocation.
|
|
38
|
+
* @param cases Closed discriminated union case list.
|
|
39
|
+
* @param value Discriminant string read from input.
|
|
40
|
+
* @returns Matching case schema, or undefined when the value is unknown.
|
|
25
41
|
*/
|
|
26
42
|
export function findDiscriminatedUnionCase(cases, value) {
|
|
27
43
|
for (let index = 0; index < cases.length; index += 1) {
|
|
@@ -33,27 +49,65 @@ export function findDiscriminatedUnionCase(cases, value) {
|
|
|
33
49
|
return undefined;
|
|
34
50
|
}
|
|
35
51
|
/**
|
|
36
|
-
* @brief
|
|
52
|
+
* @brief Test for the only accepted refinement success value.
|
|
53
|
+
* @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
|
|
54
|
+
* aligned with compiled behavior.
|
|
55
|
+
* @param value Predicate return value.
|
|
56
|
+
* @returns True only for the boolean literal true.
|
|
37
57
|
*/
|
|
38
58
|
export function isStrictTrue(value) {
|
|
39
59
|
return value === true;
|
|
40
60
|
}
|
|
41
61
|
/**
|
|
42
|
-
* @brief
|
|
62
|
+
* @brief Test whether a value can host object-schema properties.
|
|
63
|
+
* @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
|
|
64
|
+
* aligned with compiled behavior.
|
|
65
|
+
* @param value Candidate runtime value.
|
|
66
|
+
* @returns True for non-array object values.
|
|
43
67
|
*/
|
|
44
68
|
export function isPlainRecord(value) {
|
|
45
69
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
46
70
|
}
|
|
47
71
|
/**
|
|
48
|
-
* @brief
|
|
72
|
+
* @brief Test whether a descriptor carries a stable data slot.
|
|
49
73
|
* @details Checks that a descriptor contains a data value instead of getter/setter code.
|
|
74
|
+
* @param descriptor Descriptor returned by Object.getOwnPropertyDescriptor.
|
|
50
75
|
* @returns True when the descriptor has a stable value slot.
|
|
51
76
|
*/
|
|
52
77
|
export function isDataPropertyDescriptor(descriptor) {
|
|
53
78
|
return Object.prototype.hasOwnProperty.call(descriptor, "value");
|
|
54
79
|
}
|
|
55
80
|
/**
|
|
56
|
-
* @brief
|
|
81
|
+
* @brief Test whether a property name is an in-bounds array index.
|
|
82
|
+
* @details Array validation ignores non-index own properties exactly as indexed
|
|
83
|
+
* loops do, but this helper lets sparse arrays avoid scanning every hole.
|
|
84
|
+
* @param key Own property name returned from an array object.
|
|
85
|
+
* @param length Current array length used as the upper bound.
|
|
86
|
+
* @returns True for canonical own array-index names below the current length.
|
|
87
|
+
* @invariant The result matches the indexes visited by a `0..length` loop.
|
|
88
|
+
*/
|
|
89
|
+
export function isArrayIndexKey(key, length) {
|
|
90
|
+
if (key.length === 0 || key === "length") {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
/*
|
|
94
|
+
* Enumeration APIs expose array indexes as strings. Round-tripping through
|
|
95
|
+
* Number rejects aliases such as "01", floats, negative keys, and length.
|
|
96
|
+
*/
|
|
97
|
+
const index = Number(key);
|
|
98
|
+
return Number.isInteger(index) &&
|
|
99
|
+
index >= 0 &&
|
|
100
|
+
index <= MAX_ARRAY_INDEX &&
|
|
101
|
+
index < length &&
|
|
102
|
+
String(index) === key;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* @brief Convert a runtime value into TypeSea's diagnostic type label.
|
|
106
|
+
* @details JavaScript reports null as object and NaN as number. Diagnostics use
|
|
107
|
+
* more precise labels so failure reports describe the actual value shape seen by
|
|
108
|
+
* validators.
|
|
109
|
+
* @param value Candidate runtime value.
|
|
110
|
+
* @returns Stable diagnostic type label.
|
|
57
111
|
*/
|
|
58
112
|
export function actualType(value) {
|
|
59
113
|
if (value === null) {
|
|
@@ -62,6 +116,15 @@ export function actualType(value) {
|
|
|
62
116
|
if (Array.isArray(value)) {
|
|
63
117
|
return "array";
|
|
64
118
|
}
|
|
119
|
+
if (value instanceof Date) {
|
|
120
|
+
return "date";
|
|
121
|
+
}
|
|
122
|
+
if (value instanceof Map) {
|
|
123
|
+
return "map";
|
|
124
|
+
}
|
|
125
|
+
if (value instanceof Set) {
|
|
126
|
+
return "set";
|
|
127
|
+
}
|
|
65
128
|
if (typeof value === "bigint") {
|
|
66
129
|
return "bigint";
|
|
67
130
|
}
|
|
@@ -74,7 +137,37 @@ export function actualType(value) {
|
|
|
74
137
|
return typeof value;
|
|
75
138
|
}
|
|
76
139
|
/**
|
|
77
|
-
* @brief
|
|
140
|
+
* @brief Validate a Date object without reading user-overridable methods.
|
|
141
|
+
* @param value Candidate runtime value.
|
|
142
|
+
* @returns True when value is a Date with a finite time value.
|
|
143
|
+
*/
|
|
144
|
+
export function isValidDateObject(value) {
|
|
145
|
+
return value instanceof Date &&
|
|
146
|
+
Number.isFinite(Date.prototype.getTime.call(value));
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* @brief Read a Date object's time value through the intrinsic method.
|
|
150
|
+
* @param value Date object already accepted by isValidDateObject.
|
|
151
|
+
* @returns Epoch millisecond value.
|
|
152
|
+
*/
|
|
153
|
+
export function readDateTime(value) {
|
|
154
|
+
return Date.prototype.getTime.call(value);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* @brief Execute ordinary instanceof without invoking custom hasInstance hooks.
|
|
158
|
+
* @param value Candidate runtime value.
|
|
159
|
+
* @param constructor Constructor function stored in the schema.
|
|
160
|
+
* @returns True when the ordinary prototype-chain check accepts the value.
|
|
161
|
+
*/
|
|
162
|
+
export function ordinaryHasInstance(value, constructor) {
|
|
163
|
+
return Function.prototype[Symbol.hasInstance].call(constructor, value);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* @brief Render a literal schema value for the `expected` diagnostic field.
|
|
167
|
+
* @details String values are JSON-quoted and negative zero is preserved because
|
|
168
|
+
* both cases are otherwise easy to misread in generated messages.
|
|
169
|
+
* @param value Literal value from a schema.
|
|
170
|
+
* @returns Stable expected-value label for diagnostics.
|
|
78
171
|
*/
|
|
79
172
|
export function literalToExpected(value) {
|
|
80
173
|
if (value === null) {
|
package/dist/evaluate/state.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file state.ts
|
|
3
3
|
* @brief Recursive validation state for cyclic input graphs.
|
|
4
|
+
* @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
|
|
5
|
+
* aligned with compiled behavior.
|
|
4
6
|
*/
|
|
5
7
|
import type { Schema } from "../schema/index.js";
|
|
6
8
|
/**
|
|
@@ -11,6 +13,8 @@ import type { Schema } from "../schema/index.js";
|
|
|
11
13
|
export type ValidationEnterResult = "entered" | "cycle" | "budget";
|
|
12
14
|
/**
|
|
13
15
|
* @brief default max validation depth.
|
|
16
|
+
* @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
|
|
17
|
+
* aligned with compiled behavior.
|
|
14
18
|
* @invariant The value stays below the V8 stack depth that recursive lazy schemas can exhaust.
|
|
15
19
|
*/
|
|
16
20
|
export declare const DEFAULT_MAX_VALIDATION_DEPTH = 256;
|
|
@@ -26,40 +30,58 @@ export interface GraphEvaluationFrame {
|
|
|
26
30
|
}
|
|
27
31
|
/**
|
|
28
32
|
* @brief validation state.
|
|
33
|
+
* @details Bundles recursion guards, lazy-resolution guards, and reusable graph
|
|
34
|
+
* frames so interpreter and IR execution observe the same limits.
|
|
29
35
|
*/
|
|
30
36
|
export interface ValidationState {
|
|
31
37
|
readonly active: WeakMap<object, WeakSet<Schema>>;
|
|
32
38
|
readonly graphFrames: GraphEvaluationFrame[];
|
|
33
39
|
readonly resolving: WeakSet<object>;
|
|
34
40
|
/**
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
41
|
+
* @brief depth.
|
|
42
|
+
* @details Counts active recursive validator frames owned by this state object.
|
|
43
|
+
* @invariant The value is incremented only after budget admission and decremented by `leaveValidation`.
|
|
44
|
+
*/
|
|
39
45
|
depth: number;
|
|
40
46
|
/**
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
* @brief graph depth.
|
|
48
|
+
* @details Counts active nested graph executions using `graphFrames` as a stack.
|
|
49
|
+
* @invariant Incremented by IR execution before frame use and decremented after it.
|
|
50
|
+
*/
|
|
45
51
|
graphDepth: number;
|
|
46
52
|
/**
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
53
|
+
* @brief max depth.
|
|
54
|
+
* @details Hard cap for recursive validator frames.
|
|
55
|
+
* @invariant Entering past this limit returns `budget` instead of recursing.
|
|
56
|
+
*/
|
|
51
57
|
readonly maxDepth: number;
|
|
52
58
|
}
|
|
53
59
|
/**
|
|
54
|
-
* @brief
|
|
60
|
+
* @brief Allocate recursion and graph-frame state for one validation run.
|
|
61
|
+
* @returns Fresh validation state for one top-level validation operation.
|
|
62
|
+
* @details State is allocated per call so cycle tracking cannot leak between
|
|
63
|
+
* unrelated inputs.
|
|
55
64
|
*/
|
|
56
65
|
export declare function makeValidationState(): ValidationState;
|
|
57
66
|
/**
|
|
58
67
|
* @brief enter validation.
|
|
68
|
+
* @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
|
|
69
|
+
* aligned with compiled behavior.
|
|
70
|
+
* @param schema Schema being entered.
|
|
71
|
+
* @param value Candidate runtime value.
|
|
72
|
+
* @param state Shared validation state.
|
|
73
|
+
* @returns Enter result describing cycle, budget, or admitted recursion.
|
|
74
|
+
* @post `state.depth` is incremented only for the entered result.
|
|
59
75
|
*/
|
|
60
76
|
export declare function enterValidation(schema: Schema, value: unknown, state: ValidationState): ValidationEnterResult;
|
|
61
77
|
/**
|
|
62
78
|
* @brief leave validation.
|
|
79
|
+
* @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
|
|
80
|
+
* aligned with compiled behavior.
|
|
81
|
+
* @param schema Schema leaving validation.
|
|
82
|
+
* @param value Candidate runtime value.
|
|
83
|
+
* @param state Shared validation state.
|
|
84
|
+
* @post Reverses the depth and active-pair effects of `enterValidation`.
|
|
63
85
|
*/
|
|
64
86
|
export declare function leaveValidation(schema: Schema, value: unknown, state: ValidationState): void;
|
|
65
87
|
//# sourceMappingURL=state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/evaluate/state.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/evaluate/state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAC3B,SAAS,GACT,OAAO,GACP,QAAQ,CAAC;AAEf;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAEhD;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACjC,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC5B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAClD,QAAQ,CAAC,WAAW,EAAE,oBAAoB,EAAE,CAAC;IAC7C,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAEpC;;;;KAIC;IACD,KAAK,EAAE,MAAM,CAAC;IAEd;;;;KAIC;IACD,UAAU,EAAE,MAAM,CAAC;IAEnB;;;;KAIC;IACD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,eAAe,CASrD;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC3B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,eAAe,GACvB,qBAAqB,CA6BvB;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC3B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,eAAe,GACvB,IAAI,CAUN"}
|
package/dist/evaluate/state.js
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file state.ts
|
|
3
3
|
* @brief Recursive validation state for cyclic input graphs.
|
|
4
|
+
* @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
|
|
5
|
+
* aligned with compiled behavior.
|
|
4
6
|
*/
|
|
5
7
|
/**
|
|
6
8
|
* @brief default max validation depth.
|
|
9
|
+
* @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
|
|
10
|
+
* aligned with compiled behavior.
|
|
7
11
|
* @invariant The value stays below the V8 stack depth that recursive lazy schemas can exhaust.
|
|
8
12
|
*/
|
|
9
13
|
export const DEFAULT_MAX_VALIDATION_DEPTH = 256;
|
|
10
14
|
/**
|
|
11
|
-
* @brief
|
|
15
|
+
* @brief Allocate recursion and graph-frame state for one validation run.
|
|
16
|
+
* @returns Fresh validation state for one top-level validation operation.
|
|
17
|
+
* @details State is allocated per call so cycle tracking cannot leak between
|
|
18
|
+
* unrelated inputs.
|
|
12
19
|
*/
|
|
13
20
|
export function makeValidationState() {
|
|
14
21
|
return {
|
|
@@ -22,10 +29,22 @@ export function makeValidationState() {
|
|
|
22
29
|
}
|
|
23
30
|
/**
|
|
24
31
|
* @brief enter validation.
|
|
32
|
+
* @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
|
|
33
|
+
* aligned with compiled behavior.
|
|
34
|
+
* @param schema Schema being entered.
|
|
35
|
+
* @param value Candidate runtime value.
|
|
36
|
+
* @param state Shared validation state.
|
|
37
|
+
* @returns Enter result describing cycle, budget, or admitted recursion.
|
|
38
|
+
* @post `state.depth` is incremented only for the entered result.
|
|
25
39
|
*/
|
|
26
40
|
export function enterValidation(schema, value, state) {
|
|
27
41
|
const cached = isReferenceValue(value) ? state.active.get(value) : undefined;
|
|
28
42
|
if (cached?.has(schema) === true) {
|
|
43
|
+
/*
|
|
44
|
+
* The same schema/value pair is already active. Returning cycle prevents
|
|
45
|
+
* infinite recursion on cyclic object graphs while preserving success for
|
|
46
|
+
* the already-open branch.
|
|
47
|
+
*/
|
|
29
48
|
return "cycle";
|
|
30
49
|
}
|
|
31
50
|
if (state.depth >= state.maxDepth) {
|
|
@@ -36,6 +55,10 @@ export function enterValidation(schema, value, state) {
|
|
|
36
55
|
return "entered";
|
|
37
56
|
}
|
|
38
57
|
if (cached !== undefined) {
|
|
58
|
+
/*
|
|
59
|
+
* WeakSet membership is per object identity. Adding the schema marks this
|
|
60
|
+
* exact pair as active until leaveValidation removes it.
|
|
61
|
+
*/
|
|
39
62
|
cached.add(schema);
|
|
40
63
|
return "entered";
|
|
41
64
|
}
|
|
@@ -46,6 +69,12 @@ export function enterValidation(schema, value, state) {
|
|
|
46
69
|
}
|
|
47
70
|
/**
|
|
48
71
|
* @brief leave validation.
|
|
72
|
+
* @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
|
|
73
|
+
* aligned with compiled behavior.
|
|
74
|
+
* @param schema Schema leaving validation.
|
|
75
|
+
* @param value Candidate runtime value.
|
|
76
|
+
* @param state Shared validation state.
|
|
77
|
+
* @post Reverses the depth and active-pair effects of `enterValidation`.
|
|
49
78
|
*/
|
|
50
79
|
export function leaveValidation(schema, value, state) {
|
|
51
80
|
if (!isReferenceValue(value)) {
|
|
@@ -59,7 +88,11 @@ export function leaveValidation(schema, value, state) {
|
|
|
59
88
|
state.depth -= 1;
|
|
60
89
|
}
|
|
61
90
|
/**
|
|
62
|
-
* @brief
|
|
91
|
+
* @brief Test whether a value can participate in object graph cycles.
|
|
92
|
+
* @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
|
|
93
|
+
* aligned with compiled behavior.
|
|
94
|
+
* @param value Candidate runtime value.
|
|
95
|
+
* @returns True for objects and functions that can participate in cycles.
|
|
63
96
|
*/
|
|
64
97
|
function isReferenceValue(value) {
|
|
65
98
|
return (typeof value === "object" && value !== null) || typeof value === "function";
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file array.ts
|
|
3
|
+
* @brief Array guard implementation.
|
|
4
|
+
* @details Array helpers append immutable length constraints while preserving
|
|
5
|
+
* the item schema owned by the original guard.
|
|
6
|
+
*/
|
|
7
|
+
import type { ArraySchema } from "../schema/index.js";
|
|
8
|
+
import { BaseGuard } from "./base.js";
|
|
9
|
+
import type { Presence } from "./types.js";
|
|
10
|
+
/**
|
|
11
|
+
* @brief Persistent builder for homogeneous array predicates.
|
|
12
|
+
* @details Length methods allocate a fresh schema record. The item schema is
|
|
13
|
+
* reused by identity because guard construction has already frozen it.
|
|
14
|
+
*/
|
|
15
|
+
export declare class ArrayGuard<TItem, TPresence extends Presence = "required"> extends BaseGuard<TItem[], TPresence> {
|
|
16
|
+
/**
|
|
17
|
+
* @brief Construct a frozen array guard.
|
|
18
|
+
* @param schema Array schema backing this guard.
|
|
19
|
+
* @post The receiver has no mutable instance state after construction.
|
|
20
|
+
*/
|
|
21
|
+
constructor(schema: ArraySchema);
|
|
22
|
+
/**
|
|
23
|
+
* @brief Require an inclusive minimum array length.
|
|
24
|
+
* @param value Non-negative integer lower bound.
|
|
25
|
+
* @returns Fresh ArrayGuard with an appended minimum length check.
|
|
26
|
+
*/
|
|
27
|
+
min(value: number): ArrayGuard<TItem, TPresence>;
|
|
28
|
+
/**
|
|
29
|
+
* @brief Require an inclusive maximum array length.
|
|
30
|
+
* @param value Non-negative integer upper bound.
|
|
31
|
+
* @returns Fresh ArrayGuard with an appended maximum length check.
|
|
32
|
+
*/
|
|
33
|
+
max(value: number): ArrayGuard<TItem, TPresence>;
|
|
34
|
+
/**
|
|
35
|
+
* @brief Require one exact array length.
|
|
36
|
+
* @param value Non-negative integer exact length.
|
|
37
|
+
* @returns Fresh ArrayGuard with matching minimum and maximum length checks.
|
|
38
|
+
* @details Exact length is represented as two ordinary bounds so every
|
|
39
|
+
* backend can reuse the same comparison and diagnostic paths.
|
|
40
|
+
*/
|
|
41
|
+
length(value: number): ArrayGuard<TItem, TPresence>;
|
|
42
|
+
/**
|
|
43
|
+
* @brief Require at least one array element.
|
|
44
|
+
* @returns Fresh ArrayGuard with a minimum length of one.
|
|
45
|
+
*/
|
|
46
|
+
nonempty(): ArrayGuard<TItem, TPresence>;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=array.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"array.d.ts","sourceRoot":"","sources":["../../src/guard/array.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EACH,SAAS,EAEZ,MAAM,WAAW,CAAC;AAMnB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;GAIG;AACH,qBAAa,UAAU,CACnB,KAAK,EACL,SAAS,SAAS,QAAQ,GAAG,UAAU,CACzC,SAAQ,SAAS,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC;IAEnC;;;;OAIG;gBACgB,MAAM,EAAE,WAAW;IAKtC;;;;OAIG;IACI,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC;IAgBvD;;;;OAIG;IACI,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC;IAgBvD;;;;;;OAMG;IACI,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC;IAK1D;;;OAGG;IACI,QAAQ,IAAI,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC;CAGlD"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file array.ts
|
|
3
|
+
* @brief Array guard implementation.
|
|
4
|
+
* @details Array helpers append immutable length constraints while preserving
|
|
5
|
+
* the item schema owned by the original guard.
|
|
6
|
+
*/
|
|
7
|
+
import { ArrayCheckTag, SchemaTag } from "../kind/index.js";
|
|
8
|
+
import { BaseGuard, setArrayGuardFactory } from "./base.js";
|
|
9
|
+
import { checkArrayLengthBound, readArrayConstructorSchema, readArrayMethodSchema } from "./read.js";
|
|
10
|
+
/**
|
|
11
|
+
* @brief Persistent builder for homogeneous array predicates.
|
|
12
|
+
* @details Length methods allocate a fresh schema record. The item schema is
|
|
13
|
+
* reused by identity because guard construction has already frozen it.
|
|
14
|
+
*/
|
|
15
|
+
export class ArrayGuard extends BaseGuard {
|
|
16
|
+
/**
|
|
17
|
+
* @brief Construct a frozen array guard.
|
|
18
|
+
* @param schema Array schema backing this guard.
|
|
19
|
+
* @post The receiver has no mutable instance state after construction.
|
|
20
|
+
*/
|
|
21
|
+
constructor(schema) {
|
|
22
|
+
super(readArrayConstructorSchema(schema));
|
|
23
|
+
Object.freeze(this);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* @brief Require an inclusive minimum array length.
|
|
27
|
+
* @param value Non-negative integer lower bound.
|
|
28
|
+
* @returns Fresh ArrayGuard with an appended minimum length check.
|
|
29
|
+
*/
|
|
30
|
+
min(value) {
|
|
31
|
+
const schema = readArrayMethodSchema(this, "array min receiver");
|
|
32
|
+
const bound = checkArrayLengthBound(value, "min");
|
|
33
|
+
return new ArrayGuard({
|
|
34
|
+
tag: SchemaTag.Array,
|
|
35
|
+
item: schema.item,
|
|
36
|
+
checks: [
|
|
37
|
+
...schema.checks,
|
|
38
|
+
{
|
|
39
|
+
tag: ArrayCheckTag.Min,
|
|
40
|
+
value: bound
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* @brief Require an inclusive maximum array length.
|
|
47
|
+
* @param value Non-negative integer upper bound.
|
|
48
|
+
* @returns Fresh ArrayGuard with an appended maximum length check.
|
|
49
|
+
*/
|
|
50
|
+
max(value) {
|
|
51
|
+
const schema = readArrayMethodSchema(this, "array max receiver");
|
|
52
|
+
const bound = checkArrayLengthBound(value, "max");
|
|
53
|
+
return new ArrayGuard({
|
|
54
|
+
tag: SchemaTag.Array,
|
|
55
|
+
item: schema.item,
|
|
56
|
+
checks: [
|
|
57
|
+
...schema.checks,
|
|
58
|
+
{
|
|
59
|
+
tag: ArrayCheckTag.Max,
|
|
60
|
+
value: bound
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* @brief Require one exact array length.
|
|
67
|
+
* @param value Non-negative integer exact length.
|
|
68
|
+
* @returns Fresh ArrayGuard with matching minimum and maximum length checks.
|
|
69
|
+
* @details Exact length is represented as two ordinary bounds so every
|
|
70
|
+
* backend can reuse the same comparison and diagnostic paths.
|
|
71
|
+
*/
|
|
72
|
+
length(value) {
|
|
73
|
+
const bound = checkArrayLengthBound(value, "exact");
|
|
74
|
+
return this.min(bound).max(bound);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* @brief Require at least one array element.
|
|
78
|
+
* @returns Fresh ArrayGuard with a minimum length of one.
|
|
79
|
+
*/
|
|
80
|
+
nonempty() {
|
|
81
|
+
return this.min(1);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
setArrayGuardFactory((schema) => new ArrayGuard(schema));
|