UNPKG

1.5 kBJavaScriptView Raw
1import process from 'node:process';
2import path from 'node:path';
3import fs from 'node:fs';
4import commonPathPrefix from 'common-path-prefix';
5import {packageDirectorySync} from 'pkg-dir';
6
7const {env, cwd} = process;
8
9const isWritable = path => {
10 try {
11 fs.accessSync(path, fs.constants.W_OK);
12 return true;
13 } catch {
14 return false;
15 }
16};
17
18function useDirectory(directory, options) {
19 if (options.create) {
20 fs.mkdirSync(directory, {recursive: true});
21 }
22
23 return directory;
24}
25
26function getNodeModuleDirectory(directory) {
27 const nodeModules = path.join(directory, 'node_modules');
28
29 if (
30 !isWritable(nodeModules)
31 && (fs.existsSync(nodeModules) || !isWritable(path.join(directory)))
32 ) {
33 return;
34 }
35
36 return nodeModules;
37}
38
39export default function findCacheDirectory(options = {}) {
40 if (env.CACHE_DIR && !['true', 'false', '1', '0'].includes(env.CACHE_DIR)) {
41 return useDirectory(path.join(env.CACHE_DIR, options.name), options);
42 }
43
44 let {cwd: directory = cwd(), files} = options;
45
46 if (files) {
47 if (!Array.isArray(files)) {
48 throw new TypeError(`Expected \`files\` option to be an array, got \`${typeof files}\`.`);
49 }
50
51 directory = commonPathPrefix(files.map(file => path.resolve(directory, file)));
52 }
53
54 directory = packageDirectorySync({cwd: directory});
55
56 if (!directory) {
57 return;
58 }
59
60 const nodeModules = getNodeModuleDirectory(directory);
61 if (!nodeModules) {
62 return;
63 }
64
65 return useDirectory(path.join(directory, 'node_modules', '.cache', options.name), options);
66}