blume 1.1.3 → 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 +35 -0
- package/dist/cli/index.js +189 -88
- package/dist/cli/index.js.map +22 -22
- package/dist/types/core/data.d.ts +2 -0
- package/package.json +1 -1
- package/src/ai/mcp/server.ts +29 -6
- package/src/astro/generate.ts +94 -46
- package/src/astro/templates.ts +59 -15
- 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/RootLayout.astro +13 -2
- package/src/components/layout/Search.astro +5 -1
- package/src/components/layout/head-scripts.ts +22 -5
- package/src/core/data.ts +2 -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/sources/normalize.ts +69 -8
- package/src/core/sources/notion.ts +4 -2
- package/src/core/sources/sanity.ts +5 -3
- package/src/markdown/code-title.ts +7 -1
- package/src/openapi/model.ts +31 -2
- package/src/openapi/render-mdx.ts +12 -7
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))) {
|
|
@@ -3468,6 +3480,13 @@ var astroOutDir = (context) => context.distDir ?? `${context.root}/dist`;
|
|
|
3468
3480
|
var adapterRoot = (context) => dirname5(astroOutDir(context));
|
|
3469
3481
|
var REACT_EXCLUDE = String.raw`exclude: [/\/node_modules\/\.vite\//]`;
|
|
3470
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
|
+
},` : "";
|
|
3471
3490
|
var astroConfigTemplate = (options) => {
|
|
3472
3491
|
const { context, config, needsReact, pages, dataPath, themePath } = options;
|
|
3473
3492
|
const {
|
|
@@ -3554,6 +3573,7 @@ var astroConfigTemplate = (options) => {
|
|
|
3554
3573
|
integrations.push("svelte()");
|
|
3555
3574
|
}
|
|
3556
3575
|
integrations.push(`blumeIntegration(${JSON.stringify({ base: deployment.base, contentRoutes, pages })})`);
|
|
3576
|
+
const watchOption = devWatchOption(context.outDir, options.contentWatchesRuntimeDir);
|
|
3557
3577
|
return `// Generated by Blume. Do not edit; this file is recreated on each run.
|
|
3558
3578
|
${defineConfigImport}
|
|
3559
3579
|
import mdx from "@astrojs/mdx";
|
|
@@ -3628,22 +3648,17 @@ export default defineConfig({
|
|
|
3628
3648
|
server: {
|
|
3629
3649
|
fs: {
|
|
3630
3650
|
allow: ${JSON.stringify(fsAllow)},
|
|
3631
|
-
}
|
|
3632
|
-
// Keep the file watcher out of Astro's own cache dir. In a migrated
|
|
3633
|
-
// (root-rooted) project the docs collection is rooted at the project dir,
|
|
3634
|
-
// so its glob-loader watcher would otherwise fire on every write Astro
|
|
3635
|
-
// makes under .blume/.astro (data-store.json, content module manifests,
|
|
3636
|
-
// self-hosted fonts) -- pure noise the loader logs as "No entry type
|
|
3637
|
-
// found". Vite appends this to its default ignores.
|
|
3638
|
-
watch: {
|
|
3639
|
-
ignored: ${JSON.stringify([join8(context.outDir, ".astro", "**")])},
|
|
3640
|
-
},
|
|
3651
|
+
},${watchOption}
|
|
3641
3652
|
},
|
|
3642
3653
|
},
|
|
3643
3654
|
});
|
|
3644
3655
|
`;
|
|
3645
3656
|
};
|
|
3646
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
|
+
};
|
|
3647
3662
|
var astroGlobBase = (base) => isAbsolute(base) ? pathToFileURL(base).href : base;
|
|
3648
3663
|
var contentConfigTemplate = (options) => {
|
|
3649
3664
|
const { context, config } = options;
|
|
@@ -3651,8 +3666,8 @@ var contentConfigTemplate = (options) => {
|
|
|
3651
3666
|
const collectionBase = options.collection?.base ?? context.contentRoot;
|
|
3652
3667
|
const includeGlobs = options.collection?.include ?? config.content.include;
|
|
3653
3668
|
const excludeGlobs = options.collection?.exclude ?? config.content.exclude;
|
|
3654
|
-
const outDirRel =
|
|
3655
|
-
const outDirIgnore = outDirRel
|
|
3669
|
+
const outDirRel = runtimeDirWithin(collectionBase, context.outDir);
|
|
3670
|
+
const outDirIgnore = outDirRel ? [`!${outDirRel}/**`] : [];
|
|
3656
3671
|
const filesystem = options.filesystem ?? true;
|
|
3657
3672
|
const docsPattern = filesystem ? [
|
|
3658
3673
|
...includeGlobs,
|
|
@@ -5125,6 +5140,10 @@ var crawlStaticDir = async (options) => {
|
|
|
5125
5140
|
};
|
|
5126
5141
|
|
|
5127
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
|
+
};
|
|
5128
5147
|
var resolveRedirects = (redirects, pageUrls) => {
|
|
5129
5148
|
const byFrom = new Map;
|
|
5130
5149
|
for (const redirect of redirects) {
|
|
@@ -5140,7 +5159,7 @@ var resolveRedirects = (redirects, pageUrls) => {
|
|
|
5140
5159
|
chain.push(current);
|
|
5141
5160
|
break;
|
|
5142
5161
|
}
|
|
5143
|
-
const next = normalizePath(current);
|
|
5162
|
+
const next = normalizePath(pathOnly(current));
|
|
5144
5163
|
if (seen.has(next)) {
|
|
5145
5164
|
chain.push(next);
|
|
5146
5165
|
return {
|
|
@@ -5222,8 +5241,9 @@ var matches = (id, terms) => {
|
|
|
5222
5241
|
var runAudit = async (options) => {
|
|
5223
5242
|
const { project } = options;
|
|
5224
5243
|
const staticDir = deployStaticDir(project.config, project.context);
|
|
5244
|
+
const basePath = normalizeBasePath(project.config.basePath);
|
|
5225
5245
|
const crawl = await crawlStaticDir({
|
|
5226
|
-
basePath
|
|
5246
|
+
basePath,
|
|
5227
5247
|
manifest: project.manifest,
|
|
5228
5248
|
staticDir
|
|
5229
5249
|
});
|
|
@@ -5240,7 +5260,11 @@ var runAudit = async (options) => {
|
|
|
5240
5260
|
origin,
|
|
5241
5261
|
pages: crawl.pages,
|
|
5242
5262
|
project,
|
|
5243
|
-
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)))),
|
|
5244
5268
|
robots: crawl.robots,
|
|
5245
5269
|
sitemap: crawl.sitemap,
|
|
5246
5270
|
sources: await readSources(crawl.pages),
|
|
@@ -8191,9 +8215,10 @@ var detectLocale = (parts, i18n) => {
|
|
|
8191
8215
|
var localePlacement = (rel, ext, i18n) => {
|
|
8192
8216
|
const base = rel.slice(0, rel.length - ext.length);
|
|
8193
8217
|
if (base.endsWith(".$")) {
|
|
8218
|
+
const shared = `${base.slice(0, -2)}${ext}`;
|
|
8194
8219
|
return {
|
|
8195
8220
|
locales: i18n.locales.map((locale2) => locale2.code),
|
|
8196
|
-
navPath:
|
|
8221
|
+
navPath: i18n.parser === "dir" ? detectLocale(shared.split("/"), i18n).rest.join("/") : shared
|
|
8197
8222
|
};
|
|
8198
8223
|
}
|
|
8199
8224
|
if (i18n.parser === "dot") {
|
|
@@ -8673,7 +8698,8 @@ var normalizeRef = (ref) => {
|
|
|
8673
8698
|
return "/";
|
|
8674
8699
|
}
|
|
8675
8700
|
const withSlash = ref.startsWith("/") ? ref : `/${ref}`;
|
|
8676
|
-
const
|
|
8701
|
+
const noTrailing = withSlash.replace(/\/+$/u, "");
|
|
8702
|
+
const trimmed = noTrailing.endsWith("/index") ? noTrailing.slice(0, -"/index".length) : noTrailing;
|
|
8677
8703
|
return trimmed === "" ? "/" : trimmed;
|
|
8678
8704
|
};
|
|
8679
8705
|
var routeForRef = (ref, byRoute, basePath) => {
|
|
@@ -8880,7 +8906,10 @@ var buildLocaleNavigation = (code, pages, fallback, fallbackByKey, options, i18n
|
|
|
8880
8906
|
basePath: options.basePath ?? "",
|
|
8881
8907
|
diagnostics,
|
|
8882
8908
|
display: options.navigation.sidebar.display,
|
|
8883
|
-
featured: options.navigation.featured
|
|
8909
|
+
featured: options.navigation.featured?.map((link) => ({
|
|
8910
|
+
...link,
|
|
8911
|
+
href: localizePath(link.href)
|
|
8912
|
+
})),
|
|
8884
8913
|
folderMeta: options.folderMeta,
|
|
8885
8914
|
localizedRoot: localizeRoute("/", code, i18n),
|
|
8886
8915
|
metaPrefix: i18n.parser === "dir" && code !== i18n.defaultLocale ? code : "",
|
|
@@ -9176,6 +9205,7 @@ var WORD_SPLIT2 = /[-_]/u;
|
|
|
9176
9205
|
var stripNumericPrefix = (segment) => segment.replace(NUMERIC_PREFIX2, "");
|
|
9177
9206
|
var groupLabel = (segment) => segment.match(GROUP_FOLDER2)?.groups?.label ?? null;
|
|
9178
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("/");
|
|
9179
9209
|
var titleCase = (value) => value.split(WORD_SPLIT2).filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
9180
9210
|
var addRouteSegment = (part, segments, groups) => {
|
|
9181
9211
|
if (part === "") {
|
|
@@ -9205,11 +9235,18 @@ var mapRoute = (relativePath) => {
|
|
|
9205
9235
|
};
|
|
9206
9236
|
var CODE_FENCE = /^(?<delimiter>```|~~~)/u;
|
|
9207
9237
|
var nextFenceState = (line, fence) => {
|
|
9208
|
-
const
|
|
9238
|
+
const trimmed = line.trimStart();
|
|
9239
|
+
const delimiter = trimmed.match(CODE_FENCE)?.groups?.delimiter;
|
|
9209
9240
|
if (delimiter === undefined) {
|
|
9210
9241
|
return fence;
|
|
9211
9242
|
}
|
|
9212
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
|
+
}
|
|
9213
9250
|
return delimiter;
|
|
9214
9251
|
}
|
|
9215
9252
|
return fence === delimiter ? null : fence;
|
|
@@ -9227,6 +9264,9 @@ var linesWithoutFrontMatter = (body) => {
|
|
|
9227
9264
|
if (!/^-{3}\s*$/u.test(lines[0] ?? "")) {
|
|
9228
9265
|
return lines;
|
|
9229
9266
|
}
|
|
9267
|
+
if ((lines[1] ?? "").trim() === "") {
|
|
9268
|
+
return lines;
|
|
9269
|
+
}
|
|
9230
9270
|
const close = lines.findIndex((line, index) => index > 0 && FRONT_MATTER_CLOSE.test(line));
|
|
9231
9271
|
return close === -1 ? lines : lines.slice(close + 1);
|
|
9232
9272
|
};
|
|
@@ -9306,8 +9346,10 @@ var extractHeadings = (body) => {
|
|
|
9306
9346
|
}
|
|
9307
9347
|
return headings;
|
|
9308
9348
|
};
|
|
9309
|
-
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;
|
|
9310
9351
|
var INLINE_CODE = /`[^`]*`/gu;
|
|
9352
|
+
var targetOffsetIn = (matched, target, title) => matched.length - 1 - (title?.length ?? 0) - target.length;
|
|
9311
9353
|
var scanLinkLine = (line, lineNumber, fence, links) => {
|
|
9312
9354
|
const next = nextFenceState(line, fence);
|
|
9313
9355
|
if (fence !== null || next !== null) {
|
|
@@ -9319,12 +9361,24 @@ var scanLinkLine = (line, lineNumber, fence, links) => {
|
|
|
9319
9361
|
if (target === undefined || match.index === undefined) {
|
|
9320
9362
|
continue;
|
|
9321
9363
|
}
|
|
9322
|
-
const targetOffset = match
|
|
9364
|
+
const targetOffset = targetOffsetIn(match[0], target, match.groups?.title);
|
|
9323
9365
|
links.push({
|
|
9324
|
-
column: targetOffset + 1,
|
|
9366
|
+
column: match.index + targetOffset + 1,
|
|
9325
9367
|
line: lineNumber,
|
|
9326
9368
|
target
|
|
9327
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
|
+
}
|
|
9328
9382
|
}
|
|
9329
9383
|
return next;
|
|
9330
9384
|
};
|
|
@@ -9598,6 +9652,24 @@ var operationKey = (method, path, operationId) => {
|
|
|
9598
9652
|
return fromId || slugify3(`${method}-${path}`);
|
|
9599
9653
|
};
|
|
9600
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
|
+
};
|
|
9601
9673
|
var extractOperations = (document, baseRoute) => {
|
|
9602
9674
|
const operations = [];
|
|
9603
9675
|
const tagOrder = [];
|
|
@@ -9605,6 +9677,7 @@ var extractOperations = (document, baseRoute) => {
|
|
|
9605
9677
|
const tagMeta = new Map((document.tags ?? []).map((tag) => [tag.name, tag.description ?? ""]));
|
|
9606
9678
|
const seen = new Set;
|
|
9607
9679
|
const warnings = [];
|
|
9680
|
+
const slugForTag = tagSlugger();
|
|
9608
9681
|
for (const [path, rawItem] of Object.entries(document.paths ?? {})) {
|
|
9609
9682
|
const item = rawItem;
|
|
9610
9683
|
if (!item) {
|
|
@@ -9620,7 +9693,7 @@ var extractOperations = (document, baseRoute) => {
|
|
|
9620
9693
|
continue;
|
|
9621
9694
|
}
|
|
9622
9695
|
const tag = operation.tags?.[0] ?? UNTAGGED;
|
|
9623
|
-
const tagSlug =
|
|
9696
|
+
const tagSlug = slugForTag(tag);
|
|
9624
9697
|
if (!tagsSeen.has(tag)) {
|
|
9625
9698
|
tagsSeen.add(tag);
|
|
9626
9699
|
tagOrder.push(tag);
|
|
@@ -9647,7 +9720,7 @@ var extractOperations = (document, baseRoute) => {
|
|
|
9647
9720
|
const tags = tagOrder.map((name) => ({
|
|
9648
9721
|
description: tagMeta.get(name) ?? "",
|
|
9649
9722
|
name,
|
|
9650
|
-
slug:
|
|
9723
|
+
slug: slugForTag(name)
|
|
9651
9724
|
}));
|
|
9652
9725
|
return { operations, tags, warnings };
|
|
9653
9726
|
};
|
|
@@ -9797,15 +9870,14 @@ var parseSpec = async (spec, root, options = {}) => {
|
|
|
9797
9870
|
};
|
|
9798
9871
|
|
|
9799
9872
|
// src/openapi/render-mdx.ts
|
|
9800
|
-
var MDX_UNSAFE = /[
|
|
9873
|
+
var MDX_UNSAFE = /[<{}]/gu;
|
|
9801
9874
|
var ENTITIES = {
|
|
9802
9875
|
"<": "<",
|
|
9803
|
-
">": ">",
|
|
9804
9876
|
"{": "{",
|
|
9805
9877
|
"}": "}"
|
|
9806
9878
|
};
|
|
9807
9879
|
var MDX_ESM_KEYWORD = /^(?<keyword>import|export)\b/gmu;
|
|
9808
|
-
var BACKTICK_CODE = /(?<bt>`+)[\s\S]
|
|
9880
|
+
var BACKTICK_CODE = /(?<!`)(?<bt>`+)(?!`)[\s\S]*?(?<!`)\k<bt>(?!`)/gu;
|
|
9809
9881
|
var escapeProse = (text) => text.replace(MDX_UNSAFE, (char) => ENTITIES[char] ?? char).replace(MDX_ESM_KEYWORD, (keyword) => `&#${keyword.codePointAt(0)};${keyword.slice(1)}`);
|
|
9810
9882
|
var mdxSafe = (text) => {
|
|
9811
9883
|
let out = "";
|
|
@@ -10417,7 +10489,7 @@ import { join as join15 } from "pathe";
|
|
|
10417
10489
|
// src/core/sources/assets.ts
|
|
10418
10490
|
import { mkdir as mkdir5, writeFile as writeFile5 } from "node:fs/promises";
|
|
10419
10491
|
import { extname as extname4, join as join14 } from "pathe";
|
|
10420
|
-
var
|
|
10492
|
+
var MD_IMAGE2 = /!\[(?<alt>[^\]]*)\]\((?<url>[^)\s]+)\)/gu;
|
|
10421
10493
|
var REMOTE = /^https?:\/\//u;
|
|
10422
10494
|
var SAFE_EXT = /^\.[a-z0-9]+$/iu;
|
|
10423
10495
|
var CODE_FENCE_BLOCK = /^(?<fence>`{3,}|~{3,})[^\n]*\n[\s\S]*?^\k<fence>[^\n]*(?=\n|$)/gmu;
|
|
@@ -10436,7 +10508,7 @@ var materializeAssets = async (markdown, ctx) => {
|
|
|
10436
10508
|
return `\x00blume-fence-${fences.length - 1}\x00`;
|
|
10437
10509
|
});
|
|
10438
10510
|
const urls = new Set;
|
|
10439
|
-
for (const match of masked.matchAll(
|
|
10511
|
+
for (const match of masked.matchAll(MD_IMAGE2)) {
|
|
10440
10512
|
const url = match.groups?.url;
|
|
10441
10513
|
if (url && REMOTE.test(url)) {
|
|
10442
10514
|
urls.add(url);
|
|
@@ -10462,7 +10534,7 @@ var materializeAssets = async (markdown, ctx) => {
|
|
|
10462
10534
|
});
|
|
10463
10535
|
}
|
|
10464
10536
|
}));
|
|
10465
|
-
const rewritten = masked.replaceAll(
|
|
10537
|
+
const rewritten = masked.replaceAll(MD_IMAGE2, (match, alt, url) => {
|
|
10466
10538
|
const local = rewrites.get(url);
|
|
10467
10539
|
return local ? `` : match;
|
|
10468
10540
|
}).replaceAll(FENCE_TOKEN, (token, index) => fences[Number(index)] ?? token);
|
|
@@ -10697,7 +10769,7 @@ ${nested}`;
|
|
|
10697
10769
|
data.sidebar = { order };
|
|
10698
10770
|
}
|
|
10699
10771
|
const slugProp = richToMarkdown(page.properties[props.slug ?? "Slug"]?.rich_text);
|
|
10700
|
-
const slug =
|
|
10772
|
+
const slug = slugifyPath(slugProp || title) || page.id;
|
|
10701
10773
|
return { data, slug };
|
|
10702
10774
|
};
|
|
10703
10775
|
const toEntry2 = async (client, page) => {
|
|
@@ -10904,7 +10976,7 @@ var sanitySource = (options, ctx) => {
|
|
|
10904
10976
|
let snapshot = new Map;
|
|
10905
10977
|
const toEntry2 = (doc) => {
|
|
10906
10978
|
const slugValue = asString(getPath(doc, fields.slug ?? "slug.current")) ?? asString(doc._id) ?? "untitled";
|
|
10907
|
-
const slug =
|
|
10979
|
+
const slug = slugifyPath(slugValue) || slugify2(asString(doc._id) ?? "") || "untitled";
|
|
10908
10980
|
const data = {};
|
|
10909
10981
|
const title = asString(getPath(doc, fields.title ?? "title"));
|
|
10910
10982
|
const description = asString(getPath(doc, fields.description ?? "description"));
|
|
@@ -11264,6 +11336,16 @@ var shouldFail = (result, gate) => {
|
|
|
11264
11336
|
const failing = failingSeverities(gate);
|
|
11265
11337
|
return result.diagnostics.some((d) => failing.has(d.severity));
|
|
11266
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
|
+
};
|
|
11267
11349
|
var auditCommand = defineCommand2({
|
|
11268
11350
|
args: {
|
|
11269
11351
|
claude: {
|
|
@@ -11369,12 +11451,7 @@ var auditCommand = defineCommand2({
|
|
|
11369
11451
|
process.stderr.write(` Handing ${count} finding${count === 1 ? "" : "s"} to ${cli.name}…
|
|
11370
11452
|
|
|
11371
11453
|
`);
|
|
11372
|
-
|
|
11373
|
-
try {
|
|
11374
|
-
code = await launchAgent(cli.bin, fixPrompt(report));
|
|
11375
|
-
} catch {
|
|
11376
|
-
code = WINDOWS_COMMAND_NOT_FOUND;
|
|
11377
|
-
}
|
|
11454
|
+
const code = await launchAgentCode(cli.bin, fixPrompt(report));
|
|
11378
11455
|
if (code === WINDOWS_COMMAND_NOT_FOUND) {
|
|
11379
11456
|
logger.error(`${cli.name} (\`${cli.bin}\`) was not found on PATH. Install it with \`${cli.install}\`.`);
|
|
11380
11457
|
process.exit(1);
|
|
@@ -12577,6 +12654,7 @@ import {
|
|
|
12577
12654
|
lstat,
|
|
12578
12655
|
mkdir as mkdir6,
|
|
12579
12656
|
readFile as readFile14,
|
|
12657
|
+
readlink,
|
|
12580
12658
|
realpath,
|
|
12581
12659
|
rename,
|
|
12582
12660
|
rm as rm2,
|
|
@@ -12585,7 +12663,7 @@ import {
|
|
|
12585
12663
|
} from "node:fs/promises";
|
|
12586
12664
|
import { createRequire as createRequire5 } from "node:module";
|
|
12587
12665
|
import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
12588
|
-
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";
|
|
12589
12667
|
import { glob as glob7 } from "tinyglobby";
|
|
12590
12668
|
|
|
12591
12669
|
// src/ai/ask-data.ts
|
|
@@ -14485,12 +14563,12 @@ var canResolveFrom = (fromDir, spec) => {
|
|
|
14485
14563
|
return false;
|
|
14486
14564
|
}
|
|
14487
14565
|
};
|
|
14488
|
-
var resolveReactCompiler = (config, needsReact) => {
|
|
14566
|
+
var resolveReactCompiler = (config, needsReact, pkgDir = packageRoot()) => {
|
|
14489
14567
|
if (!(needsReact && config.react.compiler)) {
|
|
14490
14568
|
return null;
|
|
14491
14569
|
}
|
|
14492
14570
|
try {
|
|
14493
|
-
return createRequire5(pathToFileURL3(join26(
|
|
14571
|
+
return createRequire5(pathToFileURL3(join26(pkgDir, "_.js")).href).resolve("babel-plugin-react-compiler");
|
|
14494
14572
|
} catch {
|
|
14495
14573
|
return null;
|
|
14496
14574
|
}
|
|
@@ -14543,6 +14621,11 @@ var linkDepsJunction = async (link, depsDir) => {
|
|
|
14543
14621
|
if (!existing.isSymbolicLink()) {
|
|
14544
14622
|
return;
|
|
14545
14623
|
}
|
|
14624
|
+
try {
|
|
14625
|
+
if (resolve7(dirname9(link), await readlink(link)) === resolve7(depsDir)) {
|
|
14626
|
+
return;
|
|
14627
|
+
}
|
|
14628
|
+
} catch {}
|
|
14546
14629
|
await rm2(link, { force: true });
|
|
14547
14630
|
}
|
|
14548
14631
|
await mkdir6(dirname9(link), { recursive: true });
|
|
@@ -14634,6 +14717,15 @@ var deploymentAdapterWarnings = (deployment, root) => {
|
|
|
14634
14717
|
}
|
|
14635
14718
|
return [];
|
|
14636
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
|
+
};
|
|
14637
14729
|
var examplesCssFile = (root, config) => config.examples.css ? join26(root, config.examples.css) : null;
|
|
14638
14730
|
var writeExamplesPreview = async (options) => {
|
|
14639
14731
|
const { config, hasExamples, root, srcDir, write } = options;
|
|
@@ -14896,6 +14988,7 @@ var buildRuntimeData = (project) => {
|
|
|
14896
14988
|
basePath: config.basePath,
|
|
14897
14989
|
codeThemes: config.markdown.codeBlocks.theme,
|
|
14898
14990
|
codeWrap: config.markdown.code.wrap,
|
|
14991
|
+
dateFormat: config.dateFormat,
|
|
14899
14992
|
description: config.description,
|
|
14900
14993
|
favicon: resolveFavicon(project),
|
|
14901
14994
|
feedback: config.feedback,
|
|
@@ -15038,6 +15131,7 @@ var writeNotFoundPage = async (write, srcDir, pages, contentPages) => {
|
|
|
15038
15131
|
}
|
|
15039
15132
|
await write(join26(srcDir, "pages", "404.astro"), notFoundPageTemplate());
|
|
15040
15133
|
};
|
|
15134
|
+
var diagnosticWarning = (diagnostic) => diagnostic.suggestion ? `${diagnostic.message} ${diagnostic.suggestion}` : diagnostic.message;
|
|
15041
15135
|
var buildComponentSlots = async (componentsFile) => {
|
|
15042
15136
|
const analysis = componentsFile ? analyzeComponentOverrides(await readFile14(componentsFile, "utf-8"), componentsFile) : null;
|
|
15043
15137
|
return {
|
|
@@ -15046,6 +15140,7 @@ var buildComponentSlots = async (componentsFile) => {
|
|
|
15046
15140
|
warnings: analysis ? analysis.warnings : []
|
|
15047
15141
|
};
|
|
15048
15142
|
};
|
|
15143
|
+
var contentWatchesRuntimeDir = (hasFilesystemSource, collectionBase, context) => hasFilesystemSource && runtimeDirWithin(collectionBase, context.outDir) !== null;
|
|
15049
15144
|
var generateRuntime = async (project) => {
|
|
15050
15145
|
const { context, config } = project;
|
|
15051
15146
|
const out = context.outDir;
|
|
@@ -15106,6 +15201,7 @@ var generateRuntime = async (project) => {
|
|
|
15106
15201
|
pages.push(...mcp.discoveryPages);
|
|
15107
15202
|
const hasStaged = staged.size > 0;
|
|
15108
15203
|
const hasFilesystemSource = project.sources.some((source) => !source.staged);
|
|
15204
|
+
const docsCollection = resolveDocsCollection(config, context);
|
|
15109
15205
|
const [structural] = await Promise.all([
|
|
15110
15206
|
Promise.all([
|
|
15111
15207
|
write(join26(out, "astro.config.mjs"), astroConfigTemplate({
|
|
@@ -15113,6 +15209,7 @@ var generateRuntime = async (project) => {
|
|
|
15113
15209
|
askPath,
|
|
15114
15210
|
config,
|
|
15115
15211
|
contentRoutes: project.manifest.routes.map((route) => route.path),
|
|
15212
|
+
contentWatchesRuntimeDir: contentWatchesRuntimeDir(hasFilesystemSource, docsCollection.base, context),
|
|
15116
15213
|
context,
|
|
15117
15214
|
dataPath,
|
|
15118
15215
|
examplesPath,
|
|
@@ -15130,7 +15227,7 @@ var generateRuntime = async (project) => {
|
|
|
15130
15227
|
write(join26(out, "tsconfig.json"), runtimeTsconfigTemplate()),
|
|
15131
15228
|
write(join26(srcDir, "env.d.ts"), envTemplate()),
|
|
15132
15229
|
write(join26(srcDir, "content.config.ts"), contentConfigTemplate({
|
|
15133
|
-
collection:
|
|
15230
|
+
collection: docsCollection,
|
|
15134
15231
|
config,
|
|
15135
15232
|
context,
|
|
15136
15233
|
filesystem: hasFilesystemSource,
|
|
@@ -15234,18 +15331,12 @@ var generateRuntime = async (project) => {
|
|
|
15234
15331
|
warnings.push(...[
|
|
15235
15332
|
...validateNavTargets(project.graph.navigation, navTargetRoutes),
|
|
15236
15333
|
...validateSearchPopularIcons(config.search.popular)
|
|
15237
|
-
].map(
|
|
15334
|
+
].map(diagnosticWarning));
|
|
15238
15335
|
const knownComponentTags = new Set([
|
|
15239
15336
|
...islandDiscovery.islands.map((island) => island.name),
|
|
15240
15337
|
...overrideTags
|
|
15241
15338
|
]);
|
|
15242
|
-
warnings.push(...validateUsedComponents(project.graph.pages, knownComponentTags, new Set(registry.map((item) => item.name))).map(
|
|
15243
|
-
for (const dep of searchProviderMeta(config.search.provider).runtimeDeps) {
|
|
15244
|
-
if (!(canResolveFrom(context.root, dep) || canResolveFrom(packageRoot(), dep))) {
|
|
15245
|
-
warnings.push(`Search provider "${config.search.provider}" needs "${dep}", which isn't installed. Run \`npm install ${dep}\` (or your package manager's equivalent).`);
|
|
15246
|
-
}
|
|
15247
|
-
}
|
|
15248
|
-
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));
|
|
15249
15340
|
if (hasScalarReferences(config)) {
|
|
15250
15341
|
const references = await buildReferenceFiles({
|
|
15251
15342
|
config,
|
|
@@ -15270,7 +15361,7 @@ var generateRuntime = async (project) => {
|
|
|
15270
15361
|
|
|
15271
15362
|
// src/cli/env.ts
|
|
15272
15363
|
import { existsSync as existsSync15, readFileSync as readFileSync10 } from "node:fs";
|
|
15273
|
-
import { dirname as dirname10, join as join27, resolve as
|
|
15364
|
+
import { dirname as dirname10, join as join27, resolve as resolve8 } from "pathe";
|
|
15274
15365
|
var ENV_LINE = /^\s*(?:export\s+)?(?<key>[A-Za-z_][A-Za-z0-9_]*)\s*=\s*(?<value>.*?)\s*$/u;
|
|
15275
15366
|
var DOUBLE_QUOTED2 = /^"(?<body>[\s\S]*)"$/u;
|
|
15276
15367
|
var SINGLE_QUOTED = /^'(?<body>[\s\S]*)'$/u;
|
|
@@ -15322,7 +15413,7 @@ var loadFile = (path) => {
|
|
|
15322
15413
|
} catch {}
|
|
15323
15414
|
};
|
|
15324
15415
|
var loadEnvFiles = (startDir) => {
|
|
15325
|
-
let dir =
|
|
15416
|
+
let dir = resolve8(startDir);
|
|
15326
15417
|
let done = false;
|
|
15327
15418
|
while (!done) {
|
|
15328
15419
|
loadFile(join27(dir, ".env.local"));
|
|
@@ -15764,6 +15855,7 @@ var checkCommand = defineCommand4({
|
|
|
15764
15855
|
import { watch } from "node:fs";
|
|
15765
15856
|
import { dev } from "astro";
|
|
15766
15857
|
import { defineCommand as defineCommand5 } from "citty";
|
|
15858
|
+
import { basename as basename4, dirname as dirname11 } from "pathe";
|
|
15767
15859
|
|
|
15768
15860
|
// src/astro/integration.ts
|
|
15769
15861
|
var overlayServer = null;
|
|
@@ -15942,17 +16034,26 @@ var devCommand = defineCommand5({
|
|
|
15942
16034
|
if (boundPort !== port) {
|
|
15943
16035
|
runRegenerate();
|
|
15944
16036
|
}
|
|
16037
|
+
const dirTargets = [project.context.pagesRoot].filter((target) => target !== null);
|
|
15945
16038
|
const fileTargets = [
|
|
15946
|
-
project.context.pagesRoot,
|
|
15947
16039
|
project.context.configFile,
|
|
15948
16040
|
project.context.themeFile,
|
|
15949
16041
|
project.context.componentsFile
|
|
15950
16042
|
].filter((target) => target !== null);
|
|
15951
16043
|
const disposers = [
|
|
15952
16044
|
...project.sources.map((source) => source.watch?.(regenerate)),
|
|
15953
|
-
...
|
|
16045
|
+
...dirTargets.map((target) => {
|
|
15954
16046
|
const watcher = watch(target, { recursive: true }, regenerate);
|
|
15955
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();
|
|
15956
16057
|
})
|
|
15957
16058
|
].filter((dispose) => dispose !== undefined);
|
|
15958
16059
|
const shutdown = async () => {
|
|
@@ -16473,7 +16574,7 @@ var updatePackageScripts = async (root) => {
|
|
|
16473
16574
|
// src/cli/init/scaffold.ts
|
|
16474
16575
|
import { existsSync as existsSync19 } from "node:fs";
|
|
16475
16576
|
import { mkdir as mkdir8, writeFile as writeFile11 } from "node:fs/promises";
|
|
16476
|
-
import { basename as
|
|
16577
|
+
import { basename as basename5, dirname as dirname12, isAbsolute as isAbsolute9, join as join33, relative as relative15 } from "pathe";
|
|
16477
16578
|
|
|
16478
16579
|
// src/core/package-json.ts
|
|
16479
16580
|
var toPackageName = (raw) => raw.toLowerCase().replaceAll(/[^a-z0-9._-]+/gu, "-").replaceAll(/^[-_.]+|[-_.]+$/gu, "") || "docs";
|
|
@@ -16683,7 +16784,7 @@ var extraDepsFor = (sources) => ({
|
|
|
16683
16784
|
var buildPlan = (root, answers) => {
|
|
16684
16785
|
const files = [
|
|
16685
16786
|
{
|
|
16686
|
-
content: blumePackageJson(toPackageName(
|
|
16787
|
+
content: blumePackageJson(toPackageName(basename5(root)), extraDepsFor(answers.sources)),
|
|
16687
16788
|
path: join33(root, "package.json")
|
|
16688
16789
|
},
|
|
16689
16790
|
{ content: buildConfig(answers), path: join33(root, "blume.config.ts") }
|
|
@@ -16698,14 +16799,14 @@ var writeFileSafe = async (file, log) => {
|
|
|
16698
16799
|
log.info(`Skipped existing ${file.path}`);
|
|
16699
16800
|
return false;
|
|
16700
16801
|
}
|
|
16701
|
-
await mkdir8(
|
|
16802
|
+
await mkdir8(dirname12(file.path), { recursive: true });
|
|
16702
16803
|
await writeFile11(file.path, file.content, "utf-8");
|
|
16703
16804
|
log.success(`Created ${file.path}`);
|
|
16704
16805
|
return true;
|
|
16705
16806
|
};
|
|
16706
16807
|
var applyPlan = async (files, log) => {
|
|
16707
16808
|
const created = await Promise.all(files.map((file) => writeFileSafe(file, log)));
|
|
16708
|
-
const createdPackage = files.some((file, index) => created[index] &&
|
|
16809
|
+
const createdPackage = files.some((file, index) => created[index] && basename5(file.path) === "package.json");
|
|
16709
16810
|
return { createdPackage };
|
|
16710
16811
|
};
|
|
16711
16812
|
var envVarsFor = (sources) => [
|
|
@@ -16792,10 +16893,10 @@ The blume package remains importable.`);
|
|
|
16792
16893
|
// src/cli/commands/init.ts
|
|
16793
16894
|
import * as clack from "@clack/prompts";
|
|
16794
16895
|
import { defineCommand as defineCommand8 } from "citty";
|
|
16795
|
-
import { resolve as
|
|
16896
|
+
import { resolve as resolve10 } from "pathe";
|
|
16796
16897
|
|
|
16797
16898
|
// src/cli/init/questions.ts
|
|
16798
|
-
import { basename as
|
|
16899
|
+
import { basename as basename6, resolve as resolve9 } from "pathe";
|
|
16799
16900
|
var cancelled = (value) => typeof value === "symbol";
|
|
16800
16901
|
var collectAnswers = async (prompter, flags, defaults) => {
|
|
16801
16902
|
const directory = flags.directory ?? await prompter.text({
|
|
@@ -16806,9 +16907,9 @@ var collectAnswers = async (prompter, flags, defaults) => {
|
|
|
16806
16907
|
if (cancelled(directory)) {
|
|
16807
16908
|
return null;
|
|
16808
16909
|
}
|
|
16809
|
-
const root =
|
|
16910
|
+
const root = resolve9(defaults.cwd, directory);
|
|
16810
16911
|
const title = await prompter.text({
|
|
16811
|
-
initialValue: titleize(
|
|
16912
|
+
initialValue: titleize(basename6(root)),
|
|
16812
16913
|
message: "What's your docs site called?",
|
|
16813
16914
|
validate: (value) => value?.trim() ? undefined : "Give your docs site a name."
|
|
16814
16915
|
});
|
|
@@ -16975,7 +17076,7 @@ var initCommand = defineCommand8({
|
|
|
16975
17076
|
title: "My Docs"
|
|
16976
17077
|
};
|
|
16977
17078
|
}
|
|
16978
|
-
const root =
|
|
17079
|
+
const root = resolve10(cwd, answers.directory);
|
|
16979
17080
|
if (validateContentDir(root, answers.contentDir) !== undefined) {
|
|
16980
17081
|
logger.error(`Invalid --content-dir "${answers.contentDir}" (must be a path inside the project).`);
|
|
16981
17082
|
process.exit(1);
|
|
@@ -17082,7 +17183,7 @@ import { join as join37 } from "pathe";
|
|
|
17082
17183
|
|
|
17083
17184
|
// src/core/links.ts
|
|
17084
17185
|
import { existsSync as existsSync21 } from "node:fs";
|
|
17085
|
-
import { basename as
|
|
17186
|
+
import { basename as basename7, join as join36 } from "pathe";
|
|
17086
17187
|
var HTTP = /^https?:\/\//iu;
|
|
17087
17188
|
var PROTOCOL_RELATIVE = /^\/\//u;
|
|
17088
17189
|
var SCHEME = /^[a-z][a-z0-9+.-]*:/iu;
|
|
@@ -17097,7 +17198,7 @@ var DOC_EXT = /\.(?:md|mdx)$/iu;
|
|
|
17097
17198
|
var FILE_EXT = /\.[a-z0-9]+$/iu;
|
|
17098
17199
|
var assetIsPresent = (resolved, ctx) => ctx.publicDir !== null && existsSync21(join36(ctx.publicDir, resolved));
|
|
17099
17200
|
var NUMERIC_PREFIX3 = /^\d+[-_.]/u;
|
|
17100
|
-
var isIndexPage = (page2) => /^index\.(?:md|mdx)$/iu.test(
|
|
17201
|
+
var isIndexPage = (page2) => /^index\.(?:md|mdx)$/iu.test(basename7(page2.navPath).replace(NUMERIC_PREFIX3, ""));
|
|
17101
17202
|
var applyRelativePart = (segments, part) => {
|
|
17102
17203
|
if (part === "" || part === ".") {
|
|
17103
17204
|
return;
|
|
@@ -17373,5 +17474,5 @@ process.on("unhandledRejection", (error) => {
|
|
|
17373
17474
|
});
|
|
17374
17475
|
runMain(main);
|
|
17375
17476
|
|
|
17376
|
-
//# debugId=
|
|
17477
|
+
//# debugId=5D342B2E16EE6E0464756E2164756E21
|
|
17377
17478
|
//# sourceMappingURL=index.js.map
|