jamdesk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +323 -0
- package/bin/jamdesk.js +76 -0
- package/dist/__tests__/integration/deprecated-components.integration.test.d.ts +8 -0
- package/dist/__tests__/integration/deprecated-components.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/deprecated-components.integration.test.js +165 -0
- package/dist/__tests__/integration/deprecated-components.integration.test.js.map +1 -0
- package/dist/__tests__/integration/migrate.integration.test.d.ts +2 -0
- package/dist/__tests__/integration/migrate.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/migrate.integration.test.js +64 -0
- package/dist/__tests__/integration/migrate.integration.test.js.map +1 -0
- package/dist/__tests__/integration/prepublish.integration.test.d.ts +2 -0
- package/dist/__tests__/integration/prepublish.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/prepublish.integration.test.js +27 -0
- package/dist/__tests__/integration/prepublish.integration.test.js.map +1 -0
- package/dist/__tests__/integration/validate.integration.test.d.ts +2 -0
- package/dist/__tests__/integration/validate.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/validate.integration.test.js +56 -0
- package/dist/__tests__/integration/validate.integration.test.js.map +1 -0
- package/dist/__tests__/unit/deploy-templates.test.d.ts +2 -0
- package/dist/__tests__/unit/deploy-templates.test.d.ts.map +1 -0
- package/dist/__tests__/unit/deploy-templates.test.js +124 -0
- package/dist/__tests__/unit/deploy-templates.test.js.map +1 -0
- package/dist/__tests__/unit/deprecated-components-sync.test.d.ts +2 -0
- package/dist/__tests__/unit/deprecated-components-sync.test.d.ts.map +1 -0
- package/dist/__tests__/unit/deprecated-components-sync.test.js +69 -0
- package/dist/__tests__/unit/deprecated-components-sync.test.js.map +1 -0
- package/dist/__tests__/unit/deps-sync.test.d.ts +14 -0
- package/dist/__tests__/unit/deps-sync.test.d.ts.map +1 -0
- package/dist/__tests__/unit/deps-sync.test.js +166 -0
- package/dist/__tests__/unit/deps-sync.test.js.map +1 -0
- package/dist/__tests__/unit/docs-config.test.d.ts +2 -0
- package/dist/__tests__/unit/docs-config.test.d.ts.map +1 -0
- package/dist/__tests__/unit/docs-config.test.js +288 -0
- package/dist/__tests__/unit/docs-config.test.js.map +1 -0
- package/dist/__tests__/unit/errors.test.d.ts +2 -0
- package/dist/__tests__/unit/errors.test.d.ts.map +1 -0
- package/dist/__tests__/unit/errors.test.js +27 -0
- package/dist/__tests__/unit/errors.test.js.map +1 -0
- package/dist/__tests__/unit/extract-hooks.test.d.ts +5 -0
- package/dist/__tests__/unit/extract-hooks.test.d.ts.map +1 -0
- package/dist/__tests__/unit/extract-hooks.test.js +205 -0
- package/dist/__tests__/unit/extract-hooks.test.js.map +1 -0
- package/dist/__tests__/unit/frontmatter-sync.test.d.ts +8 -0
- package/dist/__tests__/unit/frontmatter-sync.test.d.ts.map +1 -0
- package/dist/__tests__/unit/frontmatter-sync.test.js +26 -0
- package/dist/__tests__/unit/frontmatter-sync.test.js.map +1 -0
- package/dist/__tests__/unit/mdx-validator.test.d.ts +2 -0
- package/dist/__tests__/unit/mdx-validator.test.d.ts.map +1 -0
- package/dist/__tests__/unit/mdx-validator.test.js +264 -0
- package/dist/__tests__/unit/mdx-validator.test.js.map +1 -0
- package/dist/__tests__/unit/migrate-convert.test.d.ts +2 -0
- package/dist/__tests__/unit/migrate-convert.test.d.ts.map +1 -0
- package/dist/__tests__/unit/migrate-convert.test.js +297 -0
- package/dist/__tests__/unit/migrate-convert.test.js.map +1 -0
- package/dist/__tests__/unit/migrate-detect.test.d.ts +2 -0
- package/dist/__tests__/unit/migrate-detect.test.d.ts.map +1 -0
- package/dist/__tests__/unit/migrate-detect.test.js +35 -0
- package/dist/__tests__/unit/migrate-detect.test.js.map +1 -0
- package/dist/__tests__/unit/migrate-mdx.test.d.ts +2 -0
- package/dist/__tests__/unit/migrate-mdx.test.d.ts.map +1 -0
- package/dist/__tests__/unit/migrate-mdx.test.js +158 -0
- package/dist/__tests__/unit/migrate-mdx.test.js.map +1 -0
- package/dist/__tests__/unit/openapi.test.d.ts +2 -0
- package/dist/__tests__/unit/openapi.test.d.ts.map +1 -0
- package/dist/__tests__/unit/openapi.test.js +52 -0
- package/dist/__tests__/unit/openapi.test.js.map +1 -0
- package/dist/__tests__/unit/package-config.test.d.ts +2 -0
- package/dist/__tests__/unit/package-config.test.d.ts.map +1 -0
- package/dist/__tests__/unit/package-config.test.js +63 -0
- package/dist/__tests__/unit/package-config.test.js.map +1 -0
- package/dist/__tests__/unit/port.test.d.ts +2 -0
- package/dist/__tests__/unit/port.test.d.ts.map +1 -0
- package/dist/__tests__/unit/port.test.js +20 -0
- package/dist/__tests__/unit/port.test.js.map +1 -0
- package/dist/__tests__/unit/vendored-sync.test.d.ts +14 -0
- package/dist/__tests__/unit/vendored-sync.test.d.ts.map +1 -0
- package/dist/__tests__/unit/vendored-sync.test.js +90 -0
- package/dist/__tests__/unit/vendored-sync.test.js.map +1 -0
- package/dist/commands/broken-links.d.ts +11 -0
- package/dist/commands/broken-links.d.ts.map +1 -0
- package/dist/commands/broken-links.js +95 -0
- package/dist/commands/broken-links.js.map +1 -0
- package/dist/commands/clean.d.ts +7 -0
- package/dist/commands/clean.d.ts.map +1 -0
- package/dist/commands/clean.js +59 -0
- package/dist/commands/clean.js.map +1 -0
- package/dist/commands/deploy/cloudflare.d.ts +12 -0
- package/dist/commands/deploy/cloudflare.d.ts.map +1 -0
- package/dist/commands/deploy/cloudflare.js +409 -0
- package/dist/commands/deploy/cloudflare.js.map +1 -0
- package/dist/commands/deploy/templates.d.ts +23 -0
- package/dist/commands/deploy/templates.d.ts.map +1 -0
- package/dist/commands/deploy/templates.js +179 -0
- package/dist/commands/deploy/templates.js.map +1 -0
- package/dist/commands/deploy/types.d.ts +19 -0
- package/dist/commands/deploy/types.d.ts.map +1 -0
- package/dist/commands/deploy/types.js +5 -0
- package/dist/commands/deploy/types.js.map +1 -0
- package/dist/commands/dev.d.ts +14 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +817 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/doctor.d.ts +7 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +159 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +7 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +96 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/migrate/convert-mdx.d.ts +50 -0
- package/dist/commands/migrate/convert-mdx.d.ts.map +1 -0
- package/dist/commands/migrate/convert-mdx.js +108 -0
- package/dist/commands/migrate/convert-mdx.js.map +1 -0
- package/dist/commands/migrate/convert.d.ts +80 -0
- package/dist/commands/migrate/convert.d.ts.map +1 -0
- package/dist/commands/migrate/convert.js +158 -0
- package/dist/commands/migrate/convert.js.map +1 -0
- package/dist/commands/migrate/detect.d.ts +31 -0
- package/dist/commands/migrate/detect.d.ts.map +1 -0
- package/dist/commands/migrate/detect.js +62 -0
- package/dist/commands/migrate/detect.js.map +1 -0
- package/dist/commands/migrate/extract-hooks.d.ts +71 -0
- package/dist/commands/migrate/extract-hooks.d.ts.map +1 -0
- package/dist/commands/migrate/extract-hooks.js +473 -0
- package/dist/commands/migrate/extract-hooks.js.map +1 -0
- package/dist/commands/migrate/index.d.ts +17 -0
- package/dist/commands/migrate/index.d.ts.map +1 -0
- package/dist/commands/migrate/index.js +282 -0
- package/dist/commands/migrate/index.js.map +1 -0
- package/dist/commands/migrate/prompts.d.ts +22 -0
- package/dist/commands/migrate/prompts.d.ts.map +1 -0
- package/dist/commands/migrate/prompts.js +67 -0
- package/dist/commands/migrate/prompts.js.map +1 -0
- package/dist/commands/migrate/types.d.ts +22 -0
- package/dist/commands/migrate/types.d.ts.map +1 -0
- package/dist/commands/migrate/types.js +26 -0
- package/dist/commands/migrate/types.js.map +1 -0
- package/dist/commands/openapi-check.d.ts +11 -0
- package/dist/commands/openapi-check.d.ts.map +1 -0
- package/dist/commands/openapi-check.js +88 -0
- package/dist/commands/openapi-check.js.map +1 -0
- package/dist/commands/rename.d.ts +10 -0
- package/dist/commands/rename.d.ts.map +1 -0
- package/dist/commands/rename.js +125 -0
- package/dist/commands/rename.js.map +1 -0
- package/dist/commands/update.d.ts +10 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +57 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/validate.d.ts +12 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +163 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +334 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/config.d.ts +7 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +18 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/deprecated-components.d.ts +72 -0
- package/dist/lib/deprecated-components.d.ts.map +1 -0
- package/dist/lib/deprecated-components.js +138 -0
- package/dist/lib/deprecated-components.js.map +1 -0
- package/dist/lib/deps.d.ts +17 -0
- package/dist/lib/deps.d.ts.map +1 -0
- package/dist/lib/deps.js +186 -0
- package/dist/lib/deps.js.map +1 -0
- package/dist/lib/docs-config.d.ts +67 -0
- package/dist/lib/docs-config.d.ts.map +1 -0
- package/dist/lib/docs-config.js +294 -0
- package/dist/lib/docs-config.js.map +1 -0
- package/dist/lib/errors.d.ts +23 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +32 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/frontmatter-utils.d.ts +25 -0
- package/dist/lib/frontmatter-utils.d.ts.map +1 -0
- package/dist/lib/frontmatter-utils.js +64 -0
- package/dist/lib/frontmatter-utils.js.map +1 -0
- package/dist/lib/mdx-validator.d.ts +27 -0
- package/dist/lib/mdx-validator.d.ts.map +1 -0
- package/dist/lib/mdx-validator.js +148 -0
- package/dist/lib/mdx-validator.js.map +1 -0
- package/dist/lib/navigation-validator.d.ts +31 -0
- package/dist/lib/navigation-validator.d.ts.map +1 -0
- package/dist/lib/navigation-validator.js +75 -0
- package/dist/lib/navigation-validator.js.map +1 -0
- package/dist/lib/normalize-config.d.ts +57 -0
- package/dist/lib/normalize-config.d.ts.map +1 -0
- package/dist/lib/normalize-config.js +63 -0
- package/dist/lib/normalize-config.js.map +1 -0
- package/dist/lib/openapi/cache.d.ts +40 -0
- package/dist/lib/openapi/cache.d.ts.map +1 -0
- package/dist/lib/openapi/cache.js +76 -0
- package/dist/lib/openapi/cache.js.map +1 -0
- package/dist/lib/openapi/errors.d.ts +36 -0
- package/dist/lib/openapi/errors.d.ts.map +1 -0
- package/dist/lib/openapi/errors.js +162 -0
- package/dist/lib/openapi/errors.js.map +1 -0
- package/dist/lib/openapi/index.d.ts +10 -0
- package/dist/lib/openapi/index.d.ts.map +1 -0
- package/dist/lib/openapi/index.js +12 -0
- package/dist/lib/openapi/index.js.map +1 -0
- package/dist/lib/openapi/types.d.ts +198 -0
- package/dist/lib/openapi/types.d.ts.map +1 -0
- package/dist/lib/openapi/types.js +8 -0
- package/dist/lib/openapi/types.js.map +1 -0
- package/dist/lib/openapi/validator.d.ts +45 -0
- package/dist/lib/openapi/validator.d.ts.map +1 -0
- package/dist/lib/openapi/validator.js +128 -0
- package/dist/lib/openapi/validator.js.map +1 -0
- package/dist/lib/openapi.d.ts +7 -0
- package/dist/lib/openapi.d.ts.map +1 -0
- package/dist/lib/openapi.js +7 -0
- package/dist/lib/openapi.js.map +1 -0
- package/dist/lib/output.d.ts +14 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +19 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/path-security.d.ts +23 -0
- package/dist/lib/path-security.d.ts.map +1 -0
- package/dist/lib/path-security.js +35 -0
- package/dist/lib/path-security.js.map +1 -0
- package/dist/lib/port.d.ts +18 -0
- package/dist/lib/port.d.ts.map +1 -0
- package/dist/lib/port.js +65 -0
- package/dist/lib/port.js.map +1 -0
- package/dist/lib/spinner.d.ts +4 -0
- package/dist/lib/spinner.d.ts.map +1 -0
- package/dist/lib/spinner.js +16 -0
- package/dist/lib/spinner.js.map +1 -0
- package/dist/lib/version.d.ts +2 -0
- package/dist/lib/version.d.ts.map +1 -0
- package/dist/lib/version.js +49 -0
- package/dist/lib/version.js.map +1 -0
- package/dist/utils/update-checker.d.ts +34 -0
- package/dist/utils/update-checker.d.ts.map +1 -0
- package/dist/utils/update-checker.js +142 -0
- package/dist/utils/update-checker.js.map +1 -0
- package/package.json +125 -0
- package/templates/docs.json +11 -0
- package/templates/introduction.mdx +19 -0
- package/templates/quickstart.mdx +20 -0
- package/vendored/app/[[...slug]]/error.tsx +103 -0
- package/vendored/app/[[...slug]]/page.tsx +690 -0
- package/vendored/app/api/assets/[...path]/route.ts +78 -0
- package/vendored/app/api/ev/route.ts +61 -0
- package/vendored/app/api/isr-health/route.ts +66 -0
- package/vendored/app/api/mcp/[project]/route.ts +435 -0
- package/vendored/app/api/og/route.tsx +167 -0
- package/vendored/app/api/r2/[project]/[...path]/route.ts +214 -0
- package/vendored/app/api/revalidate/route.ts +76 -0
- package/vendored/app/globals.css +37 -0
- package/vendored/app/layout.tsx +571 -0
- package/vendored/app/not-found.tsx +47 -0
- package/vendored/components/CodeBlockCopyButton.tsx +146 -0
- package/vendored/components/HeaderLinkCopy.tsx +135 -0
- package/vendored/components/errors/NotFoundContent.tsx +147 -0
- package/vendored/components/layout/LayoutWrapper.tsx +128 -0
- package/vendored/components/mdx/Accordion.tsx +91 -0
- package/vendored/components/mdx/ApiCodePanel.tsx +51 -0
- package/vendored/components/mdx/ApiEndpoint.tsx +104 -0
- package/vendored/components/mdx/ApiPage.tsx +379 -0
- package/vendored/components/mdx/Badge.tsx +169 -0
- package/vendored/components/mdx/Callouts.tsx +140 -0
- package/vendored/components/mdx/Card.tsx +214 -0
- package/vendored/components/mdx/CodeGroup.tsx +136 -0
- package/vendored/components/mdx/Color.tsx +244 -0
- package/vendored/components/mdx/Columns.tsx +37 -0
- package/vendored/components/mdx/Expandable.tsx +37 -0
- package/vendored/components/mdx/Frame.tsx +51 -0
- package/vendored/components/mdx/Icon.tsx +132 -0
- package/vendored/components/mdx/Latex.tsx +75 -0
- package/vendored/components/mdx/MDXComponents.tsx +414 -0
- package/vendored/components/mdx/Mermaid.tsx +35 -0
- package/vendored/components/mdx/MermaidInner.tsx +342 -0
- package/vendored/components/mdx/OpenApiEndpoint.tsx +971 -0
- package/vendored/components/mdx/Panel.tsx +26 -0
- package/vendored/components/mdx/PanelWrapper.tsx +100 -0
- package/vendored/components/mdx/ParamField.tsx +75 -0
- package/vendored/components/mdx/RequestExample.tsx +91 -0
- package/vendored/components/mdx/ResponseExample.tsx +145 -0
- package/vendored/components/mdx/ResponseField.tsx +109 -0
- package/vendored/components/mdx/Steps.tsx +173 -0
- package/vendored/components/mdx/Table.tsx +352 -0
- package/vendored/components/mdx/Tabs.tsx +147 -0
- package/vendored/components/mdx/Tile.tsx +127 -0
- package/vendored/components/mdx/Tooltip.tsx +111 -0
- package/vendored/components/mdx/Tree.tsx +484 -0
- package/vendored/components/mdx/Update.tsx +90 -0
- package/vendored/components/mdx/View.tsx +354 -0
- package/vendored/components/mdx/YouTube.tsx +35 -0
- package/vendored/components/mdx/ZoomableImage.tsx +83 -0
- package/vendored/components/navigation/Breadcrumb.tsx +241 -0
- package/vendored/components/navigation/DefaultLogo.tsx +81 -0
- package/vendored/components/navigation/Header.tsx +512 -0
- package/vendored/components/navigation/LanguageSelector.tsx +249 -0
- package/vendored/components/navigation/PageNavigation.tsx +174 -0
- package/vendored/components/navigation/Sidebar.tsx +713 -0
- package/vendored/components/navigation/SocialFooter.tsx +186 -0
- package/vendored/components/navigation/TableOfContents.tsx +435 -0
- package/vendored/components/navigation/TabsNav.tsx +182 -0
- package/vendored/components/search/LazySearchModal.tsx +19 -0
- package/vendored/components/search/SearchModal.tsx +573 -0
- package/vendored/components/snippets/ProjectSnippets.tsx +4 -0
- package/vendored/components/theme/ThemeProvider.tsx +31 -0
- package/vendored/components/theme/ThemeToggle.tsx +134 -0
- package/vendored/components/ui/CodePanel.tsx +517 -0
- package/vendored/components/ui/CodePanelModal.tsx +342 -0
- package/vendored/contexts/TabSyncContext.tsx +30 -0
- package/vendored/hooks/useFocusTrap.ts +42 -0
- package/vendored/hooks/useHashNavigation.ts +39 -0
- package/vendored/hooks/useShikiHighlight.ts +101 -0
- package/vendored/lib/analytics-client.ts +77 -0
- package/vendored/lib/build/cache.ts +138 -0
- package/vendored/lib/build/error-parser.ts +690 -0
- package/vendored/lib/build/estimation.ts +113 -0
- package/vendored/lib/build/index.ts +17 -0
- package/vendored/lib/build/page-file-map.ts +48 -0
- package/vendored/lib/build/r2-upload.ts +179 -0
- package/vendored/lib/cache-keys.ts +117 -0
- package/vendored/lib/code-utils.ts +42 -0
- package/vendored/lib/content-loader.ts +176 -0
- package/vendored/lib/deprecated-components.ts +185 -0
- package/vendored/lib/docs-isr.ts +180 -0
- package/vendored/lib/docs-types.ts +874 -0
- package/vendored/lib/docs.ts +203 -0
- package/vendored/lib/domain-helpers.ts +107 -0
- package/vendored/lib/email-notifier.ts +102 -0
- package/vendored/lib/email-templates/build-failure.tsx +193 -0
- package/vendored/lib/email-templates/components/base-layout.tsx +150 -0
- package/vendored/lib/email-templates/components/error-box.tsx +88 -0
- package/vendored/lib/email-templates/components/info-row.tsx +63 -0
- package/vendored/lib/email-templates/index.ts +13 -0
- package/vendored/lib/empty-polyfill.js +3 -0
- package/vendored/lib/extract-highlights.ts +124 -0
- package/vendored/lib/fonts.ts +227 -0
- package/vendored/lib/frontmatter-utils.ts +77 -0
- package/vendored/lib/fs-utils.ts +20 -0
- package/vendored/lib/git-utils.ts +87 -0
- package/vendored/lib/health-checks.ts +224 -0
- package/vendored/lib/icon-utils.ts +492 -0
- package/vendored/lib/infer-page-type.ts +14 -0
- package/vendored/lib/isr-build-executor.ts +185 -0
- package/vendored/lib/language-icons.ts +152 -0
- package/vendored/lib/language-utils.ts +338 -0
- package/vendored/lib/latex-config.ts +64 -0
- package/vendored/lib/link-prefix-context.tsx +32 -0
- package/vendored/lib/logger.ts +63 -0
- package/vendored/lib/mcp-search.ts +255 -0
- package/vendored/lib/mdx-inline-components.ts +155 -0
- package/vendored/lib/mdx.ts +100 -0
- package/vendored/lib/middleware-helpers.ts +519 -0
- package/vendored/lib/navigation-resolver.ts +621 -0
- package/vendored/lib/navigation-utils.ts +103 -0
- package/vendored/lib/normalize-config.ts +94 -0
- package/vendored/lib/openapi/cache.ts +92 -0
- package/vendored/lib/openapi/code-examples.ts +389 -0
- package/vendored/lib/openapi/errors.ts +253 -0
- package/vendored/lib/openapi/generator.ts +230 -0
- package/vendored/lib/openapi/index.ts +84 -0
- package/vendored/lib/openapi/parser.ts +474 -0
- package/vendored/lib/openapi/types.ts +232 -0
- package/vendored/lib/openapi/validator.ts +156 -0
- package/vendored/lib/openapi-isr.ts +121 -0
- package/vendored/lib/page-isr-helpers.ts +137 -0
- package/vendored/lib/path-safety.ts +130 -0
- package/vendored/lib/paths.ts +35 -0
- package/vendored/lib/preprocess-mdx.ts +951 -0
- package/vendored/lib/process-mdx-with-exports.ts +75 -0
- package/vendored/lib/project-resolver.ts +165 -0
- package/vendored/lib/r2-content.ts +60 -0
- package/vendored/lib/r2-manifest.ts +84 -0
- package/vendored/lib/recent-searches.ts +41 -0
- package/vendored/lib/recma-compound-components.ts +84 -0
- package/vendored/lib/redirect-compiler.ts +160 -0
- package/vendored/lib/redirect-matcher.ts +296 -0
- package/vendored/lib/redis.ts +23 -0
- package/vendored/lib/rehype-class-to-classname.ts +31 -0
- package/vendored/lib/rehype-code-meta.ts +275 -0
- package/vendored/lib/rehype-nozoom-to-data.ts +45 -0
- package/vendored/lib/remark-extract-exports.ts +104 -0
- package/vendored/lib/resilience.ts +260 -0
- package/vendored/lib/revalidation-helpers.ts +200 -0
- package/vendored/lib/revalidation-trigger.ts +150 -0
- package/vendored/lib/screenshot-capture.ts +229 -0
- package/vendored/lib/search-client.ts +91 -0
- package/vendored/lib/search-suggestions.ts +38 -0
- package/vendored/lib/search.ts +158 -0
- package/vendored/lib/seo.ts +264 -0
- package/vendored/lib/shiki-client.ts +131 -0
- package/vendored/lib/shiki-config.ts +289 -0
- package/vendored/lib/shiki-css-theme.ts +46 -0
- package/vendored/lib/shiki-highlighter.ts +62 -0
- package/vendored/lib/shiki-transformers.ts +337 -0
- package/vendored/lib/slack-notifier.ts +248 -0
- package/vendored/lib/snippet-compiler-isr.ts +114 -0
- package/vendored/lib/snippet-loader-isr.ts +276 -0
- package/vendored/lib/static-artifacts.ts +375 -0
- package/vendored/lib/static-file-route.ts +72 -0
- package/vendored/lib/tracking-script.ts +19 -0
- package/vendored/lib/typography-config.ts +42 -0
- package/vendored/lib/validate-config.ts +268 -0
- package/vendored/next.config.js +45 -0
- package/vendored/postcss.config.js +6 -0
- package/vendored/schema/README.md +28 -0
- package/vendored/schema/docs-schema.json +4631 -0
- package/vendored/scripts/build-project.cjs +174 -0
- package/vendored/scripts/build-search-index.cjs +347 -0
- package/vendored/scripts/compile-snippets.cjs +488 -0
- package/vendored/scripts/copy-files.cjs +295 -0
- package/vendored/scripts/dev-project.cjs +534 -0
- package/vendored/scripts/enhance-navigation.cjs +354 -0
- package/vendored/scripts/validate-links.cjs +423 -0
- package/vendored/shared/constants.ts +6 -0
- package/vendored/shared/index.ts +19 -0
- package/vendored/shared/logger.ts +62 -0
- package/vendored/shared/memory-monitor.ts +190 -0
- package/vendored/shared/navigation-validator.ts +101 -0
- package/vendored/shared/path-security.ts +39 -0
- package/vendored/shared/status-reporter.ts +199 -0
- package/vendored/shared/timer.ts +51 -0
- package/vendored/shared/types.ts +102 -0
- package/vendored/tailwind.config.ts +39 -0
- package/vendored/themes/base.css +1311 -0
- package/vendored/themes/index.ts +119 -0
- package/vendored/themes/jam/variables.css +835 -0
- package/vendored/themes/nebula/variables.css +282 -0
- package/vendored/themes/pulsar/variables.css +1009 -0
- package/vendored/themes/types.ts +89 -0
- package/vendored/tsconfig.json +48 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { createContext, useContext, type ReactNode } from 'react';
|
|
4
|
+
|
|
5
|
+
type ColorValue = string | { light: string; dark: string };
|
|
6
|
+
|
|
7
|
+
interface ColorItemProps {
|
|
8
|
+
name?: string;
|
|
9
|
+
value: ColorValue;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface ColorRowProps {
|
|
13
|
+
title?: string;
|
|
14
|
+
children: ReactNode;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface ColorProps {
|
|
18
|
+
variant?: 'compact' | 'table';
|
|
19
|
+
children: ReactNode;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Context to pass variant down to children
|
|
23
|
+
const ColorContext = createContext<{ variant: 'compact' | 'table' }>({ variant: 'compact' });
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Parse a color string and return RGB values
|
|
27
|
+
* Supports: hex (#RGB, #RRGGBB, #RRGGBBAA), rgb(), rgba()
|
|
28
|
+
*/
|
|
29
|
+
function parseColor(color: string): { r: number; g: number; b: number } | null {
|
|
30
|
+
const trimmed = color.trim().toLowerCase();
|
|
31
|
+
|
|
32
|
+
// Handle hex colors
|
|
33
|
+
if (trimmed.startsWith('#')) {
|
|
34
|
+
const hex = trimmed.slice(1);
|
|
35
|
+
let r: number, g: number, b: number;
|
|
36
|
+
|
|
37
|
+
if (hex.length === 3 || hex.length === 4) {
|
|
38
|
+
// #RGB or #RGBA
|
|
39
|
+
r = parseInt(hex[0] + hex[0], 16);
|
|
40
|
+
g = parseInt(hex[1] + hex[1], 16);
|
|
41
|
+
b = parseInt(hex[2] + hex[2], 16);
|
|
42
|
+
} else if (hex.length === 6 || hex.length === 8) {
|
|
43
|
+
// #RRGGBB or #RRGGBBAA
|
|
44
|
+
r = parseInt(hex.slice(0, 2), 16);
|
|
45
|
+
g = parseInt(hex.slice(2, 4), 16);
|
|
46
|
+
b = parseInt(hex.slice(4, 6), 16);
|
|
47
|
+
} else {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (isNaN(r) || isNaN(g) || isNaN(b)) return null;
|
|
52
|
+
return { r, g, b };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Handle rgb() and rgba()
|
|
56
|
+
const rgbMatch = trimmed.match(/rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/);
|
|
57
|
+
if (rgbMatch) {
|
|
58
|
+
return {
|
|
59
|
+
r: parseInt(rgbMatch[1], 10),
|
|
60
|
+
g: parseInt(rgbMatch[2], 10),
|
|
61
|
+
b: parseInt(rgbMatch[3], 10),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Calculate relative luminance and determine if text should be light or dark
|
|
70
|
+
* Uses WCAG formula for contrast
|
|
71
|
+
*/
|
|
72
|
+
function shouldUseLightText(color: string): boolean {
|
|
73
|
+
const rgb = parseColor(color);
|
|
74
|
+
if (!rgb) return false;
|
|
75
|
+
|
|
76
|
+
// Calculate relative luminance using WCAG formula
|
|
77
|
+
const [r, g, b] = [rgb.r, rgb.g, rgb.b].map((c) => {
|
|
78
|
+
const normalized = c / 255;
|
|
79
|
+
return normalized <= 0.03928
|
|
80
|
+
? normalized / 12.92
|
|
81
|
+
: Math.pow((normalized + 0.055) / 1.055, 2.4);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
85
|
+
return luminance < 0.5;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Get display value for a color (for showing in the UI)
|
|
90
|
+
*/
|
|
91
|
+
function getDisplayValue(value: ColorValue): string {
|
|
92
|
+
if (typeof value === 'string') {
|
|
93
|
+
return value;
|
|
94
|
+
}
|
|
95
|
+
return value.light;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* ColorItem - Individual color swatch
|
|
100
|
+
*/
|
|
101
|
+
export function ColorItem({ name, value }: ColorItemProps) {
|
|
102
|
+
const { variant } = useContext(ColorContext);
|
|
103
|
+
const isThemeAware = typeof value === 'object';
|
|
104
|
+
const displayValue = getDisplayValue(value);
|
|
105
|
+
|
|
106
|
+
// CSS variables for theme-aware colors
|
|
107
|
+
const cssVars = isThemeAware
|
|
108
|
+
? ({
|
|
109
|
+
'--color-swatch-light': value.light,
|
|
110
|
+
'--color-swatch-dark': value.dark,
|
|
111
|
+
} as React.CSSProperties)
|
|
112
|
+
: {};
|
|
113
|
+
|
|
114
|
+
const swatchColor = isThemeAware ? 'var(--color-swatch-light)' : value;
|
|
115
|
+
const lightTextOnLight = isThemeAware ? shouldUseLightText(value.light) : shouldUseLightText(value as string);
|
|
116
|
+
const lightTextOnDark = isThemeAware ? shouldUseLightText(value.dark) : lightTextOnLight;
|
|
117
|
+
|
|
118
|
+
if (variant === 'table') {
|
|
119
|
+
return (
|
|
120
|
+
<div
|
|
121
|
+
className="color-item-table flex items-center gap-3 py-2 px-3 border-b border-[var(--color-border)] last:border-b-0 cursor-pointer"
|
|
122
|
+
style={cssVars}
|
|
123
|
+
data-copy-text={displayValue}
|
|
124
|
+
title="Click to copy"
|
|
125
|
+
>
|
|
126
|
+
{/* Color swatch */}
|
|
127
|
+
<div
|
|
128
|
+
className="color-swatch w-8 h-8 rounded-md border border-black/10 flex-shrink-0"
|
|
129
|
+
style={{ backgroundColor: swatchColor }}
|
|
130
|
+
/>
|
|
131
|
+
{/* Name */}
|
|
132
|
+
<span className="color-name flex-1 text-sm font-medium text-[var(--color-text-primary)]">
|
|
133
|
+
{name}
|
|
134
|
+
</span>
|
|
135
|
+
{/* Value */}
|
|
136
|
+
<code className="color-value text-xs font-mono text-[var(--color-text-secondary)]">
|
|
137
|
+
{displayValue}
|
|
138
|
+
</code>
|
|
139
|
+
{/* Copy icon */}
|
|
140
|
+
<i className="fa-regular fa-copy text-xs text-[var(--color-text-muted)]" aria-hidden="true" />
|
|
141
|
+
</div>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Compact variant
|
|
146
|
+
return (
|
|
147
|
+
<div
|
|
148
|
+
className="color-item-compact flex flex-col rounded-lg overflow-hidden border border-[var(--color-border)] cursor-pointer"
|
|
149
|
+
style={cssVars}
|
|
150
|
+
data-copy-text={displayValue}
|
|
151
|
+
title="Click to copy"
|
|
152
|
+
>
|
|
153
|
+
{/* Color swatch area */}
|
|
154
|
+
<div
|
|
155
|
+
className="color-swatch h-20 flex items-end justify-start p-2"
|
|
156
|
+
style={{ backgroundColor: swatchColor }}
|
|
157
|
+
>
|
|
158
|
+
{isThemeAware && (
|
|
159
|
+
<span
|
|
160
|
+
className="color-theme-indicator text-xs px-1.5 py-0.5 rounded bg-black/20"
|
|
161
|
+
style={{
|
|
162
|
+
color: lightTextOnLight ? '#fff' : '#000',
|
|
163
|
+
}}
|
|
164
|
+
>
|
|
165
|
+
Theme
|
|
166
|
+
</span>
|
|
167
|
+
)}
|
|
168
|
+
</div>
|
|
169
|
+
{/* Info area */}
|
|
170
|
+
<div className="color-info p-3 bg-[var(--color-bg-primary)]">
|
|
171
|
+
{name && (
|
|
172
|
+
<div className="color-name text-sm font-medium text-[var(--color-text-primary)] mb-1">
|
|
173
|
+
{name}
|
|
174
|
+
</div>
|
|
175
|
+
)}
|
|
176
|
+
<code className="color-value text-xs font-mono text-[var(--color-text-secondary)]">
|
|
177
|
+
{displayValue}
|
|
178
|
+
</code>
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* ColorRow - Group of colors with a title (for table variant)
|
|
186
|
+
*/
|
|
187
|
+
export function ColorRow({ title, children }: ColorRowProps) {
|
|
188
|
+
return (
|
|
189
|
+
<div className="color-row mb-4 last:mb-0">
|
|
190
|
+
{title && (
|
|
191
|
+
<div className="color-row-title text-sm font-semibold text-[var(--color-text-primary)] mb-2 px-3">
|
|
192
|
+
{title}
|
|
193
|
+
</div>
|
|
194
|
+
)}
|
|
195
|
+
<div className="color-row-items rounded-lg border border-[var(--color-border)] overflow-hidden">
|
|
196
|
+
{children}
|
|
197
|
+
</div>
|
|
198
|
+
</div>
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Color - Container component for displaying color palettes
|
|
204
|
+
*
|
|
205
|
+
* @example Compact variant (grid layout)
|
|
206
|
+
* <Color variant="compact">
|
|
207
|
+
* <Color.Item name="Primary" value="#3b82f6" />
|
|
208
|
+
* <Color.Item name="Secondary" value="#6366f1" />
|
|
209
|
+
* </Color>
|
|
210
|
+
*
|
|
211
|
+
* @example Table variant (grouped rows)
|
|
212
|
+
* <Color variant="table">
|
|
213
|
+
* <Color.Row title="Primary Colors">
|
|
214
|
+
* <Color.Item name="Blue" value="#3b82f6" />
|
|
215
|
+
* </Color.Row>
|
|
216
|
+
* </Color>
|
|
217
|
+
*
|
|
218
|
+
* @example Theme-aware colors
|
|
219
|
+
* <Color.Item name="Background" value={{ light: "#ffffff", dark: "#000000" }} />
|
|
220
|
+
*/
|
|
221
|
+
export function Color({ variant = 'compact', children }: ColorProps) {
|
|
222
|
+
const isCompact = variant === 'compact';
|
|
223
|
+
|
|
224
|
+
return (
|
|
225
|
+
<ColorContext.Provider value={{ variant }}>
|
|
226
|
+
<div
|
|
227
|
+
className={`color-palette my-6 not-prose ${
|
|
228
|
+
isCompact ? 'grid gap-4' : ''
|
|
229
|
+
}`}
|
|
230
|
+
style={
|
|
231
|
+
isCompact
|
|
232
|
+
? { gridTemplateColumns: 'repeat(auto-fill, minmax(140px, 1fr))' }
|
|
233
|
+
: undefined
|
|
234
|
+
}
|
|
235
|
+
>
|
|
236
|
+
{children}
|
|
237
|
+
</div>
|
|
238
|
+
</ColorContext.Provider>
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Attach sub-components
|
|
243
|
+
Color.Item = ColorItem;
|
|
244
|
+
Color.Row = ColorRow;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
interface ColumnsProps {
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
/** The number of columns per row. Accepts values from 1 to 4. Default: 2 */
|
|
6
|
+
cols?: number;
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Columns component for displaying multiple Card components together in a responsive grid.
|
|
12
|
+
* The grid automatically adapts to smaller screens.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* <Columns cols={2}>
|
|
16
|
+
* <Card title="Get started">Set up your project</Card>
|
|
17
|
+
* <Card title="API reference">Explore endpoints</Card>
|
|
18
|
+
* </Columns>
|
|
19
|
+
*/
|
|
20
|
+
// Responsive grid classes: mobile (1 col), tablet (2 cols max), desktop (full count)
|
|
21
|
+
const GRID_CLASSES: Record<number, string> = {
|
|
22
|
+
1: 'grid-cols-1',
|
|
23
|
+
2: 'grid-cols-1 md:grid-cols-2',
|
|
24
|
+
3: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
|
|
25
|
+
4: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-4',
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export function Columns({ children, cols = 2, className = '' }: ColumnsProps) {
|
|
29
|
+
const gridCols = Math.min(Math.max(cols, 1), 4);
|
|
30
|
+
const responsiveClass = GRID_CLASSES[gridCols];
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<div className={`grid gap-4 my-4 not-prose [&>*]:my-0 [&>div]:my-0 [&>a]:my-0 ${responsiveClass} ${className}`.trim()}>
|
|
34
|
+
{children}
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
|
|
5
|
+
interface ExpandableProps {
|
|
6
|
+
title: string;
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
defaultOpen?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Expandable component - a collapsible section.
|
|
13
|
+
* Component for expandable content.
|
|
14
|
+
*/
|
|
15
|
+
export function Expandable({ title, children, defaultOpen = false }: ExpandableProps) {
|
|
16
|
+
const [isOpen, setIsOpen] = useState(defaultOpen);
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div className="border border-[var(--color-border)] rounded-lg my-4 overflow-hidden not-prose">
|
|
20
|
+
<button
|
|
21
|
+
className="w-full px-4 py-3 flex items-center gap-2 text-left bg-theme-bg-secondary hover:bg-theme-bg-tertiary transition-colors"
|
|
22
|
+
onClick={() => setIsOpen(!isOpen)}
|
|
23
|
+
>
|
|
24
|
+
<span className="font-medium text-theme-text-primary capitalize">{title}</span>
|
|
25
|
+
<i
|
|
26
|
+
className={`fa-solid fa-chevron-right text-[10px] text-[var(--color-text-muted)] transition-transform ${isOpen ? 'rotate-90' : ''}`}
|
|
27
|
+
aria-hidden="true"
|
|
28
|
+
/>
|
|
29
|
+
</button>
|
|
30
|
+
{isOpen && (
|
|
31
|
+
<div className="px-4 py-3 border-t border-[var(--color-border)] text-sm leading-relaxed [&>p]:m-0 [&>p]:mb-3 [&>p:last-child]:mb-0 [&>*:first-child]:mt-0 [&>*:last-child]:mb-0 [&>ul]:my-2 [&>ul]:ml-4 [&>ul]:list-disc [&>ol]:my-2 [&>ol]:ml-4 [&>ol]:list-decimal [&>li]:mb-1 [&>strong]:font-semibold [&>a]:text-[var(--color-accent)] [&>a]:underline">
|
|
32
|
+
{children}
|
|
33
|
+
</div>
|
|
34
|
+
)}
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
|
|
5
|
+
interface FrameProps {
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
caption?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Frame component - wraps content in a styled frame.
|
|
12
|
+
* Component for framed content/images.
|
|
13
|
+
*/
|
|
14
|
+
export function Frame({ children, caption }: FrameProps) {
|
|
15
|
+
const [isDark, setIsDark] = useState(false);
|
|
16
|
+
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
// Check initial theme
|
|
19
|
+
setIsDark(document.documentElement.classList.contains('dark'));
|
|
20
|
+
|
|
21
|
+
// Watch for theme changes
|
|
22
|
+
const observer = new MutationObserver(() => {
|
|
23
|
+
setIsDark(document.documentElement.classList.contains('dark'));
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
|
|
27
|
+
|
|
28
|
+
return () => observer.disconnect();
|
|
29
|
+
}, []);
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<figure className="my-6">
|
|
33
|
+
<div
|
|
34
|
+
className="frame-content rounded-lg overflow-x-auto p-2 [&_img]:!my-0 [&_img]:!rounded-md [&_p]:!my-0"
|
|
35
|
+
style={{
|
|
36
|
+
backgroundColor: isDark ? '#0f1419' : '#f8f9fa',
|
|
37
|
+
boxShadow: isDark
|
|
38
|
+
? 'inset 0 0 0 0.5px rgba(107, 114, 128, 0.3)'
|
|
39
|
+
: 'inset 0 0 0 0.5px rgba(209, 213, 219, 0.8)'
|
|
40
|
+
}}
|
|
41
|
+
>
|
|
42
|
+
{children}
|
|
43
|
+
</div>
|
|
44
|
+
{caption && (
|
|
45
|
+
<figcaption className="mt-2 text-sm text-center text-theme-text-tertiary">
|
|
46
|
+
{caption}
|
|
47
|
+
</figcaption>
|
|
48
|
+
)}
|
|
49
|
+
</figure>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { getIconClass } from '@/lib/icon-utils';
|
|
2
|
+
|
|
3
|
+
interface IconProps {
|
|
4
|
+
/**
|
|
5
|
+
* The icon to display. Options:
|
|
6
|
+
* - Font Awesome icon name (e.g., "flag", "circle-xmark")
|
|
7
|
+
* - URL to external icon (e.g., "https://example.com/icon.svg")
|
|
8
|
+
* - Path to icon file (e.g., "/images/icon.svg")
|
|
9
|
+
*/
|
|
10
|
+
icon: string | React.ReactElement;
|
|
11
|
+
/** Font Awesome icon style */
|
|
12
|
+
iconType?: 'regular' | 'solid' | 'light' | 'thin' | 'sharp-solid' | 'duotone' | 'brands';
|
|
13
|
+
/** Color as hex code (#FF5733) or named color (red, blue, etc.) */
|
|
14
|
+
color?: string;
|
|
15
|
+
/** Size in pixels (default: 16) */
|
|
16
|
+
size?: number;
|
|
17
|
+
/** Custom CSS class */
|
|
18
|
+
className?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Get color style from color prop
|
|
23
|
+
*/
|
|
24
|
+
function getColorStyle(color?: string): { style?: React.CSSProperties; className?: string } {
|
|
25
|
+
if (!color) return {};
|
|
26
|
+
|
|
27
|
+
// Hex code - use inline style
|
|
28
|
+
if (color.startsWith('#')) {
|
|
29
|
+
return { style: { color } };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Named colors - map to Tailwind classes
|
|
33
|
+
const colorMap: Record<string, string> = {
|
|
34
|
+
'red': 'text-red-500',
|
|
35
|
+
'blue': 'text-blue-500',
|
|
36
|
+
'green': 'text-green-500',
|
|
37
|
+
'yellow': 'text-yellow-500',
|
|
38
|
+
'orange': 'text-orange-500',
|
|
39
|
+
'purple': 'text-purple-500',
|
|
40
|
+
'pink': 'text-pink-500',
|
|
41
|
+
'gray': 'text-gray-400',
|
|
42
|
+
'grey': 'text-gray-400',
|
|
43
|
+
'white': 'text-white',
|
|
44
|
+
'black': 'text-black',
|
|
45
|
+
'primary': 'text-theme-accent',
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
if (colorMap[color.toLowerCase()]) {
|
|
49
|
+
return { className: colorMap[color.toLowerCase()] };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Try as direct color value
|
|
53
|
+
return { style: { color } };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Icon component for rendering icons in MDX content.
|
|
58
|
+
* Supports Font Awesome icons via CSS, SVG elements, URLs, and file paths.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* // Font Awesome icon by name
|
|
62
|
+
* <Icon icon="flag" size={32} />
|
|
63
|
+
*
|
|
64
|
+
* // Font Awesome with style
|
|
65
|
+
* <Icon icon="circle-xmark" iconType="solid" color="red" />
|
|
66
|
+
*
|
|
67
|
+
* // Hex color
|
|
68
|
+
* <Icon icon="repeat" color="#FF5733" />
|
|
69
|
+
*
|
|
70
|
+
* // External URL
|
|
71
|
+
* <Icon icon="https://example.com/icon.svg" size={24} />
|
|
72
|
+
*
|
|
73
|
+
* // Local file path
|
|
74
|
+
* <Icon icon="/images/custom-icon.svg" size={24} />
|
|
75
|
+
*
|
|
76
|
+
* // Inline SVG (JSX)
|
|
77
|
+
* <Icon icon={<svg viewBox="0 0 24 24"><path d="..."/></svg>} />
|
|
78
|
+
*
|
|
79
|
+
*/
|
|
80
|
+
export function Icon({ icon, iconType = 'solid', color, size = 16, className }: IconProps) {
|
|
81
|
+
const { style: colorStyle, className: colorClass } = getColorStyle(color);
|
|
82
|
+
const combinedClassName = `inline-block ${colorClass || ''} ${className || ''}`.trim();
|
|
83
|
+
const sizeStyle = { width: size, height: size };
|
|
84
|
+
|
|
85
|
+
// Case 1: JSX SVG element passed directly
|
|
86
|
+
if (typeof icon !== 'string') {
|
|
87
|
+
// It's a React element (SVG)
|
|
88
|
+
return (
|
|
89
|
+
<span
|
|
90
|
+
className={combinedClassName}
|
|
91
|
+
style={{ ...sizeStyle, ...colorStyle, display: 'inline-flex', alignItems: 'center' }}
|
|
92
|
+
>
|
|
93
|
+
{icon}
|
|
94
|
+
</span>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Case 2: URL to external icon
|
|
99
|
+
if (icon.startsWith('http://') || icon.startsWith('https://')) {
|
|
100
|
+
return (
|
|
101
|
+
<img
|
|
102
|
+
src={icon}
|
|
103
|
+
alt=""
|
|
104
|
+
className={combinedClassName}
|
|
105
|
+
style={{ ...sizeStyle, ...colorStyle }}
|
|
106
|
+
/>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Case 3: Local file path (starts with / or ./)
|
|
111
|
+
if (icon.startsWith('/') || icon.startsWith('./')) {
|
|
112
|
+
return (
|
|
113
|
+
<img
|
|
114
|
+
src={icon}
|
|
115
|
+
alt=""
|
|
116
|
+
className={combinedClassName}
|
|
117
|
+
style={{ ...sizeStyle, ...colorStyle }}
|
|
118
|
+
/>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Case 4: Font Awesome icon via CSS class
|
|
123
|
+
const faClass = getIconClass(icon);
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<i
|
|
127
|
+
className={`${faClass} ${combinedClassName}`}
|
|
128
|
+
style={{ ...sizeStyle, ...colorStyle }}
|
|
129
|
+
aria-hidden="true"
|
|
130
|
+
/>
|
|
131
|
+
);
|
|
132
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import katex from 'katex';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
interface LatexProps {
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
block?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Latex component for rendering mathematical equations using KaTeX.
|
|
11
|
+
*
|
|
12
|
+
* Supports two modes:
|
|
13
|
+
* - Inline (default): Renders within text flow
|
|
14
|
+
* - Block: Centered display mode for standalone equations
|
|
15
|
+
*
|
|
16
|
+
* Security: Uses dangerouslySetInnerHTML with KaTeX output. This is safe
|
|
17
|
+
* because KaTeX only processes LaTeX math syntax (not arbitrary HTML).
|
|
18
|
+
* KaTeX is designed to be XSS-safe and is widely used by documentation platforms.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* // Inline math
|
|
22
|
+
* <Latex>E = mc^2</Latex>
|
|
23
|
+
*
|
|
24
|
+
* // Block/display math
|
|
25
|
+
* <Latex block>
|
|
26
|
+
* \int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2}
|
|
27
|
+
* </Latex>
|
|
28
|
+
*/
|
|
29
|
+
export function Latex({ children, block = false }: LatexProps) {
|
|
30
|
+
// Convert children to string - handles string, array, or other ReactNode types
|
|
31
|
+
const latex = extractLatexString(children);
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
// KaTeX.renderToString is safe - it only parses LaTeX math syntax,
|
|
35
|
+
// not arbitrary HTML. Invalid LaTeX produces error messages, not XSS.
|
|
36
|
+
const html = katex.renderToString(latex, {
|
|
37
|
+
displayMode: block,
|
|
38
|
+
throwOnError: false, // Render error message instead of throwing
|
|
39
|
+
errorColor: '#cc0000',
|
|
40
|
+
trust: false, // Don't allow potentially dangerous commands like \url
|
|
41
|
+
strict: 'warn', // Log warnings for unsupported commands
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<span
|
|
46
|
+
className={block ? 'katex-display block my-4 text-center overflow-x-auto' : 'katex-inline'}
|
|
47
|
+
dangerouslySetInnerHTML={{ __html: html }}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
} catch (error) {
|
|
51
|
+
// Fallback for truly unexpected errors
|
|
52
|
+
console.error('[Latex] Rendering error:', error);
|
|
53
|
+
return (
|
|
54
|
+
<span className="text-red-500 font-mono text-sm bg-red-50 dark:bg-red-950 px-1 rounded">
|
|
55
|
+
LaTeX Error: {latex.slice(0, 50)}{latex.length > 50 ? '...' : ''}
|
|
56
|
+
</span>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Extract a string from ReactNode children.
|
|
63
|
+
* Handles strings, arrays, and stringifies other types.
|
|
64
|
+
*/
|
|
65
|
+
function extractLatexString(children: ReactNode): string {
|
|
66
|
+
if (typeof children === 'string') {
|
|
67
|
+
return children;
|
|
68
|
+
}
|
|
69
|
+
if (Array.isArray(children)) {
|
|
70
|
+
return children.map(child =>
|
|
71
|
+
typeof child === 'string' ? child : String(child ?? '')
|
|
72
|
+
).join('');
|
|
73
|
+
}
|
|
74
|
+
return String(children ?? '');
|
|
75
|
+
}
|