@backblaze-labs/b2-sdk 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (393) hide show
  1. package/CHANGELOG.md +45 -1
  2. package/README.md +18 -5
  3. package/dist/_virtual/_b2-sdk-version-json.cjs +1 -1
  4. package/dist/_virtual/_b2-sdk-version-json.js +1 -1
  5. package/dist/auth/reauth-coalescer.cjs +65 -0
  6. package/dist/auth/reauth-coalescer.cjs.map +1 -0
  7. package/dist/auth/reauth-coalescer.d.cts +34 -0
  8. package/dist/auth/reauth-coalescer.d.cts.map +1 -0
  9. package/dist/auth/reauth-coalescer.d.ts +34 -0
  10. package/dist/auth/reauth-coalescer.d.ts.map +1 -0
  11. package/dist/auth/reauth-coalescer.js +65 -0
  12. package/dist/auth/reauth-coalescer.js.map +1 -0
  13. package/dist/backup/raw.cjs +37 -15
  14. package/dist/backup/raw.cjs.map +1 -1
  15. package/dist/backup/raw.d.cts +2 -2
  16. package/dist/backup/raw.d.cts.map +1 -1
  17. package/dist/backup/raw.d.ts +2 -2
  18. package/dist/backup/raw.d.ts.map +1 -1
  19. package/dist/backup/raw.js +37 -15
  20. package/dist/backup/raw.js.map +1 -1
  21. package/dist/bucket-validation.cjs +111 -0
  22. package/dist/bucket-validation.cjs.map +1 -0
  23. package/dist/bucket-validation.d.cts +27 -0
  24. package/dist/bucket-validation.d.cts.map +1 -0
  25. package/dist/bucket-validation.d.ts +27 -0
  26. package/dist/bucket-validation.d.ts.map +1 -0
  27. package/dist/bucket-validation.js +109 -0
  28. package/dist/bucket-validation.js.map +1 -0
  29. package/dist/bucket.cjs +123 -73
  30. package/dist/bucket.cjs.map +1 -1
  31. package/dist/bucket.d.cts +156 -61
  32. package/dist/bucket.d.cts.map +1 -1
  33. package/dist/bucket.d.ts +156 -61
  34. package/dist/bucket.d.ts.map +1 -1
  35. package/dist/bucket.js +123 -73
  36. package/dist/bucket.js.map +1 -1
  37. package/dist/client.cjs +29 -8
  38. package/dist/client.cjs.map +1 -1
  39. package/dist/client.d.cts +30 -9
  40. package/dist/client.d.cts.map +1 -1
  41. package/dist/client.d.ts +30 -9
  42. package/dist/client.d.ts.map +1 -1
  43. package/dist/client.js +29 -8
  44. package/dist/client.js.map +1 -1
  45. package/dist/download/single.cjs +38 -13
  46. package/dist/download/single.cjs.map +1 -1
  47. package/dist/download/single.d.cts +10 -4
  48. package/dist/download/single.d.cts.map +1 -1
  49. package/dist/download/single.d.ts +10 -4
  50. package/dist/download/single.d.ts.map +1 -1
  51. package/dist/download/single.js +38 -13
  52. package/dist/download/single.js.map +1 -1
  53. package/dist/errors/index.cjs +27 -4
  54. package/dist/errors/index.cjs.map +1 -1
  55. package/dist/errors/index.d.cts +15 -0
  56. package/dist/errors/index.d.cts.map +1 -1
  57. package/dist/errors/index.d.ts +15 -0
  58. package/dist/errors/index.d.ts.map +1 -1
  59. package/dist/errors/index.js +27 -5
  60. package/dist/errors/index.js.map +1 -1
  61. package/dist/http/non-idempotent-mutations.cjs +38 -0
  62. package/dist/http/non-idempotent-mutations.cjs.map +1 -0
  63. package/dist/http/non-idempotent-mutations.d.cts +25 -0
  64. package/dist/http/non-idempotent-mutations.d.cts.map +1 -0
  65. package/dist/http/non-idempotent-mutations.d.ts +25 -0
  66. package/dist/http/non-idempotent-mutations.d.ts.map +1 -0
  67. package/dist/http/non-idempotent-mutations.js +35 -0
  68. package/dist/http/non-idempotent-mutations.js.map +1 -0
  69. package/dist/http/transport.cjs +9 -8
  70. package/dist/http/transport.cjs.map +1 -1
  71. package/dist/http/transport.d.cts +5 -0
  72. package/dist/http/transport.d.cts.map +1 -1
  73. package/dist/http/transport.d.ts +5 -0
  74. package/dist/http/transport.d.ts.map +1 -1
  75. package/dist/http/transport.js +9 -8
  76. package/dist/http/transport.js.map +1 -1
  77. package/dist/http/user-agent.cjs +12 -1
  78. package/dist/http/user-agent.cjs.map +1 -1
  79. package/dist/http/user-agent.d.cts +8 -0
  80. package/dist/http/user-agent.d.cts.map +1 -1
  81. package/dist/http/user-agent.d.ts +8 -0
  82. package/dist/http/user-agent.d.ts.map +1 -1
  83. package/dist/http/user-agent.js +13 -3
  84. package/dist/http/user-agent.js.map +1 -1
  85. package/dist/index.cjs +25 -0
  86. package/dist/index.d.cts +10 -9
  87. package/dist/index.d.cts.map +1 -1
  88. package/dist/index.d.ts +10 -9
  89. package/dist/index.d.ts.map +1 -1
  90. package/dist/index.js +7 -6
  91. package/dist/notifications/index.cjs +3 -0
  92. package/dist/notifications/index.d.cts +2 -0
  93. package/dist/notifications/index.d.cts.map +1 -1
  94. package/dist/notifications/index.d.ts +2 -0
  95. package/dist/notifications/index.d.ts.map +1 -1
  96. package/dist/notifications/index.js +2 -1
  97. package/dist/object.cjs +12 -1
  98. package/dist/object.cjs.map +1 -1
  99. package/dist/object.d.cts +7 -1
  100. package/dist/object.d.cts.map +1 -1
  101. package/dist/object.d.ts +7 -1
  102. package/dist/object.d.ts.map +1 -1
  103. package/dist/object.js +12 -1
  104. package/dist/object.js.map +1 -1
  105. package/dist/partner/auth-core.cjs +4 -23
  106. package/dist/partner/auth-core.cjs.map +1 -1
  107. package/dist/partner/auth-core.d.cts +1 -1
  108. package/dist/partner/auth-core.d.cts.map +1 -1
  109. package/dist/partner/auth-core.d.ts +1 -1
  110. package/dist/partner/auth-core.d.ts.map +1 -1
  111. package/dist/partner/auth-core.js +5 -24
  112. package/dist/partner/auth-core.js.map +1 -1
  113. package/dist/partner/client.cjs +25 -10
  114. package/dist/partner/client.cjs.map +1 -1
  115. package/dist/partner/client.d.cts +32 -10
  116. package/dist/partner/client.d.cts.map +1 -1
  117. package/dist/partner/client.d.ts +32 -10
  118. package/dist/partner/client.d.ts.map +1 -1
  119. package/dist/partner/client.js +25 -10
  120. package/dist/partner/client.js.map +1 -1
  121. package/dist/partner/endpoint-url.cjs +1 -0
  122. package/dist/partner/endpoint-url.cjs.map +1 -1
  123. package/dist/partner/endpoint-url.d.cts +2 -0
  124. package/dist/partner/endpoint-url.d.cts.map +1 -1
  125. package/dist/partner/endpoint-url.d.ts +2 -0
  126. package/dist/partner/endpoint-url.d.ts.map +1 -1
  127. package/dist/partner/endpoint-url.js +1 -0
  128. package/dist/partner/endpoint-url.js.map +1 -1
  129. package/dist/partner/in-memory.cjs.map +1 -1
  130. package/dist/partner/in-memory.js.map +1 -1
  131. package/dist/partner/index.cjs +9 -0
  132. package/dist/partner/index.d.cts +11 -2
  133. package/dist/partner/index.d.cts.map +1 -1
  134. package/dist/partner/index.d.ts +11 -2
  135. package/dist/partner/index.d.ts.map +1 -1
  136. package/dist/partner/index.js +3 -1
  137. package/dist/partner/raw.cjs +52 -44
  138. package/dist/partner/raw.cjs.map +1 -1
  139. package/dist/partner/raw.d.cts +16 -19
  140. package/dist/partner/raw.d.cts.map +1 -1
  141. package/dist/partner/raw.d.ts +16 -19
  142. package/dist/partner/raw.d.ts.map +1 -1
  143. package/dist/partner/raw.js +52 -44
  144. package/dist/partner/raw.js.map +1 -1
  145. package/dist/partner/redaction.cjs +133 -108
  146. package/dist/partner/redaction.cjs.map +1 -1
  147. package/dist/partner/redaction.d.cts +47 -13
  148. package/dist/partner/redaction.d.cts.map +1 -1
  149. package/dist/partner/redaction.d.ts +47 -13
  150. package/dist/partner/redaction.d.ts.map +1 -1
  151. package/dist/partner/redaction.js +133 -109
  152. package/dist/partner/redaction.js.map +1 -1
  153. package/dist/raw/encoding.cjs +29 -10
  154. package/dist/raw/encoding.cjs.map +1 -1
  155. package/dist/raw/encoding.d.cts +3 -2
  156. package/dist/raw/encoding.d.cts.map +1 -1
  157. package/dist/raw/encoding.d.ts +3 -2
  158. package/dist/raw/encoding.d.ts.map +1 -1
  159. package/dist/raw/encoding.js +29 -10
  160. package/dist/raw/encoding.js.map +1 -1
  161. package/dist/raw/index.cjs +64 -39
  162. package/dist/raw/index.cjs.map +1 -1
  163. package/dist/raw/index.d.cts +21 -19
  164. package/dist/raw/index.d.cts.map +1 -1
  165. package/dist/raw/index.d.ts +21 -19
  166. package/dist/raw/index.d.ts.map +1 -1
  167. package/dist/raw/index.js +47 -40
  168. package/dist/raw/index.js.map +1 -1
  169. package/dist/raw/url.cjs.map +1 -1
  170. package/dist/raw/url.d.cts +3 -3
  171. package/dist/raw/url.d.ts +3 -3
  172. package/dist/raw/url.js.map +1 -1
  173. package/dist/simulator/index.cjs +456 -125
  174. package/dist/simulator/index.cjs.map +1 -1
  175. package/dist/simulator/index.d.cts +16 -1
  176. package/dist/simulator/index.d.cts.map +1 -1
  177. package/dist/simulator/index.d.ts +16 -1
  178. package/dist/simulator/index.d.ts.map +1 -1
  179. package/dist/simulator/index.js +449 -130
  180. package/dist/simulator/index.js.map +1 -1
  181. package/dist/simulator/partner-capabilities.cjs +77 -0
  182. package/dist/simulator/partner-capabilities.cjs.map +1 -0
  183. package/dist/simulator/partner-capabilities.d.cts +53 -0
  184. package/dist/simulator/partner-capabilities.d.cts.map +1 -0
  185. package/dist/simulator/partner-capabilities.d.ts +53 -0
  186. package/dist/simulator/partner-capabilities.d.ts.map +1 -0
  187. package/dist/simulator/partner-capabilities.js +73 -0
  188. package/dist/simulator/partner-capabilities.js.map +1 -0
  189. package/dist/simulator/partner.cjs +55 -61
  190. package/dist/simulator/partner.cjs.map +1 -1
  191. package/dist/simulator/partner.d.cts +5 -2
  192. package/dist/simulator/partner.d.cts.map +1 -1
  193. package/dist/simulator/partner.d.ts +5 -2
  194. package/dist/simulator/partner.d.ts.map +1 -1
  195. package/dist/simulator/partner.js +56 -61
  196. package/dist/simulator/partner.js.map +1 -1
  197. package/dist/simulator/validation.cjs +160 -30
  198. package/dist/simulator/validation.cjs.map +1 -1
  199. package/dist/simulator/validation.d.cts +28 -6
  200. package/dist/simulator/validation.d.cts.map +1 -1
  201. package/dist/simulator/validation.d.ts +28 -6
  202. package/dist/simulator/validation.d.ts.map +1 -1
  203. package/dist/simulator/validation.js +148 -31
  204. package/dist/simulator/validation.js.map +1 -1
  205. package/dist/streams/file-source.cjs +1 -1
  206. package/dist/streams/file-source.cjs.map +1 -1
  207. package/dist/streams/file-source.js +1 -1
  208. package/dist/streams/file-source.js.map +1 -1
  209. package/dist/streams/hash.cjs +246 -13
  210. package/dist/streams/hash.cjs.map +1 -1
  211. package/dist/streams/hash.d.cts +37 -12
  212. package/dist/streams/hash.d.cts.map +1 -1
  213. package/dist/streams/hash.d.ts +37 -12
  214. package/dist/streams/hash.d.ts.map +1 -1
  215. package/dist/streams/hash.js +246 -15
  216. package/dist/streams/hash.js.map +1 -1
  217. package/dist/streams/index.cjs +2 -0
  218. package/dist/streams/index.d.cts +1 -1
  219. package/dist/streams/index.d.cts.map +1 -1
  220. package/dist/streams/index.d.ts +1 -1
  221. package/dist/streams/index.d.ts.map +1 -1
  222. package/dist/streams/index.js +2 -2
  223. package/dist/streams/progress.cjs +63 -4
  224. package/dist/streams/progress.cjs.map +1 -1
  225. package/dist/streams/progress.d.cts +28 -2
  226. package/dist/streams/progress.d.cts.map +1 -1
  227. package/dist/streams/progress.d.ts +28 -2
  228. package/dist/streams/progress.d.ts.map +1 -1
  229. package/dist/streams/progress.js +63 -4
  230. package/dist/streams/progress.js.map +1 -1
  231. package/dist/sync/download-staging.cjs +147 -35
  232. package/dist/sync/download-staging.cjs.map +1 -1
  233. package/dist/sync/download-staging.d.cts +25 -2
  234. package/dist/sync/download-staging.d.cts.map +1 -1
  235. package/dist/sync/download-staging.d.ts +25 -2
  236. package/dist/sync/download-staging.d.ts.map +1 -1
  237. package/dist/sync/download-staging.js +146 -36
  238. package/dist/sync/download-staging.js.map +1 -1
  239. package/dist/sync/index.d.cts +1 -1
  240. package/dist/sync/index.d.cts.map +1 -1
  241. package/dist/sync/index.d.ts +1 -1
  242. package/dist/sync/index.d.ts.map +1 -1
  243. package/dist/sync/local-file-io.cjs +5 -1
  244. package/dist/sync/local-file-io.cjs.map +1 -1
  245. package/dist/sync/local-file-io.d.cts +2 -0
  246. package/dist/sync/local-file-io.d.cts.map +1 -1
  247. package/dist/sync/local-file-io.d.ts +2 -0
  248. package/dist/sync/local-file-io.d.ts.map +1 -1
  249. package/dist/sync/local-file-io.js +5 -1
  250. package/dist/sync/local-file-io.js.map +1 -1
  251. package/dist/sync/pairing.cjs +1 -0
  252. package/dist/sync/pairing.cjs.map +1 -1
  253. package/dist/sync/pairing.js +1 -0
  254. package/dist/sync/pairing.js.map +1 -1
  255. package/dist/sync/scanners/b2.cjs +2 -0
  256. package/dist/sync/scanners/b2.cjs.map +1 -1
  257. package/dist/sync/scanners/b2.d.cts.map +1 -1
  258. package/dist/sync/scanners/b2.d.ts.map +1 -1
  259. package/dist/sync/scanners/b2.js +2 -0
  260. package/dist/sync/scanners/b2.js.map +1 -1
  261. package/dist/sync/scanners/local.cjs +150 -33
  262. package/dist/sync/scanners/local.cjs.map +1 -1
  263. package/dist/sync/scanners/local.d.cts +6 -0
  264. package/dist/sync/scanners/local.d.cts.map +1 -1
  265. package/dist/sync/scanners/local.d.ts +6 -0
  266. package/dist/sync/scanners/local.d.ts.map +1 -1
  267. package/dist/sync/scanners/local.js +150 -33
  268. package/dist/sync/scanners/local.js.map +1 -1
  269. package/dist/sync/synchronizer.cjs +76 -29
  270. package/dist/sync/synchronizer.cjs.map +1 -1
  271. package/dist/sync/synchronizer.d.cts +1 -0
  272. package/dist/sync/synchronizer.d.cts.map +1 -1
  273. package/dist/sync/synchronizer.d.ts +1 -0
  274. package/dist/sync/synchronizer.d.ts.map +1 -1
  275. package/dist/sync/synchronizer.js +76 -29
  276. package/dist/sync/synchronizer.js.map +1 -1
  277. package/dist/sync/types.d.cts +19 -3
  278. package/dist/sync/types.d.cts.map +1 -1
  279. package/dist/sync/types.d.ts +19 -3
  280. package/dist/sync/types.d.ts.map +1 -1
  281. package/dist/types/backup.d.cts +6 -1
  282. package/dist/types/backup.d.cts.map +1 -1
  283. package/dist/types/backup.d.ts +6 -1
  284. package/dist/types/backup.d.ts.map +1 -1
  285. package/dist/types/bucket.cjs +81 -11
  286. package/dist/types/bucket.cjs.map +1 -1
  287. package/dist/types/bucket.d.cts +190 -39
  288. package/dist/types/bucket.d.cts.map +1 -1
  289. package/dist/types/bucket.d.ts +190 -39
  290. package/dist/types/bucket.d.ts.map +1 -1
  291. package/dist/types/bucket.js +67 -12
  292. package/dist/types/bucket.js.map +1 -1
  293. package/dist/types/download.cjs.map +1 -1
  294. package/dist/types/download.d.cts +3 -17
  295. package/dist/types/download.d.cts.map +1 -1
  296. package/dist/types/download.d.ts +3 -17
  297. package/dist/types/download.d.ts.map +1 -1
  298. package/dist/types/download.js.map +1 -1
  299. package/dist/types/encryption.cjs +18 -0
  300. package/dist/types/encryption.cjs.map +1 -1
  301. package/dist/types/encryption.d.cts +21 -11
  302. package/dist/types/encryption.d.cts.map +1 -1
  303. package/dist/types/encryption.d.ts +21 -11
  304. package/dist/types/encryption.d.ts.map +1 -1
  305. package/dist/types/encryption.js +18 -0
  306. package/dist/types/encryption.js.map +1 -1
  307. package/dist/types/file.cjs +3 -0
  308. package/dist/types/file.cjs.map +1 -1
  309. package/dist/types/file.d.cts +125 -16
  310. package/dist/types/file.d.cts.map +1 -1
  311. package/dist/types/file.d.ts +125 -16
  312. package/dist/types/file.d.ts.map +1 -1
  313. package/dist/types/file.js +3 -1
  314. package/dist/types/file.js.map +1 -1
  315. package/dist/types/index.d.cts +7 -7
  316. package/dist/types/index.d.cts.map +1 -1
  317. package/dist/types/index.d.ts +7 -7
  318. package/dist/types/index.d.ts.map +1 -1
  319. package/dist/types/key.d.cts +4 -3
  320. package/dist/types/key.d.cts.map +1 -1
  321. package/dist/types/key.d.ts +4 -3
  322. package/dist/types/key.d.ts.map +1 -1
  323. package/dist/types/notifications.cjs +30 -0
  324. package/dist/types/notifications.cjs.map +1 -1
  325. package/dist/types/notifications.d.cts +26 -1
  326. package/dist/types/notifications.d.cts.map +1 -1
  327. package/dist/types/notifications.d.ts +26 -1
  328. package/dist/types/notifications.d.ts.map +1 -1
  329. package/dist/types/notifications.js +29 -1
  330. package/dist/types/notifications.js.map +1 -1
  331. package/dist/types/partner.cjs.map +1 -1
  332. package/dist/types/partner.d.cts +28 -36
  333. package/dist/types/partner.d.cts.map +1 -1
  334. package/dist/types/partner.d.ts +28 -36
  335. package/dist/types/partner.d.ts.map +1 -1
  336. package/dist/types/partner.js.map +1 -1
  337. package/dist/types/upload.d.cts +4 -0
  338. package/dist/types/upload.d.cts.map +1 -1
  339. package/dist/types/upload.d.ts +4 -0
  340. package/dist/types/upload.d.ts.map +1 -1
  341. package/dist/upload/large.cjs +10 -7
  342. package/dist/upload/large.cjs.map +1 -1
  343. package/dist/upload/large.d.cts +15 -6
  344. package/dist/upload/large.d.cts.map +1 -1
  345. package/dist/upload/large.d.ts +15 -6
  346. package/dist/upload/large.d.ts.map +1 -1
  347. package/dist/upload/large.js +10 -7
  348. package/dist/upload/large.js.map +1 -1
  349. package/dist/upload/options.cjs.map +1 -1
  350. package/dist/upload/options.d.cts +12 -0
  351. package/dist/upload/options.d.cts.map +1 -1
  352. package/dist/upload/options.d.ts +12 -0
  353. package/dist/upload/options.d.ts.map +1 -1
  354. package/dist/upload/options.js.map +1 -1
  355. package/dist/upload/resume.cjs +4 -3
  356. package/dist/upload/resume.cjs.map +1 -1
  357. package/dist/upload/resume.d.cts +6 -4
  358. package/dist/upload/resume.d.cts.map +1 -1
  359. package/dist/upload/resume.d.ts +6 -4
  360. package/dist/upload/resume.d.ts.map +1 -1
  361. package/dist/upload/resume.js +4 -3
  362. package/dist/upload/resume.js.map +1 -1
  363. package/dist/upload/retry.cjs +17 -10
  364. package/dist/upload/retry.cjs.map +1 -1
  365. package/dist/upload/retry.d.cts.map +1 -1
  366. package/dist/upload/retry.d.ts.map +1 -1
  367. package/dist/upload/retry.js +17 -10
  368. package/dist/upload/retry.js.map +1 -1
  369. package/dist/upload/single.cjs +35 -31
  370. package/dist/upload/single.cjs.map +1 -1
  371. package/dist/upload/single.d.cts +6 -0
  372. package/dist/upload/single.d.cts.map +1 -1
  373. package/dist/upload/single.d.ts +6 -0
  374. package/dist/upload/single.d.ts.map +1 -1
  375. package/dist/upload/single.js +35 -31
  376. package/dist/upload/single.js.map +1 -1
  377. package/dist/upload/stream.cjs +12 -1
  378. package/dist/upload/stream.cjs.map +1 -1
  379. package/dist/upload/stream.d.cts +6 -0
  380. package/dist/upload/stream.d.cts.map +1 -1
  381. package/dist/upload/stream.d.ts +6 -0
  382. package/dist/upload/stream.d.ts.map +1 -1
  383. package/dist/upload/stream.js +12 -1
  384. package/dist/upload/stream.js.map +1 -1
  385. package/dist/version.cjs +56 -4
  386. package/dist/version.cjs.map +1 -1
  387. package/dist/version.d.cts +53 -4
  388. package/dist/version.d.cts.map +1 -1
  389. package/dist/version.d.ts +53 -4
  390. package/dist/version.d.ts.map +1 -1
  391. package/dist/version.js +52 -5
  392. package/dist/version.js.map +1 -1
  393. package/package.json +11 -4
@@ -1 +1 @@
1
- {"version":3,"file":"encoding.cjs","names":[],"sources":["../../src/raw/encoding.ts"],"sourcesContent":["import { utf8Encoder } from '../util/text-codec.ts'\n\n/**\n * Characters that B2 treats as safe (not percent-encoded) in file names.\n *\n * Per the B2 docs, everything except `a-z A-Z 0-9 - . _ ~ / ! $ & ' ( ) * + , ; = : @`\n * must be percent-encoded using UTF-8 byte values.\n */\nconst SAFE_CHARS = new Set(\n \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$&'()*+,;=:@/\".split(''),\n)\n\n/**\n * Percent-encodes a file name using the B2-specific encoding rules.\n *\n * Unlike standard `encodeURIComponent`, B2 keeps `/` and several other\n * characters unencoded while encoding all other non-ASCII and special\n * characters as uppercase percent-encoded UTF-8 bytes.\n *\n * @param name - The raw (unencoded) file name.\n *\n * @returns The percent-encoded file name suitable for `X-Bz-File-Name` headers.\n */\nexport function encodeFileName(name: string): string {\n const encoded: string[] = []\n for (const char of name) {\n if (SAFE_CHARS.has(char)) {\n encoded.push(char)\n } else {\n const bytes = utf8Encoder.encode(char)\n for (const byte of bytes) {\n encoded.push(`%${byte.toString(16).toUpperCase().padStart(2, '0')}`)\n }\n }\n }\n return encoded.join('')\n}\n\n/**\n * Decodes a B2 percent-encoded file name back to a plain string.\n *\n * B2 percent-encoding is compatible with standard `decodeURIComponent`,\n * so this is a thin wrapper.\n *\n * @param encoded - The percent-encoded file name from B2.\n *\n * @returns The decoded file name.\n */\nexport function decodeFileName(encoded: string): string {\n return decodeURIComponent(encoded)\n}\n\n/**\n * Converts a file-info map into `X-Bz-Info-*` HTTP headers.\n *\n * Both keys and values are percent-encoded with {@link encodeFileName}\n * to satisfy B2 header requirements.\n *\n * @param fileInfo - Key/value pairs to attach as custom file info, or `undefined`.\n *\n * @returns A record of header name/value pairs (empty if `fileInfo` is `undefined`).\n */\nexport function buildFileInfoHeaders(\n fileInfo: Record<string, string> | undefined,\n): Record<string, string> {\n if (!fileInfo) return {}\n const headers: Record<string, string> = {}\n for (const [key, value] of Object.entries(fileInfo)) {\n headers[`X-Bz-Info-${encodeFileName(key)}`] = encodeFileName(value)\n }\n return headers\n}\n\n/**\n * Extracts custom file-info key/value pairs from B2 response headers.\n *\n * Scans for headers prefixed with `x-bz-info-` and decodes both the\n * key suffix and value using {@link decodeFileName}.\n *\n * @param headers - The HTTP response headers from a B2 download or file-info call.\n *\n * @returns A record of decoded file-info key/value pairs.\n */\nexport function parseFileInfoHeaders(headers: Headers): Record<string, string> {\n const info: Record<string, string> = {}\n headers.forEach((value, key) => {\n const lower = key.toLowerCase()\n if (lower.startsWith('x-bz-info-')) {\n const infoKey = decodeFileName(lower.slice('x-bz-info-'.length))\n info[infoKey] = decodeFileName(value)\n }\n })\n return info\n}\n"],"mappings":";;;;;;;;AAQA,IAAM,aAAa,IAAI,IACrB,mFAAmF,MAAM,EAAE,CAC7F;;;;;;;;;;;;AAaA,SAAgB,eAAe,MAAsB;CACnD,MAAM,UAAoB,CAAC;CAC3B,KAAK,MAAM,QAAQ,MACjB,IAAI,WAAW,IAAI,IAAI,GACrB,QAAQ,KAAK,IAAI;MACZ;EACL,MAAM,QAAQ,mBAAA,YAAY,OAAO,IAAI;EACrC,KAAK,MAAM,QAAQ,OACjB,QAAQ,KAAK,IAAI,KAAK,SAAS,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG;CAEvE;CAEF,OAAO,QAAQ,KAAK,EAAE;AACxB;;;;;;;;;;;AAYA,SAAgB,eAAe,SAAyB;CACtD,OAAO,mBAAmB,OAAO;AACnC;;;;;;;;;;;AAYA,SAAgB,qBACd,UACwB;CACxB,IAAI,CAAC,UAAU,OAAO,CAAC;CACvB,MAAM,UAAkC,CAAC;CACzC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,GAChD,QAAQ,aAAa,eAAe,GAAG,OAAO,eAAe,KAAK;CAEpE,OAAO;AACT;;;;;;;;;;;AAYA,SAAgB,qBAAqB,SAA0C;CAC7E,MAAM,OAA+B,CAAC;CACtC,QAAQ,SAAS,OAAO,QAAQ;EAC9B,MAAM,QAAQ,IAAI,YAAY;EAC9B,IAAI,MAAM,WAAW,YAAY,GAAG;GAClC,MAAM,UAAU,eAAe,MAAM,MAAM,EAAmB,CAAC;GAC/D,KAAK,WAAW,eAAe,KAAK;EACtC;CACF,CAAC;CACD,OAAO;AACT"}
1
+ {"version":3,"file":"encoding.cjs","names":[],"sources":["../../src/raw/encoding.ts"],"sourcesContent":["import { utf8Encoder } from '../util/text-codec.ts'\n\n/**\n * Characters that B2 treats as safe (not percent-encoded) in file names.\n *\n * Per the B2 docs, everything except `a-z A-Z 0-9 - . _ ~ / ! $ & ' ( ) * + , ; = : @`\n * must be percent-encoded using UTF-8 byte values.\n */\nconst SAFE_CHARS = new Set(\n \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$&'()*+,;=:@/\".split(''),\n)\n\nconst FILE_INFO_VALUE_SAFE_CHARS = new Set(\n 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~'.split(''),\n)\n\nfunction encodeWithSafeChars(value: string, safeChars: ReadonlySet<string>): string {\n const encoded: string[] = []\n for (const char of value) {\n if (safeChars.has(char)) {\n encoded.push(char)\n } else {\n const bytes = utf8Encoder.encode(char)\n for (const byte of bytes) {\n encoded.push(`%${byte.toString(16).toUpperCase().padStart(2, '0')}`)\n }\n }\n }\n return encoded.join('')\n}\n\n/**\n * Percent-encodes a file name using the B2-specific encoding rules.\n *\n * Unlike standard `encodeURIComponent`, B2 keeps `/` and several other\n * characters unencoded while encoding all other non-ASCII and special\n * characters as uppercase percent-encoded UTF-8 bytes.\n *\n * @param name - The raw (unencoded) file name.\n *\n * @returns The percent-encoded file name suitable for `X-Bz-File-Name` headers.\n */\nexport function encodeFileName(name: string): string {\n return encodeWithSafeChars(name, SAFE_CHARS)\n}\n\n/**\n * Percent-encodes a file-info value using the stricter B2 metadata value rules.\n *\n * File-info values must be decoded by B2 before storage. Live B2 rejects comma\n * and other RFC punctuation when left raw in these values, so only RFC 3986\n * unreserved characters are passed through.\n *\n * @param value - The raw (unencoded) file-info value.\n *\n * @returns The percent-encoded value suitable for `X-Bz-Info-*` header values.\n */\nfunction encodeFileInfoValue(value: string): string {\n return encodeWithSafeChars(value, FILE_INFO_VALUE_SAFE_CHARS)\n}\n\n/**\n * Decodes a B2 percent-encoded file name back to a plain string.\n *\n * B2 percent-encoding is compatible with standard `decodeURIComponent`,\n * so this is a thin wrapper.\n *\n * @param encoded - The percent-encoded file name from B2.\n *\n * @returns The decoded file name.\n */\nexport function decodeFileName(encoded: string): string {\n return decodeURIComponent(encoded)\n}\n\n/**\n * Converts a file-info map into `X-Bz-Info-*` HTTP headers.\n *\n * Keys use B2 file-name encoding. Values use stricter B2 file-info value\n * encoding so punctuation such as commas is percent-encoded before B2 decodes\n * and validates stored metadata.\n *\n * @param fileInfo - Key/value pairs to attach as custom file info, or `undefined`.\n *\n * @returns A record of header name/value pairs (empty if `fileInfo` is `undefined`).\n */\nexport function buildFileInfoHeaders(\n fileInfo: Record<string, string> | undefined,\n): Record<string, string> {\n if (!fileInfo) return {}\n const headers: Record<string, string> = {}\n for (const [key, value] of Object.entries(fileInfo)) {\n headers[`X-Bz-Info-${encodeFileName(key)}`] = encodeFileInfoValue(value)\n }\n return headers\n}\n\n/**\n * Extracts custom file-info key/value pairs from B2 response headers.\n *\n * Scans for headers prefixed with `x-bz-info-` and decodes both the\n * key suffix and value using {@link decodeFileName}.\n *\n * @param headers - The HTTP response headers from a B2 download or file-info call.\n *\n * @returns A record of decoded file-info key/value pairs.\n */\nexport function parseFileInfoHeaders(headers: Headers): Record<string, string> {\n const info: Record<string, string> = {}\n headers.forEach((value, key) => {\n const lower = key.toLowerCase()\n if (lower.startsWith('x-bz-info-')) {\n const infoKey = decodeFileName(lower.slice('x-bz-info-'.length))\n info[infoKey] = decodeFileName(value)\n }\n })\n return info\n}\n"],"mappings":";;;;;;;;AAQA,IAAM,aAAa,IAAI,IACrB,mFAAmF,MAAM,EAAE,CAC7F;AAEA,IAAM,6BAA6B,IAAI,IACrC,qEAAqE,MAAM,EAAE,CAC/E;AAEA,SAAS,oBAAoB,OAAe,WAAwC;CAClF,MAAM,UAAoB,CAAC;CAC3B,KAAK,MAAM,QAAQ,OACjB,IAAI,UAAU,IAAI,IAAI,GACpB,QAAQ,KAAK,IAAI;MACZ;EACL,MAAM,QAAQ,mBAAA,YAAY,OAAO,IAAI;EACrC,KAAK,MAAM,QAAQ,OACjB,QAAQ,KAAK,IAAI,KAAK,SAAS,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG;CAEvE;CAEF,OAAO,QAAQ,KAAK,EAAE;AACxB;;;;;;;;;;;;AAaA,SAAgB,eAAe,MAAsB;CACnD,OAAO,oBAAoB,MAAM,UAAU;AAC7C;;;;;;;;;;;;AAaA,SAAS,oBAAoB,OAAuB;CAClD,OAAO,oBAAoB,OAAO,0BAA0B;AAC9D;;;;;;;;;;;AAYA,SAAgB,eAAe,SAAyB;CACtD,OAAO,mBAAmB,OAAO;AACnC;;;;;;;;;;;;AAaA,SAAgB,qBACd,UACwB;CACxB,IAAI,CAAC,UAAU,OAAO,CAAC;CACvB,MAAM,UAAkC,CAAC;CACzC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,GAChD,QAAQ,aAAa,eAAe,GAAG,OAAO,oBAAoB,KAAK;CAEzE,OAAO;AACT;;;;;;;;;;;AAYA,SAAgB,qBAAqB,SAA0C;CAC7E,MAAM,OAA+B,CAAC;CACtC,QAAQ,SAAS,OAAO,QAAQ;EAC9B,MAAM,QAAQ,IAAI,YAAY;EAC9B,IAAI,MAAM,WAAW,YAAY,GAAG;GAClC,MAAM,UAAU,eAAe,MAAM,MAAM,EAAmB,CAAC;GAC/D,KAAK,WAAW,eAAe,KAAK;EACtC;CACF,CAAC;CACD,OAAO;AACT"}
@@ -24,8 +24,9 @@ export declare function decodeFileName(encoded: string): string;
24
24
  /**
25
25
  * Converts a file-info map into `X-Bz-Info-*` HTTP headers.
26
26
  *
27
- * Both keys and values are percent-encoded with {@link encodeFileName}
28
- * to satisfy B2 header requirements.
27
+ * Keys use B2 file-name encoding. Values use stricter B2 file-info value
28
+ * encoding so punctuation such as commas is percent-encoded before B2 decodes
29
+ * and validates stored metadata.
29
30
  *
30
31
  * @param fileInfo - Key/value pairs to attach as custom file info, or `undefined`.
31
32
  *
@@ -1 +1 @@
1
- {"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../../src/raw/encoding.js"],"names":[],"mappings":"AAYA;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAanD;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GAC3C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOxB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAU7E"}
1
+ {"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../../src/raw/encoding.js"],"names":[],"mappings":"AA+BA;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAiBD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GAC3C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOxB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAU7E"}
@@ -24,8 +24,9 @@ export declare function decodeFileName(encoded: string): string;
24
24
  /**
25
25
  * Converts a file-info map into `X-Bz-Info-*` HTTP headers.
26
26
  *
27
- * Both keys and values are percent-encoded with {@link encodeFileName}
28
- * to satisfy B2 header requirements.
27
+ * Keys use B2 file-name encoding. Values use stricter B2 file-info value
28
+ * encoding so punctuation such as commas is percent-encoded before B2 decodes
29
+ * and validates stored metadata.
29
30
  *
30
31
  * @param fileInfo - Key/value pairs to attach as custom file info, or `undefined`.
31
32
  *
@@ -1 +1 @@
1
- {"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../../src/raw/encoding.js"],"names":[],"mappings":"AAYA;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAanD;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GAC3C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOxB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAU7E"}
1
+ {"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../../src/raw/encoding.js"],"names":[],"mappings":"AA+BA;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAiBD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GAC3C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOxB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAU7E"}
@@ -7,6 +7,16 @@ import { utf8Encoder } from "../util/text-codec.js";
7
7
  * must be percent-encoded using UTF-8 byte values.
8
8
  */
9
9
  var SAFE_CHARS = new Set("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$&'()*+,;=:@/".split(""));
10
+ var FILE_INFO_VALUE_SAFE_CHARS = new Set("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~".split(""));
11
+ function encodeWithSafeChars(value, safeChars) {
12
+ const encoded = [];
13
+ for (const char of value) if (safeChars.has(char)) encoded.push(char);
14
+ else {
15
+ const bytes = utf8Encoder.encode(char);
16
+ for (const byte of bytes) encoded.push(`%${byte.toString(16).toUpperCase().padStart(2, "0")}`);
17
+ }
18
+ return encoded.join("");
19
+ }
10
20
  /**
11
21
  * Percent-encodes a file name using the B2-specific encoding rules.
12
22
  *
@@ -19,13 +29,21 @@ var SAFE_CHARS = new Set("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01
19
29
  * @returns The percent-encoded file name suitable for `X-Bz-File-Name` headers.
20
30
  */
21
31
  function encodeFileName(name) {
22
- const encoded = [];
23
- for (const char of name) if (SAFE_CHARS.has(char)) encoded.push(char);
24
- else {
25
- const bytes = utf8Encoder.encode(char);
26
- for (const byte of bytes) encoded.push(`%${byte.toString(16).toUpperCase().padStart(2, "0")}`);
27
- }
28
- return encoded.join("");
32
+ return encodeWithSafeChars(name, SAFE_CHARS);
33
+ }
34
+ /**
35
+ * Percent-encodes a file-info value using the stricter B2 metadata value rules.
36
+ *
37
+ * File-info values must be decoded by B2 before storage. Live B2 rejects comma
38
+ * and other RFC punctuation when left raw in these values, so only RFC 3986
39
+ * unreserved characters are passed through.
40
+ *
41
+ * @param value - The raw (unencoded) file-info value.
42
+ *
43
+ * @returns The percent-encoded value suitable for `X-Bz-Info-*` header values.
44
+ */
45
+ function encodeFileInfoValue(value) {
46
+ return encodeWithSafeChars(value, FILE_INFO_VALUE_SAFE_CHARS);
29
47
  }
30
48
  /**
31
49
  * Decodes a B2 percent-encoded file name back to a plain string.
@@ -43,8 +61,9 @@ function decodeFileName(encoded) {
43
61
  /**
44
62
  * Converts a file-info map into `X-Bz-Info-*` HTTP headers.
45
63
  *
46
- * Both keys and values are percent-encoded with {@link encodeFileName}
47
- * to satisfy B2 header requirements.
64
+ * Keys use B2 file-name encoding. Values use stricter B2 file-info value
65
+ * encoding so punctuation such as commas is percent-encoded before B2 decodes
66
+ * and validates stored metadata.
48
67
  *
49
68
  * @param fileInfo - Key/value pairs to attach as custom file info, or `undefined`.
50
69
  *
@@ -53,7 +72,7 @@ function decodeFileName(encoded) {
53
72
  function buildFileInfoHeaders(fileInfo) {
54
73
  if (!fileInfo) return {};
55
74
  const headers = {};
56
- for (const [key, value] of Object.entries(fileInfo)) headers[`X-Bz-Info-${encodeFileName(key)}`] = encodeFileName(value);
75
+ for (const [key, value] of Object.entries(fileInfo)) headers[`X-Bz-Info-${encodeFileName(key)}`] = encodeFileInfoValue(value);
57
76
  return headers;
58
77
  }
59
78
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"encoding.js","names":[],"sources":["../../src/raw/encoding.ts"],"sourcesContent":["import { utf8Encoder } from '../util/text-codec.ts'\n\n/**\n * Characters that B2 treats as safe (not percent-encoded) in file names.\n *\n * Per the B2 docs, everything except `a-z A-Z 0-9 - . _ ~ / ! $ & ' ( ) * + , ; = : @`\n * must be percent-encoded using UTF-8 byte values.\n */\nconst SAFE_CHARS = new Set(\n \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$&'()*+,;=:@/\".split(''),\n)\n\n/**\n * Percent-encodes a file name using the B2-specific encoding rules.\n *\n * Unlike standard `encodeURIComponent`, B2 keeps `/` and several other\n * characters unencoded while encoding all other non-ASCII and special\n * characters as uppercase percent-encoded UTF-8 bytes.\n *\n * @param name - The raw (unencoded) file name.\n *\n * @returns The percent-encoded file name suitable for `X-Bz-File-Name` headers.\n */\nexport function encodeFileName(name: string): string {\n const encoded: string[] = []\n for (const char of name) {\n if (SAFE_CHARS.has(char)) {\n encoded.push(char)\n } else {\n const bytes = utf8Encoder.encode(char)\n for (const byte of bytes) {\n encoded.push(`%${byte.toString(16).toUpperCase().padStart(2, '0')}`)\n }\n }\n }\n return encoded.join('')\n}\n\n/**\n * Decodes a B2 percent-encoded file name back to a plain string.\n *\n * B2 percent-encoding is compatible with standard `decodeURIComponent`,\n * so this is a thin wrapper.\n *\n * @param encoded - The percent-encoded file name from B2.\n *\n * @returns The decoded file name.\n */\nexport function decodeFileName(encoded: string): string {\n return decodeURIComponent(encoded)\n}\n\n/**\n * Converts a file-info map into `X-Bz-Info-*` HTTP headers.\n *\n * Both keys and values are percent-encoded with {@link encodeFileName}\n * to satisfy B2 header requirements.\n *\n * @param fileInfo - Key/value pairs to attach as custom file info, or `undefined`.\n *\n * @returns A record of header name/value pairs (empty if `fileInfo` is `undefined`).\n */\nexport function buildFileInfoHeaders(\n fileInfo: Record<string, string> | undefined,\n): Record<string, string> {\n if (!fileInfo) return {}\n const headers: Record<string, string> = {}\n for (const [key, value] of Object.entries(fileInfo)) {\n headers[`X-Bz-Info-${encodeFileName(key)}`] = encodeFileName(value)\n }\n return headers\n}\n\n/**\n * Extracts custom file-info key/value pairs from B2 response headers.\n *\n * Scans for headers prefixed with `x-bz-info-` and decodes both the\n * key suffix and value using {@link decodeFileName}.\n *\n * @param headers - The HTTP response headers from a B2 download or file-info call.\n *\n * @returns A record of decoded file-info key/value pairs.\n */\nexport function parseFileInfoHeaders(headers: Headers): Record<string, string> {\n const info: Record<string, string> = {}\n headers.forEach((value, key) => {\n const lower = key.toLowerCase()\n if (lower.startsWith('x-bz-info-')) {\n const infoKey = decodeFileName(lower.slice('x-bz-info-'.length))\n info[infoKey] = decodeFileName(value)\n }\n })\n return info\n}\n"],"mappings":";;;;;;;;AAQA,IAAM,aAAa,IAAI,IACrB,mFAAmF,MAAM,EAAE,CAC7F;;;;;;;;;;;;AAaA,SAAgB,eAAe,MAAsB;CACnD,MAAM,UAAoB,CAAC;CAC3B,KAAK,MAAM,QAAQ,MACjB,IAAI,WAAW,IAAI,IAAI,GACrB,QAAQ,KAAK,IAAI;MACZ;EACL,MAAM,QAAQ,YAAY,OAAO,IAAI;EACrC,KAAK,MAAM,QAAQ,OACjB,QAAQ,KAAK,IAAI,KAAK,SAAS,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG;CAEvE;CAEF,OAAO,QAAQ,KAAK,EAAE;AACxB;;;;;;;;;;;AAYA,SAAgB,eAAe,SAAyB;CACtD,OAAO,mBAAmB,OAAO;AACnC;;;;;;;;;;;AAYA,SAAgB,qBACd,UACwB;CACxB,IAAI,CAAC,UAAU,OAAO,CAAC;CACvB,MAAM,UAAkC,CAAC;CACzC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,GAChD,QAAQ,aAAa,eAAe,GAAG,OAAO,eAAe,KAAK;CAEpE,OAAO;AACT;;;;;;;;;;;AAYA,SAAgB,qBAAqB,SAA0C;CAC7E,MAAM,OAA+B,CAAC;CACtC,QAAQ,SAAS,OAAO,QAAQ;EAC9B,MAAM,QAAQ,IAAI,YAAY;EAC9B,IAAI,MAAM,WAAW,YAAY,GAAG;GAClC,MAAM,UAAU,eAAe,MAAM,MAAM,EAAmB,CAAC;GAC/D,KAAK,WAAW,eAAe,KAAK;EACtC;CACF,CAAC;CACD,OAAO;AACT"}
1
+ {"version":3,"file":"encoding.js","names":[],"sources":["../../src/raw/encoding.ts"],"sourcesContent":["import { utf8Encoder } from '../util/text-codec.ts'\n\n/**\n * Characters that B2 treats as safe (not percent-encoded) in file names.\n *\n * Per the B2 docs, everything except `a-z A-Z 0-9 - . _ ~ / ! $ & ' ( ) * + , ; = : @`\n * must be percent-encoded using UTF-8 byte values.\n */\nconst SAFE_CHARS = new Set(\n \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$&'()*+,;=:@/\".split(''),\n)\n\nconst FILE_INFO_VALUE_SAFE_CHARS = new Set(\n 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~'.split(''),\n)\n\nfunction encodeWithSafeChars(value: string, safeChars: ReadonlySet<string>): string {\n const encoded: string[] = []\n for (const char of value) {\n if (safeChars.has(char)) {\n encoded.push(char)\n } else {\n const bytes = utf8Encoder.encode(char)\n for (const byte of bytes) {\n encoded.push(`%${byte.toString(16).toUpperCase().padStart(2, '0')}`)\n }\n }\n }\n return encoded.join('')\n}\n\n/**\n * Percent-encodes a file name using the B2-specific encoding rules.\n *\n * Unlike standard `encodeURIComponent`, B2 keeps `/` and several other\n * characters unencoded while encoding all other non-ASCII and special\n * characters as uppercase percent-encoded UTF-8 bytes.\n *\n * @param name - The raw (unencoded) file name.\n *\n * @returns The percent-encoded file name suitable for `X-Bz-File-Name` headers.\n */\nexport function encodeFileName(name: string): string {\n return encodeWithSafeChars(name, SAFE_CHARS)\n}\n\n/**\n * Percent-encodes a file-info value using the stricter B2 metadata value rules.\n *\n * File-info values must be decoded by B2 before storage. Live B2 rejects comma\n * and other RFC punctuation when left raw in these values, so only RFC 3986\n * unreserved characters are passed through.\n *\n * @param value - The raw (unencoded) file-info value.\n *\n * @returns The percent-encoded value suitable for `X-Bz-Info-*` header values.\n */\nfunction encodeFileInfoValue(value: string): string {\n return encodeWithSafeChars(value, FILE_INFO_VALUE_SAFE_CHARS)\n}\n\n/**\n * Decodes a B2 percent-encoded file name back to a plain string.\n *\n * B2 percent-encoding is compatible with standard `decodeURIComponent`,\n * so this is a thin wrapper.\n *\n * @param encoded - The percent-encoded file name from B2.\n *\n * @returns The decoded file name.\n */\nexport function decodeFileName(encoded: string): string {\n return decodeURIComponent(encoded)\n}\n\n/**\n * Converts a file-info map into `X-Bz-Info-*` HTTP headers.\n *\n * Keys use B2 file-name encoding. Values use stricter B2 file-info value\n * encoding so punctuation such as commas is percent-encoded before B2 decodes\n * and validates stored metadata.\n *\n * @param fileInfo - Key/value pairs to attach as custom file info, or `undefined`.\n *\n * @returns A record of header name/value pairs (empty if `fileInfo` is `undefined`).\n */\nexport function buildFileInfoHeaders(\n fileInfo: Record<string, string> | undefined,\n): Record<string, string> {\n if (!fileInfo) return {}\n const headers: Record<string, string> = {}\n for (const [key, value] of Object.entries(fileInfo)) {\n headers[`X-Bz-Info-${encodeFileName(key)}`] = encodeFileInfoValue(value)\n }\n return headers\n}\n\n/**\n * Extracts custom file-info key/value pairs from B2 response headers.\n *\n * Scans for headers prefixed with `x-bz-info-` and decodes both the\n * key suffix and value using {@link decodeFileName}.\n *\n * @param headers - The HTTP response headers from a B2 download or file-info call.\n *\n * @returns A record of decoded file-info key/value pairs.\n */\nexport function parseFileInfoHeaders(headers: Headers): Record<string, string> {\n const info: Record<string, string> = {}\n headers.forEach((value, key) => {\n const lower = key.toLowerCase()\n if (lower.startsWith('x-bz-info-')) {\n const infoKey = decodeFileName(lower.slice('x-bz-info-'.length))\n info[infoKey] = decodeFileName(value)\n }\n })\n return info\n}\n"],"mappings":";;;;;;;;AAQA,IAAM,aAAa,IAAI,IACrB,mFAAmF,MAAM,EAAE,CAC7F;AAEA,IAAM,6BAA6B,IAAI,IACrC,qEAAqE,MAAM,EAAE,CAC/E;AAEA,SAAS,oBAAoB,OAAe,WAAwC;CAClF,MAAM,UAAoB,CAAC;CAC3B,KAAK,MAAM,QAAQ,OACjB,IAAI,UAAU,IAAI,IAAI,GACpB,QAAQ,KAAK,IAAI;MACZ;EACL,MAAM,QAAQ,YAAY,OAAO,IAAI;EACrC,KAAK,MAAM,QAAQ,OACjB,QAAQ,KAAK,IAAI,KAAK,SAAS,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG;CAEvE;CAEF,OAAO,QAAQ,KAAK,EAAE;AACxB;;;;;;;;;;;;AAaA,SAAgB,eAAe,MAAsB;CACnD,OAAO,oBAAoB,MAAM,UAAU;AAC7C;;;;;;;;;;;;AAaA,SAAS,oBAAoB,OAAuB;CAClD,OAAO,oBAAoB,OAAO,0BAA0B;AAC9D;;;;;;;;;;;AAYA,SAAgB,eAAe,SAAyB;CACtD,OAAO,mBAAmB,OAAO;AACnC;;;;;;;;;;;;AAaA,SAAgB,qBACd,UACwB;CACxB,IAAI,CAAC,UAAU,OAAO,CAAC;CACvB,MAAM,UAAkC,CAAC;CACzC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,GAChD,QAAQ,aAAa,eAAe,GAAG,OAAO,oBAAoB,KAAK;CAEzE,OAAO;AACT;;;;;;;;;;;AAYA,SAAgB,qBAAqB,SAA0C;CAC7E,MAAM,OAA+B,CAAC;CACtC,QAAQ,SAAS,OAAO,QAAQ;EAC9B,MAAM,QAAQ,IAAI,YAAY;EAC9B,IAAI,MAAM,WAAW,YAAY,GAAG;GAClC,MAAM,UAAU,eAAe,MAAM,MAAM,EAAmB,CAAC;GAC/D,KAAK,WAAW,eAAe,KAAK;EACtC;CACF,CAAC;CACD,OAAO;AACT"}
@@ -3,6 +3,8 @@ const require_errors_index = require("../errors/index.cjs");
3
3
  const require_encoding = require("./encoding.cjs");
4
4
  const require_encryption = require("../types/encryption.cjs");
5
5
  const require_normalize = require("../util/normalize.cjs");
6
+ const require_bucket = require("../types/bucket.cjs");
7
+ const require_bucket_validation = require("../bucket-validation.cjs");
6
8
  const require_realms = require("../auth/realms.cjs");
7
9
  const require_url = require("./url.cjs");
8
10
  //#region src/raw/index.ts
@@ -13,14 +15,13 @@ const require_url = require("./url.cjs");
13
15
  * with fully typed request and response objects. No retry logic, no URL pooling,
14
16
  * no automatic reauthorization. Use this when you need precise control over
15
17
  * individual API calls; for most use cases prefer the high-level `B2Client`.
18
+ * SDK-built B2 native storage API URLs use `/b2api/v4`. JSON endpoints use
19
+ * POST request bodies, including read/list endpoints whose API docs also show
20
+ * GET query examples but document POST JSON compatibility.
16
21
  *
17
22
  * @packageDocumentation
18
23
  */
19
- var B2_NATIVE_API_V3 = {
20
- prefix: "b2api",
21
- version: "v3"
22
- };
23
- var B2_NATIVE_API_V4 = {
24
+ var B2_NATIVE_API = {
24
25
  prefix: "b2api",
25
26
  version: "v4"
26
27
  };
@@ -43,6 +44,21 @@ function assertCustomUploadTimestamp(value) {
43
44
  if (typeof value === "number" && Number.isSafeInteger(value) && value >= 0) return;
44
45
  throw new TypeError("customUploadTimestamp must be a non-negative safe integer");
45
46
  }
47
+ function assertSafeHttpHeaderValue(name, value) {
48
+ if (hasHttpHeaderControlByte(value)) throw new TypeError(`${name} must not contain HTTP control characters`);
49
+ }
50
+ function hasHttpHeaderControlByte(value) {
51
+ for (let i = 0; i < value.length; i += 1) {
52
+ const code = value.charCodeAt(i);
53
+ if (code <= 31 || code === 127) return true;
54
+ }
55
+ return false;
56
+ }
57
+ function setB2ContentFileInfoHeader(headers, key, optionName, value) {
58
+ if (!value) return;
59
+ assertSafeHttpHeaderValue(optionName, value);
60
+ Object.assign(headers, require_encoding.buildFileInfoHeaders({ [key]: value }));
61
+ }
46
62
  function assertRawCustomUploadTimestamp(value) {
47
63
  if (value === void 0 || value === null) return;
48
64
  if (typeof value === "string" && /^\d+$/.test(value)) {
@@ -139,18 +155,21 @@ var RawClient = class {
139
155
  * @param applicationKeyId - The application key ID for authentication.
140
156
  * @param applicationKey - The application key secret.
141
157
  * @param realmUrl - The B2 realm URL to authenticate against.
158
+ * @param options - Optional request controls.
142
159
  *
143
160
  * @returns The authorization response with API URLs and credentials.
144
161
  */
145
- async authorizeAccount(applicationKeyId, applicationKey, realmUrl = "https://api.backblazeb2.com") {
162
+ async authorizeAccount(applicationKeyId, applicationKey, realmUrl = "https://api.backblazeb2.com", options) {
146
163
  require_realms.assertSecureRealmUrl(realmUrl);
147
164
  return normalizeAuthorizeAccountResponse(await (await this.transport.send({
148
165
  url: require_url.b2Url(realmUrl, {
149
- ...B2_NATIVE_API_V4,
166
+ ...B2_NATIVE_API,
150
167
  endpoint: "b2_authorize_account"
151
168
  }),
152
169
  method: "GET",
153
- headers: { Authorization: `Basic ${btoa(`${applicationKeyId}:${applicationKey}`)}` }
170
+ headers: { Authorization: `Basic ${btoa(`${applicationKeyId}:${applicationKey}`)}` },
171
+ ...options?.signal !== void 0 ? { signal: options.signal } : {},
172
+ ...options?.retry !== void 0 ? { retry: options.retry } : {}
154
173
  })).json());
155
174
  }
156
175
  /**
@@ -162,6 +181,7 @@ var RawClient = class {
162
181
  * @returns The created bucket metadata.
163
182
  */
164
183
  async createBucket(apiUrl, authToken, request) {
184
+ require_bucket_validation.assertValidBucketConfiguration(request);
165
185
  return this.postJson(apiUrl, authToken, "b2_create_bucket", request);
166
186
  }
167
187
  /**
@@ -195,6 +215,7 @@ var RawClient = class {
195
215
  * @returns The updated bucket metadata.
196
216
  */
197
217
  async updateBucket(apiUrl, authToken, request) {
218
+ require_bucket_validation.assertValidBucketConfiguration(request);
198
219
  return this.postJson(apiUrl, authToken, "b2_update_bucket", request);
199
220
  }
200
221
  /**
@@ -222,6 +243,9 @@ var RawClient = class {
222
243
  */
223
244
  async uploadFile(uploadUrl, headers, body, optionsOrSignal, retry) {
224
245
  const options = normalizeRawRequestOptions(optionsOrSignal, retry);
246
+ assertSafeHttpHeaderValue("authorization", headers.authorization);
247
+ assertSafeHttpHeaderValue("contentType", headers.contentType);
248
+ assertSafeHttpHeaderValue("contentSha1", headers.contentSha1);
225
249
  const reqHeaders = {
226
250
  Authorization: headers.authorization,
227
251
  "X-Bz-File-Name": require_encoding.encodeFileName(headers.fileName),
@@ -235,11 +259,11 @@ var RawClient = class {
235
259
  assertCustomUploadTimestamp(headers.customUploadTimestamp);
236
260
  reqHeaders["X-Bz-Custom-Upload-Timestamp"] = String(headers.customUploadTimestamp);
237
261
  }
238
- if (headers.contentDisposition) reqHeaders["X-Bz-Info-b2-content-disposition"] = headers.contentDisposition;
239
- if (headers.contentLanguage) reqHeaders["X-Bz-Info-b2-content-language"] = headers.contentLanguage;
240
- if (headers.expires) reqHeaders["X-Bz-Info-b2-expires"] = headers.expires;
241
- if (headers.cacheControl) reqHeaders["X-Bz-Info-b2-cache-control"] = headers.cacheControl;
242
- if (headers.contentEncoding) reqHeaders["X-Bz-Info-b2-content-encoding"] = headers.contentEncoding;
262
+ setB2ContentFileInfoHeader(reqHeaders, "b2-content-disposition", "contentDisposition", headers.contentDisposition);
263
+ setB2ContentFileInfoHeader(reqHeaders, "b2-content-language", "contentLanguage", headers.contentLanguage);
264
+ setB2ContentFileInfoHeader(reqHeaders, "b2-expires", "expires", headers.expires);
265
+ setB2ContentFileInfoHeader(reqHeaders, "b2-cache-control", "cacheControl", headers.cacheControl);
266
+ setB2ContentFileInfoHeader(reqHeaders, "b2-content-encoding", "contentEncoding", headers.contentEncoding);
243
267
  applyEncryptionHeaders(reqHeaders, headers.serverSideEncryption);
244
268
  applyRetentionHeaders(reqHeaders, headers.fileRetention);
245
269
  applyLegalHoldHeader(reqHeaders, headers.legalHold);
@@ -257,27 +281,9 @@ var RawClient = class {
257
281
  throw uploadResponseBodyError(err, options?.signal);
258
282
  }
259
283
  }
260
- /**
261
- * Calls {@link https://www.backblaze.com/apidocs/b2-list-file-names | b2_list_file_names}.
262
- * @param apiUrl - The B2 API base URL.
263
- * @param authToken - The authorization token.
264
- * @param request - The API request parameters.
265
- * @param options - Optional request controls such as an abort signal.
266
- *
267
- * @returns The list of file names and optional continuation token.
268
- */
269
284
  async listFileNames(apiUrl, authToken, request, options) {
270
285
  return require_normalize.normalizeFileVersionListSha1(await this.postJson(apiUrl, authToken, "b2_list_file_names", request, options));
271
286
  }
272
- /**
273
- * Calls {@link https://www.backblaze.com/apidocs/b2-list-file-versions | b2_list_file_versions}.
274
- * @param apiUrl - The B2 API base URL.
275
- * @param authToken - The authorization token.
276
- * @param request - The API request parameters.
277
- * @param options - Optional request controls such as an abort signal.
278
- *
279
- * @returns The list of file versions and optional continuation token.
280
- */
281
287
  async listFileVersions(apiUrl, authToken, request, options) {
282
288
  return require_normalize.normalizeFileVersionListSha1(await this.postJson(apiUrl, authToken, "b2_list_file_versions", request, options));
283
289
  }
@@ -378,6 +384,8 @@ var RawClient = class {
378
384
  */
379
385
  async uploadPart(uploadUrl, headers, body, optionsOrSignal, retry) {
380
386
  const options = normalizeRawRequestOptions(optionsOrSignal, retry);
387
+ assertSafeHttpHeaderValue("authorization", headers.authorization);
388
+ assertSafeHttpHeaderValue("contentSha1", headers.contentSha1);
381
389
  const reqHeaders = {
382
390
  Authorization: headers.authorization,
383
391
  "X-Bz-Part-Number": String(headers.partNumber),
@@ -411,7 +419,7 @@ var RawClient = class {
411
419
  async finishLargeFile(apiUrl, authToken, request, options) {
412
420
  const response = await this.transport.send({
413
421
  url: require_url.b2Url(apiUrl, {
414
- ...B2_NATIVE_API_V3,
422
+ ...B2_NATIVE_API,
415
423
  endpoint: "b2_finish_large_file"
416
424
  }),
417
425
  method: "POST",
@@ -482,7 +490,7 @@ var RawClient = class {
482
490
  async downloadFileById(downloadUrl, authToken, fileId, options) {
483
491
  const headers = buildDownloadRequestHeaders(authToken, options);
484
492
  const url = appendDownloadOverrides(`${require_url.b2Url(downloadUrl, {
485
- ...B2_NATIVE_API_V3,
493
+ ...B2_NATIVE_API,
486
494
  endpoint: "b2_download_file_by_id"
487
495
  })}?fileId=${encodeURIComponent(fileId)}`, options);
488
496
  const response = await this.transport.send({
@@ -542,7 +550,7 @@ var RawClient = class {
542
550
  * @returns The newly created application key with secret.
543
551
  */
544
552
  async createKey(apiUrl, authToken, request) {
545
- return normalizeKeyResponse(await this.postJson(apiUrl, authToken, "b2_create_key", normalizeCreateKeyRequest(request), void 0, B2_NATIVE_API_V4));
553
+ return normalizeKeyResponse(await this.postJson(apiUrl, authToken, "b2_create_key", normalizeCreateKeyRequest(request)));
546
554
  }
547
555
  /**
548
556
  * Calls {@link https://www.backblaze.com/apidocs/b2-list-keys | b2_list_keys}.
@@ -553,7 +561,7 @@ var RawClient = class {
553
561
  * @returns The list of application keys and optional continuation token.
554
562
  */
555
563
  async listKeys(apiUrl, authToken, request) {
556
- const response = await this.postJson(apiUrl, authToken, "b2_list_keys", request, void 0, B2_NATIVE_API_V4);
564
+ const response = await this.postJson(apiUrl, authToken, "b2_list_keys", request);
557
565
  return {
558
566
  ...response,
559
567
  keys: response.keys.map((key) => normalizeKeyResponse(key))
@@ -568,7 +576,7 @@ var RawClient = class {
568
576
  * @returns The deleted application key metadata.
569
577
  */
570
578
  async deleteKey(apiUrl, authToken, request) {
571
- return normalizeKeyResponse(await this.postJson(apiUrl, authToken, "b2_delete_key", request, void 0, B2_NATIVE_API_V4));
579
+ return normalizeKeyResponse(await this.postJson(apiUrl, authToken, "b2_delete_key", request));
572
580
  }
573
581
  /**
574
582
  * Calls {@link https://www.backblaze.com/apidocs/b2-update-file-retention | b2_update_file_retention}.
@@ -621,14 +629,13 @@ var RawClient = class {
621
629
  * @param endpoint - The B2 API endpoint name.
622
630
  * @param body - The JSON request body.
623
631
  * @param options - Optional abort and per-request retry settings.
624
- * @param urlOptions - B2 endpoint path prefix and version settings.
625
632
  *
626
633
  * @returns The parsed JSON response.
627
634
  */
628
- async postJson(apiUrl, authToken, endpoint, body, options, urlOptions = B2_NATIVE_API_V3) {
635
+ async postJson(apiUrl, authToken, endpoint, body, options) {
629
636
  return (await this.transport.send({
630
637
  url: require_url.b2Url(apiUrl, {
631
- ...urlOptions,
638
+ ...B2_NATIVE_API,
632
639
  endpoint
633
640
  }),
634
641
  method: "POST",
@@ -744,7 +751,25 @@ function applyLegalHoldHeader(headers, legalHold) {
744
751
  headers["X-Bz-File-Legal-Hold"] = legalHold;
745
752
  }
746
753
  //#endregion
754
+ exports.BUCKET_INFO_KEY_MAX_BYTES = require_bucket.BUCKET_INFO_KEY_MAX_BYTES;
755
+ exports.BUCKET_INFO_KEY_MIN_BYTES = require_bucket.BUCKET_INFO_KEY_MIN_BYTES;
756
+ exports.BUCKET_INFO_KEY_PATTERN = require_bucket.BUCKET_INFO_KEY_PATTERN;
757
+ exports.BUCKET_INFO_RESERVED_PREFIX = require_bucket.BUCKET_INFO_RESERVED_PREFIX;
758
+ exports.BUCKET_INFO_VALUES_MAX_BYTES = require_bucket.BUCKET_INFO_VALUES_MAX_BYTES;
759
+ exports.BucketKeyOption = require_bucket.BucketKeyOption;
760
+ exports.CORS_ALLOWED_OPERATIONS = require_bucket.CORS_ALLOWED_OPERATIONS;
761
+ exports.CORS_MAX_AGE_SECONDS_MAX = require_bucket.CORS_MAX_AGE_SECONDS_MAX;
762
+ exports.CORS_RULES_MAX_COUNT = require_bucket.CORS_RULES_MAX_COUNT;
763
+ exports.CORS_RULE_MAX_BYTES = require_bucket.CORS_RULE_MAX_BYTES;
764
+ exports.CORS_RULE_NAME_MAX_LENGTH = require_bucket.CORS_RULE_NAME_MAX_LENGTH;
765
+ exports.CORS_RULE_NAME_MIN_LENGTH = require_bucket.CORS_RULE_NAME_MIN_LENGTH;
766
+ exports.CORS_RULE_NAME_PATTERN = require_bucket.CORS_RULE_NAME_PATTERN;
767
+ exports.CORS_RULE_NAME_RESERVED_PREFIX = require_bucket.CORS_RULE_NAME_RESERVED_PREFIX;
768
+ exports.CorsOperation = require_bucket.CorsOperation;
747
769
  exports.RawClient = RawClient;
770
+ exports.assertValidBucketConfiguration = require_bucket_validation.assertValidBucketConfiguration;
771
+ exports.assertValidBucketInfo = require_bucket_validation.assertValidBucketInfo;
772
+ exports.assertValidCorsRules = require_bucket_validation.assertValidCorsRules;
748
773
  exports.buildFileInfoHeaders = require_encoding.buildFileInfoHeaders;
749
774
  exports.decodeFileName = require_encoding.decodeFileName;
750
775
  exports.encodeFileName = require_encoding.encodeFileName;