feat(scan-sprite): walk dir, normalise aliases, detect collisions
This commit is contained in:
48
src/scan-sprite.js
Normal file
48
src/scan-sprite.js
Normal file
@@ -0,0 +1,48 @@
|
||||
// src/scan-sprite.js
|
||||
// Scans a source dir for PNG/WebP/JPG sprite files (no _diffuse/_height
|
||||
// suffix convention — sprite-mode treats each file as a standalone
|
||||
// sprite). Normalises filenames to snake_case aliases, detects
|
||||
// collisions.
|
||||
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const { aliasFromFilename } = require('./alias');
|
||||
|
||||
const SUPPORTED_EXT = ['.png', '.webp', '.jpg', '.jpeg'];
|
||||
|
||||
function scanSpriteSourceDir(srcDir, opts = {}) {
|
||||
if (!fs.existsSync(srcDir)) {
|
||||
return { sources: [], errors: [`scan-sprite: source dir does not exist: ${srcDir}`] };
|
||||
}
|
||||
const entries = fs.readdirSync(srcDir, { withFileTypes: true });
|
||||
const candidates = [];
|
||||
for (const e of entries) {
|
||||
if (!e.isFile()) continue;
|
||||
const ext = path.extname(e.name).toLowerCase();
|
||||
if (!SUPPORTED_EXT.includes(ext)) continue;
|
||||
candidates.push(e.name);
|
||||
}
|
||||
candidates.sort();
|
||||
|
||||
const aliasToFile = new Map();
|
||||
const sources = [];
|
||||
for (const filename of candidates) {
|
||||
const alias = aliasFromFilename(filename, opts);
|
||||
if (aliasToFile.has(alias)) {
|
||||
const prev = aliasToFile.get(alias);
|
||||
return {
|
||||
sources: [],
|
||||
errors: [`scan-sprite: alias collision "${alias}" — both "${prev}" and "${filename}" map to the same alias`],
|
||||
};
|
||||
}
|
||||
aliasToFile.set(alias, filename);
|
||||
sources.push({
|
||||
alias,
|
||||
sourceFile: filename,
|
||||
sourcePath: path.join(srcDir, filename),
|
||||
});
|
||||
}
|
||||
return { sources, errors: [] };
|
||||
}
|
||||
|
||||
module.exports = { scanSpriteSourceDir };
|
||||
Reference in New Issue
Block a user