@protontech/drive-sdk 0.1.0 → 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/cache/memoryCache.js +0 -1
- package/dist/cache/memoryCache.js.map +1 -1
- package/dist/cache/memoryCache.test.js +2 -4
- package/dist/cache/memoryCache.test.js.map +1 -1
- package/dist/cache/nullCache.js +0 -1
- package/dist/cache/nullCache.js.map +1 -1
- package/dist/crypto/driveCrypto.d.ts +2 -5
- package/dist/crypto/driveCrypto.js +7 -12
- package/dist/crypto/driveCrypto.js.map +1 -1
- package/dist/crypto/driveCrypto.test.js +14 -14
- package/dist/crypto/openPGPCrypto.js +3 -3
- package/dist/crypto/openPGPCrypto.js.map +1 -1
- package/dist/diagnostic/eventsGenerator.js +1 -1
- package/dist/diagnostic/eventsGenerator.js.map +1 -1
- package/dist/diagnostic/httpClient.d.ts +1 -1
- package/dist/diagnostic/httpClient.js.map +1 -1
- package/dist/diagnostic/index.d.ts +3 -3
- package/dist/diagnostic/index.js.map +1 -1
- package/dist/diagnostic/integrityVerificationStream.js +1 -1
- package/dist/diagnostic/integrityVerificationStream.js.map +1 -1
- package/dist/diagnostic/interface.d.ts +2 -2
- package/dist/diagnostic/sdkDiagnostic.d.ts +3 -3
- package/dist/diagnostic/sdkDiagnostic.js +8 -2
- package/dist/diagnostic/sdkDiagnostic.js.map +1 -1
- package/dist/diagnostic/sdkDiagnosticFull.d.ts +4 -4
- package/dist/diagnostic/sdkDiagnosticFull.js.map +1 -1
- package/dist/diagnostic/telemetry.js.map +1 -1
- package/dist/diagnostic/zipGenerators.js +2 -2
- package/dist/diagnostic/zipGenerators.js.map +1 -1
- package/dist/diagnostic/zipGenerators.test.js +1 -1
- package/dist/diagnostic/zipGenerators.test.js.map +1 -1
- package/dist/interface/events.d.ts +2 -4
- package/dist/interface/events.js.map +1 -1
- package/dist/interface/index.d.ts +5 -5
- package/dist/interface/index.js +0 -1
- package/dist/interface/index.js.map +1 -1
- package/dist/interface/result.js.map +1 -1
- package/dist/interface/sharing.d.ts +1 -0
- package/dist/interface/sharing.js.map +1 -1
- package/dist/interface/telemetry.js +0 -8
- package/dist/interface/telemetry.js.map +1 -1
- package/dist/interface/thumbnail.js.map +1 -1
- package/dist/interface/upload.d.ts +1 -1
- package/dist/internal/apiService/apiService.d.ts +1 -1
- package/dist/internal/apiService/apiService.js +7 -11
- package/dist/internal/apiService/apiService.js.map +1 -1
- package/dist/internal/apiService/apiService.test.js +55 -48
- package/dist/internal/apiService/apiService.test.js.map +1 -1
- package/dist/internal/apiService/coreTypes.d.ts +2356 -2356
- package/dist/internal/apiService/driveTypes.d.ts +1680 -1680
- package/dist/internal/apiService/errors.js +14 -8
- package/dist/internal/apiService/errors.js.map +1 -1
- package/dist/internal/apiService/errors.test.js +17 -12
- package/dist/internal/apiService/errors.test.js.map +1 -1
- package/dist/internal/apiService/transformers.d.ts +1 -1
- package/dist/internal/apiService/transformers.js +1 -1
- package/dist/internal/asyncIteratorMap.test.js +2 -2
- package/dist/internal/asyncIteratorMap.test.js.map +1 -1
- package/dist/internal/asyncIteratorRace.d.ts +13 -0
- package/dist/internal/asyncIteratorRace.js +59 -0
- package/dist/internal/asyncIteratorRace.js.map +1 -0
- package/dist/internal/asyncIteratorRace.test.d.ts +1 -0
- package/dist/internal/asyncIteratorRace.test.js +119 -0
- package/dist/internal/asyncIteratorRace.test.js.map +1 -0
- package/dist/internal/batch.d.ts +1 -0
- package/dist/internal/batch.js +12 -0
- package/dist/internal/batch.js.map +1 -0
- package/dist/internal/batch.test.d.ts +1 -0
- package/dist/internal/batch.test.js +41 -0
- package/dist/internal/batch.test.js.map +1 -0
- package/dist/internal/batchLoading.js.map +1 -1
- package/dist/internal/batchLoading.test.js +13 -13
- package/dist/internal/batchLoading.test.js.map +1 -1
- package/dist/internal/devices/apiService.d.ts +3 -3
- package/dist/internal/devices/apiService.js +2 -2
- package/dist/internal/devices/apiService.js.map +1 -1
- package/dist/internal/devices/cryptoService.js +1 -2
- package/dist/internal/devices/cryptoService.js.map +1 -1
- package/dist/internal/devices/index.d.ts +5 -5
- package/dist/internal/devices/index.js.map +1 -1
- package/dist/internal/devices/interface.d.ts +3 -3
- package/dist/internal/devices/manager.js +2 -2
- package/dist/internal/devices/manager.js.map +1 -1
- package/dist/internal/devices/manager.test.js +38 -7
- package/dist/internal/devices/manager.test.js.map +1 -1
- package/dist/internal/download/apiService.d.ts +4 -4
- package/dist/internal/download/apiService.js +0 -1
- package/dist/internal/download/apiService.js.map +1 -1
- package/dist/internal/download/cryptoService.d.ts +4 -4
- package/dist/internal/download/cryptoService.js +6 -5
- package/dist/internal/download/cryptoService.js.map +1 -1
- package/dist/internal/download/fileDownloader.d.ts +4 -4
- package/dist/internal/download/fileDownloader.js +3 -2
- package/dist/internal/download/fileDownloader.js.map +1 -1
- package/dist/internal/download/fileDownloader.test.js +1 -1
- package/dist/internal/download/fileDownloader.test.js.map +1 -1
- package/dist/internal/download/index.d.ts +5 -5
- package/dist/internal/download/index.js +5 -5
- package/dist/internal/download/index.js.map +1 -1
- package/dist/internal/download/interface.d.ts +3 -4
- package/dist/internal/download/telemetry.d.ts +3 -3
- package/dist/internal/download/telemetry.js +4 -2
- package/dist/internal/download/telemetry.js.map +1 -1
- package/dist/internal/download/telemetry.test.js +8 -8
- package/dist/internal/download/telemetry.test.js.map +1 -1
- package/dist/internal/download/thumbnailDownloader.d.ts +4 -4
- package/dist/internal/download/thumbnailDownloader.js +6 -6
- package/dist/internal/download/thumbnailDownloader.js.map +1 -1
- package/dist/internal/download/thumbnailDownloader.test.js.map +1 -1
- package/dist/internal/errors.d.ts +1 -1
- package/dist/internal/errors.js +1 -3
- package/dist/internal/errors.js.map +1 -1
- package/dist/internal/events/apiService.d.ts +2 -2
- package/dist/internal/events/apiService.js +9 -5
- package/dist/internal/events/apiService.js.map +1 -1
- package/dist/internal/events/coreEventManager.d.ts +3 -3
- package/dist/internal/events/coreEventManager.js.map +1 -1
- package/dist/internal/events/coreEventManager.test.js +14 -14
- package/dist/internal/events/eventManager.d.ts +2 -1
- package/dist/internal/events/eventManager.js +9 -1
- package/dist/internal/events/eventManager.js.map +1 -1
- package/dist/internal/events/eventManager.test.js +84 -60
- package/dist/internal/events/eventManager.test.js.map +1 -1
- package/dist/internal/events/index.d.ts +10 -9
- package/dist/internal/events/index.js +38 -32
- package/dist/internal/events/index.js.map +1 -1
- package/dist/internal/events/interface.d.ts +1 -1
- package/dist/internal/events/interface.js +0 -1
- package/dist/internal/events/interface.js.map +1 -1
- package/dist/internal/events/volumeEventManager.d.ts +3 -3
- package/dist/internal/events/volumeEventManager.js.map +1 -1
- package/dist/internal/events/volumeEventManager.test.js +55 -55
- package/dist/internal/events/volumeEventManager.test.js.map +1 -1
- package/dist/internal/nodes/apiService.d.ts +4 -3
- package/dist/internal/nodes/apiService.js +36 -15
- package/dist/internal/nodes/apiService.js.map +1 -1
- package/dist/internal/nodes/apiService.test.js +60 -41
- package/dist/internal/nodes/apiService.test.js.map +1 -1
- package/dist/internal/nodes/cache.d.ts +5 -5
- package/dist/internal/nodes/cache.js +14 -7
- package/dist/internal/nodes/cache.js.map +1 -1
- package/dist/internal/nodes/cache.test.js +31 -9
- package/dist/internal/nodes/cache.test.js.map +1 -1
- package/dist/internal/nodes/cryptoCache.d.ts +2 -2
- package/dist/internal/nodes/cryptoCache.js.map +1 -1
- package/dist/internal/nodes/cryptoCache.test.js +24 -4
- package/dist/internal/nodes/cryptoCache.test.js.map +1 -1
- package/dist/internal/nodes/cryptoService.d.ts +3 -3
- package/dist/internal/nodes/cryptoService.js +11 -17
- package/dist/internal/nodes/cryptoService.js.map +1 -1
- package/dist/internal/nodes/cryptoService.test.js +320 -241
- package/dist/internal/nodes/cryptoService.test.js.map +1 -1
- package/dist/internal/nodes/events.d.ts +3 -3
- package/dist/internal/nodes/events.js +7 -7
- package/dist/internal/nodes/events.js.map +1 -1
- package/dist/internal/nodes/events.test.js +27 -21
- package/dist/internal/nodes/events.test.js.map +1 -1
- package/dist/internal/nodes/extendedAttributes.d.ts +1 -1
- package/dist/internal/nodes/extendedAttributes.js +3 -1
- package/dist/internal/nodes/extendedAttributes.js.map +1 -1
- package/dist/internal/nodes/extendedAttributes.test.js +7 -10
- package/dist/internal/nodes/extendedAttributes.test.js.map +1 -1
- package/dist/internal/nodes/index.d.ts +10 -10
- package/dist/internal/nodes/index.js.map +1 -1
- package/dist/internal/nodes/index.test.d.ts +1 -0
- package/dist/internal/nodes/index.test.js +106 -0
- package/dist/internal/nodes/index.test.js.map +1 -0
- package/dist/internal/nodes/interface.d.ts +2 -2
- package/dist/internal/nodes/nodesAccess.d.ts +7 -7
- package/dist/internal/nodes/nodesAccess.js +28 -16
- package/dist/internal/nodes/nodesAccess.js.map +1 -1
- package/dist/internal/nodes/nodesAccess.test.js +39 -13
- package/dist/internal/nodes/nodesAccess.test.js.map +1 -1
- package/dist/internal/nodes/nodesManagement.d.ts +6 -6
- package/dist/internal/nodes/nodesManagement.js +9 -7
- package/dist/internal/nodes/nodesManagement.js.map +1 -1
- package/dist/internal/nodes/nodesManagement.test.js +9 -9
- package/dist/internal/nodes/nodesManagement.test.js.map +1 -1
- package/dist/internal/nodes/nodesRevisions.d.ts +4 -4
- package/dist/internal/nodes/nodesRevisions.js.map +1 -1
- package/dist/internal/photos/albums.d.ts +3 -3
- package/dist/internal/photos/albums.js.map +1 -1
- package/dist/internal/photos/apiService.d.ts +1 -1
- package/dist/internal/photos/apiService.js +3 -6
- package/dist/internal/photos/apiService.js.map +1 -1
- package/dist/internal/photos/cache.d.ts +1 -1
- package/dist/internal/photos/index.d.ts +5 -5
- package/dist/internal/photos/index.js.map +1 -1
- package/dist/internal/photos/interface.d.ts +2 -2
- package/dist/internal/photos/photosTimeline.d.ts +3 -3
- package/dist/internal/photos/photosTimeline.js +1 -2
- package/dist/internal/photos/photosTimeline.js.map +1 -1
- package/dist/internal/sdkEvents.d.ts +1 -1
- package/dist/internal/sdkEvents.js +2 -7
- package/dist/internal/sdkEvents.js.map +1 -1
- package/dist/internal/sdkEvents.test.js +8 -8
- package/dist/internal/shares/apiService.d.ts +2 -2
- package/dist/internal/shares/apiService.js +5 -3
- package/dist/internal/shares/apiService.js.map +1 -1
- package/dist/internal/shares/cache.d.ts +2 -2
- package/dist/internal/shares/cache.js +12 -6
- package/dist/internal/shares/cache.js.map +1 -1
- package/dist/internal/shares/cache.test.js.map +1 -1
- package/dist/internal/shares/cryptoCache.d.ts +2 -2
- package/dist/internal/shares/cryptoCache.test.js +8 -2
- package/dist/internal/shares/cryptoCache.test.js.map +1 -1
- package/dist/internal/shares/cryptoService.d.ts +3 -3
- package/dist/internal/shares/cryptoService.js.map +1 -1
- package/dist/internal/shares/cryptoService.test.js +42 -42
- package/dist/internal/shares/cryptoService.test.js.map +1 -1
- package/dist/internal/shares/index.d.ts +4 -4
- package/dist/internal/shares/index.js.map +1 -1
- package/dist/internal/shares/interface.d.ts +2 -2
- package/dist/internal/shares/manager.d.ts +7 -7
- package/dist/internal/shares/manager.js.map +1 -1
- package/dist/internal/shares/manager.test.js +71 -63
- package/dist/internal/shares/manager.test.js.map +1 -1
- package/dist/internal/sharing/apiService.d.ts +4 -4
- package/dist/internal/sharing/apiService.js +4 -3
- package/dist/internal/sharing/apiService.js.map +1 -1
- package/dist/internal/sharing/cache.d.ts +2 -1
- package/dist/internal/sharing/cache.js +9 -0
- package/dist/internal/sharing/cache.js.map +1 -1
- package/dist/internal/sharing/cache.test.js +33 -33
- package/dist/internal/sharing/cryptoService.d.ts +3 -3
- package/dist/internal/sharing/cryptoService.js +3 -5
- package/dist/internal/sharing/cryptoService.js.map +1 -1
- package/dist/internal/sharing/cryptoService.test.js +39 -39
- package/dist/internal/sharing/cryptoService.test.js.map +1 -1
- package/dist/internal/sharing/events.d.ts +5 -4
- package/dist/internal/sharing/events.js +28 -19
- package/dist/internal/sharing/events.js.map +1 -1
- package/dist/internal/sharing/events.test.js +101 -88
- package/dist/internal/sharing/events.test.js.map +1 -1
- package/dist/internal/sharing/index.d.ts +6 -6
- package/dist/internal/sharing/index.js.map +1 -1
- package/dist/internal/sharing/interface.d.ts +5 -4
- package/dist/internal/sharing/sharingAccess.d.ts +6 -6
- package/dist/internal/sharing/sharingAccess.js +8 -4
- package/dist/internal/sharing/sharingAccess.js.map +1 -1
- package/dist/internal/sharing/sharingAccess.test.js +45 -39
- package/dist/internal/sharing/sharingAccess.test.js.map +1 -1
- package/dist/internal/sharing/sharingManagement.d.ts +4 -4
- package/dist/internal/sharing/sharingManagement.js +5 -7
- package/dist/internal/sharing/sharingManagement.js.map +1 -1
- package/dist/internal/sharing/sharingManagement.test.js +297 -248
- package/dist/internal/sharing/sharingManagement.test.js.map +1 -1
- package/dist/internal/uids.js.map +1 -1
- package/dist/internal/upload/apiService.d.ts +3 -3
- package/dist/internal/upload/apiService.js +1 -1
- package/dist/internal/upload/apiService.js.map +1 -1
- package/dist/internal/upload/blockVerifier.d.ts +3 -3
- package/dist/internal/upload/blockVerifier.js +1 -1
- package/dist/internal/upload/blockVerifier.js.map +1 -1
- package/dist/internal/upload/chunkStreamReader.test.js +6 -6
- package/dist/internal/upload/cryptoService.d.ts +4 -4
- package/dist/internal/upload/cryptoService.js +4 -4
- package/dist/internal/upload/cryptoService.js.map +1 -1
- package/dist/internal/upload/digests.js.map +1 -1
- package/dist/internal/upload/fileUploader.d.ts +6 -6
- package/dist/internal/upload/fileUploader.js.map +1 -1
- 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.map +1 -1
- package/dist/internal/upload/interface.d.ts +4 -3
- package/dist/internal/upload/manager.d.ts +5 -5
- package/dist/internal/upload/manager.js +15 -9
- package/dist/internal/upload/manager.js.map +1 -1
- package/dist/internal/upload/manager.test.js +139 -128
- package/dist/internal/upload/manager.test.js.map +1 -1
- package/dist/internal/upload/streamUploader.d.ts +6 -6
- package/dist/internal/upload/streamUploader.js +9 -7
- package/dist/internal/upload/streamUploader.js.map +1 -1
- package/dist/internal/upload/streamUploader.test.js +17 -12
- package/dist/internal/upload/streamUploader.test.js.map +1 -1
- package/dist/internal/upload/telemetry.d.ts +3 -3
- package/dist/internal/upload/telemetry.js +5 -3
- package/dist/internal/upload/telemetry.js.map +1 -1
- package/dist/internal/upload/telemetry.test.js +8 -8
- package/dist/internal/upload/telemetry.test.js.map +1 -1
- package/dist/protonDriveClient.d.ts +8 -8
- package/dist/protonDriveClient.js +12 -9
- package/dist/protonDriveClient.js.map +1 -1
- package/dist/protonDrivePhotosClient.js.map +1 -1
- package/dist/telemetry.js +18 -15
- package/dist/telemetry.js.map +1 -1
- package/dist/tests/logger.js.map +1 -1
- package/dist/tests/telemetry.d.ts +1 -1
- package/dist/transformers.d.ts +1 -1
- package/dist/transformers.js +5 -2
- package/dist/transformers.js.map +1 -1
- package/package.json +1 -1
- package/src/cache/interface.ts +22 -22
- package/src/cache/memoryCache.test.ts +7 -7
- package/src/cache/memoryCache.ts +4 -4
- package/src/cache/nullCache.ts +1 -1
- package/src/config.ts +5 -5
- package/src/crypto/driveCrypto.test.ts +15 -15
- package/src/crypto/driveCrypto.ts +120 -156
- package/src/crypto/hmac.ts +1 -1
- package/src/crypto/interface.ts +63 -72
- package/src/crypto/openPGPCrypto.ts +74 -94
- package/src/crypto/utils.ts +1 -1
- package/src/diagnostic/eventsGenerator.ts +2 -2
- package/src/diagnostic/httpClient.ts +6 -2
- package/src/diagnostic/index.ts +12 -10
- package/src/diagnostic/integrityVerificationStream.ts +3 -4
- package/src/diagnostic/interface.ts +81 -81
- package/src/diagnostic/sdkDiagnostic.ts +35 -24
- package/src/diagnostic/sdkDiagnosticFull.ts +16 -19
- package/src/diagnostic/telemetry.ts +4 -1
- package/src/diagnostic/zipGenerators.test.ts +1 -1
- package/src/diagnostic/zipGenerators.ts +3 -3
- package/src/errors.ts +21 -21
- package/src/index.ts +3 -3
- package/src/interface/account.ts +10 -10
- package/src/interface/author.ts +6 -6
- package/src/interface/config.ts +4 -4
- package/src/interface/devices.ts +6 -6
- package/src/interface/download.ts +12 -9
- package/src/interface/events.ts +45 -39
- package/src/interface/httpClient.ts +11 -11
- package/src/interface/index.ts +76 -19
- package/src/interface/nodes.ts +47 -49
- package/src/interface/result.ts +1 -3
- package/src/interface/sharing.ts +60 -57
- package/src/interface/telemetry.ts +74 -74
- package/src/interface/thumbnail.ts +5 -6
- package/src/interface/upload.ts +20 -12
- package/src/internal/apiService/apiService.test.ts +109 -76
- package/src/internal/apiService/apiService.ts +40 -26
- package/src/internal/apiService/coreTypes.ts +2474 -2463
- package/src/internal/apiService/driveTypes.ts +1868 -1822
- package/src/internal/apiService/errorCodes.ts +4 -4
- package/src/internal/apiService/errors.test.ts +25 -23
- package/src/internal/apiService/errors.ts +15 -9
- package/src/internal/apiService/index.ts +1 -1
- package/src/internal/apiService/transformers.ts +2 -2
- package/src/internal/asyncIteratorMap.test.ts +4 -4
- package/src/internal/asyncIteratorMap.ts +1 -1
- package/src/internal/asyncIteratorRace.test.ts +149 -0
- package/src/internal/asyncIteratorRace.ts +79 -0
- package/src/internal/batch.test.ts +50 -0
- package/src/internal/batch.ts +9 -0
- package/src/internal/batchLoading.test.ts +13 -14
- package/src/internal/batchLoading.ts +8 -8
- package/src/internal/devices/apiService.ts +58 -51
- package/src/internal/devices/cryptoService.ts +22 -17
- package/src/internal/devices/index.ts +17 -10
- package/src/internal/devices/interface.ts +21 -12
- package/src/internal/devices/manager.test.ts +40 -9
- package/src/internal/devices/manager.ts +3 -3
- package/src/internal/download/apiService.ts +66 -49
- package/src/internal/download/cryptoService.ts +34 -18
- package/src/internal/download/fileDownloader.test.ts +25 -9
- package/src/internal/download/fileDownloader.ts +36 -18
- package/src/internal/download/index.ts +19 -19
- package/src/internal/download/interface.ts +19 -20
- package/src/internal/download/queue.ts +3 -3
- package/src/internal/download/telemetry.test.ts +11 -11
- package/src/internal/download/telemetry.ts +24 -14
- package/src/internal/download/thumbnailDownloader.test.ts +11 -6
- package/src/internal/download/thumbnailDownloader.ts +43 -32
- package/src/internal/errors.ts +7 -5
- package/src/internal/events/apiService.ts +30 -17
- package/src/internal/events/coreEventManager.test.ts +18 -18
- package/src/internal/events/coreEventManager.ts +9 -6
- package/src/internal/events/eventManager.test.ts +108 -82
- package/src/internal/events/eventManager.ts +16 -5
- package/src/internal/events/index.ts +75 -47
- package/src/internal/events/interface.ts +47 -39
- package/src/internal/events/volumeEventManager.test.ts +61 -65
- package/src/internal/events/volumeEventManager.ts +18 -9
- package/src/internal/nodes/apiService.test.ts +197 -147
- package/src/internal/nodes/apiService.ts +288 -174
- package/src/internal/nodes/cache.test.ts +48 -20
- package/src/internal/nodes/cache.ts +60 -44
- package/src/internal/nodes/cryptoCache.test.ts +34 -14
- package/src/internal/nodes/cryptoCache.ts +10 -5
- package/src/internal/nodes/cryptoService.test.ts +492 -351
- package/src/internal/nodes/cryptoService.ts +170 -88
- package/src/internal/nodes/events.test.ts +38 -28
- package/src/internal/nodes/events.ts +13 -12
- package/src/internal/nodes/extendedAttributes.test.ts +28 -24
- package/src/internal/nodes/extendedAttributes.ts +20 -15
- package/src/internal/nodes/index.test.ts +133 -0
- package/src/internal/nodes/index.ts +27 -15
- package/src/internal/nodes/interface.ts +42 -29
- package/src/internal/nodes/nodesAccess.test.ts +124 -58
- package/src/internal/nodes/nodesAccess.ts +73 -49
- package/src/internal/nodes/nodesManagement.test.ts +32 -31
- package/src/internal/nodes/nodesManagement.ts +39 -32
- package/src/internal/nodes/nodesRevisions.ts +7 -7
- package/src/internal/nodes/validations.ts +2 -2
- package/src/internal/photos/albums.ts +5 -5
- package/src/internal/photos/apiService.ts +4 -7
- package/src/internal/photos/cache.ts +1 -1
- package/src/internal/photos/index.ts +8 -8
- package/src/internal/photos/interface.ts +2 -2
- package/src/internal/photos/photosTimeline.ts +4 -5
- package/src/internal/sdkEvents.test.ts +10 -10
- package/src/internal/sdkEvents.ts +5 -13
- package/src/internal/shares/apiService.ts +44 -33
- package/src/internal/shares/cache.test.ts +6 -4
- package/src/internal/shares/cache.ts +21 -12
- package/src/internal/shares/cryptoCache.test.ts +17 -11
- package/src/internal/shares/cryptoCache.ts +4 -4
- package/src/internal/shares/cryptoService.test.ts +72 -74
- package/src/internal/shares/cryptoService.ts +48 -23
- package/src/internal/shares/index.ts +23 -11
- package/src/internal/shares/interface.ts +8 -8
- package/src/internal/shares/manager.test.ts +88 -80
- package/src/internal/shares/manager.ts +19 -19
- package/src/internal/sharing/apiService.ts +282 -175
- package/src/internal/sharing/cache.test.ts +35 -35
- package/src/internal/sharing/cache.ts +11 -2
- package/src/internal/sharing/cryptoService.test.ts +58 -46
- package/src/internal/sharing/cryptoService.ts +121 -84
- package/src/internal/sharing/events.test.ts +113 -102
- package/src/internal/sharing/events.ts +42 -24
- package/src/internal/sharing/index.ts +22 -11
- package/src/internal/sharing/interface.ts +40 -40
- package/src/internal/sharing/sharingAccess.test.ts +71 -65
- package/src/internal/sharing/sharingAccess.ts +39 -21
- package/src/internal/sharing/sharingManagement.test.ts +398 -298
- package/src/internal/sharing/sharingManagement.ts +138 -65
- package/src/internal/uids.ts +1 -1
- package/src/internal/upload/apiService.ts +167 -117
- package/src/internal/upload/blockVerifier.ts +8 -6
- package/src/internal/upload/chunkStreamReader.test.ts +7 -7
- package/src/internal/upload/cryptoService.ts +42 -36
- package/src/internal/upload/digests.ts +2 -2
- package/src/internal/upload/fileUploader.test.ts +15 -3
- package/src/internal/upload/fileUploader.ts +39 -17
- package/src/internal/upload/index.ts +13 -14
- package/src/internal/upload/interface.ts +79 -78
- package/src/internal/upload/manager.test.ts +170 -156
- package/src/internal/upload/manager.ts +66 -39
- package/src/internal/upload/queue.ts +3 -3
- package/src/internal/upload/streamUploader.test.ts +40 -26
- package/src/internal/upload/streamUploader.ts +87 -69
- package/src/internal/upload/telemetry.test.ts +11 -11
- package/src/internal/upload/telemetry.ts +25 -15
- package/src/internal/wait.test.ts +1 -1
- package/src/internal/wait.ts +3 -3
- package/src/protonDriveClient.ts +121 -39
- package/src/protonDrivePhotosClient.ts +16 -10
- package/src/telemetry.ts +60 -52
- package/src/tests/logger.ts +1 -1
- package/src/tests/telemetry.ts +2 -2
- package/src/transformers.ts +29 -21
- package/src/version.ts +0 -1
|
@@ -1,57 +1,108 @@
|
|
|
1
|
-
import { c } from
|
|
2
|
-
|
|
3
|
-
import { ProtonDriveError, ValidationError } from
|
|
4
|
-
import { Logger, NodeResult } from
|
|
5
|
-
import { MemberRole, RevisionState } from
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
type
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
1
|
+
import { c } from 'ttag';
|
|
2
|
+
|
|
3
|
+
import { ProtonDriveError, ValidationError } from '../../errors';
|
|
4
|
+
import { Logger, NodeResult } from '../../interface';
|
|
5
|
+
import { MemberRole, RevisionState } from '../../interface/nodes';
|
|
6
|
+
import {
|
|
7
|
+
DriveAPIService,
|
|
8
|
+
drivePaths,
|
|
9
|
+
isCodeOk,
|
|
10
|
+
nodeTypeNumberToNodeType,
|
|
11
|
+
permissionsToDirectMemberRole,
|
|
12
|
+
} from '../apiService';
|
|
13
|
+
import { asyncIteratorRace } from '../asyncIteratorRace';
|
|
14
|
+
import { batch } from '../batch';
|
|
15
|
+
import { splitNodeUid, makeNodeUid, makeNodeRevisionUid, splitNodeRevisionUid, makeNodeThumbnailUid } from '../uids';
|
|
16
|
+
import { EncryptedNode, EncryptedRevision, Thumbnail } from './interface';
|
|
17
|
+
|
|
18
|
+
// This is the number of calls to the API that are made in parallel.
|
|
19
|
+
const API_CONCURRENCY = 15;
|
|
20
|
+
|
|
21
|
+
// This is the number of nodes that are loaded from the API in one call.
|
|
22
|
+
const API_NODES_BATCH_SIZE = 100;
|
|
23
|
+
|
|
24
|
+
type PostLoadLinksMetadataRequest = Extract<
|
|
25
|
+
drivePaths['/drive/v2/volumes/{volumeID}/links']['post']['requestBody'],
|
|
26
|
+
{ content: object }
|
|
27
|
+
>['content']['application/json'];
|
|
28
|
+
type PostLoadLinksMetadataResponse =
|
|
29
|
+
drivePaths['/drive/v2/volumes/{volumeID}/links']['post']['responses']['200']['content']['application/json'];
|
|
30
|
+
|
|
31
|
+
type GetChildrenResponse =
|
|
32
|
+
drivePaths['/drive/v2/volumes/{volumeID}/folders/{linkID}/children']['get']['responses']['200']['content']['application/json'];
|
|
33
|
+
|
|
34
|
+
type GetTrashedNodesResponse =
|
|
35
|
+
drivePaths['/drive/volumes/{volumeID}/trash']['get']['responses']['200']['content']['application/json'];
|
|
36
|
+
|
|
37
|
+
type PutRenameNodeRequest = Extract<
|
|
38
|
+
drivePaths['/drive/v2/volumes/{volumeID}/links/{linkID}/rename']['put']['requestBody'],
|
|
39
|
+
{ content: object }
|
|
40
|
+
>['content']['application/json'];
|
|
41
|
+
type PutRenameNodeResponse =
|
|
42
|
+
drivePaths['/drive/v2/volumes/{volumeID}/links/{linkID}/rename']['put']['responses']['200']['content']['application/json'];
|
|
43
|
+
|
|
44
|
+
type PutMoveNodeRequest = Extract<
|
|
45
|
+
drivePaths['/drive/v2/volumes/{volumeID}/links/{linkID}/move']['put']['requestBody'],
|
|
46
|
+
{ content: object }
|
|
47
|
+
>['content']['application/json'];
|
|
48
|
+
type PutMoveNodeResponse =
|
|
49
|
+
drivePaths['/drive/v2/volumes/{volumeID}/links/{linkID}/move']['put']['responses']['200']['content']['application/json'];
|
|
50
|
+
|
|
51
|
+
type PostTrashNodesRequest = Extract<
|
|
52
|
+
drivePaths['/drive/v2/volumes/{volumeID}/trash_multiple']['post']['requestBody'],
|
|
53
|
+
{ content: object }
|
|
54
|
+
>['content']['application/json'];
|
|
55
|
+
type PostTrashNodesResponse =
|
|
56
|
+
drivePaths['/drive/v2/volumes/{volumeID}/trash_multiple']['post']['responses']['200']['content']['application/json'];
|
|
57
|
+
|
|
58
|
+
type PutRestoreNodesRequest = Extract<
|
|
59
|
+
drivePaths['/drive/v2/volumes/{volumeID}/trash/restore_multiple']['put']['requestBody'],
|
|
60
|
+
{ content: object }
|
|
61
|
+
>['content']['application/json'];
|
|
62
|
+
type PutRestoreNodesResponse =
|
|
63
|
+
drivePaths['/drive/v2/volumes/{volumeID}/trash/restore_multiple']['put']['responses']['200']['content']['application/json'];
|
|
64
|
+
|
|
65
|
+
type PostDeleteNodesRequest = Extract<
|
|
66
|
+
drivePaths['/drive/v2/volumes/{volumeID}/trash/delete_multiple']['post']['requestBody'],
|
|
67
|
+
{ content: object }
|
|
68
|
+
>['content']['application/json'];
|
|
69
|
+
type PostDeleteNodesResponse =
|
|
70
|
+
drivePaths['/drive/v2/volumes/{volumeID}/trash/delete_multiple']['post']['responses']['200']['content']['application/json'];
|
|
71
|
+
|
|
72
|
+
type PostCreateFolderRequest = Extract<
|
|
73
|
+
drivePaths['/drive/v2/volumes/{volumeID}/folders']['post']['requestBody'],
|
|
74
|
+
{ content: object }
|
|
75
|
+
>['content']['application/json'];
|
|
76
|
+
type PostCreateFolderResponse =
|
|
77
|
+
drivePaths['/drive/v2/volumes/{volumeID}/folders']['post']['responses']['200']['content']['application/json'];
|
|
78
|
+
|
|
79
|
+
type GetRevisionResponse =
|
|
80
|
+
drivePaths['/drive/v2/volumes/{volumeID}/files/{linkID}/revisions/{revisionID}']['get']['responses']['200']['content']['application/json'];
|
|
81
|
+
type GetRevisionsResponse =
|
|
82
|
+
drivePaths['/drive/v2/volumes/{volumeID}/files/{linkID}/revisions']['get']['responses']['200']['content']['application/json'];
|
|
37
83
|
enum APIRevisionState {
|
|
38
84
|
Draft = 0,
|
|
39
85
|
Active = 1,
|
|
40
86
|
Obsolete = 2,
|
|
41
87
|
}
|
|
42
88
|
|
|
43
|
-
type PostRestoreRevisionResponse =
|
|
89
|
+
type PostRestoreRevisionResponse =
|
|
90
|
+
drivePaths['/drive/v2/volumes/{volumeID}/files/{linkID}/revisions/{revisionID}/restore']['post']['responses']['202']['content']['application/json'];
|
|
44
91
|
|
|
45
|
-
type DeleteRevisionResponse =
|
|
92
|
+
type DeleteRevisionResponse =
|
|
93
|
+
drivePaths['/drive/v2/volumes/{volumeID}/files/{linkID}/revisions/{revisionID}']['delete']['responses']['200']['content']['application/json'];
|
|
46
94
|
|
|
47
95
|
/**
|
|
48
96
|
* Provides API communication for fetching and manipulating nodes metadata.
|
|
49
|
-
*
|
|
97
|
+
*
|
|
50
98
|
* The service is responsible for transforming local objects to API payloads
|
|
51
99
|
* and vice versa. It should not contain any business logic.
|
|
52
100
|
*/
|
|
53
101
|
export class NodeAPIService {
|
|
54
|
-
constructor(
|
|
102
|
+
constructor(
|
|
103
|
+
private logger: Logger,
|
|
104
|
+
private apiService: DriveAPIService,
|
|
105
|
+
) {
|
|
55
106
|
this.logger = logger;
|
|
56
107
|
this.apiService = apiService;
|
|
57
108
|
}
|
|
@@ -59,12 +110,11 @@ export class NodeAPIService {
|
|
|
59
110
|
async getNode(nodeUid: string, ownVolumeId: string, signal?: AbortSignal): Promise<EncryptedNode> {
|
|
60
111
|
const nodesGenerator = this.iterateNodes([nodeUid], ownVolumeId, signal);
|
|
61
112
|
const result = await nodesGenerator.next();
|
|
62
|
-
await nodesGenerator.return(
|
|
113
|
+
await nodesGenerator.return('finish');
|
|
63
114
|
return result.value;
|
|
64
115
|
}
|
|
65
116
|
|
|
66
|
-
|
|
67
|
-
async* iterateNodes(nodeUids: string[], ownVolumeId: string, signal?: AbortSignal): AsyncGenerator<EncryptedNode> {
|
|
117
|
+
async *iterateNodes(nodeUids: string[], ownVolumeId: string, signal?: AbortSignal): AsyncGenerator<EncryptedNode> {
|
|
68
118
|
const allNodeIds = nodeUids.map(splitNodeUid);
|
|
69
119
|
|
|
70
120
|
const nodeIdsByVolumeId = new Map<string, string[]>();
|
|
@@ -78,18 +128,50 @@ export class NodeAPIService {
|
|
|
78
128
|
// If the API returns node that is not recognised, it is returned as
|
|
79
129
|
// an error, but first all nodes that are recognised are yielded.
|
|
80
130
|
// Thus we capture all errors and throw them at the end of iteration.
|
|
81
|
-
const errors = [];
|
|
131
|
+
const errors: unknown[] = [];
|
|
132
|
+
|
|
133
|
+
const iterateNodesPerVolume = this.iterateNodesPerVolume.bind(this);
|
|
134
|
+
const iterateNodesPerVolumeGenerator = async function* () {
|
|
135
|
+
for (const [volumeId, nodeIds] of nodeIdsByVolumeId.entries()) {
|
|
136
|
+
const isAdmin = volumeId === ownVolumeId;
|
|
137
|
+
|
|
138
|
+
yield (async function* () {
|
|
139
|
+
const errorsPerVolume = yield* iterateNodesPerVolume(volumeId, nodeIds, isAdmin, signal);
|
|
140
|
+
if (errorsPerVolume.length) {
|
|
141
|
+
errors.push(...errorsPerVolume);
|
|
142
|
+
}
|
|
143
|
+
})();
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
yield* asyncIteratorRace(iterateNodesPerVolumeGenerator(), API_CONCURRENCY);
|
|
82
148
|
|
|
83
|
-
|
|
84
|
-
|
|
149
|
+
if (errors.length) {
|
|
150
|
+
this.logger.warn(`Failed to load ${errors.length} nodes`);
|
|
151
|
+
throw new ProtonDriveError(c('Error').t`Failed to load some nodes`, { cause: errors });
|
|
152
|
+
}
|
|
153
|
+
}
|
|
85
154
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
155
|
+
private async *iterateNodesPerVolume(
|
|
156
|
+
volumeId: string,
|
|
157
|
+
nodeIds: string[],
|
|
158
|
+
isOwnVolumeId: boolean,
|
|
159
|
+
signal?: AbortSignal,
|
|
160
|
+
): AsyncGenerator<EncryptedNode, unknown[]> {
|
|
161
|
+
const errors: unknown[] = [];
|
|
162
|
+
|
|
163
|
+
for (const nodeIdsBatch of batch(nodeIds, API_NODES_BATCH_SIZE)) {
|
|
164
|
+
const response = await this.apiService.post<PostLoadLinksMetadataRequest, PostLoadLinksMetadataResponse>(
|
|
165
|
+
`drive/v2/volumes/${volumeId}/links`,
|
|
166
|
+
{
|
|
167
|
+
LinkIDs: nodeIdsBatch,
|
|
168
|
+
},
|
|
169
|
+
signal,
|
|
170
|
+
);
|
|
89
171
|
|
|
90
172
|
for (const link of response.Links) {
|
|
91
173
|
try {
|
|
92
|
-
yield linkToEncryptedNode(this.logger, volumeId, link,
|
|
174
|
+
yield linkToEncryptedNode(this.logger, volumeId, link, isOwnVolumeId);
|
|
93
175
|
} catch (error: unknown) {
|
|
94
176
|
this.logger.error(`Failed to transform node ${link.Link.LinkID}`, error);
|
|
95
177
|
errors.push(error);
|
|
@@ -97,24 +179,23 @@ export class NodeAPIService {
|
|
|
97
179
|
}
|
|
98
180
|
}
|
|
99
181
|
|
|
100
|
-
|
|
101
|
-
if (errors.length) {
|
|
102
|
-
this.logger.warn(`Failed to load ${errors.length} nodes`);
|
|
103
|
-
throw new ProtonDriveError(c('Error').t`Failed to load some nodes`, { cause: errors });
|
|
104
|
-
}
|
|
182
|
+
return errors;
|
|
105
183
|
}
|
|
106
184
|
|
|
107
185
|
// Improvement requested: load next page sooner before all IDs are yielded.
|
|
108
186
|
async *iterateChildrenNodeUids(parentNodeUid: string, signal?: AbortSignal): AsyncGenerator<string> {
|
|
109
187
|
const { volumeId, nodeId } = splitNodeUid(parentNodeUid);
|
|
110
188
|
|
|
111
|
-
let anchor =
|
|
189
|
+
let anchor = '';
|
|
112
190
|
while (true) {
|
|
113
|
-
const response = await this.apiService.get<GetChildrenResponse>(
|
|
191
|
+
const response = await this.apiService.get<GetChildrenResponse>(
|
|
192
|
+
`drive/v2/volumes/${volumeId}/folders/${nodeId}/children?${anchor ? `AnchorID=${anchor}` : ''}`,
|
|
193
|
+
signal,
|
|
194
|
+
);
|
|
114
195
|
for (const linkID of response.LinkIDs) {
|
|
115
196
|
yield makeNodeUid(volumeId, linkID);
|
|
116
197
|
}
|
|
117
|
-
|
|
198
|
+
|
|
118
199
|
if (!response.More || !response.AnchorID) {
|
|
119
200
|
break;
|
|
120
201
|
}
|
|
@@ -126,8 +207,11 @@ export class NodeAPIService {
|
|
|
126
207
|
async *iterateTrashedNodeUids(volumeId: string, signal?: AbortSignal): AsyncGenerator<string> {
|
|
127
208
|
let page = 0;
|
|
128
209
|
while (true) {
|
|
129
|
-
const response = await this.apiService.get<GetTrashedNodesResponse>(
|
|
130
|
-
|
|
210
|
+
const response = await this.apiService.get<GetTrashedNodesResponse>(
|
|
211
|
+
`drive/volumes/${volumeId}/trash?Page=${page}`,
|
|
212
|
+
signal,
|
|
213
|
+
);
|
|
214
|
+
|
|
131
215
|
// The API returns items per shares which is not straightforward to
|
|
132
216
|
// count if there is another page. We had mistakes in the past, thus
|
|
133
217
|
// we rather end when the page is fully empty.
|
|
@@ -142,7 +226,7 @@ export class NodeAPIService {
|
|
|
142
226
|
hasItems = true;
|
|
143
227
|
}
|
|
144
228
|
}
|
|
145
|
-
|
|
229
|
+
|
|
146
230
|
if (!hasItems) {
|
|
147
231
|
break;
|
|
148
232
|
}
|
|
@@ -153,110 +237,115 @@ export class NodeAPIService {
|
|
|
153
237
|
async renameNode(
|
|
154
238
|
nodeUid: string,
|
|
155
239
|
originalNode: {
|
|
156
|
-
hash?: string
|
|
240
|
+
hash?: string;
|
|
157
241
|
},
|
|
158
242
|
newNode: {
|
|
159
|
-
encryptedName: string
|
|
160
|
-
nameSignatureEmail: string
|
|
161
|
-
hash?: string
|
|
243
|
+
encryptedName: string;
|
|
244
|
+
nameSignatureEmail: string;
|
|
245
|
+
hash?: string;
|
|
162
246
|
},
|
|
163
247
|
signal?: AbortSignal,
|
|
164
248
|
): Promise<void> {
|
|
165
249
|
const { volumeId, nodeId } = splitNodeUid(nodeUid);
|
|
166
250
|
|
|
167
|
-
await this.apiService.put<
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
251
|
+
await this.apiService.put<Omit<PutRenameNodeRequest, 'SignatureAddress' | 'MIMEType'>, PutRenameNodeResponse>(
|
|
252
|
+
`drive/v2/volumes/${volumeId}/links/${nodeId}/rename`,
|
|
253
|
+
{
|
|
254
|
+
Name: newNode.encryptedName,
|
|
255
|
+
NameSignatureEmail: newNode.nameSignatureEmail,
|
|
256
|
+
Hash: newNode.hash,
|
|
257
|
+
OriginalHash: originalNode.hash || null,
|
|
258
|
+
},
|
|
259
|
+
signal,
|
|
260
|
+
);
|
|
176
261
|
}
|
|
177
262
|
|
|
178
263
|
async moveNode(
|
|
179
264
|
nodeUid: string,
|
|
180
265
|
oldNode: {
|
|
181
|
-
hash: string
|
|
266
|
+
hash: string;
|
|
182
267
|
},
|
|
183
268
|
newNode: {
|
|
184
|
-
parentUid: string
|
|
185
|
-
armoredNodePassphrase: string
|
|
186
|
-
armoredNodePassphraseSignature?: string
|
|
187
|
-
signatureEmail?: string
|
|
188
|
-
encryptedName: string
|
|
189
|
-
nameSignatureEmail?: string
|
|
190
|
-
hash: string
|
|
191
|
-
contentHash?: string
|
|
269
|
+
parentUid: string;
|
|
270
|
+
armoredNodePassphrase: string;
|
|
271
|
+
armoredNodePassphraseSignature?: string;
|
|
272
|
+
signatureEmail?: string;
|
|
273
|
+
encryptedName: string;
|
|
274
|
+
nameSignatureEmail?: string;
|
|
275
|
+
hash: string;
|
|
276
|
+
contentHash?: string;
|
|
192
277
|
},
|
|
193
278
|
signal?: AbortSignal,
|
|
194
279
|
): Promise<void> {
|
|
195
280
|
const { volumeId, nodeId } = splitNodeUid(nodeUid);
|
|
196
281
|
const { nodeId: newParentNodeId } = splitNodeUid(newNode.parentUid);
|
|
197
282
|
|
|
198
|
-
await this.apiService.put<
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
283
|
+
await this.apiService.put<Omit<PutMoveNodeRequest, 'SignatureAddress' | 'MIMEType'>, PutMoveNodeResponse>(
|
|
284
|
+
`drive/v2/volumes/${volumeId}/links/${nodeId}/move`,
|
|
285
|
+
{
|
|
286
|
+
ParentLinkID: newParentNodeId,
|
|
287
|
+
NodePassphrase: newNode.armoredNodePassphrase,
|
|
288
|
+
// @ts-expect-error: API accepts NodePassphraseSignature as optional.
|
|
289
|
+
NodePassphraseSignature: newNode.armoredNodePassphraseSignature,
|
|
290
|
+
// @ts-expect-error: API accepts SignatureEmail as optional.
|
|
291
|
+
SignatureEmail: newNode.signatureEmail,
|
|
292
|
+
Name: newNode.encryptedName,
|
|
293
|
+
// @ts-expect-error: API accepts NameSignatureEmail as optional.
|
|
294
|
+
NameSignatureEmail: newNode.nameSignatureEmail,
|
|
295
|
+
Hash: newNode.hash,
|
|
296
|
+
OriginalHash: oldNode.hash,
|
|
297
|
+
ContentHash: newNode.contentHash || null,
|
|
298
|
+
},
|
|
299
|
+
signal,
|
|
300
|
+
);
|
|
215
301
|
}
|
|
216
302
|
|
|
217
303
|
// Improvement requested: split into multiple calls for many nodes.
|
|
218
|
-
async*
|
|
304
|
+
async *trashNodes(nodeUids: string[], signal?: AbortSignal): AsyncGenerator<NodeResult> {
|
|
219
305
|
const nodeIds = nodeUids.map(splitNodeUid);
|
|
220
306
|
const volumeId = assertAndGetSingleVolumeId(c('Operation').t`Trashing items`, nodeIds);
|
|
221
307
|
|
|
222
|
-
const response = await this.apiService.post<
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
308
|
+
const response = await this.apiService.post<PostTrashNodesRequest, PostTrashNodesResponse>(
|
|
309
|
+
`drive/v2/volumes/${volumeId}/trash_multiple`,
|
|
310
|
+
{
|
|
311
|
+
LinkIDs: nodeIds.map(({ nodeId }) => nodeId),
|
|
312
|
+
},
|
|
313
|
+
signal,
|
|
314
|
+
);
|
|
228
315
|
|
|
229
316
|
// TODO: remove `as` when backend fixes OpenAPI schema.
|
|
230
317
|
yield* handleResponseErrors(nodeUids, volumeId, response.Responses as LinkResponse[]);
|
|
231
318
|
}
|
|
232
319
|
|
|
233
320
|
// Improvement requested: split into multiple calls for many nodes.
|
|
234
|
-
async*
|
|
321
|
+
async *restoreNodes(nodeUids: string[], signal?: AbortSignal): AsyncGenerator<NodeResult> {
|
|
235
322
|
const nodeIds = nodeUids.map(splitNodeUid);
|
|
236
323
|
const volumeId = assertAndGetSingleVolumeId(c('Operation').t`Restoring items`, nodeIds);
|
|
237
324
|
|
|
238
|
-
const response = await this.apiService.put<
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
325
|
+
const response = await this.apiService.put<PutRestoreNodesRequest, PutRestoreNodesResponse>(
|
|
326
|
+
`drive/v2/volumes/${volumeId}/trash/restore_multiple`,
|
|
327
|
+
{
|
|
328
|
+
LinkIDs: nodeIds.map(({ nodeId }) => nodeId),
|
|
329
|
+
},
|
|
330
|
+
signal,
|
|
331
|
+
);
|
|
244
332
|
|
|
245
333
|
// TODO: remove `as` when backend fixes OpenAPI schema.
|
|
246
334
|
yield* handleResponseErrors(nodeUids, volumeId, response.Responses as LinkResponse[]);
|
|
247
335
|
}
|
|
248
336
|
|
|
249
337
|
// Improvement requested: split into multiple calls for many nodes.
|
|
250
|
-
async*
|
|
338
|
+
async *deleteNodes(nodeUids: string[], signal?: AbortSignal): AsyncGenerator<NodeResult> {
|
|
251
339
|
const nodeIds = nodeUids.map(splitNodeUid);
|
|
252
340
|
const volumeId = assertAndGetSingleVolumeId(c('Operation').t`Deleting items`, nodeIds);
|
|
253
341
|
|
|
254
|
-
const response = await this.apiService.post<
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
342
|
+
const response = await this.apiService.post<PostDeleteNodesRequest, PostDeleteNodesResponse>(
|
|
343
|
+
`drive/v2/volumes/${volumeId}/trash/delete_multiple`,
|
|
344
|
+
{
|
|
345
|
+
LinkIDs: nodeIds.map(({ nodeId }) => nodeId),
|
|
346
|
+
},
|
|
347
|
+
signal,
|
|
348
|
+
);
|
|
260
349
|
|
|
261
350
|
// TODO: remove `as` when backend fixes OpenAPI schema.
|
|
262
351
|
yield* handleResponseErrors(nodeUids, volumeId, response.Responses as LinkResponse[]);
|
|
@@ -265,33 +354,33 @@ export class NodeAPIService {
|
|
|
265
354
|
async createFolder(
|
|
266
355
|
parentUid: string,
|
|
267
356
|
newNode: {
|
|
268
|
-
armoredKey: string
|
|
269
|
-
armoredHashKey: string
|
|
270
|
-
armoredNodePassphrase: string
|
|
271
|
-
armoredNodePassphraseSignature: string
|
|
272
|
-
signatureEmail: string
|
|
273
|
-
encryptedName: string
|
|
274
|
-
hash: string
|
|
275
|
-
armoredExtendedAttributes?: string
|
|
357
|
+
armoredKey: string;
|
|
358
|
+
armoredHashKey: string;
|
|
359
|
+
armoredNodePassphrase: string;
|
|
360
|
+
armoredNodePassphraseSignature: string;
|
|
361
|
+
signatureEmail: string;
|
|
362
|
+
encryptedName: string;
|
|
363
|
+
hash: string;
|
|
364
|
+
armoredExtendedAttributes?: string;
|
|
276
365
|
},
|
|
277
366
|
): Promise<string> {
|
|
278
367
|
const { volumeId, nodeId: parentId } = splitNodeUid(parentUid);
|
|
279
368
|
|
|
280
|
-
const response = await this.apiService.post<
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
369
|
+
const response = await this.apiService.post<PostCreateFolderRequest, PostCreateFolderResponse>(
|
|
370
|
+
`drive/v2/volumes/${volumeId}/folders`,
|
|
371
|
+
{
|
|
372
|
+
ParentLinkID: parentId,
|
|
373
|
+
NodeKey: newNode.armoredKey,
|
|
374
|
+
NodeHashKey: newNode.armoredHashKey,
|
|
375
|
+
NodePassphrase: newNode.armoredNodePassphrase,
|
|
376
|
+
NodePassphraseSignature: newNode.armoredNodePassphraseSignature,
|
|
377
|
+
SignatureEmail: newNode.signatureEmail,
|
|
378
|
+
Name: newNode.encryptedName,
|
|
379
|
+
Hash: newNode.hash,
|
|
380
|
+
// @ts-expect-error: XAttr is optional as undefined.
|
|
381
|
+
XAttr: newNode.armoredExtendedAttributes,
|
|
382
|
+
},
|
|
383
|
+
);
|
|
295
384
|
|
|
296
385
|
return makeNodeUid(volumeId, response.Folder.ID);
|
|
297
386
|
}
|
|
@@ -299,32 +388,39 @@ export class NodeAPIService {
|
|
|
299
388
|
async getRevision(nodeRevisionUid: string, signal?: AbortSignal): Promise<EncryptedRevision> {
|
|
300
389
|
const { volumeId, nodeId, revisionId } = splitNodeRevisionUid(nodeRevisionUid);
|
|
301
390
|
|
|
302
|
-
const response = await this.apiService.get<GetRevisionResponse>(
|
|
391
|
+
const response = await this.apiService.get<GetRevisionResponse>(
|
|
392
|
+
`drive/v2/volumes/${volumeId}/files/${nodeId}/revisions/${revisionId}?NoBlockUrls=true`,
|
|
393
|
+
signal,
|
|
394
|
+
);
|
|
303
395
|
return transformRevisionResponse(volumeId, nodeId, response.Revision);
|
|
304
396
|
}
|
|
305
397
|
|
|
306
398
|
async getRevisions(nodeUid: string, signal?: AbortSignal): Promise<EncryptedRevision[]> {
|
|
307
399
|
const { volumeId, nodeId } = splitNodeUid(nodeUid);
|
|
308
400
|
|
|
309
|
-
const response = await this.apiService.get<GetRevisionsResponse>(
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
401
|
+
const response = await this.apiService.get<GetRevisionsResponse>(
|
|
402
|
+
`drive/v2/volumes/${volumeId}/files/${nodeId}/revisions`,
|
|
403
|
+
signal,
|
|
404
|
+
);
|
|
405
|
+
return response.Revisions.filter(
|
|
406
|
+
(revision) => revision.State === APIRevisionState.Active || revision.State === APIRevisionState.Obsolete,
|
|
407
|
+
).map((revision) => transformRevisionResponse(volumeId, nodeId, revision));
|
|
313
408
|
}
|
|
314
409
|
|
|
315
410
|
async restoreRevision(nodeRevisionUid: string): Promise<void> {
|
|
316
411
|
const { volumeId, nodeId, revisionId } = splitNodeRevisionUid(nodeRevisionUid);
|
|
317
412
|
|
|
318
|
-
await this.apiService.post<
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
>(`drive/v2/volumes/${volumeId}/files/${nodeId}/revisions/${revisionId}/restore`);
|
|
413
|
+
await this.apiService.post<undefined, PostRestoreRevisionResponse>(
|
|
414
|
+
`drive/v2/volumes/${volumeId}/files/${nodeId}/revisions/${revisionId}/restore`,
|
|
415
|
+
);
|
|
322
416
|
}
|
|
323
417
|
|
|
324
418
|
async deleteRevision(nodeRevisionUid: string): Promise<void> {
|
|
325
419
|
const { volumeId, nodeId, revisionId } = splitNodeRevisionUid(nodeRevisionUid);
|
|
326
420
|
|
|
327
|
-
await this.apiService.delete<DeleteRevisionResponse>(
|
|
421
|
+
await this.apiService.delete<DeleteRevisionResponse>(
|
|
422
|
+
`drive/v2/volumes/${volumeId}/files/${nodeId}/revisions/${revisionId}`,
|
|
423
|
+
);
|
|
328
424
|
}
|
|
329
425
|
}
|
|
330
426
|
|
|
@@ -338,14 +434,18 @@ function assertAndGetSingleVolumeId(operationForErrorMessage: string, nodeIds: {
|
|
|
338
434
|
}
|
|
339
435
|
|
|
340
436
|
type LinkResponse = {
|
|
341
|
-
LinkID: string
|
|
437
|
+
LinkID: string;
|
|
342
438
|
Response: {
|
|
343
|
-
Code?: number
|
|
344
|
-
Error?: string
|
|
345
|
-
}
|
|
439
|
+
Code?: number;
|
|
440
|
+
Error?: string;
|
|
441
|
+
};
|
|
346
442
|
};
|
|
347
443
|
|
|
348
|
-
function* handleResponseErrors(
|
|
444
|
+
function* handleResponseErrors(
|
|
445
|
+
nodeUids: string[],
|
|
446
|
+
volumeId: string,
|
|
447
|
+
responses: LinkResponse[] = [],
|
|
448
|
+
): Generator<NodeResult> {
|
|
349
449
|
const errors = new Map();
|
|
350
450
|
|
|
351
451
|
responses.forEach((response) => {
|
|
@@ -365,7 +465,12 @@ function* handleResponseErrors(nodeUids: string[], volumeId: string, responses:
|
|
|
365
465
|
}
|
|
366
466
|
}
|
|
367
467
|
|
|
368
|
-
function linkToEncryptedNode(
|
|
468
|
+
function linkToEncryptedNode(
|
|
469
|
+
logger: Logger,
|
|
470
|
+
volumeId: string,
|
|
471
|
+
link: PostLoadLinksMetadataResponse['Links'][0],
|
|
472
|
+
isAdmin: boolean,
|
|
473
|
+
): EncryptedNode {
|
|
369
474
|
const baseNodeMetadata = {
|
|
370
475
|
// Internal metadata
|
|
371
476
|
hash: link.Link.NameHash || undefined,
|
|
@@ -375,21 +480,23 @@ function linkToEncryptedNode(logger: Logger, volumeId: string, link: PostLoadLin
|
|
|
375
480
|
uid: makeNodeUid(volumeId, link.Link.LinkID),
|
|
376
481
|
parentUid: link.Link.ParentLinkID ? makeNodeUid(volumeId, link.Link.ParentLinkID) : undefined,
|
|
377
482
|
type: nodeTypeNumberToNodeType(logger, link.Link.Type),
|
|
378
|
-
creationTime: new Date(link.Link.CreateTime*1000),
|
|
379
|
-
trashTime: link.Link.TrashTime ? new Date(link.Link.TrashTime*1000) : undefined,
|
|
483
|
+
creationTime: new Date(link.Link.CreateTime * 1000),
|
|
484
|
+
trashTime: link.Link.TrashTime ? new Date(link.Link.TrashTime * 1000) : undefined,
|
|
380
485
|
|
|
381
486
|
// Sharing node metadata
|
|
382
487
|
shareId: link.Sharing?.ShareID || undefined,
|
|
383
488
|
isShared: !!link.Sharing,
|
|
384
|
-
directMemberRole: isAdmin
|
|
385
|
-
|
|
489
|
+
directMemberRole: isAdmin
|
|
490
|
+
? MemberRole.Admin
|
|
491
|
+
: permissionsToDirectMemberRole(logger, link.Membership?.Permissions),
|
|
492
|
+
};
|
|
386
493
|
const baseCryptoNodeMetadata = {
|
|
387
494
|
signatureEmail: link.Link.SignatureEmail || undefined,
|
|
388
495
|
nameSignatureEmail: link.Link.NameSignatureEmail || undefined,
|
|
389
496
|
armoredKey: link.Link.NodeKey,
|
|
390
497
|
armoredNodePassphrase: link.Link.NodePassphrase,
|
|
391
498
|
armoredNodePassphraseSignature: link.Link.NodePassphraseSignature,
|
|
392
|
-
}
|
|
499
|
+
};
|
|
393
500
|
|
|
394
501
|
if (link.Link.Type === 1 && link.Folder) {
|
|
395
502
|
return {
|
|
@@ -401,7 +508,7 @@ function linkToEncryptedNode(logger: Logger, volumeId: string, link: PostLoadLin
|
|
|
401
508
|
armoredHashKey: link.Folder.NodeHashKey as string,
|
|
402
509
|
},
|
|
403
510
|
},
|
|
404
|
-
}
|
|
511
|
+
};
|
|
405
512
|
}
|
|
406
513
|
|
|
407
514
|
if (link.Link.Type === 2 && link.File && link.File.ActiveRevision) {
|
|
@@ -418,14 +525,17 @@ function linkToEncryptedNode(logger: Logger, volumeId: string, link: PostLoadLin
|
|
|
418
525
|
activeRevision: {
|
|
419
526
|
uid: makeNodeRevisionUid(volumeId, link.Link.LinkID, link.File.ActiveRevision.RevisionID),
|
|
420
527
|
state: RevisionState.Active,
|
|
421
|
-
creationTime: new Date(link.File.ActiveRevision.CreateTime*1000),
|
|
528
|
+
creationTime: new Date(link.File.ActiveRevision.CreateTime * 1000),
|
|
422
529
|
storageSize: link.File.ActiveRevision.EncryptedSize,
|
|
423
530
|
signatureEmail: link.File.ActiveRevision.SignatureEmail || undefined,
|
|
424
531
|
armoredExtendedAttributes: link.File.ActiveRevision.XAttr || undefined,
|
|
425
|
-
thumbnails:
|
|
532
|
+
thumbnails:
|
|
533
|
+
link.File.ActiveRevision.Thumbnails?.map((thumbnail) =>
|
|
534
|
+
transformThumbnail(volumeId, link.Link.LinkID, thumbnail),
|
|
535
|
+
) || [],
|
|
426
536
|
},
|
|
427
537
|
},
|
|
428
|
-
}
|
|
538
|
+
};
|
|
429
539
|
}
|
|
430
540
|
|
|
431
541
|
if (link.Link.Type === 3) {
|
|
@@ -434,7 +544,7 @@ function linkToEncryptedNode(logger: Logger, volumeId: string, link: PostLoadLin
|
|
|
434
544
|
encryptedCrypto: {
|
|
435
545
|
...baseCryptoNodeMetadata,
|
|
436
546
|
},
|
|
437
|
-
}
|
|
547
|
+
};
|
|
438
548
|
}
|
|
439
549
|
|
|
440
550
|
throw new Error(`Unknown node type: ${link.Link.Type}`);
|
|
@@ -449,19 +559,23 @@ function transformRevisionResponse(
|
|
|
449
559
|
uid: makeNodeRevisionUid(volumeId, nodeId, revision.ID),
|
|
450
560
|
state: revision.State === APIRevisionState.Active ? RevisionState.Active : RevisionState.Superseded,
|
|
451
561
|
// @ts-expect-error: API doc is wrong, CreateTime is not optional.
|
|
452
|
-
creationTime: new Date(revision.CreateTime*1000),
|
|
562
|
+
creationTime: new Date(revision.CreateTime * 1000),
|
|
453
563
|
storageSize: revision.Size,
|
|
454
564
|
signatureEmail: revision.SignatureEmail || undefined,
|
|
455
565
|
armoredExtendedAttributes: revision.XAttr || undefined,
|
|
456
566
|
thumbnails: revision.Thumbnails?.map((thumbnail) => transformThumbnail(volumeId, nodeId, thumbnail)) || [],
|
|
457
|
-
}
|
|
567
|
+
};
|
|
458
568
|
}
|
|
459
569
|
|
|
460
|
-
function transformThumbnail(
|
|
570
|
+
function transformThumbnail(
|
|
571
|
+
volumeId: string,
|
|
572
|
+
nodeId: string,
|
|
573
|
+
thumbnail: { ThumbnailID: string | null; Type: 1 | 2 | 3 },
|
|
574
|
+
): Thumbnail {
|
|
461
575
|
return {
|
|
462
576
|
// TODO: Legacy thumbnails didn't have ID but we don't have them anymore. Remove typing once API doc is updated.
|
|
463
577
|
uid: makeNodeThumbnailUid(volumeId, nodeId, thumbnail.ThumbnailID as string),
|
|
464
578
|
// TODO: We don't support any other thumbnail type yet.
|
|
465
579
|
type: thumbnail.Type as 1 | 2,
|
|
466
|
-
}
|
|
580
|
+
};
|
|
467
581
|
}
|