blume 2.0.2 → 2.1.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/AGENTS.md +1 -0
- package/CHANGELOG.md +113 -0
- package/README.md +1 -1
- package/dist/cli/{chunk-6k4ftwze.js → chunk-0gz36akr.js} +18 -2
- package/dist/cli/{chunk-6k4ftwze.js.map → chunk-0gz36akr.js.map} +3 -3
- package/dist/cli/{chunk-zp79m0ts.js → chunk-1n228xqb.js} +2 -2
- package/dist/cli/{chunk-ddndchfr.js → chunk-2f3ndkpw.js} +57 -29
- package/dist/cli/chunk-2f3ndkpw.js.map +14 -0
- package/dist/cli/{chunk-fsmrqk8a.js → chunk-2f7n4qzt.js} +8 -2
- package/dist/cli/{chunk-fsmrqk8a.js.map → chunk-2f7n4qzt.js.map} +3 -3
- package/dist/cli/{chunk-ppzjqwx2.js → chunk-2n4ps1b3.js} +17 -18
- package/dist/cli/{chunk-ppzjqwx2.js.map → chunk-2n4ps1b3.js.map} +3 -3
- package/dist/cli/{chunk-5r8g91qn.js → chunk-43zcf4gz.js} +398 -159
- package/dist/cli/chunk-43zcf4gz.js.map +36 -0
- package/dist/cli/chunk-4ejxbzee.js +39 -0
- package/dist/cli/chunk-4ejxbzee.js.map +10 -0
- package/dist/cli/{chunk-hr8ne106.js → chunk-4h8z9vv5.js} +296 -77
- package/dist/cli/chunk-4h8z9vv5.js.map +16 -0
- package/dist/cli/{chunk-k7pj68a8.js → chunk-5cg2rzgf.js} +18 -16
- package/dist/cli/{chunk-k7pj68a8.js.map → chunk-5cg2rzgf.js.map} +2 -2
- package/dist/cli/{chunk-h2ez8dzb.js → chunk-5ffywsmb.js} +4 -4
- package/dist/cli/{chunk-g698a744.js → chunk-5wj2qwn2.js} +5 -5
- package/dist/cli/chunk-6bm0xpgd.js +18 -0
- package/dist/cli/chunk-6bm0xpgd.js.map +10 -0
- package/dist/cli/{chunk-3yce002v.js → chunk-713mngdq.js} +15 -8
- package/dist/cli/chunk-713mngdq.js.map +14 -0
- package/dist/cli/{chunk-91ws1n6j.js → chunk-9geymqns.js} +17 -15
- package/dist/cli/{chunk-91ws1n6j.js.map → chunk-9geymqns.js.map} +2 -2
- package/dist/cli/{chunk-6dtt0zfn.js → chunk-9xr4dgee.js} +27 -18
- package/dist/cli/chunk-9xr4dgee.js.map +10 -0
- package/dist/cli/{chunk-sqw4ekg1.js → chunk-amrb6hgh.js} +2 -2
- package/dist/cli/chunk-cm89scdv.js +443 -0
- package/dist/cli/chunk-cm89scdv.js.map +11 -0
- package/dist/cli/{chunk-wdrt2k2v.js → chunk-cmtcnh9f.js} +90 -26
- package/dist/cli/chunk-cmtcnh9f.js.map +10 -0
- package/dist/cli/chunk-cy5bm0j0.js +104 -0
- package/dist/cli/chunk-cy5bm0j0.js.map +11 -0
- package/dist/cli/{chunk-7mbqtmgb.js → chunk-e7vvk5ya.js} +21 -12
- package/dist/cli/chunk-e7vvk5ya.js.map +10 -0
- package/dist/cli/{chunk-qkb5a8sa.js → chunk-g2z9x01v.js} +6 -98
- package/dist/cli/chunk-g2z9x01v.js.map +10 -0
- package/dist/cli/{chunk-273ygyr4.js → chunk-ga0pf4aj.js} +7 -7
- package/dist/cli/{chunk-273ygyr4.js.map → chunk-ga0pf4aj.js.map} +3 -3
- package/dist/cli/{chunk-h7k3nq3v.js → chunk-gp84za0h.js} +2 -2
- package/dist/cli/{chunk-hqp2ajnh.js → chunk-h2a48yhd.js} +195 -73
- package/dist/cli/chunk-h2a48yhd.js.map +36 -0
- package/dist/cli/{chunk-pbg5a4s3.js → chunk-jnwj5kjj.js} +71 -47
- package/dist/cli/chunk-jnwj5kjj.js.map +19 -0
- package/dist/cli/chunk-kwrg63tm.js +31 -0
- package/dist/cli/chunk-kwrg63tm.js.map +10 -0
- package/dist/cli/{chunk-8g8ytmgx.js → chunk-nd1821sk.js} +21 -19
- package/dist/cli/{chunk-8g8ytmgx.js.map → chunk-nd1821sk.js.map} +2 -2
- package/dist/cli/{chunk-w4bxdvsa.js → chunk-ntv4qrt7.js} +17 -15
- package/dist/cli/{chunk-w4bxdvsa.js.map → chunk-ntv4qrt7.js.map} +2 -2
- package/dist/cli/{chunk-bfwp9vp6.js → chunk-p804f3pe.js} +7 -7
- package/dist/cli/{chunk-4e9b9ra6.js → chunk-py62fewh.js} +6 -6
- package/dist/cli/{chunk-4e9b9ra6.js.map → chunk-py62fewh.js.map} +1 -1
- package/dist/cli/chunk-q3wxxq39.js +126 -0
- package/dist/cli/chunk-q3wxxq39.js.map +11 -0
- package/dist/cli/{chunk-j85scx15.js → chunk-rekqz4qg.js} +142 -46
- package/dist/cli/chunk-rekqz4qg.js.map +10 -0
- package/dist/cli/{chunk-00gs3wqs.js → chunk-ta27feev.js} +1 -1
- package/dist/cli/{chunk-v6ya5kcb.js → chunk-xkz5xbtv.js} +4031 -1132
- package/dist/cli/chunk-xkz5xbtv.js.map +213 -0
- package/dist/cli/{chunk-bbnwccaz.js → chunk-y4ykbark.js} +2 -2
- package/dist/cli/{chunk-n1yg3tj3.js → chunk-y5h4r2y0.js} +6 -6
- package/dist/cli/{chunk-n1yg3tj3.js.map → chunk-y5h4r2y0.js.map} +3 -3
- package/dist/cli/{chunk-nfcyttvj.js → chunk-yj17vs39.js} +9 -9
- package/dist/cli/{chunk-nfcyttvj.js.map → chunk-yj17vs39.js.map} +1 -1
- package/dist/cli/{chunk-7vtckvaw.js → chunk-yxmk4pec.js} +16 -14
- package/dist/cli/{chunk-7vtckvaw.js.map → chunk-yxmk4pec.js.map} +2 -2
- package/dist/cli/{chunk-gs7r695n.js → chunk-zccbjcj0.js} +22 -8
- package/dist/cli/{chunk-gs7r695n.js.map → chunk-zccbjcj0.js.map} +3 -3
- package/dist/cli/{chunk-xh43dwgw.js → chunk-zf748avv.js} +415 -225
- package/dist/cli/chunk-zf748avv.js.map +37 -0
- package/dist/cli/{chunk-d1v5rhy0.js → chunk-zhvd6adm.js} +16 -14
- package/dist/cli/{chunk-d1v5rhy0.js.map → chunk-zhvd6adm.js.map} +2 -2
- package/dist/cli/index.js +28 -20
- package/dist/cli/index.js.map +5 -5
- package/dist/types/ai/agent-surface.d.ts +8 -7
- package/dist/types/ai/ai-catalog.d.ts +7 -0
- package/dist/types/ai/ask-context.d.ts +22 -0
- package/dist/types/ai/ask.d.ts +271 -58
- package/dist/types/ai/index.d.ts +2 -2
- package/dist/types/ai/link-headers.d.ts +8 -1
- package/dist/types/ai/openapi-components.d.ts +5 -2
- package/dist/types/ai/relative-links.d.ts +9 -7
- package/dist/types/ai/site-skill.d.ts +26 -0
- package/dist/types/ai/skills.d.ts +20 -1
- package/dist/types/ai/tar.d.ts +1 -3
- package/dist/types/analytics/index.d.ts +2 -0
- package/dist/types/analytics/one-dollar-stats.d.ts +48 -0
- package/dist/types/analytics/schema.d.ts +14 -0
- package/dist/types/astro/integration.d.ts +11 -2
- package/dist/types/captcha/hcaptcha.d.ts +27 -0
- package/dist/types/captcha/index.d.ts +28 -0
- package/dist/types/captcha/schema.d.ts +29 -0
- package/dist/types/captcha/turnstile.d.ts +28 -0
- package/dist/types/components/content/api-field.d.ts +59 -0
- package/dist/types/components/content/api-page.d.ts +95 -0
- package/dist/types/components/layout/nav-utils.d.ts +26 -0
- package/dist/types/components/openapi/helpers.d.ts +137 -0
- package/dist/types/components/openapi/security.d.ts +85 -0
- package/dist/types/consent/ethyca.d.ts +48 -0
- package/dist/types/consent/index.d.ts +37 -0
- package/dist/types/consent/native.d.ts +28 -0
- package/dist/types/consent/osano.d.ts +42 -0
- package/dist/types/consent/schema.d.ts +110 -0
- package/dist/types/core/base-path.d.ts +21 -7
- package/dist/types/core/config-input.d.ts +196 -27
- package/dist/types/core/data.d.ts +49 -4
- package/dist/types/core/directive-diagnostics.d.ts +12 -0
- package/dist/types/core/footer.d.ts +8 -0
- package/dist/types/core/heading-markers.d.ts +5 -7
- package/dist/types/core/i18n-ui.d.ts +86 -0
- package/dist/types/core/i18n.d.ts +2 -0
- package/dist/types/core/includes.d.ts +8 -2
- package/dist/types/core/last-modified.d.ts +10 -0
- package/dist/types/core/localizable.d.ts +7 -0
- package/dist/types/core/meta.d.ts +8 -0
- package/dist/types/core/page-modes.d.ts +29 -0
- package/dist/types/core/redirect-patterns.d.ts +144 -0
- package/dist/types/core/related.d.ts +40 -0
- package/dist/types/core/schema.d.ts +558 -56
- package/dist/types/core/sources/lower.d.ts +29 -16
- package/dist/types/core/sources/normalize.d.ts +13 -1
- package/dist/types/core/sources/read.d.ts +5 -0
- package/dist/types/core/sources/watch.d.ts +12 -5
- package/dist/types/core/standard-schema.d.ts +5 -0
- package/dist/types/core/types.d.ts +1 -1
- package/dist/types/core/variables.d.ts +42 -0
- package/dist/types/deploy/artifacts.d.ts +6 -4
- package/dist/types/deploy/headers.d.ts +5 -0
- package/dist/types/deploy/node-headers.d.ts +13 -2
- package/dist/types/deploy/platforms/cloudflare.d.ts +5 -0
- package/dist/types/deploy/platforms/netlify.d.ts +7 -0
- package/dist/types/deploy/platforms/types.d.ts +8 -0
- package/dist/types/deploy/platforms/vercel.d.ts +6 -0
- package/dist/types/deploy/redirects.d.ts +61 -22
- package/dist/types/deploy/vercel-negotiation.d.ts +9 -0
- package/dist/types/markdown/code-title.d.ts +17 -0
- package/dist/types/markdown/directives.d.ts +62 -0
- package/dist/types/markdown/features.d.ts +24 -2
- package/dist/types/markdown/mdast.d.ts +63 -0
- package/dist/types/narration/build.d.ts +70 -0
- package/dist/types/narration/provider.d.ts +26 -0
- package/dist/types/narration/script.d.ts +154 -0
- package/dist/types/openapi/asyncapi.d.ts +4 -2
- package/dist/types/openapi/model.d.ts +12 -6
- package/dist/types/openapi/overlay.d.ts +54 -0
- package/dist/types/openapi/parse.d.ts +13 -0
- package/dist/types/openapi/references.d.ts +14 -4
- package/dist/types/ratelimit/cloudflare.d.ts +39 -0
- package/dist/types/ratelimit/index.d.ts +27 -0
- package/dist/types/ratelimit/memory.d.ts +36 -0
- package/dist/types/ratelimit/schema.d.ts +111 -0
- package/dist/types/ratelimit/upstash.d.ts +21 -0
- package/dist/types/ratelimit/wrangler.d.ts +23 -0
- package/dist/types/reference/asyncapi.d.ts +10 -10
- package/dist/types/reference/graphql.d.ts +13 -10
- package/dist/types/reference/openapi.d.ts +33 -12
- package/dist/types/reference/options.d.ts +45 -5
- package/dist/types/reference/scalar.d.ts +13 -0
- package/dist/types/reference/schema.d.ts +60 -36
- package/dist/types/search/documents.d.ts +12 -1
- package/dist/types/search/orama-index.d.ts +4 -0
- package/dist/types/seo/metatags.d.ts +20 -0
- package/docs/02-deployment.mdx +44 -6
- package/docs/03-upgrading.mdx +4 -4
- package/docs/04-migrating.mdx +1 -1
- package/docs/08-faq.mdx +1 -1
- package/docs/advanced/changelog.mdx +2 -2
- package/docs/advanced/custom-pages.mdx +3 -3
- package/docs/advanced/skills.mdx +14 -0
- package/docs/cli/audit.mdx +38 -2
- package/docs/cli/evals.mdx +3 -3
- package/docs/cli/index.mdx +1 -0
- package/docs/cli/translate.mdx +3 -3
- package/docs/cli/version.mdx +1 -1
- package/docs/configuration/analytics.mdx +22 -1
- package/docs/configuration/assistant.mdx +188 -36
- package/docs/configuration/consent.mdx +100 -0
- package/docs/configuration/customization.mdx +6 -4
- package/docs/configuration/index.mdx +63 -5
- package/docs/configuration/meta.ts +3 -0
- package/docs/configuration/narration.mdx +119 -0
- package/docs/configuration/rate-limiting.mdx +69 -0
- package/docs/configuration/search.mdx +30 -2
- package/docs/configuration/theming.mdx +3 -1
- package/docs/content/components.mdx +107 -1
- package/docs/content/frontmatter.mdx +77 -1
- package/docs/content/i18n.mdx +40 -3
- package/docs/content/includes.mdx +16 -0
- package/docs/content/index.mdx +4 -2
- package/docs/content/islands.mdx +1 -1
- package/docs/content/meta.mdx +4 -1
- package/docs/content/meta.ts +1 -0
- package/docs/content/navigation.mdx +28 -6
- package/docs/content/sources/contentful.mdx +32 -0
- package/docs/content/sources/custom.mdx +39 -0
- package/docs/content/sources/github-releases.mdx +31 -0
- package/docs/content/sources/index.mdx +91 -0
- package/docs/content/sources/meta.ts +16 -0
- package/docs/content/sources/notion.mdx +32 -0
- package/docs/content/sources/obsidian.mdx +37 -0
- package/docs/content/sources/payload.mdx +30 -0
- package/docs/content/sources/remote-mdx.mdx +40 -0
- package/docs/content/sources/sanity.mdx +29 -0
- package/docs/content/sources/strapi.mdx +31 -0
- package/docs/content/syntax.mdx +81 -2
- package/docs/content/variables.mdx +41 -0
- package/docs/content/versioning.mdx +1 -1
- package/docs/discoverability/agent-discovery.mdx +30 -3
- package/docs/discoverability/index.mdx +3 -2
- package/docs/discoverability/llms-txt.mdx +1 -1
- package/docs/discoverability/markdown.mdx +2 -2
- package/docs/discoverability/metadata.mdx +17 -0
- package/docs/discoverability/open-graph.mdx +5 -3
- package/docs/discoverability/rss.mdx +1 -1
- package/docs/references/api-pages.mdx +74 -0
- package/docs/references/asyncapi.mdx +2 -2
- package/docs/references/graphql.mdx +3 -3
- package/docs/references/meta.ts +1 -1
- package/docs/references/openapi.mdx +106 -5
- package/docs/references/scalar.mdx +3 -1
- package/package.json +36 -1
- package/skills/blume/SKILL.md +3 -0
- package/skills/blume-migrate/SKILL.md +5 -5
- package/skills/blume-migrate/references/docusaurus.md +3 -3
- package/skills/blume-migrate/references/fumadocs.md +1 -1
- package/skills/blume-migrate/references/mintlify.md +37 -19
- package/skills/blume-migrate/references/nextra.md +3 -3
- package/skills/blume-migrate/references/starlight.md +2 -1
- package/skills/blume-migrate/scripts/mintlify-codemod.mjs +67 -16
- package/skills/blume-write-skill/SKILL.md +82 -0
- package/src/ai/agent-readability.ts +4 -3
- package/src/ai/agent-surface.ts +9 -7
- package/src/ai/ai-catalog.ts +12 -5
- package/src/ai/api/handlers.ts +2 -2
- package/src/ai/api/spec.ts +2 -2
- package/src/ai/api-catalog.ts +6 -2
- package/src/ai/ask-context.ts +73 -20
- package/src/ai/ask-data.ts +6 -0
- package/src/ai/ask-tools.ts +142 -0
- package/src/ai/ask.ts +354 -76
- package/src/ai/changelog-markdown.ts +2 -2
- package/src/ai/component-markdown.ts +75 -0
- package/src/ai/cors.ts +2 -0
- package/src/ai/index.ts +12 -0
- package/src/ai/link-headers.ts +14 -5
- package/src/ai/llms.ts +24 -9
- package/src/ai/markdown.ts +2 -1
- package/src/ai/mcp/data.ts +6 -0
- package/src/ai/mcp/discovery.ts +2 -2
- package/src/ai/mcp/query.ts +2 -2
- package/src/ai/mcp/server.ts +2 -2
- package/src/ai/openapi-components.ts +31 -9
- package/src/ai/relative-links.ts +42 -26
- package/src/ai/serializers.ts +2 -1
- package/src/ai/site-skill.ts +274 -0
- package/src/ai/skills.ts +49 -3
- package/src/ai/tar.ts +139 -12
- package/src/ai/write-skill.ts +97 -0
- package/src/analytics/head.ts +4 -0
- package/src/analytics/index.ts +5 -0
- package/src/analytics/one-dollar-stats.ts +86 -0
- package/src/analytics/schema.ts +2 -0
- package/src/astro/generate.ts +133 -19
- package/src/astro/include-hmr.ts +31 -12
- package/src/astro/include-refresh.ts +19 -8
- package/src/astro/index.ts +1 -0
- package/src/astro/integration.ts +143 -14
- package/src/astro/module-types.ts +6 -0
- package/src/astro/runtime-modules.ts +28 -13
- package/src/astro/templates.ts +364 -67
- package/src/astro/variables.ts +31 -0
- package/src/audit/catalog.ts +19 -0
- package/src/audit/checks/contrast.ts +183 -0
- package/src/audit/checks/i18n.ts +2 -3
- package/src/audit/checks/indexability.ts +2 -3
- package/src/audit/checks/links.ts +13 -13
- package/src/audit/checks/sitemap.ts +2 -3
- package/src/audit/graph.ts +3 -1
- package/src/audit/redirects.ts +46 -15
- package/src/audit/run.ts +14 -9
- package/src/audit/snapshot.ts +5 -0
- package/src/audit/types.ts +2 -1
- package/src/blume-modules.d.ts +7 -0
- package/src/captcha/client.ts +152 -0
- package/src/captcha/hcaptcha.ts +36 -0
- package/src/captcha/index.ts +28 -0
- package/src/captcha/schema.ts +32 -0
- package/src/captcha/turnstile.ts +38 -0
- package/src/captcha/verify.ts +71 -0
- package/src/cli/args.ts +32 -0
- package/src/cli/command-meta.ts +5 -0
- package/src/cli/commands/audit.ts +4 -1
- package/src/cli/commands/doctor.ts +25 -17
- package/src/cli/commands/eval.ts +19 -11
- package/src/cli/commands/skill.ts +96 -0
- package/src/cli/commands/translate.ts +9 -12
- package/src/cli/commands/validate.ts +3 -1
- package/src/cli/dev-lock.ts +157 -37
- package/src/cli/index.ts +5 -0
- package/src/cli/report-format.ts +11 -6
- package/src/cli/required-secrets.ts +71 -29
- package/src/components/BlumePage.astro +2 -0
- package/src/components/colors.ts +19 -0
- package/src/components/content/ApiEndpoint.astro +18 -0
- package/src/components/content/ApiField.astro +79 -0
- package/src/components/content/ApiPlayground.astro +62 -0
- package/src/components/content/ApiRail.astro +19 -0
- package/src/components/content/Badge.astro +5 -3
- package/src/components/content/Color.astro +1 -0
- package/src/components/content/Component.astro +2 -2
- package/src/components/content/FileTree.astro +1 -0
- package/src/components/content/GithubInfo.astro +1 -0
- package/src/components/content/Panel.astro +1 -0
- package/src/components/content/ParamField.astro +25 -0
- package/src/components/content/RequestExample.astro +17 -0
- package/src/components/content/ResponseExample.astro +17 -0
- package/src/components/content/ResponseField.astro +32 -0
- package/src/components/content/Step.astro +1 -0
- package/src/components/content/Tab.astro +0 -1
- package/src/components/content/Tabs.astro +4 -0
- package/src/components/content/Tile.astro +1 -0
- package/src/components/content/Tooltip.astro +1 -0
- package/src/components/content/Tree.astro +1 -0
- package/src/components/content/TypeTable.astro +4 -1
- package/src/components/content/View.astro +21 -0
- package/src/components/content/ViewSwitcher.astro +168 -0
- package/src/components/content/api-field.ts +100 -0
- package/src/components/content/api-page.ts +224 -0
- package/src/components/content/badge-color.ts +5 -2
- package/src/components/content/base-href.ts +13 -36
- package/src/components/content/view-switcher.ts +71 -0
- package/src/components/index.ts +2 -0
- package/src/components/islands/Assistant.astro +10 -1
- package/src/components/islands/assistant.tsx +125 -18
- package/src/components/islands/base-path.ts +47 -10
- package/src/components/islands/code-question.ts +62 -0
- package/src/components/islands/hooks.ts +145 -40
- package/src/components/islands/support-link.ts +68 -0
- package/src/components/islands/webmcp.ts +4 -2
- package/src/components/layout/Analytics.astro +11 -2
- package/src/components/layout/Banner.astro +14 -10
- package/src/components/layout/Breadcrumbs.astro +11 -4
- package/src/components/layout/ConsentBanner.astro +62 -0
- package/src/components/layout/ConsentHead.astro +38 -0
- package/src/components/layout/Directory.astro +94 -0
- package/src/components/layout/DiscoveryLinks.astro +9 -5
- package/src/components/layout/DrawerSwitchers.astro +51 -0
- package/src/components/layout/Empty.astro +2 -2
- package/src/components/layout/Header.astro +124 -82
- package/src/components/layout/LanguageSwitcher.astro +50 -17
- package/src/components/layout/NarrationPlayer.astro +1085 -0
- package/src/components/layout/NavSelector.astro +35 -9
- package/src/components/layout/NavTabMenu.astro +3 -3
- package/src/components/layout/NavTree.astro +16 -6
- package/src/components/layout/PageActions.astro +4 -3
- package/src/components/layout/PageFeedback.astro +54 -49
- package/src/components/layout/PageLayout.astro +78 -9
- package/src/components/layout/Pagination.astro +3 -3
- package/src/components/layout/ReferenceLayout.astro +17 -6
- package/src/components/layout/RelatedPages.astro +42 -0
- package/src/components/layout/RootLayout.astro +313 -50
- package/src/components/layout/Search.astro +64 -30
- package/src/components/layout/SiteFooter.astro +124 -0
- package/src/components/layout/SiteMetatags.astro +16 -0
- package/src/components/layout/VersionBanner.astro +2 -2
- package/src/components/layout/analytics-client.ts +12 -0
- package/src/components/layout/consent/native.ts +79 -0
- package/src/components/layout/consent/types.ts +37 -0
- package/src/components/layout/footer-links.ts +53 -0
- package/src/components/layout/footer-socials.ts +87 -0
- package/src/components/layout/locale-redirect.ts +107 -0
- package/src/components/layout/nav-utils.ts +83 -0
- package/src/components/layout/page-feedback.ts +96 -0
- package/src/components/layout/search/analytics.ts +98 -0
- package/src/components/layout/search/flexsearch.ts +17 -5
- package/src/components/layout/search/orama-cloud.ts +26 -14
- package/src/components/layout/search/types.ts +20 -0
- package/src/components/layout/search/typesense.ts +5 -1
- package/src/components/layout/toc-active.ts +41 -0
- package/src/components/layout/toc-element.ts +8 -14
- package/src/components/openapi/ApiTagOperations.astro +2 -2
- package/src/components/openapi/AsyncApiOperation.astro +7 -4
- package/src/components/openapi/GraphqlChip.astro +2 -2
- package/src/components/openapi/Operation.astro +163 -13
- package/src/components/openapi/Playground.astro +4 -4
- package/src/components/openapi/RequestBody.astro +6 -4
- package/src/components/openapi/RequestPanel.astro +63 -8
- package/src/components/openapi/Responses.astro +6 -4
- package/src/components/openapi/SchemaTable.astro +7 -0
- package/src/components/openapi/async-snippets.ts +4 -4
- package/src/components/openapi/async.ts +38 -6
- package/src/components/openapi/code-samples.ts +97 -0
- package/src/components/openapi/helpers.ts +19 -9
- package/src/components/openapi/message-composer.ts +6 -1
- package/src/components/openapi/message.ts +17 -2
- package/src/components/openapi/operation-model.ts +81 -11
- package/src/components/openapi/panel.ts +4 -2
- package/src/components/openapi/param-style.ts +181 -0
- package/src/components/openapi/playground-client.ts +73 -16
- package/src/components/openapi/request.ts +190 -26
- package/src/components/openapi/schema-tree.ts +30 -24
- package/src/components/openapi/security.ts +6 -3
- package/src/components/openapi/snippets.ts +953 -13
- package/src/components/openapi/ws-client.ts +18 -2
- package/src/components/props.ts +6 -0
- package/src/consent/client.ts +95 -0
- package/src/consent/clients.ts +19 -0
- package/src/consent/ethyca.ts +71 -0
- package/src/consent/head.ts +24 -0
- package/src/consent/index.ts +37 -0
- package/src/consent/init.ts +29 -0
- package/src/consent/native.ts +36 -0
- package/src/consent/osano.ts +59 -0
- package/src/consent/schema.ts +30 -0
- package/src/core/base-path.ts +62 -16
- package/src/core/builtin-tags.ts +5 -0
- package/src/core/client-address.ts +19 -0
- package/src/core/config-input.ts +203 -27
- package/src/core/data.ts +44 -4
- package/src/core/diagnostics.ts +5 -2
- package/src/core/directive-diagnostics.ts +99 -0
- package/src/core/footer.ts +26 -0
- package/src/core/frontmatter.ts +21 -18
- package/src/core/graph.ts +39 -36
- package/src/core/heading-markers.ts +5 -18
- package/src/core/i18n-ui.ts +82 -2
- package/src/core/i18n.ts +31 -3
- package/src/core/includes.ts +20 -3
- package/src/core/last-modified.ts +25 -3
- package/src/core/links.ts +16 -2
- package/src/core/locale-links.ts +5 -1
- package/src/core/localizable.ts +26 -0
- package/src/core/meta.ts +33 -19
- package/src/core/navigation.ts +71 -20
- package/src/core/page-modes.ts +56 -0
- package/src/core/project-graph.ts +138 -10
- package/src/core/redirect-patterns.ts +491 -0
- package/src/core/related.ts +131 -0
- package/src/core/schema.ts +342 -68
- package/src/core/sources/contentful-rich-text.ts +27 -20
- package/src/core/sources/filesystem.ts +20 -2
- package/src/core/sources/github-releases.ts +25 -6
- package/src/core/sources/lexical.ts +23 -18
- package/src/core/sources/lower.ts +201 -34
- package/src/core/sources/mdx-remote.ts +51 -16
- package/src/core/sources/normalize.ts +327 -91
- package/src/core/sources/notion.ts +52 -25
- package/src/core/sources/obsidian.ts +23 -6
- package/src/core/sources/portable-text.ts +38 -21
- package/src/core/sources/read.ts +8 -3
- package/src/core/sources/strapi-blocks.ts +20 -16
- package/src/core/sources/watch.ts +20 -7
- package/src/core/standard-schema.ts +10 -6
- package/src/core/types.ts +1 -1
- package/src/core/ui-packs/ar.ts +43 -0
- package/src/core/ui-packs/bg.ts +45 -0
- package/src/core/ui-packs/bn.ts +43 -0
- package/src/core/ui-packs/ca.ts +46 -0
- package/src/core/ui-packs/cs.ts +44 -0
- package/src/core/ui-packs/da.ts +45 -0
- package/src/core/ui-packs/de.ts +46 -0
- package/src/core/ui-packs/el.ts +45 -0
- package/src/core/ui-packs/es.ts +46 -0
- package/src/core/ui-packs/fa.ts +45 -0
- package/src/core/ui-packs/fi.ts +45 -0
- package/src/core/ui-packs/fr.ts +46 -0
- package/src/core/ui-packs/he.ts +43 -0
- package/src/core/ui-packs/hi.ts +44 -0
- package/src/core/ui-packs/hr.ts +45 -0
- package/src/core/ui-packs/hu.ts +44 -0
- package/src/core/ui-packs/id.ts +45 -0
- package/src/core/ui-packs/it.ts +45 -0
- package/src/core/ui-packs/ja.ts +45 -0
- package/src/core/ui-packs/ko.ts +44 -0
- package/src/core/ui-packs/nl.ts +46 -0
- package/src/core/ui-packs/no.ts +44 -0
- package/src/core/ui-packs/pl.ts +45 -0
- package/src/core/ui-packs/pt-br.ts +46 -0
- package/src/core/ui-packs/pt.ts +45 -0
- package/src/core/ui-packs/ro.ts +45 -0
- package/src/core/ui-packs/ru.ts +45 -0
- package/src/core/ui-packs/sk.ts +44 -0
- package/src/core/ui-packs/sr.ts +45 -0
- package/src/core/ui-packs/sv.ts +44 -0
- package/src/core/ui-packs/th.ts +43 -0
- package/src/core/ui-packs/tr.ts +45 -0
- package/src/core/ui-packs/uk.ts +45 -0
- package/src/core/ui-packs/vi.ts +45 -0
- package/src/core/ui-packs/zh-tw.ts +43 -0
- package/src/core/ui-packs/zh.ts +43 -0
- package/src/core/variables.ts +103 -0
- package/src/core/version-cut.ts +52 -15
- package/src/deploy/artifacts.ts +104 -14
- package/src/deploy/cloudflare-negotiation.ts +39 -17
- package/src/deploy/headers.ts +10 -5
- package/src/deploy/node-headers.ts +64 -10
- package/src/deploy/platforms/cloudflare.ts +44 -3
- package/src/deploy/platforms/netlify.ts +34 -1
- package/src/deploy/platforms/node.ts +1 -0
- package/src/deploy/platforms/static.ts +1 -0
- package/src/deploy/platforms/types.ts +8 -0
- package/src/deploy/platforms/vercel.ts +38 -2
- package/src/deploy/redirects.ts +139 -36
- package/src/deploy/robots.ts +2 -2
- package/src/deploy/rss.ts +4 -3
- package/src/deploy/sitemap.ts +7 -5
- package/src/deploy/vercel-negotiation.ts +36 -0
- package/src/markdown/api-rail.ts +259 -0
- package/src/markdown/base-links.ts +34 -36
- package/src/markdown/code-title.ts +35 -9
- package/src/markdown/directives.ts +242 -36
- package/src/markdown/features.ts +20 -2
- package/src/markdown/fence-meta.ts +2 -0
- package/src/markdown/include.ts +11 -1
- package/src/markdown/index.ts +35 -11
- package/src/markdown/math.ts +4 -4
- package/src/markdown/mdast.ts +5 -2
- package/src/markdown/relative-links.ts +12 -4
- package/src/markdown/variables.ts +56 -0
- package/src/markdown/views.ts +82 -0
- package/src/narration/build.ts +412 -0
- package/src/narration/player.ts +249 -0
- package/src/narration/provider.ts +29 -0
- package/src/narration/script.ts +592 -0
- package/src/og/card.ts +136 -11
- package/src/og/derive.ts +41 -31
- package/src/og/index.ts +1 -0
- package/src/openapi/asyncapi.ts +4 -2
- package/src/openapi/model.ts +77 -36
- package/src/openapi/overlay.ts +256 -0
- package/src/openapi/parse.ts +55 -2
- package/src/openapi/proxy.ts +63 -10
- package/src/openapi/references.ts +21 -5
- package/src/openapi/render-mdx.ts +46 -3
- package/src/openapi/scalar.ts +40 -6
- package/src/openapi/source.ts +1 -1
- package/src/ratelimit/cloudflare.ts +54 -0
- package/src/ratelimit/index.ts +30 -0
- package/src/ratelimit/memory.ts +45 -0
- package/src/ratelimit/runtime.ts +229 -0
- package/src/ratelimit/schema.ts +28 -0
- package/src/ratelimit/upstash.ts +30 -0
- package/src/ratelimit/wrangler.ts +70 -0
- package/src/reference/asyncapi.ts +2 -2
- package/src/reference/graphql.ts +5 -2
- package/src/reference/openapi.ts +21 -7
- package/src/reference/options.ts +51 -7
- package/src/reference/scalar.ts +33 -8
- package/src/registry/eject.ts +201 -28
- package/src/registry/registry.ts +7 -0
- package/src/search/adapters/version-scope.ts +30 -0
- package/src/search/documents.ts +93 -28
- package/src/search/orama-index.ts +28 -3
- package/src/search/pagefind-ranking.ts +39 -0
- package/src/search/popular.ts +2 -1
- package/src/search/sync/algolia.ts +15 -4
- package/src/search/sync/orama-cloud.ts +3 -0
- package/src/search/sync/typesense.ts +5 -0
- package/src/seo/jsonld.ts +7 -3
- package/src/seo/metatags.ts +67 -0
- package/src/theme/chrome-icons.ts +1 -0
- package/src/theme/color.ts +500 -0
- package/src/theme/entry.ts +56 -3
- package/src/theme/palette.ts +121 -45
- package/src/translate/meta.ts +68 -24
- package/src/translate/prompts.ts +1 -0
- package/src/translate/run.ts +3 -3
- package/src/translate/validate.ts +12 -3
- package/src/translate/work-list.ts +56 -17
- package/src/upgrade/upgrade.ts +4 -171
- package/dist/cli/chunk-3yce002v.js.map +0 -14
- package/dist/cli/chunk-5r8g91qn.js.map +0 -34
- package/dist/cli/chunk-6dtt0zfn.js.map +0 -10
- package/dist/cli/chunk-7mbqtmgb.js.map +0 -10
- package/dist/cli/chunk-ddndchfr.js.map +0 -14
- package/dist/cli/chunk-esh98wmb.js +0 -23
- package/dist/cli/chunk-esh98wmb.js.map +0 -10
- package/dist/cli/chunk-hqp2ajnh.js.map +0 -35
- package/dist/cli/chunk-hr8ne106.js.map +0 -13
- package/dist/cli/chunk-j85scx15.js.map +0 -10
- package/dist/cli/chunk-mqc662a6.js +0 -75
- package/dist/cli/chunk-mqc662a6.js.map +0 -11
- package/dist/cli/chunk-pbg5a4s3.js.map +0 -19
- package/dist/cli/chunk-qkb5a8sa.js.map +0 -10
- package/dist/cli/chunk-v6ya5kcb.js.map +0 -189
- package/dist/cli/chunk-wdrt2k2v.js.map +0 -10
- package/dist/cli/chunk-xh43dwgw.js.map +0 -36
- package/docs/content/sources.mdx +0 -338
- /package/dist/cli/{chunk-zp79m0ts.js.map → chunk-1n228xqb.js.map} +0 -0
- /package/dist/cli/{chunk-h2ez8dzb.js.map → chunk-5ffywsmb.js.map} +0 -0
- /package/dist/cli/{chunk-g698a744.js.map → chunk-5wj2qwn2.js.map} +0 -0
- /package/dist/cli/{chunk-sqw4ekg1.js.map → chunk-amrb6hgh.js.map} +0 -0
- /package/dist/cli/{chunk-h7k3nq3v.js.map → chunk-gp84za0h.js.map} +0 -0
- /package/dist/cli/{chunk-bfwp9vp6.js.map → chunk-p804f3pe.js.map} +0 -0
- /package/dist/cli/{chunk-00gs3wqs.js.map → chunk-ta27feev.js.map} +0 -0
- /package/dist/cli/{chunk-bbnwccaz.js.map → chunk-y4ykbark.js.map} +0 -0
package/src/core/meta.ts
CHANGED
|
@@ -89,6 +89,38 @@ const withinInclude = (
|
|
|
89
89
|
(pattern) => !pattern.startsWith("!") && onPathOf(dir, globBase(pattern))
|
|
90
90
|
);
|
|
91
91
|
|
|
92
|
+
/**
|
|
93
|
+
* The folder-meta files a filesystem source contributes: `patterns` (every
|
|
94
|
+
* meta module name, shared `meta.$.*` included, by default) under the source's
|
|
95
|
+
* root, minus its `exclude` globs, dependencies, and build output, and only in
|
|
96
|
+
* folders its `include` globs reach. `blume translate` finds the meta files it
|
|
97
|
+
* translates through this too, so it covers exactly the ones the scan reads.
|
|
98
|
+
*/
|
|
99
|
+
export const findFolderMetaFiles = async (
|
|
100
|
+
source: FolderMetaSource,
|
|
101
|
+
patterns: readonly string[] = META_FILES
|
|
102
|
+
): Promise<string[]> => {
|
|
103
|
+
const found = await glob([...patterns], {
|
|
104
|
+
absolute: true,
|
|
105
|
+
cwd: source.root,
|
|
106
|
+
// Never descend into dependencies or build output — relevant when the
|
|
107
|
+
// root is the project root (e.g. a `.`-rooted or all-staged project).
|
|
108
|
+
// The source's own `exclude` applies too: a `meta.ts` under an excluded
|
|
109
|
+
// folder (`src/lib/meta.ts` beside `exclude: ["src/**"]`) is application
|
|
110
|
+
// code, not folder meta, and importing it would fail.
|
|
111
|
+
ignore: [
|
|
112
|
+
...(source.exclude ?? []),
|
|
113
|
+
"**/node_modules/**",
|
|
114
|
+
"**/.blume/**",
|
|
115
|
+
"**/dist/**",
|
|
116
|
+
],
|
|
117
|
+
onlyFiles: true,
|
|
118
|
+
});
|
|
119
|
+
return found.filter((file) =>
|
|
120
|
+
withinInclude(relative(source.root, dirname(file)), source.include)
|
|
121
|
+
);
|
|
122
|
+
};
|
|
123
|
+
|
|
92
124
|
/**
|
|
93
125
|
* The folder-meta key for a directory. Mirrors the sidebar group path: the
|
|
94
126
|
* source's route prefix (`docs`) followed by the directory relative to the
|
|
@@ -155,25 +187,7 @@ export const discoverFolderMeta = async (
|
|
|
155
187
|
// `content.root` still contributes its folder meta.
|
|
156
188
|
const perSource = await Promise.all(
|
|
157
189
|
list.map(async (source) => {
|
|
158
|
-
const
|
|
159
|
-
absolute: true,
|
|
160
|
-
cwd: source.root,
|
|
161
|
-
// Never descend into dependencies or build output — relevant when the
|
|
162
|
-
// root is the project root (e.g. a `.`-rooted or all-staged project).
|
|
163
|
-
// The source's own `exclude` applies too: a `meta.ts` under an
|
|
164
|
-
// excluded folder (`src/lib/meta.ts` beside `exclude: ["src/**"]`)
|
|
165
|
-
// is application code, not folder meta, and importing it would fail.
|
|
166
|
-
ignore: [
|
|
167
|
-
...(source.exclude ?? []),
|
|
168
|
-
"**/node_modules/**",
|
|
169
|
-
"**/.blume/**",
|
|
170
|
-
"**/dist/**",
|
|
171
|
-
],
|
|
172
|
-
onlyFiles: true,
|
|
173
|
-
});
|
|
174
|
-
const files = found.filter((file) =>
|
|
175
|
-
withinInclude(relative(source.root, dirname(file)), source.include)
|
|
176
|
-
);
|
|
190
|
+
const files = await findFolderMetaFiles(source);
|
|
177
191
|
const loaded = await Promise.all(
|
|
178
192
|
files.map(
|
|
179
193
|
async (
|
package/src/core/navigation.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { extname } from "pathe";
|
|
|
3
3
|
import { stripBasePath, withBasePath } from "./base-path.ts";
|
|
4
4
|
import { orderingPrefix, stripOrderingPrefix } from "./ordering-prefix.ts";
|
|
5
5
|
import type {
|
|
6
|
+
DirectoryMode,
|
|
6
7
|
FolderMeta,
|
|
7
8
|
SidebarDisplay,
|
|
8
9
|
SidebarItemConfig,
|
|
@@ -115,11 +116,29 @@ const numericOrder = (segment: string): number => {
|
|
|
115
116
|
return value ? Math.trunc(Number(value)) : Number.POSITIVE_INFINITY;
|
|
116
117
|
};
|
|
117
118
|
|
|
119
|
+
/**
|
|
120
|
+
* The name inside a group folder's parentheses — `(guides)`, or `01-(guides)`
|
|
121
|
+
* with its ordering prefix outside them — else undefined. A prefix written
|
|
122
|
+
* inside (`(01-guides)`) stays in the name, where it sorts and drops like any
|
|
123
|
+
* folder's.
|
|
124
|
+
*/
|
|
125
|
+
const groupName = (raw: string): string | undefined =>
|
|
126
|
+
(raw.match(GROUP_FOLDER) ?? stripOrderingPrefix(raw).match(GROUP_FOLDER))
|
|
127
|
+
?.groups?.label;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* A folder's sidebar order: its ordering prefix, or — for a group folder
|
|
131
|
+
* without one outside the parentheses — the prefix inside them, so
|
|
132
|
+
* `01-(guides)` and `(01-guides)` both sort like `01-guides`.
|
|
133
|
+
*/
|
|
134
|
+
const folderOrder = (raw: string): number =>
|
|
135
|
+
numericOrder(
|
|
136
|
+
orderingPrefix(raw) === undefined ? (groupName(raw) ?? raw) : raw
|
|
137
|
+
);
|
|
138
|
+
|
|
118
139
|
/** The nav key of a raw path segment: group label or numeric-stripped name. */
|
|
119
|
-
const segmentKey = (raw: string): string =>
|
|
120
|
-
|
|
121
|
-
return stripOrderingPrefix(group ?? raw);
|
|
122
|
-
};
|
|
140
|
+
const segmentKey = (raw: string): string =>
|
|
141
|
+
stripOrderingPrefix(groupName(raw) ?? raw);
|
|
123
142
|
|
|
124
143
|
/**
|
|
125
144
|
* Whether a filename stem is a directory index, ignoring an ordering prefix:
|
|
@@ -184,6 +203,7 @@ interface MutableGroup {
|
|
|
184
203
|
label: string;
|
|
185
204
|
icon?: string;
|
|
186
205
|
collapsed?: boolean;
|
|
206
|
+
directory?: DirectoryMode;
|
|
187
207
|
display?: SidebarDisplay;
|
|
188
208
|
order: number;
|
|
189
209
|
/** Whether `order` is the node's position in its folder meta `pages` list. */
|
|
@@ -221,8 +241,8 @@ const ensureGroup = (
|
|
|
221
241
|
const group = createGroup(
|
|
222
242
|
segmentKey(rawSegment),
|
|
223
243
|
path,
|
|
224
|
-
humanize(rawSegment
|
|
225
|
-
|
|
244
|
+
humanize(groupName(rawSegment) ?? rawSegment),
|
|
245
|
+
folderOrder(rawSegment)
|
|
226
246
|
);
|
|
227
247
|
parent.index.set(rawSegment, group);
|
|
228
248
|
parent.children.push(group);
|
|
@@ -287,9 +307,19 @@ interface FallbackFolderMeta {
|
|
|
287
307
|
meta: (path: string) => FolderMeta | undefined;
|
|
288
308
|
}
|
|
289
309
|
|
|
310
|
+
/** A folder meta's own fields onto its group, over what the folder implied. */
|
|
311
|
+
const applyMetaFields = (group: MutableGroup, meta: FolderMeta): void => {
|
|
312
|
+
group.label = meta.title ?? group.label;
|
|
313
|
+
group.icon = meta.icon ?? group.icon;
|
|
314
|
+
group.order = meta.order ?? group.order;
|
|
315
|
+
group.collapsed = meta.collapsed ?? group.collapsed;
|
|
316
|
+
group.directory = meta.directory ?? group.directory;
|
|
317
|
+
};
|
|
318
|
+
|
|
290
319
|
/**
|
|
291
|
-
* Apply folder meta (title/order/icon/collapsed/display and
|
|
292
|
-
* order), plus the index-frontmatter display sugar collected
|
|
320
|
+
* Apply folder meta (title/order/icon/collapsed/display/directory and
|
|
321
|
+
* explicit page order), plus the index-frontmatter display sugar collected
|
|
322
|
+
* per folder path.
|
|
293
323
|
*/
|
|
294
324
|
const applyFolderMeta = (
|
|
295
325
|
group: MutableGroup,
|
|
@@ -328,10 +358,7 @@ const applyFolderMeta = (
|
|
|
328
358
|
(mirrored ? fallback.indexDisplay.get(group.path) : undefined) ??
|
|
329
359
|
meta?.display;
|
|
330
360
|
if (meta) {
|
|
331
|
-
group
|
|
332
|
-
group.icon = meta.icon ?? group.icon;
|
|
333
|
-
group.order = meta.order ?? group.order;
|
|
334
|
-
group.collapsed = meta.collapsed ?? group.collapsed;
|
|
361
|
+
applyMetaFields(group, meta);
|
|
335
362
|
}
|
|
336
363
|
|
|
337
364
|
for (const child of group.children) {
|
|
@@ -612,7 +639,15 @@ const hoistTabSections = (
|
|
|
612
639
|
}
|
|
613
640
|
};
|
|
614
641
|
|
|
615
|
-
|
|
642
|
+
/**
|
|
643
|
+
* A group's directory mode: its own, else the nearest one set above it (see
|
|
644
|
+
* `directory` in `schema.ts`).
|
|
645
|
+
*/
|
|
646
|
+
const toNavNode = (
|
|
647
|
+
node: MutableNode,
|
|
648
|
+
display: SidebarDisplay,
|
|
649
|
+
inheritedDirectory?: DirectoryMode
|
|
650
|
+
): NavNode => {
|
|
616
651
|
if (node.kind === "page") {
|
|
617
652
|
return {
|
|
618
653
|
badge: node.badge,
|
|
@@ -625,9 +660,13 @@ const toNavNode = (node: MutableNode, display: SidebarDisplay): NavNode => {
|
|
|
625
660
|
route: node.route,
|
|
626
661
|
};
|
|
627
662
|
}
|
|
663
|
+
const directory = node.directory ?? inheritedDirectory;
|
|
628
664
|
return {
|
|
629
|
-
children: node.children.map((child) =>
|
|
665
|
+
children: node.children.map((child) =>
|
|
666
|
+
toNavNode(child, display, directory)
|
|
667
|
+
),
|
|
630
668
|
collapsed: node.collapsed,
|
|
669
|
+
directory,
|
|
631
670
|
display: node.display ?? display,
|
|
632
671
|
icon: node.icon,
|
|
633
672
|
kind: "group",
|
|
@@ -722,7 +761,9 @@ const buildFileSystemSidebar = (
|
|
|
722
761
|
const folderParts = isIndexStem(stem)
|
|
723
762
|
? routeSegments
|
|
724
763
|
: routeSegments.slice(0, -1);
|
|
725
|
-
const routeDirCount = dirs.filter(
|
|
764
|
+
const routeDirCount = dirs.filter(
|
|
765
|
+
(dir) => groupName(dir) === undefined
|
|
766
|
+
).length;
|
|
726
767
|
const offset = Math.max(0, folderParts.length - routeDirCount);
|
|
727
768
|
// A frontmatter `slug` publishes the page away from its folder, so its
|
|
728
769
|
// route says nothing about where the folder lives (`guides/a.md` with
|
|
@@ -744,7 +785,7 @@ const buildFileSystemSidebar = (
|
|
|
744
785
|
const folders: string[] = [];
|
|
745
786
|
for (const dir of dirs) {
|
|
746
787
|
parent = ensureGroup(parent, dir);
|
|
747
|
-
if (
|
|
788
|
+
if (groupName(dir) === undefined) {
|
|
748
789
|
consumed += 1;
|
|
749
790
|
folders.push(stripOrderingPrefix(dir));
|
|
750
791
|
}
|
|
@@ -785,7 +826,9 @@ const buildFileSystemSidebar = (
|
|
|
785
826
|
sortNodes(root.children, diagnostics);
|
|
786
827
|
hoistPages(root.children, display, true);
|
|
787
828
|
hoistTabSections(root.children, tabPaths, display);
|
|
788
|
-
return root.children.map((child) =>
|
|
829
|
+
return root.children.map((child) =>
|
|
830
|
+
toNavNode(child, display, root.directory)
|
|
831
|
+
);
|
|
789
832
|
};
|
|
790
833
|
|
|
791
834
|
/**
|
|
@@ -912,16 +955,24 @@ const buildConfigSidebar = (
|
|
|
912
955
|
items: SidebarItemConfig[],
|
|
913
956
|
byRoute: Map<string, PageRecord>,
|
|
914
957
|
display: SidebarDisplay,
|
|
915
|
-
basePath: string
|
|
958
|
+
basePath: string,
|
|
959
|
+
inheritedDirectory?: DirectoryMode
|
|
916
960
|
): NavNode[] => {
|
|
917
961
|
const nodes: NavNode[] = [];
|
|
918
962
|
for (const item of items) {
|
|
919
963
|
if (!isPageRef(item) && item.items) {
|
|
964
|
+
const directory = item.directory ?? inheritedDirectory;
|
|
920
965
|
nodes.push({
|
|
921
966
|
badge: item.badge,
|
|
922
|
-
children: buildConfigSidebar(
|
|
967
|
+
children: buildConfigSidebar(
|
|
968
|
+
item.items,
|
|
969
|
+
byRoute,
|
|
970
|
+
display,
|
|
971
|
+
basePath,
|
|
972
|
+
directory
|
|
973
|
+
),
|
|
923
974
|
collapsed: item.collapsed,
|
|
924
|
-
directory
|
|
975
|
+
directory,
|
|
925
976
|
display: item.display ?? display,
|
|
926
977
|
icon: item.icon,
|
|
927
978
|
kind: "group",
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Page layout modes (`mode` frontmatter), Mintlify's names for what a page
|
|
3
|
+
* shows around its content:
|
|
4
|
+
*
|
|
5
|
+
* - `default`: the sidebar, the page's title and table of contents, and the
|
|
6
|
+
* page-end links, around the prose column.
|
|
7
|
+
* - `wide`: no table of contents; the content takes its width.
|
|
8
|
+
* - `center`: no sidebar or table of contents; a wider column, centered.
|
|
9
|
+
* For changelogs and other pages read top to bottom.
|
|
10
|
+
* - `custom`: only the header. No sidebar, title, breadcrumbs, table of
|
|
11
|
+
* contents, page-end links, or site footer, and the content spans the
|
|
12
|
+
* page, for a landing page written in MDX.
|
|
13
|
+
* - `frame`: `custom`, keeping the sidebar.
|
|
14
|
+
*
|
|
15
|
+
* Mintlify's `assistant` mode, a full-page chat, has no equivalent.
|
|
16
|
+
*/
|
|
17
|
+
export const PAGE_MODES = [
|
|
18
|
+
"default",
|
|
19
|
+
"wide",
|
|
20
|
+
"center",
|
|
21
|
+
"custom",
|
|
22
|
+
"frame",
|
|
23
|
+
] as const;
|
|
24
|
+
|
|
25
|
+
export type PageMode = (typeof PAGE_MODES)[number];
|
|
26
|
+
|
|
27
|
+
/** What a page shows around its content, and how wide the content runs. */
|
|
28
|
+
export interface PageModeLayout {
|
|
29
|
+
/** The page's own chrome: title, description, breadcrumbs, page-end links, and the site footer. */
|
|
30
|
+
chrome: boolean;
|
|
31
|
+
sidebar: boolean;
|
|
32
|
+
toc: boolean;
|
|
33
|
+
/** `content` is the prose measure, `center` a wider centered column, `full` the whole column. */
|
|
34
|
+
width: "content" | "center" | "full";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** The layout a mode gives a page. */
|
|
38
|
+
export const pageModeLayout = (mode: PageMode = "default"): PageModeLayout => {
|
|
39
|
+
switch (mode) {
|
|
40
|
+
case "wide": {
|
|
41
|
+
return { chrome: true, sidebar: true, toc: false, width: "full" };
|
|
42
|
+
}
|
|
43
|
+
case "center": {
|
|
44
|
+
return { chrome: true, sidebar: false, toc: false, width: "center" };
|
|
45
|
+
}
|
|
46
|
+
case "custom": {
|
|
47
|
+
return { chrome: false, sidebar: false, toc: false, width: "full" };
|
|
48
|
+
}
|
|
49
|
+
case "frame": {
|
|
50
|
+
return { chrome: false, sidebar: true, toc: false, width: "full" };
|
|
51
|
+
}
|
|
52
|
+
default: {
|
|
53
|
+
return { chrome: true, sidebar: true, toc: true, width: "content" };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { isAbsolute, relative } from "pathe";
|
|
2
2
|
|
|
3
|
+
import { withBasePath } from "./base-path.ts";
|
|
3
4
|
import { CHANGELOG_INDEX_ROUTE, hasChangelogIndex } from "./changelog-index.ts";
|
|
4
5
|
import { loadConfig } from "./config.ts";
|
|
5
6
|
import { customStaticRoutes, discoverPages } from "./custom-pages.ts";
|
|
7
|
+
import { unknownDirectiveDiagnostics } from "./directive-diagnostics.ts";
|
|
6
8
|
import { buildContentGraph } from "./graph.ts";
|
|
7
9
|
import { i18nDiagnostics } from "./i18n.ts";
|
|
8
10
|
import { expandIncludes, hasIncludeStatements } from "./includes.ts";
|
|
@@ -10,16 +12,22 @@ import {
|
|
|
10
12
|
gitLastModifiedTimes,
|
|
11
13
|
gitRepositoryRoot,
|
|
12
14
|
lastModifiedShallowWarning,
|
|
15
|
+
realPath,
|
|
13
16
|
resolveLastModifiedConfig,
|
|
14
17
|
} from "./last-modified.ts";
|
|
15
18
|
import { buildManifest } from "./manifest.ts";
|
|
16
19
|
import { discoverFolderMeta } from "./meta.ts";
|
|
17
20
|
import type { FolderMetaSource } from "./meta.ts";
|
|
18
21
|
import { resolveProjectContext } from "./project.ts";
|
|
22
|
+
import { pathsUnderPattern } from "./redirect-patterns.ts";
|
|
19
23
|
import type { ResolvedConfig } from "./schema.ts";
|
|
20
24
|
import { normalizeEntry, strippedLineOffset } from "./sources/normalize.ts";
|
|
21
25
|
import { resolveDocsCollection, resolveSources } from "./sources/resolve.ts";
|
|
22
|
-
import type {
|
|
26
|
+
import type {
|
|
27
|
+
ContentSource,
|
|
28
|
+
SourceEntry,
|
|
29
|
+
SourceLoadResult,
|
|
30
|
+
} from "./sources/types.ts";
|
|
23
31
|
import type {
|
|
24
32
|
BlumeManifest,
|
|
25
33
|
ContentGraph,
|
|
@@ -28,6 +36,12 @@ import type {
|
|
|
28
36
|
PageRecord,
|
|
29
37
|
ProjectContext,
|
|
30
38
|
} from "./types.ts";
|
|
39
|
+
import {
|
|
40
|
+
hasVariables,
|
|
41
|
+
substituteVariables,
|
|
42
|
+
undefinedVariables,
|
|
43
|
+
} from "./variables.ts";
|
|
44
|
+
import type { ContentVariables } from "./variables.ts";
|
|
31
45
|
import { versionsDiagnostics } from "./versions.ts";
|
|
32
46
|
|
|
33
47
|
/** Build mode: drafts are kept in `dev` and dropped in `build`. */
|
|
@@ -196,11 +210,34 @@ const normalizeLoadedEntries = (
|
|
|
196
210
|
}
|
|
197
211
|
pages.push(...normalized.pages);
|
|
198
212
|
allDiagnostics.push(...normalized.diagnostics);
|
|
213
|
+
if (normalized.pages.length > 0) {
|
|
214
|
+
allDiagnostics.push(...unknownDirectiveDiagnostics(entry, source.name));
|
|
215
|
+
}
|
|
199
216
|
}
|
|
200
217
|
}
|
|
201
218
|
return { diagnostics: allDiagnostics, droppedPages, pages };
|
|
202
219
|
};
|
|
203
220
|
|
|
221
|
+
/**
|
|
222
|
+
* The local sources' on-disk roots a `git log` pathspec can cover: those
|
|
223
|
+
* inside the repository at `gitRoot`. A root outside it would fail the log
|
|
224
|
+
* outright and can never yield dates. Compared by real path, since git spells
|
|
225
|
+
* its toplevel with every symlink resolved (`/private/tmp/site` for a project
|
|
226
|
+
* opened as `/tmp/site`); the roots themselves keep the project's spelling.
|
|
227
|
+
*/
|
|
228
|
+
const gitContentRoots = (
|
|
229
|
+
sources: readonly ContentSource[],
|
|
230
|
+
gitRoot: string | null
|
|
231
|
+
): string[] => {
|
|
232
|
+
if (gitRoot === null) {
|
|
233
|
+
return [];
|
|
234
|
+
}
|
|
235
|
+
const top = realPath(gitRoot);
|
|
236
|
+
return sources
|
|
237
|
+
.flatMap((source) => (source.contentRoot ? [source.contentRoot] : []))
|
|
238
|
+
.filter((dir) => isWithin(top, realPath(dir)));
|
|
239
|
+
};
|
|
240
|
+
|
|
204
241
|
/**
|
|
205
242
|
* Run the full core pipeline for a project root: load config, resolve paths,
|
|
206
243
|
* discover content and folder meta, build the graph, and assemble the manifest.
|
|
@@ -221,6 +258,85 @@ const isBannerShorthand = (
|
|
|
221
258
|
banner: NonNullable<ResolvedConfig["banner"]>
|
|
222
259
|
): banner is string => typeof banner === "string";
|
|
223
260
|
|
|
261
|
+
/**
|
|
262
|
+
* Report an entry's undefined content variables at their source lines, then
|
|
263
|
+
* replace the defined ones in the text the scan extracts from: the expanded
|
|
264
|
+
* text when includes were spliced (its `origins` map lines back to the file
|
|
265
|
+
* each came from), else the body.
|
|
266
|
+
*/
|
|
267
|
+
const substituteEntryVariables = (
|
|
268
|
+
entry: SourceEntry,
|
|
269
|
+
variables: ContentVariables
|
|
270
|
+
): Diagnostic[] => {
|
|
271
|
+
const { expanded } = entry;
|
|
272
|
+
const text = expanded?.text ?? entry.body.text;
|
|
273
|
+
const offset = expanded ? 0 : strippedLineOffset(entry.raw, entry.body.text);
|
|
274
|
+
const diagnostics = undefinedVariables(text, variables).map(
|
|
275
|
+
({ line, name }): Diagnostic => {
|
|
276
|
+
const origin = expanded?.origins[line - 1];
|
|
277
|
+
return {
|
|
278
|
+
code: "BLUME_UNDEFINED_VARIABLE",
|
|
279
|
+
file: origin?.file ?? entry.sourcePath,
|
|
280
|
+
line: origin?.line ?? line + offset,
|
|
281
|
+
message: `{{${name}}} isn't a defined variable, so it would show as written.`,
|
|
282
|
+
severity: "error",
|
|
283
|
+
suggestion: `Define "${name}" under variables in blume.config.ts, or put it in inline code to show it as written.`,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
);
|
|
287
|
+
if (expanded) {
|
|
288
|
+
expanded.text = substituteVariables(expanded.text, variables);
|
|
289
|
+
} else {
|
|
290
|
+
entry.body.text = substituteVariables(entry.body.text, variables);
|
|
291
|
+
}
|
|
292
|
+
return diagnostics;
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
/** {@link substituteEntryVariables} over every loaded entry, when any are defined. */
|
|
296
|
+
const substituteLoadedVariables = (
|
|
297
|
+
loaded: readonly SourceLoadResult[],
|
|
298
|
+
variables: ContentVariables
|
|
299
|
+
): Diagnostic[] =>
|
|
300
|
+
hasVariables(variables)
|
|
301
|
+
? loaded.flatMap(({ entries }) =>
|
|
302
|
+
entries.flatMap((entry) => substituteEntryVariables(entry, variables))
|
|
303
|
+
)
|
|
304
|
+
: [];
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* A pattern redirect that also matches a page. Hosts disagree on which
|
|
308
|
+
* answers (Vercel and Cloudflare apply the rule ahead of the page, Netlify
|
|
309
|
+
* and the Node server serve the page), so the pattern is rejected rather than
|
|
310
|
+
* let the answer depend on the host. `pages` are the served page paths, which
|
|
311
|
+
* carry `basePath`, as the based `from` does.
|
|
312
|
+
*/
|
|
313
|
+
const redirectPageDiagnostics = (
|
|
314
|
+
config: ResolvedConfig,
|
|
315
|
+
pages: readonly string[],
|
|
316
|
+
configFile: string | null
|
|
317
|
+
): Diagnostic[] =>
|
|
318
|
+
config.redirects.flatMap((redirect) => {
|
|
319
|
+
const matched = pathsUnderPattern(
|
|
320
|
+
withBasePath(config.basePath, redirect.from),
|
|
321
|
+
pages
|
|
322
|
+
);
|
|
323
|
+
const [first] = matched;
|
|
324
|
+
if (first === undefined) {
|
|
325
|
+
return [];
|
|
326
|
+
}
|
|
327
|
+
const more = matched.length > 1 ? ` and ${matched.length - 1} more` : "";
|
|
328
|
+
return [
|
|
329
|
+
{
|
|
330
|
+
code: "BLUME_REDIRECT_MATCHES_PAGE",
|
|
331
|
+
file: configFile ?? undefined,
|
|
332
|
+
message: `The redirect from ${redirect.from} also matches the page ${first}${more}, which some hosts would redirect and others would serve.`,
|
|
333
|
+
severity: "error",
|
|
334
|
+
suggestion:
|
|
335
|
+
"Narrow the pattern to the paths that moved, or move the pages out from under it.",
|
|
336
|
+
} satisfies Diagnostic,
|
|
337
|
+
];
|
|
338
|
+
});
|
|
339
|
+
|
|
224
340
|
/** The configured banner link target, when the banner has a link. */
|
|
225
341
|
const bannerLinkHref = (
|
|
226
342
|
banner: ResolvedConfig["banner"]
|
|
@@ -327,6 +443,14 @@ export const scanProject = async (
|
|
|
327
443
|
})
|
|
328
444
|
);
|
|
329
445
|
|
|
446
|
+
// Content variables: an undefined name in prose is an error at its source
|
|
447
|
+
// line, and every defined one is replaced in the text headings, links, and
|
|
448
|
+
// components are extracted from, so they match the rendered page.
|
|
449
|
+
const variableDiagnostics = substituteLoadedVariables(
|
|
450
|
+
loaded,
|
|
451
|
+
config.variables
|
|
452
|
+
);
|
|
453
|
+
|
|
330
454
|
// Folder meta contributed by the sources themselves (the OpenAPI source
|
|
331
455
|
// labels each tag directory with the spec's own tag name). It applies to
|
|
332
456
|
// every locale, so it merges into the shared map — beneath user-authored
|
|
@@ -362,12 +486,9 @@ export const scanProject = async (
|
|
|
362
486
|
// The git pathspecs must cover where the pages actually live: each local
|
|
363
487
|
// source's own on-disk root — a filesystem source's `root`, or a staged
|
|
364
488
|
// local source's tree (an Obsidian vault) — which diverges from the global
|
|
365
|
-
// `content.root`.
|
|
366
|
-
// and can never yield dates, so those are dropped up front.
|
|
489
|
+
// `content.root`.
|
|
367
490
|
const gitRoot = gitRepositoryRoot(context.root);
|
|
368
|
-
const contentRoots = sources
|
|
369
|
-
.flatMap((source) => (source.contentRoot ? [source.contentRoot] : []))
|
|
370
|
-
.filter((dir) => gitRoot !== null && isWithin(gitRoot, dir));
|
|
491
|
+
const contentRoots = gitContentRoots(sources, gitRoot);
|
|
371
492
|
const gitTimes = gitLastModifiedTimes(
|
|
372
493
|
context.root,
|
|
373
494
|
contentRoots,
|
|
@@ -402,14 +523,15 @@ export const scanProject = async (
|
|
|
402
523
|
const customPages = context.pagesRoot
|
|
403
524
|
? await discoverPages(context.pagesRoot)
|
|
404
525
|
: [];
|
|
526
|
+
const extraRoutes = new Set([
|
|
527
|
+
...customStaticRoutes(customPages),
|
|
528
|
+
...(hasChangelogIndex(pages, config) ? [CHANGELOG_INDEX_ROUTE] : []),
|
|
529
|
+
]);
|
|
405
530
|
const graph = buildContentGraph(pages, {
|
|
406
531
|
bannerHref: bannerLinkHref(config.banner),
|
|
407
532
|
basePath: config.basePath,
|
|
408
533
|
brandHref: logoHref(config.logo),
|
|
409
|
-
extraRoutes
|
|
410
|
-
...customStaticRoutes(customPages),
|
|
411
|
-
...(hasChangelogIndex(pages, config) ? [CHANGELOG_INDEX_ROUTE] : []),
|
|
412
|
-
]),
|
|
534
|
+
extraRoutes,
|
|
413
535
|
folderMeta: folderMeta.meta,
|
|
414
536
|
i18n: config.i18n,
|
|
415
537
|
navigation: config.navigation,
|
|
@@ -431,6 +553,7 @@ export const scanProject = async (
|
|
|
431
553
|
diagnostics: [
|
|
432
554
|
...contentDiagnostics,
|
|
433
555
|
...includeDiagnostics,
|
|
556
|
+
...variableDiagnostics,
|
|
434
557
|
...folderMeta.diagnostics,
|
|
435
558
|
...entryIdDiagnostics(
|
|
436
559
|
pages,
|
|
@@ -440,6 +563,11 @@ export const scanProject = async (
|
|
|
440
563
|
...i18nWarnings,
|
|
441
564
|
...versionWarnings,
|
|
442
565
|
...lastModifiedWarnings,
|
|
566
|
+
...redirectPageDiagnostics(
|
|
567
|
+
config,
|
|
568
|
+
[...manifest.routes.map((route) => route.path), ...extraRoutes],
|
|
569
|
+
context.configFile
|
|
570
|
+
),
|
|
443
571
|
],
|
|
444
572
|
droppedPages,
|
|
445
573
|
graph,
|