blume 1.1.2 → 1.1.4
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 +47 -0
- package/dist/cli/index.js +284 -109
- package/dist/cli/index.js.map +33 -33
- package/dist/types/ai/component-markdown.d.ts +10 -0
- package/dist/types/core/config-input.d.ts +44 -0
- package/dist/types/core/data.d.ts +2 -0
- package/dist/types/core/i18n-ui.d.ts +24 -24
- package/dist/types/core/schema.d.ts +282 -114
- package/dist/types/core/types.d.ts +14 -0
- package/dist/types/openapi/references.d.ts +5 -0
- package/docs/advanced/api-reference.mdx +20 -0
- package/docs/configuration/index.mdx +27 -0
- package/package.json +1 -1
- package/src/ai/component-markdown.ts +28 -0
- package/src/ai/llms.ts +11 -2
- package/src/ai/markdown.ts +12 -6
- package/src/ai/mcp/server.ts +29 -6
- package/src/astro/examples.ts +13 -0
- package/src/astro/generate.ts +141 -58
- package/src/astro/templates.ts +65 -21
- package/src/audit/checks/duplicates.ts +15 -6
- package/src/audit/checks/indexability.ts +11 -2
- package/src/audit/checks/network.ts +22 -8
- package/src/audit/checks/sitemap.ts +42 -16
- package/src/audit/redirects.ts +12 -1
- package/src/audit/run.ts +13 -3
- package/src/audit/url.ts +21 -2
- package/src/cli/commands/audit.ts +21 -6
- package/src/cli/commands/dev.ts +19 -2
- package/src/components/content/Frame.astro +4 -1
- package/src/components/content/Prompt.astro +4 -1
- package/src/components/content/Tooltip.astro +4 -1
- package/src/components/content/Update.astro +45 -0
- package/src/components/islands/ask-ai.tsx +19 -2
- package/src/components/islands/hooks.ts +38 -11
- package/src/components/layout/Logo.astro +2 -2
- package/src/components/layout/RootLayout.astro +27 -7
- package/src/components/layout/Search.astro +5 -1
- package/src/components/layout/head-scripts.ts +22 -5
- package/src/components/openapi/ApiTagOperations.astro +17 -8
- package/src/core/config-input.ts +45 -0
- package/src/core/data.ts +2 -0
- package/src/core/date-format.ts +17 -0
- package/src/core/deployment-env.ts +7 -2
- package/src/core/graph.ts +7 -1
- package/src/core/i18n.ts +10 -2
- package/src/core/navigation.ts +7 -3
- package/src/core/project-graph.ts +9 -0
- package/src/core/schema.ts +64 -0
- package/src/core/sources/normalize.ts +69 -8
- package/src/core/sources/notion.ts +4 -2
- package/src/core/sources/sanity.ts +5 -3
- package/src/core/types.ts +16 -0
- package/src/markdown/code-title.ts +7 -1
- package/src/openapi/model.ts +31 -2
- package/src/openapi/references.ts +6 -0
- package/src/openapi/render-mdx.ts +12 -7
- package/src/openapi/scalar.ts +4 -0
- package/src/registry/eject.ts +6 -3
- package/src/theme/entry.ts +7 -0
- package/src/theme/twoslash.ts +10 -0
package/dist/cli/index.js
CHANGED
|
@@ -1581,6 +1581,13 @@ var normalizePath = (path) => {
|
|
|
1581
1581
|
const trimmed = path.replace(/\/+$/u, "");
|
|
1582
1582
|
return trimmed === "" ? "/" : trimmed;
|
|
1583
1583
|
};
|
|
1584
|
+
var decodePath = (path) => {
|
|
1585
|
+
try {
|
|
1586
|
+
return decodeURI(path);
|
|
1587
|
+
} catch {
|
|
1588
|
+
return path;
|
|
1589
|
+
}
|
|
1590
|
+
};
|
|
1584
1591
|
var siteOrigin = (site) => {
|
|
1585
1592
|
if (!site) {
|
|
1586
1593
|
return null;
|
|
@@ -1611,7 +1618,7 @@ var resolveHref = (pageUrl, href, origin, deployBase = "") => {
|
|
|
1611
1618
|
return {
|
|
1612
1619
|
hash: parsed.hash.slice(1),
|
|
1613
1620
|
kind: "self-origin",
|
|
1614
|
-
path: normalizePath(stripBasePath(deployBase, parsed.pathname))
|
|
1621
|
+
path: normalizePath(stripBasePath(deployBase, decodePath(parsed.pathname)))
|
|
1615
1622
|
};
|
|
1616
1623
|
}
|
|
1617
1624
|
return { kind: "external", url: parsed.toString() };
|
|
@@ -1626,7 +1633,7 @@ var resolveHref = (pageUrl, href, origin, deployBase = "") => {
|
|
|
1626
1633
|
return {
|
|
1627
1634
|
hash: resolved.hash.slice(1),
|
|
1628
1635
|
kind: "internal",
|
|
1629
|
-
path: normalizePath(stripBasePath(deployBase, resolved.pathname))
|
|
1636
|
+
path: normalizePath(stripBasePath(deployBase, decodePath(resolved.pathname)))
|
|
1630
1637
|
};
|
|
1631
1638
|
};
|
|
1632
1639
|
|
|
@@ -1825,17 +1832,20 @@ var contentChecks = {
|
|
|
1825
1832
|
};
|
|
1826
1833
|
|
|
1827
1834
|
// src/audit/checks/duplicates.ts
|
|
1828
|
-
var isNonCanonical = (page) => {
|
|
1835
|
+
var isNonCanonical = (page, deployBase) => {
|
|
1829
1836
|
if (!page.canonical) {
|
|
1830
1837
|
return false;
|
|
1831
1838
|
}
|
|
1832
1839
|
try {
|
|
1833
|
-
return new URL(page.canonical).pathname.replace(/\/$/u, "") !== page.url.replace(/\/$/u, "");
|
|
1840
|
+
return stripBasePath(deployBase, decodePath(new URL(page.canonical).pathname)).replace(/\/$/u, "") !== page.url.replace(/\/$/u, "");
|
|
1834
1841
|
} catch {
|
|
1835
1842
|
return false;
|
|
1836
1843
|
}
|
|
1837
1844
|
};
|
|
1838
|
-
var comparable = (context) =>
|
|
1845
|
+
var comparable = (context) => {
|
|
1846
|
+
const deployBase = normalizeBasePath(context.project.config.deployment.base);
|
|
1847
|
+
return context.pages.filter((page) => page.indexable && !page.route?.fallback && !isNonCanonical(page, deployBase));
|
|
1848
|
+
};
|
|
1839
1849
|
var reportGroups = (context, pages, id, key, describe, frontmatterKey) => {
|
|
1840
1850
|
const groups = new Map;
|
|
1841
1851
|
for (const page of pages) {
|
|
@@ -2009,12 +2019,12 @@ var PLATFORMS = [
|
|
|
2009
2019
|
{
|
|
2010
2020
|
adapter: "vercel",
|
|
2011
2021
|
detect: (env) => Boolean(env.VERCEL),
|
|
2012
|
-
site: (env) => toUrl(env.VERCEL_PROJECT_PRODUCTION_URL ?? env.VERCEL_URL)
|
|
2022
|
+
site: (env) => toUrl(env.VERCEL_PROJECT_PRODUCTION_URL) ?? toUrl(env.VERCEL_URL)
|
|
2013
2023
|
},
|
|
2014
2024
|
{
|
|
2015
2025
|
adapter: "netlify",
|
|
2016
2026
|
detect: (env) => Boolean(env.NETLIFY),
|
|
2017
|
-
site: (env) => toUrl(env.URL ?? env.DEPLOY_PRIME_URL ?? env.DEPLOY_URL)
|
|
2027
|
+
site: (env) => toUrl(env.URL) ?? toUrl(env.DEPLOY_PRIME_URL) ?? toUrl(env.DEPLOY_URL)
|
|
2018
2028
|
},
|
|
2019
2029
|
{
|
|
2020
2030
|
adapter: "cloudflare",
|
|
@@ -2073,7 +2083,7 @@ var canonicalChecks = (context, page) => {
|
|
|
2073
2083
|
}
|
|
2074
2084
|
return found;
|
|
2075
2085
|
}
|
|
2076
|
-
const target = normalizePath(canonical.pathname);
|
|
2086
|
+
const target = normalizePath(stripBasePath(normalizeBasePath(context.project.config.deployment.base), decodePath(canonical.pathname)));
|
|
2077
2087
|
if (target === normalizePath(page.url)) {
|
|
2078
2088
|
return found;
|
|
2079
2089
|
}
|
|
@@ -2401,7 +2411,7 @@ var probeAll = async (urls, options = {}) => {
|
|
|
2401
2411
|
var CLIENT_ERROR = 400;
|
|
2402
2412
|
var SERVER_ERROR = 500;
|
|
2403
2413
|
var SLOW_MS = 1500;
|
|
2404
|
-
var liveUrl = (origin, page) => new URL(page.url
|
|
2414
|
+
var liveUrl = (origin, page, deployBase) => new URL(`${deployBase}${page.url}`, origin).toString();
|
|
2405
2415
|
var badResponse = (context, page, result) => {
|
|
2406
2416
|
const site = pageSite(context, page);
|
|
2407
2417
|
if (result.timedOut) {
|
|
@@ -2445,12 +2455,13 @@ var networkChecks = {
|
|
|
2445
2455
|
return [];
|
|
2446
2456
|
}
|
|
2447
2457
|
const found = [];
|
|
2448
|
-
const
|
|
2449
|
-
const
|
|
2450
|
-
const
|
|
2458
|
+
const deployBase = normalizeBasePath(context.project.config.deployment.base);
|
|
2459
|
+
const targets = context.pages.map((page) => liveUrl(origin, page, deployBase));
|
|
2460
|
+
const robotsUrl = new URL(`${deployBase}/robots.txt`, origin).toString();
|
|
2461
|
+
const sitemapUrl = new URL(`${deployBase}/sitemap.xml`, origin).toString();
|
|
2451
2462
|
const results = await probeAll([...targets, robotsUrl, sitemapUrl]);
|
|
2452
2463
|
for (const page of context.pages) {
|
|
2453
|
-
const result = results.get(liveUrl(origin, page));
|
|
2464
|
+
const result = results.get(liveUrl(origin, page, deployBase));
|
|
2454
2465
|
if (!result) {
|
|
2455
2466
|
continue;
|
|
2456
2467
|
}
|
|
@@ -2717,23 +2728,23 @@ var MAX_SITEMAP_BYTES = 50 * 1024 * 1024;
|
|
|
2717
2728
|
var MAX_SITEMAP_URLS = 50000;
|
|
2718
2729
|
var LASTMOD_SLACK_MS = 24 * 60 * 60 * 1000;
|
|
2719
2730
|
var ERROR_ROUTES2 = new Set(["/404", "/500"]);
|
|
2720
|
-
var sitemapPaths = (context) => {
|
|
2731
|
+
var sitemapPaths = (context, deployBase) => {
|
|
2721
2732
|
const paths = new Map;
|
|
2722
2733
|
for (const loc of context.sitemap?.urls ?? []) {
|
|
2723
2734
|
try {
|
|
2724
|
-
paths.set(normalizePath(new URL(loc).pathname), loc);
|
|
2735
|
+
paths.set(normalizePath(stripBasePath(deployBase, decodePath(new URL(loc).pathname))), loc);
|
|
2725
2736
|
} catch {}
|
|
2726
2737
|
}
|
|
2727
2738
|
return paths;
|
|
2728
2739
|
};
|
|
2729
|
-
var canonicalPath = (canonical) => {
|
|
2740
|
+
var canonicalPath = (canonical, deployBase) => {
|
|
2730
2741
|
try {
|
|
2731
|
-
return normalizePath(new URL(canonical).pathname);
|
|
2742
|
+
return normalizePath(stripBasePath(deployBase, decodePath(new URL(canonical).pathname)));
|
|
2732
2743
|
} catch {
|
|
2733
2744
|
return null;
|
|
2734
2745
|
}
|
|
2735
2746
|
};
|
|
2736
|
-
var checkListedUrl = (context, loc, origin, file) => {
|
|
2747
|
+
var checkListedUrl = (context, loc, origin, file, deployBase) => {
|
|
2737
2748
|
let parsed;
|
|
2738
2749
|
try {
|
|
2739
2750
|
parsed = new URL(loc);
|
|
@@ -2747,7 +2758,7 @@ var checkListedUrl = (context, loc, origin, file) => {
|
|
|
2747
2758
|
finding("BLUME_AUDIT_SITEMAP_OUT_OF_SCOPE", { file, url: loc }, `sitemap.xml lists ${loc}, which is on another origin.`)
|
|
2748
2759
|
];
|
|
2749
2760
|
}
|
|
2750
|
-
const path = normalizePath(stripBasePath(
|
|
2761
|
+
const path = normalizePath(stripBasePath(deployBase, decodePath(parsed.pathname)));
|
|
2751
2762
|
const page = context.byUrl.get(path);
|
|
2752
2763
|
if (!page) {
|
|
2753
2764
|
const redirect = context.redirects.find((entry) => normalizePath(entry.from) === path);
|
|
@@ -2759,7 +2770,7 @@ var checkListedUrl = (context, loc, origin, file) => {
|
|
|
2759
2770
|
if (!page.indexable) {
|
|
2760
2771
|
found.push(finding("BLUME_AUDIT_NOINDEX_IN_SITEMAP", pageSite(context, page, ["noindex"]), `${path} is in the sitemap but declares robots "${page.robots}".`));
|
|
2761
2772
|
}
|
|
2762
|
-
const canonical = page.canonical && canonicalPath(page.canonical);
|
|
2773
|
+
const canonical = page.canonical && canonicalPath(page.canonical, deployBase);
|
|
2763
2774
|
if (canonical && canonical !== path) {
|
|
2764
2775
|
found.push(finding("BLUME_AUDIT_NON_CANONICAL_IN_SITEMAP", pageSite(context, page, ["seo", "canonical"]), `${path} is in the sitemap but canonicalizes to ${canonical}.`));
|
|
2765
2776
|
}
|
|
@@ -2795,9 +2806,10 @@ var sitemapChecks = {
|
|
|
2795
2806
|
}
|
|
2796
2807
|
}
|
|
2797
2808
|
const origin = siteOrigin(site);
|
|
2798
|
-
const
|
|
2809
|
+
const deployBase = normalizeBasePath(context.project.config.deployment.base);
|
|
2810
|
+
const listed = sitemapPaths(context, deployBase);
|
|
2799
2811
|
for (const loc of sitemap.urls) {
|
|
2800
|
-
found.push(...checkListedUrl(context, loc, origin, sitemap.file));
|
|
2812
|
+
found.push(...checkListedUrl(context, loc, origin, sitemap.file, deployBase));
|
|
2801
2813
|
}
|
|
2802
2814
|
for (const page of context.pages) {
|
|
2803
2815
|
if (!page.indexable || ERROR_ROUTES2.has(page.url) || listed.has(normalizePath(page.url))) {
|
|
@@ -3106,6 +3118,7 @@ var referencesFor = (kind, block, defaultLabel, renderer, display, basePath) =>
|
|
|
3106
3118
|
label,
|
|
3107
3119
|
renderer,
|
|
3108
3120
|
route,
|
|
3121
|
+
scalar: block.scalar,
|
|
3109
3122
|
slug: routeSlug(route),
|
|
3110
3123
|
spec: source.spec,
|
|
3111
3124
|
theme: block.theme
|
|
@@ -3467,6 +3480,13 @@ var astroOutDir = (context) => context.distDir ?? `${context.root}/dist`;
|
|
|
3467
3480
|
var adapterRoot = (context) => dirname5(astroOutDir(context));
|
|
3468
3481
|
var REACT_EXCLUDE = String.raw`exclude: [/\/node_modules\/\.vite\//]`;
|
|
3469
3482
|
var reactIntegration = (compilerPath) => compilerPath ? `react({ babel: { plugins: [[${JSON.stringify(compilerPath)}, { target: "19" }]] }, ${REACT_EXCLUDE} })` : `react({ ${REACT_EXCLUDE} })`;
|
|
3483
|
+
var devWatchOption = (outDir, contentWatchesRuntimeDir) => contentWatchesRuntimeDir ? `
|
|
3484
|
+
// Astro's cache dir sits inside the docs collection, whose watcher would
|
|
3485
|
+
// otherwise churn (and can loop) on Astro's own writes. Trade-off: .md
|
|
3486
|
+
// body edits need a dev-server restart in this layout.
|
|
3487
|
+
watch: {
|
|
3488
|
+
ignored: ${JSON.stringify([join8(outDir, ".astro", "**")])},
|
|
3489
|
+
},` : "";
|
|
3470
3490
|
var astroConfigTemplate = (options) => {
|
|
3471
3491
|
const { context, config, needsReact, pages, dataPath, themePath } = options;
|
|
3472
3492
|
const {
|
|
@@ -3553,6 +3573,7 @@ var astroConfigTemplate = (options) => {
|
|
|
3553
3573
|
integrations.push("svelte()");
|
|
3554
3574
|
}
|
|
3555
3575
|
integrations.push(`blumeIntegration(${JSON.stringify({ base: deployment.base, contentRoutes, pages })})`);
|
|
3576
|
+
const watchOption = devWatchOption(context.outDir, options.contentWatchesRuntimeDir);
|
|
3556
3577
|
return `// Generated by Blume. Do not edit; this file is recreated on each run.
|
|
3557
3578
|
${defineConfigImport}
|
|
3558
3579
|
import mdx from "@astrojs/mdx";
|
|
@@ -3627,22 +3648,17 @@ export default defineConfig({
|
|
|
3627
3648
|
server: {
|
|
3628
3649
|
fs: {
|
|
3629
3650
|
allow: ${JSON.stringify(fsAllow)},
|
|
3630
|
-
}
|
|
3631
|
-
// Keep the file watcher out of Astro's own cache dir. In a migrated
|
|
3632
|
-
// (root-rooted) project the docs collection is rooted at the project dir,
|
|
3633
|
-
// so its glob-loader watcher would otherwise fire on every write Astro
|
|
3634
|
-
// makes under .blume/.astro (data-store.json, content module manifests,
|
|
3635
|
-
// self-hosted fonts) -- pure noise the loader logs as "No entry type
|
|
3636
|
-
// found". Vite appends this to its default ignores.
|
|
3637
|
-
watch: {
|
|
3638
|
-
ignored: ${JSON.stringify([join8(context.outDir, ".astro", "**")])},
|
|
3639
|
-
},
|
|
3651
|
+
},${watchOption}
|
|
3640
3652
|
},
|
|
3641
3653
|
},
|
|
3642
3654
|
});
|
|
3643
3655
|
`;
|
|
3644
3656
|
};
|
|
3645
3657
|
var stagedContentDir = (outDir) => join8(outDir, "content");
|
|
3658
|
+
var runtimeDirWithin = (base, outDir) => {
|
|
3659
|
+
const rel = relative5(base, outDir);
|
|
3660
|
+
return rel && !rel.startsWith("..") && !isAbsolute(rel) ? rel : null;
|
|
3661
|
+
};
|
|
3646
3662
|
var astroGlobBase = (base) => isAbsolute(base) ? pathToFileURL(base).href : base;
|
|
3647
3663
|
var contentConfigTemplate = (options) => {
|
|
3648
3664
|
const { context, config } = options;
|
|
@@ -3650,8 +3666,8 @@ var contentConfigTemplate = (options) => {
|
|
|
3650
3666
|
const collectionBase = options.collection?.base ?? context.contentRoot;
|
|
3651
3667
|
const includeGlobs = options.collection?.include ?? config.content.include;
|
|
3652
3668
|
const excludeGlobs = options.collection?.exclude ?? config.content.exclude;
|
|
3653
|
-
const outDirRel =
|
|
3654
|
-
const outDirIgnore = outDirRel
|
|
3669
|
+
const outDirRel = runtimeDirWithin(collectionBase, context.outDir);
|
|
3670
|
+
const outDirIgnore = outDirRel ? [`!${outDirRel}/**`] : [];
|
|
3655
3671
|
const filesystem = options.filesystem ?? true;
|
|
3656
3672
|
const docsPattern = filesystem ? [
|
|
3657
3673
|
...includeGlobs,
|
|
@@ -4327,6 +4343,7 @@ const LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);
|
|
|
4327
4343
|
page={{ title: seo.title ?? title, description: seo.description ?? frontmatter.description, route }}
|
|
4328
4344
|
headings={headings}
|
|
4329
4345
|
toc={data.config.toc}
|
|
4346
|
+
dateFormat={data.config.dateFormat}
|
|
4330
4347
|
themeMode={data.config.theme.mode}
|
|
4331
4348
|
fontCssVars={data.fontCssVars}
|
|
4332
4349
|
searchEnabled={data.config.search.enabled}
|
|
@@ -4365,6 +4382,7 @@ import RootLayout from "blume/components/layout/RootLayout.astro";
|
|
|
4365
4382
|
import Update from "blume/components/content/Update.astro";
|
|
4366
4383
|
import { withBase } from "blume/components/islands/base-path.ts";
|
|
4367
4384
|
import { resolveSlot } from "blume/components/layout/overrides.ts";
|
|
4385
|
+
import { resolveDateFormatOptions } from "blume/core/date-format.ts";
|
|
4368
4386
|
import { layoutOverrides } from "../generated/components.ts";
|
|
4369
4387
|
import data from "blume:data";
|
|
4370
4388
|
|
|
@@ -4392,8 +4410,9 @@ const localeMeta = i18n
|
|
|
4392
4410
|
const dir = localeMeta?.dir ?? "ltr";
|
|
4393
4411
|
const htmlLang = i18n ? i18n.defaultLocale : "en";
|
|
4394
4412
|
|
|
4395
|
-
// Formatted in the same locale as the chrome, and
|
|
4396
|
-
// per-page "last updated" stamp.
|
|
4413
|
+
// Formatted in the same locale as the chrome, and with the configured
|
|
4414
|
+
// \`dateFormat\` (UTC by default), to match the per-page "last updated" stamp.
|
|
4415
|
+
const dateFormatOptions = resolveDateFormatOptions(data.config.dateFormat);
|
|
4397
4416
|
const formatDate = (value: string | null | undefined) => {
|
|
4398
4417
|
if (!value) {
|
|
4399
4418
|
return;
|
|
@@ -4401,10 +4420,7 @@ const formatDate = (value: string | null | undefined) => {
|
|
|
4401
4420
|
const date = new Date(value);
|
|
4402
4421
|
return Number.isNaN(date.getTime())
|
|
4403
4422
|
? undefined
|
|
4404
|
-
: new Intl.DateTimeFormat(htmlLang,
|
|
4405
|
-
dateStyle: "long",
|
|
4406
|
-
timeZone: "UTC",
|
|
4407
|
-
}).format(date);
|
|
4423
|
+
: new Intl.DateTimeFormat(htmlLang, dateFormatOptions).format(date);
|
|
4408
4424
|
};
|
|
4409
4425
|
|
|
4410
4426
|
const slugify = (text: string) =>
|
|
@@ -5124,6 +5140,10 @@ var crawlStaticDir = async (options) => {
|
|
|
5124
5140
|
};
|
|
5125
5141
|
|
|
5126
5142
|
// src/audit/redirects.ts
|
|
5143
|
+
var pathOnly = (value) => {
|
|
5144
|
+
const cut = value.search(/[?#]/u);
|
|
5145
|
+
return cut === -1 ? value : value.slice(0, cut);
|
|
5146
|
+
};
|
|
5127
5147
|
var resolveRedirects = (redirects, pageUrls) => {
|
|
5128
5148
|
const byFrom = new Map;
|
|
5129
5149
|
for (const redirect of redirects) {
|
|
@@ -5139,7 +5159,7 @@ var resolveRedirects = (redirects, pageUrls) => {
|
|
|
5139
5159
|
chain.push(current);
|
|
5140
5160
|
break;
|
|
5141
5161
|
}
|
|
5142
|
-
const next = normalizePath(current);
|
|
5162
|
+
const next = normalizePath(pathOnly(current));
|
|
5143
5163
|
if (seen.has(next)) {
|
|
5144
5164
|
chain.push(next);
|
|
5145
5165
|
return {
|
|
@@ -5221,8 +5241,9 @@ var matches = (id, terms) => {
|
|
|
5221
5241
|
var runAudit = async (options) => {
|
|
5222
5242
|
const { project } = options;
|
|
5223
5243
|
const staticDir = deployStaticDir(project.config, project.context);
|
|
5244
|
+
const basePath = normalizeBasePath(project.config.basePath);
|
|
5224
5245
|
const crawl = await crawlStaticDir({
|
|
5225
|
-
basePath
|
|
5246
|
+
basePath,
|
|
5226
5247
|
manifest: project.manifest,
|
|
5227
5248
|
staticDir
|
|
5228
5249
|
});
|
|
@@ -5239,7 +5260,11 @@ var runAudit = async (options) => {
|
|
|
5239
5260
|
origin,
|
|
5240
5261
|
pages: crawl.pages,
|
|
5241
5262
|
project,
|
|
5242
|
-
redirects: resolveRedirects(project.config.redirects
|
|
5263
|
+
redirects: resolveRedirects(project.config.redirects.map((redirect) => ({
|
|
5264
|
+
...redirect,
|
|
5265
|
+
from: withBasePath(basePath, redirect.from),
|
|
5266
|
+
to: withBasePath(basePath, redirect.to)
|
|
5267
|
+
})), new Set([...byUrl.keys(), ...crawl.files.keys()].map((path) => normalizePath(path)))),
|
|
5243
5268
|
robots: crawl.robots,
|
|
5244
5269
|
sitemap: crawl.sitemap,
|
|
5245
5270
|
sources: await readSources(crawl.pages),
|
|
@@ -7994,6 +8019,19 @@ var lastModifiedConfigSchema = z2.union([
|
|
|
7994
8019
|
z2.boolean(),
|
|
7995
8020
|
z2.strictObject({ type: z2.enum(["git", "frontmatter"]).default("git") })
|
|
7996
8021
|
]);
|
|
8022
|
+
var dateFormatConfigSchema = z2.strictObject({
|
|
8023
|
+
calendar: z2.string().optional(),
|
|
8024
|
+
dateStyle: z2.enum(["full", "long", "medium", "short"]).optional(),
|
|
8025
|
+
day: z2.enum(["numeric", "2-digit"]).optional(),
|
|
8026
|
+
era: z2.enum(["long", "short", "narrow"]).optional(),
|
|
8027
|
+
month: z2.enum(["numeric", "2-digit", "long", "short", "narrow"]).optional(),
|
|
8028
|
+
numberingSystem: z2.string().optional(),
|
|
8029
|
+
timeZone: z2.string().optional(),
|
|
8030
|
+
weekday: z2.enum(["long", "short", "narrow"]).optional(),
|
|
8031
|
+
year: z2.enum(["numeric", "2-digit"]).optional()
|
|
8032
|
+
}).refine((value) => value.dateStyle === undefined || value.weekday === undefined && value.era === undefined && value.year === undefined && value.month === undefined && value.day === undefined, {
|
|
8033
|
+
message: "dateFormat.dateStyle can't be combined with weekday/era/year/month/day; use one or the other."
|
|
8034
|
+
});
|
|
7997
8035
|
var codeConfigSchema = z2.strictObject({
|
|
7998
8036
|
icons: z2.boolean().default(true),
|
|
7999
8037
|
wrap: z2.boolean().default(false)
|
|
@@ -8012,12 +8050,14 @@ var openapiSourceSchema = z2.strictObject({
|
|
|
8012
8050
|
route: z2.string().optional(),
|
|
8013
8051
|
spec: z2.string()
|
|
8014
8052
|
});
|
|
8053
|
+
var scalarConfigSchema = z2.record(z2.string(), z2.unknown()).optional();
|
|
8015
8054
|
var openapiConfigSchema = z2.strictObject({
|
|
8016
8055
|
codeSamples: z2.array(z2.string()).default(["curl", "js", "python"]),
|
|
8017
8056
|
enabled: z2.boolean().default(false),
|
|
8018
8057
|
expandSchemas: z2.boolean().default(false),
|
|
8019
8058
|
renderer: z2.enum(["blume", "scalar"]).default("blume"),
|
|
8020
8059
|
route: z2.string().default("/reference"),
|
|
8060
|
+
scalar: scalarConfigSchema,
|
|
8021
8061
|
sources: z2.array(openapiSourceSchema).default([]),
|
|
8022
8062
|
spec: z2.string().optional(),
|
|
8023
8063
|
theme: z2.string().optional()
|
|
@@ -8025,6 +8065,7 @@ var openapiConfigSchema = z2.strictObject({
|
|
|
8025
8065
|
var asyncapiConfigSchema = z2.strictObject({
|
|
8026
8066
|
enabled: z2.boolean().default(false),
|
|
8027
8067
|
route: z2.string().default("/events"),
|
|
8068
|
+
scalar: scalarConfigSchema,
|
|
8028
8069
|
sources: z2.array(openapiSourceSchema).default([]),
|
|
8029
8070
|
spec: z2.string().optional(),
|
|
8030
8071
|
theme: z2.string().optional()
|
|
@@ -8069,6 +8110,7 @@ var blumeConfigSchema = z2.strictObject({
|
|
|
8069
8110
|
banner: bannerConfigSchema.optional(),
|
|
8070
8111
|
basePath: z2.string().optional().transform((value) => normalizeBasePath(value)),
|
|
8071
8112
|
content: contentConfigSchema.default({}),
|
|
8113
|
+
dateFormat: dateFormatConfigSchema.default({ dateStyle: "long" }),
|
|
8072
8114
|
deployment: deploymentConfigSchema.default({}),
|
|
8073
8115
|
description: z2.string().optional(),
|
|
8074
8116
|
examples: examplesConfigSchema.default("examples"),
|
|
@@ -8173,9 +8215,10 @@ var detectLocale = (parts, i18n) => {
|
|
|
8173
8215
|
var localePlacement = (rel, ext, i18n) => {
|
|
8174
8216
|
const base = rel.slice(0, rel.length - ext.length);
|
|
8175
8217
|
if (base.endsWith(".$")) {
|
|
8218
|
+
const shared = `${base.slice(0, -2)}${ext}`;
|
|
8176
8219
|
return {
|
|
8177
8220
|
locales: i18n.locales.map((locale2) => locale2.code),
|
|
8178
|
-
navPath:
|
|
8221
|
+
navPath: i18n.parser === "dir" ? detectLocale(shared.split("/"), i18n).rest.join("/") : shared
|
|
8179
8222
|
};
|
|
8180
8223
|
}
|
|
8181
8224
|
if (i18n.parser === "dot") {
|
|
@@ -8655,7 +8698,8 @@ var normalizeRef = (ref) => {
|
|
|
8655
8698
|
return "/";
|
|
8656
8699
|
}
|
|
8657
8700
|
const withSlash = ref.startsWith("/") ? ref : `/${ref}`;
|
|
8658
|
-
const
|
|
8701
|
+
const noTrailing = withSlash.replace(/\/+$/u, "");
|
|
8702
|
+
const trimmed = noTrailing.endsWith("/index") ? noTrailing.slice(0, -"/index".length) : noTrailing;
|
|
8659
8703
|
return trimmed === "" ? "/" : trimmed;
|
|
8660
8704
|
};
|
|
8661
8705
|
var routeForRef = (ref, byRoute, basePath) => {
|
|
@@ -8862,7 +8906,10 @@ var buildLocaleNavigation = (code, pages, fallback, fallbackByKey, options, i18n
|
|
|
8862
8906
|
basePath: options.basePath ?? "",
|
|
8863
8907
|
diagnostics,
|
|
8864
8908
|
display: options.navigation.sidebar.display,
|
|
8865
|
-
featured: options.navigation.featured
|
|
8909
|
+
featured: options.navigation.featured?.map((link) => ({
|
|
8910
|
+
...link,
|
|
8911
|
+
href: localizePath(link.href)
|
|
8912
|
+
})),
|
|
8866
8913
|
folderMeta: options.folderMeta,
|
|
8867
8914
|
localizedRoot: localizeRoute("/", code, i18n),
|
|
8868
8915
|
metaPrefix: i18n.parser === "dir" && code !== i18n.defaultLocale ? code : "",
|
|
@@ -9158,6 +9205,7 @@ var WORD_SPLIT2 = /[-_]/u;
|
|
|
9158
9205
|
var stripNumericPrefix = (segment) => segment.replace(NUMERIC_PREFIX2, "");
|
|
9159
9206
|
var groupLabel = (segment) => segment.match(GROUP_FOLDER2)?.groups?.label ?? null;
|
|
9160
9207
|
var slugify2 = (text) => text.toLowerCase().trim().replaceAll(/[^\w\s-]/gu, "").replaceAll(/[\s_]+/gu, "-").replaceAll(/-+/gu, "-").replaceAll(/^-|-$/gu, "");
|
|
9208
|
+
var slugifyPath = (text) => text.split("/").map(slugify2).filter(Boolean).join("/");
|
|
9161
9209
|
var titleCase = (value) => value.split(WORD_SPLIT2).filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
9162
9210
|
var addRouteSegment = (part, segments, groups) => {
|
|
9163
9211
|
if (part === "") {
|
|
@@ -9187,11 +9235,18 @@ var mapRoute = (relativePath) => {
|
|
|
9187
9235
|
};
|
|
9188
9236
|
var CODE_FENCE = /^(?<delimiter>```|~~~)/u;
|
|
9189
9237
|
var nextFenceState = (line, fence) => {
|
|
9190
|
-
const
|
|
9238
|
+
const trimmed = line.trimStart();
|
|
9239
|
+
const delimiter = trimmed.match(CODE_FENCE)?.groups?.delimiter;
|
|
9191
9240
|
if (delimiter === undefined) {
|
|
9192
9241
|
return fence;
|
|
9193
9242
|
}
|
|
9194
9243
|
if (fence === null) {
|
|
9244
|
+
if (delimiter === "```") {
|
|
9245
|
+
const run = trimmed.match(/^`+/u)?.[0].length ?? 0;
|
|
9246
|
+
if (trimmed.slice(run).includes("`")) {
|
|
9247
|
+
return fence;
|
|
9248
|
+
}
|
|
9249
|
+
}
|
|
9195
9250
|
return delimiter;
|
|
9196
9251
|
}
|
|
9197
9252
|
return fence === delimiter ? null : fence;
|
|
@@ -9209,6 +9264,9 @@ var linesWithoutFrontMatter = (body) => {
|
|
|
9209
9264
|
if (!/^-{3}\s*$/u.test(lines[0] ?? "")) {
|
|
9210
9265
|
return lines;
|
|
9211
9266
|
}
|
|
9267
|
+
if ((lines[1] ?? "").trim() === "") {
|
|
9268
|
+
return lines;
|
|
9269
|
+
}
|
|
9212
9270
|
const close = lines.findIndex((line, index) => index > 0 && FRONT_MATTER_CLOSE.test(line));
|
|
9213
9271
|
return close === -1 ? lines : lines.slice(close + 1);
|
|
9214
9272
|
};
|
|
@@ -9288,8 +9346,10 @@ var extractHeadings = (body) => {
|
|
|
9288
9346
|
}
|
|
9289
9347
|
return headings;
|
|
9290
9348
|
};
|
|
9291
|
-
var MD_LINK = /\[[^\]]*\]\((?<target>[^)\s]+)(
|
|
9349
|
+
var MD_LINK = /\[(?<label>(?:[^[\]]|\[[^\]]*\])*)\]\((?<target>(?:[^()\s]|\([^()\s]*\))+)(?<title>\s+"[^"]*")?\)/gu;
|
|
9350
|
+
var MD_IMAGE = /!\[[^\]]*\]\((?<target>(?:[^()\s]|\([^()\s]*\))+)(?<title>\s+"[^"]*")?\)/gu;
|
|
9292
9351
|
var INLINE_CODE = /`[^`]*`/gu;
|
|
9352
|
+
var targetOffsetIn = (matched, target, title) => matched.length - 1 - (title?.length ?? 0) - target.length;
|
|
9293
9353
|
var scanLinkLine = (line, lineNumber, fence, links) => {
|
|
9294
9354
|
const next = nextFenceState(line, fence);
|
|
9295
9355
|
if (fence !== null || next !== null) {
|
|
@@ -9301,12 +9361,24 @@ var scanLinkLine = (line, lineNumber, fence, links) => {
|
|
|
9301
9361
|
if (target === undefined || match.index === undefined) {
|
|
9302
9362
|
continue;
|
|
9303
9363
|
}
|
|
9304
|
-
const targetOffset = match
|
|
9364
|
+
const targetOffset = targetOffsetIn(match[0], target, match.groups?.title);
|
|
9305
9365
|
links.push({
|
|
9306
|
-
column: targetOffset + 1,
|
|
9366
|
+
column: match.index + targetOffset + 1,
|
|
9307
9367
|
line: lineNumber,
|
|
9308
9368
|
target
|
|
9309
9369
|
});
|
|
9370
|
+
const label = match[0].slice(0, targetOffset - "](".length);
|
|
9371
|
+
for (const image of label.matchAll(MD_IMAGE)) {
|
|
9372
|
+
const imageTarget = image.groups?.target;
|
|
9373
|
+
if (imageTarget === undefined || image.index === undefined) {
|
|
9374
|
+
continue;
|
|
9375
|
+
}
|
|
9376
|
+
links.push({
|
|
9377
|
+
column: match.index + image.index + targetOffsetIn(image[0], imageTarget, image.groups?.title) + 1,
|
|
9378
|
+
line: lineNumber,
|
|
9379
|
+
target: imageTarget
|
|
9380
|
+
});
|
|
9381
|
+
}
|
|
9310
9382
|
}
|
|
9311
9383
|
return next;
|
|
9312
9384
|
};
|
|
@@ -9580,6 +9652,24 @@ var operationKey = (method, path, operationId) => {
|
|
|
9580
9652
|
return fromId || slugify3(`${method}-${path}`);
|
|
9581
9653
|
};
|
|
9582
9654
|
var isOperation = (value) => typeof value === "object" && value !== null;
|
|
9655
|
+
var tagSlugger = () => {
|
|
9656
|
+
const assigned = new Map;
|
|
9657
|
+
const taken = new Set;
|
|
9658
|
+
return (name) => {
|
|
9659
|
+
const existing = assigned.get(name);
|
|
9660
|
+
if (existing) {
|
|
9661
|
+
return existing;
|
|
9662
|
+
}
|
|
9663
|
+
const base = slugify3(name) || "operations";
|
|
9664
|
+
let slug = base;
|
|
9665
|
+
for (let suffix = 2;taken.has(slug); suffix += 1) {
|
|
9666
|
+
slug = `${base}-${suffix}`;
|
|
9667
|
+
}
|
|
9668
|
+
taken.add(slug);
|
|
9669
|
+
assigned.set(name, slug);
|
|
9670
|
+
return slug;
|
|
9671
|
+
};
|
|
9672
|
+
};
|
|
9583
9673
|
var extractOperations = (document, baseRoute) => {
|
|
9584
9674
|
const operations = [];
|
|
9585
9675
|
const tagOrder = [];
|
|
@@ -9587,6 +9677,7 @@ var extractOperations = (document, baseRoute) => {
|
|
|
9587
9677
|
const tagMeta = new Map((document.tags ?? []).map((tag) => [tag.name, tag.description ?? ""]));
|
|
9588
9678
|
const seen = new Set;
|
|
9589
9679
|
const warnings = [];
|
|
9680
|
+
const slugForTag = tagSlugger();
|
|
9590
9681
|
for (const [path, rawItem] of Object.entries(document.paths ?? {})) {
|
|
9591
9682
|
const item = rawItem;
|
|
9592
9683
|
if (!item) {
|
|
@@ -9602,7 +9693,7 @@ var extractOperations = (document, baseRoute) => {
|
|
|
9602
9693
|
continue;
|
|
9603
9694
|
}
|
|
9604
9695
|
const tag = operation.tags?.[0] ?? UNTAGGED;
|
|
9605
|
-
const tagSlug =
|
|
9696
|
+
const tagSlug = slugForTag(tag);
|
|
9606
9697
|
if (!tagsSeen.has(tag)) {
|
|
9607
9698
|
tagsSeen.add(tag);
|
|
9608
9699
|
tagOrder.push(tag);
|
|
@@ -9629,7 +9720,7 @@ var extractOperations = (document, baseRoute) => {
|
|
|
9629
9720
|
const tags = tagOrder.map((name) => ({
|
|
9630
9721
|
description: tagMeta.get(name) ?? "",
|
|
9631
9722
|
name,
|
|
9632
|
-
slug:
|
|
9723
|
+
slug: slugForTag(name)
|
|
9633
9724
|
}));
|
|
9634
9725
|
return { operations, tags, warnings };
|
|
9635
9726
|
};
|
|
@@ -9779,15 +9870,14 @@ var parseSpec = async (spec, root, options = {}) => {
|
|
|
9779
9870
|
};
|
|
9780
9871
|
|
|
9781
9872
|
// src/openapi/render-mdx.ts
|
|
9782
|
-
var MDX_UNSAFE = /[
|
|
9873
|
+
var MDX_UNSAFE = /[<{}]/gu;
|
|
9783
9874
|
var ENTITIES = {
|
|
9784
9875
|
"<": "<",
|
|
9785
|
-
">": ">",
|
|
9786
9876
|
"{": "{",
|
|
9787
9877
|
"}": "}"
|
|
9788
9878
|
};
|
|
9789
9879
|
var MDX_ESM_KEYWORD = /^(?<keyword>import|export)\b/gmu;
|
|
9790
|
-
var BACKTICK_CODE = /(?<bt>`+)[\s\S]
|
|
9880
|
+
var BACKTICK_CODE = /(?<!`)(?<bt>`+)(?!`)[\s\S]*?(?<!`)\k<bt>(?!`)/gu;
|
|
9791
9881
|
var escapeProse = (text) => text.replace(MDX_UNSAFE, (char) => ENTITIES[char] ?? char).replace(MDX_ESM_KEYWORD, (keyword) => `&#${keyword.codePointAt(0)};${keyword.slice(1)}`);
|
|
9792
9882
|
var mdxSafe = (text) => {
|
|
9793
9883
|
let out = "";
|
|
@@ -10399,7 +10489,7 @@ import { join as join15 } from "pathe";
|
|
|
10399
10489
|
// src/core/sources/assets.ts
|
|
10400
10490
|
import { mkdir as mkdir5, writeFile as writeFile5 } from "node:fs/promises";
|
|
10401
10491
|
import { extname as extname4, join as join14 } from "pathe";
|
|
10402
|
-
var
|
|
10492
|
+
var MD_IMAGE2 = /!\[(?<alt>[^\]]*)\]\((?<url>[^)\s]+)\)/gu;
|
|
10403
10493
|
var REMOTE = /^https?:\/\//u;
|
|
10404
10494
|
var SAFE_EXT = /^\.[a-z0-9]+$/iu;
|
|
10405
10495
|
var CODE_FENCE_BLOCK = /^(?<fence>`{3,}|~{3,})[^\n]*\n[\s\S]*?^\k<fence>[^\n]*(?=\n|$)/gmu;
|
|
@@ -10418,7 +10508,7 @@ var materializeAssets = async (markdown, ctx) => {
|
|
|
10418
10508
|
return `\x00blume-fence-${fences.length - 1}\x00`;
|
|
10419
10509
|
});
|
|
10420
10510
|
const urls = new Set;
|
|
10421
|
-
for (const match of masked.matchAll(
|
|
10511
|
+
for (const match of masked.matchAll(MD_IMAGE2)) {
|
|
10422
10512
|
const url = match.groups?.url;
|
|
10423
10513
|
if (url && REMOTE.test(url)) {
|
|
10424
10514
|
urls.add(url);
|
|
@@ -10444,7 +10534,7 @@ var materializeAssets = async (markdown, ctx) => {
|
|
|
10444
10534
|
});
|
|
10445
10535
|
}
|
|
10446
10536
|
}));
|
|
10447
|
-
const rewritten = masked.replaceAll(
|
|
10537
|
+
const rewritten = masked.replaceAll(MD_IMAGE2, (match, alt, url) => {
|
|
10448
10538
|
const local = rewrites.get(url);
|
|
10449
10539
|
return local ? `` : match;
|
|
10450
10540
|
}).replaceAll(FENCE_TOKEN, (token, index) => fences[Number(index)] ?? token);
|
|
@@ -10679,7 +10769,7 @@ ${nested}`;
|
|
|
10679
10769
|
data.sidebar = { order };
|
|
10680
10770
|
}
|
|
10681
10771
|
const slugProp = richToMarkdown(page.properties[props.slug ?? "Slug"]?.rich_text);
|
|
10682
|
-
const slug =
|
|
10772
|
+
const slug = slugifyPath(slugProp || title) || page.id;
|
|
10683
10773
|
return { data, slug };
|
|
10684
10774
|
};
|
|
10685
10775
|
const toEntry2 = async (client, page) => {
|
|
@@ -10886,7 +10976,7 @@ var sanitySource = (options, ctx) => {
|
|
|
10886
10976
|
let snapshot = new Map;
|
|
10887
10977
|
const toEntry2 = (doc) => {
|
|
10888
10978
|
const slugValue = asString(getPath(doc, fields.slug ?? "slug.current")) ?? asString(doc._id) ?? "untitled";
|
|
10889
|
-
const slug =
|
|
10979
|
+
const slug = slugifyPath(slugValue) || slugify2(asString(doc._id) ?? "") || "untitled";
|
|
10890
10980
|
const data = {};
|
|
10891
10981
|
const title = asString(getPath(doc, fields.title ?? "title"));
|
|
10892
10982
|
const description = asString(getPath(doc, fields.description ?? "description"));
|
|
@@ -11246,6 +11336,16 @@ var shouldFail = (result, gate) => {
|
|
|
11246
11336
|
const failing = failingSeverities(gate);
|
|
11247
11337
|
return result.diagnostics.some((d) => failing.has(d.severity));
|
|
11248
11338
|
};
|
|
11339
|
+
var launchAgentCode = async (bin, prompt) => {
|
|
11340
|
+
try {
|
|
11341
|
+
return await launchAgent(bin, prompt);
|
|
11342
|
+
} catch (error) {
|
|
11343
|
+
if (error?.code !== "ENOENT") {
|
|
11344
|
+
throw error;
|
|
11345
|
+
}
|
|
11346
|
+
return WINDOWS_COMMAND_NOT_FOUND;
|
|
11347
|
+
}
|
|
11348
|
+
};
|
|
11249
11349
|
var auditCommand = defineCommand2({
|
|
11250
11350
|
args: {
|
|
11251
11351
|
claude: {
|
|
@@ -11351,12 +11451,7 @@ var auditCommand = defineCommand2({
|
|
|
11351
11451
|
process.stderr.write(` Handing ${count} finding${count === 1 ? "" : "s"} to ${cli.name}…
|
|
11352
11452
|
|
|
11353
11453
|
`);
|
|
11354
|
-
|
|
11355
|
-
try {
|
|
11356
|
-
code = await launchAgent(cli.bin, fixPrompt(report));
|
|
11357
|
-
} catch {
|
|
11358
|
-
code = WINDOWS_COMMAND_NOT_FOUND;
|
|
11359
|
-
}
|
|
11454
|
+
const code = await launchAgentCode(cli.bin, fixPrompt(report));
|
|
11360
11455
|
if (code === WINDOWS_COMMAND_NOT_FOUND) {
|
|
11361
11456
|
logger.error(`${cli.name} (\`${cli.bin}\`) was not found on PATH. Install it with \`${cli.install}\`.`);
|
|
11362
11457
|
process.exit(1);
|
|
@@ -11734,6 +11829,22 @@ var youtube = ({ props }) => {
|
|
|
11734
11829
|
const title = typeof props.title === "string" && props.title !== "" ? props.title : "Watch on YouTube";
|
|
11735
11830
|
return `[${title}](https://www.youtube.com/watch?v=${videoId}${start})`;
|
|
11736
11831
|
};
|
|
11832
|
+
var fencedBlock = (lang, code) => {
|
|
11833
|
+
const trimmed = code.replace(/(?<!\n)\n+$/u, "");
|
|
11834
|
+
const runs = trimmed.match(/`+/gu);
|
|
11835
|
+
const longest = runs ? Math.max(...runs.map((run) => run.length)) : 0;
|
|
11836
|
+
const fence = "`".repeat(Math.max(3, longest + 1));
|
|
11837
|
+
return `${fence}${lang}
|
|
11838
|
+
${trimmed}
|
|
11839
|
+
${fence}`;
|
|
11840
|
+
};
|
|
11841
|
+
var exampleComponentSerializers = (examples) => ({
|
|
11842
|
+
Component: ({ props }) => {
|
|
11843
|
+
const path = typeof props.path === "string" ? props.path : undefined;
|
|
11844
|
+
const example = path === undefined ? undefined : examples[path];
|
|
11845
|
+
return example ? fencedBlock(example.lang, example.source) : null;
|
|
11846
|
+
}
|
|
11847
|
+
});
|
|
11737
11848
|
var SERIALIZERS = {
|
|
11738
11849
|
Callout: callout,
|
|
11739
11850
|
Steps: steps,
|
|
@@ -11929,10 +12040,14 @@ var buildIndex = (project) => {
|
|
|
11929
12040
|
var buildFull = async (project) => {
|
|
11930
12041
|
const { config } = project;
|
|
11931
12042
|
const pages = eligiblePages(project).toSorted((a, b) => a.route.localeCompare(b.route));
|
|
12043
|
+
const components = {
|
|
12044
|
+
...exampleComponentSerializers(project.examples ?? {}),
|
|
12045
|
+
...config.ai.markdownComponents
|
|
12046
|
+
};
|
|
11932
12047
|
const sections = await Promise.all(pages.map(async (page) => {
|
|
11933
12048
|
const raw = await readEntryText(project, page);
|
|
11934
12049
|
const parsed = frontmatter_default(raw);
|
|
11935
|
-
const body = downlevelComponents(applyAgentVisibility(parsed.content),
|
|
12050
|
+
const body = downlevelComponents(applyAgentVisibility(parsed.content), components, parsed.data).trim();
|
|
11936
12051
|
const url = pageUrl(page.route, config.deployment.site, normalizeBasePath(config.deployment.base));
|
|
11937
12052
|
return [`# ${page.title}`, `Source: ${url}`, "", body].join(`
|
|
11938
12053
|
`);
|
|
@@ -12539,6 +12654,7 @@ import {
|
|
|
12539
12654
|
lstat,
|
|
12540
12655
|
mkdir as mkdir6,
|
|
12541
12656
|
readFile as readFile14,
|
|
12657
|
+
readlink,
|
|
12542
12658
|
realpath,
|
|
12543
12659
|
rename,
|
|
12544
12660
|
rm as rm2,
|
|
@@ -12547,7 +12663,7 @@ import {
|
|
|
12547
12663
|
} from "node:fs/promises";
|
|
12548
12664
|
import { createRequire as createRequire5 } from "node:module";
|
|
12549
12665
|
import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
12550
|
-
import { basename as basename3, dirname as dirname9, join as join26, normalize as normalize3, relative as relative13 } from "pathe";
|
|
12666
|
+
import { basename as basename3, dirname as dirname9, join as join26, normalize as normalize3, relative as relative13, resolve as resolve7 } from "pathe";
|
|
12551
12667
|
import { glob as glob7 } from "tinyglobby";
|
|
12552
12668
|
|
|
12553
12669
|
// src/ai/ask-data.ts
|
|
@@ -12574,6 +12690,10 @@ import { readFile as readFile10 } from "node:fs/promises";
|
|
|
12574
12690
|
var agentMarkdown = (entry) => entry.md ?? entry.mdx;
|
|
12575
12691
|
var buildRawMarkdown = async (project) => {
|
|
12576
12692
|
const pageById = new Map(project.graph.pages.map((page) => [page.id, page]));
|
|
12693
|
+
const components = {
|
|
12694
|
+
...exampleComponentSerializers(project.examples ?? {}),
|
|
12695
|
+
...project.config.ai.markdownComponents
|
|
12696
|
+
};
|
|
12577
12697
|
const readRoute = async (route) => {
|
|
12578
12698
|
const page = pageById.get(route.id);
|
|
12579
12699
|
if (page) {
|
|
@@ -12583,7 +12703,7 @@ var buildRawMarkdown = async (project) => {
|
|
|
12583
12703
|
};
|
|
12584
12704
|
const entries = await Promise.all(project.manifest.routes.map(async (route) => {
|
|
12585
12705
|
const source = applyAgentVisibility(await readRoute(route));
|
|
12586
|
-
const md = downlevelComponents(source,
|
|
12706
|
+
const md = downlevelComponents(source, components, frontmatter_default(source).data);
|
|
12587
12707
|
const entry = md === source ? { mdx: source } : { md, mdx: source };
|
|
12588
12708
|
return [route.path, entry];
|
|
12589
12709
|
}));
|
|
@@ -13351,7 +13471,8 @@ var buildReferenceFiles = async (options) => {
|
|
|
13351
13471
|
content: scalarReferenceTemplate({
|
|
13352
13472
|
configuration: {
|
|
13353
13473
|
...spec.config,
|
|
13354
|
-
...themeConfiguration(config, ref.theme)
|
|
13474
|
+
...themeConfiguration(config, ref.theme),
|
|
13475
|
+
...ref.scalar
|
|
13355
13476
|
},
|
|
13356
13477
|
dataImport: `${"../".repeat(depth + 1)}generated/data.json`,
|
|
13357
13478
|
route: ref.route,
|
|
@@ -13582,6 +13703,13 @@ ${THEME_MAPPING}
|
|
|
13582
13703
|
letter-spacing: 0;
|
|
13583
13704
|
}
|
|
13584
13705
|
|
|
13706
|
+
/* A heading can carry one long unbreakable token — an OpenAPI operation's title
|
|
13707
|
+
is \`METHOD /very/long/{path}\` when the spec sets no summary — which would run
|
|
13708
|
+
off the content column. Break it across lines instead of overflowing. */
|
|
13709
|
+
.prose :where(h1, h2, h3, h4, h5, h6) {
|
|
13710
|
+
overflow-wrap: break-word;
|
|
13711
|
+
}
|
|
13712
|
+
|
|
13585
13713
|
.prose :where(h1) {
|
|
13586
13714
|
font-size: 3rem;
|
|
13587
13715
|
line-height: 1.1;
|
|
@@ -14132,6 +14260,16 @@ var OVERRIDES = `
|
|
|
14132
14260
|
padding-right: 1.25rem;
|
|
14133
14261
|
}
|
|
14134
14262
|
|
|
14263
|
+
/* Twoslash blocks keep \`overflow: visible\` so popups can escape, which means
|
|
14264
|
+
long lines can't scroll — they'd push past the viewport on narrow screens.
|
|
14265
|
+
Wrap them on mobile instead; hover popups still position against the token. */
|
|
14266
|
+
@media (max-width: 640px) {
|
|
14267
|
+
.prose pre.twoslash code {
|
|
14268
|
+
white-space: pre-wrap;
|
|
14269
|
+
overflow-wrap: anywhere;
|
|
14270
|
+
}
|
|
14271
|
+
}
|
|
14272
|
+
|
|
14135
14273
|
/* The rich renderer renders each popup's type signature as a nested Shiki
|
|
14136
14274
|
pre. Strip the code-block chrome (border, radius, padding, background) so it
|
|
14137
14275
|
sits flush inside the popup, which owns the frame. */
|
|
@@ -14410,6 +14548,10 @@ var discoverExamples = async (root, pattern = "examples") => {
|
|
|
14410
14548
|
}
|
|
14411
14549
|
return { examples, warnings };
|
|
14412
14550
|
};
|
|
14551
|
+
var exampleMarkdownLookup = (examples) => Object.fromEntries(examples.map((example) => [
|
|
14552
|
+
example.path,
|
|
14553
|
+
{ lang: example.lang, source: example.source }
|
|
14554
|
+
]));
|
|
14413
14555
|
|
|
14414
14556
|
// src/astro/generate.ts
|
|
14415
14557
|
var BLUME_SRC = join26(packageRoot(), "src");
|
|
@@ -14421,12 +14563,12 @@ var canResolveFrom = (fromDir, spec) => {
|
|
|
14421
14563
|
return false;
|
|
14422
14564
|
}
|
|
14423
14565
|
};
|
|
14424
|
-
var resolveReactCompiler = (config, needsReact) => {
|
|
14566
|
+
var resolveReactCompiler = (config, needsReact, pkgDir = packageRoot()) => {
|
|
14425
14567
|
if (!(needsReact && config.react.compiler)) {
|
|
14426
14568
|
return null;
|
|
14427
14569
|
}
|
|
14428
14570
|
try {
|
|
14429
|
-
return createRequire5(pathToFileURL3(join26(
|
|
14571
|
+
return createRequire5(pathToFileURL3(join26(pkgDir, "_.js")).href).resolve("babel-plugin-react-compiler");
|
|
14430
14572
|
} catch {
|
|
14431
14573
|
return null;
|
|
14432
14574
|
}
|
|
@@ -14441,12 +14583,13 @@ var resolveAstroPackageJson = (modulesDir) => {
|
|
|
14441
14583
|
return null;
|
|
14442
14584
|
}
|
|
14443
14585
|
};
|
|
14444
|
-
var
|
|
14586
|
+
var resolvedAstroHit = (fromDir) => {
|
|
14445
14587
|
let dir = normalize3(fromDir);
|
|
14446
14588
|
while (true) {
|
|
14447
|
-
const
|
|
14448
|
-
|
|
14449
|
-
|
|
14589
|
+
const modulesDir = join26(dir, "node_modules");
|
|
14590
|
+
const pkg = resolveAstroPackageJson(modulesDir);
|
|
14591
|
+
if (pkg) {
|
|
14592
|
+
return { modulesDir, pkg };
|
|
14450
14593
|
}
|
|
14451
14594
|
const parent = dirname9(dir);
|
|
14452
14595
|
if (parent === dir) {
|
|
@@ -14455,6 +14598,13 @@ var resolvedAstroPath = (fromDir) => {
|
|
|
14455
14598
|
dir = parent;
|
|
14456
14599
|
}
|
|
14457
14600
|
};
|
|
14601
|
+
var sameRealDir = (a, b) => {
|
|
14602
|
+
try {
|
|
14603
|
+
return realpathSync(a) === realpathSync(b);
|
|
14604
|
+
} catch {
|
|
14605
|
+
return false;
|
|
14606
|
+
}
|
|
14607
|
+
};
|
|
14458
14608
|
var depsCandidates = (pkgDir) => [
|
|
14459
14609
|
join26(pkgDir, "node_modules"),
|
|
14460
14610
|
dirname9(pkgDir)
|
|
@@ -14471,6 +14621,11 @@ var linkDepsJunction = async (link, depsDir) => {
|
|
|
14471
14621
|
if (!existing.isSymbolicLink()) {
|
|
14472
14622
|
return;
|
|
14473
14623
|
}
|
|
14624
|
+
try {
|
|
14625
|
+
if (resolve7(dirname9(link), await readlink(link)) === resolve7(depsDir)) {
|
|
14626
|
+
return;
|
|
14627
|
+
}
|
|
14628
|
+
} catch {}
|
|
14474
14629
|
await rm2(link, { force: true });
|
|
14475
14630
|
}
|
|
14476
14631
|
await mkdir6(dirname9(link), { recursive: true });
|
|
@@ -14523,16 +14678,17 @@ var ensureDepsLink = async (outDir, pkgDir = packageRoot()) => {
|
|
|
14523
14678
|
const mdxDir = candidateHolding(pkgDir, "@astrojs", "mdx");
|
|
14524
14679
|
const blumeAstro = resolveAstroPackageJson(astroDir);
|
|
14525
14680
|
await dropStaleDepsLink(join26(outDir, "node_modules"), pkgDir);
|
|
14526
|
-
const
|
|
14527
|
-
const astroCorrect = blumeAstro !== null &&
|
|
14528
|
-
|
|
14681
|
+
const outDirHit = resolvedAstroHit(outDir);
|
|
14682
|
+
const astroCorrect = blumeAstro !== null && outDirHit?.pkg === blumeAstro;
|
|
14683
|
+
const walkLandsInDeps = astroCorrect && outDirHit !== null && sameRealDir(outDirHit.modulesDir, astroDir);
|
|
14684
|
+
if (walkLandsInDeps && mdxDir === astroDir) {
|
|
14529
14685
|
return null;
|
|
14530
14686
|
}
|
|
14531
14687
|
if (mdxDir && (mdxDir === astroDir || astroCorrect)) {
|
|
14532
14688
|
await linkDepsJunction(join26(outDir, "node_modules"), mdxDir);
|
|
14533
14689
|
return null;
|
|
14534
14690
|
}
|
|
14535
|
-
return astroConflictWarning(blumeAstro,
|
|
14691
|
+
return astroConflictWarning(blumeAstro, outDirHit?.pkg ?? null);
|
|
14536
14692
|
};
|
|
14537
14693
|
var ISLAND_FRAMEWORK_DEPS = {
|
|
14538
14694
|
svelte: "@astrojs/svelte",
|
|
@@ -14561,6 +14717,15 @@ var deploymentAdapterWarnings = (deployment, root) => {
|
|
|
14561
14717
|
}
|
|
14562
14718
|
return [];
|
|
14563
14719
|
};
|
|
14720
|
+
var searchProviderWarnings = (provider, root, pkgDir = packageRoot()) => {
|
|
14721
|
+
const warnings = [];
|
|
14722
|
+
for (const dep of searchProviderMeta(provider).runtimeDeps) {
|
|
14723
|
+
if (!(canResolveFrom(root, dep) || canResolveFrom(pkgDir, dep))) {
|
|
14724
|
+
warnings.push(`Search provider "${provider}" needs "${dep}", which isn't installed. Run \`npm install ${dep}\` (or your package manager's equivalent).`);
|
|
14725
|
+
}
|
|
14726
|
+
}
|
|
14727
|
+
return warnings;
|
|
14728
|
+
};
|
|
14564
14729
|
var examplesCssFile = (root, config) => config.examples.css ? join26(root, config.examples.css) : null;
|
|
14565
14730
|
var writeExamplesPreview = async (options) => {
|
|
14566
14731
|
const { config, hasExamples, root, srcDir, write } = options;
|
|
@@ -14823,6 +14988,7 @@ var buildRuntimeData = (project) => {
|
|
|
14823
14988
|
basePath: config.basePath,
|
|
14824
14989
|
codeThemes: config.markdown.codeBlocks.theme,
|
|
14825
14990
|
codeWrap: config.markdown.code.wrap,
|
|
14991
|
+
dateFormat: config.dateFormat,
|
|
14826
14992
|
description: config.description,
|
|
14827
14993
|
favicon: resolveFavicon(project),
|
|
14828
14994
|
feedback: config.feedback,
|
|
@@ -14965,6 +15131,7 @@ var writeNotFoundPage = async (write, srcDir, pages, contentPages) => {
|
|
|
14965
15131
|
}
|
|
14966
15132
|
await write(join26(srcDir, "pages", "404.astro"), notFoundPageTemplate());
|
|
14967
15133
|
};
|
|
15134
|
+
var diagnosticWarning = (diagnostic) => diagnostic.suggestion ? `${diagnostic.message} ${diagnostic.suggestion}` : diagnostic.message;
|
|
14968
15135
|
var buildComponentSlots = async (componentsFile) => {
|
|
14969
15136
|
const analysis = componentsFile ? analyzeComponentOverrides(await readFile14(componentsFile, "utf-8"), componentsFile) : null;
|
|
14970
15137
|
return {
|
|
@@ -14973,6 +15140,7 @@ var buildComponentSlots = async (componentsFile) => {
|
|
|
14973
15140
|
warnings: analysis ? analysis.warnings : []
|
|
14974
15141
|
};
|
|
14975
15142
|
};
|
|
15143
|
+
var contentWatchesRuntimeDir = (hasFilesystemSource, collectionBase, context) => hasFilesystemSource && runtimeDirWithin(collectionBase, context.outDir) !== null;
|
|
14976
15144
|
var generateRuntime = async (project) => {
|
|
14977
15145
|
const { context, config } = project;
|
|
14978
15146
|
const out = context.outDir;
|
|
@@ -15018,6 +15186,7 @@ var generateRuntime = async (project) => {
|
|
|
15018
15186
|
tags: overrideTags,
|
|
15019
15187
|
warnings: overrideWarnings
|
|
15020
15188
|
} = componentSlots;
|
|
15189
|
+
project.examples = exampleMarkdownLookup(exampleDiscovery.examples);
|
|
15021
15190
|
const frameworks = new Set([
|
|
15022
15191
|
...islandDiscovery.islands.map((island) => island.framework),
|
|
15023
15192
|
...exampleDiscovery.examples.map((example) => example.framework),
|
|
@@ -15032,6 +15201,7 @@ var generateRuntime = async (project) => {
|
|
|
15032
15201
|
pages.push(...mcp.discoveryPages);
|
|
15033
15202
|
const hasStaged = staged.size > 0;
|
|
15034
15203
|
const hasFilesystemSource = project.sources.some((source) => !source.staged);
|
|
15204
|
+
const docsCollection = resolveDocsCollection(config, context);
|
|
15035
15205
|
const [structural] = await Promise.all([
|
|
15036
15206
|
Promise.all([
|
|
15037
15207
|
write(join26(out, "astro.config.mjs"), astroConfigTemplate({
|
|
@@ -15039,6 +15209,7 @@ var generateRuntime = async (project) => {
|
|
|
15039
15209
|
askPath,
|
|
15040
15210
|
config,
|
|
15041
15211
|
contentRoutes: project.manifest.routes.map((route) => route.path),
|
|
15212
|
+
contentWatchesRuntimeDir: contentWatchesRuntimeDir(hasFilesystemSource, docsCollection.base, context),
|
|
15042
15213
|
context,
|
|
15043
15214
|
dataPath,
|
|
15044
15215
|
examplesPath,
|
|
@@ -15056,7 +15227,7 @@ var generateRuntime = async (project) => {
|
|
|
15056
15227
|
write(join26(out, "tsconfig.json"), runtimeTsconfigTemplate()),
|
|
15057
15228
|
write(join26(srcDir, "env.d.ts"), envTemplate()),
|
|
15058
15229
|
write(join26(srcDir, "content.config.ts"), contentConfigTemplate({
|
|
15059
|
-
collection:
|
|
15230
|
+
collection: docsCollection,
|
|
15060
15231
|
config,
|
|
15061
15232
|
context,
|
|
15062
15233
|
filesystem: hasFilesystemSource,
|
|
@@ -15160,18 +15331,12 @@ var generateRuntime = async (project) => {
|
|
|
15160
15331
|
warnings.push(...[
|
|
15161
15332
|
...validateNavTargets(project.graph.navigation, navTargetRoutes),
|
|
15162
15333
|
...validateSearchPopularIcons(config.search.popular)
|
|
15163
|
-
].map(
|
|
15334
|
+
].map(diagnosticWarning));
|
|
15164
15335
|
const knownComponentTags = new Set([
|
|
15165
15336
|
...islandDiscovery.islands.map((island) => island.name),
|
|
15166
15337
|
...overrideTags
|
|
15167
15338
|
]);
|
|
15168
|
-
warnings.push(...validateUsedComponents(project.graph.pages, knownComponentTags, new Set(registry.map((item) => item.name))).map(
|
|
15169
|
-
for (const dep of searchProviderMeta(config.search.provider).runtimeDeps) {
|
|
15170
|
-
if (!(canResolveFrom(context.root, dep) || canResolveFrom(packageRoot(), dep))) {
|
|
15171
|
-
warnings.push(`Search provider "${config.search.provider}" needs "${dep}", which isn't installed. Run \`npm install ${dep}\` (or your package manager's equivalent).`);
|
|
15172
|
-
}
|
|
15173
|
-
}
|
|
15174
|
-
warnings.push(...deploymentAdapterWarnings(config.deployment, context.root), ...islandFrameworkWarnings(frameworks, context.root));
|
|
15339
|
+
warnings.push(...validateUsedComponents(project.graph.pages, knownComponentTags, new Set(registry.map((item) => item.name))).map(diagnosticWarning), ...searchProviderWarnings(config.search.provider, context.root), ...deploymentAdapterWarnings(config.deployment, context.root), ...islandFrameworkWarnings(frameworks, context.root));
|
|
15175
15340
|
if (hasScalarReferences(config)) {
|
|
15176
15341
|
const references = await buildReferenceFiles({
|
|
15177
15342
|
config,
|
|
@@ -15196,7 +15361,7 @@ var generateRuntime = async (project) => {
|
|
|
15196
15361
|
|
|
15197
15362
|
// src/cli/env.ts
|
|
15198
15363
|
import { existsSync as existsSync15, readFileSync as readFileSync10 } from "node:fs";
|
|
15199
|
-
import { dirname as dirname10, join as join27, resolve as
|
|
15364
|
+
import { dirname as dirname10, join as join27, resolve as resolve8 } from "pathe";
|
|
15200
15365
|
var ENV_LINE = /^\s*(?:export\s+)?(?<key>[A-Za-z_][A-Za-z0-9_]*)\s*=\s*(?<value>.*?)\s*$/u;
|
|
15201
15366
|
var DOUBLE_QUOTED2 = /^"(?<body>[\s\S]*)"$/u;
|
|
15202
15367
|
var SINGLE_QUOTED = /^'(?<body>[\s\S]*)'$/u;
|
|
@@ -15248,7 +15413,7 @@ var loadFile = (path) => {
|
|
|
15248
15413
|
} catch {}
|
|
15249
15414
|
};
|
|
15250
15415
|
var loadEnvFiles = (startDir) => {
|
|
15251
|
-
let dir =
|
|
15416
|
+
let dir = resolve8(startDir);
|
|
15252
15417
|
let done = false;
|
|
15253
15418
|
while (!done) {
|
|
15254
15419
|
loadFile(join27(dir, ".env.local"));
|
|
@@ -15690,6 +15855,7 @@ var checkCommand = defineCommand4({
|
|
|
15690
15855
|
import { watch } from "node:fs";
|
|
15691
15856
|
import { dev } from "astro";
|
|
15692
15857
|
import { defineCommand as defineCommand5 } from "citty";
|
|
15858
|
+
import { basename as basename4, dirname as dirname11 } from "pathe";
|
|
15693
15859
|
|
|
15694
15860
|
// src/astro/integration.ts
|
|
15695
15861
|
var overlayServer = null;
|
|
@@ -15868,17 +16034,26 @@ var devCommand = defineCommand5({
|
|
|
15868
16034
|
if (boundPort !== port) {
|
|
15869
16035
|
runRegenerate();
|
|
15870
16036
|
}
|
|
16037
|
+
const dirTargets = [project.context.pagesRoot].filter((target) => target !== null);
|
|
15871
16038
|
const fileTargets = [
|
|
15872
|
-
project.context.pagesRoot,
|
|
15873
16039
|
project.context.configFile,
|
|
15874
16040
|
project.context.themeFile,
|
|
15875
16041
|
project.context.componentsFile
|
|
15876
16042
|
].filter((target) => target !== null);
|
|
15877
16043
|
const disposers = [
|
|
15878
16044
|
...project.sources.map((source) => source.watch?.(regenerate)),
|
|
15879
|
-
...
|
|
16045
|
+
...dirTargets.map((target) => {
|
|
15880
16046
|
const watcher = watch(target, { recursive: true }, regenerate);
|
|
15881
16047
|
return () => watcher.close();
|
|
16048
|
+
}),
|
|
16049
|
+
...fileTargets.map((target) => {
|
|
16050
|
+
const name = basename4(target);
|
|
16051
|
+
const watcher = watch(dirname11(target), (_event, filename) => {
|
|
16052
|
+
if (!filename || filename === name) {
|
|
16053
|
+
regenerate();
|
|
16054
|
+
}
|
|
16055
|
+
});
|
|
16056
|
+
return () => watcher.close();
|
|
15882
16057
|
})
|
|
15883
16058
|
].filter((dispose) => dispose !== undefined);
|
|
15884
16059
|
const shutdown = async () => {
|
|
@@ -16112,6 +16287,8 @@ var eject = async (root) => {
|
|
|
16112
16287
|
const askEnabled = config.ai.ask?.enabled ?? false;
|
|
16113
16288
|
const exportPdf = config.export.pdf;
|
|
16114
16289
|
const exportEpub = config.export.epub;
|
|
16290
|
+
const examples = await discoverExamples(root, config.examples.source);
|
|
16291
|
+
project.examples = exampleMarkdownLookup(examples.examples);
|
|
16115
16292
|
const [
|
|
16116
16293
|
pages,
|
|
16117
16294
|
needsReactRaw,
|
|
@@ -16119,8 +16296,7 @@ var eject = async (root) => {
|
|
|
16119
16296
|
userTheme,
|
|
16120
16297
|
userExamplesCss,
|
|
16121
16298
|
rawMarkdown,
|
|
16122
|
-
islands
|
|
16123
|
-
examples
|
|
16299
|
+
islands
|
|
16124
16300
|
] = await Promise.all([
|
|
16125
16301
|
context.pagesRoot ? discoverPages(context.pagesRoot) : Promise.resolve([]),
|
|
16126
16302
|
detectNeedsReact(root),
|
|
@@ -16128,8 +16304,7 @@ var eject = async (root) => {
|
|
|
16128
16304
|
context.themeFile ? readFile15(context.themeFile, "utf-8") : Promise.resolve(""),
|
|
16129
16305
|
readExamplesCss(root, config.examples.css),
|
|
16130
16306
|
buildRawMarkdown(project),
|
|
16131
|
-
discoverIslands(root)
|
|
16132
|
-
discoverExamples(root, config.examples.source)
|
|
16307
|
+
discoverIslands(root)
|
|
16133
16308
|
]);
|
|
16134
16309
|
const frameworks = new Set([
|
|
16135
16310
|
...islands.islands.map((island) => island.framework),
|
|
@@ -16399,7 +16574,7 @@ var updatePackageScripts = async (root) => {
|
|
|
16399
16574
|
// src/cli/init/scaffold.ts
|
|
16400
16575
|
import { existsSync as existsSync19 } from "node:fs";
|
|
16401
16576
|
import { mkdir as mkdir8, writeFile as writeFile11 } from "node:fs/promises";
|
|
16402
|
-
import { basename as
|
|
16577
|
+
import { basename as basename5, dirname as dirname12, isAbsolute as isAbsolute9, join as join33, relative as relative15 } from "pathe";
|
|
16403
16578
|
|
|
16404
16579
|
// src/core/package-json.ts
|
|
16405
16580
|
var toPackageName = (raw) => raw.toLowerCase().replaceAll(/[^a-z0-9._-]+/gu, "-").replaceAll(/^[-_.]+|[-_.]+$/gu, "") || "docs";
|
|
@@ -16609,7 +16784,7 @@ var extraDepsFor = (sources) => ({
|
|
|
16609
16784
|
var buildPlan = (root, answers) => {
|
|
16610
16785
|
const files = [
|
|
16611
16786
|
{
|
|
16612
|
-
content: blumePackageJson(toPackageName(
|
|
16787
|
+
content: blumePackageJson(toPackageName(basename5(root)), extraDepsFor(answers.sources)),
|
|
16613
16788
|
path: join33(root, "package.json")
|
|
16614
16789
|
},
|
|
16615
16790
|
{ content: buildConfig(answers), path: join33(root, "blume.config.ts") }
|
|
@@ -16624,14 +16799,14 @@ var writeFileSafe = async (file, log) => {
|
|
|
16624
16799
|
log.info(`Skipped existing ${file.path}`);
|
|
16625
16800
|
return false;
|
|
16626
16801
|
}
|
|
16627
|
-
await mkdir8(
|
|
16802
|
+
await mkdir8(dirname12(file.path), { recursive: true });
|
|
16628
16803
|
await writeFile11(file.path, file.content, "utf-8");
|
|
16629
16804
|
log.success(`Created ${file.path}`);
|
|
16630
16805
|
return true;
|
|
16631
16806
|
};
|
|
16632
16807
|
var applyPlan = async (files, log) => {
|
|
16633
16808
|
const created = await Promise.all(files.map((file) => writeFileSafe(file, log)));
|
|
16634
|
-
const createdPackage = files.some((file, index) => created[index] &&
|
|
16809
|
+
const createdPackage = files.some((file, index) => created[index] && basename5(file.path) === "package.json");
|
|
16635
16810
|
return { createdPackage };
|
|
16636
16811
|
};
|
|
16637
16812
|
var envVarsFor = (sources) => [
|
|
@@ -16718,10 +16893,10 @@ The blume package remains importable.`);
|
|
|
16718
16893
|
// src/cli/commands/init.ts
|
|
16719
16894
|
import * as clack from "@clack/prompts";
|
|
16720
16895
|
import { defineCommand as defineCommand8 } from "citty";
|
|
16721
|
-
import { resolve as
|
|
16896
|
+
import { resolve as resolve10 } from "pathe";
|
|
16722
16897
|
|
|
16723
16898
|
// src/cli/init/questions.ts
|
|
16724
|
-
import { basename as
|
|
16899
|
+
import { basename as basename6, resolve as resolve9 } from "pathe";
|
|
16725
16900
|
var cancelled = (value) => typeof value === "symbol";
|
|
16726
16901
|
var collectAnswers = async (prompter, flags, defaults) => {
|
|
16727
16902
|
const directory = flags.directory ?? await prompter.text({
|
|
@@ -16732,9 +16907,9 @@ var collectAnswers = async (prompter, flags, defaults) => {
|
|
|
16732
16907
|
if (cancelled(directory)) {
|
|
16733
16908
|
return null;
|
|
16734
16909
|
}
|
|
16735
|
-
const root =
|
|
16910
|
+
const root = resolve9(defaults.cwd, directory);
|
|
16736
16911
|
const title = await prompter.text({
|
|
16737
|
-
initialValue: titleize(
|
|
16912
|
+
initialValue: titleize(basename6(root)),
|
|
16738
16913
|
message: "What's your docs site called?",
|
|
16739
16914
|
validate: (value) => value?.trim() ? undefined : "Give your docs site a name."
|
|
16740
16915
|
});
|
|
@@ -16901,7 +17076,7 @@ var initCommand = defineCommand8({
|
|
|
16901
17076
|
title: "My Docs"
|
|
16902
17077
|
};
|
|
16903
17078
|
}
|
|
16904
|
-
const root =
|
|
17079
|
+
const root = resolve10(cwd, answers.directory);
|
|
16905
17080
|
if (validateContentDir(root, answers.contentDir) !== undefined) {
|
|
16906
17081
|
logger.error(`Invalid --content-dir "${answers.contentDir}" (must be a path inside the project).`);
|
|
16907
17082
|
process.exit(1);
|
|
@@ -17008,7 +17183,7 @@ import { join as join37 } from "pathe";
|
|
|
17008
17183
|
|
|
17009
17184
|
// src/core/links.ts
|
|
17010
17185
|
import { existsSync as existsSync21 } from "node:fs";
|
|
17011
|
-
import { basename as
|
|
17186
|
+
import { basename as basename7, join as join36 } from "pathe";
|
|
17012
17187
|
var HTTP = /^https?:\/\//iu;
|
|
17013
17188
|
var PROTOCOL_RELATIVE = /^\/\//u;
|
|
17014
17189
|
var SCHEME = /^[a-z][a-z0-9+.-]*:/iu;
|
|
@@ -17023,7 +17198,7 @@ var DOC_EXT = /\.(?:md|mdx)$/iu;
|
|
|
17023
17198
|
var FILE_EXT = /\.[a-z0-9]+$/iu;
|
|
17024
17199
|
var assetIsPresent = (resolved, ctx) => ctx.publicDir !== null && existsSync21(join36(ctx.publicDir, resolved));
|
|
17025
17200
|
var NUMERIC_PREFIX3 = /^\d+[-_.]/u;
|
|
17026
|
-
var isIndexPage = (page2) => /^index\.(?:md|mdx)$/iu.test(
|
|
17201
|
+
var isIndexPage = (page2) => /^index\.(?:md|mdx)$/iu.test(basename7(page2.navPath).replace(NUMERIC_PREFIX3, ""));
|
|
17027
17202
|
var applyRelativePart = (segments, part) => {
|
|
17028
17203
|
if (part === "" || part === ".") {
|
|
17029
17204
|
return;
|
|
@@ -17299,5 +17474,5 @@ process.on("unhandledRejection", (error) => {
|
|
|
17299
17474
|
});
|
|
17300
17475
|
runMain(main);
|
|
17301
17476
|
|
|
17302
|
-
//# debugId=
|
|
17477
|
+
//# debugId=5D342B2E16EE6E0464756E2164756E21
|
|
17303
17478
|
//# sourceMappingURL=index.js.map
|