schema-components 1.12.10 → 1.13.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/README.md +31 -0
- package/dist/core/adapter.d.mts +1 -1
- package/dist/core/adapter.mjs +37 -8
- package/dist/core/constraints.d.mts +16 -0
- package/dist/core/constraints.mjs +138 -0
- package/dist/core/merge.d.mts +32 -0
- package/dist/core/merge.mjs +96 -0
- package/dist/core/normalise.d.mts +40 -0
- package/dist/core/normalise.mjs +171 -0
- package/dist/core/openapi30.d.mts +38 -0
- package/dist/core/openapi30.mjs +223 -0
- package/dist/core/ref.d.mts +25 -0
- package/dist/core/ref.mjs +86 -0
- package/dist/core/renderer.d.mts +2 -2
- package/dist/core/renderer.mjs +8 -0
- package/dist/core/swagger2.d.mts +10 -0
- package/dist/core/swagger2.mjs +294 -0
- package/dist/core/typeInference.d.mts +2 -0
- package/dist/core/typeInference.mjs +1 -0
- package/dist/core/types.d.mts +2 -3
- package/dist/core/types.mjs +55 -2
- package/dist/core/version.d.mts +2 -0
- package/dist/core/version.mjs +79 -0
- package/dist/core/walkBuilders.d.mts +52 -0
- package/dist/core/walkBuilders.mjs +152 -0
- package/dist/core/walker.d.mts +3 -10
- package/dist/core/walker.mjs +143 -231
- package/dist/html/a11y.d.mts +5 -4
- package/dist/html/renderToHtml.d.mts +3 -3
- package/dist/html/renderToHtml.mjs +23 -379
- package/dist/html/renderToHtmlStream.d.mts +29 -47
- package/dist/html/renderToHtmlStream.mjs +33 -305
- package/dist/html/renderers.d.mts +14 -0
- package/dist/html/renderers.mjs +406 -0
- package/dist/html/streamRenderers.d.mts +13 -0
- package/dist/html/streamRenderers.mjs +243 -0
- package/dist/openapi/components.d.mts +2 -1
- package/dist/openapi/parser.d.mts +59 -2
- package/dist/openapi/parser.mjs +189 -8
- package/dist/react/SchemaComponent.d.mts +4 -2
- package/dist/react/SchemaComponent.mjs +39 -85
- package/dist/react/SchemaView.d.mts +2 -1
- package/dist/react/SchemaView.mjs +21 -9
- package/dist/react/fieldPath.d.mts +20 -0
- package/dist/react/fieldPath.mjs +81 -0
- package/dist/react/headless.d.mts +2 -4
- package/dist/react/headless.mjs +3 -492
- package/dist/react/headlessRenderers.d.mts +23 -0
- package/dist/react/headlessRenderers.mjs +507 -0
- package/dist/renderer-DseHeliw.d.mts +160 -0
- package/dist/themes/mantine.d.mts +1 -1
- package/dist/themes/mantine.mjs +2 -1
- package/dist/themes/mui.d.mts +1 -1
- package/dist/themes/mui.mjs +2 -1
- package/dist/themes/radix.d.mts +1 -1
- package/dist/themes/radix.mjs +2 -1
- package/dist/themes/shadcn.d.mts +1 -1
- package/dist/themes/shadcn.mjs +10 -6
- package/dist/typeInference-CRPqVwKu.d.mts +299 -0
- package/dist/types-ag2jYLqQ.d.mts +261 -0
- package/dist/version-CLchheaH.d.mts +40 -0
- package/package.json +1 -1
- package/dist/types-BJzEgJdX.d.mts +0 -335
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { m as JsonObject } from "../types-ag2jYLqQ.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/openapi/parser.d.ts
|
|
4
4
|
interface OpenApiDocument {
|
|
@@ -28,6 +28,7 @@ interface ResponseInfo {
|
|
|
28
28
|
description: string | undefined;
|
|
29
29
|
contentTypes: string[];
|
|
30
30
|
schema: JsonObject | undefined;
|
|
31
|
+
headers: Map<string, HeaderInfo>;
|
|
31
32
|
}
|
|
32
33
|
interface RequestBodyInfo {
|
|
33
34
|
required: boolean;
|
|
@@ -35,11 +36,67 @@ interface RequestBodyInfo {
|
|
|
35
36
|
contentTypes: string[];
|
|
36
37
|
schema: JsonObject | undefined;
|
|
37
38
|
}
|
|
39
|
+
interface SecurityRequirement {
|
|
40
|
+
name: string;
|
|
41
|
+
scopes: string[];
|
|
42
|
+
}
|
|
43
|
+
interface SecurityScheme {
|
|
44
|
+
type: string;
|
|
45
|
+
description: string | undefined;
|
|
46
|
+
name: string | undefined;
|
|
47
|
+
location: string | undefined;
|
|
48
|
+
scheme: string | undefined;
|
|
49
|
+
bearerFormat: string | undefined;
|
|
50
|
+
flows: JsonObject | undefined;
|
|
51
|
+
openIdConnectUrl: string | undefined;
|
|
52
|
+
}
|
|
53
|
+
interface HeaderInfo {
|
|
54
|
+
name: string;
|
|
55
|
+
description: string | undefined;
|
|
56
|
+
required: boolean;
|
|
57
|
+
deprecated: boolean;
|
|
58
|
+
schema: JsonObject | undefined;
|
|
59
|
+
}
|
|
60
|
+
interface WebhookInfo {
|
|
61
|
+
name: string;
|
|
62
|
+
operations: OperationInfo[];
|
|
63
|
+
}
|
|
64
|
+
interface ExternalDocs {
|
|
65
|
+
url: string;
|
|
66
|
+
description: string | undefined;
|
|
67
|
+
}
|
|
68
|
+
interface XmlInfo {
|
|
69
|
+
name: string | undefined;
|
|
70
|
+
namespace: string | undefined;
|
|
71
|
+
prefix: string | undefined;
|
|
72
|
+
attribute: boolean;
|
|
73
|
+
wrapped: boolean;
|
|
74
|
+
}
|
|
75
|
+
interface CallbackInfo {
|
|
76
|
+
name: string;
|
|
77
|
+
operations: OperationInfo[];
|
|
78
|
+
}
|
|
79
|
+
interface LinkInfo {
|
|
80
|
+
name: string;
|
|
81
|
+
operationId: string | undefined;
|
|
82
|
+
operationRef: string | undefined;
|
|
83
|
+
description: string | undefined;
|
|
84
|
+
parameters: Map<string, string>;
|
|
85
|
+
requestBody: string | undefined;
|
|
86
|
+
}
|
|
38
87
|
declare function parseOpenApiDocument(doc: JsonObject): OpenApiDocument;
|
|
39
88
|
declare function getSchema(parsed: OpenApiDocument, ref: string): JsonObject | undefined;
|
|
40
89
|
declare function listOperations(parsed: OpenApiDocument): OperationInfo[];
|
|
41
90
|
declare function getParameters(parsed: OpenApiDocument, path: string, method: string): ParameterInfo[];
|
|
42
91
|
declare function getRequestBody(parsed: OpenApiDocument, path: string, method: string): RequestBodyInfo | undefined;
|
|
43
92
|
declare function getResponses(parsed: OpenApiDocument, path: string, method: string): ResponseInfo[];
|
|
93
|
+
declare function getSecurityRequirements(parsed: OpenApiDocument, path: string, method: string): SecurityRequirement[];
|
|
94
|
+
declare function getSecuritySchemes(parsed: OpenApiDocument): Map<string, SecurityScheme>;
|
|
95
|
+
declare function getResponseHeaders(response: JsonObject): Map<string, HeaderInfo>;
|
|
96
|
+
declare function listWebhooks(parsed: OpenApiDocument): WebhookInfo[];
|
|
97
|
+
declare function getExternalDocs(obj: JsonObject): ExternalDocs | undefined;
|
|
98
|
+
declare function getXmlInfo(schema: JsonObject): XmlInfo | undefined;
|
|
99
|
+
declare function listCallbacks(parsed: OpenApiDocument, path: string, method: string): CallbackInfo[];
|
|
100
|
+
declare function getLinks(parsed: OpenApiDocument, path: string, method: string, statusCode: string): LinkInfo[];
|
|
44
101
|
//#endregion
|
|
45
|
-
export { OpenApiDocument, OperationInfo, ParameterInfo, ParameterLocation, RequestBodyInfo, ResponseInfo, getParameters, getRequestBody, getResponses, getSchema, listOperations, parseOpenApiDocument };
|
|
102
|
+
export { CallbackInfo, ExternalDocs, HeaderInfo, LinkInfo, OpenApiDocument, OperationInfo, ParameterInfo, ParameterLocation, RequestBodyInfo, ResponseInfo, SecurityRequirement, SecurityScheme, WebhookInfo, XmlInfo, getExternalDocs, getLinks, getParameters, getRequestBody, getResponseHeaders, getResponses, getSchema, getSecurityRequirements, getSecuritySchemes, getXmlInfo, listCallbacks, listOperations, listWebhooks, parseOpenApiDocument };
|
package/dist/openapi/parser.mjs
CHANGED
|
@@ -35,12 +35,29 @@ const METHODS = [
|
|
|
35
35
|
"patch",
|
|
36
36
|
"delete"
|
|
37
37
|
];
|
|
38
|
+
/**
|
|
39
|
+
* Resolve a path item, following a `$ref` to `components/pathItems/<Name>`
|
|
40
|
+
* (OpenAPI 3.1) if present. Returns `undefined` when the value is not a
|
|
41
|
+
* path item, the ref is malformed, or the target does not resolve.
|
|
42
|
+
*/
|
|
43
|
+
function resolvePathItem(parsed, pathItem) {
|
|
44
|
+
if (!isObject(pathItem)) return void 0;
|
|
45
|
+
const ref = getString(pathItem, "$ref");
|
|
46
|
+
if (ref === void 0) return pathItem;
|
|
47
|
+
return resolveRefInDoc(parsed.doc, ref) ?? void 0;
|
|
48
|
+
}
|
|
49
|
+
function lookupPathItem(parsed, path) {
|
|
50
|
+
const resolved = resolvePathItem(parsed, getProperty(getProperty(parsed.doc, "paths"), path));
|
|
51
|
+
if (resolved !== void 0) return resolved;
|
|
52
|
+
return resolvePathItem(parsed, getProperty(getProperty(parsed.doc, "webhooks"), path));
|
|
53
|
+
}
|
|
38
54
|
function listOperations(parsed) {
|
|
39
55
|
const operations = [];
|
|
40
56
|
const paths = getProperty(parsed.doc, "paths");
|
|
41
57
|
if (!isObject(paths)) return operations;
|
|
42
|
-
for (const [path,
|
|
43
|
-
|
|
58
|
+
for (const [path, rawPathItem] of Object.entries(paths)) {
|
|
59
|
+
const pathItem = resolvePathItem(parsed, rawPathItem);
|
|
60
|
+
if (pathItem === void 0) continue;
|
|
44
61
|
for (const method of METHODS) {
|
|
45
62
|
const operation = getProperty(pathItem, method);
|
|
46
63
|
if (!isObject(operation)) continue;
|
|
@@ -58,8 +75,8 @@ function listOperations(parsed) {
|
|
|
58
75
|
return operations;
|
|
59
76
|
}
|
|
60
77
|
function getParameters(parsed, path, method) {
|
|
61
|
-
const pathItem =
|
|
62
|
-
if (
|
|
78
|
+
const pathItem = lookupPathItem(parsed, path);
|
|
79
|
+
if (pathItem === void 0) return [];
|
|
63
80
|
const operation = getProperty(pathItem, method);
|
|
64
81
|
if (!isObject(operation)) return [];
|
|
65
82
|
const pathParams = extractParameterList(getProperty(pathItem, "parameters"));
|
|
@@ -99,7 +116,7 @@ function resolveParam(param) {
|
|
|
99
116
|
return param;
|
|
100
117
|
}
|
|
101
118
|
function getRequestBody(parsed, path, method) {
|
|
102
|
-
const requestBody = getProperty(getProperty(
|
|
119
|
+
const requestBody = getProperty(getProperty(lookupPathItem(parsed, path), method), "requestBody");
|
|
103
120
|
if (!isObject(requestBody)) return void 0;
|
|
104
121
|
const content = getProperty(requestBody, "content");
|
|
105
122
|
if (!isObject(content)) return {
|
|
@@ -118,7 +135,7 @@ function getRequestBody(parsed, path, method) {
|
|
|
118
135
|
};
|
|
119
136
|
}
|
|
120
137
|
function getResponses(parsed, path, method) {
|
|
121
|
-
const responses = getProperty(getProperty(
|
|
138
|
+
const responses = getProperty(getProperty(lookupPathItem(parsed, path), method), "responses");
|
|
122
139
|
if (!isObject(responses)) return [];
|
|
123
140
|
const result = [];
|
|
124
141
|
for (const [statusCode, response] of Object.entries(responses)) {
|
|
@@ -126,11 +143,13 @@ function getResponses(parsed, path, method) {
|
|
|
126
143
|
const content = getProperty(response, "content");
|
|
127
144
|
const contentTypes = isObject(content) ? Object.keys(content) : [];
|
|
128
145
|
const schema = isObject(content) ? extractSchemaFromContent(content) : void 0;
|
|
146
|
+
const headers = getResponseHeaders(response);
|
|
129
147
|
result.push({
|
|
130
148
|
statusCode,
|
|
131
149
|
description: getString(response, "description"),
|
|
132
150
|
contentTypes,
|
|
133
|
-
schema
|
|
151
|
+
schema,
|
|
152
|
+
headers
|
|
134
153
|
});
|
|
135
154
|
}
|
|
136
155
|
return result;
|
|
@@ -155,5 +174,167 @@ function resolveRefInDoc(doc, ref) {
|
|
|
155
174
|
}
|
|
156
175
|
return isObject(current) ? current : void 0;
|
|
157
176
|
}
|
|
177
|
+
function getSecurityRequirements(parsed, path, method) {
|
|
178
|
+
const opSecurity = getProperty(getProperty(lookupPathItem(parsed, path), method), "security");
|
|
179
|
+
const globalSecurity = getProperty(parsed.doc, "security");
|
|
180
|
+
const securityArray = Array.isArray(opSecurity) ? opSecurity : Array.isArray(globalSecurity) ? globalSecurity : [];
|
|
181
|
+
const result = [];
|
|
182
|
+
for (const entry of securityArray) {
|
|
183
|
+
if (!isObject(entry)) continue;
|
|
184
|
+
for (const [name, scopes] of Object.entries(entry)) result.push({
|
|
185
|
+
name,
|
|
186
|
+
scopes: Array.isArray(scopes) ? scopes.filter((s) => typeof s === "string") : []
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
return result;
|
|
190
|
+
}
|
|
191
|
+
function getSecuritySchemes(parsed) {
|
|
192
|
+
const result = /* @__PURE__ */ new Map();
|
|
193
|
+
const securitySchemes = getProperty(getProperty(parsed.doc, "components"), "securitySchemes");
|
|
194
|
+
if (!isObject(securitySchemes)) return result;
|
|
195
|
+
for (const [name, scheme] of Object.entries(securitySchemes)) {
|
|
196
|
+
if (!isObject(scheme)) continue;
|
|
197
|
+
const flowsProp = getProperty(scheme, "flows");
|
|
198
|
+
result.set(name, {
|
|
199
|
+
type: getString(scheme, "type") ?? "",
|
|
200
|
+
description: getString(scheme, "description"),
|
|
201
|
+
name: getString(scheme, "name"),
|
|
202
|
+
location: getString(scheme, "in"),
|
|
203
|
+
scheme: getString(scheme, "scheme"),
|
|
204
|
+
bearerFormat: getString(scheme, "bearerFormat"),
|
|
205
|
+
flows: isObject(flowsProp) ? flowsProp : void 0,
|
|
206
|
+
openIdConnectUrl: getString(scheme, "openIdConnectUrl")
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
return result;
|
|
210
|
+
}
|
|
211
|
+
function getResponseHeaders(response) {
|
|
212
|
+
const result = /* @__PURE__ */ new Map();
|
|
213
|
+
const headers = getProperty(response, "headers");
|
|
214
|
+
if (!isObject(headers)) return result;
|
|
215
|
+
for (const [name, headerObj] of Object.entries(headers)) {
|
|
216
|
+
if (!isObject(headerObj)) continue;
|
|
217
|
+
const ref = getString(headerObj, "$ref");
|
|
218
|
+
const header = (ref !== void 0 ? resolveRefInDoc(headerObj, ref) : void 0) ?? headerObj;
|
|
219
|
+
const schemaProp = getProperty(header, "schema");
|
|
220
|
+
result.set(name, {
|
|
221
|
+
name,
|
|
222
|
+
description: getString(header, "description"),
|
|
223
|
+
required: getProperty(header, "required") === true,
|
|
224
|
+
deprecated: getProperty(header, "deprecated") === true,
|
|
225
|
+
schema: isObject(schemaProp) ? schemaProp : void 0
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
return result;
|
|
229
|
+
}
|
|
230
|
+
function listWebhooks(parsed) {
|
|
231
|
+
const result = [];
|
|
232
|
+
const webhooks = getProperty(parsed.doc, "webhooks");
|
|
233
|
+
if (!isObject(webhooks)) return result;
|
|
234
|
+
for (const [name, hookItem] of Object.entries(webhooks)) {
|
|
235
|
+
if (!isObject(hookItem)) continue;
|
|
236
|
+
const operations = [];
|
|
237
|
+
for (const method of METHODS) {
|
|
238
|
+
const operation = getProperty(hookItem, method);
|
|
239
|
+
if (!isObject(operation)) continue;
|
|
240
|
+
operations.push({
|
|
241
|
+
path: name,
|
|
242
|
+
method,
|
|
243
|
+
operationId: getString(operation, "operationId"),
|
|
244
|
+
summary: getString(operation, "summary"),
|
|
245
|
+
description: getString(operation, "description"),
|
|
246
|
+
deprecated: getProperty(operation, "deprecated") === true,
|
|
247
|
+
operation
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
result.push({
|
|
251
|
+
name,
|
|
252
|
+
operations
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
return result;
|
|
256
|
+
}
|
|
257
|
+
function getExternalDocs(obj) {
|
|
258
|
+
const docs = getProperty(obj, "externalDocs");
|
|
259
|
+
if (!isObject(docs)) return void 0;
|
|
260
|
+
const url = getString(docs, "url");
|
|
261
|
+
if (typeof url !== "string") return void 0;
|
|
262
|
+
return {
|
|
263
|
+
url,
|
|
264
|
+
description: getString(docs, "description")
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
function getXmlInfo(schema) {
|
|
268
|
+
const xml = getProperty(schema, "xml");
|
|
269
|
+
if (!isObject(xml)) return void 0;
|
|
270
|
+
return {
|
|
271
|
+
name: getString(xml, "name"),
|
|
272
|
+
namespace: getString(xml, "namespace"),
|
|
273
|
+
prefix: getString(xml, "prefix"),
|
|
274
|
+
attribute: getProperty(xml, "attribute") === true,
|
|
275
|
+
wrapped: getProperty(xml, "wrapped") === true
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
function listCallbacks(parsed, path, method) {
|
|
279
|
+
const operation = getProperty(lookupPathItem(parsed, path), method);
|
|
280
|
+
if (!isObject(operation)) return [];
|
|
281
|
+
const callbacks = getProperty(operation, "callbacks");
|
|
282
|
+
if (!isObject(callbacks)) return [];
|
|
283
|
+
const result = [];
|
|
284
|
+
for (const [name, callbackItem] of Object.entries(callbacks)) {
|
|
285
|
+
if (!isObject(callbackItem)) continue;
|
|
286
|
+
const operations = [];
|
|
287
|
+
for (const [cbPath, cbPathItem] of Object.entries(callbackItem)) {
|
|
288
|
+
if (!isObject(cbPathItem)) continue;
|
|
289
|
+
for (const cbMethod of METHODS) {
|
|
290
|
+
const cbOp = getProperty(cbPathItem, cbMethod);
|
|
291
|
+
if (!isObject(cbOp)) continue;
|
|
292
|
+
const ref = getString(cbOp, "$ref");
|
|
293
|
+
const resolved = ref !== void 0 ? resolveRefInDoc(parsed.doc, ref) ?? cbOp : cbOp;
|
|
294
|
+
operations.push({
|
|
295
|
+
path: `${name}/${cbPath}`,
|
|
296
|
+
method: cbMethod,
|
|
297
|
+
operationId: getString(resolved, "operationId"),
|
|
298
|
+
summary: getString(resolved, "summary"),
|
|
299
|
+
description: getString(resolved, "description"),
|
|
300
|
+
deprecated: getProperty(resolved, "deprecated") === true,
|
|
301
|
+
operation: isObject(resolved) ? resolved : cbOp
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
result.push({
|
|
306
|
+
name,
|
|
307
|
+
operations
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
return result;
|
|
311
|
+
}
|
|
312
|
+
function getLinks(parsed, path, method, statusCode) {
|
|
313
|
+
const response = getProperty(getProperty(getProperty(lookupPathItem(parsed, path), method), "responses"), statusCode);
|
|
314
|
+
if (!isObject(response)) return [];
|
|
315
|
+
const links = getProperty(response, "links");
|
|
316
|
+
if (!isObject(links)) return [];
|
|
317
|
+
const result = [];
|
|
318
|
+
for (const [name, linkObj] of Object.entries(links)) {
|
|
319
|
+
if (!isObject(linkObj)) continue;
|
|
320
|
+
const ref = getString(linkObj, "$ref");
|
|
321
|
+
const resolved = ref !== void 0 ? resolveRefInDoc(parsed.doc, ref) ?? linkObj : linkObj;
|
|
322
|
+
const link = isObject(resolved) ? resolved : linkObj;
|
|
323
|
+
const params = getProperty(link, "parameters");
|
|
324
|
+
const paramMap = /* @__PURE__ */ new Map();
|
|
325
|
+
if (isObject(params)) {
|
|
326
|
+
for (const [paramName, paramValue] of Object.entries(params)) if (typeof paramValue === "string") paramMap.set(paramName, paramValue);
|
|
327
|
+
}
|
|
328
|
+
result.push({
|
|
329
|
+
name,
|
|
330
|
+
operationId: getString(link, "operationId"),
|
|
331
|
+
operationRef: getString(link, "operationRef"),
|
|
332
|
+
description: getString(link, "description"),
|
|
333
|
+
parameters: paramMap,
|
|
334
|
+
requestBody: getString(link, "requestBody")
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
return result;
|
|
338
|
+
}
|
|
158
339
|
//#endregion
|
|
159
|
-
export { getParameters, getRequestBody, getResponses, getSchema, listOperations, parseOpenApiDocument };
|
|
340
|
+
export { getExternalDocs, getLinks, getParameters, getRequestBody, getResponseHeaders, getResponses, getSchema, getSecurityRequirements, getSecuritySchemes, getXmlInfo, listCallbacks, listOperations, listWebhooks, parseOpenApiDocument };
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { d as FieldOverrides, j as WalkedField, u as FieldOverride, w as SchemaMeta } from "../types-ag2jYLqQ.mjs";
|
|
2
2
|
import { t as SchemaError } from "../errors-DIKI2C78.mjs";
|
|
3
|
+
import { l as RenderProps, r as ComponentResolver } from "../renderer-DseHeliw.mjs";
|
|
4
|
+
import { c as ResolveOpenAPIRef, s as PathOfType, t as FromJSONSchema } from "../typeInference-CRPqVwKu.mjs";
|
|
3
5
|
import { z } from "zod";
|
|
4
6
|
import { ReactNode } from "react";
|
|
5
7
|
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
@@ -79,7 +81,7 @@ declare function SchemaComponent<T = unknown, Ref extends string | undefined = u
|
|
|
79
81
|
description,
|
|
80
82
|
widgets: instanceWidgets
|
|
81
83
|
}: SchemaComponentProps<T, Ref>): ReactNode;
|
|
82
|
-
declare function renderField(tree: WalkedField, value: unknown, onChange: (v: unknown) => void, userResolver: ComponentResolver | undefined, renderChild: (tree: WalkedField, value: unknown, onChange: (v: unknown) => void) => ReactNode, instanceWidgets?: WidgetMap, contextWidgets?: WidgetMap): ReactNode;
|
|
84
|
+
declare function renderField(tree: WalkedField, value: unknown, onChange: (v: unknown) => void, userResolver: ComponentResolver | undefined, renderChild: (tree: WalkedField, value: unknown, onChange: (v: unknown) => void) => ReactNode, instanceWidgets?: WidgetMap, contextWidgets?: WidgetMap, depth?: number): ReactNode;
|
|
83
85
|
/**
|
|
84
86
|
* Infer the schema's output type for SchemaField path inference.
|
|
85
87
|
*/
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { isObject,
|
|
2
|
+
import { isObject, toRecordOrUndefined } from "../core/guards.mjs";
|
|
3
3
|
import { normaliseSchema } from "../core/adapter.mjs";
|
|
4
4
|
import { SchemaFieldError, SchemaNormalisationError, SchemaRenderError } from "../core/errors.mjs";
|
|
5
5
|
import { getRenderFunction, mergeResolvers } from "../core/renderer.mjs";
|
|
6
6
|
import { walk } from "../core/walker.mjs";
|
|
7
7
|
import { headlessResolver } from "./headless.mjs";
|
|
8
|
+
import { resolvePath, resolveValue, setNestedValue } from "./fieldPath.mjs";
|
|
8
9
|
import { z } from "zod";
|
|
9
10
|
import { createContext, isValidElement, useCallback, useContext, useMemo } from "react";
|
|
10
|
-
import { jsx } from "react/jsx-runtime";
|
|
11
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
12
|
//#region src/react/SchemaComponent.tsx
|
|
12
13
|
/**
|
|
13
14
|
* <SchemaComponent> — renders UI from Zod, JSON Schema, or OpenAPI schemas.
|
|
@@ -101,10 +102,11 @@ function SchemaComponent({ schema: schemaInput, ref: refInput, value, onChange,
|
|
|
101
102
|
fieldOverrides: fields,
|
|
102
103
|
rootDocument
|
|
103
104
|
});
|
|
104
|
-
const
|
|
105
|
-
return renderField(childTree, childValue, childOnChange, userResolver,
|
|
105
|
+
const makeRenderChild = (currentDepth) => (childTree, childValue, childOnChange) => {
|
|
106
|
+
return renderField(childTree, childValue, childOnChange, userResolver, makeRenderChild(currentDepth + 1), instanceWidgets, contextWidgets, currentDepth + 1);
|
|
106
107
|
};
|
|
107
|
-
|
|
108
|
+
const renderChild = makeRenderChild(0);
|
|
109
|
+
return renderField(tree, value ?? tree.defaultValue, handleChange, userResolver, renderChild, instanceWidgets, contextWidgets, 0);
|
|
108
110
|
}
|
|
109
111
|
function runValidation(zodSchema, jsonSchema, value) {
|
|
110
112
|
if (zodSchema !== void 0 && isObject(zodSchema)) {
|
|
@@ -124,8 +126,17 @@ function runValidation(zodSchema, jsonSchema, value) {
|
|
|
124
126
|
}
|
|
125
127
|
}
|
|
126
128
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
+
/** Maximum rendering depth before treating a field as recursive. */
|
|
130
|
+
const MAX_RENDER_DEPTH = 10;
|
|
131
|
+
function renderField(tree, value, onChange, userResolver, renderChild, instanceWidgets, contextWidgets, depth = 0) {
|
|
132
|
+
if (depth >= MAX_RENDER_DEPTH) {
|
|
133
|
+
const refTarget = tree.type === "recursive" ? tree.refTarget : "";
|
|
134
|
+
return /* @__PURE__ */ jsx("fieldset", { children: /* @__PURE__ */ jsxs("em", { children: [
|
|
135
|
+
"↻ ",
|
|
136
|
+
(typeof tree.meta.description === "string" ? tree.meta.description : refTarget) || "schema",
|
|
137
|
+
" (recursive)"
|
|
138
|
+
] }) });
|
|
139
|
+
}
|
|
129
140
|
const componentHint = tree.meta.component;
|
|
130
141
|
if (typeof componentHint === "string") {
|
|
131
142
|
const widget = instanceWidgets?.get(componentHint) ?? contextWidgets?.get(componentHint) ?? globalWidgets.get(componentHint);
|
|
@@ -166,13 +177,21 @@ function buildRenderProps(tree, value, onChange, renderChild) {
|
|
|
166
177
|
tree,
|
|
167
178
|
renderChild
|
|
168
179
|
};
|
|
169
|
-
if (tree.
|
|
170
|
-
if (tree.element !== void 0) props.element = tree.element;
|
|
171
|
-
if (tree.
|
|
172
|
-
if (tree.
|
|
173
|
-
if (tree.
|
|
174
|
-
if (tree.
|
|
175
|
-
if (tree.
|
|
180
|
+
if (tree.type === "enum") props.enumValues = tree.enumValues;
|
|
181
|
+
if (tree.type === "array" && tree.element !== void 0) props.element = tree.element;
|
|
182
|
+
if (tree.type === "object") props.fields = tree.fields;
|
|
183
|
+
if (tree.type === "union" || tree.type === "discriminatedUnion") props.options = tree.options;
|
|
184
|
+
if (tree.type === "discriminatedUnion") props.discriminator = tree.discriminator;
|
|
185
|
+
if (tree.type === "record") props.keyType = tree.keyType;
|
|
186
|
+
if (tree.type === "record") props.valueType = tree.valueType;
|
|
187
|
+
if (tree.type === "tuple") props.prefixItems = tree.prefixItems;
|
|
188
|
+
if (tree.type === "conditional") props.ifClause = tree.ifClause;
|
|
189
|
+
if (tree.type === "conditional" && tree.thenClause !== void 0) props.thenClause = tree.thenClause;
|
|
190
|
+
if (tree.type === "conditional" && tree.elseClause !== void 0) props.elseClause = tree.elseClause;
|
|
191
|
+
if (tree.type === "negation") props.negated = tree.negated;
|
|
192
|
+
if (tree.type === "recursive") props.refTarget = tree.refTarget;
|
|
193
|
+
if (tree.type === "literal") props.literalValues = tree.literalValues;
|
|
194
|
+
if (tree.examples !== void 0) props.examples = tree.examples;
|
|
176
195
|
return props;
|
|
177
196
|
}
|
|
178
197
|
function SchemaField({ path, schema: schemaInput, ref: refInput, value, onChange, meta: fieldMeta, validate, onValidationError }) {
|
|
@@ -215,78 +234,10 @@ function SchemaField({ path, schema: schemaInput, ref: refInput, value, onChange
|
|
|
215
234
|
onChange,
|
|
216
235
|
onValidationError
|
|
217
236
|
]);
|
|
218
|
-
const
|
|
219
|
-
return renderField(childTree, childValue, childOnChange, userResolver,
|
|
237
|
+
const makeRenderChild = (currentDepth) => (childTree, childValue, childOnChange) => {
|
|
238
|
+
return renderField(childTree, childValue, childOnChange, userResolver, makeRenderChild(currentDepth + 1), void 0, contextWidgets, currentDepth + 1);
|
|
220
239
|
};
|
|
221
|
-
return renderField(fieldTree, fieldValue, handleChange, userResolver,
|
|
222
|
-
}
|
|
223
|
-
function resolvePath(tree, path) {
|
|
224
|
-
if (path.length === 0) return tree;
|
|
225
|
-
const parts = path.split(".");
|
|
226
|
-
let current = tree;
|
|
227
|
-
for (const part of parts) {
|
|
228
|
-
if (current === void 0) return void 0;
|
|
229
|
-
const bracketMatch = /^(.+)\[(\d+)\]$/.exec(part);
|
|
230
|
-
if (bracketMatch?.[1] !== void 0 && bracketMatch[2] !== void 0) {
|
|
231
|
-
const arrayField = bracketMatch[1];
|
|
232
|
-
if (current.fields !== void 0) current = current.fields[arrayField];
|
|
233
|
-
if (current?.element !== void 0) current = current.element;
|
|
234
|
-
continue;
|
|
235
|
-
}
|
|
236
|
-
if (current.fields !== void 0) current = current.fields[part];
|
|
237
|
-
else if (current.element !== void 0) current = current.element;
|
|
238
|
-
else return;
|
|
239
|
-
}
|
|
240
|
-
return current;
|
|
241
|
-
}
|
|
242
|
-
function resolveValue(root, path) {
|
|
243
|
-
if (path.length === 0) return root;
|
|
244
|
-
const parts = path.split(".");
|
|
245
|
-
let current = root;
|
|
246
|
-
for (const part of parts) {
|
|
247
|
-
if (typeof current !== "object" || current === null) return void 0;
|
|
248
|
-
const bracketMatch = /^(.+)\[(\d+)\]$/.exec(part);
|
|
249
|
-
if (bracketMatch?.[1] !== void 0 && bracketMatch[2] !== void 0) {
|
|
250
|
-
const key = bracketMatch[1];
|
|
251
|
-
const index = Number(bracketMatch[2]);
|
|
252
|
-
const arr = toRecord(current)[key];
|
|
253
|
-
if (Array.isArray(arr)) current = arr[index];
|
|
254
|
-
else return;
|
|
255
|
-
} else current = toRecord(current)[part];
|
|
256
|
-
}
|
|
257
|
-
return current;
|
|
258
|
-
}
|
|
259
|
-
function setNestedValue(root, path, leafValue) {
|
|
260
|
-
if (path.length === 0) return leafValue;
|
|
261
|
-
const parts = path.split(".");
|
|
262
|
-
const result = isObject(root) ? { ...toRecord(root) } : {};
|
|
263
|
-
let current = result;
|
|
264
|
-
for (let i = 0; i < parts.length; i++) {
|
|
265
|
-
const part = parts[i];
|
|
266
|
-
if (part === void 0) break;
|
|
267
|
-
const isLast = i === parts.length - 1;
|
|
268
|
-
const bracketMatch = /^(.+)\[(\d+)\]$/.exec(part);
|
|
269
|
-
if (bracketMatch?.[1] !== void 0 && bracketMatch[2] !== void 0) {
|
|
270
|
-
const key = bracketMatch[1];
|
|
271
|
-
const index = Number(bracketMatch[2]);
|
|
272
|
-
const existing = current[key];
|
|
273
|
-
const arr = Array.isArray(existing) ? existing.slice() : [];
|
|
274
|
-
if (isLast) arr[index] = leafValue;
|
|
275
|
-
current[key] = arr;
|
|
276
|
-
const nextCurrent = arr[index];
|
|
277
|
-
if (nextCurrent !== void 0 && isObject(nextCurrent)) current = toRecord(nextCurrent);
|
|
278
|
-
} else if (isLast) current[part] = leafValue;
|
|
279
|
-
else {
|
|
280
|
-
const existing = current[part];
|
|
281
|
-
const next = isObject(existing) ? { ...toRecord(existing) } : {};
|
|
282
|
-
current[part] = next;
|
|
283
|
-
current = next;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
return result;
|
|
287
|
-
}
|
|
288
|
-
function isFieldErrorCallback(value) {
|
|
289
|
-
return typeof value === "function";
|
|
240
|
+
return renderField(fieldTree, fieldValue, handleChange, userResolver, makeRenderChild(0), void 0, contextWidgets, 0);
|
|
290
241
|
}
|
|
291
242
|
/**
|
|
292
243
|
* Dispatch Zod errors to per-field onValidationError callbacks.
|
|
@@ -315,6 +266,9 @@ function dispatchFieldErrors(fields, error) {
|
|
|
315
266
|
if (fieldErrors.length > 0 && isFieldErrorCallback(fieldCallback)) fieldCallback({ issues: fieldErrors });
|
|
316
267
|
}
|
|
317
268
|
}
|
|
269
|
+
function isFieldErrorCallback(value) {
|
|
270
|
+
return typeof value === "function";
|
|
271
|
+
}
|
|
318
272
|
function isCallable(value) {
|
|
319
273
|
return typeof value === "function";
|
|
320
274
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { w as SchemaMeta } from "../types-ag2jYLqQ.mjs";
|
|
2
|
+
import { r as ComponentResolver } from "../renderer-DseHeliw.mjs";
|
|
2
3
|
import { WidgetMap } from "./SchemaComponent.mjs";
|
|
3
4
|
import { ReactNode } from "react";
|
|
4
5
|
|
|
@@ -3,7 +3,7 @@ import { SchemaNormalisationError, SchemaRenderError } from "../core/errors.mjs"
|
|
|
3
3
|
import { getRenderFunction, mergeResolvers } from "../core/renderer.mjs";
|
|
4
4
|
import { walk } from "../core/walker.mjs";
|
|
5
5
|
import { headlessResolver } from "./headless.mjs";
|
|
6
|
-
import { isValidElement } from "react";
|
|
6
|
+
import { createElement, isValidElement } from "react";
|
|
7
7
|
import { jsx } from "react/jsx-runtime";
|
|
8
8
|
//#region src/react/SchemaView.tsx
|
|
9
9
|
/**
|
|
@@ -61,7 +61,12 @@ function SchemaView({ schema: schemaInput, ref: refInput, value, fields, meta: c
|
|
|
61
61
|
rootDocument
|
|
62
62
|
});
|
|
63
63
|
const userResolver = resolver !== void 0 ? mergeResolvers(resolver, headlessResolver) : headlessResolver;
|
|
64
|
-
const
|
|
64
|
+
const MAX_SERVER_DEPTH = 10;
|
|
65
|
+
const makeRenderChild = (currentDepth) => (childTree, childValue) => {
|
|
66
|
+
if (currentDepth >= MAX_SERVER_DEPTH) return createElement("fieldset", null, createElement("em", null, `\u21bb ${typeof childTree.meta.description === "string" ? childTree.meta.description : childTree.type === "recursive" ? childTree.refTarget : "schema"} (recursive)`));
|
|
67
|
+
return renderFieldServer(childTree, childValue, userResolver, makeRenderChild(currentDepth + 1), widgets);
|
|
68
|
+
};
|
|
69
|
+
const renderChild = makeRenderChild(0);
|
|
65
70
|
return renderFieldServer(tree, value ?? tree.defaultValue, userResolver, renderChild, widgets);
|
|
66
71
|
}
|
|
67
72
|
function renderFieldServer(tree, value, resolver, renderChild, widgets) {
|
|
@@ -99,13 +104,20 @@ function renderFieldServer(tree, value, resolver, renderChild, widgets) {
|
|
|
99
104
|
tree,
|
|
100
105
|
renderChild: (childTree, childValue) => renderChild(childTree, childValue)
|
|
101
106
|
};
|
|
102
|
-
if (tree.
|
|
103
|
-
if (tree.element !== void 0) props.element = tree.element;
|
|
104
|
-
if (tree.
|
|
105
|
-
if (tree.
|
|
106
|
-
if (tree.
|
|
107
|
-
if (tree.
|
|
108
|
-
if (tree.
|
|
107
|
+
if (tree.type === "enum") props.enumValues = tree.enumValues;
|
|
108
|
+
if (tree.type === "array" && tree.element !== void 0) props.element = tree.element;
|
|
109
|
+
if (tree.type === "object") props.fields = tree.fields;
|
|
110
|
+
if (tree.type === "union" || tree.type === "discriminatedUnion") props.options = tree.options;
|
|
111
|
+
if (tree.type === "discriminatedUnion") props.discriminator = tree.discriminator;
|
|
112
|
+
if (tree.type === "record") props.keyType = tree.keyType;
|
|
113
|
+
if (tree.type === "record") props.valueType = tree.valueType;
|
|
114
|
+
if (tree.type === "tuple") props.prefixItems = tree.prefixItems;
|
|
115
|
+
if (tree.type === "conditional") props.ifClause = tree.ifClause;
|
|
116
|
+
if (tree.type === "conditional" && tree.thenClause !== void 0) props.thenClause = tree.thenClause;
|
|
117
|
+
if (tree.type === "conditional" && tree.elseClause !== void 0) props.elseClause = tree.elseClause;
|
|
118
|
+
if (tree.type === "negation") props.negated = tree.negated;
|
|
119
|
+
if (tree.type === "recursive") props.refTarget = tree.refTarget;
|
|
120
|
+
if (tree.type === "literal") props.literalValues = tree.literalValues;
|
|
109
121
|
try {
|
|
110
122
|
const result = renderFn(props);
|
|
111
123
|
if (result !== void 0 && result !== null) {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { j as WalkedField } from "../types-ag2jYLqQ.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/react/fieldPath.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Resolve a dot-separated path through a WalkedField tree.
|
|
6
|
+
* Supports array index notation: `field[0]`.
|
|
7
|
+
*/
|
|
8
|
+
declare function resolvePath(tree: WalkedField, path: string): WalkedField | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Resolve a dot-separated path through a data value.
|
|
11
|
+
* Supports array index notation: `field[0]`.
|
|
12
|
+
*/
|
|
13
|
+
declare function resolveValue(root: unknown, path: string): unknown;
|
|
14
|
+
/**
|
|
15
|
+
* Set a value at a dot-separated path, producing a new root object.
|
|
16
|
+
* Does not mutate the input — returns a shallow-updated copy at each level.
|
|
17
|
+
*/
|
|
18
|
+
declare function setNestedValue(root: unknown, path: string, leafValue: unknown): unknown;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { resolvePath, resolveValue, setNestedValue };
|