@visulima/find-cache-dir
Version:
Finds the common standard cache directory
819 lines (801 loc) • 21.2 kB
JavaScript
import { createRequire as __cjs_createRequire } from "node:module";
const __cjs_require = __cjs_createRequire(import.meta.url);
const __cjs_getProcess = typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" ? globalThis.process : process;
const __cjs_getBuiltinModule = (module) => {
// Check if we're in Node.js and version supports getBuiltinModule
if (typeof __cjs_getProcess !== "undefined" && __cjs_getProcess.versions && __cjs_getProcess.versions.node) {
const [major, minor] = __cjs_getProcess.versions.node.split(".").map(Number);
// Node.js 20.16.0+ and 22.3.0+
if (major > 22 || (major === 22 && minor >= 3) || (major === 20 && minor >= 16)) {
return __cjs_getProcess.getBuiltinModule(module);
}
}
// Fallback to createRequire
return __cjs_require(module);
};
const {
existsSync
} = __cjs_getBuiltinModule("node:fs");
const {
env,
cwd: cwd$1
} = __cjs_getProcess;
const {
createRequire
} = __cjs_getBuiltinModule("node:module");
const F_OK = 0;
const W_OK = 2;
const FIND_UP_STOP = /* @__PURE__ */ Symbol("findUpStop");
const assertValidFileOrDirectoryPath = (fileOrDirectoryPath) => {
if (!fileOrDirectoryPath || !(fileOrDirectoryPath instanceof URL) && typeof fileOrDirectoryPath !== "string") {
throw new TypeError("Path must be a non-empty string or URL.");
}
};
const getFileInfoType = (fileInfo) => {
if (fileInfo.isFile()) {
return "file";
}
if (fileInfo.isDirectory()) {
return "dir";
}
if (fileInfo.isSymbolicLink()) {
return "symlink";
}
return void 0;
};
const __cjs_require$5 = createRequire(import.meta.url);
const __cjs_getProcess$5 = typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" ? globalThis.process : process;
const __cjs_getBuiltinModule$5 = (module) => {
if (typeof __cjs_getProcess$5 !== "undefined" && __cjs_getProcess$5.versions && __cjs_getProcess$5.versions.node) {
const [major, minor] = __cjs_getProcess$5.versions.node.split(".").map(Number);
if (major > 22 || major === 22 && minor >= 3 || major === 20 && minor >= 16) {
return __cjs_getProcess$5.getBuiltinModule(module);
}
}
return __cjs_require$5(module);
};
const {
lstatSync: lstatSync$1,
mkdirSync
} = __cjs_getBuiltinModule$5("node:fs");
const ensureDirSync = (directory) => {
assertValidFileOrDirectoryPath(directory);
try {
const fileInfo = lstatSync$1(directory);
if (!fileInfo.isDirectory()) {
throw new Error(`Ensure path exists, expected 'dir', got '${getFileInfoType(fileInfo)}'`);
}
return;
} catch (error) {
if (error.code !== "ENOENT") {
throw error;
}
}
try {
mkdirSync(directory, { recursive: true });
} catch (error) {
if (error.code !== "EEXIST") {
throw error;
}
const fileInfo = lstatSync$1(directory);
if (!fileInfo.isDirectory()) {
throw new Error(`Ensure path exists, expected 'dir', got '${getFileInfoType(fileInfo)}'`);
}
}
};
const DRIVE_LETTER_START_RE = /^[A-Z]:\//i;
const normalizeWindowsPath = (input = "") => {
if (!input) {
return input;
}
return input.replaceAll("\\", "/").replace(DRIVE_LETTER_START_RE, (r) => r.toUpperCase());
};
const UNC_REGEX = /^[/\\]{2}/;
const IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Z]:[/\\]/i;
const DRIVE_LETTER_RE = /^[A-Z]:$/i;
const EXTNAME_RE = /.(\.[^./]+)$/;
const PATH_ROOT_RE = /^[/\\]|^[a-z]:[/\\]/i;
const cwd = () => {
if (typeof process.cwd === "function") {
return process.cwd().replaceAll("\\", "/");
}
return "/";
};
const normalizeString = (path2, allowAboveRoot) => {
let result = "";
let lastSegmentLength = 0;
let lastSlash = -1;
let dots = 0;
let char;
for (let index = 0; index <= path2.length; ++index) {
if (index < path2.length) {
char = path2[index];
} else if (char === "/") {
break;
} else {
char = "/";
}
if (char === "/") {
if (lastSlash === index - 1 || dots === 1) ;
else if (dots === 2) {
if (result.length < 2 || lastSegmentLength !== 2 || !result.endsWith(".") || result.at(-2) !== ".") {
if (result.length > 2) {
const lastSlashIndex = result.lastIndexOf("/");
if (lastSlashIndex === -1) {
result = "";
lastSegmentLength = 0;
} else {
result = result.slice(0, lastSlashIndex);
lastSegmentLength = result.length - 1 - result.lastIndexOf("/");
}
lastSlash = index;
dots = 0;
continue;
} else if (result.length > 0) {
result = "";
lastSegmentLength = 0;
lastSlash = index;
dots = 0;
continue;
}
}
if (allowAboveRoot) {
result += result.length > 0 ? "/.." : "..";
lastSegmentLength = 2;
}
} else {
if (result.length > 0) {
result += `/${path2.slice(lastSlash + 1, index)}`;
} else {
result = path2.slice(lastSlash + 1, index);
}
lastSegmentLength = index - lastSlash - 1;
}
lastSlash = index;
dots = 0;
} else if (char === "." && dots !== -1) {
++dots;
} else {
dots = -1;
}
}
return result;
};
const isAbsolute = (path2) => IS_ABSOLUTE_RE.test(path2);
const normalize = function(path2) {
if (path2.length === 0) {
return ".";
}
path2 = normalizeWindowsPath(path2);
const isUNCPath = UNC_REGEX.exec(path2);
const isPathAbsolute = isAbsolute(path2);
const trailingSeparator = path2.at(-1) === "/";
path2 = normalizeString(path2, !isPathAbsolute);
if (path2.length === 0) {
if (isPathAbsolute) {
return "/";
}
return trailingSeparator ? "./" : ".";
}
if (trailingSeparator) {
path2 += "/";
}
if (DRIVE_LETTER_RE.test(path2)) {
path2 += "/";
}
if (isUNCPath) {
if (!isPathAbsolute) {
return `//./${path2}`;
}
return `//${path2}`;
}
return isPathAbsolute && !isAbsolute(path2) ? `/${path2}` : path2;
};
const join = (...segments) => {
let path2 = "";
for (const seg of segments) {
if (!seg) {
continue;
}
if (path2.length > 0) {
const pathTrailing = path2[path2.length - 1] === "/";
const segLeading = seg[0] === "/";
const both = pathTrailing && segLeading;
if (both) {
path2 += seg.slice(1);
} else {
path2 += pathTrailing || segLeading ? seg : `/${seg}`;
}
} else {
path2 += seg;
}
}
return normalize(path2);
};
const resolve = function(...arguments_) {
arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument));
let resolvedPath = "";
let resolvedAbsolute = false;
for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) {
const path2 = index >= 0 ? arguments_[index] : cwd();
if (!path2 || path2.length === 0) {
continue;
}
resolvedPath = `${path2}/${resolvedPath}`;
resolvedAbsolute = isAbsolute(path2);
}
resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute);
if (resolvedAbsolute && !isAbsolute(resolvedPath)) {
return `/${resolvedPath}`;
}
return resolvedPath.length > 0 ? resolvedPath : ".";
};
const extname = function(p) {
const match = EXTNAME_RE.exec(normalizeWindowsPath(p));
return match?.[1] ?? "";
};
const dirname = (path2) => {
const segments = normalizeWindowsPath(path2).replace(/\/$/, "").split("/").slice(0, -1);
if (segments.length === 1 && DRIVE_LETTER_RE.test(segments[0])) {
segments[0] += "/";
}
return segments.join("/") || (isAbsolute(path2) ? "/" : ".");
};
const basename = (path2, extension) => {
const lastSegment = normalizeWindowsPath(path2).split("/").pop();
if (extension && lastSegment.endsWith(extension)) {
return lastSegment.slice(0, -extension.length);
}
return lastSegment;
};
const parse = function(p) {
const root = PATH_ROOT_RE.exec(p)?.[0]?.replaceAll("\\", "/") ?? "";
const base = basename(p);
const extension = extname(base);
return {
base,
dir: dirname(p),
ext: extension,
name: base.slice(0, base.length - extension.length),
root
};
};
const __cjs_require$4 = createRequire(import.meta.url);
const __cjs_getProcess$4 = typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" ? globalThis.process : process;
const __cjs_getBuiltinModule$4 = (module) => {
if (typeof __cjs_getProcess$4 !== "undefined" && __cjs_getProcess$4.versions && __cjs_getProcess$4.versions.node) {
const [major, minor] = __cjs_getProcess$4.versions.node.split(".").map(Number);
if (major > 22 || major === 22 && minor >= 3 || major === 20 && minor >= 16) {
return __cjs_getProcess$4.getBuiltinModule(module);
}
}
return __cjs_require$4(module);
};
const {
fileURLToPath: fileURLToPath$2
} = __cjs_getBuiltinModule$4("node:url");
function getDefaultExportFromCjs(x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
}
var binaryExtensions$1;
var hasRequiredBinaryExtensions;
function requireBinaryExtensions() {
if (hasRequiredBinaryExtensions) return binaryExtensions$1;
hasRequiredBinaryExtensions = 1;
binaryExtensions$1 = [
"3dm",
"3ds",
"3g2",
"3gp",
"7z",
"a",
"aac",
"adp",
"afdesign",
"afphoto",
"afpub",
"ai",
"aif",
"aiff",
"alz",
"ape",
"apk",
"appimage",
"ar",
"arj",
"asf",
"au",
"avi",
"bak",
"baml",
"bh",
"bin",
"bk",
"bmp",
"btif",
"bz2",
"bzip2",
"cab",
"caf",
"cgm",
"class",
"cmx",
"cpio",
"cr2",
"cr3",
"cur",
"dat",
"dcm",
"deb",
"dex",
"djvu",
"dll",
"dmg",
"dng",
"doc",
"docm",
"docx",
"dot",
"dotm",
"dra",
"DS_Store",
"dsk",
"dts",
"dtshd",
"dvb",
"dwg",
"dxf",
"ecelp4800",
"ecelp7470",
"ecelp9600",
"egg",
"eol",
"eot",
"epub",
"exe",
"f4v",
"fbs",
"fh",
"fla",
"flac",
"flatpak",
"fli",
"flv",
"fpx",
"fst",
"fvt",
"g3",
"gh",
"gif",
"graffle",
"gz",
"gzip",
"h261",
"h263",
"h264",
"icns",
"ico",
"ief",
"img",
"ipa",
"iso",
"jar",
"jpeg",
"jpg",
"jpgv",
"jpm",
"jxr",
"key",
"ktx",
"lha",
"lib",
"lvp",
"lz",
"lzh",
"lzma",
"lzo",
"m3u",
"m4a",
"m4v",
"mar",
"mdi",
"mht",
"mid",
"midi",
"mj2",
"mka",
"mkv",
"mmr",
"mng",
"mobi",
"mov",
"movie",
"mp3",
"mp4",
"mp4a",
"mpeg",
"mpg",
"mpga",
"mxu",
"nef",
"npx",
"numbers",
"nupkg",
"o",
"odp",
"ods",
"odt",
"oga",
"ogg",
"ogv",
"otf",
"ott",
"pages",
"pbm",
"pcx",
"pdb",
"pdf",
"pea",
"pgm",
"pic",
"png",
"pnm",
"pot",
"potm",
"potx",
"ppa",
"ppam",
"ppm",
"pps",
"ppsm",
"ppsx",
"ppt",
"pptm",
"pptx",
"psd",
"pya",
"pyc",
"pyo",
"pyv",
"qt",
"rar",
"ras",
"raw",
"resources",
"rgb",
"rip",
"rlc",
"rmf",
"rmvb",
"rpm",
"rtf",
"rz",
"s3m",
"s7z",
"scpt",
"sgi",
"shar",
"snap",
"sil",
"sketch",
"slk",
"smv",
"snk",
"so",
"stl",
"suo",
"sub",
"swf",
"tar",
"tbz",
"tbz2",
"tga",
"tgz",
"thmx",
"tif",
"tiff",
"tlz",
"ttc",
"ttf",
"txz",
"udf",
"uvh",
"uvi",
"uvm",
"uvp",
"uvs",
"uvu",
"viv",
"vob",
"war",
"wav",
"wax",
"wbmp",
"wdp",
"weba",
"webm",
"webp",
"whl",
"wim",
"wm",
"wma",
"wmv",
"wmx",
"woff",
"woff2",
"wrm",
"wvx",
"xbm",
"xif",
"xla",
"xlam",
"xls",
"xlsb",
"xlsm",
"xlsx",
"xlt",
"xltm",
"xltx",
"xm",
"xmind",
"xpi",
"xpm",
"xwd",
"xz",
"z",
"zip",
"zipx"
];
return binaryExtensions$1;
}
var binaryExtensionsExports = /* @__PURE__ */ requireBinaryExtensions();
const binaryExtensions = /* @__PURE__ */ getDefaultExportFromCjs(binaryExtensionsExports);
new Set(binaryExtensions);
const toPath = (urlOrPath) => normalizeWindowsPath(urlOrPath instanceof URL ? fileURLToPath$2(urlOrPath) : urlOrPath);
const __cjs_require$3 = createRequire(import.meta.url);
const __cjs_getProcess$3 = typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" ? globalThis.process : process;
const __cjs_getBuiltinModule$3 = (module) => {
if (typeof __cjs_getProcess$3 !== "undefined" && __cjs_getProcess$3.versions && __cjs_getProcess$3.versions.node) {
const [major, minor] = __cjs_getProcess$3.versions.node.split(".").map(Number);
if (major > 22 || major === 22 && minor >= 3 || major === 20 && minor >= 16) {
return __cjs_getProcess$3.getBuiltinModule(module);
}
}
return __cjs_require$3(module);
};
const {
stat,
lstat
} = __cjs_getBuiltinModule$3("node:fs/promises");
const {
fileURLToPath: fileURLToPath$1
} = __cjs_getBuiltinModule$3("node:url");
const findUp = async (name, options = {}) => {
const cwd = options.cwd ? toPath(options.cwd) : process.cwd();
let directory = resolve(cwd);
const { root } = parse(directory);
const stopPath = toPath(options.stopAt ?? root);
const stopAt = resolve(directory, stopPath);
const type = options.type ?? "file";
const getMatchers = async function(currentDirectory) {
{
return [name];
}
};
if (options.allowSymlinks === void 0) {
options.allowSymlinks = true;
}
const statFunction = options.allowSymlinks ? stat : lstat;
while (directory && directory !== stopAt && directory !== root) {
for await (let fileName of await getMatchers()) {
if (fileName === FIND_UP_STOP) {
return void 0;
}
if (fileName === void 0) {
continue;
}
if (Buffer.isBuffer(fileName)) {
fileName = fileName.toString();
} else if (fileName instanceof URL) {
fileName = fileURLToPath$1(fileName);
}
const filePath = isAbsolute(fileName) ? fileName : resolve(directory, fileName);
try {
const stats = await statFunction(filePath);
if (type === "file" && stats.isFile() || type === "directory" && stats.isDirectory()) {
return filePath;
}
} catch {
}
}
directory = dirname(directory);
}
return void 0;
};
const __cjs_require$2 = createRequire(import.meta.url);
const __cjs_getProcess$2 = typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" ? globalThis.process : process;
const __cjs_getBuiltinModule$2 = (module) => {
if (typeof __cjs_getProcess$2 !== "undefined" && __cjs_getProcess$2.versions && __cjs_getProcess$2.versions.node) {
const [major, minor] = __cjs_getProcess$2.versions.node.split(".").map(Number);
if (major > 22 || major === 22 && minor >= 3 || major === 20 && minor >= 16) {
return __cjs_getProcess$2.getBuiltinModule(module);
}
}
return __cjs_require$2(module);
};
const {
statSync,
lstatSync
} = __cjs_getBuiltinModule$2("node:fs");
const {
fileURLToPath
} = __cjs_getBuiltinModule$2("node:url");
const findUpSync = (name, options = {}) => {
const cwd = options.cwd ? toPath(options.cwd) : process.cwd();
let directory = resolve(cwd);
const { root } = parse(directory);
const stopPath = toPath(options.stopAt ?? root);
const stopAt = resolve(directory, stopPath);
const type = options.type ?? "file";
const getMatchers = function(currentDirectory) {
{
return [name];
}
};
if (options.allowSymlinks === void 0) {
options.allowSymlinks = true;
}
const statFunction = options.allowSymlinks ? statSync : lstatSync;
while (directory && directory !== stopAt && directory !== root) {
for (let fileName of getMatchers()) {
if (fileName === FIND_UP_STOP) {
return void 0;
}
if (fileName === void 0) {
continue;
}
if (Buffer.isBuffer(fileName)) {
fileName = fileName.toString();
} else if (fileName instanceof URL) {
fileName = fileURLToPath(fileName);
}
const filePath = isAbsolute(fileName) ? fileName : resolve(directory, fileName);
try {
const stats = statFunction(filePath);
if (type === "file" && stats.isFile() || type === "directory" && stats.isDirectory()) {
return filePath;
}
} catch {
}
}
directory = dirname(directory);
}
return void 0;
};
const __cjs_require$1 = createRequire(import.meta.url);
const __cjs_getProcess$1 = typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" ? globalThis.process : process;
const __cjs_getBuiltinModule$1 = (module) => {
if (typeof __cjs_getProcess$1 !== "undefined" && __cjs_getProcess$1.versions && __cjs_getProcess$1.versions.node) {
const [major, minor] = __cjs_getProcess$1.versions.node.split(".").map(Number);
if (major > 22 || major === 22 && minor >= 3 || major === 20 && minor >= 16) {
return __cjs_getProcess$1.getBuiltinModule(module);
}
}
return __cjs_require$1(module);
};
const {
access
} = __cjs_getBuiltinModule$1("node:fs/promises");
async function isAccessible(path, mode = F_OK) {
assertValidFileOrDirectoryPath(path);
path = toPath(path);
try {
await access(path, mode);
return true;
} catch {
return false;
}
}
const {
accessSync
} = __cjs_getBuiltinModule("node:fs");
function isAccessibleSync(path, mode = F_OK) {
assertValidFileOrDirectoryPath(path);
path = toPath(path);
try {
accessSync(path, mode);
return true;
} catch {
return false;
}
}
class NotFoundError extends Error {
/**
* Creates a new instance.
* @param message
*/
constructor(message) {
super(`ENOENT: ${message}`);
}
// eslint-disable-next-line class-methods-use-this
get code() {
return "ENOENT";
}
// eslint-disable-next-line class-methods-use-this,@typescript-eslint/explicit-module-boundary-types
set code(_name) {
throw new Error("Cannot overwrite code ENOENT");
}
// eslint-disable-next-line class-methods-use-this
get name() {
return "NotFoundError";
}
// eslint-disable-next-line class-methods-use-this,@typescript-eslint/explicit-module-boundary-types
set name(_name) {
throw new Error("Cannot overwrite name of NotFoundError");
}
}
const useDirectory = (directory, options) => {
if (options?.create) {
ensureDirSync(directory);
}
return directory;
};
const findCacheDirectory = async (name, options) => {
if (env.CACHE_DIR && !["0", "1", "false", "true"].includes(env.CACHE_DIR)) {
return useDirectory(join(env.CACHE_DIR, name), options);
}
const rootDirectory = await findUp("package.json", {
cwd: options?.cwd ?? cwd$1(),
type: "file"
});
if (!rootDirectory) {
if (options?.throwError) {
throw new NotFoundError("No such file or directory found.");
}
return void 0;
}
const nodeModulesDirectory = join(dirname(rootDirectory), "node_modules");
const cacheDirectory = join(nodeModulesDirectory, ".cache");
const cacheNameDirectory = join(cacheDirectory, name);
if (existsSync(cacheNameDirectory) && !await isAccessible(cacheNameDirectory, W_OK)) {
return void 0;
}
if (existsSync(cacheDirectory) && !await isAccessible(cacheDirectory, W_OK)) {
return void 0;
}
if (existsSync(nodeModulesDirectory) && !await isAccessible(nodeModulesDirectory, W_OK)) {
return void 0;
}
return useDirectory(cacheNameDirectory, options);
};
const findCacheDirectorySync = (name, options) => {
if (env.CACHE_DIR && !["0", "1", "false", "true"].includes(env.CACHE_DIR)) {
return useDirectory(join(env.CACHE_DIR, name), options);
}
const rootDirectory = findUpSync("package.json", {
cwd: options?.cwd ?? cwd$1(),
type: "file"
});
if (!rootDirectory) {
if (options?.throwError) {
throw new NotFoundError("No such file or directory found.");
}
return void 0;
}
const nodeModulesDirectory = join(dirname(rootDirectory), "node_modules");
const cacheDirectory = join(nodeModulesDirectory, ".cache");
const cacheNameDirectory = join(cacheDirectory, name);
if (existsSync(cacheNameDirectory) && !isAccessibleSync(cacheNameDirectory, W_OK)) {
return void 0;
}
if (existsSync(cacheDirectory) && !isAccessibleSync(cacheDirectory, W_OK)) {
return void 0;
}
if (existsSync(nodeModulesDirectory) && !isAccessibleSync(nodeModulesDirectory, W_OK)) {
return void 0;
}
return useDirectory(cacheNameDirectory, options);
};
const findCacheDir = findCacheDirectory;
const findCacheDirSync = findCacheDirectorySync;
export { findCacheDir, findCacheDirSync };