@internxt/cli 1.6.2 → 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.
Files changed (150) hide show
  1. package/README.md +410 -71
  2. package/dist/commands/add-cert.d.ts +1 -1
  3. package/dist/commands/add-cert.js +1 -1
  4. package/dist/commands/config.d.ts +7 -1
  5. package/dist/commands/config.js +36 -5
  6. package/dist/commands/create-folder.d.ts +2 -1
  7. package/dist/commands/create-folder.js +10 -7
  8. package/dist/commands/delete-permanently-file.d.ts +1 -0
  9. package/dist/commands/delete-permanently-folder.d.ts +1 -0
  10. package/dist/commands/download-file.d.ts +1 -0
  11. package/dist/commands/download-file.js +4 -2
  12. package/dist/commands/list.d.ts +1 -0
  13. package/dist/commands/list.js +2 -4
  14. package/dist/commands/login-legacy.d.ts +1 -0
  15. package/dist/commands/move-file.d.ts +1 -1
  16. package/dist/commands/move-file.js +7 -21
  17. package/dist/commands/move-folder.d.ts +1 -1
  18. package/dist/commands/move-folder.js +7 -21
  19. package/dist/commands/rename-file.d.ts +1 -0
  20. package/dist/commands/rename-folder.d.ts +1 -0
  21. package/dist/commands/trash-clear.d.ts +1 -0
  22. package/dist/commands/trash-file.d.ts +1 -0
  23. package/dist/commands/trash-folder.d.ts +1 -0
  24. package/dist/commands/trash-restore-file.d.ts +1 -1
  25. package/dist/commands/trash-restore-file.js +7 -21
  26. package/dist/commands/trash-restore-folder.d.ts +1 -1
  27. package/dist/commands/trash-restore-folder.js +7 -21
  28. package/dist/commands/upload-file.d.ts +4 -5
  29. package/dist/commands/upload-file.js +32 -21
  30. package/dist/commands/upload-folder.d.ts +1 -0
  31. package/dist/commands/upload-folder.js +11 -6
  32. package/dist/commands/webdav-config.d.ts +19 -1
  33. package/dist/commands/webdav-config.js +81 -3
  34. package/dist/commands/webdav.d.ts +1 -1
  35. package/dist/commands/webdav.js +10 -5
  36. package/dist/commands/whoami.js +2 -1
  37. package/dist/commands/workspaces-list.d.ts +20 -0
  38. package/dist/commands/workspaces-list.js +67 -0
  39. package/dist/commands/workspaces-unset.d.ts +23 -0
  40. package/dist/commands/workspaces-unset.js +45 -0
  41. package/dist/commands/workspaces-use.d.ts +27 -0
  42. package/dist/commands/workspaces-use.js +113 -0
  43. package/dist/constants/configs.d.ts +2 -1
  44. package/dist/constants/configs.js +4 -3
  45. package/dist/hooks/prerun/auth_check.js +13 -4
  46. package/dist/services/auth.service.d.ts +5 -2
  47. package/dist/services/auth.service.js +69 -12
  48. package/dist/services/config.service.d.ts +1 -1
  49. package/dist/services/config.service.js +12 -4
  50. package/dist/services/crypto.service.d.ts +5 -0
  51. package/dist/services/crypto.service.js +43 -0
  52. package/dist/services/database/database.service.d.ts +9 -0
  53. package/dist/services/database/database.service.js +39 -0
  54. package/dist/services/database/drive-file/drive-file.attributes.d.ts +3 -6
  55. package/dist/services/database/drive-file/drive-file.domain.d.ts +3 -6
  56. package/dist/services/database/drive-file/drive-file.domain.js +1 -12
  57. package/dist/services/database/drive-file/drive-file.model.d.ts +15 -0
  58. package/dist/services/database/drive-file/drive-file.model.js +67 -0
  59. package/dist/services/database/drive-file/drive-file.repository.d.ts +11 -0
  60. package/dist/services/database/drive-file/drive-file.repository.js +63 -0
  61. package/dist/services/database/drive-folder/drive-folder.attributes.d.ts +3 -4
  62. package/dist/services/database/drive-folder/drive-folder.domain.d.ts +4 -5
  63. package/dist/services/database/drive-folder/drive-folder.domain.js +11 -15
  64. package/dist/services/database/drive-folder/drive-folder.model.d.ts +11 -0
  65. package/dist/services/database/drive-folder/drive-folder.model.js +51 -0
  66. package/dist/services/database/drive-folder/drive-folder.repository.d.ts +13 -0
  67. package/dist/services/database/drive-folder/drive-folder.repository.js +99 -0
  68. package/dist/services/drive/drive-file.service.d.ts +2 -0
  69. package/dist/services/drive/drive-file.service.js +71 -15
  70. package/dist/services/drive/drive-folder.service.d.ts +6 -1
  71. package/dist/services/drive/drive-folder.service.js +157 -31
  72. package/dist/services/drive/trash.service.d.ts +3 -0
  73. package/dist/services/drive/trash.service.js +52 -16
  74. package/dist/services/drive/workspace.service.d.ts +7 -0
  75. package/dist/services/drive/workspace.service.js +30 -0
  76. package/dist/services/keys.service.d.ts +7 -0
  77. package/dist/services/keys.service.js +55 -0
  78. package/dist/services/local-filesystem/local-filesystem.service.d.ts +2 -2
  79. package/dist/services/local-filesystem/local-filesystem.service.js +4 -4
  80. package/dist/services/network/download.service.d.ts +2 -2
  81. package/dist/services/network/download.service.js +2 -2
  82. package/dist/services/network/network-facade.service.d.ts +3 -7
  83. package/dist/services/network/network-facade.service.js +9 -11
  84. package/dist/services/network/upload/upload-facade.service.d.ts +1 -1
  85. package/dist/services/network/upload/upload-facade.service.js +14 -7
  86. package/dist/services/network/upload/upload-file.service.d.ts +3 -3
  87. package/dist/services/network/upload/upload-file.service.js +33 -23
  88. package/dist/services/network/upload/upload-folder.service.d.ts +2 -2
  89. package/dist/services/network/upload/upload-folder.service.js +15 -10
  90. package/dist/services/network/upload/upload.types.d.ts +11 -0
  91. package/dist/services/sdk-manager.service.d.ts +9 -7
  92. package/dist/services/sdk-manager.service.js +27 -13
  93. package/dist/services/thumbnail.service.d.ts +19 -1
  94. package/dist/services/thumbnail.service.js +29 -2
  95. package/dist/services/universal-link.service.d.ts +3 -1
  96. package/dist/services/universal-link.service.js +15 -3
  97. package/dist/services/usage.service.d.ts +1 -2
  98. package/dist/services/usage.service.js +1 -1
  99. package/dist/services/validation.service.js +14 -4
  100. package/dist/{webdav/services → services/webdav}/webdav-folder.service.d.ts +1 -7
  101. package/dist/{webdav/services → services/webdav}/webdav-folder.service.js +6 -10
  102. package/dist/types/command.types.d.ts +44 -1
  103. package/dist/types/command.types.js +29 -1
  104. package/dist/types/config.types.d.ts +1 -0
  105. package/dist/types/drive.types.d.ts +7 -6
  106. package/dist/types/network.types.d.ts +6 -0
  107. package/dist/utils/async.utils.d.ts +2 -1
  108. package/dist/utils/async.utils.js +13 -2
  109. package/dist/utils/cli.utils.d.ts +20 -15
  110. package/dist/utils/cli.utils.js +48 -18
  111. package/dist/utils/crypto.utils.d.ts +3 -1
  112. package/dist/utils/crypto.utils.js +15 -2
  113. package/dist/utils/database.utils.d.ts +11 -0
  114. package/dist/utils/database.utils.js +26 -0
  115. package/dist/utils/drive.utils.js +7 -10
  116. package/dist/utils/errors.utils.d.ts +4 -4
  117. package/dist/utils/errors.utils.js +16 -19
  118. package/dist/utils/format.utils.d.ts +1 -0
  119. package/dist/utils/format.utils.js +3 -0
  120. package/dist/utils/inquirer.utils.js +10 -1
  121. package/dist/utils/path.utils.d.ts +7 -0
  122. package/dist/utils/path.utils.js +18 -0
  123. package/dist/utils/thumbnail.utils.d.ts +6 -20
  124. package/dist/utils/thumbnail.utils.js +16 -41
  125. package/dist/utils/webdav.utils.d.ts +4 -20
  126. package/dist/utils/webdav.utils.js +12 -14
  127. package/dist/webdav/handlers/DELETE.handler.d.ts +0 -9
  128. package/dist/webdav/handlers/DELETE.handler.js +18 -16
  129. package/dist/webdav/handlers/GET.handler.d.ts +0 -13
  130. package/dist/webdav/handlers/GET.handler.js +6 -11
  131. package/dist/webdav/handlers/HEAD.handler.d.ts +0 -5
  132. package/dist/webdav/handlers/HEAD.handler.js +11 -23
  133. package/dist/webdav/handlers/MKCOL.handler.d.ts +0 -7
  134. package/dist/webdav/handlers/MKCOL.handler.js +5 -12
  135. package/dist/webdav/handlers/MOVE.handler.d.ts +0 -9
  136. package/dist/webdav/handlers/MOVE.handler.js +10 -16
  137. package/dist/webdav/handlers/PROPFIND.handler.d.ts +0 -7
  138. package/dist/webdav/handlers/PROPFIND.handler.js +7 -19
  139. package/dist/webdav/handlers/PUT.handler.d.ts +0 -15
  140. package/dist/webdav/handlers/PUT.handler.js +24 -26
  141. package/dist/webdav/index.js +6 -8
  142. package/dist/webdav/middewares/auth.middleware.d.ts +1 -2
  143. package/dist/webdav/middewares/auth.middleware.js +5 -4
  144. package/dist/webdav/middewares/errors.middleware.js +2 -2
  145. package/dist/webdav/middewares/webdav-auth.middleware.d.ts +3 -0
  146. package/dist/webdav/middewares/webdav-auth.middleware.js +44 -0
  147. package/dist/webdav/webdav-server.d.ts +3 -16
  148. package/dist/webdav/webdav-server.js +29 -87
  149. package/oclif.manifest.json +429 -6
  150. package/package.json +25 -20
@@ -3,18 +3,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.UploadFacade = void 0;
4
4
  const node_path_1 = require("node:path");
5
5
  const cli_utils_1 = require("../../../utils/cli.utils");
6
- const logger_utils_1 = require("../../../utils/logger.utils");
7
6
  const local_filesystem_service_1 = require("../../local-filesystem/local-filesystem.service");
8
7
  const upload_folder_service_1 = require("./upload-folder.service");
9
8
  const upload_file_service_1 = require("./upload-file.service");
10
9
  const async_utils_1 = require("../../../utils/async.utils");
11
10
  class UploadFacade {
12
11
  static instance = new UploadFacade();
13
- async uploadFolder({ localPath, destinationFolderUuid, loginUserDetails, jsonFlag, onProgress }) {
12
+ uploadFolder = async ({ localPath, destinationFolderUuid, loginUserDetails, jsonFlag, debugMode, onProgress, reporter, }) => {
14
13
  const timer = cli_utils_1.CLIUtils.timer();
15
- const network = cli_utils_1.CLIUtils.prepareNetwork({ jsonFlag, loginUserDetails });
14
+ cli_utils_1.CLIUtils.doing('Preparing Network', jsonFlag);
15
+ const { networkFacade, bucket } = await cli_utils_1.CLIUtils.prepareNetwork(loginUserDetails);
16
+ cli_utils_1.CLIUtils.done(jsonFlag);
16
17
  const scanResult = await local_filesystem_service_1.LocalFilesystemService.instance.scanLocalDirectory(localPath);
17
- logger_utils_1.logger.info(`Scanned folder ${localPath}: found ${scanResult.totalItems} items, total size ${scanResult.totalBytes} bytes.`);
18
+ if (debugMode) {
19
+ cli_utils_1.CLIUtils.success(reporter, `Scanned folder ${localPath}: found ${scanResult.totalItems} items, total size ${scanResult.totalBytes} bytes.`);
20
+ }
18
21
  const currentProgress = { itemsUploaded: 0, bytesUploaded: 0 };
19
22
  const emitProgress = () => {
20
23
  const itemProgress = currentProgress.itemsUploaded / scanResult.totalItems;
@@ -27,19 +30,23 @@ class UploadFacade {
27
30
  destinationFolderUuid,
28
31
  currentProgress,
29
32
  emitProgress,
33
+ reporter,
34
+ debugMode,
30
35
  });
31
36
  if (folderMap.size === 0) {
32
37
  throw new Error('Failed to create folders, cannot upload files');
33
38
  }
34
39
  await async_utils_1.AsyncUtils.sleep(500);
35
40
  const totalBytes = await upload_file_service_1.UploadFileService.instance.uploadFilesConcurrently({
36
- network,
41
+ network: networkFacade,
37
42
  filesToUpload: scanResult.files,
38
43
  folderMap,
39
- bucket: loginUserDetails.bucket,
44
+ bucket,
40
45
  destinationFolderUuid,
41
46
  currentProgress,
42
47
  emitProgress,
48
+ debugMode,
49
+ reporter,
43
50
  });
44
51
  const rootFolderName = (0, node_path_1.basename)(localPath);
45
52
  const rootFolderId = folderMap.get(rootFolderName) ?? '';
@@ -48,6 +55,6 @@ class UploadFacade {
48
55
  rootFolderId,
49
56
  uploadTimeMs: timer.stop(),
50
57
  };
51
- }
58
+ };
52
59
  }
53
60
  exports.UploadFacade = UploadFacade;
@@ -2,7 +2,7 @@ import { UploadFilesConcurrentlyParams, UploadFileWithRetryParams } from './uplo
2
2
  import { DriveFileItem } from '../../../types/drive.types';
3
3
  export declare class UploadFileService {
4
4
  static readonly instance: UploadFileService;
5
- uploadFilesConcurrently({ network, filesToUpload, folderMap, bucket, destinationFolderUuid, currentProgress, emitProgress, }: UploadFilesConcurrentlyParams): Promise<number>;
6
- uploadFileWithRetry({ file, network, bucket, parentFolderUuid, }: UploadFileWithRetryParams): Promise<DriveFileItem | null>;
7
- private concurrencyArray;
5
+ uploadFilesConcurrently: ({ network, filesToUpload, folderMap, bucket, destinationFolderUuid, currentProgress, emitProgress, debugMode, reporter, }: UploadFilesConcurrentlyParams) => Promise<number>;
6
+ uploadFileWithRetry: ({ file, network, bucket, parentFolderUuid, debugMode, reporter, }: UploadFileWithRetryParams) => Promise<DriveFileItem | null>;
7
+ private readonly concurrencyArray;
8
8
  }
@@ -8,11 +8,11 @@ const node_path_1 = require("node:path");
8
8
  const errors_utils_1 = require("../../../utils/errors.utils");
9
9
  const promises_1 = require("node:fs/promises");
10
10
  const types_1 = require("@internxt/sdk/dist/drive/storage/types");
11
- const thumbnail_utils_1 = require("../../../utils/thumbnail.utils");
12
11
  const cli_utils_1 = require("../../../utils/cli.utils");
12
+ const thumbnail_service_1 = require("../../thumbnail.service");
13
13
  class UploadFileService {
14
14
  static instance = new UploadFileService();
15
- async uploadFilesConcurrently({ network, filesToUpload, folderMap, bucket, destinationFolderUuid, currentProgress, emitProgress, }) {
15
+ uploadFilesConcurrently = async ({ network, filesToUpload, folderMap, bucket, destinationFolderUuid, currentProgress, emitProgress, debugMode, reporter, }) => {
16
16
  let bytesUploaded = 0;
17
17
  const concurrentFiles = this.concurrencyArray(filesToUpload, upload_types_1.MAX_CONCURRENT_UPLOADS);
18
18
  for (const fileArray of concurrentFiles) {
@@ -20,7 +20,9 @@ class UploadFileService {
20
20
  const parentPath = (0, node_path_1.dirname)(file.relativePath);
21
21
  const parentFolderUuid = parentPath === '.' || parentPath === '' ? destinationFolderUuid : folderMap.get(parentPath);
22
22
  if (!parentFolderUuid) {
23
- logger_utils_1.logger.warn(`Parent folder not found for ${file.relativePath}, skipping...`);
23
+ if (debugMode) {
24
+ cli_utils_1.CLIUtils.warning(reporter, `Parent folder not found for ${file.relativePath}, skipping...`);
25
+ }
24
26
  return null;
25
27
  }
26
28
  const createdFileUuid = await this.uploadFileWithRetry({
@@ -28,6 +30,8 @@ class UploadFileService {
28
30
  network,
29
31
  bucket,
30
32
  parentFolderUuid,
33
+ debugMode,
34
+ reporter,
31
35
  });
32
36
  if (createdFileUuid) {
33
37
  bytesUploaded += file.size;
@@ -38,8 +42,8 @@ class UploadFileService {
38
42
  }));
39
43
  }
40
44
  return bytesUploaded;
41
- }
42
- async uploadFileWithRetry({ file, network, bucket, parentFolderUuid, }) {
45
+ };
46
+ uploadFileWithRetry = async ({ file, network, bucket, parentFolderUuid, debugMode, reporter, }) => {
43
47
  for (let attempt = 0; attempt <= upload_types_1.MAX_RETRIES; attempt++) {
44
48
  try {
45
49
  const stats = await (0, promises_1.stat)(file.absolutePath);
@@ -53,7 +57,7 @@ class UploadFileService {
53
57
  thumbnailUpload: 0,
54
58
  };
55
59
  if (fileSize > 0) {
56
- const { fileStream, bufferStream } = (0, thumbnail_utils_1.createFileStreamWithBuffer)({
60
+ const { fileStream, bufferStream } = thumbnail_service_1.ThumbnailService.instance.createFileStreamWithBuffer({
57
61
  path: file.absolutePath,
58
62
  fileType,
59
63
  });
@@ -84,51 +88,57 @@ class UploadFileService {
84
88
  timings.driveUpload = driveTimer.stop();
85
89
  const thumbnailTimer = cli_utils_1.CLIUtils.timer();
86
90
  if (thumbnailStream && fileSize > 0) {
87
- void (0, thumbnail_utils_1.tryUploadThumbnail)({
91
+ await thumbnail_service_1.ThumbnailService.instance.tryUploadThumbnail({
88
92
  bufferStream: thumbnailStream,
89
93
  fileType,
90
- userBucket: bucket,
94
+ bucket,
91
95
  fileUuid: createdDriveFile.uuid,
92
96
  networkFacade: network,
97
+ size: fileSize,
93
98
  });
94
99
  }
95
100
  timings.thumbnailUpload = thumbnailTimer.stop();
96
- const totalTime = Object.values(timings).reduce((sum, time) => sum + time, 0);
97
- const throughputMBps = cli_utils_1.CLIUtils.calculateThroughputMBps(stats.size, timings.networkUpload);
98
- logger_utils_1.logger.info(`Uploaded '${file.name}' (${cli_utils_1.CLIUtils.formatBytesToString(stats.size)})`);
99
- logger_utils_1.logger.info(`Timing breakdown:\n
100
- Network upload: ${cli_utils_1.CLIUtils.formatDuration(timings.networkUpload)} (${throughputMBps.toFixed(2)} MB/s)\n
101
- Drive upload: ${cli_utils_1.CLIUtils.formatDuration(timings.driveUpload)}\n
102
- Thumbnail: ${cli_utils_1.CLIUtils.formatDuration(timings.thumbnailUpload)}\n
103
- Total: ${cli_utils_1.CLIUtils.formatDuration(totalTime)}\n`);
101
+ if (debugMode) {
102
+ const totalTime = Object.values(timings).reduce((sum, time) => sum + time, 0);
103
+ const throughputMBps = cli_utils_1.CLIUtils.calculateThroughputMBps(stats.size, timings.networkUpload);
104
+ cli_utils_1.CLIUtils.success(reporter, `Uploaded '${file.name}' (${cli_utils_1.CLIUtils.formatBytesToString(stats.size)})`);
105
+ cli_utils_1.CLIUtils.log(reporter, 'Timing breakdown:\n' +
106
+ `Network upload: ${cli_utils_1.CLIUtils.formatDuration(timings.networkUpload)}` +
107
+ ` (${throughputMBps.toFixed(2)} MB/s)\n` +
108
+ `Drive upload: ${cli_utils_1.CLIUtils.formatDuration(timings.driveUpload)}\n` +
109
+ `Thumbnail: ${cli_utils_1.CLIUtils.formatDuration(timings.thumbnailUpload)}\n` +
110
+ `Total: ${cli_utils_1.CLIUtils.formatDuration(totalTime)}\n`);
111
+ }
104
112
  return createdDriveFile;
105
113
  }
106
114
  catch (error) {
107
- if ((0, errors_utils_1.isAlreadyExistsError)(error)) {
115
+ if (errors_utils_1.ErrorUtils.isAlreadyExistsError(error)) {
108
116
  const msg = `File ${file.name} already exists, skipping...`;
109
117
  logger_utils_1.logger.info(msg);
110
118
  return null;
111
119
  }
112
120
  if (attempt < upload_types_1.MAX_RETRIES) {
113
121
  const delay = upload_types_1.DELAYS_MS[attempt];
114
- const retryMsg = `Failed to upload file ${file.name}, retrying in ${delay}ms...`;
115
- logger_utils_1.logger.warn(`${retryMsg} (attempt ${attempt + 1}/${upload_types_1.MAX_RETRIES + 1})`);
122
+ if (debugMode) {
123
+ const retryMsg = `Failed to upload file ${file.name}, retrying in ${delay}ms...`;
124
+ cli_utils_1.CLIUtils.warning(reporter, `${retryMsg} (attempt ${attempt + 1}/${upload_types_1.MAX_RETRIES + 1})`);
125
+ }
116
126
  await new Promise((resolve) => setTimeout(resolve, delay));
117
127
  }
118
128
  else {
119
- logger_utils_1.logger.error(`Failed to upload file ${file.name} after ${upload_types_1.MAX_RETRIES + 1} attempts`);
129
+ cli_utils_1.CLIUtils.error(reporter, `Failed to upload file '${file.name}' after ${upload_types_1.MAX_RETRIES + 1} attempts`);
120
130
  return null;
121
131
  }
122
132
  }
123
133
  }
124
134
  return null;
125
- }
126
- concurrencyArray(array, arraySize) {
135
+ };
136
+ concurrencyArray = (array, arraySize) => {
127
137
  const arrays = [];
128
138
  for (let i = 0; i < array.length; i += arraySize) {
129
139
  arrays.push(array.slice(i, i + arraySize));
130
140
  }
131
141
  return arrays;
132
- }
142
+ };
133
143
  }
134
144
  exports.UploadFileService = UploadFileService;
@@ -1,6 +1,6 @@
1
1
  import { CreateFoldersParams, CreateFolderWithRetryParams } from './upload.types';
2
2
  export declare class UploadFolderService {
3
3
  static readonly instance: UploadFolderService;
4
- createFolders({ foldersToCreate, destinationFolderUuid, currentProgress, emitProgress, }: CreateFoldersParams): Promise<Map<string, string>>;
5
- createFolderWithRetry({ folderName, parentFolderUuid }: CreateFolderWithRetryParams): Promise<string | null>;
4
+ createFolders: ({ foldersToCreate, destinationFolderUuid, currentProgress, emitProgress, debugMode, reporter, }: CreateFoldersParams) => Promise<Map<string, string>>;
5
+ createFolderWithRetry: ({ folderName, parentFolderUuid, debugMode, reporter, }: CreateFolderWithRetryParams) => Promise<string | null>;
6
6
  }
@@ -6,9 +6,10 @@ const errors_utils_1 = require("../../../utils/errors.utils");
6
6
  const logger_utils_1 = require("../../../utils/logger.utils");
7
7
  const drive_folder_service_1 = require("../../drive/drive-folder.service");
8
8
  const upload_types_1 = require("./upload.types");
9
+ const cli_utils_1 = require("../../../utils/cli.utils");
9
10
  class UploadFolderService {
10
11
  static instance = new UploadFolderService();
11
- async createFolders({ foldersToCreate, destinationFolderUuid, currentProgress, emitProgress, }) {
12
+ createFolders = async ({ foldersToCreate, destinationFolderUuid, currentProgress, emitProgress, debugMode, reporter, }) => {
12
13
  const folderMap = new Map();
13
14
  for (const folder of foldersToCreate) {
14
15
  const parentPath = (0, node_path_1.dirname)(folder.relativePath);
@@ -20,6 +21,8 @@ class UploadFolderService {
20
21
  const createdFolderUuid = await this.createFolderWithRetry({
21
22
  folderName: folder.name,
22
23
  parentFolderUuid: parentUuid,
24
+ debugMode,
25
+ reporter,
23
26
  });
24
27
  if (createdFolderUuid) {
25
28
  folderMap.set(folder.relativePath, createdFolderUuid);
@@ -28,11 +31,11 @@ class UploadFolderService {
28
31
  }
29
32
  }
30
33
  return folderMap;
31
- }
32
- async createFolderWithRetry({ folderName, parentFolderUuid }) {
34
+ };
35
+ createFolderWithRetry = async ({ folderName, parentFolderUuid, debugMode, reporter, }) => {
33
36
  for (let attempt = 0; attempt <= upload_types_1.MAX_RETRIES; attempt++) {
34
37
  try {
35
- const [createFolderPromise] = drive_folder_service_1.DriveFolderService.instance.createFolder({
38
+ const [createFolderPromise] = await drive_folder_service_1.DriveFolderService.instance.createFolder({
36
39
  plainName: folderName,
37
40
  parentFolderUuid,
38
41
  });
@@ -40,23 +43,25 @@ class UploadFolderService {
40
43
  return createdFolder.uuid;
41
44
  }
42
45
  catch (error) {
43
- if ((0, errors_utils_1.isAlreadyExistsError)(error)) {
44
- logger_utils_1.logger.info(`Folder ${folderName} already exists, skipping...`);
46
+ if (errors_utils_1.ErrorUtils.isAlreadyExistsError(error)) {
47
+ logger_utils_1.logger.warn(`Folder ${folderName} already exists, skipping...`);
45
48
  return null;
46
49
  }
47
50
  if (attempt < upload_types_1.MAX_RETRIES) {
48
51
  const delay = upload_types_1.DELAYS_MS[attempt];
49
- logger_utils_1.logger.warn(`Failed to create folder ${folderName},
50
- retrying in ${delay}ms... (attempt ${attempt + 1}/${upload_types_1.MAX_RETRIES + 1})`);
52
+ if (debugMode) {
53
+ cli_utils_1.CLIUtils.warning(reporter, `Failed to create folder '${folderName}', retrying in ${delay}ms... ` +
54
+ `(attempt ${attempt + 1}/${upload_types_1.MAX_RETRIES + 1})`);
55
+ }
51
56
  await new Promise((resolve) => setTimeout(resolve, delay));
52
57
  }
53
58
  else {
54
- logger_utils_1.logger.error(`Failed to create folder ${folderName} after ${upload_types_1.MAX_RETRIES + 1} attempts`);
59
+ cli_utils_1.CLIUtils.error(reporter, `Failed to create folder '${folderName}' after ${upload_types_1.MAX_RETRIES + 1} attempts`);
55
60
  throw error;
56
61
  }
57
62
  }
58
63
  }
59
64
  return null;
60
- }
65
+ };
61
66
  }
62
67
  exports.UploadFolderService = UploadFolderService;
@@ -1,4 +1,5 @@
1
1
  import { LoginUserDetails } from '../../../types/command.types';
2
+ import { LogReporter } from '../../../utils/cli.utils';
2
3
  import { FileSystemNode } from '../../local-filesystem/local-filesystem.types';
3
4
  import { NetworkFacade } from '../network-facade.service';
4
5
  export interface UploadResult {
@@ -12,6 +13,8 @@ export interface UploadFolderParams {
12
13
  loginUserDetails: LoginUserDetails;
13
14
  jsonFlag?: boolean;
14
15
  onProgress: (progress: UploadProgress) => void;
16
+ debugMode: boolean;
17
+ reporter: LogReporter;
15
18
  }
16
19
  export interface UploadProgress {
17
20
  percentage: number;
@@ -25,10 +28,14 @@ export interface CreateFoldersParams {
25
28
  bytesUploaded: number;
26
29
  };
27
30
  emitProgress: () => void;
31
+ debugMode: boolean;
32
+ reporter: LogReporter;
28
33
  }
29
34
  export interface CreateFolderWithRetryParams {
30
35
  folderName: string;
31
36
  parentFolderUuid: string;
37
+ debugMode: boolean;
38
+ reporter: LogReporter;
32
39
  }
33
40
  export interface UploadFilesConcurrentlyParams {
34
41
  network: NetworkFacade;
@@ -41,12 +48,16 @@ export interface UploadFilesConcurrentlyParams {
41
48
  bytesUploaded: number;
42
49
  };
43
50
  emitProgress: () => void;
51
+ debugMode: boolean;
52
+ reporter: LogReporter;
44
53
  }
45
54
  export interface UploadFileWithRetryParams {
46
55
  file: FileSystemNode;
47
56
  network: NetworkFacade;
48
57
  bucket: string;
49
58
  parentFolderUuid: string;
59
+ debugMode: boolean;
60
+ reporter: LogReporter;
50
61
  }
51
62
  export declare const MAX_CONCURRENT_UPLOADS = 10;
52
63
  export declare const DELAYS_MS: number[];
@@ -1,5 +1,6 @@
1
1
  import { Auth, Drive, Network as NetworkModule } from '@internxt/sdk';
2
2
  import { ApiSecurity, AppDetails } from '@internxt/sdk/dist/shared';
3
+ import { Workspaces } from '@internxt/sdk/dist/workspaces';
3
4
  export type SdkManagerApiSecurity = ApiSecurity;
4
5
  export declare class SdkManager {
5
6
  static readonly instance: SdkManager;
@@ -10,13 +11,14 @@ export declare class SdkManager {
10
11
  throwErrorOnMissingCredentials?: boolean | undefined;
11
12
  }) => SdkManagerApiSecurity;
12
13
  static readonly getAppDetails: () => AppDetails;
13
- getAuth(): Auth;
14
- getUsers(): Drive.Users;
15
- getStorage(): Drive.Storage;
16
- getTrash(): Drive.Trash;
17
- getShare(): Drive.Share;
18
- getNetwork(credentials: {
14
+ getAuth: () => Auth;
15
+ getUsers: () => Drive.Users;
16
+ getStorage: () => Drive.Storage;
17
+ getTrash: () => Drive.Trash;
18
+ getShare: () => Drive.Share;
19
+ getWorkspaces: () => Workspaces;
20
+ getNetwork: (credentials: {
19
21
  user: string;
20
22
  pass: string;
21
- }): NetworkModule.Network;
23
+ }) => NetworkModule.Network;
22
24
  }
@@ -9,11 +9,19 @@ const drive_1 = require("@internxt/sdk/dist/drive");
9
9
  const config_service_1 = require("./config.service");
10
10
  const package_json_1 = __importDefault(require("../../package.json"));
11
11
  const network_utils_1 = require("../utils/network.utils");
12
+ const workspaces_1 = require("@internxt/sdk/dist/workspaces");
13
+ const MAX_RETRIES = 3;
12
14
  class SdkManager {
13
15
  static instance = new SdkManager();
14
16
  static apiSecurity;
15
17
  static init = (apiSecurity) => {
16
- SdkManager.apiSecurity = apiSecurity;
18
+ const newApiSecurity = {
19
+ ...apiSecurity,
20
+ retryOptions: {
21
+ maxRetries: MAX_RETRIES,
22
+ },
23
+ };
24
+ SdkManager.apiSecurity = newApiSecurity;
17
25
  };
18
26
  static clean = () => {
19
27
  SdkManager.apiSecurity = undefined;
@@ -30,37 +38,43 @@ class SdkManager {
30
38
  desktopHeader: config_service_1.ConfigService.instance.get('DESKTOP_HEADER'),
31
39
  };
32
40
  };
33
- getAuth() {
41
+ getAuth = () => {
34
42
  const DRIVE_API_URL = config_service_1.ConfigService.instance.get('DRIVE_NEW_API_URL');
35
43
  const apiSecurity = SdkManager.getApiSecurity({ throwErrorOnMissingCredentials: false });
36
44
  const appDetails = SdkManager.getAppDetails();
37
45
  return sdk_1.Auth.client(DRIVE_API_URL, appDetails, apiSecurity);
38
- }
39
- getUsers() {
46
+ };
47
+ getUsers = () => {
40
48
  const DRIVE_API_URL = config_service_1.ConfigService.instance.get('DRIVE_NEW_API_URL');
41
49
  const apiSecurity = SdkManager.getApiSecurity({ throwErrorOnMissingCredentials: false });
42
50
  const appDetails = SdkManager.getAppDetails();
43
51
  return sdk_1.Drive.Users.client(DRIVE_API_URL, appDetails, apiSecurity);
44
- }
45
- getStorage() {
52
+ };
53
+ getStorage = () => {
46
54
  const DRIVE_API_URL = config_service_1.ConfigService.instance.get('DRIVE_NEW_API_URL');
47
55
  const apiSecurity = SdkManager.getApiSecurity();
48
56
  const appDetails = SdkManager.getAppDetails();
49
57
  return sdk_1.Drive.Storage.client(DRIVE_API_URL, appDetails, apiSecurity);
50
- }
51
- getTrash() {
58
+ };
59
+ getTrash = () => {
52
60
  const DRIVE_NEW_API_URL = config_service_1.ConfigService.instance.get('DRIVE_NEW_API_URL');
53
61
  const apiSecurity = SdkManager.getApiSecurity();
54
62
  const appDetails = SdkManager.getAppDetails();
55
63
  return drive_1.Trash.client(DRIVE_NEW_API_URL, appDetails, apiSecurity);
56
- }
57
- getShare() {
64
+ };
65
+ getShare = () => {
58
66
  const DRIVE_NEW_API_URL = config_service_1.ConfigService.instance.get('DRIVE_NEW_API_URL');
59
67
  const apiSecurity = SdkManager.getApiSecurity();
60
68
  const appDetails = SdkManager.getAppDetails();
61
69
  return sdk_1.Drive.Share.client(DRIVE_NEW_API_URL, appDetails, apiSecurity);
62
- }
63
- getNetwork(credentials) {
70
+ };
71
+ getWorkspaces = () => {
72
+ const DRIVE_NEW_API_URL = config_service_1.ConfigService.instance.get('DRIVE_NEW_API_URL');
73
+ const apiSecurity = SdkManager.getApiSecurity();
74
+ const appDetails = SdkManager.getAppDetails();
75
+ return workspaces_1.Workspaces.client(DRIVE_NEW_API_URL, appDetails, apiSecurity);
76
+ };
77
+ getNetwork = (credentials) => {
64
78
  const appDetails = SdkManager.getAppDetails();
65
79
  const auth = network_utils_1.NetworkUtils.getAuthFromCredentials({
66
80
  user: credentials.user,
@@ -70,6 +84,6 @@ class SdkManager {
70
84
  bridgeUser: auth.username,
71
85
  userId: auth.password,
72
86
  });
73
- }
87
+ };
74
88
  }
75
89
  exports.SdkManager = SdkManager;
@@ -1,7 +1,25 @@
1
+ import { Readable } from 'node:stream';
1
2
  import { StorageTypes } from '@internxt/sdk/dist/drive';
2
3
  import { NetworkFacade } from './network/network-facade.service';
4
+ import { BufferStream } from '../utils/stream.utils';
3
5
  export declare class ThumbnailService {
4
6
  static readonly instance: ThumbnailService;
5
- uploadThumbnail: (fileContent: Buffer, fileType: string, userBucket: string, file_id: string, networkFacade: NetworkFacade) => Promise<StorageTypes.Thumbnail | undefined>;
7
+ private static readonly MAX_THUMBNAIL_TIMEOUT;
8
+ uploadThumbnail: (fileContent: Buffer, fileType: string, userBucket: string, file_id: string, networkFacade: NetworkFacade, fileSize: number) => Promise<StorageTypes.Thumbnail | undefined>;
6
9
  private readonly getThumbnailFromImageBuffer;
10
+ tryUploadThumbnail: ({ bufferStream, fileType, bucket, fileUuid, networkFacade, size, }: {
11
+ bufferStream?: BufferStream;
12
+ fileType: string;
13
+ bucket: string;
14
+ fileUuid: string;
15
+ networkFacade: NetworkFacade;
16
+ size: number;
17
+ }) => Promise<void>;
18
+ createFileStreamWithBuffer: ({ path, fileType, }: {
19
+ path: string;
20
+ fileType: string;
21
+ }) => {
22
+ bufferStream?: BufferStream;
23
+ fileStream: Readable;
24
+ };
7
25
  }
@@ -2,9 +2,13 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ThumbnailService = void 0;
4
4
  const node_stream_1 = require("node:stream");
5
+ const node_fs_1 = require("node:fs");
5
6
  const drive_file_service_1 = require("./drive/drive-file.service");
6
7
  const drive_1 = require("@internxt/sdk/dist/drive");
7
8
  const thumbnail_utils_1 = require("../utils/thumbnail.utils");
9
+ const stream_utils_1 = require("../utils/stream.utils");
10
+ const errors_utils_1 = require("../utils/errors.utils");
11
+ const async_utils_1 = require("../utils/async.utils");
8
12
  let sharpDependency = null;
9
13
  const getSharp = async () => {
10
14
  if (!sharpDependency) {
@@ -19,9 +23,10 @@ const getSharp = async () => {
19
23
  };
20
24
  class ThumbnailService {
21
25
  static instance = new ThumbnailService();
22
- uploadThumbnail = async (fileContent, fileType, userBucket, file_id, networkFacade) => {
26
+ static MAX_THUMBNAIL_TIMEOUT = 30000;
27
+ uploadThumbnail = async (fileContent, fileType, userBucket, file_id, networkFacade, fileSize) => {
23
28
  let thumbnailBuffer;
24
- if ((0, thumbnail_utils_1.isImageThumbnailable)(fileType)) {
29
+ if (thumbnail_utils_1.ThumbnailUtils.isImageThumbnailable(fileType, fileSize)) {
25
30
  thumbnailBuffer = await this.getThumbnailFromImageBuffer(fileContent);
26
31
  }
27
32
  if (thumbnailBuffer) {
@@ -62,5 +67,27 @@ class ThumbnailService {
62
67
  .toBuffer();
63
68
  }
64
69
  };
70
+ tryUploadThumbnail = async ({ bufferStream, fileType, bucket, fileUuid, networkFacade, size, }) => {
71
+ try {
72
+ const thumbnailBuffer = bufferStream?.getBuffer();
73
+ if (thumbnailBuffer) {
74
+ await async_utils_1.AsyncUtils.withTimeout(ThumbnailService.instance.uploadThumbnail(thumbnailBuffer, fileType, bucket, fileUuid, networkFacade, size), ThumbnailService.MAX_THUMBNAIL_TIMEOUT, 'Thumbnail upload timeout');
75
+ }
76
+ }
77
+ catch (error) {
78
+ errors_utils_1.ErrorUtils.report(error);
79
+ }
80
+ };
81
+ createFileStreamWithBuffer = ({ path, fileType, }) => {
82
+ const readable = (0, node_fs_1.createReadStream)(path);
83
+ if (thumbnail_utils_1.ThumbnailUtils.isFileThumbnailable(fileType)) {
84
+ const bufferStream = new stream_utils_1.BufferStream();
85
+ return {
86
+ bufferStream,
87
+ fileStream: readable.pipe(bufferStream),
88
+ };
89
+ }
90
+ return { fileStream: readable };
91
+ };
65
92
  }
66
93
  exports.ThumbnailService = ThumbnailService;
@@ -1,10 +1,12 @@
1
1
  import { LoginCredentials } from '../types/command.types';
2
+ import { LogReporter } from '../utils/cli.utils';
2
3
  export declare class UniversalLinkService {
3
4
  static readonly instance: UniversalLinkService;
4
5
  getUserCredentials: (userSession: {
5
6
  mnemonic: string;
6
7
  token: string;
8
+ privateKey: string;
7
9
  }) => Promise<LoginCredentials>;
8
10
  buildLoginUrl: (redirectUri: string) => string;
9
- loginSSO: (jsonFlag: boolean, reporter: (message: string) => void, hostIp?: string, forcedPort?: number) => Promise<LoginCredentials>;
11
+ loginSSO: (jsonFlag: boolean, reporter: LogReporter, hostIp?: string, forcedPort?: number) => Promise<LoginCredentials>;
10
12
  }
@@ -14,11 +14,22 @@ class UniversalLinkService {
14
14
  getUserCredentials = async (userSession) => {
15
15
  const clearMnemonic = Buffer.from(userSession.mnemonic, 'base64').toString('utf-8');
16
16
  const clearToken = Buffer.from(userSession.token, 'base64').toString('utf-8');
17
- const loginCredentials = await auth_service_1.AuthService.instance.refreshUserToken(clearToken, clearMnemonic);
17
+ const clearPrivateKey = Buffer.from(userSession.privateKey, 'base64').toString('utf-8');
18
+ const loginCredentials = await auth_service_1.AuthService.instance.refreshUserToken(clearToken, clearMnemonic, clearPrivateKey);
18
19
  return {
19
20
  user: {
20
21
  ...loginCredentials.user,
21
22
  mnemonic: clearMnemonic,
23
+ keys: {
24
+ ecc: {
25
+ privateKey: clearPrivateKey,
26
+ publicKey: loginCredentials.user.keys.ecc.publicKey,
27
+ },
28
+ kyber: {
29
+ privateKey: loginCredentials.user.keys.kyber.privateKey,
30
+ publicKey: loginCredentials.user.keys.kyber.publicKey,
31
+ },
32
+ },
22
33
  },
23
34
  token: clearToken,
24
35
  };
@@ -41,10 +52,11 @@ class UniversalLinkService {
41
52
  try {
42
53
  const mnemonic = parsedUrl.searchParams.get('mnemonic');
43
54
  const token = parsedUrl.searchParams.get('newToken');
44
- if (!mnemonic || !token) {
55
+ const privateKey = parsedUrl.searchParams.get('privateKey');
56
+ if (!mnemonic || !token || !privateKey) {
45
57
  throw new Error('Login has failed, please try again');
46
58
  }
47
- const loginCredentials = await this.getUserCredentials({ mnemonic, token });
59
+ const loginCredentials = await this.getUserCredentials({ mnemonic, token, privateKey });
48
60
  res.writeHead(302, {
49
61
  Location: `${driveUrl}/auth-link-ok`,
50
62
  });
@@ -1,7 +1,6 @@
1
- import { UsageResponseV2 } from '@internxt/sdk/dist/drive/storage/types';
2
1
  export declare class UsageService {
3
2
  static readonly instance: UsageService;
4
3
  static readonly INFINITE_LIMIT: number;
5
- fetchUsage: () => Promise<UsageResponseV2>;
4
+ fetchUsage: () => Promise<number>;
6
5
  fetchSpaceLimit: () => Promise<number>;
7
6
  }
@@ -8,7 +8,7 @@ class UsageService {
8
8
  fetchUsage = async () => {
9
9
  const storageClient = sdk_manager_service_1.SdkManager.instance.getStorage();
10
10
  const driveUsage = await storageClient.spaceUsageV2();
11
- return driveUsage;
11
+ return driveUsage.total;
12
12
  };
13
13
  fetchSpaceLimit = async () => {
14
14
  const storageClient = sdk_manager_service_1.SdkManager.instance.getStorage();
@@ -31,12 +31,22 @@ class ValidationService {
31
31
  return str.trim().length > 0;
32
32
  };
33
33
  validateDirectoryExists = async (path) => {
34
- const directoryStat = await promises_1.default.stat(path);
35
- return directoryStat.isDirectory();
34
+ try {
35
+ const directoryStat = await promises_1.default.stat(path);
36
+ return directoryStat.isDirectory();
37
+ }
38
+ catch {
39
+ return false;
40
+ }
36
41
  };
37
42
  validateFileExists = async (path) => {
38
- const fileStat = await promises_1.default.stat(path);
39
- return fileStat.isFile();
43
+ try {
44
+ const fileStat = await promises_1.default.stat(path);
45
+ return fileStat.isFile();
46
+ }
47
+ catch {
48
+ return false;
49
+ }
40
50
  };
41
51
  validateJwtAndCheckExpiration = (token) => {
42
52
  if (!token || typeof token !== 'string' || token.split('.').length !== 3) {
@@ -1,12 +1,6 @@
1
- import { ConfigService } from '../../services/config.service';
2
- import { DriveFolderService } from '../../services/drive/drive-folder.service';
3
1
  import { DriveFolderItem } from '../../types/drive.types';
4
2
  export declare class WebDavFolderService {
5
- private readonly dependencies;
6
- constructor(dependencies: {
7
- driveFolderService: DriveFolderService;
8
- configService: ConfigService;
9
- });
3
+ static readonly instance: WebDavFolderService;
10
4
  getDriveFolderItemFromPath: (path: string) => Promise<DriveFolderItem | undefined>;
11
5
  createFolder: ({ folderName, parentFolderUuid, }: {
12
6
  folderName: string;