@protontech/drive-sdk 0.0.12 → 0.1.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.
- package/dist/cache/index.d.ts +1 -0
- package/dist/cache/index.js +3 -1
- package/dist/cache/index.js.map +1 -1
- package/dist/cache/memoryCache.d.ts +1 -1
- package/dist/cache/nullCache.d.ts +14 -0
- package/dist/cache/nullCache.js +37 -0
- package/dist/cache/nullCache.js.map +1 -0
- package/dist/config.d.ts +16 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/crypto/openPGPCrypto.js +2 -0
- package/dist/crypto/openPGPCrypto.js.map +1 -1
- package/dist/diagnostic/eventsGenerator.d.ts +14 -0
- package/dist/diagnostic/eventsGenerator.js +49 -0
- package/dist/diagnostic/eventsGenerator.js.map +1 -0
- package/dist/diagnostic/httpClient.d.ts +16 -0
- package/dist/diagnostic/httpClient.js +81 -0
- package/dist/diagnostic/httpClient.js.map +1 -0
- package/dist/diagnostic/index.d.ts +10 -0
- package/dist/diagnostic/index.js +35 -0
- package/dist/diagnostic/index.js.map +1 -0
- package/dist/diagnostic/integrityVerificationStream.d.ts +21 -0
- package/dist/diagnostic/integrityVerificationStream.js +56 -0
- package/dist/diagnostic/integrityVerificationStream.js.map +1 -0
- package/dist/diagnostic/interface.d.ts +102 -0
- package/dist/diagnostic/interface.js +3 -0
- package/dist/diagnostic/interface.js.map +1 -0
- package/dist/diagnostic/sdkDiagnostic.d.ts +22 -0
- package/dist/diagnostic/sdkDiagnostic.js +216 -0
- package/dist/diagnostic/sdkDiagnostic.js.map +1 -0
- package/dist/diagnostic/sdkDiagnosticFull.d.ts +18 -0
- package/dist/diagnostic/sdkDiagnosticFull.js +35 -0
- package/dist/diagnostic/sdkDiagnosticFull.js.map +1 -0
- package/dist/diagnostic/telemetry.d.ts +25 -0
- package/dist/diagnostic/telemetry.js +70 -0
- package/dist/diagnostic/telemetry.js.map +1 -0
- package/dist/diagnostic/zipGenerators.d.ts +9 -0
- package/dist/diagnostic/zipGenerators.js +64 -0
- package/dist/diagnostic/zipGenerators.js.map +1 -0
- package/dist/diagnostic/zipGenerators.test.js +144 -0
- package/dist/diagnostic/zipGenerators.test.js.map +1 -0
- package/dist/errors.d.ts +8 -3
- package/dist/errors.js +11 -4
- package/dist/errors.js.map +1 -1
- package/dist/interface/config.d.ts +26 -0
- package/dist/interface/config.js +3 -0
- package/dist/interface/config.js.map +1 -0
- package/dist/interface/download.d.ts +2 -2
- package/dist/interface/events.d.ts +60 -20
- package/dist/interface/events.js +11 -1
- package/dist/interface/events.js.map +1 -1
- package/dist/interface/httpClient.d.ts +0 -14
- package/dist/interface/index.d.ts +9 -5
- package/dist/interface/index.js +2 -1
- package/dist/interface/index.js.map +1 -1
- package/dist/interface/nodes.d.ts +21 -1
- package/dist/interface/nodes.js +11 -0
- package/dist/interface/nodes.js.map +1 -1
- package/dist/interface/sharing.d.ts +1 -0
- package/dist/interface/upload.d.ts +57 -3
- package/dist/internal/apiService/driveTypes.d.ts +1341 -465
- package/dist/internal/apiService/errors.js +2 -2
- package/dist/internal/apiService/errors.js.map +1 -1
- package/dist/internal/apiService/transformers.js +2 -0
- package/dist/internal/apiService/transformers.js.map +1 -1
- package/dist/internal/asyncIteratorMap.d.ts +15 -0
- package/dist/internal/asyncIteratorMap.js +59 -0
- package/dist/internal/asyncIteratorMap.js.map +1 -0
- package/dist/internal/asyncIteratorMap.test.js +120 -0
- package/dist/internal/asyncIteratorMap.test.js.map +1 -0
- package/dist/internal/download/apiService.js +32 -31
- package/dist/internal/download/apiService.js.map +1 -1
- package/dist/internal/download/fileDownloader.d.ts +2 -2
- package/dist/internal/download/fileDownloader.js.map +1 -1
- package/dist/internal/events/apiService.d.ts +4 -6
- package/dist/internal/events/apiService.js +15 -22
- package/dist/internal/events/apiService.js.map +1 -1
- package/dist/internal/events/coreEventManager.d.ts +7 -10
- package/dist/internal/events/coreEventManager.js +19 -36
- package/dist/internal/events/coreEventManager.js.map +1 -1
- package/dist/internal/events/coreEventManager.test.d.ts +1 -0
- package/dist/internal/events/coreEventManager.test.js +87 -0
- package/dist/internal/events/coreEventManager.test.js.map +1 -0
- package/dist/internal/events/eventManager.d.ts +11 -36
- package/dist/internal/events/eventManager.js +59 -105
- package/dist/internal/events/eventManager.js.map +1 -1
- package/dist/internal/events/eventManager.test.js +167 -82
- package/dist/internal/events/eventManager.test.js.map +1 -1
- package/dist/internal/events/index.d.ts +13 -33
- package/dist/internal/events/index.js +56 -72
- package/dist/internal/events/index.js.map +1 -1
- package/dist/internal/events/interface.d.ts +59 -14
- package/dist/internal/events/interface.js +13 -3
- package/dist/internal/events/interface.js.map +1 -1
- package/dist/internal/events/volumeEventManager.d.ts +7 -17
- package/dist/internal/events/volumeEventManager.js +58 -45
- package/dist/internal/events/volumeEventManager.js.map +1 -1
- package/dist/internal/events/volumeEventManager.test.d.ts +1 -0
- package/dist/internal/events/volumeEventManager.test.js +203 -0
- package/dist/internal/events/volumeEventManager.test.js.map +1 -0
- package/dist/internal/nodes/apiService.d.ts +2 -2
- package/dist/internal/nodes/apiService.js +16 -6
- package/dist/internal/nodes/apiService.js.map +1 -1
- package/dist/internal/nodes/apiService.test.js +30 -8
- package/dist/internal/nodes/apiService.test.js.map +1 -1
- package/dist/internal/nodes/cache.d.ts +10 -1
- package/dist/internal/nodes/cache.js +18 -0
- package/dist/internal/nodes/cache.js.map +1 -1
- package/dist/internal/nodes/cache.test.js +1 -0
- package/dist/internal/nodes/cache.test.js.map +1 -1
- package/dist/internal/nodes/cryptoService.d.ts +1 -1
- package/dist/internal/nodes/cryptoService.js.map +1 -1
- package/dist/internal/nodes/cryptoService.test.js +34 -0
- package/dist/internal/nodes/cryptoService.test.js.map +1 -1
- package/dist/internal/nodes/events.d.ts +7 -83
- package/dist/internal/nodes/events.js +43 -217
- package/dist/internal/nodes/events.js.map +1 -1
- package/dist/internal/nodes/events.test.js +27 -277
- package/dist/internal/nodes/events.test.js.map +1 -1
- package/dist/internal/nodes/index.d.ts +3 -4
- package/dist/internal/nodes/index.js +5 -5
- package/dist/internal/nodes/index.js.map +1 -1
- package/dist/internal/nodes/interface.d.ts +3 -1
- package/dist/internal/nodes/nodesAccess.d.ts +15 -0
- package/dist/internal/nodes/nodesAccess.js +65 -7
- package/dist/internal/nodes/nodesAccess.js.map +1 -1
- package/dist/internal/nodes/nodesAccess.test.js +132 -93
- package/dist/internal/nodes/nodesAccess.test.js.map +1 -1
- package/dist/internal/nodes/nodesManagement.d.ts +1 -3
- package/dist/internal/nodes/nodesManagement.js +12 -26
- package/dist/internal/nodes/nodesManagement.js.map +1 -1
- package/dist/internal/nodes/nodesManagement.test.js +35 -14
- package/dist/internal/nodes/nodesManagement.test.js.map +1 -1
- package/dist/internal/shares/cache.d.ts +2 -0
- package/dist/internal/shares/cache.js +2 -0
- package/dist/internal/shares/cache.js.map +1 -1
- package/dist/internal/shares/manager.d.ts +1 -0
- package/dist/internal/shares/manager.js +3 -0
- package/dist/internal/shares/manager.js.map +1 -1
- package/dist/internal/sharing/apiService.js +20 -2
- package/dist/internal/sharing/apiService.js.map +1 -1
- package/dist/internal/sharing/cryptoService.js +1 -0
- package/dist/internal/sharing/cryptoService.js.map +1 -1
- package/dist/internal/sharing/events.d.ts +23 -55
- package/dist/internal/sharing/events.js +46 -138
- package/dist/internal/sharing/events.js.map +1 -1
- package/dist/internal/sharing/events.test.js +77 -180
- package/dist/internal/sharing/events.test.js.map +1 -1
- package/dist/internal/sharing/index.d.ts +4 -5
- package/dist/internal/sharing/index.js +5 -5
- package/dist/internal/sharing/index.js.map +1 -1
- package/dist/internal/sharing/interface.d.ts +3 -0
- package/dist/internal/sharing/sharingManagement.d.ts +2 -3
- package/dist/internal/sharing/sharingManagement.js +7 -9
- package/dist/internal/sharing/sharingManagement.js.map +1 -1
- package/dist/internal/sharing/sharingManagement.test.js +9 -39
- package/dist/internal/sharing/sharingManagement.test.js.map +1 -1
- package/dist/internal/upload/apiService.d.ts +2 -3
- package/dist/internal/upload/apiService.js +7 -4
- package/dist/internal/upload/apiService.js.map +1 -1
- package/dist/internal/upload/fileUploader.d.ts +49 -53
- package/dist/internal/upload/fileUploader.js +91 -395
- package/dist/internal/upload/fileUploader.js.map +1 -1
- package/dist/internal/upload/fileUploader.test.js +38 -292
- package/dist/internal/upload/fileUploader.test.js.map +1 -1
- package/dist/internal/upload/index.d.ts +5 -5
- package/dist/internal/upload/index.js +23 -44
- package/dist/internal/upload/index.js.map +1 -1
- package/dist/internal/upload/interface.d.ts +2 -0
- package/dist/internal/upload/manager.d.ts +6 -6
- package/dist/internal/upload/manager.js +32 -66
- package/dist/internal/upload/manager.js.map +1 -1
- package/dist/internal/upload/manager.test.js +100 -117
- package/dist/internal/upload/manager.test.js.map +1 -1
- package/dist/internal/upload/streamUploader.d.ts +62 -0
- package/dist/internal/upload/streamUploader.js +440 -0
- package/dist/internal/upload/streamUploader.js.map +1 -0
- package/dist/internal/upload/streamUploader.test.d.ts +1 -0
- package/dist/internal/upload/streamUploader.test.js +358 -0
- package/dist/internal/upload/streamUploader.test.js.map +1 -0
- package/dist/protonDriveClient.d.ts +22 -165
- package/dist/protonDriveClient.js +27 -191
- package/dist/protonDriveClient.js.map +1 -1
- package/dist/protonDrivePhotosClient.js +3 -2
- package/dist/protonDrivePhotosClient.js.map +1 -1
- package/package.json +4 -4
- package/src/cache/index.ts +1 -0
- package/src/cache/memoryCache.ts +1 -1
- package/src/cache/nullCache.ts +38 -0
- package/src/config.ts +17 -2
- package/src/crypto/openPGPCrypto.ts +2 -0
- package/src/diagnostic/eventsGenerator.ts +48 -0
- package/src/diagnostic/httpClient.ts +80 -0
- package/src/diagnostic/index.ts +38 -0
- package/src/diagnostic/integrityVerificationStream.ts +56 -0
- package/src/diagnostic/interface.ts +158 -0
- package/src/diagnostic/sdkDiagnostic.ts +238 -0
- package/src/diagnostic/sdkDiagnosticFull.ts +40 -0
- package/src/diagnostic/telemetry.ts +71 -0
- package/src/diagnostic/zipGenerators.test.ts +177 -0
- package/src/diagnostic/zipGenerators.ts +70 -0
- package/src/errors.ts +13 -4
- package/src/interface/config.ts +28 -0
- package/src/interface/download.ts +2 -2
- package/src/interface/events.ts +66 -21
- package/src/interface/httpClient.ts +0 -16
- package/src/interface/index.ts +9 -5
- package/src/interface/nodes.ts +32 -12
- package/src/interface/sharing.ts +1 -0
- package/src/interface/upload.ts +59 -3
- package/src/internal/apiService/driveTypes.ts +1341 -465
- package/src/internal/apiService/errors.ts +3 -2
- package/src/internal/apiService/transformers.ts +2 -0
- package/src/internal/asyncIteratorMap.test.ts +150 -0
- package/src/internal/asyncIteratorMap.ts +64 -0
- package/src/internal/download/apiService.ts +11 -8
- package/src/internal/download/fileDownloader.ts +2 -2
- package/src/internal/events/apiService.ts +25 -28
- package/src/internal/events/coreEventManager.test.ts +101 -0
- package/src/internal/events/coreEventManager.ts +20 -45
- package/src/internal/events/eventManager.test.ts +201 -88
- package/src/internal/events/eventManager.ts +69 -115
- package/src/internal/events/index.ts +54 -84
- package/src/internal/events/interface.ts +70 -15
- package/src/internal/events/volumeEventManager.test.ts +243 -0
- package/src/internal/events/volumeEventManager.ts +55 -53
- package/src/internal/nodes/apiService.test.ts +36 -7
- package/src/internal/nodes/apiService.ts +19 -7
- package/src/internal/nodes/cache.test.ts +1 -0
- package/src/internal/nodes/cache.ts +21 -2
- package/src/internal/nodes/cryptoService.test.ts +38 -0
- package/src/internal/nodes/cryptoService.ts +1 -1
- package/src/internal/nodes/events.test.ts +29 -335
- package/src/internal/nodes/events.ts +45 -253
- package/src/internal/nodes/index.ts +6 -8
- package/src/internal/nodes/interface.ts +6 -3
- package/src/internal/nodes/nodesAccess.test.ts +133 -91
- package/src/internal/nodes/nodesAccess.ts +70 -8
- package/src/internal/nodes/nodesManagement.test.ts +39 -15
- package/src/internal/nodes/nodesManagement.ts +12 -30
- package/src/internal/shares/cache.ts +4 -2
- package/src/internal/shares/manager.ts +9 -5
- package/src/internal/sharing/apiService.ts +25 -2
- package/src/internal/sharing/cache.ts +1 -1
- package/src/internal/sharing/cryptoService.ts +1 -0
- package/src/internal/sharing/events.test.ts +89 -195
- package/src/internal/sharing/events.ts +42 -156
- package/src/internal/sharing/index.ts +6 -9
- package/src/internal/sharing/interface.ts +6 -2
- package/src/internal/sharing/sharingManagement.test.ts +10 -40
- package/src/internal/sharing/sharingManagement.ts +7 -11
- package/src/internal/upload/apiService.ts +5 -6
- package/src/internal/upload/fileUploader.test.ts +46 -376
- package/src/internal/upload/fileUploader.ts +114 -494
- package/src/internal/upload/index.ts +30 -54
- package/src/internal/upload/interface.ts +2 -0
- package/src/internal/upload/manager.test.ts +107 -124
- package/src/internal/upload/manager.ts +48 -80
- package/src/internal/upload/streamUploader.test.ts +468 -0
- package/src/internal/upload/streamUploader.ts +550 -0
- package/src/protonDriveClient.ts +80 -248
- package/src/protonDrivePhotosClient.ts +4 -3
- package/dist/internal/events/cache.d.ts +0 -28
- package/dist/internal/events/cache.js +0 -67
- package/dist/internal/events/cache.js.map +0 -1
- package/dist/internal/events/cache.test.js +0 -43
- package/dist/internal/events/cache.test.js.map +0 -1
- package/dist/internal/nodes/index.test.js +0 -112
- package/dist/internal/nodes/index.test.js.map +0 -1
- package/src/internal/events/cache.test.ts +0 -47
- package/src/internal/events/cache.ts +0 -80
- package/src/internal/nodes/index.test.ts +0 -135
- /package/dist/{internal/events/cache.test.d.ts → diagnostic/zipGenerators.test.d.ts} +0 -0
- /package/dist/internal/{nodes/index.test.d.ts → asyncIteratorMap.test.d.ts} +0 -0
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const interface_1 = require("../../interface");
|
|
4
|
+
const errors_1 = require("../../errors");
|
|
5
|
+
const apiService_1 = require("../apiService");
|
|
6
|
+
const streamUploader_1 = require("./streamUploader");
|
|
7
|
+
const controller_1 = require("./controller");
|
|
8
|
+
const BLOCK_ENCRYPTION_OVERHEAD = 10000;
|
|
9
|
+
async function mockEncryptBlock(verifyBlock, _, block, index) {
|
|
10
|
+
await verifyBlock(block);
|
|
11
|
+
return {
|
|
12
|
+
index,
|
|
13
|
+
encryptedData: block,
|
|
14
|
+
armoredSignature: 'signature',
|
|
15
|
+
verificationToken: 'verificationToken',
|
|
16
|
+
originalSize: block.length,
|
|
17
|
+
encryptedSize: block.length + BLOCK_ENCRYPTION_OVERHEAD,
|
|
18
|
+
hash: 'blockHash',
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function mockUploadBlock(_, __, encryptedBlock, onProgress) {
|
|
22
|
+
onProgress(encryptedBlock.length);
|
|
23
|
+
}
|
|
24
|
+
describe('StreamUploader', () => {
|
|
25
|
+
let telemetry;
|
|
26
|
+
let apiService;
|
|
27
|
+
let cryptoService;
|
|
28
|
+
let uploadManager;
|
|
29
|
+
let blockVerifier;
|
|
30
|
+
let revisionDraft;
|
|
31
|
+
let metadata;
|
|
32
|
+
let controller;
|
|
33
|
+
let onFinish;
|
|
34
|
+
let abortController;
|
|
35
|
+
let uploader;
|
|
36
|
+
beforeEach(() => {
|
|
37
|
+
// @ts-expect-error No need to implement all methods for mocking
|
|
38
|
+
telemetry = {
|
|
39
|
+
getLoggerForRevision: jest.fn().mockReturnValue({
|
|
40
|
+
debug: jest.fn(),
|
|
41
|
+
info: jest.fn(),
|
|
42
|
+
warn: jest.fn(),
|
|
43
|
+
error: jest.fn(),
|
|
44
|
+
}),
|
|
45
|
+
logBlockVerificationError: jest.fn(),
|
|
46
|
+
uploadFailed: jest.fn(),
|
|
47
|
+
uploadFinished: jest.fn(),
|
|
48
|
+
};
|
|
49
|
+
// @ts-expect-error No need to implement all methods for mocking
|
|
50
|
+
apiService = {
|
|
51
|
+
requestBlockUpload: jest.fn().mockImplementation((_, __, blocks) => ({
|
|
52
|
+
blockTokens: blocks.contentBlocks.map((block) => ({
|
|
53
|
+
index: block.index,
|
|
54
|
+
bareUrl: `bareUrl/block:${block.index}`,
|
|
55
|
+
token: `token/block:${block.index}`,
|
|
56
|
+
})),
|
|
57
|
+
thumbnailTokens: (blocks.thumbnails || []).map((thumbnail) => ({
|
|
58
|
+
type: thumbnail.type,
|
|
59
|
+
bareUrl: `bareUrl/thumbnail:${thumbnail.type}`,
|
|
60
|
+
token: `token/thumbnail:${thumbnail.type}`,
|
|
61
|
+
})),
|
|
62
|
+
})),
|
|
63
|
+
uploadBlock: jest.fn().mockImplementation(mockUploadBlock),
|
|
64
|
+
};
|
|
65
|
+
// @ts-expect-error No need to implement all methods for mocking
|
|
66
|
+
cryptoService = {
|
|
67
|
+
encryptThumbnail: jest.fn().mockImplementation(async (_, thumbnail) => ({
|
|
68
|
+
type: thumbnail.type,
|
|
69
|
+
encryptedData: thumbnail.thumbnail,
|
|
70
|
+
originalSize: thumbnail.thumbnail.length,
|
|
71
|
+
encryptedSize: thumbnail.thumbnail + 1000,
|
|
72
|
+
hash: 'thumbnailHash',
|
|
73
|
+
})),
|
|
74
|
+
encryptBlock: jest.fn().mockImplementation(mockEncryptBlock),
|
|
75
|
+
};
|
|
76
|
+
// @ts-expect-error No need to implement all methods for mocking
|
|
77
|
+
uploadManager = {
|
|
78
|
+
commitDraft: jest.fn().mockResolvedValue(undefined),
|
|
79
|
+
};
|
|
80
|
+
// @ts-expect-error No need to implement all methods for mocking
|
|
81
|
+
blockVerifier = {
|
|
82
|
+
verifyBlock: jest.fn().mockResolvedValue(undefined),
|
|
83
|
+
};
|
|
84
|
+
revisionDraft = {
|
|
85
|
+
nodeRevisionUid: 'revisionUid',
|
|
86
|
+
nodeKeys: {
|
|
87
|
+
signatureAddress: { addressId: 'addressId' },
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
metadata = {
|
|
91
|
+
// 3 blocks: 4 + 4 + 2 MB
|
|
92
|
+
expectedSize: 10 * 1024 * 1024,
|
|
93
|
+
};
|
|
94
|
+
controller = new controller_1.UploadController();
|
|
95
|
+
onFinish = jest.fn();
|
|
96
|
+
abortController = new AbortController();
|
|
97
|
+
uploader = new streamUploader_1.StreamUploader(telemetry, apiService, cryptoService, uploadManager, blockVerifier, revisionDraft, metadata, onFinish, abortController.signal);
|
|
98
|
+
});
|
|
99
|
+
describe('start', () => {
|
|
100
|
+
let thumbnails;
|
|
101
|
+
let thumbnailSize;
|
|
102
|
+
let onProgress;
|
|
103
|
+
let stream;
|
|
104
|
+
const verifySuccess = async () => {
|
|
105
|
+
await uploader.start(stream, thumbnails, onProgress);
|
|
106
|
+
const numberOfExpectedBlocks = Math.ceil(metadata.expectedSize / streamUploader_1.FILE_CHUNK_SIZE);
|
|
107
|
+
expect(uploadManager.commitDraft).toHaveBeenCalledTimes(1);
|
|
108
|
+
expect(uploadManager.commitDraft).toHaveBeenCalledWith(revisionDraft, expect.anything(), metadata, {
|
|
109
|
+
size: metadata.expectedSize,
|
|
110
|
+
blockSizes: metadata.expectedSize ? [
|
|
111
|
+
...Array(numberOfExpectedBlocks - 1).fill(streamUploader_1.FILE_CHUNK_SIZE),
|
|
112
|
+
metadata.expectedSize % streamUploader_1.FILE_CHUNK_SIZE
|
|
113
|
+
] : [],
|
|
114
|
+
modificationTime: undefined,
|
|
115
|
+
digests: {
|
|
116
|
+
sha1: expect.anything(),
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
expect(telemetry.uploadFinished).toHaveBeenCalledTimes(1);
|
|
120
|
+
expect(telemetry.uploadFinished).toHaveBeenCalledWith('revisionUid', metadata.expectedSize + thumbnailSize);
|
|
121
|
+
expect(telemetry.uploadFailed).not.toHaveBeenCalled();
|
|
122
|
+
expect(onFinish).toHaveBeenCalledTimes(1);
|
|
123
|
+
expect(onFinish).toHaveBeenCalledWith(false);
|
|
124
|
+
};
|
|
125
|
+
const verifyFailure = async (error, uploadedBytes, expectedSize = metadata.expectedSize) => {
|
|
126
|
+
const promise = uploader.start(stream, thumbnails, onProgress);
|
|
127
|
+
await expect(promise).rejects.toThrow(error);
|
|
128
|
+
expect(telemetry.uploadFinished).not.toHaveBeenCalled();
|
|
129
|
+
expect(telemetry.uploadFailed).toHaveBeenCalledTimes(1);
|
|
130
|
+
expect(telemetry.uploadFailed).toHaveBeenCalledWith('revisionUid', new Error(error), uploadedBytes === undefined ? expect.anything() : uploadedBytes, expectedSize);
|
|
131
|
+
expect(onFinish).toHaveBeenCalledTimes(1);
|
|
132
|
+
expect(onFinish).toHaveBeenCalledWith(true);
|
|
133
|
+
};
|
|
134
|
+
const verifyOnProgress = async (uploadedBytes) => {
|
|
135
|
+
expect(onProgress).toHaveBeenCalledTimes(uploadedBytes.length);
|
|
136
|
+
for (let i = 0; i < uploadedBytes.length; i++) {
|
|
137
|
+
expect(onProgress).toHaveBeenNthCalledWith(i + 1, uploadedBytes[i]);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
beforeEach(() => {
|
|
141
|
+
onProgress = jest.fn();
|
|
142
|
+
thumbnails = [
|
|
143
|
+
{
|
|
144
|
+
type: interface_1.ThumbnailType.Type1,
|
|
145
|
+
thumbnail: new Uint8Array(1024),
|
|
146
|
+
}
|
|
147
|
+
];
|
|
148
|
+
thumbnailSize = thumbnails.reduce((acc, thumbnail) => acc + thumbnail.thumbnail.length, 0);
|
|
149
|
+
stream = new ReadableStream({
|
|
150
|
+
start(controller) {
|
|
151
|
+
const chunkSize = 1024;
|
|
152
|
+
const chunkCount = metadata.expectedSize / chunkSize;
|
|
153
|
+
for (let i = 1; i <= chunkCount; i++) {
|
|
154
|
+
controller.enqueue(new Uint8Array(chunkSize));
|
|
155
|
+
}
|
|
156
|
+
controller.close();
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
it("should upload successfully", async () => {
|
|
161
|
+
await verifySuccess();
|
|
162
|
+
expect(apiService.requestBlockUpload).toHaveBeenCalledTimes(1);
|
|
163
|
+
expect(apiService.uploadBlock).toHaveBeenCalledTimes(4); // 3 blocks + 1 thumbnail
|
|
164
|
+
expect(blockVerifier.verifyBlock).toHaveBeenCalledTimes(3); // 3 blocks
|
|
165
|
+
expect(telemetry.logBlockVerificationError).not.toHaveBeenCalled();
|
|
166
|
+
await verifyOnProgress([thumbnailSize, 4 * 1024 * 1024, 4 * 1024 * 1024, 2 * 1024 * 1024]);
|
|
167
|
+
});
|
|
168
|
+
it("should upload successfully empty file without thumbnail", async () => {
|
|
169
|
+
metadata = {
|
|
170
|
+
expectedSize: 0,
|
|
171
|
+
};
|
|
172
|
+
stream = new ReadableStream({
|
|
173
|
+
start(controller) {
|
|
174
|
+
controller.close();
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
thumbnails = [];
|
|
178
|
+
thumbnailSize = 0;
|
|
179
|
+
uploader = new streamUploader_1.StreamUploader(telemetry, apiService, cryptoService, uploadManager, blockVerifier, revisionDraft, metadata, onFinish);
|
|
180
|
+
await verifySuccess();
|
|
181
|
+
expect(apiService.requestBlockUpload).toHaveBeenCalledTimes(0);
|
|
182
|
+
expect(apiService.uploadBlock).toHaveBeenCalledTimes(0);
|
|
183
|
+
expect(blockVerifier.verifyBlock).toHaveBeenCalledTimes(0);
|
|
184
|
+
await verifyOnProgress([]);
|
|
185
|
+
});
|
|
186
|
+
it("should upload successfully empty file with thumbnail", async () => {
|
|
187
|
+
metadata = {
|
|
188
|
+
expectedSize: 0,
|
|
189
|
+
};
|
|
190
|
+
stream = new ReadableStream({
|
|
191
|
+
start(controller) {
|
|
192
|
+
controller.close();
|
|
193
|
+
},
|
|
194
|
+
});
|
|
195
|
+
uploader = new streamUploader_1.StreamUploader(telemetry, apiService, cryptoService, uploadManager, blockVerifier, revisionDraft, metadata, onFinish);
|
|
196
|
+
await verifySuccess();
|
|
197
|
+
expect(apiService.requestBlockUpload).toHaveBeenCalledTimes(1);
|
|
198
|
+
expect(apiService.uploadBlock).toHaveBeenCalledTimes(1);
|
|
199
|
+
expect(blockVerifier.verifyBlock).toHaveBeenCalledTimes(0);
|
|
200
|
+
await verifyOnProgress([thumbnailSize]);
|
|
201
|
+
});
|
|
202
|
+
it('should handle failure when encrypting thumbnails', async () => {
|
|
203
|
+
cryptoService.encryptThumbnail = jest.fn().mockImplementation(async function () {
|
|
204
|
+
throw new Error('Failed to encrypt thumbnail');
|
|
205
|
+
});
|
|
206
|
+
await verifyFailure('Failed to encrypt thumbnail', 0);
|
|
207
|
+
expect(cryptoService.encryptThumbnail).toHaveBeenCalledTimes(1);
|
|
208
|
+
});
|
|
209
|
+
it('should handle failure when encrypting block', async () => {
|
|
210
|
+
cryptoService.encryptBlock = jest.fn().mockImplementation(async function () {
|
|
211
|
+
throw new Error('Failed to encrypt block');
|
|
212
|
+
});
|
|
213
|
+
// Encrypting thumbnails is before blocks, thus it can be uploaded before failure.
|
|
214
|
+
await verifyFailure('Failed to encrypt block', 1024);
|
|
215
|
+
// 1 block + 1 retry, others are skipped
|
|
216
|
+
expect(cryptoService.encryptBlock).toHaveBeenCalledTimes(2);
|
|
217
|
+
});
|
|
218
|
+
it('should handle one time-off failure when encrypting block', async () => {
|
|
219
|
+
let count = 0;
|
|
220
|
+
cryptoService.encryptBlock = jest.fn().mockImplementation(async function (verifyBlock, keys, block, index) {
|
|
221
|
+
if (count === 0) {
|
|
222
|
+
count++;
|
|
223
|
+
throw new Error('Failed to encrypt block');
|
|
224
|
+
}
|
|
225
|
+
return mockEncryptBlock(verifyBlock, keys, block, index);
|
|
226
|
+
});
|
|
227
|
+
await verifySuccess();
|
|
228
|
+
// 1 block + 1 retry + 2 other blocks without retry
|
|
229
|
+
expect(cryptoService.encryptBlock).toHaveBeenCalledTimes(4);
|
|
230
|
+
await verifyOnProgress([thumbnailSize, 4 * 1024 * 1024, 4 * 1024 * 1024, 2 * 1024 * 1024]);
|
|
231
|
+
});
|
|
232
|
+
it('should handle failure when requesting tokens', async () => {
|
|
233
|
+
apiService.requestBlockUpload = jest.fn().mockImplementation(async function () {
|
|
234
|
+
throw new Error('Failed to request tokens');
|
|
235
|
+
});
|
|
236
|
+
await verifyFailure('Failed to request tokens', 0);
|
|
237
|
+
});
|
|
238
|
+
it('should handle failure when uploading thumbnail', async () => {
|
|
239
|
+
apiService.uploadBlock = jest.fn().mockImplementation(async function (bareUrl, token, block, onProgress) {
|
|
240
|
+
if (token === 'token/thumbnail:1') {
|
|
241
|
+
throw new Error('Failed to upload thumbnail');
|
|
242
|
+
}
|
|
243
|
+
return mockUploadBlock(bareUrl, token, block, onProgress);
|
|
244
|
+
});
|
|
245
|
+
// 10 MB uploaded as blocks still uploaded
|
|
246
|
+
await verifyFailure('Failed to upload thumbnail', 10 * 1024 * 1024);
|
|
247
|
+
});
|
|
248
|
+
it('should handle one time-off failure when uploading thubmnail', async () => {
|
|
249
|
+
let count = 0;
|
|
250
|
+
apiService.uploadBlock = jest.fn().mockImplementation(async function (bareUrl, token, block, onProgress) {
|
|
251
|
+
if (token === 'token/thumbnail:1' && count === 0) {
|
|
252
|
+
count++;
|
|
253
|
+
throw new Error('Failed to upload thumbnail');
|
|
254
|
+
}
|
|
255
|
+
return mockUploadBlock(bareUrl, token, block, onProgress);
|
|
256
|
+
});
|
|
257
|
+
await verifySuccess();
|
|
258
|
+
expect(apiService.requestBlockUpload).toHaveBeenCalledTimes(1);
|
|
259
|
+
// 3 blocks + 1 retry + 1 thumbnail
|
|
260
|
+
expect(apiService.uploadBlock).toHaveBeenCalledTimes(5);
|
|
261
|
+
await verifyOnProgress([4 * 1024 * 1024, 4 * 1024 * 1024, 2 * 1024 * 1024, 1024]);
|
|
262
|
+
});
|
|
263
|
+
it('should handle failure when uploading block', async () => {
|
|
264
|
+
apiService.uploadBlock = jest.fn().mockImplementation(async function (bareUrl, token, block, onProgress) {
|
|
265
|
+
if (token === 'token/block:3') {
|
|
266
|
+
throw new Error('Failed to upload block');
|
|
267
|
+
}
|
|
268
|
+
return mockUploadBlock(bareUrl, token, block, onProgress);
|
|
269
|
+
});
|
|
270
|
+
// ~8 MB uploaded as 2 first blocks + 1 thumbnail still uploaded
|
|
271
|
+
await verifyFailure('Failed to upload block', 8 * 1024 * 1024 + 1024);
|
|
272
|
+
});
|
|
273
|
+
it('should handle one time-off failure when uploading block', async () => {
|
|
274
|
+
let count = 0;
|
|
275
|
+
apiService.uploadBlock = jest.fn().mockImplementation(async function (bareUrl, token, block, onProgress) {
|
|
276
|
+
if (token === 'token/block:2' && count === 0) {
|
|
277
|
+
count++;
|
|
278
|
+
throw new Error('Failed to upload block');
|
|
279
|
+
}
|
|
280
|
+
return mockUploadBlock(bareUrl, token, block, onProgress);
|
|
281
|
+
});
|
|
282
|
+
await verifySuccess();
|
|
283
|
+
expect(apiService.requestBlockUpload).toHaveBeenCalledTimes(1);
|
|
284
|
+
// 3 blocks + 1 retry + 1 thumbnail
|
|
285
|
+
expect(apiService.uploadBlock).toHaveBeenCalledTimes(5);
|
|
286
|
+
await verifyOnProgress([1024, 4 * 1024 * 1024, 2 * 1024 * 1024, 4 * 1024 * 1024]);
|
|
287
|
+
});
|
|
288
|
+
it('should handle expired token when uploading block', async () => {
|
|
289
|
+
let count = 0;
|
|
290
|
+
apiService.uploadBlock = jest.fn().mockImplementation(async function (bareUrl, token, block, onProgress) {
|
|
291
|
+
if (token === 'token/block:2' && count === 0) {
|
|
292
|
+
count++;
|
|
293
|
+
throw new apiService_1.APIHTTPError('Expired token', 404 /* HTTPErrorCode.NOT_FOUND */);
|
|
294
|
+
}
|
|
295
|
+
return mockUploadBlock(bareUrl, token, block, onProgress);
|
|
296
|
+
});
|
|
297
|
+
await verifySuccess();
|
|
298
|
+
// 1 for first try + 1 for retry
|
|
299
|
+
expect(apiService.requestBlockUpload).toHaveBeenCalledTimes(2);
|
|
300
|
+
expect(apiService.requestBlockUpload).toHaveBeenCalledWith(revisionDraft.nodeRevisionUid, revisionDraft.nodeKeys.signatureAddress.addressId, {
|
|
301
|
+
contentBlocks: [
|
|
302
|
+
{
|
|
303
|
+
index: 2,
|
|
304
|
+
encryptedSize: 4 * 1024 * 1024 + 10000,
|
|
305
|
+
hash: 'blockHash',
|
|
306
|
+
armoredSignature: 'signature',
|
|
307
|
+
verificationToken: 'verificationToken',
|
|
308
|
+
}
|
|
309
|
+
],
|
|
310
|
+
});
|
|
311
|
+
// 3 blocks + 1 retry + 1 thumbnail
|
|
312
|
+
expect(apiService.uploadBlock).toHaveBeenCalledTimes(5);
|
|
313
|
+
await verifyOnProgress([1024, 4 * 1024 * 1024, 2 * 1024 * 1024, 4 * 1024 * 1024]);
|
|
314
|
+
});
|
|
315
|
+
it('should handle abortion', async () => {
|
|
316
|
+
const error = new Error('Aborted');
|
|
317
|
+
const promise = uploader.start(stream, thumbnails, onProgress);
|
|
318
|
+
abortController.abort(error);
|
|
319
|
+
await promise;
|
|
320
|
+
expect(apiService.uploadBlock.mock.calls[0][4]?.aborted).toBe(true);
|
|
321
|
+
});
|
|
322
|
+
describe('verifyIntegrity', () => {
|
|
323
|
+
it('should report block verification error', async () => {
|
|
324
|
+
blockVerifier.verifyBlock = jest.fn().mockRejectedValue(new errors_1.IntegrityError('Block verification error'));
|
|
325
|
+
await verifyFailure('Block verification error', 1024);
|
|
326
|
+
expect(telemetry.logBlockVerificationError).toHaveBeenCalledWith(false);
|
|
327
|
+
});
|
|
328
|
+
it('should report block verification error when retry helped', async () => {
|
|
329
|
+
blockVerifier.verifyBlock = jest.fn().mockRejectedValueOnce(new errors_1.IntegrityError('Block verification error')).mockResolvedValue({
|
|
330
|
+
verificationToken: new Uint8Array(),
|
|
331
|
+
});
|
|
332
|
+
await verifySuccess();
|
|
333
|
+
expect(telemetry.logBlockVerificationError).toHaveBeenCalledWith(true);
|
|
334
|
+
});
|
|
335
|
+
it('should throw an error if block count does not match', async () => {
|
|
336
|
+
uploader = new streamUploader_1.StreamUploader(telemetry, apiService, cryptoService, uploadManager, blockVerifier, revisionDraft, {
|
|
337
|
+
// Fake expected size to break verification
|
|
338
|
+
expectedSize: 1 * 1024 * 1024 + 1024,
|
|
339
|
+
mediaType: '',
|
|
340
|
+
}, onFinish);
|
|
341
|
+
await verifyFailure('Some file parts failed to upload', 10 * 1024 * 1024 + 1024, 1 * 1024 * 1024 + 1024);
|
|
342
|
+
});
|
|
343
|
+
it('should throw an error if file size does not match', async () => {
|
|
344
|
+
cryptoService.encryptBlock = jest.fn().mockImplementation(async (_, __, block, index) => ({
|
|
345
|
+
index,
|
|
346
|
+
encryptedData: block,
|
|
347
|
+
armoredSignature: 'signature',
|
|
348
|
+
verificationToken: 'verificationToken',
|
|
349
|
+
originalSize: 0, // Fake original size to break verification
|
|
350
|
+
encryptedSize: block.length + 10000,
|
|
351
|
+
hash: 'blockHash',
|
|
352
|
+
}));
|
|
353
|
+
await verifyFailure('Some file bytes failed to upload', 10 * 1024 * 1024 + 1024);
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
});
|
|
358
|
+
//# sourceMappingURL=streamUploader.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streamUploader.test.js","sourceRoot":"","sources":["../../../src/internal/upload/streamUploader.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { ProtonDriveClientContructorParameters, NodeOrUid, MaybeNode, MaybeMissingNode, NodeResult, Revision, ShareNodeSettings, UnshareNodeSettings, ProtonInvitationOrUid, NonProtonInvitationOrUid, ProtonInvitationWithNode, MaybeBookmark, BookmarkOrUid, ShareResult, Device, DeviceType, DeviceOrUid, UploadMetadata, FileDownloader,
|
|
1
|
+
import { ProtonDriveClientContructorParameters, NodeOrUid, MaybeNode, MaybeMissingNode, NodeResult, Revision, ShareNodeSettings, UnshareNodeSettings, ProtonInvitationOrUid, NonProtonInvitationOrUid, ProtonInvitationWithNode, MaybeBookmark, BookmarkOrUid, ShareResult, Device, DeviceType, DeviceOrUid, UploadMetadata, FileDownloader, FileUploader, FileRevisionUploader, ThumbnailType, ThumbnailResult, SDKEvent } from './interface';
|
|
2
2
|
import { SessionKey } from './crypto';
|
|
3
|
+
import { DriveListener } from './internal/events';
|
|
4
|
+
import { EventSubscription } from './internal/events/interface';
|
|
3
5
|
/**
|
|
4
6
|
* ProtonDriveClient is the main interface for the ProtonDrive SDK.
|
|
5
7
|
*
|
|
@@ -33,7 +35,7 @@ export declare class ProtonDriveClient {
|
|
|
33
35
|
*/
|
|
34
36
|
getDocsKey: (nodeUid: NodeOrUid) => Promise<SessionKey>;
|
|
35
37
|
};
|
|
36
|
-
constructor({ httpClient, entitiesCache, cryptoCache, account, openPGPCryptoModule, srpModule, config, telemetry, }: ProtonDriveClientContructorParameters);
|
|
38
|
+
constructor({ httpClient, entitiesCache, cryptoCache, account, openPGPCryptoModule, srpModule, config, telemetry, latestEventIdProvider, }: ProtonDriveClientContructorParameters);
|
|
37
39
|
/**
|
|
38
40
|
* Subscribes to the general SDK events.
|
|
39
41
|
*
|
|
@@ -46,161 +48,23 @@ export declare class ProtonDriveClient {
|
|
|
46
48
|
*/
|
|
47
49
|
onMessage(eventName: SDKEvent, callback: () => void): () => void;
|
|
48
50
|
/**
|
|
49
|
-
* Subscribes to the remote data updates
|
|
51
|
+
* Subscribes to the remote data updates for all files and folders in a
|
|
52
|
+
* tree.
|
|
50
53
|
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* keeps the local cache in sync with the remote data.
|
|
54
|
+
* In order to keep local data up to date, the client must call this method
|
|
55
|
+
* to receive events on update and to keep the SDK cache in sync.
|
|
54
56
|
*
|
|
55
|
-
*
|
|
57
|
+
* The `treeEventScopeId` can be obtained from node properties.
|
|
56
58
|
*
|
|
57
|
-
*
|
|
58
|
-
* for own data at minimum. Updates to nodes from other users are polled
|
|
59
|
-
* with lower frequency depending on the number of subscriptions, and only
|
|
60
|
-
* after accessing them for the first time via `iterateSharedNodesWithMe`.
|
|
59
|
+
* Only one instance of the SDK should subscribe to updates.
|
|
61
60
|
*/
|
|
62
|
-
|
|
61
|
+
subscribeToTreeEvents(treeEventScopeId: string, callback: DriveListener): Promise<EventSubscription>;
|
|
63
62
|
/**
|
|
64
|
-
*
|
|
63
|
+
* Subscribes to sharing updates.
|
|
65
64
|
*
|
|
66
|
-
*
|
|
67
|
-
* to ensure that updates are reflected once a device is in the cache.
|
|
68
|
-
* Subscribing before listing is also required to ensure that devices
|
|
69
|
-
* that are created during the listing will be recognized.
|
|
70
|
-
*
|
|
71
|
-
* ```typescript
|
|
72
|
-
* const unsubscribe = sdk.subscribeToDevices((event) => {
|
|
73
|
-
* if (event.type === 'update') {
|
|
74
|
-
* // Update the device in the UI
|
|
75
|
-
* } else if (event.type === 'remove') {
|
|
76
|
-
* // Remove the device from the UI
|
|
77
|
-
* }
|
|
78
|
-
* });
|
|
79
|
-
*
|
|
80
|
-
* const devices = await Array.fromAsync(sdk.iterateDevices());
|
|
81
|
-
* // Render the devices in the UI
|
|
82
|
-
*
|
|
83
|
-
* // Unsubscribe from the updates when the component is unmounted
|
|
84
|
-
* unsubscribe();
|
|
85
|
-
* ```
|
|
86
|
-
*
|
|
87
|
-
* @param callback - Callback to be called when the event is emitted.
|
|
88
|
-
* @returns Callback to unsubscribe from the event.
|
|
89
|
-
*/
|
|
90
|
-
subscribeToDevices(callback: DeviceEventCallback): () => void;
|
|
91
|
-
/**
|
|
92
|
-
* Subscribe to updates of the children of the given parent node.
|
|
93
|
-
*
|
|
94
|
-
* Clients should subscribe to this before beginning to list children
|
|
95
|
-
* to ensure that updates are reflected once a node is in the cache.
|
|
96
|
-
* Subscribing before listing is also required to ensure that nodes
|
|
97
|
-
* that are created during the listing will be recognized.
|
|
98
|
-
*
|
|
99
|
-
* ```typescript
|
|
100
|
-
* const unsubscribe = sdk.subscribeToChildren(parentNodeUid, (event) => {
|
|
101
|
-
* if (event.type === 'update') {
|
|
102
|
-
* // Update the node in the UI
|
|
103
|
-
* } else if (event.type === 'remove') {
|
|
104
|
-
* // Remove the node from the UI
|
|
105
|
-
* }
|
|
106
|
-
* });
|
|
107
|
-
*
|
|
108
|
-
* const nodes = await Array.fromAsync(sdk.iterateChildren(parentNodeUid));
|
|
109
|
-
* // Render the nodes in the UI
|
|
110
|
-
*
|
|
111
|
-
* // Unsubscribe from the updates when the component is unmounted
|
|
112
|
-
* unsubscribe();
|
|
113
|
-
* ```
|
|
114
|
-
*
|
|
115
|
-
* @param parentNodeUid - Node entity or its UID string.
|
|
116
|
-
* @param callback - Callback to be called when the event is emitted.
|
|
117
|
-
* @returns Callback to unsubscribe from the event.
|
|
65
|
+
* Only one instance of the SDK should subscribe to updates.
|
|
118
66
|
*/
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Subscribe to updates of the trashed nodes.
|
|
122
|
-
*
|
|
123
|
-
* Clients should subscribe to this before beginning to list trashed
|
|
124
|
-
* nodes to ensure that updates are reflected once a node is in the cache.
|
|
125
|
-
* Subscribing before listing is also required to ensure that nodes
|
|
126
|
-
* that are trashed during the listing will be recognized.
|
|
127
|
-
*
|
|
128
|
-
* ```typescript
|
|
129
|
-
* const unsubscribe = sdk.subscribeToTrashedNodes((event) => {
|
|
130
|
-
* if (event.type === 'update') {
|
|
131
|
-
* // Update the node in the UI
|
|
132
|
-
* } else if (event.type === 'remove') {
|
|
133
|
-
* // Remove the node from the UI
|
|
134
|
-
* }
|
|
135
|
-
* });
|
|
136
|
-
*
|
|
137
|
-
* const nodes = await Array.fromAsync(sdk.iterateTrashedNodes());
|
|
138
|
-
* // Render the nodes in the UI
|
|
139
|
-
*
|
|
140
|
-
* // Unsubscribe from the updates when the component is unmounted
|
|
141
|
-
* unsubscribe();
|
|
142
|
-
* ```
|
|
143
|
-
*
|
|
144
|
-
* @param callback - Callback to be called when the event is emitted.
|
|
145
|
-
* @returns Callback to unsubscribe from the event.
|
|
146
|
-
*/
|
|
147
|
-
subscribeToTrashedNodes(callback: NodeEventCallback): () => void;
|
|
148
|
-
/**
|
|
149
|
-
* Subscribe to updates of the nodes shared by the user.
|
|
150
|
-
*
|
|
151
|
-
* Clients should subscribe to this before beginning to list shared
|
|
152
|
-
* nodes to ensure that updates are reflected once a node is in the cache.
|
|
153
|
-
* Subscribing before listing is also required to ensure that nodes
|
|
154
|
-
* that are shared during the listing will be recognized.
|
|
155
|
-
*
|
|
156
|
-
* ```typescript
|
|
157
|
-
* const unsubscribe = sdk.subscribeToSharedNodesByMe((event) => {
|
|
158
|
-
* if (event.type === 'update') {
|
|
159
|
-
* // Update the node in the UI
|
|
160
|
-
* } else if (event.type === 'remove') {
|
|
161
|
-
* // Remove the node from the UI
|
|
162
|
-
* }
|
|
163
|
-
* });
|
|
164
|
-
*
|
|
165
|
-
* const nodes = await Array.fromAsync(sdk.iterateSharedNodes());
|
|
166
|
-
* // Render the nodes in the UI
|
|
167
|
-
*
|
|
168
|
-
* // Unsubscribe from the updates when the component is unmounted
|
|
169
|
-
* unsubscribe();
|
|
170
|
-
* ```
|
|
171
|
-
*
|
|
172
|
-
* @param callback - Callback to be called when the event is emitted.
|
|
173
|
-
* @returns Callback to unsubscribe from the event.
|
|
174
|
-
*/
|
|
175
|
-
subscribeToSharedNodesByMe(callback: NodeEventCallback): () => void;
|
|
176
|
-
/**
|
|
177
|
-
* Subscribe to updates of the nodes shared with the user.
|
|
178
|
-
*
|
|
179
|
-
* Clients should subscribe to this before beginning to list shared
|
|
180
|
-
* nodes to ensure that updates are reflected once a node is in the cache.
|
|
181
|
-
* Subscribing before listing is also required to ensure that nodes
|
|
182
|
-
* that are shared during the listing will be recognized.
|
|
183
|
-
*
|
|
184
|
-
* ```typescript
|
|
185
|
-
* const unsubscribe = sdk.subscribeToSharedNodesWithMe((event) => {
|
|
186
|
-
* if (event.type === 'update') {
|
|
187
|
-
* // Update the node in the UI
|
|
188
|
-
* } else if (event.type === 'remove') {
|
|
189
|
-
* // Remove the node from the UI
|
|
190
|
-
* }
|
|
191
|
-
* });
|
|
192
|
-
*
|
|
193
|
-
* const nodes = await Array.fromAsync(sdk.iterateSharedNodesWithMe());
|
|
194
|
-
* // Render the nodes in the UI
|
|
195
|
-
*
|
|
196
|
-
* // Unsubscribe from the updates when the component is unmounted
|
|
197
|
-
* unsubscribe();
|
|
198
|
-
* ```
|
|
199
|
-
*
|
|
200
|
-
* @param callback - Callback to be called when the event is emitted.
|
|
201
|
-
* @returns Callback to unsubscribe from the event.
|
|
202
|
-
*/
|
|
203
|
-
subscribeToSharedNodesWithMe(callback: NodeEventCallback): () => void;
|
|
67
|
+
subscribeToDriveEvents(callback: DriveListener): Promise<EventSubscription>;
|
|
204
68
|
/**
|
|
205
69
|
* Provides the node UID for the given raw share and node IDs.
|
|
206
70
|
*
|
|
@@ -224,8 +88,6 @@ export declare class ProtonDriveClient {
|
|
|
224
88
|
*
|
|
225
89
|
* The output is not sorted and the order of the children is not guaranteed.
|
|
226
90
|
*
|
|
227
|
-
* You can listen to updates via `subscribeToChildren`.
|
|
228
|
-
*
|
|
229
91
|
* @param parentNodeUid - Node entity or its UID string.
|
|
230
92
|
* @param signal - Signal to abort the operation.
|
|
231
93
|
* @returns An async generator of the children of the given parent node.
|
|
@@ -239,8 +101,6 @@ export declare class ProtonDriveClient {
|
|
|
239
101
|
*
|
|
240
102
|
* The output is not sorted and the order of the trashed nodes is not guaranteed.
|
|
241
103
|
*
|
|
242
|
-
* You can listen to updates via `subscribeToTrashedNodes`.
|
|
243
|
-
*
|
|
244
104
|
* @param signal - Signal to abort the operation.
|
|
245
105
|
* @returns An async generator of the trashed nodes.
|
|
246
106
|
*/
|
|
@@ -384,8 +244,6 @@ export declare class ProtonDriveClient {
|
|
|
384
244
|
*
|
|
385
245
|
* The output is not sorted and the order of the shared nodes is not guaranteed.
|
|
386
246
|
*
|
|
387
|
-
* You can listen to updates via `subscribeToSharedNodesByMe`.
|
|
388
|
-
*
|
|
389
247
|
* @param signal - Signal to abort the operation.
|
|
390
248
|
* @returns An async generator of the shared nodes.
|
|
391
249
|
*/
|
|
@@ -395,11 +253,9 @@ export declare class ProtonDriveClient {
|
|
|
395
253
|
*
|
|
396
254
|
* The output is not sorted and the order of the shared nodes is not guaranteed.
|
|
397
255
|
*
|
|
398
|
-
*
|
|
399
|
-
*
|
|
400
|
-
*
|
|
401
|
-
*
|
|
402
|
-
* You can listen to updates via `subscribeToSharedNodesWithMe`.
|
|
256
|
+
* Clients can subscribe to drive events in order to receive a
|
|
257
|
+
* `SharedWithMeUpdated` event when there are changes to the user's
|
|
258
|
+
* access to shared nodes.
|
|
403
259
|
*
|
|
404
260
|
* @param signal - Signal to abort the operation.
|
|
405
261
|
* @returns An async generator of the shared nodes.
|
|
@@ -560,7 +416,7 @@ export declare class ProtonDriveClient {
|
|
|
560
416
|
*
|
|
561
417
|
* ```typescript
|
|
562
418
|
* const uploader = await client.getFileUploader(parentFolderUid, name, metadata, signal);
|
|
563
|
-
* const uploadController = uploader.writeStream(stream, thumbnails, (uploadedBytes) => { ... });
|
|
419
|
+
* const uploadController = await uploader.writeStream(stream, thumbnails, (uploadedBytes) => { ... });
|
|
564
420
|
*
|
|
565
421
|
* signalController.abort(); // to cancel
|
|
566
422
|
* uploadController.pause(); // to pause
|
|
@@ -568,17 +424,18 @@ export declare class ProtonDriveClient {
|
|
|
568
424
|
* const nodeUid = await uploadController.completion(); // to await completion
|
|
569
425
|
* ```
|
|
570
426
|
*/
|
|
571
|
-
getFileUploader(parentFolderUid: NodeOrUid, name: string, metadata: UploadMetadata, signal?: AbortSignal): Promise<
|
|
427
|
+
getFileUploader(parentFolderUid: NodeOrUid, name: string, metadata: UploadMetadata, signal?: AbortSignal): Promise<FileUploader>;
|
|
572
428
|
/**
|
|
573
429
|
* Same as `getFileUploader`, but for a uploading new revision of the file.
|
|
574
430
|
*/
|
|
575
|
-
getFileRevisionUploader(nodeUid: NodeOrUid, metadata: UploadMetadata, signal?: AbortSignal): Promise<
|
|
431
|
+
getFileRevisionUploader(nodeUid: NodeOrUid, metadata: UploadMetadata, signal?: AbortSignal): Promise<FileRevisionUploader>;
|
|
576
432
|
/**
|
|
577
433
|
* Iterates the devices of the user.
|
|
578
434
|
*
|
|
579
435
|
* The output is not sorted and the order of the devices is not guaranteed.
|
|
580
436
|
*
|
|
581
|
-
*
|
|
437
|
+
* New devices can be registered by listening to events in the
|
|
438
|
+
* event scope of "My Files" and filtering on nodes with null `ParentLinkId`.
|
|
582
439
|
*
|
|
583
440
|
* @returns An async generator of devices.
|
|
584
441
|
*/
|