@backblaze-labs/b2-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (512) hide show
  1. package/CHANGELOG.md +121 -0
  2. package/LICENSE +21 -0
  3. package/README.md +664 -0
  4. package/dist/auth/account-info.d.cts +51 -0
  5. package/dist/auth/account-info.d.cts.map +1 -0
  6. package/dist/auth/account-info.d.ts +51 -0
  7. package/dist/auth/account-info.d.ts.map +1 -0
  8. package/dist/auth/file.cjs +210 -0
  9. package/dist/auth/file.cjs.map +1 -0
  10. package/dist/auth/file.d.cts +157 -0
  11. package/dist/auth/file.d.cts.map +1 -0
  12. package/dist/auth/file.d.ts +157 -0
  13. package/dist/auth/file.d.ts.map +1 -0
  14. package/dist/auth/file.js +210 -0
  15. package/dist/auth/file.js.map +1 -0
  16. package/dist/auth/in-memory.cjs +184 -0
  17. package/dist/auth/in-memory.cjs.map +1 -0
  18. package/dist/auth/in-memory.d.cts +147 -0
  19. package/dist/auth/in-memory.d.cts.map +1 -0
  20. package/dist/auth/in-memory.d.ts +147 -0
  21. package/dist/auth/in-memory.d.ts.map +1 -0
  22. package/dist/auth/in-memory.js +184 -0
  23. package/dist/auth/in-memory.js.map +1 -0
  24. package/dist/auth/index.cjs +10 -0
  25. package/dist/auth/index.cjs.map +1 -0
  26. package/dist/auth/index.d.cts +6 -0
  27. package/dist/auth/index.d.cts.map +1 -0
  28. package/dist/auth/index.d.ts +6 -0
  29. package/dist/auth/index.d.ts.map +1 -0
  30. package/dist/auth/index.js +10 -0
  31. package/dist/auth/index.js.map +1 -0
  32. package/dist/auth/realms.cjs +12 -0
  33. package/dist/auth/realms.cjs.map +1 -0
  34. package/dist/auth/realms.d.cts +12 -0
  35. package/dist/auth/realms.d.cts.map +1 -0
  36. package/dist/auth/realms.d.ts +12 -0
  37. package/dist/auth/realms.d.ts.map +1 -0
  38. package/dist/auth/realms.js +12 -0
  39. package/dist/auth/realms.js.map +1 -0
  40. package/dist/auth/upload-url-pool.cjs +52 -0
  41. package/dist/auth/upload-url-pool.cjs.map +1 -0
  42. package/dist/auth/upload-url-pool.d.cts +35 -0
  43. package/dist/auth/upload-url-pool.d.cts.map +1 -0
  44. package/dist/auth/upload-url-pool.d.ts +35 -0
  45. package/dist/auth/upload-url-pool.d.ts.map +1 -0
  46. package/dist/auth/upload-url-pool.js +52 -0
  47. package/dist/auth/upload-url-pool.js.map +1 -0
  48. package/dist/bucket.cjs +789 -0
  49. package/dist/bucket.cjs.map +1 -0
  50. package/dist/bucket.d.cts +659 -0
  51. package/dist/bucket.d.cts.map +1 -0
  52. package/dist/bucket.d.ts +659 -0
  53. package/dist/bucket.d.ts.map +1 -0
  54. package/dist/bucket.js +789 -0
  55. package/dist/bucket.js.map +1 -0
  56. package/dist/client.cjs +230 -0
  57. package/dist/client.cjs.map +1 -0
  58. package/dist/client.d.cts +222 -0
  59. package/dist/client.d.cts.map +1 -0
  60. package/dist/client.d.ts +222 -0
  61. package/dist/client.d.ts.map +1 -0
  62. package/dist/client.js +230 -0
  63. package/dist/client.js.map +1 -0
  64. package/dist/copy/large.cjs +74 -0
  65. package/dist/copy/large.cjs.map +1 -0
  66. package/dist/copy/large.d.cts +53 -0
  67. package/dist/copy/large.d.cts.map +1 -0
  68. package/dist/copy/large.d.ts +53 -0
  69. package/dist/copy/large.d.ts.map +1 -0
  70. package/dist/copy/large.js +74 -0
  71. package/dist/copy/large.js.map +1 -0
  72. package/dist/download/parallel.cjs +122 -0
  73. package/dist/download/parallel.cjs.map +1 -0
  74. package/dist/download/parallel.d.cts +42 -0
  75. package/dist/download/parallel.d.cts.map +1 -0
  76. package/dist/download/parallel.d.ts +42 -0
  77. package/dist/download/parallel.d.ts.map +1 -0
  78. package/dist/download/parallel.js +122 -0
  79. package/dist/download/parallel.js.map +1 -0
  80. package/dist/download/single.cjs +117 -0
  81. package/dist/download/single.cjs.map +1 -0
  82. package/dist/download/single.d.cts +152 -0
  83. package/dist/download/single.d.cts.map +1 -0
  84. package/dist/download/single.d.ts +152 -0
  85. package/dist/download/single.d.ts.map +1 -0
  86. package/dist/download/single.js +117 -0
  87. package/dist/download/single.js.map +1 -0
  88. package/dist/errors/index.cjs +268 -0
  89. package/dist/errors/index.cjs.map +1 -0
  90. package/dist/errors/index.d.cts +264 -0
  91. package/dist/errors/index.d.cts.map +1 -0
  92. package/dist/errors/index.d.ts +264 -0
  93. package/dist/errors/index.d.ts.map +1 -0
  94. package/dist/errors/index.js +268 -0
  95. package/dist/errors/index.js.map +1 -0
  96. package/dist/http/retry.cjs +36 -0
  97. package/dist/http/retry.cjs.map +1 -0
  98. package/dist/http/retry.d.cts +34 -0
  99. package/dist/http/retry.d.cts.map +1 -0
  100. package/dist/http/retry.d.ts +34 -0
  101. package/dist/http/retry.d.ts.map +1 -0
  102. package/dist/http/retry.js +36 -0
  103. package/dist/http/retry.js.map +1 -0
  104. package/dist/http/transport.cjs +143 -0
  105. package/dist/http/transport.cjs.map +1 -0
  106. package/dist/http/transport.d.cts +122 -0
  107. package/dist/http/transport.d.cts.map +1 -0
  108. package/dist/http/transport.d.ts +122 -0
  109. package/dist/http/transport.d.ts.map +1 -0
  110. package/dist/http/transport.js +143 -0
  111. package/dist/http/transport.js.map +1 -0
  112. package/dist/http/url-guard.cjs +97 -0
  113. package/dist/http/url-guard.cjs.map +1 -0
  114. package/dist/http/url-guard.d.cts +88 -0
  115. package/dist/http/url-guard.d.cts.map +1 -0
  116. package/dist/http/url-guard.d.ts +88 -0
  117. package/dist/http/url-guard.d.ts.map +1 -0
  118. package/dist/http/url-guard.js +97 -0
  119. package/dist/http/url-guard.js.map +1 -0
  120. package/dist/http/user-agent.cjs +51 -0
  121. package/dist/http/user-agent.cjs.map +1 -0
  122. package/dist/http/user-agent.d.cts +28 -0
  123. package/dist/http/user-agent.d.cts.map +1 -0
  124. package/dist/http/user-agent.d.ts +28 -0
  125. package/dist/http/user-agent.d.ts.map +1 -0
  126. package/dist/http/user-agent.js +51 -0
  127. package/dist/http/user-agent.js.map +1 -0
  128. package/dist/index.cjs +78 -0
  129. package/dist/index.cjs.map +1 -0
  130. package/dist/index.d.cts +39 -0
  131. package/dist/index.d.cts.map +1 -0
  132. package/dist/index.d.ts +39 -0
  133. package/dist/index.d.ts.map +1 -0
  134. package/dist/index.js +78 -0
  135. package/dist/index.js.map +1 -0
  136. package/dist/notifications/index.cjs +7 -0
  137. package/dist/notifications/index.cjs.map +1 -0
  138. package/dist/notifications/index.d.cts +3 -0
  139. package/dist/notifications/index.d.cts.map +1 -0
  140. package/dist/notifications/index.d.ts +3 -0
  141. package/dist/notifications/index.d.ts.map +1 -0
  142. package/dist/notifications/index.js +7 -0
  143. package/dist/notifications/index.js.map +1 -0
  144. package/dist/notifications/webhook.cjs +106 -0
  145. package/dist/notifications/webhook.cjs.map +1 -0
  146. package/dist/notifications/webhook.d.cts +146 -0
  147. package/dist/notifications/webhook.d.cts.map +1 -0
  148. package/dist/notifications/webhook.d.ts +146 -0
  149. package/dist/notifications/webhook.d.ts.map +1 -0
  150. package/dist/notifications/webhook.js +106 -0
  151. package/dist/notifications/webhook.js.map +1 -0
  152. package/dist/object.cjs +212 -0
  153. package/dist/object.cjs.map +1 -0
  154. package/dist/object.d.cts +263 -0
  155. package/dist/object.d.cts.map +1 -0
  156. package/dist/object.d.ts +263 -0
  157. package/dist/object.d.ts.map +1 -0
  158. package/dist/object.js +212 -0
  159. package/dist/object.js.map +1 -0
  160. package/dist/package.json.cjs +9 -0
  161. package/dist/package.json.cjs.map +1 -0
  162. package/dist/package.json.js +9 -0
  163. package/dist/package.json.js.map +1 -0
  164. package/dist/raw/encoding.cjs +47 -0
  165. package/dist/raw/encoding.cjs.map +1 -0
  166. package/dist/raw/encoding.d.cts +46 -0
  167. package/dist/raw/encoding.d.cts.map +1 -0
  168. package/dist/raw/encoding.d.ts +46 -0
  169. package/dist/raw/encoding.d.ts.map +1 -0
  170. package/dist/raw/encoding.js +47 -0
  171. package/dist/raw/encoding.js.map +1 -0
  172. package/dist/raw/index.cjs +600 -0
  173. package/dist/raw/index.cjs.map +1 -0
  174. package/dist/raw/index.d.cts +381 -0
  175. package/dist/raw/index.d.cts.map +1 -0
  176. package/dist/raw/index.d.ts +381 -0
  177. package/dist/raw/index.d.ts.map +1 -0
  178. package/dist/raw/index.js +601 -0
  179. package/dist/raw/index.js.map +1 -0
  180. package/dist/s3/index.cjs +23 -0
  181. package/dist/s3/index.cjs.map +1 -0
  182. package/dist/s3/index.d.cts +74 -0
  183. package/dist/s3/index.d.cts.map +1 -0
  184. package/dist/s3/index.d.ts +74 -0
  185. package/dist/s3/index.d.ts.map +1 -0
  186. package/dist/s3/index.js +23 -0
  187. package/dist/s3/index.js.map +1 -0
  188. package/dist/simulator/capabilities.cjs +53 -0
  189. package/dist/simulator/capabilities.cjs.map +1 -0
  190. package/dist/simulator/capabilities.d.cts +15 -0
  191. package/dist/simulator/capabilities.d.cts.map +1 -0
  192. package/dist/simulator/capabilities.d.ts +15 -0
  193. package/dist/simulator/capabilities.d.ts.map +1 -0
  194. package/dist/simulator/capabilities.js +53 -0
  195. package/dist/simulator/capabilities.js.map +1 -0
  196. package/dist/simulator/index.cjs +1559 -0
  197. package/dist/simulator/index.cjs.map +1 -0
  198. package/dist/simulator/index.d.cts +495 -0
  199. package/dist/simulator/index.d.cts.map +1 -0
  200. package/dist/simulator/index.d.ts +495 -0
  201. package/dist/simulator/index.d.ts.map +1 -0
  202. package/dist/simulator/index.js +1560 -0
  203. package/dist/simulator/index.js.map +1 -0
  204. package/dist/simulator/validation.cjs +174 -0
  205. package/dist/simulator/validation.cjs.map +1 -0
  206. package/dist/simulator/validation.d.cts +104 -0
  207. package/dist/simulator/validation.d.cts.map +1 -0
  208. package/dist/simulator/validation.d.ts +104 -0
  209. package/dist/simulator/validation.d.ts.map +1 -0
  210. package/dist/simulator/validation.js +174 -0
  211. package/dist/simulator/validation.js.map +1 -0
  212. package/dist/streams/collect.cjs +26 -0
  213. package/dist/streams/collect.cjs.map +1 -0
  214. package/dist/streams/collect.d.cts +18 -0
  215. package/dist/streams/collect.d.cts.map +1 -0
  216. package/dist/streams/collect.d.ts +18 -0
  217. package/dist/streams/collect.d.ts.map +1 -0
  218. package/dist/streams/collect.js +26 -0
  219. package/dist/streams/collect.js.map +1 -0
  220. package/dist/streams/hash.cjs +123 -0
  221. package/dist/streams/hash.cjs.map +1 -0
  222. package/dist/streams/hash.d.cts +42 -0
  223. package/dist/streams/hash.d.cts.map +1 -0
  224. package/dist/streams/hash.d.ts +42 -0
  225. package/dist/streams/hash.d.ts.map +1 -0
  226. package/dist/streams/hash.js +101 -0
  227. package/dist/streams/hash.js.map +1 -0
  228. package/dist/streams/index.cjs +13 -0
  229. package/dist/streams/index.cjs.map +1 -0
  230. package/dist/streams/index.d.cts +7 -0
  231. package/dist/streams/index.d.cts.map +1 -0
  232. package/dist/streams/index.d.ts +7 -0
  233. package/dist/streams/index.d.ts.map +1 -0
  234. package/dist/streams/index.js +13 -0
  235. package/dist/streams/index.js.map +1 -0
  236. package/dist/streams/progress.cjs +47 -0
  237. package/dist/streams/progress.cjs.map +1 -0
  238. package/dist/streams/progress.d.cts +53 -0
  239. package/dist/streams/progress.d.cts.map +1 -0
  240. package/dist/streams/progress.d.ts +53 -0
  241. package/dist/streams/progress.d.ts.map +1 -0
  242. package/dist/streams/progress.js +47 -0
  243. package/dist/streams/progress.js.map +1 -0
  244. package/dist/streams/source.cjs +155 -0
  245. package/dist/streams/source.cjs.map +1 -0
  246. package/dist/streams/source.d.cts +140 -0
  247. package/dist/streams/source.d.cts.map +1 -0
  248. package/dist/streams/source.d.ts +140 -0
  249. package/dist/streams/source.d.ts.map +1 -0
  250. package/dist/streams/source.js +155 -0
  251. package/dist/streams/source.js.map +1 -0
  252. package/dist/sync/actions/index.cjs +191 -0
  253. package/dist/sync/actions/index.cjs.map +1 -0
  254. package/dist/sync/actions/index.d.cts +167 -0
  255. package/dist/sync/actions/index.d.cts.map +1 -0
  256. package/dist/sync/actions/index.d.ts +167 -0
  257. package/dist/sync/actions/index.d.ts.map +1 -0
  258. package/dist/sync/actions/index.js +191 -0
  259. package/dist/sync/actions/index.js.map +1 -0
  260. package/dist/sync/index.cjs +23 -0
  261. package/dist/sync/index.cjs.map +1 -0
  262. package/dist/sync/index.d.cts +21 -0
  263. package/dist/sync/index.d.cts.map +1 -0
  264. package/dist/sync/index.d.ts +21 -0
  265. package/dist/sync/index.d.ts.map +1 -0
  266. package/dist/sync/index.js +23 -0
  267. package/dist/sync/index.js.map +1 -0
  268. package/dist/sync/pairing.cjs +31 -0
  269. package/dist/sync/pairing.cjs.map +1 -0
  270. package/dist/sync/pairing.d.cts +13 -0
  271. package/dist/sync/pairing.d.cts.map +1 -0
  272. package/dist/sync/pairing.d.ts +13 -0
  273. package/dist/sync/pairing.d.ts.map +1 -0
  274. package/dist/sync/pairing.js +31 -0
  275. package/dist/sync/pairing.js.map +1 -0
  276. package/dist/sync/policies/compare.cjs +14 -0
  277. package/dist/sync/policies/compare.cjs.map +1 -0
  278. package/dist/sync/policies/compare.d.cts +13 -0
  279. package/dist/sync/policies/compare.d.cts.map +1 -0
  280. package/dist/sync/policies/compare.d.ts +13 -0
  281. package/dist/sync/policies/compare.d.ts.map +1 -0
  282. package/dist/sync/policies/compare.js +14 -0
  283. package/dist/sync/policies/compare.js.map +1 -0
  284. package/dist/sync/policies/index.cjs +74 -0
  285. package/dist/sync/policies/index.cjs.map +1 -0
  286. package/dist/sync/policies/index.d.cts +42 -0
  287. package/dist/sync/policies/index.d.cts.map +1 -0
  288. package/dist/sync/policies/index.d.ts +42 -0
  289. package/dist/sync/policies/index.d.ts.map +1 -0
  290. package/dist/sync/policies/index.js +74 -0
  291. package/dist/sync/policies/index.js.map +1 -0
  292. package/dist/sync/scanners/b2.cjs +57 -0
  293. package/dist/sync/scanners/b2.cjs.map +1 -0
  294. package/dist/sync/scanners/b2.d.cts +20 -0
  295. package/dist/sync/scanners/b2.d.cts.map +1 -0
  296. package/dist/sync/scanners/b2.d.ts +20 -0
  297. package/dist/sync/scanners/b2.d.ts.map +1 -0
  298. package/dist/sync/scanners/b2.js +57 -0
  299. package/dist/sync/scanners/b2.js.map +1 -0
  300. package/dist/sync/scanners/local.cjs +58 -0
  301. package/dist/sync/scanners/local.cjs.map +1 -0
  302. package/dist/sync/scanners/local.d.cts +24 -0
  303. package/dist/sync/scanners/local.d.cts.map +1 -0
  304. package/dist/sync/scanners/local.d.ts +24 -0
  305. package/dist/sync/scanners/local.d.ts.map +1 -0
  306. package/dist/sync/scanners/local.js +58 -0
  307. package/dist/sync/scanners/local.js.map +1 -0
  308. package/dist/sync/synchronizer.cjs +203 -0
  309. package/dist/sync/synchronizer.cjs.map +1 -0
  310. package/dist/sync/synchronizer.d.cts +52 -0
  311. package/dist/sync/synchronizer.d.cts.map +1 -0
  312. package/dist/sync/synchronizer.d.ts +52 -0
  313. package/dist/sync/synchronizer.d.ts.map +1 -0
  314. package/dist/sync/synchronizer.js +181 -0
  315. package/dist/sync/synchronizer.js.map +1 -0
  316. package/dist/sync/types.d.cts +121 -0
  317. package/dist/sync/types.d.cts.map +1 -0
  318. package/dist/sync/types.d.ts +121 -0
  319. package/dist/sync/types.d.ts.map +1 -0
  320. package/dist/types/auth.cjs +58 -0
  321. package/dist/types/auth.cjs.map +1 -0
  322. package/dist/types/auth.d.cts +150 -0
  323. package/dist/types/auth.d.cts.map +1 -0
  324. package/dist/types/auth.d.ts +150 -0
  325. package/dist/types/auth.d.ts.map +1 -0
  326. package/dist/types/auth.js +58 -0
  327. package/dist/types/auth.js.map +1 -0
  328. package/dist/types/bucket.cjs +44 -0
  329. package/dist/types/bucket.cjs.map +1 -0
  330. package/dist/types/bucket.d.cts +245 -0
  331. package/dist/types/bucket.d.cts.map +1 -0
  332. package/dist/types/bucket.d.ts +245 -0
  333. package/dist/types/bucket.d.ts.map +1 -0
  334. package/dist/types/bucket.js +44 -0
  335. package/dist/types/bucket.js.map +1 -0
  336. package/dist/types/download.d.cts +110 -0
  337. package/dist/types/download.d.cts.map +1 -0
  338. package/dist/types/download.d.ts +110 -0
  339. package/dist/types/download.d.ts.map +1 -0
  340. package/dist/types/encryption.cjs +343 -0
  341. package/dist/types/encryption.cjs.map +1 -0
  342. package/dist/types/encryption.d.cts +132 -0
  343. package/dist/types/encryption.d.cts.map +1 -0
  344. package/dist/types/encryption.d.ts +132 -0
  345. package/dist/types/encryption.d.ts.map +1 -0
  346. package/dist/types/encryption.js +321 -0
  347. package/dist/types/encryption.js.map +1 -0
  348. package/dist/types/errors.d.cts +16 -0
  349. package/dist/types/errors.d.cts.map +1 -0
  350. package/dist/types/errors.d.ts +16 -0
  351. package/dist/types/errors.d.ts.map +1 -0
  352. package/dist/types/file.cjs +23 -0
  353. package/dist/types/file.cjs.map +1 -0
  354. package/dist/types/file.d.cts +220 -0
  355. package/dist/types/file.d.cts.map +1 -0
  356. package/dist/types/file.d.ts +220 -0
  357. package/dist/types/file.d.ts.map +1 -0
  358. package/dist/types/file.js +23 -0
  359. package/dist/types/file.js.map +1 -0
  360. package/dist/types/ids.cjs +27 -0
  361. package/dist/types/ids.cjs.map +1 -0
  362. package/dist/types/ids.d.cts +84 -0
  363. package/dist/types/ids.d.cts.map +1 -0
  364. package/dist/types/ids.d.ts +84 -0
  365. package/dist/types/ids.d.ts.map +1 -0
  366. package/dist/types/ids.js +27 -0
  367. package/dist/types/ids.js.map +1 -0
  368. package/dist/types/index.d.cts +25 -0
  369. package/dist/types/index.d.cts.map +1 -0
  370. package/dist/types/index.d.ts +25 -0
  371. package/dist/types/index.d.ts.map +1 -0
  372. package/dist/types/key.d.cts +84 -0
  373. package/dist/types/key.d.cts.map +1 -0
  374. package/dist/types/key.d.ts +84 -0
  375. package/dist/types/key.d.ts.map +1 -0
  376. package/dist/types/lock.cjs +17 -0
  377. package/dist/types/lock.cjs.map +1 -0
  378. package/dist/types/lock.d.cts +92 -0
  379. package/dist/types/lock.d.cts.map +1 -0
  380. package/dist/types/lock.d.ts +92 -0
  381. package/dist/types/lock.d.ts.map +1 -0
  382. package/dist/types/lock.js +17 -0
  383. package/dist/types/lock.js.map +1 -0
  384. package/dist/types/notifications.cjs +24 -0
  385. package/dist/types/notifications.cjs.map +1 -0
  386. package/dist/types/notifications.d.cts +97 -0
  387. package/dist/types/notifications.d.cts.map +1 -0
  388. package/dist/types/notifications.d.ts +97 -0
  389. package/dist/types/notifications.d.ts.map +1 -0
  390. package/dist/types/notifications.js +24 -0
  391. package/dist/types/notifications.js.map +1 -0
  392. package/dist/types/replication.d.cts +42 -0
  393. package/dist/types/replication.d.cts.map +1 -0
  394. package/dist/types/replication.d.ts +42 -0
  395. package/dist/types/replication.d.ts.map +1 -0
  396. package/dist/types/upload.d.cts +219 -0
  397. package/dist/types/upload.d.cts.map +1 -0
  398. package/dist/types/upload.d.ts +219 -0
  399. package/dist/types/upload.d.ts.map +1 -0
  400. package/dist/upload/cancel.cjs +10 -0
  401. package/dist/upload/cancel.cjs.map +1 -0
  402. package/dist/upload/cancel.d.cts +23 -0
  403. package/dist/upload/cancel.d.cts.map +1 -0
  404. package/dist/upload/cancel.d.ts +23 -0
  405. package/dist/upload/cancel.d.ts.map +1 -0
  406. package/dist/upload/cancel.js +10 -0
  407. package/dist/upload/cancel.js.map +1 -0
  408. package/dist/upload/concurrency.cjs +54 -0
  409. package/dist/upload/concurrency.cjs.map +1 -0
  410. package/dist/upload/concurrency.d.cts +46 -0
  411. package/dist/upload/concurrency.d.cts.map +1 -0
  412. package/dist/upload/concurrency.d.ts +46 -0
  413. package/dist/upload/concurrency.d.ts.map +1 -0
  414. package/dist/upload/concurrency.js +54 -0
  415. package/dist/upload/concurrency.js.map +1 -0
  416. package/dist/upload/large.cjs +222 -0
  417. package/dist/upload/large.cjs.map +1 -0
  418. package/dist/upload/large.d.cts +71 -0
  419. package/dist/upload/large.d.cts.map +1 -0
  420. package/dist/upload/large.d.ts +71 -0
  421. package/dist/upload/large.d.ts.map +1 -0
  422. package/dist/upload/large.js +222 -0
  423. package/dist/upload/large.js.map +1 -0
  424. package/dist/upload/resume.cjs +34 -0
  425. package/dist/upload/resume.cjs.map +1 -0
  426. package/dist/upload/resume.d.cts +33 -0
  427. package/dist/upload/resume.d.cts.map +1 -0
  428. package/dist/upload/resume.d.ts +33 -0
  429. package/dist/upload/resume.d.ts.map +1 -0
  430. package/dist/upload/resume.js +34 -0
  431. package/dist/upload/resume.js.map +1 -0
  432. package/dist/upload/single.cjs +47 -0
  433. package/dist/upload/single.cjs.map +1 -0
  434. package/dist/upload/single.d.cts +51 -0
  435. package/dist/upload/single.d.cts.map +1 -0
  436. package/dist/upload/single.d.ts +51 -0
  437. package/dist/upload/single.d.ts.map +1 -0
  438. package/dist/upload/single.js +47 -0
  439. package/dist/upload/single.js.map +1 -0
  440. package/dist/upload/stream.cjs +198 -0
  441. package/dist/upload/stream.cjs.map +1 -0
  442. package/dist/upload/stream.d.cts +61 -0
  443. package/dist/upload/stream.d.cts.map +1 -0
  444. package/dist/upload/stream.d.ts +61 -0
  445. package/dist/upload/stream.d.ts.map +1 -0
  446. package/dist/upload/stream.js +198 -0
  447. package/dist/upload/stream.js.map +1 -0
  448. package/dist/util/best-effort.cjs +10 -0
  449. package/dist/util/best-effort.cjs.map +1 -0
  450. package/dist/util/best-effort.d.cts +31 -0
  451. package/dist/util/best-effort.d.cts.map +1 -0
  452. package/dist/util/best-effort.d.ts +31 -0
  453. package/dist/util/best-effort.d.ts.map +1 -0
  454. package/dist/util/best-effort.js +10 -0
  455. package/dist/util/best-effort.js.map +1 -0
  456. package/dist/util/defaults.cjs +11 -0
  457. package/dist/util/defaults.cjs.map +1 -0
  458. package/dist/util/defaults.d.cts +54 -0
  459. package/dist/util/defaults.d.cts.map +1 -0
  460. package/dist/util/defaults.d.ts +54 -0
  461. package/dist/util/defaults.d.ts.map +1 -0
  462. package/dist/util/defaults.js +11 -0
  463. package/dist/util/defaults.js.map +1 -0
  464. package/dist/util/normalize.cjs +16 -0
  465. package/dist/util/normalize.cjs.map +1 -0
  466. package/dist/util/normalize.d.cts +62 -0
  467. package/dist/util/normalize.d.cts.map +1 -0
  468. package/dist/util/normalize.d.ts +62 -0
  469. package/dist/util/normalize.d.ts.map +1 -0
  470. package/dist/util/normalize.js +16 -0
  471. package/dist/util/normalize.js.map +1 -0
  472. package/dist/util/paginator.cjs +20 -0
  473. package/dist/util/paginator.cjs.map +1 -0
  474. package/dist/util/paginator.d.cts +120 -0
  475. package/dist/util/paginator.d.cts.map +1 -0
  476. package/dist/util/paginator.d.ts +120 -0
  477. package/dist/util/paginator.d.ts.map +1 -0
  478. package/dist/util/paginator.js +20 -0
  479. package/dist/util/paginator.js.map +1 -0
  480. package/dist/util/plan-ranges.cjs +28 -0
  481. package/dist/util/plan-ranges.cjs.map +1 -0
  482. package/dist/util/plan-ranges.d.cts +56 -0
  483. package/dist/util/plan-ranges.d.cts.map +1 -0
  484. package/dist/util/plan-ranges.d.ts +56 -0
  485. package/dist/util/plan-ranges.d.ts.map +1 -0
  486. package/dist/util/plan-ranges.js +28 -0
  487. package/dist/util/plan-ranges.js.map +1 -0
  488. package/dist/util/text-codec.cjs +7 -0
  489. package/dist/util/text-codec.cjs.map +1 -0
  490. package/dist/util/text-codec.d.cts +26 -0
  491. package/dist/util/text-codec.d.cts.map +1 -0
  492. package/dist/util/text-codec.d.ts +26 -0
  493. package/dist/util/text-codec.d.ts.map +1 -0
  494. package/dist/util/text-codec.js +7 -0
  495. package/dist/util/text-codec.js.map +1 -0
  496. package/dist/util/to-error.cjs +7 -0
  497. package/dist/util/to-error.cjs.map +1 -0
  498. package/dist/util/to-error.d.cts +15 -0
  499. package/dist/util/to-error.d.cts.map +1 -0
  500. package/dist/util/to-error.d.ts +15 -0
  501. package/dist/util/to-error.d.ts.map +1 -0
  502. package/dist/util/to-error.js +7 -0
  503. package/dist/util/to-error.js.map +1 -0
  504. package/dist/version.cjs +6 -0
  505. package/dist/version.cjs.map +1 -0
  506. package/dist/version.d.cts +14 -0
  507. package/dist/version.d.cts.map +1 -0
  508. package/dist/version.d.ts +14 -0
  509. package/dist/version.d.ts.map +1 -0
  510. package/dist/version.js +6 -0
  511. package/dist/version.js.map +1 -0
  512. package/package.json +198 -0
@@ -0,0 +1,222 @@
1
+ import { IncrementalSha1 } from "../streams/hash.js";
2
+ import { ProgressTracker } from "../streams/progress.js";
3
+ import { DEFAULT_TRANSFER_CONCURRENCY, DEFAULT_CONTENT_TYPE } from "../util/defaults.js";
4
+ import { planRanges } from "../util/plan-ranges.js";
5
+ import { cancelLargeFileBestEffort } from "./cancel.js";
6
+ import { Semaphore } from "./concurrency.js";
7
+ import { collectPartSha1s, findResumeCandidate } from "./resume.js";
8
+ async function uploadLargeFile(raw, accountInfo, options) {
9
+ const recommendedPartSize = accountInfo.getRecommendedPartSize();
10
+ const minPartSize = accountInfo.getAbsoluteMinimumPartSize();
11
+ const partSize = Math.max(options.partSize ?? recommendedPartSize, minPartSize);
12
+ const concurrency = options.concurrency ?? DEFAULT_TRANSFER_CONCURRENCY;
13
+ const totalSize = options.source.size;
14
+ const parts = planRanges(totalSize, partSize);
15
+ const fileInfo = { ...options.fileInfo };
16
+ const startLargeFileRequest = {
17
+ bucketId: options.bucketId,
18
+ fileName: options.fileName,
19
+ contentType: options.contentType ?? DEFAULT_CONTENT_TYPE,
20
+ fileInfo,
21
+ ...options.serverSideEncryption !== void 0 ? { serverSideEncryption: options.serverSideEncryption } : {},
22
+ ...options.fileRetention !== void 0 ? { fileRetention: options.fileRetention } : {},
23
+ ...options.legalHold !== void 0 ? { legalHold: options.legalHold } : {}
24
+ };
25
+ let largeFileId;
26
+ let preUploaded;
27
+ if (options.resumeFileId !== void 0) {
28
+ largeFileId = options.resumeFileId;
29
+ preUploaded = await collectPartSha1s(raw, accountInfo, largeFileId);
30
+ } else if (options.resume === true) {
31
+ const candidate = await findResumeCandidate(
32
+ raw,
33
+ accountInfo,
34
+ options.bucketId,
35
+ options.fileName
36
+ );
37
+ if (candidate) {
38
+ largeFileId = candidate.fileId;
39
+ preUploaded = candidate.uploadedPartSha1s;
40
+ } else {
41
+ const startResp = await raw.startLargeFile(
42
+ accountInfo.getApiUrl(),
43
+ accountInfo.getAuthToken(),
44
+ startLargeFileRequest
45
+ );
46
+ largeFileId = startResp.fileId;
47
+ preUploaded = /* @__PURE__ */ new Map();
48
+ }
49
+ } else {
50
+ const startResp = await raw.startLargeFile(
51
+ accountInfo.getApiUrl(),
52
+ accountInfo.getAuthToken(),
53
+ startLargeFileRequest
54
+ );
55
+ largeFileId = startResp.fileId;
56
+ preUploaded = /* @__PURE__ */ new Map();
57
+ }
58
+ const partSha1s = new Array(parts.length);
59
+ const tracker = new ProgressTracker(options.onProgress, totalSize, parts.length);
60
+ const sem = new Semaphore(concurrency);
61
+ if (!options.source.canSlice) {
62
+ if (options.resume === true || options.resumeFileId !== void 0) {
63
+ await cancelLargeFileBestEffort(raw, accountInfo, largeFileId);
64
+ throw new Error(
65
+ "uploadLargeFile: resume is not supported on non-sliceable sources (e.g. StreamSource)."
66
+ );
67
+ }
68
+ try {
69
+ await uploadPartsSequentially(
70
+ raw,
71
+ accountInfo,
72
+ options,
73
+ largeFileId,
74
+ parts,
75
+ partSha1s,
76
+ tracker
77
+ );
78
+ return await raw.finishLargeFile(accountInfo.getApiUrl(), accountInfo.getAuthToken(), {
79
+ fileId: largeFileId,
80
+ partSha1Array: partSha1s
81
+ });
82
+ } catch (err) {
83
+ await cancelLargeFileBestEffort(raw, accountInfo, largeFileId);
84
+ throw err;
85
+ }
86
+ }
87
+ try {
88
+ const tasks = parts.map(async (part) => {
89
+ await sem.acquire();
90
+ try {
91
+ options.signal?.throwIfAborted();
92
+ const partSource = options.source.slice(part.offset, part.offset + part.length);
93
+ const data = new Uint8Array(await partSource.toArrayBuffer());
94
+ const partSha1 = new IncrementalSha1();
95
+ await partSha1.update(data);
96
+ const sha1Hex = await partSha1.digest();
97
+ const serverSha1 = preUploaded.get(part.partNumber);
98
+ if (serverSha1 !== void 0 && serverSha1 === sha1Hex) {
99
+ partSha1s[part.partNumber - 1] = serverSha1;
100
+ tracker.addBytes(data.byteLength);
101
+ tracker.completePart();
102
+ return;
103
+ }
104
+ let uploadEntry = accountInfo.checkoutPartUploadUrl(largeFileId);
105
+ if (!uploadEntry) {
106
+ const resp = await raw.getUploadPartUrl(
107
+ accountInfo.getApiUrl(),
108
+ accountInfo.getAuthToken(),
109
+ { fileId: largeFileId }
110
+ );
111
+ uploadEntry = { uploadUrl: resp.uploadUrl, authorizationToken: resp.authorizationToken };
112
+ }
113
+ try {
114
+ const result2 = await raw.uploadPart(
115
+ uploadEntry.uploadUrl,
116
+ {
117
+ authorization: uploadEntry.authorizationToken,
118
+ partNumber: part.partNumber,
119
+ contentLength: data.byteLength,
120
+ contentSha1: sha1Hex,
121
+ ...options.serverSideEncryption !== void 0 ? { serverSideEncryption: options.serverSideEncryption } : {}
122
+ },
123
+ data,
124
+ options.signal
125
+ );
126
+ accountInfo.returnPartUploadUrl(largeFileId, uploadEntry);
127
+ partSha1s[part.partNumber - 1] = result2.contentSha1;
128
+ tracker.addBytes(data.byteLength);
129
+ tracker.completePart();
130
+ } catch (err) {
131
+ accountInfo.evictPartUploadUrl(largeFileId, uploadEntry);
132
+ throw err;
133
+ }
134
+ } finally {
135
+ sem.release();
136
+ }
137
+ });
138
+ await Promise.all(tasks);
139
+ const result = await raw.finishLargeFile(accountInfo.getApiUrl(), accountInfo.getAuthToken(), {
140
+ fileId: largeFileId,
141
+ partSha1Array: partSha1s
142
+ });
143
+ return result;
144
+ } catch (err) {
145
+ await cancelLargeFileBestEffort(raw, accountInfo, largeFileId);
146
+ throw err;
147
+ }
148
+ }
149
+ async function uploadPartsSequentially(raw, accountInfo, options, largeFileId, parts, partSha1s, tracker) {
150
+ const reader = options.source.stream().getReader();
151
+ let partNumber = 1;
152
+ let carry = null;
153
+ try {
154
+ for (const planned of parts) {
155
+ options.signal?.throwIfAborted();
156
+ const buf = new Uint8Array(planned.length);
157
+ let filled = 0;
158
+ if (carry !== null) {
159
+ const take = Math.min(carry.byteLength, buf.byteLength - filled);
160
+ buf.set(carry.subarray(0, take), filled);
161
+ filled += take;
162
+ carry = take < carry.byteLength ? carry.subarray(take) : null;
163
+ }
164
+ while (filled < buf.byteLength) {
165
+ const { done, value } = await reader.read();
166
+ if (done) break;
167
+ const take = Math.min(value.byteLength, buf.byteLength - filled);
168
+ buf.set(value.subarray(0, take), filled);
169
+ filled += take;
170
+ if (take < value.byteLength) {
171
+ carry = value.subarray(take);
172
+ }
173
+ }
174
+ const data = filled === buf.byteLength ? buf : buf.subarray(0, filled);
175
+ if (data.byteLength === 0) {
176
+ throw new Error(
177
+ `uploadLargeFile: source stream ended before part ${partNumber}; advertised size does not match emitted bytes.`
178
+ );
179
+ }
180
+ const partSha1 = new IncrementalSha1();
181
+ await partSha1.update(data);
182
+ const sha1Hex = await partSha1.digest();
183
+ let uploadEntry = accountInfo.checkoutPartUploadUrl(largeFileId);
184
+ if (!uploadEntry) {
185
+ const resp = await raw.getUploadPartUrl(
186
+ accountInfo.getApiUrl(),
187
+ accountInfo.getAuthToken(),
188
+ { fileId: largeFileId }
189
+ );
190
+ uploadEntry = { uploadUrl: resp.uploadUrl, authorizationToken: resp.authorizationToken };
191
+ }
192
+ try {
193
+ const result = await raw.uploadPart(
194
+ uploadEntry.uploadUrl,
195
+ {
196
+ authorization: uploadEntry.authorizationToken,
197
+ partNumber: planned.partNumber,
198
+ contentLength: data.byteLength,
199
+ contentSha1: sha1Hex,
200
+ ...options.serverSideEncryption !== void 0 ? { serverSideEncryption: options.serverSideEncryption } : {}
201
+ },
202
+ data,
203
+ options.signal
204
+ );
205
+ accountInfo.returnPartUploadUrl(largeFileId, uploadEntry);
206
+ partSha1s[planned.partNumber - 1] = result.contentSha1;
207
+ tracker.addBytes(data.byteLength);
208
+ tracker.completePart();
209
+ } catch (err) {
210
+ accountInfo.evictPartUploadUrl(largeFileId, uploadEntry);
211
+ throw err;
212
+ }
213
+ partNumber++;
214
+ }
215
+ } finally {
216
+ reader.releaseLock();
217
+ }
218
+ }
219
+ export {
220
+ uploadLargeFile
221
+ };
222
+ //# sourceMappingURL=large.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"large.js","sources":["../../src/upload/large.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 } from '../streams/progress.ts'\nimport { 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, LargeFileId } from '../types/ids.ts'\nimport type { FileRetentionValue, LegalHoldValue } from '../types/lock.ts'\nimport { DEFAULT_CONTENT_TYPE, DEFAULT_TRANSFER_CONCURRENCY } from '../util/defaults.ts'\nimport { type RangePlan, planRanges } from '../util/plan-ranges.ts'\nimport { cancelLargeFileBestEffort } from './cancel.ts'\nimport { Semaphore } from './concurrency.ts'\nimport { collectPartSha1s, findResumeCandidate } from './resume.ts'\n\n/** Options for uploading a large file via the multipart protocol. */\nexport interface UploadLargeFileOptions {\n /** Target bucket for the upload. */\n readonly bucketId: BucketId\n /** Full B2 file name including any path prefix. */\n readonly fileName: string\n /**\n * Content to upload. Sliceable sources ({@link BufferSource},\n * {@link BlobSource}) use the parallel-parts path. Non-sliceable\n * sources ({@link StreamSource}) fall back to a sequential read path\n * — one part at a time, concurrency forced to 1 — so callers can\n * stream a multi-GB file without buffering the whole payload in\n * memory. The `resume` / `resumeFileId` options require a sliceable\n * source; they throw on a `StreamSource`.\n */\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 applied to each part. */\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 /** Size of each part in bytes. Defaults to the account's recommended part size. */\n readonly partSize?: number\n /** Maximum number of parts uploaded in parallel. Defaults to 4. */\n readonly concurrency?: number\n /** Callback invoked with upload progress updates. */\n readonly onProgress?: ProgressListener\n /** Signal to abort the upload. Triggers cancellation of the large file. */\n readonly signal?: AbortSignal\n /**\n * If true, look for an unfinished large file with the same bucket and file name\n * and skip parts whose locally-recomputed SHA-1 matches the server's.\n */\n readonly resume?: boolean\n /**\n * Explicit large file ID to resume into. Overrides {@link resume} discovery\n * but the local `partSize` must still match the server's plan.\n */\n readonly resumeFileId?: LargeFileId\n}\n\n/**\n * Uploads a file using the B2 multipart (large file) protocol.\n *\n * The source is sliced into parts and uploaded concurrently via\n * `b2_upload_part`. This is appropriate for files larger than the recommended\n * part size. For smaller files, use {@link uploadSmallFile} which sends the\n * entire payload in a single request.\n *\n * On failure, the in-progress large file is cancelled on a best-effort basis.\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 including part size and concurrency.\n *\n * @returns The resulting {@link FileVersion} metadata.\n */\nexport async function uploadLargeFile(\n raw: RawClient,\n accountInfo: AccountInfo,\n options: UploadLargeFileOptions,\n): Promise<FileVersion> {\n const recommendedPartSize = accountInfo.getRecommendedPartSize()\n const minPartSize = accountInfo.getAbsoluteMinimumPartSize()\n const partSize = Math.max(options.partSize ?? recommendedPartSize, minPartSize)\n const concurrency = options.concurrency ?? DEFAULT_TRANSFER_CONCURRENCY\n const totalSize = options.source.size\n\n const parts = planRanges(totalSize, partSize)\n const fileInfo: Record<string, string> = { ...options.fileInfo }\n\n // Construct the `b2_start_large_file` request body once so the two\n // non-resume branches below (no `resume`, resume-but-no-candidate)\n // can dispatch without re-spelling the conditional spreads.\n const startLargeFileRequest = {\n bucketId: options.bucketId,\n fileName: options.fileName,\n contentType: options.contentType ?? DEFAULT_CONTENT_TYPE,\n 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 }\n\n // --- Resume discovery (M11.1) ---\n let largeFileId: LargeFileId\n let preUploaded: ReadonlyMap<number, string>\n\n if (options.resumeFileId !== undefined) {\n largeFileId = options.resumeFileId\n preUploaded = await collectPartSha1s(raw, accountInfo, largeFileId)\n } else if (options.resume === true) {\n const candidate = await findResumeCandidate(\n raw,\n accountInfo,\n options.bucketId,\n options.fileName,\n )\n if (candidate) {\n largeFileId = candidate.fileId\n preUploaded = candidate.uploadedPartSha1s\n } else {\n const startResp = await raw.startLargeFile(\n accountInfo.getApiUrl(),\n accountInfo.getAuthToken(),\n startLargeFileRequest,\n )\n largeFileId = startResp.fileId\n preUploaded = new Map<number, string>()\n }\n } else {\n const startResp = await raw.startLargeFile(\n accountInfo.getApiUrl(),\n accountInfo.getAuthToken(),\n startLargeFileRequest,\n )\n largeFileId = startResp.fileId\n preUploaded = new Map<number, string>()\n }\n\n const partSha1s: string[] = new Array(parts.length)\n const tracker = new ProgressTracker(options.onProgress, totalSize, parts.length)\n const sem = new Semaphore(concurrency)\n\n // Non-sliceable sources (e.g. `StreamSource` wrapping a Node\n // `Readable.toWeb`) can't be read in parallel — there's only one\n // forward-only cursor. Resume is also impossible (no seek). Bail to a\n // sequential read loop instead. Each part is buffered, hashed,\n // shipped, then dropped before the next read starts, so the peak\n // memory footprint is ~partSize bytes regardless of total file size.\n if (!options.source.canSlice) {\n if (options.resume === true || options.resumeFileId !== undefined) {\n // Cancel the unfinished large file before throwing so the caller\n // doesn't have to clean it up themselves.\n await cancelLargeFileBestEffort(raw, accountInfo, largeFileId)\n throw new Error(\n 'uploadLargeFile: resume is not supported on non-sliceable sources (e.g. StreamSource).',\n )\n }\n try {\n await uploadPartsSequentially(\n raw,\n accountInfo,\n options,\n largeFileId,\n parts,\n partSha1s,\n tracker,\n )\n return await raw.finishLargeFile(accountInfo.getApiUrl(), accountInfo.getAuthToken(), {\n fileId: largeFileId,\n partSha1Array: partSha1s,\n })\n } catch (err) {\n await cancelLargeFileBestEffort(raw, accountInfo, largeFileId)\n throw err\n }\n }\n\n try {\n const tasks = parts.map(async (part) => {\n await sem.acquire()\n try {\n options.signal?.throwIfAborted()\n\n const partSource = options.source.slice(part.offset, part.offset + part.length)\n const data = new Uint8Array(await partSource.toArrayBuffer())\n\n const partSha1 = new IncrementalSha1()\n await partSha1.update(data)\n const sha1Hex = await partSha1.digest()\n\n // Resume short-circuit: server already has this part with matching SHA-1\n const serverSha1 = preUploaded.get(part.partNumber)\n if (serverSha1 !== undefined && serverSha1 === sha1Hex) {\n partSha1s[part.partNumber - 1] = serverSha1\n tracker.addBytes(data.byteLength)\n tracker.completePart()\n return\n }\n\n let uploadEntry = accountInfo.checkoutPartUploadUrl(largeFileId)\n if (!uploadEntry) {\n const resp = await raw.getUploadPartUrl(\n accountInfo.getApiUrl(),\n accountInfo.getAuthToken(),\n { fileId: largeFileId },\n )\n uploadEntry = { uploadUrl: resp.uploadUrl, authorizationToken: resp.authorizationToken }\n }\n\n try {\n const result = await raw.uploadPart(\n uploadEntry.uploadUrl,\n {\n authorization: uploadEntry.authorizationToken,\n partNumber: part.partNumber,\n contentLength: data.byteLength,\n contentSha1: sha1Hex,\n ...(options.serverSideEncryption !== undefined\n ? { serverSideEncryption: options.serverSideEncryption }\n : {}),\n },\n data,\n options.signal,\n )\n\n accountInfo.returnPartUploadUrl(largeFileId, uploadEntry)\n partSha1s[part.partNumber - 1] = result.contentSha1\n tracker.addBytes(data.byteLength)\n tracker.completePart()\n } catch (err) {\n accountInfo.evictPartUploadUrl(largeFileId, uploadEntry)\n throw err\n }\n } finally {\n sem.release()\n }\n })\n\n await Promise.all(tasks)\n\n const result = await raw.finishLargeFile(accountInfo.getApiUrl(), accountInfo.getAuthToken(), {\n fileId: largeFileId,\n partSha1Array: partSha1s,\n })\n\n return result\n } catch (err) {\n await cancelLargeFileBestEffort(raw, accountInfo, largeFileId)\n throw err\n }\n}\n\n/**\n * Sequential upload path for non-sliceable sources (`StreamSource`).\n *\n * Reads the source's `stream()` once and accumulates exactly `partSize`\n * bytes into an in-memory buffer per iteration. Each filled buffer is\n * hashed, dispatched to `b2_upload_part`, then released before the next\n * part starts — so peak memory is ~partSize regardless of file size.\n *\n * Concurrency is forced to 1 here because the stream is a single\n * forward-only cursor; the engine can't read part N+1 until part N is\n * fully consumed.\n *\n * @param raw - Low-level B2 API client.\n * @param accountInfo - Authorized account state.\n * @param options - The original `uploadLargeFile` options.\n * @param largeFileId - ID of the in-progress large file (already started).\n * @param parts - Pre-planned part layout (used for part numbers + count).\n * @param partSha1s - Output array, written in-place at index `partNumber - 1`.\n * @param tracker - Progress tracker; bytes added per chunk, part completed\n * each time a part finishes.\n */\nasync function uploadPartsSequentially(\n raw: RawClient,\n accountInfo: AccountInfo,\n options: UploadLargeFileOptions,\n largeFileId: LargeFileId,\n parts: readonly RangePlan[],\n partSha1s: string[],\n tracker: ProgressTracker,\n): Promise<void> {\n const reader = options.source.stream().getReader()\n let partNumber = 1\n // Carry-over bytes from a previous read when the read returned more\n // than we needed to fill one part. Kept as an array to avoid an\n // allocation per loop iteration on a typical multi-part upload.\n let carry: Uint8Array | null = null\n\n try {\n for (const planned of parts) {\n options.signal?.throwIfAborted()\n\n const buf = new Uint8Array(planned.length)\n let filled = 0\n\n if (carry !== null) {\n const take = Math.min(carry.byteLength, buf.byteLength - filled)\n buf.set(carry.subarray(0, take), filled)\n filled += take\n carry = take < carry.byteLength ? carry.subarray(take) : null\n }\n\n while (filled < buf.byteLength) {\n const { done, value } = await reader.read()\n if (done) break\n const take = Math.min(value.byteLength, buf.byteLength - filled)\n buf.set(value.subarray(0, take), filled)\n filled += take\n if (take < value.byteLength) {\n carry = value.subarray(take)\n }\n }\n\n // For the LAST part the stream may run dry mid-buffer, leaving a\n // shorter chunk. B2 accepts a final part smaller than `partSize`.\n const data = filled === buf.byteLength ? buf : buf.subarray(0, filled)\n /* v8 ignore start -- defensive: only fires when the source's advertised\n size over-reports the actual emitted byte count, which a well-behaved\n ContentSource implementation cannot do. Kept so callers feeding the\n engine a buggy custom stream get an actionable error rather than a\n B2 wire-level failure. */\n if (data.byteLength === 0) {\n throw new Error(\n `uploadLargeFile: source stream ended before part ${partNumber}; advertised size does not match emitted bytes.`,\n )\n }\n /* v8 ignore stop */\n\n const partSha1 = new IncrementalSha1()\n await partSha1.update(data)\n const sha1Hex = await partSha1.digest()\n\n let uploadEntry = accountInfo.checkoutPartUploadUrl(largeFileId)\n if (!uploadEntry) {\n const resp = await raw.getUploadPartUrl(\n accountInfo.getApiUrl(),\n accountInfo.getAuthToken(),\n { fileId: largeFileId },\n )\n uploadEntry = { uploadUrl: resp.uploadUrl, authorizationToken: resp.authorizationToken }\n }\n\n try {\n const result = await raw.uploadPart(\n uploadEntry.uploadUrl,\n {\n authorization: uploadEntry.authorizationToken,\n partNumber: planned.partNumber,\n contentLength: data.byteLength,\n contentSha1: sha1Hex,\n ...(options.serverSideEncryption !== undefined\n ? { serverSideEncryption: options.serverSideEncryption }\n : {}),\n },\n data,\n options.signal,\n )\n\n accountInfo.returnPartUploadUrl(largeFileId, uploadEntry)\n partSha1s[planned.partNumber - 1] = result.contentSha1\n tracker.addBytes(data.byteLength)\n tracker.completePart()\n } catch (err) {\n accountInfo.evictPartUploadUrl(largeFileId, uploadEntry)\n throw err\n }\n\n partNumber++\n }\n } finally {\n // Releasing the lock lets the underlying stream propagate close /\n // error events to any upstream producer (e.g. a Node `Readable`).\n reader.releaseLock()\n }\n}\n"],"names":["result"],"mappings":";;;;;;;AA8EA,eAAsB,gBACpB,KACA,aACA,SACsB;AACtB,QAAM,sBAAsB,YAAY,uBAAA;AACxC,QAAM,cAAc,YAAY,2BAAA;AAChC,QAAM,WAAW,KAAK,IAAI,QAAQ,YAAY,qBAAqB,WAAW;AAC9E,QAAM,cAAc,QAAQ,eAAe;AAC3C,QAAM,YAAY,QAAQ,OAAO;AAEjC,QAAM,QAAQ,WAAW,WAAW,QAAQ;AAC5C,QAAM,WAAmC,EAAE,GAAG,QAAQ,SAAA;AAKtD,QAAM,wBAAwB;AAAA,IAC5B,UAAU,QAAQ;AAAA,IAClB,UAAU,QAAQ;AAAA,IAClB,aAAa,QAAQ,eAAe;AAAA,IACpC;AAAA,IACA,GAAI,QAAQ,yBAAyB,SACjC,EAAE,sBAAsB,QAAQ,qBAAA,IAChC,CAAA;AAAA,IACJ,GAAI,QAAQ,kBAAkB,SAAY,EAAE,eAAe,QAAQ,cAAA,IAAkB,CAAA;AAAA,IACrF,GAAI,QAAQ,cAAc,SAAY,EAAE,WAAW,QAAQ,cAAc,CAAA;AAAA,EAAC;AAI5E,MAAI;AACJ,MAAI;AAEJ,MAAI,QAAQ,iBAAiB,QAAW;AACtC,kBAAc,QAAQ;AACtB,kBAAc,MAAM,iBAAiB,KAAK,aAAa,WAAW;AAAA,EACpE,WAAW,QAAQ,WAAW,MAAM;AAClC,UAAM,YAAY,MAAM;AAAA,MACtB;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,IAAA;AAEV,QAAI,WAAW;AACb,oBAAc,UAAU;AACxB,oBAAc,UAAU;AAAA,IAC1B,OAAO;AACL,YAAM,YAAY,MAAM,IAAI;AAAA,QAC1B,YAAY,UAAA;AAAA,QACZ,YAAY,aAAA;AAAA,QACZ;AAAA,MAAA;AAEF,oBAAc,UAAU;AACxB,wCAAkB,IAAA;AAAA,IACpB;AAAA,EACF,OAAO;AACL,UAAM,YAAY,MAAM,IAAI;AAAA,MAC1B,YAAY,UAAA;AAAA,MACZ,YAAY,aAAA;AAAA,MACZ;AAAA,IAAA;AAEF,kBAAc,UAAU;AACxB,sCAAkB,IAAA;AAAA,EACpB;AAEA,QAAM,YAAsB,IAAI,MAAM,MAAM,MAAM;AAClD,QAAM,UAAU,IAAI,gBAAgB,QAAQ,YAAY,WAAW,MAAM,MAAM;AAC/E,QAAM,MAAM,IAAI,UAAU,WAAW;AAQrC,MAAI,CAAC,QAAQ,OAAO,UAAU;AAC5B,QAAI,QAAQ,WAAW,QAAQ,QAAQ,iBAAiB,QAAW;AAGjE,YAAM,0BAA0B,KAAK,aAAa,WAAW;AAC7D,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAAA,IAEJ;AACA,QAAI;AACF,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAEF,aAAO,MAAM,IAAI,gBAAgB,YAAY,aAAa,YAAY,gBAAgB;AAAA,QACpF,QAAQ;AAAA,QACR,eAAe;AAAA,MAAA,CAChB;AAAA,IACH,SAAS,KAAK;AACZ,YAAM,0BAA0B,KAAK,aAAa,WAAW;AAC7D,YAAM;AAAA,IACR;AAAA,EACF;AAEA,MAAI;AACF,UAAM,QAAQ,MAAM,IAAI,OAAO,SAAS;AACtC,YAAM,IAAI,QAAA;AACV,UAAI;AACF,gBAAQ,QAAQ,eAAA;AAEhB,cAAM,aAAa,QAAQ,OAAO,MAAM,KAAK,QAAQ,KAAK,SAAS,KAAK,MAAM;AAC9E,cAAM,OAAO,IAAI,WAAW,MAAM,WAAW,eAAe;AAE5D,cAAM,WAAW,IAAI,gBAAA;AACrB,cAAM,SAAS,OAAO,IAAI;AAC1B,cAAM,UAAU,MAAM,SAAS,OAAA;AAG/B,cAAM,aAAa,YAAY,IAAI,KAAK,UAAU;AAClD,YAAI,eAAe,UAAa,eAAe,SAAS;AACtD,oBAAU,KAAK,aAAa,CAAC,IAAI;AACjC,kBAAQ,SAAS,KAAK,UAAU;AAChC,kBAAQ,aAAA;AACR;AAAA,QACF;AAEA,YAAI,cAAc,YAAY,sBAAsB,WAAW;AAC/D,YAAI,CAAC,aAAa;AAChB,gBAAM,OAAO,MAAM,IAAI;AAAA,YACrB,YAAY,UAAA;AAAA,YACZ,YAAY,aAAA;AAAA,YACZ,EAAE,QAAQ,YAAA;AAAA,UAAY;AAExB,wBAAc,EAAE,WAAW,KAAK,WAAW,oBAAoB,KAAK,mBAAA;AAAA,QACtE;AAEA,YAAI;AACF,gBAAMA,UAAS,MAAM,IAAI;AAAA,YACvB,YAAY;AAAA,YACZ;AAAA,cACE,eAAe,YAAY;AAAA,cAC3B,YAAY,KAAK;AAAA,cACjB,eAAe,KAAK;AAAA,cACpB,aAAa;AAAA,cACb,GAAI,QAAQ,yBAAyB,SACjC,EAAE,sBAAsB,QAAQ,yBAChC,CAAA;AAAA,YAAC;AAAA,YAEP;AAAA,YACA,QAAQ;AAAA,UAAA;AAGV,sBAAY,oBAAoB,aAAa,WAAW;AACxD,oBAAU,KAAK,aAAa,CAAC,IAAIA,QAAO;AACxC,kBAAQ,SAAS,KAAK,UAAU;AAChC,kBAAQ,aAAA;AAAA,QACV,SAAS,KAAK;AACZ,sBAAY,mBAAmB,aAAa,WAAW;AACvD,gBAAM;AAAA,QACR;AAAA,MACF,UAAA;AACE,YAAI,QAAA;AAAA,MACN;AAAA,IACF,CAAC;AAED,UAAM,QAAQ,IAAI,KAAK;AAEvB,UAAM,SAAS,MAAM,IAAI,gBAAgB,YAAY,UAAA,GAAa,YAAY,gBAAgB;AAAA,MAC5F,QAAQ;AAAA,MACR,eAAe;AAAA,IAAA,CAChB;AAED,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,UAAM,0BAA0B,KAAK,aAAa,WAAW;AAC7D,UAAM;AAAA,EACR;AACF;AAuBA,eAAe,wBACb,KACA,aACA,SACA,aACA,OACA,WACA,SACe;AACf,QAAM,SAAS,QAAQ,OAAO,OAAA,EAAS,UAAA;AACvC,MAAI,aAAa;AAIjB,MAAI,QAA2B;AAE/B,MAAI;AACF,eAAW,WAAW,OAAO;AAC3B,cAAQ,QAAQ,eAAA;AAEhB,YAAM,MAAM,IAAI,WAAW,QAAQ,MAAM;AACzC,UAAI,SAAS;AAEb,UAAI,UAAU,MAAM;AAClB,cAAM,OAAO,KAAK,IAAI,MAAM,YAAY,IAAI,aAAa,MAAM;AAC/D,YAAI,IAAI,MAAM,SAAS,GAAG,IAAI,GAAG,MAAM;AACvC,kBAAU;AACV,gBAAQ,OAAO,MAAM,aAAa,MAAM,SAAS,IAAI,IAAI;AAAA,MAC3D;AAEA,aAAO,SAAS,IAAI,YAAY;AAC9B,cAAM,EAAE,MAAM,MAAA,IAAU,MAAM,OAAO,KAAA;AACrC,YAAI,KAAM;AACV,cAAM,OAAO,KAAK,IAAI,MAAM,YAAY,IAAI,aAAa,MAAM;AAC/D,YAAI,IAAI,MAAM,SAAS,GAAG,IAAI,GAAG,MAAM;AACvC,kBAAU;AACV,YAAI,OAAO,MAAM,YAAY;AAC3B,kBAAQ,MAAM,SAAS,IAAI;AAAA,QAC7B;AAAA,MACF;AAIA,YAAM,OAAO,WAAW,IAAI,aAAa,MAAM,IAAI,SAAS,GAAG,MAAM;AAMrE,UAAI,KAAK,eAAe,GAAG;AACzB,cAAM,IAAI;AAAA,UACR,oDAAoD,UAAU;AAAA,QAAA;AAAA,MAElE;AAGA,YAAM,WAAW,IAAI,gBAAA;AACrB,YAAM,SAAS,OAAO,IAAI;AAC1B,YAAM,UAAU,MAAM,SAAS,OAAA;AAE/B,UAAI,cAAc,YAAY,sBAAsB,WAAW;AAC/D,UAAI,CAAC,aAAa;AAChB,cAAM,OAAO,MAAM,IAAI;AAAA,UACrB,YAAY,UAAA;AAAA,UACZ,YAAY,aAAA;AAAA,UACZ,EAAE,QAAQ,YAAA;AAAA,QAAY;AAExB,sBAAc,EAAE,WAAW,KAAK,WAAW,oBAAoB,KAAK,mBAAA;AAAA,MACtE;AAEA,UAAI;AACF,cAAM,SAAS,MAAM,IAAI;AAAA,UACvB,YAAY;AAAA,UACZ;AAAA,YACE,eAAe,YAAY;AAAA,YAC3B,YAAY,QAAQ;AAAA,YACpB,eAAe,KAAK;AAAA,YACpB,aAAa;AAAA,YACb,GAAI,QAAQ,yBAAyB,SACjC,EAAE,sBAAsB,QAAQ,yBAChC,CAAA;AAAA,UAAC;AAAA,UAEP;AAAA,UACA,QAAQ;AAAA,QAAA;AAGV,oBAAY,oBAAoB,aAAa,WAAW;AACxD,kBAAU,QAAQ,aAAa,CAAC,IAAI,OAAO;AAC3C,gBAAQ,SAAS,KAAK,UAAU;AAChC,gBAAQ,aAAA;AAAA,MACV,SAAS,KAAK;AACZ,oBAAY,mBAAmB,aAAa,WAAW;AACvD,cAAM;AAAA,MACR;AAEA;AAAA,IACF;AAAA,EACF,UAAA;AAGE,WAAO,YAAA;AAAA,EACT;AACF;"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const ids = require("../types/ids.cjs");
4
+ async function findResumeCandidate(raw, accountInfo, bucketId, fileName) {
5
+ const unfinished = await raw.listUnfinishedLargeFiles(
6
+ accountInfo.getApiUrl(),
7
+ accountInfo.getAuthToken(),
8
+ { bucketId }
9
+ );
10
+ const match = unfinished.files.find((f) => f.fileName === fileName);
11
+ if (!match) return null;
12
+ const fileId = ids.largeFileId(match.fileId);
13
+ const uploadedPartSha1s = await collectPartSha1s(raw, accountInfo, fileId);
14
+ return { fileId, uploadedPartSha1s };
15
+ }
16
+ async function collectPartSha1s(raw, accountInfo, fileId) {
17
+ const sha1s = /* @__PURE__ */ new Map();
18
+ let startPartNumber;
19
+ while (true) {
20
+ const page = await raw.listParts(accountInfo.getApiUrl(), accountInfo.getAuthToken(), {
21
+ fileId,
22
+ ...startPartNumber !== void 0 ? { startPartNumber } : {}
23
+ });
24
+ for (const part of page.parts) {
25
+ sha1s.set(part.partNumber, part.contentSha1);
26
+ }
27
+ if (page.nextPartNumber === null) break;
28
+ startPartNumber = page.nextPartNumber;
29
+ }
30
+ return sha1s;
31
+ }
32
+ exports.collectPartSha1s = collectPartSha1s;
33
+ exports.findResumeCandidate = findResumeCandidate;
34
+ //# sourceMappingURL=resume.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resume.cjs","sources":["../../src/upload/resume.ts"],"sourcesContent":["import type { AccountInfo } from '../auth/account-info.ts'\nimport type { RawClient } from '../raw/index.ts'\nimport type { BucketId, LargeFileId } from '../types/ids.ts'\nimport { largeFileId as largeFileIdOf } from '../types/ids.ts'\n\n/** Information about an unfinished large file eligible for resume. */\nexport interface ResumeCandidate {\n /** ID of the unfinished large file. */\n readonly fileId: LargeFileId\n /** SHA-1 of each part already uploaded, indexed by 1-based part number. */\n readonly uploadedPartSha1s: ReadonlyMap<number, string>\n}\n\n/**\n * Finds an unfinished large file matching the given bucket and file name.\n * Returns `null` when no matching candidate exists.\n *\n * @param raw - Low-level B2 API client.\n * @param accountInfo - Authorized account state.\n * @param bucketId - Target bucket of the upload.\n * @param fileName - Destination file name of the upload.\n *\n * @returns A {@link ResumeCandidate} describing the candidate and its uploaded parts, or `null`.\n */\nexport async function findResumeCandidate(\n raw: RawClient,\n accountInfo: AccountInfo,\n bucketId: BucketId,\n fileName: string,\n): Promise<ResumeCandidate | null> {\n const unfinished = await raw.listUnfinishedLargeFiles(\n accountInfo.getApiUrl(),\n accountInfo.getAuthToken(),\n { bucketId },\n )\n\n const match = unfinished.files.find((f) => f.fileName === fileName)\n if (!match) return null\n\n const fileId = largeFileIdOf(match.fileId)\n const uploadedPartSha1s = await collectPartSha1s(raw, accountInfo, fileId)\n\n return { fileId, uploadedPartSha1s }\n}\n\n/**\n * Lists all uploaded parts for a large file, paginating until exhausted.\n *\n * @param raw - Low-level B2 API client.\n * @param accountInfo - Authorized account state.\n * @param fileId - ID of the large file to inspect.\n *\n * @returns A map from 1-based part number to its server-stored SHA-1.\n */\nexport async function collectPartSha1s(\n raw: RawClient,\n accountInfo: AccountInfo,\n fileId: LargeFileId,\n): Promise<Map<number, string>> {\n const sha1s = new Map<number, string>()\n let startPartNumber: number | undefined\n\n while (true) {\n const page = await raw.listParts(accountInfo.getApiUrl(), accountInfo.getAuthToken(), {\n fileId,\n ...(startPartNumber !== undefined ? { startPartNumber } : {}),\n })\n for (const part of page.parts) {\n sha1s.set(part.partNumber, part.contentSha1)\n }\n if (page.nextPartNumber === null) break\n startPartNumber = page.nextPartNumber\n }\n\n return sha1s\n}\n"],"names":["largeFileIdOf"],"mappings":";;;AAwBA,eAAsB,oBACpB,KACA,aACA,UACA,UACiC;AACjC,QAAM,aAAa,MAAM,IAAI;AAAA,IAC3B,YAAY,UAAA;AAAA,IACZ,YAAY,aAAA;AAAA,IACZ,EAAE,SAAA;AAAA,EAAS;AAGb,QAAM,QAAQ,WAAW,MAAM,KAAK,CAAC,MAAM,EAAE,aAAa,QAAQ;AAClE,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,SAASA,IAAAA,YAAc,MAAM,MAAM;AACzC,QAAM,oBAAoB,MAAM,iBAAiB,KAAK,aAAa,MAAM;AAEzE,SAAO,EAAE,QAAQ,kBAAA;AACnB;AAWA,eAAsB,iBACpB,KACA,aACA,QAC8B;AAC9B,QAAM,4BAAY,IAAA;AAClB,MAAI;AAEJ,SAAO,MAAM;AACX,UAAM,OAAO,MAAM,IAAI,UAAU,YAAY,UAAA,GAAa,YAAY,gBAAgB;AAAA,MACpF;AAAA,MACA,GAAI,oBAAoB,SAAY,EAAE,oBAAoB,CAAA;AAAA,IAAC,CAC5D;AACD,eAAW,QAAQ,KAAK,OAAO;AAC7B,YAAM,IAAI,KAAK,YAAY,KAAK,WAAW;AAAA,IAC7C;AACA,QAAI,KAAK,mBAAmB,KAAM;AAClC,sBAAkB,KAAK;AAAA,EACzB;AAEA,SAAO;AACT;;;"}
@@ -0,0 +1,33 @@
1
+ import { AccountInfo } from '../auth/account-info.js';
2
+ import { RawClient } from '../raw/index.js';
3
+ import { BucketId, LargeFileId } from '../types/ids.js';
4
+ /** Information about an unfinished large file eligible for resume. */
5
+ export interface ResumeCandidate {
6
+ /** ID of the unfinished large file. */
7
+ readonly fileId: LargeFileId;
8
+ /** SHA-1 of each part already uploaded, indexed by 1-based part number. */
9
+ readonly uploadedPartSha1s: ReadonlyMap<number, string>;
10
+ }
11
+ /**
12
+ * Finds an unfinished large file matching the given bucket and file name.
13
+ * Returns `null` when no matching candidate exists.
14
+ *
15
+ * @param raw - Low-level B2 API client.
16
+ * @param accountInfo - Authorized account state.
17
+ * @param bucketId - Target bucket of the upload.
18
+ * @param fileName - Destination file name of the upload.
19
+ *
20
+ * @returns A {@link ResumeCandidate} describing the candidate and its uploaded parts, or `null`.
21
+ */
22
+ export declare function findResumeCandidate(raw: RawClient, accountInfo: AccountInfo, bucketId: BucketId, fileName: string): Promise<ResumeCandidate | null>;
23
+ /**
24
+ * Lists all uploaded parts for a large file, paginating until exhausted.
25
+ *
26
+ * @param raw - Low-level B2 API client.
27
+ * @param accountInfo - Authorized account state.
28
+ * @param fileId - ID of the large file to inspect.
29
+ *
30
+ * @returns A map from 1-based part number to its server-stored SHA-1.
31
+ */
32
+ export declare function collectPartSha1s(raw: RawClient, accountInfo: AccountInfo, fileId: LargeFileId): Promise<Map<number, string>>;
33
+ //# sourceMappingURL=resume.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resume.d.ts","sourceRoot":"","sources":["../../src/upload/resume.js"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAG5D,sEAAsE;AACtE,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,2EAA2E;IAC3E,QAAQ,CAAC,iBAAiB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACxD;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,SAAS,EACd,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAcjC;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,SAAS,EACd,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAiB9B"}
@@ -0,0 +1,33 @@
1
+ import { AccountInfo } from '../auth/account-info.js';
2
+ import { RawClient } from '../raw/index.js';
3
+ import { BucketId, LargeFileId } from '../types/ids.js';
4
+ /** Information about an unfinished large file eligible for resume. */
5
+ export interface ResumeCandidate {
6
+ /** ID of the unfinished large file. */
7
+ readonly fileId: LargeFileId;
8
+ /** SHA-1 of each part already uploaded, indexed by 1-based part number. */
9
+ readonly uploadedPartSha1s: ReadonlyMap<number, string>;
10
+ }
11
+ /**
12
+ * Finds an unfinished large file matching the given bucket and file name.
13
+ * Returns `null` when no matching candidate exists.
14
+ *
15
+ * @param raw - Low-level B2 API client.
16
+ * @param accountInfo - Authorized account state.
17
+ * @param bucketId - Target bucket of the upload.
18
+ * @param fileName - Destination file name of the upload.
19
+ *
20
+ * @returns A {@link ResumeCandidate} describing the candidate and its uploaded parts, or `null`.
21
+ */
22
+ export declare function findResumeCandidate(raw: RawClient, accountInfo: AccountInfo, bucketId: BucketId, fileName: string): Promise<ResumeCandidate | null>;
23
+ /**
24
+ * Lists all uploaded parts for a large file, paginating until exhausted.
25
+ *
26
+ * @param raw - Low-level B2 API client.
27
+ * @param accountInfo - Authorized account state.
28
+ * @param fileId - ID of the large file to inspect.
29
+ *
30
+ * @returns A map from 1-based part number to its server-stored SHA-1.
31
+ */
32
+ export declare function collectPartSha1s(raw: RawClient, accountInfo: AccountInfo, fileId: LargeFileId): Promise<Map<number, string>>;
33
+ //# sourceMappingURL=resume.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resume.d.ts","sourceRoot":"","sources":["../../src/upload/resume.js"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAG5D,sEAAsE;AACtE,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,2EAA2E;IAC3E,QAAQ,CAAC,iBAAiB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACxD;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,SAAS,EACd,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAcjC;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,SAAS,EACd,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAiB9B"}
@@ -0,0 +1,34 @@
1
+ import { largeFileId } from "../types/ids.js";
2
+ async function findResumeCandidate(raw, accountInfo, bucketId, fileName) {
3
+ const unfinished = await raw.listUnfinishedLargeFiles(
4
+ accountInfo.getApiUrl(),
5
+ accountInfo.getAuthToken(),
6
+ { bucketId }
7
+ );
8
+ const match = unfinished.files.find((f) => f.fileName === fileName);
9
+ if (!match) return null;
10
+ const fileId = largeFileId(match.fileId);
11
+ const uploadedPartSha1s = await collectPartSha1s(raw, accountInfo, fileId);
12
+ return { fileId, uploadedPartSha1s };
13
+ }
14
+ async function collectPartSha1s(raw, accountInfo, fileId) {
15
+ const sha1s = /* @__PURE__ */ new Map();
16
+ let startPartNumber;
17
+ while (true) {
18
+ const page = await raw.listParts(accountInfo.getApiUrl(), accountInfo.getAuthToken(), {
19
+ fileId,
20
+ ...startPartNumber !== void 0 ? { startPartNumber } : {}
21
+ });
22
+ for (const part of page.parts) {
23
+ sha1s.set(part.partNumber, part.contentSha1);
24
+ }
25
+ if (page.nextPartNumber === null) break;
26
+ startPartNumber = page.nextPartNumber;
27
+ }
28
+ return sha1s;
29
+ }
30
+ export {
31
+ collectPartSha1s,
32
+ findResumeCandidate
33
+ };
34
+ //# sourceMappingURL=resume.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resume.js","sources":["../../src/upload/resume.ts"],"sourcesContent":["import type { AccountInfo } from '../auth/account-info.ts'\nimport type { RawClient } from '../raw/index.ts'\nimport type { BucketId, LargeFileId } from '../types/ids.ts'\nimport { largeFileId as largeFileIdOf } from '../types/ids.ts'\n\n/** Information about an unfinished large file eligible for resume. */\nexport interface ResumeCandidate {\n /** ID of the unfinished large file. */\n readonly fileId: LargeFileId\n /** SHA-1 of each part already uploaded, indexed by 1-based part number. */\n readonly uploadedPartSha1s: ReadonlyMap<number, string>\n}\n\n/**\n * Finds an unfinished large file matching the given bucket and file name.\n * Returns `null` when no matching candidate exists.\n *\n * @param raw - Low-level B2 API client.\n * @param accountInfo - Authorized account state.\n * @param bucketId - Target bucket of the upload.\n * @param fileName - Destination file name of the upload.\n *\n * @returns A {@link ResumeCandidate} describing the candidate and its uploaded parts, or `null`.\n */\nexport async function findResumeCandidate(\n raw: RawClient,\n accountInfo: AccountInfo,\n bucketId: BucketId,\n fileName: string,\n): Promise<ResumeCandidate | null> {\n const unfinished = await raw.listUnfinishedLargeFiles(\n accountInfo.getApiUrl(),\n accountInfo.getAuthToken(),\n { bucketId },\n )\n\n const match = unfinished.files.find((f) => f.fileName === fileName)\n if (!match) return null\n\n const fileId = largeFileIdOf(match.fileId)\n const uploadedPartSha1s = await collectPartSha1s(raw, accountInfo, fileId)\n\n return { fileId, uploadedPartSha1s }\n}\n\n/**\n * Lists all uploaded parts for a large file, paginating until exhausted.\n *\n * @param raw - Low-level B2 API client.\n * @param accountInfo - Authorized account state.\n * @param fileId - ID of the large file to inspect.\n *\n * @returns A map from 1-based part number to its server-stored SHA-1.\n */\nexport async function collectPartSha1s(\n raw: RawClient,\n accountInfo: AccountInfo,\n fileId: LargeFileId,\n): Promise<Map<number, string>> {\n const sha1s = new Map<number, string>()\n let startPartNumber: number | undefined\n\n while (true) {\n const page = await raw.listParts(accountInfo.getApiUrl(), accountInfo.getAuthToken(), {\n fileId,\n ...(startPartNumber !== undefined ? { startPartNumber } : {}),\n })\n for (const part of page.parts) {\n sha1s.set(part.partNumber, part.contentSha1)\n }\n if (page.nextPartNumber === null) break\n startPartNumber = page.nextPartNumber\n }\n\n return sha1s\n}\n"],"names":["largeFileIdOf"],"mappings":";AAwBA,eAAsB,oBACpB,KACA,aACA,UACA,UACiC;AACjC,QAAM,aAAa,MAAM,IAAI;AAAA,IAC3B,YAAY,UAAA;AAAA,IACZ,YAAY,aAAA;AAAA,IACZ,EAAE,SAAA;AAAA,EAAS;AAGb,QAAM,QAAQ,WAAW,MAAM,KAAK,CAAC,MAAM,EAAE,aAAa,QAAQ;AAClE,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,SAASA,YAAc,MAAM,MAAM;AACzC,QAAM,oBAAoB,MAAM,iBAAiB,KAAK,aAAa,MAAM;AAEzE,SAAO,EAAE,QAAQ,kBAAA;AACnB;AAWA,eAAsB,iBACpB,KACA,aACA,QAC8B;AAC9B,QAAM,4BAAY,IAAA;AAClB,MAAI;AAEJ,SAAO,MAAM;AACX,UAAM,OAAO,MAAM,IAAI,UAAU,YAAY,UAAA,GAAa,YAAY,gBAAgB;AAAA,MACpF;AAAA,MACA,GAAI,oBAAoB,SAAY,EAAE,oBAAoB,CAAA;AAAA,IAAC,CAC5D;AACD,eAAW,QAAQ,KAAK,OAAO;AAC7B,YAAM,IAAI,KAAK,YAAY,KAAK,WAAW;AAAA,IAC7C;AACA,QAAI,KAAK,mBAAmB,KAAM;AAClC,sBAAkB,KAAK;AAAA,EACzB;AAEA,SAAO;AACT;"}
@@ -0,0 +1,47 @@
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");
6
+ 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
+ }
45
+ }
46
+ exports.uploadSmallFile = uploadSmallFile;
47
+ //# sourceMappingURL=single.cjs.map
@@ -0,0 +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;;"}
@@ -0,0 +1,51 @@
1
+ import { AccountInfo } from '../auth/account-info.js';
2
+ import { RawClient } from '../raw/index.js';
3
+ import { ProgressListener } from '../streams/progress.js';
4
+ import { ContentSource } from '../streams/source.js';
5
+ import { EncryptionSetting } from '../types/encryption.js';
6
+ import { FileVersion } from '../types/file.js';
7
+ import { BucketId } from '../types/ids.js';
8
+ import { FileRetentionValue, LegalHoldValue } from '../types/lock.js';
9
+ /** Options for uploading a small file in a single HTTP request. */
10
+ export interface UploadFileOptions {
11
+ /** Target bucket for the upload. */
12
+ readonly bucketId: BucketId;
13
+ /** Full B2 file name including any path prefix. */
14
+ readonly fileName: string;
15
+ /** Content to upload. */
16
+ readonly source: ContentSource;
17
+ /** MIME type. Defaults to `b2/x-auto` for server-side detection. */
18
+ readonly contentType?: string;
19
+ /** Custom file info key/value pairs stored with the file. */
20
+ readonly fileInfo?: Record<string, string>;
21
+ /** Server-side encryption settings. */
22
+ readonly serverSideEncryption?: EncryptionSetting;
23
+ /** File retention policy applied at upload time. */
24
+ readonly fileRetention?: FileRetentionValue;
25
+ /** Legal hold status applied at upload time. */
26
+ readonly legalHold?: LegalHoldValue;
27
+ /** Override the last-modified timestamp (epoch millis). */
28
+ readonly lastModifiedMillis?: number;
29
+ /** Callback invoked with upload progress updates. */
30
+ readonly onProgress?: ProgressListener;
31
+ /** Signal to abort the upload. */
32
+ readonly signal?: AbortSignal;
33
+ }
34
+ /**
35
+ * Uploads a file in a single HTTP request (suitable for files up to ~100 MB).
36
+ *
37
+ * The entire file content is read into memory, SHA-1 hashed, and sent in one
38
+ * `b2_upload_file` call. For files larger than the recommended part size, use
39
+ * {@link uploadLargeFile} which splits the file into parts uploaded in parallel.
40
+ *
41
+ * Upload URLs are pooled via {@link AccountInfo} and recycled on success or
42
+ * evicted on failure.
43
+ *
44
+ * @param raw - Low-level B2 API client.
45
+ * @param accountInfo - Authorized account state (tokens, URLs, upload URL pool).
46
+ * @param options - Upload parameters.
47
+ *
48
+ * @returns The resulting {@link FileVersion} metadata.
49
+ */
50
+ export declare function uploadSmallFile(raw: RawClient, accountInfo: AccountInfo, options: UploadFileOptions): Promise<FileVersion>;
51
+ //# sourceMappingURL=single.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,51 @@
1
+ import { AccountInfo } from '../auth/account-info.js';
2
+ import { RawClient } from '../raw/index.js';
3
+ import { ProgressListener } from '../streams/progress.js';
4
+ import { ContentSource } from '../streams/source.js';
5
+ import { EncryptionSetting } from '../types/encryption.js';
6
+ import { FileVersion } from '../types/file.js';
7
+ import { BucketId } from '../types/ids.js';
8
+ import { FileRetentionValue, LegalHoldValue } from '../types/lock.js';
9
+ /** Options for uploading a small file in a single HTTP request. */
10
+ export interface UploadFileOptions {
11
+ /** Target bucket for the upload. */
12
+ readonly bucketId: BucketId;
13
+ /** Full B2 file name including any path prefix. */
14
+ readonly fileName: string;
15
+ /** Content to upload. */
16
+ readonly source: ContentSource;
17
+ /** MIME type. Defaults to `b2/x-auto` for server-side detection. */
18
+ readonly contentType?: string;
19
+ /** Custom file info key/value pairs stored with the file. */
20
+ readonly fileInfo?: Record<string, string>;
21
+ /** Server-side encryption settings. */
22
+ readonly serverSideEncryption?: EncryptionSetting;
23
+ /** File retention policy applied at upload time. */
24
+ readonly fileRetention?: FileRetentionValue;
25
+ /** Legal hold status applied at upload time. */
26
+ readonly legalHold?: LegalHoldValue;
27
+ /** Override the last-modified timestamp (epoch millis). */
28
+ readonly lastModifiedMillis?: number;
29
+ /** Callback invoked with upload progress updates. */
30
+ readonly onProgress?: ProgressListener;
31
+ /** Signal to abort the upload. */
32
+ readonly signal?: AbortSignal;
33
+ }
34
+ /**
35
+ * Uploads a file in a single HTTP request (suitable for files up to ~100 MB).
36
+ *
37
+ * The entire file content is read into memory, SHA-1 hashed, and sent in one
38
+ * `b2_upload_file` call. For files larger than the recommended part size, use
39
+ * {@link uploadLargeFile} which splits the file into parts uploaded in parallel.
40
+ *
41
+ * Upload URLs are pooled via {@link AccountInfo} and recycled on success or
42
+ * evicted on failure.
43
+ *
44
+ * @param raw - Low-level B2 API client.
45
+ * @param accountInfo - Authorized account state (tokens, URLs, upload URL pool).
46
+ * @param options - Upload parameters.
47
+ *
48
+ * @returns The resulting {@link FileVersion} metadata.
49
+ */
50
+ export declare function uploadSmallFile(raw: RawClient, accountInfo: AccountInfo, options: UploadFileOptions): Promise<FileVersion>;
51
+ //# sourceMappingURL=single.d.ts.map
@@ -0,0 +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"}