@gjsify/fs 0.0.1 → 0.0.3

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.
Files changed (80) hide show
  1. package/README.md +6 -8
  2. package/lib/cjs/callback.js +112 -0
  3. package/lib/cjs/dirent.js +98 -0
  4. package/lib/cjs/encoding.js +34 -0
  5. package/lib/cjs/file-handle.js +444 -0
  6. package/lib/cjs/fs-watcher.js +50 -0
  7. package/lib/cjs/index.js +95 -0
  8. package/lib/cjs/promises.js +160 -0
  9. package/lib/cjs/read-stream.js +78 -0
  10. package/lib/cjs/stats.js +45 -0
  11. package/lib/cjs/sync.js +126 -0
  12. package/lib/cjs/types/encoding-option.js +0 -0
  13. package/lib/cjs/types/file-read-options.js +0 -0
  14. package/lib/cjs/types/file-read-result.js +0 -0
  15. package/lib/cjs/types/flag-and-open-mode.js +0 -0
  16. package/lib/cjs/types/index.js +6 -0
  17. package/lib/cjs/types/open-flags.js +0 -0
  18. package/lib/cjs/types/read-options.js +0 -0
  19. package/lib/cjs/utils.js +18 -0
  20. package/lib/cjs/write-stream.js +116 -0
  21. package/lib/esm/callback.js +112 -0
  22. package/lib/esm/dirent.js +98 -0
  23. package/lib/esm/encoding.js +34 -0
  24. package/lib/esm/file-handle.js +444 -0
  25. package/lib/esm/fs-watcher.js +50 -0
  26. package/lib/esm/index.js +95 -0
  27. package/lib/esm/promises.js +160 -0
  28. package/lib/esm/read-stream.js +78 -0
  29. package/lib/esm/stats.js +45 -0
  30. package/lib/esm/sync.js +126 -0
  31. package/lib/esm/types/encoding-option.js +0 -0
  32. package/lib/esm/types/file-read-options.js +0 -0
  33. package/lib/esm/types/file-read-result.js +0 -0
  34. package/lib/esm/types/flag-and-open-mode.js +0 -0
  35. package/lib/esm/types/index.js +6 -0
  36. package/lib/esm/types/open-flags.js +0 -0
  37. package/lib/esm/types/read-options.js +0 -0
  38. package/lib/esm/utils.js +18 -0
  39. package/lib/esm/write-stream.js +116 -0
  40. package/package.json +52 -17
  41. package/src/callback.spec.ts +42 -0
  42. package/src/callback.ts +362 -0
  43. package/src/dirent.ts +117 -0
  44. package/src/encoding.ts +40 -0
  45. package/src/file-handle.spec.ts +34 -0
  46. package/src/file-handle.ts +606 -0
  47. package/{fs-watcher.js → src/fs-watcher.ts} +10 -9
  48. package/src/index.ts +95 -0
  49. package/src/promises.spec.ts +172 -0
  50. package/src/promises.ts +349 -0
  51. package/src/read-stream.ts +98 -0
  52. package/src/stat.spec.ts +79 -0
  53. package/src/stats.ts +106 -0
  54. package/src/symlink.spec.ts +38 -0
  55. package/src/sync.spec.ts +205 -0
  56. package/src/sync.ts +239 -0
  57. package/src/test.mts +11 -0
  58. package/src/types/encoding-option.ts +3 -0
  59. package/src/types/file-read-options.ts +15 -0
  60. package/src/types/file-read-result.ts +4 -0
  61. package/src/types/flag-and-open-mode.ts +6 -0
  62. package/src/types/index.ts +6 -0
  63. package/src/types/open-flags.ts +14 -0
  64. package/src/types/read-options.ts +9 -0
  65. package/src/utils.ts +19 -0
  66. package/src/write-stream.ts +143 -0
  67. package/test/file.txt +1 -0
  68. package/test/watch.js +1 -0
  69. package/test.gjs.js +35359 -0
  70. package/test.gjs.js.map +7 -0
  71. package/test.gjs.mjs +40570 -0
  72. package/test.gjs.mjs.meta.json +1 -0
  73. package/test.node.js +1479 -0
  74. package/test.node.js.map +7 -0
  75. package/test.node.mjs +710 -0
  76. package/tsconfig.json +18 -0
  77. package/tsconfig.types.json +8 -0
  78. package/index.js +0 -114
  79. package/test/index.js +0 -90
  80. package/test/resources/file.txt +0 -1
@@ -0,0 +1,50 @@
1
+ import Gio from "@girs/gio-2.0";
2
+ import { EventEmitter } from "events";
3
+ const privates = /* @__PURE__ */ new WeakMap();
4
+ class FSWatcher extends EventEmitter {
5
+ constructor(filename, options, listener) {
6
+ super();
7
+ if (!options || typeof options !== "object")
8
+ options = { persistent: true };
9
+ const cancellable = Gio.Cancellable.new();
10
+ const file = Gio.File.new_for_path(filename);
11
+ const watcher = file.monitor(Gio.FileMonitorFlags.NONE, cancellable);
12
+ watcher.connect("changed", changed.bind(this));
13
+ privates.set(this, {
14
+ persistent: options.persistent,
15
+ cancellable,
16
+ // even if never used later on, the monitor needs to be
17
+ // attached to this instance or GJS reference counter
18
+ // will ignore it and no watch will ever happen
19
+ watcher
20
+ });
21
+ if (listener)
22
+ this.on("change", listener);
23
+ }
24
+ close() {
25
+ const { cancellable, persistent } = privates.get(this);
26
+ if (!cancellable.is_cancelled()) {
27
+ cancellable.cancel();
28
+ }
29
+ }
30
+ }
31
+ ;
32
+ function changed(watcher, file, otherFile, eventType) {
33
+ switch (eventType) {
34
+ case Gio.FileMonitorEvent.CHANGES_DONE_HINT:
35
+ this.emit("change", "change", file.get_basename());
36
+ break;
37
+ case Gio.FileMonitorEvent.DELETED:
38
+ case Gio.FileMonitorEvent.CREATED:
39
+ case Gio.FileMonitorEvent.RENAMED:
40
+ case Gio.FileMonitorEvent.MOVED_IN:
41
+ case Gio.FileMonitorEvent.MOVED_OUT:
42
+ this.emit("rename", "rename", file.get_basename());
43
+ break;
44
+ }
45
+ }
46
+ var fs_watcher_default = FSWatcher;
47
+ export {
48
+ FSWatcher,
49
+ fs_watcher_default as default
50
+ };
@@ -0,0 +1,95 @@
1
+ import {
2
+ existsSync,
3
+ readdirSync,
4
+ readFileSync,
5
+ writeFileSync,
6
+ mkdirSync,
7
+ rmdirSync,
8
+ unlinkSync,
9
+ watch,
10
+ mkdtempSync,
11
+ rmSync,
12
+ statSync,
13
+ openSync,
14
+ realpathSync,
15
+ symlinkSync,
16
+ lstatSync
17
+ } from "./sync.js";
18
+ import {
19
+ open,
20
+ close,
21
+ read,
22
+ write,
23
+ rm,
24
+ realpath,
25
+ readdir,
26
+ symlink,
27
+ lstat
28
+ } from "./callback.js";
29
+ import FSWatcher from "./fs-watcher.js";
30
+ import {
31
+ createReadStream,
32
+ ReadStream
33
+ } from "./read-stream.js";
34
+ import * as promises from "./promises.js";
35
+ var src_default = {
36
+ FSWatcher,
37
+ existsSync,
38
+ readdirSync,
39
+ readFileSync,
40
+ writeFileSync,
41
+ mkdirSync,
42
+ rmdirSync,
43
+ unlinkSync,
44
+ mkdtempSync,
45
+ rmSync,
46
+ statSync,
47
+ openSync,
48
+ realpathSync,
49
+ symlinkSync,
50
+ lstatSync,
51
+ watch,
52
+ createReadStream,
53
+ ReadStream,
54
+ promises,
55
+ open,
56
+ close,
57
+ read,
58
+ write,
59
+ rm,
60
+ realpath,
61
+ readdir,
62
+ symlink,
63
+ lstat
64
+ };
65
+ export {
66
+ FSWatcher,
67
+ ReadStream,
68
+ close,
69
+ createReadStream,
70
+ src_default as default,
71
+ existsSync,
72
+ lstat,
73
+ lstatSync,
74
+ mkdirSync,
75
+ mkdtempSync,
76
+ open,
77
+ openSync,
78
+ promises,
79
+ read,
80
+ readFileSync,
81
+ readdir,
82
+ readdirSync,
83
+ realpath,
84
+ realpathSync,
85
+ rm,
86
+ rmSync,
87
+ rmdirSync,
88
+ statSync,
89
+ symlink,
90
+ symlinkSync,
91
+ unlinkSync,
92
+ watch,
93
+ write,
94
+ writeFileSync
95
+ };
@@ -0,0 +1,160 @@
1
+ import Gio from "@girs/gio-2.0";
2
+ import GLib from "@girs/glib-2.0";
3
+ import { warnNotImplemented } from "@gjsify/utils";
4
+ import { join } from "path";
5
+ import { getEncodingFromOptions, encodeUint8Array, decode } from "./encoding.js";
6
+ import { writeFileSync, mkdirSync, rmdirSync, unlinkSync } from "./sync.js";
7
+ import { FileHandle } from "./file-handle.js";
8
+ import { tempDirPath } from "./utils.js";
9
+ import { Dirent } from "./dirent.js";
10
+ import { realpathPromise as realpath } from "@gjsify/deno_std/node/_fs/_fs_realpath";
11
+ import { readdirPromise as readdir } from "@gjsify/deno_std/node/_fs/_fs_readdir";
12
+ import { symlinkPromise as symlink } from "@gjsify/deno_std/node/_fs/_fs_symlink";
13
+ import { lstatPromise as lstat } from "@gjsify/deno_std/node/_fs/_fs_lstat";
14
+ import { statPromise as stat } from "@gjsify/deno_std/node/_fs/_fs_stat";
15
+ async function mkdir(path, options) {
16
+ let recursive;
17
+ let mode = 511;
18
+ if (typeof options === "object") {
19
+ if (options.recursive)
20
+ recursive = options.recursive;
21
+ if (options.mode)
22
+ mode = options.mode;
23
+ } else {
24
+ mode = options;
25
+ }
26
+ const firstPath = mkdirSync(path, {
27
+ recursive,
28
+ mode
29
+ });
30
+ return firstPath;
31
+ }
32
+ async function readFile(path, options = { encoding: null, flag: "r" }) {
33
+ const file = Gio.File.new_for_path(path.toString());
34
+ const [ok, data] = await new Promise((resolve, reject) => {
35
+ file.load_contents_async(null, (self, res) => {
36
+ try {
37
+ resolve(file.load_contents_finish(res));
38
+ } catch (error) {
39
+ reject(error);
40
+ }
41
+ });
42
+ });
43
+ if (!ok) {
44
+ throw new Error("failed to read file");
45
+ }
46
+ return encodeUint8Array(getEncodingFromOptions(options, "buffer"), data);
47
+ }
48
+ async function mkdtemp(prefix, options) {
49
+ const encoding = getEncodingFromOptions(options);
50
+ const path = tempDirPath(prefix);
51
+ await mkdir(
52
+ path,
53
+ { recursive: false, mode: 448 }
54
+ );
55
+ return decode(path, encoding);
56
+ }
57
+ async function writeFile(path, data) {
58
+ return writeFileSync(path, data);
59
+ }
60
+ async function rmdir(path, options) {
61
+ return rmdirSync(path, options);
62
+ }
63
+ async function unlink(path) {
64
+ return unlinkSync(path);
65
+ }
66
+ async function open(path, flags, mode) {
67
+ return new FileHandle({
68
+ path,
69
+ flags,
70
+ mode
71
+ });
72
+ }
73
+ async function write(fd, data, positionOrOffset, encodingOrLength, position) {
74
+ if (typeof data === "string") {
75
+ return _writeStr(fd, data, positionOrOffset, encodingOrLength);
76
+ }
77
+ return _writeBuf(fd, data, positionOrOffset, encodingOrLength, position);
78
+ }
79
+ async function _writeBuf(fd, buffer, offset, length, position) {
80
+ warnNotImplemented("fs.promises.write");
81
+ return {
82
+ bytesWritten: 0,
83
+ buffer
84
+ };
85
+ }
86
+ async function _writeStr(fd, data, position, encoding) {
87
+ warnNotImplemented("fs.promises.write");
88
+ return {
89
+ bytesWritten: 0,
90
+ buffer: data
91
+ };
92
+ }
93
+ async function rm(path, options) {
94
+ const file = Gio.File.new_for_path(path.toString());
95
+ const recursive = options?.recursive || false;
96
+ const dirent = new Dirent(path.toString());
97
+ if (dirent.isDirectory()) {
98
+ const childFiles = await readdir(path, { withFileTypes: true });
99
+ if (!recursive && childFiles.length) {
100
+ throw new Error("Dir is not empty!");
101
+ }
102
+ for (const childFile of childFiles) {
103
+ if (childFile.isDirectory()) {
104
+ await rmdir(join(path.toString(), childFile.name), options);
105
+ } else if (childFile.isFile()) {
106
+ await rm(join(path.toString(), childFile.name), options);
107
+ }
108
+ }
109
+ }
110
+ const ok = await new Promise((resolve, reject) => {
111
+ try {
112
+ file.delete_async(GLib.PRIORITY_DEFAULT, null, (self, res) => {
113
+ try {
114
+ resolve(file.delete_finish(res));
115
+ } catch (error) {
116
+ reject(error);
117
+ }
118
+ });
119
+ } catch (error) {
120
+ reject(error);
121
+ }
122
+ });
123
+ if (!ok) {
124
+ const err = new Error("failed to remove file " + path);
125
+ throw err;
126
+ }
127
+ }
128
+ var promises_default = {
129
+ readFile,
130
+ mkdir,
131
+ mkdtemp,
132
+ realpath,
133
+ readdir,
134
+ writeFile,
135
+ rmdir,
136
+ unlink,
137
+ open,
138
+ write,
139
+ rm,
140
+ lstat,
141
+ symlink,
142
+ stat
143
+ };
144
+ export {
145
+ promises_default as default,
146
+ lstat,
147
+ mkdir,
148
+ mkdtemp,
149
+ open,
150
+ readFile,
151
+ readdir,
152
+ realpath,
153
+ rm,
154
+ rmdir,
155
+ stat,
156
+ symlink,
157
+ unlink,
158
+ write,
159
+ writeFile
160
+ };
@@ -0,0 +1,78 @@
1
+ import GLib from "@girs/glib-2.0";
2
+ import { notImplemented } from "@gjsify/utils";
3
+ import { Buffer } from "buffer";
4
+ import { Readable } from "stream";
5
+ import { URL } from "url";
6
+ function fromFileUrl(url) {
7
+ url = url instanceof URL ? url : new URL(url);
8
+ if (url.protocol != "file:") {
9
+ throw new TypeError("Must be a file URL.");
10
+ }
11
+ return decodeURIComponent(
12
+ url.pathname.replace(/%(?![0-9A-Fa-f]{2})/g, "%25")
13
+ );
14
+ }
15
+ class ReadStream extends Readable {
16
+ close(callback) {
17
+ callback(notImplemented("ReadStream.close"));
18
+ }
19
+ /**
20
+ * The number of bytes that have been read so far.
21
+ * @since v6.4.0
22
+ */
23
+ bytesRead;
24
+ /**
25
+ * The path to the file the stream is reading from as specified in the first
26
+ * argument to `fs.createReadStream()`. If `path` is passed as a string, then`readStream.path` will be a string. If `path` is passed as a `Buffer`, then`readStream.path` will be a
27
+ * `Buffer`. If `fd` is specified, then`readStream.path` will be `undefined`.
28
+ * @since v0.1.93
29
+ */
30
+ path;
31
+ /**
32
+ * This property is `true` if the underlying file has not been opened yet,
33
+ * i.e. before the `'ready'` event is emitted.
34
+ * @since v11.2.0, v10.16.0
35
+ */
36
+ pending;
37
+ constructor(path, opts) {
38
+ path = path instanceof URL ? fromFileUrl(path) : path;
39
+ const hasBadOptions = opts && (opts.start || opts.end);
40
+ if (hasBadOptions) {
41
+ notImplemented(
42
+ `fs.ReadStream.prototype.constructor with unsupported options (${JSON.stringify(opts)})`
43
+ );
44
+ }
45
+ const file = GLib.IOChannel.new_file(path.toString(), "r");
46
+ const buffer = "";
47
+ super({
48
+ autoDestroy: true,
49
+ emitClose: true,
50
+ objectMode: false,
51
+ read: async function(_size) {
52
+ try {
53
+ let n = 0;
54
+ file.read(buffer, 16 * 1024, n);
55
+ this.push(n ? Buffer.from(buffer.slice(0, n)) : null);
56
+ } catch (err) {
57
+ this.destroy(err);
58
+ }
59
+ },
60
+ destroy: (err, cb) => {
61
+ try {
62
+ file.close();
63
+ } catch {
64
+ }
65
+ cb(err);
66
+ }
67
+ });
68
+ this.path = path.toString();
69
+ }
70
+ }
71
+ function createReadStream(path, options) {
72
+ return new ReadStream(path, options);
73
+ }
74
+ export {
75
+ ReadStream,
76
+ createReadStream,
77
+ fromFileUrl
78
+ };
@@ -0,0 +1,45 @@
1
+ import Gio from "@girs/gio-2.0";
2
+ import { Dirent } from "./dirent.js";
3
+ import { basename } from "path";
4
+ class Stats extends Dirent {
5
+ dev;
6
+ ino;
7
+ mode;
8
+ nlink;
9
+ uid;
10
+ gid;
11
+ rdev;
12
+ size;
13
+ blksize;
14
+ blocks;
15
+ atimeMs;
16
+ mtimeMs;
17
+ ctimeMs;
18
+ /** The timestamp indicating the creation time of this file expressed in milliseconds since the POSIX Epoch. */
19
+ get birthtimeMs() {
20
+ const creationDateTime = this._info.get_creation_date_time();
21
+ return creationDateTime.get_microsecond() * 1e3;
22
+ }
23
+ atime;
24
+ mtime;
25
+ ctime;
26
+ /** The timestamp indicating the creation time of this file. */
27
+ get birthtime() {
28
+ const creationDateTime = this._info.get_creation_date_time();
29
+ return new Date(creationDateTime.format_iso8601());
30
+ }
31
+ _info;
32
+ constructor(path, filename) {
33
+ const pathStr = path.toString();
34
+ if (!filename)
35
+ filename = basename(pathStr);
36
+ super(pathStr, filename);
37
+ if (!this._file) {
38
+ throw new TypeError("this._file is not defined!");
39
+ }
40
+ this._info = this._file.query_info("standard::", Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, null);
41
+ }
42
+ }
43
+ export {
44
+ Stats
45
+ };
@@ -0,0 +1,126 @@
1
+ import GLib from "@girs/glib-2.0";
2
+ import Gio from "@girs/gio-2.0";
3
+ import { existsSync } from "@gjsify/utils";
4
+ import { join } from "path";
5
+ import FSWatcher from "./fs-watcher.js";
6
+ import { getEncodingFromOptions, encodeUint8Array, decode } from "./encoding.js";
7
+ import { FileHandle } from "./file-handle.js";
8
+ import { Dirent } from "./dirent.js";
9
+ import { tempDirPath } from "./utils.js";
10
+ import { realpathSync } from "@gjsify/deno_std/node/_fs/_fs_realpath";
11
+ import { readdirSync } from "@gjsify/deno_std/node/_fs/_fs_readdir";
12
+ import { symlinkSync } from "@gjsify/deno_std/node/_fs/_fs_symlink";
13
+ import { lstatSync } from "@gjsify/deno_std/node/_fs/_fs_lstat";
14
+ import { statSync } from "@gjsify/deno_std/node/_fs/_fs_stat";
15
+ function readFileSync(path, options = { encoding: null, flag: "r" }) {
16
+ const file = Gio.File.new_for_path(path);
17
+ const [ok, data] = file.load_contents(null);
18
+ if (!ok) {
19
+ throw new Error("failed to read file");
20
+ }
21
+ return encodeUint8Array(getEncodingFromOptions(options, "buffer"), data);
22
+ }
23
+ function mkdirSync(path, options) {
24
+ let recursive = false;
25
+ let mode = 511;
26
+ if (typeof options === "object") {
27
+ if (options?.recursive)
28
+ recursive = options.recursive;
29
+ if (options?.mode)
30
+ mode = options.mode;
31
+ } else {
32
+ mode = options || 511;
33
+ }
34
+ if (typeof path !== "string") {
35
+ path = path.toString();
36
+ }
37
+ if (typeof mode === "string") {
38
+ throw new TypeError("mode as string is currently not supported!");
39
+ }
40
+ if (GLib.mkdir_with_parents(path, mode) !== 0) {
41
+ throw new Error(`failed to make ${path} directory`);
42
+ }
43
+ if (recursive) {
44
+ return path.split("/")[0];
45
+ }
46
+ return void 0;
47
+ }
48
+ function rmdirSync(path, options) {
49
+ const recursive = options?.recursive || false;
50
+ const childFiles = readdirSync(path, { withFileTypes: true });
51
+ if (!recursive && childFiles.length) {
52
+ throw new Error("Dir is not empty!");
53
+ }
54
+ for (const childFile of childFiles) {
55
+ if (childFile.isDirectory()) {
56
+ rmdirSync(join(path.toString(), childFile.name));
57
+ } else if (childFile.isFile()) {
58
+ rmSync(join(path.toString(), childFile.name));
59
+ }
60
+ }
61
+ const result = GLib.rmdir(path.toString());
62
+ if (result !== 0) {
63
+ throw new Error(`Failed to remove ${path} directory`);
64
+ }
65
+ }
66
+ function unlinkSync(path) {
67
+ GLib.unlink(path);
68
+ }
69
+ function writeFileSync(path, data) {
70
+ GLib.file_set_contents(path, data);
71
+ }
72
+ function watch(filename, options, listener) {
73
+ return new FSWatcher(filename, options, listener);
74
+ }
75
+ function openSync(path, flags, mode) {
76
+ return new FileHandle({ path, flags, mode });
77
+ }
78
+ function mkdtempSync(prefix, options) {
79
+ const encoding = getEncodingFromOptions(options);
80
+ const path = tempDirPath(prefix);
81
+ mkdirSync(
82
+ path,
83
+ { recursive: false, mode: 511 }
84
+ );
85
+ return decode(path, encoding);
86
+ }
87
+ function rmSync(path, options) {
88
+ const file = Gio.File.new_for_path(path.toString());
89
+ const recursive = options?.recursive || false;
90
+ const dirent = new Dirent(path.toString());
91
+ if (dirent.isDirectory()) {
92
+ const childFiles = readdirSync(path, { withFileTypes: true });
93
+ if (!recursive && childFiles.length) {
94
+ throw new Error("Dir is not empty!");
95
+ }
96
+ for (const childFile of childFiles) {
97
+ if (childFile.isDirectory()) {
98
+ rmdirSync(join(path.toString(), childFile.name), options);
99
+ } else if (childFile.isFile()) {
100
+ rmSync(join(path.toString(), childFile.name), options);
101
+ }
102
+ }
103
+ }
104
+ const ok = file.delete(null);
105
+ if (!ok) {
106
+ const err = new Error("failed to remove file " + path);
107
+ throw err;
108
+ }
109
+ }
110
+ export {
111
+ existsSync,
112
+ lstatSync,
113
+ mkdirSync,
114
+ mkdtempSync,
115
+ openSync,
116
+ readFileSync,
117
+ readdirSync,
118
+ realpathSync,
119
+ rmSync,
120
+ rmdirSync,
121
+ statSync,
122
+ symlinkSync,
123
+ unlinkSync,
124
+ watch,
125
+ writeFileSync
126
+ };
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,6 @@
1
+ export * from "./encoding-option.js";
2
+ export * from "./file-read-options.js";
3
+ export * from "./file-read-result.js";
4
+ export * from "./flag-and-open-mode.js";
5
+ export * from "./open-flags.js";
6
+ export * from "./read-options.js";
File without changes
File without changes
@@ -0,0 +1,18 @@
1
+ import { existsSync } from "./sync.js";
2
+ const CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
3
+ function randomName() {
4
+ return [...Array(6)].map(
5
+ () => CHARS[Math.floor(Math.random() * CHARS.length)]
6
+ ).join("");
7
+ }
8
+ function tempDirPath(prefix) {
9
+ let path;
10
+ do {
11
+ path = prefix + randomName();
12
+ } while (existsSync(path));
13
+ return path;
14
+ }
15
+ export {
16
+ randomName,
17
+ tempDirPath
18
+ };