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,18 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file compile/predicate.ts
|
|
3
3
|
* @brief Boolean validator source emitter.
|
|
4
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
5
|
+
* stable across runtime and AOT emission.
|
|
4
6
|
*/
|
|
5
|
-
import { NumberCheckTag, ObjectModeTag, PresenceTag, SchemaTag, StringCheckTag } from "../kind/index.js";
|
|
6
|
-
import { UUID_PATTERN } from "../schema/index.js";
|
|
7
|
+
import { ArrayCheckTag, DateCheckTag, NumberCheckTag, ObjectModeTag, PresenceTag, SchemaTag, StringCheckTag } from "../kind/index.js";
|
|
8
|
+
import { EMAIL_PATTERN, IPV4_PATTERN, IPV6_PATTERN, ISO_DATETIME_PATTERN, ISO_DATE_PATTERN, ULID_PATTERN, URL_PATTERN, UUID_PATTERN } from "../schema/index.js";
|
|
7
9
|
import { pushLiteral, pushRegex, pushSchema, stringRef } from "./context.js";
|
|
8
10
|
/**
|
|
9
11
|
* @brief emit function.
|
|
12
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
13
|
+
* stable across runtime and AOT emission.
|
|
14
|
+
* @param schema Schema represented by the predicate.
|
|
15
|
+
* @param context Shared code-generation context.
|
|
16
|
+
* @returns Generated predicate function name.
|
|
17
|
+
* @invariant The same schema object maps to one predicate function per bundle.
|
|
10
18
|
*/
|
|
11
19
|
export function emitFunction(schema, context) {
|
|
12
20
|
const cached = context.functionNames.get(schema);
|
|
13
21
|
if (cached !== undefined) {
|
|
14
22
|
return cached;
|
|
15
23
|
}
|
|
24
|
+
/*
|
|
25
|
+
* Register before body emission so recursive references can point at the
|
|
26
|
+
* function name even while its body is still under construction.
|
|
27
|
+
*/
|
|
16
28
|
const name = `p${String(context.functions.length)}`;
|
|
17
29
|
const source = {
|
|
18
30
|
name,
|
|
@@ -25,6 +37,10 @@ export function emitFunction(schema, context) {
|
|
|
25
37
|
}
|
|
26
38
|
/**
|
|
27
39
|
* @brief emit functions.
|
|
40
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
41
|
+
* stable across runtime and AOT emission.
|
|
42
|
+
* @param context Shared code-generation context with accumulated predicate sources.
|
|
43
|
+
* @returns Concatenated JavaScript function declarations.
|
|
28
44
|
*/
|
|
29
45
|
export function emitFunctions(context) {
|
|
30
46
|
const chunks = new Array(context.functions.length);
|
|
@@ -39,15 +55,29 @@ export function emitFunctions(context) {
|
|
|
39
55
|
}
|
|
40
56
|
/**
|
|
41
57
|
* @brief emit body.
|
|
58
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
59
|
+
* stable across runtime and AOT emission.
|
|
60
|
+
* @param schema Schema represented by this predicate body.
|
|
61
|
+
* @param value Generated expression for the candidate value.
|
|
62
|
+
* @param context Shared code-generation context.
|
|
63
|
+
* @returns JavaScript source for a predicate function body.
|
|
42
64
|
*/
|
|
43
65
|
function emitBody(schema, value, context) {
|
|
44
66
|
switch (schema.tag) {
|
|
45
67
|
case SchemaTag.Array:
|
|
46
|
-
return emitArrayBody(schema
|
|
68
|
+
return emitArrayBody(schema, value, context);
|
|
47
69
|
case SchemaTag.Tuple:
|
|
70
|
+
if (schema.rest !== undefined) {
|
|
71
|
+
return `return d(${String(pushSchema(context, schema))},${value});`;
|
|
72
|
+
}
|
|
48
73
|
return emitTupleBody(schema.items, value, context);
|
|
49
74
|
case SchemaTag.Record:
|
|
50
75
|
return emitRecordBody(schema.value, value, context);
|
|
76
|
+
case SchemaTag.Map:
|
|
77
|
+
case SchemaTag.Set:
|
|
78
|
+
case SchemaTag.InstanceOf:
|
|
79
|
+
case SchemaTag.Property:
|
|
80
|
+
return `return d(${String(pushSchema(context, schema))},${value});`;
|
|
51
81
|
case SchemaTag.Object:
|
|
52
82
|
return emitObjectBody(schema, value, context);
|
|
53
83
|
case SchemaTag.DiscriminatedUnion:
|
|
@@ -58,6 +88,12 @@ function emitBody(schema, value, context) {
|
|
|
58
88
|
}
|
|
59
89
|
/**
|
|
60
90
|
* @brief emit expression.
|
|
91
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
92
|
+
* stable across runtime and AOT emission.
|
|
93
|
+
* @param schema Schema represented by the expression.
|
|
94
|
+
* @param value Generated expression for the candidate value.
|
|
95
|
+
* @param context Shared code-generation context.
|
|
96
|
+
* @returns JavaScript expression that evaluates to a boolean.
|
|
61
97
|
*/
|
|
62
98
|
export function emitExpression(schema, value, context) {
|
|
63
99
|
switch (schema.tag) {
|
|
@@ -69,6 +105,8 @@ export function emitExpression(schema, value, context) {
|
|
|
69
105
|
return emitString(schema, value, context);
|
|
70
106
|
case SchemaTag.Number:
|
|
71
107
|
return emitNumber(schema, value);
|
|
108
|
+
case SchemaTag.Date:
|
|
109
|
+
return emitDate(schema, value);
|
|
72
110
|
case SchemaTag.BigInt:
|
|
73
111
|
return `(typeof ${value}==="bigint")`;
|
|
74
112
|
case SchemaTag.Symbol:
|
|
@@ -78,11 +116,23 @@ export function emitExpression(schema, value, context) {
|
|
|
78
116
|
case SchemaTag.Literal:
|
|
79
117
|
return `Object.is(${value},l[${String(pushLiteral(context, schema.value))}])`;
|
|
80
118
|
case SchemaTag.Array:
|
|
119
|
+
/*
|
|
120
|
+
* Composite schemas get their own functions. That keeps deeply nested
|
|
121
|
+
* predicates readable to V8 and avoids duplicating loops at each use site.
|
|
122
|
+
*/
|
|
81
123
|
return `${emitFunction(schema, context)}(${value})`;
|
|
82
124
|
case SchemaTag.Tuple:
|
|
125
|
+
if (schema.rest !== undefined) {
|
|
126
|
+
return `d(${String(pushSchema(context, schema))},${value})`;
|
|
127
|
+
}
|
|
83
128
|
return `${emitFunction(schema, context)}(${value})`;
|
|
84
129
|
case SchemaTag.Record:
|
|
85
130
|
return `${emitFunction(schema, context)}(${value})`;
|
|
131
|
+
case SchemaTag.Map:
|
|
132
|
+
case SchemaTag.Set:
|
|
133
|
+
case SchemaTag.InstanceOf:
|
|
134
|
+
case SchemaTag.Property:
|
|
135
|
+
return `d(${String(pushSchema(context, schema))},${value})`;
|
|
86
136
|
case SchemaTag.Object:
|
|
87
137
|
return `${emitFunction(schema, context)}(${value})`;
|
|
88
138
|
case SchemaTag.Union:
|
|
@@ -100,16 +150,61 @@ export function emitExpression(schema, value, context) {
|
|
|
100
150
|
return emitExpression(schema.inner, value, context);
|
|
101
151
|
case SchemaTag.Lazy:
|
|
102
152
|
case SchemaTag.Refine:
|
|
153
|
+
/*
|
|
154
|
+
* User predicates and lazy resolution remain behind the runtime `d`
|
|
155
|
+
* helper because generated source cannot inline their behavior.
|
|
156
|
+
*/
|
|
103
157
|
return `d(${String(pushSchema(context, schema))},${value})`;
|
|
104
158
|
}
|
|
105
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* @brief Emit a Date predicate expression.
|
|
162
|
+
* @param schema Date schema with normalized checks.
|
|
163
|
+
* @param value Generated expression for the candidate value.
|
|
164
|
+
* @returns JavaScript expression that accepts valid Date objects within bounds.
|
|
165
|
+
*/
|
|
166
|
+
function emitDate(schema, value) {
|
|
167
|
+
const checks = schema.checks;
|
|
168
|
+
const parts = [
|
|
169
|
+
`(${value} instanceof Date)`,
|
|
170
|
+
`dg(${value})`
|
|
171
|
+
];
|
|
172
|
+
for (let index = 0; index < checks.length; index += 1) {
|
|
173
|
+
const check = checks[index];
|
|
174
|
+
if (check === undefined) {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
switch (check.tag) {
|
|
178
|
+
case DateCheckTag.Min:
|
|
179
|
+
parts.push(`dt(${value})>=${String(check.value)}`);
|
|
180
|
+
break;
|
|
181
|
+
case DateCheckTag.Max:
|
|
182
|
+
parts.push(`dt(${value})<=${String(check.value)}`);
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return `(${parts.join("&&")})`;
|
|
187
|
+
}
|
|
106
188
|
/**
|
|
107
189
|
* @brief emit array body.
|
|
190
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
191
|
+
* stable across runtime and AOT emission.
|
|
192
|
+
* @param item Schema applied to each logical slot.
|
|
193
|
+
* @param value Generated expression for the array value.
|
|
194
|
+
* @param context Shared code-generation context.
|
|
195
|
+
* @returns JavaScript source for an array predicate body.
|
|
108
196
|
*/
|
|
109
|
-
function emitArrayBody(
|
|
197
|
+
function emitArrayBody(schema, value, context) {
|
|
198
|
+
const item = schema.item;
|
|
110
199
|
const itemFunction = emitFunction(item, context);
|
|
200
|
+
/*
|
|
201
|
+
* Descriptor reads block accessor-backed slots without executing getters.
|
|
202
|
+
* Holes are forwarded as undefined so optional item schemas keep normal JS
|
|
203
|
+
* sparse-array semantics.
|
|
204
|
+
*/
|
|
111
205
|
return [
|
|
112
206
|
`if(!Array.isArray(${value}))return false;`,
|
|
207
|
+
emitArrayLengthBody(value, schema.checks),
|
|
113
208
|
`for(let i=0;i<${value}.length;i+=1){`,
|
|
114
209
|
`const d=gp(${value},i);`,
|
|
115
210
|
`if(d!==undefined&&!h.call(d,"value"))return false;`,
|
|
@@ -118,11 +213,49 @@ function emitArrayBody(item, value, context) {
|
|
|
118
213
|
"return true;"
|
|
119
214
|
].join("");
|
|
120
215
|
}
|
|
216
|
+
/**
|
|
217
|
+
* @brief Emit array length checks for direct predicate bodies.
|
|
218
|
+
* @param value Generated expression for the candidate array.
|
|
219
|
+
* @param checks Normalized array length checks.
|
|
220
|
+
* @returns Straight-line early-return checks, or an empty string.
|
|
221
|
+
*/
|
|
222
|
+
function emitArrayLengthBody(value, checks) {
|
|
223
|
+
if (checks.length === 0) {
|
|
224
|
+
return "";
|
|
225
|
+
}
|
|
226
|
+
const chunks = [];
|
|
227
|
+
for (let index = 0; index < checks.length; index += 1) {
|
|
228
|
+
const check = checks[index];
|
|
229
|
+
if (check === undefined) {
|
|
230
|
+
chunks.push("return false;");
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
switch (check.tag) {
|
|
234
|
+
case ArrayCheckTag.Min:
|
|
235
|
+
chunks.push(`if(${value}.length<${String(check.value)})return false;`);
|
|
236
|
+
break;
|
|
237
|
+
case ArrayCheckTag.Max:
|
|
238
|
+
chunks.push(`if(${value}.length>${String(check.value)})return false;`);
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return chunks.join("");
|
|
243
|
+
}
|
|
121
244
|
/**
|
|
122
245
|
* @brief emit record body.
|
|
246
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
247
|
+
* stable across runtime and AOT emission.
|
|
248
|
+
* @param item Schema applied to each own enumerable string key.
|
|
249
|
+
* @param value Generated expression for the record value.
|
|
250
|
+
* @param context Shared code-generation context.
|
|
251
|
+
* @returns JavaScript source for a record predicate body.
|
|
123
252
|
*/
|
|
124
253
|
function emitRecordBody(item, value, context) {
|
|
125
254
|
const itemFunction = emitFunction(item, context);
|
|
255
|
+
/*
|
|
256
|
+
* Object.keys intentionally ignores inherited and non-enumerable keys,
|
|
257
|
+
* matching TypeSea record semantics while keeping iteration predictable.
|
|
258
|
+
*/
|
|
126
259
|
return [
|
|
127
260
|
`if(!o(${value}))return false;`,
|
|
128
261
|
`const ks=Object.keys(${value});`,
|
|
@@ -137,6 +270,9 @@ function emitRecordBody(item, value, context) {
|
|
|
137
270
|
/**
|
|
138
271
|
* @brief emit tuple body.
|
|
139
272
|
* @details Emits tuple validation as straight-line descriptor reads and early returns.
|
|
273
|
+
* @param items Tuple item schemas.
|
|
274
|
+
* @param value Generated expression for the tuple value.
|
|
275
|
+
* @param context Shared code-generation context.
|
|
140
276
|
* @returns Generated tuple predicate body.
|
|
141
277
|
*/
|
|
142
278
|
function emitTupleBody(items, value, context) {
|
|
@@ -150,6 +286,10 @@ function emitTupleBody(items, value, context) {
|
|
|
150
286
|
}
|
|
151
287
|
const descriptor = `d${String(index)}`;
|
|
152
288
|
const itemValue = `v${String(index)}`;
|
|
289
|
+
/*
|
|
290
|
+
* Tuple arity is already checked above. Each index still needs descriptor
|
|
291
|
+
* validation because an accessor slot would execute user code if read.
|
|
292
|
+
*/
|
|
153
293
|
chunks.push(`const ${descriptor}=gp(${value},${String(index)});`, `if(${descriptor}!==undefined&&!h.call(${descriptor},"value"))return false;`, `const ${itemValue}=${descriptor}===undefined?undefined:${descriptor}.value;`, `if(!${emitExpression(item, itemValue, context)})return false;`);
|
|
154
294
|
}
|
|
155
295
|
chunks.push("return true;");
|
|
@@ -158,6 +298,9 @@ function emitTupleBody(items, value, context) {
|
|
|
158
298
|
/**
|
|
159
299
|
* @brief emit object body.
|
|
160
300
|
* @details Emits object validation as Ajv-style straight-line code with local descriptor variables.
|
|
301
|
+
* @param schema Object schema to emit.
|
|
302
|
+
* @param value Generated expression for the object value.
|
|
303
|
+
* @param context Shared code-generation context.
|
|
161
304
|
* @returns Generated object predicate body.
|
|
162
305
|
*/
|
|
163
306
|
function emitObjectBody(schema, value, context) {
|
|
@@ -174,22 +317,54 @@ function emitObjectBody(schema, value, context) {
|
|
|
174
317
|
const itemValue = `v${String(index)}`;
|
|
175
318
|
chunks.push(`const ${descriptor}=gp(${value},${key});`);
|
|
176
319
|
if (entry.presence === PresenceTag.Optional) {
|
|
320
|
+
/*
|
|
321
|
+
* Optional own accessors are rejected. A missing descriptor is valid,
|
|
322
|
+
* but an own non-data property at the key is still hostile input.
|
|
323
|
+
*/
|
|
177
324
|
chunks.push(`if(${descriptor}!==undefined){`, `if(!h.call(${descriptor},"value"))return false;`, `const ${itemValue}=${descriptor}.value;`, `if(!${emitExpression(entry.schema, itemValue, context)})return false;`, `}else if(h.call(${value},${key}))return false;`);
|
|
178
325
|
}
|
|
179
326
|
else {
|
|
180
327
|
chunks.push(`if(${descriptor}===undefined||!h.call(${descriptor},"value"))return false;`, `const ${itemValue}=${descriptor}.value;`, `if(!${emitExpression(entry.schema, itemValue, context)})return false;`);
|
|
181
328
|
}
|
|
182
329
|
}
|
|
330
|
+
chunks.push(emitObjectCatchallBody(schema, value, context));
|
|
183
331
|
chunks.push("return true;");
|
|
184
332
|
return chunks.join("");
|
|
185
333
|
}
|
|
334
|
+
/**
|
|
335
|
+
* @brief Emit catchall checks for undeclared object keys.
|
|
336
|
+
* @param schema Object schema with optional catchall.
|
|
337
|
+
* @param value Generated expression for the object value.
|
|
338
|
+
* @param context Shared code-generation context.
|
|
339
|
+
* @returns Generated source that validates extra own keys.
|
|
340
|
+
*/
|
|
341
|
+
function emitObjectCatchallBody(schema, value, context) {
|
|
342
|
+
if (schema.catchall === undefined) {
|
|
343
|
+
return "";
|
|
344
|
+
}
|
|
345
|
+
const keys = schema.keys;
|
|
346
|
+
const membership = keyMembershipExpression("key", keys, context);
|
|
347
|
+
return [
|
|
348
|
+
`const cx=Reflect.ownKeys(${value});`,
|
|
349
|
+
"for(let ci=0;ci<cx.length;ci+=1){",
|
|
350
|
+
"const key=cx[ci];",
|
|
351
|
+
`if(typeof key==="string"&&${membership})continue;`,
|
|
352
|
+
`const cd=gp(${value},key);`,
|
|
353
|
+
"if(cd===undefined||!h.call(cd,\"value\"))return false;",
|
|
354
|
+
`if(!${emitExpression(schema.catchall, "cd.value", context)})return false;`,
|
|
355
|
+
"}"
|
|
356
|
+
].join("");
|
|
357
|
+
}
|
|
186
358
|
/**
|
|
187
359
|
* @brief emit strict object key body.
|
|
188
360
|
* @details Emits a low-allocation known-key check specialized for one object shape.
|
|
361
|
+
* @param schema Object schema with mode and entries.
|
|
362
|
+
* @param value Generated expression for the object value.
|
|
363
|
+
* @param context Shared code-generation context.
|
|
189
364
|
* @returns Generated strict-key prelude, or an empty string for passthrough objects.
|
|
190
365
|
*/
|
|
191
366
|
function emitStrictObjectKeyBody(schema, value, context) {
|
|
192
|
-
if (schema.mode !== ObjectModeTag.Strict) {
|
|
367
|
+
if (schema.mode !== ObjectModeTag.Strict || schema.catchall !== undefined) {
|
|
193
368
|
return "";
|
|
194
369
|
}
|
|
195
370
|
const entries = schema.entries;
|
|
@@ -203,6 +378,10 @@ function emitStrictObjectKeyBody(schema, value, context) {
|
|
|
203
378
|
if (comparisons.length === 0) {
|
|
204
379
|
return `if(Reflect.ownKeys(${value}).length!==0)return false;`;
|
|
205
380
|
}
|
|
381
|
+
/*
|
|
382
|
+
* Reflect.ownKeys is required for strict objects because symbol and
|
|
383
|
+
* non-enumerable extras are still extras.
|
|
384
|
+
*/
|
|
206
385
|
return [
|
|
207
386
|
`const xs=Reflect.ownKeys(${value});`,
|
|
208
387
|
"for(let i=0;i<xs.length;i+=1){",
|
|
@@ -214,6 +393,10 @@ function emitStrictObjectKeyBody(schema, value, context) {
|
|
|
214
393
|
/**
|
|
215
394
|
* @brief emit discriminated union body.
|
|
216
395
|
* @details Emits discriminant selection once and dispatches to branch validators.
|
|
396
|
+
* @param key Discriminant property name.
|
|
397
|
+
* @param cases Closed discriminated union cases.
|
|
398
|
+
* @param value Generated expression for the candidate object.
|
|
399
|
+
* @param context Shared code-generation context.
|
|
217
400
|
* @returns Generated discriminated-union predicate body.
|
|
218
401
|
*/
|
|
219
402
|
function emitDiscriminatedUnionBody(key, cases, value, context) {
|
|
@@ -237,6 +420,12 @@ function emitDiscriminatedUnionBody(key, cases, value, context) {
|
|
|
237
420
|
}
|
|
238
421
|
/**
|
|
239
422
|
* @brief emit string.
|
|
423
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
424
|
+
* stable across runtime and AOT emission.
|
|
425
|
+
* @param schema String schema with scalar checks.
|
|
426
|
+
* @param value Generated expression for the candidate value.
|
|
427
|
+
* @param context Shared code-generation context.
|
|
428
|
+
* @returns JavaScript expression for the string predicate.
|
|
240
429
|
*/
|
|
241
430
|
function emitString(schema, value, context) {
|
|
242
431
|
const parts = [`(typeof ${value}==="string")`];
|
|
@@ -259,19 +448,52 @@ function emitString(schema, value, context) {
|
|
|
259
448
|
case StringCheckTag.Uuid:
|
|
260
449
|
parts.push(emitRegex(value, UUID_PATTERN, context));
|
|
261
450
|
break;
|
|
451
|
+
case StringCheckTag.Email:
|
|
452
|
+
parts.push(emitRegex(value, EMAIL_PATTERN, context));
|
|
453
|
+
break;
|
|
454
|
+
case StringCheckTag.Url:
|
|
455
|
+
parts.push(emitRegex(value, URL_PATTERN, context));
|
|
456
|
+
break;
|
|
457
|
+
case StringCheckTag.IsoDate:
|
|
458
|
+
parts.push(emitRegex(value, ISO_DATE_PATTERN, context));
|
|
459
|
+
break;
|
|
460
|
+
case StringCheckTag.IsoDateTime:
|
|
461
|
+
parts.push(emitRegex(value, ISO_DATETIME_PATTERN, context));
|
|
462
|
+
break;
|
|
463
|
+
case StringCheckTag.Ulid:
|
|
464
|
+
parts.push(emitRegex(value, ULID_PATTERN, context));
|
|
465
|
+
break;
|
|
466
|
+
case StringCheckTag.Ipv4:
|
|
467
|
+
parts.push(emitRegex(value, IPV4_PATTERN, context));
|
|
468
|
+
break;
|
|
469
|
+
case StringCheckTag.Ipv6:
|
|
470
|
+
parts.push(emitRegex(value, IPV6_PATTERN, context));
|
|
471
|
+
break;
|
|
262
472
|
}
|
|
263
473
|
}
|
|
264
474
|
return `(${parts.join("&&")})`;
|
|
265
475
|
}
|
|
266
476
|
/**
|
|
267
477
|
* @brief emit number.
|
|
478
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
479
|
+
* stable across runtime and AOT emission.
|
|
480
|
+
* @param schema Number schema with scalar checks.
|
|
481
|
+
* @param value Generated expression for the candidate value.
|
|
482
|
+
* @returns JavaScript expression for the number predicate.
|
|
268
483
|
*/
|
|
269
484
|
function emitNumber(schema, value) {
|
|
270
|
-
const
|
|
271
|
-
|
|
272
|
-
`Number.
|
|
273
|
-
|
|
485
|
+
const integer = numberChecksRequireInteger(schema.checks);
|
|
486
|
+
const parts = integer
|
|
487
|
+
? [`Number.isInteger(${value})`]
|
|
488
|
+
: [
|
|
489
|
+
`(typeof ${value}==="number")`,
|
|
490
|
+
`Number.isFinite(${value})`
|
|
491
|
+
];
|
|
274
492
|
const checks = schema.checks;
|
|
493
|
+
/*
|
|
494
|
+
* Number.isInteger already proves finite number, so integer schemas avoid
|
|
495
|
+
* emitting a separate typeof/finite pair.
|
|
496
|
+
*/
|
|
275
497
|
for (let index = 0; index < checks.length; index += 1) {
|
|
276
498
|
const check = checks[index];
|
|
277
499
|
if (check === undefined) {
|
|
@@ -279,7 +501,6 @@ function emitNumber(schema, value) {
|
|
|
279
501
|
}
|
|
280
502
|
switch (check.tag) {
|
|
281
503
|
case NumberCheckTag.Integer:
|
|
282
|
-
parts.push(`Number.isInteger(${value})`);
|
|
283
504
|
break;
|
|
284
505
|
case NumberCheckTag.Gte:
|
|
285
506
|
parts.push(`(${value}>=${String(check.value)})`);
|
|
@@ -287,12 +508,42 @@ function emitNumber(schema, value) {
|
|
|
287
508
|
case NumberCheckTag.Lte:
|
|
288
509
|
parts.push(`(${value}<=${String(check.value)})`);
|
|
289
510
|
break;
|
|
511
|
+
case NumberCheckTag.Gt:
|
|
512
|
+
parts.push(`(${value}>${String(check.value)})`);
|
|
513
|
+
break;
|
|
514
|
+
case NumberCheckTag.Lt:
|
|
515
|
+
parts.push(`(${value}<${String(check.value)})`);
|
|
516
|
+
break;
|
|
517
|
+
case NumberCheckTag.MultipleOf:
|
|
518
|
+
parts.push(`(${value}%${String(check.value)}===0)`);
|
|
519
|
+
break;
|
|
290
520
|
}
|
|
291
521
|
}
|
|
292
522
|
return `(${parts.join("&&")})`;
|
|
293
523
|
}
|
|
524
|
+
/**
|
|
525
|
+
* @brief Test whether a number schema contains an integer constraint.
|
|
526
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
527
|
+
* stable across runtime and AOT emission.
|
|
528
|
+
* @param checks Number check list.
|
|
529
|
+
* @returns True when Number.isInteger can replace the broader number guard.
|
|
530
|
+
*/
|
|
531
|
+
function numberChecksRequireInteger(checks) {
|
|
532
|
+
for (let index = 0; index < checks.length; index += 1) {
|
|
533
|
+
if (checks[index]?.tag === NumberCheckTag.Integer) {
|
|
534
|
+
return true;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
return false;
|
|
538
|
+
}
|
|
294
539
|
/**
|
|
295
540
|
* @brief emit union.
|
|
541
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
542
|
+
* stable across runtime and AOT emission.
|
|
543
|
+
* @param options Union option schemas.
|
|
544
|
+
* @param value Generated expression for the candidate value.
|
|
545
|
+
* @param context Shared code-generation context.
|
|
546
|
+
* @returns JavaScript expression for the union predicate.
|
|
296
547
|
*/
|
|
297
548
|
export function emitUnion(options, value, context) {
|
|
298
549
|
const parts = [];
|
|
@@ -309,9 +560,35 @@ export function emitUnion(options, value, context) {
|
|
|
309
560
|
}
|
|
310
561
|
/**
|
|
311
562
|
* @brief emit regex.
|
|
563
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
564
|
+
* stable across runtime and AOT emission.
|
|
565
|
+
* @param value Generated expression for the candidate string.
|
|
566
|
+
* @param regex Pattern to test.
|
|
567
|
+
* @param context Shared code-generation context.
|
|
568
|
+
* @returns JavaScript expression that resets lastIndex and tests the regex.
|
|
312
569
|
*/
|
|
313
570
|
function emitRegex(value, regex, context) {
|
|
314
571
|
const index = pushRegex(context, regex);
|
|
315
572
|
const access = `r[${String(index)}]`;
|
|
316
573
|
return `((${access}.lastIndex=0),${access}.test(${value}))`;
|
|
317
574
|
}
|
|
575
|
+
/**
|
|
576
|
+
* @brief Emit a side-table backed key membership expression.
|
|
577
|
+
* @param key Generated expression containing the candidate property key.
|
|
578
|
+
* @param keys Known object shape keys.
|
|
579
|
+
* @param context Shared code-generation context.
|
|
580
|
+
* @returns JavaScript expression that is true for known string keys.
|
|
581
|
+
*/
|
|
582
|
+
function keyMembershipExpression(key, keys, context) {
|
|
583
|
+
if (keys.length === 0) {
|
|
584
|
+
return "false";
|
|
585
|
+
}
|
|
586
|
+
const parts = new Array(keys.length);
|
|
587
|
+
for (let index = 0; index < keys.length; index += 1) {
|
|
588
|
+
const value = keys[index];
|
|
589
|
+
parts[index] = value === undefined
|
|
590
|
+
? "false"
|
|
591
|
+
: `${key}===${stringRef(context, value)}`;
|
|
592
|
+
}
|
|
593
|
+
return `(${parts.join("||")})`;
|
|
594
|
+
}
|
|
@@ -1,55 +1,142 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file compile-runtime.ts
|
|
3
3
|
* @brief Runtime support passed into generated validator factories.
|
|
4
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
5
|
+
* stable across runtime and AOT emission.
|
|
4
6
|
*
|
|
5
7
|
* @section side_tables Side-table ABI
|
|
6
8
|
* Generated validators receive literals, regexps, keysets, strings, and
|
|
7
9
|
* dynamic schema fallbacks as indexed tables. The emitted source contains only
|
|
8
10
|
* numeric table slots and compact helper names.
|
|
9
11
|
*/
|
|
10
|
-
import type { Issue, PathSegment } from "../issue/index.js";
|
|
12
|
+
import type { CheckResult, Issue, PathSegment } from "../issue/index.js";
|
|
11
13
|
import type { LiteralValue, Schema } from "../schema/index.js";
|
|
12
14
|
/**
|
|
13
|
-
* @brief
|
|
15
|
+
* @brief Allocation-lean validator root generated for `is` calls.
|
|
16
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
17
|
+
* stable across runtime and AOT emission.
|
|
18
|
+
* @param value Candidate runtime value.
|
|
19
|
+
* @returns True when the generated predicate accepts the value.
|
|
14
20
|
*/
|
|
15
21
|
export type BooleanPredicate = (value: unknown) => boolean;
|
|
16
22
|
/**
|
|
17
|
-
* @brief
|
|
23
|
+
* @brief Diagnostic collector generated for `check` calls.
|
|
24
|
+
* @details Generated collectors return undefined for the successful fast path.
|
|
25
|
+
* Hand-written collectors still have to return an issue array and are validated
|
|
26
|
+
* before publication.
|
|
27
|
+
* @param value Candidate runtime value.
|
|
28
|
+
* @returns Undefined on success, otherwise the collected validation issues.
|
|
18
29
|
*/
|
|
19
|
-
export type IssueCollectorRoot = (value: unknown) => readonly Issue[];
|
|
30
|
+
export type IssueCollectorRoot = (value: unknown) => readonly Issue[] | undefined;
|
|
20
31
|
/**
|
|
21
|
-
* @brief
|
|
32
|
+
* @brief Result-producing wrapper generated beside every compiled predicate.
|
|
33
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
34
|
+
* stable across runtime and AOT emission.
|
|
35
|
+
* @param value Candidate runtime value.
|
|
36
|
+
* @returns TypeSea check result carrying the accepted value or issue list.
|
|
37
|
+
*/
|
|
38
|
+
export type CheckResultRoot = (value: unknown) => CheckResult<unknown>;
|
|
39
|
+
/**
|
|
40
|
+
* @brief Boolean fallback for schemas that cannot be fully lowered.
|
|
41
|
+
* @details Generated code stores only a schema table index. The helper keeps
|
|
42
|
+
* recursive and user-refined branches out of the emitted source while retaining
|
|
43
|
+
* the same boolean contract as the interpreter.
|
|
44
|
+
* @param schemaIndex Slot in the side table supplied to the factory.
|
|
45
|
+
* @param value Candidate value for that schema.
|
|
46
|
+
* @returns True when the fallback schema accepts the value.
|
|
22
47
|
*/
|
|
23
48
|
export type DynamicCheck = (schemaIndex: number, value: unknown) => boolean;
|
|
24
49
|
/**
|
|
25
|
-
* @brief
|
|
50
|
+
* @brief Diagnostic fallback for non-lowered schema fragments.
|
|
51
|
+
* @details The generated collector delegates here only at opaque graph leaves.
|
|
52
|
+
* Nested issues are copied into the caller-owned buffer so the outer generated
|
|
53
|
+
* path prefix remains in control.
|
|
54
|
+
* @param schemaIndex Slot in the side table supplied to the factory.
|
|
55
|
+
* @param value Candidate value for that schema.
|
|
56
|
+
* @param path Path prefix owned by the generated collector.
|
|
57
|
+
* @param issues Mutable issue buffer owned by the caller.
|
|
26
58
|
*/
|
|
27
59
|
export type DynamicIssueCheck = (schemaIndex: number, value: unknown, path: readonly PathSegment[], issues: Issue[]) => void;
|
|
28
60
|
/**
|
|
29
|
-
* @brief
|
|
61
|
+
* @brief First-fault fallback for non-lowered schema fragments.
|
|
62
|
+
* @details Opaque lazy and refine schemas use the interpreter for correctness,
|
|
63
|
+
* then return only the first nested issue under the generated path prefix.
|
|
64
|
+
* @param schemaIndex Slot in the side table supplied to the factory.
|
|
65
|
+
* @param value Candidate value for that schema.
|
|
66
|
+
* @param path Path prefix owned by the generated collector.
|
|
67
|
+
* @returns First nested issue, or undefined when the fallback accepts the value.
|
|
68
|
+
*/
|
|
69
|
+
export type DynamicFirstIssueCheck = (schemaIndex: number, value: unknown, path: readonly PathSegment[]) => Issue | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* @brief Runtime helper for strict-object excess key validation.
|
|
72
|
+
* @details Code generation can choose safe or fast property access strategies,
|
|
73
|
+
* but strict key counting remains centralized so the emitted source uses a
|
|
74
|
+
* compact ABI.
|
|
75
|
+
* @param value Candidate object.
|
|
76
|
+
* @param keys Allowed string keys for the strict schema.
|
|
77
|
+
* @returns True when no extra own string key is present.
|
|
30
78
|
*/
|
|
31
79
|
export type StrictKeysCheck = (value: unknown, keys: readonly string[]) => boolean;
|
|
32
80
|
/**
|
|
33
|
-
* @brief
|
|
81
|
+
* @brief Published validator entry points returned by a compiled factory.
|
|
82
|
+
* @details The three functions share side tables and generated helper code but
|
|
83
|
+
* expose the distinct public contracts used by Guard methods.
|
|
34
84
|
*/
|
|
35
85
|
export interface RuntimeBundle {
|
|
36
86
|
readonly is: BooleanPredicate;
|
|
37
87
|
readonly check: IssueCollectorRoot;
|
|
88
|
+
readonly result: CheckResultRoot;
|
|
89
|
+
readonly first: CheckResultRoot;
|
|
38
90
|
}
|
|
39
91
|
/**
|
|
40
|
-
* @brief
|
|
92
|
+
* @brief Factory signature consumed by `new Function` compiled modules.
|
|
93
|
+
* @details Generated source is pure JavaScript text. All runtime objects that
|
|
94
|
+
* should not be serialized into source travel through these side tables, which
|
|
95
|
+
* keeps emitted code small and friendly to V8 inline caches.
|
|
96
|
+
* @param literals Literal constants referenced by emitted predicates.
|
|
97
|
+
* @param regexps Precompiled regular expressions for string constraints.
|
|
98
|
+
* @param keysets Strict-object key tables.
|
|
99
|
+
* @param strings Shared string constants used by generated diagnostics.
|
|
100
|
+
* @param dynamicCheck Boolean fallback for opaque schema fragments.
|
|
101
|
+
* @param dynamicIssueCheck Diagnostic fallback for opaque schema fragments.
|
|
102
|
+
* @param strictKeys Shared strict-object excess key helper.
|
|
103
|
+
* @returns Runtime bundle exposed by the compiled guard.
|
|
41
104
|
*/
|
|
42
|
-
export type IsFactory = (literals: readonly LiteralValue[], regexps: readonly RegExp[], keysets: readonly (readonly string[])[], strings: readonly string[], dynamicCheck: DynamicCheck, dynamicIssueCheck: DynamicIssueCheck, strictKeys: StrictKeysCheck) => RuntimeBundle;
|
|
105
|
+
export type IsFactory = (literals: readonly LiteralValue[], regexps: readonly RegExp[], keysets: readonly (readonly string[])[], strings: readonly string[], dynamicCheck: DynamicCheck, dynamicIssueCheck: DynamicIssueCheck, dynamicFirstIssueCheck: DynamicFirstIssueCheck, strictKeys: StrictKeysCheck) => RuntimeBundle;
|
|
43
106
|
/**
|
|
44
|
-
* @brief
|
|
107
|
+
* @brief Build the boolean fallback table reader for generated validators.
|
|
108
|
+
* @details Missing table slots fail closed. That preserves the security
|
|
109
|
+
* invariant that malformed generated code cannot accidentally accept a value by
|
|
110
|
+
* indexing outside the schema side table.
|
|
111
|
+
* @param schemas Schema side table captured by the compiled guard.
|
|
112
|
+
* @returns Boolean fallback callback used by emitted predicates.
|
|
45
113
|
*/
|
|
46
114
|
export declare function makeDynamicCheck(schemas: readonly Schema[]): DynamicCheck;
|
|
47
115
|
/**
|
|
48
|
-
* @brief
|
|
116
|
+
* @brief Build the diagnostic fallback table reader for generated validators.
|
|
117
|
+
* @details Nested interpreter issues are re-rooted under the path supplied by
|
|
118
|
+
* generated code. This lets compiled object and array checks delegate complex
|
|
119
|
+
* children without losing exact issue locations.
|
|
120
|
+
* @param schemas Schema side table captured by the compiled guard.
|
|
121
|
+
* @returns Issue fallback callback used by emitted collectors.
|
|
49
122
|
*/
|
|
50
123
|
export declare function makeDynamicIssueCheck(schemas: readonly Schema[]): DynamicIssueCheck;
|
|
51
124
|
/**
|
|
52
|
-
* @brief
|
|
125
|
+
* @brief Build the first-fault fallback table reader for generated validators.
|
|
126
|
+
* @details This path is entered only for opaque schema fragments that codegen
|
|
127
|
+
* cannot inline. The nested interpreter result is re-rooted once and returned.
|
|
128
|
+
* @param schemas Schema side table captured by the compiled guard.
|
|
129
|
+
* @returns First-issue fallback callback used by emitted collectors.
|
|
130
|
+
*/
|
|
131
|
+
export declare function makeDynamicFirstIssueCheck(schemas: readonly Schema[]): DynamicFirstIssueCheck;
|
|
132
|
+
/**
|
|
133
|
+
* @brief Safe strict-object key membership helper for generated validators.
|
|
134
|
+
* @details The default compiled mode uses Reflect.ownKeys so symbol and
|
|
135
|
+
* non-enumerable extras are rejected as strictly as the interpreter. Unsafe
|
|
136
|
+
* modes may emit a cheaper loop, but this helper remains the conservative ABI.
|
|
137
|
+
* @param value Candidate object value.
|
|
138
|
+
* @param keys Allowed string keys for the strict object schema.
|
|
139
|
+
* @returns True when every own key belongs to the schema key set.
|
|
53
140
|
*/
|
|
54
141
|
export declare function strictKeys(value: unknown, keys: readonly string[]): boolean;
|
|
55
142
|
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/compile/runtime.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/compile/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE/D;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;AAE3D;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,SAAS,KAAK,EAAE,GAAG,SAAS,CAAC;AAElF;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,WAAW,CAAC,OAAO,CAAC,CAAC;AAEvE;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;AAE5E;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAC5B,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,SAAS,WAAW,EAAE,EAC5B,MAAM,EAAE,KAAK,EAAE,KACd,IAAI,CAAC;AAEV;;;;;;;;GAQG;AACH,MAAM,MAAM,sBAAsB,GAAG,CACjC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,SAAS,WAAW,EAAE,KAC3B,KAAK,GAAG,SAAS,CAAC;AAEvB;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GAAG,CAC1B,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,SAAS,MAAM,EAAE,KACtB,OAAO,CAAC;AAEb;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,EAAE,EAAE,gBAAgB,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;CACnC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,SAAS,GAAG,CACpB,QAAQ,EAAE,SAAS,YAAY,EAAE,EACjC,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,OAAO,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,EACvC,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,YAAY,EAAE,YAAY,EAC1B,iBAAiB,EAAE,iBAAiB,EACpC,sBAAsB,EAAE,sBAAsB,EAC9C,UAAU,EAAE,eAAe,KAC1B,aAAa,CAAC;AAEnB;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,YAAY,CAKzE;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACjC,OAAO,EAAE,SAAS,MAAM,EAAE,GAC3B,iBAAiB,CA8BnB;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACtC,OAAO,EAAE,SAAS,MAAM,EAAE,GAC3B,sBAAsB,CA2BxB;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACtB,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,SAAS,MAAM,EAAE,GACxB,OAAO,CAYT"}
|