12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- 'use strict';
- const fs = require('fs');
- const path = require('path');
- const pify = require('pify');
- const defaults = {
- mode: 0o777 & (~process.umask()),
- fs
- };
- // 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 err = new Error(`Path contains invalid characters: ${pth}`);
- err.code = 'EINVAL';
- throw err;
- }
- }
- };
- module.exports = (input, opts) => Promise.resolve().then(() => {
- checkPath(input);
- opts = Object.assign({}, defaults, opts);
- const mkdir = pify(opts.fs.mkdir);
- const stat = pify(opts.fs.stat);
- const make = pth => {
- return mkdir(pth, opts.mode)
- .then(() => pth)
- .catch(err => {
- if (err.code === 'ENOENT') {
- if (err.message.includes('null bytes') || path.dirname(pth) === pth) {
- throw err;
- }
- return make(path.dirname(pth)).then(() => make(pth));
- }
- return stat(pth)
- .then(stats => stats.isDirectory() ? pth : Promise.reject())
- .catch(() => {
- throw err;
- });
- });
- };
- return make(path.resolve(input));
- });
- module.exports.sync = (input, opts) => {
- checkPath(input);
- opts = Object.assign({}, defaults, opts);
- const make = pth => {
- try {
- opts.fs.mkdirSync(pth, opts.mode);
- } catch (err) {
- if (err.code === 'ENOENT') {
- if (err.message.includes('null bytes') || path.dirname(pth) === pth) {
- throw err;
- }
- make(path.dirname(pth));
- return make(pth);
- }
- try {
- if (!opts.fs.statSync(pth).isDirectory()) {
- throw new Error('The path is not a directory');
- }
- } catch (_) {
- throw err;
- }
- }
- return pth;
- };
- return make(path.resolve(input));
- };
|