core/loaders/package.loader.ts
core/loaders/package.loader.ts is a file in GovLab Quality. 55 lines of code and 17 definitions.
import { readJsonField, safeReaddir } from "#core/loaders/source.loader";
import { forwardSlashed } from "#core/converters/filename.converter";
import fs from "node:fs";
import path from "node:path";
const PACKAGE_MANIFEST = "package.json";
const nameOfPackage = function nameOfPackage(dir: string): string {
const manifest = path.join(dir, PACKAGE_MANIFEST);
if (!fs.existsSync(manifest)) {
return "";
}
const name = readJsonField(manifest, "name");
return typeof name === "string" ? name : "";
};
const expandWorkspace = function expandWorkspace(rootAbs: string, pattern: string): string[] {
const star = pattern.indexOf("*");
if (star === -1) {
return [forwardSlashed(path.join(rootAbs, pattern))];
}
const cut = pattern.lastIndexOf("/", star);
const base = path.join(rootAbs, pattern.slice(0, cut));
const prefix = pattern.slice(cut + 1, star);
return safeReaddir(base)
.filter((entry) => entry.isDirectory() && entry.name.startsWith(prefix))
.map((entry) => forwardSlashed(path.join(base, entry.name)));
};
const workspacePatterns = function workspacePatterns(rootAbs: string): string[] {
const declared = readJsonField(path.join(rootAbs, PACKAGE_MANIFEST), "workspaces");
return Array.isArray(declared) ? declared.filter((value): value is string => typeof value === "string") : [];
};
export const workspaceDirs = function workspaceDirs(rootAbs: string): string[] {
return workspacePatterns(rootAbs)
.flatMap((pattern) => expandWorkspace(rootAbs, pattern))
.filter((dir) => fs.existsSync(path.join(dir, PACKAGE_MANIFEST)));
};
export const dependentWorkspaces = function dependentWorkspaces(rootAbs: string, packageDir: string): string[] {
const name = nameOfPackage(packageDir);
const own = forwardSlashed(path.resolve(packageDir));
return workspaceDirs(rootAbs).filter((dir) => {
if (name.length === 0 || forwardSlashed(path.resolve(dir)) === own) {
return false;
}
const dependencies = readJsonField(path.join(dir, PACKAGE_MANIFEST), "dependencies");
return typeof dependencies === "object" && dependencies !== null && name in dependencies;
});
};
export const packageNameIndex = function packageNameIndex(rootAbs: string): Map<string, string> {
const byName = new Map<string, string>();
for (const dir of workspaceDirs(rootAbs)) {
const name = nameOfPackage(dir);
if (name.length > 0) {
byName.set(name, dir);
}
}
return byName;
};