123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- 'use strict'
- const fs = require('../fs')
- const path = require('path')
- const atLeastNode = require('at-least-node')
- const useNativeRecursiveOption = atLeastNode('10.12.0')
- 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 => {
- const defaults = { mode: 0o777 }
- if (typeof options === 'number') options = { mode: options }
- return { ...defaults, ...options }
- }
- const permissionError = pth => {
-
-
- const error = new Error(`operation not permitted, mkdir '${pth}'`)
- error.code = 'EPERM'
- error.errno = -4048
- error.path = pth
- error.syscall = 'mkdir'
- return error
- }
- module.exports.makeDir = async (input, options) => {
- checkPath(input)
- options = processOptions(options)
- if (useNativeRecursiveOption) {
- const pth = path.resolve(input)
- return fs.mkdir(pth, {
- mode: options.mode,
- recursive: true
- })
- }
- const make = async pth => {
- try {
- await fs.mkdir(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
- }
- await make(path.dirname(pth))
- return make(pth)
- }
- try {
- const stats = await fs.stat(pth)
- if (!stats.isDirectory()) {
-
-
- throw new Error('The path is not a directory')
- }
- } catch {
- throw error
- }
- }
- }
- return make(path.resolve(input))
- }
- module.exports.makeDirSync = (input, options) => {
- checkPath(input)
- options = processOptions(options)
- if (useNativeRecursiveOption) {
- const pth = path.resolve(input)
- return fs.mkdirSync(pth, {
- mode: options.mode,
- recursive: true
- })
- }
- const make = pth => {
- try {
- 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 (!fs.statSync(pth).isDirectory()) {
-
-
- throw new Error('The path is not a directory')
- }
- } catch {
- throw error
- }
- }
- }
- return make(path.resolve(input))
- }
|