aboutsummaryrefslogtreecommitdiff
path: root/node_modules/make-dir/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/make-dir/index.js')
-rw-r--r--node_modules/make-dir/index.js156
1 files changed, 156 insertions, 0 deletions
diff --git a/node_modules/make-dir/index.js b/node_modules/make-dir/index.js
new file mode 100644
index 0000000..75889d8
--- /dev/null
+++ b/node_modules/make-dir/index.js
@@ -0,0 +1,156 @@
+'use strict';
+const fs = require('fs');
+const path = require('path');
+const {promisify} = require('util');
+const semver = require('semver');
+
+const useNativeRecursiveOption = semver.satisfies(process.version, '>=10.12.0');
+
+// https://github.com/nodejs/node/issues/8987
+// https://github.com/libuv/libuv/pull/1088
+const checkPath = pth => {
+ if (process.platform === 'win32') {
+ const pathHasInvalidWinCharacters = /[<>:"|?*]/.test(pth.replace(path.parse(pth).root, ''));
+
+ if (pathHasInvalidWinCharacters) {
+ const error = new Error(`Path contains invalid characters: ${pth}`);
+ error.code = 'EINVAL';
+ throw error;
+ }
+ }
+};
+
+const processOptions = options => {
+ // https://github.com/sindresorhus/make-dir/issues/18
+ const defaults = {
+ mode: 0o777,
+ fs
+ };
+
+ return {
+ ...defaults,
+ ...options
+ };
+};
+
+const permissionError = pth => {
+ // This replicates the exception of `fs.mkdir` with native the
+ // `recusive` option when run on an invalid drive under Windows.
+ const error = new Error(`operation not permitted, mkdir '${pth}'`);
+ error.code = 'EPERM';
+ error.errno = -4048;
+ error.path = pth;
+ error.syscall = 'mkdir';
+ return error;
+};
+
+const makeDir = async (input, options) => {
+ checkPath(input);
+ options = processOptions(options);
+
+ const mkdir = promisify(options.fs.mkdir);
+ const stat = promisify(options.fs.stat);
+
+ if (useNativeRecursiveOption && options.fs.mkdir === fs.mkdir) {
+ const pth = path.resolve(input);
+
+ await mkdir(pth, {
+ mode: options.mode,
+ recursive: true
+ });
+
+ return pth;
+ }
+
+ const make = async pth => {
+ try {
+ await mkdir(pth, options.mode);
+
+ return pth;
+ } catch (error) {
+ if (error.code === 'EPERM') {
+ throw error;
+ }
+
+ if (error.code === 'ENOENT') {
+ if (path.dirname(pth) === pth) {
+ throw permissionError(pth);
+ }
+
+ if (error.message.includes('null bytes')) {
+ throw error;
+ }
+
+ await make(path.dirname(pth));
+
+ return make(pth);
+ }
+
+ try {
+ const stats = await stat(pth);
+ if (!stats.isDirectory()) {
+ throw new Error('The path is not a directory');
+ }
+ } catch (_) {
+ throw error;
+ }
+
+ return pth;
+ }
+ };
+
+ return make(path.resolve(input));
+};
+
+module.exports = makeDir;
+
+module.exports.sync = (input, options) => {
+ checkPath(input);
+ options = processOptions(options);
+
+ if (useNativeRecursiveOption && options.fs.mkdirSync === fs.mkdirSync) {
+ const pth = path.resolve(input);
+
+ fs.mkdirSync(pth, {
+ mode: options.mode,
+ recursive: true
+ });
+
+ return pth;
+ }
+
+ const make = pth => {
+ try {
+ options.fs.mkdirSync(pth, options.mode);
+ } catch (error) {
+ if (error.code === 'EPERM') {
+ throw error;
+ }
+
+ if (error.code === 'ENOENT') {
+ if (path.dirname(pth) === pth) {
+ throw permissionError(pth);
+ }
+
+ if (error.message.includes('null bytes')) {
+ throw error;
+ }
+
+ make(path.dirname(pth));
+ return make(pth);
+ }
+
+ try {
+ if (!options.fs.statSync(pth).isDirectory()) {
+ throw new Error('The path is not a directory');
+ }
+ } catch (_) {
+ throw error;
+ }
+ }
+
+ return pth;
+ };
+
+ return make(path.resolve(input));
+};