@trap_stevo/filetide 0.0.29 → 0.0.32

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.
@@ -11,7 +11,10 @@ const {
11
11
  FileTransferManager
12
12
  } = require("./HUDManagers/FileTransferManager");
13
13
  class FileMessager {
14
- constructor(options = {}, transportOptions = {
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
- const baseDirectoryName = path.basename(baseDirectory);
75
- const adjustedDestinationPath = FileUtilityManager.normalizePath(path.join(destinationPath, baseDirectoryName));
76
- const sendFilePromises = filesData.map((fileInfo, index) => {
77
- const relativeFilePath = path.dirname(path.relative(baseDirectory, fileInfo.filePath));
78
- const fileDestinationPath = FileUtilityManager.normalizePath(path.join(adjustedDestinationPath, relativeFilePath));
79
- return this.sendFile(clientID, recipientId, fileInfo.fileName, fileInfo.fileData, fileDestinationPath, fileInfo.size, adjustedDestinationPath, index);
80
- });
81
- Promise.all(sendFilePromises).then(() => console.log("\nAll files in directory transferred successfully!")).catch(error => console.error("Did not transfer files: ", error));
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,7 +144,7 @@ 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
149
  }
146
150
  ;
@@ -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,6 +72,7 @@ class FileTide {
71
72
  }
72
73
  const newClient = new FileMessagerClient(clientOptions);
73
74
  newClient.joinRoom(userID, roomName, connectionOptions);
75
+ this.clientShorePolicies.set(userID, [FileUtilityManager.getTidePath(">CurrentUser"), FileUtilityManager.getTidePath(">Downloads"), FileUtilityManager.getTidePath(">Documents")]);
74
76
  this.clients.set(userID, newClient);
75
77
  FileTide.outputGradient(`[FileTide] ~ Messager launched successfully for client ~ ${userID}!`, significantMessageColors);
76
78
  _assertClassBrand(_FileTide_brand, this, _setupFileEventListeners).call(this, userID, newClient, onIncomingFile);
@@ -91,6 +93,29 @@ class FileTide {
91
93
  getTidePath(inputPath) {
92
94
  return FileUtilityManager.getTidePath(inputPath);
93
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
+ }
94
119
 
95
120
  /**
96
121
  * Send files / directories directly to a device.
@@ -227,22 +252,26 @@ function _setupFileEventListeners(userID, client, onIncomingFile) {
227
252
  this.progressBarManager.listenForInput("Page Number:", "Press 'n' for next page, 'p' for previous page.", chalk.blue, chalk.magenta, chalk.yellow);
228
253
  });
229
254
  client.clientTide.onEvent(userID, "incoming-file", data => {
230
- _FileTide.outputGradient(`[${userID}] Preparing to receive file : ${data.fileName}`, significantMessageColors);
231
- activeTransfers.set(data.fileName, {
232
- receivedChunks: [],
233
- totalChunks: data.totalChunks,
234
- fileInfo: data
235
- });
236
- const saveDir = FileUtilityManager.getTidePath(data.path);
237
- this.progressBarManager.addTask({
238
- name: data.fileName,
239
- size: data.fileSize
240
- });
241
- if (data.senderID && data.senderID !== userID && !fs.existsSync(saveDir)) {
242
- fs.mkdirSync(saveDir, {
243
- 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
244
261
  });
245
- _FileTide.outputGradient(`[${userID}] Created directory : ${saveDir}`, significantMessageColors);
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);
246
275
  }
247
276
  });
248
277
  client.clientTide.onEvent(userID, "transfer-progress", data => {
@@ -261,16 +290,21 @@ function _setupFileEventListeners(userID, client, onIncomingFile) {
261
290
  }
262
291
  });
263
292
  client.clientTide.onEvent(userID, "transfer-complete", data => {
264
- _FileTide.outputGradient(`[${userID}] File transfer complete : ${data.fileName}`, significantMessageColors);
265
- const transferState = activeTransfers.get(data.fileName);
266
- if (!transferState) {
267
- return;
268
- }
269
293
  const savePath = FileUtilityManager.getTidePath(path.join(data.filePath, data.fileName));
270
- const fullFile = Buffer.concat(transferState.receivedChunks);
271
- fs.writeFileSync(savePath, fullFile);
272
- _FileTide.outputGradient(`[${userID}] File saved at : ${savePath}`, significantMessageColors);
273
- activeTransfers.delete(data.fileName);
294
+ try {
295
+ _FileTide.outputGradient(`[${userID}] File transfer complete : ${data.fileName}`, significantMessageColors);
296
+ const transferState = activeTransfers.get(data.fileName);
297
+ if (!transferState) {
298
+ return;
299
+ }
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);
307
+ }
274
308
  });
275
309
  client.clientTide.onEvent(userID, "transfer-requested", data => {
276
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 = 'http://localhost:3000'
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
- const homeDir = os.homedir();
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") : "/var/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.29",
3
+ "version": "0.0.32",
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.36",
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",