basant307/AI_Governance_Project
048
1'use strict';2const fs = require('fs');3const path = require('path');4const {promisify} = require('util');5const semverGte = require('semver/functions/gte');6 7const useNativeRecursiveOption = semverGte(process.version, '10.12.0');8 9// https://github.com/nodejs/node/issues/898710// https://github.com/libuv/libuv/pull/108811const checkPath = pth => {12 if (process.platform === 'win32') {13 const pathHasInvalidWinCharacters = /[<>:"|?*]/.test(pth.replace(path.parse(pth).root, ''));14 15 if (pathHasInvalidWinCharacters) {16 const error = new Error(`Path contains invalid characters: ${pth}`);17 error.code = 'EINVAL';18 throw error;19 }20 }21};22 23const processOptions = options => {24 const defaults = {25 mode: 0o777,26 fs27 };28 29 return {30 ...defaults,31 ...options32 };33};34 35const permissionError = pth => {36 // This replicates the exception of `fs.mkdir` with native the37 // `recusive` option when run on an invalid drive under Windows.38 const error = new Error(`operation not permitted, mkdir '${pth}'`);39 error.code = 'EPERM';40 error.errno = -4048;41 error.path = pth;42 error.syscall = 'mkdir';43 return error;44};45 46const makeDir = async (input, options) => {47 checkPath(input);48 options = processOptions(options);49 50 const mkdir = promisify(options.fs.mkdir);51 const stat = promisify(options.fs.stat);52 53 if (useNativeRecursiveOption && options.fs.mkdir === fs.mkdir) {54 const pth = path.resolve(input);55 56 await mkdir(pth, {57 mode: options.mode,58 recursive: true59 });60 61 return pth;62 }63 64 const make = async pth => {65 try {66 await mkdir(pth, options.mode);67 68 return pth;69 } catch (error) {70 if (error.code === 'EPERM') {71 throw error;72 }73 74 if (error.code === 'ENOENT') {75 if (path.dirname(pth) === pth) {76 throw permissionError(pth);77 }78 79 if (error.message.includes('null bytes')) {80 throw error;81 }82 83 await make(path.dirname(pth));84 85 return make(pth);86 }87 88 try {89 const stats = await stat(pth);90 if (!stats.isDirectory()) {91 throw new Error('The path is not a directory');92 }93 } catch {94 throw error;95 }96 97 return pth;98 }99 };100 101 return make(path.resolve(input));102};103 104module.exports = makeDir;105 106module.exports.sync = (input, options) => {107 checkPath(input);108 options = processOptions(options);109 110 if (useNativeRecursiveOption && options.fs.mkdirSync === fs.mkdirSync) {111 const pth = path.resolve(input);112 113 fs.mkdirSync(pth, {114 mode: options.mode,115 recursive: true116 });117 118 return pth;119 }120 121 const make = pth => {122 try {123 options.fs.mkdirSync(pth, options.mode);124 } catch (error) {125 if (error.code === 'EPERM') {126 throw error;127 }128 129 if (error.code === 'ENOENT') {130 if (path.dirname(pth) === pth) {131 throw permissionError(pth);132 }133 134 if (error.message.includes('null bytes')) {135 throw error;136 }137 138 make(path.dirname(pth));139 return make(pth);140 }141 142 try {143 if (!options.fs.statSync(pth).isDirectory()) {144 throw new Error('The path is not a directory');145 }146 } catch {147 throw error;148 }149 }150 151 return pth;152 };153 154 return make(path.resolve(input));155};156 