blume 2.1.3 → 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 +126 -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 +4 -4
- 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
|
@@ -3,7 +3,7 @@ import { setTimeout as sleep } from "node:timers/promises";
|
|
|
3
3
|
import pLimit from "p-limit";
|
|
4
4
|
import { join } from "pathe";
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { youtubeEmbedSrc } from "../../components/content/youtube.ts";
|
|
7
7
|
import { BlumeError } from "../diagnostics.ts";
|
|
8
8
|
import matter from "../frontmatter.ts";
|
|
9
9
|
import { nodeRequire } from "../node-require.ts";
|
|
@@ -316,12 +316,13 @@ const FRAME_ESCAPED = /\\(?=[<>])/gu;
|
|
|
316
316
|
|
|
317
317
|
const YOUTUBE_HOST = /(?:^|\.)(?:youtube(?:-nocookie)?\.com|youtu\.be)$/u;
|
|
318
318
|
|
|
319
|
-
// `
|
|
319
|
+
// `youtubeEmbedSrc` is host-agnostic on purpose (the component accepts bare
|
|
320
320
|
// ids), so gate on the hostname first: `https://cdn.example.com/live/promo.mp4`
|
|
321
|
-
// matches its `/live/<11 chars>` shape but is a media file, not an embed.
|
|
321
|
+
// matches its `/live/<11 chars>` shape but is a media file, not an embed. A
|
|
322
|
+
// playlist URL embeds too.
|
|
322
323
|
const isYouTubeUrl = (url: string): boolean => {
|
|
323
324
|
const host = URL.parse(url)?.hostname ?? "";
|
|
324
|
-
return YOUTUBE_HOST.test(host) &&
|
|
325
|
+
return YOUTUBE_HOST.test(host) && youtubeEmbedSrc(url) !== null;
|
|
325
326
|
};
|
|
326
327
|
|
|
327
328
|
/**
|
|
@@ -9,7 +9,7 @@ import { nextFenceState } from "../code-fences.ts";
|
|
|
9
9
|
import type { FenceState } from "../code-fences.ts";
|
|
10
10
|
import { BlumeError } from "../diagnostics.ts";
|
|
11
11
|
import matter from "../frontmatter.ts";
|
|
12
|
-
import {
|
|
12
|
+
import { BUILT_IN_PAGE_META_KEYS } from "../schema.ts";
|
|
13
13
|
import type { ResolvedI18nConfig, ResolvedVersionsConfig } from "../schema.ts";
|
|
14
14
|
import type { Diagnostic } from "../types.ts";
|
|
15
15
|
import { hashText } from "./cache.ts";
|
|
@@ -139,9 +139,6 @@ const OBSIDIAN_NATIVE_KEYS = new Set([
|
|
|
139
139
|
"tags",
|
|
140
140
|
]);
|
|
141
141
|
|
|
142
|
-
/** Every key Blume's page meta schema accepts. */
|
|
143
|
-
const PAGE_META_KEYS = new Set<string>(pageMetaSchema.keyof().options);
|
|
144
|
-
|
|
145
142
|
/**
|
|
146
143
|
* A note's route input: its locale- and version-stripped path, slugged. Vault
|
|
147
144
|
* filenames are prose (`Getting Started.md`) and the route mapper does not
|
|
@@ -759,7 +756,7 @@ const noteToEntry = (
|
|
|
759
756
|
Object.entries(note.data).filter(
|
|
760
757
|
([key]) =>
|
|
761
758
|
!OBSIDIAN_NATIVE_KEYS.has(key) &&
|
|
762
|
-
(
|
|
759
|
+
(BUILT_IN_PAGE_META_KEYS.has(key) || keep.has(key))
|
|
763
760
|
)
|
|
764
761
|
);
|
|
765
762
|
const merged = title === undefined ? data : { ...data, title };
|
|
@@ -67,6 +67,16 @@ export interface SourceEntry {
|
|
|
67
67
|
};
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
/**
|
|
71
|
+
* A redirect a source asks for: from a route one of its pages used to have
|
|
72
|
+
* to the route it has now, both locale-stripped and without `basePath`, as
|
|
73
|
+
* the page routes its entries map to.
|
|
74
|
+
*/
|
|
75
|
+
export interface SourceRedirect {
|
|
76
|
+
from: string;
|
|
77
|
+
to: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
70
80
|
/** The result of a single `ContentSource.load()` call. */
|
|
71
81
|
export interface SourceLoadResult {
|
|
72
82
|
entries: SourceEntry[];
|
|
@@ -80,6 +90,13 @@ export interface SourceLoadResult {
|
|
|
80
90
|
* beneath user-authored meta files, which always win.
|
|
81
91
|
*/
|
|
82
92
|
folderMeta?: Record<string, FolderMeta>;
|
|
93
|
+
/**
|
|
94
|
+
* Redirects from routes the source's pages moved off: the OpenAPI source
|
|
95
|
+
* keeps the URLs earlier releases gave operation pages working. Added to
|
|
96
|
+
* the config's `redirects` after them, skipping any whose `from` a page or
|
|
97
|
+
* a configured redirect already owns.
|
|
98
|
+
*/
|
|
99
|
+
redirects?: SourceRedirect[];
|
|
83
100
|
}
|
|
84
101
|
|
|
85
102
|
/**
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { statSync } from "node:fs";
|
|
2
|
+
|
|
3
|
+
import { join } from "pathe";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Whether a root-relative path names a file the site serves outside its pages,
|
|
7
|
+
* as a static host answers it: a file in `public/`, a `public/` folder's
|
|
8
|
+
* `index.html` (`/demo` and `/demo/` for `public/demo/index.html`), or one of
|
|
9
|
+
* the files Blume generates (`generated`, base-less paths like `/llms.txt`;
|
|
10
|
+
* see `deploy/generated-files.ts`). `publicDir` is `null` when the project has
|
|
11
|
+
* no `public/` folder, which ships no files then. Paths come decoded, without
|
|
12
|
+
* `deployment.base`, which a host mounts `public/` under.
|
|
13
|
+
*/
|
|
14
|
+
export const staticFileResolver = (
|
|
15
|
+
publicDir: string | null,
|
|
16
|
+
generated: Iterable<string> = []
|
|
17
|
+
): ((path: string) => boolean) => {
|
|
18
|
+
const files = new Set(generated);
|
|
19
|
+
return (path) => {
|
|
20
|
+
const folder = path.endsWith("/");
|
|
21
|
+
const trimmed = folder ? path.slice(0, -1) : path;
|
|
22
|
+
if (files.has(trimmed)) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
if (publicDir === null) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
const target = join(publicDir, trimmed);
|
|
29
|
+
const stat = statSync(target, { throwIfNoEntry: false });
|
|
30
|
+
if (stat?.isDirectory()) {
|
|
31
|
+
return (
|
|
32
|
+
statSync(join(target, "index.html"), {
|
|
33
|
+
throwIfNoEntry: false,
|
|
34
|
+
})?.isFile() === true
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
// A host answers `/spec.pdf/` with a 404: only a folder takes the slash.
|
|
38
|
+
return !folder && stat?.isFile() === true;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a static host does with the URLs `blume dev` and `blume preview`
|
|
3
|
+
* would otherwise answer on their own terms. Astro's `trailingSlash: "never"`
|
|
4
|
+
* has both 404 a slashed URL (`/guide/`), which every host answers: Vercel
|
|
5
|
+
* redirects it to `/guide`, and the others serve `guide/index.html`. And a
|
|
6
|
+
* folder of HTML shipped in `public/` (`public/demo/index.html`) is served at
|
|
7
|
+
* `/demo/`, `/demo` redirecting there, so the relative links inside it
|
|
8
|
+
* resolve against the folder; the dev server 404s both spellings, and Vite's
|
|
9
|
+
* preview serves only the slashless one.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { statSync } from "node:fs";
|
|
13
|
+
import type { IncomingMessage, Server, ServerResponse } from "node:http";
|
|
14
|
+
|
|
15
|
+
import { join, resolve } from "pathe";
|
|
16
|
+
|
|
17
|
+
import { stripBasePath } from "./base-path.ts";
|
|
18
|
+
import { trimEnd } from "./trim.ts";
|
|
19
|
+
|
|
20
|
+
/** How to answer a request ahead of the server's own handlers. */
|
|
21
|
+
export type HostAnswer =
|
|
22
|
+
| { kind: "redirect"; location: string; status: number }
|
|
23
|
+
| { kind: "rewrite"; url: string };
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The paths Astro keeps out of its trailing-slash handling (`/_astro/`,
|
|
27
|
+
* `/@vite/`, `/.well-known/`, `//`), and the root.
|
|
28
|
+
*/
|
|
29
|
+
const UNHANDLED_PATH = /^\/(?:[_@./]|$)/u;
|
|
30
|
+
|
|
31
|
+
/** A request URL's path and its query string, `?` included. */
|
|
32
|
+
const splitUrl = (url: string): { pathname: string; search: string } => {
|
|
33
|
+
const queryAt = url.search(/[?#]/u);
|
|
34
|
+
return queryAt === -1
|
|
35
|
+
? { pathname: url, search: "" }
|
|
36
|
+
: { pathname: url.slice(0, queryAt), search: url.slice(queryAt) };
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Whether `public/<path>/index.html` exists: a folder of HTML the site ships
|
|
41
|
+
* as is. `path` is the decoded request path with `deployment.base` stripped.
|
|
42
|
+
*/
|
|
43
|
+
export const publicFolder = (publicDir: string) => {
|
|
44
|
+
const root = resolve(publicDir);
|
|
45
|
+
return (path: string): boolean => {
|
|
46
|
+
const index = join(root, path, "index.html");
|
|
47
|
+
if (!index.startsWith(`${root}/`)) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
return statSync(index).isFile();
|
|
52
|
+
} catch {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* How a static host answers a URL's trailing slash, or null to leave the
|
|
60
|
+
* request alone. A slashed URL redirects to its slashless page, its query
|
|
61
|
+
* kept, unless it names a public folder, which serves its `index.html`; a
|
|
62
|
+
* slashless public folder redirects to its slashed URL. `base` is the
|
|
63
|
+
* normalized `deployment.base`, which the URL carries and `public/` doesn't.
|
|
64
|
+
* The redirect is a `301`, a `308` for a method a `301` would turn into a
|
|
65
|
+
* `GET`, as Astro answers on a server-rendered route.
|
|
66
|
+
*/
|
|
67
|
+
export const trailingSlashAnswer = (
|
|
68
|
+
request: Pick<IncomingMessage, "method" | "url">,
|
|
69
|
+
base: string,
|
|
70
|
+
isPublicFolder: (path: string) => boolean
|
|
71
|
+
): HostAnswer | null => {
|
|
72
|
+
const { pathname, search } = splitUrl(request.url ?? "/");
|
|
73
|
+
if (UNHANDLED_PATH.test(pathname)) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
let path: string;
|
|
77
|
+
try {
|
|
78
|
+
path = decodeURIComponent(stripBasePath(base, pathname));
|
|
79
|
+
} catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
const status =
|
|
83
|
+
request.method === "GET" || request.method === "HEAD" ? 301 : 308;
|
|
84
|
+
if (!pathname.endsWith("/")) {
|
|
85
|
+
return isPublicFolder(path)
|
|
86
|
+
? { kind: "redirect", location: `${pathname}/${search}`, status }
|
|
87
|
+
: null;
|
|
88
|
+
}
|
|
89
|
+
const slashless = trimEnd(pathname, "/");
|
|
90
|
+
return isPublicFolder(trimEnd(path, "/"))
|
|
91
|
+
? { kind: "rewrite", url: `${slashless}/index.html${search}` }
|
|
92
|
+
: { kind: "redirect", location: `${slashless}${search}`, status };
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Answer every request on `server` with `answer` first: a redirect is sent
|
|
97
|
+
* then and there, and a rewrite changes the URL the server's own handlers
|
|
98
|
+
* (Vite's middleware) then see. They're the request listeners the server
|
|
99
|
+
* already has, so this goes ahead of every middleware, Astro's included.
|
|
100
|
+
*/
|
|
101
|
+
export const answerRequestsFirst = (
|
|
102
|
+
server: Server,
|
|
103
|
+
answer: (request: IncomingMessage) => HostAnswer | null,
|
|
104
|
+
headers: Record<string, string> = {}
|
|
105
|
+
): void => {
|
|
106
|
+
const handlers = server.listeners("request");
|
|
107
|
+
server.removeAllListeners("request");
|
|
108
|
+
server.on("request", (request: IncomingMessage, response: ServerResponse) => {
|
|
109
|
+
const answered = answer(request);
|
|
110
|
+
if (answered?.kind === "redirect") {
|
|
111
|
+
response.writeHead(answered.status, {
|
|
112
|
+
...headers,
|
|
113
|
+
Location: answered.location,
|
|
114
|
+
});
|
|
115
|
+
response.end();
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (answered) {
|
|
119
|
+
request.url = answered.url;
|
|
120
|
+
}
|
|
121
|
+
for (const handler of handlers) {
|
|
122
|
+
handler.call(server, request, response);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
|
|
3
|
+
import { imageMetadata } from "astro/assets/utils";
|
|
4
|
+
import { dirname, extname } from "pathe";
|
|
5
|
+
|
|
6
|
+
import { contentAssetParam, contentAssetUrl } from "./content-assets.ts";
|
|
7
|
+
import { resolveRelativeImage } from "./relative-files.ts";
|
|
8
|
+
import type { Diagnostic, PageRecord } from "./types.ts";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Colocated SVGs Astro's image pipeline can't measure. Astro reads an image's
|
|
12
|
+
* size before it optimizes it, and for an SVG it looks for the `<svg>` tag in
|
|
13
|
+
* the file's first 1,000 bytes only, then needs a width and height or a
|
|
14
|
+
* viewBox on that tag. A draw.io export carries its whole diagram in a
|
|
15
|
+
* `content` attribute on the tag, which pushes the tag's end past that
|
|
16
|
+
* window, so one diagram fails the build (`NoImageMetadata`). Blume serves
|
|
17
|
+
* such an SVG as it is instead, from the endpoint that already serves content
|
|
18
|
+
* images to agents (`/blume-assets/content/…`), and warns about it
|
|
19
|
+
* (`BLUME_SVG_UNOPTIMIZED`). A browser draws an SVG at any size, so the
|
|
20
|
+
* only loss is the intrinsic `width`/`height` the optimized `<img>` carries.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/** Whether the file at `path` is an SVG Astro can't read the size of. */
|
|
24
|
+
export const isUnmeasurableSvg = async (path: string): Promise<boolean> => {
|
|
25
|
+
if (extname(path).toLowerCase() !== ".svg") {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
let data: Buffer;
|
|
29
|
+
try {
|
|
30
|
+
data = await readFile(path);
|
|
31
|
+
} catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
await imageMetadata(data, path);
|
|
36
|
+
return false;
|
|
37
|
+
} catch {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The URL an unmeasurable SVG is served at, unbased (the base links plugin
|
|
44
|
+
* mounts `deployment.base`), or null when `target` isn't a colocated image
|
|
45
|
+
* Astro can measure no size for.
|
|
46
|
+
*/
|
|
47
|
+
export const unmeasurableSvgUrl = async (
|
|
48
|
+
sourceDir: string,
|
|
49
|
+
target: string,
|
|
50
|
+
projectRoot: string
|
|
51
|
+
): Promise<string | null> => {
|
|
52
|
+
const abs = resolveRelativeImage(sourceDir, target);
|
|
53
|
+
if (!(abs && (await isUnmeasurableSvg(abs)))) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
return contentAssetUrl(contentAssetParam(projectRoot, abs));
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* A warning for each image embed of a colocated SVG Astro can't measure, at
|
|
61
|
+
* the line that embeds it (in a partial, when an `<include>` brought it in).
|
|
62
|
+
*/
|
|
63
|
+
export const unmeasurableSvgDiagnostics = async (
|
|
64
|
+
pages: readonly PageRecord[]
|
|
65
|
+
): Promise<Diagnostic[]> => {
|
|
66
|
+
const seen = new Set<string>();
|
|
67
|
+
const embeds = pages.flatMap((page) => {
|
|
68
|
+
const { sourcePath } = page;
|
|
69
|
+
if (!sourcePath) {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
return page.links.flatMap((link) => {
|
|
73
|
+
const file = link.file ?? sourcePath;
|
|
74
|
+
const key = `${file}:${link.line}:${link.column}`;
|
|
75
|
+
if (!link.image || seen.has(key)) {
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
seen.add(key);
|
|
79
|
+
const abs = resolveRelativeImage(dirname(sourcePath), link.target);
|
|
80
|
+
return abs ? [{ abs, file, link }] : [];
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
const found = await Promise.all(
|
|
84
|
+
embeds.map(async (embed) =>
|
|
85
|
+
(await isUnmeasurableSvg(embed.abs)) ? [embed] : []
|
|
86
|
+
)
|
|
87
|
+
);
|
|
88
|
+
return found.flat().map(({ file, link }) => ({
|
|
89
|
+
code: "BLUME_SVG_UNOPTIMIZED",
|
|
90
|
+
column: link.column,
|
|
91
|
+
file,
|
|
92
|
+
line: link.line,
|
|
93
|
+
message: `\`${link.target}\` is served as it is, not optimized: Astro can't read its size, which takes the whole \`<svg>\` tag within the file's first 1,000 bytes, with a width and height or a viewBox.`,
|
|
94
|
+
severity: "warning",
|
|
95
|
+
suggestion:
|
|
96
|
+
"The image still shows. To have it optimized, put the `<svg>` tag's width and height (or viewBox) near the start of the file. In a draw.io export, the `content` attribute pushes them out: export without a copy of the diagram, or remove that attribute.",
|
|
97
|
+
}));
|
|
98
|
+
};
|