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
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
|
|
4
|
+
import { join, relative, resolve } from "pathe";
|
|
5
|
+
import { glob } from "tinyglobby";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
analyzeComponentOverrides,
|
|
10
|
+
ComponentOverridesError,
|
|
11
|
+
} from "../core/component-overrides.ts";
|
|
12
|
+
import { ConfigValidationError, loadConfig } from "../core/config.ts";
|
|
13
|
+
import { BlumeError, locateFrontmatterKey } from "../core/diagnostics.ts";
|
|
14
|
+
import matter from "../core/frontmatter.ts";
|
|
15
|
+
import { createModuleLoader } from "../core/load-module.ts";
|
|
16
|
+
import { findComponentsFile, findConfigFile } from "../core/project.ts";
|
|
17
|
+
import { pageMetaSchema } from "../core/schema.ts";
|
|
18
|
+
import { baselineScanIgnore } from "../core/sources/watch.ts";
|
|
19
|
+
import type { Diagnostic } from "../core/types.ts";
|
|
20
|
+
import {
|
|
21
|
+
DEFAULT_CONTENT_EXCLUDE,
|
|
22
|
+
DEFAULT_CONTENT_INCLUDE,
|
|
23
|
+
} from "../sources/filesystem.ts";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* `blume upgrade`'s logic, kept out of the command module so it runs (and is
|
|
27
|
+
* covered) in-process: bump the `blume` dependency to the running CLI's major,
|
|
28
|
+
* then check the project against it — the config through the same loader
|
|
29
|
+
* every command uses, which names each removed or renamed field and its
|
|
30
|
+
* replacement, `components.ts` through the same static planner the build
|
|
31
|
+
* runs, and each page's front matter for fields the schema removed. The
|
|
32
|
+
* command prints the findings or hands them to a coding agent.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
/** The upgrade guide's route on the Blume docs site. */
|
|
36
|
+
export const UPGRADE_GUIDE_URL = "https://useblume.dev/docs/upgrading";
|
|
37
|
+
|
|
38
|
+
/** The upgrade guide's file inside the published package's bundled docs. */
|
|
39
|
+
export const UPGRADE_GUIDE_FILE = join("docs", "03-upgrading.mdx");
|
|
40
|
+
|
|
41
|
+
/** What `bumpBlumeDependency` did to `package.json`. */
|
|
42
|
+
export type DependencyBump =
|
|
43
|
+
| {
|
|
44
|
+
field: DependencyField;
|
|
45
|
+
from: string;
|
|
46
|
+
status: "bumped";
|
|
47
|
+
to: string;
|
|
48
|
+
}
|
|
49
|
+
| { range: string; status: "current" }
|
|
50
|
+
| { status: "missing" };
|
|
51
|
+
|
|
52
|
+
type DependencyField = "dependencies" | "devDependencies";
|
|
53
|
+
|
|
54
|
+
const DEPENDENCY_FIELDS: DependencyField[] = [
|
|
55
|
+
"dependencies",
|
|
56
|
+
"devDependencies",
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
/** The slice of `package.json` the bump reads and rewrites. */
|
|
60
|
+
interface PackageJson {
|
|
61
|
+
dependencies?: Record<string, string>;
|
|
62
|
+
devDependencies?: Record<string, string>;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Leading comparators and a `v` may precede the major (`^1.7.3`, `>=1 <2`,
|
|
66
|
+
// `v1`); a protocol (`workspace:`, `file:`, `npm:`) or a tag (`latest`) names
|
|
67
|
+
// no major at all, and those ranges are left to the user.
|
|
68
|
+
const RANGE_MAJOR = /^[\s<=>^~v]*(?<major>\d+)/u;
|
|
69
|
+
|
|
70
|
+
/** The major version a dependency range pins, or null when it names none. */
|
|
71
|
+
export const rangeMajor = (range: string): number | null => {
|
|
72
|
+
const major = RANGE_MAJOR.exec(range)?.groups?.major;
|
|
73
|
+
return major === undefined ? null : Number(major);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// The file's own indentation (two spaces, four, or a tab), so a fallback
|
|
77
|
+
// rewrite doesn't reformat a package.json the user keeps differently.
|
|
78
|
+
const INDENT = /^(?<indent>[ \t]+)"/mu;
|
|
79
|
+
|
|
80
|
+
const REGEXP_SPECIAL = /[$()*+.?[\\\]^{|}]/gu;
|
|
81
|
+
const escapeRegExp = (value: string): string =>
|
|
82
|
+
value.replaceAll(REGEXP_SPECIAL, String.raw`\$&`);
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* `text` with the `blume` range under `field` replaced in place, so the file
|
|
86
|
+
* keeps its own formatting, key order, and inline objects; null when the entry
|
|
87
|
+
* isn't written the plain way (an escaped key or value).
|
|
88
|
+
*/
|
|
89
|
+
const replaceRange = (
|
|
90
|
+
text: string,
|
|
91
|
+
field: DependencyField,
|
|
92
|
+
from: string,
|
|
93
|
+
to: string
|
|
94
|
+
): string | null => {
|
|
95
|
+
const value = JSON.stringify(from);
|
|
96
|
+
const entry = new RegExp(`"blume"\\s*:\\s*${escapeRegExp(value)}`, "gu");
|
|
97
|
+
entry.lastIndex = Math.max(text.indexOf(JSON.stringify(field)), 0);
|
|
98
|
+
const match = entry.exec(text);
|
|
99
|
+
if (!match) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
const end = match.index + match[0].length;
|
|
103
|
+
return `${text.slice(0, end - value.length)}${JSON.stringify(to)}${text.slice(end)}`;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Point `package.json`'s `blume` dependency at `^version` when it pins an
|
|
108
|
+
* older major. A range already on this major, or one that names no version
|
|
109
|
+
* (`workspace:*`, `latest`), is reported as current and left alone; a
|
|
110
|
+
* project with no `package.json`, or none that lists `blume`, is `missing`.
|
|
111
|
+
* Only the range changes: the rest of the file is kept byte for byte.
|
|
112
|
+
*/
|
|
113
|
+
export const bumpBlumeDependency = async (
|
|
114
|
+
root: string,
|
|
115
|
+
version: string
|
|
116
|
+
): Promise<DependencyBump> => {
|
|
117
|
+
const path = join(root, "package.json");
|
|
118
|
+
if (!existsSync(path)) {
|
|
119
|
+
return { status: "missing" };
|
|
120
|
+
}
|
|
121
|
+
const text = await readFile(path, "utf-8");
|
|
122
|
+
// SAFETY: package.json is a JSON object; only its dependency maps, which
|
|
123
|
+
// map package names to range strings, are read.
|
|
124
|
+
const pkg = JSON.parse(text) as PackageJson;
|
|
125
|
+
const field = DEPENDENCY_FIELDS.find(
|
|
126
|
+
(name) => pkg[name]?.blume !== undefined
|
|
127
|
+
);
|
|
128
|
+
const from = field ? pkg[field]?.blume : undefined;
|
|
129
|
+
if (!(field && from)) {
|
|
130
|
+
return { status: "missing" };
|
|
131
|
+
}
|
|
132
|
+
const current = rangeMajor(from);
|
|
133
|
+
const target = rangeMajor(version);
|
|
134
|
+
if (current === null || target === null || current >= target) {
|
|
135
|
+
return { range: from, status: "current" };
|
|
136
|
+
}
|
|
137
|
+
const to = `^${version}`;
|
|
138
|
+
const indent = INDENT.exec(text)?.groups?.indent ?? " ";
|
|
139
|
+
const updated = { ...pkg, [field]: { ...pkg[field], blume: to } };
|
|
140
|
+
await writeFile(
|
|
141
|
+
path,
|
|
142
|
+
replaceRange(text, field, from, to) ??
|
|
143
|
+
`${JSON.stringify(updated, null, indent)}\n`
|
|
144
|
+
);
|
|
145
|
+
return { field, from, status: "bumped", to };
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Whether `root` is no Blume project at all: no config file and no `blume`
|
|
150
|
+
* dependency, so the upgrade would only check the defaults and report the
|
|
151
|
+
* folder ready. A zero-config project still lists `blume`.
|
|
152
|
+
*/
|
|
153
|
+
export const isOutsideBlumeProject = (
|
|
154
|
+
root: string,
|
|
155
|
+
bump: DependencyBump
|
|
156
|
+
): boolean => bump.status === "missing" && findConfigFile(root) === null;
|
|
157
|
+
|
|
158
|
+
// ---------------------------------------------------------------------------
|
|
159
|
+
// Removed `blume build` flags
|
|
160
|
+
// ---------------------------------------------------------------------------
|
|
161
|
+
|
|
162
|
+
/** A `blume build` flag Blume 2 removed, bare or with an `=value`. */
|
|
163
|
+
const REMOVED_BUILD_FLAG = /^--(?<flag>adapter|base|output)(?:=|$)/u;
|
|
164
|
+
|
|
165
|
+
/** The removed `blume build` flags among `args`, in order, each once. */
|
|
166
|
+
export const removedBuildFlags = (args: readonly string[]): string[] => [
|
|
167
|
+
...new Set(
|
|
168
|
+
args.flatMap((arg) => {
|
|
169
|
+
const flag = REMOVED_BUILD_FLAG.exec(arg)?.groups?.flag;
|
|
170
|
+
return flag ? [flag] : [];
|
|
171
|
+
})
|
|
172
|
+
),
|
|
173
|
+
];
|
|
174
|
+
|
|
175
|
+
/** The flags as the reader typed them: `--adapter, --output`. */
|
|
176
|
+
export const flagList = (flags: string[]): string =>
|
|
177
|
+
flags.map((flag) => `--${flag}`).join(", ");
|
|
178
|
+
|
|
179
|
+
/** What replaces each removed flag: the `deployment` config. */
|
|
180
|
+
export const removedBuildFlagsAdvice = (flags: string[]): string => {
|
|
181
|
+
const advice: string[] = [];
|
|
182
|
+
if (flags.includes("adapter") || flags.includes("output")) {
|
|
183
|
+
advice.push(
|
|
184
|
+
'name the host in blume.config.ts with `deployment: vercel()` (or `netlify()`, `cloudflare()`, `node()`) from "blume/deploy" — a host adapter builds for the server, and `output: "static"` keeps it static'
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
if (flags.includes("base")) {
|
|
188
|
+
advice.push(
|
|
189
|
+
'set the subpath with `deployment: { base: "/docs" }`, or the host adapter\'s `base` option'
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
return `Drop ${flagList(flags)} and ${advice.join("; ")}.`;
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
// A command that runs the Blume CLI: the bare bin, a versioned package
|
|
196
|
+
// (`blume@2`), or a path to it (`./node_modules/.bin/blume`).
|
|
197
|
+
const BLUME_BIN = /(?:^|[/\\])blume(?:@\S+)?$/u;
|
|
198
|
+
const COMMAND_SEPARATOR = /&&|\|\||[;|]/u;
|
|
199
|
+
const WHITESPACE = /\s+/u;
|
|
200
|
+
|
|
201
|
+
/** The arguments each `blume build` in a script passes, flattened. */
|
|
202
|
+
const buildArgs = (script: string): string[] =>
|
|
203
|
+
script.split(COMMAND_SEPARATOR).flatMap((command) => {
|
|
204
|
+
const words = command.trim().split(WHITESPACE);
|
|
205
|
+
const at = words.findIndex(
|
|
206
|
+
(word, index) => BLUME_BIN.test(word) && words[index + 1] === "build"
|
|
207
|
+
);
|
|
208
|
+
return at === -1 ? [] : words.slice(at + 2);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
/** The slice of package.json the script check reads. */
|
|
212
|
+
const scriptsSchema = z.looseObject({
|
|
213
|
+
scripts: z.record(z.string(), z.string()).default({}),
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
const lineOf = (text: string, index: number): number =>
|
|
217
|
+
text.slice(0, index).split("\n").length;
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* A finding for each package.json script that still passes a removed flag to
|
|
221
|
+
* `blume build` — it would otherwise build a static site without a word.
|
|
222
|
+
*/
|
|
223
|
+
const scriptFindings = async (root: string): Promise<Diagnostic[]> => {
|
|
224
|
+
const path = join(root, "package.json");
|
|
225
|
+
if (!existsSync(path)) {
|
|
226
|
+
return [];
|
|
227
|
+
}
|
|
228
|
+
const text = await readFile(path, "utf-8");
|
|
229
|
+
const pkg = scriptsSchema.safeParse(JSON.parse(text));
|
|
230
|
+
const scripts = pkg.success ? pkg.data.scripts : {};
|
|
231
|
+
const scriptsAt = text.indexOf('"scripts"');
|
|
232
|
+
return Object.entries(scripts).flatMap(([name, script]) => {
|
|
233
|
+
const flags = removedBuildFlags(buildArgs(script));
|
|
234
|
+
if (flags.length === 0) {
|
|
235
|
+
return [];
|
|
236
|
+
}
|
|
237
|
+
const at = text.indexOf(JSON.stringify(name), scriptsAt);
|
|
238
|
+
return [
|
|
239
|
+
{
|
|
240
|
+
code: "BLUME_BUILD_FLAG_REMOVED",
|
|
241
|
+
file: path,
|
|
242
|
+
line: at === -1 ? undefined : lineOf(text, at),
|
|
243
|
+
message: `The "${name}" script passes ${flagList(flags)} to \`blume build\`, which Blume 2 removed.`,
|
|
244
|
+
severity: "error",
|
|
245
|
+
suggestion: removedBuildFlagsAdvice(flags),
|
|
246
|
+
} satisfies Diagnostic,
|
|
247
|
+
];
|
|
248
|
+
});
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
// ---------------------------------------------------------------------------
|
|
252
|
+
// Removed front matter fields
|
|
253
|
+
// ---------------------------------------------------------------------------
|
|
254
|
+
|
|
255
|
+
/** Where a project's local content lives, as its config names it. */
|
|
256
|
+
interface ContentGlobs {
|
|
257
|
+
exclude: string[];
|
|
258
|
+
include: string[];
|
|
259
|
+
root: string;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const globFields = {
|
|
263
|
+
exclude: z.array(z.string()).optional(),
|
|
264
|
+
include: z.array(z.string()).optional(),
|
|
265
|
+
root: z.string().optional(),
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* A filesystem source in either form a config being upgraded may hold: the
|
|
270
|
+
* `filesystem()` descriptor, or Blume 1's `{ type: "filesystem" }` object.
|
|
271
|
+
*/
|
|
272
|
+
const rawFilesystemSourceSchema = z.union([
|
|
273
|
+
z
|
|
274
|
+
.looseObject({
|
|
275
|
+
kind: z.literal("filesystem"),
|
|
276
|
+
options: z.looseObject(globFields).default({}),
|
|
277
|
+
})
|
|
278
|
+
.transform((source) => source.options),
|
|
279
|
+
z.looseObject({ type: z.literal("filesystem"), ...globFields }),
|
|
280
|
+
]);
|
|
281
|
+
|
|
282
|
+
/** The `content` slice of a config as written, before validation. */
|
|
283
|
+
const rawContentSchema = z.looseObject({
|
|
284
|
+
content: z
|
|
285
|
+
.looseObject({ ...globFields, sources: z.array(z.unknown()).optional() })
|
|
286
|
+
.optional(),
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* The content roots to scan, read from the config as written rather than the
|
|
291
|
+
* validated config: the upgrade runs on configs that don't validate yet. Its
|
|
292
|
+
* filesystem sources when it lists any, else the `content.root` shorthand,
|
|
293
|
+
* else the zero-config `docs` folder.
|
|
294
|
+
*/
|
|
295
|
+
export const contentGlobs = ({
|
|
296
|
+
content,
|
|
297
|
+
}: z.infer<typeof rawContentSchema>): ContentGlobs[] => {
|
|
298
|
+
const sources = (content?.sources ?? []).flatMap((source) => {
|
|
299
|
+
const filesystem = rawFilesystemSourceSchema.safeParse(source);
|
|
300
|
+
return filesystem.success ? [filesystem.data] : [];
|
|
301
|
+
});
|
|
302
|
+
return (sources.length > 0 ? sources : [content ?? {}]).map((globs) => ({
|
|
303
|
+
exclude: globs.exclude ?? DEFAULT_CONTENT_EXCLUDE,
|
|
304
|
+
include: globs.include ?? DEFAULT_CONTENT_INCLUDE,
|
|
305
|
+
root: globs.root ?? "docs",
|
|
306
|
+
}));
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
/** The content roots the project's config names, loaded as written. */
|
|
310
|
+
const configContentGlobs = async (root: string): Promise<ContentGlobs[]> => {
|
|
311
|
+
const file = findConfigFile(root);
|
|
312
|
+
let raw: z.infer<typeof rawContentSchema> = {};
|
|
313
|
+
if (file) {
|
|
314
|
+
try {
|
|
315
|
+
const parsed = rawContentSchema.safeParse(
|
|
316
|
+
await createModuleLoader()(file)
|
|
317
|
+
);
|
|
318
|
+
raw = parsed.success ? parsed.data : {};
|
|
319
|
+
} catch {
|
|
320
|
+
// A config that won't load is already reported by the config check;
|
|
321
|
+
// its content still gets the zero-config scan.
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return contentGlobs(raw);
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
const isPathKey = (segment: PropertyKey): segment is number | string =>
|
|
328
|
+
typeof segment !== "symbol";
|
|
329
|
+
|
|
330
|
+
// Zod's own wording for an unknown key; a removed field's hint replaces it.
|
|
331
|
+
const PLAIN_UNKNOWN_KEY = "Unrecognized key";
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* The removed fields among one page's front matter issues, each at its own
|
|
335
|
+
* line. Only issues the page schema words as a removed-field hint count: a
|
|
336
|
+
* key a project declares through `frontmatter.extend` is unknown to the bare
|
|
337
|
+
* schema, and any other invalid value was already an error on Blume 1.
|
|
338
|
+
*/
|
|
339
|
+
const removedFieldFindings = (
|
|
340
|
+
file: string,
|
|
341
|
+
text: string,
|
|
342
|
+
issues: readonly z.core.$ZodIssue[]
|
|
343
|
+
): Diagnostic[] =>
|
|
344
|
+
issues.flatMap((issue) => {
|
|
345
|
+
if (
|
|
346
|
+
issue.code !== "unrecognized_keys" ||
|
|
347
|
+
issue.message.startsWith(PLAIN_UNKNOWN_KEY)
|
|
348
|
+
) {
|
|
349
|
+
return [];
|
|
350
|
+
}
|
|
351
|
+
const path = issue.path.filter(isPathKey);
|
|
352
|
+
const position =
|
|
353
|
+
locateFrontmatterKey(text, [...path, ...issue.keys.slice(0, 1)]) ??
|
|
354
|
+
locateFrontmatterKey(text, path);
|
|
355
|
+
return [
|
|
356
|
+
{
|
|
357
|
+
code: "BLUME_FRONTMATTER_INVALID",
|
|
358
|
+
column: position?.column,
|
|
359
|
+
file,
|
|
360
|
+
line: position?.line,
|
|
361
|
+
message: issue.message,
|
|
362
|
+
severity: "error",
|
|
363
|
+
} satisfies Diagnostic,
|
|
364
|
+
];
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
/** The removed front matter fields in one page, or none it can't parse. */
|
|
368
|
+
const pageFindings = async (file: string): Promise<Diagnostic[]> => {
|
|
369
|
+
const text = await readFile(file, "utf-8");
|
|
370
|
+
let parsed: ReturnType<typeof pageMetaSchema.safeParse>;
|
|
371
|
+
try {
|
|
372
|
+
parsed = pageMetaSchema.safeParse(matter(text).data);
|
|
373
|
+
} catch {
|
|
374
|
+
// Unparseable front matter fails the build with its own diagnostic.
|
|
375
|
+
return [];
|
|
376
|
+
}
|
|
377
|
+
return parsed.success
|
|
378
|
+
? []
|
|
379
|
+
: removedFieldFindings(file, text, parsed.error.issues);
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* A finding for each front matter field Blume 2 removed, across the project's
|
|
384
|
+
* local content. A page with one fails validation and drops out of the build,
|
|
385
|
+
* which the config and components checks alone would report as ready.
|
|
386
|
+
*/
|
|
387
|
+
const frontmatterFindings = async (root: string): Promise<Diagnostic[]> => {
|
|
388
|
+
const roots = await configContentGlobs(root);
|
|
389
|
+
const matches = await Promise.all(
|
|
390
|
+
roots.map((globs) => {
|
|
391
|
+
const cwd = resolve(root, globs.root);
|
|
392
|
+
return existsSync(cwd)
|
|
393
|
+
? glob(globs.include, {
|
|
394
|
+
absolute: true,
|
|
395
|
+
cwd,
|
|
396
|
+
ignore: [...globs.exclude, ...baselineScanIgnore()],
|
|
397
|
+
onlyFiles: true,
|
|
398
|
+
})
|
|
399
|
+
: [];
|
|
400
|
+
})
|
|
401
|
+
);
|
|
402
|
+
// Two sources can share a folder; each page is checked once.
|
|
403
|
+
const files = [...new Set(matches.flat())].toSorted();
|
|
404
|
+
const findings = await Promise.all(files.map(pageFindings));
|
|
405
|
+
return findings.flat();
|
|
406
|
+
};
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Run one check, turning the {@link BlumeError} it throws into its findings:
|
|
410
|
+
* each config issue or `components.ts` entry on its own, or the one diagnostic
|
|
411
|
+
* any other check has.
|
|
412
|
+
*/
|
|
413
|
+
const findingsOf = async (
|
|
414
|
+
check: () => Promise<void>
|
|
415
|
+
): Promise<Diagnostic[]> => {
|
|
416
|
+
try {
|
|
417
|
+
await check();
|
|
418
|
+
return [];
|
|
419
|
+
} catch (error) {
|
|
420
|
+
if (
|
|
421
|
+
error instanceof ConfigValidationError ||
|
|
422
|
+
error instanceof ComponentOverridesError
|
|
423
|
+
) {
|
|
424
|
+
return error.issues;
|
|
425
|
+
}
|
|
426
|
+
if (error instanceof BlumeError) {
|
|
427
|
+
return [error.diagnostic];
|
|
428
|
+
}
|
|
429
|
+
throw error;
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Check a project against this version of Blume: its config through the
|
|
435
|
+
* loader (every invalid field, each with its line and replacement), its
|
|
436
|
+
* `components.ts` through the static override planner (each entry at its
|
|
437
|
+
* line), its pages' front matter for removed fields, and its package.json
|
|
438
|
+
* scripts for `blume build` flags that no longer exist. Returns the failures;
|
|
439
|
+
* an empty list means the project is ready.
|
|
440
|
+
*/
|
|
441
|
+
export const collectUpgradeFindings = async (
|
|
442
|
+
root: string
|
|
443
|
+
): Promise<Diagnostic[]> => {
|
|
444
|
+
const componentsFile = findComponentsFile(root);
|
|
445
|
+
return [
|
|
446
|
+
...(await findingsOf(async () => {
|
|
447
|
+
await loadConfig(root);
|
|
448
|
+
})),
|
|
449
|
+
...(componentsFile
|
|
450
|
+
? await findingsOf(async () => {
|
|
451
|
+
analyzeComponentOverrides(
|
|
452
|
+
await readFile(componentsFile, "utf-8"),
|
|
453
|
+
componentsFile
|
|
454
|
+
);
|
|
455
|
+
})
|
|
456
|
+
: []),
|
|
457
|
+
...(await frontmatterFindings(root)),
|
|
458
|
+
...(await scriptFindings(root)),
|
|
459
|
+
];
|
|
460
|
+
};
|
|
461
|
+
|
|
462
|
+
/** A finding as plain text for the agent: where, what, and the fix. */
|
|
463
|
+
const plainFinding = (finding: Diagnostic, root: string): string => {
|
|
464
|
+
const where = finding.file
|
|
465
|
+
? `${relative(root, finding.file)}${finding.line === undefined ? "" : `:${finding.line}`}`
|
|
466
|
+
: "blume.config.ts";
|
|
467
|
+
const fix = finding.suggestion ? `\n Fix: ${finding.suggestion}` : "";
|
|
468
|
+
return `- ${where} (${finding.code})\n ${finding.message.replaceAll("\n", "\n ")}${fix}`;
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* The handoff prompt: the findings inline (they're few, and each already
|
|
473
|
+
* names its replacement), where the guide is, and the ground rules — change
|
|
474
|
+
* the config's shape, never the site's behavior, and verify with the site's
|
|
475
|
+
* own checks, run through the project's package runner (`npx`, `pnpm exec`),
|
|
476
|
+
* since a local install puts no `blume` on PATH.
|
|
477
|
+
*/
|
|
478
|
+
export const upgradePrompt = (options: {
|
|
479
|
+
findings: Diagnostic[];
|
|
480
|
+
guidePath: string;
|
|
481
|
+
root: string;
|
|
482
|
+
runner: string;
|
|
483
|
+
version: string;
|
|
484
|
+
}): string =>
|
|
485
|
+
`Upgrade this Blume project to Blume ${options.version}. \`blume upgrade\` has bumped the \`blume\` dependency in package.json where it could; what's left is the config.
|
|
486
|
+
|
|
487
|
+
The upgrade guide is at ${options.guidePath} (online at ${UPGRADE_GUIDE_URL}). It covers every change between Blume 1 and 2 with before-and-after examples: search, deployment, content sources, API references, analytics, and Ask AI become adapters imported from \`blume/*\` subpaths; the machine-readable settings move from \`ai\` to \`agents\`; and \`components.ts\` entries must be one of the static forms.
|
|
488
|
+
|
|
489
|
+
\`blume upgrade\` found:
|
|
490
|
+
|
|
491
|
+
${options.findings.map((finding) => plainFinding(finding, options.root)).join("\n\n")}
|
|
492
|
+
|
|
493
|
+
Work through every finding:
|
|
494
|
+
1. Read the guide section for each change before editing.
|
|
495
|
+
2. Rewrite the config to the Blume 2 form, adding the adapter imports it needs. Keep the site's behavior the same: the same content, routes, search backend, deployment target, analytics, and credentials (keep reading secrets from the same environment variables).
|
|
496
|
+
3. The config loader reports every invalid field at once, but some changes only surface once earlier ones are fixed, so rerun \`${options.runner} blume doctor\` after each round of edits.
|
|
497
|
+
4. Never delete content, or remove a setting only to silence an error; if something needs a human decision, leave it and say so in your summary.
|
|
498
|
+
|
|
499
|
+
When \`${options.runner} blume doctor\` reports no errors, run \`${options.runner} blume build\` and fix anything it reports until it succeeds.`;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/cli/commands/dev.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"import { dev } from \"astro\";\nimport { watch } from \"chokidar\";\nimport { defineCommand } from \"citty\";\nimport { debounce } from \"perfect-debounce\";\n\nimport { generateRuntime } from \"../../astro/generate.ts\";\nimport {\n refreshBlumeContent,\n showBlumeErrorOverlay,\n} from \"../../astro/integration.ts\";\nimport { scanProject } from \"../../core/project-graph.ts\";\nimport { resolveRuntimeDir } from \"../../core/project.ts\";\nimport { parsePort } from \"../args.ts\";\nimport { commandMeta } from \"../command-meta.ts\";\nimport {\n acquireDevLock,\n describeDevLock,\n DevLockHeldError,\n updateDevLockPort,\n} from \"../dev-lock.ts\";\nimport { normalizeHost } from \"../host-args.ts\";\nimport { logger, reportDiagnostics } from \"../log.ts\";\nimport { prepareProject } from \"../prepare.ts\";\n\n/**\n * A fingerprint of the route set: the sorted `path entryId` pairs. It changes\n * when a page is added, removed, or renamed (a folder rename shifts many at\n * once) but stays equal across pure body edits — so the dev loop can tell a\n * \"structural\" change (needs a content re-sync) from a hot-reloadable one.\n */\nconst routeSignature = (\n routes: readonly { entryId: string; path: string }[]\n): string =>\n routes\n .map((route) => `${route.path} ${route.entryId}`)\n .toSorted()\n .join(\"\\n\");\n\nexport const devCommand = defineCommand({\n args: {\n \"content-dir\": {\n description: \"Content folder to scan, overriding config (content.root).\",\n type: \"string\",\n },\n debug: {\n description: \"Verbose Astro/Vite logging for troubleshooting.\",\n type: \"boolean\",\n },\n host: { description: \"Network host to bind.\", type: \"string\" },\n open: { description: \"Open the browser on start.\", type: \"boolean\" },\n port: { description: \"Port to listen on.\", type: \"string\" },\n preview: {\n description: \"Include drafts and unpublished CMS content.\",\n type: \"boolean\",\n },\n strict: { description: \"Fail on diagnostics.\", type: \"boolean\" },\n },\n meta: commandMeta.dev,\n async run({ args }) {\n const root = process.cwd();\n const preview = args.preview ?? false;\n const overrides = args[\"content-dir\"]\n ? { contentRoot: args[\"content-dir\"] }\n : undefined;\n // Astro's dev server defaults to 4321 when no port is passed. Feeding the\n // resolved URL in as the `deployment.site` fallback lets site-gated features\n // (OG images, canonicals, sitemap) work locally without configuring a site.\n const explicitPort = parsePort(args.port);\n const port = explicitPort ?? 4321;\n let devServerUrl = `http://localhost:${port}`;\n\n // Claim the shared `.blume` dir BEFORE preparing: `prepareProject`\n // regenerates the runtime, so even a refused second dev server would\n // otherwise clobber the running one's generated tree (with this\n // invocation's port baked in) on its way out. The claim is atomic, so two\n // simultaneous starts can't both win. Dev never relocates the runtime dir,\n // so the lock always lives at `<root>/.blume`.\n const outDir = resolveRuntimeDir(root);\n let releaseLock: () => void;\n try {\n releaseLock = acquireDevLock(outDir, port);\n } catch (error) {\n if (error instanceof DevLockHeldError) {\n logger.error(\n `A \\`blume dev\\` server is already running${describeDevLock(error.lock)} in this project. Reuse that server instead of starting a second one — two dev servers would corrupt the shared .blume dir. If it crashed, delete .blume/dev.lock.`\n );\n process.exit(1);\n }\n throw error;\n }\n process.on(\"exit\", releaseLock);\n\n const project = await prepareProject({\n devServerUrl,\n mode: \"dev\",\n overrides,\n preview,\n root,\n strict: args.strict,\n });\n\n // A factory so the regenerate loop can recreate the server when a\n // structural (route-set) change can't be re-synced in place (see below).\n // `open` is honored on first boot only — a restart must not reopen the\n // browser.\n const createServer = (listenPort: number | undefined, open: boolean) =>\n dev({\n logLevel: args.debug ? \"debug\" : \"info\",\n root: project.context.outDir,\n server: { host: normalizeHost(args.host), open, port: listenPort },\n });\n\n let server = await createServer(explicitPort, args.open ?? false);\n\n // Vite bumps to the next free port when the default is taken, so record\n // the port the server actually bound — the lock's URL is what a refused\n // second invocation tells its caller to reuse. The site fallback baked\n // into the runtime also carries the port, so it must follow suit (below,\n // once the regeneration closure exists).\n const boundPort = server.address.port;\n if (boundPort !== port) {\n updateDevLockPort(outDir, boundPort);\n devServerUrl = `http://localhost:${boundPort}`;\n }\n\n // Mirror any initial diagnostics into the browser overlay now the server\n // (and its HMR channel) is up.\n showBlumeErrorOverlay(project.diagnostics);\n\n let lastSignature = routeSignature(project.manifest.routes);\n\n // Watch user inputs and regenerate the runtime data on change. A body edit\n // hot-reloads via Vite (fast path). A route-set change also needs Astro's\n // content store re-synced: its glob watcher misses directory renames, so a\n // renamed page would 404 (`getEntry` reads a stale store). Astro hands the\n // integration `refreshContent` for exactly that — a full loader run\n // against the live server, after which Astro's own store watcher clears\n // the route cache and reloads the browser. Only a server that registered\n // no refresh (none since Astro 5) falls back to a cold restart: stop,\n // then bring up a fresh container whose cold sync re-globs everything.\n // perfect-debounce both debounces the watch burst (80ms) and\n // single-flights the scan: a\n // trigger during a run never starts a second run, only marks one trailing\n // rerun after the current settles. Both halves are load-bearing — a plain\n // debounce once let bursts stack overlapping scans until the heap was\n // exhausted (observed as an OOM after minutes of looping). The contract is\n // pinned by test/dev-debounce.test.ts. The task must not reject (the\n // library re-invokes it from an unhandled .finally), so the body catches\n // its own errors and always resolves.\n const regenerate = debounce(async () => {\n try {\n const next = await scanProject(root, {\n devServerUrl,\n mode: \"dev\",\n overrides,\n preview,\n });\n const nextSignature = routeSignature(next.manifest.routes);\n const structural = nextSignature !== lastSignature;\n // Generate first: the new runtime data (and any staged remote content)\n // is on disk and published before the store re-syncs against it.\n await generateRuntime(next);\n if (structural && !(await refreshBlumeContent())) {\n await server.stop();\n server = await createServer(boundPort, false);\n }\n // Commit the signature only after the (re)generation succeeded. If the\n // re-sync or restart above throws mid-sequence, the signature stays\n // stale so the next watch event retries the structural path.\n lastSignature = nextSignature;\n // Surface any content/config errors in the terminal AND the browser\n // overlay. The terminal report is not redundant: the overlay only\n // shows once the browser has connected, and it clears on the next HMR\n // update.\n reportDiagnostics(next.diagnostics, root);\n showBlumeErrorOverlay(next.diagnostics);\n } catch (error) {\n // SAFETY: regeneration failures come from the generator and Astro's\n // server API, which raise Error instances; only the message is shown.\n logger.error(`Regeneration failed: ${(error as Error).message}`);\n }\n }, 80);\n\n // The runtime prepared above baked the *requested* port into the site\n // fallback; if Vite bumped it, regenerate so OG images, canonicals, and\n // other site-gated URLs point at the port actually serving.\n if (boundPort !== port) {\n void regenerate();\n }\n\n // Content is watched per source (filesystem uses fs.watch; remote sources\n // are frozen for the session). The remaining project inputs — user pages,\n // config, theme, and component overrides — are watched directly.\n const dirTargets = [project.context.pagesRoot].filter(\n (target) => target !== null\n );\n const fileTargets = [\n project.context.configFile,\n project.context.themeFile,\n project.context.componentsFile,\n ].filter((target) => target !== null);\n\n // chokidar handles what raw fs.watch made us hand-roll: recursive\n // directory watching on every platform, and single files surviving a\n // rename-replace save (vim and most \"atomic save\" editors), which orphans\n // an inode-tracking fs.watch watcher after the first write.\n const projectWatcher = watch([...dirTargets, ...fileTargets], {\n ignoreInitial: true,\n }).on(\"all\", regenerate);\n const disposers = [\n ...project.sources.map((source) => source.watch?.(regenerate)),\n () => {\n void projectWatcher.close();\n },\n ].filter((dispose) => dispose !== undefined);\n\n const shutdown = async () => {\n for (const dispose of disposers) {\n dispose();\n }\n releaseLock();\n await server.stop();\n process.exit(0);\n };\n\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n },\n});\n"
|
|
6
|
-
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "350EDAE5A410927464756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|