source: trip-planner-front/node_modules/chownr/chownr.js@ 6a3a178

Last change on this file since 6a3a178 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 4.2 KB
Line 
1'use strict'
2const fs = require('fs')
3const path = require('path')
4
5/* istanbul ignore next */
6const LCHOWN = fs.lchown ? 'lchown' : 'chown'
7/* istanbul ignore next */
8const LCHOWNSYNC = fs.lchownSync ? 'lchownSync' : 'chownSync'
9
10/* istanbul ignore next */
11const needEISDIRHandled = fs.lchown &&
12 !process.version.match(/v1[1-9]+\./) &&
13 !process.version.match(/v10\.[6-9]/)
14
15const lchownSync = (path, uid, gid) => {
16 try {
17 return fs[LCHOWNSYNC](path, uid, gid)
18 } catch (er) {
19 if (er.code !== 'ENOENT')
20 throw er
21 }
22}
23
24/* istanbul ignore next */
25const chownSync = (path, uid, gid) => {
26 try {
27 return fs.chownSync(path, uid, gid)
28 } catch (er) {
29 if (er.code !== 'ENOENT')
30 throw er
31 }
32}
33
34/* istanbul ignore next */
35const handleEISDIR =
36 needEISDIRHandled ? (path, uid, gid, cb) => er => {
37 // Node prior to v10 had a very questionable implementation of
38 // fs.lchown, which would always try to call fs.open on a directory
39 // Fall back to fs.chown in those cases.
40 if (!er || er.code !== 'EISDIR')
41 cb(er)
42 else
43 fs.chown(path, uid, gid, cb)
44 }
45 : (_, __, ___, cb) => cb
46
47/* istanbul ignore next */
48const handleEISDirSync =
49 needEISDIRHandled ? (path, uid, gid) => {
50 try {
51 return lchownSync(path, uid, gid)
52 } catch (er) {
53 if (er.code !== 'EISDIR')
54 throw er
55 chownSync(path, uid, gid)
56 }
57 }
58 : (path, uid, gid) => lchownSync(path, uid, gid)
59
60// fs.readdir could only accept an options object as of node v6
61const nodeVersion = process.version
62let readdir = (path, options, cb) => fs.readdir(path, options, cb)
63let readdirSync = (path, options) => fs.readdirSync(path, options)
64/* istanbul ignore next */
65if (/^v4\./.test(nodeVersion))
66 readdir = (path, options, cb) => fs.readdir(path, cb)
67
68const chown = (cpath, uid, gid, cb) => {
69 fs[LCHOWN](cpath, uid, gid, handleEISDIR(cpath, uid, gid, er => {
70 // Skip ENOENT error
71 cb(er && er.code !== 'ENOENT' ? er : null)
72 }))
73}
74
75const chownrKid = (p, child, uid, gid, cb) => {
76 if (typeof child === 'string')
77 return fs.lstat(path.resolve(p, child), (er, stats) => {
78 // Skip ENOENT error
79 if (er)
80 return cb(er.code !== 'ENOENT' ? er : null)
81 stats.name = child
82 chownrKid(p, stats, uid, gid, cb)
83 })
84
85 if (child.isDirectory()) {
86 chownr(path.resolve(p, child.name), uid, gid, er => {
87 if (er)
88 return cb(er)
89 const cpath = path.resolve(p, child.name)
90 chown(cpath, uid, gid, cb)
91 })
92 } else {
93 const cpath = path.resolve(p, child.name)
94 chown(cpath, uid, gid, cb)
95 }
96}
97
98
99const chownr = (p, uid, gid, cb) => {
100 readdir(p, { withFileTypes: true }, (er, children) => {
101 // any error other than ENOTDIR or ENOTSUP means it's not readable,
102 // or doesn't exist. give up.
103 if (er) {
104 if (er.code === 'ENOENT')
105 return cb()
106 else if (er.code !== 'ENOTDIR' && er.code !== 'ENOTSUP')
107 return cb(er)
108 }
109 if (er || !children.length)
110 return chown(p, uid, gid, cb)
111
112 let len = children.length
113 let errState = null
114 const then = er => {
115 if (errState)
116 return
117 if (er)
118 return cb(errState = er)
119 if (-- len === 0)
120 return chown(p, uid, gid, cb)
121 }
122
123 children.forEach(child => chownrKid(p, child, uid, gid, then))
124 })
125}
126
127const chownrKidSync = (p, child, uid, gid) => {
128 if (typeof child === 'string') {
129 try {
130 const stats = fs.lstatSync(path.resolve(p, child))
131 stats.name = child
132 child = stats
133 } catch (er) {
134 if (er.code === 'ENOENT')
135 return
136 else
137 throw er
138 }
139 }
140
141 if (child.isDirectory())
142 chownrSync(path.resolve(p, child.name), uid, gid)
143
144 handleEISDirSync(path.resolve(p, child.name), uid, gid)
145}
146
147const chownrSync = (p, uid, gid) => {
148 let children
149 try {
150 children = readdirSync(p, { withFileTypes: true })
151 } catch (er) {
152 if (er.code === 'ENOENT')
153 return
154 else if (er.code === 'ENOTDIR' || er.code === 'ENOTSUP')
155 return handleEISDirSync(p, uid, gid)
156 else
157 throw er
158 }
159
160 if (children && children.length)
161 children.forEach(child => chownrKidSync(p, child, uid, gid))
162
163 return handleEISDirSync(p, uid, gid)
164}
165
166module.exports = chownr
167chownr.sync = chownrSync
Note: See TracBrowser for help on using the repository browser.