codekingpro/portable-devtools
115k
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6exports.mkdirSync = exports.mkdir = void 0;
7const chownr_1 = require("chownr");
8const node_fs_1 = __importDefault(require("node:fs"));
9const promises_1 = __importDefault(require("node:fs/promises"));
10const node_path_1 = __importDefault(require("node:path"));
11const cwd_error_js_1 = require("./cwd-error.js");
12const normalize_windows_path_js_1 = require("./normalize-windows-path.js");
13const symlink_error_js_1 = require("./symlink-error.js");
14const checkCwd = (dir, cb) => {
15 node_fs_1.default.stat(dir, (er, st) => {
16 if (er || !st.isDirectory()) {
17 er = new cwd_error_js_1.CwdError(dir, er?.code || 'ENOTDIR');
18 }
19 cb(er);
20 });
21};
22/**
23 * Wrapper around fs/promises.mkdir for tar's needs.
24 *
25 * The main purpose is to avoid creating directories if we know that
26 * they already exist (and track which ones exist for this purpose),
27 * and prevent entries from being extracted into symlinked folders,
28 * if `preservePaths` is not set.
29 */
30const mkdir = (dir, opt, cb) => {
31 dir = (0, normalize_windows_path_js_1.normalizeWindowsPath)(dir);
32 // if there's any overlap between mask and mode,
33 // then we'll need an explicit chmod
34 /* c8 ignore next */
35 const umask = opt.umask ?? 0o22;
36 const mode = opt.mode | 0o0700;
37 const needChmod = (mode & umask) !== 0;
38 const uid = opt.uid;
39 const gid = opt.gid;
40 const doChown = typeof uid === 'number' &&
41 typeof gid === 'number' &&
42 (uid !== opt.processUid || gid !== opt.processGid);
43 const preserve = opt.preserve;
44 const unlink = opt.unlink;
45 const cwd = (0, normalize_windows_path_js_1.normalizeWindowsPath)(opt.cwd);
46 const done = (er, created) => {
47 if (er) {
48 cb(er);
49 }
50 else {
51 if (created && doChown) {
52 (0, chownr_1.chownr)(created, uid, gid, er => done(er));
53 }
54 else if (needChmod) {
55 node_fs_1.default.chmod(dir, mode, cb);
56 }
57 else {
58 cb();
59 }
60 }
61 };
62 if (dir === cwd) {
63 return checkCwd(dir, done);
64 }
65 if (preserve) {
66 return promises_1.default.mkdir(dir, { mode, recursive: true }).then(made => done(null, made ?? undefined), // oh, ts
67 done);
68 }
69 const sub = (0, normalize_windows_path_js_1.normalizeWindowsPath)(node_path_1.default.relative(cwd, dir));
70 const parts = sub.split('/');
71 mkdir_(cwd, parts, mode, unlink, cwd, undefined, done);
72};
73exports.mkdir = mkdir;
74const mkdir_ = (base, parts, mode, unlink, cwd, created, cb) => {
75 if (parts.length === 0) {
76 return cb(null, created);
77 }
78 const p = parts.shift();
79 const part = (0, normalize_windows_path_js_1.normalizeWindowsPath)(node_path_1.default.resolve(base + '/' + p));
80 node_fs_1.default.mkdir(part, mode, onmkdir(part, parts, mode, unlink, cwd, created, cb));
81};
82const onmkdir = (part, parts, mode, unlink, cwd, created, cb) => (er) => {
83 if (er) {
84 node_fs_1.default.lstat(part, (statEr, st) => {
85 if (statEr) {
86 statEr.path = statEr.path && (0, normalize_windows_path_js_1.normalizeWindowsPath)(statEr.path);
87 cb(statEr);
88 }
89 else if (st.isDirectory()) {
90 mkdir_(part, parts, mode, unlink, cwd, created, cb);
91 }
92 else if (unlink) {
93 node_fs_1.default.unlink(part, er => {
94 if (er) {
95 return cb(er);
96 }
97 node_fs_1.default.mkdir(part, mode, onmkdir(part, parts, mode, unlink, cwd, created, cb));
98 });
99 }
100 else if (st.isSymbolicLink()) {
101 return cb(new symlink_error_js_1.SymlinkError(part, part + '/' + parts.join('/')));
102 }
103 else {
104 cb(er);
105 }
106 });
107 }
108 else {
109 created = created || part;
110 mkdir_(part, parts, mode, unlink, cwd, created, cb);
111 }
112};
113const checkCwdSync = (dir) => {
114 let ok = false;
115 let code;
116 try {
117 ok = node_fs_1.default.statSync(dir).isDirectory();
118 }
119 catch (er) {
120 code = er?.code;
121 }
122 finally {
123 if (!ok) {
124 throw new cwd_error_js_1.CwdError(dir, code ?? 'ENOTDIR');
125 }
126 }
127};
128const mkdirSync = (dir, opt) => {
129 dir = (0, normalize_windows_path_js_1.normalizeWindowsPath)(dir);
130 // if there's any overlap between mask and mode,
131 // then we'll need an explicit chmod
132 /* c8 ignore next */
133 const umask = opt.umask ?? 0o22;
134 const mode = opt.mode | 0o700;
135 const needChmod = (mode & umask) !== 0;
136 const uid = opt.uid;
137 const gid = opt.gid;
138 const doChown = typeof uid === 'number' &&
139 typeof gid === 'number' &&
140 (uid !== opt.processUid || gid !== opt.processGid);
141 const preserve = opt.preserve;
142 const unlink = opt.unlink;
143 const cwd = (0, normalize_windows_path_js_1.normalizeWindowsPath)(opt.cwd);
144 const done = (created) => {
145 if (created && doChown) {
146 (0, chownr_1.chownrSync)(created, uid, gid);
147 }
148 if (needChmod) {
149 node_fs_1.default.chmodSync(dir, mode);
150 }
151 };
152 if (dir === cwd) {
153 checkCwdSync(cwd);
154 return done();
155 }
156 if (preserve) {
157 return done(node_fs_1.default.mkdirSync(dir, { mode, recursive: true }) ?? undefined);
158 }
159 const sub = (0, normalize_windows_path_js_1.normalizeWindowsPath)(node_path_1.default.relative(cwd, dir));
160 const parts = sub.split('/');
161 let created;
162 for (let p = parts.shift(), part = cwd; p && (part += '/' + p); p = parts.shift()) {
163 part = (0, normalize_windows_path_js_1.normalizeWindowsPath)(node_path_1.default.resolve(part));
164 try {
165 node_fs_1.default.mkdirSync(part, mode);
166 created = created || part;
167 }
168 catch {
169 const st = node_fs_1.default.lstatSync(part);
170 if (st.isDirectory()) {
171 continue;
172 }
173 else if (unlink) {
174 node_fs_1.default.unlinkSync(part);
175 node_fs_1.default.mkdirSync(part, mode);
176 created = created || part;
177 continue;
178 }
179 else if (st.isSymbolicLink()) {
180 return new symlink_error_js_1.SymlinkError(part, part + '/' + parts.join('/'));
181 }
182 }
183 }
184 return done(created);
185};
186exports.mkdirSync = mkdirSync;
187//# sourceMappingURL=mkdir.js.map