filefive 1.3.0 → 1.4.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/README.md +13 -3
- package/dist/App.js +7 -4
- package/dist/LocalWatcher.js +3 -4
- package/dist/RemoteFiles.js +1 -1
- package/dist/RemoteWatcher.js +3 -4
- package/dist/commands/copy.js +8 -6
- package/dist/index.js +1 -1
- package/dist/public/index.js +1 -1
- package/dist/queues/Copy.js +2 -2
- package/dist/queues/Download.js +2 -2
- package/dist/queues/Duplicate.js +1 -1
- package/dist/queues/Queue.js +4 -3
- package/dist/queues/Upload.js +5 -3
- package/dist/transformers/Local.js +17 -0
- package/dist/transformers/git.js +88 -0
- package/dist/types.js +2 -2
- package/dist/utils/filter.js +1 -1
- package/package.json +6 -2
package/dist/queues/Copy.js
CHANGED
|
@@ -8,8 +8,8 @@ const Queue_1 = __importDefault(require("./Queue"));
|
|
|
8
8
|
const types_1 = require("../types");
|
|
9
9
|
const URI_1 = require("../utils/URI");
|
|
10
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);
|
|
11
|
+
constructor(connId, src, dest, filter, fromRoot, onState, onConflict, onError, onComplete, watcher, move) {
|
|
12
|
+
super(connId, connId, src, dest, filter, fromRoot, onState, onConflict, onComplete);
|
|
13
13
|
this.onError = onError;
|
|
14
14
|
this.watcher = watcher;
|
|
15
15
|
this.move = move;
|
package/dist/queues/Download.js
CHANGED
|
@@ -8,8 +8,8 @@ const Queue_1 = __importDefault(require("./Queue"));
|
|
|
8
8
|
const types_1 = require("../types");
|
|
9
9
|
const Local_1 = require("../Local");
|
|
10
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);
|
|
11
|
+
constructor(connId, src, dest, filter, fromRoot, onState, onConflict, onError, onComplete) {
|
|
12
|
+
super(connId, types_1.LocalFileSystemID, src, dest, filter, fromRoot, onState, onConflict, onComplete);
|
|
13
13
|
this.onError = onError;
|
|
14
14
|
}
|
|
15
15
|
async transmit(fs, from, dirs, to) {
|
package/dist/queues/Duplicate.js
CHANGED
|
@@ -7,7 +7,7 @@ const Copy_1 = __importDefault(require("./Copy"));
|
|
|
7
7
|
const types_1 = require("../types");
|
|
8
8
|
class DuplicateQueue extends Copy_1.default {
|
|
9
9
|
constructor(connId, src, dest, filter, onState, onConflict, onError, onComplete, watcher) {
|
|
10
|
-
super(connId, src, dest, filter, onState, onConflict, onError, onComplete, watcher, false);
|
|
10
|
+
super(connId, src, dest, filter, null, onState, onConflict, onError, onComplete, watcher, false);
|
|
11
11
|
this.newNames = new Map();
|
|
12
12
|
this.resolve({ type: types_1.QueueActionType.Rename }, true);
|
|
13
13
|
}
|
package/dist/queues/Queue.js
CHANGED
|
@@ -30,12 +30,13 @@ const lsRemote = (connId) => {
|
|
|
30
30
|
};
|
|
31
31
|
exports.lsRemote = lsRemote;
|
|
32
32
|
class TransmitQueue {
|
|
33
|
-
constructor(from, to, src, dest, filter, onState, onConflict, onComplete) {
|
|
33
|
+
constructor(from, to, src, dest, filter, fromRoot, onState, onConflict, onComplete) {
|
|
34
34
|
this.from = from;
|
|
35
35
|
this.to = to;
|
|
36
36
|
this.src = src;
|
|
37
37
|
this.dest = dest;
|
|
38
38
|
this.filter = filter;
|
|
39
|
+
this.fromRoot = fromRoot;
|
|
39
40
|
this.onState = onState;
|
|
40
41
|
this.onConflict = onConflict;
|
|
41
42
|
this.onComplete = onComplete;
|
|
@@ -57,7 +58,7 @@ class TransmitQueue {
|
|
|
57
58
|
}
|
|
58
59
|
const stat = this.stat(this.to);
|
|
59
60
|
this.processing = this.queue$.subscribe(async ({ from, dirs, to, action }) => {
|
|
60
|
-
|
|
61
|
+
const a = action ?? this.action;
|
|
61
62
|
const existing = await stat((0, node_path_1.join)(to, ...dirs, from.name));
|
|
62
63
|
if (existing) {
|
|
63
64
|
if (a) {
|
|
@@ -115,7 +116,7 @@ class TransmitQueue {
|
|
|
115
116
|
}
|
|
116
117
|
}
|
|
117
118
|
};
|
|
118
|
-
await Promise.all(paths.map(path => add(path, dest)));
|
|
119
|
+
await Promise.all(paths.map(path => add(path, dest, this.fromRoot ? (0, node_path_1.dirname)(path).substring(this.fromRoot.length + 1).split('/') : [])));
|
|
119
120
|
}
|
|
120
121
|
stop() {
|
|
121
122
|
if (!this.stopped) {
|
package/dist/queues/Upload.js
CHANGED
|
@@ -9,8 +9,8 @@ const types_1 = require("../types");
|
|
|
9
9
|
const Local_1 = require("../Local");
|
|
10
10
|
const URI_1 = require("../utils/URI");
|
|
11
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);
|
|
12
|
+
constructor(connId, src, dest, filter, fromRoot, onState, onConflict, onError, onComplete, watcher) {
|
|
13
|
+
super(types_1.LocalFileSystemID, connId, src, dest, filter, fromRoot, onState, onConflict, onComplete);
|
|
14
14
|
this.onError = onError;
|
|
15
15
|
this.watcher = watcher;
|
|
16
16
|
this.touched = new Map();
|
|
@@ -34,7 +34,9 @@ class UploadQueue extends Queue_1.default {
|
|
|
34
34
|
try {
|
|
35
35
|
await fs.mkdir(targetDir);
|
|
36
36
|
}
|
|
37
|
-
catch
|
|
37
|
+
catch {
|
|
38
|
+
// the targetDir already exists
|
|
39
|
+
}
|
|
38
40
|
resolve();
|
|
39
41
|
}));
|
|
40
42
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
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 types_1 = require("../types");
|
|
7
|
+
const git_1 = __importDefault(require("./git"));
|
|
8
|
+
class default_1 {
|
|
9
|
+
async transform(path, files) {
|
|
10
|
+
files = files.map(f => ({ ...f, [types_1.FileAttrsAttr]: {} }));
|
|
11
|
+
for (const f of [git_1.default]) {
|
|
12
|
+
files = await f(path, files);
|
|
13
|
+
}
|
|
14
|
+
return files;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.default = default_1;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = default_1;
|
|
4
|
+
const node_util_1 = require("node:util");
|
|
5
|
+
const node_child_process_1 = require("node:child_process");
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
const types_1 = require("../types");
|
|
8
|
+
const ramda_1 = require("ramda");
|
|
9
|
+
async function default_1(path, files) {
|
|
10
|
+
const run = (0, node_util_1.promisify)(node_child_process_1.execFile);
|
|
11
|
+
try {
|
|
12
|
+
let { stdout: repoRoot } = await run('git', ['rev-parse', '--show-toplevel'], { cwd: path });
|
|
13
|
+
repoRoot = repoRoot.trim();
|
|
14
|
+
const { stdout: statuses } = await run('git', ['status', '-z', '.'], { cwd: path });
|
|
15
|
+
const [inRoot, inSubfolders] = (0, ramda_1.partition)(([p]) => (0, node_path_1.dirname)(p) == path, statuses
|
|
16
|
+
.replace(/\0$/, '')
|
|
17
|
+
.split('\0')
|
|
18
|
+
.map(s => [(0, node_path_1.join)(repoRoot, s.substring(3)), s.substring(0, 2)])
|
|
19
|
+
.map(([path, status]) => [path.replace(/\/$/, ''), status]));
|
|
20
|
+
if (inSubfolders.length == 1 && inSubfolders[0][0] == path && inSubfolders[0][1].includes('?')) {
|
|
21
|
+
files.forEach(f => {
|
|
22
|
+
const status = f.dir ? GitStatus.Contains : GitStatus.Untracked;
|
|
23
|
+
f[types_1.FileAttrsAttr][status] = statusNames[status];
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
const topDir = new RegExp('^([^/]+)');
|
|
28
|
+
[...inRoot
|
|
29
|
+
.map(([path, s]) => [path, getStatusCode(s)])
|
|
30
|
+
.filter(([, status]) => status),
|
|
31
|
+
...[...new Set(inSubfolders.map(([p]) => topDir.exec(p.substring(path.length + 1))?.[1]).filter(s => s))].map(dir => [(0, node_path_1.join)(path, dir), GitStatus.Contains])
|
|
32
|
+
].forEach(([path, status]) => {
|
|
33
|
+
const f = files.find(f => f.path == path);
|
|
34
|
+
if (f) {
|
|
35
|
+
if (f.dir) {
|
|
36
|
+
status = GitStatus.Contains;
|
|
37
|
+
}
|
|
38
|
+
f[types_1.FileAttrsAttr][status] = status ? (statusNames[status] ?? '') : '';
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const { stdout: ignored } = await run('git', ['ls-files', '--others', '--ignored', '--exclude-standard', '--directory', '-z'], { cwd: path });
|
|
43
|
+
if (ignored == './\0') {
|
|
44
|
+
files.forEach(f => f[types_1.FileAttrsAttr][GitStatus.Ignored] = statusNames[GitStatus.Ignored]);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
ignored
|
|
48
|
+
.replace(/\0$/, '')
|
|
49
|
+
.split('\0')
|
|
50
|
+
.map(s => (0, node_path_1.join)(path, s.replace(/\/$/, '')))
|
|
51
|
+
.forEach(path => {
|
|
52
|
+
const f = files.find(f => f.path == path);
|
|
53
|
+
f && (f[types_1.FileAttrsAttr][GitStatus.Ignored] = statusNames[GitStatus.Ignored]);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// either path is not in git repo or no git installed
|
|
59
|
+
}
|
|
60
|
+
return files;
|
|
61
|
+
}
|
|
62
|
+
var GitStatus;
|
|
63
|
+
(function (GitStatus) {
|
|
64
|
+
GitStatus["Untracked"] = "git_u";
|
|
65
|
+
GitStatus["Modified"] = "git_m";
|
|
66
|
+
GitStatus["Added"] = "git_a";
|
|
67
|
+
GitStatus["Contains"] = "git_c";
|
|
68
|
+
GitStatus["Ignored"] = "git_i";
|
|
69
|
+
})(GitStatus || (GitStatus = {}));
|
|
70
|
+
const statusNames = {
|
|
71
|
+
[GitStatus.Untracked]: 'Untracked',
|
|
72
|
+
[GitStatus.Modified]: 'Modified',
|
|
73
|
+
[GitStatus.Added]: 'Index Added',
|
|
74
|
+
[GitStatus.Contains]: 'Has uncommited items',
|
|
75
|
+
[GitStatus.Ignored]: 'Ignored'
|
|
76
|
+
};
|
|
77
|
+
function getStatusCode(s) {
|
|
78
|
+
if (s.includes('?')) {
|
|
79
|
+
return GitStatus.Untracked;
|
|
80
|
+
}
|
|
81
|
+
else if (s.includes('M')) {
|
|
82
|
+
return GitStatus.Modified;
|
|
83
|
+
}
|
|
84
|
+
else if (s.includes('A')) {
|
|
85
|
+
return GitStatus.Added;
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
package/dist/types.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FailureType = exports.QueueActionType = exports.QueueEventType = exports.QueueType = exports.SortOrder = exports.
|
|
3
|
+
exports.FailureType = exports.QueueActionType = exports.QueueEventType = exports.QueueType = exports.SortOrder = exports.FileAttrsAttr = exports.FileState = exports.FileStateAttr = exports.LocalFileSystemID = void 0;
|
|
4
4
|
exports.LocalFileSystemID = 'file://';
|
|
5
5
|
exports.FileStateAttr = Symbol.for('state');
|
|
6
6
|
var FileState;
|
|
@@ -8,7 +8,7 @@ var FileState;
|
|
|
8
8
|
FileState["Creating"] = "creating";
|
|
9
9
|
FileState["Renaming"] = "renaming";
|
|
10
10
|
})(FileState || (exports.FileState = FileState = {}));
|
|
11
|
-
exports.
|
|
11
|
+
exports.FileAttrsAttr = 'attributes';
|
|
12
12
|
var SortOrder;
|
|
13
13
|
(function (SortOrder) {
|
|
14
14
|
SortOrder["Asc"] = "asc";
|
package/dist/utils/filter.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "filefive",
|
|
3
3
|
"description": "A SFTP/FTP client and dual-panel file manager for macOS and Linux",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.0",
|
|
5
5
|
"license": "GPL-3.0",
|
|
6
6
|
"author": "Max Miroshnikov",
|
|
7
7
|
"bin": {
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"dev": "NODE_ENV=development nodemon src/index.ts",
|
|
32
32
|
"build": "tsc -p .",
|
|
33
33
|
"start": "node dist/index.js",
|
|
34
|
+
"lint": "eslint",
|
|
34
35
|
"publish": "tsc -p . && npm publish"
|
|
35
36
|
},
|
|
36
37
|
"dependencies": {
|
|
@@ -48,6 +49,7 @@
|
|
|
48
49
|
"ws": "^8.18.0"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
52
|
+
"@eslint/js": "^9.22.0",
|
|
51
53
|
"@types/express": "^5.0.0",
|
|
52
54
|
"@types/ftp": "^0.3.36",
|
|
53
55
|
"@types/multer": "^1.4.12",
|
|
@@ -56,9 +58,11 @@
|
|
|
56
58
|
"@types/ssh2": "^1.15.4",
|
|
57
59
|
"@types/whatwg-url": "^13.0.0",
|
|
58
60
|
"@types/ws": "^8.5.14",
|
|
61
|
+
"eslint": "^9.22.0",
|
|
59
62
|
"nodemon": "^3.1.9",
|
|
60
63
|
"ts-node": "^10.9.2",
|
|
61
|
-
"typescript": "^5.
|
|
64
|
+
"typescript": "^5.8.2",
|
|
65
|
+
"typescript-eslint": "^8.26.1"
|
|
62
66
|
},
|
|
63
67
|
"nodemonConfig": {
|
|
64
68
|
"ignore": [
|