@backblaze-labs/b2-sdk 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (701) hide show
  1. package/CHANGELOG.md +110 -5
  2. package/README.md +144 -33
  3. package/dist/_virtual/_b2-sdk-version-json.cjs +4 -0
  4. package/dist/_virtual/_b2-sdk-version-json.js +4 -0
  5. package/dist/auth/account-info.d.cts +32 -0
  6. package/dist/auth/account-info.d.cts.map +1 -1
  7. package/dist/auth/account-info.d.ts +32 -0
  8. package/dist/auth/account-info.d.ts.map +1 -1
  9. package/dist/auth/file.cjs +408 -207
  10. package/dist/auth/file.cjs.map +1 -1
  11. package/dist/auth/file.d.cts +77 -3
  12. package/dist/auth/file.d.cts.map +1 -1
  13. package/dist/auth/file.d.ts +77 -3
  14. package/dist/auth/file.d.ts.map +1 -1
  15. package/dist/auth/file.js +407 -207
  16. package/dist/auth/file.js.map +1 -1
  17. package/dist/auth/in-memory.cjs +212 -183
  18. package/dist/auth/in-memory.cjs.map +1 -1
  19. package/dist/auth/in-memory.d.cts +8 -0
  20. package/dist/auth/in-memory.d.cts.map +1 -1
  21. package/dist/auth/in-memory.d.ts +8 -0
  22. package/dist/auth/in-memory.d.ts.map +1 -1
  23. package/dist/auth/in-memory.js +211 -182
  24. package/dist/auth/in-memory.js.map +1 -1
  25. package/dist/auth/index.cjs +7 -9
  26. package/dist/auth/index.d.cts +3 -2
  27. package/dist/auth/index.d.cts.map +1 -1
  28. package/dist/auth/index.d.ts +3 -2
  29. package/dist/auth/index.d.ts.map +1 -1
  30. package/dist/auth/index.js +2 -8
  31. package/dist/auth/realms.cjs +80 -7
  32. package/dist/auth/realms.cjs.map +1 -1
  33. package/dist/auth/realms.d.cts +27 -4
  34. package/dist/auth/realms.d.cts.map +1 -1
  35. package/dist/auth/realms.d.ts +27 -4
  36. package/dist/auth/realms.d.ts.map +1 -1
  37. package/dist/auth/realms.js +80 -9
  38. package/dist/auth/realms.js.map +1 -1
  39. package/dist/auth/upload-url-pool.cjs +55 -51
  40. package/dist/auth/upload-url-pool.cjs.map +1 -1
  41. package/dist/auth/upload-url-pool.js +55 -51
  42. package/dist/auth/upload-url-pool.js.map +1 -1
  43. package/dist/bucket.cjs +785 -787
  44. package/dist/bucket.cjs.map +1 -1
  45. package/dist/bucket.d.cts +35 -47
  46. package/dist/bucket.d.cts.map +1 -1
  47. package/dist/bucket.d.ts +35 -47
  48. package/dist/bucket.d.ts.map +1 -1
  49. package/dist/bucket.js +780 -782
  50. package/dist/bucket.js.map +1 -1
  51. package/dist/client.cjs +246 -228
  52. package/dist/client.cjs.map +1 -1
  53. package/dist/client.d.cts +25 -17
  54. package/dist/client.d.cts.map +1 -1
  55. package/dist/client.d.ts +25 -17
  56. package/dist/client.d.ts.map +1 -1
  57. package/dist/client.js +243 -225
  58. package/dist/client.js.map +1 -1
  59. package/dist/copy/large.cjs +114 -71
  60. package/dist/copy/large.cjs.map +1 -1
  61. package/dist/copy/large.d.cts +6 -0
  62. package/dist/copy/large.d.cts.map +1 -1
  63. package/dist/copy/large.d.ts +6 -0
  64. package/dist/copy/large.d.ts.map +1 -1
  65. package/dist/copy/large.js +112 -69
  66. package/dist/copy/large.js.map +1 -1
  67. package/dist/download/checksum.cjs +89 -0
  68. package/dist/download/checksum.cjs.map +1 -0
  69. package/dist/download/checksum.d.cts +40 -0
  70. package/dist/download/checksum.d.cts.map +1 -0
  71. package/dist/download/checksum.d.ts +40 -0
  72. package/dist/download/checksum.d.ts.map +1 -0
  73. package/dist/download/checksum.js +87 -0
  74. package/dist/download/checksum.js.map +1 -0
  75. package/dist/download/parallel.cjs +214 -118
  76. package/dist/download/parallel.cjs.map +1 -1
  77. package/dist/download/parallel.d.cts +5 -1
  78. package/dist/download/parallel.d.cts.map +1 -1
  79. package/dist/download/parallel.d.ts +5 -1
  80. package/dist/download/parallel.d.ts.map +1 -1
  81. package/dist/download/parallel.js +212 -116
  82. package/dist/download/parallel.js.map +1 -1
  83. package/dist/download/single.cjs +188 -97
  84. package/dist/download/single.cjs.map +1 -1
  85. package/dist/download/single.d.cts +6 -1
  86. package/dist/download/single.d.cts.map +1 -1
  87. package/dist/download/single.d.ts +6 -1
  88. package/dist/download/single.d.ts.map +1 -1
  89. package/dist/download/single.js +186 -98
  90. package/dist/download/single.js.map +1 -1
  91. package/dist/errors/index.cjs +699 -243
  92. package/dist/errors/index.cjs.map +1 -1
  93. package/dist/errors/index.d.cts +285 -82
  94. package/dist/errors/index.d.cts.map +1 -1
  95. package/dist/errors/index.d.ts +285 -82
  96. package/dist/errors/index.d.ts.map +1 -1
  97. package/dist/errors/index.js +678 -261
  98. package/dist/errors/index.js.map +1 -1
  99. package/dist/http/retry.cjs +45 -28
  100. package/dist/http/retry.cjs.map +1 -1
  101. package/dist/http/retry.d.cts +15 -2
  102. package/dist/http/retry.d.cts.map +1 -1
  103. package/dist/http/retry.d.ts +15 -2
  104. package/dist/http/retry.d.ts.map +1 -1
  105. package/dist/http/retry.js +46 -31
  106. package/dist/http/retry.js.map +1 -1
  107. package/dist/http/transport.cjs +438 -140
  108. package/dist/http/transport.cjs.map +1 -1
  109. package/dist/http/transport.d.cts +21 -2
  110. package/dist/http/transport.d.cts.map +1 -1
  111. package/dist/http/transport.d.ts +21 -2
  112. package/dist/http/transport.d.ts.map +1 -1
  113. package/dist/http/transport.js +437 -140
  114. package/dist/http/transport.js.map +1 -1
  115. package/dist/http/url-guard.cjs +154 -89
  116. package/dist/http/url-guard.cjs.map +1 -1
  117. package/dist/http/url-guard.d.cts +25 -3
  118. package/dist/http/url-guard.d.cts.map +1 -1
  119. package/dist/http/url-guard.d.ts +25 -3
  120. package/dist/http/url-guard.d.ts.map +1 -1
  121. package/dist/http/url-guard.js +152 -90
  122. package/dist/http/url-guard.js.map +1 -1
  123. package/dist/http/user-agent.cjs +84 -44
  124. package/dist/http/user-agent.cjs.map +1 -1
  125. package/dist/http/user-agent.js +84 -46
  126. package/dist/http/user-agent.js.map +1 -1
  127. package/dist/index.cjs +101 -77
  128. package/dist/index.d.cts +27 -21
  129. package/dist/index.d.cts.map +1 -1
  130. package/dist/index.d.ts +27 -21
  131. package/dist/index.d.ts.map +1 -1
  132. package/dist/index.js +15 -71
  133. package/dist/internal/b2-naming.cjs +66 -0
  134. package/dist/internal/b2-naming.cjs.map +1 -0
  135. package/dist/internal/b2-naming.d.cts +43 -0
  136. package/dist/internal/b2-naming.d.cts.map +1 -0
  137. package/dist/internal/b2-naming.d.ts +43 -0
  138. package/dist/internal/b2-naming.d.ts.map +1 -0
  139. package/dist/internal/b2-naming.js +60 -0
  140. package/dist/internal/b2-naming.js.map +1 -0
  141. package/dist/internal/upload-retry-options.cjs +21 -0
  142. package/dist/internal/upload-retry-options.cjs.map +1 -0
  143. package/dist/internal/upload-retry-options.d.cts +12 -0
  144. package/dist/internal/upload-retry-options.d.cts.map +1 -0
  145. package/dist/internal/upload-retry-options.d.ts +12 -0
  146. package/dist/internal/upload-retry-options.d.ts.map +1 -0
  147. package/dist/internal/upload-retry-options.js +21 -0
  148. package/dist/internal/upload-retry-options.js.map +1 -0
  149. package/dist/internal/url-redaction.cjs +31 -0
  150. package/dist/internal/url-redaction.cjs.map +1 -0
  151. package/dist/internal/url-redaction.d.cts +17 -0
  152. package/dist/internal/url-redaction.d.cts.map +1 -0
  153. package/dist/internal/url-redaction.d.ts +17 -0
  154. package/dist/internal/url-redaction.d.ts.map +1 -0
  155. package/dist/internal/url-redaction.js +31 -0
  156. package/dist/internal/url-redaction.js.map +1 -0
  157. package/dist/notifications/index.cjs +4 -6
  158. package/dist/notifications/index.d.cts +1 -1
  159. package/dist/notifications/index.d.cts.map +1 -1
  160. package/dist/notifications/index.d.ts +1 -1
  161. package/dist/notifications/index.d.ts.map +1 -1
  162. package/dist/notifications/index.js +1 -6
  163. package/dist/notifications/webhook.cjs +195 -85
  164. package/dist/notifications/webhook.cjs.map +1 -1
  165. package/dist/notifications/webhook.d.cts.map +1 -1
  166. package/dist/notifications/webhook.d.ts.map +1 -1
  167. package/dist/notifications/webhook.js +195 -87
  168. package/dist/notifications/webhook.js.map +1 -1
  169. package/dist/object.cjs +253 -210
  170. package/dist/object.cjs.map +1 -1
  171. package/dist/object.d.cts +9 -55
  172. package/dist/object.d.cts.map +1 -1
  173. package/dist/object.d.ts +9 -55
  174. package/dist/object.d.ts.map +1 -1
  175. package/dist/object.js +249 -206
  176. package/dist/object.js.map +1 -1
  177. package/dist/raw/encoding.cjs +74 -35
  178. package/dist/raw/encoding.cjs.map +1 -1
  179. package/dist/raw/encoding.js +74 -38
  180. package/dist/raw/encoding.js.map +1 -1
  181. package/dist/raw/index.cjs +678 -587
  182. package/dist/raw/index.cjs.map +1 -1
  183. package/dist/raw/index.d.cts +121 -18
  184. package/dist/raw/index.d.cts.map +1 -1
  185. package/dist/raw/index.d.ts +121 -18
  186. package/dist/raw/index.d.ts.map +1 -1
  187. package/dist/raw/index.js +674 -589
  188. package/dist/raw/index.js.map +1 -1
  189. package/dist/s3/index.cjs +355 -18
  190. package/dist/s3/index.cjs.map +1 -1
  191. package/dist/s3/index.d.cts +233 -5
  192. package/dist/s3/index.d.cts.map +1 -1
  193. package/dist/s3/index.d.ts +233 -5
  194. package/dist/s3/index.d.ts.map +1 -1
  195. package/dist/s3/index.js +351 -22
  196. package/dist/s3/index.js.map +1 -1
  197. package/dist/s3/sigv4.cjs +149 -0
  198. package/dist/s3/sigv4.cjs.map +1 -0
  199. package/dist/s3/sigv4.d.cts +43 -0
  200. package/dist/s3/sigv4.d.cts.map +1 -0
  201. package/dist/s3/sigv4.d.ts +43 -0
  202. package/dist/s3/sigv4.d.ts.map +1 -0
  203. package/dist/s3/sigv4.js +148 -0
  204. package/dist/s3/sigv4.js.map +1 -0
  205. package/dist/s3/validation.cjs +69 -0
  206. package/dist/s3/validation.cjs.map +1 -0
  207. package/dist/s3/validation.d.cts +43 -0
  208. package/dist/s3/validation.d.cts.map +1 -0
  209. package/dist/s3/validation.d.ts +43 -0
  210. package/dist/s3/validation.d.ts.map +1 -0
  211. package/dist/s3/validation.js +66 -0
  212. package/dist/s3/validation.js.map +1 -0
  213. package/dist/simulator/capabilities.cjs +63 -48
  214. package/dist/simulator/capabilities.cjs.map +1 -1
  215. package/dist/simulator/capabilities.js +63 -49
  216. package/dist/simulator/capabilities.js.map +1 -1
  217. package/dist/simulator/index.cjs +2124 -1548
  218. package/dist/simulator/index.cjs.map +1 -1
  219. package/dist/simulator/index.d.cts +79 -11
  220. package/dist/simulator/index.d.cts.map +1 -1
  221. package/dist/simulator/index.d.ts +79 -11
  222. package/dist/simulator/index.d.ts.map +1 -1
  223. package/dist/simulator/index.js +2112 -1546
  224. package/dist/simulator/index.js.map +1 -1
  225. package/dist/simulator/validation.cjs +191 -153
  226. package/dist/simulator/validation.cjs.map +1 -1
  227. package/dist/simulator/validation.d.cts +3 -21
  228. package/dist/simulator/validation.d.cts.map +1 -1
  229. package/dist/simulator/validation.d.ts +3 -21
  230. package/dist/simulator/validation.d.ts.map +1 -1
  231. package/dist/simulator/validation.js +188 -162
  232. package/dist/simulator/validation.js.map +1 -1
  233. package/dist/streams/collect.cjs +74 -24
  234. package/dist/streams/collect.cjs.map +1 -1
  235. package/dist/streams/collect.d.cts +14 -1
  236. package/dist/streams/collect.d.cts.map +1 -1
  237. package/dist/streams/collect.d.ts +14 -1
  238. package/dist/streams/collect.d.ts.map +1 -1
  239. package/dist/streams/collect.js +74 -25
  240. package/dist/streams/collect.js.map +1 -1
  241. package/dist/streams/file-source.cjs +287 -0
  242. package/dist/streams/file-source.cjs.map +1 -0
  243. package/dist/streams/file-source.d.cts +96 -0
  244. package/dist/streams/file-source.d.cts.map +1 -0
  245. package/dist/streams/file-source.d.ts +96 -0
  246. package/dist/streams/file-source.d.ts.map +1 -0
  247. package/dist/streams/file-source.js +286 -0
  248. package/dist/streams/file-source.js.map +1 -0
  249. package/dist/streams/hash.cjs +207 -115
  250. package/dist/streams/hash.cjs.map +1 -1
  251. package/dist/streams/hash.d.cts +5 -4
  252. package/dist/streams/hash.d.cts.map +1 -1
  253. package/dist/streams/hash.d.ts +5 -4
  254. package/dist/streams/hash.d.ts.map +1 -1
  255. package/dist/streams/hash.js +208 -95
  256. package/dist/streams/hash.js.map +1 -1
  257. package/dist/streams/index.cjs +12 -12
  258. package/dist/streams/index.d.cts +3 -3
  259. package/dist/streams/index.d.cts.map +1 -1
  260. package/dist/streams/index.d.ts +3 -3
  261. package/dist/streams/index.d.ts.map +1 -1
  262. package/dist/streams/index.js +2 -10
  263. package/dist/streams/progress.cjs +60 -46
  264. package/dist/streams/progress.cjs.map +1 -1
  265. package/dist/streams/progress.js +60 -46
  266. package/dist/streams/progress.js.map +1 -1
  267. package/dist/streams/source.cjs +316 -146
  268. package/dist/streams/source.cjs.map +1 -1
  269. package/dist/streams/source.d.cts +56 -18
  270. package/dist/streams/source.d.cts.map +1 -1
  271. package/dist/streams/source.d.ts +56 -18
  272. package/dist/streams/source.d.ts.map +1 -1
  273. package/dist/streams/source.js +312 -149
  274. package/dist/streams/source.js.map +1 -1
  275. package/dist/sync/actions/index.cjs +236 -184
  276. package/dist/sync/actions/index.cjs.map +1 -1
  277. package/dist/sync/actions/index.d.cts +29 -21
  278. package/dist/sync/actions/index.d.cts.map +1 -1
  279. package/dist/sync/actions/index.d.ts +29 -21
  280. package/dist/sync/actions/index.d.ts.map +1 -1
  281. package/dist/sync/actions/index.js +236 -190
  282. package/dist/sync/actions/index.js.map +1 -1
  283. package/dist/sync/b2-sha1-reader.cjs +148 -0
  284. package/dist/sync/b2-sha1-reader.cjs.map +1 -0
  285. package/dist/sync/b2-sha1-reader.d.cts +58 -0
  286. package/dist/sync/b2-sha1-reader.d.cts.map +1 -0
  287. package/dist/sync/b2-sha1-reader.d.ts +58 -0
  288. package/dist/sync/b2-sha1-reader.d.ts.map +1 -0
  289. package/dist/sync/b2-sha1-reader.js +145 -0
  290. package/dist/sync/b2-sha1-reader.js.map +1 -0
  291. package/dist/sync/download-staging.cjs +265 -0
  292. package/dist/sync/download-staging.cjs.map +1 -0
  293. package/dist/sync/download-staging.d.cts +54 -0
  294. package/dist/sync/download-staging.d.cts.map +1 -0
  295. package/dist/sync/download-staging.d.ts +54 -0
  296. package/dist/sync/download-staging.d.ts.map +1 -0
  297. package/dist/sync/download-staging.js +259 -0
  298. package/dist/sync/download-staging.js.map +1 -0
  299. package/dist/sync/filesystem-errors.cjs +32 -0
  300. package/dist/sync/filesystem-errors.cjs.map +1 -0
  301. package/dist/sync/filesystem-errors.d.cts +8 -0
  302. package/dist/sync/filesystem-errors.d.cts.map +1 -0
  303. package/dist/sync/filesystem-errors.d.ts +8 -0
  304. package/dist/sync/filesystem-errors.d.ts.map +1 -0
  305. package/dist/sync/filesystem-errors.js +32 -0
  306. package/dist/sync/filesystem-errors.js.map +1 -0
  307. package/dist/sync/filters.cjs +217 -0
  308. package/dist/sync/filters.cjs.map +1 -0
  309. package/dist/sync/filters.d.cts +51 -0
  310. package/dist/sync/filters.d.cts.map +1 -0
  311. package/dist/sync/filters.d.ts +51 -0
  312. package/dist/sync/filters.d.ts.map +1 -0
  313. package/dist/sync/filters.js +213 -0
  314. package/dist/sync/filters.js.map +1 -0
  315. package/dist/sync/index.cjs +39 -22
  316. package/dist/sync/index.d.cts +14 -9
  317. package/dist/sync/index.d.cts.map +1 -1
  318. package/dist/sync/index.d.ts +14 -9
  319. package/dist/sync/index.d.ts.map +1 -1
  320. package/dist/sync/index.js +9 -20
  321. package/dist/sync/local-file-identity.cjs +61 -0
  322. package/dist/sync/local-file-identity.cjs.map +1 -0
  323. package/dist/sync/local-file-identity.d.cts +37 -0
  324. package/dist/sync/local-file-identity.d.cts.map +1 -0
  325. package/dist/sync/local-file-identity.d.ts +37 -0
  326. package/dist/sync/local-file-identity.d.ts.map +1 -0
  327. package/dist/sync/local-file-identity.js +60 -0
  328. package/dist/sync/local-file-identity.js.map +1 -0
  329. package/dist/sync/local-file-io.cjs +364 -0
  330. package/dist/sync/local-file-io.cjs.map +1 -0
  331. package/dist/sync/local-file-io.d.cts +75 -0
  332. package/dist/sync/local-file-io.d.cts.map +1 -0
  333. package/dist/sync/local-file-io.d.ts +75 -0
  334. package/dist/sync/local-file-io.d.ts.map +1 -0
  335. package/dist/sync/local-file-io.js +360 -0
  336. package/dist/sync/local-file-io.js.map +1 -0
  337. package/dist/sync/local-filesystem-root.cjs +27 -0
  338. package/dist/sync/local-filesystem-root.cjs.map +1 -0
  339. package/dist/sync/local-filesystem-root.d.cts +18 -0
  340. package/dist/sync/local-filesystem-root.d.cts.map +1 -0
  341. package/dist/sync/local-filesystem-root.d.ts +18 -0
  342. package/dist/sync/local-filesystem-root.d.ts.map +1 -0
  343. package/dist/sync/local-filesystem-root.js +26 -0
  344. package/dist/sync/local-filesystem-root.js.map +1 -0
  345. package/dist/sync/local-sha1.cjs +119 -0
  346. package/dist/sync/local-sha1.cjs.map +1 -0
  347. package/dist/sync/local-sha1.d.cts +39 -0
  348. package/dist/sync/local-sha1.d.cts.map +1 -0
  349. package/dist/sync/local-sha1.d.ts +39 -0
  350. package/dist/sync/local-sha1.d.ts.map +1 -0
  351. package/dist/sync/local-sha1.js +117 -0
  352. package/dist/sync/local-sha1.js.map +1 -0
  353. package/dist/sync/pairing.cjs +118 -29
  354. package/dist/sync/pairing.cjs.map +1 -1
  355. package/dist/sync/pairing.d.cts +7 -2
  356. package/dist/sync/pairing.d.cts.map +1 -1
  357. package/dist/sync/pairing.d.ts +7 -2
  358. package/dist/sync/pairing.d.ts.map +1 -1
  359. package/dist/sync/pairing.js +120 -31
  360. package/dist/sync/pairing.js.map +1 -1
  361. package/dist/sync/path-order.cjs +30 -0
  362. package/dist/sync/path-order.cjs.map +1 -0
  363. package/dist/sync/path-order.d.cts +28 -0
  364. package/dist/sync/path-order.d.cts.map +1 -0
  365. package/dist/sync/path-order.d.ts +28 -0
  366. package/dist/sync/path-order.d.ts.map +1 -0
  367. package/dist/sync/path-order.js +29 -0
  368. package/dist/sync/path-order.js.map +1 -0
  369. package/dist/sync/path-safety.cjs +111 -0
  370. package/dist/sync/path-safety.cjs.map +1 -0
  371. package/dist/sync/path-safety.d.cts +78 -0
  372. package/dist/sync/path-safety.d.cts.map +1 -0
  373. package/dist/sync/path-safety.d.ts +78 -0
  374. package/dist/sync/path-safety.d.ts.map +1 -0
  375. package/dist/sync/path-safety.js +105 -0
  376. package/dist/sync/path-safety.js.map +1 -0
  377. package/dist/sync/paths.d.cts +19 -0
  378. package/dist/sync/paths.d.cts.map +1 -0
  379. package/dist/sync/paths.d.ts +19 -0
  380. package/dist/sync/paths.d.ts.map +1 -0
  381. package/dist/sync/policies/compare.cjs +389 -11
  382. package/dist/sync/policies/compare.cjs.map +1 -1
  383. package/dist/sync/policies/compare.d.cts +100 -2
  384. package/dist/sync/policies/compare.d.cts.map +1 -1
  385. package/dist/sync/policies/compare.d.ts +100 -2
  386. package/dist/sync/policies/compare.d.ts.map +1 -1
  387. package/dist/sync/policies/compare.js +387 -13
  388. package/dist/sync/policies/compare.js.map +1 -1
  389. package/dist/sync/policies/index.cjs +76 -65
  390. package/dist/sync/policies/index.cjs.map +1 -1
  391. package/dist/sync/policies/index.d.cts +35 -6
  392. package/dist/sync/policies/index.d.cts.map +1 -1
  393. package/dist/sync/policies/index.d.ts +35 -6
  394. package/dist/sync/policies/index.d.ts.map +1 -1
  395. package/dist/sync/policies/index.js +76 -65
  396. package/dist/sync/policies/index.js.map +1 -1
  397. package/dist/sync/prefix.cjs +96 -0
  398. package/dist/sync/prefix.cjs.map +1 -0
  399. package/dist/sync/prefix.d.cts +55 -0
  400. package/dist/sync/prefix.d.cts.map +1 -0
  401. package/dist/sync/prefix.d.ts +55 -0
  402. package/dist/sync/prefix.d.ts.map +1 -0
  403. package/dist/sync/prefix.js +92 -0
  404. package/dist/sync/prefix.js.map +1 -0
  405. package/dist/sync/regexp-safety.cjs +192 -0
  406. package/dist/sync/regexp-safety.cjs.map +1 -0
  407. package/dist/sync/regexp-safety.d.cts +29 -0
  408. package/dist/sync/regexp-safety.d.cts.map +1 -0
  409. package/dist/sync/regexp-safety.d.ts +29 -0
  410. package/dist/sync/regexp-safety.d.ts.map +1 -0
  411. package/dist/sync/regexp-safety.js +190 -0
  412. package/dist/sync/regexp-safety.js.map +1 -0
  413. package/dist/sync/scan-events.cjs +33 -0
  414. package/dist/sync/scan-events.cjs.map +1 -0
  415. package/dist/sync/scan-events.d.cts +17 -0
  416. package/dist/sync/scan-events.d.cts.map +1 -0
  417. package/dist/sync/scan-events.d.ts +17 -0
  418. package/dist/sync/scan-events.d.ts.map +1 -0
  419. package/dist/sync/scan-events.js +32 -0
  420. package/dist/sync/scan-events.js.map +1 -0
  421. package/dist/sync/scan-limit.cjs +33 -0
  422. package/dist/sync/scan-limit.cjs.map +1 -0
  423. package/dist/sync/scan-limit.d.cts +21 -0
  424. package/dist/sync/scan-limit.d.cts.map +1 -0
  425. package/dist/sync/scan-limit.d.ts +21 -0
  426. package/dist/sync/scan-limit.d.ts.map +1 -0
  427. package/dist/sync/scan-limit.js +31 -0
  428. package/dist/sync/scan-limit.js.map +1 -0
  429. package/dist/sync/scanners/b2.cjs +239 -55
  430. package/dist/sync/scanners/b2.cjs.map +1 -1
  431. package/dist/sync/scanners/b2.d.cts +26 -7
  432. package/dist/sync/scanners/b2.d.cts.map +1 -1
  433. package/dist/sync/scanners/b2.d.ts +26 -7
  434. package/dist/sync/scanners/b2.d.ts.map +1 -1
  435. package/dist/sync/scanners/b2.js +239 -55
  436. package/dist/sync/scanners/b2.js.map +1 -1
  437. package/dist/sync/scanners/local.cjs +215 -56
  438. package/dist/sync/scanners/local.cjs.map +1 -1
  439. package/dist/sync/scanners/local.d.cts +22 -7
  440. package/dist/sync/scanners/local.d.cts.map +1 -1
  441. package/dist/sync/scanners/local.d.ts +22 -7
  442. package/dist/sync/scanners/local.d.ts.map +1 -1
  443. package/dist/sync/scanners/local.js +216 -57
  444. package/dist/sync/scanners/local.js.map +1 -1
  445. package/dist/sync/sha1-metadata.cjs +94 -0
  446. package/dist/sync/sha1-metadata.cjs.map +1 -0
  447. package/dist/sync/sha1-metadata.d.cts +82 -0
  448. package/dist/sync/sha1-metadata.d.cts.map +1 -0
  449. package/dist/sync/sha1-metadata.d.ts +82 -0
  450. package/dist/sync/sha1-metadata.d.ts.map +1 -0
  451. package/dist/sync/sha1-metadata.js +89 -0
  452. package/dist/sync/sha1-metadata.js.map +1 -0
  453. package/dist/sync/sha1-options.cjs +23 -0
  454. package/dist/sync/sha1-options.cjs.map +1 -0
  455. package/dist/sync/sha1-options.d.cts +14 -0
  456. package/dist/sync/sha1-options.d.cts.map +1 -0
  457. package/dist/sync/sha1-options.d.ts +14 -0
  458. package/dist/sync/sha1-options.d.ts.map +1 -0
  459. package/dist/sync/sha1-options.js +21 -0
  460. package/dist/sync/sha1-options.js.map +1 -0
  461. package/dist/sync/synchronizer.cjs +782 -197
  462. package/dist/sync/synchronizer.cjs.map +1 -1
  463. package/dist/sync/synchronizer.d.cts +47 -1
  464. package/dist/sync/synchronizer.d.cts.map +1 -1
  465. package/dist/sync/synchronizer.d.ts +47 -1
  466. package/dist/sync/synchronizer.d.ts.map +1 -1
  467. package/dist/sync/synchronizer.js +779 -173
  468. package/dist/sync/synchronizer.js.map +1 -1
  469. package/dist/sync/types.d.cts +208 -16
  470. package/dist/sync/types.d.cts.map +1 -1
  471. package/dist/sync/types.d.ts +208 -16
  472. package/dist/sync/types.d.ts.map +1 -1
  473. package/dist/types/auth.cjs +76 -56
  474. package/dist/types/auth.cjs.map +1 -1
  475. package/dist/types/auth.d.cts +67 -9
  476. package/dist/types/auth.d.cts.map +1 -1
  477. package/dist/types/auth.d.ts +67 -9
  478. package/dist/types/auth.d.ts.map +1 -1
  479. package/dist/types/auth.js +77 -57
  480. package/dist/types/auth.js.map +1 -1
  481. package/dist/types/bucket.cjs +74 -38
  482. package/dist/types/bucket.cjs.map +1 -1
  483. package/dist/types/bucket.js +75 -41
  484. package/dist/types/bucket.js.map +1 -1
  485. package/dist/types/encryption.cjs +364 -327
  486. package/dist/types/encryption.cjs.map +1 -1
  487. package/dist/types/encryption.d.cts +16 -0
  488. package/dist/types/encryption.d.cts.map +1 -1
  489. package/dist/types/encryption.d.ts +16 -0
  490. package/dist/types/encryption.d.ts.map +1 -1
  491. package/dist/types/encryption.js +364 -310
  492. package/dist/types/encryption.js.map +1 -1
  493. package/dist/types/errors.cjs +47 -0
  494. package/dist/types/errors.cjs.map +1 -0
  495. package/dist/types/errors.d.cts +13 -4
  496. package/dist/types/errors.d.cts.map +1 -1
  497. package/dist/types/errors.d.ts +13 -4
  498. package/dist/types/errors.d.ts.map +1 -1
  499. package/dist/types/errors.js +47 -0
  500. package/dist/types/errors.js.map +1 -0
  501. package/dist/types/file.cjs +36 -19
  502. package/dist/types/file.cjs.map +1 -1
  503. package/dist/types/file.d.cts +2 -2
  504. package/dist/types/file.d.cts.map +1 -1
  505. package/dist/types/file.d.ts +2 -2
  506. package/dist/types/file.d.ts.map +1 -1
  507. package/dist/types/file.js +37 -21
  508. package/dist/types/file.js.map +1 -1
  509. package/dist/types/ids.cjs +53 -9
  510. package/dist/types/ids.cjs.map +1 -1
  511. package/dist/types/ids.js +54 -15
  512. package/dist/types/ids.js.map +1 -1
  513. package/dist/types/index.d.cts +12 -11
  514. package/dist/types/index.d.cts.map +1 -1
  515. package/dist/types/index.d.ts +12 -11
  516. package/dist/types/index.d.ts.map +1 -1
  517. package/dist/types/key.d.cts +44 -8
  518. package/dist/types/key.d.cts.map +1 -1
  519. package/dist/types/key.d.ts +44 -8
  520. package/dist/types/key.d.ts.map +1 -1
  521. package/dist/types/lock.cjs +33 -13
  522. package/dist/types/lock.cjs.map +1 -1
  523. package/dist/types/lock.js +34 -15
  524. package/dist/types/lock.js.map +1 -1
  525. package/dist/types/notifications.cjs +44 -22
  526. package/dist/types/notifications.cjs.map +1 -1
  527. package/dist/types/notifications.js +45 -23
  528. package/dist/types/notifications.js.map +1 -1
  529. package/dist/types/upload.d.cts +39 -5
  530. package/dist/types/upload.d.cts.map +1 -1
  531. package/dist/types/upload.d.ts +39 -5
  532. package/dist/types/upload.d.ts.map +1 -1
  533. package/dist/upload/abort-scope.cjs +91 -0
  534. package/dist/upload/abort-scope.cjs.map +1 -0
  535. package/dist/upload/abort-scope.d.cts +48 -0
  536. package/dist/upload/abort-scope.d.cts.map +1 -0
  537. package/dist/upload/abort-scope.d.ts +48 -0
  538. package/dist/upload/abort-scope.d.ts.map +1 -0
  539. package/dist/upload/abort-scope.js +88 -0
  540. package/dist/upload/abort-scope.js.map +1 -0
  541. package/dist/upload/cancel.cjs +183 -8
  542. package/dist/upload/cancel.cjs.map +1 -1
  543. package/dist/upload/cancel.d.cts +110 -2
  544. package/dist/upload/cancel.d.cts.map +1 -1
  545. package/dist/upload/cancel.d.ts +110 -2
  546. package/dist/upload/cancel.d.ts.map +1 -1
  547. package/dist/upload/cancel.js +178 -9
  548. package/dist/upload/cancel.js.map +1 -1
  549. package/dist/upload/concurrency.cjs +79 -52
  550. package/dist/upload/concurrency.cjs.map +1 -1
  551. package/dist/upload/concurrency.js +79 -53
  552. package/dist/upload/concurrency.js.map +1 -1
  553. package/dist/upload/finish.cjs +59 -0
  554. package/dist/upload/finish.cjs.map +1 -0
  555. package/dist/upload/finish.d.cts +26 -0
  556. package/dist/upload/finish.d.cts.map +1 -0
  557. package/dist/upload/finish.d.ts +26 -0
  558. package/dist/upload/finish.d.ts.map +1 -0
  559. package/dist/upload/finish.js +59 -0
  560. package/dist/upload/finish.js.map +1 -0
  561. package/dist/upload/large.cjs +301 -218
  562. package/dist/upload/large.cjs.map +1 -1
  563. package/dist/upload/large.d.cts +76 -9
  564. package/dist/upload/large.d.cts.map +1 -1
  565. package/dist/upload/large.d.ts +76 -9
  566. package/dist/upload/large.d.ts.map +1 -1
  567. package/dist/upload/large.js +301 -218
  568. package/dist/upload/large.js.map +1 -1
  569. package/dist/upload/options.cjs +28 -0
  570. package/dist/upload/options.cjs.map +1 -0
  571. package/dist/upload/options.d.cts +104 -0
  572. package/dist/upload/options.d.cts.map +1 -0
  573. package/dist/upload/options.d.ts +104 -0
  574. package/dist/upload/options.d.ts.map +1 -0
  575. package/dist/upload/options.js +27 -0
  576. package/dist/upload/options.js.map +1 -0
  577. package/dist/upload/resume.cjs +333 -33
  578. package/dist/upload/resume.cjs.map +1 -1
  579. package/dist/upload/resume.d.cts +82 -12
  580. package/dist/upload/resume.d.cts.map +1 -1
  581. package/dist/upload/resume.d.ts +82 -12
  582. package/dist/upload/resume.d.ts.map +1 -1
  583. package/dist/upload/resume.js +330 -33
  584. package/dist/upload/resume.js.map +1 -1
  585. package/dist/upload/retry.cjs +186 -0
  586. package/dist/upload/retry.cjs.map +1 -0
  587. package/dist/upload/retry.d.cts +127 -0
  588. package/dist/upload/retry.d.cts.map +1 -0
  589. package/dist/upload/retry.d.ts +127 -0
  590. package/dist/upload/retry.d.ts.map +1 -0
  591. package/dist/upload/retry.js +182 -0
  592. package/dist/upload/retry.js.map +1 -0
  593. package/dist/upload/single.cjs +68 -44
  594. package/dist/upload/single.cjs.map +1 -1
  595. package/dist/upload/single.d.cts +2 -1
  596. package/dist/upload/single.d.cts.map +1 -1
  597. package/dist/upload/single.d.ts +2 -1
  598. package/dist/upload/single.d.ts.map +1 -1
  599. package/dist/upload/single.js +68 -44
  600. package/dist/upload/single.js.map +1 -1
  601. package/dist/upload/stream.cjs +317 -193
  602. package/dist/upload/stream.cjs.map +1 -1
  603. package/dist/upload/stream.d.cts +3 -1
  604. package/dist/upload/stream.d.cts.map +1 -1
  605. package/dist/upload/stream.d.ts +3 -1
  606. package/dist/upload/stream.d.ts.map +1 -1
  607. package/dist/upload/stream.js +316 -192
  608. package/dist/upload/stream.js.map +1 -1
  609. package/dist/util/best-effort.cjs +42 -8
  610. package/dist/util/best-effort.cjs.map +1 -1
  611. package/dist/util/best-effort.d.cts +2 -1
  612. package/dist/util/best-effort.d.cts.map +1 -1
  613. package/dist/util/best-effort.d.ts +2 -1
  614. package/dist/util/best-effort.d.ts.map +1 -1
  615. package/dist/util/best-effort.js +43 -9
  616. package/dist/util/best-effort.js.map +1 -1
  617. package/dist/util/bytes.cjs +23 -0
  618. package/dist/util/bytes.cjs.map +1 -0
  619. package/dist/util/bytes.d.cts +15 -0
  620. package/dist/util/bytes.d.cts.map +1 -0
  621. package/dist/util/bytes.d.ts +15 -0
  622. package/dist/util/bytes.d.ts.map +1 -0
  623. package/dist/util/bytes.js +23 -0
  624. package/dist/util/bytes.js.map +1 -0
  625. package/dist/util/crypto.cjs +68 -0
  626. package/dist/util/crypto.cjs.map +1 -0
  627. package/dist/util/crypto.d.cts +26 -0
  628. package/dist/util/crypto.d.cts.map +1 -0
  629. package/dist/util/crypto.d.ts +26 -0
  630. package/dist/util/crypto.d.ts.map +1 -0
  631. package/dist/util/crypto.js +66 -0
  632. package/dist/util/crypto.js.map +1 -0
  633. package/dist/util/defaults.cjs +25 -9
  634. package/dist/util/defaults.cjs.map +1 -1
  635. package/dist/util/defaults.js +26 -11
  636. package/dist/util/defaults.js.map +1 -1
  637. package/dist/util/error-reason.cjs +41 -0
  638. package/dist/util/error-reason.cjs.map +1 -0
  639. package/dist/util/error-reason.d.cts +9 -0
  640. package/dist/util/error-reason.d.cts.map +1 -0
  641. package/dist/util/error-reason.d.ts +9 -0
  642. package/dist/util/error-reason.d.ts.map +1 -0
  643. package/dist/util/error-reason.js +41 -0
  644. package/dist/util/error-reason.js.map +1 -0
  645. package/dist/util/http.cjs +23 -0
  646. package/dist/util/http.cjs.map +1 -0
  647. package/dist/util/http.d.cts +13 -0
  648. package/dist/util/http.d.cts.map +1 -0
  649. package/dist/util/http.d.ts +13 -0
  650. package/dist/util/http.d.ts.map +1 -0
  651. package/dist/util/http.js +23 -0
  652. package/dist/util/http.js.map +1 -0
  653. package/dist/util/normalize.cjs +66 -7
  654. package/dist/util/normalize.cjs.map +1 -1
  655. package/dist/util/normalize.js +67 -10
  656. package/dist/util/normalize.js.map +1 -1
  657. package/dist/util/paginator.cjs +63 -14
  658. package/dist/util/paginator.cjs.map +1 -1
  659. package/dist/util/paginator.js +64 -16
  660. package/dist/util/paginator.js.map +1 -1
  661. package/dist/util/plan-ranges.cjs +47 -22
  662. package/dist/util/plan-ranges.cjs.map +1 -1
  663. package/dist/util/plan-ranges.js +48 -24
  664. package/dist/util/plan-ranges.js.map +1 -1
  665. package/dist/util/sha1.cjs +27 -0
  666. package/dist/util/sha1.cjs.map +1 -0
  667. package/dist/util/sha1.d.cts +17 -0
  668. package/dist/util/sha1.d.cts.map +1 -0
  669. package/dist/util/sha1.d.ts +17 -0
  670. package/dist/util/sha1.d.ts.map +1 -0
  671. package/dist/util/sha1.js +26 -0
  672. package/dist/util/sha1.js.map +1 -0
  673. package/dist/util/text-codec.cjs +29 -5
  674. package/dist/util/text-codec.cjs.map +1 -1
  675. package/dist/util/text-codec.js +30 -7
  676. package/dist/util/text-codec.js.map +1 -1
  677. package/dist/util/to-error.cjs +18 -4
  678. package/dist/util/to-error.cjs.map +1 -1
  679. package/dist/util/to-error.js +19 -5
  680. package/dist/util/to-error.js.map +1 -1
  681. package/dist/version.cjs +17 -5
  682. package/dist/version.cjs.map +1 -1
  683. package/dist/version.d.cts +3 -3
  684. package/dist/version.d.ts +3 -3
  685. package/dist/version.js +19 -6
  686. package/dist/version.js.map +1 -1
  687. package/package.json +19 -16
  688. package/dist/auth/index.cjs.map +0 -1
  689. package/dist/auth/index.js.map +0 -1
  690. package/dist/index.cjs.map +0 -1
  691. package/dist/index.js.map +0 -1
  692. package/dist/notifications/index.cjs.map +0 -1
  693. package/dist/notifications/index.js.map +0 -1
  694. package/dist/package.json.cjs +0 -9
  695. package/dist/package.json.cjs.map +0 -1
  696. package/dist/package.json.js +0 -9
  697. package/dist/package.json.js.map +0 -1
  698. package/dist/streams/index.cjs.map +0 -1
  699. package/dist/streams/index.js.map +0 -1
  700. package/dist/sync/index.cjs.map +0 -1
  701. package/dist/sync/index.js.map +0 -1
package/dist/bucket.js CHANGED
@@ -1,789 +1,787 @@
1
- import { copyLargeFile } from "./copy/large.js";
2
- import { downloadByName, headByName } from "./download/single.js";
3
- import { B2Object } from "./object.js";
4
1
  import { accountId } from "./types/ids.js";
5
2
  import { Semaphore } from "./upload/concurrency.js";
3
+ import "./util/defaults.js";
4
+ import { copyLargeFile } from "./copy/large.js";
5
+ import { downloadByName, headByName } from "./download/single.js";
6
+ import { mergeUploadRetryOptions } from "./internal/upload-retry-options.js";
6
7
  import { uploadLargeFile } from "./upload/large.js";
8
+ import { rejectSmallResumeFileId, stripResumeOnlyOptions } from "./upload/options.js";
7
9
  import { uploadSmallFile } from "./upload/single.js";
8
- import { DEFAULT_PAGE_SIZE, DEFAULT_BULK_CONCURRENCY } from "./util/defaults.js";
9
- import { paginateItems } from "./util/paginator.js";
10
10
  import { toError } from "./util/to-error.js";
11
- class Bucket {
12
- /** Unique identifier for this bucket. */
13
- id;
14
- /** Human-readable bucket name. */
15
- name;
16
- /** Full bucket metadata as returned by the B2 API. */
17
- info;
18
- client;
19
- /**
20
- * @param client - The parent B2Client instance.
21
- * @param info - The bucket metadata from the API.
22
- *
23
- * @internal
24
- */
25
- constructor(client, info) {
26
- this.client = client;
27
- this.info = info;
28
- this.id = info.bucketId;
29
- this.name = info.bucketName;
30
- }
31
- /**
32
- * Returns a {@link B2Object} handle for a specific file name in this bucket.
33
- * @param fileName - The file path within the bucket.
34
- *
35
- * @returns A B2Object handle bound to this bucket and file name.
36
- */
37
- file(fileName) {
38
- return new B2Object(this.client, this, fileName);
39
- }
40
- /**
41
- * Uploads a file to this bucket. Automatically uses multipart upload for files
42
- * larger than the recommended part size.
43
- * @param options - Upload configuration including file name, source data, and optional settings.
44
- *
45
- * @returns Metadata for the uploaded file version.
46
- */
47
- async upload(options) {
48
- const recommendedPartSize = this.client.accountInfo.getRecommendedPartSize();
49
- const isLarge = options.source.size > recommendedPartSize;
50
- if (isLarge) {
51
- return uploadLargeFile(this.client.raw, this.client.accountInfo, {
52
- bucketId: this.id,
53
- ...options
54
- });
55
- }
56
- const { resume: _resume, resumeFileId: _resumeFileId, ...smallOptions } = options;
57
- return uploadSmallFile(this.client.raw, this.client.accountInfo, {
58
- bucketId: this.id,
59
- ...smallOptions
60
- });
61
- }
62
- /**
63
- * Downloads a file from this bucket by name. Pass `method: 'HEAD'` in
64
- * `options` to fetch only the response headers (file metadata) without
65
- * streaming the body.
66
- * @param fileName - The file name (path) to download.
67
- * @param options - Optional method, range, SSE-C decryption, response-header overrides, and abort signal.
68
- *
69
- * @returns The download result containing response headers and a readable body stream.
70
- */
71
- async download(fileName, options) {
72
- return downloadByName(this.client.raw, this.client.accountInfo, {
73
- bucketName: this.name,
74
- fileName,
75
- ...options
76
- });
77
- }
78
- /**
79
- * Fetches the response headers (file metadata) for a file via HTTP
80
- * HEAD. Returns a body-less result so callers never have to drain
81
- * the (logically empty) HEAD body themselves.
82
- *
83
- * Use this for metadata-only checks like "does this file exist", "what
84
- * is its current SHA-1", "what is its Content-Length". For full file
85
- * retrieval use {@link Bucket.download}.
86
- *
87
- * @param fileName - The file name (path) to inspect.
88
- * @param options - Optional range, SSE-C decryption, response-header
89
- * overrides, and abort signal. Same shape as {@link Bucket.download}'s
90
- * options minus `method` (always HEAD) and `onProgress` (no body).
91
- *
92
- * @returns Parsed download headers (content type, SHA-1, file info, etc.).
93
- *
94
- * @example
95
- * ```ts
96
- * const { headers } = await bucket.head('photos/2026/sunset.jpg')
97
- * console.log(headers.contentLength, headers.contentSha1)
98
- * ```
99
- */
100
- async head(fileName, options) {
101
- return headByName(this.client.raw, this.client.accountInfo, {
102
- bucketName: this.name,
103
- fileName,
104
- ...options
105
- });
106
- }
107
- /**
108
- * Lists file names in this bucket (most recent versions only).
109
- * @param options - Optional filtering and pagination settings.
110
- *
111
- * @returns A page of file versions with an optional continuation token.
112
- */
113
- async listFileNames(options) {
114
- return this.client.raw.listFileNames(
115
- this.client.accountInfo.getApiUrl(),
116
- this.client.accountInfo.getAuthToken(),
117
- {
118
- bucketId: this.id,
119
- ...options?.startFileName !== void 0 ? { startFileName: options.startFileName } : {},
120
- ...options?.pageSize !== void 0 ? { maxFileCount: options.pageSize } : {},
121
- ...options?.prefix !== void 0 ? { prefix: options.prefix } : {},
122
- ...options?.delimiter !== void 0 ? { delimiter: options.delimiter } : {}
123
- }
124
- );
125
- }
126
- /**
127
- * Lists all file versions in this bucket, including hidden files.
128
- * @param options - Optional filtering and pagination settings.
129
- *
130
- * @returns A page of file versions with an optional continuation token.
131
- */
132
- async listFileVersions(options) {
133
- return this.client.raw.listFileVersions(
134
- this.client.accountInfo.getApiUrl(),
135
- this.client.accountInfo.getAuthToken(),
136
- {
137
- bucketId: this.id,
138
- ...options?.startFileName !== void 0 ? { startFileName: options.startFileName } : {},
139
- ...options?.startFileId !== void 0 ? { startFileId: options.startFileId } : {},
140
- ...options?.pageSize !== void 0 ? { maxFileCount: options.pageSize } : {},
141
- ...options?.prefix !== void 0 ? { prefix: options.prefix } : {},
142
- ...options?.delimiter !== void 0 ? { delimiter: options.delimiter } : {}
143
- }
144
- );
145
- }
146
- /**
147
- * Async iterator that yields the latest visible version of every file in
148
- * the bucket, automatically handling pagination via `listFileNames`.
149
- *
150
- * Hidden files (those whose latest version is a hide marker) are NOT
151
- * yielded by this iterator. Use {@link paginateFileVersions} when you
152
- * need full version history.
153
- *
154
- * @param options - Filter + pagination + abort options. `pageSize` is
155
- * forwarded to `b2_list_file_names`'s `maxFileCount` (default 1000,
156
- * B2-capped at 10000).
157
- *
158
- * @returns An async iterable of {@link FileVersion} entries.
159
- *
160
- * @example
161
- * ```ts
162
- * for await (const file of bucket.paginateFileNames({ prefix: 'photos/' })) {
163
- * console.log(file.fileName, file.contentLength)
164
- * }
165
- * ```
166
- */
167
- paginateFileNames(options) {
168
- return paginateItems(
169
- async (cursor) => {
170
- const resp = await this.listFileNames({
171
- pageSize: options?.pageSize ?? DEFAULT_PAGE_SIZE,
172
- ...cursor !== void 0 ? { startFileName: cursor } : {},
173
- ...options?.prefix !== void 0 ? { prefix: options.prefix } : {},
174
- ...options?.delimiter !== void 0 ? { delimiter: options.delimiter } : {}
175
- });
176
- return { page: resp, nextCursor: resp.nextFileName ?? void 0 };
177
- },
178
- // Real B2 surfaces hide markers as rows in `b2_list_file_names`. This
179
- // iterator's documented contract is "latest VISIBLE version", so we
180
- // drop hide-action rows here. Callers who need full history should
181
- // use `paginateFileVersions`.
182
- (page) => page.files.filter((f) => f.action !== "hide"),
183
- options?.signal
184
- );
185
- }
186
- /**
187
- * Async iterator that yields every version of every file in the bucket,
188
- * including hidden files and historical versions, automatically handling
189
- * pagination via `listFileVersions`.
190
- *
191
- * The two-cursor `(nextFileName, nextFileId)` continuation that the raw
192
- * endpoint exposes is threaded internally; callers iterate flat.
193
- *
194
- * @param options - Filter + pagination + abort options.
195
- *
196
- * @returns An async iterable of {@link FileVersion} entries.
197
- */
198
- paginateFileVersions(options) {
199
- return paginateItems(
200
- async (cursor) => {
201
- const resp = await this.listFileVersions({
202
- pageSize: options?.pageSize ?? DEFAULT_PAGE_SIZE,
203
- ...cursor !== void 0 ? { startFileName: cursor.fileName } : {},
204
- ...cursor?.fileId !== void 0 ? { startFileId: cursor.fileId } : {},
205
- ...options?.prefix !== void 0 ? { prefix: options.prefix } : {},
206
- ...options?.delimiter !== void 0 ? { delimiter: options.delimiter } : {}
207
- });
208
- const nextCursor = resp.nextFileName !== null ? { fileName: resp.nextFileName, fileId: resp.nextFileId ?? void 0 } : void 0;
209
- return { page: resp, nextCursor };
210
- },
211
- (page) => page.files,
212
- options?.signal
213
- );
214
- }
215
- /**
216
- * Async iterator that yields every unfinished large file in the bucket,
217
- * automatically handling pagination via `listUnfinishedLargeFiles`.
218
- *
219
- * Useful for janitorial scripts that want to inspect or cancel abandoned
220
- * multipart uploads (typically followed by {@link cancelLargeFile} on
221
- * the underlying raw client).
222
- *
223
- * @param options - Filter + pagination + abort options. `pageSize` is
224
- * B2-capped at 100 for this endpoint.
225
- *
226
- * @returns An async iterable of unfinished-large-file metadata entries.
227
- */
228
- paginateUnfinishedLargeFiles(options) {
229
- return paginateItems(
230
- async (cursor) => {
231
- const resp = await this.listUnfinishedLargeFiles({
232
- pageSize: options?.pageSize ?? 100,
233
- ...cursor !== void 0 ? { startFileId: cursor } : {},
234
- ...options?.namePrefix !== void 0 ? { namePrefix: options.namePrefix } : {}
235
- });
236
- return { page: resp, nextCursor: resp.nextFileId ?? void 0 };
237
- },
238
- (page) => page.files,
239
- options?.signal
240
- );
241
- }
242
- /**
243
- * Async iterator that yields every uploaded part for a specific large
244
- * file, automatically handling pagination via `listParts`.
245
- *
246
- * @param largeFileId - The unfinished large file to enumerate parts of.
247
- * @param options - Pagination + abort options. `pageSize` is B2-capped
248
- * at 1000 for this endpoint; the default is 1000.
249
- *
250
- * @returns An async iterable of {@link PartInfo} entries.
251
- */
252
- paginateParts(largeFileId, options) {
253
- return paginateItems(
254
- async (cursor) => {
255
- const resp = await this.client.raw.listParts(
256
- this.client.accountInfo.getApiUrl(),
257
- this.client.accountInfo.getAuthToken(),
258
- {
259
- fileId: largeFileId,
260
- maxPartCount: options?.pageSize ?? DEFAULT_PAGE_SIZE,
261
- ...cursor !== void 0 ? { startPartNumber: cursor } : {}
262
- }
263
- );
264
- return { page: resp, nextCursor: resp.nextPartNumber ?? void 0 };
265
- },
266
- (page) => page.parts,
267
- options?.signal
268
- );
269
- }
270
- /**
271
- * Looks up the latest visible version of a file by name.
272
- * Uses `listFileNames` under the hood; returns `null` when the file does not
273
- * exist or its latest version is a hide marker.
274
- * @param fileName - The exact file path to look up.
275
- *
276
- * @returns The latest {@link FileVersion}, or `null` if not found.
277
- */
278
- async getFileInfoByName(fileName) {
279
- const resp = await this.listFileNames({ prefix: fileName, pageSize: 1 });
280
- const match = resp.files.find((f) => f.fileName === fileName);
281
- if (!match || match.action === "hide") return null;
282
- return match;
283
- }
284
- /**
285
- * Removes the latest hide marker for a file, restoring visibility of the
286
- * previous upload. Returns the deleted hide marker, or `null` if there was
287
- * no hide marker to remove (file is already visible or does not exist).
288
- * @param fileName - The file path to unhide.
289
- *
290
- * @returns The deleted hide marker version, or `null` if nothing was hidden.
291
- */
292
- async unhideFile(fileName) {
293
- const resp = await this.listFileVersions({ prefix: fileName, pageSize: 100 });
294
- const versions = resp.files.filter((f) => f.fileName === fileName);
295
- if (versions.length === 0) return null;
296
- const latest = versions[0];
297
- if (!latest || latest.action !== "hide") return null;
298
- await this.deleteFileVersion(fileName, latest.fileId);
299
- return latest;
300
- }
301
- /**
302
- * Hides a file by creating a hide marker. The file remains in version history but is no longer visible in `listFileNames`.
303
- * @param fileName - The file path to hide.
304
- *
305
- * @returns Metadata for the newly created hide marker.
306
- */
307
- async hideFile(fileName) {
308
- return this.client.raw.hideFile(
309
- this.client.accountInfo.getApiUrl(),
310
- this.client.accountInfo.getAuthToken(),
311
- { bucketId: this.id, fileName }
312
- );
313
- }
314
- /**
315
- * Permanently deletes a specific file version. Both file name and file ID are required.
316
- *
317
- * If the file is under Object Lock retention, B2 will reject the
318
- * delete: compliance-mode files cannot be deleted until the retention
319
- * expires; governance-mode files require `bypassGovernance: true`
320
- * AND a calling key with the `bypassGovernance` capability. Files on
321
- * legal hold cannot be deleted by anyone until the hold is removed.
322
- *
323
- * @param fileName - The file path of the version to delete.
324
- * @param fileId - The unique identifier of the file version to delete.
325
- * @param options - Optional flag for bypassing governance retention.
326
- */
327
- async deleteFileVersion(fileName, fileId, options) {
328
- await this.client.raw.deleteFileVersion(
329
- this.client.accountInfo.getApiUrl(),
330
- this.client.accountInfo.getAuthToken(),
331
- {
332
- fileName,
333
- fileId,
334
- ...options?.bypassGovernance !== void 0 ? { bypassGovernance: options.bypassGovernance } : {}
335
- }
336
- );
337
- }
338
- /**
339
- * Cancels an in-progress large file upload so the partial parts are not
340
- * retained or billed. The most common reason to call this is to clean up
341
- * abandoned multipart uploads surfaced by {@link listUnfinishedLargeFiles}.
342
- * @param fileId - The unique identifier of the unfinished large file to cancel.
343
- *
344
- * @returns Metadata about the cancelled large file.
345
- */
346
- async cancelLargeFile(fileId) {
347
- return this.client.raw.cancelLargeFile(
348
- this.client.accountInfo.getApiUrl(),
349
- this.client.accountInfo.getAuthToken(),
350
- { fileId }
351
- );
352
- }
353
- /**
354
- * Lists large files in this bucket that were started but never finished or
355
- * cancelled. Wraps `b2_list_unfinished_large_files`.
356
- * @param options - Optional pagination filters.
357
- *
358
- * @returns The page of unfinished large files plus a continuation token.
359
- */
360
- async listUnfinishedLargeFiles(options) {
361
- return this.client.raw.listUnfinishedLargeFiles(
362
- this.client.accountInfo.getApiUrl(),
363
- this.client.accountInfo.getAuthToken(),
364
- {
365
- bucketId: this.id,
366
- ...options?.namePrefix !== void 0 ? { namePrefix: options.namePrefix } : {},
367
- ...options?.startFileId !== void 0 ? { startFileId: options.startFileId } : {},
368
- ...options?.pageSize !== void 0 ? { maxFileCount: options.pageSize } : {}
369
- }
370
- );
371
- }
372
- /**
373
- * Deletes many file versions with bounded concurrency. Errors from individual
374
- * deletes are collected and returned rather than thrown, so partial success
375
- * does not abort the run.
376
- *
377
- * When `options.signal` is supplied and aborted, in-flight deletes
378
- * complete (they're already on the wire), but no new deletes start
379
- * after the abort fires. Subsequent targets are short-circuited to an
380
- * error entry so the result tally reflects what actually happened.
381
- * @param targets - File versions to delete.
382
- * @param options - Optional concurrency override and abort signal.
383
- * Concurrency defaults to the SDK-wide bulk-metadata setting
384
- * (currently 10, higher than transfer concurrency because each
385
- * task is a single tiny API round-trip).
386
- *
387
- * @returns A summary of successes and per-target errors.
388
- */
389
- async deleteMany(targets, options) {
390
- const concurrency = options?.concurrency ?? DEFAULT_BULK_CONCURRENCY;
391
- const sem = new Semaphore(concurrency);
392
- const signal = options?.signal;
393
- let deleted = 0;
394
- const errors = [];
395
- await Promise.all(
396
- targets.map(async (target) => {
397
- await sem.acquire();
398
- try {
399
- if (signal?.aborted) {
400
- errors.push({
401
- target,
402
- error: toError(signal.reason ?? "aborted")
403
- });
404
- return;
405
- }
406
- await this.deleteFileVersion(target.fileName, target.fileId);
407
- deleted++;
408
- } catch (err) {
409
- errors.push({
410
- target,
411
- error: toError(err)
412
- });
413
- } finally {
414
- sem.release();
415
- }
416
- })
417
- );
418
- return { deleted, errors };
419
- }
420
- /**
421
- * Async generator that streams every file version in the bucket (optionally
422
- * filtered by prefix) and deletes each one. Yields a {@link DeleteAllEvent}
423
- * per file version. With `dryRun: true`, no deletes are performed but `skip`
424
- * events are still emitted.
425
- * @param options - Optional prefix filter, page size, and dry-run flag.
426
- *
427
- * @returns An async generator of per-file events.
428
- */
429
- async *deleteAll(options) {
430
- const dryRun = options?.dryRun ?? false;
431
- const pageSize = options?.pageSize ?? DEFAULT_PAGE_SIZE;
432
- let startFileName;
433
- let startFileId;
434
- while (true) {
435
- const page = await this.listFileVersions({
436
- pageSize,
437
- ...options?.prefix !== void 0 ? { prefix: options.prefix } : {},
438
- ...startFileName !== void 0 ? { startFileName } : {},
439
- ...startFileId !== void 0 ? { startFileId } : {}
440
- });
441
- for (const version of page.files) {
442
- if (dryRun) {
443
- yield { type: "skip", fileName: version.fileName, fileId: version.fileId };
444
- continue;
445
- }
446
- try {
447
- await this.deleteFileVersion(version.fileName, version.fileId);
448
- yield { type: "delete", fileName: version.fileName, fileId: version.fileId };
449
- } catch (err) {
450
- yield {
451
- type: "error",
452
- fileName: version.fileName,
453
- fileId: version.fileId,
454
- message: toError(err).message
455
- };
456
- }
457
- }
458
- if (!page.nextFileName) break;
459
- startFileName = page.nextFileName;
460
- startFileId = page.nextFileId ?? void 0;
461
- }
462
- }
463
- /**
464
- * Creates a server-side copy of a file within or across buckets.
465
- * @param options - Copy configuration including source file ID and destination name.
466
- *
467
- * @returns Metadata for the newly created file version.
468
- */
469
- async copyFile(options) {
470
- return this.client.raw.copyFile(
471
- this.client.accountInfo.getApiUrl(),
472
- this.client.accountInfo.getAuthToken(),
473
- options
474
- );
475
- }
476
- /**
477
- * Copies a file via the server-side multipart protocol. Each part is copied
478
- * by reference through `b2_copy_part`; data never traverses the client. Falls
479
- * back to a single `copyFile` call when the source fits within a single part.
480
- * @param options - Copy parameters including source file ID, destination name, part size, and concurrency.
481
- *
482
- * @returns Metadata for the newly created destination file version.
483
- */
484
- async copyLargeFile(options) {
485
- return copyLargeFile(this.client.raw, this.client.accountInfo, {
486
- sourceFileId: options.sourceFileId,
487
- fileName: options.fileName,
488
- ...options.destinationBucketId !== void 0 ? { destinationBucketId: options.destinationBucketId } : { destinationBucketId: this.id },
489
- ...options.contentType !== void 0 ? { contentType: options.contentType } : {},
490
- ...options.fileInfo !== void 0 ? { fileInfo: options.fileInfo } : {},
491
- ...options.destinationServerSideEncryption !== void 0 ? { destinationServerSideEncryption: options.destinationServerSideEncryption } : {},
492
- ...options.sourceServerSideEncryption !== void 0 ? { sourceServerSideEncryption: options.sourceServerSideEncryption } : {},
493
- ...options.partSize !== void 0 ? { partSize: options.partSize } : {},
494
- ...options.concurrency !== void 0 ? { concurrency: options.concurrency } : {},
495
- ...options.signal !== void 0 ? { signal: options.signal } : {}
496
- });
497
- }
498
- /**
499
- * Updates bucket settings such as type, CORS, lifecycle rules, and encryption.
500
- * @param options - Fields to update. Omitted fields are left unchanged.
501
- *
502
- * @returns Updated bucket metadata.
503
- */
504
- async update(options) {
505
- return this.client.raw.updateBucket(
506
- this.client.accountInfo.getApiUrl(),
507
- this.client.accountInfo.getAuthToken(),
508
- {
509
- accountId: accountId(this.client.accountInfo.getAccountId()),
510
- bucketId: this.id,
511
- ...options
512
- }
513
- );
514
- }
515
- /**
516
- * Permanently deletes this bucket. The bucket must be empty (no file versions).
517
- *
518
- * @returns The deleted bucket metadata.
519
- */
520
- async delete() {
521
- return this.client.deleteBucket(this.id);
522
- }
523
- /**
524
- * Gets a download authorization token scoped to a file name prefix in this bucket.
525
- * @param fileNamePrefix - Only authorize downloads of files starting with this prefix.
526
- * @param validDurationInSeconds - How long the authorization is valid (1-604800 seconds).
527
- *
528
- * @returns The download authorization response containing a time-limited token.
529
- */
530
- async getDownloadAuthorization(fileNamePrefix, validDurationInSeconds) {
531
- return this.client.raw.getDownloadAuthorization(
532
- this.client.accountInfo.getApiUrl(),
533
- this.client.accountInfo.getAuthToken(),
534
- { bucketId: this.id, fileNamePrefix, validDurationInSeconds }
535
- );
536
- }
537
- /**
538
- * Gets the event notification rules configured for this bucket.
539
- *
540
- * @returns The current notification rules for this bucket.
541
- */
542
- async getNotificationRules() {
543
- return this.client.raw.getBucketNotificationRules(
544
- this.client.accountInfo.getApiUrl(),
545
- this.client.accountInfo.getAuthToken(),
546
- { bucketId: this.id }
547
- );
548
- }
549
- /**
550
- * Replaces the event notification rules for this bucket.
551
- * @param rules - The new set of notification rules to apply.
552
- *
553
- * @returns The updated notification rules for this bucket.
554
- */
555
- async setNotificationRules(rules) {
556
- return this.client.raw.setBucketNotificationRules(
557
- this.client.accountInfo.getApiUrl(),
558
- this.client.accountInfo.getAuthToken(),
559
- { bucketId: this.id, eventNotificationRules: rules }
560
- );
561
- }
562
- /**
563
- * Updates the file retention policy for a specific file version. Requires file lock on the bucket.
564
- * @param fileName - The file path of the version to update.
565
- * @param fileId - The unique identifier of the file version.
566
- * @param retention - The new retention policy to apply.
567
- * @param options - Optional flags. Set `bypassGovernance: true` to shorten governance-mode retention.
568
- *
569
- * @returns The updated file retention metadata.
570
- */
571
- async updateFileRetention(fileName, fileId, retention, options) {
572
- return this.client.raw.updateFileRetention(
573
- this.client.accountInfo.getApiUrl(),
574
- this.client.accountInfo.getAuthToken(),
575
- {
576
- fileName,
577
- fileId,
578
- fileRetention: retention,
579
- ...options?.bypassGovernance !== void 0 ? { bypassGovernance: options.bypassGovernance } : {}
580
- }
581
- );
582
- }
583
- /**
584
- * Updates the legal hold status for a specific file version. Requires file lock on the bucket.
585
- * @param fileName - The file path of the version to update.
586
- * @param fileId - The unique identifier of the file version.
587
- * @param legalHold - The new legal hold status to apply.
588
- *
589
- * @returns The updated legal hold metadata.
590
- */
591
- async updateFileLegalHold(fileName, fileId, legalHold) {
592
- return this.client.raw.updateFileLegalHold(
593
- this.client.accountInfo.getApiUrl(),
594
- this.client.accountInfo.getAuthToken(),
595
- { fileName, fileId, legalHold }
596
- );
597
- }
598
- /**
599
- * Refetches this bucket's metadata from B2 so callers operating on
600
- * replication / lifecycle / retention configuration always start from the
601
- * server-of-record state.
602
- *
603
- * Bucket configuration is monotonically revisioned by B2: B2 increments
604
- * `revision` on every accepted update. The local {@link info} snapshot
605
- * captured at construction time goes stale as soon as anyone else (or any
606
- * prior `update()` call) mutates the bucket, so the ergonomic
607
- * add/remove helpers below always refresh before composing the next
608
- * `setX()` call. The result is that each helper is safe to call without
609
- * the caller having to thread BucketInfo through their code.
610
- *
611
- * @returns Fresh {@link BucketInfo} for this bucket.
612
- *
613
- * @throws If the bucket no longer exists.
614
- */
615
- async refresh() {
616
- const fresh = await this.client.listBuckets({ bucketId: this.id });
617
- const found = fresh[0];
618
- if (!found) throw new Error(`Bucket ${this.id} not found`);
619
- return found.info;
620
- }
621
- /**
622
- * Returns the current cross-region replication configuration, refetched
623
- * from B2.
624
- *
625
- * Use this when you need to read replication state without composing a
626
- * write. For add/remove flows the helper methods below handle the
627
- * refresh-then-set sequence for you.
628
- *
629
- * @returns The current {@link ReplicationConfiguration}.
630
- */
631
- async getReplication() {
632
- const fresh = await this.refresh();
633
- return fresh.replicationConfiguration;
634
- }
635
- /**
636
- * Replaces this bucket's complete replication configuration.
637
- * @param replication - The new configuration. Pass an empty source/destination
638
- * pair (`{ asReplicationSource: null, asReplicationDestination: null }`)
639
- * to clear replication entirely.
640
- *
641
- * @returns The updated bucket metadata.
642
- */
643
- async setReplication(replication) {
644
- return this.update({ replicationConfiguration: replication });
645
- }
646
- /**
647
- * Adds (or replaces by `replicationRuleName`) a single replication rule
648
- * on this bucket while leaving any other rules, the source key, and the
649
- * destination key mapping untouched.
650
- *
651
- * When this is the very first source-side rule, `sourceApplicationKeyId`
652
- * must be supplied to seed `asReplicationSource.sourceApplicationKeyId`;
653
- * for subsequent calls the existing source key is reused unless the
654
- * caller explicitly overrides it.
655
- *
656
- * @param rule - The replication rule to add or replace.
657
- * @param options - Optional source application key ID override (or seed
658
- * when no source side exists yet).
659
- *
660
- * @returns The updated bucket metadata.
661
- *
662
- * @throws If no source-side replication exists yet and the caller did
663
- * not supply `sourceApplicationKeyId`.
664
- */
665
- async addReplicationRule(rule, options) {
666
- const current = (await this.refresh()).replicationConfiguration;
667
- const existingSource = current.asReplicationSource;
668
- const sourceKey = options?.sourceApplicationKeyId ?? existingSource?.sourceApplicationKeyId;
669
- if (!sourceKey) {
670
- throw new Error(
671
- "addReplicationRule: no existing source-side replication; pass options.sourceApplicationKeyId"
672
- );
673
- }
674
- const existingRules = existingSource?.replicationRules ?? [];
675
- const without = existingRules.filter((r) => r.replicationRuleName !== rule.replicationRuleName);
676
- return this.setReplication({
677
- asReplicationSource: {
678
- sourceApplicationKeyId: sourceKey,
679
- replicationRules: [...without, rule]
680
- },
681
- asReplicationDestination: current.asReplicationDestination
682
- });
683
- }
684
- /**
685
- * Removes a single replication rule by name. No-ops cleanly when the rule
686
- * is not present (returns the unchanged-but-revision-bumped bucket info).
687
- *
688
- * @param replicationRuleName - Name of the rule to remove.
689
- *
690
- * @returns The updated bucket metadata.
691
- */
692
- async removeReplicationRule(replicationRuleName) {
693
- const current = (await this.refresh()).replicationConfiguration;
694
- const existingSource = current.asReplicationSource;
695
- if (!existingSource) {
696
- return this.setReplication(current);
697
- }
698
- const filtered = existingSource.replicationRules.filter(
699
- (r) => r.replicationRuleName !== replicationRuleName
700
- );
701
- return this.setReplication({
702
- asReplicationSource: {
703
- sourceApplicationKeyId: existingSource.sourceApplicationKeyId,
704
- replicationRules: filtered
705
- },
706
- asReplicationDestination: current.asReplicationDestination
707
- });
708
- }
709
- /**
710
- * Returns the current lifecycle rules for this bucket, refetched from B2.
711
- *
712
- * @returns The current array of {@link LifecycleRule}s.
713
- */
714
- async getLifecycleRules() {
715
- const fresh = await this.refresh();
716
- return fresh.lifecycleRules;
717
- }
718
- /**
719
- * Replaces this bucket's lifecycle rules in their entirety.
720
- * @param rules - The new rule set. Pass `[]` to remove all lifecycle
721
- * automation.
722
- *
723
- * @returns The updated bucket metadata.
724
- */
725
- async setLifecycleRules(rules) {
726
- return this.update({ lifecycleRules: [...rules] });
727
- }
728
- /**
729
- * Adds (or replaces, matched by `fileNamePrefix`) a single lifecycle rule
730
- * while leaving any other rules untouched.
731
- *
732
- * Matching on prefix mirrors B2's own data model: each unique prefix can
733
- * have at most one rule, and a `b2_update_bucket` call that contains two
734
- * rules with the same prefix is rejected. The helper enforces this for
735
- * the caller.
736
- *
737
- * @param rule - The lifecycle rule to add or replace.
738
- *
739
- * @returns The updated bucket metadata.
740
- */
741
- async addLifecycleRule(rule) {
742
- const current = await this.getLifecycleRules();
743
- const without = current.filter((r) => r.fileNamePrefix !== rule.fileNamePrefix);
744
- return this.setLifecycleRules([...without, rule]);
745
- }
746
- /**
747
- * Removes a single lifecycle rule by prefix. No-ops cleanly when the rule
748
- * is not present.
749
- *
750
- * @param fileNamePrefix - The prefix of the rule to remove.
751
- *
752
- * @returns The updated bucket metadata.
753
- */
754
- async removeLifecycleRule(fileNamePrefix) {
755
- const current = await this.getLifecycleRules();
756
- return this.setLifecycleRules(current.filter((r) => r.fileNamePrefix !== fileNamePrefix));
757
- }
758
- /**
759
- * Returns the current default Object Lock retention policy for new
760
- * uploads to this bucket, refetched from B2.
761
- *
762
- * @returns The default {@link BucketRetentionPolicy} (which may be
763
- * `{ mode: 'none', period: null }` when Object Lock is enabled on the
764
- * bucket but no default is set).
765
- */
766
- async getDefaultRetention() {
767
- const fresh = await this.refresh();
768
- return fresh.defaultRetention;
769
- }
770
- /**
771
- * Sets (or clears, by passing `{ mode: 'none', period: null }`) the
772
- * default Object Lock retention policy applied to new uploads.
773
- *
774
- * Object Lock must already be enabled on the bucket. Buckets created
775
- * without `fileLockEnabled: true` cannot accept a default retention
776
- * policy and B2 will reject this call.
777
- *
778
- * @param policy - The new default retention policy.
779
- *
780
- * @returns The updated bucket metadata.
781
- */
782
- async setDefaultRetention(policy) {
783
- return this.update({ defaultRetention: policy });
784
- }
11
+ import { B2Object } from "./object.js";
12
+ import { paginateItems } from "./util/paginator.js";
13
+ //#region src/bucket.ts
14
+ function bucketDefaultRetentionSnapshot(info) {
15
+ const fileLock = info.fileLockConfiguration;
16
+ if (!fileLock.isClientAuthorizedToRead) return { unreadable: true };
17
+ if (fileLock.value === null) return { unreadable: false };
18
+ return {
19
+ retention: fileLock.value.defaultRetention,
20
+ unreadable: false
21
+ };
22
+ }
23
+ function resumeNeedsFreshBucketDefaults(options) {
24
+ return (options.resume === true || options.resumeFileId !== void 0) && (options.serverSideEncryption === void 0 || options.fileRetention === void 0);
785
25
  }
786
- export {
787
- Bucket
26
+ /**
27
+ * Handle to a B2 bucket providing upload, download, listing, and management operations.
28
+ *
29
+ * Obtained via {@link B2Client.createBucket}, {@link B2Client.listBuckets}, or {@link B2Client.getBucket}.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * const bucket = await client.getBucket('my-bucket')
34
+ * await bucket.upload({ fileName: 'hello.txt', source: new BufferSource(data) })
35
+ * ```
36
+ */
37
+ var Bucket = class {
38
+ /** Unique identifier for this bucket. */
39
+ id;
40
+ /** Human-readable bucket name. */
41
+ name;
42
+ /** Full bucket metadata as returned by the B2 API. */
43
+ info;
44
+ client;
45
+ uploadRetryOptions;
46
+ /**
47
+ * @param client - The parent B2Client instance.
48
+ * @param info - The bucket metadata from the API.
49
+ * @param uploadRetryOptions - Resolved client upload retry defaults.
50
+ *
51
+ * @internal
52
+ */
53
+ constructor(client, info, uploadRetryOptions) {
54
+ this.client = client;
55
+ this.info = info;
56
+ this.id = info.bucketId;
57
+ this.name = info.bucketName;
58
+ this.uploadRetryOptions = uploadRetryOptions;
59
+ }
60
+ /**
61
+ * Returns a {@link B2Object} handle for a specific file name in this bucket.
62
+ * @param fileName - The file path within the bucket.
63
+ *
64
+ * @returns A B2Object handle bound to this bucket and file name.
65
+ */
66
+ file(fileName) {
67
+ return new B2Object(this.client, this, fileName, this.uploadRetryOptions);
68
+ }
69
+ /**
70
+ * Uploads a file to this bucket. Automatically uses multipart upload for files
71
+ * larger than the recommended part size.
72
+ * @param options - Upload configuration including file name, source data, and optional settings.
73
+ *
74
+ * @returns Metadata for the uploaded file version.
75
+ */
76
+ async upload(options) {
77
+ const recommendedPartSize = this.client.accountInfo.getRecommendedPartSize();
78
+ const isLarge = options.source.size > recommendedPartSize;
79
+ const uploadRetryOptions = mergeUploadRetryOptions(this.uploadRetryOptions, options.retry);
80
+ if (isLarge) {
81
+ const bucketInfo = resumeNeedsFreshBucketDefaults(options) ? await this.refresh() : this.info;
82
+ const bucketDefaultRetention = bucketDefaultRetentionSnapshot(bucketInfo);
83
+ return uploadLargeFile(this.client.raw, this.client.accountInfo, {
84
+ ...options,
85
+ bucketId: this.id,
86
+ retry: uploadRetryOptions,
87
+ bucketDefaultServerSideEncryption: bucketInfo.defaultServerSideEncryption,
88
+ ...bucketDefaultRetention.retention !== void 0 ? { bucketDefaultRetention: bucketDefaultRetention.retention } : {},
89
+ ...bucketDefaultRetention.unreadable ? { bucketDefaultRetentionUnreadable: true } : {}
90
+ });
91
+ }
92
+ rejectSmallResumeFileId(options, "Bucket.upload");
93
+ const smallOptions = stripResumeOnlyOptions(options);
94
+ return uploadSmallFile(this.client.raw, this.client.accountInfo, {
95
+ ...smallOptions,
96
+ bucketId: this.id,
97
+ retry: uploadRetryOptions
98
+ });
99
+ }
100
+ /**
101
+ * Downloads a file from this bucket by name. Pass `method: 'HEAD'` in
102
+ * `options` to fetch only the response headers (file metadata) without
103
+ * streaming the body.
104
+ * @param fileName - The file name (path) to download.
105
+ * @param options - Optional method, range, SSE-C decryption, response-header overrides, and abort signal.
106
+ *
107
+ * @returns The download result containing response headers and a readable body stream.
108
+ */
109
+ async download(fileName, options) {
110
+ return downloadByName(this.client.raw, this.client.accountInfo, {
111
+ bucketName: this.name,
112
+ fileName,
113
+ ...options
114
+ });
115
+ }
116
+ /**
117
+ * Fetches the response headers (file metadata) for a file via HTTP
118
+ * HEAD. Returns a body-less result so callers never have to drain
119
+ * the (logically empty) HEAD body themselves.
120
+ *
121
+ * Use this for metadata-only checks like "does this file exist", "what
122
+ * is its current SHA-1", "what is its Content-Length". For full file
123
+ * retrieval use {@link Bucket.download}.
124
+ *
125
+ * @param fileName - The file name (path) to inspect.
126
+ * @param options - Optional range, SSE-C decryption, response-header
127
+ * overrides, and abort signal. Same shape as {@link Bucket.download}'s
128
+ * options minus `method` (always HEAD) and `onProgress` (no body).
129
+ *
130
+ * @returns Parsed download headers (content type, SHA-1, file info, etc.).
131
+ *
132
+ * @example
133
+ * ```ts
134
+ * const { headers } = await bucket.head('photos/2026/sunset.jpg')
135
+ * console.log(headers.contentLength, headers.contentSha1)
136
+ * ```
137
+ */
138
+ async head(fileName, options) {
139
+ return headByName(this.client.raw, this.client.accountInfo, {
140
+ bucketName: this.name,
141
+ fileName,
142
+ ...options
143
+ });
144
+ }
145
+ /**
146
+ * Lists file names in this bucket (most recent versions only).
147
+ * @param options - Optional filtering and pagination settings.
148
+ *
149
+ * @returns A page of file versions with an optional continuation token.
150
+ */
151
+ async listFileNames(options) {
152
+ return this.client.raw.listFileNames(this.client.accountInfo.getApiUrl(), this.client.accountInfo.getAuthToken(), {
153
+ bucketId: this.id,
154
+ ...options?.startFileName !== void 0 ? { startFileName: options.startFileName } : {},
155
+ ...options?.pageSize !== void 0 ? { maxFileCount: options.pageSize } : {},
156
+ ...options?.prefix !== void 0 ? { prefix: options.prefix } : {},
157
+ ...options?.delimiter !== void 0 ? { delimiter: options.delimiter } : {}
158
+ }, { ...options?.signal !== void 0 ? { signal: options.signal } : {} });
159
+ }
160
+ /**
161
+ * Lists all file versions in this bucket, including hidden files.
162
+ * @param options - Optional filtering and pagination settings.
163
+ *
164
+ * @returns A page of file versions with an optional continuation token.
165
+ */
166
+ async listFileVersions(options) {
167
+ return this.client.raw.listFileVersions(this.client.accountInfo.getApiUrl(), this.client.accountInfo.getAuthToken(), {
168
+ bucketId: this.id,
169
+ ...options?.startFileName !== void 0 ? { startFileName: options.startFileName } : {},
170
+ ...options?.startFileId !== void 0 ? { startFileId: options.startFileId } : {},
171
+ ...options?.pageSize !== void 0 ? { maxFileCount: options.pageSize } : {},
172
+ ...options?.prefix !== void 0 ? { prefix: options.prefix } : {},
173
+ ...options?.delimiter !== void 0 ? { delimiter: options.delimiter } : {}
174
+ }, { ...options?.signal !== void 0 ? { signal: options.signal } : {} });
175
+ }
176
+ /**
177
+ * Async iterator that yields the latest visible version of every file in
178
+ * the bucket, automatically handling pagination via `listFileNames`.
179
+ *
180
+ * Hidden files (those whose latest version is a hide marker) are NOT
181
+ * yielded by this iterator. Use {@link paginateFileVersions} when you
182
+ * need full version history.
183
+ *
184
+ * @param options - Filter + pagination + abort options. `pageSize` is
185
+ * forwarded to `b2_list_file_names`'s `maxFileCount` (default 1000,
186
+ * B2-capped at 10000).
187
+ *
188
+ * @returns An async iterable of {@link FileVersion} entries.
189
+ *
190
+ * @example
191
+ * ```ts
192
+ * for await (const file of bucket.paginateFileNames({ prefix: 'photos/' })) {
193
+ * console.log(file.fileName, file.contentLength)
194
+ * }
195
+ * ```
196
+ */
197
+ paginateFileNames(options) {
198
+ return paginateItems(async (cursor) => {
199
+ const resp = await this.listFileNames({
200
+ pageSize: options?.pageSize ?? 1e3,
201
+ ...cursor !== void 0 ? { startFileName: cursor } : {},
202
+ ...options?.prefix !== void 0 ? { prefix: options.prefix } : {},
203
+ ...options?.delimiter !== void 0 ? { delimiter: options.delimiter } : {},
204
+ ...options?.signal !== void 0 ? { signal: options.signal } : {}
205
+ });
206
+ return {
207
+ page: resp,
208
+ nextCursor: resp.nextFileName ?? void 0
209
+ };
210
+ }, (page) => page.files.filter((f) => f.action !== "hide"), options?.signal);
211
+ }
212
+ /**
213
+ * Async iterator that yields every version of every file in the bucket,
214
+ * including hidden files and historical versions, automatically handling
215
+ * pagination via `listFileVersions`.
216
+ *
217
+ * The two-cursor `(nextFileName, nextFileId)` continuation that the raw
218
+ * endpoint exposes is threaded internally; callers iterate flat.
219
+ *
220
+ * @param options - Filter + pagination + abort options.
221
+ *
222
+ * @returns An async iterable of {@link FileVersion} entries.
223
+ */
224
+ paginateFileVersions(options) {
225
+ return paginateItems(async (cursor) => {
226
+ const resp = await this.listFileVersions({
227
+ pageSize: options?.pageSize ?? 1e3,
228
+ ...cursor !== void 0 ? { startFileName: cursor.fileName } : {},
229
+ ...cursor?.fileId !== void 0 ? { startFileId: cursor.fileId } : {},
230
+ ...options?.prefix !== void 0 ? { prefix: options.prefix } : {},
231
+ ...options?.delimiter !== void 0 ? { delimiter: options.delimiter } : {},
232
+ ...options?.signal !== void 0 ? { signal: options.signal } : {}
233
+ });
234
+ return {
235
+ page: resp,
236
+ nextCursor: resp.nextFileName !== null ? {
237
+ fileName: resp.nextFileName,
238
+ fileId: resp.nextFileId ?? void 0
239
+ } : void 0
240
+ };
241
+ }, (page) => page.files, options?.signal);
242
+ }
243
+ /**
244
+ * Async iterator that yields every unfinished large file in the bucket,
245
+ * automatically handling pagination via `listUnfinishedLargeFiles`.
246
+ *
247
+ * Useful for janitorial scripts that want to inspect or cancel abandoned
248
+ * multipart uploads (typically followed by {@link cancelLargeFile} on
249
+ * the underlying raw client).
250
+ *
251
+ * @param options - Filter + pagination + abort options. `pageSize` is
252
+ * B2-capped at 100 for this endpoint.
253
+ *
254
+ * @returns An async iterable of unfinished-large-file metadata entries.
255
+ */
256
+ paginateUnfinishedLargeFiles(options) {
257
+ return paginateItems(async (cursor) => {
258
+ const resp = await this.listUnfinishedLargeFiles({
259
+ pageSize: options?.pageSize ?? 100,
260
+ ...cursor !== void 0 ? { startFileId: cursor } : {},
261
+ ...options?.namePrefix !== void 0 ? { namePrefix: options.namePrefix } : {},
262
+ ...options?.signal !== void 0 ? { signal: options.signal } : {}
263
+ });
264
+ return {
265
+ page: resp,
266
+ nextCursor: resp.nextFileId ?? void 0
267
+ };
268
+ }, (page) => page.files, options?.signal);
269
+ }
270
+ /**
271
+ * Async iterator that yields every uploaded part for a specific large
272
+ * file, automatically handling pagination via `listParts`.
273
+ *
274
+ * @param largeFileId - The unfinished large file to enumerate parts of.
275
+ * @param options - Pagination + abort options. `pageSize` is B2-capped
276
+ * at 1000 for this endpoint; the default is 1000.
277
+ *
278
+ * @returns An async iterable of {@link PartInfo} entries.
279
+ */
280
+ paginateParts(largeFileId, options) {
281
+ return paginateItems(async (cursor) => {
282
+ const resp = await this.client.raw.listParts(this.client.accountInfo.getApiUrl(), this.client.accountInfo.getAuthToken(), {
283
+ fileId: largeFileId,
284
+ maxPartCount: options?.pageSize ?? 1e3,
285
+ ...cursor !== void 0 ? { startPartNumber: cursor } : {}
286
+ }, options?.signal !== void 0 ? { signal: options.signal } : void 0);
287
+ return {
288
+ page: resp,
289
+ nextCursor: resp.nextPartNumber ?? void 0
290
+ };
291
+ }, (page) => page.parts, options?.signal);
292
+ }
293
+ /**
294
+ * Looks up the latest visible version of a file by name.
295
+ * Uses `listFileNames` under the hood; returns `null` when the file does not
296
+ * exist or its latest version is a hide marker.
297
+ * @param fileName - The exact file path to look up.
298
+ *
299
+ * @returns The latest {@link FileVersion}, or `null` if not found.
300
+ */
301
+ async getFileInfoByName(fileName) {
302
+ const match = (await this.listFileNames({
303
+ prefix: fileName,
304
+ pageSize: 1
305
+ })).files.find((f) => f.fileName === fileName);
306
+ if (!match || match.action === "hide") return null;
307
+ return match;
308
+ }
309
+ /**
310
+ * Removes the latest hide marker for a file, restoring visibility of the
311
+ * previous upload. Returns the deleted hide marker, or `null` if there was
312
+ * no hide marker to remove (file is already visible or does not exist).
313
+ * @param fileName - The file path to unhide.
314
+ *
315
+ * @returns The deleted hide marker version, or `null` if nothing was hidden.
316
+ */
317
+ async unhideFile(fileName) {
318
+ const versions = (await this.listFileVersions({
319
+ prefix: fileName,
320
+ pageSize: 100
321
+ })).files.filter((f) => f.fileName === fileName);
322
+ if (versions.length === 0) return null;
323
+ const latest = versions[0];
324
+ if (latest?.action !== "hide") return null;
325
+ await this.deleteFileVersion(fileName, latest.fileId);
326
+ return latest;
327
+ }
328
+ /**
329
+ * Hides a file by creating a hide marker. The file remains in version history but is no longer visible in `listFileNames`.
330
+ * @param fileName - The file path to hide.
331
+ * @param options - Optional request controls such as an abort signal.
332
+ *
333
+ * @returns Metadata for the newly created hide marker.
334
+ */
335
+ async hideFile(fileName, options) {
336
+ return this.client.raw.hideFile(this.client.accountInfo.getApiUrl(), this.client.accountInfo.getAuthToken(), {
337
+ bucketId: this.id,
338
+ fileName
339
+ }, options);
340
+ }
341
+ /**
342
+ * Permanently deletes a specific file version. Both file name and file ID are required.
343
+ *
344
+ * If the file is under Object Lock retention, B2 will reject the
345
+ * delete: compliance-mode files cannot be deleted until the retention
346
+ * expires; governance-mode files require `bypassGovernance: true`
347
+ * AND a calling key with the `bypassGovernance` capability. Files on
348
+ * legal hold cannot be deleted by anyone until the hold is removed.
349
+ *
350
+ * @param fileName - The file path of the version to delete.
351
+ * @param fileId - The unique identifier of the file version to delete.
352
+ * @param options - Optional governance and abort controls.
353
+ */
354
+ async deleteFileVersion(fileName, fileId, options) {
355
+ await this.client.raw.deleteFileVersion(this.client.accountInfo.getApiUrl(), this.client.accountInfo.getAuthToken(), {
356
+ fileName,
357
+ fileId,
358
+ ...options?.bypassGovernance !== void 0 ? { bypassGovernance: options.bypassGovernance } : {}
359
+ }, options?.signal !== void 0 ? { signal: options.signal } : void 0);
360
+ }
361
+ /**
362
+ * Cancels an in-progress large file upload so the partial parts are not
363
+ * retained or billed. The most common reason to call this is to clean up
364
+ * abandoned multipart uploads surfaced by {@link listUnfinishedLargeFiles}.
365
+ * @param fileId - The unique identifier of the unfinished large file to cancel.
366
+ *
367
+ * @returns Metadata about the cancelled large file.
368
+ */
369
+ async cancelLargeFile(fileId) {
370
+ return this.client.raw.cancelLargeFile(this.client.accountInfo.getApiUrl(), this.client.accountInfo.getAuthToken(), { fileId });
371
+ }
372
+ /**
373
+ * Lists large files in this bucket that were started but never finished or
374
+ * cancelled. Wraps `b2_list_unfinished_large_files`.
375
+ * @param options - Optional pagination filters.
376
+ *
377
+ * @returns The page of unfinished large files plus a continuation token.
378
+ */
379
+ async listUnfinishedLargeFiles(options) {
380
+ return this.client.raw.listUnfinishedLargeFiles(this.client.accountInfo.getApiUrl(), this.client.accountInfo.getAuthToken(), {
381
+ bucketId: this.id,
382
+ ...options?.namePrefix !== void 0 ? { namePrefix: options.namePrefix } : {},
383
+ ...options?.startFileId !== void 0 ? { startFileId: options.startFileId } : {},
384
+ ...options?.pageSize !== void 0 ? { maxFileCount: options.pageSize } : {}
385
+ }, options?.signal !== void 0 ? { signal: options.signal } : void 0);
386
+ }
387
+ /**
388
+ * Deletes many file versions with bounded concurrency. Errors from individual
389
+ * deletes are collected and returned rather than thrown, so partial success
390
+ * does not abort the run.
391
+ *
392
+ * When `options.signal` is supplied and aborted, in-flight deletes
393
+ * complete (they're already on the wire), but no new deletes start
394
+ * after the abort fires. Subsequent targets are short-circuited to an
395
+ * error entry so the result tally reflects what actually happened.
396
+ * @param targets - File versions to delete.
397
+ * @param options - Optional concurrency override and abort signal.
398
+ * Concurrency defaults to the SDK-wide bulk-metadata setting
399
+ * (currently 10, higher than transfer concurrency because each
400
+ * task is a single tiny API round-trip).
401
+ *
402
+ * @returns A summary of successes and per-target errors.
403
+ */
404
+ async deleteMany(targets, options) {
405
+ const sem = new Semaphore(options?.concurrency ?? 10);
406
+ const signal = options?.signal;
407
+ let deleted = 0;
408
+ const errors = [];
409
+ await Promise.all(targets.map(async (target) => {
410
+ await sem.acquire();
411
+ try {
412
+ if (signal?.aborted) {
413
+ errors.push({
414
+ target,
415
+ error: toError(signal.reason ?? "aborted")
416
+ });
417
+ return;
418
+ }
419
+ await this.deleteFileVersion(target.fileName, target.fileId);
420
+ deleted++;
421
+ } catch (err) {
422
+ errors.push({
423
+ target,
424
+ error: toError(err)
425
+ });
426
+ } finally {
427
+ sem.release();
428
+ }
429
+ }));
430
+ return {
431
+ deleted,
432
+ errors
433
+ };
434
+ }
435
+ /**
436
+ * Async generator that streams every file version in the bucket (optionally
437
+ * filtered by prefix) and deletes each one. Yields a {@link DeleteAllEvent}
438
+ * per file version. With `dryRun: true`, no deletes are performed but `skip`
439
+ * events are still emitted.
440
+ * @param options - Optional prefix filter, page size, and dry-run flag.
441
+ *
442
+ * @returns An async generator of per-file events.
443
+ */
444
+ async *deleteAll(options) {
445
+ const dryRun = options?.dryRun ?? false;
446
+ const pageSize = options?.pageSize ?? 1e3;
447
+ let startFileName;
448
+ let startFileId;
449
+ while (true) {
450
+ const page = await this.listFileVersions({
451
+ pageSize,
452
+ ...options?.prefix !== void 0 ? { prefix: options.prefix } : {},
453
+ ...startFileName !== void 0 ? { startFileName } : {},
454
+ ...startFileId !== void 0 ? { startFileId } : {}
455
+ });
456
+ for (const version of page.files) {
457
+ if (dryRun) {
458
+ yield {
459
+ type: "skip",
460
+ fileName: version.fileName,
461
+ fileId: version.fileId
462
+ };
463
+ continue;
464
+ }
465
+ try {
466
+ await this.deleteFileVersion(version.fileName, version.fileId);
467
+ yield {
468
+ type: "delete",
469
+ fileName: version.fileName,
470
+ fileId: version.fileId
471
+ };
472
+ } catch (err) {
473
+ yield {
474
+ type: "error",
475
+ fileName: version.fileName,
476
+ fileId: version.fileId,
477
+ message: toError(err).message
478
+ };
479
+ }
480
+ }
481
+ if (!page.nextFileName) break;
482
+ startFileName = page.nextFileName;
483
+ startFileId = page.nextFileId ?? void 0;
484
+ }
485
+ }
486
+ /**
487
+ * Creates a server-side copy of a file within or across buckets.
488
+ * @param options - Copy configuration including source file ID and destination name.
489
+ *
490
+ * @returns Metadata for the newly created file version.
491
+ */
492
+ async copyFile(options) {
493
+ const { serverSideEncryption, destinationServerSideEncryption, signal, ...copyOptions } = options;
494
+ const destinationEncryption = destinationServerSideEncryption ?? serverSideEncryption;
495
+ return this.client.raw.copyFile(this.client.accountInfo.getApiUrl(), this.client.accountInfo.getAuthToken(), {
496
+ ...copyOptions,
497
+ ...destinationEncryption !== void 0 ? { destinationServerSideEncryption: destinationEncryption } : {}
498
+ }, signal !== void 0 ? { signal } : void 0);
499
+ }
500
+ /**
501
+ * Copies a file via the server-side multipart protocol. Each part is copied
502
+ * by reference through `b2_copy_part`; data never traverses the client. Falls
503
+ * back to a single `copyFile` call when the source fits within a single part.
504
+ * @param options - Copy parameters including source file ID, destination name, part size, and concurrency.
505
+ *
506
+ * @returns Metadata for the newly created destination file version.
507
+ */
508
+ async copyLargeFile(options) {
509
+ return copyLargeFile(this.client.raw, this.client.accountInfo, {
510
+ sourceFileId: options.sourceFileId,
511
+ fileName: options.fileName,
512
+ ...options.destinationBucketId !== void 0 ? { destinationBucketId: options.destinationBucketId } : { destinationBucketId: this.id },
513
+ ...options.contentType !== void 0 ? { contentType: options.contentType } : {},
514
+ ...options.fileInfo !== void 0 ? { fileInfo: options.fileInfo } : {},
515
+ ...options.destinationServerSideEncryption !== void 0 ? { destinationServerSideEncryption: options.destinationServerSideEncryption } : {},
516
+ ...options.sourceServerSideEncryption !== void 0 ? { sourceServerSideEncryption: options.sourceServerSideEncryption } : {},
517
+ ...options.partSize !== void 0 ? { partSize: options.partSize } : {},
518
+ ...options.concurrency !== void 0 ? { concurrency: options.concurrency } : {},
519
+ ...options.onCleanupFailure !== void 0 ? { onCleanupFailure: options.onCleanupFailure } : {},
520
+ ...options.signal !== void 0 ? { signal: options.signal } : {}
521
+ });
522
+ }
523
+ /**
524
+ * Updates bucket settings such as type, CORS, lifecycle rules, and encryption.
525
+ * @param options - Fields to update. Omitted fields are left unchanged.
526
+ *
527
+ * @returns Updated bucket metadata.
528
+ */
529
+ async update(options) {
530
+ return this.client.raw.updateBucket(this.client.accountInfo.getApiUrl(), this.client.accountInfo.getAuthToken(), {
531
+ accountId: accountId(this.client.accountInfo.getAccountId()),
532
+ bucketId: this.id,
533
+ ...options
534
+ });
535
+ }
536
+ /**
537
+ * Permanently deletes this bucket. The bucket must be empty (no file versions).
538
+ *
539
+ * @returns The deleted bucket metadata.
540
+ */
541
+ async delete() {
542
+ return this.client.deleteBucket(this.id);
543
+ }
544
+ /**
545
+ * Gets a download authorization token scoped to a file name prefix in this bucket.
546
+ * @param fileNamePrefix - Only authorize downloads of files starting with this prefix.
547
+ * @param validDurationInSeconds - How long the authorization is valid (1-604800 seconds).
548
+ *
549
+ * @returns The download authorization response containing a time-limited token.
550
+ */
551
+ async getDownloadAuthorization(fileNamePrefix, validDurationInSeconds) {
552
+ return this.client.raw.getDownloadAuthorization(this.client.accountInfo.getApiUrl(), this.client.accountInfo.getAuthToken(), {
553
+ bucketId: this.id,
554
+ fileNamePrefix,
555
+ validDurationInSeconds
556
+ });
557
+ }
558
+ /**
559
+ * Gets the event notification rules configured for this bucket.
560
+ *
561
+ * @returns The current notification rules for this bucket.
562
+ */
563
+ async getNotificationRules() {
564
+ return this.client.raw.getBucketNotificationRules(this.client.accountInfo.getApiUrl(), this.client.accountInfo.getAuthToken(), { bucketId: this.id });
565
+ }
566
+ /**
567
+ * Replaces the event notification rules for this bucket.
568
+ * @param rules - The new set of notification rules to apply.
569
+ *
570
+ * @returns The updated notification rules for this bucket.
571
+ */
572
+ async setNotificationRules(rules) {
573
+ return this.client.raw.setBucketNotificationRules(this.client.accountInfo.getApiUrl(), this.client.accountInfo.getAuthToken(), {
574
+ bucketId: this.id,
575
+ eventNotificationRules: rules
576
+ });
577
+ }
578
+ /**
579
+ * Updates the file retention policy for a specific file version. Requires file lock on the bucket.
580
+ * @param fileName - The file path of the version to update.
581
+ * @param fileId - The unique identifier of the file version.
582
+ * @param retention - The new retention policy to apply.
583
+ * @param options - Optional flags. Set `bypassGovernance: true` to shorten governance-mode retention.
584
+ *
585
+ * @returns The updated file retention metadata.
586
+ */
587
+ async updateFileRetention(fileName, fileId, retention, options) {
588
+ return this.client.raw.updateFileRetention(this.client.accountInfo.getApiUrl(), this.client.accountInfo.getAuthToken(), {
589
+ fileName,
590
+ fileId,
591
+ fileRetention: retention,
592
+ ...options?.bypassGovernance !== void 0 ? { bypassGovernance: options.bypassGovernance } : {}
593
+ });
594
+ }
595
+ /**
596
+ * Updates the legal hold status for a specific file version. Requires file lock on the bucket.
597
+ * @param fileName - The file path of the version to update.
598
+ * @param fileId - The unique identifier of the file version.
599
+ * @param legalHold - The new legal hold status to apply.
600
+ *
601
+ * @returns The updated legal hold metadata.
602
+ */
603
+ async updateFileLegalHold(fileName, fileId, legalHold) {
604
+ return this.client.raw.updateFileLegalHold(this.client.accountInfo.getApiUrl(), this.client.accountInfo.getAuthToken(), {
605
+ fileName,
606
+ fileId,
607
+ legalHold
608
+ });
609
+ }
610
+ /**
611
+ * Refetches this bucket's metadata from B2 so callers operating on
612
+ * replication / lifecycle / retention configuration always start from the
613
+ * server-of-record state.
614
+ *
615
+ * Bucket configuration is monotonically revisioned by B2: B2 increments
616
+ * `revision` on every accepted update. The local {@link info} snapshot
617
+ * captured at construction time goes stale as soon as anyone else (or any
618
+ * prior `update()` call) mutates the bucket, so the ergonomic
619
+ * add/remove helpers below always refresh before composing the next
620
+ * `setX()` call. The result is that each helper is safe to call without
621
+ * the caller having to thread BucketInfo through their code.
622
+ *
623
+ * @returns Fresh {@link BucketInfo} for this bucket.
624
+ *
625
+ * @throws If the bucket no longer exists.
626
+ */
627
+ async refresh() {
628
+ const found = (await this.client.listBuckets({ bucketId: this.id }))[0];
629
+ if (!found) throw new Error(`Bucket ${this.id} not found`);
630
+ return found.info;
631
+ }
632
+ /**
633
+ * Returns the current cross-region replication configuration, refetched
634
+ * from B2.
635
+ *
636
+ * Use this when you need to read replication state without composing a
637
+ * write. For add/remove flows the helper methods below handle the
638
+ * refresh-then-set sequence for you.
639
+ *
640
+ * @returns The current {@link ReplicationConfiguration}.
641
+ */
642
+ async getReplication() {
643
+ return (await this.refresh()).replicationConfiguration;
644
+ }
645
+ /**
646
+ * Replaces this bucket's complete replication configuration.
647
+ * @param replication - The new configuration. Pass an empty source/destination
648
+ * pair (`{ asReplicationSource: null, asReplicationDestination: null }`)
649
+ * to clear replication entirely.
650
+ *
651
+ * @returns The updated bucket metadata.
652
+ */
653
+ async setReplication(replication) {
654
+ return this.update({ replicationConfiguration: replication });
655
+ }
656
+ /**
657
+ * Adds (or replaces by `replicationRuleName`) a single replication rule
658
+ * on this bucket while leaving any other rules, the source key, and the
659
+ * destination key mapping untouched.
660
+ *
661
+ * When this is the very first source-side rule, `sourceApplicationKeyId`
662
+ * must be supplied to seed `asReplicationSource.sourceApplicationKeyId`;
663
+ * for subsequent calls the existing source key is reused unless the
664
+ * caller explicitly overrides it.
665
+ *
666
+ * @param rule - The replication rule to add or replace.
667
+ * @param options - Optional source application key ID override (or seed
668
+ * when no source side exists yet).
669
+ *
670
+ * @returns The updated bucket metadata.
671
+ *
672
+ * @throws If no source-side replication exists yet and the caller did
673
+ * not supply `sourceApplicationKeyId`.
674
+ */
675
+ async addReplicationRule(rule, options) {
676
+ const current = (await this.refresh()).replicationConfiguration;
677
+ const existingSource = current.asReplicationSource;
678
+ const sourceKey = options?.sourceApplicationKeyId ?? existingSource?.sourceApplicationKeyId;
679
+ if (!sourceKey) throw new Error("addReplicationRule: no existing source-side replication; pass options.sourceApplicationKeyId");
680
+ const without = (existingSource?.replicationRules ?? []).filter((r) => r.replicationRuleName !== rule.replicationRuleName);
681
+ return this.setReplication({
682
+ asReplicationSource: {
683
+ sourceApplicationKeyId: sourceKey,
684
+ replicationRules: [...without, rule]
685
+ },
686
+ asReplicationDestination: current.asReplicationDestination
687
+ });
688
+ }
689
+ /**
690
+ * Removes a single replication rule by name. No-ops cleanly when the rule
691
+ * is not present (returns the unchanged-but-revision-bumped bucket info).
692
+ *
693
+ * @param replicationRuleName - Name of the rule to remove.
694
+ *
695
+ * @returns The updated bucket metadata.
696
+ */
697
+ async removeReplicationRule(replicationRuleName) {
698
+ const current = (await this.refresh()).replicationConfiguration;
699
+ const existingSource = current.asReplicationSource;
700
+ if (!existingSource) return this.setReplication(current);
701
+ const filtered = existingSource.replicationRules.filter((r) => r.replicationRuleName !== replicationRuleName);
702
+ return this.setReplication({
703
+ asReplicationSource: {
704
+ sourceApplicationKeyId: existingSource.sourceApplicationKeyId,
705
+ replicationRules: filtered
706
+ },
707
+ asReplicationDestination: current.asReplicationDestination
708
+ });
709
+ }
710
+ /**
711
+ * Returns the current lifecycle rules for this bucket, refetched from B2.
712
+ *
713
+ * @returns The current array of {@link LifecycleRule}s.
714
+ */
715
+ async getLifecycleRules() {
716
+ return (await this.refresh()).lifecycleRules;
717
+ }
718
+ /**
719
+ * Replaces this bucket's lifecycle rules in their entirety.
720
+ * @param rules - The new rule set. Pass `[]` to remove all lifecycle
721
+ * automation.
722
+ *
723
+ * @returns The updated bucket metadata.
724
+ */
725
+ async setLifecycleRules(rules) {
726
+ return this.update({ lifecycleRules: [...rules] });
727
+ }
728
+ /**
729
+ * Adds (or replaces, matched by `fileNamePrefix`) a single lifecycle rule
730
+ * while leaving any other rules untouched.
731
+ *
732
+ * Matching on prefix mirrors B2's own data model: each unique prefix can
733
+ * have at most one rule, and a `b2_update_bucket` call that contains two
734
+ * rules with the same prefix is rejected. The helper enforces this for
735
+ * the caller.
736
+ *
737
+ * @param rule - The lifecycle rule to add or replace.
738
+ *
739
+ * @returns The updated bucket metadata.
740
+ */
741
+ async addLifecycleRule(rule) {
742
+ const without = (await this.getLifecycleRules()).filter((r) => r.fileNamePrefix !== rule.fileNamePrefix);
743
+ return this.setLifecycleRules([...without, rule]);
744
+ }
745
+ /**
746
+ * Removes a single lifecycle rule by prefix. No-ops cleanly when the rule
747
+ * is not present.
748
+ *
749
+ * @param fileNamePrefix - The prefix of the rule to remove.
750
+ *
751
+ * @returns The updated bucket metadata.
752
+ */
753
+ async removeLifecycleRule(fileNamePrefix) {
754
+ const current = await this.getLifecycleRules();
755
+ return this.setLifecycleRules(current.filter((r) => r.fileNamePrefix !== fileNamePrefix));
756
+ }
757
+ /**
758
+ * Returns the current default Object Lock retention policy for new
759
+ * uploads to this bucket, refetched from B2.
760
+ *
761
+ * @returns The default {@link BucketRetentionPolicy} (which may be
762
+ * `{ mode: 'none', period: null }` when Object Lock is enabled on the
763
+ * bucket but no default is set).
764
+ */
765
+ async getDefaultRetention() {
766
+ return (await this.refresh()).defaultRetention;
767
+ }
768
+ /**
769
+ * Sets (or clears, by passing `{ mode: 'none', period: null }`) the
770
+ * default Object Lock retention policy applied to new uploads.
771
+ *
772
+ * Object Lock must already be enabled on the bucket. Buckets created
773
+ * without `fileLockEnabled: true` cannot accept a default retention
774
+ * policy and B2 will reject this call.
775
+ *
776
+ * @param policy - The new default retention policy.
777
+ *
778
+ * @returns The updated bucket metadata.
779
+ */
780
+ async setDefaultRetention(policy) {
781
+ return this.update({ defaultRetention: policy });
782
+ }
788
783
  };
789
- //# sourceMappingURL=bucket.js.map
784
+ //#endregion
785
+ export { Bucket };
786
+
787
+ //# sourceMappingURL=bucket.js.map