@protontech/drive-sdk 0.3.2 → 0.4.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 (120) hide show
  1. package/dist/internal/apiService/errorCodes.d.ts +1 -0
  2. package/dist/internal/apiService/errors.d.ts +3 -0
  3. package/dist/internal/apiService/errors.js +7 -1
  4. package/dist/internal/apiService/errors.js.map +1 -1
  5. package/dist/internal/devices/interface.d.ts +1 -1
  6. package/dist/internal/devices/manager.js +1 -1
  7. package/dist/internal/devices/manager.js.map +1 -1
  8. package/dist/internal/devices/manager.test.js +3 -3
  9. package/dist/internal/devices/manager.test.js.map +1 -1
  10. package/dist/internal/events/apiService.js +1 -1
  11. package/dist/internal/events/apiService.js.map +1 -1
  12. package/dist/internal/events/coreEventManager.js +1 -1
  13. package/dist/internal/events/coreEventManager.js.map +1 -1
  14. package/dist/internal/events/coreEventManager.test.js +18 -24
  15. package/dist/internal/events/coreEventManager.test.js.map +1 -1
  16. package/dist/internal/events/index.d.ts +3 -4
  17. package/dist/internal/events/index.js +4 -4
  18. package/dist/internal/events/index.js.map +1 -1
  19. package/dist/internal/events/interface.d.ts +3 -0
  20. package/dist/internal/nodes/apiService.d.ts +12 -3
  21. package/dist/internal/nodes/apiService.js +53 -13
  22. package/dist/internal/nodes/apiService.js.map +1 -1
  23. package/dist/internal/nodes/apiService.test.js +19 -2
  24. package/dist/internal/nodes/apiService.test.js.map +1 -1
  25. package/dist/internal/nodes/cryptoService.d.ts +1 -1
  26. package/dist/internal/nodes/cryptoService.js +1 -1
  27. package/dist/internal/nodes/cryptoService.js.map +1 -1
  28. package/dist/internal/nodes/cryptoService.test.js +4 -4
  29. package/dist/internal/nodes/cryptoService.test.js.map +1 -1
  30. package/dist/internal/nodes/errors.d.ts +4 -0
  31. package/dist/internal/nodes/errors.js +9 -0
  32. package/dist/internal/nodes/errors.js.map +1 -0
  33. package/dist/internal/nodes/index.test.js +1 -1
  34. package/dist/internal/nodes/index.test.js.map +1 -1
  35. package/dist/internal/nodes/interface.d.ts +4 -1
  36. package/dist/internal/nodes/nodesAccess.d.ts +3 -3
  37. package/dist/internal/nodes/nodesAccess.js +25 -15
  38. package/dist/internal/nodes/nodesAccess.js.map +1 -1
  39. package/dist/internal/nodes/nodesAccess.test.js +48 -8
  40. package/dist/internal/nodes/nodesAccess.test.js.map +1 -1
  41. package/dist/internal/nodes/nodesManagement.d.ts +2 -0
  42. package/dist/internal/nodes/nodesManagement.js +86 -9
  43. package/dist/internal/nodes/nodesManagement.js.map +1 -1
  44. package/dist/internal/nodes/nodesManagement.test.js +81 -5
  45. package/dist/internal/nodes/nodesManagement.test.js.map +1 -1
  46. package/dist/internal/photos/albums.d.ts +9 -7
  47. package/dist/internal/photos/albums.js +26 -13
  48. package/dist/internal/photos/albums.js.map +1 -1
  49. package/dist/internal/photos/apiService.d.ts +34 -3
  50. package/dist/internal/photos/apiService.js +96 -3
  51. package/dist/internal/photos/apiService.js.map +1 -1
  52. package/dist/internal/photos/index.d.ts +20 -4
  53. package/dist/internal/photos/index.js +30 -7
  54. package/dist/internal/photos/index.js.map +1 -1
  55. package/dist/internal/photos/interface.d.ts +25 -1
  56. package/dist/internal/photos/shares.d.ts +43 -0
  57. package/dist/internal/photos/shares.js +112 -0
  58. package/dist/internal/photos/shares.js.map +1 -0
  59. package/dist/internal/photos/timeline.d.ts +15 -0
  60. package/dist/internal/photos/timeline.js +22 -0
  61. package/dist/internal/photos/timeline.js.map +1 -0
  62. package/dist/internal/shares/manager.d.ts +1 -1
  63. package/dist/internal/shares/manager.js +4 -4
  64. package/dist/internal/shares/manager.js.map +1 -1
  65. package/dist/internal/shares/manager.test.js +7 -7
  66. package/dist/internal/shares/manager.test.js.map +1 -1
  67. package/dist/internal/sharing/interface.d.ts +1 -1
  68. package/dist/internal/sharing/sharingAccess.js +1 -1
  69. package/dist/internal/sharing/sharingAccess.js.map +1 -1
  70. package/dist/internal/sharing/sharingAccess.test.js +1 -1
  71. package/dist/internal/sharing/sharingAccess.test.js.map +1 -1
  72. package/dist/protonDriveClient.d.ts +20 -3
  73. package/dist/protonDriveClient.js +23 -4
  74. package/dist/protonDriveClient.js.map +1 -1
  75. package/dist/protonDrivePhotosClient.d.ts +86 -12
  76. package/dist/protonDrivePhotosClient.js +132 -29
  77. package/dist/protonDrivePhotosClient.js.map +1 -1
  78. package/package.json +1 -1
  79. package/src/internal/apiService/errorCodes.ts +1 -0
  80. package/src/internal/apiService/errors.ts +6 -0
  81. package/src/internal/devices/interface.ts +1 -1
  82. package/src/internal/devices/manager.test.ts +3 -3
  83. package/src/internal/devices/manager.ts +1 -1
  84. package/src/internal/events/apiService.ts +1 -1
  85. package/src/internal/events/coreEventManager.test.ts +21 -27
  86. package/src/internal/events/coreEventManager.ts +1 -1
  87. package/src/internal/events/index.ts +3 -4
  88. package/src/internal/events/interface.ts +4 -0
  89. package/src/internal/nodes/apiService.test.ts +35 -1
  90. package/src/internal/nodes/apiService.ts +103 -17
  91. package/src/internal/nodes/cryptoService.test.ts +8 -8
  92. package/src/internal/nodes/cryptoService.ts +1 -1
  93. package/src/internal/nodes/errors.ts +5 -0
  94. package/src/internal/nodes/index.test.ts +1 -1
  95. package/src/internal/nodes/interface.ts +5 -1
  96. package/src/internal/nodes/nodesAccess.test.ts +68 -8
  97. package/src/internal/nodes/nodesAccess.ts +42 -15
  98. package/src/internal/nodes/nodesManagement.test.ts +100 -5
  99. package/src/internal/nodes/nodesManagement.ts +100 -13
  100. package/src/internal/photos/albums.ts +31 -12
  101. package/src/internal/photos/apiService.ts +159 -4
  102. package/src/internal/photos/index.ts +54 -9
  103. package/src/internal/photos/interface.ts +23 -1
  104. package/src/internal/photos/shares.ts +134 -0
  105. package/src/internal/photos/timeline.ts +24 -0
  106. package/src/internal/shares/manager.test.ts +7 -7
  107. package/src/internal/shares/manager.ts +4 -4
  108. package/src/internal/sharing/interface.ts +1 -1
  109. package/src/internal/sharing/sharingAccess.test.ts +1 -1
  110. package/src/internal/sharing/sharingAccess.ts +1 -1
  111. package/src/protonDriveClient.ts +33 -4
  112. package/src/protonDrivePhotosClient.ts +211 -32
  113. package/dist/internal/photos/cache.d.ts +0 -6
  114. package/dist/internal/photos/cache.js +0 -15
  115. package/dist/internal/photos/cache.js.map +0 -1
  116. package/dist/internal/photos/photosTimeline.d.ts +0 -10
  117. package/dist/internal/photos/photosTimeline.js +0 -19
  118. package/dist/internal/photos/photosTimeline.js.map +0 -1
  119. package/src/internal/photos/cache.ts +0 -11
  120. package/src/internal/photos/photosTimeline.ts +0 -17
@@ -1,16 +1,90 @@
1
- import { ProtonDriveClientContructorParameters } from './interface';
1
+ import { ProtonDriveClientContructorParameters, NodeOrUid, MaybeMissingNode, UploadMetadata, FileDownloader, FileUploader, SDKEvent, MaybeNode } from './interface';
2
+ import { DriveListener, EventSubscription } from './internal/events';
3
+ /**
4
+ * ProtonDrivePhotosClient is the interface to access Photos functionality.
5
+ *
6
+ * The client provides high-level operations for managing photos, albums, sharing,
7
+ * and downloading/uploading photos.
8
+ *
9
+ * @deprecated This is an experimental feature that might change without a warning.
10
+ */
2
11
  export declare class ProtonDrivePhotosClient {
12
+ private logger;
13
+ private sdkEvents;
14
+ private events;
15
+ private photoShares;
3
16
  private nodes;
17
+ private sharing;
18
+ private download;
19
+ private upload;
4
20
  private photos;
5
- constructor({ httpClient, entitiesCache, cryptoCache, account, openPGPCryptoModule, srpModule, config, telemetry, }: ProtonDriveClientContructorParameters);
6
- iterateTimelinePhotos(): void;
7
- iterateAlbumPhotos(): void;
8
- iterateThumbnails(): void;
9
- getPhoto(): void;
10
- createAlbum(albumName: string): Promise<void>;
11
- renameAlbum(): void;
12
- shareAlbum(): void;
13
- deleteAlbum(): void;
14
- iterateAlbums(): void;
15
- addPhotosToAlbum(): void;
21
+ experimental: {
22
+ /**
23
+ * Experimental feature to return the URL of the node.
24
+ *
25
+ * See `ProtonDriveClient.experimental.getNodeUrl` for more information.
26
+ */
27
+ getNodeUrl: (nodeUid: NodeOrUid) => Promise<string>;
28
+ };
29
+ constructor({ httpClient, entitiesCache, cryptoCache, account, openPGPCryptoModule, srpModule, config, telemetry, latestEventIdProvider, }: ProtonDriveClientContructorParameters);
30
+ /**
31
+ * Subscribes to the general SDK events.
32
+ *
33
+ * See `ProtonDriveClient.onMessage` for more information.
34
+ */
35
+ onMessage(eventName: SDKEvent, callback: () => void): () => void;
36
+ /**
37
+ * Subscribes to the remote data updates for all files in a tree.
38
+ *
39
+ * See `ProtonDriveClient.subscribeToTreeEvents` for more information.
40
+ */
41
+ subscribeToTreeEvents(treeEventScopeId: string, callback: DriveListener): Promise<EventSubscription>;
42
+ /**
43
+ * Subscribes to the remote general data updates.
44
+ *
45
+ * See `ProtonDriveClient.subscribeToDriveEvents` for more information.
46
+ */
47
+ subscribeToDriveEvents(callback: DriveListener): Promise<EventSubscription>;
48
+ /**
49
+ * Iterates all the photos for the timeline view.
50
+ *
51
+ * The output includes only necessary information to quickly prepare
52
+ * the whole timeline view with the break-down per month/year and fast
53
+ * scrollbar.
54
+ *
55
+ * Individual photos details must be loaded separately based on what
56
+ * is visible in the UI.
57
+ *
58
+ * The output is sorted by the capture time, starting from the
59
+ * the most recent photos.
60
+ */
61
+ iterateTimeline(signal?: AbortSignal): AsyncGenerator<{
62
+ nodeUid: string;
63
+ captureTime: Date;
64
+ tags: number[];
65
+ }>;
66
+ /**
67
+ * Iterates the nodes by their UIDs.
68
+ *
69
+ * See `ProtonDriveClient.iterateNodes` for more information.
70
+ */
71
+ iterateNodes(nodeUids: NodeOrUid[], signal?: AbortSignal): AsyncGenerator<MaybeMissingNode>;
72
+ /**
73
+ * Iterates the albums.
74
+ *
75
+ * The output is not sorted and the order of the nodes is not guaranteed.
76
+ */
77
+ iterateAlbums(signal?: AbortSignal): AsyncGenerator<MaybeNode>;
78
+ /**
79
+ * Get the file downloader to download the node content.
80
+ *
81
+ * See `ProtonDriveClient.getFileDownloader` for more information.
82
+ */
83
+ getFileDownloader(nodeUid: NodeOrUid, signal?: AbortSignal): Promise<FileDownloader>;
84
+ /**
85
+ * Get the file uploader to upload a new file.
86
+ *
87
+ * See `ProtonDriveClient.getFileUploader` for more information.
88
+ */
89
+ getFileUploader(name: string, metadata: UploadMetadata, signal?: AbortSignal): Promise<FileUploader>;
16
90
  }
@@ -1,47 +1,150 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ProtonDrivePhotosClient = void 0;
4
- const apiService_1 = require("./internal/apiService");
4
+ const config_1 = require("./config");
5
5
  const crypto_1 = require("./crypto");
6
- const shares_1 = require("./internal/shares");
6
+ const telemetry_1 = require("./telemetry");
7
+ const transformers_1 = require("./transformers");
8
+ const apiService_1 = require("./internal/apiService");
9
+ const download_1 = require("./internal/download");
10
+ const events_1 = require("./internal/events");
7
11
  const nodes_1 = require("./internal/nodes");
8
12
  const photos_1 = require("./internal/photos");
9
- const events_1 = require("./internal/events");
10
13
  const sdkEvents_1 = require("./internal/sdkEvents");
11
- const config_1 = require("./config");
12
- const telemetry_1 = require("./telemetry");
13
- // TODO: this is only example, on background it use drive internals, but it exposes nice interface for photos
14
+ const shares_1 = require("./internal/shares");
15
+ const sharing_1 = require("./internal/sharing");
16
+ const upload_1 = require("./internal/upload");
17
+ /**
18
+ * ProtonDrivePhotosClient is the interface to access Photos functionality.
19
+ *
20
+ * The client provides high-level operations for managing photos, albums, sharing,
21
+ * and downloading/uploading photos.
22
+ *
23
+ * @deprecated This is an experimental feature that might change without a warning.
24
+ */
14
25
  class ProtonDrivePhotosClient {
26
+ logger;
27
+ sdkEvents;
28
+ events;
29
+ photoShares;
15
30
  nodes;
31
+ sharing;
32
+ download;
33
+ upload;
16
34
  photos;
17
- constructor({ httpClient, entitiesCache, cryptoCache, account, openPGPCryptoModule, srpModule, config, telemetry, }) {
35
+ experimental;
36
+ constructor({ httpClient, entitiesCache, cryptoCache, account, openPGPCryptoModule, srpModule, config, telemetry, latestEventIdProvider, }) {
18
37
  if (!telemetry) {
19
38
  telemetry = new telemetry_1.Telemetry();
20
39
  }
40
+ this.logger = telemetry.getLogger('interface');
21
41
  const fullConfig = (0, config_1.getConfig)(config);
22
- const sdkEvents = new sdkEvents_1.SDKEvents(telemetry);
42
+ this.sdkEvents = new sdkEvents_1.SDKEvents(telemetry);
23
43
  const cryptoModule = new crypto_1.DriveCrypto(openPGPCryptoModule, srpModule);
24
- const apiService = new apiService_1.DriveAPIService(telemetry, sdkEvents, httpClient, fullConfig.baseUrl, fullConfig.language);
25
- const shares = (0, shares_1.initSharesModule)(telemetry, apiService, entitiesCache, cryptoCache, account, cryptoModule);
26
- this.nodes = (0, nodes_1.initNodesModule)(telemetry, apiService, entitiesCache, cryptoCache, account, cryptoModule, shares);
27
- const cacheEventListeners = [this.nodes.eventHandler.updateNodesCacheOnEvent];
28
- new events_1.DriveEventsService(telemetry, apiService, shares, cacheEventListeners);
29
- this.photos = (0, photos_1.initPhotosModule)(apiService, entitiesCache, this.nodes.access);
30
- }
31
- // Timeline or album view
32
- iterateTimelinePhotos() { } // returns only UIDs and dates - used to show grid and scrolling
33
- iterateAlbumPhotos() { } // same as above but for album
34
- iterateThumbnails() { } // returns thumbnails for passed photos that are visible in the UI
35
- getPhoto() { } // returns full photo details
36
- // Album management
37
- createAlbum(albumName) {
38
- return this.photos.albums.createAlbum(albumName);
39
- }
40
- renameAlbum() { }
41
- shareAlbum() { }
42
- deleteAlbum() { }
43
- iterateAlbums() { }
44
- addPhotosToAlbum() { }
44
+ const apiService = new apiService_1.DriveAPIService(telemetry, this.sdkEvents, httpClient, fullConfig.baseUrl, fullConfig.language);
45
+ const coreShares = (0, shares_1.initSharesModule)(telemetry, apiService, entitiesCache, cryptoCache, account, cryptoModule);
46
+ this.photoShares = (0, photos_1.initPhotoSharesModule)(telemetry, apiService, entitiesCache, cryptoCache, account, cryptoModule, coreShares);
47
+ this.nodes = (0, nodes_1.initNodesModule)(telemetry, apiService, entitiesCache, cryptoCache, account, cryptoModule, this.photoShares);
48
+ this.photos = (0, photos_1.initPhotosModule)(apiService, this.photoShares, this.nodes.access);
49
+ this.sharing = (0, sharing_1.initSharingModule)(telemetry, apiService, entitiesCache, account, cryptoModule, this.photoShares, this.nodes.access);
50
+ this.download = (0, download_1.initDownloadModule)(telemetry, apiService, cryptoModule, account, this.photoShares, this.nodes.access, this.nodes.revisions);
51
+ this.upload = (0, upload_1.initUploadModule)(telemetry, apiService, cryptoModule, this.photoShares, this.nodes.access, fullConfig.clientUid);
52
+ // These are used to keep the internal cache up to date
53
+ const cacheEventListeners = [
54
+ this.nodes.eventHandler.updateNodesCacheOnEvent.bind(this.nodes.eventHandler),
55
+ this.sharing.eventHandler.handleDriveEvent.bind(this.sharing.eventHandler),
56
+ ];
57
+ this.events = new events_1.DriveEventsService(telemetry, apiService, this.photoShares, cacheEventListeners, latestEventIdProvider);
58
+ this.experimental = {
59
+ getNodeUrl: async (nodeUid) => {
60
+ this.logger.debug(`Getting node URL for ${(0, transformers_1.getUid)(nodeUid)}`);
61
+ return this.nodes.access.getNodeUrl((0, transformers_1.getUid)(nodeUid));
62
+ },
63
+ };
64
+ }
65
+ /**
66
+ * Subscribes to the general SDK events.
67
+ *
68
+ * See `ProtonDriveClient.onMessage` for more information.
69
+ */
70
+ onMessage(eventName, callback) {
71
+ this.logger.debug(`Subscribing to event ${eventName}`);
72
+ return this.sdkEvents.addListener(eventName, callback);
73
+ }
74
+ /**
75
+ * Subscribes to the remote data updates for all files in a tree.
76
+ *
77
+ * See `ProtonDriveClient.subscribeToTreeEvents` for more information.
78
+ */
79
+ async subscribeToTreeEvents(treeEventScopeId, callback) {
80
+ this.logger.debug('Subscribing to node updates');
81
+ return this.events.subscribeToTreeEvents(treeEventScopeId, callback);
82
+ }
83
+ /**
84
+ * Subscribes to the remote general data updates.
85
+ *
86
+ * See `ProtonDriveClient.subscribeToDriveEvents` for more information.
87
+ */
88
+ async subscribeToDriveEvents(callback) {
89
+ this.logger.debug('Subscribing to core updates');
90
+ return this.events.subscribeToCoreEvents(callback);
91
+ }
92
+ /**
93
+ * Iterates all the photos for the timeline view.
94
+ *
95
+ * The output includes only necessary information to quickly prepare
96
+ * the whole timeline view with the break-down per month/year and fast
97
+ * scrollbar.
98
+ *
99
+ * Individual photos details must be loaded separately based on what
100
+ * is visible in the UI.
101
+ *
102
+ * The output is sorted by the capture time, starting from the
103
+ * the most recent photos.
104
+ */
105
+ async *iterateTimeline(signal) {
106
+ // TODO: expose better type
107
+ yield* this.photos.timeline.iterateTimeline(signal);
108
+ }
109
+ /**
110
+ * Iterates the nodes by their UIDs.
111
+ *
112
+ * See `ProtonDriveClient.iterateNodes` for more information.
113
+ */
114
+ async *iterateNodes(nodeUids, signal) {
115
+ this.logger.info(`Iterating ${nodeUids.length} nodes`);
116
+ // TODO: expose photo type
117
+ yield* (0, transformers_1.convertInternalMissingNodeIterator)(this.nodes.access.iterateNodes((0, transformers_1.getUids)(nodeUids), signal));
118
+ }
119
+ /**
120
+ * Iterates the albums.
121
+ *
122
+ * The output is not sorted and the order of the nodes is not guaranteed.
123
+ */
124
+ async *iterateAlbums(signal) {
125
+ this.logger.info('Iterating albums');
126
+ // TODO: expose album type
127
+ yield* (0, transformers_1.convertInternalNodeIterator)(this.photos.albums.iterateAlbums(signal));
128
+ }
129
+ /**
130
+ * Get the file downloader to download the node content.
131
+ *
132
+ * See `ProtonDriveClient.getFileDownloader` for more information.
133
+ */
134
+ async getFileDownloader(nodeUid, signal) {
135
+ this.logger.info(`Getting file downloader for ${(0, transformers_1.getUid)(nodeUid)}`);
136
+ return this.download.getFileDownloader((0, transformers_1.getUid)(nodeUid), signal);
137
+ }
138
+ /**
139
+ * Get the file uploader to upload a new file.
140
+ *
141
+ * See `ProtonDriveClient.getFileUploader` for more information.
142
+ */
143
+ async getFileUploader(name, metadata, signal) {
144
+ this.logger.info(`Getting file uploader`);
145
+ const parentFolderUid = await this.nodes.access.getVolumeRootFolder();
146
+ return this.upload.getFileUploader((0, transformers_1.getUid)(parentFolderUid), name, metadata, signal);
147
+ }
45
148
  }
46
149
  exports.ProtonDrivePhotosClient = ProtonDrivePhotosClient;
47
150
  //# sourceMappingURL=protonDrivePhotosClient.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"protonDrivePhotosClient.js","sourceRoot":"","sources":["../src/protonDrivePhotosClient.ts"],"names":[],"mappings":";;;AAAA,sDAAwD;AAExD,qCAAuC;AACvC,8CAAqD;AACrD,4CAAmD;AACnD,8CAAqD;AACrD,8CAAuD;AACvD,oDAAiD;AACjD,qCAAqC;AACrC,2CAAwC;AAExC,6GAA6G;AAC7G,MAAa,uBAAuB;IACxB,KAAK,CAAqC;IAC1C,MAAM,CAAsC;IAEpD,YAAY,EACR,UAAU,EACV,aAAa,EACb,WAAW,EACX,OAAO,EACP,mBAAmB,EACnB,SAAS,EACT,MAAM,EACN,SAAS,GAC2B;QACpC,IAAI,CAAC,SAAS,EAAE,CAAC;YACb,SAAS,GAAG,IAAI,qBAAS,EAAE,CAAC;QAChC,CAAC;QAED,MAAM,UAAU,GAAG,IAAA,kBAAS,EAAC,MAAM,CAAC,CAAC;QACrC,MAAM,SAAS,GAAG,IAAI,qBAAS,CAAC,SAAS,CAAC,CAAC;QAC3C,MAAM,YAAY,GAAG,IAAI,oBAAW,CAAC,mBAAmB,EAAE,SAAS,CAAC,CAAC;QACrE,MAAM,UAAU,GAAG,IAAI,4BAAe,CAClC,SAAS,EACT,SAAS,EACT,UAAU,EACV,UAAU,CAAC,OAAO,EAClB,UAAU,CAAC,QAAQ,CACtB,CAAC;QACF,MAAM,MAAM,GAAG,IAAA,yBAAgB,EAAC,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;QAC1G,IAAI,CAAC,KAAK,GAAG,IAAA,uBAAe,EAAC,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;QAC/G,MAAM,mBAAmB,GAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,uBAAuB,CAAC,CAAC;QAC/F,IAAI,2BAAkB,CAAC,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,mBAAmB,CAAC,CAAC;QAC3E,IAAI,CAAC,MAAM,GAAG,IAAA,yBAAgB,EAAC,UAAU,EAAE,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACjF,CAAC;IAED,yBAAyB;IACzB,qBAAqB,KAAI,CAAC,CAAC,gEAAgE;IAC3F,kBAAkB,KAAI,CAAC,CAAC,8BAA8B;IACtD,iBAAiB,KAAI,CAAC,CAAC,kEAAkE;IACzF,QAAQ,KAAI,CAAC,CAAC,6BAA6B;IAE3C,mBAAmB;IACnB,WAAW,CAAC,SAAiB;QACzB,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IACrD,CAAC;IACD,WAAW,KAAI,CAAC;IAChB,UAAU,KAAI,CAAC;IACf,WAAW,KAAI,CAAC;IAChB,aAAa,KAAI,CAAC;IAClB,gBAAgB,KAAI,CAAC;CACxB;AAlDD,0DAkDC"}
1
+ {"version":3,"file":"protonDrivePhotosClient.js","sourceRoot":"","sources":["../src/protonDrivePhotosClient.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@protontech/drive-sdk",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "description": "Proton Drive SDK",
5
5
  "license": "GPL-3.0",
6
6
  "main": "dist/index.js",
@@ -18,6 +18,7 @@ export const enum ErrorCode {
18
18
  OK = 1000,
19
19
  OK_MANY = 1001,
20
20
  OK_ASYNC = 1002,
21
+ INVALID_REQUIREMENTS = 2000,
21
22
  INVALID_VALUE = 2001,
22
23
  NOT_ENOUGH_PERMISSIONS = 2011,
23
24
  NOT_ENOUGH_PERMISSIONS_TO_GRANT_PERMISSIONS = 2026,
@@ -57,6 +57,8 @@ export function apiErrorFactory({
57
57
  // Here we convert only general enough codes. Specific cases that are
58
58
  // not clear from the code itself must be handled by each module
59
59
  // separately.
60
+ case ErrorCode.INVALID_REQUIREMENTS:
61
+ return new InvalidRequirementsAPIError(message, code, details);
60
62
  case ErrorCode.INVALID_VALUE:
61
63
  case ErrorCode.NOT_ENOUGH_PERMISSIONS:
62
64
  case ErrorCode.NOT_ENOUGH_PERMISSIONS_TO_GRANT_PERMISSIONS:
@@ -108,3 +110,7 @@ export class APICodeError extends ServerError {
108
110
  export class NotFoundAPIError extends ValidationError {
109
111
  name = 'NotFoundAPIError';
110
112
  }
113
+
114
+ export class InvalidRequirementsAPIError extends ValidationError {
115
+ name = 'InvalidRequirementsAPIError';
116
+ }
@@ -13,7 +13,7 @@ export type DeviceMetadata = {
13
13
  };
14
14
 
15
15
  export interface SharesService {
16
- getMyFilesIDs(): Promise<{ volumeId: string }>;
16
+ getOwnVolumeIDs(): Promise<{ volumeId: string }>;
17
17
  getMyFilesShareMemberEmailKey(): Promise<{
18
18
  addressId: string;
19
19
  email: string;
@@ -30,7 +30,7 @@ describe('DevicesManager', () => {
30
30
  };
31
31
  // @ts-expect-error No need to implement all methods for mocking
32
32
  sharesService = {
33
- getMyFilesIDs: jest.fn(),
33
+ getOwnVolumeIDs: jest.fn(),
34
34
  };
35
35
  // @ts-expect-error No need to implement all methods for mocking
36
36
  nodesService = {};
@@ -74,13 +74,13 @@ describe('DevicesManager', () => {
74
74
  shareId: 'shareid',
75
75
  } as DeviceMetadata;
76
76
 
77
- sharesService.getMyFilesIDs.mockResolvedValue({ volumeId });
77
+ sharesService.getOwnVolumeIDs.mockResolvedValue({ volumeId });
78
78
  cryptoService.createDevice.mockResolvedValue({ address, shareKey, node });
79
79
  apiService.createDevice.mockResolvedValue(createdDevice);
80
80
 
81
81
  const result = await manager.createDevice(name, deviceType);
82
82
 
83
- expect(sharesService.getMyFilesIDs).toHaveBeenCalled();
83
+ expect(sharesService.getOwnVolumeIDs).toHaveBeenCalled();
84
84
  expect(cryptoService.createDevice).toHaveBeenCalledWith(name);
85
85
  expect(apiService.createDevice).toHaveBeenCalledWith(
86
86
  { volumeId, type: deviceType },
@@ -47,7 +47,7 @@ export class DevicesManager {
47
47
  }
48
48
 
49
49
  async createDevice(name: string, deviceType: DeviceType): Promise<Device> {
50
- const { volumeId } = await this.sharesService.getMyFilesIDs();
50
+ const { volumeId } = await this.sharesService.getOwnVolumeIDs();
51
51
  const { address, shareKey, node } = await this.cryptoService.createDevice(name);
52
52
 
53
53
  const device = await this.apiService.createDevice(
@@ -57,7 +57,7 @@ export class EventsAPIService {
57
57
  return {
58
58
  latestEventId: result.EventID,
59
59
  more: result.More === 1,
60
- refresh: result.Refresh === 1,
60
+ refresh,
61
61
  events,
62
62
  };
63
63
  }
@@ -46,29 +46,6 @@ describe('CoreEventManager', () => {
46
46
  const eventId = 'event1';
47
47
  const latestEventId = 'event2';
48
48
 
49
- it('should yield ShareWithMeUpdated event when refresh is true', async () => {
50
- const mockEvents: DriveEventsListWithStatus = {
51
- latestEventId,
52
- more: false,
53
- refresh: true,
54
- events: [],
55
- };
56
- mockApiService.getCoreEvents.mockResolvedValue(mockEvents);
57
-
58
- const events = [];
59
- for await (const event of coreEventManager.getEvents(eventId)) {
60
- events.push(event);
61
- }
62
-
63
- expect(events).toHaveLength(1);
64
- expect(events[0]).toEqual({
65
- type: DriveEventType.SharedWithMeUpdated,
66
- treeEventScopeId: 'core',
67
- eventId: latestEventId,
68
- });
69
- expect(mockApiService.getCoreEvents).toHaveBeenCalledWith(eventId);
70
- });
71
-
72
49
  it('should yield all events when there are actual events', async () => {
73
50
  const mockEvent1: DriveEvent = {
74
51
  type: DriveEventType.SharedWithMeUpdated,
@@ -88,14 +65,31 @@ describe('CoreEventManager', () => {
88
65
  };
89
66
  mockApiService.getCoreEvents.mockResolvedValue(mockEvents);
90
67
 
91
- const events = [];
92
- for await (const event of coreEventManager.getEvents(eventId)) {
93
- events.push(event);
94
- }
68
+ const events = await Array.fromAsync(coreEventManager.getEvents(eventId));
95
69
 
96
70
  expect(events).toHaveLength(2);
97
71
  expect(events[0]).toEqual(mockEvent1);
98
72
  expect(events[1]).toEqual(mockEvent2);
99
73
  });
74
+
75
+ it('should yield FastForward event there are no events but lastEventId changed', async () => {
76
+ const mockEvents: DriveEventsListWithStatus = {
77
+ latestEventId,
78
+ more: false,
79
+ refresh: false,
80
+ events: [],
81
+ };
82
+ mockApiService.getCoreEvents.mockResolvedValue(mockEvents);
83
+
84
+ const events = await Array.fromAsync(coreEventManager.getEvents(eventId));
85
+
86
+ expect(events).toHaveLength(1);
87
+ expect(events[0]).toEqual({
88
+ type: DriveEventType.FastForward,
89
+ treeEventScopeId: 'core',
90
+ eventId: latestEventId,
91
+ });
92
+ expect(mockApiService.getCoreEvents).toHaveBeenCalledWith(eventId);
93
+ });
100
94
  });
101
95
  });
@@ -32,7 +32,7 @@ export class CoreEventManager implements EventManagerInterface<DriveEvent> {
32
32
  const events = await this.apiService.getCoreEvents(eventId);
33
33
  if (events.events.length === 0 && events.latestEventId !== eventId) {
34
34
  yield {
35
- type: DriveEventType.SharedWithMeUpdated,
35
+ type: DriveEventType.FastForward,
36
36
  treeEventScopeId: 'core',
37
37
  eventId: events.latestEventId,
38
38
  };
@@ -1,11 +1,10 @@
1
1
  import { Logger, ProtonDriveTelemetry } from '../../interface';
2
2
  import { DriveAPIService } from '../apiService';
3
- import { DriveEvent, DriveListener, EventSubscription, LatestEventIdProvider } from './interface';
3
+ import { DriveEvent, DriveListener, EventSubscription, LatestEventIdProvider, SharesService } from './interface';
4
4
  import { EventsAPIService } from './apiService';
5
5
  import { CoreEventManager } from './coreEventManager';
6
6
  import { VolumeEventManager } from './volumeEventManager';
7
7
  import { EventManager } from './eventManager';
8
- import { SharesManager } from '../shares/manager';
9
8
 
10
9
  export type { DriveEvent, DriveListener, EventSubscription } from './interface';
11
10
  export { DriveEventType } from './interface';
@@ -28,7 +27,7 @@ export class DriveEventsService {
28
27
  constructor(
29
28
  private telemetry: ProtonDriveTelemetry,
30
29
  apiService: DriveAPIService,
31
- private shareManagement: SharesManager,
30
+ private sharesService: SharesService,
32
31
  private cacheEventListeners: DriveListener[] = [],
33
32
  private latestEventIdProvider?: LatestEventIdProvider,
34
33
  ) {
@@ -104,7 +103,7 @@ export class DriveEventsService {
104
103
  this.logger.debug(`Creating volume event manager for volume ${volumeId}`);
105
104
  const volumeEventManager = new VolumeEventManager(this.logger, this.apiService, volumeId);
106
105
 
107
- const isOwnVolume = await this.shareManagement.isOwnVolume(volumeId);
106
+ const isOwnVolume = await this.sharesService.isOwnVolume(volumeId);
108
107
  const pollingInterval = this.getDefaultVolumePollingInterval(isOwnVolume);
109
108
  const latestEventId = this.latestEventIdProvider.getLatestEventId(volumeId);
110
109
  const eventManager = new EventManager<DriveEvent>(volumeEventManager, pollingInterval, latestEventId);
@@ -112,3 +112,7 @@ export interface EventManagerInterface<T> {
112
112
  getEvents(eventId: string): AsyncIterable<T>;
113
113
  getLogger(): Logger;
114
114
  }
115
+
116
+ export interface SharesService {
117
+ isOwnVolume(volumeId: string): Promise<boolean>;
118
+ }
@@ -1,7 +1,8 @@
1
1
  import { MemberRole, NodeType } from '../../interface';
2
2
  import { getMockLogger } from '../../tests/logger';
3
- import { DriveAPIService, ErrorCode } from '../apiService';
3
+ import { DriveAPIService, ErrorCode, InvalidRequirementsAPIError } from '../apiService';
4
4
  import { NodeAPIService } from './apiService';
5
+ import { NodeOutOfSyncError } from './errors';
5
6
 
6
7
  function generateAPIFileNode(linkOverrides = {}, overrides = {}) {
7
8
  const node = generateAPINode();
@@ -542,4 +543,37 @@ describe('nodeAPIService', () => {
542
543
  }
543
544
  });
544
545
  });
546
+
547
+ describe('renameNode', () => {
548
+ it('should rename node', async () => {
549
+ await api.renameNode(
550
+ 'volumeId~nodeId1',
551
+ { hash: 'originalHash' },
552
+ { encryptedName: 'encryptedName1', nameSignatureEmail: 'nameSignatureEmail1', hash: 'newHash' },
553
+ );
554
+
555
+ expect(apiMock.put).toHaveBeenCalledWith(
556
+ 'drive/v2/volumes/volumeId/links/nodeId1/rename',
557
+ {
558
+ Name: 'encryptedName1',
559
+ NameSignatureEmail: 'nameSignatureEmail1',
560
+ Hash: 'newHash',
561
+ OriginalHash: 'originalHash',
562
+ },
563
+ undefined,
564
+ );
565
+ });
566
+
567
+ it('should throw error if node is out of sync', async () => {
568
+ apiMock.put = jest.fn().mockRejectedValue(new InvalidRequirementsAPIError('Node is out of sync'));
569
+
570
+ await expect(
571
+ api.renameNode(
572
+ 'volumeId~nodeId1',
573
+ { hash: 'originalHash' },
574
+ { encryptedName: 'encryptedName1', nameSignatureEmail: 'nameSignatureEmail1', hash: 'newHash' },
575
+ ),
576
+ ).rejects.toThrow(new NodeOutOfSyncError('Node is out of sync'));
577
+ });
578
+ });
545
579
  });