typesea 0.1.0 → 0.2.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 +67 -6
- package/README.md +98 -17
- 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 +18 -2
- package/dist/aot/index.d.ts.map +1 -1
- package/dist/aot/index.js +93 -14
- 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 +37 -6
- package/dist/builders/composite.d.ts.map +1 -1
- package/dist/builders/composite.js +84 -10
- package/dist/builders/index.d.ts +2 -0
- package/dist/builders/index.d.ts.map +1 -1
- package/dist/builders/index.js +2 -0
- package/dist/builders/modifier.d.ts +30 -5
- package/dist/builders/modifier.d.ts.map +1 -1
- package/dist/builders/modifier.js +38 -5
- package/dist/builders/object/guard.d.ts +18 -22
- package/dist/builders/object/guard.d.ts.map +1 -1
- package/dist/builders/object/guard.js +26 -26
- package/dist/builders/object/index.d.ts +2 -0
- package/dist/builders/object/index.d.ts.map +1 -1
- package/dist/builders/object/index.js +2 -0
- package/dist/builders/object/schema.d.ts +55 -9
- package/dist/builders/object/schema.d.ts.map +1 -1
- package/dist/builders/object/schema.js +92 -15
- package/dist/builders/object/types.d.ts +5 -31
- package/dist/builders/object/types.d.ts.map +1 -1
- package/dist/builders/object/types.js +2 -0
- package/dist/builders/scalar.d.ts +29 -8
- package/dist/builders/scalar.d.ts.map +1 -1
- package/dist/builders/scalar.js +33 -8
- package/dist/builders/table.d.ts +4 -0
- package/dist/builders/table.d.ts.map +1 -1
- package/dist/builders/table.js +4 -0
- package/dist/builders/types.d.ts +14 -4
- package/dist/builders/types.d.ts.map +1 -1
- package/dist/builders/types.js +2 -0
- package/dist/compile/check-composite.d.ts +22 -1
- package/dist/compile/check-composite.d.ts.map +1 -1
- package/dist/compile/check-composite.js +564 -24
- package/dist/compile/check-scalar.d.ts +78 -0
- package/dist/compile/check-scalar.d.ts.map +1 -1
- package/dist/compile/check-scalar.js +432 -1
- package/dist/compile/check.d.ts +12 -0
- package/dist/compile/check.d.ts.map +1 -1
- package/dist/compile/check.js +37 -0
- package/dist/compile/context.d.ts +47 -9
- package/dist/compile/context.d.ts.map +1 -1
- package/dist/compile/context.js +51 -8
- 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 +1907 -171
- package/dist/compile/guard.d.ts +15 -24
- package/dist/compile/guard.d.ts.map +1 -1
- package/dist/compile/guard.js +158 -74
- 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 +131 -5
- package/dist/compile/runtime.d.ts +80 -12
- package/dist/compile/runtime.d.ts.map +1 -1
- package/dist/compile/runtime.js +25 -6
- package/dist/compile/source.d.ts +10 -2
- package/dist/compile/source.d.ts.map +1 -1
- package/dist/compile/source.js +361 -26
- package/dist/compile/types.d.ts +20 -0
- package/dist/compile/types.d.ts.map +1 -1
- package/dist/compile/types.js +2 -0
- package/dist/decoder/index.d.ts +32 -46
- package/dist/decoder/index.d.ts.map +1 -1
- package/dist/decoder/index.js +102 -38
- package/dist/evaluate/check-composite.d.ts +59 -0
- package/dist/evaluate/check-composite.d.ts.map +1 -1
- package/dist/evaluate/check-composite.js +151 -3
- package/dist/evaluate/check-scalar.d.ts +16 -0
- package/dist/evaluate/check-scalar.d.ts.map +1 -1
- package/dist/evaluate/check-scalar.js +32 -0
- package/dist/evaluate/check.d.ts +7 -0
- package/dist/evaluate/check.d.ts.map +1 -1
- package/dist/evaluate/check.js +43 -0
- 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 +59 -13
- package/dist/evaluate/shared.d.ts.map +1 -1
- package/dist/evaluate/shared.js +66 -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/base.d.ts +79 -29
- package/dist/guard/base.d.ts.map +1 -1
- package/dist/guard/base.js +91 -29
- 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 +2 -0
- package/dist/guard/index.d.ts.map +1 -1
- package/dist/guard/index.js +2 -0
- package/dist/guard/number.d.ts +26 -11
- package/dist/guard/number.d.ts.map +1 -1
- package/dist/guard/number.js +30 -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 +62 -9
- package/dist/guard/read.d.ts.map +1 -1
- package/dist/guard/read.js +83 -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 +33 -13
- package/dist/guard/string.d.ts.map +1 -1
- package/dist/guard/string.js +37 -13
- package/dist/guard/types.d.ts +92 -40
- package/dist/guard/types.d.ts.map +1 -1
- package/dist/guard/types.js +2 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- 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 +16 -126
- package/dist/ir/builder.d.ts.map +1 -1
- package/dist/ir/builder.js +77 -137
- package/dist/ir/freeze.d.ts +4 -0
- package/dist/ir/freeze.d.ts.map +1 -1
- package/dist/ir/freeze.js +59 -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 +90 -55
- 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 +477 -61
- package/dist/issue/index.d.ts +41 -9
- package/dist/issue/index.d.ts.map +1 -1
- package/dist/issue/index.js +61 -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 +10 -0
- package/dist/json-schema/emit-composite.d.ts.map +1 -1
- package/dist/json-schema/emit-composite.js +15 -1
- 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 +70 -9
- 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 +12 -1
- 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 +38 -15
- package/dist/json-schema/types.d.ts.map +1 -1
- package/dist/json-schema/types.js +2 -0
- package/dist/kind/index.d.ts +15 -28
- package/dist/kind/index.d.ts.map +1 -1
- package/dist/kind/index.js +15 -10
- package/dist/lower/index.d.ts +6 -1
- package/dist/lower/index.d.ts.map +1 -1
- package/dist/lower/index.js +411 -44
- package/dist/message/index.d.ts +46 -10
- package/dist/message/index.d.ts.map +1 -1
- package/dist/message/index.js +88 -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 +615 -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 +45 -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 +21 -5
- 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 +268 -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 +117 -13
- 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 +18 -0
- package/dist/schema/index.d.ts +3 -0
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +3 -0
- 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 +20 -96
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +5 -1
- package/dist/schema/undefined.d.ts +17 -0
- package/dist/schema/undefined.d.ts.map +1 -0
- package/dist/schema/undefined.js +72 -0
- package/dist/schema/validate.d.ts +8 -1
- package/dist/schema/validate.d.ts.map +1 -1
- package/dist/schema/validate.js +146 -55
- package/docs/api.md +57 -0
- package/docs/assets/benchmark-headline.svg +163 -0
- package/docs/engine-notes.md +58 -15
- package/docs/index.html +130 -110
- package/package.json +65 -65
package/dist/compile/issue.js
CHANGED
|
@@ -1,28 +1,211 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file compile/issue.ts
|
|
3
3
|
* @brief Diagnostic issue source snippets.
|
|
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
|
import { UUID_PATTERN } from "../schema/index.js";
|
|
6
8
|
import { pushRegex, stringRef } from "./context.js";
|
|
7
9
|
import { stringLiteral } from "./names.js";
|
|
8
10
|
/**
|
|
9
11
|
* @brief emit pattern issue.
|
|
12
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
13
|
+
* stable across runtime and AOT emission.
|
|
14
|
+
* @param value Generated expression for the string value.
|
|
15
|
+
* @param path Generated expression for the current diagnostic path.
|
|
16
|
+
* @param issues Generated expression for the diagnostic buffer.
|
|
17
|
+
* @param regex Pattern used by the schema check.
|
|
18
|
+
* @param name Human-readable pattern name stored in the issue.
|
|
19
|
+
* @param context Shared code-generation context.
|
|
20
|
+
* @returns JavaScript source that appends a pattern issue when the test fails.
|
|
10
21
|
*/
|
|
11
22
|
export function emitPatternIssue(value, path, issues, regex, name, context) {
|
|
12
23
|
const source = regex === UUID_PATTERN ? UUID_PATTERN : regex;
|
|
13
24
|
const index = pushRegex(context, source);
|
|
14
25
|
const access = `r[${String(index)}]`;
|
|
15
|
-
|
|
26
|
+
const test = regexNeedsLastIndexReset(source)
|
|
27
|
+
? `((${access}.lastIndex=0),!${access}.test(${value}))`
|
|
28
|
+
: `!${access}.test(${value})`;
|
|
29
|
+
/*
|
|
30
|
+
* Pattern names live in the string side table. That keeps generated source
|
|
31
|
+
* stable even when users provide long or escaped pattern descriptions.
|
|
32
|
+
*/
|
|
33
|
+
return `if(${test}){${emitIssueExpr(issues, path, "expected_pattern", stringRef(context, name), stringLiteral("string"))}}`;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* @brief emit pattern issue at one appended path segment.
|
|
37
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
38
|
+
* stable across runtime and AOT emission.
|
|
39
|
+
* @param value Generated expression for the string value.
|
|
40
|
+
* @param path Generated expression for the current diagnostic path.
|
|
41
|
+
* @param segmentExpression Generated expression for the appended segment.
|
|
42
|
+
* @param issues Generated expression for the diagnostic buffer.
|
|
43
|
+
* @param regex Pattern used by the schema check.
|
|
44
|
+
* @param name Human-readable pattern name stored in the issue.
|
|
45
|
+
* @param context Shared code-generation context.
|
|
46
|
+
* @returns JavaScript source that appends a one-segment pattern issue.
|
|
47
|
+
*/
|
|
48
|
+
export function emitPatternIssueAtSegment(value, path, segmentExpression, issues, regex, name, context) {
|
|
49
|
+
const source = regex === UUID_PATTERN ? UUID_PATTERN : regex;
|
|
50
|
+
const index = pushRegex(context, source);
|
|
51
|
+
const access = `r[${String(index)}]`;
|
|
52
|
+
const test = regexNeedsLastIndexReset(source)
|
|
53
|
+
? `((${access}.lastIndex=0),!${access}.test(${value}))`
|
|
54
|
+
: `!${access}.test(${value})`;
|
|
55
|
+
return `if(${test}){${emitIssueExprAtSegment(issues, path, segmentExpression, "expected_pattern", stringRef(context, name), stringLiteral("string"))}}`;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* @brief emit pattern issue at two appended path segments.
|
|
59
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
60
|
+
* stable across runtime and AOT emission.
|
|
61
|
+
* @param value Generated expression for the string value.
|
|
62
|
+
* @param path Generated expression for the current diagnostic path.
|
|
63
|
+
* @param firstSegmentExpression Generated expression for the first appended segment.
|
|
64
|
+
* @param secondSegmentExpression Generated expression for the second appended segment.
|
|
65
|
+
* @param issues Generated expression for the diagnostic buffer.
|
|
66
|
+
* @param regex Pattern used by the schema check.
|
|
67
|
+
* @param name Human-readable pattern name stored in the issue.
|
|
68
|
+
* @param context Shared code-generation context.
|
|
69
|
+
* @returns JavaScript source that appends a two-segment pattern issue.
|
|
70
|
+
*/
|
|
71
|
+
export function emitPatternIssueAtTwoSegments(value, path, firstSegmentExpression, secondSegmentExpression, issues, regex, name, context) {
|
|
72
|
+
const source = regex === UUID_PATTERN ? UUID_PATTERN : regex;
|
|
73
|
+
const index = pushRegex(context, source);
|
|
74
|
+
const access = `r[${String(index)}]`;
|
|
75
|
+
const test = regexNeedsLastIndexReset(source)
|
|
76
|
+
? `((${access}.lastIndex=0),!${access}.test(${value}))`
|
|
77
|
+
: `!${access}.test(${value})`;
|
|
78
|
+
return `if(${test}){${emitIssueExprAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_pattern", stringRef(context, name), stringLiteral("string"))}}`;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* @brief Decide whether a RegExp must be reset before generated testing.
|
|
82
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
83
|
+
* stable across runtime and AOT emission.
|
|
84
|
+
* @param regex RegExp stored in the generated side table.
|
|
85
|
+
* @returns True for stateful global or sticky expressions.
|
|
86
|
+
*/
|
|
87
|
+
function regexNeedsLastIndexReset(regex) {
|
|
88
|
+
return regex.global || regex.sticky;
|
|
16
89
|
}
|
|
17
90
|
/**
|
|
18
91
|
* @brief emit issue.
|
|
92
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
93
|
+
* stable across runtime and AOT emission.
|
|
94
|
+
* @param issues Generated expression for the diagnostic buffer.
|
|
95
|
+
* @param path Generated expression for the current diagnostic path.
|
|
96
|
+
* @param code Issue code string.
|
|
97
|
+
* @param expected Expected type or condition text.
|
|
98
|
+
* @param actualExpression Generated expression for actual type text.
|
|
99
|
+
* @returns JavaScript source that appends an issue at the current path.
|
|
19
100
|
*/
|
|
20
101
|
export function emitIssue(issues, path, code, expected, actualExpression) {
|
|
21
102
|
return emitIssueExpr(issues, path, code, stringLiteral(expected), actualExpression);
|
|
22
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* @brief emit issue at one appended path segment.
|
|
106
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
107
|
+
* stable across runtime and AOT emission.
|
|
108
|
+
* @param issues Generated expression for the diagnostic buffer.
|
|
109
|
+
* @param path Generated expression for the current diagnostic path.
|
|
110
|
+
* @param segmentExpression Generated expression for the appended segment.
|
|
111
|
+
* @param code Issue code string.
|
|
112
|
+
* @param expected Expected type or condition text.
|
|
113
|
+
* @param actualExpression Generated expression for actual type text.
|
|
114
|
+
* @returns JavaScript source that appends an issue under one extra segment.
|
|
115
|
+
*/
|
|
116
|
+
export function emitIssueAtSegment(issues, path, segmentExpression, code, expected, actualExpression) {
|
|
117
|
+
return emitIssueExprAtSegment(issues, path, segmentExpression, code, stringLiteral(expected), actualExpression);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* @brief emit issue at two appended path segments.
|
|
121
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
122
|
+
* stable across runtime and AOT emission.
|
|
123
|
+
* @param issues Generated expression for the diagnostic buffer.
|
|
124
|
+
* @param path Generated expression for the current diagnostic path.
|
|
125
|
+
* @param firstSegmentExpression Generated expression for the first appended segment.
|
|
126
|
+
* @param secondSegmentExpression Generated expression for the second appended segment.
|
|
127
|
+
* @param code Issue code string.
|
|
128
|
+
* @param expected Expected type or condition text.
|
|
129
|
+
* @param actualExpression Generated expression for actual type text.
|
|
130
|
+
* @returns JavaScript source that appends an issue under two extra segments.
|
|
131
|
+
*/
|
|
132
|
+
export function emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, code, expected, actualExpression) {
|
|
133
|
+
return emitIssueExprAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, code, stringLiteral(expected), actualExpression);
|
|
134
|
+
}
|
|
23
135
|
/**
|
|
24
136
|
* @brief emit issue expr.
|
|
137
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
138
|
+
* stable across runtime and AOT emission.
|
|
139
|
+
* @param issues Generated expression for the diagnostic buffer.
|
|
140
|
+
* @param path Generated expression for the current diagnostic path.
|
|
141
|
+
* @param code Issue code string.
|
|
142
|
+
* @param expectedExpression Generated expression for expected text.
|
|
143
|
+
* @param actualExpression Generated expression for actual type text.
|
|
144
|
+
* @returns JavaScript source that appends an issue using expression operands.
|
|
25
145
|
*/
|
|
26
146
|
export function emitIssueExpr(issues, path, code, expectedExpression, actualExpression) {
|
|
27
147
|
return `q(${issues},${path},${stringLiteral(code)},${expectedExpression},${actualExpression});`;
|
|
28
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* @brief emit issue expr at one appended path segment.
|
|
151
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
152
|
+
* stable across runtime and AOT emission.
|
|
153
|
+
* @param issues Generated expression for the diagnostic buffer.
|
|
154
|
+
* @param path Generated expression for the current diagnostic path.
|
|
155
|
+
* @param segmentExpression Generated expression for the appended segment.
|
|
156
|
+
* @param code Issue code string.
|
|
157
|
+
* @param expectedExpression Generated expression for expected text.
|
|
158
|
+
* @param actualExpression Generated expression for actual type text.
|
|
159
|
+
* @returns JavaScript source using the most compact one-segment issue helper.
|
|
160
|
+
*/
|
|
161
|
+
export function emitIssueExprAtSegment(issues, path, segmentExpression, code, expectedExpression, actualExpression) {
|
|
162
|
+
const stringIndex = readStringRefIndex(segmentExpression);
|
|
163
|
+
if (stringIndex !== undefined) {
|
|
164
|
+
/*
|
|
165
|
+
* q1s reuses the pre-frozen path segment cache for static string keys.
|
|
166
|
+
* Dynamic segments still go through q1 because their value is known only
|
|
167
|
+
* inside the generated validator.
|
|
168
|
+
*/
|
|
169
|
+
return `q1s(${issues},${path},${stringIndex},${stringLiteral(code)},${expectedExpression},${actualExpression});`;
|
|
170
|
+
}
|
|
171
|
+
return `q1(${issues},${path},${segmentExpression},${stringLiteral(code)},${expectedExpression},${actualExpression});`;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* @brief emit issue expr at two appended path segments.
|
|
175
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
176
|
+
* stable across runtime and AOT emission.
|
|
177
|
+
* @param issues Generated expression for the diagnostic buffer.
|
|
178
|
+
* @param path Generated expression for the current diagnostic path.
|
|
179
|
+
* @param firstSegmentExpression Generated expression for the first appended segment.
|
|
180
|
+
* @param secondSegmentExpression Generated expression for the second appended segment.
|
|
181
|
+
* @param code Issue code string.
|
|
182
|
+
* @param expectedExpression Generated expression for expected text.
|
|
183
|
+
* @param actualExpression Generated expression for actual type text.
|
|
184
|
+
* @returns JavaScript source using the two-segment issue helper.
|
|
185
|
+
*/
|
|
186
|
+
export function emitIssueExprAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, code, expectedExpression, actualExpression) {
|
|
187
|
+
return `q2(${issues},${path},${firstSegmentExpression},${secondSegmentExpression},${stringLiteral(code)},${expectedExpression},${actualExpression});`;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* @brief Extract the numeric side-table index from a generated string reference.
|
|
191
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
192
|
+
* stable across runtime and AOT emission.
|
|
193
|
+
* @param expression Candidate generated expression such as `u[3]`.
|
|
194
|
+
* @returns Index text when the expression is a plain string-table read.
|
|
195
|
+
*/
|
|
196
|
+
function readStringRefIndex(expression) {
|
|
197
|
+
if (!expression.startsWith("u[") || !expression.endsWith("]")) {
|
|
198
|
+
return undefined;
|
|
199
|
+
}
|
|
200
|
+
const value = expression.slice(2, -1);
|
|
201
|
+
if (value.length === 0) {
|
|
202
|
+
return undefined;
|
|
203
|
+
}
|
|
204
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
205
|
+
const code = value.charCodeAt(index);
|
|
206
|
+
if (code < 48 || code > 57) {
|
|
207
|
+
return undefined;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return value;
|
|
211
|
+
}
|
package/dist/compile/names.d.ts
CHANGED
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file compile-names.ts
|
|
3
3
|
* @brief Generated function-name and string literal helpers.
|
|
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
|
* @invariant User-provided names never enter generated source until they are
|
|
6
8
|
* reduced to a strict-mode-safe identifier with a fixed length bound.
|
|
7
9
|
*/
|
|
8
10
|
/**
|
|
9
|
-
* @brief
|
|
11
|
+
* @brief Convert a user supplied compile name into a strict-mode function id.
|
|
12
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
13
|
+
* stable across runtime and AOT emission.
|
|
14
|
+
* @param value Requested public function name.
|
|
15
|
+
* @returns Identifier-safe, reserved-word-safe, bounded function name.
|
|
10
16
|
*/
|
|
11
17
|
export declare function safeFunctionName(value: string): string;
|
|
12
18
|
/**
|
|
13
|
-
* @brief string
|
|
19
|
+
* @brief Quote a string for generated JavaScript source.
|
|
20
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
21
|
+
* stable across runtime and AOT emission.
|
|
22
|
+
* @param value Runtime string to embed.
|
|
23
|
+
* @returns JSON-escaped string literal source.
|
|
14
24
|
*/
|
|
15
25
|
export declare function stringLiteral(value: string): string;
|
|
16
26
|
//# sourceMappingURL=names.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"names.d.ts","sourceRoot":"","sources":["../../src/compile/names.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"names.d.ts","sourceRoot":"","sources":["../../src/compile/names.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAgBtD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnD"}
|
package/dist/compile/names.js
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file compile-names.ts
|
|
3
3
|
* @brief Generated function-name and string literal helpers.
|
|
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
|
* @invariant User-provided names never enter generated source until they are
|
|
6
8
|
* reduced to a strict-mode-safe identifier with a fixed length bound.
|
|
7
9
|
*/
|
|
8
10
|
const MAX_GENERATED_FUNCTION_NAME_LENGTH = 96;
|
|
9
11
|
/**
|
|
10
|
-
* @brief
|
|
12
|
+
* @brief Convert a user supplied compile name into a strict-mode function id.
|
|
13
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
14
|
+
* stable across runtime and AOT emission.
|
|
15
|
+
* @param value Requested public function name.
|
|
16
|
+
* @returns Identifier-safe, reserved-word-safe, bounded function name.
|
|
11
17
|
*/
|
|
12
18
|
export function safeFunctionName(value) {
|
|
13
19
|
const replaced = value.replace(/[^$_a-zA-Z0-9]/gu, "_");
|
|
@@ -17,19 +23,29 @@ export function safeFunctionName(value) {
|
|
|
17
23
|
if (/^[$_a-zA-Z]/u.test(bounded) && !reservedFunctionNames.has(bounded)) {
|
|
18
24
|
return bounded;
|
|
19
25
|
}
|
|
26
|
+
/*
|
|
27
|
+
* Prefixing recovers names that start with a digit or collide with reserved
|
|
28
|
+
* words while keeping the final identifier under the same length cap.
|
|
29
|
+
*/
|
|
20
30
|
const prefixed = `_${bounded}`;
|
|
21
31
|
return prefixed.length > MAX_GENERATED_FUNCTION_NAME_LENGTH
|
|
22
32
|
? prefixed.slice(0, MAX_GENERATED_FUNCTION_NAME_LENGTH)
|
|
23
33
|
: prefixed;
|
|
24
34
|
}
|
|
25
35
|
/**
|
|
26
|
-
* @brief string
|
|
36
|
+
* @brief Quote a string for generated JavaScript source.
|
|
37
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
38
|
+
* stable across runtime and AOT emission.
|
|
39
|
+
* @param value Runtime string to embed.
|
|
40
|
+
* @returns JSON-escaped string literal source.
|
|
27
41
|
*/
|
|
28
42
|
export function stringLiteral(value) {
|
|
29
43
|
return JSON.stringify(value);
|
|
30
44
|
}
|
|
31
45
|
/**
|
|
32
|
-
* @brief
|
|
46
|
+
* @brief Strict-mode names that cannot be emitted as generated function ids.
|
|
47
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
48
|
+
* stable across runtime and AOT emission.
|
|
33
49
|
*/
|
|
34
50
|
const reservedFunctionNames = new Set([
|
|
35
51
|
"arguments",
|
|
@@ -1,23 +1,47 @@
|
|
|
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
7
|
import { type Schema } from "../schema/index.js";
|
|
6
8
|
import type { EmitContext } from "./types.js";
|
|
7
9
|
/**
|
|
8
10
|
* @brief emit function.
|
|
11
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
12
|
+
* stable across runtime and AOT emission.
|
|
13
|
+
* @param schema Schema represented by the predicate.
|
|
14
|
+
* @param context Shared code-generation context.
|
|
15
|
+
* @returns Generated predicate function name.
|
|
16
|
+
* @invariant The same schema object maps to one predicate function per bundle.
|
|
9
17
|
*/
|
|
10
18
|
export declare function emitFunction(schema: Schema, context: EmitContext): string;
|
|
11
19
|
/**
|
|
12
20
|
* @brief emit functions.
|
|
21
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
22
|
+
* stable across runtime and AOT emission.
|
|
23
|
+
* @param context Shared code-generation context with accumulated predicate sources.
|
|
24
|
+
* @returns Concatenated JavaScript function declarations.
|
|
13
25
|
*/
|
|
14
26
|
export declare function emitFunctions(context: EmitContext): string;
|
|
15
27
|
/**
|
|
16
28
|
* @brief emit expression.
|
|
29
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
30
|
+
* stable across runtime and AOT emission.
|
|
31
|
+
* @param schema Schema represented by the expression.
|
|
32
|
+
* @param value Generated expression for the candidate value.
|
|
33
|
+
* @param context Shared code-generation context.
|
|
34
|
+
* @returns JavaScript expression that evaluates to a boolean.
|
|
17
35
|
*/
|
|
18
36
|
export declare function emitExpression(schema: Schema, value: string, context: EmitContext): string;
|
|
19
37
|
/**
|
|
20
38
|
* @brief emit union.
|
|
39
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
40
|
+
* stable across runtime and AOT emission.
|
|
41
|
+
* @param options Union option schemas.
|
|
42
|
+
* @param value Generated expression for the candidate value.
|
|
43
|
+
* @param context Shared code-generation context.
|
|
44
|
+
* @returns JavaScript expression for the union predicate.
|
|
21
45
|
*/
|
|
22
46
|
export declare function emitUnion(options: readonly Schema[], value: string, context: EmitContext): string;
|
|
23
47
|
//# sourceMappingURL=predicate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"predicate.d.ts","sourceRoot":"","sources":["../../src/compile/predicate.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"predicate.d.ts","sourceRoot":"","sources":["../../src/compile/predicate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,EAIH,KAAK,MAAM,EACd,MAAM,oBAAoB,CAAC;AAO5B,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,YAAY,CAAC;AAE9D;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,MAAM,CAkBzE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAU1D;AA4BD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC1B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,WAAW,GACrB,MAAM,CAuDR;AAyUD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CACrB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,WAAW,GACrB,MAAM,CAYR"}
|
|
@@ -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
7
|
import { NumberCheckTag, ObjectModeTag, PresenceTag, SchemaTag, StringCheckTag } from "../kind/index.js";
|
|
6
8
|
import { 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,6 +55,12 @@ 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) {
|
|
@@ -58,6 +80,12 @@ function emitBody(schema, value, context) {
|
|
|
58
80
|
}
|
|
59
81
|
/**
|
|
60
82
|
* @brief emit expression.
|
|
83
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
84
|
+
* stable across runtime and AOT emission.
|
|
85
|
+
* @param schema Schema represented by the expression.
|
|
86
|
+
* @param value Generated expression for the candidate value.
|
|
87
|
+
* @param context Shared code-generation context.
|
|
88
|
+
* @returns JavaScript expression that evaluates to a boolean.
|
|
61
89
|
*/
|
|
62
90
|
export function emitExpression(schema, value, context) {
|
|
63
91
|
switch (schema.tag) {
|
|
@@ -78,6 +106,10 @@ export function emitExpression(schema, value, context) {
|
|
|
78
106
|
case SchemaTag.Literal:
|
|
79
107
|
return `Object.is(${value},l[${String(pushLiteral(context, schema.value))}])`;
|
|
80
108
|
case SchemaTag.Array:
|
|
109
|
+
/*
|
|
110
|
+
* Composite schemas get their own functions. That keeps deeply nested
|
|
111
|
+
* predicates readable to V8 and avoids duplicating loops at each use site.
|
|
112
|
+
*/
|
|
81
113
|
return `${emitFunction(schema, context)}(${value})`;
|
|
82
114
|
case SchemaTag.Tuple:
|
|
83
115
|
return `${emitFunction(schema, context)}(${value})`;
|
|
@@ -100,14 +132,29 @@ export function emitExpression(schema, value, context) {
|
|
|
100
132
|
return emitExpression(schema.inner, value, context);
|
|
101
133
|
case SchemaTag.Lazy:
|
|
102
134
|
case SchemaTag.Refine:
|
|
135
|
+
/*
|
|
136
|
+
* User predicates and lazy resolution remain behind the runtime `d`
|
|
137
|
+
* helper because generated source cannot inline their behavior.
|
|
138
|
+
*/
|
|
103
139
|
return `d(${String(pushSchema(context, schema))},${value})`;
|
|
104
140
|
}
|
|
105
141
|
}
|
|
106
142
|
/**
|
|
107
143
|
* @brief emit array body.
|
|
144
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
145
|
+
* stable across runtime and AOT emission.
|
|
146
|
+
* @param item Schema applied to each logical slot.
|
|
147
|
+
* @param value Generated expression for the array value.
|
|
148
|
+
* @param context Shared code-generation context.
|
|
149
|
+
* @returns JavaScript source for an array predicate body.
|
|
108
150
|
*/
|
|
109
151
|
function emitArrayBody(item, value, context) {
|
|
110
152
|
const itemFunction = emitFunction(item, context);
|
|
153
|
+
/*
|
|
154
|
+
* Descriptor reads block accessor-backed slots without executing getters.
|
|
155
|
+
* Holes are forwarded as undefined so optional item schemas keep normal JS
|
|
156
|
+
* sparse-array semantics.
|
|
157
|
+
*/
|
|
111
158
|
return [
|
|
112
159
|
`if(!Array.isArray(${value}))return false;`,
|
|
113
160
|
`for(let i=0;i<${value}.length;i+=1){`,
|
|
@@ -120,9 +167,19 @@ function emitArrayBody(item, value, context) {
|
|
|
120
167
|
}
|
|
121
168
|
/**
|
|
122
169
|
* @brief emit record body.
|
|
170
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
171
|
+
* stable across runtime and AOT emission.
|
|
172
|
+
* @param item Schema applied to each own enumerable string key.
|
|
173
|
+
* @param value Generated expression for the record value.
|
|
174
|
+
* @param context Shared code-generation context.
|
|
175
|
+
* @returns JavaScript source for a record predicate body.
|
|
123
176
|
*/
|
|
124
177
|
function emitRecordBody(item, value, context) {
|
|
125
178
|
const itemFunction = emitFunction(item, context);
|
|
179
|
+
/*
|
|
180
|
+
* Object.keys intentionally ignores inherited and non-enumerable keys,
|
|
181
|
+
* matching TypeSea record semantics while keeping iteration predictable.
|
|
182
|
+
*/
|
|
126
183
|
return [
|
|
127
184
|
`if(!o(${value}))return false;`,
|
|
128
185
|
`const ks=Object.keys(${value});`,
|
|
@@ -137,6 +194,9 @@ function emitRecordBody(item, value, context) {
|
|
|
137
194
|
/**
|
|
138
195
|
* @brief emit tuple body.
|
|
139
196
|
* @details Emits tuple validation as straight-line descriptor reads and early returns.
|
|
197
|
+
* @param items Tuple item schemas.
|
|
198
|
+
* @param value Generated expression for the tuple value.
|
|
199
|
+
* @param context Shared code-generation context.
|
|
140
200
|
* @returns Generated tuple predicate body.
|
|
141
201
|
*/
|
|
142
202
|
function emitTupleBody(items, value, context) {
|
|
@@ -150,6 +210,10 @@ function emitTupleBody(items, value, context) {
|
|
|
150
210
|
}
|
|
151
211
|
const descriptor = `d${String(index)}`;
|
|
152
212
|
const itemValue = `v${String(index)}`;
|
|
213
|
+
/*
|
|
214
|
+
* Tuple arity is already checked above. Each index still needs descriptor
|
|
215
|
+
* validation because an accessor slot would execute user code if read.
|
|
216
|
+
*/
|
|
153
217
|
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
218
|
}
|
|
155
219
|
chunks.push("return true;");
|
|
@@ -158,6 +222,9 @@ function emitTupleBody(items, value, context) {
|
|
|
158
222
|
/**
|
|
159
223
|
* @brief emit object body.
|
|
160
224
|
* @details Emits object validation as Ajv-style straight-line code with local descriptor variables.
|
|
225
|
+
* @param schema Object schema to emit.
|
|
226
|
+
* @param value Generated expression for the object value.
|
|
227
|
+
* @param context Shared code-generation context.
|
|
161
228
|
* @returns Generated object predicate body.
|
|
162
229
|
*/
|
|
163
230
|
function emitObjectBody(schema, value, context) {
|
|
@@ -174,6 +241,10 @@ function emitObjectBody(schema, value, context) {
|
|
|
174
241
|
const itemValue = `v${String(index)}`;
|
|
175
242
|
chunks.push(`const ${descriptor}=gp(${value},${key});`);
|
|
176
243
|
if (entry.presence === PresenceTag.Optional) {
|
|
244
|
+
/*
|
|
245
|
+
* Optional own accessors are rejected. A missing descriptor is valid,
|
|
246
|
+
* but an own non-data property at the key is still hostile input.
|
|
247
|
+
*/
|
|
177
248
|
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
249
|
}
|
|
179
250
|
else {
|
|
@@ -186,6 +257,9 @@ function emitObjectBody(schema, value, context) {
|
|
|
186
257
|
/**
|
|
187
258
|
* @brief emit strict object key body.
|
|
188
259
|
* @details Emits a low-allocation known-key check specialized for one object shape.
|
|
260
|
+
* @param schema Object schema with mode and entries.
|
|
261
|
+
* @param value Generated expression for the object value.
|
|
262
|
+
* @param context Shared code-generation context.
|
|
189
263
|
* @returns Generated strict-key prelude, or an empty string for passthrough objects.
|
|
190
264
|
*/
|
|
191
265
|
function emitStrictObjectKeyBody(schema, value, context) {
|
|
@@ -203,6 +277,10 @@ function emitStrictObjectKeyBody(schema, value, context) {
|
|
|
203
277
|
if (comparisons.length === 0) {
|
|
204
278
|
return `if(Reflect.ownKeys(${value}).length!==0)return false;`;
|
|
205
279
|
}
|
|
280
|
+
/*
|
|
281
|
+
* Reflect.ownKeys is required for strict objects because symbol and
|
|
282
|
+
* non-enumerable extras are still extras.
|
|
283
|
+
*/
|
|
206
284
|
return [
|
|
207
285
|
`const xs=Reflect.ownKeys(${value});`,
|
|
208
286
|
"for(let i=0;i<xs.length;i+=1){",
|
|
@@ -214,6 +292,10 @@ function emitStrictObjectKeyBody(schema, value, context) {
|
|
|
214
292
|
/**
|
|
215
293
|
* @brief emit discriminated union body.
|
|
216
294
|
* @details Emits discriminant selection once and dispatches to branch validators.
|
|
295
|
+
* @param key Discriminant property name.
|
|
296
|
+
* @param cases Closed discriminated union cases.
|
|
297
|
+
* @param value Generated expression for the candidate object.
|
|
298
|
+
* @param context Shared code-generation context.
|
|
217
299
|
* @returns Generated discriminated-union predicate body.
|
|
218
300
|
*/
|
|
219
301
|
function emitDiscriminatedUnionBody(key, cases, value, context) {
|
|
@@ -237,6 +319,12 @@ function emitDiscriminatedUnionBody(key, cases, value, context) {
|
|
|
237
319
|
}
|
|
238
320
|
/**
|
|
239
321
|
* @brief emit string.
|
|
322
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
323
|
+
* stable across runtime and AOT emission.
|
|
324
|
+
* @param schema String schema with scalar checks.
|
|
325
|
+
* @param value Generated expression for the candidate value.
|
|
326
|
+
* @param context Shared code-generation context.
|
|
327
|
+
* @returns JavaScript expression for the string predicate.
|
|
240
328
|
*/
|
|
241
329
|
function emitString(schema, value, context) {
|
|
242
330
|
const parts = [`(typeof ${value}==="string")`];
|
|
@@ -265,13 +353,25 @@ function emitString(schema, value, context) {
|
|
|
265
353
|
}
|
|
266
354
|
/**
|
|
267
355
|
* @brief emit number.
|
|
356
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
357
|
+
* stable across runtime and AOT emission.
|
|
358
|
+
* @param schema Number schema with scalar checks.
|
|
359
|
+
* @param value Generated expression for the candidate value.
|
|
360
|
+
* @returns JavaScript expression for the number predicate.
|
|
268
361
|
*/
|
|
269
362
|
function emitNumber(schema, value) {
|
|
270
|
-
const
|
|
271
|
-
|
|
272
|
-
`Number.
|
|
273
|
-
|
|
363
|
+
const integer = numberChecksRequireInteger(schema.checks);
|
|
364
|
+
const parts = integer
|
|
365
|
+
? [`Number.isInteger(${value})`]
|
|
366
|
+
: [
|
|
367
|
+
`(typeof ${value}==="number")`,
|
|
368
|
+
`Number.isFinite(${value})`
|
|
369
|
+
];
|
|
274
370
|
const checks = schema.checks;
|
|
371
|
+
/*
|
|
372
|
+
* Number.isInteger already proves finite number, so integer schemas avoid
|
|
373
|
+
* emitting a separate typeof/finite pair.
|
|
374
|
+
*/
|
|
275
375
|
for (let index = 0; index < checks.length; index += 1) {
|
|
276
376
|
const check = checks[index];
|
|
277
377
|
if (check === undefined) {
|
|
@@ -279,7 +379,6 @@ function emitNumber(schema, value) {
|
|
|
279
379
|
}
|
|
280
380
|
switch (check.tag) {
|
|
281
381
|
case NumberCheckTag.Integer:
|
|
282
|
-
parts.push(`Number.isInteger(${value})`);
|
|
283
382
|
break;
|
|
284
383
|
case NumberCheckTag.Gte:
|
|
285
384
|
parts.push(`(${value}>=${String(check.value)})`);
|
|
@@ -291,8 +390,29 @@ function emitNumber(schema, value) {
|
|
|
291
390
|
}
|
|
292
391
|
return `(${parts.join("&&")})`;
|
|
293
392
|
}
|
|
393
|
+
/**
|
|
394
|
+
* @brief Test whether a number schema contains an integer constraint.
|
|
395
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
396
|
+
* stable across runtime and AOT emission.
|
|
397
|
+
* @param checks Number check list.
|
|
398
|
+
* @returns True when Number.isInteger can replace the broader number guard.
|
|
399
|
+
*/
|
|
400
|
+
function numberChecksRequireInteger(checks) {
|
|
401
|
+
for (let index = 0; index < checks.length; index += 1) {
|
|
402
|
+
if (checks[index]?.tag === NumberCheckTag.Integer) {
|
|
403
|
+
return true;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
return false;
|
|
407
|
+
}
|
|
294
408
|
/**
|
|
295
409
|
* @brief emit union.
|
|
410
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
411
|
+
* stable across runtime and AOT emission.
|
|
412
|
+
* @param options Union option schemas.
|
|
413
|
+
* @param value Generated expression for the candidate value.
|
|
414
|
+
* @param context Shared code-generation context.
|
|
415
|
+
* @returns JavaScript expression for the union predicate.
|
|
296
416
|
*/
|
|
297
417
|
export function emitUnion(options, value, context) {
|
|
298
418
|
const parts = [];
|
|
@@ -309,6 +429,12 @@ export function emitUnion(options, value, context) {
|
|
|
309
429
|
}
|
|
310
430
|
/**
|
|
311
431
|
* @brief emit regex.
|
|
432
|
+
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
433
|
+
* stable across runtime and AOT emission.
|
|
434
|
+
* @param value Generated expression for the candidate string.
|
|
435
|
+
* @param regex Pattern to test.
|
|
436
|
+
* @param context Shared code-generation context.
|
|
437
|
+
* @returns JavaScript expression that resets lastIndex and tests the regex.
|
|
312
438
|
*/
|
|
313
439
|
function emitRegex(value, regex, context) {
|
|
314
440
|
const index = pushRegex(context, regex);
|