@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
@@ -0,0 +1,34 @@
1
+ /** Configuration for retry behavior on transient failures. */
2
+ export interface RetryOptions {
3
+ /** Maximum number of retry attempts before giving up. */
4
+ readonly maxRetries: number;
5
+ /** Upper bound on retry delay in milliseconds, regardless of backoff calculation. */
6
+ readonly maxRetryDelayMs: number;
7
+ /** Base delay in milliseconds for the first retry. Doubles on each subsequent attempt. */
8
+ readonly initialRetryDelayMs: number;
9
+ }
10
+ /** Default retry settings: 5 retries, 1s initial delay, 64s max delay. */
11
+ export declare const DEFAULT_RETRY_OPTIONS: RetryOptions;
12
+ /**
13
+ * Computes the delay before the next retry using exponential backoff with jitter.
14
+ * If a `Retry-After` value is provided by the server, it takes precedence over
15
+ * the calculated backoff (still capped at {@link RetryOptions.maxRetryDelayMs}).
16
+ *
17
+ * @param attempt - Zero-based retry attempt index.
18
+ * @param options - Retry configuration with delay bounds.
19
+ * @param retryAfter - Server-provided retry delay in seconds, if any.
20
+ *
21
+ * @returns The delay in milliseconds before the next retry attempt.
22
+ */
23
+ export declare function computeBackoff(attempt: number, options: RetryOptions, retryAfter?: number): number;
24
+ /**
25
+ * Returns a promise that resolves after the given delay. Supports cancellation
26
+ * via an optional AbortSignal.
27
+ *
28
+ * @param ms - Delay in milliseconds.
29
+ * @param signal - Optional abort signal to cancel the sleep early.
30
+ *
31
+ * @returns A promise that resolves when the delay elapses or rejects if aborted.
32
+ */
33
+ export declare function sleep(ms: number, signal?: AbortSignal): Promise<void>;
34
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/http/retry.js"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,MAAM,WAAW,YAAY;IAC3B,yDAAyD;IACzD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,qFAAqF;IACrF,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,0FAA0F;IAC1F,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAA;CACrC;AAED,0EAA0E;AAC1E,eAAO,MAAM,qBAAqB,EAAE,YAInC,CAAA;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,YAAY,EACrB,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAOR;AAED;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBrE"}
@@ -0,0 +1,36 @@
1
+ const DEFAULT_RETRY_OPTIONS = {
2
+ maxRetries: 5,
3
+ maxRetryDelayMs: 64e3,
4
+ initialRetryDelayMs: 1e3
5
+ };
6
+ function computeBackoff(attempt, options, retryAfter) {
7
+ if (retryAfter !== void 0 && retryAfter > 0) {
8
+ return Math.min(retryAfter * 1e3, options.maxRetryDelayMs);
9
+ }
10
+ const base = options.initialRetryDelayMs * 2 ** attempt;
11
+ const jitter = Math.random() * base * 0.5;
12
+ return Math.min(base + jitter, options.maxRetryDelayMs);
13
+ }
14
+ function sleep(ms, signal) {
15
+ return new Promise((resolve, reject) => {
16
+ if (signal?.aborted) {
17
+ reject(signal.reason ?? new DOMException("Aborted", "AbortError"));
18
+ return;
19
+ }
20
+ const timer = setTimeout(resolve, ms);
21
+ signal?.addEventListener(
22
+ "abort",
23
+ () => {
24
+ clearTimeout(timer);
25
+ reject(signal.reason ?? new DOMException("Aborted", "AbortError"));
26
+ },
27
+ { once: true }
28
+ );
29
+ });
30
+ }
31
+ export {
32
+ DEFAULT_RETRY_OPTIONS,
33
+ computeBackoff,
34
+ sleep
35
+ };
36
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sources":["../../src/http/retry.ts"],"sourcesContent":["/** Configuration for retry behavior on transient failures. */\nexport interface RetryOptions {\n /** Maximum number of retry attempts before giving up. */\n readonly maxRetries: number\n /** Upper bound on retry delay in milliseconds, regardless of backoff calculation. */\n readonly maxRetryDelayMs: number\n /** Base delay in milliseconds for the first retry. Doubles on each subsequent attempt. */\n readonly initialRetryDelayMs: number\n}\n\n/** Default retry settings: 5 retries, 1s initial delay, 64s max delay. */\nexport const DEFAULT_RETRY_OPTIONS: RetryOptions = {\n maxRetries: 5,\n maxRetryDelayMs: 64_000,\n initialRetryDelayMs: 1_000,\n}\n\n/**\n * Computes the delay before the next retry using exponential backoff with jitter.\n * If a `Retry-After` value is provided by the server, it takes precedence over\n * the calculated backoff (still capped at {@link RetryOptions.maxRetryDelayMs}).\n *\n * @param attempt - Zero-based retry attempt index.\n * @param options - Retry configuration with delay bounds.\n * @param retryAfter - Server-provided retry delay in seconds, if any.\n *\n * @returns The delay in milliseconds before the next retry attempt.\n */\nexport function computeBackoff(\n attempt: number,\n options: RetryOptions,\n retryAfter?: number,\n): number {\n if (retryAfter !== undefined && retryAfter > 0) {\n return Math.min(retryAfter * 1000, options.maxRetryDelayMs)\n }\n const base = options.initialRetryDelayMs * 2 ** attempt\n const jitter = Math.random() * base * 0.5\n return Math.min(base + jitter, options.maxRetryDelayMs)\n}\n\n/**\n * Returns a promise that resolves after the given delay. Supports cancellation\n * via an optional AbortSignal.\n *\n * @param ms - Delay in milliseconds.\n * @param signal - Optional abort signal to cancel the sleep early.\n *\n * @returns A promise that resolves when the delay elapses or rejects if aborted.\n */\nexport function sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason ?? new DOMException('Aborted', 'AbortError'))\n return\n }\n const timer = setTimeout(resolve, ms)\n signal?.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer)\n reject(signal.reason ?? new DOMException('Aborted', 'AbortError'))\n },\n { once: true },\n )\n })\n}\n"],"names":[],"mappings":"AAWO,MAAM,wBAAsC;AAAA,EACjD,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,qBAAqB;AACvB;AAaO,SAAS,eACd,SACA,SACA,YACQ;AACR,MAAI,eAAe,UAAa,aAAa,GAAG;AAC9C,WAAO,KAAK,IAAI,aAAa,KAAM,QAAQ,eAAe;AAAA,EAC5D;AACA,QAAM,OAAO,QAAQ,sBAAsB,KAAK;AAChD,QAAM,SAAS,KAAK,OAAA,IAAW,OAAO;AACtC,SAAO,KAAK,IAAI,OAAO,QAAQ,QAAQ,eAAe;AACxD;AAWO,SAAS,MAAM,IAAY,QAAqC;AACrE,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,QAAI,QAAQ,SAAS;AACnB,aAAO,OAAO,UAAU,IAAI,aAAa,WAAW,YAAY,CAAC;AACjE;AAAA,IACF;AACA,UAAM,QAAQ,WAAW,SAAS,EAAE;AACpC,YAAQ;AAAA,MACN;AAAA,MACA,MAAM;AACJ,qBAAa,KAAK;AAClB,eAAO,OAAO,UAAU,IAAI,aAAa,WAAW,YAAY,CAAC;AAAA,MACnE;AAAA,MACA,EAAE,MAAM,KAAA;AAAA,IAAK;AAAA,EAEjB,CAAC;AACH;"}
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const errors_index = require("../errors/index.cjs");
4
+ const retry = require("./retry.cjs");
5
+ const urlGuard = require("./url-guard.cjs");
6
+ const userAgent = require("./user-agent.cjs");
7
+ class FetchTransport {
8
+ /** User-Agent string sent with every request. */
9
+ userAgent;
10
+ /** SSRF allow-list applied to every outgoing URL. Mutable so `B2Client.authorize()` can lock it down post-auth. */
11
+ urlGuard;
12
+ /**
13
+ * Creates a new FetchTransport.
14
+ * @param options - Optional configuration: custom User-Agent prefix and SSRF guard.
15
+ */
16
+ constructor(options) {
17
+ this.userAgent = userAgent.getUserAgent(options?.userAgent);
18
+ this.urlGuard = options?.urlGuard ?? new urlGuard.UrlGuard();
19
+ }
20
+ /**
21
+ * Sends the request using the global `fetch` function.
22
+ * @param request - The HTTP request to execute.
23
+ *
24
+ * @returns The HTTP response.
25
+ *
26
+ * @throws B2SsrfError when the URL fails the configured SSRF guard.
27
+ */
28
+ async send(request) {
29
+ this.urlGuard.check(request.url);
30
+ const headers = new Headers(request.headers);
31
+ if (!headers.has("User-Agent")) {
32
+ headers.set("User-Agent", this.userAgent);
33
+ }
34
+ const response = await fetch(request.url, {
35
+ method: request.method,
36
+ headers,
37
+ body: request.body ?? null,
38
+ ...request.signal !== void 0 ? { signal: request.signal } : {}
39
+ });
40
+ return {
41
+ status: response.status,
42
+ headers: response.headers,
43
+ body: response.body,
44
+ json: () => response.json(),
45
+ text: () => response.text(),
46
+ arrayBuffer: () => response.arrayBuffer()
47
+ };
48
+ }
49
+ }
50
+ class RetryTransport {
51
+ /** The wrapped transport that performs actual HTTP requests. */
52
+ inner;
53
+ /** Resolved retry options (defaults merged with user overrides). */
54
+ options;
55
+ /** Optional callback to refresh auth credentials on 401 — returns the fresh token. */
56
+ onReauth;
57
+ /** Sleep implementation used between retries; injectable for tests. */
58
+ sleepImpl;
59
+ /**
60
+ * Creates a new RetryTransport.
61
+ * @param opts - Retry transport configuration.
62
+ */
63
+ constructor(opts) {
64
+ this.inner = opts.transport;
65
+ this.options = { ...retry.DEFAULT_RETRY_OPTIONS, ...opts.retry };
66
+ if (opts.onReauth !== void 0) this.onReauth = opts.onReauth;
67
+ this.sleepImpl = opts.sleepImpl ?? retry.sleep;
68
+ }
69
+ /**
70
+ * Sends the request with automatic retry on transient failures.
71
+ * On expired auth tokens, calls {@link RetryTransportOptions.onReauth} and retries.
72
+ * @param originalRequest - The HTTP request to execute. The caller's
73
+ * reference is not mutated; on reauth, a copy with a refreshed
74
+ * Authorization header is sent.
75
+ *
76
+ * @returns The HTTP response.
77
+ */
78
+ async send(originalRequest) {
79
+ let request = originalRequest;
80
+ let lastError;
81
+ for (let attempt = 0; attempt <= this.options.maxRetries; attempt++) {
82
+ if (attempt > 0 && lastError) {
83
+ const retryAfter = lastError instanceof errors_index.NetworkError ? void 0 : lastError.retryAfter;
84
+ const delay = retry.computeBackoff(attempt - 1, this.options, retryAfter);
85
+ await this.sleepImpl(delay, request.signal);
86
+ }
87
+ try {
88
+ const response = await this.inner.send(request);
89
+ if (response.status >= 200 && response.status < 300) {
90
+ return response;
91
+ }
92
+ let errorBody;
93
+ try {
94
+ errorBody = await response.json();
95
+ } catch {
96
+ errorBody = {
97
+ status: response.status,
98
+ code: "internal_error",
99
+ message: `HTTP ${response.status}`
100
+ };
101
+ }
102
+ const retryAfterHeader = response.headers.get("Retry-After");
103
+ const retryAfterSec = retryAfterHeader ? Number.parseInt(retryAfterHeader, 10) : void 0;
104
+ const requestId = response.headers.get("X-Bz-Request-Id") ?? void 0;
105
+ const error = errors_index.classifyError(errorBody, {
106
+ ...retryAfterSec !== void 0 ? { retryAfter: retryAfterSec } : {},
107
+ ...requestId !== void 0 ? { requestId } : {}
108
+ });
109
+ if (error instanceof errors_index.ExpiredAuthTokenError && this.onReauth) {
110
+ const freshToken = await this.onReauth();
111
+ request = {
112
+ ...request,
113
+ headers: { ...request.headers ?? {}, Authorization: freshToken }
114
+ };
115
+ continue;
116
+ }
117
+ if (!error.retryable || attempt === this.options.maxRetries) {
118
+ throw error;
119
+ }
120
+ lastError = error;
121
+ } catch (err) {
122
+ if (err instanceof errors_index.B2Error || err instanceof errors_index.NetworkError) {
123
+ throw err;
124
+ }
125
+ if (err instanceof DOMException && err.name === "AbortError") {
126
+ throw err;
127
+ }
128
+ const networkErr = new errors_index.NetworkError(
129
+ err instanceof Error ? err.message : "Network error",
130
+ err
131
+ );
132
+ if (attempt === this.options.maxRetries) {
133
+ throw networkErr;
134
+ }
135
+ lastError = networkErr;
136
+ }
137
+ }
138
+ throw lastError ?? new errors_index.NetworkError("Max retries exceeded");
139
+ }
140
+ }
141
+ exports.FetchTransport = FetchTransport;
142
+ exports.RetryTransport = RetryTransport;
143
+ //# sourceMappingURL=transport.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.cjs","sources":["../../src/http/transport.ts"],"sourcesContent":["import { B2Error, ExpiredAuthTokenError, NetworkError, classifyError } from '../errors/index.ts'\nimport type { B2ErrorResponse } from '../types/errors.ts'\nimport { DEFAULT_RETRY_OPTIONS, type RetryOptions, computeBackoff, sleep } from './retry.ts'\nimport { UrlGuard } from './url-guard.ts'\nimport { getUserAgent } from './user-agent.ts'\n\n/** Describes an outgoing HTTP request to the B2 API. */\nexport interface HttpRequest {\n /** Fully qualified URL to send the request to. */\n readonly url: string\n /** HTTP method. B2 uses GET for downloads (HEAD to fetch only headers) and POST for all other operations. */\n readonly method: 'GET' | 'HEAD' | 'POST'\n /** Request headers. Authorization and content-type are typically included. */\n readonly headers?: Record<string, string>\n /** Request body. Used for POST requests (JSON payloads or file uploads). */\n readonly body?: BodyInit | null\n /** Optional abort signal for request cancellation. */\n readonly signal?: AbortSignal\n}\n\n/** Represents a parsed HTTP response from the B2 API. */\nexport interface HttpResponse {\n /** HTTP status code. */\n readonly status: number\n /** Response headers. */\n readonly headers: Headers\n /** Response body as a readable stream, or null for empty responses. */\n readonly body: ReadableStream<Uint8Array> | null\n /** Parses the response body as JSON. */\n json<T>(): Promise<T>\n /** Reads the response body as a UTF-8 string. */\n text(): Promise<string>\n /** Reads the response body as an ArrayBuffer. */\n arrayBuffer(): Promise<ArrayBuffer>\n}\n\n/**\n * Transport layer abstraction for sending HTTP requests.\n * Implementations handle the actual network I/O and can be composed\n * (e.g. wrapping a {@link FetchTransport} with a {@link RetryTransport}).\n */\nexport interface HttpTransport {\n /** Sends an HTTP request and returns the response. */\n send(request: HttpRequest): Promise<HttpResponse>\n}\n\n/**\n * Default transport implementation using the global `fetch` API.\n * Automatically sets the User-Agent header on each request and applies the\n * SSRF {@link UrlGuard} (if configured) before opening the connection.\n */\nexport class FetchTransport implements HttpTransport {\n /** User-Agent string sent with every request. */\n private readonly userAgent: string\n /** SSRF allow-list applied to every outgoing URL. Mutable so `B2Client.authorize()` can lock it down post-auth. */\n readonly urlGuard: UrlGuard\n\n /**\n * Creates a new FetchTransport.\n * @param options - Optional configuration: custom User-Agent prefix and SSRF guard.\n */\n constructor(options?: { userAgent?: string; urlGuard?: UrlGuard }) {\n this.userAgent = getUserAgent(options?.userAgent)\n this.urlGuard = options?.urlGuard ?? new UrlGuard()\n }\n\n /**\n * Sends the request using the global `fetch` function.\n * @param request - The HTTP request to execute.\n *\n * @returns The HTTP response.\n *\n * @throws B2SsrfError when the URL fails the configured SSRF guard.\n */\n async send(request: HttpRequest): Promise<HttpResponse> {\n this.urlGuard.check(request.url)\n\n const headers = new Headers(request.headers)\n if (!headers.has('User-Agent')) {\n headers.set('User-Agent', this.userAgent)\n }\n\n const response = await fetch(request.url, {\n method: request.method,\n headers,\n body: request.body ?? null,\n ...(request.signal !== undefined ? { signal: request.signal } : {}),\n })\n\n return {\n status: response.status,\n headers: response.headers,\n body: response.body,\n json: <T>() => response.json() as Promise<T>,\n text: () => response.text(),\n arrayBuffer: () => response.arrayBuffer(),\n }\n }\n}\n\n/** Configuration for {@link RetryTransport}. */\nexport interface RetryTransportOptions {\n /** The underlying transport to delegate requests to. */\n readonly transport: HttpTransport\n /** Override default retry settings (max retries, delays). */\n readonly retry?: Partial<RetryOptions>\n /**\n * Callback invoked on expired auth token errors. Must refresh\n * credentials AND return the fresh auth token. The transport\n * substitutes the new token into `request.headers.Authorization`\n * before retrying — without this, the retried request would still\n * carry the expired token captured by the original caller and the\n * loop would never make progress.\n */\n readonly onReauth?: () => Promise<string>\n /**\n * Sleep implementation used between retry attempts. Defaults to the real\n * `sleep` from `./retry.js`. Test code can inject a no-op to avoid real\n * delays without relying on module mocking (which differs across runners).\n *\n * @internal\n */\n readonly sleepImpl?: (ms: number, signal?: AbortSignal) => Promise<void>\n}\n\n/**\n * Transport wrapper that adds automatic retry with exponential backoff.\n * Handles transient B2 errors (408, 429, 503), expired auth tokens,\n * and network failures. Delegates to an inner {@link HttpTransport}.\n */\nexport class RetryTransport implements HttpTransport {\n /** The wrapped transport that performs actual HTTP requests. */\n private readonly inner: HttpTransport\n /** Resolved retry options (defaults merged with user overrides). */\n private readonly options: RetryOptions\n /** Optional callback to refresh auth credentials on 401 — returns the fresh token. */\n private readonly onReauth?: () => Promise<string>\n /** Sleep implementation used between retries; injectable for tests. */\n private readonly sleepImpl: (ms: number, signal?: AbortSignal) => Promise<void>\n\n /**\n * Creates a new RetryTransport.\n * @param opts - Retry transport configuration.\n */\n constructor(opts: RetryTransportOptions) {\n this.inner = opts.transport\n this.options = { ...DEFAULT_RETRY_OPTIONS, ...opts.retry }\n if (opts.onReauth !== undefined) this.onReauth = opts.onReauth\n this.sleepImpl = opts.sleepImpl ?? sleep\n }\n\n /**\n * Sends the request with automatic retry on transient failures.\n * On expired auth tokens, calls {@link RetryTransportOptions.onReauth} and retries.\n * @param originalRequest - The HTTP request to execute. The caller's\n * reference is not mutated; on reauth, a copy with a refreshed\n * Authorization header is sent.\n *\n * @returns The HTTP response.\n */\n async send(originalRequest: HttpRequest): Promise<HttpResponse> {\n // `request` is reassigned (not mutated) when reauth produces a\n // fresh Authorization header, so the caller's `originalRequest`\n // stays untouched.\n let request: HttpRequest = originalRequest\n let lastError: B2Error | NetworkError | undefined\n\n for (let attempt = 0; attempt <= this.options.maxRetries; attempt++) {\n if (attempt > 0 && lastError) {\n const retryAfter = lastError instanceof NetworkError ? undefined : lastError.retryAfter\n const delay = computeBackoff(attempt - 1, this.options, retryAfter)\n await this.sleepImpl(delay, request.signal)\n }\n\n try {\n const response = await this.inner.send(request)\n\n if (response.status >= 200 && response.status < 300) {\n return response\n }\n\n let errorBody: B2ErrorResponse\n try {\n errorBody = await response.json<B2ErrorResponse>()\n } catch {\n errorBody = {\n status: response.status,\n code: 'internal_error',\n message: `HTTP ${response.status}`,\n }\n }\n\n const retryAfterHeader = response.headers.get('Retry-After')\n const retryAfterSec = retryAfterHeader ? Number.parseInt(retryAfterHeader, 10) : undefined\n const requestId = response.headers.get('X-Bz-Request-Id') ?? undefined\n\n const error = classifyError(errorBody, {\n ...(retryAfterSec !== undefined ? { retryAfter: retryAfterSec } : {}),\n ...(requestId !== undefined ? { requestId } : {}),\n })\n\n if (error instanceof ExpiredAuthTokenError && this.onReauth) {\n // Reauth returns the FRESH token; build a new request with a\n // shallow-copied headers object so the Authorization swap\n // doesn't mutate the caller's original request (which they\n // may hold for retry / introspection). Without this swap the\n // retry would carry the expired token captured at\n // request-build time and bounce off the server again,\n // exhausting the retry budget.\n const freshToken = await this.onReauth()\n request = {\n ...request,\n headers: { ...(request.headers ?? {}), Authorization: freshToken },\n }\n continue\n }\n\n if (!error.retryable || attempt === this.options.maxRetries) {\n throw error\n }\n\n lastError = error\n } catch (err) {\n if (err instanceof B2Error || err instanceof NetworkError) {\n throw err\n }\n\n if (err instanceof DOMException && err.name === 'AbortError') {\n throw err\n }\n\n const networkErr = new NetworkError(\n err instanceof Error ? err.message : 'Network error',\n err,\n )\n\n if (attempt === this.options.maxRetries) {\n throw networkErr\n }\n\n lastError = networkErr\n }\n }\n\n throw lastError ?? new NetworkError('Max retries exceeded')\n }\n}\n"],"names":["getUserAgent","UrlGuard","DEFAULT_RETRY_OPTIONS","sleep","NetworkError","computeBackoff","classifyError","ExpiredAuthTokenError","B2Error"],"mappings":";;;;;;AAmDO,MAAM,eAAwC;AAAA;AAAA,EAElC;AAAA;AAAA,EAER;AAAA;AAAA;AAAA;AAAA;AAAA,EAMT,YAAY,SAAuD;AACjE,SAAK,YAAYA,uBAAa,SAAS,SAAS;AAChD,SAAK,WAAW,SAAS,YAAY,IAAIC,SAAAA,SAAA;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,KAAK,SAA6C;AACtD,SAAK,SAAS,MAAM,QAAQ,GAAG;AAE/B,UAAM,UAAU,IAAI,QAAQ,QAAQ,OAAO;AAC3C,QAAI,CAAC,QAAQ,IAAI,YAAY,GAAG;AAC9B,cAAQ,IAAI,cAAc,KAAK,SAAS;AAAA,IAC1C;AAEA,UAAM,WAAW,MAAM,MAAM,QAAQ,KAAK;AAAA,MACxC,QAAQ,QAAQ;AAAA,MAChB;AAAA,MACA,MAAM,QAAQ,QAAQ;AAAA,MACtB,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,WAAW,CAAA;AAAA,IAAC,CAClE;AAED,WAAO;AAAA,MACL,QAAQ,SAAS;AAAA,MACjB,SAAS,SAAS;AAAA,MAClB,MAAM,SAAS;AAAA,MACf,MAAM,MAAS,SAAS,KAAA;AAAA,MACxB,MAAM,MAAM,SAAS,KAAA;AAAA,MACrB,aAAa,MAAM,SAAS,YAAA;AAAA,IAAY;AAAA,EAE5C;AACF;AAgCO,MAAM,eAAwC;AAAA;AAAA,EAElC;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMjB,YAAY,MAA6B;AACvC,SAAK,QAAQ,KAAK;AAClB,SAAK,UAAU,EAAE,GAAGC,MAAAA,uBAAuB,GAAG,KAAK,MAAA;AACnD,QAAI,KAAK,aAAa,OAAW,MAAK,WAAW,KAAK;AACtD,SAAK,YAAY,KAAK,aAAaC,MAAAA;AAAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,KAAK,iBAAqD;AAI9D,QAAI,UAAuB;AAC3B,QAAI;AAEJ,aAAS,UAAU,GAAG,WAAW,KAAK,QAAQ,YAAY,WAAW;AACnE,UAAI,UAAU,KAAK,WAAW;AAC5B,cAAM,aAAa,qBAAqBC,aAAAA,eAAe,SAAY,UAAU;AAC7E,cAAM,QAAQC,MAAAA,eAAe,UAAU,GAAG,KAAK,SAAS,UAAU;AAClE,cAAM,KAAK,UAAU,OAAO,QAAQ,MAAM;AAAA,MAC5C;AAEA,UAAI;AACF,cAAM,WAAW,MAAM,KAAK,MAAM,KAAK,OAAO;AAE9C,YAAI,SAAS,UAAU,OAAO,SAAS,SAAS,KAAK;AACnD,iBAAO;AAAA,QACT;AAEA,YAAI;AACJ,YAAI;AACF,sBAAY,MAAM,SAAS,KAAA;AAAA,QAC7B,QAAQ;AACN,sBAAY;AAAA,YACV,QAAQ,SAAS;AAAA,YACjB,MAAM;AAAA,YACN,SAAS,QAAQ,SAAS,MAAM;AAAA,UAAA;AAAA,QAEpC;AAEA,cAAM,mBAAmB,SAAS,QAAQ,IAAI,aAAa;AAC3D,cAAM,gBAAgB,mBAAmB,OAAO,SAAS,kBAAkB,EAAE,IAAI;AACjF,cAAM,YAAY,SAAS,QAAQ,IAAI,iBAAiB,KAAK;AAE7D,cAAM,QAAQC,aAAAA,cAAc,WAAW;AAAA,UACrC,GAAI,kBAAkB,SAAY,EAAE,YAAY,cAAA,IAAkB,CAAA;AAAA,UAClE,GAAI,cAAc,SAAY,EAAE,UAAA,IAAc,CAAA;AAAA,QAAC,CAChD;AAED,YAAI,iBAAiBC,aAAAA,yBAAyB,KAAK,UAAU;AAQ3D,gBAAM,aAAa,MAAM,KAAK,SAAA;AAC9B,oBAAU;AAAA,YACR,GAAG;AAAA,YACH,SAAS,EAAE,GAAI,QAAQ,WAAW,CAAA,GAAK,eAAe,WAAA;AAAA,UAAW;AAEnE;AAAA,QACF;AAEA,YAAI,CAAC,MAAM,aAAa,YAAY,KAAK,QAAQ,YAAY;AAC3D,gBAAM;AAAA,QACR;AAEA,oBAAY;AAAA,MACd,SAAS,KAAK;AACZ,YAAI,eAAeC,aAAAA,WAAW,eAAeJ,2BAAc;AACzD,gBAAM;AAAA,QACR;AAEA,YAAI,eAAe,gBAAgB,IAAI,SAAS,cAAc;AAC5D,gBAAM;AAAA,QACR;AAEA,cAAM,aAAa,IAAIA,aAAAA;AAAAA,UACrB,eAAe,QAAQ,IAAI,UAAU;AAAA,UACrC;AAAA,QAAA;AAGF,YAAI,YAAY,KAAK,QAAQ,YAAY;AACvC,gBAAM;AAAA,QACR;AAEA,oBAAY;AAAA,MACd;AAAA,IACF;AAEA,UAAM,aAAa,IAAIA,aAAAA,aAAa,sBAAsB;AAAA,EAC5D;AACF;;;"}
@@ -0,0 +1,122 @@
1
+ import { RetryOptions } from './retry.js';
2
+ import { UrlGuard } from './url-guard.js';
3
+ /** Describes an outgoing HTTP request to the B2 API. */
4
+ export interface HttpRequest {
5
+ /** Fully qualified URL to send the request to. */
6
+ readonly url: string;
7
+ /** HTTP method. B2 uses GET for downloads (HEAD to fetch only headers) and POST for all other operations. */
8
+ readonly method: 'GET' | 'HEAD' | 'POST';
9
+ /** Request headers. Authorization and content-type are typically included. */
10
+ readonly headers?: Record<string, string>;
11
+ /** Request body. Used for POST requests (JSON payloads or file uploads). */
12
+ readonly body?: BodyInit | null;
13
+ /** Optional abort signal for request cancellation. */
14
+ readonly signal?: AbortSignal;
15
+ }
16
+ /** Represents a parsed HTTP response from the B2 API. */
17
+ export interface HttpResponse {
18
+ /** HTTP status code. */
19
+ readonly status: number;
20
+ /** Response headers. */
21
+ readonly headers: Headers;
22
+ /** Response body as a readable stream, or null for empty responses. */
23
+ readonly body: ReadableStream<Uint8Array> | null;
24
+ /** Parses the response body as JSON. */
25
+ json<T>(): Promise<T>;
26
+ /** Reads the response body as a UTF-8 string. */
27
+ text(): Promise<string>;
28
+ /** Reads the response body as an ArrayBuffer. */
29
+ arrayBuffer(): Promise<ArrayBuffer>;
30
+ }
31
+ /**
32
+ * Transport layer abstraction for sending HTTP requests.
33
+ * Implementations handle the actual network I/O and can be composed
34
+ * (e.g. wrapping a {@link FetchTransport} with a {@link RetryTransport}).
35
+ */
36
+ export interface HttpTransport {
37
+ /** Sends an HTTP request and returns the response. */
38
+ send(request: HttpRequest): Promise<HttpResponse>;
39
+ }
40
+ /**
41
+ * Default transport implementation using the global `fetch` API.
42
+ * Automatically sets the User-Agent header on each request and applies the
43
+ * SSRF {@link UrlGuard} (if configured) before opening the connection.
44
+ */
45
+ export declare class FetchTransport implements HttpTransport {
46
+ /** User-Agent string sent with every request. */
47
+ private readonly userAgent;
48
+ /** SSRF allow-list applied to every outgoing URL. Mutable so `B2Client.authorize()` can lock it down post-auth. */
49
+ readonly urlGuard: UrlGuard;
50
+ /**
51
+ * Creates a new FetchTransport.
52
+ * @param options - Optional configuration: custom User-Agent prefix and SSRF guard.
53
+ */
54
+ constructor(options?: {
55
+ userAgent?: string;
56
+ urlGuard?: UrlGuard;
57
+ });
58
+ /**
59
+ * Sends the request using the global `fetch` function.
60
+ * @param request - The HTTP request to execute.
61
+ *
62
+ * @returns The HTTP response.
63
+ *
64
+ * @throws B2SsrfError when the URL fails the configured SSRF guard.
65
+ */
66
+ send(request: HttpRequest): Promise<HttpResponse>;
67
+ }
68
+ /** Configuration for {@link RetryTransport}. */
69
+ export interface RetryTransportOptions {
70
+ /** The underlying transport to delegate requests to. */
71
+ readonly transport: HttpTransport;
72
+ /** Override default retry settings (max retries, delays). */
73
+ readonly retry?: Partial<RetryOptions>;
74
+ /**
75
+ * Callback invoked on expired auth token errors. Must refresh
76
+ * credentials AND return the fresh auth token. The transport
77
+ * substitutes the new token into `request.headers.Authorization`
78
+ * before retrying — without this, the retried request would still
79
+ * carry the expired token captured by the original caller and the
80
+ * loop would never make progress.
81
+ */
82
+ readonly onReauth?: () => Promise<string>;
83
+ /**
84
+ * Sleep implementation used between retry attempts. Defaults to the real
85
+ * `sleep` from `./retry.js`. Test code can inject a no-op to avoid real
86
+ * delays without relying on module mocking (which differs across runners).
87
+ *
88
+ * @internal
89
+ */
90
+ readonly sleepImpl?: (ms: number, signal?: AbortSignal) => Promise<void>;
91
+ }
92
+ /**
93
+ * Transport wrapper that adds automatic retry with exponential backoff.
94
+ * Handles transient B2 errors (408, 429, 503), expired auth tokens,
95
+ * and network failures. Delegates to an inner {@link HttpTransport}.
96
+ */
97
+ export declare class RetryTransport implements HttpTransport {
98
+ /** The wrapped transport that performs actual HTTP requests. */
99
+ private readonly inner;
100
+ /** Resolved retry options (defaults merged with user overrides). */
101
+ private readonly options;
102
+ /** Optional callback to refresh auth credentials on 401 — returns the fresh token. */
103
+ private readonly onReauth?;
104
+ /** Sleep implementation used between retries; injectable for tests. */
105
+ private readonly sleepImpl;
106
+ /**
107
+ * Creates a new RetryTransport.
108
+ * @param opts - Retry transport configuration.
109
+ */
110
+ constructor(opts: RetryTransportOptions);
111
+ /**
112
+ * Sends the request with automatic retry on transient failures.
113
+ * On expired auth tokens, calls {@link RetryTransportOptions.onReauth} and retries.
114
+ * @param originalRequest - The HTTP request to execute. The caller's
115
+ * reference is not mutated; on reauth, a copy with a refreshed
116
+ * Authorization header is sent.
117
+ *
118
+ * @returns The HTTP response.
119
+ */
120
+ send(originalRequest: HttpRequest): Promise<HttpResponse>;
121
+ }
122
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/http/transport.js"],"names":[],"mappings":"AAEA,OAAO,EAAyB,KAAK,YAAY,EAAyB,MAAM,YAAY,CAAA;AAC5F,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAGzC,wDAAwD;AACxD,MAAM,WAAW,WAAW;IAC1B,kDAAkD;IAClD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,6GAA6G;IAC7G,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAA;IACxC,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACzC,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAA;IAC/B,sDAAsD;IACtD,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAC9B;AAED,yDAAyD;AACzD,MAAM,WAAW,YAAY;IAC3B,wBAAwB;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,wBAAwB;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,uEAAuE;IACvE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,IAAI,CAAA;IAChD,wCAAwC;IACxC,IAAI,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;IACrB,iDAAiD;IACjD,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IACvB,iDAAiD;IACjD,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,CAAA;CACpC;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,sDAAsD;IACtD,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;CAClD;AAED;;;;GAIG;AACH,qBAAa,cAAe,YAAW,aAAa;IAClD,iDAAiD;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAClC,mHAAmH;IACnH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAE3B;;;OAGG;gBACS,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,QAAQ,CAAA;KAAE;IAKjE;;;;;;;OAOG;IACG,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;CAwBxD;AAED,gDAAgD;AAChD,MAAM,WAAW,qBAAqB;IACpC,wDAAwD;IACxD,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAA;IACjC,6DAA6D;IAC7D,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAA;IACtC;;;;;;;OAOG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;IACzC;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACzE;AAED;;;;GAIG;AACH,qBAAa,cAAe,YAAW,aAAa;IAClD,gEAAgE;IAChE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,oEAAoE;IACpE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,sFAAsF;IACtF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAuB;IACjD,uEAAuE;IACvE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqD;IAE/E;;;OAGG;gBACS,IAAI,EAAE,qBAAqB;IAOvC;;;;;;;;OAQG;IACG,IAAI,CAAC,eAAe,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;CAsFhE"}
@@ -0,0 +1,122 @@
1
+ import { RetryOptions } from './retry.js';
2
+ import { UrlGuard } from './url-guard.js';
3
+ /** Describes an outgoing HTTP request to the B2 API. */
4
+ export interface HttpRequest {
5
+ /** Fully qualified URL to send the request to. */
6
+ readonly url: string;
7
+ /** HTTP method. B2 uses GET for downloads (HEAD to fetch only headers) and POST for all other operations. */
8
+ readonly method: 'GET' | 'HEAD' | 'POST';
9
+ /** Request headers. Authorization and content-type are typically included. */
10
+ readonly headers?: Record<string, string>;
11
+ /** Request body. Used for POST requests (JSON payloads or file uploads). */
12
+ readonly body?: BodyInit | null;
13
+ /** Optional abort signal for request cancellation. */
14
+ readonly signal?: AbortSignal;
15
+ }
16
+ /** Represents a parsed HTTP response from the B2 API. */
17
+ export interface HttpResponse {
18
+ /** HTTP status code. */
19
+ readonly status: number;
20
+ /** Response headers. */
21
+ readonly headers: Headers;
22
+ /** Response body as a readable stream, or null for empty responses. */
23
+ readonly body: ReadableStream<Uint8Array> | null;
24
+ /** Parses the response body as JSON. */
25
+ json<T>(): Promise<T>;
26
+ /** Reads the response body as a UTF-8 string. */
27
+ text(): Promise<string>;
28
+ /** Reads the response body as an ArrayBuffer. */
29
+ arrayBuffer(): Promise<ArrayBuffer>;
30
+ }
31
+ /**
32
+ * Transport layer abstraction for sending HTTP requests.
33
+ * Implementations handle the actual network I/O and can be composed
34
+ * (e.g. wrapping a {@link FetchTransport} with a {@link RetryTransport}).
35
+ */
36
+ export interface HttpTransport {
37
+ /** Sends an HTTP request and returns the response. */
38
+ send(request: HttpRequest): Promise<HttpResponse>;
39
+ }
40
+ /**
41
+ * Default transport implementation using the global `fetch` API.
42
+ * Automatically sets the User-Agent header on each request and applies the
43
+ * SSRF {@link UrlGuard} (if configured) before opening the connection.
44
+ */
45
+ export declare class FetchTransport implements HttpTransport {
46
+ /** User-Agent string sent with every request. */
47
+ private readonly userAgent;
48
+ /** SSRF allow-list applied to every outgoing URL. Mutable so `B2Client.authorize()` can lock it down post-auth. */
49
+ readonly urlGuard: UrlGuard;
50
+ /**
51
+ * Creates a new FetchTransport.
52
+ * @param options - Optional configuration: custom User-Agent prefix and SSRF guard.
53
+ */
54
+ constructor(options?: {
55
+ userAgent?: string;
56
+ urlGuard?: UrlGuard;
57
+ });
58
+ /**
59
+ * Sends the request using the global `fetch` function.
60
+ * @param request - The HTTP request to execute.
61
+ *
62
+ * @returns The HTTP response.
63
+ *
64
+ * @throws B2SsrfError when the URL fails the configured SSRF guard.
65
+ */
66
+ send(request: HttpRequest): Promise<HttpResponse>;
67
+ }
68
+ /** Configuration for {@link RetryTransport}. */
69
+ export interface RetryTransportOptions {
70
+ /** The underlying transport to delegate requests to. */
71
+ readonly transport: HttpTransport;
72
+ /** Override default retry settings (max retries, delays). */
73
+ readonly retry?: Partial<RetryOptions>;
74
+ /**
75
+ * Callback invoked on expired auth token errors. Must refresh
76
+ * credentials AND return the fresh auth token. The transport
77
+ * substitutes the new token into `request.headers.Authorization`
78
+ * before retrying — without this, the retried request would still
79
+ * carry the expired token captured by the original caller and the
80
+ * loop would never make progress.
81
+ */
82
+ readonly onReauth?: () => Promise<string>;
83
+ /**
84
+ * Sleep implementation used between retry attempts. Defaults to the real
85
+ * `sleep` from `./retry.js`. Test code can inject a no-op to avoid real
86
+ * delays without relying on module mocking (which differs across runners).
87
+ *
88
+ * @internal
89
+ */
90
+ readonly sleepImpl?: (ms: number, signal?: AbortSignal) => Promise<void>;
91
+ }
92
+ /**
93
+ * Transport wrapper that adds automatic retry with exponential backoff.
94
+ * Handles transient B2 errors (408, 429, 503), expired auth tokens,
95
+ * and network failures. Delegates to an inner {@link HttpTransport}.
96
+ */
97
+ export declare class RetryTransport implements HttpTransport {
98
+ /** The wrapped transport that performs actual HTTP requests. */
99
+ private readonly inner;
100
+ /** Resolved retry options (defaults merged with user overrides). */
101
+ private readonly options;
102
+ /** Optional callback to refresh auth credentials on 401 — returns the fresh token. */
103
+ private readonly onReauth?;
104
+ /** Sleep implementation used between retries; injectable for tests. */
105
+ private readonly sleepImpl;
106
+ /**
107
+ * Creates a new RetryTransport.
108
+ * @param opts - Retry transport configuration.
109
+ */
110
+ constructor(opts: RetryTransportOptions);
111
+ /**
112
+ * Sends the request with automatic retry on transient failures.
113
+ * On expired auth tokens, calls {@link RetryTransportOptions.onReauth} and retries.
114
+ * @param originalRequest - The HTTP request to execute. The caller's
115
+ * reference is not mutated; on reauth, a copy with a refreshed
116
+ * Authorization header is sent.
117
+ *
118
+ * @returns The HTTP response.
119
+ */
120
+ send(originalRequest: HttpRequest): Promise<HttpResponse>;
121
+ }
122
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/http/transport.js"],"names":[],"mappings":"AAEA,OAAO,EAAyB,KAAK,YAAY,EAAyB,MAAM,YAAY,CAAA;AAC5F,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAGzC,wDAAwD;AACxD,MAAM,WAAW,WAAW;IAC1B,kDAAkD;IAClD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,6GAA6G;IAC7G,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAA;IACxC,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACzC,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAA;IAC/B,sDAAsD;IACtD,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAC9B;AAED,yDAAyD;AACzD,MAAM,WAAW,YAAY;IAC3B,wBAAwB;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,wBAAwB;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,uEAAuE;IACvE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,IAAI,CAAA;IAChD,wCAAwC;IACxC,IAAI,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;IACrB,iDAAiD;IACjD,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IACvB,iDAAiD;IACjD,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,CAAA;CACpC;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,sDAAsD;IACtD,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;CAClD;AAED;;;;GAIG;AACH,qBAAa,cAAe,YAAW,aAAa;IAClD,iDAAiD;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAClC,mHAAmH;IACnH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAE3B;;;OAGG;gBACS,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,QAAQ,CAAA;KAAE;IAKjE;;;;;;;OAOG;IACG,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;CAwBxD;AAED,gDAAgD;AAChD,MAAM,WAAW,qBAAqB;IACpC,wDAAwD;IACxD,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAA;IACjC,6DAA6D;IAC7D,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAA;IACtC;;;;;;;OAOG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;IACzC;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACzE;AAED;;;;GAIG;AACH,qBAAa,cAAe,YAAW,aAAa;IAClD,gEAAgE;IAChE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,oEAAoE;IACpE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,sFAAsF;IACtF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAuB;IACjD,uEAAuE;IACvE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqD;IAE/E;;;OAGG;gBACS,IAAI,EAAE,qBAAqB;IAOvC;;;;;;;;OAQG;IACG,IAAI,CAAC,eAAe,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;CAsFhE"}
@@ -0,0 +1,143 @@
1
+ import { classifyError, ExpiredAuthTokenError, B2Error, NetworkError } from "../errors/index.js";
2
+ import { DEFAULT_RETRY_OPTIONS, sleep, computeBackoff } from "./retry.js";
3
+ import { UrlGuard } from "./url-guard.js";
4
+ import { getUserAgent } from "./user-agent.js";
5
+ class FetchTransport {
6
+ /** User-Agent string sent with every request. */
7
+ userAgent;
8
+ /** SSRF allow-list applied to every outgoing URL. Mutable so `B2Client.authorize()` can lock it down post-auth. */
9
+ urlGuard;
10
+ /**
11
+ * Creates a new FetchTransport.
12
+ * @param options - Optional configuration: custom User-Agent prefix and SSRF guard.
13
+ */
14
+ constructor(options) {
15
+ this.userAgent = getUserAgent(options?.userAgent);
16
+ this.urlGuard = options?.urlGuard ?? new UrlGuard();
17
+ }
18
+ /**
19
+ * Sends the request using the global `fetch` function.
20
+ * @param request - The HTTP request to execute.
21
+ *
22
+ * @returns The HTTP response.
23
+ *
24
+ * @throws B2SsrfError when the URL fails the configured SSRF guard.
25
+ */
26
+ async send(request) {
27
+ this.urlGuard.check(request.url);
28
+ const headers = new Headers(request.headers);
29
+ if (!headers.has("User-Agent")) {
30
+ headers.set("User-Agent", this.userAgent);
31
+ }
32
+ const response = await fetch(request.url, {
33
+ method: request.method,
34
+ headers,
35
+ body: request.body ?? null,
36
+ ...request.signal !== void 0 ? { signal: request.signal } : {}
37
+ });
38
+ return {
39
+ status: response.status,
40
+ headers: response.headers,
41
+ body: response.body,
42
+ json: () => response.json(),
43
+ text: () => response.text(),
44
+ arrayBuffer: () => response.arrayBuffer()
45
+ };
46
+ }
47
+ }
48
+ class RetryTransport {
49
+ /** The wrapped transport that performs actual HTTP requests. */
50
+ inner;
51
+ /** Resolved retry options (defaults merged with user overrides). */
52
+ options;
53
+ /** Optional callback to refresh auth credentials on 401 — returns the fresh token. */
54
+ onReauth;
55
+ /** Sleep implementation used between retries; injectable for tests. */
56
+ sleepImpl;
57
+ /**
58
+ * Creates a new RetryTransport.
59
+ * @param opts - Retry transport configuration.
60
+ */
61
+ constructor(opts) {
62
+ this.inner = opts.transport;
63
+ this.options = { ...DEFAULT_RETRY_OPTIONS, ...opts.retry };
64
+ if (opts.onReauth !== void 0) this.onReauth = opts.onReauth;
65
+ this.sleepImpl = opts.sleepImpl ?? sleep;
66
+ }
67
+ /**
68
+ * Sends the request with automatic retry on transient failures.
69
+ * On expired auth tokens, calls {@link RetryTransportOptions.onReauth} and retries.
70
+ * @param originalRequest - The HTTP request to execute. The caller's
71
+ * reference is not mutated; on reauth, a copy with a refreshed
72
+ * Authorization header is sent.
73
+ *
74
+ * @returns The HTTP response.
75
+ */
76
+ async send(originalRequest) {
77
+ let request = originalRequest;
78
+ let lastError;
79
+ for (let attempt = 0; attempt <= this.options.maxRetries; attempt++) {
80
+ if (attempt > 0 && lastError) {
81
+ const retryAfter = lastError instanceof NetworkError ? void 0 : lastError.retryAfter;
82
+ const delay = computeBackoff(attempt - 1, this.options, retryAfter);
83
+ await this.sleepImpl(delay, request.signal);
84
+ }
85
+ try {
86
+ const response = await this.inner.send(request);
87
+ if (response.status >= 200 && response.status < 300) {
88
+ return response;
89
+ }
90
+ let errorBody;
91
+ try {
92
+ errorBody = await response.json();
93
+ } catch {
94
+ errorBody = {
95
+ status: response.status,
96
+ code: "internal_error",
97
+ message: `HTTP ${response.status}`
98
+ };
99
+ }
100
+ const retryAfterHeader = response.headers.get("Retry-After");
101
+ const retryAfterSec = retryAfterHeader ? Number.parseInt(retryAfterHeader, 10) : void 0;
102
+ const requestId = response.headers.get("X-Bz-Request-Id") ?? void 0;
103
+ const error = classifyError(errorBody, {
104
+ ...retryAfterSec !== void 0 ? { retryAfter: retryAfterSec } : {},
105
+ ...requestId !== void 0 ? { requestId } : {}
106
+ });
107
+ if (error instanceof ExpiredAuthTokenError && this.onReauth) {
108
+ const freshToken = await this.onReauth();
109
+ request = {
110
+ ...request,
111
+ headers: { ...request.headers ?? {}, Authorization: freshToken }
112
+ };
113
+ continue;
114
+ }
115
+ if (!error.retryable || attempt === this.options.maxRetries) {
116
+ throw error;
117
+ }
118
+ lastError = error;
119
+ } catch (err) {
120
+ if (err instanceof B2Error || err instanceof NetworkError) {
121
+ throw err;
122
+ }
123
+ if (err instanceof DOMException && err.name === "AbortError") {
124
+ throw err;
125
+ }
126
+ const networkErr = new NetworkError(
127
+ err instanceof Error ? err.message : "Network error",
128
+ err
129
+ );
130
+ if (attempt === this.options.maxRetries) {
131
+ throw networkErr;
132
+ }
133
+ lastError = networkErr;
134
+ }
135
+ }
136
+ throw lastError ?? new NetworkError("Max retries exceeded");
137
+ }
138
+ }
139
+ export {
140
+ FetchTransport,
141
+ RetryTransport
142
+ };
143
+ //# sourceMappingURL=transport.js.map