blume 2.1.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +94 -0
- package/dist/cli/{chunk-5cg2rzgf.js → chunk-073rdvgb.js} +19 -48
- package/dist/cli/{chunk-5cg2rzgf.js.map → chunk-073rdvgb.js.map} +4 -5
- package/dist/cli/{chunk-ga0pf4aj.js → chunk-0n9xkp3d.js} +12 -3
- package/dist/cli/{chunk-ga0pf4aj.js.map → chunk-0n9xkp3d.js.map} +3 -3
- package/dist/cli/chunk-150jk7km.js +52 -0
- package/dist/cli/chunk-150jk7km.js.map +10 -0
- package/dist/cli/{chunk-rekqz4qg.js → chunk-313vnn40.js} +16 -15
- package/dist/cli/chunk-313vnn40.js.map +10 -0
- package/dist/cli/{chunk-gp84za0h.js → chunk-3v3ffbrj.js} +2 -2
- package/dist/cli/{chunk-9xr4dgee.js → chunk-3x6x3pph.js} +29 -16
- package/dist/cli/chunk-3x6x3pph.js.map +10 -0
- package/dist/cli/{chunk-0gz36akr.js → chunk-42t4jxdx.js} +21 -5
- package/dist/cli/chunk-42t4jxdx.js.map +12 -0
- package/dist/cli/{chunk-ta27feev.js → chunk-54ztw1nj.js} +21 -2
- package/dist/cli/chunk-54ztw1nj.js.map +10 -0
- package/dist/cli/{chunk-jnwj5kjj.js → chunk-5vjtgs6e.js} +20 -7
- package/dist/cli/{chunk-jnwj5kjj.js.map → chunk-5vjtgs6e.js.map} +3 -3
- package/dist/cli/chunk-66w9j7p6.js +322 -0
- package/dist/cli/chunk-66w9j7p6.js.map +14 -0
- package/dist/cli/{chunk-nd1821sk.js → chunk-7ppf1rva.js} +32 -18
- package/dist/cli/chunk-7ppf1rva.js.map +10 -0
- package/dist/cli/{chunk-p804f3pe.js → chunk-8y2kmjv8.js} +6 -6
- package/dist/cli/{chunk-2f7n4qzt.js → chunk-c1y538kd.js} +1 -1
- package/dist/cli/{chunk-1n228xqb.js → chunk-c887fj0s.js} +2 -2
- package/dist/cli/{chunk-y5h4r2y0.js → chunk-cfyg47zg.js} +15 -5
- package/dist/cli/chunk-cfyg47zg.js.map +10 -0
- package/dist/cli/{chunk-cmtcnh9f.js → chunk-dzwehpy7.js} +2 -2
- package/dist/cli/{chunk-h2a48yhd.js → chunk-e6atmn4h.js} +119 -15
- package/dist/cli/{chunk-h2a48yhd.js.map → chunk-e6atmn4h.js.map} +10 -10
- package/dist/cli/{chunk-5ffywsmb.js → chunk-e8xw9qkh.js} +8 -6
- package/dist/cli/{chunk-5ffywsmb.js.map → chunk-e8xw9qkh.js.map} +3 -3
- package/dist/cli/{chunk-ntv4qrt7.js → chunk-e9q7a2ak.js} +14 -14
- package/dist/cli/{chunk-xkz5xbtv.js → chunk-ehweg4fr.js} +2366 -1114
- package/dist/cli/chunk-ehweg4fr.js.map +218 -0
- package/dist/cli/{chunk-zf748avv.js → chunk-ep6nd0rn.js} +176 -281
- package/dist/cli/{chunk-zf748avv.js.map → chunk-ep6nd0rn.js.map} +11 -12
- package/dist/cli/{chunk-yxmk4pec.js → chunk-fdrkhpjy.js} +16 -15
- package/dist/cli/{chunk-yxmk4pec.js.map → chunk-fdrkhpjy.js.map} +3 -3
- package/dist/cli/{chunk-5wj2qwn2.js → chunk-ft9vfys6.js} +4 -4
- package/dist/cli/{chunk-4h8z9vv5.js → chunk-gb420vvz.js} +89 -46
- package/dist/cli/chunk-gb420vvz.js.map +17 -0
- package/dist/cli/{chunk-713mngdq.js → chunk-hebn0tpx.js} +76 -10
- package/dist/cli/chunk-hebn0tpx.js.map +14 -0
- package/dist/cli/{chunk-2n4ps1b3.js → chunk-htrwgabr.js} +40 -22
- package/dist/cli/chunk-htrwgabr.js.map +15 -0
- package/dist/cli/{chunk-zhvd6adm.js → chunk-hx3xqnk9.js} +13 -13
- package/dist/cli/chunk-j134vrp2.js +65 -0
- package/dist/cli/chunk-j134vrp2.js.map +10 -0
- package/dist/cli/{chunk-y4ykbark.js → chunk-kma9f6sf.js} +2 -2
- package/dist/cli/{chunk-py62fewh.js → chunk-mrcccgnh.js} +3 -3
- package/dist/cli/{chunk-2f3ndkpw.js → chunk-n0v7m8ry.js} +3 -3
- package/dist/cli/{chunk-43zcf4gz.js → chunk-ncj7w596.js} +522 -353
- package/dist/cli/chunk-ncj7w596.js.map +35 -0
- package/dist/cli/{chunk-9geymqns.js → chunk-nq1d20w2.js} +14 -14
- package/dist/cli/{chunk-g2z9x01v.js → chunk-nrns10mj.js} +3 -3
- package/dist/cli/{chunk-e7vvk5ya.js → chunk-sds923fa.js} +3 -3
- package/dist/cli/{chunk-cy5bm0j0.js → chunk-t2m5j4pr.js} +2 -2
- package/dist/cli/{chunk-cy5bm0j0.js.map → chunk-t2m5j4pr.js.map} +1 -1
- package/dist/cli/{chunk-yj17vs39.js → chunk-tdqhyxfz.js} +5 -5
- package/dist/cli/{chunk-q3wxxq39.js → chunk-tphac74f.js} +5 -5
- package/dist/cli/{chunk-6bm0xpgd.js → chunk-w1r4vase.js} +2 -2
- package/dist/cli/index.js +24 -19
- package/dist/cli/index.js.map +3 -3
- package/dist/types/ai/ask-context.d.ts +6 -2
- package/dist/types/ai/component-markdown.d.ts +2 -0
- package/dist/types/ai/openapi-components.d.ts +4 -1
- package/dist/types/astro/integration.d.ts +5 -4
- package/dist/types/astro/markdown-negotiation.d.ts +3 -0
- package/dist/types/astro/pages.d.ts +10 -0
- package/dist/types/cli/init/scaffold.d.ts +1 -1
- package/dist/types/components/content/api-field.d.ts +4 -1
- package/dist/types/components/content/api-page.d.ts +6 -1
- package/dist/types/components/openapi/code-samples.d.ts +29 -0
- package/dist/types/components/openapi/helpers.d.ts +22 -1
- package/dist/types/components/openapi/security.d.ts +10 -0
- package/dist/types/components/openapi/snippets.d.ts +60 -0
- package/dist/types/core/changelog-index.d.ts +8 -0
- package/dist/types/core/config-input.d.ts +30 -3
- package/dist/types/core/data.d.ts +4 -0
- package/dist/types/core/i18n-ui.d.ts +2 -0
- package/dist/types/core/links.d.ts +8 -0
- package/dist/types/core/probe.d.ts +2 -0
- package/dist/types/core/project-graph.d.ts +6 -0
- package/dist/types/core/redirect-patterns.d.ts +11 -3
- package/dist/types/core/schema.d.ts +119 -0
- package/dist/types/core/sources/cache.d.ts +3 -0
- package/dist/types/core/sources/contentful-rich-text.d.ts +11 -2
- package/dist/types/core/sources/contentful.d.ts +17 -1
- package/dist/types/core/sources/lexical.d.ts +5 -0
- package/dist/types/core/sources/normalize.d.ts +20 -1
- package/dist/types/core/sources/remote.d.ts +37 -10
- package/dist/types/core/sources/sanity.d.ts +1 -1
- package/dist/types/core/types.d.ts +17 -0
- package/dist/types/deploy/adapter-output.d.ts +2 -1
- package/dist/types/deploy/adapters/cloudflare.d.ts +7 -5
- package/dist/types/deploy/adapters/node.d.ts +58 -23
- package/dist/types/deploy/adapters/registry.d.ts +10 -0
- package/dist/types/deploy/adapters/types.d.ts +3 -2
- package/dist/types/deploy/platforms/cloudflare.d.ts +10 -7
- package/dist/types/deploy/platforms/node.d.ts +3 -1
- package/dist/types/deploy/platforms/types.d.ts +18 -7
- package/dist/types/deploy/platforms/vercel.d.ts +20 -1
- package/dist/types/deploy/redirects.d.ts +17 -1
- package/dist/types/deploy/sitemap.d.ts +2 -1
- package/dist/types/deploy/vercel-negotiation.d.ts +42 -21
- package/dist/types/openapi/checks.d.ts +27 -0
- package/dist/types/openapi/graphql.d.ts +6 -0
- package/dist/types/openapi/model.d.ts +15 -4
- package/dist/types/openapi/parse.d.ts +3 -0
- package/dist/types/openapi/references.d.ts +16 -0
- package/dist/types/ratelimit/index.d.ts +1 -1
- package/dist/types/ratelimit/schema.d.ts +8 -0
- package/dist/types/ratelimit/upstash.d.ts +39 -14
- package/dist/types/reference/graphql.d.ts +76 -1
- package/dist/types/reference/index.d.ts +1 -1
- package/dist/types/reference/openapi.d.ts +2 -2
- package/dist/types/reference/options.d.ts +37 -1
- package/dist/types/reference/schema.d.ts +84 -0
- package/dist/types/search/adapters/registry.d.ts +3 -0
- package/dist/types/search/adapters/typesense.d.ts +14 -4
- package/dist/types/search/build.d.ts +3 -1
- package/dist/types/search/orama-index.d.ts +9 -9
- package/dist/types/search/sync/algolia.d.ts +5 -2
- package/dist/types/search/sync/index.d.ts +3 -1
- package/dist/types/search/sync/typesense.d.ts +11 -7
- package/dist/types/sources/contentful.d.ts +16 -0
- package/dist/types/sources/github-releases.d.ts +8 -1
- package/dist/types/sources/payload.d.ts +2 -0
- package/dist/types/sources/registry.d.ts +54 -0
- package/dist/types/sources/shared.d.ts +3 -0
- package/dist/types/sources/strapi.d.ts +2 -0
- package/docs/01-quickstart.mdx +4 -2
- package/docs/02-deployment.mdx +31 -13
- package/docs/advanced/changelog.mdx +11 -0
- package/docs/advanced/skills.mdx +1 -1
- package/docs/cli/audit.mdx +30 -7
- package/docs/cli/doctor.mdx +5 -1
- package/docs/cli/evals.mdx +4 -4
- package/docs/cli/translate.mdx +1 -0
- package/docs/cli/validate.mdx +4 -3
- package/docs/configuration/analytics.mdx +1 -1
- package/docs/configuration/assistant.mdx +6 -2
- package/docs/configuration/customization.mdx +4 -2
- package/docs/configuration/export.mdx +5 -3
- package/docs/configuration/index.mdx +3 -2
- package/docs/configuration/rate-limiting.mdx +23 -2
- package/docs/configuration/search.mdx +37 -14
- package/docs/content/components.mdx +2 -2
- package/docs/content/frontmatter.mdx +5 -3
- package/docs/content/i18n.mdx +2 -2
- package/docs/content/includes.mdx +1 -1
- package/docs/content/navigation.mdx +4 -4
- package/docs/content/sources/contentful.mdx +7 -4
- package/docs/content/sources/custom.mdx +7 -3
- package/docs/content/sources/github-releases.mdx +10 -2
- package/docs/content/sources/index.mdx +3 -3
- package/docs/content/sources/notion.mdx +1 -1
- package/docs/content/sources/obsidian.mdx +1 -1
- package/docs/content/sources/payload.mdx +3 -2
- package/docs/content/sources/remote-mdx.mdx +4 -0
- package/docs/content/sources/sanity.mdx +2 -2
- package/docs/content/sources/strapi.mdx +3 -2
- package/docs/content/syntax.mdx +2 -2
- package/docs/discoverability/agent-discovery.mdx +1 -1
- package/docs/discoverability/index.mdx +1 -1
- package/docs/discoverability/json-api.mdx +2 -0
- package/docs/discoverability/llms-txt.mdx +1 -1
- package/docs/discoverability/markdown.mdx +3 -1
- package/docs/discoverability/mcp.mdx +4 -0
- package/docs/discoverability/sitemap-and-robots.mdx +1 -1
- package/docs/references/api-pages.mdx +1 -1
- package/docs/references/asyncapi.mdx +3 -1
- package/docs/references/graphql.mdx +13 -1
- package/docs/references/openapi.mdx +50 -8
- package/package.json +9 -9
- package/skills/blume-migrate/SKILL.md +1 -1
- package/skills/blume-migrate/references/docusaurus.md +4 -4
- package/skills/blume-migrate/references/fumadocs.md +17 -13
- package/skills/blume-migrate/references/nextra.md +8 -5
- package/skills/blume-migrate/references/starlight.md +9 -7
- package/src/ai/ask-context.ts +33 -3
- package/src/ai/ask-limits.ts +13 -0
- package/src/ai/changelog-markdown.ts +11 -6
- package/src/ai/component-markdown.ts +1 -1
- package/src/ai/cors.ts +12 -3
- package/src/ai/mcp/query.ts +14 -6
- package/src/ai/openapi-components.ts +28 -4
- package/src/ai/relative-links.ts +4 -38
- package/src/astro/generate.ts +78 -48
- package/src/astro/integration.ts +16 -13
- package/src/astro/markdown-negotiation.ts +3 -0
- package/src/astro/module-types.ts +3 -1
- package/src/astro/pages.ts +23 -0
- package/src/astro/templates.ts +125 -80
- package/src/audit/catalog.ts +19 -3
- package/src/audit/checks/links.ts +14 -1
- package/src/audit/checks/network.ts +110 -6
- package/src/audit/checks/redirects.ts +6 -4
- package/src/audit/checks/robots.ts +58 -2
- package/src/audit/run.ts +3 -0
- package/src/audit/types.ts +2 -0
- package/src/audit/url.ts +14 -5
- package/src/blume-modules.d.ts +5 -1
- package/src/cli/args.ts +51 -0
- package/src/cli/build-failure.ts +23 -0
- package/src/cli/commands/audit.ts +10 -1
- package/src/cli/commands/dev.ts +18 -2
- package/src/cli/commands/doctor.ts +45 -12
- package/src/cli/commands/eval.ts +36 -4
- package/src/cli/commands/init.ts +6 -4
- package/src/cli/commands/validate.ts +10 -1
- package/src/cli/init/scaffold.ts +3 -3
- package/src/cli/prepare.ts +6 -3
- package/src/cli/required-secrets.ts +1 -1
- package/src/components/content/ApiPlayground.astro +6 -2
- package/src/components/content/api-field.ts +4 -1
- package/src/components/content/api-page.ts +31 -7
- package/src/components/content/mermaid-element.ts +15 -1
- package/src/components/islands/hooks.ts +27 -1
- package/src/components/layout/PageActions.astro +139 -24
- package/src/components/layout/RootLayout.astro +10 -2
- package/src/components/layout/Search.astro +17 -3
- package/src/components/layout/TableOfContents.astro +24 -17
- package/src/components/layout/head-scripts.ts +6 -1
- package/src/components/layout/search/algolia.ts +10 -1
- package/src/components/layout/search/analytics.ts +42 -14
- package/src/components/layout/search/endpoint.ts +48 -5
- package/src/components/layout/search/pagefind.ts +114 -5
- package/src/components/layout/search/types.ts +12 -0
- package/src/components/layout/search/typesense.ts +18 -6
- package/src/components/openapi/AsyncApiOperation.astro +14 -7
- package/src/components/openapi/Authorization.astro +10 -0
- package/src/components/openapi/GraphqlOperation.astro +5 -0
- package/src/components/openapi/Operation.astro +24 -1
- package/src/components/openapi/ParametersTable.astro +8 -4
- package/src/components/openapi/Playground.astro +7 -1
- package/src/components/openapi/RequestBody.astro +19 -2
- package/src/components/openapi/Responses.astro +1 -0
- package/src/components/openapi/SchemaTable.astro +15 -3
- package/src/components/openapi/async-snippets.ts +61 -5
- package/src/components/openapi/async.ts +123 -29
- package/src/components/openapi/graphql-helpers.ts +35 -12
- package/src/components/openapi/helpers.ts +36 -2
- package/src/components/openapi/message-model.ts +54 -11
- package/src/components/openapi/message.ts +14 -4
- package/src/components/openapi/operation-model.ts +16 -7
- package/src/components/openapi/playground-client.ts +24 -5
- package/src/components/openapi/playground-schema.ts +1 -1
- package/src/components/openapi/schema-tree.ts +44 -14
- package/src/components/openapi/security.ts +10 -0
- package/src/components/openapi/snippets.ts +5 -3
- package/src/components/openapi/validate-json.ts +4 -3
- package/src/core/changelog-index.ts +31 -1
- package/src/core/component-diagnostics.ts +53 -0
- package/src/core/component-overrides.ts +32 -0
- package/src/core/config-input.ts +31 -3
- package/src/core/data.ts +2 -0
- package/src/core/diagnostics.ts +5 -0
- package/src/core/i18n-ui.ts +2 -0
- package/src/core/includes.ts +1 -1
- package/src/core/links.ts +47 -17
- package/src/core/probe.ts +26 -6
- package/src/core/project-graph.ts +59 -18
- package/src/core/redirect-patterns.ts +36 -7
- package/src/core/schema.ts +21 -2
- package/src/core/sources/cache.ts +6 -0
- package/src/core/sources/contentful-rich-text.ts +29 -6
- package/src/core/sources/contentful.ts +135 -25
- package/src/core/sources/filesystem.ts +26 -4
- package/src/core/sources/github-releases.ts +12 -1
- package/src/core/sources/lexical.ts +15 -10
- package/src/core/sources/mdx-remote.ts +62 -10
- package/src/core/sources/normalize.ts +227 -41
- package/src/core/sources/notion.ts +7 -1
- package/src/core/sources/obsidian.ts +16 -3
- package/src/core/sources/payload.ts +38 -15
- package/src/core/sources/remote.ts +72 -15
- package/src/core/sources/resolve.ts +11 -1
- package/src/core/sources/sanity.ts +43 -25
- package/src/core/sources/strapi.ts +2 -2
- package/src/core/types.ts +18 -0
- package/src/core/ui-packs/ar.ts +1 -0
- package/src/core/ui-packs/bg.ts +1 -0
- package/src/core/ui-packs/bn.ts +1 -0
- package/src/core/ui-packs/ca.ts +1 -0
- package/src/core/ui-packs/cs.ts +1 -0
- package/src/core/ui-packs/da.ts +1 -0
- package/src/core/ui-packs/de.ts +1 -0
- package/src/core/ui-packs/el.ts +1 -0
- package/src/core/ui-packs/es.ts +1 -0
- package/src/core/ui-packs/fa.ts +1 -0
- package/src/core/ui-packs/fi.ts +1 -0
- package/src/core/ui-packs/fr.ts +1 -0
- package/src/core/ui-packs/he.ts +1 -0
- package/src/core/ui-packs/hi.ts +1 -0
- package/src/core/ui-packs/hr.ts +1 -0
- package/src/core/ui-packs/hu.ts +1 -0
- package/src/core/ui-packs/id.ts +1 -0
- package/src/core/ui-packs/it.ts +1 -0
- package/src/core/ui-packs/ja.ts +1 -0
- package/src/core/ui-packs/ko.ts +1 -0
- package/src/core/ui-packs/nl.ts +1 -0
- package/src/core/ui-packs/no.ts +1 -0
- package/src/core/ui-packs/pl.ts +1 -0
- package/src/core/ui-packs/pt-br.ts +1 -0
- package/src/core/ui-packs/pt.ts +1 -0
- package/src/core/ui-packs/ro.ts +1 -0
- package/src/core/ui-packs/ru.ts +1 -0
- package/src/core/ui-packs/sk.ts +1 -0
- package/src/core/ui-packs/sr.ts +1 -0
- package/src/core/ui-packs/sv.ts +1 -0
- package/src/core/ui-packs/th.ts +1 -0
- package/src/core/ui-packs/tr.ts +1 -0
- package/src/core/ui-packs/uk.ts +1 -0
- package/src/core/ui-packs/vi.ts +1 -0
- package/src/core/ui-packs/zh-tw.ts +1 -0
- package/src/core/ui-packs/zh.ts +1 -0
- package/src/deploy/adapter-output.ts +7 -2
- package/src/deploy/adapters/cloudflare.ts +7 -5
- package/src/deploy/adapters/node.ts +47 -9
- package/src/deploy/adapters/types.ts +7 -3
- package/src/deploy/artifacts.ts +2 -1
- package/src/deploy/platforms/cloudflare.ts +13 -9
- package/src/deploy/platforms/netlify.ts +2 -1
- package/src/deploy/platforms/node.ts +12 -2
- package/src/deploy/platforms/types.ts +21 -7
- package/src/deploy/platforms/vercel.ts +113 -16
- package/src/deploy/redirects.ts +66 -6
- package/src/deploy/rss.ts +3 -1
- package/src/deploy/sitemap.ts +39 -5
- package/src/deploy/vercel-negotiation.ts +290 -102
- package/src/eval/agents.ts +18 -1
- package/src/eval/prompts.ts +6 -3
- package/src/eval/report.ts +34 -13
- package/src/eval/run.ts +5 -0
- package/src/markdown/relative-links.ts +3 -2
- package/src/openapi/checks.ts +273 -0
- package/src/openapi/graphql-build.ts +21 -0
- package/src/openapi/graphql.ts +11 -0
- package/src/openapi/model.ts +15 -3
- package/src/openapi/parse.ts +127 -2
- package/src/openapi/references.ts +43 -3
- package/src/openapi/source.ts +39 -14
- package/src/ratelimit/index.ts +1 -1
- package/src/ratelimit/runtime.ts +37 -19
- package/src/ratelimit/upstash.ts +40 -10
- package/src/reference/graphql.ts +15 -1
- package/src/reference/index.ts +1 -0
- package/src/reference/openapi.ts +2 -2
- package/src/reference/options.ts +29 -1
- package/src/registry/eject.ts +3 -1
- package/src/search/adapters/locale-scope.ts +30 -0
- package/src/search/adapters/typesense.ts +14 -4
- package/src/search/build.ts +21 -3
- package/src/search/orama-index.ts +163 -31
- package/src/search/source-pages.ts +29 -0
- package/src/search/sync/algolia.ts +99 -9
- package/src/search/sync/index.ts +52 -13
- package/src/search/sync/typesense.ts +72 -27
- package/src/sources/contentful.ts +12 -0
- package/src/sources/github-releases.ts +7 -1
- package/src/sources/shared.ts +3 -0
- package/src/theme/entry.ts +29 -3
- package/src/translate/validate.ts +23 -1
- package/dist/cli/chunk-0gz36akr.js.map +0 -12
- package/dist/cli/chunk-2n4ps1b3.js.map +0 -15
- package/dist/cli/chunk-43zcf4gz.js.map +0 -36
- package/dist/cli/chunk-4ejxbzee.js +0 -39
- package/dist/cli/chunk-4ejxbzee.js.map +0 -10
- package/dist/cli/chunk-4h8z9vv5.js.map +0 -16
- package/dist/cli/chunk-713mngdq.js.map +0 -14
- package/dist/cli/chunk-9xr4dgee.js.map +0 -10
- package/dist/cli/chunk-amrb6hgh.js +0 -145
- package/dist/cli/chunk-amrb6hgh.js.map +0 -11
- package/dist/cli/chunk-nd1821sk.js.map +0 -10
- package/dist/cli/chunk-rekqz4qg.js.map +0 -10
- package/dist/cli/chunk-ta27feev.js.map +0 -10
- package/dist/cli/chunk-xkz5xbtv.js.map +0 -213
- package/dist/cli/chunk-y5h4r2y0.js.map +0 -10
- /package/dist/cli/{chunk-gp84za0h.js.map → chunk-3v3ffbrj.js.map} +0 -0
- /package/dist/cli/{chunk-p804f3pe.js.map → chunk-8y2kmjv8.js.map} +0 -0
- /package/dist/cli/{chunk-2f7n4qzt.js.map → chunk-c1y538kd.js.map} +0 -0
- /package/dist/cli/{chunk-1n228xqb.js.map → chunk-c887fj0s.js.map} +0 -0
- /package/dist/cli/{chunk-cmtcnh9f.js.map → chunk-dzwehpy7.js.map} +0 -0
- /package/dist/cli/{chunk-ntv4qrt7.js.map → chunk-e9q7a2ak.js.map} +0 -0
- /package/dist/cli/{chunk-5wj2qwn2.js.map → chunk-ft9vfys6.js.map} +0 -0
- /package/dist/cli/{chunk-zhvd6adm.js.map → chunk-hx3xqnk9.js.map} +0 -0
- /package/dist/cli/{chunk-y4ykbark.js.map → chunk-kma9f6sf.js.map} +0 -0
- /package/dist/cli/{chunk-py62fewh.js.map → chunk-mrcccgnh.js.map} +0 -0
- /package/dist/cli/{chunk-2f3ndkpw.js.map → chunk-n0v7m8ry.js.map} +0 -0
- /package/dist/cli/{chunk-9geymqns.js.map → chunk-nq1d20w2.js.map} +0 -0
- /package/dist/cli/{chunk-g2z9x01v.js.map → chunk-nrns10mj.js.map} +0 -0
- /package/dist/cli/{chunk-e7vvk5ya.js.map → chunk-sds923fa.js.map} +0 -0
- /package/dist/cli/{chunk-yj17vs39.js.map → chunk-tdqhyxfz.js.map} +0 -0
- /package/dist/cli/{chunk-q3wxxq39.js.map → chunk-tphac74f.js.map} +0 -0
- /package/dist/cli/{chunk-6bm0xpgd.js.map → chunk-w1r4vase.js.map} +0 -0
|
@@ -21,17 +21,17 @@ Keep content where it is — set `content.root: "src/content/docs"`.
|
|
|
21
21
|
| `logo` (`{ src }` or `{ light, dark, alt }`) | `logo` — move the referenced file into `public/` |
|
|
22
22
|
| `logo.replacesTitle` | `logo: { text: "" }` (renders the mark alone) |
|
|
23
23
|
| `favicon` | copy the file into `public/` (drop the config field — Blume auto-detects) |
|
|
24
|
-
| `social` (array of `{ label, icon, href }`; pre-0.33 legacy: `{ github: url }` object) | derive **`github: { owner, repo }`** from the GitHub entry; other socials drop (report) |
|
|
24
|
+
| `social` (array of `{ label, icon, href }`; pre-0.33 legacy: `{ github: url }` object) | derive **`github: { owner, repo }`** from the GitHub entry; every other entry whose platform Blume knows → **`footer.socials`** (`{ discord: href, bluesky: href, … }`; the `x.com`/`twitter` icon → `x`; the platform list is under `footer` in `docs/configuration/index.mdx`); the rest (`mastodon`, `gitlab`, `rss`, …) drop (report) |
|
|
25
25
|
| `editLink.baseUrl` (`…/edit/<branch>/<subdir?>`) | `github: { owner, repo, branch }` — **and any repo sub-path after the branch → `github.dir`** (a docs-in-subfolder repo breaks every edit link without it); **an origin other than `https://github.com` → `github.host`** (a GitHub Enterprise repo otherwise links to the public site) |
|
|
26
26
|
| `sidebar` (array) | filesystem nav / `navigation.sidebar` (see below) |
|
|
27
27
|
| `tableOfContents` (`false` or `{ minHeadingLevel, maxHeadingLevel }`) | `toc` — identical shape, 1:1 |
|
|
28
28
|
| `markdown.headingLinks: false` | `markdown.headingAnchors: false` |
|
|
29
29
|
| `expressiveCode.themes` | `markdown.code.theme: { light, dark }` — EC assigns by theme _type_, so match each theme by its darkness, not by array position |
|
|
30
30
|
| `expressiveCode.styleOverrides` | drop → restyle via a root `theme.css` file |
|
|
31
|
-
| `head` |
|
|
31
|
+
| `head` | per entry: a `meta` tag → **`seo.metatags`** (`{ [attrs.name ?? attrs.property]: attrs.content }` — verification tokens, `theme-color`, and the like), minus the tags Blume writes itself (`description`, `robots`, `og:title`/`og:description`/`og:image`/`og:url`/`og:type`/`og:site_name`, `twitter:*` card tags, `article:*` dates — the build refuses them and names the setting that owns each, e.g. `og:image` → `seo.og`, `twitter:site` → `seo.x.handle`); an analytics `<script>` → one `script()` adapter each in the `analytics` list (from `blume/analytics`): `attrs.src` → `src`, an `async`/`defer` attr → `strategy`, every other `attrs` key → `attributes`, and an inline body (`content`) → `content`; anything else (`link`, `style`, other scripts) → drop and report |
|
|
32
32
|
| `lastUpdated: true` | `lastModified: "git"` |
|
|
33
33
|
| `customCss` | drop → move into a root **`theme.css`** file (auto-picked-up; not a config field) |
|
|
34
|
-
| `components` (overrides) | Blume's layout slots via `defineComponents({ layout: { Header
|
|
34
|
+
| `components` (overrides) | Blume's layout slots via `defineComponents({ layout: { … } })` in a root `components.ts`: `Header`, `Search`, `Sidebar`, `TableOfContents`, `Pagination` keep their names; `SiteTitle` → `Logo`; **`Footer` → `PageFooter`**, not Blume's `Footer` (that slot is the site footer; Starlight's `Footer` is the page-end last-updated date, pagination, and edit link, which Blume renders itself, so keep only what the override added). Other overrides (`Banner`, `PageTitle`, `Hero`, `EditLink`, `SocialIcons`, …) have no slot — fold their additions into `PageHeader`/`PageFooter`, or `blume eject`; a Starlight name left under `layout` matches no slot and does nothing. Rewrite reads of `Astro.locals.starlightRoute` against the slot's props |
|
|
35
35
|
| `plugins` | **map, don't blanket-drop** — see Plugins below |
|
|
36
36
|
| `pagination: false`, `pagefind`/Pagefind options, `titleDelimiter`, `credits`, `disable404Route`, `routeMiddleware` | drop (report) |
|
|
37
37
|
| `locales` / `defaultLocale` | `i18n` (see below) |
|
|
@@ -40,7 +40,7 @@ Keep content where it is — set `content.root: "src/content/docs"`.
|
|
|
40
40
|
|
|
41
41
|
Starlight's `sidebar` array → prefer letting Blume generate from the filesystem; use `navigation.sidebar` only for shapes files can't express:
|
|
42
42
|
|
|
43
|
-
- `{ label, autogenerate: { directory: "d" } }` → **structure the folder and rely on filesystem nav** (label → the folder's `meta.ts` `title`). Do **not** map it to a sidebar item with `root:` — in an explicit Blume sidebar that renders a single page link, not the directory's children.
|
|
43
|
+
- `{ label, items: [{ autogenerate: { directory: "d" } }] }` (0.39 and later; before 0.39 the group held it directly, `{ label, autogenerate: { directory: "d" } }`) → **structure the folder and rely on filesystem nav** (label → the folder's `meta.ts` `title`; `autogenerate.collapsed` → `collapsed: true` in each subfolder's `meta.ts`). Do **not** map it to a sidebar item with `root:` — in an explicit Blume sidebar that renders a single page link, not the directory's children. Since 0.39 a group's `items` can mix manual entries with an `autogenerate` entry; move those manual pages into the folder (route change → `redirects`) so the folder holds the whole group.
|
|
44
44
|
- string `"guides/intro"` → `"/guides/intro"`; `{ label?, slug }` → `/<slug>`.
|
|
45
45
|
- `{ label, items: [...] }` → `{ label, items: [...] }` (recursive) — or better, a real folder.
|
|
46
46
|
- `{ label?, link }` → `{ label, href: link }`.
|
|
@@ -59,7 +59,8 @@ Starlight's `sidebar` array → prefer letting Blume generate from the filesyste
|
|
|
59
59
|
| `lastUpdated: false` (boolean) | **remove** (Blume's `lastModified` takes a date; a boolean is a build error) |
|
|
60
60
|
| `prev: false` **and** `next: false` | `pagination: false` (hides both links) |
|
|
61
61
|
| `prev` / `next` otherwise (one side, or a label/link) | **drop** (report — the links can only be hidden together, and their labels come from the linked pages) |
|
|
62
|
-
| `template: splash`
|
|
62
|
+
| `template: splash` | `mode: center` (no sidebar, a wider centered column — the closest layout; report) |
|
|
63
|
+
| `hero` | **no key** — its tagline → a paragraph, its actions → `<Card>`s or links, its image → a Markdown image (report); for a designed landing page, rebuild it as a custom `.astro` page under `content.pages` (`pages/index.astro` on `PageLayout` wins over the content page) |
|
|
63
64
|
| `banner`, `tableOfContents`, `editUrl`, `head` | drop (report) |
|
|
64
65
|
|
|
65
66
|
## Asides → directives (and the `.md` trap)
|
|
@@ -83,7 +84,8 @@ Starlight content is full of Expressive Code fence meta; Blume understands some
|
|
|
83
84
|
- `title="file.js"` → works as-is (or use the space-title shorthand). Line ranges `{2-3}` → work as-is.
|
|
84
85
|
- `ins=`/`del=` line marks → `// [!code ++]` / `// [!code --]` comments; `mark=` → `{ranges}` or `// [!code highlight]`.
|
|
85
86
|
- `showLineNumbers` → `lineNumbers`.
|
|
86
|
-
-
|
|
87
|
+
- `wrap` / `wrap=true` → a bare `wrap` (that block's long lines wrap); a site-wide `expressiveCode.defaultProps.wrap: true` → `markdown.code.wrap: true`.
|
|
88
|
+
- **Drop:** `frame="terminal"`, `collapse=`, `wrap=false`, `preserveIndent`/`hangingIndent`, `"string"` and `/regex/` text markers (report if they carried meaning).
|
|
87
89
|
- ` ```diff lang="js" ` → a normal ` ```js ` fence with `[!code ++]`/`[!code --]` markers.
|
|
88
90
|
|
|
89
91
|
## Plugins — map, don't drop
|
|
@@ -114,4 +116,4 @@ Remove `@astrojs/starlight` (and plugin deps) from deps, delete the Starlight bi
|
|
|
114
116
|
|
|
115
117
|
## Dropped — report these
|
|
116
118
|
|
|
117
|
-
|
|
119
|
+
Socials on a platform `footer.socials` lacks, badge variants, sidebar/item `attrs` + `translations`, `customCss` beyond `theme.css`, `head` entries other than meta tags and analytics scripts, a page's frontmatter `head`, `routeMiddleware`, splash layouts approximated with `mode: center` and hero blocks rebuilt as content, override components with no Blume slot, starlight-blog's tag and author pages, aside custom icons, EC frames/collapse/text markers, prev/next toggles, unmapped plugins, any `<Icon>` name with no Lucide equivalent.
|
package/src/ai/ask-context.ts
CHANGED
|
@@ -622,10 +622,37 @@ export interface ReaderScope {
|
|
|
622
622
|
filters: { locale: string | undefined; version: string | undefined };
|
|
623
623
|
}
|
|
624
624
|
|
|
625
|
+
// The snapshot's locale codes, keyed lowercase, built once per snapshot.
|
|
626
|
+
const localeCodes = new WeakMap<AskData, Map<string, string>>();
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* The locale a path's first segment names (`/ja` or `/ja/pricing` → `ja`),
|
|
630
|
+
* when it's one the snapshot's documents carry: a page outside the docs,
|
|
631
|
+
* like a localized landing page, still says which language it's in.
|
|
632
|
+
*/
|
|
633
|
+
const pathLocale = (data: AskData, path: string): string | undefined => {
|
|
634
|
+
let codes = localeCodes.get(data);
|
|
635
|
+
if (!codes) {
|
|
636
|
+
codes = new Map<string, string>();
|
|
637
|
+
for (const { locale } of data.documents) {
|
|
638
|
+
if (locale) {
|
|
639
|
+
codes.set(locale.toLowerCase(), locale);
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
localeCodes.set(data, codes);
|
|
643
|
+
}
|
|
644
|
+
const [, first = ""] = normalizeRoute(path).split("/");
|
|
645
|
+
return first ? codes.get(first.toLowerCase()) : undefined;
|
|
646
|
+
};
|
|
647
|
+
|
|
625
648
|
/**
|
|
626
649
|
* Where the reader is: their page, when it's in the snapshot, and the locale
|
|
627
|
-
* and docs version retrieval keeps to.
|
|
628
|
-
*
|
|
650
|
+
* and docs version retrieval keeps to. A page the snapshot doesn't have (the
|
|
651
|
+
* homepage, a custom page, or none at all from a cross-origin caller) keeps
|
|
652
|
+
* to the locale its path's first segment names, or the default locale, so
|
|
653
|
+
* translations of every page don't crowd each other out. Without a page, a
|
|
654
|
+
* versioned site grounds in the current docs rather than every archived copy
|
|
655
|
+
* of each page.
|
|
629
656
|
*/
|
|
630
657
|
export const readerScope = (
|
|
631
658
|
data: AskData,
|
|
@@ -635,10 +662,13 @@ export const readerScope = (
|
|
|
635
662
|
const current = page?.path
|
|
636
663
|
? byRoute.get(normalizeRoute(page.path))
|
|
637
664
|
: undefined;
|
|
665
|
+
const locale = current
|
|
666
|
+
? current.locale
|
|
667
|
+
: (page?.path && pathLocale(data, page.path)) || data.defaultLocale;
|
|
638
668
|
return {
|
|
639
669
|
current,
|
|
640
670
|
filters: {
|
|
641
|
-
locale:
|
|
671
|
+
locale: locale || undefined,
|
|
642
672
|
version: data.versioned ? (current?.version ?? "") : undefined,
|
|
643
673
|
},
|
|
644
674
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What one request to the assistant's generated route (`/api/ask`) may carry.
|
|
3
|
+
* The route answers a longer conversation with a `400` (see
|
|
4
|
+
* `askEndpointTemplate`), so the panel's client (`useAssistant`) sends only
|
|
5
|
+
* the latest turns that fit. The endpoint is unauthenticated, so the limits
|
|
6
|
+
* bound what one request can spend against the model.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** The most messages, questions and answers together, one request sends. */
|
|
10
|
+
export const ASK_MAX_MESSAGES = 40;
|
|
11
|
+
|
|
12
|
+
/** The most characters the messages take as JSON (`JSON.stringify`). */
|
|
13
|
+
export const ASK_MAX_MESSAGES_CHARS = 24_000;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { mountBasePath, normalizeBasePath } from "../core/base-path.ts";
|
|
2
|
+
import { withChangelogIndexText } from "../core/changelog-index.ts";
|
|
2
3
|
import { EN_UI, resolveUIStrings } from "../core/i18n-ui.ts";
|
|
3
4
|
import type { BlumeProject } from "../core/project-graph.ts";
|
|
4
5
|
import { absoluteUrl } from "../core/site-url.ts";
|
|
@@ -45,12 +46,16 @@ const rowLine = (project: BlumeProject, { date, page }: IndexRow): string => {
|
|
|
45
46
|
|
|
46
47
|
export const buildChangelogIndexMarkdown = (project: BlumeProject): string => {
|
|
47
48
|
const { i18n } = project.config;
|
|
48
|
-
const ui =
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
const ui = withChangelogIndexText(
|
|
50
|
+
project.config,
|
|
51
|
+
i18n
|
|
52
|
+
? resolveUIStrings(i18n.defaultLocale, {
|
|
53
|
+
defaultLocale: i18n.defaultLocale,
|
|
54
|
+
overrides: i18n.ui,
|
|
55
|
+
})
|
|
56
|
+
: EN_UI,
|
|
57
|
+
i18n?.defaultLocale
|
|
58
|
+
);
|
|
54
59
|
const rows: IndexRow[] = project.graph.pages
|
|
55
60
|
.filter(
|
|
56
61
|
(page) =>
|
|
@@ -584,7 +584,7 @@ export const inlineCode = (text: string): string => {
|
|
|
584
584
|
};
|
|
585
585
|
|
|
586
586
|
/** Fence `code` so its opening/closing run outlengths any backticks inside. */
|
|
587
|
-
const fencedBlock = (lang: string, code: string): string => {
|
|
587
|
+
export const fencedBlock = (lang: string, code: string): string => {
|
|
588
588
|
const trimmed = code.replace(/(?<!\n)\n+$/u, "");
|
|
589
589
|
const runs = trimmed.match(/`+/gu);
|
|
590
590
|
const longest = runs ? Math.max(...runs.map((run) => run.length)) : 0;
|
package/src/ai/cors.ts
CHANGED
|
@@ -66,6 +66,13 @@ interface RequestContext {
|
|
|
66
66
|
request: Request;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
/**
|
|
70
|
+
* The response headers a cross-origin caller may read beyond the safelisted
|
|
71
|
+
* ones: the rate limit's `Retry-After`, so a caller can tell a reader how
|
|
72
|
+
* long to wait after a `429`.
|
|
73
|
+
*/
|
|
74
|
+
const EXPOSED_HEADERS = "retry-after";
|
|
75
|
+
|
|
69
76
|
/** Stamp the CORS headers on every response `handler` returns. */
|
|
70
77
|
export const withCors =
|
|
71
78
|
(
|
|
@@ -74,9 +81,8 @@ export const withCors =
|
|
|
74
81
|
): ((context: RequestContext) => Promise<Response>) =>
|
|
75
82
|
async (context) => {
|
|
76
83
|
const response = await handler(context);
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
)) {
|
|
84
|
+
const headers = corsHeaders(context.request, allowed);
|
|
85
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
80
86
|
// `Vary` accumulates (the handler may already vary on something), the
|
|
81
87
|
// rest replace.
|
|
82
88
|
if (key === "vary") {
|
|
@@ -85,5 +91,8 @@ export const withCors =
|
|
|
85
91
|
response.headers.set(key, value);
|
|
86
92
|
}
|
|
87
93
|
}
|
|
94
|
+
if (headers["access-control-allow-origin"]) {
|
|
95
|
+
response.headers.set("access-control-expose-headers", EXPOSED_HEADERS);
|
|
96
|
+
}
|
|
88
97
|
return response;
|
|
89
98
|
};
|
package/src/ai/mcp/query.ts
CHANGED
|
@@ -53,20 +53,28 @@ const contentTypesField = z.preprocess((value) => {
|
|
|
53
53
|
}, z.array(z.string()).optional().describe('Only include pages of these content types (frontmatter `type`, e.g. `["doc", "rfc"]`). `list_pages` shows each page\'s type. Omit to include every type.'));
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
|
-
* The optional facet filter `search_docs` and `list_pages` share.
|
|
57
|
-
*
|
|
56
|
+
* The optional facet filter `search_docs` and `list_pages` share. A value
|
|
57
|
+
* is read the way `pageFacets` stores one: a string as-is, a number or
|
|
58
|
+
* boolean stringified (`{"priority": 1}` matches the facet `"1"`). Entries of
|
|
59
|
+
* any other shape are dropped; an empty `{}` means "no filter".
|
|
58
60
|
*/
|
|
59
|
-
/** Accepts any plain object, so the
|
|
61
|
+
/** Accepts any plain object, so the usable entries can be sifted out. */
|
|
60
62
|
const looseFacetObject = z.record(z.string(), z.unknown());
|
|
61
63
|
|
|
64
|
+
/** A filter value a facet can hold, stringified like `pageFacets` does. */
|
|
65
|
+
const facetFilterValue = z
|
|
66
|
+
.union([z.string(), z.number(), z.boolean()])
|
|
67
|
+
.transform(String);
|
|
68
|
+
|
|
62
69
|
const filtersField = z.preprocess((value) => {
|
|
63
70
|
const candidate = looseFacetObject.safeParse(value);
|
|
64
71
|
if (!candidate.success) {
|
|
65
72
|
return;
|
|
66
73
|
}
|
|
67
|
-
const entries = Object.entries(candidate.data).
|
|
68
|
-
|
|
69
|
-
|
|
74
|
+
const entries = Object.entries(candidate.data).flatMap(([key, entry]) => {
|
|
75
|
+
const parsed = facetFilterValue.safeParse(entry);
|
|
76
|
+
return parsed.success ? [[key, parsed.data] as const] : [];
|
|
77
|
+
});
|
|
70
78
|
return entries.length > 0 ? Object.fromEntries(entries) : undefined;
|
|
71
79
|
}, z.record(z.string(), z.string()).optional().describe('Only include pages matching every facet, key → required value (e.g. `{"status": "enforced"}`). Facets are metadata the site declares per content type; `list_pages` shows each page\'s facet values. Omit for no facet filtering.'));
|
|
72
80
|
|
|
@@ -1,13 +1,24 @@
|
|
|
1
|
+
import { customCodeSamples } from "../components/openapi/code-samples.ts";
|
|
1
2
|
import { mountBasePath, normalizeBasePath } from "../core/base-path.ts";
|
|
2
3
|
import type { ApiOperationRef, OpenApiData } from "../openapi/model.ts";
|
|
3
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
operationObject,
|
|
6
|
+
operationOf,
|
|
7
|
+
specAddresses,
|
|
8
|
+
specOf,
|
|
9
|
+
} from "../openapi/model.ts";
|
|
4
10
|
import { asSentence } from "../openapi/sentence.ts";
|
|
5
11
|
import { operationSignature } from "../openapi/signature.ts";
|
|
6
12
|
import type {
|
|
7
13
|
ComponentMarkdown,
|
|
8
14
|
EvaluatedValue,
|
|
9
15
|
} from "./component-markdown.ts";
|
|
10
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
fencedBlock,
|
|
18
|
+
inlineCode,
|
|
19
|
+
isString,
|
|
20
|
+
linkDestination,
|
|
21
|
+
} from "./component-markdown.ts";
|
|
11
22
|
|
|
12
23
|
/**
|
|
13
24
|
* Spec-authored prose as one line of inline Markdown. Unlike the props the
|
|
@@ -62,7 +73,10 @@ const listItem = (
|
|
|
62
73
|
* section shows. Parameters, schemas and responses are deliberately left out:
|
|
63
74
|
* those are `operation-model.ts` plus each component's own preparation, and a
|
|
64
75
|
* second implementation here would be free to disagree with the page. The
|
|
65
|
-
* endpoint and what it does is the part that was missing altogether.
|
|
76
|
+
* endpoint and what it does is the part that was missing altogether. The
|
|
77
|
+
* spec's own `x-codeSamples` do come along, as fenced code: they're text the
|
|
78
|
+
* spec wrote out (often an SDK call no agent could derive from the
|
|
79
|
+
* endpoint), read through the same `customCodeSamples` the page renders.
|
|
66
80
|
*
|
|
67
81
|
* `specs` is the parsed `blume:openapi` data — empty when the project has no
|
|
68
82
|
* API reference, in which case every serializer declines. `deployBase` is the
|
|
@@ -142,7 +156,17 @@ export const openapiComponentSerializers = (
|
|
|
142
156
|
: "",
|
|
143
157
|
operation.deprecated ? "**Deprecated.**" : "",
|
|
144
158
|
].filter(Boolean);
|
|
145
|
-
|
|
159
|
+
// The spec's own `x-codeSamples`, labeled as their tabs are.
|
|
160
|
+
const object =
|
|
161
|
+
data.kind === "openapi" ? operationObject(data, operation) : undefined;
|
|
162
|
+
const samples = customCodeSamples({
|
|
163
|
+
"x-code-samples": object?.["x-code-samples"],
|
|
164
|
+
"x-codeSamples": object?.["x-codeSamples"],
|
|
165
|
+
}).map(
|
|
166
|
+
(sample) =>
|
|
167
|
+
`**${inlineText(sample.label)}**\n\n${fencedBlock(sample.lang, sample.source)}`
|
|
168
|
+
);
|
|
169
|
+
return [signature, ...notes, ...samples].join("\n\n");
|
|
146
170
|
},
|
|
147
171
|
} satisfies Record<string, ComponentMarkdown>;
|
|
148
172
|
};
|
package/src/ai/relative-links.ts
CHANGED
|
@@ -7,8 +7,6 @@ import {
|
|
|
7
7
|
withAuthoredBasePath,
|
|
8
8
|
withBasePath,
|
|
9
9
|
} from "../core/base-path.ts";
|
|
10
|
-
import { nextFenceState } from "../core/code-fences.ts";
|
|
11
|
-
import type { FenceState } from "../core/code-fences.ts";
|
|
12
10
|
import { localePrefix } from "../core/i18n.ts";
|
|
13
11
|
import {
|
|
14
12
|
buildFileRouteIndex,
|
|
@@ -49,10 +47,6 @@ export interface LinkedPage {
|
|
|
49
47
|
/** Rewrite a page's relative page links to the routes they mean. */
|
|
50
48
|
export type RelativeLinkRewriter = (text: string, page: LinkedPage) => string;
|
|
51
49
|
|
|
52
|
-
/** A reference definition's target: `[label]: ./install` or `<./install>`. */
|
|
53
|
-
const DEFINITION =
|
|
54
|
-
/^(?<lead> {0,3}\[(?:[^\]\\]|\\.)+\]:[\t ]*)(?:<(?<angled>[^>]*)>|(?<bare>\S+))/u;
|
|
55
|
-
|
|
56
50
|
/**
|
|
57
51
|
* Whether a text could hold a relative page link at all: an inline link, a
|
|
58
52
|
* reference definition, or a component `href` whose target isn't a URL with
|
|
@@ -88,31 +82,13 @@ const spliceLine = (line: string, splices: readonly Splice[]): string => {
|
|
|
88
82
|
return out;
|
|
89
83
|
};
|
|
90
84
|
|
|
91
|
-
/** One line's reference-definition splice, when it defines a routed target. */
|
|
92
|
-
const definitionSplice = (
|
|
93
|
-
line: string,
|
|
94
|
-
routed: (target: string) => string | undefined
|
|
95
|
-
): Splice | undefined => {
|
|
96
|
-
const groups = DEFINITION.exec(line)?.groups;
|
|
97
|
-
const lead = groups?.lead;
|
|
98
|
-
const target = groups?.angled ?? groups?.bare;
|
|
99
|
-
const route = target === undefined ? undefined : routed(target);
|
|
100
|
-
if (lead === undefined || target === undefined || route === undefined) {
|
|
101
|
-
return undefined;
|
|
102
|
-
}
|
|
103
|
-
// An angle-bracketed target starts one past its `<`.
|
|
104
|
-
const angled = groups?.angled === undefined ? 0 : 1;
|
|
105
|
-
return { column: lead.length + angled, length: target.length, text: route };
|
|
106
|
-
};
|
|
107
|
-
|
|
108
85
|
/**
|
|
109
|
-
* Every routed splice in `text`, by 0-based line: links
|
|
110
|
-
* definitions. An image target goes
|
|
111
|
-
* `routed`.
|
|
86
|
+
* Every routed splice in `text`, by 0-based line: links, images, and
|
|
87
|
+
* reference definitions, as `extractLinks` finds them. An image target goes
|
|
88
|
+
* through `imaged`, everything else through `routed`.
|
|
112
89
|
*/
|
|
113
90
|
const collectSplices = (
|
|
114
91
|
text: string,
|
|
115
|
-
lines: readonly string[],
|
|
116
92
|
routed: (target: string) => string | undefined,
|
|
117
93
|
imaged: (target: string) => string | undefined
|
|
118
94
|
): Map<number, Splice[]> => {
|
|
@@ -130,16 +106,6 @@ const collectSplices = (
|
|
|
130
106
|
});
|
|
131
107
|
}
|
|
132
108
|
}
|
|
133
|
-
let fence: FenceState = null;
|
|
134
|
-
for (const [index, line] of lines.entries()) {
|
|
135
|
-
const next = nextFenceState(line, fence);
|
|
136
|
-
const inFence = fence !== null || next !== null;
|
|
137
|
-
fence = next;
|
|
138
|
-
const splice = inFence ? undefined : definitionSplice(line, routed);
|
|
139
|
-
if (splice !== undefined) {
|
|
140
|
-
add(index, splice);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
109
|
return splices;
|
|
144
110
|
};
|
|
145
111
|
|
|
@@ -242,7 +208,7 @@ export const relativeLinkRewriter = (
|
|
|
242
208
|
};
|
|
243
209
|
|
|
244
210
|
const lines = text.split("\n");
|
|
245
|
-
const splices = collectSplices(text,
|
|
211
|
+
const splices = collectSplices(text, routed, imaged);
|
|
246
212
|
|
|
247
213
|
return lines
|
|
248
214
|
.map((line, index) => {
|
package/src/astro/generate.ts
CHANGED
|
@@ -34,7 +34,11 @@ import {
|
|
|
34
34
|
navVariants,
|
|
35
35
|
} from "../components/layout/nav-utils.ts";
|
|
36
36
|
import { normalizeBasePath, withBasePath } from "../core/base-path.ts";
|
|
37
|
-
import {
|
|
37
|
+
import { withChangelogIndexText } from "../core/changelog-index.ts";
|
|
38
|
+
import {
|
|
39
|
+
missingExampleDiagnostics,
|
|
40
|
+
validateUsedComponents,
|
|
41
|
+
} from "../core/component-diagnostics.ts";
|
|
38
42
|
import {
|
|
39
43
|
analyzeComponentOverrides,
|
|
40
44
|
emptyComponentOverrides,
|
|
@@ -93,13 +97,13 @@ import {
|
|
|
93
97
|
builtinProxyReferences,
|
|
94
98
|
hasScalarReferences,
|
|
95
99
|
needsPlaygroundProxy,
|
|
96
|
-
referenceRoutes,
|
|
97
100
|
} from "../openapi/references.ts";
|
|
98
101
|
import { buildReferenceFiles } from "../openapi/scalar.ts";
|
|
99
102
|
import { isOpenApiSource } from "../openapi/source.ts";
|
|
100
103
|
import { registry } from "../registry/registry.ts";
|
|
101
104
|
import { buildSearchDocuments } from "../search/documents.ts";
|
|
102
105
|
import { resolveSearchPopular } from "../search/popular.ts";
|
|
106
|
+
import { sourcePages } from "../search/source-pages.ts";
|
|
103
107
|
import {
|
|
104
108
|
examplesEntryTemplate,
|
|
105
109
|
tailwindEntryTemplate,
|
|
@@ -125,6 +129,7 @@ import {
|
|
|
125
129
|
customOgRoutes,
|
|
126
130
|
discoverPages,
|
|
127
131
|
hasGeneratedChangelog,
|
|
132
|
+
navTargetRoutes,
|
|
128
133
|
routeIsTaken,
|
|
129
134
|
} from "./pages.ts";
|
|
130
135
|
import { candidateHolding } from "./render-deps.ts";
|
|
@@ -180,28 +185,35 @@ export type { PrerenderDepsPlugin } from "./render-deps.ts";
|
|
|
180
185
|
const BLUME_SRC = join(packageRoot(), "src");
|
|
181
186
|
|
|
182
187
|
/**
|
|
183
|
-
*
|
|
184
|
-
*
|
|
188
|
+
* Whether the generated `react()` call turns the React Compiler on: React and
|
|
189
|
+
* `react.compiler` are both on, and `oxc-transform-react` (Blume ships it)
|
|
190
|
+
* resolves. False when React or the compiler is off.
|
|
185
191
|
*
|
|
186
|
-
* The
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
192
|
+
* The compiler is loaded by `@vitejs/plugin-react` with a bare
|
|
193
|
+
* `import("oxc-transform-react")` from its own directory, which fails the
|
|
194
|
+
* build when it throws, so the check walks the same chain — Blume →
|
|
195
|
+
* `@astrojs/react` → `@vitejs/plugin-react` — rather than resolving from
|
|
196
|
+
* Blume's root, which a strict package manager may not link the plugin to.
|
|
190
197
|
*/
|
|
191
198
|
export const resolveReactCompiler = (
|
|
192
199
|
config: ResolvedConfig,
|
|
193
200
|
needsReact: boolean,
|
|
194
201
|
pkgDir: string = packageRoot()
|
|
195
|
-
):
|
|
202
|
+
): boolean => {
|
|
196
203
|
if (!(needsReact && config.react.compiler)) {
|
|
197
|
-
return
|
|
204
|
+
return false;
|
|
198
205
|
}
|
|
199
206
|
try {
|
|
200
|
-
|
|
201
|
-
"
|
|
207
|
+
const astroReact = createRequire(
|
|
208
|
+
pathToFileURL(join(pkgDir, "_.js")).href
|
|
209
|
+
).resolve("@astrojs/react");
|
|
210
|
+
const pluginReact = createRequire(astroReact).resolve(
|
|
211
|
+
"@vitejs/plugin-react"
|
|
202
212
|
);
|
|
213
|
+
createRequire(pluginReact).resolve("oxc-transform-react");
|
|
214
|
+
return true;
|
|
203
215
|
} catch {
|
|
204
|
-
return
|
|
216
|
+
return false;
|
|
205
217
|
}
|
|
206
218
|
};
|
|
207
219
|
|
|
@@ -213,11 +225,11 @@ export const resolveReactCompiler = (
|
|
|
213
225
|
export const reactCompilerWarnings = (
|
|
214
226
|
config: ResolvedConfig,
|
|
215
227
|
needsReact: boolean,
|
|
216
|
-
|
|
228
|
+
compiler: boolean
|
|
217
229
|
): string[] =>
|
|
218
|
-
needsReact && config.react.compiler && !
|
|
230
|
+
needsReact && config.react.compiler && !compiler
|
|
219
231
|
? [
|
|
220
|
-
"React Compiler is enabled but `
|
|
232
|
+
"React Compiler is enabled but `oxc-transform-react` could not be resolved; falling back to an uncompiled build. Reinstall Blume, or set `react: { compiler: false }` to silence this.",
|
|
221
233
|
]
|
|
222
234
|
: [];
|
|
223
235
|
|
|
@@ -1142,23 +1154,32 @@ export const buildRuntimeData = (project: BlumeProject): string => {
|
|
|
1142
1154
|
|
|
1143
1155
|
// Resolved UI dictionaries: one per locale under i18n, English baseline
|
|
1144
1156
|
// otherwise. Threaded into chrome so the catch-all can pick the active locale.
|
|
1157
|
+
// The `changelog` config's title and description replace the dictionaries'.
|
|
1145
1158
|
const uiByLocale = i18n
|
|
1146
1159
|
? Object.fromEntries(
|
|
1147
1160
|
i18n.locales.map(({ code }) => [
|
|
1148
1161
|
code,
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1162
|
+
withChangelogIndexText(
|
|
1163
|
+
config,
|
|
1164
|
+
resolveUIStrings(code, {
|
|
1165
|
+
defaultLocale: i18n.defaultLocale,
|
|
1166
|
+
overrides: i18n.ui,
|
|
1167
|
+
}),
|
|
1168
|
+
code
|
|
1169
|
+
),
|
|
1153
1170
|
])
|
|
1154
1171
|
)
|
|
1155
1172
|
: {};
|
|
1156
|
-
const defaultUi =
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1173
|
+
const defaultUi = withChangelogIndexText(
|
|
1174
|
+
config,
|
|
1175
|
+
i18n
|
|
1176
|
+
? resolveUIStrings(i18n.defaultLocale, {
|
|
1177
|
+
defaultLocale: i18n.defaultLocale,
|
|
1178
|
+
overrides: i18n.ui,
|
|
1179
|
+
})
|
|
1180
|
+
: EN_UI,
|
|
1181
|
+
i18n?.defaultLocale
|
|
1182
|
+
);
|
|
1162
1183
|
|
|
1163
1184
|
const navigationByLocale = i18n
|
|
1164
1185
|
? Object.fromEntries(
|
|
@@ -1255,6 +1276,7 @@ export const buildRuntimeData = (project: BlumeProject): string => {
|
|
|
1255
1276
|
openInChat: config.ai.openInChat,
|
|
1256
1277
|
repoUrl,
|
|
1257
1278
|
search: {
|
|
1279
|
+
analytics: config.search.analytics,
|
|
1258
1280
|
enabled: config.search.provider.mode !== "none",
|
|
1259
1281
|
popular: resolveSearchPopular(config.search.popular, config.basePath),
|
|
1260
1282
|
provider: config.search.provider.kind,
|
|
@@ -2064,11 +2086,12 @@ export const generateRuntime = async (
|
|
|
2064
2086
|
const needsVue = frameworks.has("vue");
|
|
2065
2087
|
const needsSvelte = frameworks.has("svelte");
|
|
2066
2088
|
|
|
2067
|
-
//
|
|
2068
|
-
//
|
|
2069
|
-
//
|
|
2070
|
-
// warning is folded into `warnings` below (declared
|
|
2071
|
-
|
|
2089
|
+
// Whether react() turns the React Compiler on (false when off). Checked here,
|
|
2090
|
+
// Node-side, so an unresolvable compiler degrades to an uncompiled build
|
|
2091
|
+
// instead of failing it — see resolveReactCompiler. Any
|
|
2092
|
+
// unresolved-but-requested warning is folded into `warnings` below (declared
|
|
2093
|
+
// later).
|
|
2094
|
+
const reactCompiler = resolveReactCompiler(config, needsReact);
|
|
2072
2095
|
|
|
2073
2096
|
// Custom pages that should get a generated OG card (the home most of all).
|
|
2074
2097
|
// Computed before the MCP `.well-known` routes are appended below — those are
|
|
@@ -2146,7 +2169,7 @@ export const generateRuntime = async (
|
|
|
2146
2169
|
needsSvelte,
|
|
2147
2170
|
needsVue,
|
|
2148
2171
|
pages,
|
|
2149
|
-
|
|
2172
|
+
reactCompiler,
|
|
2150
2173
|
searchClientPath,
|
|
2151
2174
|
themePath,
|
|
2152
2175
|
})
|
|
@@ -2209,7 +2232,7 @@ export const generateRuntime = async (
|
|
|
2209
2232
|
languageIcons,
|
|
2210
2233
|
sources: [
|
|
2211
2234
|
`${BLUME_SRC}/**/*.{astro,ts,tsx}`,
|
|
2212
|
-
`${context.root}/**/*.{astro,mdx,ts,tsx}`,
|
|
2235
|
+
`${context.root}/**/*.{astro,jsx,mdx,ts,tsx}`,
|
|
2213
2236
|
],
|
|
2214
2237
|
twoslashCss: twoslashCss(),
|
|
2215
2238
|
userTheme,
|
|
@@ -2247,7 +2270,10 @@ export const generateRuntime = async (
|
|
|
2247
2270
|
writeMcpFiles(mcp, write, agentData),
|
|
2248
2271
|
writeApiFiles(project, api, write, agentData, mcp),
|
|
2249
2272
|
playgroundProxy.enabled
|
|
2250
|
-
? write(
|
|
2273
|
+
? write(
|
|
2274
|
+
playgroundProxy.entrypoint,
|
|
2275
|
+
playgroundProxyTemplate(proxyOrigins, config.rateLimit)
|
|
2276
|
+
)
|
|
2251
2277
|
: Promise.resolve(false),
|
|
2252
2278
|
]);
|
|
2253
2279
|
|
|
@@ -2317,7 +2343,11 @@ export const generateRuntime = async (
|
|
|
2317
2343
|
if (searchAdapter.kind === "mixedbread") {
|
|
2318
2344
|
await write(
|
|
2319
2345
|
join(srcDir, "pages", "api", "search.ts"),
|
|
2320
|
-
mixedbreadSearchEndpointTemplate(
|
|
2346
|
+
mixedbreadSearchEndpointTemplate(
|
|
2347
|
+
searchAdapter.options,
|
|
2348
|
+
sourcePages(project),
|
|
2349
|
+
config.rateLimit
|
|
2350
|
+
)
|
|
2321
2351
|
);
|
|
2322
2352
|
}
|
|
2323
2353
|
|
|
@@ -2372,7 +2402,7 @@ export const generateRuntime = async (
|
|
|
2372
2402
|
...(depsLinkWarning ? [depsLinkWarning] : []),
|
|
2373
2403
|
...proxyAllowlistWarnings(config, openApiData),
|
|
2374
2404
|
...apiPageProxyWarnings(project),
|
|
2375
|
-
...reactCompilerWarnings(config, needsReact,
|
|
2405
|
+
...reactCompilerWarnings(config, needsReact, reactCompiler),
|
|
2376
2406
|
...mcp.warnings,
|
|
2377
2407
|
...islandDiscovery.warnings,
|
|
2378
2408
|
...exampleDiscovery.warnings,
|
|
@@ -2380,24 +2410,18 @@ export const generateRuntime = async (
|
|
|
2380
2410
|
...overrideWarnings,
|
|
2381
2411
|
];
|
|
2382
2412
|
|
|
2383
|
-
// Missing-navigation-target check, now that every servable route is known
|
|
2384
|
-
//
|
|
2385
|
-
// OpenAPI reference routes (so a tab an author points at one still validates).
|
|
2386
|
-
const navTargetRoutes = new Set<string>([
|
|
2387
|
-
...project.graph.routes.keys(),
|
|
2388
|
-
...pages.map((page) => page.pattern),
|
|
2389
|
-
...referenceRoutes(config),
|
|
2390
|
-
]);
|
|
2391
|
-
if (changelogIndex) {
|
|
2392
|
-
navTargetRoutes.add("/changelog");
|
|
2393
|
-
}
|
|
2413
|
+
// Missing-navigation-target check, now that every servable route is known
|
|
2414
|
+
// (see `navTargetRoutes`).
|
|
2394
2415
|
// Curated `search.popular` icons live outside the navigation model, so they
|
|
2395
2416
|
// miss `validateNavIcons` in the graph build — they're checked here too,
|
|
2396
2417
|
// where the search config is known. A typo otherwise just renders the
|
|
2397
2418
|
// default glyph.
|
|
2398
2419
|
warnings.push(
|
|
2399
2420
|
...[
|
|
2400
|
-
...validateNavTargets(
|
|
2421
|
+
...validateNavTargets(
|
|
2422
|
+
project.graph.navigation,
|
|
2423
|
+
navTargetRoutes(project, pages)
|
|
2424
|
+
),
|
|
2401
2425
|
...validateSearchPopularIcons(config.search.popular),
|
|
2402
2426
|
].map(diagnosticWarning)
|
|
2403
2427
|
);
|
|
@@ -2414,6 +2438,12 @@ export const generateRuntime = async (
|
|
|
2414
2438
|
knownComponentTags,
|
|
2415
2439
|
new Set(registry.map((item) => item.name))
|
|
2416
2440
|
).map(diagnosticWarning),
|
|
2441
|
+
...missingExampleDiagnostics(
|
|
2442
|
+
project.graph.pages,
|
|
2443
|
+
exampleDiscovery,
|
|
2444
|
+
context.root,
|
|
2445
|
+
knownComponentTags
|
|
2446
|
+
).map(diagnosticWarning),
|
|
2417
2447
|
...dependencyWarnings
|
|
2418
2448
|
);
|
|
2419
2449
|
if (hasScalarReferences(config)) {
|