schema-components 1.29.0 → 2.0.1

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 (90) hide show
  1. package/README.md +38 -16
  2. package/dist/core/adapter.d.mts +213 -3
  3. package/dist/core/adapter.mjs +1 -1
  4. package/dist/core/constraintHint.d.mts +15 -0
  5. package/dist/core/constraintHint.mjs +24 -0
  6. package/dist/core/constraints.d.mts +2 -2
  7. package/dist/core/constraints.mjs +1 -1
  8. package/dist/core/diagnostics.d.mts +1 -1
  9. package/dist/core/errors.d.mts +1 -1
  10. package/dist/core/fieldOrder.d.mts +1 -1
  11. package/dist/core/formats.d.mts +1 -1
  12. package/dist/core/idPath.d.mts +35 -5
  13. package/dist/core/idPath.mjs +79 -7
  14. package/dist/core/inferValue.d.mts +2 -0
  15. package/dist/core/inferValue.mjs +1 -0
  16. package/dist/core/limits.d.mts +1 -1
  17. package/dist/core/limits.mjs +5 -0
  18. package/dist/core/merge.d.mts +12 -1
  19. package/dist/core/merge.mjs +66 -3
  20. package/dist/core/normalise.d.mts +1 -1
  21. package/dist/core/normalise.mjs +1 -1
  22. package/dist/core/openapi30.mjs +1 -1
  23. package/dist/core/ref.d.mts +1 -1
  24. package/dist/core/refChain.d.mts +3 -4
  25. package/dist/core/refChain.mjs +2 -3
  26. package/dist/core/renderer.d.mts +199 -2
  27. package/dist/core/swagger2.d.mts +1 -1
  28. package/dist/core/swagger2.mjs +1 -1
  29. package/dist/core/typeInference.d.mts +3 -3
  30. package/dist/core/types.d.mts +1 -1
  31. package/dist/core/unionMatch.d.mts +1 -1
  32. package/dist/core/uri.d.mts +12 -4
  33. package/dist/core/uri.mjs +30 -4
  34. package/dist/core/walkBuilders.d.mts +18 -6
  35. package/dist/core/walkBuilders.mjs +3 -1
  36. package/dist/core/walker.d.mts +1 -1
  37. package/dist/core/walker.mjs +5 -0
  38. package/dist/{diagnostics-ByEzkjrA.d.mts → diagnostics-BTrm3O6J.d.mts} +1 -1
  39. package/dist/{errors-D8JndRwI.d.mts → errors-Dki7tji4.d.mts} +1 -1
  40. package/dist/html/a11y.d.mts +3 -7
  41. package/dist/html/a11y.mjs +1 -16
  42. package/dist/html/renderToHtml.d.mts +22 -9
  43. package/dist/html/renderToHtml.mjs +2 -1
  44. package/dist/html/renderToHtmlStream.d.mts +24 -11
  45. package/dist/html/renderToHtmlStream.mjs +2 -1
  46. package/dist/html/renderers.d.mts +2 -33
  47. package/dist/html/renderers.mjs +39 -91
  48. package/dist/html/streamRenderers.d.mts +3 -3
  49. package/dist/html/streamRenderers.mjs +13 -8
  50. package/dist/inferValue-PPXWJpbN.d.mts +77 -0
  51. package/dist/{limits-DswmqWuy.d.mts → limits-x4OiyJxh.d.mts} +5 -0
  52. package/dist/{normalise-Db1xaxgx.mjs → normalise-DB-Xtjmn.mjs} +43 -2
  53. package/dist/openapi/ApiCallbacks.d.mts +1 -1
  54. package/dist/openapi/ApiLinks.d.mts +1 -1
  55. package/dist/openapi/ApiResponseHeaders.d.mts +1 -1
  56. package/dist/openapi/ApiSecurity.d.mts +1 -1
  57. package/dist/openapi/ApiSecurity.mjs +21 -8
  58. package/dist/openapi/bundle.d.mts +31 -0
  59. package/dist/openapi/components.d.mts +41 -10
  60. package/dist/openapi/components.mjs +19 -13
  61. package/dist/openapi/parser.d.mts +13 -13
  62. package/dist/openapi/parser.mjs +12 -12
  63. package/dist/openapi/resolve.d.mts +38 -49
  64. package/dist/openapi/resolve.mjs +62 -56
  65. package/dist/react/SchemaComponent.d.mts +19 -95
  66. package/dist/react/SchemaComponent.mjs +12 -1
  67. package/dist/react/SchemaView.d.mts +11 -7
  68. package/dist/react/SchemaView.mjs +3 -1
  69. package/dist/react/a11y.d.mts +74 -7
  70. package/dist/react/a11y.mjs +67 -6
  71. package/dist/react/fieldPath.d.mts +16 -1
  72. package/dist/react/fieldPath.mjs +25 -1
  73. package/dist/react/fieldShell.d.mts +49 -0
  74. package/dist/react/fieldShell.mjs +37 -0
  75. package/dist/react/headless.d.mts +1 -1
  76. package/dist/react/headlessRenderers.d.mts +2 -2
  77. package/dist/react/headlessRenderers.mjs +123 -54
  78. package/dist/{ref-CPh8rKQ3.d.mts → ref-DdsbekXX.d.mts} +33 -1
  79. package/dist/themes/mantine.d.mts +36 -20
  80. package/dist/themes/mantine.mjs +179 -150
  81. package/dist/themes/mui.d.mts +47 -21
  82. package/dist/themes/mui.mjs +259 -222
  83. package/dist/themes/radix.d.mts +38 -23
  84. package/dist/themes/radix.mjs +208 -180
  85. package/dist/themes/shadcn.d.mts +6 -3
  86. package/dist/themes/shadcn.mjs +93 -93
  87. package/dist/{types-C2Ay1FEh.d.mts → types-BrYbjC7_.d.mts} +7 -0
  88. package/package.json +5 -1
  89. package/dist/adapter-DcWi4XXn.d.mts +0 -223
  90. package/dist/renderer-OaOz-n6-.d.mts +0 -185
@@ -1,5 +1,6 @@
1
1
  import { isObject } from "./core/guards.mjs";
2
2
  import { appendPointer, emitDiagnostic } from "./core/diagnostics.mjs";
3
+ import { isPrototypePollutingKey } from "./core/uri.mjs";
3
4
  import { RECURSIVE_ANCHOR_SENTINEL } from "./core/ref.mjs";
4
5
  import { isOpenApi30, isOpenApi31, isSwagger2, matchJsonSchemaDraftUri, readJsonSchemaDialect } from "./core/version.mjs";
5
6
  import { SWAGGER_2_METHODS, rewriteSwaggerRefPrefix } from "./core/openapiConstants.mjs";
@@ -801,7 +802,18 @@ function normaliseSwaggerOperation(operation, doc, path, method, diagnostics) {
801
802
  const producesResolution = resolveSwaggerContentTypes(operation.produces, doc.produces);
802
803
  const produces = producesResolution.types;
803
804
  const consumes = consumesResolution.types;
804
- for (const [key, value] of Object.entries(operation)) if (key !== "parameters" && key !== "responses" && key !== "produces" && key !== "consumes") result[key] = value;
805
+ for (const [key, value] of Object.entries(operation)) if (key !== "parameters" && key !== "responses" && key !== "produces" && key !== "consumes") {
806
+ if (isPrototypePollutingKey(key)) {
807
+ emitDiagnostic(diagnostics, {
808
+ code: "prototype-polluting-property",
809
+ message: `Refusing to copy prototype-polluting property name into normalised operation: ${key}`,
810
+ pointer: appendPointer(`/paths/${path}/${method}`, key),
811
+ detail: { propertyName: key }
812
+ });
813
+ continue;
814
+ }
815
+ result[key] = value;
816
+ }
805
817
  const params = operation.parameters;
806
818
  if (Array.isArray(params)) {
807
819
  const nonBodyParams = [];
@@ -1038,6 +1050,15 @@ function normaliseSwaggerParameter(param, doc, diagnostics, pointer = "") {
1038
1050
  const result = {};
1039
1051
  for (const [key, value] of Object.entries(param)) {
1040
1052
  if (PARAM_KEYWORDS_LIFTED_INTO_SCHEMA.has(key)) continue;
1053
+ if (isPrototypePollutingKey(key)) {
1054
+ emitDiagnostic(diagnostics, {
1055
+ code: "prototype-polluting-property",
1056
+ message: `Refusing to copy prototype-polluting property name into normalised parameter: ${key}`,
1057
+ pointer: appendPointer(pointer, key),
1058
+ detail: { propertyName: key }
1059
+ });
1060
+ continue;
1061
+ }
1041
1062
  result[key] = value;
1042
1063
  }
1043
1064
  if (typeof param.type === "string") if (param.type === "file" && param.in !== "formData") {
@@ -1186,7 +1207,18 @@ function normaliseSwaggerResponses(responses, doc, produces, producesSource, dia
1186
1207
  function normaliseSwaggerSingleResponse(response, doc, produces, producesSource = "synthesised", diagnostics, path, method, statusCode) {
1187
1208
  const resolved = resolveSwaggerResponse(response, doc);
1188
1209
  const normalised = {};
1189
- for (const [key, value] of Object.entries(resolved)) if (key !== "schema" && key !== "headers") normalised[key] = value;
1210
+ for (const [key, value] of Object.entries(resolved)) if (key !== "schema" && key !== "headers") {
1211
+ if (isPrototypePollutingKey(key)) {
1212
+ emitDiagnostic(diagnostics, {
1213
+ code: "prototype-polluting-property",
1214
+ message: `Refusing to copy prototype-polluting property name into normalised response: ${key}`,
1215
+ pointer: path !== void 0 && method !== void 0 && statusCode !== void 0 ? appendPointer(`/paths/${path}/${method}/responses/${statusCode}`, key) : key,
1216
+ detail: { propertyName: key }
1217
+ });
1218
+ continue;
1219
+ }
1220
+ normalised[key] = value;
1221
+ }
1190
1222
  const schema = resolved.schema;
1191
1223
  if (isObject(schema)) {
1192
1224
  const content = {};
@@ -1232,6 +1264,15 @@ function normaliseSwaggerHeader(header, diagnostics, pointer = "") {
1232
1264
  const result = {};
1233
1265
  for (const [key, value] of Object.entries(header)) {
1234
1266
  if (PARAM_KEYWORDS_LIFTED_INTO_SCHEMA.has(key)) continue;
1267
+ if (isPrototypePollutingKey(key)) {
1268
+ emitDiagnostic(diagnostics, {
1269
+ code: "prototype-polluting-property",
1270
+ message: `Refusing to copy prototype-polluting property name into normalised header: ${key}`,
1271
+ pointer: appendPointer(pointer, key),
1272
+ detail: { propertyName: key }
1273
+ });
1274
+ continue;
1275
+ }
1235
1276
  result[key] = value;
1236
1277
  }
1237
1278
  if (typeof header.type === "string") result.schema = buildSchemaFromSwaggerParameterShape(header);
@@ -1,4 +1,4 @@
1
- import { w as SchemaMeta } from "../types-C2Ay1FEh.mjs";
1
+ import { w as SchemaMeta } from "../types-BrYbjC7_.mjs";
2
2
  import { CallbackInfo } from "./parser.mjs";
3
3
  import { ReactNode } from "react";
4
4
 
@@ -1,4 +1,4 @@
1
- import { w as SchemaMeta } from "../types-C2Ay1FEh.mjs";
1
+ import { w as SchemaMeta } from "../types-BrYbjC7_.mjs";
2
2
  import { LinkInfo } from "./parser.mjs";
3
3
  import { ReactNode } from "react";
4
4
 
@@ -1,4 +1,4 @@
1
- import { w as SchemaMeta } from "../types-C2Ay1FEh.mjs";
1
+ import { w as SchemaMeta } from "../types-BrYbjC7_.mjs";
2
2
  import { HeaderInfo } from "./parser.mjs";
3
3
  import { ReactNode } from "react";
4
4
 
@@ -1,4 +1,4 @@
1
- import { w as SchemaMeta } from "../types-C2Ay1FEh.mjs";
1
+ import { w as SchemaMeta } from "../types-BrYbjC7_.mjs";
2
2
  import { SecurityRequirement, SecurityScheme } from "./parser.mjs";
3
3
  import { ReactNode } from "react";
4
4
 
@@ -1,4 +1,5 @@
1
1
  import { isObject } from "../core/guards.mjs";
2
+ import { isSafeHyperlink } from "../core/uri.mjs";
2
3
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
4
  //#region src/openapi/ApiSecurity.tsx
4
5
  /**
@@ -113,11 +114,14 @@ function SchemeDetails({ scheme }) {
113
114
  "data-security-apikey-in": true,
114
115
  children: scheme.location
115
116
  }),
116
- scheme.openIdConnectUrl !== void 0 && /* @__PURE__ */ jsx("a", {
117
+ scheme.openIdConnectUrl !== void 0 && (isSafeHyperlink(scheme.openIdConnectUrl) ? /* @__PURE__ */ jsx("a", {
117
118
  "data-security-openid-url": true,
118
119
  href: scheme.openIdConnectUrl,
119
120
  children: scheme.openIdConnectUrl
120
- }),
121
+ }) : /* @__PURE__ */ jsx("span", {
122
+ "data-security-openid-url": true,
123
+ children: scheme.openIdConnectUrl
124
+ })),
121
125
  flows.length > 0 && /* @__PURE__ */ jsx("section", {
122
126
  "data-security-flows": true,
123
127
  children: flows.map((flow) => /* @__PURE__ */ jsx(FlowDetails, { flow }, flow.name))
@@ -132,21 +136,30 @@ function FlowDetails({ flow }) {
132
136
  "data-security-flow-name": true,
133
137
  children: flow.name
134
138
  }),
135
- flow.authorizationUrl !== void 0 && /* @__PURE__ */ jsx("a", {
139
+ flow.authorizationUrl !== void 0 && (isSafeHyperlink(flow.authorizationUrl) ? /* @__PURE__ */ jsx("a", {
136
140
  "data-security-flow-authorization-url": true,
137
141
  href: flow.authorizationUrl,
138
142
  children: flow.authorizationUrl
139
- }),
140
- flow.tokenUrl !== void 0 && /* @__PURE__ */ jsx("a", {
143
+ }) : /* @__PURE__ */ jsx("span", {
144
+ "data-security-flow-authorization-url": true,
145
+ children: flow.authorizationUrl
146
+ })),
147
+ flow.tokenUrl !== void 0 && (isSafeHyperlink(flow.tokenUrl) ? /* @__PURE__ */ jsx("a", {
141
148
  "data-security-flow-token-url": true,
142
149
  href: flow.tokenUrl,
143
150
  children: flow.tokenUrl
144
- }),
145
- flow.refreshUrl !== void 0 && /* @__PURE__ */ jsx("a", {
151
+ }) : /* @__PURE__ */ jsx("span", {
152
+ "data-security-flow-token-url": true,
153
+ children: flow.tokenUrl
154
+ })),
155
+ flow.refreshUrl !== void 0 && (isSafeHyperlink(flow.refreshUrl) ? /* @__PURE__ */ jsx("a", {
146
156
  "data-security-flow-refresh-url": true,
147
157
  href: flow.refreshUrl,
148
158
  children: flow.refreshUrl
149
- }),
159
+ }) : /* @__PURE__ */ jsx("span", {
160
+ "data-security-flow-refresh-url": true,
161
+ children: flow.refreshUrl
162
+ })),
150
163
  flow.scopes.size > 0 && /* @__PURE__ */ jsx("dl", {
151
164
  "data-security-flow-scopes": true,
152
165
  children: [...flow.scopes.entries()].map(([name, description]) => /* @__PURE__ */ jsxs("div", {
@@ -27,6 +27,37 @@
27
27
  * Resolver function for external documents.
28
28
  * Called with the URI portion of an external $ref (everything before `#`).
29
29
  * Returns the parsed JSON document.
30
+ *
31
+ * ### Security warning — SSRF and local-file disclosure
32
+ *
33
+ * Consumers MUST validate the URI before fetching the target document.
34
+ * The bundler hands the resolver the raw `$ref` URI from the OpenAPI
35
+ * document — which is typically user-controlled — and any network or
36
+ * filesystem access the resolver performs runs with the host
37
+ * application's full privileges. An attacker-crafted document that
38
+ * references an internal endpoint or a local filesystem path will
39
+ * happily exfiltrate or expose data the application never intended to
40
+ * surface.
41
+ *
42
+ * At a minimum the resolver should:
43
+ *
44
+ * - Refuse non-`https:` schemes by default. Permit `http:` only on an
45
+ * explicit allow-list. Refuse `file:`, `data:`, `javascript:`,
46
+ * `ftp:`, `gopher:`, and every other scheme outright.
47
+ * - Resolve the URI's hostname and refuse loopback addresses
48
+ * (`127.0.0.0/8`, `::1`), link-local addresses (`169.254.0.0/16`,
49
+ * `fe80::/10`), private ranges (`10.0.0.0/8`, `172.16.0.0/12`,
50
+ * `192.168.0.0/16`, `fc00::/7`), and cloud-metadata IPs
51
+ * (`169.254.169.254`, `fd00:ec2::254`).
52
+ * - Apply a strict allow-list of permitted hosts where possible.
53
+ * - Set request timeouts and a maximum response size.
54
+ * - Disable HTTP redirects, or re-validate the redirected URL against
55
+ * the same denylist before following.
56
+ * - Reject responses that are not `application/json` or
57
+ * `application/yaml`.
58
+ *
59
+ * The bundler itself performs no validation — that responsibility sits
60
+ * exclusively with the resolver implementation supplied by the caller.
30
61
  */
31
62
  type BundleResolver = (uri: string) => unknown;
32
63
  /**
@@ -1,7 +1,7 @@
1
- import { u as FieldOverride, w as SchemaMeta } from "../types-C2Ay1FEh.mjs";
2
- import { r as DiagnosticSink } from "../diagnostics-ByEzkjrA.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
@@ -173,13 +173,30 @@ interface ApiDiagnosticsProps {
173
173
  *
174
174
  * @group OpenAPI
175
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>> extends ApiDiagnosticsProps {
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 {
177
177
  schema: Doc;
178
178
  path: Path;
179
179
  method: Method;
180
- requestBodyValue?: unknown;
181
- onRequestBodyChange?: (value: unknown) => void;
182
- 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>;
183
200
  meta?: SchemaMeta;
184
201
  /**
185
202
  * Media type whose request body schema drives `requestBodyFields`
@@ -190,6 +207,20 @@ interface ApiOperationProps<Doc = unknown, Path extends PathKeysOf<Doc> = PathKe
190
207
  * same precision as `<ApiRequestBody>`.
191
208
  */
192
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;
193
224
  requestBodyFields?: Doc extends Record<string, unknown> ? InferRequestBodyFields<Doc, Path & string, Method & string, ContentType & string> : Record<string, FieldOverride>;
194
225
  /** Instance-scoped widgets. */
195
226
  widgets?: WidgetMap;
@@ -213,7 +244,7 @@ interface ApiOperationProps<Doc = unknown, Path extends PathKeysOf<Doc> = PathKe
213
244
  * <ApiOperation schema={petStore} path="/pets" method="post" />
214
245
  * ```
215
246
  */
216
- 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>>({
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>>({
217
248
  schema: doc,
218
249
  path,
219
250
  method,
@@ -225,7 +256,7 @@ declare function ApiOperation<Doc = unknown, Path extends PathKeysOf<Doc> = Path
225
256
  widgets,
226
257
  onDiagnostic,
227
258
  strict
228
- }: ApiOperationProps<Doc, Path, Method, ContentType>): ReactNode;
259
+ }: ApiOperationProps<Doc, Path, Method, ContentType, ResponseStatus, ResponseContentType>): ReactNode;
229
260
  /**
230
261
  * Props accepted by {@link ApiParameters}.
231
262
  *
@@ -1,14 +1,15 @@
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
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
- import { getExternalDocs, getLinks, getSecurityRequirements, getSecuritySchemes, getXmlInfo, listCallbacks, listWebhooks } from "./parser.mjs";
10
+ import { extractExternalDocs, extractLinks, extractSecurityRequirements, extractSecuritySchemes, extractXmlInfo, listCallbacks, listWebhooks } from "./parser.mjs";
10
11
  import { joinPath, renderField, sanitisePrefix } from "../react/SchemaComponent.mjs";
11
- import { getParsed, resolveOperationFromParsed, resolveParametersFromParsed, resolveRequestBodyFromParsed, resolveResponseFromParsed, toDoc } from "./resolve.mjs";
12
+ import { getParsed, resolveOperation, resolveParameters, resolveRequestBody, resolveResponse, toDoc } from "./resolve.mjs";
12
13
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
13
14
  import { useId } from "react";
14
15
  //#region src/openapi/components.tsx
@@ -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
  }
@@ -132,12 +138,12 @@ function ApiOperation({ schema: doc, path, method, requestBodyValue, onRequestBo
132
138
  const rootDoc = resolveRootDoc(doc, diagnostics);
133
139
  if (rootDoc === void 0) return null;
134
140
  const parsed = getParsed(rootDoc, diagnostics);
135
- const resolved = resolveOperationFromParsed(parsed, path, method, diagnostics);
136
- const securityReqs = getSecurityRequirements(parsed, path, method);
137
- const securitySchemes = getSecuritySchemes(parsed);
141
+ const resolved = resolveOperation(parsed, path, method, diagnostics);
142
+ const securityReqs = extractSecurityRequirements(parsed, path, method);
143
+ const securitySchemes = extractSecuritySchemes(parsed);
138
144
  const callbacks = listCallbacks(parsed, path, method);
139
- const operationExternalDocs = getExternalDocs(resolved.operation.operation);
140
- 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;
141
147
  return /* @__PURE__ */ jsxs("section", {
142
148
  "data-operation": `${method.toUpperCase()} ${path}`,
143
149
  children: [
@@ -216,7 +222,7 @@ function ApiParameters({ schema: doc, path, method, meta, overrides, widgets, on
216
222
  const instancePrefix = sanitisePrefix(useId());
217
223
  const rootDoc = resolveRootDoc(doc, diagnostics);
218
224
  if (rootDoc === void 0) return null;
219
- const params = resolveParametersFromParsed(getParsed(rootDoc, diagnostics), path, method);
225
+ const params = resolveParameters(getParsed(rootDoc, diagnostics), path, method);
220
226
  if (params.length === 0) return null;
221
227
  return /* @__PURE__ */ jsxs("section", {
222
228
  "data-parameters": true,
@@ -248,9 +254,9 @@ function ApiRequestBody({ schema: doc, path, method, value, onChange, meta, fiel
248
254
  const instancePrefix = sanitisePrefix(useId());
249
255
  const rootDoc = resolveRootDoc(doc, diagnostics);
250
256
  if (rootDoc === void 0) return null;
251
- const requestBody = resolveRequestBodyFromParsed(getParsed(rootDoc, diagnostics), path, method);
257
+ const requestBody = resolveRequestBody(getParsed(rootDoc, diagnostics), path, method);
252
258
  if (requestBody?.schema === void 0) return null;
253
- const requestBodyXml = getXmlInfo(requestBody.schema);
259
+ const requestBodyXml = extractXmlInfo(requestBody.schema);
254
260
  return /* @__PURE__ */ jsxs("section", {
255
261
  "data-request-body": true,
256
262
  children: [
@@ -293,7 +299,7 @@ function ApiResponse({ schema: doc, path, method, status, value, meta, fields, w
293
299
  const rootDoc = resolveRootDoc(doc, diagnostics);
294
300
  if (rootDoc === void 0) return null;
295
301
  const parsed = getParsed(rootDoc, diagnostics);
296
- const response = resolveResponseFromParsed(parsed, path, method, status);
302
+ const response = resolveResponse(parsed, path, method, status);
297
303
  if (response.schema === void 0) return /* @__PURE__ */ jsxs("div", {
298
304
  "data-status": status,
299
305
  children: [
@@ -449,7 +455,7 @@ function ResponseCard({ response, rootDoc, parsed, value, fields, meta, widgets,
449
455
  ]
450
456
  });
451
457
  let links = [];
452
- 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);
453
459
  return /* @__PURE__ */ jsxs("div", {
454
460
  "data-status": response.statusCode,
455
461
  children: [
@@ -1,5 +1,5 @@
1
- import { m as JsonObject } from "../types-C2Ay1FEh.mjs";
2
- import { i as DiagnosticsOptions } from "../diagnostics-ByEzkjrA.mjs";
1
+ import { m as JsonObject } from "../types-BrYbjC7_.mjs";
2
+ import { i as DiagnosticsOptions } from "../diagnostics-BTrm3O6J.mjs";
3
3
 
4
4
  //#region src/openapi/parser.d.ts
5
5
  /**
@@ -155,7 +155,7 @@ declare function parseOpenApiDocument(doc: JsonObject): OpenApiDocument;
155
155
  * resolved value for arbitrary fragment refs), or `undefined` when the
156
156
  * ref cannot be resolved.
157
157
  */
158
- declare function getSchema(parsed: OpenApiDocument, ref: string): JsonObject | undefined;
158
+ declare function extractSchema(parsed: OpenApiDocument, ref: string): JsonObject | undefined;
159
159
  /**
160
160
  * List every operation declared under the document's `paths` map.
161
161
  * Follows Path Item `$ref` chains internally; cycles and over-deep
@@ -167,36 +167,36 @@ declare function listOperations(parsed: OpenApiDocument, diagnostics?: Diagnosti
167
167
  * parameters with operation-level overrides and following any
168
168
  * Parameter Object `$ref` chains.
169
169
  */
170
- declare function getParameters(parsed: OpenApiDocument, path: string, method: string, diagnostics?: DiagnosticsOptions): ParameterInfo[];
170
+ declare function extractParameters(parsed: OpenApiDocument, path: string, method: string, diagnostics?: DiagnosticsOptions): ParameterInfo[];
171
171
  /**
172
172
  * Resolve the request body of a single operation, including its
173
173
  * declared content types and schema. Returns `undefined` when the
174
174
  * operation declares no request body.
175
175
  */
176
- declare function getRequestBody(parsed: OpenApiDocument, path: string, method: string): RequestBodyInfo | undefined;
176
+ declare function extractRequestBody(parsed: OpenApiDocument, path: string, method: string): RequestBodyInfo | undefined;
177
177
  /**
178
178
  * Resolve the responses of a single operation, returning one
179
179
  * {@link ResponseInfo} per declared status code (including class
180
180
  * wildcards and `default`).
181
181
  */
182
- declare function getResponses(parsed: OpenApiDocument, path: string, method: string, diagnostics?: DiagnosticsOptions): ResponseInfo[];
182
+ declare function extractResponses(parsed: OpenApiDocument, path: string, method: string, diagnostics?: DiagnosticsOptions): ResponseInfo[];
183
183
  /**
184
184
  * Resolve the effective security requirements for a single operation.
185
185
  * Operation-level requirements override the document-level defaults
186
186
  * when present.
187
187
  */
188
- declare function getSecurityRequirements(parsed: OpenApiDocument, path: string, method: string): SecurityRequirement[];
188
+ declare function extractSecurityRequirements(parsed: OpenApiDocument, path: string, method: string): SecurityRequirement[];
189
189
  /**
190
190
  * Read the document's `components.securitySchemes` map as a map of
191
191
  * scheme names to {@link SecurityScheme} entries.
192
192
  */
193
- declare function getSecuritySchemes(parsed: OpenApiDocument): Map<string, SecurityScheme>;
193
+ declare function extractSecuritySchemes(parsed: OpenApiDocument): Map<string, SecurityScheme>;
194
194
  /**
195
195
  * Resolve the headers of a single OpenAPI Response Object as a map of
196
196
  * header name to {@link HeaderInfo}. Follows Header Object `$ref`
197
197
  * chains via the optional document root.
198
198
  */
199
- declare function getResponseHeaders(response: JsonObject, doc?: JsonObject, diagnostics?: DiagnosticsOptions): Map<string, HeaderInfo>;
199
+ declare function extractResponseHeaders(response: JsonObject, doc?: JsonObject, diagnostics?: DiagnosticsOptions): Map<string, HeaderInfo>;
200
200
  /**
201
201
  * List every OpenAPI 3.1 webhook declared under the document's
202
202
  * `webhooks` map, each with its name and resolved operations.
@@ -216,13 +216,13 @@ declare function listAllOperations(parsed: OpenApiDocument, diagnostics?: Diagno
216
216
  * (document, operation, tag, schema, ...) into an {@link ExternalDocs}
217
217
  * record. Returns `undefined` when absent or malformed.
218
218
  */
219
- declare function getExternalDocs(obj: JsonObject): ExternalDocs | undefined;
219
+ declare function extractExternalDocs(obj: JsonObject): ExternalDocs | undefined;
220
220
  /**
221
221
  * Read the optional `xml` keyword on a JSON Schema object into an
222
222
  * {@link XmlInfo} record describing how the field is serialised in an
223
223
  * XML payload. Returns `undefined` when absent or malformed.
224
224
  */
225
- declare function getXmlInfo(schema: JsonObject): XmlInfo | undefined;
225
+ declare function extractXmlInfo(schema: JsonObject): XmlInfo | undefined;
226
226
  /**
227
227
  * List the OpenAPI callback definitions declared on a single
228
228
  * operation. Each entry carries the callback name and the operations
@@ -234,6 +234,6 @@ declare function listCallbacks(parsed: OpenApiDocument, path: string, method: st
234
234
  * a single operation, returning each link's parsed
235
235
  * {@link LinkInfo} entry.
236
236
  */
237
- declare function getLinks(parsed: OpenApiDocument, path: string, method: string, statusCode: string, diagnostics?: DiagnosticsOptions): LinkInfo[];
237
+ declare function extractLinks(parsed: OpenApiDocument, path: string, method: string, statusCode: string, diagnostics?: DiagnosticsOptions): LinkInfo[];
238
238
  //#endregion
239
- 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 };
239
+ export { CallbackInfo, ExternalDocs, HeaderInfo, LinkInfo, OpenApiDocument, OperationInfo, ParameterInfo, ParameterLocation, RequestBodyInfo, ResponseInfo, SecurityRequirement, SecurityScheme, WebhookInfo, XmlInfo, extractExternalDocs, extractLinks, extractParameters, extractRequestBody, extractResponseHeaders, extractResponses, extractSchema, extractSecurityRequirements, extractSecuritySchemes, extractXmlInfo, listAllOperations, listCallbacks, listOperations, listWebhooks, parseOpenApiDocument };
@@ -58,7 +58,7 @@ function parseOpenApiDocument(doc) {
58
58
  * resolved value for arbitrary fragment refs), or `undefined` when the
59
59
  * ref cannot be resolved.
60
60
  */
61
- function getSchema(parsed, ref) {
61
+ function extractSchema(parsed, ref) {
62
62
  const cached = parsed.schemas.get(ref);
63
63
  if (cached !== void 0) return cached;
64
64
  const resolved = resolveRefInDoc(parsed.doc, ref);
@@ -174,7 +174,7 @@ function listOperations(parsed, diagnostics, seenIds = /* @__PURE__ */ new Map()
174
174
  * parameters with operation-level overrides and following any
175
175
  * Parameter Object `$ref` chains.
176
176
  */
177
- function getParameters(parsed, path, method, diagnostics) {
177
+ function extractParameters(parsed, path, method, diagnostics) {
178
178
  const pathItem = lookupPathItem(parsed, path);
179
179
  if (pathItem === void 0) return [];
180
180
  const operation = getProperty(pathItem, method);
@@ -275,7 +275,7 @@ function jsonPointerEscape(segment) {
275
275
  * declared content types and schema. Returns `undefined` when the
276
276
  * operation declares no request body.
277
277
  */
278
- function getRequestBody(parsed, path, method) {
278
+ function extractRequestBody(parsed, path, method) {
279
279
  const requestBodyRaw = getProperty(getProperty(lookupPathItem(parsed, path), method), "requestBody");
280
280
  if (!isObject(requestBodyRaw)) return void 0;
281
281
  const requestBody = resolveWrapperRef(parsed.doc, requestBodyRaw);
@@ -301,7 +301,7 @@ function getRequestBody(parsed, path, method) {
301
301
  * {@link ResponseInfo} per declared status code (including class
302
302
  * wildcards and `default`).
303
303
  */
304
- function getResponses(parsed, path, method, diagnostics) {
304
+ function extractResponses(parsed, path, method, diagnostics) {
305
305
  const responses = getProperty(getProperty(lookupPathItem(parsed, path), method), "responses");
306
306
  if (!isObject(responses)) return [];
307
307
  const result = [];
@@ -312,7 +312,7 @@ function getResponses(parsed, path, method, diagnostics) {
312
312
  const content = getProperty(response, "content");
313
313
  const contentTypes = isObject(content) ? Object.keys(content) : [];
314
314
  const schema = isObject(content) ? extractSchemaFromContent(content) : void 0;
315
- const headers = getResponseHeaders(response, parsed.doc, diagnostics);
315
+ const headers = extractResponseHeaders(response, parsed.doc, diagnostics);
316
316
  result.push({
317
317
  statusCode,
318
318
  description: getString(response, "description"),
@@ -448,7 +448,7 @@ function resolveRefInDoc(doc, ref) {
448
448
  * Operation-level requirements override the document-level defaults
449
449
  * when present.
450
450
  */
451
- function getSecurityRequirements(parsed, path, method) {
451
+ function extractSecurityRequirements(parsed, path, method) {
452
452
  const opSecurity = getProperty(getProperty(lookupPathItem(parsed, path), method), "security");
453
453
  const globalSecurity = getProperty(parsed.doc, "security");
454
454
  const securityArray = Array.isArray(opSecurity) ? opSecurity : Array.isArray(globalSecurity) ? globalSecurity : [];
@@ -466,7 +466,7 @@ function getSecurityRequirements(parsed, path, method) {
466
466
  * Read the document's `components.securitySchemes` map as a map of
467
467
  * scheme names to {@link SecurityScheme} entries.
468
468
  */
469
- function getSecuritySchemes(parsed) {
469
+ function extractSecuritySchemes(parsed) {
470
470
  const result = /* @__PURE__ */ new Map();
471
471
  const securitySchemes = getProperty(getProperty(parsed.doc, "components"), "securitySchemes");
472
472
  if (!isObject(securitySchemes)) return result;
@@ -491,7 +491,7 @@ function getSecuritySchemes(parsed) {
491
491
  * header name to {@link HeaderInfo}. Follows Header Object `$ref`
492
492
  * chains via the optional document root.
493
493
  */
494
- function getResponseHeaders(response, doc, diagnostics) {
494
+ function extractResponseHeaders(response, doc, diagnostics) {
495
495
  const result = /* @__PURE__ */ new Map();
496
496
  const headers = getProperty(response, "headers");
497
497
  if (!isObject(headers)) return result;
@@ -562,7 +562,7 @@ function listAllOperations(parsed, diagnostics) {
562
562
  * (document, operation, tag, schema, ...) into an {@link ExternalDocs}
563
563
  * record. Returns `undefined` when absent or malformed.
564
564
  */
565
- function getExternalDocs(obj) {
565
+ function extractExternalDocs(obj) {
566
566
  const docs = getProperty(obj, "externalDocs");
567
567
  if (!isObject(docs)) return void 0;
568
568
  const url = getString(docs, "url");
@@ -577,7 +577,7 @@ function getExternalDocs(obj) {
577
577
  * {@link XmlInfo} record describing how the field is serialised in an
578
578
  * XML payload. Returns `undefined` when absent or malformed.
579
579
  */
580
- function getXmlInfo(schema) {
580
+ function extractXmlInfo(schema) {
581
581
  const xml = getProperty(schema, "xml");
582
582
  if (!isObject(xml)) return void 0;
583
583
  return {
@@ -631,7 +631,7 @@ function listCallbacks(parsed, path, method, diagnostics) {
631
631
  * a single operation, returning each link's parsed
632
632
  * {@link LinkInfo} entry.
633
633
  */
634
- function getLinks(parsed, path, method, statusCode, diagnostics) {
634
+ function extractLinks(parsed, path, method, statusCode, diagnostics) {
635
635
  const response = getProperty(getProperty(getProperty(lookupPathItem(parsed, path), method), "responses"), statusCode);
636
636
  if (!isObject(response)) return [];
637
637
  const links = getProperty(response, "links");
@@ -657,4 +657,4 @@ function getLinks(parsed, path, method, statusCode, diagnostics) {
657
657
  return result;
658
658
  }
659
659
  //#endregion
660
- export { getExternalDocs, getLinks, getParameters, getRequestBody, getResponseHeaders, getResponses, getSchema, getSecurityRequirements, getSecuritySchemes, getXmlInfo, listAllOperations, listCallbacks, listOperations, listWebhooks, parseOpenApiDocument };
660
+ export { extractExternalDocs, extractLinks, extractParameters, extractRequestBody, extractResponseHeaders, extractResponses, extractSchema, extractSecurityRequirements, extractSecuritySchemes, extractXmlInfo, listAllOperations, listCallbacks, listOperations, listWebhooks, parseOpenApiDocument };