blume 2.1.2 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +133 -0
- package/README.md +4 -4
- package/dist/cli/{chunk-74wfhv79.js → chunk-05f21r8h.js} +1 -1
- package/dist/cli/{chunk-9qzgg6mj.js → chunk-1cm0h819.js} +3 -3
- package/dist/cli/{chunk-nbyvgnnm.js → chunk-1rkxzg3n.js} +104 -47
- package/dist/cli/chunk-1rkxzg3n.js.map +36 -0
- package/dist/cli/{chunk-desvm72z.js → chunk-2nr29y95.js} +22 -26
- package/dist/cli/chunk-2nr29y95.js.map +13 -0
- package/dist/cli/{chunk-32khwcb6.js → chunk-49r370mb.js} +42 -69
- package/dist/cli/{chunk-32khwcb6.js.map → chunk-49r370mb.js.map} +9 -10
- package/dist/cli/{chunk-ms9z66nz.js → chunk-4rftmttv.js} +2 -2
- package/dist/cli/{chunk-s0bdnc7v.js → chunk-79bzzkx4.js} +5 -4
- package/dist/cli/chunk-79bzzkx4.js.map +10 -0
- package/dist/cli/{chunk-hvcxng5f.js → chunk-7tekknev.js} +6 -6
- package/dist/cli/{chunk-dv2z0rzf.js → chunk-8b489v1b.js} +38 -13
- package/dist/cli/{chunk-dv2z0rzf.js.map → chunk-8b489v1b.js.map} +5 -4
- package/dist/cli/{chunk-0pmb4tr4.js → chunk-8f8xw4x2.js} +1195 -222
- package/dist/cli/chunk-8f8xw4x2.js.map +44 -0
- package/dist/cli/chunk-96snx8yy.js +329 -0
- package/dist/cli/chunk-96snx8yy.js.map +13 -0
- package/dist/cli/{chunk-ckrcm08h.js → chunk-a3ydrqny.js} +48 -62
- package/dist/cli/{chunk-ckrcm08h.js.map → chunk-a3ydrqny.js.map} +4 -5
- package/dist/cli/{chunk-bxwhtvw8.js → chunk-ahc5gc9h.js} +5 -5
- package/dist/cli/{chunk-dpy8qdjf.js → chunk-as09pafp.js} +73 -182
- package/dist/cli/chunk-as09pafp.js.map +18 -0
- package/dist/cli/{chunk-tfycddbt.js → chunk-bjk964fp.js} +2 -2
- package/dist/cli/{chunk-gfc5fqvf.js → chunk-br0n8n3e.js} +18 -18
- package/dist/cli/{chunk-gfc5fqvf.js.map → chunk-br0n8n3e.js.map} +1 -1
- package/dist/cli/{chunk-297ajdcv.js → chunk-c69tw29j.js} +6 -6
- package/dist/cli/{chunk-297ajdcv.js.map → chunk-c69tw29j.js.map} +3 -3
- package/dist/cli/chunk-cn3dy3hz.js +146 -0
- package/dist/cli/chunk-cn3dy3hz.js.map +11 -0
- package/dist/cli/{chunk-124fvmzq.js → chunk-dm4mg9bj.js} +11064 -8742
- package/dist/cli/{chunk-124fvmzq.js.map → chunk-dm4mg9bj.js.map} +78 -64
- package/dist/cli/{chunk-dqhg54mr.js → chunk-dmx6cezx.js} +1 -1
- package/dist/cli/{chunk-60hz265r.js → chunk-dpcahcrb.js} +24 -11
- package/dist/cli/chunk-dpcahcrb.js.map +10 -0
- package/dist/cli/{chunk-a57yh0h9.js → chunk-dyk3r7jw.js} +7 -7
- package/dist/cli/{chunk-a57yh0h9.js.map → chunk-dyk3r7jw.js.map} +1 -1
- package/dist/cli/{chunk-twy7psdz.js → chunk-enk76qd5.js} +14 -10
- package/dist/cli/chunk-enk76qd5.js.map +10 -0
- package/dist/cli/{chunk-k3gr1nm9.js → chunk-fqy4n3q2.js} +13 -16
- package/dist/cli/{chunk-k3gr1nm9.js.map → chunk-fqy4n3q2.js.map} +3 -3
- package/dist/cli/{chunk-sc93apfs.js → chunk-frk2wdq1.js} +17 -17
- package/dist/cli/{chunk-sc93apfs.js.map → chunk-frk2wdq1.js.map} +2 -2
- package/dist/cli/{chunk-kdpzw38a.js → chunk-gprwej7h.js} +95 -7
- package/dist/cli/chunk-gprwej7h.js.map +11 -0
- package/dist/cli/chunk-kkrteb15.js +157 -0
- package/dist/cli/chunk-kkrteb15.js.map +10 -0
- package/dist/cli/{chunk-ave1wcbr.js → chunk-m9bp2hc1.js} +1 -1
- package/dist/cli/{chunk-58bt3hag.js → chunk-mrvh4c88.js} +4 -4
- package/dist/cli/{chunk-5cmts6dv.js → chunk-p8zg3a2h.js} +7 -7
- package/dist/cli/{chunk-5cmts6dv.js.map → chunk-p8zg3a2h.js.map} +1 -1
- package/dist/cli/{chunk-0w6hs479.js → chunk-rkqae7kh.js} +30 -18
- package/dist/cli/chunk-rkqae7kh.js.map +10 -0
- package/dist/cli/{chunk-bqxaqn5p.js → chunk-t5xx74rd.js} +8 -8
- package/dist/cli/{chunk-bqxaqn5p.js.map → chunk-t5xx74rd.js.map} +1 -1
- package/dist/cli/{chunk-1f882900.js → chunk-th0pgaj5.js} +2 -2
- package/dist/cli/{chunk-dhwtqnnd.js → chunk-vnbvhgmd.js} +2 -2
- package/dist/cli/{chunk-gxtg6ed2.js → chunk-vzy9rh6y.js} +21 -21
- package/dist/cli/{chunk-gxtg6ed2.js.map → chunk-vzy9rh6y.js.map} +3 -3
- package/dist/cli/{chunk-j1x92mx9.js → chunk-w6e455pz.js} +1 -1
- package/dist/cli/chunk-wehv26ry.js +155 -0
- package/dist/cli/chunk-wehv26ry.js.map +11 -0
- package/dist/cli/{chunk-y4msrwm9.js → chunk-xgq4eytj.js} +15 -15
- package/dist/cli/{chunk-36bxs9c7.js → chunk-xt0qvz1t.js} +27 -23
- package/dist/cli/chunk-xt0qvz1t.js.map +10 -0
- package/dist/cli/index.js +78 -42
- package/dist/cli/index.js.map +7 -6
- package/dist/types/ai/changelog-components.d.ts +18 -0
- package/dist/types/ai/changelog-markdown.d.ts +12 -0
- package/dist/types/ai/openapi-components.d.ts +7 -7
- package/dist/types/ai/operation-details.d.ts +39 -0
- package/dist/types/ai/relative-links.d.ts +3 -1
- package/dist/types/ai/serializers.d.ts +6 -4
- package/dist/types/analytics/head.d.ts +4 -2
- package/dist/types/analytics/script.d.ts +8 -2
- package/dist/types/components/content/youtube.d.ts +20 -0
- package/dist/types/components/layout/nav-utils.d.ts +8 -0
- package/dist/types/components/openapi/example-panels.d.ts +33 -0
- package/dist/types/components/openapi/helpers.d.ts +53 -11
- package/dist/types/components/openapi/snippets.d.ts +7 -1
- package/dist/types/core/alert-diagnostics.d.ts +10 -0
- package/dist/types/core/builtin-tags.d.ts +16 -0
- package/dist/types/core/changelog-list.d.ts +48 -0
- package/dist/types/core/closest-match.d.ts +6 -0
- package/dist/types/core/code-fence-diagnostics.d.ts +18 -0
- package/dist/types/core/code-fences.d.ts +8 -1
- package/dist/types/core/config-input.d.ts +1 -1
- package/dist/types/core/content-assets.d.ts +16 -18
- package/dist/types/core/diagnostics.d.ts +14 -0
- package/dist/types/core/directive-diagnostics.d.ts +22 -8
- package/dist/types/core/former-routes.d.ts +14 -0
- package/dist/types/core/github.d.ts +5 -4
- package/dist/types/core/heading-markers.d.ts +65 -2
- package/dist/types/core/hidden-pages.d.ts +3 -0
- package/dist/types/core/includes.d.ts +23 -0
- package/dist/types/core/last-modified.d.ts +18 -6
- package/dist/types/core/links.d.ts +42 -2
- package/dist/types/core/load-module.d.ts +19 -4
- package/dist/types/core/manifest.d.ts +14 -1
- package/dist/types/core/markdown-mirrors.d.ts +22 -0
- package/dist/types/core/mdx-elements.d.ts +32 -0
- package/dist/types/core/mdx-syntax.d.ts +100 -0
- package/dist/types/core/meta-diagnostics.d.ts +7 -0
- package/dist/types/core/meta.d.ts +32 -5
- package/dist/types/core/nav-diagnostics.d.ts +9 -2
- package/dist/types/core/navigation.d.ts +13 -0
- package/dist/types/core/ordering-prefix.d.ts +6 -0
- package/dist/types/core/pinned-ids.d.ts +23 -0
- package/dist/types/core/project-graph.d.ts +9 -1
- package/dist/types/core/redirect-patterns.d.ts +18 -0
- package/dist/types/core/relative-files.d.ts +31 -0
- package/dist/types/core/schema.d.ts +267 -7
- package/dist/types/core/sources/normalize.d.ts +101 -9
- package/dist/types/core/sources/types.d.ts +16 -0
- package/dist/types/core/static-files.d.ts +10 -0
- package/dist/types/core/static-host.d.ts +42 -0
- package/dist/types/core/svg-images.d.ts +26 -0
- package/dist/types/core/syntax-diagnostics.d.ts +14 -0
- package/dist/types/core/types.d.ts +42 -1
- package/dist/types/deploy/generated-files.d.ts +41 -0
- package/dist/types/deploy/redirects.d.ts +21 -7
- package/dist/types/markdown/code-title.d.ts +9 -5
- package/dist/types/markdown/directives.d.ts +8 -0
- package/dist/types/markdown/fence-language.d.ts +51 -0
- package/dist/types/markdown/fence-meta.d.ts +5 -0
- package/dist/types/markdown/github-alerts.d.ts +35 -0
- package/dist/types/openapi/asyncapi.d.ts +6 -5
- package/dist/types/openapi/checks.d.ts +10 -5
- package/dist/types/openapi/model.d.ts +55 -8
- package/dist/types/openapi/parse.d.ts +4 -1
- package/dist/types/sources/filesystem.d.ts +14 -4
- package/dist/types/sources/mdx-remote.d.ts +6 -3
- package/dist/types/sources/registry.d.ts +3 -3
- package/dist/types/theme/color.d.ts +33 -0
- package/dist/types/theme/palette.d.ts +122 -0
- package/docs/01-quickstart.mdx +1 -1
- package/docs/02-deployment.mdx +23 -8
- package/docs/04-migrating.mdx +16 -4
- package/docs/advanced/changelog.mdx +27 -1
- package/docs/advanced/skills.mdx +1 -1
- package/docs/cli/audit.mdx +1 -1
- package/docs/cli/doctor.mdx +2 -2
- package/docs/cli/evals.mdx +1 -1
- package/docs/cli/index.mdx +4 -2
- package/docs/cli/validate.mdx +10 -7
- package/docs/configuration/analytics.mdx +2 -0
- package/docs/configuration/customization.mdx +3 -1
- package/docs/configuration/index.mdx +2 -2
- package/docs/configuration/theming.mdx +5 -1
- package/docs/content/components.mdx +26 -6
- package/docs/content/frontmatter.mdx +1 -1
- package/docs/content/includes.mdx +6 -2
- package/docs/content/index.mdx +11 -1
- package/docs/content/islands.mdx +2 -0
- package/docs/content/meta.mdx +9 -3
- package/docs/content/navigation.mdx +14 -6
- package/docs/content/sources/obsidian.mdx +1 -1
- package/docs/content/sources/remote-mdx.mdx +3 -1
- package/docs/content/syntax.mdx +76 -8
- package/docs/content/variables.mdx +3 -1
- package/docs/discoverability/agent-discovery.mdx +1 -1
- package/docs/discoverability/json-api.mdx +1 -1
- package/docs/discoverability/llms-txt.mdx +1 -1
- package/docs/discoverability/markdown.mdx +2 -2
- package/docs/discoverability/open-graph.mdx +1 -1
- package/docs/discoverability/sitemap-and-robots.mdx +1 -1
- package/docs/references/graphql.mdx +2 -0
- package/docs/references/openapi.mdx +45 -7
- package/package.json +10 -9
- package/skills/blume/SKILL.md +2 -2
- package/skills/blume-migrate/SKILL.md +49 -27
- package/skills/blume-migrate/references/docsify.md +262 -0
- package/skills/blume-migrate/references/docus.md +298 -0
- package/skills/blume-migrate/references/docusaurus.md +3 -3
- package/skills/blume-migrate/references/fern.md +327 -0
- package/skills/blume-migrate/references/fumadocs.md +1 -1
- package/skills/blume-migrate/references/gitbook.md +267 -0
- package/skills/blume-migrate/references/github-wiki.md +259 -0
- package/skills/blume-migrate/references/jekyll.md +253 -0
- package/skills/blume-migrate/references/mdbook.md +256 -0
- package/skills/blume-migrate/references/mintlify.md +5 -5
- package/skills/blume-migrate/references/mkdocs.md +236 -0
- package/skills/blume-migrate/references/monorepo.md +20 -8
- package/skills/blume-migrate/references/nextra.md +2 -2
- package/skills/blume-migrate/references/readme.md +257 -0
- package/skills/blume-migrate/references/redocly.md +198 -0
- package/skills/blume-migrate/references/starlight.md +3 -3
- package/skills/blume-migrate/references/vitepress.md +204 -0
- package/skills/blume-migrate/references/vuepress.md +271 -0
- package/skills/blume-migrate/scripts/docsify-codemod.mjs +2387 -0
- package/skills/blume-migrate/scripts/docus-codemod.mjs +2542 -0
- package/skills/blume-migrate/scripts/fern-codemod.mjs +2633 -0
- package/skills/blume-migrate/scripts/github-wiki-codemod.mjs +2808 -0
- package/skills/blume-migrate/scripts/include-excerpts.mjs +649 -0
- package/skills/blume-migrate/scripts/jekyll-codemod.mjs +3649 -0
- package/skills/blume-migrate/scripts/mintlify-codemod.mjs +17 -13
- package/skills/blume-migrate/scripts/mkdocs-codemod.mjs +2526 -0
- package/skills/blume-migrate/scripts/operation-routes.mjs +508 -0
- package/skills/blume-migrate/scripts/pin-heading-ids.mjs +1049 -0
- package/skills/blume-migrate/scripts/readme-codemod.mjs +4139 -0
- package/skills/blume-migrate/scripts/vitepress-codemod.mjs +1511 -0
- package/src/ai/changelog-components.ts +24 -0
- package/src/ai/changelog-markdown.ts +45 -41
- package/src/ai/component-markdown.ts +22 -9
- package/src/ai/llms.ts +36 -5
- package/src/ai/markdown.ts +2 -2
- package/src/ai/openapi-components.ts +25 -9
- package/src/ai/operation-details.ts +208 -0
- package/src/ai/relative-links.ts +48 -8
- package/src/ai/serializers.ts +7 -6
- package/src/ai/site-skill.ts +6 -2
- package/src/analytics/head.ts +11 -5
- package/src/analytics/script.ts +13 -3
- package/src/astro/generate.ts +32 -6
- package/src/astro/index.ts +1 -0
- package/src/astro/integration.ts +27 -1
- package/src/astro/mdx-source-errors.ts +46 -0
- package/src/astro/templates.ts +89 -185
- package/src/audit/checks/redirects.ts +5 -1
- package/src/audit/redirects.ts +36 -19
- package/src/audit/report.ts +22 -9
- package/src/audit/run.ts +12 -28
- package/src/audit/terms.ts +23 -0
- package/src/audit/url.ts +2 -2
- package/src/cli/build-failure.ts +256 -7
- package/src/cli/command-meta.ts +1 -1
- package/src/cli/commands/audit.ts +1 -1
- package/src/cli/commands/build.ts +12 -3
- package/src/cli/commands/check.ts +13 -2
- package/src/cli/commands/dev.ts +1 -1
- package/src/cli/commands/doctor.ts +4 -2
- package/src/cli/commands/init.ts +3 -3
- package/src/cli/commands/preview.ts +17 -1
- package/src/cli/commands/validate.ts +22 -10
- package/src/cli/prepare.ts +1 -1
- package/src/cli/preview-pages.ts +161 -0
- package/src/cli/unknown-flags.ts +1 -42
- package/src/components/code-copy.ts +51 -0
- package/src/components/code-language.ts +75 -0
- package/src/components/content/AccordionItem.astro +16 -1
- package/src/components/content/Callout.astro +11 -1
- package/src/components/content/Changelog.astro +189 -0
- package/src/components/content/CodeBlock.astro +8 -11
- package/src/components/content/Tabs.astro +16 -2
- package/src/components/content/YouTube.astro +6 -4
- package/src/components/content/code-block.ts +33 -0
- package/src/components/content/content-strings.ts +5 -1
- package/src/components/content/inline-markdown.ts +35 -8
- package/src/components/content/youtube.ts +49 -7
- package/src/components/layout/Analytics.astro +5 -1
- package/src/components/layout/NavTree.astro +8 -3
- package/src/components/layout/RootLayout.astro +18 -31
- package/src/components/layout/nav-utils.ts +14 -0
- package/src/components/layout/search/pagefind.ts +2 -1
- package/src/components/openapi/Operation.astro +4 -0
- package/src/components/openapi/PanelTabs.astro +9 -3
- package/src/components/openapi/RequestBody.astro +42 -8
- package/src/components/openapi/RequestPanel.astro +34 -53
- package/src/components/openapi/example-panels.ts +110 -0
- package/src/components/openapi/helpers.ts +195 -20
- package/src/components/openapi/operation-model.ts +63 -26
- package/src/components/openapi/request.ts +13 -0
- package/src/components/openapi/snippets.ts +14 -2
- package/src/core/alert-diagnostics.ts +89 -0
- package/src/core/builtin-tags.ts +76 -0
- package/src/core/changelog-list.ts +87 -0
- package/src/core/closest-match.ts +41 -0
- package/src/core/code-fence-diagnostics.ts +267 -0
- package/src/core/code-fences.ts +43 -7
- package/src/core/component-diagnostics.ts +65 -12
- package/src/core/config-input.ts +1 -1
- package/src/core/config.ts +46 -1
- package/src/core/content-assets.ts +64 -144
- package/src/core/diagnostics.ts +36 -3
- package/src/core/directive-diagnostics.ts +265 -47
- package/src/core/former-routes.ts +46 -0
- package/src/core/git-ignored.ts +53 -0
- package/src/core/github.ts +5 -4
- package/src/core/heading-markers.ts +156 -2
- package/src/core/hidden-pages.ts +64 -0
- package/src/core/includes.ts +181 -41
- package/src/core/last-modified.ts +47 -10
- package/src/core/links.ts +438 -83
- package/src/core/load-module.ts +98 -9
- package/src/core/manifest.ts +12 -9
- package/src/core/markdown-mirrors.ts +52 -0
- package/src/core/mdx-elements.ts +153 -0
- package/src/core/mdx-syntax.ts +377 -0
- package/src/core/meta-diagnostics.ts +134 -0
- package/src/core/meta.ts +154 -55
- package/src/core/nav-diagnostics.ts +16 -4
- package/src/core/navigation.ts +70 -10
- package/src/core/ordering-prefix.ts +22 -2
- package/src/core/pinned-ids.ts +141 -0
- package/src/core/project-graph.ts +221 -29
- package/src/core/redirect-patterns.ts +41 -0
- package/src/core/relative-files.ts +145 -0
- package/src/core/schema.ts +17 -3
- package/src/core/sources/mdx-remote.ts +75 -14
- package/src/core/sources/normalize.ts +885 -179
- package/src/core/sources/notion.ts +5 -4
- package/src/core/sources/obsidian.ts +2 -5
- package/src/core/sources/types.ts +17 -0
- package/src/core/static-files.ts +40 -0
- package/src/core/static-host.ts +125 -0
- package/src/core/svg-images.ts +98 -0
- package/src/core/syntax-diagnostics.ts +491 -0
- package/src/core/types.ts +43 -1
- package/src/deploy/artifacts.ts +2 -28
- package/src/deploy/generated-files.ts +128 -0
- package/src/deploy/platforms/vercel.ts +25 -1
- package/src/deploy/redirects.ts +43 -16
- package/src/deploy/sitemap.ts +2 -1
- package/src/markdown/base-links.ts +87 -6
- package/src/markdown/code-title.ts +29 -13
- package/src/markdown/content-assets.ts +210 -0
- package/src/markdown/directives.ts +69 -5
- package/src/markdown/fence-language.ts +106 -0
- package/src/markdown/fence-meta.ts +42 -0
- package/src/markdown/github-alerts.ts +172 -0
- package/src/markdown/heading-anchors.ts +265 -56
- package/src/markdown/include.ts +30 -3
- package/src/markdown/index.ts +145 -40
- package/src/markdown/prompt-text.ts +95 -0
- package/src/markdown/relative-links.ts +37 -2
- package/src/markdown/route-snapshot.ts +22 -12
- package/src/markdown/svg-fallback.ts +51 -0
- package/src/markdown/title-heading.ts +134 -0
- package/src/migrate/migrate.ts +127 -2
- package/src/og/card.ts +14 -4
- package/src/openapi/asyncapi.ts +14 -6
- package/src/openapi/checks.ts +160 -15
- package/src/openapi/model.ts +172 -33
- package/src/openapi/parse.ts +13 -4
- package/src/openapi/render-mdx.ts +55 -9
- package/src/openapi/source.ts +87 -6
- package/src/registry/eject.ts +0 -1
- package/src/search/documents.ts +10 -2
- package/src/sources/filesystem.ts +28 -3
- package/src/sources/mdx-remote.ts +7 -15
- package/src/theme/color.ts +14 -0
- package/src/theme/entry.ts +22 -1
- package/src/theme/palette.ts +74 -1
- package/dist/cli/chunk-0pmb4tr4.js.map +0 -35
- package/dist/cli/chunk-0w6hs479.js.map +0 -10
- package/dist/cli/chunk-150jk7km.js +0 -52
- package/dist/cli/chunk-150jk7km.js.map +0 -10
- package/dist/cli/chunk-36bxs9c7.js.map +0 -10
- package/dist/cli/chunk-53jqw8z0.js +0 -89
- package/dist/cli/chunk-53jqw8z0.js.map +0 -10
- package/dist/cli/chunk-60hz265r.js.map +0 -10
- package/dist/cli/chunk-desvm72z.js.map +0 -14
- package/dist/cli/chunk-dpy8qdjf.js.map +0 -17
- package/dist/cli/chunk-es8h0v3j.js +0 -441
- package/dist/cli/chunk-es8h0v3j.js.map +0 -11
- package/dist/cli/chunk-kdpzw38a.js.map +0 -11
- package/dist/cli/chunk-nbyvgnnm.js.map +0 -36
- package/dist/cli/chunk-s0bdnc7v.js.map +0 -10
- package/dist/cli/chunk-twy7psdz.js.map +0 -10
- package/dist/cli/chunk-ydp3065p.js +0 -64
- package/dist/cli/chunk-ydp3065p.js.map +0 -10
- /package/dist/cli/{chunk-74wfhv79.js.map → chunk-05f21r8h.js.map} +0 -0
- /package/dist/cli/{chunk-9qzgg6mj.js.map → chunk-1cm0h819.js.map} +0 -0
- /package/dist/cli/{chunk-ms9z66nz.js.map → chunk-4rftmttv.js.map} +0 -0
- /package/dist/cli/{chunk-hvcxng5f.js.map → chunk-7tekknev.js.map} +0 -0
- /package/dist/cli/{chunk-bxwhtvw8.js.map → chunk-ahc5gc9h.js.map} +0 -0
- /package/dist/cli/{chunk-tfycddbt.js.map → chunk-bjk964fp.js.map} +0 -0
- /package/dist/cli/{chunk-dqhg54mr.js.map → chunk-dmx6cezx.js.map} +0 -0
- /package/dist/cli/{chunk-ave1wcbr.js.map → chunk-m9bp2hc1.js.map} +0 -0
- /package/dist/cli/{chunk-58bt3hag.js.map → chunk-mrvh4c88.js.map} +0 -0
- /package/dist/cli/{chunk-1f882900.js.map → chunk-th0pgaj5.js.map} +0 -0
- /package/dist/cli/{chunk-dhwtqnnd.js.map → chunk-vnbvhgmd.js.map} +0 -0
- /package/dist/cli/{chunk-j1x92mx9.js.map → chunk-w6e455pz.js.map} +0 -0
- /package/dist/cli/{chunk-y4msrwm9.js.map → chunk-xgq4eytj.js.map} +0 -0
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/core/component-diagnostics.ts", "../src/
|
|
3
|
+
"sources": ["../src/core/component-diagnostics.ts", "../src/astro/islands.ts", "../src/astro/examples.ts", "../src/astro/runtime-deps.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import { relative } from \"pathe\";\n\nimport { BUILTIN_MDX_TAGS } from \"./builtin-tags.ts\";\nimport type { Diagnostic, PageRecord } from \"./types.ts\";\n\n/** `CardGroup` → `card-group`, matching registry item names. */\nconst toKebab = (tag: string): string =>\n tag\n .replaceAll(/(?<lower>[a-z0-9])(?<upper>[A-Z])/gu, \"$<lower>-$<upper>\")\n .toLowerCase();\n\n/**\n * Warn when an `.mdx` page uses a `<Component>` tag that resolves to nothing —\n * a built-in, an island, or a `components.ts` override — so a typo surfaces as a\n * friendly diagnostic (with a `blume add` hint where one exists) instead of a raw\n * MDX \"X is not defined\" build error. `extraTags` are the project's own known\n * components (islands + overrides); `registryNames` gates the install hint.\n */\nexport const validateUsedComponents = (\n pages: PageRecord[],\n extraTags: Set<string>,\n registryNames: Set<string>\n): Diagnostic[] => {\n const
|
|
6
|
-
"/**\n * The MDX component tags Blume ships (the keys of the catch-all's component map,\n * plus composed sub-parts like `Color.Item`/`Tree.File`). Used by the\n * missing-component diagnostic to tell an unknown `<Tag>` from a built-in. Keep\n * in sync with the component map in `astro/templates.ts`.\n */\nexport const BUILTIN_MDX_TAGS = new Set<string>([\n \"Accordion\",\n \"AccordionItem\",\n \"ApiOverview\",\n \"ApiTagOperations\",\n \"AutoTypeTable\",\n \"Badge\",\n \"Callout\",\n \"Card\",\n \"CardGroup\",\n \"CodeBlock\",\n \"CodeGroup\",\n \"Color\",\n \"Column\",\n \"Columns\",\n \"Component\",\n \"Diff\",\n \"Expandable\",\n \"FileTree\",\n \"Frame\",\n \"GithubInfo\",\n \"Icon\",\n // Conditionally imported by the catch-all, but `detectUsesMath` matches any\n // authored `<Math`, so it is always wired wherever it can appear.\n \"Math\",\n \"Operation\",\n \"Panel\",\n \"ParamField\",\n \"Prompt\",\n \"RequestExample\",\n \"ResponseExample\",\n \"ResponseField\",\n \"Step\",\n \"Steps\",\n \"Tab\",\n \"Tabs\",\n \"Tile\",\n \"Tooltip\",\n \"Tree\",\n \"TypeTable\",\n \"View\",\n \"Visibility\",\n \"YouTube\",\n]);\n",
|
|
5
|
+
"import { relative } from \"pathe\";\n\nimport { BUILTIN_CHILD_PROPS, BUILTIN_MDX_TAGS } from \"./builtin-tags.ts\";\nimport type { Diagnostic, PageRecord } from \"./types.ts\";\n\n/** `CardGroup` → `card-group`, matching registry item names. */\nconst toKebab = (tag: string): string =>\n tag\n .replaceAll(/(?<lower>[a-z0-9])(?<upper>[A-Z])/gu, \"$<lower>-$<upper>\")\n .toLowerCase();\n\nconst LIST = new Intl.ListFormat(\"en\", { type: \"conjunction\" });\n\n/**\n * Warn when an `.mdx` page uses a `<Component>` tag that resolves to nothing —\n * a built-in, an island, or a `components.ts` override — so a typo surfaces as a\n * friendly diagnostic (with a `blume add` hint where one exists) instead of a raw\n * MDX \"X is not defined\" build error. `extraTags` are the project's own known\n * components (islands + overrides); `registryNames` gates the install hint.\n * One warning per tag names every page that uses it, anchored to the first.\n */\nexport const validateUsedComponents = (\n pages: PageRecord[],\n extraTags: Set<string>,\n registryNames: Set<string>\n): Diagnostic[] => {\n const users = new Map<string, PageRecord[]>();\n for (const page of pages) {\n for (const tag of page.componentsUsed ?? []) {\n if (!(BUILTIN_MDX_TAGS.has(tag) || extraTags.has(tag))) {\n users.set(tag, [...(users.get(tag) ?? []), page]);\n }\n }\n }\n return [...users].map(([tag, using]) => {\n const name = toKebab(tag);\n const suggestion = registryNames.has(name)\n ? `Run \\`blume add ${name}\\` to install it, or register <${tag}> in components.ts (mdx).`\n : `Register <${tag}> in components.ts (mdx), or add an islands/${tag}.tsx component.`;\n const routes = using.map((page) => page.route);\n const [first] = using;\n return {\n code: \"BLUME_UNKNOWN_COMPONENT\",\n file: first?.sourcePath ?? first?.id,\n message:\n routes.length === 1\n ? `<${tag}> is used in ${LIST.format(routes)} but isn't a known component.`\n : `<${tag}> is used on ${routes.length} pages but isn't a known component: ${LIST.format(routes)}.`,\n severity: \"warning\",\n suggestion,\n };\n });\n};\n\nconst EITHER = new Intl.ListFormat(\"en\", { type: \"disjunction\" });\nconst quoted = (names: readonly string[]): string[] =>\n names.map((name) => `\\`${name}\\``);\n\n/**\n * Warn about each childless built-in in an `.mdx` page given props it doesn't\n * take (`<Badge type=\"tip\" text=\"beta\" />`, VitePress's Badge). Blume's\n * components ignore unknown props, so the element renders without the\n * content those props carried. `extraTags` are the project's own components\n * (islands + overrides): one that replaces a built-in takes its own props,\n * so its uses aren't checked. A file shared by several locales is reported\n * once.\n */\nexport const unknownPropDiagnostics = (\n pages: readonly PageRecord[],\n extraTags: ReadonlySet<string>\n): Diagnostic[] => {\n const diagnostics: Diagnostic[] = [];\n const seen = new Set<string>();\n for (const page of pages) {\n for (const use of page.unknownProps ?? []) {\n const file = use.file ?? page.sourcePath ?? page.id;\n const key = `${file}:${use.line}:${use.column}`;\n if (extraTags.has(use.tag) || seen.has(key)) {\n continue;\n }\n seen.add(key);\n const accepted = BUILTIN_CHILD_PROPS.get(use.tag) ?? [];\n const takes =\n accepted.length > 0\n ? `, and use the props ${use.tag} takes: ${LIST.format(quoted(accepted))}`\n : `; ${use.tag} takes no props`;\n diagnostics.push({\n code: \"BLUME_UNKNOWN_PROP\",\n column: use.column,\n file,\n line: use.line,\n message: `<${use.tag}> in ${page.route} has no children, and ${use.tag} doesn't take ${EITHER.format(quoted(use.props))}, so it renders without what ${use.props.length === 1 ? \"that prop\" : \"those props\"} meant to show.`,\n severity: \"warning\",\n suggestion: `Put the content between the tags (<${use.tag}>…</${use.tag}>)${takes}.`,\n });\n }\n }\n return diagnostics;\n};\n\n/** What example discovery found: where it looked, and each example's key. */\nexport interface ExampleKeys {\n /** Absolute directory the examples were discovered under. */\n dir: string;\n examples: readonly { path: string }[];\n}\n\n/**\n * Warn about each `<Component path>` in an `.mdx` page that names no\n * discovered example. The page still renders, with a \"No example found\" box\n * where the preview should be, so without this a typo or a moved example\n * ships silently. Reported at the `path` value, in the partial that holds it\n * when an `<include>` brought it in; a file shared by several locales is\n * reported once. `extraTags` are the project's own components (islands +\n * overrides), as for {@link validateUsedComponents}: one named `Component`\n * replaces the built-in and resolves `path` its own way, so none is checked.\n */\nexport const missingExampleDiagnostics = (\n pages: readonly PageRecord[],\n discovery: ExampleKeys,\n root: string,\n extraTags: ReadonlySet<string>\n): Diagnostic[] => {\n if (extraTags.has(\"Component\")) {\n return [];\n }\n const known = new Set(discovery.examples.map((example) => example.path));\n const dir = relative(root, discovery.dir) || \".\";\n const diagnostics: Diagnostic[] = [];\n const seen = new Set<string>();\n for (const page of pages) {\n for (const use of page.examplesUsed ?? []) {\n const file = use.file ?? page.sourcePath ?? page.id;\n const key = `${file}:${use.line}:${use.column}`;\n if (!(known.has(use.path) || seen.has(key))) {\n seen.add(key);\n diagnostics.push({\n code: \"BLUME_EXAMPLE_NOT_FOUND\",\n column: use.column,\n file,\n line: use.line,\n message: `<Component path=\"${use.path}\"> in ${page.route} names no example, so the page shows \"No example found\" in its place.`,\n severity: \"warning\",\n suggestion: `Fix the path, or add the example under ${dir}/: \\`path\\` is its location there, without the extension.`,\n });\n }\n }\n }\n return diagnostics;\n};\n",
|
|
7
6
|
"import { readFile } from \"node:fs/promises\";\n\nimport pMap from \"p-map\";\nimport { basename, join } from \"pathe\";\nimport { glob } from \"tinyglobby\";\n\n/** Astro hydration directives Blume applies to a convention island. */\nexport type IslandClientMode = \"idle\" | \"load\" | \"only\" | \"visible\";\n\n/** Client framework an island is authored in, inferred from its extension. */\nexport type IslandFramework = \"react\" | \"svelte\" | \"vue\";\n\n/** A discovered `islands/` component, ready to wrap and expose to MDX. */\nexport interface IslandSpec {\n /** Hydration directive, from `export const client` or the default. */\n client: IslandClientMode;\n /** Absolute path to the island source file. */\n file: string;\n /** Astro client framework, used to enable the renderer and for `client:only`. */\n framework: IslandFramework;\n /** Component name used in MDX — the file's basename without extension. */\n name: string;\n}\n\nexport interface IslandDiscovery {\n islands: IslandSpec[];\n warnings: string[];\n}\n\n/** Hydration mode used when an island doesn't declare one. */\nconst DEFAULT_CLIENT: IslandClientMode = \"visible\";\n\n/** Ceiling on concurrent island-file reads; unbounded fan-out risks EMFILE. */\nconst READ_CONCURRENCY = 16;\n\nconst VALID_MODES = new Set<IslandClientMode>([\n \"idle\",\n \"load\",\n \"only\",\n \"visible\",\n]);\n\n/** Whether a declared client mode is one Astro's directives support. */\nconst isClientMode = (mode: string): mode is IslandClientMode =>\n // SAFETY: `Set.has` only compares identity at runtime; the assertion widens\n // the lookup key so the narrower-typed set accepts it, and the `has` result\n // is exactly the predicate being claimed.\n VALID_MODES.has(mode as IslandClientMode);\n\n/** Island extensions mapped to the Astro renderer that handles them. */\nconst FRAMEWORK_BY_EXT = new Map<string, IslandFramework>([\n [\"jsx\", \"react\"],\n [\"svelte\", \"svelte\"],\n [\"tsx\", \"react\"],\n [\"vue\", \"vue\"],\n]);\n\n// Captures the extension so we can both strip it from the name and pick the\n// framework. Kept in sync with the glob below.\nconst ISLAND_FILE = /\\.(?<ext>jsx|svelte|tsx|vue)$/u;\n\n// Matches `export const client = \"load\"` (with optional type annotation and\n// either quote style). Read statically so we never execute island code in Node.\nconst CLIENT_EXPORT =\n /export\\s+const\\s+client\\s*(?::[^=]+)?=\\s*[\"'](?<mode>\\w+)[\"']/u;\n\nexport const readClientMode = (\n source: string,\n file: string,\n warnings: string[]\n): IslandClientMode => {\n const mode = source.match(CLIENT_EXPORT)?.groups?.mode;\n if (!mode) {\n return DEFAULT_CLIENT;\n }\n if (!isClientMode(mode)) {\n warnings.push(\n `Island \"${file}\" declares an unknown client mode \"${mode}\"; defaulting to \"${DEFAULT_CLIENT}\". Use \"load\", \"idle\", \"visible\", or \"only\".`\n );\n return DEFAULT_CLIENT;\n }\n return mode;\n};\n\n/**\n * Discover convention islands under `<root>/islands`. Every `.tsx`/`.jsx`/\n * `.vue`/`.svelte` file becomes a globally-available, hydrated MDX component\n * named after the file (which must be PascalCase to be usable as a JSX tag).\n * Hydration defaults to `client:visible`; a file opts out with `export const\n * client = \"load\" | \"idle\" | \"only\"`. Discovery is path-based (a glob), so no\n * user code is executed.\n */\nexport const discoverIslands = async (\n root: string\n): Promise<IslandDiscovery> => {\n const dir = join(root, \"islands\");\n // Enumerate everything and let ISLAND_FILE do the filtering below, so\n // unknown extensions take the skip guard instead of relying on a glob\n // pattern staying in sync with the regex and framework map.\n const matches = await glob([\"**/*\"], {\n absolute: true,\n cwd: dir,\n onlyFiles: true,\n });\n const files = matches.toSorted();\n const sources = await pMap(files, (file) => readFile(file, \"utf-8\"), {\n concurrency: READ_CONCURRENCY,\n });\n\n const islands: IslandSpec[] = [];\n const warnings: string[] = [];\n const seen = new Map<string, string>();\n\n // Extracted so the skip paths become early `return`s (one `continue` budget\n // per loop under the lint rule) instead of `continue` statements.\n const collectIsland = (file: string, source: string): void => {\n const base = basename(file);\n const ext = base.match(ISLAND_FILE)?.groups?.ext;\n const framework = ext ? FRAMEWORK_BY_EXT.get(ext) : undefined;\n if (!framework) {\n return;\n }\n const name = base.replace(ISLAND_FILE, \"\");\n // The name is used verbatim as both an MDX tag and an unquoted object key\n // in the generated island map, so it must be a plain PascalCase identifier\n // — a `-`, `.`, or space (e.g. `Time-Picker.tsx`) would otherwise emit a\n // syntax-error module and fail the whole build with no pointer to the file.\n if (!/^[A-Z][A-Za-z0-9_]*$/u.test(name)) {\n warnings.push(\n `Island \"${file}\" must have a PascalCase identifier filename to be used in MDX (letters, digits, and underscores only, e.g. Counter.tsx → <Counter />); skipping it.`\n );\n return;\n }\n const existing = seen.get(name);\n if (existing) {\n warnings.push(\n `Two islands both resolve to <${name}> (\"${existing}\" and \"${file}\"); ignoring the second. Give them distinct filenames.`\n );\n return;\n }\n seen.set(name, file);\n islands.push({\n client: readClientMode(source, file, warnings),\n file,\n framework,\n name,\n });\n };\n\n for (const [index, file] of files.entries()) {\n collectIsland(file, sources[index] ?? \"\");\n }\n\n return { islands, warnings };\n};\n",
|
|
8
7
|
"import { readFile } from \"node:fs/promises\";\n\nimport pMap from \"p-map\";\nimport { isAbsolute, join, relative } from \"pathe\";\nimport { glob } from \"tinyglobby\";\n\nimport type { ExampleLookup } from \"../core/types.ts\";\nimport type { IslandClientMode } from \"./islands.ts\";\nimport { readClientMode } from \"./islands.ts\";\n\n/** Framework an example is authored in, inferred from its extension. */\nexport type ExampleFramework = \"astro\" | \"react\" | \"svelte\" | \"vue\";\n\n/** A discovered `examples/` file, ready to wrap (live) and show (source). */\nexport interface ExampleSpec {\n /** Hydration directive for a framework example; `undefined` for `.astro`. */\n client?: IslandClientMode;\n /** Absolute path to the example source file. */\n file: string;\n /** Framework, or `astro` for a server-rendered (static) example. */\n framework: ExampleFramework;\n /** Shiki language for the source pane — the file extension. */\n lang: string;\n /** MDX-facing key: the path under `examples/`, sans extension, `/`-joined. */\n path: string;\n /** Raw source text shown in the code tab. */\n source: string;\n}\n\nexport interface ExampleDiscovery {\n /**\n * Absolute directory the examples were discovered under: the configured\n * `examples.source` (or a glob's static prefix) resolved against the root.\n */\n dir: string;\n examples: ExampleSpec[];\n warnings: string[];\n}\n\n/** Example extensions mapped to the framework that renders them. */\ninterface FrameworkByExtension {\n [extension: string]: ExampleFramework;\n}\n\nconst FRAMEWORK_BY_EXT: FrameworkByExtension = {\n astro: \"astro\",\n jsx: \"react\",\n svelte: \"svelte\",\n tsx: \"react\",\n vue: \"vue\",\n};\n\n// Captures the extension so we can strip it from the path key and pick the\n// framework. Kept in sync with the glob below — non-matching files a user glob\n// happens to sweep in (e.g. a registry's `.ts` sources) are dropped here.\nconst EXAMPLE_FILE = /\\.(?<ext>astro|jsx|svelte|tsx|vue)$/u;\n\n// Renderable example files when `examples` names a plain directory.\nconst DEFAULT_EXAMPLE_GLOB = \"**/*.{astro,jsx,svelte,tsx,vue}\";\n\n/** Ceiling on concurrent example-file reads; unbounded fan-out risks EMFILE. */\nconst READ_CONCURRENCY = 16;\n\n/**\n * Files the preview-frame Tailwind entry scans for utility classes, appended\n * to each directory from `exampleScanRoots`.\n */\nexport const EXAMPLE_SCAN_GLOB = \"**/*.{astro,jsx,svelte,ts,tsx,vue}\";\n\n/**\n * Directories the `<Component />` preview sheet scans for utility classes:\n * the project root, plus the examples directory when it lives outside the\n * root (a sibling workspace package, say). Tailwind's `@source` is a file\n * glob, not an import graph, so an out-of-root examples directory would\n * otherwise contribute no utilities and previews would render half-styled.\n */\nexport const exampleScanRoots = (\n root: string,\n examplesDir: string\n): string[] => {\n const path = relative(root, examplesDir);\n const outside = path.startsWith(\"..\") || isAbsolute(path);\n return outside ? [root, examplesDir] : [root];\n};\n\n// Glob magic that turns `examples` from a plain directory into a pattern. `()`,\n// `@`, and `+` are excluded so literal path segments (npm scopes, parens) keep\n// resolving as directories; the extglob leads `*?!` still trigger here.\nconst GLOB_MAGIC = /[!*?[\\]{}]/u;\n\n/**\n * Split a glob into its static directory prefix and the remaining pattern, so\n * discovered files can be keyed relative to that prefix (e.g.\n * `registry/x/**\\/examples/*` → `{ base: \"registry/x\", rest: \"**\\/examples/*\" }`).\n */\nconst splitGlobBase = (pattern: string) => {\n const segments = pattern.split(\"/\");\n // Only called when the pattern contains glob magic (see the caller), and `/`\n // is never magic, so the magic char always lands in a segment — `findIndex`\n // is never -1 here.\n const firstMagic = segments.findIndex((segment) => GLOB_MAGIC.test(segment));\n return {\n base: segments.slice(0, firstMagic).join(\"/\"),\n rest: segments.slice(firstMagic).join(\"/\"),\n };\n};\n\n/**\n * Discover preview examples for the `examples` config (default `examples`).\n * Every `.astro`/`.tsx`/`.jsx`/`.vue`/`.svelte` file becomes addressable by\n * `<Component path=\"...\">`, where the path is the file's location without its\n * extension (e.g. `forms/login.tsx` → `forms/login`).\n *\n * `pattern` is a directory by default, but may be a glob (anything with\n * `*`/`?`/`[]`/`{}`/`!`) — then only matching files are discovered and each\n * `<Component path>` key is relative to the glob's static prefix. This lets a\n * registry layout that colocates component sources with their examples be\n * targeted directly (e.g. `registry/<pkg>/**\\/examples/*`) without the sources —\n * which have no default export and so can't be wrapped — being swept in.\n *\n * Discovery is path-based (a glob), so no example code is executed. Framework\n * examples carry a hydration mode (default `client:visible`, overridable via\n * `export const client`); `.astro` examples render statically with no client\n * directive.\n */\nexport const discoverExamples = async (\n root: string,\n pattern = \"examples\"\n): Promise<ExampleDiscovery> => {\n const { base, rest } = GLOB_MAGIC.test(pattern)\n ? splitGlobBase(pattern)\n : { base: pattern, rest: DEFAULT_EXAMPLE_GLOB };\n const dir = join(root, base);\n const matches = await glob([rest], {\n absolute: true,\n cwd: dir,\n onlyFiles: true,\n });\n const files = matches.toSorted();\n const sources = await pMap(files, (file) => readFile(file, \"utf-8\"), {\n concurrency: READ_CONCURRENCY,\n });\n\n const examples: ExampleSpec[] = [];\n const warnings: string[] = [];\n const seen = new Map<string, string>();\n\n // Extracted so the two skip paths become early `return`s (one `continue`\n // budget per loop under the lint rule) instead of `continue` statements.\n const collectExample = (file: string, source: string): void => {\n const ext = file.match(EXAMPLE_FILE)?.groups?.ext;\n const framework = ext ? FRAMEWORK_BY_EXT[ext] : undefined;\n if (!(ext && framework)) {\n return;\n }\n // Strip the trailing `.<ext>` to form the `<Component path>` key.\n const path = relative(dir, file).slice(0, -(ext.length + 1));\n const existing = seen.get(path);\n if (existing) {\n warnings.push(\n `Two examples both resolve to \"${path}\" (\"${existing}\" and \"${file}\"); ignoring the second. Give them distinct paths.`\n );\n return;\n }\n seen.set(path, file);\n examples.push({\n client:\n framework === \"astro\"\n ? undefined\n : readClientMode(source, file, warnings),\n file,\n framework,\n lang: ext,\n path,\n source,\n });\n };\n\n for (const [index, file] of files.entries()) {\n collectExample(file, sources[index] ?? \"\");\n }\n\n return { dir, examples, warnings };\n};\n\n/**\n * Reduce discovered examples to the `<Component path>` → source lookup the\n * agent-facing Markdown downleveler needs (see {@link BlumeProject.examples}).\n */\nexport const exampleMarkdownLookup = (examples: ExampleSpec[]): ExampleLookup =>\n Object.fromEntries(\n examples.map((example) => [\n example.path,\n { lang: example.lang, source: example.source },\n ])\n );\n",
|
|
9
8
|
"import { createRequire } from \"node:module\";\nimport { pathToFileURL } from \"node:url\";\n\nimport { join } from \"pathe\";\n\nimport {\n commandsFor,\n detectProjectPackageManager,\n} from \"../cli/init/scaffold.ts\";\nimport { packageRoot } from \"../core/package-root.ts\";\nimport type { ResolvedConfig } from \"../core/schema.ts\";\nimport type { Diagnostic } from \"../core/types.ts\";\n\n/** Whether a module specifier resolves from a directory via node resolution. */\nexport const canResolveFrom = (fromDir: string, spec: string): boolean => {\n try {\n createRequire(pathToFileURL(join(fromDir, \"_.js\")).href).resolve(spec);\n return true;\n } catch {\n return false;\n }\n};\n\n/** A package a configured feature imports that the project can't resolve. */\nexport interface MissingDependency {\n /** The package whose absence was detected. */\n dep: string;\n /** Every package to install for the feature (a framework and its integration). */\n install: string[];\n /** What needs it, as the message names it: `Search adapter \"algolia\"`. */\n owner: string;\n}\n\n/**\n * The declared `deps` of one feature that resolve neither from the project\n * root nor from the Blume package itself. A dep is available when the project\n * installed it OR Blume ships it (the same set the `.blume` deps link exposes\n * to the build). Resolving from the project root alone falsely flagged a\n * shipped SDK like Orama (the default provider) as missing whenever it wasn't\n * hoisted into the project, e.g. under isolated linkers. Each package is\n * resolved from its real location rather than through the `.blume` junction,\n * which can't be traversed reliably for store-symlinked deps.\n */\nconst unresolved = (\n owner: string,\n deps: readonly string[],\n root: string,\n pkgDir: string\n): MissingDependency[] =>\n deps\n .filter(\n (dep) => !(canResolveFrom(root, dep) || canResolveFrom(pkgDir, dep))\n )\n .map((dep) => ({ dep, install: [dep], owner }));\n\n/**\n * The search adapter's SDK, when missing. Provider SDKs are optional peers,\n * so a hosted adapter's client import fails in Vite without one.\n */\nexport const searchProviderDependencies = (\n provider: ResolvedConfig[\"search\"][\"provider\"],\n root: string,\n pkgDir: string = packageRoot()\n): MissingDependency[] =>\n unresolved(\n `Search adapter \"${provider.kind}\"`,\n provider.runtimeDeps,\n root,\n pkgDir\n );\n\n/** Content source SDKs (`@notionhq/client`, `@sanity/client`), when missing. */\nexport const sourceAdapterDependencies = (\n sources: ResolvedConfig[\"content\"][\"sources\"],\n root: string,\n pkgDir: string = packageRoot()\n): MissingDependency[] =>\n sources.flatMap((source) =>\n unresolved(\n `Content source \"${source.kind}\"`,\n source.runtimeDeps,\n root,\n pkgDir\n )\n );\n\n/**\n * The assistant adapter's provider SDK, when missing — only `gateway` needs\n * nothing beyond the core `ai` package Blume ships. An external `endpoint`\n * means no generated route, so no SDK is imported.\n */\nexport const assistantProviderDependencies = (\n ask: ResolvedConfig[\"ai\"][\"assistant\"],\n root: string,\n pkgDir: string = packageRoot()\n): MissingDependency[] =>\n ask?.enabled && !ask.endpoint\n ? unresolved(\n `Assistant provider \"${ask.provider.kind}\"`,\n ask.provider.runtimeDeps,\n root,\n pkgDir\n )\n : [];\n\n/**\n * The narration provider's SDK, when missing: `openai()` speaks through\n * `@ai-sdk/openai`, which the build loads to generate the clips, while\n * `gateway()` needs nothing beyond the core `ai` package Blume ships.\n */\nexport const narrationProviderDependencies = (\n narration: ResolvedConfig[\"narration\"],\n root: string,\n pkgDir: string = packageRoot()\n): MissingDependency[] =>\n narration.enabled && narration.provider\n ? unresolved(\n `Narration provider \"${narration.provider.kind}\"`,\n narration.provider.runtimeDeps,\n root,\n pkgDir\n )\n : [];\n\n/**\n * The deployment adapter's package, when missing. Node and Vercel ship with\n * Blume, so theirs always resolve; Netlify and Cloudflare are optional peers.\n * The generated astro.config.mjs imports the package directly, so without it\n * the build dies with an opaque ERR_MODULE_NOT_FOUND from the hidden config.\n */\nexport const deploymentAdapterDependencies = (\n deployment: ResolvedConfig[\"deployment\"],\n root: string,\n pkgDir: string = packageRoot()\n): MissingDependency[] =>\n unresolved(\n `Deployment adapter \"${deployment.kind}\"`,\n deployment.runtimeDeps,\n root,\n pkgDir\n );\n\n/** Astro integration package each non-React island framework needs installed. */\nconst ISLAND_FRAMEWORK_DEPS = new Map([\n [\"svelte\", \"@astrojs/svelte\"],\n [\"vue\", \"@astrojs/vue\"],\n]);\n\n/**\n * A Vue/Svelte island's Astro integration, when missing — the generated config\n * imports it. React ships with Blume, so it never needs this. The framework\n * itself is installed alongside its integration.\n */\nexport const islandFrameworkDependencies = (\n frameworks: Iterable<string>,\n root: string\n): MissingDependency[] =>\n [...frameworks].flatMap((framework) => {\n const dep = ISLAND_FRAMEWORK_DEPS.get(framework);\n return dep && !canResolveFrom(root, dep)\n ? [\n {\n dep,\n install: [dep, framework],\n owner: `Island framework \"${framework}\"`,\n },\n ]\n : [];\n });\n\n/**\n * Every package the resolved config's adapters (and the given island\n * frameworks) import that isn't installed: the search SDK, content source\n * SDKs, the assistant and narration provider SDKs, the deployment adapter,\n * and island integrations. The adapters' `runtimeDeps` are the one place that\n * knows.\n */\nexport const missingRuntimeDependencies = (\n config: ResolvedConfig,\n root: string,\n frameworks: Iterable<string> = [],\n pkgDir: string = packageRoot()\n): MissingDependency[] => [\n ...searchProviderDependencies(config.search.provider, root, pkgDir),\n ...sourceAdapterDependencies(config.content.sources, root, pkgDir),\n ...assistantProviderDependencies(config.ai.assistant, root, pkgDir),\n ...narrationProviderDependencies(config.narration, root, pkgDir),\n ...deploymentAdapterDependencies(config.deployment, root, pkgDir),\n ...islandFrameworkDependencies(frameworks, root),\n];\n\n/**\n * One diagnostic for every package the config imports that isn't installed,\n * with the command that installs them all through the project's package\n * manager (`npm install`, `pnpm add`, …), or undefined when nothing is\n * missing. `blume build` raises it as an error and `blume dev` as a warning;\n * `blume doctor` reports it before a build ever runs.\n */\nexport const missingDependencyDiagnostic = async (\n config: ResolvedConfig,\n root: string,\n severity: Diagnostic[\"severity\"],\n frameworks: Iterable<string> = [],\n pkgDir: string = packageRoot()\n): Promise<Diagnostic | undefined> => {\n const missing = missingRuntimeDependencies(config, root, frameworks, pkgDir);\n if (missing.length === 0) {\n return undefined;\n }\n const { add } = commandsFor(await detectProjectPackageManager(root));\n const needs = missing.map(({ dep, owner }) => `${owner} needs \"${dep}\"`);\n const packages = [...new Set(missing.flatMap(({ install }) => install))];\n return {\n code: \"BLUME_DEPENDENCY_MISSING\",\n message:\n missing.length === 1\n ? `${needs[0]}, which isn't installed.`\n : `These packages aren't installed: ${needs.join(\"; \")}.`,\n severity,\n suggestion: `Install ${packages.length === 1 ? \"it\" : \"them\"}: \\`${add} ${packages.join(\" \")}\\`.`,\n };\n};\n"
|
|
10
9
|
],
|
|
11
|
-
"mappings": "
|
|
12
|
-
"debugId": "
|
|
10
|
+
"mappings": "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",
|
|
11
|
+
"debugId": "01581CA3D72AB06264756E2164756E21",
|
|
13
12
|
"names": []
|
|
14
13
|
}
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from "./index.js";
|
|
10
10
|
import {
|
|
11
11
|
AGENTS
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-8b489v1b.js";
|
|
13
13
|
import {
|
|
14
14
|
i18nEnabled,
|
|
15
15
|
localeCodes,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
folderMetaSchema,
|
|
19
19
|
scanBody,
|
|
20
20
|
createModuleLoader
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-dm4mg9bj.js";
|
|
22
22
|
import {
|
|
23
23
|
seconds,
|
|
24
24
|
money,
|
|
@@ -34,11 +34,11 @@ import {
|
|
|
34
34
|
import {
|
|
35
35
|
findFolderMetaFiles,
|
|
36
36
|
scanProject
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-8f8xw4x2.js";
|
|
38
38
|
import"./chunk-zccbjcj0.js";
|
|
39
39
|
import {
|
|
40
40
|
parseTimeoutSeconds
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-05f21r8h.js";
|
|
42
42
|
|
|
43
43
|
// src/cli/commands/translate.ts
|
|
44
44
|
import { defineCommand } from "citty";
|
|
@@ -1212,4 +1212,4 @@ export {
|
|
|
1212
1212
|
};
|
|
1213
1213
|
|
|
1214
1214
|
//# debugId=7CBDF68DDB18B6AB64756E2164756E21
|
|
1215
|
-
//# sourceMappingURL=chunk-
|
|
1215
|
+
//# sourceMappingURL=chunk-ahc5gc9h.js.map
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
buildHomeLinkHeader,
|
|
4
4
|
resolveDocsCollection,
|
|
5
5
|
TOC_HIDDEN_KEY,
|
|
6
|
+
TOC_TEXT_KEY,
|
|
6
7
|
deployPassthrough,
|
|
7
8
|
RATE_LIMIT_BINDING,
|
|
8
9
|
fontLocaleCodes,
|
|
@@ -12,15 +13,19 @@ import {
|
|
|
12
13
|
hasVariables,
|
|
13
14
|
SVG_ASSET_HEADERS,
|
|
14
15
|
applyBaseToAstroRedirects,
|
|
16
|
+
isPageIndexFile,
|
|
15
17
|
withMirrorRedirects,
|
|
16
18
|
distDir,
|
|
17
19
|
adapterRoot,
|
|
18
20
|
deployPlatform
|
|
19
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-dm4mg9bj.js";
|
|
20
22
|
import {
|
|
21
23
|
trimChar,
|
|
22
24
|
normalizeBasePath
|
|
23
25
|
} from "./chunk-zccbjcj0.js";
|
|
26
|
+
import {
|
|
27
|
+
getBlumeVersion
|
|
28
|
+
} from "./index.js";
|
|
24
29
|
import {
|
|
25
30
|
BLUME_IGNORE_DIRS
|
|
26
31
|
} from "./chunk-kwrg63tm.js";
|
|
@@ -232,6 +237,10 @@ var CONSENT_CLIENT_MODULES = new Map([
|
|
|
232
237
|
// src/markdown/api-rail.ts
|
|
233
238
|
var API_RAIL_KEY = "blumeApiRail";
|
|
234
239
|
|
|
240
|
+
// src/markdown/title-heading.ts
|
|
241
|
+
var TITLE_ID_KEY = "blumeTitleId";
|
|
242
|
+
var seen = new WeakSet;
|
|
243
|
+
|
|
235
244
|
// src/markdown/views.ts
|
|
236
245
|
var VIEWS_KEY = "blumeViews";
|
|
237
246
|
|
|
@@ -496,7 +505,8 @@ var astroConfigTemplate = (options) => {
|
|
|
496
505
|
})},` : "";
|
|
497
506
|
const redirectPages = new Set(contentRoutes);
|
|
498
507
|
const basedRedirects = withMirrorRedirects(applyBaseToAstroRedirects(config.redirects, config.basePath, deployment.options.base ?? "", redirectPages), redirectPages, { from: "", to: normalizeBasePath(deployment.options.base) });
|
|
499
|
-
const
|
|
508
|
+
const staticOutput = deployment.options.output === "static";
|
|
509
|
+
const exactRedirects = basedRedirects.filter((redirect) => !(isPatternPath(redirect.from) || staticOutput && isPageIndexFile(redirect.from, redirectPages)));
|
|
500
510
|
const redirectsOption = exactRedirects.length > 0 ? `
|
|
501
511
|
redirects: ${JSON.stringify(Object.fromEntries(exactRedirects.map((redirect) => [
|
|
502
512
|
redirect.from,
|
|
@@ -533,6 +543,7 @@ var astroConfigTemplate = (options) => {
|
|
|
533
543
|
const blumeImports = [
|
|
534
544
|
"blumeIntegration",
|
|
535
545
|
"includeHmrPlugin",
|
|
546
|
+
"mdxSourceErrorsPlugin",
|
|
536
547
|
"prerenderDepsPlugin",
|
|
537
548
|
...runtimeModuleImports,
|
|
538
549
|
...adapterOption.includes("withAdapterRoot") ? ["withAdapterRoot"] : [],
|
|
@@ -607,10 +618,10 @@ ${userConfigSetup}export default defineConfig({
|
|
|
607
618
|
devToolbar: { enabled: false },
|
|
608
619
|
// One canonical URL per page: canonicals, the sitemap, and hreflang all use
|
|
609
620
|
// the slashless form, so the slashed spelling is not a second address. Astro
|
|
610
|
-
// applies this itself —
|
|
611
|
-
//
|
|
612
|
-
// turns it into the platform's 308 route, so the Build Output config
|
|
613
|
-
// no hand-spliced redirect (see deploy/vercel-negotiation.ts). Static hosts
|
|
621
|
+
// applies this itself — an on-demand route redirects, and the integration
|
|
622
|
+
// has the dev server redirect too, ahead of Astro's own 404 — and the Vercel
|
|
623
|
+
// adapter turns it into the platform's 308 route, so the Build Output config
|
|
624
|
+
// needs no hand-spliced redirect (see deploy/vercel-negotiation.ts). Static hosts
|
|
614
625
|
// serve the \`index.html\` directory layout as they always did.
|
|
615
626
|
trailingSlash: "never",
|
|
616
627
|
// The layouts render Astro's <ClientRouter />, and its in-place swaps read
|
|
@@ -625,7 +636,7 @@ ${userConfigSetup}export default defineConfig({
|
|
|
625
636
|
// the overlap only adds memory.
|
|
626
637
|
build: { concurrency: Math.min(8, availableParallelism()) },
|
|
627
638
|
vite: {${viteCacheOption}
|
|
628
|
-
plugins: [${runtimeModulesPluginEntry}${variablesPluginEntry}tailwindcss(), includeHmrPlugin(${configPath(`${context.outDir}/src/generated/includes.json`, ejected)}), prerenderDepsPlugin()],
|
|
639
|
+
plugins: [${runtimeModulesPluginEntry}${variablesPluginEntry}tailwindcss(), includeHmrPlugin(${configPath(`${context.outDir}/src/generated/includes.json`, ejected)}), mdxSourceErrorsPlugin(), prerenderDepsPlugin()],
|
|
629
640
|
build: {${features.mermaid ? MERMAID_CHUNK_LIMIT : ""}
|
|
630
641
|
rolldownOptions: {
|
|
631
642
|
${ROLLDOWN_ON_LOG},
|
|
@@ -704,6 +715,8 @@ var runtimeDirWithin = (base, outDir) => {
|
|
|
704
715
|
return rel && !rel.startsWith("..") && !isAbsolute2(rel) ? rel : null;
|
|
705
716
|
};
|
|
706
717
|
var astroGlobBase = (base) => isAbsolute2(base) ? pathToFileURL(base).href : base;
|
|
718
|
+
var GLOB_SYNTAX = /[!()*+?@[\\\]{|}]/gu;
|
|
719
|
+
var escapeGlob = (path) => path.replaceAll(GLOB_SYNTAX, String.raw`\$&`);
|
|
707
720
|
var contentConfigTemplate = (options) => {
|
|
708
721
|
const { context, config } = options;
|
|
709
722
|
const stagedBase = options.stagedBase ?? stagedContentDir(context.outDir);
|
|
@@ -718,7 +731,11 @@ var contentConfigTemplate = (options) => {
|
|
|
718
731
|
...includeGlobs,
|
|
719
732
|
...(excludeGlobs ?? []).map((pattern) => `!${pattern}`),
|
|
720
733
|
...BLUME_IGNORE_DIRS.flatMap((dir) => dir === ".blume" ? [] : [`!**/${dir}/**`]),
|
|
721
|
-
...outDirIgnore
|
|
734
|
+
...outDirIgnore,
|
|
735
|
+
...(options.unparsable ?? []).flatMap((file) => {
|
|
736
|
+
const rel = relative2(collectionBase, file);
|
|
737
|
+
return rel.startsWith("..") || isAbsolute2(rel) ? [] : [`!${escapeGlob(rel)}`];
|
|
738
|
+
})
|
|
722
739
|
] : [];
|
|
723
740
|
const stagedBlock = options.staged ? `
|
|
724
741
|
const staged = defineCollection({
|
|
@@ -743,6 +760,10 @@ import { pageCollectionSchema } from "blume/core/schema.ts";
|
|
|
743
760
|
// pageCollectionSchema is the scan's page front-matter schema, so entry.data
|
|
744
761
|
// is typed and normalized the same way; it passes custom keys through and
|
|
745
762
|
// falls back to defaults for a page the scan already dropped as invalid.
|
|
763
|
+
//
|
|
764
|
+
// Astro's content store re-parses an entry only when its file or this config
|
|
765
|
+
// changes, so naming the Blume version (${getBlumeVersion()}) here re-parses
|
|
766
|
+
// every entry after an upgrade: none keeps what an older schema produced.
|
|
746
767
|
const docs = defineCollection({
|
|
747
768
|
loader: withIncludeRefresh(glob({
|
|
748
769
|
pattern: ${JSON.stringify(docsPattern)},
|
|
@@ -1214,11 +1235,25 @@ const TYPES: Record<string, string> = {
|
|
|
1214
1235
|
".webp": "image/webp",
|
|
1215
1236
|
};
|
|
1216
1237
|
|
|
1238
|
+
// The other files a page's links name beside it, typed so the dev server
|
|
1239
|
+
// opens them the way a static host would. Anything else downloads.
|
|
1240
|
+
const FILE_TYPES: Record<string, string> = {
|
|
1241
|
+
".csv": "text/csv; charset=utf-8",
|
|
1242
|
+
".json": "application/json",
|
|
1243
|
+
".mp3": "audio/mpeg",
|
|
1244
|
+
".pdf": "application/pdf",
|
|
1245
|
+
".txt": "text/plain; charset=utf-8",
|
|
1246
|
+
".wav": "audio/wav",
|
|
1247
|
+
".zip": "application/zip",
|
|
1248
|
+
};
|
|
1249
|
+
|
|
1217
1250
|
const extensionOf = (path: string): string =>
|
|
1218
1251
|
path.slice(path.lastIndexOf(".")).toLowerCase();
|
|
1219
1252
|
|
|
1220
1253
|
const contentType = (path: string): string =>
|
|
1221
|
-
TYPES[extensionOf(path)] ??
|
|
1254
|
+
TYPES[extensionOf(path)] ??
|
|
1255
|
+
FILE_TYPES[extensionOf(path)] ??
|
|
1256
|
+
"application/octet-stream";
|
|
1222
1257
|
|
|
1223
1258
|
// A source downloads only images and videos; anything else in the staged
|
|
1224
1259
|
// directory (a page an older build saved under its URL's extension) is never
|
|
@@ -1567,6 +1602,7 @@ import Badge from "blume/components/content/Badge.astro";
|
|
|
1567
1602
|
import Callout from "blume/components/content/Callout.astro";
|
|
1568
1603
|
import Card from "blume/components/content/Card.astro";
|
|
1569
1604
|
import CardGroup from "blume/components/content/CardGroup.astro";
|
|
1605
|
+
import Changelog from "blume/components/content/Changelog.astro";
|
|
1570
1606
|
import CodeBlock from "blume/components/content/CodeBlock.astro";
|
|
1571
1607
|
import CodeGroup from "blume/components/content/CodeGroup.astro";
|
|
1572
1608
|
import ColorRoot from "blume/components/content/Color.astro";
|
|
@@ -1620,6 +1656,7 @@ ${mathImport}import { mdxComponents as userMdx, layoutOverrides } from "../gener
|
|
|
1620
1656
|
Callout,
|
|
1621
1657
|
Card,
|
|
1622
1658
|
CardGroup,
|
|
1659
|
+
Changelog,
|
|
1623
1660
|
CodeBlock,
|
|
1624
1661
|
CodeGroup,
|
|
1625
1662
|
Color,
|
|
@@ -1723,10 +1760,25 @@ const views = Array.isArray(viewsRaw)
|
|
|
1723
1760
|
: [];
|
|
1724
1761
|
const tocHiddenRaw = remarkPluginFrontmatter?.${TOC_HIDDEN_KEY};
|
|
1725
1762
|
const tocHidden = new Set(Array.isArray(tocHiddenRaw) ? tocHiddenRaw : []);
|
|
1726
|
-
|
|
1763
|
+
// A heading holding a \`<Badge>\` lists without the badge's text, which the
|
|
1764
|
+
// heading plugin reports by slug the same way.
|
|
1765
|
+
const tocTextRaw = remarkPluginFrontmatter?.${TOC_TEXT_KEY};
|
|
1766
|
+
const tocText = tocTextRaw && typeof tocTextRaw === "object" ? tocTextRaw : {};
|
|
1767
|
+
const headings = (
|
|
1727
1768
|
tocHidden.size > 0
|
|
1728
1769
|
? allHeadings.filter((heading) => !tocHidden.has(heading.slug))
|
|
1729
|
-
: allHeadings
|
|
1770
|
+
: allHeadings
|
|
1771
|
+
).map((heading) =>
|
|
1772
|
+
typeof tocText[heading.slug] === "string"
|
|
1773
|
+
? { ...heading, text: tocText[heading.slug] }
|
|
1774
|
+
: heading
|
|
1775
|
+
);
|
|
1776
|
+
// An untitled page's opening \`# Heading\` is its title, so the title-heading
|
|
1777
|
+
// plugin drops it from the body and reports its id here: the title \`<h1>\`
|
|
1778
|
+
// below takes it, so links to the heading's anchor still land (see
|
|
1779
|
+
// markdown/title-heading.ts).
|
|
1780
|
+
const titleIdRaw = remarkPluginFrontmatter?.${TITLE_ID_KEY};
|
|
1781
|
+
const titleId = typeof titleIdRaw === "string" ? titleIdRaw : undefined;
|
|
1730
1782
|
const frontmatter = entry.data;
|
|
1731
1783
|
|
|
1732
1784
|
const seo = frontmatter.seo;
|
|
@@ -2015,7 +2067,7 @@ const LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);
|
|
|
2015
2067
|
noindex={effectiveNoindex}
|
|
2016
2068
|
structuredDataEnabled={data.config.structuredData}
|
|
2017
2069
|
>
|
|
2018
|
-
{pageChrome && <h1>{title}</h1>}
|
|
2070
|
+
{pageChrome && <h1 id={titleId}>{title}</h1>}
|
|
2019
2071
|
{pageChrome && frontmatter.description && <p class="text-lg text-muted-foreground">{frontmatter.description}</p>}
|
|
2020
2072
|
{narration && (
|
|
2021
2073
|
<NarrationPlayer
|
|
@@ -2036,32 +2088,17 @@ const LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);
|
|
|
2036
2088
|
var changelogIndexTemplate = (options) => {
|
|
2037
2089
|
const clientData = options.needsReact ? `
|
|
2038
2090
|
clientData={{ config: data.config, navigation: data.navigation, page: { route: "/changelog", title: pageTitle } }}` : "";
|
|
2039
|
-
const stagedSpread = options.staged ? `
|
|
2040
|
-
...(await getCollection("staged")),` : "";
|
|
2041
2091
|
return `---
|
|
2042
2092
|
// Generated by Blume. Do not edit.
|
|
2043
|
-
import { getCollection } from "astro:content";
|
|
2044
2093
|
import RootLayout from "blume/components/layout/RootLayout.astro";
|
|
2094
|
+
import Changelog from "blume/components/content/Changelog.astro";
|
|
2045
2095
|
import { withMountedBase } from "blume/components/islands/base-path.ts";
|
|
2046
2096
|
import { resolveSlot } from "blume/components/layout/overrides.ts";
|
|
2047
|
-
import { resolveDateFormatOptions } from "blume/core/date-format.ts";
|
|
2048
2097
|
import { layoutOverrides } from "../generated/components.ts";
|
|
2049
2098
|
import data from "blume:data";
|
|
2050
2099
|
|
|
2051
2100
|
export const prerender = true;
|
|
2052
2101
|
|
|
2053
|
-
const entryDate = (entry: {
|
|
2054
|
-
data: { date?: string | null; changelog?: { date?: string | null } | null };
|
|
2055
|
-
}) => entry.data.date ?? entry.data.changelog?.date ?? null;
|
|
2056
|
-
|
|
2057
|
-
const parseDate = (value: string | null | undefined) => {
|
|
2058
|
-
if (!value) {
|
|
2059
|
-
return null;
|
|
2060
|
-
}
|
|
2061
|
-
const date = new Date(value);
|
|
2062
|
-
return Number.isNaN(date.getTime()) ? null : date;
|
|
2063
|
-
};
|
|
2064
|
-
|
|
2065
2102
|
// The changelog is an unlocalized route, so its chrome renders in the default
|
|
2066
2103
|
// locale's dictionary and direction (\`data.ui\` is the default locale's resolved
|
|
2067
2104
|
// dictionary), mirroring the catch-all's locale wiring.
|
|
@@ -2072,109 +2109,6 @@ const localeMeta = i18n
|
|
|
2072
2109
|
const dir = localeMeta?.dir ?? "ltr";
|
|
2073
2110
|
const htmlLang = i18n ? i18n.defaultLocale : "en";
|
|
2074
2111
|
|
|
2075
|
-
// Formatted in the same locale as the chrome, and with the configured
|
|
2076
|
-
// \`dateFormat\` (UTC by default), to match the per-page "last updated" stamp.
|
|
2077
|
-
// The year heads each group, so a row shows the rest of the date: a preset
|
|
2078
|
-
// style keeps its month wording, a component format simply drops the year.
|
|
2079
|
-
const dateFormatOptions = resolveDateFormatOptions(data.config.dateFormat);
|
|
2080
|
-
const { dateStyle, year: _year, ...dateComponents } = dateFormatOptions;
|
|
2081
|
-
const rowDateFormat: Intl.DateTimeFormatOptions = dateStyle
|
|
2082
|
-
? {
|
|
2083
|
-
...dateComponents,
|
|
2084
|
-
day: "numeric",
|
|
2085
|
-
month: dateStyle === "medium" ? "short" : "long",
|
|
2086
|
-
}
|
|
2087
|
-
: dateComponents;
|
|
2088
|
-
const formatRowDate = (date: Date) =>
|
|
2089
|
-
new Intl.DateTimeFormat(htmlLang, rowDateFormat).format(date);
|
|
2090
|
-
const formatYear = (date: Date) =>
|
|
2091
|
-
new Intl.DateTimeFormat(htmlLang, {
|
|
2092
|
-
timeZone: dateFormatOptions.timeZone,
|
|
2093
|
-
year: "numeric",
|
|
2094
|
-
}).format(date);
|
|
2095
|
-
|
|
2096
|
-
const slugify = (text: string) =>
|
|
2097
|
-
text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") ||
|
|
2098
|
-
"update";
|
|
2099
|
-
|
|
2100
|
-
// Map each entry to its own generated page so the row can link to it. The
|
|
2101
|
-
// collection entry id matches the route manifest's \`entryId\` — and under
|
|
2102
|
-
// i18n every locale serves a page for it (its translations plus fallback
|
|
2103
|
-
// copies of an untranslated one), all sharing that id, so a map over every
|
|
2104
|
-
// route would keep whichever locale came last: a Portuguese permalink on an
|
|
2105
|
-
// unlocalized index. Only the default locale's routes are kept, and an entry
|
|
2106
|
-
// is listed only when it has one, so a translated changelog file (a distinct
|
|
2107
|
-
// entry that lives under its own locale) does not add a second row for the
|
|
2108
|
-
// same release.
|
|
2109
|
-
const defaultLocale = i18n ? i18n.defaultLocale : null;
|
|
2110
|
-
const routeByEntry = new Map<string, string>();
|
|
2111
|
-
for (const route of data.routes) {
|
|
2112
|
-
if (defaultLocale === null || route.locale === defaultLocale) {
|
|
2113
|
-
routeByEntry.set(route.entryId, route.path);
|
|
2114
|
-
}
|
|
2115
|
-
}
|
|
2116
|
-
|
|
2117
|
-
const changelogEntries = [
|
|
2118
|
-
...(await getCollection("docs")),${stagedSpread}
|
|
2119
|
-
]
|
|
2120
|
-
.filter(
|
|
2121
|
-
(entry) =>
|
|
2122
|
-
entry.data.type === "changelog" &&
|
|
2123
|
-
!entry.data.draft &&
|
|
2124
|
-
!entry.data.sidebar?.hidden &&
|
|
2125
|
-
(defaultLocale === null || routeByEntry.has(entry.id))
|
|
2126
|
-
)
|
|
2127
|
-
.toSorted(
|
|
2128
|
-
(a, b) =>
|
|
2129
|
-
(parseDate(entryDate(b))?.getTime() ?? 0) -
|
|
2130
|
-
(parseDate(entryDate(a))?.getTime() ?? 0)
|
|
2131
|
-
);
|
|
2132
|
-
|
|
2133
|
-
const items = changelogEntries.map((entry) => {
|
|
2134
|
-
const label =
|
|
2135
|
-
entry.data.title ??
|
|
2136
|
-
(entry.data.changelog?.version
|
|
2137
|
-
? "v" + entry.data.changelog.version
|
|
2138
|
-
: "Update");
|
|
2139
|
-
const date = parseDate(entryDate(entry));
|
|
2140
|
-
const route = routeByEntry.get(entry.id);
|
|
2141
|
-
return {
|
|
2142
|
-
date: date ? formatRowDate(date) : null,
|
|
2143
|
-
dateTime: date ? date.toISOString().slice(0, 10) : null,
|
|
2144
|
-
href: route ? withMountedBase(route) : null,
|
|
2145
|
-
id: slugify(label),
|
|
2146
|
-
label,
|
|
2147
|
-
tag: entry.data.changelog?.category ?? null,
|
|
2148
|
-
year: date ? formatYear(date) : null,
|
|
2149
|
-
};
|
|
2150
|
-
});
|
|
2151
|
-
|
|
2152
|
-
// Repeated labels slug to the same id (e.g. two entries with neither a title
|
|
2153
|
-
// nor a version both falling back to "update"); suffix the later ones -2, -3,
|
|
2154
|
-
// ... so every row keeps its own hash anchor. The first keeps the plain slug.
|
|
2155
|
-
const seenIds = new Set();
|
|
2156
|
-
for (const item of items) {
|
|
2157
|
-
let uniqueId = item.id;
|
|
2158
|
-
for (let n = 2; seenIds.has(uniqueId); n += 1) {
|
|
2159
|
-
uniqueId = item.id + "-" + n;
|
|
2160
|
-
}
|
|
2161
|
-
seenIds.add(uniqueId);
|
|
2162
|
-
item.id = uniqueId;
|
|
2163
|
-
}
|
|
2164
|
-
|
|
2165
|
-
// Consecutive releases from the same year share a group, so the list reads as
|
|
2166
|
-
// a year rail beside the rows; undated entries (sorted last) form a final
|
|
2167
|
-
// group with no year label.
|
|
2168
|
-
const groups: { items: typeof items; year: string | null }[] = [];
|
|
2169
|
-
for (const item of items) {
|
|
2170
|
-
const last = groups[groups.length - 1];
|
|
2171
|
-
if (last && last.year === item.year) {
|
|
2172
|
-
last.items.push(item);
|
|
2173
|
-
} else {
|
|
2174
|
-
groups.push({ items: [item], year: item.year });
|
|
2175
|
-
}
|
|
2176
|
-
}
|
|
2177
|
-
|
|
2178
2112
|
const base = data.config.site ? data.config.site.replace(/\\/$/, "") : null;
|
|
2179
2113
|
// The canonical URL carries the deployment base (the page is served under it),
|
|
2180
2114
|
// matching how the catch-all canonicalizes via \`withMountedBase(route)\`.
|
|
@@ -2187,15 +2121,16 @@ const canonical = base ? base + basedRoute : null;
|
|
|
2187
2121
|
const ogPath = data.config.og.enabled ? withMountedBase("/og/changelog.png") : null;
|
|
2188
2122
|
const ogImage = ogPath && base ? base + ogPath : ogPath;
|
|
2189
2123
|
|
|
2190
|
-
// The page chrome (h1, title, description
|
|
2191
|
-
//
|
|
2124
|
+
// The page chrome (h1, title, description) comes from the translatable
|
|
2125
|
+
// \`changelog\` group, which carries the \`changelog\` config's title and
|
|
2192
2126
|
// description when it sets them; optional chaining tolerates a
|
|
2193
|
-
// not-yet-regenerated data snapshot from before these keys existed.
|
|
2127
|
+
// not-yet-regenerated data snapshot from before these keys existed. The list
|
|
2128
|
+
// itself is \`<Changelog />\`, the same component an authored page can place to
|
|
2129
|
+
// put prose above it.
|
|
2194
2130
|
const changelogTitle = data.ui.changelog?.title ?? "Changelog";
|
|
2195
2131
|
const changelogDescription =
|
|
2196
2132
|
data.ui.changelog?.description ??
|
|
2197
2133
|
"Product updates, new features, and fixes from every release.";
|
|
2198
|
-
const changelogEmpty = data.ui.changelog?.empty ?? "No changelog entries yet.";
|
|
2199
2134
|
// The layout suffixes "- {site title}" itself, so the page title is just the
|
|
2200
2135
|
// changelog's own name — prefixing the site title too would double it
|
|
2201
2136
|
// ("Acme Changelog - Acme").
|
|
@@ -2246,51 +2181,7 @@ const LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);
|
|
|
2246
2181
|
>
|
|
2247
2182
|
<h1>{changelogTitle}</h1>
|
|
2248
2183
|
<p class="text-lg text-muted-foreground">{changelogDescription}</p>
|
|
2249
|
-
|
|
2250
|
-
items.length === 0 ? (
|
|
2251
|
-
<p>{changelogEmpty}</p>
|
|
2252
|
-
) : (
|
|
2253
|
-
<div class="not-prose mt-10 divide-y divide-border border-border border-y">
|
|
2254
|
-
{groups.map((group) => (
|
|
2255
|
-
<section
|
|
2256
|
-
aria-label={group.year ?? undefined}
|
|
2257
|
-
class="grid md:grid-cols-[6rem_minmax(0,1fr)] md:gap-x-8"
|
|
2258
|
-
>
|
|
2259
|
-
<h2 class="mt-0! pt-3! font-medium! text-muted-foreground text-sm! leading-5! tabular-nums max-md:pb-1">
|
|
2260
|
-
{group.year}
|
|
2261
|
-
</h2>
|
|
2262
|
-
<ul class="m-0! list-none divide-y divide-border p-0!">
|
|
2263
|
-
{group.items.map((item) => (
|
|
2264
|
-
<li class="m-0! p-0!" id={item.id}>
|
|
2265
|
-
<a
|
|
2266
|
-
class="group/release flex items-baseline gap-4 py-3 no-underline! hover:no-underline!"
|
|
2267
|
-
href={item.href ?? "#" + item.id}
|
|
2268
|
-
>
|
|
2269
|
-
<span class="min-w-0 flex-1 font-medium text-foreground text-sm transition-colors group-hover/release:text-accent">
|
|
2270
|
-
{item.label}
|
|
2271
|
-
</span>
|
|
2272
|
-
{item.tag && (
|
|
2273
|
-
<span class="shrink-0 rounded-full bg-muted px-2 py-0.5 font-medium text-[0.65rem] text-muted-foreground">
|
|
2274
|
-
{item.tag}
|
|
2275
|
-
</span>
|
|
2276
|
-
)}
|
|
2277
|
-
{item.date && (
|
|
2278
|
-
<time
|
|
2279
|
-
class="shrink-0 font-mono text-muted-foreground text-xs tabular-nums"
|
|
2280
|
-
datetime={item.dateTime}
|
|
2281
|
-
>
|
|
2282
|
-
{item.date}
|
|
2283
|
-
</time>
|
|
2284
|
-
)}
|
|
2285
|
-
</a>
|
|
2286
|
-
</li>
|
|
2287
|
-
))}
|
|
2288
|
-
</ul>
|
|
2289
|
-
</section>
|
|
2290
|
-
))}
|
|
2291
|
-
</div>
|
|
2292
|
-
)
|
|
2293
|
-
}
|
|
2184
|
+
<Changelog />
|
|
2294
2185
|
</LayoutComponent>
|
|
2295
2186
|
`;
|
|
2296
2187
|
};
|
|
@@ -2801,5 +2692,5 @@ var runtimeTsconfigTemplate = () => `${JSON.stringify({
|
|
|
2801
2692
|
|
|
2802
2693
|
export { deployOutputDir, deployStaticDir, surfaceAdapterOutput, planComponentSlots, publishRuntimeModules, runtimeDependencies, EJECTED_CONFIG_HEADER, astroConfigTemplate, stagedContentDir, contentConfigTemplate, askEndpointTemplate, askComponentTemplate, searchEndpointTemplate, featuresTemplate, consentClientTemplate, searchClientTemplate, mixedbreadSearchEndpointTemplate, rawMarkdownEndpointTemplate, contentAssetsEndpointTemplate, mcpPageFile, mcpEndpointTemplate, playgroundProxyTemplate, staticJsonEndpointTemplate, rssEndpointTemplate, navFragmentTemplate, ogEndpointTemplate, scalarReferenceTemplate, catchAllPageTemplate, changelogIndexTemplate, notFoundPageTemplate, notFoundMarkdownTemplate, notFoundJsonTemplate, apiPagesIndexTemplate, apiPageTemplate, apiNavigationTemplate, apiSearchTemplate, apiNotFoundTemplate, exampleSlug, exampleWrapperTemplate, examplesRouteBase, exampleMapTemplate, examplesPageTemplate, runtimePackageTemplate, runtimeTsconfigTemplate };
|
|
2803
2694
|
|
|
2804
|
-
//# debugId=
|
|
2805
|
-
//# sourceMappingURL=chunk-
|
|
2695
|
+
//# debugId=68D6AC80F8EF84D964756E2164756E21
|
|
2696
|
+
//# sourceMappingURL=chunk-as09pafp.js.map
|