blume 2.1.0 → 2.1.2
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 +110 -0
- 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-43zcf4gz.js → chunk-0pmb4tr4.js} +541 -368
- package/dist/cli/chunk-0pmb4tr4.js.map +35 -0
- package/dist/cli/{chunk-9geymqns.js → chunk-0w6hs479.js} +15 -15
- package/dist/cli/{chunk-xkz5xbtv.js → chunk-124fvmzq.js} +2802 -1422
- package/dist/cli/chunk-124fvmzq.js.map +220 -0
- package/dist/cli/chunk-150jk7km.js +52 -0
- package/dist/cli/chunk-150jk7km.js.map +10 -0
- package/dist/cli/{chunk-y4ykbark.js → chunk-1f882900.js} +2 -2
- package/dist/cli/{chunk-5ffywsmb.js → chunk-297ajdcv.js} +8 -6
- package/dist/cli/{chunk-5ffywsmb.js.map → chunk-297ajdcv.js.map} +3 -3
- package/dist/cli/{chunk-h2a48yhd.js → chunk-32khwcb6.js} +120 -16
- package/dist/cli/{chunk-h2a48yhd.js.map → chunk-32khwcb6.js.map} +10 -10
- package/dist/cli/{chunk-5cg2rzgf.js → chunk-36bxs9c7.js} +20 -49
- package/dist/cli/{chunk-5cg2rzgf.js.map → chunk-36bxs9c7.js.map} +4 -5
- package/dist/cli/{chunk-py62fewh.js → chunk-53jqw8z0.js} +3 -3
- package/dist/cli/{chunk-5wj2qwn2.js → chunk-58bt3hag.js} +4 -4
- package/dist/cli/{chunk-e7vvk5ya.js → chunk-5cmts6dv.js} +3 -3
- package/dist/cli/{chunk-y5h4r2y0.js → chunk-60hz265r.js} +15 -5
- package/dist/cli/chunk-60hz265r.js.map +10 -0
- package/dist/cli/chunk-74wfhv79.js +65 -0
- package/dist/cli/chunk-74wfhv79.js.map +10 -0
- package/dist/cli/{chunk-g2z9x01v.js → chunk-9qzgg6mj.js} +3 -3
- package/dist/cli/{chunk-q3wxxq39.js → chunk-a57yh0h9.js} +5 -5
- package/dist/cli/{chunk-713mngdq.js → chunk-ave1wcbr.js} +76 -10
- package/dist/cli/chunk-ave1wcbr.js.map +14 -0
- package/dist/cli/{chunk-2n4ps1b3.js → chunk-bqxaqn5p.js} +40 -22
- package/dist/cli/chunk-bqxaqn5p.js.map +15 -0
- package/dist/cli/{chunk-jnwj5kjj.js → chunk-bxwhtvw8.js} +20 -7
- package/dist/cli/{chunk-jnwj5kjj.js.map → chunk-bxwhtvw8.js.map} +3 -3
- package/dist/cli/chunk-ckrcm08h.js +324 -0
- package/dist/cli/chunk-ckrcm08h.js.map +14 -0
- package/dist/cli/{chunk-2f3ndkpw.js → chunk-desvm72z.js} +3 -3
- package/dist/cli/{chunk-gp84za0h.js → chunk-dhwtqnnd.js} +2 -2
- package/dist/cli/{chunk-4h8z9vv5.js → chunk-dpy8qdjf.js} +93 -47
- package/dist/cli/chunk-dpy8qdjf.js.map +17 -0
- package/dist/cli/{chunk-2f7n4qzt.js → chunk-dqhg54mr.js} +1 -1
- package/dist/cli/{chunk-0gz36akr.js → chunk-dv2z0rzf.js} +21 -5
- package/dist/cli/chunk-dv2z0rzf.js.map +12 -0
- package/dist/cli/{chunk-cm89scdv.js → chunk-es8h0v3j.js} +9 -11
- package/dist/cli/{chunk-cm89scdv.js.map → chunk-es8h0v3j.js.map} +3 -3
- package/dist/cli/{chunk-zhvd6adm.js → chunk-gfc5fqvf.js} +14 -14
- package/dist/cli/{chunk-nd1821sk.js → chunk-gxtg6ed2.js} +33 -19
- package/dist/cli/chunk-gxtg6ed2.js.map +10 -0
- package/dist/cli/{chunk-p804f3pe.js → chunk-hvcxng5f.js} +6 -6
- package/dist/cli/{chunk-ta27feev.js → chunk-j1x92mx9.js} +21 -2
- package/dist/cli/chunk-j1x92mx9.js.map +10 -0
- package/dist/cli/{chunk-rekqz4qg.js → chunk-k3gr1nm9.js} +19 -16
- package/dist/cli/chunk-k3gr1nm9.js.map +10 -0
- package/dist/cli/{chunk-1n228xqb.js → chunk-kdpzw38a.js} +2 -2
- package/dist/cli/{chunk-cy5bm0j0.js → chunk-ms9z66nz.js} +2 -2
- package/dist/cli/{chunk-cy5bm0j0.js.map → chunk-ms9z66nz.js.map} +2 -2
- package/dist/cli/{chunk-zf748avv.js → chunk-nbyvgnnm.js} +193 -286
- package/dist/cli/chunk-nbyvgnnm.js.map +36 -0
- package/dist/cli/{chunk-6bm0xpgd.js → chunk-s0bdnc7v.js} +2 -2
- package/dist/cli/{chunk-yxmk4pec.js → chunk-sc93apfs.js} +17 -16
- package/dist/cli/{chunk-yxmk4pec.js.map → chunk-sc93apfs.js.map} +3 -3
- package/dist/cli/{chunk-cmtcnh9f.js → chunk-tfycddbt.js} +2 -2
- package/dist/cli/{chunk-9xr4dgee.js → chunk-twy7psdz.js} +29 -16
- package/dist/cli/chunk-twy7psdz.js.map +10 -0
- package/dist/cli/{chunk-ntv4qrt7.js → chunk-y4msrwm9.js} +15 -15
- package/dist/cli/{chunk-yj17vs39.js → chunk-ydp3065p.js} +5 -5
- 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/ask.d.ts +24 -5
- package/dist/types/ai/component-markdown.d.ts +2 -0
- package/dist/types/ai/openapi-components.d.ts +4 -1
- package/dist/types/analytics/clics.d.ts +37 -0
- package/dist/types/analytics/index.d.ts +2 -0
- package/dist/types/analytics/schema.d.ts +18 -0
- package/dist/types/astro/integration.d.ts +11 -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 +37 -6
- 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/powered-by.d.ts +12 -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 +228 -3
- 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/lower.d.ts +10 -2
- package/dist/types/core/sources/normalize.d.ts +20 -1
- package/dist/types/core/sources/notion.d.ts +8 -0
- 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/cloudflare-negotiation.d.ts +5 -2
- package/dist/types/deploy/node-headers.d.ts +12 -4
- 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 +21 -2
- 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 +44 -21
- package/dist/types/narration/build.d.ts +34 -12
- package/dist/types/narration/provider.d.ts +96 -8
- 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/openapi/sentence.d.ts +11 -1
- 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/seo/jsonld.d.ts +11 -6
- package/dist/types/sources/contentful.d.ts +16 -0
- package/dist/types/sources/github-releases.d.ts +8 -1
- package/dist/types/sources/notion.d.ts +8 -0
- package/dist/types/sources/payload.d.ts +2 -0
- package/dist/types/sources/registry.d.ts +63 -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 +59 -13
- package/docs/03-upgrading.mdx +2 -1
- package/docs/04-migrating.mdx +9 -9
- package/docs/08-faq.mdx +12 -12
- package/docs/advanced/changelog.mdx +30 -2
- package/docs/advanced/custom-pages.mdx +1 -1
- package/docs/advanced/skills.mdx +1 -1
- package/docs/cli/audit.mdx +30 -7
- package/docs/cli/doctor.mdx +6 -2
- 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 +19 -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 +4 -2
- package/docs/configuration/narration.mdx +43 -6
- 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 +8 -6
- package/docs/content/sources/contentful.mdx +9 -4
- package/docs/content/sources/custom.mdx +7 -3
- package/docs/content/sources/github-releases.mdx +12 -2
- package/docs/content/sources/index.mdx +3 -3
- package/docs/content/sources/notion.mdx +17 -2
- package/docs/content/sources/obsidian.mdx +3 -1
- package/docs/content/sources/payload.mdx +5 -2
- package/docs/content/sources/remote-mdx.mdx +6 -0
- package/docs/content/sources/sanity.mdx +4 -2
- package/docs/content/sources/strapi.mdx +5 -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 +6 -0
- package/docs/discoverability/sitemap-and-robots.mdx +1 -1
- package/docs/discoverability/structured-data.mdx +8 -6
- package/docs/references/api-pages.mdx +1 -1
- package/docs/references/asyncapi.mdx +5 -1
- package/docs/references/graphql.mdx +15 -1
- package/docs/references/openapi.mdx +64 -8
- package/package.json +9 -9
- package/skills/blume/SKILL.md +1 -1
- package/skills/blume-migrate/SKILL.md +2 -2
- package/skills/blume-migrate/assets/{oxfmt@0.67.0.patch → oxfmt@0.71.0.patch} +7 -7
- package/skills/blume-migrate/references/docusaurus.md +4 -4
- package/skills/blume-migrate/references/fumadocs.md +17 -13
- package/skills/blume-migrate/references/monorepo.md +5 -5
- 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/ask.ts +24 -6
- 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/analytics/clics.ts +58 -0
- package/src/analytics/head.ts +5 -0
- package/src/analytics/index.ts +2 -0
- package/src/analytics/schema.ts +2 -0
- package/src/astro/generate.ts +91 -56
- package/src/astro/integration.ts +72 -22
- 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/render-deps.ts +10 -5
- package/src/astro/runtime-deps.ts +23 -2
- package/src/astro/templates.ts +129 -81
- 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 +9 -6
- package/src/cli/prepare.ts +6 -3
- package/src/cli/required-secrets.ts +3 -2
- 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/content/view-switcher.ts +7 -4
- package/src/components/islands/hooks.ts +27 -1
- package/src/components/layout/NavTree.astro +49 -5
- package/src/components/layout/NavTreeScript.astro +18 -0
- package/src/components/layout/PageActions.astro +139 -24
- package/src/components/layout/PageLayout.astro +13 -3
- package/src/components/layout/RootLayout.astro +27 -14
- package/src/components/layout/Search.astro +17 -3
- package/src/components/layout/TableOfContents.astro +24 -17
- package/src/components/layout/analytics-client.ts +8 -8
- 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 +77 -58
- 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/components/powered-by-middleware.ts +33 -0
- 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 +42 -6
- 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/powered-by.ts +12 -0
- 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 +26 -6
- 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/lower.ts +19 -3
- package/src/core/sources/mdx-remote.ts +62 -10
- package/src/core/sources/normalize.ts +227 -41
- package/src/core/sources/notion.ts +34 -10
- 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/cloudflare-negotiation.ts +36 -7
- package/src/deploy/headers.ts +15 -1
- package/src/deploy/node-headers.ts +32 -20
- package/src/deploy/platforms/cloudflare.ts +14 -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 +115 -17
- 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 +325 -103
- 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/base-links.ts +15 -14
- package/src/markdown/package-commands.ts +9 -8
- package/src/markdown/relative-links.ts +3 -2
- package/src/narration/build.ts +218 -40
- package/src/narration/provider.ts +89 -9
- 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/render-mdx.ts +68 -8
- package/src/openapi/sentence.ts +29 -2
- 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 +8 -2
- 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/seo/jsonld.ts +38 -20
- package/src/sources/contentful.ts +12 -0
- package/src/sources/github-releases.ts +7 -1
- package/src/sources/notion.ts +7 -0
- package/src/sources/shared.ts +3 -0
- package/src/theme/color.ts +9 -10
- package/src/theme/entry.ts +43 -6
- 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-zf748avv.js.map +0 -37
- /package/dist/cli/{chunk-9geymqns.js.map → chunk-0w6hs479.js.map} +0 -0
- /package/dist/cli/{chunk-y4ykbark.js.map → chunk-1f882900.js.map} +0 -0
- /package/dist/cli/{chunk-py62fewh.js.map → chunk-53jqw8z0.js.map} +0 -0
- /package/dist/cli/{chunk-5wj2qwn2.js.map → chunk-58bt3hag.js.map} +0 -0
- /package/dist/cli/{chunk-e7vvk5ya.js.map → chunk-5cmts6dv.js.map} +0 -0
- /package/dist/cli/{chunk-g2z9x01v.js.map → chunk-9qzgg6mj.js.map} +0 -0
- /package/dist/cli/{chunk-q3wxxq39.js.map → chunk-a57yh0h9.js.map} +0 -0
- /package/dist/cli/{chunk-2f3ndkpw.js.map → chunk-desvm72z.js.map} +0 -0
- /package/dist/cli/{chunk-gp84za0h.js.map → chunk-dhwtqnnd.js.map} +0 -0
- /package/dist/cli/{chunk-2f7n4qzt.js.map → chunk-dqhg54mr.js.map} +0 -0
- /package/dist/cli/{chunk-zhvd6adm.js.map → chunk-gfc5fqvf.js.map} +0 -0
- /package/dist/cli/{chunk-p804f3pe.js.map → chunk-hvcxng5f.js.map} +0 -0
- /package/dist/cli/{chunk-1n228xqb.js.map → chunk-kdpzw38a.js.map} +0 -0
- /package/dist/cli/{chunk-6bm0xpgd.js.map → chunk-s0bdnc7v.js.map} +0 -0
- /package/dist/cli/{chunk-cmtcnh9f.js.map → chunk-tfycddbt.js.map} +0 -0
- /package/dist/cli/{chunk-ntv4qrt7.js.map → chunk-y4msrwm9.js.map} +0 -0
- /package/dist/cli/{chunk-yj17vs39.js.map → chunk-ydp3065p.js.map} +0 -0
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,
|
|
@@ -1796,21 +1818,26 @@ export const diagnosticWarning = (diagnostic: Diagnostic): string =>
|
|
|
1796
1818
|
|
|
1797
1819
|
/**
|
|
1798
1820
|
* Missing-dependency preflight: the search provider's SDK, content source
|
|
1799
|
-
* SDKs, the assistant backend's provider
|
|
1800
|
-
* and — since React ships with Blume while Vue/Svelte
|
|
1801
|
-
* framework's Astro integration. A build fails here,
|
|
1802
|
-
* written, with the install command for the project's
|
|
1803
|
-
* otherwise Vite dies later on an opaque unresolved import
|
|
1804
|
-
* runtime. Dev warns and keeps serving: only the pages and
|
|
1805
|
-
* the package break, and installing it is picked up on
|
|
1821
|
+
* SDKs, the assistant backend's and narration provider's SDKs, the deployment
|
|
1822
|
+
* adapter's package, and — since React ships with Blume while Vue/Svelte
|
|
1823
|
+
* don't — any island framework's Astro integration. A build fails here,
|
|
1824
|
+
* before anything is written, with the install command for the project's
|
|
1825
|
+
* package manager — otherwise Vite dies later on an opaque unresolved import
|
|
1826
|
+
* from the hidden runtime. Dev warns and keeps serving: only the pages and
|
|
1827
|
+
* routes that import the package break, and installing it is picked up on
|
|
1828
|
+
* the next restart. Dev leaves narration's SDK out, since only a build
|
|
1829
|
+
* generates the clips.
|
|
1806
1830
|
*/
|
|
1807
1831
|
const dependencyPreflight = async (
|
|
1808
1832
|
project: BlumeProject,
|
|
1809
1833
|
frameworks: Set<string>
|
|
1810
1834
|
): Promise<string[]> => {
|
|
1811
1835
|
const build = project.mode === "build";
|
|
1836
|
+
const { config } = project;
|
|
1812
1837
|
const diagnostic = await missingDependencyDiagnostic(
|
|
1813
|
-
|
|
1838
|
+
build
|
|
1839
|
+
? config
|
|
1840
|
+
: { ...config, narration: { ...config.narration, provider: null } },
|
|
1814
1841
|
project.context.root,
|
|
1815
1842
|
build ? "error" : "warning",
|
|
1816
1843
|
frameworks
|
|
@@ -2064,11 +2091,12 @@ export const generateRuntime = async (
|
|
|
2064
2091
|
const needsVue = frameworks.has("vue");
|
|
2065
2092
|
const needsSvelte = frameworks.has("svelte");
|
|
2066
2093
|
|
|
2067
|
-
//
|
|
2068
|
-
//
|
|
2069
|
-
//
|
|
2070
|
-
// warning is folded into `warnings` below (declared
|
|
2071
|
-
|
|
2094
|
+
// Whether react() turns the React Compiler on (false when off). Checked here,
|
|
2095
|
+
// Node-side, so an unresolvable compiler degrades to an uncompiled build
|
|
2096
|
+
// instead of failing it — see resolveReactCompiler. Any
|
|
2097
|
+
// unresolved-but-requested warning is folded into `warnings` below (declared
|
|
2098
|
+
// later).
|
|
2099
|
+
const reactCompiler = resolveReactCompiler(config, needsReact);
|
|
2072
2100
|
|
|
2073
2101
|
// Custom pages that should get a generated OG card (the home most of all).
|
|
2074
2102
|
// Computed before the MCP `.well-known` routes are appended below — those are
|
|
@@ -2146,7 +2174,7 @@ export const generateRuntime = async (
|
|
|
2146
2174
|
needsSvelte,
|
|
2147
2175
|
needsVue,
|
|
2148
2176
|
pages,
|
|
2149
|
-
|
|
2177
|
+
reactCompiler,
|
|
2150
2178
|
searchClientPath,
|
|
2151
2179
|
themePath,
|
|
2152
2180
|
})
|
|
@@ -2209,7 +2237,7 @@ export const generateRuntime = async (
|
|
|
2209
2237
|
languageIcons,
|
|
2210
2238
|
sources: [
|
|
2211
2239
|
`${BLUME_SRC}/**/*.{astro,ts,tsx}`,
|
|
2212
|
-
`${context.root}/**/*.{astro,mdx,ts,tsx}`,
|
|
2240
|
+
`${context.root}/**/*.{astro,jsx,mdx,ts,tsx}`,
|
|
2213
2241
|
],
|
|
2214
2242
|
twoslashCss: twoslashCss(),
|
|
2215
2243
|
userTheme,
|
|
@@ -2247,7 +2275,10 @@ export const generateRuntime = async (
|
|
|
2247
2275
|
writeMcpFiles(mcp, write, agentData),
|
|
2248
2276
|
writeApiFiles(project, api, write, agentData, mcp),
|
|
2249
2277
|
playgroundProxy.enabled
|
|
2250
|
-
? write(
|
|
2278
|
+
? write(
|
|
2279
|
+
playgroundProxy.entrypoint,
|
|
2280
|
+
playgroundProxyTemplate(proxyOrigins, config.rateLimit)
|
|
2281
|
+
)
|
|
2251
2282
|
: Promise.resolve(false),
|
|
2252
2283
|
]);
|
|
2253
2284
|
|
|
@@ -2317,7 +2348,11 @@ export const generateRuntime = async (
|
|
|
2317
2348
|
if (searchAdapter.kind === "mixedbread") {
|
|
2318
2349
|
await write(
|
|
2319
2350
|
join(srcDir, "pages", "api", "search.ts"),
|
|
2320
|
-
mixedbreadSearchEndpointTemplate(
|
|
2351
|
+
mixedbreadSearchEndpointTemplate(
|
|
2352
|
+
searchAdapter.options,
|
|
2353
|
+
sourcePages(project),
|
|
2354
|
+
config.rateLimit
|
|
2355
|
+
)
|
|
2321
2356
|
);
|
|
2322
2357
|
}
|
|
2323
2358
|
|
|
@@ -2372,7 +2407,7 @@ export const generateRuntime = async (
|
|
|
2372
2407
|
...(depsLinkWarning ? [depsLinkWarning] : []),
|
|
2373
2408
|
...proxyAllowlistWarnings(config, openApiData),
|
|
2374
2409
|
...apiPageProxyWarnings(project),
|
|
2375
|
-
...reactCompilerWarnings(config, needsReact,
|
|
2410
|
+
...reactCompilerWarnings(config, needsReact, reactCompiler),
|
|
2376
2411
|
...mcp.warnings,
|
|
2377
2412
|
...islandDiscovery.warnings,
|
|
2378
2413
|
...exampleDiscovery.warnings,
|
|
@@ -2380,24 +2415,18 @@ export const generateRuntime = async (
|
|
|
2380
2415
|
...overrideWarnings,
|
|
2381
2416
|
];
|
|
2382
2417
|
|
|
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
|
-
}
|
|
2418
|
+
// Missing-navigation-target check, now that every servable route is known
|
|
2419
|
+
// (see `navTargetRoutes`).
|
|
2394
2420
|
// Curated `search.popular` icons live outside the navigation model, so they
|
|
2395
2421
|
// miss `validateNavIcons` in the graph build — they're checked here too,
|
|
2396
2422
|
// where the search config is known. A typo otherwise just renders the
|
|
2397
2423
|
// default glyph.
|
|
2398
2424
|
warnings.push(
|
|
2399
2425
|
...[
|
|
2400
|
-
...validateNavTargets(
|
|
2426
|
+
...validateNavTargets(
|
|
2427
|
+
project.graph.navigation,
|
|
2428
|
+
navTargetRoutes(project, pages)
|
|
2429
|
+
),
|
|
2401
2430
|
...validateSearchPopularIcons(config.search.popular),
|
|
2402
2431
|
].map(diagnosticWarning)
|
|
2403
2432
|
);
|
|
@@ -2414,6 +2443,12 @@ export const generateRuntime = async (
|
|
|
2414
2443
|
knownComponentTags,
|
|
2415
2444
|
new Set(registry.map((item) => item.name))
|
|
2416
2445
|
).map(diagnosticWarning),
|
|
2446
|
+
...missingExampleDiagnostics(
|
|
2447
|
+
project.graph.pages,
|
|
2448
|
+
exampleDiscovery,
|
|
2449
|
+
context.root,
|
|
2450
|
+
knownComponentTags
|
|
2451
|
+
).map(diagnosticWarning),
|
|
2417
2452
|
...dependencyWarnings
|
|
2418
2453
|
);
|
|
2419
2454
|
if (hasScalarReferences(config)) {
|
package/src/astro/integration.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { join, relative, resolve } from "pathe";
|
|
|
7
7
|
import { loadEnvFiles } from "../cli/env.ts";
|
|
8
8
|
import type { CustomPageRoute } from "../core/custom-pages.ts";
|
|
9
9
|
import { enrichDiagnostic } from "../core/diagnostics.ts";
|
|
10
|
+
import { POWERED_BY_HEADERS } from "../core/powered-by.ts";
|
|
10
11
|
import { scanProject } from "../core/project-graph.ts";
|
|
11
12
|
import type { BlumeProject } from "../core/project-graph.ts";
|
|
12
13
|
import {
|
|
@@ -146,23 +147,33 @@ export const publishBuildProject = (project: BlumeProject | null): void => {
|
|
|
146
147
|
* the Astro root recorded on `astro:config:done`. Scan diagnostics surface as
|
|
147
148
|
* warnings — there is no `--strict` to honor here, and the build itself has
|
|
148
149
|
* already succeeded. `null` when nothing asked for a scan.
|
|
150
|
+
*
|
|
151
|
+
* The app's runtime settings were baked in at eject, `poweredBy` among them
|
|
152
|
+
* (the integration option that registers the runtime middleware), so the
|
|
153
|
+
* artifacts follow that option rather than the config file: one switch puts
|
|
154
|
+
* `X-Powered-By` on the server-rendered responses and in `_headers` alike.
|
|
149
155
|
*/
|
|
150
156
|
const scanForArtifacts = async (
|
|
151
157
|
astroRoot: URL | null,
|
|
152
|
-
|
|
158
|
+
options: Pick<BlumeIntegrationOptions, "buildArtifactsRoot" | "poweredBy">,
|
|
153
159
|
logger: ArtifactLogger
|
|
154
160
|
): Promise<BlumeProject | null> => {
|
|
155
|
-
if (!(astroRoot &&
|
|
161
|
+
if (!(astroRoot && options.buildArtifactsRoot)) {
|
|
156
162
|
return null;
|
|
157
163
|
}
|
|
158
|
-
const root = resolve(fileURLToPath(astroRoot),
|
|
164
|
+
const root = resolve(fileURLToPath(astroRoot), options.buildArtifactsRoot);
|
|
159
165
|
// Remote sources read their tokens from the environment during the scan.
|
|
160
166
|
loadEnvFiles(root);
|
|
161
167
|
const project = await scanProject(root, { mode: "build" });
|
|
162
168
|
for (const diagnostic of project.diagnostics) {
|
|
163
169
|
logger.warn(`[${diagnostic.code}] ${diagnostic.message}`);
|
|
164
170
|
}
|
|
165
|
-
return
|
|
171
|
+
return options.poweredBy === undefined
|
|
172
|
+
? project
|
|
173
|
+
: {
|
|
174
|
+
...project,
|
|
175
|
+
config: { ...project.config, poweredBy: options.poweredBy },
|
|
176
|
+
};
|
|
166
177
|
};
|
|
167
178
|
|
|
168
179
|
/**
|
|
@@ -317,6 +328,12 @@ export type BlumePageRoute = CustomPageRoute;
|
|
|
317
328
|
|
|
318
329
|
export interface BlumeIntegrationOptions {
|
|
319
330
|
pages: BlumePageRoute[];
|
|
331
|
+
/**
|
|
332
|
+
* Whether responses name Blume in `X-Powered-By` (see
|
|
333
|
+
* `core/powered-by.ts`): the dev server's, and the server-rendered ones of
|
|
334
|
+
* a build, through the runtime middleware. Defaults to `true`.
|
|
335
|
+
*/
|
|
336
|
+
poweredBy?: boolean;
|
|
320
337
|
/**
|
|
321
338
|
* Page routes that have a raw-Markdown variant (the content manifest). The
|
|
322
339
|
* hidden runtime leaves this out: the CLI publishes the live set through
|
|
@@ -342,10 +359,11 @@ export interface BlumeIntegrationOptions {
|
|
|
342
359
|
*/
|
|
343
360
|
buildArtifactsRoot?: string;
|
|
344
361
|
/**
|
|
345
|
-
*
|
|
346
|
-
*
|
|
347
|
-
* carry only the exact ones, since it can't
|
|
348
|
-
*
|
|
362
|
+
* Every configured redirect, compiled against base-less request paths
|
|
363
|
+
* (see `compileEveryRedirect`), for the dev server to answer itself.
|
|
364
|
+
* Astro's own `redirects` carry only the exact ones, since it can't
|
|
365
|
+
* prerender a pattern's pages, and its dev handler answers one whose
|
|
366
|
+
* destination `[...slug]` serves with a `301` whatever its status.
|
|
349
367
|
*/
|
|
350
368
|
redirects?: CompiledRedirect[];
|
|
351
369
|
}
|
|
@@ -398,10 +416,12 @@ const negotiateMarkdown =
|
|
|
398
416
|
if (homeLinkHeader && isHomeUrl(req.url)) {
|
|
399
417
|
res.setHeader("Link", homeLinkHeader);
|
|
400
418
|
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
419
|
+
const variant = markdownVariantUrl(req.url, contentRoutes);
|
|
420
|
+
if (variant) {
|
|
421
|
+
// Both answers at a negotiated URL depend on `Accept`, the HTML one
|
|
422
|
+
// too, so a cache never hands one client's variant to the other.
|
|
423
|
+
res.setHeader("Vary", "Accept");
|
|
424
|
+
if (prefersMarkdown(req.headers.accept)) {
|
|
405
425
|
req.url = variant;
|
|
406
426
|
}
|
|
407
427
|
}
|
|
@@ -410,11 +430,11 @@ const negotiateMarkdown =
|
|
|
410
430
|
};
|
|
411
431
|
|
|
412
432
|
/**
|
|
413
|
-
* Answer a
|
|
414
|
-
*
|
|
415
|
-
* {@link negotiateMarkdown}), and the
|
|
433
|
+
* Answer a configured redirect in dev with its status, the way the server
|
|
434
|
+
* wrappers do in a build. Request URLs arrive base-less (see
|
|
435
|
+
* {@link negotiateMarkdown}), and the redirects were based to match.
|
|
416
436
|
*/
|
|
417
|
-
const
|
|
437
|
+
const answerRedirects =
|
|
418
438
|
(redirects: readonly CompiledRedirect[]) =>
|
|
419
439
|
(req: IncomingMessage, res: ServerResponse, next: () => void): void => {
|
|
420
440
|
const answer = matchCompiledRedirect(redirects, requestPath(req.url ?? ""));
|
|
@@ -426,6 +446,24 @@ const answerPatternRedirects =
|
|
|
426
446
|
res.end();
|
|
427
447
|
};
|
|
428
448
|
|
|
449
|
+
/**
|
|
450
|
+
* Name Blume in `X-Powered-By` on every dev response, as the deployed site
|
|
451
|
+
* does. It goes on the Node response before anything answers, so the
|
|
452
|
+
* redirects, the `public/` files Vite serves, and the rendered pages all
|
|
453
|
+
* carry it, and a page or project middleware that sets its own value
|
|
454
|
+
* replaces it.
|
|
455
|
+
*/
|
|
456
|
+
const identifyBlume = (
|
|
457
|
+
_req: IncomingMessage,
|
|
458
|
+
res: ServerResponse,
|
|
459
|
+
next: () => void
|
|
460
|
+
): void => {
|
|
461
|
+
for (const [name, value] of Object.entries(POWERED_BY_HEADERS)) {
|
|
462
|
+
res.setHeader(name, value);
|
|
463
|
+
}
|
|
464
|
+
next();
|
|
465
|
+
};
|
|
466
|
+
|
|
429
467
|
/** The `.d.ts` the integration injects for the `blume:*` virtual modules. */
|
|
430
468
|
const MODULE_TYPES_FILE = "modules.d.ts";
|
|
431
469
|
|
|
@@ -459,11 +497,7 @@ export const blumeIntegration = (
|
|
|
459
497
|
"astro:build:done": async ({ dir, logger }) => {
|
|
460
498
|
const project =
|
|
461
499
|
registry().buildProject ??
|
|
462
|
-
(await scanForArtifacts(
|
|
463
|
-
astroRoot,
|
|
464
|
-
options.buildArtifactsRoot,
|
|
465
|
-
logger
|
|
466
|
-
));
|
|
500
|
+
(await scanForArtifacts(astroRoot, options, logger));
|
|
467
501
|
if (!project) {
|
|
468
502
|
return;
|
|
469
503
|
}
|
|
@@ -502,6 +536,15 @@ export const blumeIntegration = (
|
|
|
502
536
|
entrypoint: "blume/components/icon-sprite-middleware.ts",
|
|
503
537
|
order: "post",
|
|
504
538
|
});
|
|
539
|
+
// Names Blume on the responses Astro renders (see
|
|
540
|
+
// components/powered-by-middleware.ts). Innermost too, so a header
|
|
541
|
+
// the project's own middleware sets wins.
|
|
542
|
+
if (options.poweredBy !== false) {
|
|
543
|
+
addMiddleware({
|
|
544
|
+
entrypoint: "blume/components/powered-by-middleware.ts",
|
|
545
|
+
order: "post",
|
|
546
|
+
});
|
|
547
|
+
}
|
|
505
548
|
for (const page of options.pages) {
|
|
506
549
|
injectRoute({
|
|
507
550
|
entrypoint: page.entrypoint,
|
|
@@ -533,7 +576,14 @@ export const blumeIntegration = (
|
|
|
533
576
|
});
|
|
534
577
|
if (options.redirects) {
|
|
535
578
|
server.middlewares.stack.unshift({
|
|
536
|
-
handle:
|
|
579
|
+
handle: answerRedirects(options.redirects),
|
|
580
|
+
route: "",
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
// Ahead of the redirects, so their answers carry it too.
|
|
584
|
+
if (options.poweredBy !== false) {
|
|
585
|
+
server.middlewares.stack.unshift({
|
|
586
|
+
handle: identifyBlume,
|
|
537
587
|
route: "",
|
|
538
588
|
});
|
|
539
589
|
}
|
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
* helpers (`deploy/cloudflare-negotiation.ts` — its deploy bundle is uploaded
|
|
9
9
|
* unbundled, so it cannot import this module); when editing here, mirror the
|
|
10
10
|
* change there. Parity is enforced by `test/cloudflare-negotiation.test.ts`.
|
|
11
|
+
* Vercel's routing conditions (`deploy/vercel-negotiation.ts`) spell the same
|
|
12
|
+
* rule as regexes, checked against {@link prefersMarkdown} by
|
|
13
|
+
* `test/vercel-negotiation.test.ts`.
|
|
11
14
|
*/
|
|
12
15
|
|
|
13
16
|
interface AcceptEntry {
|
|
@@ -82,7 +82,9 @@ declare module "blume:consent-client" {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
declare module "blume:search-client" {
|
|
85
|
-
export const createSearch: (
|
|
85
|
+
export const createSearch: (
|
|
86
|
+
options?: import("blume/components/layout/search/types.ts").SearchClientOptions
|
|
87
|
+
) =>
|
|
86
88
|
| import("blume/components/layout/search/types.ts").SearchFn
|
|
87
89
|
| Promise<import("blume/components/layout/search/types.ts").SearchFn>;
|
|
88
90
|
}
|
package/src/astro/pages.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
} from "../core/changelog-index.ts";
|
|
5
5
|
import { staticSegments } from "../core/custom-pages.ts";
|
|
6
6
|
import type { BlumeProject } from "../core/project-graph.ts";
|
|
7
|
+
import { referenceRoutes } from "../openapi/references.ts";
|
|
7
8
|
import type { BlumePageRoute } from "./integration.ts";
|
|
8
9
|
|
|
9
10
|
export {
|
|
@@ -48,6 +49,28 @@ export const hasGeneratedChangelog = (
|
|
|
48
49
|
hasChangelogIndex(project.graph.pages, project.config) &&
|
|
49
50
|
!routeIsTaken(userPages, project.graph.pages, CHANGELOG_INDEX_ROUTE);
|
|
50
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Every route a navigation entry (a tab, selector item, featured link, header
|
|
54
|
+
* action, or CTA) may point at: content routes, custom `.astro` pages, the
|
|
55
|
+
* generated changelog, and reference routes (so a tab an author points at one
|
|
56
|
+
* still validates). `generateRuntime` and `blume doctor` both check
|
|
57
|
+
* `validateNavTargets` against it, so they flag the same entries.
|
|
58
|
+
*/
|
|
59
|
+
export const navTargetRoutes = (
|
|
60
|
+
project: BlumeProject,
|
|
61
|
+
userPages: { pattern: string }[]
|
|
62
|
+
): Set<string> => {
|
|
63
|
+
const routes = new Set<string>([
|
|
64
|
+
...project.graph.routes.keys(),
|
|
65
|
+
...userPages.map((page) => page.pattern),
|
|
66
|
+
...referenceRoutes(project.config),
|
|
67
|
+
]);
|
|
68
|
+
if (hasGeneratedChangelog(project, userPages)) {
|
|
69
|
+
routes.add(CHANGELOG_INDEX_ROUTE);
|
|
70
|
+
}
|
|
71
|
+
return routes;
|
|
72
|
+
};
|
|
73
|
+
|
|
51
74
|
const humanizeSegment = (segment: string): string =>
|
|
52
75
|
segment
|
|
53
76
|
.split(/[-_]/u)
|
package/src/astro/render-deps.ts
CHANGED
|
@@ -369,11 +369,16 @@ export const prerenderDepsPlugin = (
|
|
|
369
369
|
if (!dir || !serverSide) {
|
|
370
370
|
return;
|
|
371
371
|
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
)
|
|
372
|
+
const packages = imported.get(environment ?? "");
|
|
373
|
+
// A bundle that leaves no package import external loads nothing from
|
|
374
|
+
// `node_modules` at runtime, so it gets none. The Cloudflare adapter
|
|
375
|
+
// bundles the Worker whole, and a copy of its output that follows the
|
|
376
|
+
// links (a CI artifact) would otherwise upload every one of Blume's
|
|
377
|
+
// dependencies as a Worker module.
|
|
378
|
+
if (environment !== undefined && !packages?.size) {
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
await linkRenderDeps(dir, packages ?? new Map<string, string>(), pkgDir);
|
|
377
382
|
},
|
|
378
383
|
};
|
|
379
384
|
};
|
|
@@ -103,6 +103,25 @@ export const assistantProviderDependencies = (
|
|
|
103
103
|
)
|
|
104
104
|
: [];
|
|
105
105
|
|
|
106
|
+
/**
|
|
107
|
+
* The narration provider's SDK, when missing: `openai()` speaks through
|
|
108
|
+
* `@ai-sdk/openai`, which the build loads to generate the clips, while
|
|
109
|
+
* `gateway()` needs nothing beyond the core `ai` package Blume ships.
|
|
110
|
+
*/
|
|
111
|
+
export const narrationProviderDependencies = (
|
|
112
|
+
narration: ResolvedConfig["narration"],
|
|
113
|
+
root: string,
|
|
114
|
+
pkgDir: string = packageRoot()
|
|
115
|
+
): MissingDependency[] =>
|
|
116
|
+
narration.enabled && narration.provider
|
|
117
|
+
? unresolved(
|
|
118
|
+
`Narration provider "${narration.provider.kind}"`,
|
|
119
|
+
narration.provider.runtimeDeps,
|
|
120
|
+
root,
|
|
121
|
+
pkgDir
|
|
122
|
+
)
|
|
123
|
+
: [];
|
|
124
|
+
|
|
106
125
|
/**
|
|
107
126
|
* The deployment adapter's package, when missing. Node and Vercel ship with
|
|
108
127
|
* Blume, so theirs always resolve; Netlify and Cloudflare are optional peers.
|
|
@@ -152,8 +171,9 @@ export const islandFrameworkDependencies = (
|
|
|
152
171
|
/**
|
|
153
172
|
* Every package the resolved config's adapters (and the given island
|
|
154
173
|
* frameworks) import that isn't installed: the search SDK, content source
|
|
155
|
-
* SDKs, the assistant provider
|
|
156
|
-
* integrations. The adapters' `runtimeDeps` are the one place that
|
|
174
|
+
* SDKs, the assistant and narration provider SDKs, the deployment adapter,
|
|
175
|
+
* and island integrations. The adapters' `runtimeDeps` are the one place that
|
|
176
|
+
* knows.
|
|
157
177
|
*/
|
|
158
178
|
export const missingRuntimeDependencies = (
|
|
159
179
|
config: ResolvedConfig,
|
|
@@ -164,6 +184,7 @@ export const missingRuntimeDependencies = (
|
|
|
164
184
|
...searchProviderDependencies(config.search.provider, root, pkgDir),
|
|
165
185
|
...sourceAdapterDependencies(config.content.sources, root, pkgDir),
|
|
166
186
|
...assistantProviderDependencies(config.ai.assistant, root, pkgDir),
|
|
187
|
+
...narrationProviderDependencies(config.narration, root, pkgDir),
|
|
167
188
|
...deploymentAdapterDependencies(config.deployment, root, pkgDir),
|
|
168
189
|
...islandFrameworkDependencies(frameworks, root),
|
|
169
190
|
];
|