schema-components 1.28.2 → 2.0.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.
Files changed (105) hide show
  1. package/README.md +38 -16
  2. package/dist/core/adapter.d.mts +213 -3
  3. package/dist/core/adapter.mjs +21 -2
  4. package/dist/core/constraintHint.d.mts +15 -0
  5. package/dist/core/constraintHint.mjs +24 -0
  6. package/dist/core/constraints.d.mts +34 -2
  7. package/dist/core/constraints.mjs +33 -1
  8. package/dist/core/cssClasses.d.mts +1 -0
  9. package/dist/core/diagnostics.d.mts +1 -1
  10. package/dist/core/errors.d.mts +1 -1
  11. package/dist/core/errors.mjs +22 -12
  12. package/dist/core/fieldOrder.d.mts +1 -1
  13. package/dist/core/formats.d.mts +7 -1
  14. package/dist/core/formats.mjs +6 -0
  15. package/dist/core/idPath.d.mts +35 -5
  16. package/dist/core/idPath.mjs +79 -7
  17. package/dist/core/inferValue.d.mts +2 -0
  18. package/dist/core/inferValue.mjs +1 -0
  19. package/dist/core/limits.d.mts +1 -1
  20. package/dist/core/limits.mjs +6 -0
  21. package/dist/core/merge.d.mts +22 -1
  22. package/dist/core/merge.mjs +66 -3
  23. package/dist/core/normalise.d.mts +17 -2
  24. package/dist/core/normalise.mjs +1 -1
  25. package/dist/core/openapi30.mjs +1 -1
  26. package/dist/core/openapiConstants.d.mts +1 -0
  27. package/dist/core/ref.d.mts +1 -1
  28. package/dist/core/refChain.d.mts +3 -4
  29. package/dist/core/refChain.mjs +2 -3
  30. package/dist/core/renderer.d.mts +199 -2
  31. package/dist/core/renderer.mjs +5 -0
  32. package/dist/core/swagger2.d.mts +1 -1
  33. package/dist/core/swagger2.mjs +1 -1
  34. package/dist/core/typeInference.d.mts +3 -3
  35. package/dist/core/types.d.mts +1 -1
  36. package/dist/core/types.mjs +17 -0
  37. package/dist/core/unionMatch.d.mts +1 -1
  38. package/dist/core/uri.d.mts +12 -4
  39. package/dist/core/uri.mjs +30 -4
  40. package/dist/core/version.d.mts +1 -1
  41. package/dist/core/walkBuilders.d.mts +63 -6
  42. package/dist/core/walkBuilders.mjs +33 -1
  43. package/dist/core/walker.d.mts +14 -1
  44. package/dist/core/walker.mjs +18 -0
  45. package/dist/{diagnostics-Cbwak-ZX.d.mts → diagnostics-BTrm3O6J.d.mts} +9 -1
  46. package/dist/{errors-DQSIK4n1.d.mts → errors-Dki7tji4.d.mts} +23 -13
  47. package/dist/html/a11y.d.mts +3 -7
  48. package/dist/html/a11y.mjs +1 -16
  49. package/dist/html/html.d.mts +11 -0
  50. package/dist/html/html.mjs +11 -0
  51. package/dist/html/renderToHtml.d.mts +45 -12
  52. package/dist/html/renderToHtml.mjs +20 -4
  53. package/dist/html/renderToHtmlStream.d.mts +63 -18
  54. package/dist/html/renderToHtmlStream.mjs +34 -8
  55. package/dist/html/renderers.d.mts +6 -31
  56. package/dist/html/renderers.mjs +45 -91
  57. package/dist/html/streamRenderers.d.mts +31 -3
  58. package/dist/html/streamRenderers.mjs +41 -8
  59. package/dist/inferValue-PPXWJpbN.d.mts +77 -0
  60. package/dist/{limits-DJhgx5Ay.d.mts → limits-x4OiyJxh.d.mts} +6 -0
  61. package/dist/{normalise-Db1xaxgx.mjs → normalise-DB-Xtjmn.mjs} +43 -2
  62. package/dist/openapi/ApiCallbacks.d.mts +13 -1
  63. package/dist/openapi/ApiCallbacks.mjs +7 -0
  64. package/dist/openapi/ApiLinks.d.mts +13 -1
  65. package/dist/openapi/ApiLinks.mjs +7 -0
  66. package/dist/openapi/ApiResponseHeaders.d.mts +13 -1
  67. package/dist/openapi/ApiResponseHeaders.mjs +7 -0
  68. package/dist/openapi/ApiSecurity.d.mts +14 -1
  69. package/dist/openapi/ApiSecurity.mjs +29 -8
  70. package/dist/openapi/bundle.d.mts +31 -0
  71. package/dist/openapi/components.d.mts +135 -20
  72. package/dist/openapi/components.mjs +90 -15
  73. package/dist/openapi/parser.d.mts +140 -13
  74. package/dist/openapi/parser.mjs +84 -12
  75. package/dist/openapi/resolve.d.mts +42 -47
  76. package/dist/openapi/resolve.mjs +62 -56
  77. package/dist/react/SchemaComponent.d.mts +90 -88
  78. package/dist/react/SchemaComponent.mjs +74 -2
  79. package/dist/react/SchemaErrorBoundary.d.mts +18 -1
  80. package/dist/react/SchemaErrorBoundary.mjs +13 -1
  81. package/dist/react/SchemaView.d.mts +39 -11
  82. package/dist/react/SchemaView.mjs +23 -6
  83. package/dist/react/a11y.d.mts +74 -7
  84. package/dist/react/a11y.mjs +67 -6
  85. package/dist/react/fieldPath.d.mts +16 -1
  86. package/dist/react/fieldPath.mjs +25 -1
  87. package/dist/react/fieldShell.d.mts +49 -0
  88. package/dist/react/fieldShell.mjs +37 -0
  89. package/dist/react/headless.d.mts +1 -1
  90. package/dist/react/headlessRenderers.d.mts +13 -2
  91. package/dist/react/headlessRenderers.mjs +134 -54
  92. package/dist/{ref-TdeMfaV_.d.mts → ref-DdsbekXX.d.mts} +33 -1
  93. package/dist/themes/mantine.d.mts +54 -12
  94. package/dist/themes/mantine.mjs +195 -140
  95. package/dist/themes/mui.d.mts +64 -11
  96. package/dist/themes/mui.mjs +277 -213
  97. package/dist/themes/radix.d.mts +67 -15
  98. package/dist/themes/radix.mjs +235 -170
  99. package/dist/themes/shadcn.d.mts +25 -1
  100. package/dist/themes/shadcn.mjs +112 -91
  101. package/dist/{types-BTB73MB8.d.mts → types-BrYbjC7_.d.mts} +30 -0
  102. package/dist/{version-ZzL5R6cS.d.mts → version-DL8U5RuA.d.mts} +6 -0
  103. package/package.json +8 -1
  104. package/dist/adapter-DqlAnZ_w.d.mts +0 -172
  105. package/dist/renderer-Ul9taFYp.d.mts +0 -169
@@ -1,7 +1,7 @@
1
- import { u as FieldOverride, w as SchemaMeta } from "../types-BTB73MB8.mjs";
2
- import { r as DiagnosticSink } from "../diagnostics-Cbwak-ZX.mjs";
3
- import { InferParameterOverrides, InferRequestBodyFields, InferResponseFields } from "../core/typeInference.mjs";
4
- import { WidgetMap } from "../react/SchemaComponent.mjs";
1
+ import { u as FieldOverride, w as SchemaMeta } from "../types-BrYbjC7_.mjs";
2
+ import { r as DiagnosticSink } from "../diagnostics-BTrm3O6J.mjs";
3
+ import { WidgetMap } from "../core/renderer.mjs";
4
+ import { InferParameterOverrides, InferRequestBodyFields, InferResponseFields, OpenAPIRequestBodyType, OpenAPIResponseType } from "../core/typeInference.mjs";
5
5
  import { ReactNode } from "react";
6
6
 
7
7
  //#region src/openapi/components.d.ts
@@ -168,13 +168,35 @@ interface ApiDiagnosticsProps {
168
168
  onDiagnostic?: DiagnosticSink;
169
169
  strict?: boolean;
170
170
  }
171
- interface ApiOperationProps<Doc = unknown, Path extends PathKeysOf<Doc> = PathKeysOf<Doc>, Method extends MethodKeysOf<Doc, Path> = MethodKeysOf<Doc, Path>, ContentType extends RequestContentTypesOf<Doc, Path, Method> = RequestContentTypesOf<Doc, Path, Method>> extends ApiDiagnosticsProps {
171
+ /**
172
+ * Props accepted by {@link ApiOperation}.
173
+ *
174
+ * @group OpenAPI
175
+ */
176
+ interface ApiOperationProps<Doc = unknown, Path extends PathKeysOf<Doc> = PathKeysOf<Doc>, Method extends MethodKeysOf<Doc, Path> = MethodKeysOf<Doc, Path>, ContentType extends RequestContentTypesOf<Doc, Path, Method> = RequestContentTypesOf<Doc, Path, Method>, ResponseStatus extends StatusKeysOf<Doc, Path, Method> = StatusKeysOf<Doc, Path, Method>, ResponseContentType extends ResponseContentTypesOf<Doc, Path, Method, ResponseStatus> = ResponseContentTypesOf<Doc, Path, Method, ResponseStatus>> extends ApiDiagnosticsProps {
172
177
  schema: Doc;
173
178
  path: Path;
174
179
  method: Method;
175
- requestBodyValue?: unknown;
176
- onRequestBodyChange?: (value: unknown) => void;
177
- responseValue?: unknown;
180
+ /**
181
+ * Current request body value. Inferred from the operation's
182
+ * request body schema via {@link OpenAPIRequestBodyType} so a
183
+ * typed `schema` argument drives the rendered value's shape.
184
+ */
185
+ requestBodyValue?: OpenAPIRequestBodyType<Doc, Path & string, Method & string, ContentType & string>;
186
+ /**
187
+ * Called when the request body value changes. Parameter type
188
+ * mirrors {@link ApiOperationProps.requestBodyValue}.
189
+ */
190
+ onRequestBodyChange?: (value: OpenAPIRequestBodyType<Doc, Path & string, Method & string, ContentType & string>) => void;
191
+ /**
192
+ * Current response value. Inferred via {@link OpenAPIResponseType}
193
+ * from the operation's response schema for the supplied
194
+ * `responseStatus` (defaulting to the union of declared statuses)
195
+ * and `responseContentType` (defaulting to the union of declared
196
+ * media types). The same value is rendered against every response
197
+ * card the component emits.
198
+ */
199
+ responseValue?: OpenAPIResponseType<Doc, Path & string, Method & string, ResponseStatus & string, ResponseContentType & string>;
178
200
  meta?: SchemaMeta;
179
201
  /**
180
202
  * Media type whose request body schema drives `requestBodyFields`
@@ -185,11 +207,44 @@ interface ApiOperationProps<Doc = unknown, Path extends PathKeysOf<Doc> = PathKe
185
207
  * same precision as `<ApiRequestBody>`.
186
208
  */
187
209
  requestBodyContentType?: ContentType;
210
+ /**
211
+ * Status code whose response schema drives `responseValue`
212
+ * inference. Defaults to the union of declared statuses so
213
+ * callers can omit it; supply explicitly to narrow inference to
214
+ * a specific response (e.g. `"200"`).
215
+ */
216
+ responseStatus?: ResponseStatus;
217
+ /**
218
+ * Media type whose response schema drives `responseValue`
219
+ * inference. Defaults to the union of declared content types so
220
+ * callers can omit it; supply explicitly to narrow inference to
221
+ * a specific media type.
222
+ */
223
+ responseContentType?: ResponseContentType;
188
224
  requestBodyFields?: Doc extends Record<string, unknown> ? InferRequestBodyFields<Doc, Path & string, Method & string, ContentType & string> : Record<string, FieldOverride>;
189
225
  /** Instance-scoped widgets. */
190
226
  widgets?: WidgetMap;
191
227
  }
192
- declare function ApiOperation<Doc = unknown, Path extends PathKeysOf<Doc> = PathKeysOf<Doc>, Method extends MethodKeysOf<Doc, Path> = MethodKeysOf<Doc, Path>, ContentType extends RequestContentTypesOf<Doc, Path, Method> = RequestContentTypesOf<Doc, Path, Method>>({
228
+ /**
229
+ * Render a single OpenAPI operation — header, parameters, request body,
230
+ * responses, callbacks, security, and external docs — picked out of a
231
+ * supplied document by `path` and `method`.
232
+ *
233
+ * When `schema` is typed `as const`, `requestBodyFields` autocomplete
234
+ * resolves from the operation's request body schema. The component
235
+ * works with OpenAPI 2.0, 3.0, and 3.1 inputs (Swagger 2.0 documents
236
+ * are normalised to 3.1 internally) and also resolves OpenAPI 3.1
237
+ * webhooks under the same code path.
238
+ *
239
+ * @group OpenAPI
240
+ * @example
241
+ * ```tsx
242
+ * import { ApiOperation } from "schema-components/openapi/components";
243
+ *
244
+ * <ApiOperation schema={petStore} path="/pets" method="post" />
245
+ * ```
246
+ */
247
+ declare function ApiOperation<Doc = unknown, Path extends PathKeysOf<Doc> = PathKeysOf<Doc>, Method extends MethodKeysOf<Doc, Path> = MethodKeysOf<Doc, Path>, ContentType extends RequestContentTypesOf<Doc, Path, Method> = RequestContentTypesOf<Doc, Path, Method>, ResponseStatus extends StatusKeysOf<Doc, Path, Method> = StatusKeysOf<Doc, Path, Method>, ResponseContentType extends ResponseContentTypesOf<Doc, Path, Method, ResponseStatus> = ResponseContentTypesOf<Doc, Path, Method, ResponseStatus>>({
193
248
  schema: doc,
194
249
  path,
195
250
  method,
@@ -201,7 +256,12 @@ declare function ApiOperation<Doc = unknown, Path extends PathKeysOf<Doc> = Path
201
256
  widgets,
202
257
  onDiagnostic,
203
258
  strict
204
- }: ApiOperationProps<Doc, Path, Method, ContentType>): ReactNode;
259
+ }: ApiOperationProps<Doc, Path, Method, ContentType, ResponseStatus, ResponseContentType>): ReactNode;
260
+ /**
261
+ * Props accepted by {@link ApiParameters}.
262
+ *
263
+ * @group OpenAPI
264
+ */
205
265
  interface ApiParametersProps<Doc = unknown, Path extends PathKeysOf<Doc> = PathKeysOf<Doc>, Method extends MethodKeysOf<Doc, Path> = MethodKeysOf<Doc, Path>> extends ApiDiagnosticsProps {
206
266
  schema: Doc;
207
267
  path: Path;
@@ -211,6 +271,14 @@ interface ApiParametersProps<Doc = unknown, Path extends PathKeysOf<Doc> = PathK
211
271
  /** Instance-scoped widgets. */
212
272
  widgets?: WidgetMap;
213
273
  }
274
+ /**
275
+ * Render the `parameters` of a single OpenAPI operation — path, query,
276
+ * header, and cookie parameters — picked out of `schema` by `path` and
277
+ * `method`. When the document is typed `as const`, the `overrides` prop
278
+ * autocompletes on each parameter name.
279
+ *
280
+ * @group OpenAPI
281
+ */
214
282
  declare function ApiParameters<Doc = unknown, Path extends PathKeysOf<Doc> = PathKeysOf<Doc>, Method extends MethodKeysOf<Doc, Path> = MethodKeysOf<Doc, Path>>({
215
283
  schema: doc,
216
284
  path,
@@ -221,6 +289,11 @@ declare function ApiParameters<Doc = unknown, Path extends PathKeysOf<Doc> = Pat
221
289
  onDiagnostic,
222
290
  strict
223
291
  }: ApiParametersProps<Doc, Path, Method>): ReactNode;
292
+ /**
293
+ * Props accepted by {@link ApiRequestBody}.
294
+ *
295
+ * @group OpenAPI
296
+ */
224
297
  interface ApiRequestBodyProps<Doc = unknown, Path extends PathKeysOf<Doc> = PathKeysOf<Doc>, Method extends MethodKeysOf<Doc, Path> = MethodKeysOf<Doc, Path>, ContentType extends RequestContentTypesOf<Doc, Path, Method> = RequestContentTypesOf<Doc, Path, Method>> extends ApiDiagnosticsProps {
225
298
  schema: Doc;
226
299
  path: Path;
@@ -239,6 +312,17 @@ interface ApiRequestBodyProps<Doc = unknown, Path extends PathKeysOf<Doc> = Path
239
312
  /** Instance-scoped widgets. */
240
313
  widgets?: WidgetMap;
241
314
  }
315
+ /**
316
+ * Render the request body of a single OpenAPI operation, picked out of
317
+ * `schema` by `path` and `method`. Returns `null` when the operation
318
+ * declares no request body or no resolvable schema.
319
+ *
320
+ * When `schema` is typed `as const`, `fields` autocomplete resolves
321
+ * from the request body schema; pass `contentType` to narrow inference
322
+ * to a specific media type.
323
+ *
324
+ * @group OpenAPI
325
+ */
242
326
  declare function ApiRequestBody<Doc = unknown, Path extends PathKeysOf<Doc> = PathKeysOf<Doc>, Method extends MethodKeysOf<Doc, Path> = MethodKeysOf<Doc, Path>, ContentType extends RequestContentTypesOf<Doc, Path, Method> = RequestContentTypesOf<Doc, Path, Method>>({
243
327
  schema: doc,
244
328
  path,
@@ -251,6 +335,11 @@ declare function ApiRequestBody<Doc = unknown, Path extends PathKeysOf<Doc> = Pa
251
335
  onDiagnostic,
252
336
  strict
253
337
  }: ApiRequestBodyProps<Doc, Path, Method, ContentType>): ReactNode;
338
+ /**
339
+ * Props accepted by {@link ApiResponse}.
340
+ *
341
+ * @group OpenAPI
342
+ */
254
343
  interface ApiResponseProps<Doc = unknown, Path extends PathKeysOf<Doc> = PathKeysOf<Doc>, Method extends MethodKeysOf<Doc, Path> = MethodKeysOf<Doc, Path>, Status extends StatusKeysOf<Doc, Path, Method> = StatusKeysOf<Doc, Path, Method>, ContentType extends ResponseContentTypesOf<Doc, Path, Method, Status> = ResponseContentTypesOf<Doc, Path, Method, Status>> extends ApiDiagnosticsProps {
255
344
  schema: Doc;
256
345
  path: Path;
@@ -269,6 +358,18 @@ interface ApiResponseProps<Doc = unknown, Path extends PathKeysOf<Doc> = PathKey
269
358
  /** Instance-scoped widgets. */
270
359
  widgets?: WidgetMap;
271
360
  }
361
+ /**
362
+ * Render the response schema for a single OpenAPI operation status —
363
+ * picked out of `schema` by `path`, `method`, and `status`.
364
+ *
365
+ * Status resolution follows the OpenAPI priority order: concrete code
366
+ * (e.g. `"200"`) > class wildcard (e.g. `"2XX"`) > `"default"`. When
367
+ * `schema` is typed `as const`, `fields` autocomplete resolves from
368
+ * the response schema; pass `contentType` to narrow inference to a
369
+ * specific media type.
370
+ *
371
+ * @group OpenAPI
372
+ */
272
373
  declare function ApiResponse<Doc = unknown, Path extends PathKeysOf<Doc> = PathKeysOf<Doc>, Method extends MethodKeysOf<Doc, Path> = MethodKeysOf<Doc, Path>, Status extends StatusKeysOf<Doc, Path, Method> = StatusKeysOf<Doc, Path, Method>, ContentType extends ResponseContentTypesOf<Doc, Path, Method, Status> = ResponseContentTypesOf<Doc, Path, Method, Status>>({
273
374
  schema: doc,
274
375
  path,
@@ -282,14 +383,9 @@ declare function ApiResponse<Doc = unknown, Path extends PathKeysOf<Doc> = PathK
282
383
  strict
283
384
  }: ApiResponseProps<Doc, Path, Method, Status, ContentType>): ReactNode;
284
385
  /**
285
- * Render a single OpenAPI 3.1 webhook by name. A webhook is a Path Item
286
- * Object under the document's top-level `webhooks` map; once resolved,
287
- * its operations are structurally identical to operations under `paths`.
386
+ * Props accepted by {@link ApiWebhook}.
288
387
  *
289
- * Internally, this delegates to `ApiOperation` for each method present
290
- * on the webhook's Path Item Object. The parser's `lookupPathItem`
291
- * resolves webhook names through the same code path as paths, so
292
- * `ApiOperation` works for both with no special-casing in the renderer.
388
+ * @group OpenAPI
293
389
  */
294
390
  interface ApiWebhookProps extends ApiDiagnosticsProps {
295
391
  schema: unknown;
@@ -299,6 +395,18 @@ interface ApiWebhookProps extends ApiDiagnosticsProps {
299
395
  widgets?: WidgetMap;
300
396
  meta?: SchemaMeta;
301
397
  }
398
+ /**
399
+ * Render a single OpenAPI 3.1 webhook by name. A webhook is a Path Item
400
+ * Object under the document's top-level `webhooks` map; once resolved,
401
+ * its operations are structurally identical to operations under `paths`.
402
+ *
403
+ * Delegates to {@link ApiOperation} for each method present on the
404
+ * webhook's Path Item Object — the parser's `lookupPathItem` resolves
405
+ * webhook names through the same code path as paths, so `ApiOperation`
406
+ * works for both with no special-casing in the renderer.
407
+ *
408
+ * @group OpenAPI
409
+ */
302
410
  declare function ApiWebhook({
303
411
  schema: doc,
304
412
  name,
@@ -308,15 +416,22 @@ declare function ApiWebhook({
308
416
  strict
309
417
  }: ApiWebhookProps): ReactNode;
310
418
  /**
311
- * Render every OpenAPI 3.1 webhook declared on the document, one
312
- * `<ApiWebhook>` per entry. Returns `null` when the document has no
313
- * `webhooks` map or it is empty.
419
+ * Props accepted by {@link ApiWebhooks}.
420
+ *
421
+ * @group OpenAPI
314
422
  */
315
423
  interface ApiWebhooksProps extends ApiDiagnosticsProps {
316
424
  schema: unknown;
317
425
  widgets?: WidgetMap;
318
426
  meta?: SchemaMeta;
319
427
  }
428
+ /**
429
+ * Render every OpenAPI 3.1 webhook declared on the document, one
430
+ * `<ApiWebhook>` per entry. Returns `null` when the document has no
431
+ * `webhooks` map or the map is empty.
432
+ *
433
+ * @group OpenAPI
434
+ */
320
435
  declare function ApiWebhooks({
321
436
  schema: doc,
322
437
  widgets,
@@ -1,16 +1,17 @@
1
1
  import { isObject, toRecordOrUndefined } from "../core/guards.mjs";
2
2
  import { emitDiagnostic } from "../core/diagnostics.mjs";
3
+ import { isSafeHyperlink } from "../core/uri.mjs";
3
4
  import { extractRootMetaFromJson } from "../core/adapter.mjs";
4
5
  import { walk } from "../core/walker.mjs";
5
- import { joinPath, renderField, sanitisePrefix } from "../react/SchemaComponent.mjs";
6
6
  import { ApiCallbacks } from "./ApiCallbacks.mjs";
7
7
  import { ApiLinks } from "./ApiLinks.mjs";
8
8
  import { ApiResponseHeaders } from "./ApiResponseHeaders.mjs";
9
9
  import { ApiSecurity } from "./ApiSecurity.mjs";
10
- import { getExternalDocs, getLinks, getSecurityRequirements, getSecuritySchemes, getXmlInfo, listCallbacks, listWebhooks } from "./parser.mjs";
11
- import { getParsed, resolveOperationFromParsed, resolveParametersFromParsed, resolveRequestBodyFromParsed, resolveResponseFromParsed, toDoc } from "./resolve.mjs";
12
- import { useId } from "react";
10
+ import { extractExternalDocs, extractLinks, extractSecurityRequirements, extractSecuritySchemes, extractXmlInfo, listCallbacks, listWebhooks } from "./parser.mjs";
11
+ import { joinPath, renderField, sanitisePrefix } from "../react/SchemaComponent.mjs";
12
+ import { getParsed, resolveOperation, resolveParameters, resolveRequestBody, resolveResponse, toDoc } from "./resolve.mjs";
13
13
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
14
+ import { useId } from "react";
14
15
  //#region src/openapi/components.tsx
15
16
  /**
16
17
  * OpenAPI React components with type-safe generics.
@@ -78,11 +79,16 @@ function renderSchema(schema, rootDocument, options) {
78
79
  */
79
80
  function ExternalDocsLink({ externalDocs }) {
80
81
  if (externalDocs === void 0) return null;
82
+ const label = externalDocs.description ?? externalDocs.url;
83
+ if (!isSafeHyperlink(externalDocs.url)) return /* @__PURE__ */ jsx("p", {
84
+ "data-external-docs": true,
85
+ children: /* @__PURE__ */ jsx("span", { children: label })
86
+ });
81
87
  return /* @__PURE__ */ jsx("p", {
82
88
  "data-external-docs": true,
83
89
  children: /* @__PURE__ */ jsx("a", {
84
90
  href: externalDocs.url,
85
- children: externalDocs.description ?? externalDocs.url
91
+ children: label
86
92
  })
87
93
  });
88
94
  }
@@ -107,18 +113,37 @@ function SchemaXmlFootnote({ xml }) {
107
113
  ] })
108
114
  });
109
115
  }
116
+ /**
117
+ * Render a single OpenAPI operation — header, parameters, request body,
118
+ * responses, callbacks, security, and external docs — picked out of a
119
+ * supplied document by `path` and `method`.
120
+ *
121
+ * When `schema` is typed `as const`, `requestBodyFields` autocomplete
122
+ * resolves from the operation's request body schema. The component
123
+ * works with OpenAPI 2.0, 3.0, and 3.1 inputs (Swagger 2.0 documents
124
+ * are normalised to 3.1 internally) and also resolves OpenAPI 3.1
125
+ * webhooks under the same code path.
126
+ *
127
+ * @group OpenAPI
128
+ * @example
129
+ * ```tsx
130
+ * import { ApiOperation } from "schema-components/openapi/components";
131
+ *
132
+ * <ApiOperation schema={petStore} path="/pets" method="post" />
133
+ * ```
134
+ */
110
135
  function ApiOperation({ schema: doc, path, method, requestBodyValue, onRequestBodyChange, responseValue, meta, requestBodyFields, widgets, onDiagnostic, strict }) {
111
136
  const diagnostics = buildDiagnostics(onDiagnostic, strict);
112
137
  const instancePrefix = sanitisePrefix(useId());
113
138
  const rootDoc = resolveRootDoc(doc, diagnostics);
114
139
  if (rootDoc === void 0) return null;
115
140
  const parsed = getParsed(rootDoc, diagnostics);
116
- const resolved = resolveOperationFromParsed(parsed, path, method, diagnostics);
117
- const securityReqs = getSecurityRequirements(parsed, path, method);
118
- const securitySchemes = getSecuritySchemes(parsed);
141
+ const resolved = resolveOperation(parsed, path, method, diagnostics);
142
+ const securityReqs = extractSecurityRequirements(parsed, path, method);
143
+ const securitySchemes = extractSecuritySchemes(parsed);
119
144
  const callbacks = listCallbacks(parsed, path, method);
120
- const operationExternalDocs = getExternalDocs(resolved.operation.operation);
121
- const requestBodyXml = resolved.requestBody?.schema !== void 0 ? getXmlInfo(resolved.requestBody.schema) : void 0;
145
+ const operationExternalDocs = extractExternalDocs(resolved.operation.operation);
146
+ const requestBodyXml = resolved.requestBody?.schema !== void 0 ? extractXmlInfo(resolved.requestBody.schema) : void 0;
122
147
  return /* @__PURE__ */ jsxs("section", {
123
148
  "data-operation": `${method.toUpperCase()} ${path}`,
124
149
  children: [
@@ -184,12 +209,20 @@ function ApiOperation({ schema: doc, path, method, requestBodyValue, onRequestBo
184
209
  ]
185
210
  });
186
211
  }
212
+ /**
213
+ * Render the `parameters` of a single OpenAPI operation — path, query,
214
+ * header, and cookie parameters — picked out of `schema` by `path` and
215
+ * `method`. When the document is typed `as const`, the `overrides` prop
216
+ * autocompletes on each parameter name.
217
+ *
218
+ * @group OpenAPI
219
+ */
187
220
  function ApiParameters({ schema: doc, path, method, meta, overrides, widgets, onDiagnostic, strict }) {
188
221
  const diagnostics = buildDiagnostics(onDiagnostic, strict);
189
222
  const instancePrefix = sanitisePrefix(useId());
190
223
  const rootDoc = resolveRootDoc(doc, diagnostics);
191
224
  if (rootDoc === void 0) return null;
192
- const params = resolveParametersFromParsed(getParsed(rootDoc, diagnostics), path, method);
225
+ const params = resolveParameters(getParsed(rootDoc, diagnostics), path, method);
193
226
  if (params.length === 0) return null;
194
227
  return /* @__PURE__ */ jsxs("section", {
195
228
  "data-parameters": true,
@@ -205,14 +238,25 @@ function ApiParameters({ schema: doc, path, method, meta, overrides, widgets, on
205
238
  })]
206
239
  });
207
240
  }
241
+ /**
242
+ * Render the request body of a single OpenAPI operation, picked out of
243
+ * `schema` by `path` and `method`. Returns `null` when the operation
244
+ * declares no request body or no resolvable schema.
245
+ *
246
+ * When `schema` is typed `as const`, `fields` autocomplete resolves
247
+ * from the request body schema; pass `contentType` to narrow inference
248
+ * to a specific media type.
249
+ *
250
+ * @group OpenAPI
251
+ */
208
252
  function ApiRequestBody({ schema: doc, path, method, value, onChange, meta, fields, widgets, onDiagnostic, strict }) {
209
253
  const diagnostics = buildDiagnostics(onDiagnostic, strict);
210
254
  const instancePrefix = sanitisePrefix(useId());
211
255
  const rootDoc = resolveRootDoc(doc, diagnostics);
212
256
  if (rootDoc === void 0) return null;
213
- const requestBody = resolveRequestBodyFromParsed(getParsed(rootDoc, diagnostics), path, method);
257
+ const requestBody = resolveRequestBody(getParsed(rootDoc, diagnostics), path, method);
214
258
  if (requestBody?.schema === void 0) return null;
215
- const requestBodyXml = getXmlInfo(requestBody.schema);
259
+ const requestBodyXml = extractXmlInfo(requestBody.schema);
216
260
  return /* @__PURE__ */ jsxs("section", {
217
261
  "data-request-body": true,
218
262
  children: [
@@ -237,13 +281,25 @@ function ApiRequestBody({ schema: doc, path, method, value, onChange, meta, fiel
237
281
  ]
238
282
  });
239
283
  }
284
+ /**
285
+ * Render the response schema for a single OpenAPI operation status —
286
+ * picked out of `schema` by `path`, `method`, and `status`.
287
+ *
288
+ * Status resolution follows the OpenAPI priority order: concrete code
289
+ * (e.g. `"200"`) > class wildcard (e.g. `"2XX"`) > `"default"`. When
290
+ * `schema` is typed `as const`, `fields` autocomplete resolves from
291
+ * the response schema; pass `contentType` to narrow inference to a
292
+ * specific media type.
293
+ *
294
+ * @group OpenAPI
295
+ */
240
296
  function ApiResponse({ schema: doc, path, method, status, value, meta, fields, widgets, onDiagnostic, strict }) {
241
297
  const diagnostics = buildDiagnostics(onDiagnostic, strict);
242
298
  const instancePrefix = sanitisePrefix(useId());
243
299
  const rootDoc = resolveRootDoc(doc, diagnostics);
244
300
  if (rootDoc === void 0) return null;
245
301
  const parsed = getParsed(rootDoc, diagnostics);
246
- const response = resolveResponseFromParsed(parsed, path, method, status);
302
+ const response = resolveResponse(parsed, path, method, status);
247
303
  if (response.schema === void 0) return /* @__PURE__ */ jsxs("div", {
248
304
  "data-status": status,
249
305
  children: [
@@ -265,6 +321,18 @@ function ApiResponse({ schema: doc, path, method, status, value, meta, fields, w
265
321
  idPrefix: instancePrefix
266
322
  });
267
323
  }
324
+ /**
325
+ * Render a single OpenAPI 3.1 webhook by name. A webhook is a Path Item
326
+ * Object under the document's top-level `webhooks` map; once resolved,
327
+ * its operations are structurally identical to operations under `paths`.
328
+ *
329
+ * Delegates to {@link ApiOperation} for each method present on the
330
+ * webhook's Path Item Object — the parser's `lookupPathItem` resolves
331
+ * webhook names through the same code path as paths, so `ApiOperation`
332
+ * works for both with no special-casing in the renderer.
333
+ *
334
+ * @group OpenAPI
335
+ */
268
336
  function ApiWebhook({ schema: doc, name, widgets, meta, onDiagnostic, strict }) {
269
337
  const diagnostics = buildDiagnostics(onDiagnostic, strict);
270
338
  const instancePrefix = sanitisePrefix(useId());
@@ -287,6 +355,13 @@ function ApiWebhook({ schema: doc, name, widgets, meta, onDiagnostic, strict })
287
355
  })]
288
356
  });
289
357
  }
358
+ /**
359
+ * Render every OpenAPI 3.1 webhook declared on the document, one
360
+ * `<ApiWebhook>` per entry. Returns `null` when the document has no
361
+ * `webhooks` map or the map is empty.
362
+ *
363
+ * @group OpenAPI
364
+ */
290
365
  function ApiWebhooks({ schema: doc, widgets, meta, onDiagnostic, strict }) {
291
366
  const diagnostics = buildDiagnostics(onDiagnostic, strict);
292
367
  const instancePrefix = sanitisePrefix(useId());
@@ -380,7 +455,7 @@ function ResponseCard({ response, rootDoc, parsed, value, fields, meta, widgets,
380
455
  ]
381
456
  });
382
457
  let links = [];
383
- if (path !== void 0 && method !== void 0) links = getLinks(parsed, path, method, response.statusCode);
458
+ if (path !== void 0 && method !== void 0) links = extractLinks(parsed, path, method, response.statusCode);
384
459
  return /* @__PURE__ */ jsxs("div", {
385
460
  "data-status": response.statusCode,
386
461
  children: [