@jsenv/filesystem 4.2.3 → 4.2.5

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 (47) hide show
  1. package/README.md +17 -17
  2. package/package.json +4 -4
  3. package/src/assertDirectoryPresence.js +10 -10
  4. package/src/assertFilePresence.js +10 -10
  5. package/src/bufferToEtag.js +11 -11
  6. package/src/collectDirectoryMatchReport.js +38 -38
  7. package/src/collectFiles.js +35 -35
  8. package/src/comparePathnames.js +23 -23
  9. package/src/copyDirectoryContent.js +37 -37
  10. package/src/copyEntry.js +88 -88
  11. package/src/directory_url_validation.js +14 -14
  12. package/src/ensureEmptyDirectory.js +13 -13
  13. package/src/ensureParentDirectories.js +9 -9
  14. package/src/ensureWindowsDriveLetter.js +19 -19
  15. package/src/fileSystemRootUrl.js +1 -1
  16. package/src/file_url_validation.js +14 -14
  17. package/src/getRealFileSystemUrlSync.js +24 -24
  18. package/src/grantPermissionsOnEntry.js +9 -9
  19. package/src/internal/createWatcher.js +12 -12
  20. package/src/internal/getCommandArgument.js +7 -7
  21. package/src/internal/guard_second_call.js +20 -20
  22. package/src/internal/permissions.js +26 -26
  23. package/src/internal/read_entry_info.js +8 -8
  24. package/src/internal/statsToType.js +9 -9
  25. package/src/internal/track_resources.js +12 -12
  26. package/src/internal/urlTargetsSameFileSystemPath.js +4 -4
  27. package/src/listFilesMatching.js +5 -5
  28. package/src/main.js +35 -35
  29. package/src/moveDirectoryContent.js +37 -37
  30. package/src/moveEntry.js +44 -44
  31. package/src/readDirectory.js +21 -21
  32. package/src/readEntryModificationTime.js +4 -4
  33. package/src/readEntryPermissions.js +10 -10
  34. package/src/readEntryStat.js +27 -27
  35. package/src/readFile.js +12 -12
  36. package/src/readFileSync.js +9 -9
  37. package/src/readSymbolicLink.js +9 -9
  38. package/src/registerDirectoryLifecycle.js +118 -118
  39. package/src/registerFileLifecycle.js +66 -66
  40. package/src/removeEntry.js +81 -81
  41. package/src/testEntryPermissions.js +15 -15
  42. package/src/writeDirectory.js +17 -17
  43. package/src/writeEntryModificationTime.js +10 -10
  44. package/src/writeEntryPermissions.js +26 -26
  45. package/src/writeFile.js +16 -16
  46. package/src/writeFileSync.js +10 -10
  47. package/src/writeSymbolicLink.js +39 -39
@@ -1,12 +1,12 @@
1
- import { statSync } from "node:fs"
2
- import { dirname, basename } from "node:path"
3
- import { urlToFileSystemPath } from "@jsenv/urls"
1
+ import { statSync } from "node:fs";
2
+ import { dirname, basename } from "node:path";
3
+ import { urlToFileSystemPath } from "@jsenv/urls";
4
4
 
5
- import { assertAndNormalizeFileUrl } from "./file_url_validation.js"
6
- import { guardTooFastSecondCall } from "./internal/guard_second_call.js"
7
- import { statsToType } from "./internal/statsToType.js"
8
- import { createWatcher } from "./internal/createWatcher.js"
9
- import { trackResources } from "./internal/track_resources.js"
5
+ import { assertAndNormalizeFileUrl } from "./file_url_validation.js";
6
+ import { guardTooFastSecondCall } from "./internal/guard_second_call.js";
7
+ import { statsToType } from "./internal/statsToType.js";
8
+ import { createWatcher } from "./internal/createWatcher.js";
9
+ import { trackResources } from "./internal/track_resources.js";
10
10
 
11
11
  export const registerFileLifecycle = (
12
12
  source,
@@ -19,138 +19,138 @@ export const registerFileLifecycle = (
19
19
  cooldownBetweenFileEvents = 0,
20
20
  },
21
21
  ) => {
22
- const sourceUrl = assertAndNormalizeFileUrl(source)
22
+ const sourceUrl = assertAndNormalizeFileUrl(source);
23
23
  if (!undefinedOrFunction(added)) {
24
- throw new TypeError(`added must be a function or undefined, got ${added}`)
24
+ throw new TypeError(`added must be a function or undefined, got ${added}`);
25
25
  }
26
26
  if (!undefinedOrFunction(updated)) {
27
27
  throw new TypeError(
28
28
  `updated must be a function or undefined, got ${updated}`,
29
- )
29
+ );
30
30
  }
31
31
  if (!undefinedOrFunction(removed)) {
32
32
  throw new TypeError(
33
33
  `removed must be a function or undefined, got ${removed}`,
34
- )
34
+ );
35
35
  }
36
36
  if (cooldownBetweenFileEvents) {
37
37
  if (added) {
38
- added = guardTooFastSecondCall(added, cooldownBetweenFileEvents)
38
+ added = guardTooFastSecondCall(added, cooldownBetweenFileEvents);
39
39
  }
40
40
  if (updated) {
41
- updated = guardTooFastSecondCall(updated, cooldownBetweenFileEvents)
41
+ updated = guardTooFastSecondCall(updated, cooldownBetweenFileEvents);
42
42
  }
43
43
  if (removed) {
44
- removed = guardTooFastSecondCall(removed, cooldownBetweenFileEvents)
44
+ removed = guardTooFastSecondCall(removed, cooldownBetweenFileEvents);
45
45
  }
46
46
  }
47
47
 
48
- const tracker = trackResources()
48
+ const tracker = trackResources();
49
49
 
50
50
  const handleFileFound = ({ existent }) => {
51
51
  const fileMutationStopWatching = watchFileMutation(sourceUrl, {
52
52
  updated,
53
53
  removed: () => {
54
- fileMutationStopTracking()
55
- watchFileAdded()
54
+ fileMutationStopTracking();
55
+ watchFileAdded();
56
56
  if (removed) {
57
- removed()
57
+ removed();
58
58
  }
59
59
  },
60
60
  keepProcessAlive,
61
- })
61
+ });
62
62
  const fileMutationStopTracking = tracker.registerCleanupCallback(
63
63
  fileMutationStopWatching,
64
- )
64
+ );
65
65
 
66
66
  if (added) {
67
67
  if (existent) {
68
68
  if (notifyExistent) {
69
- added({ existent: true })
69
+ added({ existent: true });
70
70
  }
71
71
  } else {
72
- added({})
72
+ added({});
73
73
  }
74
74
  }
75
- }
75
+ };
76
76
 
77
77
  const watchFileAdded = () => {
78
78
  const fileCreationStopWatching = watchFileCreation(
79
79
  sourceUrl,
80
80
  () => {
81
- fileCreationgStopTracking()
82
- handleFileFound({ existent: false })
81
+ fileCreationgStopTracking();
82
+ handleFileFound({ existent: false });
83
83
  },
84
84
  keepProcessAlive,
85
- )
85
+ );
86
86
  const fileCreationgStopTracking = tracker.registerCleanupCallback(
87
87
  fileCreationStopWatching,
88
- )
89
- }
88
+ );
89
+ };
90
90
 
91
- const sourceType = entryToTypeOrNull(sourceUrl)
91
+ const sourceType = entryToTypeOrNull(sourceUrl);
92
92
  if (sourceType === null) {
93
93
  if (added) {
94
- watchFileAdded()
94
+ watchFileAdded();
95
95
  } else {
96
96
  throw new Error(
97
97
  `${urlToFileSystemPath(sourceUrl)} must lead to a file, found nothing`,
98
- )
98
+ );
99
99
  }
100
100
  } else if (sourceType === "file") {
101
- handleFileFound({ existent: true })
101
+ handleFileFound({ existent: true });
102
102
  } else {
103
103
  throw new Error(
104
104
  `${urlToFileSystemPath(
105
105
  sourceUrl,
106
106
  )} must lead to a file, type found instead`,
107
- )
107
+ );
108
108
  }
109
109
 
110
- return tracker.cleanup
111
- }
110
+ return tracker.cleanup;
111
+ };
112
112
 
113
113
  const entryToTypeOrNull = (url) => {
114
114
  try {
115
- const stats = statSync(new URL(url))
116
- return statsToType(stats)
115
+ const stats = statSync(new URL(url));
116
+ return statsToType(stats);
117
117
  } catch (e) {
118
118
  if (e.code === "ENOENT") {
119
- return null
119
+ return null;
120
120
  }
121
- throw e
121
+ throw e;
122
122
  }
123
- }
123
+ };
124
124
 
125
125
  const undefinedOrFunction = (value) =>
126
- typeof value === "undefined" || typeof value === "function"
126
+ typeof value === "undefined" || typeof value === "function";
127
127
 
128
128
  const watchFileCreation = (source, callback, keepProcessAlive) => {
129
- const sourcePath = urlToFileSystemPath(source)
130
- const sourceFilename = basename(sourcePath)
131
- const directoryPath = dirname(sourcePath)
129
+ const sourcePath = urlToFileSystemPath(source);
130
+ const sourceFilename = basename(sourcePath);
131
+ const directoryPath = dirname(sourcePath);
132
132
  let directoryWatcher = createWatcher(directoryPath, {
133
133
  persistent: keepProcessAlive,
134
- })
134
+ });
135
135
  directoryWatcher.on("change", (eventType, filename) => {
136
- if (filename && filename !== sourceFilename) return
136
+ if (filename && filename !== sourceFilename) return;
137
137
 
138
- const type = entryToTypeOrNull(source)
138
+ const type = entryToTypeOrNull(source);
139
139
  // ignore if something else with that name gets created
140
140
  // we are only interested into files
141
- if (type !== "file") return
141
+ if (type !== "file") return;
142
142
 
143
- directoryWatcher.close()
144
- directoryWatcher = undefined
145
- callback()
146
- })
143
+ directoryWatcher.close();
144
+ directoryWatcher = undefined;
145
+ callback();
146
+ });
147
147
 
148
148
  return () => {
149
149
  if (directoryWatcher) {
150
- directoryWatcher.close()
150
+ directoryWatcher.close();
151
151
  }
152
- }
153
- }
152
+ };
153
+ };
154
154
 
155
155
  const watchFileMutation = (
156
156
  sourceUrl,
@@ -158,27 +158,27 @@ const watchFileMutation = (
158
158
  ) => {
159
159
  let watcher = createWatcher(urlToFileSystemPath(sourceUrl), {
160
160
  persistent: keepProcessAlive,
161
- })
161
+ });
162
162
 
163
163
  watcher.on("change", () => {
164
- const sourceType = entryToTypeOrNull(sourceUrl)
164
+ const sourceType = entryToTypeOrNull(sourceUrl);
165
165
 
166
166
  if (sourceType === null) {
167
- watcher.close()
168
- watcher = undefined
167
+ watcher.close();
168
+ watcher = undefined;
169
169
  if (removed) {
170
- removed()
170
+ removed();
171
171
  }
172
172
  } else if (sourceType === "file") {
173
173
  if (updated) {
174
- updated()
174
+ updated();
175
175
  }
176
176
  }
177
- })
177
+ });
178
178
 
179
179
  return () => {
180
180
  if (watcher) {
181
- watcher.close()
181
+ watcher.close();
182
182
  }
183
- }
184
- }
183
+ };
184
+ };
@@ -1,14 +1,14 @@
1
- import { unlink, rmdir, openSync, closeSync } from "node:fs"
2
- import { Abort } from "@jsenv/abort"
1
+ import { unlink, rmdir, openSync, closeSync } from "node:fs";
2
+ import { Abort } from "@jsenv/abort";
3
3
  import {
4
4
  ensurePathnameTrailingSlash,
5
5
  urlToFileSystemPath,
6
6
  resolveUrl,
7
- } from "@jsenv/urls"
7
+ } from "@jsenv/urls";
8
8
 
9
- import { assertAndNormalizeFileUrl } from "./file_url_validation.js"
10
- import { readEntryStat } from "./readEntryStat.js"
11
- import { readDirectory } from "./readDirectory.js"
9
+ import { assertAndNormalizeFileUrl } from "./file_url_validation.js";
10
+ import { readEntryStat } from "./readEntryStat.js";
11
+ import { readDirectory } from "./readDirectory.js";
12
12
 
13
13
  export const removeEntry = async (
14
14
  source,
@@ -21,22 +21,22 @@ export const removeEntry = async (
21
21
  onlyContent = false,
22
22
  } = {},
23
23
  ) => {
24
- const sourceUrl = assertAndNormalizeFileUrl(source)
24
+ const sourceUrl = assertAndNormalizeFileUrl(source);
25
25
 
26
- const removeOperation = Abort.startOperation()
27
- removeOperation.addAbortSignal(signal)
26
+ const removeOperation = Abort.startOperation();
27
+ removeOperation.addAbortSignal(signal);
28
28
 
29
29
  try {
30
- removeOperation.throwIfAborted()
30
+ removeOperation.throwIfAborted();
31
31
  const sourceStats = await readEntryStat(sourceUrl, {
32
32
  nullIfNotFound: true,
33
33
  followLink: false,
34
- })
34
+ });
35
35
  if (!sourceStats) {
36
36
  if (allowUseless) {
37
- return
37
+ return;
38
38
  }
39
- throw new Error(`nothing to remove at ${urlToFileSystemPath(sourceUrl)}`)
39
+ throw new Error(`nothing to remove at ${urlToFileSystemPath(sourceUrl)}`);
40
40
  }
41
41
 
42
42
  // https://nodejs.org/dist/latest-v13.x/docs/api/fs.html#fs_class_fs_stats
@@ -54,7 +54,7 @@ export const removeEntry = async (
54
54
  maxRetries,
55
55
  retryDelay,
56
56
  },
57
- )
57
+ );
58
58
  } else if (sourceStats.isDirectory()) {
59
59
  await removeDirectory(ensurePathnameTrailingSlash(sourceUrl), {
60
60
  signal: removeOperation.signal,
@@ -62,42 +62,42 @@ export const removeEntry = async (
62
62
  maxRetries,
63
63
  retryDelay,
64
64
  onlyContent,
65
- })
65
+ });
66
66
  }
67
67
  } finally {
68
- await removeOperation.end()
68
+ await removeOperation.end();
69
69
  }
70
- }
70
+ };
71
71
 
72
72
  const removeNonDirectory = (sourceUrl, { maxRetries, retryDelay }) => {
73
- const sourcePath = urlToFileSystemPath(sourceUrl)
73
+ const sourcePath = urlToFileSystemPath(sourceUrl);
74
74
 
75
- let retryCount = 0
75
+ let retryCount = 0;
76
76
  const attempt = () => {
77
77
  return unlinkNaive(sourcePath, {
78
78
  ...(retryCount >= maxRetries
79
79
  ? {}
80
80
  : {
81
81
  handleTemporaryError: async () => {
82
- retryCount++
82
+ retryCount++;
83
83
  return new Promise((resolve) => {
84
84
  setTimeout(() => {
85
- resolve(attempt())
86
- }, retryCount * retryDelay)
87
- })
85
+ resolve(attempt());
86
+ }, retryCount * retryDelay);
87
+ });
88
88
  },
89
89
  }),
90
- })
91
- }
92
- return attempt()
93
- }
90
+ });
91
+ };
92
+ return attempt();
93
+ };
94
94
 
95
95
  const unlinkNaive = (sourcePath, { handleTemporaryError = null } = {}) => {
96
96
  return new Promise((resolve, reject) => {
97
97
  unlink(sourcePath, (error) => {
98
98
  if (error) {
99
99
  if (error.code === "ENOENT") {
100
- resolve()
100
+ resolve();
101
101
  } else if (
102
102
  handleTemporaryError &&
103
103
  (error.code === "EBUSY" ||
@@ -105,34 +105,34 @@ const unlinkNaive = (sourcePath, { handleTemporaryError = null } = {}) => {
105
105
  error.code === "ENFILE" ||
106
106
  error.code === "ENOENT")
107
107
  ) {
108
- resolve(handleTemporaryError(error))
108
+ resolve(handleTemporaryError(error));
109
109
  } else {
110
- reject(error)
110
+ reject(error);
111
111
  }
112
112
  } else {
113
- resolve()
113
+ resolve();
114
114
  }
115
- })
116
- })
117
- }
115
+ });
116
+ });
117
+ };
118
118
 
119
119
  const removeDirectory = async (
120
120
  rootDirectoryUrl,
121
121
  { signal, maxRetries, retryDelay, recursive, onlyContent },
122
122
  ) => {
123
- const removeDirectoryOperation = Abort.startOperation()
124
- removeDirectoryOperation.addAbortSignal(signal)
123
+ const removeDirectoryOperation = Abort.startOperation();
124
+ removeDirectoryOperation.addAbortSignal(signal);
125
125
 
126
126
  const visit = async (sourceUrl) => {
127
- removeDirectoryOperation.throwIfAborted()
127
+ removeDirectoryOperation.throwIfAborted();
128
128
  const sourceStats = await readEntryStat(sourceUrl, {
129
129
  nullIfNotFound: true,
130
130
  followLink: false,
131
- })
131
+ });
132
132
 
133
133
  // file/directory not found
134
134
  if (sourceStats === null) {
135
- return
135
+ return;
136
136
  }
137
137
 
138
138
  if (
@@ -140,25 +140,25 @@ const removeDirectory = async (
140
140
  sourceStats.isCharacterDevice() ||
141
141
  sourceStats.isBlockDevice()
142
142
  ) {
143
- await visitFile(sourceUrl)
143
+ await visitFile(sourceUrl);
144
144
  } else if (sourceStats.isSymbolicLink()) {
145
- await visitSymbolicLink(sourceUrl)
145
+ await visitSymbolicLink(sourceUrl);
146
146
  } else if (sourceStats.isDirectory()) {
147
- await visitDirectory(`${sourceUrl}/`)
147
+ await visitDirectory(`${sourceUrl}/`);
148
148
  }
149
- }
149
+ };
150
150
 
151
151
  const visitDirectory = async (directoryUrl) => {
152
- const directoryPath = urlToFileSystemPath(directoryUrl)
152
+ const directoryPath = urlToFileSystemPath(directoryUrl);
153
153
  const optionsFromRecursive = recursive
154
154
  ? {
155
155
  handleNotEmptyError: async () => {
156
- await removeDirectoryContent(directoryUrl)
157
- await visitDirectory(directoryUrl)
156
+ await removeDirectoryContent(directoryUrl);
157
+ await visitDirectory(directoryUrl);
158
158
  },
159
159
  }
160
- : {}
161
- removeDirectoryOperation.throwIfAborted()
160
+ : {};
161
+ removeDirectoryOperation.throwIfAborted();
162
162
  await removeDirectoryNaive(directoryPath, {
163
163
  ...optionsFromRecursive,
164
164
  // Workaround for https://github.com/joyent/node/issues/4337
@@ -167,64 +167,64 @@ const removeDirectory = async (
167
167
  handlePermissionError: async (error) => {
168
168
  console.error(
169
169
  `trying to fix windows EPERM after readir on ${directoryPath}`,
170
- )
170
+ );
171
171
 
172
- let openOrCloseError
172
+ let openOrCloseError;
173
173
  try {
174
- const fd = openSync(directoryPath)
175
- closeSync(fd)
174
+ const fd = openSync(directoryPath);
175
+ closeSync(fd);
176
176
  } catch (e) {
177
- openOrCloseError = e
177
+ openOrCloseError = e;
178
178
  }
179
179
 
180
180
  if (openOrCloseError) {
181
181
  if (openOrCloseError.code === "ENOENT") {
182
- return
182
+ return;
183
183
  }
184
184
  console.error(
185
185
  `error while trying to fix windows EPERM after readir on ${directoryPath}: ${openOrCloseError.stack}`,
186
- )
187
- throw error
186
+ );
187
+ throw error;
188
188
  }
189
189
 
190
190
  await removeDirectoryNaive(directoryPath, {
191
191
  ...optionsFromRecursive,
192
- })
192
+ });
193
193
  },
194
194
  }
195
195
  : {}),
196
- })
197
- }
196
+ });
197
+ };
198
198
 
199
199
  const removeDirectoryContent = async (directoryUrl) => {
200
- removeDirectoryOperation.throwIfAborted()
201
- const names = await readDirectory(directoryUrl)
200
+ removeDirectoryOperation.throwIfAborted();
201
+ const names = await readDirectory(directoryUrl);
202
202
  await Promise.all(
203
203
  names.map(async (name) => {
204
- const url = resolveUrl(name, directoryUrl)
205
- await visit(url)
204
+ const url = resolveUrl(name, directoryUrl);
205
+ await visit(url);
206
206
  }),
207
- )
208
- }
207
+ );
208
+ };
209
209
 
210
210
  const visitFile = async (fileUrl) => {
211
- await removeNonDirectory(fileUrl, { maxRetries, retryDelay })
212
- }
211
+ await removeNonDirectory(fileUrl, { maxRetries, retryDelay });
212
+ };
213
213
 
214
214
  const visitSymbolicLink = async (symbolicLinkUrl) => {
215
- await removeNonDirectory(symbolicLinkUrl, { maxRetries, retryDelay })
216
- }
215
+ await removeNonDirectory(symbolicLinkUrl, { maxRetries, retryDelay });
216
+ };
217
217
 
218
218
  try {
219
219
  if (onlyContent) {
220
- await removeDirectoryContent(rootDirectoryUrl)
220
+ await removeDirectoryContent(rootDirectoryUrl);
221
221
  } else {
222
- await visitDirectory(rootDirectoryUrl)
222
+ await visitDirectory(rootDirectoryUrl);
223
223
  }
224
224
  } finally {
225
- await removeDirectoryOperation.end()
225
+ await removeDirectoryOperation.end();
226
226
  }
227
- }
227
+ };
228
228
 
229
229
  const removeDirectoryNaive = (
230
230
  directoryPath,
@@ -234,9 +234,9 @@ const removeDirectoryNaive = (
234
234
  rmdir(directoryPath, (error, lstatObject) => {
235
235
  if (error) {
236
236
  if (handlePermissionError && error.code === "EPERM") {
237
- resolve(handlePermissionError(error))
237
+ resolve(handlePermissionError(error));
238
238
  } else if (error.code === "ENOENT") {
239
- resolve()
239
+ resolve();
240
240
  } else if (
241
241
  handleNotEmptyError &&
242
242
  // linux os
@@ -244,13 +244,13 @@ const removeDirectoryNaive = (
244
244
  // SunOS
245
245
  error.code === "EEXIST")
246
246
  ) {
247
- resolve(handleNotEmptyError(error))
247
+ resolve(handleNotEmptyError(error));
248
248
  } else {
249
- reject(error)
249
+ reject(error);
250
250
  }
251
251
  } else {
252
- resolve(lstatObject)
252
+ resolve(lstatObject);
253
253
  }
254
- })
255
- })
256
- }
254
+ });
255
+ });
256
+ };
@@ -1,14 +1,14 @@
1
- import { promises, constants } from "node:fs"
1
+ import { promises, constants } from "node:fs";
2
2
 
3
- import { assertAndNormalizeFileUrl } from "./file_url_validation.js"
3
+ import { assertAndNormalizeFileUrl } from "./file_url_validation.js";
4
4
 
5
- const { access } = promises
5
+ const { access } = promises;
6
6
  const {
7
7
  // F_OK,
8
8
  R_OK,
9
9
  W_OK,
10
10
  X_OK,
11
- } = constants
11
+ } = constants;
12
12
 
13
13
  export const testEntryPermissions = async (
14
14
  source,
@@ -19,24 +19,24 @@ export const testEntryPermissions = async (
19
19
  allowedIfNotFound = false,
20
20
  } = {},
21
21
  ) => {
22
- const sourceUrl = assertAndNormalizeFileUrl(source)
23
- let binaryFlags = 0
22
+ const sourceUrl = assertAndNormalizeFileUrl(source);
23
+ let binaryFlags = 0;
24
24
 
25
25
  // if (visible) binaryFlags |= F_OK
26
- if (read) binaryFlags |= R_OK
27
- if (write) binaryFlags |= W_OK
28
- if (execute) binaryFlags |= X_OK
26
+ if (read) binaryFlags |= R_OK;
27
+ if (write) binaryFlags |= W_OK;
28
+ if (execute) binaryFlags |= X_OK;
29
29
 
30
30
  try {
31
- await access(new URL(sourceUrl), binaryFlags)
32
- return true
31
+ await access(new URL(sourceUrl), binaryFlags);
32
+ return true;
33
33
  } catch (error) {
34
34
  if (error.code === "ENOENT") {
35
35
  if (allowedIfNotFound) {
36
- return true
36
+ return true;
37
37
  }
38
- throw error
38
+ throw error;
39
39
  }
40
- return false
40
+ return false;
41
41
  }
42
- }
42
+ };
@@ -1,45 +1,45 @@
1
- import { promises } from "node:fs"
2
- import { urlToFileSystemPath } from "@jsenv/urls"
1
+ import { promises } from "node:fs";
2
+ import { urlToFileSystemPath } from "@jsenv/urls";
3
3
 
4
- import { assertAndNormalizeDirectoryUrl } from "./directory_url_validation.js"
5
- import { statsToType } from "./internal/statsToType.js"
6
- import { readEntryStat } from "./readEntryStat.js"
4
+ import { assertAndNormalizeDirectoryUrl } from "./directory_url_validation.js";
5
+ import { statsToType } from "./internal/statsToType.js";
6
+ import { readEntryStat } from "./readEntryStat.js";
7
7
 
8
8
  // https://nodejs.org/dist/latest-v13.x/docs/api/fs.html#fs_fspromises_mkdir_path_options
9
- const { mkdir } = promises
9
+ const { mkdir } = promises;
10
10
 
11
11
  export const writeDirectory = async (
12
12
  destination,
13
13
  { recursive = true, allowUseless = false } = {},
14
14
  ) => {
15
- const destinationUrl = assertAndNormalizeDirectoryUrl(destination)
16
- const destinationPath = urlToFileSystemPath(destinationUrl)
15
+ const destinationUrl = assertAndNormalizeDirectoryUrl(destination);
16
+ const destinationPath = urlToFileSystemPath(destinationUrl);
17
17
 
18
18
  const destinationStats = await readEntryStat(destinationUrl, {
19
19
  nullIfNotFound: true,
20
20
  followLink: false,
21
- })
21
+ });
22
22
 
23
23
  if (destinationStats) {
24
24
  if (destinationStats.isDirectory()) {
25
25
  if (allowUseless) {
26
- return
26
+ return;
27
27
  }
28
- throw new Error(`directory already exists at ${destinationPath}`)
28
+ throw new Error(`directory already exists at ${destinationPath}`);
29
29
  }
30
30
 
31
- const destinationType = statsToType(destinationStats)
31
+ const destinationType = statsToType(destinationStats);
32
32
  throw new Error(
33
33
  `cannot write directory at ${destinationPath} because there is a ${destinationType}`,
34
- )
34
+ );
35
35
  }
36
36
 
37
37
  try {
38
- await mkdir(destinationPath, { recursive })
38
+ await mkdir(destinationPath, { recursive });
39
39
  } catch (error) {
40
40
  if (allowUseless && error.code === "EEXIST") {
41
- return
41
+ return;
42
42
  }
43
- throw error
43
+ throw error;
44
44
  }
45
- }
45
+ };