schema-components 1.23.0 → 1.26.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/adapter-MiEFkRVV.d.mts +172 -0
- package/dist/core/adapter.d.mts +2 -141
- package/dist/core/adapter.mjs +39 -5
- package/dist/core/constraints.d.mts +1 -1
- package/dist/core/diagnostics.d.mts +1 -1
- package/dist/core/errors.d.mts +1 -1
- package/dist/core/formats.d.mts +1 -1
- package/dist/core/limits.d.mts +1 -1
- package/dist/core/merge.d.mts +1 -1
- package/dist/core/normalise.d.mts +2 -2
- package/dist/core/ref.d.mts +1 -1
- package/dist/core/ref.mjs +4 -5
- package/dist/core/renderer.d.mts +1 -1
- package/dist/core/swagger2.d.mts +1 -1
- package/dist/core/typeInference.d.mts +1 -1
- package/dist/core/version.d.mts +1 -1
- package/dist/core/walkBuilders.d.mts +2 -2
- package/dist/{diagnostics-BS2kaUyE.d.mts → diagnostics-Cbwak-ZX.d.mts} +1 -1
- package/dist/html/a11y.d.mts +1 -1
- package/dist/html/renderToHtml.d.mts +1 -1
- package/dist/html/renderToHtmlStream.d.mts +1 -1
- package/dist/html/renderers.d.mts +6 -17
- package/dist/html/renderers.mjs +5 -16
- package/dist/html/streamRenderers.d.mts +2 -2
- package/dist/openapi/components.d.mts +1 -1
- package/dist/openapi/components.mjs +2 -2
- package/dist/openapi/parser.d.mts +13 -4
- package/dist/openapi/parser.mjs +59 -33
- package/dist/openapi/resolve.d.mts +1 -1
- package/dist/openapi/resolve.mjs +2 -2
- package/dist/react/SchemaComponent.d.mts +74 -64
- package/dist/react/SchemaComponent.mjs +23 -31
- package/dist/react/SchemaView.d.mts +24 -20
- package/dist/react/SchemaView.mjs +6 -3
- package/dist/react/headless.d.mts +1 -1
- package/dist/react/headlessRenderers.d.mts +1 -1
- package/dist/react/headlessRenderers.mjs +1 -1
- package/dist/{ref-DjLEKa_E.d.mts → ref-TdeMfaV_.d.mts} +1 -1
- package/dist/themes/mantine.d.mts +1 -1
- package/dist/themes/mui.d.mts +1 -1
- package/dist/themes/mui.mjs +1 -1
- package/dist/themes/radix.d.mts +1 -1
- package/dist/themes/shadcn.d.mts +1 -1
- package/package.json +6 -2
- /package/dist/{errors-g_MCTQel.d.mts → errors-DQSIK4n1.d.mts} +0 -0
- /package/dist/{limits-Cw5QZND8.d.mts → limits-DJhgx5Ay.d.mts} +0 -0
- /package/dist/{renderer-CXJ8y0qw.d.mts → renderer-Ul9taFYp.d.mts} +0 -0
- /package/dist/{version-BFTVLsdb.d.mts → version-ZzL5R6cS.d.mts} +0 -0
package/dist/html/renderers.mjs
CHANGED
|
@@ -15,16 +15,11 @@ import { ariaDescribedByAttrs, ariaLabelAttrs, ariaReadonlyAttrs, ariaRequiredAt
|
|
|
15
15
|
* `aria-controls`, `aria-labelledby`, and `htmlFor` references resolve
|
|
16
16
|
* consistently across the React, sync-HTML, and streaming-HTML outputs.
|
|
17
17
|
*
|
|
18
|
-
* The wrapper tolerates an empty path here (returning `sc-`)
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* structured form.
|
|
24
|
-
*
|
|
25
|
-
* TODO(round7-integration): once `renderToHtml` always threads a stable
|
|
26
|
-
* root path (e.g. `"$"`) into the leaf renderers, drop this wrapper and
|
|
27
|
-
* call `fieldDomId` directly so the throw fires as designed.
|
|
18
|
+
* The wrapper tolerates an empty path here (returning `sc-`) so that
|
|
19
|
+
* a leaf renderer at the schema root — `renderToHtml(z.string())` — has
|
|
20
|
+
* a usable id without throwing. Container renderers always thread a
|
|
21
|
+
* non-empty path through `renderChild`, so the empty-id fallback can
|
|
22
|
+
* never produce sibling collisions inside a structured form.
|
|
28
23
|
*/
|
|
29
24
|
function fieldId(path) {
|
|
30
25
|
if (path.length === 0) return "sc-";
|
|
@@ -41,9 +36,6 @@ function fieldId(path) {
|
|
|
41
36
|
* Exported because `streamRenderers.ts` needs to derive identical ids
|
|
42
37
|
* — the panel id on the `<div role="tabpanel">` must match the
|
|
43
38
|
* `aria-controls` on every tab regardless of which pipeline rendered it.
|
|
44
|
-
*
|
|
45
|
-
* TODO(round7-integration): drop the empty-path branch once `renderToHtml`
|
|
46
|
-
* threads a stable root path so `panelIdFor` can be called directly.
|
|
47
39
|
*/
|
|
48
40
|
function panelId(path) {
|
|
49
41
|
if (path.length === 0) return `${fieldId(path)}-panel`;
|
|
@@ -52,9 +44,6 @@ function panelId(path) {
|
|
|
52
44
|
/**
|
|
53
45
|
* Tab id for tab `i` within a discriminated union at `path`. Mirror of
|
|
54
46
|
* `panelId` above — see its comment.
|
|
55
|
-
*
|
|
56
|
-
* TODO(round7-integration): drop the empty-path branch once `renderToHtml`
|
|
57
|
-
* threads a stable root path so `tabIdFor` can be called directly.
|
|
58
47
|
*/
|
|
59
48
|
function tabId(path, i) {
|
|
60
49
|
if (path.length === 0) return `${fieldId(path)}-tab-${String(i)}`;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { j as WalkedField } from "../types-BTB73MB8.mjs";
|
|
2
|
-
import { i as DiagnosticsOptions } from "../diagnostics-
|
|
3
|
-
import { o as HtmlResolver } from "../renderer-
|
|
2
|
+
import { i as DiagnosticsOptions } from "../diagnostics-Cbwak-ZX.mjs";
|
|
3
|
+
import { o as HtmlResolver } from "../renderer-Ul9taFYp.mjs";
|
|
4
4
|
import { HtmlElement } from "./html.mjs";
|
|
5
5
|
|
|
6
6
|
//#region src/html/streamRenderers.d.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { u as FieldOverride, w as SchemaMeta } from "../types-BTB73MB8.mjs";
|
|
2
|
-
import { r as DiagnosticSink } from "../diagnostics-
|
|
2
|
+
import { r as DiagnosticSink } from "../diagnostics-Cbwak-ZX.mjs";
|
|
3
3
|
import { InferParameterOverrides, InferRequestBodyFields, InferResponseFields } from "../core/typeInference.mjs";
|
|
4
4
|
import { WidgetMap } from "../react/SchemaComponent.mjs";
|
|
5
5
|
import { ReactNode } from "react";
|
|
@@ -2,15 +2,15 @@ import { isObject, toRecordOrUndefined } from "../core/guards.mjs";
|
|
|
2
2
|
import { emitDiagnostic } from "../core/diagnostics.mjs";
|
|
3
3
|
import { extractRootMetaFromJson } from "../core/adapter.mjs";
|
|
4
4
|
import { walk } from "../core/walker.mjs";
|
|
5
|
+
import { joinPath, renderField, sanitisePrefix } from "../react/SchemaComponent.mjs";
|
|
5
6
|
import { ApiCallbacks } from "./ApiCallbacks.mjs";
|
|
6
7
|
import { ApiLinks } from "./ApiLinks.mjs";
|
|
7
8
|
import { ApiResponseHeaders } from "./ApiResponseHeaders.mjs";
|
|
8
9
|
import { ApiSecurity } from "./ApiSecurity.mjs";
|
|
9
10
|
import { getExternalDocs, getLinks, getSecurityRequirements, getSecuritySchemes, getXmlInfo, listCallbacks, listWebhooks } from "./parser.mjs";
|
|
10
|
-
import { joinPath, renderField, sanitisePrefix } from "../react/SchemaComponent.mjs";
|
|
11
11
|
import { getParsed, resolveOperationFromParsed, resolveParametersFromParsed, resolveRequestBodyFromParsed, resolveResponseFromParsed, toDoc } from "./resolve.mjs";
|
|
12
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
13
12
|
import { useId } from "react";
|
|
13
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
14
14
|
//#region src/openapi/components.tsx
|
|
15
15
|
/**
|
|
16
16
|
* OpenAPI React components with type-safe generics.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { m as JsonObject } from "../types-BTB73MB8.mjs";
|
|
2
|
-
import { i as DiagnosticsOptions } from "../diagnostics-
|
|
2
|
+
import { i as DiagnosticsOptions } from "../diagnostics-Cbwak-ZX.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/openapi/parser.d.ts
|
|
5
5
|
interface OpenApiDocument {
|
|
@@ -87,17 +87,26 @@ interface LinkInfo {
|
|
|
87
87
|
}
|
|
88
88
|
declare function parseOpenApiDocument(doc: JsonObject): OpenApiDocument;
|
|
89
89
|
declare function getSchema(parsed: OpenApiDocument, ref: string): JsonObject | undefined;
|
|
90
|
-
declare function listOperations(parsed: OpenApiDocument, diagnostics?: DiagnosticsOptions): OperationInfo[];
|
|
90
|
+
declare function listOperations(parsed: OpenApiDocument, diagnostics?: DiagnosticsOptions, seenIds?: Map<string, string>): OperationInfo[];
|
|
91
91
|
declare function getParameters(parsed: OpenApiDocument, path: string, method: string, diagnostics?: DiagnosticsOptions): ParameterInfo[];
|
|
92
92
|
declare function getRequestBody(parsed: OpenApiDocument, path: string, method: string): RequestBodyInfo | undefined;
|
|
93
93
|
declare function getResponses(parsed: OpenApiDocument, path: string, method: string, diagnostics?: DiagnosticsOptions): ResponseInfo[];
|
|
94
94
|
declare function getSecurityRequirements(parsed: OpenApiDocument, path: string, method: string): SecurityRequirement[];
|
|
95
95
|
declare function getSecuritySchemes(parsed: OpenApiDocument): Map<string, SecurityScheme>;
|
|
96
96
|
declare function getResponseHeaders(response: JsonObject, doc?: JsonObject, diagnostics?: DiagnosticsOptions): Map<string, HeaderInfo>;
|
|
97
|
-
declare function listWebhooks(parsed: OpenApiDocument, diagnostics?: DiagnosticsOptions): WebhookInfo[];
|
|
97
|
+
declare function listWebhooks(parsed: OpenApiDocument, diagnostics?: DiagnosticsOptions, seenIds?: Map<string, string>): WebhookInfo[];
|
|
98
|
+
/**
|
|
99
|
+
* Enumerate every operation in the document — both the `paths` map and
|
|
100
|
+
* the OpenAPI 3.1 `webhooks` map — sharing a single `seenIds` cache so
|
|
101
|
+
* cross-list `operationId` collisions surface the same way as same-list
|
|
102
|
+
* collisions. Returns the path-operation list followed by webhook
|
|
103
|
+
* operations (flattened); callers that need the structured webhook
|
|
104
|
+
* grouping should call `listWebhooks` directly.
|
|
105
|
+
*/
|
|
106
|
+
declare function listAllOperations(parsed: OpenApiDocument, diagnostics?: DiagnosticsOptions): OperationInfo[];
|
|
98
107
|
declare function getExternalDocs(obj: JsonObject): ExternalDocs | undefined;
|
|
99
108
|
declare function getXmlInfo(schema: JsonObject): XmlInfo | undefined;
|
|
100
109
|
declare function listCallbacks(parsed: OpenApiDocument, path: string, method: string, diagnostics?: DiagnosticsOptions): CallbackInfo[];
|
|
101
110
|
declare function getLinks(parsed: OpenApiDocument, path: string, method: string, statusCode: string, diagnostics?: DiagnosticsOptions): LinkInfo[];
|
|
102
111
|
//#endregion
|
|
103
|
-
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 };
|
|
112
|
+
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, listAllOperations, listCallbacks, listOperations, listWebhooks, parseOpenApiDocument };
|
package/dist/openapi/parser.mjs
CHANGED
|
@@ -96,11 +96,39 @@ function lookupPathItem(parsed, path) {
|
|
|
96
96
|
if (resolved !== void 0) return resolved;
|
|
97
97
|
return resolvePathItem(parsed, getProperty(getProperty(parsed.doc, "webhooks"), path));
|
|
98
98
|
}
|
|
99
|
-
|
|
99
|
+
/**
|
|
100
|
+
* Record an `operationId` against a shared `seenIds` map and emit a
|
|
101
|
+
* `duplicate-operation-id` diagnostic when a subsequent location reuses
|
|
102
|
+
* the same identifier. Returns the original `operationId` so the caller
|
|
103
|
+
* can pass the value straight onto its `OperationInfo`.
|
|
104
|
+
*
|
|
105
|
+
* When the same map is threaded through `listOperations` and
|
|
106
|
+
* `listWebhooks` (see `listAllOperations`), cross-list collisions
|
|
107
|
+
* between a path operation and a webhook operation surface as the same
|
|
108
|
+
* diagnostic class as same-list collisions.
|
|
109
|
+
*/
|
|
110
|
+
function recordOperationId(operationId, location, pointer, seenIds, diagnostics) {
|
|
111
|
+
if (operationId === void 0) return;
|
|
112
|
+
const firstSeenAt = seenIds.get(operationId);
|
|
113
|
+
if (firstSeenAt !== void 0) {
|
|
114
|
+
emitDiagnostic(diagnostics, {
|
|
115
|
+
code: "duplicate-operation-id",
|
|
116
|
+
message: `operationId "${operationId}" is declared more than once (first at ${firstSeenAt}, again at ${location})`,
|
|
117
|
+
pointer,
|
|
118
|
+
detail: {
|
|
119
|
+
operationId,
|
|
120
|
+
firstSeenAt,
|
|
121
|
+
duplicateAt: location
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
seenIds.set(operationId, location);
|
|
127
|
+
}
|
|
128
|
+
function listOperations(parsed, diagnostics, seenIds = /* @__PURE__ */ new Map()) {
|
|
100
129
|
const operations = [];
|
|
101
130
|
const paths = getProperty(parsed.doc, "paths");
|
|
102
131
|
if (!isObject(paths)) return operations;
|
|
103
|
-
const seenIds = /* @__PURE__ */ new Map();
|
|
104
132
|
for (const [path, rawPathItem] of Object.entries(paths)) {
|
|
105
133
|
const pathItem = resolvePathItem(parsed, rawPathItem, diagnostics);
|
|
106
134
|
if (pathItem === void 0) continue;
|
|
@@ -108,20 +136,7 @@ function listOperations(parsed, diagnostics) {
|
|
|
108
136
|
const operation = getProperty(pathItem, method);
|
|
109
137
|
if (!isObject(operation)) continue;
|
|
110
138
|
const operationId = getString(operation, "operationId");
|
|
111
|
-
|
|
112
|
-
const firstSeenAt = seenIds.get(operationId);
|
|
113
|
-
if (firstSeenAt !== void 0) emitDiagnostic(diagnostics, {
|
|
114
|
-
code: "duplicate-operation-id",
|
|
115
|
-
message: `operationId "${operationId}" is declared more than once (first at ${firstSeenAt}, again at ${method.toUpperCase()} ${path})`,
|
|
116
|
-
pointer: `/paths/${jsonPointerEscape(path)}/${method}/operationId`,
|
|
117
|
-
detail: {
|
|
118
|
-
operationId,
|
|
119
|
-
firstSeenAt,
|
|
120
|
-
duplicateAt: `${method.toUpperCase()} ${path}`
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
else seenIds.set(operationId, `${method.toUpperCase()} ${path}`);
|
|
124
|
-
}
|
|
139
|
+
recordOperationId(operationId, `${method.toUpperCase()} ${path}`, `/paths/${jsonPointerEscape(path)}/${method}/operationId`, seenIds, diagnostics);
|
|
125
140
|
operations.push({
|
|
126
141
|
path,
|
|
127
142
|
method,
|
|
@@ -179,26 +194,21 @@ function extractParameterList(doc, parameters, pointerBase, diagnostics) {
|
|
|
179
194
|
* length — a Reference Object whose target is itself a Reference Object
|
|
180
195
|
* is legal. `resolveRefChain` centralises cycle and depth-cap protection.
|
|
181
196
|
*
|
|
182
|
-
* Cycles and over-deep chains
|
|
183
|
-
*
|
|
184
|
-
* `
|
|
185
|
-
* `
|
|
186
|
-
*
|
|
187
|
-
* they care to distinguish the source.
|
|
188
|
-
*
|
|
189
|
-
* TODO(round7-integration): consider adding dedicated `cyclic-*-ref` /
|
|
190
|
-
* `*-ref-too-deep` codes per node kind to `core/diagnostics.ts` so the
|
|
191
|
-
* kind discriminator on `detail` is not needed. The existing Swagger
|
|
192
|
-
* 2.0 path already uses a dedicated `swagger-cyclic-parameter-ref` for
|
|
193
|
-
* the equivalent failure mode.
|
|
197
|
+
* Cycles and over-deep chains emit a dedicated diagnostic code per node
|
|
198
|
+
* kind (`cyclic-parameter-ref`, `parameter-ref-too-deep`, and the
|
|
199
|
+
* `header` / `link` equivalents), mirroring the existing
|
|
200
|
+
* `swagger-cyclic-parameter-ref` precedent so consumers can pattern-match
|
|
201
|
+
* directly on the code instead of filtering by `detail.kind`.
|
|
194
202
|
*/
|
|
195
203
|
function resolveReferenceObjectChain(doc, node, kind, diagnostics) {
|
|
196
204
|
const kindLabel = kind === "parameter" ? "Parameter Object" : kind === "header" ? "Header Object" : "Link Object";
|
|
205
|
+
const cyclicCode = kind === "parameter" ? "cyclic-parameter-ref" : kind === "header" ? "cyclic-header-ref" : "cyclic-link-ref";
|
|
206
|
+
const tooDeepCode = kind === "parameter" ? "parameter-ref-too-deep" : kind === "header" ? "header-ref-too-deep" : "link-ref-too-deep";
|
|
197
207
|
return resolveRefChain(node, {
|
|
198
208
|
lookup: (ref) => ref.startsWith("#/") ? resolveRefInDoc(doc, ref) : void 0,
|
|
199
209
|
onCycle: (ref) => {
|
|
200
210
|
emitDiagnostic(diagnostics, {
|
|
201
|
-
code:
|
|
211
|
+
code: cyclicCode,
|
|
202
212
|
message: `Cyclic ${kindLabel} $ref "${ref}"`,
|
|
203
213
|
pointer: ref,
|
|
204
214
|
detail: {
|
|
@@ -209,7 +219,7 @@ function resolveReferenceObjectChain(doc, node, kind, diagnostics) {
|
|
|
209
219
|
},
|
|
210
220
|
onDepthExceeded: (ref) => {
|
|
211
221
|
emitDiagnostic(diagnostics, {
|
|
212
|
-
code:
|
|
222
|
+
code: tooDeepCode,
|
|
213
223
|
message: `${kindLabel} $ref chain exceeded the hop cap starting from "${ref}"`,
|
|
214
224
|
pointer: ref,
|
|
215
225
|
detail: {
|
|
@@ -451,7 +461,7 @@ function getResponseHeaders(response, doc, diagnostics) {
|
|
|
451
461
|
}
|
|
452
462
|
return result;
|
|
453
463
|
}
|
|
454
|
-
function listWebhooks(parsed, diagnostics) {
|
|
464
|
+
function listWebhooks(parsed, diagnostics, seenIds = /* @__PURE__ */ new Map()) {
|
|
455
465
|
const result = [];
|
|
456
466
|
const webhooks = getProperty(parsed.doc, "webhooks");
|
|
457
467
|
if (!isObject(webhooks)) return result;
|
|
@@ -462,10 +472,12 @@ function listWebhooks(parsed, diagnostics) {
|
|
|
462
472
|
for (const method of HTTP_METHODS) {
|
|
463
473
|
const operation = getProperty(hookItem, method);
|
|
464
474
|
if (!isObject(operation)) continue;
|
|
475
|
+
const operationId = getString(operation, "operationId");
|
|
476
|
+
recordOperationId(operationId, `${method.toUpperCase()} webhook:${name}`, `/webhooks/${jsonPointerEscape(name)}/${method}/operationId`, seenIds, diagnostics);
|
|
465
477
|
operations.push({
|
|
466
478
|
path: name,
|
|
467
479
|
method,
|
|
468
|
-
operationId
|
|
480
|
+
operationId,
|
|
469
481
|
summary: getString(operation, "summary"),
|
|
470
482
|
description: getString(operation, "description"),
|
|
471
483
|
deprecated: getProperty(operation, "deprecated") === true,
|
|
@@ -479,6 +491,20 @@ function listWebhooks(parsed, diagnostics) {
|
|
|
479
491
|
}
|
|
480
492
|
return result;
|
|
481
493
|
}
|
|
494
|
+
/**
|
|
495
|
+
* Enumerate every operation in the document — both the `paths` map and
|
|
496
|
+
* the OpenAPI 3.1 `webhooks` map — sharing a single `seenIds` cache so
|
|
497
|
+
* cross-list `operationId` collisions surface the same way as same-list
|
|
498
|
+
* collisions. Returns the path-operation list followed by webhook
|
|
499
|
+
* operations (flattened); callers that need the structured webhook
|
|
500
|
+
* grouping should call `listWebhooks` directly.
|
|
501
|
+
*/
|
|
502
|
+
function listAllOperations(parsed, diagnostics) {
|
|
503
|
+
const seenIds = /* @__PURE__ */ new Map();
|
|
504
|
+
const pathOps = listOperations(parsed, diagnostics, seenIds);
|
|
505
|
+
const webhookOps = listWebhooks(parsed, diagnostics, seenIds).flatMap((w) => w.operations);
|
|
506
|
+
return [...pathOps, ...webhookOps];
|
|
507
|
+
}
|
|
482
508
|
function getExternalDocs(obj) {
|
|
483
509
|
const docs = getProperty(obj, "externalDocs");
|
|
484
510
|
if (!isObject(docs)) return void 0;
|
|
@@ -559,4 +585,4 @@ function getLinks(parsed, path, method, statusCode, diagnostics) {
|
|
|
559
585
|
return result;
|
|
560
586
|
}
|
|
561
587
|
//#endregion
|
|
562
|
-
export { getExternalDocs, getLinks, getParameters, getRequestBody, getResponseHeaders, getResponses, getSchema, getSecurityRequirements, getSecuritySchemes, getXmlInfo, listCallbacks, listOperations, listWebhooks, parseOpenApiDocument };
|
|
588
|
+
export { getExternalDocs, getLinks, getParameters, getRequestBody, getResponseHeaders, getResponses, getSchema, getSecurityRequirements, getSecuritySchemes, getXmlInfo, listAllOperations, listCallbacks, listOperations, listWebhooks, parseOpenApiDocument };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as DiagnosticsOptions } from "../diagnostics-
|
|
1
|
+
import { i as DiagnosticsOptions } from "../diagnostics-Cbwak-ZX.mjs";
|
|
2
2
|
import { OpenApiDocument, OperationInfo, ParameterInfo, ResponseInfo, getRequestBody } from "./parser.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/openapi/resolve.d.ts
|
package/dist/openapi/resolve.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { isPrototypePollutingKey } from "../core/uri.mjs";
|
|
|
5
5
|
import { detectOpenApiVersion } from "../core/version.mjs";
|
|
6
6
|
import { o as normaliseOpenApiSchemas, r as documentContainsKeyword } from "../normalise-DCYp06Sr.mjs";
|
|
7
7
|
import { resolveRefChain } from "../core/refChain.mjs";
|
|
8
|
-
import { getParameters, getRequestBody, getResponses,
|
|
8
|
+
import { getParameters, getRequestBody, getResponses, listAllOperations, parseOpenApiDocument } from "./parser.mjs";
|
|
9
9
|
//#region src/openapi/resolve.ts
|
|
10
10
|
/**
|
|
11
11
|
* OpenAPI document resolution and caching.
|
|
@@ -325,7 +325,7 @@ function extractPathItemInfo(pathItem) {
|
|
|
325
325
|
*/
|
|
326
326
|
function resolveOperationFromParsed(parsed, path, method, diagnostics) {
|
|
327
327
|
const pathItemNode = lookupPathItemNode(parsed, path, diagnostics);
|
|
328
|
-
const operation =
|
|
328
|
+
const operation = listAllOperations(parsed).find((op) => op.path === path && op.method === method);
|
|
329
329
|
if (operation === void 0) throw new Error(`Operation not found: ${method.toUpperCase()} ${path}`);
|
|
330
330
|
if (pathItemNode === void 0) throw new Error(`Path item missing for ${method.toUpperCase()} ${path}`);
|
|
331
331
|
return {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { d as FieldOverrides, j as WalkedField, u as FieldOverride, w as SchemaMeta } from "../types-BTB73MB8.mjs";
|
|
2
|
-
import { t as Diagnostic } from "../diagnostics-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { t as Diagnostic } from "../diagnostics-Cbwak-ZX.mjs";
|
|
3
|
+
import { i as SchemaIoSide } from "../adapter-MiEFkRVV.mjs";
|
|
4
|
+
import { t as SchemaError } from "../errors-DQSIK4n1.mjs";
|
|
5
|
+
import { l as RenderProps, r as ComponentResolver } from "../renderer-Ul9taFYp.mjs";
|
|
5
6
|
import { FromJSONSchema, FromJSONSchemaMode, IsSwagger2Doc, PathOfType, RejectUnrepresentableZod, ResolveOpenAPIRef, TypeAtPath, __SchemaInferenceFellBack } from "../core/typeInference.mjs";
|
|
6
7
|
import { z } from "zod";
|
|
7
|
-
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
8
8
|
import { ReactNode } from "react";
|
|
9
|
+
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
9
10
|
|
|
10
11
|
//#region src/react/SchemaComponent.d.ts
|
|
11
12
|
/**
|
|
@@ -65,28 +66,36 @@ type InferSchemaValue<T, Ref extends string | undefined, Mode extends FromJSONSc
|
|
|
65
66
|
type NarrowAtPath<V, P extends string | undefined> = P extends string ? TypeAtPath<V, P> : V;
|
|
66
67
|
/**
|
|
67
68
|
* Public alias mapping a schema input to the rendered value type.
|
|
68
|
-
* Use to narrow a runtime callback inside the body of an `onChange`
|
|
69
|
-
* handler:
|
|
70
|
-
*
|
|
71
|
-
* ```tsx
|
|
72
|
-
* <SchemaComponent
|
|
73
|
-
* schema={userSchema}
|
|
74
|
-
* onChange={(v) => {
|
|
75
|
-
* const user = v as InferredOutputValue<typeof userSchema>;
|
|
76
|
-
* // ...narrowly typed access on `user`
|
|
77
|
-
* }}
|
|
78
|
-
* />
|
|
79
|
-
* ```
|
|
80
69
|
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
70
|
+
* Picks the OUTPUT side (server → client) of every transform / pipe /
|
|
71
|
+
* codec. For an `<SchemaComponent io="output">` or `<SchemaView
|
|
72
|
+
* io="output">` (both defaults), this is the inferred shape of
|
|
73
|
+
* `value` and the parameter of `onChange`.
|
|
85
74
|
*/
|
|
86
75
|
type InferredOutputValue<T, Ref extends string | undefined = undefined, P extends string | undefined = undefined> = NarrowAtPath<InferSchemaValue<T, Ref, "output">, P>;
|
|
87
|
-
/**
|
|
76
|
+
/**
|
|
77
|
+
* Companion to {@link InferredOutputValue} for `"input"`-mode shapes.
|
|
78
|
+
*
|
|
79
|
+
* Picks the INPUT side (client → server) of every transform / pipe /
|
|
80
|
+
* codec. Surfaces as the inferred shape of `value` / `onChange` when
|
|
81
|
+
* a consumer renders `<SchemaComponent io="input">`. For JSON Schema
|
|
82
|
+
* inputs with `readOnly`/`writeOnly` annotations, the INPUT mode
|
|
83
|
+
* omits properties marked `readOnly: true`.
|
|
84
|
+
*/
|
|
88
85
|
type InferredInputValue<T, Ref extends string | undefined = undefined, P extends string | undefined = undefined> = NarrowAtPath<InferSchemaValue<T, Ref, "input">, P>;
|
|
89
|
-
|
|
86
|
+
/**
|
|
87
|
+
* Resolve the schema-driven value type for either I/O direction.
|
|
88
|
+
*
|
|
89
|
+
* Thin convenience over {@link InferredOutputValue} /
|
|
90
|
+
* {@link InferredInputValue} so consumers that decide between the
|
|
91
|
+
* two at the type level (e.g. a generic wrapper component) can pass
|
|
92
|
+
* the chosen direction as a type argument rather than branch on it
|
|
93
|
+
* with conditional types. Falls back to `unknown` when the schema's
|
|
94
|
+
* value type cannot be statically inferred, identical to the
|
|
95
|
+
* underlying helpers.
|
|
96
|
+
*/
|
|
97
|
+
type InferredValue<T, Ref extends string | undefined = undefined, P extends string | undefined = undefined, Mode extends SchemaIoSide = "output"> = NarrowAtPath<InferSchemaValue<T, Ref, Mode>, P>;
|
|
98
|
+
interface SchemaComponentProps<T = unknown, Ref extends string | undefined = undefined, P extends string | undefined = undefined, Mode extends SchemaIoSide = "output"> {
|
|
90
99
|
/**
|
|
91
100
|
* Zod schema, JSON Schema object, or OpenAPI document.
|
|
92
101
|
*
|
|
@@ -116,56 +125,57 @@ interface SchemaComponentProps<T = unknown, Ref extends string | undefined = und
|
|
|
116
125
|
*/
|
|
117
126
|
path?: P;
|
|
118
127
|
/**
|
|
119
|
-
*
|
|
128
|
+
* Which side of every transform / pipe / codec to render.
|
|
120
129
|
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
130
|
+
* - `"output"` (default) — renderer draws the OUTPUT side of the
|
|
131
|
+
* schema. For a `z.codec(z.string(), z.number(), …)` chain
|
|
132
|
+
* this renders a number input. `value` and `onChange` therefore
|
|
133
|
+
* carry the OUTPUT shape, and `validate` runs `safeEncode`
|
|
134
|
+
* (the reverse direction) so user-supplied OUTPUT values are
|
|
135
|
+
* validated against the codec.
|
|
136
|
+
* - `"input"` — renderer draws the INPUT side instead. For the
|
|
137
|
+
* same codec this renders a string input, `value` and
|
|
138
|
+
* `onChange` carry the INPUT shape, and `validate` runs
|
|
139
|
+
* `safeParse` (the forward direction).
|
|
140
|
+
*
|
|
141
|
+
* The choice is propagated through `normaliseSchema` →
|
|
142
|
+
* `normaliseZod4` → `z.toJSONSchema(..., { io })` so a single
|
|
143
|
+
* source of truth drives both the rendered JSON Schema shape and
|
|
144
|
+
* the validation direction. Has no effect for plain JSON Schema
|
|
145
|
+
* or OpenAPI inputs — those advertise a single canonical shape.
|
|
146
|
+
*/
|
|
147
|
+
io?: Mode;
|
|
148
|
+
/**
|
|
149
|
+
* Current value to render. Typed against `InferSchemaValue<T,
|
|
150
|
+
* Ref, Mode>` so the prop tracks the schema's inferred shape for
|
|
151
|
+
* the chosen `io` direction. Narrowed further by `P` when a
|
|
152
|
+
* `path` is supplied (currently type-level only — see the JSDoc
|
|
153
|
+
* on {@link SchemaComponentProps.path}).
|
|
154
|
+
*
|
|
155
|
+
* Falls back to `unknown` when the schema's value type cannot be
|
|
156
|
+
* statically inferred (runtime `Record<string, unknown>` JSON
|
|
157
|
+
* Schemas, OpenAPI documents without a ref, etc.), so untyped
|
|
158
|
+
* call sites still compile.
|
|
159
|
+
*
|
|
160
|
+
* Use {@link InferredOutputValue} or {@link InferredInputValue}
|
|
161
|
+
* to narrow a value declared at the call site:
|
|
126
162
|
*
|
|
127
163
|
* ```tsx
|
|
128
164
|
* const user: InferredOutputValue<typeof userSchema> = { ... };
|
|
129
165
|
* <SchemaComponent schema={userSchema} value={user} readOnly />
|
|
130
166
|
* ```
|
|
131
|
-
*
|
|
132
|
-
* The narrowing is fully expressible through the helper alias
|
|
133
|
-
* without forcing every existing caller to update their value
|
|
134
|
-
* shapes for `exactOptionalPropertyTypes` / enum literal widening.
|
|
135
|
-
*
|
|
136
|
-
* TODO(round7-integration): promote to
|
|
137
|
-
* `NarrowAtPath<InferSchemaValue<T, Ref, "output">, P>` once the
|
|
138
|
-
* round-7 test fixtures (headless union, discriminated union,
|
|
139
|
-
* schemaview equivalence, type-inference issue fixes) are
|
|
140
|
-
* migrated to either narrow their fixtures or accept the loose
|
|
141
|
-
* boundary. The retype cascades through call sites that
|
|
142
|
-
* intentionally pass invalid values to exercise fallback paths
|
|
143
|
-
* (`value={undefined}`, off-discriminator values, etc.) and
|
|
144
|
-
* through fixtures whose enum/literal types widen at the call
|
|
145
|
-
* site. Coordinated migration is required.
|
|
146
167
|
*/
|
|
147
|
-
value?:
|
|
168
|
+
value?: NarrowAtPath<InferSchemaValue<T, Ref, Mode>, P>;
|
|
148
169
|
/**
|
|
149
|
-
* Called when the value changes (editable fields).
|
|
170
|
+
* Called when the value changes (editable fields). The parameter
|
|
171
|
+
* shares the same shape as {@link SchemaComponentProps.value} so
|
|
172
|
+
* a controlled component can round-trip the value through React
|
|
173
|
+
* state without re-shaping.
|
|
150
174
|
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
* propagates `unknown` values and a narrow contravariant callback
|
|
154
|
-
* signature is not assignable from an `unknown`-emitting source
|
|
155
|
-
* without an unsafe boundary cast. The {@link InferredInputValue}
|
|
156
|
-
* alias is the recommended way for callers to narrow on the
|
|
157
|
-
* consumer side — `onChange={(v) => { const u = v as InferredInputValue<typeof schema>; ... }}`.
|
|
158
|
-
*
|
|
159
|
-
* TODO(round7-integration): promote to
|
|
160
|
-
* `(value: NarrowAtPath<InferSchemaValue<T, Ref, "input">, P>) => void`
|
|
161
|
-
* alongside the `value` retype. The contravariant boundary needs
|
|
162
|
-
* an internal cast at the only call site (`onChange?.(nextValue)`
|
|
163
|
-
* in `handleChange`) that the project's no-`as` rule disallows
|
|
164
|
-
* without explicit justification. The right place to introduce
|
|
165
|
-
* the cast is a tiny typed boundary helper accompanied by the
|
|
166
|
-
* fixture migration noted above.
|
|
175
|
+
* Falls back to `unknown` for schemas whose value type cannot be
|
|
176
|
+
* statically inferred — see {@link SchemaComponentProps.value}.
|
|
167
177
|
*/
|
|
168
|
-
onChange?: (value:
|
|
178
|
+
onChange?: (value: NarrowAtPath<InferSchemaValue<T, Ref, Mode>, P>) => void;
|
|
169
179
|
/** Run schema.safeParse() on change and surface errors via onValidationError. */
|
|
170
180
|
validate?: boolean;
|
|
171
181
|
/** Called with the ZodError when validation fails. */
|
|
@@ -196,7 +206,7 @@ interface SchemaComponentProps<T = unknown, Ref extends string | undefined = und
|
|
|
196
206
|
*/
|
|
197
207
|
idPrefix?: string;
|
|
198
208
|
}
|
|
199
|
-
declare function SchemaComponent<T = unknown, Ref extends string | undefined = undefined, P extends string | undefined = undefined>(props: SchemaComponentProps<T, Ref, P>): ReactNode;
|
|
209
|
+
declare function SchemaComponent<T = unknown, Ref extends string | undefined = undefined, P extends string | undefined = undefined, Mode extends SchemaIoSide = "output">(props: SchemaComponentProps<T, Ref, P, Mode>): ReactNode;
|
|
200
210
|
/**
|
|
201
211
|
* Append a child path suffix to a parent path. When the suffix is omitted
|
|
202
212
|
* (e.g. transparent wrappers like union options), the parent path is
|
|
@@ -255,4 +265,4 @@ declare function SchemaField<T = unknown, Ref extends string | undefined = undef
|
|
|
255
265
|
onValidationError
|
|
256
266
|
}: SchemaFieldProps<T, Ref, P>): ReactNode;
|
|
257
267
|
//#endregion
|
|
258
|
-
export { InferredInputValue, InferredOutputValue, SchemaComponent, SchemaComponentProps, SchemaField, SchemaFieldProps, SchemaProvider, WidgetMap, joinPath, registerWidget, renderField, sanitisePrefix };
|
|
268
|
+
export { InferredInputValue, InferredOutputValue, InferredValue, SchemaComponent, SchemaComponentProps, SchemaField, SchemaFieldProps, SchemaProvider, WidgetMap, joinPath, registerWidget, renderField, sanitisePrefix };
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { isObject, toRecordOrUndefined } from "../core/guards.mjs";
|
|
3
3
|
import "../core/limits.mjs";
|
|
4
4
|
import { SchemaFieldError, SchemaNormalisationError, SchemaRenderError } from "../core/errors.mjs";
|
|
5
|
-
import { normaliseSchema } from "../core/adapter.mjs";
|
|
5
|
+
import { isCodecSchema, normaliseSchema } from "../core/adapter.mjs";
|
|
6
6
|
import { buildRenderProps, getRenderFunction, mergeResolvers } from "../core/renderer.mjs";
|
|
7
7
|
import { walk } from "../core/walker.mjs";
|
|
8
8
|
import { headlessResolver } from "./headless.mjs";
|
|
9
9
|
import { resolvePath, resolveValue, setNestedValue } from "./fieldPath.mjs";
|
|
10
10
|
import { z } from "zod";
|
|
11
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
12
11
|
import { createContext, isValidElement, useCallback, useContext, useId, useMemo } from "react";
|
|
12
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
13
13
|
//#region src/react/SchemaComponent.tsx
|
|
14
14
|
/**
|
|
15
15
|
* <SchemaComponent> — renders UI from Zod, JSON Schema, or OpenAPI schemas.
|
|
@@ -48,7 +48,7 @@ function registerWidget(name, render) {
|
|
|
48
48
|
globalWidgets.set(name, render);
|
|
49
49
|
}
|
|
50
50
|
function SchemaComponent(props) {
|
|
51
|
-
const { schema: schemaInput, ref: refInput, value, onChange, validate, onValidationError, onError, onDiagnostic, strict, fields, meta: componentMeta, readOnly, writeOnly, description, widgets: instanceWidgets, idPrefix } = props;
|
|
51
|
+
const { schema: schemaInput, ref: refInput, io, value, onChange, validate, onValidationError, onError, onDiagnostic, strict, fields, meta: componentMeta, readOnly, writeOnly, description, widgets: instanceWidgets, idPrefix } = props;
|
|
52
52
|
const userResolver = useContext(UserResolverContext);
|
|
53
53
|
const contextWidgets = useContext(WidgetsContext);
|
|
54
54
|
const generatedId = useId();
|
|
@@ -74,7 +74,10 @@ function SchemaComponent(props) {
|
|
|
74
74
|
let rootMeta;
|
|
75
75
|
let rootDocument;
|
|
76
76
|
try {
|
|
77
|
-
const normalised = normaliseSchema(schemaInput, refInput, diagnostics !== void 0
|
|
77
|
+
const normalised = normaliseSchema(schemaInput, refInput, diagnostics !== void 0 || io !== void 0 ? {
|
|
78
|
+
...diagnostics !== void 0 ? { diagnostics } : {},
|
|
79
|
+
...io !== void 0 ? { io } : {}
|
|
80
|
+
} : void 0);
|
|
78
81
|
jsonSchema = normalised.jsonSchema;
|
|
79
82
|
zodSchema = normalised.zodSchema;
|
|
80
83
|
rootMeta = normalised.rootMeta;
|
|
@@ -92,7 +95,7 @@ function SchemaComponent(props) {
|
|
|
92
95
|
if (validate) {
|
|
93
96
|
let error;
|
|
94
97
|
try {
|
|
95
|
-
error = runValidation(zodSchema, jsonSchema, nextValue, onDiagnostic);
|
|
98
|
+
error = runValidation(zodSchema, jsonSchema, nextValue, io, onDiagnostic);
|
|
96
99
|
} catch (err) {
|
|
97
100
|
const normalised = err instanceof SchemaNormalisationError ? err : new SchemaNormalisationError(err instanceof Error ? err.message : "Fallback validation failed", schemaInput, "zod-conversion-failed", void 0, err);
|
|
98
101
|
if (onError !== void 0) {
|
|
@@ -106,11 +109,12 @@ function SchemaComponent(props) {
|
|
|
106
109
|
dispatchFieldErrors(fieldsRecord, error);
|
|
107
110
|
}
|
|
108
111
|
}
|
|
109
|
-
onChange
|
|
112
|
+
if (onChange !== void 0) onChange(nextValue);
|
|
110
113
|
}, [
|
|
111
114
|
validate,
|
|
112
115
|
zodSchema,
|
|
113
116
|
jsonSchema,
|
|
117
|
+
io,
|
|
114
118
|
onChange,
|
|
115
119
|
onValidationError,
|
|
116
120
|
fieldsRecord,
|
|
@@ -174,10 +178,19 @@ function sanitisePrefix(value) {
|
|
|
174
178
|
* to surface somewhere — diagnostics if the consumer opted in, an error
|
|
175
179
|
* otherwise — so the caller can route it through `onError` / an error
|
|
176
180
|
* boundary rather than have validation quietly disappear.
|
|
181
|
+
*
|
|
182
|
+
* The `io` argument mirrors the prop on `<SchemaComponent>` and
|
|
183
|
+
* `<SchemaView>`. It determines which Zod entry point validates a
|
|
184
|
+
* codec: `safeEncode` for the OUTPUT side (the default, matching the
|
|
185
|
+
* renderer's default direction), `safeParse` for the INPUT side. For
|
|
186
|
+
* non-codec schemas the choice is irrelevant — both `safeEncode` and
|
|
187
|
+
* `safeParse` behave identically — so `safeParse` is used
|
|
188
|
+
* unconditionally.
|
|
177
189
|
*/
|
|
178
|
-
function runValidation(zodSchema, jsonSchema, value, onDiagnostic) {
|
|
190
|
+
function runValidation(zodSchema, jsonSchema, value, io, onDiagnostic) {
|
|
179
191
|
if (zodSchema !== void 0 && isObject(zodSchema)) {
|
|
180
|
-
const
|
|
192
|
+
const resolvedIo = io ?? "output";
|
|
193
|
+
const validateFn = isCodecSchema(zodSchema) && resolvedIo === "output" ? zodSchema.safeEncode : zodSchema.safeParse;
|
|
181
194
|
if (isCallable(validateFn)) {
|
|
182
195
|
const result = validateFn(value);
|
|
183
196
|
if (isObject(result) && "success" in result && result.success !== true) return result.error;
|
|
@@ -270,7 +283,7 @@ function SchemaField({ path, schema: schemaInput, ref: refInput, value, onChange
|
|
|
270
283
|
const handleChange = useCallback((nextFieldValue) => {
|
|
271
284
|
const newRootValue = setNestedValue(value, path, nextFieldValue);
|
|
272
285
|
if (validate) {
|
|
273
|
-
const error = runValidation(zodSchema, jsonSchema, newRootValue);
|
|
286
|
+
const error = runValidation(zodSchema, jsonSchema, newRootValue, void 0);
|
|
274
287
|
if (error !== void 0) onValidationError?.(error);
|
|
275
288
|
}
|
|
276
289
|
onChange?.(newRootValue);
|
|
@@ -330,26 +343,5 @@ function isFieldErrorCallback(value) {
|
|
|
330
343
|
function isCallable(value) {
|
|
331
344
|
return typeof value === "function";
|
|
332
345
|
}
|
|
333
|
-
/**
|
|
334
|
-
* True when `value` is a Zod schema implemented as a codec.
|
|
335
|
-
*
|
|
336
|
-
* Detection looks for `"$ZodCodec"` in the schema's `_zod.traits`
|
|
337
|
-
* Set, mirroring the runtime detection used inside
|
|
338
|
-
* `core/adapter.ts` (`isCodecSchema` there) and Zod's own
|
|
339
|
-
* `isTransforming` helper. Duplicated here rather than imported
|
|
340
|
-
* because adapter.ts does not export the helper and is outside this
|
|
341
|
-
* fix-cycle's owned files.
|
|
342
|
-
*
|
|
343
|
-
* TODO(round7-integration): replace with an `import` once
|
|
344
|
-
* `isCodecSchema` is exported from `core/adapter.ts` (or promoted to
|
|
345
|
-
* `core/guards.ts`) by a coordinating commit.
|
|
346
|
-
*/
|
|
347
|
-
function isCodecSchema(value) {
|
|
348
|
-
const zod = getProperty(value, "_zod");
|
|
349
|
-
if (!isObject(zod)) return false;
|
|
350
|
-
const traits = zod.traits;
|
|
351
|
-
if (traits instanceof Set) return traits.has("$ZodCodec");
|
|
352
|
-
return false;
|
|
353
|
-
}
|
|
354
346
|
//#endregion
|
|
355
347
|
export { SchemaComponent, SchemaField, SchemaProvider, joinPath, registerWidget, renderField, sanitisePrefix };
|