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/openapi/resolve.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { isObject } from "../core/guards.mjs";
|
|
1
|
+
import { getProperty, isObject } from "../core/guards.mjs";
|
|
2
|
+
import { isPrototypePollutingKey } from "../core/uri.mjs";
|
|
2
3
|
import { detectOpenApiVersion } from "../core/version.mjs";
|
|
3
|
-
import { a as normaliseOpenApiSchemas } from "../normalise-
|
|
4
|
+
import { a as normaliseOpenApiSchemas } from "../normalise-DaSrnr8g.mjs";
|
|
4
5
|
import { getParameters, getRequestBody, getResponses, listOperations, parseOpenApiDocument } from "./parser.mjs";
|
|
5
6
|
//#region src/openapi/resolve.ts
|
|
6
7
|
/**
|
|
@@ -24,17 +25,30 @@ const docCache = /* @__PURE__ */ new WeakMap();
|
|
|
24
25
|
* same form `<SchemaComponent>` does, keeping the OpenAPI components on
|
|
25
26
|
* the same pipeline as the top-level adapter.
|
|
26
27
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
28
|
+
* When `diagnostics` is supplied, normalisation events
|
|
29
|
+
* (`duplicate-body-parameter`, `dropped-swagger-feature`,
|
|
30
|
+
* `unknown-json-schema-dialect`, `divisible-by-conflict`,
|
|
31
|
+
* `relative-ref-resolved`, etc.) are forwarded to the sink. Passing
|
|
32
|
+
* diagnostics also bypasses the cache so each call observes the
|
|
33
|
+
* normalisation pipeline running against the supplied sink — caching
|
|
34
|
+
* would silently swallow every emission after the first.
|
|
35
|
+
*
|
|
36
|
+
* The cache is keyed by the caller-supplied document so subsequent
|
|
37
|
+
* cache-eligible calls with the same input bypass both normalisation
|
|
38
|
+
* and parsing.
|
|
29
39
|
*/
|
|
30
|
-
function getParsed(doc) {
|
|
31
|
-
|
|
32
|
-
|
|
40
|
+
function getParsed(doc, diagnostics) {
|
|
41
|
+
if (diagnostics === void 0) {
|
|
42
|
+
const cached = docCache.get(doc);
|
|
43
|
+
if (cached !== void 0) return cached;
|
|
44
|
+
}
|
|
33
45
|
const version = detectOpenApiVersion(doc);
|
|
34
|
-
const normalisedDoc = version !== void 0 ? normaliseOpenApiSchemas(doc, version) : doc;
|
|
46
|
+
const normalisedDoc = version !== void 0 ? normaliseOpenApiSchemas(doc, version, diagnostics) : doc;
|
|
35
47
|
const parsed = parseOpenApiDocument(normalisedDoc);
|
|
36
|
-
|
|
37
|
-
|
|
48
|
+
if (diagnostics === void 0) {
|
|
49
|
+
docCache.set(doc, parsed);
|
|
50
|
+
if (normalisedDoc !== doc) docCache.set(normalisedDoc, parsed);
|
|
51
|
+
}
|
|
38
52
|
return parsed;
|
|
39
53
|
}
|
|
40
54
|
/**
|
|
@@ -45,45 +59,131 @@ function toDoc(value) {
|
|
|
45
59
|
return isObject(value) ? value : {};
|
|
46
60
|
}
|
|
47
61
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
62
|
+
* Look up a Path Item Object on the (already-normalised) parsed document,
|
|
63
|
+
* following a single `$ref` hop into `components/pathItems` (OpenAPI 3.1)
|
|
64
|
+
* if present. Returns `undefined` when the path is not present or the
|
|
65
|
+
* value is not an object.
|
|
66
|
+
*
|
|
67
|
+
* Implemented inside `resolve.ts` to avoid touching `parser.ts` while
|
|
68
|
+
* still surfacing path-item-level metadata to the React layer.
|
|
50
69
|
*/
|
|
51
|
-
function
|
|
52
|
-
|
|
70
|
+
function lookupPathItemNode(parsed, path) {
|
|
71
|
+
return resolvePathItemNode(parsed, getProperty(getProperty(parsed.doc, "paths"), path));
|
|
72
|
+
}
|
|
73
|
+
function resolvePathItemNode(parsed, pathItem) {
|
|
74
|
+
if (!isObject(pathItem)) return void 0;
|
|
75
|
+
const ref = getProperty(pathItem, "$ref");
|
|
76
|
+
if (typeof ref !== "string") return pathItem;
|
|
77
|
+
if (!ref.startsWith("#/")) return pathItem;
|
|
78
|
+
const parts = ref.slice(2).split("/");
|
|
79
|
+
let current = parsed.doc;
|
|
80
|
+
for (const part of parts) {
|
|
81
|
+
if (!isObject(current)) return void 0;
|
|
82
|
+
const decoded = part.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
83
|
+
if (isPrototypePollutingKey(decoded)) return void 0;
|
|
84
|
+
current = current[decoded];
|
|
85
|
+
}
|
|
86
|
+
return isObject(current) ? current : pathItem;
|
|
87
|
+
}
|
|
88
|
+
function extractPathItemInfo(pathItem) {
|
|
89
|
+
const summary = pathItem.summary;
|
|
90
|
+
const description = pathItem.description;
|
|
91
|
+
return {
|
|
92
|
+
summary: typeof summary === "string" ? summary : void 0,
|
|
93
|
+
description: typeof description === "string" ? description : void 0
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Resolve an operation against an already-parsed document. Throws if
|
|
98
|
+
* the operation is not found.
|
|
99
|
+
*
|
|
100
|
+
* Used by callers that have already obtained a parsed document via
|
|
101
|
+
* {@link getParsed} — most importantly the React components, which
|
|
102
|
+
* supply `diagnostics` to `getParsed` and must avoid re-running the
|
|
103
|
+
* normalisation pipeline (every re-run would emit each diagnostic
|
|
104
|
+
* again into the sink).
|
|
105
|
+
*/
|
|
106
|
+
function resolveOperationFromParsed(parsed, path, method) {
|
|
53
107
|
const operation = listOperations(parsed).find((op) => op.path === path && op.method === method);
|
|
54
108
|
if (operation === void 0) throw new Error(`Operation not found: ${method.toUpperCase()} ${path}`);
|
|
109
|
+
const pathItemNode = lookupPathItemNode(parsed, path);
|
|
110
|
+
if (pathItemNode === void 0) throw new Error(`Path item missing for ${method.toUpperCase()} ${path}`);
|
|
55
111
|
return {
|
|
56
112
|
operation,
|
|
113
|
+
pathItem: extractPathItemInfo(pathItemNode),
|
|
57
114
|
parameters: getParameters(parsed, path, method),
|
|
58
115
|
requestBody: getRequestBody(parsed, path, method),
|
|
59
116
|
responses: getResponses(parsed, path, method)
|
|
60
117
|
};
|
|
61
118
|
}
|
|
62
119
|
/**
|
|
120
|
+
* Resolve an operation from an OpenAPI document by path and method.
|
|
121
|
+
* Throws if the operation is not found.
|
|
122
|
+
*
|
|
123
|
+
* `diagnostics` is forwarded to {@link getParsed} so normalisation
|
|
124
|
+
* events surface to the caller's sink.
|
|
125
|
+
*/
|
|
126
|
+
function resolveOperation(doc, path, method, diagnostics) {
|
|
127
|
+
return resolveOperationFromParsed(getParsed(doc, diagnostics), path, method);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Resolve parameters against an already-parsed document. See
|
|
131
|
+
* {@link resolveOperationFromParsed} for the rationale.
|
|
132
|
+
*/
|
|
133
|
+
function resolveParametersFromParsed(parsed, path, method) {
|
|
134
|
+
return getParameters(parsed, path, method);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
63
137
|
* Resolve parameters for an operation. Returns empty array if none.
|
|
138
|
+
*
|
|
139
|
+
* `diagnostics` is forwarded to {@link getParsed} so normalisation
|
|
140
|
+
* events surface to the caller's sink.
|
|
141
|
+
*/
|
|
142
|
+
function resolveParameters(doc, path, method, diagnostics) {
|
|
143
|
+
return resolveParametersFromParsed(getParsed(doc, diagnostics), path, method);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Resolve a request body against an already-parsed document. See
|
|
147
|
+
* {@link resolveOperationFromParsed} for the rationale.
|
|
64
148
|
*/
|
|
65
|
-
function
|
|
66
|
-
return
|
|
149
|
+
function resolveRequestBodyFromParsed(parsed, path, method) {
|
|
150
|
+
return getRequestBody(parsed, path, method);
|
|
67
151
|
}
|
|
68
152
|
/**
|
|
69
153
|
* Resolve request body for an operation. Returns undefined if none.
|
|
154
|
+
*
|
|
155
|
+
* `diagnostics` is forwarded to {@link getParsed} so normalisation
|
|
156
|
+
* events surface to the caller's sink.
|
|
70
157
|
*/
|
|
71
|
-
function resolveRequestBody(doc, path, method) {
|
|
72
|
-
return
|
|
158
|
+
function resolveRequestBody(doc, path, method, diagnostics) {
|
|
159
|
+
return resolveRequestBodyFromParsed(getParsed(doc, diagnostics), path, method);
|
|
73
160
|
}
|
|
74
161
|
/**
|
|
75
|
-
* Resolve a specific response
|
|
162
|
+
* Resolve a specific response against an already-parsed document. See
|
|
163
|
+
* {@link resolveOperationFromParsed} for the rationale.
|
|
76
164
|
*/
|
|
77
|
-
function
|
|
78
|
-
const response = getResponses(
|
|
165
|
+
function resolveResponseFromParsed(parsed, path, method, statusCode) {
|
|
166
|
+
const response = getResponses(parsed, path, method).find((r) => r.statusCode === statusCode);
|
|
79
167
|
if (response === void 0) throw new Error(`Response not found: ${statusCode}`);
|
|
80
168
|
return response;
|
|
81
169
|
}
|
|
82
170
|
/**
|
|
171
|
+
* Resolve a specific response by status code. Throws if not found.
|
|
172
|
+
*
|
|
173
|
+
* `diagnostics` is forwarded to {@link getParsed} so normalisation
|
|
174
|
+
* events surface to the caller's sink.
|
|
175
|
+
*/
|
|
176
|
+
function resolveResponse(doc, path, method, statusCode, diagnostics) {
|
|
177
|
+
return resolveResponseFromParsed(getParsed(doc, diagnostics), path, method, statusCode);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
83
180
|
* Resolve all responses for an operation.
|
|
181
|
+
*
|
|
182
|
+
* `diagnostics` is forwarded to {@link getParsed} so normalisation
|
|
183
|
+
* events surface to the caller's sink.
|
|
84
184
|
*/
|
|
85
|
-
function resolveResponses(doc, path, method) {
|
|
86
|
-
return getResponses(getParsed(doc), path, method);
|
|
185
|
+
function resolveResponses(doc, path, method, diagnostics) {
|
|
186
|
+
return getResponses(getParsed(doc, diagnostics), path, method);
|
|
87
187
|
}
|
|
88
188
|
//#endregion
|
|
89
|
-
export { getParsed, resolveOperation, resolveParameters, resolveRequestBody, resolveResponse, resolveResponses, toDoc };
|
|
189
|
+
export { getParsed, resolveOperation, resolveOperationFromParsed, resolveParameters, resolveParametersFromParsed, resolveRequestBody, resolveRequestBodyFromParsed, resolveResponse, resolveResponseFromParsed, resolveResponses, toDoc };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { M as WalkedField, T as SchemaMeta, d as FieldOverrides, u as FieldOverride } from "../types-
|
|
2
|
-
import { t as Diagnostic } from "../diagnostics-
|
|
3
|
-
import { t as SchemaError } from "../errors-
|
|
4
|
-
import { l as RenderProps, r as ComponentResolver } from "../renderer-
|
|
5
|
-
import { c as PathOfType, l as
|
|
1
|
+
import { M as WalkedField, T as SchemaMeta, d as FieldOverrides, u as FieldOverride } from "../types-BnxPEElk.mjs";
|
|
2
|
+
import { t as Diagnostic } from "../diagnostics-CbBPsxSt.mjs";
|
|
3
|
+
import { t as SchemaError } from "../errors-QEwOtQAA.mjs";
|
|
4
|
+
import { l as RenderProps, r as ComponentResolver } from "../renderer-DI6ZYf7a.mjs";
|
|
5
|
+
import { c as PathOfType, l as RejectUnrepresentableZod, n as FromJSONSchema, u as ResolveOpenAPIRef } from "../typeInference-Bxw3NOG1.mjs";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
8
8
|
import { ReactNode } from "react";
|
|
@@ -40,8 +40,17 @@ type InferFields<T, Ref extends string | undefined> = T extends z.ZodType ? Fiel
|
|
|
40
40
|
openapi: unknown;
|
|
41
41
|
} ? Ref extends string ? FieldOverrides<ResolveOpenAPIRef<T & Record<string, unknown>, Ref>> : Record<string, FieldOverride> : T extends object ? unknown extends FromJSONSchema<T> ? Record<string, FieldOverride> : FieldOverrides<FromJSONSchema<T>> : Record<string, FieldOverride>;
|
|
42
42
|
interface SchemaComponentProps<T = unknown, Ref extends string | undefined = undefined> {
|
|
43
|
-
/**
|
|
44
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Zod schema, JSON Schema object, or OpenAPI document.
|
|
45
|
+
*
|
|
46
|
+
* Zod 4 types that cannot round-trip through `z.toJSONSchema()`
|
|
47
|
+
* (bigint, date, map, set, symbol, function, undefined, void, nan,
|
|
48
|
+
* codec) are rejected at the type level via
|
|
49
|
+
* {@link RejectUnrepresentableZod}. Runtime conversion would throw
|
|
50
|
+
* `SchemaNormalisationError` with kind `zod-type-unrepresentable`
|
|
51
|
+
* — the static rejection surfaces the same failure at compile time.
|
|
52
|
+
*/
|
|
53
|
+
schema: RejectUnrepresentableZod<T>;
|
|
45
54
|
/** For OpenAPI: a ref string like "#/components/schemas/User" or "/users/post". */
|
|
46
55
|
ref?: Ref;
|
|
47
56
|
/** Current value to render. */
|
|
@@ -128,8 +137,11 @@ interface SchemaFieldProps<T = unknown, Ref extends string | undefined = undefin
|
|
|
128
137
|
* paths are accepted. Falls back to `string` for runtime schemas.
|
|
129
138
|
*/
|
|
130
139
|
path: P;
|
|
131
|
-
/**
|
|
132
|
-
|
|
140
|
+
/**
|
|
141
|
+
* The schema to extract the field from. Subject to the same
|
|
142
|
+
* unrepresentable-Zod rejection as {@link SchemaComponentProps.schema}.
|
|
143
|
+
*/
|
|
144
|
+
schema: RejectUnrepresentableZod<T>;
|
|
133
145
|
/** For OpenAPI: a ref string. */
|
|
134
146
|
ref?: Ref;
|
|
135
147
|
/** Current value of the field at the given path. */
|
|
@@ -87,7 +87,7 @@ function SchemaComponent({ schema: schemaInput, ref: refInput, value, onChange,
|
|
|
87
87
|
}
|
|
88
88
|
const handleChange = useCallback((nextValue) => {
|
|
89
89
|
if (validate) {
|
|
90
|
-
const error = runValidation(zodSchema, jsonSchema, nextValue);
|
|
90
|
+
const error = runValidation(zodSchema, jsonSchema, nextValue, onDiagnostic);
|
|
91
91
|
if (error !== void 0) {
|
|
92
92
|
onValidationError?.(error);
|
|
93
93
|
dispatchFieldErrors(fields, error);
|
|
@@ -100,7 +100,8 @@ function SchemaComponent({ schema: schemaInput, ref: refInput, value, onChange,
|
|
|
100
100
|
jsonSchema,
|
|
101
101
|
onChange,
|
|
102
102
|
onValidationError,
|
|
103
|
-
fields
|
|
103
|
+
fields,
|
|
104
|
+
onDiagnostic
|
|
104
105
|
]);
|
|
105
106
|
const walkOptions = {
|
|
106
107
|
componentMeta: mergedMeta,
|
|
@@ -145,7 +146,7 @@ function sanitisePrefix(value) {
|
|
|
145
146
|
if (sanitised.length === 0) throw new Error(`Cannot derive a DOM-safe id prefix from "${value}". Pass an explicit idPrefix prop.`);
|
|
146
147
|
return sanitised;
|
|
147
148
|
}
|
|
148
|
-
function runValidation(zodSchema, jsonSchema, value) {
|
|
149
|
+
function runValidation(zodSchema, jsonSchema, value, onDiagnostic) {
|
|
149
150
|
if (zodSchema !== void 0 && isObject(zodSchema)) {
|
|
150
151
|
const safeParseFn = zodSchema.safeParse;
|
|
151
152
|
if (isCallable(safeParseFn)) {
|
|
@@ -154,7 +155,13 @@ function runValidation(zodSchema, jsonSchema, value) {
|
|
|
154
155
|
return;
|
|
155
156
|
}
|
|
156
157
|
}
|
|
157
|
-
|
|
158
|
+
let parsed;
|
|
159
|
+
try {
|
|
160
|
+
parsed = z.fromJSONSchema(jsonSchema);
|
|
161
|
+
} catch (err) {
|
|
162
|
+
emitFromJsonSchemaDiagnostic(err, onDiagnostic);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
158
165
|
if (isObject(parsed)) {
|
|
159
166
|
const safeParseFn = parsed.safeParse;
|
|
160
167
|
if (isCallable(safeParseFn)) {
|
|
@@ -163,6 +170,27 @@ function runValidation(zodSchema, jsonSchema, value) {
|
|
|
163
170
|
}
|
|
164
171
|
}
|
|
165
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* Emit a diagnostic when `z.fromJSONSchema` refuses to round-trip the
|
|
175
|
+
* already-normalised JSON Schema. The diagnostic reuses the existing
|
|
176
|
+
* `unsupported-type` code because the failure mode is the same — a
|
|
177
|
+
* keyword/structure Zod cannot represent — and the consumer should be
|
|
178
|
+
* able to opt in to noticing it via the existing diagnostics channel.
|
|
179
|
+
*
|
|
180
|
+
* Best-effort: when no `onDiagnostic` sink is configured we still swallow
|
|
181
|
+
* the throw (the alternative would crash the React render for a
|
|
182
|
+
* non-essential validation step), matching the silent-fallback contract
|
|
183
|
+
* the rest of the diagnostics system uses.
|
|
184
|
+
*/
|
|
185
|
+
function emitFromJsonSchemaDiagnostic(err, onDiagnostic) {
|
|
186
|
+
if (onDiagnostic === void 0) return;
|
|
187
|
+
onDiagnostic({
|
|
188
|
+
code: "unsupported-type",
|
|
189
|
+
message: `Skipping fallback validation: z.fromJSONSchema could not round-trip the normalised JSON Schema. Original message: ${err instanceof Error ? err.message : "z.fromJSONSchema threw a non-Error value"}`,
|
|
190
|
+
pointer: "",
|
|
191
|
+
detail: { source: "z.fromJSONSchema" }
|
|
192
|
+
});
|
|
193
|
+
}
|
|
166
194
|
/** Maximum rendering depth before treating a field as recursive. */
|
|
167
195
|
const MAX_RENDER_DEPTH = 10;
|
|
168
196
|
function renderField(tree, value, onChange, userResolver, renderChild, path, instanceWidgets, contextWidgets, depth = 0) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { T as SchemaMeta } from "../types-
|
|
2
|
-
import { t as Diagnostic } from "../diagnostics-
|
|
3
|
-
import { r as ComponentResolver } from "../renderer-
|
|
1
|
+
import { T as SchemaMeta } from "../types-BnxPEElk.mjs";
|
|
2
|
+
import { t as Diagnostic } from "../diagnostics-CbBPsxSt.mjs";
|
|
3
|
+
import { r as ComponentResolver } from "../renderer-DI6ZYf7a.mjs";
|
|
4
4
|
import { WidgetMap } from "./SchemaComponent.mjs";
|
|
5
5
|
import { ReactNode } from "react";
|
|
6
6
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { M as WalkedField } from "../types-
|
|
2
|
-
import { l as RenderProps } from "../renderer-
|
|
1
|
+
import { M as WalkedField } from "../types-BnxPEElk.mjs";
|
|
2
|
+
import { l as RenderProps } from "../renderer-DI6ZYf7a.mjs";
|
|
3
3
|
import { ReactNode } from "react";
|
|
4
4
|
|
|
5
5
|
//#region src/react/headlessRenderers.d.ts
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isObject } from "../core/guards.mjs";
|
|
2
|
+
import { isSafeHyperlink, isSafeMailtoAddress } from "../core/uri.mjs";
|
|
2
3
|
import { sortFieldsByOrder } from "../core/fieldOrder.mjs";
|
|
3
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
5
|
import { isValidElement, useCallback, useEffect, useRef } from "react";
|
|
@@ -83,13 +84,13 @@ function renderString(props) {
|
|
|
83
84
|
children: "—"
|
|
84
85
|
});
|
|
85
86
|
const format = props.constraints.format;
|
|
86
|
-
if (format === "email") return /* @__PURE__ */ jsx("a", {
|
|
87
|
+
if (format === "email" && isSafeMailtoAddress(strValue)) return /* @__PURE__ */ jsx("a", {
|
|
87
88
|
href: `mailto:${strValue}`,
|
|
88
89
|
id,
|
|
89
90
|
"aria-readonly": "true",
|
|
90
91
|
children: strValue
|
|
91
92
|
});
|
|
92
|
-
if (format === "uri" || format === "url") return /* @__PURE__ */ jsx("a", {
|
|
93
|
+
if ((format === "uri" || format === "url") && isSafeHyperlink(strValue)) return /* @__PURE__ */ jsx("a", {
|
|
93
94
|
href: strValue,
|
|
94
95
|
id,
|
|
95
96
|
"aria-readonly": "true",
|
|
@@ -658,12 +659,14 @@ function renderNever(props) {
|
|
|
658
659
|
function renderTuple(props) {
|
|
659
660
|
if (props.tree.type !== "tuple") return null;
|
|
660
661
|
const prefixItems = props.tree.prefixItems;
|
|
661
|
-
|
|
662
|
+
const restItems = props.tree.restItems;
|
|
662
663
|
const arr = Array.isArray(props.value) ? props.value : [];
|
|
663
|
-
|
|
664
|
+
if (prefixItems.length === 0 && restItems === void 0 && arr.length === 0) return null;
|
|
665
|
+
const restCount = restItems !== void 0 ? Math.max(arr.length - prefixItems.length, 0) : 0;
|
|
666
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
664
667
|
role: "group",
|
|
665
668
|
"aria-label": props.meta.description ?? void 0,
|
|
666
|
-
children: prefixItems.map((element, i) => {
|
|
669
|
+
children: [prefixItems.map((element, i) => {
|
|
667
670
|
const itemValue = arr[i];
|
|
668
671
|
const childOnChange = (v) => {
|
|
669
672
|
const next = arr.slice();
|
|
@@ -671,7 +674,16 @@ function renderTuple(props) {
|
|
|
671
674
|
props.onChange(next);
|
|
672
675
|
};
|
|
673
676
|
return /* @__PURE__ */ jsx("div", { children: toReactNode(props.renderChild(element, itemValue, childOnChange, `[${String(i)}]`)) }, String(i));
|
|
674
|
-
})
|
|
677
|
+
}), restItems !== void 0 && Array.from({ length: restCount }, (_, j) => {
|
|
678
|
+
const i = prefixItems.length + j;
|
|
679
|
+
const itemValue = arr[i];
|
|
680
|
+
const childOnChange = (v) => {
|
|
681
|
+
const next = arr.slice();
|
|
682
|
+
next[i] = v;
|
|
683
|
+
props.onChange(next);
|
|
684
|
+
};
|
|
685
|
+
return /* @__PURE__ */ jsx("div", { children: toReactNode(props.renderChild(restItems, itemValue, childOnChange, `[${String(i)}]`)) }, `rest-${String(i)}`);
|
|
686
|
+
})]
|
|
675
687
|
});
|
|
676
688
|
}
|
|
677
689
|
/**
|
|
@@ -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/ref.d.ts
|
|
4
4
|
/**
|
|
@@ -38,7 +38,12 @@ declare function dereference(ref: string, root: Record<string, unknown>): Record
|
|
|
38
38
|
/**
|
|
39
39
|
* Recursively scan a schema document for a `$anchor` matching the given name.
|
|
40
40
|
* Returns the schema object containing the anchor, or undefined.
|
|
41
|
+
*
|
|
42
|
+
* The optional `visited` set guards against shared object references and
|
|
43
|
+
* cycles introduced by the OpenAPI bundler's `structuredClone`-based
|
|
44
|
+
* inlining of external refs. Without it a recursive document would stack
|
|
45
|
+
* overflow before reaching the matching anchor.
|
|
41
46
|
*/
|
|
42
|
-
declare function findAnchor(node: unknown, anchorName: string): Record<string, unknown> | undefined;
|
|
47
|
+
declare function findAnchor(node: unknown, anchorName: string, visited?: WeakSet<object>): Record<string, unknown> | undefined;
|
|
43
48
|
//#endregion
|
|
44
49
|
export { findAnchor as a, dereference as i, RefOptions as n, resolveRef as o, countDistinctRefs as r, ExternalResolver as t };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { D as StringConstraints, M as WalkedField, T as SchemaMeta, f as FileConstraints, t as ArrayConstraints, x as ObjectConstraints, y as NumberConstraints } from "./types-
|
|
1
|
+
import { D as StringConstraints, M as WalkedField, T as SchemaMeta, f as FileConstraints, t as ArrayConstraints, x as ObjectConstraints, y as NumberConstraints } from "./types-BnxPEElk.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/core/renderer.d.ts
|
|
4
4
|
/**
|
package/dist/themes/mui.d.mts
CHANGED
package/dist/themes/radix.d.mts
CHANGED
package/dist/themes/shadcn.d.mts
CHANGED