Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / packages / docs-core / lib / UseCase / DuplicateDocument.ts
blob3540ddc0691a7aa6cc604018be0b6a26097a0ab6
1 import type { DocumentNodeMeta, DriveCompat } from '@proton/drive-store'
2 import { Result } from '@proton/docs-shared'
4 import type { NodeMeta } from '@proton/drive-store'
5 import type { SeedInitialCommit } from './SeedInitialCommit'
6 import type { GetDocumentMeta } from './GetDocumentMeta'
7 import { getErrorString } from '../Util/GetErrorString'
8 import type { DocumentMetaInterface } from '@proton/docs-shared'
9 import { getPlatformFriendlyDateForFileName } from '../Util/PlatformFriendlyFileNameDate'
11 export class DuplicateDocument {
12   constructor(
13     private driveCompat: DriveCompat,
14     private getDocumentMeta: GetDocumentMeta,
15     private seedInitialCommit: SeedInitialCommit,
16   ) {}
18   /** Execute for a private document */
19   async executePrivate(
20     nodeMeta: NodeMeta,
21     docMeta: DocumentMetaInterface,
22     state: Uint8Array,
23   ): Promise<Result<DocumentNodeMeta>> {
24     try {
25       const node = await this.driveCompat.getNode(nodeMeta)
27       const parentMeta: NodeMeta = node.parentNodeId
28         ? {
29             volumeId: node.volumeId,
30             linkId: node.parentNodeId,
31           }
32         : await this.driveCompat.getMyFilesNodeMeta()
34       const date = getPlatformFriendlyDateForFileName()
35       const newName = `${docMeta.name} (copy ${date})`
37       return await this.genericDuplicate(newName, parentMeta, state)
38     } catch (error) {
39       return Result.fail(getErrorString(error) ?? 'Failed to duplicate document')
40     }
41   }
43   /** Execute for a public document */
44   async executePublic(originalName: string, state: Uint8Array): Promise<Result<DocumentNodeMeta>> {
45     try {
46       const parentMeta: NodeMeta = await this.driveCompat.getMyFilesNodeMeta()
47       return await this.genericDuplicate(originalName, parentMeta, state)
48     } catch (error) {
49       return Result.fail(getErrorString(error) ?? 'Failed to duplicate document')
50     }
51   }
53   private async genericDuplicate(
54     newName: string,
55     parentMeta: NodeMeta,
56     state: Uint8Array,
57   ): Promise<Result<DocumentNodeMeta>> {
58     try {
59       const name = await this.driveCompat.findAvailableNodeName(parentMeta, newName)
60       const shellResult = await this.driveCompat.createDocumentNode(parentMeta, name)
62       const documentMetaResult = await this.getDocumentMeta.execute({
63         volumeId: shellResult.volumeId,
64         linkId: shellResult.linkId,
65       })
66       if (documentMetaResult.isFailed()) {
67         return Result.fail(documentMetaResult.getError())
68       }
70       const newNodeMeta = {
71         volumeId: shellResult.volumeId,
72         linkId: shellResult.linkId,
73       }
75       const commitResult = await this.seedInitialCommit.execute(newNodeMeta, state, shellResult.keys)
76       if (commitResult.isFailed()) {
77         return Result.fail(commitResult.getError())
78       }
80       return Result.ok(shellResult)
81     } catch (error) {
82       return Result.fail(getErrorString(error) ?? 'Failed to duplicate document')
83     }
84   }