@trap_stevo/filetide 0.0.69 → 0.0.71
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/LICENSE.md +8 -2
- package/dist/cjs/FileMessager.js +15 -0
- package/dist/cjs/FileMessagerClient.js +22 -17
- package/dist/cjs/FileTide.js +256 -179
- package/dist/cjs/FileTideEnvironment.js +8 -0
- package/dist/cjs/HUDComponents/FileTideCommunicationConfigurations.js +12 -0
- package/dist/cjs/HUDComponents/FileTideEnvironment.js +8 -0
- package/dist/cjs/HUDManagers/FileNetClientManager.js +8 -0
- package/dist/cjs/HUDManagers/FileTideDebugUtilityManager.js +44 -5
- package/dist/cjs/HUDManagers/FileTideUniversalUtilityManager.js +109 -0
- package/dist/cjs/HUDManagers/TidalyticsUtilityManager.js +44 -2
- package/dist/cjs/HUDManagers/TideTokenEnforcementManager.js +149 -0
- package/package.json +9 -6
package/LICENSE.md
CHANGED
|
@@ -30,7 +30,11 @@ Without the express written permission of the Licensor, Licensee shall not:
|
|
|
30
30
|
2. Include the Package's source code or object code in any distributed software, service, or application.
|
|
31
31
|
3. Use the Package to create a competing product or service that replicates the functionality of the Package.
|
|
32
32
|
4. Make the Package publicly available, including uploading it to public repositories or including it in distributed software bundles.
|
|
33
|
-
5.
|
|
33
|
+
5. Attempt to extract or analyze the functionality, structure, or behavior of the Package through runtime inspection, instrumentation, reflection, or behavioral analysis.
|
|
34
|
+
6. Privately share, sublicense, or distribute the Package or any portion thereof, whether internally within an organization or externally to any third party, without written authorization.
|
|
35
|
+
7. Remove, obscure, obfuscate, or alter any attribution, copyright notices, proprietary labels, or identifiers included in the Package.
|
|
36
|
+
8. Re-upload, rename, fork, or redistribute the Package or any portion thereof on any registry, platform, or namespace other than that explicitly maintained by or authorized by the Licensor.
|
|
37
|
+
9. Use the Package in any way that violates applicable laws, infringes on third-party rights, or breaches this agreement.
|
|
34
38
|
|
|
35
39
|
## 5. **Wrapper API Creation**
|
|
36
40
|
Licensee is permitted to create and distribute Wrapper APIs, provided that:
|
|
@@ -69,5 +73,7 @@ Licensee agrees to indemnify and hold harmless the Licensor from any and all cla
|
|
|
69
73
|
## 10. **Governing Law and Dispute Resolution**
|
|
70
74
|
This Agreement shall be governed by and construed in accordance with the laws of **the state of Georgia**, without regard to its conflict of law principles. Any disputes arising out of this Agreement shall be resolved through arbitration in **the state of Georgia**.
|
|
71
75
|
|
|
72
|
-
##
|
|
76
|
+
## 11. **Amendments**
|
|
73
77
|
Licensor reserves the right to modify or update this Agreement at any time. Any changes to the Agreement will be effective **30 days** after being posted to **https://www.npmjs.com/package/@trap_stevo/filetide**. The Licensor will notify Licensees of any material changes by **posting a notice in the package’s release notes on NPM**. Continued use of the package after the notice period constitutes acceptance of the modified terms.
|
|
78
|
+
|
|
79
|
+
**This Agreement applies to all versions of @trap_stevo/filetide downloaded, installed, or used on or after the Effective Date of this license, regardless of version number.** Use of any version of the Package after this date shall be deemed acceptance of and agreement to the terms of this license, unless otherwise explicitly stated by the Licensor.
|
package/dist/cjs/FileMessager.js
CHANGED
|
@@ -64,6 +64,13 @@ class FileMessager {
|
|
|
64
64
|
}
|
|
65
65
|
onDisconnect(connectionRes, socket) {
|
|
66
66
|
console.log(`Client disconnected ~ ${socket.id}`);
|
|
67
|
+
const currentOnlineClient = FileNetClientManager.getOnlineClientByConnectionID(socket.id);
|
|
68
|
+
if (currentOnlineClient) {
|
|
69
|
+
this.handleClientOffline({}, {
|
|
70
|
+
connectionID: currentOnlineClient.id,
|
|
71
|
+
...currentOnlineClient
|
|
72
|
+
});
|
|
73
|
+
}
|
|
67
74
|
this.onlineClients.delete(socket.id);
|
|
68
75
|
return;
|
|
69
76
|
}
|
|
@@ -1165,6 +1172,14 @@ class FileMessager {
|
|
|
1165
1172
|
}
|
|
1166
1173
|
return client;
|
|
1167
1174
|
}
|
|
1175
|
+
getClient(clientID) {
|
|
1176
|
+
const client = FileNetClientManager.getOnlineClient(clientID);
|
|
1177
|
+
if (!client) {
|
|
1178
|
+
console.log(`Client ~ ${clientID} not found.`);
|
|
1179
|
+
return;
|
|
1180
|
+
}
|
|
1181
|
+
return client;
|
|
1182
|
+
}
|
|
1168
1183
|
requestFromClient(requesterID, senderID, filePath = process.cwd(), destinationPath) {
|
|
1169
1184
|
const senderConnectionID = FileNetClientManager.getOnlineClient(senderID).id;
|
|
1170
1185
|
const client = this.getClientFromID(senderConnectionID);
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
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"); }
|
|
3
6
|
const {
|
|
4
7
|
HUDIoTide
|
|
5
8
|
} = require("@trap_stevo/iotide-client");
|
|
@@ -24,8 +27,9 @@ const {
|
|
|
24
27
|
const {
|
|
25
28
|
FileUtilityManager
|
|
26
29
|
} = require("./HUDManagers/FileUtilityManager");
|
|
30
|
+
var _FileMessagerClient_brand = /*#__PURE__*/new WeakSet();
|
|
27
31
|
class FileMessagerClient {
|
|
28
|
-
constructor(
|
|
32
|
+
constructor(_options = {}, transportOptions = {
|
|
29
33
|
parallelChunks: 3,
|
|
30
34
|
maxRetries: 3
|
|
31
35
|
}, messagerSettings = {
|
|
@@ -33,13 +37,14 @@ class FileMessagerClient {
|
|
|
33
37
|
reconnectionAttempts: 15,
|
|
34
38
|
maxReconnectionDelay: 10000
|
|
35
39
|
}) {
|
|
40
|
+
_classPrivateMethodInitSpec(this, _FileMessagerClient_brand);
|
|
36
41
|
const {
|
|
37
42
|
maxReconnectionAttempts = 15,
|
|
38
43
|
reconnectionAttempts = 15,
|
|
39
44
|
maxReconnectionDelay = 10000,
|
|
40
45
|
...messagerConfigurations
|
|
41
46
|
} = messagerSettings;
|
|
42
|
-
this.clientOptions = FileMessagerConfigManager.getClientOptions(
|
|
47
|
+
this.clientOptions = FileMessagerConfigManager.getClientOptions(_options);
|
|
43
48
|
this.transporter = new FileTransferManager(transportOptions);
|
|
44
49
|
this.activeTransferTypes = new Map();
|
|
45
50
|
this.clientTide = new HUDIoTide(maxReconnectionAttempts, reconnectionAttempts, maxReconnectionDelay, {
|
|
@@ -49,22 +54,8 @@ class FileMessagerClient {
|
|
|
49
54
|
});
|
|
50
55
|
this.clients = new Map();
|
|
51
56
|
}
|
|
52
|
-
createClientInstance(clientID, clientOptions, options = {}, headers = {}, onConnect = null, onDisconnect = null, authURL = "", authHeaders = {}, useAuthentication = false, queryAuthToken = false) {
|
|
53
|
-
this.clientTide.createIO(clientID, clientOptions.url, {
|
|
54
|
-
transports: ["websocket"],
|
|
55
|
-
...options
|
|
56
|
-
}, headers, authURL, authHeaders, useAuthentication, queryAuthToken, onConnect, async () => {
|
|
57
|
-
FileTransferTrackingManager.outputCurrentTransfers();
|
|
58
|
-
FileTransferRecoveryManager.flushToDisk();
|
|
59
|
-
if (onDisconnect) {
|
|
60
|
-
await onDisconnect();
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
FileTideDebugUtilityManager.outputGradient(`\n[FileTide ~ File Messager] ~ Created client with ID ${clientID} and socket ${clientID}!`, significantMessageColors);
|
|
64
|
-
return clientID;
|
|
65
|
-
}
|
|
66
57
|
joinRoom(userID, roomName, options = {}, headers = {}, onConnect = null, onDisconnect = null, authURL = "", authHeaders = {}, useAuthentication = false, queryAuthToken = false) {
|
|
67
|
-
const socketName = this.
|
|
58
|
+
const socketName = _assertClassBrand(_FileMessagerClient_brand, this, _createClientInstance).call(this, userID, {
|
|
68
59
|
url: this.clientOptions.url
|
|
69
60
|
}, options, headers, onConnect, onDisconnect, authURL, authHeaders, useAuthentication, queryAuthToken);
|
|
70
61
|
return () => {
|
|
@@ -315,5 +306,19 @@ class FileMessagerClient {
|
|
|
315
306
|
}
|
|
316
307
|
}
|
|
317
308
|
}
|
|
309
|
+
function _createClientInstance(clientID, clientOptions, options = {}, headers = {}, onConnect = null, onDisconnect = null, authURL = "", authHeaders = {}, useAuthentication = false, queryAuthToken = false) {
|
|
310
|
+
this.clientTide.createIO(clientID, clientOptions.url, {
|
|
311
|
+
transports: ["websocket"],
|
|
312
|
+
...options
|
|
313
|
+
}, headers, authURL, authHeaders, useAuthentication, queryAuthToken, onConnect, async () => {
|
|
314
|
+
FileTransferTrackingManager.outputCurrentTransfers();
|
|
315
|
+
FileTransferRecoveryManager.flushToDisk();
|
|
316
|
+
if (onDisconnect) {
|
|
317
|
+
await onDisconnect();
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
FileTideDebugUtilityManager.outputGradient(`\n[FileTide ~ File Messager] ~ Created client with ID ${clientID} and socket ${clientID}!`, significantMessageColors);
|
|
321
|
+
return clientID;
|
|
322
|
+
}
|
|
318
323
|
;
|
|
319
324
|
module.exports = FileMessagerClient;
|
package/dist/cjs/FileTide.js
CHANGED
|
@@ -11,11 +11,18 @@ const chalk = require("chalk");
|
|
|
11
11
|
const path = require("path");
|
|
12
12
|
const fs = require("fs");
|
|
13
13
|
const os = require("os");
|
|
14
|
+
require("./HUDComponents/FileTideCommunicationConfigurations.js");
|
|
15
|
+
require("./HUDComponents/FileTideEnvironment.js");
|
|
14
16
|
const {
|
|
15
17
|
FileTideDebugUtilityManager,
|
|
16
18
|
significantMessageColors,
|
|
17
19
|
errorMessageColors
|
|
18
20
|
} = require("./HUDManagers/FileTideDebugUtilityManager.js");
|
|
21
|
+
const {
|
|
22
|
+
displayFileTideAuthor,
|
|
23
|
+
displayFileTideTitle,
|
|
24
|
+
displayFileTideLogo
|
|
25
|
+
} = require("./HUDManagers/FileTideUniversalUtilityManager.js");
|
|
19
26
|
const {
|
|
20
27
|
FileTransferTrackingManager
|
|
21
28
|
} = require("./HUDManagers/FileTransferTrackingManager.js");
|
|
@@ -23,20 +30,22 @@ const {
|
|
|
23
30
|
FileTransferReceiverManager
|
|
24
31
|
} = require("./HUDManagers/FileTransferReceiverManager.js");
|
|
25
32
|
const FileTransferRecoveryManager = require("./HUDManagers/FileTransferRecoveryManager.js");
|
|
33
|
+
const TideTokenEnforcer = require("./HUDManagers/TideTokenEnforcementManager.js");
|
|
26
34
|
const {
|
|
27
35
|
FileNetConfigManager
|
|
28
36
|
} = require("./HUDManagers/FileNetConfigManager.js");
|
|
29
37
|
const {
|
|
30
38
|
FileUtilityManager
|
|
31
39
|
} = require("./HUDManagers/FileUtilityManager.js");
|
|
32
|
-
const ConsoleProgressBarManager = require("./HUDComponents/ConsoleProgressBarManager");
|
|
40
|
+
const ConsoleProgressBarManager = require("./HUDComponents/ConsoleProgressBarManager.js");
|
|
33
41
|
const ChunkCapacitor = require("./HUDComponents/ChunkCapacitor.js");
|
|
34
42
|
const ConsoleTable = require("./HUDComponents/ConsoleTable.js");
|
|
35
|
-
const FileMessagerClient = require("./FileMessagerClient");
|
|
36
|
-
const FileMessager = require("./FileMessager");
|
|
43
|
+
const FileMessagerClient = require("./FileMessagerClient.js");
|
|
44
|
+
const FileMessager = require("./FileMessager.js");
|
|
37
45
|
var _FileTide_brand = /*#__PURE__*/new WeakSet();
|
|
38
46
|
class FileTide {
|
|
39
47
|
constructor(debugMode = true) {
|
|
48
|
+
// --- FileTide Event Management ---
|
|
40
49
|
/**
|
|
41
50
|
* Set up file transfer event listeners natively.
|
|
42
51
|
* Automatically checks and creates directories as needed.
|
|
@@ -60,6 +69,23 @@ class FileTide {
|
|
|
60
69
|
return;
|
|
61
70
|
}
|
|
62
71
|
|
|
72
|
+
// --- FileTide TideToken Enforcement Management ---
|
|
73
|
+
|
|
74
|
+
updateTideTokenEnforcementCallbackConfigurations(updatedConfigurations = {}) {
|
|
75
|
+
TideTokenEnforcer.updateTideTokenEnforcementCallbackConfigurations(updatedConfigurations);
|
|
76
|
+
}
|
|
77
|
+
async registerTideToken(tideToken, meta = {}) {
|
|
78
|
+
return await TideTokenEnforcer.seal(tideToken, meta);
|
|
79
|
+
}
|
|
80
|
+
async inspectTideToken(tideToken) {
|
|
81
|
+
return await TideTokenEnforcer.inspect(tideToken);
|
|
82
|
+
}
|
|
83
|
+
getTideToken(scope = "default") {
|
|
84
|
+
return TideTokenEnforcer.getKey(scope);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// --- FileTide Gateway Management ---
|
|
88
|
+
|
|
63
89
|
/**
|
|
64
90
|
* Initialize and start the server.
|
|
65
91
|
* @param {Object} serverOptions - Configuration for server (e.g., port, useCors, useHTTPS)
|
|
@@ -67,12 +93,14 @@ class FileTide {
|
|
|
67
93
|
* @param {...any} tideConfigurations - Additional configuration objects for customizing FileTide behavior
|
|
68
94
|
*/
|
|
69
95
|
launchFileTide(serverOptions = {}, onLaunch, ...tideConfigurations) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
onLaunch
|
|
75
|
-
|
|
96
|
+
TideTokenEnforcer.protect(() => {
|
|
97
|
+
this.fileNet = new FileMessager(serverOptions, ...tideConfigurations);
|
|
98
|
+
this.fileNet.start();
|
|
99
|
+
FileTide.outputGradient("[FileTide] ~ FileNet launched successfully!", significantMessageColors);
|
|
100
|
+
if (onLaunch) {
|
|
101
|
+
onLaunch(this.fileNet);
|
|
102
|
+
}
|
|
103
|
+
}, "default")();
|
|
76
104
|
return;
|
|
77
105
|
}
|
|
78
106
|
|
|
@@ -107,39 +135,43 @@ class FileTide {
|
|
|
107
135
|
reconnectionAttempts: 15,
|
|
108
136
|
maxReconnectionDelay: 10000
|
|
109
137
|
}, roomName, userID, onLaunch, onIncomingFile, onIncomingTransfer, onTransferBarrier, onTransferProgress, enableTransferBarrier = true, options = {}, headers = {}, onConnect = null, onDisconnect = null, authURL = "", authHeaders = {}, useAuthentication = false, queryAuthToken = false) {
|
|
110
|
-
|
|
111
|
-
this.
|
|
112
|
-
|
|
113
|
-
const currentClientDetails = this.clientDetails.get(userID);
|
|
114
|
-
if (currentClientDetails && currentClientDetails.unauthorized) {
|
|
115
|
-
const {
|
|
116
|
-
onCurrentClientUnauthorized
|
|
117
|
-
} = options;
|
|
118
|
-
FileTide.outputGradient(`[FileTide ~ FileNet] ~ Unauthorized access detected.`, errorMessageColors);
|
|
119
|
-
if (onCurrentClientUnauthorized) {
|
|
120
|
-
onCurrentClientUnauthorized({
|
|
121
|
-
...currentClientDetails,
|
|
122
|
-
userID
|
|
123
|
-
});
|
|
138
|
+
TideTokenEnforcer.protect(() => {
|
|
139
|
+
if (this.clients.has(userID)) {
|
|
140
|
+
this.stopMessager(userID);
|
|
124
141
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
142
|
+
const currentClientDetails = this.clientDetails.get(userID);
|
|
143
|
+
if (currentClientDetails && currentClientDetails.unauthorized) {
|
|
144
|
+
const {
|
|
145
|
+
onCurrentClientUnauthorized
|
|
146
|
+
} = options;
|
|
147
|
+
FileTide.outputGradient(`[FileTide ~ FileNet] ~ Unauthorized access detected.`, errorMessageColors);
|
|
148
|
+
if (onCurrentClientUnauthorized) {
|
|
149
|
+
onCurrentClientUnauthorized({
|
|
150
|
+
...currentClientDetails,
|
|
151
|
+
userID
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const newClient = new FileMessagerClient(clientOptions, transportOptions, messagerSettings);
|
|
157
|
+
const enterRoom = newClient.joinRoom(userID, roomName, connectionOptions, headers, onConnect, onDisconnect, authURL, authHeaders, useAuthentication, queryAuthToken);
|
|
158
|
+
this.transferBarrier = enableTransferBarrier;
|
|
159
|
+
this.clientShorePolicies.set(userID, [FileUtilityManager.getTidePath(">Downloads"), FileUtilityManager.getTidePath(">Documents"), FileUtilityManager.getTidePath(">Desktop"), FileUtilityManager.getTidePath(">Photos"), FileUtilityManager.getTidePath(">Videos"), FileUtilityManager.getTidePath(">Music")]);
|
|
160
|
+
this.clients.set(userID, newClient);
|
|
161
|
+
this.clientDetails.set(userID, {
|
|
162
|
+
unauthorized: false,
|
|
163
|
+
userID
|
|
164
|
+
});
|
|
165
|
+
FileTide.outputGradient(`[FileTide] ~ Messager launched successfully for client ~ ${userID}!`, significantMessageColors);
|
|
166
|
+
_assertClassBrand(_FileTide_brand, this, _setupFileEventListeners).call(this, userID, newClient, onTransferProgress, onIncomingTransfer, onIncomingFile, onTransferBarrier, options);
|
|
167
|
+
if (onLaunch) {
|
|
168
|
+
onLaunch(newClient, enterRoom);
|
|
169
|
+
}
|
|
170
|
+
}, "default")();
|
|
141
171
|
return;
|
|
142
172
|
}
|
|
173
|
+
// --- FileTide Path Management ---
|
|
174
|
+
|
|
143
175
|
async getDirectoryData(directoryPath) {
|
|
144
176
|
return await FileUtilityManager.getDirectoryData(directoryPath);
|
|
145
177
|
}
|
|
@@ -152,12 +184,6 @@ class FileTide {
|
|
|
152
184
|
getTidePath(inputPath) {
|
|
153
185
|
return FileUtilityManager.getTidePath(inputPath);
|
|
154
186
|
}
|
|
155
|
-
getTidingTransferStates() {
|
|
156
|
-
return FileTransferRecoveryManager.memoryStorage;
|
|
157
|
-
}
|
|
158
|
-
saveTransferStates() {
|
|
159
|
-
FileTransferRecoveryManager.flushToDisk();
|
|
160
|
-
}
|
|
161
187
|
filterFilesAndDirectories(dirPath, filterContent = [], callback) {
|
|
162
188
|
FileUtilityManager.filterFilesAndDirectories(dirPath, filterContent, (files, error) => {
|
|
163
189
|
if (callback) {
|
|
@@ -165,46 +191,73 @@ class FileTide {
|
|
|
165
191
|
}
|
|
166
192
|
});
|
|
167
193
|
}
|
|
168
|
-
listFilesFromClient(recipientID, depth = 1) {
|
|
169
|
-
const clientID = this.currentUserID;
|
|
170
|
-
const clientMessager = this.clients.get(clientID);
|
|
171
|
-
if (!clientMessager) {
|
|
172
|
-
FileTide.outputGradient(`[FileTide] Client ~ ${clientID} not found.`, errorMessageColors);
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
clientMessager.clientTide.emitEvent(clientID, "check-client-banned", {
|
|
176
|
-
clientID,
|
|
177
|
-
tideID: clientMessager.clientTide.sockets[clientID].tideID
|
|
178
|
-
});
|
|
179
|
-
clientMessager.listFiles(clientID, recipientID, depth);
|
|
180
|
-
}
|
|
181
194
|
async listFiles(directories, depth = 1, onDirectory) {
|
|
182
195
|
return await FileUtilityManager.listFiles(directories, depth, onDirectory);
|
|
183
196
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
190
|
-
const shorePolicies = Array.from(clientShorePolicies.values());
|
|
191
|
-
const currentShores = new Set(clientShorePolicies);
|
|
192
|
-
this.clientShorePolicies.set(clientID, shorePolicies.filter(shorePolicy => !currentShores.has(shorePolicy)));
|
|
193
|
-
return true;
|
|
197
|
+
|
|
198
|
+
// --- FileTide Transfer State Management ---
|
|
199
|
+
|
|
200
|
+
async getTidingTransferStates() {
|
|
201
|
+
return await TideTokenEnforcer.protect(() => FileTransferRecoveryManager.memoryStorage, "default")();
|
|
194
202
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
+
saveTransferStates() {
|
|
204
|
+
TideTokenEnforcer.protect(() => {
|
|
205
|
+
FileTransferRecoveryManager.flushToDisk();
|
|
206
|
+
}, "default")();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// --- FileTide Remote Files Management ---
|
|
210
|
+
|
|
211
|
+
listFilesFromClient(recipientID, depth = 1) {
|
|
212
|
+
TideTokenEnforcer.protect(() => {
|
|
213
|
+
const clientID = this.currentUserID;
|
|
214
|
+
const clientMessager = this.clients.get(clientID);
|
|
215
|
+
if (!clientMessager) {
|
|
216
|
+
FileTide.outputGradient(`[FileTide] Client ~ ${clientID} not found.`, errorMessageColors);
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
clientMessager.clientTide.emitEvent(clientID, "check-client-banned", {
|
|
220
|
+
clientID,
|
|
221
|
+
tideID: clientMessager.clientTide.sockets[clientID].tideID
|
|
222
|
+
});
|
|
223
|
+
clientMessager.listFiles(clientID, recipientID, depth);
|
|
224
|
+
}, "default")();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// --- FileTide Shore Policy Management ---
|
|
228
|
+
|
|
229
|
+
async clearShorePolicies(clientID, shores = []) {
|
|
230
|
+
return await TideTokenEnforcer.protect(() => {
|
|
231
|
+
let clientShorePolicies = this.clientShorePolicies.get(clientID);
|
|
232
|
+
if (!shores || shores.length <= 0 || !clientShorePolicies || !clientID) {
|
|
233
|
+
FileTide.outputGradient(`[FileTide] Did not clear from client ~ ${clientID} shore policies.`, errorMessageColors);
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
const shorePolicies = Array.from(clientShorePolicies.values());
|
|
237
|
+
const currentShores = new Set(clientShorePolicies);
|
|
238
|
+
this.clientShorePolicies.set(clientID, shorePolicies.filter(shorePolicy => !currentShores.has(shorePolicy)));
|
|
239
|
+
return true;
|
|
240
|
+
}, "default")();
|
|
241
|
+
}
|
|
242
|
+
async addShorePolicies(clientID, shores = []) {
|
|
243
|
+
return await TideTokenEnforcer.protect(() => {
|
|
244
|
+
const clientShorePolicies = this.clientShorePolicies.get(clientID);
|
|
245
|
+
if (!shores || shores.length <= 0 || !clientShorePolicies || !clientID) {
|
|
246
|
+
FileTide.outputGradient(`[FileTide] Did not add to client ~ ${clientID} shore policies.`, errorMessageColors);
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
this.clientShorePolicies.set(clientID, [...new Set([...clientShorePolicies, ...shores])]);
|
|
250
|
+
return true;
|
|
251
|
+
}, "default")();
|
|
203
252
|
}
|
|
204
|
-
getShorePolicies(clientID) {
|
|
205
|
-
return
|
|
253
|
+
async getShorePolicies(clientID) {
|
|
254
|
+
return await TideTokenEnforcer.protect(() => {
|
|
255
|
+
return this.clientShorePolicies.get(clientID);
|
|
256
|
+
}, "default")();
|
|
206
257
|
}
|
|
207
258
|
|
|
259
|
+
// --- FileTide Transfer Management ---
|
|
260
|
+
|
|
208
261
|
/**
|
|
209
262
|
* Send files / directories directly to a device.
|
|
210
263
|
* @param {String} recipientID - The ID of the client device to send the data to.
|
|
@@ -218,73 +271,81 @@ class FileTide {
|
|
|
218
271
|
* @param {Number} transferRequestExpirationTime - The maximum time until the transfer barrier times out the transfer request.
|
|
219
272
|
*/
|
|
220
273
|
async sendToDevice(recipientID, filePath, destinationPath, filterDirectoryContent = [], tideSize = 200, tidalSize = 500, minTideSize = 10, maxTideSize = 2000, transferRequestExpirationTime = 30000) {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
clientID,
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
clientID
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
if (fileDetails.
|
|
245
|
-
|
|
246
|
-
|
|
274
|
+
return await TideTokenEnforcer.protect(async () => {
|
|
275
|
+
const clientID = this.currentUserID;
|
|
276
|
+
const clientMessager = this.clients.get(clientID);
|
|
277
|
+
if (!clientMessager) {
|
|
278
|
+
FileTide.outputGradient(`[FileTide] Client ~ ${clientID} not found.`, errorMessageColors);
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
clientMessager.clientTide.emitEvent(clientID, "check-client-banned", {
|
|
282
|
+
clientID,
|
|
283
|
+
tideID: clientMessager.clientTide.sockets[clientID].tideID
|
|
284
|
+
});
|
|
285
|
+
const recipientOnline = await clientMessager.clientTide.emitEventWithResponse(clientID, "check-client-online", "retrieved-client-online", {
|
|
286
|
+
clientID: recipientID
|
|
287
|
+
}, 5000);
|
|
288
|
+
if (!recipientOnline || !recipientOnline.online) {
|
|
289
|
+
FileTide.outputGradient(`[FileTide] ${recipientID} currently not tiding.`, errorMessageColors);
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
const fileDetails = await this.getPathData(filePath, filterDirectoryContent);
|
|
293
|
+
if (!fileDetails) {
|
|
294
|
+
FileTide.outputGradient(`[${clientID}] File at path ${filePath} not found.`, errorMessageColors);
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
if (fileDetails.type === "file") {
|
|
298
|
+
if (fileDetails.largeFile) {
|
|
299
|
+
FileTide.outputGradient(`[${clientID}] Sending large file ~ ${fileDetails.fileName} to client ~ ${recipientID}...`, significantMessageColors);
|
|
300
|
+
await clientMessager.sendFile(clientID, recipientID, fileDetails.fileName, fileDetails.filePath, destinationPath, fileDetails.fileSize, tidalSize, minTideSize, maxTideSize, true, false, true, transferRequestExpirationTime);
|
|
301
|
+
return true;
|
|
302
|
+
}
|
|
303
|
+
FileTide.outputGradient(`[${clientID}] Sending file ~ ${fileDetails.content.fileName} to client ~ ${recipientID}...`, significantMessageColors);
|
|
304
|
+
await clientMessager.sendFile(clientID, recipientID, fileDetails.content.fileName, fileDetails.content.filePath, destinationPath, fileDetails.content.size, tideSize, minTideSize, maxTideSize, transferRequestExpirationTime);
|
|
247
305
|
return true;
|
|
248
306
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
FileTide.outputGradient(`[
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
258
|
-
FileTide.outputGradient(`[FileTide] ~ No active client ~ ${recipientID} found.`, errorMessageColors);
|
|
259
|
-
return false;
|
|
307
|
+
if (fileDetails.type === "directory") {
|
|
308
|
+
FileTide.outputGradient(`[${clientID}] Sending ${fileDetails.content.length} files in directory ~ ${path.basename(filePath)} to client ~ ${recipientID}...`, significantMessageColors);
|
|
309
|
+
await clientMessager.sendDirectoryFiles(clientID, recipientID, fileDetails.content, this.getTidePath(filePath), destinationPath, tideSize, minTideSize, maxTideSize, transferRequestExpirationTime);
|
|
310
|
+
return true;
|
|
311
|
+
}
|
|
312
|
+
FileTide.outputGradient(`[FileTide] ~ No active client ~ ${recipientID} found.`, errorMessageColors);
|
|
313
|
+
return false;
|
|
314
|
+
}, "default")();
|
|
260
315
|
}
|
|
261
316
|
|
|
317
|
+
// --- FileTide Operational Status Management ---
|
|
318
|
+
|
|
262
319
|
/**
|
|
263
320
|
* Check if running in server mode.
|
|
264
|
-
* @returns {Boolean} - True if running
|
|
321
|
+
* @returns {Boolean} - True if server running
|
|
265
322
|
*/
|
|
266
|
-
fileTideOperational() {
|
|
267
|
-
return this.fileNet !== null;
|
|
323
|
+
async fileTideOperational() {
|
|
324
|
+
return await TideTokenEnforcer.protect(() => this.fileNet !== null, "default")();
|
|
268
325
|
}
|
|
269
326
|
|
|
270
327
|
/**
|
|
271
328
|
* Check if running in client mode.
|
|
272
|
-
* @returns {Boolean} - True if any
|
|
329
|
+
* @returns {Boolean} - True if any connected clients found
|
|
273
330
|
*/
|
|
274
|
-
messagerOperational() {
|
|
275
|
-
return this.clients.size > 0;
|
|
331
|
+
async messagerOperational() {
|
|
332
|
+
return await TideTokenEnforcer.protect(() => this.clients.size > 0, "default")();
|
|
276
333
|
}
|
|
277
334
|
|
|
335
|
+
// --- FileTide Cleanup Management ---
|
|
336
|
+
|
|
278
337
|
/**
|
|
279
338
|
* Stop the server if running.
|
|
280
339
|
*/
|
|
281
340
|
stopFileTide() {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
341
|
+
TideTokenEnforcer.protect(() => {
|
|
342
|
+
if (this.fileNet) {
|
|
343
|
+
FileTide.outputGradient("Stopping FileTide...", significantMessageColors);
|
|
344
|
+
this.fileNet.close();
|
|
345
|
+
this.fileNet = null;
|
|
346
|
+
FileTide.outputGradient("Stopped FileTide.", significantMessageColors);
|
|
347
|
+
}
|
|
348
|
+
}, "default")();
|
|
288
349
|
return;
|
|
289
350
|
}
|
|
290
351
|
|
|
@@ -296,33 +357,35 @@ class FileTide {
|
|
|
296
357
|
* @param {Function} onCompletion - Executes upon messager disconnection completion
|
|
297
358
|
*/
|
|
298
359
|
async stopMessager(userID, onBeforeDisconnect, onDisconnect, onCompletion) {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
360
|
+
TideTokenEnforcer.protect(async () => {
|
|
361
|
+
if (this.clients.has(userID)) {
|
|
362
|
+
FileTide.outputGradient(`Stopping messager for user ${userID}...`, significantMessageColors);
|
|
363
|
+
const connectionOrigin = this.clients.get(userID);
|
|
364
|
+
if (typeof onBeforeDisconnect === "function") {
|
|
365
|
+
await onBeforeDisconnect(this, userID, connectionOrigin);
|
|
366
|
+
}
|
|
367
|
+
if (connectionOrigin?.clientTide?.closeSocket) {
|
|
368
|
+
const result = connectionOrigin.clientTide.closeSocket(userID);
|
|
369
|
+
if (result instanceof Promise) {
|
|
370
|
+
try {
|
|
371
|
+
await result;
|
|
372
|
+
} catch (error) {
|
|
373
|
+
FileTide.outputGradient(`Did not disconnect ~ ${userID} ~ ${error.message}`, errorMessageColors);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
if (typeof onDisconnect === "function") {
|
|
377
|
+
await onDisconnect(this, userID, connectionOrigin);
|
|
312
378
|
}
|
|
313
379
|
}
|
|
314
|
-
|
|
315
|
-
|
|
380
|
+
this.clients.delete(userID);
|
|
381
|
+
FileTide.outputGradient(`Stopped messager for user ${userID}.`, significantMessageColors);
|
|
382
|
+
if (typeof onCompletion === "function") {
|
|
383
|
+
await onCompletion(this, userID, connectionOrigin);
|
|
316
384
|
}
|
|
385
|
+
return;
|
|
317
386
|
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
if (typeof onCompletion === "function") {
|
|
321
|
-
await onCompletion(this, userID, connectionOrigin);
|
|
322
|
-
}
|
|
323
|
-
return;
|
|
324
|
-
}
|
|
325
|
-
FileTide.outputGradient(`No active messager found for user ${userID}.`, errorMessageColors);
|
|
387
|
+
FileTide.outputGradient(`No active messager found for user ${userID}.`, errorMessageColors);
|
|
388
|
+
}, "default")();
|
|
326
389
|
return;
|
|
327
390
|
}
|
|
328
391
|
|
|
@@ -333,38 +396,52 @@ class FileTide {
|
|
|
333
396
|
* @param {Function} onCompletion - Executes upon all messager disconnection
|
|
334
397
|
*/
|
|
335
398
|
async stopAllMessagers(onBeforeClientDisconnect, onClientDisconnect, onCompletion) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
399
|
+
TideTokenEnforcer.protect(async () => {
|
|
400
|
+
FileTide.outputGradient("Stopping all messagers...", significantMessageColors);
|
|
401
|
+
const disconnectTasks = [];
|
|
402
|
+
for (let [userID, connectionOrigin] of this.clients.entries()) {
|
|
403
|
+
if (typeof onBeforeClientDisconnect === "function") {
|
|
404
|
+
await onBeforeClientDisconnect(this, userID, connectionOrigin);
|
|
405
|
+
}
|
|
406
|
+
if (connectionOrigin?.clientTide?.closeSocket) {
|
|
407
|
+
const task = async () => {
|
|
408
|
+
try {
|
|
409
|
+
const result = connectionOrigin.clientTide.closeSocket(userID);
|
|
410
|
+
if (result instanceof Promise) {
|
|
411
|
+
await result;
|
|
412
|
+
}
|
|
413
|
+
if (typeof onClientDisconnect === "function") {
|
|
414
|
+
await onClientDisconnect(this, userID, connectionOrigin);
|
|
415
|
+
}
|
|
416
|
+
FileTide.outputGradient(`Disconnected ~ ${userID}`, significantMessageColors);
|
|
417
|
+
} catch (error) {
|
|
418
|
+
FileTide.outputGradient(`Did not disconnect ~ ${userID} - ${error.message}`, errorMessageColors);
|
|
351
419
|
}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
}
|
|
356
|
-
};
|
|
357
|
-
disconnectTasks.push(task());
|
|
420
|
+
};
|
|
421
|
+
disconnectTasks.push(task());
|
|
422
|
+
}
|
|
358
423
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
}
|
|
424
|
+
await Promise.all(disconnectTasks);
|
|
425
|
+
this.clients.clear();
|
|
426
|
+
FileTide.outputGradient("All messagers stopped.", significantMessageColors);
|
|
427
|
+
if (typeof onCompletion === "function") {
|
|
428
|
+
await onCompletion(this);
|
|
429
|
+
}
|
|
430
|
+
}, "default")();
|
|
366
431
|
return;
|
|
367
432
|
}
|
|
433
|
+
|
|
434
|
+
// --- FileTide Display Management ---
|
|
435
|
+
|
|
436
|
+
static displayFileTideLogo() {
|
|
437
|
+
displayFileTideLogo();
|
|
438
|
+
}
|
|
439
|
+
static displayFileTideTitle(cli = false) {
|
|
440
|
+
displayFileTideTitle(cli);
|
|
441
|
+
}
|
|
442
|
+
static displayFileTideAuthor() {
|
|
443
|
+
displayFileTideAuthor();
|
|
444
|
+
}
|
|
368
445
|
}
|
|
369
446
|
_FileTide = FileTide;
|
|
370
447
|
function _setupFileEventListeners(userID, client, onTransferProgress, onIncomingTransfer, onIncomingFile, onTransferBarrier, options = {}) {
|
|
@@ -701,7 +778,7 @@ function _setupFileEventListeners(userID, client, onTransferProgress, onIncoming
|
|
|
701
778
|
});
|
|
702
779
|
client.clientTide.onEvent(userID, "list-files", async data => {
|
|
703
780
|
_FileTide.outputGradient(`[${userID}] Sending file list to ${data.senderID}...!`, significantMessageColors);
|
|
704
|
-
const currentClientShorePolicies = this.getShorePolicies(userID);
|
|
781
|
+
const currentClientShorePolicies = await this.getShorePolicies(userID);
|
|
705
782
|
let totalFilesSent = 0;
|
|
706
783
|
const listedFiles = await this.listFiles(currentClientShorePolicies || [">Downloads"], data.depth || 1, (totalItems, directoryContents) => {
|
|
707
784
|
const capacitor = new ChunkCapacitor(directoryContents, 100);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const LogicTide = require("@trap_stevo/logictide");
|
|
4
|
+
|
|
5
|
+
// ~ Universal FileTide Communication Configurations ~
|
|
6
|
+
|
|
7
|
+
LogicTide.defineLogic("filetide-api-origin-url", "development", () => {
|
|
8
|
+
return "http://localhost:19269";
|
|
9
|
+
});
|
|
10
|
+
LogicTide.defineLogic("filetide-api-origin-url", "production", () => {
|
|
11
|
+
return "https://api.filetide.com";
|
|
12
|
+
});
|
|
@@ -33,6 +33,14 @@ class FileNetClientManager {
|
|
|
33
33
|
currentOnlineClients.delete(clientID);
|
|
34
34
|
return currentOnlineClients;
|
|
35
35
|
}
|
|
36
|
+
static getOnlineClientByConnectionID(connectionID) {
|
|
37
|
+
for (const clientData of currentOnlineClients.values()) {
|
|
38
|
+
if (clientData.id === connectionID) {
|
|
39
|
+
return clientData;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
36
44
|
static getOnlineClient(clientID) {
|
|
37
45
|
return currentOnlineClients.get(clientID);
|
|
38
46
|
}
|
|
@@ -6,6 +6,7 @@ const {
|
|
|
6
6
|
const chalk = require("chalk");
|
|
7
7
|
const significantMessageColors = ["#00C897", "#00E0FF"];
|
|
8
8
|
const noticeMessageColors = ["#4A90E2", "#A3D8F4"];
|
|
9
|
+
const infoAccentMessageColors = ["#6B768F", "#8D99AB"];
|
|
9
10
|
const errorMessageColors = ["#F94144", "#F3722C"];
|
|
10
11
|
const infoMessageColors = ["#028090", "#56cfe1"];
|
|
11
12
|
const logHandler = {
|
|
@@ -26,14 +27,29 @@ const logHandler = {
|
|
|
26
27
|
outputGradient(log + message.join(" "), infoMessageColors);
|
|
27
28
|
}
|
|
28
29
|
};
|
|
29
|
-
function
|
|
30
|
+
function gradientText(text, colors, options = {
|
|
31
|
+
underline: false
|
|
32
|
+
}) {
|
|
30
33
|
const gradient = HUDUtilityManager.generateGradientColors(colors, text.length);
|
|
31
34
|
let coloredText = "";
|
|
35
|
+
const underlineRange = Array.isArray(options.underline) ? options.underline : null;
|
|
36
|
+
const underlineNone = options.underline === false;
|
|
37
|
+
const underlineAll = options.underline === true;
|
|
32
38
|
for (let i = 0; i < text.length; i++) {
|
|
33
39
|
const [r, g, b] = gradient[i];
|
|
34
|
-
|
|
40
|
+
let styledChar = chalk.rgb(r, g, b);
|
|
41
|
+
if (underlineAll || underlineRange && i >= underlineRange[0] && i < underlineRange[1]) {
|
|
42
|
+
styledChar = styledChar.underline;
|
|
43
|
+
}
|
|
44
|
+
coloredText += styledChar(text[i]);
|
|
35
45
|
}
|
|
36
|
-
|
|
46
|
+
return coloredText;
|
|
47
|
+
}
|
|
48
|
+
;
|
|
49
|
+
function outputGradient(text, colors, options = {
|
|
50
|
+
underline: false
|
|
51
|
+
}) {
|
|
52
|
+
console.log(gradientText(text, colors, options));
|
|
37
53
|
return;
|
|
38
54
|
}
|
|
39
55
|
;
|
|
@@ -45,13 +61,35 @@ class FileTideDebugUtilityManager {
|
|
|
45
61
|
this.debugMode = false;
|
|
46
62
|
FileTideDebugUtilityManager.instance = this;
|
|
47
63
|
}
|
|
48
|
-
outputGradient(text, colors
|
|
49
|
-
|
|
64
|
+
outputGradient(text, colors, options = {
|
|
65
|
+
underline: false
|
|
66
|
+
}) {
|
|
67
|
+
outputGradient(text, colors, options);
|
|
50
68
|
return;
|
|
51
69
|
}
|
|
70
|
+
gradientText(text, colors, options = {
|
|
71
|
+
underline: false
|
|
72
|
+
}) {
|
|
73
|
+
return gradientText(text, colors, options);
|
|
74
|
+
}
|
|
75
|
+
createHyperlink(text, url) {
|
|
76
|
+
const ESC = "\u001b";
|
|
77
|
+
const BEL = "\u0007";
|
|
78
|
+
return `${ESC}]8;;${url}${BEL}${text}${ESC}]8;;${BEL}`;
|
|
79
|
+
}
|
|
52
80
|
setDebugMode(mode) {
|
|
53
81
|
this.debugMode = mode;
|
|
54
82
|
}
|
|
83
|
+
logLink(displayText, url, prefix = "➜", colors = noticeMessageColors.slice(0)) {
|
|
84
|
+
const styledText = gradientText(displayText, colors, {
|
|
85
|
+
underline: true
|
|
86
|
+
});
|
|
87
|
+
const link = this.createHyperlink(styledText, url);
|
|
88
|
+
const styledPrefix = gradientText(prefix, colors);
|
|
89
|
+
process.stdout.write(`${styledPrefix} `);
|
|
90
|
+
process.stdout.write(link);
|
|
91
|
+
process.stdout.write("\n");
|
|
92
|
+
}
|
|
55
93
|
log(type = "info", includeDate = false, ...message) {
|
|
56
94
|
if (!this.debugMode && type !== "error") {
|
|
57
95
|
return;
|
|
@@ -69,5 +107,6 @@ module.exports = {
|
|
|
69
107
|
significantMessageColors,
|
|
70
108
|
noticeMessageColors,
|
|
71
109
|
errorMessageColors,
|
|
110
|
+
infoAccentMessageColors,
|
|
72
111
|
infoMessageColors
|
|
73
112
|
};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
FileTideDebugUtilityManager
|
|
5
|
+
} = require("./FileTideDebugUtilityManager.js");
|
|
6
|
+
function displayFileTideLogo() {
|
|
7
|
+
FileTideDebugUtilityManager.outputGradient(`
|
|
8
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
9
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
10
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
11
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
12
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
13
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
14
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
15
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
16
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
17
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
18
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
19
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
20
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
21
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:;:::::;;;;:::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
22
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::::;+?%%%%%%%?*;::::::::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
23
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;:::;*%%?+;:,,,::+?S?;:::::::::::::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
24
|
+
;;;;;;;;;;;;;;;;;;;;;;;;::::;*S?;,,,,::::::,,;SS;:::;+++++++++;;:::::::;;;;;;:::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
25
|
+
;;;;;;;;;;;;;;;;;;;;;;;;:::+S%:.,::;::;;+++;::*@+:*SSS%%%%%%%%SS%+:::::::::::::::::::::;::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
26
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;:+#*,,:;;::+?SSSSS#?+SS+SS;:,,,,,,,,,,;S#?;::::::::::::::::::::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
27
|
+
;;;;;;;;;;;;;;;;;;;;;;;;:;S?.,;;;:;%#%*+;*S##SS%S*,:;;;;;;;;;;;:,+S#%%%%%%%%%%%%%%%%%%%%%?+::::;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
28
|
+
;;;;;;;;;;;;;;;;;;;;;;;;:?#:,;;;:;S#*;::?#%+++%#*.:;;;;;;;;;;;;;;::;++++++++++++++++++++*?#S+::;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
29
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;S%,;;;;;%#*;::*#?:::;S#+;+++++++++++++++++++++++++;;;;;;;;;;;;;;;;##;:;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
30
|
+
;;;;;;;;;;;;;;;;;;;;;;;:;#%:;;;;*#?+::;#S:::::S#*%%SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS?S#;::;;;;;;;;;;;;;;;;;;;;;;;;
|
|
31
|
+
;;;;;;;;;;;;;;;;;;;;;;;:;S%;+;;;%#*+::+#%:::::S#S?+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+%##;::;;;;;;;;;;;;;;;;;;;;;;;;
|
|
32
|
+
;;;;;;;;;;;;;;;;;;;;;;;:;SS++;;;%#**::+#?::::;#S:,,:::::::::::::::::::::::::::::::::::::::,+#%::;;;;;;;;;;;;;;;;;;;;;;;;
|
|
33
|
+
;;;;;;;;;;;;;;;;;;;;;;::;SS?*+;;%#?*;:;#S::::+#?,;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,S#;:::::;;;;;;;;;;;;;;;;;;;;
|
|
34
|
+
;;;;;;;;;;;;;;;;;;;;;;;:;S#S*+;;*#%*+::?#*:::+#?,;;;;;;;;;**;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:S#;::::;;;;;;;;;;;;;;;;;;;;;
|
|
35
|
+
;;;;;;;;;;;;;;;;;;;;;;::;S##?*;;;SS**;::%#*::+#?,;;;;;;;;;++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:S#;::::;;;;;;;;;;;;;;;;;;;;;
|
|
36
|
+
;;;;;;;;;;;;;;;;;;;;;;::;S##S**;;*#%**;;:?#?:;#?,+++++++++;;+++++++++++++++++++++++++++++++;S#;:::::;;;;;;;;;;;;;;;;;;;;
|
|
37
|
+
;;;;;;;;;;;;;;;;;;;;;;::;S%?#?*+;;?#%**;;:*#S?#%:*++++++++++++++++++++++++++++++++++++++++*+S#;:::;;;;;;;;;;;;;;;;;;;;;;
|
|
38
|
+
;;;;;;;;;;;;;;;;;;;;;;::;S%:SS?*+;;?#%**+;;;?##S;******************************************+S#;::::;;;;;;;;;;;;;;;;;;;;;
|
|
39
|
+
;;;;;;;;;;;;;;;;;;;;;:::;SS,;#S??+;;*#S?*+;;:;?##%?******??%%SSSSSSS%%??********************##;::::::;;;;;;;;;;;;;;;;;;;
|
|
40
|
+
;;;;;;;;;;;;;;;;;;;;;;::;SS;,;#S??+;;;%#S?*+;;;;?S#S%??%SS?*+;:::::;+*%SSS%%????????????????##;::::::;;;;;;;;;;;;;;;;;;;
|
|
41
|
+
;;;;;;;;;;;;;;;;;;;;;;::;SS;;,:S#??*+;;+%#S%?*++;;+?##S*;,,,,:::::::,,,,;?##SSSS%%%???????%%##;::::;;;;;;;;;;;;;;;;;;;;;
|
|
42
|
+
;;;;;;;;;;;;;;;;;;;;;;::;SS*+;:,*#S??*+;;+?S#S%?**?SS+,,::;;;;;::::;;;;::,:?#%**?%SSSSSSSSS%%S;:::;;;;;;;;;;;;;;;;;;;;;;
|
|
43
|
+
;;;;;;;;;;;;;;;;;;;;;;::;S#%**+;,:?SS%?**+;;+?S###%+,,:;;;;;;+**???**;;;;;:,;%#S*;;;;;;;;;::?S;:::;;;;;;;;;;;;;;;;;;;;;;
|
|
44
|
+
;;;;;;;;;;;;;;;;;;;;;;::;S##S?*++;::*%SSSSS%%%S%*:,,:;;;;;;*%SS%???%SSS?*+;;:,;%##%?**+++++*S#;:::;;;;;;;;;;;;;;;;;;;;;;
|
|
45
|
+
;;;;;;;;;;;;;;;;;;;;;;;:;SS;%#%?*++;:::;++**+;:,,:;;;;;;;;%#?+;;;;;;;;*%SS?*+;;::+?%SSSSSSSSS#;:::;;;;;;;;;;;;;;;;;;;;;;
|
|
46
|
+
;;;;;;;;;;;;;;;;;;;;;;::;SS;:+S#S?**++;;;:::::;;;;;+*+++;*S?+++++++;;;;;;*S#%**+;;:::;;;;;;:*S;:::;;;;;;;;;;;;;;;;;;;;;;
|
|
47
|
+
;;;;;;;;;;;;;;;;;;;;;;;:;SS*+;;+?SSS%?**+++++++**?%S%+;;?#?*???????**++;;;;*%SS%?**++;;;;;;;%S;:::;;;;;;;;;;;;;;;;;;;;;;
|
|
48
|
+
;;;;;;;;;;;;;;;;;;;;;;;::?#%?*++;;+*%SSSSS%%%%SSS%?+;;+%#SSSSSSSSSSS%%?**++;;;*%SSSS%%????%%#S;:::;;;;;;;;;;;;;;;;;;;;;;
|
|
49
|
+
;;;;;;;;;;;;;;;;;;;;;;;;::%#%??**++;;;;+**???**++;;;+?S#S%%???**++*?%SSS%?**+++;;++*?%%%%%%##+:::;;;;;;;;;;;;;;;;;;;;;;;
|
|
50
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;::*##%???****+++;;;;;;+++*?S#S%??????***+++++*%SSS%??****+++++++*%S+:::;;;;;;;;;;;;;;;;;;;;;;;;
|
|
51
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;::;?S#SS%?????******??%%SSS%%%%SSSS%%%%????****?%SSSS%%??????%S#?;::::;;;;;;;;;;;;;;;;;;;;;;;;
|
|
52
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;:::;+?%S##SSSSSSSSS#####SSSSS#SS#######SSSSSSSSSSS#######SSS%*;::::;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
53
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::;+++********************************************+++;;::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
54
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::::::::::::::::::::::::::::::::::::::::::::::::::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
55
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::::::::::::::::::::::::::;;;::::::::::::;;;;;;;;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
56
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::::;::::::::::;;:;;;;;;;;;;::;;:::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
57
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::::::;;;;;:;;;;;;;;;;;;;;;::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
58
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
59
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
60
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
61
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
62
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
63
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
64
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
65
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
66
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
67
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
68
|
+
`, ["#0077B6", "#00B4D8"]);
|
|
69
|
+
}
|
|
70
|
+
;
|
|
71
|
+
function displayFileTideTitle(cli = false) {
|
|
72
|
+
if (cli) {
|
|
73
|
+
FileTideDebugUtilityManager.outputGradient(`
|
|
74
|
+
\t\t _______ ___ ___ _______ _______ ___ ______ _______ _______ ___ ___
|
|
75
|
+
\t\t| || | | | | || || | | | | | | || | | |
|
|
76
|
+
\t\t| ___|| | | | | ___||_ _|| | | _ || ___| | || | | |
|
|
77
|
+
\t\t| |___ | | | | | |___ | | | | | | | || |___ | || | | |
|
|
78
|
+
\t\t| ___|| | | |___ | ___| | | | | | |_| || ___| | _|| |___ | |
|
|
79
|
+
\t\t| | | | | || |___ | | | | | || |___ | |_ | || |
|
|
80
|
+
\t\t|___| |___| |_______||_______| |___| |___| |______| |_______| |_______||_______||___|
|
|
81
|
+
`, ["#028090", "#56cfe1"]);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
FileTideDebugUtilityManager.outputGradient(`
|
|
85
|
+
\t\t\t\t _______ ___ ___ _______ _______ ___ ______ _______
|
|
86
|
+
\t\t\t\t| || | | | | || || | | | | |
|
|
87
|
+
\t\t\t\t| ___|| | | | | ___||_ _|| | | _ || ___|
|
|
88
|
+
\t\t\t\t| |___ | | | | | |___ | | | | | | | || |___
|
|
89
|
+
\t\t\t\t| ___|| | | |___ | ___| | | | | | |_| || ___|
|
|
90
|
+
\t\t\t\t| | | | | || |___ | | | | | || |___
|
|
91
|
+
\t\t\t\t|___| |___| |_______||_______| |___| |___| |______| |_______|
|
|
92
|
+
`, ["#028090", "#56cfe1"]);
|
|
93
|
+
}
|
|
94
|
+
;
|
|
95
|
+
function displayFileTideAuthor() {
|
|
96
|
+
FileTideDebugUtilityManager.outputGradient(`
|
|
97
|
+
▄▄· ▄▄▄ ▄▄▄ . ▄▄▄· ▄▄▄▄▄▄▄▄ .·▄▄▄▄ ▄▄▄▄· ▄· ▄▌ .▄▄ · ▄▄▄▄▄▄▄▄ . ▌ ▐·▄▄▄ . ▐ ▄ ▄▄· • ▌ ▄ ·. ▄▄▄·▄▄▄▄▄ ▐ ▄
|
|
98
|
+
▐█ ▌▪▀▄ █·▀▄.▀·▐█ ▀█ •██ ▀▄.▀·██▪ ██ ▐█ ▀█▪▐█▪██▌ ▐█ ▀. •██ ▀▄.▀·▪█·█▌▀▄.▀·•█▌▐█ ▐█ ▌▪▪ ·██ ▐███▪▐█ ▄█•██ ▪ •█▌▐█
|
|
99
|
+
██ ▄▄▐▀▀▄ ▐▀▀▪▄▄█▀▀█ ▐█.▪▐▀▀▪▄▐█· ▐█▌ ▐█▀▀█▄▐█▌▐█▪ ▄▀▀▀█▄ ▐█.▪▐▀▀▪▄▐█▐█•▐▀▀▪▄▐█▐▐▌ ██ ▄▄ ▄█▀▄ ▐█ ▌▐▌▐█· ██▀· ▐█.▪ ▄█▀▄ ▐█▐▐▌
|
|
100
|
+
▐███▌▐█•█▌▐█▄▄▌▐█ ▪▐▌ ▐█▌·▐█▄▄▌██. ██ ██▄▪▐█ ▐█▀·. ▐█▄▪▐█ ▐█▌·▐█▄▄▌ ███ ▐█▄▄▌██▐█▌ ▐███▌▐█▌.▐▌██ ██▌▐█▌▐█▪·• ▐█▌·▐█▌.▐▌██▐█▌
|
|
101
|
+
·▀▀▀ .▀ ▀ ▀▀▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀▀▀▀▀• ·▀▀▀▀ ▀ • ▀▀▀▀ ▀▀▀ ▀▀▀ . ▀ ▀▀▀ ▀▀ █▪ ·▀▀▀ ▀█▄▀▪▀▀ █▪▀▀▀.▀ ▀▀▀ ▀█▄▀▪▀▀ █▪
|
|
102
|
+
`, ["#1a73e8", "#a0c4ff"]);
|
|
103
|
+
}
|
|
104
|
+
;
|
|
105
|
+
module.exports = {
|
|
106
|
+
displayFileTideAuthor,
|
|
107
|
+
displayFileTideTitle,
|
|
108
|
+
displayFileTideLogo
|
|
109
|
+
};
|
|
@@ -16,6 +16,28 @@ function pickData(data, keys) {
|
|
|
16
16
|
}, {});
|
|
17
17
|
}
|
|
18
18
|
;
|
|
19
|
+
function parseSizeString(str) {
|
|
20
|
+
if (typeof str === "number") {
|
|
21
|
+
return str;
|
|
22
|
+
}
|
|
23
|
+
if (typeof str !== "string") {
|
|
24
|
+
return 0;
|
|
25
|
+
}
|
|
26
|
+
const units = {
|
|
27
|
+
B: 1,
|
|
28
|
+
KB: 1024,
|
|
29
|
+
MB: 1024 ** 2,
|
|
30
|
+
GB: 1024 ** 3,
|
|
31
|
+
TB: 1024 ** 4
|
|
32
|
+
};
|
|
33
|
+
const match = str.trim().toUpperCase().match(/^([\d.]+)\s*(B|KB|MB|GB|TB)$/);
|
|
34
|
+
if (!match) {
|
|
35
|
+
return 0;
|
|
36
|
+
}
|
|
37
|
+
const [, numStr, unit] = match;
|
|
38
|
+
return parseFloat(numStr) * units[unit];
|
|
39
|
+
}
|
|
40
|
+
;
|
|
19
41
|
function aggregateMultiAverageChartData(events, {
|
|
20
42
|
groupBy = ["user"],
|
|
21
43
|
valueKey = "metadata.fileSize",
|
|
@@ -38,7 +60,17 @@ function aggregateMultiAverageChartData(events, {
|
|
|
38
60
|
return getNestedData(event, path) ?? "unknown";
|
|
39
61
|
});
|
|
40
62
|
const label = labelParts.join(" | ");
|
|
41
|
-
|
|
63
|
+
let rawValue = getNestedData(event, valueKey);
|
|
64
|
+
let value;
|
|
65
|
+
if (mode === "sum") {
|
|
66
|
+
if (valueKey.includes("speed") || valueKey.includes("fileSize")) {
|
|
67
|
+
value = parseSizeString(rawValue);
|
|
68
|
+
} else {
|
|
69
|
+
value = parseFloat(rawValue) || 0;
|
|
70
|
+
}
|
|
71
|
+
} else {
|
|
72
|
+
value = 1;
|
|
73
|
+
}
|
|
42
74
|
if (typeof value !== "number") {
|
|
43
75
|
continue;
|
|
44
76
|
}
|
|
@@ -100,7 +132,17 @@ function aggregateChartData(events, {
|
|
|
100
132
|
label = event[typeKey] || "other";
|
|
101
133
|
}
|
|
102
134
|
const type = event[typeKey] || "other";
|
|
103
|
-
|
|
135
|
+
let rawValue = mode === "sum" ? getNestedData(event, valueKey) || 0 : 1;
|
|
136
|
+
let value;
|
|
137
|
+
if (mode === "sum") {
|
|
138
|
+
if (valueKey.includes("speed") || valueKey.includes("fileSize")) {
|
|
139
|
+
value = parseSizeString(rawValue);
|
|
140
|
+
} else {
|
|
141
|
+
value = parseFloat(rawValue) || 0;
|
|
142
|
+
}
|
|
143
|
+
} else {
|
|
144
|
+
value = 1;
|
|
145
|
+
}
|
|
104
146
|
if (!buckets[type]) {
|
|
105
147
|
buckets[type] = {
|
|
106
148
|
previewFileNames: [],
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const LogicTide = require("@trap_stevo/logictide");
|
|
4
|
+
const Lockline = require("@trap_stevo/lockline");
|
|
5
|
+
const axios = require("axios");
|
|
6
|
+
const {
|
|
7
|
+
FileTideDebugUtilityManager,
|
|
8
|
+
significantMessageColors,
|
|
9
|
+
noticeMessageColors,
|
|
10
|
+
infoMessageColors,
|
|
11
|
+
infoAccentMessageColors,
|
|
12
|
+
errorMessageColors
|
|
13
|
+
} = require("./FileTideDebugUtilityManager.js");
|
|
14
|
+
const {
|
|
15
|
+
displayFileTideAuthor,
|
|
16
|
+
displayFileTideTitle,
|
|
17
|
+
displayFileTideLogo
|
|
18
|
+
} = require("./FileTideUniversalUtilityManager.js");
|
|
19
|
+
class TideTokenEnforcementManager {
|
|
20
|
+
constructor(options = {}) {
|
|
21
|
+
const {
|
|
22
|
+
tideTokenEnforcementCallbackConfigurations = {},
|
|
23
|
+
onDidNotLoadRecentTideTokens
|
|
24
|
+
} = options;
|
|
25
|
+
this.tideTokenEnforcementCallbackConfigurations = tideTokenEnforcementCallbackConfigurations;
|
|
26
|
+
this.tideTokenEnforcementComplianceHandlers = this.generateTideTokenEnforcementHandlers();
|
|
27
|
+
this.lock = new Lockline();
|
|
28
|
+
this.lock.setStorage(Lockline.lockbox("./lockbox", {
|
|
29
|
+
namespace: "tide-tokens",
|
|
30
|
+
encrypt: true
|
|
31
|
+
}));
|
|
32
|
+
this.lock.registerValidator("tide-token-authorization", async ({
|
|
33
|
+
key
|
|
34
|
+
}) => {
|
|
35
|
+
const fileTideAPIURL = await LogicTide.run("filetide-api-origin-url");
|
|
36
|
+
const response = await axios.get(`${fileTideAPIURL}/tide-token-auth/authorized-tide-token`, {
|
|
37
|
+
params: {
|
|
38
|
+
inputTideToken: key
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
return {
|
|
42
|
+
valid: response.data.authorizedTideToken,
|
|
43
|
+
raw: response.data.details,
|
|
44
|
+
reason: response.data.message
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
this.lock.setDefaultValidator("tide-token-authorization");
|
|
48
|
+
this.loadedRecentLicenseKeys = this.lock.loadRecentLicenseKeys().catch(error => {
|
|
49
|
+
if (typeof onDidNotLoadRecentTideTokens === "function") {
|
|
50
|
+
onDidNotLoadRecentTideTokens(error);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
this.enforcerOverviewMetrics = {
|
|
54
|
+
"tide-token-authorized": 0,
|
|
55
|
+
"tide-token-blocked": 0,
|
|
56
|
+
"tide-token-missing": 0,
|
|
57
|
+
"tide-token-invalid": 0
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
updateTideTokenEnforcementCallbackConfigurations(updatedConfigurations = {}) {
|
|
61
|
+
this.tideTokenEnforcementCallbackConfigurations = {
|
|
62
|
+
...this.tideTokenEnforcementCallbackConfigurations,
|
|
63
|
+
...updatedConfigurations
|
|
64
|
+
};
|
|
65
|
+
this.tideTokenEnforcementComplianceHandlers = this.generateTideTokenEnforcementHandlers();
|
|
66
|
+
}
|
|
67
|
+
generateTideTokenEnforcementHandlers() {
|
|
68
|
+
const {
|
|
69
|
+
onLicenseBlocked,
|
|
70
|
+
onMissingLicense,
|
|
71
|
+
onInvalidLicense,
|
|
72
|
+
onSuccess
|
|
73
|
+
} = this.tideTokenEnforcementCallbackConfigurations;
|
|
74
|
+
const url = "https://filetide.com/tider-portal";
|
|
75
|
+
return {
|
|
76
|
+
onLicenseBlocked: enforcedDetails => {
|
|
77
|
+
FileTideDebugUtilityManager.outputGradient(`[FileTide | ${new Date().toLocaleString()}] ~ ❌ TideToken Blocked\n`, errorMessageColors);
|
|
78
|
+
FileTideDebugUtilityManager.outputGradient(`\t→ Visit ~ ${url} to configure / create TideTokens.\n`, infoAccentMessageColors);
|
|
79
|
+
FileTideDebugUtilityManager.outputGradient(`| ${new Date().toLocaleString()} |`, infoAccentMessageColors);
|
|
80
|
+
FileTideDebugUtilityManager.outputGradient(`${"-".repeat(130)}\n`, infoAccentMessageColors);
|
|
81
|
+
this.enforcerOverviewMetrics["tide-token-blocked"] += 1;
|
|
82
|
+
onLicenseBlocked?.(enforcedDetails);
|
|
83
|
+
},
|
|
84
|
+
onMissingKey: enforcedDetails => {
|
|
85
|
+
displayFileTideLogo();
|
|
86
|
+
displayFileTideTitle();
|
|
87
|
+
FileTideDebugUtilityManager.outputGradient(`[FileTide] ~ Welcome!\n`, significantMessageColors);
|
|
88
|
+
FileTideDebugUtilityManager.outputGradient("\t~ No TideToken(s) Detected\n", significantMessageColors);
|
|
89
|
+
FileTideDebugUtilityManager.outputGradient(`\t→ Visit ~ ${url} to create TideTokens.\n`, infoMessageColors);
|
|
90
|
+
FileTideDebugUtilityManager.outputGradient(`| ${new Date().toLocaleString()} |`, infoAccentMessageColors);
|
|
91
|
+
FileTideDebugUtilityManager.outputGradient(`${"-".repeat(130)}\n`, infoAccentMessageColors);
|
|
92
|
+
this.enforcerOverviewMetrics["tide-token-missing"] += 1;
|
|
93
|
+
onMissingLicense?.(enforcedDetails);
|
|
94
|
+
},
|
|
95
|
+
onInvalidKey: enforcedDetails => {
|
|
96
|
+
FileTideDebugUtilityManager.outputGradient(`[FileTide | ${new Date().toLocaleString()}] ~ ❌ TideToken Unauthorized\n`, errorMessageColors);
|
|
97
|
+
FileTideDebugUtilityManager.outputGradient(`\t→ Visit ~ ${url} to configure / create TideTokens.\n`, infoAccentMessageColors);
|
|
98
|
+
FileTideDebugUtilityManager.outputGradient(`| ${new Date().toLocaleString()} |`, infoAccentMessageColors);
|
|
99
|
+
FileTideDebugUtilityManager.outputGradient(`${"-".repeat(130)}\n`, infoAccentMessageColors);
|
|
100
|
+
this.enforcerOverviewMetrics["tide-token-invalid"] += 1;
|
|
101
|
+
onInvalidLicense?.(enforcedDetails);
|
|
102
|
+
},
|
|
103
|
+
onSuccess: enforcedDetails => {
|
|
104
|
+
FileTideDebugUtilityManager.outputGradient(`[FileTide | ${new Date().toLocaleString()}] ~ ✅ TideToken Authorized\n`, significantMessageColors);
|
|
105
|
+
if (this.enforcerOverviewMetrics["tide-token-authorized"] <= 0) {
|
|
106
|
+
FileTideDebugUtilityManager.outputGradient(`\t→ Configure TideTokens at ${url}\n`, noticeMessageColors);
|
|
107
|
+
}
|
|
108
|
+
FileTideDebugUtilityManager.outputGradient(`| ${new Date().toLocaleString()} |`, infoAccentMessageColors);
|
|
109
|
+
FileTideDebugUtilityManager.outputGradient(`${"-".repeat(130)}\n`, infoAccentMessageColors);
|
|
110
|
+
this.enforcerOverviewMetrics["tide-token-authorized"] += 1;
|
|
111
|
+
onSuccess?.(enforcedDetails);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
protect(handler, scope, options = {}) {
|
|
116
|
+
return async (...args) => {
|
|
117
|
+
await this.loadedRecentLicenseKeys;
|
|
118
|
+
const protectedHandler = this.lock.withLicenseProtection(handler, scope, {
|
|
119
|
+
...(options ?? {}),
|
|
120
|
+
...this.tideTokenEnforcementComplianceHandlers
|
|
121
|
+
});
|
|
122
|
+
return await protectedHandler(...args);
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
getKey(scope = "default") {
|
|
126
|
+
return this.lock.getCurrentLicenseKey(scope);
|
|
127
|
+
}
|
|
128
|
+
async seal(key, meta = {}) {
|
|
129
|
+
return await this.lock.sealKey(key, {
|
|
130
|
+
validators: [{
|
|
131
|
+
name: "tide-token-authorization"
|
|
132
|
+
}],
|
|
133
|
+
meta
|
|
134
|
+
}, {
|
|
135
|
+
assumePreviouslyValid: true,
|
|
136
|
+
fallbackIfOffline: true,
|
|
137
|
+
autoRemoveExpired: true,
|
|
138
|
+
storeInvalid: true
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
async validate(key) {
|
|
142
|
+
return await this.lock.validate(key);
|
|
143
|
+
}
|
|
144
|
+
async inspect(key) {
|
|
145
|
+
return await this.lock.inspectKey(key);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
;
|
|
149
|
+
module.exports = new TideTokenEnforcementManager();
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trap_stevo/filetide",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.71",
|
|
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": {
|
|
7
7
|
"build": "babel src -d dist/cjs --env-name cjs",
|
|
8
|
+
"start-tide-token-server": "node demos/tideTokenServerDemo.js",
|
|
8
9
|
"start-file-generation": "node demos/FileGenerator.js",
|
|
9
10
|
"start-messager": "node demos/FileTideClientDemo.js",
|
|
10
11
|
"start-net": "node demos/FileTideNetDemo.js",
|
|
@@ -34,11 +35,13 @@
|
|
|
34
35
|
"author": "Steven Compton",
|
|
35
36
|
"license": "See License in LICENSE.md",
|
|
36
37
|
"dependencies": {
|
|
37
|
-
"@trap_stevo/iotide": "^0.0.
|
|
38
|
-
"@trap_stevo/iotide-client": "^0.0.
|
|
39
|
-
"@trap_stevo/legendarybuilderpronodejs-utilities": "^1.0.
|
|
40
|
-
"@trap_stevo/
|
|
41
|
-
"@trap_stevo/
|
|
38
|
+
"@trap_stevo/iotide": "^0.0.44",
|
|
39
|
+
"@trap_stevo/iotide-client": "^0.0.26",
|
|
40
|
+
"@trap_stevo/legendarybuilderpronodejs-utilities": "^1.0.49",
|
|
41
|
+
"@trap_stevo/lockline": "^0.0.11",
|
|
42
|
+
"@trap_stevo/logictide": "^0.0.1",
|
|
43
|
+
"@trap_stevo/metrictide": "^0.0.4",
|
|
44
|
+
"@trap_stevo/timelyst": "^0.0.6",
|
|
42
45
|
"chalk": "^4.1.2",
|
|
43
46
|
"readline": "^1.3.0"
|
|
44
47
|
},
|