@backblaze-labs/b2-sdk 0.3.0 → 0.4.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 (393) hide show
  1. package/CHANGELOG.md +45 -1
  2. package/README.md +18 -5
  3. package/dist/_virtual/_b2-sdk-version-json.cjs +1 -1
  4. package/dist/_virtual/_b2-sdk-version-json.js +1 -1
  5. package/dist/auth/reauth-coalescer.cjs +65 -0
  6. package/dist/auth/reauth-coalescer.cjs.map +1 -0
  7. package/dist/auth/reauth-coalescer.d.cts +34 -0
  8. package/dist/auth/reauth-coalescer.d.cts.map +1 -0
  9. package/dist/auth/reauth-coalescer.d.ts +34 -0
  10. package/dist/auth/reauth-coalescer.d.ts.map +1 -0
  11. package/dist/auth/reauth-coalescer.js +65 -0
  12. package/dist/auth/reauth-coalescer.js.map +1 -0
  13. package/dist/backup/raw.cjs +37 -15
  14. package/dist/backup/raw.cjs.map +1 -1
  15. package/dist/backup/raw.d.cts +2 -2
  16. package/dist/backup/raw.d.cts.map +1 -1
  17. package/dist/backup/raw.d.ts +2 -2
  18. package/dist/backup/raw.d.ts.map +1 -1
  19. package/dist/backup/raw.js +37 -15
  20. package/dist/backup/raw.js.map +1 -1
  21. package/dist/bucket-validation.cjs +111 -0
  22. package/dist/bucket-validation.cjs.map +1 -0
  23. package/dist/bucket-validation.d.cts +27 -0
  24. package/dist/bucket-validation.d.cts.map +1 -0
  25. package/dist/bucket-validation.d.ts +27 -0
  26. package/dist/bucket-validation.d.ts.map +1 -0
  27. package/dist/bucket-validation.js +109 -0
  28. package/dist/bucket-validation.js.map +1 -0
  29. package/dist/bucket.cjs +123 -73
  30. package/dist/bucket.cjs.map +1 -1
  31. package/dist/bucket.d.cts +156 -61
  32. package/dist/bucket.d.cts.map +1 -1
  33. package/dist/bucket.d.ts +156 -61
  34. package/dist/bucket.d.ts.map +1 -1
  35. package/dist/bucket.js +123 -73
  36. package/dist/bucket.js.map +1 -1
  37. package/dist/client.cjs +29 -8
  38. package/dist/client.cjs.map +1 -1
  39. package/dist/client.d.cts +30 -9
  40. package/dist/client.d.cts.map +1 -1
  41. package/dist/client.d.ts +30 -9
  42. package/dist/client.d.ts.map +1 -1
  43. package/dist/client.js +29 -8
  44. package/dist/client.js.map +1 -1
  45. package/dist/download/single.cjs +38 -13
  46. package/dist/download/single.cjs.map +1 -1
  47. package/dist/download/single.d.cts +10 -4
  48. package/dist/download/single.d.cts.map +1 -1
  49. package/dist/download/single.d.ts +10 -4
  50. package/dist/download/single.d.ts.map +1 -1
  51. package/dist/download/single.js +38 -13
  52. package/dist/download/single.js.map +1 -1
  53. package/dist/errors/index.cjs +27 -4
  54. package/dist/errors/index.cjs.map +1 -1
  55. package/dist/errors/index.d.cts +15 -0
  56. package/dist/errors/index.d.cts.map +1 -1
  57. package/dist/errors/index.d.ts +15 -0
  58. package/dist/errors/index.d.ts.map +1 -1
  59. package/dist/errors/index.js +27 -5
  60. package/dist/errors/index.js.map +1 -1
  61. package/dist/http/non-idempotent-mutations.cjs +38 -0
  62. package/dist/http/non-idempotent-mutations.cjs.map +1 -0
  63. package/dist/http/non-idempotent-mutations.d.cts +25 -0
  64. package/dist/http/non-idempotent-mutations.d.cts.map +1 -0
  65. package/dist/http/non-idempotent-mutations.d.ts +25 -0
  66. package/dist/http/non-idempotent-mutations.d.ts.map +1 -0
  67. package/dist/http/non-idempotent-mutations.js +35 -0
  68. package/dist/http/non-idempotent-mutations.js.map +1 -0
  69. package/dist/http/transport.cjs +9 -8
  70. package/dist/http/transport.cjs.map +1 -1
  71. package/dist/http/transport.d.cts +5 -0
  72. package/dist/http/transport.d.cts.map +1 -1
  73. package/dist/http/transport.d.ts +5 -0
  74. package/dist/http/transport.d.ts.map +1 -1
  75. package/dist/http/transport.js +9 -8
  76. package/dist/http/transport.js.map +1 -1
  77. package/dist/http/user-agent.cjs +12 -1
  78. package/dist/http/user-agent.cjs.map +1 -1
  79. package/dist/http/user-agent.d.cts +8 -0
  80. package/dist/http/user-agent.d.cts.map +1 -1
  81. package/dist/http/user-agent.d.ts +8 -0
  82. package/dist/http/user-agent.d.ts.map +1 -1
  83. package/dist/http/user-agent.js +13 -3
  84. package/dist/http/user-agent.js.map +1 -1
  85. package/dist/index.cjs +25 -0
  86. package/dist/index.d.cts +10 -9
  87. package/dist/index.d.cts.map +1 -1
  88. package/dist/index.d.ts +10 -9
  89. package/dist/index.d.ts.map +1 -1
  90. package/dist/index.js +7 -6
  91. package/dist/notifications/index.cjs +3 -0
  92. package/dist/notifications/index.d.cts +2 -0
  93. package/dist/notifications/index.d.cts.map +1 -1
  94. package/dist/notifications/index.d.ts +2 -0
  95. package/dist/notifications/index.d.ts.map +1 -1
  96. package/dist/notifications/index.js +2 -1
  97. package/dist/object.cjs +12 -1
  98. package/dist/object.cjs.map +1 -1
  99. package/dist/object.d.cts +7 -1
  100. package/dist/object.d.cts.map +1 -1
  101. package/dist/object.d.ts +7 -1
  102. package/dist/object.d.ts.map +1 -1
  103. package/dist/object.js +12 -1
  104. package/dist/object.js.map +1 -1
  105. package/dist/partner/auth-core.cjs +4 -23
  106. package/dist/partner/auth-core.cjs.map +1 -1
  107. package/dist/partner/auth-core.d.cts +1 -1
  108. package/dist/partner/auth-core.d.cts.map +1 -1
  109. package/dist/partner/auth-core.d.ts +1 -1
  110. package/dist/partner/auth-core.d.ts.map +1 -1
  111. package/dist/partner/auth-core.js +5 -24
  112. package/dist/partner/auth-core.js.map +1 -1
  113. package/dist/partner/client.cjs +25 -10
  114. package/dist/partner/client.cjs.map +1 -1
  115. package/dist/partner/client.d.cts +32 -10
  116. package/dist/partner/client.d.cts.map +1 -1
  117. package/dist/partner/client.d.ts +32 -10
  118. package/dist/partner/client.d.ts.map +1 -1
  119. package/dist/partner/client.js +25 -10
  120. package/dist/partner/client.js.map +1 -1
  121. package/dist/partner/endpoint-url.cjs +1 -0
  122. package/dist/partner/endpoint-url.cjs.map +1 -1
  123. package/dist/partner/endpoint-url.d.cts +2 -0
  124. package/dist/partner/endpoint-url.d.cts.map +1 -1
  125. package/dist/partner/endpoint-url.d.ts +2 -0
  126. package/dist/partner/endpoint-url.d.ts.map +1 -1
  127. package/dist/partner/endpoint-url.js +1 -0
  128. package/dist/partner/endpoint-url.js.map +1 -1
  129. package/dist/partner/in-memory.cjs.map +1 -1
  130. package/dist/partner/in-memory.js.map +1 -1
  131. package/dist/partner/index.cjs +9 -0
  132. package/dist/partner/index.d.cts +11 -2
  133. package/dist/partner/index.d.cts.map +1 -1
  134. package/dist/partner/index.d.ts +11 -2
  135. package/dist/partner/index.d.ts.map +1 -1
  136. package/dist/partner/index.js +3 -1
  137. package/dist/partner/raw.cjs +52 -44
  138. package/dist/partner/raw.cjs.map +1 -1
  139. package/dist/partner/raw.d.cts +16 -19
  140. package/dist/partner/raw.d.cts.map +1 -1
  141. package/dist/partner/raw.d.ts +16 -19
  142. package/dist/partner/raw.d.ts.map +1 -1
  143. package/dist/partner/raw.js +52 -44
  144. package/dist/partner/raw.js.map +1 -1
  145. package/dist/partner/redaction.cjs +133 -108
  146. package/dist/partner/redaction.cjs.map +1 -1
  147. package/dist/partner/redaction.d.cts +47 -13
  148. package/dist/partner/redaction.d.cts.map +1 -1
  149. package/dist/partner/redaction.d.ts +47 -13
  150. package/dist/partner/redaction.d.ts.map +1 -1
  151. package/dist/partner/redaction.js +133 -109
  152. package/dist/partner/redaction.js.map +1 -1
  153. package/dist/raw/encoding.cjs +29 -10
  154. package/dist/raw/encoding.cjs.map +1 -1
  155. package/dist/raw/encoding.d.cts +3 -2
  156. package/dist/raw/encoding.d.cts.map +1 -1
  157. package/dist/raw/encoding.d.ts +3 -2
  158. package/dist/raw/encoding.d.ts.map +1 -1
  159. package/dist/raw/encoding.js +29 -10
  160. package/dist/raw/encoding.js.map +1 -1
  161. package/dist/raw/index.cjs +64 -39
  162. package/dist/raw/index.cjs.map +1 -1
  163. package/dist/raw/index.d.cts +21 -19
  164. package/dist/raw/index.d.cts.map +1 -1
  165. package/dist/raw/index.d.ts +21 -19
  166. package/dist/raw/index.d.ts.map +1 -1
  167. package/dist/raw/index.js +47 -40
  168. package/dist/raw/index.js.map +1 -1
  169. package/dist/raw/url.cjs.map +1 -1
  170. package/dist/raw/url.d.cts +3 -3
  171. package/dist/raw/url.d.ts +3 -3
  172. package/dist/raw/url.js.map +1 -1
  173. package/dist/simulator/index.cjs +456 -125
  174. package/dist/simulator/index.cjs.map +1 -1
  175. package/dist/simulator/index.d.cts +16 -1
  176. package/dist/simulator/index.d.cts.map +1 -1
  177. package/dist/simulator/index.d.ts +16 -1
  178. package/dist/simulator/index.d.ts.map +1 -1
  179. package/dist/simulator/index.js +449 -130
  180. package/dist/simulator/index.js.map +1 -1
  181. package/dist/simulator/partner-capabilities.cjs +77 -0
  182. package/dist/simulator/partner-capabilities.cjs.map +1 -0
  183. package/dist/simulator/partner-capabilities.d.cts +53 -0
  184. package/dist/simulator/partner-capabilities.d.cts.map +1 -0
  185. package/dist/simulator/partner-capabilities.d.ts +53 -0
  186. package/dist/simulator/partner-capabilities.d.ts.map +1 -0
  187. package/dist/simulator/partner-capabilities.js +73 -0
  188. package/dist/simulator/partner-capabilities.js.map +1 -0
  189. package/dist/simulator/partner.cjs +55 -61
  190. package/dist/simulator/partner.cjs.map +1 -1
  191. package/dist/simulator/partner.d.cts +5 -2
  192. package/dist/simulator/partner.d.cts.map +1 -1
  193. package/dist/simulator/partner.d.ts +5 -2
  194. package/dist/simulator/partner.d.ts.map +1 -1
  195. package/dist/simulator/partner.js +56 -61
  196. package/dist/simulator/partner.js.map +1 -1
  197. package/dist/simulator/validation.cjs +160 -30
  198. package/dist/simulator/validation.cjs.map +1 -1
  199. package/dist/simulator/validation.d.cts +28 -6
  200. package/dist/simulator/validation.d.cts.map +1 -1
  201. package/dist/simulator/validation.d.ts +28 -6
  202. package/dist/simulator/validation.d.ts.map +1 -1
  203. package/dist/simulator/validation.js +148 -31
  204. package/dist/simulator/validation.js.map +1 -1
  205. package/dist/streams/file-source.cjs +1 -1
  206. package/dist/streams/file-source.cjs.map +1 -1
  207. package/dist/streams/file-source.js +1 -1
  208. package/dist/streams/file-source.js.map +1 -1
  209. package/dist/streams/hash.cjs +246 -13
  210. package/dist/streams/hash.cjs.map +1 -1
  211. package/dist/streams/hash.d.cts +37 -12
  212. package/dist/streams/hash.d.cts.map +1 -1
  213. package/dist/streams/hash.d.ts +37 -12
  214. package/dist/streams/hash.d.ts.map +1 -1
  215. package/dist/streams/hash.js +246 -15
  216. package/dist/streams/hash.js.map +1 -1
  217. package/dist/streams/index.cjs +2 -0
  218. package/dist/streams/index.d.cts +1 -1
  219. package/dist/streams/index.d.cts.map +1 -1
  220. package/dist/streams/index.d.ts +1 -1
  221. package/dist/streams/index.d.ts.map +1 -1
  222. package/dist/streams/index.js +2 -2
  223. package/dist/streams/progress.cjs +63 -4
  224. package/dist/streams/progress.cjs.map +1 -1
  225. package/dist/streams/progress.d.cts +28 -2
  226. package/dist/streams/progress.d.cts.map +1 -1
  227. package/dist/streams/progress.d.ts +28 -2
  228. package/dist/streams/progress.d.ts.map +1 -1
  229. package/dist/streams/progress.js +63 -4
  230. package/dist/streams/progress.js.map +1 -1
  231. package/dist/sync/download-staging.cjs +147 -35
  232. package/dist/sync/download-staging.cjs.map +1 -1
  233. package/dist/sync/download-staging.d.cts +25 -2
  234. package/dist/sync/download-staging.d.cts.map +1 -1
  235. package/dist/sync/download-staging.d.ts +25 -2
  236. package/dist/sync/download-staging.d.ts.map +1 -1
  237. package/dist/sync/download-staging.js +146 -36
  238. package/dist/sync/download-staging.js.map +1 -1
  239. package/dist/sync/index.d.cts +1 -1
  240. package/dist/sync/index.d.cts.map +1 -1
  241. package/dist/sync/index.d.ts +1 -1
  242. package/dist/sync/index.d.ts.map +1 -1
  243. package/dist/sync/local-file-io.cjs +5 -1
  244. package/dist/sync/local-file-io.cjs.map +1 -1
  245. package/dist/sync/local-file-io.d.cts +2 -0
  246. package/dist/sync/local-file-io.d.cts.map +1 -1
  247. package/dist/sync/local-file-io.d.ts +2 -0
  248. package/dist/sync/local-file-io.d.ts.map +1 -1
  249. package/dist/sync/local-file-io.js +5 -1
  250. package/dist/sync/local-file-io.js.map +1 -1
  251. package/dist/sync/pairing.cjs +1 -0
  252. package/dist/sync/pairing.cjs.map +1 -1
  253. package/dist/sync/pairing.js +1 -0
  254. package/dist/sync/pairing.js.map +1 -1
  255. package/dist/sync/scanners/b2.cjs +2 -0
  256. package/dist/sync/scanners/b2.cjs.map +1 -1
  257. package/dist/sync/scanners/b2.d.cts.map +1 -1
  258. package/dist/sync/scanners/b2.d.ts.map +1 -1
  259. package/dist/sync/scanners/b2.js +2 -0
  260. package/dist/sync/scanners/b2.js.map +1 -1
  261. package/dist/sync/scanners/local.cjs +150 -33
  262. package/dist/sync/scanners/local.cjs.map +1 -1
  263. package/dist/sync/scanners/local.d.cts +6 -0
  264. package/dist/sync/scanners/local.d.cts.map +1 -1
  265. package/dist/sync/scanners/local.d.ts +6 -0
  266. package/dist/sync/scanners/local.d.ts.map +1 -1
  267. package/dist/sync/scanners/local.js +150 -33
  268. package/dist/sync/scanners/local.js.map +1 -1
  269. package/dist/sync/synchronizer.cjs +76 -29
  270. package/dist/sync/synchronizer.cjs.map +1 -1
  271. package/dist/sync/synchronizer.d.cts +1 -0
  272. package/dist/sync/synchronizer.d.cts.map +1 -1
  273. package/dist/sync/synchronizer.d.ts +1 -0
  274. package/dist/sync/synchronizer.d.ts.map +1 -1
  275. package/dist/sync/synchronizer.js +76 -29
  276. package/dist/sync/synchronizer.js.map +1 -1
  277. package/dist/sync/types.d.cts +19 -3
  278. package/dist/sync/types.d.cts.map +1 -1
  279. package/dist/sync/types.d.ts +19 -3
  280. package/dist/sync/types.d.ts.map +1 -1
  281. package/dist/types/backup.d.cts +6 -1
  282. package/dist/types/backup.d.cts.map +1 -1
  283. package/dist/types/backup.d.ts +6 -1
  284. package/dist/types/backup.d.ts.map +1 -1
  285. package/dist/types/bucket.cjs +81 -11
  286. package/dist/types/bucket.cjs.map +1 -1
  287. package/dist/types/bucket.d.cts +190 -39
  288. package/dist/types/bucket.d.cts.map +1 -1
  289. package/dist/types/bucket.d.ts +190 -39
  290. package/dist/types/bucket.d.ts.map +1 -1
  291. package/dist/types/bucket.js +67 -12
  292. package/dist/types/bucket.js.map +1 -1
  293. package/dist/types/download.cjs.map +1 -1
  294. package/dist/types/download.d.cts +3 -17
  295. package/dist/types/download.d.cts.map +1 -1
  296. package/dist/types/download.d.ts +3 -17
  297. package/dist/types/download.d.ts.map +1 -1
  298. package/dist/types/download.js.map +1 -1
  299. package/dist/types/encryption.cjs +18 -0
  300. package/dist/types/encryption.cjs.map +1 -1
  301. package/dist/types/encryption.d.cts +21 -11
  302. package/dist/types/encryption.d.cts.map +1 -1
  303. package/dist/types/encryption.d.ts +21 -11
  304. package/dist/types/encryption.d.ts.map +1 -1
  305. package/dist/types/encryption.js +18 -0
  306. package/dist/types/encryption.js.map +1 -1
  307. package/dist/types/file.cjs +3 -0
  308. package/dist/types/file.cjs.map +1 -1
  309. package/dist/types/file.d.cts +125 -16
  310. package/dist/types/file.d.cts.map +1 -1
  311. package/dist/types/file.d.ts +125 -16
  312. package/dist/types/file.d.ts.map +1 -1
  313. package/dist/types/file.js +3 -1
  314. package/dist/types/file.js.map +1 -1
  315. package/dist/types/index.d.cts +7 -7
  316. package/dist/types/index.d.cts.map +1 -1
  317. package/dist/types/index.d.ts +7 -7
  318. package/dist/types/index.d.ts.map +1 -1
  319. package/dist/types/key.d.cts +4 -3
  320. package/dist/types/key.d.cts.map +1 -1
  321. package/dist/types/key.d.ts +4 -3
  322. package/dist/types/key.d.ts.map +1 -1
  323. package/dist/types/notifications.cjs +30 -0
  324. package/dist/types/notifications.cjs.map +1 -1
  325. package/dist/types/notifications.d.cts +26 -1
  326. package/dist/types/notifications.d.cts.map +1 -1
  327. package/dist/types/notifications.d.ts +26 -1
  328. package/dist/types/notifications.d.ts.map +1 -1
  329. package/dist/types/notifications.js +29 -1
  330. package/dist/types/notifications.js.map +1 -1
  331. package/dist/types/partner.cjs.map +1 -1
  332. package/dist/types/partner.d.cts +28 -36
  333. package/dist/types/partner.d.cts.map +1 -1
  334. package/dist/types/partner.d.ts +28 -36
  335. package/dist/types/partner.d.ts.map +1 -1
  336. package/dist/types/partner.js.map +1 -1
  337. package/dist/types/upload.d.cts +4 -0
  338. package/dist/types/upload.d.cts.map +1 -1
  339. package/dist/types/upload.d.ts +4 -0
  340. package/dist/types/upload.d.ts.map +1 -1
  341. package/dist/upload/large.cjs +10 -7
  342. package/dist/upload/large.cjs.map +1 -1
  343. package/dist/upload/large.d.cts +15 -6
  344. package/dist/upload/large.d.cts.map +1 -1
  345. package/dist/upload/large.d.ts +15 -6
  346. package/dist/upload/large.d.ts.map +1 -1
  347. package/dist/upload/large.js +10 -7
  348. package/dist/upload/large.js.map +1 -1
  349. package/dist/upload/options.cjs.map +1 -1
  350. package/dist/upload/options.d.cts +12 -0
  351. package/dist/upload/options.d.cts.map +1 -1
  352. package/dist/upload/options.d.ts +12 -0
  353. package/dist/upload/options.d.ts.map +1 -1
  354. package/dist/upload/options.js.map +1 -1
  355. package/dist/upload/resume.cjs +4 -3
  356. package/dist/upload/resume.cjs.map +1 -1
  357. package/dist/upload/resume.d.cts +6 -4
  358. package/dist/upload/resume.d.cts.map +1 -1
  359. package/dist/upload/resume.d.ts +6 -4
  360. package/dist/upload/resume.d.ts.map +1 -1
  361. package/dist/upload/resume.js +4 -3
  362. package/dist/upload/resume.js.map +1 -1
  363. package/dist/upload/retry.cjs +17 -10
  364. package/dist/upload/retry.cjs.map +1 -1
  365. package/dist/upload/retry.d.cts.map +1 -1
  366. package/dist/upload/retry.d.ts.map +1 -1
  367. package/dist/upload/retry.js +17 -10
  368. package/dist/upload/retry.js.map +1 -1
  369. package/dist/upload/single.cjs +35 -31
  370. package/dist/upload/single.cjs.map +1 -1
  371. package/dist/upload/single.d.cts +6 -0
  372. package/dist/upload/single.d.cts.map +1 -1
  373. package/dist/upload/single.d.ts +6 -0
  374. package/dist/upload/single.d.ts.map +1 -1
  375. package/dist/upload/single.js +35 -31
  376. package/dist/upload/single.js.map +1 -1
  377. package/dist/upload/stream.cjs +12 -1
  378. package/dist/upload/stream.cjs.map +1 -1
  379. package/dist/upload/stream.d.cts +6 -0
  380. package/dist/upload/stream.d.cts.map +1 -1
  381. package/dist/upload/stream.d.ts +6 -0
  382. package/dist/upload/stream.d.ts.map +1 -1
  383. package/dist/upload/stream.js +12 -1
  384. package/dist/upload/stream.js.map +1 -1
  385. package/dist/version.cjs +56 -4
  386. package/dist/version.cjs.map +1 -1
  387. package/dist/version.d.cts +53 -4
  388. package/dist/version.d.cts.map +1 -1
  389. package/dist/version.d.ts +53 -4
  390. package/dist/version.d.ts.map +1 -1
  391. package/dist/version.js +52 -5
  392. package/dist/version.js.map +1 -1
  393. package/package.json +11 -4
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/errors/index.ts"],"sourcesContent":["/**\n * Typed error hierarchy for B2 API failures.\n *\n * Every B2 error response maps to a specific {@link B2Error} subclass.\n * Retry behavior is exposed through {@link B2Error.retryable}.\n * Examples include {@link ExpiredAuthTokenError} and {@link CapExceededError}.\n * Use {@link classifyError} to convert a raw error response into the\n * appropriate subclass.\n *\n * Convention: most `B2Error` subclasses represent failures returned by the B2\n * API. The client-side exceptions are {@link B2RealmConfigurationError} and\n * {@link B2PartnerAuthorizationError}; they extend `B2Error` so realm- and\n * Partner-authorization failures can be handled with the SDK error hierarchy\n * before or without a server round-trip.\n *\n * Other programming errors and SDK preconditions, such as \"not yet authorized\",\n * \"stream consumed twice\", or \"called before init\", use the native `Error`\n * constructor instead. The direct `Error` outliers are\n * {@link B2InsufficientCapabilityError}, {@link B2RedirectError},\n * {@link B2SsrfError}, {@link NetworkError},\n * {@link ResumeFileIdMismatchError}, {@link UploadResponseBodyError}, and\n * {@link FinishLargeFileResponseBodyError}.\n *\n * @packageDocumentation\n */\n\nimport { redactUrlForError } from '../internal/url-redaction.ts'\nimport {\n type B2ErrorCode,\n type B2ErrorResponse,\n KNOWN_B2_ERROR_CODES,\n type KnownB2ErrorCode,\n} from '../types/errors.ts'\nimport type { BucketId, LargeFileId } from '../types/ids.ts'\n\n/** Thrown when an explicit resumeFileId is not compatible with the requested upload. */\nexport class ResumeFileIdMismatchError extends Error {\n /** Caller-supplied unfinished large file ID that failed verification. */\n readonly fileId: LargeFileId\n /** Requested destination file name. */\n readonly fileName: string\n\n /**\n * Creates a new resume-file ID mismatch error.\n * @param fileId - Caller-supplied unfinished large file ID that failed verification.\n * @param fileName - Requested destination file name.\n */\n constructor(fileId: LargeFileId, fileName: string) {\n super(\n `uploadLargeFile: resumeFileId ${fileId} does not identify a compatible unfinished large file for ${fileName}.`,\n )\n this.name = 'ResumeFileIdMismatchError'\n this.fileId = fileId\n this.fileName = fileName\n }\n}\n\n/** Metadata captured from B2 error response headers. */\nexport interface B2ErrorOptions {\n /** Retry delay in seconds from the `Retry-After` response header, if present. */\n readonly retryAfter?: number\n /** B2 request ID from the `X-Bz-Request-Id` response header, if present. */\n readonly requestId?: string\n}\n\n/**\n * Base error class for all B2 API errors.\n * Contains the HTTP status, B2 error code, and retry metadata from the response.\n */\nexport class B2Error extends Error {\n /** HTTP status code returned by the B2 API. */\n readonly status: number\n /** B2 error code identifying the error type (e.g. `expired_auth_token`). */\n readonly code: B2ErrorCode\n /** B2 request ID from the `X-Bz-Request-Id` response header, if present. */\n readonly requestId?: string\n /** Retry delay in seconds from the `Retry-After` response header, if present. */\n readonly retryAfter?: number\n /** Whether this error is transient and the request can be retried. */\n readonly retryable: boolean\n\n /**\n * Creates a new B2Error instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional retry and request metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response.message)\n this.name = 'B2Error'\n this.status = response.status\n this.code = response.code\n if (options?.retryAfter !== undefined) this.retryAfter = options.retryAfter\n if (options?.requestId !== undefined) this.requestId = options.requestId\n this.retryable = isTransient(response.status, response.code)\n }\n}\n\n/** Thrown when the auth token has expired. Triggers automatic re-authorization. */\nexport class ExpiredAuthTokenError extends B2Error {\n /**\n * Creates a new ExpiredAuthTokenError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'ExpiredAuthTokenError'\n }\n}\n\n/** Thrown when the auth token is invalid or unauthorized. */\nexport class BadAuthTokenError extends B2Error {\n /**\n * Creates a new BadAuthTokenError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'BadAuthTokenError'\n }\n}\n\n/** Thrown when the B2 service is temporarily unavailable (HTTP 503). */\nexport class ServiceUnavailableError extends B2Error {\n /**\n * Creates a new ServiceUnavailableError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'ServiceUnavailableError'\n }\n}\n\n/** Thrown when B2 reports an internal server error. */\nexport class InternalError extends B2Error {\n /**\n * Creates a new InternalError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InternalError'\n }\n}\n\n/** Thrown when a request times out on the server side (HTTP 408). */\nexport class RequestTimeoutError extends B2Error {\n /**\n * Creates a new RequestTimeoutError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'RequestTimeoutError'\n }\n}\n\n/** Thrown when the client has sent too many requests (HTTP 429). */\nexport class TooManyRequestsError extends B2Error {\n /**\n * Creates a new TooManyRequestsError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'TooManyRequestsError'\n }\n}\n\n/** Thrown when the account has reached the maximum number of buckets. */\nexport class TooManyBucketsError extends B2Error {\n /**\n * Creates a new TooManyBucketsError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'TooManyBucketsError'\n }\n}\n\n/** Thrown when the bucket or request has reached the maximum number of files. */\nexport class TooManyFilesError extends B2Error {\n /**\n * Creates a new TooManyFilesError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'TooManyFilesError'\n }\n}\n\n/** Thrown when a storage, transaction, or download cap has been exceeded. */\nexport class CapExceededError extends B2Error {\n /**\n * Creates a new CapExceededError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'CapExceededError'\n }\n}\n\n/** Thrown when the application key does not have permission for the requested operation. */\nexport class AccessDeniedError extends B2Error {\n /**\n * Creates a new AccessDeniedError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'AccessDeniedError'\n }\n}\n\n/** Thrown when the requested file does not exist. */\nexport class FileNotPresentError extends B2Error {\n /**\n * Creates a new FileNotPresentError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'FileNotPresentError'\n }\n}\n\n/** Thrown when a requested B2 resource does not exist. */\nexport class NotFoundError extends B2Error {\n /**\n * Creates a new NotFoundError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'NotFoundError'\n }\n}\n\n/** Thrown when creating a bucket with a name that already exists in the account. */\nexport class DuplicateBucketNameError extends B2Error {\n /**\n * Creates a new DuplicateBucketNameError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'DuplicateBucketNameError'\n }\n}\n\n/** Thrown when a bucket name is malformed, reserved, or otherwise rejected by B2. */\nexport class InvalidBucketNameError extends B2Error {\n /**\n * Creates a new InvalidBucketNameError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidBucketNameError'\n }\n}\n\n/** Thrown when bucket metadata fails B2 validation. */\nexport class InvalidBucketInfoError extends B2Error {\n /**\n * Creates a new InvalidBucketInfoError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidBucketInfoError'\n }\n}\n\n/** Thrown when a bucket ID is malformed or does not identify a valid bucket. */\nexport class BadBucketIdError extends B2Error {\n /**\n * Creates a new BadBucketIdError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'BadBucketIdError'\n }\n}\n\n/** Thrown when the B2 endpoint does not allow the request method. */\nexport class MethodNotAllowedError extends B2Error {\n /**\n * Creates a new MethodNotAllowedError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'MethodNotAllowedError'\n }\n}\n\n/** Thrown when the request conflicts with current B2 resource state. */\nexport class ConflictError extends B2Error {\n /**\n * Creates a new ConflictError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'ConflictError'\n }\n}\n\n/** Thrown for general bad request errors (HTTP 400) not covered by a more specific subclass. */\nexport class BadRequestError extends B2Error {\n /**\n * Creates a new BadRequestError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'BadRequestError'\n }\n}\n\n/** Thrown when B2 cannot parse the JSON request body. */\nexport class BadJsonError extends B2Error {\n /**\n * Creates a new BadJsonError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'BadJsonError'\n }\n}\n\n/** Thrown when a bucket ID has a valid shape but does not identify a usable bucket. */\nexport class InvalidBucketIdError extends B2Error {\n /**\n * Creates a new InvalidBucketIdError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidBucketIdError'\n }\n}\n\n/** Thrown when a numeric request parameter is outside the allowed range. */\nexport class OutOfRangeError extends B2Error {\n /**\n * Creates a new OutOfRangeError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'OutOfRangeError'\n }\n}\n\n/** Thrown when a requested byte range cannot be satisfied. */\nexport class RangeNotSatisfiableError extends B2Error {\n /**\n * Creates a new RangeNotSatisfiableError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'RangeNotSatisfiableError'\n }\n}\n\n/** Thrown when a file name is malformed or otherwise rejected by B2. */\nexport class InvalidFileNameError extends B2Error {\n /**\n * Creates a new InvalidFileNameError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidFileNameError'\n }\n}\n\n/** Thrown when file metadata fails B2 validation. */\nexport class InvalidFileInfoError extends B2Error {\n /**\n * Creates a new InvalidFileInfoError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidFileInfoError'\n }\n}\n\n/** Thrown when a file ID is malformed or does not identify a valid file. */\nexport class InvalidFileIdError extends B2Error {\n /**\n * Creates a new InvalidFileIdError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidFileIdError'\n }\n}\n\n/** Thrown when a multipart upload part number is invalid. */\nexport class InvalidPartNumberError extends B2Error {\n /**\n * Creates a new InvalidPartNumberError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidPartNumberError'\n }\n}\n\n/**\n * Thrown when an upload URL is no longer valid and must be refreshed.\n *\n * Forward-compat insurance: B2 does not currently surface a distinct\n * error code for this case, so {@link classifyError} never actually\n * instantiates this class today. It's part of the public API so\n * consumers can pre-write `instanceof` checks; when B2 documents a\n * `bad_upload_url` (or similar) error code, the `classifyError`\n * switch gets a matching case and existing consumer code starts\n * catching the typed error without any changes on their side.\n *\n * Until then, expect `BadRequestError` for upload-URL invalidation\n * scenarios — that's what B2 currently returns.\n */\nexport class BadUploadUrlError extends B2Error {\n /**\n * Creates a new BadUploadUrlError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'BadUploadUrlError'\n }\n}\n\n/**\n * Thrown when the uploaded file's SHA-1 checksum does not match the\n * expected value.\n *\n * When B2 returns `bad_sha1_checksum`, {@link classifyError} instantiates\n * this class so callers can handle checksum failures with `instanceof`.\n * Generic `bad_request` checksum failures continue to classify as\n * {@link BadRequestError}.\n */\nexport class ChecksumMismatchError extends B2Error {\n /**\n * Creates a new ChecksumMismatchError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'ChecksumMismatchError'\n }\n}\n\n/** Thrown when a Partner group has reached its maximum member count. */\nexport class TooManyMembersError extends B2Error {\n /**\n * Creates a new TooManyMembersError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'TooManyMembersError'\n }\n}\n\n/**\n * Compatibility alias for the issue #167 Partner member-limit error name.\n * @deprecated Use {@link TooManyMembersError}.\n */\nexport const TooManyGroupMembersError = TooManyMembersError\n/** @deprecated Use {@link TooManyMembersError}. */\nexport type TooManyGroupMembersError = TooManyMembersError\n\n/** Thrown when a Partner group ID is malformed or does not identify a valid group. */\nexport class InvalidGroupIdError extends B2Error {\n /**\n * Creates a new InvalidGroupIdError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidGroupIdError'\n }\n}\n\n/** Thrown when a Partner member email address fails validation. */\nexport class InvalidEmailError extends B2Error {\n /**\n * Creates a new InvalidEmailError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidEmailError'\n }\n}\n\n/** Thrown when a Partner API region value is unsupported or malformed. */\nexport class InvalidRegionError extends B2Error {\n /**\n * Creates a new InvalidRegionError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidRegionError'\n }\n}\n\n/** Thrown when a Partner account SMS phone number fails validation. */\nexport class InvalidSmsPhoneError extends B2Error {\n /**\n * Creates a new InvalidSmsPhoneError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidSmsPhoneError'\n }\n}\n\n/**\n * Compatibility alias for the issue #167 Partner SMS-phone error name.\n * @deprecated Use {@link InvalidSmsPhoneError}.\n */\nexport const MissingSmsPhoneError = InvalidSmsPhoneError\n/** @deprecated Use {@link InvalidSmsPhoneError}. */\nexport type MissingSmsPhoneError = InvalidSmsPhoneError\n\n/**\n * Thrown when B2 returns `method_failure`.\n *\n * The documented Partner group-member creation flow uses this code after\n * server-side creation fails and Backblaze rolls back before callers retry.\n * The code itself is classified globally, so this class stays endpoint-neutral.\n */\nexport class MethodFailureError extends B2Error {\n /** Always `false` because callers should decide when a documented operation-level retry is safe. */\n override readonly retryable = false\n\n /**\n * Creates a new MethodFailureError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'MethodFailureError'\n }\n}\n\n/**\n * Compatibility alias for the issue #167 Partner group-member failure name.\n * @deprecated Use {@link MethodFailureError}.\n */\nexport const GroupMemberCreationFailedError = MethodFailureError\n/** @deprecated Use {@link MethodFailureError}. */\nexport type GroupMemberCreationFailedError = MethodFailureError\n\n/** Thrown when a Partner group member account ID fails validation. */\nexport class InvalidMemberAccountIdError extends B2Error {\n /**\n * Creates a new InvalidMemberAccountIdError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidMemberAccountIdError'\n }\n}\n\n/** Thrown when an account ID fails Partner or Computer Backup API validation. */\nexport class InvalidAccountIdError extends B2Error {\n /**\n * Creates a new InvalidAccountIdError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidAccountIdError'\n }\n}\n\n/** Thrown when a Computer Backup computer ID fails validation. */\nexport class InvalidComputerIdError extends B2Error {\n /**\n * Creates a new InvalidComputerIdError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidComputerIdError'\n }\n}\n\n/**\n * Thrown by client-side capability checks when the application key is missing\n * capabilities required by an operation. Not raised by the server.\n */\nexport class B2InsufficientCapabilityError extends Error {\n /** Capabilities that were required for the operation. */\n readonly required: readonly string[]\n /** Capabilities that the current key actually has. */\n readonly available: readonly string[]\n /** Capabilities present in `required` but not in `available`. */\n readonly missing: readonly string[]\n\n /**\n * Creates a new B2InsufficientCapabilityError instance.\n *\n * @param required - Capabilities the operation requires.\n * @param available - Capabilities the current key holds.\n * @param missing - The subset of required that isn't available.\n */\n constructor(\n required: readonly string[],\n available: readonly string[],\n missing: readonly string[],\n ) {\n super(`Application key is missing capabilities: ${missing.join(', ')}`)\n this.name = 'B2InsufficientCapabilityError'\n this.required = required\n this.available = available\n this.missing = missing\n }\n}\n\n/**\n * Thrown when the SDK is asked to fetch a URL whose host is outside the\n * authorized B2 realm. Defense against SSRF / URL-substitution attacks where\n * a compromised or hostile B2 endpoint returns an upload URL pointing at an\n * internal service (e.g. cloud metadata at `169.254.169.254`).\n *\n * Not retryable.\n */\nexport class B2SsrfError extends Error {\n /** Always `false` — this is a security failure, not transient. */\n readonly retryable = false\n\n /**\n * Creates a new {@link B2SsrfError}.\n *\n * @param message - Human-readable description of which URL was rejected and why.\n * @param url - The URL that was rejected. Stored as a sanitized URL.\n */\n constructor(message: string, url: string) {\n const safeUrl = redactUrlForError(url)\n super(`${message.split(url).join(safeUrl)} (${safeUrl})`)\n this.name = 'B2SsrfError'\n this.url = safeUrl\n }\n\n /** Sanitized URL that was rejected. */\n readonly url: string\n}\n\n/** Thrown when a configured auth realm cannot safely be used for authorization. */\nexport class B2RealmConfigurationError extends B2Error {\n /**\n * Creates a new B2RealmConfigurationError instance.\n *\n * @param message - Human-readable description of the invalid realm setting.\n */\n constructor(message: string) {\n super({ status: 400, code: 'bad_request', message })\n this.name = 'B2RealmConfigurationError'\n }\n}\n\n/** Thrown when Partner authorization returns unusable Partner/Backup auth data. */\nexport class B2PartnerAuthorizationError extends B2Error {\n /**\n * Creates a new B2PartnerAuthorizationError instance.\n *\n * @param message - Human-readable description of the invalid Partner authorization state.\n */\n constructor(message: string) {\n super({ status: 400, code: 'bad_request', message })\n this.name = 'B2PartnerAuthorizationError'\n }\n}\n\n/** Thrown when the SDK refuses to follow an HTTP redirect automatically. */\nexport class B2RedirectError extends Error {\n /** Always `false` because a blocked redirect is deterministic. */\n readonly retryable = false\n /** Sanitized request URL whose response attempted to redirect. */\n readonly url: string\n /** HTTP redirect status code, or 0 for an opaque browser redirect. */\n readonly status: number\n /** Sanitized redirect target, or `null` when no Location header was present. */\n readonly location: string | null\n\n /**\n * Creates a new B2RedirectError instance.\n *\n * @param url - Request URL whose response attempted to redirect. Stored as a sanitized URL.\n * @param status - HTTP redirect status code.\n * @param location - Redirect Location header, if present. Stored as a sanitized URL.\n */\n constructor(url: string, status: number, location: string | null) {\n const safeUrl = redactUrlForError(url)\n const safeLocation = location !== null ? redactUrlForError(location, { baseUrl: url }) : null\n super(\n safeLocation !== null\n ? `HTTP ${status} redirect blocked for ${safeUrl} to ${safeLocation}`\n : `HTTP ${status} redirect blocked for ${safeUrl}`,\n )\n this.name = 'B2RedirectError'\n this.url = safeUrl\n this.status = status\n this.location = safeLocation\n }\n}\n\n/** Thrown when a network-level failure occurs (DNS, TCP, TLS). Always retryable. */\nexport class NetworkError extends Error {\n /** Always `true` since network errors are transient. */\n readonly retryable = true\n\n /**\n * Creates a new NetworkError instance.\n * @param message - Human-readable description of the network failure.\n * @param cause - The underlying error that caused this failure, if any.\n */\n constructor(\n message: string,\n public override readonly cause?: unknown,\n ) {\n super(message)\n this.name = 'NetworkError'\n }\n}\n\n/**\n * Thrown when an upload POST returned a response but its body could not be\n * read. The upload may already have been stored by B2, so retrying this error\n * can create duplicate file versions or parts.\n */\nexport class UploadResponseBodyError extends Error {\n /** Underlying response body error, when available. */\n public override readonly cause?: unknown\n\n /**\n * Creates a new UploadResponseBodyError instance.\n * @param message - Human-readable description of the response read failure.\n * @param options - Optional cause.\n */\n constructor(\n message: string,\n options: {\n readonly cause?: unknown\n } = {},\n ) {\n super(message, { cause: options.cause })\n this.name = 'UploadResponseBodyError'\n if (options.cause !== undefined) this.cause = options.cause\n }\n}\n\n/**\n * Thrown when `b2_finish_large_file` returned a response but its body could not\n * be read. The large file may already be committed server-side, so high-level\n * upload paths do not cancel the large file after this error.\n */\nexport class FinishLargeFileResponseBodyError extends Error {\n /** Ambiguous large file ID that may already be committed server-side. */\n readonly fileId?: LargeFileId\n /** Bucket requested by the high-level upload, when available. */\n readonly bucketId?: BucketId\n /** File name requested by the high-level upload, when available. */\n readonly fileName?: string\n\n /**\n * Creates a new FinishLargeFileResponseBodyError instance.\n * @param message - Human-readable description of the response read failure.\n * @param options - Optional cause and reconciliation metadata.\n */\n constructor(\n message: string,\n options: {\n readonly cause?: unknown\n readonly fileId?: LargeFileId\n readonly bucketId?: BucketId\n readonly fileName?: string\n } = {},\n ) {\n super(message, { cause: options.cause })\n this.name = 'FinishLargeFileResponseBodyError'\n if (options.cause !== undefined) this.cause = options.cause\n if (options.fileId !== undefined) this.fileId = options.fileId\n if (options.bucketId !== undefined) this.bucketId = options.bucketId\n if (options.fileName !== undefined) this.fileName = options.fileName\n }\n}\n\nfunction isTransient(status: number, code: B2ErrorCode): boolean {\n // Request timeout + rate limit.\n if (status === 408 || status === 429) return true\n // Transient server errors: internal error (500), bad gateway (502), service\n // unavailable (503), gateway timeout (504). B2 documents 500 and 503 as\n // retryable; 502/504 are transient infrastructure failures. 501 (Not\n // Implemented) is deliberately excluded — it is deterministic, not transient.\n //\n // This is keyed on STATUS, not on the `internal_error` code: `RetryTransport`\n // synthesizes `{ code: 'internal_error' }` for any error response whose body\n // is not parseable JSON (see transport.ts), including bodyless 4xx like a 404\n // download miss. Treating that code as transient would wrongly retry 4xx.\n if (status === 500 || status === 502 || status === 503 || status === 504) return true\n if (code === 'expired_auth_token') return true\n if (code === 'service_unavailable' || code === 'request_timeout') return true\n return false\n}\n\nconst knownB2ErrorCodes: ReadonlySet<string> = new Set(KNOWN_B2_ERROR_CODES)\n\nfunction isKnownB2ErrorCode(code: B2ErrorCode): code is KnownB2ErrorCode {\n return knownB2ErrorCodes.has(code)\n}\n\nfunction assertNever(value: never): never {\n throw new Error(`Unhandled B2 error code: ${String(value)}`)\n}\n\nfunction classifyKnownError(\n response: B2ErrorResponse,\n code: KnownB2ErrorCode,\n options?: B2ErrorOptions,\n): B2Error {\n switch (code) {\n case 'expired_auth_token':\n return new ExpiredAuthTokenError(response, options)\n case 'bad_auth_token':\n case 'unauthorized':\n return new BadAuthTokenError(response, options)\n case 'bad_request':\n return new BadRequestError(response, options)\n case 'bad_bucket_name':\n case 'invalid_bucket_name':\n return new InvalidBucketNameError(response, options)\n case 'bad_bucket_id':\n return new BadBucketIdError(response, options)\n case 'not_found':\n return new NotFoundError(response, options)\n case 'method_not_allowed':\n return new MethodNotAllowedError(response, options)\n case 'request_timeout':\n return new RequestTimeoutError(response, options)\n case 'too_many_requests':\n return new TooManyRequestsError(response, options)\n case 'conflict':\n return new ConflictError(response, options)\n case 'duplicate_bucket_name':\n return new DuplicateBucketNameError(response, options)\n case 'too_many_buckets':\n return new TooManyBucketsError(response, options)\n case 'too_many_files':\n return new TooManyFilesError(response, options)\n case 'too_many_members':\n return new TooManyMembersError(response, options)\n case 'cap_exceeded':\n case 'storage_cap_exceeded':\n case 'transaction_cap_exceeded':\n case 'download_cap_exceeded':\n return new CapExceededError(response, options)\n case 'access_denied':\n return new AccessDeniedError(response, options)\n case 'service_unavailable':\n return new ServiceUnavailableError(response, options)\n case 'internal_error':\n return new InternalError(response, options)\n case 'bad_json':\n return new BadJsonError(response, options)\n case 'invalid_account_id':\n return new InvalidAccountIdError(response, options)\n case 'invalid_bucket_id':\n return new InvalidBucketIdError(response, options)\n case 'invalid_bucket_info':\n return new InvalidBucketInfoError(response, options)\n case 'invalid_computer_id':\n return new InvalidComputerIdError(response, options)\n case 'invalid_email':\n return new InvalidEmailError(response, options)\n case 'invalid_group_id':\n return new InvalidGroupIdError(response, options)\n case 'invalid_member_account_id':\n return new InvalidMemberAccountIdError(response, options)\n case 'invalid_region':\n return new InvalidRegionError(response, options)\n case 'invalid_sms_phone':\n return new InvalidSmsPhoneError(response, options)\n case 'file_not_present':\n case 'no_such_file':\n return new FileNotPresentError(response, options)\n case 'out_of_range':\n return new OutOfRangeError(response, options)\n case 'range_not_satisfiable':\n return new RangeNotSatisfiableError(response, options)\n case 'invalid_file_id':\n return new InvalidFileIdError(response, options)\n case 'invalid_file_name':\n return new InvalidFileNameError(response, options)\n case 'invalid_file_info':\n return new InvalidFileInfoError(response, options)\n case 'invalid_part_number':\n return new InvalidPartNumberError(response, options)\n case 'method_failure':\n return new MethodFailureError(response, options)\n case 'bad_sha1_checksum':\n return new ChecksumMismatchError(response, options)\n default:\n return assertNever(code)\n }\n}\n\nfunction classifyUnknownError(response: B2ErrorResponse, options?: B2ErrorOptions): B2Error {\n if (response.status === 429) return new TooManyRequestsError(response, options)\n if (response.status === 503) return new ServiceUnavailableError(response, options)\n if (response.status === 408) return new RequestTimeoutError(response, options)\n\n return new B2Error(response, options)\n}\n\n/**\n * Maps a B2 error response to the appropriate {@link B2Error} subclass.\n * Uses known error codes for exact matching, then falls back to HTTP status\n * codes for unknown future B2 codes.\n *\n * Maintainer note: when B2 documents a new error code, add it to\n * `KNOWN_B2_ERROR_CODES` in `src/types/errors.ts` and add a matching\n * `classifyKnownError` switch case. Unknown codes fall through to the\n * HTTP-status-based heuristic and finally to a generic `B2Error`, which is\n * safe but loses semantic specificity (the caller can't `instanceof` against\n * a precise subclass and the retry decision relies on status alone).\n *\n * @param response - Parsed B2 error response body.\n * @param options - Optional retry and request metadata from response headers.\n *\n * @returns A typed B2Error subclass instance.\n */\nexport function classifyError(response: B2ErrorResponse, options?: B2ErrorOptions): B2Error {\n // `RetryTransport` and ranged-download parsing synthesize `internal_error`\n // when a non-JSON response body cannot provide a real B2 code. Only the\n // documented 500/internal_error pair should classify as InternalError.\n if (response.code === 'internal_error' && response.status !== 500) {\n return classifyUnknownError(response, options)\n }\n\n if (isKnownB2ErrorCode(response.code)) return classifyKnownError(response, response.code, options)\n\n return classifyUnknownError(response, options)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/errors/index.ts"],"sourcesContent":["/**\n * Typed error hierarchy for B2 API failures.\n *\n * Every B2 error response maps to a specific {@link B2Error} subclass.\n * Retry behavior is exposed through {@link B2Error.retryable}.\n * Examples include {@link ExpiredAuthTokenError} and {@link CapExceededError}.\n * Use {@link classifyError} to convert a raw error response into the\n * appropriate subclass.\n *\n * Convention: most `B2Error` subclasses represent failures returned by the B2\n * API. The client-side exceptions are {@link B2BucketConfigurationError},\n * {@link B2RealmConfigurationError}, and {@link B2PartnerAuthorizationError};\n * they extend `B2Error` so validation, realm-, and Partner-authorization\n * failures can be handled with the SDK error hierarchy before or without a\n * server round-trip.\n *\n * Other programming errors and SDK preconditions, such as \"not yet authorized\",\n * \"stream consumed twice\", or \"called before init\", use the native `Error`\n * constructor instead. The direct `Error` outliers are\n * {@link B2InsufficientCapabilityError}, {@link B2RedirectError},\n * {@link B2SsrfError}, {@link NetworkError},\n * {@link ResumeFileIdMismatchError}, {@link UploadResponseBodyError}, and\n * {@link FinishLargeFileResponseBodyError}.\n *\n * @packageDocumentation\n */\n\nimport { redactUrlForError } from '../internal/url-redaction.ts'\nimport {\n type B2ErrorCode,\n type B2ErrorResponse,\n KNOWN_B2_ERROR_CODES,\n type KnownB2ErrorCode,\n} from '../types/errors.ts'\nimport type { BucketId, LargeFileId } from '../types/ids.ts'\n\n/** Thrown when an explicit resumeFileId is not compatible with the requested upload. */\nexport class ResumeFileIdMismatchError extends Error {\n /** Caller-supplied unfinished large file ID that failed verification. */\n readonly fileId: LargeFileId\n /** Requested destination file name. */\n readonly fileName: string\n\n /**\n * Creates a new resume-file ID mismatch error.\n * @param fileId - Caller-supplied unfinished large file ID that failed verification.\n * @param fileName - Requested destination file name.\n */\n constructor(fileId: LargeFileId, fileName: string) {\n super(\n `uploadLargeFile: resumeFileId ${fileId} does not identify a compatible unfinished large file for ${fileName}.`,\n )\n this.name = 'ResumeFileIdMismatchError'\n this.fileId = fileId\n this.fileName = fileName\n }\n}\n\n/** Metadata captured from B2 error response headers. */\nexport interface B2ErrorOptions {\n /** Retry delay in seconds from the `Retry-After` response header, if present. */\n readonly retryAfter?: number\n /** B2 request ID from the `X-Bz-Request-Id` response header, if present. */\n readonly requestId?: string\n}\n\n/**\n * Base error class for all B2 API errors.\n * Contains the HTTP status, B2 error code, and retry metadata from the response.\n */\nexport class B2Error extends Error {\n /** HTTP status code returned by the B2 API. */\n readonly status: number\n /** B2 error code identifying the error type (e.g. `expired_auth_token`). */\n readonly code: B2ErrorCode\n /** B2 request ID from the `X-Bz-Request-Id` response header, if present. */\n readonly requestId?: string\n /** Retry delay in seconds from the `Retry-After` response header, if present. */\n readonly retryAfter?: number\n /** Whether this error is transient and the request can be retried. */\n readonly retryable: boolean\n\n /**\n * Creates a new B2Error instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional retry and request metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response.message)\n this.name = 'B2Error'\n this.status = response.status\n this.code = response.code\n if (options?.retryAfter !== undefined) this.retryAfter = options.retryAfter\n if (options?.requestId !== undefined) this.requestId = options.requestId\n this.retryable = isTransient(response.status, response.code)\n }\n}\n\n/** Thrown when the auth token has expired. Triggers automatic re-authorization. */\nexport class ExpiredAuthTokenError extends B2Error {\n /**\n * Creates a new ExpiredAuthTokenError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'ExpiredAuthTokenError'\n }\n}\n\n/** Thrown when the auth token is invalid or unauthorized. */\nexport class BadAuthTokenError extends B2Error {\n /**\n * Creates a new BadAuthTokenError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'BadAuthTokenError'\n }\n}\n\n/** Thrown when the B2 service is temporarily unavailable (HTTP 503). */\nexport class ServiceUnavailableError extends B2Error {\n /**\n * Creates a new ServiceUnavailableError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'ServiceUnavailableError'\n }\n}\n\n/** Thrown when B2 reports an internal server error. */\nexport class InternalError extends B2Error {\n /**\n * Creates a new InternalError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InternalError'\n }\n}\n\n/** Thrown when a request times out on the server side (HTTP 408). */\nexport class RequestTimeoutError extends B2Error {\n /**\n * Creates a new RequestTimeoutError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'RequestTimeoutError'\n }\n}\n\n/** Thrown when the client has sent too many requests (HTTP 429). */\nexport class TooManyRequestsError extends B2Error {\n /**\n * Creates a new TooManyRequestsError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'TooManyRequestsError'\n }\n}\n\n/** Thrown when the account has reached the maximum number of buckets. */\nexport class TooManyBucketsError extends B2Error {\n /**\n * Creates a new TooManyBucketsError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'TooManyBucketsError'\n }\n}\n\n/** Thrown when the bucket or request has reached the maximum number of files. */\nexport class TooManyFilesError extends B2Error {\n /**\n * Creates a new TooManyFilesError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'TooManyFilesError'\n }\n}\n\n/** Thrown when a storage, transaction, or download cap has been exceeded. */\nexport class CapExceededError extends B2Error {\n /**\n * Creates a new CapExceededError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'CapExceededError'\n }\n}\n\n/** Thrown when the application key does not have permission for the requested operation. */\nexport class AccessDeniedError extends B2Error {\n /**\n * Creates a new AccessDeniedError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'AccessDeniedError'\n }\n}\n\n/** Thrown when the requested file does not exist. */\nexport class FileNotPresentError extends B2Error {\n /**\n * Creates a new FileNotPresentError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'FileNotPresentError'\n }\n}\n\n/** Thrown when a requested B2 resource does not exist. */\nexport class NotFoundError extends B2Error {\n /**\n * Creates a new NotFoundError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'NotFoundError'\n }\n}\n\n/** Thrown when creating a bucket with a name that already exists in the account. */\nexport class DuplicateBucketNameError extends B2Error {\n /**\n * Creates a new DuplicateBucketNameError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'DuplicateBucketNameError'\n }\n}\n\n/** Thrown when a bucket name is malformed, reserved, or otherwise rejected by B2. */\nexport class InvalidBucketNameError extends B2Error {\n /**\n * Creates a new InvalidBucketNameError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidBucketNameError'\n }\n}\n\n/** Thrown when bucket metadata fails B2 validation. */\nexport class InvalidBucketInfoError extends B2Error {\n /**\n * Creates a new InvalidBucketInfoError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidBucketInfoError'\n }\n}\n\n/** Thrown when a bucket ID is malformed or does not identify a valid bucket. */\nexport class BadBucketIdError extends B2Error {\n /**\n * Creates a new BadBucketIdError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'BadBucketIdError'\n }\n}\n\n/** Thrown when the B2 endpoint does not allow the request method. */\nexport class MethodNotAllowedError extends B2Error {\n /**\n * Creates a new MethodNotAllowedError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'MethodNotAllowedError'\n }\n}\n\n/** Thrown when the request conflicts with current B2 resource state. */\nexport class ConflictError extends B2Error {\n /**\n * Creates a new ConflictError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'ConflictError'\n }\n}\n\n/** Thrown for general bad request errors (HTTP 400) not covered by a more specific subclass. */\nexport class BadRequestError extends B2Error {\n /**\n * Creates a new BadRequestError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'BadRequestError'\n }\n}\n\n/** Thrown when B2 cannot parse the JSON request body. */\nexport class BadJsonError extends B2Error {\n /**\n * Creates a new BadJsonError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'BadJsonError'\n }\n}\n\n/** Thrown when a bucket ID has a valid shape but does not identify a usable bucket. */\nexport class InvalidBucketIdError extends B2Error {\n /**\n * Creates a new InvalidBucketIdError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidBucketIdError'\n }\n}\n\n/** Thrown when a numeric request parameter is outside the allowed range. */\nexport class OutOfRangeError extends B2Error {\n /**\n * Creates a new OutOfRangeError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'OutOfRangeError'\n }\n}\n\n/** Thrown when a requested byte range cannot be satisfied. */\nexport class RangeNotSatisfiableError extends B2Error {\n /**\n * Creates a new RangeNotSatisfiableError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'RangeNotSatisfiableError'\n }\n}\n\n/** Thrown when a file name is malformed or otherwise rejected by B2. */\nexport class InvalidFileNameError extends B2Error {\n /**\n * Creates a new InvalidFileNameError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidFileNameError'\n }\n}\n\n/** Thrown when file metadata fails B2 validation. */\nexport class InvalidFileInfoError extends B2Error {\n /**\n * Creates a new InvalidFileInfoError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidFileInfoError'\n }\n}\n\n/** Thrown when a file ID is malformed or does not identify a valid file. */\nexport class InvalidFileIdError extends B2Error {\n /**\n * Creates a new InvalidFileIdError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidFileIdError'\n }\n}\n\n/** Thrown when a multipart upload part number is invalid. */\nexport class InvalidPartNumberError extends B2Error {\n /**\n * Creates a new InvalidPartNumberError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidPartNumberError'\n }\n}\n\n/**\n * Thrown when an upload URL is no longer valid and must be refreshed.\n *\n * Forward-compat insurance: B2 does not currently surface a distinct\n * error code for this case, so {@link classifyError} never actually\n * instantiates this class today. It's part of the public API so\n * consumers can pre-write `instanceof` checks; when B2 documents a\n * `bad_upload_url` (or similar) error code, the `classifyError`\n * switch gets a matching case and existing consumer code starts\n * catching the typed error without any changes on their side.\n *\n * Until then, expect `BadRequestError` for upload-URL invalidation\n * scenarios — that's what B2 currently returns.\n */\nexport class BadUploadUrlError extends B2Error {\n /**\n * Creates a new BadUploadUrlError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'BadUploadUrlError'\n }\n}\n\n/**\n * Thrown when the uploaded file's SHA-1 checksum does not match the\n * expected value.\n *\n * When B2 returns `bad_sha1_checksum`, {@link classifyError} instantiates\n * this class so callers can handle checksum failures with `instanceof`.\n * Generic `bad_request` checksum failures continue to classify as\n * {@link BadRequestError}.\n */\nexport class ChecksumMismatchError extends B2Error {\n /**\n * Creates a new ChecksumMismatchError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'ChecksumMismatchError'\n }\n}\n\n/** Thrown when a Partner group has reached its maximum member count. */\nexport class TooManyMembersError extends B2Error {\n /**\n * Creates a new TooManyMembersError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'TooManyMembersError'\n }\n}\n\n/**\n * Compatibility alias for the issue #167 Partner member-limit error name.\n * @deprecated Use {@link TooManyMembersError}.\n */\nexport const TooManyGroupMembersError = TooManyMembersError\n/** @deprecated Use {@link TooManyMembersError}. */\nexport type TooManyGroupMembersError = TooManyMembersError\n\n/** Thrown when a Partner group ID is malformed or does not identify a valid group. */\nexport class InvalidGroupIdError extends B2Error {\n /**\n * Creates a new InvalidGroupIdError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidGroupIdError'\n }\n}\n\n/** Thrown when a Partner member email address fails validation. */\nexport class InvalidEmailError extends B2Error {\n /**\n * Creates a new InvalidEmailError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidEmailError'\n }\n}\n\n/** Thrown when a Partner API region value is unsupported or malformed. */\nexport class InvalidRegionError extends B2Error {\n /**\n * Creates a new InvalidRegionError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidRegionError'\n }\n}\n\n/** Thrown when a Partner account SMS phone number fails validation. */\nexport class InvalidSmsPhoneError extends B2Error {\n /**\n * Creates a new InvalidSmsPhoneError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidSmsPhoneError'\n }\n}\n\n/**\n * Compatibility alias for the issue #167 Partner SMS-phone error name.\n * @deprecated Use {@link InvalidSmsPhoneError}.\n */\nexport const MissingSmsPhoneError = InvalidSmsPhoneError\n/** @deprecated Use {@link InvalidSmsPhoneError}. */\nexport type MissingSmsPhoneError = InvalidSmsPhoneError\n\n/**\n * Thrown when B2 returns `method_failure`.\n *\n * The documented Partner group-member creation flow uses this code after\n * server-side creation fails and Backblaze rolls back before callers retry.\n * The code itself is classified globally, so this class stays endpoint-neutral.\n */\nexport class MethodFailureError extends B2Error {\n /** Always `false` because callers should decide when a documented operation-level retry is safe. */\n override readonly retryable = false\n\n /**\n * Creates a new MethodFailureError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'MethodFailureError'\n }\n}\n\n/**\n * Compatibility alias for the issue #167 Partner group-member failure name.\n * @deprecated Use {@link MethodFailureError}.\n */\nexport const GroupMemberCreationFailedError = MethodFailureError\n/** @deprecated Use {@link MethodFailureError}. */\nexport type GroupMemberCreationFailedError = MethodFailureError\n\n/** Thrown when a Partner group member account ID fails validation. */\nexport class InvalidMemberAccountIdError extends B2Error {\n /**\n * Creates a new InvalidMemberAccountIdError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidMemberAccountIdError'\n }\n}\n\n/** Thrown when an account ID fails Partner or Computer Backup API validation. */\nexport class InvalidAccountIdError extends B2Error {\n /**\n * Creates a new InvalidAccountIdError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidAccountIdError'\n }\n}\n\n/** Thrown when a Computer Backup computer ID fails validation. */\nexport class InvalidComputerIdError extends B2Error {\n /**\n * Creates a new InvalidComputerIdError instance.\n * @param response - Parsed B2 error response body.\n * @param options - Optional metadata from response headers.\n */\n constructor(response: B2ErrorResponse, options?: B2ErrorOptions) {\n super(response, options)\n this.name = 'InvalidComputerIdError'\n }\n}\n\n/**\n * Thrown by client-side capability checks when the application key is missing\n * capabilities required by an operation. Not raised by the server.\n */\nexport class B2InsufficientCapabilityError extends Error {\n /** Capabilities that were required for the operation. */\n readonly required: readonly string[]\n /** Capabilities that the current key actually has. */\n readonly available: readonly string[]\n /** Capabilities present in `required` but not in `available`. */\n readonly missing: readonly string[]\n\n /**\n * Creates a new B2InsufficientCapabilityError instance.\n *\n * @param required - Capabilities the operation requires.\n * @param available - Capabilities the current key holds.\n * @param missing - The subset of required that isn't available.\n */\n constructor(\n required: readonly string[],\n available: readonly string[],\n missing: readonly string[],\n ) {\n super(`Application key is missing capabilities: ${missing.join(', ')}`)\n this.name = 'B2InsufficientCapabilityError'\n this.required = required\n this.available = available\n this.missing = missing\n }\n}\n\n/**\n * Thrown when the SDK is asked to fetch a URL whose host is outside the\n * authorized B2 realm. Defense against SSRF / URL-substitution attacks where\n * a compromised or hostile B2 endpoint returns an upload URL pointing at an\n * internal service (e.g. cloud metadata at `169.254.169.254`).\n *\n * Not retryable.\n */\nexport class B2SsrfError extends Error {\n /** Always `false` — this is a security failure, not transient. */\n readonly retryable = false\n\n /**\n * Creates a new {@link B2SsrfError}.\n *\n * @param message - Human-readable description of which URL was rejected and why.\n * @param url - The URL that was rejected. Stored as a sanitized URL.\n */\n constructor(message: string, url: string) {\n const safeUrl = redactUrlForError(url)\n super(`${message.split(url).join(safeUrl)} (${safeUrl})`)\n this.name = 'B2SsrfError'\n this.url = safeUrl\n }\n\n /** Sanitized URL that was rejected. */\n readonly url: string\n}\n\n/** Thrown when a configured auth realm cannot safely be used for authorization. */\nexport class B2RealmConfigurationError extends B2Error {\n /**\n * Creates a new B2RealmConfigurationError instance.\n *\n * @param message - Human-readable description of the invalid realm setting.\n */\n constructor(message: string) {\n super({ status: 400, code: 'bad_request', message })\n this.name = 'B2RealmConfigurationError'\n }\n}\n\n/** Thrown when Partner authorization returns unusable Partner/Backup auth data. */\nexport class B2PartnerAuthorizationError extends B2Error {\n /**\n * Creates a new B2PartnerAuthorizationError instance.\n *\n * @param message - Human-readable description of the invalid Partner authorization state.\n */\n constructor(message: string) {\n super({ status: 400, code: 'bad_request', message })\n this.name = 'B2PartnerAuthorizationError'\n }\n}\n\n/** Bucket create/update field rejected by client-side bucket configuration validation. */\nexport type B2BucketConfigurationErrorField = 'bucketInfo' | 'corsRules'\n\n/** Thrown when bucket create/update metadata fails SDK client-side validation. */\nexport class B2BucketConfigurationError extends B2Error {\n /** The request field that failed validation. */\n readonly field: B2BucketConfigurationErrorField\n\n /**\n * Creates a new B2BucketConfigurationError instance.\n *\n * @param field - The bucket configuration field that failed validation.\n * @param message - Human-readable validation failure.\n * @param code - B2-style error code for the rejected field.\n */\n constructor(\n field: B2BucketConfigurationErrorField,\n message: string,\n code: B2ErrorCode = 'bad_request',\n ) {\n super({ status: 400, code, message })\n this.name = 'B2BucketConfigurationError'\n this.field = field\n }\n}\n\n/** Thrown when the SDK refuses to follow an HTTP redirect automatically. */\nexport class B2RedirectError extends Error {\n /** Always `false` because a blocked redirect is deterministic. */\n readonly retryable = false\n /** Sanitized request URL whose response attempted to redirect. */\n readonly url: string\n /** HTTP redirect status code, or 0 for an opaque browser redirect. */\n readonly status: number\n /** Sanitized redirect target, or `null` when no Location header was present. */\n readonly location: string | null\n\n /**\n * Creates a new B2RedirectError instance.\n *\n * @param url - Request URL whose response attempted to redirect. Stored as a sanitized URL.\n * @param status - HTTP redirect status code.\n * @param location - Redirect Location header, if present. Stored as a sanitized URL.\n */\n constructor(url: string, status: number, location: string | null) {\n const safeUrl = redactUrlForError(url)\n const safeLocation = location !== null ? redactUrlForError(location, { baseUrl: url }) : null\n super(\n safeLocation !== null\n ? `HTTP ${status} redirect blocked for ${safeUrl} to ${safeLocation}`\n : `HTTP ${status} redirect blocked for ${safeUrl}`,\n )\n this.name = 'B2RedirectError'\n this.url = safeUrl\n this.status = status\n this.location = safeLocation\n }\n}\n\n/** Thrown when a network-level failure occurs (DNS, TCP, TLS). Always retryable. */\nexport class NetworkError extends Error {\n /** Always `true` since network errors are transient. */\n readonly retryable = true\n\n /**\n * Creates a new NetworkError instance.\n * @param message - Human-readable description of the network failure.\n * @param cause - The underlying error that caused this failure, if any.\n */\n constructor(\n message: string,\n public override readonly cause?: unknown,\n ) {\n super(message)\n this.name = 'NetworkError'\n }\n}\n\n/**\n * Thrown when an upload POST returned a response but its body could not be\n * read. The upload may already have been stored by B2, so retrying this error\n * can create duplicate file versions or parts.\n */\nexport class UploadResponseBodyError extends Error {\n /** Underlying response body error, when available. */\n public override readonly cause?: unknown\n\n /**\n * Creates a new UploadResponseBodyError instance.\n * @param message - Human-readable description of the response read failure.\n * @param options - Optional cause.\n */\n constructor(\n message: string,\n options: {\n readonly cause?: unknown\n } = {},\n ) {\n super(message, { cause: options.cause })\n this.name = 'UploadResponseBodyError'\n if (options.cause !== undefined) this.cause = options.cause\n }\n}\n\n/**\n * Thrown when `b2_finish_large_file` returned a response but its body could not\n * be read. The large file may already be committed server-side, so high-level\n * upload paths do not cancel the large file after this error.\n */\nexport class FinishLargeFileResponseBodyError extends Error {\n /** Ambiguous large file ID that may already be committed server-side. */\n readonly fileId?: LargeFileId\n /** Bucket requested by the high-level upload, when available. */\n readonly bucketId?: BucketId\n /** File name requested by the high-level upload, when available. */\n readonly fileName?: string\n\n /**\n * Creates a new FinishLargeFileResponseBodyError instance.\n * @param message - Human-readable description of the response read failure.\n * @param options - Optional cause and reconciliation metadata.\n */\n constructor(\n message: string,\n options: {\n readonly cause?: unknown\n readonly fileId?: LargeFileId\n readonly bucketId?: BucketId\n readonly fileName?: string\n } = {},\n ) {\n super(message, { cause: options.cause })\n this.name = 'FinishLargeFileResponseBodyError'\n if (options.cause !== undefined) this.cause = options.cause\n if (options.fileId !== undefined) this.fileId = options.fileId\n if (options.bucketId !== undefined) this.bucketId = options.bucketId\n if (options.fileName !== undefined) this.fileName = options.fileName\n }\n}\n\nfunction isTransient(status: number, code: B2ErrorCode): boolean {\n // Request timeout + rate limit.\n if (status === 408 || status === 429) return true\n // Transient server errors: internal error (500), bad gateway (502), service\n // unavailable (503), gateway timeout (504). B2 documents 500 and 503 as\n // retryable; 502/504 are transient infrastructure failures. 501 (Not\n // Implemented) is deliberately excluded — it is deterministic, not transient.\n //\n // This is keyed on STATUS, not on the `internal_error` code: `RetryTransport`\n // synthesizes `{ code: 'internal_error' }` for any error response whose body\n // is not parseable JSON (see transport.ts), including bodyless 4xx like a 404\n // download miss. Treating that code as transient would wrongly retry 4xx.\n if (status === 500 || status === 502 || status === 503 || status === 504) return true\n if (code === 'expired_auth_token') return true\n if (code === 'service_unavailable' || code === 'request_timeout') return true\n return false\n}\n\nconst knownB2ErrorCodes: ReadonlySet<string> = new Set(KNOWN_B2_ERROR_CODES)\n\nfunction isKnownB2ErrorCode(code: B2ErrorCode): code is KnownB2ErrorCode {\n return knownB2ErrorCodes.has(code)\n}\n\nfunction assertNever(value: never): never {\n throw new Error(`Unhandled B2 error code: ${String(value)}`)\n}\n\nfunction classifyKnownError(\n response: B2ErrorResponse,\n code: KnownB2ErrorCode,\n options?: B2ErrorOptions,\n): B2Error {\n switch (code) {\n case 'expired_auth_token':\n return new ExpiredAuthTokenError(response, options)\n case 'bad_auth_token':\n case 'unauthorized':\n return new BadAuthTokenError(response, options)\n case 'bad_request':\n return new BadRequestError(response, options)\n case 'bad_bucket_name':\n case 'invalid_bucket_name':\n return new InvalidBucketNameError(response, options)\n case 'bad_bucket_id':\n return new BadBucketIdError(response, options)\n case 'not_found':\n return new NotFoundError(response, options)\n case 'method_not_allowed':\n return new MethodNotAllowedError(response, options)\n case 'request_timeout':\n return new RequestTimeoutError(response, options)\n case 'too_many_requests':\n return new TooManyRequestsError(response, options)\n case 'conflict':\n return new ConflictError(response, options)\n case 'duplicate_bucket_name':\n return new DuplicateBucketNameError(response, options)\n case 'too_many_buckets':\n return new TooManyBucketsError(response, options)\n case 'too_many_files':\n return new TooManyFilesError(response, options)\n case 'too_many_members':\n return new TooManyMembersError(response, options)\n case 'cap_exceeded':\n case 'storage_cap_exceeded':\n case 'transaction_cap_exceeded':\n case 'download_cap_exceeded':\n return new CapExceededError(response, options)\n case 'access_denied':\n return new AccessDeniedError(response, options)\n case 'service_unavailable':\n return new ServiceUnavailableError(response, options)\n case 'internal_error':\n return new InternalError(response, options)\n case 'bad_json':\n return new BadJsonError(response, options)\n case 'invalid_account_id':\n return new InvalidAccountIdError(response, options)\n case 'invalid_bucket_id':\n return new InvalidBucketIdError(response, options)\n case 'invalid_bucket_info':\n return new InvalidBucketInfoError(response, options)\n case 'invalid_computer_id':\n return new InvalidComputerIdError(response, options)\n case 'invalid_email':\n return new InvalidEmailError(response, options)\n case 'invalid_group_id':\n return new InvalidGroupIdError(response, options)\n case 'invalid_member_account_id':\n return new InvalidMemberAccountIdError(response, options)\n case 'invalid_region':\n return new InvalidRegionError(response, options)\n case 'invalid_sms_phone':\n return new InvalidSmsPhoneError(response, options)\n case 'file_not_present':\n case 'no_such_file':\n return new FileNotPresentError(response, options)\n case 'out_of_range':\n return new OutOfRangeError(response, options)\n case 'range_not_satisfiable':\n return new RangeNotSatisfiableError(response, options)\n case 'invalid_file_id':\n return new InvalidFileIdError(response, options)\n case 'invalid_file_name':\n return new InvalidFileNameError(response, options)\n case 'invalid_file_info':\n return new InvalidFileInfoError(response, options)\n case 'invalid_part_number':\n return new InvalidPartNumberError(response, options)\n case 'method_failure':\n return new MethodFailureError(response, options)\n case 'bad_sha1_checksum':\n return new ChecksumMismatchError(response, options)\n default:\n return assertNever(code)\n }\n}\n\nfunction classifyUnknownError(response: B2ErrorResponse, options?: B2ErrorOptions): B2Error {\n if (response.status === 429) return new TooManyRequestsError(response, options)\n if (response.status === 503) return new ServiceUnavailableError(response, options)\n if (response.status === 408) return new RequestTimeoutError(response, options)\n\n return new B2Error(response, options)\n}\n\n/**\n * Maps a B2 error response to the appropriate {@link B2Error} subclass.\n * Uses known error codes for exact matching, then falls back to HTTP status\n * codes for unknown future B2 codes.\n *\n * Maintainer note: when B2 documents a new error code, add it to\n * `KNOWN_B2_ERROR_CODES` in `src/types/errors.ts` and add a matching\n * `classifyKnownError` switch case. Unknown codes fall through to the\n * HTTP-status-based heuristic and finally to a generic `B2Error`, which is\n * safe but loses semantic specificity (the caller can't `instanceof` against\n * a precise subclass and the retry decision relies on status alone).\n *\n * @param response - Parsed B2 error response body.\n * @param options - Optional retry and request metadata from response headers.\n *\n * @returns A typed B2Error subclass instance.\n */\nexport function classifyError(response: B2ErrorResponse, options?: B2ErrorOptions): B2Error {\n // `RetryTransport` and ranged-download parsing synthesize `internal_error`\n // when a non-JSON response body cannot provide a real B2 code. Only the\n // documented 500/internal_error pair should classify as InternalError.\n if (response.code === 'internal_error' && response.status !== 500) {\n return classifyUnknownError(response, options)\n }\n\n if (isKnownB2ErrorCode(response.code)) return classifyKnownError(response, response.code, options)\n\n return classifyUnknownError(response, options)\n}\n"],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ //#region src/http/non-idempotent-mutations.ts
2
+ /** Partner API endpoints that must not be automatically replayed. */
3
+ var PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINTS = [
4
+ "b2_create_group_member",
5
+ "b2_eject_group_member",
6
+ "b2_reserve_trial_create_account"
7
+ ];
8
+ /** Computer Backup API endpoints that must not be automatically replayed. */
9
+ var BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINTS = ["bz_delete_computer"];
10
+ var PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINT_SET = new Set(PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINTS);
11
+ var BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINT_SET = new Set(BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINTS);
12
+ /**
13
+ * Checks whether a Partner endpoint name is a non-idempotent mutation.
14
+ *
15
+ * @param endpoint - Partner endpoint name parsed from the request URL.
16
+ *
17
+ * @returns Whether the endpoint must opt out of automatic replay.
18
+ */
19
+ function isPartnerNonIdempotentMutationEndpoint(endpoint) {
20
+ return endpoint !== void 0 && PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINT_SET.has(endpoint);
21
+ }
22
+ /**
23
+ * Checks whether a Computer Backup endpoint name is a non-idempotent mutation.
24
+ *
25
+ * @param endpoint - Computer Backup endpoint name parsed from the request URL.
26
+ *
27
+ * @returns Whether the endpoint must opt out of automatic replay.
28
+ */
29
+ function isBackupNonIdempotentMutationEndpoint(endpoint) {
30
+ return endpoint !== void 0 && BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINT_SET.has(endpoint);
31
+ }
32
+ //#endregion
33
+ exports.BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINTS = BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINTS;
34
+ exports.PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINTS = PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINTS;
35
+ exports.isBackupNonIdempotentMutationEndpoint = isBackupNonIdempotentMutationEndpoint;
36
+ exports.isPartnerNonIdempotentMutationEndpoint = isPartnerNonIdempotentMutationEndpoint;
37
+
38
+ //# sourceMappingURL=non-idempotent-mutations.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"non-idempotent-mutations.cjs","names":[],"sources":["../../src/http/non-idempotent-mutations.ts"],"sourcesContent":["/** Partner API endpoints that must not be automatically replayed. */\nexport const PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINTS = [\n 'b2_create_group_member',\n 'b2_eject_group_member',\n 'b2_reserve_trial_create_account',\n] as const\n\n/** Computer Backup API endpoints that must not be automatically replayed. */\nexport const BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINTS = ['bz_delete_computer'] as const\n\n/** Partner endpoint name that requires replay opt-out handling. */\nexport type PartnerNonIdempotentMutationEndpoint =\n (typeof PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINTS)[number]\n\n/** Computer Backup endpoint name that requires replay opt-out handling. */\nexport type BackupNonIdempotentMutationEndpoint =\n (typeof BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINTS)[number]\n\nconst PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINT_SET: ReadonlySet<string> = new Set(\n PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINTS,\n)\nconst BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINT_SET: ReadonlySet<string> = new Set(\n BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINTS,\n)\n\n/**\n * Checks whether a Partner endpoint name is a non-idempotent mutation.\n *\n * @param endpoint - Partner endpoint name parsed from the request URL.\n *\n * @returns Whether the endpoint must opt out of automatic replay.\n */\nexport function isPartnerNonIdempotentMutationEndpoint(\n endpoint: string | undefined,\n): endpoint is PartnerNonIdempotentMutationEndpoint {\n return endpoint !== undefined && PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINT_SET.has(endpoint)\n}\n\n/**\n * Checks whether a Computer Backup endpoint name is a non-idempotent mutation.\n *\n * @param endpoint - Computer Backup endpoint name parsed from the request URL.\n *\n * @returns Whether the endpoint must opt out of automatic replay.\n */\nexport function isBackupNonIdempotentMutationEndpoint(\n endpoint: string | undefined,\n): endpoint is BackupNonIdempotentMutationEndpoint {\n return endpoint !== undefined && BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINT_SET.has(endpoint)\n}\n"],"mappings":";;AACA,IAAa,4CAA4C;CACvD;CACA;CACA;AACF;;AAGA,IAAa,2CAA2C,CAAC,oBAAoB;AAU7E,IAAM,+CAAoE,IAAI,IAC5E,yCACF;AACA,IAAM,8CAAmE,IAAI,IAC3E,wCACF;;;;;;;;AASA,SAAgB,uCACd,UACkD;CAClD,OAAO,aAAa,KAAA,KAAa,6CAA6C,IAAI,QAAQ;AAC5F;;;;;;;;AASA,SAAgB,sCACd,UACiD;CACjD,OAAO,aAAa,KAAA,KAAa,4CAA4C,IAAI,QAAQ;AAC3F"}
@@ -0,0 +1,25 @@
1
+ /** Partner API endpoints that must not be automatically replayed. */
2
+ export declare const PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINTS: readonly ["b2_create_group_member", "b2_eject_group_member", "b2_reserve_trial_create_account"];
3
+ /** Computer Backup API endpoints that must not be automatically replayed. */
4
+ export declare const BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINTS: readonly ["bz_delete_computer"];
5
+ /** Partner endpoint name that requires replay opt-out handling. */
6
+ export type PartnerNonIdempotentMutationEndpoint = (typeof PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINTS)[number];
7
+ /** Computer Backup endpoint name that requires replay opt-out handling. */
8
+ export type BackupNonIdempotentMutationEndpoint = (typeof BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINTS)[number];
9
+ /**
10
+ * Checks whether a Partner endpoint name is a non-idempotent mutation.
11
+ *
12
+ * @param endpoint - Partner endpoint name parsed from the request URL.
13
+ *
14
+ * @returns Whether the endpoint must opt out of automatic replay.
15
+ */
16
+ export declare function isPartnerNonIdempotentMutationEndpoint(endpoint: string | undefined): endpoint is PartnerNonIdempotentMutationEndpoint;
17
+ /**
18
+ * Checks whether a Computer Backup endpoint name is a non-idempotent mutation.
19
+ *
20
+ * @param endpoint - Computer Backup endpoint name parsed from the request URL.
21
+ *
22
+ * @returns Whether the endpoint must opt out of automatic replay.
23
+ */
24
+ export declare function isBackupNonIdempotentMutationEndpoint(endpoint: string | undefined): endpoint is BackupNonIdempotentMutationEndpoint;
25
+ //# sourceMappingURL=non-idempotent-mutations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"non-idempotent-mutations.d.ts","sourceRoot":"","sources":["../../src/http/non-idempotent-mutations.js"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,eAAO,MAAM,yCAAyC,iGAI5C,CAAA;AAEV,6EAA6E;AAC7E,eAAO,MAAM,wCAAwC,iCAAkC,CAAA;AAEvF,mEAAmE;AACnE,MAAM,MAAM,oCAAoC,GAC9C,CAAC,OAAO,yCAAyC,CAAC,CAAC,MAAM,CAAC,CAAA;AAE5D,2EAA2E;AAC3E,MAAM,MAAM,mCAAmC,GAC7C,CAAC,OAAO,wCAAwC,CAAC,CAAC,MAAM,CAAC,CAAA;AAS3D;;;;;;GAMG;AACH,wBAAgB,sCAAsC,CACpD,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,QAAQ,IAAI,oCAAoC,CAElD;AAED;;;;;;GAMG;AACH,wBAAgB,qCAAqC,CACnD,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,QAAQ,IAAI,mCAAmC,CAEjD"}
@@ -0,0 +1,25 @@
1
+ /** Partner API endpoints that must not be automatically replayed. */
2
+ export declare const PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINTS: readonly ["b2_create_group_member", "b2_eject_group_member", "b2_reserve_trial_create_account"];
3
+ /** Computer Backup API endpoints that must not be automatically replayed. */
4
+ export declare const BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINTS: readonly ["bz_delete_computer"];
5
+ /** Partner endpoint name that requires replay opt-out handling. */
6
+ export type PartnerNonIdempotentMutationEndpoint = (typeof PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINTS)[number];
7
+ /** Computer Backup endpoint name that requires replay opt-out handling. */
8
+ export type BackupNonIdempotentMutationEndpoint = (typeof BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINTS)[number];
9
+ /**
10
+ * Checks whether a Partner endpoint name is a non-idempotent mutation.
11
+ *
12
+ * @param endpoint - Partner endpoint name parsed from the request URL.
13
+ *
14
+ * @returns Whether the endpoint must opt out of automatic replay.
15
+ */
16
+ export declare function isPartnerNonIdempotentMutationEndpoint(endpoint: string | undefined): endpoint is PartnerNonIdempotentMutationEndpoint;
17
+ /**
18
+ * Checks whether a Computer Backup endpoint name is a non-idempotent mutation.
19
+ *
20
+ * @param endpoint - Computer Backup endpoint name parsed from the request URL.
21
+ *
22
+ * @returns Whether the endpoint must opt out of automatic replay.
23
+ */
24
+ export declare function isBackupNonIdempotentMutationEndpoint(endpoint: string | undefined): endpoint is BackupNonIdempotentMutationEndpoint;
25
+ //# sourceMappingURL=non-idempotent-mutations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"non-idempotent-mutations.d.ts","sourceRoot":"","sources":["../../src/http/non-idempotent-mutations.js"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,eAAO,MAAM,yCAAyC,iGAI5C,CAAA;AAEV,6EAA6E;AAC7E,eAAO,MAAM,wCAAwC,iCAAkC,CAAA;AAEvF,mEAAmE;AACnE,MAAM,MAAM,oCAAoC,GAC9C,CAAC,OAAO,yCAAyC,CAAC,CAAC,MAAM,CAAC,CAAA;AAE5D,2EAA2E;AAC3E,MAAM,MAAM,mCAAmC,GAC7C,CAAC,OAAO,wCAAwC,CAAC,CAAC,MAAM,CAAC,CAAA;AAS3D;;;;;;GAMG;AACH,wBAAgB,sCAAsC,CACpD,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,QAAQ,IAAI,oCAAoC,CAElD;AAED;;;;;;GAMG;AACH,wBAAgB,qCAAqC,CACnD,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,QAAQ,IAAI,mCAAmC,CAEjD"}
@@ -0,0 +1,35 @@
1
+ //#region src/http/non-idempotent-mutations.ts
2
+ /** Partner API endpoints that must not be automatically replayed. */
3
+ var PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINTS = [
4
+ "b2_create_group_member",
5
+ "b2_eject_group_member",
6
+ "b2_reserve_trial_create_account"
7
+ ];
8
+ /** Computer Backup API endpoints that must not be automatically replayed. */
9
+ var BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINTS = ["bz_delete_computer"];
10
+ var PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINT_SET = new Set(PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINTS);
11
+ var BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINT_SET = new Set(BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINTS);
12
+ /**
13
+ * Checks whether a Partner endpoint name is a non-idempotent mutation.
14
+ *
15
+ * @param endpoint - Partner endpoint name parsed from the request URL.
16
+ *
17
+ * @returns Whether the endpoint must opt out of automatic replay.
18
+ */
19
+ function isPartnerNonIdempotentMutationEndpoint(endpoint) {
20
+ return endpoint !== void 0 && PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINT_SET.has(endpoint);
21
+ }
22
+ /**
23
+ * Checks whether a Computer Backup endpoint name is a non-idempotent mutation.
24
+ *
25
+ * @param endpoint - Computer Backup endpoint name parsed from the request URL.
26
+ *
27
+ * @returns Whether the endpoint must opt out of automatic replay.
28
+ */
29
+ function isBackupNonIdempotentMutationEndpoint(endpoint) {
30
+ return endpoint !== void 0 && BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINT_SET.has(endpoint);
31
+ }
32
+ //#endregion
33
+ export { BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINTS, PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINTS, isBackupNonIdempotentMutationEndpoint, isPartnerNonIdempotentMutationEndpoint };
34
+
35
+ //# sourceMappingURL=non-idempotent-mutations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"non-idempotent-mutations.js","names":[],"sources":["../../src/http/non-idempotent-mutations.ts"],"sourcesContent":["/** Partner API endpoints that must not be automatically replayed. */\nexport const PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINTS = [\n 'b2_create_group_member',\n 'b2_eject_group_member',\n 'b2_reserve_trial_create_account',\n] as const\n\n/** Computer Backup API endpoints that must not be automatically replayed. */\nexport const BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINTS = ['bz_delete_computer'] as const\n\n/** Partner endpoint name that requires replay opt-out handling. */\nexport type PartnerNonIdempotentMutationEndpoint =\n (typeof PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINTS)[number]\n\n/** Computer Backup endpoint name that requires replay opt-out handling. */\nexport type BackupNonIdempotentMutationEndpoint =\n (typeof BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINTS)[number]\n\nconst PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINT_SET: ReadonlySet<string> = new Set(\n PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINTS,\n)\nconst BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINT_SET: ReadonlySet<string> = new Set(\n BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINTS,\n)\n\n/**\n * Checks whether a Partner endpoint name is a non-idempotent mutation.\n *\n * @param endpoint - Partner endpoint name parsed from the request URL.\n *\n * @returns Whether the endpoint must opt out of automatic replay.\n */\nexport function isPartnerNonIdempotentMutationEndpoint(\n endpoint: string | undefined,\n): endpoint is PartnerNonIdempotentMutationEndpoint {\n return endpoint !== undefined && PARTNER_NON_IDEMPOTENT_MUTATION_ENDPOINT_SET.has(endpoint)\n}\n\n/**\n * Checks whether a Computer Backup endpoint name is a non-idempotent mutation.\n *\n * @param endpoint - Computer Backup endpoint name parsed from the request URL.\n *\n * @returns Whether the endpoint must opt out of automatic replay.\n */\nexport function isBackupNonIdempotentMutationEndpoint(\n endpoint: string | undefined,\n): endpoint is BackupNonIdempotentMutationEndpoint {\n return endpoint !== undefined && BACKUP_NON_IDEMPOTENT_MUTATION_ENDPOINT_SET.has(endpoint)\n}\n"],"mappings":";;AACA,IAAa,4CAA4C;CACvD;CACA;CACA;AACF;;AAGA,IAAa,2CAA2C,CAAC,oBAAoB;AAU7E,IAAM,+CAAoE,IAAI,IAC5E,yCACF;AACA,IAAM,8CAAmE,IAAI,IAC3E,wCACF;;;;;;;;AASA,SAAgB,uCACd,UACkD;CAClD,OAAO,aAAa,KAAA,KAAa,6CAA6C,IAAI,QAAQ;AAC5F;;;;;;;;AASA,SAAgB,sCACd,UACiD;CACjD,OAAO,aAAa,KAAA,KAAa,4CAA4C,IAAI,QAAQ;AAC3F"}
@@ -1,6 +1,7 @@
1
1
  const require_errors_index = require("../errors/index.cjs");
2
2
  const require_abort = require("../util/abort.cjs");
3
3
  const require_retry = require("./retry.cjs");
4
+ const require_non_idempotent_mutations = require("./non-idempotent-mutations.cjs");
4
5
  const require_url_guard = require("./url-guard.cjs");
5
6
  const require_user_agent = require("./user-agent.cjs");
6
7
  //#region src/http/transport.ts
@@ -295,15 +296,14 @@ function isAuthorizeEndpoint(url) {
295
296
  function isStartLargeFileEndpoint(url) {
296
297
  return b2ApiEndpointName(url) === "b2_start_large_file";
297
298
  }
298
- function isPartnerMutationEndpoint(url) {
299
- const endpoint = b2ApiEndpointName(url);
300
- return endpoint === "b2_create_group_member" || endpoint === "b2_eject_group_member" || endpoint === "b2_reserve_trial_create_account";
299
+ function isKnownPartnerNonIdempotentMutationEndpoint(url) {
300
+ return require_non_idempotent_mutations.isPartnerNonIdempotentMutationEndpoint(b2ApiEndpointName(url));
301
301
  }
302
- function isBackupMutationEndpoint(url) {
303
- return backupApiEndpointName(url) === "bz_delete_computer";
302
+ function isKnownBackupNonIdempotentMutationEndpoint(url) {
303
+ return require_non_idempotent_mutations.isBackupNonIdempotentMutationEndpoint(backupApiEndpointName(url));
304
304
  }
305
305
  function isNonIdempotentMutationRequest(request) {
306
- return request.method === "POST" && (isPartnerMutationEndpoint(request.url) || isBackupMutationEndpoint(request.url));
306
+ return request.idempotent === false || request.method === "POST" && (isKnownPartnerNonIdempotentMutationEndpoint(request.url) || isKnownBackupNonIdempotentMutationEndpoint(request.url));
307
307
  }
308
308
  function b2ApiEndpointName(url) {
309
309
  const segments = new URL(url).pathname.split("/").filter((segment) => segment.length > 0);
@@ -318,7 +318,8 @@ function backupApiEndpointName(url) {
318
318
  if (!/^v\d+$/.test(segments[apiRootIndex + 2] ?? "")) return void 0;
319
319
  return segments[apiRootIndex + 3];
320
320
  }
321
- function isReplayUnsafePostRequest(request) {
321
+ function isReplayUnsafeRequest(request) {
322
+ if (request.idempotent === false) return true;
322
323
  if (request.method !== "POST") return false;
323
324
  return isUploadEndpoint(request.url) || isStartLargeFileEndpoint(request.url) || isFinishLargeFileEndpoint(request.url) || isNonIdempotentMutationRequest(request);
324
325
  }
@@ -455,7 +456,7 @@ var RetryTransport = class {
455
456
  require_abort.throwIfSignalAborted(request.signal);
456
457
  if (isTerminalTransportError(err)) throw err;
457
458
  const networkErr = new require_errors_index.NetworkError(err instanceof Error ? err.message : "Network error", err);
458
- if (isReplayUnsafePostRequest(request) || attempt === retryOptions.maxRetries) throw networkErr;
459
+ if (isReplayUnsafeRequest(request) || attempt === retryOptions.maxRetries) throw networkErr;
459
460
  lastError = networkErr;
460
461
  attempt += 1;
461
462
  }
@@ -1 +1 @@
1
- {"version":3,"file":"transport.cjs","names":[],"sources":["../../src/http/transport.ts"],"sourcesContent":["import {\n B2Error,\n B2RedirectError,\n B2SsrfError,\n classifyError,\n ExpiredAuthTokenError,\n NetworkError,\n} from '../errors/index.ts'\nimport type { B2ErrorResponse } from '../types/errors.ts'\nimport { abortReason, raceWithAbort, throwIfSignalAborted } from '../util/abort.ts'\nimport { computeBackoff, DEFAULT_RETRY_OPTIONS, type RetryOptions, sleep } from './retry.ts'\nimport { UrlGuard } from './url-guard.ts'\nimport { getUserAgent } from './user-agent.ts'\n\nconst REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308])\nconst MAX_SAME_ORIGIN_REDIRECTS = 5\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 /** Optional per-request retry override. */\n readonly retry?: Partial<RetryOptions>\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 * Transport capability for implementations that expose the SSRF URL guard\n * protecting credential-bearing requests. Wrappers that preserve this\n * capability should forward the same `urlGuard` property.\n */\nexport interface UrlGuardedTransport extends HttpTransport {\n /** SSRF allow-list applied to outgoing URLs. */\n readonly urlGuard: UrlGuard\n}\n\n/**\n * Returns the URL guard exposed by `transport`, if it implements\n * {@link UrlGuardedTransport}.\n *\n * @param transport - Transport to inspect.\n *\n * @returns The exposed URL guard, or undefined for unguarded transports.\n */\nexport function getTransportUrlGuard(transport: HttpTransport): UrlGuard | undefined {\n const candidate = transport as Partial<UrlGuardedTransport>\n return candidate.urlGuard instanceof UrlGuard ? candidate.urlGuard : undefined\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 * Redirect following is disabled so redirected URLs cannot bypass the guard or\n * receive credential-bearing headers without an explicit checked request.\n */\nexport class FetchTransport implements UrlGuardedTransport {\n /** User-Agent string sent with every request. */\n private readonly userAgent: string\n /** Whether same-origin GET/HEAD redirects should be followed after guard checks. */\n private readonly followSameOriginRedirects: boolean\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?: {\n userAgent?: string\n urlGuard?: UrlGuard\n /**\n * Follow same-origin GET/HEAD redirects after checking the target with the\n * URL guard. POST redirects are still blocked to avoid replaying\n * credential-bearing payloads to an unexpected endpoint. Defaults to true.\n */\n followSameOriginRedirects?: boolean\n }) {\n this.userAgent = getUserAgent(options?.userAgent)\n this.followSameOriginRedirects = options?.followSameOriginRedirects ?? true\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 * @throws B2RedirectError when a response attempts to redirect.\n */\n async send(request: HttpRequest): Promise<HttpResponse> {\n let currentRequest = request\n let redirectCount = 0\n\n while (true) {\n this.urlGuard.check(currentRequest.url)\n\n const headers = new Headers(currentRequest.headers)\n if (!headers.has('User-Agent')) {\n headers.set('User-Agent', this.userAgent)\n }\n\n const timeoutScope = createRequestTimeoutScope(currentRequest)\n let response: Response\n try {\n response = await fetch(currentRequest.url, {\n method: currentRequest.method,\n headers,\n body: currentRequest.body ?? null,\n redirect: 'manual',\n ...(timeoutScope.signal !== undefined ? { signal: timeoutScope.signal } : {}),\n })\n } catch (err) {\n timeoutScope.dispose()\n if (timeoutScope.timedOut) {\n throw createRequestTimeoutError(timeoutScope)\n }\n throw err\n }\n\n if (isBlockedRedirect(response)) {\n const location = response.headers.get('Location')\n if (\n this.followSameOriginRedirects &&\n location !== null &&\n redirectCount < MAX_SAME_ORIGIN_REDIRECTS &&\n canFollowSameOriginRedirect(currentRequest, location)\n ) {\n const nextUrl = new URL(location, currentRequest.url).toString()\n await cancelResponseBody(response)\n timeoutScope.dispose()\n this.urlGuard.check(nextUrl)\n currentRequest = { ...currentRequest, url: nextUrl }\n redirectCount += 1\n continue\n }\n\n await cancelResponseBody(response)\n timeoutScope.dispose()\n throw new B2RedirectError(currentRequest.url, response.status, location)\n }\n\n return createTimedHttpResponse(response, timeoutScope)\n }\n }\n}\n\ninterface RequestTimeoutScope {\n readonly signal?: AbortSignal\n readonly timeoutMs: number\n readonly timedOut: boolean\n reset(): void\n dispose(): void\n}\n\nfunction createRequestTimeoutScope(request: HttpRequest): RequestTimeoutScope {\n const timeoutMs = request.retry?.requestTimeoutMs ?? DEFAULT_RETRY_OPTIONS.requestTimeoutMs\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n const scope: RequestTimeoutScope = {\n timeoutMs: 0,\n timedOut: false,\n reset() {},\n dispose() {},\n }\n if (request.signal !== undefined) return { ...scope, signal: request.signal }\n return scope\n }\n\n const controller = new AbortController()\n let timedOut = false\n let timer: ReturnType<typeof setTimeout>\n const abortFromUpstream = (): void => {\n clearTimeout(timer)\n controller.abort(request.signal?.reason ?? new DOMException('Aborted', 'AbortError'))\n }\n const armTimer = (): ReturnType<typeof setTimeout> => {\n const nextTimer = setTimeout(() => {\n timedOut = true\n controller.abort(new DOMException('HTTP request timed out', 'TimeoutError'))\n }, timeoutMs)\n unrefTimer(nextTimer)\n return nextTimer\n }\n timer = armTimer()\n\n const reset = (): void => {\n if (timedOut || controller.signal.aborted) return\n clearTimeout(timer)\n timer = armTimer()\n }\n\n if (request.signal?.aborted === true) {\n clearTimeout(timer)\n abortFromUpstream()\n } else {\n request.signal?.addEventListener('abort', abortFromUpstream, { once: true })\n }\n\n return {\n signal: controller.signal,\n timeoutMs,\n get timedOut() {\n return timedOut\n },\n reset,\n dispose() {\n clearTimeout(timer)\n request.signal?.removeEventListener('abort', abortFromUpstream)\n },\n }\n}\n\nfunction unrefTimer(timer: ReturnType<typeof setTimeout>): void {\n const maybeUnref = (timer as { unref?: () => void }).unref\n if (typeof maybeUnref === 'function') maybeUnref.call(timer)\n}\n\nfunction createRequestTimeoutError(scope: RequestTimeoutScope): DOMException {\n return new DOMException(`HTTP request timed out after ${scope.timeoutMs} ms`, 'TimeoutError')\n}\n\nfunction createTimedHttpResponse(\n response: Response,\n timeoutScope: RequestTimeoutScope,\n): HttpResponse {\n const body = response.body\n if (body === null) timeoutScope.dispose()\n let timedBody: ReadableStream<Uint8Array> | undefined\n\n return {\n status: response.status,\n headers: response.headers,\n get body() {\n if (body === null) return null\n timedBody ??= createTimedResponseBody(body, timeoutScope)\n return timedBody\n },\n json: <T>() =>\n readTimedResponseBody(timeoutScope, response, () => response.json() as Promise<T>),\n text: () => readTimedResponseBody(timeoutScope, response, () => response.text()),\n arrayBuffer: () => readTimedResponseBody(timeoutScope, response, () => response.arrayBuffer()),\n }\n}\n\nasync function readTimedResponseBody<T>(\n timeoutScope: RequestTimeoutScope,\n response: Response,\n read: () => Promise<T>,\n): Promise<T> {\n try {\n return await raceBodyReadWithAbort(timeoutScope, read(), (reason) =>\n cancelResponseBody(response, reason),\n )\n } catch (err) {\n if (timeoutScope.timedOut) {\n throw createRequestTimeoutError(timeoutScope)\n }\n throw err\n } finally {\n timeoutScope.dispose()\n }\n}\n\nfunction createTimedResponseBody(\n body: ReadableStream<Uint8Array>,\n timeoutScope: RequestTimeoutScope,\n): ReadableStream<Uint8Array> {\n let reader: ReadableStreamDefaultReader<Uint8Array> | undefined\n let disposed = false\n const dispose = (): void => {\n if (disposed) return\n disposed = true\n timeoutScope.dispose()\n }\n\n return new ReadableStream<Uint8Array>({\n async pull(controller) {\n reader ??= body.getReader()\n try {\n const result = await raceBodyReadWithAbort(timeoutScope, reader.read(), (reason) =>\n reader?.cancel(reason),\n )\n if (result.done) {\n dispose()\n controller.close()\n return\n }\n timeoutScope.reset()\n controller.enqueue(result.value)\n } catch (err) {\n dispose()\n if (timeoutScope.timedOut) {\n controller.error(createRequestTimeoutError(timeoutScope))\n return\n }\n controller.error(err)\n }\n },\n async cancel(reason) {\n dispose()\n try {\n if (reader !== undefined) {\n await reader.cancel(reason)\n return\n }\n await body.cancel(reason)\n } catch {\n // Best-effort cleanup when the caller cancels the wrapper body.\n }\n },\n })\n}\n\nasync function raceBodyReadWithAbort<T>(\n timeoutScope: RequestTimeoutScope,\n read: Promise<T>,\n abortCleanup?: ((reason: unknown) => Promise<void> | void) | undefined,\n): Promise<T> {\n const signal = timeoutScope.signal\n if (signal === undefined) return read\n if (signal.aborted) {\n void read.catch(() => {})\n const reason = abortReason(signal)\n await runAbortCleanup(abortCleanup, reason)\n throw reason\n }\n\n let removeAbortListener: (() => void) | undefined\n const abort = new Promise<never>((_, reject) => {\n const onAbort = (): void => {\n const reason = abortReason(signal)\n void read.catch(() => {})\n reject(reason)\n void runAbortCleanup(abortCleanup, reason)\n }\n signal.addEventListener('abort', onAbort, { once: true })\n removeAbortListener = () => signal.removeEventListener('abort', onAbort)\n })\n\n try {\n return await Promise.race([read, abort])\n } finally {\n removeAbortListener?.()\n }\n}\n\nasync function runAbortCleanup(\n abortCleanup: ((reason: unknown) => Promise<void> | void) | undefined,\n reason: unknown,\n): Promise<void> {\n try {\n await abortCleanup?.(reason)\n } catch {\n // Abort cleanup is best-effort and must not mask the abort reason.\n }\n}\n\nfunction isBlockedRedirect(response: Response): boolean {\n return response.type === 'opaqueredirect' || REDIRECT_STATUSES.has(response.status)\n}\n\nfunction canFollowSameOriginRedirect(request: HttpRequest, location: string): boolean {\n if (request.method !== 'GET' && request.method !== 'HEAD') return false\n try {\n return new URL(request.url).origin === new URL(location, request.url).origin\n } catch {\n return false\n }\n}\n\nasync function cancelResponseBody(response: Response, reason?: unknown): Promise<void> {\n try {\n await response.body?.cancel(reason)\n } catch {\n // Best-effort cleanup before throwing the primary error.\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 original request's\n * abort signal is forwarded so reauthorization can be cancelled with the\n * operation that triggered it. 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?: (signal?: AbortSignal) => 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 * Decide whether `url` points at a URL-pinned upload POST endpoint.\n *\n * @param url - Request URL to inspect.\n *\n * @returns Whether the request is a direct upload endpoint.\n */\nfunction isUploadEndpoint(url: string): boolean {\n const endpoint = b2ApiEndpointName(url)\n return endpoint === 'b2_upload_file' || endpoint === 'b2_upload_part'\n}\n\nfunction isFinishLargeFileEndpoint(url: string): boolean {\n return b2ApiEndpointName(url) === 'b2_finish_large_file'\n}\n\nfunction isAuthorizeEndpoint(url: string): boolean {\n return b2ApiEndpointName(url) === 'b2_authorize_account'\n}\n\nfunction isStartLargeFileEndpoint(url: string): boolean {\n return b2ApiEndpointName(url) === 'b2_start_large_file'\n}\n\nfunction isPartnerMutationEndpoint(url: string): boolean {\n const endpoint = b2ApiEndpointName(url)\n return (\n endpoint === 'b2_create_group_member' ||\n endpoint === 'b2_eject_group_member' ||\n endpoint === 'b2_reserve_trial_create_account'\n )\n}\n\nfunction isBackupMutationEndpoint(url: string): boolean {\n return backupApiEndpointName(url) === 'bz_delete_computer'\n}\n\nfunction isNonIdempotentMutationRequest(request: HttpRequest): boolean {\n return (\n request.method === 'POST' &&\n (isPartnerMutationEndpoint(request.url) || isBackupMutationEndpoint(request.url))\n )\n}\n\nfunction b2ApiEndpointName(url: string): string | undefined {\n const segments = new URL(url).pathname.split('/').filter((segment) => segment.length > 0)\n // Partner endpoint base URLs can themselves contain a b2api-looking segment\n // before the SDK appends the real API route. Classify the terminal route.\n const apiRootIndex = segments.lastIndexOf('b2api')\n if (apiRootIndex === -1) return undefined\n return segments[apiRootIndex + 2]\n}\n\nfunction backupApiEndpointName(url: string): string | undefined {\n const segments = new URL(url).pathname.split('/').filter((segment) => segment.length > 0)\n const apiRootIndex = segments.lastIndexOf('api')\n if (apiRootIndex === -1 || segments[apiRootIndex + 1] !== 'backup') return undefined\n if (!/^v\\d+$/.test(segments[apiRootIndex + 2] ?? '')) return undefined\n return segments[apiRootIndex + 3]\n}\n\nfunction isReplayUnsafePostRequest(request: HttpRequest): boolean {\n if (request.method !== 'POST') return false\n return (\n isUploadEndpoint(request.url) ||\n isStartLargeFileEndpoint(request.url) ||\n isFinishLargeFileEndpoint(request.url) ||\n isNonIdempotentMutationRequest(request)\n )\n}\n\n/**\n * Decide whether a classified error should be retried in place for `url`.\n * Transient errors normally retry; upload endpoints bubble to the upload layer\n * for fresh-URL retry except account-level 429 throttling, where fetching a new\n * upload URL only amplifies the rate limit.\n *\n * @param error - The classified, retryability-tagged error.\n * @param request - The request being considered for in-place retry.\n *\n * @returns Whether to retry the request in place.\n */\nfunction shouldRetryInPlace(error: B2Error, request: HttpRequest): boolean {\n if (!error.retryable) return false\n if (isAuthorizeEndpoint(request.url) && error instanceof ExpiredAuthTokenError) return false\n if (isNonIdempotentMutationRequest(request)) return false\n if (isStartLargeFileEndpoint(request.url) || isFinishLargeFileEndpoint(request.url)) return false\n if (isUploadEndpoint(request.url) && error.status === 429) return true\n if (isUploadEndpoint(request.url)) return false\n return true\n}\n\nfunction isRequestTimeoutError(err: unknown): boolean {\n return err instanceof DOMException && err.name === 'TimeoutError'\n}\n\nfunction isTerminalTransportError(err: unknown): boolean {\n return (\n err instanceof B2Error ||\n err instanceof B2RedirectError ||\n err instanceof NetworkError ||\n err instanceof B2SsrfError ||\n (err instanceof DOMException && err.name === 'AbortError')\n )\n}\n\n/**\n * Transport wrapper that adds automatic retry with exponential backoff.\n * Handles transient errors (408, 429, and the transient 5xx set 500/502/503/504),\n * expired auth tokens, and network failures. Delegates to an inner\n * {@link HttpTransport}.\n *\n * Upload endpoints (`b2_upload_file` / `b2_upload_part`) are URL-pinned. Their\n * retryable pod failures bubble to the upload layer, which evicts the failed\n * URL, fetches a fresh one, and retries there. HTTP 429 remains an in-place\n * retry so account-level throttling does not trigger extra upload URL fetches.\n */\nexport class RetryTransport implements HttpTransport {\n /** URL guard from the wrapped transport, when the transport exposes one. */\n readonly urlGuard: UrlGuard | undefined\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?: (signal?: AbortSignal) => 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.urlGuard = getTransportUrlGuard(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 const retryOptions = { ...this.options, ...originalRequest.retry }\n let lastError: B2Error | NetworkError | undefined\n let didReauth = false\n let attempt = 0\n\n while (attempt <= retryOptions.maxRetries) {\n throwIfSignalAborted(request.signal)\n\n if (attempt > 0 && lastError) {\n const retryAfter = lastError instanceof NetworkError ? undefined : lastError.retryAfter\n const delay = computeBackoff(attempt - 1, retryOptions, retryAfter)\n await this.sleepImpl(delay, request.signal)\n }\n\n try {\n const response = await this.inner.send({ ...request, retry: retryOptions })\n await throwIfSignalAbortedAfterResponse(request.signal, response)\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 (err) {\n if (isRequestTimeoutError(err)) throw err\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 (\n error instanceof ExpiredAuthTokenError &&\n this.onReauth &&\n !isAuthorizeEndpoint(request.url) &&\n !isUploadEndpoint(request.url) &&\n !isNonIdempotentMutationRequest(request) &&\n !didReauth\n ) {\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 raceWithAbort(this.onReauth(request.signal), request.signal)\n throwIfSignalAborted(request.signal)\n request = {\n ...request,\n headers: { ...(request.headers ?? {}), Authorization: freshToken },\n }\n didReauth = true\n lastError = undefined\n continue\n }\n\n if (!shouldRetryInPlace(error, request) || attempt === retryOptions.maxRetries) {\n throw error\n }\n\n lastError = error\n attempt += 1\n } catch (err) {\n throwIfSignalAborted(request.signal)\n if (isTerminalTransportError(err)) {\n throw err\n }\n\n const networkErr = new NetworkError(\n err instanceof Error ? err.message : 'Network error',\n err,\n )\n\n if (isReplayUnsafePostRequest(request) || attempt === retryOptions.maxRetries) {\n throw networkErr\n }\n\n lastError = networkErr\n attempt += 1\n }\n }\n\n throw lastError ?? new NetworkError('Max retries exceeded')\n }\n}\n\nasync function throwIfSignalAbortedAfterResponse(\n signal: AbortSignal | undefined,\n response: HttpResponse,\n): Promise<void> {\n if (signal?.aborted !== true) return\n const reason = abortReason(signal)\n try {\n await response.body?.cancel(reason)\n } catch {\n // Best-effort cleanup before preserving the caller's abort reason.\n }\n throw reason\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"transport.cjs","names":[],"sources":["../../src/http/transport.ts"],"sourcesContent":["import {\n B2Error,\n B2RedirectError,\n B2SsrfError,\n classifyError,\n ExpiredAuthTokenError,\n NetworkError,\n} from '../errors/index.ts'\nimport type { B2ErrorResponse } from '../types/errors.ts'\nimport { abortReason, raceWithAbort, throwIfSignalAborted } from '../util/abort.ts'\nimport {\n isBackupNonIdempotentMutationEndpoint,\n isPartnerNonIdempotentMutationEndpoint,\n} from './non-idempotent-mutations.ts'\nimport { computeBackoff, DEFAULT_RETRY_OPTIONS, type RetryOptions, sleep } from './retry.ts'\nimport { UrlGuard } from './url-guard.ts'\nimport { getUserAgent } from './user-agent.ts'\n\nconst REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308])\nconst MAX_SAME_ORIGIN_REDIRECTS = 5\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 /** Optional per-request retry override. */\n readonly retry?: Partial<RetryOptions>\n /**\n * Set false to disable automatic retry and expired-token reauth replay.\n * This is not a general idempotency override.\n */\n readonly idempotent?: false\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 * Transport capability for implementations that expose the SSRF URL guard\n * protecting credential-bearing requests. Wrappers that preserve this\n * capability should forward the same `urlGuard` property.\n */\nexport interface UrlGuardedTransport extends HttpTransport {\n /** SSRF allow-list applied to outgoing URLs. */\n readonly urlGuard: UrlGuard\n}\n\n/**\n * Returns the URL guard exposed by `transport`, if it implements\n * {@link UrlGuardedTransport}.\n *\n * @param transport - Transport to inspect.\n *\n * @returns The exposed URL guard, or undefined for unguarded transports.\n */\nexport function getTransportUrlGuard(transport: HttpTransport): UrlGuard | undefined {\n const candidate = transport as Partial<UrlGuardedTransport>\n return candidate.urlGuard instanceof UrlGuard ? candidate.urlGuard : undefined\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 * Redirect following is disabled so redirected URLs cannot bypass the guard or\n * receive credential-bearing headers without an explicit checked request.\n */\nexport class FetchTransport implements UrlGuardedTransport {\n /** User-Agent string sent with every request. */\n private readonly userAgent: string\n /** Whether same-origin GET/HEAD redirects should be followed after guard checks. */\n private readonly followSameOriginRedirects: boolean\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?: {\n userAgent?: string\n urlGuard?: UrlGuard\n /**\n * Follow same-origin GET/HEAD redirects after checking the target with the\n * URL guard. POST redirects are still blocked to avoid replaying\n * credential-bearing payloads to an unexpected endpoint. Defaults to true.\n */\n followSameOriginRedirects?: boolean\n }) {\n this.userAgent = getUserAgent(options?.userAgent)\n this.followSameOriginRedirects = options?.followSameOriginRedirects ?? true\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 * @throws B2RedirectError when a response attempts to redirect.\n */\n async send(request: HttpRequest): Promise<HttpResponse> {\n let currentRequest = request\n let redirectCount = 0\n\n while (true) {\n this.urlGuard.check(currentRequest.url)\n\n const headers = new Headers(currentRequest.headers)\n if (!headers.has('User-Agent')) {\n headers.set('User-Agent', this.userAgent)\n }\n\n const timeoutScope = createRequestTimeoutScope(currentRequest)\n let response: Response\n try {\n response = await fetch(currentRequest.url, {\n method: currentRequest.method,\n headers,\n body: currentRequest.body ?? null,\n redirect: 'manual',\n ...(timeoutScope.signal !== undefined ? { signal: timeoutScope.signal } : {}),\n })\n } catch (err) {\n timeoutScope.dispose()\n if (timeoutScope.timedOut) {\n throw createRequestTimeoutError(timeoutScope)\n }\n throw err\n }\n\n if (isBlockedRedirect(response)) {\n const location = response.headers.get('Location')\n if (\n this.followSameOriginRedirects &&\n location !== null &&\n redirectCount < MAX_SAME_ORIGIN_REDIRECTS &&\n canFollowSameOriginRedirect(currentRequest, location)\n ) {\n const nextUrl = new URL(location, currentRequest.url).toString()\n await cancelResponseBody(response)\n timeoutScope.dispose()\n this.urlGuard.check(nextUrl)\n currentRequest = { ...currentRequest, url: nextUrl }\n redirectCount += 1\n continue\n }\n\n await cancelResponseBody(response)\n timeoutScope.dispose()\n throw new B2RedirectError(currentRequest.url, response.status, location)\n }\n\n return createTimedHttpResponse(response, timeoutScope)\n }\n }\n}\n\ninterface RequestTimeoutScope {\n readonly signal?: AbortSignal\n readonly timeoutMs: number\n readonly timedOut: boolean\n reset(): void\n dispose(): void\n}\n\nfunction createRequestTimeoutScope(request: HttpRequest): RequestTimeoutScope {\n const timeoutMs = request.retry?.requestTimeoutMs ?? DEFAULT_RETRY_OPTIONS.requestTimeoutMs\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n const scope: RequestTimeoutScope = {\n timeoutMs: 0,\n timedOut: false,\n reset() {},\n dispose() {},\n }\n if (request.signal !== undefined) return { ...scope, signal: request.signal }\n return scope\n }\n\n const controller = new AbortController()\n let timedOut = false\n let timer: ReturnType<typeof setTimeout>\n const abortFromUpstream = (): void => {\n clearTimeout(timer)\n controller.abort(request.signal?.reason ?? new DOMException('Aborted', 'AbortError'))\n }\n const armTimer = (): ReturnType<typeof setTimeout> => {\n const nextTimer = setTimeout(() => {\n timedOut = true\n controller.abort(new DOMException('HTTP request timed out', 'TimeoutError'))\n }, timeoutMs)\n unrefTimer(nextTimer)\n return nextTimer\n }\n timer = armTimer()\n\n const reset = (): void => {\n if (timedOut || controller.signal.aborted) return\n clearTimeout(timer)\n timer = armTimer()\n }\n\n if (request.signal?.aborted === true) {\n clearTimeout(timer)\n abortFromUpstream()\n } else {\n request.signal?.addEventListener('abort', abortFromUpstream, { once: true })\n }\n\n return {\n signal: controller.signal,\n timeoutMs,\n get timedOut() {\n return timedOut\n },\n reset,\n dispose() {\n clearTimeout(timer)\n request.signal?.removeEventListener('abort', abortFromUpstream)\n },\n }\n}\n\nfunction unrefTimer(timer: ReturnType<typeof setTimeout>): void {\n const maybeUnref = (timer as { unref?: () => void }).unref\n if (typeof maybeUnref === 'function') maybeUnref.call(timer)\n}\n\nfunction createRequestTimeoutError(scope: RequestTimeoutScope): DOMException {\n return new DOMException(`HTTP request timed out after ${scope.timeoutMs} ms`, 'TimeoutError')\n}\n\nfunction createTimedHttpResponse(\n response: Response,\n timeoutScope: RequestTimeoutScope,\n): HttpResponse {\n const body = response.body\n if (body === null) timeoutScope.dispose()\n let timedBody: ReadableStream<Uint8Array> | undefined\n\n return {\n status: response.status,\n headers: response.headers,\n get body() {\n if (body === null) return null\n timedBody ??= createTimedResponseBody(body, timeoutScope)\n return timedBody\n },\n json: <T>() =>\n readTimedResponseBody(timeoutScope, response, () => response.json() as Promise<T>),\n text: () => readTimedResponseBody(timeoutScope, response, () => response.text()),\n arrayBuffer: () => readTimedResponseBody(timeoutScope, response, () => response.arrayBuffer()),\n }\n}\n\nasync function readTimedResponseBody<T>(\n timeoutScope: RequestTimeoutScope,\n response: Response,\n read: () => Promise<T>,\n): Promise<T> {\n try {\n return await raceBodyReadWithAbort(timeoutScope, read(), (reason) =>\n cancelResponseBody(response, reason),\n )\n } catch (err) {\n if (timeoutScope.timedOut) {\n throw createRequestTimeoutError(timeoutScope)\n }\n throw err\n } finally {\n timeoutScope.dispose()\n }\n}\n\nfunction createTimedResponseBody(\n body: ReadableStream<Uint8Array>,\n timeoutScope: RequestTimeoutScope,\n): ReadableStream<Uint8Array> {\n let reader: ReadableStreamDefaultReader<Uint8Array> | undefined\n let disposed = false\n const dispose = (): void => {\n if (disposed) return\n disposed = true\n timeoutScope.dispose()\n }\n\n return new ReadableStream<Uint8Array>({\n async pull(controller) {\n reader ??= body.getReader()\n try {\n const result = await raceBodyReadWithAbort(timeoutScope, reader.read(), (reason) =>\n reader?.cancel(reason),\n )\n if (result.done) {\n dispose()\n controller.close()\n return\n }\n timeoutScope.reset()\n controller.enqueue(result.value)\n } catch (err) {\n dispose()\n if (timeoutScope.timedOut) {\n controller.error(createRequestTimeoutError(timeoutScope))\n return\n }\n controller.error(err)\n }\n },\n async cancel(reason) {\n dispose()\n try {\n if (reader !== undefined) {\n await reader.cancel(reason)\n return\n }\n await body.cancel(reason)\n } catch {\n // Best-effort cleanup when the caller cancels the wrapper body.\n }\n },\n })\n}\n\nasync function raceBodyReadWithAbort<T>(\n timeoutScope: RequestTimeoutScope,\n read: Promise<T>,\n abortCleanup?: ((reason: unknown) => Promise<void> | void) | undefined,\n): Promise<T> {\n const signal = timeoutScope.signal\n if (signal === undefined) return read\n if (signal.aborted) {\n void read.catch(() => {})\n const reason = abortReason(signal)\n await runAbortCleanup(abortCleanup, reason)\n throw reason\n }\n\n let removeAbortListener: (() => void) | undefined\n const abort = new Promise<never>((_, reject) => {\n const onAbort = (): void => {\n const reason = abortReason(signal)\n void read.catch(() => {})\n reject(reason)\n void runAbortCleanup(abortCleanup, reason)\n }\n signal.addEventListener('abort', onAbort, { once: true })\n removeAbortListener = () => signal.removeEventListener('abort', onAbort)\n })\n\n try {\n return await Promise.race([read, abort])\n } finally {\n removeAbortListener?.()\n }\n}\n\nasync function runAbortCleanup(\n abortCleanup: ((reason: unknown) => Promise<void> | void) | undefined,\n reason: unknown,\n): Promise<void> {\n try {\n await abortCleanup?.(reason)\n } catch {\n // Abort cleanup is best-effort and must not mask the abort reason.\n }\n}\n\nfunction isBlockedRedirect(response: Response): boolean {\n return response.type === 'opaqueredirect' || REDIRECT_STATUSES.has(response.status)\n}\n\nfunction canFollowSameOriginRedirect(request: HttpRequest, location: string): boolean {\n if (request.method !== 'GET' && request.method !== 'HEAD') return false\n try {\n return new URL(request.url).origin === new URL(location, request.url).origin\n } catch {\n return false\n }\n}\n\nasync function cancelResponseBody(response: Response, reason?: unknown): Promise<void> {\n try {\n await response.body?.cancel(reason)\n } catch {\n // Best-effort cleanup before throwing the primary error.\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 original request's\n * abort signal is forwarded so reauthorization can be cancelled with the\n * operation that triggered it. 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?: (signal?: AbortSignal) => 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 * Decide whether `url` points at a URL-pinned upload POST endpoint.\n *\n * @param url - Request URL to inspect.\n *\n * @returns Whether the request is a direct upload endpoint.\n */\nfunction isUploadEndpoint(url: string): boolean {\n const endpoint = b2ApiEndpointName(url)\n return endpoint === 'b2_upload_file' || endpoint === 'b2_upload_part'\n}\n\nfunction isFinishLargeFileEndpoint(url: string): boolean {\n return b2ApiEndpointName(url) === 'b2_finish_large_file'\n}\n\nfunction isAuthorizeEndpoint(url: string): boolean {\n return b2ApiEndpointName(url) === 'b2_authorize_account'\n}\n\nfunction isStartLargeFileEndpoint(url: string): boolean {\n return b2ApiEndpointName(url) === 'b2_start_large_file'\n}\n\nfunction isKnownPartnerNonIdempotentMutationEndpoint(url: string): boolean {\n return isPartnerNonIdempotentMutationEndpoint(b2ApiEndpointName(url))\n}\n\nfunction isKnownBackupNonIdempotentMutationEndpoint(url: string): boolean {\n return isBackupNonIdempotentMutationEndpoint(backupApiEndpointName(url))\n}\n\nfunction isNonIdempotentMutationRequest(request: HttpRequest): boolean {\n // Defense in depth: known mutations must not replay if a wrapper drops\n // the raw client's explicit `idempotent: false` marker.\n return (\n request.idempotent === false ||\n (request.method === 'POST' &&\n (isKnownPartnerNonIdempotentMutationEndpoint(request.url) ||\n isKnownBackupNonIdempotentMutationEndpoint(request.url)))\n )\n}\n\nfunction b2ApiEndpointName(url: string): string | undefined {\n const segments = new URL(url).pathname.split('/').filter((segment) => segment.length > 0)\n // Partner endpoint base URLs can themselves contain a b2api-looking segment\n // before the SDK appends the real API route. Classify the terminal route.\n const apiRootIndex = segments.lastIndexOf('b2api')\n if (apiRootIndex === -1) return undefined\n return segments[apiRootIndex + 2]\n}\n\nfunction backupApiEndpointName(url: string): string | undefined {\n const segments = new URL(url).pathname.split('/').filter((segment) => segment.length > 0)\n const apiRootIndex = segments.lastIndexOf('api')\n if (apiRootIndex === -1 || segments[apiRootIndex + 1] !== 'backup') return undefined\n if (!/^v\\d+$/.test(segments[apiRootIndex + 2] ?? '')) return undefined\n return segments[apiRootIndex + 3]\n}\n\nfunction isReplayUnsafeRequest(request: HttpRequest): boolean {\n if (request.idempotent === false) return true\n if (request.method !== 'POST') return false\n return (\n isUploadEndpoint(request.url) ||\n isStartLargeFileEndpoint(request.url) ||\n isFinishLargeFileEndpoint(request.url) ||\n isNonIdempotentMutationRequest(request)\n )\n}\n\n/**\n * Decide whether a classified error should be retried in place for `url`.\n * Transient errors normally retry; upload endpoints bubble to the upload layer\n * for fresh-URL retry except account-level 429 throttling, where fetching a new\n * upload URL only amplifies the rate limit.\n *\n * @param error - The classified, retryability-tagged error.\n * @param request - The request being considered for in-place retry.\n *\n * @returns Whether to retry the request in place.\n */\nfunction shouldRetryInPlace(error: B2Error, request: HttpRequest): boolean {\n if (!error.retryable) return false\n if (isAuthorizeEndpoint(request.url) && error instanceof ExpiredAuthTokenError) return false\n if (isNonIdempotentMutationRequest(request)) return false\n if (isStartLargeFileEndpoint(request.url) || isFinishLargeFileEndpoint(request.url)) return false\n if (isUploadEndpoint(request.url) && error.status === 429) return true\n if (isUploadEndpoint(request.url)) return false\n return true\n}\n\nfunction isRequestTimeoutError(err: unknown): boolean {\n return err instanceof DOMException && err.name === 'TimeoutError'\n}\n\nfunction isTerminalTransportError(err: unknown): boolean {\n return (\n err instanceof B2Error ||\n err instanceof B2RedirectError ||\n err instanceof NetworkError ||\n err instanceof B2SsrfError ||\n (err instanceof DOMException && err.name === 'AbortError')\n )\n}\n\n/**\n * Transport wrapper that adds automatic retry with exponential backoff.\n * Handles transient errors (408, 429, and the transient 5xx set 500/502/503/504),\n * expired auth tokens, and network failures. Delegates to an inner\n * {@link HttpTransport}.\n *\n * Upload endpoints (`b2_upload_file` / `b2_upload_part`) are URL-pinned. Their\n * retryable pod failures bubble to the upload layer, which evicts the failed\n * URL, fetches a fresh one, and retries there. HTTP 429 remains an in-place\n * retry so account-level throttling does not trigger extra upload URL fetches.\n */\nexport class RetryTransport implements HttpTransport {\n /** URL guard from the wrapped transport, when the transport exposes one. */\n readonly urlGuard: UrlGuard | undefined\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?: (signal?: AbortSignal) => 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.urlGuard = getTransportUrlGuard(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 const retryOptions = { ...this.options, ...originalRequest.retry }\n let lastError: B2Error | NetworkError | undefined\n let didReauth = false\n let attempt = 0\n\n while (attempt <= retryOptions.maxRetries) {\n throwIfSignalAborted(request.signal)\n\n if (attempt > 0 && lastError) {\n const retryAfter = lastError instanceof NetworkError ? undefined : lastError.retryAfter\n const delay = computeBackoff(attempt - 1, retryOptions, retryAfter)\n await this.sleepImpl(delay, request.signal)\n }\n\n try {\n const response = await this.inner.send({ ...request, retry: retryOptions })\n await throwIfSignalAbortedAfterResponse(request.signal, response)\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 (err) {\n if (isRequestTimeoutError(err)) throw err\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 (\n error instanceof ExpiredAuthTokenError &&\n this.onReauth &&\n !isAuthorizeEndpoint(request.url) &&\n !isUploadEndpoint(request.url) &&\n !isNonIdempotentMutationRequest(request) &&\n !didReauth\n ) {\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 raceWithAbort(this.onReauth(request.signal), request.signal)\n throwIfSignalAborted(request.signal)\n request = {\n ...request,\n headers: { ...(request.headers ?? {}), Authorization: freshToken },\n }\n didReauth = true\n lastError = undefined\n continue\n }\n\n if (!shouldRetryInPlace(error, request) || attempt === retryOptions.maxRetries) {\n throw error\n }\n\n lastError = error\n attempt += 1\n } catch (err) {\n throwIfSignalAborted(request.signal)\n if (isTerminalTransportError(err)) {\n throw err\n }\n\n const networkErr = new NetworkError(\n err instanceof Error ? err.message : 'Network error',\n err,\n )\n\n if (isReplayUnsafeRequest(request) || attempt === retryOptions.maxRetries) {\n throw networkErr\n }\n\n lastError = networkErr\n attempt += 1\n }\n }\n\n throw lastError ?? new NetworkError('Max retries exceeded')\n }\n}\n\nasync function throwIfSignalAbortedAfterResponse(\n signal: AbortSignal | undefined,\n response: HttpResponse,\n): Promise<void> {\n if (signal?.aborted !== true) return\n const reason = abortReason(signal)\n try {\n await response.body?.cancel(reason)\n } catch {\n // Best-effort cleanup before preserving the caller's abort reason.\n }\n throw reason\n}\n"],"mappings":"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"}