@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 +14 -0
- package/dist/index.js +101 -71
- package/dist/types/check.d.ts +9 -0
- package/dist/types/check.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/check.ts +59 -9
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
|
|
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
|
-
|
|
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 (
|
|
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
|
|
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 (!
|
|
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
|
|
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 (!
|
|
24340
|
+
if (!existsSync4(srcDir))
|
|
24311
24341
|
return [];
|
|
24312
24342
|
const results = [];
|
|
24313
24343
|
try {
|
|
24314
|
-
const files =
|
|
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 (!
|
|
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
|
|
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 =
|
|
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 =
|
|
24479
|
-
const relPath =
|
|
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 =
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
24806
|
-
if (!fullPath.startsWith(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 =
|
|
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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
24828
24858
|
}
|
|
24829
24859
|
function relativeImportPath2(fromFile, toFile) {
|
|
24830
|
-
const fromDir =
|
|
24831
|
-
let rel =
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
25574
|
+
import path8 from "path";
|
|
25545
25575
|
function isHugoStyleEntry(entryAbsPath) {
|
|
25546
|
-
return HUGO_INDEX_RE.test(
|
|
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 =
|
|
25582
|
+
const entryDir = path8.dirname(args.entryAbsPath);
|
|
25553
25583
|
const isHugoStyle = isHugoStyleEntry(args.entryAbsPath);
|
|
25554
|
-
const safeFilename =
|
|
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 =
|
|
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: `./${
|
|
25594
|
+
return { absPath: candidateAbs, relPath: `./${path8.basename(candidateAbs)}` };
|
|
25565
25595
|
}
|
|
25566
25596
|
async function pickSiblingTarget(dir, filename, buf) {
|
|
25567
|
-
const safe =
|
|
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 =
|
|
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 =
|
|
25579
|
-
const stem =
|
|
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 =
|
|
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
|
|
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(
|
|
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:
|
|
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
|
|
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(
|
|
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 =
|
|
31788
|
-
const targetAbs = await pickSiblingTarget(
|
|
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) =>
|
|
31799
|
-
const diskPath = newSrc.startsWith("/src/") ?
|
|
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
|
|
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 =
|
|
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(
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
33378
|
+
return path13.join(this.outDir, "index.json");
|
|
33349
33379
|
}
|
|
33350
33380
|
const cleanPath = pagePath.replace(/^\//, "");
|
|
33351
|
-
return
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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:
|
|
34123
|
+
originalFilename: path14.basename(current),
|
|
34094
34124
|
compareBuffer: sourceBuf
|
|
34095
34125
|
});
|
|
34096
34126
|
if (!dryRun) {
|
|
34097
|
-
await fs11.mkdir(
|
|
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
|
|
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: ${
|
|
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) {
|
package/dist/types/check.d.ts
CHANGED
|
@@ -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":"
|
|
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"}
|