@protontech/drive-sdk 0.1.1 → 0.1.2
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.
- package/dist/internal/events/eventManager.d.ts +1 -0
- package/dist/internal/events/eventManager.js +9 -0
- package/dist/internal/events/eventManager.js.map +1 -1
- package/dist/internal/events/eventManager.test.js +53 -38
- package/dist/internal/events/eventManager.test.js.map +1 -1
- package/dist/internal/events/index.d.ts +4 -3
- package/dist/internal/events/index.js +38 -32
- package/dist/internal/events/index.js.map +1 -1
- package/dist/internal/nodes/events.js +7 -7
- package/dist/internal/nodes/events.js.map +1 -1
- package/dist/internal/sharing/cache.d.ts +1 -0
- package/dist/internal/sharing/cache.js +9 -0
- package/dist/internal/sharing/cache.js.map +1 -1
- package/dist/internal/sharing/events.d.ts +1 -0
- package/dist/internal/sharing/events.js +28 -18
- package/dist/internal/sharing/events.js.map +1 -1
- package/dist/internal/sharing/events.test.js +98 -84
- package/dist/internal/sharing/events.test.js.map +1 -1
- package/dist/internal/upload/interface.d.ts +1 -0
- package/dist/internal/upload/manager.d.ts +1 -1
- package/dist/internal/upload/manager.js +8 -4
- package/dist/internal/upload/manager.js.map +1 -1
- package/dist/internal/upload/manager.test.js +7 -10
- package/dist/internal/upload/manager.test.js.map +1 -1
- package/dist/internal/upload/streamUploader.js +1 -1
- package/dist/internal/upload/streamUploader.js.map +1 -1
- package/dist/internal/upload/streamUploader.test.js +1 -1
- package/dist/internal/upload/streamUploader.test.js.map +1 -1
- package/dist/protonDriveClient.js +2 -2
- package/dist/protonDriveClient.js.map +1 -1
- package/dist/transformers.d.ts +1 -1
- package/dist/transformers.js +1 -0
- package/dist/transformers.js.map +1 -1
- package/package.json +1 -1
- package/src/internal/events/eventManager.test.ts +61 -40
- package/src/internal/events/eventManager.ts +10 -0
- package/src/internal/events/index.ts +53 -35
- package/src/internal/nodes/events.ts +6 -7
- package/src/internal/sharing/cache.ts +9 -0
- package/src/internal/sharing/events.test.ts +104 -89
- package/src/internal/sharing/events.ts +33 -18
- package/src/internal/upload/interface.ts +1 -0
- package/src/internal/upload/manager.test.ts +7 -10
- package/src/internal/upload/manager.ts +7 -4
- package/src/internal/upload/streamUploader.test.ts +1 -1
- package/src/internal/upload/streamUploader.ts +1 -1
- package/src/protonDriveClient.ts +2 -2
- package/src/transformers.ts +2 -0
|
@@ -21,6 +21,7 @@ describe('handleSharedByMeNodes', () => {
|
|
|
21
21
|
removeSharedByMeNodeUid: jest.fn(),
|
|
22
22
|
setSharedWithMeNodeUids: jest.fn(),
|
|
23
23
|
getSharedByMeNodeUids: jest.fn().mockResolvedValue(['cachedNodeUid']),
|
|
24
|
+
hasSharedByMeNodeUidsLoaded: jest.fn().mockResolvedValue(true),
|
|
24
25
|
};
|
|
25
26
|
sharesManager = {
|
|
26
27
|
isOwnVolume: jest.fn(async (volumeId: string) => volumeId === 'MyVolume1'),
|
|
@@ -28,94 +29,108 @@ describe('handleSharedByMeNodes', () => {
|
|
|
28
29
|
sharingEventHandler = new SharingEventHandler(getMockLogger(), cache, sharesManager);
|
|
29
30
|
});
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
32
|
+
it('should add if new own shared node is created', async () => {
|
|
33
|
+
const event: DriveEvent = {
|
|
34
|
+
eventId: '1',
|
|
35
|
+
type: DriveEventType.NodeCreated,
|
|
36
|
+
nodeUid: 'newNodeUid',
|
|
37
|
+
parentNodeUid: 'parentUid',
|
|
38
|
+
isTrashed: false,
|
|
39
|
+
isShared: true,
|
|
40
|
+
treeEventScopeId: 'MyVolume1',
|
|
41
|
+
};
|
|
42
|
+
await sharingEventHandler.handleDriveEvent(event);
|
|
43
|
+
expect(cache.addSharedByMeNodeUid).toHaveBeenCalledWith('newNodeUid');
|
|
44
|
+
expect(cache.setSharedWithMeNodeUids).not.toHaveBeenCalled();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('should not add if new shared node is not own', async () => {
|
|
48
|
+
const event: DriveEvent = {
|
|
49
|
+
eventId: '1',
|
|
50
|
+
type: DriveEventType.NodeCreated,
|
|
51
|
+
nodeUid: 'newNodeUid',
|
|
52
|
+
parentNodeUid: 'parentUid',
|
|
53
|
+
isTrashed: false,
|
|
54
|
+
isShared: true,
|
|
55
|
+
treeEventScopeId: 'NotOwnVolume',
|
|
56
|
+
};
|
|
57
|
+
await sharingEventHandler.handleDriveEvent(event);
|
|
58
|
+
expect(cache.addSharedByMeNodeUid).not.toHaveBeenCalled();
|
|
59
|
+
expect(cache.setSharedWithMeNodeUids).not.toHaveBeenCalled();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should not add if new own node is not shared', async () => {
|
|
63
|
+
const event: DriveEvent = {
|
|
64
|
+
type: DriveEventType.NodeCreated,
|
|
65
|
+
nodeUid: 'newNodeUid',
|
|
66
|
+
parentNodeUid: 'parentUid',
|
|
67
|
+
isTrashed: false,
|
|
68
|
+
isShared: false,
|
|
69
|
+
eventId: '1',
|
|
70
|
+
treeEventScopeId: 'MyVolume1',
|
|
71
|
+
};
|
|
72
|
+
await sharingEventHandler.handleDriveEvent(event);
|
|
73
|
+
expect(cache.addSharedByMeNodeUid).not.toHaveBeenCalled();
|
|
74
|
+
expect(cache.setSharedWithMeNodeUids).not.toHaveBeenCalled();
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('should add if own node is updated and shared', async () => {
|
|
78
|
+
const event: DriveEvent = {
|
|
79
|
+
type: DriveEventType.NodeUpdated,
|
|
80
|
+
nodeUid: 'cachedNodeUid',
|
|
81
|
+
parentNodeUid: 'parentUid',
|
|
82
|
+
isTrashed: false,
|
|
83
|
+
isShared: true,
|
|
84
|
+
eventId: '1',
|
|
85
|
+
treeEventScopeId: 'MyVolume1',
|
|
86
|
+
};
|
|
87
|
+
await sharingEventHandler.handleDriveEvent(event);
|
|
88
|
+
expect(cache.addSharedByMeNodeUid).toHaveBeenCalledWith('cachedNodeUid');
|
|
89
|
+
expect(cache.setSharedWithMeNodeUids).not.toHaveBeenCalled();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should remove if shared node is un-shared', async () => {
|
|
93
|
+
const event: DriveEvent = {
|
|
94
|
+
type: DriveEventType.NodeUpdated,
|
|
95
|
+
nodeUid: 'cachedNodeUid',
|
|
96
|
+
parentNodeUid: 'parentUid',
|
|
97
|
+
isTrashed: false,
|
|
98
|
+
isShared: false,
|
|
99
|
+
eventId: '1',
|
|
100
|
+
treeEventScopeId: 'MyVolume1',
|
|
101
|
+
};
|
|
102
|
+
await sharingEventHandler.handleDriveEvent(event);
|
|
103
|
+
expect(cache.removeSharedByMeNodeUid).toHaveBeenCalledWith('cachedNodeUid');
|
|
104
|
+
expect(cache.setSharedWithMeNodeUids).not.toHaveBeenCalled();
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('should remove if shared node is deleted', async () => {
|
|
108
|
+
const event: DriveEvent = {
|
|
109
|
+
type: DriveEventType.NodeDeleted,
|
|
110
|
+
nodeUid: 'cachedNodeUid',
|
|
111
|
+
parentNodeUid: 'parentUid',
|
|
112
|
+
eventId: '1',
|
|
113
|
+
treeEventScopeId: 'MyVolume1',
|
|
114
|
+
};
|
|
115
|
+
await sharingEventHandler.handleDriveEvent(event);
|
|
116
|
+
expect(cache.removeSharedByMeNodeUid).toHaveBeenCalledWith('cachedNodeUid');
|
|
117
|
+
expect(cache.setSharedWithMeNodeUids).not.toHaveBeenCalled();
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('should not update cache if shared by me is not loaded', async () => {
|
|
121
|
+
cache.hasSharedByMeNodeUidsLoaded = jest.fn().mockResolvedValue(false);
|
|
122
|
+
const event: DriveEvent = {
|
|
123
|
+
eventId: '1',
|
|
124
|
+
type: DriveEventType.NodeCreated,
|
|
125
|
+
nodeUid: 'newNodeUid',
|
|
126
|
+
parentNodeUid: 'parentUid',
|
|
127
|
+
isTrashed: false,
|
|
128
|
+
isShared: true,
|
|
129
|
+
treeEventScopeId: 'MyVolume1',
|
|
130
|
+
};
|
|
131
|
+
await sharingEventHandler.handleDriveEvent(event);
|
|
132
|
+
expect(cache.addSharedByMeNodeUid).not.toHaveBeenCalled();
|
|
133
|
+
expect(cache.setSharedWithMeNodeUids).not.toHaveBeenCalled();
|
|
119
134
|
});
|
|
120
135
|
});
|
|
121
136
|
|
|
@@ -141,7 +156,7 @@ describe('handleSharedWithMeNodes', () => {
|
|
|
141
156
|
} as any;
|
|
142
157
|
});
|
|
143
158
|
|
|
144
|
-
it('should
|
|
159
|
+
it('should update cache', async () => {
|
|
145
160
|
const event: DriveEvent = {
|
|
146
161
|
type: DriveEventType.SharedWithMeUpdated,
|
|
147
162
|
eventId: 'event1',
|
|
@@ -30,26 +30,41 @@ export class SharingEventHandler {
|
|
|
30
30
|
await this.cache.setSharedWithMeNodeUids(undefined);
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
33
|
-
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
if (event.type === DriveEventType.NodeCreated || event.type == DriveEventType.NodeUpdated) {
|
|
37
|
-
if (event.isShared && !event.isTrashed) {
|
|
38
|
-
await this.cache.addSharedByMeNodeUid(event.nodeUid);
|
|
39
|
-
} else {
|
|
40
|
-
await this.cache.removeSharedByMeNodeUid(event.nodeUid);
|
|
41
|
-
}
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
if (event.type === DriveEventType.NodeDeleted) {
|
|
45
|
-
await this.cache.removeSharedByMeNodeUid(event.nodeUid);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
if (event.type === DriveEventType.TreeRefresh || event.type === DriveEventType.TreeRemove) {
|
|
49
|
-
await this.cache.setSharedWithMeNodeUids(undefined);
|
|
50
|
-
}
|
|
33
|
+
await this.handleSharedByMeNodeUidsLoaded(event);
|
|
51
34
|
} catch (error: unknown) {
|
|
52
35
|
this.logger.error(`Skipping shared by me node cache update`, error);
|
|
53
36
|
}
|
|
54
37
|
}
|
|
38
|
+
|
|
39
|
+
private async handleSharedByMeNodeUidsLoaded(event: DriveEvent) {
|
|
40
|
+
if (event.type === DriveEventType.TreeRefresh || event.type === DriveEventType.TreeRemove) {
|
|
41
|
+
await this.cache.setSharedWithMeNodeUids(undefined);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (![DriveEventType.NodeCreated, DriveEventType.NodeUpdated, DriveEventType.NodeDeleted].includes(event.type)) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const hasSharedByMeLoaded = await this.cache.hasSharedByMeNodeUidsLoaded();
|
|
50
|
+
if (!hasSharedByMeLoaded) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const isOwnVolume = await this.shares.isOwnVolume(event.treeEventScopeId);
|
|
55
|
+
if (!isOwnVolume) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (event.type === DriveEventType.NodeCreated || event.type == DriveEventType.NodeUpdated) {
|
|
60
|
+
if (event.isShared && !event.isTrashed) {
|
|
61
|
+
await this.cache.addSharedByMeNodeUid(event.nodeUid);
|
|
62
|
+
} else {
|
|
63
|
+
await this.cache.removeSharedByMeNodeUid(event.nodeUid);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (event.type === DriveEventType.NodeDeleted) {
|
|
67
|
+
await this.cache.removeSharedByMeNodeUid(event.nodeUid);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
55
70
|
}
|
|
@@ -91,9 +91,8 @@ describe('UploadManager', () => {
|
|
|
91
91
|
email: 'signatureEmail',
|
|
92
92
|
addressId: 'addressId',
|
|
93
93
|
}),
|
|
94
|
-
notifyChildCreated: jest.fn(
|
|
95
|
-
|
|
96
|
-
}),
|
|
94
|
+
notifyChildCreated: jest.fn(),
|
|
95
|
+
notifyNodeChanged: jest.fn(),
|
|
97
96
|
};
|
|
98
97
|
|
|
99
98
|
manager = new UploadManager(telemetry, apiService, cryptoService, nodesService, clientUid);
|
|
@@ -337,10 +336,6 @@ describe('UploadManager', () => {
|
|
|
337
336
|
},
|
|
338
337
|
};
|
|
339
338
|
const manifest = new Uint8Array([1, 2, 3]);
|
|
340
|
-
const metadata = {
|
|
341
|
-
mediaType: 'myMimeType',
|
|
342
|
-
expectedSize: 123456,
|
|
343
|
-
};
|
|
344
339
|
const extendedAttributes = {
|
|
345
340
|
modificationTime: new Date(),
|
|
346
341
|
digests: {
|
|
@@ -349,7 +344,7 @@ describe('UploadManager', () => {
|
|
|
349
344
|
};
|
|
350
345
|
|
|
351
346
|
it('should commit revision draft', async () => {
|
|
352
|
-
await manager.commitDraft(nodeRevisionDraft as any, manifest,
|
|
347
|
+
await manager.commitDraft(nodeRevisionDraft as any, manifest, extendedAttributes);
|
|
353
348
|
|
|
354
349
|
expect(cryptoService.commitFile).toHaveBeenCalledWith(
|
|
355
350
|
nodeRevisionDraft.nodeKeys,
|
|
@@ -360,7 +355,8 @@ describe('UploadManager', () => {
|
|
|
360
355
|
nodeRevisionDraft.nodeRevisionUid,
|
|
361
356
|
expect.anything(),
|
|
362
357
|
);
|
|
363
|
-
expect(nodesService.
|
|
358
|
+
expect(nodesService.notifyNodeChanged).toHaveBeenCalledWith('newNode:nodeUid');
|
|
359
|
+
expect(nodesService.notifyChildCreated).not.toHaveBeenCalled();
|
|
364
360
|
});
|
|
365
361
|
|
|
366
362
|
it('should commit node draft', async () => {
|
|
@@ -373,7 +369,7 @@ describe('UploadManager', () => {
|
|
|
373
369
|
hash: 'newNode:hash',
|
|
374
370
|
},
|
|
375
371
|
};
|
|
376
|
-
await manager.commitDraft(nodeRevisionDraftWithNewNodeInfo as any, manifest,
|
|
372
|
+
await manager.commitDraft(nodeRevisionDraftWithNewNodeInfo as any, manifest, extendedAttributes);
|
|
377
373
|
|
|
378
374
|
expect(cryptoService.commitFile).toHaveBeenCalledWith(
|
|
379
375
|
nodeRevisionDraft.nodeKeys,
|
|
@@ -385,6 +381,7 @@ describe('UploadManager', () => {
|
|
|
385
381
|
expect.anything(),
|
|
386
382
|
);
|
|
387
383
|
expect(nodesService.notifyChildCreated).toHaveBeenCalledWith('parentUid');
|
|
384
|
+
expect(nodesService.notifyNodeChanged).not.toHaveBeenCalled();
|
|
388
385
|
});
|
|
389
386
|
});
|
|
390
387
|
});
|
|
@@ -260,7 +260,6 @@ export class UploadManager {
|
|
|
260
260
|
async commitDraft(
|
|
261
261
|
nodeRevisionDraft: NodeRevisionDraft,
|
|
262
262
|
manifest: Uint8Array,
|
|
263
|
-
_metadata: UploadMetadata,
|
|
264
263
|
extendedAttributes: {
|
|
265
264
|
modificationTime?: Date;
|
|
266
265
|
size?: number;
|
|
@@ -277,9 +276,13 @@ export class UploadManager {
|
|
|
277
276
|
generatedExtendedAttributes,
|
|
278
277
|
);
|
|
279
278
|
await this.apiService.commitDraftRevision(nodeRevisionDraft.nodeRevisionUid, nodeCommitCrypto);
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
279
|
+
|
|
280
|
+
// If new revision to existing node was created, invalidate the node.
|
|
281
|
+
// Otherwise notify about the new child in the parent.
|
|
282
|
+
if (nodeRevisionDraft.newNodeInfo) {
|
|
283
|
+
await this.nodesService.notifyChildCreated(nodeRevisionDraft.newNodeInfo.parentUid);
|
|
284
|
+
} else {
|
|
285
|
+
await this.nodesService.notifyNodeChanged(nodeRevisionDraft.nodeUid);
|
|
283
286
|
}
|
|
284
287
|
}
|
|
285
288
|
}
|
|
@@ -147,7 +147,7 @@ describe('StreamUploader', () => {
|
|
|
147
147
|
|
|
148
148
|
const numberOfExpectedBlocks = Math.ceil(metadata.expectedSize / FILE_CHUNK_SIZE);
|
|
149
149
|
expect(uploadManager.commitDraft).toHaveBeenCalledTimes(1);
|
|
150
|
-
expect(uploadManager.commitDraft).toHaveBeenCalledWith(revisionDraft, expect.anything(),
|
|
150
|
+
expect(uploadManager.commitDraft).toHaveBeenCalledWith(revisionDraft, expect.anything(), {
|
|
151
151
|
size: metadata.expectedSize,
|
|
152
152
|
blockSizes: metadata.expectedSize
|
|
153
153
|
? [
|
|
@@ -217,7 +217,7 @@ export class StreamUploader {
|
|
|
217
217
|
blockSizes: uploadedBlocks.map((block) => block.originalSize),
|
|
218
218
|
digests: this.digests.digests(),
|
|
219
219
|
};
|
|
220
|
-
await this.uploadManager.commitDraft(this.revisionDraft, this.manifest,
|
|
220
|
+
await this.uploadManager.commitDraft(this.revisionDraft, this.manifest, extendedAttributes);
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
private async encryptThumbnails(thumbnails: Thumbnail[]) {
|
package/src/protonDriveClient.ts
CHANGED
|
@@ -155,8 +155,8 @@ export class ProtonDriveClient {
|
|
|
155
155
|
);
|
|
156
156
|
// These are used to keep the internal cache up to date
|
|
157
157
|
const cacheEventListeners: DriveListener[] = [
|
|
158
|
-
this.nodes.eventHandler.updateNodesCacheOnEvent,
|
|
159
|
-
this.sharing.eventHandler.handleDriveEvent,
|
|
158
|
+
this.nodes.eventHandler.updateNodesCacheOnEvent.bind(this.nodes.eventHandler),
|
|
159
|
+
this.sharing.eventHandler.handleDriveEvent.bind(this.sharing.eventHandler),
|
|
160
160
|
];
|
|
161
161
|
this.events = new DriveEventsService(
|
|
162
162
|
telemetry,
|
package/src/transformers.ts
CHANGED
|
@@ -29,6 +29,7 @@ type InternalPartialNode = Pick<
|
|
|
29
29
|
| 'totalStorageSize'
|
|
30
30
|
| 'errors'
|
|
31
31
|
| 'shareId'
|
|
32
|
+
| 'treeEventScopeId'
|
|
32
33
|
>;
|
|
33
34
|
|
|
34
35
|
type NodeUid = string | { uid: string } | Result<{ uid: string }, { uid: string }>;
|
|
@@ -92,6 +93,7 @@ export function convertInternalNode(node: InternalPartialNode): PublicMaybeNode
|
|
|
92
93
|
totalStorageSize: node.totalStorageSize,
|
|
93
94
|
folder: node.folder,
|
|
94
95
|
deprecatedShareId: node.shareId,
|
|
96
|
+
treeEventScopeId: node.treeEventScopeId,
|
|
95
97
|
};
|
|
96
98
|
|
|
97
99
|
const name = node.name;
|