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,174 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Build Project Script
|
|
4
|
+
*
|
|
5
|
+
* Validates a project and provides guidance for the ISR workflow.
|
|
6
|
+
*
|
|
7
|
+
* With ISR (Incremental Static Regeneration), pages are compiled on-demand
|
|
8
|
+
* by Vercel, so local static builds are no longer needed.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* npm run build-project acme # Validate project
|
|
12
|
+
* npm run build-project acme --deploy # Trigger production deploy
|
|
13
|
+
*
|
|
14
|
+
* For local development:
|
|
15
|
+
* jamdesk dev <project> # Start local dev server
|
|
16
|
+
*
|
|
17
|
+
* For production deployment:
|
|
18
|
+
* ./jam trigger <project> # Trigger Cloud Run build
|
|
19
|
+
* Or push to GitHub to trigger automatic deployment
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
const { execSync } = require('child_process');
|
|
23
|
+
const fs = require('fs-extra');
|
|
24
|
+
const path = require('path');
|
|
25
|
+
|
|
26
|
+
// Parse arguments
|
|
27
|
+
const args = process.argv.slice(2);
|
|
28
|
+
const projectName = args.find(arg => !arg.startsWith('--'));
|
|
29
|
+
const shouldDeploy = args.includes('--deploy');
|
|
30
|
+
|
|
31
|
+
if (!projectName) {
|
|
32
|
+
console.log(`
|
|
33
|
+
╔═══════════════════════════════════════════════════════════════════╗
|
|
34
|
+
║ Build Project Documentation ║
|
|
35
|
+
╚═══════════════════════════════════════════════════════════════════╝
|
|
36
|
+
|
|
37
|
+
Usage:
|
|
38
|
+
npm run build-project <project-name> [options]
|
|
39
|
+
|
|
40
|
+
Options:
|
|
41
|
+
--deploy Trigger production deployment
|
|
42
|
+
|
|
43
|
+
For local preview:
|
|
44
|
+
jamdesk dev <project>
|
|
45
|
+
|
|
46
|
+
Available projects:`);
|
|
47
|
+
|
|
48
|
+
const projectsDir = process.env.JAMDESK_PROJECTS_DIR || path.join(__dirname, '../projects');
|
|
49
|
+
if (fs.existsSync(projectsDir)) {
|
|
50
|
+
const projects = fs.readdirSync(projectsDir)
|
|
51
|
+
.filter(f => fs.statSync(path.join(projectsDir, f)).isDirectory());
|
|
52
|
+
if (projects.length > 0) {
|
|
53
|
+
projects.forEach(t => console.log(` - ${t}`));
|
|
54
|
+
} else {
|
|
55
|
+
console.log(' (no projects found - create directories in /projects/)');
|
|
56
|
+
}
|
|
57
|
+
} else {
|
|
58
|
+
console.log(' (projects directory not found)');
|
|
59
|
+
}
|
|
60
|
+
console.log('');
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Verify project exists
|
|
65
|
+
const projectsDir = process.env.JAMDESK_PROJECTS_DIR || path.join(__dirname, '../projects');
|
|
66
|
+
const projectDir = path.join(projectsDir, projectName);
|
|
67
|
+
if (!fs.existsSync(projectDir)) {
|
|
68
|
+
console.error(`\n❌ Error: Project directory not found: ${projectDir}`);
|
|
69
|
+
console.error('\nAvailable projects:');
|
|
70
|
+
if (fs.existsSync(projectsDir)) {
|
|
71
|
+
const projects = fs.readdirSync(projectsDir)
|
|
72
|
+
.filter(f => fs.statSync(path.join(projectsDir, f)).isDirectory());
|
|
73
|
+
projects.forEach(t => console.error(` - ${t}`));
|
|
74
|
+
}
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Verify required files (flat structure - MDX files directly in project dir)
|
|
79
|
+
const hasDocsJson = fs.existsSync(path.join(projectDir, 'docs.json'));
|
|
80
|
+
|
|
81
|
+
// Check for at least one MDX file (recursively, skipping images/ and hidden dirs)
|
|
82
|
+
function hasMdxFiles(dir) {
|
|
83
|
+
const files = fs.readdirSync(dir);
|
|
84
|
+
for (const file of files) {
|
|
85
|
+
// Skip hidden files/directories (like .claude, .git, etc.)
|
|
86
|
+
if (file.startsWith('.')) continue;
|
|
87
|
+
|
|
88
|
+
const filePath = path.join(dir, file);
|
|
89
|
+
|
|
90
|
+
// Use lstatSync to handle symlinks - if target doesn't exist, skip
|
|
91
|
+
let stat;
|
|
92
|
+
try {
|
|
93
|
+
stat = fs.statSync(filePath);
|
|
94
|
+
} catch (e) {
|
|
95
|
+
// Broken symlink or inaccessible file - skip
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (stat.isDirectory() && file !== 'images' && file !== 'node_modules') {
|
|
100
|
+
if (hasMdxFiles(filePath)) return true;
|
|
101
|
+
} else if (file.endsWith('.mdx')) {
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const hasMdx = hasMdxFiles(projectDir);
|
|
109
|
+
|
|
110
|
+
if (!hasDocsJson || !hasMdx) {
|
|
111
|
+
console.error(`\n❌ Error: Missing required files in project directory:`);
|
|
112
|
+
if (!hasDocsJson) console.error(` - docs.json`);
|
|
113
|
+
if (!hasMdx) console.error(` - *.mdx files`);
|
|
114
|
+
console.error(`\nExpected structure (flat):`);
|
|
115
|
+
console.error(` projects/${projectName}/`);
|
|
116
|
+
console.error(` ├── docs.json`);
|
|
117
|
+
console.error(` ├── introduction.mdx`);
|
|
118
|
+
console.error(` ├── apis/`);
|
|
119
|
+
console.error(` │ └── overview.mdx`);
|
|
120
|
+
console.error(` └── images/`);
|
|
121
|
+
process.exit(1);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Project validated - show ISR workflow guidance
|
|
125
|
+
const title = `Project: ${projectName}`;
|
|
126
|
+
const titlePadding = 69 - 2 - title.length;
|
|
127
|
+
const titleLeft = Math.floor(titlePadding / 2);
|
|
128
|
+
const titleRight = titlePadding - titleLeft;
|
|
129
|
+
|
|
130
|
+
console.log(`
|
|
131
|
+
╔═══════════════════════════════════════════════════════════════════╗
|
|
132
|
+
║${' '.repeat(titleLeft)}${title}${' '.repeat(titleRight)}║
|
|
133
|
+
╚═══════════════════════════════════════════════════════════════════╝
|
|
134
|
+
`);
|
|
135
|
+
|
|
136
|
+
console.log('✅ Project validated successfully\n');
|
|
137
|
+
console.log(` docs.json: Found`);
|
|
138
|
+
console.log(` MDX files: Found\n`);
|
|
139
|
+
|
|
140
|
+
if (shouldDeploy) {
|
|
141
|
+
// Trigger production deployment
|
|
142
|
+
console.log('📤 Triggering production deployment...\n');
|
|
143
|
+
|
|
144
|
+
try {
|
|
145
|
+
// Try to trigger via ./jam trigger (requires BUILD_API_KEY)
|
|
146
|
+
// Note: execSync is safe here - projectName is validated against existing directories
|
|
147
|
+
execSync(`./jam trigger ${projectName}`, {
|
|
148
|
+
stdio: 'inherit',
|
|
149
|
+
cwd: path.join(__dirname, '../..'),
|
|
150
|
+
});
|
|
151
|
+
} catch (error) {
|
|
152
|
+
console.log(`
|
|
153
|
+
To deploy to production, you can:
|
|
154
|
+
|
|
155
|
+
1. Push to GitHub (triggers automatic deployment)
|
|
156
|
+
2. Use the dashboard at https://dashboard.jamdesk.com
|
|
157
|
+
3. Run: ./jam trigger ${projectName}
|
|
158
|
+
(requires BUILD_API_KEY in functions/.env.local)
|
|
159
|
+
`);
|
|
160
|
+
}
|
|
161
|
+
} else {
|
|
162
|
+
console.log(`ISR Workflow:
|
|
163
|
+
|
|
164
|
+
Local preview:
|
|
165
|
+
jamdesk dev ${projectName}
|
|
166
|
+
|
|
167
|
+
Production deployment:
|
|
168
|
+
./jam trigger ${projectName}
|
|
169
|
+
Or push to GitHub for automatic deployment
|
|
170
|
+
|
|
171
|
+
Live site:
|
|
172
|
+
https://${projectName}.jamdesk.app
|
|
173
|
+
`);
|
|
174
|
+
}
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Build Search Index Script
|
|
4
|
+
*
|
|
5
|
+
* Generates a search-data.json file from MDX content.
|
|
6
|
+
* Supports project-specific builds via PROJECT_NAME environment variable.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* node scripts/build-search-index.js # Uses default content directory
|
|
10
|
+
* PROJECT_NAME=acme node scripts/build-search-index.js # Uses project's content
|
|
11
|
+
* node scripts/build-search-index.js --project acme # Same as above
|
|
12
|
+
*
|
|
13
|
+
* Search Data Handling:
|
|
14
|
+
* - LOCAL DEV: Writes to public/search-data.json (served by Next.js dev server)
|
|
15
|
+
* - PRODUCTION BUILD: Writes to public/search-data.json, then included in /out/ static export
|
|
16
|
+
* - Each project gets their own search-data.json when deployed to R2
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const fs = require('fs');
|
|
20
|
+
const fsPromises = require('fs/promises');
|
|
21
|
+
const path = require('path');
|
|
22
|
+
const matter = require('gray-matter');
|
|
23
|
+
const os = require('os');
|
|
24
|
+
const { create, insertMultiple } = require('@orama/orama');
|
|
25
|
+
const { persist } = require('@orama/plugin-data-persistence');
|
|
26
|
+
|
|
27
|
+
// Concurrency control for parallel file processing
|
|
28
|
+
const CONCURRENCY = parseInt(process.env.SEARCH_INDEX_CONCURRENCY || '') || os.cpus().length * 2;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Pre-process frontmatter to handle common YAML issues:
|
|
32
|
+
* - Colons in unquoted string values (e.g., "description: Follow the workflow: step 1")
|
|
33
|
+
* - YAML tags like !Jamdesk that should be plain text
|
|
34
|
+
*
|
|
35
|
+
* NOTE: This is duplicated from lib/frontmatter-utils.ts for CJS compatibility.
|
|
36
|
+
*/
|
|
37
|
+
function preprocessFrontmatter(content) {
|
|
38
|
+
if (!content.startsWith('---')) return content;
|
|
39
|
+
|
|
40
|
+
const endMatch = content.slice(3).match(/\n---(\r?\n|$)/);
|
|
41
|
+
if (!endMatch) return content;
|
|
42
|
+
|
|
43
|
+
const frontmatterEnd = 3 + endMatch.index + endMatch[0].length;
|
|
44
|
+
const frontmatter = content.slice(3, frontmatterEnd - endMatch[0].length);
|
|
45
|
+
const body = content.slice(frontmatterEnd);
|
|
46
|
+
|
|
47
|
+
const fixedLines = frontmatter.split('\n').map((line) => {
|
|
48
|
+
if (!line.trim() || line.trim().startsWith('#')) return line;
|
|
49
|
+
|
|
50
|
+
const match = line.match(/^(\s*)([a-zA-Z_][a-zA-Z0-9_]*):\s*(.*)$/);
|
|
51
|
+
if (!match) return line;
|
|
52
|
+
|
|
53
|
+
const [, indent, key, value] = match;
|
|
54
|
+
|
|
55
|
+
if (!value || value.startsWith('"') || value.startsWith("'") || /^[|>][-+]?$/.test(value)) {
|
|
56
|
+
return line;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (value.startsWith('{') || value.startsWith('[')) return line;
|
|
60
|
+
|
|
61
|
+
let fixedValue = value.replace(/^![a-zA-Z][a-zA-Z0-9_-]*\s*/, '');
|
|
62
|
+
|
|
63
|
+
if (fixedValue.includes(':') && !fixedValue.endsWith(':')) {
|
|
64
|
+
fixedValue = '"' + fixedValue.replace(/"/g, '\\"') + '"';
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return `${indent}${key}: ${fixedValue}`;
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
return '---\n' + fixedLines.join('\n') + '\n---' + body;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Parse frontmatter with lenient preprocessing.
|
|
75
|
+
*/
|
|
76
|
+
function parseFrontmatterLenient(content) {
|
|
77
|
+
const processed = preprocessFrontmatter(content);
|
|
78
|
+
const { data, content: rawContent } = matter(processed);
|
|
79
|
+
return { data, content: rawContent };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Infer page type from slug for search result badges.
|
|
84
|
+
* Returns: 'api' | 'component' | 'guide' | 'help' | 'quickstart'
|
|
85
|
+
*
|
|
86
|
+
* NOTE: This logic is duplicated from lib/infer-page-type.ts for CJS compatibility.
|
|
87
|
+
* If you update the rules here, also update the TypeScript version.
|
|
88
|
+
* Run `npm run test:run -- infer-page-type` to verify both implementations match.
|
|
89
|
+
*/
|
|
90
|
+
function inferPageType(slug) {
|
|
91
|
+
const lower = slug.toLowerCase();
|
|
92
|
+
if (lower.startsWith('apis/') || lower.includes('/api/') || lower.startsWith('api-reference/')) {
|
|
93
|
+
return 'api';
|
|
94
|
+
}
|
|
95
|
+
if (lower.startsWith('components/') || lower.startsWith('component/')) {
|
|
96
|
+
return 'component';
|
|
97
|
+
}
|
|
98
|
+
if (lower.startsWith('help-center/') || lower.startsWith('help/') || lower.startsWith('faq')) {
|
|
99
|
+
return 'help';
|
|
100
|
+
}
|
|
101
|
+
if (lower.includes('quickstart') || lower.includes('getting-started') || lower === 'introduction') {
|
|
102
|
+
return 'quickstart';
|
|
103
|
+
}
|
|
104
|
+
return 'guide';
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
class Semaphore {
|
|
108
|
+
constructor(max) {
|
|
109
|
+
this.max = max;
|
|
110
|
+
this.current = 0;
|
|
111
|
+
this.queue = [];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async acquire() {
|
|
115
|
+
if (this.current < this.max) {
|
|
116
|
+
this.current++;
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
await new Promise(resolve => this.queue.push(resolve));
|
|
120
|
+
this.current++;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
release() {
|
|
124
|
+
this.current--;
|
|
125
|
+
if (this.queue.length > 0) {
|
|
126
|
+
const next = this.queue.shift();
|
|
127
|
+
next();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Parse command line arguments
|
|
133
|
+
const args = process.argv.slice(2);
|
|
134
|
+
const projectArgIndex = args.indexOf('--project');
|
|
135
|
+
const projectFromArg = projectArgIndex !== -1 ? args[projectArgIndex + 1] : null;
|
|
136
|
+
const projectName = projectFromArg || process.env.PROJECT_NAME;
|
|
137
|
+
|
|
138
|
+
// Directories to skip when traversing
|
|
139
|
+
const SKIP_DIRS = ['images', 'node_modules', 'files'];
|
|
140
|
+
|
|
141
|
+
// Determine paths based on project
|
|
142
|
+
function getContentDir() {
|
|
143
|
+
if (projectName) {
|
|
144
|
+
// Use JAMDESK_PROJECTS_DIR if set, otherwise fall back to local projects/
|
|
145
|
+
const projectsDir = process.env.JAMDESK_PROJECTS_DIR || path.join(__dirname, '../projects');
|
|
146
|
+
return path.join(projectsDir, projectName);
|
|
147
|
+
}
|
|
148
|
+
return path.join(process.cwd(), 'content');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function getOutputPath() {
|
|
152
|
+
// During build, output goes to public so it's included in the static export
|
|
153
|
+
return path.join(process.cwd(), 'public', 'search-data.json');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function stripMarkdown(text) {
|
|
157
|
+
return text
|
|
158
|
+
.replace(/```[\s\S]*?```/g, '')
|
|
159
|
+
.replace(/`[^`]+`/g, '')
|
|
160
|
+
.replace(/#{1,6}\s/g, '')
|
|
161
|
+
.replace(/\*\*([^*]+)\*\*/g, '$1')
|
|
162
|
+
.replace(/\*([^*]+)\*/g, '$1')
|
|
163
|
+
.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
|
|
164
|
+
.replace(/<[^>]+>/g, '')
|
|
165
|
+
.replace(/!\[([^\]]*)\]\([^)]+\)/g, '')
|
|
166
|
+
.replace(/\n+/g, ' ')
|
|
167
|
+
.trim();
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function extractSections(content) {
|
|
171
|
+
const sections = [];
|
|
172
|
+
const lines = content.split('\n');
|
|
173
|
+
let currentHeading = '';
|
|
174
|
+
let currentContent = [];
|
|
175
|
+
|
|
176
|
+
for (const line of lines) {
|
|
177
|
+
const headingMatch = line.match(/^#{1,6}\s+(.+)$/);
|
|
178
|
+
if (headingMatch) {
|
|
179
|
+
if (currentHeading || currentContent.length > 0) {
|
|
180
|
+
sections.push({
|
|
181
|
+
heading: currentHeading,
|
|
182
|
+
content: currentContent.join('\n'),
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
currentHeading = headingMatch[1];
|
|
186
|
+
currentContent = [];
|
|
187
|
+
} else {
|
|
188
|
+
currentContent.push(line);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (currentHeading || currentContent.length > 0) {
|
|
193
|
+
sections.push({
|
|
194
|
+
heading: currentHeading,
|
|
195
|
+
content: currentContent.join('\n'),
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return sections;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
async function buildSearchIndex() {
|
|
203
|
+
const contentDir = getContentDir();
|
|
204
|
+
const outputPath = getOutputPath();
|
|
205
|
+
|
|
206
|
+
if (projectName) {
|
|
207
|
+
console.log(`Building search index for project: ${projectName}`);
|
|
208
|
+
}
|
|
209
|
+
console.log(`Content directory: ${contentDir}`);
|
|
210
|
+
|
|
211
|
+
if (!fs.existsSync(contentDir)) {
|
|
212
|
+
console.error(`Error: Content directory not found: ${contentDir}`);
|
|
213
|
+
process.exit(1);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// First, collect all MDX file paths
|
|
217
|
+
const mdxFiles = [];
|
|
218
|
+
|
|
219
|
+
function collectFiles(dir, basePath = '') {
|
|
220
|
+
const files = fs.readdirSync(dir);
|
|
221
|
+
|
|
222
|
+
for (const file of files) {
|
|
223
|
+
// Skip hidden files/directories (like .claude, .git, etc.)
|
|
224
|
+
if (file.startsWith('.')) continue;
|
|
225
|
+
|
|
226
|
+
const filePath = path.join(dir, file);
|
|
227
|
+
|
|
228
|
+
// Handle broken symlinks gracefully
|
|
229
|
+
let stat;
|
|
230
|
+
try {
|
|
231
|
+
stat = fs.statSync(filePath);
|
|
232
|
+
} catch (e) {
|
|
233
|
+
// Broken symlink or inaccessible file - skip
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (stat.isDirectory()) {
|
|
238
|
+
// Skip non-content directories
|
|
239
|
+
if (SKIP_DIRS.includes(file)) continue;
|
|
240
|
+
collectFiles(filePath, path.join(basePath, file));
|
|
241
|
+
} else if (file.endsWith('.mdx')) {
|
|
242
|
+
const slug = path.join(basePath, file.replace(/\.mdx$/, ''));
|
|
243
|
+
mdxFiles.push({ filePath, slug });
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
collectFiles(contentDir);
|
|
249
|
+
console.log(`Found ${mdxFiles.length} MDX files, processing with concurrency ${CONCURRENCY}...`);
|
|
250
|
+
|
|
251
|
+
// Process files in parallel with semaphore
|
|
252
|
+
const semaphore = new Semaphore(CONCURRENCY);
|
|
253
|
+
|
|
254
|
+
async function processFile({ filePath, slug }) {
|
|
255
|
+
await semaphore.acquire();
|
|
256
|
+
try {
|
|
257
|
+
const fileContents = await fsPromises.readFile(filePath, 'utf8');
|
|
258
|
+
const { data, content } = parseFrontmatterLenient(fileContents);
|
|
259
|
+
const sections = extractSections(content);
|
|
260
|
+
|
|
261
|
+
const docs = [];
|
|
262
|
+
const normalizedSlug = slug.replace(/\\/g, '/');
|
|
263
|
+
const pageType = inferPageType(normalizedSlug);
|
|
264
|
+
sections.forEach((section, idx) => {
|
|
265
|
+
const cleanContent = stripMarkdown(section.content);
|
|
266
|
+
if (cleanContent.trim()) {
|
|
267
|
+
docs.push({
|
|
268
|
+
id: `${slug}-${idx}`,
|
|
269
|
+
title: data.title || slug.split('/').pop() || '',
|
|
270
|
+
description: data.description,
|
|
271
|
+
content: cleanContent.substring(0, 300),
|
|
272
|
+
slug: normalizedSlug,
|
|
273
|
+
section: section.heading || undefined,
|
|
274
|
+
type: pageType,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
return docs;
|
|
279
|
+
} finally {
|
|
280
|
+
semaphore.release();
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Process all files in parallel
|
|
285
|
+
const results = await Promise.all(mdxFiles.map(processFile));
|
|
286
|
+
const documents = results.flat();
|
|
287
|
+
|
|
288
|
+
// Ensure output directory exists
|
|
289
|
+
const outputDir = path.dirname(outputPath);
|
|
290
|
+
if (!fs.existsSync(outputDir)) {
|
|
291
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// Write to public directory
|
|
295
|
+
await fsPromises.writeFile(outputPath, JSON.stringify(documents, null, 2));
|
|
296
|
+
|
|
297
|
+
console.log(`✓ Built search index with ${documents.length} documents`);
|
|
298
|
+
console.log(`✓ Saved to ${outputPath}`);
|
|
299
|
+
|
|
300
|
+
// Build pre-built Orama index for MCP server (faster cold starts)
|
|
301
|
+
await buildOramaIndex(documents, outputDir);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Build and serialize an Orama search index for use by the MCP server.
|
|
306
|
+
* The pre-built index loads ~4x faster than building from search-data.json.
|
|
307
|
+
*/
|
|
308
|
+
async function buildOramaIndex(searchData, outputDir) {
|
|
309
|
+
const db = await create({
|
|
310
|
+
schema: {
|
|
311
|
+
id: 'string',
|
|
312
|
+
title: 'string',
|
|
313
|
+
description: 'string',
|
|
314
|
+
content: 'string',
|
|
315
|
+
slug: 'string',
|
|
316
|
+
section: 'string',
|
|
317
|
+
type: 'string',
|
|
318
|
+
},
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
// Normalize data (ensure all fields exist)
|
|
322
|
+
const normalizedData = searchData.map(item => ({
|
|
323
|
+
id: item.id,
|
|
324
|
+
title: item.title,
|
|
325
|
+
description: item.description || '',
|
|
326
|
+
content: item.content,
|
|
327
|
+
slug: item.slug,
|
|
328
|
+
section: item.section || '',
|
|
329
|
+
type: item.type || 'guide',
|
|
330
|
+
}));
|
|
331
|
+
|
|
332
|
+
await insertMultiple(db, normalizedData);
|
|
333
|
+
|
|
334
|
+
// Serialize the index using the persistence plugin
|
|
335
|
+
const serialized = await persist(db, 'json');
|
|
336
|
+
|
|
337
|
+
// Write to public directory (will be uploaded to R2)
|
|
338
|
+
const indexPath = path.join(outputDir, 'search-index.orama.json');
|
|
339
|
+
await fsPromises.writeFile(indexPath, JSON.stringify(serialized));
|
|
340
|
+
|
|
341
|
+
console.log(`✓ Built Orama index for MCP server`);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
buildSearchIndex().catch(err => {
|
|
345
|
+
console.error('Error building search index:', err);
|
|
346
|
+
process.exit(1);
|
|
347
|
+
});
|