@protontech/drive-sdk 0.9.1 → 0.9.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 (65) hide show
  1. package/dist/crypto/interface.d.ts +6 -27
  2. package/dist/crypto/interface.js.map +1 -1
  3. package/dist/crypto/openPGPCrypto.d.ts +25 -25
  4. package/dist/crypto/openPGPCrypto.js +12 -24
  5. package/dist/crypto/openPGPCrypto.js.map +1 -1
  6. package/dist/diagnostic/diagnostic.d.ts +3 -1
  7. package/dist/diagnostic/diagnostic.js +8 -0
  8. package/dist/diagnostic/diagnostic.js.map +1 -1
  9. package/dist/diagnostic/interface.d.ts +11 -0
  10. package/dist/diagnostic/sdkDiagnosticMain.d.ts +2 -1
  11. package/dist/diagnostic/sdkDiagnosticMain.js +28 -0
  12. package/dist/diagnostic/sdkDiagnosticMain.js.map +1 -1
  13. package/dist/diagnostic/sdkDiagnosticPhotos.d.ts +2 -1
  14. package/dist/diagnostic/sdkDiagnosticPhotos.js +31 -0
  15. package/dist/diagnostic/sdkDiagnosticPhotos.js.map +1 -1
  16. package/dist/internal/apiService/driveTypes.d.ts +492 -384
  17. package/dist/internal/apiService/transformers.d.ts +10 -1
  18. package/dist/internal/apiService/transformers.js +13 -1
  19. package/dist/internal/apiService/transformers.js.map +1 -1
  20. package/dist/internal/nodes/apiService.d.ts +1 -1
  21. package/dist/internal/nodes/apiService.js.map +1 -1
  22. package/dist/internal/nodes/cryptoService.test.js +1 -1
  23. package/dist/internal/nodes/cryptoService.test.js.map +1 -1
  24. package/dist/internal/nodes/nodesAccess.d.ts +1 -0
  25. package/dist/internal/nodes/nodesAccess.js +6 -2
  26. package/dist/internal/nodes/nodesAccess.js.map +1 -1
  27. package/dist/internal/sharing/apiService.js +10 -2
  28. package/dist/internal/sharing/apiService.js.map +1 -1
  29. package/dist/internal/sharingPublic/index.d.ts +3 -3
  30. package/dist/internal/sharingPublic/index.js +8 -8
  31. package/dist/internal/sharingPublic/index.js.map +1 -1
  32. package/dist/internal/sharingPublic/nodes.d.ts +30 -2
  33. package/dist/internal/sharingPublic/nodes.js +47 -1
  34. package/dist/internal/sharingPublic/nodes.js.map +1 -1
  35. package/dist/internal/sharingPublic/session/apiService.js +1 -1
  36. package/dist/internal/sharingPublic/session/apiService.js.map +1 -1
  37. package/dist/internal/sharingPublic/session/interface.d.ts +1 -1
  38. package/dist/internal/sharingPublic/session/manager.d.ts +2 -0
  39. package/dist/internal/sharingPublic/session/manager.js +6 -2
  40. package/dist/internal/sharingPublic/session/manager.js.map +1 -1
  41. package/dist/protonDriveClient.js +2 -1
  42. package/dist/protonDriveClient.js.map +1 -1
  43. package/dist/protonDrivePublicLinkClient.d.ts +3 -2
  44. package/dist/protonDrivePublicLinkClient.js +2 -2
  45. package/dist/protonDrivePublicLinkClient.js.map +1 -1
  46. package/package.json +1 -1
  47. package/src/crypto/interface.ts +6 -39
  48. package/src/crypto/openPGPCrypto.ts +60 -69
  49. package/src/diagnostic/diagnostic.ts +11 -1
  50. package/src/diagnostic/interface.ts +13 -0
  51. package/src/diagnostic/sdkDiagnosticMain.ts +41 -2
  52. package/src/diagnostic/sdkDiagnosticPhotos.ts +47 -2
  53. package/src/internal/apiService/driveTypes.ts +492 -384
  54. package/src/internal/apiService/transformers.ts +17 -1
  55. package/src/internal/nodes/apiService.ts +1 -1
  56. package/src/internal/nodes/cryptoService.test.ts +1 -1
  57. package/src/internal/nodes/nodesAccess.ts +7 -2
  58. package/src/internal/sharing/apiService.ts +11 -3
  59. package/src/internal/sharingPublic/index.ts +12 -2
  60. package/src/internal/sharingPublic/nodes.ts +63 -4
  61. package/src/internal/sharingPublic/session/apiService.ts +1 -1
  62. package/src/internal/sharingPublic/session/interface.ts +1 -1
  63. package/src/internal/sharingPublic/session/manager.ts +7 -2
  64. package/src/protonDriveClient.ts +2 -1
  65. package/src/protonDrivePublicLinkClient.ts +4 -0
@@ -1,4 +1,5 @@
1
1
  import { c } from 'ttag';
2
+
2
3
  import { OpenPGPCrypto, PrivateKey, PublicKey, SessionKey, VERIFICATION_STATUS } from './interface';
3
4
  import { uint8ArrayToBase64String } from './utils';
4
5
 
@@ -10,29 +11,39 @@ export interface OpenPGPCryptoProxy {
10
11
  generateKey: (options: { userIDs: { name: string }[]; type: 'ecc'; curve: 'ed25519Legacy' }) => Promise<PrivateKey>;
11
12
  exportPrivateKey: (options: { privateKey: PrivateKey; passphrase: string | null }) => Promise<string>;
12
13
  importPrivateKey: (options: { armoredKey: string; passphrase: string | null }) => Promise<PrivateKey>;
13
- generateSessionKey: (options: { recipientKeys: PrivateKey[] }) => Promise<SessionKey>;
14
+ generateSessionKey: (options: { recipientKeys: PublicKey[] }) => Promise<SessionKey>;
14
15
  encryptSessionKey: (
15
- options: SessionKey & { format: 'binary'; encryptionKeys?: PublicKey | PublicKey[]; passwords?: string[] },
16
+ options: SessionKey & {
17
+ format: 'binary';
18
+ encryptionKeys?: PublicKey | PublicKey[];
19
+ passwords?: string[];
20
+ },
16
21
  ) => Promise<Uint8Array>;
17
22
  decryptSessionKey: (options: {
18
23
  armoredMessage?: string;
19
24
  binaryMessage?: Uint8Array;
20
25
  decryptionKeys: PrivateKey | PrivateKey[];
21
26
  }) => Promise<SessionKey | undefined>;
22
- encryptMessage: (options: {
23
- format?: 'armored' | 'binary';
27
+ encryptMessage: <Format extends 'armored' | 'binary' = 'armored', Detached extends boolean = false>(options: {
28
+ format?: Format;
24
29
  binaryData: Uint8Array;
25
30
  sessionKey?: SessionKey;
26
- encryptionKeys: PrivateKey[];
31
+ encryptionKeys: PublicKey[];
27
32
  signingKeys?: PrivateKey;
28
- detached?: boolean;
33
+ detached?: Detached;
29
34
  compress?: boolean;
30
- }) => Promise<{
31
- message: string | Uint8Array;
32
- signature?: string | Uint8Array;
33
- }>;
34
- decryptMessage: (options: {
35
- format: 'utf8' | 'binary';
35
+ }) => Promise<
36
+ Detached extends true
37
+ ? {
38
+ message: Format extends 'binary' ? Uint8Array : string;
39
+ signature: Format extends 'binary' ? Uint8Array : string;
40
+ }
41
+ : {
42
+ message: Format extends 'binary' ? Uint8Array : string;
43
+ }
44
+ >;
45
+ decryptMessage: <Format extends 'utf8' | 'binary' = 'utf8'>(options: {
46
+ format: Format;
36
47
  armoredMessage?: string;
37
48
  binaryMessage?: Uint8Array;
38
49
  armoredSignature?: string;
@@ -42,20 +53,17 @@ export interface OpenPGPCryptoProxy {
42
53
  decryptionKeys?: PrivateKey | PrivateKey[];
43
54
  verificationKeys?: PublicKey | PublicKey[];
44
55
  }) => Promise<{
45
- data: Uint8Array | string;
46
- // pmcrypto 8.3.0 changes `verified` to `verificationStatus`.
47
- // Web clients are using newer pmcrypto, but CLI is using older version due to build issues with Bun.
48
- verified?: VERIFICATION_STATUS;
49
- verificationStatus?: VERIFICATION_STATUS;
56
+ data: Format extends 'binary' ? Uint8Array : string;
57
+ verificationStatus: VERIFICATION_STATUS;
50
58
  verificationErrors?: Error[];
51
59
  }>;
52
- signMessage: (options: {
53
- format: 'binary' | 'armored';
60
+ signMessage: <Format extends 'binary' | 'armored' = 'armored'>(options: {
61
+ format: Format;
54
62
  binaryData: Uint8Array;
55
63
  signingKeys: PrivateKey | PrivateKey[];
56
64
  detached: boolean;
57
65
  signatureContext?: { critical: boolean; value: string };
58
- }) => Promise<Uint8Array | string>;
66
+ }) => Promise<Format extends 'binary' ? Uint8Array : string>;
59
67
  verifyMessage: (options: {
60
68
  binaryData: Uint8Array;
61
69
  armoredSignature?: string;
@@ -63,10 +71,7 @@ export interface OpenPGPCryptoProxy {
63
71
  verificationKeys: PublicKey | PublicKey[];
64
72
  signatureContext?: { critical: boolean; value: string };
65
73
  }) => Promise<{
66
- // pmcrypto 8.3.0 changes `verified` to `verificationStatus`.
67
- // Web clients are using newer pmcrypto, but CLI is using older version due to build issues with Bun.
68
- verified?: VERIFICATION_STATUS;
69
- verificationStatus?: VERIFICATION_STATUS;
74
+ verificationStatus: VERIFICATION_STATUS;
70
75
  errors?: Error[];
71
76
  }>;
72
77
  }
@@ -88,7 +93,7 @@ export class OpenPGPCryptoWithCryptoProxy implements OpenPGPCrypto {
88
93
  return uint8ArrayToBase64String(value);
89
94
  }
90
95
 
91
- async generateSessionKey(encryptionKeys: PrivateKey[]) {
96
+ async generateSessionKey(encryptionKeys: PublicKey[]) {
92
97
  return this.cryptoProxy.generateSessionKey({ recipientKeys: encryptionKeys });
93
98
  }
94
99
 
@@ -132,21 +137,21 @@ export class OpenPGPCryptoWithCryptoProxy implements OpenPGPCrypto {
132
137
  };
133
138
  }
134
139
 
135
- async encryptArmored(data: Uint8Array, encryptionKeys: PrivateKey[], sessionKey?: SessionKey) {
140
+ async encryptArmored(data: Uint8Array, encryptionKeys: PublicKey[], sessionKey?: SessionKey) {
136
141
  const { message: armoredData } = await this.cryptoProxy.encryptMessage({
137
142
  binaryData: data,
138
143
  sessionKey,
139
144
  encryptionKeys,
140
145
  });
141
146
  return {
142
- armoredData: armoredData as string,
147
+ armoredData: armoredData,
143
148
  };
144
149
  }
145
150
 
146
151
  async encryptAndSign(
147
152
  data: Uint8Array,
148
153
  sessionKey: SessionKey,
149
- encryptionKeys: PrivateKey[],
154
+ encryptionKeys: PublicKey[],
150
155
  signingKey: PrivateKey,
151
156
  ) {
152
157
  const { message: encryptedData } = await this.cryptoProxy.encryptMessage({
@@ -158,14 +163,14 @@ export class OpenPGPCryptoWithCryptoProxy implements OpenPGPCrypto {
158
163
  detached: false,
159
164
  });
160
165
  return {
161
- encryptedData: encryptedData as Uint8Array,
166
+ encryptedData: encryptedData,
162
167
  };
163
168
  }
164
169
 
165
170
  async encryptAndSignArmored(
166
171
  data: Uint8Array,
167
172
  sessionKey: SessionKey | undefined,
168
- encryptionKeys: PrivateKey[],
173
+ encryptionKeys: PublicKey[],
169
174
  signingKey: PrivateKey,
170
175
  options: { compress?: boolean } = {},
171
176
  ) {
@@ -178,14 +183,14 @@ export class OpenPGPCryptoWithCryptoProxy implements OpenPGPCrypto {
178
183
  compress: options.compress || false,
179
184
  });
180
185
  return {
181
- armoredData: armoredData as string,
186
+ armoredData: armoredData,
182
187
  };
183
188
  }
184
189
 
185
190
  async encryptAndSignDetached(
186
191
  data: Uint8Array,
187
192
  sessionKey: SessionKey,
188
- encryptionKeys: PrivateKey[],
193
+ encryptionKeys: PublicKey[],
189
194
  signingKey: PrivateKey,
190
195
  ) {
191
196
  const { message: encryptedData, signature } = await this.cryptoProxy.encryptMessage({
@@ -197,15 +202,15 @@ export class OpenPGPCryptoWithCryptoProxy implements OpenPGPCrypto {
197
202
  detached: true,
198
203
  });
199
204
  return {
200
- encryptedData: encryptedData as Uint8Array,
201
- signature: signature as Uint8Array,
205
+ encryptedData: encryptedData,
206
+ signature: signature,
202
207
  };
203
208
  }
204
209
 
205
210
  async encryptAndSignDetachedArmored(
206
211
  data: Uint8Array,
207
212
  sessionKey: SessionKey,
208
- encryptionKeys: PrivateKey[],
213
+ encryptionKeys: PublicKey[],
209
214
  signingKey: PrivateKey,
210
215
  ) {
211
216
  const { message: armoredData, signature: armoredSignature } = await this.cryptoProxy.encryptMessage({
@@ -216,8 +221,8 @@ export class OpenPGPCryptoWithCryptoProxy implements OpenPGPCrypto {
216
221
  detached: true,
217
222
  });
218
223
  return {
219
- armoredData: armoredData as string,
220
- armoredSignature: armoredSignature as string,
224
+ armoredData: armoredData,
225
+ armoredSignature: armoredSignature,
221
226
  };
222
227
  }
223
228
 
@@ -230,7 +235,7 @@ export class OpenPGPCryptoWithCryptoProxy implements OpenPGPCrypto {
230
235
  signatureContext: { critical: true, value: signatureContext },
231
236
  });
232
237
  return {
233
- signature: signature as Uint8Array,
238
+ signature: signature,
234
239
  };
235
240
  }
236
241
 
@@ -242,20 +247,18 @@ export class OpenPGPCryptoWithCryptoProxy implements OpenPGPCrypto {
242
247
  format: 'armored',
243
248
  });
244
249
  return {
245
- signature: signature as string,
250
+ signature: signature,
246
251
  };
247
252
  }
248
253
 
249
254
  async verify(data: Uint8Array, signature: Uint8Array, verificationKeys: PublicKey | PublicKey[]) {
250
- const { verified, verificationStatus, errors } = await this.cryptoProxy.verifyMessage({
255
+ const { verificationStatus, errors } = await this.cryptoProxy.verifyMessage({
251
256
  binaryData: data,
252
257
  binarySignature: signature,
253
258
  verificationKeys,
254
259
  });
255
260
  return {
256
- // pmcrypto 8.3.0 changes `verified` to `verificationStatus`.
257
- // Proper typing is too complex, it will be removed to support only newer pmcrypto.
258
- verified: verified || verificationStatus!,
261
+ verified: verificationStatus,
259
262
  verificationErrors: errors,
260
263
  };
261
264
  }
@@ -266,7 +269,7 @@ export class OpenPGPCryptoWithCryptoProxy implements OpenPGPCrypto {
266
269
  verificationKeys: PublicKey | PublicKey[],
267
270
  signatureContext?: string,
268
271
  ) {
269
- const { verified, verificationStatus, errors } = await this.cryptoProxy.verifyMessage({
272
+ const { verificationStatus, errors } = await this.cryptoProxy.verifyMessage({
270
273
  binaryData: data,
271
274
  armoredSignature,
272
275
  verificationKeys,
@@ -274,9 +277,7 @@ export class OpenPGPCryptoWithCryptoProxy implements OpenPGPCrypto {
274
277
  });
275
278
 
276
279
  return {
277
- // pmcrypto 8.3.0 changes `verified` to `verificationStatus`.
278
- // Proper typing is too complex, it will be removed to support only newer pmcrypto.
279
- verified: verified || verificationStatus!,
280
+ verified: verificationStatus,
280
281
  verificationErrors: errors,
281
282
  };
282
283
  }
@@ -318,7 +319,6 @@ export class OpenPGPCryptoWithCryptoProxy implements OpenPGPCrypto {
318
319
  async decryptAndVerify(data: Uint8Array, sessionKey: SessionKey, verificationKeys: PublicKey[]) {
319
320
  const {
320
321
  data: decryptedData,
321
- verified,
322
322
  verificationStatus,
323
323
  verificationErrors,
324
324
  } = await this.cryptoProxy.decryptMessage({
@@ -329,10 +329,8 @@ export class OpenPGPCryptoWithCryptoProxy implements OpenPGPCrypto {
329
329
  });
330
330
 
331
331
  return {
332
- data: decryptedData as Uint8Array,
333
- // pmcrypto 8.3.0 changes `verified` to `verificationStatus`.
334
- // Proper typing is too complex, it will be removed to support only newer pmcrypto.
335
- verified: verified || verificationStatus!,
332
+ data: decryptedData,
333
+ verified: verificationStatus,
336
334
  verificationErrors,
337
335
  };
338
336
  }
@@ -345,7 +343,6 @@ export class OpenPGPCryptoWithCryptoProxy implements OpenPGPCrypto {
345
343
  ) {
346
344
  const {
347
345
  data: decryptedData,
348
- verified,
349
346
  verificationStatus,
350
347
  verificationErrors,
351
348
  } = await this.cryptoProxy.decryptMessage({
@@ -357,10 +354,8 @@ export class OpenPGPCryptoWithCryptoProxy implements OpenPGPCrypto {
357
354
  });
358
355
 
359
356
  return {
360
- data: decryptedData as Uint8Array,
361
- // pmcrypto 8.3.0 changes `verified` to `verificationStatus`.
362
- // Proper typing is too complex, it will be removed to support only newer pmcrypto.
363
- verified: verified || verificationStatus!,
357
+ data: decryptedData,
358
+ verified: verificationStatus,
364
359
  verificationErrors,
365
360
  };
366
361
  }
@@ -371,7 +366,7 @@ export class OpenPGPCryptoWithCryptoProxy implements OpenPGPCrypto {
371
366
  decryptionKeys,
372
367
  format: 'binary',
373
368
  });
374
- return data as Uint8Array;
369
+ return data;
375
370
  }
376
371
 
377
372
  async decryptArmoredAndVerify(
@@ -379,7 +374,7 @@ export class OpenPGPCryptoWithCryptoProxy implements OpenPGPCrypto {
379
374
  decryptionKeys: PrivateKey | PrivateKey[],
380
375
  verificationKeys: PublicKey | PublicKey[],
381
376
  ) {
382
- const { data, verified, verificationStatus, verificationErrors } = await this.cryptoProxy.decryptMessage({
377
+ const { data, verificationStatus, verificationErrors } = await this.cryptoProxy.decryptMessage({
383
378
  armoredMessage: armoredData,
384
379
  decryptionKeys,
385
380
  verificationKeys,
@@ -387,10 +382,8 @@ export class OpenPGPCryptoWithCryptoProxy implements OpenPGPCrypto {
387
382
  });
388
383
 
389
384
  return {
390
- data: data as Uint8Array,
391
- // pmcrypto 8.3.0 changes `verified` to `verificationStatus`.
392
- // Proper typing is too complex, it will be removed to support only newer pmcrypto.
393
- verified: verified || verificationStatus!,
385
+ data: data,
386
+ verified: verificationStatus,
394
387
  verificationErrors,
395
388
  };
396
389
  }
@@ -401,7 +394,7 @@ export class OpenPGPCryptoWithCryptoProxy implements OpenPGPCrypto {
401
394
  sessionKey: SessionKey,
402
395
  verificationKeys: PublicKey | PublicKey[],
403
396
  ) {
404
- const { data, verified, verificationStatus, verificationErrors } = await this.cryptoProxy.decryptMessage({
397
+ const { data, verificationStatus, verificationErrors } = await this.cryptoProxy.decryptMessage({
405
398
  armoredMessage: armoredData,
406
399
  armoredSignature,
407
400
  sessionKeys: sessionKey,
@@ -410,10 +403,8 @@ export class OpenPGPCryptoWithCryptoProxy implements OpenPGPCrypto {
410
403
  });
411
404
 
412
405
  return {
413
- data: data as Uint8Array,
414
- // pmcrypto 8.3.0 changes `verified` to `verificationStatus`.
415
- // Proper typing is too complex, it will be removed to support only newer pmcrypto.
416
- verified: verified || verificationStatus!,
406
+ data: data,
407
+ verified: verificationStatus,
417
408
  verificationErrors: !armoredSignature
418
409
  ? [new Error(c('Error').t`Signature is missing`)]
419
410
  : verificationErrors,
@@ -426,6 +417,6 @@ export class OpenPGPCryptoWithCryptoProxy implements OpenPGPCrypto {
426
417
  passwords: [password],
427
418
  format: 'binary',
428
419
  });
429
- return data as Uint8Array;
420
+ return data;
430
421
  }
431
422
  }
@@ -2,7 +2,7 @@ import { MaybeNode } from '../interface';
2
2
  import { ProtonDriveClient } from '../protonDriveClient';
3
3
  import { ProtonDrivePhotosClient } from '../protonDrivePhotosClient';
4
4
  import { DiagnosticHTTPClient } from './httpClient';
5
- import { DiagnosticOptions, DiagnosticProgressCallback, DiagnosticResult } from './interface';
5
+ import { DiagnosticOptions, DiagnosticProgressCallback, DiagnosticResult, TreeNode } from './interface';
6
6
  import { SDKDiagnosticMain } from './sdkDiagnosticMain';
7
7
  import { SDKDiagnosticPhotos } from './sdkDiagnosticPhotos';
8
8
  import { DiagnosticTelemetry } from './telemetry';
@@ -57,4 +57,14 @@ export class Diagnostic {
57
57
  private async *internalGenerator(): AsyncGenerator<DiagnosticResult> {
58
58
  yield* zipGenerators(this.telemetry.iterateEvents(), this.httpClient.iterateEvents());
59
59
  }
60
+
61
+ async getNodeTreeStructure(node: MaybeNode): Promise<TreeNode> {
62
+ const diagnostic = new SDKDiagnosticMain(this.protonDriveClient);
63
+ return diagnostic.getStructure(node);
64
+ }
65
+
66
+ async getPhotosTimelineStructure(): Promise<TreeNode> {
67
+ const diagnostic = new SDKDiagnosticPhotos(this.protonDrivePhotosClient);
68
+ return diagnostic.getStructure();
69
+ }
60
70
  }
@@ -15,6 +15,8 @@ export interface Diagnostic {
15
15
  options?: DiagnosticOptions,
16
16
  onProgress?: DiagnosticProgressCallback,
17
17
  ): AsyncGenerator<DiagnosticResult>;
18
+ getNodeTreeStructure(node: MaybeNode): Promise<TreeNode>;
19
+ getPhotosTimelineStructure(): Promise<TreeNode>;
18
20
  }
19
21
 
20
22
  export type DiagnosticOptions = {
@@ -36,6 +38,17 @@ export type ExpectedTreeNode = {
36
38
  children?: ExpectedTreeNode[];
37
39
  };
38
40
 
41
+ export type TreeNode = {
42
+ uid: string;
43
+ type: NodeType;
44
+ // If node is degraded, error will be set.
45
+ error?: unknown;
46
+ name: string;
47
+ claimedSha1?: string;
48
+ claimedSizeInBytes?: number;
49
+ children?: TreeNode[];
50
+ };
51
+
39
52
  export type ExpectedAuthor = string | 'anonymous';
40
53
 
41
54
  export type DiagnosticProgressCallback = (progress: {
@@ -1,8 +1,14 @@
1
1
  import { MaybeNode, NodeType } from '../interface';
2
2
  import { ProtonDriveClient } from '../protonDriveClient';
3
- import { DiagnosticOptions, DiagnosticProgressCallback, DiagnosticResult, ExpectedTreeNode } from './interface';
3
+ import {
4
+ DiagnosticOptions,
5
+ DiagnosticProgressCallback,
6
+ DiagnosticResult,
7
+ ExpectedTreeNode,
8
+ TreeNode,
9
+ } from './interface';
4
10
  import { zipGenerators } from './zipGenerators';
5
- import { getNodeType, getNodeName, getTreeNodeChildByNodeName } from './nodeUtils';
11
+ import { getNodeType, getNodeName, getTreeNodeChildByNodeName, getActiveRevision } from './nodeUtils';
6
12
  import { SDKDiagnosticBase } from './sdkDiagnosticBase';
7
13
 
8
14
  /**
@@ -92,4 +98,37 @@ export class SDKDiagnosticMain extends SDKDiagnosticBase {
92
98
  }
93
99
  }
94
100
  }
101
+
102
+ async getStructure(node: MaybeNode): Promise<TreeNode> {
103
+ const nodeType = getNodeType(node);
104
+ const treeNode: TreeNode = {
105
+ uid: node.ok ? node.value.uid : node.error.uid,
106
+ type: nodeType,
107
+ name: getNodeName(node),
108
+ };
109
+
110
+ if (!node.ok) {
111
+ treeNode.error = node.error || 'degraded node';
112
+ }
113
+
114
+ if (nodeType === NodeType.Folder) {
115
+ const children = [];
116
+
117
+ for await (const child of this.protonDriveClient.iterateFolderChildren(node)) {
118
+ children.push(child);
119
+ }
120
+
121
+ treeNode.children = [];
122
+ for (const child of children) {
123
+ const childStructure = await this.getStructure(child);
124
+ treeNode.children.push(childStructure);
125
+ }
126
+ } else if (nodeType === NodeType.File) {
127
+ const activeRevision = getActiveRevision(node);
128
+ treeNode.claimedSha1 = activeRevision?.claimedDigests?.sha1;
129
+ treeNode.claimedSizeInBytes = activeRevision?.claimedSize;
130
+ }
131
+
132
+ return treeNode;
133
+ }
95
134
  }
@@ -1,8 +1,14 @@
1
1
  import { MaybeNode } from '../interface';
2
2
  import { ProtonDrivePhotosClient } from '../protonDrivePhotosClient';
3
- import { DiagnosticOptions, DiagnosticProgressCallback, DiagnosticResult, ExpectedTreeNode } from './interface';
3
+ import {
4
+ DiagnosticOptions,
5
+ DiagnosticProgressCallback,
6
+ DiagnosticResult,
7
+ ExpectedTreeNode,
8
+ TreeNode,
9
+ } from './interface';
4
10
  import { zipGenerators } from './zipGenerators';
5
- import { getNodeName, getTreeNodeChildByNodeName } from './nodeUtils';
11
+ import { getNodeName, getTreeNodeChildByNodeName, getActiveRevision, getNodeType } from './nodeUtils';
6
12
  import { SDKDiagnosticBase } from './sdkDiagnosticBase';
7
13
 
8
14
  /**
@@ -67,4 +73,43 @@ export class SDKDiagnosticPhotos extends SDKDiagnosticBase {
67
73
 
68
74
  this.allNodesLoaded = true;
69
75
  }
76
+
77
+ async getStructure(): Promise<TreeNode> {
78
+ const myPhotosRootFolder = await this.protonDrivePhotosClient.getMyPhotosRootFolder();
79
+
80
+ const treeNode: TreeNode = {
81
+ uid: myPhotosRootFolder.ok ? myPhotosRootFolder.value.uid : myPhotosRootFolder.error.uid,
82
+ type: getNodeType(myPhotosRootFolder),
83
+ name: getNodeName(myPhotosRootFolder),
84
+ };
85
+ const children = [];
86
+
87
+ const results = await Array.fromAsync(this.protonDrivePhotosClient.iterateTimeline());
88
+ const nodeUids = results.map((result) => result.nodeUid);
89
+
90
+ for await (const maybeMissingNode of this.protonDrivePhotosClient.iterateNodes(nodeUids)) {
91
+ if (!maybeMissingNode.ok && 'missingUid' in maybeMissingNode.error) {
92
+ continue;
93
+ }
94
+ const node = maybeMissingNode as MaybeNode;
95
+
96
+ const activeRevision = getActiveRevision(node);
97
+ const childNode: TreeNode = {
98
+ uid: node.ok ? node.value.uid : node.error.uid,
99
+ name: getNodeName(node),
100
+ type: getNodeType(node),
101
+ claimedSha1: activeRevision?.claimedDigests?.sha1,
102
+ claimedSizeInBytes: activeRevision?.claimedSize,
103
+ };
104
+
105
+ if (!node.ok) {
106
+ childNode.error = node.error || 'degraded node';
107
+ }
108
+
109
+ children.push(childNode);
110
+ }
111
+
112
+ treeNode.children = children;
113
+ return treeNode;
114
+ }
70
115
  }