d4d6e4d9461c1d3e829c2b0094cdc98366aa18fd80dc0da6ed2c5f9ceb2c26461aa3e3929784369a62ba1a8719fa7b4e8d3ca11d167142e4ecea175cd1c492 7.3 KB

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