@trap_stevo/filetide-client 0.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.
@@ -0,0 +1,353 @@
1
+ "use strict";
2
+
3
+ function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
4
+ function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
5
+ function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
6
+ const {
7
+ HUDUtilityManager
8
+ } = require("@trap_stevo/legendarybuilderpronodejs-utilities");
9
+ const FileTide = require("@trap_stevo/filetide");
10
+ const chalk = require("chalk");
11
+ const path = require("path");
12
+ const fs = require("fs");
13
+ const os = require("os");
14
+ let currentRoom = "file-room";
15
+ let tideUrl = "http://localhost:9269";
16
+ const deviceName = os.hostname();
17
+ const fileTide = new FileTide();
18
+ let fileMessagerInstance;
19
+ const gradients = {
20
+ success: ["\x1b[38;5;48m", "\x1b[38;5;49m", "\x1b[38;5;50m"],
21
+ "indicator": ["\x1b[38;5;30m", "\x1b[38;5;37m", "\x1b[38;5;44m", "\x1b[38;5;51m", "\x1b[38;5;147m"],
22
+ error: ["\x1b[38;5;203m", "\x1b[38;5;202m", "\x1b[38;5;208m"],
23
+ info: ["\x1b[38;5;74m", "\x1b[38;5;75m"],
24
+ critical: ["\x1b[38;5;203m", "\x1b[38;5;214m"],
25
+ neutral: ["\x1b[38;5;74m", "\x1b[38;5;81m", "\x1b[38;5;117m", "\x1b[38;5;153m"]
26
+ };
27
+ const shortcuts = {
28
+ ">Downloads": {
29
+ description: "User's downloads folder.",
30
+ shortCut: ">Downloads"
31
+ },
32
+ ">Documents": {
33
+ description: "User's documents folder.",
34
+ shortCut: ">Documents"
35
+ },
36
+ ">Desktop": {
37
+ description: "User's desktop folder.",
38
+ shortCut: ">Desktop"
39
+ },
40
+ ">AppData": {
41
+ description: "User's roaming application data folder.",
42
+ shortCut: ">AppData"
43
+ },
44
+ ">LocalAppData": {
45
+ description: "User's local application data folder.",
46
+ shortCut: ">LocalAppData"
47
+ },
48
+ ">Music": {
49
+ description: "User's music folder.",
50
+ shortCut: ">Music"
51
+ },
52
+ ">Pictures": {
53
+ description: "User's pictures folder.",
54
+ shortCut: ">Pictures"
55
+ },
56
+ ">Videos": {
57
+ description: "User's videos folder.",
58
+ shortCut: ">Videos"
59
+ },
60
+ ">Public": {
61
+ description: "User's public folder.",
62
+ shortCut: ">Public"
63
+ },
64
+ ">Templates": {
65
+ description: "User's templates folder",
66
+ shortCut: ">Templates"
67
+ },
68
+ ">Temp": {
69
+ description: "System's temp folder.",
70
+ shortCut: ">Temp"
71
+ },
72
+ ">LogFiles": {
73
+ description: "System's logs folder.",
74
+ shortCut: ">LogFiles"
75
+ },
76
+ ">SystemRoot": {
77
+ description: "System's root folder.",
78
+ shortCut: ">SystemRoot"
79
+ },
80
+ ">Cache": {
81
+ description: "User's application cache folder.",
82
+ shortCut: ">Cache"
83
+ },
84
+ ">Config": {
85
+ description: "User's application config folder.",
86
+ shortCut: ">Config"
87
+ },
88
+ ">CurrentDirectory": {
89
+ description: "User's current folder.",
90
+ shortCut: ">CurrentDirectory"
91
+ },
92
+ ">Home": {
93
+ description: "System's home folder.",
94
+ shortCut: ">Home"
95
+ }
96
+ };
97
+ const colorReset = "\x1b[0m";
98
+ var _FileTideClient_brand = /*#__PURE__*/new WeakSet();
99
+ class FileTideClient {
100
+ constructor(inputDeviceName, inputTideURL, inputCurrentRoom, displayTitle = true, showCLITitle = false) {
101
+ _classPrivateMethodInitSpec(this, _FileTideClient_brand);
102
+ this.currentDeviceName = inputDeviceName || deviceName;
103
+ this.originDeviceName = inputDeviceName || deviceName;
104
+ this.deviceName = inputDeviceName || deviceName;
105
+ this.tideUrl = inputTideURL || tideUrl;
106
+ this.currentRoom = inputCurrentRoom || currentRoom;
107
+ this.fileMessagerInstance = fileMessagerInstance;
108
+ this.clientDisconnected = false;
109
+ this.shortcuts = shortcuts;
110
+ _assertClassBrand(_FileTideClient_brand, this, _setupProcessEvents).call(this);
111
+ if (displayTitle) {
112
+ this.displayTitle(showCLITitle);
113
+ }
114
+ return;
115
+ }
116
+ applyGradient(text, gradientType) {
117
+ const colors = gradients[gradientType];
118
+ let gradientText = "";
119
+ if (text.length === 0) return colorReset + text;
120
+ const totalSteps = Math.max(text.length - 1, 1);
121
+ for (let i = 0; i < text.length; i++) {
122
+ const progress = i / totalSteps;
123
+ const colorIndex = Math.floor(progress * (colors.length - 1));
124
+ gradientText += colors[colorIndex] + text[i];
125
+ }
126
+ return gradientText + colorReset;
127
+ }
128
+ displayMessage(type, message) {
129
+ switch (type) {
130
+ case "success":
131
+ console.log(this.applyGradient(message, "success"));
132
+ break;
133
+ case "indicator":
134
+ console.log(this.applyGradient(message, "indicator"));
135
+ break;
136
+ case "error":
137
+ console.log(this.applyGradient(message, "error"));
138
+ break;
139
+ case "info":
140
+ console.log(this.applyGradient(message, "info"));
141
+ break;
142
+ case "critical":
143
+ console.log(this.applyGradient(message, "critical"));
144
+ break;
145
+ case "neutral":
146
+ console.log(this.applyGradient(message, "neutral"));
147
+ break;
148
+ default:
149
+ console.log(this.applyGradient(message, "neutral"));
150
+ }
151
+ }
152
+ broadcastClientOffline(fileMessager) {
153
+ if (fileMessager && !this.clientDisconnected) {
154
+ this.clientDisconnected = true;
155
+ fileMessager.clientTide.emitEvent(this.currentDeviceName, "client-offline", this.currentDeviceName);
156
+ FileTide.outputGradient(`[${this.currentDeviceName}] Disconnected from the file net.`, ["#00C897", "#00E0FF"]);
157
+ }
158
+ }
159
+ startClient(clientOptions = {}, connectionOptions = {}, ...clientConfigurations) {
160
+ if (this.fileMessagerInstance && this.fileMessagerInstance.clientTide) {
161
+ this.fileMessagerInstance.clientTide.closeSocket(this.currentDeviceName);
162
+ }
163
+ fileTide.launchMessager({
164
+ serverUrl: this.tideUrl,
165
+ ...clientOptions
166
+ }, {
167
+ maxHttpBufferSize: 5e9,
168
+ pingTimeout: 3600000,
169
+ pingInterval: 60000,
170
+ ...connectionOptions
171
+ }, this.currentRoom, this.deviceName, fileMessager => {
172
+ this.fileMessagerInstance = fileMessager;
173
+ fileMessager.clientTide.onEvent(this.deviceName, "connect", () => {
174
+ this.clientDisconnected = false;
175
+ FileTide.outputGradient(`[${this.deviceName}] Connected to FileTide ~ ${this.tideUrl} in ${this.currentRoom}!`, ["#00C897", "#00E0FF"]);
176
+ fileMessager.clientTide.emitEvent(this.deviceName, "client-online", this.deviceName, fileMessager.clientTide.sockets[this.deviceName].tideID, this.pDeviceName, fileMessager.clientTide.sockets[this.deviceName].id);
177
+ FileTide.outputGradient(`[${this.currentDeviceName}] Getting connected clients...`, ["#00C897", "#00E0FF"]);
178
+ });
179
+ fileMessager.clientTide.onEvent(this.deviceName, "disconnect", () => {
180
+ this.broadcastClientOffline(fileMessager);
181
+ });
182
+ }, ...clientConfigurations);
183
+ }
184
+ requestFileTransfer(senderID, filePath, destinationPath) {
185
+ FileTide.outputGradient(`[${this.deviceName}] Requesting ${path.basename(filePath)} from client ~ ${senderID}...`, ["#00C897", "#00E0FF"]);
186
+ this.fileMessagerInstance.requestTransfer(this.deviceName, senderID, filePath, destinationPath);
187
+ return;
188
+ }
189
+ sendFileTransfer(recipientID, filePath, destinationPath) {
190
+ const fileDetails = fileTide.getPathData(filePath);
191
+ if (!fileDetails) {
192
+ FileTide.outputGradient(`[${this.deviceName}] File at path ${filePath} not found.`, ["#F94144", "#F3722C"]);
193
+ return;
194
+ }
195
+ if (fileDetails.type === "file") {
196
+ FileTide.outputGradient(`[${this.deviceName}] Sending file ~ ${fileDetails.content.fileName} to client ~ ${recipientID}...`, ["#00C897", "#00E0FF"]);
197
+ this.fileMessagerInstance.sendFile(this.deviceName, recipientID, fileDetails.content.fileName, fileDetails.content.fileData, destinationPath, fileDetails.content.size);
198
+ return;
199
+ }
200
+ if (fileDetails.type === "directory") {
201
+ FileTide.outputGradient(`[${this.deviceName}] Sending ${fileDetails.content.length} files in directory ~ ${path.basename(filePath)} to client ~ ${recipientID}...`, ["#00C897", "#00E0FF"]);
202
+ this.fileMessagerInstance.sendDirectoryFiles(this.deviceName, recipientID, fileDetails.content, fileTide.getTidePath(filePath), destinationPath);
203
+ return;
204
+ }
205
+ return;
206
+ }
207
+ addShortcuts(inputShortcuts) {
208
+ for (const [key, value] of Object.entries(inputShortcuts)) {
209
+ if (!shortcuts[key]) {
210
+ this.shortcuts[key] = {
211
+ description: value.description || "No description provided.",
212
+ shortCut: key
213
+ };
214
+ }
215
+ }
216
+ return shortcuts;
217
+ }
218
+ getShortcuts() {
219
+ return shortcuts;
220
+ }
221
+ getOnlineClients() {
222
+ this.fileMessagerInstance.clientTide.emitEvent(this.deviceName, "clients-online", this.deviceName);
223
+ return;
224
+ }
225
+ changeRoom(room) {
226
+ this.currentRoom = room;
227
+ FileTide.outputGradient(`[${this.deviceName}] Updated room to ${this.currentRoom}`, ["#4D96FF", "#89CFF0"]);
228
+ this.startClient();
229
+ return;
230
+ }
231
+ changeClientID(clientID) {
232
+ this.currentDeviceName = this.deviceName;
233
+ this.deviceName = clientID;
234
+ this.fileMessagerInstance.clientTide.emitEvent(this.currentDeviceName, "client-offline", this.currentDeviceName);
235
+ FileTide.outputGradient(`[${this.deviceName}] Updated client name to ${this.deviceName}`, ["#4D96FF", "#89CFF0"]);
236
+ this.startClient();
237
+ return;
238
+ }
239
+ changeTideUrl(url) {
240
+ this.tideUrl = url;
241
+ FileTide.outputGradient(`[${this.deviceName}] Updated tide URL to ${this.tideUrl}`, ["#4D96FF", "#89CFF0"]);
242
+ this.startClient();
243
+ return;
244
+ }
245
+ displayTitle(cli = false) {
246
+ FileTide.outputGradient(`
247
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
248
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
249
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
250
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
251
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
252
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
253
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
254
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
255
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
256
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
257
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
258
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
259
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
260
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:;:::::;;;;:::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
261
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::::;+?%%%%%%%?*;::::::::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
262
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;:::;*%%?+;:,,,::+?S?;:::::::::::::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
263
+ ;;;;;;;;;;;;;;;;;;;;;;;;::::;*S?;,,,,::::::,,;SS;:::;+++++++++;;:::::::;;;;;;:::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
264
+ ;;;;;;;;;;;;;;;;;;;;;;;;:::+S%:.,::;::;;+++;::*@+:*SSS%%%%%%%%SS%+:::::::::::::::::::::;::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
265
+ ;;;;;;;;;;;;;;;;;;;;;;;;;:+#*,,:;;::+?SSSSS#?+SS+SS;:,,,,,,,,,,;S#?;::::::::::::::::::::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;;
266
+ ;;;;;;;;;;;;;;;;;;;;;;;;:;S?.,;;;:;%#%*+;*S##SS%S*,:;;;;;;;;;;;:,+S#%%%%%%%%%%%%%%%%%%%%%?+::::;;;;;;;;;;;;;;;;;;;;;;;;;
267
+ ;;;;;;;;;;;;;;;;;;;;;;;;:?#:,;;;:;S#*;::?#%+++%#*.:;;;;;;;;;;;;;;::;++++++++++++++++++++*?#S+::;;;;;;;;;;;;;;;;;;;;;;;;;
268
+ ;;;;;;;;;;;;;;;;;;;;;;;;;S%,;;;;;%#*;::*#?:::;S#+;+++++++++++++++++++++++++;;;;;;;;;;;;;;;;##;:;;;;;;;;;;;;;;;;;;;;;;;;;
269
+ ;;;;;;;;;;;;;;;;;;;;;;;:;#%:;;;;*#?+::;#S:::::S#*%%SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS?S#;::;;;;;;;;;;;;;;;;;;;;;;;;
270
+ ;;;;;;;;;;;;;;;;;;;;;;;:;S%;+;;;%#*+::+#%:::::S#S?+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+%##;::;;;;;;;;;;;;;;;;;;;;;;;;
271
+ ;;;;;;;;;;;;;;;;;;;;;;;:;SS++;;;%#**::+#?::::;#S:,,:::::::::::::::::::::::::::::::::::::::,+#%::;;;;;;;;;;;;;;;;;;;;;;;;
272
+ ;;;;;;;;;;;;;;;;;;;;;;::;SS?*+;;%#?*;:;#S::::+#?,;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,S#;:::::;;;;;;;;;;;;;;;;;;;;
273
+ ;;;;;;;;;;;;;;;;;;;;;;;:;S#S*+;;*#%*+::?#*:::+#?,;;;;;;;;;**;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:S#;::::;;;;;;;;;;;;;;;;;;;;;
274
+ ;;;;;;;;;;;;;;;;;;;;;;::;S##?*;;;SS**;::%#*::+#?,;;;;;;;;;++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:S#;::::;;;;;;;;;;;;;;;;;;;;;
275
+ ;;;;;;;;;;;;;;;;;;;;;;::;S##S**;;*#%**;;:?#?:;#?,+++++++++;;+++++++++++++++++++++++++++++++;S#;:::::;;;;;;;;;;;;;;;;;;;;
276
+ ;;;;;;;;;;;;;;;;;;;;;;::;S%?#?*+;;?#%**;;:*#S?#%:*++++++++++++++++++++++++++++++++++++++++*+S#;:::;;;;;;;;;;;;;;;;;;;;;;
277
+ ;;;;;;;;;;;;;;;;;;;;;;::;S%:SS?*+;;?#%**+;;;?##S;******************************************+S#;::::;;;;;;;;;;;;;;;;;;;;;
278
+ ;;;;;;;;;;;;;;;;;;;;;:::;SS,;#S??+;;*#S?*+;;:;?##%?******??%%SSSSSSS%%??********************##;::::::;;;;;;;;;;;;;;;;;;;
279
+ ;;;;;;;;;;;;;;;;;;;;;;::;SS;,;#S??+;;;%#S?*+;;;;?S#S%??%SS?*+;:::::;+*%SSS%%????????????????##;::::::;;;;;;;;;;;;;;;;;;;
280
+ ;;;;;;;;;;;;;;;;;;;;;;::;SS;;,:S#??*+;;+%#S%?*++;;+?##S*;,,,,:::::::,,,,;?##SSSS%%%???????%%##;::::;;;;;;;;;;;;;;;;;;;;;
281
+ ;;;;;;;;;;;;;;;;;;;;;;::;SS*+;:,*#S??*+;;+?S#S%?**?SS+,,::;;;;;::::;;;;::,:?#%**?%SSSSSSSSS%%S;:::;;;;;;;;;;;;;;;;;;;;;;
282
+ ;;;;;;;;;;;;;;;;;;;;;;::;S#%**+;,:?SS%?**+;;+?S###%+,,:;;;;;;+**???**;;;;;:,;%#S*;;;;;;;;;::?S;:::;;;;;;;;;;;;;;;;;;;;;;
283
+ ;;;;;;;;;;;;;;;;;;;;;;::;S##S?*++;::*%SSSSS%%%S%*:,,:;;;;;;*%SS%???%SSS?*+;;:,;%##%?**+++++*S#;:::;;;;;;;;;;;;;;;;;;;;;;
284
+ ;;;;;;;;;;;;;;;;;;;;;;;:;SS;%#%?*++;:::;++**+;:,,:;;;;;;;;%#?+;;;;;;;;*%SS?*+;;::+?%SSSSSSSSS#;:::;;;;;;;;;;;;;;;;;;;;;;
285
+ ;;;;;;;;;;;;;;;;;;;;;;::;SS;:+S#S?**++;;;:::::;;;;;+*+++;*S?+++++++;;;;;;*S#%**+;;:::;;;;;;:*S;:::;;;;;;;;;;;;;;;;;;;;;;
286
+ ;;;;;;;;;;;;;;;;;;;;;;;:;SS*+;;+?SSS%?**+++++++**?%S%+;;?#?*???????**++;;;;*%SS%?**++;;;;;;;%S;:::;;;;;;;;;;;;;;;;;;;;;;
287
+ ;;;;;;;;;;;;;;;;;;;;;;;::?#%?*++;;+*%SSSSS%%%%SSS%?+;;+%#SSSSSSSSSSS%%?**++;;;*%SSSS%%????%%#S;:::;;;;;;;;;;;;;;;;;;;;;;
288
+ ;;;;;;;;;;;;;;;;;;;;;;;;::%#%??**++;;;;+**???**++;;;+?S#S%%???**++*?%SSS%?**+++;;++*?%%%%%%##+:::;;;;;;;;;;;;;;;;;;;;;;;
289
+ ;;;;;;;;;;;;;;;;;;;;;;;;;::*##%???****+++;;;;;;+++*?S#S%??????***+++++*%SSS%??****+++++++*%S+:::;;;;;;;;;;;;;;;;;;;;;;;;
290
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;::;?S#SS%?????******??%%SSS%%%%SSSS%%%%????****?%SSSS%%??????%S#?;::::;;;;;;;;;;;;;;;;;;;;;;;;
291
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;:::;+?%S##SSSSSSSSS#####SSSSS#SS#######SSSSSSSSSSS#######SSS%*;::::;;;;;;;;;;;;;;;;;;;;;;;;;;
292
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::;+++********************************************+++;;::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;
293
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::::::::::::::::::::::::::::::::::::::::::::::::::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
294
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::::::::::::::::::::::::::;;;::::::::::::;;;;;;;;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
295
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::::;::::::::::;;:;;;;;;;;;;::;;:::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
296
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::::::;;;;;:;;;;;;;;;;;;;;;::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
297
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
298
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
299
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
300
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
301
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
302
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
303
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
304
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
305
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
306
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
307
+ `, ["#0077B6", "#00B4D8"]);
308
+ if (cli) {
309
+ FileTide.outputGradient(`
310
+ \t\t _______ ___ ___ _______ _______ ___ ______ _______ _______ ___ ___
311
+ \t\t| || | | | | || || | | | | | | || | | |
312
+ \t\t| ___|| | | | | ___||_ _|| | | _ || ___| | || | | |
313
+ \t\t| |___ | | | | | |___ | | | | | | | || |___ | || | | |
314
+ \t\t| ___|| | | |___ | ___| | | | | | |_| || ___| | _|| |___ | |
315
+ \t\t| | | | | || |___ | | | | | || |___ | |_ | || |
316
+ \t\t|___| |___| |_______||_______| |___| |___| |______| |_______| |_______||_______||___|
317
+ `, ["#028090", "#56cfe1"]);
318
+ } else if (!cli) {
319
+ FileTide.outputGradient(`
320
+ \t\t\t\t _______ ___ ___ _______ _______ ___ ______ _______
321
+ \t\t\t\t| || | | | | || || | | | | |
322
+ \t\t\t\t| ___|| | | | | ___||_ _|| | | _ || ___|
323
+ \t\t\t\t| |___ | | | | | |___ | | | | | | | || |___
324
+ \t\t\t\t| ___|| | | |___ | ___| | | | | | |_| || ___|
325
+ \t\t\t\t| | | | | || |___ | | | | | || |___
326
+ \t\t\t\t|___| |___| |_______||_______| |___| |___| |______| |_______|
327
+ `, ["#028090", "#56cfe1"]);
328
+ }
329
+ FileTide.outputGradient(`
330
+ ▄▄· ▄▄▄ ▄▄▄ . ▄▄▄· ▄▄▄▄▄▄▄▄ .·▄▄▄▄ ▄▄▄▄· ▄· ▄▌ .▄▄ · ▄▄▄▄▄▄▄▄ . ▌ ▐·▄▄▄ . ▐ ▄ ▄▄· • ▌ ▄ ·. ▄▄▄·▄▄▄▄▄ ▐ ▄
331
+ ▐█ ▌▪▀▄ █·▀▄.▀·▐█ ▀█ •██ ▀▄.▀·██▪ ██ ▐█ ▀█▪▐█▪██▌ ▐█ ▀. •██ ▀▄.▀·▪█·█▌▀▄.▀·•█▌▐█ ▐█ ▌▪▪ ·██ ▐███▪▐█ ▄█•██ ▪ •█▌▐█
332
+ ██ ▄▄▐▀▀▄ ▐▀▀▪▄▄█▀▀█ ▐█.▪▐▀▀▪▄▐█· ▐█▌ ▐█▀▀█▄▐█▌▐█▪ ▄▀▀▀█▄ ▐█.▪▐▀▀▪▄▐█▐█•▐▀▀▪▄▐█▐▐▌ ██ ▄▄ ▄█▀▄ ▐█ ▌▐▌▐█· ██▀· ▐█.▪ ▄█▀▄ ▐█▐▐▌
333
+ ▐███▌▐█•█▌▐█▄▄▌▐█ ▪▐▌ ▐█▌·▐█▄▄▌██. ██ ██▄▪▐█ ▐█▀·. ▐█▄▪▐█ ▐█▌·▐█▄▄▌ ███ ▐█▄▄▌██▐█▌ ▐███▌▐█▌.▐▌██ ██▌▐█▌▐█▪·• ▐█▌·▐█▌.▐▌██▐█▌
334
+ ·▀▀▀ .▀ ▀ ▀▀▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀▀▀▀▀• ·▀▀▀▀ ▀ • ▀▀▀▀ ▀▀▀ ▀▀▀ . ▀ ▀▀▀ ▀▀ █▪ ·▀▀▀ ▀█▄▀▪▀▀ █▪▀▀▀.▀ ▀▀▀ ▀█▄▀▪▀▀ █▪
335
+ `, ["#1a73e8", "#a0c4ff"]);
336
+ }
337
+ }
338
+ function _setupProcessEvents() {
339
+ process.on("exit", code => {
340
+ FileTide.outputGradient(`Exited FileTide: ${code}`, ["#00C897", "#00E0FF"]);
341
+ this.broadcastClientOffline(this.fileMessagerInstance);
342
+ });
343
+ process.on("SIGINT", () => {
344
+ FileTide.outputGradient("Exiting FileTide (Ctrl+C).", ["#00C897", "#00E0FF"]);
345
+ process.exit();
346
+ });
347
+ process.on("uncaughtException", error => {
348
+ FileTide.outputGradient(`Uncaught exception: ${error}`, ["#F94144", "#F3722C"]);
349
+ process.exit(1);
350
+ });
351
+ }
352
+ ;
353
+ module.exports = FileTideClient;
@@ -0,0 +1,349 @@
1
+ "use strict";
2
+
3
+ const chalk = require("chalk");
4
+ class ConsoleTable {
5
+ constructor(options = {}) {
6
+ this.options = {
7
+ padding: 1,
8
+ headerAlign: "center",
9
+ cellAlign: "left",
10
+ borderStyle: "solid",
11
+ headerColor: null,
12
+ borderColor: null,
13
+ cellColor: (content, columnName, rowData) => content,
14
+ columnOrder: null,
15
+ columnNames: {},
16
+ title: "",
17
+ tableNumber: null,
18
+ gradient: {
19
+ title: null,
20
+ header: null,
21
+ border: null,
22
+ cell: null
23
+ },
24
+ ...options
25
+ };
26
+ this.borderChars = this.getBorderChars(this.options.borderStyle);
27
+ }
28
+ getBorderChars(style) {
29
+ const styles = {
30
+ solid: {
31
+ topLeft: "┌",
32
+ topRight: "┐",
33
+ bottomLeft: "└",
34
+ bottomRight: "┘",
35
+ horizontal: "─",
36
+ vertical: "│",
37
+ topJoin: "┬",
38
+ bottomJoin: "┴",
39
+ leftJoin: "├",
40
+ rightJoin: "┤",
41
+ center: "┼"
42
+ },
43
+ double: {
44
+ topLeft: "╔",
45
+ topRight: "╗",
46
+ bottomLeft: "╚",
47
+ bottomRight: "╝",
48
+ horizontal: "═",
49
+ vertical: "║",
50
+ topJoin: "╦",
51
+ bottomJoin: "╩",
52
+ leftJoin: "╠",
53
+ rightJoin: "╣",
54
+ center: "╬"
55
+ },
56
+ round: {
57
+ topLeft: "╭",
58
+ topRight: "╮",
59
+ bottomLeft: "╰",
60
+ bottomRight: "╯",
61
+ horizontal: "─",
62
+ vertical: "│",
63
+ topJoin: "┬",
64
+ bottomJoin: "┴",
65
+ leftJoin: "├",
66
+ rightJoin: "┤",
67
+ center: "┼"
68
+ },
69
+ bold: {
70
+ topLeft: "┏",
71
+ topRight: "┓",
72
+ bottomLeft: "┗",
73
+ bottomRight: "┛",
74
+ horizontal: "━",
75
+ vertical: "┃",
76
+ topJoin: "┳",
77
+ bottomJoin: "┻",
78
+ leftJoin: "┣",
79
+ rightJoin: "┫",
80
+ center: "╋"
81
+ }
82
+ };
83
+ return styles[style] || styles["solid"];
84
+ }
85
+ setData(data) {
86
+ if (Array.isArray(data)) {
87
+ this.data = data;
88
+ } else if (typeof data === "object") {
89
+ this.data = Object.values(data);
90
+ } else {
91
+ throw new Error("Array or an object only.");
92
+ }
93
+ this.extractColumns();
94
+ this.calculateColumnWidths();
95
+ }
96
+ extractColumns() {
97
+ if (this.options.columnOrder && Array.isArray(this.options.columnOrder)) {
98
+ this.columns = this.options.columnOrder;
99
+ } else {
100
+ const columnsSet = new Set();
101
+ this.data.forEach(item => {
102
+ Object.keys(item).forEach(key => columnsSet.add(key));
103
+ });
104
+ this.columns = Array.from(columnsSet);
105
+ }
106
+ }
107
+ calculateColumnWidths() {
108
+ const {
109
+ padding
110
+ } = this.options;
111
+ this.columnWidths = {};
112
+ this.totalWidth = 0;
113
+ this.columns.forEach(column => {
114
+ const headerName = this.options.columnNames[column] || column;
115
+ let maxWidth = String(headerName).length;
116
+ this.data.forEach(item => {
117
+ const cellContent = item[column] !== undefined ? String(item[column]) : "";
118
+ maxWidth = Math.max(maxWidth, cellContent.length);
119
+ });
120
+ const columnWidth = maxWidth + padding * 2;
121
+ this.columnWidths[column] = columnWidth;
122
+ this.totalWidth += columnWidth;
123
+ });
124
+ this.totalWidth += this.columns.length + 1;
125
+ }
126
+ alignText(text, width, align) {
127
+ const {
128
+ padding
129
+ } = this.options;
130
+ const textLength = text.length;
131
+ let totalPadding = width - textLength;
132
+ let leftPadding = " ".repeat(padding);
133
+ let rightPadding = " ".repeat(padding);
134
+ if (totalPadding < padding * 2) {
135
+ leftPadding = "";
136
+ rightPadding = "";
137
+ } else {
138
+ totalPadding -= padding * 2;
139
+ if (align === "left") {
140
+ rightPadding += " ".repeat(totalPadding);
141
+ } else if (align === "right") {
142
+ leftPadding += " ".repeat(totalPadding);
143
+ } else {
144
+ const half = Math.floor(totalPadding / 2);
145
+ leftPadding += " ".repeat(half);
146
+ rightPadding += " ".repeat(totalPadding - half);
147
+ }
148
+ }
149
+ return leftPadding + text + rightPadding;
150
+ }
151
+ generateGradientText(text, startColor, endColor) {
152
+ const length = text.length;
153
+ const startRGB = this.hexToRgb(startColor);
154
+ const endRGB = this.hexToRgb(endColor);
155
+ let gradientText = "";
156
+ for (let i = 0; i < length; i++) {
157
+ const ratio = i / (length - 1 || 1);
158
+ const color = {
159
+ r: Math.round(startRGB.r + ratio * (endRGB.r - startRGB.r)),
160
+ g: Math.round(startRGB.g + ratio * (endRGB.g - startRGB.g)),
161
+ b: Math.round(startRGB.b + ratio * (endRGB.b - startRGB.b))
162
+ };
163
+ gradientText += chalk.rgb(color.r, color.g, color.b)(text[i]);
164
+ }
165
+ return gradientText;
166
+ }
167
+ hexToRgb(hex) {
168
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
169
+ return result ? {
170
+ r: parseInt(result[1], 16),
171
+ g: parseInt(result[2], 16),
172
+ b: parseInt(result[3], 16)
173
+ } : null;
174
+ }
175
+ generateBorder(type) {
176
+ const {
177
+ columns,
178
+ columnWidths
179
+ } = this;
180
+ let {
181
+ horizontal,
182
+ vertical,
183
+ topLeft,
184
+ topRight,
185
+ bottomLeft,
186
+ bottomRight,
187
+ topJoin,
188
+ bottomJoin,
189
+ leftJoin,
190
+ rightJoin,
191
+ center
192
+ } = this.borderChars;
193
+ const {
194
+ borderColor
195
+ } = this.options;
196
+ const borderGradient = this.options.gradient.border;
197
+ if (borderGradient && borderGradient.length === 2) {
198
+ const chars = [topLeft, topRight, bottomLeft, bottomRight, horizontal, vertical, topJoin, bottomJoin, leftJoin, rightJoin, center];
199
+ const coloredChars = {};
200
+ chars.forEach((char, index) => {
201
+ coloredChars[char] = this.generateGradientText(char, borderGradient[0], borderGradient[1]);
202
+ });
203
+ bottomRight = coloredChars[bottomRight];
204
+ bottomLeft = coloredChars[bottomLeft];
205
+ topRight = coloredChars[topRight];
206
+ topLeft = coloredChars[topLeft];
207
+ horizontal = coloredChars[horizontal];
208
+ vertical = coloredChars[vertical];
209
+ bottomJoin = coloredChars[bottomJoin];
210
+ rightJoin = coloredChars[rightJoin];
211
+ leftJoin = coloredChars[leftJoin];
212
+ topJoin = coloredChars[topJoin];
213
+ center = coloredChars[center];
214
+ } else if (borderColor) {
215
+ bottomRight = borderColor(bottomRight);
216
+ bottomLeft = borderColor(bottomLeft);
217
+ topRight = borderColor(topRight);
218
+ topLeft = borderColor(topLeft);
219
+ horizontal = borderColor(horizontal);
220
+ vertical = borderColor(vertical);
221
+ bottomJoin = borderColor(bottomJoin);
222
+ rightJoin = borderColor(rightJoin);
223
+ leftJoin = borderColor(leftJoin);
224
+ topJoin = borderColor(topJoin);
225
+ center = borderColor(center);
226
+ }
227
+ let border = "";
228
+ columns.forEach((column, index) => {
229
+ const first = index === 0;
230
+ const last = index === columns.length - 1;
231
+ const width = columnWidths[column];
232
+ const line = horizontal.repeat(width);
233
+ if (type === "top") {
234
+ border += first ? topLeft : topJoin;
235
+ } else if (type === "bottom") {
236
+ border += first ? bottomLeft : bottomJoin;
237
+ } else {
238
+ border += first ? leftJoin : center;
239
+ }
240
+ border += line;
241
+ if (last) {
242
+ if (type === "top") {
243
+ border += topRight;
244
+ } else if (type === "bottom") {
245
+ border += bottomRight;
246
+ } else {
247
+ border += rightJoin;
248
+ }
249
+ }
250
+ });
251
+ return border;
252
+ }
253
+ generateRow(rowData, headerRow = false) {
254
+ const {
255
+ columns,
256
+ columnWidths
257
+ } = this;
258
+ let {
259
+ vertical
260
+ } = this.borderChars;
261
+ const {
262
+ headerAlign,
263
+ cellAlign,
264
+ headerColor,
265
+ cellColor
266
+ } = this.options;
267
+ const align = headerRow ? headerAlign : cellAlign;
268
+ const headerGradient = this.options.gradient.header;
269
+ const cellGradient = this.options.gradient.cell;
270
+ const borderGradient = this.options.gradient.border;
271
+ if (borderGradient && borderGradient.length === 2) {
272
+ vertical = this.generateGradientText(vertical, borderGradient[0], borderGradient[1]);
273
+ } else if (this.options.borderColor) {
274
+ vertical = this.options.borderColor(vertical);
275
+ }
276
+ let row = "";
277
+ columns.forEach((column, index) => {
278
+ const content = rowData[column] !== undefined ? String(rowData[column]) : "";
279
+ const width = columnWidths[column];
280
+ const alignedText = this.alignText(content, width, align);
281
+ let cellContent = alignedText;
282
+ const first = index === 0;
283
+ if (headerRow) {
284
+ if (headerGradient && headerGradient.length === 2) {
285
+ cellContent = this.generateGradientText(cellContent, headerGradient[0], headerGradient[1]);
286
+ } else if (headerColor) {
287
+ cellContent = headerColor(cellContent);
288
+ }
289
+ } else {
290
+ if (cellGradient && cellGradient.length === 2) {
291
+ cellContent = this.generateGradientText(cellContent, cellGradient[0], cellGradient[1]);
292
+ } else if (cellColor) {
293
+ cellContent = cellColor(cellContent, column, rowData);
294
+ }
295
+ }
296
+ if (first) {
297
+ row += vertical;
298
+ }
299
+ row += cellContent + vertical;
300
+ });
301
+ return row;
302
+ }
303
+ setTitle(title, tableNumber = null) {
304
+ this.options.title = title;
305
+ if (tableNumber !== null) {
306
+ this.options.tableNumber = tableNumber;
307
+ }
308
+ }
309
+ renderTitle() {
310
+ let titleText = this.options.title;
311
+ if (this.options.tableNumber !== null) {
312
+ titleText = titleText;
313
+ }
314
+ const totalWidth = this.totalWidth - 2;
315
+ const titleLength = titleText.length;
316
+ let leftPadding = Math.floor((totalWidth - titleLength) / 2);
317
+ if (leftPadding < 0) leftPadding = 0;
318
+ let titleLine = " ".repeat(leftPadding) + titleText;
319
+ const titleGradient = this.options.gradient.title;
320
+ if (titleGradient && titleGradient.length === 2) {
321
+ titleLine = this.generateGradientText(titleLine.trim(), titleGradient[0], titleGradient[1]);
322
+ }
323
+ return titleLine;
324
+ }
325
+ render() {
326
+ const {
327
+ data
328
+ } = this;
329
+ if (!data || data.length === 0) return "";
330
+ const lines = [];
331
+ if (this.options.title) {
332
+ const title = this.renderTitle();
333
+ lines.push(title);
334
+ }
335
+ lines.push(this.generateBorder("top"));
336
+ const headerData = {};
337
+ this.columns.forEach(column => {
338
+ headerData[column] = this.options.columnNames[column] || column;
339
+ });
340
+ lines.push(this.generateRow(headerData, true));
341
+ lines.push(this.generateBorder("middle"));
342
+ data.forEach(rowData => {
343
+ lines.push(this.generateRow(rowData));
344
+ });
345
+ lines.push(this.generateBorder("bottom"));
346
+ return lines.join("\n");
347
+ }
348
+ }
349
+ module.exports = ConsoleTable;
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ const FileTideClient = require("./FileTideClient.js");
5
+ const os = require("os");
6
+ const args = process.argv.slice(2);
7
+ const tideUrl = args[0] || "http://localhost:9269";
8
+ const deviceName = args[1] || os.hostname();
9
+ const currentRoom = args[2] || "file-room";
10
+ const client = new FileTideClient(deviceName, tideUrl, currentRoom, true, true);
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@trap_stevo/filetide-client",
3
+ "version": "0.0.0",
4
+ "description": "Seamless, real-time file transfers between devices with effortless connectivity. Allowing for powerful, instant, secure, and cross-platform file sharing, enabling efficient and reliable data transfers in any network environment.",
5
+ "main": "dist/cjs/FileTideClient.js",
6
+ "exports": {
7
+ ".": "./dist/cjs/FileTideClient.js"
8
+ },
9
+ "scripts": {
10
+ "build": "babel src -d dist/cjs --env-name cjs",
11
+ "start": "node ./dist/cjs/FileTideClient.js"
12
+ },
13
+ "keywords": [
14
+ "Legendary",
15
+ "Enlightened",
16
+ "Steven Compton",
17
+ "Magical",
18
+ "real-time",
19
+ "file-transfer",
20
+ "file-sharing",
21
+ "file-sync",
22
+ "peer-to-peer",
23
+ "p2p",
24
+ "networking",
25
+ "data-transfer",
26
+ "file-upload",
27
+ "file-download",
28
+ "secure-transfer",
29
+ "live-file-transfer",
30
+ "cross-platform",
31
+ "fast-transfer",
32
+ "file-syncing",
33
+ "data-streaming",
34
+ "real-time-sync"
35
+ ],
36
+ "author": "Steven Compton",
37
+ "license": "ISC",
38
+ "dependencies": {
39
+ "@trap_stevo/filetide": "^0.0.31",
40
+ "@trap_stevo/iotide": "^0.0.37",
41
+ "@trap_stevo/legendarybuilderpronodejs-utilities": "^1.0.36",
42
+ "chalk": "^4.1.2",
43
+ "readline": "^1.3.0"
44
+ },
45
+ "devDependencies": {
46
+ "@babel/cli": "^7.24.8",
47
+ "@babel/core": "^7.25.2",
48
+ "@babel/plugin-proposal-class-properties": "^7.18.6",
49
+ "@babel/plugin-transform-runtime": "^7.24.7",
50
+ "@babel/preset-env": "^7.25.3"
51
+ }
52
+ }