typesea 0.2.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 +18 -0
- package/README.md +45 -11
- package/dist/aot/index.d.ts +1 -1
- package/dist/aot/index.d.ts.map +1 -1
- package/dist/aot/index.js +22 -3
- package/dist/builders/composite.d.ts +6 -3
- package/dist/builders/composite.d.ts.map +1 -1
- package/dist/builders/composite.js +22 -13
- package/dist/builders/index.d.ts +6 -5
- package/dist/builders/index.d.ts.map +1 -1
- package/dist/builders/index.js +5 -4
- package/dist/builders/modifier.d.ts +6 -0
- package/dist/builders/modifier.d.ts.map +1 -1
- package/dist/builders/modifier.js +14 -0
- package/dist/builders/object/guard.d.ts +54 -2
- package/dist/builders/object/guard.d.ts.map +1 -1
- package/dist/builders/object/guard.js +117 -7
- package/dist/builders/object/index.d.ts +2 -2
- package/dist/builders/object/index.d.ts.map +1 -1
- package/dist/builders/object/index.js +1 -1
- package/dist/builders/object/schema.d.ts +33 -2
- package/dist/builders/object/schema.d.ts.map +1 -1
- package/dist/builders/object/schema.js +198 -8
- package/dist/builders/object/types.d.ts +15 -0
- package/dist/builders/object/types.d.ts.map +1 -1
- 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 +20 -1
- package/dist/builders/scalar.d.ts.map +1 -1
- package/dist/builders/scalar.js +54 -1
- package/dist/builders/table.d.ts +31 -5
- package/dist/builders/table.d.ts.map +1 -1
- package/dist/builders/table.js +31 -5
- package/dist/builders/types.d.ts +6 -0
- package/dist/builders/types.d.ts.map +1 -1
- package/dist/compile/check-composite.d.ts +3 -1
- package/dist/compile/check-composite.d.ts.map +1 -1
- package/dist/compile/check-composite.js +143 -11
- package/dist/compile/check-scalar.d.ts +10 -0
- package/dist/compile/check-scalar.d.ts.map +1 -1
- package/dist/compile/check-scalar.js +138 -2
- package/dist/compile/check.d.ts.map +1 -1
- package/dist/compile/check.js +25 -3
- package/dist/compile/context.d.ts.map +1 -1
- package/dist/compile/context.js +2 -0
- 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.map +1 -1
- package/dist/compile/graph-predicate.js +389 -18
- package/dist/compile/guard.d.ts +2 -1
- package/dist/compile/guard.d.ts.map +1 -1
- package/dist/compile/guard.js +54 -8
- package/dist/compile/predicate.d.ts.map +1 -1
- package/dist/compile/predicate.js +156 -5
- package/dist/compile/runtime.d.ts +20 -1
- package/dist/compile/runtime.d.ts.map +1 -1
- package/dist/compile/runtime.js +31 -0
- package/dist/compile/source.d.ts.map +1 -1
- package/dist/compile/source.js +27 -3
- package/dist/compile/types.d.ts +2 -0
- package/dist/compile/types.d.ts.map +1 -1
- package/dist/decoder/index.d.ts +60 -0
- package/dist/decoder/index.d.ts.map +1 -1
- package/dist/decoder/index.js +164 -1
- package/dist/evaluate/check-composite.d.ts +52 -2
- package/dist/evaluate/check-composite.d.ts.map +1 -1
- package/dist/evaluate/check-composite.js +193 -6
- package/dist/evaluate/check-scalar.d.ts +9 -0
- package/dist/evaluate/check-scalar.d.ts.map +1 -1
- package/dist/evaluate/check-scalar.js +92 -3
- package/dist/evaluate/check.d.ts.map +1 -1
- package/dist/evaluate/check.js +19 -4
- package/dist/evaluate/shared.d.ts +19 -0
- package/dist/evaluate/shared.d.ts.map +1 -1
- package/dist/evaluate/shared.js +35 -0
- 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 +32 -2
- package/dist/guard/base.d.ts.map +1 -1
- package/dist/guard/base.js +74 -3
- 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/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 +60 -0
- package/dist/guard/number.d.ts.map +1 -1
- package/dist/guard/number.js +129 -0
- package/dist/guard/read.d.ts +53 -1
- package/dist/guard/read.d.ts.map +1 -1
- package/dist/guard/read.js +102 -0
- package/dist/guard/string.d.ts +82 -0
- package/dist/guard/string.d.ts.map +1 -1
- package/dist/guard/string.js +213 -0
- package/dist/guard/types.d.ts +18 -0
- package/dist/guard/types.d.ts.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/ir/builder.d.ts +3 -3
- package/dist/ir/builder.d.ts.map +1 -1
- package/dist/ir/builder.js +5 -2
- package/dist/ir/freeze.js +7 -0
- package/dist/ir/types.d.ts +4 -1
- package/dist/ir/types.d.ts.map +1 -1
- package/dist/ir/validate.d.ts.map +1 -1
- package/dist/ir/validate.js +35 -1
- package/dist/issue/index.d.ts +1 -1
- package/dist/issue/index.d.ts.map +1 -1
- package/dist/issue/index.js +4 -0
- package/dist/json-schema/emit-composite.d.ts +6 -2
- package/dist/json-schema/emit-composite.d.ts.map +1 -1
- package/dist/json-schema/emit-composite.js +66 -12
- package/dist/json-schema/emit-scalar.d.ts.map +1 -1
- package/dist/json-schema/emit-scalar.js +54 -1
- package/dist/json-schema/emit.d.ts.map +1 -1
- package/dist/json-schema/emit.js +11 -2
- package/dist/json-schema/types.d.ts +7 -1
- package/dist/json-schema/types.d.ts.map +1 -1
- package/dist/kind/index.d.ts +25 -0
- package/dist/kind/index.d.ts.map +1 -1
- package/dist/kind/index.js +26 -3
- package/dist/lower/index.d.ts.map +1 -1
- package/dist/lower/index.js +52 -3
- package/dist/message/index.d.ts +18 -0
- package/dist/message/index.d.ts.map +1 -1
- package/dist/message/index.js +67 -0
- package/dist/optimize/domain.js +6 -2
- package/dist/optimize/map-node.d.ts.map +1 -1
- package/dist/optimize/map-node.js +3 -0
- package/dist/plan/cache.js +13 -1
- package/dist/plan/predicate.d.ts.map +1 -1
- package/dist/plan/predicate.js +33 -3
- package/dist/plan/schema-predicate.d.ts.map +1 -1
- package/dist/plan/schema-predicate.js +267 -8
- package/dist/schema/freeze.js +22 -0
- package/dist/schema/index.d.ts +2 -2
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +1 -1
- package/dist/schema/types.d.ts +89 -4
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +8 -1
- package/dist/schema/undefined.d.ts.map +1 -1
- package/dist/schema/undefined.js +5 -0
- package/dist/schema/validate.d.ts.map +1 -1
- package/dist/schema/validate.js +111 -4
- package/docs/api.md +71 -8
- package/docs/engine-notes.md +4 -0
- package/docs/index.html +1340 -722
- 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 +3 -2
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
5
5
|
* stable across runtime and AOT emission.
|
|
6
6
|
*/
|
|
7
|
-
import { ObjectModeTag, PresenceTag, SchemaTag } from "../kind/index.js";
|
|
7
|
+
import { ArrayCheckTag, ObjectModeTag, PresenceTag, SchemaTag } from "../kind/index.js";
|
|
8
8
|
import { schemaCanAcceptUndefined } from "../schema/index.js";
|
|
9
9
|
import { pushLiteral, stringRef } from "./context.js";
|
|
10
10
|
import { emitIssue, emitIssueAtSegment, emitIssueAtTwoSegments, emitIssueExprAtSegment } from "./issue.js";
|
|
@@ -22,10 +22,11 @@ import { stringLiteral } from "./names.js";
|
|
|
22
22
|
* @param emitChild Fallback emitter for non-leaf child validators.
|
|
23
23
|
* @returns JavaScript source for array diagnostics.
|
|
24
24
|
*/
|
|
25
|
-
export function emitArrayCheck(
|
|
25
|
+
export function emitArrayCheck(schema, value, path, issues, context, emitChild) {
|
|
26
26
|
if (isUnsafeMode(context)) {
|
|
27
|
-
return emitUnsafeArrayCheck(
|
|
27
|
+
return emitUnsafeArrayCheck(schema, value, path, issues, context, emitChild);
|
|
28
28
|
}
|
|
29
|
+
const item = schema.item;
|
|
29
30
|
const itemValue = "av";
|
|
30
31
|
const itemLeaf = emitLeafCheckAtSegment(item, itemValue, path, "i", issues, context);
|
|
31
32
|
const missingLeaf = itemLeaf === undefined
|
|
@@ -53,6 +54,7 @@ export function emitArrayCheck(item, value, path, issues, context, emitChild) {
|
|
|
53
54
|
*/
|
|
54
55
|
return [
|
|
55
56
|
`if(!Array.isArray(${value})){${emitIssue(issues, path, "expected_array", "array", `a(${value})`)}return;}`,
|
|
57
|
+
emitArrayLengthIssues(schema, value, path, issues),
|
|
56
58
|
`const xs=Object.getOwnPropertyNames(${value});`,
|
|
57
59
|
"for(let xi=0;xi<xs.length;xi+=1){",
|
|
58
60
|
"const key=xs[xi];",
|
|
@@ -65,6 +67,7 @@ export function emitArrayCheck(item, value, path, issues, context, emitChild) {
|
|
|
65
67
|
}
|
|
66
68
|
return [
|
|
67
69
|
`if(!Array.isArray(${value})){${emitIssue(issues, path, "expected_array", "array", `a(${value})`)}return;}`,
|
|
70
|
+
emitArrayLengthIssues(schema, value, path, issues),
|
|
68
71
|
`for(let i=0;i<${value}.length;i+=1){`,
|
|
69
72
|
`const d=gp(${value},i);`,
|
|
70
73
|
`if(d===undefined){${missingCheck}}else if(!h.call(d,"value")){${emitIssueAtSegment(issues, path, "i", "expected_array", "data property", stringLiteral("accessor"))}}else{${presentCheck}}`,
|
|
@@ -118,7 +121,8 @@ export function emitTupleCheck(items, value, path, issues, context, emitChild) {
|
|
|
118
121
|
* @brief Execute emit unsafe array check.
|
|
119
122
|
* @details Code generation helpers keep emitted JavaScript shape stable across runtime and AOT paths.
|
|
120
123
|
*/
|
|
121
|
-
function emitUnsafeArrayCheck(
|
|
124
|
+
function emitUnsafeArrayCheck(schema, value, path, issues, context, emitChild) {
|
|
125
|
+
const item = schema.item;
|
|
122
126
|
const itemValue = "av";
|
|
123
127
|
const itemLeaf = emitLeafCheckAtSegment(item, itemValue, path, "i", issues, context);
|
|
124
128
|
let itemCheck;
|
|
@@ -132,11 +136,67 @@ function emitUnsafeArrayCheck(item, value, path, issues, context, emitChild) {
|
|
|
132
136
|
const parts = [
|
|
133
137
|
`if(!Array.isArray(${value})){${emitIssue(issues, path, "expected_array", "array", `a(${value})`)}return;}`
|
|
134
138
|
];
|
|
139
|
+
parts.push(emitArrayLengthIssues(schema, value, path, issues));
|
|
135
140
|
if (itemCheck !== "") {
|
|
136
141
|
parts.push(`for(let i=0;i<${value}.length;i+=1){`, `const ${itemValue}=${value}[i];`, itemCheck, "}");
|
|
137
142
|
}
|
|
138
143
|
return parts.join("");
|
|
139
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* @brief Emit root-level array length diagnostics.
|
|
147
|
+
* @param schema Array schema with normalized checks.
|
|
148
|
+
* @param value Generated expression for the candidate array.
|
|
149
|
+
* @param path Generated expression for the current diagnostic path.
|
|
150
|
+
* @param issues Generated expression for the issue buffer.
|
|
151
|
+
* @returns JavaScript source that appends zero or more length issues.
|
|
152
|
+
*/
|
|
153
|
+
function emitArrayLengthIssues(schema, value, path, issues) {
|
|
154
|
+
const chunks = [];
|
|
155
|
+
const checks = schema.checks;
|
|
156
|
+
for (let index = 0; index < checks.length; index += 1) {
|
|
157
|
+
const check = checks[index];
|
|
158
|
+
if (check === undefined) {
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
switch (check.tag) {
|
|
162
|
+
case ArrayCheckTag.Min:
|
|
163
|
+
chunks.push(`if(${value}.length<${String(check.value)}){${emitIssue(issues, path, "expected_min_length", `length >= ${String(check.value)}`, `"length "+String(${value}.length)`)}}`);
|
|
164
|
+
break;
|
|
165
|
+
case ArrayCheckTag.Max:
|
|
166
|
+
chunks.push(`if(${value}.length>${String(check.value)}){${emitIssue(issues, path, "expected_max_length", `length <= ${String(check.value)}`, `"length "+String(${value}.length)`)}}`);
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return chunks.join("");
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* @brief Emit one-segment array length diagnostics.
|
|
174
|
+
* @param schema Array schema with normalized checks.
|
|
175
|
+
* @param value Generated expression for the candidate array.
|
|
176
|
+
* @param path Generated expression for the current diagnostic path.
|
|
177
|
+
* @param segmentExpression Generated path segment for the array field.
|
|
178
|
+
* @param issues Generated expression for the issue buffer.
|
|
179
|
+
* @returns JavaScript source that appends zero or more length issues.
|
|
180
|
+
*/
|
|
181
|
+
function emitArrayLengthIssuesAtSegment(schema, value, path, segmentExpression, issues) {
|
|
182
|
+
const chunks = [];
|
|
183
|
+
const checks = schema.checks;
|
|
184
|
+
for (let index = 0; index < checks.length; index += 1) {
|
|
185
|
+
const check = checks[index];
|
|
186
|
+
if (check === undefined) {
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
switch (check.tag) {
|
|
190
|
+
case ArrayCheckTag.Min:
|
|
191
|
+
chunks.push(`if(${value}.length<${String(check.value)}){${emitIssueAtSegment(issues, path, segmentExpression, "expected_min_length", `length >= ${String(check.value)}`, `"length "+String(${value}.length)`)}}`);
|
|
192
|
+
break;
|
|
193
|
+
case ArrayCheckTag.Max:
|
|
194
|
+
chunks.push(`if(${value}.length>${String(check.value)}){${emitIssueAtSegment(issues, path, segmentExpression, "expected_max_length", `length <= ${String(check.value)}`, `"length "+String(${value}.length)`)}}`);
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return chunks.join("");
|
|
199
|
+
}
|
|
140
200
|
/**
|
|
141
201
|
* @brief Execute emit unsafe tuple check.
|
|
142
202
|
* @details Code generation helpers keep emitted JavaScript shape stable across runtime and AOT paths.
|
|
@@ -181,10 +241,11 @@ function emitUnsafeTupleCheck(items, value, path, issues, context, emitChild) {
|
|
|
181
241
|
* @param context Shared code-generation context.
|
|
182
242
|
* @returns JavaScript source, or undefined when the caller must fall back.
|
|
183
243
|
*/
|
|
184
|
-
function emitArrayCheckAtSegment(
|
|
244
|
+
function emitArrayCheckAtSegment(schema, value, path, segmentExpression, issues, context) {
|
|
185
245
|
if (isUnsafeMode(context)) {
|
|
186
|
-
return emitUnsafeArrayCheckAtSegment(
|
|
246
|
+
return emitUnsafeArrayCheckAtSegment(schema, value, path, segmentExpression, issues, context);
|
|
187
247
|
}
|
|
248
|
+
const item = schema.item;
|
|
188
249
|
const itemValue = "av";
|
|
189
250
|
const itemLeaf = emitLeafCheckAtTwoSegments(item, itemValue, path, segmentExpression, "i", issues, context);
|
|
190
251
|
const missingLeaf = itemLeaf === undefined
|
|
@@ -203,6 +264,7 @@ function emitArrayCheckAtSegment(item, value, path, segmentExpression, issues, c
|
|
|
203
264
|
*/
|
|
204
265
|
return [
|
|
205
266
|
`if(!Array.isArray(${value})){${emitIssueAtSegment(issues, path, segmentExpression, "expected_array", "array", `a(${value})`)}}else{`,
|
|
267
|
+
emitArrayLengthIssuesAtSegment(schema, value, path, segmentExpression, issues),
|
|
206
268
|
`const xs=Object.getOwnPropertyNames(${value});`,
|
|
207
269
|
"for(let xi=0;xi<xs.length;xi+=1){",
|
|
208
270
|
"const key=xs[xi];",
|
|
@@ -216,6 +278,7 @@ function emitArrayCheckAtSegment(item, value, path, segmentExpression, issues, c
|
|
|
216
278
|
}
|
|
217
279
|
return [
|
|
218
280
|
`if(!Array.isArray(${value})){${emitIssueAtSegment(issues, path, segmentExpression, "expected_array", "array", `a(${value})`)}}else{`,
|
|
281
|
+
emitArrayLengthIssuesAtSegment(schema, value, path, segmentExpression, issues),
|
|
219
282
|
`for(let i=0;i<${value}.length;i+=1){`,
|
|
220
283
|
`const vd=gp(${value},i);`,
|
|
221
284
|
`if(vd===undefined){${missingLeaf}}else if(!h.call(vd,"value")){${emitIssueAtTwoSegments(issues, path, segmentExpression, "i", "expected_array", "data property", stringLiteral("accessor"))}}else{${presentCheck}}`,
|
|
@@ -263,7 +326,8 @@ function emitTupleCheckAtSegment(items, value, path, segmentExpression, issues,
|
|
|
263
326
|
* @brief Execute emit unsafe array check at segment.
|
|
264
327
|
* @details Code generation helpers keep emitted JavaScript shape stable across runtime and AOT paths.
|
|
265
328
|
*/
|
|
266
|
-
function emitUnsafeArrayCheckAtSegment(
|
|
329
|
+
function emitUnsafeArrayCheckAtSegment(schema, value, path, segmentExpression, issues, context) {
|
|
330
|
+
const item = schema.item;
|
|
267
331
|
const itemLeaf = emitLeafCheckAtTwoSegments(item, "av", path, segmentExpression, "i", issues, context);
|
|
268
332
|
if (itemLeaf === undefined) {
|
|
269
333
|
return undefined;
|
|
@@ -271,9 +335,11 @@ function emitUnsafeArrayCheckAtSegment(item, value, path, segmentExpression, iss
|
|
|
271
335
|
const parts = [
|
|
272
336
|
`if(!Array.isArray(${value})){${emitIssueAtSegment(issues, path, segmentExpression, "expected_array", "array", `a(${value})`)}}`
|
|
273
337
|
];
|
|
338
|
+
parts.push("else{", emitArrayLengthIssuesAtSegment(schema, value, path, segmentExpression, issues));
|
|
274
339
|
if (itemLeaf !== "") {
|
|
275
|
-
parts.push(
|
|
340
|
+
parts.push(`for(let i=0;i<${value}.length;i+=1){`, `const av=${value}[i];`, itemLeaf, "}");
|
|
276
341
|
}
|
|
342
|
+
parts.push("}");
|
|
277
343
|
return parts.join("");
|
|
278
344
|
}
|
|
279
345
|
/**
|
|
@@ -441,11 +507,50 @@ export function emitObjectCheck(schema, value, path, issues, context, emitChild)
|
|
|
441
507
|
parts.push(`if(h.call(${value},${key})){const d=gp(${value},${key});if(d===undefined||!h.call(d,"value")){${emitIssueAtSegment(issues, path, key, "expected_object", "data property", stringLiteral("accessor"))}}else{${presentCheck}}}`);
|
|
442
508
|
}
|
|
443
509
|
}
|
|
444
|
-
if (schema.
|
|
510
|
+
if (schema.catchall !== undefined) {
|
|
511
|
+
parts.push(emitObjectCatchallCheck(schema, value, path, issues, context, emitChild));
|
|
512
|
+
}
|
|
513
|
+
else if (schema.mode === ObjectModeTag.Strict) {
|
|
445
514
|
parts.push(`const xs=Object.getOwnPropertyNames(${value});const xn=xs.length;for(let i=0;i<xn;i+=1){const key=xs[i];if(!(${safeKeyMembershipExpression("key", keyExpressions)})){${emitIssueAtSegment(issues, path, "key", "unrecognized_key", "known key", stringLiteral("extra key"))}}}const ys=Object.getOwnPropertySymbols(${value});const yn=ys.length;for(let i=0;i<yn;i+=1){const key=ys[i];if(key!==undefined){${emitIssueAtSegment(issues, path, "String(key)", "unrecognized_key", "known key", stringLiteral("extra key"))}}}`);
|
|
446
515
|
}
|
|
447
516
|
return parts.join("");
|
|
448
517
|
}
|
|
518
|
+
/**
|
|
519
|
+
* @brief Emit diagnostic collection for object catchall keys.
|
|
520
|
+
*/
|
|
521
|
+
function emitObjectCatchallCheck(schema, value, path, issues, context, emitChild) {
|
|
522
|
+
const catchall = schema.catchall;
|
|
523
|
+
if (catchall === undefined) {
|
|
524
|
+
return "";
|
|
525
|
+
}
|
|
526
|
+
const child = emitChild(catchall, context);
|
|
527
|
+
const membership = safeKeyMembershipExpression("key", objectKeyExpressions(schema, context));
|
|
528
|
+
return [
|
|
529
|
+
`const cx=Reflect.ownKeys(${value});`,
|
|
530
|
+
"const cn=cx.length;",
|
|
531
|
+
"for(let ci=0;ci<cn;ci+=1){",
|
|
532
|
+
"const key=cx[ci];",
|
|
533
|
+
`if(typeof key==="string"&&(${membership}))continue;`,
|
|
534
|
+
"const pk=typeof key===\"string\"?key:String(key);",
|
|
535
|
+
`const cd=gp(${value},key);`,
|
|
536
|
+
`if(cd===undefined||!h.call(cd,"value")){${emitIssueAtSegment(issues, path, "pk", "expected_object", "data property", stringLiteral("accessor"))}}else{`,
|
|
537
|
+
`${path}.push(pk);${child}(cd.value,${path},${issues});${path}.pop();`,
|
|
538
|
+
"}}"
|
|
539
|
+
].join("");
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* @brief Convert object schema keys into side-table source expressions.
|
|
543
|
+
*/
|
|
544
|
+
function objectKeyExpressions(schema, context) {
|
|
545
|
+
const keys = new Array(schema.keys.length);
|
|
546
|
+
for (let index = 0; index < schema.keys.length; index += 1) {
|
|
547
|
+
const key = schema.keys[index];
|
|
548
|
+
if (key !== undefined) {
|
|
549
|
+
keys[index] = stringRef(context, key);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
return keys;
|
|
553
|
+
}
|
|
449
554
|
/**
|
|
450
555
|
* @brief Execute emit unsafe object check.
|
|
451
556
|
* @details Code generation helpers keep emitted JavaScript shape stable across runtime and AOT paths.
|
|
@@ -475,7 +580,10 @@ function emitUnsafeObjectCheck(schema, value, path, issues, context, emitChild)
|
|
|
475
580
|
}
|
|
476
581
|
parts.push("}");
|
|
477
582
|
}
|
|
478
|
-
if (schema.
|
|
583
|
+
if (schema.catchall !== undefined) {
|
|
584
|
+
parts.push(emitUnsafeObjectCatchallCheck(schema, value, path, issues, context, emitChild));
|
|
585
|
+
}
|
|
586
|
+
else if (schema.mode === ObjectModeTag.Strict && !isUncheckedMode(context)) {
|
|
479
587
|
const keys = new Array(schema.entries.length);
|
|
480
588
|
for (let index = 0; index < schema.entries.length; index += 1) {
|
|
481
589
|
const entry = schema.entries[index];
|
|
@@ -487,6 +595,27 @@ function emitUnsafeObjectCheck(schema, value, path, issues, context, emitChild)
|
|
|
487
595
|
}
|
|
488
596
|
return parts.join("");
|
|
489
597
|
}
|
|
598
|
+
/**
|
|
599
|
+
* @brief Emit unsafe diagnostic collection for object catchall keys.
|
|
600
|
+
*/
|
|
601
|
+
function emitUnsafeObjectCatchallCheck(schema, value, path, issues, context, emitChild) {
|
|
602
|
+
const catchall = schema.catchall;
|
|
603
|
+
if (catchall === undefined) {
|
|
604
|
+
return "";
|
|
605
|
+
}
|
|
606
|
+
const child = emitChild(catchall, context);
|
|
607
|
+
const membership = unsafeKeyMembershipExpression("key", schema.keys);
|
|
608
|
+
return [
|
|
609
|
+
`const cx=Reflect.ownKeys(${value});`,
|
|
610
|
+
"const cn=cx.length;",
|
|
611
|
+
"for(let ci=0;ci<cn;ci+=1){",
|
|
612
|
+
"const key=cx[ci];",
|
|
613
|
+
`if(typeof key==="string"&&(${membership}))continue;`,
|
|
614
|
+
"const pk=typeof key===\"string\"?key:String(key);",
|
|
615
|
+
`${path}.push(pk);${child}(${value}[key],${path},${issues});${path}.pop();`,
|
|
616
|
+
"}"
|
|
617
|
+
].join("");
|
|
618
|
+
}
|
|
490
619
|
/**
|
|
491
620
|
* @brief Execute emit object field check.
|
|
492
621
|
* @details Code generation helpers keep emitted JavaScript shape stable across runtime and AOT paths.
|
|
@@ -510,8 +639,11 @@ function emitObjectFieldCheck(schema, value, path, segmentExpression, issues, co
|
|
|
510
639
|
function emitCompositeCheckAtSegment(schema, value, path, segmentExpression, issues, context) {
|
|
511
640
|
switch (schema.tag) {
|
|
512
641
|
case SchemaTag.Array:
|
|
513
|
-
return emitArrayCheckAtSegment(schema
|
|
642
|
+
return emitArrayCheckAtSegment(schema, value, path, segmentExpression, issues, context);
|
|
514
643
|
case SchemaTag.Tuple:
|
|
644
|
+
if (schema.rest !== undefined) {
|
|
645
|
+
return undefined;
|
|
646
|
+
}
|
|
515
647
|
return emitTupleCheckAtSegment(schema.items, value, path, segmentExpression, issues, context);
|
|
516
648
|
case SchemaTag.Record:
|
|
517
649
|
return emitRecordCheckAtSegment(schema.value, value, path, segmentExpression, issues, context);
|
|
@@ -21,6 +21,16 @@ import type { EmitContext } from "./types.js";
|
|
|
21
21
|
export declare function emitStringCheck(schema: Extract<Schema, {
|
|
22
22
|
readonly tag: typeof SchemaTag.String;
|
|
23
23
|
}>, value: string, path: string, issues: string, context: EmitContext): string;
|
|
24
|
+
/**
|
|
25
|
+
* @brief Emit Date diagnostics.
|
|
26
|
+
* @param value Generated expression for the candidate value.
|
|
27
|
+
* @param path Generated expression for the current diagnostic path.
|
|
28
|
+
* @param issues Generated expression for the issue buffer.
|
|
29
|
+
* @returns JavaScript source for root Date diagnostics.
|
|
30
|
+
*/
|
|
31
|
+
export declare function emitDateCheck(schema: Extract<Schema, {
|
|
32
|
+
readonly tag: typeof SchemaTag.Date;
|
|
33
|
+
}>, value: string, path: string, issues: string): string;
|
|
24
34
|
/**
|
|
25
35
|
* @brief emit leaf check at one appended path segment.
|
|
26
36
|
* @details This path is used by object-field diagnostics to avoid building a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-scalar.d.ts","sourceRoot":"","sources":["../../src/compile/check-scalar.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"check-scalar.d.ts","sourceRoot":"","sources":["../../src/compile/check-scalar.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAGH,SAAS,EAEZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EASH,KAAK,YAAY,EACjB,KAAK,MAAM,EACd,MAAM,oBAAoB,CAAC;AAe5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC3B,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,MAAM,CAAA;CAAE,CAAC,EAClE,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,GACrB,MAAM,CAqER;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CACzB,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,IAAI,CAAA;CAAE,CAAC,EAChE,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACf,MAAM,CAgDR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAClC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,iBAAiB,EAAE,MAAM,EACzB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,GACrB,MAAM,GAAG,SAAS,CA8FpB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,+BAA+B,CAC3C,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,iBAAiB,EAAE,MAAM,EACzB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,GACrB,MAAM,GAAG,SAAS,CA8EpB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CACtC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,sBAAsB,EAAE,MAAM,EAC9B,uBAAuB,EAAE,MAAM,EAC/B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,GACrB,MAAM,GAAG,SAAS,CAmGpB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mCAAmC,CAC/C,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,sBAAsB,EAAE,MAAM,EAC9B,uBAAuB,EAAE,MAAM,EAC/B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,GACrB,MAAM,GAAG,SAAS,CAsFpB;AA6WD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC3B,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,MAAM,CAAA;CAAE,CAAC,EAClE,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACf,MAAM,CA8ER;AA8OD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC5B,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,GACrB,MAAM,CAaR"}
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
5
5
|
* stable across runtime and AOT emission.
|
|
6
6
|
*/
|
|
7
|
-
import { NumberCheckTag, SchemaTag, StringCheckTag } from "../kind/index.js";
|
|
8
|
-
import { UUID_PATTERN } from "../schema/index.js";
|
|
7
|
+
import { DateCheckTag, NumberCheckTag, 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";
|
|
9
9
|
import { pushLiteral } from "./context.js";
|
|
10
10
|
import { emitIssue, emitIssueAtSegment, emitIssueAtTwoSegments, emitIssueExpr, emitIssueExprAtSegment, emitIssueExprAtTwoSegments, emitPatternIssueAtSegment, emitPatternIssueAtTwoSegments, emitPatternIssue } from "./issue.js";
|
|
11
11
|
import { stringLiteral } from "./names.js";
|
|
@@ -48,10 +48,63 @@ export function emitStringCheck(schema, value, path, issues, context) {
|
|
|
48
48
|
case StringCheckTag.Uuid:
|
|
49
49
|
parts.push(emitPatternIssue(value, path, issues, UUID_PATTERN, "uuid", context));
|
|
50
50
|
break;
|
|
51
|
+
case StringCheckTag.Email:
|
|
52
|
+
parts.push(emitPatternIssue(value, path, issues, EMAIL_PATTERN, "email", context));
|
|
53
|
+
break;
|
|
54
|
+
case StringCheckTag.Url:
|
|
55
|
+
parts.push(emitPatternIssue(value, path, issues, URL_PATTERN, "url", context));
|
|
56
|
+
break;
|
|
57
|
+
case StringCheckTag.IsoDate:
|
|
58
|
+
parts.push(emitPatternIssue(value, path, issues, ISO_DATE_PATTERN, "iso_date", context));
|
|
59
|
+
break;
|
|
60
|
+
case StringCheckTag.IsoDateTime:
|
|
61
|
+
parts.push(emitPatternIssue(value, path, issues, ISO_DATETIME_PATTERN, "iso_datetime", context));
|
|
62
|
+
break;
|
|
63
|
+
case StringCheckTag.Ulid:
|
|
64
|
+
parts.push(emitPatternIssue(value, path, issues, ULID_PATTERN, "ulid", context));
|
|
65
|
+
break;
|
|
66
|
+
case StringCheckTag.Ipv4:
|
|
67
|
+
parts.push(emitPatternIssue(value, path, issues, IPV4_PATTERN, "ipv4", context));
|
|
68
|
+
break;
|
|
69
|
+
case StringCheckTag.Ipv6:
|
|
70
|
+
parts.push(emitPatternIssue(value, path, issues, IPV6_PATTERN, "ipv6", context));
|
|
71
|
+
break;
|
|
51
72
|
}
|
|
52
73
|
}
|
|
53
74
|
return parts.join("");
|
|
54
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* @brief Emit Date diagnostics.
|
|
78
|
+
* @param value Generated expression for the candidate value.
|
|
79
|
+
* @param path Generated expression for the current diagnostic path.
|
|
80
|
+
* @param issues Generated expression for the issue buffer.
|
|
81
|
+
* @returns JavaScript source for root Date diagnostics.
|
|
82
|
+
*/
|
|
83
|
+
export function emitDateCheck(schema, value, path, issues) {
|
|
84
|
+
const invalid = `!dg(${value})`;
|
|
85
|
+
const checks = schema.checks;
|
|
86
|
+
if (checks.length === 0) {
|
|
87
|
+
return `if(${invalid}){${emitIssue(issues, path, "expected_date", "valid Date", `a(${value})`)}}`;
|
|
88
|
+
}
|
|
89
|
+
const parts = [`if(${invalid}){${emitIssue(issues, path, "expected_date", "valid Date", `a(${value})`)}}else{`];
|
|
90
|
+
for (let index = 0; index < checks.length; index += 1) {
|
|
91
|
+
const check = checks[index];
|
|
92
|
+
if (check === undefined) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const actual = `new Date(dt(${value})).toISOString()`;
|
|
96
|
+
switch (check.tag) {
|
|
97
|
+
case DateCheckTag.Min:
|
|
98
|
+
parts.push(`if(dt(${value})<${String(check.value)}){${emitIssue(issues, path, "expected_gte", `>= ${new Date(check.value).toISOString()}`, actual)}}`);
|
|
99
|
+
break;
|
|
100
|
+
case DateCheckTag.Max:
|
|
101
|
+
parts.push(`if(dt(${value})>${String(check.value)}){${emitIssue(issues, path, "expected_lte", `<= ${new Date(check.value).toISOString()}`, actual)}}`);
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
parts.push("}");
|
|
106
|
+
return parts.join("");
|
|
107
|
+
}
|
|
55
108
|
/**
|
|
56
109
|
* @brief emit leaf check at one appended path segment.
|
|
57
110
|
* @details This path is used by object-field diagnostics to avoid building a
|
|
@@ -74,6 +127,11 @@ export function emitLeafCheckAtSegment(schema, value, path, segmentExpression, i
|
|
|
74
127
|
return emitStringCheckAtSegment(schema, value, path, segmentExpression, issues, context);
|
|
75
128
|
case SchemaTag.Number:
|
|
76
129
|
return emitNumberCheckAtSegment(schema, value, path, segmentExpression, issues);
|
|
130
|
+
case SchemaTag.Date:
|
|
131
|
+
if (schema.checks.length !== 0) {
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
return `if(!dg(${value})){${emitIssueAtSegment(issues, path, segmentExpression, "expected_date", "valid Date", `a(${value})`)}}`;
|
|
77
135
|
case SchemaTag.BigInt:
|
|
78
136
|
return `if(typeof ${value}!=="bigint"){${emitIssueAtSegment(issues, path, segmentExpression, "expected_bigint", "bigint", `a(${value})`)}}`;
|
|
79
137
|
case SchemaTag.Symbol:
|
|
@@ -114,6 +172,8 @@ export function emitUndefinedLeafCheckAtSegment(schema, path, segmentExpression,
|
|
|
114
172
|
return emitIssueAtSegment(issues, path, segmentExpression, "expected_string", "string", stringLiteral("undefined"));
|
|
115
173
|
case SchemaTag.Number:
|
|
116
174
|
return emitIssueAtSegment(issues, path, segmentExpression, "expected_number", "number", stringLiteral("undefined"));
|
|
175
|
+
case SchemaTag.Date:
|
|
176
|
+
return emitIssueAtSegment(issues, path, segmentExpression, "expected_date", "valid Date", stringLiteral("undefined"));
|
|
117
177
|
case SchemaTag.BigInt:
|
|
118
178
|
return emitIssueAtSegment(issues, path, segmentExpression, "expected_bigint", "bigint", stringLiteral("undefined"));
|
|
119
179
|
case SchemaTag.Symbol:
|
|
@@ -149,6 +209,11 @@ export function emitLeafCheckAtTwoSegments(schema, value, path, firstSegmentExpr
|
|
|
149
209
|
return emitStringCheckAtTwoSegments(schema, value, path, firstSegmentExpression, secondSegmentExpression, issues, context);
|
|
150
210
|
case SchemaTag.Number:
|
|
151
211
|
return emitNumberCheckAtTwoSegments(schema, value, path, firstSegmentExpression, secondSegmentExpression, issues);
|
|
212
|
+
case SchemaTag.Date:
|
|
213
|
+
if (schema.checks.length !== 0) {
|
|
214
|
+
return undefined;
|
|
215
|
+
}
|
|
216
|
+
return `if(!dg(${value})){${emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_date", "valid Date", `a(${value})`)}}`;
|
|
152
217
|
case SchemaTag.BigInt:
|
|
153
218
|
return `if(typeof ${value}!=="bigint"){${emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_bigint", "bigint", `a(${value})`)}}`;
|
|
154
219
|
case SchemaTag.Symbol:
|
|
@@ -185,6 +250,8 @@ export function emitUndefinedLeafCheckAtTwoSegments(schema, path, firstSegmentEx
|
|
|
185
250
|
return emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_string", "string", stringLiteral("undefined"));
|
|
186
251
|
case SchemaTag.Number:
|
|
187
252
|
return emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_number", "number", stringLiteral("undefined"));
|
|
253
|
+
case SchemaTag.Date:
|
|
254
|
+
return emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_date", "valid Date", stringLiteral("undefined"));
|
|
188
255
|
case SchemaTag.BigInt:
|
|
189
256
|
return emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_bigint", "bigint", stringLiteral("undefined"));
|
|
190
257
|
case SchemaTag.Symbol:
|
|
@@ -239,6 +306,27 @@ function emitStringCheckAtSegment(schema, value, path, segmentExpression, issues
|
|
|
239
306
|
case StringCheckTag.Uuid:
|
|
240
307
|
parts.push(emitPatternIssueAtSegment(value, path, segmentExpression, issues, UUID_PATTERN, "uuid", context));
|
|
241
308
|
break;
|
|
309
|
+
case StringCheckTag.Email:
|
|
310
|
+
parts.push(emitPatternIssueAtSegment(value, path, segmentExpression, issues, EMAIL_PATTERN, "email", context));
|
|
311
|
+
break;
|
|
312
|
+
case StringCheckTag.Url:
|
|
313
|
+
parts.push(emitPatternIssueAtSegment(value, path, segmentExpression, issues, URL_PATTERN, "url", context));
|
|
314
|
+
break;
|
|
315
|
+
case StringCheckTag.IsoDate:
|
|
316
|
+
parts.push(emitPatternIssueAtSegment(value, path, segmentExpression, issues, ISO_DATE_PATTERN, "iso_date", context));
|
|
317
|
+
break;
|
|
318
|
+
case StringCheckTag.IsoDateTime:
|
|
319
|
+
parts.push(emitPatternIssueAtSegment(value, path, segmentExpression, issues, ISO_DATETIME_PATTERN, "iso_datetime", context));
|
|
320
|
+
break;
|
|
321
|
+
case StringCheckTag.Ulid:
|
|
322
|
+
parts.push(emitPatternIssueAtSegment(value, path, segmentExpression, issues, ULID_PATTERN, "ulid", context));
|
|
323
|
+
break;
|
|
324
|
+
case StringCheckTag.Ipv4:
|
|
325
|
+
parts.push(emitPatternIssueAtSegment(value, path, segmentExpression, issues, IPV4_PATTERN, "ipv4", context));
|
|
326
|
+
break;
|
|
327
|
+
case StringCheckTag.Ipv6:
|
|
328
|
+
parts.push(emitPatternIssueAtSegment(value, path, segmentExpression, issues, IPV6_PATTERN, "ipv6", context));
|
|
329
|
+
break;
|
|
242
330
|
}
|
|
243
331
|
}
|
|
244
332
|
parts.push("}");
|
|
@@ -283,6 +371,27 @@ function emitStringCheckAtTwoSegments(schema, value, path, firstSegmentExpressio
|
|
|
283
371
|
case StringCheckTag.Uuid:
|
|
284
372
|
parts.push(emitPatternIssueAtTwoSegments(value, path, firstSegmentExpression, secondSegmentExpression, issues, UUID_PATTERN, "uuid", context));
|
|
285
373
|
break;
|
|
374
|
+
case StringCheckTag.Email:
|
|
375
|
+
parts.push(emitPatternIssueAtTwoSegments(value, path, firstSegmentExpression, secondSegmentExpression, issues, EMAIL_PATTERN, "email", context));
|
|
376
|
+
break;
|
|
377
|
+
case StringCheckTag.Url:
|
|
378
|
+
parts.push(emitPatternIssueAtTwoSegments(value, path, firstSegmentExpression, secondSegmentExpression, issues, URL_PATTERN, "url", context));
|
|
379
|
+
break;
|
|
380
|
+
case StringCheckTag.IsoDate:
|
|
381
|
+
parts.push(emitPatternIssueAtTwoSegments(value, path, firstSegmentExpression, secondSegmentExpression, issues, ISO_DATE_PATTERN, "iso_date", context));
|
|
382
|
+
break;
|
|
383
|
+
case StringCheckTag.IsoDateTime:
|
|
384
|
+
parts.push(emitPatternIssueAtTwoSegments(value, path, firstSegmentExpression, secondSegmentExpression, issues, ISO_DATETIME_PATTERN, "iso_datetime", context));
|
|
385
|
+
break;
|
|
386
|
+
case StringCheckTag.Ulid:
|
|
387
|
+
parts.push(emitPatternIssueAtTwoSegments(value, path, firstSegmentExpression, secondSegmentExpression, issues, ULID_PATTERN, "ulid", context));
|
|
388
|
+
break;
|
|
389
|
+
case StringCheckTag.Ipv4:
|
|
390
|
+
parts.push(emitPatternIssueAtTwoSegments(value, path, firstSegmentExpression, secondSegmentExpression, issues, IPV4_PATTERN, "ipv4", context));
|
|
391
|
+
break;
|
|
392
|
+
case StringCheckTag.Ipv6:
|
|
393
|
+
parts.push(emitPatternIssueAtTwoSegments(value, path, firstSegmentExpression, secondSegmentExpression, issues, IPV6_PATTERN, "ipv6", context));
|
|
394
|
+
break;
|
|
286
395
|
}
|
|
287
396
|
}
|
|
288
397
|
parts.push("}");
|
|
@@ -322,6 +431,15 @@ export function emitNumberCheck(schema, value, path, issues) {
|
|
|
322
431
|
case NumberCheckTag.Lte:
|
|
323
432
|
parts.push(`if(${value}>${String(check.value)}){${emitIssue(issues, path, "expected_lte", `<= ${String(check.value)}`, `String(${value})`)}}`);
|
|
324
433
|
break;
|
|
434
|
+
case NumberCheckTag.Gt:
|
|
435
|
+
parts.push(`if(${value}<=${String(check.value)}){${emitIssue(issues, path, "expected_gt", `> ${String(check.value)}`, `String(${value})`)}}`);
|
|
436
|
+
break;
|
|
437
|
+
case NumberCheckTag.Lt:
|
|
438
|
+
parts.push(`if(${value}>=${String(check.value)}){${emitIssue(issues, path, "expected_lt", `< ${String(check.value)}`, `String(${value})`)}}`);
|
|
439
|
+
break;
|
|
440
|
+
case NumberCheckTag.MultipleOf:
|
|
441
|
+
parts.push(`if(${value}%${String(check.value)}!==0){${emitIssue(issues, path, "expected_multiple_of", `multiple of ${String(check.value)}`, `String(${value})`)}}`);
|
|
442
|
+
break;
|
|
325
443
|
}
|
|
326
444
|
}
|
|
327
445
|
return parts.join("");
|
|
@@ -364,6 +482,15 @@ function emitNumberCheckAtSegment(schema, value, path, segmentExpression, issues
|
|
|
364
482
|
case NumberCheckTag.Lte:
|
|
365
483
|
parts.push(`if(${value}>${String(check.value)}){${emitIssueAtSegment(issues, path, segmentExpression, "expected_lte", `<= ${String(check.value)}`, `String(${value})`)}}`);
|
|
366
484
|
break;
|
|
485
|
+
case NumberCheckTag.Gt:
|
|
486
|
+
parts.push(`if(${value}<=${String(check.value)}){${emitIssueAtSegment(issues, path, segmentExpression, "expected_gt", `> ${String(check.value)}`, `String(${value})`)}}`);
|
|
487
|
+
break;
|
|
488
|
+
case NumberCheckTag.Lt:
|
|
489
|
+
parts.push(`if(${value}>=${String(check.value)}){${emitIssueAtSegment(issues, path, segmentExpression, "expected_lt", `< ${String(check.value)}`, `String(${value})`)}}`);
|
|
490
|
+
break;
|
|
491
|
+
case NumberCheckTag.MultipleOf:
|
|
492
|
+
parts.push(`if(${value}%${String(check.value)}!==0){${emitIssueAtSegment(issues, path, segmentExpression, "expected_multiple_of", `multiple of ${String(check.value)}`, `String(${value})`)}}`);
|
|
493
|
+
break;
|
|
367
494
|
}
|
|
368
495
|
}
|
|
369
496
|
parts.push("}");
|
|
@@ -404,6 +531,15 @@ function emitNumberCheckAtTwoSegments(schema, value, path, firstSegmentExpressio
|
|
|
404
531
|
case NumberCheckTag.Lte:
|
|
405
532
|
parts.push(`if(${value}>${String(check.value)}){${emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_lte", `<= ${String(check.value)}`, `String(${value})`)}}`);
|
|
406
533
|
break;
|
|
534
|
+
case NumberCheckTag.Gt:
|
|
535
|
+
parts.push(`if(${value}<=${String(check.value)}){${emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_gt", `> ${String(check.value)}`, `String(${value})`)}}`);
|
|
536
|
+
break;
|
|
537
|
+
case NumberCheckTag.Lt:
|
|
538
|
+
parts.push(`if(${value}>=${String(check.value)}){${emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_lt", `< ${String(check.value)}`, `String(${value})`)}}`);
|
|
539
|
+
break;
|
|
540
|
+
case NumberCheckTag.MultipleOf:
|
|
541
|
+
parts.push(`if(${value}%${String(check.value)}!==0){${emitIssueAtTwoSegments(issues, path, firstSegmentExpression, secondSegmentExpression, "expected_multiple_of", `multiple of ${String(check.value)}`, `String(${value})`)}}`);
|
|
542
|
+
break;
|
|
407
543
|
}
|
|
408
544
|
}
|
|
409
545
|
parts.push("}");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/compile/check.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/compile/check.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAiBjD,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,YAAY,CAAC;AAE9D;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,MAAM,CAkB9E;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAU/D"}
|
package/dist/compile/check.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { SchemaTag } from "../kind/index.js";
|
|
8
8
|
import { emitArrayCheck, emitDiscriminatedUnionCheck, emitObjectCheck, emitRecordCheck, emitTupleCheck } from "./check-composite.js";
|
|
9
|
-
import { emitLiteralCheck, emitNumberCheck, emitStringCheck } from "./check-scalar.js";
|
|
9
|
+
import { emitDateCheck, emitLiteralCheck, emitNumberCheck, emitStringCheck } from "./check-scalar.js";
|
|
10
10
|
import { pushSchema } from "./context.js";
|
|
11
11
|
import { emitIssue } from "./issue.js";
|
|
12
12
|
import { emitUnion } from "./predicate.js";
|
|
@@ -77,6 +77,8 @@ function emitCheckBody(schema, value, path, issues, context) {
|
|
|
77
77
|
return emitStringCheck(schema, value, path, issues, context);
|
|
78
78
|
case SchemaTag.Number:
|
|
79
79
|
return emitNumberCheck(schema, value, path, issues);
|
|
80
|
+
case SchemaTag.Date:
|
|
81
|
+
return emitDateCheck(schema, value, path, issues);
|
|
80
82
|
case SchemaTag.BigInt:
|
|
81
83
|
return `if(typeof ${value}!=="bigint"){${emitIssue(issues, path, "expected_bigint", "bigint", `a(${value})`)}}`;
|
|
82
84
|
case SchemaTag.Symbol:
|
|
@@ -86,11 +88,19 @@ function emitCheckBody(schema, value, path, issues, context) {
|
|
|
86
88
|
case SchemaTag.Literal:
|
|
87
89
|
return emitLiteralCheck(schema.value, value, path, issues, context);
|
|
88
90
|
case SchemaTag.Array:
|
|
89
|
-
return emitArrayCheck(schema
|
|
91
|
+
return emitArrayCheck(schema, value, path, issues, context, emitCheckFunction);
|
|
90
92
|
case SchemaTag.Tuple:
|
|
93
|
+
if (schema.rest !== undefined) {
|
|
94
|
+
return emitDynamicCheck(schema, value, path, issues, context);
|
|
95
|
+
}
|
|
91
96
|
return emitTupleCheck(schema.items, value, path, issues, context, emitCheckFunction);
|
|
92
97
|
case SchemaTag.Record:
|
|
93
98
|
return emitRecordCheck(schema.value, value, path, issues, context, emitCheckFunction);
|
|
99
|
+
case SchemaTag.Map:
|
|
100
|
+
case SchemaTag.Set:
|
|
101
|
+
case SchemaTag.InstanceOf:
|
|
102
|
+
case SchemaTag.Property:
|
|
103
|
+
return emitDynamicCheck(schema, value, path, issues, context);
|
|
94
104
|
case SchemaTag.Object:
|
|
95
105
|
return emitObjectCheck(schema, value, path, issues, context, emitCheckFunction);
|
|
96
106
|
case SchemaTag.Union:
|
|
@@ -116,9 +126,21 @@ function emitCheckBody(schema, value, path, issues, context) {
|
|
|
116
126
|
* inlined into generated source. The `m` helper calls the interpreter
|
|
117
127
|
* diagnostic path through the dynamic schema side table.
|
|
118
128
|
*/
|
|
119
|
-
return
|
|
129
|
+
return emitDynamicCheck(schema, value, path, issues, context);
|
|
120
130
|
}
|
|
121
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* @brief Emit a diagnostic fallback call for runtime-only schema nodes.
|
|
134
|
+
* @param schema Schema captured in the dynamic side table.
|
|
135
|
+
* @param value Generated candidate value expression.
|
|
136
|
+
* @param path Generated path expression.
|
|
137
|
+
* @param issues Generated issue buffer expression.
|
|
138
|
+
* @param context Shared emission context.
|
|
139
|
+
* @returns JavaScript source delegating diagnostics to the interpreter.
|
|
140
|
+
*/
|
|
141
|
+
function emitDynamicCheck(schema, value, path, issues, context) {
|
|
142
|
+
return `m(${String(pushSchema(context, schema))},${value},${path},${issues});`;
|
|
143
|
+
}
|
|
122
144
|
/**
|
|
123
145
|
* @brief emit check call.
|
|
124
146
|
* @details Generated-source helpers keep the side-table ABI and JavaScript source shape
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/compile/context.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE3D;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,WAAW,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/compile/context.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE3D;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,WAAW,CAgBhE;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,GAAG,MAAM,CAI7E;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAIrE;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAIjF;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAErE;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAatE;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAItE"}
|
package/dist/compile/context.js
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file first.ts
|
|
3
|
+
* @brief First-fault diagnostic validator function table emitter.
|
|
4
|
+
* @details Generated first-fault helpers return one frozen issue immediately,
|
|
5
|
+
* keeping hot rejection diagnostics out of the full issue collector.
|
|
6
|
+
*/
|
|
7
|
+
import { type Schema } from "../schema/index.js";
|
|
8
|
+
import type { EmitContext } from "./types.js";
|
|
9
|
+
/**
|
|
10
|
+
* @brief Emit or reuse a first-fault diagnostic function.
|
|
11
|
+
* @details Each schema identity maps to one generated first-fault function so
|
|
12
|
+
* recursive and shared schemas keep stable function identities in source.
|
|
13
|
+
* @param schema Schema whose first diagnostic should be emitted.
|
|
14
|
+
* @param context Shared code-generation context.
|
|
15
|
+
* @returns Generated first-fault function name.
|
|
16
|
+
*/
|
|
17
|
+
export declare function emitFirstFunction(schema: Schema, context: EmitContext): string;
|
|
18
|
+
/**
|
|
19
|
+
* @brief Emit all first-fault diagnostic functions.
|
|
20
|
+
* @details Generated functions return undefined on success or one frozen issue
|
|
21
|
+
* on failure. They never allocate an issue array.
|
|
22
|
+
* @param context Shared code-generation context with accumulated sources.
|
|
23
|
+
* @returns Concatenated JavaScript function declarations.
|
|
24
|
+
*/
|
|
25
|
+
export declare function emitFirstFunctions(context: EmitContext): string;
|
|
26
|
+
//# sourceMappingURL=first.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"first.d.ts","sourceRoot":"","sources":["../../src/compile/first.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,OAAO,EAYH,KAAK,MAAM,EACd,MAAM,oBAAoB,CAAC;AAS5B,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,YAAY,CAAC;AAE9D;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,MAAM,CAc9E;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAS/D"}
|