2023-03-01 15:34:30 +08:00
|
|
|
import fs from "node:fs";
|
2023-12-17 19:34:12 +00:00
|
|
|
import path from "node:path";
|
2025-10-15 06:19:13 +08:00
|
|
|
import url from "node:url";
|
|
|
|
|
import { resolve } from "import-meta-resolve";
|
|
|
|
|
import { isUrl, toUrl } from "url-or-path";
|
2023-03-28 16:18:53 +08:00
|
|
|
import { PROJECT_ROOT } from "../utils/index.js";
|
2023-03-01 15:34:30 +08:00
|
|
|
|
2025-10-15 06:19:13 +08:00
|
|
|
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));
|
|
|
|
|
}
|
2023-03-01 15:34:30 +08:00
|
|
|
|
|
|
|
|
if (!fs.existsSync(resolved)) {
|
|
|
|
|
throw new Error(`'${file}' not exist.`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return resolved;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export { getPackageFile };
|