@clarify-labs/renderer 0.9.3 → 0.9.4

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 (44) hide show
  1. package/output/{ClarifyShell-Dm--LZco.cjs → ClarifyShell-7r92MZg9.cjs} +109 -72
  2. package/output/ClarifyShell-7r92MZg9.cjs.map +1 -0
  3. package/output/{ClarifyShell-BQ29N8P5.js → ClarifyShell-D2P0iZ_m.js} +104 -73
  4. package/output/ClarifyShell-D2P0iZ_m.js.map +1 -0
  5. package/output/{OpenApiOperation-DIWGdw29.cjs → OpenApiOperation-CyyPlZL6.cjs} +100 -26
  6. package/output/OpenApiOperation-CyyPlZL6.cjs.map +1 -0
  7. package/output/{OpenApiOperation-C9xyRo5a.js → OpenApiOperation-Dhlz3JSx.js} +100 -26
  8. package/output/OpenApiOperation-Dhlz3JSx.js.map +1 -0
  9. package/output/{PageActions-DEuFHgyB.cjs → PageActions-CTn2XkPg.cjs} +12 -3
  10. package/output/PageActions-CTn2XkPg.cjs.map +1 -0
  11. package/output/{PageActions-B_tSec1f.js → PageActions-D0PA8Zv5.js} +7 -4
  12. package/output/PageActions-D0PA8Zv5.js.map +1 -0
  13. package/output/app/ContentDiagnostic.d.ts +9 -0
  14. package/output/app/ErrorBoundary.d.ts +0 -2
  15. package/output/app/RenderErrorPanel.d.ts +20 -0
  16. package/output/client.cjs +3 -3
  17. package/output/client.js +3 -3
  18. package/output/core/context.d.ts +1 -0
  19. package/output/core/i18n.d.ts +1 -1
  20. package/output/core/types.d.ts +1 -0
  21. package/output/index.cjs +43 -4
  22. package/output/index.cjs.map +1 -1
  23. package/output/index.d.ts +5 -3
  24. package/output/index.js +42 -5
  25. package/output/index.js.map +1 -1
  26. package/output/openapi/components/SchemaProperties.d.ts +1 -0
  27. package/output/openapi/entry.d.ts +5 -0
  28. package/output/openapi/index.d.ts +2 -2
  29. package/output/preview.cjs +2 -2
  30. package/output/preview.js +2 -2
  31. package/output/{render-CEWLJSmt.js → render-CwSsfrs7.js} +2 -2
  32. package/output/{render-CEWLJSmt.js.map → render-CwSsfrs7.js.map} +1 -1
  33. package/output/{render-BCGK1WpS.cjs → render-DXDSIfZ8.cjs} +2 -2
  34. package/output/{render-BCGK1WpS.cjs.map → render-DXDSIfZ8.cjs.map} +1 -1
  35. package/output/renderer.css +4 -0
  36. package/output/server.cjs +2 -2
  37. package/output/server.js +2 -2
  38. package/package.json +1 -1
  39. package/output/ClarifyShell-BQ29N8P5.js.map +0 -1
  40. package/output/ClarifyShell-Dm--LZco.cjs.map +0 -1
  41. package/output/OpenApiOperation-C9xyRo5a.js.map +0 -1
  42. package/output/OpenApiOperation-DIWGdw29.cjs.map +0 -1
  43. package/output/PageActions-B_tSec1f.js.map +0 -1
  44. package/output/PageActions-DEuFHgyB.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":[],"sources":["../source/openapi/lib/spec-path.ts","../source/openapi/lib/utils.ts","../source/openapi/entry.tsx","../source/mdx/components.ts","../source/mdx/DocShell.tsx"],"sourcesContent":["import { useLocation } from 'react-router-dom'\n\nimport { useConfig, useLocale, useOpenApis } from '../../core/context'\n\nimport type { OpenAPISpec } from './utils'\n\nconst VIRTUAL_PREFIX = 'virtual:clarify-page/'\n\nfunction resolveRelativePath(fromDir: string, to: string): string {\n const parts = (fromDir + '/' + to).split('/').filter(Boolean)\n const stack: string[] = []\n for (const part of parts) {\n if (part === '..') {\n stack.pop()\n } else if (part !== '.') {\n stack.push(part)\n }\n }\n return stack.join('/')\n}\n\nfunction normalizeSpecPath(specPath: string, currentRoutePath?: string, routePrefix = ''): string {\n if (specPath.startsWith(VIRTUAL_PREFIX)) return specPath\n\n const normalizedRoutePrefix = routePrefix.replace(/^\\/+|\\/+$/g, '')\n const normalizedSpecPath = specPath.startsWith('/') && normalizedRoutePrefix && specPath.slice(1).startsWith(`${normalizedRoutePrefix}/`)\n ? '/' + specPath.slice(normalizedRoutePrefix.length + 2)\n : specPath\n\n if (normalizedSpecPath.startsWith('/')) {\n return VIRTUAL_PREFIX + normalizedSpecPath.replace(/^\\//, '')\n }\n const fromDir = currentRoutePath === '/' ? '' : currentRoutePath?.replace(/^\\//, '').replace(/\\/[^/]*$/, '') ?? ''\n const normalizedFromDir = normalizedRoutePrefix && fromDir.startsWith(`${normalizedRoutePrefix}/`)\n ? fromDir.slice(normalizedRoutePrefix.length + 1)\n : fromDir\n return VIRTUAL_PREFIX + resolveRelativePath(normalizedFromDir, normalizedSpecPath)\n}\n\n/**\n * 为绝对 specPath 生成带 locale 前缀的候选模块 ID。\n *\n * 所有 locale 的 spec 都注册在 `virtual:clarify-page/<locale>/...` 下,\n * 因此绝对路径(如 `/api`)需要显式注入 locale 前缀才能命中。\n * 相对路径会因为当前路由已含 locale 前缀而自动解析到正确的 spec。\n */\nfunction localizeSpecModuleId(moduleId: string, specPath: string, locale: string | undefined, _defaultLocale: string | undefined): string | undefined {\n if (!locale) return undefined\n // 仅处理绝对路径;相对路径已经基于含 locale 前缀的当前路由解析。\n if (!specPath.startsWith('/') || specPath.startsWith(VIRTUAL_PREFIX)) return undefined\n const rest = moduleId.slice(VIRTUAL_PREFIX.length)\n if (rest.startsWith(`${locale}/`) || rest === locale) return undefined\n return `${VIRTUAL_PREFIX}${locale}/${rest}`\n}\n\nexport function useOpenApiSpec(spec?: OpenAPISpec, specPath?: string): OpenAPISpec | null {\n const config = useConfig()\n const locale = useLocale()\n const specs = useOpenApis()\n const location = useLocation()\n\n if (spec) return spec\n if (!specPath) return null\n\n const normalized = normalizeSpecPath(specPath, location.pathname, config.routePrefix)\n const localized = localizeSpecModuleId(normalized, specPath, locale, config.i18n?.defaultLocale)\n\n if (localized && specs[localized]) return specs[localized]\n return specs[normalized] ?? null\n}\n","import type { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'\n\nimport type { OpenApiRecord } from '../types'\n\nexport type OpenAPISpec = OpenAPIV3.Document | OpenAPIV3_1.Document\nexport type OpenAPIOperation = OpenAPIV3.OperationObject | OpenAPIV3_1.OperationObject\n\nexport const OPENAPI_HTTP_METHODS = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace'] as const\n\nexport type OpenAPIHttpMethod = typeof OPENAPI_HTTP_METHODS[number]\n\nexport function isOpenAPIHttpMethod(method: string): method is OpenAPIHttpMethod {\n return (OPENAPI_HTTP_METHODS as readonly string[]).includes(method.toLowerCase())\n}\n\nfunction isRecord(value: unknown): value is OpenApiRecord {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction resolveOpenApiRef(spec: OpenAPISpec, ref: string): unknown {\n if (!ref.startsWith('#/')) return undefined\n\n return ref\n .slice(2)\n .split('/')\n .map((part) => part.replace(/~1/g, '/').replace(/~0/g, '~'))\n .reduce<unknown>((current, part) => (isRecord(current) ? current[part] : undefined), spec)\n}\n\nfunction getPathItem(spec: OpenAPISpec, path: string): OpenApiRecord | undefined {\n const pathItem = spec.paths?.[path]\n const resolved = isRecord(pathItem) && typeof pathItem.$ref === 'string' ? resolveOpenApiRef(spec, pathItem.$ref) : pathItem\n return isRecord(resolved) ? resolved : undefined\n}\n\nexport function getOpenApiOperation(spec: OpenAPISpec, path: string, method: string): OpenAPIOperation | undefined {\n if (!isOpenAPIHttpMethod(method)) return undefined\n return getPathItem(spec, path)?.[method.toLowerCase() as OpenAPIHttpMethod] as OpenAPIOperation | undefined\n}\n\nexport function listOpenApiOperations(spec: OpenAPISpec): Array<{ path: string; method: OpenAPIHttpMethod; operation: OpenAPIOperation }> {\n const paths = spec.paths ?? {}\n const operations: Array<{ path: string; method: OpenAPIHttpMethod; operation: OpenAPIOperation }> = []\n\n for (const path of Object.keys(paths)) {\n const pathItem = getPathItem(spec, path)\n if (!pathItem) continue\n for (const method of OPENAPI_HTTP_METHODS) {\n const operation = pathItem[method]\n if (operation) operations.push({ path, method, operation: operation as OpenAPIOperation })\n }\n }\n\n return operations\n}\n","import type { ReactNode } from 'react'\n\nimport { PageTitleActions } from '../app/PageActions'\nimport { Prose } from '../components/Prose'\nimport { useBuiltInText } from '../core/i18n'\nimport { Markdown } from '../mdx/Markdown'\n\nimport { OpenApiOperation as OpenApiOperationComponent } from './components/OpenApiOperation'\nimport { useOpenApiSpec } from './lib/spec-path'\nimport { getOpenApiOperation, listOpenApiOperations } from './lib/utils'\nimport type { OpenAPISpec } from './lib/utils'\n\ntype OpenApiPathsProps = { spec: OpenAPISpec; tagFilter?: string[] }\n\ntype OpenApiHeaderProps = { spec: OpenAPISpec }\n\ntype WarningBoxProps = {\n children: ReactNode\n tone?: 'amber' | 'red'\n}\n\nexport type OpenApiDocumentProps = {\n spec?: OpenAPISpec\n specPath?: string\n tagFilter?: string[]\n}\n\ntype OpenApiOperationWithSpecProps = {\n spec: OpenAPISpec\n path: string\n method: string\n}\n\nexport type OpenApiOperationProps = {\n specPath: string\n path: string\n method: string\n}\n\nfunction OpenApiHeader(arg0: OpenApiHeaderProps): ReactNode {\n const { spec } = arg0\n\n const t = useBuiltInText()\n return (\n <header className=\"clarify-openapi-header mb-16 border-b border-(--clarify-theme-tokens-colors-border) pb-8\">\n <p className=\"mb-3 text-xs/6 font-medium tracking-widest text-(--clarify-ui-accent-text) uppercase\">\n {t('openapi.openApiReference')}\n </p>\n <div className=\"clarify-page-title-row flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n <h1 className=\"clarify-page-title min-w-0 flex-1\">{spec.info?.title ?? t('openapi.apiDocumentation')}</h1>\n <PageTitleActions />\n </div>\n {spec.info?.description ? <Markdown className=\"lead mt-4 *:first:mt-0 *:last:mb-0\">{spec.info.description}</Markdown> : null}\n {spec.info?.version ? <p className=\"mt-4 text-sm text-(--clarify-ui-text-faint)\">{t('openapi.version', { version: spec.info.version })}</p> : null}\n </header>\n )\n}\n\nfunction operationMatchesTags(operationTags: string[] | undefined, filterTags: string[] | undefined): boolean {\n if (!filterTags?.length) return true\n return operationTags?.some(tag => filterTags.includes(tag)) ?? false\n}\n\nfunction OpenApiPaths(arg0: OpenApiPathsProps): ReactNode {\n const { spec, tagFilter } = arg0\n\n const entries = listOpenApiOperations(spec)\n .filter(({ operation }) => operationMatchesTags(operation.tags, tagFilter))\n .map(({ path, method, operation }) => ({\n path,\n method: method.toUpperCase(),\n operation,\n }))\n\n return (\n <div className=\"clarify-api-endpoints divide-y divide-zinc-200/70 dark:divide-white/10\">\n {entries.map(({ path, method, operation }) => (\n <OpenApiOperationComponent key={`${method}-${path}`} spec={spec} path={path} method={method} operation={operation} />\n ))}\n </div>\n )\n}\n\nfunction WarningBox(arg0: WarningBoxProps): ReactNode {\n const { children, tone = 'amber' } = arg0\n\n const classes = tone === 'red'\n ? 'rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-700 dark:border-red-500/30 dark:bg-red-500/10 dark:text-red-200'\n : 'rounded-lg border border-amber-200 bg-amber-50 p-4 text-sm text-amber-700 dark:border-amber-500/30 dark:bg-amber-500/10 dark:text-amber-200'\n\n return <div className={`clarify-warning ${classes}`}>{children}</div>\n}\n\nexport function OpenApiDocument(arg0: OpenApiDocumentProps): ReactNode {\n const { spec, specPath, tagFilter } = arg0\n const t = useBuiltInText()\n const resolved = useOpenApiSpec(spec, specPath)\n\n if (!resolved) {\n return <WarningBox>{t('openapi.specNotFound', { specPath: specPath ?? t('openapi.specPathMissing') })}</WarningBox>\n }\n\n return (\n <article className=\"clarify-openapi-page flex h-full flex-col pt-16 pb-10\">\n <Prose className=\"flex-auto\">\n <OpenApiHeader spec={resolved} />\n <OpenApiPaths spec={resolved} tagFilter={tagFilter} />\n </Prose>\n </article>\n )\n}\n\nfunction OpenApiOperationWithSpec(arg0: OpenApiOperationWithSpecProps): ReactNode {\n const { spec, path, method } = arg0\n const t = useBuiltInText()\n const op = getOpenApiOperation(spec, path, method)\n\n if (!op) {\n return <WarningBox tone=\"red\">{t('openapi.endpointNotFound', { endpoint: `${method.toUpperCase()} ${path}` })}</WarningBox>\n }\n\n const normalizedMethod = method.toUpperCase()\n return <OpenApiOperationComponent key={`${normalizedMethod}-${path}`} spec={spec} path={path} method={normalizedMethod} operation={op} />\n}\n\nexport function OpenApiOperation(arg0: OpenApiOperationProps): ReactNode {\n const { specPath, path, method } = arg0\n const t = useBuiltInText()\n const spec = useOpenApiSpec(undefined, specPath)\n\n if (!spec) {\n return <WarningBox>{t('openapi.specNotFound', { specPath })}</WarningBox>\n }\n\n return <OpenApiOperationWithSpec spec={spec} path={path} method={method} />\n}\n","import { Collapse } from '../components/Collapse'\nimport { Mermaid } from '../components/Mermaid'\nimport { OpenApiDocument, OpenApiOperation } from '../openapi'\n\nimport { Markdown } from './Markdown'\nimport * as mdxPrimitives from './primitives'\n\nconst builtInMDXComponents = {\n ...mdxPrimitives,\n Markdown,\n Collapse,\n Mermaid,\n}\n\nconst builtInOpenAPIComponents = {\n OpenApiDocument,\n OpenApiOperation,\n}\n\nexport function useMDXComponents(components: Record<string, unknown> = {}) {\n return {\n ...components,\n ...builtInMDXComponents,\n ...builtInOpenAPIComponents,\n }\n}\n","import type { ReactNode } from 'react'\n\nimport { Prose } from '../components/Prose'\n\nexport type DocShellProps = {\n title: string\n subtitle?: string\n children: ReactNode\n}\n\nexport function DocShell(arg0: DocShellProps) {\n const { title, subtitle, children } = arg0\n\n return (\n <main className=\"clarify-doc-shell min-h-screen bg-(--clarify-theme-tokens-colors-background) px-6 py-10 text-(--clarify-theme-tokens-colors-foreground) md:px-10\">\n <div className=\"mx-auto max-w-6xl\">\n <header className=\"mb-10\">\n <h1 className=\"text-3xl font-bold tracking-tight md:text-5xl\">{title}</h1>\n {subtitle ? <p className=\"mt-3 max-w-2xl text-(--clarify-ui-text-soft)\">{subtitle}</p> : null}\n </header>\n <Prose>{children}</Prose>\n </div>\n </main>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../source/app/ContentDiagnostic.tsx","../source/openapi/lib/spec-path.ts","../source/openapi/lib/utils.ts","../source/openapi/entry.tsx","../source/mdx/components.ts","../source/mdx/DocShell.tsx"],"sourcesContent":["import type { ComponentType } from 'react'\n\nimport { RenderErrorPanel } from './RenderErrorPanel'\n\nexport type ContentDiagnostic = {\n kind: string\n title: string\n message: string\n details?: string\n filePath?: string\n}\n\ntype ContentDiagnosticPanelProps = {\n data: ContentDiagnostic\n}\n\nfunction ContentDiagnosticPanel(params: ContentDiagnosticPanelProps) {\n const { data } = params\n const typeLabel = data.kind === 'mdx' ? 'MDX' : data.kind === 'openapi' ? 'OpenAPI' : 'Route'\n const detailsLabel = data.kind === 'mdx' ? 'Why it happened' : 'Details'\n const pathLabel = 'File'\n\n return (\n <RenderErrorPanel\n title={data.title}\n description={data.message}\n titleId=\"clarify-content-diagnostic-title\"\n metadata={[\n { label: pathLabel, value: data.filePath ?? 'Unknown' },\n { label: 'Type', value: typeLabel },\n ]}\n detailsLabel={detailsLabel}\n detailsContent={data.details ? (\n <pre className=\"max-h-(--clarify-error-details-max-height) overflow-auto whitespace-pre-wrap wrap-break-word font-mono\">\n {data.details}\n </pre>\n ) : null}\n />\n )\n}\n\nexport function createContentDiagnosticComponent(data: ContentDiagnostic): ComponentType {\n return function ContentDiagnosticComponent() {\n return <ContentDiagnosticPanel data={data} />\n }\n}\n","import { useLocation } from 'react-router-dom'\n\nimport { useConfig, useLocale, useOpenApis } from '../../core/context'\n\nimport type { OpenAPISpec } from './utils'\n\nconst VIRTUAL_PREFIX = 'virtual:clarify-page/'\n\nfunction resolveRelativePath(fromDir: string, to: string): string {\n const parts = (fromDir + '/' + to).split('/').filter(Boolean)\n const stack: string[] = []\n for (const part of parts) {\n if (part === '..') {\n stack.pop()\n } else if (part !== '.') {\n stack.push(part)\n }\n }\n return stack.join('/')\n}\n\nfunction normalizeSpecPath(specPath: string, currentRoutePath?: string, routePrefix = ''): string {\n if (specPath.startsWith(VIRTUAL_PREFIX)) return specPath\n\n const normalizedRoutePrefix = routePrefix.replace(/^\\/+|\\/+$/g, '')\n const normalizedSpecPath = specPath.startsWith('/') && normalizedRoutePrefix && specPath.slice(1).startsWith(`${normalizedRoutePrefix}/`)\n ? '/' + specPath.slice(normalizedRoutePrefix.length + 2)\n : specPath\n\n if (normalizedSpecPath.startsWith('/')) {\n return VIRTUAL_PREFIX + normalizedSpecPath.replace(/^\\//, '')\n }\n const fromDir = currentRoutePath === '/' ? '' : currentRoutePath?.replace(/^\\//, '').replace(/\\/[^/]*$/, '') ?? ''\n const normalizedFromDir = normalizedRoutePrefix && fromDir.startsWith(`${normalizedRoutePrefix}/`)\n ? fromDir.slice(normalizedRoutePrefix.length + 1)\n : fromDir\n return VIRTUAL_PREFIX + resolveRelativePath(normalizedFromDir, normalizedSpecPath)\n}\n\n/**\n * 为绝对 specPath 生成带 locale 前缀的候选模块 ID。\n *\n * 所有 locale 的 spec 都注册在 `virtual:clarify-page/<locale>/...` 下,\n * 因此绝对路径(如 `/api`)需要显式注入 locale 前缀才能命中。\n * 相对路径会因为当前路由已含 locale 前缀而自动解析到正确的 spec。\n */\nfunction localizeSpecModuleId(moduleId: string, specPath: string, locale: string | undefined, _defaultLocale: string | undefined): string | undefined {\n if (!locale) return undefined\n // 仅处理绝对路径;相对路径已经基于含 locale 前缀的当前路由解析。\n if (!specPath.startsWith('/') || specPath.startsWith(VIRTUAL_PREFIX)) return undefined\n const rest = moduleId.slice(VIRTUAL_PREFIX.length)\n if (rest.startsWith(`${locale}/`) || rest === locale) return undefined\n return `${VIRTUAL_PREFIX}${locale}/${rest}`\n}\n\nexport function useOpenApiSpec(spec?: OpenAPISpec, specPath?: string): OpenAPISpec | null {\n const config = useConfig()\n const locale = useLocale()\n const specs = useOpenApis()\n const location = useLocation()\n\n if (spec) return spec\n if (!specPath) return null\n\n const normalized = normalizeSpecPath(specPath, location.pathname, config.routePrefix)\n const localized = localizeSpecModuleId(normalized, specPath, locale, config.i18n?.defaultLocale)\n\n if (localized && specs[localized]) return specs[localized]\n return specs[normalized] ?? null\n}\n","import type { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'\n\nimport type { OpenApiRecord } from '../types'\n\nexport type OpenAPISpec = OpenAPIV3.Document | OpenAPIV3_1.Document\nexport type OpenAPIOperation = OpenAPIV3.OperationObject | OpenAPIV3_1.OperationObject\n\nexport const OPENAPI_HTTP_METHODS = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace'] as const\n\nexport type OpenAPIHttpMethod = typeof OPENAPI_HTTP_METHODS[number]\n\nexport function isOpenAPIHttpMethod(method: string): method is OpenAPIHttpMethod {\n return (OPENAPI_HTTP_METHODS as readonly string[]).includes(method.toLowerCase())\n}\n\nfunction isRecord(value: unknown): value is OpenApiRecord {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction resolveOpenApiRef(spec: OpenAPISpec, ref: string): unknown {\n if (!ref.startsWith('#/')) return undefined\n\n return ref\n .slice(2)\n .split('/')\n .map((part) => part.replace(/~1/g, '/').replace(/~0/g, '~'))\n .reduce<unknown>((current, part) => (isRecord(current) ? current[part] : undefined), spec)\n}\n\nfunction getPathItem(spec: OpenAPISpec, path: string): OpenApiRecord | undefined {\n const pathItem = spec.paths?.[path]\n const resolved = isRecord(pathItem) && typeof pathItem.$ref === 'string' ? resolveOpenApiRef(spec, pathItem.$ref) : pathItem\n return isRecord(resolved) ? resolved : undefined\n}\n\nexport function getOpenApiOperation(spec: OpenAPISpec, path: string, method: string): OpenAPIOperation | undefined {\n if (!isOpenAPIHttpMethod(method)) return undefined\n return getPathItem(spec, path)?.[method.toLowerCase() as OpenAPIHttpMethod] as OpenAPIOperation | undefined\n}\n\nexport function listOpenApiOperations(spec: OpenAPISpec): Array<{ path: string; method: OpenAPIHttpMethod; operation: OpenAPIOperation }> {\n const paths = spec.paths ?? {}\n const operations: Array<{ path: string; method: OpenAPIHttpMethod; operation: OpenAPIOperation }> = []\n\n for (const path of Object.keys(paths)) {\n const pathItem = getPathItem(spec, path)\n if (!pathItem) continue\n for (const method of OPENAPI_HTTP_METHODS) {\n const operation = pathItem[method]\n if (operation) operations.push({ path, method, operation: operation as OpenAPIOperation })\n }\n }\n\n return operations\n}\n","import type { ReactNode } from 'react'\n\nimport { PageTitleActions } from '../app/PageActions'\nimport { Prose } from '../components/Prose'\nimport { useBuiltInText } from '../core/i18n'\nimport { Markdown } from '../mdx/Markdown'\n\nimport { OpenApiOperation as OpenApiOperationComponent } from './components/OpenApiOperation'\nimport { useOpenApiSpec } from './lib/spec-path'\nimport { getOpenApiOperation, listOpenApiOperations } from './lib/utils'\nimport type { OpenAPISpec } from './lib/utils'\n\ntype OpenApiPathsProps = { spec: OpenAPISpec; tagFilter?: string[] }\n\ntype OpenApiHeaderProps = { spec: OpenAPISpec }\n\ntype WarningBoxProps = {\n children: ReactNode\n tone?: 'amber' | 'red'\n}\n\nexport type OpenApiDocumentProps = {\n spec?: OpenAPISpec\n specPath?: string\n tagFilter?: string[]\n}\n\nexport type OpenApiRouteData = {\n spec: OpenAPISpec\n tagFilter?: string[]\n}\n\ntype OpenApiOperationWithSpecProps = {\n spec: OpenAPISpec\n path: string\n method: string\n}\n\nexport type OpenApiOperationProps = {\n specPath: string\n path: string\n method: string\n}\n\nfunction OpenApiHeader(arg0: OpenApiHeaderProps): ReactNode {\n const { spec } = arg0\n\n const t = useBuiltInText()\n return (\n <header className=\"clarify-openapi-header mb-16 border-b border-(--clarify-theme-tokens-colors-border) pb-8\">\n <p className=\"mb-3 text-xs/6 font-medium tracking-widest text-(--clarify-ui-accent-text) uppercase\">\n {t('openapi.openApiReference')}\n </p>\n <div className=\"clarify-page-title-row flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n <h1 className=\"clarify-page-title min-w-0 flex-1\">{spec.info?.title ?? t('openapi.apiDocumentation')}</h1>\n <PageTitleActions />\n </div>\n {spec.info?.description ? <Markdown className=\"lead mt-4 *:first:mt-0 *:last:mb-0\">{spec.info.description}</Markdown> : null}\n {spec.info?.version ? <p className=\"mt-4 text-sm text-(--clarify-ui-text-faint)\">{t('openapi.version', { version: spec.info.version })}</p> : null}\n </header>\n )\n}\n\nfunction operationMatchesTags(operationTags: string[] | undefined, filterTags: string[] | undefined): boolean {\n if (!filterTags?.length) return true\n return operationTags?.some(tag => filterTags.includes(tag)) ?? false\n}\n\nfunction OpenApiPaths(arg0: OpenApiPathsProps): ReactNode {\n const { spec, tagFilter } = arg0\n\n const entries = listOpenApiOperations(spec)\n .filter(({ operation }) => operationMatchesTags(operation.tags, tagFilter))\n .map(({ path, method, operation }) => ({\n path,\n method: method.toUpperCase(),\n operation,\n }))\n\n return (\n <div className=\"clarify-api-endpoints divide-y divide-zinc-200/70 dark:divide-white/10\">\n {entries.map(({ path, method, operation }) => (\n <OpenApiOperationComponent key={`${method}-${path}`} spec={spec} path={path} method={method} operation={operation} />\n ))}\n </div>\n )\n}\n\nfunction WarningBox(arg0: WarningBoxProps): ReactNode {\n const { children, tone = 'amber' } = arg0\n\n const classes = tone === 'red'\n ? 'rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-700 dark:border-red-500/30 dark:bg-red-500/10 dark:text-red-200'\n : 'rounded-lg border border-amber-200 bg-amber-50 p-4 text-sm text-amber-700 dark:border-amber-500/30 dark:bg-amber-500/10 dark:text-amber-200'\n\n return <div className={`clarify-warning ${classes}`}>{children}</div>\n}\n\nexport function OpenApiDocument(arg0: OpenApiDocumentProps): ReactNode {\n const { spec, specPath, tagFilter } = arg0\n const t = useBuiltInText()\n const resolved = useOpenApiSpec(spec, specPath)\n\n if (!resolved) {\n return <WarningBox>{t('openapi.specNotFound', { specPath: specPath ?? t('openapi.specPathMissing') })}</WarningBox>\n }\n\n return (\n <article className=\"clarify-openapi-page flex h-full flex-col pt-16 pb-10\">\n <Prose className=\"flex-auto\">\n <OpenApiHeader spec={resolved} />\n <OpenApiPaths spec={resolved} tagFilter={tagFilter} />\n </Prose>\n </article>\n )\n}\n\nfunction OpenApiOperationWithSpec(arg0: OpenApiOperationWithSpecProps): ReactNode {\n const { spec, path, method } = arg0\n const t = useBuiltInText()\n const op = getOpenApiOperation(spec, path, method)\n\n if (!op) {\n return <WarningBox tone=\"red\">{t('openapi.endpointNotFound', { endpoint: `${method.toUpperCase()} ${path}` })}</WarningBox>\n }\n\n const normalizedMethod = method.toUpperCase()\n return <OpenApiOperationComponent key={`${normalizedMethod}-${path}`} spec={spec} path={path} method={normalizedMethod} operation={op} />\n}\n\nexport function OpenApiOperation(arg0: OpenApiOperationProps): ReactNode {\n const { specPath, path, method } = arg0\n const t = useBuiltInText()\n const spec = useOpenApiSpec(undefined, specPath)\n\n if (!spec) {\n return <WarningBox>{t('openapi.specNotFound', { specPath })}</WarningBox>\n }\n\n return <OpenApiOperationWithSpec spec={spec} path={path} method={method} />\n}\n\nexport function createOpenApiRouteComponent(data: OpenApiRouteData) {\n return function OpenApiRoutePage() {\n return <OpenApiDocument spec={data.spec} tagFilter={data.tagFilter} />\n }\n}\n","import { Collapse } from '../components/Collapse'\nimport { Mermaid } from '../components/Mermaid'\nimport { OpenApiDocument, OpenApiOperation } from '../openapi'\n\nimport { Markdown } from './Markdown'\nimport * as mdxPrimitives from './primitives'\n\nconst builtInMDXComponents = {\n ...mdxPrimitives,\n Markdown,\n Collapse,\n Mermaid,\n}\n\nconst builtInOpenAPIComponents = {\n OpenApiDocument,\n OpenApiOperation,\n}\n\nexport function useMDXComponents(components: Record<string, unknown> = {}) {\n return {\n ...components,\n ...builtInMDXComponents,\n ...builtInOpenAPIComponents,\n }\n}\n","import type { ReactNode } from 'react'\n\nimport { Prose } from '../components/Prose'\n\nexport type DocShellProps = {\n title: string\n subtitle?: string\n children: ReactNode\n}\n\nexport function DocShell(arg0: DocShellProps) {\n const { title, subtitle, children } = arg0\n\n return (\n <main className=\"clarify-doc-shell min-h-screen bg-(--clarify-theme-tokens-colors-background) px-6 py-10 text-(--clarify-theme-tokens-colors-foreground) md:px-10\">\n <div className=\"mx-auto max-w-6xl\">\n <header className=\"mb-10\">\n <h1 className=\"text-3xl font-bold tracking-tight md:text-5xl\">{title}</h1>\n {subtitle ? <p className=\"mt-3 max-w-2xl text-(--clarify-ui-text-soft)\">{subtitle}</p> : null}\n </header>\n <Prose>{children}</Prose>\n </div>\n </main>\n )\n}\n"],"mappings":"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"}
package/output/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { AppShell } from './app/AppShell';
2
2
  import { BuiltWithClarify } from './app/BuiltWithClarify';
3
+ import { createContentDiagnosticComponent, ContentDiagnostic } from './app/ContentDiagnostic';
3
4
  import { PageBanner } from './app/PageBanner';
4
5
  import { PageFooter } from './app/PageFooter';
5
6
  import { SectionProvider, useSectionStore, Section } from './app/SectionProvider';
@@ -9,7 +10,7 @@ import { useMDXComponents } from './mdx/components';
9
10
  import { DocShell } from './mdx/DocShell';
10
11
  import { Markdown } from './mdx/Markdown';
11
12
  import { markdownRemarkPlugins } from './mdx/remark';
12
- import { OpenApiDocument, OpenApiOperation } from './openapi';
13
+ import { OpenApiDocument, OpenApiOperation, createOpenApiRouteComponent } from './openapi';
13
14
  import { render } from './runtime/render';
14
15
  import { SlotProvider, RuntimeSlot, RuntimeSlotsProvider, useSlot } from './slots';
15
16
  import { applyThemeVariables, themeEditorPresets, ThemeEditor } from './theme/ThemeEditor';
@@ -18,11 +19,12 @@ import { ThemeToggle } from './theme/ThemeToggle';
18
19
  import { themePresets, themeBootstrapScript } from './theme/variables';
19
20
  import { Config, RouteItem, RenderOptions, ServerRenderOptions } from './types';
20
21
  import { remToPx } from './utils/remToPx';
21
- export type { OpenApiOperationProps, OpenApiDocumentProps, OpenAPIOperation, OpenAPISpec } from './openapi';
22
+ export type { OpenApiOperationProps, OpenApiDocumentProps, OpenAPIOperation, OpenAPISpec, OpenApiRouteData } from './openapi';
22
23
  export type { ThemeEditorProps } from './theme/ThemeEditor';
24
+ export type { ContentDiagnostic };
23
25
  export type { Config, RouteItem, RenderOptions, ServerRenderOptions, Section };
24
26
  export type { RuntimeSlotEntry, RuntimeSlots, UISlotRegistration, UISlotName, SlotContext } from './slots';
25
- export { AppShell, render, OpenApisContext, useOpenApis, BuiltWithClarify, PageBanner, PageFooter, ThemeProvider, ThemeToggle, ThemeEditor, useTheme, SectionProvider, useSectionStore, remToPx, applyThemeVariables, themeEditorPresets, themePresets, themeBootstrapScript };
27
+ export { AppShell, render, OpenApisContext, useOpenApis, BuiltWithClarify, PageBanner, PageFooter, ThemeProvider, ThemeToggle, ThemeEditor, useTheme, SectionProvider, useSectionStore, remToPx, applyThemeVariables, themeEditorPresets, themePresets, themeBootstrapScript, createContentDiagnosticComponent, createOpenApiRouteComponent };
26
28
  export { Button, Callout, Card, CardGroup, Code, CodeGroup, Collapse, Pre, Prose, Heading, Logo, Mermaid, GridPattern, HeroPattern, Feedback, Tag, WebFrame };
27
29
  export { DocShell, Markdown, useMDXComponents, markdownRemarkPlugins };
28
30
  export { SlotProvider, RuntimeSlot, RuntimeSlotsProvider, useSlot };
package/output/index.js CHANGED
@@ -1,10 +1,39 @@
1
- import { A as Button, C as Code, D as Card, E as Mermaid, O as CardGroup, S as Collapse, T as Pre, _ as HeroPattern, b as Tag, f as Markdown, g as GridPattern, h as Prose, k as Callout, m as WebFrame, n as OpenApiOperation$1, p as primitives_exports, v as Logo, w as CodeGroup, x as Feedback, y as Heading } from "./OpenApiOperation-C9xyRo5a.js";
2
- import { A as OpenApisContext, D as useBuiltInText, M as useLocale, N as useOpenApis, a as SectionProvider, h as useTheme, j as useConfig, m as ThemeProvider, n as PageTitleActions, o as useSectionStore, p as ThemeToggle, s as remToPx } from "./PageActions-B_tSec1f.js";
3
- import { a as themeBootstrapScript, c as AppShell, d as BuiltWithClarify, f as RuntimeSlot, h as useSlot, i as themeEditorPresets, l as PageFooter, m as SlotProvider, n as ThemeEditor, o as themePresets, p as RuntimeSlotsProvider, r as applyThemeVariables, u as PageBanner } from "./ClarifyShell-BQ29N8P5.js";
1
+ import { A as Button, C as Code, D as Card, E as Mermaid, O as CardGroup, S as Collapse, T as Pre, _ as HeroPattern, b as Tag, f as Markdown, g as GridPattern, h as Prose, k as Callout, m as WebFrame, n as OpenApiOperation$1, p as primitives_exports, v as Logo, w as CodeGroup, x as Feedback, y as Heading } from "./OpenApiOperation-Dhlz3JSx.js";
2
+ import { A as OpenApisContext, D as useBuiltInText, N as useLocale, P as useOpenApis, a as SectionProvider, h as useTheme, j as useConfig, m as ThemeProvider, n as PageTitleActions, o as useSectionStore, p as ThemeToggle, s as remToPx } from "./PageActions-D0PA8Zv5.js";
3
+ import { a as themeBootstrapScript, c as AppShell, d as RenderErrorPanel, f as BuiltWithClarify, g as useSlot, h as SlotProvider, i as themeEditorPresets, l as PageFooter, m as RuntimeSlotsProvider, n as ThemeEditor, o as themePresets, p as RuntimeSlot, r as applyThemeVariables, u as PageBanner } from "./ClarifyShell-D2P0iZ_m.js";
4
4
  import { t as markdownRemarkPlugins } from "./remark-Dd2WU50s.js";
5
- import { t as render } from "./render-CEWLJSmt.js";
5
+ import { t as render } from "./render-CwSsfrs7.js";
6
6
  import { useLocation } from "react-router-dom";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
+ //#region source/app/ContentDiagnostic.tsx
9
+ function ContentDiagnosticPanel(params) {
10
+ const { data } = params;
11
+ const typeLabel = data.kind === "mdx" ? "MDX" : data.kind === "openapi" ? "OpenAPI" : "Route";
12
+ const detailsLabel = data.kind === "mdx" ? "Why it happened" : "Details";
13
+ return /* @__PURE__ */ jsx(RenderErrorPanel, {
14
+ title: data.title,
15
+ description: data.message,
16
+ titleId: "clarify-content-diagnostic-title",
17
+ metadata: [{
18
+ label: "File",
19
+ value: data.filePath ?? "Unknown"
20
+ }, {
21
+ label: "Type",
22
+ value: typeLabel
23
+ }],
24
+ detailsLabel,
25
+ detailsContent: data.details ? /* @__PURE__ */ jsx("pre", {
26
+ className: "max-h-(--clarify-error-details-max-height) overflow-auto whitespace-pre-wrap wrap-break-word font-mono",
27
+ children: data.details
28
+ }) : null
29
+ });
30
+ }
31
+ function createContentDiagnosticComponent(data) {
32
+ return function ContentDiagnosticComponent() {
33
+ return /* @__PURE__ */ jsx(ContentDiagnosticPanel, { data });
34
+ };
35
+ }
36
+ //#endregion
8
37
  //#region source/openapi/lib/spec-path.ts
9
38
  var VIRTUAL_PREFIX = "virtual:clarify-page/";
10
39
  function resolveRelativePath(fromDir, to) {
@@ -196,6 +225,14 @@ function OpenApiOperation(arg0) {
196
225
  method
197
226
  });
198
227
  }
228
+ function createOpenApiRouteComponent(data) {
229
+ return function OpenApiRoutePage() {
230
+ return /* @__PURE__ */ jsx(OpenApiDocument, {
231
+ spec: data.spec,
232
+ tagFilter: data.tagFilter
233
+ });
234
+ };
235
+ }
199
236
  //#endregion
200
237
  //#region source/mdx/components.ts
201
238
  var builtInMDXComponents = {
@@ -237,6 +274,6 @@ function DocShell(arg0) {
237
274
  });
238
275
  }
239
276
  //#endregion
240
- export { AppShell, BuiltWithClarify, Button, Callout, Card, CardGroup, Code, CodeGroup, Collapse, DocShell, Feedback, GridPattern, Heading, HeroPattern, Logo, Markdown, Mermaid, OpenApiDocument, OpenApiOperation, OpenApisContext, PageBanner, PageFooter, Pre, Prose, RuntimeSlot, RuntimeSlotsProvider, SectionProvider, SlotProvider, Tag, ThemeEditor, ThemeProvider, ThemeToggle, WebFrame, applyThemeVariables, markdownRemarkPlugins, remToPx, render, themeBootstrapScript, themeEditorPresets, themePresets, useMDXComponents, useOpenApis, useSectionStore, useSlot, useTheme };
277
+ export { AppShell, BuiltWithClarify, Button, Callout, Card, CardGroup, Code, CodeGroup, Collapse, DocShell, Feedback, GridPattern, Heading, HeroPattern, Logo, Markdown, Mermaid, OpenApiDocument, OpenApiOperation, OpenApisContext, PageBanner, PageFooter, Pre, Prose, RuntimeSlot, RuntimeSlotsProvider, SectionProvider, SlotProvider, Tag, ThemeEditor, ThemeProvider, ThemeToggle, WebFrame, applyThemeVariables, createContentDiagnosticComponent, createOpenApiRouteComponent, markdownRemarkPlugins, remToPx, render, themeBootstrapScript, themeEditorPresets, themePresets, useMDXComponents, useOpenApis, useSectionStore, useSlot, useTheme };
241
278
 
242
279
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../source/openapi/lib/spec-path.ts","../source/openapi/lib/utils.ts","../source/openapi/entry.tsx","../source/mdx/components.ts","../source/mdx/DocShell.tsx"],"sourcesContent":["import { useLocation } from 'react-router-dom'\n\nimport { useConfig, useLocale, useOpenApis } from '../../core/context'\n\nimport type { OpenAPISpec } from './utils'\n\nconst VIRTUAL_PREFIX = 'virtual:clarify-page/'\n\nfunction resolveRelativePath(fromDir: string, to: string): string {\n const parts = (fromDir + '/' + to).split('/').filter(Boolean)\n const stack: string[] = []\n for (const part of parts) {\n if (part === '..') {\n stack.pop()\n } else if (part !== '.') {\n stack.push(part)\n }\n }\n return stack.join('/')\n}\n\nfunction normalizeSpecPath(specPath: string, currentRoutePath?: string, routePrefix = ''): string {\n if (specPath.startsWith(VIRTUAL_PREFIX)) return specPath\n\n const normalizedRoutePrefix = routePrefix.replace(/^\\/+|\\/+$/g, '')\n const normalizedSpecPath = specPath.startsWith('/') && normalizedRoutePrefix && specPath.slice(1).startsWith(`${normalizedRoutePrefix}/`)\n ? '/' + specPath.slice(normalizedRoutePrefix.length + 2)\n : specPath\n\n if (normalizedSpecPath.startsWith('/')) {\n return VIRTUAL_PREFIX + normalizedSpecPath.replace(/^\\//, '')\n }\n const fromDir = currentRoutePath === '/' ? '' : currentRoutePath?.replace(/^\\//, '').replace(/\\/[^/]*$/, '') ?? ''\n const normalizedFromDir = normalizedRoutePrefix && fromDir.startsWith(`${normalizedRoutePrefix}/`)\n ? fromDir.slice(normalizedRoutePrefix.length + 1)\n : fromDir\n return VIRTUAL_PREFIX + resolveRelativePath(normalizedFromDir, normalizedSpecPath)\n}\n\n/**\n * 为绝对 specPath 生成带 locale 前缀的候选模块 ID。\n *\n * 所有 locale 的 spec 都注册在 `virtual:clarify-page/<locale>/...` 下,\n * 因此绝对路径(如 `/api`)需要显式注入 locale 前缀才能命中。\n * 相对路径会因为当前路由已含 locale 前缀而自动解析到正确的 spec。\n */\nfunction localizeSpecModuleId(moduleId: string, specPath: string, locale: string | undefined, _defaultLocale: string | undefined): string | undefined {\n if (!locale) return undefined\n // 仅处理绝对路径;相对路径已经基于含 locale 前缀的当前路由解析。\n if (!specPath.startsWith('/') || specPath.startsWith(VIRTUAL_PREFIX)) return undefined\n const rest = moduleId.slice(VIRTUAL_PREFIX.length)\n if (rest.startsWith(`${locale}/`) || rest === locale) return undefined\n return `${VIRTUAL_PREFIX}${locale}/${rest}`\n}\n\nexport function useOpenApiSpec(spec?: OpenAPISpec, specPath?: string): OpenAPISpec | null {\n const config = useConfig()\n const locale = useLocale()\n const specs = useOpenApis()\n const location = useLocation()\n\n if (spec) return spec\n if (!specPath) return null\n\n const normalized = normalizeSpecPath(specPath, location.pathname, config.routePrefix)\n const localized = localizeSpecModuleId(normalized, specPath, locale, config.i18n?.defaultLocale)\n\n if (localized && specs[localized]) return specs[localized]\n return specs[normalized] ?? null\n}\n","import type { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'\n\nimport type { OpenApiRecord } from '../types'\n\nexport type OpenAPISpec = OpenAPIV3.Document | OpenAPIV3_1.Document\nexport type OpenAPIOperation = OpenAPIV3.OperationObject | OpenAPIV3_1.OperationObject\n\nexport const OPENAPI_HTTP_METHODS = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace'] as const\n\nexport type OpenAPIHttpMethod = typeof OPENAPI_HTTP_METHODS[number]\n\nexport function isOpenAPIHttpMethod(method: string): method is OpenAPIHttpMethod {\n return (OPENAPI_HTTP_METHODS as readonly string[]).includes(method.toLowerCase())\n}\n\nfunction isRecord(value: unknown): value is OpenApiRecord {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction resolveOpenApiRef(spec: OpenAPISpec, ref: string): unknown {\n if (!ref.startsWith('#/')) return undefined\n\n return ref\n .slice(2)\n .split('/')\n .map((part) => part.replace(/~1/g, '/').replace(/~0/g, '~'))\n .reduce<unknown>((current, part) => (isRecord(current) ? current[part] : undefined), spec)\n}\n\nfunction getPathItem(spec: OpenAPISpec, path: string): OpenApiRecord | undefined {\n const pathItem = spec.paths?.[path]\n const resolved = isRecord(pathItem) && typeof pathItem.$ref === 'string' ? resolveOpenApiRef(spec, pathItem.$ref) : pathItem\n return isRecord(resolved) ? resolved : undefined\n}\n\nexport function getOpenApiOperation(spec: OpenAPISpec, path: string, method: string): OpenAPIOperation | undefined {\n if (!isOpenAPIHttpMethod(method)) return undefined\n return getPathItem(spec, path)?.[method.toLowerCase() as OpenAPIHttpMethod] as OpenAPIOperation | undefined\n}\n\nexport function listOpenApiOperations(spec: OpenAPISpec): Array<{ path: string; method: OpenAPIHttpMethod; operation: OpenAPIOperation }> {\n const paths = spec.paths ?? {}\n const operations: Array<{ path: string; method: OpenAPIHttpMethod; operation: OpenAPIOperation }> = []\n\n for (const path of Object.keys(paths)) {\n const pathItem = getPathItem(spec, path)\n if (!pathItem) continue\n for (const method of OPENAPI_HTTP_METHODS) {\n const operation = pathItem[method]\n if (operation) operations.push({ path, method, operation: operation as OpenAPIOperation })\n }\n }\n\n return operations\n}\n","import type { ReactNode } from 'react'\n\nimport { PageTitleActions } from '../app/PageActions'\nimport { Prose } from '../components/Prose'\nimport { useBuiltInText } from '../core/i18n'\nimport { Markdown } from '../mdx/Markdown'\n\nimport { OpenApiOperation as OpenApiOperationComponent } from './components/OpenApiOperation'\nimport { useOpenApiSpec } from './lib/spec-path'\nimport { getOpenApiOperation, listOpenApiOperations } from './lib/utils'\nimport type { OpenAPISpec } from './lib/utils'\n\ntype OpenApiPathsProps = { spec: OpenAPISpec; tagFilter?: string[] }\n\ntype OpenApiHeaderProps = { spec: OpenAPISpec }\n\ntype WarningBoxProps = {\n children: ReactNode\n tone?: 'amber' | 'red'\n}\n\nexport type OpenApiDocumentProps = {\n spec?: OpenAPISpec\n specPath?: string\n tagFilter?: string[]\n}\n\ntype OpenApiOperationWithSpecProps = {\n spec: OpenAPISpec\n path: string\n method: string\n}\n\nexport type OpenApiOperationProps = {\n specPath: string\n path: string\n method: string\n}\n\nfunction OpenApiHeader(arg0: OpenApiHeaderProps): ReactNode {\n const { spec } = arg0\n\n const t = useBuiltInText()\n return (\n <header className=\"clarify-openapi-header mb-16 border-b border-(--clarify-theme-tokens-colors-border) pb-8\">\n <p className=\"mb-3 text-xs/6 font-medium tracking-widest text-(--clarify-ui-accent-text) uppercase\">\n {t('openapi.openApiReference')}\n </p>\n <div className=\"clarify-page-title-row flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n <h1 className=\"clarify-page-title min-w-0 flex-1\">{spec.info?.title ?? t('openapi.apiDocumentation')}</h1>\n <PageTitleActions />\n </div>\n {spec.info?.description ? <Markdown className=\"lead mt-4 *:first:mt-0 *:last:mb-0\">{spec.info.description}</Markdown> : null}\n {spec.info?.version ? <p className=\"mt-4 text-sm text-(--clarify-ui-text-faint)\">{t('openapi.version', { version: spec.info.version })}</p> : null}\n </header>\n )\n}\n\nfunction operationMatchesTags(operationTags: string[] | undefined, filterTags: string[] | undefined): boolean {\n if (!filterTags?.length) return true\n return operationTags?.some(tag => filterTags.includes(tag)) ?? false\n}\n\nfunction OpenApiPaths(arg0: OpenApiPathsProps): ReactNode {\n const { spec, tagFilter } = arg0\n\n const entries = listOpenApiOperations(spec)\n .filter(({ operation }) => operationMatchesTags(operation.tags, tagFilter))\n .map(({ path, method, operation }) => ({\n path,\n method: method.toUpperCase(),\n operation,\n }))\n\n return (\n <div className=\"clarify-api-endpoints divide-y divide-zinc-200/70 dark:divide-white/10\">\n {entries.map(({ path, method, operation }) => (\n <OpenApiOperationComponent key={`${method}-${path}`} spec={spec} path={path} method={method} operation={operation} />\n ))}\n </div>\n )\n}\n\nfunction WarningBox(arg0: WarningBoxProps): ReactNode {\n const { children, tone = 'amber' } = arg0\n\n const classes = tone === 'red'\n ? 'rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-700 dark:border-red-500/30 dark:bg-red-500/10 dark:text-red-200'\n : 'rounded-lg border border-amber-200 bg-amber-50 p-4 text-sm text-amber-700 dark:border-amber-500/30 dark:bg-amber-500/10 dark:text-amber-200'\n\n return <div className={`clarify-warning ${classes}`}>{children}</div>\n}\n\nexport function OpenApiDocument(arg0: OpenApiDocumentProps): ReactNode {\n const { spec, specPath, tagFilter } = arg0\n const t = useBuiltInText()\n const resolved = useOpenApiSpec(spec, specPath)\n\n if (!resolved) {\n return <WarningBox>{t('openapi.specNotFound', { specPath: specPath ?? t('openapi.specPathMissing') })}</WarningBox>\n }\n\n return (\n <article className=\"clarify-openapi-page flex h-full flex-col pt-16 pb-10\">\n <Prose className=\"flex-auto\">\n <OpenApiHeader spec={resolved} />\n <OpenApiPaths spec={resolved} tagFilter={tagFilter} />\n </Prose>\n </article>\n )\n}\n\nfunction OpenApiOperationWithSpec(arg0: OpenApiOperationWithSpecProps): ReactNode {\n const { spec, path, method } = arg0\n const t = useBuiltInText()\n const op = getOpenApiOperation(spec, path, method)\n\n if (!op) {\n return <WarningBox tone=\"red\">{t('openapi.endpointNotFound', { endpoint: `${method.toUpperCase()} ${path}` })}</WarningBox>\n }\n\n const normalizedMethod = method.toUpperCase()\n return <OpenApiOperationComponent key={`${normalizedMethod}-${path}`} spec={spec} path={path} method={normalizedMethod} operation={op} />\n}\n\nexport function OpenApiOperation(arg0: OpenApiOperationProps): ReactNode {\n const { specPath, path, method } = arg0\n const t = useBuiltInText()\n const spec = useOpenApiSpec(undefined, specPath)\n\n if (!spec) {\n return <WarningBox>{t('openapi.specNotFound', { specPath })}</WarningBox>\n }\n\n return <OpenApiOperationWithSpec spec={spec} path={path} method={method} />\n}\n","import { Collapse } from '../components/Collapse'\nimport { Mermaid } from '../components/Mermaid'\nimport { OpenApiDocument, OpenApiOperation } from '../openapi'\n\nimport { Markdown } from './Markdown'\nimport * as mdxPrimitives from './primitives'\n\nconst builtInMDXComponents = {\n ...mdxPrimitives,\n Markdown,\n Collapse,\n Mermaid,\n}\n\nconst builtInOpenAPIComponents = {\n OpenApiDocument,\n OpenApiOperation,\n}\n\nexport function useMDXComponents(components: Record<string, unknown> = {}) {\n return {\n ...components,\n ...builtInMDXComponents,\n ...builtInOpenAPIComponents,\n }\n}\n","import type { ReactNode } from 'react'\n\nimport { Prose } from '../components/Prose'\n\nexport type DocShellProps = {\n title: string\n subtitle?: string\n children: ReactNode\n}\n\nexport function DocShell(arg0: DocShellProps) {\n const { title, subtitle, children } = arg0\n\n return (\n <main className=\"clarify-doc-shell min-h-screen bg-(--clarify-theme-tokens-colors-background) px-6 py-10 text-(--clarify-theme-tokens-colors-foreground) md:px-10\">\n <div className=\"mx-auto max-w-6xl\">\n <header className=\"mb-10\">\n <h1 className=\"text-3xl font-bold tracking-tight md:text-5xl\">{title}</h1>\n {subtitle ? <p className=\"mt-3 max-w-2xl text-(--clarify-ui-text-soft)\">{subtitle}</p> : null}\n </header>\n <Prose>{children}</Prose>\n </div>\n </main>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../source/app/ContentDiagnostic.tsx","../source/openapi/lib/spec-path.ts","../source/openapi/lib/utils.ts","../source/openapi/entry.tsx","../source/mdx/components.ts","../source/mdx/DocShell.tsx"],"sourcesContent":["import type { ComponentType } from 'react'\n\nimport { RenderErrorPanel } from './RenderErrorPanel'\n\nexport type ContentDiagnostic = {\n kind: string\n title: string\n message: string\n details?: string\n filePath?: string\n}\n\ntype ContentDiagnosticPanelProps = {\n data: ContentDiagnostic\n}\n\nfunction ContentDiagnosticPanel(params: ContentDiagnosticPanelProps) {\n const { data } = params\n const typeLabel = data.kind === 'mdx' ? 'MDX' : data.kind === 'openapi' ? 'OpenAPI' : 'Route'\n const detailsLabel = data.kind === 'mdx' ? 'Why it happened' : 'Details'\n const pathLabel = 'File'\n\n return (\n <RenderErrorPanel\n title={data.title}\n description={data.message}\n titleId=\"clarify-content-diagnostic-title\"\n metadata={[\n { label: pathLabel, value: data.filePath ?? 'Unknown' },\n { label: 'Type', value: typeLabel },\n ]}\n detailsLabel={detailsLabel}\n detailsContent={data.details ? (\n <pre className=\"max-h-(--clarify-error-details-max-height) overflow-auto whitespace-pre-wrap wrap-break-word font-mono\">\n {data.details}\n </pre>\n ) : null}\n />\n )\n}\n\nexport function createContentDiagnosticComponent(data: ContentDiagnostic): ComponentType {\n return function ContentDiagnosticComponent() {\n return <ContentDiagnosticPanel data={data} />\n }\n}\n","import { useLocation } from 'react-router-dom'\n\nimport { useConfig, useLocale, useOpenApis } from '../../core/context'\n\nimport type { OpenAPISpec } from './utils'\n\nconst VIRTUAL_PREFIX = 'virtual:clarify-page/'\n\nfunction resolveRelativePath(fromDir: string, to: string): string {\n const parts = (fromDir + '/' + to).split('/').filter(Boolean)\n const stack: string[] = []\n for (const part of parts) {\n if (part === '..') {\n stack.pop()\n } else if (part !== '.') {\n stack.push(part)\n }\n }\n return stack.join('/')\n}\n\nfunction normalizeSpecPath(specPath: string, currentRoutePath?: string, routePrefix = ''): string {\n if (specPath.startsWith(VIRTUAL_PREFIX)) return specPath\n\n const normalizedRoutePrefix = routePrefix.replace(/^\\/+|\\/+$/g, '')\n const normalizedSpecPath = specPath.startsWith('/') && normalizedRoutePrefix && specPath.slice(1).startsWith(`${normalizedRoutePrefix}/`)\n ? '/' + specPath.slice(normalizedRoutePrefix.length + 2)\n : specPath\n\n if (normalizedSpecPath.startsWith('/')) {\n return VIRTUAL_PREFIX + normalizedSpecPath.replace(/^\\//, '')\n }\n const fromDir = currentRoutePath === '/' ? '' : currentRoutePath?.replace(/^\\//, '').replace(/\\/[^/]*$/, '') ?? ''\n const normalizedFromDir = normalizedRoutePrefix && fromDir.startsWith(`${normalizedRoutePrefix}/`)\n ? fromDir.slice(normalizedRoutePrefix.length + 1)\n : fromDir\n return VIRTUAL_PREFIX + resolveRelativePath(normalizedFromDir, normalizedSpecPath)\n}\n\n/**\n * 为绝对 specPath 生成带 locale 前缀的候选模块 ID。\n *\n * 所有 locale 的 spec 都注册在 `virtual:clarify-page/<locale>/...` 下,\n * 因此绝对路径(如 `/api`)需要显式注入 locale 前缀才能命中。\n * 相对路径会因为当前路由已含 locale 前缀而自动解析到正确的 spec。\n */\nfunction localizeSpecModuleId(moduleId: string, specPath: string, locale: string | undefined, _defaultLocale: string | undefined): string | undefined {\n if (!locale) return undefined\n // 仅处理绝对路径;相对路径已经基于含 locale 前缀的当前路由解析。\n if (!specPath.startsWith('/') || specPath.startsWith(VIRTUAL_PREFIX)) return undefined\n const rest = moduleId.slice(VIRTUAL_PREFIX.length)\n if (rest.startsWith(`${locale}/`) || rest === locale) return undefined\n return `${VIRTUAL_PREFIX}${locale}/${rest}`\n}\n\nexport function useOpenApiSpec(spec?: OpenAPISpec, specPath?: string): OpenAPISpec | null {\n const config = useConfig()\n const locale = useLocale()\n const specs = useOpenApis()\n const location = useLocation()\n\n if (spec) return spec\n if (!specPath) return null\n\n const normalized = normalizeSpecPath(specPath, location.pathname, config.routePrefix)\n const localized = localizeSpecModuleId(normalized, specPath, locale, config.i18n?.defaultLocale)\n\n if (localized && specs[localized]) return specs[localized]\n return specs[normalized] ?? null\n}\n","import type { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'\n\nimport type { OpenApiRecord } from '../types'\n\nexport type OpenAPISpec = OpenAPIV3.Document | OpenAPIV3_1.Document\nexport type OpenAPIOperation = OpenAPIV3.OperationObject | OpenAPIV3_1.OperationObject\n\nexport const OPENAPI_HTTP_METHODS = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace'] as const\n\nexport type OpenAPIHttpMethod = typeof OPENAPI_HTTP_METHODS[number]\n\nexport function isOpenAPIHttpMethod(method: string): method is OpenAPIHttpMethod {\n return (OPENAPI_HTTP_METHODS as readonly string[]).includes(method.toLowerCase())\n}\n\nfunction isRecord(value: unknown): value is OpenApiRecord {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction resolveOpenApiRef(spec: OpenAPISpec, ref: string): unknown {\n if (!ref.startsWith('#/')) return undefined\n\n return ref\n .slice(2)\n .split('/')\n .map((part) => part.replace(/~1/g, '/').replace(/~0/g, '~'))\n .reduce<unknown>((current, part) => (isRecord(current) ? current[part] : undefined), spec)\n}\n\nfunction getPathItem(spec: OpenAPISpec, path: string): OpenApiRecord | undefined {\n const pathItem = spec.paths?.[path]\n const resolved = isRecord(pathItem) && typeof pathItem.$ref === 'string' ? resolveOpenApiRef(spec, pathItem.$ref) : pathItem\n return isRecord(resolved) ? resolved : undefined\n}\n\nexport function getOpenApiOperation(spec: OpenAPISpec, path: string, method: string): OpenAPIOperation | undefined {\n if (!isOpenAPIHttpMethod(method)) return undefined\n return getPathItem(spec, path)?.[method.toLowerCase() as OpenAPIHttpMethod] as OpenAPIOperation | undefined\n}\n\nexport function listOpenApiOperations(spec: OpenAPISpec): Array<{ path: string; method: OpenAPIHttpMethod; operation: OpenAPIOperation }> {\n const paths = spec.paths ?? {}\n const operations: Array<{ path: string; method: OpenAPIHttpMethod; operation: OpenAPIOperation }> = []\n\n for (const path of Object.keys(paths)) {\n const pathItem = getPathItem(spec, path)\n if (!pathItem) continue\n for (const method of OPENAPI_HTTP_METHODS) {\n const operation = pathItem[method]\n if (operation) operations.push({ path, method, operation: operation as OpenAPIOperation })\n }\n }\n\n return operations\n}\n","import type { ReactNode } from 'react'\n\nimport { PageTitleActions } from '../app/PageActions'\nimport { Prose } from '../components/Prose'\nimport { useBuiltInText } from '../core/i18n'\nimport { Markdown } from '../mdx/Markdown'\n\nimport { OpenApiOperation as OpenApiOperationComponent } from './components/OpenApiOperation'\nimport { useOpenApiSpec } from './lib/spec-path'\nimport { getOpenApiOperation, listOpenApiOperations } from './lib/utils'\nimport type { OpenAPISpec } from './lib/utils'\n\ntype OpenApiPathsProps = { spec: OpenAPISpec; tagFilter?: string[] }\n\ntype OpenApiHeaderProps = { spec: OpenAPISpec }\n\ntype WarningBoxProps = {\n children: ReactNode\n tone?: 'amber' | 'red'\n}\n\nexport type OpenApiDocumentProps = {\n spec?: OpenAPISpec\n specPath?: string\n tagFilter?: string[]\n}\n\nexport type OpenApiRouteData = {\n spec: OpenAPISpec\n tagFilter?: string[]\n}\n\ntype OpenApiOperationWithSpecProps = {\n spec: OpenAPISpec\n path: string\n method: string\n}\n\nexport type OpenApiOperationProps = {\n specPath: string\n path: string\n method: string\n}\n\nfunction OpenApiHeader(arg0: OpenApiHeaderProps): ReactNode {\n const { spec } = arg0\n\n const t = useBuiltInText()\n return (\n <header className=\"clarify-openapi-header mb-16 border-b border-(--clarify-theme-tokens-colors-border) pb-8\">\n <p className=\"mb-3 text-xs/6 font-medium tracking-widest text-(--clarify-ui-accent-text) uppercase\">\n {t('openapi.openApiReference')}\n </p>\n <div className=\"clarify-page-title-row flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n <h1 className=\"clarify-page-title min-w-0 flex-1\">{spec.info?.title ?? t('openapi.apiDocumentation')}</h1>\n <PageTitleActions />\n </div>\n {spec.info?.description ? <Markdown className=\"lead mt-4 *:first:mt-0 *:last:mb-0\">{spec.info.description}</Markdown> : null}\n {spec.info?.version ? <p className=\"mt-4 text-sm text-(--clarify-ui-text-faint)\">{t('openapi.version', { version: spec.info.version })}</p> : null}\n </header>\n )\n}\n\nfunction operationMatchesTags(operationTags: string[] | undefined, filterTags: string[] | undefined): boolean {\n if (!filterTags?.length) return true\n return operationTags?.some(tag => filterTags.includes(tag)) ?? false\n}\n\nfunction OpenApiPaths(arg0: OpenApiPathsProps): ReactNode {\n const { spec, tagFilter } = arg0\n\n const entries = listOpenApiOperations(spec)\n .filter(({ operation }) => operationMatchesTags(operation.tags, tagFilter))\n .map(({ path, method, operation }) => ({\n path,\n method: method.toUpperCase(),\n operation,\n }))\n\n return (\n <div className=\"clarify-api-endpoints divide-y divide-zinc-200/70 dark:divide-white/10\">\n {entries.map(({ path, method, operation }) => (\n <OpenApiOperationComponent key={`${method}-${path}`} spec={spec} path={path} method={method} operation={operation} />\n ))}\n </div>\n )\n}\n\nfunction WarningBox(arg0: WarningBoxProps): ReactNode {\n const { children, tone = 'amber' } = arg0\n\n const classes = tone === 'red'\n ? 'rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-700 dark:border-red-500/30 dark:bg-red-500/10 dark:text-red-200'\n : 'rounded-lg border border-amber-200 bg-amber-50 p-4 text-sm text-amber-700 dark:border-amber-500/30 dark:bg-amber-500/10 dark:text-amber-200'\n\n return <div className={`clarify-warning ${classes}`}>{children}</div>\n}\n\nexport function OpenApiDocument(arg0: OpenApiDocumentProps): ReactNode {\n const { spec, specPath, tagFilter } = arg0\n const t = useBuiltInText()\n const resolved = useOpenApiSpec(spec, specPath)\n\n if (!resolved) {\n return <WarningBox>{t('openapi.specNotFound', { specPath: specPath ?? t('openapi.specPathMissing') })}</WarningBox>\n }\n\n return (\n <article className=\"clarify-openapi-page flex h-full flex-col pt-16 pb-10\">\n <Prose className=\"flex-auto\">\n <OpenApiHeader spec={resolved} />\n <OpenApiPaths spec={resolved} tagFilter={tagFilter} />\n </Prose>\n </article>\n )\n}\n\nfunction OpenApiOperationWithSpec(arg0: OpenApiOperationWithSpecProps): ReactNode {\n const { spec, path, method } = arg0\n const t = useBuiltInText()\n const op = getOpenApiOperation(spec, path, method)\n\n if (!op) {\n return <WarningBox tone=\"red\">{t('openapi.endpointNotFound', { endpoint: `${method.toUpperCase()} ${path}` })}</WarningBox>\n }\n\n const normalizedMethod = method.toUpperCase()\n return <OpenApiOperationComponent key={`${normalizedMethod}-${path}`} spec={spec} path={path} method={normalizedMethod} operation={op} />\n}\n\nexport function OpenApiOperation(arg0: OpenApiOperationProps): ReactNode {\n const { specPath, path, method } = arg0\n const t = useBuiltInText()\n const spec = useOpenApiSpec(undefined, specPath)\n\n if (!spec) {\n return <WarningBox>{t('openapi.specNotFound', { specPath })}</WarningBox>\n }\n\n return <OpenApiOperationWithSpec spec={spec} path={path} method={method} />\n}\n\nexport function createOpenApiRouteComponent(data: OpenApiRouteData) {\n return function OpenApiRoutePage() {\n return <OpenApiDocument spec={data.spec} tagFilter={data.tagFilter} />\n }\n}\n","import { Collapse } from '../components/Collapse'\nimport { Mermaid } from '../components/Mermaid'\nimport { OpenApiDocument, OpenApiOperation } from '../openapi'\n\nimport { Markdown } from './Markdown'\nimport * as mdxPrimitives from './primitives'\n\nconst builtInMDXComponents = {\n ...mdxPrimitives,\n Markdown,\n Collapse,\n Mermaid,\n}\n\nconst builtInOpenAPIComponents = {\n OpenApiDocument,\n OpenApiOperation,\n}\n\nexport function useMDXComponents(components: Record<string, unknown> = {}) {\n return {\n ...components,\n ...builtInMDXComponents,\n ...builtInOpenAPIComponents,\n }\n}\n","import type { ReactNode } from 'react'\n\nimport { Prose } from '../components/Prose'\n\nexport type DocShellProps = {\n title: string\n subtitle?: string\n children: ReactNode\n}\n\nexport function DocShell(arg0: DocShellProps) {\n const { title, subtitle, children } = arg0\n\n return (\n <main className=\"clarify-doc-shell min-h-screen bg-(--clarify-theme-tokens-colors-background) px-6 py-10 text-(--clarify-theme-tokens-colors-foreground) md:px-10\">\n <div className=\"mx-auto max-w-6xl\">\n <header className=\"mb-10\">\n <h1 className=\"text-3xl font-bold tracking-tight md:text-5xl\">{title}</h1>\n {subtitle ? <p className=\"mt-3 max-w-2xl text-(--clarify-ui-text-soft)\">{subtitle}</p> : null}\n </header>\n <Prose>{children}</Prose>\n </div>\n </main>\n )\n}\n"],"mappings":"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"}
@@ -5,6 +5,7 @@ type SchemaPropertiesProps = {
5
5
  title: string;
6
6
  schema: unknown;
7
7
  spec: OpenAPISpec;
8
+ defaultExpanded?: boolean;
8
9
  };
9
10
  export declare function SchemaProperties(arg0: SchemaPropertiesProps): ReactNode;
10
11
  type ParameterListProps = {
@@ -5,6 +5,10 @@ export type OpenApiDocumentProps = {
5
5
  specPath?: string;
6
6
  tagFilter?: string[];
7
7
  };
8
+ export type OpenApiRouteData = {
9
+ spec: OpenAPISpec;
10
+ tagFilter?: string[];
11
+ };
8
12
  export type OpenApiOperationProps = {
9
13
  specPath: string;
10
14
  path: string;
@@ -12,3 +16,4 @@ export type OpenApiOperationProps = {
12
16
  };
13
17
  export declare function OpenApiDocument(arg0: OpenApiDocumentProps): ReactNode;
14
18
  export declare function OpenApiOperation(arg0: OpenApiOperationProps): ReactNode;
19
+ export declare function createOpenApiRouteComponent(data: OpenApiRouteData): () => import("react").JSX.Element;
@@ -1,3 +1,3 @@
1
- export { OpenApiOperation, OpenApiDocument } from './entry';
2
- export type { OpenApiOperationProps, OpenApiDocumentProps } from './entry';
1
+ export { OpenApiOperation, OpenApiDocument, createOpenApiRouteComponent } from './entry';
2
+ export type { OpenApiOperationProps, OpenApiDocumentProps, OpenApiRouteData } from './entry';
3
3
  export type { OpenAPIOperation, OpenAPISpec } from './lib/utils';
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_PageActions = require("./PageActions-DEuFHgyB.cjs");
3
- const require_OpenApiOperation = require("./OpenApiOperation-DIWGdw29.cjs");
2
+ const require_PageActions = require("./PageActions-CTn2XkPg.cjs");
3
+ const require_OpenApiOperation = require("./OpenApiOperation-CyyPlZL6.cjs");
4
4
  let react = require("react");
5
5
  let react_router_dom = require("react-router-dom");
6
6
  let lucide_react = require("lucide-react");
package/output/preview.js CHANGED
@@ -1,5 +1,5 @@
1
- import { a as authPlaceholder, c as getServerKey, d as getRequestBody, i as ResponseExamplesPanel, l as getServers, o as defaultServerVariables, r as RequestExamplesPanel, s as getAuthOptions, t as EndpointIdentity, u as getMediaTypeEntries } from "./OpenApiOperation-C9xyRo5a.js";
2
- import { A as OpenApisContext, O as ConfigContext, a as SectionProvider, i as Navigation, k as LocaleContext } from "./PageActions-B_tSec1f.js";
1
+ import { a as authPlaceholder, c as getServerKey, d as getRequestBody, i as ResponseExamplesPanel, l as getServers, o as defaultServerVariables, r as RequestExamplesPanel, s as getAuthOptions, t as EndpointIdentity, u as getMediaTypeEntries } from "./OpenApiOperation-Dhlz3JSx.js";
2
+ import { A as OpenApisContext, O as ConfigContext, a as SectionProvider, i as Navigation, k as LocaleContext } from "./PageActions-D0PA8Zv5.js";
3
3
  import { useState } from "react";
4
4
  import { MemoryRouter } from "react-router-dom";
5
5
  import { Menu, X } from "lucide-react";
@@ -1,4 +1,4 @@
1
- import { t as ClarifyShell } from "./ClarifyShell-BQ29N8P5.js";
1
+ import { t as ClarifyShell } from "./ClarifyShell-D2P0iZ_m.js";
2
2
  import { StrictMode } from "react";
3
3
  import { BrowserRouter } from "react-router-dom";
4
4
  import { jsx } from "react/jsx-runtime";
@@ -49,4 +49,4 @@ function render(options) {
49
49
  //#endregion
50
50
  export { render as t };
51
51
 
52
- //# sourceMappingURL=render-CEWLJSmt.js.map
52
+ //# sourceMappingURL=render-CwSsfrs7.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"render-CEWLJSmt.js","names":[],"sources":["../source/runtime/render.tsx"],"sourcesContent":["import { StrictMode } from 'react'\nimport { hydrateRoot, createRoot } from 'react-dom/client'\nimport { BrowserRouter } from 'react-router-dom'\n\nimport type { RenderOptions } from '../types'\n\nimport { ClarifyShell } from './ClarifyShell'\n\n/**\n * Clarify 客户端 Hydration 入口。\n * 在文档项目的 main.tsx 中调用:\n * ```ts\n * import { render } from '@clarify-labs/renderer';\n * import { routes } from 'virtual:clarify-routes';\n * import { config } from 'virtual:clarify-config';\n * render({ config, routes });\n * ```\n */\nfunction isHydrationDebugEnabled(): boolean {\n try {\n const params = new URLSearchParams(window.location.search)\n return params.get('clarifyHydrationDebug') === '1' || window.localStorage.getItem('clarify:hydration-debug') === '1'\n } catch {\n return false\n }\n}\n\nexport function render(options: RenderOptions) {\n const { config, routes, navigation, openApis = {}, runtimeSlots, container, themeEditor = false } = options\n\n const target = container ?? document.getElementById('root')\n if (!target) {\n throw new Error('[clarify] 渲染失败:找不到挂载节点,请确保 HTML 中存在 id=\"root\" 的元素')\n }\n\n const app = (\n <StrictMode>\n <BrowserRouter basename={config.routePrefix}>\n <ClarifyShell\n config={config}\n routes={routes}\n navigation={navigation}\n openApis={openApis}\n runtimeSlots={runtimeSlots}\n themeEditor={themeEditor}\n />\n </BrowserRouter>\n </StrictMode>\n )\n\n const hydrationDebug = isHydrationDebugEnabled()\n\n try {\n hydrateRoot(target as Element, app, {\n onRecoverableError(error, errorInfo) {\n // Phase 1: suppress hydration mismatch noise by default. React 19\n // recovers automatically, but diagnostics can be enabled explicitly.\n if (hydrationDebug) {\n console.warn('[clarify] Recoverable hydration error:', error, errorInfo)\n }\n },\n })\n } catch (err) {\n console.warn('[clarify] Hydration failed, falling back to client render:', err)\n createRoot(target as Element).render(app)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAkBA,SAAS,0BAAmC;CAC1C,IAAI;EAEF,OAAO,IADY,gBAAgB,OAAO,SAAS,MAC5C,EAAO,IAAI,uBAAuB,MAAM,OAAO,OAAO,aAAa,QAAQ,yBAAyB,MAAM;CACnH,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAgB,OAAO,SAAwB;CAC7C,MAAM,EAAE,QAAQ,QAAQ,YAAY,WAAW,CAAC,GAAG,cAAc,WAAW,cAAc,UAAU;CAEpG,MAAM,SAAS,aAAa,SAAS,eAAe,MAAM;CAC1D,IAAI,CAAC,QACH,MAAM,IAAI,MAAM,qDAAmD;CAGrE,MAAM,MACJ,oBAAC,YAAD,EAAA,UACE,oBAAC,eAAD;EAAe,UAAU,OAAO;YAC9B,oBAAC,cAAD;GACU;GACA;GACI;GACF;GACI;GACD;EACd,CAAA;CACY,CAAA,EACL,CAAA;CAGd,MAAM,iBAAiB,wBAAwB;CAE/C,IAAI;EACF,YAAY,QAAmB,KAAK,EAClC,mBAAmB,OAAO,WAAW;GAGnC,IAAI,gBACF,QAAQ,KAAK,0CAA0C,OAAO,SAAS;EAE3E,EACF,CAAC;CACH,SAAS,KAAK;EACZ,QAAQ,KAAK,8DAA8D,GAAG;EAC9E,WAAW,MAAiB,EAAE,OAAO,GAAG;CAC1C;AACF"}
1
+ {"version":3,"file":"render-CwSsfrs7.js","names":[],"sources":["../source/runtime/render.tsx"],"sourcesContent":["import { StrictMode } from 'react'\nimport { hydrateRoot, createRoot } from 'react-dom/client'\nimport { BrowserRouter } from 'react-router-dom'\n\nimport type { RenderOptions } from '../types'\n\nimport { ClarifyShell } from './ClarifyShell'\n\n/**\n * Clarify 客户端 Hydration 入口。\n * 在文档项目的 main.tsx 中调用:\n * ```ts\n * import { render } from '@clarify-labs/renderer';\n * import { routes } from 'virtual:clarify-routes';\n * import { config } from 'virtual:clarify-config';\n * render({ config, routes });\n * ```\n */\nfunction isHydrationDebugEnabled(): boolean {\n try {\n const params = new URLSearchParams(window.location.search)\n return params.get('clarifyHydrationDebug') === '1' || window.localStorage.getItem('clarify:hydration-debug') === '1'\n } catch {\n return false\n }\n}\n\nexport function render(options: RenderOptions) {\n const { config, routes, navigation, openApis = {}, runtimeSlots, container, themeEditor = false } = options\n\n const target = container ?? document.getElementById('root')\n if (!target) {\n throw new Error('[clarify] 渲染失败:找不到挂载节点,请确保 HTML 中存在 id=\"root\" 的元素')\n }\n\n const app = (\n <StrictMode>\n <BrowserRouter basename={config.routePrefix}>\n <ClarifyShell\n config={config}\n routes={routes}\n navigation={navigation}\n openApis={openApis}\n runtimeSlots={runtimeSlots}\n themeEditor={themeEditor}\n />\n </BrowserRouter>\n </StrictMode>\n )\n\n const hydrationDebug = isHydrationDebugEnabled()\n\n try {\n hydrateRoot(target as Element, app, {\n onRecoverableError(error, errorInfo) {\n // Phase 1: suppress hydration mismatch noise by default. React 19\n // recovers automatically, but diagnostics can be enabled explicitly.\n if (hydrationDebug) {\n console.warn('[clarify] Recoverable hydration error:', error, errorInfo)\n }\n },\n })\n } catch (err) {\n console.warn('[clarify] Hydration failed, falling back to client render:', err)\n createRoot(target as Element).render(app)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAkBA,SAAS,0BAAmC;CAC1C,IAAI;EAEF,OAAO,IADY,gBAAgB,OAAO,SAAS,MAC5C,EAAO,IAAI,uBAAuB,MAAM,OAAO,OAAO,aAAa,QAAQ,yBAAyB,MAAM;CACnH,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAgB,OAAO,SAAwB;CAC7C,MAAM,EAAE,QAAQ,QAAQ,YAAY,WAAW,CAAC,GAAG,cAAc,WAAW,cAAc,UAAU;CAEpG,MAAM,SAAS,aAAa,SAAS,eAAe,MAAM;CAC1D,IAAI,CAAC,QACH,MAAM,IAAI,MAAM,qDAAmD;CAGrE,MAAM,MACJ,oBAAC,YAAD,EAAA,UACE,oBAAC,eAAD;EAAe,UAAU,OAAO;YAC9B,oBAAC,cAAD;GACU;GACA;GACI;GACF;GACI;GACD;EACd,CAAA;CACY,CAAA,EACL,CAAA;CAGd,MAAM,iBAAiB,wBAAwB;CAE/C,IAAI;EACF,YAAY,QAAmB,KAAK,EAClC,mBAAmB,OAAO,WAAW;GAGnC,IAAI,gBACF,QAAQ,KAAK,0CAA0C,OAAO,SAAS;EAE3E,EACF,CAAC;CACH,SAAS,KAAK;EACZ,QAAQ,KAAK,8DAA8D,GAAG;EAC9E,WAAW,MAAiB,EAAE,OAAO,GAAG;CAC1C;AACF"}
@@ -1,4 +1,4 @@
1
- const require_ClarifyShell = require("./ClarifyShell-Dm--LZco.cjs");
1
+ const require_ClarifyShell = require("./ClarifyShell-7r92MZg9.cjs");
2
2
  let react = require("react");
3
3
  let react_router_dom = require("react-router-dom");
4
4
  let react_jsx_runtime = require("react/jsx-runtime");
@@ -54,4 +54,4 @@ Object.defineProperty(exports, "render", {
54
54
  }
55
55
  });
56
56
 
57
- //# sourceMappingURL=render-BCGK1WpS.cjs.map
57
+ //# sourceMappingURL=render-DXDSIfZ8.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"render-BCGK1WpS.cjs","names":[],"sources":["../source/runtime/render.tsx"],"sourcesContent":["import { StrictMode } from 'react'\nimport { hydrateRoot, createRoot } from 'react-dom/client'\nimport { BrowserRouter } from 'react-router-dom'\n\nimport type { RenderOptions } from '../types'\n\nimport { ClarifyShell } from './ClarifyShell'\n\n/**\n * Clarify 客户端 Hydration 入口。\n * 在文档项目的 main.tsx 中调用:\n * ```ts\n * import { render } from '@clarify-labs/renderer';\n * import { routes } from 'virtual:clarify-routes';\n * import { config } from 'virtual:clarify-config';\n * render({ config, routes });\n * ```\n */\nfunction isHydrationDebugEnabled(): boolean {\n try {\n const params = new URLSearchParams(window.location.search)\n return params.get('clarifyHydrationDebug') === '1' || window.localStorage.getItem('clarify:hydration-debug') === '1'\n } catch {\n return false\n }\n}\n\nexport function render(options: RenderOptions) {\n const { config, routes, navigation, openApis = {}, runtimeSlots, container, themeEditor = false } = options\n\n const target = container ?? document.getElementById('root')\n if (!target) {\n throw new Error('[clarify] 渲染失败:找不到挂载节点,请确保 HTML 中存在 id=\"root\" 的元素')\n }\n\n const app = (\n <StrictMode>\n <BrowserRouter basename={config.routePrefix}>\n <ClarifyShell\n config={config}\n routes={routes}\n navigation={navigation}\n openApis={openApis}\n runtimeSlots={runtimeSlots}\n themeEditor={themeEditor}\n />\n </BrowserRouter>\n </StrictMode>\n )\n\n const hydrationDebug = isHydrationDebugEnabled()\n\n try {\n hydrateRoot(target as Element, app, {\n onRecoverableError(error, errorInfo) {\n // Phase 1: suppress hydration mismatch noise by default. React 19\n // recovers automatically, but diagnostics can be enabled explicitly.\n if (hydrationDebug) {\n console.warn('[clarify] Recoverable hydration error:', error, errorInfo)\n }\n },\n })\n } catch (err) {\n console.warn('[clarify] Hydration failed, falling back to client render:', err)\n createRoot(target as Element).render(app)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAkBA,SAAS,0BAAmC;CAC1C,IAAI;EAEF,OAAO,IADY,gBAAgB,OAAO,SAAS,MAC5C,EAAO,IAAI,uBAAuB,MAAM,OAAO,OAAO,aAAa,QAAQ,yBAAyB,MAAM;CACnH,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAgB,OAAO,SAAwB;CAC7C,MAAM,EAAE,QAAQ,QAAQ,YAAY,WAAW,CAAC,GAAG,cAAc,WAAW,cAAc,UAAU;CAEpG,MAAM,SAAS,aAAa,SAAS,eAAe,MAAM;CAC1D,IAAI,CAAC,QACH,MAAM,IAAI,MAAM,qDAAmD;CAGrE,MAAM,MACJ,iBAAA,GAAA,kBAAA,KAAC,MAAA,YAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,KAAC,iBAAA,eAAD;EAAe,UAAU,OAAO;YAC9B,iBAAA,GAAA,kBAAA,KAAC,qBAAA,cAAD;GACU;GACA;GACI;GACF;GACI;GACD;EACd,CAAA;CACY,CAAA,EACL,CAAA;CAGd,MAAM,iBAAiB,wBAAwB;CAE/C,IAAI;EACF,CAAA,GAAA,iBAAA,aAAY,QAAmB,KAAK,EAClC,mBAAmB,OAAO,WAAW;GAGnC,IAAI,gBACF,QAAQ,KAAK,0CAA0C,OAAO,SAAS;EAE3E,EACF,CAAC;CACH,SAAS,KAAK;EACZ,QAAQ,KAAK,8DAA8D,GAAG;EAC9E,CAAA,GAAA,iBAAA,YAAW,MAAiB,EAAE,OAAO,GAAG;CAC1C;AACF"}
1
+ {"version":3,"file":"render-DXDSIfZ8.cjs","names":[],"sources":["../source/runtime/render.tsx"],"sourcesContent":["import { StrictMode } from 'react'\nimport { hydrateRoot, createRoot } from 'react-dom/client'\nimport { BrowserRouter } from 'react-router-dom'\n\nimport type { RenderOptions } from '../types'\n\nimport { ClarifyShell } from './ClarifyShell'\n\n/**\n * Clarify 客户端 Hydration 入口。\n * 在文档项目的 main.tsx 中调用:\n * ```ts\n * import { render } from '@clarify-labs/renderer';\n * import { routes } from 'virtual:clarify-routes';\n * import { config } from 'virtual:clarify-config';\n * render({ config, routes });\n * ```\n */\nfunction isHydrationDebugEnabled(): boolean {\n try {\n const params = new URLSearchParams(window.location.search)\n return params.get('clarifyHydrationDebug') === '1' || window.localStorage.getItem('clarify:hydration-debug') === '1'\n } catch {\n return false\n }\n}\n\nexport function render(options: RenderOptions) {\n const { config, routes, navigation, openApis = {}, runtimeSlots, container, themeEditor = false } = options\n\n const target = container ?? document.getElementById('root')\n if (!target) {\n throw new Error('[clarify] 渲染失败:找不到挂载节点,请确保 HTML 中存在 id=\"root\" 的元素')\n }\n\n const app = (\n <StrictMode>\n <BrowserRouter basename={config.routePrefix}>\n <ClarifyShell\n config={config}\n routes={routes}\n navigation={navigation}\n openApis={openApis}\n runtimeSlots={runtimeSlots}\n themeEditor={themeEditor}\n />\n </BrowserRouter>\n </StrictMode>\n )\n\n const hydrationDebug = isHydrationDebugEnabled()\n\n try {\n hydrateRoot(target as Element, app, {\n onRecoverableError(error, errorInfo) {\n // Phase 1: suppress hydration mismatch noise by default. React 19\n // recovers automatically, but diagnostics can be enabled explicitly.\n if (hydrationDebug) {\n console.warn('[clarify] Recoverable hydration error:', error, errorInfo)\n }\n },\n })\n } catch (err) {\n console.warn('[clarify] Hydration failed, falling back to client render:', err)\n createRoot(target as Element).render(app)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAkBA,SAAS,0BAAmC;CAC1C,IAAI;EAEF,OAAO,IADY,gBAAgB,OAAO,SAAS,MAC5C,EAAO,IAAI,uBAAuB,MAAM,OAAO,OAAO,aAAa,QAAQ,yBAAyB,MAAM;CACnH,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAgB,OAAO,SAAwB;CAC7C,MAAM,EAAE,QAAQ,QAAQ,YAAY,WAAW,CAAC,GAAG,cAAc,WAAW,cAAc,UAAU;CAEpG,MAAM,SAAS,aAAa,SAAS,eAAe,MAAM;CAC1D,IAAI,CAAC,QACH,MAAM,IAAI,MAAM,qDAAmD;CAGrE,MAAM,MACJ,iBAAA,GAAA,kBAAA,KAAC,MAAA,YAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,KAAC,iBAAA,eAAD;EAAe,UAAU,OAAO;YAC9B,iBAAA,GAAA,kBAAA,KAAC,qBAAA,cAAD;GACU;GACA;GACI;GACF;GACI;GACD;EACd,CAAA;CACY,CAAA,EACL,CAAA;CAGd,MAAM,iBAAiB,wBAAwB;CAE/C,IAAI;EACF,CAAA,GAAA,iBAAA,aAAY,QAAmB,KAAK,EAClC,mBAAmB,OAAO,WAAW;GAGnC,IAAI,gBACF,QAAQ,KAAK,0CAA0C,OAAO,SAAS;EAE3E,EACF,CAAC;CACH,SAAS,KAAK;EACZ,QAAQ,KAAK,8DAA8D,GAAG;EAC9E,CAAA,GAAA,iBAAA,YAAW,MAAiB,EAAE,OAAO,GAAG;CAC1C;AACF"}
@@ -2094,6 +2094,10 @@
2094
2094
  display: none;
2095
2095
  }
2096
2096
 
2097
+ .inline {
2098
+ display: inline;
2099
+ }
2100
+
2097
2101
  .inline-flex {
2098
2102
  display: inline-flex;
2099
2103
  }
package/output/server.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_PageActions = require("./PageActions-DEuFHgyB.cjs");
3
- const require_ClarifyShell = require("./ClarifyShell-Dm--LZco.cjs");
2
+ const require_PageActions = require("./PageActions-CTn2XkPg.cjs");
3
+ const require_ClarifyShell = require("./ClarifyShell-7r92MZg9.cjs");
4
4
  let react = require("react");
5
5
  let react_router_dom = require("react-router-dom");
6
6
  let react_jsx_runtime = require("react/jsx-runtime");
package/output/server.js CHANGED
@@ -1,5 +1,5 @@
1
- import { T as prefixHref } from "./PageActions-B_tSec1f.js";
2
- import { t as ClarifyShell } from "./ClarifyShell-BQ29N8P5.js";
1
+ import { T as prefixHref } from "./PageActions-D0PA8Zv5.js";
2
+ import { t as ClarifyShell } from "./ClarifyShell-D2P0iZ_m.js";
3
3
  import { StrictMode } from "react";
4
4
  import { StaticRouter } from "react-router-dom";
5
5
  import { jsx } from "react/jsx-runtime";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clarify-labs/renderer",
3
- "version": "0.9.3",
3
+ "version": "0.9.4",
4
4
  "license": "AGPL-3.0-only",
5
5
  "type": "module",
6
6
  "repository": {