INIT
This commit is contained in:
commit
14555c6e37
5 files changed
+744
No files matched your search
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Scans ./img recursively and writes ./images.json — the manifest the
|
||||
* single-page app fetches at runtime. No backend required.
|
||||
*
|
||||
* Usage:
|
||||
* node scripts/generate-manifest.mjs
|
||||
*
|
||||
* Re-run this whenever you add, rename, or remove images.
|
||||
*/
|
||||
import { readdir, stat, writeFile } from "node:fs/promises";
|
||||
import { join, relative, sep, extname } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const ROOT = fileURLToPath(new URL("..", import.meta.url));
|
||||
const IMG_DIR = join(ROOT, "img");
|
||||
const OUT_FILE = join(ROOT, "images.json");
|
||||
|
||||
const IMAGE_EXTS = new Set([
|
||||
".png", ".jpg", ".jpeg", ".gif", ".webp", ".avif",
|
||||
".svg", ".bmp", ".ico", ".tif", ".tiff",
|
||||
]);
|
||||
|
||||
const collator = new Intl.Collator(undefined, { numeric: true, sensitivity: "base" });
|
||||
|
||||
async function walk(dir) {
|
||||
const entries = await readdir(dir, { withFileTypes: true });
|
||||
const files = [];
|
||||
|
||||
for (const entry of entries) {
|
||||
if (entry.name.startsWith(".")) continue; // skip dotfiles/dirs
|
||||
const full = join(dir, entry.name);
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
files.push(...(await walk(full)));
|
||||
} else if (entry.isFile() && IMAGE_EXTS.has(extname(entry.name).toLowerCase())) {
|
||||
const info = await stat(full);
|
||||
files.push({
|
||||
name: entry.name,
|
||||
path: relative(ROOT, full).split(sep).join("/"), // POSIX-style for URLs
|
||||
size: info.size,
|
||||
mtime: info.mtime.toISOString(),
|
||||
});
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
let files;
|
||||
try {
|
||||
files = await walk(IMG_DIR);
|
||||
} catch (err) {
|
||||
if (err.code === "ENOENT") {
|
||||
console.error(`✗ Image folder not found: ${IMG_DIR}`);
|
||||
console.error(" Create it and add some images, then re-run.");
|
||||
process.exit(1);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
files.sort((a, b) => collator.compare(a.path, b.path));
|
||||
|
||||
const manifest = {
|
||||
generatedAt: new Date().toISOString(),
|
||||
count: files.length,
|
||||
images: files,
|
||||
};
|
||||
|
||||
await writeFile(OUT_FILE, JSON.stringify(manifest, null, 2) + "\n", "utf8");
|
||||
console.log(`✓ Wrote ${files.length} image${files.length === 1 ? "" : "s"} to images.json`);
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in new issue
Block a user