@internxt/cli 1.6.1 → 1.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +410 -71
- package/dist/commands/add-cert.d.ts +1 -1
- package/dist/commands/add-cert.js +3 -3
- package/dist/commands/config.d.ts +7 -1
- package/dist/commands/config.js +36 -5
- package/dist/commands/create-folder.d.ts +2 -1
- package/dist/commands/create-folder.js +10 -7
- package/dist/commands/delete-permanently-file.d.ts +1 -0
- package/dist/commands/delete-permanently-folder.d.ts +1 -0
- package/dist/commands/download-file.d.ts +1 -0
- package/dist/commands/download-file.js +4 -2
- package/dist/commands/list.d.ts +1 -0
- package/dist/commands/list.js +2 -4
- package/dist/commands/login-legacy.d.ts +1 -0
- package/dist/commands/logs.js +3 -3
- package/dist/commands/move-file.d.ts +1 -1
- package/dist/commands/move-file.js +7 -21
- package/dist/commands/move-folder.d.ts +1 -1
- package/dist/commands/move-folder.js +7 -21
- package/dist/commands/rename-file.d.ts +1 -0
- package/dist/commands/rename-folder.d.ts +1 -0
- package/dist/commands/trash-clear.d.ts +1 -0
- package/dist/commands/trash-file.d.ts +1 -0
- package/dist/commands/trash-folder.d.ts +1 -0
- package/dist/commands/trash-restore-file.d.ts +1 -1
- package/dist/commands/trash-restore-file.js +7 -21
- package/dist/commands/trash-restore-folder.d.ts +1 -1
- package/dist/commands/trash-restore-folder.js +7 -21
- package/dist/commands/upload-file.d.ts +5 -6
- package/dist/commands/upload-file.js +77 -52
- package/dist/commands/upload-folder.d.ts +1 -0
- package/dist/commands/upload-folder.js +11 -6
- package/dist/commands/webdav-config.d.ts +19 -1
- package/dist/commands/webdav-config.js +81 -3
- package/dist/commands/webdav.d.ts +1 -1
- package/dist/commands/webdav.js +10 -5
- package/dist/commands/whoami.js +2 -1
- package/dist/commands/workspaces-list.d.ts +20 -0
- package/dist/commands/workspaces-list.js +67 -0
- package/dist/commands/workspaces-unset.d.ts +23 -0
- package/dist/commands/workspaces-unset.js +45 -0
- package/dist/commands/workspaces-use.d.ts +27 -0
- package/dist/commands/workspaces-use.js +113 -0
- package/dist/constants/configs.d.ts +13 -0
- package/dist/constants/configs.js +21 -0
- package/dist/hooks/prerun/auth_check.js +13 -4
- package/dist/services/auth.service.d.ts +5 -2
- package/dist/services/auth.service.js +68 -6
- package/dist/services/config.service.d.ts +1 -13
- package/dist/services/config.service.js +44 -41
- package/dist/services/crypto.service.d.ts +5 -0
- package/dist/services/crypto.service.js +43 -0
- package/dist/services/database/database.service.d.ts +9 -0
- package/dist/services/database/database.service.js +39 -0
- package/dist/services/database/drive-file/drive-file.attributes.d.ts +3 -6
- package/dist/services/database/drive-file/drive-file.domain.d.ts +3 -6
- package/dist/services/database/drive-file/drive-file.domain.js +1 -12
- package/dist/services/database/drive-file/drive-file.model.d.ts +15 -0
- package/dist/services/database/drive-file/drive-file.model.js +67 -0
- package/dist/services/database/drive-file/drive-file.repository.d.ts +11 -0
- package/dist/services/database/drive-file/drive-file.repository.js +63 -0
- package/dist/services/database/drive-folder/drive-folder.attributes.d.ts +3 -4
- package/dist/services/database/drive-folder/drive-folder.domain.d.ts +4 -5
- package/dist/services/database/drive-folder/drive-folder.domain.js +11 -15
- package/dist/services/database/drive-folder/drive-folder.model.d.ts +11 -0
- package/dist/services/database/drive-folder/drive-folder.model.js +51 -0
- package/dist/services/database/drive-folder/drive-folder.repository.d.ts +13 -0
- package/dist/services/database/drive-folder/drive-folder.repository.js +99 -0
- package/dist/services/drive/drive-file.service.d.ts +2 -0
- package/dist/services/drive/drive-file.service.js +71 -15
- package/dist/services/drive/drive-folder.service.d.ts +6 -1
- package/dist/services/drive/drive-folder.service.js +157 -31
- package/dist/services/drive/trash.service.d.ts +3 -0
- package/dist/services/drive/trash.service.js +52 -16
- package/dist/services/drive/workspace.service.d.ts +7 -0
- package/dist/services/drive/workspace.service.js +30 -0
- package/dist/services/keys.service.d.ts +7 -0
- package/dist/services/keys.service.js +55 -0
- package/dist/services/local-filesystem/local-filesystem.service.d.ts +2 -2
- package/dist/services/local-filesystem/local-filesystem.service.js +4 -4
- package/dist/services/network/download.service.d.ts +2 -2
- package/dist/services/network/download.service.js +2 -2
- package/dist/services/network/network-facade.service.d.ts +3 -7
- package/dist/services/network/network-facade.service.js +9 -11
- package/dist/services/network/upload/upload-facade.service.d.ts +1 -1
- package/dist/services/network/upload/upload-facade.service.js +15 -8
- package/dist/services/network/upload/upload-file.service.d.ts +5 -4
- package/dist/services/network/upload/upload-file.service.js +73 -41
- package/dist/services/network/upload/upload-folder.service.d.ts +2 -2
- package/dist/services/network/upload/upload-folder.service.js +15 -10
- package/dist/services/network/upload/upload.types.d.ts +13 -2
- package/dist/services/network/upload/upload.types.js +1 -1
- package/dist/services/sdk-manager.service.d.ts +11 -9
- package/dist/services/sdk-manager.service.js +29 -15
- package/dist/services/thumbnail.service.d.ts +19 -1
- package/dist/services/thumbnail.service.js +29 -2
- package/dist/services/universal-link.service.d.ts +3 -1
- package/dist/services/universal-link.service.js +15 -3
- package/dist/services/usage.service.d.ts +1 -2
- package/dist/services/usage.service.js +1 -1
- package/dist/services/validation.service.d.ts +5 -0
- package/dist/services/validation.service.js +36 -22
- package/dist/{webdav/services → services/webdav}/webdav-folder.service.d.ts +1 -7
- package/dist/{webdav/services → services/webdav}/webdav-folder.service.js +6 -10
- package/dist/types/command.types.d.ts +44 -1
- package/dist/types/command.types.js +29 -1
- package/dist/types/config.types.d.ts +1 -0
- package/dist/types/drive.types.d.ts +7 -6
- package/dist/types/network.types.d.ts +6 -0
- package/dist/utils/async.utils.d.ts +2 -1
- package/dist/utils/async.utils.js +13 -2
- package/dist/utils/cli.utils.d.ts +23 -15
- package/dist/utils/cli.utils.js +85 -21
- package/dist/utils/crypto.utils.d.ts +3 -1
- package/dist/utils/crypto.utils.js +15 -2
- package/dist/utils/database.utils.d.ts +11 -0
- package/dist/utils/database.utils.js +26 -0
- package/dist/utils/drive.utils.js +7 -10
- package/dist/utils/errors.utils.d.ts +4 -3
- package/dist/utils/errors.utils.js +16 -13
- package/dist/utils/format.utils.d.ts +1 -0
- package/dist/utils/format.utils.js +3 -0
- package/dist/utils/inquirer.utils.js +10 -1
- package/dist/utils/logger.utils.js +5 -5
- package/dist/utils/network.utils.js +17 -18
- package/dist/utils/path.utils.d.ts +7 -0
- package/dist/utils/path.utils.js +18 -0
- package/dist/utils/thumbnail.utils.d.ts +6 -20
- package/dist/utils/thumbnail.utils.js +20 -45
- package/dist/utils/webdav.utils.d.ts +4 -20
- package/dist/utils/webdav.utils.js +12 -14
- package/dist/utils/xml.utils.d.ts +1 -1
- package/dist/utils/xml.utils.js +1 -1
- package/dist/webdav/handlers/DELETE.handler.d.ts +0 -9
- package/dist/webdav/handlers/DELETE.handler.js +18 -16
- package/dist/webdav/handlers/GET.handler.d.ts +0 -13
- package/dist/webdav/handlers/GET.handler.js +6 -13
- package/dist/webdav/handlers/HEAD.handler.d.ts +0 -5
- package/dist/webdav/handlers/HEAD.handler.js +11 -23
- package/dist/webdav/handlers/MKCOL.handler.d.ts +0 -7
- package/dist/webdav/handlers/MKCOL.handler.js +5 -12
- package/dist/webdav/handlers/MOVE.handler.d.ts +0 -9
- package/dist/webdav/handlers/MOVE.handler.js +10 -16
- package/dist/webdav/handlers/PROPFIND.handler.d.ts +0 -7
- package/dist/webdav/handlers/PROPFIND.handler.js +7 -19
- package/dist/webdav/handlers/PUT.handler.d.ts +0 -15
- package/dist/webdav/handlers/PUT.handler.js +70 -57
- package/dist/webdav/index.js +6 -8
- package/dist/webdav/middewares/auth.middleware.d.ts +1 -2
- package/dist/webdav/middewares/auth.middleware.js +5 -4
- package/dist/webdav/middewares/errors.middleware.js +3 -3
- package/dist/webdav/middewares/webdav-auth.middleware.d.ts +3 -0
- package/dist/webdav/middewares/webdav-auth.middleware.js +44 -0
- package/dist/webdav/webdav-server.d.ts +3 -16
- package/dist/webdav/webdav-server.js +33 -91
- package/oclif.manifest.json +429 -6
- package/package.json +27 -22
package/dist/utils/cli.utils.js
CHANGED
|
@@ -15,8 +15,7 @@ const sdk_manager_service_1 = require("../services/sdk-manager.service");
|
|
|
15
15
|
const inxt_js_1 = require("@internxt/inxt-js");
|
|
16
16
|
const config_service_1 = require("../services/config.service");
|
|
17
17
|
const network_facade_service_1 = require("../services/network/network-facade.service");
|
|
18
|
-
const
|
|
19
|
-
const crypto_service_1 = require("../services/crypto.service");
|
|
18
|
+
const auth_service_1 = require("../services/auth.service");
|
|
20
19
|
class CLIUtils {
|
|
21
20
|
static clearPreviousLine = (jsonFlag) => {
|
|
22
21
|
if (!jsonFlag) {
|
|
@@ -77,6 +76,12 @@ class CLIUtils {
|
|
|
77
76
|
description: 'Prevents the CLI from being interactive. When enabled, the CLI will not request input through the console and will throw errors directly.',
|
|
78
77
|
required: false,
|
|
79
78
|
}),
|
|
79
|
+
debug: core_1.Flags.boolean({
|
|
80
|
+
env: 'INXT_DEBUG',
|
|
81
|
+
helpGroup: 'helper',
|
|
82
|
+
description: 'Enables debug mode. When enabled, the CLI will print debug messages to the console.',
|
|
83
|
+
required: false,
|
|
84
|
+
}),
|
|
80
85
|
};
|
|
81
86
|
static getValueFromFlag = async (flag, command, validation, reporter) => {
|
|
82
87
|
if (flag.value) {
|
|
@@ -117,12 +122,7 @@ class CLIUtils {
|
|
|
117
122
|
error: new command_types_1.NotValidFolderUuidError(),
|
|
118
123
|
canBeEmpty: true,
|
|
119
124
|
}, reporter);
|
|
120
|
-
|
|
121
|
-
return undefined;
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
return destinationFolderUuid;
|
|
125
|
-
}
|
|
125
|
+
return destinationFolderUuid;
|
|
126
126
|
};
|
|
127
127
|
static promptWithAttempts = async (prompt, maxAttempts, validation, reporter) => {
|
|
128
128
|
let isValid = false;
|
|
@@ -143,11 +143,11 @@ class CLIUtils {
|
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
} while (!isValid && currentAttempts < maxAttempts);
|
|
146
|
-
if (
|
|
147
|
-
|
|
146
|
+
if (isValid) {
|
|
147
|
+
return promptValue;
|
|
148
148
|
}
|
|
149
149
|
else {
|
|
150
|
-
|
|
150
|
+
throw validation.error;
|
|
151
151
|
}
|
|
152
152
|
};
|
|
153
153
|
static timer = () => {
|
|
@@ -160,6 +160,40 @@ class CLIUtils {
|
|
|
160
160
|
},
|
|
161
161
|
};
|
|
162
162
|
};
|
|
163
|
+
static formatDuration = (milliseconds) => {
|
|
164
|
+
if (milliseconds <= 0) {
|
|
165
|
+
return '00:00:00.000';
|
|
166
|
+
}
|
|
167
|
+
const totalSeconds = Math.floor(milliseconds / 1000);
|
|
168
|
+
const hours = Math.floor(totalSeconds / 3600);
|
|
169
|
+
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
|
170
|
+
const seconds = totalSeconds % 60;
|
|
171
|
+
const ms = Math.floor(milliseconds % 1000);
|
|
172
|
+
const hoursFormated = hours.toString().padStart(2, '0');
|
|
173
|
+
const minutesFormated = minutes.toString().padStart(2, '0');
|
|
174
|
+
const secondsFormated = seconds.toString().padStart(2, '0');
|
|
175
|
+
const msFormated = ms.toString().padStart(3, '0');
|
|
176
|
+
return `${hoursFormated}:${minutesFormated}:${secondsFormated}.${msFormated}`;
|
|
177
|
+
};
|
|
178
|
+
static formatBytesToString = (bytes) => {
|
|
179
|
+
if (bytes <= 0) {
|
|
180
|
+
return '0.00 KB';
|
|
181
|
+
}
|
|
182
|
+
const kb = bytes / 1024;
|
|
183
|
+
if (kb < 1024) {
|
|
184
|
+
return `${kb.toFixed(2)} KB`;
|
|
185
|
+
}
|
|
186
|
+
const mb = kb / 1024;
|
|
187
|
+
return `${mb.toFixed(2)} MB`;
|
|
188
|
+
};
|
|
189
|
+
static calculateThroughputMBps = (bytes, milliseconds) => {
|
|
190
|
+
if (bytes <= 0 || milliseconds <= 0) {
|
|
191
|
+
return 0;
|
|
192
|
+
}
|
|
193
|
+
const megabytes = bytes / 1024 / 1024;
|
|
194
|
+
const seconds = milliseconds / 1000;
|
|
195
|
+
return megabytes / seconds;
|
|
196
|
+
};
|
|
163
197
|
static catchError = ({ error, logReporter, command, jsonFlag, }) => {
|
|
164
198
|
let message;
|
|
165
199
|
if ('message' in error && error.message.trim().length > 0) {
|
|
@@ -178,22 +212,52 @@ class CLIUtils {
|
|
|
178
212
|
}
|
|
179
213
|
};
|
|
180
214
|
static parseEmpty = async (input) => (input.trim().length === 0 ? ' ' : input);
|
|
181
|
-
static prepareNetwork = (
|
|
182
|
-
|
|
215
|
+
static prepareNetwork = async (loginUserDetails) => {
|
|
216
|
+
const { credentials, mnemonic, bucket } = await this.getNetworkCreds(loginUserDetails);
|
|
183
217
|
const networkModule = sdk_manager_service_1.SdkManager.instance.getNetwork({
|
|
184
|
-
user:
|
|
185
|
-
pass:
|
|
218
|
+
user: credentials.user,
|
|
219
|
+
pass: credentials.pass,
|
|
186
220
|
});
|
|
187
221
|
const environment = new inxt_js_1.Environment({
|
|
188
|
-
bridgeUser:
|
|
189
|
-
bridgePass:
|
|
222
|
+
bridgeUser: credentials.user,
|
|
223
|
+
bridgePass: credentials.pass,
|
|
224
|
+
encryptionKey: mnemonic,
|
|
190
225
|
bridgeUrl: config_service_1.ConfigService.instance.get('NETWORK_URL'),
|
|
191
|
-
encryptionKey: loginUserDetails.mnemonic,
|
|
192
226
|
appDetails: sdk_manager_service_1.SdkManager.getAppDetails(),
|
|
193
227
|
});
|
|
194
|
-
const networkFacade = new network_facade_service_1.NetworkFacade(networkModule, environment
|
|
195
|
-
|
|
196
|
-
|
|
228
|
+
const networkFacade = new network_facade_service_1.NetworkFacade(networkModule, environment);
|
|
229
|
+
return { networkFacade, bucket, mnemonic };
|
|
230
|
+
};
|
|
231
|
+
static fallbackToRootFolderIdIfEmpty = async (folderId) => {
|
|
232
|
+
if (folderId.trim().length === 0) {
|
|
233
|
+
return await auth_service_1.AuthService.instance.getCurrentRootFolder();
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
return folderId;
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
static getNetworkCreds = async (userCredentials) => {
|
|
240
|
+
const currentWorkspace = await auth_service_1.AuthService.instance.getCurrentWorkspace();
|
|
241
|
+
if (currentWorkspace) {
|
|
242
|
+
return {
|
|
243
|
+
bucket: currentWorkspace.workspaceCredentials.bucket,
|
|
244
|
+
credentials: {
|
|
245
|
+
user: currentWorkspace.workspaceCredentials.credentials.user,
|
|
246
|
+
pass: currentWorkspace.workspaceCredentials.credentials.pass,
|
|
247
|
+
},
|
|
248
|
+
mnemonic: currentWorkspace.workspaceData.workspaceUser.key,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
return {
|
|
253
|
+
bucket: userCredentials.bucket,
|
|
254
|
+
credentials: {
|
|
255
|
+
user: userCredentials.bridgeUser,
|
|
256
|
+
pass: userCredentials.userId,
|
|
257
|
+
},
|
|
258
|
+
mnemonic: userCredentials.mnemonic,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
197
261
|
};
|
|
198
262
|
}
|
|
199
263
|
exports.CLIUtils = CLIUtils;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export declare class CryptoUtils {
|
|
2
|
-
static getAesInit()
|
|
2
|
+
static readonly getAesInit: () => {
|
|
3
3
|
iv: string;
|
|
4
4
|
salt: string;
|
|
5
5
|
};
|
|
6
|
+
static readonly extendSecret: (secret: Uint8Array, length: number) => Promise<string>;
|
|
7
|
+
static readonly XORhex: (a: string, b: string) => string;
|
|
6
8
|
}
|
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CryptoUtils = void 0;
|
|
4
|
+
const hash_wasm_1 = require("hash-wasm");
|
|
4
5
|
const config_service_1 = require("../services/config.service");
|
|
5
6
|
class CryptoUtils {
|
|
6
|
-
static getAesInit() {
|
|
7
|
+
static getAesInit = () => {
|
|
7
8
|
return { iv: config_service_1.ConfigService.instance.get('APP_MAGIC_IV'), salt: config_service_1.ConfigService.instance.get('APP_MAGIC_SALT') };
|
|
8
|
-
}
|
|
9
|
+
};
|
|
10
|
+
static extendSecret = (secret, length) => {
|
|
11
|
+
return (0, hash_wasm_1.blake3)(secret, length);
|
|
12
|
+
};
|
|
13
|
+
static XORhex = (a, b) => {
|
|
14
|
+
let res = '', i = a.length, j = b.length;
|
|
15
|
+
if (i != j) {
|
|
16
|
+
throw new Error('Can XOR only strings with identical length');
|
|
17
|
+
}
|
|
18
|
+
while (i-- > 0 && j-- > 0)
|
|
19
|
+
res = (Number.parseInt(a.charAt(i), 16) ^ Number.parseInt(b.charAt(j), 16)).toString(16) + res;
|
|
20
|
+
return res;
|
|
21
|
+
};
|
|
9
22
|
}
|
|
10
23
|
exports.CryptoUtils = CryptoUtils;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare class DatabaseUtils {
|
|
2
|
+
static readonly CREATE_BATCH_SIZE = 100;
|
|
3
|
+
static readonly getFolderByPathGeneric: <T>({ path, parentUuid, onFound, getByParentAndName, }: {
|
|
4
|
+
path: string;
|
|
5
|
+
parentUuid: string;
|
|
6
|
+
onFound: (uuid: string) => Promise<T>;
|
|
7
|
+
getByParentAndName: (parentUuid: string, name: string) => Promise<{
|
|
8
|
+
uuid: string;
|
|
9
|
+
} | null | undefined>;
|
|
10
|
+
}) => Promise<T | undefined>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DatabaseUtils = void 0;
|
|
4
|
+
class DatabaseUtils {
|
|
5
|
+
static CREATE_BATCH_SIZE = 100;
|
|
6
|
+
static getFolderByPathGeneric = async ({ path, parentUuid, onFound, getByParentAndName, }) => {
|
|
7
|
+
path = path.replace(/^\//, '').replace(/\/$/, '');
|
|
8
|
+
if (path.trim().length === 0) {
|
|
9
|
+
return onFound(parentUuid);
|
|
10
|
+
}
|
|
11
|
+
const slashIndex = path.indexOf('/');
|
|
12
|
+
const currentFolder = slashIndex === -1 ? path : path.substring(0, slashIndex);
|
|
13
|
+
const nextPath = slashIndex === -1 ? '' : path.substring(slashIndex + 1);
|
|
14
|
+
const folder = await getByParentAndName(parentUuid, currentFolder);
|
|
15
|
+
if (!folder) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
return this.getFolderByPathGeneric({
|
|
19
|
+
path: nextPath,
|
|
20
|
+
parentUuid: folder.uuid,
|
|
21
|
+
onFound,
|
|
22
|
+
getByParentAndName,
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
exports.DatabaseUtils = DatabaseUtils;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DriveUtils = void 0;
|
|
4
|
+
const types_1 = require("@internxt/sdk/dist/drive/storage/types");
|
|
4
5
|
class DriveUtils {
|
|
5
6
|
static driveFileMetaToItem(fileMeta) {
|
|
6
7
|
return {
|
|
7
8
|
itemType: 'file',
|
|
8
9
|
uuid: fileMeta.uuid ?? '',
|
|
9
10
|
status: fileMeta.status,
|
|
10
|
-
folderId: fileMeta.folderId,
|
|
11
11
|
folderUuid: fileMeta.folderUuid,
|
|
12
12
|
size: Number(fileMeta.size),
|
|
13
13
|
name: fileMeta.plainName ?? fileMeta.name,
|
|
@@ -17,7 +17,6 @@ class DriveUtils {
|
|
|
17
17
|
creationTime: new Date(fileMeta.creationTime ?? fileMeta.createdAt),
|
|
18
18
|
modificationTime: new Date(fileMeta.modificationTime ?? fileMeta.updatedAt),
|
|
19
19
|
fileId: fileMeta.fileId,
|
|
20
|
-
id: fileMeta.id,
|
|
21
20
|
type: fileMeta.type,
|
|
22
21
|
};
|
|
23
22
|
}
|
|
@@ -25,30 +24,28 @@ class DriveUtils {
|
|
|
25
24
|
return {
|
|
26
25
|
itemType: 'folder',
|
|
27
26
|
uuid: folderMeta.uuid,
|
|
28
|
-
id: folderMeta.id,
|
|
29
27
|
bucket: folderMeta.bucket,
|
|
30
|
-
status: folderMeta.deleted || folderMeta.removed ?
|
|
28
|
+
status: folderMeta.deleted || folderMeta.removed ? types_1.FileStatus.TRASHED : types_1.FileStatus.EXISTS,
|
|
31
29
|
name: folderMeta.plainName ?? folderMeta.name,
|
|
32
|
-
encryptedName: folderMeta.name,
|
|
33
|
-
parentId: folderMeta.parentId,
|
|
34
30
|
parentUuid: folderMeta.parentUuid,
|
|
35
31
|
createdAt: new Date(folderMeta.createdAt),
|
|
36
32
|
updatedAt: new Date(folderMeta.updatedAt),
|
|
33
|
+
creationTime: new Date(folderMeta.creation_time),
|
|
34
|
+
modificationTime: new Date(folderMeta.creation_time),
|
|
37
35
|
};
|
|
38
36
|
}
|
|
39
37
|
static createFolderResponseToItem(folderResponse) {
|
|
40
38
|
return {
|
|
41
39
|
itemType: 'folder',
|
|
42
40
|
uuid: folderResponse.uuid,
|
|
43
|
-
id: folderResponse.id,
|
|
44
41
|
bucket: folderResponse.bucket,
|
|
45
|
-
status: folderResponse.deleted || folderResponse.removed ?
|
|
42
|
+
status: folderResponse.deleted || folderResponse.removed ? types_1.FileStatus.TRASHED : types_1.FileStatus.EXISTS,
|
|
46
43
|
name: folderResponse.plainName ?? folderResponse.name,
|
|
47
|
-
encryptedName: folderResponse.name,
|
|
48
|
-
parentId: folderResponse.parentId,
|
|
49
44
|
parentUuid: folderResponse.parentUuid,
|
|
50
45
|
createdAt: new Date(folderResponse.createdAt),
|
|
51
46
|
updatedAt: new Date(folderResponse.updatedAt),
|
|
47
|
+
creationTime: new Date(folderResponse.creationTime),
|
|
48
|
+
modificationTime: new Date(folderResponse.modificationTime),
|
|
52
49
|
};
|
|
53
50
|
}
|
|
54
51
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export declare function isError(error: unknown): error is Error;
|
|
2
|
-
export declare function isAlreadyExistsError(error: unknown): error is Error;
|
|
3
1
|
export declare class ErrorUtils {
|
|
4
|
-
static
|
|
2
|
+
static readonly isError: (error: unknown) => error is Error;
|
|
3
|
+
static readonly report: (error: unknown, props?: Record<string, unknown>) => void;
|
|
4
|
+
static readonly isAlreadyExistsError: (error: unknown) => error is Error;
|
|
5
|
+
static readonly isFileNotFoundError: (error: unknown) => error is NodeJS.ErrnoException;
|
|
5
6
|
}
|
|
6
7
|
export declare class ConflictError extends Error {
|
|
7
8
|
statusCode: number;
|
|
@@ -1,26 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.NotImplementedError = exports.MethodNotAllowed = exports.UnsupportedMediaTypeError = exports.BadRequestError = exports.NotFoundError = exports.ConflictError = exports.ErrorUtils = void 0;
|
|
4
|
-
exports.isError = isError;
|
|
5
|
-
exports.isAlreadyExistsError = isAlreadyExistsError;
|
|
6
4
|
const logger_utils_1 = require("./logger.utils");
|
|
7
|
-
const node_util_1 = require("node:util");
|
|
8
|
-
function isError(error) {
|
|
9
|
-
return node_util_1.types.isNativeError(error);
|
|
10
|
-
}
|
|
11
|
-
function isAlreadyExistsError(error) {
|
|
12
|
-
return ((isError(error) && error.message.includes('already exists')) ||
|
|
13
|
-
(typeof error === 'object' && error !== null && 'status' in error && error.status === 409));
|
|
14
|
-
}
|
|
15
5
|
class ErrorUtils {
|
|
16
|
-
static
|
|
17
|
-
|
|
6
|
+
static isError = (error) => {
|
|
7
|
+
return typeof Error.isError === 'function'
|
|
8
|
+
? Error.isError(error)
|
|
9
|
+
: error instanceof Error ||
|
|
10
|
+
(typeof error === 'object' && error !== null && 'message' in error && ('stack' in error || 'name' in error));
|
|
11
|
+
};
|
|
12
|
+
static report = (error, props = {}) => {
|
|
13
|
+
if (this.isError(error)) {
|
|
18
14
|
logger_utils_1.logger.error(`[REPORTED_ERROR]: ${error.message}\nProperties => ${JSON.stringify(props, null, 2)}\nStack => ${error.stack}`);
|
|
19
15
|
}
|
|
20
16
|
else {
|
|
21
17
|
logger_utils_1.logger.error(`[REPORTED_ERROR]: ${JSON.stringify(error)}\nProperties => ${JSON.stringify(props, null, 2)}\n`);
|
|
22
18
|
}
|
|
23
|
-
}
|
|
19
|
+
};
|
|
20
|
+
static isAlreadyExistsError = (error) => {
|
|
21
|
+
return ((this.isError(error) && error.message.includes('already exists')) ||
|
|
22
|
+
(typeof error === 'object' && error !== null && 'status' in error && error.status === 409));
|
|
23
|
+
};
|
|
24
|
+
static isFileNotFoundError = (error) => {
|
|
25
|
+
return this.isError(error) && 'code' in error && error.code === 'ENOENT';
|
|
26
|
+
};
|
|
24
27
|
}
|
|
25
28
|
exports.ErrorUtils = ErrorUtils;
|
|
26
29
|
class ConflictError extends Error {
|
|
@@ -3,4 +3,5 @@ export declare class FormatUtils {
|
|
|
3
3
|
static readonly formatDate: (date: string | Date) => string;
|
|
4
4
|
static readonly formatDateForWebDav: (date: string | Date) => string;
|
|
5
5
|
static readonly formatLimit: (limit: number) => string;
|
|
6
|
+
static readonly capitalizeFirstLetter: (string: string) => string;
|
|
6
7
|
}
|
|
@@ -15,7 +15,16 @@ class InquirerUtils {
|
|
|
15
15
|
const confirmation = await (0, prompts_1.confirm)({ message, default: options.confirm?.default || false });
|
|
16
16
|
return confirmation ? 'y' : 'n';
|
|
17
17
|
}
|
|
18
|
-
case '
|
|
18
|
+
case 'list':
|
|
19
|
+
if (!options.choices)
|
|
20
|
+
throw new Error('Missing choices');
|
|
21
|
+
return (0, prompts_1.select)({
|
|
22
|
+
message,
|
|
23
|
+
choices: options.choices.values,
|
|
24
|
+
default: options.choices.values[options.choices.default ?? 0],
|
|
25
|
+
});
|
|
26
|
+
case 'input':
|
|
27
|
+
default: {
|
|
19
28
|
return (0, prompts_1.input)({ message });
|
|
20
29
|
}
|
|
21
30
|
}
|
|
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.webdavLogger = exports.logger = void 0;
|
|
7
7
|
const winston_1 = __importDefault(require("winston"));
|
|
8
|
-
const
|
|
8
|
+
const configs_1 = require("../constants/configs");
|
|
9
9
|
const maxLogSize = 40 * 1024 * 1024;
|
|
10
10
|
const maxLogsFiles = 5;
|
|
11
11
|
exports.logger = winston_1.default.createLogger({
|
|
@@ -16,14 +16,14 @@ exports.logger = winston_1.default.createLogger({
|
|
|
16
16
|
new winston_1.default.transports.File({
|
|
17
17
|
filename: 'internxt-cli-error.log',
|
|
18
18
|
level: 'error',
|
|
19
|
-
dirname:
|
|
19
|
+
dirname: configs_1.INTERNXT_CLI_LOGS_DIR,
|
|
20
20
|
maxsize: maxLogSize,
|
|
21
21
|
maxFiles: maxLogsFiles,
|
|
22
22
|
tailable: true,
|
|
23
23
|
}),
|
|
24
24
|
new winston_1.default.transports.File({
|
|
25
25
|
filename: 'internxt-cli-combined.log',
|
|
26
|
-
dirname:
|
|
26
|
+
dirname: configs_1.INTERNXT_CLI_LOGS_DIR,
|
|
27
27
|
maxsize: maxLogSize,
|
|
28
28
|
maxFiles: maxLogsFiles,
|
|
29
29
|
tailable: true,
|
|
@@ -38,14 +38,14 @@ exports.webdavLogger = winston_1.default.createLogger({
|
|
|
38
38
|
new winston_1.default.transports.File({
|
|
39
39
|
filename: 'internxt-webdav-error.log',
|
|
40
40
|
level: 'error',
|
|
41
|
-
dirname:
|
|
41
|
+
dirname: configs_1.INTERNXT_CLI_LOGS_DIR,
|
|
42
42
|
maxsize: maxLogSize,
|
|
43
43
|
maxFiles: maxLogsFiles,
|
|
44
44
|
tailable: true,
|
|
45
45
|
}),
|
|
46
46
|
new winston_1.default.transports.File({
|
|
47
47
|
filename: 'internxt-webdav-combined.log',
|
|
48
|
-
dirname:
|
|
48
|
+
dirname: configs_1.INTERNXT_CLI_LOGS_DIR,
|
|
49
49
|
maxsize: maxLogSize,
|
|
50
50
|
maxFiles: maxLogsFiles,
|
|
51
51
|
tailable: true,
|
|
@@ -9,7 +9,7 @@ const promises_1 = require("node:fs/promises");
|
|
|
9
9
|
const node_path_1 = __importDefault(require("node:path"));
|
|
10
10
|
const selfsigned_1 = __importDefault(require("selfsigned"));
|
|
11
11
|
const range_parser_1 = __importDefault(require("range-parser"));
|
|
12
|
-
const
|
|
12
|
+
const configs_1 = require("../constants/configs");
|
|
13
13
|
class NetworkUtils {
|
|
14
14
|
static getAuthFromCredentials(creds) {
|
|
15
15
|
return {
|
|
@@ -18,8 +18,8 @@ class NetworkUtils {
|
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
20
|
static WEBDAV_SSL_CERTS_PATH = {
|
|
21
|
-
cert: node_path_1.default.join(
|
|
22
|
-
privateKey: node_path_1.default.join(
|
|
21
|
+
cert: node_path_1.default.join(configs_1.WEBDAV_SSL_CERTS_DIR, 'cert.crt'),
|
|
22
|
+
privateKey: node_path_1.default.join(configs_1.WEBDAV_SSL_CERTS_DIR, 'priv.key'),
|
|
23
23
|
};
|
|
24
24
|
static async generateNewSelfsignedCerts(configs) {
|
|
25
25
|
const newCerts = await this.generateSelfSignedSSLCerts(configs);
|
|
@@ -59,17 +59,16 @@ class NetworkUtils {
|
|
|
59
59
|
}
|
|
60
60
|
static async generateSelfSignedSSLCerts(configs) {
|
|
61
61
|
const attrs = [{ name: 'commonName', value: configs.host }];
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
];
|
|
62
|
+
const extension = {
|
|
63
|
+
name: 'subjectAltName',
|
|
64
|
+
altNames: [
|
|
65
|
+
{
|
|
66
|
+
type: 2,
|
|
67
|
+
value: configs.host,
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
};
|
|
71
|
+
const extensions = [extension];
|
|
73
72
|
const notAfterDate = new Date();
|
|
74
73
|
notAfterDate.setDate(notAfterDate.getDate() + 365);
|
|
75
74
|
const pems = await selfsigned_1.default.generate(attrs, { notAfterDate, algorithm: 'sha256', keySize: 2048, extensions });
|
|
@@ -87,10 +86,7 @@ class NetworkUtils {
|
|
|
87
86
|
else if (parsed.length <= 0) {
|
|
88
87
|
throw new Error(`Empty Range-Request. ${JSON.stringify(rangeOptions)}`);
|
|
89
88
|
}
|
|
90
|
-
|
|
91
|
-
throw new Error(`Unkwnown Range-Request type "${parsed.type}". ${JSON.stringify(rangeOptions)}`);
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
89
|
+
if (parsed.type === 'bytes') {
|
|
94
90
|
const rangeSize = parsed[0].end - parsed[0].start + 1;
|
|
95
91
|
return {
|
|
96
92
|
range: rangeOptions.range,
|
|
@@ -99,6 +95,9 @@ class NetworkUtils {
|
|
|
99
95
|
parsed: parsed[0],
|
|
100
96
|
};
|
|
101
97
|
}
|
|
98
|
+
else {
|
|
99
|
+
throw new Error(`Unkwnown Range-Request type "${parsed.type}". ${JSON.stringify(rangeOptions)}`);
|
|
100
|
+
}
|
|
102
101
|
}
|
|
103
102
|
else if (parsed === -1) {
|
|
104
103
|
throw new Error(`Malformed Range-Request. ${JSON.stringify(rangeOptions)}`);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.PathUtils = void 0;
|
|
7
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
class PathUtils {
|
|
9
|
+
static getPathFileData(filePath) {
|
|
10
|
+
const folderPath = node_path_1.default.dirname(filePath);
|
|
11
|
+
const fileExt = node_path_1.default.extname(filePath);
|
|
12
|
+
const fileName = node_path_1.default.basename(filePath, fileExt);
|
|
13
|
+
const fileExtWithoutDot = fileExt.replace('.', '').trim();
|
|
14
|
+
const fileType = fileExtWithoutDot.length > 0 ? fileExtWithoutDot : null;
|
|
15
|
+
return { folderPath, fileName, fileType };
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.PathUtils = PathUtils;
|
|
@@ -1,26 +1,12 @@
|
|
|
1
|
-
import { Readable } from 'node:stream';
|
|
2
|
-
import { NetworkFacade } from '../services/network/network-facade.service';
|
|
3
|
-
import { BufferStream } from './stream.utils';
|
|
4
1
|
export declare const ThumbnailConfig: {
|
|
5
2
|
readonly MaxWidth: 300;
|
|
6
3
|
readonly MaxHeight: 300;
|
|
7
4
|
readonly Quality: 100;
|
|
8
5
|
readonly Type: "png";
|
|
9
6
|
};
|
|
10
|
-
export declare
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
userBucket: string;
|
|
17
|
-
fileUuid: string;
|
|
18
|
-
networkFacade: NetworkFacade;
|
|
19
|
-
}) => Promise<void>;
|
|
20
|
-
export declare const createFileStreamWithBuffer: ({ path, fileType, }: {
|
|
21
|
-
path: string;
|
|
22
|
-
fileType: string;
|
|
23
|
-
}) => {
|
|
24
|
-
bufferStream?: BufferStream;
|
|
25
|
-
fileStream: Readable;
|
|
26
|
-
};
|
|
7
|
+
export declare class ThumbnailUtils {
|
|
8
|
+
static readonly MAX_IMAGE_THUMBNAILABLE_SIZE_IN_MB: number;
|
|
9
|
+
static readonly isFileThumbnailable: (fileType: string) => boolean;
|
|
10
|
+
static readonly isPDFThumbnailable: (fileType: string) => boolean;
|
|
11
|
+
static readonly isImageThumbnailable: (fileType: string, size: number) => boolean;
|
|
12
|
+
}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const thumbnail_service_1 = require("../services/thumbnail.service");
|
|
5
|
-
const errors_utils_1 = require("./errors.utils");
|
|
6
|
-
const stream_utils_1 = require("./stream.utils");
|
|
7
|
-
const node_fs_1 = require("node:fs");
|
|
3
|
+
exports.ThumbnailUtils = exports.ThumbnailConfig = void 0;
|
|
8
4
|
exports.ThumbnailConfig = {
|
|
9
5
|
MaxWidth: 300,
|
|
10
6
|
MaxHeight: 300,
|
|
@@ -25,48 +21,27 @@ const imageExtensions = {
|
|
|
25
21
|
const pdfExtensions = {
|
|
26
22
|
pdf: ['pdf'],
|
|
27
23
|
};
|
|
28
|
-
const thumbnailableImageExtension = [
|
|
24
|
+
const thumbnailableImageExtension = new Set([
|
|
29
25
|
...imageExtensions['jpg'],
|
|
30
26
|
...imageExtensions['png'],
|
|
31
27
|
...imageExtensions['webp'],
|
|
32
28
|
...imageExtensions['gif'],
|
|
33
29
|
...imageExtensions['tiff'],
|
|
34
|
-
];
|
|
35
|
-
const thumbnailablePdfExtension = pdfExtensions['pdf'];
|
|
36
|
-
const thumbnailableExtension =
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (thumbnailBuffer) {
|
|
53
|
-
await thumbnail_service_1.ThumbnailService.instance.uploadThumbnail(thumbnailBuffer, fileType, userBucket, fileUuid, networkFacade);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
catch (error) {
|
|
57
|
-
errors_utils_1.ErrorUtils.report(error);
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
exports.tryUploadThumbnail = tryUploadThumbnail;
|
|
61
|
-
const createFileStreamWithBuffer = ({ path, fileType, }) => {
|
|
62
|
-
const readable = (0, node_fs_1.createReadStream)(path);
|
|
63
|
-
if ((0, exports.isFileThumbnailable)(fileType)) {
|
|
64
|
-
const bufferStream = new stream_utils_1.BufferStream();
|
|
65
|
-
return {
|
|
66
|
-
bufferStream,
|
|
67
|
-
fileStream: readable.pipe(bufferStream),
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
return { fileStream: readable };
|
|
71
|
-
};
|
|
72
|
-
exports.createFileStreamWithBuffer = createFileStreamWithBuffer;
|
|
30
|
+
]);
|
|
31
|
+
const thumbnailablePdfExtension = new Set(pdfExtensions['pdf']);
|
|
32
|
+
const thumbnailableExtension = new Set(thumbnailableImageExtension);
|
|
33
|
+
class ThumbnailUtils {
|
|
34
|
+
static MAX_IMAGE_THUMBNAILABLE_SIZE_IN_MB = 500 * 1024 * 1024;
|
|
35
|
+
static isFileThumbnailable = (fileType) => {
|
|
36
|
+
return fileType.trim().length > 0 && thumbnailableExtension.has(fileType.trim().toLowerCase());
|
|
37
|
+
};
|
|
38
|
+
static isPDFThumbnailable = (fileType) => {
|
|
39
|
+
return fileType.trim().length > 0 && thumbnailablePdfExtension.has(fileType.trim().toLowerCase());
|
|
40
|
+
};
|
|
41
|
+
static isImageThumbnailable = (fileType, size) => {
|
|
42
|
+
if (size > ThumbnailUtils.MAX_IMAGE_THUMBNAILABLE_SIZE_IN_MB)
|
|
43
|
+
return false;
|
|
44
|
+
return fileType.trim().length > 0 && thumbnailableImageExtension.has(fileType.trim().toLowerCase());
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
exports.ThumbnailUtils = ThumbnailUtils;
|