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
|
@@ -15,14 +15,15 @@ import {
|
|
|
15
15
|
pollingWatch,
|
|
16
16
|
snapshotCache,
|
|
17
17
|
} from "./cache.ts";
|
|
18
|
+
import type { InlineRun } from "./lower.ts";
|
|
18
19
|
import {
|
|
19
20
|
codeFence,
|
|
20
21
|
guardBlockStart,
|
|
21
22
|
image,
|
|
23
|
+
linkParts,
|
|
22
24
|
renderInline,
|
|
23
|
-
renderLink,
|
|
24
25
|
} from "./lower.ts";
|
|
25
|
-
import { slugifyPath } from "./normalize.ts";
|
|
26
|
+
import { slugify, slugifyPath } from "./normalize.ts";
|
|
26
27
|
import type {
|
|
27
28
|
ContentSource,
|
|
28
29
|
SourceContext,
|
|
@@ -160,26 +161,43 @@ interface NotionFrontmatter {
|
|
|
160
161
|
[key: string]: boolean | string | { order: number } | undefined;
|
|
161
162
|
}
|
|
162
163
|
|
|
164
|
+
/** Neighboring rich-text runs that link to one `href` (or none), and it. */
|
|
165
|
+
interface LinkedRuns {
|
|
166
|
+
href?: string;
|
|
167
|
+
runs: InlineRun[];
|
|
168
|
+
}
|
|
169
|
+
|
|
163
170
|
/**
|
|
164
|
-
* Rich text as Markdown for an MDX body.
|
|
171
|
+
* Rich text as Markdown for an MDX body. The runs go through the shared
|
|
165
172
|
* lowering, so a literal `{`, `<`, `*`, or `[` typed in Notion renders as
|
|
166
|
-
* itself instead of opening a JSX expression, a tag, or emphasis,
|
|
167
|
-
*
|
|
173
|
+
* itself instead of opening a JSX expression, a tag, or emphasis, a code run
|
|
174
|
+
* keeps its text verbatim inside a long-enough code span, neighbors share
|
|
175
|
+
* their marks' delimiters, and neighbors that link to one `href` share one
|
|
176
|
+
* link.
|
|
168
177
|
*/
|
|
169
|
-
const richToMarkdown = (rich: NotionRichText[] = []): string =>
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
)
|
|
182
|
-
.
|
|
178
|
+
const richToMarkdown = (rich: NotionRichText[] = []): string => {
|
|
179
|
+
const linked: LinkedRuns[] = [];
|
|
180
|
+
for (const { annotations = {}, href, plain_text: text } of rich) {
|
|
181
|
+
const run: InlineRun = {
|
|
182
|
+
marks: {
|
|
183
|
+
bold: annotations.bold,
|
|
184
|
+
code: annotations.code,
|
|
185
|
+
italic: annotations.italic,
|
|
186
|
+
strike: annotations.strikethrough,
|
|
187
|
+
},
|
|
188
|
+
text,
|
|
189
|
+
};
|
|
190
|
+
const last = linked.at(-1);
|
|
191
|
+
if (last && last.href === (href ?? undefined)) {
|
|
192
|
+
last.runs.push(run);
|
|
193
|
+
} else {
|
|
194
|
+
linked.push({ href: href ?? undefined, runs: [run] });
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return renderInline(
|
|
198
|
+
linked.flatMap(({ href, runs }) => linkParts(runs, href))
|
|
199
|
+
);
|
|
200
|
+
};
|
|
183
201
|
|
|
184
202
|
const isBlockPayload = (
|
|
185
203
|
value: NotionBlockPayload | boolean | string | undefined
|
|
@@ -307,10 +325,14 @@ const renderVideo = (data: NotionBlockPayload): string => {
|
|
|
307
325
|
const title = caption ? ` title=${jsxString(richToPlain(data.caption))}` : "";
|
|
308
326
|
// Everything else (a Notion upload, or a direct link to a media file) is a
|
|
309
327
|
// real video file: `materializeAssets` rewrites the `src`, which matters most
|
|
310
|
-
// for uploads, whose Notion URLs are signed and expire.
|
|
328
|
+
// for uploads, whose Notion URLs are signed and expire. It finds the file by
|
|
329
|
+
// that quoted `src`, where MDX decodes no backslash escapes — a JSON
|
|
330
|
+
// string's `\\` and `\"` would corrupt the URL or end the attribute — so the
|
|
331
|
+
// URL goes in as written, with a double quote as the `%22` it means anyway.
|
|
332
|
+
// The embed's `url` takes the expression form, like every string prop here.
|
|
311
333
|
const media = isYouTubeUrl(url)
|
|
312
|
-
? `<YouTube${title} url=${
|
|
313
|
-
: `<video controls src
|
|
334
|
+
? `<YouTube${title} url=${jsxString(url)} />`
|
|
335
|
+
: `<video controls src="${url.replaceAll('"', "%22")}" />`;
|
|
314
336
|
return caption
|
|
315
337
|
? `<Frame caption=${jsxString(caption.replaceAll(FRAME_ESCAPED, ""))}>\n${media}\n</Frame>`
|
|
316
338
|
: media;
|
|
@@ -577,9 +599,14 @@ export const notionSource = (
|
|
|
577
599
|
const slugProp = richToPlain(
|
|
578
600
|
page.properties[props.slug ?? "Slug"]?.rich_text
|
|
579
601
|
);
|
|
580
|
-
//
|
|
581
|
-
// instead of mashing into `guidessetup`.
|
|
582
|
-
|
|
602
|
+
// A Slug property is path-aware: `guides/setup` keeps its `/` (per-segment
|
|
603
|
+
// slugging) instead of mashing into `guidessetup`. A title is one name, so
|
|
604
|
+
// its slashes become hyphens: "CI/CD Setup" routes to `ci-cd-setup`, not
|
|
605
|
+
// to `cd-setup` inside an invented `ci` group.
|
|
606
|
+
const slug =
|
|
607
|
+
(slugProp
|
|
608
|
+
? slugifyPath(slugProp)
|
|
609
|
+
: slugify(title.replaceAll("/", "-"))) || page.id;
|
|
583
610
|
return { data, slug };
|
|
584
611
|
};
|
|
585
612
|
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
resolveEntryRoute,
|
|
22
22
|
slugifyPath,
|
|
23
23
|
strippedLineOffset,
|
|
24
|
+
unloadablePathDiagnostic,
|
|
24
25
|
} from "./normalize.ts";
|
|
25
26
|
import type {
|
|
26
27
|
ContentSource,
|
|
@@ -587,10 +588,11 @@ const transformBody = (
|
|
|
587
588
|
* `[#custom-id]` pin and the `setup-1` a later collision gets are honored
|
|
588
589
|
* rather than re-slugged. When no heading holds anything the rewrite changes,
|
|
589
590
|
* the raw body's headings are the staged body's; otherwise the body is lowered
|
|
590
|
-
* once more so the headings are scanned exactly as they ship. A link
|
|
591
|
-
* heading is rewritten here before
|
|
592
|
-
*
|
|
593
|
-
*
|
|
591
|
+
* once more so the headings are scanned exactly as they ship. A heading link
|
|
592
|
+
* inside a heading is rewritten here before every note's anchors are known,
|
|
593
|
+
* so its href may still lack the anchor it ships with. That moves no id: a
|
|
594
|
+
* heading is slugged by its rendered text, where the link is its label alone,
|
|
595
|
+
* so the heading stays as addressable as any other.
|
|
594
596
|
*/
|
|
595
597
|
const fillAnchors = (pair: IndexedPair, index: LinkIndex): void => {
|
|
596
598
|
const raw = extractHeadings(pair.note.content);
|
|
@@ -958,7 +960,19 @@ export const obsidianSource = (
|
|
|
958
960
|
const exclude = new Set([...BLUME_IGNORE_DIRS, ...(options.exclude ?? [])]);
|
|
959
961
|
|
|
960
962
|
const load = async (): Promise<SourceLoadResult> => {
|
|
961
|
-
|
|
963
|
+
// A note is staged under its vault path, where Astro's content loader
|
|
964
|
+
// can't read a name holding `#` or `?`; such a note is reported and left
|
|
965
|
+
// out, and links to it degrade like links to any missing note.
|
|
966
|
+
const skipped: Diagnostic[] = [];
|
|
967
|
+
const files: string[] = [];
|
|
968
|
+
for (const rel of await walkVault(vaultDir, vaultDir, exclude)) {
|
|
969
|
+
const unloadable = unloadablePathDiagnostic(rel, join(vaultDir, rel));
|
|
970
|
+
if (unloadable) {
|
|
971
|
+
skipped.push(unloadable);
|
|
972
|
+
} else {
|
|
973
|
+
files.push(rel);
|
|
974
|
+
}
|
|
975
|
+
}
|
|
962
976
|
const read = await Promise.all(
|
|
963
977
|
files.map((rel) => readNote(vaultDir, rel, options))
|
|
964
978
|
);
|
|
@@ -971,7 +985,10 @@ export const obsidianSource = (
|
|
|
971
985
|
noteToEntry(pair, index, options, unresolved)
|
|
972
986
|
);
|
|
973
987
|
return {
|
|
974
|
-
diagnostics:
|
|
988
|
+
diagnostics: [
|
|
989
|
+
...skipped,
|
|
990
|
+
...unresolvedDiagnostics(options.name, unresolved),
|
|
991
|
+
],
|
|
975
992
|
entries,
|
|
976
993
|
};
|
|
977
994
|
};
|
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
* user-supplied serializer or are skipped with a noted comment. Output is
|
|
5
5
|
* Markdown text that flows through Blume's normal pipeline.
|
|
6
6
|
*/
|
|
7
|
+
import type { InlineRun } from "./lower.ts";
|
|
7
8
|
import {
|
|
8
9
|
guardBlockStart,
|
|
9
10
|
image,
|
|
11
|
+
linkParts,
|
|
10
12
|
renderInline,
|
|
11
|
-
renderLink,
|
|
12
13
|
unsupported,
|
|
13
14
|
writesMdx,
|
|
14
15
|
} from "./lower.ts";
|
|
@@ -73,38 +74,54 @@ const HEADING_STYLES = new Map([
|
|
|
73
74
|
["h6", "###### "],
|
|
74
75
|
]);
|
|
75
76
|
|
|
76
|
-
/**
|
|
77
|
-
|
|
78
|
-
* uses: prose is escaped, a code span outruns the backticks inside it, edge
|
|
79
|
-
* whitespace stays outside emphasis, and a link def wraps last (so its label
|
|
80
|
-
* keeps emphasis) only when its destination is safe to click.
|
|
81
|
-
*/
|
|
82
|
-
const renderSpan = (
|
|
83
|
-
span: PortableTextSpan,
|
|
84
|
-
defs: Map<string, PortableTextMarkDef>
|
|
85
|
-
): string => {
|
|
77
|
+
/** A span's text and the marks Markdown has syntax for. */
|
|
78
|
+
const spanRun = (span: PortableTextSpan): InlineRun => {
|
|
86
79
|
const marks = span.marks ?? [];
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
.findLast((def) => def?._type === "link");
|
|
90
|
-
return renderLink(
|
|
91
|
-
renderInline(span.text ?? "", {
|
|
80
|
+
return {
|
|
81
|
+
marks: {
|
|
92
82
|
bold: marks.includes("strong"),
|
|
93
83
|
code: marks.includes("code"),
|
|
94
84
|
italic: marks.includes("em"),
|
|
95
85
|
strike: marks.includes("strike-through"),
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
|
|
86
|
+
},
|
|
87
|
+
text: span.text ?? "",
|
|
88
|
+
};
|
|
99
89
|
};
|
|
100
90
|
|
|
101
|
-
/**
|
|
91
|
+
/** Neighboring spans under one link def (or none), and that def. */
|
|
92
|
+
interface LinkedSpans {
|
|
93
|
+
link?: PortableTextMarkDef;
|
|
94
|
+
runs: InlineRun[];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Render the inline children of a block to a single Markdown string, through
|
|
99
|
+
* the shared lowering every CMS uses: prose is escaped, a code span outruns
|
|
100
|
+
* the backticks inside it, edge whitespace stays outside emphasis, neighbors
|
|
101
|
+
* share their marks' delimiters, and neighbors under one link def share one
|
|
102
|
+
* link — wrapped last (so its label keeps emphasis), and only when its
|
|
103
|
+
* destination is safe to click.
|
|
104
|
+
*/
|
|
102
105
|
const renderChildren = (block: PortableTextBlock): string => {
|
|
103
106
|
const defs = new Map(
|
|
104
107
|
(block.markDefs ?? []).map((def) => [def._key, def] as const)
|
|
105
108
|
);
|
|
109
|
+
const linked: LinkedSpans[] = [];
|
|
110
|
+
for (const span of block.children ?? []) {
|
|
111
|
+
const link = (span.marks ?? [])
|
|
112
|
+
.map((mark) => defs.get(mark))
|
|
113
|
+
.findLast((def) => def?._type === "link");
|
|
114
|
+
const last = linked.at(-1);
|
|
115
|
+
if (last && last.link === link) {
|
|
116
|
+
last.runs.push(spanRun(span));
|
|
117
|
+
} else {
|
|
118
|
+
linked.push({ link, runs: [spanRun(span)] });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
106
121
|
return guardBlockStart(
|
|
107
|
-
(
|
|
122
|
+
renderInline(
|
|
123
|
+
linked.flatMap(({ link, runs }) => linkParts(runs, link?.href))
|
|
124
|
+
)
|
|
108
125
|
);
|
|
109
126
|
};
|
|
110
127
|
|
package/src/core/sources/read.ts
CHANGED
|
@@ -2,10 +2,14 @@ import { readFile } from "node:fs/promises";
|
|
|
2
2
|
|
|
3
3
|
import { expandIncludes, hasIncludeStatements } from "../includes.ts";
|
|
4
4
|
import type { PageRecord } from "../types.ts";
|
|
5
|
+
import { substituteVariablesInBody } from "../variables.ts";
|
|
6
|
+
import type { ContentVariables } from "../variables.ts";
|
|
5
7
|
import type { ContentSource } from "./types.ts";
|
|
6
8
|
|
|
7
9
|
/** The subset of a scanned project the entry reader needs. */
|
|
8
10
|
export interface EntryReadContext {
|
|
11
|
+
/** The site's content variables, substituted into what's read. */
|
|
12
|
+
config?: { variables?: ContentVariables };
|
|
9
13
|
/** The instantiated sources, keyed for `read()` lookups. */
|
|
10
14
|
sources?: ContentSource[];
|
|
11
15
|
}
|
|
@@ -48,9 +52,10 @@ export const readExpandedEntryText = async (
|
|
|
48
52
|
ctx: EntryReadContext,
|
|
49
53
|
page: PageRecord
|
|
50
54
|
): Promise<string> => {
|
|
55
|
+
const variables = ctx.config?.variables;
|
|
51
56
|
const raw = await readEntryText(ctx, page);
|
|
52
57
|
if (!(page.sourcePath && hasIncludeStatements(raw))) {
|
|
53
|
-
return raw;
|
|
58
|
+
return substituteVariablesInBody(raw, variables);
|
|
54
59
|
}
|
|
55
60
|
const source = ctx.sources?.find(
|
|
56
61
|
(candidate) => candidate.name === page.source.name
|
|
@@ -61,11 +66,11 @@ export const readExpandedEntryText = async (
|
|
|
61
66
|
// here would splice text the rest of the pipeline never validated, with no
|
|
62
67
|
// content-root bound on resolution.
|
|
63
68
|
if (!source || source.staged || !source.contentRoot) {
|
|
64
|
-
return raw;
|
|
69
|
+
return substituteVariablesInBody(raw, variables);
|
|
65
70
|
}
|
|
66
71
|
const expansion = await expandIncludes(raw, {
|
|
67
72
|
contentRoot: source.contentRoot,
|
|
68
73
|
sourcePath: page.sourcePath,
|
|
69
74
|
});
|
|
70
|
-
return expansion.text;
|
|
75
|
+
return substituteVariablesInBody(expansion.text, variables);
|
|
71
76
|
};
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { JsonObject, JsonValue } from "./json.ts";
|
|
7
7
|
import { asNumber, asObject, asString, objectsIn } from "./json.ts";
|
|
8
|
+
import type { InlinePart } from "./lower.ts";
|
|
8
9
|
import {
|
|
9
10
|
absoluteUrl,
|
|
10
11
|
blockquote,
|
|
@@ -12,10 +13,10 @@ import {
|
|
|
12
13
|
guardBlockStart,
|
|
13
14
|
headingPrefix,
|
|
14
15
|
image,
|
|
16
|
+
linkParts,
|
|
15
17
|
listItem,
|
|
16
18
|
markdownDocument,
|
|
17
19
|
renderInline,
|
|
18
|
-
renderLink,
|
|
19
20
|
unsupported,
|
|
20
21
|
} from "./lower.ts";
|
|
21
22
|
|
|
@@ -28,34 +29,37 @@ const children = (node: JsonObject): JsonObject[] => objectsIn(node.children);
|
|
|
28
29
|
|
|
29
30
|
const typeOf = (node: JsonObject): string => asString(node.type) ?? "";
|
|
30
31
|
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
.map((node) => renderInlineNode(node))
|
|
35
|
-
.join("");
|
|
32
|
+
const inlineParts = (nodes: JsonObject[]): InlinePart[] =>
|
|
33
|
+
// oxlint-disable-next-line no-use-before-define -- mutual recursion: a link's label is itself inline content
|
|
34
|
+
nodes.flatMap((node) => inlineNodeParts(node));
|
|
36
35
|
|
|
37
|
-
const
|
|
36
|
+
const inlineNodeParts = (node: JsonObject): InlinePart[] => {
|
|
38
37
|
switch (typeOf(node)) {
|
|
39
38
|
case "text": {
|
|
40
|
-
return
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
return [
|
|
40
|
+
{
|
|
41
|
+
marks: {
|
|
42
|
+
bold: node.bold === true,
|
|
43
|
+
code: node.code === true,
|
|
44
|
+
italic: node.italic === true,
|
|
45
|
+
strike: node.strikethrough === true,
|
|
46
|
+
},
|
|
47
|
+
text: asString(node.text) ?? "",
|
|
48
|
+
},
|
|
49
|
+
];
|
|
46
50
|
}
|
|
47
51
|
case "link": {
|
|
48
|
-
return
|
|
52
|
+
return linkParts(inlineParts(children(node)), asString(node.url));
|
|
49
53
|
}
|
|
50
54
|
default: {
|
|
51
|
-
return
|
|
55
|
+
return inlineParts(children(node));
|
|
52
56
|
}
|
|
53
57
|
}
|
|
54
58
|
};
|
|
55
59
|
|
|
56
60
|
/** A text block's inline nodes, joined and guarded as one block. */
|
|
57
61
|
const blockText = (nodes: JsonObject[]): string =>
|
|
58
|
-
guardBlockStart(
|
|
62
|
+
guardBlockStart(renderInline(inlineParts(nodes)));
|
|
59
63
|
|
|
60
64
|
const renderList = (node: JsonObject): string => {
|
|
61
65
|
const ordered = asString(node.format) === "ordered";
|
|
@@ -51,18 +51,26 @@ export const baselineScanIgnore = (): string[] =>
|
|
|
51
51
|
*/
|
|
52
52
|
export const BLUME_WATCH_IGNORE_DIRS = BLUME_IGNORE_DIRS;
|
|
53
53
|
|
|
54
|
-
/**
|
|
54
|
+
/**
|
|
55
|
+
* Extract root-anchored ignore dirs (`/foo`) from `foo/**`-style excludes. The
|
|
56
|
+
* scan's glob `foo/**` matches `foo` at the source root only, so the watcher
|
|
57
|
+
* skips that one directory: a nested `guides/foo/` is still content, and an
|
|
58
|
+
* edit there must still reload.
|
|
59
|
+
*/
|
|
55
60
|
export const excludeDirSegments = (patterns: readonly string[]): string[] =>
|
|
56
61
|
patterns
|
|
57
62
|
.map((pattern) => /^(?<dir>[^*/]+)\/\*\*$/u.exec(pattern)?.groups?.dir)
|
|
58
|
-
.filter((dir): dir is string => dir !== undefined)
|
|
63
|
+
.filter((dir): dir is string => dir !== undefined)
|
|
64
|
+
.map((dir) => `/${dir}`);
|
|
59
65
|
|
|
60
66
|
/**
|
|
61
67
|
* Build a recursive-watch listener that fires `onChange` for content changes but
|
|
62
|
-
* ignores events whose path crosses an ignored directory segment
|
|
63
|
-
* `ignoreDirs
|
|
64
|
-
* a shape (every dot-name) rather than a list.
|
|
65
|
-
*
|
|
68
|
+
* ignores events whose path crosses an ignored directory — a segment named in
|
|
69
|
+
* `ignoreDirs` at any depth, or one `ignoreSegment` rejects, for a scan whose
|
|
70
|
+
* skip rule is a shape (every dot-name) rather than a list. An entry written
|
|
71
|
+
* with a leading slash (`/drafts`, see {@link excludeDirSegments}) names a
|
|
72
|
+
* directory at the watched root only. A missing `filename` — rare; the
|
|
73
|
+
* platform couldn't name the changed path — falls through to `onChange`
|
|
66
74
|
* rather than silently dropping a real edit. Exported for testing.
|
|
67
75
|
*/
|
|
68
76
|
export const ignoringWatchListener = (
|
|
@@ -76,7 +84,12 @@ export const ignoringWatchListener = (
|
|
|
76
84
|
filename !== null &&
|
|
77
85
|
filename
|
|
78
86
|
.split(/[/\\]/u)
|
|
79
|
-
.some(
|
|
87
|
+
.some(
|
|
88
|
+
(segment, index) =>
|
|
89
|
+
ignore.has(segment) ||
|
|
90
|
+
(index === 0 && ignore.has(`/${segment}`)) ||
|
|
91
|
+
ignoreSegment(segment)
|
|
92
|
+
)
|
|
80
93
|
) {
|
|
81
94
|
return;
|
|
82
95
|
}
|
|
@@ -50,11 +50,15 @@ export interface StandardSchema<Input = unknown, Output = Input> {
|
|
|
50
50
|
* Whether a config-supplied value implements the `~standard` contract. Generic
|
|
51
51
|
* so it can decode any input at the config boundary (`z.custom` hands it the
|
|
52
52
|
* raw config value) while narrowing whatever type the caller holds.
|
|
53
|
+
*
|
|
54
|
+
* The contract is the `~standard` property, whatever carries it: Zod and
|
|
55
|
+
* Valibot schemas are objects, but an ArkType type is a callable function. The
|
|
56
|
+
* optional-chained probe reads the property off either, and off `null`,
|
|
57
|
+
* `undefined`, or a primitive it finds nothing.
|
|
53
58
|
*/
|
|
54
59
|
export const isStandardSchema = <T>(value: T): value is T & StandardSchema =>
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
?.validate === "function";
|
|
60
|
+
// SAFETY: the assertion only widens the value for property probing; the
|
|
61
|
+
// typeof check is what verifies `~standard.validate` exists.
|
|
62
|
+
typeof (
|
|
63
|
+
value as { "~standard"?: { validate?: unknown } } | null | undefined
|
|
64
|
+
)?.["~standard"]?.validate === "function";
|
package/src/core/types.ts
CHANGED
|
@@ -316,7 +316,7 @@ export interface Navigation {
|
|
|
316
316
|
cta?: HeaderAction | null;
|
|
317
317
|
/** Pinned links shown above the sidebar sections, unscoped by tab. */
|
|
318
318
|
featured: FeaturedLink[];
|
|
319
|
-
/** Repo URL for the
|
|
319
|
+
/** Repo URL for the footer's GitHub link, or null when hidden (`navigation.repo`). */
|
|
320
320
|
repoUrl?: string | null;
|
|
321
321
|
/**
|
|
322
322
|
* Where the header's brand link points in this locale: `logo.href` moved
|
package/src/core/ui-packs/ar.ts
CHANGED
|
@@ -5,6 +5,7 @@ export const ar: UIStringsOverride = {
|
|
|
5
5
|
actions: {
|
|
6
6
|
addToCursor: "إضافة إلى Cursor",
|
|
7
7
|
addToVscode: "إضافة إلى VS Code",
|
|
8
|
+
askAboutCode: "اسأل عن هذه الشيفرة",
|
|
8
9
|
connectMcp: "الاتصال بـ MCP",
|
|
9
10
|
copied: "تم النسخ!",
|
|
10
11
|
copyClaudeCode: "نسخ أمر Claude Code",
|
|
@@ -30,11 +31,18 @@ export const ar: UIStringsOverride = {
|
|
|
30
31
|
copy: "نسخ المحادثة",
|
|
31
32
|
empty: "اطرح سؤالاً حول الوثائق.",
|
|
32
33
|
error: "عذراً، حدث خطأ ما.",
|
|
34
|
+
explainCode: "اشرح هذه الشيفرة.",
|
|
33
35
|
label: "اطرح سؤالاً",
|
|
36
|
+
open: "فتح المساعد",
|
|
34
37
|
placeholder: "اطرح سؤالاً…",
|
|
38
|
+
rateLimited: "لقد طرحت الكثير من الأسئلة. حاول مرة أخرى بعد بضع دقائق.",
|
|
39
|
+
removeCode: "إزالة الشيفرة",
|
|
35
40
|
send: "إرسال",
|
|
41
|
+
support: "تواصل مع الدعم",
|
|
42
|
+
supportSubject: "سؤال من التوثيق",
|
|
36
43
|
tip: "نصيحة: يمكنك فتح المحادثة وإغلاقها باستخدام",
|
|
37
44
|
title: "المساعد",
|
|
45
|
+
verifyFailed: "تعذّر التحقق من أنك إنسان. حاول مرة أخرى.",
|
|
38
46
|
you: "أنت",
|
|
39
47
|
},
|
|
40
48
|
banner: { dismiss: "إغلاق الإعلان" },
|
|
@@ -42,6 +50,14 @@ export const ar: UIStringsOverride = {
|
|
|
42
50
|
description: "تحديثات المنتج وملاحظات الإصدارات.",
|
|
43
51
|
title: "سجل التغييرات",
|
|
44
52
|
},
|
|
53
|
+
consent: {
|
|
54
|
+
accept: "قبول",
|
|
55
|
+
decline: "رفض",
|
|
56
|
+
label: "الموافقة على ملفات تعريف الارتباط",
|
|
57
|
+
message: "نودّ استخدام ملفات تعريف الارتباط لفهم كيفية استخدام هذا التوثيق.",
|
|
58
|
+
policy: "سياسة الخصوصية",
|
|
59
|
+
settings: "إعدادات ملفات تعريف الارتباط",
|
|
60
|
+
},
|
|
45
61
|
content: {
|
|
46
62
|
code: "الكود",
|
|
47
63
|
copyColor: "نسخ اللون {name} {value}",
|
|
@@ -52,6 +68,8 @@ export const ar: UIStringsOverride = {
|
|
|
52
68
|
preview: "معاينة",
|
|
53
69
|
prop: "الخاصية",
|
|
54
70
|
selectTab: "اختيار علامة تبويب",
|
|
71
|
+
selectView: "اختيار طريقة العرض",
|
|
72
|
+
showLess: "عرض أقل",
|
|
55
73
|
showMore: "عرض المزيد",
|
|
56
74
|
stars: "النجوم",
|
|
57
75
|
tab: "علامة التبويب {n}",
|
|
@@ -59,12 +77,36 @@ export const ar: UIStringsOverride = {
|
|
|
59
77
|
update: "تحديث",
|
|
60
78
|
},
|
|
61
79
|
feedback: {
|
|
80
|
+
comment: "أخبرنا بالمزيد (اختياري)",
|
|
62
81
|
no: "لا",
|
|
63
82
|
question: "هل كانت هذه الصفحة مفيدة؟",
|
|
83
|
+
send: "إرسال",
|
|
64
84
|
thanks: "شكراً على ملاحظاتك!",
|
|
65
85
|
yes: "نعم",
|
|
66
86
|
},
|
|
67
87
|
languageSwitcher: { label: "اللغة", untranslated: "غير مترجم" },
|
|
88
|
+
narration: {
|
|
89
|
+
cueDanger: "خطر.",
|
|
90
|
+
cueInfo: "معلومة.",
|
|
91
|
+
cueNote: "ملاحظة.",
|
|
92
|
+
cueSection: "قسم قابل للتوسيع.",
|
|
93
|
+
cueStep: "الخطوة {n}.",
|
|
94
|
+
cueSuccess: "نجاح.",
|
|
95
|
+
cueTab: "علامة التبويب {title}.",
|
|
96
|
+
cueTip: "نصيحة.",
|
|
97
|
+
cueWarning: "تحذير.",
|
|
98
|
+
error: "تعذّر تحميل القراءة الصوتية.",
|
|
99
|
+
follow: "متابعة القراءة",
|
|
100
|
+
label: "استمع إلى هذه الصفحة",
|
|
101
|
+
minutes: "{n} دقيقة",
|
|
102
|
+
next: "الجملة التالية",
|
|
103
|
+
pause: "إيقاف مؤقت",
|
|
104
|
+
play: "تشغيل",
|
|
105
|
+
previous: "الجملة السابقة",
|
|
106
|
+
progress: "تقدّم القراءة",
|
|
107
|
+
speed: "سرعة التشغيل",
|
|
108
|
+
stop: "إيقاف الاستماع",
|
|
109
|
+
},
|
|
68
110
|
nav: {
|
|
69
111
|
back: "رجوع",
|
|
70
112
|
breadcrumb: "مسار التنقل",
|
|
@@ -89,6 +131,7 @@ export const ar: UIStringsOverride = {
|
|
|
89
131
|
next: "التالي",
|
|
90
132
|
pagination: "ترقيم الصفحات",
|
|
91
133
|
previous: "السابق",
|
|
134
|
+
related: "صفحات ذات صلة",
|
|
92
135
|
skipToContent: "الانتقال إلى المحتوى",
|
|
93
136
|
},
|
|
94
137
|
search: {
|
package/src/core/ui-packs/bg.ts
CHANGED
|
@@ -5,6 +5,7 @@ export const bg: UIStringsOverride = {
|
|
|
5
5
|
actions: {
|
|
6
6
|
addToCursor: "Добави в Cursor",
|
|
7
7
|
addToVscode: "Добави във VS Code",
|
|
8
|
+
askAboutCode: "Попитай за този код",
|
|
8
9
|
connectMcp: "Свържи се с MCP",
|
|
9
10
|
copied: "Копирано!",
|
|
10
11
|
copyClaudeCode: "Копирай командата на Claude Code",
|
|
@@ -31,11 +32,19 @@ export const bg: UIStringsOverride = {
|
|
|
31
32
|
copy: "Копирай разговора",
|
|
32
33
|
empty: "Задайте въпрос за документацията.",
|
|
33
34
|
error: "Съжаляваме, нещо се обърка.",
|
|
35
|
+
explainCode: "Обясни този код.",
|
|
34
36
|
label: "Задайте въпрос",
|
|
37
|
+
open: "Отваряне на асистента",
|
|
35
38
|
placeholder: "Задайте въпрос…",
|
|
39
|
+
rateLimited:
|
|
40
|
+
"Зададохте много въпроси. Опитайте отново след няколко минути.",
|
|
41
|
+
removeCode: "Премахни кода",
|
|
36
42
|
send: "Изпрати",
|
|
43
|
+
support: "Свържете се с поддръжката",
|
|
44
|
+
supportSubject: "Въпрос от документацията",
|
|
37
45
|
tip: "Съвет: Можете да отваряте и затваряте чата с",
|
|
38
46
|
title: "Асистент",
|
|
47
|
+
verifyFailed: "Не успяхме да потвърдим, че сте човек. Опитайте отново.",
|
|
39
48
|
you: "Вие",
|
|
40
49
|
},
|
|
41
50
|
banner: { dismiss: "Затваряне на съобщението" },
|
|
@@ -43,6 +52,15 @@ export const bg: UIStringsOverride = {
|
|
|
43
52
|
description: "Актуализации на продукта и бележки към изданията.",
|
|
44
53
|
title: "Дневник на промените",
|
|
45
54
|
},
|
|
55
|
+
consent: {
|
|
56
|
+
accept: "Приемам",
|
|
57
|
+
decline: "Отказвам",
|
|
58
|
+
label: "Съгласие за бисквитки",
|
|
59
|
+
message:
|
|
60
|
+
"Бихме искали да използваме бисквитки, за да разберем как се използва тази документация.",
|
|
61
|
+
policy: "Политика за поверителност",
|
|
62
|
+
settings: "Настройки за бисквитки",
|
|
63
|
+
},
|
|
46
64
|
content: {
|
|
47
65
|
code: "Код",
|
|
48
66
|
copyColor: "Копирай цвета {name} {value}",
|
|
@@ -53,6 +71,8 @@ export const bg: UIStringsOverride = {
|
|
|
53
71
|
preview: "Преглед",
|
|
54
72
|
prop: "Свойство",
|
|
55
73
|
selectTab: "Избери раздел",
|
|
74
|
+
selectView: "Избери изглед",
|
|
75
|
+
showLess: "Покажи по-малко",
|
|
56
76
|
showMore: "Покажи още",
|
|
57
77
|
stars: "Звезди",
|
|
58
78
|
tab: "Раздел {n}",
|
|
@@ -60,12 +80,36 @@ export const bg: UIStringsOverride = {
|
|
|
60
80
|
update: "Актуализация",
|
|
61
81
|
},
|
|
62
82
|
feedback: {
|
|
83
|
+
comment: "Разкажете ни повече (по избор)",
|
|
63
84
|
no: "Не",
|
|
64
85
|
question: "Беше ли полезна тази страница?",
|
|
86
|
+
send: "Изпрати",
|
|
65
87
|
thanks: "Благодарим за обратната връзка!",
|
|
66
88
|
yes: "Да",
|
|
67
89
|
},
|
|
68
90
|
languageSwitcher: { label: "Език", untranslated: "Непреведено" },
|
|
91
|
+
narration: {
|
|
92
|
+
cueDanger: "Опасност.",
|
|
93
|
+
cueInfo: "Информация.",
|
|
94
|
+
cueNote: "Бележка.",
|
|
95
|
+
cueSection: "Разгъваем раздел.",
|
|
96
|
+
cueStep: "Стъпка {n}.",
|
|
97
|
+
cueSuccess: "Успех.",
|
|
98
|
+
cueTab: "Раздел {title}.",
|
|
99
|
+
cueTip: "Съвет.",
|
|
100
|
+
cueWarning: "Предупреждение.",
|
|
101
|
+
error: "Аудиоверсията не можа да бъде заредена.",
|
|
102
|
+
follow: "Следи четенето",
|
|
103
|
+
label: "Слушай тази страница",
|
|
104
|
+
minutes: "{n} мин",
|
|
105
|
+
next: "Следващо изречение",
|
|
106
|
+
pause: "Пауза",
|
|
107
|
+
play: "Пусни",
|
|
108
|
+
previous: "Предишно изречение",
|
|
109
|
+
progress: "Напредък на четенето",
|
|
110
|
+
speed: "Скорост на възпроизвеждане",
|
|
111
|
+
stop: "Спри слушането",
|
|
112
|
+
},
|
|
69
113
|
nav: {
|
|
70
114
|
back: "Назад",
|
|
71
115
|
breadcrumb: "Навигационна пътека",
|
|
@@ -90,6 +134,7 @@ export const bg: UIStringsOverride = {
|
|
|
90
134
|
next: "Напред",
|
|
91
135
|
pagination: "Пагинация",
|
|
92
136
|
previous: "Назад",
|
|
137
|
+
related: "Свързани страници",
|
|
93
138
|
skipToContent: "Към съдържанието",
|
|
94
139
|
},
|
|
95
140
|
search: {
|