Files
test-repo/scripts/build/utilities.js
T

62 lines
1.7 KiB
JavaScript

import fs from "node:fs";
import path from "node:path";
import url from "node:url";
import { resolve } from "import-meta-resolve";
import { isUrl, toUrl } from "url-or-path";
import { PROJECT_ROOT } from "../utilities/index.js";
const NODE_MODULES_PATH = path.join(PROJECT_ROOT, "node_modules");
/**
Get a package file.
@param {string} file - package file to get
- a package name like `"prettier"`
- a package name with path like `"prettier/index.js"`
@param {string} [base] -- Where the package should be solved from
- a package name like `"prettier"`
- a file URL like `"file://path/to/prettier"`
- an absolute path like `"/path/to/prettier"`
@returns {string}
*/
function getPackageFile(file, base) {
const packageName = file
.split("/")
.slice(0, file.startsWith("@") ? 2 : 1)
.join("/");
base ??= path.join(NODE_MODULES_PATH, packageName);
if (!path.isAbsolute(base) && !isUrl(base)) {
base = getPackageFile(base);
}
const packageEntry = url.fileURLToPath(resolve(packageName, toUrl(base)));
const dirname = `/node_modules/${packageName}/`.replaceAll("/", path.sep);
const index = packageEntry
.slice(PROJECT_ROOT.length - 1)
.lastIndexOf(dirname);
if (!packageEntry.startsWith(NODE_MODULES_PATH) || index === -1) {
throw new Error(`Unexpected '${packageName}' entry '${packageEntry}'.`);
}
let resolved;
if (packageName === file) {
resolved = packageEntry;
} else {
const packageDirectory = packageEntry.slice(
0,
PROJECT_ROOT.length + dirname.length + index - 1,
);
resolved = path.join(packageDirectory, file.slice(packageName.length));
}
if (!fs.existsSync(resolved)) {
throw new Error(`'${file}' not exist.`);
}
return resolved;
}
export { getPackageFile };