Welcome to mirror list, hosted at ThFree Co, Russian Federation.

polyfill.js « mkdir « lib « fs « @npmcli « node_modules - github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 4f8e6f006a30ece82382648d94c46d60dff0d410 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
const { dirname } = require('path')

const fileURLToPath = require('../common/file-url-to-path/index.js')
const fs = require('../fs.js')

const defaultOptions = {
  mode: 0o777,
  recursive: false,
}

const mkdir = async (path, opts) => {
  const options = { ...defaultOptions, ...opts }

  // if we're not in recursive mode, just call the real mkdir with the path and
  // the mode option only
  if (!options.recursive) {
    return fs.mkdir(path, options.mode)
  }

  const makeDirectory = async (dir, mode) => {
    // we can't use dirname directly since these functions support URL
    // objects with the file: protocol as the path input, so first we get a
    // string path, then we can call dirname on that
    const parent = dir != null && dir.href && dir.origin
      ? dirname(fileURLToPath(dir))
      : dirname(dir)

    // if the parent is the dir itself, try to create it. anything but EISDIR
    // should be rethrown
    if (parent === dir) {
      try {
        await fs.mkdir(dir, opts)
      } catch (err) {
        if (err.code !== 'EISDIR') {
          throw err
        }
      }
      return undefined
    }

    try {
      await fs.mkdir(dir, mode)
      return dir
    } catch (err) {
      // ENOENT means the parent wasn't there, so create that
      if (err.code === 'ENOENT') {
        const made = await makeDirectory(parent, mode)
        await makeDirectory(dir, mode)
        // return the shallowest path we created, i.e. the result of creating
        // the parent
        return made
      }

      // an EEXIST means there's already something there
      // an EROFS means we have a read-only filesystem and can't create a dir
      // any other error is fatal and we should give up now
      if (err.code !== 'EEXIST' && err.code !== 'EROFS') {
        throw err
      }

      // stat the directory, if the result is a directory, then we successfully
      // created this one so return its path. otherwise, we reject with the
      // original error by ignoring the error in the catch
      try {
        const stat = await fs.stat(dir)
        if (stat.isDirectory()) {
          // if it already existed, we didn't create anything so return
          // undefined
          return undefined
        }
      } catch (_) {}

      // if the thing that's there isn't a directory, then just re-throw
      throw err
    }
  }

  return makeDirectory(path, options.mode)
}

module.exports = mkdir