87 lines
2.8 KiB
JavaScript
87 lines
2.8 KiB
JavaScript
import fs from "fs";
|
|
import path from "path";
|
|
import { AppData } from "../data/app-data";
|
|
function extensionToFormat(extension) {
|
|
switch (extension) {
|
|
case ".ts":
|
|
return "ts";
|
|
case ".js":
|
|
return "js";
|
|
case ".json":
|
|
return "json";
|
|
case ".yaml":
|
|
case ".yml":
|
|
return "yaml";
|
|
}
|
|
}
|
|
/**
|
|
* Resolve a basename (no extension) to an existing file among supported formats.
|
|
* Priority: .ts > .js > .json > .yaml > .yml
|
|
* Errors if multiple matches exist.
|
|
*/
|
|
export function resolveDataFile(dir, baseName) {
|
|
const matches = [];
|
|
for (const extension of AppData.SupportedDataFileExtensions) {
|
|
const filePath = path.join(dir, `${baseName}${extension}`);
|
|
if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) {
|
|
matches.push({
|
|
path: filePath,
|
|
basename: `${baseName}${extension}`,
|
|
extension,
|
|
format: extensionToFormat(extension),
|
|
});
|
|
}
|
|
}
|
|
if (matches.length === 0) {
|
|
return null;
|
|
}
|
|
if (matches.length > 1) {
|
|
const found = matches.map((m) => m.basename).join(", ");
|
|
throw new Error(`Multiple \`${baseName}\` files found (${found}). Keep only one of: ${AppData.SupportedDataFileExtensions.join(", ")}`);
|
|
}
|
|
return matches[0];
|
|
}
|
|
export function supportedDataFileNames(baseName) {
|
|
return AppData.SupportedDataFileExtensions.map((ext) => `\`${baseName}${ext}\``).join(", ");
|
|
}
|
|
export function isSchemaFileName(name) {
|
|
const base = path.basename(name);
|
|
if (base === AppData.DbSchemaFileName) {
|
|
return true;
|
|
}
|
|
return AppData.SupportedDataFileExtensions.some((ext) => base === `${AppData.DbSchemaFileName}${ext}`);
|
|
}
|
|
/**
|
|
* Load a data file as a plain object.
|
|
* - .ts / .js: require() and use default export (or module itself)
|
|
* - .json: JSON.parse
|
|
* - .yaml / .yml: Bun.YAML.parse
|
|
*/
|
|
export function loadDataFile(resolved) {
|
|
if (resolved.format === "ts" || resolved.format === "js") {
|
|
const imported = require(resolved.path);
|
|
const data = imported && typeof imported === "object" && "default" in imported
|
|
? imported.default
|
|
: imported;
|
|
if (data == null) {
|
|
throw new Error(`No default export from \`${resolved.path}\`. Please export a default module.`);
|
|
}
|
|
return data;
|
|
}
|
|
const text = fs.readFileSync(resolved.path, "utf-8");
|
|
if (resolved.format === "json") {
|
|
return JSON.parse(text);
|
|
}
|
|
return Bun.YAML.parse(text);
|
|
}
|
|
export function resolveAndLoadDataFile(dir, baseName) {
|
|
const resolved = resolveDataFile(dir, baseName);
|
|
if (!resolved) {
|
|
return null;
|
|
}
|
|
return {
|
|
...resolved,
|
|
data: loadDataFile(resolved),
|
|
};
|
|
}
|