@trap_stevo/filetide 0.0.28 → 0.0.31
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/cjs/FileMessager.js
CHANGED
|
@@ -11,7 +11,10 @@ const {
|
|
|
11
11
|
FileTransferManager
|
|
12
12
|
} = require("./HUDManagers/FileTransferManager");
|
|
13
13
|
class FileMessager {
|
|
14
|
-
constructor(options = {
|
|
14
|
+
constructor(options = {
|
|
15
|
+
pingTimeout: 3600000,
|
|
16
|
+
pingInterval: 60000
|
|
17
|
+
}, transportOptions = {
|
|
15
18
|
parallelChunks: 3,
|
|
16
19
|
maxRetries: 3
|
|
17
20
|
}) {
|
|
@@ -71,14 +71,18 @@ class FileMessagerClient {
|
|
|
71
71
|
* @param {string} destinationPath - The path to which the files should be sent.
|
|
72
72
|
*/
|
|
73
73
|
sendDirectoryFiles(clientID, recipientId, filesData, baseDirectory, destinationPath) {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
74
|
+
try {
|
|
75
|
+
const baseDirectoryName = path.basename(baseDirectory);
|
|
76
|
+
const adjustedDestinationPath = FileUtilityManager.normalizePath(path.join(destinationPath, baseDirectoryName));
|
|
77
|
+
const sendFilePromises = filesData.map((fileInfo, index) => {
|
|
78
|
+
const relativeFilePath = path.dirname(path.relative(baseDirectory, fileInfo.filePath));
|
|
79
|
+
const fileDestinationPath = FileUtilityManager.normalizePath(path.join(adjustedDestinationPath, relativeFilePath));
|
|
80
|
+
return this.sendFile(clientID, recipientId, fileInfo.fileName, fileInfo.fileData, fileDestinationPath, fileInfo.size, adjustedDestinationPath, index);
|
|
81
|
+
});
|
|
82
|
+
Promise.all(sendFilePromises).then(() => console.log("\nAll files in directory transferred successfully!")).catch(error => console.error("Did not transfer directory: ", error));
|
|
83
|
+
} catch (error) {
|
|
84
|
+
FileNetUtilityManager.outputGradient(`[FileTide ~ File Messager] ~ Refused directory transfer: ${error}`, errorMessageColors);
|
|
85
|
+
}
|
|
82
86
|
}
|
|
83
87
|
sendFile(clientID, recipientId, fileName, file, filePath = process.cwd(), fileSize, directoryPath = null, index = 0) {
|
|
84
88
|
if (!file) {
|
|
@@ -140,45 +144,8 @@ class FileMessagerClient {
|
|
|
140
144
|
path: filePath,
|
|
141
145
|
size: fileSize
|
|
142
146
|
}
|
|
143
|
-
}).then(() => FileNetUtilityManager.outputGradient(`[FileTide ~ File Messager] ~ File ~ ${fileName} transfer complete!`, significantMessageColors)).catch(error => FileNetUtilityManager.outputGradient(`Refused file transfer: ${error}`, errorMessageColors));
|
|
147
|
+
}).then(() => FileNetUtilityManager.outputGradient(`[FileTide ~ File Messager] ~ File ~ ${fileName} transfer complete!`, significantMessageColors)).catch(error => FileNetUtilityManager.outputGradient(`[FileTide ~ File Messager] ~ Refused file transfer: ${error}`, errorMessageColors));
|
|
144
148
|
}
|
|
145
|
-
|
|
146
|
-
/*onFileChunkReceived(userID)
|
|
147
|
-
{
|
|
148
|
-
this.clientTide.onEvent(userID, "transfer-progress", (data) => {
|
|
149
|
-
console.log(`\n[FileTide ~ File Messager] ~ Receiving file chunk for client ~ ${userID}: `, data.fileChunk);
|
|
150
|
-
|
|
151
|
-
console.log("\n[FileTide ~ File Messager] ~ Progress: ", data.progress);
|
|
152
|
-
|
|
153
|
-
FileUtilityManager.saveChunk(userID, data.fileChunk, data.path, data.name);
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
onFileTransferComplete(userID) {
|
|
158
|
-
this.clientTide.onEvent(userID, "transfer-complete", (data) => {
|
|
159
|
-
console.log(`\n[FileTide ~ File Messager] ~ File transfer completed for user ${userID}.`);
|
|
160
|
-
|
|
161
|
-
FileUtilityManager.assembleFile(userID);
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
handleIncomingFile(userID)
|
|
166
|
-
{
|
|
167
|
-
this.clientTide.onEvent(userID, "incoming-file", (data) => {
|
|
168
|
-
console.log(`\n[FileTide ~ File Messager] ~ Received file for user ${userID}: ${data.fileName}.`);
|
|
169
|
-
|
|
170
|
-
FileUtilityManager.saveFile(data.fileName, data.fileData, data.path, data.name);
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
handleMultipleClientsTransfer()
|
|
175
|
-
{
|
|
176
|
-
this.clients.forEach((userID, roomData) => {
|
|
177
|
-
this.onFileChunkReceived(userID);
|
|
178
|
-
|
|
179
|
-
this.onFileTransferComplete(userID);
|
|
180
|
-
});
|
|
181
|
-
}*/
|
|
182
149
|
}
|
|
183
150
|
;
|
|
184
151
|
module.exports = FileMessagerClient;
|
package/dist/cjs/FileTide.js
CHANGED
|
@@ -33,6 +33,7 @@ class FileTide {
|
|
|
33
33
|
this.progressBarManager = new ConsoleProgressBarManager([], {
|
|
34
34
|
completionMessageColor: chalk.blue.bold
|
|
35
35
|
});
|
|
36
|
+
this.clientShorePolicies = new Map();
|
|
36
37
|
this.clients = new Map();
|
|
37
38
|
this.currentUserID = "";
|
|
38
39
|
return;
|
|
@@ -71,9 +72,7 @@ class FileTide {
|
|
|
71
72
|
}
|
|
72
73
|
const newClient = new FileMessagerClient(clientOptions);
|
|
73
74
|
newClient.joinRoom(userID, roomName, connectionOptions);
|
|
74
|
-
|
|
75
|
-
//newClient.handleMultipleClientsTransfer();
|
|
76
|
-
|
|
75
|
+
this.clientShorePolicies.set(userID, [FileUtilityManager.getTidePath(">CurrentUser"), FileUtilityManager.getTidePath(">Downloads"), FileUtilityManager.getTidePath(">Documents")]);
|
|
77
76
|
this.clients.set(userID, newClient);
|
|
78
77
|
FileTide.outputGradient(`[FileTide] ~ Messager launched successfully for client ~ ${userID}!`, significantMessageColors);
|
|
79
78
|
_assertClassBrand(_FileTide_brand, this, _setupFileEventListeners).call(this, userID, newClient, onIncomingFile);
|
|
@@ -94,6 +93,29 @@ class FileTide {
|
|
|
94
93
|
getTidePath(inputPath) {
|
|
95
94
|
return FileUtilityManager.getTidePath(inputPath);
|
|
96
95
|
}
|
|
96
|
+
clearShorePolicies(clientID, shores = []) {
|
|
97
|
+
let clientShorePolicies = this.clientShorePolicies.get(clientID);
|
|
98
|
+
if (!shores || shores.length <= 0 || !clientShorePolicies || !clientID) {
|
|
99
|
+
FileTide.outputGradient(`[FileTide] Did not clear from client ~ ${clientID} shore policies.`, ["#F94144", "#F3722C"]);
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
const shorePolicies = Array.from(clientShorePolicies.values());
|
|
103
|
+
const currentShores = new Set(clientShorePolicies);
|
|
104
|
+
this.clientShorePolicies.set(clientID, shorePolicies.filter(shorePolicy => !currentShores.has(shorePolicy)));
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
addShorePolicies(clientID, shores = []) {
|
|
108
|
+
const clientShorePolicies = this.clientShorePolicies.get(clientID);
|
|
109
|
+
if (!shores || shores.length <= 0 || !clientShorePolicies || !clientID) {
|
|
110
|
+
FileTide.outputGradient(`[FileTide] Did not add to client ~ ${clientID} shore policies.`, ["#F94144", "#F3722C"]);
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
this.clientShorePolicies.set(clientID, [...new Set([...clientShorePolicies, ...shores])]);
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
getShorePolicies(clientID) {
|
|
117
|
+
return this.clientShorePolicies.get(clientID);
|
|
118
|
+
}
|
|
97
119
|
|
|
98
120
|
/**
|
|
99
121
|
* Send files / directories directly to a device.
|
|
@@ -230,22 +252,26 @@ function _setupFileEventListeners(userID, client, onIncomingFile) {
|
|
|
230
252
|
this.progressBarManager.listenForInput("Page Number:", "Press 'n' for next page, 'p' for previous page.", chalk.blue, chalk.magenta, chalk.yellow);
|
|
231
253
|
});
|
|
232
254
|
client.clientTide.onEvent(userID, "incoming-file", data => {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
const saveDir = FileUtilityManager.getTidePath(data.path);
|
|
240
|
-
this.progressBarManager.addTask({
|
|
241
|
-
name: data.fileName,
|
|
242
|
-
size: data.fileSize
|
|
243
|
-
});
|
|
244
|
-
if (data.senderID && data.senderID !== userID && !fs.existsSync(saveDir)) {
|
|
245
|
-
fs.mkdirSync(saveDir, {
|
|
246
|
-
recursive: true
|
|
255
|
+
try {
|
|
256
|
+
_FileTide.outputGradient(`[${userID}] Preparing to receive file : ${data.fileName}`, significantMessageColors);
|
|
257
|
+
activeTransfers.set(data.fileName, {
|
|
258
|
+
receivedChunks: [],
|
|
259
|
+
totalChunks: data.totalChunks,
|
|
260
|
+
fileInfo: data
|
|
247
261
|
});
|
|
248
|
-
|
|
262
|
+
const saveDir = FileUtilityManager.getTidePath(data.path);
|
|
263
|
+
if (data.senderID && data.senderID !== userID && !fs.existsSync(saveDir)) {
|
|
264
|
+
this.progressBarManager.addTask({
|
|
265
|
+
name: data.fileName,
|
|
266
|
+
size: data.fileSize
|
|
267
|
+
});
|
|
268
|
+
fs.mkdirSync(saveDir, {
|
|
269
|
+
recursive: true
|
|
270
|
+
});
|
|
271
|
+
_FileTide.outputGradient(`[${userID}] Created directory : ${saveDir}`, significantMessageColors);
|
|
272
|
+
}
|
|
273
|
+
} catch (error) {
|
|
274
|
+
_FileTide.outputGradient(`[${userID}] Halted file recieval preparation : ${data.fileName}\n${error}`, errorMessageColors);
|
|
249
275
|
}
|
|
250
276
|
});
|
|
251
277
|
client.clientTide.onEvent(userID, "transfer-progress", data => {
|
|
@@ -256,30 +282,29 @@ function _setupFileEventListeners(userID, client, onIncomingFile) {
|
|
|
256
282
|
if (!transferState) {
|
|
257
283
|
return;
|
|
258
284
|
}
|
|
259
|
-
|
|
260
|
-
//console.log(`[${userID}] Receiving chunk ${data.chunkIndex + 1}/${transferState.totalChunks} for file : ${data.fileName}`);
|
|
261
|
-
|
|
262
285
|
transferState.receivedChunks[data.chunkIndex] = Buffer.from(data.fileChunk);
|
|
263
286
|
const progress = (data.chunkIndex + 1) / transferState.totalChunks * 100;
|
|
264
|
-
|
|
265
|
-
//console.log(`[${userID}] Progress : ${progress.toFixed(2)}%`);
|
|
266
|
-
|
|
267
287
|
this.progressBarManager.updateTaskProgress(data.fileName, 512 * 1024);
|
|
268
288
|
if (onIncomingFile) {
|
|
269
289
|
onIncomingFile(data);
|
|
270
290
|
}
|
|
271
291
|
});
|
|
272
292
|
client.clientTide.onEvent(userID, "transfer-complete", data => {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
293
|
+
try {
|
|
294
|
+
_FileTide.outputGradient(`[${userID}] File transfer complete : ${data.fileName}`, significantMessageColors);
|
|
295
|
+
const transferState = activeTransfers.get(data.fileName);
|
|
296
|
+
if (!transferState) {
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
const savePath = FileUtilityManager.getTidePath(path.join(data.filePath, data.fileName));
|
|
300
|
+
const fullFile = Buffer.concat(transferState.receivedChunks);
|
|
301
|
+
fs.writeFileSync(savePath, fullFile);
|
|
302
|
+
_FileTide.outputGradient(`[${userID}] File saved at : ${savePath}`, significantMessageColors);
|
|
303
|
+
activeTransfers.delete(data.fileName);
|
|
304
|
+
} catch (error) {
|
|
305
|
+
_FileTide.outputGradient(`[${userID}] Did not save file at : ${savePath}\n${error}`, errorMessageColors);
|
|
306
|
+
activeTransfers.delete(data.fileName);
|
|
277
307
|
}
|
|
278
|
-
const savePath = FileUtilityManager.getTidePath(path.join(data.filePath, data.fileName));
|
|
279
|
-
const fullFile = Buffer.concat(transferState.receivedChunks);
|
|
280
|
-
fs.writeFileSync(savePath, fullFile);
|
|
281
|
-
_FileTide.outputGradient(`[${userID}] File saved at : ${savePath}`, significantMessageColors);
|
|
282
|
-
activeTransfers.delete(data.fileName);
|
|
283
308
|
});
|
|
284
309
|
client.clientTide.onEvent(userID, "transfer-requested", data => {
|
|
285
310
|
_FileTide.outputGradient(`[${userID}] Transfer requested from: ${data.requesterID}`, significantMessageColors);
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
class FileMessagerConfigManager {
|
|
4
4
|
static getServerOptions({
|
|
5
5
|
maxHttpBufferSize = 1e9,
|
|
6
|
+
pingTimeout = 3600000,
|
|
7
|
+
pingInterval = 60000,
|
|
6
8
|
useHTTPS = false,
|
|
7
9
|
corsOrigin = "*",
|
|
8
10
|
useCors = true,
|
|
@@ -24,7 +26,7 @@ class FileMessagerConfigManager {
|
|
|
24
26
|
};
|
|
25
27
|
}
|
|
26
28
|
static getClientOptions({
|
|
27
|
-
serverUrl =
|
|
29
|
+
serverUrl = "http://localhost:3000"
|
|
28
30
|
} = {}) {
|
|
29
31
|
return {
|
|
30
32
|
url: serverUrl
|
|
@@ -24,15 +24,83 @@ class FileUtilityManager {
|
|
|
24
24
|
});
|
|
25
25
|
return totalSize;
|
|
26
26
|
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Function to filter files and directories.
|
|
30
|
+
* @param {string} dirPath - The directory path to scan
|
|
31
|
+
* @param {Array} filterContent - Array of paths (files, directories, extensions) to avoid (e.g., ['docs', 'example.txt', '.js'])
|
|
32
|
+
* @param {function} callback - A callback function to handle the results
|
|
33
|
+
*/
|
|
34
|
+
static filterFilesAndDirectories(dirPath, filterContent = [], callback) {
|
|
35
|
+
fs.readdir(dirPath, {
|
|
36
|
+
withFileTypes: true
|
|
37
|
+
}, (error, items) => {
|
|
38
|
+
if (error) {
|
|
39
|
+
return callback(error);
|
|
40
|
+
}
|
|
41
|
+
const results = [];
|
|
42
|
+
items.forEach(item => {
|
|
43
|
+
const itemPath = path.join(dirPath, item.name);
|
|
44
|
+
const filtered = filterContent.some(filterEntry => {
|
|
45
|
+
const resolvedFilterEntry = path.resolve(filterEntry);
|
|
46
|
+
const fileExtension = filterEntry.startsWith(".");
|
|
47
|
+
return itemPath === resolvedFilterEntry || item.name === filterEntry || fileExtension && path.extname(item.name) === filterEntry;
|
|
48
|
+
});
|
|
49
|
+
if (!filtered) {
|
|
50
|
+
fs.stat(itemPath, (error, stats) => {
|
|
51
|
+
if (error) {
|
|
52
|
+
return callback(error);
|
|
53
|
+
}
|
|
54
|
+
results.push({
|
|
55
|
+
dateCreated: stats.birthtime,
|
|
56
|
+
type: item.isDirectory() ? "directory" : "file",
|
|
57
|
+
size: stats.size,
|
|
58
|
+
name: item.name,
|
|
59
|
+
path: itemPath
|
|
60
|
+
});
|
|
61
|
+
if (results.length === items.length) {
|
|
62
|
+
callback(null, results);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
} else if (results.length === items.length) {
|
|
66
|
+
callback(null, results);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Function to check for a path or any of the path's subpaths inside the user's open shore (allowed drop-zone) policy.
|
|
74
|
+
* Supports a wildcard '*' which allows all paths.
|
|
75
|
+
* @param {string} shorePath - The file or directory path to check
|
|
76
|
+
* @param {Array} openShores - Array of paths or '*' to check against
|
|
77
|
+
* @returns {boolean} - Returns true if openShores found the itemPath or the itemPath's subpath.
|
|
78
|
+
*/
|
|
79
|
+
static allowedShore(shorePath, openShores = []) {
|
|
80
|
+
const resolvedShorePath = path.resolve(shorePath);
|
|
81
|
+
if (openShores.includes("*")) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
return openShores.some(listedShore => {
|
|
85
|
+
const currentShore = path.resolve(listedShore);
|
|
86
|
+
return resolvedShorePath === currentShore || resolvedShorePath.startsWith(currentShore + path.sep);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
27
89
|
static getTidePath(inputPath) {
|
|
28
|
-
|
|
90
|
+
let homeDir = os.homedir();
|
|
29
91
|
const platform = process.platform;
|
|
92
|
+
let currentUserDir = homeDir;
|
|
93
|
+
if (platform === "linux") {
|
|
94
|
+
const username = process.env.USER || process.env.LOGNAME;
|
|
95
|
+
homeDir = "/home";
|
|
96
|
+
currentUserDir = path.join(homeDir, username);
|
|
97
|
+
}
|
|
30
98
|
const folderMappings = {
|
|
31
99
|
">Downloads": path.join(homeDir, "Downloads"),
|
|
32
100
|
">Documents": path.join(homeDir, "Documents"),
|
|
33
101
|
">Desktop": path.join(homeDir, "Desktop"),
|
|
34
102
|
">AppData": platform === "win32" ? path.join(homeDir, "AppData", "Roaming") : path.join(homeDir, ".config"),
|
|
35
|
-
">LocalAppData": platform === "win32" ? path.join(homeDir, "AppData", "Local") : "
|
|
103
|
+
">LocalAppData": platform === "win32" ? path.join(homeDir, "AppData", "Local") : path.join(homeDir, ".local", "share"),
|
|
36
104
|
">Music": path.join(homeDir, "Music"),
|
|
37
105
|
">Pictures": path.join(homeDir, "Pictures"),
|
|
38
106
|
">Videos": path.join(homeDir, "Videos"),
|
|
@@ -44,6 +112,7 @@ class FileUtilityManager {
|
|
|
44
112
|
">Cache": platform === "win32" ? path.join(homeDir, "AppData", "Local", "Cache") : path.join(homeDir, ".cache"),
|
|
45
113
|
">Config": platform === "win32" ? path.join(homeDir, "AppData", "Local", "Config") : "/etc",
|
|
46
114
|
">CurrentDirectory": process.cwd(),
|
|
115
|
+
">CurrentUser": currentUserDir,
|
|
47
116
|
">Home": homeDir
|
|
48
117
|
};
|
|
49
118
|
let resolvedPath = inputPath;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trap_stevo/filetide",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.31",
|
|
4
4
|
"description": "Revolutionizing real-time file transfer with seamless, instant communication across any device. Deliver files instantly, regardless of platform, and experience unparalleled speed and control in managing transfers. Elevate your file-sharing capabilities with a tool designed for precision, efficiency, and effortless connectivity.",
|
|
5
5
|
"main": "dist/cjs/FileTide.js",
|
|
6
6
|
"scripts": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"author": "Steven Compton",
|
|
30
30
|
"license": "ISC",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@trap_stevo/iotide": "^0.0.
|
|
32
|
+
"@trap_stevo/iotide": "^0.0.37",
|
|
33
33
|
"@trap_stevo/iotide-client": "^0.0.15",
|
|
34
34
|
"@trap_stevo/legendarybuilderpronodejs-utilities": "^1.0.40",
|
|
35
35
|
"chalk": "^4.1.2",
|