@internxt/cli 1.5.1 → 1.5.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 (79) hide show
  1. package/.env +0 -3
  2. package/README.md +30 -29
  3. package/dist/commands/add-cert.d.ts +1 -1
  4. package/dist/commands/add-cert.js +23 -23
  5. package/dist/commands/config.js +8 -3
  6. package/dist/commands/create-folder.js +10 -5
  7. package/dist/commands/delete-permanently-file.js +8 -3
  8. package/dist/commands/delete-permanently-folder.js +8 -3
  9. package/dist/commands/download-file.js +21 -16
  10. package/dist/commands/list.js +8 -3
  11. package/dist/commands/login.js +8 -6
  12. package/dist/commands/logout.js +8 -5
  13. package/dist/commands/logs.js +8 -3
  14. package/dist/commands/move-file.js +8 -3
  15. package/dist/commands/move-folder.js +8 -3
  16. package/dist/commands/rename-file.js +8 -3
  17. package/dist/commands/rename-folder.js +8 -3
  18. package/dist/commands/trash-clear.js +8 -3
  19. package/dist/commands/trash-file.js +8 -3
  20. package/dist/commands/trash-folder.js +8 -3
  21. package/dist/commands/trash-list.js +8 -3
  22. package/dist/commands/trash-restore-file.js +8 -3
  23. package/dist/commands/trash-restore-folder.js +8 -3
  24. package/dist/commands/upload-file.js +15 -9
  25. package/dist/commands/webdav-config.d.ts +1 -0
  26. package/dist/commands/webdav-config.js +18 -3
  27. package/dist/commands/webdav.js +22 -25
  28. package/dist/commands/whoami.js +8 -5
  29. package/dist/hooks/prerun/auth_check.js +13 -7
  30. package/dist/services/auth.service.js +10 -2
  31. package/dist/services/config.service.d.ts +1 -0
  32. package/dist/services/config.service.js +3 -0
  33. package/dist/types/command.types.d.ts +1 -0
  34. package/dist/types/config.types.d.ts +0 -3
  35. package/dist/utils/cli.utils.d.ts +13 -4
  36. package/dist/utils/cli.utils.js +44 -10
  37. package/dist/utils/webdav.utils.d.ts +2 -8
  38. package/dist/utils/webdav.utils.js +16 -33
  39. package/dist/utils/xml.utils.d.ts +2 -2
  40. package/dist/utils/xml.utils.js +3 -3
  41. package/dist/webdav/handlers/DELETE.handler.d.ts +0 -2
  42. package/dist/webdav/handlers/DELETE.handler.js +1 -8
  43. package/dist/webdav/handlers/GET.handler.d.ts +0 -2
  44. package/dist/webdav/handlers/GET.handler.js +1 -2
  45. package/dist/webdav/handlers/HEAD.handler.d.ts +0 -2
  46. package/dist/webdav/handlers/HEAD.handler.js +24 -19
  47. package/dist/webdav/handlers/MKCOL.handler.d.ts +0 -2
  48. package/dist/webdav/handlers/MKCOL.handler.js +14 -15
  49. package/dist/webdav/handlers/MOVE.handler.d.ts +0 -2
  50. package/dist/webdav/handlers/MOVE.handler.js +1 -7
  51. package/dist/webdav/handlers/PROPFIND.handler.d.ts +0 -2
  52. package/dist/webdav/handlers/PROPFIND.handler.js +34 -38
  53. package/dist/webdav/handlers/PUT.handler.d.ts +0 -2
  54. package/dist/webdav/handlers/PUT.handler.js +3 -7
  55. package/dist/webdav/index.js +1 -5
  56. package/dist/webdav/middewares/auth.middleware.js +10 -2
  57. package/dist/webdav/middewares/errors.middleware.js +8 -13
  58. package/dist/webdav/middewares/mkcol.middleware.d.ts +2 -0
  59. package/dist/webdav/middewares/mkcol.middleware.js +23 -0
  60. package/dist/webdav/webdav-server.d.ts +3 -4
  61. package/dist/webdav/webdav-server.js +22 -25
  62. package/oclif.manifest.json +10 -1
  63. package/package.json +24 -30
  64. package/dist/database/migrations/20240402164914-create-files.d.ts +0 -1
  65. package/dist/database/migrations/20240402164914-create-files.js +0 -55
  66. package/dist/database/migrations/20240402165418-create-folders.d.ts +0 -1
  67. package/dist/database/migrations/20240402165418-create-folders.js +0 -37
  68. package/dist/database/migrations/20241018114828-add-parent-column.d.ts +0 -1
  69. package/dist/database/migrations/20241018114828-add-parent-column.js +0 -24
  70. package/dist/services/database/drive-database-manager.service.d.ts +0 -23
  71. package/dist/services/database/drive-database-manager.service.js +0 -93
  72. package/dist/services/database/drive-file/drive-file.model.d.ts +0 -18
  73. package/dist/services/database/drive-file/drive-file.model.js +0 -80
  74. package/dist/services/database/drive-file/drive-file.repository.d.ts +0 -11
  75. package/dist/services/database/drive-file/drive-file.repository.js +0 -40
  76. package/dist/services/database/drive-folder/drive-folder.model.d.ts +0 -14
  77. package/dist/services/database/drive-folder/drive-folder.model.js +0 -65
  78. package/dist/services/database/drive-folder/drive-folder.repository.d.ts +0 -11
  79. package/dist/services/database/drive-folder/drive-folder.repository.js +0 -40
@@ -2,14 +2,16 @@ import cliProgress from 'cli-progress';
2
2
  import { Header } from 'tty-table';
3
3
  import { PromptOptions } from '../types/command.types';
4
4
  export declare class CLIUtils {
5
- static readonly clearPreviousLine: () => void;
5
+ static readonly clearPreviousLine: (jsonFlag?: boolean) => void;
6
6
  static readonly warning: (reporter: (message: string) => void, message: string) => void;
7
7
  static readonly error: (reporter: (message: string) => void, message: string) => void;
8
- static readonly doing: (message: string) => void;
9
8
  static readonly success: (reporter: (message: string) => void, message: string) => void;
10
9
  static readonly log: (reporter: (message: string) => void, message: string) => void;
11
- static readonly done: () => void;
12
- static readonly progress: (opts: cliProgress.Options) => cliProgress.SingleBar;
10
+ static readonly consoleLog: (message: string) => void;
11
+ static readonly doing: (message: string, jsonFlag?: boolean) => void;
12
+ static readonly done: (jsonFlag?: boolean) => void;
13
+ static readonly failed: (jsonFlag?: boolean) => void;
14
+ static readonly progress: (opts: cliProgress.Options, jsonFlag?: boolean) => cliProgress.SingleBar | undefined;
13
15
  static readonly table: (reporter: (message: string) => void, header: Header[], rows: object[]) => void;
14
16
  static readonly generateTableHeaderFromType: <T extends object>() => Header[];
15
17
  static readonly CommonFlags: {
@@ -34,6 +36,13 @@ export declare class CLIUtils {
34
36
  static readonly timer: () => {
35
37
  stop: () => number;
36
38
  };
39
+ static readonly catchError: ({ error, logReporter, errorReporter, command, jsonFlag, }: {
40
+ error: Error;
41
+ command?: string;
42
+ logReporter: (message: string) => void;
43
+ errorReporter: (message: string) => void;
44
+ jsonFlag?: boolean;
45
+ }) => void;
37
46
  static readonly parseEmpty: (input: string) => Promise<string>;
38
47
  }
39
48
  export declare class NoFlagProvidedError extends Error {
@@ -8,10 +8,13 @@ const core_1 = require("@oclif/core");
8
8
  const cli_progress_1 = __importDefault(require("cli-progress"));
9
9
  const tty_table_1 = __importDefault(require("tty-table"));
10
10
  const inquirer_utils_1 = require("./inquirer.utils");
11
+ const errors_utils_1 = require("./errors.utils");
11
12
  class CLIUtils {
12
- static clearPreviousLine = () => {
13
- process.stdout.write('\x1b[1A');
14
- process.stdout.clearLine(0);
13
+ static clearPreviousLine = (jsonFlag) => {
14
+ if (!jsonFlag) {
15
+ process.stdout?.write?.('\x1b[1A');
16
+ process.stdout?.clearLine?.(0);
17
+ }
15
18
  };
16
19
  static warning = (reporter, message) => {
17
20
  reporter(core_1.ux.colorize('#a67805', `⚠ Warning: ${message}`));
@@ -19,20 +22,34 @@ class CLIUtils {
19
22
  static error = (reporter, message) => {
20
23
  reporter(core_1.ux.colorize('red', `⚠ Error: ${message}`));
21
24
  };
22
- static doing = (message) => {
23
- core_1.ux.action.start(message, undefined, {});
24
- };
25
25
  static success = (reporter, message) => {
26
26
  reporter(core_1.ux.colorize('green', `✓ ${message}`));
27
27
  };
28
28
  static log = (reporter, message) => {
29
29
  reporter(`${message}`);
30
30
  };
31
- static done = () => {
32
- core_1.ux.action.stop(core_1.ux.colorize('green', 'done ✓'));
31
+ static consoleLog = (message) => {
32
+ console.log(message);
33
+ };
34
+ static doing = (message, jsonFlag) => {
35
+ if (!jsonFlag) {
36
+ core_1.ux.action.start(message, undefined, {});
37
+ }
38
+ };
39
+ static done = (jsonFlag) => {
40
+ if (!jsonFlag && core_1.ux.action.running) {
41
+ core_1.ux.action.stop(core_1.ux.colorize('green', 'done ✓'));
42
+ }
43
+ };
44
+ static failed = (jsonFlag) => {
45
+ if (!jsonFlag && core_1.ux.action.running) {
46
+ core_1.ux.action.stop(core_1.ux.colorize('red', 'failed ✕'));
47
+ }
33
48
  };
34
- static progress = (opts) => {
35
- return new cli_progress_1.default.SingleBar({ noTTYOutput: Boolean(!process.stdin.isTTY), ...opts }, cli_progress_1.default.Presets.shades_classic);
49
+ static progress = (opts, jsonFlag) => {
50
+ if (!jsonFlag) {
51
+ return new cli_progress_1.default.SingleBar({ noTTYOutput: Boolean(!process.stdin.isTTY), ...opts }, cli_progress_1.default.Presets.shades_classic);
52
+ }
36
53
  };
37
54
  static table = (reporter, header, rows) => {
38
55
  const table = (0, tty_table_1.default)(header, rows);
@@ -113,6 +130,23 @@ class CLIUtils {
113
130
  },
114
131
  };
115
132
  };
133
+ static catchError = ({ error, logReporter, errorReporter, command, jsonFlag, }) => {
134
+ let message;
135
+ if ('message' in error && error.message.trim().length > 0) {
136
+ message = error.message;
137
+ }
138
+ else {
139
+ message = JSON.stringify(error);
140
+ }
141
+ CLIUtils.failed(jsonFlag);
142
+ if (jsonFlag) {
143
+ CLIUtils.consoleLog(JSON.stringify({ success: false, message }));
144
+ }
145
+ else {
146
+ errors_utils_1.ErrorUtils.report(errorReporter, error, { command });
147
+ CLIUtils.error(logReporter, message);
148
+ }
149
+ };
116
150
  static parseEmpty = async (input) => (input.trim().length === 0 ? ' ' : input);
117
151
  }
118
152
  exports.CLIUtils = CLIUtils;
@@ -1,21 +1,15 @@
1
1
  import { Request } from 'express';
2
2
  import { WebDavRequestedResource } from '../types/webdav.types';
3
- import { DriveFile } from '../services/database/drive-file/drive-file.domain';
4
- import { DriveFolder } from '../services/database/drive-folder/drive-folder.domain';
5
- import { DriveDatabaseManager } from '../services/database/drive-database-manager.service';
6
3
  import { DriveFolderService } from '../services/drive/drive-folder.service';
7
4
  import { DriveFileService } from '../services/drive/drive-file.service';
8
5
  import { DriveFileItem, DriveFolderItem } from '../types/drive.types';
9
6
  export declare class WebDavUtils {
10
7
  static joinURL(...pathComponents: string[]): string;
11
8
  static removeHostFromURL(completeURL: string): string;
12
- static getRequestedResource(urlObject: string | Request): Promise<WebDavRequestedResource>;
13
- static getDatabaseItemFromResource(resource: WebDavRequestedResource, driveDatabaseManager: DriveDatabaseManager): Promise<DriveFileItem | DriveFolderItem | null>;
14
- static setDatabaseItem(type: 'file' | 'folder', driveItem: DriveFileItem | DriveFolderItem, driveDatabaseManager: DriveDatabaseManager, relativePath: string): Promise<DriveFolder | DriveFile | undefined>;
9
+ static getRequestedResource(urlObject: string | Request, decodeUri?: boolean): Promise<WebDavRequestedResource>;
15
10
  static getDriveItemFromResource(resource: WebDavRequestedResource, driveFolderService?: DriveFolderService, driveFileService?: DriveFileService): Promise<DriveFileItem | DriveFolderItem | undefined>;
16
- static getAndSearchItemFromResource({ resource, driveDatabaseManager, driveFolderService, driveFileService, }: {
11
+ static getAndSearchItemFromResource({ resource, driveFolderService, driveFileService, }: {
17
12
  resource: WebDavRequestedResource;
18
- driveDatabaseManager: DriveDatabaseManager;
19
13
  driveFolderService?: DriveFolderService;
20
14
  driveFileService?: DriveFileService;
21
15
  }): Promise<DriveFileItem | DriveFolderItem>;
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.WebDavUtils = void 0;
7
7
  const node_path_1 = __importDefault(require("node:path"));
8
8
  const errors_utils_1 = require("./errors.utils");
9
- const logger_utils_1 = require("./logger.utils");
10
9
  class WebDavUtils {
11
10
  static joinURL(...pathComponents) {
12
11
  return node_path_1.default.posix.join(...pathComponents);
@@ -21,7 +20,7 @@ class WebDavUtils {
21
20
  url = '/'.concat(url);
22
21
  return url;
23
22
  }
24
- static async getRequestedResource(urlObject) {
23
+ static async getRequestedResource(urlObject, decodeUri = true) {
25
24
  let requestUrl;
26
25
  if (typeof urlObject === 'string') {
27
26
  requestUrl = urlObject;
@@ -29,7 +28,7 @@ class WebDavUtils {
29
28
  else {
30
29
  requestUrl = urlObject.url;
31
30
  }
32
- const decodedUrl = decodeURIComponent(requestUrl).replaceAll('/./', '/');
31
+ const decodedUrl = (decodeUri ? decodeURIComponent(requestUrl) : requestUrl).replaceAll('/./', '/');
33
32
  const parsedPath = node_path_1.default.parse(decodedUrl);
34
33
  let parentPath = node_path_1.default.dirname(decodedUrl);
35
34
  if (!parentPath.startsWith('/'))
@@ -56,46 +55,30 @@ class WebDavUtils {
56
55
  };
57
56
  }
58
57
  }
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
58
  static async getDriveItemFromResource(resource, driveFolderService, driveFileService) {
78
59
  let item = undefined;
79
60
  if (resource.type === 'folder') {
80
- item = await driveFolderService?.getFolderMetadataByPath(resource.url);
61
+ try {
62
+ item = await driveFolderService?.getFolderMetadataByPath(resource.url);
63
+ }
64
+ catch (error) {
65
+ if (error.status === 404) {
66
+ throw new errors_utils_1.ConflictError(`Resource not found on Internxt Drive at ${resource.url}`);
67
+ }
68
+ throw error;
69
+ }
81
70
  }
82
71
  if (resource.type === 'file') {
83
72
  item = await driveFileService?.getFileMetadataByPath(resource.url);
84
73
  }
85
74
  return item;
86
75
  }
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);
76
+ static async getAndSearchItemFromResource({ resource, driveFolderService, driveFileService, }) {
77
+ const driveItem = await this.getDriveItemFromResource(resource, driveFolderService, driveFileService);
78
+ if (!driveItem) {
79
+ throw new errors_utils_1.NotFoundError(`Resource not found on Internxt Drive at ${resource.url}`);
97
80
  }
98
- return databaseItem;
81
+ return driveItem;
99
82
  }
100
83
  }
101
84
  exports.WebDavUtils = WebDavUtils;
@@ -2,8 +2,8 @@ import { X2jOptions, XmlBuilderOptions } from 'fast-xml-parser';
2
2
  export declare class XMLUtils {
3
3
  static readonly DEFAULT_NAMESPACE_LETTER = "D";
4
4
  static toJSON(xml: string, options?: X2jOptions): any;
5
- static toXML(object: object, options?: XmlBuilderOptions): any;
6
- static toWebDavXML(object: object, options: XmlBuilderOptions): string;
5
+ static toXML(object: object, options?: XmlBuilderOptions): string;
6
+ static toWebDavXML(object: object, options: XmlBuilderOptions, rootObject?: string): string;
7
7
  static addDefaultNamespace(key: string): string;
8
8
  static encodeWebDavUri(uri: string): string;
9
9
  }
@@ -12,12 +12,12 @@ class XMLUtils {
12
12
  const builder = new fast_xml_parser_1.XMLBuilder(options);
13
13
  return builder.build(object);
14
14
  }
15
- static toWebDavXML(object, options) {
15
+ static toWebDavXML(object, options, rootObject = 'multistatus') {
16
16
  const xmlContent = this.toXML(object, options);
17
17
  return ('<?xml version="1.0" encoding="utf-8" ?>' +
18
- `<${XMLUtils.addDefaultNamespace('multistatus')} xmlns:${XMLUtils.DEFAULT_NAMESPACE_LETTER}="DAV:">` +
18
+ `<${XMLUtils.addDefaultNamespace(rootObject)} xmlns:${XMLUtils.DEFAULT_NAMESPACE_LETTER}="DAV:">` +
19
19
  `${xmlContent}` +
20
- `</${XMLUtils.addDefaultNamespace('multistatus')}>`);
20
+ `</${XMLUtils.addDefaultNamespace(rootObject)}>`);
21
21
  }
22
22
  static addDefaultNamespace(key) {
23
23
  return `${XMLUtils.DEFAULT_NAMESPACE_LETTER}:${key}`;
@@ -1,13 +1,11 @@
1
1
  import { Request, Response } from 'express';
2
2
  import { WebDavMethodHandler } from '../../types/webdav.types';
3
- import { DriveDatabaseManager } from '../../services/database/drive-database-manager.service';
4
3
  import { TrashService } from '../../services/drive/trash.service';
5
4
  import { DriveFileService } from '../../services/drive/drive-file.service';
6
5
  import { DriveFolderService } from '../../services/drive/drive-folder.service';
7
6
  export declare class DELETERequestHandler implements WebDavMethodHandler {
8
7
  private readonly dependencies;
9
8
  constructor(dependencies: {
10
- driveDatabaseManager: DriveDatabaseManager;
11
9
  trashService: TrashService;
12
10
  driveFileService: DriveFileService;
13
11
  driveFolderService: DriveFolderService;
@@ -9,12 +9,11 @@ class DELETERequestHandler {
9
9
  this.dependencies = dependencies;
10
10
  }
11
11
  handle = async (req, res) => {
12
- const { driveDatabaseManager, driveFileService, driveFolderService, trashService } = this.dependencies;
12
+ const { driveFileService, driveFolderService, trashService } = this.dependencies;
13
13
  const resource = await webdav_utils_1.WebDavUtils.getRequestedResource(req);
14
14
  logger_utils_1.webdavLogger.info(`[DELETE] Request received for ${resource.type} at ${resource.url}`);
15
15
  const driveItem = await webdav_utils_1.WebDavUtils.getAndSearchItemFromResource({
16
16
  resource,
17
- driveDatabaseManager,
18
17
  driveFolderService,
19
18
  driveFileService: driveFileService,
20
19
  });
@@ -22,12 +21,6 @@ class DELETERequestHandler {
22
21
  await trashService.trashItems({
23
22
  items: [{ type: resource.type, uuid: driveItem.uuid }],
24
23
  });
25
- if (resource.type === 'folder') {
26
- await driveDatabaseManager.deleteFolderById(driveItem.id);
27
- }
28
- else if (resource.type === 'file') {
29
- await driveDatabaseManager.deleteFileById(driveItem.id);
30
- }
31
24
  res.status(204).send();
32
25
  const type = resource.type.charAt(0).toUpperCase() + resource.type.substring(1);
33
26
  logger_utils_1.webdavLogger.info(`[DELETE] [${driveItem.uuid}] ${type} trashed successfully`);
@@ -1,7 +1,6 @@
1
1
  import { WebDavMethodHandler } from '../../types/webdav.types';
2
2
  import { Request, Response } from 'express';
3
3
  import { DriveFileService } from '../../services/drive/drive-file.service';
4
- import { DriveDatabaseManager } from '../../services/database/drive-database-manager.service';
5
4
  import { NetworkFacade } from '../../services/network/network-facade.service';
6
5
  import { DownloadService } from '../../services/network/download.service';
7
6
  import { CryptoService } from '../../services/crypto.service';
@@ -10,7 +9,6 @@ export declare class GETRequestHandler implements WebDavMethodHandler {
10
9
  private readonly dependencies;
11
10
  constructor(dependencies: {
12
11
  driveFileService: DriveFileService;
13
- driveDatabaseManager: DriveDatabaseManager;
14
12
  downloadService: DownloadService;
15
13
  cryptoService: CryptoService;
16
14
  authService: AuthService;
@@ -11,7 +11,7 @@ class GETRequestHandler {
11
11
  this.dependencies = dependencies;
12
12
  }
13
13
  handle = async (req, res) => {
14
- const { driveDatabaseManager, driveFileService, authService, networkFacade } = this.dependencies;
14
+ const { driveFileService, authService, networkFacade } = this.dependencies;
15
15
  const resource = await webdav_utils_1.WebDavUtils.getRequestedResource(req);
16
16
  if (resource.name.startsWith('._'))
17
17
  throw new errors_utils_1.NotFoundError('File not found');
@@ -20,7 +20,6 @@ class GETRequestHandler {
20
20
  logger_utils_1.webdavLogger.info(`[GET] Request received for ${resource.type} at ${resource.url}`);
21
21
  const driveFile = (await webdav_utils_1.WebDavUtils.getAndSearchItemFromResource({
22
22
  resource,
23
- driveDatabaseManager,
24
23
  driveFileService,
25
24
  }));
26
25
  logger_utils_1.webdavLogger.info(`[GET] [${driveFile.uuid}] Found Drive File`);
@@ -1,12 +1,10 @@
1
1
  import { Request, Response } from 'express';
2
2
  import { WebDavMethodHandler } from '../../types/webdav.types';
3
3
  import { DriveFileService } from '../../services/drive/drive-file.service';
4
- import { DriveDatabaseManager } from '../../services/database/drive-database-manager.service';
5
4
  export declare class HEADRequestHandler implements WebDavMethodHandler {
6
5
  private readonly dependencies;
7
6
  constructor(dependencies: {
8
7
  driveFileService: DriveFileService;
9
- driveDatabaseManager: DriveDatabaseManager;
10
8
  });
11
9
  handle: (req: Request, res: Response) => Promise<void>;
12
10
  }
@@ -10,32 +10,37 @@ class HEADRequestHandler {
10
10
  this.dependencies = dependencies;
11
11
  }
12
12
  handle = async (req, res) => {
13
- const { driveDatabaseManager, driveFileService } = this.dependencies;
13
+ const { driveFileService } = this.dependencies;
14
14
  const resource = await webdav_utils_1.WebDavUtils.getRequestedResource(req);
15
15
  if (resource.type === 'folder') {
16
16
  res.status(200).send();
17
17
  return;
18
18
  }
19
19
  logger_utils_1.webdavLogger.info(`[HEAD] Request received for ${resource.type} at ${resource.url}`);
20
- const driveFile = (await webdav_utils_1.WebDavUtils.getAndSearchItemFromResource({
21
- resource,
22
- driveDatabaseManager,
23
- driveFileService,
24
- }));
25
- logger_utils_1.webdavLogger.info(`[HEAD] [${driveFile.uuid}] Found Drive File`);
26
- const range = req.headers['range'];
27
- const rangeOptions = network_utils_1.NetworkUtils.parseRangeHeader({
28
- range,
29
- totalFileSize: driveFile.size,
30
- });
31
- let contentLength = driveFile.size;
32
- if (rangeOptions) {
33
- logger_utils_1.webdavLogger.info(`[HEAD] [${driveFile.uuid}] Range request received:`, { rangeOptions });
34
- contentLength = rangeOptions.rangeSize;
20
+ try {
21
+ const driveFile = (await webdav_utils_1.WebDavUtils.getAndSearchItemFromResource({
22
+ resource,
23
+ driveFileService,
24
+ }));
25
+ logger_utils_1.webdavLogger.info(`[HEAD] [${driveFile.uuid}] Found Drive File`);
26
+ const range = req.headers['range'];
27
+ const rangeOptions = network_utils_1.NetworkUtils.parseRangeHeader({
28
+ range,
29
+ totalFileSize: driveFile.size,
30
+ });
31
+ let contentLength = driveFile.size;
32
+ if (rangeOptions) {
33
+ logger_utils_1.webdavLogger.info(`[HEAD] [${driveFile.uuid}] Range request received:`, { rangeOptions });
34
+ contentLength = rangeOptions.rangeSize;
35
+ }
36
+ res.header('Content-Type', 'application/octet-stream');
37
+ res.header('Content-length', contentLength.toString());
38
+ res.status(200).send();
39
+ }
40
+ catch {
41
+ res.header('Content-Type', 'application/octet-stream');
42
+ res.status(200).send();
35
43
  }
36
- res.header('Content-Type', 'application/octet-stream');
37
- res.header('Content-length', contentLength.toString());
38
- res.status(200).send();
39
44
  };
40
45
  }
41
46
  exports.HEADRequestHandler = HEADRequestHandler;
@@ -1,11 +1,9 @@
1
- import { DriveDatabaseManager } from '../../services/database/drive-database-manager.service';
2
1
  import { WebDavMethodHandler } from '../../types/webdav.types';
3
2
  import { Request, Response } from 'express';
4
3
  import { DriveFolderService } from '../../services/drive/drive-folder.service';
5
4
  export declare class MKCOLRequestHandler implements WebDavMethodHandler {
6
5
  private readonly dependencies;
7
6
  constructor(dependencies: {
8
- driveDatabaseManager: DriveDatabaseManager;
9
7
  driveFolderService: DriveFolderService;
10
8
  });
11
9
  handle: (req: Request, res: Response) => Promise<void>;
@@ -5,39 +5,38 @@ const webdav_utils_1 = require("../../utils/webdav.utils");
5
5
  const logger_utils_1 = require("../../utils/logger.utils");
6
6
  const xml_utils_1 = require("../../utils/xml.utils");
7
7
  const async_utils_1 = require("../../utils/async.utils");
8
+ const errors_utils_1 = require("../../utils/errors.utils");
8
9
  class MKCOLRequestHandler {
9
10
  dependencies;
10
11
  constructor(dependencies) {
11
12
  this.dependencies = dependencies;
12
13
  }
13
14
  handle = async (req, res) => {
14
- const { driveDatabaseManager, driveFolderService } = this.dependencies;
15
+ const { driveFolderService } = this.dependencies;
15
16
  const resource = await webdav_utils_1.WebDavUtils.getRequestedResource(req);
16
17
  logger_utils_1.webdavLogger.info(`[MKCOL] Request received for ${resource.type} at ${resource.url}`);
17
- const parentResource = await webdav_utils_1.WebDavUtils.getRequestedResource(resource.parentPath);
18
+ const parentResource = await webdav_utils_1.WebDavUtils.getRequestedResource(resource.parentPath, false);
18
19
  const parentFolderItem = (await webdav_utils_1.WebDavUtils.getAndSearchItemFromResource({
19
20
  resource: parentResource,
20
- driveDatabaseManager,
21
21
  driveFolderService,
22
22
  }));
23
+ let folderAlreadyExists = true;
24
+ try {
25
+ await driveFolderService.getFolderMetadataByPath(resource.url);
26
+ }
27
+ catch {
28
+ folderAlreadyExists = false;
29
+ }
30
+ if (folderAlreadyExists) {
31
+ logger_utils_1.webdavLogger.info(`[MKCOL] ❌ Folder '${resource.url}' already exists`);
32
+ throw new errors_utils_1.MethodNotAllowed('Folder already exists');
33
+ }
23
34
  const [createFolder] = driveFolderService.createFolder({
24
35
  plainName: resource.path.base,
25
36
  parentFolderUuid: parentFolderItem.uuid,
26
37
  });
27
38
  const newFolder = await createFolder;
28
39
  logger_utils_1.webdavLogger.info(`[MKCOL] ✅ Folder created with UUID ${newFolder.uuid}`);
29
- await driveDatabaseManager.createFolder({
30
- name: newFolder.plainName,
31
- status: 'EXISTS',
32
- encryptedName: newFolder.name,
33
- bucket: newFolder.bucket,
34
- id: newFolder.id,
35
- parentId: newFolder.parentId,
36
- parentUuid: newFolder.parentUuid,
37
- uuid: newFolder.uuid,
38
- createdAt: new Date(newFolder.createdAt),
39
- updatedAt: new Date(newFolder.updatedAt),
40
- }, resource.url);
41
40
  await async_utils_1.AsyncUtils.sleep(500);
42
41
  res.status(201).send(xml_utils_1.XMLUtils.toWebDavXML({}, {}));
43
42
  };
@@ -1,12 +1,10 @@
1
1
  import { Request, Response } from 'express';
2
- import { DriveDatabaseManager } from '../../services/database/drive-database-manager.service';
3
2
  import { DriveFileService } from '../../services/drive/drive-file.service';
4
3
  import { DriveFolderService } from '../../services/drive/drive-folder.service';
5
4
  import { WebDavMethodHandler } from '../../types/webdav.types';
6
5
  export declare class MOVERequestHandler implements WebDavMethodHandler {
7
6
  private readonly dependencies;
8
7
  constructor(dependencies: {
9
- driveDatabaseManager: DriveDatabaseManager;
10
8
  driveFolderService: DriveFolderService;
11
9
  driveFileService: DriveFileService;
12
10
  });
@@ -10,7 +10,7 @@ class MOVERequestHandler {
10
10
  this.dependencies = dependencies;
11
11
  }
12
12
  handle = async (req, res) => {
13
- const { driveDatabaseManager, driveFolderService, driveFileService } = this.dependencies;
13
+ const { driveFolderService, driveFileService } = this.dependencies;
14
14
  const resource = await webdav_utils_1.WebDavUtils.getRequestedResource(req);
15
15
  logger_utils_1.webdavLogger.info(`[MOVE] Request received for ${resource.type} at ${resource.url}`);
16
16
  const destinationUrl = req.header('destination');
@@ -22,7 +22,6 @@ class MOVERequestHandler {
22
22
  logger_utils_1.webdavLogger.info('[MOVE] Destination resource found', { destinationResource });
23
23
  const originalDriveItem = await webdav_utils_1.WebDavUtils.getAndSearchItemFromResource({
24
24
  resource,
25
- driveDatabaseManager,
26
25
  driveFolderService,
27
26
  driveFileService,
28
27
  });
@@ -35,7 +34,6 @@ class MOVERequestHandler {
35
34
  folderUuid: folder.uuid,
36
35
  name: newName,
37
36
  });
38
- await driveDatabaseManager.createFolder(folder, destinationResource.url);
39
37
  }
40
38
  else if (resource.type === 'file') {
41
39
  const newType = destinationResource.path.ext.replace('.', '');
@@ -44,7 +42,6 @@ class MOVERequestHandler {
44
42
  plainName: newName,
45
43
  type: newType,
46
44
  });
47
- await driveDatabaseManager.createFile(file, destinationResource.url);
48
45
  }
49
46
  }
50
47
  else {
@@ -52,7 +49,6 @@ class MOVERequestHandler {
52
49
  const destinationFolderResource = await webdav_utils_1.WebDavUtils.getRequestedResource(destinationResource.parentPath);
53
50
  const destinationFolderItem = (await webdav_utils_1.WebDavUtils.getAndSearchItemFromResource({
54
51
  resource: destinationFolderResource,
55
- driveDatabaseManager,
56
52
  driveFolderService,
57
53
  }));
58
54
  if (resource.type === 'folder') {
@@ -61,7 +57,6 @@ class MOVERequestHandler {
61
57
  folderUuid: folder.uuid,
62
58
  destinationFolderUuid: destinationFolderItem.uuid,
63
59
  });
64
- await driveDatabaseManager.createFolder(folder, destinationPath);
65
60
  }
66
61
  else if (resource.type === 'file') {
67
62
  const file = originalDriveItem;
@@ -69,7 +64,6 @@ class MOVERequestHandler {
69
64
  fileUuid: file.uuid,
70
65
  destinationFolderUuid: destinationFolderItem.uuid,
71
66
  });
72
- await driveDatabaseManager.createFile(file, destinationPath);
73
67
  }
74
68
  }
75
69
  res.status(204).send();
@@ -2,13 +2,11 @@ import { WebDavMethodHandler } from '../../types/webdav.types';
2
2
  import { DriveFolderService } from '../../services/drive/drive-folder.service';
3
3
  import { DriveFileService } from '../../services/drive/drive-file.service';
4
4
  import { Request, Response } from 'express';
5
- import { DriveDatabaseManager } from '../../services/database/drive-database-manager.service';
6
5
  export declare class PROPFINDRequestHandler implements WebDavMethodHandler {
7
6
  private readonly dependencies;
8
7
  constructor(dependencies: {
9
8
  driveFolderService: DriveFolderService;
10
9
  driveFileService: DriveFileService;
11
- driveDatabaseManager: DriveDatabaseManager;
12
10
  });
13
11
  handle: (req: Request, res: Response) => Promise<void>;
14
12
  private readonly getFileMetaXML;