blume 1.7.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +19 -0
- package/CHANGELOG.md +227 -0
- package/README.md +34 -21
- package/dist/cli/chunk-11j0384y.js +148 -0
- package/dist/cli/chunk-11j0384y.js.map +10 -0
- package/dist/cli/{chunk-xhtpx3ff.js → chunk-1w8dp3qb.js} +17 -16
- package/dist/cli/{chunk-xhtpx3ff.js.map → chunk-1w8dp3qb.js.map} +3 -3
- package/dist/cli/chunk-2q1dwty4.js +75 -0
- package/dist/cli/chunk-2q1dwty4.js.map +11 -0
- package/dist/cli/chunk-41za066z.js +122 -0
- package/dist/cli/chunk-41za066z.js.map +11 -0
- package/dist/cli/chunk-5a2z0198.js +133 -0
- package/dist/cli/chunk-5a2z0198.js.map +10 -0
- package/dist/cli/{chunk-9he6crym.js → chunk-6k8vp3ta.js} +25 -13
- package/dist/cli/{chunk-9he6crym.js.map → chunk-6k8vp3ta.js.map} +4 -4
- package/dist/cli/{chunk-mt76t7dj.js → chunk-79njf86q.js} +133 -54
- package/dist/cli/chunk-79njf86q.js.map +11 -0
- package/dist/cli/{chunk-3w7b2vcx.js → chunk-7ez8ny0t.js} +2 -2
- package/dist/cli/{chunk-688e0dde.js → chunk-88cpgt6h.js} +1 -1
- package/dist/cli/chunk-a9kptbw5.js +361 -0
- package/dist/cli/chunk-a9kptbw5.js.map +14 -0
- package/dist/cli/chunk-abh8yjkn.js +31 -0
- package/dist/cli/chunk-abh8yjkn.js.map +10 -0
- package/dist/cli/chunk-b5aj94ah.js +91 -0
- package/dist/cli/chunk-b5aj94ah.js.map +10 -0
- package/dist/cli/{chunk-hs3gbh8p.js → chunk-bctazmbk.js} +9 -5
- package/dist/cli/chunk-bctazmbk.js.map +10 -0
- package/dist/cli/chunk-beat36xx.js +279 -0
- package/dist/cli/chunk-beat36xx.js.map +10 -0
- package/dist/cli/chunk-bnbmcwfb.js +145 -0
- package/dist/cli/chunk-bnbmcwfb.js.map +11 -0
- package/dist/cli/{chunk-9bkjd11x.js → chunk-bw22s759.js} +15 -5
- package/dist/cli/{chunk-9bkjd11x.js.map → chunk-bw22s759.js.map} +4 -4
- package/dist/cli/chunk-by2290sx.js +39 -0
- package/dist/cli/chunk-by2290sx.js.map +10 -0
- package/dist/cli/chunk-d1tadaw7.js +79 -0
- package/dist/cli/chunk-d1tadaw7.js.map +10 -0
- package/dist/cli/{chunk-t3tj0dgr.js → chunk-d80hr03s.js} +24 -19
- package/dist/cli/chunk-d80hr03s.js.map +15 -0
- package/dist/cli/chunk-ernrthtr.js +97 -0
- package/dist/cli/chunk-ernrthtr.js.map +10 -0
- package/dist/cli/chunk-f2972sbt.js +374 -0
- package/dist/cli/chunk-f2972sbt.js.map +10 -0
- package/dist/cli/{chunk-exeeb35e.js → chunk-f7t03s3g.js} +2 -2
- package/dist/cli/{chunk-2z47ypj8.js → chunk-fa25z98p.js} +16 -3
- package/dist/cli/chunk-fa25z98p.js.map +11 -0
- package/dist/cli/{chunk-12dxjqk7.js → chunk-fh5hj5jt.js} +44 -21
- package/dist/cli/chunk-fh5hj5jt.js.map +10 -0
- package/dist/cli/{chunk-8cd8tj54.js → chunk-j8mw0za6.js} +86 -57
- package/dist/cli/chunk-j8mw0za6.js.map +35 -0
- package/dist/cli/chunk-jts8mvcz.js +106 -0
- package/dist/cli/{chunk-2mzebbbz.js.map → chunk-jts8mvcz.js.map} +6 -4
- package/dist/cli/{chunk-ejjx8znq.js → chunk-mnqj32sj.js} +505 -536
- package/dist/cli/chunk-mnqj32sj.js.map +12 -0
- package/dist/cli/{chunk-196vjxp9.js → chunk-mwt1k8n7.js} +100 -372
- package/dist/cli/chunk-mwt1k8n7.js.map +10 -0
- package/dist/cli/chunk-nk3ts2xk.js +51 -0
- package/dist/cli/chunk-nk3ts2xk.js.map +10 -0
- package/dist/cli/{chunk-n9sra6sy.js → chunk-pat2zzwc.js} +10 -14
- package/dist/cli/{chunk-n9sra6sy.js.map → chunk-pat2zzwc.js.map} +2 -2
- package/dist/cli/chunk-pnnvybbk.js +176 -0
- package/dist/cli/chunk-pnnvybbk.js.map +11 -0
- package/dist/cli/{chunk-cvky9gb2.js → chunk-sqn5t4q0.js} +81 -87
- package/dist/cli/chunk-sqn5t4q0.js.map +10 -0
- package/dist/cli/{chunk-eevwt1sc.js → chunk-tzne8qfq.js} +15 -15
- package/dist/cli/{chunk-eevwt1sc.js.map → chunk-tzne8qfq.js.map} +1 -1
- package/dist/cli/chunk-xaz13gwg.js +12449 -0
- package/dist/cli/chunk-xaz13gwg.js.map +182 -0
- package/dist/cli/chunk-y3e45rc8.js +102 -0
- package/dist/cli/chunk-y3e45rc8.js.map +10 -0
- package/dist/cli/chunk-z01ze5c1.js +261 -0
- package/dist/cli/chunk-z01ze5c1.js.map +10 -0
- package/dist/cli/{chunk-5n7t497w.js → chunk-z1f5arsg.js} +247 -755
- package/dist/cli/chunk-z1f5arsg.js.map +36 -0
- package/dist/cli/{chunk-hdm2dkd2.js → chunk-zg2gtj10.js} +1086 -2596
- package/dist/cli/chunk-zg2gtj10.js.map +35 -0
- package/dist/cli/{chunk-ppfvdcd4.js → chunk-zxccj738.js} +1 -1
- package/dist/cli/index.js +214 -57
- package/dist/cli/index.js.map +8 -7
- package/dist/types/ai/agent-readability.d.ts +52 -0
- package/dist/types/ai/ai-catalog.d.ts +42 -0
- package/dist/types/ai/api/paths.d.ts +17 -0
- package/dist/types/ai/api-catalog.d.ts +18 -0
- package/dist/types/ai/ask.d.ts +368 -0
- package/dist/types/ai/changelog-markdown.d.ts +2 -0
- package/dist/types/ai/component-markdown.d.ts +2 -2
- package/dist/types/ai/index.d.ts +24 -0
- package/dist/types/ai/link-headers.d.ts +24 -0
- package/dist/types/ai/llms.d.ts +25 -0
- package/dist/types/ai/markdown.d.ts +45 -0
- package/dist/types/ai/mcp/discovery.d.ts +68 -0
- package/dist/types/ai/mcp/tools.d.ts +16 -0
- package/dist/types/ai/openapi-components.d.ts +43 -0
- package/dist/types/ai/relative-links.d.ts +26 -0
- package/dist/types/ai/serializers.d.ts +15 -0
- package/dist/types/ai/skills.d.ts +42 -0
- package/dist/types/ai/tar.d.ts +25 -0
- package/dist/types/ai/visibility.d.ts +17 -0
- package/dist/types/ai/web-bot-auth.d.ts +16 -0
- package/dist/types/analytics/adobe.d.ts +35 -0
- package/dist/types/analytics/amplitude.d.ts +50 -0
- package/dist/types/analytics/clarity.d.ts +31 -0
- package/dist/types/analytics/clearbit.d.ts +29 -0
- package/dist/types/analytics/cloudflare.d.ts +41 -0
- package/dist/types/analytics/fathom.d.ts +41 -0
- package/dist/types/analytics/google-analytics.d.ts +44 -0
- package/dist/types/analytics/google-tag-manager.d.ts +40 -0
- package/dist/types/analytics/head.d.ts +30 -0
- package/dist/types/analytics/heap.d.ts +40 -0
- package/dist/types/analytics/hightouch.d.ts +44 -0
- package/dist/types/analytics/hotjar.d.ts +33 -0
- package/dist/types/analytics/index.d.ts +61 -0
- package/dist/types/analytics/inline.d.ts +17 -0
- package/dist/types/analytics/logrocket.d.ts +44 -0
- package/dist/types/analytics/mixpanel.d.ts +67 -0
- package/dist/types/analytics/pirsch.d.ts +42 -0
- package/dist/types/analytics/plausible.d.ts +56 -0
- package/dist/types/analytics/posthog.d.ts +45 -0
- package/dist/types/analytics/schema.d.ts +320 -0
- package/dist/types/analytics/script.d.ts +46 -0
- package/dist/types/analytics/segment.d.ts +50 -0
- package/dist/types/analytics/vercel.d.ts +48 -0
- package/dist/types/astro/integration.d.ts +76 -0
- package/dist/types/astro/markdown-negotiation.d.ts +23 -0
- package/dist/types/astro/module-types.d.ts +14 -0
- package/dist/types/astro/pages.d.ts +44 -0
- package/dist/types/cli/env.d.ts +12 -0
- package/dist/types/cli/init/scaffold.d.ts +154 -0
- package/dist/types/components/layout/nav-utils.d.ts +11 -0
- package/dist/types/core/adapter.d.ts +47 -0
- package/dist/types/core/api-name.d.ts +7 -0
- package/dist/types/core/changelog-index.d.ts +13 -0
- package/dist/types/core/config-input.d.ts +209 -505
- package/dist/types/core/config.d.ts +60 -34
- package/dist/types/core/content-assets.d.ts +76 -0
- package/dist/types/core/custom-pages.d.ts +33 -0
- package/dist/types/core/data.d.ts +28 -11
- package/dist/types/core/define-components.d.ts +12 -9
- package/dist/types/core/deployment-env.d.ts +6 -11
- package/dist/types/core/frontmatter.d.ts +10 -0
- package/dist/types/core/graph.d.ts +18 -0
- package/dist/types/core/heading-markers.d.ts +54 -0
- package/dist/types/core/i18n-ui.d.ts +6 -2
- package/dist/types/core/i18n.d.ts +87 -0
- package/dist/types/core/includes.d.ts +138 -0
- package/dist/types/core/last-modified.d.ts +47 -0
- package/dist/types/core/links.d.ts +95 -0
- package/dist/types/core/locale-links.d.ts +60 -0
- package/dist/types/core/manifest.d.ts +17 -0
- package/dist/types/core/meta.d.ts +38 -0
- package/dist/types/core/nav-diagnostics.d.ts +26 -0
- package/dist/types/core/navigation.d.ts +6 -0
- package/dist/types/core/node-require.d.ts +19 -0
- package/dist/types/core/package-json.d.ts +13 -0
- package/dist/types/core/probe.d.ts +42 -0
- package/dist/types/core/project-graph.d.ts +51 -0
- package/dist/types/core/project.d.ts +2 -0
- package/dist/types/core/safe-href.d.ts +2 -0
- package/dist/types/core/safe-links.d.ts +26 -0
- package/dist/types/core/schema.d.ts +2291 -441
- package/dist/types/core/site-url.d.ts +16 -0
- package/dist/types/core/sources/assets.d.ts +36 -0
- package/dist/types/core/sources/cache.d.ts +37 -0
- package/dist/types/core/sources/collection.d.ts +28 -0
- package/dist/types/core/sources/contentful-rich-text.d.ts +31 -0
- package/dist/types/core/sources/contentful.d.ts +40 -0
- package/dist/types/core/sources/filesystem.d.ts +24 -0
- package/dist/types/core/sources/github-releases.d.ts +31 -0
- package/dist/types/core/sources/json.d.ts +30 -0
- package/dist/types/core/sources/lexical.d.ts +19 -0
- package/dist/types/core/sources/lower.d.ts +75 -0
- package/dist/types/core/sources/mdx-remote.d.ts +28 -0
- package/dist/types/core/sources/normalize.d.ts +147 -0
- package/dist/types/core/sources/notion.d.ts +131 -0
- package/dist/types/core/sources/obsidian.d.ts +46 -0
- package/dist/types/core/sources/payload.d.ts +39 -0
- package/dist/types/core/sources/portable-text.d.ts +42 -0
- package/dist/types/core/sources/read.d.ts +23 -0
- package/dist/types/core/sources/remote.d.ts +74 -0
- package/dist/types/core/sources/resolve.d.ts +19 -0
- package/dist/types/core/sources/sanity.d.ts +43 -0
- package/dist/types/core/sources/strapi-blocks.d.ts +12 -0
- package/dist/types/core/sources/strapi.d.ts +33 -0
- package/dist/types/core/sources/types.d.ts +7 -0
- package/dist/types/core/sources/watch.d.ts +45 -0
- package/dist/types/core/text-width.d.ts +11 -0
- package/dist/types/core/types.d.ts +20 -1
- package/dist/types/core/unrecognized-keys.d.ts +7 -0
- package/dist/types/core/versions.d.ts +72 -0
- package/dist/types/core/yaml.d.ts +9 -0
- package/dist/types/deploy/adapter-output.d.ts +45 -0
- package/dist/types/deploy/adapters/cloudflare.d.ts +40 -0
- package/dist/types/deploy/adapters/index.d.ts +29 -0
- package/dist/types/deploy/adapters/netlify.d.ts +37 -0
- package/dist/types/deploy/adapters/node.d.ts +37 -0
- package/dist/types/deploy/adapters/registry.d.ts +133 -0
- package/dist/types/deploy/adapters/types.d.ts +71 -0
- package/dist/types/deploy/adapters/vercel.d.ts +38 -0
- package/dist/types/deploy/artifacts.d.ts +65 -0
- package/dist/types/deploy/cloudflare-negotiation.d.ts +196 -0
- package/dist/types/deploy/function-bundle.d.ts +80 -0
- package/dist/types/deploy/headers.d.ts +50 -0
- package/dist/types/deploy/node-headers.d.ts +42 -0
- package/dist/types/deploy/platforms/cloudflare.d.ts +40 -0
- package/dist/types/deploy/platforms/index.d.ts +18 -0
- package/dist/types/deploy/platforms/netlify.d.ts +13 -0
- package/dist/types/deploy/platforms/node.d.ts +11 -0
- package/dist/types/deploy/platforms/paths.d.ts +27 -0
- package/dist/types/deploy/platforms/static.d.ts +10 -0
- package/dist/types/deploy/platforms/types.d.ts +104 -0
- package/dist/types/deploy/platforms/vercel.d.ts +32 -0
- package/dist/types/deploy/redirects.d.ts +53 -0
- package/dist/types/deploy/robots.d.ts +8 -0
- package/dist/types/deploy/rss.d.ts +31 -0
- package/dist/types/deploy/sitemap.d.ts +21 -0
- package/dist/types/deploy/vercel-negotiation.d.ts +109 -0
- package/dist/types/markdown/code-title.d.ts +32 -0
- package/dist/types/markdown/fence-meta.d.ts +23 -0
- package/dist/types/markdown/themes.d.ts +3 -3
- package/dist/types/openapi/asyncapi.d.ts +129 -0
- package/dist/types/openapi/graphql-build.d.ts +8 -0
- package/dist/types/openapi/graphql.d.ts +122 -0
- package/dist/types/openapi/model.d.ts +158 -0
- package/dist/types/openapi/parse.d.ts +57 -0
- package/dist/types/openapi/references.d.ts +37 -25
- package/dist/types/openapi/render-mdx.d.ts +33 -0
- package/dist/types/openapi/sentence.d.ts +7 -0
- package/dist/types/openapi/signature.d.ts +10 -0
- package/dist/types/openapi/source.d.ts +22 -0
- package/dist/types/openapi/spec-dependency-error.d.ts +10 -0
- package/dist/types/reference/asyncapi.d.ts +166 -0
- package/dist/types/reference/graphql.d.ts +181 -0
- package/dist/types/reference/index.d.ts +32 -0
- package/dist/types/reference/openapi.d.ts +165 -0
- package/dist/types/reference/options.d.ts +157 -0
- package/dist/types/reference/scalar.d.ts +136 -0
- package/dist/types/reference/schema.d.ts +630 -0
- package/dist/types/search/adapters/algolia.d.ts +32 -0
- package/dist/types/search/adapters/flexsearch.d.ts +12 -0
- package/dist/types/search/adapters/index.d.ts +31 -0
- package/dist/types/search/adapters/mixedbread.d.ts +22 -0
- package/dist/types/search/adapters/orama-cloud.d.ts +33 -0
- package/dist/types/search/adapters/orama.d.ts +13 -0
- package/dist/types/search/adapters/pagefind.d.ts +12 -0
- package/dist/types/search/adapters/registry.d.ts +228 -0
- package/dist/types/search/adapters/types.d.ts +34 -0
- package/dist/types/search/adapters/typesense.d.ts +42 -0
- package/dist/types/search/build.d.ts +23 -0
- package/dist/types/search/documents.d.ts +90 -0
- package/dist/types/search/facets.d.ts +3 -0
- package/dist/types/search/sync/algolia.d.ts +14 -0
- package/dist/types/search/sync/index.d.ts +14 -0
- package/dist/types/search/sync/orama-cloud.d.ts +10 -0
- package/dist/types/search/sync/typesense.d.ts +14 -0
- package/dist/types/sources/contentful.d.ts +68 -0
- package/dist/types/sources/custom.d.ts +20 -0
- package/dist/types/sources/filesystem.d.ts +42 -0
- package/dist/types/sources/github-releases.d.ts +46 -0
- package/dist/types/sources/index.d.ts +48 -0
- package/dist/types/sources/mdx-remote.d.ts +63 -0
- package/dist/types/sources/notion.d.ts +65 -0
- package/dist/types/sources/obsidian.d.ts +34 -0
- package/dist/types/sources/payload.d.ts +68 -0
- package/dist/types/sources/registry.d.ts +1414 -0
- package/dist/types/sources/sanity.d.ts +69 -0
- package/dist/types/sources/shared.d.ts +46 -0
- package/dist/types/sources/strapi.d.ts +66 -0
- package/dist/types/theme/icon-kind.d.ts +11 -0
- package/dist/types/theme/icons.d.ts +20 -0
- package/docs/01-quickstart.mdx +18 -18
- package/docs/02-deployment.mdx +50 -26
- package/docs/03-upgrading.mdx +351 -0
- package/docs/04-migrating.mdx +58 -0
- package/docs/08-faq.mdx +3 -3
- package/docs/advanced/blog.mdx +13 -6
- package/docs/advanced/changelog.mdx +23 -35
- package/docs/advanced/custom-pages.mdx +20 -8
- package/docs/advanced/meta.ts +1 -8
- package/docs/advanced/skills.mdx +8 -0
- package/docs/cli/audit.mdx +646 -0
- package/docs/cli/doctor.mdx +29 -0
- package/docs/{reference/eval.mdx → cli/evals.mdx} +9 -8
- package/docs/cli/index.mdx +105 -0
- package/docs/cli/meta.ts +7 -0
- package/docs/{reference → cli}/translate.mdx +1 -1
- package/docs/cli/validate.mdx +41 -0
- package/docs/cli/version.mdx +40 -0
- package/docs/configuration/analytics.mdx +350 -59
- package/docs/configuration/ask-ai.mdx +176 -61
- package/docs/configuration/customization.mdx +15 -9
- package/docs/configuration/index.mdx +52 -31
- package/docs/configuration/search.mdx +75 -54
- package/docs/configuration/theming.mdx +24 -15
- package/docs/content/components.mdx +21 -5
- package/docs/{reference → content}/frontmatter.mdx +37 -1
- package/docs/content/i18n.mdx +8 -6
- package/docs/content/includes.mdx +2 -4
- package/docs/content/index.mdx +1 -1
- package/docs/content/islands.mdx +10 -5
- package/docs/content/meta.mdx +1 -1
- package/docs/content/meta.ts +1 -0
- package/docs/content/navigation.mdx +12 -7
- package/docs/content/sources.mdx +145 -50
- package/docs/content/syntax.mdx +26 -12
- package/docs/content/versioning.mdx +3 -3
- package/docs/discoverability/agent-discovery.mdx +91 -10
- package/docs/discoverability/index.mdx +5 -5
- package/docs/discoverability/json-api.mdx +4 -4
- package/docs/discoverability/llms-txt.mdx +6 -6
- package/docs/discoverability/markdown.mdx +4 -4
- package/docs/discoverability/mcp.mdx +11 -11
- package/docs/discoverability/sitemap-and-robots.mdx +3 -3
- package/docs/index.mdx +2 -2
- package/docs/references/asyncapi.mdx +59 -0
- package/docs/{advanced → references}/graphql.mdx +45 -32
- package/docs/{reference → references}/meta.ts +2 -2
- package/docs/references/openapi.mdx +171 -0
- package/docs/references/scalar.mdx +64 -0
- package/package.json +42 -8
- package/skills/blume/SKILL.md +21 -8
- package/skills/blume-migrate/SKILL.md +22 -21
- package/skills/blume-migrate/assets/oxfmt@0.67.0.patch +49 -0
- package/skills/blume-migrate/references/docusaurus.md +5 -4
- package/skills/blume-migrate/references/fumadocs.md +4 -4
- package/skills/blume-migrate/references/mintlify.md +23 -8
- package/skills/blume-migrate/references/monorepo.md +6 -6
- package/skills/blume-migrate/references/starlight.md +4 -4
- package/src/ai/agent-readability.ts +26 -22
- package/src/ai/ai-catalog.ts +259 -0
- package/src/ai/api/handlers.ts +46 -11
- package/src/ai/api-catalog.ts +8 -8
- package/src/ai/ask-data.ts +1 -1
- package/src/ai/ask.ts +624 -100
- package/src/ai/changelog-markdown.ts +91 -0
- package/src/ai/component-markdown.ts +328 -12
- package/src/ai/index.ts +45 -0
- package/src/ai/link-headers.ts +19 -6
- package/src/ai/llms.ts +26 -15
- package/src/ai/markdown.ts +35 -5
- package/src/ai/mcp/data.ts +9 -5
- package/src/ai/mcp/discovery.ts +1 -1
- package/src/ai/openapi-components.ts +4 -1
- package/src/ai/relative-links.ts +170 -0
- package/src/ai/serializers.ts +2 -2
- package/src/ai/skills.ts +1 -1
- package/src/ai/web-bot-auth.ts +2 -2
- package/src/analytics/adobe.ts +46 -0
- package/src/analytics/amplitude.ts +79 -0
- package/src/analytics/clarity.ts +46 -0
- package/src/analytics/clearbit.ts +47 -0
- package/src/analytics/cloudflare.ts +67 -0
- package/src/analytics/fathom.ts +64 -0
- package/src/analytics/google-analytics.ts +84 -0
- package/src/analytics/google-tag-manager.ts +61 -0
- package/src/analytics/head.ts +130 -0
- package/src/analytics/heap.ts +65 -0
- package/src/analytics/hightouch.ts +77 -0
- package/src/analytics/hotjar.ts +47 -0
- package/src/analytics/index.ts +71 -0
- package/src/analytics/inline.ts +21 -0
- package/src/analytics/logrocket.ts +71 -0
- package/src/analytics/mixpanel.ts +92 -0
- package/src/analytics/pirsch.ts +66 -0
- package/src/analytics/plausible.ts +83 -0
- package/src/analytics/posthog.ts +78 -0
- package/src/analytics/schema.ts +60 -0
- package/src/analytics/script.ts +60 -0
- package/src/analytics/segment.ts +85 -0
- package/src/analytics/vercel.ts +50 -0
- package/src/astro/adapter-root.ts +7 -9
- package/src/astro/component-slots.ts +131 -91
- package/src/astro/generate.ts +114 -345
- package/src/astro/integration.ts +2 -6
- package/src/astro/pages.ts +13 -101
- package/src/astro/render-deps.ts +379 -0
- package/src/astro/runtime-deps.ts +201 -0
- package/src/astro/templates.ts +554 -541
- package/src/audit/agent.ts +24 -0
- package/src/audit/catalog.ts +2 -2
- package/src/audit/checks/assets.ts +2 -2
- package/src/audit/checks/dns-aid.ts +1 -1
- package/src/audit/checks/duplicates.ts +3 -1
- package/src/audit/checks/i18n.ts +1 -1
- package/src/audit/checks/indexability.ts +7 -7
- package/src/audit/checks/links.ts +2 -2
- package/src/audit/checks/llms.ts +6 -6
- package/src/audit/checks/network.ts +3 -3
- package/src/audit/checks/og-image.ts +2 -2
- package/src/audit/checks/robots.ts +1 -1
- package/src/audit/checks/sitemap.ts +2 -2
- package/src/audit/checks/social.ts +1 -1
- package/src/audit/run.ts +4 -3
- package/src/audit/terms.ts +31 -0
- package/src/audit/url.ts +13 -13
- package/src/cli/command-meta.ts +10 -0
- package/src/cli/commands/audit.ts +39 -20
- package/src/cli/commands/build.ts +71 -314
- package/src/cli/commands/check.ts +1 -0
- package/src/cli/commands/dev.ts +40 -1
- package/src/cli/commands/doctor.ts +90 -14
- package/src/cli/commands/eject.ts +44 -7
- package/src/cli/commands/eval.ts +2 -2
- package/src/cli/commands/init.ts +161 -41
- package/src/cli/commands/migrate.ts +121 -0
- package/src/cli/commands/preview.ts +7 -1
- package/src/cli/commands/translate.ts +2 -2
- package/src/cli/commands/upgrade.ts +141 -0
- package/src/cli/commands/version.ts +57 -44
- package/src/cli/eject-scripts.ts +121 -6
- package/src/cli/index.ts +11 -1
- package/src/cli/init/install.ts +70 -0
- package/src/cli/init/questions.ts +7 -0
- package/src/cli/init/scaffold.ts +459 -75
- package/src/cli/lazy-command.ts +37 -1
- package/src/cli/prepare.ts +40 -6
- package/src/cli/required-secrets.ts +38 -11
- package/src/cli/unknown-flags.ts +266 -0
- package/src/cli/yarn-pnp.ts +52 -0
- package/src/components/content/AccordionItem.astro +7 -1
- package/src/components/content/Card.astro +4 -3
- package/src/components/content/ColorItem.astro +22 -4
- package/src/components/content/GithubInfo.astro +2 -2
- package/src/components/content/Prompt.astro +25 -25
- package/src/components/content/Tabs.astro +3 -1
- package/src/components/content/Tile.astro +2 -3
- package/src/components/content/Tooltip.astro +57 -9
- package/src/components/content/content-strings.ts +34 -0
- package/src/components/content/diff.ts +1 -1
- package/src/components/content/mermaid-element.ts +13 -2
- package/src/components/content/prompt-markdown.ts +292 -0
- package/src/components/content/tooltip-id.ts +41 -0
- package/src/components/islands/hooks.ts +75 -3
- package/src/components/layout/Analytics.astro +21 -79
- package/src/components/layout/Banner.astro +3 -1
- package/src/components/layout/DiscoveryLinks.astro +69 -0
- package/src/components/layout/Header.astro +83 -20
- package/src/components/layout/LanguageSwitcher.astro +4 -1
- package/src/components/layout/Logo.astro +23 -2
- package/src/components/layout/NavSelector.astro +13 -2
- package/src/components/layout/NavTree.astro +12 -3
- package/src/components/layout/NavTreeScript.astro +17 -3
- package/src/components/layout/PageActions.astro +3 -3
- package/src/components/layout/PageFeedback.astro +11 -1
- package/src/components/layout/PageLayout.astro +52 -5
- package/src/components/layout/ReferenceLayout.astro +21 -12
- package/src/components/layout/RootLayout.astro +69 -43
- package/src/components/layout/Search.astro +30 -6
- package/src/components/layout/WebMcp.astro +1 -1
- package/src/components/layout/analytics-client.ts +101 -15
- package/src/components/layout/drawer-inert.ts +113 -15
- package/src/components/layout/dropdown-clamp.ts +105 -0
- package/src/components/layout/head-scripts.ts +15 -6
- package/src/components/layout/nav-utils.ts +17 -0
- package/src/components/layout/search/algolia.ts +8 -8
- package/src/components/layout/search/orama-cloud.ts +9 -7
- package/src/components/layout/search/typesense.ts +11 -17
- package/src/components/openapi/MessageComposer.astro +2 -2
- package/src/components/openapi/Playground.astro +2 -2
- package/src/components/openapi/playground-client.ts +79 -10
- package/src/core/changelog-index.ts +24 -0
- package/src/core/component-overrides.ts +399 -154
- package/src/core/config-input.ts +212 -543
- package/src/core/config.ts +130 -41
- package/src/core/custom-pages.ts +105 -0
- package/src/core/data.ts +32 -11
- package/src/core/define-components.ts +12 -9
- package/src/core/deployment-env.ts +18 -74
- package/src/core/diagnostics.ts +14 -7
- package/src/core/graph.ts +69 -25
- package/src/core/i18n-ui.ts +6 -2
- package/src/core/i18n.ts +17 -0
- package/src/core/includes.ts +156 -38
- package/src/core/last-modified.ts +6 -11
- package/src/core/links.ts +166 -2
- package/src/core/manifest.ts +10 -3
- package/src/core/navigation.ts +137 -19
- package/src/core/new-tab.ts +35 -0
- package/src/core/node-require.ts +21 -0
- package/src/core/project-graph.ts +42 -26
- package/src/core/project.ts +9 -4
- package/src/core/request-body.ts +61 -0
- package/src/core/safe-href.ts +28 -0
- package/src/core/safe-links.ts +68 -0
- package/src/core/schema.ts +531 -721
- package/src/core/server-features.ts +8 -9
- package/src/core/sources/assets.ts +47 -11
- package/src/core/sources/collection.ts +67 -0
- package/src/core/sources/contentful-rich-text.ts +285 -0
- package/src/core/sources/contentful.ts +173 -0
- package/src/core/sources/github-releases.ts +51 -1
- package/src/core/sources/json.ts +71 -0
- package/src/core/sources/lexical.ts +195 -0
- package/src/core/sources/lower.ts +226 -0
- package/src/core/sources/normalize.ts +52 -2
- package/src/core/sources/notion.ts +39 -28
- package/src/core/sources/payload.ts +135 -0
- package/src/core/sources/portable-text.ts +11 -16
- package/src/core/sources/remote.ts +226 -0
- package/src/core/sources/resolve.ts +104 -166
- package/src/core/sources/sanity.ts +16 -49
- package/src/core/sources/strapi-blocks.ts +124 -0
- package/src/core/sources/strapi.ts +191 -0
- package/src/core/sources/types.ts +12 -1
- package/src/core/types.ts +20 -1
- package/src/core/ui-packs/ar.ts +6 -2
- package/src/core/ui-packs/bg.ts +6 -2
- package/src/core/ui-packs/bn.ts +6 -2
- package/src/core/ui-packs/ca.ts +3 -1
- package/src/core/ui-packs/cs.ts +6 -2
- package/src/core/ui-packs/da.ts +6 -2
- package/src/core/ui-packs/de.ts +6 -2
- package/src/core/ui-packs/el.ts +3 -1
- package/src/core/ui-packs/es.ts +3 -1
- package/src/core/ui-packs/fa.ts +6 -2
- package/src/core/ui-packs/fi.ts +6 -2
- package/src/core/ui-packs/fr.ts +3 -1
- package/src/core/ui-packs/he.ts +6 -2
- package/src/core/ui-packs/hi.ts +6 -2
- package/src/core/ui-packs/hr.ts +6 -2
- package/src/core/ui-packs/hu.ts +6 -2
- package/src/core/ui-packs/id.ts +6 -2
- package/src/core/ui-packs/it.ts +3 -1
- package/src/core/ui-packs/ja.ts +3 -1
- package/src/core/ui-packs/ko.ts +3 -1
- package/src/core/ui-packs/nl.ts +6 -2
- package/src/core/ui-packs/no.ts +6 -2
- package/src/core/ui-packs/pl.ts +6 -2
- package/src/core/ui-packs/pt-br.ts +3 -1
- package/src/core/ui-packs/pt.ts +3 -1
- package/src/core/ui-packs/ro.ts +6 -2
- package/src/core/ui-packs/ru.ts +6 -2
- package/src/core/ui-packs/sk.ts +6 -2
- package/src/core/ui-packs/sr.ts +6 -2
- package/src/core/ui-packs/sv.ts +6 -2
- package/src/core/ui-packs/th.ts +3 -1
- package/src/core/ui-packs/tr.ts +6 -2
- package/src/core/ui-packs/uk.ts +6 -2
- package/src/core/ui-packs/vi.ts +3 -1
- package/src/core/ui-packs/zh-tw.ts +3 -1
- package/src/core/ui-packs/zh.ts +3 -1
- package/src/core/unrecognized-keys.ts +10 -0
- package/src/core/version-cut.ts +116 -8
- package/src/deploy/adapter-output.ts +57 -97
- package/src/deploy/adapters/cloudflare.ts +39 -0
- package/src/deploy/adapters/index.ts +41 -0
- package/src/deploy/adapters/netlify.ts +34 -0
- package/src/deploy/adapters/node.ts +34 -0
- package/src/deploy/adapters/registry.ts +127 -0
- package/src/deploy/adapters/types.ts +92 -0
- package/src/deploy/adapters/vercel.ts +35 -0
- package/src/deploy/artifacts.ts +67 -28
- package/src/deploy/cloudflare-negotiation.ts +179 -100
- package/src/deploy/function-bundle.ts +18 -3
- package/src/deploy/headers.ts +129 -22
- package/src/deploy/node-headers.ts +198 -0
- package/src/deploy/platforms/cloudflare.ts +312 -0
- package/src/deploy/platforms/index.ts +67 -0
- package/src/deploy/platforms/netlify.ts +52 -0
- package/src/deploy/platforms/node.ts +40 -0
- package/src/deploy/platforms/paths.ts +42 -0
- package/src/deploy/platforms/static.ts +29 -0
- package/src/deploy/platforms/types.ts +112 -0
- package/src/deploy/platforms/vercel.ts +193 -0
- package/src/deploy/redirects.ts +30 -18
- package/src/deploy/robots.ts +3 -3
- package/src/deploy/rss.ts +2 -2
- package/src/deploy/sitemap.ts +2 -2
- package/src/deploy/vercel-negotiation.ts +27 -4
- package/src/eval/agents.ts +32 -1
- package/src/eval/findings.ts +19 -11
- package/src/eval/report.ts +10 -2
- package/src/markdown/external-links.ts +65 -0
- package/src/markdown/include.ts +45 -27
- package/src/markdown/index.ts +34 -9
- package/src/markdown/inline-code.ts +12 -6
- package/src/markdown/relative-links.ts +324 -0
- package/src/markdown/themes.ts +3 -3
- package/src/migrate/migrate.ts +149 -0
- package/src/openapi/parse.ts +64 -16
- package/src/openapi/proxy.ts +62 -10
- package/src/openapi/references.ts +147 -147
- package/src/openapi/render-mdx.ts +32 -10
- package/src/openapi/scalar.ts +15 -13
- package/src/openapi/sentence.ts +14 -0
- package/src/openapi/source.ts +37 -21
- package/src/openapi/spec-dependency-error.ts +15 -0
- package/src/reference/asyncapi.ts +83 -0
- package/src/reference/graphql.ts +89 -0
- package/src/reference/index.ts +40 -0
- package/src/reference/openapi.ts +83 -0
- package/src/reference/options.ts +201 -0
- package/src/reference/scalar.ts +136 -0
- package/src/reference/schema.ts +88 -0
- package/src/registry/eject.ts +97 -42
- package/src/search/adapters/algolia.ts +46 -0
- package/src/search/adapters/flexsearch.ts +29 -0
- package/src/search/adapters/index.ts +39 -0
- package/src/search/adapters/mixedbread.ts +39 -0
- package/src/search/adapters/orama-cloud.ts +51 -0
- package/src/search/adapters/orama.ts +24 -0
- package/src/search/adapters/pagefind.ts +27 -0
- package/src/search/adapters/registry.ts +131 -0
- package/src/search/adapters/types.ts +46 -0
- package/src/search/adapters/typesense.ts +57 -0
- package/src/search/build.ts +33 -7
- package/src/search/documents.ts +6 -0
- package/src/search/sync/algolia.ts +12 -11
- package/src/search/sync/index.ts +35 -20
- package/src/search/sync/orama-cloud.ts +12 -9
- package/src/search/sync/typesense.ts +15 -13
- package/src/sources/contentful.ts +63 -0
- package/src/sources/custom.ts +38 -0
- package/src/sources/filesystem.ts +51 -0
- package/src/sources/github-releases.ts +52 -0
- package/src/sources/index.ts +60 -0
- package/src/sources/mdx-remote.ts +76 -0
- package/src/sources/notion.ts +63 -0
- package/src/sources/obsidian.ts +38 -0
- package/src/sources/payload.ts +60 -0
- package/src/sources/registry.ts +182 -0
- package/src/sources/sanity.ts +66 -0
- package/src/sources/shared.ts +52 -0
- package/src/sources/strapi.ts +58 -0
- package/src/theme/entry.ts +47 -2
- package/src/translate/report.ts +40 -7
- package/src/upgrade/upgrade.ts +499 -0
- package/dist/cli/chunk-12dxjqk7.js.map +0 -10
- package/dist/cli/chunk-196vjxp9.js.map +0 -13
- package/dist/cli/chunk-2mzebbbz.js +0 -69
- package/dist/cli/chunk-2z47ypj8.js.map +0 -11
- package/dist/cli/chunk-30e87n55.js +0 -108
- package/dist/cli/chunk-30e87n55.js.map +0 -10
- package/dist/cli/chunk-450a7rcr.js +0 -185
- package/dist/cli/chunk-450a7rcr.js.map +0 -11
- package/dist/cli/chunk-5n7t497w.js.map +0 -40
- package/dist/cli/chunk-61j18dwk.js +0 -5342
- package/dist/cli/chunk-61j18dwk.js.map +0 -58
- package/dist/cli/chunk-88by27n5.js +0 -17
- package/dist/cli/chunk-88by27n5.js.map +0 -10
- package/dist/cli/chunk-8cd8tj54.js.map +0 -34
- package/dist/cli/chunk-aztttvb3.js +0 -381
- package/dist/cli/chunk-aztttvb3.js.map +0 -12
- package/dist/cli/chunk-cvky9gb2.js.map +0 -11
- package/dist/cli/chunk-ejjx8znq.js.map +0 -15
- package/dist/cli/chunk-fmceyezb.js +0 -1007
- package/dist/cli/chunk-fmceyezb.js.map +0 -13
- package/dist/cli/chunk-hdm2dkd2.js.map +0 -48
- package/dist/cli/chunk-hs3gbh8p.js.map +0 -10
- package/dist/cli/chunk-jbj4qhfw.js +0 -30
- package/dist/cli/chunk-jbj4qhfw.js.map +0 -10
- package/dist/cli/chunk-mqb2ka8m.js +0 -68
- package/dist/cli/chunk-mqb2ka8m.js.map +0 -10
- package/dist/cli/chunk-mt76t7dj.js.map +0 -11
- package/dist/cli/chunk-q4rae3bg.js +0 -60
- package/dist/cli/chunk-q4rae3bg.js.map +0 -10
- package/dist/cli/chunk-ra1v2nc2.js +0 -35
- package/dist/cli/chunk-ra1v2nc2.js.map +0 -10
- package/dist/cli/chunk-t3tj0dgr.js.map +0 -15
- package/dist/cli/chunk-tqa1s0k8.js +0 -69
- package/dist/cli/chunk-tqa1s0k8.js.map +0 -11
- package/dist/cli/chunk-vh9w1sgp.js +0 -73
- package/dist/cli/chunk-vh9w1sgp.js.map +0 -10
- package/dist/cli/chunk-vkrsvbr5.js +0 -107
- package/dist/cli/chunk-vkrsvbr5.js.map +0 -11
- package/dist/cli/chunk-vrfp10qk.js +0 -81
- package/dist/cli/chunk-vrfp10qk.js.map +0 -10
- package/dist/cli/chunk-wjt80jps.js +0 -1049
- package/dist/cli/chunk-wjt80jps.js.map +0 -24
- package/docs/advanced/api-reference.mdx +0 -240
- package/docs/reference/cli.mdx +0 -197
- package/skills/blume-migrate/assets/oxfmt@0.55.0.patch +0 -20
- package/src/components/content/changelog-element.ts +0 -69
- package/src/search/providers.ts +0 -91
- /package/dist/cli/{chunk-3w7b2vcx.js.map → chunk-7ez8ny0t.js.map} +0 -0
- /package/dist/cli/{chunk-688e0dde.js.map → chunk-88cpgt6h.js.map} +0 -0
- /package/dist/cli/{chunk-exeeb35e.js.map → chunk-f7t03s3g.js.map} +0 -0
- /package/dist/cli/{chunk-ppfvdcd4.js.map → chunk-zxccj738.js.map} +0 -0
package/src/deploy/artifacts.ts
CHANGED
|
@@ -4,6 +4,11 @@ import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
|
4
4
|
import { dirname, join, resolve } from "pathe";
|
|
5
5
|
|
|
6
6
|
import { buildAgentReadability } from "../ai/agent-readability.ts";
|
|
7
|
+
import {
|
|
8
|
+
AI_CATALOG_PATH,
|
|
9
|
+
ARD_MANIFEST_PATH,
|
|
10
|
+
buildAiCatalog,
|
|
11
|
+
} from "../ai/ai-catalog.ts";
|
|
7
12
|
import { API_CATALOG_PATH, buildApiCatalog } from "../ai/api-catalog.ts";
|
|
8
13
|
import { buildHomeLinkHeader } from "../ai/link-headers.ts";
|
|
9
14
|
import { buildLlmsFiles } from "../ai/llms.ts";
|
|
@@ -23,9 +28,10 @@ import type { ResolvedConfig } from "../core/schema.ts";
|
|
|
23
28
|
import { buildSearchIndex } from "../search/build.ts";
|
|
24
29
|
import { syncSearchProvider } from "../search/sync/index.ts";
|
|
25
30
|
import { readsHeaderFiles } from "./adapter-output.ts";
|
|
26
|
-
import { buildNetlifyHeaders } from "./headers.ts";
|
|
31
|
+
import { buildNetlifyHeaders, buildVercelHeaders } from "./headers.ts";
|
|
32
|
+
import { deployPlatform } from "./platforms/index.ts";
|
|
33
|
+
import { VERCEL_JSON_FILE } from "./platforms/vercel.ts";
|
|
27
34
|
import {
|
|
28
|
-
buildNetlifyRedirects,
|
|
29
35
|
buildRedirectManifest,
|
|
30
36
|
buildVercelConfig,
|
|
31
37
|
platformRedirects,
|
|
@@ -58,38 +64,63 @@ export interface ArtifactLogger {
|
|
|
58
64
|
}
|
|
59
65
|
|
|
60
66
|
/**
|
|
61
|
-
* Emit platform redirect files for a static build (
|
|
62
|
-
*
|
|
63
|
-
*
|
|
67
|
+
* Emit platform redirect files for a static build (a server build answers
|
|
68
|
+
* redirects at request time): the files the deployment's platform reads
|
|
69
|
+
* (`_redirects`, `vercel.json` — every one of them when no host is named),
|
|
70
|
+
* each only when the user hasn't shipped one via public/, plus the
|
|
71
|
+
* `blume-redirects.json` manifest when no host is named. `vercel.json` also
|
|
72
|
+
* carries the header rules `_headers` gives the other hosts, since Vercel reads
|
|
73
|
+
* no `_headers`, so it is written even with no redirects. Note that Vercel's
|
|
64
74
|
* git-integration builds read `vercel.json` from the repository root only —
|
|
65
75
|
* the copy emitted here takes effect when the dist folder itself is deployed
|
|
66
76
|
* directly via the Vercel CLI.
|
|
67
77
|
*/
|
|
68
78
|
const emitRedirectFiles = async (
|
|
69
|
-
|
|
79
|
+
project: BlumeProject,
|
|
70
80
|
distDir: string,
|
|
71
81
|
logger: ArtifactLogger
|
|
72
82
|
): Promise<void> => {
|
|
73
|
-
const
|
|
74
|
-
if (
|
|
83
|
+
const { config } = project;
|
|
84
|
+
if (config.deployment.options.output !== "static") {
|
|
75
85
|
return;
|
|
76
86
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
87
|
+
const platform = deployPlatform(config.deployment);
|
|
88
|
+
const redirects = platformRedirects(config);
|
|
89
|
+
const vercelHeaders = platform.redirectFiles.includes(VERCEL_JSON_FILE)
|
|
90
|
+
? buildVercelHeaders(
|
|
91
|
+
config,
|
|
92
|
+
buildHomeLinkHeader(config, markdownRoutePaths(project))
|
|
93
|
+
)
|
|
94
|
+
: [];
|
|
95
|
+
const files = platform.redirectFiles.filter(
|
|
96
|
+
(file) =>
|
|
97
|
+
!existsSync(join(distDir, file.name)) &&
|
|
98
|
+
(redirects.length > 0 ||
|
|
99
|
+
(file === VERCEL_JSON_FILE && vercelHeaders.length > 0))
|
|
81
100
|
);
|
|
82
|
-
const platformFiles = [
|
|
83
|
-
{ content: buildNetlifyRedirects(redirects), name: "_redirects" },
|
|
84
|
-
{ content: buildVercelConfig(redirects), name: "vercel.json" },
|
|
85
|
-
];
|
|
86
101
|
await Promise.all(
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
102
|
+
files.map((file) =>
|
|
103
|
+
writeFile(
|
|
104
|
+
join(distDir, file.name),
|
|
105
|
+
file === VERCEL_JSON_FILE
|
|
106
|
+
? buildVercelConfig(redirects, vercelHeaders)
|
|
107
|
+
: file.build(redirects),
|
|
108
|
+
"utf-8"
|
|
109
|
+
)
|
|
91
110
|
)
|
|
92
111
|
);
|
|
112
|
+
if (redirects.length === 0) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
// The manifest is for a host Blume can't name, where nothing reads the
|
|
116
|
+
// platform files above.
|
|
117
|
+
if (platform.kind === "static") {
|
|
118
|
+
await writeFile(
|
|
119
|
+
join(distDir, "blume-redirects.json"),
|
|
120
|
+
buildRedirectManifest(redirects),
|
|
121
|
+
"utf-8"
|
|
122
|
+
);
|
|
123
|
+
}
|
|
93
124
|
logger.info(`Emitted redirect files for ${redirects.length} redirect(s)`);
|
|
94
125
|
};
|
|
95
126
|
|
|
@@ -156,7 +187,7 @@ export const emitHeaderFiles = async (
|
|
|
156
187
|
};
|
|
157
188
|
|
|
158
189
|
/**
|
|
159
|
-
* Collect the Agent Skills `
|
|
190
|
+
* Collect the Agent Skills `agents.skills` publishes, once per build, so both the
|
|
160
191
|
* skills surface and llms.txt (which lists them) read the same set. Empty
|
|
161
192
|
* when the feature is off, the directory is missing, nothing in it is
|
|
162
193
|
* publishable (each with a warning), or a user-shipped
|
|
@@ -167,14 +198,14 @@ const collectConfiguredSkills = async (
|
|
|
167
198
|
distDir: string,
|
|
168
199
|
logger: ArtifactLogger
|
|
169
200
|
): Promise<SkillArtifact[]> => {
|
|
170
|
-
const configured = project.config.
|
|
201
|
+
const configured = project.config.agents.skills;
|
|
171
202
|
if (!configured) {
|
|
172
203
|
return [];
|
|
173
204
|
}
|
|
174
205
|
const dir = resolve(project.context.root, configured);
|
|
175
206
|
if (!existsSync(dir)) {
|
|
176
207
|
logger.warn(
|
|
177
|
-
`
|
|
208
|
+
`agents.skills points at "${configured}" (${dir}), which does not exist; no skills published.`
|
|
178
209
|
);
|
|
179
210
|
return [];
|
|
180
211
|
}
|
|
@@ -186,7 +217,9 @@ const collectConfiguredSkills = async (
|
|
|
186
217
|
logger.warn(warning);
|
|
187
218
|
}
|
|
188
219
|
if (skills.length === 0) {
|
|
189
|
-
logger.warn(
|
|
220
|
+
logger.warn(
|
|
221
|
+
`agents.skills: no publishable skills found in "${configured}".`
|
|
222
|
+
);
|
|
190
223
|
}
|
|
191
224
|
return skills;
|
|
192
225
|
};
|
|
@@ -234,8 +267,12 @@ const emitAgentSkills = async (
|
|
|
234
267
|
const emitWellKnownFiles = async (
|
|
235
268
|
config: ResolvedConfig,
|
|
236
269
|
distDir: string,
|
|
270
|
+
skills: readonly SkillArtifact[],
|
|
237
271
|
logger: ArtifactLogger
|
|
238
272
|
): Promise<void> => {
|
|
273
|
+
// One document, two paths: the ai-catalog spec's well-known URI and the
|
|
274
|
+
// ARD v0.91 one (see `ai/ai-catalog.ts`).
|
|
275
|
+
const aiCatalog = buildAiCatalog(config, skills);
|
|
239
276
|
const files = [
|
|
240
277
|
{
|
|
241
278
|
content: buildSignaturesDirectory(config),
|
|
@@ -247,6 +284,8 @@ const emitWellKnownFiles = async (
|
|
|
247
284
|
label: "RFC 9727",
|
|
248
285
|
path: API_CATALOG_PATH,
|
|
249
286
|
},
|
|
287
|
+
{ content: aiCatalog, label: "AI Catalog", path: AI_CATALOG_PATH },
|
|
288
|
+
{ content: aiCatalog, label: "ARD manifest", path: ARD_MANIFEST_PATH },
|
|
250
289
|
];
|
|
251
290
|
for (const file of files) {
|
|
252
291
|
const target = join(distDir, file.path.slice(1));
|
|
@@ -313,7 +352,7 @@ export const publishBuildArtifacts = async (
|
|
|
313
352
|
logger: ArtifactLogger,
|
|
314
353
|
indexSearch: (outDir: string) => Promise<number> = buildSearchIndex
|
|
315
354
|
): Promise<void> => {
|
|
316
|
-
if (project.config.search.provider === "pagefind") {
|
|
355
|
+
if (project.config.search.provider.mode === "pagefind") {
|
|
317
356
|
logger.info("Building search index");
|
|
318
357
|
const indexed = await indexSearch(distDir);
|
|
319
358
|
logger.info(`Indexed ${indexed} page(s) for search`);
|
|
@@ -329,7 +368,7 @@ export const publishBuildArtifacts = async (
|
|
|
329
368
|
|
|
330
369
|
// Collected once: llms.txt lists the skills the build publishes below.
|
|
331
370
|
const skills = await collectConfiguredSkills(project, distDir, logger);
|
|
332
|
-
if (project.config.
|
|
371
|
+
if (project.config.agents.llmsTxt.enabled) {
|
|
333
372
|
await publishLlmsFiles(project, distDir, skills, logger);
|
|
334
373
|
}
|
|
335
374
|
|
|
@@ -362,9 +401,9 @@ export const publishBuildArtifacts = async (
|
|
|
362
401
|
logger.info("Generated agent-readability.json");
|
|
363
402
|
}
|
|
364
403
|
|
|
365
|
-
await emitWellKnownFiles(project.config, distDir, logger);
|
|
404
|
+
await emitWellKnownFiles(project.config, distDir, skills, logger);
|
|
366
405
|
await emitAgentSkills(project, distDir, skills, logger);
|
|
367
406
|
|
|
368
|
-
await emitRedirectFiles(project
|
|
407
|
+
await emitRedirectFiles(project, distDir, logger);
|
|
369
408
|
await emitHeaderFiles(project, distDir, logger);
|
|
370
409
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `Accept: text/markdown` content negotiation for Cloudflare server builds.
|
|
3
3
|
*
|
|
4
|
-
* Blume prerenders every content page — even
|
|
5
|
-
*
|
|
4
|
+
* Blume prerenders every content page — even in a server build (`deployment:
|
|
5
|
+
* cloudflare()`) — and on Cloudflare the ASSETS binding serves those files before
|
|
6
6
|
* the Worker script runs, so no server-side code (Astro middleware included)
|
|
7
7
|
* ever sees a content-page request. Worse, even a content-page request that
|
|
8
8
|
* does reach the Worker is answered by `@astrojs/cloudflare`'s handler
|
|
@@ -13,10 +13,11 @@
|
|
|
13
13
|
* Negotiation therefore needs two coordinated pieces, both applied to the
|
|
14
14
|
* adapter's emitted deploy bundle after `astro build`:
|
|
15
15
|
*
|
|
16
|
-
* 1. `assets.run_worker_first` in `dist/server/wrangler.json`,
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
16
|
+
* 1. `assets.run_worker_first` in `dist/server/wrangler.json`, claiming every
|
|
17
|
+
* path except the static files that never negotiate, so the platform
|
|
18
|
+
* routes page requests — and requests for pages that do not exist — to
|
|
19
|
+
* the Worker instead of serving the static HTML directly (see
|
|
20
|
+
* `buildRunWorkerFirstRules`).
|
|
20
21
|
* 2. A generated entry Worker that fronts the adapter's: when the client
|
|
21
22
|
* prefers `text/markdown` it serves the page's prerendered `.md` mirror
|
|
22
23
|
* from the ASSETS binding, and it delegates everything else to the Astro
|
|
@@ -32,11 +33,9 @@
|
|
|
32
33
|
* they sit in the manifest's asset set, which the handler serves from the
|
|
33
34
|
* binding first. So whenever a worker-first rule claims a page JSON URL, the
|
|
34
35
|
* wrapper answers it from the binding itself, keyed by the exact set of
|
|
35
|
-
* documents the build emitted. The generated rule
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* covers the remaining claims (a content section under `/api`, or
|
|
39
|
-
* user-configured rules).
|
|
36
|
+
* documents the build emitted. The generated rule set claims them (a miss
|
|
37
|
+
* must reach the API's `PAGE_NOT_FOUND` answer, see `STATIC_EXEMPTIONS`), and
|
|
38
|
+
* so do user-configured rules or a bare `true`.
|
|
40
39
|
*
|
|
41
40
|
* Cloudflare does not apply `_headers` to worker-first routes, so the wrapper
|
|
42
41
|
* also re-stamps what the static layer would otherwise add on the routes it
|
|
@@ -62,9 +61,30 @@
|
|
|
62
61
|
* its keys are full served URLs, which is exactly what the Worker sees.
|
|
63
62
|
* Redirects outside every worker-first rule still never invoke the Worker;
|
|
64
63
|
* the static layer serves them from `_redirects` as before.
|
|
64
|
+
*
|
|
65
|
+
* Missing pages negotiate too. Under an explicit `run_worker_first` list the
|
|
66
|
+
* platform answers every request outside the rules from the static layer —
|
|
67
|
+
* an asset miss included, as the nearest `404.html` — which is why the rules
|
|
68
|
+
* claim every path: a request for a URL no page backs then reaches the
|
|
69
|
+
* Worker, and the Astro Worker answers it with the HTML 404 shell from the
|
|
70
|
+
* binding (`not_found_handling: "404-page"`). When the client prefers
|
|
71
|
+
* Markdown the wrapper swaps that shell for the prerendered `/404.md` twin,
|
|
72
|
+
* and when it prefers JSON for the `/404.json` problem document, keeping the
|
|
73
|
+
* 404 status either way — the counterpart of the miss-phase routes in
|
|
74
|
+
* `deploy/vercel-negotiation.ts`. A raw `.md` or `.json` URL no file backs
|
|
75
|
+
* asks for the same twin implicitly, but on this platform such a request only
|
|
76
|
+
* reaches the Worker for `.json` (the generated set keeps `.md` on the static
|
|
77
|
+
* layer for its `_headers`). Only an HTML 404 is swapped, so an API endpoint's
|
|
78
|
+
* own problem document is never overwritten.
|
|
65
79
|
*/
|
|
66
80
|
|
|
81
|
+
import {
|
|
82
|
+
API_NAVIGATION_PATH,
|
|
83
|
+
API_PAGES_PATH,
|
|
84
|
+
OPENAPI_PATH,
|
|
85
|
+
} from "../ai/api/paths.ts";
|
|
67
86
|
import { normalizePath } from "../core/base-path.ts";
|
|
87
|
+
import type { NotFoundVariants } from "./vercel-negotiation.ts";
|
|
68
88
|
|
|
69
89
|
/** Filename of the generated wrapper Worker, next to the adapter's entry. */
|
|
70
90
|
export const NEGOTIATION_WORKER_FILE = "blume-worker.mjs";
|
|
@@ -72,28 +92,42 @@ export const NEGOTIATION_WORKER_FILE = "blume-worker.mjs";
|
|
|
72
92
|
/**
|
|
73
93
|
* Wrangler's limits on `assets.run_worker_first`: at most 100 rules of at
|
|
74
94
|
* most 100 characters each. A rule set over either limit fails
|
|
75
|
-
* `wrangler deploy` outright, so the
|
|
95
|
+
* `wrangler deploy` outright, so the injection is skipped instead — only
|
|
96
|
+
* user-configured rules can push the generated set over.
|
|
76
97
|
*/
|
|
77
98
|
const MAX_RULES = 100;
|
|
78
99
|
const MAX_RULE_LENGTH = 100;
|
|
79
100
|
|
|
80
101
|
/**
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
102
|
+
* The paths the generated rules leave on the static layer, relative to the
|
|
103
|
+
* deployment base: the fingerprinted build assets, and the files whose
|
|
104
|
+
* response headers come from `_headers` — which Cloudflare does not apply to
|
|
105
|
+
* a response the Worker produced — and which never negotiate. Those are the
|
|
106
|
+
* raw AI-ready endpoints (`charset=utf-8` on `.md`/`.mdx`/`.txt`) and the
|
|
107
|
+
* `.well-known` discovery documents (the extensionless api-catalog's content
|
|
108
|
+
* type, the CORS headers).
|
|
109
|
+
*
|
|
110
|
+
* The JSON Blume writes at fixed paths stays there too, but JSON as a whole
|
|
111
|
+
* does not: a negative rule outranks every positive one, so a `*.json`
|
|
112
|
+
* exemption would keep a request for a page JSON that doesn't exist
|
|
113
|
+
* (`/api/docs/pages/nope.json`) off the Worker, and the platform would answer
|
|
114
|
+
* it with an empty 404 instead of the API's `PAGE_NOT_FOUND` problem document.
|
|
115
|
+
* The per-page documents themselves reach the wrapper, which serves them from
|
|
116
|
+
* the binding (see the module comment); any other JSON goes through the Astro
|
|
117
|
+
* Worker, which serves a static file from the binding as well.
|
|
89
118
|
*/
|
|
90
|
-
const
|
|
91
|
-
"/*",
|
|
92
|
-
"
|
|
93
|
-
"
|
|
94
|
-
"
|
|
95
|
-
"
|
|
96
|
-
"
|
|
119
|
+
const STATIC_EXEMPTIONS = [
|
|
120
|
+
"/_astro/*",
|
|
121
|
+
"/*.md",
|
|
122
|
+
"/*.mdx",
|
|
123
|
+
"/*.txt",
|
|
124
|
+
"/.well-known/*",
|
|
125
|
+
"/404.json",
|
|
126
|
+
"/agent-readability.json",
|
|
127
|
+
"/blume-search.json",
|
|
128
|
+
OPENAPI_PATH,
|
|
129
|
+
API_PAGES_PATH,
|
|
130
|
+
API_NAVIGATION_PATH,
|
|
97
131
|
];
|
|
98
132
|
|
|
99
133
|
/**
|
|
@@ -129,68 +163,26 @@ const ruleBody = (rule: string): string =>
|
|
|
129
163
|
isNegativeRule(rule) ? rule.slice(1) : rule;
|
|
130
164
|
|
|
131
165
|
/**
|
|
132
|
-
* The `run_worker_first` rules
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
166
|
+
* The `run_worker_first` rules: every path under the deployment base goes
|
|
167
|
+
* through the Worker except the {@link STATIC_EXEMPTIONS}. Claiming
|
|
168
|
+
* everything — rather than only the content routes — is what lets a
|
|
169
|
+
* *missing* page negotiate: under an explicit rule list the platform answers
|
|
170
|
+
* any request outside every rule from the static layer, an asset miss
|
|
171
|
+
* included (as the nearest `404.html`), so a rule set scoped to the content
|
|
172
|
+
* routes would never let the Worker see a request for a URL that has no
|
|
173
|
+
* page. The price is a Worker hop on every page request the site does serve.
|
|
174
|
+
* On a subpath deploy the base is claimed in both request spellings.
|
|
141
175
|
*
|
|
142
176
|
* Configured redirects need no exemption from these rules: the wrapper Worker
|
|
143
177
|
* answers any it claims from its baked-in redirect table with the configured
|
|
144
178
|
* status (see the module comment).
|
|
145
179
|
*/
|
|
146
|
-
export const buildRunWorkerFirstRules = (
|
|
147
|
-
routePaths: readonly string[],
|
|
148
|
-
base?: string
|
|
149
|
-
): string[] => {
|
|
180
|
+
export const buildRunWorkerFirstRules = (base?: string): string[] => {
|
|
150
181
|
const prefix = encodeURI(basePrefix(base));
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
`!${prefix}/*.md`,
|
|
156
|
-
`!${prefix}/*.mdx`,
|
|
157
|
-
`!${prefix}/*.txt`,
|
|
158
|
-
`!${prefix}/*.json`,
|
|
159
|
-
`!${prefix}/_astro/*`,
|
|
160
|
-
];
|
|
161
|
-
}
|
|
162
|
-
const groups = new Map<string, { bare: boolean; nested: boolean }>();
|
|
163
|
-
let home = false;
|
|
164
|
-
for (const route of routePaths) {
|
|
165
|
-
if (route === "/") {
|
|
166
|
-
home = true;
|
|
167
|
-
continue;
|
|
168
|
-
}
|
|
169
|
-
const segments = route.split("/").filter(Boolean);
|
|
170
|
-
const head = segments[0] ?? "";
|
|
171
|
-
const group = groups.get(head) ?? { bare: false, nested: false };
|
|
172
|
-
if (segments.length === 1) {
|
|
173
|
-
group.bare = true;
|
|
174
|
-
} else {
|
|
175
|
-
group.nested = true;
|
|
176
|
-
}
|
|
177
|
-
groups.set(head, group);
|
|
178
|
-
}
|
|
179
|
-
const rules: string[] = home ? ["/"] : [];
|
|
180
|
-
const negatives: string[] = [];
|
|
181
|
-
for (const [head, group] of groups) {
|
|
182
|
-
const segment = `/${encodeURI(head)}`;
|
|
183
|
-
if (group.bare) {
|
|
184
|
-
rules.push(segment);
|
|
185
|
-
}
|
|
186
|
-
if (group.nested) {
|
|
187
|
-
rules.push(`${segment}/*`);
|
|
188
|
-
negatives.push(`!${segment}/*.md`, `!${segment}/*.mdx`);
|
|
189
|
-
} else {
|
|
190
|
-
rules.push(`${segment}/`);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
return [...rules, ...negatives];
|
|
182
|
+
const exemptions = STATIC_EXEMPTIONS.map((path) => `!${prefix}${path}`);
|
|
183
|
+
return prefix
|
|
184
|
+
? [prefix, `${prefix}/*`, ...exemptions]
|
|
185
|
+
: [`/*`, ...exemptions];
|
|
194
186
|
};
|
|
195
187
|
|
|
196
188
|
/**
|
|
@@ -268,6 +260,12 @@ export interface NegotiationWorkerOptions {
|
|
|
268
260
|
* the `/api/` catch-all (see the module comment).
|
|
269
261
|
*/
|
|
270
262
|
pageJsonPaths?: readonly string[];
|
|
263
|
+
/**
|
|
264
|
+
* Which prerendered 404 twins the build emitted (`404.md`, `404.json`), so
|
|
265
|
+
* the wrapper only substitutes a twin that exists. A project that owns
|
|
266
|
+
* `/404` emits neither and keeps the HTML answer.
|
|
267
|
+
*/
|
|
268
|
+
notFound?: NotFoundVariants;
|
|
271
269
|
}
|
|
272
270
|
|
|
273
271
|
/**
|
|
@@ -287,6 +285,10 @@ export const buildNegotiationWorker = (
|
|
|
287
285
|
const homeTokens = JSON.stringify(
|
|
288
286
|
options.homeTokens === undefined ? null : String(options.homeTokens)
|
|
289
287
|
);
|
|
288
|
+
const notFound = JSON.stringify({
|
|
289
|
+
json: options.notFound?.json === true,
|
|
290
|
+
markdown: options.notFound?.markdown === true,
|
|
291
|
+
});
|
|
290
292
|
// Keyed by the normalized served path; the runtime lookup decodes and
|
|
291
293
|
// trims the request path the same way, so both spellings of a URL match.
|
|
292
294
|
// The destination is percent-encoded here because it ships as a `Location`
|
|
@@ -309,9 +311,11 @@ export const buildNegotiationWorker = (
|
|
|
309
311
|
// per-page JSON document is served from the binding (the Astro Worker would
|
|
310
312
|
// route it to the \`/api/\` catch-all, because Astro resolves a prerendered
|
|
311
313
|
// dynamic route to the first live route on the same path). Every other
|
|
312
|
-
// request is delegated to the Astro Worker untouched
|
|
313
|
-
//
|
|
314
|
-
//
|
|
314
|
+
// request is delegated to the Astro Worker untouched — except a missing
|
|
315
|
+
// page, whose HTML 404 shell is swapped for the prerendered Markdown or JSON
|
|
316
|
+
// 404 twin when the client prefers one. \`_headers\` does not apply to
|
|
317
|
+
// worker-first routes, so the homepage Link header and the Markdown charset
|
|
318
|
+
// are re-stamped here.
|
|
315
319
|
import server from ${JSON.stringify(options.mainSpecifier)};
|
|
316
320
|
|
|
317
321
|
const ROUTES = new Set(${routes});
|
|
@@ -321,6 +325,7 @@ const ASSETS_BINDING = ${binding};
|
|
|
321
325
|
const HOME_LINK_HEADER = ${homeLinkHeader};
|
|
322
326
|
const HOME_TOKENS = ${homeTokens};
|
|
323
327
|
const REDIRECTS = ${redirects};
|
|
328
|
+
const NOT_FOUND = ${notFound};
|
|
324
329
|
|
|
325
330
|
// Configured redirects live in \`_redirects\`, which only the static layer
|
|
326
331
|
// reads — a worker-first route never reaches it. Answering from this baked-in
|
|
@@ -383,20 +388,93 @@ const parseAccept = (accept) =>
|
|
|
383
388
|
return { q: Number.isNaN(q) ? 1 : q, type };
|
|
384
389
|
});
|
|
385
390
|
|
|
386
|
-
|
|
391
|
+
// Whether the client explicitly prefers one of \`types\` over HTML. Browsers
|
|
392
|
+
// never send these, so an ordinary page request is false.
|
|
393
|
+
const prefers = (accept, types) => {
|
|
387
394
|
if (!accept) {
|
|
388
395
|
return false;
|
|
389
396
|
}
|
|
390
|
-
let
|
|
397
|
+
let wantedQ = -1;
|
|
391
398
|
let htmlQ = 0;
|
|
392
399
|
for (const { q, type } of parseAccept(accept)) {
|
|
393
|
-
if (type
|
|
394
|
-
|
|
400
|
+
if (types.includes(type)) {
|
|
401
|
+
wantedQ = Math.max(wantedQ, q);
|
|
395
402
|
} else if (type === "text/html") {
|
|
396
403
|
htmlQ = Math.max(htmlQ, q);
|
|
397
404
|
}
|
|
398
405
|
}
|
|
399
|
-
return
|
|
406
|
+
return wantedQ > 0 && wantedQ >= htmlQ;
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
const prefersMarkdown = (accept) =>
|
|
410
|
+
prefers(accept, ["text/markdown", "text/x-markdown"]);
|
|
411
|
+
|
|
412
|
+
const prefersJson = (accept) =>
|
|
413
|
+
prefers(accept, ["application/json", "application/problem+json"]);
|
|
414
|
+
|
|
415
|
+
// The prerendered 404 twins, in the order a client asking for both is
|
|
416
|
+
// answered: which twin, when a client prefers it, the raw URL extension that
|
|
417
|
+
// asks for it implicitly, where it lives, and the content type to re-pin.
|
|
418
|
+
const NOT_FOUND_TWINS = [
|
|
419
|
+
{
|
|
420
|
+
contentType: "text/markdown; charset=utf-8",
|
|
421
|
+
extension: /\\.mdx?$/u,
|
|
422
|
+
key: "markdown",
|
|
423
|
+
path: "/404.md",
|
|
424
|
+
prefers: prefersMarkdown,
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
contentType: "application/problem+json; charset=utf-8",
|
|
428
|
+
extension: /\\.json$/u,
|
|
429
|
+
key: "json",
|
|
430
|
+
path: "/404.json",
|
|
431
|
+
prefers: prefersJson,
|
|
432
|
+
},
|
|
433
|
+
];
|
|
434
|
+
|
|
435
|
+
// A missing page comes back from the Astro Worker as the HTML 404 shell (the
|
|
436
|
+
// binding's \`not_found_handling\`); a client that prefers Markdown or JSON —
|
|
437
|
+
// or asked for a raw \`.md\`/\`.json\` URL no file backs — gets the prerendered
|
|
438
|
+
// twin instead, with the same 404 status. Anything but an HTML 404 (an API
|
|
439
|
+
// endpoint's own problem document, a missing image) is left alone. The twin
|
|
440
|
+
// is fetched without the request's conditional headers, so a stray ETag match
|
|
441
|
+
// cannot turn the 404 into a 304.
|
|
442
|
+
const notFoundTwin = async (request, url, response, assets) => {
|
|
443
|
+
if (response.status !== 404 || assets === undefined) {
|
|
444
|
+
return null;
|
|
445
|
+
}
|
|
446
|
+
const type = response.headers.get("content-type") ?? "";
|
|
447
|
+
if (!type.startsWith("text/html")) {
|
|
448
|
+
return null;
|
|
449
|
+
}
|
|
450
|
+
const accept = request.headers.get("accept");
|
|
451
|
+
for (const twin of NOT_FOUND_TWINS) {
|
|
452
|
+
if (!NOT_FOUND[twin.key]) {
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
455
|
+
const negotiated = twin.prefers(accept);
|
|
456
|
+
if (!negotiated && !twin.extension.test(url.pathname)) {
|
|
457
|
+
continue;
|
|
458
|
+
}
|
|
459
|
+
const asset = await assets.fetch(
|
|
460
|
+
new Request(new URL(BASE_PREFIX + twin.path, url), {
|
|
461
|
+
method: request.method,
|
|
462
|
+
})
|
|
463
|
+
);
|
|
464
|
+
if (!asset.ok) {
|
|
465
|
+
return null;
|
|
466
|
+
}
|
|
467
|
+
const patched = new Response(asset.body, {
|
|
468
|
+
headers: asset.headers,
|
|
469
|
+
status: 404,
|
|
470
|
+
});
|
|
471
|
+
patched.headers.set("content-type", twin.contentType);
|
|
472
|
+
if (negotiated) {
|
|
473
|
+
patched.headers.append("vary", "Accept");
|
|
474
|
+
}
|
|
475
|
+
return patched;
|
|
476
|
+
}
|
|
477
|
+
return null;
|
|
400
478
|
};
|
|
401
479
|
|
|
402
480
|
const markdownVariantUrl = (rawUrl) => {
|
|
@@ -487,6 +565,10 @@ export default {
|
|
|
487
565
|
}
|
|
488
566
|
}
|
|
489
567
|
const response = await server.fetch(request, env, context);
|
|
568
|
+
const twin = await notFoundTwin(request, url, response, assets);
|
|
569
|
+
if (twin !== null) {
|
|
570
|
+
return twin;
|
|
571
|
+
}
|
|
490
572
|
if (variant === null && !(home && HOME_LINK_HEADER !== null)) {
|
|
491
573
|
return response;
|
|
492
574
|
}
|
|
@@ -531,13 +613,13 @@ export interface WorkerNegotiationOptions extends Omit<
|
|
|
531
613
|
* updated config text plus the wrapper module, or `null` when there is
|
|
532
614
|
* nothing to do or nowhere safe to do it: no routes, unparsable config, no
|
|
533
615
|
* usable `main` or assets binding (the wrapper serves the `.md` mirrors from
|
|
534
|
-
* it), an already-swapped `main` (the original entry is unrecoverable), or
|
|
535
|
-
*
|
|
616
|
+
* it), an already-swapped `main` (the original entry is unrecoverable), or
|
|
617
|
+
* user-configured rules that push the set over Wrangler's limits.
|
|
536
618
|
*
|
|
537
619
|
* The configured redirects are baked into the wrapper, which answers any the
|
|
538
620
|
* worker-first rules claim with the exact configured status (see the module
|
|
539
|
-
* comment) — whichever rules do the claiming: the generated
|
|
540
|
-
*
|
|
621
|
+
* comment) — whichever rules do the claiming: the generated `/*`, or the
|
|
622
|
+
* user's own (including a bare `true`). A
|
|
541
623
|
* redirect at a content route's own path is never baked: the page owns it,
|
|
542
624
|
* and answering a redirect there would take a real page off the air. When
|
|
543
625
|
* `null` is returned no rule set is written at all, so every request stays on
|
|
@@ -594,13 +676,10 @@ export const injectWorkerNegotiation = (
|
|
|
594
676
|
redirect.from.startsWith("/") &&
|
|
595
677
|
!guardRoutes.has(normalizePath(redirect.from))
|
|
596
678
|
);
|
|
597
|
-
|
|
679
|
+
const rules = mergeRunWorkerFirstRules(
|
|
598
680
|
assets.run_worker_first,
|
|
599
|
-
buildRunWorkerFirstRules(options.
|
|
681
|
+
buildRunWorkerFirstRules(options.base)
|
|
600
682
|
);
|
|
601
|
-
if (!withinWranglerLimits(rules)) {
|
|
602
|
-
rules = mergeRunWorkerFirstRules(assets.run_worker_first, FALLBACK_RULES);
|
|
603
|
-
}
|
|
604
683
|
if (!withinWranglerLimits(rules)) {
|
|
605
684
|
return null;
|
|
606
685
|
}
|
|
@@ -6,6 +6,10 @@ import { init, parse } from "es-module-lexer";
|
|
|
6
6
|
import { dirname, join, relative } from "pathe";
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
|
|
9
|
+
import {
|
|
10
|
+
commandsFor,
|
|
11
|
+
detectProjectPackageManager,
|
|
12
|
+
} from "../cli/init/scaffold.ts";
|
|
9
13
|
import { packageRoot } from "../core/package-root.ts";
|
|
10
14
|
|
|
11
15
|
/**
|
|
@@ -271,16 +275,27 @@ export interface FunctionBundleVerdict {
|
|
|
271
275
|
message: string;
|
|
272
276
|
}
|
|
273
277
|
|
|
278
|
+
/**
|
|
279
|
+
* The command that adds a dev dependency with the project's package manager
|
|
280
|
+
* (`pnpm add -D`, `npm install -D`, …), for the fix a verdict prints. The
|
|
281
|
+
* missing packages are an isolated-linker problem, so the project is often
|
|
282
|
+
* not on npm at all.
|
|
283
|
+
*/
|
|
284
|
+
export const addDevDependencyCommand = async (root: string): Promise<string> =>
|
|
285
|
+
`${commandsFor(await detectProjectPackageManager(root)).add} -D`;
|
|
286
|
+
|
|
274
287
|
/**
|
|
275
288
|
* Describe a function's missing packages and how to fix them. Vercel's trace
|
|
276
289
|
* only reaches packages resolvable from the project root, so the remedy is a
|
|
277
290
|
* root-level dependency entry for each — the same mirror rule Blume's native
|
|
278
|
-
* dependencies (`sharp`, `takumi-js`) already follow
|
|
291
|
+
* dependencies (`sharp`, `takumi-js`) already follow — added with
|
|
292
|
+
* `addDevCommand` (see {@link addDevDependencyCommand}).
|
|
279
293
|
*/
|
|
280
294
|
export const functionBundleVerdict = (
|
|
281
295
|
audit: FunctionBundleAudit,
|
|
282
296
|
root: string,
|
|
283
|
-
ownDependencies: ReadonlySet<string
|
|
297
|
+
ownDependencies: ReadonlySet<string>,
|
|
298
|
+
addDevCommand = "npm install -D"
|
|
284
299
|
): FunctionBundleVerdict => {
|
|
285
300
|
const names = audit.missing.map((entry) => entry.name);
|
|
286
301
|
const lines = audit.missing.map(
|
|
@@ -291,7 +306,7 @@ export const functionBundleVerdict = (
|
|
|
291
306
|
`The Vercel function bundle at ${relative(root, audit.dir) || audit.dir} is missing packages its server code imports, so the deployed function would fail on every request with ERR_MODULE_NOT_FOUND:`,
|
|
292
307
|
...lines,
|
|
293
308
|
"Vercel's dependency trace only includes packages resolvable from the project root; under an isolated linker (pnpm, Bun's isolated mode) Blume's own dependencies are not. Add them to the project's package.json so the trace can find them:",
|
|
294
|
-
`
|
|
309
|
+
` ${addDevCommand} ${names.join(" ")}`,
|
|
295
310
|
].join("\n");
|
|
296
311
|
return { fatal, message };
|
|
297
312
|
};
|