1 | const fs = require('fs')
|
2 | const makePromise = require('makepromise')
|
3 | const { dirname } = require('path')
|
4 |
|
5 | /**
|
6 | * Make sure that a file can be created by creating all directories to which it
|
7 | * belongs, e.g., ensurePath('/usr/local/test/wrote.data') will attempt to
|
8 | * create /usr/local/test/ directory recursivelly.
|
9 | * @param {string} path Path to the file
|
10 | * @returns {Promise.<string>} Same path as passed
|
11 | * @throws {Error} When the first folder in the path is non-executable
|
12 | */
|
13 | async function ensurePath(path) {
|
14 | const dir = dirname(path)
|
15 | try {
|
16 | await make(dir)
|
17 | return path
|
18 | } catch (err) {
|
19 | if (/EEXIST/.test(err.message) && err.message.indexOf(dir) != -1) {
|
20 | return path
|
21 | }
|
22 | throw err
|
23 | }
|
24 | }
|
25 |
|
26 | /**
|
27 | * Recursive promise-based mkdir.
|
28 | * @param {string} dir Path to the directory to be created
|
29 | */
|
30 | async function make(dir) {
|
31 | try {
|
32 | const res = await makeDir(dir)
|
33 | return res
|
34 | } catch (err) {
|
35 | if (/ENOENT/.test(err.message)) {
|
36 | const parentDir = dirname(dir)
|
37 | await make(parentDir)
|
38 | const res2 = await make(dir)
|
39 | return res2
|
40 | }
|
41 | throw err
|
42 | }
|
43 | }
|
44 |
|
45 | /**
|
46 | * Promisified fs.mkdir
|
47 | * @param {string} dir directory name
|
48 | * @returns {string} created directory name
|
49 | */
|
50 | async function makeDir(dir) {
|
51 | const res = await makePromise(fs.mkdir, dir, dir)
|
52 | return res
|
53 | }
|
54 |
|
55 | module.exports = ensurePath
|