@backblaze-labs/b2-sdk 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (393) hide show
  1. package/CHANGELOG.md +45 -1
  2. package/README.md +18 -5
  3. package/dist/_virtual/_b2-sdk-version-json.cjs +1 -1
  4. package/dist/_virtual/_b2-sdk-version-json.js +1 -1
  5. package/dist/auth/reauth-coalescer.cjs +65 -0
  6. package/dist/auth/reauth-coalescer.cjs.map +1 -0
  7. package/dist/auth/reauth-coalescer.d.cts +34 -0
  8. package/dist/auth/reauth-coalescer.d.cts.map +1 -0
  9. package/dist/auth/reauth-coalescer.d.ts +34 -0
  10. package/dist/auth/reauth-coalescer.d.ts.map +1 -0
  11. package/dist/auth/reauth-coalescer.js +65 -0
  12. package/dist/auth/reauth-coalescer.js.map +1 -0
  13. package/dist/backup/raw.cjs +37 -15
  14. package/dist/backup/raw.cjs.map +1 -1
  15. package/dist/backup/raw.d.cts +2 -2
  16. package/dist/backup/raw.d.cts.map +1 -1
  17. package/dist/backup/raw.d.ts +2 -2
  18. package/dist/backup/raw.d.ts.map +1 -1
  19. package/dist/backup/raw.js +37 -15
  20. package/dist/backup/raw.js.map +1 -1
  21. package/dist/bucket-validation.cjs +111 -0
  22. package/dist/bucket-validation.cjs.map +1 -0
  23. package/dist/bucket-validation.d.cts +27 -0
  24. package/dist/bucket-validation.d.cts.map +1 -0
  25. package/dist/bucket-validation.d.ts +27 -0
  26. package/dist/bucket-validation.d.ts.map +1 -0
  27. package/dist/bucket-validation.js +109 -0
  28. package/dist/bucket-validation.js.map +1 -0
  29. package/dist/bucket.cjs +123 -73
  30. package/dist/bucket.cjs.map +1 -1
  31. package/dist/bucket.d.cts +156 -61
  32. package/dist/bucket.d.cts.map +1 -1
  33. package/dist/bucket.d.ts +156 -61
  34. package/dist/bucket.d.ts.map +1 -1
  35. package/dist/bucket.js +123 -73
  36. package/dist/bucket.js.map +1 -1
  37. package/dist/client.cjs +29 -8
  38. package/dist/client.cjs.map +1 -1
  39. package/dist/client.d.cts +30 -9
  40. package/dist/client.d.cts.map +1 -1
  41. package/dist/client.d.ts +30 -9
  42. package/dist/client.d.ts.map +1 -1
  43. package/dist/client.js +29 -8
  44. package/dist/client.js.map +1 -1
  45. package/dist/download/single.cjs +38 -13
  46. package/dist/download/single.cjs.map +1 -1
  47. package/dist/download/single.d.cts +10 -4
  48. package/dist/download/single.d.cts.map +1 -1
  49. package/dist/download/single.d.ts +10 -4
  50. package/dist/download/single.d.ts.map +1 -1
  51. package/dist/download/single.js +38 -13
  52. package/dist/download/single.js.map +1 -1
  53. package/dist/errors/index.cjs +27 -4
  54. package/dist/errors/index.cjs.map +1 -1
  55. package/dist/errors/index.d.cts +15 -0
  56. package/dist/errors/index.d.cts.map +1 -1
  57. package/dist/errors/index.d.ts +15 -0
  58. package/dist/errors/index.d.ts.map +1 -1
  59. package/dist/errors/index.js +27 -5
  60. package/dist/errors/index.js.map +1 -1
  61. package/dist/http/non-idempotent-mutations.cjs +38 -0
  62. package/dist/http/non-idempotent-mutations.cjs.map +1 -0
  63. package/dist/http/non-idempotent-mutations.d.cts +25 -0
  64. package/dist/http/non-idempotent-mutations.d.cts.map +1 -0
  65. package/dist/http/non-idempotent-mutations.d.ts +25 -0
  66. package/dist/http/non-idempotent-mutations.d.ts.map +1 -0
  67. package/dist/http/non-idempotent-mutations.js +35 -0
  68. package/dist/http/non-idempotent-mutations.js.map +1 -0
  69. package/dist/http/transport.cjs +9 -8
  70. package/dist/http/transport.cjs.map +1 -1
  71. package/dist/http/transport.d.cts +5 -0
  72. package/dist/http/transport.d.cts.map +1 -1
  73. package/dist/http/transport.d.ts +5 -0
  74. package/dist/http/transport.d.ts.map +1 -1
  75. package/dist/http/transport.js +9 -8
  76. package/dist/http/transport.js.map +1 -1
  77. package/dist/http/user-agent.cjs +12 -1
  78. package/dist/http/user-agent.cjs.map +1 -1
  79. package/dist/http/user-agent.d.cts +8 -0
  80. package/dist/http/user-agent.d.cts.map +1 -1
  81. package/dist/http/user-agent.d.ts +8 -0
  82. package/dist/http/user-agent.d.ts.map +1 -1
  83. package/dist/http/user-agent.js +13 -3
  84. package/dist/http/user-agent.js.map +1 -1
  85. package/dist/index.cjs +25 -0
  86. package/dist/index.d.cts +10 -9
  87. package/dist/index.d.cts.map +1 -1
  88. package/dist/index.d.ts +10 -9
  89. package/dist/index.d.ts.map +1 -1
  90. package/dist/index.js +7 -6
  91. package/dist/notifications/index.cjs +3 -0
  92. package/dist/notifications/index.d.cts +2 -0
  93. package/dist/notifications/index.d.cts.map +1 -1
  94. package/dist/notifications/index.d.ts +2 -0
  95. package/dist/notifications/index.d.ts.map +1 -1
  96. package/dist/notifications/index.js +2 -1
  97. package/dist/object.cjs +12 -1
  98. package/dist/object.cjs.map +1 -1
  99. package/dist/object.d.cts +7 -1
  100. package/dist/object.d.cts.map +1 -1
  101. package/dist/object.d.ts +7 -1
  102. package/dist/object.d.ts.map +1 -1
  103. package/dist/object.js +12 -1
  104. package/dist/object.js.map +1 -1
  105. package/dist/partner/auth-core.cjs +4 -23
  106. package/dist/partner/auth-core.cjs.map +1 -1
  107. package/dist/partner/auth-core.d.cts +1 -1
  108. package/dist/partner/auth-core.d.cts.map +1 -1
  109. package/dist/partner/auth-core.d.ts +1 -1
  110. package/dist/partner/auth-core.d.ts.map +1 -1
  111. package/dist/partner/auth-core.js +5 -24
  112. package/dist/partner/auth-core.js.map +1 -1
  113. package/dist/partner/client.cjs +25 -10
  114. package/dist/partner/client.cjs.map +1 -1
  115. package/dist/partner/client.d.cts +32 -10
  116. package/dist/partner/client.d.cts.map +1 -1
  117. package/dist/partner/client.d.ts +32 -10
  118. package/dist/partner/client.d.ts.map +1 -1
  119. package/dist/partner/client.js +25 -10
  120. package/dist/partner/client.js.map +1 -1
  121. package/dist/partner/endpoint-url.cjs +1 -0
  122. package/dist/partner/endpoint-url.cjs.map +1 -1
  123. package/dist/partner/endpoint-url.d.cts +2 -0
  124. package/dist/partner/endpoint-url.d.cts.map +1 -1
  125. package/dist/partner/endpoint-url.d.ts +2 -0
  126. package/dist/partner/endpoint-url.d.ts.map +1 -1
  127. package/dist/partner/endpoint-url.js +1 -0
  128. package/dist/partner/endpoint-url.js.map +1 -1
  129. package/dist/partner/in-memory.cjs.map +1 -1
  130. package/dist/partner/in-memory.js.map +1 -1
  131. package/dist/partner/index.cjs +9 -0
  132. package/dist/partner/index.d.cts +11 -2
  133. package/dist/partner/index.d.cts.map +1 -1
  134. package/dist/partner/index.d.ts +11 -2
  135. package/dist/partner/index.d.ts.map +1 -1
  136. package/dist/partner/index.js +3 -1
  137. package/dist/partner/raw.cjs +52 -44
  138. package/dist/partner/raw.cjs.map +1 -1
  139. package/dist/partner/raw.d.cts +16 -19
  140. package/dist/partner/raw.d.cts.map +1 -1
  141. package/dist/partner/raw.d.ts +16 -19
  142. package/dist/partner/raw.d.ts.map +1 -1
  143. package/dist/partner/raw.js +52 -44
  144. package/dist/partner/raw.js.map +1 -1
  145. package/dist/partner/redaction.cjs +133 -108
  146. package/dist/partner/redaction.cjs.map +1 -1
  147. package/dist/partner/redaction.d.cts +47 -13
  148. package/dist/partner/redaction.d.cts.map +1 -1
  149. package/dist/partner/redaction.d.ts +47 -13
  150. package/dist/partner/redaction.d.ts.map +1 -1
  151. package/dist/partner/redaction.js +133 -109
  152. package/dist/partner/redaction.js.map +1 -1
  153. package/dist/raw/encoding.cjs +29 -10
  154. package/dist/raw/encoding.cjs.map +1 -1
  155. package/dist/raw/encoding.d.cts +3 -2
  156. package/dist/raw/encoding.d.cts.map +1 -1
  157. package/dist/raw/encoding.d.ts +3 -2
  158. package/dist/raw/encoding.d.ts.map +1 -1
  159. package/dist/raw/encoding.js +29 -10
  160. package/dist/raw/encoding.js.map +1 -1
  161. package/dist/raw/index.cjs +64 -39
  162. package/dist/raw/index.cjs.map +1 -1
  163. package/dist/raw/index.d.cts +21 -19
  164. package/dist/raw/index.d.cts.map +1 -1
  165. package/dist/raw/index.d.ts +21 -19
  166. package/dist/raw/index.d.ts.map +1 -1
  167. package/dist/raw/index.js +47 -40
  168. package/dist/raw/index.js.map +1 -1
  169. package/dist/raw/url.cjs.map +1 -1
  170. package/dist/raw/url.d.cts +3 -3
  171. package/dist/raw/url.d.ts +3 -3
  172. package/dist/raw/url.js.map +1 -1
  173. package/dist/simulator/index.cjs +456 -125
  174. package/dist/simulator/index.cjs.map +1 -1
  175. package/dist/simulator/index.d.cts +16 -1
  176. package/dist/simulator/index.d.cts.map +1 -1
  177. package/dist/simulator/index.d.ts +16 -1
  178. package/dist/simulator/index.d.ts.map +1 -1
  179. package/dist/simulator/index.js +449 -130
  180. package/dist/simulator/index.js.map +1 -1
  181. package/dist/simulator/partner-capabilities.cjs +77 -0
  182. package/dist/simulator/partner-capabilities.cjs.map +1 -0
  183. package/dist/simulator/partner-capabilities.d.cts +53 -0
  184. package/dist/simulator/partner-capabilities.d.cts.map +1 -0
  185. package/dist/simulator/partner-capabilities.d.ts +53 -0
  186. package/dist/simulator/partner-capabilities.d.ts.map +1 -0
  187. package/dist/simulator/partner-capabilities.js +73 -0
  188. package/dist/simulator/partner-capabilities.js.map +1 -0
  189. package/dist/simulator/partner.cjs +55 -61
  190. package/dist/simulator/partner.cjs.map +1 -1
  191. package/dist/simulator/partner.d.cts +5 -2
  192. package/dist/simulator/partner.d.cts.map +1 -1
  193. package/dist/simulator/partner.d.ts +5 -2
  194. package/dist/simulator/partner.d.ts.map +1 -1
  195. package/dist/simulator/partner.js +56 -61
  196. package/dist/simulator/partner.js.map +1 -1
  197. package/dist/simulator/validation.cjs +160 -30
  198. package/dist/simulator/validation.cjs.map +1 -1
  199. package/dist/simulator/validation.d.cts +28 -6
  200. package/dist/simulator/validation.d.cts.map +1 -1
  201. package/dist/simulator/validation.d.ts +28 -6
  202. package/dist/simulator/validation.d.ts.map +1 -1
  203. package/dist/simulator/validation.js +148 -31
  204. package/dist/simulator/validation.js.map +1 -1
  205. package/dist/streams/file-source.cjs +1 -1
  206. package/dist/streams/file-source.cjs.map +1 -1
  207. package/dist/streams/file-source.js +1 -1
  208. package/dist/streams/file-source.js.map +1 -1
  209. package/dist/streams/hash.cjs +246 -13
  210. package/dist/streams/hash.cjs.map +1 -1
  211. package/dist/streams/hash.d.cts +37 -12
  212. package/dist/streams/hash.d.cts.map +1 -1
  213. package/dist/streams/hash.d.ts +37 -12
  214. package/dist/streams/hash.d.ts.map +1 -1
  215. package/dist/streams/hash.js +246 -15
  216. package/dist/streams/hash.js.map +1 -1
  217. package/dist/streams/index.cjs +2 -0
  218. package/dist/streams/index.d.cts +1 -1
  219. package/dist/streams/index.d.cts.map +1 -1
  220. package/dist/streams/index.d.ts +1 -1
  221. package/dist/streams/index.d.ts.map +1 -1
  222. package/dist/streams/index.js +2 -2
  223. package/dist/streams/progress.cjs +63 -4
  224. package/dist/streams/progress.cjs.map +1 -1
  225. package/dist/streams/progress.d.cts +28 -2
  226. package/dist/streams/progress.d.cts.map +1 -1
  227. package/dist/streams/progress.d.ts +28 -2
  228. package/dist/streams/progress.d.ts.map +1 -1
  229. package/dist/streams/progress.js +63 -4
  230. package/dist/streams/progress.js.map +1 -1
  231. package/dist/sync/download-staging.cjs +147 -35
  232. package/dist/sync/download-staging.cjs.map +1 -1
  233. package/dist/sync/download-staging.d.cts +25 -2
  234. package/dist/sync/download-staging.d.cts.map +1 -1
  235. package/dist/sync/download-staging.d.ts +25 -2
  236. package/dist/sync/download-staging.d.ts.map +1 -1
  237. package/dist/sync/download-staging.js +146 -36
  238. package/dist/sync/download-staging.js.map +1 -1
  239. package/dist/sync/index.d.cts +1 -1
  240. package/dist/sync/index.d.cts.map +1 -1
  241. package/dist/sync/index.d.ts +1 -1
  242. package/dist/sync/index.d.ts.map +1 -1
  243. package/dist/sync/local-file-io.cjs +5 -1
  244. package/dist/sync/local-file-io.cjs.map +1 -1
  245. package/dist/sync/local-file-io.d.cts +2 -0
  246. package/dist/sync/local-file-io.d.cts.map +1 -1
  247. package/dist/sync/local-file-io.d.ts +2 -0
  248. package/dist/sync/local-file-io.d.ts.map +1 -1
  249. package/dist/sync/local-file-io.js +5 -1
  250. package/dist/sync/local-file-io.js.map +1 -1
  251. package/dist/sync/pairing.cjs +1 -0
  252. package/dist/sync/pairing.cjs.map +1 -1
  253. package/dist/sync/pairing.js +1 -0
  254. package/dist/sync/pairing.js.map +1 -1
  255. package/dist/sync/scanners/b2.cjs +2 -0
  256. package/dist/sync/scanners/b2.cjs.map +1 -1
  257. package/dist/sync/scanners/b2.d.cts.map +1 -1
  258. package/dist/sync/scanners/b2.d.ts.map +1 -1
  259. package/dist/sync/scanners/b2.js +2 -0
  260. package/dist/sync/scanners/b2.js.map +1 -1
  261. package/dist/sync/scanners/local.cjs +150 -33
  262. package/dist/sync/scanners/local.cjs.map +1 -1
  263. package/dist/sync/scanners/local.d.cts +6 -0
  264. package/dist/sync/scanners/local.d.cts.map +1 -1
  265. package/dist/sync/scanners/local.d.ts +6 -0
  266. package/dist/sync/scanners/local.d.ts.map +1 -1
  267. package/dist/sync/scanners/local.js +150 -33
  268. package/dist/sync/scanners/local.js.map +1 -1
  269. package/dist/sync/synchronizer.cjs +76 -29
  270. package/dist/sync/synchronizer.cjs.map +1 -1
  271. package/dist/sync/synchronizer.d.cts +1 -0
  272. package/dist/sync/synchronizer.d.cts.map +1 -1
  273. package/dist/sync/synchronizer.d.ts +1 -0
  274. package/dist/sync/synchronizer.d.ts.map +1 -1
  275. package/dist/sync/synchronizer.js +76 -29
  276. package/dist/sync/synchronizer.js.map +1 -1
  277. package/dist/sync/types.d.cts +19 -3
  278. package/dist/sync/types.d.cts.map +1 -1
  279. package/dist/sync/types.d.ts +19 -3
  280. package/dist/sync/types.d.ts.map +1 -1
  281. package/dist/types/backup.d.cts +6 -1
  282. package/dist/types/backup.d.cts.map +1 -1
  283. package/dist/types/backup.d.ts +6 -1
  284. package/dist/types/backup.d.ts.map +1 -1
  285. package/dist/types/bucket.cjs +81 -11
  286. package/dist/types/bucket.cjs.map +1 -1
  287. package/dist/types/bucket.d.cts +190 -39
  288. package/dist/types/bucket.d.cts.map +1 -1
  289. package/dist/types/bucket.d.ts +190 -39
  290. package/dist/types/bucket.d.ts.map +1 -1
  291. package/dist/types/bucket.js +67 -12
  292. package/dist/types/bucket.js.map +1 -1
  293. package/dist/types/download.cjs.map +1 -1
  294. package/dist/types/download.d.cts +3 -17
  295. package/dist/types/download.d.cts.map +1 -1
  296. package/dist/types/download.d.ts +3 -17
  297. package/dist/types/download.d.ts.map +1 -1
  298. package/dist/types/download.js.map +1 -1
  299. package/dist/types/encryption.cjs +18 -0
  300. package/dist/types/encryption.cjs.map +1 -1
  301. package/dist/types/encryption.d.cts +21 -11
  302. package/dist/types/encryption.d.cts.map +1 -1
  303. package/dist/types/encryption.d.ts +21 -11
  304. package/dist/types/encryption.d.ts.map +1 -1
  305. package/dist/types/encryption.js +18 -0
  306. package/dist/types/encryption.js.map +1 -1
  307. package/dist/types/file.cjs +3 -0
  308. package/dist/types/file.cjs.map +1 -1
  309. package/dist/types/file.d.cts +125 -16
  310. package/dist/types/file.d.cts.map +1 -1
  311. package/dist/types/file.d.ts +125 -16
  312. package/dist/types/file.d.ts.map +1 -1
  313. package/dist/types/file.js +3 -1
  314. package/dist/types/file.js.map +1 -1
  315. package/dist/types/index.d.cts +7 -7
  316. package/dist/types/index.d.cts.map +1 -1
  317. package/dist/types/index.d.ts +7 -7
  318. package/dist/types/index.d.ts.map +1 -1
  319. package/dist/types/key.d.cts +4 -3
  320. package/dist/types/key.d.cts.map +1 -1
  321. package/dist/types/key.d.ts +4 -3
  322. package/dist/types/key.d.ts.map +1 -1
  323. package/dist/types/notifications.cjs +30 -0
  324. package/dist/types/notifications.cjs.map +1 -1
  325. package/dist/types/notifications.d.cts +26 -1
  326. package/dist/types/notifications.d.cts.map +1 -1
  327. package/dist/types/notifications.d.ts +26 -1
  328. package/dist/types/notifications.d.ts.map +1 -1
  329. package/dist/types/notifications.js +29 -1
  330. package/dist/types/notifications.js.map +1 -1
  331. package/dist/types/partner.cjs.map +1 -1
  332. package/dist/types/partner.d.cts +28 -36
  333. package/dist/types/partner.d.cts.map +1 -1
  334. package/dist/types/partner.d.ts +28 -36
  335. package/dist/types/partner.d.ts.map +1 -1
  336. package/dist/types/partner.js.map +1 -1
  337. package/dist/types/upload.d.cts +4 -0
  338. package/dist/types/upload.d.cts.map +1 -1
  339. package/dist/types/upload.d.ts +4 -0
  340. package/dist/types/upload.d.ts.map +1 -1
  341. package/dist/upload/large.cjs +10 -7
  342. package/dist/upload/large.cjs.map +1 -1
  343. package/dist/upload/large.d.cts +15 -6
  344. package/dist/upload/large.d.cts.map +1 -1
  345. package/dist/upload/large.d.ts +15 -6
  346. package/dist/upload/large.d.ts.map +1 -1
  347. package/dist/upload/large.js +10 -7
  348. package/dist/upload/large.js.map +1 -1
  349. package/dist/upload/options.cjs.map +1 -1
  350. package/dist/upload/options.d.cts +12 -0
  351. package/dist/upload/options.d.cts.map +1 -1
  352. package/dist/upload/options.d.ts +12 -0
  353. package/dist/upload/options.d.ts.map +1 -1
  354. package/dist/upload/options.js.map +1 -1
  355. package/dist/upload/resume.cjs +4 -3
  356. package/dist/upload/resume.cjs.map +1 -1
  357. package/dist/upload/resume.d.cts +6 -4
  358. package/dist/upload/resume.d.cts.map +1 -1
  359. package/dist/upload/resume.d.ts +6 -4
  360. package/dist/upload/resume.d.ts.map +1 -1
  361. package/dist/upload/resume.js +4 -3
  362. package/dist/upload/resume.js.map +1 -1
  363. package/dist/upload/retry.cjs +17 -10
  364. package/dist/upload/retry.cjs.map +1 -1
  365. package/dist/upload/retry.d.cts.map +1 -1
  366. package/dist/upload/retry.d.ts.map +1 -1
  367. package/dist/upload/retry.js +17 -10
  368. package/dist/upload/retry.js.map +1 -1
  369. package/dist/upload/single.cjs +35 -31
  370. package/dist/upload/single.cjs.map +1 -1
  371. package/dist/upload/single.d.cts +6 -0
  372. package/dist/upload/single.d.cts.map +1 -1
  373. package/dist/upload/single.d.ts +6 -0
  374. package/dist/upload/single.d.ts.map +1 -1
  375. package/dist/upload/single.js +35 -31
  376. package/dist/upload/single.js.map +1 -1
  377. package/dist/upload/stream.cjs +12 -1
  378. package/dist/upload/stream.cjs.map +1 -1
  379. package/dist/upload/stream.d.cts +6 -0
  380. package/dist/upload/stream.d.cts.map +1 -1
  381. package/dist/upload/stream.d.ts +6 -0
  382. package/dist/upload/stream.d.ts.map +1 -1
  383. package/dist/upload/stream.js +12 -1
  384. package/dist/upload/stream.js.map +1 -1
  385. package/dist/version.cjs +56 -4
  386. package/dist/version.cjs.map +1 -1
  387. package/dist/version.d.cts +53 -4
  388. package/dist/version.d.cts.map +1 -1
  389. package/dist/version.d.ts +53 -4
  390. package/dist/version.d.ts.map +1 -1
  391. package/dist/version.js +52 -5
  392. package/dist/version.js.map +1 -1
  393. package/package.json +11 -4
package/dist/raw/index.js CHANGED
@@ -2,6 +2,8 @@ import { FinishLargeFileResponseBodyError, UploadResponseBodyError } from "../er
2
2
  import { buildFileInfoHeaders, decodeFileName, encodeFileName, parseFileInfoHeaders } from "./encoding.js";
3
3
  import { EncryptionAlgorithm, EncryptionMode } from "../types/encryption.js";
4
4
  import { normalizeFileVersionListSha1, normalizeFileVersionSha1 } from "../util/normalize.js";
5
+ import { BUCKET_INFO_KEY_MAX_BYTES, BUCKET_INFO_KEY_MIN_BYTES, BUCKET_INFO_KEY_PATTERN, BUCKET_INFO_RESERVED_PREFIX, BUCKET_INFO_VALUES_MAX_BYTES, BucketKeyOption, CORS_ALLOWED_OPERATIONS, CORS_MAX_AGE_SECONDS_MAX, CORS_RULES_MAX_COUNT, CORS_RULE_MAX_BYTES, CORS_RULE_NAME_MAX_LENGTH, CORS_RULE_NAME_MIN_LENGTH, CORS_RULE_NAME_PATTERN, CORS_RULE_NAME_RESERVED_PREFIX, CorsOperation } from "../types/bucket.js";
6
+ import { assertValidBucketConfiguration, assertValidBucketInfo, assertValidCorsRules } from "../bucket-validation.js";
5
7
  import { assertSecureRealmUrl } from "../auth/realms.js";
6
8
  import { b2Url } from "./url.js";
7
9
  //#region src/raw/index.ts
@@ -12,14 +14,13 @@ import { b2Url } from "./url.js";
12
14
  * with fully typed request and response objects. No retry logic, no URL pooling,
13
15
  * no automatic reauthorization. Use this when you need precise control over
14
16
  * individual API calls; for most use cases prefer the high-level `B2Client`.
17
+ * SDK-built B2 native storage API URLs use `/b2api/v4`. JSON endpoints use
18
+ * POST request bodies, including read/list endpoints whose API docs also show
19
+ * GET query examples but document POST JSON compatibility.
15
20
  *
16
21
  * @packageDocumentation
17
22
  */
18
- var B2_NATIVE_API_V3 = {
19
- prefix: "b2api",
20
- version: "v3"
21
- };
22
- var B2_NATIVE_API_V4 = {
23
+ var B2_NATIVE_API = {
23
24
  prefix: "b2api",
24
25
  version: "v4"
25
26
  };
@@ -42,6 +43,21 @@ function assertCustomUploadTimestamp(value) {
42
43
  if (typeof value === "number" && Number.isSafeInteger(value) && value >= 0) return;
43
44
  throw new TypeError("customUploadTimestamp must be a non-negative safe integer");
44
45
  }
46
+ function assertSafeHttpHeaderValue(name, value) {
47
+ if (hasHttpHeaderControlByte(value)) throw new TypeError(`${name} must not contain HTTP control characters`);
48
+ }
49
+ function hasHttpHeaderControlByte(value) {
50
+ for (let i = 0; i < value.length; i += 1) {
51
+ const code = value.charCodeAt(i);
52
+ if (code <= 31 || code === 127) return true;
53
+ }
54
+ return false;
55
+ }
56
+ function setB2ContentFileInfoHeader(headers, key, optionName, value) {
57
+ if (!value) return;
58
+ assertSafeHttpHeaderValue(optionName, value);
59
+ Object.assign(headers, buildFileInfoHeaders({ [key]: value }));
60
+ }
45
61
  function assertRawCustomUploadTimestamp(value) {
46
62
  if (value === void 0 || value === null) return;
47
63
  if (typeof value === "string" && /^\d+$/.test(value)) {
@@ -138,18 +154,21 @@ var RawClient = class {
138
154
  * @param applicationKeyId - The application key ID for authentication.
139
155
  * @param applicationKey - The application key secret.
140
156
  * @param realmUrl - The B2 realm URL to authenticate against.
157
+ * @param options - Optional request controls.
141
158
  *
142
159
  * @returns The authorization response with API URLs and credentials.
143
160
  */
144
- async authorizeAccount(applicationKeyId, applicationKey, realmUrl = "https://api.backblazeb2.com") {
161
+ async authorizeAccount(applicationKeyId, applicationKey, realmUrl = "https://api.backblazeb2.com", options) {
145
162
  assertSecureRealmUrl(realmUrl);
146
163
  return normalizeAuthorizeAccountResponse(await (await this.transport.send({
147
164
  url: b2Url(realmUrl, {
148
- ...B2_NATIVE_API_V4,
165
+ ...B2_NATIVE_API,
149
166
  endpoint: "b2_authorize_account"
150
167
  }),
151
168
  method: "GET",
152
- headers: { Authorization: `Basic ${btoa(`${applicationKeyId}:${applicationKey}`)}` }
169
+ headers: { Authorization: `Basic ${btoa(`${applicationKeyId}:${applicationKey}`)}` },
170
+ ...options?.signal !== void 0 ? { signal: options.signal } : {},
171
+ ...options?.retry !== void 0 ? { retry: options.retry } : {}
153
172
  })).json());
154
173
  }
155
174
  /**
@@ -161,6 +180,7 @@ var RawClient = class {
161
180
  * @returns The created bucket metadata.
162
181
  */
163
182
  async createBucket(apiUrl, authToken, request) {
183
+ assertValidBucketConfiguration(request);
164
184
  return this.postJson(apiUrl, authToken, "b2_create_bucket", request);
165
185
  }
166
186
  /**
@@ -194,6 +214,7 @@ var RawClient = class {
194
214
  * @returns The updated bucket metadata.
195
215
  */
196
216
  async updateBucket(apiUrl, authToken, request) {
217
+ assertValidBucketConfiguration(request);
197
218
  return this.postJson(apiUrl, authToken, "b2_update_bucket", request);
198
219
  }
199
220
  /**
@@ -221,6 +242,9 @@ var RawClient = class {
221
242
  */
222
243
  async uploadFile(uploadUrl, headers, body, optionsOrSignal, retry) {
223
244
  const options = normalizeRawRequestOptions(optionsOrSignal, retry);
245
+ assertSafeHttpHeaderValue("authorization", headers.authorization);
246
+ assertSafeHttpHeaderValue("contentType", headers.contentType);
247
+ assertSafeHttpHeaderValue("contentSha1", headers.contentSha1);
224
248
  const reqHeaders = {
225
249
  Authorization: headers.authorization,
226
250
  "X-Bz-File-Name": encodeFileName(headers.fileName),
@@ -234,11 +258,11 @@ var RawClient = class {
234
258
  assertCustomUploadTimestamp(headers.customUploadTimestamp);
235
259
  reqHeaders["X-Bz-Custom-Upload-Timestamp"] = String(headers.customUploadTimestamp);
236
260
  }
237
- if (headers.contentDisposition) reqHeaders["X-Bz-Info-b2-content-disposition"] = headers.contentDisposition;
238
- if (headers.contentLanguage) reqHeaders["X-Bz-Info-b2-content-language"] = headers.contentLanguage;
239
- if (headers.expires) reqHeaders["X-Bz-Info-b2-expires"] = headers.expires;
240
- if (headers.cacheControl) reqHeaders["X-Bz-Info-b2-cache-control"] = headers.cacheControl;
241
- if (headers.contentEncoding) reqHeaders["X-Bz-Info-b2-content-encoding"] = headers.contentEncoding;
261
+ setB2ContentFileInfoHeader(reqHeaders, "b2-content-disposition", "contentDisposition", headers.contentDisposition);
262
+ setB2ContentFileInfoHeader(reqHeaders, "b2-content-language", "contentLanguage", headers.contentLanguage);
263
+ setB2ContentFileInfoHeader(reqHeaders, "b2-expires", "expires", headers.expires);
264
+ setB2ContentFileInfoHeader(reqHeaders, "b2-cache-control", "cacheControl", headers.cacheControl);
265
+ setB2ContentFileInfoHeader(reqHeaders, "b2-content-encoding", "contentEncoding", headers.contentEncoding);
242
266
  applyEncryptionHeaders(reqHeaders, headers.serverSideEncryption);
243
267
  applyRetentionHeaders(reqHeaders, headers.fileRetention);
244
268
  applyLegalHoldHeader(reqHeaders, headers.legalHold);
@@ -256,27 +280,9 @@ var RawClient = class {
256
280
  throw uploadResponseBodyError(err, options?.signal);
257
281
  }
258
282
  }
259
- /**
260
- * Calls {@link https://www.backblaze.com/apidocs/b2-list-file-names | b2_list_file_names}.
261
- * @param apiUrl - The B2 API base URL.
262
- * @param authToken - The authorization token.
263
- * @param request - The API request parameters.
264
- * @param options - Optional request controls such as an abort signal.
265
- *
266
- * @returns The list of file names and optional continuation token.
267
- */
268
283
  async listFileNames(apiUrl, authToken, request, options) {
269
284
  return normalizeFileVersionListSha1(await this.postJson(apiUrl, authToken, "b2_list_file_names", request, options));
270
285
  }
271
- /**
272
- * Calls {@link https://www.backblaze.com/apidocs/b2-list-file-versions | b2_list_file_versions}.
273
- * @param apiUrl - The B2 API base URL.
274
- * @param authToken - The authorization token.
275
- * @param request - The API request parameters.
276
- * @param options - Optional request controls such as an abort signal.
277
- *
278
- * @returns The list of file versions and optional continuation token.
279
- */
280
286
  async listFileVersions(apiUrl, authToken, request, options) {
281
287
  return normalizeFileVersionListSha1(await this.postJson(apiUrl, authToken, "b2_list_file_versions", request, options));
282
288
  }
@@ -377,6 +383,8 @@ var RawClient = class {
377
383
  */
378
384
  async uploadPart(uploadUrl, headers, body, optionsOrSignal, retry) {
379
385
  const options = normalizeRawRequestOptions(optionsOrSignal, retry);
386
+ assertSafeHttpHeaderValue("authorization", headers.authorization);
387
+ assertSafeHttpHeaderValue("contentSha1", headers.contentSha1);
380
388
  const reqHeaders = {
381
389
  Authorization: headers.authorization,
382
390
  "X-Bz-Part-Number": String(headers.partNumber),
@@ -410,7 +418,7 @@ var RawClient = class {
410
418
  async finishLargeFile(apiUrl, authToken, request, options) {
411
419
  const response = await this.transport.send({
412
420
  url: b2Url(apiUrl, {
413
- ...B2_NATIVE_API_V3,
421
+ ...B2_NATIVE_API,
414
422
  endpoint: "b2_finish_large_file"
415
423
  }),
416
424
  method: "POST",
@@ -481,7 +489,7 @@ var RawClient = class {
481
489
  async downloadFileById(downloadUrl, authToken, fileId, options) {
482
490
  const headers = buildDownloadRequestHeaders(authToken, options);
483
491
  const url = appendDownloadOverrides(`${b2Url(downloadUrl, {
484
- ...B2_NATIVE_API_V3,
492
+ ...B2_NATIVE_API,
485
493
  endpoint: "b2_download_file_by_id"
486
494
  })}?fileId=${encodeURIComponent(fileId)}`, options);
487
495
  const response = await this.transport.send({
@@ -541,7 +549,7 @@ var RawClient = class {
541
549
  * @returns The newly created application key with secret.
542
550
  */
543
551
  async createKey(apiUrl, authToken, request) {
544
- return normalizeKeyResponse(await this.postJson(apiUrl, authToken, "b2_create_key", normalizeCreateKeyRequest(request), void 0, B2_NATIVE_API_V4));
552
+ return normalizeKeyResponse(await this.postJson(apiUrl, authToken, "b2_create_key", normalizeCreateKeyRequest(request)));
545
553
  }
546
554
  /**
547
555
  * Calls {@link https://www.backblaze.com/apidocs/b2-list-keys | b2_list_keys}.
@@ -552,7 +560,7 @@ var RawClient = class {
552
560
  * @returns The list of application keys and optional continuation token.
553
561
  */
554
562
  async listKeys(apiUrl, authToken, request) {
555
- const response = await this.postJson(apiUrl, authToken, "b2_list_keys", request, void 0, B2_NATIVE_API_V4);
563
+ const response = await this.postJson(apiUrl, authToken, "b2_list_keys", request);
556
564
  return {
557
565
  ...response,
558
566
  keys: response.keys.map((key) => normalizeKeyResponse(key))
@@ -567,7 +575,7 @@ var RawClient = class {
567
575
  * @returns The deleted application key metadata.
568
576
  */
569
577
  async deleteKey(apiUrl, authToken, request) {
570
- return normalizeKeyResponse(await this.postJson(apiUrl, authToken, "b2_delete_key", request, void 0, B2_NATIVE_API_V4));
578
+ return normalizeKeyResponse(await this.postJson(apiUrl, authToken, "b2_delete_key", request));
571
579
  }
572
580
  /**
573
581
  * Calls {@link https://www.backblaze.com/apidocs/b2-update-file-retention | b2_update_file_retention}.
@@ -620,14 +628,13 @@ var RawClient = class {
620
628
  * @param endpoint - The B2 API endpoint name.
621
629
  * @param body - The JSON request body.
622
630
  * @param options - Optional abort and per-request retry settings.
623
- * @param urlOptions - B2 endpoint path prefix and version settings.
624
631
  *
625
632
  * @returns The parsed JSON response.
626
633
  */
627
- async postJson(apiUrl, authToken, endpoint, body, options, urlOptions = B2_NATIVE_API_V3) {
634
+ async postJson(apiUrl, authToken, endpoint, body, options) {
628
635
  return (await this.transport.send({
629
636
  url: b2Url(apiUrl, {
630
- ...urlOptions,
637
+ ...B2_NATIVE_API,
631
638
  endpoint
632
639
  }),
633
640
  method: "POST",
@@ -743,6 +750,6 @@ function applyLegalHoldHeader(headers, legalHold) {
743
750
  headers["X-Bz-File-Legal-Hold"] = legalHold;
744
751
  }
745
752
  //#endregion
746
- export { RawClient, buildFileInfoHeaders, decodeFileName, encodeFileName, parseFileInfoHeaders };
753
+ export { BUCKET_INFO_KEY_MAX_BYTES, BUCKET_INFO_KEY_MIN_BYTES, BUCKET_INFO_KEY_PATTERN, BUCKET_INFO_RESERVED_PREFIX, BUCKET_INFO_VALUES_MAX_BYTES, BucketKeyOption, CORS_ALLOWED_OPERATIONS, CORS_MAX_AGE_SECONDS_MAX, CORS_RULES_MAX_COUNT, CORS_RULE_MAX_BYTES, CORS_RULE_NAME_MAX_LENGTH, CORS_RULE_NAME_MIN_LENGTH, CORS_RULE_NAME_PATTERN, CORS_RULE_NAME_RESERVED_PREFIX, CorsOperation, RawClient, assertValidBucketConfiguration, assertValidBucketInfo, assertValidCorsRules, buildFileInfoHeaders, decodeFileName, encodeFileName, parseFileInfoHeaders };
747
754
 
748
755
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/raw/index.ts"],"sourcesContent":["/**\n * Low-level 1:1 bindings for every B2 native API endpoint.\n *\n * Each method on {@link RawClient} maps directly to a single `b2_*` HTTP call\n * with fully typed request and response objects. No retry logic, no URL pooling,\n * no automatic reauthorization. Use this when you need precise control over\n * individual API calls; for most use cases prefer the high-level `B2Client`.\n *\n * @packageDocumentation\n */\n\nimport { assertSecureRealmUrl } from '../auth/realms.ts'\nimport { FinishLargeFileResponseBodyError, UploadResponseBodyError } from '../errors/index.ts'\nimport type { RetryOptions } from '../http/retry.ts'\nimport type { HttpTransport } from '../http/transport.ts'\nimport type {\n AllowedBucket,\n ApplicationKey,\n AuthorizeAccountResponse,\n BucketId,\n BucketInfo,\n CancelLargeFileRequest,\n CancelLargeFileResponse,\n CopyFileRequest,\n CopyPartRequest,\n CopyPartResponse,\n CreateBucketRequest,\n CreateKeyRequest,\n DeleteBucketRequest,\n DeleteFileVersionRequest,\n DeleteFileVersionResponse,\n DeleteKeyRequest,\n DownloadAuthorizationRequest,\n DownloadAuthorizationResponse,\n FileVersion,\n FinishLargeFileRequest,\n FullApplicationKey,\n GetBucketNotificationRulesRequest,\n GetBucketNotificationRulesResponse,\n GetFileInfoRequest,\n GetUploadPartUrlRequest,\n GetUploadPartUrlResponse,\n GetUploadUrlRequest,\n GetUploadUrlResponse,\n HideFileRequest,\n ListBucketsRequest,\n ListBucketsResponse,\n ListFileNamesRequest,\n ListFileNamesResponse,\n ListFileVersionsRequest,\n ListFileVersionsResponse,\n ListKeysRequest,\n ListKeysResponse,\n ListPartsRequest,\n ListPartsResponse,\n ListUnfinishedLargeFilesRequest,\n ListUnfinishedLargeFilesResponse,\n SetBucketNotificationRulesRequest,\n SetBucketNotificationRulesResponse,\n StartLargeFileRequest,\n StartLargeFileResponse,\n UpdateBucketRequest,\n UpdateFileLegalHoldRequest,\n UpdateFileLegalHoldResponse,\n UpdateFileRetentionRequest,\n UpdateFileRetentionResponse,\n} from '../types/index.ts'\nimport type { UploadFileHeaders, UploadPartHeaders, UploadPartResponse } from '../types/upload.ts'\nimport { normalizeFileVersionListSha1, normalizeFileVersionSha1 } from '../util/normalize.ts'\nimport { buildFileInfoHeaders, encodeFileName } from './encoding.ts'\nimport { type B2EndpointUrlOptions, b2Url } from './url.ts'\n\nconst B2_NATIVE_API_V3: B2EndpointUrlOptions = { prefix: 'b2api', version: 'v3' }\nconst B2_NATIVE_API_V4: B2EndpointUrlOptions = { prefix: 'b2api', version: 'v4' }\n\n/** Configuration for constructing a {@link RawClient}. */\nexport interface RawClientOptions {\n /** The HTTP transport used to send requests (e.g., FetchTransport or RetryTransport). */\n readonly transport: HttpTransport\n}\n\n/** Optional request controls for {@link RawClient.listFileNames}. */\nexport type ListFileNamesOptions = RawRequestOptions\n\n/** Optional request controls for {@link RawClient.listFileVersions}. */\nexport type ListFileVersionsOptions = RawRequestOptions\n\n/** Optional controls for raw JSON API requests. */\nexport interface RawRequestOptions {\n /** Abort signal for cancelling the request. */\n readonly signal?: AbortSignal\n /** Per-request retry override. */\n readonly retry?: Partial<RetryOptions>\n}\n\n/**\n * @deprecated Use {@link RawRequestOptions}.\n */\nexport type JsonPostOptions = RawRequestOptions\n\n/** Optional request controls for {@link RawClient.finishLargeFile}. */\nexport type FinishLargeFileOptions = RawRequestOptions\n\n/** Optional request controls for {@link RawClient.copyPart}. */\nexport type CopyPartOptions = RawRequestOptions\n\n/** Optional request controls for {@link RawClient.startLargeFile}. */\nexport type StartLargeFileOptions = RawRequestOptions\n\n/** Optional request controls for {@link RawClient.uploadFile}. */\nexport type UploadFileOptions = RawRequestOptions\n\n/** Optional request controls for {@link RawClient.uploadPart}. */\nexport type UploadPartOptions = RawRequestOptions\n\nfunction normalizeRawRequestOptions(\n optionsOrSignal?: RawRequestOptions | AbortSignal,\n retry?: Partial<RetryOptions>,\n): RawRequestOptions | undefined {\n if (optionsOrSignal === undefined) {\n return retry === undefined ? undefined : { retry }\n }\n if (isAbortSignal(optionsOrSignal)) {\n return {\n signal: optionsOrSignal,\n ...(retry !== undefined ? { retry } : {}),\n }\n }\n return retry === undefined ? optionsOrSignal : { ...optionsOrSignal, retry }\n}\n\nfunction isAbortSignal(value: unknown): value is AbortSignal {\n // Back-compat only: legacy upload-URL overloads accepted an AbortSignal as\n // the fourth positional argument. Prefer the RawRequestOptions bag.\n return (\n typeof value === 'object' &&\n value !== null &&\n 'aborted' in value &&\n typeof (value as AbortSignal).addEventListener === 'function'\n )\n}\n\nfunction assertCustomUploadTimestamp(value: unknown): asserts value is number {\n if (value === undefined) return\n if (typeof value === 'number' && Number.isSafeInteger(value) && value >= 0) return\n throw new TypeError('customUploadTimestamp must be a non-negative safe integer')\n}\n\nfunction assertRawCustomUploadTimestamp(\n value: unknown,\n): asserts value is string | null | undefined {\n if (value === undefined || value === null) return\n if (typeof value === 'string' && /^\\d+$/.test(value)) {\n const timestamp = Number(value)\n if (Number.isSafeInteger(timestamp)) return\n }\n throw new TypeError('customUploadTimestamp must be a non-negative safe integer string or null')\n}\n\nfunction normalizeCreateKeyRequest(request: CreateKeyRequest): CreateKeyRequest {\n const { bucketId, ...withoutDeprecatedBucketId } = request\n if (bucketId !== undefined && withoutDeprecatedBucketId.bucketIds !== undefined) {\n throw new TypeError('createKey accepts either bucketIds or deprecated bucketId, not both')\n }\n if (bucketId === undefined) {\n return withoutDeprecatedBucketId\n }\n return { ...withoutDeprecatedBucketId, bucketIds: [bucketId] }\n}\n\nfunction singleBucketId(bucketIds: readonly BucketId[] | null): BucketId | null {\n return bucketIds?.length === 1 ? (bucketIds[0] ?? null) : null\n}\n\nfunction normalizeKeyResponse<T extends { readonly bucketIds: readonly BucketId[] | null }>(\n key: T,\n): T & { readonly bucketId: BucketId | null } {\n return { ...key, bucketId: singleBucketId(key.bucketIds) }\n}\n\ntype NormalizedAllowedInfo = AuthorizeAccountResponse['apiInfo']['storageApi']['allowed']\ntype NormalizedStorageApiInfo = AuthorizeAccountResponse['apiInfo']['storageApi']\n\ninterface WireAllowedInfo {\n readonly capabilities?: NormalizedAllowedInfo['capabilities']\n readonly buckets?: readonly AllowedBucket[] | null\n readonly bucketId?: BucketId | null\n readonly bucketName?: string | null\n readonly namePrefix?: string | null\n}\n\ntype WireStorageApiInfo = Omit<\n NormalizedStorageApiInfo,\n 'allowed' | 'bucketId' | 'bucketName' | 'infoType' | 'namePrefix'\n> & {\n readonly allowed?: WireAllowedInfo\n readonly capabilities?: NormalizedAllowedInfo['capabilities']\n readonly bucketId?: BucketId | null\n readonly bucketName?: string | null\n readonly infoType?: 'storageApi'\n readonly namePrefix?: string | null\n}\n\ntype WireAuthorizeAccountResponse = Omit<AuthorizeAccountResponse, 'apiInfo'> & {\n readonly apiInfo: Omit<AuthorizeAccountResponse['apiInfo'], 'storageApi'> & {\n readonly storageApi: WireStorageApiInfo\n }\n}\n\nfunction normalizeAllowedBuckets(storageApi: WireStorageApiInfo): readonly AllowedBucket[] | null {\n const allowed = storageApi.allowed\n if (allowed?.buckets !== undefined) {\n return allowed.buckets === null ? null : allowed.buckets.map((bucket) => ({ ...bucket }))\n }\n const bucketId = allowed?.bucketId ?? storageApi.bucketId ?? null\n if (bucketId === null) return null\n return [{ id: bucketId, name: allowed?.bucketName ?? storageApi.bucketName ?? null }]\n}\n\nfunction normalizeAuthorizeAccountResponse(\n response: WireAuthorizeAccountResponse,\n): AuthorizeAccountResponse {\n const storageApi = response.apiInfo.storageApi\n const allowed = storageApi.allowed\n const buckets = normalizeAllowedBuckets(storageApi)\n const singleBucket = buckets?.length === 1 ? buckets[0] : undefined\n const bucketId = singleBucket?.id ?? null\n const bucketName = singleBucket?.name ?? null\n const namePrefix = allowed?.namePrefix ?? storageApi.namePrefix ?? null\n const capabilities = allowed?.capabilities ?? storageApi.capabilities ?? []\n const { allowed: _wireAllowed, capabilities: _legacyCapabilities, ...storageApiBase } = storageApi\n\n return {\n ...response,\n apiInfo: {\n ...response.apiInfo,\n storageApi: {\n ...storageApiBase,\n bucketId,\n bucketName,\n downloadUrl: storageApi.downloadUrl,\n infoType: 'storageApi',\n namePrefix,\n allowed: {\n ...(allowed ?? {}),\n capabilities,\n buckets,\n bucketId,\n bucketName,\n namePrefix,\n },\n },\n },\n }\n}\n\nfunction uploadResponseBodyError(\n err: unknown,\n signal: AbortSignal | undefined,\n): UploadResponseBodyError {\n if (signal?.aborted === true) {\n throw signal.reason ?? new DOMException('Aborted', 'AbortError')\n }\n const message = err instanceof Error ? err.message : 'Upload response body could not be read'\n return new UploadResponseBodyError(message, { cause: err })\n}\n\n/**\n * Low-level client providing 1:1 bindings to all B2 native API endpoints.\n *\n * Each method maps directly to a single B2 API call. Most methods accept\n * `(apiUrl, authToken, request)` and return the JSON response. Upload and\n * download methods accept endpoint-specific parameters instead.\n */\nexport class RawClient {\n /** @internal */\n private readonly transport: HttpTransport\n\n /**\n * Creates a new RawClient with the given transport.\n * @param options - The constructor configuration.\n */\n constructor(options: RawClientOptions) {\n this.transport = options.transport\n }\n\n // --- Auth ---\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-authorize-account | b2_authorize_account}.\n * @param applicationKeyId - The application key ID for authentication.\n * @param applicationKey - The application key secret.\n * @param realmUrl - The B2 realm URL to authenticate against.\n *\n * @returns The authorization response with API URLs and credentials.\n */\n async authorizeAccount(\n applicationKeyId: string,\n applicationKey: string,\n realmUrl = 'https://api.backblazeb2.com',\n ): Promise<AuthorizeAccountResponse> {\n assertSecureRealmUrl(realmUrl)\n const response = await this.transport.send({\n url: b2Url(realmUrl, { ...B2_NATIVE_API_V4, endpoint: 'b2_authorize_account' }),\n method: 'GET',\n headers: {\n Authorization: `Basic ${btoa(`${applicationKeyId}:${applicationKey}`)}`,\n },\n })\n return normalizeAuthorizeAccountResponse(await response.json<WireAuthorizeAccountResponse>())\n }\n\n // --- Buckets ---\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-create-bucket | b2_create_bucket}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The created bucket metadata.\n */\n async createBucket(\n apiUrl: string,\n authToken: string,\n request: CreateBucketRequest,\n ): Promise<BucketInfo> {\n return this.postJson<BucketInfo>(apiUrl, authToken, 'b2_create_bucket', request)\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-delete-bucket | b2_delete_bucket}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The deleted bucket metadata.\n */\n async deleteBucket(\n apiUrl: string,\n authToken: string,\n request: DeleteBucketRequest,\n ): Promise<BucketInfo> {\n return this.postJson<BucketInfo>(apiUrl, authToken, 'b2_delete_bucket', request)\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-list-buckets | b2_list_buckets}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The list of matching buckets.\n */\n async listBuckets(\n apiUrl: string,\n authToken: string,\n request: ListBucketsRequest,\n ): Promise<ListBucketsResponse> {\n return this.postJson<ListBucketsResponse>(apiUrl, authToken, 'b2_list_buckets', request)\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-update-bucket | b2_update_bucket}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The updated bucket metadata.\n */\n async updateBucket(\n apiUrl: string,\n authToken: string,\n request: UpdateBucketRequest,\n ): Promise<BucketInfo> {\n return this.postJson<BucketInfo>(apiUrl, authToken, 'b2_update_bucket', request)\n }\n\n // --- Files ---\n\n /**\n * Calls `b2_get_upload_url` with legacy positional request controls.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param signal - Optional abort signal for cancellation.\n * @param retry - Optional per-request retry override.\n *\n * @returns The upload URL and authorization token.\n *\n * @deprecated Use the options-bag overload: `getUploadUrl(apiUrl, authToken, request, { signal, retry })`.\n */\n async getUploadUrl(\n apiUrl: string,\n authToken: string,\n request: GetUploadUrlRequest,\n signal?: AbortSignal,\n retry?: Partial<RetryOptions>,\n ): Promise<GetUploadUrlResponse>\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-get-upload-url | b2_get_upload_url}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional request controls such as cancellation and retry overrides.\n *\n * @returns The upload URL and authorization token.\n */\n async getUploadUrl(\n apiUrl: string,\n authToken: string,\n request: GetUploadUrlRequest,\n options?: RawRequestOptions,\n ): Promise<GetUploadUrlResponse>\n /**\n * Implementation for both upload URL request-control signatures.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param optionsOrSignal - Options bag or legacy abort signal.\n * @param retry - Optional legacy per-request retry override.\n *\n * @returns The upload URL and authorization token.\n */\n async getUploadUrl(\n apiUrl: string,\n authToken: string,\n request: GetUploadUrlRequest,\n optionsOrSignal?: RawRequestOptions | AbortSignal,\n retry?: Partial<RetryOptions>,\n ): Promise<GetUploadUrlResponse> {\n return this.postJson<GetUploadUrlResponse>(\n apiUrl,\n authToken,\n 'b2_get_upload_url',\n request,\n normalizeRawRequestOptions(optionsOrSignal, retry),\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-upload-file | b2_upload_file}.\n *\n * Unlike most methods, this posts directly to the `uploadUrl` obtained\n * from {@link getUploadUrl} rather than the API URL.\n * @param uploadUrl - The upload endpoint URL.\n * @param headers - The request headers including authorization and content metadata.\n * @param body - The file data to upload.\n * @param signal - Optional legacy abort signal for cancellation.\n * @param retry - Optional legacy per-request retry override.\n *\n * @returns The uploaded file version metadata.\n *\n * @deprecated Use the options-bag overload: `uploadFile(uploadUrl, headers, body, { signal, retry })`.\n */\n async uploadFile(\n uploadUrl: string,\n headers: UploadFileHeaders,\n body: BodyInit,\n signal?: AbortSignal,\n retry?: Partial<RetryOptions>,\n ): Promise<FileVersion>\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-upload-file | b2_upload_file}.\n *\n * Unlike most methods, this posts directly to the `uploadUrl` obtained\n * from {@link getUploadUrl} rather than the API URL.\n * @param uploadUrl - The upload endpoint URL.\n * @param headers - The request headers including authorization and content metadata.\n * @param body - The file data to upload.\n * @param options - Optional request controls such as cancellation and retry overrides.\n *\n * @returns The uploaded file version metadata.\n */\n async uploadFile(\n uploadUrl: string,\n headers: UploadFileHeaders,\n body: BodyInit,\n options?: UploadFileOptions,\n ): Promise<FileVersion>\n /**\n * Implementation for both upload-file request-control signatures.\n * @param uploadUrl - The upload endpoint URL.\n * @param headers - The request headers including authorization and content metadata.\n * @param body - The file data to upload.\n * @param optionsOrSignal - Options bag or legacy abort signal.\n * @param retry - Optional legacy per-request retry override.\n *\n * @returns The uploaded file version metadata.\n */\n async uploadFile(\n uploadUrl: string,\n headers: UploadFileHeaders,\n body: BodyInit,\n optionsOrSignal?: UploadFileOptions | AbortSignal,\n retry?: Partial<RetryOptions>,\n ): Promise<FileVersion> {\n const options = normalizeRawRequestOptions(optionsOrSignal, retry)\n const reqHeaders: Record<string, string> = {\n Authorization: headers.authorization,\n 'X-Bz-File-Name': encodeFileName(headers.fileName),\n 'Content-Type': headers.contentType,\n 'Content-Length': String(headers.contentLength),\n 'X-Bz-Content-Sha1': headers.contentSha1,\n ...buildFileInfoHeaders(headers.fileInfo),\n }\n\n if (headers.lastModifiedMillis !== undefined) {\n reqHeaders['X-Bz-Info-src_last_modified_millis'] = String(headers.lastModifiedMillis)\n }\n if (headers.customUploadTimestamp !== undefined) {\n assertCustomUploadTimestamp(headers.customUploadTimestamp)\n reqHeaders['X-Bz-Custom-Upload-Timestamp'] = String(headers.customUploadTimestamp)\n }\n if (headers.contentDisposition) {\n reqHeaders['X-Bz-Info-b2-content-disposition'] = headers.contentDisposition\n }\n if (headers.contentLanguage) {\n reqHeaders['X-Bz-Info-b2-content-language'] = headers.contentLanguage\n }\n if (headers.expires) {\n reqHeaders['X-Bz-Info-b2-expires'] = headers.expires\n }\n if (headers.cacheControl) {\n reqHeaders['X-Bz-Info-b2-cache-control'] = headers.cacheControl\n }\n if (headers.contentEncoding) {\n reqHeaders['X-Bz-Info-b2-content-encoding'] = headers.contentEncoding\n }\n\n applyEncryptionHeaders(reqHeaders, headers.serverSideEncryption)\n applyRetentionHeaders(reqHeaders, headers.fileRetention)\n applyLegalHoldHeader(reqHeaders, headers.legalHold)\n\n const response = await this.transport.send({\n url: uploadUrl,\n method: 'POST',\n headers: reqHeaders,\n body,\n ...(options?.signal !== undefined ? { signal: options.signal } : {}),\n ...(options?.retry !== undefined ? { retry: options.retry } : {}),\n })\n try {\n return normalizeFileVersionSha1(await response.json<FileVersion>())\n } catch (err) {\n throw uploadResponseBodyError(err, options?.signal)\n }\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-list-file-names | b2_list_file_names}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional request controls such as an abort signal.\n *\n * @returns The list of file names and optional continuation token.\n */\n async listFileNames(\n apiUrl: string,\n authToken: string,\n request: ListFileNamesRequest,\n options?: ListFileNamesOptions,\n ): Promise<ListFileNamesResponse> {\n return normalizeFileVersionListSha1(\n await this.postJson<ListFileNamesResponse>(\n apiUrl,\n authToken,\n 'b2_list_file_names',\n request,\n options,\n ),\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-list-file-versions | b2_list_file_versions}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional request controls such as an abort signal.\n *\n * @returns The list of file versions and optional continuation token.\n */\n async listFileVersions(\n apiUrl: string,\n authToken: string,\n request: ListFileVersionsRequest,\n options?: ListFileVersionsOptions,\n ): Promise<ListFileVersionsResponse> {\n return normalizeFileVersionListSha1(\n await this.postJson<ListFileVersionsResponse>(\n apiUrl,\n authToken,\n 'b2_list_file_versions',\n request,\n options,\n ),\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-get-file-info | b2_get_file_info}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The file version metadata.\n */\n async getFileInfo(\n apiUrl: string,\n authToken: string,\n request: GetFileInfoRequest,\n ): Promise<FileVersion> {\n return normalizeFileVersionSha1(\n await this.postJson<FileVersion>(apiUrl, authToken, 'b2_get_file_info', request),\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-hide-file | b2_hide_file}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional request controls such as an abort signal.\n *\n * @returns The hidden file version metadata.\n */\n async hideFile(\n apiUrl: string,\n authToken: string,\n request: HideFileRequest,\n options?: { readonly signal?: AbortSignal },\n ): Promise<FileVersion> {\n return normalizeFileVersionSha1(\n await this.postJson<FileVersion>(apiUrl, authToken, 'b2_hide_file', request, options),\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-delete-file-version | b2_delete_file_version}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional request controls such as an abort signal.\n *\n * @returns The deleted file version identifier.\n */\n async deleteFileVersion(\n apiUrl: string,\n authToken: string,\n request: DeleteFileVersionRequest,\n options?: { readonly signal?: AbortSignal },\n ): Promise<DeleteFileVersionResponse> {\n return this.postJson<DeleteFileVersionResponse>(\n apiUrl,\n authToken,\n 'b2_delete_file_version',\n request,\n options,\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-copy-file | b2_copy_file}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional request controls such as an abort signal.\n *\n * @returns The copied file version metadata.\n */\n async copyFile(\n apiUrl: string,\n authToken: string,\n request: CopyFileRequest,\n options?: RawRequestOptions,\n ): Promise<FileVersion> {\n return normalizeFileVersionSha1(\n await this.postJson<FileVersion>(\n apiUrl,\n authToken,\n 'b2_copy_file',\n withJsonBodyWireSseC(request),\n options,\n ),\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-copy-part | b2_copy_part}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional abort and retry controls.\n *\n * @returns The copied part metadata.\n */\n async copyPart(\n apiUrl: string,\n authToken: string,\n request: CopyPartRequest,\n options?: CopyPartOptions,\n ): Promise<CopyPartResponse> {\n return this.postJson<CopyPartResponse>(\n apiUrl,\n authToken,\n 'b2_copy_part',\n withJsonBodyWireSseC(request),\n options,\n )\n }\n\n // --- Large Files ---\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-start-large-file | b2_start_large_file}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional abort and retry controls.\n *\n * @returns The started large file metadata with file ID.\n */\n async startLargeFile(\n apiUrl: string,\n authToken: string,\n request: StartLargeFileRequest,\n options?: StartLargeFileOptions,\n ): Promise<StartLargeFileResponse> {\n assertRawCustomUploadTimestamp(request.customUploadTimestamp)\n return normalizeFileVersionSha1(\n await this.postJson<StartLargeFileResponse>(\n apiUrl,\n authToken,\n 'b2_start_large_file',\n withJsonBodyWireSseC(request),\n options,\n ),\n )\n }\n\n /**\n * Calls `b2_get_upload_part_url` with legacy positional request controls.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param signal - Optional abort signal for cancellation.\n * @param retry - Optional per-request retry override.\n *\n * @returns The upload part URL and authorization token.\n *\n * @deprecated Use the options-bag overload: `getUploadPartUrl(apiUrl, authToken, request, { signal, retry })`.\n */\n async getUploadPartUrl(\n apiUrl: string,\n authToken: string,\n request: GetUploadPartUrlRequest,\n signal?: AbortSignal,\n retry?: Partial<RetryOptions>,\n ): Promise<GetUploadPartUrlResponse>\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-get-upload-part-url | b2_get_upload_part_url}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional request controls such as cancellation and retry overrides.\n *\n * @returns The upload part URL and authorization token.\n */\n async getUploadPartUrl(\n apiUrl: string,\n authToken: string,\n request: GetUploadPartUrlRequest,\n options?: RawRequestOptions,\n ): Promise<GetUploadPartUrlResponse>\n /**\n * Implementation for both upload part URL request-control signatures.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param optionsOrSignal - Options bag or legacy abort signal.\n * @param retry - Optional legacy per-request retry override.\n *\n * @returns The upload part URL and authorization token.\n */\n async getUploadPartUrl(\n apiUrl: string,\n authToken: string,\n request: GetUploadPartUrlRequest,\n optionsOrSignal?: RawRequestOptions | AbortSignal,\n retry?: Partial<RetryOptions>,\n ): Promise<GetUploadPartUrlResponse> {\n return this.postJson<GetUploadPartUrlResponse>(\n apiUrl,\n authToken,\n 'b2_get_upload_part_url',\n request,\n normalizeRawRequestOptions(optionsOrSignal, retry),\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-upload-part | b2_upload_part}.\n *\n * Posts directly to the `uploadUrl` obtained from {@link getUploadPartUrl}\n * rather than the API URL.\n * @param uploadUrl - The upload endpoint URL.\n * @param headers - The request headers including authorization and content metadata.\n * @param body - The file data to upload.\n * @param signal - Optional legacy abort signal for cancellation.\n * @param retry - Optional legacy per-request retry override.\n *\n * @returns The uploaded part metadata.\n *\n * @deprecated Use the options-bag overload: `uploadPart(uploadUrl, headers, body, { signal, retry })`.\n */\n async uploadPart(\n uploadUrl: string,\n headers: UploadPartHeaders,\n body: BodyInit,\n signal?: AbortSignal,\n retry?: Partial<RetryOptions>,\n ): Promise<UploadPartResponse>\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-upload-part | b2_upload_part}.\n *\n * Posts directly to the `uploadUrl` obtained from {@link getUploadPartUrl}\n * rather than the API URL.\n * @param uploadUrl - The upload endpoint URL.\n * @param headers - The request headers including authorization and content metadata.\n * @param body - The file data to upload.\n * @param options - Optional request controls such as cancellation and retry overrides.\n *\n * @returns The uploaded part metadata.\n */\n async uploadPart(\n uploadUrl: string,\n headers: UploadPartHeaders,\n body: BodyInit,\n options?: UploadPartOptions,\n ): Promise<UploadPartResponse>\n /**\n * Implementation for both upload-part request-control signatures.\n * @param uploadUrl - The upload endpoint URL.\n * @param headers - The request headers including authorization and content metadata.\n * @param body - The file data to upload.\n * @param optionsOrSignal - Options bag or legacy abort signal.\n * @param retry - Optional legacy per-request retry override.\n *\n * @returns The uploaded part metadata.\n */\n async uploadPart(\n uploadUrl: string,\n headers: UploadPartHeaders,\n body: BodyInit,\n optionsOrSignal?: UploadPartOptions | AbortSignal,\n retry?: Partial<RetryOptions>,\n ): Promise<UploadPartResponse> {\n const options = normalizeRawRequestOptions(optionsOrSignal, retry)\n const reqHeaders: Record<string, string> = {\n Authorization: headers.authorization,\n 'X-Bz-Part-Number': String(headers.partNumber),\n 'Content-Length': String(headers.contentLength),\n 'X-Bz-Content-Sha1': headers.contentSha1,\n }\n\n applyEncryptionHeaders(reqHeaders, headers.serverSideEncryption)\n\n const response = await this.transport.send({\n url: uploadUrl,\n method: 'POST',\n headers: reqHeaders,\n body,\n ...(options?.signal !== undefined ? { signal: options.signal } : {}),\n ...(options?.retry !== undefined ? { retry: options.retry } : {}),\n })\n try {\n return await response.json<UploadPartResponse>()\n } catch (err) {\n throw uploadResponseBodyError(err, options?.signal)\n }\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-finish-large-file | b2_finish_large_file}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional abort and retry controls.\n *\n * @returns The completed file version metadata.\n */\n async finishLargeFile(\n apiUrl: string,\n authToken: string,\n request: FinishLargeFileRequest,\n options?: FinishLargeFileOptions,\n ): Promise<FileVersion> {\n const response = await this.transport.send({\n url: b2Url(apiUrl, { ...B2_NATIVE_API_V3, endpoint: 'b2_finish_large_file' }),\n method: 'POST',\n headers: {\n Authorization: authToken,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(request),\n ...(options?.signal !== undefined ? { signal: options.signal } : {}),\n ...(options?.retry !== undefined ? { retry: options.retry } : {}),\n })\n\n let fileVersion: FileVersion\n try {\n fileVersion = await response.json<FileVersion>()\n } catch (err) {\n throw new FinishLargeFileResponseBodyError(\n err instanceof Error ? err.message : 'Finish large file response body could not be read',\n { cause: err, fileId: request.fileId },\n )\n }\n return normalizeFileVersionSha1(fileVersion)\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-cancel-large-file | b2_cancel_large_file}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional request controls such as cancellation and retry overrides.\n *\n * @returns The cancelled large file metadata.\n */\n async cancelLargeFile(\n apiUrl: string,\n authToken: string,\n request: CancelLargeFileRequest,\n options?: RawRequestOptions,\n ): Promise<CancelLargeFileResponse> {\n return this.postJson<CancelLargeFileResponse>(\n apiUrl,\n authToken,\n 'b2_cancel_large_file',\n request,\n options,\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-list-unfinished-large-files | b2_list_unfinished_large_files}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional request controls such as cancellation and retry.\n *\n * @returns The list of unfinished large files and optional continuation token.\n */\n async listUnfinishedLargeFiles(\n apiUrl: string,\n authToken: string,\n request: ListUnfinishedLargeFilesRequest,\n options?: RawRequestOptions,\n ): Promise<ListUnfinishedLargeFilesResponse> {\n return normalizeFileVersionListSha1(\n await this.postJson<ListUnfinishedLargeFilesResponse>(\n apiUrl,\n authToken,\n 'b2_list_unfinished_large_files',\n request,\n options,\n ),\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-list-parts | b2_list_parts}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional request controls such as cancellation and retry.\n *\n * @returns The list of uploaded parts and optional continuation token.\n */\n async listParts(\n apiUrl: string,\n authToken: string,\n request: ListPartsRequest,\n options?: RawRequestOptions,\n ): Promise<ListPartsResponse> {\n return this.postJson<ListPartsResponse>(apiUrl, authToken, 'b2_list_parts', request, options)\n }\n\n // --- Downloads ---\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-download-file-by-id | b2_download_file_by_id}.\n * @param downloadUrl - The B2 download base URL.\n * @param authToken - The authorization token.\n * @param fileId - The unique identifier of the file to download.\n * @param options - Optional download parameters for range requests and cancellation.\n *\n * @returns The response headers, streaming body, and HTTP status code.\n */\n async downloadFileById(\n downloadUrl: string,\n authToken: string,\n fileId: string,\n options?: DownloadFileOptions,\n ): Promise<{\n /** Response headers containing file metadata and B2 info headers. */\n headers: Headers\n /** Streaming response body, or `null` for HEAD-like responses. */\n body: ReadableStream<Uint8Array> | null\n /** HTTP status code (200 for full content, 206 for partial content). */\n status: number\n }> {\n const headers = buildDownloadRequestHeaders(authToken, options)\n const url = appendDownloadOverrides(\n `${b2Url(downloadUrl, {\n ...B2_NATIVE_API_V3,\n endpoint: 'b2_download_file_by_id',\n })}?fileId=${encodeURIComponent(fileId)}`,\n options,\n )\n\n const response = await this.transport.send({\n url,\n method: options?.method ?? 'GET',\n headers,\n ...(options?.signal !== undefined ? { signal: options.signal } : {}),\n })\n\n return { headers: response.headers, body: response.body, status: response.status }\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-download-file-by-name | b2_download_file_by_name}.\n * @param downloadUrl - The B2 download base URL.\n * @param authToken - The authorization token.\n * @param bucketName - The name of the bucket containing the file.\n * @param fileName - The name of the file to download.\n * @param options - Optional download parameters for range requests and cancellation.\n *\n * @returns The response headers, streaming body, and HTTP status code.\n */\n async downloadFileByName(\n downloadUrl: string,\n authToken: string,\n bucketName: string,\n fileName: string,\n options?: DownloadFileOptions,\n ): Promise<{\n /** Response headers containing file metadata and B2 info headers. */\n headers: Headers\n /** Streaming response body, or `null` for HEAD-like responses. */\n body: ReadableStream<Uint8Array> | null\n /** HTTP status code (200 for full content, 206 for partial content). */\n status: number\n }> {\n const headers = buildDownloadRequestHeaders(authToken, options)\n const url = appendDownloadOverrides(\n `${downloadUrl}/file/${encodeURIComponent(bucketName)}/${encodeFileName(fileName)}`,\n options,\n )\n\n const response = await this.transport.send({\n url,\n method: options?.method ?? 'GET',\n headers,\n ...(options?.signal !== undefined ? { signal: options.signal } : {}),\n })\n\n return { headers: response.headers, body: response.body, status: response.status }\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-get-download-authorization | b2_get_download_authorization}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The current session authorization token.\n * @param request - The API request parameters.\n *\n * @returns The download authorization token for the specified file prefix.\n */\n async getDownloadAuthorization(\n apiUrl: string,\n authToken: string,\n request: DownloadAuthorizationRequest,\n ): Promise<DownloadAuthorizationResponse> {\n return this.postJson<DownloadAuthorizationResponse>(\n apiUrl,\n authToken,\n 'b2_get_download_authorization',\n request,\n )\n }\n\n // --- Keys ---\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-create-key | b2_create_key}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The newly created application key with secret.\n */\n async createKey(\n apiUrl: string,\n authToken: string,\n request: CreateKeyRequest,\n ): Promise<FullApplicationKey> {\n const key = await this.postJson<FullApplicationKey>(\n apiUrl,\n authToken,\n 'b2_create_key',\n normalizeCreateKeyRequest(request),\n undefined,\n B2_NATIVE_API_V4,\n )\n return normalizeKeyResponse(key)\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-list-keys | b2_list_keys}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The list of application keys and optional continuation token.\n */\n async listKeys(\n apiUrl: string,\n authToken: string,\n request: ListKeysRequest,\n ): Promise<ListKeysResponse> {\n const response = await this.postJson<ListKeysResponse>(\n apiUrl,\n authToken,\n 'b2_list_keys',\n request,\n undefined,\n B2_NATIVE_API_V4,\n )\n return { ...response, keys: response.keys.map((key) => normalizeKeyResponse(key)) }\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-delete-key | b2_delete_key}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The deleted application key metadata.\n */\n async deleteKey(\n apiUrl: string,\n authToken: string,\n request: DeleteKeyRequest,\n ): Promise<ApplicationKey> {\n const key = await this.postJson<ApplicationKey>(\n apiUrl,\n authToken,\n 'b2_delete_key',\n request,\n undefined,\n B2_NATIVE_API_V4,\n )\n return normalizeKeyResponse(key)\n }\n\n // --- Retention / Legal Hold ---\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-update-file-retention | b2_update_file_retention}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The updated file retention settings.\n */\n async updateFileRetention(\n apiUrl: string,\n authToken: string,\n request: UpdateFileRetentionRequest,\n ): Promise<UpdateFileRetentionResponse> {\n return this.postJson<UpdateFileRetentionResponse>(\n apiUrl,\n authToken,\n 'b2_update_file_retention',\n request,\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-update-file-legal-hold | b2_update_file_legal_hold}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The updated file legal hold status.\n */\n async updateFileLegalHold(\n apiUrl: string,\n authToken: string,\n request: UpdateFileLegalHoldRequest,\n ): Promise<UpdateFileLegalHoldResponse> {\n return this.postJson<UpdateFileLegalHoldResponse>(\n apiUrl,\n authToken,\n 'b2_update_file_legal_hold',\n request,\n )\n }\n\n // --- Notifications ---\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-get-bucket-notification-rules | b2_get_bucket_notification_rules}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The configured event notification rules for the specified bucket.\n */\n async getBucketNotificationRules(\n apiUrl: string,\n authToken: string,\n request: GetBucketNotificationRulesRequest,\n ): Promise<GetBucketNotificationRulesResponse> {\n return this.postJson<GetBucketNotificationRulesResponse>(\n apiUrl,\n authToken,\n 'b2_get_bucket_notification_rules',\n request,\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-set-bucket-notification-rules | b2_set_bucket_notification_rules}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The updated bucket notification rules.\n */\n async setBucketNotificationRules(\n apiUrl: string,\n authToken: string,\n request: SetBucketNotificationRulesRequest,\n ): Promise<SetBucketNotificationRulesResponse> {\n return this.postJson<SetBucketNotificationRulesResponse>(\n apiUrl,\n authToken,\n 'b2_set_bucket_notification_rules',\n request,\n )\n }\n\n // --- Internal ---\n\n /**\n * Sends a JSON POST request to the specified B2 API endpoint.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param endpoint - The B2 API endpoint name.\n * @param body - The JSON request body.\n * @param options - Optional abort and per-request retry settings.\n * @param urlOptions - B2 endpoint path prefix and version settings.\n *\n * @returns The parsed JSON response.\n */\n private async postJson<T>(\n apiUrl: string,\n authToken: string,\n endpoint: string,\n body: unknown,\n options?: RawRequestOptions,\n urlOptions: B2EndpointUrlOptions = B2_NATIVE_API_V3,\n ): Promise<T> {\n const response = await this.transport.send({\n url: b2Url(apiUrl, { ...urlOptions, endpoint }),\n method: 'POST',\n headers: {\n Authorization: authToken,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(body),\n ...(options?.signal !== undefined ? { signal: options.signal } : {}),\n ...(options?.retry !== undefined ? { retry: options.retry } : {}),\n })\n return response.json<T>()\n }\n}\n\n// --- Header helpers ---\n\nimport { EncryptionAlgorithm, EncryptionMode, type EncryptionSetting } from '../types/encryption.ts'\nimport type { FileRetentionValue, LegalHoldValue } from '../types/lock.ts'\n\ninterface JsonBodySseCRequest {\n readonly serverSideEncryption?: EncryptionSetting\n readonly sourceServerSideEncryption?: EncryptionSetting\n readonly destinationServerSideEncryption?: EncryptionSetting\n}\n\nfunction withJsonBodyWireSseC<T extends JsonBodySseCRequest>(request: T): T {\n return {\n ...request,\n ...(request.serverSideEncryption !== undefined\n ? { serverSideEncryption: toWireSseC(request.serverSideEncryption) }\n : {}),\n ...(request.sourceServerSideEncryption !== undefined\n ? { sourceServerSideEncryption: toWireSseC(request.sourceServerSideEncryption) }\n : {}),\n ...(request.destinationServerSideEncryption !== undefined\n ? { destinationServerSideEncryption: toWireSseC(request.destinationServerSideEncryption) }\n : {}),\n }\n}\n\nfunction toWireSseC(setting: EncryptionSetting): EncryptionSetting {\n if (setting.mode !== EncryptionMode.SseC) return setting\n // SSE-C settings may be redacted wrappers with non-enumerable key fields.\n // Passing the wrapper through would let toJSON() emit the redaction placeholder;\n // spreading it would drop the key fields. Read directly into a plain wire\n // literal for the B2 JSON body only, and never pass that cleartext literal to\n // diagnostics or logging sinks.\n return {\n mode: EncryptionMode.SseC,\n algorithm: setting.algorithm,\n customerKey: setting.customerKey,\n customerKeyMd5: setting.customerKeyMd5,\n }\n}\n\n/**\n * Applies server-side encryption headers to the request.\n * @param headers - The mutable headers object to populate.\n * @param encryption - The encryption settings, or undefined to skip.\n */\nfunction applyEncryptionHeaders(\n headers: Record<string, string>,\n encryption: EncryptionSetting | undefined,\n): void {\n if (!encryption || encryption.mode === EncryptionMode.None) return\n if (encryption.mode === EncryptionMode.SseB2) {\n headers['X-Bz-Server-Side-Encryption'] = EncryptionAlgorithm.Aes256\n } else if (encryption.mode === EncryptionMode.SseC) {\n headers['X-Bz-Server-Side-Encryption-Customer-Algorithm'] = EncryptionAlgorithm.Aes256\n headers['X-Bz-Server-Side-Encryption-Customer-Key'] = encryption.customerKey\n headers['X-Bz-Server-Side-Encryption-Customer-Key-Md5'] = encryption.customerKeyMd5\n }\n}\n\n/**\n * SSE-C decryption parameters supplied to downloads of files that were\n * uploaded with customer-managed keys.\n */\nexport interface SseCDownloadKey {\n /** Encryption algorithm. Always `EncryptionAlgorithm.Aes256` (`'AES256'`). */\n readonly algorithm: EncryptionAlgorithm\n /**\n * Base64-encoded customer-provided decryption key. This value must be sent as\n * an HTTP request header for SSE-C downloads, so custom transports should not\n * log request headers without redacting them first.\n */\n readonly customerKey: string\n /** Base64-encoded MD5 digest of the decryption key. */\n readonly customerKeyMd5: string\n}\n\n/**\n * Options accepted by {@link RawClient.downloadFileById} and\n * {@link RawClient.downloadFileByName}. Mirrors the B2 native API: range +\n * SSE-C decryption headers + the documented `b2Content*` response-header\n * overrides (query-string parameters on the request URL).\n */\nexport interface DownloadFileOptions {\n /** HTTP method. Defaults to `'GET'`. Use `'HEAD'` to fetch headers without the body. */\n readonly method?: 'GET' | 'HEAD'\n /** HTTP Range header value for partial content requests. */\n readonly range?: string\n /** SSE-C decryption parameters, required if the file was uploaded with SSE-C. */\n readonly serverSideEncryption?: SseCDownloadKey\n /** Override the `Content-Disposition` header in the download response. */\n readonly b2ContentDisposition?: string\n /** Override the `Content-Language` header in the download response. */\n readonly b2ContentLanguage?: string\n /** Override the `Content-Encoding` header in the download response. */\n readonly b2ContentEncoding?: string\n /** Override the `Content-Type` header in the download response. */\n readonly b2ContentType?: string\n /** Override the `Cache-Control` header in the download response. */\n readonly b2CacheControl?: string\n /** Override the `Expires` header in the download response. */\n readonly b2Expires?: string\n /** Signal to abort the download. */\n readonly signal?: AbortSignal\n}\n\nconst DOWNLOAD_OVERRIDE_PARAMS = [\n 'b2ContentDisposition',\n 'b2ContentLanguage',\n 'b2ContentEncoding',\n 'b2ContentType',\n 'b2CacheControl',\n 'b2Expires',\n] as const\n\n/**\n * Builds the HTTP request headers for a download: Authorization, optional\n * Range, and optional SSE-C decryption headers.\n *\n * @param authToken - The B2 session authorization token.\n * @param options - Caller-supplied download options.\n *\n * @returns The header map to send with the request.\n */\nfunction buildDownloadRequestHeaders(\n authToken: string,\n options: DownloadFileOptions | undefined,\n): Record<string, string> {\n const headers: Record<string, string> = { Authorization: authToken }\n if (options?.range) headers['Range'] = options.range\n if (options?.serverSideEncryption) {\n const encryption = options.serverSideEncryption\n // SSE-C keys may be redacted wrappers with non-enumerable key fields.\n // Read fields directly; object spread would drop the wire header values.\n applyEncryptionHeaders(headers, {\n mode: EncryptionMode.SseC,\n algorithm: encryption.algorithm,\n customerKey: encryption.customerKey,\n customerKeyMd5: encryption.customerKeyMd5,\n })\n }\n return headers\n}\n\n/**\n * Appends the documented `b2Content*` response-header overrides to a download\n * URL as query-string parameters. B2 echoes the values into the response\n * headers so callers can control content type, disposition, and caching.\n *\n * @param url - The base download URL.\n * @param options - Caller-supplied download options.\n *\n * @returns The URL with any override parameters appended.\n */\nfunction appendDownloadOverrides(url: string, options: DownloadFileOptions | undefined): string {\n if (!options) return url\n const params: string[] = []\n for (const key of DOWNLOAD_OVERRIDE_PARAMS) {\n const value = options[key]\n if (value !== undefined) {\n params.push(`${key}=${encodeURIComponent(value)}`)\n }\n }\n if (params.length === 0) return url\n const separator = url.includes('?') ? '&' : '?'\n return `${url}${separator}${params.join('&')}`\n}\n\n/**\n * Applies file retention headers to the request.\n * @param headers - The mutable headers object to populate.\n * @param retention - The retention settings, or undefined to skip.\n */\nfunction applyRetentionHeaders(\n headers: Record<string, string>,\n retention: FileRetentionValue | undefined,\n): void {\n if (!retention) return\n if (retention.mode) {\n headers['X-Bz-File-Retention-Mode'] = retention.mode\n }\n if (retention.retainUntilTimestamp) {\n headers['X-Bz-File-Retention-Retain-Until-Timestamp'] = String(retention.retainUntilTimestamp)\n }\n}\n\n/**\n * Applies the legal hold header to the request.\n * @param headers - The mutable headers object to populate.\n * @param legalHold - The legal hold value, or undefined to skip.\n */\nfunction applyLegalHoldHeader(\n headers: Record<string, string>,\n legalHold: LegalHoldValue | undefined,\n): void {\n if (!legalHold) return\n headers['X-Bz-File-Legal-Hold'] = legalHold\n}\n\nexport {\n buildFileInfoHeaders,\n decodeFileName,\n encodeFileName,\n parseFileInfoHeaders,\n} from './encoding.ts'\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/raw/index.ts"],"sourcesContent":["/**\n * Low-level 1:1 bindings for every B2 native API endpoint.\n *\n * Each method on {@link RawClient} maps directly to a single `b2_*` HTTP call\n * with fully typed request and response objects. No retry logic, no URL pooling,\n * no automatic reauthorization. Use this when you need precise control over\n * individual API calls; for most use cases prefer the high-level `B2Client`.\n * SDK-built B2 native storage API URLs use `/b2api/v4`. JSON endpoints use\n * POST request bodies, including read/list endpoints whose API docs also show\n * GET query examples but document POST JSON compatibility.\n *\n * @packageDocumentation\n */\n\nimport { assertSecureRealmUrl } from '../auth/realms.ts'\nimport { assertValidBucketConfiguration } from '../bucket-validation.ts'\nimport { FinishLargeFileResponseBodyError, UploadResponseBodyError } from '../errors/index.ts'\nimport type { RetryOptions } from '../http/retry.ts'\nimport type { HttpTransport } from '../http/transport.ts'\nimport type {\n AllowedBucket,\n ApplicationKey,\n AuthorizeAccountResponse,\n BucketId,\n BucketInfo,\n CancelLargeFileRequest,\n CancelLargeFileResponse,\n CopyFileRequest,\n CopyPartRequest,\n CopyPartResponse,\n CreateBucketRequest,\n CreateKeyRequest,\n DeleteBucketRequest,\n DeleteFileVersionRequest,\n DeleteFileVersionResponse,\n DeleteKeyRequest,\n DownloadAuthorizationRequest,\n DownloadAuthorizationResponse,\n FileVersion,\n FinishLargeFileRequest,\n FullApplicationKey,\n GetBucketNotificationRulesRequest,\n GetBucketNotificationRulesResponse,\n GetFileInfoRequest,\n GetUploadPartUrlRequest,\n GetUploadPartUrlResponse,\n GetUploadUrlRequest,\n GetUploadUrlResponse,\n HideFileRequest,\n ListBucketsRequest,\n ListBucketsResponse,\n ListFileNamesMaybeDelimiterRequest,\n ListFileNamesRequest,\n ListFileNamesResponse,\n ListFileNamesWithDelimiterRequest,\n ListFileNamesWithDelimiterResponse,\n ListFileVersionsMaybeDelimiterRequest,\n ListFileVersionsRequest,\n ListFileVersionsResponse,\n ListFileVersionsWithDelimiterRequest,\n ListFileVersionsWithDelimiterResponse,\n ListKeysRequest,\n ListKeysResponse,\n ListPartsRequest,\n ListPartsResponse,\n ListUnfinishedLargeFilesRequest,\n ListUnfinishedLargeFilesResponse,\n SetBucketNotificationRulesRequest,\n SetBucketNotificationRulesResponse,\n StartLargeFileRequest,\n StartLargeFileResponse,\n UpdateBucketRequest,\n UpdateFileLegalHoldRequest,\n UpdateFileLegalHoldResponse,\n UpdateFileRetentionRequest,\n UpdateFileRetentionResponse,\n} from '../types/index.ts'\nimport type { UploadFileHeaders, UploadPartHeaders, UploadPartResponse } from '../types/upload.ts'\nimport { normalizeFileVersionListSha1, normalizeFileVersionSha1 } from '../util/normalize.ts'\nimport { buildFileInfoHeaders, encodeFileName } from './encoding.ts'\nimport { type B2EndpointUrlOptions, b2Url } from './url.ts'\n\nexport {\n assertValidBucketConfiguration,\n assertValidBucketInfo,\n assertValidCorsRules,\n} from '../bucket-validation.ts'\nexport {\n BUCKET_INFO_KEY_MAX_BYTES,\n BUCKET_INFO_KEY_MIN_BYTES,\n BUCKET_INFO_KEY_PATTERN,\n BUCKET_INFO_RESERVED_PREFIX,\n BUCKET_INFO_VALUES_MAX_BYTES,\n BucketKeyOption,\n CORS_ALLOWED_OPERATIONS,\n CORS_MAX_AGE_SECONDS_MAX,\n CORS_RULE_MAX_BYTES,\n CORS_RULE_NAME_MAX_LENGTH,\n CORS_RULE_NAME_MIN_LENGTH,\n CORS_RULE_NAME_PATTERN,\n CORS_RULE_NAME_RESERVED_PREFIX,\n CORS_RULES_MAX_COUNT,\n CorsOperation,\n} from '../types/bucket.ts'\n\nconst B2_NATIVE_API: B2EndpointUrlOptions = { prefix: 'b2api', version: 'v4' }\n\n/** Configuration for constructing a {@link RawClient}. */\nexport interface RawClientOptions {\n /** The HTTP transport used to send requests (e.g., FetchTransport or RetryTransport). */\n readonly transport: HttpTransport\n}\n\n/** Optional request controls for {@link RawClient.listFileNames}. */\nexport type ListFileNamesOptions = RawRequestOptions\n\n/** Optional request controls for {@link RawClient.authorizeAccount}. */\nexport type AuthorizeAccountOptions = RawRequestOptions\n\n/** Optional request controls for {@link RawClient.listFileVersions}. */\nexport type ListFileVersionsOptions = RawRequestOptions\n\n/** Optional controls for raw JSON API requests. */\nexport interface RawRequestOptions {\n /** Abort signal for cancelling the request. */\n readonly signal?: AbortSignal\n /** Per-request retry override. */\n readonly retry?: Partial<RetryOptions>\n}\n\n/**\n * @deprecated Use {@link RawRequestOptions}.\n */\nexport type JsonPostOptions = RawRequestOptions\n\n/** Optional request controls for {@link RawClient.finishLargeFile}. */\nexport type FinishLargeFileOptions = RawRequestOptions\n\n/** Optional request controls for {@link RawClient.copyPart}. */\nexport type CopyPartOptions = RawRequestOptions\n\n/** Optional request controls for {@link RawClient.startLargeFile}. */\nexport type StartLargeFileOptions = RawRequestOptions\n\n/** Optional request controls for {@link RawClient.uploadFile}. */\nexport type UploadFileOptions = RawRequestOptions\n\n/** Optional request controls for {@link RawClient.uploadPart}. */\nexport type UploadPartOptions = RawRequestOptions\n\nfunction normalizeRawRequestOptions(\n optionsOrSignal?: RawRequestOptions | AbortSignal,\n retry?: Partial<RetryOptions>,\n): RawRequestOptions | undefined {\n if (optionsOrSignal === undefined) {\n return retry === undefined ? undefined : { retry }\n }\n if (isAbortSignal(optionsOrSignal)) {\n return {\n signal: optionsOrSignal,\n ...(retry !== undefined ? { retry } : {}),\n }\n }\n return retry === undefined ? optionsOrSignal : { ...optionsOrSignal, retry }\n}\n\nfunction isAbortSignal(value: unknown): value is AbortSignal {\n // Back-compat only: legacy upload-URL overloads accepted an AbortSignal as\n // the fourth positional argument. Prefer the RawRequestOptions bag.\n return (\n typeof value === 'object' &&\n value !== null &&\n 'aborted' in value &&\n typeof (value as AbortSignal).addEventListener === 'function'\n )\n}\n\nfunction assertCustomUploadTimestamp(value: unknown): asserts value is number {\n if (value === undefined) return\n if (typeof value === 'number' && Number.isSafeInteger(value) && value >= 0) return\n throw new TypeError('customUploadTimestamp must be a non-negative safe integer')\n}\n\nfunction assertSafeHttpHeaderValue(name: string, value: string): void {\n if (hasHttpHeaderControlByte(value)) {\n throw new TypeError(`${name} must not contain HTTP control characters`)\n }\n}\n\nfunction hasHttpHeaderControlByte(value: string): boolean {\n for (let i = 0; i < value.length; i += 1) {\n const code = value.charCodeAt(i)\n if (code <= 0x1f || code === 0x7f) return true\n }\n return false\n}\n\nfunction setB2ContentFileInfoHeader(\n headers: Record<string, string>,\n key: string,\n optionName: string,\n value: string | undefined,\n): void {\n if (!value) return\n assertSafeHttpHeaderValue(optionName, value)\n Object.assign(headers, buildFileInfoHeaders({ [key]: value }))\n}\n\nfunction assertRawCustomUploadTimestamp(\n value: unknown,\n): asserts value is string | null | undefined {\n if (value === undefined || value === null) return\n if (typeof value === 'string' && /^\\d+$/.test(value)) {\n const timestamp = Number(value)\n if (Number.isSafeInteger(timestamp)) return\n }\n throw new TypeError('customUploadTimestamp must be a non-negative safe integer string or null')\n}\n\nfunction normalizeCreateKeyRequest(request: CreateKeyRequest): CreateKeyRequest {\n const { bucketId, ...withoutDeprecatedBucketId } = request\n if (bucketId !== undefined && withoutDeprecatedBucketId.bucketIds !== undefined) {\n throw new TypeError('createKey accepts either bucketIds or deprecated bucketId, not both')\n }\n if (bucketId === undefined) {\n return withoutDeprecatedBucketId\n }\n return { ...withoutDeprecatedBucketId, bucketIds: [bucketId] }\n}\n\nfunction singleBucketId(bucketIds: readonly BucketId[] | null): BucketId | null {\n return bucketIds?.length === 1 ? (bucketIds[0] ?? null) : null\n}\n\nfunction normalizeKeyResponse<T extends { readonly bucketIds: readonly BucketId[] | null }>(\n key: T,\n): T & { readonly bucketId: BucketId | null } {\n return { ...key, bucketId: singleBucketId(key.bucketIds) }\n}\n\ntype NormalizedAllowedInfo = AuthorizeAccountResponse['apiInfo']['storageApi']['allowed']\ntype NormalizedStorageApiInfo = AuthorizeAccountResponse['apiInfo']['storageApi']\n\ninterface WireAllowedInfo {\n readonly capabilities?: NormalizedAllowedInfo['capabilities']\n readonly buckets?: readonly AllowedBucket[] | null\n readonly bucketId?: BucketId | null\n readonly bucketName?: string | null\n readonly namePrefix?: string | null\n}\n\ntype WireStorageApiInfo = Omit<\n NormalizedStorageApiInfo,\n 'allowed' | 'bucketId' | 'bucketName' | 'infoType' | 'namePrefix'\n> & {\n readonly allowed?: WireAllowedInfo\n readonly capabilities?: NormalizedAllowedInfo['capabilities']\n readonly bucketId?: BucketId | null\n readonly bucketName?: string | null\n readonly infoType?: 'storageApi'\n readonly namePrefix?: string | null\n}\n\ntype WireAuthorizeAccountResponse = Omit<AuthorizeAccountResponse, 'apiInfo'> & {\n readonly apiInfo: Omit<AuthorizeAccountResponse['apiInfo'], 'storageApi'> & {\n readonly storageApi: WireStorageApiInfo\n }\n}\n\nfunction normalizeAllowedBuckets(storageApi: WireStorageApiInfo): readonly AllowedBucket[] | null {\n const allowed = storageApi.allowed\n if (allowed?.buckets !== undefined) {\n return allowed.buckets === null ? null : allowed.buckets.map((bucket) => ({ ...bucket }))\n }\n const bucketId = allowed?.bucketId ?? storageApi.bucketId ?? null\n if (bucketId === null) return null\n return [{ id: bucketId, name: allowed?.bucketName ?? storageApi.bucketName ?? null }]\n}\n\nfunction normalizeAuthorizeAccountResponse(\n response: WireAuthorizeAccountResponse,\n): AuthorizeAccountResponse {\n const storageApi = response.apiInfo.storageApi\n const allowed = storageApi.allowed\n const buckets = normalizeAllowedBuckets(storageApi)\n const singleBucket = buckets?.length === 1 ? buckets[0] : undefined\n const bucketId = singleBucket?.id ?? null\n const bucketName = singleBucket?.name ?? null\n const namePrefix = allowed?.namePrefix ?? storageApi.namePrefix ?? null\n const capabilities = allowed?.capabilities ?? storageApi.capabilities ?? []\n const { allowed: _wireAllowed, capabilities: _legacyCapabilities, ...storageApiBase } = storageApi\n\n return {\n ...response,\n apiInfo: {\n ...response.apiInfo,\n storageApi: {\n ...storageApiBase,\n bucketId,\n bucketName,\n downloadUrl: storageApi.downloadUrl,\n infoType: 'storageApi',\n namePrefix,\n allowed: {\n ...(allowed ?? {}),\n capabilities,\n buckets,\n bucketId,\n bucketName,\n namePrefix,\n },\n },\n },\n }\n}\n\nfunction uploadResponseBodyError(\n err: unknown,\n signal: AbortSignal | undefined,\n): UploadResponseBodyError {\n if (signal?.aborted === true) {\n throw signal.reason ?? new DOMException('Aborted', 'AbortError')\n }\n const message = err instanceof Error ? err.message : 'Upload response body could not be read'\n return new UploadResponseBodyError(message, { cause: err })\n}\n\n/**\n * Low-level client providing 1:1 bindings to all B2 native API endpoints.\n *\n * Each method maps directly to a single B2 API call. Most methods accept\n * `(apiUrl, authToken, request)` and return the JSON response. Upload and\n * download methods accept endpoint-specific parameters instead.\n */\nexport class RawClient {\n /** @internal */\n private readonly transport: HttpTransport\n\n /**\n * Creates a new RawClient with the given transport.\n * @param options - The constructor configuration.\n */\n constructor(options: RawClientOptions) {\n this.transport = options.transport\n }\n\n // --- Auth ---\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-authorize-account | b2_authorize_account}.\n * @param applicationKeyId - The application key ID for authentication.\n * @param applicationKey - The application key secret.\n * @param realmUrl - The B2 realm URL to authenticate against.\n * @param options - Optional request controls.\n *\n * @returns The authorization response with API URLs and credentials.\n */\n async authorizeAccount(\n applicationKeyId: string,\n applicationKey: string,\n realmUrl = 'https://api.backblazeb2.com',\n options?: AuthorizeAccountOptions,\n ): Promise<AuthorizeAccountResponse> {\n assertSecureRealmUrl(realmUrl)\n const response = await this.transport.send({\n url: b2Url(realmUrl, { ...B2_NATIVE_API, endpoint: 'b2_authorize_account' }),\n method: 'GET',\n headers: {\n Authorization: `Basic ${btoa(`${applicationKeyId}:${applicationKey}`)}`,\n },\n ...(options?.signal !== undefined ? { signal: options.signal } : {}),\n ...(options?.retry !== undefined ? { retry: options.retry } : {}),\n })\n return normalizeAuthorizeAccountResponse(await response.json<WireAuthorizeAccountResponse>())\n }\n\n // --- Buckets ---\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-create-bucket | b2_create_bucket}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The created bucket metadata.\n */\n async createBucket(\n apiUrl: string,\n authToken: string,\n request: CreateBucketRequest,\n ): Promise<BucketInfo> {\n assertValidBucketConfiguration(request)\n return this.postJson<BucketInfo>(apiUrl, authToken, 'b2_create_bucket', request)\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-delete-bucket | b2_delete_bucket}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The deleted bucket metadata.\n */\n async deleteBucket(\n apiUrl: string,\n authToken: string,\n request: DeleteBucketRequest,\n ): Promise<BucketInfo> {\n return this.postJson<BucketInfo>(apiUrl, authToken, 'b2_delete_bucket', request)\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-list-buckets | b2_list_buckets}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The list of matching buckets.\n */\n async listBuckets(\n apiUrl: string,\n authToken: string,\n request: ListBucketsRequest,\n ): Promise<ListBucketsResponse> {\n return this.postJson<ListBucketsResponse>(apiUrl, authToken, 'b2_list_buckets', request)\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-update-bucket | b2_update_bucket}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The updated bucket metadata.\n */\n async updateBucket(\n apiUrl: string,\n authToken: string,\n request: UpdateBucketRequest,\n ): Promise<BucketInfo> {\n assertValidBucketConfiguration(request)\n return this.postJson<BucketInfo>(apiUrl, authToken, 'b2_update_bucket', request)\n }\n\n // --- Files ---\n\n /**\n * Calls `b2_get_upload_url` with legacy positional request controls.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param signal - Optional abort signal for cancellation.\n * @param retry - Optional per-request retry override.\n *\n * @returns The upload URL and authorization token.\n *\n * @deprecated Use the options-bag overload: `getUploadUrl(apiUrl, authToken, request, { signal, retry })`.\n */\n async getUploadUrl(\n apiUrl: string,\n authToken: string,\n request: GetUploadUrlRequest,\n signal?: AbortSignal,\n retry?: Partial<RetryOptions>,\n ): Promise<GetUploadUrlResponse>\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-get-upload-url | b2_get_upload_url}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional request controls such as cancellation and retry overrides.\n *\n * @returns The upload URL and authorization token.\n */\n async getUploadUrl(\n apiUrl: string,\n authToken: string,\n request: GetUploadUrlRequest,\n options?: RawRequestOptions,\n ): Promise<GetUploadUrlResponse>\n /**\n * Implementation for both upload URL request-control signatures.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param optionsOrSignal - Options bag or legacy abort signal.\n * @param retry - Optional legacy per-request retry override.\n *\n * @returns The upload URL and authorization token.\n */\n async getUploadUrl(\n apiUrl: string,\n authToken: string,\n request: GetUploadUrlRequest,\n optionsOrSignal?: RawRequestOptions | AbortSignal,\n retry?: Partial<RetryOptions>,\n ): Promise<GetUploadUrlResponse> {\n return this.postJson<GetUploadUrlResponse>(\n apiUrl,\n authToken,\n 'b2_get_upload_url',\n request,\n normalizeRawRequestOptions(optionsOrSignal, retry),\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-upload-file | b2_upload_file}.\n *\n * Unlike most methods, this posts directly to the `uploadUrl` obtained\n * from {@link getUploadUrl} rather than the API URL.\n * @param uploadUrl - The upload endpoint URL.\n * @param headers - The request headers including authorization and content metadata.\n * @param body - The file data to upload.\n * @param signal - Optional legacy abort signal for cancellation.\n * @param retry - Optional legacy per-request retry override.\n *\n * @returns The uploaded file version metadata.\n *\n * @deprecated Use the options-bag overload: `uploadFile(uploadUrl, headers, body, { signal, retry })`.\n */\n async uploadFile(\n uploadUrl: string,\n headers: UploadFileHeaders,\n body: BodyInit,\n signal?: AbortSignal,\n retry?: Partial<RetryOptions>,\n ): Promise<FileVersion>\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-upload-file | b2_upload_file}.\n *\n * Unlike most methods, this posts directly to the `uploadUrl` obtained\n * from {@link getUploadUrl} rather than the API URL.\n * @param uploadUrl - The upload endpoint URL.\n * @param headers - The request headers including authorization and content metadata.\n * @param body - The file data to upload.\n * @param options - Optional request controls such as cancellation and retry overrides.\n *\n * @returns The uploaded file version metadata.\n */\n async uploadFile(\n uploadUrl: string,\n headers: UploadFileHeaders,\n body: BodyInit,\n options?: UploadFileOptions,\n ): Promise<FileVersion>\n /**\n * Implementation for both upload-file request-control signatures.\n * @param uploadUrl - The upload endpoint URL.\n * @param headers - The request headers including authorization and content metadata.\n * @param body - The file data to upload.\n * @param optionsOrSignal - Options bag or legacy abort signal.\n * @param retry - Optional legacy per-request retry override.\n *\n * @returns The uploaded file version metadata.\n */\n async uploadFile(\n uploadUrl: string,\n headers: UploadFileHeaders,\n body: BodyInit,\n optionsOrSignal?: UploadFileOptions | AbortSignal,\n retry?: Partial<RetryOptions>,\n ): Promise<FileVersion> {\n const options = normalizeRawRequestOptions(optionsOrSignal, retry)\n assertSafeHttpHeaderValue('authorization', headers.authorization)\n assertSafeHttpHeaderValue('contentType', headers.contentType)\n assertSafeHttpHeaderValue('contentSha1', headers.contentSha1)\n const reqHeaders: Record<string, string> = {\n Authorization: headers.authorization,\n 'X-Bz-File-Name': encodeFileName(headers.fileName),\n 'Content-Type': headers.contentType,\n 'Content-Length': String(headers.contentLength),\n 'X-Bz-Content-Sha1': headers.contentSha1,\n ...buildFileInfoHeaders(headers.fileInfo),\n }\n\n if (headers.lastModifiedMillis !== undefined) {\n reqHeaders['X-Bz-Info-src_last_modified_millis'] = String(headers.lastModifiedMillis)\n }\n if (headers.customUploadTimestamp !== undefined) {\n assertCustomUploadTimestamp(headers.customUploadTimestamp)\n reqHeaders['X-Bz-Custom-Upload-Timestamp'] = String(headers.customUploadTimestamp)\n }\n setB2ContentFileInfoHeader(\n reqHeaders,\n 'b2-content-disposition',\n 'contentDisposition',\n headers.contentDisposition,\n )\n setB2ContentFileInfoHeader(\n reqHeaders,\n 'b2-content-language',\n 'contentLanguage',\n headers.contentLanguage,\n )\n setB2ContentFileInfoHeader(reqHeaders, 'b2-expires', 'expires', headers.expires)\n setB2ContentFileInfoHeader(reqHeaders, 'b2-cache-control', 'cacheControl', headers.cacheControl)\n setB2ContentFileInfoHeader(\n reqHeaders,\n 'b2-content-encoding',\n 'contentEncoding',\n headers.contentEncoding,\n )\n\n applyEncryptionHeaders(reqHeaders, headers.serverSideEncryption)\n applyRetentionHeaders(reqHeaders, headers.fileRetention)\n applyLegalHoldHeader(reqHeaders, headers.legalHold)\n\n const response = await this.transport.send({\n url: uploadUrl,\n method: 'POST',\n headers: reqHeaders,\n body,\n ...(options?.signal !== undefined ? { signal: options.signal } : {}),\n ...(options?.retry !== undefined ? { retry: options.retry } : {}),\n })\n try {\n return normalizeFileVersionSha1(await response.json<FileVersion>())\n } catch (err) {\n throw uploadResponseBodyError(err, options?.signal)\n }\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-list-file-names | b2_list_file_names}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional request controls such as an abort signal.\n *\n * @returns The list of file names and optional continuation token. Requests\n * with `delimiter` use the delimiter overload and may include virtual\n * folder rows.\n */\n async listFileNames(\n apiUrl: string,\n authToken: string,\n request: ListFileNamesWithDelimiterRequest,\n options?: ListFileNamesOptions,\n ): Promise<ListFileNamesWithDelimiterResponse>\n async listFileNames(\n apiUrl: string,\n authToken: string,\n request: ListFileNamesRequest,\n options?: ListFileNamesOptions,\n ): Promise<ListFileNamesResponse>\n async listFileNames(\n apiUrl: string,\n authToken: string,\n request: ListFileNamesMaybeDelimiterRequest,\n options?: ListFileNamesOptions,\n ): Promise<ListFileNamesResponse | ListFileNamesWithDelimiterResponse>\n async listFileNames(\n apiUrl: string,\n authToken: string,\n request:\n | ListFileNamesRequest\n | ListFileNamesWithDelimiterRequest\n | ListFileNamesMaybeDelimiterRequest,\n options?: ListFileNamesOptions,\n ): Promise<ListFileNamesResponse | ListFileNamesWithDelimiterResponse> {\n return normalizeFileVersionListSha1(\n await this.postJson<ListFileNamesResponse | ListFileNamesWithDelimiterResponse>(\n apiUrl,\n authToken,\n 'b2_list_file_names',\n request,\n options,\n ),\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-list-file-versions | b2_list_file_versions}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional request controls such as an abort signal.\n *\n * @returns The list of file versions and optional continuation token.\n * Requests with `delimiter` use the delimiter overload and may include\n * virtual folder rows.\n */\n async listFileVersions(\n apiUrl: string,\n authToken: string,\n request: ListFileVersionsWithDelimiterRequest,\n options?: ListFileVersionsOptions,\n ): Promise<ListFileVersionsWithDelimiterResponse>\n async listFileVersions(\n apiUrl: string,\n authToken: string,\n request: ListFileVersionsRequest,\n options?: ListFileVersionsOptions,\n ): Promise<ListFileVersionsResponse>\n async listFileVersions(\n apiUrl: string,\n authToken: string,\n request: ListFileVersionsMaybeDelimiterRequest,\n options?: ListFileVersionsOptions,\n ): Promise<ListFileVersionsResponse | ListFileVersionsWithDelimiterResponse>\n async listFileVersions(\n apiUrl: string,\n authToken: string,\n request:\n | ListFileVersionsRequest\n | ListFileVersionsWithDelimiterRequest\n | ListFileVersionsMaybeDelimiterRequest,\n options?: ListFileVersionsOptions,\n ): Promise<ListFileVersionsResponse | ListFileVersionsWithDelimiterResponse> {\n return normalizeFileVersionListSha1(\n await this.postJson<ListFileVersionsResponse | ListFileVersionsWithDelimiterResponse>(\n apiUrl,\n authToken,\n 'b2_list_file_versions',\n request,\n options,\n ),\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-get-file-info | b2_get_file_info}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The file version metadata.\n */\n async getFileInfo(\n apiUrl: string,\n authToken: string,\n request: GetFileInfoRequest,\n ): Promise<FileVersion> {\n return normalizeFileVersionSha1(\n await this.postJson<FileVersion>(apiUrl, authToken, 'b2_get_file_info', request),\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-hide-file | b2_hide_file}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional request controls such as an abort signal.\n *\n * @returns The hidden file version metadata.\n */\n async hideFile(\n apiUrl: string,\n authToken: string,\n request: HideFileRequest,\n options?: { readonly signal?: AbortSignal },\n ): Promise<FileVersion> {\n return normalizeFileVersionSha1(\n await this.postJson<FileVersion>(apiUrl, authToken, 'b2_hide_file', request, options),\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-delete-file-version | b2_delete_file_version}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional request controls such as an abort signal.\n *\n * @returns The deleted file version identifier.\n */\n async deleteFileVersion(\n apiUrl: string,\n authToken: string,\n request: DeleteFileVersionRequest,\n options?: { readonly signal?: AbortSignal },\n ): Promise<DeleteFileVersionResponse> {\n return this.postJson<DeleteFileVersionResponse>(\n apiUrl,\n authToken,\n 'b2_delete_file_version',\n request,\n options,\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-copy-file | b2_copy_file}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional request controls such as an abort signal.\n *\n * @returns The copied file version metadata.\n */\n async copyFile(\n apiUrl: string,\n authToken: string,\n request: CopyFileRequest,\n options?: RawRequestOptions,\n ): Promise<FileVersion> {\n return normalizeFileVersionSha1(\n await this.postJson<FileVersion>(\n apiUrl,\n authToken,\n 'b2_copy_file',\n withJsonBodyWireSseC(request),\n options,\n ),\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-copy-part | b2_copy_part}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional abort and retry controls.\n *\n * @returns The copied part metadata.\n */\n async copyPart(\n apiUrl: string,\n authToken: string,\n request: CopyPartRequest,\n options?: CopyPartOptions,\n ): Promise<CopyPartResponse> {\n return this.postJson<CopyPartResponse>(\n apiUrl,\n authToken,\n 'b2_copy_part',\n withJsonBodyWireSseC(request),\n options,\n )\n }\n\n // --- Large Files ---\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-start-large-file | b2_start_large_file}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional abort and retry controls.\n *\n * @returns The started large file metadata with file ID.\n */\n async startLargeFile(\n apiUrl: string,\n authToken: string,\n request: StartLargeFileRequest,\n options?: StartLargeFileOptions,\n ): Promise<StartLargeFileResponse> {\n assertRawCustomUploadTimestamp(request.customUploadTimestamp)\n return normalizeFileVersionSha1(\n await this.postJson<StartLargeFileResponse>(\n apiUrl,\n authToken,\n 'b2_start_large_file',\n withJsonBodyWireSseC(request),\n options,\n ),\n )\n }\n\n /**\n * Calls `b2_get_upload_part_url` with legacy positional request controls.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param signal - Optional abort signal for cancellation.\n * @param retry - Optional per-request retry override.\n *\n * @returns The upload part URL and authorization token.\n *\n * @deprecated Use the options-bag overload: `getUploadPartUrl(apiUrl, authToken, request, { signal, retry })`.\n */\n async getUploadPartUrl(\n apiUrl: string,\n authToken: string,\n request: GetUploadPartUrlRequest,\n signal?: AbortSignal,\n retry?: Partial<RetryOptions>,\n ): Promise<GetUploadPartUrlResponse>\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-get-upload-part-url | b2_get_upload_part_url}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional request controls such as cancellation and retry overrides.\n *\n * @returns The upload part URL and authorization token.\n */\n async getUploadPartUrl(\n apiUrl: string,\n authToken: string,\n request: GetUploadPartUrlRequest,\n options?: RawRequestOptions,\n ): Promise<GetUploadPartUrlResponse>\n /**\n * Implementation for both upload part URL request-control signatures.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param optionsOrSignal - Options bag or legacy abort signal.\n * @param retry - Optional legacy per-request retry override.\n *\n * @returns The upload part URL and authorization token.\n */\n async getUploadPartUrl(\n apiUrl: string,\n authToken: string,\n request: GetUploadPartUrlRequest,\n optionsOrSignal?: RawRequestOptions | AbortSignal,\n retry?: Partial<RetryOptions>,\n ): Promise<GetUploadPartUrlResponse> {\n return this.postJson<GetUploadPartUrlResponse>(\n apiUrl,\n authToken,\n 'b2_get_upload_part_url',\n request,\n normalizeRawRequestOptions(optionsOrSignal, retry),\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-upload-part | b2_upload_part}.\n *\n * Posts directly to the `uploadUrl` obtained from {@link getUploadPartUrl}\n * rather than the API URL.\n * @param uploadUrl - The upload endpoint URL.\n * @param headers - The request headers including authorization and content metadata.\n * @param body - The file data to upload.\n * @param signal - Optional legacy abort signal for cancellation.\n * @param retry - Optional legacy per-request retry override.\n *\n * @returns The uploaded part metadata.\n *\n * @deprecated Use the options-bag overload: `uploadPart(uploadUrl, headers, body, { signal, retry })`.\n */\n async uploadPart(\n uploadUrl: string,\n headers: UploadPartHeaders,\n body: BodyInit,\n signal?: AbortSignal,\n retry?: Partial<RetryOptions>,\n ): Promise<UploadPartResponse>\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-upload-part | b2_upload_part}.\n *\n * Posts directly to the `uploadUrl` obtained from {@link getUploadPartUrl}\n * rather than the API URL.\n * @param uploadUrl - The upload endpoint URL.\n * @param headers - The request headers including authorization and content metadata.\n * @param body - The file data to upload.\n * @param options - Optional request controls such as cancellation and retry overrides.\n *\n * @returns The uploaded part metadata.\n */\n async uploadPart(\n uploadUrl: string,\n headers: UploadPartHeaders,\n body: BodyInit,\n options?: UploadPartOptions,\n ): Promise<UploadPartResponse>\n /**\n * Implementation for both upload-part request-control signatures.\n * @param uploadUrl - The upload endpoint URL.\n * @param headers - The request headers including authorization and content metadata.\n * @param body - The file data to upload.\n * @param optionsOrSignal - Options bag or legacy abort signal.\n * @param retry - Optional legacy per-request retry override.\n *\n * @returns The uploaded part metadata.\n */\n async uploadPart(\n uploadUrl: string,\n headers: UploadPartHeaders,\n body: BodyInit,\n optionsOrSignal?: UploadPartOptions | AbortSignal,\n retry?: Partial<RetryOptions>,\n ): Promise<UploadPartResponse> {\n const options = normalizeRawRequestOptions(optionsOrSignal, retry)\n assertSafeHttpHeaderValue('authorization', headers.authorization)\n assertSafeHttpHeaderValue('contentSha1', headers.contentSha1)\n const reqHeaders: Record<string, string> = {\n Authorization: headers.authorization,\n 'X-Bz-Part-Number': String(headers.partNumber),\n 'Content-Length': String(headers.contentLength),\n 'X-Bz-Content-Sha1': headers.contentSha1,\n }\n\n applyEncryptionHeaders(reqHeaders, headers.serverSideEncryption)\n\n const response = await this.transport.send({\n url: uploadUrl,\n method: 'POST',\n headers: reqHeaders,\n body,\n ...(options?.signal !== undefined ? { signal: options.signal } : {}),\n ...(options?.retry !== undefined ? { retry: options.retry } : {}),\n })\n try {\n return await response.json<UploadPartResponse>()\n } catch (err) {\n throw uploadResponseBodyError(err, options?.signal)\n }\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-finish-large-file | b2_finish_large_file}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional abort and retry controls.\n *\n * @returns The completed file version metadata.\n */\n async finishLargeFile(\n apiUrl: string,\n authToken: string,\n request: FinishLargeFileRequest,\n options?: FinishLargeFileOptions,\n ): Promise<FileVersion> {\n const response = await this.transport.send({\n url: b2Url(apiUrl, { ...B2_NATIVE_API, endpoint: 'b2_finish_large_file' }),\n method: 'POST',\n headers: {\n Authorization: authToken,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(request),\n ...(options?.signal !== undefined ? { signal: options.signal } : {}),\n ...(options?.retry !== undefined ? { retry: options.retry } : {}),\n })\n\n let fileVersion: FileVersion\n try {\n fileVersion = await response.json<FileVersion>()\n } catch (err) {\n throw new FinishLargeFileResponseBodyError(\n err instanceof Error ? err.message : 'Finish large file response body could not be read',\n { cause: err, fileId: request.fileId },\n )\n }\n return normalizeFileVersionSha1(fileVersion)\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-cancel-large-file | b2_cancel_large_file}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional request controls such as cancellation and retry overrides.\n *\n * @returns The cancelled large file metadata.\n */\n async cancelLargeFile(\n apiUrl: string,\n authToken: string,\n request: CancelLargeFileRequest,\n options?: RawRequestOptions,\n ): Promise<CancelLargeFileResponse> {\n return this.postJson<CancelLargeFileResponse>(\n apiUrl,\n authToken,\n 'b2_cancel_large_file',\n request,\n options,\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-list-unfinished-large-files | b2_list_unfinished_large_files}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional request controls such as cancellation and retry.\n *\n * @returns The list of unfinished large files and optional continuation token.\n */\n async listUnfinishedLargeFiles(\n apiUrl: string,\n authToken: string,\n request: ListUnfinishedLargeFilesRequest,\n options?: RawRequestOptions,\n ): Promise<ListUnfinishedLargeFilesResponse> {\n return normalizeFileVersionListSha1(\n await this.postJson<ListUnfinishedLargeFilesResponse>(\n apiUrl,\n authToken,\n 'b2_list_unfinished_large_files',\n request,\n options,\n ),\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-list-parts | b2_list_parts}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n * @param options - Optional request controls such as cancellation and retry.\n *\n * @returns The list of uploaded parts and optional continuation token.\n */\n async listParts(\n apiUrl: string,\n authToken: string,\n request: ListPartsRequest,\n options?: RawRequestOptions,\n ): Promise<ListPartsResponse> {\n return this.postJson<ListPartsResponse>(apiUrl, authToken, 'b2_list_parts', request, options)\n }\n\n // --- Downloads ---\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-download-file-by-id | b2_download_file_by_id}.\n * @param downloadUrl - The B2 download base URL.\n * @param authToken - The authorization token.\n * @param fileId - The unique identifier of the file to download.\n * @param options - Optional download parameters for range requests and cancellation.\n *\n * @returns The response headers, streaming body, and HTTP status code.\n */\n async downloadFileById(\n downloadUrl: string,\n authToken: string,\n fileId: string,\n options?: DownloadFileOptions,\n ): Promise<{\n /** Response headers containing file metadata and B2 info headers. */\n headers: Headers\n /** Streaming response body, or `null` for HEAD-like responses. */\n body: ReadableStream<Uint8Array> | null\n /** HTTP status code (200 for full content, 206 for partial content). */\n status: number\n }> {\n const headers = buildDownloadRequestHeaders(authToken, options)\n const url = appendDownloadOverrides(\n `${b2Url(downloadUrl, {\n ...B2_NATIVE_API,\n endpoint: 'b2_download_file_by_id',\n })}?fileId=${encodeURIComponent(fileId)}`,\n options,\n )\n\n const response = await this.transport.send({\n url,\n method: options?.method ?? 'GET',\n headers,\n ...(options?.signal !== undefined ? { signal: options.signal } : {}),\n })\n\n return { headers: response.headers, body: response.body, status: response.status }\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-download-file-by-name | b2_download_file_by_name}.\n * @param downloadUrl - The B2 download base URL.\n * @param authToken - The authorization token.\n * @param bucketName - The name of the bucket containing the file.\n * @param fileName - The name of the file to download.\n * @param options - Optional download parameters for range requests and cancellation.\n *\n * @returns The response headers, streaming body, and HTTP status code.\n */\n async downloadFileByName(\n downloadUrl: string,\n authToken: string,\n bucketName: string,\n fileName: string,\n options?: DownloadFileOptions,\n ): Promise<{\n /** Response headers containing file metadata and B2 info headers. */\n headers: Headers\n /** Streaming response body, or `null` for HEAD-like responses. */\n body: ReadableStream<Uint8Array> | null\n /** HTTP status code (200 for full content, 206 for partial content). */\n status: number\n }> {\n const headers = buildDownloadRequestHeaders(authToken, options)\n const url = appendDownloadOverrides(\n `${downloadUrl}/file/${encodeURIComponent(bucketName)}/${encodeFileName(fileName)}`,\n options,\n )\n\n const response = await this.transport.send({\n url,\n method: options?.method ?? 'GET',\n headers,\n ...(options?.signal !== undefined ? { signal: options.signal } : {}),\n })\n\n return { headers: response.headers, body: response.body, status: response.status }\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-get-download-authorization | b2_get_download_authorization}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The current session authorization token.\n * @param request - The API request parameters.\n *\n * @returns The download authorization token for the specified file prefix.\n */\n async getDownloadAuthorization(\n apiUrl: string,\n authToken: string,\n request: DownloadAuthorizationRequest,\n ): Promise<DownloadAuthorizationResponse> {\n return this.postJson<DownloadAuthorizationResponse>(\n apiUrl,\n authToken,\n 'b2_get_download_authorization',\n request,\n )\n }\n\n // --- Keys ---\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-create-key | b2_create_key}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The newly created application key with secret.\n */\n async createKey(\n apiUrl: string,\n authToken: string,\n request: CreateKeyRequest,\n ): Promise<FullApplicationKey> {\n const key = await this.postJson<FullApplicationKey>(\n apiUrl,\n authToken,\n 'b2_create_key',\n normalizeCreateKeyRequest(request),\n )\n return normalizeKeyResponse(key)\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-list-keys | b2_list_keys}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The list of application keys and optional continuation token.\n */\n async listKeys(\n apiUrl: string,\n authToken: string,\n request: ListKeysRequest,\n ): Promise<ListKeysResponse> {\n const response = await this.postJson<ListKeysResponse>(\n apiUrl,\n authToken,\n 'b2_list_keys',\n request,\n )\n return { ...response, keys: response.keys.map((key) => normalizeKeyResponse(key)) }\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-delete-key | b2_delete_key}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The deleted application key metadata.\n */\n async deleteKey(\n apiUrl: string,\n authToken: string,\n request: DeleteKeyRequest,\n ): Promise<ApplicationKey> {\n const key = await this.postJson<ApplicationKey>(apiUrl, authToken, 'b2_delete_key', request)\n return normalizeKeyResponse(key)\n }\n\n // --- Retention / Legal Hold ---\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-update-file-retention | b2_update_file_retention}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The updated file retention settings.\n */\n async updateFileRetention(\n apiUrl: string,\n authToken: string,\n request: UpdateFileRetentionRequest,\n ): Promise<UpdateFileRetentionResponse> {\n return this.postJson<UpdateFileRetentionResponse>(\n apiUrl,\n authToken,\n 'b2_update_file_retention',\n request,\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-update-file-legal-hold | b2_update_file_legal_hold}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The updated file legal hold status.\n */\n async updateFileLegalHold(\n apiUrl: string,\n authToken: string,\n request: UpdateFileLegalHoldRequest,\n ): Promise<UpdateFileLegalHoldResponse> {\n return this.postJson<UpdateFileLegalHoldResponse>(\n apiUrl,\n authToken,\n 'b2_update_file_legal_hold',\n request,\n )\n }\n\n // --- Notifications ---\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-get-bucket-notification-rules | b2_get_bucket_notification_rules}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The configured event notification rules for the specified bucket.\n */\n async getBucketNotificationRules(\n apiUrl: string,\n authToken: string,\n request: GetBucketNotificationRulesRequest,\n ): Promise<GetBucketNotificationRulesResponse> {\n return this.postJson<GetBucketNotificationRulesResponse>(\n apiUrl,\n authToken,\n 'b2_get_bucket_notification_rules',\n request,\n )\n }\n\n /**\n * Calls {@link https://www.backblaze.com/apidocs/b2-set-bucket-notification-rules | b2_set_bucket_notification_rules}.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param request - The API request parameters.\n *\n * @returns The updated bucket notification rules.\n */\n async setBucketNotificationRules(\n apiUrl: string,\n authToken: string,\n request: SetBucketNotificationRulesRequest,\n ): Promise<SetBucketNotificationRulesResponse> {\n return this.postJson<SetBucketNotificationRulesResponse>(\n apiUrl,\n authToken,\n 'b2_set_bucket_notification_rules',\n request,\n )\n }\n\n // --- Internal ---\n\n /**\n * Sends a JSON POST request to the specified B2 API endpoint.\n * @param apiUrl - The B2 API base URL.\n * @param authToken - The authorization token.\n * @param endpoint - The B2 API endpoint name.\n * @param body - The JSON request body.\n * @param options - Optional abort and per-request retry settings.\n *\n * @returns The parsed JSON response.\n */\n private async postJson<T>(\n apiUrl: string,\n authToken: string,\n endpoint: string,\n body: unknown,\n options?: RawRequestOptions,\n ): Promise<T> {\n const response = await this.transport.send({\n url: b2Url(apiUrl, { ...B2_NATIVE_API, endpoint }),\n method: 'POST',\n headers: {\n Authorization: authToken,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(body),\n ...(options?.signal !== undefined ? { signal: options.signal } : {}),\n ...(options?.retry !== undefined ? { retry: options.retry } : {}),\n })\n return response.json<T>()\n }\n}\n\n// --- Header helpers ---\n\nimport {\n EncryptionAlgorithm,\n EncryptionMode,\n type EncryptionSetting,\n type SseCKeyMaterial,\n} from '../types/encryption.ts'\nimport type { FileRetentionValue, LegalHoldValue } from '../types/lock.ts'\n\ninterface JsonBodySseCRequest {\n readonly serverSideEncryption?: EncryptionSetting\n readonly sourceServerSideEncryption?: EncryptionSetting\n readonly destinationServerSideEncryption?: EncryptionSetting\n}\n\nfunction withJsonBodyWireSseC<T extends JsonBodySseCRequest>(request: T): T {\n return {\n ...request,\n ...(request.serverSideEncryption !== undefined\n ? { serverSideEncryption: toWireSseC(request.serverSideEncryption) }\n : {}),\n ...(request.sourceServerSideEncryption !== undefined\n ? { sourceServerSideEncryption: toWireSseC(request.sourceServerSideEncryption) }\n : {}),\n ...(request.destinationServerSideEncryption !== undefined\n ? { destinationServerSideEncryption: toWireSseC(request.destinationServerSideEncryption) }\n : {}),\n }\n}\n\nfunction toWireSseC(setting: EncryptionSetting): EncryptionSetting {\n if (setting.mode !== EncryptionMode.SseC) return setting\n // SSE-C settings may be redacted wrappers with non-enumerable key fields.\n // Passing the wrapper through would let toJSON() emit the redaction placeholder;\n // spreading it would drop the key fields. Read directly into a plain wire\n // literal for the B2 JSON body only, and never pass that cleartext literal to\n // diagnostics or logging sinks.\n return {\n mode: EncryptionMode.SseC,\n algorithm: setting.algorithm,\n customerKey: setting.customerKey,\n customerKeyMd5: setting.customerKeyMd5,\n }\n}\n\n/**\n * Applies server-side encryption headers to the request.\n * @param headers - The mutable headers object to populate.\n * @param encryption - The encryption settings, or undefined to skip.\n */\nfunction applyEncryptionHeaders(\n headers: Record<string, string>,\n encryption: EncryptionSetting | undefined,\n): void {\n if (!encryption || encryption.mode === EncryptionMode.None) return\n if (encryption.mode === EncryptionMode.SseB2) {\n headers['X-Bz-Server-Side-Encryption'] = EncryptionAlgorithm.Aes256\n } else if (encryption.mode === EncryptionMode.SseC) {\n headers['X-Bz-Server-Side-Encryption-Customer-Algorithm'] = EncryptionAlgorithm.Aes256\n headers['X-Bz-Server-Side-Encryption-Customer-Key'] = encryption.customerKey\n headers['X-Bz-Server-Side-Encryption-Customer-Key-Md5'] = encryption.customerKeyMd5\n }\n}\n\n/**\n * SSE-C decryption parameters supplied to downloads of files uploaded with customer-managed keys.\n * `customerKey` is secret key material sent as a request header; custom transports must redact\n * request headers before logging them.\n */\nexport type SseCDownloadKey = SseCKeyMaterial\n\n/**\n * Options accepted by {@link RawClient.downloadFileById} and\n * {@link RawClient.downloadFileByName}. Mirrors the B2 native API: range +\n * SSE-C decryption headers + the documented `b2Content*` response-header\n * overrides (query-string parameters on the request URL).\n */\nexport interface DownloadFileOptions {\n /** HTTP method. Defaults to `'GET'`. Use `'HEAD'` to fetch headers without the body. */\n readonly method?: 'GET' | 'HEAD'\n /** HTTP Range header value for partial content requests. */\n readonly range?: string\n /** SSE-C decryption parameters, required if the file was uploaded with SSE-C. */\n readonly serverSideEncryption?: SseCDownloadKey\n /** Override the `Content-Disposition` header in the download response. */\n readonly b2ContentDisposition?: string\n /** Override the `Content-Language` header in the download response. */\n readonly b2ContentLanguage?: string\n /** Override the `Content-Encoding` header in the download response. */\n readonly b2ContentEncoding?: string\n /** Override the `Content-Type` header in the download response. */\n readonly b2ContentType?: string\n /** Override the `Cache-Control` header in the download response. */\n readonly b2CacheControl?: string\n /** Override the `Expires` header in the download response. */\n readonly b2Expires?: string\n /** Signal to abort the download. */\n readonly signal?: AbortSignal\n}\n\nconst DOWNLOAD_OVERRIDE_PARAMS = [\n 'b2ContentDisposition',\n 'b2ContentLanguage',\n 'b2ContentEncoding',\n 'b2ContentType',\n 'b2CacheControl',\n 'b2Expires',\n] as const\n\n/**\n * Builds the HTTP request headers for a download: Authorization, optional\n * Range, and optional SSE-C decryption headers.\n *\n * @param authToken - The B2 session authorization token.\n * @param options - Caller-supplied download options.\n *\n * @returns The header map to send with the request.\n */\nfunction buildDownloadRequestHeaders(\n authToken: string,\n options: DownloadFileOptions | undefined,\n): Record<string, string> {\n const headers: Record<string, string> = { Authorization: authToken }\n if (options?.range) headers['Range'] = options.range\n if (options?.serverSideEncryption) {\n const encryption = options.serverSideEncryption\n // SSE-C keys may be redacted wrappers with non-enumerable key fields.\n // Read fields directly; object spread would drop the wire header values.\n applyEncryptionHeaders(headers, {\n mode: EncryptionMode.SseC,\n algorithm: encryption.algorithm,\n customerKey: encryption.customerKey,\n customerKeyMd5: encryption.customerKeyMd5,\n })\n }\n return headers\n}\n\n/**\n * Appends the documented `b2Content*` response-header overrides to a download\n * URL as query-string parameters. B2 echoes the values into the response\n * headers so callers can control content type, disposition, and caching.\n *\n * @param url - The base download URL.\n * @param options - Caller-supplied download options.\n *\n * @returns The URL with any override parameters appended.\n */\nfunction appendDownloadOverrides(url: string, options: DownloadFileOptions | undefined): string {\n if (!options) return url\n const params: string[] = []\n for (const key of DOWNLOAD_OVERRIDE_PARAMS) {\n const value = options[key]\n if (value !== undefined) {\n params.push(`${key}=${encodeURIComponent(value)}`)\n }\n }\n if (params.length === 0) return url\n const separator = url.includes('?') ? '&' : '?'\n return `${url}${separator}${params.join('&')}`\n}\n\n/**\n * Applies file retention headers to the request.\n * @param headers - The mutable headers object to populate.\n * @param retention - The retention settings, or undefined to skip.\n */\nfunction applyRetentionHeaders(\n headers: Record<string, string>,\n retention: FileRetentionValue | undefined,\n): void {\n if (!retention) return\n if (retention.mode) {\n headers['X-Bz-File-Retention-Mode'] = retention.mode\n }\n if (retention.retainUntilTimestamp) {\n headers['X-Bz-File-Retention-Retain-Until-Timestamp'] = String(retention.retainUntilTimestamp)\n }\n}\n\n/**\n * Applies the legal hold header to the request.\n * @param headers - The mutable headers object to populate.\n * @param legalHold - The legal hold value, or undefined to skip.\n */\nfunction applyLegalHoldHeader(\n headers: Record<string, string>,\n legalHold: LegalHoldValue | undefined,\n): void {\n if (!legalHold) return\n headers['X-Bz-File-Legal-Hold'] = legalHold\n}\n\nexport {\n buildFileInfoHeaders,\n decodeFileName,\n encodeFileName,\n parseFileInfoHeaders,\n} from './encoding.ts'\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAyGA,IAAM,gBAAsC;CAAE,QAAQ;CAAS,SAAS;AAAK;AA6C7E,SAAS,2BACP,iBACA,OAC+B;CAC/B,IAAI,oBAAoB,KAAA,GACtB,OAAO,UAAU,KAAA,IAAY,KAAA,IAAY,EAAE,MAAM;CAEnD,IAAI,cAAc,eAAe,GAC/B,OAAO;EACL,QAAQ;EACR,GAAI,UAAU,KAAA,IAAY,EAAE,MAAM,IAAI,CAAC;CACzC;CAEF,OAAO,UAAU,KAAA,IAAY,kBAAkB;EAAE,GAAG;EAAiB;CAAM;AAC7E;AAEA,SAAS,cAAc,OAAsC;CAG3D,OACE,OAAO,UAAU,YACjB,UAAU,QACV,aAAa,SACb,OAAQ,MAAsB,qBAAqB;AAEvD;AAEA,SAAS,4BAA4B,OAAyC;CAC5E,IAAI,UAAU,KAAA,GAAW;CACzB,IAAI,OAAO,UAAU,YAAY,OAAO,cAAc,KAAK,KAAK,SAAS,GAAG;CAC5E,MAAM,IAAI,UAAU,2DAA2D;AACjF;AAEA,SAAS,0BAA0B,MAAc,OAAqB;CACpE,IAAI,yBAAyB,KAAK,GAChC,MAAM,IAAI,UAAU,GAAG,KAAK,0CAA0C;AAE1E;AAEA,SAAS,yBAAyB,OAAwB;CACxD,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,GAAG;EACxC,MAAM,OAAO,MAAM,WAAW,CAAC;EAC/B,IAAI,QAAQ,MAAQ,SAAS,KAAM,OAAO;CAC5C;CACA,OAAO;AACT;AAEA,SAAS,2BACP,SACA,KACA,YACA,OACM;CACN,IAAI,CAAC,OAAO;CACZ,0BAA0B,YAAY,KAAK;CAC3C,OAAO,OAAO,SAAS,qBAAqB,GAAG,MAAM,MAAM,CAAC,CAAC;AAC/D;AAEA,SAAS,+BACP,OAC4C;CAC5C,IAAI,UAAU,KAAA,KAAa,UAAU,MAAM;CAC3C,IAAI,OAAO,UAAU,YAAY,QAAQ,KAAK,KAAK,GAAG;EACpD,MAAM,YAAY,OAAO,KAAK;EAC9B,IAAI,OAAO,cAAc,SAAS,GAAG;CACvC;CACA,MAAM,IAAI,UAAU,0EAA0E;AAChG;AAEA,SAAS,0BAA0B,SAA6C;CAC9E,MAAM,EAAE,UAAU,GAAG,8BAA8B;CACnD,IAAI,aAAa,KAAA,KAAa,0BAA0B,cAAc,KAAA,GACpE,MAAM,IAAI,UAAU,qEAAqE;CAE3F,IAAI,aAAa,KAAA,GACf,OAAO;CAET,OAAO;EAAE,GAAG;EAA2B,WAAW,CAAC,QAAQ;CAAE;AAC/D;AAEA,SAAS,eAAe,WAAwD;CAC9E,OAAO,WAAW,WAAW,IAAK,UAAU,MAAM,OAAQ;AAC5D;AAEA,SAAS,qBACP,KAC4C;CAC5C,OAAO;EAAE,GAAG;EAAK,UAAU,eAAe,IAAI,SAAS;CAAE;AAC3D;AA+BA,SAAS,wBAAwB,YAAiE;CAChG,MAAM,UAAU,WAAW;CAC3B,IAAI,SAAS,YAAY,KAAA,GACvB,OAAO,QAAQ,YAAY,OAAO,OAAO,QAAQ,QAAQ,KAAK,YAAY,EAAE,GAAG,OAAO,EAAE;CAE1F,MAAM,WAAW,SAAS,YAAY,WAAW,YAAY;CAC7D,IAAI,aAAa,MAAM,OAAO;CAC9B,OAAO,CAAC;EAAE,IAAI;EAAU,MAAM,SAAS,cAAc,WAAW,cAAc;CAAK,CAAC;AACtF;AAEA,SAAS,kCACP,UAC0B;CAC1B,MAAM,aAAa,SAAS,QAAQ;CACpC,MAAM,UAAU,WAAW;CAC3B,MAAM,UAAU,wBAAwB,UAAU;CAClD,MAAM,eAAe,SAAS,WAAW,IAAI,QAAQ,KAAK,KAAA;CAC1D,MAAM,WAAW,cAAc,MAAM;CACrC,MAAM,aAAa,cAAc,QAAQ;CACzC,MAAM,aAAa,SAAS,cAAc,WAAW,cAAc;CACnE,MAAM,eAAe,SAAS,gBAAgB,WAAW,gBAAgB,CAAC;CAC1E,MAAM,EAAE,SAAS,cAAc,cAAc,qBAAqB,GAAG,mBAAmB;CAExF,OAAO;EACL,GAAG;EACH,SAAS;GACP,GAAG,SAAS;GACZ,YAAY;IACV,GAAG;IACH;IACA;IACA,aAAa,WAAW;IACxB,UAAU;IACV;IACA,SAAS;KACP,GAAI,WAAW,CAAC;KAChB;KACA;KACA;KACA;KACA;IACF;GACF;EACF;CACF;AACF;AAEA,SAAS,wBACP,KACA,QACyB;CACzB,IAAI,QAAQ,YAAY,MACtB,MAAM,OAAO,UAAU,IAAI,aAAa,WAAW,YAAY;CAEjE,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU;CACrD,OAAO,IAAI,wBAAwB,SAAS,EAAE,OAAO,IAAI,CAAC;AAC5D;;;;;;;;AASA,IAAa,YAAb,MAAuB;;CAErB;;;;;CAMA,YAAY,SAA2B;EACrC,KAAK,YAAY,QAAQ;CAC3B;;;;;;;;;;CAaA,MAAM,iBACJ,kBACA,gBACA,WAAW,+BACX,SACmC;EACnC,qBAAqB,QAAQ;EAU7B,OAAO,kCAAkC,OAAM,MATxB,KAAK,UAAU,KAAK;GACzC,KAAK,MAAM,UAAU;IAAE,GAAG;IAAe,UAAU;GAAuB,CAAC;GAC3E,QAAQ;GACR,SAAS,EACP,eAAe,SAAS,KAAK,GAAG,iBAAiB,GAAG,gBAAgB,IACtE;GACA,GAAI,SAAS,WAAW,KAAA,IAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;GAClE,GAAI,SAAS,UAAU,KAAA,IAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;EACjE,CAAC,EAAA,CACuD,KAAmC,CAAC;CAC9F;;;;;;;;;CAYA,MAAM,aACJ,QACA,WACA,SACqB;EACrB,+BAA+B,OAAO;EACtC,OAAO,KAAK,SAAqB,QAAQ,WAAW,oBAAoB,OAAO;CACjF;;;;;;;;;CAUA,MAAM,aACJ,QACA,WACA,SACqB;EACrB,OAAO,KAAK,SAAqB,QAAQ,WAAW,oBAAoB,OAAO;CACjF;;;;;;;;;CAUA,MAAM,YACJ,QACA,WACA,SAC8B;EAC9B,OAAO,KAAK,SAA8B,QAAQ,WAAW,mBAAmB,OAAO;CACzF;;;;;;;;;CAUA,MAAM,aACJ,QACA,WACA,SACqB;EACrB,+BAA+B,OAAO;EACtC,OAAO,KAAK,SAAqB,QAAQ,WAAW,oBAAoB,OAAO;CACjF;;;;;;;;;;;CAgDA,MAAM,aACJ,QACA,WACA,SACA,iBACA,OAC+B;EAC/B,OAAO,KAAK,SACV,QACA,WACA,qBACA,SACA,2BAA2B,iBAAiB,KAAK,CACnD;CACF;;;;;;;;;;;CAoDA,MAAM,WACJ,WACA,SACA,MACA,iBACA,OACsB;EACtB,MAAM,UAAU,2BAA2B,iBAAiB,KAAK;EACjE,0BAA0B,iBAAiB,QAAQ,aAAa;EAChE,0BAA0B,eAAe,QAAQ,WAAW;EAC5D,0BAA0B,eAAe,QAAQ,WAAW;EAC5D,MAAM,aAAqC;GACzC,eAAe,QAAQ;GACvB,kBAAkB,eAAe,QAAQ,QAAQ;GACjD,gBAAgB,QAAQ;GACxB,kBAAkB,OAAO,QAAQ,aAAa;GAC9C,qBAAqB,QAAQ;GAC7B,GAAG,qBAAqB,QAAQ,QAAQ;EAC1C;EAEA,IAAI,QAAQ,uBAAuB,KAAA,GACjC,WAAW,wCAAwC,OAAO,QAAQ,kBAAkB;EAEtF,IAAI,QAAQ,0BAA0B,KAAA,GAAW;GAC/C,4BAA4B,QAAQ,qBAAqB;GACzD,WAAW,kCAAkC,OAAO,QAAQ,qBAAqB;EACnF;EACA,2BACE,YACA,0BACA,sBACA,QAAQ,kBACV;EACA,2BACE,YACA,uBACA,mBACA,QAAQ,eACV;EACA,2BAA2B,YAAY,cAAc,WAAW,QAAQ,OAAO;EAC/E,2BAA2B,YAAY,oBAAoB,gBAAgB,QAAQ,YAAY;EAC/F,2BACE,YACA,uBACA,mBACA,QAAQ,eACV;EAEA,uBAAuB,YAAY,QAAQ,oBAAoB;EAC/D,sBAAsB,YAAY,QAAQ,aAAa;EACvD,qBAAqB,YAAY,QAAQ,SAAS;EAElD,MAAM,WAAW,MAAM,KAAK,UAAU,KAAK;GACzC,KAAK;GACL,QAAQ;GACR,SAAS;GACT;GACA,GAAI,SAAS,WAAW,KAAA,IAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;GAClE,GAAI,SAAS,UAAU,KAAA,IAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;EACjE,CAAC;EACD,IAAI;GACF,OAAO,yBAAyB,MAAM,SAAS,KAAkB,CAAC;EACpE,SAAS,KAAK;GACZ,MAAM,wBAAwB,KAAK,SAAS,MAAM;EACpD;CACF;CA+BA,MAAM,cACJ,QACA,WACA,SAIA,SACqE;EACrE,OAAO,6BACL,MAAM,KAAK,SACT,QACA,WACA,sBACA,SACA,OACF,CACF;CACF;CA+BA,MAAM,iBACJ,QACA,WACA,SAIA,SAC2E;EAC3E,OAAO,6BACL,MAAM,KAAK,SACT,QACA,WACA,yBACA,SACA,OACF,CACF;CACF;;;;;;;;;CAUA,MAAM,YACJ,QACA,WACA,SACsB;EACtB,OAAO,yBACL,MAAM,KAAK,SAAsB,QAAQ,WAAW,oBAAoB,OAAO,CACjF;CACF;;;;;;;;;;CAWA,MAAM,SACJ,QACA,WACA,SACA,SACsB;EACtB,OAAO,yBACL,MAAM,KAAK,SAAsB,QAAQ,WAAW,gBAAgB,SAAS,OAAO,CACtF;CACF;;;;;;;;;;CAWA,MAAM,kBACJ,QACA,WACA,SACA,SACoC;EACpC,OAAO,KAAK,SACV,QACA,WACA,0BACA,SACA,OACF;CACF;;;;;;;;;;CAWA,MAAM,SACJ,QACA,WACA,SACA,SACsB;EACtB,OAAO,yBACL,MAAM,KAAK,SACT,QACA,WACA,gBACA,qBAAqB,OAAO,GAC5B,OACF,CACF;CACF;;;;;;;;;;CAWA,MAAM,SACJ,QACA,WACA,SACA,SAC2B;EAC3B,OAAO,KAAK,SACV,QACA,WACA,gBACA,qBAAqB,OAAO,GAC5B,OACF;CACF;;;;;;;;;;CAaA,MAAM,eACJ,QACA,WACA,SACA,SACiC;EACjC,+BAA+B,QAAQ,qBAAqB;EAC5D,OAAO,yBACL,MAAM,KAAK,SACT,QACA,WACA,uBACA,qBAAqB,OAAO,GAC5B,OACF,CACF;CACF;;;;;;;;;;;CA8CA,MAAM,iBACJ,QACA,WACA,SACA,iBACA,OACmC;EACnC,OAAO,KAAK,SACV,QACA,WACA,0BACA,SACA,2BAA2B,iBAAiB,KAAK,CACnD;CACF;;;;;;;;;;;CAoDA,MAAM,WACJ,WACA,SACA,MACA,iBACA,OAC6B;EAC7B,MAAM,UAAU,2BAA2B,iBAAiB,KAAK;EACjE,0BAA0B,iBAAiB,QAAQ,aAAa;EAChE,0BAA0B,eAAe,QAAQ,WAAW;EAC5D,MAAM,aAAqC;GACzC,eAAe,QAAQ;GACvB,oBAAoB,OAAO,QAAQ,UAAU;GAC7C,kBAAkB,OAAO,QAAQ,aAAa;GAC9C,qBAAqB,QAAQ;EAC/B;EAEA,uBAAuB,YAAY,QAAQ,oBAAoB;EAE/D,MAAM,WAAW,MAAM,KAAK,UAAU,KAAK;GACzC,KAAK;GACL,QAAQ;GACR,SAAS;GACT;GACA,GAAI,SAAS,WAAW,KAAA,IAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;GAClE,GAAI,SAAS,UAAU,KAAA,IAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;EACjE,CAAC;EACD,IAAI;GACF,OAAO,MAAM,SAAS,KAAyB;EACjD,SAAS,KAAK;GACZ,MAAM,wBAAwB,KAAK,SAAS,MAAM;EACpD;CACF;;;;;;;;;;CAWA,MAAM,gBACJ,QACA,WACA,SACA,SACsB;EACtB,MAAM,WAAW,MAAM,KAAK,UAAU,KAAK;GACzC,KAAK,MAAM,QAAQ;IAAE,GAAG;IAAe,UAAU;GAAuB,CAAC;GACzE,QAAQ;GACR,SAAS;IACP,eAAe;IACf,gBAAgB;GAClB;GACA,MAAM,KAAK,UAAU,OAAO;GAC5B,GAAI,SAAS,WAAW,KAAA,IAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;GAClE,GAAI,SAAS,UAAU,KAAA,IAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;EACjE,CAAC;EAED,IAAI;EACJ,IAAI;GACF,cAAc,MAAM,SAAS,KAAkB;EACjD,SAAS,KAAK;GACZ,MAAM,IAAI,iCACR,eAAe,QAAQ,IAAI,UAAU,qDACrC;IAAE,OAAO;IAAK,QAAQ,QAAQ;GAAO,CACvC;EACF;EACA,OAAO,yBAAyB,WAAW;CAC7C;;;;;;;;;;CAWA,MAAM,gBACJ,QACA,WACA,SACA,SACkC;EAClC,OAAO,KAAK,SACV,QACA,WACA,wBACA,SACA,OACF;CACF;;;;;;;;;;CAWA,MAAM,yBACJ,QACA,WACA,SACA,SAC2C;EAC3C,OAAO,6BACL,MAAM,KAAK,SACT,QACA,WACA,kCACA,SACA,OACF,CACF;CACF;;;;;;;;;;CAWA,MAAM,UACJ,QACA,WACA,SACA,SAC4B;EAC5B,OAAO,KAAK,SAA4B,QAAQ,WAAW,iBAAiB,SAAS,OAAO;CAC9F;;;;;;;;;;CAaA,MAAM,iBACJ,aACA,WACA,QACA,SAQC;EACD,MAAM,UAAU,4BAA4B,WAAW,OAAO;EAC9D,MAAM,MAAM,wBACV,GAAG,MAAM,aAAa;GACpB,GAAG;GACH,UAAU;EACZ,CAAC,EAAE,UAAU,mBAAmB,MAAM,KACtC,OACF;EAEA,MAAM,WAAW,MAAM,KAAK,UAAU,KAAK;GACzC;GACA,QAAQ,SAAS,UAAU;GAC3B;GACA,GAAI,SAAS,WAAW,KAAA,IAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;EACpE,CAAC;EAED,OAAO;GAAE,SAAS,SAAS;GAAS,MAAM,SAAS;GAAM,QAAQ,SAAS;EAAO;CACnF;;;;;;;;;;;CAYA,MAAM,mBACJ,aACA,WACA,YACA,UACA,SAQC;EACD,MAAM,UAAU,4BAA4B,WAAW,OAAO;EAC9D,MAAM,MAAM,wBACV,GAAG,YAAY,QAAQ,mBAAmB,UAAU,EAAE,GAAG,eAAe,QAAQ,KAChF,OACF;EAEA,MAAM,WAAW,MAAM,KAAK,UAAU,KAAK;GACzC;GACA,QAAQ,SAAS,UAAU;GAC3B;GACA,GAAI,SAAS,WAAW,KAAA,IAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;EACpE,CAAC;EAED,OAAO;GAAE,SAAS,SAAS;GAAS,MAAM,SAAS;GAAM,QAAQ,SAAS;EAAO;CACnF;;;;;;;;;CAUA,MAAM,yBACJ,QACA,WACA,SACwC;EACxC,OAAO,KAAK,SACV,QACA,WACA,iCACA,OACF;CACF;;;;;;;;;CAYA,MAAM,UACJ,QACA,WACA,SAC6B;EAO7B,OAAO,qBAAqB,MANV,KAAK,SACrB,QACA,WACA,iBACA,0BAA0B,OAAO,CACnC,CAC+B;CACjC;;;;;;;;;CAUA,MAAM,SACJ,QACA,WACA,SAC2B;EAC3B,MAAM,WAAW,MAAM,KAAK,SAC1B,QACA,WACA,gBACA,OACF;EACA,OAAO;GAAE,GAAG;GAAU,MAAM,SAAS,KAAK,KAAK,QAAQ,qBAAqB,GAAG,CAAC;EAAE;CACpF;;;;;;;;;CAUA,MAAM,UACJ,QACA,WACA,SACyB;EAEzB,OAAO,qBAAqB,MADV,KAAK,SAAyB,QAAQ,WAAW,iBAAiB,OAAO,CAC5D;CACjC;;;;;;;;;CAYA,MAAM,oBACJ,QACA,WACA,SACsC;EACtC,OAAO,KAAK,SACV,QACA,WACA,4BACA,OACF;CACF;;;;;;;;;CAUA,MAAM,oBACJ,QACA,WACA,SACsC;EACtC,OAAO,KAAK,SACV,QACA,WACA,6BACA,OACF;CACF;;;;;;;;;CAYA,MAAM,2BACJ,QACA,WACA,SAC6C;EAC7C,OAAO,KAAK,SACV,QACA,WACA,oCACA,OACF;CACF;;;;;;;;;CAUA,MAAM,2BACJ,QACA,WACA,SAC6C;EAC7C,OAAO,KAAK,SACV,QACA,WACA,oCACA,OACF;CACF;;;;;;;;;;;CAcA,MAAc,SACZ,QACA,WACA,UACA,MACA,SACY;EAYZ,QAAO,MAXgB,KAAK,UAAU,KAAK;GACzC,KAAK,MAAM,QAAQ;IAAE,GAAG;IAAe;GAAS,CAAC;GACjD,QAAQ;GACR,SAAS;IACP,eAAe;IACf,gBAAgB;GAClB;GACA,MAAM,KAAK,UAAU,IAAI;GACzB,GAAI,SAAS,WAAW,KAAA,IAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;GAClE,GAAI,SAAS,UAAU,KAAA,IAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;EACjE,CAAC,EAAA,CACe,KAAQ;CAC1B;AACF;AAkBA,SAAS,qBAAoD,SAAe;CAC1E,OAAO;EACL,GAAG;EACH,GAAI,QAAQ,yBAAyB,KAAA,IACjC,EAAE,sBAAsB,WAAW,QAAQ,oBAAoB,EAAE,IACjE,CAAC;EACL,GAAI,QAAQ,+BAA+B,KAAA,IACvC,EAAE,4BAA4B,WAAW,QAAQ,0BAA0B,EAAE,IAC7E,CAAC;EACL,GAAI,QAAQ,oCAAoC,KAAA,IAC5C,EAAE,iCAAiC,WAAW,QAAQ,+BAA+B,EAAE,IACvF,CAAC;CACP;AACF;AAEA,SAAS,WAAW,SAA+C;CACjE,IAAI,QAAQ,SAAS,eAAe,MAAM,OAAO;CAMjD,OAAO;EACL,MAAM,eAAe;EACrB,WAAW,QAAQ;EACnB,aAAa,QAAQ;EACrB,gBAAgB,QAAQ;CAC1B;AACF;;;;;;AAOA,SAAS,uBACP,SACA,YACM;CACN,IAAI,CAAC,cAAc,WAAW,SAAS,eAAe,MAAM;CAC5D,IAAI,WAAW,SAAS,eAAe,OACrC,QAAQ,iCAAiC,oBAAoB;MACxD,IAAI,WAAW,SAAS,eAAe,MAAM;EAClD,QAAQ,oDAAoD,oBAAoB;EAChF,QAAQ,8CAA8C,WAAW;EACjE,QAAQ,kDAAkD,WAAW;CACvE;AACF;AAsCA,IAAM,2BAA2B;CAC/B;CACA;CACA;CACA;CACA;CACA;AACF;;;;;;;;;;AAWA,SAAS,4BACP,WACA,SACwB;CACxB,MAAM,UAAkC,EAAE,eAAe,UAAU;CACnE,IAAI,SAAS,OAAO,QAAQ,WAAW,QAAQ;CAC/C,IAAI,SAAS,sBAAsB;EACjC,MAAM,aAAa,QAAQ;EAG3B,uBAAuB,SAAS;GAC9B,MAAM,eAAe;GACrB,WAAW,WAAW;GACtB,aAAa,WAAW;GACxB,gBAAgB,WAAW;EAC7B,CAAC;CACH;CACA,OAAO;AACT;;;;;;;;;;;AAYA,SAAS,wBAAwB,KAAa,SAAkD;CAC9F,IAAI,CAAC,SAAS,OAAO;CACrB,MAAM,SAAmB,CAAC;CAC1B,KAAK,MAAM,OAAO,0BAA0B;EAC1C,MAAM,QAAQ,QAAQ;EACtB,IAAI,UAAU,KAAA,GACZ,OAAO,KAAK,GAAG,IAAI,GAAG,mBAAmB,KAAK,GAAG;CAErD;CACA,IAAI,OAAO,WAAW,GAAG,OAAO;CAEhC,OAAO,GAAG,MADQ,IAAI,SAAS,GAAG,IAAI,MAAM,MAChB,OAAO,KAAK,GAAG;AAC7C;;;;;;AAOA,SAAS,sBACP,SACA,WACM;CACN,IAAI,CAAC,WAAW;CAChB,IAAI,UAAU,MACZ,QAAQ,8BAA8B,UAAU;CAElD,IAAI,UAAU,sBACZ,QAAQ,gDAAgD,OAAO,UAAU,oBAAoB;AAEjG;;;;;;AAOA,SAAS,qBACP,SACA,WACM;CACN,IAAI,CAAC,WAAW;CAChB,QAAQ,0BAA0B;AACpC"}
@@ -1 +1 @@
1
- {"version":3,"file":"url.cjs","names":[],"sources":["../../src/raw/url.ts"],"sourcesContent":["/**\n * B2-style API version segment, such as `v1`, `v3`, or `v4`.\n *\n * The template-literal type documents the compile-time shape; use\n * {@link isB2ApiVersion} when accepting untyped runtime input.\n */\nexport type B2ApiVersion = `v${number}`\n\nconst SLASH = '/'\nconst BACKSLASH = '\\\\'\nconst VERSION_PREFIX = 'v'\nconst VERSION_DIGITS = '0123456789'\nconst URL_DELIMITERS = ['?', '#'] as const\n\n/** URL path options for a B2 API endpoint. */\nexport interface B2UrlOptions {\n /** Base path prefix before the optional version segment. Defaults to `b2api`. */\n readonly prefix?: string\n /**\n * Optional API version segment. SDK storage endpoints use `v3` and `v4`;\n * Computer Backup endpoints use the same `vN` segment shape under a\n * different prefix, such as `api/backup/v1`.\n */\n readonly version?: B2ApiVersion\n /** Endpoint name appended after the prefix and optional version. */\n readonly endpoint: string\n}\n\n/** URL path options for a B2 API surface before the endpoint is selected. */\nexport type B2EndpointUrlOptions = Omit<B2UrlOptions, 'endpoint'>\n\n/**\n * Returns true when `value` is a B2 API version segment of the form `vN`.\n *\n * @param value - Candidate API version segment.\n *\n * @returns Whether the value is a valid B2 API version segment.\n */\nexport function isB2ApiVersion(value: string): value is B2ApiVersion {\n if (!value.startsWith(VERSION_PREFIX) || value.length === VERSION_PREFIX.length) return false\n\n for (let index = VERSION_PREFIX.length; index < value.length; index += 1) {\n const digit = value[index]\n if (digit === undefined || !VERSION_DIGITS.includes(digit)) return false\n }\n\n return true\n}\n\nfunction assertB2ApiVersion(value: string): asserts value is B2ApiVersion {\n if (!isB2ApiVersion(value)) {\n throw new TypeError('Invalid version: expected a B2 API version segment like \"v3\"')\n }\n}\n\nfunction trimSlashes(\n value: string,\n { leading, trailing }: { readonly leading: boolean; readonly trailing: boolean },\n): string {\n let start = 0\n let end = value.length\n\n while (leading && start < end && value[start] === SLASH) {\n start += 1\n }\n while (trailing && end > start && value[end - 1] === SLASH) {\n end -= 1\n }\n\n return start === 0 && end === value.length ? value : value.slice(start, end)\n}\n\nfunction hasUrlDelimiter(value: string): boolean {\n return URL_DELIMITERS.some((delimiter) => value.includes(delimiter))\n}\n\nfunction hasEncodedPathDelimiter(value: string): boolean {\n const lowerValue = value.toLowerCase()\n return (\n lowerValue.includes('%2f') ||\n lowerValue.includes('%3f') ||\n lowerValue.includes('%23') ||\n lowerValue.includes('%5c')\n )\n}\n\nfunction withDotEscapesDecoded(value: string): string {\n let decoded = ''\n let index = 0\n\n while (index < value.length) {\n if (value.slice(index, index + 3).toLowerCase() === '%2e') {\n decoded += '.'\n index += 3\n } else {\n decoded += value[index]\n index += 1\n }\n }\n\n return decoded\n}\n\nfunction isTraversalComponent(value: string): boolean {\n const decoded = withDotEscapesDecoded(value)\n return decoded === '.' || decoded === '..'\n}\n\nfunction validatePathComponent(component: string, optionName: string): void {\n if (component.length === 0) {\n throw new TypeError(`Invalid ${optionName}: path components must not be empty`)\n }\n if (hasUrlDelimiter(component)) {\n throw new TypeError(`Invalid ${optionName}: path components must not contain \"?\" or \"#\"`)\n }\n if (component.includes(BACKSLASH)) {\n throw new TypeError(`Invalid ${optionName}: path components must not contain \"\\\\\"`)\n }\n if (hasEncodedPathDelimiter(component)) {\n throw new TypeError(\n `Invalid ${optionName}: path components must not contain encoded \"/\", \"\\\\\", \"?\", or \"#\"`,\n )\n }\n if (isTraversalComponent(component)) {\n throw new TypeError(`Invalid ${optionName}: path components must not be \".\" or \"..\"`)\n }\n}\n\nfunction preparePathPrefix(prefix: string): string {\n const trimmed = trimSlashes(prefix, { leading: true, trailing: true })\n if (trimmed.length === 0) return ''\n\n for (const component of trimmed.split(SLASH)) {\n validatePathComponent(component, 'prefix')\n }\n\n return trimmed\n}\n\nfunction preparePathSegment(segment: string, optionName: string): string {\n const trimmed = trimSlashes(segment, { leading: true, trailing: true })\n if (trimmed.length === 0) return ''\n if (trimmed.includes(SLASH)) {\n throw new TypeError(`Invalid ${optionName}: expected a single path segment`)\n }\n\n validatePathComponent(trimmed, optionName)\n return trimmed\n}\n\nfunction prepareVersionSegment(version: B2ApiVersion): B2ApiVersion {\n const trimmed = preparePathSegment(version, 'version')\n assertB2ApiVersion(trimmed)\n return trimmed\n}\n\n/**\n * Builds a B2 API endpoint URL from a base URL, path prefix, optional version,\n * and endpoint name.\n *\n * @param baseUrl - API or download base URL.\n * @param options - Path prefix, optional version, and endpoint name.\n *\n * @returns The absolute endpoint URL.\n */\nexport function b2Url(\n baseUrl: string,\n { prefix = 'b2api', version, endpoint }: B2UrlOptions,\n): string {\n const base = trimSlashes(baseUrl, { leading: false, trailing: true })\n const path = [\n preparePathPrefix(prefix),\n version === undefined ? undefined : prepareVersionSegment(version),\n preparePathSegment(endpoint, 'endpoint'),\n ]\n .filter((segment): segment is string => segment !== undefined)\n .filter((segment) => segment.length > 0)\n .join(SLASH)\n\n return path.length === 0 ? base : `${base}/${path}`\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"url.cjs","names":[],"sources":["../../src/raw/url.ts"],"sourcesContent":["/**\n * B2-style API version segment, such as `v1`, `v3`, or `v4`.\n *\n * The template-literal type documents the compile-time shape; use\n * {@link isB2ApiVersion} when accepting untyped runtime input.\n */\nexport type B2ApiVersion = `v${number}`\n\nconst SLASH = '/'\nconst BACKSLASH = '\\\\'\nconst VERSION_PREFIX = 'v'\nconst VERSION_DIGITS = '0123456789'\nconst URL_DELIMITERS = ['?', '#'] as const\n\n/** URL path options for a B2 API endpoint. */\nexport interface B2UrlOptions {\n /** Base path prefix before the optional version segment. Defaults to `b2api`. */\n readonly prefix?: string\n /**\n * Optional API version segment. SDK-built B2 native storage endpoints use\n * the current published `v4` segment; Computer Backup endpoints use the same\n * `vN` segment shape under a different prefix, such as `api/backup/v1`.\n */\n readonly version?: B2ApiVersion\n /** Endpoint name appended after the prefix and optional version. */\n readonly endpoint: string\n}\n\n/** URL path options for a B2 API surface before the endpoint is selected. */\nexport type B2EndpointUrlOptions = Omit<B2UrlOptions, 'endpoint'>\n\n/**\n * Returns true when `value` is a B2 API version segment of the form `vN`.\n *\n * @param value - Candidate API version segment.\n *\n * @returns Whether the value is a valid B2 API version segment.\n */\nexport function isB2ApiVersion(value: string): value is B2ApiVersion {\n if (!value.startsWith(VERSION_PREFIX) || value.length === VERSION_PREFIX.length) return false\n\n for (let index = VERSION_PREFIX.length; index < value.length; index += 1) {\n const digit = value[index]\n if (digit === undefined || !VERSION_DIGITS.includes(digit)) return false\n }\n\n return true\n}\n\nfunction assertB2ApiVersion(value: string): asserts value is B2ApiVersion {\n if (!isB2ApiVersion(value)) {\n throw new TypeError('Invalid version: expected a B2 API version segment like \"v3\"')\n }\n}\n\nfunction trimSlashes(\n value: string,\n { leading, trailing }: { readonly leading: boolean; readonly trailing: boolean },\n): string {\n let start = 0\n let end = value.length\n\n while (leading && start < end && value[start] === SLASH) {\n start += 1\n }\n while (trailing && end > start && value[end - 1] === SLASH) {\n end -= 1\n }\n\n return start === 0 && end === value.length ? value : value.slice(start, end)\n}\n\nfunction hasUrlDelimiter(value: string): boolean {\n return URL_DELIMITERS.some((delimiter) => value.includes(delimiter))\n}\n\nfunction hasEncodedPathDelimiter(value: string): boolean {\n const lowerValue = value.toLowerCase()\n return (\n lowerValue.includes('%2f') ||\n lowerValue.includes('%3f') ||\n lowerValue.includes('%23') ||\n lowerValue.includes('%5c')\n )\n}\n\nfunction withDotEscapesDecoded(value: string): string {\n let decoded = ''\n let index = 0\n\n while (index < value.length) {\n if (value.slice(index, index + 3).toLowerCase() === '%2e') {\n decoded += '.'\n index += 3\n } else {\n decoded += value[index]\n index += 1\n }\n }\n\n return decoded\n}\n\nfunction isTraversalComponent(value: string): boolean {\n const decoded = withDotEscapesDecoded(value)\n return decoded === '.' || decoded === '..'\n}\n\nfunction validatePathComponent(component: string, optionName: string): void {\n if (component.length === 0) {\n throw new TypeError(`Invalid ${optionName}: path components must not be empty`)\n }\n if (hasUrlDelimiter(component)) {\n throw new TypeError(`Invalid ${optionName}: path components must not contain \"?\" or \"#\"`)\n }\n if (component.includes(BACKSLASH)) {\n throw new TypeError(`Invalid ${optionName}: path components must not contain \"\\\\\"`)\n }\n if (hasEncodedPathDelimiter(component)) {\n throw new TypeError(\n `Invalid ${optionName}: path components must not contain encoded \"/\", \"\\\\\", \"?\", or \"#\"`,\n )\n }\n if (isTraversalComponent(component)) {\n throw new TypeError(`Invalid ${optionName}: path components must not be \".\" or \"..\"`)\n }\n}\n\nfunction preparePathPrefix(prefix: string): string {\n const trimmed = trimSlashes(prefix, { leading: true, trailing: true })\n if (trimmed.length === 0) return ''\n\n for (const component of trimmed.split(SLASH)) {\n validatePathComponent(component, 'prefix')\n }\n\n return trimmed\n}\n\nfunction preparePathSegment(segment: string, optionName: string): string {\n const trimmed = trimSlashes(segment, { leading: true, trailing: true })\n if (trimmed.length === 0) return ''\n if (trimmed.includes(SLASH)) {\n throw new TypeError(`Invalid ${optionName}: expected a single path segment`)\n }\n\n validatePathComponent(trimmed, optionName)\n return trimmed\n}\n\nfunction prepareVersionSegment(version: B2ApiVersion): B2ApiVersion {\n const trimmed = preparePathSegment(version, 'version')\n assertB2ApiVersion(trimmed)\n return trimmed\n}\n\n/**\n * Builds a B2 API endpoint URL from a base URL, path prefix, optional version,\n * and endpoint name.\n *\n * @param baseUrl - API or download base URL.\n * @param options - Path prefix, optional version, and endpoint name.\n *\n * @returns The absolute endpoint URL.\n */\nexport function b2Url(\n baseUrl: string,\n { prefix = 'b2api', version, endpoint }: B2UrlOptions,\n): string {\n const base = trimSlashes(baseUrl, { leading: false, trailing: true })\n const path = [\n preparePathPrefix(prefix),\n version === undefined ? undefined : prepareVersionSegment(version),\n preparePathSegment(endpoint, 'endpoint'),\n ]\n .filter((segment): segment is string => segment !== undefined)\n .filter((segment) => segment.length > 0)\n .join(SLASH)\n\n return path.length === 0 ? base : `${base}/${path}`\n}\n"],"mappings":"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"}
@@ -10,9 +10,9 @@ export interface B2UrlOptions {
10
10
  /** Base path prefix before the optional version segment. Defaults to `b2api`. */
11
11
  readonly prefix?: string;
12
12
  /**
13
- * Optional API version segment. SDK storage endpoints use `v3` and `v4`;
14
- * Computer Backup endpoints use the same `vN` segment shape under a
15
- * different prefix, such as `api/backup/v1`.
13
+ * Optional API version segment. SDK-built B2 native storage endpoints use
14
+ * the current published `v4` segment; Computer Backup endpoints use the same
15
+ * `vN` segment shape under a different prefix, such as `api/backup/v1`.
16
16
  */
17
17
  readonly version?: B2ApiVersion;
18
18
  /** Endpoint name appended after the prefix and optional version. */
package/dist/raw/url.d.ts CHANGED
@@ -10,9 +10,9 @@ export interface B2UrlOptions {
10
10
  /** Base path prefix before the optional version segment. Defaults to `b2api`. */
11
11
  readonly prefix?: string;
12
12
  /**
13
- * Optional API version segment. SDK storage endpoints use `v3` and `v4`;
14
- * Computer Backup endpoints use the same `vN` segment shape under a
15
- * different prefix, such as `api/backup/v1`.
13
+ * Optional API version segment. SDK-built B2 native storage endpoints use
14
+ * the current published `v4` segment; Computer Backup endpoints use the same
15
+ * `vN` segment shape under a different prefix, such as `api/backup/v1`.
16
16
  */
17
17
  readonly version?: B2ApiVersion;
18
18
  /** Endpoint name appended after the prefix and optional version. */