@ciderpress/ui 1.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +23 -0
- package/dist/0~142.js +2 -0
- package/dist/0~164.js +2 -0
- package/dist/0~2.js +2 -0
- package/dist/0~225.js +2 -0
- package/dist/0~288.js +2 -0
- package/dist/0~299.js +2 -0
- package/dist/0~3.js +2 -0
- package/dist/0~301.js +2 -0
- package/dist/0~311.js +2 -0
- package/dist/0~326.js +2 -0
- package/dist/0~40.js +2 -0
- package/dist/0~43.js +2 -0
- package/dist/0~433.js +2 -0
- package/dist/0~453.js +2 -0
- package/dist/0~457.js +2 -0
- package/dist/0~497.js +2 -0
- package/dist/0~511.js +2 -0
- package/dist/0~603.js +2 -0
- package/dist/0~616.js +2 -0
- package/dist/0~659.js +2 -0
- package/dist/0~670.js +2 -0
- package/dist/0~687.js +2 -0
- package/dist/0~706.js +2 -0
- package/dist/0~729.js +2 -0
- package/dist/0~768.js +2 -0
- package/dist/0~819.js +2 -0
- package/dist/0~830.js +2 -0
- package/dist/0~854.js +2 -0
- package/dist/0~863.js +2 -0
- package/dist/0~879.js +2 -0
- package/dist/0~96.js +2 -0
- package/dist/0~97.js +2 -0
- package/dist/components/FileTree/FileTree.css +90 -0
- package/dist/components/FileTree/FileTree.d.ts +7 -0
- package/dist/components/FileTree/FileTree.js +531 -0
- package/dist/components/FileTree/FileTreeItem.d.ts +8 -0
- package/dist/components/FileTree/RemoteSvgIcon.d.ts +11 -0
- package/dist/components/FileTree/index.d.ts +4 -0
- package/dist/components/folder-icons.d.ts +32 -0
- package/dist/components/languages.d.ts +7 -0
- package/dist/components/tree-parser/tree-parser.d.ts +12 -0
- package/dist/components/tree-parser/types.d.ts +11 -0
- package/dist/head/css/loader-apple.css +1 -0
- package/dist/head/css/loader-backdrop.css +1 -0
- package/dist/head/css/loader-dots.css +1 -0
- package/dist/head/css/themes/amber.css +1 -0
- package/dist/head/css/themes/arcade.css +1 -0
- package/dist/head/css/themes/grannysmith.css +1 -0
- package/dist/head/css/themes/honeycrisp.css +1 -0
- package/dist/head/css/themes/midnight.css +1 -0
- package/dist/head/css/themes/mulled.css +1 -0
- package/dist/head/js/loader-dots.js +1 -0
- package/dist/head/js/vscode-nav.js +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.mjs +40 -0
- package/dist/node.d.ts +81 -0
- package/dist/node.mjs +17762 -0
- package/dist/plugins/mermaid/MermaidRenderer.tsx +480 -0
- package/dist/plugins/mermaid/mermaid.css +199 -0
- package/dist/theme/components/announcement/announcement-bar.css +103 -0
- package/dist/theme/components/announcement/announcement-bar.tsx +173 -0
- package/dist/theme/components/ask-ai/ask-ai-button.css +52 -0
- package/dist/theme/components/ask-ai/ask-ai-button.tsx +56 -0
- package/dist/theme/components/content-footer/content-footer-portal.tsx +70 -0
- package/dist/theme/components/content-footer/feedback.css +47 -0
- package/dist/theme/components/content-footer/feedback.tsx +96 -0
- package/dist/theme/components/content-footer/meta-actions.css +25 -0
- package/dist/theme/components/content-footer/meta-actions.tsx +57 -0
- package/dist/theme/components/content-footer/page-pager.css +61 -0
- package/dist/theme/components/content-footer/page-pager.tsx +110 -0
- package/dist/theme/components/edit-source-button.tsx +97 -0
- package/dist/theme/components/footer/site-footer.css +179 -0
- package/dist/theme/components/footer/site-footer.tsx +115 -0
- package/dist/theme/components/home/cta.css +67 -0
- package/dist/theme/components/home/cta.tsx +77 -0
- package/dist/theme/components/home/feature-card.css +52 -0
- package/dist/theme/components/home/feature-card.tsx +131 -0
- package/dist/theme/components/home/feature.tsx +79 -0
- package/dist/theme/components/home/hero-demo.css +66 -0
- package/dist/theme/components/home/hero-demo.tsx +46 -0
- package/dist/theme/components/home/hero.css +96 -0
- package/dist/theme/components/home/hero.tsx +111 -0
- package/dist/theme/components/home/layout.tsx +183 -0
- package/dist/theme/components/home/page-rail.css +21 -0
- package/dist/theme/components/home/page-rail.tsx +19 -0
- package/dist/theme/components/home/split.css +148 -0
- package/dist/theme/components/home/split.tsx +120 -0
- package/dist/theme/components/home/trust-strip.css +33 -0
- package/dist/theme/components/home/trust-strip.tsx +43 -0
- package/dist/theme/components/home/workspaces.tsx +71 -0
- package/dist/theme/components/nav/branch-tag.css +54 -0
- package/dist/theme/components/nav/branch-tag.tsx +101 -0
- package/dist/theme/components/nav/ciderpress-doc-layout.tsx +247 -0
- package/dist/theme/components/nav/ciderpress-docs-bar.css +505 -0
- package/dist/theme/components/nav/ciderpress-docs-bar.tsx +426 -0
- package/dist/theme/components/nav/ciderpress-header.css +172 -0
- package/dist/theme/components/nav/ciderpress-header.tsx +113 -0
- package/dist/theme/components/nav/ciderpress-layout-context.tsx +49 -0
- package/dist/theme/components/nav/ciderpress-nav-hamburger.css +193 -0
- package/dist/theme/components/nav/ciderpress-nav-hamburger.tsx +112 -0
- package/dist/theme/components/nav/ciderpress-nav-menu.css +130 -0
- package/dist/theme/components/nav/ciderpress-nav-menu.tsx +372 -0
- package/dist/theme/components/nav/ciderpress-nav-search.css +73 -0
- package/dist/theme/components/nav/ciderpress-nav-search.tsx +55 -0
- package/dist/theme/components/nav/ciderpress-nav-social-links.css +35 -0
- package/dist/theme/components/nav/ciderpress-nav-social-links.tsx +87 -0
- package/dist/theme/components/nav/floating-branch-indicator.css +106 -0
- package/dist/theme/components/nav/floating-branch-indicator.tsx +109 -0
- package/dist/theme/components/nav/layout.tsx +268 -0
- package/dist/theme/components/nav/mobile-nav-cta.tsx +79 -0
- package/dist/theme/components/nav/nav-divider.css +15 -0
- package/dist/theme/components/nav/nav-divider.tsx +19 -0
- package/dist/theme/components/nav/nav-logo.css +42 -0
- package/dist/theme/components/nav/nav-logo.tsx +262 -0
- package/dist/theme/components/nav/theme-switcher.css +92 -0
- package/dist/theme/components/nav/theme-switcher.tsx +298 -0
- package/dist/theme/components/nav/topbar-cta.css +45 -0
- package/dist/theme/components/nav/topbar-cta.tsx +39 -0
- package/dist/theme/components/nav/variant-toggle.css +70 -0
- package/dist/theme/components/nav/variant-toggle.tsx +83 -0
- package/dist/theme/components/nav/version-chip.css +31 -0
- package/dist/theme/components/nav/version-chip.tsx +45 -0
- package/dist/theme/components/nav/vscode-tag.css +32 -0
- package/dist/theme/components/nav/vscode-tag.tsx +20 -0
- package/dist/theme/components/openapi/code-sample.tsx +341 -0
- package/dist/theme/components/openapi/copy-markdown-button.tsx +41 -0
- package/dist/theme/components/openapi/icons.tsx +45 -0
- package/dist/theme/components/openapi/index.ts +6 -0
- package/dist/theme/components/openapi/method-badge.tsx +24 -0
- package/dist/theme/components/openapi/openapi.css +665 -0
- package/dist/theme/components/openapi/operation.tsx +200 -0
- package/dist/theme/components/openapi/overview.tsx +207 -0
- package/dist/theme/components/openapi/parameters-table.tsx +149 -0
- package/dist/theme/components/openapi/request-body.tsx +90 -0
- package/dist/theme/components/openapi/response-list.tsx +112 -0
- package/dist/theme/components/openapi/schema-viewer.tsx +277 -0
- package/dist/theme/components/openapi/security-badges.tsx +63 -0
- package/dist/theme/components/openapi/spec-utils.ts +122 -0
- package/dist/theme/components/shared/accordion.css +118 -0
- package/dist/theme/components/shared/accordion.stories.tsx +96 -0
- package/dist/theme/components/shared/accordion.tsx +191 -0
- package/dist/theme/components/shared/brand-logo.stories.tsx +49 -0
- package/dist/theme/components/shared/brand-mark.stories.tsx +53 -0
- package/dist/theme/components/shared/browser-window.css +1 -0
- package/dist/theme/components/shared/browser-window.stories.tsx +100 -0
- package/dist/theme/components/shared/browser-window.tsx +2 -0
- package/dist/theme/components/shared/card.stories.tsx +50 -0
- package/dist/theme/components/shared/card.tsx +35 -0
- package/dist/theme/components/shared/ciderpress-logo.tsx +93 -0
- package/dist/theme/components/shared/ciderpress-mark.tsx +77 -0
- package/dist/theme/components/shared/color.css +56 -0
- package/dist/theme/components/shared/color.stories.tsx +47 -0
- package/dist/theme/components/shared/color.tsx +69 -0
- package/dist/theme/components/shared/columns.css +37 -0
- package/dist/theme/components/shared/columns.stories.tsx +91 -0
- package/dist/theme/components/shared/columns.tsx +50 -0
- package/dist/theme/components/shared/desktop-window.css +339 -0
- package/dist/theme/components/shared/desktop-window.tsx +535 -0
- package/dist/theme/components/shared/field.css +158 -0
- package/dist/theme/components/shared/field.stories.tsx +100 -0
- package/dist/theme/components/shared/field.tsx +186 -0
- package/dist/theme/components/shared/frame.css +39 -0
- package/dist/theme/components/shared/frame.stories.tsx +49 -0
- package/dist/theme/components/shared/frame.tsx +76 -0
- package/dist/theme/components/shared/icon.stories.tsx +90 -0
- package/dist/theme/components/shared/icon.tsx +41 -0
- package/dist/theme/components/shared/prompt.css +178 -0
- package/dist/theme/components/shared/prompt.stories.tsx +57 -0
- package/dist/theme/components/shared/prompt.tsx +369 -0
- package/dist/theme/components/shared/resolve-card-icon.ts +28 -0
- package/dist/theme/components/shared/section-card.stories.tsx +51 -0
- package/dist/theme/components/shared/section-card.tsx +44 -0
- package/dist/theme/components/shared/section-grid.stories.tsx +46 -0
- package/dist/theme/components/shared/section-grid.tsx +15 -0
- package/dist/theme/components/shared/status-badge.css +37 -0
- package/dist/theme/components/shared/status-badge.stories.tsx +61 -0
- package/dist/theme/components/shared/status-badge.tsx +74 -0
- package/dist/theme/components/shared/steps.css +88 -0
- package/dist/theme/components/shared/steps.stories.tsx +68 -0
- package/dist/theme/components/shared/steps.tsx +100 -0
- package/dist/theme/components/shared/tech-icon-table.stories.tsx +29 -0
- package/dist/theme/components/shared/tech-icon-table.tsx +71 -0
- package/dist/theme/components/shared/tech-tag.stories.tsx +40 -0
- package/dist/theme/components/shared/tech-tag.tsx +31 -0
- package/dist/theme/components/shared/theme-color-palette.css +80 -0
- package/dist/theme/components/shared/theme-color-palette.stories.tsx +52 -0
- package/dist/theme/components/shared/theme-color-palette.tsx +275 -0
- package/dist/theme/components/shared/tooltip.css +69 -0
- package/dist/theme/components/shared/tooltip.stories.tsx +72 -0
- package/dist/theme/components/shared/tooltip.tsx +77 -0
- package/dist/theme/components/sidebar/framework-picker.css +77 -0
- package/dist/theme/components/sidebar/framework-picker.tsx +78 -0
- package/dist/theme/components/sidebar/sidebar-filter.test.ts +140 -0
- package/dist/theme/components/sidebar/sidebar-filter.ts +79 -0
- package/dist/theme/components/sidebar/sidebar-links.css +102 -0
- package/dist/theme/components/sidebar/sidebar-links.tsx +122 -0
- package/dist/theme/components/sidebar/sidebar-promo.css +42 -0
- package/dist/theme/components/sidebar/sidebar-promo.tsx +52 -0
- package/dist/theme/components/sidebar/sidebar-scope.tsx +151 -0
- package/dist/theme/components/sidebar/sidebar-toggle.css +181 -0
- package/dist/theme/components/sidebar/sidebar-toggle.tsx +127 -0
- package/dist/theme/components/theme-provider.tsx +637 -0
- package/dist/theme/components/workspaces/card.css +151 -0
- package/dist/theme/components/workspaces/card.tsx +166 -0
- package/dist/theme/components/workspaces/grid.tsx +62 -0
- package/dist/theme/css.d.ts +1 -0
- package/dist/theme/env.d.ts +12 -0
- package/dist/theme/fonts/GeistMono-Variable.woff2 +0 -0
- package/dist/theme/fonts/GeistPixel-Square.woff2 +0 -0
- package/dist/theme/fonts/GeistSans-Variable.woff2 +0 -0
- package/dist/theme/hooks/use-ciderpress.ts +61 -0
- package/dist/theme/hooks/use-nav-items.ts +76 -0
- package/dist/theme/icons/index.ts +2 -0
- package/dist/theme/icons/tech-map.ts +228 -0
- package/dist/theme/index.tsx +180 -0
- package/dist/theme/lib/read-social-links.ts +27 -0
- package/dist/theme/lib/route-link.tsx +126 -0
- package/dist/theme/lib/safe-url.test.ts +0 -0
- package/dist/theme/lib/safe-url.ts +68 -0
- package/dist/theme/lib/theme-favicon.ts +125 -0
- package/dist/theme/lib/user-config-stub.ts +12 -0
- package/dist/theme/styles/layers.css +32 -0
- package/dist/theme/styles/overrides/badge.css +26 -0
- package/dist/theme/styles/overrides/content-footer.css +80 -0
- package/dist/theme/styles/overrides/details.css +61 -0
- package/dist/theme/styles/overrides/fonts.css +32 -0
- package/dist/theme/styles/overrides/home-card.css +133 -0
- package/dist/theme/styles/overrides/home.css +243 -0
- package/dist/theme/styles/overrides/rail.css +337 -0
- package/dist/theme/styles/overrides/rspress.css +62 -0
- package/dist/theme/styles/overrides/scrollbar.css +25 -0
- package/dist/theme/styles/overrides/section-card.css +114 -0
- package/dist/theme/styles/overrides/sidebar.css +144 -0
- package/dist/theme/styles/overrides/tokens.css +288 -0
- package/dist/theme/styles/overrides/vscode.css +88 -0
- package/dist/theme/styles/themes/amber.css +545 -0
- package/dist/theme/styles/themes/arcade-fx.css +366 -0
- package/dist/theme/styles/themes/arcade.css +273 -0
- package/dist/theme/styles/themes/grannysmith.css +545 -0
- package/dist/theme/styles/themes/honeycrisp.css +545 -0
- package/dist/theme/styles/themes/midnight.css +273 -0
- package/dist/theme/styles/themes/mulled.css +817 -0
- package/package.json +103 -0
- package/src/theme/components/announcement/announcement-bar.css +103 -0
- package/src/theme/components/announcement/announcement-bar.tsx +173 -0
- package/src/theme/components/ask-ai/ask-ai-button.css +52 -0
- package/src/theme/components/ask-ai/ask-ai-button.tsx +56 -0
- package/src/theme/components/content-footer/content-footer-portal.tsx +70 -0
- package/src/theme/components/content-footer/feedback.css +47 -0
- package/src/theme/components/content-footer/feedback.tsx +96 -0
- package/src/theme/components/content-footer/meta-actions.css +25 -0
- package/src/theme/components/content-footer/meta-actions.tsx +57 -0
- package/src/theme/components/content-footer/page-pager.css +61 -0
- package/src/theme/components/content-footer/page-pager.tsx +110 -0
- package/src/theme/components/edit-source-button.tsx +97 -0
- package/src/theme/components/footer/site-footer.css +179 -0
- package/src/theme/components/footer/site-footer.tsx +115 -0
- package/src/theme/components/home/cta.css +67 -0
- package/src/theme/components/home/cta.tsx +77 -0
- package/src/theme/components/home/feature-card.css +52 -0
- package/src/theme/components/home/feature-card.tsx +131 -0
- package/src/theme/components/home/feature.tsx +79 -0
- package/src/theme/components/home/hero-demo.css +66 -0
- package/src/theme/components/home/hero-demo.tsx +46 -0
- package/src/theme/components/home/hero.css +96 -0
- package/src/theme/components/home/hero.tsx +111 -0
- package/src/theme/components/home/layout.tsx +183 -0
- package/src/theme/components/home/page-rail.css +21 -0
- package/src/theme/components/home/page-rail.tsx +19 -0
- package/src/theme/components/home/split.css +148 -0
- package/src/theme/components/home/split.tsx +120 -0
- package/src/theme/components/home/trust-strip.css +33 -0
- package/src/theme/components/home/trust-strip.tsx +43 -0
- package/src/theme/components/home/workspaces.tsx +71 -0
- package/src/theme/components/nav/branch-tag.css +54 -0
- package/src/theme/components/nav/branch-tag.tsx +101 -0
- package/src/theme/components/nav/ciderpress-doc-layout.tsx +247 -0
- package/src/theme/components/nav/ciderpress-docs-bar.css +505 -0
- package/src/theme/components/nav/ciderpress-docs-bar.tsx +426 -0
- package/src/theme/components/nav/ciderpress-header.css +172 -0
- package/src/theme/components/nav/ciderpress-header.tsx +113 -0
- package/src/theme/components/nav/ciderpress-layout-context.tsx +49 -0
- package/src/theme/components/nav/ciderpress-nav-hamburger.css +193 -0
- package/src/theme/components/nav/ciderpress-nav-hamburger.tsx +112 -0
- package/src/theme/components/nav/ciderpress-nav-menu.css +130 -0
- package/src/theme/components/nav/ciderpress-nav-menu.tsx +372 -0
- package/src/theme/components/nav/ciderpress-nav-search.css +73 -0
- package/src/theme/components/nav/ciderpress-nav-search.tsx +55 -0
- package/src/theme/components/nav/ciderpress-nav-social-links.css +35 -0
- package/src/theme/components/nav/ciderpress-nav-social-links.tsx +87 -0
- package/src/theme/components/nav/floating-branch-indicator.css +106 -0
- package/src/theme/components/nav/floating-branch-indicator.tsx +109 -0
- package/src/theme/components/nav/layout.tsx +268 -0
- package/src/theme/components/nav/mobile-nav-cta.tsx +79 -0
- package/src/theme/components/nav/nav-divider.css +15 -0
- package/src/theme/components/nav/nav-divider.tsx +19 -0
- package/src/theme/components/nav/nav-logo.css +42 -0
- package/src/theme/components/nav/nav-logo.tsx +262 -0
- package/src/theme/components/nav/theme-switcher.css +92 -0
- package/src/theme/components/nav/theme-switcher.tsx +298 -0
- package/src/theme/components/nav/topbar-cta.css +45 -0
- package/src/theme/components/nav/topbar-cta.tsx +39 -0
- package/src/theme/components/nav/variant-toggle.css +70 -0
- package/src/theme/components/nav/variant-toggle.tsx +83 -0
- package/src/theme/components/nav/version-chip.css +31 -0
- package/src/theme/components/nav/version-chip.tsx +45 -0
- package/src/theme/components/nav/vscode-tag.css +32 -0
- package/src/theme/components/nav/vscode-tag.tsx +20 -0
- package/src/theme/components/openapi/code-sample.tsx +341 -0
- package/src/theme/components/openapi/copy-markdown-button.tsx +41 -0
- package/src/theme/components/openapi/icons.tsx +45 -0
- package/src/theme/components/openapi/index.ts +6 -0
- package/src/theme/components/openapi/method-badge.tsx +24 -0
- package/src/theme/components/openapi/openapi.css +665 -0
- package/src/theme/components/openapi/operation.tsx +200 -0
- package/src/theme/components/openapi/overview.tsx +207 -0
- package/src/theme/components/openapi/parameters-table.tsx +149 -0
- package/src/theme/components/openapi/request-body.tsx +90 -0
- package/src/theme/components/openapi/response-list.tsx +112 -0
- package/src/theme/components/openapi/schema-viewer.tsx +277 -0
- package/src/theme/components/openapi/security-badges.tsx +63 -0
- package/src/theme/components/openapi/spec-utils.ts +122 -0
- package/src/theme/components/shared/accordion.css +118 -0
- package/src/theme/components/shared/accordion.stories.tsx +96 -0
- package/src/theme/components/shared/accordion.tsx +191 -0
- package/src/theme/components/shared/brand-logo.stories.tsx +49 -0
- package/src/theme/components/shared/brand-mark.stories.tsx +53 -0
- package/src/theme/components/shared/browser-window.css +1 -0
- package/src/theme/components/shared/browser-window.stories.tsx +100 -0
- package/src/theme/components/shared/browser-window.tsx +2 -0
- package/src/theme/components/shared/card.stories.tsx +50 -0
- package/src/theme/components/shared/card.tsx +35 -0
- package/src/theme/components/shared/ciderpress-logo.tsx +93 -0
- package/src/theme/components/shared/ciderpress-mark.tsx +77 -0
- package/src/theme/components/shared/color.css +56 -0
- package/src/theme/components/shared/color.stories.tsx +47 -0
- package/src/theme/components/shared/color.tsx +69 -0
- package/src/theme/components/shared/columns.css +37 -0
- package/src/theme/components/shared/columns.stories.tsx +91 -0
- package/src/theme/components/shared/columns.tsx +50 -0
- package/src/theme/components/shared/desktop-window.css +339 -0
- package/src/theme/components/shared/desktop-window.tsx +535 -0
- package/src/theme/components/shared/field.css +158 -0
- package/src/theme/components/shared/field.stories.tsx +100 -0
- package/src/theme/components/shared/field.tsx +186 -0
- package/src/theme/components/shared/frame.css +39 -0
- package/src/theme/components/shared/frame.stories.tsx +49 -0
- package/src/theme/components/shared/frame.tsx +76 -0
- package/src/theme/components/shared/icon.stories.tsx +90 -0
- package/src/theme/components/shared/icon.tsx +41 -0
- package/src/theme/components/shared/prompt.css +178 -0
- package/src/theme/components/shared/prompt.stories.tsx +57 -0
- package/src/theme/components/shared/prompt.tsx +369 -0
- package/src/theme/components/shared/resolve-card-icon.ts +28 -0
- package/src/theme/components/shared/section-card.stories.tsx +51 -0
- package/src/theme/components/shared/section-card.tsx +44 -0
- package/src/theme/components/shared/section-grid.stories.tsx +46 -0
- package/src/theme/components/shared/section-grid.tsx +15 -0
- package/src/theme/components/shared/status-badge.css +37 -0
- package/src/theme/components/shared/status-badge.stories.tsx +61 -0
- package/src/theme/components/shared/status-badge.tsx +74 -0
- package/src/theme/components/shared/steps.css +88 -0
- package/src/theme/components/shared/steps.stories.tsx +68 -0
- package/src/theme/components/shared/steps.tsx +100 -0
- package/src/theme/components/shared/tech-icon-table.stories.tsx +29 -0
- package/src/theme/components/shared/tech-icon-table.tsx +71 -0
- package/src/theme/components/shared/tech-tag.stories.tsx +40 -0
- package/src/theme/components/shared/tech-tag.tsx +31 -0
- package/src/theme/components/shared/theme-color-palette.css +80 -0
- package/src/theme/components/shared/theme-color-palette.stories.tsx +52 -0
- package/src/theme/components/shared/theme-color-palette.tsx +275 -0
- package/src/theme/components/shared/tooltip.css +69 -0
- package/src/theme/components/shared/tooltip.stories.tsx +72 -0
- package/src/theme/components/shared/tooltip.tsx +77 -0
- package/src/theme/components/sidebar/framework-picker.css +77 -0
- package/src/theme/components/sidebar/framework-picker.tsx +78 -0
- package/src/theme/components/sidebar/sidebar-filter.test.ts +140 -0
- package/src/theme/components/sidebar/sidebar-filter.ts +79 -0
- package/src/theme/components/sidebar/sidebar-links.css +102 -0
- package/src/theme/components/sidebar/sidebar-links.tsx +122 -0
- package/src/theme/components/sidebar/sidebar-promo.css +42 -0
- package/src/theme/components/sidebar/sidebar-promo.tsx +52 -0
- package/src/theme/components/sidebar/sidebar-scope.tsx +151 -0
- package/src/theme/components/sidebar/sidebar-toggle.css +181 -0
- package/src/theme/components/sidebar/sidebar-toggle.tsx +127 -0
- package/src/theme/components/theme-provider.tsx +637 -0
- package/src/theme/components/workspaces/card.css +151 -0
- package/src/theme/components/workspaces/card.tsx +166 -0
- package/src/theme/components/workspaces/grid.tsx +62 -0
- package/src/theme/css.d.ts +1 -0
- package/src/theme/env.d.ts +12 -0
- package/src/theme/fonts/GeistMono-Variable.woff2 +0 -0
- package/src/theme/fonts/GeistPixel-Square.woff2 +0 -0
- package/src/theme/fonts/GeistSans-Variable.woff2 +0 -0
- package/src/theme/hooks/use-ciderpress.ts +61 -0
- package/src/theme/hooks/use-nav-items.ts +76 -0
- package/src/theme/icons/index.ts +2 -0
- package/src/theme/icons/tech-map.ts +228 -0
- package/src/theme/index.tsx +180 -0
- package/src/theme/lib/read-social-links.ts +27 -0
- package/src/theme/lib/route-link.tsx +126 -0
- package/src/theme/lib/safe-url.test.ts +0 -0
- package/src/theme/lib/safe-url.ts +68 -0
- package/src/theme/lib/theme-favicon.ts +125 -0
- package/src/theme/lib/user-config-stub.ts +12 -0
- package/src/theme/styles/layers.css +32 -0
- package/src/theme/styles/overrides/badge.css +26 -0
- package/src/theme/styles/overrides/content-footer.css +80 -0
- package/src/theme/styles/overrides/details.css +61 -0
- package/src/theme/styles/overrides/fonts.css +32 -0
- package/src/theme/styles/overrides/home-card.css +133 -0
- package/src/theme/styles/overrides/home.css +243 -0
- package/src/theme/styles/overrides/rail.css +337 -0
- package/src/theme/styles/overrides/rspress.css +62 -0
- package/src/theme/styles/overrides/scrollbar.css +25 -0
- package/src/theme/styles/overrides/section-card.css +114 -0
- package/src/theme/styles/overrides/sidebar.css +144 -0
- package/src/theme/styles/overrides/tokens.css +288 -0
- package/src/theme/styles/overrides/vscode.css +88 -0
- package/src/theme/styles/themes/amber.css +545 -0
- package/src/theme/styles/themes/arcade-fx.css +366 -0
- package/src/theme/styles/themes/arcade.css +273 -0
- package/src/theme/styles/themes/grannysmith.css +545 -0
- package/src/theme/styles/themes/honeycrisp.css +545 -0
- package/src/theme/styles/themes/midnight.css +273 -0
- package/src/theme/styles/themes/mulled.css +817 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type React from 'react'
|
|
2
|
+
|
|
3
|
+
import { RouteLink } from '../../lib/route-link.tsx'
|
|
4
|
+
import { safeUrl } from '../../lib/safe-url.ts'
|
|
5
|
+
|
|
6
|
+
import './topbar-cta.css'
|
|
7
|
+
|
|
8
|
+
export interface TopbarCTAProps {
|
|
9
|
+
/**
|
|
10
|
+
* Button label.
|
|
11
|
+
*/
|
|
12
|
+
readonly text: string
|
|
13
|
+
/**
|
|
14
|
+
* Destination URL.
|
|
15
|
+
*/
|
|
16
|
+
readonly href: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* TopbarCTA — mint primary pill rendered at the right end of the topbar
|
|
21
|
+
* to drive the headline conversion (e.g. "Get started →").
|
|
22
|
+
*
|
|
23
|
+
* Renders `null` when `href` fails `safeUrl()` validation — config-driven
|
|
24
|
+
* hrefs must not become script-execution sinks.
|
|
25
|
+
*
|
|
26
|
+
* @param props - Button configuration.
|
|
27
|
+
* @returns React element, or `null` when the href fails URL validation.
|
|
28
|
+
*/
|
|
29
|
+
export function TopbarCTA(props: TopbarCTAProps): React.ReactElement | null {
|
|
30
|
+
const href = safeUrl(props.href)
|
|
31
|
+
if (href === null) {
|
|
32
|
+
return null
|
|
33
|
+
}
|
|
34
|
+
return (
|
|
35
|
+
<RouteLink className="cp-topbar-cta" href={href}>
|
|
36
|
+
{props.text}
|
|
37
|
+
</RouteLink>
|
|
38
|
+
)
|
|
39
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VariantToggle — sun/moon button that flips the active theme's variant.
|
|
3
|
+
*
|
|
4
|
+
* Both icons render into the DOM; CSS hides whichever doesn't match the
|
|
5
|
+
* current `html[data-cp-variant]` value. When dark, the sun is visible
|
|
6
|
+
* (click to go light); when light, the moon is visible (click to go
|
|
7
|
+
* dark) — the icon telegraphs the destination, matching the convention
|
|
8
|
+
* used by GitHub, Vercel, and most modern docs sites.
|
|
9
|
+
*
|
|
10
|
+
* Theme-author API:
|
|
11
|
+
* --cp-variant-toggle-size button width/height (default 32px)
|
|
12
|
+
* --cp-variant-toggle-radius border-radius (defaults to --rp-radius)
|
|
13
|
+
*/
|
|
14
|
+
.cp-variant-toggle {
|
|
15
|
+
display: inline-flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
justify-content: center;
|
|
18
|
+
width: var(--cp-variant-toggle-size, 32px);
|
|
19
|
+
height: var(--cp-variant-toggle-size, 32px);
|
|
20
|
+
padding: 0;
|
|
21
|
+
border: 1px solid var(--cp-c-border);
|
|
22
|
+
border-radius: var(--cp-variant-toggle-radius, var(--rp-radius));
|
|
23
|
+
background: var(--cp-c-bg);
|
|
24
|
+
color: var(--cp-c-text-2);
|
|
25
|
+
cursor: pointer;
|
|
26
|
+
transition:
|
|
27
|
+
color 0.2s,
|
|
28
|
+
border-color 0.2s;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.cp-variant-toggle:hover {
|
|
32
|
+
color: var(--cp-c-text-1);
|
|
33
|
+
border-color: var(--cp-c-brand-1);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/* ── Icon swap ─────────────────────────────────────────────────────
|
|
37
|
+
* Visibility is driven entirely by the `[data-cp-variant]` attribute
|
|
38
|
+
* set on `<html>` (by the head IIFE for first paint, then by the
|
|
39
|
+
* toggle's click handler).
|
|
40
|
+
* ──────────────────────────────────────────────────────────────── */
|
|
41
|
+
.cp-variant-toggle__icon {
|
|
42
|
+
display: none;
|
|
43
|
+
align-items: center;
|
|
44
|
+
justify-content: center;
|
|
45
|
+
line-height: 0;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
html[data-cp-variant='dark'] .cp-variant-toggle__icon--sun {
|
|
49
|
+
display: inline-flex;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
html[data-cp-variant='light'] .cp-variant-toggle__icon--moon {
|
|
53
|
+
display: inline-flex;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* SSR / pre-hydration fallback — before the head IIFE has set
|
|
57
|
+
`data-cp-variant`, neither selector above matches. Show the moon so
|
|
58
|
+
the button isn't empty during the first paint window. */
|
|
59
|
+
html:not([data-cp-variant]) .cp-variant-toggle__icon--moon {
|
|
60
|
+
display: inline-flex;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/* ── Single-variant themes — hide the toggle when the active theme
|
|
64
|
+
only ships one variant. Mirrors the existing rule that hides
|
|
65
|
+
Rspress's `.rp-switch-appearance` for the same reason (see
|
|
66
|
+
`styles/overrides/rspress.css`). ────────────────────────────── */
|
|
67
|
+
html[data-cp-variants='dark'] .cp-variant-toggle,
|
|
68
|
+
html[data-cp-variants='light'] .cp-variant-toggle {
|
|
69
|
+
display: none;
|
|
70
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { match } from 'massaman/match'
|
|
2
|
+
import { useCallback } from 'react'
|
|
3
|
+
import type React from 'react'
|
|
4
|
+
|
|
5
|
+
import { Icon } from '../shared/icon.tsx'
|
|
6
|
+
|
|
7
|
+
import './variant-toggle.css'
|
|
8
|
+
|
|
9
|
+
type Variant = 'dark' | 'light'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* VariantToggle — single button that flips between the active theme's
|
|
13
|
+
* dark and light variants. Both icons (sun + moon) live in the DOM and
|
|
14
|
+
* are toggled purely via CSS against `html[data-cp-variant]`, so the
|
|
15
|
+
* button carries no React state and survives SSR with no hydration
|
|
16
|
+
* mismatch.
|
|
17
|
+
*
|
|
18
|
+
* Hidden via `variant-toggle.css` when the active theme only declares
|
|
19
|
+
* one variant — mirrors the existing `[data-cp-variants]` rule that
|
|
20
|
+
* already hides Rspress's `.rp-switch-appearance`.
|
|
21
|
+
*
|
|
22
|
+
* Click handler mirrors the same DOM + `localStorage` writes the head
|
|
23
|
+
* IIFE and `<ThemeProvider />` perform — keep all three in sync.
|
|
24
|
+
*
|
|
25
|
+
* @returns Toggle button element
|
|
26
|
+
*/
|
|
27
|
+
export function VariantToggle(): React.ReactElement {
|
|
28
|
+
const handleClick = useCallback(() => {
|
|
29
|
+
const html = document.documentElement
|
|
30
|
+
const next = match(html.dataset.cpVariant)
|
|
31
|
+
.with('light', () => 'dark' as const)
|
|
32
|
+
.otherwise(() => 'light' as const)
|
|
33
|
+
applyVariant({ html, variant: next })
|
|
34
|
+
}, [])
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<button
|
|
38
|
+
type="button"
|
|
39
|
+
className="cp-variant-toggle"
|
|
40
|
+
onClick={handleClick}
|
|
41
|
+
aria-label="Toggle light and dark mode"
|
|
42
|
+
title="Toggle light and dark mode"
|
|
43
|
+
>
|
|
44
|
+
<span className="cp-variant-toggle__icon cp-variant-toggle__icon--sun">
|
|
45
|
+
<Icon icon="mdi:weather-sunny" width={16} height={16} />
|
|
46
|
+
</span>
|
|
47
|
+
<span className="cp-variant-toggle__icon cp-variant-toggle__icon--moon">
|
|
48
|
+
<Icon icon="mdi:weather-night" width={16} height={16} />
|
|
49
|
+
</span>
|
|
50
|
+
</button>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { VariantToggle as default }
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Apply the new variant to the DOM and persist it. Mirrors the writes
|
|
58
|
+
* performed by `buildHeadScriptBody` (head IIFE in
|
|
59
|
+
* `packages/ui/src/config.ts`) and `<ThemeProvider />`'s `applyVariant`
|
|
60
|
+
* so the three sources of truth never diverge.
|
|
61
|
+
*
|
|
62
|
+
* @private
|
|
63
|
+
* @param params - HTML element and target variant
|
|
64
|
+
*/
|
|
65
|
+
function applyVariant(params: { readonly html: HTMLElement; readonly variant: Variant }): void {
|
|
66
|
+
const { html, variant } = params
|
|
67
|
+
html.dataset.cpVariant = variant
|
|
68
|
+
match(variant)
|
|
69
|
+
.with('dark', () => {
|
|
70
|
+
html.classList.add('rp-dark', 'dark')
|
|
71
|
+
html.dataset.dark = 'true'
|
|
72
|
+
})
|
|
73
|
+
.otherwise(() => {
|
|
74
|
+
html.classList.remove('rp-dark', 'dark')
|
|
75
|
+
html.dataset.dark = 'false'
|
|
76
|
+
})
|
|
77
|
+
try {
|
|
78
|
+
localStorage.setItem('rspress-theme-appearance', variant)
|
|
79
|
+
localStorage.setItem('ciderpress-variant', variant)
|
|
80
|
+
} catch {
|
|
81
|
+
// storage unavailable (privacy mode, quota) — DOM is still correct
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/* Make the Rspress brand title row flex so the portalled VersionChip
|
|
2
|
+
sits inline with the logo/text instead of stacking below it. */
|
|
3
|
+
html .rp-nav__title {
|
|
4
|
+
display: inline-flex;
|
|
5
|
+
align-items: center;
|
|
6
|
+
gap: 0;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.cp-version-chip {
|
|
10
|
+
display: inline-flex;
|
|
11
|
+
align-items: center;
|
|
12
|
+
gap: 10px;
|
|
13
|
+
white-space: nowrap;
|
|
14
|
+
margin-left: 10px;
|
|
15
|
+
height: 22px;
|
|
16
|
+
line-height: 1;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.cp-version-chip__divider {
|
|
20
|
+
display: inline-block;
|
|
21
|
+
width: 1px;
|
|
22
|
+
height: 16px;
|
|
23
|
+
background: var(--cp-c-border);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.cp-version-chip__text {
|
|
27
|
+
font-family: var(--cp-font-family-mono);
|
|
28
|
+
font-size: 11px;
|
|
29
|
+
font-weight: 400;
|
|
30
|
+
color: var(--cp-c-text-3);
|
|
31
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react'
|
|
2
|
+
import { createPortal } from 'react-dom'
|
|
3
|
+
|
|
4
|
+
import './version-chip.css'
|
|
5
|
+
|
|
6
|
+
export interface VersionChipProps {
|
|
7
|
+
/**
|
|
8
|
+
* Version label, e.g. "v0.5".
|
|
9
|
+
*/
|
|
10
|
+
readonly version: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* VersionChip — small mono label rendered next to the topbar brand to
|
|
15
|
+
* advertise the active package version. Renders a thin vertical divider
|
|
16
|
+
* before the version text so it visually attaches to the brand:
|
|
17
|
+
* `ciderpress | v0.5`.
|
|
18
|
+
*
|
|
19
|
+
* Portals into `.rp-nav__title` so the chip sits directly beside the
|
|
20
|
+
* Rspress logo/title rather than in the nav-menu area. Falls back to
|
|
21
|
+
* inline rendering when the title node is not yet mounted.
|
|
22
|
+
*
|
|
23
|
+
* @param props - Version chip configuration.
|
|
24
|
+
* @returns React element.
|
|
25
|
+
*/
|
|
26
|
+
export function VersionChip(props: VersionChipProps): React.ReactElement | null {
|
|
27
|
+
const [target, setTarget] = useState<HTMLElement | null>(null)
|
|
28
|
+
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
const el = globalThis.document.querySelector('.rp-nav__title') as HTMLElement | null
|
|
31
|
+
setTarget(el)
|
|
32
|
+
}, [])
|
|
33
|
+
|
|
34
|
+
const chip = (
|
|
35
|
+
<span className="cp-version-chip">
|
|
36
|
+
<span className="cp-version-chip__divider" aria-hidden="true" />
|
|
37
|
+
<span className="cp-version-chip__text">{props.version}</span>
|
|
38
|
+
</span>
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
if (target === null) {
|
|
42
|
+
return null
|
|
43
|
+
}
|
|
44
|
+
return createPortal(chip, target)
|
|
45
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VS Code tag pill — mode indicator badge positioned in the nav bar.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
.cp-vscode-tag {
|
|
6
|
+
display: inline-flex;
|
|
7
|
+
align-items: center;
|
|
8
|
+
gap: 5px;
|
|
9
|
+
margin-left: 6px;
|
|
10
|
+
padding: 3px 10px;
|
|
11
|
+
border-radius: 20px;
|
|
12
|
+
background: var(--cp-c-bg-soft);
|
|
13
|
+
border: 1px solid var(--cp-c-brand-1, #60a5fa);
|
|
14
|
+
color: var(--cp-c-brand-1, #60a5fa);
|
|
15
|
+
font-family: var(--cp-font-family-mono);
|
|
16
|
+
font-size: 11px;
|
|
17
|
+
font-weight: 600;
|
|
18
|
+
line-height: 1;
|
|
19
|
+
white-space: nowrap;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.cp-vscode-tag svg {
|
|
23
|
+
width: 14px;
|
|
24
|
+
height: 14px;
|
|
25
|
+
flex-shrink: 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@media (max-width: 768px) {
|
|
29
|
+
.cp-vscode-tag__text {
|
|
30
|
+
display: none;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type React from 'react'
|
|
2
|
+
|
|
3
|
+
import './vscode-tag.css'
|
|
4
|
+
import { Icon } from '../shared/icon.tsx'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* VS Code mode indicator — pill-shaped badge rendered next to the
|
|
8
|
+
* BranchTag when the page is loaded inside the VS Code webview
|
|
9
|
+
* (detected via `?env=vscode` query parameter).
|
|
10
|
+
*
|
|
11
|
+
* @returns React element with the VS Code badge
|
|
12
|
+
*/
|
|
13
|
+
export function VscodeTag(): React.ReactElement {
|
|
14
|
+
return (
|
|
15
|
+
<span className="cp-vscode-tag" title="VS Code preview mode" aria-label="VS Code preview mode">
|
|
16
|
+
<Icon icon="vscode-icons:file-type-vscode" width={14} height={14} />
|
|
17
|
+
<span className="cp-vscode-tag__text">vscode</span>
|
|
18
|
+
</span>
|
|
19
|
+
)
|
|
20
|
+
}
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
import { CodeBlockRuntime } from '@rspress/core/theme'
|
|
2
|
+
import { match, P } from 'massaman/match'
|
|
3
|
+
import type React from 'react'
|
|
4
|
+
import { useState } from 'react'
|
|
5
|
+
|
|
6
|
+
import { extractBodyExample, isBodyMethod } from './spec-utils'
|
|
7
|
+
|
|
8
|
+
export interface CodeSampleProps {
|
|
9
|
+
/**
|
|
10
|
+
* HTTP method (get, post, etc.).
|
|
11
|
+
*/
|
|
12
|
+
readonly method: string
|
|
13
|
+
/**
|
|
14
|
+
* URL path (e.g. /users/{id}).
|
|
15
|
+
*/
|
|
16
|
+
readonly path: string
|
|
17
|
+
/**
|
|
18
|
+
* Base URL for the API server.
|
|
19
|
+
*/
|
|
20
|
+
readonly baseUrl: string
|
|
21
|
+
/**
|
|
22
|
+
* Operation parameters for generating sample values.
|
|
23
|
+
*/
|
|
24
|
+
readonly parameters?: readonly Record<string, unknown>[]
|
|
25
|
+
/**
|
|
26
|
+
* Request body for POST/PUT/PATCH examples.
|
|
27
|
+
*/
|
|
28
|
+
readonly requestBody?: Record<string, unknown>
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface TabConfig {
|
|
32
|
+
readonly label: string
|
|
33
|
+
readonly lang: string
|
|
34
|
+
readonly generator: (props: CodeSampleProps) => string
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const TABS: readonly TabConfig[] = [
|
|
38
|
+
{ label: 'cURL', lang: 'bash', generator: generateCurl },
|
|
39
|
+
{ label: 'JavaScript', lang: 'javascript', generator: generateJavascript },
|
|
40
|
+
{ label: 'Python', lang: 'python', generator: generatePython },
|
|
41
|
+
{ label: 'Go', lang: 'go', generator: generateGo },
|
|
42
|
+
{ label: 'Ruby', lang: 'ruby', generator: generateRuby },
|
|
43
|
+
{ label: 'Java', lang: 'java', generator: generateJava },
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Auto-generated code examples for an API operation.
|
|
48
|
+
*
|
|
49
|
+
* Renders cURL, JavaScript, Python, Go, Ruby, and Java code
|
|
50
|
+
* using Rspress's CodeBlockRuntime for full syntax highlighting.
|
|
51
|
+
*
|
|
52
|
+
* @param props - Code sample props including method, path, baseUrl, and optional body
|
|
53
|
+
* @returns React element with tabbed code examples
|
|
54
|
+
*/
|
|
55
|
+
export function CodeSample(props: CodeSampleProps): React.ReactElement {
|
|
56
|
+
const [activeTab, setActiveTab] = useState<string>('cURL')
|
|
57
|
+
|
|
58
|
+
const activeConfig = TABS.find((tab) => tab.label === activeTab)
|
|
59
|
+
const resolved = match(activeConfig)
|
|
60
|
+
.with(P.nonNullable, (config) => ({
|
|
61
|
+
code: config.generator(props),
|
|
62
|
+
lang: config.lang,
|
|
63
|
+
}))
|
|
64
|
+
.otherwise(() => ({ code: generateCurl(props), lang: 'bash' }))
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<div className="cp-oas-code-sample">
|
|
68
|
+
<div className="cp-oas-code-sample__title">Code Examples</div>
|
|
69
|
+
<div className="cp-oas-code-sample__tabs">
|
|
70
|
+
{TABS.map((tab) => (
|
|
71
|
+
<button
|
|
72
|
+
key={tab.label}
|
|
73
|
+
type="button"
|
|
74
|
+
className={match(activeTab === tab.label)
|
|
75
|
+
.with(true, () => 'cp-oas-code-sample__tab cp-oas-code-sample__tab--active')
|
|
76
|
+
.otherwise(() => 'cp-oas-code-sample__tab')}
|
|
77
|
+
onClick={() => {
|
|
78
|
+
setActiveTab(tab.label)
|
|
79
|
+
}}
|
|
80
|
+
>
|
|
81
|
+
{tab.label}
|
|
82
|
+
</button>
|
|
83
|
+
))}
|
|
84
|
+
</div>
|
|
85
|
+
<div className="cp-oas-code-sample__block">
|
|
86
|
+
<CodeBlockRuntime lang={resolved.lang} code={resolved.code} />
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Build a full URL from base URL and path.
|
|
94
|
+
*
|
|
95
|
+
* @private
|
|
96
|
+
* @param input - Object with baseUrl and path
|
|
97
|
+
* @returns Full URL string
|
|
98
|
+
*/
|
|
99
|
+
function buildUrl(input: { readonly baseUrl: string; readonly path: string }): string {
|
|
100
|
+
const base = input.baseUrl.replace(/\/+$/, '')
|
|
101
|
+
if (input.path.startsWith('/')) {
|
|
102
|
+
return `${base}${input.path}`
|
|
103
|
+
}
|
|
104
|
+
return `${base}/${input.path}`
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Generate a cURL code example for the operation.
|
|
109
|
+
*
|
|
110
|
+
* @private
|
|
111
|
+
* @param props - Code sample props
|
|
112
|
+
* @returns cURL command string
|
|
113
|
+
*/
|
|
114
|
+
function generateCurl(props: CodeSampleProps): string {
|
|
115
|
+
const url = buildUrl({ baseUrl: props.baseUrl, path: props.path })
|
|
116
|
+
const method = props.method.toUpperCase()
|
|
117
|
+
const headers = match(isBodyMethod(props.method.toLowerCase()))
|
|
118
|
+
.with(true, () => " \\\n -H 'Content-Type: application/json'")
|
|
119
|
+
.otherwise(() => '')
|
|
120
|
+
const body = match(extractBodyExample(props.requestBody))
|
|
121
|
+
.with(P.nonNullable, (ex) => ` \\\n -d '${JSON.stringify(ex)}'`)
|
|
122
|
+
.otherwise(() => '')
|
|
123
|
+
return `curl -X ${method} '${url}'${headers}${body}`
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Generate a Python requests code example for the operation.
|
|
128
|
+
*
|
|
129
|
+
* @private
|
|
130
|
+
* @param props - Code sample props
|
|
131
|
+
* @returns Python code string
|
|
132
|
+
*/
|
|
133
|
+
function generatePython(props: CodeSampleProps): string {
|
|
134
|
+
const url = buildUrl({ baseUrl: props.baseUrl, path: props.path })
|
|
135
|
+
const method = props.method.toLowerCase()
|
|
136
|
+
const bodyExample = extractBodyExample(props.requestBody)
|
|
137
|
+
const hasBody = isBodyMethod(method) && bodyExample !== null
|
|
138
|
+
|
|
139
|
+
const payloadLines = match(hasBody)
|
|
140
|
+
.with(true, () => [`payload = ${JSON.stringify(bodyExample, null, 4)}`, ''])
|
|
141
|
+
.otherwise(() => [])
|
|
142
|
+
|
|
143
|
+
const jsonArg = match(hasBody)
|
|
144
|
+
.with(true, () => ',\n json=payload')
|
|
145
|
+
.otherwise(() => '')
|
|
146
|
+
|
|
147
|
+
return [
|
|
148
|
+
'import requests',
|
|
149
|
+
'',
|
|
150
|
+
...payloadLines,
|
|
151
|
+
`response = requests.${method}(`,
|
|
152
|
+
` "${url}"${jsonArg}`,
|
|
153
|
+
')',
|
|
154
|
+
'',
|
|
155
|
+
'print(response.json())',
|
|
156
|
+
].join('\n')
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Generate a JavaScript fetch code example for the operation.
|
|
161
|
+
*
|
|
162
|
+
* @private
|
|
163
|
+
* @param props - Code sample props
|
|
164
|
+
* @returns JavaScript code string
|
|
165
|
+
*/
|
|
166
|
+
function generateJavascript(props: CodeSampleProps): string {
|
|
167
|
+
const url = buildUrl({ baseUrl: props.baseUrl, path: props.path })
|
|
168
|
+
const method = props.method.toUpperCase()
|
|
169
|
+
const hasBody = isBodyMethod(props.method.toLowerCase())
|
|
170
|
+
const bodyExample = extractBodyExample(props.requestBody)
|
|
171
|
+
|
|
172
|
+
const headersStr = match(hasBody)
|
|
173
|
+
.with(true, () => "\n headers: { 'Content-Type': 'application/json' },")
|
|
174
|
+
.otherwise(() => '')
|
|
175
|
+
|
|
176
|
+
const bodyStr = match(hasBody && bodyExample !== null)
|
|
177
|
+
.with(true, () => `\n body: JSON.stringify(${JSON.stringify(bodyExample, null, 2)}),`)
|
|
178
|
+
.otherwise(() => '')
|
|
179
|
+
|
|
180
|
+
return [
|
|
181
|
+
`const response = await fetch('${url}', {`,
|
|
182
|
+
` method: '${method}',${headersStr}${bodyStr}`,
|
|
183
|
+
'})',
|
|
184
|
+
'',
|
|
185
|
+
'const data = await response.json()',
|
|
186
|
+
'console.log(data)',
|
|
187
|
+
].join('\n')
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Generate a Go net/http code example for the operation.
|
|
192
|
+
*
|
|
193
|
+
* @private
|
|
194
|
+
* @param props - Code sample props
|
|
195
|
+
* @returns Go code string
|
|
196
|
+
*/
|
|
197
|
+
function generateGo(props: CodeSampleProps): string {
|
|
198
|
+
const url = buildUrl({ baseUrl: props.baseUrl, path: props.path })
|
|
199
|
+
const method = props.method.toUpperCase()
|
|
200
|
+
const hasBody = isBodyMethod(props.method.toLowerCase())
|
|
201
|
+
const bodyExample = extractBodyExample(props.requestBody)
|
|
202
|
+
|
|
203
|
+
const hasBodyPayload = hasBody && bodyExample !== null
|
|
204
|
+
const escapedBody = match(hasBodyPayload)
|
|
205
|
+
.with(true, () => JSON.stringify(bodyExample).replaceAll('"', String.raw`\"`))
|
|
206
|
+
.otherwise(() => '')
|
|
207
|
+
|
|
208
|
+
const bodySetup = match(hasBodyPayload)
|
|
209
|
+
.with(true, () =>
|
|
210
|
+
[
|
|
211
|
+
`\tpayload := strings.NewReader("${escapedBody}")`,
|
|
212
|
+
`\treq, err := http.NewRequest("${method}", "${url}", payload)`,
|
|
213
|
+
].join('\n')
|
|
214
|
+
)
|
|
215
|
+
.otherwise(() => `\treq, err := http.NewRequest("${method}", "${url}", nil)`)
|
|
216
|
+
|
|
217
|
+
const contentTypeHeader = match(hasBody)
|
|
218
|
+
.with(true, () => '\treq.Header.Set("Content-Type", "application/json")')
|
|
219
|
+
.otherwise(() => '')
|
|
220
|
+
|
|
221
|
+
const stringsImport = match(hasBodyPayload)
|
|
222
|
+
.with(true, () => ['\t"strings"'])
|
|
223
|
+
.otherwise(() => [])
|
|
224
|
+
|
|
225
|
+
return [
|
|
226
|
+
'package main',
|
|
227
|
+
'',
|
|
228
|
+
'import (',
|
|
229
|
+
'\t"fmt"',
|
|
230
|
+
'\t"io"',
|
|
231
|
+
'\t"net/http"',
|
|
232
|
+
...stringsImport,
|
|
233
|
+
')',
|
|
234
|
+
'',
|
|
235
|
+
'func main() {',
|
|
236
|
+
bodySetup,
|
|
237
|
+
'\tif err != nil {',
|
|
238
|
+
'\t\tpanic(err)',
|
|
239
|
+
'\t}',
|
|
240
|
+
contentTypeHeader,
|
|
241
|
+
'',
|
|
242
|
+
'\tresp, err := http.DefaultClient.Do(req)',
|
|
243
|
+
'\tif err != nil {',
|
|
244
|
+
'\t\tpanic(err)',
|
|
245
|
+
'\t}',
|
|
246
|
+
'\tdefer resp.Body.Close()',
|
|
247
|
+
'',
|
|
248
|
+
'\tbody, _ := io.ReadAll(resp.Body)',
|
|
249
|
+
'\tfmt.Println(string(body))',
|
|
250
|
+
'}',
|
|
251
|
+
].join('\n')
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Generate a Ruby net/http code example for the operation.
|
|
256
|
+
*
|
|
257
|
+
* @private
|
|
258
|
+
* @param props - Code sample props
|
|
259
|
+
* @returns Ruby code string
|
|
260
|
+
*/
|
|
261
|
+
function generateRuby(props: CodeSampleProps): string {
|
|
262
|
+
const url = buildUrl({ baseUrl: props.baseUrl, path: props.path })
|
|
263
|
+
const method = props.method.toLowerCase()
|
|
264
|
+
const hasBody = isBodyMethod(method)
|
|
265
|
+
const bodyExample = extractBodyExample(props.requestBody)
|
|
266
|
+
|
|
267
|
+
const uriLines = ["require 'net/http'", "require 'json'", '', `uri = URI('${url}')`]
|
|
268
|
+
|
|
269
|
+
const methodClass = match(method)
|
|
270
|
+
.with('get', () => 'Get')
|
|
271
|
+
.with('post', () => 'Post')
|
|
272
|
+
.with('put', () => 'Put')
|
|
273
|
+
.with('patch', () => 'Patch')
|
|
274
|
+
.with('delete', () => 'Delete')
|
|
275
|
+
.otherwise(() => 'Get')
|
|
276
|
+
|
|
277
|
+
const requestLines = [`request = Net::HTTP::${methodClass}.new(uri)`]
|
|
278
|
+
|
|
279
|
+
const bodyLines = match(hasBody && bodyExample !== null)
|
|
280
|
+
.with(true, () => [
|
|
281
|
+
"request['Content-Type'] = 'application/json'",
|
|
282
|
+
`request.body = '${JSON.stringify(bodyExample)}'`,
|
|
283
|
+
])
|
|
284
|
+
.otherwise(() => [])
|
|
285
|
+
|
|
286
|
+
return [
|
|
287
|
+
...uriLines,
|
|
288
|
+
...requestLines,
|
|
289
|
+
...bodyLines,
|
|
290
|
+
'',
|
|
291
|
+
`response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: ${String(props.baseUrl.startsWith('https'))}) do |http|`,
|
|
292
|
+
' http.request(request)',
|
|
293
|
+
'end',
|
|
294
|
+
'',
|
|
295
|
+
'puts JSON.parse(response.body)',
|
|
296
|
+
].join('\n')
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Generate a Java HttpClient code example for the operation.
|
|
301
|
+
*
|
|
302
|
+
* @private
|
|
303
|
+
* @param props - Code sample props
|
|
304
|
+
* @returns Java code string
|
|
305
|
+
*/
|
|
306
|
+
function generateJava(props: CodeSampleProps): string {
|
|
307
|
+
const url = buildUrl({ baseUrl: props.baseUrl, path: props.path })
|
|
308
|
+
const method = props.method.toUpperCase()
|
|
309
|
+
const hasBody = isBodyMethod(props.method.toLowerCase())
|
|
310
|
+
const bodyExample = extractBodyExample(props.requestBody)
|
|
311
|
+
|
|
312
|
+
const builderMethod = match(hasBody && bodyExample !== null)
|
|
313
|
+
.with(
|
|
314
|
+
true,
|
|
315
|
+
() =>
|
|
316
|
+
` .method("${method}", HttpRequest.BodyPublishers.ofString("${JSON.stringify(bodyExample).replaceAll('"', String.raw`\"`)}"))`
|
|
317
|
+
)
|
|
318
|
+
.otherwise(() => ` .method("${method}", HttpRequest.BodyPublishers.noBody())`)
|
|
319
|
+
|
|
320
|
+
const contentTypeHeader = match(hasBody)
|
|
321
|
+
.with(true, () => '\n .header("Content-Type", "application/json")')
|
|
322
|
+
.otherwise(() => '')
|
|
323
|
+
|
|
324
|
+
return [
|
|
325
|
+
'import java.net.http.*;',
|
|
326
|
+
'import java.net.URI;',
|
|
327
|
+
'',
|
|
328
|
+
'HttpClient client = HttpClient.newHttpClient();',
|
|
329
|
+
'',
|
|
330
|
+
'HttpRequest request = HttpRequest.newBuilder()',
|
|
331
|
+
` .uri(URI.create("${url}"))`,
|
|
332
|
+
`${builderMethod}${contentTypeHeader}`,
|
|
333
|
+
' .build();',
|
|
334
|
+
'',
|
|
335
|
+
'HttpResponse<String> response = client.send(',
|
|
336
|
+
' request, HttpResponse.BodyHandlers.ofString()',
|
|
337
|
+
');',
|
|
338
|
+
'',
|
|
339
|
+
'System.out.println(response.body());',
|
|
340
|
+
].join('\n')
|
|
341
|
+
}
|