schema-components 1.19.0 → 1.21.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/dist/core/adapter.d.mts +10 -3
- package/dist/core/adapter.mjs +237 -31
- package/dist/core/constraints.d.mts +2 -2
- package/dist/core/constraints.mjs +0 -2
- package/dist/core/diagnostics.d.mts +1 -1
- package/dist/core/errors.d.mts +1 -1
- package/dist/core/errors.mjs +10 -8
- package/dist/core/fieldOrder.d.mts +1 -1
- package/dist/core/formats.d.mts +21 -14
- package/dist/core/formats.mjs +88 -4
- package/dist/core/merge.d.mts +11 -2
- package/dist/core/merge.mjs +11 -0
- package/dist/core/normalise.d.mts +9 -3
- package/dist/core/normalise.mjs +1 -1
- package/dist/core/openapi30.d.mts +24 -1
- package/dist/core/openapi30.mjs +2 -2
- package/dist/core/ref.d.mts +1 -1
- package/dist/core/ref.mjs +34 -9
- package/dist/core/renderer.d.mts +1 -1
- package/dist/core/swagger2.d.mts +1 -1
- package/dist/core/swagger2.mjs +1 -1
- package/dist/core/typeInference.d.mts +2 -2
- package/dist/core/types.d.mts +1 -1
- package/dist/core/uri.d.mts +41 -0
- package/dist/core/uri.mjs +76 -0
- package/dist/core/version.d.mts +2 -2
- package/dist/core/version.mjs +25 -1
- package/dist/core/walkBuilders.d.mts +13 -5
- package/dist/core/walkBuilders.mjs +11 -3
- package/dist/core/walker.d.mts +1 -1
- package/dist/core/walker.mjs +80 -26
- package/dist/{diagnostics-VgEKI_Ct.d.mts → diagnostics-CbBPsxSt.d.mts} +1 -1
- package/dist/{errors-CnGjT1cg.d.mts → errors-QEwOtQAA.d.mts} +8 -5
- package/dist/html/a11y.d.mts +2 -2
- package/dist/html/renderToHtml.d.mts +2 -2
- package/dist/html/renderToHtmlStream.d.mts +2 -2
- package/dist/html/renderers.d.mts +2 -2
- package/dist/html/renderers.mjs +9 -2
- package/dist/html/streamRenderers.d.mts +2 -2
- package/dist/{normalise-C0ofw3W6.mjs → normalise-DaSrnr8g.mjs} +574 -40
- package/dist/openapi/ApiCallbacks.d.mts +1 -1
- package/dist/openapi/ApiLinks.d.mts +1 -1
- package/dist/openapi/ApiResponseHeaders.d.mts +1 -1
- package/dist/openapi/ApiSecurity.d.mts +1 -1
- package/dist/openapi/ApiSecurity.mjs +113 -7
- package/dist/openapi/bundle.mjs +2 -0
- package/dist/openapi/components.d.mts +32 -10
- package/dist/openapi/components.mjs +37 -16
- package/dist/openapi/parser.d.mts +1 -1
- package/dist/openapi/parser.mjs +41 -4
- package/dist/openapi/resolve.d.mts +70 -9
- package/dist/openapi/resolve.mjs +124 -24
- package/dist/react/SchemaComponent.d.mts +21 -9
- package/dist/react/SchemaComponent.mjs +32 -4
- package/dist/react/SchemaView.d.mts +3 -3
- package/dist/react/fieldPath.d.mts +1 -1
- package/dist/react/headless.d.mts +1 -1
- package/dist/react/headlessRenderers.d.mts +2 -2
- package/dist/react/headlessRenderers.mjs +18 -6
- package/dist/{ref-Bb43ZURY.d.mts → ref-si8ViYun.d.mts} +7 -2
- package/dist/{renderer-BQqiXUYP.d.mts → renderer-DI6ZYf7a.d.mts} +1 -1
- package/dist/themes/mantine.d.mts +1 -1
- package/dist/themes/mui.d.mts +1 -1
- package/dist/themes/radix.d.mts +1 -1
- package/dist/themes/shadcn.d.mts +1 -1
- package/dist/typeInference-Bxw3NOG1.d.mts +647 -0
- package/dist/{types-D_5ST7SS.d.mts → types-BnxPEElk.d.mts} +18 -2
- package/dist/{version-XNH7PRGP.d.mts → version-D-u7aMfy.d.mts} +36 -1
- package/package.json +1 -1
- package/dist/typeInference-5JiqIZ8t.d.mts +0 -388
package/dist/core/adapter.d.mts
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
|
-
import { T as SchemaMeta, m as JsonObject } from "../types-
|
|
2
|
-
import { i as DiagnosticsOptions } from "../diagnostics-
|
|
1
|
+
import { T as SchemaMeta, m as JsonObject } from "../types-BnxPEElk.mjs";
|
|
2
|
+
import { i as DiagnosticsOptions } from "../diagnostics-CbBPsxSt.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/core/adapter.d.ts
|
|
5
5
|
type SchemaInput = Record<string, unknown>;
|
|
6
6
|
type SchemaKind = "zod4" | "zod3" | "jsonSchema" | "openapi";
|
|
7
7
|
declare function detectSchemaKind(input: unknown): SchemaKind;
|
|
8
|
+
/**
|
|
9
|
+
* Exposed for unit testing — lets the contract test enumerate every rule's
|
|
10
|
+
* `prefix` value and assert mutual non-prefixing.
|
|
11
|
+
*/
|
|
12
|
+
declare const __CLASSIFIER_RULES_FOR_TEST: readonly {
|
|
13
|
+
readonly prefix: string;
|
|
14
|
+
}[];
|
|
8
15
|
interface NormalisedSchema {
|
|
9
16
|
/** JSON Schema object — the authoritative schema for rendering. */
|
|
10
17
|
jsonSchema: JsonObject;
|
|
@@ -21,4 +28,4 @@ interface NormaliseOptions {
|
|
|
21
28
|
}
|
|
22
29
|
declare function normaliseSchema(input: unknown, ref?: string, options?: NormaliseOptions): NormalisedSchema;
|
|
23
30
|
//#endregion
|
|
24
|
-
export { type JsonObject, NormaliseOptions, NormalisedSchema, SchemaInput, SchemaKind, type SchemaMeta, detectSchemaKind, normaliseSchema };
|
|
31
|
+
export { type JsonObject, NormaliseOptions, NormalisedSchema, SchemaInput, SchemaKind, type SchemaMeta, __CLASSIFIER_RULES_FOR_TEST, detectSchemaKind, normaliseSchema };
|
package/dist/core/adapter.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { SchemaNormalisationError } from "./errors.mjs";
|
|
|
3
3
|
import { emitDiagnostic } from "./diagnostics.mjs";
|
|
4
4
|
import { dereference } from "./ref.mjs";
|
|
5
5
|
import { detectOpenApiVersion, inferJsonSchemaDraftWithReason, isSwagger2, matchJsonSchemaDraftUri } from "./version.mjs";
|
|
6
|
-
import { a as normaliseOpenApiSchemas, i as normaliseJsonSchema$1 } from "../normalise-
|
|
6
|
+
import { a as normaliseOpenApiSchemas, i as normaliseJsonSchema$1 } from "../normalise-DaSrnr8g.mjs";
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
//#region src/core/adapter.ts
|
|
9
9
|
/**
|
|
@@ -36,12 +36,36 @@ function detectSchemaKind(input) {
|
|
|
36
36
|
* SchemaNormalisationError so the caller does not have to re-parse error
|
|
37
37
|
* message strings. The classification covers:
|
|
38
38
|
*
|
|
39
|
-
* - Nested Zod 3 schemas inside a Zod 4 tree
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* -
|
|
39
|
+
* - Nested Zod 3 schemas inside a Zod 4 tree → zod3-unsupported.
|
|
40
|
+
* Detected structurally (presence of `_def.typeName` markers anywhere
|
|
41
|
+
* in the schema tree) so the check works across V8, JavaScriptCore,
|
|
42
|
+
* and SpiderMonkey, none of which agree on the wording of
|
|
43
|
+
* "Cannot read properties of undefined".
|
|
44
|
+
* - Transforms → zod-transform-unsupported. This also catches `z.codec(…)`
|
|
45
|
+
* because Zod implements codecs as a pipe + transform internally, so
|
|
46
|
+
* they trip the same processor when round-tripping is forced. (Plain
|
|
47
|
+
* `z.toJSONSchema(codec)` itself does NOT throw because Zod picks one
|
|
48
|
+
* side of the codec; the static rejection in `typeInference.ts` is the
|
|
49
|
+
* compile-time guard.)
|
|
50
|
+
* - Dynamic catch values whose handler throws → zod-type-unrepresentable
|
|
51
|
+
* with zodType "dynamic-catch".
|
|
52
|
+
* - Unrepresentable types — bigint, date, map, set, symbol, function, custom,
|
|
53
|
+
* undefined, void, NaN, and the literal-only forms `z.literal(undefined)`
|
|
54
|
+
* ("undefined-literal") and `z.literal(<bigint>)` ("bigint-literal") →
|
|
55
|
+
* zod-type-unrepresentable.
|
|
56
|
+
* - The catch-all "Non-representable type encountered: <type>" fallback Zod
|
|
57
|
+
* emits for any new schema kind without a registered processor →
|
|
58
|
+
* zod-type-unrepresentable with zodType set to the offending def.type.
|
|
59
|
+
* - Cycle detected (`cycles: "throw"`) → zod-cycle-detected.
|
|
60
|
+
* - Duplicate schema id → zod-duplicate-id.
|
|
61
|
+
* - "Unprocessed schema. This is a bug in Zod." → zod-conversion-bug.
|
|
62
|
+
* - "Error converting schema to JSON." → zod-conversion-failed (explicit
|
|
63
|
+
* classification rather than the generic fallback so the contract test
|
|
64
|
+
* protects the prefix from drift).
|
|
65
|
+
* - Anything else → zod-conversion-failed.
|
|
66
|
+
*
|
|
67
|
+
* The original error is preserved on each classified error via the `cause`
|
|
68
|
+
* field so consumers can still inspect the Zod stack trace.
|
|
45
69
|
*/
|
|
46
70
|
function callToJsonSchema(schema) {
|
|
47
71
|
try {
|
|
@@ -51,36 +75,218 @@ function callToJsonSchema(schema) {
|
|
|
51
75
|
}
|
|
52
76
|
}
|
|
53
77
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
78
|
+
* Escape a string for inclusion in a `RegExp`. Required because Zod
|
|
79
|
+
* messages contain `[`, `]`, `.`, `(`, and `)` characters which have regex
|
|
80
|
+
* meaning. The set covers every character with special meaning in a
|
|
81
|
+
* JavaScript regular-expression source — RegExp.escape is not yet widely
|
|
82
|
+
* available so we escape manually.
|
|
83
|
+
*/
|
|
84
|
+
function escapeRegExp(literal) {
|
|
85
|
+
return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Compile a prefix into an anchored regex that captures any trailing text
|
|
89
|
+
* (used by rules that need to extract dynamic data such as the duplicate id
|
|
90
|
+
* or the def.type that tripped the non-representable fallback).
|
|
91
|
+
*/
|
|
92
|
+
function anchored(prefix) {
|
|
93
|
+
return new RegExp(`^${escapeRegExp(prefix)}(.*)$`, "s");
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Build the message body shared by every unrepresentable-type rule.
|
|
97
|
+
*/
|
|
98
|
+
function unrepresentableMessage(typeName, fullMessage) {
|
|
99
|
+
return `Zod type ${typeName} cannot be represented in JSON Schema and is not supported by schema-components. Original message: ${fullMessage}`;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Classifier rules ordered most-specific first. Order is load-bearing:
|
|
103
|
+
* `Literal \`undefined\` cannot be represented` must precede the broader
|
|
104
|
+
* `Undefined cannot be represented` so the literal classification wins
|
|
105
|
+
* even when both share a leading word. A consistency check in the unit
|
|
106
|
+
* test suite asserts no two `prefix` values are prefixes of each other —
|
|
107
|
+
* any future rule that breaks the invariant fails the build.
|
|
57
108
|
*
|
|
58
|
-
*
|
|
109
|
+
* Verbatim sources (kept aligned with `tests/zod-error-wording-contract.unit.test.ts`):
|
|
110
|
+
* - zod/src/v4/core/json-schema-processors.ts L104 (bigint), L110 (symbol),
|
|
111
|
+
* L126 (undefined), L132 (void), L150 (date), L169 (literal-undefined),
|
|
112
|
+
* L175 (literal-bigint), L204 (NaN), L246 (custom), L252 (function),
|
|
113
|
+
* L258 (transforms), L264 (map), L270 (set), L521 (dynamic catch).
|
|
114
|
+
* - zod/src/v4/core/to-json-schema.ts L182 (non-representable type fallback),
|
|
115
|
+
* L225 + L364 (unprocessed schema), L235 (duplicate id), L307 (cycle),
|
|
116
|
+
* L522 (error converting).
|
|
59
117
|
*/
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
118
|
+
const CLASSIFIER_RULES = [
|
|
119
|
+
{
|
|
120
|
+
prefix: "Literal `undefined` cannot be represented",
|
|
121
|
+
kind: "zod-type-unrepresentable",
|
|
122
|
+
zodType: "undefined-literal",
|
|
123
|
+
build: (_m, cause, schema, full) => new SchemaNormalisationError(unrepresentableMessage("undefined-literal", full), schema, "zod-type-unrepresentable", "undefined-literal", cause)
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
prefix: "BigInt literals cannot be represented",
|
|
127
|
+
kind: "zod-type-unrepresentable",
|
|
128
|
+
zodType: "bigint-literal",
|
|
129
|
+
build: (_m, cause, schema, full) => new SchemaNormalisationError(unrepresentableMessage("bigint-literal", full), schema, "zod-type-unrepresentable", "bigint-literal", cause)
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
prefix: "BigInt cannot be represented",
|
|
133
|
+
kind: "zod-type-unrepresentable",
|
|
134
|
+
zodType: "bigint",
|
|
135
|
+
build: (_m, cause, schema, full) => new SchemaNormalisationError(unrepresentableMessage("bigint", full), schema, "zod-type-unrepresentable", "bigint", cause)
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
prefix: "Date cannot be represented",
|
|
139
|
+
kind: "zod-type-unrepresentable",
|
|
140
|
+
zodType: "date",
|
|
141
|
+
build: (_m, cause, schema, full) => new SchemaNormalisationError(unrepresentableMessage("date", full), schema, "zod-type-unrepresentable", "date", cause)
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
prefix: "Map cannot be represented",
|
|
145
|
+
kind: "zod-type-unrepresentable",
|
|
146
|
+
zodType: "map",
|
|
147
|
+
build: (_m, cause, schema, full) => new SchemaNormalisationError(unrepresentableMessage("map", full), schema, "zod-type-unrepresentable", "map", cause)
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
prefix: "Set cannot be represented",
|
|
151
|
+
kind: "zod-type-unrepresentable",
|
|
152
|
+
zodType: "set",
|
|
153
|
+
build: (_m, cause, schema, full) => new SchemaNormalisationError(unrepresentableMessage("set", full), schema, "zod-type-unrepresentable", "set", cause)
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
prefix: "Symbols cannot be represented",
|
|
157
|
+
kind: "zod-type-unrepresentable",
|
|
158
|
+
zodType: "symbol",
|
|
159
|
+
build: (_m, cause, schema, full) => new SchemaNormalisationError(unrepresentableMessage("symbol", full), schema, "zod-type-unrepresentable", "symbol", cause)
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
prefix: "Function types cannot be represented",
|
|
163
|
+
kind: "zod-type-unrepresentable",
|
|
164
|
+
zodType: "function",
|
|
165
|
+
build: (_m, cause, schema, full) => new SchemaNormalisationError(unrepresentableMessage("function", full), schema, "zod-type-unrepresentable", "function", cause)
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
prefix: "Custom types cannot be represented",
|
|
169
|
+
kind: "zod-type-unrepresentable",
|
|
170
|
+
zodType: "custom",
|
|
171
|
+
build: (_m, cause, schema, full) => new SchemaNormalisationError(unrepresentableMessage("custom", full), schema, "zod-type-unrepresentable", "custom", cause)
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
prefix: "Undefined cannot be represented",
|
|
175
|
+
kind: "zod-type-unrepresentable",
|
|
176
|
+
zodType: "undefined",
|
|
177
|
+
build: (_m, cause, schema, full) => new SchemaNormalisationError(unrepresentableMessage("undefined", full), schema, "zod-type-unrepresentable", "undefined", cause)
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
prefix: "Void cannot be represented",
|
|
181
|
+
kind: "zod-type-unrepresentable",
|
|
182
|
+
zodType: "void",
|
|
183
|
+
build: (_m, cause, schema, full) => new SchemaNormalisationError(unrepresentableMessage("void", full), schema, "zod-type-unrepresentable", "void", cause)
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
prefix: "NaN cannot be represented",
|
|
187
|
+
kind: "zod-type-unrepresentable",
|
|
188
|
+
zodType: "nan",
|
|
189
|
+
build: (_m, cause, schema, full) => new SchemaNormalisationError(unrepresentableMessage("nan", full), schema, "zod-type-unrepresentable", "nan", cause)
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
prefix: "Transforms cannot be represented",
|
|
193
|
+
kind: "zod-transform-unsupported",
|
|
194
|
+
build: (_m, cause, schema) => new SchemaNormalisationError("Zod transforms cannot be represented in JSON Schema. Remove the .transform() call, or pre-transform the input before passing it to the component. (Note: z.codec(...) is implemented as a transform internally — codecs that force round-tripping trip this same rule.)", schema, "zod-transform-unsupported", void 0, cause)
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
prefix: "Dynamic catch values are not supported",
|
|
198
|
+
kind: "zod-type-unrepresentable",
|
|
199
|
+
zodType: "dynamic-catch",
|
|
200
|
+
build: (_m, cause, schema) => new SchemaNormalisationError("Zod catch values that depend on runtime computation cannot be represented in JSON Schema. Provide a static catch value or remove the .catch() call.", schema, "zod-type-unrepresentable", "dynamic-catch", cause)
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
prefix: "[toJSONSchema]: Non-representable type encountered:",
|
|
204
|
+
kind: "zod-type-unrepresentable",
|
|
205
|
+
build: (match, cause, schema, full) => {
|
|
206
|
+
const trailing = match[1]?.trim() ?? "";
|
|
207
|
+
const typeName = trailing.length > 0 ? trailing.split(/\s+/)[0] : void 0;
|
|
208
|
+
return new SchemaNormalisationError(`Zod encountered a schema kind${typeName !== void 0 ? ` "${typeName}"` : ""} with no JSON Schema processor registered. This usually means Zod added a new schema type that schema-components does not yet support. Original message: ${full}`, schema, "zod-type-unrepresentable", typeName, cause);
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
prefix: "Cycle detected: ",
|
|
213
|
+
kind: "zod-cycle-detected",
|
|
214
|
+
build: (match, cause, schema, full) => {
|
|
215
|
+
return new SchemaNormalisationError(`Zod detected a cycle in the schema graph at ${(match[1] ?? "").split(/\s+/)[0] ?? ""}. Cycles can only be converted when z.toJSONSchema is called with { cycles: "ref" } — schema-components calls it without options for cache safety, so the cycle surfaces as an error. Restructure the schema to break the cycle, or use a $ref-based definition. Original message: ${full}`, schema, "zod-cycle-detected", void 0, cause);
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
prefix: "Duplicate schema id \"",
|
|
220
|
+
kind: "zod-duplicate-id",
|
|
221
|
+
build: (match, cause, schema, full) => {
|
|
222
|
+
const trailing = match[1] ?? "";
|
|
223
|
+
const closing = trailing.indexOf("\"");
|
|
224
|
+
return new SchemaNormalisationError(`Two different Zod schemas share the same id "${closing === -1 ? trailing : trailing.slice(0, closing)}". JSON Schema requires distinct ids when multiple schemas are bundled together. Give each schema its own .meta({ id: ... }) or remove the duplicate. Original message: ${full}`, schema, "zod-duplicate-id", void 0, cause);
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
prefix: "Unprocessed schema. This is a bug in Zod.",
|
|
229
|
+
kind: "zod-conversion-bug",
|
|
230
|
+
build: (_m, cause, schema, full) => new SchemaNormalisationError(`Zod failed to process this schema during JSON Schema conversion and reports it as an internal bug. File an issue on the Zod tracker with a reproduction. Original message: ${full}`, schema, "zod-conversion-bug", void 0, cause)
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
prefix: "Error converting schema to JSON.",
|
|
234
|
+
kind: "zod-conversion-failed",
|
|
235
|
+
build: (_m, cause, schema, full) => new SchemaNormalisationError(`z.toJSONSchema() failed to produce a Standard Schema payload. Inspect the underlying cause for the original error. Original message: ${full}`, schema, "zod-conversion-failed", void 0, cause)
|
|
236
|
+
}
|
|
70
237
|
];
|
|
71
238
|
/**
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
|
|
239
|
+
* Compiled regex form of {@link CLASSIFIER_RULES} — built once at module
|
|
240
|
+
* load. Avoids per-error compilation.
|
|
241
|
+
*/
|
|
242
|
+
const COMPILED_CLASSIFIER_RULES = CLASSIFIER_RULES.map((rule) => ({
|
|
243
|
+
rule,
|
|
244
|
+
pattern: anchored(rule.prefix)
|
|
245
|
+
}));
|
|
246
|
+
/**
|
|
247
|
+
* Walk an arbitrary value looking for Zod 3 markers (`_def.typeName`).
|
|
248
|
+
* Zod 4 schemas always carry a `_zod.def`; Zod 3 schemas carry `_def`
|
|
249
|
+
* with a `typeName` field. Presence of the latter anywhere in the tree
|
|
250
|
+
* means a Zod 3 schema was nested inside a Zod 4 input, which is what
|
|
251
|
+
* trips the V8 `"Cannot read properties of undefined"` failure.
|
|
252
|
+
*
|
|
253
|
+
* Engine-agnostic by construction — the detector inspects schema shape
|
|
254
|
+
* instead of pattern-matching against the runtime's TypeError message,
|
|
255
|
+
* so it works equivalently under V8, JavaScriptCore (Bun/Safari), and
|
|
256
|
+
* SpiderMonkey (Firefox) — none of which agree on the wording.
|
|
257
|
+
*
|
|
258
|
+
* The walk is bounded by an explicit `visited` set so cyclical references
|
|
259
|
+
* cannot cause stack overflow. The recursion follows both array elements
|
|
260
|
+
* and own enumerable properties of every object encountered.
|
|
75
261
|
*/
|
|
76
|
-
|
|
262
|
+
function containsNestedZod3(value, visited) {
|
|
263
|
+
if (value === null || typeof value !== "object") return false;
|
|
264
|
+
if (visited.has(value)) return false;
|
|
265
|
+
visited.add(value);
|
|
266
|
+
if (Array.isArray(value)) {
|
|
267
|
+
for (const item of value) if (containsNestedZod3(item, visited)) return true;
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
if (!isObject(value)) return false;
|
|
271
|
+
const def = value._def;
|
|
272
|
+
if (value._zod === void 0 && isObject(def) && typeof def.typeName === "string") return true;
|
|
273
|
+
for (const key of Object.keys(value)) if (containsNestedZod3(value[key], visited)) return true;
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
77
276
|
function classifyZodConversionError(err, schema) {
|
|
78
277
|
const message = err instanceof Error ? err.message : String(err);
|
|
79
|
-
if (
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
278
|
+
if (containsNestedZod3(schema, /* @__PURE__ */ new Set())) return new SchemaNormalisationError("A nested Zod 3 schema was found inside a Zod 4 schema. schema-components requires Zod 4 throughout the schema tree. See the Zod 4 migration guide at https://zod.dev/v4/migration or run: pnpm add zod@^4", schema, "zod3-unsupported", void 0, err);
|
|
279
|
+
for (const { rule, pattern } of COMPILED_CLASSIFIER_RULES) {
|
|
280
|
+
const match = pattern.exec(message);
|
|
281
|
+
if (match !== null) return rule.build(match, err, schema, message);
|
|
282
|
+
}
|
|
283
|
+
return new SchemaNormalisationError(`z.toJSONSchema() failed: ${message}`, schema, "zod-conversion-failed", void 0, err);
|
|
83
284
|
}
|
|
285
|
+
/**
|
|
286
|
+
* Exposed for unit testing — lets the contract test enumerate every rule's
|
|
287
|
+
* `prefix` value and assert mutual non-prefixing.
|
|
288
|
+
*/
|
|
289
|
+
const __CLASSIFIER_RULES_FOR_TEST = CLASSIFIER_RULES;
|
|
84
290
|
function normaliseSchema(input, ref, options) {
|
|
85
291
|
if (ref === void 0 && isObject(input)) {
|
|
86
292
|
const cached = schemaCache.get(input);
|
|
@@ -206,7 +412,7 @@ function resolveOpenApiRef(doc, ref) {
|
|
|
206
412
|
if (!isObject(resolved)) throw new Error(`OpenAPI ref not found: ${ref}`);
|
|
207
413
|
return resolved;
|
|
208
414
|
}
|
|
209
|
-
const pathMatch = /^\/(.+)\/(get|post|put|patch|delete)$/.exec(ref);
|
|
415
|
+
const pathMatch = /^\/(.+)\/(get|post|put|patch|delete|head|options|trace)$/.exec(ref);
|
|
210
416
|
if (pathMatch?.[1] !== void 0 && pathMatch[2] !== void 0) {
|
|
211
417
|
const pathStr = pathMatch[1];
|
|
212
418
|
const method = pathMatch[2];
|
|
@@ -244,4 +450,4 @@ function extractRootMetaFromJson(jsonSchema) {
|
|
|
244
450
|
return Object.keys(meta).length > 0 ? meta : void 0;
|
|
245
451
|
}
|
|
246
452
|
//#endregion
|
|
247
|
-
export { detectSchemaKind, normaliseSchema };
|
|
453
|
+
export { __CLASSIFIER_RULES_FOR_TEST, detectSchemaKind, normaliseSchema };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { D as StringConstraints, f as FileConstraints, t as ArrayConstraints, x as ObjectConstraints, y as NumberConstraints } from "../types-
|
|
2
|
-
import { i as DiagnosticsOptions } from "../diagnostics-
|
|
1
|
+
import { D as StringConstraints, f as FileConstraints, t as ArrayConstraints, x as ObjectConstraints, y as NumberConstraints } from "../types-BnxPEElk.mjs";
|
|
2
|
+
import { i as DiagnosticsOptions } from "../diagnostics-CbBPsxSt.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/core/constraints.d.ts
|
|
5
5
|
declare function extractStringConstraints(schema: Record<string, unknown>, diagnostics?: DiagnosticsOptions, pointer?: string): StringConstraints;
|
|
@@ -61,8 +61,6 @@ function extractArrayConstraints(schema) {
|
|
|
61
61
|
const maxItems = getNumber(schema, "maxItems");
|
|
62
62
|
if (maxItems !== void 0) c.maxItems = maxItems;
|
|
63
63
|
if (schema.uniqueItems === true) c.uniqueItems = true;
|
|
64
|
-
const contains = getObject(schema, "contains");
|
|
65
|
-
if (contains !== void 0) c.contains = contains;
|
|
66
64
|
const minContains = getNumber(schema, "minContains");
|
|
67
65
|
if (minContains !== void 0) c.minContains = minContains;
|
|
68
66
|
const maxContains = getNumber(schema, "maxContains");
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as appendPointer, i as DiagnosticsOptions, n as DiagnosticCode, o as emitDiagnostic, r as DiagnosticSink, t as Diagnostic } from "../diagnostics-
|
|
1
|
+
import { a as appendPointer, i as DiagnosticsOptions, n as DiagnosticCode, o as emitDiagnostic, r as DiagnosticSink, t as Diagnostic } from "../diagnostics-CbBPsxSt.mjs";
|
|
2
2
|
export { Diagnostic, DiagnosticCode, DiagnosticSink, DiagnosticsOptions, appendPointer, emitDiagnostic };
|
package/dist/core/errors.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as SchemaRenderError, n as SchemaFieldError, r as SchemaNormalisationError, t as SchemaError } from "../errors-
|
|
1
|
+
import { i as SchemaRenderError, n as SchemaFieldError, r as SchemaNormalisationError, t as SchemaError } from "../errors-QEwOtQAA.mjs";
|
|
2
2
|
export { SchemaError, SchemaFieldError, SchemaNormalisationError, SchemaRenderError };
|
package/dist/core/errors.mjs
CHANGED
|
@@ -14,12 +14,17 @@
|
|
|
14
14
|
/**
|
|
15
15
|
* Base class for all schema-components errors.
|
|
16
16
|
* Catch this to handle any library error uniformly.
|
|
17
|
+
*
|
|
18
|
+
* Forwards the optional `cause` to the native ES2022 `Error` constructor so
|
|
19
|
+
* `error.cause` is wired up by the runtime and rendered correctly by
|
|
20
|
+
* `util.inspect` ("Caused by: ..."). Subclasses that need a typed `cause`
|
|
21
|
+
* field still get it via the platform's own `Error.cause` getter.
|
|
17
22
|
*/
|
|
18
23
|
var SchemaError = class extends Error {
|
|
19
24
|
/** The schema input that caused the error. */
|
|
20
25
|
schema;
|
|
21
|
-
constructor(message, schema) {
|
|
22
|
-
super(message);
|
|
26
|
+
constructor(message, schema, cause) {
|
|
27
|
+
super(message, cause !== void 0 ? { cause } : void 0);
|
|
23
28
|
this.name = "SchemaError";
|
|
24
29
|
this.schema = schema;
|
|
25
30
|
}
|
|
@@ -37,8 +42,8 @@ var SchemaNormalisationError = class extends SchemaError {
|
|
|
37
42
|
* (e.g. "bigint", "date", "map", "set"). `undefined` for other kinds.
|
|
38
43
|
*/
|
|
39
44
|
zodType;
|
|
40
|
-
constructor(message, schema, kind, zodType) {
|
|
41
|
-
super(message, schema);
|
|
45
|
+
constructor(message, schema, kind, zodType, cause) {
|
|
46
|
+
super(message, schema, cause);
|
|
42
47
|
this.name = "SchemaNormalisationError";
|
|
43
48
|
this.kind = kind;
|
|
44
49
|
this.zodType = zodType;
|
|
@@ -52,13 +57,10 @@ var SchemaNormalisationError = class extends SchemaError {
|
|
|
52
57
|
var SchemaRenderError = class extends SchemaError {
|
|
53
58
|
/** The schema type being rendered when the error occurred. */
|
|
54
59
|
schemaType;
|
|
55
|
-
/** The original error from the render function. */
|
|
56
|
-
cause;
|
|
57
60
|
constructor(message, schema, schemaType, cause) {
|
|
58
|
-
super(message, schema);
|
|
61
|
+
super(message, schema, cause);
|
|
59
62
|
this.name = "SchemaRenderError";
|
|
60
63
|
this.schemaType = schemaType;
|
|
61
|
-
this.cause = cause;
|
|
62
64
|
}
|
|
63
65
|
};
|
|
64
66
|
/**
|
package/dist/core/formats.d.mts
CHANGED
|
@@ -1,18 +1,14 @@
|
|
|
1
|
+
import { i as DiagnosticsOptions } from "../diagnostics-CbBPsxSt.mjs";
|
|
2
|
+
|
|
1
3
|
//#region src/core/formats.d.ts
|
|
2
4
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* `validate` helper for runtime format checking.
|
|
9
|
-
*
|
|
10
|
-
* Formats that cannot be validated by regex (iri, regex) use predicate
|
|
11
|
-
* functions instead. `validateFormat` dispatches to whichever is available.
|
|
12
|
-
*
|
|
13
|
-
* The user's explicit `pattern` constraint always takes precedence —
|
|
14
|
-
* `formatPattern` is exposed as a separate field for renderers.
|
|
5
|
+
* Maximum length of a string that will be compiled by `new RegExp(...)`.
|
|
6
|
+
* Patterns that exceed this cap are rejected without compilation. A
|
|
7
|
+
* pathological pattern (e.g. `(a+)+`) doesn't need to be long to hang,
|
|
8
|
+
* but the cap is cheap defence and stops obviously hostile input before
|
|
9
|
+
* it reaches the regex engine.
|
|
15
10
|
*/
|
|
11
|
+
declare const MAX_REGEX_PATTERN_LENGTH = 500;
|
|
16
12
|
/**
|
|
17
13
|
* A format validator: either a RegExp pattern or a predicate function.
|
|
18
14
|
*/
|
|
@@ -21,13 +17,24 @@ type FormatValidator = RegExp | ((value: string) => boolean);
|
|
|
21
17
|
* Recognised JSON Schema formats with their validation patterns.
|
|
22
18
|
* Unknown formats emit an `unknown-format` diagnostic and skip derivation.
|
|
23
19
|
*/
|
|
20
|
+
/**
|
|
21
|
+
* Email format pattern, exported as a named const so callers that need a
|
|
22
|
+
* guaranteed `RegExp` (rather than the `RegExp | undefined` shape of
|
|
23
|
+
* `FORMAT_PATTERNS[name]` under `noUncheckedIndexedAccess`) can import it
|
|
24
|
+
* directly. Used by the URI safety helpers for mailto address checks.
|
|
25
|
+
*/
|
|
26
|
+
declare const EMAIL_FORMAT_PATTERN: RegExp;
|
|
24
27
|
declare const FORMAT_PATTERNS: Readonly<Record<string, RegExp>>;
|
|
25
28
|
/**
|
|
26
29
|
* Validate a string value against format constraints.
|
|
27
30
|
* Returns `true` when the value matches the format,
|
|
28
31
|
* `false` when it does not, and `undefined` when the format
|
|
29
32
|
* is not recognised (no validator available).
|
|
33
|
+
*
|
|
34
|
+
* `diagnostics` and `pointer` are forwarded to validators that can
|
|
35
|
+
* surface structured diagnostics — currently the `regex` format, which
|
|
36
|
+
* emits `pattern-invalid` for over-length or malformed input.
|
|
30
37
|
*/
|
|
31
|
-
declare function validateFormat(value: string, format: string): boolean | undefined;
|
|
38
|
+
declare function validateFormat(value: string, format: string, diagnostics?: DiagnosticsOptions, pointer?: string): boolean | undefined;
|
|
32
39
|
//#endregion
|
|
33
|
-
export { FORMAT_PATTERNS, FormatValidator, validateFormat };
|
|
40
|
+
export { EMAIL_FORMAT_PATTERN, FORMAT_PATTERNS, FormatValidator, MAX_REGEX_PATTERN_LENGTH, validateFormat };
|
package/dist/core/formats.mjs
CHANGED
|
@@ -1,11 +1,27 @@
|
|
|
1
|
+
import { emitDiagnostic } from "./diagnostics.mjs";
|
|
1
2
|
//#region src/core/formats.ts
|
|
2
3
|
/**
|
|
4
|
+
* Maximum length of a string that will be compiled by `new RegExp(...)`.
|
|
5
|
+
* Patterns that exceed this cap are rejected without compilation. A
|
|
6
|
+
* pathological pattern (e.g. `(a+)+`) doesn't need to be long to hang,
|
|
7
|
+
* but the cap is cheap defence and stops obviously hostile input before
|
|
8
|
+
* it reaches the regex engine.
|
|
9
|
+
*/
|
|
10
|
+
const MAX_REGEX_PATTERN_LENGTH = 500;
|
|
11
|
+
/**
|
|
3
12
|
* Recognised JSON Schema formats with their validation patterns.
|
|
4
13
|
* Unknown formats emit an `unknown-format` diagnostic and skip derivation.
|
|
5
14
|
*/
|
|
15
|
+
/**
|
|
16
|
+
* Email format pattern, exported as a named const so callers that need a
|
|
17
|
+
* guaranteed `RegExp` (rather than the `RegExp | undefined` shape of
|
|
18
|
+
* `FORMAT_PATTERNS[name]` under `noUncheckedIndexedAccess`) can import it
|
|
19
|
+
* directly. Used by the URI safety helpers for mailto address checks.
|
|
20
|
+
*/
|
|
21
|
+
const EMAIL_FORMAT_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
6
22
|
const FORMAT_PATTERNS = {
|
|
7
23
|
uuid: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,
|
|
8
|
-
email:
|
|
24
|
+
email: EMAIL_FORMAT_PATTERN,
|
|
9
25
|
"date-time": /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/,
|
|
10
26
|
date: /^\d{4}-\d{2}-\d{2}$/,
|
|
11
27
|
time: /^\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})?$/,
|
|
@@ -27,11 +43,22 @@ const FORMAT_PATTERNS = {
|
|
|
27
43
|
cidrv6: /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,
|
|
28
44
|
base64: /^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/,
|
|
29
45
|
base64url: /^[A-Za-z0-9_-]*$/,
|
|
30
|
-
e164: /^\+[1-9]\d{6,14}
|
|
46
|
+
e164: /^\+[1-9]\d{6,14}$/,
|
|
47
|
+
emoji: /^(\p{Extended_Pictographic}|\p{Emoji_Component})+$/u,
|
|
48
|
+
ulid: /^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/,
|
|
49
|
+
xid: /^[0-9a-vA-V]{20}$/,
|
|
50
|
+
ksuid: /^[A-Za-z0-9]{27}$/,
|
|
51
|
+
lowercase: /^[^A-Z]*$/,
|
|
52
|
+
uppercase: /^[^a-z]*$/,
|
|
53
|
+
jwt: /^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]*$/
|
|
31
54
|
};
|
|
32
55
|
/**
|
|
33
56
|
* Format validators that use predicate functions instead of regex.
|
|
34
57
|
* These are checked in `validateFormat` when no regex pattern exists.
|
|
58
|
+
*
|
|
59
|
+
* The `regex` format is intentionally absent here — it requires a
|
|
60
|
+
* length cap and structured diagnostic emission and is handled via
|
|
61
|
+
* {@link validateRegexFormat} directly from {@link validateFormat}.
|
|
35
62
|
*/
|
|
36
63
|
const PREDICATE_VALIDATORS = {
|
|
37
64
|
iri: (value) => {
|
|
@@ -57,19 +84,76 @@ const PREDICATE_VALIDATORS = {
|
|
|
57
84
|
} catch {
|
|
58
85
|
return false;
|
|
59
86
|
}
|
|
87
|
+
},
|
|
88
|
+
"json-string": (value) => {
|
|
89
|
+
try {
|
|
90
|
+
JSON.parse(value);
|
|
91
|
+
return true;
|
|
92
|
+
} catch {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
60
95
|
}
|
|
61
96
|
};
|
|
62
97
|
/**
|
|
98
|
+
* Validate that a string is a syntactically valid regular expression.
|
|
99
|
+
*
|
|
100
|
+
* Hardened against ReDoS-style abuse:
|
|
101
|
+
* - Values longer than {@link MAX_REGEX_PATTERN_LENGTH} are treated as
|
|
102
|
+
* "format unmatched" without ever being compiled.
|
|
103
|
+
* - Any `SyntaxError` thrown by `new RegExp(...)` (malformed pattern,
|
|
104
|
+
* invalid flags, unbalanced groups) is caught and treated as "format
|
|
105
|
+
* unmatched".
|
|
106
|
+
*
|
|
107
|
+
* In both cases a diagnostic is emitted when a sink is supplied so
|
|
108
|
+
* callers can surface the offending value to the schema author.
|
|
109
|
+
*/
|
|
110
|
+
function validateRegexFormat(value, diagnostics, pointer) {
|
|
111
|
+
if (value.length > 500) {
|
|
112
|
+
emitDiagnostic(diagnostics, {
|
|
113
|
+
code: "pattern-invalid",
|
|
114
|
+
message: `Pattern length (${String(value.length)}) exceeds maximum (${String(500)}); treating as unmatched`,
|
|
115
|
+
pointer,
|
|
116
|
+
detail: {
|
|
117
|
+
reason: "length-exceeded",
|
|
118
|
+
length: value.length,
|
|
119
|
+
maxLength: 500
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
new RegExp(value);
|
|
126
|
+
return true;
|
|
127
|
+
} catch (error) {
|
|
128
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
129
|
+
emitDiagnostic(diagnostics, {
|
|
130
|
+
code: "pattern-invalid",
|
|
131
|
+
message: `Failed to compile pattern as RegExp: ${message}; treating as unmatched`,
|
|
132
|
+
pointer,
|
|
133
|
+
detail: {
|
|
134
|
+
reason: "compile-error",
|
|
135
|
+
error: message
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
63
142
|
* Validate a string value against format constraints.
|
|
64
143
|
* Returns `true` when the value matches the format,
|
|
65
144
|
* `false` when it does not, and `undefined` when the format
|
|
66
145
|
* is not recognised (no validator available).
|
|
146
|
+
*
|
|
147
|
+
* `diagnostics` and `pointer` are forwarded to validators that can
|
|
148
|
+
* surface structured diagnostics — currently the `regex` format, which
|
|
149
|
+
* emits `pattern-invalid` for over-length or malformed input.
|
|
67
150
|
*/
|
|
68
|
-
function validateFormat(value, format) {
|
|
151
|
+
function validateFormat(value, format, diagnostics, pointer = "") {
|
|
69
152
|
const pattern = FORMAT_PATTERNS[format];
|
|
70
153
|
if (pattern !== void 0) return pattern.test(value);
|
|
154
|
+
if (format === "regex") return validateRegexFormat(value, diagnostics, pointer);
|
|
71
155
|
const predicate = PREDICATE_VALIDATORS[format];
|
|
72
156
|
if (predicate !== void 0) return predicate(value);
|
|
73
157
|
}
|
|
74
158
|
//#endregion
|
|
75
|
-
export { FORMAT_PATTERNS, validateFormat };
|
|
159
|
+
export { EMAIL_FORMAT_PATTERN, FORMAT_PATTERNS, MAX_REGEX_PATTERN_LENGTH, validateFormat };
|
package/dist/core/merge.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as DiagnosticsOptions } from "../diagnostics-
|
|
1
|
+
import { i as DiagnosticsOptions } from "../diagnostics-CbBPsxSt.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/core/merge.d.ts
|
|
4
4
|
/**
|
|
@@ -25,8 +25,17 @@ declare function mergeRefSiblings(referencer: Record<string, unknown>, resolvedM
|
|
|
25
25
|
* When a later branch redefines a keyword with a non-equal value the
|
|
26
26
|
* later value is silently dropped — an `allof-conflict` diagnostic is
|
|
27
27
|
* emitted so the loss is visible to consumers.
|
|
28
|
+
*
|
|
29
|
+
* Boolean branches (valid per Draft 06+) collapse the composite:
|
|
30
|
+
* - `false` makes the entire \`allOf\` unsatisfiable — return \`false\`,
|
|
31
|
+
* which the walker turns into a \`NeverField\`.
|
|
32
|
+
* - \`true\` is the always-valid schema and contributes no constraints —
|
|
33
|
+
* skip silently.
|
|
34
|
+
*
|
|
35
|
+
* Non-boolean, non-object entries (e.g. arrays, numbers) are malformed
|
|
36
|
+
* inputs that cannot represent a schema; skip them as before.
|
|
28
37
|
*/
|
|
29
|
-
declare function mergeAllOf(schemas: unknown[], diagnostics?: DiagnosticsOptions, pointer?: string): Record<string, unknown
|
|
38
|
+
declare function mergeAllOf(schemas: unknown[], diagnostics?: DiagnosticsOptions, pointer?: string): Record<string, unknown> | false;
|
|
30
39
|
interface NormalisedAnyOf {
|
|
31
40
|
inner: Record<string, unknown>;
|
|
32
41
|
isNullable: boolean;
|
package/dist/core/merge.mjs
CHANGED
|
@@ -109,12 +109,23 @@ function mergeRefSiblings(referencer, resolvedMeta) {
|
|
|
109
109
|
* When a later branch redefines a keyword with a non-equal value the
|
|
110
110
|
* later value is silently dropped — an `allof-conflict` diagnostic is
|
|
111
111
|
* emitted so the loss is visible to consumers.
|
|
112
|
+
*
|
|
113
|
+
* Boolean branches (valid per Draft 06+) collapse the composite:
|
|
114
|
+
* - `false` makes the entire \`allOf\` unsatisfiable — return \`false\`,
|
|
115
|
+
* which the walker turns into a \`NeverField\`.
|
|
116
|
+
* - \`true\` is the always-valid schema and contributes no constraints —
|
|
117
|
+
* skip silently.
|
|
118
|
+
*
|
|
119
|
+
* Non-boolean, non-object entries (e.g. arrays, numbers) are malformed
|
|
120
|
+
* inputs that cannot represent a schema; skip them as before.
|
|
112
121
|
*/
|
|
113
122
|
function mergeAllOf(schemas, diagnostics, pointer = "") {
|
|
114
123
|
const merged = {};
|
|
115
124
|
const properties = {};
|
|
116
125
|
const required = [];
|
|
117
126
|
for (const entry of schemas) {
|
|
127
|
+
if (entry === false) return false;
|
|
128
|
+
if (entry === true) continue;
|
|
118
129
|
if (!isObject(entry)) continue;
|
|
119
130
|
const props = getObject(entry, "properties");
|
|
120
131
|
if (props !== void 0) for (const [key, value] of Object.entries(props)) properties[key] = value;
|