@intlayer/chokidar
Version:
Uses chokidar to scan and build Intlayer declaration files into dictionaries based on Intlayer configuration.
97 lines (95 loc) • 3.41 kB
JavaScript
import { basename, dirname, join, relative, resolve, sep } from "node:path";
import { existsSync, readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
//#region \0utils:asset
const hereDirname = () => {
try {
return dirname(fileURLToPath(import.meta.url));
} catch {
return typeof __dirname !== "undefined" ? __dirname : process.cwd();
}
};
const findDistRoot = (startDir) => {
let dir = startDir;
for (let i = 0; i < 12; i++) {
if (basename(dir) === "dist") return dir;
const parent = resolve(dir, "..");
if (parent === dir) break;
dir = parent;
}
return null;
};
const normalizeFrameFile = (file) => {
if (!file) return null;
try {
if (file.startsWith("file://")) return fileURLToPath(file);
} catch {}
return file;
};
/**
* Returns the directory of the *caller* module that invoked readAsset.
* Prefers non-virtual frames; falls back to the first real frame.
*/
const getCallerDir = () => {
const prev = Error.prepareStackTrace;
try {
Error.prepareStackTrace = (_, structured) => structured;
const err = /* @__PURE__ */ new Error();
Error.captureStackTrace(err, getCallerDir);
/** @type {import('node:vm').CallSite[]} */
const frames = err.stack || [];
const isVirtualPath = (p) => p.includes(`${sep}_virtual${sep}`) || p.includes("/_virtual/");
for (const frame of frames) {
const file = normalizeFrameFile(typeof frame.getFileName === "function" ? frame.getFileName() : null);
if (!file) continue;
if (file.includes("node:internal") || file.includes(`${sep}internal${sep}modules${sep}`)) continue;
if (!isVirtualPath(file)) return dirname(file);
}
for (const frame of frames) {
const file = normalizeFrameFile(typeof frame.getFileName === "function" ? frame.getFileName() : null);
if (file) return dirname(file);
}
} catch {} finally {
Error.prepareStackTrace = prev;
}
return hereDirname();
};
/**
* Read an asset copied from src/** to dist/assets/**.
* - './' or '../' is resolved relative to the *caller module's* emitted directory.
* - otherwise, treat as src-relative.
*
* @param {string} relPath - e.g. './PROMPT.md' or 'utils/AI/askDocQuestion/embeddings/<fileKey>.json'
* @param {BufferEncoding} [encoding='utf8']
*/
const readAsset = (relPath, encoding = "utf8") => {
const here = hereDirname();
const distRoot = findDistRoot(here) ?? resolve(here, "..", "..", "dist");
const assetsRoot = join(distRoot, "assets");
const tried = [];
/**
* Transform dist/(esm|cjs)/... and _virtual/ prefix to clean subpath (Windows-safe)
*/
const callerSubpath = relative(distRoot, getCallerDir()).split("\\").join("/").replace(/^(?:dist\/)?(?:esm|cjs)\//, "").replace(/^_virtual\//, "");
if (relPath.startsWith("./") || relPath.startsWith("../")) {
const fromCallerAbs = resolve(assetsRoot, callerSubpath, relPath);
tried.push(fromCallerAbs);
if (existsSync(fromCallerAbs)) return readFileSync(fromCallerAbs, encoding);
}
const directPath = join(assetsRoot, relPath);
tried.push(directPath);
if (existsSync(directPath)) return readFileSync(directPath, encoding);
if (callerSubpath) {
const nested = join(assetsRoot, callerSubpath, relPath);
tried.push(nested);
if (existsSync(nested)) return readFileSync(nested, encoding);
}
const msg = [
"readAsset: file not found.",
"Searched:",
...tried.map((p) => `- ${p}`)
].join("\n");
throw new Error(msg);
};
//#endregion
export { readAsset };