@lvce-editor/explorer-view 2.35.0 → 2.36.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.
@@ -850,6 +850,116 @@ const WebWorkerRpcClient = {
850
850
  create: create$2
851
851
  };
852
852
 
853
+ const rpcs = Object.create(null);
854
+ const set$5 = (id, rpc) => {
855
+ rpcs[id] = rpc;
856
+ };
857
+ const get$1 = id => {
858
+ return rpcs[id];
859
+ };
860
+ const RendererWorker$1 = 1;
861
+ const invoke$2 = (method, ...params) => {
862
+ const rpc = get$1(RendererWorker$1);
863
+ // @ts-ignore
864
+ return rpc.invoke(method, ...params);
865
+ };
866
+ const set$2 = rpc => {
867
+ set$5(RendererWorker$1, rpc);
868
+ };
869
+ const RendererWorker = {
870
+ __proto__: null,
871
+ invoke: invoke$2,
872
+ set: set$2
873
+ };
874
+
875
+ const {
876
+ invoke,
877
+ set: set$1
878
+ } = RendererWorker;
879
+
880
+ const remove = async dirent => {
881
+ return invoke('FileSystem.remove', dirent);
882
+ };
883
+ const readDirWithFileTypes = async uri => {
884
+ return invoke('FileSystem.readDirWithFileTypes', uri);
885
+ };
886
+ const getPathSeparator$1 = async root => {
887
+ return invoke('FileSystem.getPathSeparator', root);
888
+ };
889
+ const getRealPath = async path => {
890
+ return invoke('FileSystem.getRealPath', path);
891
+ };
892
+ const stat = async dirent => {
893
+ return invoke('FileSystem.stat', dirent);
894
+ };
895
+ const createFile = async uri => {
896
+ return invoke('FileSystem.writeFile', uri, '');
897
+ };
898
+ const writeFile = async (uri, content) => {
899
+ return invoke('FileSystem.writeFile', uri, content);
900
+ };
901
+ const mkdir = async uri => {
902
+ return invoke('FileSystem.mkdir', uri);
903
+ };
904
+ const rename$1 = async (oldUri, newUri) => {
905
+ return invoke('FileSystem.rename', oldUri, newUri);
906
+ };
907
+ const copy$1 = async (oldUri, newUri) => {
908
+ return invoke('FileSystem.copy', oldUri, newUri);
909
+ };
910
+
911
+ const createNestedPath = async (root, path, pathSeparator) => {
912
+ const parts = path.slice(root.length).split(pathSeparator);
913
+ let currentPath = '';
914
+ for (const part of parts) {
915
+ if (!part) continue;
916
+ currentPath = currentPath ? `${currentPath}${pathSeparator}${part}` : part;
917
+ try {
918
+ await mkdir(`${root}${currentPath}`);
919
+ } catch (error) {
920
+ // Ignore error if directory already exists
921
+ if (!(error instanceof Error && error.message.includes('already exists'))) {
922
+ throw error;
923
+ }
924
+ }
925
+ }
926
+ };
927
+
928
+ const dirname = (pathSeparator, path) => {
929
+ const index = path.lastIndexOf(pathSeparator);
930
+ if (index === -1) {
931
+ return path;
932
+ }
933
+ return path.slice(0, index);
934
+ };
935
+ const join = (pathSeparator, ...parts) => {
936
+ return parts.join(pathSeparator);
937
+ };
938
+ const getBaseName = (pathSeparator, path) => {
939
+ return path.slice(path.lastIndexOf(pathSeparator) + 1);
940
+ };
941
+ const join2 = (path, childPath) => {
942
+ if (path.endsWith('/')) {
943
+ return `${path}${childPath}`;
944
+ }
945
+ return `${path}/${childPath}`;
946
+ };
947
+
948
+ const createNewDirentsAccept = async (newFileName, pathSeparator, absolutePath, root, createFn) => {
949
+ try {
950
+ // Create parent directories if they don't exist
951
+ if (newFileName.includes(pathSeparator)) {
952
+ const parentPath = dirname(pathSeparator, absolutePath);
953
+ await createNestedPath(root, parentPath, pathSeparator);
954
+ }
955
+ await createFn(absolutePath);
956
+ return true;
957
+ } catch (error) {
958
+ console.error(new VError(error, `Failed to create file`));
959
+ return false;
960
+ }
961
+ };
962
+
853
963
  const None$5 = 0;
854
964
  const CreateFile = 1;
855
965
  const CreateFolder = 2;
@@ -901,7 +1011,7 @@ const openInIntegratedTerminal = () => {
901
1011
  const cut = () => {
902
1012
  return i18nString(Cut$1);
903
1013
  };
904
- const copy$1 = () => {
1014
+ const copy = () => {
905
1015
  return i18nString(Copy$1);
906
1016
  };
907
1017
  const paste = () => {
@@ -913,7 +1023,7 @@ const copyPath$1 = () => {
913
1023
  const copyRelativePath$1 = () => {
914
1024
  return i18nString(CopyRelativePath);
915
1025
  };
916
- const rename$1 = () => {
1026
+ const rename = () => {
917
1027
  return i18nString(Rename);
918
1028
  };
919
1029
  const deleteItem = () => {
@@ -982,33 +1092,6 @@ const getPaths = items => {
982
1092
  return items.map(getPath);
983
1093
  };
984
1094
 
985
- const rpcs = Object.create(null);
986
- const set$5 = (id, rpc) => {
987
- rpcs[id] = rpc;
988
- };
989
- const get$1 = id => {
990
- return rpcs[id];
991
- };
992
- const RendererWorker$1 = 1;
993
- const invoke$2 = (method, ...params) => {
994
- const rpc = get$1(RendererWorker$1);
995
- // @ts-ignore
996
- return rpc.invoke(method, ...params);
997
- };
998
- const set$2 = rpc => {
999
- set$5(RendererWorker$1, rpc);
1000
- };
1001
- const RendererWorker = {
1002
- __proto__: null,
1003
- invoke: invoke$2,
1004
- set: set$2
1005
- };
1006
-
1007
- const {
1008
- invoke,
1009
- set: set$1
1010
- } = RendererWorker;
1011
-
1012
1095
  const DELTA_EDITING = 100;
1013
1096
 
1014
1097
  const BlockDevice = 1;
@@ -1109,26 +1192,12 @@ const getParentFolder = (dirents, index, root) => {
1109
1192
  }
1110
1193
  return dirents[index].path;
1111
1194
  };
1112
- const getNewDirentsAccept = async (state, newDirentType, createFn) => {
1113
- const {
1114
- focusedIndex,
1115
- editingValue
1116
- } = state;
1195
+
1196
+ const getNewDirentsAccept = (items, focusedIndex, editingValue, root, pathSeparator, newDirentType) => {
1117
1197
  const newFileName = editingValue;
1118
- const parentFolder = getParentFolder(state.items, focusedIndex, state.root);
1119
- const absolutePath = [parentFolder, newFileName].join(state.pathSeparator);
1120
- // TODO better handle error
1121
- try {
1122
- await createFn(absolutePath);
1123
- } catch (error) {
1124
- console.error(new VError(error, `Failed to create file`));
1125
- // TODO display error
1126
- return {
1127
- dirents: state.items,
1128
- newFocusedIndex: state.focusedIndex
1129
- };
1130
- }
1131
- const parentDirent = focusedIndex >= 0 ? state.items[focusedIndex] : {
1198
+ const parentFolder = getParentFolder(items, focusedIndex, root);
1199
+ const absolutePath = [parentFolder, newFileName].join(pathSeparator);
1200
+ const parentDirent = focusedIndex >= 0 ? items[focusedIndex] : {
1132
1201
  depth: 0};
1133
1202
  const depth = parentDirent.depth + 1;
1134
1203
  const newDirent = {
@@ -1144,14 +1213,11 @@ const getNewDirentsAccept = async (state, newDirentType, createFn) => {
1144
1213
  };
1145
1214
  // @ts-ignore
1146
1215
  newDirent.icon = '';
1147
- let insertIndex = state.focusedIndex;
1216
+ let insertIndex = focusedIndex;
1148
1217
  let deltaPosInSet = 0;
1149
1218
  let posInSet = 1;
1150
1219
  let setSize = 1;
1151
- let i = Math.max(state.focusedIndex, -1) + 1;
1152
- const {
1153
- items
1154
- } = state;
1220
+ let i = Math.max(focusedIndex, -1) + 1;
1155
1221
  // TODO update posinset and setsize of all affected dirents
1156
1222
  for (; i < items.length; i++) {
1157
1223
  const dirent = items[i];
@@ -1180,11 +1246,10 @@ const getNewDirentsAccept = async (state, newDirentType, createFn) => {
1180
1246
  newDirent.setSize = setSize;
1181
1247
  // @ts-ignore
1182
1248
  newDirent.posInSet = posInSet;
1183
- // @ts-ignore
1184
- items.splice(insertIndex + 1, 0, newDirent);
1185
- const newDirents = [...items].filter(item => item.type !== EditingFile && item.type !== EditingFolder);
1249
+ const newItems = [...items];
1250
+ newItems.splice(insertIndex + 1, 0, newDirent);
1186
1251
  return {
1187
- dirents: newDirents,
1252
+ dirents: newItems,
1188
1253
  newFocusedIndex: insertIndex + 1
1189
1254
  };
1190
1255
  };
@@ -1195,7 +1260,11 @@ const acceptCreate = async (state, newDirentType, createFn) => {
1195
1260
  minLineY,
1196
1261
  height,
1197
1262
  itemHeight,
1198
- fileIconCache
1263
+ fileIconCache,
1264
+ pathSeparator,
1265
+ root,
1266
+ focusedIndex,
1267
+ items
1199
1268
  } = state;
1200
1269
  const newFileName = editingValue;
1201
1270
  if (!newFileName) {
@@ -1208,10 +1277,16 @@ const acceptCreate = async (state, newDirentType, createFn) => {
1208
1277
  editingErrorMessage
1209
1278
  };
1210
1279
  }
1280
+ const parentFolder = getParentFolder(items, focusedIndex, root);
1281
+ const absolutePath = join2(parentFolder, newFileName);
1282
+ const successful = await createNewDirentsAccept(newFileName, pathSeparator, absolutePath, root, createFn);
1283
+ if (!successful) {
1284
+ return state;
1285
+ }
1211
1286
  const {
1212
1287
  dirents,
1213
1288
  newFocusedIndex
1214
- } = await getNewDirentsAccept(state, newDirentType, createFn);
1289
+ } = getNewDirentsAccept(items, focusedIndex, editingValue, root, pathSeparator, newDirentType);
1215
1290
  const maxLineY = getExplorerMaxLineY(minLineY, height, itemHeight, dirents.length);
1216
1291
  const visible = dirents.slice(minLineY, maxLineY);
1217
1292
  const {
@@ -1231,37 +1306,6 @@ const acceptCreate = async (state, newDirentType, createFn) => {
1231
1306
  };
1232
1307
  };
1233
1308
 
1234
- const remove = async dirent => {
1235
- return invoke('FileSystem.remove', dirent);
1236
- };
1237
- const readDirWithFileTypes = async uri => {
1238
- return invoke('FileSystem.readDirWithFileTypes', uri);
1239
- };
1240
- const getPathSeparator$1 = async root => {
1241
- return invoke('FileSystem.getPathSeparator', root);
1242
- };
1243
- const getRealPath = async path => {
1244
- return invoke('FileSystem.getRealPath', path);
1245
- };
1246
- const stat = async dirent => {
1247
- return invoke('FileSystem.stat', dirent);
1248
- };
1249
- const createFile = async uri => {
1250
- return invoke('FileSystem.writeFile', uri, '');
1251
- };
1252
- const writeFile = async (uri, content) => {
1253
- return invoke('FileSystem.writeFile', uri, content);
1254
- };
1255
- const mkdir = async uri => {
1256
- return invoke('FileSystem.mkdir', uri);
1257
- };
1258
- const rename = async (oldUri, newUri) => {
1259
- return invoke('FileSystem.rename', oldUri, newUri);
1260
- };
1261
- const copy = async (oldUri, newUri) => {
1262
- return invoke('FileSystem.copy', oldUri, newUri);
1263
- };
1264
-
1265
1309
  const acceptCreateFile = async state => {
1266
1310
  return acceptCreate(state, File, createFile);
1267
1311
  };
@@ -1365,24 +1409,18 @@ const computeExplorerRenamedDirent = (dirents, index, newName) => {
1365
1409
  };
1366
1410
  };
1367
1411
 
1368
- const dirname = (pathSeparator, path) => {
1369
- const index = path.lastIndexOf(pathSeparator);
1370
- if (index === -1) {
1371
- return path;
1372
- }
1373
- return path.slice(0, index);
1374
- };
1375
- const join = (pathSeparator, ...parts) => {
1376
- return parts.join(pathSeparator);
1377
- };
1378
- const getBaseName = (pathSeparator, path) => {
1379
- return path.slice(path.lastIndexOf(pathSeparator) + 1);
1380
- };
1381
- const join2 = (path, childPath) => {
1382
- if (path.endsWith('/')) {
1383
- return `${path}${childPath}`;
1412
+ const createNewDirentsRename = async (renamedDirent, editingValue, pathSeparator) => {
1413
+ try {
1414
+ // TODO this does not work with rename of nested file
1415
+ const oldAbsolutePath = renamedDirent.path;
1416
+ const oldParentPath = dirname(pathSeparator, oldAbsolutePath);
1417
+ const newAbsolutePath = join2(oldParentPath, editingValue);
1418
+ await rename$1(oldAbsolutePath, newAbsolutePath);
1419
+ } catch (error) {
1420
+ console.error(new VError(error, `Failed to rename file`));
1421
+ return false;
1384
1422
  }
1385
- return `${path}/${childPath}`;
1423
+ return true;
1386
1424
  };
1387
1425
 
1388
1426
  const acceptRename = async state => {
@@ -1393,14 +1431,8 @@ const acceptRename = async state => {
1393
1431
  pathSeparator
1394
1432
  } = state;
1395
1433
  const renamedDirent = items[editingIndex];
1396
- try {
1397
- // TODO this does not work with rename of nested file
1398
- const oldAbsolutePath = renamedDirent.path;
1399
- const oldParentPath = dirname(pathSeparator, oldAbsolutePath);
1400
- const newAbsolutePath = join2(oldParentPath, editingValue);
1401
- await rename(oldAbsolutePath, newAbsolutePath);
1402
- } catch (error) {
1403
- console.error(new VError(error, `Failed to rename file`));
1434
+ const successful = await createNewDirentsRename(renamedDirent, editingValue, pathSeparator);
1435
+ if (!successful) {
1404
1436
  return state;
1405
1437
  }
1406
1438
  const {
@@ -1514,7 +1546,7 @@ const cancelTypeAhead = state => {
1514
1546
  };
1515
1547
  };
1516
1548
 
1517
- const isTopLevel$1 = dirent => {
1549
+ const isTopLevel = dirent => {
1518
1550
  return dirent.depth === 1;
1519
1551
  };
1520
1552
 
@@ -1532,7 +1564,7 @@ const collapseAll = state => {
1532
1564
  const {
1533
1565
  items
1534
1566
  } = state;
1535
- const newDirents = items.filter(isTopLevel$1).map(toCollapsedDirent);
1567
+ const newDirents = items.filter(isTopLevel).map(toCollapsedDirent);
1536
1568
  return {
1537
1569
  ...state,
1538
1570
  items: newDirents
@@ -1799,6 +1831,10 @@ const isSymbolicLink = dirent => {
1799
1831
  return dirent.type === Symlink;
1800
1832
  };
1801
1833
 
1834
+ const hasSymbolicLinks = rawDirents => {
1835
+ return rawDirents.some(isSymbolicLink);
1836
+ };
1837
+
1802
1838
  const ENOENT = 'ENOENT';
1803
1839
 
1804
1840
  const getSymlinkType = type => {
@@ -1882,9 +1918,6 @@ const toDisplayDirents = (pathSeparator, rawDirents, parentDirent, excluded) =>
1882
1918
  return result;
1883
1919
  };
1884
1920
 
1885
- const hasSymbolicLinks = rawDirents => {
1886
- return rawDirents.some(isSymbolicLink);
1887
- };
1888
1921
  const getChildDirentsRaw = async uri => {
1889
1922
  const rawDirents = await readDirWithFileTypes(uri);
1890
1923
  array(rawDirents);
@@ -2348,7 +2381,7 @@ const menuEntryCut = {
2348
2381
  };
2349
2382
  const menuEntryCopy = {
2350
2383
  id: 'copy',
2351
- label: copy$1(),
2384
+ label: copy(),
2352
2385
  flags: RestoreFocus,
2353
2386
  command: 'Explorer.handleCopy'
2354
2387
  };
@@ -2372,7 +2405,7 @@ const menuEntryCopyRelativePath = {
2372
2405
  };
2373
2406
  const menuEntryRename = {
2374
2407
  id: 'rename',
2375
- label: rename$1(),
2408
+ label: rename(),
2376
2409
  flags: None$4,
2377
2410
  command: 'Explorer.renameDirent'
2378
2411
  };
@@ -3116,7 +3149,7 @@ const applyOperation = operation => {
3116
3149
  return mkdir(operation.path);
3117
3150
  }
3118
3151
  if (operation.type === 'copy') {
3119
- return copy(operation.from || '', operation.path);
3152
+ return copy$1(operation.from || '', operation.path);
3120
3153
  }
3121
3154
  return writeFile(operation.path, operation.text);
3122
3155
  };
@@ -3330,7 +3363,7 @@ const handleDropIntoFolder = async (state, dirent, index, fileHandles, files, pa
3330
3363
  const baseName = file.name;
3331
3364
  const to = dirent.path + pathSeparator + baseName;
3332
3365
  // @ts-ignore
3333
- await copy(file, to);
3366
+ await copy$1(file, to);
3334
3367
  }
3335
3368
  const childDirents = await getChildDirents(pathSeparator, dirent);
3336
3369
  const mergedDirents = getMergedDirents(items, index, dirent, childDirents);
@@ -3584,7 +3617,7 @@ const handlePasteCopy = async (state, nativeFiles) => {
3584
3617
  for (const source of nativeFiles.files) {
3585
3618
  // @ts-ignore
3586
3619
  const target = join(state.pathSeperator, state.root, getBaseName(state.pathSeparator, source));
3587
- await copy(source, target);
3620
+ await copy$1(source, target);
3588
3621
  }
3589
3622
  // TODO only update folder at which level it changed
3590
3623
  return updateRoot(state);
@@ -3593,7 +3626,7 @@ const handlePasteCopy = async (state, nativeFiles) => {
3593
3626
  const handlePasteCut = async (state, nativeFiles) => {
3594
3627
  for (const source of nativeFiles.files) {
3595
3628
  const target = `${state.root}${state.pathSeparator}${getBaseName(state.pathSeparator, source)}`;
3596
- await rename(source, target);
3629
+ await rename$1(source, target);
3597
3630
  }
3598
3631
  return state;
3599
3632
  };
@@ -4842,9 +4875,20 @@ const getPathPartsToReveal = (root, pathParts, dirents) => {
4842
4875
  return pathParts;
4843
4876
  };
4844
4877
 
4845
- const isTopLevel = dirent => {
4846
- return dirent.depth === 1;
4878
+ const mergeVisibleWithHiddenItems = (visibleItems, hiddenItems) => {
4879
+ const merged = [...visibleItems, ...hiddenItems];
4880
+ const seen = Object.create(null);
4881
+ const unique = [];
4882
+ for (const item of merged) {
4883
+ if (seen[item.path]) {
4884
+ continue;
4885
+ }
4886
+ seen[item.path] = true;
4887
+ unique.push(item);
4888
+ }
4889
+ return unique;
4847
4890
  };
4891
+
4848
4892
  const orderDirents = dirents => {
4849
4893
  if (dirents.length === 0) {
4850
4894
  return dirents;
@@ -4894,19 +4938,6 @@ const getPathPartChildren = async pathPart => {
4894
4938
  const children = await getChildDirents(pathPart.pathSeparator, pathPart);
4895
4939
  return children;
4896
4940
  };
4897
- const mergeVisibleWithHiddenItems = (visibleItems, hiddenItems) => {
4898
- const merged = [...visibleItems, ...hiddenItems];
4899
- const seen = Object.create(null);
4900
- const unique = [];
4901
- for (const item of merged) {
4902
- if (seen[item.path]) {
4903
- continue;
4904
- }
4905
- seen[item.path] = true;
4906
- unique.push(item);
4907
- }
4908
- return unique;
4909
- };
4910
4941
 
4911
4942
  // TODO maybe just insert items into explorer and refresh whole explorer
4912
4943
  const revealItemHidden = async (state, uri) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/explorer-view",
3
- "version": "2.35.0",
3
+ "version": "2.36.0",
4
4
  "description": "Explorer Worker",
5
5
  "repository": {
6
6
  "type": "git",