zip-lib 1.0.4 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/fs.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ export interface FileEntry {
2
+ path: string;
3
+ isSymbolicLink: boolean;
4
+ type: FileType;
5
+ mtime: Date;
6
+ mode: number;
7
+ }
8
+ export type FileType = "file" | "dir";
9
+ export declare function realpath(target: string): Promise<string>;
10
+ export declare function readdirp(folder: string): Promise<FileEntry[]>;
11
+ export declare function getFileEntry(target: string): Promise<FileEntry>;
12
+ export declare function ensureFolder(folder: string): Promise<{
13
+ isDirectory: boolean;
14
+ isSymbolicLink: boolean;
15
+ realpath?: string;
16
+ }>;
17
+ export declare function pathExists(target: string): Promise<boolean>;
18
+ export declare function rimraf(target: string): Promise<void>;
19
+ export declare function isRootPath(target: string): boolean;
@@ -1,11 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isRootPath = exports.rimraf = exports.pathExists = exports.ensureFolder = exports.getFileEntry = exports.readdirp = void 0;
3
+ exports.realpath = realpath;
4
+ exports.readdirp = readdirp;
5
+ exports.getFileEntry = getFileEntry;
6
+ exports.ensureFolder = ensureFolder;
7
+ exports.pathExists = pathExists;
8
+ exports.rimraf = rimraf;
9
+ exports.isRootPath = isRootPath;
4
10
  const path = require("path");
5
- const util = require("./util");
11
+ const fs = require("fs/promises");
12
+ const util = require("node:util");
13
+ const fsSync = require("fs");
14
+ async function realpath(target) {
15
+ // fs.promises.realpath has a bug with long path on Windows.
16
+ // https://github.com/nodejs/node/issues/51031
17
+ return util.promisify(fsSync.realpath)(target);
18
+ }
6
19
  async function readdirp(folder) {
7
20
  const result = [];
8
- const files = await util.readdir(folder);
21
+ const files = await fs.readdir(folder);
9
22
  for (const item of files) {
10
23
  const file = path.join(folder, item);
11
24
  const entry = await getFileEntry(file);
@@ -22,9 +35,8 @@ async function readdirp(folder) {
22
35
  }
23
36
  return result;
24
37
  }
25
- exports.readdirp = readdirp;
26
38
  async function getFileEntry(target) {
27
- const stat = await util.lstat(target);
39
+ const stat = await fs.lstat(target);
28
40
  let isSymbolicLink = false;
29
41
  let fileType = "file";
30
42
  if (stat.isDirectory()) {
@@ -36,7 +48,7 @@ async function getFileEntry(target) {
36
48
  // If the path is a link, we must instead use fs.stat() to find out if the
37
49
  // link is a directory or not because lstat will always return the stat of
38
50
  // the link which is always a file.
39
- const actualStat = await util.stat(target);
51
+ const actualStat = await fs.stat(target);
40
52
  if (actualStat.isDirectory()) {
41
53
  fileType = "dir";
42
54
  }
@@ -50,14 +62,17 @@ async function getFileEntry(target) {
50
62
  mode: stat.mode
51
63
  };
52
64
  }
53
- exports.getFileEntry = getFileEntry;
54
65
  async function ensureFolder(folder) {
55
66
  // stop at root
56
67
  if (folder === path.dirname(folder)) {
57
- return Promise.resolve();
68
+ return Promise.resolve({
69
+ isDirectory: true,
70
+ isSymbolicLink: false
71
+ });
58
72
  }
59
73
  try {
60
- await mkdir(folder);
74
+ const result = await mkdir(folder);
75
+ return result;
61
76
  }
62
77
  catch (error) {
63
78
  // ENOENT: a parent folder does not exist yet, continue
@@ -70,40 +85,38 @@ async function ensureFolder(folder) {
70
85
  return Promise.reject(error);
71
86
  }
72
87
  }
73
- exports.ensureFolder = ensureFolder;
74
88
  async function pathExists(target) {
75
89
  try {
76
- await util.access(target);
90
+ await fs.access(target);
77
91
  return true;
78
92
  }
79
93
  catch (error) {
80
94
  return false;
81
95
  }
82
96
  }
83
- exports.pathExists = pathExists;
84
97
  async function rimraf(target) {
85
98
  if (isRootPath(target)) {
86
99
  // refuse to recursively delete root
87
100
  return Promise.reject(new Error(`Refuse to recursively delete root, path: "${target}"`));
88
101
  }
89
102
  try {
90
- const stat = await util.lstat(target);
103
+ const stat = await fs.lstat(target);
91
104
  // Folder delete (recursive) - NOT for symbolic links though!
92
105
  if (stat.isDirectory() && !stat.isSymbolicLink()) {
93
106
  // Children
94
- const children = await util.readdir(target);
107
+ const children = await fs.readdir(target);
95
108
  await Promise.all(children.map(child => rimraf(path.join(target, child))));
96
109
  // Folder
97
- await util.rmdir(target);
110
+ await fs.rmdir(target);
98
111
  }
99
112
  // Single file delete
100
113
  else {
101
114
  // chmod as needed to allow for unlink
102
115
  const mode = stat.mode;
103
116
  if (!(mode & 128)) { // 128 === 0200
104
- await util.chmod(target, mode | 128);
117
+ await fs.chmod(target, mode | 128);
105
118
  }
106
- return util.unlink(target);
119
+ return fs.unlink(target);
107
120
  }
108
121
  }
109
122
  catch (error) {
@@ -112,10 +125,13 @@ async function rimraf(target) {
112
125
  }
113
126
  }
114
127
  }
115
- exports.rimraf = rimraf;
116
128
  async function mkdir(folder) {
117
129
  try {
118
- await util.mkdir(folder, 0o777);
130
+ await fs.mkdir(folder, 0o777);
131
+ return {
132
+ isDirectory: true,
133
+ isSymbolicLink: false,
134
+ };
119
135
  }
120
136
  catch (error) {
121
137
  // ENOENT: a parent folder does not exist yet or folder name is invalid.
@@ -125,15 +141,81 @@ async function mkdir(folder) {
125
141
  // Any other error: check if folder exists and
126
142
  // return normally in that case if its a folder
127
143
  try {
128
- const fileStat = await util.stat(folder);
129
- if (!fileStat.isDirectory()) {
130
- return Promise.reject(new Error(`"${folder}" exists and is not a directory.`));
144
+ const fileStat = await fs.lstat(folder);
145
+ if (fileStat.isSymbolicLink()) {
146
+ const realFilePath = await realpath(folder);
147
+ const realFileStat = await fs.lstat(realFilePath);
148
+ if (!realFileStat.isDirectory()) {
149
+ return Promise.reject(new Error(`"${folder}" exists and is not a directory.`));
150
+ }
151
+ return {
152
+ isDirectory: false,
153
+ isSymbolicLink: true,
154
+ realpath: realFilePath,
155
+ };
156
+ }
157
+ else {
158
+ if (!fileStat.isDirectory()) {
159
+ return Promise.reject(new Error(`"${folder}" exists and is not a directory.`));
160
+ }
161
+ return {
162
+ isDirectory: true,
163
+ isSymbolicLink: false,
164
+ };
131
165
  }
132
166
  }
133
167
  catch (statError) {
134
168
  throw error; // rethrow original error
135
169
  }
136
170
  }
171
+ // // Any other error: check if folder exists and
172
+ // // return normally in that case if its a folder
173
+ // try {
174
+ // if (folder.includes("dirlink")) {
175
+ // console.log("tttttt11111", folder);
176
+ // }
177
+ // const fileStat = await fs.lstat(folder);
178
+ // if (folder.includes("dirlink")) {
179
+ // console.log("tttttt22222", fileStat);
180
+ // }
181
+ // if (fileStat.isSymbolicLink()) {
182
+ // console.log("kkkkkkkkk", fileStat);
183
+ // const realFilePath = await realpath(folder);
184
+ // const realFileStat = await fs.lstat(realFilePath);
185
+ // if (!realFileStat.isDirectory()) {
186
+ // return Promise.reject(new Error(`"${folder}" exists and is not a directory.`));
187
+ // }
188
+ // return {
189
+ // isDirectory: false,
190
+ // isSymbolicLink: true,
191
+ // realpath: realFilePath,
192
+ // }
193
+ // } else {
194
+ // if (!fileStat.isDirectory()) {
195
+ // return Promise.reject(new Error(`"${folder}" exists and is not a directory.`));
196
+ // }
197
+ // return {
198
+ // isDirectory: true,
199
+ // isSymbolicLink: false,
200
+ // }
201
+ // }
202
+ // } catch (statError) {
203
+ // if (folder.includes("dirlink")) {
204
+ // console.log("yyyyy", statError);
205
+ // }
206
+ // // ignore
207
+ // }
208
+ // if (folder.includes("dirlink")) {
209
+ // console.log("kkkkkkkkk22222", folder);
210
+ // }
211
+ // await fs.mkdir(folder, { recursive: true, mode: 0o777 });
212
+ // if (folder.includes("dirlink")) {
213
+ // console.log("kkkkkkkkk3333333", folder);
214
+ // }
215
+ // return {
216
+ // isDirectory: true,
217
+ // isSymbolicLink: false,
218
+ // };
137
219
  }
138
220
  // "A"
139
221
  const charA = 65;
@@ -172,4 +254,3 @@ function isRootPath(target) {
172
254
  }
173
255
  return false;
174
256
  }
175
- exports.isRootPath = isRootPath;
@@ -14,7 +14,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.extract = exports.archiveFolder = exports.archiveFile = void 0;
17
+ exports.archiveFile = archiveFile;
18
+ exports.archiveFolder = archiveFolder;
19
+ exports.extract = extract;
18
20
  const zip_1 = require("./zip");
19
21
  const unzip_1 = require("./unzip");
20
22
  __exportStar(require("./zip"), exports);
@@ -30,7 +32,6 @@ function archiveFile(file, zipFile, options) {
30
32
  zip.addFile(file);
31
33
  return zip.archive(zipFile);
32
34
  }
33
- exports.archiveFile = archiveFile;
34
35
  /**
35
36
  * Compress all the contents of the specified folder to zip.
36
37
  * @param folder
@@ -42,7 +43,6 @@ function archiveFolder(folder, zipFile, options) {
42
43
  zip.addFolder(folder);
43
44
  return zip.archive(zipFile);
44
45
  }
45
- exports.archiveFolder = archiveFolder;
46
46
  /**
47
47
  * Extract the zip file to the specified location.
48
48
  * @param zipFile
@@ -53,4 +53,3 @@ function extract(zipFile, targetFolder, options) {
53
53
  const unzip = new unzip_1.Unzip(options);
54
54
  return unzip.extract(zipFile, targetFolder);
55
55
  }
56
- exports.extract = extract;
package/package.json CHANGED
@@ -1,45 +1,43 @@
1
- {
2
- "name": "zip-lib",
3
- "version": "1.0.4",
4
- "description": "zip and unzip library for node",
5
- "main": "lib/index.js",
6
- "scripts": {
7
- "compile": "rimraf ./lib && tsc -p ./src/tsconfig.json",
8
- "release": "rimraf ./lib && tsc -p ./src/tsconfig.release.json",
9
- "compile-test": "rimraf ./test/out && tsc -p ./test/src/tsconfig.json",
10
- "test": "node ./test/src/before.js && mocha ./test/out --timeout 10000",
11
- "pack": "npm run release && npm pack",
12
- "publish": "npm run release && npm publish"
13
- },
14
- "repository": {
15
- "type": "git",
16
- "url": "https://github.com/fpsqdb/zip-lib.git"
17
- },
18
- "engines": {
19
- "node": ">=12"
20
- },
21
- "keywords": [
22
- "zip",
23
- "folder",
24
- "unzip",
25
- "archive",
26
- "extract",
27
- "promise",
28
- "async"
29
- ],
30
- "author": "fpsqdb",
31
- "license": "MIT",
32
- "dependencies": {
33
- "yauzl": "^3.1.3",
34
- "yazl": "^2.5.1"
35
- },
36
- "devDependencies": {
37
- "@types/mocha": "^10.0.6",
38
- "@types/node": "^12.20.55",
39
- "@types/yauzl": "^2.9.1",
40
- "@types/yazl": "^2.4.2",
41
- "mocha": "^10.4.0",
42
- "rimraf": "^5.0.5",
43
- "typescript": "^5.4.5"
44
- }
45
- }
1
+ {
2
+ "name": "zip-lib",
3
+ "version": "1.1.0",
4
+ "description": "zip and unzip library for node",
5
+ "main": "lib/index.js",
6
+ "scripts": {
7
+ "compile": "rimraf ./dist && tsc -p ./src/tsconfig.json",
8
+ "release": "rimraf ./lib && tsc -p ./src/tsconfig.release.json && node ./build.mjs",
9
+ "compile-test": "rimraf ./test/out && tsc -p ./test/src/tsconfig.json",
10
+ "test": "npm run compile && npm run compile-test && node ./test/src/before.js && mocha ./test/out --timeout 10000"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/fpsqdb/zip-lib.git"
15
+ },
16
+ "engines": {
17
+ "node": ">=18"
18
+ },
19
+ "keywords": [
20
+ "zip",
21
+ "folder",
22
+ "unzip",
23
+ "archive",
24
+ "extract",
25
+ "promise",
26
+ "async"
27
+ ],
28
+ "author": "fpsqdb",
29
+ "license": "MIT",
30
+ "dependencies": {
31
+ "yauzl": "^3.2.0",
32
+ "yazl": "^3.3.1"
33
+ },
34
+ "devDependencies": {
35
+ "@types/mocha": "^10.0.10",
36
+ "@types/node": "^18.19.86",
37
+ "@types/yauzl": "^2.10.3",
38
+ "@types/yazl": "^2.4.6",
39
+ "mocha": "^11.1.0",
40
+ "rimraf": "^6.0.1",
41
+ "typescript": "^5.8.3"
42
+ }
43
+ }
@@ -4,8 +4,8 @@ exports.Unzip = void 0;
4
4
  const yauzl = require("yauzl");
5
5
  const exfs = require("./fs");
6
6
  const fs_1 = require("fs");
7
+ const fs = require("fs/promises");
7
8
  const path = require("path");
8
- const util = require("./util");
9
9
  const cancelable_1 = require("./cancelable");
10
10
  class EntryEvent {
11
11
  /**
@@ -40,6 +40,7 @@ class EntryContext {
40
40
  this._realTargetFolder = _realTargetFolder;
41
41
  this.symlinkAsFileOnWindows = symlinkAsFileOnWindows;
42
42
  this._symlinkFileNames = [];
43
+ this._symlinkFolders = [];
43
44
  }
44
45
  get decodeEntryFileName() {
45
46
  return this._decodeEntryFileName;
@@ -56,20 +57,31 @@ class EntryContext {
56
57
  get symlinkFileNames() {
57
58
  return this._symlinkFileNames;
58
59
  }
60
+ get symlinkFolders() {
61
+ return this._symlinkFolders;
62
+ }
59
63
  getFilePath() {
60
64
  return path.join(this.targetFolder, this.decodeEntryFileName);
61
65
  }
62
66
  async isOutsideTargetFolder(tpath) {
63
- if (this.symlinkFileNames.length === 0) {
67
+ if (this.symlinkFileNames.length === 0 &&
68
+ this.symlinkFolders.length === 0) {
64
69
  return false;
65
70
  }
66
71
  if (process.platform === "win32" &&
67
72
  this.symlinkAsFileOnWindows) {
68
73
  return false;
69
74
  }
75
+ for (const { folder, realpath } of this.symlinkFolders) {
76
+ if (tpath.includes(folder)) {
77
+ if (realpath.indexOf(this.realTargetFolder) !== 0) {
78
+ return true;
79
+ }
80
+ }
81
+ }
70
82
  for (const fileName of this.symlinkFileNames) {
71
83
  if (tpath.includes(fileName)) {
72
- const realFilePath = await util.realpath(tpath);
84
+ const realFilePath = await exfs.realpath(tpath);
73
85
  if (realFilePath.indexOf(this.realTargetFolder) !== 0) {
74
86
  return true;
75
87
  }
@@ -106,7 +118,7 @@ class Unzip extends cancelable_1.Cancelable {
106
118
  return Promise.reject(this.canceledError());
107
119
  }
108
120
  await exfs.ensureFolder(targetFolder);
109
- const realTargetFolder = await util.realpath(targetFolder);
121
+ const realTargetFolder = await exfs.realpath(targetFolder);
110
122
  const zfile = await this.openZip(zipFile, token);
111
123
  this.zipFile = zfile;
112
124
  zfile.readEntry();
@@ -240,7 +252,13 @@ class Unzip extends cancelable_1.Cancelable {
240
252
  async extractEntry(zfile, entry, entryContext, token) {
241
253
  const filePath = entryContext.getFilePath();
242
254
  const fileDir = path.dirname(filePath);
243
- await exfs.ensureFolder(fileDir);
255
+ const folderStat = await exfs.ensureFolder(fileDir);
256
+ if (folderStat.isSymbolicLink) {
257
+ entryContext.symlinkFolders.push({
258
+ folder: fileDir,
259
+ realpath: folderStat.realpath,
260
+ });
261
+ }
244
262
  const outside = await entryContext.isOutsideTargetFolder(fileDir);
245
263
  if (outside) {
246
264
  const error = new Error(`Refuse to write file outside "${entryContext.targetFolder}", file: "${filePath}"`);
@@ -317,7 +335,7 @@ class Unzip extends cancelable_1.Cancelable {
317
335
  targetPath = path.join(path.dirname(des), linkContent);
318
336
  }
319
337
  try {
320
- const stat = await util.stat(targetPath);
338
+ const stat = await fs.stat(targetPath);
321
339
  if (stat.isDirectory()) {
322
340
  linkType = "dir";
323
341
  }
@@ -327,7 +345,7 @@ class Unzip extends cancelable_1.Cancelable {
327
345
  }
328
346
  }
329
347
  }
330
- await util.symlink(linkContent, des, linkType);
348
+ await fs.symlink(linkContent, des, linkType);
331
349
  }
332
350
  isOverwrite() {
333
351
  if (this.options &&
@@ -10,6 +10,14 @@ export interface IZipOptions {
10
10
  * The default value is `false`.
11
11
  */
12
12
  followSymlinks?: boolean;
13
+ /**
14
+ * Sets the compression level.
15
+ *
16
+ * 0: the file data will be stored, otherwise, the file data will be deflated.
17
+ *
18
+ * The default value is `6`.
19
+ */
20
+ compressionLevel?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
13
21
  }
14
22
  /**
15
23
  * Compress files or folders to a zip file.
@@ -56,4 +64,11 @@ export declare class Zip extends Cancelable {
56
64
  private walkDir;
57
65
  private stopPipe;
58
66
  private followSymlink;
67
+ /**
68
+ * Retrieves the yazl options based on the current settings.
69
+ *
70
+ * @returns The yazl options with the specified compression level,
71
+ * or undefined if options or compressionLevel are not properly set.
72
+ */
73
+ private getYazlOption;
59
74
  }
@@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Zip = void 0;
4
4
  const yazl = require("yazl");
5
5
  const fs_1 = require("fs");
6
+ const fs = require("fs/promises");
6
7
  const exfs = require("./fs");
7
8
  const path = require("path");
8
- const util = require("./util");
9
9
  const cancelable_1 = require("./cancelable");
10
10
  /**
11
11
  * Compress files or folders to a zip file.
@@ -28,13 +28,13 @@ class Zip extends cancelable_1.Cancelable {
28
28
  * A valid metadataPath must not start with "/" or /[A-Za-z]:\//, and must not contain "..".
29
29
  */
30
30
  addFile(file, metadataPath) {
31
- let mpath = metadataPath;
32
- if (!mpath) {
33
- mpath = path.basename(file);
31
+ let mPath = metadataPath;
32
+ if (!mPath) {
33
+ mPath = path.basename(file);
34
34
  }
35
35
  this.zipFiles.push({
36
36
  path: file,
37
- metadataPath: mpath
37
+ metadataPath: mPath
38
38
  });
39
39
  }
40
40
  /**
@@ -120,11 +120,11 @@ class Zip extends cancelable_1.Cancelable {
120
120
  if (entry.isSymbolicLink) {
121
121
  if (this.followSymlink()) {
122
122
  if (entry.type === "dir") {
123
- const realPath = await util.realpath(file.path);
123
+ const realPath = await exfs.realpath(file.path);
124
124
  await this.walkDir([{ path: realPath, metadataPath: file.metadataPath }], token);
125
125
  }
126
126
  else {
127
- zip.addFile(file.path, file.metadataPath);
127
+ zip.addFile(file.path, file.metadataPath, this.getYazlOption());
128
128
  }
129
129
  }
130
130
  else {
@@ -156,18 +156,12 @@ class Zip extends cancelable_1.Cancelable {
156
156
  });
157
157
  // If the file attribute is known, add the entry using `addReadStream`,
158
158
  // this can reduce the number of calls to the `fs.stat` method.
159
- zip.addReadStream(fileStream, metadataPath, {
160
- mode: file.mode,
161
- mtime: file.mtime
162
- });
159
+ zip.addReadStream(fileStream, metadataPath, Object.assign(Object.assign({}, this.getYazlOption()), { mode: file.mode, mtime: file.mtime }));
163
160
  });
164
161
  }
165
162
  async addSymlink(zip, file, metadataPath) {
166
- const linkTarget = await util.readlink(file.path);
167
- zip.addBuffer(Buffer.from(linkTarget), metadataPath, {
168
- mtime: file.mtime,
169
- mode: file.mode
170
- });
163
+ const linkTarget = await fs.readlink(file.path);
164
+ zip.addBuffer(Buffer.from(linkTarget), metadataPath, Object.assign(Object.assign({}, this.getYazlOption()), { mtime: file.mtime, mode: file.mode }));
171
165
  }
172
166
  async walkDir(folders, token) {
173
167
  for (const folder of folders) {
@@ -209,5 +203,22 @@ class Zip extends cancelable_1.Cancelable {
209
203
  }
210
204
  return followSymlink;
211
205
  }
206
+ /**
207
+ * Retrieves the yazl options based on the current settings.
208
+ *
209
+ * @returns The yazl options with the specified compression level,
210
+ * or undefined if options or compressionLevel are not properly set.
211
+ */
212
+ getYazlOption() {
213
+ if (!this.options) {
214
+ return undefined;
215
+ }
216
+ if (typeof this.options.compressionLevel !== "number") {
217
+ return undefined;
218
+ }
219
+ return {
220
+ compressionLevel: this.options.compressionLevel,
221
+ };
222
+ }
212
223
  }
213
224
  exports.Zip = Zip;
package/lib/util.js DELETED
@@ -1,49 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.readlink = exports.symlink = exports.rmdir = exports.access = exports.readdir = exports.chmod = exports.lstat = exports.stat = exports.realpath = exports.mkdir = exports.unlink = void 0;
4
- const fs = require("fs");
5
- const util = require("util");
6
- function unlink(path) {
7
- return util.promisify(fs.unlink)(path);
8
- }
9
- exports.unlink = unlink;
10
- function mkdir(path, mode) {
11
- return util.promisify(fs.mkdir)(path, mode);
12
- }
13
- exports.mkdir = mkdir;
14
- function realpath(path) {
15
- return util.promisify(fs.realpath)(path);
16
- }
17
- exports.realpath = realpath;
18
- function stat(path) {
19
- return util.promisify(fs.stat)(path);
20
- }
21
- exports.stat = stat;
22
- function lstat(path) {
23
- return util.promisify(fs.lstat)(path);
24
- }
25
- exports.lstat = lstat;
26
- function chmod(path, mode) {
27
- return util.promisify(fs.chmod)(path, mode);
28
- }
29
- exports.chmod = chmod;
30
- function readdir(path) {
31
- return util.promisify(fs.readdir)(path);
32
- }
33
- exports.readdir = readdir;
34
- function access(path, mode) {
35
- return util.promisify(fs.access)(path, mode);
36
- }
37
- exports.access = access;
38
- function rmdir(path) {
39
- return util.promisify(fs.rmdir)(path);
40
- }
41
- exports.rmdir = rmdir;
42
- function symlink(target, path, type) {
43
- return util.promisify(fs.symlink)(target, path, type);
44
- }
45
- exports.symlink = symlink;
46
- function readlink(path) {
47
- return util.promisify(fs.readlink)(path);
48
- }
49
- exports.readlink = readlink;
File without changes
File without changes
File without changes
File without changes