fumadocs-openapi 10.3.18 → 10.4.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 (59) hide show
  1. package/css/generated/shared.css +64 -15
  2. package/dist/i18n.d.ts +100 -0
  3. package/dist/i18n.d.ts.map +1 -0
  4. package/dist/i18n.js +113 -0
  5. package/dist/i18n.js.map +1 -0
  6. package/dist/playground/client.d.ts.map +1 -1
  7. package/dist/playground/client.js +35 -23
  8. package/dist/playground/client.js.map +1 -1
  9. package/dist/playground/components/inputs.js +16 -12
  10. package/dist/playground/components/inputs.js.map +1 -1
  11. package/dist/playground/components/oauth-dialog.js +45 -44
  12. package/dist/playground/components/oauth-dialog.js.map +1 -1
  13. package/dist/playground/components/server-select.js +7 -4
  14. package/dist/playground/components/server-select.js.map +1 -1
  15. package/dist/playground/status-info.js +18 -11
  16. package/dist/playground/status-info.js.map +1 -1
  17. package/dist/types.d.ts +3 -1
  18. package/dist/types.d.ts.map +1 -1
  19. package/dist/ui/base.d.ts +7 -6
  20. package/dist/ui/base.d.ts.map +1 -1
  21. package/dist/ui/base.js +13 -7
  22. package/dist/ui/base.js.map +1 -1
  23. package/dist/ui/client/i18n.js +19 -0
  24. package/dist/ui/client/i18n.js.map +1 -0
  25. package/dist/ui/components/codeblock.d.ts +15 -0
  26. package/dist/ui/components/codeblock.d.ts.map +1 -0
  27. package/dist/ui/components/codeblock.js +27 -0
  28. package/dist/ui/components/codeblock.js.map +1 -0
  29. package/dist/ui/components/dialog.js +17 -13
  30. package/dist/ui/components/dialog.js.map +1 -1
  31. package/dist/ui/full.client.js +6 -7
  32. package/dist/ui/full.client.js.map +1 -1
  33. package/dist/ui/full.d.ts.map +1 -1
  34. package/dist/ui/full.js +8 -4
  35. package/dist/ui/full.js.map +1 -1
  36. package/dist/ui/operation/client.js +7 -8
  37. package/dist/ui/operation/client.js.map +1 -1
  38. package/dist/ui/operation/index.js +42 -19
  39. package/dist/ui/operation/index.js.map +1 -1
  40. package/dist/ui/operation/request-tabs.d.ts.map +1 -1
  41. package/dist/ui/operation/request-tabs.js +9 -8
  42. package/dist/ui/operation/request-tabs.js.map +1 -1
  43. package/dist/ui/operation/response-tabs.d.ts +1 -1
  44. package/dist/ui/operation/response-tabs.d.ts.map +1 -1
  45. package/dist/ui/operation/response-tabs.js +13 -12
  46. package/dist/ui/operation/response-tabs.js.map +1 -1
  47. package/dist/ui/operation/usage-tabs/client.js +4 -5
  48. package/dist/ui/operation/usage-tabs/client.js.map +1 -1
  49. package/dist/ui/schema/client.d.ts.map +1 -1
  50. package/dist/ui/schema/client.js +32 -21
  51. package/dist/ui/schema/client.js.map +1 -1
  52. package/dist/ui/schema/index.d.ts +1 -1
  53. package/dist/ui/schema/index.d.ts.map +1 -1
  54. package/dist/ui/schema/index.js +11 -10
  55. package/dist/ui/schema/index.js.map +1 -1
  56. package/dist/utils/process-document.d.ts +1 -1
  57. package/dist/utils/process-document.js +19 -15
  58. package/dist/utils/process-document.js.map +1 -1
  59. package/package.json +19 -12
@@ -1 +1 @@
1
- {"version":3,"file":"base.js","names":[],"sources":["../../src/ui/base.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any -- rehype-react without types */\nimport Slugger from 'github-slugger';\nimport type { Awaitable, DistributiveOmit, MethodInformation, RenderContext } from '@/types';\nimport type { NoReference } from '@/utils/schema';\nimport type { ProcessedDocument } from '@/utils/process-document';\nimport { defaultAdapters, MediaAdapter } from '@/requests/media/adapter';\nimport type { FC, HTMLAttributes, ReactNode } from 'react';\nimport { highlight, type CoreHighlightOptions } from 'fumadocs-core/highlight/core';\nimport type { OpenAPIServer } from '@/server';\nimport type { APIPageClientOptions } from './client';\nimport { Heading } from 'fumadocs-ui/components/heading';\nimport { createRehypeCode } from 'fumadocs-core/mdx-plugins/rehype-code.core';\nimport { remarkGfm } from 'fumadocs-core/mdx-plugins/remark-gfm';\nimport defaultMdxComponents from 'fumadocs-ui/mdx';\nimport { remark } from 'remark';\nimport remarkRehype from 'remark-rehype';\nimport { toJsxRuntime } from 'hast-util-to-jsx-runtime';\nimport * as JsxRuntime from 'react/jsx-runtime';\nimport { CodeBlock, Pre } from 'fumadocs-ui/components/codeblock';\nimport type { SchemaUIOptions } from './schema';\nimport type { ResponseTab } from './operation/response-tabs';\nimport type { ExampleRequestItem } from './operation/request-tabs';\nimport type { ResolvedShikiConfig } from 'fumadocs-core/highlight/config';\nimport { APIPage, type ApiPageProps, type OperationItem, type WebhookItem } from './api-page';\nimport type { CodeUsageGeneratorRegistry, InlineCodeUsageGenerator } from '@/requests/generators';\nimport type { JSONSchema } from 'json-schema-typed';\n\nexport interface GenerateTypeScriptDefinitionsContext extends RenderContext {\n operation: NoReference<MethodInformation>;\n readOnly: boolean;\n writeOnly: boolean;\n /** @deprecated */\n _internal_legacy?: {\n statusCode: string;\n contentType: string;\n };\n}\n\nexport interface CreateAPIPageOptions {\n /**\n * Generate TypeScript definitions from response schema.\n *\n * Pass `false` to disable it.\n *\n * @param method - the operation object\n * @param statusCode - status code\n * @deprecated use `generateTypeScriptDefinitions` instead.\n */\n generateTypeScriptSchema?:\n | ((\n method: NoReference<MethodInformation>,\n statusCode: string,\n contentType: string,\n ctx: RenderContext,\n ) => Awaitable<string | undefined>)\n | false;\n\n /**\n * Generate TypeScript definitions from JSON schema.\n *\n * Pass `false` to disable it.\n */\n generateTypeScriptDefinitions?: (\n schema: JSONSchema,\n ctx: GenerateTypeScriptDefinitionsContext,\n ) => Awaitable<string | undefined>;\n\n /**\n * Generate example code usage for all endpoints.\n */\n codeUsages?: CodeUsageGeneratorRegistry;\n\n /**\n * Generate example code usage for each endpoint.\n */\n generateCodeSamples?: (method: MethodInformation) => Awaitable<InlineCodeUsageGenerator[]>;\n\n shiki: ResolvedShikiConfig;\n renderMarkdown?: (md: string) => ReactNode;\n shikiOptions?: DistributiveOmit<CoreHighlightOptions, 'config' | 'lang' | 'components'>;\n\n /**\n * Show full response schema instead of only example response & Typescript definitions.\n *\n * @default true\n */\n showResponseSchema?: boolean;\n\n /**\n * Support other media types (for server-side generation).\n */\n mediaAdapters?: Record<string, MediaAdapter>;\n\n /**\n * Customise page content\n */\n content?: {\n renderResponseTabs?: (tabs: ResponseTab[], ctx: RenderContext) => Awaitable<ReactNode>;\n\n renderRequestTabs?: (\n items: ExampleRequestItem[],\n ctx: RenderContext & {\n route: string;\n operation: NoReference<MethodInformation>;\n },\n ) => Awaitable<ReactNode>;\n\n renderAPIExampleLayout?: (\n slots: {\n selector: ReactNode;\n usageTabs: ReactNode;\n responseTabs: ReactNode;\n },\n ctx: RenderContext,\n ) => Awaitable<ReactNode>;\n\n /**\n * @param generators - codegens for API example usages\n */\n renderAPIExampleUsageTabs?: (\n generators: CodeUsageGeneratorRegistry,\n ctx: RenderContext,\n ) => Awaitable<ReactNode>;\n\n /**\n * renderer of the entire page's layout (containing all operations & webhooks UI)\n */\n renderPageLayout?: (\n slots: {\n operations?: {\n item: OperationItem;\n children: ReactNode;\n }[];\n webhooks?: {\n item: WebhookItem;\n children: ReactNode;\n }[];\n },\n ctx: RenderContext,\n ) => Awaitable<ReactNode>;\n\n renderOperationLayout?: (\n slots: {\n header: ReactNode;\n description: ReactNode;\n apiExample: ReactNode;\n apiPlayground: ReactNode;\n\n authSchemes: ReactNode;\n paremeters: ReactNode;\n body: ReactNode;\n responses: ReactNode;\n callbacks: ReactNode;\n },\n ctx: RenderContext,\n method: NoReference<MethodInformation>,\n ) => Awaitable<ReactNode>;\n\n renderWebhookLayout?: (slots: {\n header: ReactNode;\n description: ReactNode;\n authSchemes: ReactNode;\n paremeters: ReactNode;\n body: ReactNode;\n requests: ReactNode;\n responses: ReactNode;\n callbacks: ReactNode;\n }) => Awaitable<ReactNode>;\n };\n\n /**\n * Info UI for JSON schemas\n */\n schemaUI?: {\n render?: (options: SchemaUIOptions, ctx: RenderContext) => Awaitable<ReactNode>;\n\n /**\n * Show examples under the generated content of JSON schemas.\n *\n * @defaultValue false\n */\n showExample?: boolean;\n };\n\n /**\n * Customise API playground\n */\n playground?: {\n /**\n * @defaultValue true\n */\n enabled?: boolean;\n /**\n * replace the server-side renderer\n */\n render?: (props: {\n path: string;\n method: MethodInformation;\n ctx: RenderContext;\n }) => Awaitable<ReactNode>;\n };\n\n renderHeading?: (\n props: HTMLAttributes<HTMLHeadingElement>,\n depth: number,\n ) => Awaitable<ReactNode>;\n renderCodeBlock?: (props: { lang: string; code: string }) => Awaitable<ReactNode>;\n\n client?: APIPageClientOptions;\n}\n\nexport function createAPIPage(\n server: OpenAPIServer,\n options: CreateAPIPageOptions,\n): FC<ApiPageProps> {\n let processor: ReturnType<typeof createMarkdownProcessor>;\n\n function createMarkdownProcessor() {\n function rehypeReact(this: any) {\n this.compiler = (tree: any, file: any) => {\n return toJsxRuntime(tree, {\n development: false,\n filePath: file.path,\n ...JsxRuntime,\n components: defaultMdxComponents,\n });\n };\n }\n\n return remark()\n .use(remarkGfm)\n .use(remarkRehype)\n .use(createRehypeCode(options.shiki), {\n langs: [],\n lazy: true,\n })\n .use(rehypeReact);\n }\n\n return async function APIPageWrapper({ document, ...props }) {\n let processed: ProcessedDocument;\n if (typeof document === 'string') {\n processed = await server.getSchema(document);\n } else {\n processed = await document;\n }\n\n const slugger = new Slugger();\n\n const ctx: RenderContext = {\n schema: processed,\n proxyUrl: server.options.proxyUrl,\n ...options,\n mediaAdapters: {\n ...defaultAdapters,\n ...options.mediaAdapters,\n },\n slugger,\n async renderHeading(depth, text, props) {\n const id = slugger.slug(text);\n\n if (options.renderHeading) {\n return options.renderHeading({ id, children: text, ...props }, depth);\n }\n\n return (\n <Heading id={id} key={id} as={`h${depth}` as `h1`} {...props}>\n {text}\n </Heading>\n );\n },\n generateTypeScriptDefinitions(schema, ctx) {\n const { generateTypeScriptSchema, generateTypeScriptDefinitions } = options;\n if (generateTypeScriptSchema && ctx._internal_legacy) {\n const { statusCode, contentType } = ctx._internal_legacy;\n return generateTypeScriptSchema(ctx.operation, statusCode, contentType, ctx);\n }\n\n return generateTypeScriptDefinitions?.(schema, ctx);\n },\n async renderMarkdown(text) {\n if (options.renderMarkdown) return options.renderMarkdown(text);\n processor ??= createMarkdownProcessor();\n\n const out = await processor.process({\n value: text,\n });\n\n return out.result as ReactNode;\n },\n async renderCodeBlock(lang, code) {\n if (options.renderCodeBlock) {\n return options.renderCodeBlock({ lang, code });\n }\n\n const rendered = await highlight(code, {\n lang,\n ...options.shikiOptions,\n config: options.shiki,\n components: {\n pre: Pre,\n },\n });\n\n return <CodeBlock className=\"my-0\">{rendered}</CodeBlock>;\n },\n };\n\n return <APIPage {...props} ctx={ctx} />;\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;AAmNA,SAAgB,cACd,QACA,SACkB;CAClB,IAAI;CAEJ,SAAS,0BAA0B;EACjC,SAAS,cAAuB;AAC9B,QAAK,YAAY,MAAW,SAAc;AACxC,WAAO,aAAa,MAAM;KACxB,aAAa;KACb,UAAU,KAAK;KACf,GAAG;KACH,YAAY;KACb,CAAC;;;AAIN,SAAO,QAAQ,CACZ,IAAI,UAAU,CACd,IAAI,aAAa,CACjB,IAAI,iBAAiB,QAAQ,MAAM,EAAE;GACpC,OAAO,EAAE;GACT,MAAM;GACP,CAAC,CACD,IAAI,YAAY;;AAGrB,QAAO,eAAe,eAAe,EAAE,UAAU,GAAG,SAAS;EAC3D,IAAI;AACJ,MAAI,OAAO,aAAa,SACtB,aAAY,MAAM,OAAO,UAAU,SAAS;MAE5C,aAAY,MAAM;EAGpB,MAAM,UAAU,IAAI,SAAS;EAE7B,MAAM,MAAqB;GACzB,QAAQ;GACR,UAAU,OAAO,QAAQ;GACzB,GAAG;GACH,eAAe;IACb,GAAG;IACH,GAAG,QAAQ;IACZ;GACD;GACA,MAAM,cAAc,OAAO,MAAM,OAAO;IACtC,MAAM,KAAK,QAAQ,KAAK,KAAK;AAE7B,QAAI,QAAQ,cACV,QAAO,QAAQ,cAAc;KAAE;KAAI,UAAU;KAAM,GAAG;KAAO,EAAE,MAAM;AAGvE,WACE,oBAAC,SAAD;KAAa;KAAa,IAAI,IAAI;KAAiB,GAAI;eACpD;KACO,EAFY,GAEZ;;GAGd,8BAA8B,QAAQ,KAAK;IACzC,MAAM,EAAE,0BAA0B,kCAAkC;AACpE,QAAI,4BAA4B,IAAI,kBAAkB;KACpD,MAAM,EAAE,YAAY,gBAAgB,IAAI;AACxC,YAAO,yBAAyB,IAAI,WAAW,YAAY,aAAa,IAAI;;AAG9E,WAAO,gCAAgC,QAAQ,IAAI;;GAErD,MAAM,eAAe,MAAM;AACzB,QAAI,QAAQ,eAAgB,QAAO,QAAQ,eAAe,KAAK;AAC/D,kBAAc,yBAAyB;AAMvC,YAJY,MAAM,UAAU,QAAQ,EAClC,OAAO,MACR,CAAC,EAES;;GAEb,MAAM,gBAAgB,MAAM,MAAM;AAChC,QAAI,QAAQ,gBACV,QAAO,QAAQ,gBAAgB;KAAE;KAAM;KAAM,CAAC;AAYhD,WAAO,oBAAC,WAAD;KAAW,WAAU;eATX,MAAM,UAAU,MAAM;MACrC;MACA,GAAG,QAAQ;MACX,QAAQ,QAAQ;MAChB,YAAY,EACV,KAAK,KACN;MACF,CAAC;KAEuD,CAAA;;GAE5D;AAED,SAAO,oBAAC,SAAD;GAAS,GAAI;GAAY;GAAO,CAAA"}
1
+ {"version":3,"file":"base.js","names":[],"sources":["../../src/ui/base.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any -- rehype-react without types */\nimport Slugger from 'github-slugger';\nimport type { Awaitable, MethodInformation, RenderContext } from '@/types';\nimport type { NoReference } from '@/utils/schema';\nimport type { ProcessedDocument } from '@/utils/process-document';\nimport { defaultAdapters, MediaAdapter } from '@/requests/media/adapter';\nimport type { FC, HTMLAttributes, ReactNode } from 'react';\nimport type { OpenAPIServer } from '@/server';\nimport type { APIPageClientOptions } from './client';\nimport { Heading } from 'fumadocs-ui/components/heading';\nimport { createRehypeCode } from 'fumadocs-core/mdx-plugins/rehype-code.core';\nimport { remarkGfm } from 'fumadocs-core/mdx-plugins/remark-gfm';\nimport defaultMdxComponents from 'fumadocs-ui/mdx';\nimport { remark } from 'remark';\nimport remarkRehype from 'remark-rehype';\nimport { toJsxRuntime } from 'hast-util-to-jsx-runtime';\nimport * as JsxRuntime from 'react/jsx-runtime';\nimport { CodeBlock, Pre } from 'fumadocs-ui/components/codeblock';\nimport type { SchemaUIOptions } from './schema';\nimport type { ResponseTab } from './operation/response-tabs';\nimport type { ExampleRequestItem } from './operation/request-tabs';\nimport { APIPage, type ApiPageProps, type OperationItem, type WebhookItem } from './api-page';\nimport type { CodeUsageGeneratorRegistry, InlineCodeUsageGenerator } from '@/requests/generators';\nimport type { JSONSchema } from 'json-schema-typed';\nimport type { BundledTheme, CodeOptionsThemes, CodeToHastOptionsCommon } from 'shiki';\nimport { highlightHast, type ShikiFactory } from 'fumadocs-core/highlight/shiki';\n\nexport interface GenerateTypeScriptDefinitionsContext extends RenderContext {\n operation: NoReference<MethodInformation>;\n readOnly: boolean;\n writeOnly: boolean;\n /** @deprecated */\n _internal_legacy?: {\n statusCode: string;\n contentType: string;\n };\n}\n\nexport interface CreateAPIPageOptions {\n /**\n * Generate TypeScript definitions from response schema.\n *\n * Pass `false` to disable it.\n *\n * @param method - the operation object\n * @param statusCode - status code\n * @deprecated use `generateTypeScriptDefinitions` instead.\n */\n generateTypeScriptSchema?:\n | ((\n method: NoReference<MethodInformation>,\n statusCode: string,\n contentType: string,\n ctx: RenderContext,\n ) => Awaitable<string | undefined>)\n | false;\n\n /**\n * Generate TypeScript definitions from JSON schema.\n *\n * Pass `false` to disable it.\n */\n generateTypeScriptDefinitions?: (\n schema: JSONSchema,\n ctx: GenerateTypeScriptDefinitionsContext,\n ) => Awaitable<string | undefined>;\n\n /**\n * Generate example code usage for all endpoints.\n */\n codeUsages?: CodeUsageGeneratorRegistry;\n\n /**\n * Generate example code usage for each endpoint.\n */\n generateCodeSamples?: (method: MethodInformation) => Awaitable<InlineCodeUsageGenerator[]>;\n\n shiki: ShikiFactory;\n renderMarkdown?: (md: string) => ReactNode;\n shikiOptions: Omit<CodeToHastOptionsCommon, 'lang'> & CodeOptionsThemes<BundledTheme>;\n\n /**\n * Show full response schema instead of only example response & Typescript definitions.\n *\n * @default true\n */\n showResponseSchema?: boolean;\n\n /**\n * Support other media types (for server-side generation).\n */\n mediaAdapters?: Record<string, MediaAdapter>;\n\n /**\n * Customise page content\n */\n content?: {\n renderResponseTabs?: (tabs: ResponseTab[], ctx: RenderContext) => Awaitable<ReactNode>;\n\n renderRequestTabs?: (\n items: ExampleRequestItem[],\n ctx: RenderContext & {\n route: string;\n operation: NoReference<MethodInformation>;\n },\n ) => Awaitable<ReactNode>;\n\n renderAPIExampleLayout?: (\n slots: {\n selector: ReactNode;\n usageTabs: ReactNode;\n responseTabs: ReactNode;\n },\n ctx: RenderContext,\n ) => Awaitable<ReactNode>;\n\n /**\n * @param generators - codegens for API example usages\n */\n renderAPIExampleUsageTabs?: (\n generators: CodeUsageGeneratorRegistry,\n ctx: RenderContext,\n ) => Awaitable<ReactNode>;\n\n /**\n * renderer of the entire page's layout (containing all operations & webhooks UI)\n */\n renderPageLayout?: (\n slots: {\n operations?: {\n item: OperationItem;\n children: ReactNode;\n }[];\n webhooks?: {\n item: WebhookItem;\n children: ReactNode;\n }[];\n },\n ctx: RenderContext,\n ) => Awaitable<ReactNode>;\n\n renderOperationLayout?: (\n slots: {\n header: ReactNode;\n description: ReactNode;\n apiExample: ReactNode;\n apiPlayground: ReactNode;\n\n authSchemes: ReactNode;\n paremeters: ReactNode;\n body: ReactNode;\n responses: ReactNode;\n callbacks: ReactNode;\n },\n ctx: RenderContext,\n method: NoReference<MethodInformation>,\n ) => Awaitable<ReactNode>;\n\n renderWebhookLayout?: (slots: {\n header: ReactNode;\n description: ReactNode;\n authSchemes: ReactNode;\n paremeters: ReactNode;\n body: ReactNode;\n requests: ReactNode;\n responses: ReactNode;\n callbacks: ReactNode;\n }) => Awaitable<ReactNode>;\n };\n\n /**\n * Info UI for JSON schemas\n */\n schemaUI?: {\n render?: (options: SchemaUIOptions, ctx: RenderContext) => Awaitable<ReactNode>;\n\n /**\n * Show examples under the generated content of JSON schemas.\n *\n * @defaultValue false\n */\n showExample?: boolean;\n };\n\n /**\n * Customise API playground\n */\n playground?: {\n /**\n * @defaultValue true\n */\n enabled?: boolean;\n /**\n * replace the server-side renderer\n */\n render?: (props: {\n path: string;\n method: MethodInformation;\n ctx: RenderContext;\n }) => Awaitable<ReactNode>;\n };\n\n renderHeading?: (\n props: HTMLAttributes<HTMLHeadingElement>,\n depth: number,\n ) => Awaitable<ReactNode>;\n renderCodeBlock?: (props: { lang: string; code: string }) => Awaitable<ReactNode>;\n\n client?: APIPageClientOptions;\n}\n\nexport function createAPIPage(\n server: OpenAPIServer,\n options: CreateAPIPageOptions,\n): FC<ApiPageProps> {\n let processor: ReturnType<typeof createMarkdownProcessor>;\n\n function createMarkdownProcessor() {\n function rehypeReact(this: any) {\n this.compiler = (tree: any, file: any) => {\n return toJsxRuntime(tree, {\n development: false,\n filePath: file.path,\n ...JsxRuntime,\n components: defaultMdxComponents,\n });\n };\n }\n\n return remark()\n .use(remarkGfm)\n .use(remarkRehype)\n .use(createRehypeCode(options.shiki), {\n langs: [],\n lazy: true,\n defaultColor: false,\n ...options.shikiOptions,\n })\n .use(rehypeReact);\n }\n\n return async function APIPageWrapper({ document, ...props }) {\n let processed: ProcessedDocument;\n if (typeof document === 'string') {\n processed = await server.getSchema(document);\n } else {\n processed = await document;\n }\n\n const slugger = new Slugger();\n\n const ctx: RenderContext = {\n schema: processed,\n proxyUrl: server.options.proxyUrl,\n ...options,\n mediaAdapters: {\n ...defaultAdapters,\n ...options.mediaAdapters,\n },\n slugger,\n async renderHeading(depth, text, props) {\n const id = typeof text === 'string' ? slugger.slug(text) : props?.id;\n if (!id) throw new Error(\"missing 'id' for non-string children\");\n\n if (options.renderHeading) {\n return options.renderHeading({ id, children: text, ...props }, depth);\n }\n\n return (\n <Heading id={id} key={id} as={`h${depth}` as `h1`} {...props}>\n {text}\n </Heading>\n );\n },\n generateTypeScriptDefinitions(schema, ctx) {\n const { generateTypeScriptSchema, generateTypeScriptDefinitions } = options;\n if (generateTypeScriptSchema && ctx._internal_legacy) {\n const { statusCode, contentType } = ctx._internal_legacy;\n return generateTypeScriptSchema(ctx.operation, statusCode, contentType, ctx);\n }\n\n return generateTypeScriptDefinitions?.(schema, ctx);\n },\n async renderMarkdown(text) {\n if (options.renderMarkdown) return options.renderMarkdown(text);\n processor ??= createMarkdownProcessor();\n\n const out = await processor.process({\n value: text,\n });\n\n return out.result as ReactNode;\n },\n async renderCodeBlock(lang, code) {\n if (options.renderCodeBlock) {\n return options.renderCodeBlock({ lang, code });\n }\n\n const hast = await highlightHast(await options.shiki.getOrInit(), code, {\n lang,\n defaultColor: false,\n ...options.shikiOptions,\n });\n const rendered = toJsxRuntime(hast, {\n ...JsxRuntime,\n components: {\n pre: Pre,\n },\n });\n\n return <CodeBlock className=\"my-0\">{rendered}</CodeBlock>;\n },\n };\n\n return <APIPage {...props} ctx={ctx} />;\n };\n}\n\nexport { ClientCodeBlockProvider } from './components/codeblock';\n"],"mappings":";;;;;;;;;;;;;;;;AAmNA,SAAgB,cACd,QACA,SACkB;CAClB,IAAI;CAEJ,SAAS,0BAA0B;EACjC,SAAS,cAAuB;AAC9B,QAAK,YAAY,MAAW,SAAc;AACxC,WAAO,aAAa,MAAM;KACxB,aAAa;KACb,UAAU,KAAK;KACf,GAAG;KACH,YAAY;KACb,CAAC;;;AAIN,SAAO,QAAQ,CACZ,IAAI,UAAU,CACd,IAAI,aAAa,CACjB,IAAI,iBAAiB,QAAQ,MAAM,EAAE;GACpC,OAAO,EAAE;GACT,MAAM;GACN,cAAc;GACd,GAAG,QAAQ;GACZ,CAAC,CACD,IAAI,YAAY;;AAGrB,QAAO,eAAe,eAAe,EAAE,UAAU,GAAG,SAAS;EAC3D,IAAI;AACJ,MAAI,OAAO,aAAa,SACtB,aAAY,MAAM,OAAO,UAAU,SAAS;MAE5C,aAAY,MAAM;EAGpB,MAAM,UAAU,IAAI,SAAS;EAE7B,MAAM,MAAqB;GACzB,QAAQ;GACR,UAAU,OAAO,QAAQ;GACzB,GAAG;GACH,eAAe;IACb,GAAG;IACH,GAAG,QAAQ;IACZ;GACD;GACA,MAAM,cAAc,OAAO,MAAM,OAAO;IACtC,MAAM,KAAK,OAAO,SAAS,WAAW,QAAQ,KAAK,KAAK,GAAG,OAAO;AAClE,QAAI,CAAC,GAAI,OAAM,IAAI,MAAM,uCAAuC;AAEhE,QAAI,QAAQ,cACV,QAAO,QAAQ,cAAc;KAAE;KAAI,UAAU;KAAM,GAAG;KAAO,EAAE,MAAM;AAGvE,WACE,oBAAC,SAAD;KAAa;KAAa,IAAI,IAAI;KAAiB,GAAI;eACpD;KACO,EAFY,GAEZ;;GAGd,8BAA8B,QAAQ,KAAK;IACzC,MAAM,EAAE,0BAA0B,kCAAkC;AACpE,QAAI,4BAA4B,IAAI,kBAAkB;KACpD,MAAM,EAAE,YAAY,gBAAgB,IAAI;AACxC,YAAO,yBAAyB,IAAI,WAAW,YAAY,aAAa,IAAI;;AAG9E,WAAO,gCAAgC,QAAQ,IAAI;;GAErD,MAAM,eAAe,MAAM;AACzB,QAAI,QAAQ,eAAgB,QAAO,QAAQ,eAAe,KAAK;AAC/D,kBAAc,yBAAyB;AAMvC,YAJY,MAAM,UAAU,QAAQ,EAClC,OAAO,MACR,CAAC,EAES;;GAEb,MAAM,gBAAgB,MAAM,MAAM;AAChC,QAAI,QAAQ,gBACV,QAAO,QAAQ,gBAAgB;KAAE;KAAM;KAAM,CAAC;AAehD,WAAO,oBAAC,WAAD;KAAW,WAAU;eAPX,aALJ,MAAM,cAAc,MAAM,QAAQ,MAAM,WAAW,EAAE,MAAM;MACtE;MACA,cAAc;MACd,GAAG,QAAQ;MACZ,CAAC,EACkC;MAClC,GAAG;MACH,YAAY,EACV,KAAK,KACN;MACF,CAAC;KAEuD,CAAA;;GAE5D;AAED,SAAO,oBAAC,SAAD;GAAS,GAAI;GAAY;GAAO,CAAA"}
@@ -0,0 +1,19 @@
1
+ "use client";
2
+ import { defaultTranslations } from "../../i18n.js";
3
+ import { useI18n } from "fumadocs-ui/contexts/i18n";
4
+ //#region src/ui/client/i18n.ts
5
+ function useTranslations() {
6
+ return useI18n().text.openapi ?? defaultTranslations;
7
+ }
8
+ /**
9
+ * Renders a translated string. Use in server components so the label is resolved on the client from the current locale.
10
+ */
11
+ function I18nLabel({ label, replacements = {} }) {
12
+ let value = useTranslations()[label];
13
+ for (const [k, v] of Object.entries(replacements)) value = value.replaceAll(`{${k}}`, v);
14
+ return value;
15
+ }
16
+ //#endregion
17
+ export { I18nLabel, useTranslations };
18
+
19
+ //# sourceMappingURL=i18n.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i18n.js","names":[],"sources":["../../../src/ui/client/i18n.ts"],"sourcesContent":["'use client';\nimport { defaultTranslations, type Translations } from '@/i18n';\nimport { useI18n } from 'fumadocs-ui/contexts/i18n';\n\nexport function useTranslations(): Translations {\n return (useI18n().text.openapi ?? defaultTranslations) as unknown as Translations;\n}\n\nexport interface OpenAPII18nLabelProps {\n label: keyof Translations;\n /** Replace {key} placeholders in the translation string */\n replacements?: Record<string, string>;\n}\n\n/**\n * Renders a translated string. Use in server components so the label is resolved on the client from the current locale.\n */\nexport function I18nLabel({ label, replacements = {} }: OpenAPII18nLabelProps): string {\n const text = useTranslations();\n let value = text[label];\n for (const [k, v] of Object.entries(replacements)) {\n value = value.replaceAll(`{${k}}`, v);\n }\n return value;\n}\n"],"mappings":";;;;AAIA,SAAgB,kBAAgC;AAC9C,QAAQ,SAAS,CAAC,KAAK,WAAW;;;;;AAYpC,SAAgB,UAAU,EAAE,OAAO,eAAe,EAAE,IAAmC;CAErF,IAAI,QADS,iBAAiB,CACb;AACjB,MAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,aAAa,CAC/C,SAAQ,MAAM,WAAW,IAAI,EAAE,IAAI,EAAE;AAEvC,QAAO"}
@@ -0,0 +1,15 @@
1
+ import { ReactNode } from "react";
2
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
3
+ import { ShikiFactory } from "fumadocs-core/highlight/shiki";
4
+
5
+ //#region src/ui/components/codeblock.d.ts
6
+ declare function ClientCodeBlockProvider({
7
+ factory,
8
+ children
9
+ }: {
10
+ factory: ShikiFactory;
11
+ children: ReactNode;
12
+ }): react_jsx_runtime0.JSX.Element;
13
+ //#endregion
14
+ export { ClientCodeBlockProvider };
15
+ //# sourceMappingURL=codeblock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codeblock.d.ts","names":[],"sources":["../../../src/ui/components/codeblock.tsx"],"mappings":";;;;;iBAsBgB,uBAAA,CAAA;EACd,OAAA;EACA;AAAA;EAEA,OAAA,EAAS,YAAA;EACT,QAAA,EAAU,SAAA;AAAA,IACX,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -0,0 +1,27 @@
1
+ "use client";
2
+ import { useApiContext } from "../contexts/api.js";
3
+ import { createContext, use } from "react";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import { DynamicCodeBlock } from "fumadocs-ui/components/dynamic-codeblock.core";
6
+ //#region src/ui/components/codeblock.tsx
7
+ const CodeBlockContext = createContext(null);
8
+ function ClientCodeBlock(props) {
9
+ const { shikiOptions } = useApiContext();
10
+ const ctx = use(CodeBlockContext);
11
+ if (!ctx) throw new Error("Missing Shiki context, please wrap your <APIPage /> component under <ClientCodeBlockProvider />");
12
+ return /* @__PURE__ */ jsx(DynamicCodeBlock, {
13
+ highlighter: () => ctx.getOrInit(),
14
+ options: shikiOptions,
15
+ ...props
16
+ });
17
+ }
18
+ function ClientCodeBlockProvider({ factory, children }) {
19
+ return /* @__PURE__ */ jsx(CodeBlockContext, {
20
+ value: factory,
21
+ children
22
+ });
23
+ }
24
+ //#endregion
25
+ export { ClientCodeBlock, ClientCodeBlockProvider };
26
+
27
+ //# sourceMappingURL=codeblock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codeblock.js","names":[],"sources":["../../../src/ui/components/codeblock.tsx"],"sourcesContent":["'use client';\nimport {\n DynamicCodeBlock,\n type DynamicCodeblockProps,\n} from 'fumadocs-ui/components/dynamic-codeblock.core';\nimport { useApiContext } from '../contexts/api';\nimport { createContext, type ReactNode, use } from 'react';\nimport type { ShikiFactory } from 'fumadocs-core/highlight/shiki';\n\nconst CodeBlockContext = createContext<ShikiFactory | null>(null);\n\nexport function ClientCodeBlock(props: Omit<DynamicCodeblockProps, 'highlighter' | 'options'>) {\n const { shikiOptions } = useApiContext();\n const ctx = use(CodeBlockContext);\n if (!ctx)\n throw new Error(\n 'Missing Shiki context, please wrap your <APIPage /> component under <ClientCodeBlockProvider />',\n );\n\n return <DynamicCodeBlock highlighter={() => ctx.getOrInit()} options={shikiOptions} {...props} />;\n}\n\nexport function ClientCodeBlockProvider({\n factory,\n children,\n}: {\n factory: ShikiFactory;\n children: ReactNode;\n}) {\n return <CodeBlockContext value={factory}>{children}</CodeBlockContext>;\n}\n"],"mappings":";;;;;;AASA,MAAM,mBAAmB,cAAmC,KAAK;AAEjE,SAAgB,gBAAgB,OAA+D;CAC7F,MAAM,EAAE,iBAAiB,eAAe;CACxC,MAAM,MAAM,IAAI,iBAAiB;AACjC,KAAI,CAAC,IACH,OAAM,IAAI,MACR,kGACD;AAEH,QAAO,oBAAC,kBAAD;EAAkB,mBAAmB,IAAI,WAAW;EAAE,SAAS;EAAc,GAAI;EAAS,CAAA;;AAGnG,SAAgB,wBAAwB,EACtC,SACA,YAIC;AACD,QAAO,oBAAC,kBAAD;EAAkB,OAAO;EAAU;EAA4B,CAAA"}
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import { cn } from "../../utils/cn.js";
3
+ import { useTranslations } from "../client/i18n.js";
3
4
  import * as React from "react";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
5
6
  import { X } from "lucide-react";
@@ -16,19 +17,22 @@ const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__P
16
17
  ...props
17
18
  }));
18
19
  DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
19
- const DialogContent = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(DialogPortal, { children: [/* @__PURE__ */ jsx(DialogOverlay, {}), /* @__PURE__ */ jsxs(DialogPrimitive.Content, {
20
- ref,
21
- className: cn("fixed left-1/2 top-1/2 z-50 flex flex-col gap-4 w-full max-w-lg -translate-x-1/2 -translate-y-1/2 border bg-fd-popover p-4 shadow-lg rounded-xl duration-200 data-[state=open]:animate-fd-dialog-in data-[state=closed]:animate-fd-dialog-out focus-visible:outline-none", className),
22
- ...props,
23
- children: [children, /* @__PURE__ */ jsx(DialogPrimitive.Close, {
24
- "aria-label": "Close",
25
- className: cn(buttonVariants({
26
- size: "icon-sm",
27
- color: "ghost"
28
- }), "absolute end-2 top-2 text-fd-muted-foreground/70"),
29
- children: /* @__PURE__ */ jsx(X, {})
30
- })]
31
- })] }));
20
+ const DialogContent = React.forwardRef(({ className, children, ...props }, ref) => {
21
+ const t = useTranslations();
22
+ return /* @__PURE__ */ jsxs(DialogPortal, { children: [/* @__PURE__ */ jsx(DialogOverlay, {}), /* @__PURE__ */ jsxs(DialogPrimitive.Content, {
23
+ ref,
24
+ className: cn("fixed left-1/2 top-1/2 z-50 flex flex-col gap-4 w-full max-w-lg -translate-x-1/2 -translate-y-1/2 border bg-fd-popover p-4 shadow-lg rounded-xl duration-200 data-[state=open]:animate-fd-dialog-in data-[state=closed]:animate-fd-dialog-out focus-visible:outline-none", className),
25
+ ...props,
26
+ children: [children, /* @__PURE__ */ jsx(DialogPrimitive.Close, {
27
+ "aria-label": t.close,
28
+ className: cn(buttonVariants({
29
+ size: "icon-sm",
30
+ color: "ghost"
31
+ }), "absolute end-2 top-2 text-fd-muted-foreground/70"),
32
+ children: /* @__PURE__ */ jsx(X, {})
33
+ })]
34
+ })] });
35
+ });
32
36
  DialogContent.displayName = DialogPrimitive.Content.displayName;
33
37
  const DialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
34
38
  className: cn("flex flex-col gap-1.5 text-center sm:text-start", className),
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.js","names":[],"sources":["../../../src/ui/components/dialog.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { X } from 'lucide-react';\nimport { cn } from '@/utils/cn';\nimport { buttonVariants } from 'fumadocs-ui/components/ui/button';\n\nconst Dialog = DialogPrimitive.Root;\n\nconst DialogTrigger = DialogPrimitive.Trigger;\n\nconst DialogPortal = DialogPrimitive.Portal;\n\nconst DialogClose = DialogPrimitive.Close;\n\nconst DialogOverlay = React.forwardRef<\n React.ComponentRef<typeof DialogPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Overlay\n ref={ref}\n className={cn(\n 'fixed inset-0 z-50 bg-black/30 backdrop-blur-sm data-[state=open]:animate-fd-fade-in data-[state=closed]:animate-fd-fade-out',\n className,\n )}\n {...props}\n />\n));\nDialogOverlay.displayName = DialogPrimitive.Overlay.displayName;\n\nconst DialogContent = React.forwardRef<\n React.ComponentRef<typeof DialogPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>\n>(({ className, children, ...props }, ref) => (\n <DialogPortal>\n <DialogOverlay />\n <DialogPrimitive.Content\n ref={ref}\n className={cn(\n 'fixed left-1/2 top-1/2 z-50 flex flex-col gap-4 w-full max-w-lg -translate-x-1/2 -translate-y-1/2 border bg-fd-popover p-4 shadow-lg rounded-xl duration-200 data-[state=open]:animate-fd-dialog-in data-[state=closed]:animate-fd-dialog-out focus-visible:outline-none',\n className,\n )}\n {...props}\n >\n {children}\n <DialogPrimitive.Close\n aria-label=\"Close\"\n className={cn(\n buttonVariants({ size: 'icon-sm', color: 'ghost' }),\n 'absolute end-2 top-2 text-fd-muted-foreground/70',\n )}\n >\n <X />\n </DialogPrimitive.Close>\n </DialogPrimitive.Content>\n </DialogPortal>\n));\nDialogContent.displayName = DialogPrimitive.Content.displayName;\n\nconst DialogHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n <div className={cn('flex flex-col gap-1.5 text-center sm:text-start', className)} {...props} />\n);\nDialogHeader.displayName = 'DialogHeader';\n\nconst DialogFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:gap-2', className)}\n {...props}\n />\n);\nDialogFooter.displayName = 'DialogFooter';\n\nconst DialogTitle = React.forwardRef<\n React.ComponentRef<typeof DialogPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Title\n ref={ref}\n className={cn('text-lg font-semibold leading-none tracking-tight', className)}\n {...props}\n />\n));\nDialogTitle.displayName = DialogPrimitive.Title.displayName;\n\nconst DialogDescription = React.forwardRef<\n React.ComponentRef<typeof DialogPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Description\n ref={ref}\n className={cn('text-sm text-fd-muted-foreground', className)}\n {...props}\n />\n));\nDialogDescription.displayName = DialogPrimitive.Description.displayName;\n\nexport {\n Dialog,\n DialogPortal,\n DialogOverlay,\n DialogClose,\n DialogTrigger,\n DialogContent,\n DialogHeader,\n DialogFooter,\n DialogTitle,\n DialogDescription,\n};\n"],"mappings":";;;;;;;;AAQA,MAAM,SAAS,gBAAgB;AAE/B,MAAM,gBAAgB,gBAAgB;AAEtC,MAAM,eAAe,gBAAgB;AAEjB,gBAAgB;AAEpC,MAAM,gBAAgB,MAAM,YAGzB,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,gBAAgB,SAAjB;CACO;CACL,WAAW,GACT,gIACA,UACD;CACD,GAAI;CACJ,CAAA,CACF;AACF,cAAc,cAAc,gBAAgB,QAAQ;AAEpD,MAAM,gBAAgB,MAAM,YAGzB,EAAE,WAAW,UAAU,GAAG,SAAS,QACpC,qBAAC,cAAD,EAAA,UAAA,CACE,oBAAC,eAAD,EAAiB,CAAA,EACjB,qBAAC,gBAAgB,SAAjB;CACO;CACL,WAAW,GACT,4QACA,UACD;CACD,GAAI;WANN,CAQG,UACD,oBAAC,gBAAgB,OAAjB;EACE,cAAW;EACX,WAAW,GACT,eAAe;GAAE,MAAM;GAAW,OAAO;GAAS,CAAC,EACnD,mDACD;YAED,oBAAC,GAAD,EAAK,CAAA;EACiB,CAAA,CACA;GACb,EAAA,CAAA,CACf;AACF,cAAc,cAAc,gBAAgB,QAAQ;AAEpD,MAAM,gBAAgB,EAAE,WAAW,GAAG,YACpC,oBAAC,OAAD;CAAK,WAAW,GAAG,mDAAmD,UAAU;CAAE,GAAI;CAAS,CAAA;AAEjG,aAAa,cAAc;AAE3B,MAAM,gBAAgB,EAAE,WAAW,GAAG,YACpC,oBAAC,OAAD;CACE,WAAW,GAAG,6DAA6D,UAAU;CACrF,GAAI;CACJ,CAAA;AAEJ,aAAa,cAAc;AAE3B,MAAM,cAAc,MAAM,YAGvB,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,gBAAgB,OAAjB;CACO;CACL,WAAW,GAAG,qDAAqD,UAAU;CAC7E,GAAI;CACJ,CAAA,CACF;AACF,YAAY,cAAc,gBAAgB,MAAM;AAEhD,MAAM,oBAAoB,MAAM,YAG7B,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,gBAAgB,aAAjB;CACO;CACL,WAAW,GAAG,oCAAoC,UAAU;CAC5D,GAAI;CACJ,CAAA,CACF;AACF,kBAAkB,cAAc,gBAAgB,YAAY"}
1
+ {"version":3,"file":"dialog.js","names":[],"sources":["../../../src/ui/components/dialog.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { X } from 'lucide-react';\nimport { cn } from '@/utils/cn';\nimport { buttonVariants } from 'fumadocs-ui/components/ui/button';\nimport { useTranslations } from '@/ui/client/i18n';\n\nconst Dialog = DialogPrimitive.Root;\n\nconst DialogTrigger = DialogPrimitive.Trigger;\n\nconst DialogPortal = DialogPrimitive.Portal;\n\nconst DialogClose = DialogPrimitive.Close;\n\nconst DialogOverlay = React.forwardRef<\n React.ComponentRef<typeof DialogPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Overlay\n ref={ref}\n className={cn(\n 'fixed inset-0 z-50 bg-black/30 backdrop-blur-sm data-[state=open]:animate-fd-fade-in data-[state=closed]:animate-fd-fade-out',\n className,\n )}\n {...props}\n />\n));\nDialogOverlay.displayName = DialogPrimitive.Overlay.displayName;\n\nconst DialogContent = React.forwardRef<\n React.ComponentRef<typeof DialogPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>\n>(({ className, children, ...props }, ref) => {\n const t = useTranslations();\n return (\n <DialogPortal>\n <DialogOverlay />\n <DialogPrimitive.Content\n ref={ref}\n className={cn(\n 'fixed left-1/2 top-1/2 z-50 flex flex-col gap-4 w-full max-w-lg -translate-x-1/2 -translate-y-1/2 border bg-fd-popover p-4 shadow-lg rounded-xl duration-200 data-[state=open]:animate-fd-dialog-in data-[state=closed]:animate-fd-dialog-out focus-visible:outline-none',\n className,\n )}\n {...props}\n >\n {children}\n <DialogPrimitive.Close\n aria-label={t.close}\n className={cn(\n buttonVariants({ size: 'icon-sm', color: 'ghost' }),\n 'absolute end-2 top-2 text-fd-muted-foreground/70',\n )}\n >\n <X />\n </DialogPrimitive.Close>\n </DialogPrimitive.Content>\n </DialogPortal>\n );\n});\nDialogContent.displayName = DialogPrimitive.Content.displayName;\n\nconst DialogHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n <div className={cn('flex flex-col gap-1.5 text-center sm:text-start', className)} {...props} />\n);\nDialogHeader.displayName = 'DialogHeader';\n\nconst DialogFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:gap-2', className)}\n {...props}\n />\n);\nDialogFooter.displayName = 'DialogFooter';\n\nconst DialogTitle = React.forwardRef<\n React.ComponentRef<typeof DialogPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Title\n ref={ref}\n className={cn('text-lg font-semibold leading-none tracking-tight', className)}\n {...props}\n />\n));\nDialogTitle.displayName = DialogPrimitive.Title.displayName;\n\nconst DialogDescription = React.forwardRef<\n React.ComponentRef<typeof DialogPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Description\n ref={ref}\n className={cn('text-sm text-fd-muted-foreground', className)}\n {...props}\n />\n));\nDialogDescription.displayName = DialogPrimitive.Description.displayName;\n\nexport {\n Dialog,\n DialogPortal,\n DialogOverlay,\n DialogClose,\n DialogTrigger,\n DialogContent,\n DialogHeader,\n DialogFooter,\n DialogTitle,\n DialogDescription,\n};\n"],"mappings":";;;;;;;;;AASA,MAAM,SAAS,gBAAgB;AAE/B,MAAM,gBAAgB,gBAAgB;AAEtC,MAAM,eAAe,gBAAgB;AAEjB,gBAAgB;AAEpC,MAAM,gBAAgB,MAAM,YAGzB,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,gBAAgB,SAAjB;CACO;CACL,WAAW,GACT,gIACA,UACD;CACD,GAAI;CACJ,CAAA,CACF;AACF,cAAc,cAAc,gBAAgB,QAAQ;AAEpD,MAAM,gBAAgB,MAAM,YAGzB,EAAE,WAAW,UAAU,GAAG,SAAS,QAAQ;CAC5C,MAAM,IAAI,iBAAiB;AAC3B,QACE,qBAAC,cAAD,EAAA,UAAA,CACE,oBAAC,eAAD,EAAiB,CAAA,EACjB,qBAAC,gBAAgB,SAAjB;EACO;EACL,WAAW,GACT,4QACA,UACD;EACD,GAAI;YANN,CAQG,UACD,oBAAC,gBAAgB,OAAjB;GACE,cAAY,EAAE;GACd,WAAW,GACT,eAAe;IAAE,MAAM;IAAW,OAAO;IAAS,CAAC,EACnD,mDACD;aAED,oBAAC,GAAD,EAAK,CAAA;GACiB,CAAA,CACA;IACb,EAAA,CAAA;EAEjB;AACF,cAAc,cAAc,gBAAgB,QAAQ;AAEpD,MAAM,gBAAgB,EAAE,WAAW,GAAG,YACpC,oBAAC,OAAD;CAAK,WAAW,GAAG,mDAAmD,UAAU;CAAE,GAAI;CAAS,CAAA;AAEjG,aAAa,cAAc;AAE3B,MAAM,gBAAgB,EAAE,WAAW,GAAG,YACpC,oBAAC,OAAD;CACE,WAAW,GAAG,6DAA6D,UAAU;CACrF,GAAI;CACJ,CAAA;AAEJ,aAAa,cAAc;AAE3B,MAAM,cAAc,MAAM,YAGvB,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,gBAAgB,OAAjB;CACO;CACL,WAAW,GAAG,qDAAqD,UAAU;CAC7E,GAAI;CACJ,CAAA,CACF;AACF,YAAY,cAAc,gBAAgB,MAAM;AAEhD,MAAM,oBAAoB,MAAM,YAG7B,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,gBAAgB,aAAjB;CACO;CACL,WAAW,GAAG,oCAAoC,UAAU;CAC5D,GAAI;CACJ,CAAA,CACF;AACF,kBAAkB,cAAc,gBAAgB,YAAY"}
@@ -1,16 +1,15 @@
1
1
  "use client";
2
+ import { ClientCodeBlockProvider } from "./components/codeblock.js";
2
3
  import { jsx } from "react/jsx-runtime";
3
- import { configDefault } from "fumadocs-core/highlight";
4
- import * as base from "fumadocs-core/highlight/core/client";
4
+ import { defaultShikiFactory } from "fumadocs-core/highlight/shiki/full";
5
5
  //#region src/ui/full.client.tsx
6
- function ShikiConfigProvider({ children }) {
7
- const config = base.useShikiConfigOptional() ?? configDefault;
8
- return /* @__PURE__ */ jsx(base.ShikiConfigProvider, {
9
- config,
6
+ function FullProvider({ children }) {
7
+ return /* @__PURE__ */ jsx(ClientCodeBlockProvider, {
8
+ factory: defaultShikiFactory,
10
9
  children
11
10
  });
12
11
  }
13
12
  //#endregion
14
- export { ShikiConfigProvider };
13
+ export { FullProvider };
15
14
 
16
15
  //# sourceMappingURL=full.client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"full.client.js","names":[],"sources":["../../src/ui/full.client.tsx"],"sourcesContent":["'use client';\nimport * as base from 'fumadocs-core/highlight/core/client';\nimport { configDefault } from 'fumadocs-core/highlight';\nimport type { ReactNode } from 'react';\n\nexport function ShikiConfigProvider({ children }: { children: ReactNode }) {\n const config = base.useShikiConfigOptional() ?? configDefault;\n return <base.ShikiConfigProvider config={config}>{children}</base.ShikiConfigProvider>;\n}\n"],"mappings":";;;;;AAKA,SAAgB,oBAAoB,EAAE,YAAqC;CACzE,MAAM,SAAS,KAAK,wBAAwB,IAAI;AAChD,QAAO,oBAAC,KAAK,qBAAN;EAAkC;EAAS;EAAoC,CAAA"}
1
+ {"version":3,"file":"full.client.js","names":[],"sources":["../../src/ui/full.client.tsx"],"sourcesContent":["'use client';\nimport type { ReactNode } from 'react';\nimport { ClientCodeBlockProvider } from './components/codeblock';\nimport { defaultShikiFactory } from 'fumadocs-core/highlight/shiki/full';\n\nexport function FullProvider({ children }: { children: ReactNode }) {\n return (\n <ClientCodeBlockProvider factory={defaultShikiFactory}>{children}</ClientCodeBlockProvider>\n );\n}\n"],"mappings":";;;;;AAKA,SAAgB,aAAa,EAAE,YAAqC;AAClE,QACE,oBAAC,yBAAD;EAAyB,SAAS;EAAsB;EAAmC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"full.d.ts","names":[],"sources":["../../src/ui/full.tsx"],"mappings":";;;;;;KAMY,oBAAA,GAAuB,OAAA,CAAQ,sBAAA;AAAA,iBAE3B,aAAA,CAAc,MAAA,EAAQ,aAAA,EAAe,OAAA,GAAS,oBAAA,IAqBhC,KAAA,EAAO,YAAA,KAAY,kBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"full.d.ts","names":[],"sources":["../../src/ui/full.tsx"],"mappings":";;;;;;KAMY,oBAAA,GAAuB,OAAA,CAAQ,sBAAA;AAAA,iBAE3B,aAAA,CAAc,MAAA,EAAQ,aAAA,EAAe,OAAA,GAAS,oBAAA,IAsBhC,KAAA,EAAO,YAAA,KAAY,kBAAA,CAAA,GAAA,CAAA,OAAA"}
package/dist/ui/full.js CHANGED
@@ -1,11 +1,15 @@
1
1
  import { createAPIPage as createAPIPage$1 } from "./base.js";
2
- import { ShikiConfigProvider } from "./full.client.js";
2
+ import { FullProvider } from "./full.client.js";
3
3
  import { jsx } from "react/jsx-runtime";
4
- import { configDefault } from "fumadocs-core/highlight";
4
+ import { defaultShikiFactory } from "fumadocs-core/highlight/shiki/full";
5
5
  //#region src/ui/full.tsx
6
6
  function createAPIPage(server, options = {}) {
7
7
  const APIPage = createAPIPage$1(server, {
8
- shiki: configDefault,
8
+ shiki: defaultShikiFactory,
9
+ shikiOptions: { themes: {
10
+ light: "github-light",
11
+ dark: "github-dark"
12
+ } },
9
13
  async generateTypeScriptDefinitions(schema, ctx) {
10
14
  if (typeof schema !== "object") return;
11
15
  const { compile } = await import("@fumari/json-schema-ts");
@@ -23,7 +27,7 @@ function createAPIPage(server, options = {}) {
23
27
  ...options
24
28
  });
25
29
  return function APIPageFull(props) {
26
- return /* @__PURE__ */ jsx(ShikiConfigProvider, { children: /* @__PURE__ */ jsx(APIPage, { ...props }) });
30
+ return /* @__PURE__ */ jsx(FullProvider, { children: /* @__PURE__ */ jsx(APIPage, { ...props }) });
27
31
  };
28
32
  }
29
33
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"full.js","names":["base.createAPIPage"],"sources":["../../src/ui/full.tsx"],"sourcesContent":["import type { OpenAPIServer } from '@/server';\nimport * as base from './base';\nimport { configDefault } from 'fumadocs-core/highlight';\nimport { ApiPageProps } from './api-page';\nimport { ShikiConfigProvider } from './full.client';\n\nexport type CreateAPIPageOptions = Partial<base.CreateAPIPageOptions>;\n\nexport function createAPIPage(server: OpenAPIServer, options: CreateAPIPageOptions = {}) {\n const APIPage = base.createAPIPage(server, {\n shiki: configDefault,\n async generateTypeScriptDefinitions(schema, ctx) {\n if (typeof schema !== 'object') return;\n const { compile } = await import('@fumari/json-schema-ts');\n\n try {\n return compile(schema, {\n name: 'Response',\n readOnly: ctx.readOnly,\n writeOnly: ctx.writeOnly,\n getSchemaId: ctx.schema.getRawRef,\n });\n } catch (e) {\n console.warn('Failed to generate typescript schema:', e);\n }\n },\n ...options,\n });\n\n return function APIPageFull(props: ApiPageProps) {\n return (\n <ShikiConfigProvider>\n <APIPage {...props} />\n </ShikiConfigProvider>\n );\n };\n}\n"],"mappings":";;;;;AAQA,SAAgB,cAAc,QAAuB,UAAgC,EAAE,EAAE;CACvF,MAAM,UAAUA,gBAAmB,QAAQ;EACzC,OAAO;EACP,MAAM,8BAA8B,QAAQ,KAAK;AAC/C,OAAI,OAAO,WAAW,SAAU;GAChC,MAAM,EAAE,YAAY,MAAM,OAAO;AAEjC,OAAI;AACF,WAAO,QAAQ,QAAQ;KACrB,MAAM;KACN,UAAU,IAAI;KACd,WAAW,IAAI;KACf,aAAa,IAAI,OAAO;KACzB,CAAC;YACK,GAAG;AACV,YAAQ,KAAK,yCAAyC,EAAE;;;EAG5D,GAAG;EACJ,CAAC;AAEF,QAAO,SAAS,YAAY,OAAqB;AAC/C,SACE,oBAAC,qBAAD,EAAA,UACE,oBAAC,SAAD,EAAS,GAAI,OAAS,CAAA,EACF,CAAA"}
1
+ {"version":3,"file":"full.js","names":["base.createAPIPage"],"sources":["../../src/ui/full.tsx"],"sourcesContent":["import type { OpenAPIServer } from '@/server';\nimport * as base from './base';\nimport type { ApiPageProps } from './api-page';\nimport { defaultShikiFactory } from 'fumadocs-core/highlight/shiki/full';\nimport { FullProvider } from './full.client';\n\nexport type CreateAPIPageOptions = Partial<base.CreateAPIPageOptions>;\n\nexport function createAPIPage(server: OpenAPIServer, options: CreateAPIPageOptions = {}) {\n const APIPage = base.createAPIPage(server, {\n shiki: defaultShikiFactory,\n shikiOptions: { themes: { light: 'github-light', dark: 'github-dark' } },\n async generateTypeScriptDefinitions(schema, ctx) {\n if (typeof schema !== 'object') return;\n const { compile } = await import('@fumari/json-schema-ts');\n\n try {\n return compile(schema, {\n name: 'Response',\n readOnly: ctx.readOnly,\n writeOnly: ctx.writeOnly,\n getSchemaId: ctx.schema.getRawRef,\n });\n } catch (e) {\n console.warn('Failed to generate typescript schema:', e);\n }\n },\n ...options,\n });\n\n return function APIPageFull(props: ApiPageProps) {\n return (\n <FullProvider>\n <APIPage {...props} />\n </FullProvider>\n );\n };\n}\n"],"mappings":";;;;;AAQA,SAAgB,cAAc,QAAuB,UAAgC,EAAE,EAAE;CACvF,MAAM,UAAUA,gBAAmB,QAAQ;EACzC,OAAO;EACP,cAAc,EAAE,QAAQ;GAAE,OAAO;GAAgB,MAAM;GAAe,EAAE;EACxE,MAAM,8BAA8B,QAAQ,KAAK;AAC/C,OAAI,OAAO,WAAW,SAAU;GAChC,MAAM,EAAE,YAAY,MAAM,OAAO;AAEjC,OAAI;AACF,WAAO,QAAQ,QAAQ;KACrB,MAAM;KACN,UAAU,IAAI;KACd,WAAW,IAAI;KACf,aAAa,IAAI,OAAO;KACzB,CAAC;YACK,GAAG;AACV,YAAQ,KAAK,yCAAyC,EAAE;;;EAG5D,GAAG;EACJ,CAAC;AAEF,QAAO,SAAS,YAAY,OAAqB;AAC/C,SACE,oBAAC,cAAD,EAAA,UACE,oBAAC,SAAD,EAAS,GAAI,OAAS,CAAA,EACT,CAAA"}
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { cn } from "../../utils/cn.js";
3
3
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../components/select.js";
4
+ import { useTranslations } from "../client/i18n.js";
4
5
  import { createContext, use, useMemo, useState } from "react";
5
6
  import { jsx, jsxs } from "react/jsx-runtime";
6
7
  import { Check, Copy } from "lucide-react";
@@ -11,18 +12,16 @@ function CopyTypeScriptPanel({ name, code, className }) {
11
12
  const [isChecked, onCopy] = useCopyButton(() => {
12
13
  navigator.clipboard.writeText(code);
13
14
  });
15
+ const t = useTranslations();
16
+ const useTypeText = t.useTypeInTypeScript.replace("{name}", name);
14
17
  return /* @__PURE__ */ jsxs("div", {
15
18
  className: cn("flex items-start justify-between gap-2 bg-fd-card text-fd-card-foreground border rounded-xl p-3 not-prose mb-4 last:mb-0", className),
16
19
  children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("p", {
17
20
  className: "font-medium text-sm mb-2",
18
- children: "TypeScript Definitions"
19
- }), /* @__PURE__ */ jsxs("p", {
21
+ children: t.typeScriptDefinitions
22
+ }), /* @__PURE__ */ jsx("p", {
20
23
  className: "text-xs text-fd-muted-foreground",
21
- children: [
22
- "Use the ",
23
- name,
24
- " type in TypeScript."
25
- ]
24
+ children: useTypeText
26
25
  })] }), /* @__PURE__ */ jsxs("button", {
27
26
  onClick: onCopy,
28
27
  className: cn(buttonVariants({
@@ -30,7 +29,7 @@ function CopyTypeScriptPanel({ name, code, className }) {
30
29
  className: "p-2 gap-2",
31
30
  size: "sm"
32
31
  })),
33
- children: [isChecked ? /* @__PURE__ */ jsx(Check, { className: "size-3.5" }) : /* @__PURE__ */ jsx(Copy, { className: "size-3.5" }), "Copy"]
32
+ children: [isChecked ? /* @__PURE__ */ jsx(Check, { className: "size-3.5" }) : /* @__PURE__ */ jsx(Copy, { className: "size-3.5" }), t.copy]
34
33
  })]
35
34
  });
36
35
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":[],"sources":["../../../src/ui/operation/client.tsx"],"sourcesContent":["'use client';\n\nimport { useCopyButton } from 'fumadocs-ui/utils/use-copy-button';\nimport { buttonVariants } from 'fumadocs-ui/components/ui/button';\nimport { cn } from '@/utils/cn';\nimport { Check, Copy } from 'lucide-react';\nimport { type ComponentProps, createContext, type ReactNode, use, useMemo, useState } from 'react';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/ui/components/select';\n\nexport function CopyTypeScriptPanel({\n name,\n code,\n className,\n}: {\n code: string;\n name: 'response body' | 'request body';\n className?: string;\n}) {\n const [isChecked, onCopy] = useCopyButton(() => {\n void navigator.clipboard.writeText(code);\n });\n\n return (\n <div\n className={cn(\n 'flex items-start justify-between gap-2 bg-fd-card text-fd-card-foreground border rounded-xl p-3 not-prose mb-4 last:mb-0',\n className,\n )}\n >\n <div>\n <p className=\"font-medium text-sm mb-2\">TypeScript Definitions</p>\n <p className=\"text-xs text-fd-muted-foreground\">Use the {name} type in TypeScript.</p>\n </div>\n <button\n onClick={onCopy}\n className={cn(\n buttonVariants({\n color: 'secondary',\n className: 'p-2 gap-2',\n size: 'sm',\n }),\n )}\n >\n {isChecked ? <Check className=\"size-3.5\" /> : <Copy className=\"size-3.5\" />}\n Copy\n </button>\n </div>\n );\n}\n\nconst Context = createContext<{\n type: string | null;\n setType: (type: string) => void;\n} | null>(null);\n\nexport function SelectTabs({\n defaultValue,\n children,\n}: {\n defaultValue?: string;\n children: ReactNode;\n}) {\n const [type, setType] = useState<string | null>(defaultValue ?? null);\n\n return <Context value={useMemo(() => ({ type, setType }), [type])}>{children}</Context>;\n}\n\nexport function SelectTab({\n value,\n ...props\n}: ComponentProps<'div'> & {\n value: string;\n}) {\n const ctx = use(Context);\n if (value !== ctx?.type) return;\n\n return <div {...props}>{props.children}</div>;\n}\n\nexport function SelectTabTrigger({\n items,\n className,\n ...props\n}: ComponentProps<typeof SelectTrigger> & {\n items: {\n label: ReactNode;\n value: string;\n }[];\n}) {\n const { type, setType } = use(Context)!;\n\n return (\n <Select value={type ?? ''} onValueChange={setType}>\n <SelectTrigger className={cn('not-prose w-fit min-w-0 *:min-w-0', className)} {...props}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {items.map(({ label, value }) => (\n <SelectItem key={value} value={value}>\n {label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n}\n"],"mappings":";;;;;;;;;AAeA,SAAgB,oBAAoB,EAClC,MACA,MACA,aAKC;CACD,MAAM,CAAC,WAAW,UAAU,oBAAoB;AACzC,YAAU,UAAU,UAAU,KAAK;GACxC;AAEF,QACE,qBAAC,OAAD;EACE,WAAW,GACT,4HACA,UACD;YAJH,CAME,qBAAC,OAAD,EAAA,UAAA,CACE,oBAAC,KAAD;GAAG,WAAU;aAA2B;GAA0B,CAAA,EAClE,qBAAC,KAAD;GAAG,WAAU;aAAb;IAAgD;IAAS;IAAK;IAAwB;KAClF,EAAA,CAAA,EACN,qBAAC,UAAD;GACE,SAAS;GACT,WAAW,GACT,eAAe;IACb,OAAO;IACP,WAAW;IACX,MAAM;IACP,CAAC,CACH;aARH,CAUG,YAAY,oBAAC,OAAD,EAAO,WAAU,YAAa,CAAA,GAAG,oBAAC,MAAD,EAAM,WAAU,YAAa,CAAA,EAAC,OAErE;KACL;;;AAIV,MAAM,UAAU,cAGN,KAAK;AAEf,SAAgB,WAAW,EACzB,cACA,YAIC;CACD,MAAM,CAAC,MAAM,WAAW,SAAwB,gBAAgB,KAAK;AAErE,QAAO,oBAAC,SAAD;EAAS,OAAO,eAAe;GAAE;GAAM;GAAS,GAAG,CAAC,KAAK,CAAC;EAAG;EAAmB,CAAA;;AAGzF,SAAgB,UAAU,EACxB,OACA,GAAG,SAGF;AAED,KAAI,UADQ,IAAI,QAAQ,EACL,KAAM;AAEzB,QAAO,oBAAC,OAAD;EAAK,GAAI;YAAQ,MAAM;EAAe,CAAA;;AAG/C,SAAgB,iBAAiB,EAC/B,OACA,WACA,GAAG,SAMF;CACD,MAAM,EAAE,MAAM,YAAY,IAAI,QAAQ;AAEtC,QACE,qBAAC,QAAD;EAAQ,OAAO,QAAQ;EAAI,eAAe;YAA1C,CACE,oBAAC,eAAD;GAAe,WAAW,GAAG,qCAAqC,UAAU;GAAE,GAAI;aAChF,oBAAC,aAAD,EAAe,CAAA;GACD,CAAA,EAChB,oBAAC,eAAD,EAAA,UACG,MAAM,KAAK,EAAE,OAAO,YACnB,oBAAC,YAAD;GAA+B;aAC5B;GACU,EAFI,MAEJ,CACb,EACY,CAAA,CACT"}
1
+ {"version":3,"file":"client.js","names":[],"sources":["../../../src/ui/operation/client.tsx"],"sourcesContent":["'use client';\n\nimport { useCopyButton } from 'fumadocs-ui/utils/use-copy-button';\nimport { buttonVariants } from 'fumadocs-ui/components/ui/button';\nimport { cn } from '@/utils/cn';\nimport { Check, Copy } from 'lucide-react';\nimport { type ComponentProps, createContext, type ReactNode, use, useMemo, useState } from 'react';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/ui/components/select';\nimport { useTranslations } from '@/ui/client/i18n';\n\nexport function CopyTypeScriptPanel({\n name,\n code,\n className,\n}: {\n code: string;\n name: 'response body' | 'request body';\n className?: string;\n}) {\n const [isChecked, onCopy] = useCopyButton(() => {\n void navigator.clipboard.writeText(code);\n });\n const t = useTranslations();\n const useTypeText = t.useTypeInTypeScript.replace('{name}', name);\n\n return (\n <div\n className={cn(\n 'flex items-start justify-between gap-2 bg-fd-card text-fd-card-foreground border rounded-xl p-3 not-prose mb-4 last:mb-0',\n className,\n )}\n >\n <div>\n <p className=\"font-medium text-sm mb-2\">{t.typeScriptDefinitions}</p>\n <p className=\"text-xs text-fd-muted-foreground\">{useTypeText}</p>\n </div>\n <button\n onClick={onCopy}\n className={cn(\n buttonVariants({\n color: 'secondary',\n className: 'p-2 gap-2',\n size: 'sm',\n }),\n )}\n >\n {isChecked ? <Check className=\"size-3.5\" /> : <Copy className=\"size-3.5\" />}\n {t.copy}\n </button>\n </div>\n );\n}\n\nconst Context = createContext<{\n type: string | null;\n setType: (type: string) => void;\n} | null>(null);\n\nexport function SelectTabs({\n defaultValue,\n children,\n}: {\n defaultValue?: string;\n children: ReactNode;\n}) {\n const [type, setType] = useState<string | null>(defaultValue ?? null);\n\n return <Context value={useMemo(() => ({ type, setType }), [type])}>{children}</Context>;\n}\n\nexport function SelectTab({\n value,\n ...props\n}: ComponentProps<'div'> & {\n value: string;\n}) {\n const ctx = use(Context);\n if (value !== ctx?.type) return;\n\n return <div {...props}>{props.children}</div>;\n}\n\nexport function SelectTabTrigger({\n items,\n className,\n ...props\n}: ComponentProps<typeof SelectTrigger> & {\n items: {\n label: ReactNode;\n value: string;\n }[];\n}) {\n const { type, setType } = use(Context)!;\n\n return (\n <Select value={type ?? ''} onValueChange={setType}>\n <SelectTrigger className={cn('not-prose w-fit min-w-0 *:min-w-0', className)} {...props}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {items.map(({ label, value }) => (\n <SelectItem key={value} value={value}>\n {label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n}\n"],"mappings":";;;;;;;;;;AAgBA,SAAgB,oBAAoB,EAClC,MACA,MACA,aAKC;CACD,MAAM,CAAC,WAAW,UAAU,oBAAoB;AACzC,YAAU,UAAU,UAAU,KAAK;GACxC;CACF,MAAM,IAAI,iBAAiB;CAC3B,MAAM,cAAc,EAAE,oBAAoB,QAAQ,UAAU,KAAK;AAEjE,QACE,qBAAC,OAAD;EACE,WAAW,GACT,4HACA,UACD;YAJH,CAME,qBAAC,OAAD,EAAA,UAAA,CACE,oBAAC,KAAD;GAAG,WAAU;aAA4B,EAAE;GAA0B,CAAA,EACrE,oBAAC,KAAD;GAAG,WAAU;aAAoC;GAAgB,CAAA,CAC7D,EAAA,CAAA,EACN,qBAAC,UAAD;GACE,SAAS;GACT,WAAW,GACT,eAAe;IACb,OAAO;IACP,WAAW;IACX,MAAM;IACP,CAAC,CACH;aARH,CAUG,YAAY,oBAAC,OAAD,EAAO,WAAU,YAAa,CAAA,GAAG,oBAAC,MAAD,EAAM,WAAU,YAAa,CAAA,EAC1E,EAAE,KACI;KACL;;;AAIV,MAAM,UAAU,cAGN,KAAK;AAEf,SAAgB,WAAW,EACzB,cACA,YAIC;CACD,MAAM,CAAC,MAAM,WAAW,SAAwB,gBAAgB,KAAK;AAErE,QAAO,oBAAC,SAAD;EAAS,OAAO,eAAe;GAAE;GAAM;GAAS,GAAG,CAAC,KAAK,CAAC;EAAG;EAAmB,CAAA;;AAGzF,SAAgB,UAAU,EACxB,OACA,GAAG,SAGF;AAED,KAAI,UADQ,IAAI,QAAQ,EACL,KAAM;AAEzB,QAAO,oBAAC,OAAD;EAAK,GAAI;YAAQ,MAAM;EAAe,CAAA;;AAG/C,SAAgB,iBAAiB,EAC/B,OACA,WACA,GAAG,SAMF;CACD,MAAM,EAAE,MAAM,YAAY,IAAI,QAAQ;AAEtC,QACE,qBAAC,QAAD;EAAQ,OAAO,QAAQ;EAAI,eAAe;YAA1C,CACE,oBAAC,eAAD;GAAe,WAAW,GAAG,qCAAqC,UAAU;GAAE,GAAI;aAChF,oBAAC,aAAD,EAAe,CAAA;GACD,CAAA,EAChB,oBAAC,eAAD,EAAA,UACG,MAAM,KAAK,EAAE,OAAO,YACnB,oBAAC,YAAD;GAA+B;aAC5B;GACU,EAFI,MAEJ,CACb,EACY,CAAA,CACT"}
@@ -4,6 +4,7 @@ import { isMediaTypeSupported } from "../../requests/media/resolve-adapter.js";
4
4
  import "../../requests/media/adapter.js";
5
5
  import { cn } from "../../utils/cn.js";
6
6
  import { Badge, MethodLabel } from "../components/method-label.js";
7
+ import { I18nLabel } from "../client/i18n.js";
7
8
  import { APIPlayground } from "../../playground/index.js";
8
9
  import { Schema } from "../schema/index.js";
9
10
  import { UsageTabsProviderLazy } from "./usage-tabs/lazy.js";
@@ -15,12 +16,12 @@ import { ServerProviderLazy } from "../contexts/api.lazy.js";
15
16
  import { Fragment } from "react";
16
17
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
17
18
  //#region src/ui/operation/index.tsx
18
- const ParamTypes = {
19
- path: "Path Parameters",
20
- query: "Query Parameters",
21
- header: "Header Parameters",
22
- cookie: "Cookie Parameters"
23
- };
19
+ const paramTypeKeys = [
20
+ "path",
21
+ "query",
22
+ "header",
23
+ "cookie"
24
+ ];
24
25
  async function Operation({ type = "operation", path, method, ctx, showTitle, showDescription, headingLevel = 2 }) {
25
26
  const { schema: { dereferenced } } = ctx;
26
27
  const body = method.requestBody;
@@ -49,7 +50,10 @@ async function Operation({ type = "operation", path, method, ctx, showTitle, sho
49
50
  children: [
50
51
  /* @__PURE__ */ jsxs("div", {
51
52
  className: "flex gap-2 items-center justify-between mt-10",
52
- children: [ctx.renderHeading(headingLevel, "Request Body", { className: "my-0!" }), contentTypes.length > 1 ? /* @__PURE__ */ jsx(SelectTabTrigger, {
53
+ children: [ctx.renderHeading(headingLevel, /* @__PURE__ */ jsx(I18nLabel, { label: "titleRequestBody" }), {
54
+ id: "request-body",
55
+ className: "my-0!"
56
+ }), contentTypes.length > 1 ? /* @__PURE__ */ jsx(SelectTabTrigger, {
53
57
  items,
54
58
  className: "font-medium"
55
59
  }) : /* @__PURE__ */ jsx("p", {
@@ -90,7 +94,7 @@ async function Operation({ type = "operation", path, method, ctx, showTitle, sho
90
94
  }
91
95
  if (method.responses && ctx.showResponseSchema !== false) {
92
96
  const statuses = Object.keys(method.responses);
93
- responseNode = /* @__PURE__ */ jsxs(Fragment$1, { children: [ctx.renderHeading(headingLevel, "Response Body"), /* @__PURE__ */ jsx(Accordions, {
97
+ responseNode = /* @__PURE__ */ jsxs(Fragment$1, { children: [ctx.renderHeading(headingLevel, /* @__PURE__ */ jsx(I18nLabel, { label: "titleResponseBody" }), { id: "response-body" }), /* @__PURE__ */ jsx(Accordions, {
94
98
  type: "multiple",
95
99
  children: statuses.map((status) => /* @__PURE__ */ jsx(ResponseAccordion, {
96
100
  status,
@@ -99,10 +103,10 @@ async function Operation({ type = "operation", path, method, ctx, showTitle, sho
99
103
  }, status))
100
104
  })] });
101
105
  }
102
- const parameterNode = Object.entries(ParamTypes).map(([type, title]) => {
106
+ const parameterNode = paramTypeKeys.map((type) => {
103
107
  const params = method.parameters?.filter((param) => param.in === type);
104
108
  if (!params || params.length === 0) return;
105
- return /* @__PURE__ */ jsxs(Fragment, { children: [ctx.renderHeading(headingLevel, title), /* @__PURE__ */ jsx("div", {
109
+ return /* @__PURE__ */ jsxs(Fragment, { children: [ctx.renderHeading(headingLevel, /* @__PURE__ */ jsx(I18nLabel, { label: `${type}Parameters` }), { id: `parameters-${type}` }), /* @__PURE__ */ jsx("div", {
106
110
  className: "flex flex-col",
107
111
  children: params.map((param) => param.schema != null && /* @__PURE__ */ jsx(Schema, {
108
112
  client: {
@@ -149,7 +153,10 @@ async function Operation({ type = "operation", path, method, ctx, showTitle, sho
149
153
  defaultValue: items[0].value,
150
154
  children: [/* @__PURE__ */ jsxs("div", {
151
155
  className: "flex items-start justify-between gap-2 mt-10",
152
- children: [ctx.renderHeading(headingLevel, "Authorization", { className: "my-0!" }), items.length > 1 ? /* @__PURE__ */ jsx(SelectTabTrigger, { items }) : /* @__PURE__ */ jsx("div", {
156
+ children: [ctx.renderHeading(headingLevel, /* @__PURE__ */ jsx(I18nLabel, { label: "authorization" }), {
157
+ id: "authorization",
158
+ className: "my-0!"
159
+ }), items.length > 1 ? /* @__PURE__ */ jsx(SelectTabTrigger, { items }) : /* @__PURE__ */ jsx("div", {
153
160
  className: "not-prose",
154
161
  children: items[0].label
155
162
  })]
@@ -180,7 +187,10 @@ async function Operation({ type = "operation", path, method, ctx, showTitle, sho
180
187
  defaultValue: items[0].value,
181
188
  children: [/* @__PURE__ */ jsxs("div", {
182
189
  className: "flex justify-between gap-2 items-end mt-10",
183
- children: [ctx.renderHeading(headingLevel, "Callbacks", { className: "my-0!" }), callbacks.length > 1 ? /* @__PURE__ */ jsx(SelectTabTrigger, {
190
+ children: [ctx.renderHeading(headingLevel, /* @__PURE__ */ jsx(I18nLabel, { label: "titleCallbacks" }), {
191
+ id: "callbacks",
192
+ className: "my-0!"
193
+ }), callbacks.length > 1 ? /* @__PURE__ */ jsx(SelectTabTrigger, {
184
194
  items,
185
195
  className: "font-medium"
186
196
  }) : /* @__PURE__ */ jsx("p", {
@@ -392,21 +402,29 @@ function WebhookCallback({ callback, ctx, headingLevel }) {
392
402
  }
393
403
  function AuthScheme({ scheme, scopes, ctx }) {
394
404
  if (scheme.type === "http" || scheme.type === "oauth2") return /* @__PURE__ */ jsxs(AuthProperty, {
395
- name: "Authorization",
396
- type: scheme.type === "http" && scheme.scheme === "basic" ? `Basic <token>` : "Bearer <token>",
405
+ name: /* @__PURE__ */ jsx(I18nLabel, { label: "authorization" }),
406
+ type: scheme.type === "http" && scheme.scheme === "basic" ? /* @__PURE__ */ jsx(I18nLabel, { label: "authBasicTokenExample" }) : /* @__PURE__ */ jsx(I18nLabel, { label: "authBearerTokenExample" }),
397
407
  deprecated: scheme.deprecated,
398
408
  scopes,
399
- children: [scheme.description && ctx.renderMarkdown(scheme.description), /* @__PURE__ */ jsxs("p", { children: ["In: ", /* @__PURE__ */ jsx("code", { children: "header" })] })]
409
+ children: [scheme.description && ctx.renderMarkdown(scheme.description), /* @__PURE__ */ jsxs("p", { children: [
410
+ /* @__PURE__ */ jsx(I18nLabel, { label: "authTokenIn" }),
411
+ ": ",
412
+ /* @__PURE__ */ jsx("code", { children: "header" })
413
+ ] })]
400
414
  });
401
415
  if (scheme.type === "apiKey") return /* @__PURE__ */ jsxs(AuthProperty, {
402
416
  name: scheme.name,
403
417
  type: "<token>",
404
418
  deprecated: scheme.deprecated,
405
419
  scopes,
406
- children: [scheme.description && ctx.renderMarkdown(scheme.description), /* @__PURE__ */ jsxs("p", { children: ["In: ", /* @__PURE__ */ jsx("code", { children: scheme.in })] })]
420
+ children: [scheme.description && ctx.renderMarkdown(scheme.description), /* @__PURE__ */ jsxs("p", { children: [
421
+ /* @__PURE__ */ jsx(I18nLabel, { label: "authTokenIn" }),
422
+ ": ",
423
+ /* @__PURE__ */ jsx("code", { children: scheme.in })
424
+ ] })]
407
425
  });
408
426
  if (scheme.type === "openIdConnect") return /* @__PURE__ */ jsx(AuthProperty, {
409
- name: "OpenID Connect",
427
+ name: /* @__PURE__ */ jsx(I18nLabel, { label: "openIdConnect" }),
410
428
  type: "<token>",
411
429
  deprecated: scheme.deprecated,
412
430
  scopes,
@@ -429,12 +447,17 @@ function AuthProperty({ name, type, deprecated = false, scopes = [], className,
429
447
  }),
430
448
  deprecated && /* @__PURE__ */ jsx(Badge, {
431
449
  color: "red",
432
- children: "Deprecated"
450
+ className: "text-xs",
451
+ children: /* @__PURE__ */ jsx(I18nLabel, { label: "deprecated" })
433
452
  })
434
453
  ]
435
454
  }), /* @__PURE__ */ jsxs("div", {
436
455
  className: "prose-no-margin pt-2.5 empty:hidden",
437
- children: [props.children, scopes.length > 0 && /* @__PURE__ */ jsxs("p", { children: ["Scope: ", /* @__PURE__ */ jsx("code", { children: scopes.join(", ") })] })]
456
+ children: [props.children, scopes.length > 0 && /* @__PURE__ */ jsxs("p", { children: [
457
+ /* @__PURE__ */ jsx(I18nLabel, { label: "authScope" }),
458
+ ": ",
459
+ /* @__PURE__ */ jsx("code", { children: scopes.join(", ") })
460
+ ] })]
438
461
  })]
439
462
  });
440
463
  }