@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
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const core_1 = require("@oclif/core");
7
7
  const promises_1 = require("node:fs/promises");
8
8
  const node_fs_1 = require("node:fs");
9
- const auth_service_1 = require("../services/auth.service");
10
9
  const cli_utils_1 = require("../utils/cli.utils");
11
10
  const config_service_1 = require("../services/config.service");
12
11
  const node_path_1 = __importDefault(require("node:path"));
@@ -16,6 +15,8 @@ const validation_service_1 = require("../services/validation.service");
16
15
  const types_1 = require("@internxt/sdk/dist/drive/storage/types");
17
16
  const stream_utils_1 = require("../utils/stream.utils");
18
17
  const thumbnail_utils_1 = require("../utils/thumbnail.utils");
18
+ const thumbnail_service_1 = require("../services/thumbnail.service");
19
+ const auth_service_1 = require("../services/auth.service");
19
20
  class UploadFile extends core_1.Command {
20
21
  static args = {};
21
22
  static description = 'Upload a file to Internxt Drive';
@@ -39,23 +40,29 @@ class UploadFile extends core_1.Command {
39
40
  run = async () => {
40
41
  const { flags } = await this.parse(UploadFile);
41
42
  const nonInteractive = flags['non-interactive'];
42
- const { user } = await auth_service_1.AuthService.instance.getAuthDetails();
43
+ const userCredentials = await config_service_1.ConfigService.instance.readUser();
44
+ if (!userCredentials)
45
+ throw new command_types_1.MissingCredentialsError();
43
46
  const filePath = await this.getFilePath(flags['file'], nonInteractive);
44
47
  const stats = await (0, promises_1.stat)(filePath);
45
48
  const fileInfo = node_path_1.default.parse(filePath);
46
49
  const fileType = fileInfo.ext.replaceAll('.', '');
47
- const destinationFolderUuid = (await cli_utils_1.CLIUtils.getDestinationFolderUuid({
50
+ const reporter = this.log.bind(this);
51
+ const destinationFolderUuidFromFlag = await cli_utils_1.CLIUtils.getDestinationFolderUuid({
48
52
  destinationFolderUuidFlag: flags['destination'],
49
53
  destinationFlagName: UploadFile.flags['destination'].name,
50
54
  nonInteractive,
51
- reporter: this.log.bind(this),
52
- })) ?? user.rootFolderId;
55
+ reporter,
56
+ });
57
+ const destinationFolderUuid = await cli_utils_1.CLIUtils.fallbackToRootFolderIdIfEmpty(destinationFolderUuidFromFlag);
53
58
  const timings = {
54
59
  networkUpload: 0,
55
60
  driveUpload: 0,
56
61
  thumbnailUpload: 0,
57
62
  };
58
- const networkFacade = cli_utils_1.CLIUtils.prepareNetwork({ loginUserDetails: user, jsonFlag: flags['json'] });
63
+ cli_utils_1.CLIUtils.doing('Preparing Network', flags['json']);
64
+ const { networkFacade, bucket } = await cli_utils_1.CLIUtils.prepareNetwork(userCredentials.user);
65
+ cli_utils_1.CLIUtils.done(flags['json']);
59
66
  const networkUploadTimer = cli_utils_1.CLIUtils.timer();
60
67
  const progressBar = cli_utils_1.CLIUtils.progress({
61
68
  format: 'Uploading file [{bar}] {percentage}%',
@@ -64,7 +71,7 @@ class UploadFile extends core_1.Command {
64
71
  progressBar?.start(100, 0);
65
72
  let fileId;
66
73
  let bufferStream;
67
- const isThumbnailable = (0, thumbnail_utils_1.isFileThumbnailable)(fileType);
74
+ const isThumbnailable = thumbnail_utils_1.ThumbnailUtils.isFileThumbnailable(fileType);
68
75
  const fileSize = stats.size ?? 0;
69
76
  if (fileSize > 0) {
70
77
  const readStream = (0, node_fs_1.createReadStream)(filePath);
@@ -77,7 +84,7 @@ class UploadFile extends core_1.Command {
77
84
  progressBar?.update(progress * 100 * 0.99);
78
85
  };
79
86
  fileId = await new Promise((resolve, reject) => {
80
- const state = networkFacade.uploadFile(fileStream, fileSize, user.bucket, (err, res) => {
87
+ const state = networkFacade.uploadFile(fileStream, fileSize, bucket, (err, res) => {
81
88
  if (err) {
82
89
  return reject(err);
83
90
  }
@@ -96,8 +103,8 @@ class UploadFile extends core_1.Command {
96
103
  type: fileType,
97
104
  size: fileSize,
98
105
  folderUuid: destinationFolderUuid,
99
- fileId: fileId,
100
- bucket: user.bucket,
106
+ fileId,
107
+ bucket,
101
108
  encryptVersion: types_1.EncryptionVersion.Aes03,
102
109
  creationTime: stats.birthtime?.toISOString(),
103
110
  modificationTime: stats.mtime?.toISOString(),
@@ -105,12 +112,13 @@ class UploadFile extends core_1.Command {
105
112
  timings.driveUpload = driveUploadTimer.stop();
106
113
  const thumbnailTimer = cli_utils_1.CLIUtils.timer();
107
114
  if (fileSize > 0 && isThumbnailable && bufferStream) {
108
- void (0, thumbnail_utils_1.tryUploadThumbnail)({
115
+ await thumbnail_service_1.ThumbnailService.instance.tryUploadThumbnail({
109
116
  bufferStream,
110
117
  fileType,
111
- userBucket: user.bucket,
118
+ bucket,
112
119
  fileUuid: createdDriveFile.uuid,
113
120
  networkFacade,
121
+ size: fileSize,
114
122
  });
115
123
  }
116
124
  timings.thumbnailUpload = thumbnailTimer.stop();
@@ -118,15 +126,18 @@ class UploadFile extends core_1.Command {
118
126
  progressBar?.stop();
119
127
  const totalTime = Object.values(timings).reduce((sum, time) => sum + time, 0);
120
128
  const throughputMBps = cli_utils_1.CLIUtils.calculateThroughputMBps(stats.size, timings.networkUpload);
121
- this.log('\n');
122
- this.log(`[PUT] Timing breakdown:\n
123
- Network upload: ${cli_utils_1.CLIUtils.formatDuration(timings.networkUpload)} (${throughputMBps.toFixed(2)} MB/s)\n
124
- Drive upload: ${cli_utils_1.CLIUtils.formatDuration(timings.driveUpload)}\n
125
- Thumbnail: ${cli_utils_1.CLIUtils.formatDuration(timings.thumbnailUpload)}\n`);
126
- this.log('\n');
129
+ if (flags['debug']) {
130
+ cli_utils_1.CLIUtils.log(reporter, '[PUT] Timing breakdown:\n' +
131
+ `Network upload: ${cli_utils_1.CLIUtils.formatDuration(timings.networkUpload)} (${throughputMBps.toFixed(2)} MB/s)\n` +
132
+ `Drive upload: ${cli_utils_1.CLIUtils.formatDuration(timings.driveUpload)}\n` +
133
+ `Thumbnail: ${cli_utils_1.CLIUtils.formatDuration(timings.thumbnailUpload)}\n`);
134
+ }
135
+ const workspace = await auth_service_1.AuthService.instance.getCurrentWorkspace();
136
+ const workspaceId = workspace?.workspaceData.workspace.id;
127
137
  const message = `File uploaded successfully in ${cli_utils_1.CLIUtils.formatDuration(totalTime)}, view it at ` +
128
- `${config_service_1.ConfigService.instance.get('DRIVE_WEB_URL')}/file/${createdDriveFile.uuid}`;
129
- cli_utils_1.CLIUtils.success(this.log.bind(this), message);
138
+ `${config_service_1.ConfigService.instance.get('DRIVE_WEB_URL')}/file/${createdDriveFile.uuid}` +
139
+ `${workspaceId ? `?workspaceid=${workspaceId}` : ''}`;
140
+ cli_utils_1.CLIUtils.success(reporter, message);
130
141
  return {
131
142
  success: true,
132
143
  message,
@@ -158,7 +169,7 @@ class UploadFile extends core_1.Command {
158
169
  },
159
170
  }, {
160
171
  validate: validation_service_1.ValidationService.instance.validateFileExists,
161
- error: new command_types_1.NotValidDirectoryError(),
172
+ error: new command_types_1.NotValidFileError(),
162
173
  }, this.log.bind(this));
163
174
  return filePath;
164
175
  };
@@ -8,6 +8,7 @@ export default class UploadFolder extends Command {
8
8
  folder: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
9
  destination: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
10
  'non-interactive': import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ debug: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
12
  };
12
13
  static readonly enableJsonFlag = true;
13
14
  run: () => Promise<void>;
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const core_1 = require("@oclif/core");
4
4
  const cli_utils_1 = require("../utils/cli.utils");
5
- const auth_service_1 = require("../services/auth.service");
6
5
  const validation_service_1 = require("../services/validation.service");
7
6
  const config_service_1 = require("../services/config.service");
8
7
  const upload_facade_service_1 = require("../services/network/upload/upload-facade.service");
@@ -28,15 +27,19 @@ class UploadFolder extends core_1.Command {
28
27
  };
29
28
  static enableJsonFlag = true;
30
29
  run = async () => {
31
- const { user } = await auth_service_1.AuthService.instance.getAuthDetails();
32
30
  const { flags } = await this.parse(UploadFolder);
31
+ const userCredentials = await config_service_1.ConfigService.instance.readUser();
32
+ if (!userCredentials)
33
+ throw new command_types_1.MissingCredentialsError();
33
34
  const localPath = await this.getFolderPath(flags['folder'], flags['non-interactive']);
34
- const destinationFolderUuid = (await cli_utils_1.CLIUtils.getDestinationFolderUuid({
35
+ const reporter = this.log.bind(this);
36
+ const destinationFolderUuidFromFlag = await cli_utils_1.CLIUtils.getDestinationFolderUuid({
35
37
  destinationFolderUuidFlag: flags['destination'],
36
38
  destinationFlagName: UploadFolder.flags['destination'].name,
37
39
  nonInteractive: flags['non-interactive'],
38
- reporter: this.log.bind(this),
39
- })) ?? user.rootFolderId;
40
+ reporter,
41
+ });
42
+ const destinationFolderUuid = await cli_utils_1.CLIUtils.fallbackToRootFolderIdIfEmpty(destinationFolderUuidFromFlag);
40
43
  const progressBar = cli_utils_1.CLIUtils.progress({
41
44
  format: 'Uploading folder [{bar}] {percentage}%',
42
45
  linewrap: true,
@@ -45,11 +48,13 @@ class UploadFolder extends core_1.Command {
45
48
  const data = await upload_facade_service_1.UploadFacade.instance.uploadFolder({
46
49
  localPath,
47
50
  destinationFolderUuid,
48
- loginUserDetails: user,
51
+ loginUserDetails: userCredentials.user,
49
52
  jsonFlag: flags['json'],
50
53
  onProgress: (progress) => {
51
54
  progressBar?.update(progress.percentage);
52
55
  },
56
+ debugMode: flags['debug'],
57
+ reporter,
53
58
  });
54
59
  progressBar?.update(100);
55
60
  progressBar?.stop();
@@ -11,12 +11,30 @@ export default class WebDAVConfig extends Command {
11
11
  http: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
12
  timeout: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
13
  createFullPath: import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
+ customAuth: import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
+ username: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
16
+ password: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
17
+ deleteFilesPermanently: import("@oclif/core/interfaces").BooleanFlag<boolean>;
18
+ 'non-interactive': import("@oclif/core/interfaces").BooleanFlag<boolean>;
19
+ debug: import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
20
  };
15
21
  static readonly enableJsonFlag = true;
16
22
  run: () => Promise<{
17
23
  success: boolean;
18
24
  message: string;
19
- config: import("../types/command.types").WebdavConfig;
25
+ config: {
26
+ password: undefined;
27
+ host: string;
28
+ port: string;
29
+ protocol: "http" | "https";
30
+ timeoutMinutes: number;
31
+ createFullPath: boolean;
32
+ customAuth: boolean;
33
+ username: string;
34
+ deleteFilesPermanently: boolean;
35
+ };
20
36
  }>;
21
37
  catch: (error: Error) => Promise<never>;
38
+ private getUsername;
39
+ private getPassword;
22
40
  }
@@ -11,6 +11,7 @@ class WebDAVConfig extends core_1.Command {
11
11
  static aliases = [];
12
12
  static examples = ['<%= config.bin %> <%= command.id %>'];
13
13
  static flags = {
14
+ ...cli_utils_1.CLIUtils.CommonFlags,
14
15
  host: core_1.Flags.string({
15
16
  char: 'l',
16
17
  description: 'The listening host for the WebDAV server.',
@@ -45,10 +46,36 @@ class WebDAVConfig extends core_1.Command {
45
46
  required: false,
46
47
  allowNo: true,
47
48
  }),
49
+ customAuth: core_1.Flags.boolean({
50
+ char: 'a',
51
+ description: 'Configures the WebDAV server to use custom authentication.',
52
+ required: false,
53
+ default: undefined,
54
+ allowNo: true,
55
+ }),
56
+ username: core_1.Flags.string({
57
+ char: 'u',
58
+ description: 'Configures the WebDAV server to use this username for custom authentication.',
59
+ required: false,
60
+ }),
61
+ password: core_1.Flags.string({
62
+ char: 'w',
63
+ description: 'Configures the WebDAV server to use this password for custom authentication.',
64
+ required: false,
65
+ }),
66
+ deleteFilesPermanently: core_1.Flags.boolean({
67
+ char: 'd',
68
+ description: 'Configures the WebDAV server to delete files permanently instead of trashing them.',
69
+ required: false,
70
+ default: undefined,
71
+ allowNo: true,
72
+ }),
48
73
  };
49
74
  static enableJsonFlag = true;
50
75
  run = async () => {
51
- const { flags: { host, port, http, https, timeout, createFullPath }, } = await this.parse(WebDAVConfig);
76
+ const { flags } = await this.parse(WebDAVConfig);
77
+ const { host, port, https, http, timeout, createFullPath, customAuth, username, password, deleteFilesPermanently } = flags;
78
+ const nonInteractive = flags['non-interactive'];
52
79
  const webdavConfig = await config_service_1.ConfigService.instance.readWebdavConfig();
53
80
  if (host) {
54
81
  webdavConfig['host'] = host;
@@ -73,10 +100,29 @@ class WebDAVConfig extends core_1.Command {
73
100
  if (createFullPath !== undefined) {
74
101
  webdavConfig['createFullPath'] = createFullPath;
75
102
  }
103
+ if (customAuth !== undefined) {
104
+ webdavConfig['customAuth'] = customAuth;
105
+ }
106
+ if (username) {
107
+ webdavConfig['username'] = await this.getUsername(username, nonInteractive);
108
+ }
109
+ if (password) {
110
+ webdavConfig['password'] = await this.getPassword(password, nonInteractive);
111
+ }
112
+ if (webdavConfig['customAuth'] && (!webdavConfig['username'] || !webdavConfig['password'])) {
113
+ throw new command_types_1.MissingCredentialsWhenUsingAuthError();
114
+ }
115
+ if (deleteFilesPermanently !== undefined) {
116
+ webdavConfig['deleteFilesPermanently'] = deleteFilesPermanently;
117
+ }
76
118
  await config_service_1.ConfigService.instance.saveWebdavConfig(webdavConfig);
77
- const message = `On the next start, the WebDAV server will use the next config: ${JSON.stringify(webdavConfig)}`;
119
+ const printWebdavConfig = {
120
+ ...webdavConfig,
121
+ password: undefined,
122
+ };
123
+ const message = 'On the next start, the WebDAV server will use the next config: ' + JSON.stringify(printWebdavConfig);
78
124
  cli_utils_1.CLIUtils.success(this.log.bind(this), message);
79
- return { success: true, message, config: webdavConfig };
125
+ return { success: true, message, config: printWebdavConfig };
80
126
  };
81
127
  catch = async (error) => {
82
128
  const { flags } = await this.parse(WebDAVConfig);
@@ -88,5 +134,37 @@ class WebDAVConfig extends core_1.Command {
88
134
  });
89
135
  this.exit(1);
90
136
  };
137
+ getUsername = async (usernameFlag, nonInteractive) => {
138
+ const username = await cli_utils_1.CLIUtils.getValueFromFlag({
139
+ value: usernameFlag,
140
+ name: WebDAVConfig.flags['username'].name,
141
+ }, {
142
+ nonInteractive,
143
+ prompt: {
144
+ message: 'What is the custom auth username?',
145
+ options: { type: 'input' },
146
+ },
147
+ }, {
148
+ validate: validation_service_1.ValidationService.instance.validateStringIsNotEmpty,
149
+ error: new command_types_1.EmptyCustomAuthUsernameError(),
150
+ }, this.log.bind(this));
151
+ return username;
152
+ };
153
+ getPassword = async (passwordFlag, nonInteractive) => {
154
+ const password = await cli_utils_1.CLIUtils.getValueFromFlag({
155
+ value: passwordFlag,
156
+ name: WebDAVConfig.flags['password'].name,
157
+ }, {
158
+ nonInteractive,
159
+ prompt: {
160
+ message: 'What is the custom auth password?',
161
+ options: { type: 'password' },
162
+ },
163
+ }, {
164
+ validate: validation_service_1.ValidationService.instance.validateStringIsNotEmpty,
165
+ error: new command_types_1.EmptyCustomAuthPasswordError(),
166
+ }, this.log.bind(this));
167
+ return password;
168
+ };
91
169
  }
92
170
  exports.default = WebDAVConfig;
@@ -3,7 +3,7 @@ export default class Webdav extends Command {
3
3
  static readonly args: {
4
4
  action: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
5
  };
6
- static readonly description = "Enable, disable, restart or get the status of the Internxt CLI WebDav server";
6
+ static readonly description = "Start, stop, restart or get the status of the Internxt CLI WebDAV server";
7
7
  static readonly aliases: never[];
8
8
  static readonly examples: string[];
9
9
  static readonly flags: {};
@@ -5,18 +5,19 @@ const pm2_utils_1 = require("../utils/pm2.utils");
5
5
  const cli_utils_1 = require("../utils/cli.utils");
6
6
  const config_service_1 = require("../services/config.service");
7
7
  const auth_service_1 = require("../services/auth.service");
8
+ const webdav_server_1 = require("../webdav/webdav-server");
8
9
  class Webdav extends core_1.Command {
9
10
  static args = {
10
11
  action: core_1.Args.string({
11
12
  required: true,
12
- options: ['enable', 'disable', 'restart', 'status'],
13
+ options: ['enable', 'start', 'disable', 'stop', 'restart', 'status'],
13
14
  }),
14
15
  };
15
- static description = 'Enable, disable, restart or get the status of the Internxt CLI WebDav server';
16
+ static description = 'Start, stop, restart or get the status of the Internxt CLI WebDAV server';
16
17
  static aliases = [];
17
18
  static examples = [
18
- '<%= config.bin %> <%= command.id %> enable',
19
- '<%= config.bin %> <%= command.id %> disable',
19
+ '<%= config.bin %> <%= command.id %> enable | start',
20
+ '<%= config.bin %> <%= command.id %> disable | stop',
20
21
  '<%= config.bin %> <%= command.id %> restart',
21
22
  '<%= config.bin %> <%= command.id %> status',
22
23
  ];
@@ -27,23 +28,27 @@ class Webdav extends core_1.Command {
27
28
  let message = '';
28
29
  let success = true;
29
30
  await pm2_utils_1.PM2Utils.connect();
31
+ const configs = await config_service_1.ConfigService.instance.readWebdavConfig();
30
32
  switch (args.action) {
33
+ case 'start':
31
34
  case 'enable': {
32
35
  await auth_service_1.AuthService.instance.getAuthDetails();
36
+ webdav_server_1.WebDavServer.checkwebDAVCredentials(configs);
33
37
  message = await this.enableWebDav(flags['json']);
34
38
  break;
35
39
  }
40
+ case 'stop':
36
41
  case 'disable': {
37
42
  message = await this.disableWebDav(flags['json']);
38
43
  break;
39
44
  }
40
45
  case 'restart': {
41
46
  await auth_service_1.AuthService.instance.getAuthDetails();
47
+ webdav_server_1.WebDavServer.checkwebDAVCredentials(configs);
42
48
  message = await this.restartWebDav(flags['json']);
43
49
  break;
44
50
  }
45
51
  case 'status': {
46
- await auth_service_1.AuthService.instance.getAuthDetails();
47
52
  message = await this.webDAVStatus();
48
53
  break;
49
54
  }
@@ -30,7 +30,8 @@ class Whoami extends core_1.Command {
30
30
  else {
31
31
  if (validCreds.refreshRequired) {
32
32
  try {
33
- await auth_service_1.AuthService.instance.refreshUserToken(userCredentials.token, userCredentials.user.mnemonic);
33
+ const refreshedCreds = await auth_service_1.AuthService.instance.refreshUserToken(userCredentials.token, userCredentials.user.mnemonic, userCredentials.user.keys.ecc.privateKey);
34
+ await config_service_1.ConfigService.instance.saveUser(refreshedCreds);
34
35
  }
35
36
  catch {
36
37
  }
@@ -0,0 +1,20 @@
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
+ }
@@ -0,0 +1,67 @@
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
+ });
64
+ this.exit(1);
65
+ };
66
+ }
67
+ exports.default = WorkspacesList;
@@ -0,0 +1,23 @@
1
+ import { Command } from '@oclif/core';
2
+ import { LogReporter } from '../utils/cli.utils';
3
+ import { LoginCredentials } from '../types/command.types';
4
+ export default class WorkspacesUnset extends Command {
5
+ static readonly args: {};
6
+ static readonly description: string;
7
+ static readonly aliases: string[];
8
+ static readonly examples: string[];
9
+ static readonly flags: {
10
+ 'non-interactive': import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ debug: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
+ };
13
+ static readonly enableJsonFlag = true;
14
+ run: () => Promise<{
15
+ success: boolean;
16
+ message: string;
17
+ }>;
18
+ catch: (error: Error) => Promise<never>;
19
+ static readonly unsetWorkspace: (userCredentials: LoginCredentials, reporter: LogReporter) => Promise<{
20
+ success: boolean;
21
+ message: string;
22
+ }>;
23
+ }
@@ -0,0 +1,45 @@
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 sdk_manager_service_1 = require("../services/sdk-manager.service");
8
+ const database_service_1 = require("../services/database/database.service");
9
+ class WorkspacesUnset extends core_1.Command {
10
+ static args = {};
11
+ static description = 'Unset the active workspace context for the current user session. ' +
12
+ 'Once a workspace is unset, WebDAV and all of the subsequent CLI commands ' +
13
+ 'will operate within the personal drive space until it is changed or set again.';
14
+ static aliases = ['workspaces:unset'];
15
+ static examples = ['<%= config.bin %> <%= command.id %>'];
16
+ static flags = {
17
+ ...cli_utils_1.CLIUtils.CommonFlags,
18
+ };
19
+ static enableJsonFlag = true;
20
+ run = async () => {
21
+ await this.parse(WorkspacesUnset);
22
+ const userCredentials = await config_service_1.ConfigService.instance.readUser();
23
+ if (!userCredentials)
24
+ throw new command_types_1.MissingCredentialsError();
25
+ return WorkspacesUnset.unsetWorkspace(userCredentials, this.log.bind(this));
26
+ };
27
+ catch = async (error) => {
28
+ const { flags } = await this.parse(WorkspacesUnset);
29
+ cli_utils_1.CLIUtils.catchError({
30
+ error,
31
+ command: this.id,
32
+ logReporter: this.log.bind(this),
33
+ jsonFlag: flags['json'],
34
+ });
35
+ this.exit(1);
36
+ };
37
+ static unsetWorkspace = async (userCredentials, reporter) => {
38
+ sdk_manager_service_1.SdkManager.init({ token: userCredentials.token });
39
+ await config_service_1.ConfigService.instance.saveUser({ ...userCredentials, workspace: undefined });
40
+ void database_service_1.DatabaseService.instance.clear();
41
+ cli_utils_1.CLIUtils.success(reporter, 'Personal drive space selected successfully.');
42
+ return { success: true, message: 'Personal drive space selected successfully.' };
43
+ };
44
+ }
45
+ exports.default = WorkspacesUnset;
@@ -0,0 +1,27 @@
1
+ import { Command } from '@oclif/core';
2
+ import { Workspace } from '../types/command.types';
3
+ export default class WorkspacesUse extends Command {
4
+ static readonly args: {};
5
+ static readonly description: string;
6
+ static readonly aliases: string[];
7
+ static readonly examples: string[];
8
+ static readonly flags: {
9
+ id: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ personal: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ 'non-interactive': import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
+ debug: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
+ };
14
+ static readonly enableJsonFlag = true;
15
+ run: () => Promise<{
16
+ success: boolean;
17
+ message: string;
18
+ } | {
19
+ success: boolean;
20
+ workspace: Workspace;
21
+ }>;
22
+ catch: (error: Error) => Promise<never>;
23
+ private getWorkspaceUuid;
24
+ private extractUuidFromWorkspaceString;
25
+ private getWorkspace;
26
+ private setWorkspace;
27
+ }