@protontech/drive-sdk 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (447) hide show
  1. package/dist/cache/memoryCache.js +0 -1
  2. package/dist/cache/memoryCache.js.map +1 -1
  3. package/dist/cache/memoryCache.test.js +2 -4
  4. package/dist/cache/memoryCache.test.js.map +1 -1
  5. package/dist/cache/nullCache.js +0 -1
  6. package/dist/cache/nullCache.js.map +1 -1
  7. package/dist/crypto/driveCrypto.d.ts +2 -5
  8. package/dist/crypto/driveCrypto.js +7 -12
  9. package/dist/crypto/driveCrypto.js.map +1 -1
  10. package/dist/crypto/driveCrypto.test.js +14 -14
  11. package/dist/crypto/openPGPCrypto.js +3 -3
  12. package/dist/crypto/openPGPCrypto.js.map +1 -1
  13. package/dist/diagnostic/eventsGenerator.js +1 -1
  14. package/dist/diagnostic/eventsGenerator.js.map +1 -1
  15. package/dist/diagnostic/httpClient.d.ts +1 -1
  16. package/dist/diagnostic/httpClient.js.map +1 -1
  17. package/dist/diagnostic/index.d.ts +3 -3
  18. package/dist/diagnostic/index.js.map +1 -1
  19. package/dist/diagnostic/integrityVerificationStream.js +1 -1
  20. package/dist/diagnostic/integrityVerificationStream.js.map +1 -1
  21. package/dist/diagnostic/interface.d.ts +2 -2
  22. package/dist/diagnostic/sdkDiagnostic.d.ts +3 -3
  23. package/dist/diagnostic/sdkDiagnostic.js +8 -2
  24. package/dist/diagnostic/sdkDiagnostic.js.map +1 -1
  25. package/dist/diagnostic/sdkDiagnosticFull.d.ts +4 -4
  26. package/dist/diagnostic/sdkDiagnosticFull.js.map +1 -1
  27. package/dist/diagnostic/telemetry.js.map +1 -1
  28. package/dist/diagnostic/zipGenerators.js +2 -2
  29. package/dist/diagnostic/zipGenerators.js.map +1 -1
  30. package/dist/diagnostic/zipGenerators.test.js +1 -1
  31. package/dist/diagnostic/zipGenerators.test.js.map +1 -1
  32. package/dist/interface/events.d.ts +2 -4
  33. package/dist/interface/events.js.map +1 -1
  34. package/dist/interface/index.d.ts +5 -5
  35. package/dist/interface/index.js +0 -1
  36. package/dist/interface/index.js.map +1 -1
  37. package/dist/interface/result.js.map +1 -1
  38. package/dist/interface/sharing.d.ts +1 -0
  39. package/dist/interface/sharing.js.map +1 -1
  40. package/dist/interface/telemetry.js +0 -8
  41. package/dist/interface/telemetry.js.map +1 -1
  42. package/dist/interface/thumbnail.js.map +1 -1
  43. package/dist/interface/upload.d.ts +1 -1
  44. package/dist/internal/apiService/apiService.d.ts +1 -1
  45. package/dist/internal/apiService/apiService.js +7 -11
  46. package/dist/internal/apiService/apiService.js.map +1 -1
  47. package/dist/internal/apiService/apiService.test.js +55 -48
  48. package/dist/internal/apiService/apiService.test.js.map +1 -1
  49. package/dist/internal/apiService/coreTypes.d.ts +2356 -2356
  50. package/dist/internal/apiService/driveTypes.d.ts +1680 -1680
  51. package/dist/internal/apiService/errors.js +14 -8
  52. package/dist/internal/apiService/errors.js.map +1 -1
  53. package/dist/internal/apiService/errors.test.js +17 -12
  54. package/dist/internal/apiService/errors.test.js.map +1 -1
  55. package/dist/internal/apiService/transformers.d.ts +1 -1
  56. package/dist/internal/apiService/transformers.js +1 -1
  57. package/dist/internal/asyncIteratorMap.test.js +2 -2
  58. package/dist/internal/asyncIteratorMap.test.js.map +1 -1
  59. package/dist/internal/asyncIteratorRace.d.ts +13 -0
  60. package/dist/internal/asyncIteratorRace.js +59 -0
  61. package/dist/internal/asyncIteratorRace.js.map +1 -0
  62. package/dist/internal/asyncIteratorRace.test.d.ts +1 -0
  63. package/dist/internal/asyncIteratorRace.test.js +119 -0
  64. package/dist/internal/asyncIteratorRace.test.js.map +1 -0
  65. package/dist/internal/batch.d.ts +1 -0
  66. package/dist/internal/batch.js +12 -0
  67. package/dist/internal/batch.js.map +1 -0
  68. package/dist/internal/batch.test.d.ts +1 -0
  69. package/dist/internal/batch.test.js +41 -0
  70. package/dist/internal/batch.test.js.map +1 -0
  71. package/dist/internal/batchLoading.js.map +1 -1
  72. package/dist/internal/batchLoading.test.js +13 -13
  73. package/dist/internal/batchLoading.test.js.map +1 -1
  74. package/dist/internal/devices/apiService.d.ts +3 -3
  75. package/dist/internal/devices/apiService.js +2 -2
  76. package/dist/internal/devices/apiService.js.map +1 -1
  77. package/dist/internal/devices/cryptoService.js +1 -2
  78. package/dist/internal/devices/cryptoService.js.map +1 -1
  79. package/dist/internal/devices/index.d.ts +5 -5
  80. package/dist/internal/devices/index.js.map +1 -1
  81. package/dist/internal/devices/interface.d.ts +3 -3
  82. package/dist/internal/devices/manager.js +2 -2
  83. package/dist/internal/devices/manager.js.map +1 -1
  84. package/dist/internal/devices/manager.test.js +38 -7
  85. package/dist/internal/devices/manager.test.js.map +1 -1
  86. package/dist/internal/download/apiService.d.ts +4 -4
  87. package/dist/internal/download/apiService.js +0 -1
  88. package/dist/internal/download/apiService.js.map +1 -1
  89. package/dist/internal/download/cryptoService.d.ts +4 -4
  90. package/dist/internal/download/cryptoService.js +6 -5
  91. package/dist/internal/download/cryptoService.js.map +1 -1
  92. package/dist/internal/download/fileDownloader.d.ts +4 -4
  93. package/dist/internal/download/fileDownloader.js +3 -2
  94. package/dist/internal/download/fileDownloader.js.map +1 -1
  95. package/dist/internal/download/fileDownloader.test.js +1 -1
  96. package/dist/internal/download/fileDownloader.test.js.map +1 -1
  97. package/dist/internal/download/index.d.ts +5 -5
  98. package/dist/internal/download/index.js +5 -5
  99. package/dist/internal/download/index.js.map +1 -1
  100. package/dist/internal/download/interface.d.ts +3 -4
  101. package/dist/internal/download/telemetry.d.ts +3 -3
  102. package/dist/internal/download/telemetry.js +4 -2
  103. package/dist/internal/download/telemetry.js.map +1 -1
  104. package/dist/internal/download/telemetry.test.js +8 -8
  105. package/dist/internal/download/telemetry.test.js.map +1 -1
  106. package/dist/internal/download/thumbnailDownloader.d.ts +4 -4
  107. package/dist/internal/download/thumbnailDownloader.js +6 -6
  108. package/dist/internal/download/thumbnailDownloader.js.map +1 -1
  109. package/dist/internal/download/thumbnailDownloader.test.js.map +1 -1
  110. package/dist/internal/errors.d.ts +1 -1
  111. package/dist/internal/errors.js +1 -3
  112. package/dist/internal/errors.js.map +1 -1
  113. package/dist/internal/events/apiService.d.ts +2 -2
  114. package/dist/internal/events/apiService.js +9 -5
  115. package/dist/internal/events/apiService.js.map +1 -1
  116. package/dist/internal/events/coreEventManager.d.ts +3 -3
  117. package/dist/internal/events/coreEventManager.js.map +1 -1
  118. package/dist/internal/events/coreEventManager.test.js +14 -14
  119. package/dist/internal/events/eventManager.d.ts +1 -1
  120. package/dist/internal/events/eventManager.js +0 -1
  121. package/dist/internal/events/eventManager.js.map +1 -1
  122. package/dist/internal/events/eventManager.test.js +34 -25
  123. package/dist/internal/events/eventManager.test.js.map +1 -1
  124. package/dist/internal/events/index.d.ts +6 -6
  125. package/dist/internal/events/index.js.map +1 -1
  126. package/dist/internal/events/interface.d.ts +1 -1
  127. package/dist/internal/events/interface.js +0 -1
  128. package/dist/internal/events/interface.js.map +1 -1
  129. package/dist/internal/events/volumeEventManager.d.ts +3 -3
  130. package/dist/internal/events/volumeEventManager.js.map +1 -1
  131. package/dist/internal/events/volumeEventManager.test.js +55 -55
  132. package/dist/internal/events/volumeEventManager.test.js.map +1 -1
  133. package/dist/internal/nodes/apiService.d.ts +4 -3
  134. package/dist/internal/nodes/apiService.js +36 -15
  135. package/dist/internal/nodes/apiService.js.map +1 -1
  136. package/dist/internal/nodes/apiService.test.js +60 -41
  137. package/dist/internal/nodes/apiService.test.js.map +1 -1
  138. package/dist/internal/nodes/cache.d.ts +5 -5
  139. package/dist/internal/nodes/cache.js +14 -7
  140. package/dist/internal/nodes/cache.js.map +1 -1
  141. package/dist/internal/nodes/cache.test.js +31 -9
  142. package/dist/internal/nodes/cache.test.js.map +1 -1
  143. package/dist/internal/nodes/cryptoCache.d.ts +2 -2
  144. package/dist/internal/nodes/cryptoCache.js.map +1 -1
  145. package/dist/internal/nodes/cryptoCache.test.js +24 -4
  146. package/dist/internal/nodes/cryptoCache.test.js.map +1 -1
  147. package/dist/internal/nodes/cryptoService.d.ts +3 -3
  148. package/dist/internal/nodes/cryptoService.js +11 -17
  149. package/dist/internal/nodes/cryptoService.js.map +1 -1
  150. package/dist/internal/nodes/cryptoService.test.js +320 -241
  151. package/dist/internal/nodes/cryptoService.test.js.map +1 -1
  152. package/dist/internal/nodes/events.d.ts +3 -3
  153. package/dist/internal/nodes/events.js.map +1 -1
  154. package/dist/internal/nodes/events.test.js +27 -21
  155. package/dist/internal/nodes/events.test.js.map +1 -1
  156. package/dist/internal/nodes/extendedAttributes.d.ts +1 -1
  157. package/dist/internal/nodes/extendedAttributes.js +3 -1
  158. package/dist/internal/nodes/extendedAttributes.js.map +1 -1
  159. package/dist/internal/nodes/extendedAttributes.test.js +7 -10
  160. package/dist/internal/nodes/extendedAttributes.test.js.map +1 -1
  161. package/dist/internal/nodes/index.d.ts +10 -10
  162. package/dist/internal/nodes/index.js.map +1 -1
  163. package/dist/internal/nodes/index.test.d.ts +1 -0
  164. package/dist/internal/nodes/index.test.js +106 -0
  165. package/dist/internal/nodes/index.test.js.map +1 -0
  166. package/dist/internal/nodes/interface.d.ts +2 -2
  167. package/dist/internal/nodes/nodesAccess.d.ts +7 -7
  168. package/dist/internal/nodes/nodesAccess.js +28 -16
  169. package/dist/internal/nodes/nodesAccess.js.map +1 -1
  170. package/dist/internal/nodes/nodesAccess.test.js +39 -13
  171. package/dist/internal/nodes/nodesAccess.test.js.map +1 -1
  172. package/dist/internal/nodes/nodesManagement.d.ts +6 -6
  173. package/dist/internal/nodes/nodesManagement.js +9 -7
  174. package/dist/internal/nodes/nodesManagement.js.map +1 -1
  175. package/dist/internal/nodes/nodesManagement.test.js +9 -9
  176. package/dist/internal/nodes/nodesManagement.test.js.map +1 -1
  177. package/dist/internal/nodes/nodesRevisions.d.ts +4 -4
  178. package/dist/internal/nodes/nodesRevisions.js.map +1 -1
  179. package/dist/internal/photos/albums.d.ts +3 -3
  180. package/dist/internal/photos/albums.js.map +1 -1
  181. package/dist/internal/photos/apiService.d.ts +1 -1
  182. package/dist/internal/photos/apiService.js +3 -6
  183. package/dist/internal/photos/apiService.js.map +1 -1
  184. package/dist/internal/photos/cache.d.ts +1 -1
  185. package/dist/internal/photos/index.d.ts +5 -5
  186. package/dist/internal/photos/index.js.map +1 -1
  187. package/dist/internal/photos/interface.d.ts +2 -2
  188. package/dist/internal/photos/photosTimeline.d.ts +3 -3
  189. package/dist/internal/photos/photosTimeline.js +1 -2
  190. package/dist/internal/photos/photosTimeline.js.map +1 -1
  191. package/dist/internal/sdkEvents.d.ts +1 -1
  192. package/dist/internal/sdkEvents.js +2 -7
  193. package/dist/internal/sdkEvents.js.map +1 -1
  194. package/dist/internal/sdkEvents.test.js +8 -8
  195. package/dist/internal/shares/apiService.d.ts +2 -2
  196. package/dist/internal/shares/apiService.js +5 -3
  197. package/dist/internal/shares/apiService.js.map +1 -1
  198. package/dist/internal/shares/cache.d.ts +2 -2
  199. package/dist/internal/shares/cache.js +12 -6
  200. package/dist/internal/shares/cache.js.map +1 -1
  201. package/dist/internal/shares/cache.test.js.map +1 -1
  202. package/dist/internal/shares/cryptoCache.d.ts +2 -2
  203. package/dist/internal/shares/cryptoCache.test.js +8 -2
  204. package/dist/internal/shares/cryptoCache.test.js.map +1 -1
  205. package/dist/internal/shares/cryptoService.d.ts +3 -3
  206. package/dist/internal/shares/cryptoService.js.map +1 -1
  207. package/dist/internal/shares/cryptoService.test.js +42 -42
  208. package/dist/internal/shares/cryptoService.test.js.map +1 -1
  209. package/dist/internal/shares/index.d.ts +4 -4
  210. package/dist/internal/shares/index.js.map +1 -1
  211. package/dist/internal/shares/interface.d.ts +2 -2
  212. package/dist/internal/shares/manager.d.ts +7 -7
  213. package/dist/internal/shares/manager.js.map +1 -1
  214. package/dist/internal/shares/manager.test.js +71 -63
  215. package/dist/internal/shares/manager.test.js.map +1 -1
  216. package/dist/internal/sharing/apiService.d.ts +4 -4
  217. package/dist/internal/sharing/apiService.js +4 -3
  218. package/dist/internal/sharing/apiService.js.map +1 -1
  219. package/dist/internal/sharing/cache.d.ts +1 -1
  220. package/dist/internal/sharing/cache.test.js +33 -33
  221. package/dist/internal/sharing/cryptoService.d.ts +3 -3
  222. package/dist/internal/sharing/cryptoService.js +3 -5
  223. package/dist/internal/sharing/cryptoService.js.map +1 -1
  224. package/dist/internal/sharing/cryptoService.test.js +39 -39
  225. package/dist/internal/sharing/cryptoService.test.js.map +1 -1
  226. package/dist/internal/sharing/events.d.ts +4 -4
  227. package/dist/internal/sharing/events.js +0 -1
  228. package/dist/internal/sharing/events.js.map +1 -1
  229. package/dist/internal/sharing/events.test.js +39 -40
  230. package/dist/internal/sharing/events.test.js.map +1 -1
  231. package/dist/internal/sharing/index.d.ts +6 -6
  232. package/dist/internal/sharing/index.js.map +1 -1
  233. package/dist/internal/sharing/interface.d.ts +5 -4
  234. package/dist/internal/sharing/sharingAccess.d.ts +6 -6
  235. package/dist/internal/sharing/sharingAccess.js +8 -4
  236. package/dist/internal/sharing/sharingAccess.js.map +1 -1
  237. package/dist/internal/sharing/sharingAccess.test.js +45 -39
  238. package/dist/internal/sharing/sharingAccess.test.js.map +1 -1
  239. package/dist/internal/sharing/sharingManagement.d.ts +4 -4
  240. package/dist/internal/sharing/sharingManagement.js +5 -7
  241. package/dist/internal/sharing/sharingManagement.js.map +1 -1
  242. package/dist/internal/sharing/sharingManagement.test.js +297 -248
  243. package/dist/internal/sharing/sharingManagement.test.js.map +1 -1
  244. package/dist/internal/uids.js.map +1 -1
  245. package/dist/internal/upload/apiService.d.ts +3 -3
  246. package/dist/internal/upload/apiService.js +1 -1
  247. package/dist/internal/upload/apiService.js.map +1 -1
  248. package/dist/internal/upload/blockVerifier.d.ts +3 -3
  249. package/dist/internal/upload/blockVerifier.js +1 -1
  250. package/dist/internal/upload/blockVerifier.js.map +1 -1
  251. package/dist/internal/upload/chunkStreamReader.test.js +6 -6
  252. package/dist/internal/upload/cryptoService.d.ts +4 -4
  253. package/dist/internal/upload/cryptoService.js +4 -4
  254. package/dist/internal/upload/cryptoService.js.map +1 -1
  255. package/dist/internal/upload/digests.js.map +1 -1
  256. package/dist/internal/upload/fileUploader.d.ts +6 -6
  257. package/dist/internal/upload/fileUploader.js.map +1 -1
  258. package/dist/internal/upload/fileUploader.test.js.map +1 -1
  259. package/dist/internal/upload/index.d.ts +5 -5
  260. package/dist/internal/upload/index.js.map +1 -1
  261. package/dist/internal/upload/interface.d.ts +3 -3
  262. package/dist/internal/upload/manager.d.ts +4 -4
  263. package/dist/internal/upload/manager.js +7 -5
  264. package/dist/internal/upload/manager.js.map +1 -1
  265. package/dist/internal/upload/manager.test.js +137 -123
  266. package/dist/internal/upload/manager.test.js.map +1 -1
  267. package/dist/internal/upload/streamUploader.d.ts +6 -6
  268. package/dist/internal/upload/streamUploader.js +8 -6
  269. package/dist/internal/upload/streamUploader.js.map +1 -1
  270. package/dist/internal/upload/streamUploader.test.js +16 -11
  271. package/dist/internal/upload/streamUploader.test.js.map +1 -1
  272. package/dist/internal/upload/telemetry.d.ts +3 -3
  273. package/dist/internal/upload/telemetry.js +5 -3
  274. package/dist/internal/upload/telemetry.js.map +1 -1
  275. package/dist/internal/upload/telemetry.test.js +8 -8
  276. package/dist/internal/upload/telemetry.test.js.map +1 -1
  277. package/dist/protonDriveClient.d.ts +8 -8
  278. package/dist/protonDriveClient.js +12 -9
  279. package/dist/protonDriveClient.js.map +1 -1
  280. package/dist/protonDrivePhotosClient.js.map +1 -1
  281. package/dist/telemetry.js +18 -15
  282. package/dist/telemetry.js.map +1 -1
  283. package/dist/tests/logger.js.map +1 -1
  284. package/dist/tests/telemetry.d.ts +1 -1
  285. package/dist/transformers.js +4 -2
  286. package/dist/transformers.js.map +1 -1
  287. package/package.json +1 -1
  288. package/src/cache/interface.ts +22 -22
  289. package/src/cache/memoryCache.test.ts +7 -7
  290. package/src/cache/memoryCache.ts +4 -4
  291. package/src/cache/nullCache.ts +1 -1
  292. package/src/config.ts +5 -5
  293. package/src/crypto/driveCrypto.test.ts +15 -15
  294. package/src/crypto/driveCrypto.ts +120 -156
  295. package/src/crypto/hmac.ts +1 -1
  296. package/src/crypto/interface.ts +63 -72
  297. package/src/crypto/openPGPCrypto.ts +74 -94
  298. package/src/crypto/utils.ts +1 -1
  299. package/src/diagnostic/eventsGenerator.ts +2 -2
  300. package/src/diagnostic/httpClient.ts +6 -2
  301. package/src/diagnostic/index.ts +12 -10
  302. package/src/diagnostic/integrityVerificationStream.ts +3 -4
  303. package/src/diagnostic/interface.ts +81 -81
  304. package/src/diagnostic/sdkDiagnostic.ts +35 -24
  305. package/src/diagnostic/sdkDiagnosticFull.ts +16 -19
  306. package/src/diagnostic/telemetry.ts +4 -1
  307. package/src/diagnostic/zipGenerators.test.ts +1 -1
  308. package/src/diagnostic/zipGenerators.ts +3 -3
  309. package/src/errors.ts +21 -21
  310. package/src/index.ts +3 -3
  311. package/src/interface/account.ts +10 -10
  312. package/src/interface/author.ts +6 -6
  313. package/src/interface/config.ts +4 -4
  314. package/src/interface/devices.ts +6 -6
  315. package/src/interface/download.ts +12 -9
  316. package/src/interface/events.ts +45 -39
  317. package/src/interface/httpClient.ts +11 -11
  318. package/src/interface/index.ts +76 -19
  319. package/src/interface/nodes.ts +47 -49
  320. package/src/interface/result.ts +1 -3
  321. package/src/interface/sharing.ts +60 -57
  322. package/src/interface/telemetry.ts +74 -74
  323. package/src/interface/thumbnail.ts +5 -6
  324. package/src/interface/upload.ts +20 -12
  325. package/src/internal/apiService/apiService.test.ts +109 -76
  326. package/src/internal/apiService/apiService.ts +40 -26
  327. package/src/internal/apiService/coreTypes.ts +2474 -2463
  328. package/src/internal/apiService/driveTypes.ts +1868 -1822
  329. package/src/internal/apiService/errorCodes.ts +4 -4
  330. package/src/internal/apiService/errors.test.ts +25 -23
  331. package/src/internal/apiService/errors.ts +15 -9
  332. package/src/internal/apiService/index.ts +1 -1
  333. package/src/internal/apiService/transformers.ts +2 -2
  334. package/src/internal/asyncIteratorMap.test.ts +4 -4
  335. package/src/internal/asyncIteratorMap.ts +1 -1
  336. package/src/internal/asyncIteratorRace.test.ts +149 -0
  337. package/src/internal/asyncIteratorRace.ts +79 -0
  338. package/src/internal/batch.test.ts +50 -0
  339. package/src/internal/batch.ts +9 -0
  340. package/src/internal/batchLoading.test.ts +13 -14
  341. package/src/internal/batchLoading.ts +8 -8
  342. package/src/internal/devices/apiService.ts +58 -51
  343. package/src/internal/devices/cryptoService.ts +22 -17
  344. package/src/internal/devices/index.ts +17 -10
  345. package/src/internal/devices/interface.ts +21 -12
  346. package/src/internal/devices/manager.test.ts +40 -9
  347. package/src/internal/devices/manager.ts +3 -3
  348. package/src/internal/download/apiService.ts +66 -49
  349. package/src/internal/download/cryptoService.ts +34 -18
  350. package/src/internal/download/fileDownloader.test.ts +25 -9
  351. package/src/internal/download/fileDownloader.ts +36 -18
  352. package/src/internal/download/index.ts +19 -19
  353. package/src/internal/download/interface.ts +19 -20
  354. package/src/internal/download/queue.ts +3 -3
  355. package/src/internal/download/telemetry.test.ts +11 -11
  356. package/src/internal/download/telemetry.ts +24 -14
  357. package/src/internal/download/thumbnailDownloader.test.ts +11 -6
  358. package/src/internal/download/thumbnailDownloader.ts +43 -32
  359. package/src/internal/errors.ts +7 -5
  360. package/src/internal/events/apiService.ts +30 -17
  361. package/src/internal/events/coreEventManager.test.ts +18 -18
  362. package/src/internal/events/coreEventManager.ts +9 -6
  363. package/src/internal/events/eventManager.test.ts +51 -46
  364. package/src/internal/events/eventManager.ts +6 -5
  365. package/src/internal/events/index.ts +24 -14
  366. package/src/internal/events/interface.ts +47 -39
  367. package/src/internal/events/volumeEventManager.test.ts +61 -65
  368. package/src/internal/events/volumeEventManager.ts +18 -9
  369. package/src/internal/nodes/apiService.test.ts +197 -147
  370. package/src/internal/nodes/apiService.ts +288 -174
  371. package/src/internal/nodes/cache.test.ts +48 -20
  372. package/src/internal/nodes/cache.ts +60 -44
  373. package/src/internal/nodes/cryptoCache.test.ts +34 -14
  374. package/src/internal/nodes/cryptoCache.ts +10 -5
  375. package/src/internal/nodes/cryptoService.test.ts +492 -351
  376. package/src/internal/nodes/cryptoService.ts +170 -88
  377. package/src/internal/nodes/events.test.ts +38 -28
  378. package/src/internal/nodes/events.ts +7 -5
  379. package/src/internal/nodes/extendedAttributes.test.ts +28 -24
  380. package/src/internal/nodes/extendedAttributes.ts +20 -15
  381. package/src/internal/nodes/index.test.ts +133 -0
  382. package/src/internal/nodes/index.ts +27 -15
  383. package/src/internal/nodes/interface.ts +42 -29
  384. package/src/internal/nodes/nodesAccess.test.ts +124 -58
  385. package/src/internal/nodes/nodesAccess.ts +73 -49
  386. package/src/internal/nodes/nodesManagement.test.ts +32 -31
  387. package/src/internal/nodes/nodesManagement.ts +39 -32
  388. package/src/internal/nodes/nodesRevisions.ts +7 -7
  389. package/src/internal/nodes/validations.ts +2 -2
  390. package/src/internal/photos/albums.ts +5 -5
  391. package/src/internal/photos/apiService.ts +4 -7
  392. package/src/internal/photos/cache.ts +1 -1
  393. package/src/internal/photos/index.ts +8 -8
  394. package/src/internal/photos/interface.ts +2 -2
  395. package/src/internal/photos/photosTimeline.ts +4 -5
  396. package/src/internal/sdkEvents.test.ts +10 -10
  397. package/src/internal/sdkEvents.ts +5 -13
  398. package/src/internal/shares/apiService.ts +44 -33
  399. package/src/internal/shares/cache.test.ts +6 -4
  400. package/src/internal/shares/cache.ts +21 -12
  401. package/src/internal/shares/cryptoCache.test.ts +17 -11
  402. package/src/internal/shares/cryptoCache.ts +4 -4
  403. package/src/internal/shares/cryptoService.test.ts +72 -74
  404. package/src/internal/shares/cryptoService.ts +48 -23
  405. package/src/internal/shares/index.ts +23 -11
  406. package/src/internal/shares/interface.ts +8 -8
  407. package/src/internal/shares/manager.test.ts +88 -80
  408. package/src/internal/shares/manager.ts +19 -19
  409. package/src/internal/sharing/apiService.ts +282 -175
  410. package/src/internal/sharing/cache.test.ts +35 -35
  411. package/src/internal/sharing/cache.ts +2 -2
  412. package/src/internal/sharing/cryptoService.test.ts +58 -46
  413. package/src/internal/sharing/cryptoService.ts +121 -84
  414. package/src/internal/sharing/events.test.ts +45 -49
  415. package/src/internal/sharing/events.ts +9 -6
  416. package/src/internal/sharing/index.ts +22 -11
  417. package/src/internal/sharing/interface.ts +40 -40
  418. package/src/internal/sharing/sharingAccess.test.ts +71 -65
  419. package/src/internal/sharing/sharingAccess.ts +39 -21
  420. package/src/internal/sharing/sharingManagement.test.ts +398 -298
  421. package/src/internal/sharing/sharingManagement.ts +138 -65
  422. package/src/internal/uids.ts +1 -1
  423. package/src/internal/upload/apiService.ts +167 -117
  424. package/src/internal/upload/blockVerifier.ts +8 -6
  425. package/src/internal/upload/chunkStreamReader.test.ts +7 -7
  426. package/src/internal/upload/cryptoService.ts +42 -36
  427. package/src/internal/upload/digests.ts +2 -2
  428. package/src/internal/upload/fileUploader.test.ts +15 -3
  429. package/src/internal/upload/fileUploader.ts +39 -17
  430. package/src/internal/upload/index.ts +13 -14
  431. package/src/internal/upload/interface.ts +78 -78
  432. package/src/internal/upload/manager.test.ts +170 -153
  433. package/src/internal/upload/manager.ts +59 -35
  434. package/src/internal/upload/queue.ts +3 -3
  435. package/src/internal/upload/streamUploader.test.ts +40 -26
  436. package/src/internal/upload/streamUploader.ts +87 -69
  437. package/src/internal/upload/telemetry.test.ts +11 -11
  438. package/src/internal/upload/telemetry.ts +25 -15
  439. package/src/internal/wait.test.ts +1 -1
  440. package/src/internal/wait.ts +3 -3
  441. package/src/protonDriveClient.ts +121 -39
  442. package/src/protonDrivePhotosClient.ts +16 -10
  443. package/src/telemetry.ts +60 -52
  444. package/src/tests/logger.ts +1 -1
  445. package/src/tests/telemetry.ts +2 -2
  446. package/src/transformers.ts +27 -21
  447. package/src/version.ts +0 -1
@@ -1,57 +1,108 @@
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 { DriveAPIService, drivePaths, isCodeOk, nodeTypeNumberToNodeType, permissionsToDirectMemberRole } from "../apiService";
7
- import { splitNodeUid, makeNodeUid, makeNodeRevisionUid, splitNodeRevisionUid, makeNodeThumbnailUid } from "../uids";
8
- import { EncryptedNode, EncryptedRevision, Thumbnail } from "./interface";
9
-
10
- type PostLoadLinksMetadataRequest = Extract<drivePaths['/drive/v2/volumes/{volumeID}/links']['post']['requestBody'], { 'content': object }>['content']['application/json'];
11
- type PostLoadLinksMetadataResponse = drivePaths['/drive/v2/volumes/{volumeID}/links']['post']['responses']['200']['content']['application/json'];
12
-
13
- type GetChildrenResponse = drivePaths['/drive/v2/volumes/{volumeID}/folders/{linkID}/children']['get']['responses']['200']['content']['application/json'];
14
-
15
- type GetTrashedNodesResponse = drivePaths['/drive/volumes/{volumeID}/trash']['get']['responses']['200']['content']['application/json'];
16
-
17
- type PutRenameNodeRequest = Extract<drivePaths['/drive/v2/volumes/{volumeID}/links/{linkID}/rename']['put']['requestBody'], { 'content': object }>['content']['application/json'];
18
- type PutRenameNodeResponse = drivePaths['/drive/v2/volumes/{volumeID}/links/{linkID}/rename']['put']['responses']['200']['content']['application/json'];
19
-
20
- type PutMoveNodeRequest = Extract<drivePaths['/drive/v2/volumes/{volumeID}/links/{linkID}/move']['put']['requestBody'], { 'content': object }>['content']['application/json'];
21
- type PutMoveNodeResponse = drivePaths['/drive/v2/volumes/{volumeID}/links/{linkID}/move']['put']['responses']['200']['content']['application/json'];
22
-
23
- type PostTrashNodesRequest = Extract<drivePaths['/drive/v2/volumes/{volumeID}/trash_multiple']['post']['requestBody'], { 'content': object }>['content']['application/json'];
24
- type PostTrashNodesResponse = drivePaths['/drive/v2/volumes/{volumeID}/trash_multiple']['post']['responses']['200']['content']['application/json'];
25
-
26
- type PutRestoreNodesRequest = Extract<drivePaths['/drive/v2/volumes/{volumeID}/trash/restore_multiple']['put']['requestBody'], { 'content': object }>['content']['application/json'];
27
- type PutRestoreNodesResponse = drivePaths['/drive/v2/volumes/{volumeID}/trash/restore_multiple']['put']['responses']['200']['content']['application/json'];
28
-
29
- type PostDeleteNodesRequest = Extract<drivePaths['/drive/v2/volumes/{volumeID}/trash/delete_multiple']['post']['requestBody'], { 'content': object }>['content']['application/json'];
30
- type PostDeleteNodesResponse = drivePaths['/drive/v2/volumes/{volumeID}/trash/delete_multiple']['post']['responses']['200']['content']['application/json'];
31
-
32
- type PostCreateFolderRequest = Extract<drivePaths['/drive/v2/volumes/{volumeID}/folders']['post']['requestBody'], { 'content': object }>['content']['application/json'];
33
- type PostCreateFolderResponse = drivePaths['/drive/v2/volumes/{volumeID}/folders']['post']['responses']['200']['content']['application/json'];
34
-
35
- type GetRevisionResponse = drivePaths['/drive/v2/volumes/{volumeID}/files/{linkID}/revisions/{revisionID}']['get']['responses']['200']['content']['application/json'];
36
- type GetRevisionsResponse = drivePaths['/drive/v2/volumes/{volumeID}/files/{linkID}/revisions']['get']['responses']['200']['content']['application/json'];
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 = drivePaths['/drive/v2/volumes/{volumeID}/files/{linkID}/revisions/{revisionID}/restore']['post']['responses']['202']['content']['application/json'];
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 = drivePaths['/drive/v2/volumes/{volumeID}/files/{linkID}/revisions/{revisionID}']['delete']['responses']['200']['content']['application/json'];
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(private logger: Logger, private apiService: DriveAPIService) {
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("finish");
113
+ await nodesGenerator.return('finish');
63
114
  return result.value;
64
115
  }
65
116
 
66
- // Improvement requested: split into multiple calls for many nodes.
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
- for (const [volumeId, nodeIds] of nodeIdsByVolumeId.entries()) {
84
- const isAdmin = volumeId === ownVolumeId;
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
- const response = await this.apiService.post<PostLoadLinksMetadataRequest, PostLoadLinksMetadataResponse>(`drive/v2/volumes/${volumeId}/links`, {
87
- LinkIDs: nodeIds,
88
- }, signal);
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, isAdmin);
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>(`drive/v2/volumes/${volumeId}/folders/${nodeId}/children?${anchor ? `AnchorID=${anchor}` : ''}`, signal);
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>(`drive/volumes/${volumeId}/trash?Page=${page}`, signal);
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
- Omit<PutRenameNodeRequest, "SignatureAddress" | "MIMEType">,
169
- PutRenameNodeResponse
170
- >(`drive/v2/volumes/${volumeId}/links/${nodeId}/rename`, {
171
- Name: newNode.encryptedName,
172
- NameSignatureEmail: newNode.nameSignatureEmail,
173
- Hash: newNode.hash,
174
- OriginalHash: originalNode.hash || null,
175
- }, signal);
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
- Omit<PutMoveNodeRequest, "SignatureAddress" | "MIMEType">,
200
- PutMoveNodeResponse
201
- >(`drive/v2/volumes/${volumeId}/links/${nodeId}/move`, {
202
- ParentLinkID: newParentNodeId,
203
- NodePassphrase: newNode.armoredNodePassphrase,
204
- // @ts-expect-error: API accepts NodePassphraseSignature as optional.
205
- NodePassphraseSignature: newNode.armoredNodePassphraseSignature,
206
- // @ts-expect-error: API accepts SignatureEmail as optional.
207
- SignatureEmail: newNode.signatureEmail,
208
- Name: newNode.encryptedName,
209
- // @ts-expect-error: API accepts NameSignatureEmail as optional.
210
- NameSignatureEmail: newNode.nameSignatureEmail,
211
- Hash: newNode.hash,
212
- OriginalHash: oldNode.hash,
213
- ContentHash: newNode.contentHash || null,
214
- }, signal);
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* trashNodes(nodeUids: string[], signal?: AbortSignal): AsyncGenerator<NodeResult> {
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
- PostTrashNodesRequest,
224
- PostTrashNodesResponse
225
- >(`drive/v2/volumes/${volumeId}/trash_multiple`, {
226
- LinkIDs: nodeIds.map(({ nodeId }) => nodeId),
227
- }, signal);
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* restoreNodes(nodeUids: string[], signal?: AbortSignal): AsyncGenerator<NodeResult> {
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
- PutRestoreNodesRequest,
240
- PutRestoreNodesResponse
241
- >(`drive/v2/volumes/${volumeId}/trash/restore_multiple`, {
242
- LinkIDs: nodeIds.map(({ nodeId }) => nodeId),
243
- }, signal);
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* deleteNodes(nodeUids: string[], signal?: AbortSignal): AsyncGenerator<NodeResult> {
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
- PostDeleteNodesRequest,
256
- PostDeleteNodesResponse
257
- >(`drive/v2/volumes/${volumeId}/trash/delete_multiple`, {
258
- LinkIDs: nodeIds.map(({ nodeId }) => nodeId),
259
- }, signal);
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
- PostCreateFolderRequest,
282
- PostCreateFolderResponse
283
- >(`drive/v2/volumes/${volumeId}/folders`, {
284
- ParentLinkID: parentId,
285
- NodeKey: newNode.armoredKey,
286
- NodeHashKey: newNode.armoredHashKey,
287
- NodePassphrase: newNode.armoredNodePassphrase,
288
- NodePassphraseSignature: newNode.armoredNodePassphraseSignature,
289
- SignatureEmail: newNode.signatureEmail,
290
- Name: newNode.encryptedName,
291
- Hash: newNode.hash,
292
- // @ts-expect-error: XAttr is optional as undefined.
293
- XAttr: newNode.armoredExtendedAttributes,
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>(`drive/v2/volumes/${volumeId}/files/${nodeId}/revisions/${revisionId}?NoBlockUrls=true`, signal);
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>(`drive/v2/volumes/${volumeId}/files/${nodeId}/revisions`, signal);
310
- return response.Revisions
311
- .filter((revision) => revision.State === APIRevisionState.Active || revision.State === APIRevisionState.Obsolete)
312
- .map((revision) => transformRevisionResponse(volumeId, nodeId, revision));
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
- undefined,
320
- PostRestoreRevisionResponse
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>(`drive/v2/volumes/${volumeId}/files/${nodeId}/revisions/${revisionId}`);
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(nodeUids: string[], volumeId: string, responses: LinkResponse[] = []): Generator<NodeResult> {
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(logger: Logger, volumeId: string, link: PostLoadLinksMetadataResponse['Links'][0], isAdmin: boolean): EncryptedNode {
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 ? MemberRole.Admin : permissionsToDirectMemberRole(logger, link.Membership?.Permissions),
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: link.File.ActiveRevision.Thumbnails?.map((thumbnail) => transformThumbnail(volumeId, link.Link.LinkID, thumbnail)) || [],
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(volumeId: string, nodeId: string, thumbnail: { ThumbnailID: string | null, Type: 1 | 2 | 3}): Thumbnail {
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
  }