@internxt/cli 1.6.7 → 1.6.8
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 +36 -231
- package/dist/commands/create-folder.js +2 -6
- package/dist/commands/delete-permanently-file.js +1 -1
- package/dist/commands/delete-permanently-folder.js +1 -1
- package/dist/commands/download-file.js +3 -3
- package/dist/commands/list.d.ts +2 -0
- package/dist/commands/list.js +1 -1
- package/dist/commands/login.d.ts +0 -1
- package/dist/commands/login.js +1 -11
- package/dist/commands/move-file.d.ts +1 -0
- package/dist/commands/move-file.js +1 -1
- package/dist/commands/move-folder.js +1 -1
- package/dist/commands/rename-file.js +1 -1
- package/dist/commands/rename-folder.js +1 -1
- package/dist/commands/trash-file.js +1 -1
- package/dist/commands/trash-folder.js +1 -1
- package/dist/commands/trash-list.d.ts +2 -0
- package/dist/commands/trash-restore-file.d.ts +1 -0
- package/dist/commands/trash-restore-file.js +1 -1
- package/dist/commands/trash-restore-folder.js +1 -1
- package/dist/commands/upload-file.d.ts +1 -0
- package/dist/commands/upload-file.js +22 -13
- package/dist/hooks/prerun/auth_check.js +2 -2
- package/dist/services/auth.service.d.ts +3 -3
- package/dist/services/auth.service.js +30 -40
- package/dist/services/crypto.service.d.ts +0 -4
- package/dist/services/crypto.service.js +1 -32
- package/dist/services/database/drive-item/drive-item.model.js +1 -0
- package/dist/services/database/drive-item/drive-item.repository.js +12 -2
- package/dist/services/drive/drive-file.service.d.ts +2 -0
- package/dist/services/drive/drive-file.service.js +48 -18
- package/dist/services/drive/drive-folder.service.d.ts +2 -0
- package/dist/services/drive/drive-folder.service.js +14 -46
- package/dist/services/drive/trash.service.d.ts +2 -0
- package/dist/services/drive/trash.service.js +14 -41
- package/dist/services/network/upload/upload-file.service.js +5 -9
- package/dist/services/network/upload/upload.types.d.ts +2 -1
- package/dist/services/sdk-manager.service.d.ts +0 -2
- package/dist/services/sdk-manager.service.js +0 -7
- package/dist/services/thumbnail.service.d.ts +4 -13
- package/dist/services/thumbnail.service.js +7 -21
- package/dist/services/universal-link.service.d.ts +1 -1
- package/dist/services/universal-link.service.js +2 -2
- package/dist/services/validation.service.d.ts +1 -1
- package/dist/services/validation.service.js +3 -2
- package/dist/types/command.types.d.ts +0 -29
- package/dist/types/command.types.js +1 -15
- package/dist/types/network.types.d.ts +3 -11
- package/dist/types/webdav.types.d.ts +0 -3
- package/dist/utils/cli.utils.js +9 -22
- package/dist/utils/logger.utils.js +9 -2
- package/dist/utils/stream.utils.d.ts +2 -2
- package/dist/utils/stream.utils.js +7 -6
- package/dist/utils/thumbnail.utils.d.ts +1 -3
- package/dist/utils/thumbnail.utils.js +3 -13
- package/dist/utils/upload.utils.d.ts +1 -1
- package/dist/utils/upload.utils.js +2 -2
- package/dist/utils/webdav.utils.d.ts +2 -0
- package/dist/utils/webdav.utils.js +16 -0
- package/dist/webdav/handlers/GET.handler.js +3 -2
- package/dist/webdav/handlers/HEAD.handler.js +1 -0
- package/dist/webdav/handlers/PROPFIND.handler.js +3 -4
- package/dist/webdav/handlers/PUT.handler.js +24 -10
- package/dist/webdav/index.js +2 -2
- package/dist/webdav/middewares/auth.middleware.js +1 -1
- package/dist/webdav/middewares/errors.middleware.js +29 -5
- package/oclif.manifest.json +9 -198
- package/package.json +18 -17
- package/dist/commands/workspaces-list.d.ts +0 -20
- package/dist/commands/workspaces-list.js +0 -68
- package/dist/commands/workspaces-unset.d.ts +0 -23
- package/dist/commands/workspaces-unset.js +0 -46
- package/dist/commands/workspaces-use.d.ts +0 -27
- package/dist/commands/workspaces-use.js +0 -114
- package/dist/services/drive/workspace.service.d.ts +0 -7
- package/dist/services/drive/workspace.service.js +0 -30
|
@@ -19,8 +19,8 @@ class UploadUtils {
|
|
|
19
19
|
throw new Error('File is too big (more than 100 GB)');
|
|
20
20
|
}
|
|
21
21
|
};
|
|
22
|
-
static prepareUploadStreams = (readable, fileType) => {
|
|
23
|
-
const isThumbnailable = thumbnail_utils_1.ThumbnailUtils.
|
|
22
|
+
static prepareUploadStreams = (readable, fileType, size) => {
|
|
23
|
+
const isThumbnailable = thumbnail_utils_1.ThumbnailUtils.isImageThumbnailable(fileType, size);
|
|
24
24
|
if (!isThumbnailable) {
|
|
25
25
|
return { fileStream: readable, thumbnailStream: undefined, isThumbnailable };
|
|
26
26
|
}
|
|
@@ -13,4 +13,6 @@ export declare class WebDavUtils {
|
|
|
13
13
|
itemType: 'file' | 'folder';
|
|
14
14
|
uuid: string;
|
|
15
15
|
}>(driveItem: T): Promise<void>;
|
|
16
|
+
static generateETag(parts: Array<string | number | null | undefined>): string;
|
|
17
|
+
static getItemETag(driveItem: DriveFileItem | DriveFolderItem): string;
|
|
16
18
|
}
|
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.WebDavUtils = void 0;
|
|
7
7
|
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
const node_crypto_1 = require("node:crypto");
|
|
8
9
|
const drive_item_service_1 = require("../services/drive/drive-item.service");
|
|
9
10
|
const logger_utils_1 = require("./logger.utils");
|
|
10
11
|
const config_service_1 = require("../services/config.service");
|
|
@@ -100,5 +101,20 @@ class WebDavUtils {
|
|
|
100
101
|
}
|
|
101
102
|
await drive_item_repository_1.DriveItemRepository.instance.delete([driveItem.uuid]);
|
|
102
103
|
}
|
|
104
|
+
static generateETag(parts) {
|
|
105
|
+
const normalized = parts.map((part) => part ?? '-');
|
|
106
|
+
const hash = (0, node_crypto_1.createHash)('sha256').update(normalized.join('|')).digest('hex');
|
|
107
|
+
return `"${hash}"`;
|
|
108
|
+
}
|
|
109
|
+
static getItemETag(driveItem) {
|
|
110
|
+
return this.generateETag([
|
|
111
|
+
driveItem.uuid,
|
|
112
|
+
driveItem.itemType === 'file' ? driveItem.size : undefined,
|
|
113
|
+
driveItem.createdAt.getTime(),
|
|
114
|
+
driveItem.updatedAt.getTime(),
|
|
115
|
+
driveItem.creationTime.getTime(),
|
|
116
|
+
driveItem.modificationTime.getTime(),
|
|
117
|
+
]);
|
|
118
|
+
}
|
|
103
119
|
}
|
|
104
120
|
exports.WebDavUtils = WebDavUtils;
|
|
@@ -21,6 +21,7 @@ class GETRequestHandler {
|
|
|
21
21
|
logger_utils_1.webdavLogger.info(`[GET] [${driveFile.uuid}] Network ready for download`);
|
|
22
22
|
res.header('Content-Type', 'application/octet-stream');
|
|
23
23
|
res.header('Accept-Ranges', 'bytes');
|
|
24
|
+
res.header('ETag', webdav_utils_1.WebDavUtils.getItemETag(driveFile));
|
|
24
25
|
const fileSize = driveFile.size ?? 0;
|
|
25
26
|
if (fileSize > 0) {
|
|
26
27
|
const range = req.headers['range'];
|
|
@@ -45,8 +46,8 @@ class GETRequestHandler {
|
|
|
45
46
|
if (!driveFile.fileId) {
|
|
46
47
|
throw new command_types_1.NotValidFileIdError();
|
|
47
48
|
}
|
|
48
|
-
const { networkFacade,
|
|
49
|
-
const [executeDownload] = await networkFacade.downloadToStream(bucket, mnemonic, driveFile.fileId, contentLength, writable, rangeOptions);
|
|
49
|
+
const { networkFacade, mnemonic } = await cli_utils_1.CLIUtils.prepareNetwork(user);
|
|
50
|
+
const [executeDownload] = await networkFacade.downloadToStream(driveFile.bucket, mnemonic, driveFile.fileId, contentLength, writable, rangeOptions);
|
|
50
51
|
logger_utils_1.webdavLogger.info(`[GET] [${driveFile.uuid}] Download prepared, executing...`);
|
|
51
52
|
res.status(200);
|
|
52
53
|
await executeDownload;
|
|
@@ -14,6 +14,7 @@ class HEADRequestHandler {
|
|
|
14
14
|
throw new errors_utils_1.NotFoundError(`Resource not found on Internxt Drive at ${resource.url}`);
|
|
15
15
|
}
|
|
16
16
|
logger_utils_1.webdavLogger.info(`[HEAD] [${driveItem.uuid}] Found Drive item`);
|
|
17
|
+
res.header('ETag', webdav_utils_1.WebDavUtils.getItemETag(driveItem));
|
|
17
18
|
if (driveItem.itemType === 'file') {
|
|
18
19
|
const range = req.headers['range'];
|
|
19
20
|
const rangeOptions = network_utils_1.NetworkUtils.parseRangeHeader({
|
|
@@ -10,7 +10,6 @@ const drive_item_repository_1 = require("../../services/database/drive-item/driv
|
|
|
10
10
|
const drive_folder_service_1 = require("../../services/drive/drive-folder.service");
|
|
11
11
|
const drive_utils_1 = require("../../utils/drive.utils");
|
|
12
12
|
const format_utils_1 = require("../../utils/format.utils");
|
|
13
|
-
const node_crypto_1 = require("node:crypto");
|
|
14
13
|
const mime_types_1 = __importDefault(require("mime-types"));
|
|
15
14
|
const webdav_utils_1 = require("../../utils/webdav.utils");
|
|
16
15
|
const logger_utils_1 = require("../../utils/logger.utils");
|
|
@@ -143,7 +142,7 @@ class PROPFINDRequestHandler {
|
|
|
143
142
|
[xml_utils_1.XMLUtils.addDefaultNamespace('status')]: 'HTTP/1.1 200 OK',
|
|
144
143
|
[xml_utils_1.XMLUtils.addDefaultNamespace('prop')]: {
|
|
145
144
|
[xml_utils_1.XMLUtils.addDefaultNamespace('getcontenttype')]: 'httpd/unix-directory',
|
|
146
|
-
[xml_utils_1.XMLUtils.addDefaultNamespace('getetag')]:
|
|
145
|
+
[xml_utils_1.XMLUtils.addDefaultNamespace('getetag')]: webdav_utils_1.WebDavUtils.getItemETag(driveFolderItem),
|
|
147
146
|
'x1:lastmodified': {
|
|
148
147
|
'#text': format_utils_1.FormatUtils.formatDateForWebDav(driveFolderItem.updatedAt),
|
|
149
148
|
'@_xmlns:x1': 'SAR:',
|
|
@@ -177,7 +176,7 @@ class PROPFINDRequestHandler {
|
|
|
177
176
|
[xml_utils_1.XMLUtils.addDefaultNamespace('getlastmodified')]: format_utils_1.FormatUtils.formatDateForWebDav(driveFolderItem.updatedAt),
|
|
178
177
|
[xml_utils_1.XMLUtils.addDefaultNamespace('getcontentlength')]: 0,
|
|
179
178
|
[xml_utils_1.XMLUtils.addDefaultNamespace('getcontenttype')]: 'httpd/unix-directory',
|
|
180
|
-
[xml_utils_1.XMLUtils.addDefaultNamespace('getetag')]:
|
|
179
|
+
[xml_utils_1.XMLUtils.addDefaultNamespace('getetag')]: webdav_utils_1.WebDavUtils.getItemETag(driveFolderItem),
|
|
181
180
|
[xml_utils_1.XMLUtils.addDefaultNamespace('resourcetype')]: {
|
|
182
181
|
[xml_utils_1.XMLUtils.addDefaultNamespace('collection')]: '',
|
|
183
182
|
},
|
|
@@ -195,7 +194,7 @@ class PROPFINDRequestHandler {
|
|
|
195
194
|
[xml_utils_1.XMLUtils.addDefaultNamespace('status')]: 'HTTP/1.1 200 OK',
|
|
196
195
|
[xml_utils_1.XMLUtils.addDefaultNamespace('prop')]: {
|
|
197
196
|
[xml_utils_1.XMLUtils.addDefaultNamespace('resourcetype')]: '',
|
|
198
|
-
[xml_utils_1.XMLUtils.addDefaultNamespace('getetag')]:
|
|
197
|
+
[xml_utils_1.XMLUtils.addDefaultNamespace('getetag')]: webdav_utils_1.WebDavUtils.getItemETag(driveFileItem),
|
|
199
198
|
[xml_utils_1.XMLUtils.addDefaultNamespace('displayname')]: displayName,
|
|
200
199
|
[xml_utils_1.XMLUtils.addDefaultNamespace('getcontenttype')]: mime_types_1.default.lookup(displayName) || 'application/octet-stream',
|
|
201
200
|
[xml_utils_1.XMLUtils.addDefaultNamespace('getlastmodified')]: lastModified,
|
|
@@ -39,16 +39,10 @@ class PUTRequestHandler {
|
|
|
39
39
|
}
|
|
40
40
|
isReplacement = true;
|
|
41
41
|
logger_utils_1.webdavLogger.info(`[PUT] File '${resource.name}' already exists in '${resource.path.dir}', it will be replaced...`);
|
|
42
|
-
try {
|
|
43
|
-
await webdav_utils_1.WebDavUtils.deleteOrTrashItem(driveFileItem);
|
|
44
|
-
await drive_item_repository_1.DriveItemRepository.instance.delete([driveFileItem.uuid]);
|
|
45
|
-
}
|
|
46
|
-
catch {
|
|
47
|
-
}
|
|
48
42
|
}
|
|
49
43
|
const { user } = await auth_service_1.AuthService.instance.getAuthDetails();
|
|
50
44
|
const fileType = resource.path.ext.replace('.', '');
|
|
51
|
-
const { fileStream, thumbnailStream } = upload_utils_1.UploadUtils.prepareUploadStreams(req, fileType);
|
|
45
|
+
const { fileStream, thumbnailStream } = upload_utils_1.UploadUtils.prepareUploadStreams(req, fileType, contentLength);
|
|
52
46
|
const { networkFacade, bucket } = await cli_utils_1.CLIUtils.prepareNetwork(user);
|
|
53
47
|
let fileId;
|
|
54
48
|
if (contentLength > 0) {
|
|
@@ -79,7 +73,7 @@ class PUTRequestHandler {
|
|
|
79
73
|
logger_utils_1.webdavLogger.info('[PUT] ✅ File uploaded to network');
|
|
80
74
|
}
|
|
81
75
|
const driveTimer = cli_utils_1.CLIUtils.timer();
|
|
82
|
-
const
|
|
76
|
+
const filePayload = {
|
|
83
77
|
plainName: resource.path.name,
|
|
84
78
|
type: fileType,
|
|
85
79
|
size: contentLength,
|
|
@@ -87,7 +81,26 @@ class PUTRequestHandler {
|
|
|
87
81
|
fileId,
|
|
88
82
|
bucket,
|
|
89
83
|
encryptVersion: types_1.EncryptionVersion.Aes03,
|
|
90
|
-
}
|
|
84
|
+
};
|
|
85
|
+
let file;
|
|
86
|
+
if (driveFileItem?.itemType === 'file' && contentLength > 0) {
|
|
87
|
+
try {
|
|
88
|
+
file = await drive_file_service_1.DriveFileService.instance.replaceFile(driveFileItem.uuid, filePayload);
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
logger_utils_1.webdavLogger.warn(`[PUT] File replace failed for '${resource.url}', falling back to delete and create: ${error instanceof Error ? error.message : String(error)}`);
|
|
92
|
+
await webdav_utils_1.WebDavUtils.deleteOrTrashItem(driveFileItem);
|
|
93
|
+
await drive_item_repository_1.DriveItemRepository.instance.delete([driveFileItem.uuid]);
|
|
94
|
+
file = await drive_file_service_1.DriveFileService.instance.createFile(filePayload);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
if (driveFileItem?.itemType === 'file') {
|
|
99
|
+
await webdav_utils_1.WebDavUtils.deleteOrTrashItem(driveFileItem);
|
|
100
|
+
await drive_item_repository_1.DriveItemRepository.instance.delete([driveFileItem.uuid]);
|
|
101
|
+
}
|
|
102
|
+
file = await drive_file_service_1.DriveFileService.instance.createFile(filePayload);
|
|
103
|
+
}
|
|
91
104
|
timings.driveUpload = driveTimer.stop();
|
|
92
105
|
await drive_item_repository_1.DriveItemRepository.instance.createOrUpdate([
|
|
93
106
|
{
|
|
@@ -101,7 +114,7 @@ class PUTRequestHandler {
|
|
|
101
114
|
const thumbnailTimer = cli_utils_1.CLIUtils.timer();
|
|
102
115
|
await thumbnail_service_1.ThumbnailService.instance.tryUploadThumbnail({
|
|
103
116
|
fileUuid: file.uuid,
|
|
104
|
-
|
|
117
|
+
input: thumbnailStream?.getBuffer(),
|
|
105
118
|
fileType,
|
|
106
119
|
bucket,
|
|
107
120
|
networkFacade,
|
|
@@ -115,6 +128,7 @@ class PUTRequestHandler {
|
|
|
115
128
|
const statusCode = isReplacement ? 204 : 201;
|
|
116
129
|
logger_utils_1.webdavLogger.info(`[PUT] [RESPONSE-${statusCode}] ${resource.url} - Returning ${statusCode} ` +
|
|
117
130
|
`after ${cli_utils_1.CLIUtils.formatDuration(totalTime)}`);
|
|
131
|
+
res.header('ETag', webdav_utils_1.WebDavUtils.getItemETag(file));
|
|
118
132
|
res.status(statusCode).send();
|
|
119
133
|
};
|
|
120
134
|
}
|
package/dist/webdav/index.js
CHANGED
|
@@ -18,8 +18,8 @@ const init = async () => {
|
|
|
18
18
|
await config_service_1.ConfigService.instance.ensureInternxtLogsDirExists();
|
|
19
19
|
await database_service_1.DatabaseService.instance.initialize();
|
|
20
20
|
await database_service_1.DatabaseService.instance.clear();
|
|
21
|
-
const { token
|
|
22
|
-
sdk_manager_service_1.SdkManager.init({ token
|
|
21
|
+
const { token } = await auth_service_1.AuthService.instance.getAuthDetails();
|
|
22
|
+
sdk_manager_service_1.SdkManager.init({ token });
|
|
23
23
|
new webdav_server_1.WebDavServer((0, express_1.default)())
|
|
24
24
|
.start()
|
|
25
25
|
.then()
|
|
@@ -13,7 +13,7 @@ const AuthMiddleware = () => {
|
|
|
13
13
|
try {
|
|
14
14
|
const cached = cache_service_1.CacheService.instance.get(cache_service_1.CacheService.AUTH_CACHE_KEY);
|
|
15
15
|
if (cached) {
|
|
16
|
-
sdk_manager_service_1.SdkManager.init({ token: cached.token
|
|
16
|
+
sdk_manager_service_1.SdkManager.init({ token: cached.token });
|
|
17
17
|
next();
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
@@ -4,8 +4,35 @@ exports.ErrorHandlingMiddleware = void 0;
|
|
|
4
4
|
const logger_utils_1 = require("../../utils/logger.utils");
|
|
5
5
|
const xml_utils_1 = require("../../utils/xml.utils");
|
|
6
6
|
const errors_utils_1 = require("../../utils/errors.utils");
|
|
7
|
+
const getErrorDetail = (err) => {
|
|
8
|
+
if (typeof err !== 'object' || err === null || !('data' in err))
|
|
9
|
+
return undefined;
|
|
10
|
+
const data = err.data;
|
|
11
|
+
if (typeof data !== 'object' || data === null || !('message' in data))
|
|
12
|
+
return undefined;
|
|
13
|
+
const message = data.message;
|
|
14
|
+
if (typeof message === 'string' && message.trim().length > 0)
|
|
15
|
+
return message;
|
|
16
|
+
if (Array.isArray(message) && message.length > 0)
|
|
17
|
+
return message.join(', ');
|
|
18
|
+
return undefined;
|
|
19
|
+
};
|
|
20
|
+
const getErrorStatusCode = (err) => {
|
|
21
|
+
if (typeof err !== 'object' || err === null)
|
|
22
|
+
return undefined;
|
|
23
|
+
const { statusCode, status } = err;
|
|
24
|
+
if (typeof statusCode === 'number' && !Number.isNaN(statusCode))
|
|
25
|
+
return statusCode;
|
|
26
|
+
if (typeof status === 'number' && !Number.isNaN(status))
|
|
27
|
+
return status;
|
|
28
|
+
return undefined;
|
|
29
|
+
};
|
|
7
30
|
const ErrorHandlingMiddleware = (err, req, res, _) => {
|
|
8
|
-
|
|
31
|
+
let message = errors_utils_1.ErrorUtils.isError(err) ? err.message : 'Something went wrong';
|
|
32
|
+
const detail = getErrorDetail(err);
|
|
33
|
+
if (detail) {
|
|
34
|
+
message += ` [${detail}]`;
|
|
35
|
+
}
|
|
9
36
|
if (errors_utils_1.ErrorUtils.isError(err) && err.stack) {
|
|
10
37
|
logger_utils_1.webdavLogger.error(`[ERROR MIDDLEWARE] [${req.method.toUpperCase()} - ${req.url}] ${message}\nStack: ${err.stack}`);
|
|
11
38
|
}
|
|
@@ -15,10 +42,7 @@ const ErrorHandlingMiddleware = (err, req, res, _) => {
|
|
|
15
42
|
const errorBodyXML = xml_utils_1.XMLUtils.toWebDavXML({
|
|
16
43
|
[xml_utils_1.XMLUtils.addDefaultNamespace('responsedescription')]: message,
|
|
17
44
|
}, {}, 'error');
|
|
18
|
-
|
|
19
|
-
if ('statusCode' in err && !Number.isNaN(err.statusCode)) {
|
|
20
|
-
statusCode = err.statusCode;
|
|
21
|
-
}
|
|
45
|
+
const statusCode = getErrorStatusCode(err) ?? 500;
|
|
22
46
|
res.set('Content-Type', 'application/xml; charset="utf-8"');
|
|
23
47
|
res.status(statusCode).send(errorBodyXML);
|
|
24
48
|
req.destroy();
|
package/oclif.manifest.json
CHANGED
|
@@ -586,19 +586,6 @@
|
|
|
586
586
|
"allowNo": false,
|
|
587
587
|
"type": "boolean"
|
|
588
588
|
},
|
|
589
|
-
"host": {
|
|
590
|
-
"aliases": [
|
|
591
|
-
"host"
|
|
592
|
-
],
|
|
593
|
-
"char": "h",
|
|
594
|
-
"description": "IP address of the machine where the CLI is running. If you are opening the login page in a browser on another device, set this to the IP address of the machine running the CLI. Defaults to 127.0.0.1.",
|
|
595
|
-
"env": "INXT_LOGIN_SERVER_HOST",
|
|
596
|
-
"name": "host",
|
|
597
|
-
"required": false,
|
|
598
|
-
"hasDynamicHelp": false,
|
|
599
|
-
"multiple": false,
|
|
600
|
-
"type": "option"
|
|
601
|
-
},
|
|
602
589
|
"port": {
|
|
603
590
|
"aliases": [
|
|
604
591
|
"port"
|
|
@@ -1443,6 +1430,14 @@
|
|
|
1443
1430
|
"hasDynamicHelp": false,
|
|
1444
1431
|
"multiple": false,
|
|
1445
1432
|
"type": "option"
|
|
1433
|
+
},
|
|
1434
|
+
"overwrite": {
|
|
1435
|
+
"char": "o",
|
|
1436
|
+
"description": "Overwrite the file if a file with the same name already exists in the cloud destination folder.",
|
|
1437
|
+
"name": "overwrite",
|
|
1438
|
+
"required": false,
|
|
1439
|
+
"allowNo": false,
|
|
1440
|
+
"type": "boolean"
|
|
1446
1441
|
}
|
|
1447
1442
|
},
|
|
1448
1443
|
"hasDynamicHelp": false,
|
|
@@ -1786,191 +1781,7 @@
|
|
|
1786
1781
|
"commands",
|
|
1787
1782
|
"whoami.js"
|
|
1788
1783
|
]
|
|
1789
|
-
},
|
|
1790
|
-
"workspaces-list": {
|
|
1791
|
-
"aliases": [
|
|
1792
|
-
"workspaces:list"
|
|
1793
|
-
],
|
|
1794
|
-
"args": {},
|
|
1795
|
-
"description": "Get the list of workspaces.",
|
|
1796
|
-
"examples": [
|
|
1797
|
-
"<%= config.bin %> <%= command.id %>"
|
|
1798
|
-
],
|
|
1799
|
-
"flags": {
|
|
1800
|
-
"json": {
|
|
1801
|
-
"description": "Format output as json.",
|
|
1802
|
-
"helpGroup": "GLOBAL",
|
|
1803
|
-
"name": "json",
|
|
1804
|
-
"allowNo": false,
|
|
1805
|
-
"type": "boolean"
|
|
1806
|
-
},
|
|
1807
|
-
"non-interactive": {
|
|
1808
|
-
"char": "x",
|
|
1809
|
-
"description": "Prevents the CLI from being interactive. When enabled, the CLI will not request input through the console and will throw errors directly.",
|
|
1810
|
-
"env": "INXT_NONINTERACTIVE",
|
|
1811
|
-
"helpGroup": "helper",
|
|
1812
|
-
"name": "non-interactive",
|
|
1813
|
-
"required": false,
|
|
1814
|
-
"allowNo": false,
|
|
1815
|
-
"type": "boolean"
|
|
1816
|
-
},
|
|
1817
|
-
"debug": {
|
|
1818
|
-
"description": "Enables debug mode. When enabled, the CLI will print debug messages to the console.",
|
|
1819
|
-
"env": "INXT_DEBUG",
|
|
1820
|
-
"helpGroup": "helper",
|
|
1821
|
-
"name": "debug",
|
|
1822
|
-
"required": false,
|
|
1823
|
-
"allowNo": false,
|
|
1824
|
-
"type": "boolean"
|
|
1825
|
-
},
|
|
1826
|
-
"extended": {
|
|
1827
|
-
"char": "e",
|
|
1828
|
-
"description": "Displays additional information in the list.",
|
|
1829
|
-
"name": "extended",
|
|
1830
|
-
"required": false,
|
|
1831
|
-
"allowNo": false,
|
|
1832
|
-
"type": "boolean"
|
|
1833
|
-
}
|
|
1834
|
-
},
|
|
1835
|
-
"hasDynamicHelp": false,
|
|
1836
|
-
"hiddenAliases": [],
|
|
1837
|
-
"id": "workspaces-list",
|
|
1838
|
-
"pluginAlias": "@internxt/cli",
|
|
1839
|
-
"pluginName": "@internxt/cli",
|
|
1840
|
-
"pluginType": "core",
|
|
1841
|
-
"strict": true,
|
|
1842
|
-
"enableJsonFlag": true,
|
|
1843
|
-
"isESM": false,
|
|
1844
|
-
"relativePath": [
|
|
1845
|
-
"dist",
|
|
1846
|
-
"commands",
|
|
1847
|
-
"workspaces-list.js"
|
|
1848
|
-
]
|
|
1849
|
-
},
|
|
1850
|
-
"workspaces-unset": {
|
|
1851
|
-
"aliases": [
|
|
1852
|
-
"workspaces:unset"
|
|
1853
|
-
],
|
|
1854
|
-
"args": {},
|
|
1855
|
-
"description": "Unset the active workspace context for the current user session. Once a workspace is unset, WebDAV and all of the subsequent CLI commands will operate within the personal drive space until it is changed or set again.",
|
|
1856
|
-
"examples": [
|
|
1857
|
-
"<%= config.bin %> <%= command.id %>"
|
|
1858
|
-
],
|
|
1859
|
-
"flags": {
|
|
1860
|
-
"json": {
|
|
1861
|
-
"description": "Format output as json.",
|
|
1862
|
-
"helpGroup": "GLOBAL",
|
|
1863
|
-
"name": "json",
|
|
1864
|
-
"allowNo": false,
|
|
1865
|
-
"type": "boolean"
|
|
1866
|
-
},
|
|
1867
|
-
"non-interactive": {
|
|
1868
|
-
"char": "x",
|
|
1869
|
-
"description": "Prevents the CLI from being interactive. When enabled, the CLI will not request input through the console and will throw errors directly.",
|
|
1870
|
-
"env": "INXT_NONINTERACTIVE",
|
|
1871
|
-
"helpGroup": "helper",
|
|
1872
|
-
"name": "non-interactive",
|
|
1873
|
-
"required": false,
|
|
1874
|
-
"allowNo": false,
|
|
1875
|
-
"type": "boolean"
|
|
1876
|
-
},
|
|
1877
|
-
"debug": {
|
|
1878
|
-
"description": "Enables debug mode. When enabled, the CLI will print debug messages to the console.",
|
|
1879
|
-
"env": "INXT_DEBUG",
|
|
1880
|
-
"helpGroup": "helper",
|
|
1881
|
-
"name": "debug",
|
|
1882
|
-
"required": false,
|
|
1883
|
-
"allowNo": false,
|
|
1884
|
-
"type": "boolean"
|
|
1885
|
-
}
|
|
1886
|
-
},
|
|
1887
|
-
"hasDynamicHelp": false,
|
|
1888
|
-
"hiddenAliases": [],
|
|
1889
|
-
"id": "workspaces-unset",
|
|
1890
|
-
"pluginAlias": "@internxt/cli",
|
|
1891
|
-
"pluginName": "@internxt/cli",
|
|
1892
|
-
"pluginType": "core",
|
|
1893
|
-
"strict": true,
|
|
1894
|
-
"enableJsonFlag": true,
|
|
1895
|
-
"isESM": false,
|
|
1896
|
-
"relativePath": [
|
|
1897
|
-
"dist",
|
|
1898
|
-
"commands",
|
|
1899
|
-
"workspaces-unset.js"
|
|
1900
|
-
]
|
|
1901
|
-
},
|
|
1902
|
-
"workspaces-use": {
|
|
1903
|
-
"aliases": [
|
|
1904
|
-
"workspaces:use"
|
|
1905
|
-
],
|
|
1906
|
-
"args": {},
|
|
1907
|
-
"description": "Set the active workspace context for the current user session. Once a workspace is selected, WebDAV and all of the subsequent CLI commands will operate within that workspace until it is changed or unset.",
|
|
1908
|
-
"examples": [
|
|
1909
|
-
"<%= config.bin %> <%= command.id %>"
|
|
1910
|
-
],
|
|
1911
|
-
"flags": {
|
|
1912
|
-
"json": {
|
|
1913
|
-
"description": "Format output as json.",
|
|
1914
|
-
"helpGroup": "GLOBAL",
|
|
1915
|
-
"name": "json",
|
|
1916
|
-
"allowNo": false,
|
|
1917
|
-
"type": "boolean"
|
|
1918
|
-
},
|
|
1919
|
-
"non-interactive": {
|
|
1920
|
-
"char": "x",
|
|
1921
|
-
"description": "Prevents the CLI from being interactive. When enabled, the CLI will not request input through the console and will throw errors directly.",
|
|
1922
|
-
"env": "INXT_NONINTERACTIVE",
|
|
1923
|
-
"helpGroup": "helper",
|
|
1924
|
-
"name": "non-interactive",
|
|
1925
|
-
"required": false,
|
|
1926
|
-
"allowNo": false,
|
|
1927
|
-
"type": "boolean"
|
|
1928
|
-
},
|
|
1929
|
-
"debug": {
|
|
1930
|
-
"description": "Enables debug mode. When enabled, the CLI will print debug messages to the console.",
|
|
1931
|
-
"env": "INXT_DEBUG",
|
|
1932
|
-
"helpGroup": "helper",
|
|
1933
|
-
"name": "debug",
|
|
1934
|
-
"required": false,
|
|
1935
|
-
"allowNo": false,
|
|
1936
|
-
"type": "boolean"
|
|
1937
|
-
},
|
|
1938
|
-
"id": {
|
|
1939
|
-
"char": "i",
|
|
1940
|
-
"description": "The id of the workspace to activate. Use <%= config.bin %> workspaces list to view your available workspace ids.",
|
|
1941
|
-
"exclusive": [
|
|
1942
|
-
"personal"
|
|
1943
|
-
],
|
|
1944
|
-
"name": "id",
|
|
1945
|
-
"required": false,
|
|
1946
|
-
"hasDynamicHelp": false,
|
|
1947
|
-
"multiple": false,
|
|
1948
|
-
"type": "option"
|
|
1949
|
-
},
|
|
1950
|
-
"personal": {
|
|
1951
|
-
"char": "p",
|
|
1952
|
-
"description": "Change to the personal drive space. It unsets the active workspace context for the current user session.",
|
|
1953
|
-
"name": "personal",
|
|
1954
|
-
"required": false,
|
|
1955
|
-
"allowNo": false,
|
|
1956
|
-
"type": "boolean"
|
|
1957
|
-
}
|
|
1958
|
-
},
|
|
1959
|
-
"hasDynamicHelp": false,
|
|
1960
|
-
"hiddenAliases": [],
|
|
1961
|
-
"id": "workspaces-use",
|
|
1962
|
-
"pluginAlias": "@internxt/cli",
|
|
1963
|
-
"pluginName": "@internxt/cli",
|
|
1964
|
-
"pluginType": "core",
|
|
1965
|
-
"strict": true,
|
|
1966
|
-
"enableJsonFlag": true,
|
|
1967
|
-
"isESM": false,
|
|
1968
|
-
"relativePath": [
|
|
1969
|
-
"dist",
|
|
1970
|
-
"commands",
|
|
1971
|
-
"workspaces-use.js"
|
|
1972
|
-
]
|
|
1973
1784
|
}
|
|
1974
1785
|
},
|
|
1975
|
-
"version": "1.6.
|
|
1786
|
+
"version": "1.6.8"
|
|
1976
1787
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"author": "Internxt <hello@internxt.com>",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.8",
|
|
4
4
|
"description": "Internxt CLI to manage your encrypted storage",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "npm run clean && tsc",
|
|
@@ -38,12 +38,12 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@dashlane/pqc-kem-kyber512-node": "1.0.0",
|
|
40
40
|
"@inquirer/prompts": "8.5.2",
|
|
41
|
-
"@internxt/inxt-js": "3.3.
|
|
42
|
-
"@internxt/lib": "1.5.
|
|
43
|
-
"@internxt/sdk": "1.
|
|
44
|
-
"@oclif/core": "4.
|
|
45
|
-
"@oclif/plugin-autocomplete": "3.2.
|
|
46
|
-
"axios": "1.
|
|
41
|
+
"@internxt/inxt-js": "3.3.5",
|
|
42
|
+
"@internxt/lib": "1.5.2",
|
|
43
|
+
"@internxt/sdk": "1.20.1",
|
|
44
|
+
"@oclif/core": "4.13.3",
|
|
45
|
+
"@oclif/plugin-autocomplete": "3.2.56",
|
|
46
|
+
"axios": "1.19.0",
|
|
47
47
|
"better-sqlite3": "12.11.1",
|
|
48
48
|
"bip39": "3.1.0",
|
|
49
49
|
"body-parser": "2.3.0",
|
|
@@ -52,18 +52,19 @@
|
|
|
52
52
|
"dotenv": "17.4.2",
|
|
53
53
|
"express": "5.2.1",
|
|
54
54
|
"express-async-handler": "1.2.0",
|
|
55
|
-
"fast-xml-builder": "1.
|
|
56
|
-
"fast-xml-parser": "5.
|
|
55
|
+
"fast-xml-builder": "1.3.1",
|
|
56
|
+
"fast-xml-parser": "5.10.1",
|
|
57
57
|
"hash-wasm": "4.12.0",
|
|
58
58
|
"mime-types": "3.0.2",
|
|
59
|
-
"open": "11.0.
|
|
59
|
+
"open": "11.0.1",
|
|
60
60
|
"openpgp": "6.3.1",
|
|
61
61
|
"otpauth": "9.5.1",
|
|
62
62
|
"pm2": "7.0.3",
|
|
63
63
|
"range-parser": "1.3.0",
|
|
64
64
|
"selfsigned": "5.5.0",
|
|
65
65
|
"tty-table": "5.0.0",
|
|
66
|
-
"typeorm": "1.
|
|
66
|
+
"typeorm": "1.1.0",
|
|
67
|
+
"uuid": "14.0.1",
|
|
67
68
|
"winston": "3.19.0"
|
|
68
69
|
},
|
|
69
70
|
"devDependencies": {
|
|
@@ -73,16 +74,16 @@
|
|
|
73
74
|
"@types/cli-progress": "^3.11.6",
|
|
74
75
|
"@types/express": "^5.0.6",
|
|
75
76
|
"@types/mime-types": "^3.0.1",
|
|
76
|
-
"@types/node": "^26.
|
|
77
|
+
"@types/node": "^26.2.0",
|
|
77
78
|
"@types/range-parser": "^1.2.7",
|
|
78
79
|
"@vitest/coverage-istanbul": "^4.1.10",
|
|
79
80
|
"@vitest/spy": "^4.1.10",
|
|
80
|
-
"eslint": "^10.
|
|
81
|
+
"eslint": "^10.8.1",
|
|
81
82
|
"husky": "^9.1.7",
|
|
82
|
-
"lint-staged": "^17.0
|
|
83
|
+
"lint-staged": "^17.3.0",
|
|
83
84
|
"nodemon": "^3.1.14",
|
|
84
|
-
"oclif": "^4.23.
|
|
85
|
-
"prettier": "^3.9.
|
|
85
|
+
"oclif": "^4.23.30",
|
|
86
|
+
"prettier": "^3.9.6",
|
|
86
87
|
"rimraf": "^6.1.3",
|
|
87
88
|
"sql.js": "^1.14.1",
|
|
88
89
|
"ts-node": "^10.9.2",
|
|
@@ -91,7 +92,7 @@
|
|
|
91
92
|
"vitest-mock-express": "^2.2.0"
|
|
92
93
|
},
|
|
93
94
|
"optionalDependencies": {
|
|
94
|
-
"sharp": "0.35.
|
|
95
|
+
"sharp": "0.35.3"
|
|
95
96
|
},
|
|
96
97
|
"engines": {
|
|
97
98
|
"node": "^22.13.0 || >=24.11.0"
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { Command } from '@oclif/core';
|
|
2
|
-
export default class WorkspacesList extends Command {
|
|
3
|
-
static readonly args: {};
|
|
4
|
-
static readonly description = "Get the list of workspaces.";
|
|
5
|
-
static readonly aliases: string[];
|
|
6
|
-
static readonly examples: string[];
|
|
7
|
-
static readonly flags: {
|
|
8
|
-
extended: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
|
-
'non-interactive': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
-
debug: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
-
};
|
|
12
|
-
static readonly enableJsonFlag = true;
|
|
13
|
-
run: () => Promise<{
|
|
14
|
-
success: boolean;
|
|
15
|
-
list: {
|
|
16
|
-
workspaces: import("@internxt/sdk/dist/workspaces").WorkspaceData[];
|
|
17
|
-
};
|
|
18
|
-
}>;
|
|
19
|
-
catch: (error: Error) => Promise<never>;
|
|
20
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const core_1 = require("@oclif/core");
|
|
4
|
-
const config_service_1 = require("../services/config.service");
|
|
5
|
-
const cli_utils_1 = require("../utils/cli.utils");
|
|
6
|
-
const command_types_1 = require("../types/command.types");
|
|
7
|
-
const workspace_service_1 = require("../services/drive/workspace.service");
|
|
8
|
-
const format_utils_1 = require("../utils/format.utils");
|
|
9
|
-
class WorkspacesList extends core_1.Command {
|
|
10
|
-
static args = {};
|
|
11
|
-
static description = 'Get the list of workspaces.';
|
|
12
|
-
static aliases = ['workspaces:list'];
|
|
13
|
-
static examples = ['<%= config.bin %> <%= command.id %>'];
|
|
14
|
-
static flags = {
|
|
15
|
-
...cli_utils_1.CLIUtils.CommonFlags,
|
|
16
|
-
extended: core_1.Flags.boolean({
|
|
17
|
-
char: 'e',
|
|
18
|
-
description: 'Displays additional information in the list.',
|
|
19
|
-
required: false,
|
|
20
|
-
}),
|
|
21
|
-
};
|
|
22
|
-
static enableJsonFlag = true;
|
|
23
|
-
run = async () => {
|
|
24
|
-
const { flags } = await this.parse(WorkspacesList);
|
|
25
|
-
const userCredentials = await config_service_1.ConfigService.instance.readUser();
|
|
26
|
-
if (!userCredentials)
|
|
27
|
-
throw new command_types_1.MissingCredentialsError();
|
|
28
|
-
const workspaces = await workspace_service_1.WorkspaceService.instance.getAvailableWorkspaces(userCredentials.user);
|
|
29
|
-
const allItems = workspaces.map((workspaceData) => {
|
|
30
|
-
const totalUsedSpace = Number(workspaceData.workspaceUser?.driveUsage ?? 0) + Number(workspaceData.workspaceUser?.backupsUsage ?? 0);
|
|
31
|
-
const spaceLimit = Number(workspaceData.workspaceUser?.spaceLimit ?? 0);
|
|
32
|
-
const usedSpace = format_utils_1.FormatUtils.humanFileSize(totalUsedSpace);
|
|
33
|
-
const availableSpace = format_utils_1.FormatUtils.formatLimit(spaceLimit);
|
|
34
|
-
return {
|
|
35
|
-
name: workspaceData.workspace.name,
|
|
36
|
-
id: workspaceData.workspace.id,
|
|
37
|
-
usedSpace,
|
|
38
|
-
availableSpace,
|
|
39
|
-
owner: workspaceData.workspace.ownerId,
|
|
40
|
-
address: workspaceData.workspace.address,
|
|
41
|
-
created: format_utils_1.FormatUtils.formatDate(workspaceData.workspace.createdAt),
|
|
42
|
-
};
|
|
43
|
-
});
|
|
44
|
-
const headers = [
|
|
45
|
-
{ value: 'name', alias: 'Name' },
|
|
46
|
-
{ value: 'id', alias: 'Workspace ID' },
|
|
47
|
-
{ value: 'usedSpace', alias: 'Used space' },
|
|
48
|
-
{ value: 'availableSpace', alias: 'Available space' },
|
|
49
|
-
];
|
|
50
|
-
if (flags.extended) {
|
|
51
|
-
headers.push({ value: 'owner', alias: 'Owner ID' }, { value: 'address', alias: 'Address' }, { value: 'created', alias: 'Created at' });
|
|
52
|
-
}
|
|
53
|
-
cli_utils_1.CLIUtils.table(this.log.bind(this), headers, allItems);
|
|
54
|
-
return { success: true, list: { workspaces } };
|
|
55
|
-
};
|
|
56
|
-
catch = async (error) => {
|
|
57
|
-
const { flags } = await this.parse(WorkspacesList);
|
|
58
|
-
cli_utils_1.CLIUtils.catchError({
|
|
59
|
-
error,
|
|
60
|
-
command: this.id,
|
|
61
|
-
logReporter: this.log.bind(this),
|
|
62
|
-
jsonFlag: flags['json'],
|
|
63
|
-
debugMode: flags['debug'],
|
|
64
|
-
});
|
|
65
|
-
this.exit(1);
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
exports.default = WorkspacesList;
|