/
mkdirs.ts
76 lines (68 loc) · 2.07 KB
/
mkdirs.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import { resolve, dirname, normalize, sep } from 'path';
import { isWindows } from '../utils/util';
import { stat, mkdir } from '../fs';
/**
* @typedef {Object} MkdirsOptions
* @memberof fsn/nextra
* @property {number} [mode = 0o777 & ~process.umask()] The chmod for the directories being made
*/
interface MkdirsOptions {
mode?: number;
}
/**
* Recursively makes directories, until the directory passed exists.
* @function ensureDir
* @memberof fsn/nextra
* @param path The path you wish to make
* @param options Options for making the directories
*/
/**
* Recursively makes directories, until the directory passed exists.
* @function mkdirp
* @memberof fsn/nextra
* @param path The path you wish to make
* @param options Options for making the directories
*/
/**
* Recursively makes directories, until the directory passed exists.
* @function mkdirs
* @memberof fsn/nextra
* @param path The path you wish to make
* @param options Options for making the directories
*/
export default async function mkdirs(path: string, options?: MkdirsOptions | number): Promise<void> {
const dirOptions = resolveOptions(options);
// Windows
/* istanbul ignore next */
if (isWindows && invalidWin32Path(path)) {
const errInval = new Error(`FS-NEXTRA: ${path} contains invalid WIN32 path characters.`);
// @ts-ignore
errInval.code = 'EINVAL';
throw errInval;
}
path = resolve(path);
try {
await mkdir(path, dirOptions.mode);
} catch (err) {
if (err.code === 'ENOENT') {
await mkdirs(dirname(path), dirOptions);
await mkdirs(path, dirOptions);
return;
}
const myStat = await stat(path);
if (myStat.isDirectory()) return;
throw err;
}
}
const resolveOptions = (options: MkdirsOptions | number = {}): MkdirsOptions => {
return {
mode: typeof options === 'number' ? options : options.mode || 0o0777 & ~process.umask()
};
};
// Windows
/* istanbul ignore next */
const invalidWin32Path = (myPath: string): boolean => {
const root = normalize(resolve(myPath)).split(sep);
const rp = root.length > 0 ? root[0] : null;
return /[<>:"|?*]/.test(myPath.replace(rp, ''));
};