@internxt/cli 1.6.4 → 1.6.6

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 (105) hide show
  1. package/README.md +94 -40
  2. package/dist/commands/add-cert.d.ts +4 -1
  3. package/dist/commands/add-cert.js +4 -1
  4. package/dist/commands/config.js +1 -0
  5. package/dist/commands/create-folder.js +1 -0
  6. package/dist/commands/delete-permanently-file.js +1 -0
  7. package/dist/commands/delete-permanently-folder.js +1 -0
  8. package/dist/commands/download-file.js +1 -0
  9. package/dist/commands/list.js +1 -0
  10. package/dist/commands/login-legacy.js +3 -0
  11. package/dist/commands/login.d.ts +2 -0
  12. package/dist/commands/login.js +4 -0
  13. package/dist/commands/logout.d.ts +4 -1
  14. package/dist/commands/logout.js +4 -1
  15. package/dist/commands/logs.d.ts +4 -1
  16. package/dist/commands/logs.js +4 -1
  17. package/dist/commands/move-file.js +1 -0
  18. package/dist/commands/move-folder.js +1 -0
  19. package/dist/commands/rename-file.js +1 -0
  20. package/dist/commands/rename-folder.js +1 -0
  21. package/dist/commands/trash-clear.js +1 -0
  22. package/dist/commands/trash-file.js +1 -0
  23. package/dist/commands/trash-folder.js +1 -0
  24. package/dist/commands/trash-list.d.ts +2 -0
  25. package/dist/commands/trash-list.js +2 -0
  26. package/dist/commands/trash-restore-file.js +1 -0
  27. package/dist/commands/trash-restore-folder.js +1 -0
  28. package/dist/commands/upload-file.js +16 -26
  29. package/dist/commands/upload-folder.js +1 -0
  30. package/dist/commands/webdav-config.js +1 -0
  31. package/dist/commands/webdav.d.ts +4 -1
  32. package/dist/commands/webdav.js +4 -1
  33. package/dist/commands/whoami.d.ts +4 -1
  34. package/dist/commands/whoami.js +4 -1
  35. package/dist/commands/workspaces-list.js +1 -0
  36. package/dist/commands/workspaces-unset.js +1 -0
  37. package/dist/commands/workspaces-use.js +1 -0
  38. package/dist/hooks/prerun/auth_check.js +2 -0
  39. package/dist/services/auth.service.js +10 -1
  40. package/dist/services/cache.service.d.ts +13 -0
  41. package/dist/services/cache.service.js +36 -0
  42. package/dist/services/config.service.js +19 -3
  43. package/dist/services/database/database.service.d.ts +1 -1
  44. package/dist/services/database/database.service.js +6 -5
  45. package/dist/services/database/drive-item/drive-item.attributes.d.ts +7 -0
  46. package/dist/services/database/drive-item/drive-item.domain.d.ts +10 -0
  47. package/dist/services/database/drive-item/drive-item.domain.js +27 -0
  48. package/dist/services/database/drive-item/drive-item.model.d.ts +8 -0
  49. package/dist/services/database/{drive-folder/drive-folder.model.js → drive-item/drive-item.model.js} +11 -23
  50. package/dist/services/database/drive-item/drive-item.repository.d.ts +12 -0
  51. package/dist/services/database/drive-item/drive-item.repository.js +88 -0
  52. package/dist/services/drive/drive-file.service.d.ts +2 -3
  53. package/dist/services/drive/drive-file.service.js +9 -34
  54. package/dist/services/drive/drive-folder.service.d.ts +1 -3
  55. package/dist/services/drive/drive-folder.service.js +9 -87
  56. package/dist/services/drive/drive-item.service.d.ts +8 -0
  57. package/dist/services/drive/drive-item.service.js +98 -0
  58. package/dist/services/network/network-facade.service.d.ts +1 -3
  59. package/dist/services/network/network-facade.service.js +5 -8
  60. package/dist/services/network/upload/upload-file.service.js +2 -1
  61. package/dist/services/thumbnail.service.js +2 -2
  62. package/dist/services/usage.service.d.ts +2 -0
  63. package/dist/services/usage.service.js +18 -0
  64. package/dist/utils/cli.utils.d.ts +5 -3
  65. package/dist/utils/cli.utils.js +36 -18
  66. package/dist/utils/format.utils.js +3 -2
  67. package/dist/utils/upload.utils.d.ts +19 -0
  68. package/dist/utils/upload.utils.js +40 -0
  69. package/dist/utils/webdav.utils.d.ts +4 -2
  70. package/dist/utils/webdav.utils.js +14 -18
  71. package/dist/utils/xml.utils.js +5 -1
  72. package/dist/webdav/handlers/DELETE.handler.js +2 -0
  73. package/dist/webdav/handlers/LOCK.handler.d.ts +5 -0
  74. package/dist/webdav/handlers/LOCK.handler.js +50 -0
  75. package/dist/webdav/handlers/MKCOL.handler.js +15 -3
  76. package/dist/webdav/handlers/MOVE.handler.js +11 -0
  77. package/dist/webdav/handlers/OPTIONS.handler.js +4 -4
  78. package/dist/webdav/handlers/PROPFIND.handler.js +30 -9
  79. package/dist/webdav/handlers/PUT.handler.js +44 -40
  80. package/dist/webdav/handlers/UNLOCK.handler.d.ts +5 -0
  81. package/dist/webdav/handlers/UNLOCK.handler.js +12 -0
  82. package/dist/webdav/middewares/auth.middleware.js +9 -2
  83. package/dist/webdav/middewares/errors.middleware.js +2 -0
  84. package/dist/webdav/middewares/request-logger.middleware.js +10 -6
  85. package/dist/webdav/middewares/webdav-auth.middleware.js +0 -3
  86. package/dist/webdav/webdav-server.js +4 -0
  87. package/oclif.manifest.json +134 -1
  88. package/package.json +47 -46
  89. package/dist/services/database/drive-file/drive-file.attributes.d.ts +0 -14
  90. package/dist/services/database/drive-file/drive-file.domain.d.ts +0 -20
  91. package/dist/services/database/drive-file/drive-file.domain.js +0 -68
  92. package/dist/services/database/drive-file/drive-file.model.d.ts +0 -15
  93. package/dist/services/database/drive-file/drive-file.model.js +0 -67
  94. package/dist/services/database/drive-file/drive-file.repository.d.ts +0 -11
  95. package/dist/services/database/drive-file/drive-file.repository.js +0 -63
  96. package/dist/services/database/drive-folder/drive-folder.attributes.d.ts +0 -10
  97. package/dist/services/database/drive-folder/drive-folder.attributes.js +0 -2
  98. package/dist/services/database/drive-folder/drive-folder.domain.d.ts +0 -16
  99. package/dist/services/database/drive-folder/drive-folder.domain.js +0 -53
  100. package/dist/services/database/drive-folder/drive-folder.model.d.ts +0 -11
  101. package/dist/services/database/drive-folder/drive-folder.repository.d.ts +0 -13
  102. package/dist/services/database/drive-folder/drive-folder.repository.js +0 -99
  103. package/dist/utils/database.utils.d.ts +0 -11
  104. package/dist/utils/database.utils.js +0 -26
  105. /package/dist/services/database/{drive-file/drive-file.attributes.js → drive-item/drive-item.attributes.js} +0 -0
@@ -45,6 +45,7 @@ class RenameFolder extends core_1.Command {
45
45
  command: this.id,
46
46
  logReporter: this.log.bind(this),
47
47
  jsonFlag: flags['json'],
48
+ debugMode: flags['debug'],
48
49
  });
49
50
  this.exit(1);
50
51
  };
@@ -50,6 +50,7 @@ class TrashClear extends core_1.Command {
50
50
  command: this.id,
51
51
  logReporter: this.log.bind(this),
52
52
  jsonFlag: flags['json'],
53
+ debugMode: flags['debug'],
53
54
  });
54
55
  this.exit(1);
55
56
  };
@@ -39,6 +39,7 @@ class TrashFile extends core_1.Command {
39
39
  command: this.id,
40
40
  logReporter: this.log.bind(this),
41
41
  jsonFlag: flags['json'],
42
+ debugMode: flags['debug'],
42
43
  });
43
44
  this.exit(1);
44
45
  };
@@ -39,6 +39,7 @@ class TrashFolder extends core_1.Command {
39
39
  command: this.id,
40
40
  logReporter: this.log.bind(this),
41
41
  jsonFlag: flags['json'],
42
+ debugMode: flags['debug'],
42
43
  });
43
44
  this.exit(1);
44
45
  };
@@ -6,6 +6,8 @@ export default class TrashList extends Command {
6
6
  static readonly examples: string[];
7
7
  static readonly flags: {
8
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>;
9
11
  };
10
12
  static readonly enableJsonFlag = true;
11
13
  run: () => Promise<{
@@ -12,6 +12,7 @@ class TrashList extends core_1.Command {
12
12
  static aliases = ['trash:list'];
13
13
  static examples = ['<%= config.bin %> <%= command.id %>'];
14
14
  static flags = {
15
+ ...cli_utils_1.CLIUtils.CommonFlags,
15
16
  extended: core_1.Flags.boolean({
16
17
  char: 'e',
17
18
  description: 'Displays additional information in the trash list.',
@@ -63,6 +64,7 @@ class TrashList extends core_1.Command {
63
64
  command: this.id,
64
65
  logReporter: this.log.bind(this),
65
66
  jsonFlag: flags['json'],
67
+ debugMode: flags['debug'],
66
68
  });
67
69
  this.exit(1);
68
70
  };
@@ -52,6 +52,7 @@ class TrashRestoreFile extends core_1.Command {
52
52
  command: this.id,
53
53
  logReporter: this.log.bind(this),
54
54
  jsonFlag: flags['json'],
55
+ debugMode: flags['debug'],
55
56
  });
56
57
  this.exit(1);
57
58
  };
@@ -54,6 +54,7 @@ class TrashRestoreFolder extends core_1.Command {
54
54
  command: this.id,
55
55
  logReporter: this.log.bind(this),
56
56
  jsonFlag: flags['json'],
57
+ debugMode: flags['debug'],
57
58
  });
58
59
  this.exit(1);
59
60
  };
@@ -13,10 +13,9 @@ const drive_file_service_1 = require("../services/drive/drive-file.service");
13
13
  const command_types_1 = require("../types/command.types");
14
14
  const validation_service_1 = require("../services/validation.service");
15
15
  const types_1 = require("@internxt/sdk/dist/drive/storage/types");
16
- const stream_utils_1 = require("../utils/stream.utils");
17
- const thumbnail_utils_1 = require("../utils/thumbnail.utils");
18
16
  const thumbnail_service_1 = require("../services/thumbnail.service");
19
17
  const auth_service_1 = require("../services/auth.service");
18
+ const upload_utils_1 = require("../utils/upload.utils");
20
19
  class UploadFile extends core_1.Command {
21
20
  static args = {};
22
21
  static description = 'Upload a file to Internxt Drive';
@@ -70,22 +69,18 @@ class UploadFile extends core_1.Command {
70
69
  }, flags['json']);
71
70
  progressBar?.start(100, 0);
72
71
  let fileId;
73
- let bufferStream;
74
- const isThumbnailable = thumbnail_utils_1.ThumbnailUtils.isFileThumbnailable(fileType);
72
+ let thumbnailStream;
75
73
  const fileSize = stats.size ?? 0;
76
74
  if (fileSize > 0) {
77
75
  const readStream = (0, node_fs_1.createReadStream)(filePath);
78
- let fileStream = readStream;
79
- if (isThumbnailable) {
80
- bufferStream = new stream_utils_1.BufferStream();
81
- fileStream = readStream.pipe(bufferStream);
82
- }
76
+ const preparedStreams = upload_utils_1.UploadUtils.prepareUploadStreams(readStream, fileType);
77
+ thumbnailStream = preparedStreams.thumbnailStream;
83
78
  const progressCallback = (progress) => {
84
79
  progressBar?.update(progress * 100 * 0.99);
85
80
  };
86
81
  const abortable = new AbortController();
87
82
  fileId = await networkFacade.uploadFile({
88
- from: fileStream,
83
+ from: preparedStreams.fileStream,
89
84
  size: fileSize,
90
85
  bucketId: bucket,
91
86
  progressCallback,
@@ -111,26 +106,20 @@ class UploadFile extends core_1.Command {
111
106
  });
112
107
  timings.driveUpload = driveUploadTimer.stop();
113
108
  const thumbnailTimer = cli_utils_1.CLIUtils.timer();
114
- if (fileSize > 0 && isThumbnailable && bufferStream) {
115
- await thumbnail_service_1.ThumbnailService.instance.tryUploadThumbnail({
116
- bufferStream,
117
- fileType,
118
- bucket,
119
- fileUuid: createdDriveFile.uuid,
120
- networkFacade,
121
- size: fileSize,
122
- });
123
- }
109
+ await thumbnail_service_1.ThumbnailService.instance.tryUploadThumbnail({
110
+ bufferStream: thumbnailStream,
111
+ fileType,
112
+ bucket,
113
+ fileUuid: createdDriveFile.uuid,
114
+ networkFacade,
115
+ size: fileSize,
116
+ });
124
117
  timings.thumbnailUpload = thumbnailTimer.stop();
125
118
  progressBar?.update(100);
126
119
  progressBar?.stop();
127
- const totalTime = Object.values(timings).reduce((sum, time) => sum + time, 0);
128
- const throughputMBps = cli_utils_1.CLIUtils.calculateThroughputMBps(stats.size, timings.networkUpload);
120
+ const { totalTime, timingBreakdown } = upload_utils_1.UploadUtils.getTimings(stats.size, timings);
129
121
  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`);
122
+ cli_utils_1.CLIUtils.log(reporter, timingBreakdown);
134
123
  }
135
124
  const workspace = await auth_service_1.AuthService.instance.getCurrentWorkspace();
136
125
  const workspaceId = workspace?.workspaceData.workspace.id;
@@ -154,6 +143,7 @@ class UploadFile extends core_1.Command {
154
143
  command: this.id,
155
144
  logReporter: this.log.bind(this),
156
145
  jsonFlag: flags['json'],
146
+ debugMode: flags['debug'],
157
147
  });
158
148
  this.exit(1);
159
149
  };
@@ -70,6 +70,7 @@ class UploadFolder extends core_1.Command {
70
70
  command: this.id,
71
71
  logReporter: this.log.bind(this),
72
72
  jsonFlag: flags['json'],
73
+ debugMode: flags['debug'],
73
74
  });
74
75
  this.exit(1);
75
76
  };
@@ -131,6 +131,7 @@ class WebDAVConfig extends core_1.Command {
131
131
  command: this.id,
132
132
  logReporter: this.log.bind(this),
133
133
  jsonFlag: flags['json'],
134
+ debugMode: flags['debug'],
134
135
  });
135
136
  this.exit(1);
136
137
  };
@@ -6,7 +6,10 @@ export default class Webdav extends Command {
6
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
- static readonly flags: {};
9
+ static readonly flags: {
10
+ 'non-interactive': import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ debug: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
+ };
10
13
  static readonly enableJsonFlag = true;
11
14
  run: () => Promise<{
12
15
  success: boolean;
@@ -21,7 +21,9 @@ class Webdav extends core_1.Command {
21
21
  '<%= config.bin %> <%= command.id %> restart',
22
22
  '<%= config.bin %> <%= command.id %> status',
23
23
  ];
24
- static flags = {};
24
+ static flags = {
25
+ ...cli_utils_1.CLIUtils.CommonFlags,
26
+ };
25
27
  static enableJsonFlag = true;
26
28
  run = async () => {
27
29
  const { args, flags } = await this.parse(Webdav);
@@ -68,6 +70,7 @@ class Webdav extends core_1.Command {
68
70
  command: this.id,
69
71
  logReporter: this.log.bind(this),
70
72
  jsonFlag: flags['json'],
73
+ debugMode: flags['debug'],
71
74
  });
72
75
  this.exit(1);
73
76
  };
@@ -5,7 +5,10 @@ export default class Whoami extends Command {
5
5
  static readonly description = "Display the current user logged into the Internxt CLI.";
6
6
  static readonly aliases: never[];
7
7
  static readonly examples: string[];
8
- static readonly flags: {};
8
+ static readonly flags: {
9
+ 'non-interactive': import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ debug: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ };
9
12
  static readonly enableJsonFlag = true;
10
13
  run: () => Promise<{
11
14
  success: boolean;
@@ -10,7 +10,9 @@ class Whoami extends core_1.Command {
10
10
  static description = 'Display the current user logged into the Internxt CLI.';
11
11
  static aliases = [];
12
12
  static examples = ['<%= config.bin %> <%= command.id %>'];
13
- static flags = {};
13
+ static flags = {
14
+ ...cli_utils_1.CLIUtils.CommonFlags,
15
+ };
14
16
  static enableJsonFlag = true;
15
17
  run = async () => {
16
18
  const userCredentials = await config_service_1.ConfigService.instance.readUser();
@@ -49,6 +51,7 @@ class Whoami extends core_1.Command {
49
51
  command: this.id,
50
52
  logReporter: this.log.bind(this),
51
53
  jsonFlag: flags['json'],
54
+ debugMode: flags['debug'],
52
55
  });
53
56
  this.exit(1);
54
57
  };
@@ -60,6 +60,7 @@ class WorkspacesList extends core_1.Command {
60
60
  command: this.id,
61
61
  logReporter: this.log.bind(this),
62
62
  jsonFlag: flags['json'],
63
+ debugMode: flags['debug'],
63
64
  });
64
65
  this.exit(1);
65
66
  };
@@ -31,6 +31,7 @@ class WorkspacesUnset extends core_1.Command {
31
31
  command: this.id,
32
32
  logReporter: this.log.bind(this),
33
33
  jsonFlag: flags['json'],
34
+ debugMode: flags['debug'],
34
35
  });
35
36
  this.exit(1);
36
37
  };
@@ -60,6 +60,7 @@ class WorkspacesUse extends core_1.Command {
60
60
  command: this.id,
61
61
  logReporter: this.log.bind(this),
62
62
  jsonFlag: flags['json'],
63
+ debugMode: flags['debug'],
63
64
  });
64
65
  this.exit(1);
65
66
  };
@@ -22,6 +22,7 @@ const CommandsToSkip = [whoami_1.default, login_1.default, login_legacy_1.defaul
22
22
  const hook = async function (opts) {
23
23
  const { Command, argv } = opts;
24
24
  const jsonFlag = argv.includes('--json');
25
+ const debugFlag = argv.includes('--debug');
25
26
  const commandsToSkipNames = CommandsToSkip.map((command) => command.name?.toLowerCase()).filter(Boolean);
26
27
  const commandsToSkipIds = CommandsToSkip.map((command) => command.id?.toLowerCase()).filter(Boolean);
27
28
  if (!commandsToSkipNames.includes(Command.name?.toLowerCase()) &&
@@ -41,6 +42,7 @@ const hook = async function (opts) {
41
42
  command: Command.id,
42
43
  logReporter: this.log.bind(this),
43
44
  jsonFlag,
45
+ debugMode: debugFlag,
44
46
  });
45
47
  opts.context.exit(1);
46
48
  }
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AuthService = void 0;
4
4
  const sdk_manager_service_1 = require("./sdk-manager.service");
5
+ const cache_service_1 = require("./cache.service");
5
6
  const crypto_service_1 = require("./crypto.service");
6
7
  const config_service_1 = require("./config.service");
7
8
  const command_types_1 = require("../types/command.types");
@@ -53,9 +54,11 @@ class AuthService {
53
54
  if (tokenDetails.expiration.expired) {
54
55
  throw new command_types_1.ExpiredCredentialsError();
55
56
  }
57
+ let credentialsChanged = false;
56
58
  if (tokenDetails.expiration.refreshRequired) {
57
59
  try {
58
60
  loginCreds = await this.refreshUserToken(loginCreds.token, loginCreds.user.mnemonic, loginCreds.user.keys.ecc.privateKey);
61
+ credentialsChanged = true;
59
62
  }
60
63
  catch (error) {
61
64
  await config_service_1.ConfigService.instance.clearUser();
@@ -63,9 +66,14 @@ class AuthService {
63
66
  }
64
67
  }
65
68
  const workspaceCreds = await this.refreshWorkspaceCredentials(loginCreds);
69
+ if (workspaceCreds !== loginCreds.workspace) {
70
+ credentialsChanged = true;
71
+ }
66
72
  loginCreds.workspace = workspaceCreds;
67
73
  sdk_manager_service_1.SdkManager.init({ token: loginCreds.token, workspaceToken: workspaceCreds?.workspaceCredentials.token });
68
- await config_service_1.ConfigService.instance.saveUser(loginCreds);
74
+ if (credentialsChanged) {
75
+ await config_service_1.ConfigService.instance.saveUser(loginCreds);
76
+ }
69
77
  return loginCreds;
70
78
  };
71
79
  refreshUserToken = async (oldToken, mnemonic, privateKey) => {
@@ -135,6 +143,7 @@ class AuthService {
135
143
  return loginCreds.workspace?.workspaceData?.workspaceUser?.rootFolderId ?? loginCreds.user.rootFolderId;
136
144
  };
137
145
  logout = async () => {
146
+ cache_service_1.CacheService.instance.clearCaches();
138
147
  try {
139
148
  const user = await config_service_1.ConfigService.instance.readUser();
140
149
  if (!user?.token) {
@@ -0,0 +1,13 @@
1
+ export declare class CacheService {
2
+ static readonly instance: CacheService;
3
+ private readonly store;
4
+ private readonly defaultTtl;
5
+ static readonly FETCH_USAGE_CACHE_KEY = "usage:fetchUsage";
6
+ static readonly FETCH_SPACE_LIMIT_CACHE_KEY = "usage:fetchSpaceLimit";
7
+ static readonly FETCH_LIMITS_CACHE_KEY = "usage:fetchLimits";
8
+ static readonly AUTH_CACHE_KEY = "auth:details";
9
+ static readonly WEBDAV_CONFIG_CACHE_KEY = "webdav:config";
10
+ get: <T>(key: string) => T | null;
11
+ set: <T>(key: string, data: T, ttl?: number) => void;
12
+ clearCaches: () => void;
13
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CacheService = void 0;
4
+ const FIFTEEN_MINUTES = 15 * 60 * 1000;
5
+ class CacheService {
6
+ static instance = new CacheService();
7
+ store = new Map();
8
+ defaultTtl = FIFTEEN_MINUTES;
9
+ static FETCH_USAGE_CACHE_KEY = 'usage:fetchUsage';
10
+ static FETCH_SPACE_LIMIT_CACHE_KEY = 'usage:fetchSpaceLimit';
11
+ static FETCH_LIMITS_CACHE_KEY = 'usage:fetchLimits';
12
+ static AUTH_CACHE_KEY = 'auth:details';
13
+ static WEBDAV_CONFIG_CACHE_KEY = 'webdav:config';
14
+ get = (key) => {
15
+ const entry = this.store.get(key);
16
+ if (!entry)
17
+ return null;
18
+ const isExpired = Date.now() - entry.timestamp > entry.ttl;
19
+ if (isExpired) {
20
+ this.store.delete(key);
21
+ return null;
22
+ }
23
+ return entry.data;
24
+ };
25
+ set = (key, data, ttl) => {
26
+ this.store.set(key, {
27
+ data,
28
+ timestamp: Date.now(),
29
+ ttl: ttl ?? this.defaultTtl,
30
+ });
31
+ };
32
+ clearCaches = () => {
33
+ this.store.clear();
34
+ };
35
+ }
36
+ exports.CacheService = CacheService;
@@ -8,6 +8,7 @@ const promises_1 = __importDefault(require("node:fs/promises"));
8
8
  const crypto_service_1 = require("./crypto.service");
9
9
  const errors_utils_1 = require("../utils/errors.utils");
10
10
  const configs_1 = require("../constants/configs");
11
+ const cache_service_1 = require("./cache.service");
11
12
  class ConfigService {
12
13
  static instance = new ConfigService();
13
14
  get = (key, throwIfNotFound = true) => {
@@ -17,12 +18,16 @@ class ConfigService {
17
18
  return value ?? '';
18
19
  };
19
20
  saveUser = async (loginCredentials) => {
21
+ cache_service_1.CacheService.instance.set(cache_service_1.CacheService.AUTH_CACHE_KEY, loginCredentials);
20
22
  await this.ensureInternxtCliDataDirExists();
21
23
  const credentialsString = JSON.stringify(loginCredentials);
22
24
  const encryptedCredentials = crypto_service_1.CryptoService.instance.encryptText(credentialsString);
23
- await promises_1.default.writeFile(configs_1.CREDENTIALS_FILE, encryptedCredentials, 'utf8');
25
+ const tempPath = configs_1.CREDENTIALS_FILE + '.tmp';
26
+ await promises_1.default.writeFile(tempPath, encryptedCredentials, 'utf8');
27
+ await promises_1.default.rename(tempPath, configs_1.CREDENTIALS_FILE);
24
28
  };
25
29
  clearUser = async () => {
30
+ cache_service_1.CacheService.instance.set(cache_service_1.CacheService.AUTH_CACHE_KEY, undefined);
26
31
  try {
27
32
  const stat = await promises_1.default.stat(configs_1.CREDENTIALS_FILE);
28
33
  if (stat.size === 0)
@@ -36,6 +41,9 @@ class ConfigService {
36
41
  }
37
42
  };
38
43
  readUser = async () => {
44
+ const cached = cache_service_1.CacheService.instance.get(cache_service_1.CacheService.AUTH_CACHE_KEY);
45
+ if (cached)
46
+ return cached;
39
47
  try {
40
48
  const encryptedCredentials = await promises_1.default.readFile(configs_1.CREDENTIALS_FILE, 'utf8');
41
49
  const credentialsString = crypto_service_1.CryptoService.instance.decryptText(encryptedCredentials);
@@ -47,15 +55,21 @@ class ConfigService {
47
55
  }
48
56
  };
49
57
  saveWebdavConfig = async (webdavConfig) => {
58
+ cache_service_1.CacheService.instance.set(cache_service_1.CacheService.WEBDAV_CONFIG_CACHE_KEY, webdavConfig);
50
59
  await this.ensureInternxtCliDataDirExists();
51
60
  const configs = JSON.stringify(webdavConfig);
52
- await promises_1.default.writeFile(configs_1.WEBDAV_CONFIGS_FILE, configs, 'utf8');
61
+ const tempPath = configs_1.WEBDAV_CONFIGS_FILE + '.tmp';
62
+ await promises_1.default.writeFile(tempPath, configs, 'utf8');
63
+ await promises_1.default.rename(tempPath, configs_1.WEBDAV_CONFIGS_FILE);
53
64
  };
54
65
  readWebdavConfig = async () => {
66
+ const cached = cache_service_1.CacheService.instance.get(cache_service_1.CacheService.WEBDAV_CONFIG_CACHE_KEY);
67
+ if (cached)
68
+ return cached;
55
69
  try {
56
70
  const configsData = await promises_1.default.readFile(configs_1.WEBDAV_CONFIGS_FILE, 'utf8');
57
71
  const configs = JSON.parse(configsData);
58
- return {
72
+ const webdavConfig = {
59
73
  host: configs?.host ?? configs_1.WEBDAV_DEFAULT_HOST,
60
74
  port: configs?.port ?? configs_1.WEBDAV_DEFAULT_PORT,
61
75
  protocol: configs?.protocol ?? configs_1.WEBDAV_DEFAULT_PROTOCOL,
@@ -66,6 +80,8 @@ class ConfigService {
66
80
  password: configs?.password ?? '',
67
81
  deleteFilesPermanently: configs?.deleteFilesPermanently ?? configs_1.WEBDAV_DEFAULT_DELETE_FILES_PERMANENTLY,
68
82
  };
83
+ cache_service_1.CacheService.instance.set(cache_service_1.CacheService.WEBDAV_CONFIG_CACHE_KEY, webdavConfig);
84
+ return webdavConfig;
69
85
  }
70
86
  catch {
71
87
  return {
@@ -2,7 +2,7 @@ import { DataSource } from 'typeorm';
2
2
  export declare class DatabaseService {
3
3
  static readonly instance: DatabaseService;
4
4
  dataSource: DataSource;
5
- initialize: () => Promise<DataSource>;
5
+ initialize: () => Promise<DataSource> | undefined;
6
6
  destroy: () => Promise<void>;
7
7
  clear: () => Promise<void>;
8
8
  drop: () => Promise<void>;
@@ -2,8 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DatabaseService = void 0;
4
4
  const typeorm_1 = require("typeorm");
5
- const drive_file_model_1 = require("./drive-file/drive-file.model");
6
- const drive_folder_model_1 = require("./drive-folder/drive-folder.model");
5
+ const drive_item_model_1 = require("./drive-item/drive-item.model");
7
6
  const configs_1 = require("../../constants/configs");
8
7
  const config_service_1 = require("../config.service");
9
8
  class DatabaseService {
@@ -14,17 +13,19 @@ class DatabaseService {
14
13
  autoSave: false,
15
14
  logging: false,
16
15
  synchronize: true,
17
- entities: [drive_file_model_1.DriveFileModel, drive_folder_model_1.DriveFolderModel],
16
+ entities: [drive_item_model_1.DriveItemModel],
18
17
  }
19
18
  : {
20
19
  type: 'better-sqlite3',
21
20
  database: configs_1.DRIVE_SQLITE_FILE,
22
21
  logging: false,
23
22
  synchronize: true,
24
- entities: [drive_file_model_1.DriveFileModel, drive_folder_model_1.DriveFolderModel],
23
+ entities: [drive_item_model_1.DriveItemModel],
25
24
  });
26
25
  initialize = () => {
27
- return this.dataSource.initialize();
26
+ if (!this.dataSource.isInitialized) {
27
+ return this.dataSource.initialize();
28
+ }
28
29
  };
29
30
  destroy = () => {
30
31
  return this.dataSource.destroy();
@@ -0,0 +1,7 @@
1
+ export interface DriveItemAttributes {
2
+ uuid: string;
3
+ path: string;
4
+ type: 'file' | 'folder';
5
+ createdAt: Date;
6
+ updatedAt: Date;
7
+ }
@@ -0,0 +1,10 @@
1
+ import { DriveItemAttributes } from './drive-item.attributes';
2
+ export declare class DriveItemBD implements DriveItemAttributes {
3
+ uuid: string;
4
+ path: string;
5
+ type: 'file' | 'folder';
6
+ createdAt: Date;
7
+ updatedAt: Date;
8
+ constructor({ uuid, path, type, createdAt, updatedAt }: DriveItemAttributes);
9
+ toJSON(): DriveItemAttributes;
10
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DriveItemBD = void 0;
4
+ class DriveItemBD {
5
+ uuid;
6
+ path;
7
+ type;
8
+ createdAt;
9
+ updatedAt;
10
+ constructor({ uuid, path, type, createdAt, updatedAt }) {
11
+ this.uuid = uuid;
12
+ this.path = path;
13
+ this.type = type;
14
+ this.createdAt = createdAt;
15
+ this.updatedAt = updatedAt;
16
+ }
17
+ toJSON() {
18
+ return {
19
+ uuid: this.uuid,
20
+ path: this.path,
21
+ type: this.type,
22
+ createdAt: this.createdAt,
23
+ updatedAt: this.updatedAt,
24
+ };
25
+ }
26
+ }
27
+ exports.DriveItemBD = DriveItemBD;
@@ -0,0 +1,8 @@
1
+ import { DriveItemAttributes } from './drive-item.attributes';
2
+ export declare class DriveItemModel implements DriveItemAttributes {
3
+ uuid: string;
4
+ path: string;
5
+ type: 'file' | 'folder';
6
+ createdAt: Date;
7
+ updatedAt: Date;
8
+ }
@@ -9,43 +9,31 @@ var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.DriveFolderModel = void 0;
12
+ exports.DriveItemModel = void 0;
13
13
  const typeorm_1 = require("typeorm");
14
- let DriveFolderModel = class DriveFolderModel {
14
+ let DriveItemModel = class DriveItemModel {
15
15
  };
16
- exports.DriveFolderModel = DriveFolderModel;
16
+ exports.DriveItemModel = DriveItemModel;
17
17
  __decorate([
18
18
  (0, typeorm_1.PrimaryColumn)({ nullable: false, type: 'varchar' }),
19
19
  __metadata("design:type", String)
20
- ], DriveFolderModel.prototype, "uuid", void 0);
20
+ ], DriveItemModel.prototype, "uuid", void 0);
21
21
  __decorate([
22
22
  (0, typeorm_1.Column)({ nullable: false, type: 'varchar' }),
23
23
  __metadata("design:type", String)
24
- ], DriveFolderModel.prototype, "name", void 0);
24
+ ], DriveItemModel.prototype, "path", void 0);
25
25
  __decorate([
26
26
  (0, typeorm_1.Column)({ nullable: false, type: 'varchar' }),
27
27
  __metadata("design:type", String)
28
- ], DriveFolderModel.prototype, "status", void 0);
29
- __decorate([
30
- (0, typeorm_1.Column)({ nullable: true, type: 'varchar' }),
31
- __metadata("design:type", Object)
32
- ], DriveFolderModel.prototype, "parentUuid", void 0);
33
- __decorate([
34
- (0, typeorm_1.Column)({ nullable: false, type: 'varchar' }),
35
- __metadata("design:type", Date)
36
- ], DriveFolderModel.prototype, "createdAt", void 0);
37
- __decorate([
38
- (0, typeorm_1.Column)({ nullable: false, type: 'varchar' }),
39
- __metadata("design:type", Date)
40
- ], DriveFolderModel.prototype, "updatedAt", void 0);
28
+ ], DriveItemModel.prototype, "type", void 0);
41
29
  __decorate([
42
30
  (0, typeorm_1.Column)({ nullable: false, type: 'varchar' }),
43
31
  __metadata("design:type", Date)
44
- ], DriveFolderModel.prototype, "creationTime", void 0);
32
+ ], DriveItemModel.prototype, "createdAt", void 0);
45
33
  __decorate([
46
34
  (0, typeorm_1.Column)({ nullable: false, type: 'varchar' }),
47
35
  __metadata("design:type", Date)
48
- ], DriveFolderModel.prototype, "modificationTime", void 0);
49
- exports.DriveFolderModel = DriveFolderModel = __decorate([
50
- (0, typeorm_1.Entity)('drive_folder')
51
- ], DriveFolderModel);
36
+ ], DriveItemModel.prototype, "updatedAt", void 0);
37
+ exports.DriveItemModel = DriveItemModel = __decorate([
38
+ (0, typeorm_1.Entity)('drive_item')
39
+ ], DriveItemModel);
@@ -0,0 +1,12 @@
1
+ import { DriveItemBD } from './drive-item.domain';
2
+ import { DriveItemModel } from './drive-item.model';
3
+ export declare class DriveItemRepository {
4
+ static readonly instance: DriveItemRepository;
5
+ private readonly repository;
6
+ createOrUpdate: (items: DriveItemModel[]) => Promise<DriveItemBD[] | undefined>;
7
+ updateByUuid: (uuid: string, update: Partial<DriveItemModel>) => Promise<import("typeorm").UpdateResult | undefined>;
8
+ delete: (uuids: string[]) => Promise<import("typeorm").DeleteResult | undefined>;
9
+ getByUuid: (uuid: string) => Promise<DriveItemBD | undefined>;
10
+ getByPath: (path: string) => Promise<DriveItemBD | undefined>;
11
+ getAll: () => Promise<DriveItemBD[]>;
12
+ }