vocs 2.0.17 → 2.1.2
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/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/globals.d.ts +16 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/internal/config.d.ts +28 -0
- package/dist/internal/config.d.ts.map +1 -1
- package/dist/internal/config.js +10 -2
- package/dist/internal/config.js.map +1 -1
- package/dist/internal/llms.d.ts +21 -2
- package/dist/internal/llms.d.ts.map +1 -1
- package/dist/internal/llms.js +41 -1
- package/dist/internal/llms.js.map +1 -1
- package/dist/internal/markdown-negotiation.d.ts +36 -0
- package/dist/internal/markdown-negotiation.d.ts.map +1 -0
- package/dist/internal/markdown-negotiation.js +81 -0
- package/dist/internal/markdown-negotiation.js.map +1 -0
- package/dist/internal/markdown.d.ts.map +1 -1
- package/dist/internal/markdown.js +5 -0
- package/dist/internal/markdown.js.map +1 -1
- package/dist/internal/openapi/anchors.d.ts +25 -0
- package/dist/internal/openapi/anchors.d.ts.map +1 -0
- package/dist/internal/openapi/anchors.js +37 -0
- package/dist/internal/openapi/anchors.js.map +1 -0
- package/dist/internal/openapi/app.d.ts +89 -0
- package/dist/internal/openapi/app.d.ts.map +1 -0
- package/dist/internal/openapi/app.js +62 -0
- package/dist/internal/openapi/app.js.map +1 -0
- package/dist/internal/openapi/index.d.ts +8 -0
- package/dist/internal/openapi/index.d.ts.map +1 -0
- package/dist/internal/openapi/index.js +5 -0
- package/dist/internal/openapi/index.js.map +1 -0
- package/dist/internal/openapi/markdown.d.ts +42 -0
- package/dist/internal/openapi/markdown.d.ts.map +1 -0
- package/dist/internal/openapi/markdown.js +235 -0
- package/dist/internal/openapi/markdown.js.map +1 -0
- package/dist/internal/openapi/openapi.d.ts +187 -0
- package/dist/internal/openapi/openapi.d.ts.map +1 -0
- package/dist/internal/openapi/openapi.js +44 -0
- package/dist/internal/openapi/openapi.js.map +1 -0
- package/dist/internal/openapi/openrpc.d.ts +90 -0
- package/dist/internal/openapi/openrpc.d.ts.map +1 -0
- package/dist/internal/openapi/openrpc.js +213 -0
- package/dist/internal/openapi/openrpc.js.map +1 -0
- package/dist/internal/openapi/parser.d.ts +181 -0
- package/dist/internal/openapi/parser.d.ts.map +1 -0
- package/dist/internal/openapi/parser.js +329 -0
- package/dist/internal/openapi/parser.js.map +1 -0
- package/dist/internal/openapi/registry.d.ts +36 -0
- package/dist/internal/openapi/registry.d.ts.map +1 -0
- package/dist/internal/openapi/registry.js +79 -0
- package/dist/internal/openapi/registry.js.map +1 -0
- package/dist/internal/openapi/sample.d.ts +115 -0
- package/dist/internal/openapi/sample.d.ts.map +1 -0
- package/dist/internal/openapi/sample.js +434 -0
- package/dist/internal/openapi/sample.js.map +1 -0
- package/dist/internal/openapi/search.d.ts +19 -0
- package/dist/internal/openapi/search.d.ts.map +1 -0
- package/dist/internal/openapi/search.js +98 -0
- package/dist/internal/openapi/search.js.map +1 -0
- package/dist/internal/openapi/sidebar.d.ts +30 -0
- package/dist/internal/openapi/sidebar.d.ts.map +1 -0
- package/dist/internal/openapi/sidebar.js +67 -0
- package/dist/internal/openapi/sidebar.js.map +1 -0
- package/dist/internal/openapi/union.d.ts +36 -0
- package/dist/internal/openapi/union.d.ts.map +1 -0
- package/dist/internal/openapi/union.js +69 -0
- package/dist/internal/openapi/union.js.map +1 -0
- package/dist/internal/search.d.ts.map +1 -1
- package/dist/internal/search.js +20 -0
- package/dist/internal/search.js.map +1 -1
- package/dist/internal/vite-plugins.d.ts +12 -0
- package/dist/internal/vite-plugins.d.ts.map +1 -1
- package/dist/internal/vite-plugins.js +102 -11
- package/dist/internal/vite-plugins.js.map +1 -1
- package/dist/react/Badge.d.ts +2 -3
- package/dist/react/Badge.d.ts.map +1 -1
- package/dist/react/Layout.client.d.ts.map +1 -1
- package/dist/react/Layout.client.js +2 -2
- package/dist/react/Layout.client.js.map +1 -1
- package/dist/react/OpenApi.d.ts +6 -0
- package/dist/react/OpenApi.d.ts.map +1 -0
- package/dist/react/OpenApi.js +6 -0
- package/dist/react/OpenApi.js.map +1 -0
- package/dist/react/internal/CodeToHtml.client.d.ts +53 -2
- package/dist/react/internal/CodeToHtml.client.d.ts.map +1 -1
- package/dist/react/internal/CodeToHtml.client.js +154 -21
- package/dist/react/internal/CodeToHtml.client.js.map +1 -1
- package/dist/react/internal/Sidebar.d.ts.map +1 -1
- package/dist/react/internal/Sidebar.js +99 -2
- package/dist/react/internal/Sidebar.js.map +1 -1
- package/dist/react/internal/openapi/CodeSample.client.d.ts +21 -0
- package/dist/react/internal/openapi/CodeSample.client.d.ts.map +1 -0
- package/dist/react/internal/openapi/CodeSample.client.js +134 -0
- package/dist/react/internal/openapi/CodeSample.client.js.map +1 -0
- package/dist/react/internal/openapi/CollapsibleChildren.client.d.ts +17 -0
- package/dist/react/internal/openapi/CollapsibleChildren.client.d.ts.map +1 -0
- package/dist/react/internal/openapi/CollapsibleChildren.client.js +18 -0
- package/dist/react/internal/openapi/CollapsibleChildren.client.js.map +1 -0
- package/dist/react/internal/openapi/Disclosure.client.d.ts +28 -0
- package/dist/react/internal/openapi/Disclosure.client.d.ts.map +1 -0
- package/dist/react/internal/openapi/Disclosure.client.js +38 -0
- package/dist/react/internal/openapi/Disclosure.client.js.map +1 -0
- package/dist/react/internal/openapi/Endpoints.d.ts +26 -0
- package/dist/react/internal/openapi/Endpoints.d.ts.map +1 -0
- package/dist/react/internal/openapi/Endpoints.js +33 -0
- package/dist/react/internal/openapi/Endpoints.js.map +1 -0
- package/dist/react/internal/openapi/EndpointsView.d.ts +24 -0
- package/dist/react/internal/openapi/EndpointsView.d.ts.map +1 -0
- package/dist/react/internal/openapi/EndpointsView.js +26 -0
- package/dist/react/internal/openapi/EndpointsView.js.map +1 -0
- package/dist/react/internal/openapi/EnumValues.client.d.ts +14 -0
- package/dist/react/internal/openapi/EnumValues.client.d.ts.map +1 -0
- package/dist/react/internal/openapi/EnumValues.client.js +20 -0
- package/dist/react/internal/openapi/EnumValues.client.js.map +1 -0
- package/dist/react/internal/openapi/HeadingAnchor.d.ts +15 -0
- package/dist/react/internal/openapi/HeadingAnchor.d.ts.map +1 -0
- package/dist/react/internal/openapi/HeadingAnchor.js +12 -0
- package/dist/react/internal/openapi/HeadingAnchor.js.map +1 -0
- package/dist/react/internal/openapi/OpenApiPage.d.ts +79 -0
- package/dist/react/internal/openapi/OpenApiPage.d.ts.map +1 -0
- package/dist/react/internal/openapi/OpenApiPage.js +72 -0
- package/dist/react/internal/openapi/OpenApiPage.js.map +1 -0
- package/dist/react/internal/openapi/Operation.d.ts +25 -0
- package/dist/react/internal/openapi/Operation.d.ts.map +1 -0
- package/dist/react/internal/openapi/Operation.js +101 -0
- package/dist/react/internal/openapi/Operation.js.map +1 -0
- package/dist/react/internal/openapi/Playground.client.d.ts +33 -0
- package/dist/react/internal/openapi/Playground.client.d.ts.map +1 -0
- package/dist/react/internal/openapi/Playground.client.js +170 -0
- package/dist/react/internal/openapi/Playground.client.js.map +1 -0
- package/dist/react/internal/openapi/PropertyExample.client.d.ts +17 -0
- package/dist/react/internal/openapi/PropertyExample.client.d.ts.map +1 -0
- package/dist/react/internal/openapi/PropertyExample.client.js +21 -0
- package/dist/react/internal/openapi/PropertyExample.client.js.map +1 -0
- package/dist/react/internal/openapi/Reference.d.ts +55 -0
- package/dist/react/internal/openapi/Reference.d.ts.map +1 -0
- package/dist/react/internal/openapi/Reference.js +42 -0
- package/dist/react/internal/openapi/Reference.js.map +1 -0
- package/dist/react/internal/openapi/Schema.d.ts +110 -0
- package/dist/react/internal/openapi/Schema.d.ts.map +1 -0
- package/dist/react/internal/openapi/Schema.js +239 -0
- package/dist/react/internal/openapi/Schema.js.map +1 -0
- package/dist/react/internal/openapi/SchemaUnion.client.d.ts +25 -0
- package/dist/react/internal/openapi/SchemaUnion.client.d.ts.map +1 -0
- package/dist/react/internal/openapi/SchemaUnion.client.js +48 -0
- package/dist/react/internal/openapi/SchemaUnion.client.js.map +1 -0
- package/dist/react/internal/openapi/anchor-navigation.client.d.ts +47 -0
- package/dist/react/internal/openapi/anchor-navigation.client.d.ts.map +1 -0
- package/dist/react/internal/openapi/anchor-navigation.client.js +120 -0
- package/dist/react/internal/openapi/anchor-navigation.client.js.map +1 -0
- package/dist/react/internal/openapi/auth.d.ts +28 -0
- package/dist/react/internal/openapi/auth.d.ts.map +1 -0
- package/dist/react/internal/openapi/auth.js +75 -0
- package/dist/react/internal/openapi/auth.js.map +1 -0
- package/dist/react/useLayout.d.ts +2 -0
- package/dist/react/useLayout.d.ts.map +1 -1
- package/dist/react/useLayout.js +2 -0
- package/dist/react/useLayout.js.map +1 -1
- package/dist/server/handlers.d.ts +1 -1
- package/dist/server/handlers.d.ts.map +1 -1
- package/dist/server/handlers.js +26 -5
- package/dist/server/handlers.js.map +1 -1
- package/dist/server/og-assets.d.ts +5 -0
- package/dist/server/og-assets.d.ts.map +1 -0
- package/dist/server/og-assets.js +11 -0
- package/dist/server/og-assets.js.map +1 -0
- package/dist/server/openapi/assets.d.ts +33 -0
- package/dist/server/openapi/assets.d.ts.map +1 -0
- package/dist/server/openapi/assets.generated.d.ts +9 -0
- package/dist/server/openapi/assets.generated.d.ts.map +1 -0
- package/dist/server/openapi/assets.generated.js +1091 -0
- package/dist/server/openapi/assets.generated.js.map +1 -0
- package/dist/server/openapi/assets.js +32 -0
- package/dist/server/openapi/assets.js.map +1 -0
- package/dist/server/openapi/handler.d.ts +103 -0
- package/dist/server/openapi/handler.d.ts.map +1 -0
- package/dist/server/openapi/handler.js +198 -0
- package/dist/server/openapi/handler.js.map +1 -0
- package/dist/server/openapi/handler.test.d.ts +2 -0
- package/dist/server/openapi/handler.test.d.ts.map +1 -0
- package/dist/server/openapi/handler.test.js +203 -0
- package/dist/server/openapi/handler.test.js.map +1 -0
- package/dist/server/openapi/html.d.ts +16 -0
- package/dist/server/openapi/html.d.ts.map +1 -0
- package/dist/server/openapi/html.js +75 -0
- package/dist/server/openapi/html.js.map +1 -0
- package/dist/server/openapi/pages.d.ts +33 -0
- package/dist/server/openapi/pages.d.ts.map +1 -0
- package/dist/server/openapi/pages.js +130 -0
- package/dist/server/openapi/pages.js.map +1 -0
- package/dist/server/openapi/pages.test.d.ts +2 -0
- package/dist/server/openapi/pages.test.d.ts.map +1 -0
- package/dist/server/openapi/pages.test.js +94 -0
- package/dist/server/openapi/pages.test.js.map +1 -0
- package/dist/server/openapi/state.d.ts +42 -0
- package/dist/server/openapi/state.d.ts.map +1 -0
- package/dist/server/openapi/state.js +101 -0
- package/dist/server/openapi/state.js.map +1 -0
- package/dist/styles/index.css +16 -0
- package/dist/styles/markdown.css +9 -7
- package/dist/styles/openapi-playground.css +80 -0
- package/dist/styles/openapi.css +660 -0
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +1 -0
- package/dist/vite.js.map +1 -1
- package/dist/waku/internal/middleware/md-router.d.ts +0 -4
- package/dist/waku/internal/middleware/md-router.d.ts.map +1 -1
- package/dist/waku/internal/middleware/md-router.js +3 -48
- package/dist/waku/internal/middleware/md-router.js.map +1 -1
- package/dist/waku/internal/patches/adapters/vercel-build-enhancer.js +1 -1
- package/dist/waku/internal/patches/adapters/vercel-build-enhancer.js.map +1 -1
- package/dist/waku/internal/patches/router.d.ts.map +1 -1
- package/dist/waku/internal/patches/router.js +114 -1
- package/dist/waku/internal/patches/router.js.map +1 -1
- package/package.json +5 -1
- package/src/config.ts +1 -0
- package/src/globals.d.ts +16 -0
- package/src/index.ts +1 -0
- package/src/internal/config.ts +40 -1
- package/src/internal/llms.ts +51 -1
- package/src/internal/markdown-negotiation.test.ts +42 -0
- package/src/internal/markdown-negotiation.ts +95 -0
- package/src/internal/markdown.ts +5 -0
- package/src/internal/openapi/anchors.ts +44 -0
- package/src/internal/openapi/app.ts +127 -0
- package/src/internal/openapi/index.ts +24 -0
- package/src/internal/openapi/markdown.test.ts +115 -0
- package/src/internal/openapi/markdown.ts +275 -0
- package/src/internal/openapi/openapi.ts +212 -0
- package/src/internal/openapi/openrpc.test.ts +239 -0
- package/src/internal/openapi/openrpc.ts +295 -0
- package/src/internal/openapi/parser.test.ts +203 -0
- package/src/internal/openapi/parser.ts +613 -0
- package/src/internal/openapi/registry.test.ts +89 -0
- package/src/internal/openapi/registry.ts +89 -0
- package/src/internal/openapi/sample.test.ts +283 -0
- package/src/internal/openapi/sample.ts +562 -0
- package/src/internal/openapi/search.test.ts +62 -0
- package/src/internal/openapi/search.ts +108 -0
- package/src/internal/openapi/sidebar.test.ts +131 -0
- package/src/internal/openapi/sidebar.ts +94 -0
- package/src/internal/openapi/union.test.ts +51 -0
- package/src/internal/openapi/union.ts +74 -0
- package/src/internal/search.ts +20 -0
- package/src/internal/test/virtual-config.stub.ts +14 -0
- package/src/internal/vite-plugins.ts +106 -11
- package/src/openapi-app/App.tsx +64 -0
- package/src/openapi-app/blocks.tsx +33 -0
- package/src/openapi-app/client.tsx +25 -0
- package/src/openapi-app/links.test.ts +84 -0
- package/src/openapi-app/links.ts +66 -0
- package/src/openapi-app/payload.ts +20 -0
- package/src/openapi-app/virtual/config.ts +7 -0
- package/src/openapi-app/virtual/group-icons.ts +2 -0
- package/src/openapi-app/virtual/langs.ts +6 -0
- package/src/openapi-app/virtual/openapi.ts +10 -0
- package/src/openapi-app/virtual/search-index.ts +21 -0
- package/src/openapi-app/virtual/slots.ts +4 -0
- package/src/openapi-app/virtual/user-styles.ts +2 -0
- package/src/openapi-app/waku.tsx +154 -0
- package/src/react/Badge.tsx +2 -3
- package/src/react/Layout.client.tsx +17 -4
- package/src/react/OpenApi.tsx +5 -0
- package/src/react/internal/CodeToHtml.client.tsx +283 -22
- package/src/react/internal/Sidebar.tsx +126 -22
- package/src/react/internal/openapi/CodeSample.client.tsx +294 -0
- package/src/react/internal/openapi/CollapsibleChildren.client.tsx +41 -0
- package/src/react/internal/openapi/Disclosure.client.tsx +67 -0
- package/src/react/internal/openapi/Endpoints.tsx +58 -0
- package/src/react/internal/openapi/EndpointsView.tsx +76 -0
- package/src/react/internal/openapi/EnumValues.client.tsx +49 -0
- package/src/react/internal/openapi/HeadingAnchor.tsx +28 -0
- package/src/react/internal/openapi/OpenApiPage.tsx +173 -0
- package/src/react/internal/openapi/Operation.test.tsx +101 -0
- package/src/react/internal/openapi/Operation.tsx +335 -0
- package/src/react/internal/openapi/Playground.client.tsx +234 -0
- package/src/react/internal/openapi/PropertyExample.client.tsx +55 -0
- package/src/react/internal/openapi/Reference.tsx +120 -0
- package/src/react/internal/openapi/Schema.tsx +467 -0
- package/src/react/internal/openapi/SchemaUnion.client.tsx +123 -0
- package/src/react/internal/openapi/anchor-navigation.client.ts +154 -0
- package/src/react/internal/openapi/auth.ts +69 -0
- package/src/react/useLayout.ts +4 -0
- package/src/server/handlers.ts +31 -6
- package/src/server/og-assets.ts +14 -0
- package/src/server/openapi/assets.generated.ts +1093 -0
- package/src/server/openapi/assets.ts +57 -0
- package/src/server/openapi/handler.test.ts +244 -0
- package/src/server/openapi/handler.ts +277 -0
- package/src/server/openapi/html.ts +84 -0
- package/src/server/openapi/pages.test.ts +111 -0
- package/src/server/openapi/pages.ts +153 -0
- package/src/server/openapi/state.ts +136 -0
- package/src/styles/index.css +16 -0
- package/src/styles/markdown.css +9 -7
- package/src/styles/openapi-playground.css +80 -0
- package/src/styles/openapi.css +660 -0
- package/src/vite.ts +1 -0
- package/src/waku/internal/middleware/md-router.ts +8 -52
- package/src/waku/internal/patches/adapters/vercel-build-enhancer.ts +1 -1
- package/src/waku/internal/patches/router.ts +131 -1
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
import { Fragment } from 'react'
|
|
2
|
+
import * as Markdown from '../../../internal/markdown.js'
|
|
3
|
+
import { type SchemaPath, schemaPropertyId } from '../../../internal/openapi/anchors.js'
|
|
4
|
+
import {
|
|
5
|
+
unionVariantSchemas,
|
|
6
|
+
unionVariantSegment,
|
|
7
|
+
unwrapSingleVariant,
|
|
8
|
+
} from '../../../internal/openapi/union.js'
|
|
9
|
+
import { Badge } from '../../Badge.js'
|
|
10
|
+
import { CollapsibleChildren } from './CollapsibleChildren.client.js'
|
|
11
|
+
import { EnumValues } from './EnumValues.client.js'
|
|
12
|
+
import { HeadingAnchor } from './HeadingAnchor.js'
|
|
13
|
+
import { PropertyExample } from './PropertyExample.client.js'
|
|
14
|
+
import { SchemaUnion } from './SchemaUnion.client.js'
|
|
15
|
+
|
|
16
|
+
type SchemaObject = Record<string, unknown>
|
|
17
|
+
|
|
18
|
+
const maxDepth = 6
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Renders a human-readable type label for a JSON Schema (post-dereference).
|
|
22
|
+
*/
|
|
23
|
+
export function typeLabel(schema: SchemaObject | undefined): string {
|
|
24
|
+
if (!schema) return 'unknown'
|
|
25
|
+
|
|
26
|
+
if (Array.isArray(schema['type'])) return (schema['type'] as string[]).join(' | ')
|
|
27
|
+
|
|
28
|
+
const composite = (schema['oneOf'] ?? schema['anyOf']) as SchemaObject[] | undefined
|
|
29
|
+
if (composite) return composite.map(typeLabel).join(' | ')
|
|
30
|
+
|
|
31
|
+
if (Array.isArray(schema['allOf']))
|
|
32
|
+
return (schema['allOf'] as SchemaObject[]).map(typeLabel).join(' & ')
|
|
33
|
+
|
|
34
|
+
if (schema['type'] === 'array') return `${typeLabel(schema['items'] as SchemaObject)}[]`
|
|
35
|
+
|
|
36
|
+
if (typeof schema['type'] === 'string') {
|
|
37
|
+
const format = schema['format'] ? ` <${schema['format']}>` : ''
|
|
38
|
+
return `${schema['type']}${format}`
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Enum without an explicit `type`: the literal values are rendered separately
|
|
42
|
+
// as a values list (see {@link enumValues}), so just label it `enum`.
|
|
43
|
+
if (Array.isArray(schema['enum'])) return 'enum'
|
|
44
|
+
|
|
45
|
+
if (schema['properties']) return 'object'
|
|
46
|
+
|
|
47
|
+
return 'unknown'
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Detects a `oneOf`/`anyOf` union (unwrapping array item schemas) worth showing
|
|
52
|
+
* as a {@link SchemaUnion} variant picker, returning its variants. Trivial
|
|
53
|
+
* `null` members are dropped, and plain scalar unions with no extra info (e.g.
|
|
54
|
+
* `string | number`) keep their inline type label instead — the picker is only
|
|
55
|
+
* used when at least one variant carries something to show (object properties,
|
|
56
|
+
* an enum, a `const`, a format, or a title).
|
|
57
|
+
*/
|
|
58
|
+
export function unionVariants(schema: SchemaObject | undefined): unionVariants.Result | undefined {
|
|
59
|
+
const variants = unionVariantSchemas(schema)
|
|
60
|
+
if (!variants) return undefined
|
|
61
|
+
const target =
|
|
62
|
+
schema?.['type'] === 'array' && schema['items'] ? (schema['items'] as SchemaObject) : schema
|
|
63
|
+
const oneOf = target?.['oneOf']
|
|
64
|
+
return {
|
|
65
|
+
kind: oneOf ? 'One of' : 'Any of',
|
|
66
|
+
variants: variants.map((member, index) => ({
|
|
67
|
+
name: variantName(member, index),
|
|
68
|
+
schema: member,
|
|
69
|
+
})),
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** A human-readable label for a single union variant. */
|
|
74
|
+
function variantName(member: SchemaObject, index: number): string {
|
|
75
|
+
if (typeof member['title'] === 'string' && member['title']) return member['title']
|
|
76
|
+
if ('const' in member) return stringify(member['const'])
|
|
77
|
+
const values = enumValues(member)
|
|
78
|
+
if (values && values.length > 0) {
|
|
79
|
+
const joined = values.join(' | ')
|
|
80
|
+
if (joined.length <= 32) return joined
|
|
81
|
+
return 'enum'
|
|
82
|
+
}
|
|
83
|
+
return typeLabel(member) || `Option ${index + 1}`
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export declare namespace unionVariants {
|
|
87
|
+
type Result = {
|
|
88
|
+
kind: string
|
|
89
|
+
variants: { name: string; schema: SchemaObject }[]
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Extracts a schema's enum literals as display strings (strings unquoted, other
|
|
95
|
+
* values JSON-stringified), unwrapping array item schemas. These are rendered
|
|
96
|
+
* as a separate "values" list rather than a wrapping inline union, matching the
|
|
97
|
+
* Scalar/Stripe reference UI.
|
|
98
|
+
*/
|
|
99
|
+
export function enumValues(schema: SchemaObject | undefined): string[] | undefined {
|
|
100
|
+
if (!schema) return undefined
|
|
101
|
+
const target =
|
|
102
|
+
schema['type'] === 'array' && schema['items'] ? (schema['items'] as SchemaObject) : schema
|
|
103
|
+
const values = target['enum']
|
|
104
|
+
if (!Array.isArray(values) || values.length === 0) return undefined
|
|
105
|
+
return values.map((value) => (typeof value === 'string' ? value : JSON.stringify(value)))
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Builds the constraint metadata shown beneath a property/parameter type as
|
|
110
|
+
* `{ label, value }` pairs (e.g. `min 0`, `max 100`, `default 10`), in the
|
|
111
|
+
* style of Scalar/Stripe references. The type itself is rendered separately
|
|
112
|
+
* (see {@link typeLabel}).
|
|
113
|
+
*/
|
|
114
|
+
export function schemaMeta(schema: SchemaObject | undefined): schemaMeta.Entry[] {
|
|
115
|
+
if (!schema) return []
|
|
116
|
+
const parts: schemaMeta.Entry[] = []
|
|
117
|
+
|
|
118
|
+
const num = (key: string) =>
|
|
119
|
+
typeof schema[key] === 'number' ? (schema[key] as number) : undefined
|
|
120
|
+
const min = num('minimum') ?? num('minLength') ?? num('minItems')
|
|
121
|
+
const max = num('maximum') ?? num('maxLength') ?? num('maxItems')
|
|
122
|
+
if (min !== undefined) parts.push({ label: 'min', value: String(min) })
|
|
123
|
+
if (max !== undefined) parts.push({ label: 'max', value: String(max) })
|
|
124
|
+
|
|
125
|
+
if ('const' in schema) parts.push({ label: 'const', value: stringify(schema['const']) })
|
|
126
|
+
if ('default' in schema) parts.push({ label: 'default', value: stringify(schema['default']) })
|
|
127
|
+
|
|
128
|
+
return parts
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export declare namespace schemaMeta {
|
|
132
|
+
type Entry = { label: string; value: string }
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function stringify(value: unknown): string {
|
|
136
|
+
if (typeof value === 'string') return value
|
|
137
|
+
return JSON.stringify(value)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Extracts a representative example value from a schema (`example` or the first
|
|
142
|
+
* entry of `examples`), returned as a display string.
|
|
143
|
+
*/
|
|
144
|
+
export function schemaExample(schema: SchemaObject | undefined): string | undefined {
|
|
145
|
+
if (!schema) return undefined
|
|
146
|
+
if ('example' in schema) return stringify(schema['example'])
|
|
147
|
+
const examples = schema['examples']
|
|
148
|
+
if (Array.isArray(examples) && examples.length > 0) return stringify(examples[0])
|
|
149
|
+
return undefined
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* A single parameter/property row: name + inline metadata, an optional
|
|
154
|
+
* markdown description, and optional nested content (child schema). Rows are
|
|
155
|
+
* separated by a top border rather than wrapped in individual cards.
|
|
156
|
+
*/
|
|
157
|
+
export function PropertyRow(props: PropertyRow.Props) {
|
|
158
|
+
const {
|
|
159
|
+
id,
|
|
160
|
+
name,
|
|
161
|
+
prefix,
|
|
162
|
+
type,
|
|
163
|
+
values,
|
|
164
|
+
meta,
|
|
165
|
+
example,
|
|
166
|
+
required,
|
|
167
|
+
deprecated,
|
|
168
|
+
description,
|
|
169
|
+
children,
|
|
170
|
+
} = props
|
|
171
|
+
const inline: { key: string; node: React.ReactNode }[] = [
|
|
172
|
+
...(type
|
|
173
|
+
? [
|
|
174
|
+
{
|
|
175
|
+
key: 'type',
|
|
176
|
+
node: (
|
|
177
|
+
<code data-v data-v-openapi-type>
|
|
178
|
+
{type}
|
|
179
|
+
</code>
|
|
180
|
+
),
|
|
181
|
+
},
|
|
182
|
+
]
|
|
183
|
+
: []),
|
|
184
|
+
...meta.map((item) => ({
|
|
185
|
+
key: item.label,
|
|
186
|
+
node: (
|
|
187
|
+
<span>
|
|
188
|
+
<span data-v-openapi-meta-label>{item.label} </span>
|
|
189
|
+
<span data-v-openapi-meta-value>{item.value}</span>
|
|
190
|
+
</span>
|
|
191
|
+
),
|
|
192
|
+
})),
|
|
193
|
+
]
|
|
194
|
+
return (
|
|
195
|
+
<div data-v-openapi-property id={id}>
|
|
196
|
+
<div data-v-openapi-property-head>
|
|
197
|
+
<span data-v-openapi-property-name>
|
|
198
|
+
{prefix && <span data-v-openapi-property-prefix>{prefix}</span>}
|
|
199
|
+
<span data-v-openapi-property-label>{name}</span>
|
|
200
|
+
</span>
|
|
201
|
+
{required && (
|
|
202
|
+
<Badge variant="warning" data-v-openapi-property-required>
|
|
203
|
+
Required
|
|
204
|
+
</Badge>
|
|
205
|
+
)}
|
|
206
|
+
{deprecated && <Badge variant="note">Deprecated</Badge>}
|
|
207
|
+
{id && <HeadingAnchor id={id} />}
|
|
208
|
+
</div>
|
|
209
|
+
{inline.length > 0 && (
|
|
210
|
+
<div data-v-openapi-property-meta>
|
|
211
|
+
{inline.map((item, index) => (
|
|
212
|
+
<Fragment key={item.key}>
|
|
213
|
+
{index > 0 && <span data-v-openapi-meta-sep>·</span>}
|
|
214
|
+
{item.node}
|
|
215
|
+
</Fragment>
|
|
216
|
+
))}
|
|
217
|
+
</div>
|
|
218
|
+
)}
|
|
219
|
+
{description && (
|
|
220
|
+
<div
|
|
221
|
+
data-v-openapi-property-description
|
|
222
|
+
data-v-content
|
|
223
|
+
// biome-ignore lint/security/noDangerouslySetInnerHtml: server-rendered trusted spec content
|
|
224
|
+
dangerouslySetInnerHTML={{ __html: Markdown.toHtml(description) }}
|
|
225
|
+
/>
|
|
226
|
+
)}
|
|
227
|
+
{values && values.length > 0 && <EnumValues values={values} />}
|
|
228
|
+
{example !== undefined && <PropertyExample id={id} value={example} />}
|
|
229
|
+
{children}
|
|
230
|
+
</div>
|
|
231
|
+
)
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export declare namespace PropertyRow {
|
|
235
|
+
type Props = {
|
|
236
|
+
/** Anchor id; when set, renders a copy-link heading anchor beside the name. */
|
|
237
|
+
id?: string | undefined
|
|
238
|
+
name: string
|
|
239
|
+
/** Muted ancestor path shown before the name (e.g. `error.details[].`). */
|
|
240
|
+
prefix?: string | undefined
|
|
241
|
+
/** Human-readable type label rendered as an inline code block. */
|
|
242
|
+
type?: string | undefined
|
|
243
|
+
/** Enum literals rendered as a vertical "values" list below the type. */
|
|
244
|
+
values?: string[] | undefined
|
|
245
|
+
/** Constraint metadata (min/max/const/default) rendered below the type. */
|
|
246
|
+
meta: schemaMeta.Entry[]
|
|
247
|
+
/** Example value rendered below the description. */
|
|
248
|
+
example?: string | undefined
|
|
249
|
+
required?: boolean | undefined
|
|
250
|
+
deprecated?: boolean | undefined
|
|
251
|
+
description?: string | undefined
|
|
252
|
+
children?: React.ReactNode
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Recursively renders a schema's properties as a list of rows. Nested
|
|
258
|
+
* object/array properties are indented beneath their parent.
|
|
259
|
+
*/
|
|
260
|
+
export function Schema(props: Schema.Props) {
|
|
261
|
+
const { schema: rawSchema, depth = 0, prefix = '', idBase, path = [] } = props
|
|
262
|
+
if (!rawSchema || depth > maxDepth) return null
|
|
263
|
+
|
|
264
|
+
// Unwrap a nullable/optional single-variant union (e.g. `oneOf: [null, X]`) to
|
|
265
|
+
// its sole member so X's type and properties render instead of nothing.
|
|
266
|
+
const schema = unwrapSingleVariant(rawSchema) ?? rawSchema
|
|
267
|
+
|
|
268
|
+
// Render oneOf/anyOf unions as a variant picker rather than a type string.
|
|
269
|
+
const union = unionVariants(schema)
|
|
270
|
+
if (union)
|
|
271
|
+
return <UnionView union={union} depth={depth} prefix={prefix} idBase={idBase} path={path} />
|
|
272
|
+
|
|
273
|
+
// Unwrap arrays to show the item schema's properties (path is unchanged: array
|
|
274
|
+
// items share the array property's anchor path).
|
|
275
|
+
if (schema['type'] === 'array' && schema['items'])
|
|
276
|
+
return (
|
|
277
|
+
<Schema
|
|
278
|
+
schema={schema['items'] as SchemaObject}
|
|
279
|
+
depth={depth}
|
|
280
|
+
prefix={prefix}
|
|
281
|
+
idBase={idBase}
|
|
282
|
+
path={path}
|
|
283
|
+
/>
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
// Merge allOf members for display.
|
|
287
|
+
const allOf = schema['allOf'] as SchemaObject[] | undefined
|
|
288
|
+
const properties = (schema['properties'] ??
|
|
289
|
+
allOf?.reduce<Record<string, SchemaObject>>((acc, member) => {
|
|
290
|
+
Object.assign(acc, (member['properties'] as Record<string, SchemaObject>) ?? {})
|
|
291
|
+
return acc
|
|
292
|
+
}, {})) as Record<string, SchemaObject> | undefined
|
|
293
|
+
|
|
294
|
+
if (!properties || Object.keys(properties).length === 0) return null
|
|
295
|
+
|
|
296
|
+
const required = new Set((schema['required'] as string[] | undefined) ?? [])
|
|
297
|
+
|
|
298
|
+
return (
|
|
299
|
+
<div data-v-openapi-schema>
|
|
300
|
+
{Object.entries(properties).map(([name, rawProperty]) => {
|
|
301
|
+
// Unwrap a nullable single-variant union so the member's type label and
|
|
302
|
+
// nested properties surface (e.g. an optional object's children).
|
|
303
|
+
const property = unwrapSingleVariant(rawProperty) ?? rawProperty
|
|
304
|
+
const childPrefix = `${prefix}${name}${property['type'] === 'array' ? '[]' : ''}.`
|
|
305
|
+
const childPath = [...path, name]
|
|
306
|
+
const id = idBase ? schemaPropertyId(idBase, childPath) : undefined
|
|
307
|
+
const propertyUnion = unionVariants(property)
|
|
308
|
+
return (
|
|
309
|
+
<PropertyRow
|
|
310
|
+
key={name}
|
|
311
|
+
id={id}
|
|
312
|
+
name={name}
|
|
313
|
+
prefix={prefix || undefined}
|
|
314
|
+
type={propertyUnion ? undefined : typeLabel(property)}
|
|
315
|
+
values={propertyUnion ? undefined : enumValues(property)}
|
|
316
|
+
meta={propertyUnion ? [] : schemaMeta(property)}
|
|
317
|
+
example={propertyUnion ? undefined : schemaExample(property)}
|
|
318
|
+
required={required.has(name)}
|
|
319
|
+
deprecated={property['deprecated'] === true}
|
|
320
|
+
description={
|
|
321
|
+
typeof property['description'] === 'string'
|
|
322
|
+
? (property['description'] as string)
|
|
323
|
+
: undefined
|
|
324
|
+
}
|
|
325
|
+
>
|
|
326
|
+
{propertyUnion
|
|
327
|
+
? depth < maxDepth && (
|
|
328
|
+
<UnionView
|
|
329
|
+
union={propertyUnion}
|
|
330
|
+
depth={depth + 1}
|
|
331
|
+
prefix={childPrefix}
|
|
332
|
+
idBase={idBase}
|
|
333
|
+
path={childPath}
|
|
334
|
+
/>
|
|
335
|
+
)
|
|
336
|
+
: depth < maxDepth &&
|
|
337
|
+
hasChildren(property) && (
|
|
338
|
+
<CollapsibleChildren>
|
|
339
|
+
<div data-v-openapi-children>
|
|
340
|
+
<Schema
|
|
341
|
+
schema={property}
|
|
342
|
+
depth={depth + 1}
|
|
343
|
+
prefix={childPrefix}
|
|
344
|
+
idBase={idBase}
|
|
345
|
+
path={childPath}
|
|
346
|
+
/>
|
|
347
|
+
</div>
|
|
348
|
+
</CollapsibleChildren>
|
|
349
|
+
)}
|
|
350
|
+
</PropertyRow>
|
|
351
|
+
)
|
|
352
|
+
})}
|
|
353
|
+
</div>
|
|
354
|
+
)
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
export declare namespace Schema {
|
|
358
|
+
type Props = {
|
|
359
|
+
schema: Record<string, unknown> | undefined
|
|
360
|
+
depth?: number | undefined
|
|
361
|
+
/** Muted ancestor path prepended to each child row's name. */
|
|
362
|
+
prefix?: string | undefined
|
|
363
|
+
/**
|
|
364
|
+
* When set, each property row gets an element id of
|
|
365
|
+
* `schemaPropertyId(idBase, path)` so response example lines can link to it.
|
|
366
|
+
*/
|
|
367
|
+
idBase?: string | undefined
|
|
368
|
+
/** Schema path (chain of property names) leading to this schema. */
|
|
369
|
+
path?: SchemaPath | undefined
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Renders a union's variant picker: each panel shows the variant's description
|
|
375
|
+
* followed by its schema. Panels are server-rendered; the client picker mounts
|
|
376
|
+
* only the selected one.
|
|
377
|
+
*/
|
|
378
|
+
export function UnionView(props: {
|
|
379
|
+
union: unionVariants.Result
|
|
380
|
+
depth: number
|
|
381
|
+
prefix: string
|
|
382
|
+
idBase?: string | undefined
|
|
383
|
+
path?: SchemaPath | undefined
|
|
384
|
+
}) {
|
|
385
|
+
const { union, depth, prefix, idBase, path = [] } = props
|
|
386
|
+
return (
|
|
387
|
+
<SchemaUnion
|
|
388
|
+
kind={union.kind}
|
|
389
|
+
names={union.variants.map((variant) => variant.name)}
|
|
390
|
+
panels={union.variants.map((variant, index) => (
|
|
391
|
+
<VariantPanel
|
|
392
|
+
key={variant.name}
|
|
393
|
+
schema={variant.schema}
|
|
394
|
+
depth={depth}
|
|
395
|
+
prefix={prefix}
|
|
396
|
+
idBase={idBase}
|
|
397
|
+
path={[...path, unionVariantSegment(index)]}
|
|
398
|
+
/>
|
|
399
|
+
))}
|
|
400
|
+
/>
|
|
401
|
+
)
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Renders the body of a single union variant: its description, plus either the
|
|
406
|
+
* nested object schema (for object-like variants) or an inline type/meta line
|
|
407
|
+
* and enum values (for scalar variants).
|
|
408
|
+
*/
|
|
409
|
+
function VariantPanel(props: {
|
|
410
|
+
schema: SchemaObject
|
|
411
|
+
depth: number
|
|
412
|
+
prefix: string
|
|
413
|
+
idBase?: string | undefined
|
|
414
|
+
path?: SchemaPath | undefined
|
|
415
|
+
}) {
|
|
416
|
+
const { schema, depth, prefix, idBase, path = [] } = props
|
|
417
|
+
const description = schema['description']
|
|
418
|
+
const items = (schema['type'] === 'array' ? schema['items'] : undefined) as
|
|
419
|
+
| SchemaObject
|
|
420
|
+
| undefined
|
|
421
|
+
const objectish = Boolean(
|
|
422
|
+
schema['properties'] || schema['allOf'] || items?.['properties'] || items?.['allOf'],
|
|
423
|
+
)
|
|
424
|
+
const meta = schemaMeta(schema)
|
|
425
|
+
const values = enumValues(schema)
|
|
426
|
+
return (
|
|
427
|
+
<div data-v-openapi-variant>
|
|
428
|
+
{!objectish && (
|
|
429
|
+
<div data-v-openapi-property-meta>
|
|
430
|
+
<code data-v data-v-openapi-type>
|
|
431
|
+
{typeLabel(schema)}
|
|
432
|
+
</code>
|
|
433
|
+
{meta.map((item) => (
|
|
434
|
+
<Fragment key={item.label}>
|
|
435
|
+
<span data-v-openapi-meta-sep>·</span>
|
|
436
|
+
<span>
|
|
437
|
+
<span data-v-openapi-meta-label>{item.label} </span>
|
|
438
|
+
<span data-v-openapi-meta-value>{item.value}</span>
|
|
439
|
+
</span>
|
|
440
|
+
</Fragment>
|
|
441
|
+
))}
|
|
442
|
+
</div>
|
|
443
|
+
)}
|
|
444
|
+
{typeof description === 'string' && (
|
|
445
|
+
<div
|
|
446
|
+
data-v-openapi-property-description
|
|
447
|
+
data-v-content
|
|
448
|
+
// biome-ignore lint/security/noDangerouslySetInnerHtml: server-rendered trusted spec content
|
|
449
|
+
dangerouslySetInnerHTML={{ __html: Markdown.toHtml(description) }}
|
|
450
|
+
/>
|
|
451
|
+
)}
|
|
452
|
+
{!objectish && values && values.length > 0 && <EnumValues values={values} />}
|
|
453
|
+
{objectish && (
|
|
454
|
+
<Schema schema={schema} depth={depth} prefix={prefix} idBase={idBase} path={path} />
|
|
455
|
+
)}
|
|
456
|
+
</div>
|
|
457
|
+
)
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/** Whether a schema exposes nested properties worth rendering as child rows. */
|
|
461
|
+
function hasChildren(schema: SchemaObject): boolean {
|
|
462
|
+
if (schema['properties']) return true
|
|
463
|
+
if (schema['allOf']) return true
|
|
464
|
+
if (schema['type'] === 'array' && schema['items'])
|
|
465
|
+
return hasChildren(schema['items'] as SchemaObject)
|
|
466
|
+
return false
|
|
467
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef, useState } from 'react'
|
|
4
|
+
import LucideChevronDown from '~icons/lucide/chevron-down'
|
|
5
|
+
import { registerDisclosure } from './anchor-navigation.client.js'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Renders a `oneOf`/`anyOf` schema union as a variant picker (in the style of
|
|
9
|
+
* Scalar's "Any of …" selector) instead of a long `a | b | c` type string.
|
|
10
|
+
* The dropdown switches which variant's schema is shown below it.
|
|
11
|
+
*
|
|
12
|
+
* All variant panels are kept mounted (only the selected one is visible) so a
|
|
13
|
+
* property inside an unselected variant is still present in the DOM. Each panel
|
|
14
|
+
* registers itself with the navigation registry so {@link revealAnchor} can
|
|
15
|
+
* select the variant containing a target before scrolling to it — letting a
|
|
16
|
+
* response example line expand the union as deep as needed.
|
|
17
|
+
*
|
|
18
|
+
* Styling lives in `openapi.css` keyed on the `data-v-openapi-union*` attributes.
|
|
19
|
+
*/
|
|
20
|
+
export function SchemaUnion(props: SchemaUnion.Props) {
|
|
21
|
+
const { kind, names, panels } = props
|
|
22
|
+
const [open, setOpen] = useState(false)
|
|
23
|
+
const [selected, setSelected] = useState<number | null>(null)
|
|
24
|
+
return (
|
|
25
|
+
<div data-v-openapi-union>
|
|
26
|
+
<div data-v-openapi-union-head>
|
|
27
|
+
<button
|
|
28
|
+
type="button"
|
|
29
|
+
onClick={() => setOpen((value) => !value)}
|
|
30
|
+
data-v-openapi-union-trigger
|
|
31
|
+
>
|
|
32
|
+
<span data-v-openapi-union-kind>{kind}</span>
|
|
33
|
+
{selected === null ? (
|
|
34
|
+
<span data-v-openapi-union-value>Select a value</span>
|
|
35
|
+
) : (
|
|
36
|
+
<span data-v-openapi-union-value>{names[selected]}</span>
|
|
37
|
+
)}
|
|
38
|
+
<LucideChevronDown data-v-openapi-union-chevron />
|
|
39
|
+
</button>
|
|
40
|
+
{open && (
|
|
41
|
+
<>
|
|
42
|
+
<button
|
|
43
|
+
type="button"
|
|
44
|
+
aria-label="Close"
|
|
45
|
+
tabIndex={-1}
|
|
46
|
+
data-v-openapi-dropdown-backdrop
|
|
47
|
+
onClick={() => setOpen(false)}
|
|
48
|
+
/>
|
|
49
|
+
<ul data-v-openapi-union-menu>
|
|
50
|
+
{names.map((name, index) => (
|
|
51
|
+
<li key={name}>
|
|
52
|
+
<button
|
|
53
|
+
type="button"
|
|
54
|
+
onClick={() => {
|
|
55
|
+
setSelected(index)
|
|
56
|
+
setOpen(false)
|
|
57
|
+
}}
|
|
58
|
+
data-v-openapi-union-option
|
|
59
|
+
data-selected={index === selected || undefined}
|
|
60
|
+
>
|
|
61
|
+
<span data-v-openapi-union-radio>
|
|
62
|
+
{index === selected && <span data-v-openapi-union-radio-dot />}
|
|
63
|
+
</span>
|
|
64
|
+
<span data-v-openapi-union-option-label>{name}</span>
|
|
65
|
+
</button>
|
|
66
|
+
</li>
|
|
67
|
+
))}
|
|
68
|
+
</ul>
|
|
69
|
+
</>
|
|
70
|
+
)}
|
|
71
|
+
</div>
|
|
72
|
+
{panels.map((panel, index) => (
|
|
73
|
+
<VariantPanelSlot
|
|
74
|
+
// biome-ignore lint/suspicious/noArrayIndexKey: panels are static and never reordered
|
|
75
|
+
key={index}
|
|
76
|
+
visible={index === selected}
|
|
77
|
+
onReveal={() => setSelected(index)}
|
|
78
|
+
>
|
|
79
|
+
{panel}
|
|
80
|
+
</VariantPanelSlot>
|
|
81
|
+
))}
|
|
82
|
+
</div>
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Wraps a single variant panel: always mounted (so its contents are navigable)
|
|
88
|
+
* but only laid out when selected. Registers the panel so navigating to an
|
|
89
|
+
* anchor inside it selects this variant.
|
|
90
|
+
*/
|
|
91
|
+
function VariantPanelSlot(props: {
|
|
92
|
+
visible: boolean
|
|
93
|
+
onReveal: () => void
|
|
94
|
+
children: React.ReactNode
|
|
95
|
+
}) {
|
|
96
|
+
const { visible, onReveal, children } = props
|
|
97
|
+
const ref = useRef<HTMLDivElement | null>(null)
|
|
98
|
+
const onRevealRef = useRef(onReveal)
|
|
99
|
+
onRevealRef.current = onReveal
|
|
100
|
+
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
const panel = ref.current
|
|
103
|
+
if (!panel) return
|
|
104
|
+
return registerDisclosure(panel, () => onRevealRef.current())
|
|
105
|
+
}, [])
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<div ref={ref} hidden={!visible} data-v-openapi-union-panel data-visible={visible || undefined}>
|
|
109
|
+
{children}
|
|
110
|
+
</div>
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export declare namespace SchemaUnion {
|
|
115
|
+
type Props = {
|
|
116
|
+
/** Leading label, e.g. `Any of` or `One of`. */
|
|
117
|
+
kind: string
|
|
118
|
+
/** Display name for each variant. */
|
|
119
|
+
names: string[]
|
|
120
|
+
/** Server-rendered schema panel for each variant. */
|
|
121
|
+
panels: React.ReactNode[]
|
|
122
|
+
}
|
|
123
|
+
}
|