@backblaze-labs/b2-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (512) hide show
  1. package/CHANGELOG.md +121 -0
  2. package/LICENSE +21 -0
  3. package/README.md +664 -0
  4. package/dist/auth/account-info.d.cts +51 -0
  5. package/dist/auth/account-info.d.cts.map +1 -0
  6. package/dist/auth/account-info.d.ts +51 -0
  7. package/dist/auth/account-info.d.ts.map +1 -0
  8. package/dist/auth/file.cjs +210 -0
  9. package/dist/auth/file.cjs.map +1 -0
  10. package/dist/auth/file.d.cts +157 -0
  11. package/dist/auth/file.d.cts.map +1 -0
  12. package/dist/auth/file.d.ts +157 -0
  13. package/dist/auth/file.d.ts.map +1 -0
  14. package/dist/auth/file.js +210 -0
  15. package/dist/auth/file.js.map +1 -0
  16. package/dist/auth/in-memory.cjs +184 -0
  17. package/dist/auth/in-memory.cjs.map +1 -0
  18. package/dist/auth/in-memory.d.cts +147 -0
  19. package/dist/auth/in-memory.d.cts.map +1 -0
  20. package/dist/auth/in-memory.d.ts +147 -0
  21. package/dist/auth/in-memory.d.ts.map +1 -0
  22. package/dist/auth/in-memory.js +184 -0
  23. package/dist/auth/in-memory.js.map +1 -0
  24. package/dist/auth/index.cjs +10 -0
  25. package/dist/auth/index.cjs.map +1 -0
  26. package/dist/auth/index.d.cts +6 -0
  27. package/dist/auth/index.d.cts.map +1 -0
  28. package/dist/auth/index.d.ts +6 -0
  29. package/dist/auth/index.d.ts.map +1 -0
  30. package/dist/auth/index.js +10 -0
  31. package/dist/auth/index.js.map +1 -0
  32. package/dist/auth/realms.cjs +12 -0
  33. package/dist/auth/realms.cjs.map +1 -0
  34. package/dist/auth/realms.d.cts +12 -0
  35. package/dist/auth/realms.d.cts.map +1 -0
  36. package/dist/auth/realms.d.ts +12 -0
  37. package/dist/auth/realms.d.ts.map +1 -0
  38. package/dist/auth/realms.js +12 -0
  39. package/dist/auth/realms.js.map +1 -0
  40. package/dist/auth/upload-url-pool.cjs +52 -0
  41. package/dist/auth/upload-url-pool.cjs.map +1 -0
  42. package/dist/auth/upload-url-pool.d.cts +35 -0
  43. package/dist/auth/upload-url-pool.d.cts.map +1 -0
  44. package/dist/auth/upload-url-pool.d.ts +35 -0
  45. package/dist/auth/upload-url-pool.d.ts.map +1 -0
  46. package/dist/auth/upload-url-pool.js +52 -0
  47. package/dist/auth/upload-url-pool.js.map +1 -0
  48. package/dist/bucket.cjs +789 -0
  49. package/dist/bucket.cjs.map +1 -0
  50. package/dist/bucket.d.cts +659 -0
  51. package/dist/bucket.d.cts.map +1 -0
  52. package/dist/bucket.d.ts +659 -0
  53. package/dist/bucket.d.ts.map +1 -0
  54. package/dist/bucket.js +789 -0
  55. package/dist/bucket.js.map +1 -0
  56. package/dist/client.cjs +230 -0
  57. package/dist/client.cjs.map +1 -0
  58. package/dist/client.d.cts +222 -0
  59. package/dist/client.d.cts.map +1 -0
  60. package/dist/client.d.ts +222 -0
  61. package/dist/client.d.ts.map +1 -0
  62. package/dist/client.js +230 -0
  63. package/dist/client.js.map +1 -0
  64. package/dist/copy/large.cjs +74 -0
  65. package/dist/copy/large.cjs.map +1 -0
  66. package/dist/copy/large.d.cts +53 -0
  67. package/dist/copy/large.d.cts.map +1 -0
  68. package/dist/copy/large.d.ts +53 -0
  69. package/dist/copy/large.d.ts.map +1 -0
  70. package/dist/copy/large.js +74 -0
  71. package/dist/copy/large.js.map +1 -0
  72. package/dist/download/parallel.cjs +122 -0
  73. package/dist/download/parallel.cjs.map +1 -0
  74. package/dist/download/parallel.d.cts +42 -0
  75. package/dist/download/parallel.d.cts.map +1 -0
  76. package/dist/download/parallel.d.ts +42 -0
  77. package/dist/download/parallel.d.ts.map +1 -0
  78. package/dist/download/parallel.js +122 -0
  79. package/dist/download/parallel.js.map +1 -0
  80. package/dist/download/single.cjs +117 -0
  81. package/dist/download/single.cjs.map +1 -0
  82. package/dist/download/single.d.cts +152 -0
  83. package/dist/download/single.d.cts.map +1 -0
  84. package/dist/download/single.d.ts +152 -0
  85. package/dist/download/single.d.ts.map +1 -0
  86. package/dist/download/single.js +117 -0
  87. package/dist/download/single.js.map +1 -0
  88. package/dist/errors/index.cjs +268 -0
  89. package/dist/errors/index.cjs.map +1 -0
  90. package/dist/errors/index.d.cts +264 -0
  91. package/dist/errors/index.d.cts.map +1 -0
  92. package/dist/errors/index.d.ts +264 -0
  93. package/dist/errors/index.d.ts.map +1 -0
  94. package/dist/errors/index.js +268 -0
  95. package/dist/errors/index.js.map +1 -0
  96. package/dist/http/retry.cjs +36 -0
  97. package/dist/http/retry.cjs.map +1 -0
  98. package/dist/http/retry.d.cts +34 -0
  99. package/dist/http/retry.d.cts.map +1 -0
  100. package/dist/http/retry.d.ts +34 -0
  101. package/dist/http/retry.d.ts.map +1 -0
  102. package/dist/http/retry.js +36 -0
  103. package/dist/http/retry.js.map +1 -0
  104. package/dist/http/transport.cjs +143 -0
  105. package/dist/http/transport.cjs.map +1 -0
  106. package/dist/http/transport.d.cts +122 -0
  107. package/dist/http/transport.d.cts.map +1 -0
  108. package/dist/http/transport.d.ts +122 -0
  109. package/dist/http/transport.d.ts.map +1 -0
  110. package/dist/http/transport.js +143 -0
  111. package/dist/http/transport.js.map +1 -0
  112. package/dist/http/url-guard.cjs +97 -0
  113. package/dist/http/url-guard.cjs.map +1 -0
  114. package/dist/http/url-guard.d.cts +88 -0
  115. package/dist/http/url-guard.d.cts.map +1 -0
  116. package/dist/http/url-guard.d.ts +88 -0
  117. package/dist/http/url-guard.d.ts.map +1 -0
  118. package/dist/http/url-guard.js +97 -0
  119. package/dist/http/url-guard.js.map +1 -0
  120. package/dist/http/user-agent.cjs +51 -0
  121. package/dist/http/user-agent.cjs.map +1 -0
  122. package/dist/http/user-agent.d.cts +28 -0
  123. package/dist/http/user-agent.d.cts.map +1 -0
  124. package/dist/http/user-agent.d.ts +28 -0
  125. package/dist/http/user-agent.d.ts.map +1 -0
  126. package/dist/http/user-agent.js +51 -0
  127. package/dist/http/user-agent.js.map +1 -0
  128. package/dist/index.cjs +78 -0
  129. package/dist/index.cjs.map +1 -0
  130. package/dist/index.d.cts +39 -0
  131. package/dist/index.d.cts.map +1 -0
  132. package/dist/index.d.ts +39 -0
  133. package/dist/index.d.ts.map +1 -0
  134. package/dist/index.js +78 -0
  135. package/dist/index.js.map +1 -0
  136. package/dist/notifications/index.cjs +7 -0
  137. package/dist/notifications/index.cjs.map +1 -0
  138. package/dist/notifications/index.d.cts +3 -0
  139. package/dist/notifications/index.d.cts.map +1 -0
  140. package/dist/notifications/index.d.ts +3 -0
  141. package/dist/notifications/index.d.ts.map +1 -0
  142. package/dist/notifications/index.js +7 -0
  143. package/dist/notifications/index.js.map +1 -0
  144. package/dist/notifications/webhook.cjs +106 -0
  145. package/dist/notifications/webhook.cjs.map +1 -0
  146. package/dist/notifications/webhook.d.cts +146 -0
  147. package/dist/notifications/webhook.d.cts.map +1 -0
  148. package/dist/notifications/webhook.d.ts +146 -0
  149. package/dist/notifications/webhook.d.ts.map +1 -0
  150. package/dist/notifications/webhook.js +106 -0
  151. package/dist/notifications/webhook.js.map +1 -0
  152. package/dist/object.cjs +212 -0
  153. package/dist/object.cjs.map +1 -0
  154. package/dist/object.d.cts +263 -0
  155. package/dist/object.d.cts.map +1 -0
  156. package/dist/object.d.ts +263 -0
  157. package/dist/object.d.ts.map +1 -0
  158. package/dist/object.js +212 -0
  159. package/dist/object.js.map +1 -0
  160. package/dist/package.json.cjs +9 -0
  161. package/dist/package.json.cjs.map +1 -0
  162. package/dist/package.json.js +9 -0
  163. package/dist/package.json.js.map +1 -0
  164. package/dist/raw/encoding.cjs +47 -0
  165. package/dist/raw/encoding.cjs.map +1 -0
  166. package/dist/raw/encoding.d.cts +46 -0
  167. package/dist/raw/encoding.d.cts.map +1 -0
  168. package/dist/raw/encoding.d.ts +46 -0
  169. package/dist/raw/encoding.d.ts.map +1 -0
  170. package/dist/raw/encoding.js +47 -0
  171. package/dist/raw/encoding.js.map +1 -0
  172. package/dist/raw/index.cjs +600 -0
  173. package/dist/raw/index.cjs.map +1 -0
  174. package/dist/raw/index.d.cts +381 -0
  175. package/dist/raw/index.d.cts.map +1 -0
  176. package/dist/raw/index.d.ts +381 -0
  177. package/dist/raw/index.d.ts.map +1 -0
  178. package/dist/raw/index.js +601 -0
  179. package/dist/raw/index.js.map +1 -0
  180. package/dist/s3/index.cjs +23 -0
  181. package/dist/s3/index.cjs.map +1 -0
  182. package/dist/s3/index.d.cts +74 -0
  183. package/dist/s3/index.d.cts.map +1 -0
  184. package/dist/s3/index.d.ts +74 -0
  185. package/dist/s3/index.d.ts.map +1 -0
  186. package/dist/s3/index.js +23 -0
  187. package/dist/s3/index.js.map +1 -0
  188. package/dist/simulator/capabilities.cjs +53 -0
  189. package/dist/simulator/capabilities.cjs.map +1 -0
  190. package/dist/simulator/capabilities.d.cts +15 -0
  191. package/dist/simulator/capabilities.d.cts.map +1 -0
  192. package/dist/simulator/capabilities.d.ts +15 -0
  193. package/dist/simulator/capabilities.d.ts.map +1 -0
  194. package/dist/simulator/capabilities.js +53 -0
  195. package/dist/simulator/capabilities.js.map +1 -0
  196. package/dist/simulator/index.cjs +1559 -0
  197. package/dist/simulator/index.cjs.map +1 -0
  198. package/dist/simulator/index.d.cts +495 -0
  199. package/dist/simulator/index.d.cts.map +1 -0
  200. package/dist/simulator/index.d.ts +495 -0
  201. package/dist/simulator/index.d.ts.map +1 -0
  202. package/dist/simulator/index.js +1560 -0
  203. package/dist/simulator/index.js.map +1 -0
  204. package/dist/simulator/validation.cjs +174 -0
  205. package/dist/simulator/validation.cjs.map +1 -0
  206. package/dist/simulator/validation.d.cts +104 -0
  207. package/dist/simulator/validation.d.cts.map +1 -0
  208. package/dist/simulator/validation.d.ts +104 -0
  209. package/dist/simulator/validation.d.ts.map +1 -0
  210. package/dist/simulator/validation.js +174 -0
  211. package/dist/simulator/validation.js.map +1 -0
  212. package/dist/streams/collect.cjs +26 -0
  213. package/dist/streams/collect.cjs.map +1 -0
  214. package/dist/streams/collect.d.cts +18 -0
  215. package/dist/streams/collect.d.cts.map +1 -0
  216. package/dist/streams/collect.d.ts +18 -0
  217. package/dist/streams/collect.d.ts.map +1 -0
  218. package/dist/streams/collect.js +26 -0
  219. package/dist/streams/collect.js.map +1 -0
  220. package/dist/streams/hash.cjs +123 -0
  221. package/dist/streams/hash.cjs.map +1 -0
  222. package/dist/streams/hash.d.cts +42 -0
  223. package/dist/streams/hash.d.cts.map +1 -0
  224. package/dist/streams/hash.d.ts +42 -0
  225. package/dist/streams/hash.d.ts.map +1 -0
  226. package/dist/streams/hash.js +101 -0
  227. package/dist/streams/hash.js.map +1 -0
  228. package/dist/streams/index.cjs +13 -0
  229. package/dist/streams/index.cjs.map +1 -0
  230. package/dist/streams/index.d.cts +7 -0
  231. package/dist/streams/index.d.cts.map +1 -0
  232. package/dist/streams/index.d.ts +7 -0
  233. package/dist/streams/index.d.ts.map +1 -0
  234. package/dist/streams/index.js +13 -0
  235. package/dist/streams/index.js.map +1 -0
  236. package/dist/streams/progress.cjs +47 -0
  237. package/dist/streams/progress.cjs.map +1 -0
  238. package/dist/streams/progress.d.cts +53 -0
  239. package/dist/streams/progress.d.cts.map +1 -0
  240. package/dist/streams/progress.d.ts +53 -0
  241. package/dist/streams/progress.d.ts.map +1 -0
  242. package/dist/streams/progress.js +47 -0
  243. package/dist/streams/progress.js.map +1 -0
  244. package/dist/streams/source.cjs +155 -0
  245. package/dist/streams/source.cjs.map +1 -0
  246. package/dist/streams/source.d.cts +140 -0
  247. package/dist/streams/source.d.cts.map +1 -0
  248. package/dist/streams/source.d.ts +140 -0
  249. package/dist/streams/source.d.ts.map +1 -0
  250. package/dist/streams/source.js +155 -0
  251. package/dist/streams/source.js.map +1 -0
  252. package/dist/sync/actions/index.cjs +191 -0
  253. package/dist/sync/actions/index.cjs.map +1 -0
  254. package/dist/sync/actions/index.d.cts +167 -0
  255. package/dist/sync/actions/index.d.cts.map +1 -0
  256. package/dist/sync/actions/index.d.ts +167 -0
  257. package/dist/sync/actions/index.d.ts.map +1 -0
  258. package/dist/sync/actions/index.js +191 -0
  259. package/dist/sync/actions/index.js.map +1 -0
  260. package/dist/sync/index.cjs +23 -0
  261. package/dist/sync/index.cjs.map +1 -0
  262. package/dist/sync/index.d.cts +21 -0
  263. package/dist/sync/index.d.cts.map +1 -0
  264. package/dist/sync/index.d.ts +21 -0
  265. package/dist/sync/index.d.ts.map +1 -0
  266. package/dist/sync/index.js +23 -0
  267. package/dist/sync/index.js.map +1 -0
  268. package/dist/sync/pairing.cjs +31 -0
  269. package/dist/sync/pairing.cjs.map +1 -0
  270. package/dist/sync/pairing.d.cts +13 -0
  271. package/dist/sync/pairing.d.cts.map +1 -0
  272. package/dist/sync/pairing.d.ts +13 -0
  273. package/dist/sync/pairing.d.ts.map +1 -0
  274. package/dist/sync/pairing.js +31 -0
  275. package/dist/sync/pairing.js.map +1 -0
  276. package/dist/sync/policies/compare.cjs +14 -0
  277. package/dist/sync/policies/compare.cjs.map +1 -0
  278. package/dist/sync/policies/compare.d.cts +13 -0
  279. package/dist/sync/policies/compare.d.cts.map +1 -0
  280. package/dist/sync/policies/compare.d.ts +13 -0
  281. package/dist/sync/policies/compare.d.ts.map +1 -0
  282. package/dist/sync/policies/compare.js +14 -0
  283. package/dist/sync/policies/compare.js.map +1 -0
  284. package/dist/sync/policies/index.cjs +74 -0
  285. package/dist/sync/policies/index.cjs.map +1 -0
  286. package/dist/sync/policies/index.d.cts +42 -0
  287. package/dist/sync/policies/index.d.cts.map +1 -0
  288. package/dist/sync/policies/index.d.ts +42 -0
  289. package/dist/sync/policies/index.d.ts.map +1 -0
  290. package/dist/sync/policies/index.js +74 -0
  291. package/dist/sync/policies/index.js.map +1 -0
  292. package/dist/sync/scanners/b2.cjs +57 -0
  293. package/dist/sync/scanners/b2.cjs.map +1 -0
  294. package/dist/sync/scanners/b2.d.cts +20 -0
  295. package/dist/sync/scanners/b2.d.cts.map +1 -0
  296. package/dist/sync/scanners/b2.d.ts +20 -0
  297. package/dist/sync/scanners/b2.d.ts.map +1 -0
  298. package/dist/sync/scanners/b2.js +57 -0
  299. package/dist/sync/scanners/b2.js.map +1 -0
  300. package/dist/sync/scanners/local.cjs +58 -0
  301. package/dist/sync/scanners/local.cjs.map +1 -0
  302. package/dist/sync/scanners/local.d.cts +24 -0
  303. package/dist/sync/scanners/local.d.cts.map +1 -0
  304. package/dist/sync/scanners/local.d.ts +24 -0
  305. package/dist/sync/scanners/local.d.ts.map +1 -0
  306. package/dist/sync/scanners/local.js +58 -0
  307. package/dist/sync/scanners/local.js.map +1 -0
  308. package/dist/sync/synchronizer.cjs +203 -0
  309. package/dist/sync/synchronizer.cjs.map +1 -0
  310. package/dist/sync/synchronizer.d.cts +52 -0
  311. package/dist/sync/synchronizer.d.cts.map +1 -0
  312. package/dist/sync/synchronizer.d.ts +52 -0
  313. package/dist/sync/synchronizer.d.ts.map +1 -0
  314. package/dist/sync/synchronizer.js +181 -0
  315. package/dist/sync/synchronizer.js.map +1 -0
  316. package/dist/sync/types.d.cts +121 -0
  317. package/dist/sync/types.d.cts.map +1 -0
  318. package/dist/sync/types.d.ts +121 -0
  319. package/dist/sync/types.d.ts.map +1 -0
  320. package/dist/types/auth.cjs +58 -0
  321. package/dist/types/auth.cjs.map +1 -0
  322. package/dist/types/auth.d.cts +150 -0
  323. package/dist/types/auth.d.cts.map +1 -0
  324. package/dist/types/auth.d.ts +150 -0
  325. package/dist/types/auth.d.ts.map +1 -0
  326. package/dist/types/auth.js +58 -0
  327. package/dist/types/auth.js.map +1 -0
  328. package/dist/types/bucket.cjs +44 -0
  329. package/dist/types/bucket.cjs.map +1 -0
  330. package/dist/types/bucket.d.cts +245 -0
  331. package/dist/types/bucket.d.cts.map +1 -0
  332. package/dist/types/bucket.d.ts +245 -0
  333. package/dist/types/bucket.d.ts.map +1 -0
  334. package/dist/types/bucket.js +44 -0
  335. package/dist/types/bucket.js.map +1 -0
  336. package/dist/types/download.d.cts +110 -0
  337. package/dist/types/download.d.cts.map +1 -0
  338. package/dist/types/download.d.ts +110 -0
  339. package/dist/types/download.d.ts.map +1 -0
  340. package/dist/types/encryption.cjs +343 -0
  341. package/dist/types/encryption.cjs.map +1 -0
  342. package/dist/types/encryption.d.cts +132 -0
  343. package/dist/types/encryption.d.cts.map +1 -0
  344. package/dist/types/encryption.d.ts +132 -0
  345. package/dist/types/encryption.d.ts.map +1 -0
  346. package/dist/types/encryption.js +321 -0
  347. package/dist/types/encryption.js.map +1 -0
  348. package/dist/types/errors.d.cts +16 -0
  349. package/dist/types/errors.d.cts.map +1 -0
  350. package/dist/types/errors.d.ts +16 -0
  351. package/dist/types/errors.d.ts.map +1 -0
  352. package/dist/types/file.cjs +23 -0
  353. package/dist/types/file.cjs.map +1 -0
  354. package/dist/types/file.d.cts +220 -0
  355. package/dist/types/file.d.cts.map +1 -0
  356. package/dist/types/file.d.ts +220 -0
  357. package/dist/types/file.d.ts.map +1 -0
  358. package/dist/types/file.js +23 -0
  359. package/dist/types/file.js.map +1 -0
  360. package/dist/types/ids.cjs +27 -0
  361. package/dist/types/ids.cjs.map +1 -0
  362. package/dist/types/ids.d.cts +84 -0
  363. package/dist/types/ids.d.cts.map +1 -0
  364. package/dist/types/ids.d.ts +84 -0
  365. package/dist/types/ids.d.ts.map +1 -0
  366. package/dist/types/ids.js +27 -0
  367. package/dist/types/ids.js.map +1 -0
  368. package/dist/types/index.d.cts +25 -0
  369. package/dist/types/index.d.cts.map +1 -0
  370. package/dist/types/index.d.ts +25 -0
  371. package/dist/types/index.d.ts.map +1 -0
  372. package/dist/types/key.d.cts +84 -0
  373. package/dist/types/key.d.cts.map +1 -0
  374. package/dist/types/key.d.ts +84 -0
  375. package/dist/types/key.d.ts.map +1 -0
  376. package/dist/types/lock.cjs +17 -0
  377. package/dist/types/lock.cjs.map +1 -0
  378. package/dist/types/lock.d.cts +92 -0
  379. package/dist/types/lock.d.cts.map +1 -0
  380. package/dist/types/lock.d.ts +92 -0
  381. package/dist/types/lock.d.ts.map +1 -0
  382. package/dist/types/lock.js +17 -0
  383. package/dist/types/lock.js.map +1 -0
  384. package/dist/types/notifications.cjs +24 -0
  385. package/dist/types/notifications.cjs.map +1 -0
  386. package/dist/types/notifications.d.cts +97 -0
  387. package/dist/types/notifications.d.cts.map +1 -0
  388. package/dist/types/notifications.d.ts +97 -0
  389. package/dist/types/notifications.d.ts.map +1 -0
  390. package/dist/types/notifications.js +24 -0
  391. package/dist/types/notifications.js.map +1 -0
  392. package/dist/types/replication.d.cts +42 -0
  393. package/dist/types/replication.d.cts.map +1 -0
  394. package/dist/types/replication.d.ts +42 -0
  395. package/dist/types/replication.d.ts.map +1 -0
  396. package/dist/types/upload.d.cts +219 -0
  397. package/dist/types/upload.d.cts.map +1 -0
  398. package/dist/types/upload.d.ts +219 -0
  399. package/dist/types/upload.d.ts.map +1 -0
  400. package/dist/upload/cancel.cjs +10 -0
  401. package/dist/upload/cancel.cjs.map +1 -0
  402. package/dist/upload/cancel.d.cts +23 -0
  403. package/dist/upload/cancel.d.cts.map +1 -0
  404. package/dist/upload/cancel.d.ts +23 -0
  405. package/dist/upload/cancel.d.ts.map +1 -0
  406. package/dist/upload/cancel.js +10 -0
  407. package/dist/upload/cancel.js.map +1 -0
  408. package/dist/upload/concurrency.cjs +54 -0
  409. package/dist/upload/concurrency.cjs.map +1 -0
  410. package/dist/upload/concurrency.d.cts +46 -0
  411. package/dist/upload/concurrency.d.cts.map +1 -0
  412. package/dist/upload/concurrency.d.ts +46 -0
  413. package/dist/upload/concurrency.d.ts.map +1 -0
  414. package/dist/upload/concurrency.js +54 -0
  415. package/dist/upload/concurrency.js.map +1 -0
  416. package/dist/upload/large.cjs +222 -0
  417. package/dist/upload/large.cjs.map +1 -0
  418. package/dist/upload/large.d.cts +71 -0
  419. package/dist/upload/large.d.cts.map +1 -0
  420. package/dist/upload/large.d.ts +71 -0
  421. package/dist/upload/large.d.ts.map +1 -0
  422. package/dist/upload/large.js +222 -0
  423. package/dist/upload/large.js.map +1 -0
  424. package/dist/upload/resume.cjs +34 -0
  425. package/dist/upload/resume.cjs.map +1 -0
  426. package/dist/upload/resume.d.cts +33 -0
  427. package/dist/upload/resume.d.cts.map +1 -0
  428. package/dist/upload/resume.d.ts +33 -0
  429. package/dist/upload/resume.d.ts.map +1 -0
  430. package/dist/upload/resume.js +34 -0
  431. package/dist/upload/resume.js.map +1 -0
  432. package/dist/upload/single.cjs +47 -0
  433. package/dist/upload/single.cjs.map +1 -0
  434. package/dist/upload/single.d.cts +51 -0
  435. package/dist/upload/single.d.cts.map +1 -0
  436. package/dist/upload/single.d.ts +51 -0
  437. package/dist/upload/single.d.ts.map +1 -0
  438. package/dist/upload/single.js +47 -0
  439. package/dist/upload/single.js.map +1 -0
  440. package/dist/upload/stream.cjs +198 -0
  441. package/dist/upload/stream.cjs.map +1 -0
  442. package/dist/upload/stream.d.cts +61 -0
  443. package/dist/upload/stream.d.cts.map +1 -0
  444. package/dist/upload/stream.d.ts +61 -0
  445. package/dist/upload/stream.d.ts.map +1 -0
  446. package/dist/upload/stream.js +198 -0
  447. package/dist/upload/stream.js.map +1 -0
  448. package/dist/util/best-effort.cjs +10 -0
  449. package/dist/util/best-effort.cjs.map +1 -0
  450. package/dist/util/best-effort.d.cts +31 -0
  451. package/dist/util/best-effort.d.cts.map +1 -0
  452. package/dist/util/best-effort.d.ts +31 -0
  453. package/dist/util/best-effort.d.ts.map +1 -0
  454. package/dist/util/best-effort.js +10 -0
  455. package/dist/util/best-effort.js.map +1 -0
  456. package/dist/util/defaults.cjs +11 -0
  457. package/dist/util/defaults.cjs.map +1 -0
  458. package/dist/util/defaults.d.cts +54 -0
  459. package/dist/util/defaults.d.cts.map +1 -0
  460. package/dist/util/defaults.d.ts +54 -0
  461. package/dist/util/defaults.d.ts.map +1 -0
  462. package/dist/util/defaults.js +11 -0
  463. package/dist/util/defaults.js.map +1 -0
  464. package/dist/util/normalize.cjs +16 -0
  465. package/dist/util/normalize.cjs.map +1 -0
  466. package/dist/util/normalize.d.cts +62 -0
  467. package/dist/util/normalize.d.cts.map +1 -0
  468. package/dist/util/normalize.d.ts +62 -0
  469. package/dist/util/normalize.d.ts.map +1 -0
  470. package/dist/util/normalize.js +16 -0
  471. package/dist/util/normalize.js.map +1 -0
  472. package/dist/util/paginator.cjs +20 -0
  473. package/dist/util/paginator.cjs.map +1 -0
  474. package/dist/util/paginator.d.cts +120 -0
  475. package/dist/util/paginator.d.cts.map +1 -0
  476. package/dist/util/paginator.d.ts +120 -0
  477. package/dist/util/paginator.d.ts.map +1 -0
  478. package/dist/util/paginator.js +20 -0
  479. package/dist/util/paginator.js.map +1 -0
  480. package/dist/util/plan-ranges.cjs +28 -0
  481. package/dist/util/plan-ranges.cjs.map +1 -0
  482. package/dist/util/plan-ranges.d.cts +56 -0
  483. package/dist/util/plan-ranges.d.cts.map +1 -0
  484. package/dist/util/plan-ranges.d.ts +56 -0
  485. package/dist/util/plan-ranges.d.ts.map +1 -0
  486. package/dist/util/plan-ranges.js +28 -0
  487. package/dist/util/plan-ranges.js.map +1 -0
  488. package/dist/util/text-codec.cjs +7 -0
  489. package/dist/util/text-codec.cjs.map +1 -0
  490. package/dist/util/text-codec.d.cts +26 -0
  491. package/dist/util/text-codec.d.cts.map +1 -0
  492. package/dist/util/text-codec.d.ts +26 -0
  493. package/dist/util/text-codec.d.ts.map +1 -0
  494. package/dist/util/text-codec.js +7 -0
  495. package/dist/util/text-codec.js.map +1 -0
  496. package/dist/util/to-error.cjs +7 -0
  497. package/dist/util/to-error.cjs.map +1 -0
  498. package/dist/util/to-error.d.cts +15 -0
  499. package/dist/util/to-error.d.cts.map +1 -0
  500. package/dist/util/to-error.d.ts +15 -0
  501. package/dist/util/to-error.d.ts.map +1 -0
  502. package/dist/util/to-error.js +7 -0
  503. package/dist/util/to-error.js.map +1 -0
  504. package/dist/version.cjs +6 -0
  505. package/dist/version.cjs.map +1 -0
  506. package/dist/version.d.cts +14 -0
  507. package/dist/version.d.cts.map +1 -0
  508. package/dist/version.d.ts +14 -0
  509. package/dist/version.d.ts.map +1 -0
  510. package/dist/version.js +6 -0
  511. package/dist/version.js.map +1 -0
  512. package/package.json +198 -0
package/README.md ADDED
@@ -0,0 +1,664 @@
1
+ # @backblaze-labs/b2-sdk
2
+
3
+ [![CI](https://github.com/backblaze-labs/b2-sdk-typescript/actions/workflows/ci.yml/badge.svg)](https://github.com/backblaze-labs/b2-sdk-typescript/actions/workflows/ci.yml)
4
+ [![API Docs](https://github.com/backblaze-labs/b2-sdk-typescript/actions/workflows/docs.yml/badge.svg)](https://backblaze-labs.github.io/b2-sdk-typescript/)
5
+ [![npm](https://img.shields.io/npm/v/@backblaze-labs/b2-sdk?color=cb3837)](https://www.npmjs.com/package/@backblaze-labs/b2-sdk)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-3178c6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
8
+ [![Node.js](https://img.shields.io/badge/Node.js-%E2%89%A522-339933?logo=nodedotjs&logoColor=white)](https://nodejs.org/)
9
+ [![Zero Dependencies](https://img.shields.io/badge/dependencies-0-brightgreen)](package.json)
10
+
11
+ The official Backblaze B2 Cloud Storage SDK for TypeScript and JavaScript.
12
+
13
+ **Isomorphic at the source level.** One source tree runs unmodified in Node.js 22+, Bun, Deno, browsers, Cloudflare Workers, and Vercel Edge. Internal imports use `.ts` extensions so Deno reads `src/` directly with no build step. See [Source isomorphism](#source-isomorphism).
14
+
15
+ **Async-first.** Built on Web Streams, `AbortSignal`, and `crypto.subtle`. No callbacks, no legacy APIs.
16
+
17
+ **Fully typed.** Branded IDs, discriminated unions for encryption settings and errors, strict TypeScript with `exactOptionalPropertyTypes`.
18
+
19
+ **Zero runtime dependencies.** The core package has no `dependencies` in `package.json`.
20
+
21
+ **Full API reference:** [backblaze-labs.github.io/b2-sdk-typescript](https://backblaze-labs.github.io/b2-sdk-typescript/) (generated from source on every push to `main`).
22
+
23
+ ## Install
24
+
25
+ ```bash
26
+ npm install @backblaze-labs/b2-sdk
27
+ # or
28
+ pnpm add @backblaze-labs/b2-sdk
29
+ # or
30
+ yarn add @backblaze-labs/b2-sdk
31
+ ```
32
+
33
+ ## Quick start
34
+
35
+ ```ts
36
+ import { B2Client, BufferSource } from '@backblaze-labs/b2-sdk'
37
+
38
+ const client = new B2Client({
39
+ applicationKeyId: process.env.B2_APPLICATION_KEY_ID,
40
+ applicationKey: process.env.B2_APPLICATION_KEY,
41
+ })
42
+
43
+ await client.authorize()
44
+
45
+ const bucket = await client.getBucket('my-app-data')
46
+ if (!bucket) throw new Error('bucket not found')
47
+
48
+ const data = new TextEncoder().encode('Hello, B2!')
49
+ const file = await bucket.upload({
50
+ fileName: 'hello.txt',
51
+ source: new BufferSource(data),
52
+ contentType: 'text/plain',
53
+ })
54
+
55
+ console.log(`Uploaded: ${file.fileName} (${file.contentLength} bytes)`)
56
+ ```
57
+
58
+ ## Features
59
+
60
+ ### Buckets
61
+
62
+ ```ts
63
+ import { BucketType } from '@backblaze-labs/b2-sdk'
64
+
65
+ // List all buckets
66
+ const buckets = await client.listBuckets()
67
+
68
+ // Get a bucket by name
69
+ const bucket = await client.getBucket('my-bucket')
70
+
71
+ // Update bucket settings
72
+ await bucket.update({
73
+ bucketType: BucketType.AllPublic,
74
+ lifecycleRules: [{ fileNamePrefix: 'logs/', daysFromUploadingToHiding: 30 }],
75
+ })
76
+
77
+ // Delete a bucket
78
+ await bucket.delete()
79
+ ```
80
+
81
+ > The `BucketType`, `RetentionMode`, `LegalHoldValue`, `Capability`, `EventType`, and `EncryptionMode` `as const` objects exported from the main entry give you type-safe alternatives to the raw string literals — pick whichever style you prefer; both are accepted at the type level.
82
+
83
+ ### Uploads
84
+
85
+ Small files (under the recommended part size, typically 100 MB) are uploaded in a single request. Larger files automatically use multipart upload with parallel part uploads.
86
+
87
+ ```ts
88
+ import { BufferSource, BlobSource } from '@backblaze-labs/b2-sdk'
89
+
90
+ // From a Uint8Array
91
+ await bucket.upload({
92
+ fileName: 'data.bin',
93
+ source: new BufferSource(myUint8Array),
94
+ })
95
+
96
+ // From a Blob or File (browser)
97
+ await bucket.upload({
98
+ fileName: 'photo.jpg',
99
+ source: new BlobSource(fileInput.files[0]),
100
+ contentType: 'image/jpeg',
101
+ })
102
+
103
+ // Large file with progress tracking
104
+ await bucket.upload({
105
+ fileName: 'backup.tar.gz',
106
+ source: new BlobSource(largeBlob),
107
+ concurrency: 8,
108
+ partSize: 64 * 1024 * 1024,
109
+ onProgress: (event) => {
110
+ console.log(`${event.bytesTransferred}/${event.totalBytes} bytes`)
111
+ },
112
+ signal: AbortSignal.timeout(300_000),
113
+ })
114
+ ```
115
+
116
+ #### Resume a failed multipart upload
117
+
118
+ Pass `resume: true` and the SDK looks up the matching unfinished large file via `b2_list_unfinished_large_files`, checks which parts are already on the server, and only re-uploads the missing ones. Parts whose locally-recomputed SHA-1 matches the server's are skipped.
119
+
120
+ ```ts
121
+ // Restart the upload that crashed at part 47 of 100
122
+ await bucket.upload({
123
+ fileName: 'backup.tar.gz',
124
+ source: new BlobSource(largeBlob),
125
+ partSize: 64 * 1024 * 1024,
126
+ resume: true,
127
+ })
128
+
129
+ // Or target a specific in-progress large file explicitly
130
+ await bucket.upload({
131
+ fileName: 'backup.tar.gz',
132
+ source: new BlobSource(largeBlob),
133
+ resumeFileId: knownLargeFileId,
134
+ })
135
+ ```
136
+
137
+ #### Streaming uploads via WritableStream
138
+
139
+ Pipe any `ReadableStream<Uint8Array>` straight into B2. The SDK buffers up to `partSize` bytes per part and uploads them in parallel through the multipart protocol. Backpressure is honoured via the internal queue.
140
+
141
+ ```ts
142
+ const { writable, done } = bucket.file('logs.ndjson').createWriteStream({
143
+ partSize: 16 * 1024 * 1024,
144
+ concurrency: 4,
145
+ })
146
+
147
+ // Pipe from any ReadableStream source: fetch().body, fs.createReadStream(...) (with toWeb), etc.
148
+ await response.body.pipeTo(writable)
149
+ const fileVersion = await done
150
+ console.log(`Streamed upload finished: ${fileVersion.fileName} (${fileVersion.contentLength} bytes)`)
151
+ ```
152
+
153
+ > Streaming uploads do not support resume because the total size and per-part SHA-1s are not known in advance. Use the buffered `upload` path with `resume: true` when that matters.
154
+
155
+ ### Downloads
156
+
157
+ ```ts
158
+ // Download by file name
159
+ const result = await bucket.download('hello.txt')
160
+ const text = await new Response(result.body).text()
161
+
162
+ // Download by file ID with range
163
+ const partial = await bucket.download('large-file.bin', {
164
+ range: 'bytes=0-1023',
165
+ })
166
+
167
+ // Parallel ranged download (for large files).
168
+ // Each range is retried independently with exponential backoff so a single
169
+ // transient 503 does not kill the whole transfer.
170
+ const obj = bucket.file('big-dataset.parquet')
171
+ const stream = obj.createReadStream(fileId, totalSize, {
172
+ concurrency: 4,
173
+ rangeSize: 10 * 1024 * 1024,
174
+ maxRetries: 5,
175
+ })
176
+ ```
177
+
178
+ ### File operations
179
+
180
+ ```ts
181
+ // List files (single page)
182
+ const listing = await bucket.listFileNames({ prefix: 'photos/', pageSize: 100 })
183
+
184
+ // Iterate all files (async generator, handles pagination)
185
+ for await (const file of bucket.paginateFileNames({ prefix: 'logs/' })) {
186
+ console.log(file.fileName, file.contentLength)
187
+ }
188
+
189
+ // Look up the latest visible version by name (returns null if missing or hidden)
190
+ const info = await bucket.getFileInfoByName('hello.txt')
191
+
192
+ // Fetch metadata without transferring the body (HTTP HEAD). Returns a
193
+ // body-less result so callers never have to drain a (logically empty)
194
+ // HEAD response stream themselves.
195
+ const { headers } = await bucket.head('hello.txt')
196
+ console.log(headers.contentLength, headers.contentSha1)
197
+
198
+ // Hide a file (soft delete)
199
+ await bucket.hideFile('old-config.json')
200
+
201
+ // Restore visibility by removing the latest hide marker
202
+ await bucket.unhideFile('old-config.json')
203
+
204
+ // Delete a specific file version
205
+ await bucket.deleteFileVersion('file.txt', fileId)
206
+
207
+ // Server-side copy (single call, suitable for any size B2 supports)
208
+ await bucket.copyFile({
209
+ sourceFileId: originalFileId,
210
+ fileName: 'copy-of-file.txt',
211
+ })
212
+
213
+ // Server-side multipart copy for large files. Splits the source into parts
214
+ // copied in parallel via b2_copy_part. Falls back to copyFile below partSize.
215
+ await bucket.copyLargeFile({
216
+ sourceFileId: originalFileId,
217
+ fileName: 'big-replica.bin',
218
+ partSize: 64 * 1024 * 1024,
219
+ concurrency: 4,
220
+ })
221
+ ```
222
+
223
+ ### Bulk delete
224
+
225
+ Two primitives on `Bucket` for cleanup at scale:
226
+
227
+ ```ts
228
+ // Delete a known set of file versions with bounded concurrency
229
+ const result = await bucket.deleteMany(
230
+ [
231
+ { fileName: 'a.txt', fileId: id1 },
232
+ { fileName: 'b.txt', fileId: id2 },
233
+ ],
234
+ { concurrency: 10 },
235
+ )
236
+ console.log(`deleted=${result.deleted} errors=${result.errors.length}`)
237
+
238
+ // Stream-delete every version matching a prefix (or the whole bucket if omitted).
239
+ // Yields a DeleteAllEvent per version; never materialises the full list in memory.
240
+ for await (const event of bucket.deleteAll({ prefix: 'tmp/', dryRun: false })) {
241
+ if (event.type === 'delete') console.log('deleted', event.fileName)
242
+ else if (event.type === 'error') console.warn('failed', event.fileName, event.message)
243
+ }
244
+ ```
245
+
246
+ ### Application keys
247
+
248
+ ```ts
249
+ import { Capability } from '@backblaze-labs/b2-sdk'
250
+
251
+ const key = await client.createKey({
252
+ capabilities: [Capability.ReadFiles, Capability.WriteFiles],
253
+ keyName: 'my-app-key',
254
+ bucketId: bucket.id,
255
+ namePrefix: 'uploads/',
256
+ validDurationInSeconds: 86400,
257
+ })
258
+
259
+ const keys = await client.listKeys()
260
+ await client.deleteKey(key.applicationKeyId)
261
+ ```
262
+
263
+ #### Capability checks
264
+
265
+ Fail fast with a typed error instead of waiting for a server 401/403:
266
+
267
+ ```ts
268
+ import { Capability } from '@backblaze-labs/b2-sdk'
269
+ import { B2InsufficientCapabilityError } from '@backblaze-labs/b2-sdk/errors'
270
+
271
+ const required = [Capability.ReadFiles, Capability.WriteFiles]
272
+ const { ok, missing } = client.hasCapabilities(required)
273
+ if (!ok) {
274
+ throw new B2InsufficientCapabilityError(required, [...missing], missing)
275
+ }
276
+ ```
277
+
278
+ ### Server-side encryption
279
+
280
+ ```ts
281
+ import { SSE_B2, sseCustomer } from '@backblaze-labs/b2-sdk'
282
+ import { EncryptionKey } from '@backblaze-labs/b2-sdk/streams'
283
+
284
+ // SSE-B2 (Backblaze-managed keys)
285
+ await bucket.upload({
286
+ fileName: 'encrypted.dat',
287
+ source: new BufferSource(data),
288
+ serverSideEncryption: SSE_B2,
289
+ })
290
+
291
+ // SSE-C (customer-provided keys) - precomputed digests
292
+ await bucket.upload({
293
+ fileName: 'secret.dat',
294
+ source: new BufferSource(data),
295
+ serverSideEncryption: sseCustomer(base64Key, base64KeyMd5),
296
+ })
297
+
298
+ // SSE-C from raw bytes (Node). EncryptionKey computes the MD5 internally and
299
+ // redacts itself in JSON.stringify, toString, and Node's util.inspect so the
300
+ // key never lands in logs.
301
+ const key = await EncryptionKey.fromBytes(randomBytes(32))
302
+ await bucket.upload({
303
+ fileName: 'secret.dat',
304
+ source: new BufferSource(data),
305
+ serverSideEncryption: key,
306
+ })
307
+ console.log(key) // [EncryptionKey SSE-C [redacted SSE-C key]]
308
+ JSON.stringify(key) // customer key and MD5 fields show "[redacted SSE-C key]"
309
+ ```
310
+
311
+ ### Object lock and legal hold
312
+
313
+ ```ts
314
+ import { LegalHoldValue, RetentionMode } from '@backblaze-labs/b2-sdk'
315
+
316
+ await bucket.updateFileRetention('important.pdf', fileId, {
317
+ mode: RetentionMode.Governance,
318
+ retainUntilTimestamp: Date.now() + 365 * 24 * 60 * 60 * 1000,
319
+ })
320
+
321
+ // Shorten a governance-mode retention. Requires the bypassGovernance capability.
322
+ await bucket.updateFileRetention(
323
+ 'important.pdf',
324
+ fileId,
325
+ { mode: RetentionMode.Governance, retainUntilTimestamp: Date.now() + 24 * 60 * 60 * 1000 },
326
+ { bypassGovernance: true },
327
+ )
328
+
329
+ await bucket.updateFileLegalHold('evidence.pdf', fileId, LegalHoldValue.On)
330
+ ```
331
+
332
+ ### Event notifications
333
+
334
+ ```ts
335
+ import { EventType } from '@backblaze-labs/b2-sdk'
336
+
337
+ await bucket.setNotificationRules([
338
+ {
339
+ name: 'upload-notify',
340
+ eventTypes: [EventType.ObjectCreatedAll],
341
+ isEnabled: true,
342
+ targetConfiguration: {
343
+ targetType: 'webhook',
344
+ url: 'https://my-app.com/webhooks/b2',
345
+ hmacSha256SigningSecret: process.env.B2_WEBHOOK_SECRET,
346
+ },
347
+ },
348
+ ])
349
+ ```
350
+
351
+ On the receiving side, verify the `X-Bz-Event-Notification-Signature` header before trusting the payload. The `@backblaze-labs/b2-sdk/notifications` subpath ships HMAC-SHA256 helpers so you don't have to implement constant-time signature checking yourself:
352
+
353
+ ```ts
354
+ import {
355
+ B2_WEBHOOK_SIGNATURE_HEADER,
356
+ requireValidWebhook,
357
+ } from '@backblaze-labs/b2-sdk/notifications'
358
+
359
+ // Inside your HTTP handler. `body` must be the raw request bytes — any
360
+ // JSON re-serialisation will invalidate the HMAC.
361
+ const body = new Uint8Array(await request.arrayBuffer())
362
+ const payload = await requireValidWebhook({
363
+ body,
364
+ signature: request.headers.get(B2_WEBHOOK_SIGNATURE_HEADER),
365
+ secret: process.env.B2_WEBHOOK_SECRET,
366
+ })
367
+ for (const event of payload.events) {
368
+ console.log(event.eventType, event.objectName)
369
+ }
370
+ ```
371
+
372
+ `requireValidWebhook` throws on missing/invalid signature and returns the parsed payload on success. If you'd rather branch on a boolean (e.g. to log the failure reason without throwing), use the lower-level `verifyWebhookSignature` which returns `{ valid, reason, payload }`.
373
+
374
+ ### Download authorization
375
+
376
+ ```ts
377
+ // Generate a short-lived download authorization for sharing
378
+ const auth = await bucket.getDownloadAuthorization('photos/', 3600)
379
+ ```
380
+
381
+ ### Persistent authorization (Node)
382
+
383
+ `FileAccountInfo` persists the authorization response to a JSON file on disk so processes can restart without re-authorizing. It implements the `AccountInfo` interface and is a drop-in replacement for `InMemoryAccountInfo`. Upload URL pools remain in memory.
384
+
385
+ ```ts
386
+ import { B2Client } from '@backblaze-labs/b2-sdk'
387
+ import { FileAccountInfo } from '@backblaze-labs/b2-sdk/auth/file'
388
+
389
+ const accountInfo = new FileAccountInfo('/var/cache/my-app/b2-auth.json')
390
+ await accountInfo.load() // populate from disk if the file exists
391
+
392
+ const client = new B2Client({
393
+ applicationKeyId: process.env.B2_APPLICATION_KEY_ID,
394
+ applicationKey: process.env.B2_APPLICATION_KEY,
395
+ accountInfo,
396
+ })
397
+
398
+ if (accountInfo.getAuth() === null) {
399
+ await client.authorize() // first run, or token cleared
400
+ }
401
+ ```
402
+
403
+ `load()` returns silently on missing or corrupt files (a fresh `authorize()` will populate fresh state). Call `await accountInfo.flushed()` before process exit if you need to guarantee the latest state has hit disk.
404
+
405
+ ## Subpath exports
406
+
407
+ The SDK is organized into subpath exports for tree-shaking:
408
+
409
+ ```ts
410
+ // High-level facade (most users need only this)
411
+ import { B2Client, Bucket, B2Object } from '@backblaze-labs/b2-sdk'
412
+
413
+ // Low-level 1:1 API bindings for the B2 native endpoints the SDK uses
414
+ import { RawClient } from '@backblaze-labs/b2-sdk/raw'
415
+
416
+ // Error types for catch blocks
417
+ import {
418
+ B2Error,
419
+ ExpiredAuthTokenError,
420
+ CapExceededError,
421
+ B2InsufficientCapabilityError,
422
+ } from '@backblaze-labs/b2-sdk/errors'
423
+
424
+ // Auth backends (in-memory default, file-backed for Node persistence)
425
+ import { InMemoryAccountInfo } from '@backblaze-labs/b2-sdk/auth'
426
+ import { FileAccountInfo } from '@backblaze-labs/b2-sdk/auth/file'
427
+
428
+ // Streaming utilities + SSE-C key wrapper
429
+ import {
430
+ IncrementalSha1,
431
+ BufferSource,
432
+ BlobSource,
433
+ EncryptionKey,
434
+ } from '@backblaze-labs/b2-sdk/streams'
435
+
436
+ // Sync engine (local <-> B2)
437
+ import { synchronize, LocalFolder, B2Folder } from '@backblaze-labs/b2-sdk/sync'
438
+
439
+ // S3-compatible helpers (requires @aws-sdk/client-s3 peer dependency)
440
+ import { createS3ClientConfig, presignGetObjectUrl } from '@backblaze-labs/b2-sdk/s3'
441
+
442
+ // In-memory B2 server for tests (no network required)
443
+ import { B2Simulator } from '@backblaze-labs/b2-sdk/simulator'
444
+ ```
445
+
446
+ Every export is documented with full type signatures in the [API reference](https://backblaze-labs.github.io/b2-sdk-typescript/).
447
+
448
+ ## Custom transport
449
+
450
+ The SDK uses a pluggable transport layer. The default `FetchTransport` uses the native `fetch` API. You can provide your own:
451
+
452
+ ```ts
453
+ import type { HttpTransport, HttpRequest, HttpResponse } from '@backblaze-labs/b2-sdk'
454
+
455
+ class MyTransport implements HttpTransport {
456
+ async send(request: HttpRequest): Promise<HttpResponse> {
457
+ // your implementation
458
+ }
459
+ }
460
+
461
+ const client = new B2Client({
462
+ applicationKeyId: '...',
463
+ applicationKey: '...',
464
+ transport: new MyTransport(),
465
+ })
466
+ ```
467
+
468
+ ## Identifying your traffic (User-Agent)
469
+
470
+ Every request the SDK issues carries a User-Agent header that Backblaze can grep server logs by:
471
+
472
+ ```
473
+ b2-sdk-typescript/0.1.0 (typescript; @backblaze-labs/b2-sdk; node/24.14.1; linux; x64)
474
+ ```
475
+
476
+ Both `b2-sdk-typescript/` (stable product token) and `@backblaze-labs/b2-sdk` (npm package name) are part of the documented contract — log queries that match either one find every request issued by this SDK. The comment block also reports the runtime (`node/<version>`, `bun/<version>`, `deno/<version>`, or `browser`) plus the OS and architecture on non-browser runtimes.
477
+
478
+ The version is read straight from `package.json` via a JSON import attribute, so bumping the package version automatically propagates to the UA, the published artifact, and the runtime constant. There is no second source of truth to keep in sync.
479
+
480
+ To prepend your own application identifier:
481
+
482
+ ```ts
483
+ const client = new B2Client({
484
+ applicationKeyId,
485
+ applicationKey,
486
+ userAgent: 'my-app/1.0',
487
+ })
488
+ // → "my-app/1.0 b2-sdk-typescript/0.1.0 (typescript; @backblaze-labs/b2-sdk; node/24.14.1; linux; x64)"
489
+ ```
490
+
491
+ ## SSRF guard
492
+
493
+ The default `FetchTransport` ships an allow-list guard that rejects any URL whose host falls outside the authorized B2 realm. This defends against URL-substitution attacks where a compromised or hostile B2 endpoint could return an upload URL pointing at an internal service (e.g. cloud metadata at `169.254.169.254`) and trick the SDK into making an authenticated request to it.
494
+
495
+ ```ts
496
+ const client = new B2Client({ applicationKeyId, applicationKey })
497
+ await client.authorize()
498
+ // Guard is now locked. Hosts under backblazeb2.com / backblaze.com are
499
+ // allowed; literal IPs, localhost, metadata.google.internal, *.internal,
500
+ // and *.local are rejected unconditionally; anything else throws B2SsrfError.
501
+
502
+ client.urlGuard?.getAllowedSuffixes()
503
+ // => ['backblaze.com', 'backblazeb2.com']
504
+ ```
505
+
506
+ You can extend the allow-list (e.g. for a self-hosted MITM proxy during debugging) without disabling the guard:
507
+
508
+ ```ts
509
+ new B2Client({
510
+ applicationKeyId,
511
+ applicationKey,
512
+ allowedHostSuffixes: ['internal-proxy.example'],
513
+ })
514
+ ```
515
+
516
+ Passing a custom `transport` opts out of the guard (your transport, your threat model).
517
+
518
+ ## Retry behavior
519
+
520
+ The SDK automatically retries transient errors with exponential backoff:
521
+
522
+ - **401 expired_auth_token**: re-authorizes and retries
523
+ - **503, 408, 429**: exponential backoff with jitter, respects `Retry-After` header
524
+ - **Network errors**: retried with backoff
525
+ - **Permanent errors** (403 cap_exceeded, 404 not_found, etc.): thrown immediately
526
+
527
+ Configure retry behavior:
528
+
529
+ ```ts
530
+ const client = new B2Client({
531
+ applicationKeyId: '...',
532
+ applicationKey: '...',
533
+ retry: {
534
+ maxRetries: 10,
535
+ maxRetryDelayMs: 120_000,
536
+ initialRetryDelayMs: 500,
537
+ },
538
+ })
539
+ ```
540
+
541
+ ## Testing with the simulator
542
+
543
+ The SDK ships an in-memory B2 simulator for unit testing without network access:
544
+
545
+ ```ts
546
+ import { describe, it, expect, beforeEach } from 'vitest'
547
+ import { B2Client, BucketType } from '@backblaze-labs/b2-sdk'
548
+ import { B2Simulator } from '@backblaze-labs/b2-sdk/simulator'
549
+ import { BufferSource } from '@backblaze-labs/b2-sdk/streams'
550
+
551
+ describe('my app', () => {
552
+ let client: B2Client
553
+
554
+ beforeEach(async () => {
555
+ const sim = new B2Simulator()
556
+ client = new B2Client({
557
+ applicationKeyId: 'test',
558
+ applicationKey: 'test',
559
+ transport: sim.transport(),
560
+ })
561
+ await client.authorize()
562
+ })
563
+
564
+ it('uploads and retrieves a file', async () => {
565
+ const bucket = await client.createBucket({
566
+ bucketName: 'test-bucket',
567
+ bucketType: BucketType.AllPrivate,
568
+ })
569
+
570
+ await bucket.upload({
571
+ fileName: 'test.txt',
572
+ source: new BufferSource(new TextEncoder().encode('hello')),
573
+ })
574
+
575
+ const listing = await bucket.listFileNames()
576
+ expect(listing.files).toHaveLength(1)
577
+ expect(listing.files[0].fileName).toBe('test.txt')
578
+ })
579
+ })
580
+ ```
581
+
582
+ ## Error handling
583
+
584
+ All B2 API errors are thrown as typed `B2Error` subclasses (13 in total). Client-side capability checks throw `B2InsufficientCapabilityError`.
585
+
586
+ ```ts
587
+ import { BucketType } from '@backblaze-labs/b2-sdk'
588
+ import {
589
+ B2Error,
590
+ CapExceededError,
591
+ DuplicateBucketNameError,
592
+ B2InsufficientCapabilityError,
593
+ } from '@backblaze-labs/b2-sdk/errors'
594
+
595
+ try {
596
+ await client.createBucket({ bucketName: 'test', bucketType: BucketType.AllPrivate })
597
+ } catch (err) {
598
+ if (err instanceof DuplicateBucketNameError) {
599
+ console.log('Bucket already exists')
600
+ } else if (err instanceof CapExceededError) {
601
+ console.log('Storage cap exceeded, upgrade your plan')
602
+ } else if (err instanceof B2InsufficientCapabilityError) {
603
+ console.log('Missing capabilities:', err.missing)
604
+ } else if (err instanceof B2Error) {
605
+ console.log(`B2 error: ${err.code} (status ${err.status}, retryable: ${err.retryable})`)
606
+ }
607
+ }
608
+ ```
609
+
610
+ ## B2-native primitives, with an S3 escape hatch
611
+
612
+ The high-level surface (`B2Client`, `Bucket`, `B2Object`) gives you direct access to features that live in B2's native API:
613
+
614
+ - **Per-part and whole-file SHA-1 verification** on multipart uploads.
615
+ - **`b2_copy_part` server-side multipart copy** via `bucket.copyLargeFile()` — no client-side bytes touched.
616
+ - **File retention + legal hold** (object lock) on `bucket.updateFileRetention()` and `bucket.updateFileLegalHold()`.
617
+ - **Time-scoped download tokens** via `bucket.getDownloadAuthorization()` for sharing without exposing the application key.
618
+ - **Replication configuration** via `bucket.update({ replicationConfiguration })`.
619
+ - **Event notification rules** via `bucket.getNotificationRules()` and `bucket.setNotificationRules()`.
620
+ - **Application key restrictions** (per-bucket, per-prefix, per-capability) via `client.createKey()`.
621
+
622
+ When you want S3 compatibility instead — for tooling that already speaks S3, or for the Bandwidth Alliance proxy pattern — `@backblaze-labs/b2-sdk/s3` exposes `createS3ClientConfig()` and `presignGetObjectUrl()` so the same SDK covers both surfaces.
623
+
624
+ ## Source isomorphism
625
+
626
+ The SDK is isomorphic at the **source** level, not just at the built artifact level. Every internal import uses a `.ts` extension (`import { foo } from './foo.ts'`, not `'./foo.js'`), `tsconfig.json` has `allowImportingTsExtensions: true` + `rewriteRelativeImportExtensions: true`, and Vite rewrites the extensions to `.js` during build so npm consumers still see a normal `dist/`.
627
+
628
+ What this means in practice: you can point a runtime straight at `src/` without a build step.
629
+
630
+ ```bash
631
+ # Deno reads src/ directly. No `pnpm build`, no node_modules, no npm: shim.
632
+ deno check examples/node-list-buckets.ts
633
+
634
+ # Bun does the same.
635
+ bun examples/node-list-buckets.ts
636
+
637
+ # Node 22.6+ with --experimental-strip-types runs raw .ts.
638
+ node --experimental-strip-types examples/node-list-buckets.ts
639
+ ```
640
+
641
+ So you get both: an `npm install`-ready `dist/` (ESM + CJS + DTS), *and* a `src/` tree that runs in Node, Bun, and Deno without a build. Useful when extending the SDK locally, contributing PRs, or vendoring the source into a Deno project.
642
+
643
+ ## Runtime support
644
+
645
+ | Runtime | Version | Status |
646
+ |---|---|---|
647
+ | Node.js | 22+ | Primary target. CI runs the full suite on Node 22 and 24 across Linux, Windows, and macOS. |
648
+ | Bun | latest | Tested in CI via `bun test src/` + example typecheck. |
649
+ | Deno | 2.x | Source isomorphism verified in CI via `deno check` against `src/`. |
650
+ | Browsers | Chromium, Firefox, WebKit (last 2 evergreen) | Tested in CI via Playwright. |
651
+ | Cloudflare Workers | - | Supported. |
652
+ | Vercel Edge | - | Supported. |
653
+
654
+ Requires: `fetch`, Web Streams, `crypto.subtle`, `AbortSignal`. Node < 22 is not supported (Node 20 reached EOL April 2026).
655
+
656
+ The browser test suite (`pnpm test:browser`) runs the same source against real Chromium, Firefox, and WebKit instances. Only Node-specific tests (filename pattern `*.node.test.ts`, covering `node:fs`, `node:os`, `node:util.inspect`) are skipped.
657
+
658
+ ## License
659
+
660
+ MIT. See [LICENSE](LICENSE).
661
+
662
+ ## Contributing
663
+
664
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.