@internxt/cli 1.2.1 → 1.3.0

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 (92) hide show
  1. package/.env +2 -1
  2. package/README.md +404 -25
  3. package/bin/dev.js +0 -0
  4. package/bin/run.js +0 -0
  5. package/dist/commands/config.js +1 -1
  6. package/dist/commands/list.js +1 -2
  7. package/dist/commands/{move.d.ts → move-file.d.ts} +5 -4
  8. package/dist/commands/move-file.js +84 -0
  9. package/dist/commands/move-folder.d.ts +19 -0
  10. package/dist/commands/move-folder.js +84 -0
  11. package/dist/commands/rename.d.ts +18 -0
  12. package/dist/commands/{move.js → rename.js} +29 -29
  13. package/dist/commands/trash-clear.d.ts +15 -0
  14. package/dist/commands/trash-clear.js +64 -0
  15. package/dist/commands/trash-list.d.ts +20 -0
  16. package/dist/commands/trash-list.js +95 -0
  17. package/dist/commands/trash-restore-file.d.ts +19 -0
  18. package/dist/commands/trash-restore-file.js +87 -0
  19. package/dist/commands/trash-restore-folder.d.ts +19 -0
  20. package/dist/commands/trash-restore-folder.js +87 -0
  21. package/dist/commands/webdav-config.d.ts +17 -0
  22. package/dist/commands/webdav-config.js +91 -0
  23. package/dist/commands/webdav.d.ts +1 -1
  24. package/dist/commands/webdav.js +5 -2
  25. package/dist/database/migrations/20241018114828-add-parent-column.d.ts +1 -0
  26. package/dist/database/migrations/20241018114828-add-parent-column.js +24 -0
  27. package/dist/hooks/prerun/auth_check.js +2 -1
  28. package/dist/services/analytics.service.d.ts +9 -6
  29. package/dist/services/analytics.service.js +2 -35
  30. package/dist/services/config.service.d.ts +6 -1
  31. package/dist/services/config.service.js +24 -0
  32. package/dist/services/database/drive-database-manager.service.d.ts +10 -7
  33. package/dist/services/database/drive-database-manager.service.js +34 -24
  34. package/dist/services/database/drive-file/drive-file.attributes.d.ts +1 -0
  35. package/dist/services/database/drive-file/drive-file.domain.d.ts +4 -1
  36. package/dist/services/database/drive-file/drive-file.domain.js +21 -1
  37. package/dist/services/database/drive-file/drive-file.model.d.ts +1 -0
  38. package/dist/services/database/drive-file/drive-file.model.js +4 -0
  39. package/dist/services/database/drive-folder/drive-folder.attributes.d.ts +1 -0
  40. package/dist/services/database/drive-folder/drive-folder.domain.d.ts +4 -1
  41. package/dist/services/database/drive-folder/drive-folder.domain.js +18 -1
  42. package/dist/services/database/drive-folder/drive-folder.model.d.ts +1 -0
  43. package/dist/services/database/drive-folder/drive-folder.model.js +5 -0
  44. package/dist/services/drive/drive-file.service.d.ts +5 -0
  45. package/dist/services/drive/drive-file.service.js +10 -0
  46. package/dist/services/drive/drive-folder.service.d.ts +7 -2
  47. package/dist/services/drive/drive-folder.service.js +16 -0
  48. package/dist/services/drive/trash.service.d.ts +7 -0
  49. package/dist/services/drive/trash.service.js +30 -0
  50. package/dist/services/network/upload.service.js +5 -1
  51. package/dist/services/sdk-manager.service.d.ts +1 -2
  52. package/dist/services/sdk-manager.service.js +0 -5
  53. package/dist/services/usage.service.d.ts +2 -1
  54. package/dist/services/usage.service.js +3 -7
  55. package/dist/services/validation.service.d.ts +2 -0
  56. package/dist/services/validation.service.js +6 -0
  57. package/dist/types/command.types.d.ts +16 -0
  58. package/dist/types/command.types.js +29 -1
  59. package/dist/types/config.types.d.ts +0 -1
  60. package/dist/types/drive.types.d.ts +2 -1
  61. package/dist/types/network.types.d.ts +5 -0
  62. package/dist/types/webdav.types.d.ts +1 -0
  63. package/dist/utils/cli.utils.d.ts +1 -1
  64. package/dist/utils/drive.utils.js +3 -1
  65. package/dist/utils/network.utils.d.ts +3 -9
  66. package/dist/utils/network.utils.js +21 -7
  67. package/dist/utils/webdav.utils.d.ts +16 -2
  68. package/dist/utils/webdav.utils.js +71 -20
  69. package/dist/utils/xml.utils.d.ts +1 -0
  70. package/dist/utils/xml.utils.js +3 -0
  71. package/dist/webdav/handlers/DELETE.handler.d.ts +5 -1
  72. package/dist/webdav/handlers/DELETE.handler.js +15 -12
  73. package/dist/webdav/handlers/GET.handler.d.ts +1 -2
  74. package/dist/webdav/handlers/GET.handler.js +10 -13
  75. package/dist/webdav/handlers/HEAD.handler.d.ts +1 -1
  76. package/dist/webdav/handlers/HEAD.handler.js +2 -2
  77. package/dist/webdav/handlers/MKCOL.handler.d.ts +1 -1
  78. package/dist/webdav/handlers/MKCOL.handler.js +14 -15
  79. package/dist/webdav/handlers/MOVE.handler.d.ts +11 -1
  80. package/dist/webdav/handlers/MOVE.handler.js +73 -2
  81. package/dist/webdav/handlers/OPTIONS.handler.d.ts +1 -1
  82. package/dist/webdav/handlers/OPTIONS.handler.js +2 -2
  83. package/dist/webdav/handlers/PROPFIND.handler.d.ts +11 -12
  84. package/dist/webdav/handlers/PROPFIND.handler.js +62 -76
  85. package/dist/webdav/handlers/PUT.handler.d.ts +5 -8
  86. package/dist/webdav/handlers/PUT.handler.js +34 -18
  87. package/dist/webdav/middewares/request-logger.middleware.js +1 -1
  88. package/dist/webdav/webdav-server.d.ts +14 -14
  89. package/dist/webdav/webdav-server.js +31 -14
  90. package/oclif.manifest.json +441 -8
  91. package/package.json +22 -26
  92. package/scripts/add-cert.sh +19 -5
@@ -5,36 +5,45 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.WebDavUtils = void 0;
7
7
  const path_1 = __importDefault(require("path"));
8
- const drive_folder_domain_1 = require("../services/database/drive-folder/drive-folder.domain");
9
- const drive_file_domain_1 = require("../services/database/drive-file/drive-file.domain");
8
+ const errors_utils_1 = require("./errors.utils");
9
+ const logger_utils_1 = require("./logger.utils");
10
10
  class WebDavUtils {
11
11
  static joinURL(...pathComponents) {
12
12
  return path_1.default.posix.join(...pathComponents);
13
13
  }
14
- static getParentPath(fromPath) {
15
- return path_1.default.dirname(fromPath);
14
+ static removeHostFromURL(completeURL) {
15
+ if (!completeURL.startsWith('/') && !/^https?:\/\//i.test(completeURL)) {
16
+ completeURL = 'https://' + completeURL;
17
+ }
18
+ const parsedUrl = new URL(completeURL);
19
+ let url = parsedUrl.href.replace(parsedUrl.origin + '/', '');
20
+ if (!url.startsWith('/'))
21
+ url = '/'.concat(url);
22
+ return url;
16
23
  }
17
- static async getRequestedResource(req, driveDatabaseManager) {
18
- const decodedUrl = decodeURI(req.url);
19
- const parsedPath = path_1.default.parse(decodedUrl);
20
- let isFolder = req.url.endsWith('/');
21
- if (!isFolder) {
22
- const findDatabaseItem = await driveDatabaseManager.findByRelativePath(decodedUrl);
23
- if (findDatabaseItem) {
24
- if (findDatabaseItem instanceof drive_file_domain_1.DriveFile) {
25
- isFolder = false;
26
- }
27
- else if (findDatabaseItem instanceof drive_folder_domain_1.DriveFolder) {
28
- isFolder = true;
29
- }
30
- }
24
+ static async getRequestedResource(urlObject) {
25
+ let requestUrl;
26
+ if (typeof urlObject === 'string') {
27
+ requestUrl = urlObject;
31
28
  }
29
+ else {
30
+ requestUrl = urlObject.url;
31
+ }
32
+ const decodedUrl = decodeURIComponent(requestUrl).replaceAll('/./', '/');
33
+ const parsedPath = path_1.default.parse(decodedUrl);
34
+ let parentPath = path_1.default.dirname(decodedUrl);
35
+ if (!parentPath.startsWith('/'))
36
+ parentPath = '/'.concat(parentPath);
37
+ if (!parentPath.endsWith('/'))
38
+ parentPath = parentPath.concat('/');
39
+ const isFolder = requestUrl.endsWith('/');
32
40
  if (isFolder) {
33
41
  return {
34
- url: decodedUrl,
35
42
  type: 'folder',
36
- name: parsedPath.name,
43
+ url: decodedUrl,
44
+ name: parsedPath.base,
37
45
  path: parsedPath,
46
+ parentPath,
38
47
  };
39
48
  }
40
49
  else {
@@ -43,8 +52,50 @@ class WebDavUtils {
43
52
  url: decodedUrl,
44
53
  name: parsedPath.name,
45
54
  path: parsedPath,
55
+ parentPath,
46
56
  };
47
57
  }
48
58
  }
59
+ static async getDatabaseItemFromResource(resource, driveDatabaseManager) {
60
+ let databaseResource = null;
61
+ if (resource.type === 'folder') {
62
+ databaseResource = await driveDatabaseManager.findFolderByRelativePath(resource.url);
63
+ }
64
+ if (resource.type === 'file') {
65
+ databaseResource = await driveDatabaseManager.findFileByRelativePath(resource.url);
66
+ }
67
+ return databaseResource?.toItem() ?? null;
68
+ }
69
+ static async setDatabaseItem(type, driveItem, driveDatabaseManager, relativePath) {
70
+ if (type === 'folder') {
71
+ return await driveDatabaseManager.createFolder(driveItem, relativePath);
72
+ }
73
+ if (type === 'file') {
74
+ return await driveDatabaseManager.createFile(driveItem, relativePath);
75
+ }
76
+ }
77
+ static async getDriveItemFromResource(resource, driveFolderService, driveFileService) {
78
+ let item = undefined;
79
+ if (resource.type === 'folder') {
80
+ item = await driveFolderService?.getFolderMetadataByPath(resource.url);
81
+ }
82
+ if (resource.type === 'file') {
83
+ item = await driveFileService?.getFileMetadataByPath(resource.url);
84
+ }
85
+ return item;
86
+ }
87
+ static async getAndSearchItemFromResource({ resource, driveDatabaseManager, driveFolderService, driveFileService, }) {
88
+ let databaseItem = await this.getDatabaseItemFromResource(resource, driveDatabaseManager);
89
+ if (!databaseItem) {
90
+ logger_utils_1.webdavLogger.info('Resource not found on local database', { resource });
91
+ const driveItem = await this.getDriveItemFromResource(resource, driveFolderService, driveFileService);
92
+ if (!driveItem) {
93
+ throw new errors_utils_1.NotFoundError(`Resource not found on Internxt Drive at ${resource.url}`);
94
+ }
95
+ databaseItem = driveItem;
96
+ await this.setDatabaseItem(resource.type, driveItem, driveDatabaseManager, resource.url);
97
+ }
98
+ return databaseItem;
99
+ }
49
100
  }
50
101
  exports.WebDavUtils = WebDavUtils;
@@ -5,4 +5,5 @@ export declare class XMLUtils {
5
5
  static toXML(object: object, options?: XmlBuilderOptions): any;
6
6
  static toWebDavXML(object: object, options: XmlBuilderOptions): string;
7
7
  static addDefaultNamespace(key: string): string;
8
+ static encodeWebDavUri(uri: string): string;
8
9
  }
@@ -19,5 +19,8 @@ class XMLUtils {
19
19
  static addDefaultNamespace(key) {
20
20
  return `${XMLUtils.DEFAULT_NAMESPACE_LETTER}:${key}`;
21
21
  }
22
+ static encodeWebDavUri(uri) {
23
+ return encodeURIComponent(uri).replaceAll('%2F', '/');
24
+ }
22
25
  }
23
26
  exports.XMLUtils = XMLUtils;
@@ -2,11 +2,15 @@ import { Request, Response } from 'express';
2
2
  import { WebDavMethodHandler } from '../../types/webdav.types';
3
3
  import { DriveDatabaseManager } from '../../services/database/drive-database-manager.service';
4
4
  import { TrashService } from '../../services/drive/trash.service';
5
+ import { DriveFileService } from '../../services/drive/drive-file.service';
6
+ import { DriveFolderService } from '../../services/drive/drive-folder.service';
5
7
  export declare class DELETERequestHandler implements WebDavMethodHandler {
6
- private dependencies;
8
+ private readonly dependencies;
7
9
  constructor(dependencies: {
8
10
  driveDatabaseManager: DriveDatabaseManager;
9
11
  trashService: TrashService;
12
+ driveFileService: DriveFileService;
13
+ driveFolderService: DriveFolderService;
10
14
  });
11
15
  handle: (req: Request, res: Response) => Promise<void>;
12
16
  }
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DELETERequestHandler = void 0;
4
- const errors_utils_1 = require("../../utils/errors.utils");
5
4
  const webdav_utils_1 = require("../../utils/webdav.utils");
6
5
  const logger_utils_1 = require("../../utils/logger.utils");
7
6
  class DELETERequestHandler {
@@ -10,21 +9,25 @@ class DELETERequestHandler {
10
9
  this.dependencies = dependencies;
11
10
  }
12
11
  handle = async (req, res) => {
12
+ const { driveDatabaseManager, driveFileService, driveFolderService, trashService } = this.dependencies;
13
13
  logger_utils_1.webdavLogger.info('DELETE request received');
14
- const resource = await webdav_utils_1.WebDavUtils.getRequestedResource(req, this.dependencies.driveDatabaseManager);
15
- logger_utils_1.webdavLogger.info('Resource found for DELETE request', { resource });
16
- const databaseItem = await this.dependencies.driveDatabaseManager.findByRelativePath(resource.url);
17
- if (!databaseItem)
18
- throw new errors_utils_1.NotFoundError('Resource not found');
19
- logger_utils_1.webdavLogger.info(`Trashing ${resource.type} with UUID ${databaseItem.uuid}...`);
20
- await this.dependencies.trashService.trashItems({
21
- items: [{ type: resource.type, uuid: databaseItem.uuid }],
14
+ const resource = await webdav_utils_1.WebDavUtils.getRequestedResource(req);
15
+ logger_utils_1.webdavLogger.info('Resource received for DELETE request', { resource });
16
+ const driveItem = await webdav_utils_1.WebDavUtils.getAndSearchItemFromResource({
17
+ resource,
18
+ driveDatabaseManager,
19
+ driveFolderService,
20
+ driveFileService: driveFileService,
21
+ });
22
+ logger_utils_1.webdavLogger.info(`Trashing ${resource.type} with UUID ${driveItem.uuid}...`);
23
+ await trashService.trashItems({
24
+ items: [{ type: resource.type, uuid: driveItem.uuid }],
22
25
  });
23
26
  if (resource.type === 'folder') {
24
- await this.dependencies.driveDatabaseManager.deleteFolder(databaseItem.id);
27
+ await driveDatabaseManager.deleteFolderById(driveItem.id);
25
28
  }
26
- if (resource.type === 'file') {
27
- await this.dependencies.driveDatabaseManager.deleteFile(databaseItem.id);
29
+ else if (resource.type === 'file') {
30
+ await driveDatabaseManager.deleteFileById(driveItem.id);
28
31
  }
29
32
  res.status(204).send();
30
33
  };
@@ -8,7 +8,7 @@ import { DownloadService } from '../../services/network/download.service';
8
8
  import { CryptoService } from '../../services/crypto.service';
9
9
  import { AuthService } from '../../services/auth.service';
10
10
  export declare class GETRequestHandler implements WebDavMethodHandler {
11
- private dependencies;
11
+ private readonly dependencies;
12
12
  constructor(dependencies: {
13
13
  driveFileService: DriveFileService;
14
14
  driveDatabaseManager: DriveDatabaseManager;
@@ -19,5 +19,4 @@ export declare class GETRequestHandler implements WebDavMethodHandler {
19
19
  networkFacade: NetworkFacade;
20
20
  });
21
21
  handle: (req: Request, res: Response) => Promise<void>;
22
- private getDriveFileDatabaseObject;
23
22
  }
@@ -10,20 +10,22 @@ class GETRequestHandler {
10
10
  this.dependencies = dependencies;
11
11
  }
12
12
  handle = async (req, res) => {
13
- const resource = await webdav_utils_1.WebDavUtils.getRequestedResource(req, this.dependencies.driveDatabaseManager);
13
+ const { driveDatabaseManager, driveFileService, authService, networkFacade } = this.dependencies;
14
+ const resource = await webdav_utils_1.WebDavUtils.getRequestedResource(req);
14
15
  if (req.headers['content-range'] || req.headers['range'])
15
16
  throw new errors_utils_1.NotImplementedError('Range requests not supported');
16
17
  if (resource.name.startsWith('._'))
17
18
  throw new errors_utils_1.NotFoundError('File not found');
18
19
  logger_utils_1.webdavLogger.info(`GET request received for file at ${resource.url}`);
19
- const driveFile = await this.getDriveFileDatabaseObject(resource);
20
- if (!driveFile) {
21
- throw new errors_utils_1.NotFoundError('Drive file not found');
22
- }
20
+ const driveFile = (await webdav_utils_1.WebDavUtils.getAndSearchItemFromResource({
21
+ resource,
22
+ driveDatabaseManager,
23
+ driveFileService,
24
+ }));
23
25
  logger_utils_1.webdavLogger.info(`✅ Found Drive File with uuid ${driveFile.uuid}`);
24
26
  res.set('Content-Type', 'application/octet-stream');
25
27
  res.set('Content-length', driveFile.size.toString());
26
- const { mnemonic } = await this.dependencies.authService.getAuthDetails();
28
+ const { mnemonic } = await authService.getAuthDetails();
27
29
  logger_utils_1.webdavLogger.info('✅ Network ready for download');
28
30
  const writable = new WritableStream({
29
31
  write(chunk) {
@@ -33,9 +35,9 @@ class GETRequestHandler {
33
35
  res.end();
34
36
  },
35
37
  });
36
- const [executeDownload] = await this.dependencies.networkFacade.downloadToStream(driveFile.bucket, mnemonic, driveFile.fileId, writable, {
38
+ const [executeDownload] = await networkFacade.downloadToStream(driveFile.bucket, mnemonic, driveFile.fileId, writable, {
37
39
  progressCallback: (progress) => {
38
- logger_utils_1.webdavLogger.info(`Download progress for file ${resource.name}: ${progress}%`);
40
+ logger_utils_1.webdavLogger.info(`Download progress for file ${resource.name}: ${(100 * progress).toFixed(2)}%`);
39
41
  },
40
42
  });
41
43
  logger_utils_1.webdavLogger.info('✅ Download prepared, executing...');
@@ -43,10 +45,5 @@ class GETRequestHandler {
43
45
  await executeDownload;
44
46
  logger_utils_1.webdavLogger.info('✅ Download ready, replying to client');
45
47
  };
46
- async getDriveFileDatabaseObject(resource) {
47
- const { driveDatabaseManager } = this.dependencies;
48
- const result = await driveDatabaseManager.findByRelativePath(resource.url);
49
- return result;
50
- }
51
48
  }
52
49
  exports.GETRequestHandler = GETRequestHandler;
@@ -1,5 +1,5 @@
1
1
  import { WebDavMethodHandler } from '../../types/webdav.types';
2
2
  import { Request, Response } from 'express';
3
3
  export declare class HEADRequestHandler implements WebDavMethodHandler {
4
- handle(req: Request, res: Response): Promise<void>;
4
+ handle: (_: Request, res: Response) => Promise<void>;
5
5
  }
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.HEADRequestHandler = void 0;
4
4
  class HEADRequestHandler {
5
- async handle(req, res) {
5
+ handle = async (_, res) => {
6
6
  res.status(405).send();
7
- }
7
+ };
8
8
  }
9
9
  exports.HEADRequestHandler = HEADRequestHandler;
@@ -3,7 +3,7 @@ import { WebDavMethodHandler } from '../../types/webdav.types';
3
3
  import { Request, Response } from 'express';
4
4
  import { DriveFolderService } from '../../services/drive/drive-folder.service';
5
5
  export declare class MKCOLRequestHandler implements WebDavMethodHandler {
6
- private dependencies;
6
+ private readonly dependencies;
7
7
  constructor(dependencies: {
8
8
  driveDatabaseManager: DriveDatabaseManager;
9
9
  driveFolderService: DriveFolderService;
@@ -1,13 +1,9 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.MKCOLRequestHandler = void 0;
7
4
  const webdav_utils_1 = require("../../utils/webdav.utils");
8
5
  const errors_utils_1 = require("../../utils/errors.utils");
9
6
  const logger_utils_1 = require("../../utils/logger.utils");
10
- const path_1 = __importDefault(require("path"));
11
7
  const xml_utils_1 = require("../../utils/xml.utils");
12
8
  const async_utils_1 = require("../../utils/async.utils");
13
9
  class MKCOLRequestHandler {
@@ -17,18 +13,20 @@ class MKCOLRequestHandler {
17
13
  }
18
14
  handle = async (req, res) => {
19
15
  const { driveDatabaseManager, driveFolderService } = this.dependencies;
20
- const decodedUrl = decodeURI(req.url);
21
- const resourceParsedPath = path_1.default.parse(decodedUrl);
22
- const parentPath = webdav_utils_1.WebDavUtils.getParentPath(decodedUrl);
23
- const parentResource = await driveDatabaseManager.findByRelativePath(parentPath);
24
- if (!parentResource) {
25
- throw new errors_utils_1.ConflictError(`Parent resource not found for parent path ${parentPath}`);
16
+ const resource = await webdav_utils_1.WebDavUtils.getRequestedResource(req);
17
+ logger_utils_1.webdavLogger.info('Resource received for MKCOL request', { resource });
18
+ const parentResource = await webdav_utils_1.WebDavUtils.getRequestedResource(resource.parentPath);
19
+ const parentFolderItem = (await webdav_utils_1.WebDavUtils.getAndSearchItemFromResource({
20
+ resource: parentResource,
21
+ driveDatabaseManager,
22
+ driveFolderService,
23
+ }));
24
+ if (!parentFolderItem) {
25
+ throw new errors_utils_1.ConflictError(`Parent resource not found for parent path ${resource.parentPath}`);
26
26
  }
27
- logger_utils_1.webdavLogger.info(`MKCOL request received for folder at ${req.url}`);
28
- logger_utils_1.webdavLogger.info(`Parent path: ${parentResource.id}`);
29
27
  const [createFolder] = driveFolderService.createFolder({
30
- folderName: resourceParsedPath.name,
31
- parentFolderId: parentResource.id,
28
+ folderName: resource.name,
29
+ parentFolderId: parentFolderItem.id,
32
30
  });
33
31
  const newFolder = await createFolder;
34
32
  logger_utils_1.webdavLogger.info(`✅ Folder created with UUID ${newFolder.uuid}`);
@@ -39,10 +37,11 @@ class MKCOLRequestHandler {
39
37
  bucket: newFolder.bucket,
40
38
  id: newFolder.id,
41
39
  parentId: newFolder.parentId,
40
+ parentUuid: newFolder.parentUuid,
42
41
  uuid: newFolder.uuid,
43
42
  createdAt: new Date(newFolder.createdAt),
44
43
  updatedAt: new Date(newFolder.updatedAt),
45
- });
44
+ }, resource.url);
46
45
  await async_utils_1.AsyncUtils.sleep(500);
47
46
  res.status(201).send(xml_utils_1.XMLUtils.toWebDavXML({}, {}));
48
47
  };
@@ -1,4 +1,14 @@
1
+ import { Request, Response } from 'express';
2
+ import { DriveDatabaseManager } from '../../services/database/drive-database-manager.service';
3
+ import { DriveFileService } from '../../services/drive/drive-file.service';
4
+ import { DriveFolderService } from '../../services/drive/drive-folder.service';
1
5
  import { WebDavMethodHandler } from '../../types/webdav.types';
2
6
  export declare class MOVERequestHandler implements WebDavMethodHandler {
3
- handle(): Promise<void>;
7
+ private readonly dependencies;
8
+ constructor(dependencies: {
9
+ driveDatabaseManager: DriveDatabaseManager;
10
+ driveFolderService: DriveFolderService;
11
+ driveFileService: DriveFileService;
12
+ });
13
+ handle: (req: Request, res: Response) => Promise<void>;
4
14
  }
@@ -2,9 +2,80 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MOVERequestHandler = void 0;
4
4
  const errors_utils_1 = require("../../utils/errors.utils");
5
+ const logger_utils_1 = require("../../utils/logger.utils");
6
+ const webdav_utils_1 = require("../../utils/webdav.utils");
5
7
  class MOVERequestHandler {
6
- async handle() {
7
- throw new errors_utils_1.NotImplementedError('MOVE is not implemented yet.');
8
+ dependencies;
9
+ constructor(dependencies) {
10
+ this.dependencies = dependencies;
8
11
  }
12
+ handle = async (req, res) => {
13
+ const { driveDatabaseManager, driveFolderService, driveFileService } = this.dependencies;
14
+ const resource = await webdav_utils_1.WebDavUtils.getRequestedResource(req);
15
+ logger_utils_1.webdavLogger.info('[MOVE] Resource found', { resource });
16
+ const destinationUrl = req.header('destination');
17
+ if (!destinationUrl) {
18
+ throw new errors_utils_1.NotFoundError('Destination folder not received');
19
+ }
20
+ const destinationPath = webdav_utils_1.WebDavUtils.removeHostFromURL(destinationUrl);
21
+ const destinationResource = await webdav_utils_1.WebDavUtils.getRequestedResource(destinationPath);
22
+ logger_utils_1.webdavLogger.info('[MOVE] Destination resource found', { destinationResource });
23
+ const originalDriveItem = await webdav_utils_1.WebDavUtils.getAndSearchItemFromResource({
24
+ resource,
25
+ driveDatabaseManager,
26
+ driveFolderService,
27
+ driveFileService,
28
+ });
29
+ if (destinationResource.path.dir === resource.path.dir) {
30
+ logger_utils_1.webdavLogger.info(`[MOVE] Renaming ${resource.type} with UUID ${originalDriveItem.uuid} to ${destinationResource.name}`);
31
+ const newName = destinationResource.name;
32
+ if (resource.type === 'folder') {
33
+ const folder = originalDriveItem;
34
+ await driveFolderService.renameFolder({
35
+ folderUuid: folder.uuid,
36
+ name: newName,
37
+ });
38
+ await driveDatabaseManager.createFolder(folder, destinationResource.url);
39
+ }
40
+ else if (resource.type === 'file') {
41
+ const newType = destinationResource.path.ext.replace('.', '');
42
+ const file = originalDriveItem;
43
+ await driveFileService.renameFile(file.uuid, {
44
+ plainName: newName,
45
+ type: newType,
46
+ });
47
+ await driveDatabaseManager.createFile(file, destinationResource.url);
48
+ }
49
+ }
50
+ else {
51
+ logger_utils_1.webdavLogger.info(`[MOVE] Moving ${resource.type} with UUID ${originalDriveItem.uuid} to ${destinationPath}`);
52
+ const destinationFolderResource = await webdav_utils_1.WebDavUtils.getRequestedResource(destinationResource.parentPath);
53
+ const destinationFolderItem = (await webdav_utils_1.WebDavUtils.getAndSearchItemFromResource({
54
+ resource: destinationFolderResource,
55
+ driveDatabaseManager,
56
+ driveFolderService,
57
+ }));
58
+ if (!destinationFolderItem) {
59
+ throw new errors_utils_1.ConflictError(`Destination folder resource not found for path ${destinationResource.parentPath}`);
60
+ }
61
+ if (resource.type === 'folder') {
62
+ const folder = originalDriveItem;
63
+ await driveFolderService.moveFolder({
64
+ folderUuid: folder.uuid,
65
+ destinationFolderUuid: destinationFolderItem.uuid,
66
+ });
67
+ await driveDatabaseManager.createFolder(folder, destinationPath);
68
+ }
69
+ else if (resource.type === 'file') {
70
+ const file = originalDriveItem;
71
+ await driveFileService.moveFile({
72
+ fileUuid: file.uuid,
73
+ destinationFolderUuid: destinationFolderItem.uuid,
74
+ });
75
+ await driveDatabaseManager.createFile(file, destinationPath);
76
+ }
77
+ }
78
+ res.status(204).send();
79
+ };
9
80
  }
10
81
  exports.MOVERequestHandler = MOVERequestHandler;
@@ -1,5 +1,5 @@
1
1
  import { WebDavMethodHandler } from '../../types/webdav.types';
2
2
  import { Request, Response } from 'express';
3
3
  export declare class OPTIONSRequestHandler implements WebDavMethodHandler {
4
- handle(_: Request, res: Response): Promise<void>;
4
+ handle: (_: Request, res: Response) => Promise<void>;
5
5
  }
@@ -2,10 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.OPTIONSRequestHandler = void 0;
4
4
  class OPTIONSRequestHandler {
5
- async handle(_, res) {
5
+ handle = async (_, res) => {
6
6
  res.header('Allow', 'OPTIONS, GET, HEAD, POST, PUT, DELETE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK');
7
7
  res.header('DAV', '1, 2, ordered-collections');
8
8
  res.status(200).send();
9
- }
9
+ };
10
10
  }
11
11
  exports.OPTIONSRequestHandler = OPTIONSRequestHandler;
@@ -1,21 +1,20 @@
1
- import { WebDavMethodHandler, WebDavMethodHandlerOptions } from '../../types/webdav.types';
1
+ import { WebDavMethodHandler } from '../../types/webdav.types';
2
2
  import { DriveFolderService } from '../../services/drive/drive-folder.service';
3
+ import { DriveFileService } from '../../services/drive/drive-file.service';
3
4
  import { Request, Response } from 'express';
4
5
  import { DriveDatabaseManager } from '../../services/database/drive-database-manager.service';
5
6
  export declare class PROPFINDRequestHandler implements WebDavMethodHandler {
6
- private options;
7
- private dependencies;
8
- constructor(options: WebDavMethodHandlerOptions, dependencies: {
7
+ private readonly dependencies;
8
+ constructor(dependencies: {
9
9
  driveFolderService: DriveFolderService;
10
+ driveFileService: DriveFileService;
10
11
  driveDatabaseManager: DriveDatabaseManager;
11
12
  });
12
13
  handle: (req: Request, res: Response) => Promise<void>;
13
- private getFileMetaXML;
14
- private getFolderContentXML;
15
- private getFolderChildsXMLNode;
16
- private getFolderRootXMLNode;
17
- private getFolderXMLNode;
18
- private driveFolderRootStatsToXMLNode;
19
- private driveFolderItemToXMLNode;
20
- private driveFileItemToXMLNode;
14
+ private readonly getFileMetaXML;
15
+ private readonly getFolderContentXML;
16
+ private readonly getFolderChildsXMLNode;
17
+ private readonly driveFolderRootStatsToXMLNode;
18
+ private readonly driveFolderItemToXMLNode;
19
+ private readonly driveFileItemToXMLNode;
21
20
  }