@lvce-editor/file-system-process 2.0.0 → 2.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/dist/index.js +297 -284
- package/package.json +1 -5
package/dist/index.js
CHANGED
|
@@ -108,7 +108,6 @@ class VError extends Error {
|
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
// @ts-ignore
|
|
112
111
|
const getDisplayPath = path => {
|
|
113
112
|
if (path === '') {
|
|
114
113
|
return '<empty string>';
|
|
@@ -116,10 +115,8 @@ const getDisplayPath = path => {
|
|
|
116
115
|
return path;
|
|
117
116
|
};
|
|
118
117
|
class FileNotFoundError extends VError {
|
|
119
|
-
// @ts-ignore
|
|
120
118
|
constructor(path) {
|
|
121
119
|
super(`File not found: '${getDisplayPath(path)}'`);
|
|
122
|
-
// @ts-ignore
|
|
123
120
|
this.code = ENOENT;
|
|
124
121
|
}
|
|
125
122
|
}
|
|
@@ -133,10 +130,6 @@ const Socket = 8;
|
|
|
133
130
|
const Symlink = 9;
|
|
134
131
|
const Unknown = 12;
|
|
135
132
|
|
|
136
|
-
/**
|
|
137
|
-
* @param {import('fs').Dirent|import('fs').StatsBase} dirent
|
|
138
|
-
*/
|
|
139
|
-
// @ts-ignore
|
|
140
133
|
const getDirentType = dirent => {
|
|
141
134
|
if (dirent.isFile()) {
|
|
142
135
|
return File;
|
|
@@ -200,13 +193,256 @@ const isEnoentError = error => {
|
|
|
200
193
|
return isEnoentErrorLinux(error) || isEnoentErrorWindows(error);
|
|
201
194
|
};
|
|
202
195
|
|
|
196
|
+
const rpcs = Object.create(null);
|
|
197
|
+
const set$7 = (id, rpc) => {
|
|
198
|
+
rpcs[id] = rpc;
|
|
199
|
+
};
|
|
200
|
+
const get$1 = id => {
|
|
201
|
+
return rpcs[id];
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
205
|
+
|
|
206
|
+
const create$6 = rpcId => {
|
|
207
|
+
return {
|
|
208
|
+
// @ts-ignore
|
|
209
|
+
invoke(method, ...params) {
|
|
210
|
+
const rpc = get$1(rpcId);
|
|
211
|
+
// @ts-ignore
|
|
212
|
+
return rpc.invoke(method, ...params);
|
|
213
|
+
},
|
|
214
|
+
// @ts-ignore
|
|
215
|
+
invokeAndTransfer(method, ...params) {
|
|
216
|
+
const rpc = get$1(rpcId);
|
|
217
|
+
// @ts-ignore
|
|
218
|
+
return rpc.invokeAndTransfer(method, ...params);
|
|
219
|
+
},
|
|
220
|
+
set(rpc) {
|
|
221
|
+
set$7(rpcId, rpc);
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
};
|
|
225
|
+
const MainProcess$1 = -5;
|
|
226
|
+
const {
|
|
227
|
+
invoke: invoke$3,
|
|
228
|
+
set: set$3
|
|
229
|
+
} = create$6(MainProcess$1);
|
|
230
|
+
const MainProcess = {
|
|
231
|
+
__proto__: null,
|
|
232
|
+
invoke: invoke$3,
|
|
233
|
+
set: set$3
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
const {
|
|
237
|
+
invoke: invoke$1,
|
|
238
|
+
set: set$1
|
|
239
|
+
} = MainProcess;
|
|
240
|
+
|
|
241
|
+
const trash$2 = async path => {
|
|
242
|
+
if (!existsSync(path)) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
// @ts-ignore
|
|
246
|
+
await invoke$1('Trash.trash', path);
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
// @ts-ignore
|
|
250
|
+
const trash$1 = async path => {
|
|
251
|
+
await _trash(path);
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
const getTrashFn = isElectron => {
|
|
255
|
+
if (isElectron) {
|
|
256
|
+
return trash$2;
|
|
257
|
+
}
|
|
258
|
+
return trash$1;
|
|
259
|
+
};
|
|
260
|
+
|
|
203
261
|
const getElectronRunAsNode = () => {
|
|
204
262
|
return process.env.ELECTRON_RUN_AS_NODE;
|
|
205
263
|
};
|
|
206
|
-
process;
|
|
207
264
|
|
|
208
265
|
const isElectron = Boolean(getElectronRunAsNode()) || 'electron' in process.versions;
|
|
209
266
|
|
|
267
|
+
const trash = async path => {
|
|
268
|
+
try {
|
|
269
|
+
const fn = getTrashFn(isElectron);
|
|
270
|
+
await fn(path);
|
|
271
|
+
} catch (error) {
|
|
272
|
+
throw new VError(error, 'Failed to move item to trash');
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
// TODO lazyload chokidar and trash (but doesn't work currently because of bug with jest)
|
|
277
|
+
const assertUri = uri => {
|
|
278
|
+
if (!uri.startsWith('file://')) {
|
|
279
|
+
throw new Error(`path must be a valid file uri`);
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
const copy = async (sourceUri, targetUri) => {
|
|
283
|
+
try {
|
|
284
|
+
assertUri(sourceUri);
|
|
285
|
+
assertUri(targetUri);
|
|
286
|
+
const source = fileURLToPath(sourceUri);
|
|
287
|
+
const target = fileURLToPath(targetUri);
|
|
288
|
+
await fs.cp(source, target, {
|
|
289
|
+
recursive: true
|
|
290
|
+
});
|
|
291
|
+
} catch (error) {
|
|
292
|
+
if (error && error.message && error.message.startsWith('Invalid src or dest: cp returned EINVAL (src and dest cannot be the same)')) {
|
|
293
|
+
throw new VError(`Failed to copy "${sourceUri}" to "${targetUri}": src and dest cannot be the same`);
|
|
294
|
+
}
|
|
295
|
+
throw new VError(error, `Failed to copy "${sourceUri}" to "${targetUri}"`);
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
const readFile = async (uri, encoding = Utf8) => {
|
|
299
|
+
try {
|
|
300
|
+
string(uri);
|
|
301
|
+
assertUri(uri);
|
|
302
|
+
const path = fileURLToPath(uri);
|
|
303
|
+
const content = await fs.readFile(path, encoding);
|
|
304
|
+
return content;
|
|
305
|
+
} catch (error) {
|
|
306
|
+
if (isEnoentError(error)) {
|
|
307
|
+
throw new FileNotFoundError(uri);
|
|
308
|
+
}
|
|
309
|
+
throw new VError(error, `Failed to read file "${uri}"`);
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
const writeFile = async (uri, content, encoding = Utf8) => {
|
|
313
|
+
try {
|
|
314
|
+
assertUri(uri);
|
|
315
|
+
string(uri);
|
|
316
|
+
string(content);
|
|
317
|
+
const path = fileURLToPath(uri);
|
|
318
|
+
// queue would be more correct for concurrent writes but also slower
|
|
319
|
+
// Queue.add(`writeFile/${path}`, () =>
|
|
320
|
+
await fs.writeFile(path, content, encoding);
|
|
321
|
+
} catch (error) {
|
|
322
|
+
if (isEnoentError(error)) {
|
|
323
|
+
throw new FileNotFoundError(uri);
|
|
324
|
+
}
|
|
325
|
+
throw new VError(error, `Failed to write to file "${uri}"`);
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
const isOkayToRemove = path => {
|
|
329
|
+
if (path === '/') {
|
|
330
|
+
return false;
|
|
331
|
+
}
|
|
332
|
+
if (path === '~') {
|
|
333
|
+
return false;
|
|
334
|
+
}
|
|
335
|
+
if (path === os.homedir()) {
|
|
336
|
+
return false;
|
|
337
|
+
}
|
|
338
|
+
return true;
|
|
339
|
+
};
|
|
340
|
+
const remove$1 = async uri => {
|
|
341
|
+
assertUri(uri);
|
|
342
|
+
const path = fileURLToPath(uri);
|
|
343
|
+
if (!isOkayToRemove(path)) {
|
|
344
|
+
console.warn('not removing path');
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// TODO lazyload trash (doesn't work currently because of bug with jest)
|
|
349
|
+
// const { trash } = await import('../../wrap/trash.js')
|
|
350
|
+
try {
|
|
351
|
+
await trash(path);
|
|
352
|
+
} catch (error) {
|
|
353
|
+
throw new VError(error, `Failed to remove "${uri}"`);
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
const toPrettyDirent = dirent => {
|
|
357
|
+
return {
|
|
358
|
+
name: dirent.name,
|
|
359
|
+
type: getDirentType(dirent)
|
|
360
|
+
};
|
|
361
|
+
};
|
|
362
|
+
const readDirWithFileTypes = async uri => {
|
|
363
|
+
try {
|
|
364
|
+
assertUri(uri);
|
|
365
|
+
const path = fileURLToPath(uri);
|
|
366
|
+
const dirents = await fs.readdir(path, {
|
|
367
|
+
withFileTypes: true
|
|
368
|
+
});
|
|
369
|
+
const prettyDirents = dirents.map(toPrettyDirent);
|
|
370
|
+
return prettyDirents;
|
|
371
|
+
} catch (error) {
|
|
372
|
+
throw new VError(error, `Failed to read directory "${uri}"`);
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
const mkdir = async uri => {
|
|
376
|
+
try {
|
|
377
|
+
assertUri(uri);
|
|
378
|
+
const path = fileURLToPath(uri);
|
|
379
|
+
await fs.mkdir(path, {
|
|
380
|
+
recursive: true
|
|
381
|
+
});
|
|
382
|
+
} catch (error) {
|
|
383
|
+
throw new VError(error, `Failed to create directory "${uri}"`);
|
|
384
|
+
}
|
|
385
|
+
};
|
|
386
|
+
const fallbackRename = async (oldUri, newUri) => {
|
|
387
|
+
try {
|
|
388
|
+
const oldPath = fileURLToPath(oldUri);
|
|
389
|
+
const newPath = fileURLToPath(newUri);
|
|
390
|
+
await fs.cp(oldPath, newPath, {
|
|
391
|
+
recursive: true
|
|
392
|
+
});
|
|
393
|
+
await fs.rm(oldPath, {
|
|
394
|
+
recursive: true
|
|
395
|
+
});
|
|
396
|
+
} catch (error) {
|
|
397
|
+
throw new VError(error, `Failed to rename "${oldUri}" to "${newUri}"`);
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
const rename = async (oldUri, newUri) => {
|
|
401
|
+
try {
|
|
402
|
+
const oldPath = fileURLToPath(oldUri);
|
|
403
|
+
const newPath = fileURLToPath(newUri);
|
|
404
|
+
await fs.rename(oldPath, newPath);
|
|
405
|
+
} catch (error) {
|
|
406
|
+
if (error && error.code === EXDEV) {
|
|
407
|
+
return fallbackRename(oldUri, newUri);
|
|
408
|
+
}
|
|
409
|
+
throw new VError(error, `Failed to rename "${oldUri}" to "${newUri}"`);
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
const getPathSeparator = () => {
|
|
413
|
+
return '/';
|
|
414
|
+
};
|
|
415
|
+
const stat = async uri => {
|
|
416
|
+
const path = fileURLToPath(uri);
|
|
417
|
+
const stats = await fs.stat(path);
|
|
418
|
+
const type = getDirentType(stats);
|
|
419
|
+
return type;
|
|
420
|
+
};
|
|
421
|
+
const chmod = async (uri, permissions) => {
|
|
422
|
+
const path = fileURLToPath(uri);
|
|
423
|
+
await fs.chmod(path, permissions);
|
|
424
|
+
};
|
|
425
|
+
const readJson = async uri => {
|
|
426
|
+
try {
|
|
427
|
+
string(uri);
|
|
428
|
+
assertUri(uri);
|
|
429
|
+
const path = fileURLToPath(uri);
|
|
430
|
+
const content = await fs.readFile(path, 'utf8');
|
|
431
|
+
const parsed = JSON.parse(content);
|
|
432
|
+
return parsed;
|
|
433
|
+
} catch (error) {
|
|
434
|
+
if (isEnoentError(error)) {
|
|
435
|
+
throw new FileNotFoundError(uri);
|
|
436
|
+
}
|
|
437
|
+
throw new VError(error, `Failed to read file as json "${uri}"`);
|
|
438
|
+
}
|
|
439
|
+
};
|
|
440
|
+
const getFolderSize = async uri => {
|
|
441
|
+
const path = fileURLToPath(uri);
|
|
442
|
+
const total = await getFolderSizeInternal(path);
|
|
443
|
+
return total;
|
|
444
|
+
};
|
|
445
|
+
|
|
210
446
|
const isMessagePort = value => {
|
|
211
447
|
return value && value instanceof MessagePort;
|
|
212
448
|
};
|
|
@@ -856,7 +1092,7 @@ const set = (id, fn) => {
|
|
|
856
1092
|
const get = id => {
|
|
857
1093
|
return callbacks[id];
|
|
858
1094
|
};
|
|
859
|
-
const remove
|
|
1095
|
+
const remove = id => {
|
|
860
1096
|
delete callbacks[id];
|
|
861
1097
|
};
|
|
862
1098
|
let id = 0;
|
|
@@ -1033,7 +1269,7 @@ const resolve = (id, response) => {
|
|
|
1033
1269
|
return;
|
|
1034
1270
|
}
|
|
1035
1271
|
fn(response);
|
|
1036
|
-
remove
|
|
1272
|
+
remove(id);
|
|
1037
1273
|
};
|
|
1038
1274
|
const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
|
|
1039
1275
|
const getErrorType = prettyError => {
|
|
@@ -1180,7 +1416,7 @@ const send = (transport, method, ...params) => {
|
|
|
1180
1416
|
const message = create$4$1(method, params);
|
|
1181
1417
|
transport.send(message);
|
|
1182
1418
|
};
|
|
1183
|
-
const invoke
|
|
1419
|
+
const invoke = (ipc, method, ...params) => {
|
|
1184
1420
|
return invokeHelper(ipc, method, params, false);
|
|
1185
1421
|
};
|
|
1186
1422
|
const invokeAndTransfer = (ipc, method, ...params) => {
|
|
@@ -1213,7 +1449,7 @@ const createRpc = ipc => {
|
|
|
1213
1449
|
send(ipc, method, ...params);
|
|
1214
1450
|
},
|
|
1215
1451
|
invoke(method, ...params) {
|
|
1216
|
-
return invoke
|
|
1452
|
+
return invoke(ipc, method, ...params);
|
|
1217
1453
|
},
|
|
1218
1454
|
invokeAndTransfer(method, ...params) {
|
|
1219
1455
|
return invokeAndTransfer(ipc, method, ...params);
|
|
@@ -1254,24 +1490,28 @@ const listen$2 = async (module, options) => {
|
|
|
1254
1490
|
const ipc = module.wrap(rawIpc);
|
|
1255
1491
|
return ipc;
|
|
1256
1492
|
};
|
|
1257
|
-
const create$
|
|
1493
|
+
const create$e = async ({
|
|
1258
1494
|
commandMap,
|
|
1259
|
-
messagePort
|
|
1495
|
+
messagePort,
|
|
1496
|
+
requiresSocket
|
|
1260
1497
|
}) => {
|
|
1261
1498
|
// TODO create a commandMap per rpc instance
|
|
1262
1499
|
register(commandMap);
|
|
1263
1500
|
const ipc = await listen$2(IpcChildWithElectronMessagePort$1, {
|
|
1264
1501
|
messagePort
|
|
1265
1502
|
});
|
|
1503
|
+
if (requiresSocket) {
|
|
1504
|
+
ipc.requiresSocket = requiresSocket;
|
|
1505
|
+
}
|
|
1266
1506
|
handleIpc(ipc);
|
|
1267
1507
|
const rpc = createRpc(ipc);
|
|
1268
1508
|
return rpc;
|
|
1269
1509
|
};
|
|
1270
1510
|
const ElectronMessagePortRpcClient = {
|
|
1271
1511
|
__proto__: null,
|
|
1272
|
-
create: create$
|
|
1512
|
+
create: create$e
|
|
1273
1513
|
};
|
|
1274
|
-
const create$
|
|
1514
|
+
const create$d = async ({
|
|
1275
1515
|
commandMap
|
|
1276
1516
|
}) => {
|
|
1277
1517
|
// TODO create a commandMap per rpc instance
|
|
@@ -1283,7 +1523,7 @@ const create$b = async ({
|
|
|
1283
1523
|
};
|
|
1284
1524
|
const ElectronUtilityProcessRpcClient = {
|
|
1285
1525
|
__proto__: null,
|
|
1286
|
-
create: create$
|
|
1526
|
+
create: create$d
|
|
1287
1527
|
};
|
|
1288
1528
|
const create$7 = async ({
|
|
1289
1529
|
commandMap
|
|
@@ -1302,7 +1542,8 @@ const NodeForkedProcessRpcClient = {
|
|
|
1302
1542
|
const create$5 = async ({
|
|
1303
1543
|
commandMap,
|
|
1304
1544
|
request,
|
|
1305
|
-
handle
|
|
1545
|
+
handle,
|
|
1546
|
+
requiresSocket
|
|
1306
1547
|
}) => {
|
|
1307
1548
|
// TODO create a commandMap per rpc instance
|
|
1308
1549
|
register(commandMap);
|
|
@@ -1310,6 +1551,9 @@ const create$5 = async ({
|
|
|
1310
1551
|
request,
|
|
1311
1552
|
handle
|
|
1312
1553
|
});
|
|
1554
|
+
if (requiresSocket) {
|
|
1555
|
+
ipc.requiresSocket = requiresSocket;
|
|
1556
|
+
}
|
|
1313
1557
|
handleIpc(ipc);
|
|
1314
1558
|
const rpc = createRpc(ipc);
|
|
1315
1559
|
return rpc;
|
|
@@ -1354,15 +1598,15 @@ const Auto = argv => {
|
|
|
1354
1598
|
const getModule = method => {
|
|
1355
1599
|
switch (method) {
|
|
1356
1600
|
case NodeForkedProcess:
|
|
1357
|
-
return NodeForkedProcessRpcClient;
|
|
1601
|
+
return NodeForkedProcessRpcClient.create;
|
|
1358
1602
|
case NodeWorker:
|
|
1359
|
-
return NodeWorkerRpcClient;
|
|
1603
|
+
return NodeWorkerRpcClient.create;
|
|
1360
1604
|
case ElectronUtilityProcess:
|
|
1361
|
-
return ElectronUtilityProcessRpcClient;
|
|
1605
|
+
return ElectronUtilityProcessRpcClient.create;
|
|
1362
1606
|
case ElectronMessagePort:
|
|
1363
|
-
return ElectronMessagePortRpcClient;
|
|
1607
|
+
return ElectronMessagePortRpcClient.create;
|
|
1364
1608
|
case WebSocket:
|
|
1365
|
-
return NodeWebSocketRpcClient;
|
|
1609
|
+
return NodeWebSocketRpcClient.create;
|
|
1366
1610
|
default:
|
|
1367
1611
|
throw new Error('unexpected ipc type');
|
|
1368
1612
|
}
|
|
@@ -1372,268 +1616,17 @@ const listen$1 = async ({
|
|
|
1372
1616
|
method,
|
|
1373
1617
|
...params
|
|
1374
1618
|
}) => {
|
|
1375
|
-
const
|
|
1376
|
-
const rpc = await
|
|
1619
|
+
const create = getModule(method);
|
|
1620
|
+
const rpc = await create(params);
|
|
1377
1621
|
return rpc;
|
|
1378
1622
|
};
|
|
1379
1623
|
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
const state = {
|
|
1387
|
-
ipc: undefined
|
|
1388
|
-
};
|
|
1389
|
-
const invoke = (method, ...params) => {
|
|
1390
|
-
return invoke$1(state.ipc, method, ...params);
|
|
1391
|
-
};
|
|
1392
|
-
|
|
1393
|
-
// @ts-ignore
|
|
1394
|
-
const trash$2 = async path => {
|
|
1395
|
-
if (!existsSync(path)) {
|
|
1396
|
-
return;
|
|
1397
|
-
}
|
|
1398
|
-
await invoke('Trash.trash', path);
|
|
1399
|
-
};
|
|
1400
|
-
|
|
1401
|
-
// @ts-ignore
|
|
1402
|
-
const trash$1 = async path => {
|
|
1403
|
-
await _trash(path);
|
|
1404
|
-
};
|
|
1405
|
-
|
|
1406
|
-
const getFn = () => {
|
|
1407
|
-
if (isElectron) {
|
|
1408
|
-
return trash$2;
|
|
1409
|
-
}
|
|
1410
|
-
return trash$1;
|
|
1411
|
-
};
|
|
1412
|
-
|
|
1413
|
-
// @ts-ignore
|
|
1414
|
-
const trash = async path => {
|
|
1415
|
-
try {
|
|
1416
|
-
const fn = getFn();
|
|
1417
|
-
await fn(path);
|
|
1418
|
-
} catch (error) {
|
|
1419
|
-
throw new VError(error, 'Failed to move item to trash');
|
|
1420
|
-
}
|
|
1421
|
-
};
|
|
1422
|
-
|
|
1423
|
-
// TODO lazyload chokidar and trash (but doesn't work currently because of bug with jest)
|
|
1424
|
-
|
|
1425
|
-
// @ts-ignore
|
|
1426
|
-
const assertUri = uri => {
|
|
1427
|
-
if (!uri.startsWith('file://')) {
|
|
1428
|
-
throw new Error(`path must be a valid file uri`);
|
|
1429
|
-
}
|
|
1430
|
-
};
|
|
1431
|
-
const copy = async (sourceUri, targetUri) => {
|
|
1432
|
-
try {
|
|
1433
|
-
assertUri(sourceUri);
|
|
1434
|
-
assertUri(targetUri);
|
|
1435
|
-
const source = fileURLToPath(sourceUri);
|
|
1436
|
-
const target = fileURLToPath(targetUri);
|
|
1437
|
-
await fs.cp(source, target, {
|
|
1438
|
-
recursive: true
|
|
1439
|
-
});
|
|
1440
|
-
} catch (error) {
|
|
1441
|
-
if (error && error.message && error.message.startsWith('Invalid src or dest: cp returned EINVAL (src and dest cannot be the same)')) {
|
|
1442
|
-
throw new VError(`Failed to copy "${sourceUri}" to "${targetUri}": src and dest cannot be the same`);
|
|
1443
|
-
}
|
|
1444
|
-
throw new VError(error, `Failed to copy "${sourceUri}" to "${targetUri}"`);
|
|
1445
|
-
}
|
|
1446
|
-
};
|
|
1447
|
-
|
|
1448
|
-
/**
|
|
1449
|
-
*
|
|
1450
|
-
* @param {string} uri
|
|
1451
|
-
* @param {BufferEncoding} encoding
|
|
1452
|
-
* @returns
|
|
1453
|
-
*/
|
|
1454
|
-
// @ts-ignore
|
|
1455
|
-
const readFile = async (uri, encoding = Utf8) => {
|
|
1456
|
-
try {
|
|
1457
|
-
string(uri);
|
|
1458
|
-
assertUri(uri);
|
|
1459
|
-
const path = fileURLToPath(uri);
|
|
1460
|
-
// @ts-ignore
|
|
1461
|
-
const content = await fs.readFile(path, encoding);
|
|
1462
|
-
return content;
|
|
1463
|
-
} catch (error) {
|
|
1464
|
-
if (isEnoentError(error)) {
|
|
1465
|
-
throw new FileNotFoundError(uri);
|
|
1466
|
-
}
|
|
1467
|
-
throw new VError(error, `Failed to read file "${uri}"`);
|
|
1468
|
-
}
|
|
1469
|
-
};
|
|
1470
|
-
|
|
1471
|
-
/**
|
|
1472
|
-
*
|
|
1473
|
-
* @param {string} uri
|
|
1474
|
-
* @param {string} content
|
|
1475
|
-
* @param {BufferEncoding} encoding
|
|
1476
|
-
*/
|
|
1477
|
-
// @ts-ignore
|
|
1478
|
-
const writeFile = async (uri, content, encoding = Utf8) => {
|
|
1479
|
-
try {
|
|
1480
|
-
assertUri(uri);
|
|
1481
|
-
string(uri);
|
|
1482
|
-
string(content);
|
|
1483
|
-
const path = fileURLToPath(uri);
|
|
1484
|
-
// queue would be more correct for concurrent writes but also slower
|
|
1485
|
-
// Queue.add(`writeFile/${path}`, () =>
|
|
1486
|
-
// @ts-ignore
|
|
1487
|
-
await fs.writeFile(path, content, encoding);
|
|
1488
|
-
} catch (error) {
|
|
1489
|
-
if (isEnoentError(error)) {
|
|
1490
|
-
throw new FileNotFoundError(uri);
|
|
1491
|
-
}
|
|
1492
|
-
throw new VError(error, `Failed to write to file "${uri}"`);
|
|
1493
|
-
}
|
|
1494
|
-
};
|
|
1495
|
-
|
|
1496
|
-
// @ts-ignore
|
|
1497
|
-
const isOkayToRemove = path => {
|
|
1498
|
-
if (path === '/') {
|
|
1499
|
-
return false;
|
|
1500
|
-
}
|
|
1501
|
-
if (path === '~') {
|
|
1502
|
-
return false;
|
|
1503
|
-
}
|
|
1504
|
-
if (path === os.homedir()) {
|
|
1505
|
-
return false;
|
|
1506
|
-
}
|
|
1507
|
-
return true;
|
|
1508
|
-
};
|
|
1509
|
-
|
|
1510
|
-
// @ts-ignore
|
|
1511
|
-
const remove = async uri => {
|
|
1512
|
-
assertUri(uri);
|
|
1513
|
-
const path = fileURLToPath(uri);
|
|
1514
|
-
if (!isOkayToRemove(path)) {
|
|
1515
|
-
console.warn('not removing path');
|
|
1516
|
-
return;
|
|
1517
|
-
}
|
|
1518
|
-
|
|
1519
|
-
// TODO lazyload trash (doesn't work currently because of bug with jest)
|
|
1520
|
-
// const { trash } = await import('../../wrap/trash.js')
|
|
1521
|
-
try {
|
|
1522
|
-
await trash(path);
|
|
1523
|
-
} catch (error) {
|
|
1524
|
-
throw new VError(error, `Failed to remove "${uri}"`);
|
|
1525
|
-
}
|
|
1526
|
-
};
|
|
1527
|
-
|
|
1528
|
-
/**
|
|
1529
|
-
* @param {import('fs').Dirent} dirent
|
|
1530
|
-
*/
|
|
1531
|
-
// @ts-ignore
|
|
1532
|
-
const toPrettyDirent = dirent => {
|
|
1533
|
-
return {
|
|
1534
|
-
name: dirent.name,
|
|
1535
|
-
type: getDirentType(dirent)
|
|
1536
|
-
};
|
|
1537
|
-
};
|
|
1538
|
-
|
|
1539
|
-
// @ts-ignore
|
|
1540
|
-
const readDirWithFileTypes = async uri => {
|
|
1541
|
-
try {
|
|
1542
|
-
assertUri(uri);
|
|
1543
|
-
const path = fileURLToPath(uri);
|
|
1544
|
-
const dirents = await fs.readdir(path, {
|
|
1545
|
-
withFileTypes: true
|
|
1546
|
-
});
|
|
1547
|
-
const prettyDirents = dirents.map(toPrettyDirent);
|
|
1548
|
-
return prettyDirents;
|
|
1549
|
-
} catch (error) {
|
|
1550
|
-
throw new VError(error, `Failed to read directory "${uri}"`);
|
|
1551
|
-
}
|
|
1552
|
-
};
|
|
1553
|
-
|
|
1554
|
-
// @ts-ignore
|
|
1555
|
-
const mkdir = async uri => {
|
|
1556
|
-
try {
|
|
1557
|
-
assertUri(uri);
|
|
1558
|
-
const path = fileURLToPath(uri);
|
|
1559
|
-
await fs.mkdir(path, {
|
|
1560
|
-
recursive: true
|
|
1561
|
-
});
|
|
1562
|
-
} catch (error) {
|
|
1563
|
-
throw new VError(error, `Failed to create directory "${uri}"`);
|
|
1564
|
-
}
|
|
1565
|
-
};
|
|
1566
|
-
|
|
1567
|
-
// @ts-ignore
|
|
1568
|
-
const fallbackRename = async (oldUri, newUri) => {
|
|
1569
|
-
try {
|
|
1570
|
-
const oldPath = fileURLToPath(oldUri);
|
|
1571
|
-
const newPath = fileURLToPath(newUri);
|
|
1572
|
-
await fs.cp(oldPath, newPath, {
|
|
1573
|
-
recursive: true
|
|
1574
|
-
});
|
|
1575
|
-
await fs.rm(oldPath, {
|
|
1576
|
-
recursive: true
|
|
1577
|
-
});
|
|
1578
|
-
} catch (error) {
|
|
1579
|
-
throw new VError(error, `Failed to rename "${oldUri}" to "${newUri}"`);
|
|
1580
|
-
}
|
|
1581
|
-
};
|
|
1582
|
-
|
|
1583
|
-
// @ts-ignore
|
|
1584
|
-
const rename = async (oldUri, newUri) => {
|
|
1585
|
-
try {
|
|
1586
|
-
const oldPath = fileURLToPath(oldUri);
|
|
1587
|
-
const newPath = fileURLToPath(newUri);
|
|
1588
|
-
await fs.rename(oldPath, newPath);
|
|
1589
|
-
} catch (error) {
|
|
1590
|
-
if (error && error.code === EXDEV) {
|
|
1591
|
-
return fallbackRename(oldUri, newUri);
|
|
1592
|
-
}
|
|
1593
|
-
throw new VError(error, `Failed to rename "${oldUri}" to "${newUri}"`);
|
|
1594
|
-
}
|
|
1595
|
-
};
|
|
1596
|
-
const getPathSeparator = () => {
|
|
1597
|
-
return '/';
|
|
1598
|
-
};
|
|
1599
|
-
|
|
1600
|
-
// TODO handle error
|
|
1601
|
-
// @ts-ignore
|
|
1602
|
-
const stat = async uri => {
|
|
1603
|
-
const path = fileURLToPath(uri);
|
|
1604
|
-
const stats = await fs.stat(path);
|
|
1605
|
-
const type = getDirentType(stats);
|
|
1606
|
-
return type;
|
|
1607
|
-
};
|
|
1608
|
-
|
|
1609
|
-
// @ts-ignore
|
|
1610
|
-
const chmod = async (uri, permissions) => {
|
|
1611
|
-
const path = fileURLToPath(uri);
|
|
1612
|
-
await fs.chmod(path, permissions);
|
|
1613
|
-
};
|
|
1614
|
-
|
|
1615
|
-
// @ts-ignore
|
|
1616
|
-
const readJson = async uri => {
|
|
1617
|
-
try {
|
|
1618
|
-
string(uri);
|
|
1619
|
-
assertUri(uri);
|
|
1620
|
-
const path = fileURLToPath(uri);
|
|
1621
|
-
const content = await fs.readFile(path, 'utf8');
|
|
1622
|
-
const parsed = JSON.parse(content);
|
|
1623
|
-
return parsed;
|
|
1624
|
-
} catch (error) {
|
|
1625
|
-
if (isEnoentError(error)) {
|
|
1626
|
-
throw new FileNotFoundError(uri);
|
|
1627
|
-
}
|
|
1628
|
-
throw new VError(error, `Failed to read file as json "${uri}"`);
|
|
1629
|
-
}
|
|
1630
|
-
};
|
|
1631
|
-
|
|
1632
|
-
// @ts-ignore
|
|
1633
|
-
const getFolderSize = async uri => {
|
|
1634
|
-
const path = fileURLToPath(uri);
|
|
1635
|
-
const total = await getFolderSizeInternal(path);
|
|
1636
|
-
return total;
|
|
1624
|
+
const handleElectronMessagePort = async (messagePort, ...params) => {
|
|
1625
|
+
object(messagePort);
|
|
1626
|
+
await listen$1({
|
|
1627
|
+
method: ElectronMessagePort,
|
|
1628
|
+
messagePort
|
|
1629
|
+
});
|
|
1637
1630
|
};
|
|
1638
1631
|
|
|
1639
1632
|
const handleWebSocket = async (handle, request) => {
|
|
@@ -1646,6 +1639,24 @@ const handleWebSocket = async (handle, request) => {
|
|
|
1646
1639
|
});
|
|
1647
1640
|
};
|
|
1648
1641
|
|
|
1642
|
+
const createMainProcessRpc = async port => {
|
|
1643
|
+
try {
|
|
1644
|
+
const rpc = await ElectronMessagePortRpcClient.create({
|
|
1645
|
+
commandMap: {},
|
|
1646
|
+
messagePort: port
|
|
1647
|
+
});
|
|
1648
|
+
return rpc;
|
|
1649
|
+
} catch (error) {
|
|
1650
|
+
throw new VError(error, `Failed to create main process rpc`);
|
|
1651
|
+
}
|
|
1652
|
+
};
|
|
1653
|
+
|
|
1654
|
+
const initialize = async port => {
|
|
1655
|
+
// TODO only connect to main process if platform is electron else not
|
|
1656
|
+
const rpc = await createMainProcessRpc(port);
|
|
1657
|
+
set$1(rpc);
|
|
1658
|
+
};
|
|
1659
|
+
|
|
1649
1660
|
const commandMap = {
|
|
1650
1661
|
'FileSystem.chmod': chmod,
|
|
1651
1662
|
'FileSystem.copy': copy,
|
|
@@ -1655,11 +1666,13 @@ const commandMap = {
|
|
|
1655
1666
|
'FileSystem.readDirWithFileTypes': readDirWithFileTypes,
|
|
1656
1667
|
'FileSystem.readFile': readFile,
|
|
1657
1668
|
'FileSystem.readJson': readJson,
|
|
1658
|
-
'FileSystem.remove': remove,
|
|
1669
|
+
'FileSystem.remove': remove$1,
|
|
1659
1670
|
'FileSystem.rename': rename,
|
|
1660
1671
|
'FileSystem.stat': stat,
|
|
1661
1672
|
'FileSystem.writeFile': writeFile,
|
|
1662
|
-
'
|
|
1673
|
+
'HandleElectronMessagePort.handleElectronMessagePort': handleElectronMessagePort,
|
|
1674
|
+
'HandleWebSocket.handleWebSocket': handleWebSocket,
|
|
1675
|
+
'Initialize.initialize': initialize
|
|
1663
1676
|
};
|
|
1664
1677
|
|
|
1665
1678
|
const listen = async argv => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lvce-editor/file-system-process",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "File System Process",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Lvce Editor",
|
|
@@ -18,10 +18,6 @@
|
|
|
18
18
|
"file-system-process": "bin/fileSystemProcess.js"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"execa": "^9.5.2",
|
|
22
|
-
"open": "^10.1.2",
|
|
23
|
-
"tail": "^2.2.6",
|
|
24
|
-
"tmp-promise": "^3.0.3",
|
|
25
21
|
"trash": "^9.0.0"
|
|
26
22
|
},
|
|
27
23
|
"engines": {
|