filefive 1.0.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.
Files changed (127) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/LICENSE +674 -0
  3. package/README.md +53 -0
  4. package/dist/App.js +69 -0
  5. package/dist/Connection.js +193 -0
  6. package/dist/FileSystem.js +13 -0
  7. package/dist/FileWatcher.js +44 -0
  8. package/dist/Local.js +86 -0
  9. package/dist/LocalWatcher.js +48 -0
  10. package/dist/Password.js +51 -0
  11. package/dist/Queue.js +236 -0
  12. package/dist/RemoteWatcher.js +44 -0
  13. package/dist/Session.js +21 -0
  14. package/dist/commands/clear.js +22 -0
  15. package/dist/commands/connect.js +87 -0
  16. package/dist/commands/copy.js +65 -0
  17. package/dist/commands/disconnect.js +12 -0
  18. package/dist/commands/duplicate.js +44 -0
  19. package/dist/commands/getConnection.js +17 -0
  20. package/dist/commands/index.js +42 -0
  21. package/dist/commands/mkdir.js +42 -0
  22. package/dist/commands/read.js +13 -0
  23. package/dist/commands/remove.js +56 -0
  24. package/dist/commands/rename.js +21 -0
  25. package/dist/commands/resolve.js +14 -0
  26. package/dist/commands/saveConnection.js +50 -0
  27. package/dist/commands/saveSettings.js +21 -0
  28. package/dist/commands/settings.js +33 -0
  29. package/dist/commands/unwatch.js +14 -0
  30. package/dist/commands/watch.js +25 -0
  31. package/dist/commands/write.js +17 -0
  32. package/dist/fs/Ftp.js +188 -0
  33. package/dist/fs/Local.js +68 -0
  34. package/dist/fs/SFtp.js +268 -0
  35. package/dist/index.js +69 -0
  36. package/dist/keybindings.json +58 -0
  37. package/dist/log.js +147 -0
  38. package/dist/options.js +5 -0
  39. package/dist/public/76e5e3fe6b35d5e6a980.woff2 +0 -0
  40. package/dist/public/assets/android-chrome-144x144.png +0 -0
  41. package/dist/public/assets/android-chrome-192x192.png +0 -0
  42. package/dist/public/assets/android-chrome-256x256.png +0 -0
  43. package/dist/public/assets/android-chrome-36x36.png +0 -0
  44. package/dist/public/assets/android-chrome-384x384.png +0 -0
  45. package/dist/public/assets/android-chrome-48x48.png +0 -0
  46. package/dist/public/assets/android-chrome-512x512.png +0 -0
  47. package/dist/public/assets/android-chrome-72x72.png +0 -0
  48. package/dist/public/assets/android-chrome-96x96.png +0 -0
  49. package/dist/public/assets/apple-touch-icon-1024x1024.png +0 -0
  50. package/dist/public/assets/apple-touch-icon-114x114.png +0 -0
  51. package/dist/public/assets/apple-touch-icon-120x120.png +0 -0
  52. package/dist/public/assets/apple-touch-icon-144x144.png +0 -0
  53. package/dist/public/assets/apple-touch-icon-152x152.png +0 -0
  54. package/dist/public/assets/apple-touch-icon-167x167.png +0 -0
  55. package/dist/public/assets/apple-touch-icon-180x180.png +0 -0
  56. package/dist/public/assets/apple-touch-icon-57x57.png +0 -0
  57. package/dist/public/assets/apple-touch-icon-60x60.png +0 -0
  58. package/dist/public/assets/apple-touch-icon-72x72.png +0 -0
  59. package/dist/public/assets/apple-touch-icon-76x76.png +0 -0
  60. package/dist/public/assets/apple-touch-icon-precomposed.png +0 -0
  61. package/dist/public/assets/apple-touch-icon.png +0 -0
  62. package/dist/public/assets/apple-touch-startup-image-1125x2436.png +0 -0
  63. package/dist/public/assets/apple-touch-startup-image-1136x640.png +0 -0
  64. package/dist/public/assets/apple-touch-startup-image-1170x2532.png +0 -0
  65. package/dist/public/assets/apple-touch-startup-image-1179x2556.png +0 -0
  66. package/dist/public/assets/apple-touch-startup-image-1242x2208.png +0 -0
  67. package/dist/public/assets/apple-touch-startup-image-1242x2688.png +0 -0
  68. package/dist/public/assets/apple-touch-startup-image-1284x2778.png +0 -0
  69. package/dist/public/assets/apple-touch-startup-image-1290x2796.png +0 -0
  70. package/dist/public/assets/apple-touch-startup-image-1334x750.png +0 -0
  71. package/dist/public/assets/apple-touch-startup-image-1488x2266.png +0 -0
  72. package/dist/public/assets/apple-touch-startup-image-1536x2048.png +0 -0
  73. package/dist/public/assets/apple-touch-startup-image-1620x2160.png +0 -0
  74. package/dist/public/assets/apple-touch-startup-image-1640x2160.png +0 -0
  75. package/dist/public/assets/apple-touch-startup-image-1668x2224.png +0 -0
  76. package/dist/public/assets/apple-touch-startup-image-1668x2388.png +0 -0
  77. package/dist/public/assets/apple-touch-startup-image-1792x828.png +0 -0
  78. package/dist/public/assets/apple-touch-startup-image-2048x1536.png +0 -0
  79. package/dist/public/assets/apple-touch-startup-image-2048x2732.png +0 -0
  80. package/dist/public/assets/apple-touch-startup-image-2160x1620.png +0 -0
  81. package/dist/public/assets/apple-touch-startup-image-2160x1640.png +0 -0
  82. package/dist/public/assets/apple-touch-startup-image-2208x1242.png +0 -0
  83. package/dist/public/assets/apple-touch-startup-image-2224x1668.png +0 -0
  84. package/dist/public/assets/apple-touch-startup-image-2266x1488.png +0 -0
  85. package/dist/public/assets/apple-touch-startup-image-2388x1668.png +0 -0
  86. package/dist/public/assets/apple-touch-startup-image-2436x1125.png +0 -0
  87. package/dist/public/assets/apple-touch-startup-image-2532x1170.png +0 -0
  88. package/dist/public/assets/apple-touch-startup-image-2556x1179.png +0 -0
  89. package/dist/public/assets/apple-touch-startup-image-2688x1242.png +0 -0
  90. package/dist/public/assets/apple-touch-startup-image-2732x2048.png +0 -0
  91. package/dist/public/assets/apple-touch-startup-image-2778x1284.png +0 -0
  92. package/dist/public/assets/apple-touch-startup-image-2796x1290.png +0 -0
  93. package/dist/public/assets/apple-touch-startup-image-640x1136.png +0 -0
  94. package/dist/public/assets/apple-touch-startup-image-750x1334.png +0 -0
  95. package/dist/public/assets/apple-touch-startup-image-828x1792.png +0 -0
  96. package/dist/public/assets/browserconfig.xml +12 -0
  97. package/dist/public/assets/favicon-16x16.png +0 -0
  98. package/dist/public/assets/favicon-32x32.png +0 -0
  99. package/dist/public/assets/favicon-48x48.png +0 -0
  100. package/dist/public/assets/favicon.ico +0 -0
  101. package/dist/public/assets/manifest.webmanifest +68 -0
  102. package/dist/public/assets/mstile-144x144.png +0 -0
  103. package/dist/public/assets/mstile-150x150.png +0 -0
  104. package/dist/public/assets/mstile-310x150.png +0 -0
  105. package/dist/public/assets/mstile-310x310.png +0 -0
  106. package/dist/public/assets/mstile-70x70.png +0 -0
  107. package/dist/public/assets/yandex-browser-50x50.png +0 -0
  108. package/dist/public/assets/yandex-browser-manifest.json +9 -0
  109. package/dist/public/ceb05254cedfa895b512.ttf +0 -0
  110. package/dist/public/f72efa639bb45d29e62f.ttf +0 -0
  111. package/dist/public/index.html +1 -0
  112. package/dist/public/index.js +2 -0
  113. package/dist/public/index.js.LICENSE.txt +43 -0
  114. package/dist/queues/Copy.js +69 -0
  115. package/dist/queues/Download.js +30 -0
  116. package/dist/queues/Duplicate.js +27 -0
  117. package/dist/queues/Queue.js +214 -0
  118. package/dist/queues/Remove.js +82 -0
  119. package/dist/queues/Upload.js +57 -0
  120. package/dist/transform.js +24 -0
  121. package/dist/types.js +46 -0
  122. package/dist/utils/ReferenceCountMap.js +61 -0
  123. package/dist/utils/URI.js +44 -0
  124. package/dist/utils/filter.js +24 -0
  125. package/dist/utils/path.js +12 -0
  126. package/dist/utils/uniqid.js +6 -0
  127. package/package.json +68 -0
@@ -0,0 +1,43 @@
1
+ /*!
2
+ Copyright (c) 2018 Jed Watson.
3
+ Licensed under the MIT License (MIT), see
4
+ http://jedwatson.github.io/classnames
5
+ */
6
+
7
+ /*! @preserve
8
+ * numeral.js
9
+ * version : 2.0.6
10
+ * author : Adam Draper
11
+ * license : MIT
12
+ * http://adamwdraper.github.com/Numeral-js/
13
+ */
14
+
15
+ /**
16
+ * @license React
17
+ * react-dom.production.min.js
18
+ *
19
+ * Copyright (c) Facebook, Inc. and its affiliates.
20
+ *
21
+ * This source code is licensed under the MIT license found in the
22
+ * LICENSE file in the root directory of this source tree.
23
+ */
24
+
25
+ /**
26
+ * @license React
27
+ * react.production.min.js
28
+ *
29
+ * Copyright (c) Facebook, Inc. and its affiliates.
30
+ *
31
+ * This source code is licensed under the MIT license found in the
32
+ * LICENSE file in the root directory of this source tree.
33
+ */
34
+
35
+ /**
36
+ * @license React
37
+ * scheduler.production.min.js
38
+ *
39
+ * Copyright (c) Facebook, Inc. and its affiliates.
40
+ *
41
+ * This source code is licensed under the MIT license found in the
42
+ * LICENSE file in the root directory of this source tree.
43
+ */
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_path_1 = require("node:path");
7
+ const Queue_1 = __importDefault(require("./Queue"));
8
+ const types_1 = require("../types");
9
+ const URI_1 = require("../utils/URI");
10
+ class CopyQueue extends Queue_1.default {
11
+ constructor(connId, src, dest, filter, onState, onConflict, onError, onComplete, watcher, move) {
12
+ super(connId, connId, src, dest, filter, onState, onConflict, onComplete);
13
+ this.onError = onError;
14
+ this.watcher = watcher;
15
+ this.move = move;
16
+ this.touched = new Map();
17
+ }
18
+ async enqueue(paths, dest) {
19
+ if (this.move) { // No filter
20
+ const stat = this.stat(this.from);
21
+ await Promise.all(paths
22
+ .filter(path => path != dest && (0, node_path_1.dirname)(path) != dest)
23
+ .map(async (path) => {
24
+ const from = await stat(path);
25
+ if (from) {
26
+ this.queue.push({
27
+ from,
28
+ dirs: [],
29
+ to: this.dest
30
+ });
31
+ this.totalCnt++;
32
+ this.totalSize++;
33
+ }
34
+ }));
35
+ }
36
+ else {
37
+ await super.enqueue(paths, dest);
38
+ }
39
+ }
40
+ async transmit(fs, from, dirs, to) {
41
+ if (this.stopped) {
42
+ return;
43
+ }
44
+ try {
45
+ let p;
46
+ if (this.move) {
47
+ p = fs.mv(from.path, (0, node_path_1.join)(to, ...dirs, from.name));
48
+ const parent = (0, node_path_1.dirname)(from.path);
49
+ this.touched.set(parent, [...(this.touched.get(parent) ?? []), p]);
50
+ }
51
+ else {
52
+ p = fs.cp(from.path, (0, node_path_1.join)(to, ...dirs, from.name), from.dir);
53
+ }
54
+ await p;
55
+ this.touched.set(to, [...(this.touched.get(to) ?? []), p]);
56
+ }
57
+ catch (error) {
58
+ this.onError(error);
59
+ }
60
+ this.sendState(from.size);
61
+ }
62
+ async finalize() {
63
+ if (this.to != types_1.LocalFileSystemID) {
64
+ await Promise.all(Array.from(this.touched.values()).flat());
65
+ Array.from(this.touched.keys()).forEach(path => this.watcher.refresh((0, URI_1.createURI)(this.to, path)));
66
+ }
67
+ }
68
+ }
69
+ exports.default = CopyQueue;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_path_1 = require("node:path");
7
+ const Queue_1 = __importDefault(require("./Queue"));
8
+ const types_1 = require("../types");
9
+ const Local_1 = require("../Local");
10
+ class DownloadQueue extends Queue_1.default {
11
+ constructor(connId, src, dest, filter, onState, onConflict, onError, onComplete) {
12
+ super(connId, types_1.LocalFileSystemID, src, dest, filter, onState, onConflict, onComplete);
13
+ this.onError = onError;
14
+ }
15
+ async transmit(fs, from, dirs, to) {
16
+ if (this.stopped) {
17
+ return;
18
+ }
19
+ const dest = (0, node_path_1.join)(to, ...dirs, from.name);
20
+ await (0, Local_1.touch)(dest);
21
+ try {
22
+ await fs.get(from.path, dest);
23
+ }
24
+ catch (error) {
25
+ this.onError(error);
26
+ }
27
+ this.sendState(from.size);
28
+ }
29
+ }
30
+ exports.default = DownloadQueue;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const Copy_1 = __importDefault(require("./Copy"));
7
+ const types_1 = require("../types");
8
+ class DuplicateQueue extends Copy_1.default {
9
+ constructor(connId, src, dest, filter, onState, onConflict, onError, onComplete, watcher) {
10
+ super(connId, src, dest, filter, onState, onConflict, onError, onComplete, watcher, false);
11
+ this.newNames = new Map();
12
+ this.resolve({ type: types_1.QueueActionType.Rename }, true);
13
+ }
14
+ async enqueue(paths, dest) {
15
+ await super.enqueue(paths, dest);
16
+ for (const item of this.queue) {
17
+ if (item.dirs.length) {
18
+ const name = item.dirs[0];
19
+ if (!this.newNames.has(name)) {
20
+ this.newNames.set(name, await this.rename(name, item.to));
21
+ }
22
+ item.dirs[0] = this.newNames.get(name);
23
+ }
24
+ }
25
+ }
26
+ }
27
+ exports.default = DuplicateQueue;
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.queues = exports.lsRemote = void 0;
7
+ const node_path_1 = require("node:path");
8
+ const types_1 = require("../types");
9
+ const rxjs_1 = require("rxjs");
10
+ const ramda_1 = require("ramda");
11
+ const Connection_1 = __importDefault(require("../Connection"));
12
+ const Local_1 = require("../Local");
13
+ const filter_1 = require("../utils/filter");
14
+ const lsRemote = (connId) => {
15
+ const cache = new Map();
16
+ return async (path) => {
17
+ if (cache.has(path)) {
18
+ return cache.get(path);
19
+ }
20
+ const list = new Promise(async (resove) => {
21
+ const [conn, close] = await Connection_1.default.transmit(connId);
22
+ conn.ls(path)
23
+ .then(resove)
24
+ .catch(() => resove(null))
25
+ .finally(() => close());
26
+ });
27
+ cache.set(path, list);
28
+ return list;
29
+ };
30
+ };
31
+ exports.lsRemote = lsRemote;
32
+ class TransmitQueue {
33
+ constructor(from, to, src, dest, filter, onState, onConflict, onComplete) {
34
+ this.from = from;
35
+ this.to = to;
36
+ this.src = src;
37
+ this.dest = dest;
38
+ this.filter = filter;
39
+ this.onState = onState;
40
+ this.onConflict = onConflict;
41
+ this.onComplete = onComplete;
42
+ this.queue$ = new rxjs_1.Subject();
43
+ this.queue = [];
44
+ this.pending = [];
45
+ this.stopped = false;
46
+ this.totalCnt = 0;
47
+ this.doneCnt = 0;
48
+ this.totalSize = 0;
49
+ this.doneSize = 0;
50
+ this.transmits = 0;
51
+ this.closed = false;
52
+ }
53
+ async create() {
54
+ await this.enqueue(this.src, this.dest);
55
+ if (this.stopped) {
56
+ return;
57
+ }
58
+ const stat = this.stat(this.to);
59
+ this.processing = this.queue$.subscribe(async ({ from, dirs, to, action }) => {
60
+ let a = action ?? this.action;
61
+ const existing = await stat((0, node_path_1.join)(to, ...dirs, from.name));
62
+ if (existing) {
63
+ if (a) {
64
+ if (a.type == types_1.QueueActionType.Skip) {
65
+ this.sendState(from.size);
66
+ return this.next();
67
+ }
68
+ }
69
+ else {
70
+ this.putOnHold(from, dirs, to, existing);
71
+ return this.next();
72
+ }
73
+ }
74
+ const [fs, close] = await Connection_1.default.transmit(this.from != types_1.LocalFileSystemID ? this.from : this.to);
75
+ this.transmits++;
76
+ (new Promise((resolve) => resolve(existing ?
77
+ this.applyAction(a, from, dirs, to, existing, this.transmit.bind(this, fs)) :
78
+ this.transmit(fs, from, dirs, to)))).then(() => {
79
+ close();
80
+ if (--this.transmits == 0 && this.closed) {
81
+ this.close();
82
+ }
83
+ });
84
+ this.next();
85
+ });
86
+ this.next();
87
+ }
88
+ async enqueue(paths, dest) {
89
+ const ls = this.ls(this.from);
90
+ let matchFilter = (file) => true;
91
+ if (this.filter) {
92
+ const re = (0, filter_1.filterRegExp)(this.filter);
93
+ matchFilter = (file) => {
94
+ const found = re.exec(file.name);
95
+ return this.filter?.invert ?? false ? found === null : found !== null;
96
+ };
97
+ }
98
+ paths = paths.map(node_path_1.normalize).filter(path => !paths.find(ancestor => path.startsWith(ancestor + node_path_1.sep)));
99
+ const add = async (path, to, dirs = []) => {
100
+ if (this.stopped) {
101
+ return;
102
+ }
103
+ const parent = (0, node_path_1.dirname)(path);
104
+ const from = (await ls(parent))?.find((0, ramda_1.whereEq)({ path }));
105
+ if (from) {
106
+ if (from.dir) {
107
+ return Promise.all((await ls(from.path))?.map(child => add(child.path, to, [...dirs, (0, node_path_1.basename)(path)])));
108
+ }
109
+ else {
110
+ if (matchFilter(from)) {
111
+ this.queue.push({ from, to, dirs });
112
+ this.totalCnt++;
113
+ this.totalSize += from.size;
114
+ }
115
+ }
116
+ }
117
+ };
118
+ await Promise.all(paths.map(path => add(path, dest)));
119
+ }
120
+ stop() {
121
+ if (!this.stopped) {
122
+ this.stopped = true;
123
+ this.pending = [];
124
+ this.close();
125
+ }
126
+ }
127
+ resolve(action, forAll = false) {
128
+ forAll && (this.action = action);
129
+ const drained = !this.queue.length;
130
+ this.queue.push(...this.pending
131
+ .splice(0, forAll ? this.pending.length : 1)
132
+ .map(f => ({ from: f.src, dirs: f.dirs, to: f.to, action })));
133
+ drained && this.queue$.next(this.queue.shift());
134
+ if (this.pending.length) {
135
+ const { src, dest } = this.pending[0];
136
+ this.onConflict(src, dest);
137
+ }
138
+ }
139
+ next() {
140
+ if (this.queue.length) {
141
+ this.queue$.next(this.queue.shift());
142
+ }
143
+ else if (!this.pending.length) {
144
+ this.close();
145
+ }
146
+ }
147
+ async close() {
148
+ if (this.processing?.closed === false) {
149
+ this.processing?.unsubscribe();
150
+ }
151
+ this.closed = true;
152
+ if (this.transmits == 0) {
153
+ this.finalize();
154
+ this.onComplete(this.stopped);
155
+ }
156
+ }
157
+ sendState(size) {
158
+ this.doneCnt++;
159
+ this.doneSize += size;
160
+ this.onState({
161
+ totalCnt: this.totalCnt,
162
+ doneCnt: this.doneCnt,
163
+ totalSize: this.totalSize,
164
+ doneSize: this.doneSize,
165
+ pending: this.pending.length
166
+ });
167
+ }
168
+ async applyAction(action, from, dirs, to, existing, transmit) {
169
+ switch (action.type) {
170
+ case types_1.QueueActionType.Replace: {
171
+ await transmit(from, dirs, to);
172
+ break;
173
+ }
174
+ case types_1.QueueActionType.Rename: {
175
+ from.name = await this.rename(from.name, (0, node_path_1.join)(to, ...dirs));
176
+ await transmit(from, dirs, to);
177
+ break;
178
+ }
179
+ }
180
+ }
181
+ putOnHold(src, dirs, to, dest) {
182
+ this.pending.push({ src, dirs, to, dest });
183
+ if (this.pending.length == 1) {
184
+ this.onConflict(src, dest);
185
+ }
186
+ }
187
+ ls(connId) {
188
+ return connId == types_1.LocalFileSystemID ?
189
+ (dir) => Connection_1.default.get(connId).ls(dir) :
190
+ (0, exports.lsRemote)(connId);
191
+ }
192
+ stat(connId) {
193
+ if (connId == types_1.LocalFileSystemID) {
194
+ return (path) => Promise.resolve((0, Local_1.stat)(path));
195
+ }
196
+ const ls = this.ls(connId);
197
+ return async (path) => (await ls((0, node_path_1.dirname)(path)))?.find((0, ramda_1.whereEq)({ path }));
198
+ }
199
+ async rename(name, dir) {
200
+ let { name: oldName, ext } = (0, node_path_1.parse)(name);
201
+ const parts = oldName.match(/^(.+) copy ?(\d*)$/);
202
+ oldName = (parts && parts.length > 2) ? parts[1] : oldName;
203
+ let counter = (parts && parts.length > 2) ? (parts[2] ? parseInt(parts[2]) + 1 : 1) : 1;
204
+ let newName = `${oldName} copy${counter > 1 ? ' ' + counter : ''}`;
205
+ const files = await this.ls(this.to)(dir);
206
+ while (files?.find((0, ramda_1.whereEq)({ name: newName + ext }))) {
207
+ newName = `${oldName} copy ${++counter}`;
208
+ }
209
+ return newName + ext;
210
+ }
211
+ async finalize() { }
212
+ }
213
+ exports.default = TransmitQueue;
214
+ exports.queues = new Map();
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_path_1 = require("node:path");
7
+ const Connection_1 = __importDefault(require("../Connection"));
8
+ const URI_1 = require("../utils/URI");
9
+ const Queue_1 = require("./Queue");
10
+ class RemoveQueue {
11
+ constructor(connId, paths, onState, onError, onComplete, watcher) {
12
+ this.connId = connId;
13
+ this.paths = paths;
14
+ this.onState = onState;
15
+ this.onError = onError;
16
+ this.onComplete = onComplete;
17
+ this.watcher = watcher;
18
+ this.touched = new Set();
19
+ this.stopped = false;
20
+ }
21
+ async create() {
22
+ const paths = this.paths.map(node_path_1.normalize).filter(path => !this.paths.find(ancestor => path.startsWith(ancestor + node_path_1.sep)));
23
+ let totalCnt = 0;
24
+ let doneCnt = 0;
25
+ const ls = (0, Queue_1.lsRemote)(this.connId);
26
+ const add = async (path, tree) => {
27
+ const parent = (0, node_path_1.dirname)(path);
28
+ const file = (await ls(parent))?.find(f => f.name == (0, node_path_1.basename)(path));
29
+ if (!file) {
30
+ return tree;
31
+ }
32
+ this.touched.add(parent);
33
+ let children = [];
34
+ if (file.dir) {
35
+ children = (await Promise.all((await ls(file.path) ?? []).map(({ path }) => add(path, [])))).flat(1);
36
+ }
37
+ totalCnt++;
38
+ return [...tree, { path, dir: file.dir, children }];
39
+ };
40
+ const files = [];
41
+ for (const path of paths) {
42
+ files.push(...await add(path, []));
43
+ }
44
+ if (this.stopped) {
45
+ return;
46
+ }
47
+ const rm = async (item) => {
48
+ for (const child of item.children) {
49
+ await rm(child);
50
+ }
51
+ const [conn, close] = await Connection_1.default.transmit(this.connId);
52
+ if (this.stopped) {
53
+ close();
54
+ return;
55
+ }
56
+ try {
57
+ await conn.rm(item.path, item.dir);
58
+ this.onState({
59
+ totalCnt,
60
+ doneCnt: ++doneCnt,
61
+ totalSize: 0,
62
+ doneSize: 0,
63
+ pending: 0
64
+ });
65
+ }
66
+ catch (error) {
67
+ this.onError(error);
68
+ }
69
+ finally {
70
+ close();
71
+ }
72
+ };
73
+ await Promise.allSettled(files.map(rm));
74
+ this.touched.forEach(path => this.watcher.refresh((0, URI_1.createURI)(this.connId, path)));
75
+ this.onComplete(this.stopped);
76
+ }
77
+ stop() {
78
+ this.stopped = true;
79
+ }
80
+ resolve(action, forAll) { }
81
+ }
82
+ exports.default = RemoveQueue;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_path_1 = require("node:path");
7
+ const Queue_1 = __importDefault(require("./Queue"));
8
+ const types_1 = require("../types");
9
+ const Local_1 = require("../Local");
10
+ const URI_1 = require("../utils/URI");
11
+ class UploadQueue extends Queue_1.default {
12
+ constructor(connId, src, dest, filter, onState, onConflict, onError, onComplete, watcher) {
13
+ super(types_1.LocalFileSystemID, connId, src, dest, filter, onState, onConflict, onComplete);
14
+ this.onError = onError;
15
+ this.watcher = watcher;
16
+ this.touched = new Map();
17
+ }
18
+ async transmit(fs, from, dirs, to) {
19
+ if (this.stopped) {
20
+ return;
21
+ }
22
+ if (!((0, Local_1.stat)(from.path))) {
23
+ return;
24
+ }
25
+ try {
26
+ let targetDir = to;
27
+ for (const dir of dirs) {
28
+ targetDir = (0, node_path_1.join)(targetDir, dir);
29
+ if (this.touched.has(targetDir)) {
30
+ await this.touched.get(targetDir);
31
+ }
32
+ else {
33
+ this.touched.set(targetDir, new Promise(async (resolve) => {
34
+ try {
35
+ await fs.mkdir(targetDir);
36
+ }
37
+ catch (e) { }
38
+ resolve();
39
+ }));
40
+ }
41
+ }
42
+ if (!this.stopped) {
43
+ await fs.put(from.path, (0, node_path_1.join)(targetDir, from.name));
44
+ }
45
+ }
46
+ catch (error) {
47
+ this.onError(error);
48
+ }
49
+ this.sendState(from.size);
50
+ }
51
+ async finalize() {
52
+ this.touched.set(this.dest, Promise.resolve());
53
+ await Promise.all(Array.from(this.touched.values()));
54
+ Array.from(this.touched.keys()).forEach(path => this.watcher.refresh((0, URI_1.createURI)(this.to, path)));
55
+ }
56
+ }
57
+ exports.default = UploadQueue;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.add = add;
7
+ exports.remove = remove;
8
+ exports.default = default_1;
9
+ const uniqid_1 = __importDefault(require("./utils/uniqid"));
10
+ const transformations = [];
11
+ function add(f) {
12
+ const id = (0, uniqid_1.default)();
13
+ transformations.push({ id, f });
14
+ return id;
15
+ }
16
+ function remove(id) {
17
+ const i = transformations.findIndex(t => t.id == id);
18
+ if (i >= 0) {
19
+ transformations.splice(i, 1);
20
+ }
21
+ }
22
+ function default_1(files) {
23
+ return transformations.reduce((files, { f }) => f(files), files);
24
+ }
package/dist/types.js ADDED
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FailureType = exports.QueueActionType = exports.QueueEventType = exports.QueueType = exports.SortOrder = exports.FileTagsAttr = exports.FileState = exports.FileStateAttr = exports.LocalFileSystemID = void 0;
4
+ exports.LocalFileSystemID = 'file://';
5
+ exports.FileStateAttr = Symbol.for('state');
6
+ var FileState;
7
+ (function (FileState) {
8
+ FileState["Creating"] = "creating";
9
+ FileState["Renaming"] = "renaming";
10
+ })(FileState || (exports.FileState = FileState = {}));
11
+ exports.FileTagsAttr = Symbol.for('tags');
12
+ var SortOrder;
13
+ (function (SortOrder) {
14
+ SortOrder["Asc"] = "asc";
15
+ SortOrder["Desc"] = "desc";
16
+ })(SortOrder || (exports.SortOrder = SortOrder = {}));
17
+ var QueueType;
18
+ (function (QueueType) {
19
+ QueueType["Copy"] = "copy";
20
+ QueueType["Move"] = "move";
21
+ QueueType["Download"] = "download";
22
+ QueueType["Upload"] = "upload";
23
+ QueueType["Remove"] = "remove";
24
+ })(QueueType || (exports.QueueType = QueueType = {}));
25
+ var QueueEventType;
26
+ (function (QueueEventType) {
27
+ QueueEventType["Create"] = "create";
28
+ QueueEventType["Update"] = "update";
29
+ QueueEventType["Ask"] = "ask";
30
+ QueueEventType["Complete"] = "complete";
31
+ })(QueueEventType || (exports.QueueEventType = QueueEventType = {}));
32
+ var QueueActionType;
33
+ (function (QueueActionType) {
34
+ QueueActionType["Skip"] = "skip";
35
+ QueueActionType["Replace"] = "replace";
36
+ QueueActionType["Rename"] = "rename";
37
+ })(QueueActionType || (exports.QueueActionType = QueueActionType = {}));
38
+ var FailureType;
39
+ (function (FailureType) {
40
+ FailureType["Unauthorized"] = "unauthorized";
41
+ FailureType["ConfirmDeletion"] = "confirm-deletion";
42
+ FailureType["ConfirmClear"] = "confirm-clear";
43
+ FailureType["MissingDir"] = "missing-dir";
44
+ FailureType["RemoteError"] = "remote-error";
45
+ FailureType["APIError"] = "api-error";
46
+ })(FailureType || (exports.FailureType = FailureType = {}));
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class default_1 {
4
+ constructor() {
5
+ this.entries = new Map;
6
+ }
7
+ set(key, value) {
8
+ const found = this.entries.get(key);
9
+ this.entries.set(key, found ? { count: ++found.count, value } : { count: 1, value });
10
+ return this;
11
+ }
12
+ has(key) {
13
+ return this.entries.has(key);
14
+ }
15
+ get(key) {
16
+ return this.entries.get(key)?.value;
17
+ }
18
+ inc(key) {
19
+ const found = this.entries.get(key);
20
+ return found ? ++found.count : 0;
21
+ }
22
+ dec(key) {
23
+ const found = this.entries.get(key);
24
+ if (found) {
25
+ if (--found.count <= 0) {
26
+ this.entries.delete(key);
27
+ return found.value;
28
+ }
29
+ }
30
+ return undefined;
31
+ }
32
+ del(key) {
33
+ const found = this.entries.get(key);
34
+ found && this.entries.delete(key);
35
+ return found?.value;
36
+ }
37
+ count(key) {
38
+ return this.entries.get(key)?.count;
39
+ }
40
+ modify(key, value) {
41
+ const found = this.entries.get(key);
42
+ if (found) {
43
+ found.value = value;
44
+ return true;
45
+ }
46
+ return false;
47
+ }
48
+ keys() {
49
+ return this.entries.keys();
50
+ }
51
+ renameKey(from, to) {
52
+ if (!this.entries.has(from)) {
53
+ return;
54
+ }
55
+ this.entries.has(to) ?
56
+ this.entries.get(to).count += this.entries.get(from).count :
57
+ this.entries.set(to, this.entries.get(from));
58
+ this.entries.delete(from);
59
+ }
60
+ }
61
+ exports.default = default_1;