source: trip-planner-front/node_modules/less/node_modules/make-dir/index.js@ fa375fe

Last change on this file since fa375fe was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 3.0 KB
Line 
1'use strict';
2const fs = require('fs');
3const path = require('path');
4const pify = require('pify');
5const semver = require('semver');
6
7const defaults = {
8 mode: 0o777 & (~process.umask()),
9 fs
10};
11
12const useNativeRecursiveOption = semver.satisfies(process.version, '>=10.12.0');
13
14// https://github.com/nodejs/node/issues/8987
15// https://github.com/libuv/libuv/pull/1088
16const checkPath = pth => {
17 if (process.platform === 'win32') {
18 const pathHasInvalidWinCharacters = /[<>:"|?*]/.test(pth.replace(path.parse(pth).root, ''));
19
20 if (pathHasInvalidWinCharacters) {
21 const error = new Error(`Path contains invalid characters: ${pth}`);
22 error.code = 'EINVAL';
23 throw error;
24 }
25 }
26};
27
28const permissionError = pth => {
29 // This replicates the exception of `fs.mkdir` with native the
30 // `recusive` option when run on an invalid drive under Windows.
31 const error = new Error(`operation not permitted, mkdir '${pth}'`);
32 error.code = 'EPERM';
33 error.errno = -4048;
34 error.path = pth;
35 error.syscall = 'mkdir';
36 return error;
37};
38
39const makeDir = (input, options) => Promise.resolve().then(() => {
40 checkPath(input);
41 options = Object.assign({}, defaults, options);
42
43 // TODO: Use util.promisify when targeting Node.js 8
44 const mkdir = pify(options.fs.mkdir);
45 const stat = pify(options.fs.stat);
46
47 if (useNativeRecursiveOption && options.fs.mkdir === fs.mkdir) {
48 const pth = path.resolve(input);
49
50 return mkdir(pth, {
51 mode: options.mode,
52 recursive: true
53 }).then(() => pth);
54 }
55
56 const make = pth => {
57 return mkdir(pth, options.mode)
58 .then(() => pth)
59 .catch(error => {
60 if (error.code === 'EPERM') {
61 throw error;
62 }
63
64 if (error.code === 'ENOENT') {
65 if (path.dirname(pth) === pth) {
66 throw permissionError(pth);
67 }
68
69 if (error.message.includes('null bytes')) {
70 throw error;
71 }
72
73 return make(path.dirname(pth)).then(() => make(pth));
74 }
75
76 return stat(pth)
77 .then(stats => stats.isDirectory() ? pth : Promise.reject())
78 .catch(() => {
79 throw error;
80 });
81 });
82 };
83
84 return make(path.resolve(input));
85});
86
87module.exports = makeDir;
88module.exports.default = makeDir;
89
90module.exports.sync = (input, options) => {
91 checkPath(input);
92 options = Object.assign({}, defaults, options);
93
94 if (useNativeRecursiveOption && options.fs.mkdirSync === fs.mkdirSync) {
95 const pth = path.resolve(input);
96
97 fs.mkdirSync(pth, {
98 mode: options.mode,
99 recursive: true
100 });
101
102 return pth;
103 }
104
105 const make = pth => {
106 try {
107 options.fs.mkdirSync(pth, options.mode);
108 } catch (error) {
109 if (error.code === 'EPERM') {
110 throw error;
111 }
112
113 if (error.code === 'ENOENT') {
114 if (path.dirname(pth) === pth) {
115 throw permissionError(pth);
116 }
117
118 if (error.message.includes('null bytes')) {
119 throw error;
120 }
121
122 make(path.dirname(pth));
123 return make(pth);
124 }
125
126 try {
127 if (!options.fs.statSync(pth).isDirectory()) {
128 throw new Error('The path is not a directory');
129 }
130 } catch (_) {
131 throw error;
132 }
133 }
134
135 return pth;
136 };
137
138 return make(path.resolve(input));
139};
Note: See TracBrowser for help on using the repository browser.