blume 2.1.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +94 -0
- package/dist/cli/{chunk-5cg2rzgf.js → chunk-073rdvgb.js} +19 -48
- package/dist/cli/{chunk-5cg2rzgf.js.map → chunk-073rdvgb.js.map} +4 -5
- package/dist/cli/{chunk-ga0pf4aj.js → chunk-0n9xkp3d.js} +12 -3
- package/dist/cli/{chunk-ga0pf4aj.js.map → chunk-0n9xkp3d.js.map} +3 -3
- package/dist/cli/chunk-150jk7km.js +52 -0
- package/dist/cli/chunk-150jk7km.js.map +10 -0
- package/dist/cli/{chunk-rekqz4qg.js → chunk-313vnn40.js} +16 -15
- package/dist/cli/chunk-313vnn40.js.map +10 -0
- package/dist/cli/{chunk-gp84za0h.js → chunk-3v3ffbrj.js} +2 -2
- package/dist/cli/{chunk-9xr4dgee.js → chunk-3x6x3pph.js} +29 -16
- package/dist/cli/chunk-3x6x3pph.js.map +10 -0
- package/dist/cli/{chunk-0gz36akr.js → chunk-42t4jxdx.js} +21 -5
- package/dist/cli/chunk-42t4jxdx.js.map +12 -0
- package/dist/cli/{chunk-ta27feev.js → chunk-54ztw1nj.js} +21 -2
- package/dist/cli/chunk-54ztw1nj.js.map +10 -0
- package/dist/cli/{chunk-jnwj5kjj.js → chunk-5vjtgs6e.js} +20 -7
- package/dist/cli/{chunk-jnwj5kjj.js.map → chunk-5vjtgs6e.js.map} +3 -3
- package/dist/cli/chunk-66w9j7p6.js +322 -0
- package/dist/cli/chunk-66w9j7p6.js.map +14 -0
- package/dist/cli/{chunk-nd1821sk.js → chunk-7ppf1rva.js} +32 -18
- package/dist/cli/chunk-7ppf1rva.js.map +10 -0
- package/dist/cli/{chunk-p804f3pe.js → chunk-8y2kmjv8.js} +6 -6
- package/dist/cli/{chunk-2f7n4qzt.js → chunk-c1y538kd.js} +1 -1
- package/dist/cli/{chunk-1n228xqb.js → chunk-c887fj0s.js} +2 -2
- package/dist/cli/{chunk-y5h4r2y0.js → chunk-cfyg47zg.js} +15 -5
- package/dist/cli/chunk-cfyg47zg.js.map +10 -0
- package/dist/cli/{chunk-cmtcnh9f.js → chunk-dzwehpy7.js} +2 -2
- package/dist/cli/{chunk-h2a48yhd.js → chunk-e6atmn4h.js} +119 -15
- package/dist/cli/{chunk-h2a48yhd.js.map → chunk-e6atmn4h.js.map} +10 -10
- package/dist/cli/{chunk-5ffywsmb.js → chunk-e8xw9qkh.js} +8 -6
- package/dist/cli/{chunk-5ffywsmb.js.map → chunk-e8xw9qkh.js.map} +3 -3
- package/dist/cli/{chunk-ntv4qrt7.js → chunk-e9q7a2ak.js} +14 -14
- package/dist/cli/{chunk-xkz5xbtv.js → chunk-ehweg4fr.js} +2366 -1114
- package/dist/cli/chunk-ehweg4fr.js.map +218 -0
- package/dist/cli/{chunk-zf748avv.js → chunk-ep6nd0rn.js} +176 -281
- package/dist/cli/{chunk-zf748avv.js.map → chunk-ep6nd0rn.js.map} +11 -12
- package/dist/cli/{chunk-yxmk4pec.js → chunk-fdrkhpjy.js} +16 -15
- package/dist/cli/{chunk-yxmk4pec.js.map → chunk-fdrkhpjy.js.map} +3 -3
- package/dist/cli/{chunk-5wj2qwn2.js → chunk-ft9vfys6.js} +4 -4
- package/dist/cli/{chunk-4h8z9vv5.js → chunk-gb420vvz.js} +89 -46
- package/dist/cli/chunk-gb420vvz.js.map +17 -0
- package/dist/cli/{chunk-713mngdq.js → chunk-hebn0tpx.js} +76 -10
- package/dist/cli/chunk-hebn0tpx.js.map +14 -0
- package/dist/cli/{chunk-2n4ps1b3.js → chunk-htrwgabr.js} +40 -22
- package/dist/cli/chunk-htrwgabr.js.map +15 -0
- package/dist/cli/{chunk-zhvd6adm.js → chunk-hx3xqnk9.js} +13 -13
- package/dist/cli/chunk-j134vrp2.js +65 -0
- package/dist/cli/chunk-j134vrp2.js.map +10 -0
- package/dist/cli/{chunk-y4ykbark.js → chunk-kma9f6sf.js} +2 -2
- package/dist/cli/{chunk-py62fewh.js → chunk-mrcccgnh.js} +3 -3
- package/dist/cli/{chunk-2f3ndkpw.js → chunk-n0v7m8ry.js} +3 -3
- package/dist/cli/{chunk-43zcf4gz.js → chunk-ncj7w596.js} +522 -353
- package/dist/cli/chunk-ncj7w596.js.map +35 -0
- package/dist/cli/{chunk-9geymqns.js → chunk-nq1d20w2.js} +14 -14
- package/dist/cli/{chunk-g2z9x01v.js → chunk-nrns10mj.js} +3 -3
- package/dist/cli/{chunk-e7vvk5ya.js → chunk-sds923fa.js} +3 -3
- package/dist/cli/{chunk-cy5bm0j0.js → chunk-t2m5j4pr.js} +2 -2
- package/dist/cli/{chunk-cy5bm0j0.js.map → chunk-t2m5j4pr.js.map} +1 -1
- package/dist/cli/{chunk-yj17vs39.js → chunk-tdqhyxfz.js} +5 -5
- package/dist/cli/{chunk-q3wxxq39.js → chunk-tphac74f.js} +5 -5
- package/dist/cli/{chunk-6bm0xpgd.js → chunk-w1r4vase.js} +2 -2
- package/dist/cli/index.js +24 -19
- package/dist/cli/index.js.map +3 -3
- package/dist/types/ai/ask-context.d.ts +6 -2
- package/dist/types/ai/component-markdown.d.ts +2 -0
- package/dist/types/ai/openapi-components.d.ts +4 -1
- package/dist/types/astro/integration.d.ts +5 -4
- package/dist/types/astro/markdown-negotiation.d.ts +3 -0
- package/dist/types/astro/pages.d.ts +10 -0
- package/dist/types/cli/init/scaffold.d.ts +1 -1
- package/dist/types/components/content/api-field.d.ts +4 -1
- package/dist/types/components/content/api-page.d.ts +6 -1
- package/dist/types/components/openapi/code-samples.d.ts +29 -0
- package/dist/types/components/openapi/helpers.d.ts +22 -1
- package/dist/types/components/openapi/security.d.ts +10 -0
- package/dist/types/components/openapi/snippets.d.ts +60 -0
- package/dist/types/core/changelog-index.d.ts +8 -0
- package/dist/types/core/config-input.d.ts +30 -3
- package/dist/types/core/data.d.ts +4 -0
- package/dist/types/core/i18n-ui.d.ts +2 -0
- package/dist/types/core/links.d.ts +8 -0
- package/dist/types/core/probe.d.ts +2 -0
- package/dist/types/core/project-graph.d.ts +6 -0
- package/dist/types/core/redirect-patterns.d.ts +11 -3
- package/dist/types/core/schema.d.ts +119 -0
- package/dist/types/core/sources/cache.d.ts +3 -0
- package/dist/types/core/sources/contentful-rich-text.d.ts +11 -2
- package/dist/types/core/sources/contentful.d.ts +17 -1
- package/dist/types/core/sources/lexical.d.ts +5 -0
- package/dist/types/core/sources/normalize.d.ts +20 -1
- package/dist/types/core/sources/remote.d.ts +37 -10
- package/dist/types/core/sources/sanity.d.ts +1 -1
- package/dist/types/core/types.d.ts +17 -0
- package/dist/types/deploy/adapter-output.d.ts +2 -1
- package/dist/types/deploy/adapters/cloudflare.d.ts +7 -5
- package/dist/types/deploy/adapters/node.d.ts +58 -23
- package/dist/types/deploy/adapters/registry.d.ts +10 -0
- package/dist/types/deploy/adapters/types.d.ts +3 -2
- package/dist/types/deploy/platforms/cloudflare.d.ts +10 -7
- package/dist/types/deploy/platforms/node.d.ts +3 -1
- package/dist/types/deploy/platforms/types.d.ts +18 -7
- package/dist/types/deploy/platforms/vercel.d.ts +20 -1
- package/dist/types/deploy/redirects.d.ts +17 -1
- package/dist/types/deploy/sitemap.d.ts +2 -1
- package/dist/types/deploy/vercel-negotiation.d.ts +42 -21
- package/dist/types/openapi/checks.d.ts +27 -0
- package/dist/types/openapi/graphql.d.ts +6 -0
- package/dist/types/openapi/model.d.ts +15 -4
- package/dist/types/openapi/parse.d.ts +3 -0
- package/dist/types/openapi/references.d.ts +16 -0
- package/dist/types/ratelimit/index.d.ts +1 -1
- package/dist/types/ratelimit/schema.d.ts +8 -0
- package/dist/types/ratelimit/upstash.d.ts +39 -14
- package/dist/types/reference/graphql.d.ts +76 -1
- package/dist/types/reference/index.d.ts +1 -1
- package/dist/types/reference/openapi.d.ts +2 -2
- package/dist/types/reference/options.d.ts +37 -1
- package/dist/types/reference/schema.d.ts +84 -0
- package/dist/types/search/adapters/registry.d.ts +3 -0
- package/dist/types/search/adapters/typesense.d.ts +14 -4
- package/dist/types/search/build.d.ts +3 -1
- package/dist/types/search/orama-index.d.ts +9 -9
- package/dist/types/search/sync/algolia.d.ts +5 -2
- package/dist/types/search/sync/index.d.ts +3 -1
- package/dist/types/search/sync/typesense.d.ts +11 -7
- package/dist/types/sources/contentful.d.ts +16 -0
- package/dist/types/sources/github-releases.d.ts +8 -1
- package/dist/types/sources/payload.d.ts +2 -0
- package/dist/types/sources/registry.d.ts +54 -0
- package/dist/types/sources/shared.d.ts +3 -0
- package/dist/types/sources/strapi.d.ts +2 -0
- package/docs/01-quickstart.mdx +4 -2
- package/docs/02-deployment.mdx +31 -13
- package/docs/advanced/changelog.mdx +11 -0
- package/docs/advanced/skills.mdx +1 -1
- package/docs/cli/audit.mdx +30 -7
- package/docs/cli/doctor.mdx +5 -1
- package/docs/cli/evals.mdx +4 -4
- package/docs/cli/translate.mdx +1 -0
- package/docs/cli/validate.mdx +4 -3
- package/docs/configuration/analytics.mdx +1 -1
- package/docs/configuration/assistant.mdx +6 -2
- package/docs/configuration/customization.mdx +4 -2
- package/docs/configuration/export.mdx +5 -3
- package/docs/configuration/index.mdx +3 -2
- package/docs/configuration/rate-limiting.mdx +23 -2
- package/docs/configuration/search.mdx +37 -14
- package/docs/content/components.mdx +2 -2
- package/docs/content/frontmatter.mdx +5 -3
- package/docs/content/i18n.mdx +2 -2
- package/docs/content/includes.mdx +1 -1
- package/docs/content/navigation.mdx +4 -4
- package/docs/content/sources/contentful.mdx +7 -4
- package/docs/content/sources/custom.mdx +7 -3
- package/docs/content/sources/github-releases.mdx +10 -2
- package/docs/content/sources/index.mdx +3 -3
- package/docs/content/sources/notion.mdx +1 -1
- package/docs/content/sources/obsidian.mdx +1 -1
- package/docs/content/sources/payload.mdx +3 -2
- package/docs/content/sources/remote-mdx.mdx +4 -0
- package/docs/content/sources/sanity.mdx +2 -2
- package/docs/content/sources/strapi.mdx +3 -2
- package/docs/content/syntax.mdx +2 -2
- package/docs/discoverability/agent-discovery.mdx +1 -1
- package/docs/discoverability/index.mdx +1 -1
- package/docs/discoverability/json-api.mdx +2 -0
- package/docs/discoverability/llms-txt.mdx +1 -1
- package/docs/discoverability/markdown.mdx +3 -1
- package/docs/discoverability/mcp.mdx +4 -0
- package/docs/discoverability/sitemap-and-robots.mdx +1 -1
- package/docs/references/api-pages.mdx +1 -1
- package/docs/references/asyncapi.mdx +3 -1
- package/docs/references/graphql.mdx +13 -1
- package/docs/references/openapi.mdx +50 -8
- package/package.json +9 -9
- package/skills/blume-migrate/SKILL.md +1 -1
- package/skills/blume-migrate/references/docusaurus.md +4 -4
- package/skills/blume-migrate/references/fumadocs.md +17 -13
- package/skills/blume-migrate/references/nextra.md +8 -5
- package/skills/blume-migrate/references/starlight.md +9 -7
- package/src/ai/ask-context.ts +33 -3
- package/src/ai/ask-limits.ts +13 -0
- package/src/ai/changelog-markdown.ts +11 -6
- package/src/ai/component-markdown.ts +1 -1
- package/src/ai/cors.ts +12 -3
- package/src/ai/mcp/query.ts +14 -6
- package/src/ai/openapi-components.ts +28 -4
- package/src/ai/relative-links.ts +4 -38
- package/src/astro/generate.ts +78 -48
- package/src/astro/integration.ts +16 -13
- package/src/astro/markdown-negotiation.ts +3 -0
- package/src/astro/module-types.ts +3 -1
- package/src/astro/pages.ts +23 -0
- package/src/astro/templates.ts +125 -80
- package/src/audit/catalog.ts +19 -3
- package/src/audit/checks/links.ts +14 -1
- package/src/audit/checks/network.ts +110 -6
- package/src/audit/checks/redirects.ts +6 -4
- package/src/audit/checks/robots.ts +58 -2
- package/src/audit/run.ts +3 -0
- package/src/audit/types.ts +2 -0
- package/src/audit/url.ts +14 -5
- package/src/blume-modules.d.ts +5 -1
- package/src/cli/args.ts +51 -0
- package/src/cli/build-failure.ts +23 -0
- package/src/cli/commands/audit.ts +10 -1
- package/src/cli/commands/dev.ts +18 -2
- package/src/cli/commands/doctor.ts +45 -12
- package/src/cli/commands/eval.ts +36 -4
- package/src/cli/commands/init.ts +6 -4
- package/src/cli/commands/validate.ts +10 -1
- package/src/cli/init/scaffold.ts +3 -3
- package/src/cli/prepare.ts +6 -3
- package/src/cli/required-secrets.ts +1 -1
- package/src/components/content/ApiPlayground.astro +6 -2
- package/src/components/content/api-field.ts +4 -1
- package/src/components/content/api-page.ts +31 -7
- package/src/components/content/mermaid-element.ts +15 -1
- package/src/components/islands/hooks.ts +27 -1
- package/src/components/layout/PageActions.astro +139 -24
- package/src/components/layout/RootLayout.astro +10 -2
- package/src/components/layout/Search.astro +17 -3
- package/src/components/layout/TableOfContents.astro +24 -17
- package/src/components/layout/head-scripts.ts +6 -1
- package/src/components/layout/search/algolia.ts +10 -1
- package/src/components/layout/search/analytics.ts +42 -14
- package/src/components/layout/search/endpoint.ts +48 -5
- package/src/components/layout/search/pagefind.ts +114 -5
- package/src/components/layout/search/types.ts +12 -0
- package/src/components/layout/search/typesense.ts +18 -6
- package/src/components/openapi/AsyncApiOperation.astro +14 -7
- package/src/components/openapi/Authorization.astro +10 -0
- package/src/components/openapi/GraphqlOperation.astro +5 -0
- package/src/components/openapi/Operation.astro +24 -1
- package/src/components/openapi/ParametersTable.astro +8 -4
- package/src/components/openapi/Playground.astro +7 -1
- package/src/components/openapi/RequestBody.astro +19 -2
- package/src/components/openapi/Responses.astro +1 -0
- package/src/components/openapi/SchemaTable.astro +15 -3
- package/src/components/openapi/async-snippets.ts +61 -5
- package/src/components/openapi/async.ts +123 -29
- package/src/components/openapi/graphql-helpers.ts +35 -12
- package/src/components/openapi/helpers.ts +36 -2
- package/src/components/openapi/message-model.ts +54 -11
- package/src/components/openapi/message.ts +14 -4
- package/src/components/openapi/operation-model.ts +16 -7
- package/src/components/openapi/playground-client.ts +24 -5
- package/src/components/openapi/playground-schema.ts +1 -1
- package/src/components/openapi/schema-tree.ts +44 -14
- package/src/components/openapi/security.ts +10 -0
- package/src/components/openapi/snippets.ts +5 -3
- package/src/components/openapi/validate-json.ts +4 -3
- package/src/core/changelog-index.ts +31 -1
- package/src/core/component-diagnostics.ts +53 -0
- package/src/core/component-overrides.ts +32 -0
- package/src/core/config-input.ts +31 -3
- package/src/core/data.ts +2 -0
- package/src/core/diagnostics.ts +5 -0
- package/src/core/i18n-ui.ts +2 -0
- package/src/core/includes.ts +1 -1
- package/src/core/links.ts +47 -17
- package/src/core/probe.ts +26 -6
- package/src/core/project-graph.ts +59 -18
- package/src/core/redirect-patterns.ts +36 -7
- package/src/core/schema.ts +21 -2
- package/src/core/sources/cache.ts +6 -0
- package/src/core/sources/contentful-rich-text.ts +29 -6
- package/src/core/sources/contentful.ts +135 -25
- package/src/core/sources/filesystem.ts +26 -4
- package/src/core/sources/github-releases.ts +12 -1
- package/src/core/sources/lexical.ts +15 -10
- package/src/core/sources/mdx-remote.ts +62 -10
- package/src/core/sources/normalize.ts +227 -41
- package/src/core/sources/notion.ts +7 -1
- package/src/core/sources/obsidian.ts +16 -3
- package/src/core/sources/payload.ts +38 -15
- package/src/core/sources/remote.ts +72 -15
- package/src/core/sources/resolve.ts +11 -1
- package/src/core/sources/sanity.ts +43 -25
- package/src/core/sources/strapi.ts +2 -2
- package/src/core/types.ts +18 -0
- package/src/core/ui-packs/ar.ts +1 -0
- package/src/core/ui-packs/bg.ts +1 -0
- package/src/core/ui-packs/bn.ts +1 -0
- package/src/core/ui-packs/ca.ts +1 -0
- package/src/core/ui-packs/cs.ts +1 -0
- package/src/core/ui-packs/da.ts +1 -0
- package/src/core/ui-packs/de.ts +1 -0
- package/src/core/ui-packs/el.ts +1 -0
- package/src/core/ui-packs/es.ts +1 -0
- package/src/core/ui-packs/fa.ts +1 -0
- package/src/core/ui-packs/fi.ts +1 -0
- package/src/core/ui-packs/fr.ts +1 -0
- package/src/core/ui-packs/he.ts +1 -0
- package/src/core/ui-packs/hi.ts +1 -0
- package/src/core/ui-packs/hr.ts +1 -0
- package/src/core/ui-packs/hu.ts +1 -0
- package/src/core/ui-packs/id.ts +1 -0
- package/src/core/ui-packs/it.ts +1 -0
- package/src/core/ui-packs/ja.ts +1 -0
- package/src/core/ui-packs/ko.ts +1 -0
- package/src/core/ui-packs/nl.ts +1 -0
- package/src/core/ui-packs/no.ts +1 -0
- package/src/core/ui-packs/pl.ts +1 -0
- package/src/core/ui-packs/pt-br.ts +1 -0
- package/src/core/ui-packs/pt.ts +1 -0
- package/src/core/ui-packs/ro.ts +1 -0
- package/src/core/ui-packs/ru.ts +1 -0
- package/src/core/ui-packs/sk.ts +1 -0
- package/src/core/ui-packs/sr.ts +1 -0
- package/src/core/ui-packs/sv.ts +1 -0
- package/src/core/ui-packs/th.ts +1 -0
- package/src/core/ui-packs/tr.ts +1 -0
- package/src/core/ui-packs/uk.ts +1 -0
- package/src/core/ui-packs/vi.ts +1 -0
- package/src/core/ui-packs/zh-tw.ts +1 -0
- package/src/core/ui-packs/zh.ts +1 -0
- package/src/deploy/adapter-output.ts +7 -2
- package/src/deploy/adapters/cloudflare.ts +7 -5
- package/src/deploy/adapters/node.ts +47 -9
- package/src/deploy/adapters/types.ts +7 -3
- package/src/deploy/artifacts.ts +2 -1
- package/src/deploy/platforms/cloudflare.ts +13 -9
- package/src/deploy/platforms/netlify.ts +2 -1
- package/src/deploy/platforms/node.ts +12 -2
- package/src/deploy/platforms/types.ts +21 -7
- package/src/deploy/platforms/vercel.ts +113 -16
- package/src/deploy/redirects.ts +66 -6
- package/src/deploy/rss.ts +3 -1
- package/src/deploy/sitemap.ts +39 -5
- package/src/deploy/vercel-negotiation.ts +290 -102
- package/src/eval/agents.ts +18 -1
- package/src/eval/prompts.ts +6 -3
- package/src/eval/report.ts +34 -13
- package/src/eval/run.ts +5 -0
- package/src/markdown/relative-links.ts +3 -2
- package/src/openapi/checks.ts +273 -0
- package/src/openapi/graphql-build.ts +21 -0
- package/src/openapi/graphql.ts +11 -0
- package/src/openapi/model.ts +15 -3
- package/src/openapi/parse.ts +127 -2
- package/src/openapi/references.ts +43 -3
- package/src/openapi/source.ts +39 -14
- package/src/ratelimit/index.ts +1 -1
- package/src/ratelimit/runtime.ts +37 -19
- package/src/ratelimit/upstash.ts +40 -10
- package/src/reference/graphql.ts +15 -1
- package/src/reference/index.ts +1 -0
- package/src/reference/openapi.ts +2 -2
- package/src/reference/options.ts +29 -1
- package/src/registry/eject.ts +3 -1
- package/src/search/adapters/locale-scope.ts +30 -0
- package/src/search/adapters/typesense.ts +14 -4
- package/src/search/build.ts +21 -3
- package/src/search/orama-index.ts +163 -31
- package/src/search/source-pages.ts +29 -0
- package/src/search/sync/algolia.ts +99 -9
- package/src/search/sync/index.ts +52 -13
- package/src/search/sync/typesense.ts +72 -27
- package/src/sources/contentful.ts +12 -0
- package/src/sources/github-releases.ts +7 -1
- package/src/sources/shared.ts +3 -0
- package/src/theme/entry.ts +29 -3
- package/src/translate/validate.ts +23 -1
- package/dist/cli/chunk-0gz36akr.js.map +0 -12
- package/dist/cli/chunk-2n4ps1b3.js.map +0 -15
- package/dist/cli/chunk-43zcf4gz.js.map +0 -36
- package/dist/cli/chunk-4ejxbzee.js +0 -39
- package/dist/cli/chunk-4ejxbzee.js.map +0 -10
- package/dist/cli/chunk-4h8z9vv5.js.map +0 -16
- package/dist/cli/chunk-713mngdq.js.map +0 -14
- package/dist/cli/chunk-9xr4dgee.js.map +0 -10
- package/dist/cli/chunk-amrb6hgh.js +0 -145
- package/dist/cli/chunk-amrb6hgh.js.map +0 -11
- package/dist/cli/chunk-nd1821sk.js.map +0 -10
- package/dist/cli/chunk-rekqz4qg.js.map +0 -10
- package/dist/cli/chunk-ta27feev.js.map +0 -10
- package/dist/cli/chunk-xkz5xbtv.js.map +0 -213
- package/dist/cli/chunk-y5h4r2y0.js.map +0 -10
- /package/dist/cli/{chunk-gp84za0h.js.map → chunk-3v3ffbrj.js.map} +0 -0
- /package/dist/cli/{chunk-p804f3pe.js.map → chunk-8y2kmjv8.js.map} +0 -0
- /package/dist/cli/{chunk-2f7n4qzt.js.map → chunk-c1y538kd.js.map} +0 -0
- /package/dist/cli/{chunk-1n228xqb.js.map → chunk-c887fj0s.js.map} +0 -0
- /package/dist/cli/{chunk-cmtcnh9f.js.map → chunk-dzwehpy7.js.map} +0 -0
- /package/dist/cli/{chunk-ntv4qrt7.js.map → chunk-e9q7a2ak.js.map} +0 -0
- /package/dist/cli/{chunk-5wj2qwn2.js.map → chunk-ft9vfys6.js.map} +0 -0
- /package/dist/cli/{chunk-zhvd6adm.js.map → chunk-hx3xqnk9.js.map} +0 -0
- /package/dist/cli/{chunk-y4ykbark.js.map → chunk-kma9f6sf.js.map} +0 -0
- /package/dist/cli/{chunk-py62fewh.js.map → chunk-mrcccgnh.js.map} +0 -0
- /package/dist/cli/{chunk-2f3ndkpw.js.map → chunk-n0v7m8ry.js.map} +0 -0
- /package/dist/cli/{chunk-9geymqns.js.map → chunk-nq1d20w2.js.map} +0 -0
- /package/dist/cli/{chunk-g2z9x01v.js.map → chunk-nrns10mj.js.map} +0 -0
- /package/dist/cli/{chunk-e7vvk5ya.js.map → chunk-sds923fa.js.map} +0 -0
- /package/dist/cli/{chunk-yj17vs39.js.map → chunk-tdqhyxfz.js.map} +0 -0
- /package/dist/cli/{chunk-q3wxxq39.js.map → chunk-tphac74f.js.map} +0 -0
- /package/dist/cli/{chunk-6bm0xpgd.js.map → chunk-w1r4vase.js.map} +0 -0
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
i18nDiagnostics,
|
|
7
7
|
blumeReferences,
|
|
8
8
|
frontmatter_default,
|
|
9
|
+
resolveLocalizable,
|
|
9
10
|
resolveDocsCollection,
|
|
10
11
|
CHANGELOG_INDEX_ROUTE,
|
|
11
12
|
hasChangelogIndex,
|
|
@@ -22,6 +23,7 @@ import {
|
|
|
22
23
|
pagesByRef,
|
|
23
24
|
buildNavigation,
|
|
24
25
|
PUBLIC_API_URL,
|
|
26
|
+
isPatternPath,
|
|
25
27
|
pathsUnderPattern,
|
|
26
28
|
hasVariables,
|
|
27
29
|
substituteVariables,
|
|
@@ -33,6 +35,7 @@ import {
|
|
|
33
35
|
slugify,
|
|
34
36
|
slugifyPath,
|
|
35
37
|
unloadablePathDiagnostic,
|
|
38
|
+
frontmatterYamlDiagnostic,
|
|
36
39
|
extractHeadings,
|
|
37
40
|
strippedLineOffset,
|
|
38
41
|
isStringValue,
|
|
@@ -73,7 +76,7 @@ import {
|
|
|
73
76
|
createModuleLoader,
|
|
74
77
|
resolveProjectContext,
|
|
75
78
|
loadConfig
|
|
76
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-ehweg4fr.js";
|
|
77
80
|
import {
|
|
78
81
|
getBlumeVersion,
|
|
79
82
|
BlumeError,
|
|
@@ -81,6 +84,7 @@ import {
|
|
|
81
84
|
} from "./index.js";
|
|
82
85
|
import {
|
|
83
86
|
trimChar,
|
|
87
|
+
normalizePath,
|
|
84
88
|
isInternalPath,
|
|
85
89
|
withBasePath,
|
|
86
90
|
mountBasePath
|
|
@@ -93,6 +97,232 @@ import {
|
|
|
93
97
|
ignoringWatchListener
|
|
94
98
|
} from "./chunk-kwrg63tm.js";
|
|
95
99
|
|
|
100
|
+
// src/theme/icon-kind.ts
|
|
101
|
+
var IMAGE_ICON = /^(?:https?:\/\/|data:image\/|\/|\.{1,2}\/)|\.(?:avif|gif|jpe?g|png|svg|webp)$/iu;
|
|
102
|
+
var INLINE_SVG = /^\s*<svg[\s\S]*<\/svg>\s*$/u;
|
|
103
|
+
var isImageIcon = (value) => IMAGE_ICON.test(value);
|
|
104
|
+
var isInlineSvg = (value) => INLINE_SVG.test(value);
|
|
105
|
+
var isAssetIcon = (value) => isInlineSvg(value) || isImageIcon(value);
|
|
106
|
+
|
|
107
|
+
// src/theme/icons.ts
|
|
108
|
+
import { createRequire } from "node:module";
|
|
109
|
+
import { getIconData, iconToSVG } from "@iconify/utils";
|
|
110
|
+
var requireJson = createRequire(import.meta.url);
|
|
111
|
+
var loadSet = (pkg) => requireJson(pkg);
|
|
112
|
+
var SETS = {
|
|
113
|
+
lucide: loadSet("@iconify-json/lucide/icons.json")
|
|
114
|
+
};
|
|
115
|
+
var DEFAULT_SET = "lucide";
|
|
116
|
+
var PREFIX_SETS = {
|
|
117
|
+
lucide: "lucide"
|
|
118
|
+
};
|
|
119
|
+
var ownEntry = (map, key) => Object.hasOwn(map, key) ? map[key] : undefined;
|
|
120
|
+
var normalize = (name) => name.trim().toLowerCase().replaceAll(/[\s_]+/gu, "-");
|
|
121
|
+
var fromSet = (setName, iconName) => {
|
|
122
|
+
const set = ownEntry(SETS, setName);
|
|
123
|
+
const data = set && getIconData(set, iconName);
|
|
124
|
+
if (!data) {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
const { attributes, body } = iconToSVG(data, { height: "auto" });
|
|
128
|
+
return { body, name: iconName, viewBox: attributes.viewBox };
|
|
129
|
+
};
|
|
130
|
+
var resolveIcon = (name) => {
|
|
131
|
+
const normalized = normalize(name);
|
|
132
|
+
const colon = normalized.indexOf(":");
|
|
133
|
+
if (colon > 0) {
|
|
134
|
+
const setName = ownEntry(PREFIX_SETS, normalized.slice(0, colon));
|
|
135
|
+
return setName ? fromSet(setName, normalized.slice(colon + 1)) : null;
|
|
136
|
+
}
|
|
137
|
+
return fromSet(DEFAULT_SET, normalized);
|
|
138
|
+
};
|
|
139
|
+
var hasIcon = (name) => resolveIcon(name) !== null;
|
|
140
|
+
|
|
141
|
+
// src/core/nav-diagnostics.ts
|
|
142
|
+
var ICON_FORMAT_HINT = "Use a built-in icon name, an image path/URL, or inline SVG markup.";
|
|
143
|
+
var flattenNodes = (nodes) => nodes.flatMap((node) => node.kind === "group" ? [node, ...flattenNodes(node.children)] : [node]);
|
|
144
|
+
var collectIcons = (navigation) => {
|
|
145
|
+
const icons = [];
|
|
146
|
+
const push = (icon, where) => {
|
|
147
|
+
if (icon) {
|
|
148
|
+
icons.push({ icon, where });
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
for (const tab of navigation.tabs) {
|
|
152
|
+
push(tab.icon, `tab "${tab.label}"`);
|
|
153
|
+
for (const item of tab.items ?? []) {
|
|
154
|
+
push(item.icon, `tab item "${item.label}"`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
for (const selector of navigation.selectors) {
|
|
158
|
+
for (const item of selector.items) {
|
|
159
|
+
push(item.icon, `selector "${item.label}"`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
for (const link of navigation.featured) {
|
|
163
|
+
push(link.icon, `featured link "${link.label}"`);
|
|
164
|
+
}
|
|
165
|
+
const sidebars = [navigation.sidebar];
|
|
166
|
+
for (const sidebar of sidebars) {
|
|
167
|
+
for (const node of flattenNodes(sidebar)) {
|
|
168
|
+
push(node.icon, `"${node.label}"`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return icons;
|
|
172
|
+
};
|
|
173
|
+
var unknownIconDiagnostics = (icons, suggestion) => {
|
|
174
|
+
const seen = new Set;
|
|
175
|
+
const diagnostics = [];
|
|
176
|
+
for (const { icon, where } of icons) {
|
|
177
|
+
if (isAssetIcon(icon) || hasIcon(icon) || seen.has(icon)) {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
seen.add(icon);
|
|
181
|
+
const message = icon.trimStart().startsWith("<") ? `Icon markup "${icon}" (${where}) isn't a complete inline <svg> element, so it won't render.` : `Unknown icon "${icon}" (${where}) — it isn't in Blume's icon set.`;
|
|
182
|
+
diagnostics.push({
|
|
183
|
+
code: "BLUME_UNKNOWN_ICON",
|
|
184
|
+
message,
|
|
185
|
+
severity: "warning",
|
|
186
|
+
suggestion
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
return diagnostics;
|
|
190
|
+
};
|
|
191
|
+
var validateNavIcons = (navigation) => unknownIconDiagnostics(collectIcons(navigation), ICON_FORMAT_HINT);
|
|
192
|
+
var validateSearchPopularIcons = (popular) => {
|
|
193
|
+
const icons = popular.flatMap((link) => link.icon ? [{ icon: link.icon, where: `popular link "${link.label}"` }] : []);
|
|
194
|
+
return unknownIconDiagnostics(icons, ICON_FORMAT_HINT);
|
|
195
|
+
};
|
|
196
|
+
var resolvesToPages = (routes, path) => routes.has(path) || [...routes].some((route) => route.startsWith(`${path}/`));
|
|
197
|
+
var validateNavTargets = (navigation, routes) => {
|
|
198
|
+
const targets = [
|
|
199
|
+
...navigation.tabs.map((tab) => ({ label: tab.label, path: tab.path })),
|
|
200
|
+
...navigation.selectors.flatMap((selector) => selector.items.map((item) => ({ label: item.label, path: item.path }))),
|
|
201
|
+
...navigation.featured.map((link) => ({
|
|
202
|
+
label: link.label,
|
|
203
|
+
path: link.href
|
|
204
|
+
})),
|
|
205
|
+
...(navigation.actions ?? []).map((action) => ({
|
|
206
|
+
label: action.label,
|
|
207
|
+
path: action.href
|
|
208
|
+
})),
|
|
209
|
+
...navigation.cta ? [{ label: navigation.cta.label, path: navigation.cta.href }] : []
|
|
210
|
+
];
|
|
211
|
+
const diagnostics = [];
|
|
212
|
+
const seen = new Set;
|
|
213
|
+
for (const { label, path } of targets) {
|
|
214
|
+
if (!isInternalPath(path) || path.startsWith("/#") || seen.has(path)) {
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
if (!resolvesToPages(routes, path.split(/[?#]/u)[0] ?? path)) {
|
|
218
|
+
seen.add(path);
|
|
219
|
+
diagnostics.push({
|
|
220
|
+
code: "BLUME_NAV_MISSING_PAGE",
|
|
221
|
+
message: `Navigation entry "${label}" points to ${path}, but no page matches it.`,
|
|
222
|
+
severity: "warning",
|
|
223
|
+
suggestion: "Fix the path, or add a page at that route."
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return diagnostics;
|
|
228
|
+
};
|
|
229
|
+
var validateSidebarItems = (items, resolves) => {
|
|
230
|
+
const diagnostics = [];
|
|
231
|
+
const walk = (list) => {
|
|
232
|
+
for (const item of list) {
|
|
233
|
+
if (isPageRef(item)) {
|
|
234
|
+
if (!resolves(normalizeRef(item))) {
|
|
235
|
+
diagnostics.push({
|
|
236
|
+
code: "BLUME_NAV_MISSING_PAGE",
|
|
237
|
+
message: `Sidebar entry "${item}" matches no page, so it's left out of the sidebar.`,
|
|
238
|
+
severity: "warning",
|
|
239
|
+
suggestion: "Fix the route, or add a page at it."
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
if (item.root && !resolves(normalizeRef(item.root))) {
|
|
245
|
+
diagnostics.push({
|
|
246
|
+
code: "BLUME_NAV_MISSING_PAGE",
|
|
247
|
+
message: `Sidebar entry "${item.label}" has root "${item.root}", but no page matches it, so its link leads nowhere.`,
|
|
248
|
+
severity: "warning",
|
|
249
|
+
suggestion: "Fix the root, or add a page at that route."
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
if (item.items) {
|
|
253
|
+
walk(item.items);
|
|
254
|
+
} else if (!(item.root || item.href)) {
|
|
255
|
+
diagnostics.push({
|
|
256
|
+
code: "BLUME_NAV_EMPTY_ITEM",
|
|
257
|
+
message: `Sidebar entry "${item.label}" has no page, href, root, or items, so it's left out of the sidebar.`,
|
|
258
|
+
severity: "warning",
|
|
259
|
+
suggestion: "Give it an href or a root to link somewhere, or items to make it a group."
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
walk(items);
|
|
265
|
+
return diagnostics;
|
|
266
|
+
};
|
|
267
|
+
var duplicateLabelDiagnostics = (navigation) => {
|
|
268
|
+
const diagnostics = [];
|
|
269
|
+
const checkLevel = (nodes, where) => {
|
|
270
|
+
const counts = new Map;
|
|
271
|
+
for (const node of nodes) {
|
|
272
|
+
counts.set(node.label, (counts.get(node.label) ?? 0) + 1);
|
|
273
|
+
}
|
|
274
|
+
for (const [label, count] of counts) {
|
|
275
|
+
if (count > 1) {
|
|
276
|
+
diagnostics.push({
|
|
277
|
+
code: "BLUME_NAV_DUPLICATE_LABEL",
|
|
278
|
+
message: `Duplicate sidebar label "${label}" appears ${count} times ${where}.`,
|
|
279
|
+
severity: "warning",
|
|
280
|
+
suggestion: "Give the entries distinct titles."
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
for (const node of nodes) {
|
|
285
|
+
if (node.kind === "group") {
|
|
286
|
+
checkLevel(node.children, `under "${node.label}"`);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
const sidebars = [
|
|
291
|
+
{ nodes: navigation.sidebar, where: "at the top level" }
|
|
292
|
+
];
|
|
293
|
+
for (const { nodes, where } of sidebars) {
|
|
294
|
+
checkLevel(nodes, where);
|
|
295
|
+
}
|
|
296
|
+
return diagnostics;
|
|
297
|
+
};
|
|
298
|
+
var hiddenInSidebarDiagnostics = (navigation, pages) => {
|
|
299
|
+
const hidden = new Set(pages.flatMap((page) => page.meta.sidebar.hidden ? [page.id] : []));
|
|
300
|
+
if (hidden.size === 0) {
|
|
301
|
+
return [];
|
|
302
|
+
}
|
|
303
|
+
const sidebars = [navigation.sidebar];
|
|
304
|
+
const diagnostics = [];
|
|
305
|
+
const seen = new Set;
|
|
306
|
+
for (const sidebar of sidebars) {
|
|
307
|
+
for (const node of flattenNodes(sidebar)) {
|
|
308
|
+
if (node.kind === "page" && hidden.has(node.pageId) && !seen.has(node.pageId)) {
|
|
309
|
+
seen.add(node.pageId);
|
|
310
|
+
diagnostics.push({
|
|
311
|
+
code: "BLUME_NAV_HIDDEN_IN_SIDEBAR",
|
|
312
|
+
message: `Page "${node.label}" is marked hidden but appears in the sidebar (and its pagination).`,
|
|
313
|
+
severity: "warning",
|
|
314
|
+
suggestion: "Remove it from the navigation config, or unset sidebar.hidden."
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return diagnostics;
|
|
320
|
+
};
|
|
321
|
+
var validateNavStructure = (navigation, pages) => [
|
|
322
|
+
...duplicateLabelDiagnostics(navigation),
|
|
323
|
+
...hiddenInSidebarDiagnostics(navigation, pages)
|
|
324
|
+
];
|
|
325
|
+
|
|
96
326
|
// src/core/manifest.ts
|
|
97
327
|
var versionAlternateKey = (versionKey, locale) => `${versionKey}\x00${locale}`;
|
|
98
328
|
var versionAlternatesFor = (byKey, versionKey, locale) => {
|
|
@@ -251,304 +481,69 @@ var LITERAL_MARKERS = new Map([
|
|
|
251
481
|
var labelSource = (label) => label.length > 0 ? `[${mdastToString(label, { includeImageAlt: false })}]` : "";
|
|
252
482
|
var attributeSource = (node) => {
|
|
253
483
|
const attributes = Object.entries(node.attributes ?? {}).map(([key, value]) => value ? `${key}="${value}"` : key);
|
|
254
|
-
return attributes.length > 0 ? `{${attributes.join(" ")}}` : "";
|
|
255
|
-
};
|
|
256
|
-
var spannedSource = (node, source) => {
|
|
257
|
-
const start = node.position?.start?.offset;
|
|
258
|
-
const end = node.position?.end?.offset;
|
|
259
|
-
return start !== undefined && end !== undefined ? source.slice(start, end) : null;
|
|
260
|
-
};
|
|
261
|
-
var directiveSource = (node, marker, source) => {
|
|
262
|
-
const opening = `${marker}${node.name}`;
|
|
263
|
-
const slice = spannedSource(node, source);
|
|
264
|
-
if (slice?.startsWith(opening)) {
|
|
265
|
-
return slice;
|
|
266
|
-
}
|
|
267
|
-
return `${opening}${labelSource(node.children ?? [])}${attributeSource(node)}`;
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
// src/core/directive-diagnostics.ts
|
|
271
|
-
var CONTAINER_OPENING = /^[\t >]*:{3,}(?<name>[a-z][\w-]*)/gimu;
|
|
272
|
-
var codeList = (names) => [...names].map((name) => `\`${name}\``).join(", ");
|
|
273
|
-
var CALLOUT_NAMES = `${codeList(CALLOUT_TYPES)} (or the aliases ${codeList(Object.keys(CALLOUT_ALIASES))})`;
|
|
274
|
-
var unknownContainers = (text) => {
|
|
275
|
-
const named = [...text.matchAll(CONTAINER_OPENING)].some((match) => calloutTypeFor(match.groups?.name ?? "") === null);
|
|
276
|
-
if (!named) {
|
|
277
|
-
return [];
|
|
278
|
-
}
|
|
279
|
-
let tree;
|
|
280
|
-
try {
|
|
281
|
-
tree = mdxToMdast(text, { features: MDX_BODY_FEATURES });
|
|
282
|
-
} catch {
|
|
283
|
-
return [];
|
|
284
|
-
}
|
|
285
|
-
const found = [];
|
|
286
|
-
const walk = (node) => {
|
|
287
|
-
if (node.type === "containerDirective" && calloutTypeFor(node.name) === null) {
|
|
288
|
-
found.push({ line: node.position?.start.line ?? 1, name: node.name });
|
|
289
|
-
}
|
|
290
|
-
if ("children" in node) {
|
|
291
|
-
for (const child of node.children) {
|
|
292
|
-
walk(child);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
};
|
|
296
|
-
walk(tree);
|
|
297
|
-
return found;
|
|
298
|
-
};
|
|
299
|
-
var unknownDirectiveDiagnostics = (entry, sourceName) => {
|
|
300
|
-
if (entry.body.format !== "mdx") {
|
|
301
|
-
return [];
|
|
302
|
-
}
|
|
303
|
-
const page = entry.sourcePath ?? `${sourceName}:${entry.ref}`;
|
|
304
|
-
const offset = entry.bodyLineOffset ?? strippedLineOffset(entry.raw, entry.body.text);
|
|
305
|
-
return unknownContainers(entry.expanded?.text ?? entry.body.text).map(({ line, name }) => {
|
|
306
|
-
const origin = entry.expanded?.origins[line - 1];
|
|
307
|
-
return {
|
|
308
|
-
code: "BLUME_UNKNOWN_DIRECTIVE",
|
|
309
|
-
file: origin?.file ?? page,
|
|
310
|
-
line: origin?.line ?? line + offset,
|
|
311
|
-
message: `\`:::${name}\` isn't a callout type, so the page shows its \`:::\` lines as written around its content.`,
|
|
312
|
-
severity: "warning",
|
|
313
|
-
suggestion: `Use a callout type — ${CALLOUT_NAMES} — or remove the \`:::\` lines to keep the content as plain prose.`
|
|
314
|
-
};
|
|
315
|
-
});
|
|
316
|
-
};
|
|
317
|
-
|
|
318
|
-
// src/core/localizable.ts
|
|
319
|
-
var isSingleLabel = (label) => typeof label === "string";
|
|
320
|
-
var resolveLocalizable = (label, locale, defaultLocale) => {
|
|
321
|
-
if (isSingleLabel(label)) {
|
|
322
|
-
return label;
|
|
323
|
-
}
|
|
324
|
-
return (locale === undefined ? undefined : label[locale]) ?? (defaultLocale === undefined ? undefined : label[defaultLocale]) ?? Object.values(label)[0] ?? "";
|
|
325
|
-
};
|
|
326
|
-
|
|
327
|
-
// src/theme/icon-kind.ts
|
|
328
|
-
var IMAGE_ICON = /^(?:https?:\/\/|data:image\/|\/|\.{1,2}\/)|\.(?:avif|gif|jpe?g|png|svg|webp)$/iu;
|
|
329
|
-
var INLINE_SVG = /^\s*<svg[\s\S]*<\/svg>\s*$/u;
|
|
330
|
-
var isImageIcon = (value) => IMAGE_ICON.test(value);
|
|
331
|
-
var isInlineSvg = (value) => INLINE_SVG.test(value);
|
|
332
|
-
var isAssetIcon = (value) => isInlineSvg(value) || isImageIcon(value);
|
|
333
|
-
|
|
334
|
-
// src/theme/icons.ts
|
|
335
|
-
import { createRequire } from "node:module";
|
|
336
|
-
import { getIconData, iconToSVG } from "@iconify/utils";
|
|
337
|
-
var requireJson = createRequire(import.meta.url);
|
|
338
|
-
var loadSet = (pkg) => requireJson(pkg);
|
|
339
|
-
var SETS = {
|
|
340
|
-
lucide: loadSet("@iconify-json/lucide/icons.json")
|
|
341
|
-
};
|
|
342
|
-
var DEFAULT_SET = "lucide";
|
|
343
|
-
var PREFIX_SETS = {
|
|
344
|
-
lucide: "lucide"
|
|
345
|
-
};
|
|
346
|
-
var ownEntry = (map, key) => Object.hasOwn(map, key) ? map[key] : undefined;
|
|
347
|
-
var normalize = (name) => name.trim().toLowerCase().replaceAll(/[\s_]+/gu, "-");
|
|
348
|
-
var fromSet = (setName, iconName) => {
|
|
349
|
-
const set = ownEntry(SETS, setName);
|
|
350
|
-
const data = set && getIconData(set, iconName);
|
|
351
|
-
if (!data) {
|
|
352
|
-
return null;
|
|
353
|
-
}
|
|
354
|
-
const { attributes, body } = iconToSVG(data, { height: "auto" });
|
|
355
|
-
return { body, name: iconName, viewBox: attributes.viewBox };
|
|
356
|
-
};
|
|
357
|
-
var resolveIcon = (name) => {
|
|
358
|
-
const normalized = normalize(name);
|
|
359
|
-
const colon = normalized.indexOf(":");
|
|
360
|
-
if (colon > 0) {
|
|
361
|
-
const setName = ownEntry(PREFIX_SETS, normalized.slice(0, colon));
|
|
362
|
-
return setName ? fromSet(setName, normalized.slice(colon + 1)) : null;
|
|
363
|
-
}
|
|
364
|
-
return fromSet(DEFAULT_SET, normalized);
|
|
365
|
-
};
|
|
366
|
-
var hasIcon = (name) => resolveIcon(name) !== null;
|
|
367
|
-
|
|
368
|
-
// src/core/nav-diagnostics.ts
|
|
369
|
-
var ICON_FORMAT_HINT = "Use a built-in icon name, an image path/URL, or inline SVG markup.";
|
|
370
|
-
var flattenNodes = (nodes) => nodes.flatMap((node) => node.kind === "group" ? [node, ...flattenNodes(node.children)] : [node]);
|
|
371
|
-
var collectIcons = (navigation) => {
|
|
372
|
-
const icons = [];
|
|
373
|
-
const push = (icon, where) => {
|
|
374
|
-
if (icon) {
|
|
375
|
-
icons.push({ icon, where });
|
|
376
|
-
}
|
|
377
|
-
};
|
|
378
|
-
for (const tab of navigation.tabs) {
|
|
379
|
-
push(tab.icon, `tab "${tab.label}"`);
|
|
380
|
-
for (const item of tab.items ?? []) {
|
|
381
|
-
push(item.icon, `tab item "${item.label}"`);
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
for (const selector of navigation.selectors) {
|
|
385
|
-
for (const item of selector.items) {
|
|
386
|
-
push(item.icon, `selector "${item.label}"`);
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
for (const link of navigation.featured) {
|
|
390
|
-
push(link.icon, `featured link "${link.label}"`);
|
|
391
|
-
}
|
|
392
|
-
const sidebars = [navigation.sidebar];
|
|
393
|
-
for (const sidebar of sidebars) {
|
|
394
|
-
for (const node of flattenNodes(sidebar)) {
|
|
395
|
-
push(node.icon, `"${node.label}"`);
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
return icons;
|
|
399
|
-
};
|
|
400
|
-
var unknownIconDiagnostics = (icons, suggestion) => {
|
|
401
|
-
const seen = new Set;
|
|
402
|
-
const diagnostics = [];
|
|
403
|
-
for (const { icon, where } of icons) {
|
|
404
|
-
if (isAssetIcon(icon) || hasIcon(icon) || seen.has(icon)) {
|
|
405
|
-
continue;
|
|
406
|
-
}
|
|
407
|
-
seen.add(icon);
|
|
408
|
-
const message = icon.trimStart().startsWith("<") ? `Icon markup "${icon}" (${where}) isn't a complete inline <svg> element, so it won't render.` : `Unknown icon "${icon}" (${where}) — it isn't in Blume's icon set.`;
|
|
409
|
-
diagnostics.push({
|
|
410
|
-
code: "BLUME_UNKNOWN_ICON",
|
|
411
|
-
message,
|
|
412
|
-
severity: "warning",
|
|
413
|
-
suggestion
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
return diagnostics;
|
|
484
|
+
return attributes.length > 0 ? `{${attributes.join(" ")}}` : "";
|
|
417
485
|
};
|
|
418
|
-
var
|
|
419
|
-
|
|
420
|
-
const
|
|
421
|
-
return
|
|
486
|
+
var spannedSource = (node, source) => {
|
|
487
|
+
const start = node.position?.start?.offset;
|
|
488
|
+
const end = node.position?.end?.offset;
|
|
489
|
+
return start !== undefined && end !== undefined ? source.slice(start, end) : null;
|
|
422
490
|
};
|
|
423
|
-
var
|
|
424
|
-
|
|
425
|
-
const
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
...navigation.featured.map((link) => ({
|
|
429
|
-
label: link.label,
|
|
430
|
-
path: link.href
|
|
431
|
-
})),
|
|
432
|
-
...(navigation.actions ?? []).map((action) => ({
|
|
433
|
-
label: action.label,
|
|
434
|
-
path: action.href
|
|
435
|
-
})),
|
|
436
|
-
...navigation.cta ? [{ label: navigation.cta.label, path: navigation.cta.href }] : []
|
|
437
|
-
];
|
|
438
|
-
const diagnostics = [];
|
|
439
|
-
const seen = new Set;
|
|
440
|
-
for (const { label, path } of targets) {
|
|
441
|
-
if (!isInternalPath(path) || path.startsWith("/#") || seen.has(path)) {
|
|
442
|
-
continue;
|
|
443
|
-
}
|
|
444
|
-
if (!resolvesToPages(routes, path.split(/[?#]/u)[0] ?? path)) {
|
|
445
|
-
seen.add(path);
|
|
446
|
-
diagnostics.push({
|
|
447
|
-
code: "BLUME_NAV_MISSING_PAGE",
|
|
448
|
-
message: `Navigation entry "${label}" points to ${path}, but no page matches it.`,
|
|
449
|
-
severity: "warning",
|
|
450
|
-
suggestion: "Fix the path, or add a page at that route."
|
|
451
|
-
});
|
|
452
|
-
}
|
|
491
|
+
var directiveSource = (node, marker, source) => {
|
|
492
|
+
const opening = `${marker}${node.name}`;
|
|
493
|
+
const slice = spannedSource(node, source);
|
|
494
|
+
if (slice?.startsWith(opening)) {
|
|
495
|
+
return slice;
|
|
453
496
|
}
|
|
454
|
-
return
|
|
455
|
-
};
|
|
456
|
-
var validateSidebarItems = (items, resolves) => {
|
|
457
|
-
const diagnostics = [];
|
|
458
|
-
const walk = (list) => {
|
|
459
|
-
for (const item of list) {
|
|
460
|
-
if (isPageRef(item)) {
|
|
461
|
-
if (!resolves(normalizeRef(item))) {
|
|
462
|
-
diagnostics.push({
|
|
463
|
-
code: "BLUME_NAV_MISSING_PAGE",
|
|
464
|
-
message: `Sidebar entry "${item}" matches no page, so it's left out of the sidebar.`,
|
|
465
|
-
severity: "warning",
|
|
466
|
-
suggestion: "Fix the route, or add a page at it."
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
continue;
|
|
470
|
-
}
|
|
471
|
-
if (item.root && !resolves(normalizeRef(item.root))) {
|
|
472
|
-
diagnostics.push({
|
|
473
|
-
code: "BLUME_NAV_MISSING_PAGE",
|
|
474
|
-
message: `Sidebar entry "${item.label}" has root "${item.root}", but no page matches it, so its link leads nowhere.`,
|
|
475
|
-
severity: "warning",
|
|
476
|
-
suggestion: "Fix the root, or add a page at that route."
|
|
477
|
-
});
|
|
478
|
-
}
|
|
479
|
-
if (item.items) {
|
|
480
|
-
walk(item.items);
|
|
481
|
-
} else if (!(item.root || item.href)) {
|
|
482
|
-
diagnostics.push({
|
|
483
|
-
code: "BLUME_NAV_EMPTY_ITEM",
|
|
484
|
-
message: `Sidebar entry "${item.label}" has no page, href, root, or items, so it's left out of the sidebar.`,
|
|
485
|
-
severity: "warning",
|
|
486
|
-
suggestion: "Give it an href or a root to link somewhere, or items to make it a group."
|
|
487
|
-
});
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
};
|
|
491
|
-
walk(items);
|
|
492
|
-
return diagnostics;
|
|
497
|
+
return `${opening}${labelSource(node.children ?? [])}${attributeSource(node)}`;
|
|
493
498
|
};
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
499
|
+
|
|
500
|
+
// src/core/directive-diagnostics.ts
|
|
501
|
+
var CONTAINER_OPENING = /^[\t >]*:{3,}(?<name>[a-z][\w-]*)/gimu;
|
|
502
|
+
var codeList = (names) => [...names].map((name) => `\`${name}\``).join(", ");
|
|
503
|
+
var CALLOUT_NAMES = `${codeList(CALLOUT_TYPES)} (or the aliases ${codeList(Object.keys(CALLOUT_ALIASES))})`;
|
|
504
|
+
var unknownContainers = (text) => {
|
|
505
|
+
const named = [...text.matchAll(CONTAINER_OPENING)].some((match) => calloutTypeFor(match.groups?.name ?? "") === null);
|
|
506
|
+
if (!named) {
|
|
507
|
+
return [];
|
|
508
|
+
}
|
|
509
|
+
let tree;
|
|
510
|
+
try {
|
|
511
|
+
tree = mdxToMdast(text, { features: MDX_BODY_FEATURES });
|
|
512
|
+
} catch {
|
|
513
|
+
return [];
|
|
514
|
+
}
|
|
515
|
+
const found = [];
|
|
516
|
+
const walk = (node) => {
|
|
517
|
+
if (node.type === "containerDirective" && calloutTypeFor(node.name) === null) {
|
|
518
|
+
found.push({ line: node.position?.start.line ?? 1, name: node.name });
|
|
510
519
|
}
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
520
|
+
if ("children" in node) {
|
|
521
|
+
for (const child of node.children) {
|
|
522
|
+
walk(child);
|
|
514
523
|
}
|
|
515
524
|
}
|
|
516
525
|
};
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
];
|
|
520
|
-
for (const { nodes, where } of sidebars) {
|
|
521
|
-
checkLevel(nodes, where);
|
|
522
|
-
}
|
|
523
|
-
return diagnostics;
|
|
526
|
+
walk(tree);
|
|
527
|
+
return found;
|
|
524
528
|
};
|
|
525
|
-
var
|
|
526
|
-
|
|
527
|
-
if (hidden.size === 0) {
|
|
529
|
+
var unknownDirectiveDiagnostics = (entry, sourceName) => {
|
|
530
|
+
if (entry.body.format !== "mdx") {
|
|
528
531
|
return [];
|
|
529
532
|
}
|
|
530
|
-
const
|
|
531
|
-
const
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
return diagnostics;
|
|
533
|
+
const page = entry.sourcePath ?? `${sourceName}:${entry.ref}`;
|
|
534
|
+
const offset = entry.bodyLineOffset ?? strippedLineOffset(entry.raw, entry.body.text);
|
|
535
|
+
return unknownContainers(entry.expanded?.text ?? entry.body.text).map(({ line, name }) => {
|
|
536
|
+
const origin = entry.expanded?.origins[line - 1];
|
|
537
|
+
return {
|
|
538
|
+
code: "BLUME_UNKNOWN_DIRECTIVE",
|
|
539
|
+
file: origin?.file ?? page,
|
|
540
|
+
line: origin?.line ?? line + offset,
|
|
541
|
+
message: `\`:::${name}\` isn't a callout type, so the page shows its \`:::\` lines as written around its content.`,
|
|
542
|
+
severity: "warning",
|
|
543
|
+
suggestion: `Use a callout type — ${CALLOUT_NAMES} — or remove the \`:::\` lines to keep the content as plain prose.`
|
|
544
|
+
};
|
|
545
|
+
});
|
|
547
546
|
};
|
|
548
|
-
var validateNavStructure = (navigation, pages) => [
|
|
549
|
-
...duplicateLabelDiagnostics(navigation),
|
|
550
|
-
...hiddenInSidebarDiagnostics(navigation, pages)
|
|
551
|
-
];
|
|
552
547
|
|
|
553
548
|
// src/core/graph.ts
|
|
554
549
|
var collectRoutes = (pages) => {
|
|
@@ -1016,7 +1011,9 @@ var assetFromEntry = (asset) => {
|
|
|
1016
1011
|
return null;
|
|
1017
1012
|
}
|
|
1018
1013
|
return {
|
|
1014
|
+
contentType: asString(getPath(asset, "fields.file.contentType")),
|
|
1019
1015
|
description: asString(getPath(asset, "fields.description")),
|
|
1016
|
+
fileName: asString(getPath(asset, "fields.file.fileName")),
|
|
1020
1017
|
title: asString(getPath(asset, "fields.title")),
|
|
1021
1018
|
url: absoluteUrl(url)
|
|
1022
1019
|
};
|
|
@@ -1084,6 +1081,11 @@ var inlineNodeParts = (node, options) => {
|
|
|
1084
1081
|
case "asset-hyperlink": {
|
|
1085
1082
|
return linkParts(inlineParts(children(node), options), linkedAsset(node, options)?.url);
|
|
1086
1083
|
}
|
|
1084
|
+
case "entry-hyperlink": {
|
|
1085
|
+
const entry = linkedTarget(node, options.resolveEntry);
|
|
1086
|
+
const href = entry ? options.entryHref?.(entry) : undefined;
|
|
1087
|
+
return linkParts(inlineParts(children(node), options), href);
|
|
1088
|
+
}
|
|
1087
1089
|
case "embedded-entry-inline": {
|
|
1088
1090
|
return [{ markdown: embeddedEntry(node, options) }];
|
|
1089
1091
|
}
|
|
@@ -1135,7 +1137,14 @@ var renderBlock = (node, options) => {
|
|
|
1135
1137
|
}
|
|
1136
1138
|
case "embedded-asset-block": {
|
|
1137
1139
|
const asset = linkedAsset(node, options);
|
|
1138
|
-
|
|
1140
|
+
if (!asset) {
|
|
1141
|
+
return "";
|
|
1142
|
+
}
|
|
1143
|
+
if (asset.contentType && !asset.contentType.startsWith("image/")) {
|
|
1144
|
+
const label = asset.title ?? asset.fileName ?? asset.url;
|
|
1145
|
+
return renderInline(linkParts([{ marks: {}, text: label }], asset.url));
|
|
1146
|
+
}
|
|
1147
|
+
return image(asset.description ?? asset.title ?? "", asset.url);
|
|
1139
1148
|
}
|
|
1140
1149
|
case "embedded-entry-block": {
|
|
1141
1150
|
return embeddedEntry(node, options);
|
|
@@ -1157,9 +1166,17 @@ var remoteSource = (options, ctx) => {
|
|
|
1157
1166
|
let snapshot = new Map;
|
|
1158
1167
|
const load = async (refresh = ctx?.refresh ?? true) => {
|
|
1159
1168
|
options.assertConfigured?.();
|
|
1160
|
-
|
|
1169
|
+
let warnings = [];
|
|
1170
|
+
const result = await loadWithCache(options.name, cache, async () => {
|
|
1171
|
+
const found = [];
|
|
1172
|
+
const entries = await options.fetchEntries((diagnostic) => {
|
|
1173
|
+
found.push(diagnostic);
|
|
1174
|
+
});
|
|
1175
|
+
warnings = found;
|
|
1176
|
+
return entries;
|
|
1177
|
+
}, refresh);
|
|
1161
1178
|
snapshot = new Map(result.entries.map((entry) => [entry.ref, entry]));
|
|
1162
|
-
return result;
|
|
1179
|
+
return { ...result, diagnostics: [...result.diagnostics, ...warnings] };
|
|
1163
1180
|
};
|
|
1164
1181
|
const read = async (ref) => {
|
|
1165
1182
|
const cached = snapshot.get(ref);
|
|
@@ -1190,6 +1207,12 @@ var stagedEntry = (slug, data, markdown, lastModified, format = "md") => {
|
|
|
1190
1207
|
ref: `${slug}.${format}`
|
|
1191
1208
|
};
|
|
1192
1209
|
};
|
|
1210
|
+
var missingSecretError = (name, env) => new BlumeError({
|
|
1211
|
+
code: "BLUME_MISSING_SECRET",
|
|
1212
|
+
message: `Source "${name}" needs ${env}, which is not set.`,
|
|
1213
|
+
severity: "error",
|
|
1214
|
+
suggestion: `Set ${env} in .env.local for local dev, or in your host's environment for production.`
|
|
1215
|
+
});
|
|
1193
1216
|
var REMOTE_TIMEOUT_MS = 30000;
|
|
1194
1217
|
var fetchJson = async (url, client) => {
|
|
1195
1218
|
const doFetch = client.fetchImpl ?? globalThis.fetch;
|
|
@@ -1211,9 +1234,9 @@ var queryString = (params) => {
|
|
|
1211
1234
|
}
|
|
1212
1235
|
return search.toString();
|
|
1213
1236
|
};
|
|
1237
|
+
var documentSlug = (doc, slugField, id) => slugifyPath(asString(getPath(doc, slugField)) ?? id) || slugify(id) || "untitled";
|
|
1214
1238
|
var documentEntry = (doc, fields, id, lower, draft = false, lowersToMdx = false) => {
|
|
1215
|
-
const
|
|
1216
|
-
const slug = slugifyPath(slugValue) || slugify(id) || "untitled";
|
|
1239
|
+
const slug = documentSlug(doc, fields.slug, id);
|
|
1217
1240
|
const data = {};
|
|
1218
1241
|
const title = asString(getPath(doc, fields.title));
|
|
1219
1242
|
const description = asString(getPath(doc, fields.description));
|
|
@@ -1226,6 +1249,10 @@ var documentEntry = (doc, fields, id, lower, draft = false, lowersToMdx = false)
|
|
|
1226
1249
|
if (draft) {
|
|
1227
1250
|
data.draft = true;
|
|
1228
1251
|
}
|
|
1252
|
+
const order = fields.order ? asNumber(getPath(doc, fields.order)) : undefined;
|
|
1253
|
+
if (order !== undefined) {
|
|
1254
|
+
data.sidebar = { order };
|
|
1255
|
+
}
|
|
1229
1256
|
const body = getPath(doc, fields.body);
|
|
1230
1257
|
let markdown = "";
|
|
1231
1258
|
let format = "md";
|
|
@@ -1240,8 +1267,8 @@ var documentEntry = (doc, fields, id, lower, draft = false, lowersToMdx = false)
|
|
|
1240
1267
|
};
|
|
1241
1268
|
|
|
1242
1269
|
// src/core/sources/contentful.ts
|
|
1243
|
-
var DELIVERY_HOST = "
|
|
1244
|
-
var PREVIEW_HOST = "
|
|
1270
|
+
var DELIVERY_HOST = "cdn.contentful.com";
|
|
1271
|
+
var PREVIEW_HOST = "preview.contentful.com";
|
|
1245
1272
|
var PAGE_SIZE = 100;
|
|
1246
1273
|
var DEFAULT_FIELDS = {
|
|
1247
1274
|
body: "body",
|
|
@@ -1251,20 +1278,50 @@ var DEFAULT_FIELDS = {
|
|
|
1251
1278
|
title: "title"
|
|
1252
1279
|
};
|
|
1253
1280
|
var byId = (objects) => new Map(objects.map((object) => [asString(getPath(object, "sys.id")) ?? "", object]));
|
|
1281
|
+
var entryView = (item) => {
|
|
1282
|
+
const sys = asObject(item.sys) ?? {};
|
|
1283
|
+
return {
|
|
1284
|
+
id: asString(sys.id) ?? "",
|
|
1285
|
+
view: { ...asObject(item.fields), sys }
|
|
1286
|
+
};
|
|
1287
|
+
};
|
|
1254
1288
|
var contentfulSource = (options, ctx) => {
|
|
1255
1289
|
const fields = { ...DEFAULT_FIELDS, ...options.fields };
|
|
1256
|
-
const
|
|
1257
|
-
const
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1290
|
+
const routeOf = (view, id) => {
|
|
1291
|
+
const route = resolveEntryRoute({ ref: `${documentSlug(view, fields.slug, id)}.md` }, ".md", undefined, { i18n: options.i18n, prefix: options.prefix, versions: options.versions });
|
|
1292
|
+
return localizedRoute(route.logicalRoute, route.locales[0] ?? "", options.i18n);
|
|
1293
|
+
};
|
|
1294
|
+
const toEntry = (item, { assets, linked }, routes, warn) => {
|
|
1295
|
+
const { id, view } = entryView(item);
|
|
1296
|
+
const missing = new Set;
|
|
1297
|
+
const entry = documentEntry(view, fields, id, (body) => isJsonObject(body) ? contentfulRichTextToMarkdown(body, {
|
|
1298
|
+
entryHref: (target) => routes.get(asString(getPath(target, "sys.id")) ?? ""),
|
|
1261
1299
|
resolveAsset: (assetId) => {
|
|
1262
1300
|
const asset = assets.get(assetId);
|
|
1263
|
-
|
|
1301
|
+
if (!asset) {
|
|
1302
|
+
missing.add(`asset "${assetId}"`);
|
|
1303
|
+
return null;
|
|
1304
|
+
}
|
|
1305
|
+
return assetFromEntry(asset);
|
|
1306
|
+
},
|
|
1307
|
+
resolveEntry: (entryId) => {
|
|
1308
|
+
const target = linked.get(entryId);
|
|
1309
|
+
if (!target) {
|
|
1310
|
+
missing.add(`entry "${entryId}"`);
|
|
1311
|
+
}
|
|
1312
|
+
return target ?? null;
|
|
1264
1313
|
},
|
|
1265
|
-
resolveEntry: (entryId) => linked.get(entryId) ?? null,
|
|
1266
1314
|
serializers: options.serializers
|
|
1267
1315
|
}) : "", false, writesMdx(options.serializers));
|
|
1316
|
+
for (const link of missing) {
|
|
1317
|
+
warn({
|
|
1318
|
+
code: "BLUME_SOURCE_UNRESOLVED_LINK",
|
|
1319
|
+
message: `Source "${options.name}": "${entry.ref}" links to Contentful ${link}, which the response didn't include, so the page renders without it.`,
|
|
1320
|
+
severity: "warning",
|
|
1321
|
+
suggestion: "Publish the linked asset or entry, or remove the link: the Delivery API returns only published content."
|
|
1322
|
+
});
|
|
1323
|
+
}
|
|
1324
|
+
return entry;
|
|
1268
1325
|
};
|
|
1269
1326
|
const preview = ctx?.preview ?? false;
|
|
1270
1327
|
const previewToken = () => options.previewToken ?? process.env.CONTENTFUL_PREVIEW_TOKEN;
|
|
@@ -1278,15 +1335,18 @@ var contentfulSource = (options, ctx) => {
|
|
|
1278
1335
|
});
|
|
1279
1336
|
}
|
|
1280
1337
|
};
|
|
1281
|
-
const fetchEntries = async () => {
|
|
1338
|
+
const fetchEntries = async (warn) => {
|
|
1282
1339
|
const token = preview ? previewToken() : options.token ?? process.env.CONTENTFUL_ACCESS_TOKEN;
|
|
1340
|
+
if (!token) {
|
|
1341
|
+
throw missingSecretError(options.name, "CONTENTFUL_ACCESS_TOKEN");
|
|
1342
|
+
}
|
|
1283
1343
|
const client = {
|
|
1284
1344
|
fetchImpl: options.fetchImpl,
|
|
1285
|
-
headers:
|
|
1345
|
+
headers: { authorization: `Bearer ${token}` }
|
|
1286
1346
|
};
|
|
1287
|
-
const host = preview ? PREVIEW_HOST : DELIVERY_HOST;
|
|
1288
|
-
const base =
|
|
1289
|
-
const
|
|
1347
|
+
const host = preview ? options.previewHost ?? PREVIEW_HOST : options.host ?? DELIVERY_HOST;
|
|
1348
|
+
const base = `https://${host}/spaces/${options.space}/environments/${options.environment ?? "master"}/entries`;
|
|
1349
|
+
const pages = [];
|
|
1290
1350
|
let skip = 0;
|
|
1291
1351
|
let more = true;
|
|
1292
1352
|
while (more) {
|
|
@@ -1302,16 +1362,20 @@ var contentfulSource = (options, ctx) => {
|
|
|
1302
1362
|
if (!page) {
|
|
1303
1363
|
throw new Error("Contentful returned a non-object response");
|
|
1304
1364
|
}
|
|
1305
|
-
const assets = byId(objectsIn(getPath(page, "includes.Asset")));
|
|
1306
|
-
const linked = byId(objectsIn(getPath(page, "includes.Entry")));
|
|
1307
1365
|
const items = objectsIn(page.items);
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1366
|
+
pages.push({
|
|
1367
|
+
assets: byId(objectsIn(getPath(page, "includes.Asset"))),
|
|
1368
|
+
items,
|
|
1369
|
+
linked: byId([...objectsIn(getPath(page, "includes.Entry")), ...items])
|
|
1370
|
+
});
|
|
1311
1371
|
skip += items.length;
|
|
1312
1372
|
more = items.length > 0 && skip < (asNumber(page.total) ?? 0);
|
|
1313
1373
|
}
|
|
1314
|
-
|
|
1374
|
+
const routes = new Map(pages.flatMap(({ items }) => items.map((item) => {
|
|
1375
|
+
const { id, view } = entryView(item);
|
|
1376
|
+
return [id, routeOf(view, id)];
|
|
1377
|
+
})));
|
|
1378
|
+
return pages.flatMap((page) => page.items.map((item) => toEntry(item, page, routes, warn)));
|
|
1315
1379
|
};
|
|
1316
1380
|
return remoteSource({
|
|
1317
1381
|
assertConfigured,
|
|
@@ -1326,6 +1390,7 @@ var contentfulSource = (options, ctx) => {
|
|
|
1326
1390
|
// src/core/sources/filesystem.ts
|
|
1327
1391
|
import { existsSync, watch as fsWatch } from "node:fs";
|
|
1328
1392
|
import { readFile } from "node:fs/promises";
|
|
1393
|
+
import { YAMLException } from "js-yaml";
|
|
1329
1394
|
import { extname, isAbsolute, join as join2, relative as relative3, resolve } from "pathe";
|
|
1330
1395
|
import { glob as glob2 } from "tinyglobby";
|
|
1331
1396
|
var filesystemSource = (options) => {
|
|
@@ -1348,11 +1413,19 @@ var filesystemSource = (options) => {
|
|
|
1348
1413
|
loadable.push(file);
|
|
1349
1414
|
}
|
|
1350
1415
|
}
|
|
1351
|
-
const
|
|
1416
|
+
const read = await Promise.all(loadable.map(async (file) => {
|
|
1352
1417
|
const source = await readFile(file, "utf-8");
|
|
1353
1418
|
const ext = extname(file).toLowerCase();
|
|
1354
1419
|
const format = ext === ".mdx" ? "mdx" : "md";
|
|
1355
|
-
|
|
1420
|
+
let parsed;
|
|
1421
|
+
try {
|
|
1422
|
+
parsed = frontmatter_default(source);
|
|
1423
|
+
} catch (error) {
|
|
1424
|
+
if (error instanceof YAMLException) {
|
|
1425
|
+
return frontmatterYamlDiagnostic(error, file);
|
|
1426
|
+
}
|
|
1427
|
+
throw error;
|
|
1428
|
+
}
|
|
1356
1429
|
return {
|
|
1357
1430
|
body: { format, text: parsed.content },
|
|
1358
1431
|
data: parsed.data,
|
|
@@ -1361,6 +1434,14 @@ var filesystemSource = (options) => {
|
|
|
1361
1434
|
sourcePath: file
|
|
1362
1435
|
};
|
|
1363
1436
|
}));
|
|
1437
|
+
const entries = [];
|
|
1438
|
+
for (const item of read) {
|
|
1439
|
+
if ("body" in item) {
|
|
1440
|
+
entries.push(item);
|
|
1441
|
+
} else {
|
|
1442
|
+
diagnostics.push(item);
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1364
1445
|
return { diagnostics, entries };
|
|
1365
1446
|
};
|
|
1366
1447
|
const validate = () => {
|
|
@@ -1526,11 +1607,17 @@ var githubHeaders = () => {
|
|
|
1526
1607
|
}
|
|
1527
1608
|
return headers;
|
|
1528
1609
|
};
|
|
1610
|
+
var releaseCategory = (release) => {
|
|
1611
|
+
if (release.draft) {
|
|
1612
|
+
return "Draft";
|
|
1613
|
+
}
|
|
1614
|
+
return release.prerelease ? "Prerelease" : "Release";
|
|
1615
|
+
};
|
|
1529
1616
|
var releaseToEntry = (release, site) => {
|
|
1530
1617
|
const version = release.tag_name.replace(LEADING_V, "");
|
|
1531
1618
|
const title = release.name?.trim() || release.tag_name;
|
|
1532
1619
|
const date = release.published_at ?? release.created_at;
|
|
1533
|
-
const category = release
|
|
1620
|
+
const category = releaseCategory(release);
|
|
1534
1621
|
const body = liftHeadings(relativizeOwnLinks(neutralizeUnsafeLinks((release.body ?? "").replaceAll(`\r
|
|
1535
1622
|
`, `
|
|
1536
1623
|
`)).trim(), site));
|
|
@@ -1641,6 +1728,11 @@ var githubReleasesSource = (options, ctx) => {
|
|
|
1641
1728
|
|
|
1642
1729
|
// src/core/sources/mdx-remote.ts
|
|
1643
1730
|
import picomatch from "picomatch";
|
|
1731
|
+
var includeMatcher = (include) => {
|
|
1732
|
+
const included = picomatch(include.filter((pattern) => !pattern.startsWith("!")));
|
|
1733
|
+
const excluded = picomatch(include.filter((pattern) => pattern.startsWith("!")).map((pattern) => pattern.slice(1)));
|
|
1734
|
+
return (ref) => included(ref) && !excluded(ref);
|
|
1735
|
+
};
|
|
1644
1736
|
var GITHUB_HOSTS = new Set(["api.github.com", "raw.githubusercontent.com"]);
|
|
1645
1737
|
var githubHeaders2 = (url) => {
|
|
1646
1738
|
const token = process.env.GITHUB_TOKEN;
|
|
@@ -1679,7 +1771,7 @@ var enumerateGithub = async (github, include, doFetch) => {
|
|
|
1679
1771
|
const text = await fetchText(treeUrl, doFetch);
|
|
1680
1772
|
const body = JSON.parse(text);
|
|
1681
1773
|
const prefix = base ? `${base}/` : "";
|
|
1682
|
-
const included =
|
|
1774
|
+
const included = includeMatcher(include);
|
|
1683
1775
|
const refs = (body.tree ?? []).flatMap((node) => {
|
|
1684
1776
|
if (!(node.type === "blob" && node.path.startsWith(prefix))) {
|
|
1685
1777
|
return [];
|
|
@@ -1696,7 +1788,13 @@ var enumerateGithub = async (github, include, doFetch) => {
|
|
|
1696
1788
|
}
|
|
1697
1789
|
];
|
|
1698
1790
|
});
|
|
1699
|
-
|
|
1791
|
+
const truncated = body.truncated === true;
|
|
1792
|
+
const found = prefix === "" || truncated || (body.tree ?? []).some((node) => node.path.startsWith(prefix));
|
|
1793
|
+
return {
|
|
1794
|
+
missing: found ? undefined : `"${base}" in ${owner}/${repo} at ${ref}`,
|
|
1795
|
+
refs,
|
|
1796
|
+
truncated
|
|
1797
|
+
};
|
|
1700
1798
|
};
|
|
1701
1799
|
var mdxRemoteSource = (options, ctx) => {
|
|
1702
1800
|
const doFetch = options.fetchImpl ?? globalThis.fetch;
|
|
@@ -1717,7 +1815,7 @@ var mdxRemoteSource = (options, ctx) => {
|
|
|
1717
1815
|
return await enumerateGithub(options.github, options.include, doFetch);
|
|
1718
1816
|
}
|
|
1719
1817
|
const base = (options.url ?? "").replace(/\/$/u, "");
|
|
1720
|
-
const included =
|
|
1818
|
+
const included = includeMatcher(options.include);
|
|
1721
1819
|
const refs = (options.files ?? []).flatMap((ref) => included(ref) ? [{ editUrl: `${base}/${ref}`, fetchUrl: `${base}/${ref}`, ref }] : []);
|
|
1722
1820
|
return { refs, truncated: false };
|
|
1723
1821
|
};
|
|
@@ -1738,12 +1836,21 @@ var mdxRemoteSource = (options, ctx) => {
|
|
|
1738
1836
|
assertConfigured();
|
|
1739
1837
|
const skipped = [];
|
|
1740
1838
|
const result = await loadWithCache(options.name, cache, async () => {
|
|
1741
|
-
const { refs, truncated } = await enumerate();
|
|
1839
|
+
const { missing, refs, truncated } = await enumerate();
|
|
1840
|
+
if (missing) {
|
|
1841
|
+
skipped.push({
|
|
1842
|
+
code: "BLUME_SOURCE_PATH_MISSING",
|
|
1843
|
+
message: `Source "${options.name}" read no files: there is no folder ${missing}.`,
|
|
1844
|
+
severity: "warning",
|
|
1845
|
+
suggestion: "Check github.path and github.ref against the repository."
|
|
1846
|
+
});
|
|
1847
|
+
}
|
|
1742
1848
|
if (truncated) {
|
|
1743
1849
|
skipped.push({
|
|
1744
1850
|
code: "BLUME_SOURCE_TRUNCATED",
|
|
1745
|
-
message: `Source "${options.name}" hit GitHub's tree listing limit; some files were not enumerated
|
|
1746
|
-
severity: "warning"
|
|
1851
|
+
message: `Source "${options.name}" hit GitHub's tree listing limit for the whole repository; some files were not enumerated.`,
|
|
1852
|
+
severity: "warning",
|
|
1853
|
+
suggestion: "List the files to read with { url, files } instead, or split the repository."
|
|
1747
1854
|
});
|
|
1748
1855
|
}
|
|
1749
1856
|
const reasons = [];
|
|
@@ -2115,7 +2222,11 @@ var notionSource = (options, ctx) => {
|
|
|
2115
2222
|
severity: "error"
|
|
2116
2223
|
});
|
|
2117
2224
|
}
|
|
2118
|
-
|
|
2225
|
+
const auth = options.token ?? process.env.NOTION_TOKEN;
|
|
2226
|
+
if (!auth) {
|
|
2227
|
+
throw missingSecretError(options.name, "NOTION_TOKEN");
|
|
2228
|
+
}
|
|
2229
|
+
return new Client({ auth });
|
|
2119
2230
|
};
|
|
2120
2231
|
const childrenOf = (client, blockId) => collectAll((cursor) => notionCall(() => client.blocks.children.list({ block_id: blockId, start_cursor: cursor })));
|
|
2121
2232
|
const renderContainer = async (client, block, render) => {
|
|
@@ -2311,6 +2422,7 @@ ${nested}`;
|
|
|
2311
2422
|
// src/core/sources/obsidian.ts
|
|
2312
2423
|
import { existsSync as existsSync2, watch as fsWatch2, statSync } from "node:fs";
|
|
2313
2424
|
import { readdir as readdir2, readFile as readFile2, stat } from "node:fs/promises";
|
|
2425
|
+
import { YAMLException as YAMLException2 } from "js-yaml";
|
|
2314
2426
|
import { basename as basename2, isAbsolute as isAbsolute2, join as join5, relative as relative4, resolve as resolve2 } from "pathe";
|
|
2315
2427
|
var MARKDOWN_FILE = /\.md$/iu;
|
|
2316
2428
|
var OBSIDIAN_COMMENT = /%%.*?%%/gu;
|
|
@@ -2643,6 +2755,9 @@ var readNote = async (vaultDir, rel, options) => {
|
|
|
2643
2755
|
rel
|
|
2644
2756
|
};
|
|
2645
2757
|
} catch (error) {
|
|
2758
|
+
if (error instanceof YAMLException2) {
|
|
2759
|
+
return frontmatterYamlDiagnostic(error, absPath);
|
|
2760
|
+
}
|
|
2646
2761
|
if (error.code === "ENOENT") {
|
|
2647
2762
|
return null;
|
|
2648
2763
|
}
|
|
@@ -2733,7 +2848,8 @@ var obsidianSource = (options, ctx) => {
|
|
|
2733
2848
|
}
|
|
2734
2849
|
}
|
|
2735
2850
|
const read = await Promise.all(files.map((rel) => readNote(vaultDir, rel, options)));
|
|
2736
|
-
const notes = read.filter((note) => note !== null);
|
|
2851
|
+
const notes = read.filter((note) => note !== null && ("rel" in note));
|
|
2852
|
+
skipped.push(...read.filter((note) => note !== null && ("code" in note)));
|
|
2737
2853
|
const { index, pairs } = buildLinkIndex(notes, options);
|
|
2738
2854
|
const unresolved = noTargets();
|
|
2739
2855
|
const entries = pairs.map((pair) => noteToEntry(pair, index, options, unresolved));
|
|
@@ -2809,6 +2925,10 @@ var marksOf2 = (node) => {
|
|
|
2809
2925
|
};
|
|
2810
2926
|
};
|
|
2811
2927
|
var children2 = (node) => objectsIn(node.children);
|
|
2928
|
+
var leftOut = (what, options) => {
|
|
2929
|
+
options.onUnsupported?.(what);
|
|
2930
|
+
return unsupported(what, writesMdx(options.serializers));
|
|
2931
|
+
};
|
|
2812
2932
|
var typeOf = (node) => asString(node.type) ?? "";
|
|
2813
2933
|
var customBlock = (node, options) => {
|
|
2814
2934
|
const fields = asObject(node.fields);
|
|
@@ -2817,7 +2937,7 @@ var customBlock = (node, options) => {
|
|
|
2817
2937
|
if (fields && serializer) {
|
|
2818
2938
|
return serializer(fields);
|
|
2819
2939
|
}
|
|
2820
|
-
return
|
|
2940
|
+
return leftOut(`Lexical block${blockType ? `: ${blockType}` : ""}`, options);
|
|
2821
2941
|
};
|
|
2822
2942
|
var inlineParts2 = (nodes, options) => nodes.flatMap((node) => inlineNodeParts2(node, options));
|
|
2823
2943
|
var inlineNodeParts2 = (node, options) => {
|
|
@@ -2850,7 +2970,7 @@ var renderUpload = (node, options) => {
|
|
|
2850
2970
|
const value = asObject(node.value);
|
|
2851
2971
|
const url = value ? asString(value.url) : undefined;
|
|
2852
2972
|
if (!(value && url)) {
|
|
2853
|
-
return
|
|
2973
|
+
return leftOut("Lexical upload (fetch with depth 1 to populate it)", options);
|
|
2854
2974
|
}
|
|
2855
2975
|
const alt = asString(value.alt) ?? asString(value.filename) ?? "";
|
|
2856
2976
|
return image(alt, absoluteUrl(url, options.baseUrl));
|
|
@@ -2909,7 +3029,7 @@ var renderBlock2 = (node, options) => {
|
|
|
2909
3029
|
return customBlock(node, options);
|
|
2910
3030
|
}
|
|
2911
3031
|
default: {
|
|
2912
|
-
return
|
|
3032
|
+
return leftOut(`Lexical node: ${typeOf(node)}`, options);
|
|
2913
3033
|
}
|
|
2914
3034
|
}
|
|
2915
3035
|
};
|
|
@@ -2930,11 +3050,26 @@ var DEFAULT_FIELDS2 = {
|
|
|
2930
3050
|
var payloadSource = (options, ctx) => {
|
|
2931
3051
|
const fields = { ...DEFAULT_FIELDS2, ...options.fields };
|
|
2932
3052
|
const origin = options.url.replace(/\/+$/u, "");
|
|
2933
|
-
const lower = (body) => lexicalToMarkdown(body, {
|
|
3053
|
+
const lower = (body, leftOut) => lexicalToMarkdown(body, {
|
|
2934
3054
|
baseUrl: origin,
|
|
3055
|
+
onUnsupported: (what) => leftOut.add(what),
|
|
2935
3056
|
serializers: options.serializers
|
|
2936
3057
|
});
|
|
2937
|
-
const
|
|
3058
|
+
const toEntry = (doc, draft, warn) => {
|
|
3059
|
+
const leftOut = new Set;
|
|
3060
|
+
const id = asString(doc.id) ?? String(doc.id ?? "");
|
|
3061
|
+
const entry = documentEntry(doc, fields, id, (body) => isJsonObject(body) ? lower(body, leftOut) : "", draft, writesMdx(options.serializers));
|
|
3062
|
+
for (const what of leftOut) {
|
|
3063
|
+
warn({
|
|
3064
|
+
code: "BLUME_SOURCE_UNSUPPORTED_NODE",
|
|
3065
|
+
message: `Source "${options.name}": "${entry.ref}" has content Blume has no Markdown for (${what}), left out as a comment.`,
|
|
3066
|
+
severity: "warning",
|
|
3067
|
+
suggestion: "Map a block type to a component with a serializer on payloadSource, passed to custom(); other nodes have no Markdown equivalent."
|
|
3068
|
+
});
|
|
3069
|
+
}
|
|
3070
|
+
return entry;
|
|
3071
|
+
};
|
|
3072
|
+
const fetchEntries = async (warn) => {
|
|
2938
3073
|
const preview = ctx?.preview ?? false;
|
|
2939
3074
|
const token = options.token ?? process.env.PAYLOAD_API_KEY;
|
|
2940
3075
|
const client = {
|
|
@@ -2964,8 +3099,7 @@ var payloadSource = (options, ctx) => {
|
|
|
2964
3099
|
if (draft && !preview) {
|
|
2965
3100
|
continue;
|
|
2966
3101
|
}
|
|
2967
|
-
|
|
2968
|
-
entries.push(documentEntry(doc, fields, id, (body) => isJsonObject(body) ? lower(body) : "", draft, writesMdx(options.serializers)));
|
|
3102
|
+
entries.push(toEntry(doc, draft, warn));
|
|
2969
3103
|
}
|
|
2970
3104
|
more = result.hasNextPage === true;
|
|
2971
3105
|
page += 1;
|
|
@@ -3126,15 +3260,22 @@ var sanitySource = (options, ctx) => {
|
|
|
3126
3260
|
if (description) {
|
|
3127
3261
|
data.description = description;
|
|
3128
3262
|
}
|
|
3129
|
-
const
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
})
|
|
3137
|
-
|
|
3263
|
+
const body = getPath(doc, fields.body ?? "body");
|
|
3264
|
+
let markdown = "";
|
|
3265
|
+
let format = writesMdx(options.serializers) ? "mdx" : "md";
|
|
3266
|
+
if (isStringValue2(body)) {
|
|
3267
|
+
markdown = neutralizeUnsafeLinks(`${body.trimEnd()}
|
|
3268
|
+
`);
|
|
3269
|
+
format = "md";
|
|
3270
|
+
} else if (Array.isArray(body)) {
|
|
3271
|
+
markdown = portableTextToMarkdown(body, {
|
|
3272
|
+
imageUrl: (block) => {
|
|
3273
|
+
const ref = block.asset?._ref;
|
|
3274
|
+
return ref ? imageUrlFromRef(ref, options.projectId, options.dataset) : null;
|
|
3275
|
+
},
|
|
3276
|
+
serializers: options.serializers
|
|
3277
|
+
});
|
|
3278
|
+
}
|
|
3138
3279
|
const raw = frontmatter_default.stringify(markdown, data);
|
|
3139
3280
|
return {
|
|
3140
3281
|
body: { format, text: markdown },
|
|
@@ -3146,13 +3287,22 @@ var sanitySource = (options, ctx) => {
|
|
|
3146
3287
|
};
|
|
3147
3288
|
};
|
|
3148
3289
|
const load = async (refresh = ctx?.refresh ?? true) => {
|
|
3290
|
+
const empty = [];
|
|
3149
3291
|
const result = await loadWithCache(options.name, cache, async () => {
|
|
3150
3292
|
const client = resolveClient(options, ctx?.preview ?? false);
|
|
3151
3293
|
const docs = await client.fetch(options.query);
|
|
3294
|
+
if (docs.length === 0 && !(options.token ?? process.env.SANITY_TOKEN)) {
|
|
3295
|
+
empty.push({
|
|
3296
|
+
code: "BLUME_MISSING_SECRET",
|
|
3297
|
+
message: `Source "${options.name}" found no documents, and SANITY_TOKEN is not set. A private dataset returns nothing to a query without a token.`,
|
|
3298
|
+
severity: "warning",
|
|
3299
|
+
suggestion: "Set SANITY_TOKEN to a token with read access if the dataset is private."
|
|
3300
|
+
});
|
|
3301
|
+
}
|
|
3152
3302
|
return docs.map(toEntry);
|
|
3153
3303
|
}, refresh);
|
|
3154
3304
|
snapshot = new Map(result.entries.map((entry) => [entry.ref, entry]));
|
|
3155
|
-
return result;
|
|
3305
|
+
return { ...result, diagnostics: [...result.diagnostics, ...empty] };
|
|
3156
3306
|
};
|
|
3157
3307
|
const read = async (ref) => {
|
|
3158
3308
|
const cached = snapshot.get(ref);
|
|
@@ -3389,7 +3539,12 @@ var buildSource = (adapter, name, config, context, runtime) => {
|
|
|
3389
3539
|
return notionSource({ ...adapter.options, name }, ctx());
|
|
3390
3540
|
}
|
|
3391
3541
|
case "contentful": {
|
|
3392
|
-
return contentfulSource({
|
|
3542
|
+
return contentfulSource({
|
|
3543
|
+
...adapter.options,
|
|
3544
|
+
i18n: config.i18n,
|
|
3545
|
+
name,
|
|
3546
|
+
versions: config.versions
|
|
3547
|
+
}, ctx());
|
|
3393
3548
|
}
|
|
3394
3549
|
case "payload": {
|
|
3395
3550
|
return payloadSource({ ...adapter.options, name }, ctx());
|
|
@@ -3543,7 +3698,20 @@ var substituteEntryVariables = (entry, variables) => {
|
|
|
3543
3698
|
};
|
|
3544
3699
|
var substituteLoadedVariables = (loaded, variables) => hasVariables(variables) ? loaded.flatMap(({ entries }) => entries.flatMap((entry) => substituteEntryVariables(entry, variables))) : [];
|
|
3545
3700
|
var redirectPageDiagnostics = (config, pages, configFile) => config.redirects.flatMap((redirect) => {
|
|
3546
|
-
const
|
|
3701
|
+
const from = withBasePath(config.basePath, redirect.from);
|
|
3702
|
+
if (!isPatternPath(redirect.from)) {
|
|
3703
|
+
const page = normalizePath(from);
|
|
3704
|
+
return pages.includes(page) ? [
|
|
3705
|
+
{
|
|
3706
|
+
code: "BLUME_REDIRECT_MATCHES_PAGE",
|
|
3707
|
+
file: configFile ?? undefined,
|
|
3708
|
+
message: `The redirect from ${redirect.from} is also the page ${page}, which never publishes: its URL redirects to ${redirect.to} instead.`,
|
|
3709
|
+
severity: "warning",
|
|
3710
|
+
suggestion: "If the page moved, delete it or give it a new slug; otherwise remove the redirect."
|
|
3711
|
+
}
|
|
3712
|
+
] : [];
|
|
3713
|
+
}
|
|
3714
|
+
const matched = pathsUnderPattern(from, pages);
|
|
3547
3715
|
const [first] = matched;
|
|
3548
3716
|
if (first === undefined) {
|
|
3549
3717
|
return [];
|
|
@@ -3560,6 +3728,14 @@ var redirectPageDiagnostics = (config, pages, configFile) => config.redirects.fl
|
|
|
3560
3728
|
];
|
|
3561
3729
|
});
|
|
3562
3730
|
var bannerLinkHref = (banner) => banner === undefined || isBannerShorthand(banner) ? undefined : banner.link?.href;
|
|
3731
|
+
var validatedSources = (config, context, runtime, beforeSources) => {
|
|
3732
|
+
beforeSources?.(config);
|
|
3733
|
+
const sources = resolveSources(config, context, runtime);
|
|
3734
|
+
for (const source of sources) {
|
|
3735
|
+
source.validate?.();
|
|
3736
|
+
}
|
|
3737
|
+
return sources;
|
|
3738
|
+
};
|
|
3563
3739
|
var scanProject = async (root, options = {}) => {
|
|
3564
3740
|
const mode = options.mode ?? "dev";
|
|
3565
3741
|
const preview = options.preview ?? false;
|
|
@@ -3570,14 +3746,7 @@ var scanProject = async (root, options = {}) => {
|
|
|
3570
3746
|
const context = resolveProjectContext(root, config, {
|
|
3571
3747
|
runtimeDir: options.runtimeDir
|
|
3572
3748
|
});
|
|
3573
|
-
const sources =
|
|
3574
|
-
mode,
|
|
3575
|
-
preview,
|
|
3576
|
-
refresh: options.refresh
|
|
3577
|
-
});
|
|
3578
|
-
for (const source of sources) {
|
|
3579
|
-
source.validate?.();
|
|
3580
|
-
}
|
|
3749
|
+
const sources = validatedSources(config, context, { mode, preview, refresh: options.refresh }, options.beforeSources);
|
|
3581
3750
|
const metaSources = sources.flatMap((source) => source.staged || !source.contentRoot ? [] : [
|
|
3582
3751
|
{
|
|
3583
3752
|
exclude: source.exclude,
|
|
@@ -3681,7 +3850,7 @@ var scanProject = async (root, options = {}) => {
|
|
|
3681
3850
|
};
|
|
3682
3851
|
};
|
|
3683
3852
|
|
|
3684
|
-
export { directiveSource,
|
|
3853
|
+
export { directiveSource, validateSearchPopularIcons, validateNavTargets, contentIndexable, buildManifest, findFolderMetaFiles, isWithin, scanProject };
|
|
3685
3854
|
|
|
3686
|
-
//# debugId=
|
|
3687
|
-
//# sourceMappingURL=chunk-
|
|
3855
|
+
//# debugId=1F41F69354D6E33464756E2164756E21
|
|
3856
|
+
//# sourceMappingURL=chunk-ncj7w596.js.map
|