@jsenv/filesystem 4.2.3 → 4.2.4
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/README.md +17 -17
- package/package.json +4 -4
- package/src/assertDirectoryPresence.js +10 -10
- package/src/assertFilePresence.js +10 -10
- package/src/bufferToEtag.js +11 -11
- package/src/collectDirectoryMatchReport.js +38 -38
- package/src/collectFiles.js +35 -35
- package/src/comparePathnames.js +23 -23
- package/src/copyDirectoryContent.js +37 -37
- package/src/copyEntry.js +88 -88
- package/src/directory_url_validation.js +14 -14
- package/src/ensureEmptyDirectory.js +13 -13
- package/src/ensureParentDirectories.js +9 -9
- package/src/ensureWindowsDriveLetter.js +19 -19
- package/src/fileSystemRootUrl.js +1 -1
- package/src/file_url_validation.js +14 -14
- package/src/getRealFileSystemUrlSync.js +24 -24
- package/src/grantPermissionsOnEntry.js +9 -9
- package/src/internal/createWatcher.js +12 -12
- package/src/internal/getCommandArgument.js +7 -7
- package/src/internal/guard_second_call.js +20 -20
- package/src/internal/permissions.js +26 -26
- package/src/internal/read_entry_info.js +8 -8
- package/src/internal/statsToType.js +9 -9
- package/src/internal/track_resources.js +12 -12
- package/src/internal/urlTargetsSameFileSystemPath.js +4 -4
- package/src/listFilesMatching.js +5 -5
- package/src/main.js +35 -35
- package/src/moveDirectoryContent.js +37 -37
- package/src/moveEntry.js +44 -44
- package/src/readDirectory.js +21 -21
- package/src/readEntryModificationTime.js +4 -4
- package/src/readEntryPermissions.js +10 -10
- package/src/readEntryStat.js +27 -27
- package/src/readFile.js +12 -12
- package/src/readFileSync.js +9 -9
- package/src/readSymbolicLink.js +9 -9
- package/src/registerDirectoryLifecycle.js +118 -118
- package/src/registerFileLifecycle.js +66 -66
- package/src/removeEntry.js +81 -81
- package/src/testEntryPermissions.js +15 -15
- package/src/writeDirectory.js +17 -17
- package/src/writeEntryModificationTime.js +10 -10
- package/src/writeEntryPermissions.js +26 -26
- package/src/writeFile.js +16 -16
- package/src/writeFileSync.js +10 -10
- package/src/writeSymbolicLink.js +39 -39
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { readdirSync, statSync } from "node:fs"
|
|
2
|
-
import { URL_META } from "@jsenv/url-meta"
|
|
3
|
-
import { urlToFileSystemPath, urlToRelativeUrl } from "@jsenv/urls"
|
|
1
|
+
import { readdirSync, statSync } from "node:fs";
|
|
2
|
+
import { URL_META } from "@jsenv/url-meta";
|
|
3
|
+
import { urlToFileSystemPath, urlToRelativeUrl } from "@jsenv/urls";
|
|
4
4
|
|
|
5
|
-
import { assertAndNormalizeDirectoryUrl } from "./directory_url_validation.js"
|
|
6
|
-
import { statsToType } from "./internal/statsToType.js"
|
|
7
|
-
import { guardTooFastSecondCallPerFile } from "./internal/guard_second_call.js"
|
|
8
|
-
import { createWatcher } from "./internal/createWatcher.js"
|
|
9
|
-
import { trackResources } from "./internal/track_resources.js"
|
|
5
|
+
import { assertAndNormalizeDirectoryUrl } from "./directory_url_validation.js";
|
|
6
|
+
import { statsToType } from "./internal/statsToType.js";
|
|
7
|
+
import { guardTooFastSecondCallPerFile } from "./internal/guard_second_call.js";
|
|
8
|
+
import { createWatcher } from "./internal/createWatcher.js";
|
|
9
|
+
import { trackResources } from "./internal/track_resources.js";
|
|
10
10
|
|
|
11
|
-
const isLinux = process.platform === "linux"
|
|
11
|
+
const isLinux = process.platform === "linux";
|
|
12
12
|
// linux does not support recursive option
|
|
13
|
-
const fsWatchSupportsRecursive = !isLinux
|
|
13
|
+
const fsWatchSupportsRecursive = !isLinux;
|
|
14
14
|
|
|
15
15
|
export const registerDirectoryLifecycle = (
|
|
16
16
|
source,
|
|
@@ -33,71 +33,71 @@ export const registerDirectoryLifecycle = (
|
|
|
33
33
|
cooldownBetweenFileEvents = 0,
|
|
34
34
|
},
|
|
35
35
|
) => {
|
|
36
|
-
const sourceUrl = assertAndNormalizeDirectoryUrl(source)
|
|
36
|
+
const sourceUrl = assertAndNormalizeDirectoryUrl(source);
|
|
37
37
|
if (!undefinedOrFunction(added)) {
|
|
38
|
-
throw new TypeError(`added must be a function or undefined, got ${added}`)
|
|
38
|
+
throw new TypeError(`added must be a function or undefined, got ${added}`);
|
|
39
39
|
}
|
|
40
40
|
if (!undefinedOrFunction(updated)) {
|
|
41
41
|
throw new TypeError(
|
|
42
42
|
`updated must be a function or undefined, got ${updated}`,
|
|
43
|
-
)
|
|
43
|
+
);
|
|
44
44
|
}
|
|
45
45
|
if (!undefinedOrFunction(removed)) {
|
|
46
46
|
throw new TypeError(
|
|
47
47
|
`removed must be a function or undefined, got ${removed}`,
|
|
48
|
-
)
|
|
48
|
+
);
|
|
49
49
|
}
|
|
50
50
|
if (cooldownBetweenFileEvents) {
|
|
51
51
|
if (added) {
|
|
52
|
-
added = guardTooFastSecondCallPerFile(added, cooldownBetweenFileEvents)
|
|
52
|
+
added = guardTooFastSecondCallPerFile(added, cooldownBetweenFileEvents);
|
|
53
53
|
}
|
|
54
54
|
if (updated) {
|
|
55
55
|
updated = guardTooFastSecondCallPerFile(
|
|
56
56
|
updated,
|
|
57
57
|
cooldownBetweenFileEvents,
|
|
58
|
-
)
|
|
58
|
+
);
|
|
59
59
|
}
|
|
60
60
|
if (removed) {
|
|
61
61
|
removed = guardTooFastSecondCallPerFile(
|
|
62
62
|
removed,
|
|
63
63
|
cooldownBetweenFileEvents,
|
|
64
|
-
)
|
|
64
|
+
);
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
const associations = URL_META.resolveAssociations(
|
|
69
69
|
{ watch: watchPatterns },
|
|
70
70
|
sourceUrl,
|
|
71
|
-
)
|
|
71
|
+
);
|
|
72
72
|
const getWatchPatternValue = ({ url, type }) => {
|
|
73
73
|
if (type === "directory") {
|
|
74
|
-
let firstMeta = false
|
|
74
|
+
let firstMeta = false;
|
|
75
75
|
URL_META.urlChildMayMatch({
|
|
76
76
|
url: `${url}/`,
|
|
77
77
|
associations,
|
|
78
78
|
predicate: ({ watch }) => {
|
|
79
79
|
if (watch) {
|
|
80
|
-
firstMeta = watch
|
|
80
|
+
firstMeta = watch;
|
|
81
81
|
}
|
|
82
|
-
return watch
|
|
82
|
+
return watch;
|
|
83
83
|
},
|
|
84
|
-
})
|
|
85
|
-
return firstMeta
|
|
84
|
+
});
|
|
85
|
+
return firstMeta;
|
|
86
86
|
}
|
|
87
|
-
const { watch } = URL_META.applyAssociations({ url, associations })
|
|
88
|
-
return watch
|
|
89
|
-
}
|
|
90
|
-
const tracker = trackResources()
|
|
91
|
-
const infoMap = new Map()
|
|
87
|
+
const { watch } = URL_META.applyAssociations({ url, associations });
|
|
88
|
+
return watch;
|
|
89
|
+
};
|
|
90
|
+
const tracker = trackResources();
|
|
91
|
+
const infoMap = new Map();
|
|
92
92
|
const readEntryInfo = (url) => {
|
|
93
93
|
try {
|
|
94
|
-
const relativeUrl = urlToRelativeUrl(url, source)
|
|
95
|
-
const previousInfo = infoMap.get(relativeUrl)
|
|
96
|
-
const stats = statSync(new URL(url))
|
|
97
|
-
const type = statsToType(stats)
|
|
94
|
+
const relativeUrl = urlToRelativeUrl(url, source);
|
|
95
|
+
const previousInfo = infoMap.get(relativeUrl);
|
|
96
|
+
const stats = statSync(new URL(url));
|
|
97
|
+
const type = statsToType(stats);
|
|
98
98
|
const patternValue = previousInfo
|
|
99
99
|
? previousInfo.patternValue
|
|
100
|
-
: getWatchPatternValue({ url, type })
|
|
100
|
+
: getWatchPatternValue({ url, type });
|
|
101
101
|
return {
|
|
102
102
|
previousInfo,
|
|
103
103
|
url,
|
|
@@ -106,14 +106,14 @@ export const registerDirectoryLifecycle = (
|
|
|
106
106
|
atimeMs: stats.atimeMs,
|
|
107
107
|
mtimeMs: stats.mtimeMs,
|
|
108
108
|
patternValue,
|
|
109
|
-
}
|
|
109
|
+
};
|
|
110
110
|
} catch (e) {
|
|
111
111
|
if (e.code === "ENOENT") {
|
|
112
|
-
return null
|
|
112
|
+
return null;
|
|
113
113
|
}
|
|
114
|
-
throw e
|
|
114
|
+
throw e;
|
|
115
115
|
}
|
|
116
|
-
}
|
|
116
|
+
};
|
|
117
117
|
|
|
118
118
|
const handleDirectoryEvent = ({
|
|
119
119
|
directoryRelativeUrl,
|
|
@@ -122,101 +122,101 @@ export const registerDirectoryLifecycle = (
|
|
|
122
122
|
}) => {
|
|
123
123
|
if (filename) {
|
|
124
124
|
if (directoryRelativeUrl) {
|
|
125
|
-
handleChange(`${directoryRelativeUrl}/${filename}`)
|
|
126
|
-
return
|
|
125
|
+
handleChange(`${directoryRelativeUrl}/${filename}`);
|
|
126
|
+
return;
|
|
127
127
|
}
|
|
128
|
-
handleChange(`${filename}`)
|
|
129
|
-
return
|
|
128
|
+
handleChange(`${filename}`);
|
|
129
|
+
return;
|
|
130
130
|
}
|
|
131
131
|
if (eventType === "rename") {
|
|
132
132
|
if (!removed && !added) {
|
|
133
|
-
return
|
|
133
|
+
return;
|
|
134
134
|
}
|
|
135
135
|
// we might receive `rename` without filename
|
|
136
136
|
// in that case we try to find ourselves which file was removed.
|
|
137
|
-
let relativeUrlCandidateArray = Array.from(infoMap.keys())
|
|
137
|
+
let relativeUrlCandidateArray = Array.from(infoMap.keys());
|
|
138
138
|
if (recursive && !fsWatchSupportsRecursive) {
|
|
139
139
|
relativeUrlCandidateArray = relativeUrlCandidateArray.filter(
|
|
140
140
|
(relativeUrlCandidate) => {
|
|
141
141
|
if (!directoryRelativeUrl) {
|
|
142
142
|
// ensure entry is top level
|
|
143
143
|
if (relativeUrlCandidate.includes("/")) {
|
|
144
|
-
return false
|
|
144
|
+
return false;
|
|
145
145
|
}
|
|
146
|
-
return true
|
|
146
|
+
return true;
|
|
147
147
|
}
|
|
148
148
|
// entry not inside this directory
|
|
149
149
|
if (!relativeUrlCandidate.startsWith(directoryRelativeUrl)) {
|
|
150
|
-
return false
|
|
150
|
+
return false;
|
|
151
151
|
}
|
|
152
152
|
const afterDirectory = relativeUrlCandidate.slice(
|
|
153
153
|
directoryRelativeUrl.length + 1,
|
|
154
|
-
)
|
|
154
|
+
);
|
|
155
155
|
// deep inside this directory
|
|
156
156
|
if (afterDirectory.includes("/")) {
|
|
157
|
-
return false
|
|
157
|
+
return false;
|
|
158
158
|
}
|
|
159
|
-
return true
|
|
159
|
+
return true;
|
|
160
160
|
},
|
|
161
|
-
)
|
|
161
|
+
);
|
|
162
162
|
}
|
|
163
163
|
const removedEntryRelativeUrl = relativeUrlCandidateArray.find(
|
|
164
164
|
(relativeUrlCandidate) => {
|
|
165
165
|
try {
|
|
166
|
-
statSync(new URL(relativeUrlCandidate, sourceUrl))
|
|
167
|
-
return false
|
|
166
|
+
statSync(new URL(relativeUrlCandidate, sourceUrl));
|
|
167
|
+
return false;
|
|
168
168
|
} catch (e) {
|
|
169
169
|
if (e.code === "ENOENT") {
|
|
170
|
-
return true
|
|
170
|
+
return true;
|
|
171
171
|
}
|
|
172
|
-
throw e
|
|
172
|
+
throw e;
|
|
173
173
|
}
|
|
174
174
|
},
|
|
175
|
-
)
|
|
175
|
+
);
|
|
176
176
|
if (removedEntryRelativeUrl) {
|
|
177
|
-
handleEntryLost(infoMap.get(removedEntryRelativeUrl))
|
|
177
|
+
handleEntryLost(infoMap.get(removedEntryRelativeUrl));
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
|
-
}
|
|
180
|
+
};
|
|
181
181
|
|
|
182
182
|
const handleChange = (relativeUrl) => {
|
|
183
|
-
const entryUrl = new URL(relativeUrl, sourceUrl).href
|
|
184
|
-
const entryInfo = readEntryInfo(entryUrl)
|
|
183
|
+
const entryUrl = new URL(relativeUrl, sourceUrl).href;
|
|
184
|
+
const entryInfo = readEntryInfo(entryUrl);
|
|
185
185
|
if (!entryInfo) {
|
|
186
|
-
const previousEntryInfo = infoMap.get(relativeUrl)
|
|
186
|
+
const previousEntryInfo = infoMap.get(relativeUrl);
|
|
187
187
|
if (!previousEntryInfo) {
|
|
188
188
|
// on MacOS it's possible to receive a "rename" event for
|
|
189
189
|
// a file that does not exists...
|
|
190
|
-
return
|
|
190
|
+
return;
|
|
191
191
|
}
|
|
192
192
|
if (debug) {
|
|
193
|
-
console.debug(`"${relativeUrl}" removed`)
|
|
193
|
+
console.debug(`"${relativeUrl}" removed`);
|
|
194
194
|
}
|
|
195
|
-
handleEntryLost(previousEntryInfo)
|
|
196
|
-
return
|
|
195
|
+
handleEntryLost(previousEntryInfo);
|
|
196
|
+
return;
|
|
197
197
|
}
|
|
198
|
-
const { previousInfo } = entryInfo
|
|
198
|
+
const { previousInfo } = entryInfo;
|
|
199
199
|
if (!previousInfo) {
|
|
200
200
|
if (debug) {
|
|
201
|
-
console.debug(`"${relativeUrl}" added`)
|
|
201
|
+
console.debug(`"${relativeUrl}" added`);
|
|
202
202
|
}
|
|
203
|
-
handleEntryFound(entryInfo)
|
|
204
|
-
return
|
|
203
|
+
handleEntryFound(entryInfo);
|
|
204
|
+
return;
|
|
205
205
|
}
|
|
206
206
|
if (entryInfo.type !== previousInfo.type) {
|
|
207
207
|
// it existed and was replaced by something else
|
|
208
208
|
// we don't handle this as an update. We rather say the resource
|
|
209
209
|
// is lost and something else is found (call removed() then added())
|
|
210
|
-
handleEntryLost(previousInfo)
|
|
211
|
-
handleEntryFound(entryInfo)
|
|
212
|
-
return
|
|
210
|
+
handleEntryLost(previousInfo);
|
|
211
|
+
handleEntryFound(entryInfo);
|
|
212
|
+
return;
|
|
213
213
|
}
|
|
214
214
|
if (entryInfo.type === "directory") {
|
|
215
215
|
// a directory cannot really be updated in way that matters for us
|
|
216
216
|
// filesystem is trying to tell us the directory content have changed
|
|
217
217
|
// but we don't care about that
|
|
218
218
|
// we'll already be notified about what has changed
|
|
219
|
-
return
|
|
219
|
+
return;
|
|
220
220
|
}
|
|
221
221
|
// something has changed at this relativeUrl (the file existed and was not deleted)
|
|
222
222
|
// it's possible to get there without a real update
|
|
@@ -231,29 +231,29 @@ export const registerDirectoryLifecycle = (
|
|
|
231
231
|
// maybe we should exclude some stuff as done in
|
|
232
232
|
// https://github.com/paulmillr/chokidar/blob/b2c4f249b6cfa98c703f0066fb4a56ccd83128b5/lib/nodefs-handler.js#L366
|
|
233
233
|
if (debug) {
|
|
234
|
-
console.debug(`"${relativeUrl}" modified`)
|
|
234
|
+
console.debug(`"${relativeUrl}" modified`);
|
|
235
235
|
}
|
|
236
|
-
handleEntryUpdated(entryInfo)
|
|
237
|
-
}
|
|
236
|
+
handleEntryUpdated(entryInfo);
|
|
237
|
+
};
|
|
238
238
|
const handleEntryFound = (entryInfo, { notify = true } = {}) => {
|
|
239
|
-
infoMap.set(entryInfo.relativeUrl, entryInfo)
|
|
239
|
+
infoMap.set(entryInfo.relativeUrl, entryInfo);
|
|
240
240
|
if (entryInfo.type === "directory") {
|
|
241
|
-
const directoryUrl = `${entryInfo.url}
|
|
241
|
+
const directoryUrl = `${entryInfo.url}/`;
|
|
242
242
|
readdirSync(new URL(directoryUrl)).forEach((entryName) => {
|
|
243
|
-
const childEntryUrl = new URL(entryName, directoryUrl).href
|
|
244
|
-
const childEntryInfo = readEntryInfo(childEntryUrl)
|
|
243
|
+
const childEntryUrl = new URL(entryName, directoryUrl).href;
|
|
244
|
+
const childEntryInfo = readEntryInfo(childEntryUrl);
|
|
245
245
|
if (childEntryInfo && childEntryInfo.patternValue) {
|
|
246
|
-
handleEntryFound(childEntryInfo, { notify })
|
|
246
|
+
handleEntryFound(childEntryInfo, { notify });
|
|
247
247
|
}
|
|
248
|
-
})
|
|
248
|
+
});
|
|
249
249
|
// we must watch manually every directory we find
|
|
250
250
|
if (!fsWatchSupportsRecursive) {
|
|
251
251
|
const watcher = createWatcher(urlToFileSystemPath(entryInfo.url), {
|
|
252
252
|
persistent: keepProcessAlive,
|
|
253
|
-
})
|
|
253
|
+
});
|
|
254
254
|
tracker.registerCleanupCallback(() => {
|
|
255
|
-
watcher.close()
|
|
256
|
-
})
|
|
255
|
+
watcher.close();
|
|
256
|
+
});
|
|
257
257
|
watcher.on("change", (eventType, filename) => {
|
|
258
258
|
handleDirectoryEvent({
|
|
259
259
|
directoryRelativeUrl: entryInfo.relativeUrl,
|
|
@@ -262,8 +262,8 @@ export const registerDirectoryLifecycle = (
|
|
|
262
262
|
filename.replace(/\\/g, "/")
|
|
263
263
|
: "",
|
|
264
264
|
eventType,
|
|
265
|
-
})
|
|
266
|
-
})
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
267
|
}
|
|
268
268
|
}
|
|
269
269
|
if (added && entryInfo.patternValue && notify) {
|
|
@@ -272,22 +272,22 @@ export const registerDirectoryLifecycle = (
|
|
|
272
272
|
type: entryInfo.type,
|
|
273
273
|
patternValue: entryInfo.patternValue,
|
|
274
274
|
mtime: entryInfo.mtimeMs,
|
|
275
|
-
})
|
|
275
|
+
});
|
|
276
276
|
}
|
|
277
|
-
}
|
|
277
|
+
};
|
|
278
278
|
const handleEntryLost = (entryInfo) => {
|
|
279
|
-
infoMap.delete(entryInfo.relativeUrl)
|
|
279
|
+
infoMap.delete(entryInfo.relativeUrl);
|
|
280
280
|
if (removed && entryInfo.patternValue) {
|
|
281
281
|
removed({
|
|
282
282
|
relativeUrl: entryInfo.relativeUrl,
|
|
283
283
|
type: entryInfo.type,
|
|
284
284
|
patternValue: entryInfo.patternValue,
|
|
285
285
|
mtime: entryInfo.mtimeMs,
|
|
286
|
-
})
|
|
286
|
+
});
|
|
287
287
|
}
|
|
288
|
-
}
|
|
288
|
+
};
|
|
289
289
|
const handleEntryUpdated = (entryInfo) => {
|
|
290
|
-
infoMap.set(entryInfo.relativeUrl, entryInfo)
|
|
290
|
+
infoMap.set(entryInfo.relativeUrl, entryInfo);
|
|
291
291
|
if (updated && entryInfo.patternValue) {
|
|
292
292
|
updated({
|
|
293
293
|
relativeUrl: entryInfo.relativeUrl,
|
|
@@ -295,72 +295,72 @@ export const registerDirectoryLifecycle = (
|
|
|
295
295
|
patternValue: entryInfo.patternValue,
|
|
296
296
|
mtime: entryInfo.mtimeMs,
|
|
297
297
|
previousMtime: entryInfo.previousInfo.mtimeMs,
|
|
298
|
-
})
|
|
298
|
+
});
|
|
299
299
|
}
|
|
300
|
-
}
|
|
300
|
+
};
|
|
301
301
|
|
|
302
302
|
readdirSync(new URL(sourceUrl)).forEach((entry) => {
|
|
303
|
-
const entryUrl = new URL(entry, sourceUrl).href
|
|
304
|
-
const entryInfo = readEntryInfo(entryUrl)
|
|
303
|
+
const entryUrl = new URL(entry, sourceUrl).href;
|
|
304
|
+
const entryInfo = readEntryInfo(entryUrl);
|
|
305
305
|
if (entryInfo && entryInfo.patternValue) {
|
|
306
306
|
handleEntryFound(entryInfo, {
|
|
307
307
|
notify: notifyExistent,
|
|
308
|
-
})
|
|
308
|
+
});
|
|
309
309
|
}
|
|
310
|
-
})
|
|
310
|
+
});
|
|
311
311
|
if (debug) {
|
|
312
|
-
const relativeUrls = Array.from(infoMap.keys())
|
|
312
|
+
const relativeUrls = Array.from(infoMap.keys());
|
|
313
313
|
if (relativeUrls.length === 0) {
|
|
314
|
-
console.debug(`No file found`)
|
|
314
|
+
console.debug(`No file found`);
|
|
315
315
|
} else {
|
|
316
316
|
console.debug(
|
|
317
317
|
`${relativeUrls.length} file found:
|
|
318
318
|
${relativeUrls.join("\n")}`,
|
|
319
|
-
)
|
|
319
|
+
);
|
|
320
320
|
}
|
|
321
321
|
}
|
|
322
322
|
const watcher = createWatcher(urlToFileSystemPath(sourceUrl), {
|
|
323
323
|
recursive: recursive && fsWatchSupportsRecursive,
|
|
324
324
|
persistent: keepProcessAlive,
|
|
325
|
-
})
|
|
325
|
+
});
|
|
326
326
|
tracker.registerCleanupCallback(() => {
|
|
327
|
-
watcher.close()
|
|
328
|
-
})
|
|
327
|
+
watcher.close();
|
|
328
|
+
});
|
|
329
329
|
watcher.on("change", (eventType, fileSystemPath) => {
|
|
330
330
|
handleDirectoryEvent({
|
|
331
331
|
...fileSystemPathToDirectoryRelativeUrlAndFilename(fileSystemPath),
|
|
332
332
|
eventType,
|
|
333
|
-
})
|
|
334
|
-
})
|
|
333
|
+
});
|
|
334
|
+
});
|
|
335
335
|
|
|
336
|
-
return tracker.cleanup
|
|
337
|
-
}
|
|
336
|
+
return tracker.cleanup;
|
|
337
|
+
};
|
|
338
338
|
|
|
339
339
|
const undefinedOrFunction = (value) => {
|
|
340
|
-
return typeof value === "undefined" || typeof value === "function"
|
|
341
|
-
}
|
|
340
|
+
return typeof value === "undefined" || typeof value === "function";
|
|
341
|
+
};
|
|
342
342
|
|
|
343
343
|
const fileSystemPathToDirectoryRelativeUrlAndFilename = (path) => {
|
|
344
344
|
if (!path) {
|
|
345
345
|
return {
|
|
346
346
|
directoryRelativeUrl: "",
|
|
347
347
|
filename: "",
|
|
348
|
-
}
|
|
348
|
+
};
|
|
349
349
|
}
|
|
350
350
|
|
|
351
|
-
const normalizedPath = path.replace(/\\/g, "/") // replace back slashes with slashes
|
|
352
|
-
const slashLastIndex = normalizedPath.lastIndexOf("/")
|
|
351
|
+
const normalizedPath = path.replace(/\\/g, "/"); // replace back slashes with slashes
|
|
352
|
+
const slashLastIndex = normalizedPath.lastIndexOf("/");
|
|
353
353
|
if (slashLastIndex === -1) {
|
|
354
354
|
return {
|
|
355
355
|
directoryRelativeUrl: "",
|
|
356
356
|
filename: normalizedPath,
|
|
357
|
-
}
|
|
357
|
+
};
|
|
358
358
|
}
|
|
359
359
|
|
|
360
|
-
const directoryRelativeUrl = normalizedPath.slice(0, slashLastIndex)
|
|
361
|
-
const filename = normalizedPath.slice(slashLastIndex + 1)
|
|
360
|
+
const directoryRelativeUrl = normalizedPath.slice(0, slashLastIndex);
|
|
361
|
+
const filename = normalizedPath.slice(slashLastIndex + 1);
|
|
362
362
|
return {
|
|
363
363
|
directoryRelativeUrl,
|
|
364
364
|
filename,
|
|
365
|
-
}
|
|
366
|
-
}
|
|
365
|
+
};
|
|
366
|
+
};
|