@nuasite/cli 0.51.0 → 0.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -68,6 +68,10 @@ nua check --json # machine-readable report
68
68
  nua check --strict # warnings fail too
69
69
  ```
70
70
 
71
+ Run it anywhere in the project: with no `astro.config.*` in the current directory
72
+ it checks every `packages/*` that has one, so a monorepo root works too — which is
73
+ where `bun run build` typically builds something else entirely.
74
+
71
75
  It reads `src/content.config.ts`, walks every collection's entries and reports
72
76
  frontmatter that does not parse, values that do not match a declared field type
73
77
  (`order: ""` where the schema wants a number), missing required fields, and
@@ -79,6 +83,16 @@ and stops at the first bad entry, while this reports every problem in one pass
79
83
  under a second on a 1500-entry site. A dangling reference is a warning, because
80
84
  it builds green and then renders nothing.
81
85
 
86
+ `check` is new in 0.51.0. Most projects do not depend on `@nuasite/cli` directly
87
+ — it arrives through `@nuasite/nua`, which pins it exactly — so a project on an
88
+ older `@nuasite/nua` has an older `nua` and answers `Unknown command: check`
89
+ until it bumps. To run it regardless of what the project pins, and from a plain
90
+ shell where `node_modules/.bin` is not on `PATH`:
91
+
92
+ ```bash
93
+ bunx @nuasite/cli@latest check
94
+ ```
95
+
82
96
  ### `nua clean`
83
97
 
84
98
  Ejects your project from the Nua toolchain back to a standard Astro setup:
package/dist/index.js CHANGED
@@ -23829,37 +23829,67 @@ var init_src2 = __esm(() => {
23829
23829
  // src/check.ts
23830
23830
  var exports_check = {};
23831
23831
  __export(exports_check, {
23832
- check: () => check
23832
+ check: () => check,
23833
+ astroRoots: () => astroRoots
23833
23834
  });
23835
+ import { existsSync, readdirSync } from "fs";
23836
+ import path4 from "path";
23837
+ function astroRoots(cwd) {
23838
+ if (hasAstroConfig(cwd))
23839
+ return ["."];
23840
+ const packagesDir = path4.join(cwd, "packages");
23841
+ if (!existsSync(packagesDir))
23842
+ return [];
23843
+ return readdirSync(packagesDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort().filter((name) => hasAstroConfig(path4.join(packagesDir, name))).map((name) => path4.join("packages", name));
23844
+ }
23845
+ function prefixed(report, root) {
23846
+ if (root === ".")
23847
+ return report;
23848
+ return {
23849
+ ...report,
23850
+ findings: report.findings.map((finding) => ({ ...finding, file: path4.join(root, finding.file) }))
23851
+ };
23852
+ }
23834
23853
  async function check(options) {
23835
- const report = await checkContent(createNodeFs(options.cwd));
23854
+ const roots = astroRoots(options.cwd);
23855
+ if (roots.length === 0) {
23856
+ console.error(`No astro.config.* found in ${options.cwd} or its packages/*. Run this in an Astro project.`);
23857
+ return 1;
23858
+ }
23859
+ const reports = await Promise.all(roots.map(async (root) => prefixed(await checkContent(createNodeFs(path4.join(options.cwd, root))), root)));
23860
+ const report = {
23861
+ findings: reports.flatMap((one) => one.findings),
23862
+ collections: reports.reduce((total, one) => total + one.collections, 0),
23863
+ entries: reports.reduce((total, one) => total + one.entries, 0)
23864
+ };
23865
+ const errors = report.findings.filter((finding) => finding.severity === "error").length;
23866
+ const warnings = report.findings.length - errors;
23836
23867
  if (options.json) {
23837
- console.log(JSON.stringify(report, null, 2));
23868
+ console.log(JSON.stringify({ ...report, roots }, null, 2));
23838
23869
  } else {
23839
23870
  const formatted = formatCheckReport(report);
23840
23871
  if (formatted)
23841
23872
  console.log(formatted + `
23842
23873
  `);
23843
- }
23844
- const errors = report.findings.filter((finding) => finding.severity === "error").length;
23845
- const warnings = report.findings.length - errors;
23846
- if (!options.json) {
23847
- const counts = `${report.collections} collection(s), ${report.entries} entries`;
23874
+ const where = roots.length === 1 && roots[0] === "." ? "" : ` in ${roots.join(", ")}`;
23875
+ const counts = `${report.collections} collection(s), ${report.entries} entries${where}`;
23848
23876
  console.log(errors === 0 && warnings === 0 ? `${counts} \u2014 no problems found` : `${counts} \u2014 ${errors} error(s), ${warnings} warning(s)`);
23849
23877
  }
23850
23878
  return errors > 0 || options.strict && warnings > 0 ? 1 : 0;
23851
23879
  }
23880
+ var ASTRO_CONFIG_NAMES, hasAstroConfig = (dir) => ASTRO_CONFIG_NAMES.some((name) => existsSync(path4.join(dir, name)));
23852
23881
  var init_check2 = __esm(() => {
23853
23882
  init_src2();
23883
+ ASTRO_CONFIG_NAMES = ["astro.config.ts", "astro.config.mts", "astro.config.mjs", "astro.config.js"];
23854
23884
  });
23855
23885
 
23856
23886
  // src/utils.ts
23857
- import { existsSync } from "fs";
23887
+ import { existsSync as existsSync2 } from "fs";
23858
23888
  import { join } from "path";
23859
23889
  function findAstroConfig(cwd = process.cwd()) {
23860
23890
  for (const name of CONFIG_NAMES) {
23861
23891
  const p = join(cwd, name);
23862
- if (existsSync(p))
23892
+ if (existsSync2(p))
23863
23893
  return p;
23864
23894
  }
23865
23895
  return null;
@@ -23976,7 +24006,7 @@ __export(exports_init, {
23976
24006
  detectNuaManagedImports: () => detectNuaManagedImports,
23977
24007
  cleanEmptyStructures: () => cleanEmptyStructures
23978
24008
  });
23979
- import { existsSync as existsSync2, readFileSync, writeFileSync } from "fs";
24009
+ import { existsSync as existsSync3, readFileSync, writeFileSync } from "fs";
23980
24010
  import { basename, join as join2 } from "path";
23981
24011
  function detectNuaManagedImports(content) {
23982
24012
  const managed = new Map;
@@ -24120,7 +24150,7 @@ async function init({ cwd = process.cwd(), dryRun = false, yes = false } = {}) {
24120
24150
  process.exit(1);
24121
24151
  }
24122
24152
  const pkgPath = join2(cwd, "package.json");
24123
- if (!existsSync2(pkgPath)) {
24153
+ if (!existsSync3(pkgPath)) {
24124
24154
  console.error("No package.json found.");
24125
24155
  process.exit(1);
24126
24156
  }
@@ -24198,7 +24228,7 @@ __export(exports_clean, {
24198
24228
  detectDisabledFeatures: () => detectDisabledFeatures,
24199
24229
  clean: () => clean
24200
24230
  });
24201
- import { existsSync as existsSync3, readdirSync, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
24231
+ import { existsSync as existsSync4, readdirSync as readdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
24202
24232
  import { basename as basename2, join as join3 } from "path";
24203
24233
  function detectDisabledFeatures(content) {
24204
24234
  const disabled = new Set;
@@ -24307,11 +24337,11 @@ function transformPackageJson2(pkg, disabled, usedRuntimePackages = []) {
24307
24337
  }
24308
24338
  function scanForNuasiteUsage(cwd) {
24309
24339
  const srcDir = join3(cwd, "src");
24310
- if (!existsSync3(srcDir))
24340
+ if (!existsSync4(srcDir))
24311
24341
  return [];
24312
24342
  const results = [];
24313
24343
  try {
24314
- const files = readdirSync(srcDir, { recursive: true });
24344
+ const files = readdirSync2(srcDir, { recursive: true });
24315
24345
  for (const entry of files) {
24316
24346
  const fileName = String(entry);
24317
24347
  if (!/\.(astro|ts|tsx|js|jsx)$/.test(fileName))
@@ -24342,7 +24372,7 @@ async function clean({ cwd = process.cwd(), dryRun = false, yes = false } = {})
24342
24372
  return;
24343
24373
  }
24344
24374
  const pkgPath = join3(cwd, "package.json");
24345
- if (!existsSync3(pkgPath)) {
24375
+ if (!existsSync4(pkgPath)) {
24346
24376
  console.error("No package.json found.");
24347
24377
  process.exit(1);
24348
24378
  }
@@ -24450,7 +24480,7 @@ var init_config = () => {};
24450
24480
 
24451
24481
  // ../cms/src/component-registry.ts
24452
24482
  import fs2 from "fs/promises";
24453
- import path4 from "path";
24483
+ import path5 from "path";
24454
24484
 
24455
24485
  class ComponentRegistry {
24456
24486
  components = new Map;
@@ -24460,7 +24490,7 @@ class ComponentRegistry {
24460
24490
  }
24461
24491
  async scan() {
24462
24492
  for (const dir of this.componentDirs) {
24463
- const fullPath = path4.join(getProjectRoot(), dir);
24493
+ const fullPath = path5.join(getProjectRoot(), dir);
24464
24494
  try {
24465
24495
  await this.scanDirectory(fullPath, dir);
24466
24496
  } catch {}
@@ -24475,8 +24505,8 @@ class ComponentRegistry {
24475
24505
  async scanDirectory(dir, relativePath) {
24476
24506
  const entries = await fs2.readdir(dir, { withFileTypes: true });
24477
24507
  for (const entry of entries) {
24478
- const fullPath = path4.join(dir, entry.name);
24479
- const relPath = path4.join(relativePath, entry.name);
24508
+ const fullPath = path5.join(dir, entry.name);
24509
+ const relPath = path5.join(relativePath, entry.name);
24480
24510
  if (entry.isDirectory()) {
24481
24511
  await this.scanDirectory(fullPath, relPath);
24482
24512
  } else if (entry.isFile() && entry.name.endsWith(".astro")) {
@@ -24487,7 +24517,7 @@ class ComponentRegistry {
24487
24517
  async parseComponent(filePath, relativePath) {
24488
24518
  try {
24489
24519
  const content = await fs2.readFile(filePath, "utf-8");
24490
- const componentName = path4.basename(filePath, ".astro");
24520
+ const componentName = path5.basename(filePath, ".astro");
24491
24521
  const props = await this.extractProps(content);
24492
24522
  const slots = this.extractSlots(content);
24493
24523
  const description = this.extractDescription(content);
@@ -24742,7 +24772,7 @@ function slugify2(text) {
24742
24772
 
24743
24773
  // ../cms/src/utils.ts
24744
24774
  import { createHash } from "crypto";
24745
- import path5 from "path";
24775
+ import path6 from "path";
24746
24776
  function normalizePagePath(url) {
24747
24777
  let pathname;
24748
24778
  try {
@@ -24795,21 +24825,21 @@ function escapeReplacement(str) {
24795
24825
  return str.replace(/\$/g, "$$$$");
24796
24826
  }
24797
24827
  function resolveSourcePath(sourcePath) {
24798
- return path5.isAbsolute(sourcePath) ? sourcePath : path5.join(getProjectRoot(), sourcePath);
24828
+ return path6.isAbsolute(sourcePath) ? sourcePath : path6.join(getProjectRoot(), sourcePath);
24799
24829
  }
24800
24830
  function resolveAndValidatePath(filePath) {
24801
24831
  const projectRoot = getProjectRoot();
24802
- const resolvedRoot = path5.resolve(projectRoot);
24832
+ const resolvedRoot = path6.resolve(projectRoot);
24803
24833
  const isAbsoluteFs = filePath.startsWith(resolvedRoot);
24804
24834
  const normalizedPath = !isAbsoluteFs && filePath.startsWith("/") ? filePath.slice(1) : filePath;
24805
- const fullPath = path5.isAbsolute(normalizedPath) ? path5.resolve(normalizedPath) : path5.resolve(projectRoot, normalizedPath);
24806
- if (!fullPath.startsWith(resolvedRoot + path5.sep) && fullPath !== resolvedRoot) {
24835
+ const fullPath = path6.isAbsolute(normalizedPath) ? path6.resolve(normalizedPath) : path6.resolve(projectRoot, normalizedPath);
24836
+ if (!fullPath.startsWith(resolvedRoot + path6.sep) && fullPath !== resolvedRoot) {
24807
24837
  throw new Error(`Path traversal detected: ${filePath}`);
24808
24838
  }
24809
24839
  return fullPath;
24810
24840
  }
24811
24841
  async function acquireFileLock(filePath) {
24812
- const key = path5.resolve(filePath);
24842
+ const key = path6.resolve(filePath);
24813
24843
  while (fileLocks.has(key)) {
24814
24844
  await fileLocks.get(key);
24815
24845
  }
@@ -24827,8 +24857,8 @@ function escapeHtml2(text) {
24827
24857
  return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
24828
24858
  }
24829
24859
  function relativeImportPath2(fromFile, toFile) {
24830
- const fromDir = path5.dirname(fromFile);
24831
- let rel = path5.relative(fromDir, toFile).split(path5.sep).join("/");
24860
+ const fromDir = path6.dirname(fromFile);
24861
+ let rel = path6.relative(fromDir, toFile).split(path6.sep).join("/");
24832
24862
  if (!rel.startsWith("."))
24833
24863
  rel = `./${rel}`;
24834
24864
  return rel;
@@ -24841,7 +24871,7 @@ var init_utils2 = __esm(() => {
24841
24871
 
24842
24872
  // ../cms/src/handlers/component-ops.ts
24843
24873
  import fs3 from "fs/promises";
24844
- import path6 from "path";
24874
+ import path7 from "path";
24845
24875
  async function handleInsertComponent(request, manifestWriter) {
24846
24876
  const { position, referenceComponentId, componentName, props, meta } = request;
24847
24877
  if (!meta?.url) {
@@ -25059,7 +25089,7 @@ function getComponentOccurrenceIndex(manifest, referenceComponent) {
25059
25089
  async function findComponentInvocationFile(projectRoot, pageUrl, manifest, referenceComponent) {
25060
25090
  if (referenceComponent.invocationSourcePath) {
25061
25091
  const filePath = normalizeFilePath(referenceComponent.invocationSourcePath);
25062
- const fullPath = path6.resolve(projectRoot, filePath);
25092
+ const fullPath = path7.resolve(projectRoot, filePath);
25063
25093
  try {
25064
25094
  const content = await fs3.readFile(fullPath, "utf-8");
25065
25095
  const lines = content.split(`
@@ -25073,7 +25103,7 @@ async function findComponentInvocationFile(projectRoot, pageUrl, manifest, refer
25073
25103
  const candidates = getPageFileCandidates(pageUrl);
25074
25104
  const occurrenceIndex = getComponentOccurrenceIndex(manifest, referenceComponent);
25075
25105
  for (const candidate of candidates) {
25076
- const fullPath = path6.resolve(projectRoot, candidate);
25106
+ const fullPath = path7.resolve(projectRoot, candidate);
25077
25107
  try {
25078
25108
  const content = await fs3.readFile(fullPath, "utf-8");
25079
25109
  const lines = content.split(`
@@ -25133,7 +25163,7 @@ function getIndentation(line) {
25133
25163
  function normalizeFilePath(p) {
25134
25164
  if (!p.startsWith("/"))
25135
25165
  return p;
25136
- const projectRoot = path6.resolve(getProjectRoot());
25166
+ const projectRoot = path7.resolve(getProjectRoot());
25137
25167
  if (p.startsWith(projectRoot))
25138
25168
  return p;
25139
25169
  return p.slice(1);
@@ -25541,45 +25571,45 @@ var init_array_ops = __esm(() => {
25541
25571
  // ../cms/src/astro-image-paths.ts
25542
25572
  import { createHash as createHash2 } from "crypto";
25543
25573
  import fs5 from "fs/promises";
25544
- import path7 from "path";
25574
+ import path8 from "path";
25545
25575
  function isHugoStyleEntry(entryAbsPath) {
25546
- return HUGO_INDEX_RE.test(path7.basename(entryAbsPath));
25576
+ return HUGO_INDEX_RE.test(path8.basename(entryAbsPath));
25547
25577
  }
25548
25578
  function shortContentHash(buf) {
25549
25579
  return createHash2("sha256").update(buf).digest("hex").slice(0, 8);
25550
25580
  }
25551
25581
  async function pickAstroImageTarget(args) {
25552
- const entryDir = path7.dirname(args.entryAbsPath);
25582
+ const entryDir = path8.dirname(args.entryAbsPath);
25553
25583
  const isHugoStyle = isHugoStyleEntry(args.entryAbsPath);
25554
- const safeFilename = path7.basename(args.originalFilename);
25584
+ const safeFilename = path8.basename(args.originalFilename);
25555
25585
  if (!safeFilename || safeFilename === "." || safeFilename === "..") {
25556
25586
  throw new Error(`Invalid filename: ${args.originalFilename}`);
25557
25587
  }
25558
25588
  const baseName = isHugoStyle ? safeFilename : `${args.slug}-${safeFilename}`;
25559
- const baseAbs = path7.join(entryDir, baseName);
25589
+ const baseAbs = path8.join(entryDir, baseName);
25560
25590
  if (await isFreeOrMatching(baseAbs, args.compareBuffer)) {
25561
25591
  return { absPath: baseAbs, relPath: `./${baseName}` };
25562
25592
  }
25563
25593
  const candidateAbs = await pickHashedSibling(entryDir, baseName, args.compareBuffer);
25564
- return { absPath: candidateAbs, relPath: `./${path7.basename(candidateAbs)}` };
25594
+ return { absPath: candidateAbs, relPath: `./${path8.basename(candidateAbs)}` };
25565
25595
  }
25566
25596
  async function pickSiblingTarget(dir, filename, buf) {
25567
- const safe = path7.basename(filename);
25597
+ const safe = path8.basename(filename);
25568
25598
  if (!safe || safe === "." || safe === "..") {
25569
25599
  throw new Error(`Invalid filename: ${filename}`);
25570
25600
  }
25571
- const baseAbs = path7.join(dir, safe);
25601
+ const baseAbs = path8.join(dir, safe);
25572
25602
  if (await isFreeOrMatching(baseAbs, buf))
25573
25603
  return baseAbs;
25574
25604
  return pickHashedSibling(dir, safe, buf);
25575
25605
  }
25576
25606
  async function pickHashedSibling(dir, baseName, buf) {
25577
25607
  const hash = shortContentHash(buf);
25578
- const ext = path7.extname(baseName);
25579
- const stem = path7.basename(baseName, ext);
25608
+ const ext = path8.extname(baseName);
25609
+ const stem = path8.basename(baseName, ext);
25580
25610
  for (let attempt = 0;attempt < 5; attempt++) {
25581
25611
  const suffix = attempt === 0 ? hash : `${hash}-${attempt}`;
25582
- const candidateAbs = path7.join(dir, `${stem}-${suffix}${ext}`);
25612
+ const candidateAbs = path8.join(dir, `${stem}-${suffix}${ext}`);
25583
25613
  if (await isFreeOrMatching(candidateAbs, buf))
25584
25614
  return candidateAbs;
25585
25615
  }
@@ -25603,7 +25633,7 @@ var init_astro_image_paths = __esm(() => {
25603
25633
 
25604
25634
  // ../cms/src/handlers/astro-image-upload.ts
25605
25635
  import fs6 from "fs/promises";
25606
- import path8 from "path";
25636
+ import path9 from "path";
25607
25637
  async function tryAstroImageUpload(args) {
25608
25638
  const { collection, entry, field } = args.context;
25609
25639
  if (!collection || !entry || !field)
@@ -25625,12 +25655,12 @@ async function tryAstroImageUpload(args) {
25625
25655
  originalFilename: args.originalFilename,
25626
25656
  compareBuffer: args.fileBuffer
25627
25657
  });
25628
- await fs6.mkdir(path8.dirname(target.absPath), { recursive: true });
25658
+ await fs6.mkdir(path9.dirname(target.absPath), { recursive: true });
25629
25659
  await fs6.writeFile(target.absPath, args.fileBuffer);
25630
25660
  return {
25631
25661
  success: true,
25632
25662
  url: target.relPath,
25633
- filename: path8.basename(target.absPath)
25663
+ filename: path9.basename(target.absPath)
25634
25664
  };
25635
25665
  }
25636
25666
  var init_astro_image_upload = __esm(() => {
@@ -31481,7 +31511,7 @@ var init_snippet_utils = __esm(() => {
31481
31511
 
31482
31512
  // ../cms/src/handlers/source-writer.ts
31483
31513
  import fs8 from "fs/promises";
31484
- import path9 from "path";
31514
+ import path10 from "path";
31485
31515
  async function handleUpdate(request, manifestWriter) {
31486
31516
  const { changes, meta } = request;
31487
31517
  const errors = [];
@@ -31518,7 +31548,7 @@ async function handleUpdate(request, manifestWriter) {
31518
31548
  }
31519
31549
  if (appliedCount > 0 && newContent !== currentContent) {
31520
31550
  for (const op of fileOps) {
31521
- await fs8.mkdir(path9.dirname(op.target), { recursive: true });
31551
+ await fs8.mkdir(path10.dirname(op.target), { recursive: true });
31522
31552
  await fs8.writeFile(op.target, op.bytes);
31523
31553
  }
31524
31554
  await fs8.writeFile(fullPath, newContent, "utf-8");
@@ -31784,8 +31814,8 @@ async function tryRewriteAssetImport(content, importInfo, newSrc, absFilePath, o
31784
31814
  const resolved = await resolveNewSrcBytes(newSrc, originUrl);
31785
31815
  if (!resolved)
31786
31816
  return null;
31787
- const originalAssetAbs = path9.resolve(path9.dirname(absFilePath), importInfo.source);
31788
- const targetAbs = await pickSiblingTarget(path9.dirname(originalAssetAbs), resolved.filename, resolved.bytes);
31817
+ const originalAssetAbs = path10.resolve(path10.dirname(absFilePath), importInfo.source);
31818
+ const targetAbs = await pickSiblingTarget(path10.dirname(originalAssetAbs), resolved.filename, resolved.bytes);
31789
31819
  const newRelImport = relativeImportPath2(absFilePath, targetAbs);
31790
31820
  const newContent = content.slice(0, importInfo.sourceStart) + newRelImport + content.slice(importInfo.sourceEnd);
31791
31821
  return {
@@ -31795,8 +31825,8 @@ async function tryRewriteAssetImport(content, importInfo, newSrc, absFilePath, o
31795
31825
  };
31796
31826
  }
31797
31827
  async function resolveNewSrcBytes(newSrc, originUrl) {
31798
- const filenameFromPath = (p) => path9.basename(p.split("?")[0] ?? p);
31799
- const diskPath = newSrc.startsWith("/src/") ? path9.join(getProjectRoot(), newSrc.slice(1)) : newSrc.startsWith("/") && !newSrc.startsWith("//") ? path9.join(getProjectRoot(), "public", newSrc.replace(/^\/+/, "")) : null;
31828
+ const filenameFromPath = (p) => path10.basename(p.split("?")[0] ?? p);
31829
+ const diskPath = newSrc.startsWith("/src/") ? path10.join(getProjectRoot(), newSrc.slice(1)) : newSrc.startsWith("/") && !newSrc.startsWith("//") ? path10.join(getProjectRoot(), "public", newSrc.replace(/^\/+/, "")) : null;
31800
31830
  if (diskPath) {
31801
31831
  try {
31802
31832
  return { bytes: await fs8.readFile(diskPath), filename: filenameFromPath(newSrc) };
@@ -32344,7 +32374,7 @@ var init_source_writer = __esm(() => {
32344
32374
  });
32345
32375
 
32346
32376
  // ../cms/src/handlers/api-routes.ts
32347
- import path10 from "path";
32377
+ import path11 from "path";
32348
32378
  function requireMedia(ctx) {
32349
32379
  if (!ctx.mediaAdapter) {
32350
32380
  sendError(ctx.res, "Media storage not configured", 501);
@@ -32507,7 +32537,7 @@ var init_api_routes = __esm(() => {
32507
32537
  sendJson(res, { success: false, error: `Invalid content path: ${body.filePath}` }, 400);
32508
32538
  return;
32509
32539
  }
32510
- const fullPath = path10.resolve(getProjectRoot(), body.filePath.replace(/^\//, ""));
32540
+ const fullPath = path11.resolve(getProjectRoot(), body.filePath.replace(/^\//, ""));
32511
32541
  expectedDeletions.add(fullPath);
32512
32542
  const result = await core.deleteEntry(entry.collection, entry.slug);
32513
32543
  if (result.success) {
@@ -32614,7 +32644,7 @@ var init_api_routes = __esm(() => {
32614
32644
  const body = await parseJsonBody(req);
32615
32645
  const result = await core.deletePage(body);
32616
32646
  if (result.success && result.filePath) {
32617
- expectedDeletions.add(path10.resolve(getProjectRoot(), result.filePath));
32647
+ expectedDeletions.add(path11.resolve(getProjectRoot(), result.filePath));
32618
32648
  }
32619
32649
  if (result.success && body.createRedirect && body.redirectTo) {
32620
32650
  await core.addRedirect({ source: body.pagePath, destination: body.redirectTo, statusCode: 307 });
@@ -32719,7 +32749,7 @@ var init_color_patterns = __esm(() => {
32719
32749
 
32720
32750
  // ../cms/src/tailwind-colors.ts
32721
32751
  import fs9 from "fs/promises";
32722
- import path11 from "path";
32752
+ import path12 from "path";
32723
32753
  async function parseTailwindConfig(projectRoot = getProjectRoot()) {
32724
32754
  const cssFiles = [
32725
32755
  "src/styles/global.css",
@@ -32733,7 +32763,7 @@ async function parseTailwindConfig(projectRoot = getProjectRoot()) {
32733
32763
  ];
32734
32764
  let customColors = [];
32735
32765
  for (const cssFile of cssFiles) {
32736
- const fullPath = path11.join(projectRoot, cssFile);
32766
+ const fullPath = path12.join(projectRoot, cssFile);
32737
32767
  try {
32738
32768
  const content = await fs9.readFile(fullPath, "utf-8");
32739
32769
  customColors = extractColorsFromCss(content);
@@ -32806,7 +32836,7 @@ async function parseTextStyles(projectRoot = getProjectRoot()) {
32806
32836
  ];
32807
32837
  let customTextStyles = {};
32808
32838
  for (const cssFile of cssFiles) {
32809
- const fullPath = path11.join(projectRoot, cssFile);
32839
+ const fullPath = path12.join(projectRoot, cssFile);
32810
32840
  try {
32811
32841
  const content = await fs9.readFile(fullPath, "utf-8");
32812
32842
  customTextStyles = extractTextStylesFromCss(content);
@@ -33274,7 +33304,7 @@ var init_local_admin = __esm(() => {
33274
33304
 
33275
33305
  // ../cms/src/manifest-writer.ts
33276
33306
  import fs10 from "fs/promises";
33277
- import path12 from "path";
33307
+ import path13 from "path";
33278
33308
 
33279
33309
  class ManifestWriter {
33280
33310
  globalManifest;
@@ -33345,10 +33375,10 @@ class ManifestWriter {
33345
33375
  }
33346
33376
  getPageManifestPath(pagePath) {
33347
33377
  if (pagePath === "/" || pagePath === "") {
33348
- return path12.join(this.outDir, "index.json");
33378
+ return path13.join(this.outDir, "index.json");
33349
33379
  }
33350
33380
  const cleanPath = pagePath.replace(/^\//, "");
33351
- return path12.join(this.outDir, `${cleanPath}.json`);
33381
+ return path13.join(this.outDir, `${cleanPath}.json`);
33352
33382
  }
33353
33383
  addPage(pagePath, entries, components, collection, seo) {
33354
33384
  this.pageManifests.set(pagePath, { entries, components, collection, seo });
@@ -33374,7 +33404,7 @@ class ManifestWriter {
33374
33404
  }
33375
33405
  async writePageManifest(pagePath, entries, components, collection, seo) {
33376
33406
  const manifestPath = this.getPageManifestPath(pagePath);
33377
- const manifestDir = path12.dirname(manifestPath);
33407
+ const manifestDir = path13.dirname(manifestPath);
33378
33408
  await fs10.mkdir(manifestDir, { recursive: true });
33379
33409
  const metadata = {
33380
33410
  version: MANIFEST_VERSION,
@@ -33430,7 +33460,7 @@ class ManifestWriter {
33430
33460
  }
33431
33461
  }
33432
33462
  if (this.outDir) {
33433
- const globalManifestPath = path12.join(this.outDir, this.manifestFile);
33463
+ const globalManifestPath = path13.join(this.outDir, this.manifestFile);
33434
33464
  const globalSettings = {
33435
33465
  componentDefinitions: this.componentDefinitions,
33436
33466
  pages
@@ -34042,7 +34072,7 @@ var init_field_types = __esm(() => {
34042
34072
 
34043
34073
  // ../cms/src/migrate-astro-image.ts
34044
34074
  import fs11 from "fs/promises";
34045
- import path13 from "path";
34075
+ import path14 from "path";
34046
34076
  async function migrateAstroImages(options = {}) {
34047
34077
  const projectRoot = options.projectRoot ?? getProjectRoot();
34048
34078
  const dryRun = options.dryRun ?? false;
@@ -34054,7 +34084,7 @@ async function migrateAstroImages(options = {}) {
34054
34084
  if (astroFields.length === 0 || !def.entries)
34055
34085
  continue;
34056
34086
  for (const entry of def.entries) {
34057
- const entryAbs = path13.isAbsolute(entry.sourcePath) ? entry.sourcePath : path13.join(projectRoot, entry.sourcePath);
34087
+ const entryAbs = path14.isAbsolute(entry.sourcePath) ? entry.sourcePath : path14.join(projectRoot, entry.sourcePath);
34058
34088
  let raw;
34059
34089
  try {
34060
34090
  raw = await fs11.readFile(entryAbs, "utf-8");
@@ -34079,7 +34109,7 @@ async function migrateAstroImages(options = {}) {
34079
34109
  }
34080
34110
  if (!current.startsWith("/") || current.startsWith("//"))
34081
34111
  continue;
34082
- const sourceAbs = path13.join(projectRoot, "public", current.replace(/^\/+/, ""));
34112
+ const sourceAbs = path14.join(projectRoot, "public", current.replace(/^\/+/, ""));
34083
34113
  let sourceBuf;
34084
34114
  try {
34085
34115
  sourceBuf = await fs11.readFile(sourceAbs);
@@ -34090,11 +34120,11 @@ async function migrateAstroImages(options = {}) {
34090
34120
  const target = await pickAstroImageTarget({
34091
34121
  entryAbsPath: entryAbs,
34092
34122
  slug: entry.slug,
34093
- originalFilename: path13.basename(current),
34123
+ originalFilename: path14.basename(current),
34094
34124
  compareBuffer: sourceBuf
34095
34125
  });
34096
34126
  if (!dryRun) {
34097
- await fs11.mkdir(path13.dirname(target.absPath), { recursive: true });
34127
+ await fs11.mkdir(path14.dirname(target.absPath), { recursive: true });
34098
34128
  await fs11.writeFile(target.absPath, sourceBuf);
34099
34129
  }
34100
34130
  doc2.set(field.name, target.relPath);
@@ -34157,7 +34187,7 @@ var exports_migrate = {};
34157
34187
  __export(exports_migrate, {
34158
34188
  migrate: () => migrate
34159
34189
  });
34160
- import path14 from "path";
34190
+ import path15 from "path";
34161
34191
  async function migrate(args) {
34162
34192
  if (args.target !== "astro-image") {
34163
34193
  console.error(`Unknown migrate target: ${args.target}`);
@@ -34176,7 +34206,7 @@ async function migrate(args) {
34176
34206
  for (const m of result.migrations) {
34177
34207
  console.log(` ${m.entrySourcePath}`);
34178
34208
  console.log(` ${m.fieldName}: ${m.originalValue} \u2192 ${m.newValue}`);
34179
- console.log(` copy: ${path14.relative(process.cwd(), m.copiedFrom)} \u2192 ${path14.relative(process.cwd(), m.copiedTo)}`);
34209
+ console.log(` copy: ${path15.relative(process.cwd(), m.copiedFrom)} \u2192 ${path15.relative(process.cwd(), m.copiedTo)}`);
34180
34210
  }
34181
34211
  }
34182
34212
  if (result.skipped.length > 0) {
@@ -4,6 +4,15 @@ export interface CheckOptions {
4
4
  /** Treat warnings as failures too. Off by default: a dangling reference builds fine. */
5
5
  strict: boolean;
6
6
  }
7
+ /**
8
+ * The Astro apps to check, relative to `cwd`.
9
+ *
10
+ * Running this at a monorepo root has to work: that is where an agent's workspace and a
11
+ * developer's shell both start, and `bun run build` there builds something else entirely
12
+ * (admin, api, worker). Every `packages/*` app is checked, not just the first — a repo with
13
+ * two sites must not have one of them silently skipped.
14
+ */
15
+ export declare function astroRoots(cwd: string): string[];
7
16
  /** Validate the content collections and return the process exit code. */
8
17
  export declare function check(options: CheckOptions): Promise<number>;
9
18
  //# sourceMappingURL=check.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/check.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,OAAO,CAAA;IACb,wFAAwF;IACxF,MAAM,EAAE,OAAO,CAAA;CACf;AAED,yEAAyE;AACzE,wBAAsB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBlE"}
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/check.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,OAAO,CAAA;IACb,wFAAwF;IACxF,MAAM,EAAE,OAAO,CAAA;CACf;AAMD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAYhD;AAWD,yEAAyE;AACzE,wBAAsB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAgClE"}