@backblaze-labs/b2-sdk 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (701) hide show
  1. package/CHANGELOG.md +110 -5
  2. package/README.md +144 -33
  3. package/dist/_virtual/_b2-sdk-version-json.cjs +4 -0
  4. package/dist/_virtual/_b2-sdk-version-json.js +4 -0
  5. package/dist/auth/account-info.d.cts +32 -0
  6. package/dist/auth/account-info.d.cts.map +1 -1
  7. package/dist/auth/account-info.d.ts +32 -0
  8. package/dist/auth/account-info.d.ts.map +1 -1
  9. package/dist/auth/file.cjs +408 -207
  10. package/dist/auth/file.cjs.map +1 -1
  11. package/dist/auth/file.d.cts +77 -3
  12. package/dist/auth/file.d.cts.map +1 -1
  13. package/dist/auth/file.d.ts +77 -3
  14. package/dist/auth/file.d.ts.map +1 -1
  15. package/dist/auth/file.js +407 -207
  16. package/dist/auth/file.js.map +1 -1
  17. package/dist/auth/in-memory.cjs +212 -183
  18. package/dist/auth/in-memory.cjs.map +1 -1
  19. package/dist/auth/in-memory.d.cts +8 -0
  20. package/dist/auth/in-memory.d.cts.map +1 -1
  21. package/dist/auth/in-memory.d.ts +8 -0
  22. package/dist/auth/in-memory.d.ts.map +1 -1
  23. package/dist/auth/in-memory.js +211 -182
  24. package/dist/auth/in-memory.js.map +1 -1
  25. package/dist/auth/index.cjs +7 -9
  26. package/dist/auth/index.d.cts +3 -2
  27. package/dist/auth/index.d.cts.map +1 -1
  28. package/dist/auth/index.d.ts +3 -2
  29. package/dist/auth/index.d.ts.map +1 -1
  30. package/dist/auth/index.js +2 -8
  31. package/dist/auth/realms.cjs +80 -7
  32. package/dist/auth/realms.cjs.map +1 -1
  33. package/dist/auth/realms.d.cts +27 -4
  34. package/dist/auth/realms.d.cts.map +1 -1
  35. package/dist/auth/realms.d.ts +27 -4
  36. package/dist/auth/realms.d.ts.map +1 -1
  37. package/dist/auth/realms.js +80 -9
  38. package/dist/auth/realms.js.map +1 -1
  39. package/dist/auth/upload-url-pool.cjs +55 -51
  40. package/dist/auth/upload-url-pool.cjs.map +1 -1
  41. package/dist/auth/upload-url-pool.js +55 -51
  42. package/dist/auth/upload-url-pool.js.map +1 -1
  43. package/dist/bucket.cjs +785 -787
  44. package/dist/bucket.cjs.map +1 -1
  45. package/dist/bucket.d.cts +35 -47
  46. package/dist/bucket.d.cts.map +1 -1
  47. package/dist/bucket.d.ts +35 -47
  48. package/dist/bucket.d.ts.map +1 -1
  49. package/dist/bucket.js +780 -782
  50. package/dist/bucket.js.map +1 -1
  51. package/dist/client.cjs +246 -228
  52. package/dist/client.cjs.map +1 -1
  53. package/dist/client.d.cts +25 -17
  54. package/dist/client.d.cts.map +1 -1
  55. package/dist/client.d.ts +25 -17
  56. package/dist/client.d.ts.map +1 -1
  57. package/dist/client.js +243 -225
  58. package/dist/client.js.map +1 -1
  59. package/dist/copy/large.cjs +114 -71
  60. package/dist/copy/large.cjs.map +1 -1
  61. package/dist/copy/large.d.cts +6 -0
  62. package/dist/copy/large.d.cts.map +1 -1
  63. package/dist/copy/large.d.ts +6 -0
  64. package/dist/copy/large.d.ts.map +1 -1
  65. package/dist/copy/large.js +112 -69
  66. package/dist/copy/large.js.map +1 -1
  67. package/dist/download/checksum.cjs +89 -0
  68. package/dist/download/checksum.cjs.map +1 -0
  69. package/dist/download/checksum.d.cts +40 -0
  70. package/dist/download/checksum.d.cts.map +1 -0
  71. package/dist/download/checksum.d.ts +40 -0
  72. package/dist/download/checksum.d.ts.map +1 -0
  73. package/dist/download/checksum.js +87 -0
  74. package/dist/download/checksum.js.map +1 -0
  75. package/dist/download/parallel.cjs +214 -118
  76. package/dist/download/parallel.cjs.map +1 -1
  77. package/dist/download/parallel.d.cts +5 -1
  78. package/dist/download/parallel.d.cts.map +1 -1
  79. package/dist/download/parallel.d.ts +5 -1
  80. package/dist/download/parallel.d.ts.map +1 -1
  81. package/dist/download/parallel.js +212 -116
  82. package/dist/download/parallel.js.map +1 -1
  83. package/dist/download/single.cjs +188 -97
  84. package/dist/download/single.cjs.map +1 -1
  85. package/dist/download/single.d.cts +6 -1
  86. package/dist/download/single.d.cts.map +1 -1
  87. package/dist/download/single.d.ts +6 -1
  88. package/dist/download/single.d.ts.map +1 -1
  89. package/dist/download/single.js +186 -98
  90. package/dist/download/single.js.map +1 -1
  91. package/dist/errors/index.cjs +699 -243
  92. package/dist/errors/index.cjs.map +1 -1
  93. package/dist/errors/index.d.cts +285 -82
  94. package/dist/errors/index.d.cts.map +1 -1
  95. package/dist/errors/index.d.ts +285 -82
  96. package/dist/errors/index.d.ts.map +1 -1
  97. package/dist/errors/index.js +678 -261
  98. package/dist/errors/index.js.map +1 -1
  99. package/dist/http/retry.cjs +45 -28
  100. package/dist/http/retry.cjs.map +1 -1
  101. package/dist/http/retry.d.cts +15 -2
  102. package/dist/http/retry.d.cts.map +1 -1
  103. package/dist/http/retry.d.ts +15 -2
  104. package/dist/http/retry.d.ts.map +1 -1
  105. package/dist/http/retry.js +46 -31
  106. package/dist/http/retry.js.map +1 -1
  107. package/dist/http/transport.cjs +438 -140
  108. package/dist/http/transport.cjs.map +1 -1
  109. package/dist/http/transport.d.cts +21 -2
  110. package/dist/http/transport.d.cts.map +1 -1
  111. package/dist/http/transport.d.ts +21 -2
  112. package/dist/http/transport.d.ts.map +1 -1
  113. package/dist/http/transport.js +437 -140
  114. package/dist/http/transport.js.map +1 -1
  115. package/dist/http/url-guard.cjs +154 -89
  116. package/dist/http/url-guard.cjs.map +1 -1
  117. package/dist/http/url-guard.d.cts +25 -3
  118. package/dist/http/url-guard.d.cts.map +1 -1
  119. package/dist/http/url-guard.d.ts +25 -3
  120. package/dist/http/url-guard.d.ts.map +1 -1
  121. package/dist/http/url-guard.js +152 -90
  122. package/dist/http/url-guard.js.map +1 -1
  123. package/dist/http/user-agent.cjs +84 -44
  124. package/dist/http/user-agent.cjs.map +1 -1
  125. package/dist/http/user-agent.js +84 -46
  126. package/dist/http/user-agent.js.map +1 -1
  127. package/dist/index.cjs +101 -77
  128. package/dist/index.d.cts +27 -21
  129. package/dist/index.d.cts.map +1 -1
  130. package/dist/index.d.ts +27 -21
  131. package/dist/index.d.ts.map +1 -1
  132. package/dist/index.js +15 -71
  133. package/dist/internal/b2-naming.cjs +66 -0
  134. package/dist/internal/b2-naming.cjs.map +1 -0
  135. package/dist/internal/b2-naming.d.cts +43 -0
  136. package/dist/internal/b2-naming.d.cts.map +1 -0
  137. package/dist/internal/b2-naming.d.ts +43 -0
  138. package/dist/internal/b2-naming.d.ts.map +1 -0
  139. package/dist/internal/b2-naming.js +60 -0
  140. package/dist/internal/b2-naming.js.map +1 -0
  141. package/dist/internal/upload-retry-options.cjs +21 -0
  142. package/dist/internal/upload-retry-options.cjs.map +1 -0
  143. package/dist/internal/upload-retry-options.d.cts +12 -0
  144. package/dist/internal/upload-retry-options.d.cts.map +1 -0
  145. package/dist/internal/upload-retry-options.d.ts +12 -0
  146. package/dist/internal/upload-retry-options.d.ts.map +1 -0
  147. package/dist/internal/upload-retry-options.js +21 -0
  148. package/dist/internal/upload-retry-options.js.map +1 -0
  149. package/dist/internal/url-redaction.cjs +31 -0
  150. package/dist/internal/url-redaction.cjs.map +1 -0
  151. package/dist/internal/url-redaction.d.cts +17 -0
  152. package/dist/internal/url-redaction.d.cts.map +1 -0
  153. package/dist/internal/url-redaction.d.ts +17 -0
  154. package/dist/internal/url-redaction.d.ts.map +1 -0
  155. package/dist/internal/url-redaction.js +31 -0
  156. package/dist/internal/url-redaction.js.map +1 -0
  157. package/dist/notifications/index.cjs +4 -6
  158. package/dist/notifications/index.d.cts +1 -1
  159. package/dist/notifications/index.d.cts.map +1 -1
  160. package/dist/notifications/index.d.ts +1 -1
  161. package/dist/notifications/index.d.ts.map +1 -1
  162. package/dist/notifications/index.js +1 -6
  163. package/dist/notifications/webhook.cjs +195 -85
  164. package/dist/notifications/webhook.cjs.map +1 -1
  165. package/dist/notifications/webhook.d.cts.map +1 -1
  166. package/dist/notifications/webhook.d.ts.map +1 -1
  167. package/dist/notifications/webhook.js +195 -87
  168. package/dist/notifications/webhook.js.map +1 -1
  169. package/dist/object.cjs +253 -210
  170. package/dist/object.cjs.map +1 -1
  171. package/dist/object.d.cts +9 -55
  172. package/dist/object.d.cts.map +1 -1
  173. package/dist/object.d.ts +9 -55
  174. package/dist/object.d.ts.map +1 -1
  175. package/dist/object.js +249 -206
  176. package/dist/object.js.map +1 -1
  177. package/dist/raw/encoding.cjs +74 -35
  178. package/dist/raw/encoding.cjs.map +1 -1
  179. package/dist/raw/encoding.js +74 -38
  180. package/dist/raw/encoding.js.map +1 -1
  181. package/dist/raw/index.cjs +678 -587
  182. package/dist/raw/index.cjs.map +1 -1
  183. package/dist/raw/index.d.cts +121 -18
  184. package/dist/raw/index.d.cts.map +1 -1
  185. package/dist/raw/index.d.ts +121 -18
  186. package/dist/raw/index.d.ts.map +1 -1
  187. package/dist/raw/index.js +674 -589
  188. package/dist/raw/index.js.map +1 -1
  189. package/dist/s3/index.cjs +355 -18
  190. package/dist/s3/index.cjs.map +1 -1
  191. package/dist/s3/index.d.cts +233 -5
  192. package/dist/s3/index.d.cts.map +1 -1
  193. package/dist/s3/index.d.ts +233 -5
  194. package/dist/s3/index.d.ts.map +1 -1
  195. package/dist/s3/index.js +351 -22
  196. package/dist/s3/index.js.map +1 -1
  197. package/dist/s3/sigv4.cjs +149 -0
  198. package/dist/s3/sigv4.cjs.map +1 -0
  199. package/dist/s3/sigv4.d.cts +43 -0
  200. package/dist/s3/sigv4.d.cts.map +1 -0
  201. package/dist/s3/sigv4.d.ts +43 -0
  202. package/dist/s3/sigv4.d.ts.map +1 -0
  203. package/dist/s3/sigv4.js +148 -0
  204. package/dist/s3/sigv4.js.map +1 -0
  205. package/dist/s3/validation.cjs +69 -0
  206. package/dist/s3/validation.cjs.map +1 -0
  207. package/dist/s3/validation.d.cts +43 -0
  208. package/dist/s3/validation.d.cts.map +1 -0
  209. package/dist/s3/validation.d.ts +43 -0
  210. package/dist/s3/validation.d.ts.map +1 -0
  211. package/dist/s3/validation.js +66 -0
  212. package/dist/s3/validation.js.map +1 -0
  213. package/dist/simulator/capabilities.cjs +63 -48
  214. package/dist/simulator/capabilities.cjs.map +1 -1
  215. package/dist/simulator/capabilities.js +63 -49
  216. package/dist/simulator/capabilities.js.map +1 -1
  217. package/dist/simulator/index.cjs +2124 -1548
  218. package/dist/simulator/index.cjs.map +1 -1
  219. package/dist/simulator/index.d.cts +79 -11
  220. package/dist/simulator/index.d.cts.map +1 -1
  221. package/dist/simulator/index.d.ts +79 -11
  222. package/dist/simulator/index.d.ts.map +1 -1
  223. package/dist/simulator/index.js +2112 -1546
  224. package/dist/simulator/index.js.map +1 -1
  225. package/dist/simulator/validation.cjs +191 -153
  226. package/dist/simulator/validation.cjs.map +1 -1
  227. package/dist/simulator/validation.d.cts +3 -21
  228. package/dist/simulator/validation.d.cts.map +1 -1
  229. package/dist/simulator/validation.d.ts +3 -21
  230. package/dist/simulator/validation.d.ts.map +1 -1
  231. package/dist/simulator/validation.js +188 -162
  232. package/dist/simulator/validation.js.map +1 -1
  233. package/dist/streams/collect.cjs +74 -24
  234. package/dist/streams/collect.cjs.map +1 -1
  235. package/dist/streams/collect.d.cts +14 -1
  236. package/dist/streams/collect.d.cts.map +1 -1
  237. package/dist/streams/collect.d.ts +14 -1
  238. package/dist/streams/collect.d.ts.map +1 -1
  239. package/dist/streams/collect.js +74 -25
  240. package/dist/streams/collect.js.map +1 -1
  241. package/dist/streams/file-source.cjs +287 -0
  242. package/dist/streams/file-source.cjs.map +1 -0
  243. package/dist/streams/file-source.d.cts +96 -0
  244. package/dist/streams/file-source.d.cts.map +1 -0
  245. package/dist/streams/file-source.d.ts +96 -0
  246. package/dist/streams/file-source.d.ts.map +1 -0
  247. package/dist/streams/file-source.js +286 -0
  248. package/dist/streams/file-source.js.map +1 -0
  249. package/dist/streams/hash.cjs +207 -115
  250. package/dist/streams/hash.cjs.map +1 -1
  251. package/dist/streams/hash.d.cts +5 -4
  252. package/dist/streams/hash.d.cts.map +1 -1
  253. package/dist/streams/hash.d.ts +5 -4
  254. package/dist/streams/hash.d.ts.map +1 -1
  255. package/dist/streams/hash.js +208 -95
  256. package/dist/streams/hash.js.map +1 -1
  257. package/dist/streams/index.cjs +12 -12
  258. package/dist/streams/index.d.cts +3 -3
  259. package/dist/streams/index.d.cts.map +1 -1
  260. package/dist/streams/index.d.ts +3 -3
  261. package/dist/streams/index.d.ts.map +1 -1
  262. package/dist/streams/index.js +2 -10
  263. package/dist/streams/progress.cjs +60 -46
  264. package/dist/streams/progress.cjs.map +1 -1
  265. package/dist/streams/progress.js +60 -46
  266. package/dist/streams/progress.js.map +1 -1
  267. package/dist/streams/source.cjs +316 -146
  268. package/dist/streams/source.cjs.map +1 -1
  269. package/dist/streams/source.d.cts +56 -18
  270. package/dist/streams/source.d.cts.map +1 -1
  271. package/dist/streams/source.d.ts +56 -18
  272. package/dist/streams/source.d.ts.map +1 -1
  273. package/dist/streams/source.js +312 -149
  274. package/dist/streams/source.js.map +1 -1
  275. package/dist/sync/actions/index.cjs +236 -184
  276. package/dist/sync/actions/index.cjs.map +1 -1
  277. package/dist/sync/actions/index.d.cts +29 -21
  278. package/dist/sync/actions/index.d.cts.map +1 -1
  279. package/dist/sync/actions/index.d.ts +29 -21
  280. package/dist/sync/actions/index.d.ts.map +1 -1
  281. package/dist/sync/actions/index.js +236 -190
  282. package/dist/sync/actions/index.js.map +1 -1
  283. package/dist/sync/b2-sha1-reader.cjs +148 -0
  284. package/dist/sync/b2-sha1-reader.cjs.map +1 -0
  285. package/dist/sync/b2-sha1-reader.d.cts +58 -0
  286. package/dist/sync/b2-sha1-reader.d.cts.map +1 -0
  287. package/dist/sync/b2-sha1-reader.d.ts +58 -0
  288. package/dist/sync/b2-sha1-reader.d.ts.map +1 -0
  289. package/dist/sync/b2-sha1-reader.js +145 -0
  290. package/dist/sync/b2-sha1-reader.js.map +1 -0
  291. package/dist/sync/download-staging.cjs +265 -0
  292. package/dist/sync/download-staging.cjs.map +1 -0
  293. package/dist/sync/download-staging.d.cts +54 -0
  294. package/dist/sync/download-staging.d.cts.map +1 -0
  295. package/dist/sync/download-staging.d.ts +54 -0
  296. package/dist/sync/download-staging.d.ts.map +1 -0
  297. package/dist/sync/download-staging.js +259 -0
  298. package/dist/sync/download-staging.js.map +1 -0
  299. package/dist/sync/filesystem-errors.cjs +32 -0
  300. package/dist/sync/filesystem-errors.cjs.map +1 -0
  301. package/dist/sync/filesystem-errors.d.cts +8 -0
  302. package/dist/sync/filesystem-errors.d.cts.map +1 -0
  303. package/dist/sync/filesystem-errors.d.ts +8 -0
  304. package/dist/sync/filesystem-errors.d.ts.map +1 -0
  305. package/dist/sync/filesystem-errors.js +32 -0
  306. package/dist/sync/filesystem-errors.js.map +1 -0
  307. package/dist/sync/filters.cjs +217 -0
  308. package/dist/sync/filters.cjs.map +1 -0
  309. package/dist/sync/filters.d.cts +51 -0
  310. package/dist/sync/filters.d.cts.map +1 -0
  311. package/dist/sync/filters.d.ts +51 -0
  312. package/dist/sync/filters.d.ts.map +1 -0
  313. package/dist/sync/filters.js +213 -0
  314. package/dist/sync/filters.js.map +1 -0
  315. package/dist/sync/index.cjs +39 -22
  316. package/dist/sync/index.d.cts +14 -9
  317. package/dist/sync/index.d.cts.map +1 -1
  318. package/dist/sync/index.d.ts +14 -9
  319. package/dist/sync/index.d.ts.map +1 -1
  320. package/dist/sync/index.js +9 -20
  321. package/dist/sync/local-file-identity.cjs +61 -0
  322. package/dist/sync/local-file-identity.cjs.map +1 -0
  323. package/dist/sync/local-file-identity.d.cts +37 -0
  324. package/dist/sync/local-file-identity.d.cts.map +1 -0
  325. package/dist/sync/local-file-identity.d.ts +37 -0
  326. package/dist/sync/local-file-identity.d.ts.map +1 -0
  327. package/dist/sync/local-file-identity.js +60 -0
  328. package/dist/sync/local-file-identity.js.map +1 -0
  329. package/dist/sync/local-file-io.cjs +364 -0
  330. package/dist/sync/local-file-io.cjs.map +1 -0
  331. package/dist/sync/local-file-io.d.cts +75 -0
  332. package/dist/sync/local-file-io.d.cts.map +1 -0
  333. package/dist/sync/local-file-io.d.ts +75 -0
  334. package/dist/sync/local-file-io.d.ts.map +1 -0
  335. package/dist/sync/local-file-io.js +360 -0
  336. package/dist/sync/local-file-io.js.map +1 -0
  337. package/dist/sync/local-filesystem-root.cjs +27 -0
  338. package/dist/sync/local-filesystem-root.cjs.map +1 -0
  339. package/dist/sync/local-filesystem-root.d.cts +18 -0
  340. package/dist/sync/local-filesystem-root.d.cts.map +1 -0
  341. package/dist/sync/local-filesystem-root.d.ts +18 -0
  342. package/dist/sync/local-filesystem-root.d.ts.map +1 -0
  343. package/dist/sync/local-filesystem-root.js +26 -0
  344. package/dist/sync/local-filesystem-root.js.map +1 -0
  345. package/dist/sync/local-sha1.cjs +119 -0
  346. package/dist/sync/local-sha1.cjs.map +1 -0
  347. package/dist/sync/local-sha1.d.cts +39 -0
  348. package/dist/sync/local-sha1.d.cts.map +1 -0
  349. package/dist/sync/local-sha1.d.ts +39 -0
  350. package/dist/sync/local-sha1.d.ts.map +1 -0
  351. package/dist/sync/local-sha1.js +117 -0
  352. package/dist/sync/local-sha1.js.map +1 -0
  353. package/dist/sync/pairing.cjs +118 -29
  354. package/dist/sync/pairing.cjs.map +1 -1
  355. package/dist/sync/pairing.d.cts +7 -2
  356. package/dist/sync/pairing.d.cts.map +1 -1
  357. package/dist/sync/pairing.d.ts +7 -2
  358. package/dist/sync/pairing.d.ts.map +1 -1
  359. package/dist/sync/pairing.js +120 -31
  360. package/dist/sync/pairing.js.map +1 -1
  361. package/dist/sync/path-order.cjs +30 -0
  362. package/dist/sync/path-order.cjs.map +1 -0
  363. package/dist/sync/path-order.d.cts +28 -0
  364. package/dist/sync/path-order.d.cts.map +1 -0
  365. package/dist/sync/path-order.d.ts +28 -0
  366. package/dist/sync/path-order.d.ts.map +1 -0
  367. package/dist/sync/path-order.js +29 -0
  368. package/dist/sync/path-order.js.map +1 -0
  369. package/dist/sync/path-safety.cjs +111 -0
  370. package/dist/sync/path-safety.cjs.map +1 -0
  371. package/dist/sync/path-safety.d.cts +78 -0
  372. package/dist/sync/path-safety.d.cts.map +1 -0
  373. package/dist/sync/path-safety.d.ts +78 -0
  374. package/dist/sync/path-safety.d.ts.map +1 -0
  375. package/dist/sync/path-safety.js +105 -0
  376. package/dist/sync/path-safety.js.map +1 -0
  377. package/dist/sync/paths.d.cts +19 -0
  378. package/dist/sync/paths.d.cts.map +1 -0
  379. package/dist/sync/paths.d.ts +19 -0
  380. package/dist/sync/paths.d.ts.map +1 -0
  381. package/dist/sync/policies/compare.cjs +389 -11
  382. package/dist/sync/policies/compare.cjs.map +1 -1
  383. package/dist/sync/policies/compare.d.cts +100 -2
  384. package/dist/sync/policies/compare.d.cts.map +1 -1
  385. package/dist/sync/policies/compare.d.ts +100 -2
  386. package/dist/sync/policies/compare.d.ts.map +1 -1
  387. package/dist/sync/policies/compare.js +387 -13
  388. package/dist/sync/policies/compare.js.map +1 -1
  389. package/dist/sync/policies/index.cjs +76 -65
  390. package/dist/sync/policies/index.cjs.map +1 -1
  391. package/dist/sync/policies/index.d.cts +35 -6
  392. package/dist/sync/policies/index.d.cts.map +1 -1
  393. package/dist/sync/policies/index.d.ts +35 -6
  394. package/dist/sync/policies/index.d.ts.map +1 -1
  395. package/dist/sync/policies/index.js +76 -65
  396. package/dist/sync/policies/index.js.map +1 -1
  397. package/dist/sync/prefix.cjs +96 -0
  398. package/dist/sync/prefix.cjs.map +1 -0
  399. package/dist/sync/prefix.d.cts +55 -0
  400. package/dist/sync/prefix.d.cts.map +1 -0
  401. package/dist/sync/prefix.d.ts +55 -0
  402. package/dist/sync/prefix.d.ts.map +1 -0
  403. package/dist/sync/prefix.js +92 -0
  404. package/dist/sync/prefix.js.map +1 -0
  405. package/dist/sync/regexp-safety.cjs +192 -0
  406. package/dist/sync/regexp-safety.cjs.map +1 -0
  407. package/dist/sync/regexp-safety.d.cts +29 -0
  408. package/dist/sync/regexp-safety.d.cts.map +1 -0
  409. package/dist/sync/regexp-safety.d.ts +29 -0
  410. package/dist/sync/regexp-safety.d.ts.map +1 -0
  411. package/dist/sync/regexp-safety.js +190 -0
  412. package/dist/sync/regexp-safety.js.map +1 -0
  413. package/dist/sync/scan-events.cjs +33 -0
  414. package/dist/sync/scan-events.cjs.map +1 -0
  415. package/dist/sync/scan-events.d.cts +17 -0
  416. package/dist/sync/scan-events.d.cts.map +1 -0
  417. package/dist/sync/scan-events.d.ts +17 -0
  418. package/dist/sync/scan-events.d.ts.map +1 -0
  419. package/dist/sync/scan-events.js +32 -0
  420. package/dist/sync/scan-events.js.map +1 -0
  421. package/dist/sync/scan-limit.cjs +33 -0
  422. package/dist/sync/scan-limit.cjs.map +1 -0
  423. package/dist/sync/scan-limit.d.cts +21 -0
  424. package/dist/sync/scan-limit.d.cts.map +1 -0
  425. package/dist/sync/scan-limit.d.ts +21 -0
  426. package/dist/sync/scan-limit.d.ts.map +1 -0
  427. package/dist/sync/scan-limit.js +31 -0
  428. package/dist/sync/scan-limit.js.map +1 -0
  429. package/dist/sync/scanners/b2.cjs +239 -55
  430. package/dist/sync/scanners/b2.cjs.map +1 -1
  431. package/dist/sync/scanners/b2.d.cts +26 -7
  432. package/dist/sync/scanners/b2.d.cts.map +1 -1
  433. package/dist/sync/scanners/b2.d.ts +26 -7
  434. package/dist/sync/scanners/b2.d.ts.map +1 -1
  435. package/dist/sync/scanners/b2.js +239 -55
  436. package/dist/sync/scanners/b2.js.map +1 -1
  437. package/dist/sync/scanners/local.cjs +215 -56
  438. package/dist/sync/scanners/local.cjs.map +1 -1
  439. package/dist/sync/scanners/local.d.cts +22 -7
  440. package/dist/sync/scanners/local.d.cts.map +1 -1
  441. package/dist/sync/scanners/local.d.ts +22 -7
  442. package/dist/sync/scanners/local.d.ts.map +1 -1
  443. package/dist/sync/scanners/local.js +216 -57
  444. package/dist/sync/scanners/local.js.map +1 -1
  445. package/dist/sync/sha1-metadata.cjs +94 -0
  446. package/dist/sync/sha1-metadata.cjs.map +1 -0
  447. package/dist/sync/sha1-metadata.d.cts +82 -0
  448. package/dist/sync/sha1-metadata.d.cts.map +1 -0
  449. package/dist/sync/sha1-metadata.d.ts +82 -0
  450. package/dist/sync/sha1-metadata.d.ts.map +1 -0
  451. package/dist/sync/sha1-metadata.js +89 -0
  452. package/dist/sync/sha1-metadata.js.map +1 -0
  453. package/dist/sync/sha1-options.cjs +23 -0
  454. package/dist/sync/sha1-options.cjs.map +1 -0
  455. package/dist/sync/sha1-options.d.cts +14 -0
  456. package/dist/sync/sha1-options.d.cts.map +1 -0
  457. package/dist/sync/sha1-options.d.ts +14 -0
  458. package/dist/sync/sha1-options.d.ts.map +1 -0
  459. package/dist/sync/sha1-options.js +21 -0
  460. package/dist/sync/sha1-options.js.map +1 -0
  461. package/dist/sync/synchronizer.cjs +782 -197
  462. package/dist/sync/synchronizer.cjs.map +1 -1
  463. package/dist/sync/synchronizer.d.cts +47 -1
  464. package/dist/sync/synchronizer.d.cts.map +1 -1
  465. package/dist/sync/synchronizer.d.ts +47 -1
  466. package/dist/sync/synchronizer.d.ts.map +1 -1
  467. package/dist/sync/synchronizer.js +779 -173
  468. package/dist/sync/synchronizer.js.map +1 -1
  469. package/dist/sync/types.d.cts +208 -16
  470. package/dist/sync/types.d.cts.map +1 -1
  471. package/dist/sync/types.d.ts +208 -16
  472. package/dist/sync/types.d.ts.map +1 -1
  473. package/dist/types/auth.cjs +76 -56
  474. package/dist/types/auth.cjs.map +1 -1
  475. package/dist/types/auth.d.cts +67 -9
  476. package/dist/types/auth.d.cts.map +1 -1
  477. package/dist/types/auth.d.ts +67 -9
  478. package/dist/types/auth.d.ts.map +1 -1
  479. package/dist/types/auth.js +77 -57
  480. package/dist/types/auth.js.map +1 -1
  481. package/dist/types/bucket.cjs +74 -38
  482. package/dist/types/bucket.cjs.map +1 -1
  483. package/dist/types/bucket.js +75 -41
  484. package/dist/types/bucket.js.map +1 -1
  485. package/dist/types/encryption.cjs +364 -327
  486. package/dist/types/encryption.cjs.map +1 -1
  487. package/dist/types/encryption.d.cts +16 -0
  488. package/dist/types/encryption.d.cts.map +1 -1
  489. package/dist/types/encryption.d.ts +16 -0
  490. package/dist/types/encryption.d.ts.map +1 -1
  491. package/dist/types/encryption.js +364 -310
  492. package/dist/types/encryption.js.map +1 -1
  493. package/dist/types/errors.cjs +47 -0
  494. package/dist/types/errors.cjs.map +1 -0
  495. package/dist/types/errors.d.cts +13 -4
  496. package/dist/types/errors.d.cts.map +1 -1
  497. package/dist/types/errors.d.ts +13 -4
  498. package/dist/types/errors.d.ts.map +1 -1
  499. package/dist/types/errors.js +47 -0
  500. package/dist/types/errors.js.map +1 -0
  501. package/dist/types/file.cjs +36 -19
  502. package/dist/types/file.cjs.map +1 -1
  503. package/dist/types/file.d.cts +2 -2
  504. package/dist/types/file.d.cts.map +1 -1
  505. package/dist/types/file.d.ts +2 -2
  506. package/dist/types/file.d.ts.map +1 -1
  507. package/dist/types/file.js +37 -21
  508. package/dist/types/file.js.map +1 -1
  509. package/dist/types/ids.cjs +53 -9
  510. package/dist/types/ids.cjs.map +1 -1
  511. package/dist/types/ids.js +54 -15
  512. package/dist/types/ids.js.map +1 -1
  513. package/dist/types/index.d.cts +12 -11
  514. package/dist/types/index.d.cts.map +1 -1
  515. package/dist/types/index.d.ts +12 -11
  516. package/dist/types/index.d.ts.map +1 -1
  517. package/dist/types/key.d.cts +44 -8
  518. package/dist/types/key.d.cts.map +1 -1
  519. package/dist/types/key.d.ts +44 -8
  520. package/dist/types/key.d.ts.map +1 -1
  521. package/dist/types/lock.cjs +33 -13
  522. package/dist/types/lock.cjs.map +1 -1
  523. package/dist/types/lock.js +34 -15
  524. package/dist/types/lock.js.map +1 -1
  525. package/dist/types/notifications.cjs +44 -22
  526. package/dist/types/notifications.cjs.map +1 -1
  527. package/dist/types/notifications.js +45 -23
  528. package/dist/types/notifications.js.map +1 -1
  529. package/dist/types/upload.d.cts +39 -5
  530. package/dist/types/upload.d.cts.map +1 -1
  531. package/dist/types/upload.d.ts +39 -5
  532. package/dist/types/upload.d.ts.map +1 -1
  533. package/dist/upload/abort-scope.cjs +91 -0
  534. package/dist/upload/abort-scope.cjs.map +1 -0
  535. package/dist/upload/abort-scope.d.cts +48 -0
  536. package/dist/upload/abort-scope.d.cts.map +1 -0
  537. package/dist/upload/abort-scope.d.ts +48 -0
  538. package/dist/upload/abort-scope.d.ts.map +1 -0
  539. package/dist/upload/abort-scope.js +88 -0
  540. package/dist/upload/abort-scope.js.map +1 -0
  541. package/dist/upload/cancel.cjs +183 -8
  542. package/dist/upload/cancel.cjs.map +1 -1
  543. package/dist/upload/cancel.d.cts +110 -2
  544. package/dist/upload/cancel.d.cts.map +1 -1
  545. package/dist/upload/cancel.d.ts +110 -2
  546. package/dist/upload/cancel.d.ts.map +1 -1
  547. package/dist/upload/cancel.js +178 -9
  548. package/dist/upload/cancel.js.map +1 -1
  549. package/dist/upload/concurrency.cjs +79 -52
  550. package/dist/upload/concurrency.cjs.map +1 -1
  551. package/dist/upload/concurrency.js +79 -53
  552. package/dist/upload/concurrency.js.map +1 -1
  553. package/dist/upload/finish.cjs +59 -0
  554. package/dist/upload/finish.cjs.map +1 -0
  555. package/dist/upload/finish.d.cts +26 -0
  556. package/dist/upload/finish.d.cts.map +1 -0
  557. package/dist/upload/finish.d.ts +26 -0
  558. package/dist/upload/finish.d.ts.map +1 -0
  559. package/dist/upload/finish.js +59 -0
  560. package/dist/upload/finish.js.map +1 -0
  561. package/dist/upload/large.cjs +301 -218
  562. package/dist/upload/large.cjs.map +1 -1
  563. package/dist/upload/large.d.cts +76 -9
  564. package/dist/upload/large.d.cts.map +1 -1
  565. package/dist/upload/large.d.ts +76 -9
  566. package/dist/upload/large.d.ts.map +1 -1
  567. package/dist/upload/large.js +301 -218
  568. package/dist/upload/large.js.map +1 -1
  569. package/dist/upload/options.cjs +28 -0
  570. package/dist/upload/options.cjs.map +1 -0
  571. package/dist/upload/options.d.cts +104 -0
  572. package/dist/upload/options.d.cts.map +1 -0
  573. package/dist/upload/options.d.ts +104 -0
  574. package/dist/upload/options.d.ts.map +1 -0
  575. package/dist/upload/options.js +27 -0
  576. package/dist/upload/options.js.map +1 -0
  577. package/dist/upload/resume.cjs +333 -33
  578. package/dist/upload/resume.cjs.map +1 -1
  579. package/dist/upload/resume.d.cts +82 -12
  580. package/dist/upload/resume.d.cts.map +1 -1
  581. package/dist/upload/resume.d.ts +82 -12
  582. package/dist/upload/resume.d.ts.map +1 -1
  583. package/dist/upload/resume.js +330 -33
  584. package/dist/upload/resume.js.map +1 -1
  585. package/dist/upload/retry.cjs +186 -0
  586. package/dist/upload/retry.cjs.map +1 -0
  587. package/dist/upload/retry.d.cts +127 -0
  588. package/dist/upload/retry.d.cts.map +1 -0
  589. package/dist/upload/retry.d.ts +127 -0
  590. package/dist/upload/retry.d.ts.map +1 -0
  591. package/dist/upload/retry.js +182 -0
  592. package/dist/upload/retry.js.map +1 -0
  593. package/dist/upload/single.cjs +68 -44
  594. package/dist/upload/single.cjs.map +1 -1
  595. package/dist/upload/single.d.cts +2 -1
  596. package/dist/upload/single.d.cts.map +1 -1
  597. package/dist/upload/single.d.ts +2 -1
  598. package/dist/upload/single.d.ts.map +1 -1
  599. package/dist/upload/single.js +68 -44
  600. package/dist/upload/single.js.map +1 -1
  601. package/dist/upload/stream.cjs +317 -193
  602. package/dist/upload/stream.cjs.map +1 -1
  603. package/dist/upload/stream.d.cts +3 -1
  604. package/dist/upload/stream.d.cts.map +1 -1
  605. package/dist/upload/stream.d.ts +3 -1
  606. package/dist/upload/stream.d.ts.map +1 -1
  607. package/dist/upload/stream.js +316 -192
  608. package/dist/upload/stream.js.map +1 -1
  609. package/dist/util/best-effort.cjs +42 -8
  610. package/dist/util/best-effort.cjs.map +1 -1
  611. package/dist/util/best-effort.d.cts +2 -1
  612. package/dist/util/best-effort.d.cts.map +1 -1
  613. package/dist/util/best-effort.d.ts +2 -1
  614. package/dist/util/best-effort.d.ts.map +1 -1
  615. package/dist/util/best-effort.js +43 -9
  616. package/dist/util/best-effort.js.map +1 -1
  617. package/dist/util/bytes.cjs +23 -0
  618. package/dist/util/bytes.cjs.map +1 -0
  619. package/dist/util/bytes.d.cts +15 -0
  620. package/dist/util/bytes.d.cts.map +1 -0
  621. package/dist/util/bytes.d.ts +15 -0
  622. package/dist/util/bytes.d.ts.map +1 -0
  623. package/dist/util/bytes.js +23 -0
  624. package/dist/util/bytes.js.map +1 -0
  625. package/dist/util/crypto.cjs +68 -0
  626. package/dist/util/crypto.cjs.map +1 -0
  627. package/dist/util/crypto.d.cts +26 -0
  628. package/dist/util/crypto.d.cts.map +1 -0
  629. package/dist/util/crypto.d.ts +26 -0
  630. package/dist/util/crypto.d.ts.map +1 -0
  631. package/dist/util/crypto.js +66 -0
  632. package/dist/util/crypto.js.map +1 -0
  633. package/dist/util/defaults.cjs +25 -9
  634. package/dist/util/defaults.cjs.map +1 -1
  635. package/dist/util/defaults.js +26 -11
  636. package/dist/util/defaults.js.map +1 -1
  637. package/dist/util/error-reason.cjs +41 -0
  638. package/dist/util/error-reason.cjs.map +1 -0
  639. package/dist/util/error-reason.d.cts +9 -0
  640. package/dist/util/error-reason.d.cts.map +1 -0
  641. package/dist/util/error-reason.d.ts +9 -0
  642. package/dist/util/error-reason.d.ts.map +1 -0
  643. package/dist/util/error-reason.js +41 -0
  644. package/dist/util/error-reason.js.map +1 -0
  645. package/dist/util/http.cjs +23 -0
  646. package/dist/util/http.cjs.map +1 -0
  647. package/dist/util/http.d.cts +13 -0
  648. package/dist/util/http.d.cts.map +1 -0
  649. package/dist/util/http.d.ts +13 -0
  650. package/dist/util/http.d.ts.map +1 -0
  651. package/dist/util/http.js +23 -0
  652. package/dist/util/http.js.map +1 -0
  653. package/dist/util/normalize.cjs +66 -7
  654. package/dist/util/normalize.cjs.map +1 -1
  655. package/dist/util/normalize.js +67 -10
  656. package/dist/util/normalize.js.map +1 -1
  657. package/dist/util/paginator.cjs +63 -14
  658. package/dist/util/paginator.cjs.map +1 -1
  659. package/dist/util/paginator.js +64 -16
  660. package/dist/util/paginator.js.map +1 -1
  661. package/dist/util/plan-ranges.cjs +47 -22
  662. package/dist/util/plan-ranges.cjs.map +1 -1
  663. package/dist/util/plan-ranges.js +48 -24
  664. package/dist/util/plan-ranges.js.map +1 -1
  665. package/dist/util/sha1.cjs +27 -0
  666. package/dist/util/sha1.cjs.map +1 -0
  667. package/dist/util/sha1.d.cts +17 -0
  668. package/dist/util/sha1.d.cts.map +1 -0
  669. package/dist/util/sha1.d.ts +17 -0
  670. package/dist/util/sha1.d.ts.map +1 -0
  671. package/dist/util/sha1.js +26 -0
  672. package/dist/util/sha1.js.map +1 -0
  673. package/dist/util/text-codec.cjs +29 -5
  674. package/dist/util/text-codec.cjs.map +1 -1
  675. package/dist/util/text-codec.js +30 -7
  676. package/dist/util/text-codec.js.map +1 -1
  677. package/dist/util/to-error.cjs +18 -4
  678. package/dist/util/to-error.cjs.map +1 -1
  679. package/dist/util/to-error.js +19 -5
  680. package/dist/util/to-error.js.map +1 -1
  681. package/dist/version.cjs +17 -5
  682. package/dist/version.cjs.map +1 -1
  683. package/dist/version.d.cts +3 -3
  684. package/dist/version.d.ts +3 -3
  685. package/dist/version.js +19 -6
  686. package/dist/version.js.map +1 -1
  687. package/package.json +19 -16
  688. package/dist/auth/index.cjs.map +0 -1
  689. package/dist/auth/index.js.map +0 -1
  690. package/dist/index.cjs.map +0 -1
  691. package/dist/index.js.map +0 -1
  692. package/dist/notifications/index.cjs.map +0 -1
  693. package/dist/notifications/index.js.map +0 -1
  694. package/dist/package.json.cjs +0 -9
  695. package/dist/package.json.cjs.map +0 -1
  696. package/dist/package.json.js +0 -9
  697. package/dist/package.json.js.map +0 -1
  698. package/dist/streams/index.cjs.map +0 -1
  699. package/dist/streams/index.js.map +0 -1
  700. package/dist/sync/index.cjs.map +0 -1
  701. package/dist/sync/index.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","names":[],"sources":["../../src/upload/retry.ts"],"sourcesContent":["import type { AccountInfo, UploadUrlEntry } from '../auth/account-info.ts'\nimport {\n B2Error,\n B2SsrfError,\n BadAuthTokenError,\n BadRequestError,\n BadUploadUrlError,\n NetworkError,\n UploadResponseBodyError,\n} from '../errors/index.ts'\nimport { computeBackoff, DEFAULT_RETRY_OPTIONS, type RetryOptions, sleep } from '../http/retry.ts'\nimport type { RawClient } from '../raw/index.ts'\nimport type { EncryptionSetting } from '../types/encryption.ts'\nimport type { BucketId, LargeFileId } from '../types/ids.ts'\nimport type { UploadPartResponse } from '../types/upload.ts'\n\n/** Event emitted before an upload is retried against a fresh upload URL. */\nexport interface UploadRetryEvent {\n /** File name being uploaded. */\n readonly fileName: string\n /** Multipart part number, or `null` for a single-request file upload. */\n readonly partNumber: number | null\n /** One-based retry attempt that is about to run. */\n readonly attempt: number\n /** Maximum number of retry attempts allowed for this upload operation. */\n readonly maxRetries: number\n /** Backoff delay in milliseconds before the fresh URL is fetched. */\n readonly delayMs: number\n /** Classified error that triggered the fresh-URL retry. */\n readonly error: B2Error | NetworkError\n}\n\n/** Callback invoked before an upload retry fetches a fresh upload URL. */\nexport type UploadRetryListener = (event: UploadRetryEvent) => void\n\n/** Shared public options for upload-layer fresh-URL retries. */\nexport interface UploadRetryOptions {\n /** Retry settings shared with the main transport retry configuration. */\n readonly retry?: Partial<RetryOptions> | undefined\n /** Callback invoked before a fresh-URL upload retry. */\n readonly onUploadRetry?: UploadRetryListener | undefined\n /**\n * Whether ambiguous failures after an upload POST should be retried,\n * including response-body read failures and transport errors where B2 may\n * have stored the payload before the success response was lost.\n * Defaults to false. Set true only when duplicate versions or parts are\n * acceptable.\n */\n readonly retryResponseBodyFailures?: boolean | undefined\n}\n\ninterface UploadLayerRetryOptions extends Omit<UploadRetryOptions, 'retryResponseBodyFailures'> {\n readonly retryResponseBodyFailures: boolean\n /** Abort signal for cancelling upload attempts and retry backoff sleeps. */\n readonly signal?: AbortSignal | undefined\n}\n\ninterface FreshUrlRetryOptions<T> extends UploadLayerRetryOptions {\n readonly fileName: string\n readonly partNumber: number | null\n readonly checkout: () => UploadUrlEntry | null\n readonly fetchFresh: () => Promise<UploadUrlEntry>\n readonly returnEntry: (entry: UploadUrlEntry) => void\n readonly evictEntry: (entry: UploadUrlEntry) => void\n readonly upload: (entry: UploadUrlEntry) => Promise<T>\n}\n\nconst freshUrlRetryOverride: Partial<RetryOptions> = { maxRetries: 0 }\n\n/**\n * Resolves the public default for `retryResponseBodyFailures`. Callers must\n * opt into replaying ambiguous upload POST failures for every upload mode.\n *\n * @param value - Caller-provided override, if any.\n *\n * @returns The boolean value passed to the upload retry helper.\n */\nexport function resolveRetryResponseBodyFailures(value: boolean | undefined): boolean {\n return value ?? false\n}\n\n/**\n * Fetches a small-file upload URL, bypassing the pool.\n *\n * @param raw - Low-level B2 API client.\n * @param accountInfo - Authorized account state.\n * @param bucketId - Bucket to upload into.\n * @param signal - Optional abort signal for the fresh URL request.\n *\n * @returns A fresh upload URL entry.\n */\nexport async function fetchFreshUploadUrl(\n raw: RawClient,\n accountInfo: AccountInfo,\n bucketId: BucketId,\n signal?: AbortSignal,\n): Promise<UploadUrlEntry> {\n const resp = await raw.getUploadUrl(\n accountInfo.getApiUrl(),\n accountInfo.getAuthToken(),\n {\n bucketId,\n },\n {\n ...(signal !== undefined ? { signal } : {}),\n retry: freshUrlRetryOverride,\n },\n )\n return { uploadUrl: resp.uploadUrl, authorizationToken: resp.authorizationToken }\n}\n\n/**\n * Fetches a large-file part upload URL, bypassing the pool.\n *\n * @param raw - Low-level B2 API client.\n * @param accountInfo - Authorized account state.\n * @param fileId - Large file to upload a part into.\n * @param signal - Optional abort signal for the fresh URL request.\n *\n * @returns A fresh part upload URL entry.\n */\nexport async function fetchFreshPartUploadUrl(\n raw: RawClient,\n accountInfo: AccountInfo,\n fileId: LargeFileId,\n signal?: AbortSignal,\n): Promise<UploadUrlEntry> {\n const resp = await raw.getUploadPartUrl(\n accountInfo.getApiUrl(),\n accountInfo.getAuthToken(),\n {\n fileId,\n },\n {\n ...(signal !== undefined ? { signal } : {}),\n retry: freshUrlRetryOverride,\n },\n )\n return { uploadUrl: resp.uploadUrl, authorizationToken: resp.authorizationToken }\n}\n\ninterface UploadPartWithFreshUrlOptions extends UploadLayerRetryOptions {\n /** File name associated with the large-file upload. */\n readonly fileName: string\n /** One-based part number. */\n readonly partNumber: number\n /** Part bytes to upload. */\n readonly data: BodyInit\n /** Number of bytes in the part. */\n readonly contentLength: number\n /** SHA-1 hex digest of the part bytes. */\n readonly contentSha1: string\n /** Server-side encryption settings for this part. */\n readonly serverSideEncryption?: EncryptionSetting | undefined\n}\n\n/**\n * Uploads one multipart part with fresh-URL retry.\n *\n * @param raw - Low-level B2 API client.\n * @param accountInfo - Authorized account state.\n * @param fileId - Large file to upload a part into.\n * @param options - Part upload parameters and retry settings.\n *\n * @returns The uploaded part response.\n */\nexport function uploadPartWithFreshUrl(\n raw: RawClient,\n accountInfo: AccountInfo,\n fileId: LargeFileId,\n options: UploadPartWithFreshUrlOptions,\n): Promise<UploadPartResponse> {\n return withFreshUploadUrlRetry({\n fileName: options.fileName,\n partNumber: options.partNumber,\n retry: options.retry,\n signal: options.signal,\n onUploadRetry: options.onUploadRetry,\n retryResponseBodyFailures: options.retryResponseBodyFailures,\n checkout: () => accountInfo.checkoutPartUploadUrl(fileId),\n fetchFresh: () => fetchFreshPartUploadUrl(raw, accountInfo, fileId, options.signal),\n returnEntry: (entry) => accountInfo.returnPartUploadUrl(fileId, entry),\n evictEntry: (entry) => accountInfo.evictPartUploadUrl(fileId, entry),\n upload: (entry) =>\n raw.uploadPart(\n entry.uploadUrl,\n {\n authorization: entry.authorizationToken,\n partNumber: options.partNumber,\n contentLength: options.contentLength,\n contentSha1: options.contentSha1,\n ...(options.serverSideEncryption !== undefined\n ? { serverSideEncryption: options.serverSideEncryption }\n : {}),\n },\n options.data,\n {\n ...(options.signal !== undefined ? { signal: options.signal } : {}),\n ...(options.retry !== undefined ? { retry: options.retry } : {}),\n },\n ),\n })\n}\n\n/**\n * Runs an upload operation with B2's documented retry flow: evict the failed\n * upload URL, back off, fetch a fresh upload URL, and retry there.\n *\n * For single-request file uploads, sending the POST again after a lost success\n * response can create a duplicate file version. Multipart retries re-send the\n * same part number instead. Response-body retry defaults are caller-specific:\n * single-request uploads keep them off by default, while multipart callers can\n * opt in with `retryResponseBodyFailures: true` when replaying the same part\n * number is acceptable.\n *\n * @param options - URL checkout, upload, eviction, and retry callbacks.\n *\n * @returns The successful upload result.\n */\nexport async function withFreshUploadUrlRetry<T>(options: FreshUrlRetryOptions<T>): Promise<T> {\n const retryOptions = { ...DEFAULT_RETRY_OPTIONS, ...options.retry }\n\n for (let attempt = 0; attempt <= retryOptions.maxRetries; attempt++) {\n let uploadEntry: UploadUrlEntry | undefined\n let uploadStarted = false\n\n try {\n options.signal?.throwIfAborted()\n uploadEntry =\n attempt === 0\n ? (options.checkout() ?? (await options.fetchFresh()))\n : await options.fetchFresh()\n\n uploadStarted = true\n const result = await options.upload(uploadEntry)\n options.returnEntry(uploadEntry)\n return result\n } catch (err) {\n const retryError = normalizeUploadRetryError(err, options)\n if (uploadEntry !== undefined) {\n if (isUploadRateLimitError(retryError)) {\n options.returnEntry(uploadEntry)\n } else {\n options.evictEntry(uploadEntry)\n }\n }\n if (options.signal?.aborted) {\n throw err\n }\n if (isUploadRateLimitError(retryError) && uploadEntry !== undefined) {\n throw retryError\n }\n if (\n !isUploadRetryable(retryError, { ...options, uploadStarted }) ||\n attempt === retryOptions.maxRetries\n ) {\n throw retryError\n }\n\n const retryAttempt = attempt + 1\n const retryAfter = retryError instanceof B2Error ? retryError.retryAfter : undefined\n const delayMs = computeBackoff(attempt, retryOptions, retryAfter)\n notifyUploadRetry(options, {\n fileName: options.fileName,\n partNumber: options.partNumber,\n attempt: retryAttempt,\n maxRetries: retryOptions.maxRetries,\n delayMs,\n error: retryError,\n })\n await sleep(delayMs, options.signal)\n }\n }\n\n // Unreachable at runtime: the loop returns on success or throws from the\n // final failed attempt. This satisfies TypeScript's return-path analysis.\n /* v8 ignore next -- defensive return-path guard. */\n throw new NetworkError('Upload retry budget exhausted')\n}\n\nfunction notifyUploadRetry(options: UploadLayerRetryOptions, event: UploadRetryEvent): void {\n try {\n options.onUploadRetry?.(event)\n } catch {\n // Telemetry observers must not replace the underlying upload failure or\n // prevent a retry that can recover with a fresh upload URL.\n }\n}\n\nfunction isUploadRetryable(\n err: unknown,\n options: UploadLayerRetryOptions & {\n readonly partNumber: number | null\n readonly uploadStarted: boolean\n },\n): err is B2Error | NetworkError {\n if (err instanceof NetworkError) {\n if (err.cause instanceof B2SsrfError) return false\n if (!options.uploadStarted) return true\n return options.retryResponseBodyFailures === true\n }\n if (err instanceof BadAuthTokenError) return true\n if (isUploadUrlInvalidationError(err)) return true\n return err instanceof B2Error && err.retryable\n}\n\nfunction isUploadRateLimitError(err: unknown): err is B2Error {\n return err instanceof B2Error && err.status === 429\n}\n\nfunction normalizeUploadRetryError(err: unknown, options: UploadLayerRetryOptions): unknown {\n if (err instanceof B2Error || err instanceof NetworkError) return err\n if (err instanceof UploadResponseBodyError) {\n if (!options.retryResponseBodyFailures) return err\n return new NetworkError(err.message, err)\n }\n if (err instanceof DOMException && err.name === 'AbortError') return err\n if (err instanceof TypeError || err instanceof SyntaxError || err instanceof DOMException) {\n const message = err instanceof Error ? err.message : 'Upload response read failed'\n return new NetworkError(message, err)\n }\n return err\n}\n\nfunction isUploadUrlInvalidationError(err: unknown): boolean {\n if (err instanceof BadUploadUrlError) return true\n return err instanceof BadRequestError && /upload url/i.test(err.message)\n}\n"],"mappings":";;;AAmEA,IAAM,wBAA+C,EAAE,YAAY,EAAE;;;;;;;;;AAUrE,SAAgB,iCAAiC,OAAqC;CACpF,OAAO,SAAS;AAClB;;;;;;;;;;;AAYA,eAAsB,oBACpB,KACA,aACA,UACA,QACyB;CACzB,MAAM,OAAO,MAAM,IAAI,aACrB,YAAY,UAAU,GACtB,YAAY,aAAa,GACzB,EACE,SACF,GACA;EACE,GAAI,WAAW,KAAA,IAAY,EAAE,OAAO,IAAI,CAAC;EACzC,OAAO;CACT,CACF;CACA,OAAO;EAAE,WAAW,KAAK;EAAW,oBAAoB,KAAK;CAAmB;AAClF;;;;;;;;;;;AAYA,eAAsB,wBACpB,KACA,aACA,QACA,QACyB;CACzB,MAAM,OAAO,MAAM,IAAI,iBACrB,YAAY,UAAU,GACtB,YAAY,aAAa,GACzB,EACE,OACF,GACA;EACE,GAAI,WAAW,KAAA,IAAY,EAAE,OAAO,IAAI,CAAC;EACzC,OAAO;CACT,CACF;CACA,OAAO;EAAE,WAAW,KAAK;EAAW,oBAAoB,KAAK;CAAmB;AAClF;;;;;;;;;;;AA2BA,SAAgB,uBACd,KACA,aACA,QACA,SAC6B;CAC7B,OAAO,wBAAwB;EAC7B,UAAU,QAAQ;EAClB,YAAY,QAAQ;EACpB,OAAO,QAAQ;EACf,QAAQ,QAAQ;EAChB,eAAe,QAAQ;EACvB,2BAA2B,QAAQ;EACnC,gBAAgB,YAAY,sBAAsB,MAAM;EACxD,kBAAkB,wBAAwB,KAAK,aAAa,QAAQ,QAAQ,MAAM;EAClF,cAAc,UAAU,YAAY,oBAAoB,QAAQ,KAAK;EACrE,aAAa,UAAU,YAAY,mBAAmB,QAAQ,KAAK;EACnE,SAAS,UACP,IAAI,WACF,MAAM,WACN;GACE,eAAe,MAAM;GACrB,YAAY,QAAQ;GACpB,eAAe,QAAQ;GACvB,aAAa,QAAQ;GACrB,GAAI,QAAQ,yBAAyB,KAAA,IACjC,EAAE,sBAAsB,QAAQ,qBAAqB,IACrD,CAAC;EACP,GACA,QAAQ,MACR;GACE,GAAI,QAAQ,WAAW,KAAA,IAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;GACjE,GAAI,QAAQ,UAAU,KAAA,IAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;EAChE,CACF;CACJ,CAAC;AACH;;;;;;;;;;;;;;;;AAiBA,eAAsB,wBAA2B,SAA8C;CAC7F,MAAM,eAAe;EAAE,GAAG;EAAuB,GAAG,QAAQ;CAAM;CAElE,KAAK,IAAI,UAAU,GAAG,WAAW,aAAa,YAAY,WAAW;EACnE,IAAI;EACJ,IAAI,gBAAgB;EAEpB,IAAI;GACF,QAAQ,QAAQ,eAAe;GAC/B,cACE,YAAY,IACP,QAAQ,SAAS,KAAM,MAAM,QAAQ,WAAW,IACjD,MAAM,QAAQ,WAAW;GAE/B,gBAAgB;GAChB,MAAM,SAAS,MAAM,QAAQ,OAAO,WAAW;GAC/C,QAAQ,YAAY,WAAW;GAC/B,OAAO;EACT,SAAS,KAAK;GACZ,MAAM,aAAa,0BAA0B,KAAK,OAAO;GACzD,IAAI,gBAAgB,KAAA,GAClB,IAAI,uBAAuB,UAAU,GACnC,QAAQ,YAAY,WAAW;QAE/B,QAAQ,WAAW,WAAW;GAGlC,IAAI,QAAQ,QAAQ,SAClB,MAAM;GAER,IAAI,uBAAuB,UAAU,KAAK,gBAAgB,KAAA,GACxD,MAAM;GAER,IACE,CAAC,kBAAkB,YAAY;IAAE,GAAG;IAAS;GAAc,CAAC,KAC5D,YAAY,aAAa,YAEzB,MAAM;GAGR,MAAM,eAAe,UAAU;GAC/B,MAAM,aAAa,sBAAsB,UAAU,WAAW,aAAa,KAAA;GAC3E,MAAM,UAAU,eAAe,SAAS,cAAc,UAAU;GAChE,kBAAkB,SAAS;IACzB,UAAU,QAAQ;IAClB,YAAY,QAAQ;IACpB,SAAS;IACT,YAAY,aAAa;IACzB;IACA,OAAO;GACT,CAAC;GACD,MAAM,MAAM,SAAS,QAAQ,MAAM;EACrC;CACF;;CAKA,MAAM,IAAI,aAAa,+BAA+B;AACxD;AAEA,SAAS,kBAAkB,SAAkC,OAA+B;CAC1F,IAAI;EACF,QAAQ,gBAAgB,KAAK;CAC/B,QAAQ,CAGR;AACF;AAEA,SAAS,kBACP,KACA,SAI+B;CAC/B,IAAI,eAAe,cAAc;EAC/B,IAAI,IAAI,iBAAiB,aAAa,OAAO;EAC7C,IAAI,CAAC,QAAQ,eAAe,OAAO;EACnC,OAAO,QAAQ,8BAA8B;CAC/C;CACA,IAAI,eAAe,mBAAmB,OAAO;CAC7C,IAAI,6BAA6B,GAAG,GAAG,OAAO;CAC9C,OAAO,eAAe,WAAW,IAAI;AACvC;AAEA,SAAS,uBAAuB,KAA8B;CAC5D,OAAO,eAAe,WAAW,IAAI,WAAW;AAClD;AAEA,SAAS,0BAA0B,KAAc,SAA2C;CAC1F,IAAI,eAAe,WAAW,eAAe,cAAc,OAAO;CAClE,IAAI,eAAe,yBAAyB;EAC1C,IAAI,CAAC,QAAQ,2BAA2B,OAAO;EAC/C,OAAO,IAAI,aAAa,IAAI,SAAS,GAAG;CAC1C;CACA,IAAI,eAAe,gBAAgB,IAAI,SAAS,cAAc,OAAO;CACrE,IAAI,eAAe,aAAa,eAAe,eAAe,eAAe,cAE3E,OAAO,IAAI,aADK,eAAe,QAAQ,IAAI,UAAU,+BACpB,GAAG;CAEtC,OAAO;AACT;AAEA,SAAS,6BAA6B,KAAuB;CAC3D,IAAI,eAAe,mBAAmB,OAAO;CAC7C,OAAO,eAAe,mBAAmB,cAAc,KAAK,IAAI,OAAO;AACzE"}
@@ -1,47 +1,71 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const hash = require("../streams/hash.cjs");
4
- const progress = require("../streams/progress.cjs");
5
- const defaults = require("../util/defaults.cjs");
1
+ require("../util/defaults.cjs");
2
+ const require_progress = require("../streams/progress.cjs");
3
+ const require_hash = require("../streams/hash.cjs");
4
+ const require_source = require("../streams/source.cjs");
5
+ const require_retry = require("./retry.cjs");
6
+ //#region src/upload/single.ts
7
+ /**
8
+ * Uploads a file in a single HTTP request (suitable for files up to ~100 MB).
9
+ *
10
+ * The entire file content is read into memory, SHA-1 hashed, and sent in one
11
+ * `b2_upload_file` call. For files larger than the recommended part size, use
12
+ * {@link uploadLargeFile} which splits the file into parts uploaded in parallel.
13
+ *
14
+ * Upload URLs are pooled via {@link AccountInfo} and recycled on success or
15
+ * evicted on failure.
16
+ *
17
+ * @param raw - Low-level B2 API client.
18
+ * @param accountInfo - Authorized account state (tokens, URLs, upload URL pool).
19
+ * @param options - Upload parameters.
20
+ *
21
+ * @returns The resulting {@link FileVersion} metadata.
22
+ */
6
23
  async function uploadSmallFile(raw, accountInfo, options) {
7
- let uploadEntry = accountInfo.checkoutUploadUrl(options.bucketId);
8
- if (!uploadEntry) {
9
- const resp = await raw.getUploadUrl(accountInfo.getApiUrl(), accountInfo.getAuthToken(), {
10
- bucketId: options.bucketId
11
- });
12
- uploadEntry = { uploadUrl: resp.uploadUrl, authorizationToken: resp.authorizationToken };
13
- }
14
- const data = new Uint8Array(await options.source.toArrayBuffer());
15
- const sha1 = new hash.IncrementalSha1();
16
- await sha1.update(data);
17
- const sha1Hex = await sha1.digest();
18
- const tracker = new progress.ProgressTracker(options.onProgress, data.byteLength, 1);
19
- try {
20
- const result = await raw.uploadFile(
21
- uploadEntry.uploadUrl,
22
- {
23
- authorization: uploadEntry.authorizationToken,
24
- fileName: options.fileName,
25
- contentType: options.contentType ?? defaults.DEFAULT_CONTENT_TYPE,
26
- contentLength: data.byteLength,
27
- contentSha1: sha1Hex,
28
- ...options.fileInfo !== void 0 ? { fileInfo: options.fileInfo } : {},
29
- ...options.serverSideEncryption !== void 0 ? { serverSideEncryption: options.serverSideEncryption } : {},
30
- ...options.fileRetention !== void 0 ? { fileRetention: options.fileRetention } : {},
31
- ...options.legalHold !== void 0 ? { legalHold: options.legalHold } : {},
32
- ...options.lastModifiedMillis !== void 0 ? { lastModifiedMillis: options.lastModifiedMillis } : {}
33
- },
34
- data,
35
- options.signal
36
- );
37
- tracker.addBytes(data.byteLength);
38
- tracker.completePart();
39
- accountInfo.returnUploadUrl(options.bucketId, uploadEntry);
40
- return result;
41
- } catch (err) {
42
- accountInfo.evictUploadUrl(options.bucketId, uploadEntry);
43
- throw err;
44
- }
24
+ const data = await readSmallFileSource(options.source, options.signal);
25
+ if (data.byteLength !== options.source.size) throw new Error(`uploadSmallFile: source byte count does not match advertised size (expected ${options.source.size} bytes, got ${data.byteLength} bytes).`);
26
+ const sha1 = new require_hash.IncrementalSha1();
27
+ await sha1.update(data);
28
+ const sha1Hex = await sha1.digest();
29
+ const tracker = new require_progress.ProgressTracker(options.onProgress, data.byteLength, 1);
30
+ const result = await require_retry.withFreshUploadUrlRetry({
31
+ fileName: options.fileName,
32
+ partNumber: null,
33
+ retry: options.retry,
34
+ signal: options.signal,
35
+ onUploadRetry: options.onUploadRetry,
36
+ retryResponseBodyFailures: require_retry.resolveRetryResponseBodyFailures(options.retryResponseBodyFailures),
37
+ checkout: () => accountInfo.checkoutUploadUrl(options.bucketId),
38
+ fetchFresh: () => require_retry.fetchFreshUploadUrl(raw, accountInfo, options.bucketId, options.signal),
39
+ returnEntry: (entry) => accountInfo.returnUploadUrl(options.bucketId, entry),
40
+ evictEntry: (entry) => accountInfo.evictUploadUrl(options.bucketId, entry),
41
+ upload: (entry) => raw.uploadFile(entry.uploadUrl, {
42
+ authorization: entry.authorizationToken,
43
+ fileName: options.fileName,
44
+ contentType: options.contentType ?? "b2/x-auto",
45
+ contentLength: data.byteLength,
46
+ contentSha1: sha1Hex,
47
+ ...options.fileInfo !== void 0 ? { fileInfo: options.fileInfo } : {},
48
+ ...options.serverSideEncryption !== void 0 ? { serverSideEncryption: options.serverSideEncryption } : {},
49
+ ...options.fileRetention !== void 0 ? { fileRetention: options.fileRetention } : {},
50
+ ...options.legalHold !== void 0 ? { legalHold: options.legalHold } : {},
51
+ ...options.lastModifiedMillis !== void 0 ? { lastModifiedMillis: options.lastModifiedMillis } : {}
52
+ }, data, {
53
+ ...options.signal !== void 0 ? { signal: options.signal } : {},
54
+ ...options.retry !== void 0 ? { retry: options.retry } : {}
55
+ })
56
+ });
57
+ tracker.addBytes(data.byteLength);
58
+ tracker.completePart();
59
+ return result;
45
60
  }
61
+ async function readSmallFileSource(source, signal) {
62
+ signal?.throwIfAborted();
63
+ if (!source.canSlice) return require_source.collectStreamExactly(source.stream(), source.size, signal);
64
+ const data = new Uint8Array(await (signal === void 0 ? source.toArrayBuffer() : source.toArrayBuffer({ signal })));
65
+ signal?.throwIfAborted();
66
+ return data;
67
+ }
68
+ //#endregion
46
69
  exports.uploadSmallFile = uploadSmallFile;
47
- //# sourceMappingURL=single.cjs.map
70
+
71
+ //# sourceMappingURL=single.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"single.cjs","sources":["../../src/upload/single.ts"],"sourcesContent":["import type { AccountInfo } from '../auth/account-info.ts'\nimport type { RawClient } from '../raw/index.ts'\nimport { IncrementalSha1 } from '../streams/hash.ts'\nimport { type ProgressListener, ProgressTracker } from '../streams/progress.ts'\nimport type { ContentSource } from '../streams/source.ts'\nimport type { EncryptionSetting } from '../types/encryption.ts'\nimport type { FileVersion } from '../types/file.ts'\nimport type { BucketId } from '../types/ids.ts'\nimport type { FileRetentionValue, LegalHoldValue } from '../types/lock.ts'\nimport { DEFAULT_CONTENT_TYPE } from '../util/defaults.ts'\n\n/** Options for uploading a small file in a single HTTP request. */\nexport interface UploadFileOptions {\n /** Target bucket for the upload. */\n readonly bucketId: BucketId\n /** Full B2 file name including any path prefix. */\n readonly fileName: string\n /** Content to upload. */\n readonly source: ContentSource\n /** MIME type. Defaults to `b2/x-auto` for server-side detection. */\n readonly contentType?: string\n /** Custom file info key/value pairs stored with the file. */\n readonly fileInfo?: Record<string, string>\n /** Server-side encryption settings. */\n readonly serverSideEncryption?: EncryptionSetting\n /** File retention policy applied at upload time. */\n readonly fileRetention?: FileRetentionValue\n /** Legal hold status applied at upload time. */\n readonly legalHold?: LegalHoldValue\n /** Override the last-modified timestamp (epoch millis). */\n readonly lastModifiedMillis?: number\n /** Callback invoked with upload progress updates. */\n readonly onProgress?: ProgressListener\n /** Signal to abort the upload. */\n readonly signal?: AbortSignal\n}\n\n/**\n * Uploads a file in a single HTTP request (suitable for files up to ~100 MB).\n *\n * The entire file content is read into memory, SHA-1 hashed, and sent in one\n * `b2_upload_file` call. For files larger than the recommended part size, use\n * {@link uploadLargeFile} which splits the file into parts uploaded in parallel.\n *\n * Upload URLs are pooled via {@link AccountInfo} and recycled on success or\n * evicted on failure.\n *\n * @param raw - Low-level B2 API client.\n * @param accountInfo - Authorized account state (tokens, URLs, upload URL pool).\n * @param options - Upload parameters.\n *\n * @returns The resulting {@link FileVersion} metadata.\n */\nexport async function uploadSmallFile(\n raw: RawClient,\n accountInfo: AccountInfo,\n options: UploadFileOptions,\n): Promise<FileVersion> {\n let uploadEntry = accountInfo.checkoutUploadUrl(options.bucketId)\n\n if (!uploadEntry) {\n const resp = await raw.getUploadUrl(accountInfo.getApiUrl(), accountInfo.getAuthToken(), {\n bucketId: options.bucketId,\n })\n uploadEntry = { uploadUrl: resp.uploadUrl, authorizationToken: resp.authorizationToken }\n }\n\n const data = new Uint8Array(await options.source.toArrayBuffer())\n const sha1 = new IncrementalSha1()\n await sha1.update(data)\n const sha1Hex = await sha1.digest()\n\n // Single-request uploads send the whole payload in one shot, so the\n // tracker reports a single \"part\" worth of progress: one byte burst at\n // completion and a parts-completed transition from 0 → 1. The tracker\n // is created (rather than calling the listener directly) so consumers\n // see the same {bytesTransferred, totalBytes, partsCompleted,\n // totalParts, elapsedMs} shape they get from `uploadLargeFile`.\n const tracker = new ProgressTracker(options.onProgress, data.byteLength, 1)\n\n try {\n const result = await raw.uploadFile(\n uploadEntry.uploadUrl,\n {\n authorization: uploadEntry.authorizationToken,\n fileName: options.fileName,\n contentType: options.contentType ?? DEFAULT_CONTENT_TYPE,\n contentLength: data.byteLength,\n contentSha1: sha1Hex,\n ...(options.fileInfo !== undefined ? { fileInfo: options.fileInfo } : {}),\n ...(options.serverSideEncryption !== undefined\n ? { serverSideEncryption: options.serverSideEncryption }\n : {}),\n ...(options.fileRetention !== undefined ? { fileRetention: options.fileRetention } : {}),\n ...(options.legalHold !== undefined ? { legalHold: options.legalHold } : {}),\n ...(options.lastModifiedMillis !== undefined\n ? { lastModifiedMillis: options.lastModifiedMillis }\n : {}),\n },\n data,\n options.signal,\n )\n\n tracker.addBytes(data.byteLength)\n tracker.completePart()\n accountInfo.returnUploadUrl(options.bucketId, uploadEntry)\n return result\n } catch (err) {\n accountInfo.evictUploadUrl(options.bucketId, uploadEntry)\n throw err\n }\n}\n"],"names":["IncrementalSha1","ProgressTracker","DEFAULT_CONTENT_TYPE"],"mappings":";;;;;AAqDA,eAAsB,gBACpB,KACA,aACA,SACsB;AACtB,MAAI,cAAc,YAAY,kBAAkB,QAAQ,QAAQ;AAEhE,MAAI,CAAC,aAAa;AAChB,UAAM,OAAO,MAAM,IAAI,aAAa,YAAY,UAAA,GAAa,YAAY,gBAAgB;AAAA,MACvF,UAAU,QAAQ;AAAA,IAAA,CACnB;AACD,kBAAc,EAAE,WAAW,KAAK,WAAW,oBAAoB,KAAK,mBAAA;AAAA,EACtE;AAEA,QAAM,OAAO,IAAI,WAAW,MAAM,QAAQ,OAAO,eAAe;AAChE,QAAM,OAAO,IAAIA,qBAAA;AACjB,QAAM,KAAK,OAAO,IAAI;AACtB,QAAM,UAAU,MAAM,KAAK,OAAA;AAQ3B,QAAM,UAAU,IAAIC,yBAAgB,QAAQ,YAAY,KAAK,YAAY,CAAC;AAE1E,MAAI;AACF,UAAM,SAAS,MAAM,IAAI;AAAA,MACvB,YAAY;AAAA,MACZ;AAAA,QACE,eAAe,YAAY;AAAA,QAC3B,UAAU,QAAQ;AAAA,QAClB,aAAa,QAAQ,eAAeC,SAAAA;AAAAA,QACpC,eAAe,KAAK;AAAA,QACpB,aAAa;AAAA,QACb,GAAI,QAAQ,aAAa,SAAY,EAAE,UAAU,QAAQ,SAAA,IAAa,CAAA;AAAA,QACtE,GAAI,QAAQ,yBAAyB,SACjC,EAAE,sBAAsB,QAAQ,qBAAA,IAChC,CAAA;AAAA,QACJ,GAAI,QAAQ,kBAAkB,SAAY,EAAE,eAAe,QAAQ,cAAA,IAAkB,CAAA;AAAA,QACrF,GAAI,QAAQ,cAAc,SAAY,EAAE,WAAW,QAAQ,UAAA,IAAc,CAAA;AAAA,QACzE,GAAI,QAAQ,uBAAuB,SAC/B,EAAE,oBAAoB,QAAQ,uBAC9B,CAAA;AAAA,MAAC;AAAA,MAEP;AAAA,MACA,QAAQ;AAAA,IAAA;AAGV,YAAQ,SAAS,KAAK,UAAU;AAChC,YAAQ,aAAA;AACR,gBAAY,gBAAgB,QAAQ,UAAU,WAAW;AACzD,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,gBAAY,eAAe,QAAQ,UAAU,WAAW;AACxD,UAAM;AAAA,EACR;AACF;;"}
1
+ {"version":3,"file":"single.cjs","names":[],"sources":["../../src/upload/single.ts"],"sourcesContent":["import type { AccountInfo } from '../auth/account-info.ts'\nimport type { RawClient } from '../raw/index.ts'\nimport { IncrementalSha1 } from '../streams/hash.ts'\nimport { type ProgressListener, ProgressTracker } from '../streams/progress.ts'\nimport { type ContentSource, collectStreamExactly } from '../streams/source.ts'\nimport type { EncryptionSetting } from '../types/encryption.ts'\nimport type { FileVersion } from '../types/file.ts'\nimport type { BucketId } from '../types/ids.ts'\nimport type { FileRetentionValue, LegalHoldValue } from '../types/lock.ts'\nimport { DEFAULT_CONTENT_TYPE } from '../util/defaults.ts'\nimport {\n fetchFreshUploadUrl,\n resolveRetryResponseBodyFailures,\n type UploadRetryOptions,\n withFreshUploadUrlRetry,\n} from './retry.ts'\n\n/** Options for uploading a small file in a single HTTP request. */\nexport interface UploadFileOptions extends UploadRetryOptions {\n /** Target bucket for the upload. */\n readonly bucketId: BucketId\n /** Full B2 file name including any path prefix. */\n readonly fileName: string\n /** Content to upload. */\n readonly source: ContentSource\n /** MIME type. Defaults to `b2/x-auto` for server-side detection. */\n readonly contentType?: string\n /** Custom file info key/value pairs stored with the file. */\n readonly fileInfo?: Record<string, string>\n /** Server-side encryption settings. */\n readonly serverSideEncryption?: EncryptionSetting\n /** File retention policy applied at upload time. */\n readonly fileRetention?: FileRetentionValue\n /** Legal hold status applied at upload time. */\n readonly legalHold?: LegalHoldValue\n /** Override the last-modified timestamp (epoch millis). */\n readonly lastModifiedMillis?: number\n /** Callback invoked with upload progress updates. */\n readonly onProgress?: ProgressListener\n /** Signal to abort the upload. */\n readonly signal?: AbortSignal\n}\n\n/**\n * Uploads a file in a single HTTP request (suitable for files up to ~100 MB).\n *\n * The entire file content is read into memory, SHA-1 hashed, and sent in one\n * `b2_upload_file` call. For files larger than the recommended part size, use\n * {@link uploadLargeFile} which splits the file into parts uploaded in parallel.\n *\n * Upload URLs are pooled via {@link AccountInfo} and recycled on success or\n * evicted on failure.\n *\n * @param raw - Low-level B2 API client.\n * @param accountInfo - Authorized account state (tokens, URLs, upload URL pool).\n * @param options - Upload parameters.\n *\n * @returns The resulting {@link FileVersion} metadata.\n */\nexport async function uploadSmallFile(\n raw: RawClient,\n accountInfo: AccountInfo,\n options: UploadFileOptions,\n): Promise<FileVersion> {\n const data = await readSmallFileSource(options.source, options.signal)\n if (data.byteLength !== options.source.size) {\n throw new Error(\n `uploadSmallFile: source byte count does not match advertised size ` +\n `(expected ${options.source.size} bytes, got ${data.byteLength} bytes).`,\n )\n }\n const sha1 = new IncrementalSha1()\n await sha1.update(data)\n const sha1Hex = await sha1.digest()\n\n // Single-request uploads send the whole payload in one shot, so the\n // tracker reports a single \"part\" worth of progress: one byte burst at\n // completion and a parts-completed transition from 0 → 1. The tracker\n // is created (rather than calling the listener directly) so consumers\n // see the same {bytesTransferred, totalBytes, partsCompleted,\n // totalParts, elapsedMs} shape they get from `uploadLargeFile`.\n const tracker = new ProgressTracker(options.onProgress, data.byteLength, 1)\n\n const result = await withFreshUploadUrlRetry({\n fileName: options.fileName,\n partNumber: null,\n retry: options.retry,\n signal: options.signal,\n onUploadRetry: options.onUploadRetry,\n retryResponseBodyFailures: resolveRetryResponseBodyFailures(options.retryResponseBodyFailures),\n checkout: () => accountInfo.checkoutUploadUrl(options.bucketId),\n fetchFresh: () => fetchFreshUploadUrl(raw, accountInfo, options.bucketId, options.signal),\n returnEntry: (entry) => accountInfo.returnUploadUrl(options.bucketId, entry),\n evictEntry: (entry) => accountInfo.evictUploadUrl(options.bucketId, entry),\n upload: (entry) =>\n raw.uploadFile(\n entry.uploadUrl,\n {\n authorization: entry.authorizationToken,\n fileName: options.fileName,\n contentType: options.contentType ?? DEFAULT_CONTENT_TYPE,\n contentLength: data.byteLength,\n contentSha1: sha1Hex,\n ...(options.fileInfo !== undefined ? { fileInfo: options.fileInfo } : {}),\n ...(options.serverSideEncryption !== undefined\n ? { serverSideEncryption: options.serverSideEncryption }\n : {}),\n ...(options.fileRetention !== undefined ? { fileRetention: options.fileRetention } : {}),\n ...(options.legalHold !== undefined ? { legalHold: options.legalHold } : {}),\n ...(options.lastModifiedMillis !== undefined\n ? { lastModifiedMillis: options.lastModifiedMillis }\n : {}),\n },\n data,\n {\n ...(options.signal !== undefined ? { signal: options.signal } : {}),\n ...(options.retry !== undefined ? { retry: options.retry } : {}),\n },\n ),\n })\n\n tracker.addBytes(data.byteLength)\n tracker.completePart()\n return result\n}\n\nasync function readSmallFileSource(\n source: ContentSource,\n signal: AbortSignal | undefined,\n): Promise<Uint8Array<ArrayBuffer>> {\n signal?.throwIfAborted()\n if (!source.canSlice) {\n return collectStreamExactly(source.stream(), source.size, signal)\n }\n const data = new Uint8Array(\n await (signal === undefined ? source.toArrayBuffer() : source.toArrayBuffer({ signal })),\n )\n signal?.throwIfAborted()\n return data\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA2DA,eAAsB,gBACpB,KACA,aACA,SACsB;CACtB,MAAM,OAAO,MAAM,oBAAoB,QAAQ,QAAQ,QAAQ,MAAM;CACrE,IAAI,KAAK,eAAe,QAAQ,OAAO,MACrC,MAAM,IAAI,MACR,+EACe,QAAQ,OAAO,KAAK,cAAc,KAAK,WAAW,SACnE;CAEF,MAAM,OAAO,IAAI,aAAA,gBAAgB;CACjC,MAAM,KAAK,OAAO,IAAI;CACtB,MAAM,UAAU,MAAM,KAAK,OAAO;CAQlC,MAAM,UAAU,IAAI,iBAAA,gBAAgB,QAAQ,YAAY,KAAK,YAAY,CAAC;CAE1E,MAAM,SAAS,MAAM,cAAA,wBAAwB;EAC3C,UAAU,QAAQ;EAClB,YAAY;EACZ,OAAO,QAAQ;EACf,QAAQ,QAAQ;EAChB,eAAe,QAAQ;EACvB,2BAA2B,cAAA,iCAAiC,QAAQ,yBAAyB;EAC7F,gBAAgB,YAAY,kBAAkB,QAAQ,QAAQ;EAC9D,kBAAkB,cAAA,oBAAoB,KAAK,aAAa,QAAQ,UAAU,QAAQ,MAAM;EACxF,cAAc,UAAU,YAAY,gBAAgB,QAAQ,UAAU,KAAK;EAC3E,aAAa,UAAU,YAAY,eAAe,QAAQ,UAAU,KAAK;EACzE,SAAS,UACP,IAAI,WACF,MAAM,WACN;GACE,eAAe,MAAM;GACrB,UAAU,QAAQ;GAClB,aAAa,QAAQ,eAAA;GACrB,eAAe,KAAK;GACpB,aAAa;GACb,GAAI,QAAQ,aAAa,KAAA,IAAY,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;GACvE,GAAI,QAAQ,yBAAyB,KAAA,IACjC,EAAE,sBAAsB,QAAQ,qBAAqB,IACrD,CAAC;GACL,GAAI,QAAQ,kBAAkB,KAAA,IAAY,EAAE,eAAe,QAAQ,cAAc,IAAI,CAAC;GACtF,GAAI,QAAQ,cAAc,KAAA,IAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;GAC1E,GAAI,QAAQ,uBAAuB,KAAA,IAC/B,EAAE,oBAAoB,QAAQ,mBAAmB,IACjD,CAAC;EACP,GACA,MACA;GACE,GAAI,QAAQ,WAAW,KAAA,IAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;GACjE,GAAI,QAAQ,UAAU,KAAA,IAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;EAChE,CACF;CACJ,CAAC;CAED,QAAQ,SAAS,KAAK,UAAU;CAChC,QAAQ,aAAa;CACrB,OAAO;AACT;AAEA,eAAe,oBACb,QACA,QACkC;CAClC,QAAQ,eAAe;CACvB,IAAI,CAAC,OAAO,UACV,OAAO,eAAA,qBAAqB,OAAO,OAAO,GAAG,OAAO,MAAM,MAAM;CAElE,MAAM,OAAO,IAAI,WACf,OAAO,WAAW,KAAA,IAAY,OAAO,cAAc,IAAI,OAAO,cAAc,EAAE,OAAO,CAAC,EACxF;CACA,QAAQ,eAAe;CACvB,OAAO;AACT"}
@@ -6,8 +6,9 @@ import { EncryptionSetting } from '../types/encryption.js';
6
6
  import { FileVersion } from '../types/file.js';
7
7
  import { BucketId } from '../types/ids.js';
8
8
  import { FileRetentionValue, LegalHoldValue } from '../types/lock.js';
9
+ import { UploadRetryOptions } from './retry.js';
9
10
  /** Options for uploading a small file in a single HTTP request. */
10
- export interface UploadFileOptions {
11
+ export interface UploadFileOptions extends UploadRetryOptions {
11
12
  /** Target bucket for the upload. */
12
13
  readonly bucketId: BucketId;
13
14
  /** Full B2 file name including any path prefix. */
@@ -1 +1 @@
1
- {"version":3,"file":"single.d.ts","sourceRoot":"","sources":["../../src/upload/single.js"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhD,OAAO,EAAE,KAAK,gBAAgB,EAAmB,MAAM,wBAAwB,CAAA;AAC/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAG1E,mEAAmE;AACnE,MAAM,WAAW,iBAAiB;IAChC,oCAAoC;IACpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,yBAAyB;IACzB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;IAC9B,oEAAoE;IACpE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC1C,uCAAuC;IACvC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,iBAAiB,CAAA;IACjD,oDAAoD;IACpD,QAAQ,CAAC,aAAa,CAAC,EAAE,kBAAkB,CAAA;IAC3C,gDAAgD;IAChD,QAAQ,CAAC,SAAS,CAAC,EAAE,cAAc,CAAA;IACnC,2DAA2D;IAC3D,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IACpC,qDAAqD;IACrD,QAAQ,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAA;IACtC,kCAAkC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAC9B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,SAAS,EACd,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,CAsDtB"}
1
+ {"version":3,"file":"single.d.ts","sourceRoot":"","sources":["../../src/upload/single.js"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhD,OAAO,EAAE,KAAK,gBAAgB,EAAmB,MAAM,wBAAwB,CAAA;AAC/E,OAAO,EAAE,KAAK,aAAa,EAAwB,MAAM,sBAAsB,CAAA;AAC/E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAE1E,OAAO,EAGL,KAAK,kBAAkB,EAExB,MAAM,YAAY,CAAA;AAEnB,mEAAmE;AACnE,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D,oCAAoC;IACpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,yBAAyB;IACzB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;IAC9B,oEAAoE;IACpE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC1C,uCAAuC;IACvC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,iBAAiB,CAAA;IACjD,oDAAoD;IACpD,QAAQ,CAAC,aAAa,CAAC,EAAE,kBAAkB,CAAA;IAC3C,gDAAgD;IAChD,QAAQ,CAAC,SAAS,CAAC,EAAE,cAAc,CAAA;IACnC,2DAA2D;IAC3D,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IACpC,qDAAqD;IACrD,QAAQ,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAA;IACtC,kCAAkC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAC9B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,SAAS,EACd,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,CA6DtB"}
@@ -6,8 +6,9 @@ import { EncryptionSetting } from '../types/encryption.js';
6
6
  import { FileVersion } from '../types/file.js';
7
7
  import { BucketId } from '../types/ids.js';
8
8
  import { FileRetentionValue, LegalHoldValue } from '../types/lock.js';
9
+ import { UploadRetryOptions } from './retry.js';
9
10
  /** Options for uploading a small file in a single HTTP request. */
10
- export interface UploadFileOptions {
11
+ export interface UploadFileOptions extends UploadRetryOptions {
11
12
  /** Target bucket for the upload. */
12
13
  readonly bucketId: BucketId;
13
14
  /** Full B2 file name including any path prefix. */
@@ -1 +1 @@
1
- {"version":3,"file":"single.d.ts","sourceRoot":"","sources":["../../src/upload/single.js"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhD,OAAO,EAAE,KAAK,gBAAgB,EAAmB,MAAM,wBAAwB,CAAA;AAC/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAG1E,mEAAmE;AACnE,MAAM,WAAW,iBAAiB;IAChC,oCAAoC;IACpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,yBAAyB;IACzB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;IAC9B,oEAAoE;IACpE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC1C,uCAAuC;IACvC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,iBAAiB,CAAA;IACjD,oDAAoD;IACpD,QAAQ,CAAC,aAAa,CAAC,EAAE,kBAAkB,CAAA;IAC3C,gDAAgD;IAChD,QAAQ,CAAC,SAAS,CAAC,EAAE,cAAc,CAAA;IACnC,2DAA2D;IAC3D,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IACpC,qDAAqD;IACrD,QAAQ,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAA;IACtC,kCAAkC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAC9B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,SAAS,EACd,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,CAsDtB"}
1
+ {"version":3,"file":"single.d.ts","sourceRoot":"","sources":["../../src/upload/single.js"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhD,OAAO,EAAE,KAAK,gBAAgB,EAAmB,MAAM,wBAAwB,CAAA;AAC/E,OAAO,EAAE,KAAK,aAAa,EAAwB,MAAM,sBAAsB,CAAA;AAC/E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAE1E,OAAO,EAGL,KAAK,kBAAkB,EAExB,MAAM,YAAY,CAAA;AAEnB,mEAAmE;AACnE,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D,oCAAoC;IACpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,yBAAyB;IACzB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;IAC9B,oEAAoE;IACpE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC1C,uCAAuC;IACvC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,iBAAiB,CAAA;IACjD,oDAAoD;IACpD,QAAQ,CAAC,aAAa,CAAC,EAAE,kBAAkB,CAAA;IAC3C,gDAAgD;IAChD,QAAQ,CAAC,SAAS,CAAC,EAAE,cAAc,CAAA;IACnC,2DAA2D;IAC3D,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IACpC,qDAAqD;IACrD,QAAQ,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAA;IACtC,kCAAkC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAC9B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,SAAS,EACd,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,CA6DtB"}
@@ -1,47 +1,71 @@
1
- import { IncrementalSha1 } from "../streams/hash.js";
1
+ import "../util/defaults.js";
2
2
  import { ProgressTracker } from "../streams/progress.js";
3
- import { DEFAULT_CONTENT_TYPE } from "../util/defaults.js";
3
+ import { IncrementalSha1 } from "../streams/hash.js";
4
+ import { collectStreamExactly } from "../streams/source.js";
5
+ import { fetchFreshUploadUrl, resolveRetryResponseBodyFailures, withFreshUploadUrlRetry } from "./retry.js";
6
+ //#region src/upload/single.ts
7
+ /**
8
+ * Uploads a file in a single HTTP request (suitable for files up to ~100 MB).
9
+ *
10
+ * The entire file content is read into memory, SHA-1 hashed, and sent in one
11
+ * `b2_upload_file` call. For files larger than the recommended part size, use
12
+ * {@link uploadLargeFile} which splits the file into parts uploaded in parallel.
13
+ *
14
+ * Upload URLs are pooled via {@link AccountInfo} and recycled on success or
15
+ * evicted on failure.
16
+ *
17
+ * @param raw - Low-level B2 API client.
18
+ * @param accountInfo - Authorized account state (tokens, URLs, upload URL pool).
19
+ * @param options - Upload parameters.
20
+ *
21
+ * @returns The resulting {@link FileVersion} metadata.
22
+ */
4
23
  async function uploadSmallFile(raw, accountInfo, options) {
5
- let uploadEntry = accountInfo.checkoutUploadUrl(options.bucketId);
6
- if (!uploadEntry) {
7
- const resp = await raw.getUploadUrl(accountInfo.getApiUrl(), accountInfo.getAuthToken(), {
8
- bucketId: options.bucketId
9
- });
10
- uploadEntry = { uploadUrl: resp.uploadUrl, authorizationToken: resp.authorizationToken };
11
- }
12
- const data = new Uint8Array(await options.source.toArrayBuffer());
13
- const sha1 = new IncrementalSha1();
14
- await sha1.update(data);
15
- const sha1Hex = await sha1.digest();
16
- const tracker = new ProgressTracker(options.onProgress, data.byteLength, 1);
17
- try {
18
- const result = await raw.uploadFile(
19
- uploadEntry.uploadUrl,
20
- {
21
- authorization: uploadEntry.authorizationToken,
22
- fileName: options.fileName,
23
- contentType: options.contentType ?? DEFAULT_CONTENT_TYPE,
24
- contentLength: data.byteLength,
25
- contentSha1: sha1Hex,
26
- ...options.fileInfo !== void 0 ? { fileInfo: options.fileInfo } : {},
27
- ...options.serverSideEncryption !== void 0 ? { serverSideEncryption: options.serverSideEncryption } : {},
28
- ...options.fileRetention !== void 0 ? { fileRetention: options.fileRetention } : {},
29
- ...options.legalHold !== void 0 ? { legalHold: options.legalHold } : {},
30
- ...options.lastModifiedMillis !== void 0 ? { lastModifiedMillis: options.lastModifiedMillis } : {}
31
- },
32
- data,
33
- options.signal
34
- );
35
- tracker.addBytes(data.byteLength);
36
- tracker.completePart();
37
- accountInfo.returnUploadUrl(options.bucketId, uploadEntry);
38
- return result;
39
- } catch (err) {
40
- accountInfo.evictUploadUrl(options.bucketId, uploadEntry);
41
- throw err;
42
- }
24
+ const data = await readSmallFileSource(options.source, options.signal);
25
+ if (data.byteLength !== options.source.size) throw new Error(`uploadSmallFile: source byte count does not match advertised size (expected ${options.source.size} bytes, got ${data.byteLength} bytes).`);
26
+ const sha1 = new IncrementalSha1();
27
+ await sha1.update(data);
28
+ const sha1Hex = await sha1.digest();
29
+ const tracker = new ProgressTracker(options.onProgress, data.byteLength, 1);
30
+ const result = await withFreshUploadUrlRetry({
31
+ fileName: options.fileName,
32
+ partNumber: null,
33
+ retry: options.retry,
34
+ signal: options.signal,
35
+ onUploadRetry: options.onUploadRetry,
36
+ retryResponseBodyFailures: resolveRetryResponseBodyFailures(options.retryResponseBodyFailures),
37
+ checkout: () => accountInfo.checkoutUploadUrl(options.bucketId),
38
+ fetchFresh: () => fetchFreshUploadUrl(raw, accountInfo, options.bucketId, options.signal),
39
+ returnEntry: (entry) => accountInfo.returnUploadUrl(options.bucketId, entry),
40
+ evictEntry: (entry) => accountInfo.evictUploadUrl(options.bucketId, entry),
41
+ upload: (entry) => raw.uploadFile(entry.uploadUrl, {
42
+ authorization: entry.authorizationToken,
43
+ fileName: options.fileName,
44
+ contentType: options.contentType ?? "b2/x-auto",
45
+ contentLength: data.byteLength,
46
+ contentSha1: sha1Hex,
47
+ ...options.fileInfo !== void 0 ? { fileInfo: options.fileInfo } : {},
48
+ ...options.serverSideEncryption !== void 0 ? { serverSideEncryption: options.serverSideEncryption } : {},
49
+ ...options.fileRetention !== void 0 ? { fileRetention: options.fileRetention } : {},
50
+ ...options.legalHold !== void 0 ? { legalHold: options.legalHold } : {},
51
+ ...options.lastModifiedMillis !== void 0 ? { lastModifiedMillis: options.lastModifiedMillis } : {}
52
+ }, data, {
53
+ ...options.signal !== void 0 ? { signal: options.signal } : {},
54
+ ...options.retry !== void 0 ? { retry: options.retry } : {}
55
+ })
56
+ });
57
+ tracker.addBytes(data.byteLength);
58
+ tracker.completePart();
59
+ return result;
60
+ }
61
+ async function readSmallFileSource(source, signal) {
62
+ signal?.throwIfAborted();
63
+ if (!source.canSlice) return collectStreamExactly(source.stream(), source.size, signal);
64
+ const data = new Uint8Array(await (signal === void 0 ? source.toArrayBuffer() : source.toArrayBuffer({ signal })));
65
+ signal?.throwIfAborted();
66
+ return data;
43
67
  }
44
- export {
45
- uploadSmallFile
46
- };
47
- //# sourceMappingURL=single.js.map
68
+ //#endregion
69
+ export { uploadSmallFile };
70
+
71
+ //# sourceMappingURL=single.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"single.js","sources":["../../src/upload/single.ts"],"sourcesContent":["import type { AccountInfo } from '../auth/account-info.ts'\nimport type { RawClient } from '../raw/index.ts'\nimport { IncrementalSha1 } from '../streams/hash.ts'\nimport { type ProgressListener, ProgressTracker } from '../streams/progress.ts'\nimport type { ContentSource } from '../streams/source.ts'\nimport type { EncryptionSetting } from '../types/encryption.ts'\nimport type { FileVersion } from '../types/file.ts'\nimport type { BucketId } from '../types/ids.ts'\nimport type { FileRetentionValue, LegalHoldValue } from '../types/lock.ts'\nimport { DEFAULT_CONTENT_TYPE } from '../util/defaults.ts'\n\n/** Options for uploading a small file in a single HTTP request. */\nexport interface UploadFileOptions {\n /** Target bucket for the upload. */\n readonly bucketId: BucketId\n /** Full B2 file name including any path prefix. */\n readonly fileName: string\n /** Content to upload. */\n readonly source: ContentSource\n /** MIME type. Defaults to `b2/x-auto` for server-side detection. */\n readonly contentType?: string\n /** Custom file info key/value pairs stored with the file. */\n readonly fileInfo?: Record<string, string>\n /** Server-side encryption settings. */\n readonly serverSideEncryption?: EncryptionSetting\n /** File retention policy applied at upload time. */\n readonly fileRetention?: FileRetentionValue\n /** Legal hold status applied at upload time. */\n readonly legalHold?: LegalHoldValue\n /** Override the last-modified timestamp (epoch millis). */\n readonly lastModifiedMillis?: number\n /** Callback invoked with upload progress updates. */\n readonly onProgress?: ProgressListener\n /** Signal to abort the upload. */\n readonly signal?: AbortSignal\n}\n\n/**\n * Uploads a file in a single HTTP request (suitable for files up to ~100 MB).\n *\n * The entire file content is read into memory, SHA-1 hashed, and sent in one\n * `b2_upload_file` call. For files larger than the recommended part size, use\n * {@link uploadLargeFile} which splits the file into parts uploaded in parallel.\n *\n * Upload URLs are pooled via {@link AccountInfo} and recycled on success or\n * evicted on failure.\n *\n * @param raw - Low-level B2 API client.\n * @param accountInfo - Authorized account state (tokens, URLs, upload URL pool).\n * @param options - Upload parameters.\n *\n * @returns The resulting {@link FileVersion} metadata.\n */\nexport async function uploadSmallFile(\n raw: RawClient,\n accountInfo: AccountInfo,\n options: UploadFileOptions,\n): Promise<FileVersion> {\n let uploadEntry = accountInfo.checkoutUploadUrl(options.bucketId)\n\n if (!uploadEntry) {\n const resp = await raw.getUploadUrl(accountInfo.getApiUrl(), accountInfo.getAuthToken(), {\n bucketId: options.bucketId,\n })\n uploadEntry = { uploadUrl: resp.uploadUrl, authorizationToken: resp.authorizationToken }\n }\n\n const data = new Uint8Array(await options.source.toArrayBuffer())\n const sha1 = new IncrementalSha1()\n await sha1.update(data)\n const sha1Hex = await sha1.digest()\n\n // Single-request uploads send the whole payload in one shot, so the\n // tracker reports a single \"part\" worth of progress: one byte burst at\n // completion and a parts-completed transition from 0 → 1. The tracker\n // is created (rather than calling the listener directly) so consumers\n // see the same {bytesTransferred, totalBytes, partsCompleted,\n // totalParts, elapsedMs} shape they get from `uploadLargeFile`.\n const tracker = new ProgressTracker(options.onProgress, data.byteLength, 1)\n\n try {\n const result = await raw.uploadFile(\n uploadEntry.uploadUrl,\n {\n authorization: uploadEntry.authorizationToken,\n fileName: options.fileName,\n contentType: options.contentType ?? DEFAULT_CONTENT_TYPE,\n contentLength: data.byteLength,\n contentSha1: sha1Hex,\n ...(options.fileInfo !== undefined ? { fileInfo: options.fileInfo } : {}),\n ...(options.serverSideEncryption !== undefined\n ? { serverSideEncryption: options.serverSideEncryption }\n : {}),\n ...(options.fileRetention !== undefined ? { fileRetention: options.fileRetention } : {}),\n ...(options.legalHold !== undefined ? { legalHold: options.legalHold } : {}),\n ...(options.lastModifiedMillis !== undefined\n ? { lastModifiedMillis: options.lastModifiedMillis }\n : {}),\n },\n data,\n options.signal,\n )\n\n tracker.addBytes(data.byteLength)\n tracker.completePart()\n accountInfo.returnUploadUrl(options.bucketId, uploadEntry)\n return result\n } catch (err) {\n accountInfo.evictUploadUrl(options.bucketId, uploadEntry)\n throw err\n }\n}\n"],"names":[],"mappings":";;;AAqDA,eAAsB,gBACpB,KACA,aACA,SACsB;AACtB,MAAI,cAAc,YAAY,kBAAkB,QAAQ,QAAQ;AAEhE,MAAI,CAAC,aAAa;AAChB,UAAM,OAAO,MAAM,IAAI,aAAa,YAAY,UAAA,GAAa,YAAY,gBAAgB;AAAA,MACvF,UAAU,QAAQ;AAAA,IAAA,CACnB;AACD,kBAAc,EAAE,WAAW,KAAK,WAAW,oBAAoB,KAAK,mBAAA;AAAA,EACtE;AAEA,QAAM,OAAO,IAAI,WAAW,MAAM,QAAQ,OAAO,eAAe;AAChE,QAAM,OAAO,IAAI,gBAAA;AACjB,QAAM,KAAK,OAAO,IAAI;AACtB,QAAM,UAAU,MAAM,KAAK,OAAA;AAQ3B,QAAM,UAAU,IAAI,gBAAgB,QAAQ,YAAY,KAAK,YAAY,CAAC;AAE1E,MAAI;AACF,UAAM,SAAS,MAAM,IAAI;AAAA,MACvB,YAAY;AAAA,MACZ;AAAA,QACE,eAAe,YAAY;AAAA,QAC3B,UAAU,QAAQ;AAAA,QAClB,aAAa,QAAQ,eAAe;AAAA,QACpC,eAAe,KAAK;AAAA,QACpB,aAAa;AAAA,QACb,GAAI,QAAQ,aAAa,SAAY,EAAE,UAAU,QAAQ,SAAA,IAAa,CAAA;AAAA,QACtE,GAAI,QAAQ,yBAAyB,SACjC,EAAE,sBAAsB,QAAQ,qBAAA,IAChC,CAAA;AAAA,QACJ,GAAI,QAAQ,kBAAkB,SAAY,EAAE,eAAe,QAAQ,cAAA,IAAkB,CAAA;AAAA,QACrF,GAAI,QAAQ,cAAc,SAAY,EAAE,WAAW,QAAQ,UAAA,IAAc,CAAA;AAAA,QACzE,GAAI,QAAQ,uBAAuB,SAC/B,EAAE,oBAAoB,QAAQ,uBAC9B,CAAA;AAAA,MAAC;AAAA,MAEP;AAAA,MACA,QAAQ;AAAA,IAAA;AAGV,YAAQ,SAAS,KAAK,UAAU;AAChC,YAAQ,aAAA;AACR,gBAAY,gBAAgB,QAAQ,UAAU,WAAW;AACzD,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,gBAAY,eAAe,QAAQ,UAAU,WAAW;AACxD,UAAM;AAAA,EACR;AACF;"}
1
+ {"version":3,"file":"single.js","names":[],"sources":["../../src/upload/single.ts"],"sourcesContent":["import type { AccountInfo } from '../auth/account-info.ts'\nimport type { RawClient } from '../raw/index.ts'\nimport { IncrementalSha1 } from '../streams/hash.ts'\nimport { type ProgressListener, ProgressTracker } from '../streams/progress.ts'\nimport { type ContentSource, collectStreamExactly } from '../streams/source.ts'\nimport type { EncryptionSetting } from '../types/encryption.ts'\nimport type { FileVersion } from '../types/file.ts'\nimport type { BucketId } from '../types/ids.ts'\nimport type { FileRetentionValue, LegalHoldValue } from '../types/lock.ts'\nimport { DEFAULT_CONTENT_TYPE } from '../util/defaults.ts'\nimport {\n fetchFreshUploadUrl,\n resolveRetryResponseBodyFailures,\n type UploadRetryOptions,\n withFreshUploadUrlRetry,\n} from './retry.ts'\n\n/** Options for uploading a small file in a single HTTP request. */\nexport interface UploadFileOptions extends UploadRetryOptions {\n /** Target bucket for the upload. */\n readonly bucketId: BucketId\n /** Full B2 file name including any path prefix. */\n readonly fileName: string\n /** Content to upload. */\n readonly source: ContentSource\n /** MIME type. Defaults to `b2/x-auto` for server-side detection. */\n readonly contentType?: string\n /** Custom file info key/value pairs stored with the file. */\n readonly fileInfo?: Record<string, string>\n /** Server-side encryption settings. */\n readonly serverSideEncryption?: EncryptionSetting\n /** File retention policy applied at upload time. */\n readonly fileRetention?: FileRetentionValue\n /** Legal hold status applied at upload time. */\n readonly legalHold?: LegalHoldValue\n /** Override the last-modified timestamp (epoch millis). */\n readonly lastModifiedMillis?: number\n /** Callback invoked with upload progress updates. */\n readonly onProgress?: ProgressListener\n /** Signal to abort the upload. */\n readonly signal?: AbortSignal\n}\n\n/**\n * Uploads a file in a single HTTP request (suitable for files up to ~100 MB).\n *\n * The entire file content is read into memory, SHA-1 hashed, and sent in one\n * `b2_upload_file` call. For files larger than the recommended part size, use\n * {@link uploadLargeFile} which splits the file into parts uploaded in parallel.\n *\n * Upload URLs are pooled via {@link AccountInfo} and recycled on success or\n * evicted on failure.\n *\n * @param raw - Low-level B2 API client.\n * @param accountInfo - Authorized account state (tokens, URLs, upload URL pool).\n * @param options - Upload parameters.\n *\n * @returns The resulting {@link FileVersion} metadata.\n */\nexport async function uploadSmallFile(\n raw: RawClient,\n accountInfo: AccountInfo,\n options: UploadFileOptions,\n): Promise<FileVersion> {\n const data = await readSmallFileSource(options.source, options.signal)\n if (data.byteLength !== options.source.size) {\n throw new Error(\n `uploadSmallFile: source byte count does not match advertised size ` +\n `(expected ${options.source.size} bytes, got ${data.byteLength} bytes).`,\n )\n }\n const sha1 = new IncrementalSha1()\n await sha1.update(data)\n const sha1Hex = await sha1.digest()\n\n // Single-request uploads send the whole payload in one shot, so the\n // tracker reports a single \"part\" worth of progress: one byte burst at\n // completion and a parts-completed transition from 0 → 1. The tracker\n // is created (rather than calling the listener directly) so consumers\n // see the same {bytesTransferred, totalBytes, partsCompleted,\n // totalParts, elapsedMs} shape they get from `uploadLargeFile`.\n const tracker = new ProgressTracker(options.onProgress, data.byteLength, 1)\n\n const result = await withFreshUploadUrlRetry({\n fileName: options.fileName,\n partNumber: null,\n retry: options.retry,\n signal: options.signal,\n onUploadRetry: options.onUploadRetry,\n retryResponseBodyFailures: resolveRetryResponseBodyFailures(options.retryResponseBodyFailures),\n checkout: () => accountInfo.checkoutUploadUrl(options.bucketId),\n fetchFresh: () => fetchFreshUploadUrl(raw, accountInfo, options.bucketId, options.signal),\n returnEntry: (entry) => accountInfo.returnUploadUrl(options.bucketId, entry),\n evictEntry: (entry) => accountInfo.evictUploadUrl(options.bucketId, entry),\n upload: (entry) =>\n raw.uploadFile(\n entry.uploadUrl,\n {\n authorization: entry.authorizationToken,\n fileName: options.fileName,\n contentType: options.contentType ?? DEFAULT_CONTENT_TYPE,\n contentLength: data.byteLength,\n contentSha1: sha1Hex,\n ...(options.fileInfo !== undefined ? { fileInfo: options.fileInfo } : {}),\n ...(options.serverSideEncryption !== undefined\n ? { serverSideEncryption: options.serverSideEncryption }\n : {}),\n ...(options.fileRetention !== undefined ? { fileRetention: options.fileRetention } : {}),\n ...(options.legalHold !== undefined ? { legalHold: options.legalHold } : {}),\n ...(options.lastModifiedMillis !== undefined\n ? { lastModifiedMillis: options.lastModifiedMillis }\n : {}),\n },\n data,\n {\n ...(options.signal !== undefined ? { signal: options.signal } : {}),\n ...(options.retry !== undefined ? { retry: options.retry } : {}),\n },\n ),\n })\n\n tracker.addBytes(data.byteLength)\n tracker.completePart()\n return result\n}\n\nasync function readSmallFileSource(\n source: ContentSource,\n signal: AbortSignal | undefined,\n): Promise<Uint8Array<ArrayBuffer>> {\n signal?.throwIfAborted()\n if (!source.canSlice) {\n return collectStreamExactly(source.stream(), source.size, signal)\n }\n const data = new Uint8Array(\n await (signal === undefined ? source.toArrayBuffer() : source.toArrayBuffer({ signal })),\n )\n signal?.throwIfAborted()\n return data\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA2DA,eAAsB,gBACpB,KACA,aACA,SACsB;CACtB,MAAM,OAAO,MAAM,oBAAoB,QAAQ,QAAQ,QAAQ,MAAM;CACrE,IAAI,KAAK,eAAe,QAAQ,OAAO,MACrC,MAAM,IAAI,MACR,+EACe,QAAQ,OAAO,KAAK,cAAc,KAAK,WAAW,SACnE;CAEF,MAAM,OAAO,IAAI,gBAAgB;CACjC,MAAM,KAAK,OAAO,IAAI;CACtB,MAAM,UAAU,MAAM,KAAK,OAAO;CAQlC,MAAM,UAAU,IAAI,gBAAgB,QAAQ,YAAY,KAAK,YAAY,CAAC;CAE1E,MAAM,SAAS,MAAM,wBAAwB;EAC3C,UAAU,QAAQ;EAClB,YAAY;EACZ,OAAO,QAAQ;EACf,QAAQ,QAAQ;EAChB,eAAe,QAAQ;EACvB,2BAA2B,iCAAiC,QAAQ,yBAAyB;EAC7F,gBAAgB,YAAY,kBAAkB,QAAQ,QAAQ;EAC9D,kBAAkB,oBAAoB,KAAK,aAAa,QAAQ,UAAU,QAAQ,MAAM;EACxF,cAAc,UAAU,YAAY,gBAAgB,QAAQ,UAAU,KAAK;EAC3E,aAAa,UAAU,YAAY,eAAe,QAAQ,UAAU,KAAK;EACzE,SAAS,UACP,IAAI,WACF,MAAM,WACN;GACE,eAAe,MAAM;GACrB,UAAU,QAAQ;GAClB,aAAa,QAAQ,eAAA;GACrB,eAAe,KAAK;GACpB,aAAa;GACb,GAAI,QAAQ,aAAa,KAAA,IAAY,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;GACvE,GAAI,QAAQ,yBAAyB,KAAA,IACjC,EAAE,sBAAsB,QAAQ,qBAAqB,IACrD,CAAC;GACL,GAAI,QAAQ,kBAAkB,KAAA,IAAY,EAAE,eAAe,QAAQ,cAAc,IAAI,CAAC;GACtF,GAAI,QAAQ,cAAc,KAAA,IAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;GAC1E,GAAI,QAAQ,uBAAuB,KAAA,IAC/B,EAAE,oBAAoB,QAAQ,mBAAmB,IACjD,CAAC;EACP,GACA,MACA;GACE,GAAI,QAAQ,WAAW,KAAA,IAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;GACjE,GAAI,QAAQ,UAAU,KAAA,IAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;EAChE,CACF;CACJ,CAAC;CAED,QAAQ,SAAS,KAAK,UAAU;CAChC,QAAQ,aAAa;CACrB,OAAO;AACT;AAEA,eAAe,oBACb,QACA,QACkC;CAClC,QAAQ,eAAe;CACvB,IAAI,CAAC,OAAO,UACV,OAAO,qBAAqB,OAAO,OAAO,GAAG,OAAO,MAAM,MAAM;CAElE,MAAM,OAAO,IAAI,WACf,OAAO,WAAW,KAAA,IAAY,OAAO,cAAc,IAAI,OAAO,cAAc,EAAE,OAAO,CAAC,EACxF;CACA,QAAQ,eAAe;CACvB,OAAO;AACT"}