typesea 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +85 -6
- package/README.md +143 -28
- package/dist/adapters/index.d.ts +50 -8
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +169 -48
- package/dist/aot/index.d.ts +19 -3
- package/dist/aot/index.d.ts.map +1 -1
- package/dist/aot/index.js +115 -17
- package/dist/async/index.d.ts +28 -56
- package/dist/async/index.d.ts.map +1 -1
- package/dist/async/index.js +94 -37
- package/dist/builders/composite.d.ts +43 -9
- package/dist/builders/composite.d.ts.map +1 -1
- package/dist/builders/composite.js +100 -17
- package/dist/builders/index.d.ts +8 -5
- package/dist/builders/index.d.ts.map +1 -1
- package/dist/builders/index.js +7 -4
- package/dist/builders/modifier.d.ts +36 -5
- package/dist/builders/modifier.d.ts.map +1 -1
- package/dist/builders/modifier.js +52 -5
- package/dist/builders/object/guard.d.ts +72 -24
- package/dist/builders/object/guard.d.ts.map +1 -1
- package/dist/builders/object/guard.js +139 -29
- package/dist/builders/object/index.d.ts +4 -2
- package/dist/builders/object/index.d.ts.map +1 -1
- package/dist/builders/object/index.js +3 -1
- package/dist/builders/object/schema.d.ts +88 -11
- package/dist/builders/object/schema.d.ts.map +1 -1
- package/dist/builders/object/schema.js +290 -23
- package/dist/builders/object/types.d.ts +20 -31
- package/dist/builders/object/types.d.ts.map +1 -1
- package/dist/builders/object/types.js +2 -0
- package/dist/builders/runtime.d.ts +40 -0
- package/dist/builders/runtime.d.ts.map +1 -0
- package/dist/builders/runtime.js +150 -0
- package/dist/builders/scalar.d.ts +49 -9
- package/dist/builders/scalar.d.ts.map +1 -1
- package/dist/builders/scalar.js +87 -9
- package/dist/builders/table.d.ts +35 -5
- package/dist/builders/table.d.ts.map +1 -1
- package/dist/builders/table.js +35 -5
- package/dist/builders/types.d.ts +20 -4
- package/dist/builders/types.d.ts.map +1 -1
- package/dist/builders/types.js +2 -0
- package/dist/compile/check-composite.d.ts +25 -2
- package/dist/compile/check-composite.d.ts.map +1 -1
- package/dist/compile/check-composite.js +699 -27
- package/dist/compile/check-scalar.d.ts +88 -0
- package/dist/compile/check-scalar.d.ts.map +1 -1
- package/dist/compile/check-scalar.js +570 -3
- package/dist/compile/check.d.ts +12 -0
- package/dist/compile/check.d.ts.map +1 -1
- package/dist/compile/check.js +62 -3
- package/dist/compile/context.d.ts +47 -9
- package/dist/compile/context.d.ts.map +1 -1
- package/dist/compile/context.js +53 -8
- package/dist/compile/first.d.ts +26 -0
- package/dist/compile/first.d.ts.map +1 -0
- package/dist/compile/first.js +850 -0
- package/dist/compile/graph-predicate.d.ts +4 -2
- package/dist/compile/graph-predicate.d.ts.map +1 -1
- package/dist/compile/graph-predicate.js +2272 -165
- package/dist/compile/guard.d.ts +16 -24
- package/dist/compile/guard.d.ts.map +1 -1
- package/dist/compile/guard.js +202 -72
- package/dist/compile/index.d.ts +3 -1
- package/dist/compile/index.d.ts.map +1 -1
- package/dist/compile/index.js +2 -0
- package/dist/compile/issue.d.ts +110 -0
- package/dist/compile/issue.d.ts.map +1 -1
- package/dist/compile/issue.js +184 -1
- package/dist/compile/names.d.ts +12 -2
- package/dist/compile/names.d.ts.map +1 -1
- package/dist/compile/names.js +19 -3
- package/dist/compile/predicate.d.ts +24 -0
- package/dist/compile/predicate.d.ts.map +1 -1
- package/dist/compile/predicate.js +287 -10
- package/dist/compile/runtime.d.ts +100 -13
- package/dist/compile/runtime.d.ts.map +1 -1
- package/dist/compile/runtime.js +56 -6
- package/dist/compile/source.d.ts +10 -2
- package/dist/compile/source.d.ts.map +1 -1
- package/dist/compile/source.js +385 -26
- package/dist/compile/types.d.ts +22 -0
- package/dist/compile/types.d.ts.map +1 -1
- package/dist/compile/types.js +2 -0
- package/dist/decoder/index.d.ts +92 -46
- package/dist/decoder/index.d.ts.map +1 -1
- package/dist/decoder/index.js +266 -39
- package/dist/evaluate/check-composite.d.ts +111 -2
- package/dist/evaluate/check-composite.d.ts.map +1 -1
- package/dist/evaluate/check-composite.js +343 -8
- package/dist/evaluate/check-scalar.d.ts +25 -0
- package/dist/evaluate/check-scalar.d.ts.map +1 -1
- package/dist/evaluate/check-scalar.js +124 -3
- package/dist/evaluate/check.d.ts +7 -0
- package/dist/evaluate/check.d.ts.map +1 -1
- package/dist/evaluate/check.js +62 -4
- package/dist/evaluate/index.d.ts +2 -0
- package/dist/evaluate/index.d.ts.map +1 -1
- package/dist/evaluate/index.js +2 -0
- package/dist/evaluate/issue.d.ts +11 -1
- package/dist/evaluate/issue.d.ts.map +1 -1
- package/dist/evaluate/issue.js +15 -1
- package/dist/evaluate/predicate.d.ts +16 -5
- package/dist/evaluate/predicate.d.ts.map +1 -1
- package/dist/evaluate/predicate.js +20 -5
- package/dist/evaluate/shared.d.ts +78 -13
- package/dist/evaluate/shared.d.ts.map +1 -1
- package/dist/evaluate/shared.js +101 -8
- package/dist/evaluate/state.d.ts +35 -13
- package/dist/evaluate/state.d.ts.map +1 -1
- package/dist/evaluate/state.js +35 -2
- package/dist/guard/array.d.ts +48 -0
- package/dist/guard/array.d.ts.map +1 -0
- package/dist/guard/array.js +84 -0
- package/dist/guard/base.d.ts +111 -31
- package/dist/guard/base.d.ts.map +1 -1
- package/dist/guard/base.js +165 -32
- package/dist/guard/date.d.ts +34 -0
- package/dist/guard/date.d.ts.map +1 -0
- package/dist/guard/date.js +60 -0
- package/dist/guard/error.d.ts +10 -5
- package/dist/guard/error.d.ts.map +1 -1
- package/dist/guard/error.js +10 -5
- package/dist/guard/index.d.ts +4 -0
- package/dist/guard/index.d.ts.map +1 -1
- package/dist/guard/index.js +4 -0
- package/dist/guard/number.d.ts +86 -11
- package/dist/guard/number.d.ts.map +1 -1
- package/dist/guard/number.js +159 -11
- package/dist/guard/props.d.ts +27 -3
- package/dist/guard/props.d.ts.map +1 -1
- package/dist/guard/props.js +27 -3
- package/dist/guard/read.d.ts +115 -10
- package/dist/guard/read.d.ts.map +1 -1
- package/dist/guard/read.js +185 -10
- package/dist/guard/registry.d.ts +12 -2
- package/dist/guard/registry.d.ts.map +1 -1
- package/dist/guard/registry.js +15 -3
- package/dist/guard/string.d.ts +115 -13
- package/dist/guard/string.d.ts.map +1 -1
- package/dist/guard/string.js +250 -13
- package/dist/guard/types.d.ts +110 -40
- package/dist/guard/types.d.ts.map +1 -1
- package/dist/guard/types.js +2 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/internal/index.d.ts +42 -6
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +51 -8
- package/dist/ir/builder.d.ts +17 -127
- package/dist/ir/builder.d.ts.map +1 -1
- package/dist/ir/builder.js +80 -137
- package/dist/ir/freeze.d.ts +4 -0
- package/dist/ir/freeze.d.ts.map +1 -1
- package/dist/ir/freeze.js +66 -0
- package/dist/ir/index.d.ts +3 -1
- package/dist/ir/index.d.ts.map +1 -1
- package/dist/ir/index.js +2 -0
- package/dist/ir/regexp.d.ts +2 -0
- package/dist/ir/regexp.d.ts.map +1 -1
- package/dist/ir/regexp.js +2 -0
- package/dist/ir/types.d.ts +94 -56
- package/dist/ir/types.d.ts.map +1 -1
- package/dist/ir/types.js +2 -0
- package/dist/ir/validate.d.ts +8 -1
- package/dist/ir/validate.d.ts.map +1 -1
- package/dist/ir/validate.js +511 -61
- package/dist/issue/index.d.ts +42 -10
- package/dist/issue/index.d.ts.map +1 -1
- package/dist/issue/index.js +65 -11
- package/dist/json-schema/emit-combinator.d.ts +44 -4
- package/dist/json-schema/emit-combinator.d.ts.map +1 -1
- package/dist/json-schema/emit-combinator.js +44 -4
- package/dist/json-schema/emit-composite.d.ts +16 -2
- package/dist/json-schema/emit-composite.d.ts.map +1 -1
- package/dist/json-schema/emit-composite.js +81 -13
- package/dist/json-schema/emit-scalar.d.ts +26 -3
- package/dist/json-schema/emit-scalar.d.ts.map +1 -1
- package/dist/json-schema/emit-scalar.js +124 -10
- package/dist/json-schema/emit-types.d.ts +11 -1
- package/dist/json-schema/emit-types.d.ts.map +1 -1
- package/dist/json-schema/emit-types.js +2 -0
- package/dist/json-schema/emit.d.ts +12 -1
- package/dist/json-schema/emit.d.ts.map +1 -1
- package/dist/json-schema/emit.js +23 -3
- package/dist/json-schema/freeze.d.ts +13 -2
- package/dist/json-schema/freeze.d.ts.map +1 -1
- package/dist/json-schema/freeze.js +41 -8
- package/dist/json-schema/index.d.ts +16 -2
- package/dist/json-schema/index.d.ts.map +1 -1
- package/dist/json-schema/index.js +23 -3
- package/dist/json-schema/issue.d.ts +4 -1
- package/dist/json-schema/issue.d.ts.map +1 -1
- package/dist/json-schema/issue.js +4 -1
- package/dist/json-schema/read.d.ts +24 -3
- package/dist/json-schema/read.d.ts.map +1 -1
- package/dist/json-schema/read.js +59 -12
- package/dist/json-schema/types.d.ts +45 -16
- package/dist/json-schema/types.d.ts.map +1 -1
- package/dist/json-schema/types.js +2 -0
- package/dist/kind/index.d.ts +40 -28
- package/dist/kind/index.d.ts.map +1 -1
- package/dist/kind/index.js +41 -13
- package/dist/lower/index.d.ts +6 -1
- package/dist/lower/index.d.ts.map +1 -1
- package/dist/lower/index.js +462 -46
- package/dist/message/index.d.ts +64 -10
- package/dist/message/index.d.ts.map +1 -1
- package/dist/message/index.js +155 -17
- package/dist/optimize/algebraic.d.ts +54 -0
- package/dist/optimize/algebraic.d.ts.map +1 -0
- package/dist/optimize/algebraic.js +314 -0
- package/dist/optimize/compact.d.ts +8 -1
- package/dist/optimize/compact.d.ts.map +1 -1
- package/dist/optimize/compact.js +13 -2
- package/dist/optimize/domain.d.ts +16 -0
- package/dist/optimize/domain.d.ts.map +1 -0
- package/dist/optimize/domain.js +619 -0
- package/dist/optimize/fold-boolean.d.ts +17 -2
- package/dist/optimize/fold-boolean.d.ts.map +1 -1
- package/dist/optimize/fold-boolean.js +59 -14
- package/dist/optimize/fold-common.d.ts +43 -8
- package/dist/optimize/fold-common.d.ts.map +1 -1
- package/dist/optimize/fold-common.js +37 -6
- package/dist/optimize/fold-constraints.d.ts +33 -0
- package/dist/optimize/fold-constraints.d.ts.map +1 -0
- package/dist/optimize/fold-constraints.js +484 -0
- package/dist/optimize/fold-scalar.d.ts +98 -13
- package/dist/optimize/fold-scalar.d.ts.map +1 -1
- package/dist/optimize/fold-scalar.js +98 -13
- package/dist/optimize/fold.d.ts +8 -1
- package/dist/optimize/fold.d.ts.map +1 -1
- package/dist/optimize/fold.js +22 -2
- package/dist/optimize/index.d.ts +9 -1
- package/dist/optimize/index.d.ts.map +1 -1
- package/dist/optimize/index.js +18 -3
- package/dist/optimize/map-node.d.ts +3 -1
- package/dist/optimize/map-node.d.ts.map +1 -1
- package/dist/optimize/map-node.js +48 -3
- package/dist/optimize/peephole.d.ts +16 -0
- package/dist/optimize/peephole.d.ts.map +1 -0
- package/dist/optimize/peephole.js +254 -0
- package/dist/optimize/remap.d.ts +2 -0
- package/dist/optimize/remap.d.ts.map +1 -1
- package/dist/optimize/remap.js +2 -0
- package/dist/optimize/rewrite.d.ts +13 -8
- package/dist/optimize/rewrite.d.ts.map +1 -1
- package/dist/optimize/rewrite.js +13 -8
- package/dist/plan/cache.d.ts +9 -3
- package/dist/plan/cache.d.ts.map +1 -1
- package/dist/plan/cache.js +34 -6
- package/dist/plan/index.d.ts +2 -0
- package/dist/plan/index.d.ts.map +1 -1
- package/dist/plan/index.js +2 -0
- package/dist/plan/predicate.d.ts +2 -0
- package/dist/plan/predicate.d.ts.map +1 -1
- package/dist/plan/predicate.js +298 -29
- package/dist/plan/schema-predicate.d.ts +6 -0
- package/dist/plan/schema-predicate.d.ts.map +1 -1
- package/dist/plan/schema-predicate.js +382 -19
- package/dist/plan/types.d.ts +2 -0
- package/dist/plan/types.d.ts.map +1 -1
- package/dist/plan/types.js +2 -0
- package/dist/result/index.d.ts +19 -5
- package/dist/result/index.d.ts.map +1 -1
- package/dist/result/index.js +10 -2
- package/dist/schema/common.d.ts +69 -6
- package/dist/schema/common.d.ts.map +1 -1
- package/dist/schema/common.js +104 -10
- package/dist/schema/freeze.d.ts +4 -0
- package/dist/schema/freeze.d.ts.map +1 -1
- package/dist/schema/freeze.js +40 -0
- package/dist/schema/index.d.ts +5 -2
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +4 -1
- package/dist/schema/lazy.d.ts +4 -0
- package/dist/schema/lazy.d.ts.map +1 -1
- package/dist/schema/lazy.js +4 -0
- package/dist/schema/literal.d.ts +7 -1
- package/dist/schema/literal.d.ts.map +1 -1
- package/dist/schema/literal.js +7 -1
- package/dist/schema/types.d.ts +109 -100
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +13 -2
- package/dist/schema/undefined.d.ts +17 -0
- package/dist/schema/undefined.d.ts.map +1 -0
- package/dist/schema/undefined.js +77 -0
- package/dist/schema/validate.d.ts +8 -1
- package/dist/schema/validate.d.ts.map +1 -1
- package/dist/schema/validate.js +255 -57
- package/docs/api.md +128 -8
- package/docs/assets/benchmark-headline.svg +163 -0
- package/docs/engine-notes.md +62 -15
- package/docs/index.html +1340 -702
- package/docs/ko/api.md +375 -0
- package/docs/ko/engine-notes.md +156 -0
- package/docs/ko/readme.md +378 -0
- package/package.json +66 -65
package/dist/issue/index.d.ts
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
import type { Result } from "../result/index.js";
|
|
2
2
|
/**
|
|
3
|
-
* @brief
|
|
3
|
+
* @brief One segment in a validation issue path.
|
|
4
|
+
* @details Strings represent object keys and numbers represent array indexes.
|
|
5
|
+
* The path formatter decides how those segments become user-facing text.
|
|
4
6
|
*/
|
|
5
7
|
export type PathSegment = string | number;
|
|
6
8
|
/**
|
|
7
|
-
* @brief issue
|
|
9
|
+
* @brief Closed set of validation issue codes emitted by TypeSea.
|
|
10
|
+
* @details Codes are stable machine-readable diagnostics shared by interpreters,
|
|
11
|
+
* compiled collectors, adapters, and message catalogs.
|
|
8
12
|
*/
|
|
9
|
-
export type IssueCode = "expected_string" | "expected_number" | "expected_bigint" | "expected_symbol" | "expected_boolean" | "expected_never" | "expected_literal" | "expected_array" | "expected_tuple" | "expected_tuple_length" | "expected_object" | "expected_record" | "expected_integer" | "expected_min_length" | "expected_max_length" | "expected_pattern" | "expected_gte" | "expected_lte" | "expected_required_key" | "expected_union" | "expected_discriminant" | "expected_refinement" | "expected_depth_limit" | "unrecognized_key";
|
|
13
|
+
export type IssueCode = "expected_string" | "expected_number" | "expected_date" | "expected_bigint" | "expected_symbol" | "expected_boolean" | "expected_never" | "expected_literal" | "expected_array" | "expected_map" | "expected_set" | "expected_instance" | "expected_tuple" | "expected_tuple_length" | "expected_object" | "expected_record" | "expected_integer" | "expected_min_length" | "expected_max_length" | "expected_pattern" | "expected_gte" | "expected_lte" | "expected_gt" | "expected_lt" | "expected_multiple_of" | "expected_required_key" | "expected_union" | "expected_discriminant" | "expected_refinement" | "expected_depth_limit" | "unrecognized_key";
|
|
10
14
|
/**
|
|
11
|
-
* @brief
|
|
15
|
+
* @brief Immutable validation diagnostic.
|
|
16
|
+
* @details The message field is optional so hot boolean validation and
|
|
17
|
+
* low-level collectors can defer human-readable formatting until requested.
|
|
12
18
|
*/
|
|
13
19
|
export interface Issue {
|
|
14
20
|
readonly path: readonly PathSegment[];
|
|
@@ -18,27 +24,53 @@ export interface Issue {
|
|
|
18
24
|
readonly message: string | undefined;
|
|
19
25
|
}
|
|
20
26
|
/**
|
|
21
|
-
* @brief
|
|
27
|
+
* @brief Result shape returned by diagnostic validation APIs.
|
|
28
|
+
* @details Success carries the accepted value, failure carries a frozen issue
|
|
29
|
+
* array suitable for message formatting or adapter conversion.
|
|
22
30
|
*/
|
|
23
31
|
export type CheckResult<TValue> = Result<TValue, readonly Issue[]>;
|
|
24
32
|
/**
|
|
25
|
-
* @brief
|
|
33
|
+
* @brief Construct one issue record without freezing it.
|
|
34
|
+
* @details Collectors use this helper while building mutable arrays, then
|
|
35
|
+
* freeze the final array at the API boundary.
|
|
36
|
+
* @param path Path to the failing value.
|
|
37
|
+
* @param code Stable issue code.
|
|
38
|
+
* @param expected Expected-value label, when available.
|
|
39
|
+
* @param actual Actual-value label, when available.
|
|
40
|
+
* @param message Pre-rendered human message, when available.
|
|
41
|
+
* @returns Mutable issue record ready for collection.
|
|
26
42
|
*/
|
|
27
43
|
export declare function makeIssue(path: readonly PathSegment[], code: IssueCode, expected: string | undefined, actual: string | undefined, message: string | undefined): Issue;
|
|
28
44
|
/**
|
|
29
|
-
* @brief copy issue
|
|
45
|
+
* @brief Defensive-copy externally supplied issue arrays before publication.
|
|
46
|
+
* @details Adapter and user callback boundaries may hand back mutable objects.
|
|
47
|
+
* Copying revalidates shape and ensures TypeSea publishes frozen diagnostics.
|
|
48
|
+
* @param value Candidate issue array.
|
|
49
|
+
* @returns Frozen issue array with copied paths.
|
|
30
50
|
*/
|
|
31
51
|
export declare function copyIssueArray(value: unknown): readonly Issue[];
|
|
32
52
|
/**
|
|
33
|
-
* @brief
|
|
53
|
+
* @brief Normalize generated collector output into the public immutable shape.
|
|
54
|
+
* @details Generated collectors return arrays only on failure. Empty arrays use
|
|
55
|
+
* the shared sentinel so failed-but-empty states cannot allocate repeatedly.
|
|
56
|
+
* @param value Candidate issue array from a collector.
|
|
57
|
+
* @returns Frozen public issue array.
|
|
34
58
|
*/
|
|
35
59
|
export declare function finalizeIssueArray(value: unknown): readonly Issue[];
|
|
36
60
|
/**
|
|
37
|
-
* @brief
|
|
61
|
+
* @brief Freeze issues and their path arrays in-place.
|
|
62
|
+
* @details Paths are built mutably for speed during collection, then hardened
|
|
63
|
+
* before callers can retain or format the diagnostics.
|
|
64
|
+
* @param issues Issue array to harden.
|
|
65
|
+
* @returns The same issue array after freezing.
|
|
38
66
|
*/
|
|
39
67
|
export declare function freezeIssueArray(issues: readonly Issue[]): readonly Issue[];
|
|
40
68
|
/**
|
|
41
|
-
* @brief is issue
|
|
69
|
+
* @brief Check whether a value is one of TypeSea's stable issue codes.
|
|
70
|
+
* @details Issue helpers publish frozen diagnostics so adapters and callers cannot mutate
|
|
71
|
+
* validation results later.
|
|
72
|
+
* @param value Candidate issue code.
|
|
73
|
+
* @returns True when the value belongs to the closed issue-code set.
|
|
42
74
|
*/
|
|
43
75
|
export declare function isIssueCodeValue(value: unknown): value is IssueCode;
|
|
44
76
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/issue/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/issue/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC;AAE1C;;;;GAIG;AACH,MAAM,MAAM,SAAS,GACf,iBAAiB,GACjB,iBAAiB,GACjB,eAAe,GACf,iBAAiB,GACjB,iBAAiB,GACjB,kBAAkB,GAClB,gBAAgB,GAChB,kBAAkB,GAClB,gBAAgB,GAChB,cAAc,GACd,cAAc,GACd,mBAAmB,GACnB,gBAAgB,GAChB,uBAAuB,GACvB,iBAAiB,GACjB,iBAAiB,GACjB,kBAAkB,GAClB,qBAAqB,GACrB,qBAAqB,GACrB,kBAAkB,GAClB,cAAc,GACd,cAAc,GACd,aAAa,GACb,aAAa,GACb,sBAAsB,GACtB,uBAAuB,GACvB,gBAAgB,GAChB,uBAAuB,GACvB,qBAAqB,GACrB,sBAAsB,GACtB,kBAAkB,CAAC;AAEzB;;;;GAIG;AACH,MAAM,WAAW,KAAK;IAClB,QAAQ,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;CACxC;AAED;;;;GAIG;AACH,MAAM,MAAM,WAAW,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC,CAAC;AAUnE;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CACrB,IAAI,EAAE,SAAS,WAAW,EAAE,EAC5B,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,MAAM,GAAG,SAAS,GAC5B,KAAK,CAQP;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,KAAK,EAAE,CAS/D;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,KAAK,EAAE,CAQnE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,SAAS,KAAK,EAAE,CAS3E;AA6DD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAkCnE"}
|
package/dist/issue/index.js
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @brief
|
|
2
|
+
* @brief Shared success sentinel for compiled check() paths.
|
|
3
|
+
* @details Reusing a frozen empty array avoids allocating diagnostics for
|
|
4
|
+
* successful validation.
|
|
3
5
|
*/
|
|
4
6
|
const EMPTY_ISSUES = Object.freeze([]);
|
|
7
|
+
const EMPTY_PATH = Object.freeze([]);
|
|
5
8
|
/**
|
|
6
|
-
* @brief
|
|
9
|
+
* @brief Construct one issue record without freezing it.
|
|
10
|
+
* @details Collectors use this helper while building mutable arrays, then
|
|
11
|
+
* freeze the final array at the API boundary.
|
|
12
|
+
* @param path Path to the failing value.
|
|
13
|
+
* @param code Stable issue code.
|
|
14
|
+
* @param expected Expected-value label, when available.
|
|
15
|
+
* @param actual Actual-value label, when available.
|
|
16
|
+
* @param message Pre-rendered human message, when available.
|
|
17
|
+
* @returns Mutable issue record ready for collection.
|
|
7
18
|
*/
|
|
8
19
|
export function makeIssue(path, code, expected, actual, message) {
|
|
9
20
|
return {
|
|
@@ -15,7 +26,11 @@ export function makeIssue(path, code, expected, actual, message) {
|
|
|
15
26
|
};
|
|
16
27
|
}
|
|
17
28
|
/**
|
|
18
|
-
* @brief copy issue
|
|
29
|
+
* @brief Defensive-copy externally supplied issue arrays before publication.
|
|
30
|
+
* @details Adapter and user callback boundaries may hand back mutable objects.
|
|
31
|
+
* Copying revalidates shape and ensures TypeSea publishes frozen diagnostics.
|
|
32
|
+
* @param value Candidate issue array.
|
|
33
|
+
* @returns Frozen issue array with copied paths.
|
|
19
34
|
*/
|
|
20
35
|
export function copyIssueArray(value) {
|
|
21
36
|
if (!isUnknownArray(value)) {
|
|
@@ -28,7 +43,11 @@ export function copyIssueArray(value) {
|
|
|
28
43
|
return freezeIssueArray(copied);
|
|
29
44
|
}
|
|
30
45
|
/**
|
|
31
|
-
* @brief
|
|
46
|
+
* @brief Normalize generated collector output into the public immutable shape.
|
|
47
|
+
* @details Generated collectors return arrays only on failure. Empty arrays use
|
|
48
|
+
* the shared sentinel so failed-but-empty states cannot allocate repeatedly.
|
|
49
|
+
* @param value Candidate issue array from a collector.
|
|
50
|
+
* @returns Frozen public issue array.
|
|
32
51
|
*/
|
|
33
52
|
export function finalizeIssueArray(value) {
|
|
34
53
|
if (!isUnknownArray(value)) {
|
|
@@ -40,7 +59,11 @@ export function finalizeIssueArray(value) {
|
|
|
40
59
|
return copyIssueArray(value);
|
|
41
60
|
}
|
|
42
61
|
/**
|
|
43
|
-
* @brief
|
|
62
|
+
* @brief Freeze issues and their path arrays in-place.
|
|
63
|
+
* @details Paths are built mutably for speed during collection, then hardened
|
|
64
|
+
* before callers can retain or format the diagnostics.
|
|
65
|
+
* @param issues Issue array to harden.
|
|
66
|
+
* @returns The same issue array after freezing.
|
|
44
67
|
*/
|
|
45
68
|
export function freezeIssueArray(issues) {
|
|
46
69
|
for (let index = 0; index < issues.length; index += 1) {
|
|
@@ -53,7 +76,11 @@ export function freezeIssueArray(issues) {
|
|
|
53
76
|
return Object.freeze(issues);
|
|
54
77
|
}
|
|
55
78
|
/**
|
|
56
|
-
* @brief
|
|
79
|
+
* @brief Copy and validate one issue-like object.
|
|
80
|
+
* @details Only own data read syntax is used here because the candidate object
|
|
81
|
+
* has already been reduced to a plain record by `isRecord`.
|
|
82
|
+
* @param value Candidate issue object.
|
|
83
|
+
* @returns Normalized mutable issue record.
|
|
57
84
|
*/
|
|
58
85
|
function copyIssue(value) {
|
|
59
86
|
if (!isRecord(value)) {
|
|
@@ -75,12 +102,19 @@ function copyIssue(value) {
|
|
|
75
102
|
return makeIssue(path, code, expected, actual, message);
|
|
76
103
|
}
|
|
77
104
|
/**
|
|
78
|
-
* @brief
|
|
105
|
+
* @brief Copy and validate an issue path.
|
|
106
|
+
* @details Negative and fractional numeric segments are rejected because TypeSea
|
|
107
|
+
* only emits non-negative array indexes.
|
|
108
|
+
* @param value Candidate path array.
|
|
109
|
+
* @returns Copied path, or the shared empty-path sentinel.
|
|
79
110
|
*/
|
|
80
111
|
function copyPath(value) {
|
|
81
112
|
if (!isUnknownArray(value)) {
|
|
82
113
|
throw new TypeError("issue path must be an array");
|
|
83
114
|
}
|
|
115
|
+
if (value.length === 0) {
|
|
116
|
+
return EMPTY_PATH;
|
|
117
|
+
}
|
|
84
118
|
const copied = new Array(value.length);
|
|
85
119
|
for (let index = 0; index < value.length; index += 1) {
|
|
86
120
|
const segment = value[index];
|
|
@@ -99,12 +133,17 @@ function copyPath(value) {
|
|
|
99
133
|
return copied;
|
|
100
134
|
}
|
|
101
135
|
/**
|
|
102
|
-
* @brief is issue
|
|
136
|
+
* @brief Check whether a value is one of TypeSea's stable issue codes.
|
|
137
|
+
* @details Issue helpers publish frozen diagnostics so adapters and callers cannot mutate
|
|
138
|
+
* validation results later.
|
|
139
|
+
* @param value Candidate issue code.
|
|
140
|
+
* @returns True when the value belongs to the closed issue-code set.
|
|
103
141
|
*/
|
|
104
142
|
export function isIssueCodeValue(value) {
|
|
105
143
|
switch (value) {
|
|
106
144
|
case "expected_string":
|
|
107
145
|
case "expected_number":
|
|
146
|
+
case "expected_date":
|
|
108
147
|
case "expected_bigint":
|
|
109
148
|
case "expected_symbol":
|
|
110
149
|
case "expected_boolean":
|
|
@@ -121,6 +160,9 @@ export function isIssueCodeValue(value) {
|
|
|
121
160
|
case "expected_pattern":
|
|
122
161
|
case "expected_gte":
|
|
123
162
|
case "expected_lte":
|
|
163
|
+
case "expected_gt":
|
|
164
|
+
case "expected_lt":
|
|
165
|
+
case "expected_multiple_of":
|
|
124
166
|
case "expected_required_key":
|
|
125
167
|
case "expected_union":
|
|
126
168
|
case "expected_discriminant":
|
|
@@ -133,19 +175,31 @@ export function isIssueCodeValue(value) {
|
|
|
133
175
|
}
|
|
134
176
|
}
|
|
135
177
|
/**
|
|
136
|
-
* @brief
|
|
178
|
+
* @brief Accept optional text fields used by issue diagnostics.
|
|
179
|
+
* @details Issue helpers publish frozen diagnostics so adapters and callers cannot mutate
|
|
180
|
+
* validation results later.
|
|
181
|
+
* @param value Candidate issue text field.
|
|
182
|
+
* @returns True for string values and undefined.
|
|
137
183
|
*/
|
|
138
184
|
function isOptionalString(value) {
|
|
139
185
|
return value === undefined || typeof value === "string";
|
|
140
186
|
}
|
|
141
187
|
/**
|
|
142
|
-
* @brief
|
|
188
|
+
* @brief Check whether a value can be read as an issue-like record.
|
|
189
|
+
* @details Issue helpers publish frozen diagnostics so adapters and callers cannot mutate
|
|
190
|
+
* validation results later.
|
|
191
|
+
* @param value Candidate runtime value.
|
|
192
|
+
* @returns True for non-array object values.
|
|
143
193
|
*/
|
|
144
194
|
function isRecord(value) {
|
|
145
195
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
146
196
|
}
|
|
147
197
|
/**
|
|
148
|
-
* @brief is
|
|
198
|
+
* @brief Check whether a value is an array before indexed reads.
|
|
199
|
+
* @details Issue helpers publish frozen diagnostics so adapters and callers cannot mutate
|
|
200
|
+
* validation results later.
|
|
201
|
+
* @param value Candidate runtime value.
|
|
202
|
+
* @returns True when the value is an array.
|
|
149
203
|
*/
|
|
150
204
|
function isUnknownArray(value) {
|
|
151
205
|
return Array.isArray(value);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file emit-combinator.ts
|
|
3
3
|
* @brief Combinator TypeSea schema to JSON Schema emitters.
|
|
4
|
+
* @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
|
|
5
|
+
* report a structured export issue.
|
|
4
6
|
*/
|
|
5
7
|
import { SchemaTag } from "../kind/index.js";
|
|
6
8
|
import type { PathSegment } from "../issue/index.js";
|
|
@@ -8,21 +10,59 @@ import type { Schema } from "../schema/index.js";
|
|
|
8
10
|
import type { JsonSchemaEmitter } from "./emit-types.js";
|
|
9
11
|
import type { JsonSchema, JsonSchemaDialect, JsonSchemaExportIssue } from "./types.js";
|
|
10
12
|
/**
|
|
11
|
-
* @brief
|
|
13
|
+
* @brief Emit a TypeSea union as a JSON Schema `anyOf` list.
|
|
14
|
+
* @details Each branch is emitted with its index appended to the issue path so
|
|
15
|
+
* unsupported children can be reported precisely. A single failed child aborts
|
|
16
|
+
* the whole union because dropping a branch would make the exported schema
|
|
17
|
+
* stricter than the TypeSea validator.
|
|
18
|
+
* @param options Union option schemas in declaration order.
|
|
19
|
+
* @param path Mutable issue path stack owned by the export walk.
|
|
20
|
+
* @param issues Mutable export issue buffer.
|
|
21
|
+
* @param emitChild Recursive schema emitter callback.
|
|
22
|
+
* @param dialect Target JSON Schema dialect.
|
|
23
|
+
* @returns JSON Schema union, or undefined when a child cannot be emitted.
|
|
12
24
|
*/
|
|
13
25
|
export declare function emitUnion(options: readonly Schema[], path: PathSegment[], issues: JsonSchemaExportIssue[], emitChild: JsonSchemaEmitter, dialect: JsonSchemaDialect): JsonSchema | undefined;
|
|
14
26
|
/**
|
|
15
|
-
* @brief
|
|
27
|
+
* @brief Emit a TypeSea intersection as a JSON Schema `allOf` pair.
|
|
28
|
+
* @details Both sides must be representable. If either side fails, the exported
|
|
29
|
+
* schema would no longer model the same acceptance set, so the emitter reports
|
|
30
|
+
* the failed side and returns undefined.
|
|
31
|
+
* @param left Left intersection operand.
|
|
32
|
+
* @param right Right intersection operand.
|
|
33
|
+
* @param path Mutable issue path stack owned by the export walk.
|
|
34
|
+
* @param issues Mutable export issue buffer.
|
|
35
|
+
* @param emitChild Recursive schema emitter callback.
|
|
36
|
+
* @param dialect Target JSON Schema dialect.
|
|
37
|
+
* @returns JSON Schema intersection, or undefined when a side cannot be emitted.
|
|
16
38
|
*/
|
|
17
39
|
export declare function emitIntersection(left: Schema, right: Schema, path: PathSegment[], issues: JsonSchemaExportIssue[], emitChild: JsonSchemaEmitter, dialect: JsonSchemaDialect): JsonSchema | undefined;
|
|
18
40
|
/**
|
|
19
|
-
* @brief
|
|
41
|
+
* @brief Emit a discriminated union through the general union exporter.
|
|
42
|
+
* @details JSON Schema output does not need TypeSea's dispatch table; it only
|
|
43
|
+
* needs the branch schemas. The discriminant proof has already been enforced at
|
|
44
|
+
* builder time, so preserving branch order is enough for diagnostics.
|
|
45
|
+
* @param cases Discriminated-union cases from the TypeSea schema.
|
|
46
|
+
* @param path Mutable issue path stack owned by the export walk.
|
|
47
|
+
* @param issues Mutable export issue buffer.
|
|
48
|
+
* @param emitChild Recursive schema emitter callback.
|
|
49
|
+
* @param dialect Target JSON Schema dialect.
|
|
50
|
+
* @returns JSON Schema union, or undefined when a child cannot be emitted.
|
|
20
51
|
*/
|
|
21
52
|
export declare function emitDiscriminatedUnion(cases: Extract<Schema, {
|
|
22
53
|
readonly tag: typeof SchemaTag.DiscriminatedUnion;
|
|
23
54
|
}>["cases"], path: PathSegment[], issues: JsonSchemaExportIssue[], emitChild: JsonSchemaEmitter, dialect: JsonSchemaDialect): JsonSchema | undefined;
|
|
24
55
|
/**
|
|
25
|
-
* @brief
|
|
56
|
+
* @brief Emit a nullable wrapper as an `anyOf` with `null`.
|
|
57
|
+
* @details The wrapped schema is emitted first so unsupported inner constructs
|
|
58
|
+
* are reported at a stable `nullable` path segment instead of silently widening
|
|
59
|
+
* to just null.
|
|
60
|
+
* @param inner Inner TypeSea schema.
|
|
61
|
+
* @param path Mutable issue path stack owned by the export walk.
|
|
62
|
+
* @param issues Mutable export issue buffer.
|
|
63
|
+
* @param emitChild Recursive schema emitter callback.
|
|
64
|
+
* @param dialect Target JSON Schema dialect.
|
|
65
|
+
* @returns Nullable JSON Schema, or undefined when the inner schema fails.
|
|
26
66
|
*/
|
|
27
67
|
export declare function emitNullable(inner: Schema, path: PathSegment[], issues: JsonSchemaExportIssue[], emitChild: JsonSchemaEmitter, dialect: JsonSchemaDialect): JsonSchema | undefined;
|
|
28
68
|
//# sourceMappingURL=emit-combinator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit-combinator.d.ts","sourceRoot":"","sources":["../../src/json-schema/emit-combinator.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"emit-combinator.d.ts","sourceRoot":"","sources":["../../src/json-schema/emit-combinator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,KAAK,EACR,UAAU,EACV,iBAAiB,EACjB,qBAAqB,EACxB,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CACrB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GAC3B,UAAU,GAAG,SAAS,CAyBxB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC5B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GAC3B,UAAU,GAAG,SAAS,CAuBxB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAClC,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE;IACnB,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,kBAAkB,CAAA;CACpD,CAAC,CAAC,OAAO,CAAC,EACX,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GAC3B,UAAU,GAAG,SAAS,CASxB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CACxB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GAC3B,UAAU,GAAG,SAAS,CAiBxB"}
|
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file emit-combinator.ts
|
|
3
3
|
* @brief Combinator TypeSea schema to JSON Schema emitters.
|
|
4
|
+
* @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
|
|
5
|
+
* report a structured export issue.
|
|
4
6
|
*/
|
|
5
7
|
import { SchemaTag } from "../kind/index.js";
|
|
6
8
|
import { pushJsonSchemaIssue } from "./issue.js";
|
|
7
9
|
/**
|
|
8
|
-
* @brief
|
|
10
|
+
* @brief Emit a TypeSea union as a JSON Schema `anyOf` list.
|
|
11
|
+
* @details Each branch is emitted with its index appended to the issue path so
|
|
12
|
+
* unsupported children can be reported precisely. A single failed child aborts
|
|
13
|
+
* the whole union because dropping a branch would make the exported schema
|
|
14
|
+
* stricter than the TypeSea validator.
|
|
15
|
+
* @param options Union option schemas in declaration order.
|
|
16
|
+
* @param path Mutable issue path stack owned by the export walk.
|
|
17
|
+
* @param issues Mutable export issue buffer.
|
|
18
|
+
* @param emitChild Recursive schema emitter callback.
|
|
19
|
+
* @param dialect Target JSON Schema dialect.
|
|
20
|
+
* @returns JSON Schema union, or undefined when a child cannot be emitted.
|
|
9
21
|
*/
|
|
10
22
|
export function emitUnion(options, path, issues, emitChild, dialect) {
|
|
11
23
|
const emitted = new Array(options.length);
|
|
@@ -34,7 +46,17 @@ export function emitUnion(options, path, issues, emitChild, dialect) {
|
|
|
34
46
|
};
|
|
35
47
|
}
|
|
36
48
|
/**
|
|
37
|
-
* @brief
|
|
49
|
+
* @brief Emit a TypeSea intersection as a JSON Schema `allOf` pair.
|
|
50
|
+
* @details Both sides must be representable. If either side fails, the exported
|
|
51
|
+
* schema would no longer model the same acceptance set, so the emitter reports
|
|
52
|
+
* the failed side and returns undefined.
|
|
53
|
+
* @param left Left intersection operand.
|
|
54
|
+
* @param right Right intersection operand.
|
|
55
|
+
* @param path Mutable issue path stack owned by the export walk.
|
|
56
|
+
* @param issues Mutable export issue buffer.
|
|
57
|
+
* @param emitChild Recursive schema emitter callback.
|
|
58
|
+
* @param dialect Target JSON Schema dialect.
|
|
59
|
+
* @returns JSON Schema intersection, or undefined when a side cannot be emitted.
|
|
38
60
|
*/
|
|
39
61
|
export function emitIntersection(left, right, path, issues, emitChild, dialect) {
|
|
40
62
|
path.push("left");
|
|
@@ -61,7 +83,16 @@ export function emitIntersection(left, right, path, issues, emitChild, dialect)
|
|
|
61
83
|
};
|
|
62
84
|
}
|
|
63
85
|
/**
|
|
64
|
-
* @brief
|
|
86
|
+
* @brief Emit a discriminated union through the general union exporter.
|
|
87
|
+
* @details JSON Schema output does not need TypeSea's dispatch table; it only
|
|
88
|
+
* needs the branch schemas. The discriminant proof has already been enforced at
|
|
89
|
+
* builder time, so preserving branch order is enough for diagnostics.
|
|
90
|
+
* @param cases Discriminated-union cases from the TypeSea schema.
|
|
91
|
+
* @param path Mutable issue path stack owned by the export walk.
|
|
92
|
+
* @param issues Mutable export issue buffer.
|
|
93
|
+
* @param emitChild Recursive schema emitter callback.
|
|
94
|
+
* @param dialect Target JSON Schema dialect.
|
|
95
|
+
* @returns JSON Schema union, or undefined when a child cannot be emitted.
|
|
65
96
|
*/
|
|
66
97
|
export function emitDiscriminatedUnion(cases, path, issues, emitChild, dialect) {
|
|
67
98
|
const options = new Array(cases.length);
|
|
@@ -74,7 +105,16 @@ export function emitDiscriminatedUnion(cases, path, issues, emitChild, dialect)
|
|
|
74
105
|
return emitUnion(options, path, issues, emitChild, dialect);
|
|
75
106
|
}
|
|
76
107
|
/**
|
|
77
|
-
* @brief
|
|
108
|
+
* @brief Emit a nullable wrapper as an `anyOf` with `null`.
|
|
109
|
+
* @details The wrapped schema is emitted first so unsupported inner constructs
|
|
110
|
+
* are reported at a stable `nullable` path segment instead of silently widening
|
|
111
|
+
* to just null.
|
|
112
|
+
* @param inner Inner TypeSea schema.
|
|
113
|
+
* @param path Mutable issue path stack owned by the export walk.
|
|
114
|
+
* @param issues Mutable export issue buffer.
|
|
115
|
+
* @param emitChild Recursive schema emitter callback.
|
|
116
|
+
* @param dialect Target JSON Schema dialect.
|
|
117
|
+
* @returns Nullable JSON Schema, or undefined when the inner schema fails.
|
|
78
118
|
*/
|
|
79
119
|
export function emitNullable(inner, path, issues, emitChild, dialect) {
|
|
80
120
|
path.push("nullable");
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file emit-composite.ts
|
|
3
3
|
* @brief Container TypeSea schema to JSON Schema emitters.
|
|
4
|
+
* @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
|
|
5
|
+
* report a structured export issue.
|
|
4
6
|
*/
|
|
5
7
|
import { SchemaTag } from "../kind/index.js";
|
|
6
8
|
import type { PathSegment } from "../issue/index.js";
|
|
@@ -9,18 +11,30 @@ import type { JsonSchemaEmitter } from "./emit-types.js";
|
|
|
9
11
|
import type { JsonSchema, JsonSchemaDialect, JsonSchemaExportIssue } from "./types.js";
|
|
10
12
|
/**
|
|
11
13
|
* @brief emit array.
|
|
14
|
+
* @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
|
|
15
|
+
* report a structured export issue.
|
|
12
16
|
*/
|
|
13
|
-
export declare function emitArray(
|
|
17
|
+
export declare function emitArray(schema: Extract<Schema, {
|
|
18
|
+
readonly tag: typeof SchemaTag.Array;
|
|
19
|
+
}>, path: PathSegment[], issues: JsonSchemaExportIssue[], emitChild: JsonSchemaEmitter, dialect: JsonSchemaDialect): JsonSchema | undefined;
|
|
14
20
|
/**
|
|
15
21
|
* @brief emit tuple.
|
|
22
|
+
* @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
|
|
23
|
+
* report a structured export issue.
|
|
16
24
|
*/
|
|
17
|
-
export declare function emitTuple(
|
|
25
|
+
export declare function emitTuple(schema: Extract<Schema, {
|
|
26
|
+
readonly tag: typeof SchemaTag.Tuple;
|
|
27
|
+
}>, path: PathSegment[], issues: JsonSchemaExportIssue[], emitChild: JsonSchemaEmitter, dialect: JsonSchemaDialect): JsonSchema | undefined;
|
|
18
28
|
/**
|
|
19
29
|
* @brief emit record.
|
|
30
|
+
* @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
|
|
31
|
+
* report a structured export issue.
|
|
20
32
|
*/
|
|
21
33
|
export declare function emitRecord(value: Schema, path: PathSegment[], issues: JsonSchemaExportIssue[], emitChild: JsonSchemaEmitter, dialect: JsonSchemaDialect): JsonSchema | undefined;
|
|
22
34
|
/**
|
|
23
35
|
* @brief emit object.
|
|
36
|
+
* @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
|
|
37
|
+
* report a structured export issue.
|
|
24
38
|
*/
|
|
25
39
|
export declare function emitObject(schema: Extract<Schema, {
|
|
26
40
|
readonly tag: typeof SchemaTag.Object;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit-composite.d.ts","sourceRoot":"","sources":["../../src/json-schema/emit-composite.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"emit-composite.d.ts","sourceRoot":"","sources":["../../src/json-schema/emit-composite.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAIH,SAAS,EACZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,KAAK,EACR,UAAU,EACV,iBAAiB,EACjB,qBAAqB,EAExB,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,wBAAgB,SAAS,CACrB,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,KAAK,CAAA;CAAE,CAAC,EACjE,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GAC3B,UAAU,GAAG,SAAS,CAkCxB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACrB,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,KAAK,CAAA;CAAE,CAAC,EACjE,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GAC3B,UAAU,GAAG,SAAS,CAyDxB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACtB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GAC3B,UAAU,GAAG,SAAS,CAaxB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACtB,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,MAAM,CAAA;CAAE,CAAC,EAClE,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GAC3B,UAAU,GAAG,SAAS,CAgDxB"}
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file emit-composite.ts
|
|
3
3
|
* @brief Container TypeSea schema to JSON Schema emitters.
|
|
4
|
+
* @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
|
|
5
|
+
* report a structured export issue.
|
|
4
6
|
*/
|
|
5
|
-
import { ObjectModeTag, PresenceTag, SchemaTag } from "../kind/index.js";
|
|
7
|
+
import { ArrayCheckTag, ObjectModeTag, PresenceTag, SchemaTag } from "../kind/index.js";
|
|
6
8
|
import { pushJsonSchemaIssue } from "./issue.js";
|
|
7
9
|
/**
|
|
8
10
|
* @brief emit array.
|
|
11
|
+
* @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
|
|
12
|
+
* report a structured export issue.
|
|
9
13
|
*/
|
|
10
|
-
export function emitArray(
|
|
14
|
+
export function emitArray(schema, path, issues, emitChild, dialect) {
|
|
15
|
+
const item = schema.item;
|
|
11
16
|
path.push("items");
|
|
12
17
|
const emitted = emitChild(item, path, issues, dialect);
|
|
13
18
|
if (emitted === undefined) {
|
|
@@ -16,15 +21,38 @@ export function emitArray(item, path, issues, emitChild, dialect) {
|
|
|
16
21
|
return undefined;
|
|
17
22
|
}
|
|
18
23
|
path.pop();
|
|
19
|
-
|
|
24
|
+
const result = {
|
|
20
25
|
type: "array",
|
|
21
26
|
items: emitted
|
|
22
27
|
};
|
|
28
|
+
const checks = schema.checks;
|
|
29
|
+
for (let index = 0; index < checks.length; index += 1) {
|
|
30
|
+
const check = checks[index];
|
|
31
|
+
if (check === undefined) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
switch (check.tag) {
|
|
35
|
+
case ArrayCheckTag.Min:
|
|
36
|
+
result.minItems = result.minItems === undefined
|
|
37
|
+
? check.value
|
|
38
|
+
: Math.max(result.minItems, check.value);
|
|
39
|
+
break;
|
|
40
|
+
case ArrayCheckTag.Max:
|
|
41
|
+
result.maxItems = result.maxItems === undefined
|
|
42
|
+
? check.value
|
|
43
|
+
: Math.min(result.maxItems, check.value);
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return result;
|
|
23
48
|
}
|
|
24
49
|
/**
|
|
25
50
|
* @brief emit tuple.
|
|
51
|
+
* @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
|
|
52
|
+
* report a structured export issue.
|
|
26
53
|
*/
|
|
27
|
-
export function emitTuple(
|
|
54
|
+
export function emitTuple(schema, path, issues, emitChild, dialect) {
|
|
55
|
+
const items = schema.items;
|
|
28
56
|
const emitted = new Array(items.length);
|
|
29
57
|
let failed = false;
|
|
30
58
|
for (let index = 0; index < items.length; index += 1) {
|
|
@@ -46,24 +74,46 @@ export function emitTuple(items, path, issues, emitChild, dialect) {
|
|
|
46
74
|
if (failed) {
|
|
47
75
|
return undefined;
|
|
48
76
|
}
|
|
77
|
+
let restSchema;
|
|
78
|
+
if (schema.rest !== undefined) {
|
|
79
|
+
path.push("rest");
|
|
80
|
+
restSchema = emitChild(schema.rest, path, issues, dialect);
|
|
81
|
+
if (restSchema === undefined) {
|
|
82
|
+
pushJsonSchemaIssue(path, issues, "unsupported_child", "Tuple rest schema is unsupported");
|
|
83
|
+
path.pop();
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
path.pop();
|
|
87
|
+
}
|
|
49
88
|
if (dialect === "2020-12") {
|
|
50
|
-
|
|
89
|
+
const result = {
|
|
51
90
|
type: "array",
|
|
52
91
|
prefixItems: emitted,
|
|
53
|
-
minItems: items.length
|
|
54
|
-
maxItems: items.length
|
|
92
|
+
minItems: items.length
|
|
55
93
|
};
|
|
94
|
+
if (restSchema === undefined) {
|
|
95
|
+
result.maxItems = items.length;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
result.items = restSchema;
|
|
99
|
+
}
|
|
100
|
+
return result;
|
|
56
101
|
}
|
|
57
|
-
|
|
102
|
+
const result = {
|
|
58
103
|
type: "array",
|
|
59
104
|
items: emitted,
|
|
60
|
-
additionalItems: false,
|
|
61
|
-
minItems: items.length
|
|
62
|
-
maxItems: items.length
|
|
105
|
+
additionalItems: restSchema ?? false,
|
|
106
|
+
minItems: items.length
|
|
63
107
|
};
|
|
108
|
+
if (restSchema === undefined) {
|
|
109
|
+
result.maxItems = items.length;
|
|
110
|
+
}
|
|
111
|
+
return result;
|
|
64
112
|
}
|
|
65
113
|
/**
|
|
66
114
|
* @brief emit record.
|
|
115
|
+
* @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
|
|
116
|
+
* report a structured export issue.
|
|
67
117
|
*/
|
|
68
118
|
export function emitRecord(value, path, issues, emitChild, dialect) {
|
|
69
119
|
path.push("additionalProperties");
|
|
@@ -81,6 +131,8 @@ export function emitRecord(value, path, issues, emitChild, dialect) {
|
|
|
81
131
|
}
|
|
82
132
|
/**
|
|
83
133
|
* @brief emit object.
|
|
134
|
+
* @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
|
|
135
|
+
* report a structured export issue.
|
|
84
136
|
*/
|
|
85
137
|
export function emitObject(schema, path, issues, emitChild, dialect) {
|
|
86
138
|
const properties = makeJsonSchemaProperties();
|
|
@@ -109,10 +161,22 @@ export function emitObject(schema, path, issues, emitChild, dialect) {
|
|
|
109
161
|
if (failed) {
|
|
110
162
|
return undefined;
|
|
111
163
|
}
|
|
164
|
+
let additionalProperties = schema.mode !== ObjectModeTag.Strict;
|
|
165
|
+
if (schema.catchall !== undefined) {
|
|
166
|
+
path.push("additionalProperties");
|
|
167
|
+
const emittedCatchall = emitChild(schema.catchall, path, issues, dialect);
|
|
168
|
+
if (emittedCatchall === undefined) {
|
|
169
|
+
pushJsonSchemaIssue(path, issues, "unsupported_child", "Object catchall schema is unsupported");
|
|
170
|
+
path.pop();
|
|
171
|
+
return undefined;
|
|
172
|
+
}
|
|
173
|
+
path.pop();
|
|
174
|
+
additionalProperties = emittedCatchall;
|
|
175
|
+
}
|
|
112
176
|
const result = {
|
|
113
177
|
type: "object",
|
|
114
178
|
properties,
|
|
115
|
-
additionalProperties
|
|
179
|
+
additionalProperties
|
|
116
180
|
};
|
|
117
181
|
if (required.length !== 0) {
|
|
118
182
|
result.required = required;
|
|
@@ -120,7 +184,11 @@ export function emitObject(schema, path, issues, emitChild, dialect) {
|
|
|
120
184
|
return result;
|
|
121
185
|
}
|
|
122
186
|
/**
|
|
123
|
-
* @brief
|
|
187
|
+
* @brief Allocate the JSON Schema property table with no prototype chain.
|
|
188
|
+
* @details Object schema keys originate from user models. A null-prototype map
|
|
189
|
+
* prevents names such as `constructor` from colliding with inherited object
|
|
190
|
+
* members while keeping writes monomorphic for the emitter loop.
|
|
191
|
+
* @returns Empty mutable property table for an object schema emission pass.
|
|
124
192
|
*/
|
|
125
193
|
function makeJsonSchemaProperties() {
|
|
126
194
|
return Object.create(null);
|