@backblaze-labs/b2-sdk 0.2.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 (590) hide show
  1. package/CHANGELOG.md +86 -1
  2. package/README.md +38 -7
  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/file.cjs.map +1 -1
  6. package/dist/auth/reauth-coalescer.cjs +65 -0
  7. package/dist/auth/reauth-coalescer.cjs.map +1 -0
  8. package/dist/auth/reauth-coalescer.d.cts +34 -0
  9. package/dist/auth/reauth-coalescer.d.cts.map +1 -0
  10. package/dist/auth/reauth-coalescer.d.ts +34 -0
  11. package/dist/auth/reauth-coalescer.d.ts.map +1 -0
  12. package/dist/auth/reauth-coalescer.js +65 -0
  13. package/dist/auth/reauth-coalescer.js.map +1 -0
  14. package/dist/backup/client.cjs +206 -0
  15. package/dist/backup/client.cjs.map +1 -0
  16. package/dist/backup/client.d.cts +238 -0
  17. package/dist/backup/client.d.cts.map +1 -0
  18. package/dist/backup/client.d.ts +238 -0
  19. package/dist/backup/client.d.ts.map +1 -0
  20. package/dist/backup/client.js +206 -0
  21. package/dist/backup/client.js.map +1 -0
  22. package/dist/backup/index.cjs +15 -0
  23. package/dist/backup/index.d.cts +22 -0
  24. package/dist/backup/index.d.cts.map +1 -0
  25. package/dist/backup/index.d.ts +22 -0
  26. package/dist/backup/index.d.ts.map +1 -0
  27. package/dist/backup/index.js +7 -0
  28. package/dist/backup/raw.cjs +168 -0
  29. package/dist/backup/raw.cjs.map +1 -0
  30. package/dist/backup/raw.d.cts +122 -0
  31. package/dist/backup/raw.d.cts.map +1 -0
  32. package/dist/backup/raw.d.ts +122 -0
  33. package/dist/backup/raw.d.ts.map +1 -0
  34. package/dist/backup/raw.js +168 -0
  35. package/dist/backup/raw.js.map +1 -0
  36. package/dist/bucket-validation.cjs +111 -0
  37. package/dist/bucket-validation.cjs.map +1 -0
  38. package/dist/bucket-validation.d.cts +27 -0
  39. package/dist/bucket-validation.d.cts.map +1 -0
  40. package/dist/bucket-validation.d.ts +27 -0
  41. package/dist/bucket-validation.d.ts.map +1 -0
  42. package/dist/bucket-validation.js +109 -0
  43. package/dist/bucket-validation.js.map +1 -0
  44. package/dist/bucket.cjs +125 -74
  45. package/dist/bucket.cjs.map +1 -1
  46. package/dist/bucket.d.cts +156 -61
  47. package/dist/bucket.d.cts.map +1 -1
  48. package/dist/bucket.d.ts +156 -61
  49. package/dist/bucket.d.ts.map +1 -1
  50. package/dist/bucket.js +125 -74
  51. package/dist/bucket.js.map +1 -1
  52. package/dist/client.cjs +29 -8
  53. package/dist/client.cjs.map +1 -1
  54. package/dist/client.d.cts +30 -9
  55. package/dist/client.d.cts.map +1 -1
  56. package/dist/client.d.ts +30 -9
  57. package/dist/client.d.ts.map +1 -1
  58. package/dist/client.js +29 -8
  59. package/dist/client.js.map +1 -1
  60. package/dist/copy/large.cjs +5 -3
  61. package/dist/copy/large.cjs.map +1 -1
  62. package/dist/copy/large.d.cts.map +1 -1
  63. package/dist/copy/large.d.ts.map +1 -1
  64. package/dist/copy/large.js +5 -3
  65. package/dist/copy/large.js.map +1 -1
  66. package/dist/download/checksum.cjs +6 -2
  67. package/dist/download/checksum.cjs.map +1 -1
  68. package/dist/download/checksum.js +6 -2
  69. package/dist/download/checksum.js.map +1 -1
  70. package/dist/download/parallel.cjs +52 -15
  71. package/dist/download/parallel.cjs.map +1 -1
  72. package/dist/download/parallel.d.cts +8 -1
  73. package/dist/download/parallel.d.cts.map +1 -1
  74. package/dist/download/parallel.d.ts +8 -1
  75. package/dist/download/parallel.d.ts.map +1 -1
  76. package/dist/download/parallel.js +52 -15
  77. package/dist/download/parallel.js.map +1 -1
  78. package/dist/download/single.cjs +179 -19
  79. package/dist/download/single.cjs.map +1 -1
  80. package/dist/download/single.d.cts +10 -4
  81. package/dist/download/single.d.cts.map +1 -1
  82. package/dist/download/single.d.ts +10 -4
  83. package/dist/download/single.d.ts.map +1 -1
  84. package/dist/download/single.js +179 -19
  85. package/dist/download/single.js.map +1 -1
  86. package/dist/errors/index.cjs +196 -3
  87. package/dist/errors/index.cjs.map +1 -1
  88. package/dist/errors/index.d.cts +134 -0
  89. package/dist/errors/index.d.cts.map +1 -1
  90. package/dist/errors/index.d.ts +134 -0
  91. package/dist/errors/index.d.ts.map +1 -1
  92. package/dist/errors/index.js +183 -4
  93. package/dist/errors/index.js.map +1 -1
  94. package/dist/http/non-idempotent-mutations.cjs +38 -0
  95. package/dist/http/non-idempotent-mutations.cjs.map +1 -0
  96. package/dist/http/non-idempotent-mutations.d.cts +25 -0
  97. package/dist/http/non-idempotent-mutations.d.cts.map +1 -0
  98. package/dist/http/non-idempotent-mutations.d.ts +25 -0
  99. package/dist/http/non-idempotent-mutations.d.ts.map +1 -0
  100. package/dist/http/non-idempotent-mutations.js +35 -0
  101. package/dist/http/non-idempotent-mutations.js.map +1 -0
  102. package/dist/http/retry.cjs +1 -1
  103. package/dist/http/retry.cjs.map +1 -1
  104. package/dist/http/retry.js +1 -1
  105. package/dist/http/retry.js.map +1 -1
  106. package/dist/http/transport.cjs +62 -23
  107. package/dist/http/transport.cjs.map +1 -1
  108. package/dist/http/transport.d.cts +30 -3
  109. package/dist/http/transport.d.cts.map +1 -1
  110. package/dist/http/transport.d.ts +30 -3
  111. package/dist/http/transport.d.ts.map +1 -1
  112. package/dist/http/transport.js +60 -22
  113. package/dist/http/transport.js.map +1 -1
  114. package/dist/http/user-agent.cjs +12 -1
  115. package/dist/http/user-agent.cjs.map +1 -1
  116. package/dist/http/user-agent.d.cts +8 -0
  117. package/dist/http/user-agent.d.cts.map +1 -1
  118. package/dist/http/user-agent.d.ts +8 -0
  119. package/dist/http/user-agent.d.ts.map +1 -1
  120. package/dist/http/user-agent.js +13 -3
  121. package/dist/http/user-agent.js.map +1 -1
  122. package/dist/index.cjs +50 -2
  123. package/dist/index.d.cts +15 -12
  124. package/dist/index.d.cts.map +1 -1
  125. package/dist/index.d.ts +15 -12
  126. package/dist/index.d.ts.map +1 -1
  127. package/dist/index.js +13 -10
  128. package/dist/notifications/index.cjs +3 -0
  129. package/dist/notifications/index.d.cts +2 -0
  130. package/dist/notifications/index.d.cts.map +1 -1
  131. package/dist/notifications/index.d.ts +2 -0
  132. package/dist/notifications/index.d.ts.map +1 -1
  133. package/dist/notifications/index.js +2 -1
  134. package/dist/object.cjs +13 -2
  135. package/dist/object.cjs.map +1 -1
  136. package/dist/object.d.cts +11 -3
  137. package/dist/object.d.cts.map +1 -1
  138. package/dist/object.d.ts +11 -3
  139. package/dist/object.d.ts.map +1 -1
  140. package/dist/object.js +13 -2
  141. package/dist/object.js.map +1 -1
  142. package/dist/partner/account-info.d.cts +43 -0
  143. package/dist/partner/account-info.d.cts.map +1 -0
  144. package/dist/partner/account-info.d.ts +43 -0
  145. package/dist/partner/account-info.d.ts.map +1 -0
  146. package/dist/partner/auth-clone.cjs +64 -0
  147. package/dist/partner/auth-clone.cjs.map +1 -0
  148. package/dist/partner/auth-clone.d.cts +27 -0
  149. package/dist/partner/auth-clone.d.cts.map +1 -0
  150. package/dist/partner/auth-clone.d.ts +27 -0
  151. package/dist/partner/auth-clone.d.ts.map +1 -0
  152. package/dist/partner/auth-clone.js +63 -0
  153. package/dist/partner/auth-clone.js.map +1 -0
  154. package/dist/partner/auth-core.cjs +156 -0
  155. package/dist/partner/auth-core.cjs.map +1 -0
  156. package/dist/partner/auth-core.d.cts +111 -0
  157. package/dist/partner/auth-core.d.cts.map +1 -0
  158. package/dist/partner/auth-core.d.ts +111 -0
  159. package/dist/partner/auth-core.d.ts.map +1 -0
  160. package/dist/partner/auth-core.js +156 -0
  161. package/dist/partner/auth-core.js.map +1 -0
  162. package/dist/partner/auth-shape.cjs +36 -0
  163. package/dist/partner/auth-shape.cjs.map +1 -0
  164. package/dist/partner/auth-shape.d.cts +12 -0
  165. package/dist/partner/auth-shape.d.cts.map +1 -0
  166. package/dist/partner/auth-shape.d.ts +12 -0
  167. package/dist/partner/auth-shape.d.ts.map +1 -0
  168. package/dist/partner/auth-shape.js +36 -0
  169. package/dist/partner/auth-shape.js.map +1 -0
  170. package/dist/partner/client.cjs +270 -0
  171. package/dist/partner/client.cjs.map +1 -0
  172. package/dist/partner/client.d.cts +357 -0
  173. package/dist/partner/client.d.cts.map +1 -0
  174. package/dist/partner/client.d.ts +357 -0
  175. package/dist/partner/client.d.ts.map +1 -0
  176. package/dist/partner/client.js +270 -0
  177. package/dist/partner/client.js.map +1 -0
  178. package/dist/partner/endpoint-url.cjs +109 -0
  179. package/dist/partner/endpoint-url.cjs.map +1 -0
  180. package/dist/partner/endpoint-url.d.cts +74 -0
  181. package/dist/partner/endpoint-url.d.cts.map +1 -0
  182. package/dist/partner/endpoint-url.d.ts +74 -0
  183. package/dist/partner/endpoint-url.d.ts.map +1 -0
  184. package/dist/partner/endpoint-url.js +106 -0
  185. package/dist/partner/endpoint-url.js.map +1 -0
  186. package/dist/partner/in-memory.cjs +135 -0
  187. package/dist/partner/in-memory.cjs.map +1 -0
  188. package/dist/partner/in-memory.d.cts +99 -0
  189. package/dist/partner/in-memory.d.cts.map +1 -0
  190. package/dist/partner/in-memory.d.ts +99 -0
  191. package/dist/partner/in-memory.d.ts.map +1 -0
  192. package/dist/partner/in-memory.js +135 -0
  193. package/dist/partner/in-memory.js.map +1 -0
  194. package/dist/partner/index.cjs +27 -0
  195. package/dist/partner/index.d.cts +32 -0
  196. package/dist/partner/index.d.cts.map +1 -0
  197. package/dist/partner/index.d.ts +32 -0
  198. package/dist/partner/index.d.ts.map +1 -0
  199. package/dist/partner/index.js +9 -0
  200. package/dist/partner/raw.cjs +400 -0
  201. package/dist/partner/raw.cjs.map +1 -0
  202. package/dist/partner/raw.d.cts +220 -0
  203. package/dist/partner/raw.d.cts.map +1 -0
  204. package/dist/partner/raw.d.ts +220 -0
  205. package/dist/partner/raw.d.ts.map +1 -0
  206. package/dist/partner/raw.js +398 -0
  207. package/dist/partner/raw.js.map +1 -0
  208. package/dist/partner/redaction-placeholders.cjs +10 -0
  209. package/dist/partner/redaction-placeholders.cjs.map +1 -0
  210. package/dist/partner/redaction-placeholders.d.cts +5 -0
  211. package/dist/partner/redaction-placeholders.d.cts.map +1 -0
  212. package/dist/partner/redaction-placeholders.d.ts +5 -0
  213. package/dist/partner/redaction-placeholders.d.ts.map +1 -0
  214. package/dist/partner/redaction-placeholders.js +9 -0
  215. package/dist/partner/redaction-placeholders.js.map +1 -0
  216. package/dist/partner/redaction.cjs +292 -0
  217. package/dist/partner/redaction.cjs.map +1 -0
  218. package/dist/partner/redaction.d.cts +158 -0
  219. package/dist/partner/redaction.d.cts.map +1 -0
  220. package/dist/partner/redaction.d.ts +158 -0
  221. package/dist/partner/redaction.d.ts.map +1 -0
  222. package/dist/partner/redaction.js +281 -0
  223. package/dist/partner/redaction.js.map +1 -0
  224. package/dist/raw/encoding.cjs +29 -10
  225. package/dist/raw/encoding.cjs.map +1 -1
  226. package/dist/raw/encoding.d.cts +3 -2
  227. package/dist/raw/encoding.d.cts.map +1 -1
  228. package/dist/raw/encoding.d.ts +3 -2
  229. package/dist/raw/encoding.d.ts.map +1 -1
  230. package/dist/raw/encoding.js +29 -10
  231. package/dist/raw/encoding.js.map +1 -1
  232. package/dist/raw/index.cjs +131 -44
  233. package/dist/raw/index.cjs.map +1 -1
  234. package/dist/raw/index.d.cts +21 -15
  235. package/dist/raw/index.d.cts.map +1 -1
  236. package/dist/raw/index.d.ts +21 -15
  237. package/dist/raw/index.d.ts.map +1 -1
  238. package/dist/raw/index.js +114 -45
  239. package/dist/raw/index.js.map +1 -1
  240. package/dist/raw/url.cjs +111 -0
  241. package/dist/raw/url.cjs.map +1 -0
  242. package/dist/raw/url.d.cts +41 -0
  243. package/dist/raw/url.d.cts.map +1 -0
  244. package/dist/raw/url.d.ts +41 -0
  245. package/dist/raw/url.d.ts.map +1 -0
  246. package/dist/raw/url.js +110 -0
  247. package/dist/raw/url.js.map +1 -0
  248. package/dist/s3/sigv4.cjs +15 -10
  249. package/dist/s3/sigv4.cjs.map +1 -1
  250. package/dist/s3/sigv4.js +15 -10
  251. package/dist/s3/sigv4.js.map +1 -1
  252. package/dist/simulator/index.cjs +1579 -257
  253. package/dist/simulator/index.cjs.map +1 -1
  254. package/dist/simulator/index.d.cts +124 -11
  255. package/dist/simulator/index.d.cts.map +1 -1
  256. package/dist/simulator/index.d.ts +124 -11
  257. package/dist/simulator/index.d.ts.map +1 -1
  258. package/dist/simulator/index.js +1568 -262
  259. package/dist/simulator/index.js.map +1 -1
  260. package/dist/simulator/partner-capabilities.cjs +77 -0
  261. package/dist/simulator/partner-capabilities.cjs.map +1 -0
  262. package/dist/simulator/partner-capabilities.d.cts +53 -0
  263. package/dist/simulator/partner-capabilities.d.cts.map +1 -0
  264. package/dist/simulator/partner-capabilities.d.ts +53 -0
  265. package/dist/simulator/partner-capabilities.d.ts.map +1 -0
  266. package/dist/simulator/partner-capabilities.js +73 -0
  267. package/dist/simulator/partner-capabilities.js.map +1 -0
  268. package/dist/simulator/partner.cjs +713 -0
  269. package/dist/simulator/partner.cjs.map +1 -0
  270. package/dist/simulator/partner.d.cts +186 -0
  271. package/dist/simulator/partner.d.cts.map +1 -0
  272. package/dist/simulator/partner.d.ts +186 -0
  273. package/dist/simulator/partner.d.ts.map +1 -0
  274. package/dist/simulator/partner.js +713 -0
  275. package/dist/simulator/partner.js.map +1 -0
  276. package/dist/simulator/validation.cjs +732 -25
  277. package/dist/simulator/validation.cjs.map +1 -1
  278. package/dist/simulator/validation.d.cts +145 -6
  279. package/dist/simulator/validation.d.cts.map +1 -1
  280. package/dist/simulator/validation.d.ts +145 -6
  281. package/dist/simulator/validation.d.ts.map +1 -1
  282. package/dist/simulator/validation.js +705 -26
  283. package/dist/simulator/validation.js.map +1 -1
  284. package/dist/streams/file-source.cjs +2 -2
  285. package/dist/streams/file-source.cjs.map +1 -1
  286. package/dist/streams/file-source.js +2 -2
  287. package/dist/streams/file-source.js.map +1 -1
  288. package/dist/streams/hash.cjs +246 -13
  289. package/dist/streams/hash.cjs.map +1 -1
  290. package/dist/streams/hash.d.cts +37 -12
  291. package/dist/streams/hash.d.cts.map +1 -1
  292. package/dist/streams/hash.d.ts +37 -12
  293. package/dist/streams/hash.d.ts.map +1 -1
  294. package/dist/streams/hash.js +246 -15
  295. package/dist/streams/hash.js.map +1 -1
  296. package/dist/streams/index.cjs +3 -1
  297. package/dist/streams/index.d.cts +1 -1
  298. package/dist/streams/index.d.cts.map +1 -1
  299. package/dist/streams/index.d.ts +1 -1
  300. package/dist/streams/index.d.ts.map +1 -1
  301. package/dist/streams/index.js +3 -3
  302. package/dist/streams/progress.cjs +63 -4
  303. package/dist/streams/progress.cjs.map +1 -1
  304. package/dist/streams/progress.d.cts +28 -2
  305. package/dist/streams/progress.d.cts.map +1 -1
  306. package/dist/streams/progress.d.ts +28 -2
  307. package/dist/streams/progress.d.ts.map +1 -1
  308. package/dist/streams/progress.js +63 -4
  309. package/dist/streams/progress.js.map +1 -1
  310. package/dist/streams/source.cjs +2 -1
  311. package/dist/streams/source.cjs.map +1 -1
  312. package/dist/streams/source.js +2 -1
  313. package/dist/streams/source.js.map +1 -1
  314. package/dist/sync/b2-sha1-reader.cjs +6 -2
  315. package/dist/sync/b2-sha1-reader.cjs.map +1 -1
  316. package/dist/sync/b2-sha1-reader.d.cts.map +1 -1
  317. package/dist/sync/b2-sha1-reader.d.ts.map +1 -1
  318. package/dist/sync/b2-sha1-reader.js +6 -2
  319. package/dist/sync/b2-sha1-reader.js.map +1 -1
  320. package/dist/sync/download-staging.cjs +156 -43
  321. package/dist/sync/download-staging.cjs.map +1 -1
  322. package/dist/sync/download-staging.d.cts +26 -2
  323. package/dist/sync/download-staging.d.cts.map +1 -1
  324. package/dist/sync/download-staging.d.ts +26 -2
  325. package/dist/sync/download-staging.d.ts.map +1 -1
  326. package/dist/sync/download-staging.js +155 -44
  327. package/dist/sync/download-staging.js.map +1 -1
  328. package/dist/sync/filters.cjs.map +1 -1
  329. package/dist/sync/filters.js.map +1 -1
  330. package/dist/sync/index.d.cts +1 -1
  331. package/dist/sync/index.d.cts.map +1 -1
  332. package/dist/sync/index.d.ts +1 -1
  333. package/dist/sync/index.d.ts.map +1 -1
  334. package/dist/sync/local-file-io.cjs +15 -6
  335. package/dist/sync/local-file-io.cjs.map +1 -1
  336. package/dist/sync/local-file-io.d.cts +3 -0
  337. package/dist/sync/local-file-io.d.cts.map +1 -1
  338. package/dist/sync/local-file-io.d.ts +3 -0
  339. package/dist/sync/local-file-io.d.ts.map +1 -1
  340. package/dist/sync/local-file-io.js +15 -6
  341. package/dist/sync/local-file-io.js.map +1 -1
  342. package/dist/sync/local-sha1.cjs +6 -15
  343. package/dist/sync/local-sha1.cjs.map +1 -1
  344. package/dist/sync/local-sha1.d.cts +0 -8
  345. package/dist/sync/local-sha1.d.cts.map +1 -1
  346. package/dist/sync/local-sha1.d.ts +0 -8
  347. package/dist/sync/local-sha1.d.ts.map +1 -1
  348. package/dist/sync/local-sha1.js +7 -15
  349. package/dist/sync/local-sha1.js.map +1 -1
  350. package/dist/sync/pairing.cjs +1 -0
  351. package/dist/sync/pairing.cjs.map +1 -1
  352. package/dist/sync/pairing.js +1 -0
  353. package/dist/sync/pairing.js.map +1 -1
  354. package/dist/sync/policies/compare.cjs +5 -3
  355. package/dist/sync/policies/compare.cjs.map +1 -1
  356. package/dist/sync/policies/compare.d.cts.map +1 -1
  357. package/dist/sync/policies/compare.d.ts.map +1 -1
  358. package/dist/sync/policies/compare.js +6 -4
  359. package/dist/sync/policies/compare.js.map +1 -1
  360. package/dist/sync/policies/index.cjs +4 -10
  361. package/dist/sync/policies/index.cjs.map +1 -1
  362. package/dist/sync/policies/index.js +4 -10
  363. package/dist/sync/policies/index.js.map +1 -1
  364. package/dist/sync/scanners/b2.cjs +4 -2
  365. package/dist/sync/scanners/b2.cjs.map +1 -1
  366. package/dist/sync/scanners/b2.d.cts.map +1 -1
  367. package/dist/sync/scanners/b2.d.ts.map +1 -1
  368. package/dist/sync/scanners/b2.js +4 -2
  369. package/dist/sync/scanners/b2.js.map +1 -1
  370. package/dist/sync/scanners/local.cjs +150 -33
  371. package/dist/sync/scanners/local.cjs.map +1 -1
  372. package/dist/sync/scanners/local.d.cts +6 -0
  373. package/dist/sync/scanners/local.d.cts.map +1 -1
  374. package/dist/sync/scanners/local.d.ts +6 -0
  375. package/dist/sync/scanners/local.d.ts.map +1 -1
  376. package/dist/sync/scanners/local.js +150 -33
  377. package/dist/sync/scanners/local.js.map +1 -1
  378. package/dist/sync/synchronizer.cjs +79 -31
  379. package/dist/sync/synchronizer.cjs.map +1 -1
  380. package/dist/sync/synchronizer.d.cts +1 -0
  381. package/dist/sync/synchronizer.d.cts.map +1 -1
  382. package/dist/sync/synchronizer.d.ts +1 -0
  383. package/dist/sync/synchronizer.d.ts.map +1 -1
  384. package/dist/sync/synchronizer.js +79 -31
  385. package/dist/sync/synchronizer.js.map +1 -1
  386. package/dist/sync/types.d.cts +19 -3
  387. package/dist/sync/types.d.cts.map +1 -1
  388. package/dist/sync/types.d.ts +19 -3
  389. package/dist/sync/types.d.ts.map +1 -1
  390. package/dist/types/auth.cjs +4 -0
  391. package/dist/types/auth.cjs.map +1 -1
  392. package/dist/types/auth.d.cts +4 -0
  393. package/dist/types/auth.d.cts.map +1 -1
  394. package/dist/types/auth.d.ts +4 -0
  395. package/dist/types/auth.d.ts.map +1 -1
  396. package/dist/types/auth.js +4 -0
  397. package/dist/types/auth.js.map +1 -1
  398. package/dist/types/backup.d.cts +85 -0
  399. package/dist/types/backup.d.cts.map +1 -0
  400. package/dist/types/backup.d.ts +85 -0
  401. package/dist/types/backup.d.ts.map +1 -0
  402. package/dist/types/bucket.cjs +81 -11
  403. package/dist/types/bucket.cjs.map +1 -1
  404. package/dist/types/bucket.d.cts +194 -41
  405. package/dist/types/bucket.d.cts.map +1 -1
  406. package/dist/types/bucket.d.ts +194 -41
  407. package/dist/types/bucket.d.ts.map +1 -1
  408. package/dist/types/bucket.js +67 -12
  409. package/dist/types/bucket.js.map +1 -1
  410. package/dist/types/download.cjs +62 -0
  411. package/dist/types/download.cjs.map +1 -0
  412. package/dist/types/download.d.cts +100 -16
  413. package/dist/types/download.d.cts.map +1 -1
  414. package/dist/types/download.d.ts +100 -16
  415. package/dist/types/download.d.ts.map +1 -1
  416. package/dist/types/download.js +61 -0
  417. package/dist/types/download.js.map +1 -0
  418. package/dist/types/encryption.cjs +76 -229
  419. package/dist/types/encryption.cjs.map +1 -1
  420. package/dist/types/encryption.d.cts +48 -6
  421. package/dist/types/encryption.d.cts.map +1 -1
  422. package/dist/types/encryption.d.ts +48 -6
  423. package/dist/types/encryption.d.ts.map +1 -1
  424. package/dist/types/encryption.js +74 -229
  425. package/dist/types/encryption.js.map +1 -1
  426. package/dist/types/errors.cjs +9 -0
  427. package/dist/types/errors.cjs.map +1 -1
  428. package/dist/types/errors.d.cts +1 -1
  429. package/dist/types/errors.d.cts.map +1 -1
  430. package/dist/types/errors.d.ts +1 -1
  431. package/dist/types/errors.d.ts.map +1 -1
  432. package/dist/types/errors.js +9 -0
  433. package/dist/types/errors.js.map +1 -1
  434. package/dist/types/file.cjs +3 -0
  435. package/dist/types/file.cjs.map +1 -1
  436. package/dist/types/file.d.cts +140 -18
  437. package/dist/types/file.d.cts.map +1 -1
  438. package/dist/types/file.d.ts +140 -18
  439. package/dist/types/file.d.ts.map +1 -1
  440. package/dist/types/file.js +3 -1
  441. package/dist/types/file.js.map +1 -1
  442. package/dist/types/ids.cjs +30 -0
  443. package/dist/types/ids.cjs.map +1 -1
  444. package/dist/types/ids.d.cts +32 -0
  445. package/dist/types/ids.d.cts.map +1 -1
  446. package/dist/types/ids.d.ts +32 -0
  447. package/dist/types/ids.d.ts.map +1 -1
  448. package/dist/types/ids.js +28 -1
  449. package/dist/types/ids.js.map +1 -1
  450. package/dist/types/index.d.cts +16 -12
  451. package/dist/types/index.d.cts.map +1 -1
  452. package/dist/types/index.d.ts +16 -12
  453. package/dist/types/index.d.ts.map +1 -1
  454. package/dist/types/key.d.cts +4 -3
  455. package/dist/types/key.d.cts.map +1 -1
  456. package/dist/types/key.d.ts +4 -3
  457. package/dist/types/key.d.ts.map +1 -1
  458. package/dist/types/lock.cjs.map +1 -1
  459. package/dist/types/lock.d.cts +14 -0
  460. package/dist/types/lock.d.cts.map +1 -1
  461. package/dist/types/lock.d.ts +14 -0
  462. package/dist/types/lock.d.ts.map +1 -1
  463. package/dist/types/lock.js.map +1 -1
  464. package/dist/types/notifications.cjs +31 -1
  465. package/dist/types/notifications.cjs.map +1 -1
  466. package/dist/types/notifications.d.cts +31 -4
  467. package/dist/types/notifications.d.cts.map +1 -1
  468. package/dist/types/notifications.d.ts +31 -4
  469. package/dist/types/notifications.d.ts.map +1 -1
  470. package/dist/types/notifications.js +30 -2
  471. package/dist/types/notifications.js.map +1 -1
  472. package/dist/types/partner.cjs +32 -0
  473. package/dist/types/partner.cjs.map +1 -0
  474. package/dist/types/partner.d.cts +386 -0
  475. package/dist/types/partner.d.cts.map +1 -0
  476. package/dist/types/partner.d.ts +386 -0
  477. package/dist/types/partner.d.ts.map +1 -0
  478. package/dist/types/partner.js +29 -0
  479. package/dist/types/partner.js.map +1 -0
  480. package/dist/types/upload.d.cts +35 -18
  481. package/dist/types/upload.d.cts.map +1 -1
  482. package/dist/types/upload.d.ts +35 -18
  483. package/dist/types/upload.d.ts.map +1 -1
  484. package/dist/upload/abort-scope.cjs +0 -45
  485. package/dist/upload/abort-scope.cjs.map +1 -1
  486. package/dist/upload/abort-scope.d.cts +0 -22
  487. package/dist/upload/abort-scope.d.cts.map +1 -1
  488. package/dist/upload/abort-scope.d.ts +0 -22
  489. package/dist/upload/abort-scope.d.ts.map +1 -1
  490. package/dist/upload/abort-scope.js +1 -44
  491. package/dist/upload/abort-scope.js.map +1 -1
  492. package/dist/upload/finish.cjs +3 -8
  493. package/dist/upload/finish.cjs.map +1 -1
  494. package/dist/upload/finish.d.cts.map +1 -1
  495. package/dist/upload/finish.d.ts.map +1 -1
  496. package/dist/upload/finish.js +1 -6
  497. package/dist/upload/finish.js.map +1 -1
  498. package/dist/upload/large.cjs +15 -8
  499. package/dist/upload/large.cjs.map +1 -1
  500. package/dist/upload/large.d.cts +31 -8
  501. package/dist/upload/large.d.cts.map +1 -1
  502. package/dist/upload/large.d.ts +31 -8
  503. package/dist/upload/large.d.ts.map +1 -1
  504. package/dist/upload/large.js +15 -8
  505. package/dist/upload/large.js.map +1 -1
  506. package/dist/upload/options.cjs.map +1 -1
  507. package/dist/upload/options.d.cts +24 -0
  508. package/dist/upload/options.d.cts.map +1 -1
  509. package/dist/upload/options.d.ts +24 -0
  510. package/dist/upload/options.d.ts.map +1 -1
  511. package/dist/upload/options.js.map +1 -1
  512. package/dist/upload/resume.cjs +6 -4
  513. package/dist/upload/resume.cjs.map +1 -1
  514. package/dist/upload/resume.d.cts +9 -5
  515. package/dist/upload/resume.d.cts.map +1 -1
  516. package/dist/upload/resume.d.ts +9 -5
  517. package/dist/upload/resume.d.ts.map +1 -1
  518. package/dist/upload/resume.js +6 -4
  519. package/dist/upload/resume.js.map +1 -1
  520. package/dist/upload/retry.cjs +25 -13
  521. package/dist/upload/retry.cjs.map +1 -1
  522. package/dist/upload/retry.d.cts.map +1 -1
  523. package/dist/upload/retry.d.ts.map +1 -1
  524. package/dist/upload/retry.js +25 -13
  525. package/dist/upload/retry.js.map +1 -1
  526. package/dist/upload/single.cjs +35 -30
  527. package/dist/upload/single.cjs.map +1 -1
  528. package/dist/upload/single.d.cts +12 -0
  529. package/dist/upload/single.d.cts.map +1 -1
  530. package/dist/upload/single.d.ts +12 -0
  531. package/dist/upload/single.d.ts.map +1 -1
  532. package/dist/upload/single.js +35 -30
  533. package/dist/upload/single.js.map +1 -1
  534. package/dist/upload/stream.cjs +18 -5
  535. package/dist/upload/stream.cjs.map +1 -1
  536. package/dist/upload/stream.d.cts +12 -0
  537. package/dist/upload/stream.d.cts.map +1 -1
  538. package/dist/upload/stream.d.ts +12 -0
  539. package/dist/upload/stream.d.ts.map +1 -1
  540. package/dist/upload/stream.js +15 -2
  541. package/dist/upload/stream.js.map +1 -1
  542. package/dist/util/abort.cjs +114 -0
  543. package/dist/util/abort.cjs.map +1 -0
  544. package/dist/util/abort.d.cts +65 -0
  545. package/dist/util/abort.d.cts.map +1 -0
  546. package/dist/util/abort.d.ts +65 -0
  547. package/dist/util/abort.d.ts.map +1 -0
  548. package/dist/util/abort.js +109 -0
  549. package/dist/util/abort.js.map +1 -0
  550. package/dist/util/defaults.cjs +3 -0
  551. package/dist/util/defaults.cjs.map +1 -1
  552. package/dist/util/defaults.d.cts +2 -0
  553. package/dist/util/defaults.d.cts.map +1 -1
  554. package/dist/util/defaults.d.ts +2 -0
  555. package/dist/util/defaults.d.ts.map +1 -1
  556. package/dist/util/defaults.js +3 -1
  557. package/dist/util/defaults.js.map +1 -1
  558. package/dist/util/md5.cjs +211 -0
  559. package/dist/util/md5.cjs.map +1 -0
  560. package/dist/util/md5.d.cts +43 -0
  561. package/dist/util/md5.d.cts.map +1 -0
  562. package/dist/util/md5.d.ts +43 -0
  563. package/dist/util/md5.d.ts.map +1 -0
  564. package/dist/util/md5.js +209 -0
  565. package/dist/util/md5.js.map +1 -0
  566. package/dist/util/normalize.cjs +5 -5
  567. package/dist/util/normalize.cjs.map +1 -1
  568. package/dist/util/normalize.d.cts +7 -7
  569. package/dist/util/normalize.d.cts.map +1 -1
  570. package/dist/util/normalize.d.ts +7 -7
  571. package/dist/util/normalize.d.ts.map +1 -1
  572. package/dist/util/normalize.js +5 -5
  573. package/dist/util/normalize.js.map +1 -1
  574. package/dist/util/paginator.cjs +7 -1
  575. package/dist/util/paginator.cjs.map +1 -1
  576. package/dist/util/paginator.d.cts +3 -1
  577. package/dist/util/paginator.d.cts.map +1 -1
  578. package/dist/util/paginator.d.ts +3 -1
  579. package/dist/util/paginator.d.ts.map +1 -1
  580. package/dist/util/paginator.js +7 -1
  581. package/dist/util/paginator.js.map +1 -1
  582. package/dist/version.cjs +56 -4
  583. package/dist/version.cjs.map +1 -1
  584. package/dist/version.d.cts +53 -4
  585. package/dist/version.d.cts.map +1 -1
  586. package/dist/version.d.ts +53 -4
  587. package/dist/version.d.ts.map +1 -1
  588. package/dist/version.js +52 -5
  589. package/dist/version.js.map +1 -1
  590. package/package.json +47 -18
@@ -0,0 +1,111 @@
1
+ const require_errors_index = require("./errors/index.cjs");
2
+ const require_text_codec = require("./util/text-codec.cjs");
3
+ const require_bucket = require("./types/bucket.cjs");
4
+ //#region src/bucket-validation.ts
5
+ var BUCKET_INFO_KEY_REGEX = new RegExp(require_bucket.BUCKET_INFO_KEY_PATTERN);
6
+ var CORS_RULE_NAME_REGEX = new RegExp(require_bucket.CORS_RULE_NAME_PATTERN);
7
+ var CORS_OPERATION_SET = new Set(require_bucket.CORS_ALLOWED_OPERATIONS);
8
+ /**
9
+ * Validates a bucketInfo record against B2's documented bucket metadata limits.
10
+ *
11
+ * @param bucketInfo - Caller-supplied bucketInfo record.
12
+ *
13
+ * @throws {@link B2BucketConfigurationError} When the record violates B2 limits.
14
+ */
15
+ function assertValidBucketInfo(bucketInfo) {
16
+ if (!isObjectRecord(bucketInfo)) throw new require_errors_index.B2BucketConfigurationError("bucketInfo", "bucketInfo must be an object", "invalid_bucket_info");
17
+ let totalValueBytes = 0;
18
+ for (const [key, value] of Object.entries(bucketInfo)) {
19
+ const keyBytes = utf8ByteLength(key);
20
+ if (keyBytes < 1 || keyBytes > 50) throw new require_errors_index.B2BucketConfigurationError("bucketInfo", `bucketInfo key "${key}" must be 1-50 UTF-8 bytes`, "invalid_bucket_info");
21
+ if (key.startsWith("b2-")) throw new require_errors_index.B2BucketConfigurationError("bucketInfo", `bucketInfo key "${key}" must not start with reserved prefix "b2-"`, "invalid_bucket_info");
22
+ if (!matchesEntirePattern(BUCKET_INFO_KEY_REGEX, key)) throw new require_errors_index.B2BucketConfigurationError("bucketInfo", `bucketInfo key "${key}" must match ${require_bucket.BUCKET_INFO_KEY_PATTERN}`, "invalid_bucket_info");
23
+ if (typeof value !== "string") throw new require_errors_index.B2BucketConfigurationError("bucketInfo", `bucketInfo value for "${key}" must be a string`, "invalid_bucket_info");
24
+ totalValueBytes += utf8ByteLength(value);
25
+ if (totalValueBytes > 1e4) throw new require_errors_index.B2BucketConfigurationError("bucketInfo", `bucketInfo values total ${totalValueBytes} UTF-8 bytes exceeds the ${require_bucket.BUCKET_INFO_VALUES_MAX_BYTES}-byte limit`, "invalid_bucket_info");
26
+ }
27
+ }
28
+ /**
29
+ * Validates CORS rules against B2's documented bucket CORS limits.
30
+ *
31
+ * @param corsRules - Caller-supplied CORS rule list.
32
+ *
33
+ * @throws {@link B2BucketConfigurationError} When any rule violates B2 limits.
34
+ */
35
+ function assertValidCorsRules(corsRules) {
36
+ if (!Array.isArray(corsRules)) throw new require_errors_index.B2BucketConfigurationError("corsRules", "corsRules must be an array");
37
+ if (corsRules.length > 100) throw new require_errors_index.B2BucketConfigurationError("corsRules", `corsRules cannot have more than 100 rules (got ${corsRules.length})`);
38
+ const names = /* @__PURE__ */ new Set();
39
+ for (const [index, rule] of corsRules.entries()) {
40
+ const rulePath = `corsRules[${index}]`;
41
+ if (!isObjectRecord(rule)) throw new require_errors_index.B2BucketConfigurationError("corsRules", `${rulePath} must be an object`);
42
+ const ruleName = readRequiredString(rule, "corsRuleName", `${rulePath}.corsRuleName`);
43
+ if (ruleName.length < 6 || ruleName.length > 63) throw new require_errors_index.B2BucketConfigurationError("corsRules", `${rulePath}.corsRuleName must be 6-63 characters`);
44
+ if (!matchesEntirePattern(CORS_RULE_NAME_REGEX, ruleName)) throw new require_errors_index.B2BucketConfigurationError("corsRules", `${rulePath}.corsRuleName must match ${require_bucket.CORS_RULE_NAME_PATTERN}`);
45
+ if (ruleName.startsWith("b2-")) throw new require_errors_index.B2BucketConfigurationError("corsRules", `${rulePath}.corsRuleName must not start with reserved prefix "b2-"`);
46
+ if (names.has(ruleName)) throw new require_errors_index.B2BucketConfigurationError("corsRules", `${rulePath}.corsRuleName must be unique within the bucket`);
47
+ names.add(ruleName);
48
+ const allowedOrigins = readRequiredStringArray(rule, "allowedOrigins", `${rulePath}.allowedOrigins`);
49
+ if (allowedOrigins.length === 0) throw new require_errors_index.B2BucketConfigurationError("corsRules", `${rulePath}.allowedOrigins must contain at least one item`);
50
+ const allowedOperations = readRequiredStringArray(rule, "allowedOperations", `${rulePath}.allowedOperations`);
51
+ if (allowedOperations.length === 0) throw new require_errors_index.B2BucketConfigurationError("corsRules", `${rulePath}.allowedOperations must contain at least one item`);
52
+ for (const operation of allowedOperations) if (!CORS_OPERATION_SET.has(operation)) throw new require_errors_index.B2BucketConfigurationError("corsRules", `${rulePath}.allowedOperations contains unsupported operation "${operation}"`);
53
+ const allowedHeaders = readNullableStringArray(rule, "allowedHeaders", `${rulePath}.allowedHeaders`);
54
+ const exposeHeaders = readNullableStringArray(rule, "exposeHeaders", `${rulePath}.exposeHeaders`);
55
+ const maxAgeSeconds = rule["maxAgeSeconds"];
56
+ if (!Number.isSafeInteger(maxAgeSeconds) || maxAgeSeconds < 0) throw new require_errors_index.B2BucketConfigurationError("corsRules", `${rulePath}.maxAgeSeconds must be a non-negative safe integer`);
57
+ if (maxAgeSeconds > 86400) throw new require_errors_index.B2BucketConfigurationError("corsRules", `${rulePath}.maxAgeSeconds must be at most ${require_bucket.CORS_MAX_AGE_SECONDS_MAX}`);
58
+ const ruleBytes = utf8ByteLength(ruleName) + sumStringBytes(allowedOrigins) + sumStringBytes(allowedOperations) + sumStringBytes(allowedHeaders ?? []) + sumStringBytes(exposeHeaders ?? []);
59
+ if (ruleBytes >= 1e3) throw new require_errors_index.B2BucketConfigurationError("corsRules", `${rulePath} size ${ruleBytes} UTF-8 bytes must be less than ${require_bucket.CORS_RULE_MAX_BYTES} bytes`);
60
+ }
61
+ }
62
+ /**
63
+ * Validates the bucket configuration fields common to create and update calls.
64
+ *
65
+ * @param request - Bucket create/update request.
66
+ *
67
+ * @throws {@link B2BucketConfigurationError} When any provided bucketInfo or
68
+ * CORS field violates B2 limits.
69
+ */
70
+ function assertValidBucketConfiguration(request) {
71
+ if (request.bucketInfo !== void 0) assertValidBucketInfo(request.bucketInfo);
72
+ if (request.corsRules !== void 0) assertValidCorsRules(request.corsRules);
73
+ }
74
+ function isObjectRecord(value) {
75
+ return typeof value === "object" && value !== null && !Array.isArray(value);
76
+ }
77
+ function matchesEntirePattern(regex, value) {
78
+ return regex.exec(value)?.[0] === value;
79
+ }
80
+ function readRequiredString(record, key, path) {
81
+ const value = record[key];
82
+ if (typeof value !== "string") throw new require_errors_index.B2BucketConfigurationError("corsRules", `${path} must be a string`);
83
+ return value;
84
+ }
85
+ function readRequiredStringArray(record, key, path) {
86
+ const value = record[key];
87
+ if (!Array.isArray(value)) throw new require_errors_index.B2BucketConfigurationError("corsRules", `${path} must be an array`);
88
+ for (const [index, item] of value.entries()) if (typeof item !== "string") throw new require_errors_index.B2BucketConfigurationError("corsRules", `${path}[${index}] must be a string`);
89
+ return value;
90
+ }
91
+ function readNullableStringArray(record, key, path) {
92
+ const value = record[key];
93
+ if (value === null || value === void 0) return null;
94
+ if (!Array.isArray(value)) throw new require_errors_index.B2BucketConfigurationError("corsRules", `${path} must be an array, null, or omitted`);
95
+ for (const [index, item] of value.entries()) if (typeof item !== "string") throw new require_errors_index.B2BucketConfigurationError("corsRules", `${path}[${index}] must be a string`);
96
+ return value;
97
+ }
98
+ function sumStringBytes(values) {
99
+ let total = 0;
100
+ for (const value of values) total += utf8ByteLength(value);
101
+ return total;
102
+ }
103
+ function utf8ByteLength(value) {
104
+ return require_text_codec.utf8Encoder.encode(value).byteLength;
105
+ }
106
+ //#endregion
107
+ exports.assertValidBucketConfiguration = assertValidBucketConfiguration;
108
+ exports.assertValidBucketInfo = assertValidBucketInfo;
109
+ exports.assertValidCorsRules = assertValidCorsRules;
110
+
111
+ //# sourceMappingURL=bucket-validation.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bucket-validation.cjs","names":[],"sources":["../src/bucket-validation.ts"],"sourcesContent":["import { B2BucketConfigurationError } from './errors/index.ts'\nimport {\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 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 type CorsRule,\n type CreateBucketRequest,\n type UpdateBucketRequest,\n} from './types/bucket.ts'\nimport { utf8Encoder } from './util/text-codec.ts'\n\nconst BUCKET_INFO_KEY_REGEX = new RegExp(BUCKET_INFO_KEY_PATTERN)\nconst CORS_RULE_NAME_REGEX = new RegExp(CORS_RULE_NAME_PATTERN)\nconst CORS_OPERATION_SET = new Set<string>(CORS_ALLOWED_OPERATIONS)\n\n/**\n * Validates a bucketInfo record against B2's documented bucket metadata limits.\n *\n * @param bucketInfo - Caller-supplied bucketInfo record.\n *\n * @throws {@link B2BucketConfigurationError} When the record violates B2 limits.\n */\nexport function assertValidBucketInfo(bucketInfo: Record<string, string>): void {\n if (!isObjectRecord(bucketInfo)) {\n throw new B2BucketConfigurationError(\n 'bucketInfo',\n 'bucketInfo must be an object',\n 'invalid_bucket_info',\n )\n }\n\n let totalValueBytes = 0\n for (const [key, value] of Object.entries(bucketInfo)) {\n const keyBytes = utf8ByteLength(key)\n if (keyBytes < BUCKET_INFO_KEY_MIN_BYTES || keyBytes > BUCKET_INFO_KEY_MAX_BYTES) {\n throw new B2BucketConfigurationError(\n 'bucketInfo',\n `bucketInfo key \"${key}\" must be ${BUCKET_INFO_KEY_MIN_BYTES}-${BUCKET_INFO_KEY_MAX_BYTES} UTF-8 bytes`,\n 'invalid_bucket_info',\n )\n }\n if (key.startsWith(BUCKET_INFO_RESERVED_PREFIX)) {\n throw new B2BucketConfigurationError(\n 'bucketInfo',\n `bucketInfo key \"${key}\" must not start with reserved prefix \"${BUCKET_INFO_RESERVED_PREFIX}\"`,\n 'invalid_bucket_info',\n )\n }\n if (!matchesEntirePattern(BUCKET_INFO_KEY_REGEX, key)) {\n throw new B2BucketConfigurationError(\n 'bucketInfo',\n `bucketInfo key \"${key}\" must match ${BUCKET_INFO_KEY_PATTERN}`,\n 'invalid_bucket_info',\n )\n }\n if (typeof value !== 'string') {\n throw new B2BucketConfigurationError(\n 'bucketInfo',\n `bucketInfo value for \"${key}\" must be a string`,\n 'invalid_bucket_info',\n )\n }\n\n totalValueBytes += utf8ByteLength(value)\n if (totalValueBytes > BUCKET_INFO_VALUES_MAX_BYTES) {\n throw new B2BucketConfigurationError(\n 'bucketInfo',\n `bucketInfo values total ${totalValueBytes} UTF-8 bytes exceeds the ${BUCKET_INFO_VALUES_MAX_BYTES}-byte limit`,\n 'invalid_bucket_info',\n )\n }\n }\n}\n\n/**\n * Validates CORS rules against B2's documented bucket CORS limits.\n *\n * @param corsRules - Caller-supplied CORS rule list.\n *\n * @throws {@link B2BucketConfigurationError} When any rule violates B2 limits.\n */\nexport function assertValidCorsRules(corsRules: readonly CorsRule[]): void {\n if (!Array.isArray(corsRules)) {\n throw new B2BucketConfigurationError('corsRules', 'corsRules must be an array')\n }\n if (corsRules.length > CORS_RULES_MAX_COUNT) {\n throw new B2BucketConfigurationError(\n 'corsRules',\n `corsRules cannot have more than ${CORS_RULES_MAX_COUNT} rules (got ${corsRules.length})`,\n )\n }\n\n const names = new Set<string>()\n for (const [index, rule] of corsRules.entries()) {\n const rulePath = `corsRules[${index}]`\n if (!isObjectRecord(rule)) {\n throw new B2BucketConfigurationError('corsRules', `${rulePath} must be an object`)\n }\n\n const ruleName = readRequiredString(rule, 'corsRuleName', `${rulePath}.corsRuleName`)\n if (\n ruleName.length < CORS_RULE_NAME_MIN_LENGTH ||\n ruleName.length > CORS_RULE_NAME_MAX_LENGTH\n ) {\n throw new B2BucketConfigurationError(\n 'corsRules',\n `${rulePath}.corsRuleName must be ${CORS_RULE_NAME_MIN_LENGTH}-${CORS_RULE_NAME_MAX_LENGTH} characters`,\n )\n }\n if (!matchesEntirePattern(CORS_RULE_NAME_REGEX, ruleName)) {\n throw new B2BucketConfigurationError(\n 'corsRules',\n `${rulePath}.corsRuleName must match ${CORS_RULE_NAME_PATTERN}`,\n )\n }\n if (ruleName.startsWith(CORS_RULE_NAME_RESERVED_PREFIX)) {\n throw new B2BucketConfigurationError(\n 'corsRules',\n `${rulePath}.corsRuleName must not start with reserved prefix \"${CORS_RULE_NAME_RESERVED_PREFIX}\"`,\n )\n }\n if (names.has(ruleName)) {\n throw new B2BucketConfigurationError(\n 'corsRules',\n `${rulePath}.corsRuleName must be unique within the bucket`,\n )\n }\n names.add(ruleName)\n\n const allowedOrigins = readRequiredStringArray(\n rule,\n 'allowedOrigins',\n `${rulePath}.allowedOrigins`,\n )\n if (allowedOrigins.length === 0) {\n throw new B2BucketConfigurationError(\n 'corsRules',\n `${rulePath}.allowedOrigins must contain at least one item`,\n )\n }\n\n const allowedOperations = readRequiredStringArray(\n rule,\n 'allowedOperations',\n `${rulePath}.allowedOperations`,\n )\n if (allowedOperations.length === 0) {\n throw new B2BucketConfigurationError(\n 'corsRules',\n `${rulePath}.allowedOperations must contain at least one item`,\n )\n }\n for (const operation of allowedOperations) {\n if (!CORS_OPERATION_SET.has(operation)) {\n throw new B2BucketConfigurationError(\n 'corsRules',\n `${rulePath}.allowedOperations contains unsupported operation \"${operation}\"`,\n )\n }\n }\n\n const allowedHeaders = readNullableStringArray(\n rule,\n 'allowedHeaders',\n `${rulePath}.allowedHeaders`,\n )\n const exposeHeaders = readNullableStringArray(\n rule,\n 'exposeHeaders',\n `${rulePath}.exposeHeaders`,\n )\n const maxAgeSeconds = (rule as Record<string, unknown>)['maxAgeSeconds']\n if (!Number.isSafeInteger(maxAgeSeconds) || (maxAgeSeconds as number) < 0) {\n throw new B2BucketConfigurationError(\n 'corsRules',\n `${rulePath}.maxAgeSeconds must be a non-negative safe integer`,\n )\n }\n if ((maxAgeSeconds as number) > CORS_MAX_AGE_SECONDS_MAX) {\n throw new B2BucketConfigurationError(\n 'corsRules',\n `${rulePath}.maxAgeSeconds must be at most ${CORS_MAX_AGE_SECONDS_MAX}`,\n )\n }\n\n const ruleBytes =\n utf8ByteLength(ruleName) +\n sumStringBytes(allowedOrigins) +\n sumStringBytes(allowedOperations) +\n sumStringBytes(allowedHeaders ?? []) +\n sumStringBytes(exposeHeaders ?? [])\n if (ruleBytes >= CORS_RULE_MAX_BYTES) {\n throw new B2BucketConfigurationError(\n 'corsRules',\n `${rulePath} size ${ruleBytes} UTF-8 bytes must be less than ${CORS_RULE_MAX_BYTES} bytes`,\n )\n }\n }\n}\n\n/**\n * Validates the bucket configuration fields common to create and update calls.\n *\n * @param request - Bucket create/update request.\n *\n * @throws {@link B2BucketConfigurationError} When any provided bucketInfo or\n * CORS field violates B2 limits.\n */\nexport function assertValidBucketConfiguration(\n request: Pick<CreateBucketRequest | UpdateBucketRequest, 'bucketInfo' | 'corsRules'>,\n): void {\n if (request.bucketInfo !== undefined) assertValidBucketInfo(request.bucketInfo)\n if (request.corsRules !== undefined) assertValidCorsRules(request.corsRules)\n}\n\nfunction isObjectRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction matchesEntirePattern(regex: RegExp, value: string): boolean {\n return regex.exec(value)?.[0] === value\n}\n\nfunction readRequiredString(record: Record<string, unknown>, key: string, path: string): string {\n const value = record[key]\n if (typeof value !== 'string') {\n throw new B2BucketConfigurationError('corsRules', `${path} must be a string`)\n }\n return value\n}\n\nfunction readRequiredStringArray(\n record: Record<string, unknown>,\n key: string,\n path: string,\n): readonly string[] {\n const value = record[key]\n if (!Array.isArray(value)) {\n throw new B2BucketConfigurationError('corsRules', `${path} must be an array`)\n }\n for (const [index, item] of value.entries()) {\n if (typeof item !== 'string') {\n throw new B2BucketConfigurationError('corsRules', `${path}[${index}] must be a string`)\n }\n }\n return value\n}\n\nfunction readNullableStringArray(\n record: Record<string, unknown>,\n key: string,\n path: string,\n): readonly string[] | null {\n const value = record[key]\n if (value === null || value === undefined) return null\n if (!Array.isArray(value)) {\n throw new B2BucketConfigurationError('corsRules', `${path} must be an array, null, or omitted`)\n }\n for (const [index, item] of value.entries()) {\n if (typeof item !== 'string') {\n throw new B2BucketConfigurationError('corsRules', `${path}[${index}] must be a string`)\n }\n }\n return value\n}\n\nfunction sumStringBytes(values: readonly string[]): number {\n let total = 0\n for (const value of values) total += utf8ByteLength(value)\n return total\n}\n\nfunction utf8ByteLength(value: string): number {\n return utf8Encoder.encode(value).byteLength\n}\n"],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { CorsRule, CreateBucketRequest, UpdateBucketRequest } from './types/bucket.js';
2
+ /**
3
+ * Validates a bucketInfo record against B2's documented bucket metadata limits.
4
+ *
5
+ * @param bucketInfo - Caller-supplied bucketInfo record.
6
+ *
7
+ * @throws {@link B2BucketConfigurationError} When the record violates B2 limits.
8
+ */
9
+ export declare function assertValidBucketInfo(bucketInfo: Record<string, string>): void;
10
+ /**
11
+ * Validates CORS rules against B2's documented bucket CORS limits.
12
+ *
13
+ * @param corsRules - Caller-supplied CORS rule list.
14
+ *
15
+ * @throws {@link B2BucketConfigurationError} When any rule violates B2 limits.
16
+ */
17
+ export declare function assertValidCorsRules(corsRules: readonly CorsRule[]): void;
18
+ /**
19
+ * Validates the bucket configuration fields common to create and update calls.
20
+ *
21
+ * @param request - Bucket create/update request.
22
+ *
23
+ * @throws {@link B2BucketConfigurationError} When any provided bucketInfo or
24
+ * CORS field violates B2 limits.
25
+ */
26
+ export declare function assertValidBucketConfiguration(request: Pick<CreateBucketRequest | UpdateBucketRequest, 'bucketInfo' | 'corsRules'>): void;
27
+ //# sourceMappingURL=bucket-validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bucket-validation.d.ts","sourceRoot":"","sources":["../src/bucket-validation.js"],"names":[],"mappings":"AACA,OAAO,EAcL,KAAK,QAAQ,EACb,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACzB,MAAM,mBAAmB,CAAA;AAO1B;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAkD9E;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,GAAG,IAAI,CAqHzE;AAED;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,IAAI,CAAC,mBAAmB,GAAG,mBAAmB,EAAE,YAAY,GAAG,WAAW,CAAC,GACnF,IAAI,CAGN"}
@@ -0,0 +1,27 @@
1
+ import { CorsRule, CreateBucketRequest, UpdateBucketRequest } from './types/bucket.js';
2
+ /**
3
+ * Validates a bucketInfo record against B2's documented bucket metadata limits.
4
+ *
5
+ * @param bucketInfo - Caller-supplied bucketInfo record.
6
+ *
7
+ * @throws {@link B2BucketConfigurationError} When the record violates B2 limits.
8
+ */
9
+ export declare function assertValidBucketInfo(bucketInfo: Record<string, string>): void;
10
+ /**
11
+ * Validates CORS rules against B2's documented bucket CORS limits.
12
+ *
13
+ * @param corsRules - Caller-supplied CORS rule list.
14
+ *
15
+ * @throws {@link B2BucketConfigurationError} When any rule violates B2 limits.
16
+ */
17
+ export declare function assertValidCorsRules(corsRules: readonly CorsRule[]): void;
18
+ /**
19
+ * Validates the bucket configuration fields common to create and update calls.
20
+ *
21
+ * @param request - Bucket create/update request.
22
+ *
23
+ * @throws {@link B2BucketConfigurationError} When any provided bucketInfo or
24
+ * CORS field violates B2 limits.
25
+ */
26
+ export declare function assertValidBucketConfiguration(request: Pick<CreateBucketRequest | UpdateBucketRequest, 'bucketInfo' | 'corsRules'>): void;
27
+ //# sourceMappingURL=bucket-validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bucket-validation.d.ts","sourceRoot":"","sources":["../src/bucket-validation.js"],"names":[],"mappings":"AACA,OAAO,EAcL,KAAK,QAAQ,EACb,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACzB,MAAM,mBAAmB,CAAA;AAO1B;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAkD9E;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,GAAG,IAAI,CAqHzE;AAED;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,IAAI,CAAC,mBAAmB,GAAG,mBAAmB,EAAE,YAAY,GAAG,WAAW,CAAC,GACnF,IAAI,CAGN"}
@@ -0,0 +1,109 @@
1
+ import { B2BucketConfigurationError } from "./errors/index.js";
2
+ import { utf8Encoder } from "./util/text-codec.js";
3
+ import { BUCKET_INFO_KEY_PATTERN, BUCKET_INFO_VALUES_MAX_BYTES, CORS_ALLOWED_OPERATIONS, CORS_MAX_AGE_SECONDS_MAX, CORS_RULE_MAX_BYTES, CORS_RULE_NAME_PATTERN } from "./types/bucket.js";
4
+ //#region src/bucket-validation.ts
5
+ var BUCKET_INFO_KEY_REGEX = new RegExp(BUCKET_INFO_KEY_PATTERN);
6
+ var CORS_RULE_NAME_REGEX = new RegExp(CORS_RULE_NAME_PATTERN);
7
+ var CORS_OPERATION_SET = new Set(CORS_ALLOWED_OPERATIONS);
8
+ /**
9
+ * Validates a bucketInfo record against B2's documented bucket metadata limits.
10
+ *
11
+ * @param bucketInfo - Caller-supplied bucketInfo record.
12
+ *
13
+ * @throws {@link B2BucketConfigurationError} When the record violates B2 limits.
14
+ */
15
+ function assertValidBucketInfo(bucketInfo) {
16
+ if (!isObjectRecord(bucketInfo)) throw new B2BucketConfigurationError("bucketInfo", "bucketInfo must be an object", "invalid_bucket_info");
17
+ let totalValueBytes = 0;
18
+ for (const [key, value] of Object.entries(bucketInfo)) {
19
+ const keyBytes = utf8ByteLength(key);
20
+ if (keyBytes < 1 || keyBytes > 50) throw new B2BucketConfigurationError("bucketInfo", `bucketInfo key "${key}" must be 1-50 UTF-8 bytes`, "invalid_bucket_info");
21
+ if (key.startsWith("b2-")) throw new B2BucketConfigurationError("bucketInfo", `bucketInfo key "${key}" must not start with reserved prefix "b2-"`, "invalid_bucket_info");
22
+ if (!matchesEntirePattern(BUCKET_INFO_KEY_REGEX, key)) throw new B2BucketConfigurationError("bucketInfo", `bucketInfo key "${key}" must match ${BUCKET_INFO_KEY_PATTERN}`, "invalid_bucket_info");
23
+ if (typeof value !== "string") throw new B2BucketConfigurationError("bucketInfo", `bucketInfo value for "${key}" must be a string`, "invalid_bucket_info");
24
+ totalValueBytes += utf8ByteLength(value);
25
+ if (totalValueBytes > 1e4) throw new B2BucketConfigurationError("bucketInfo", `bucketInfo values total ${totalValueBytes} UTF-8 bytes exceeds the ${BUCKET_INFO_VALUES_MAX_BYTES}-byte limit`, "invalid_bucket_info");
26
+ }
27
+ }
28
+ /**
29
+ * Validates CORS rules against B2's documented bucket CORS limits.
30
+ *
31
+ * @param corsRules - Caller-supplied CORS rule list.
32
+ *
33
+ * @throws {@link B2BucketConfigurationError} When any rule violates B2 limits.
34
+ */
35
+ function assertValidCorsRules(corsRules) {
36
+ if (!Array.isArray(corsRules)) throw new B2BucketConfigurationError("corsRules", "corsRules must be an array");
37
+ if (corsRules.length > 100) throw new B2BucketConfigurationError("corsRules", `corsRules cannot have more than 100 rules (got ${corsRules.length})`);
38
+ const names = /* @__PURE__ */ new Set();
39
+ for (const [index, rule] of corsRules.entries()) {
40
+ const rulePath = `corsRules[${index}]`;
41
+ if (!isObjectRecord(rule)) throw new B2BucketConfigurationError("corsRules", `${rulePath} must be an object`);
42
+ const ruleName = readRequiredString(rule, "corsRuleName", `${rulePath}.corsRuleName`);
43
+ if (ruleName.length < 6 || ruleName.length > 63) throw new B2BucketConfigurationError("corsRules", `${rulePath}.corsRuleName must be 6-63 characters`);
44
+ if (!matchesEntirePattern(CORS_RULE_NAME_REGEX, ruleName)) throw new B2BucketConfigurationError("corsRules", `${rulePath}.corsRuleName must match ${CORS_RULE_NAME_PATTERN}`);
45
+ if (ruleName.startsWith("b2-")) throw new B2BucketConfigurationError("corsRules", `${rulePath}.corsRuleName must not start with reserved prefix "b2-"`);
46
+ if (names.has(ruleName)) throw new B2BucketConfigurationError("corsRules", `${rulePath}.corsRuleName must be unique within the bucket`);
47
+ names.add(ruleName);
48
+ const allowedOrigins = readRequiredStringArray(rule, "allowedOrigins", `${rulePath}.allowedOrigins`);
49
+ if (allowedOrigins.length === 0) throw new B2BucketConfigurationError("corsRules", `${rulePath}.allowedOrigins must contain at least one item`);
50
+ const allowedOperations = readRequiredStringArray(rule, "allowedOperations", `${rulePath}.allowedOperations`);
51
+ if (allowedOperations.length === 0) throw new B2BucketConfigurationError("corsRules", `${rulePath}.allowedOperations must contain at least one item`);
52
+ for (const operation of allowedOperations) if (!CORS_OPERATION_SET.has(operation)) throw new B2BucketConfigurationError("corsRules", `${rulePath}.allowedOperations contains unsupported operation "${operation}"`);
53
+ const allowedHeaders = readNullableStringArray(rule, "allowedHeaders", `${rulePath}.allowedHeaders`);
54
+ const exposeHeaders = readNullableStringArray(rule, "exposeHeaders", `${rulePath}.exposeHeaders`);
55
+ const maxAgeSeconds = rule["maxAgeSeconds"];
56
+ if (!Number.isSafeInteger(maxAgeSeconds) || maxAgeSeconds < 0) throw new B2BucketConfigurationError("corsRules", `${rulePath}.maxAgeSeconds must be a non-negative safe integer`);
57
+ if (maxAgeSeconds > 86400) throw new B2BucketConfigurationError("corsRules", `${rulePath}.maxAgeSeconds must be at most ${CORS_MAX_AGE_SECONDS_MAX}`);
58
+ const ruleBytes = utf8ByteLength(ruleName) + sumStringBytes(allowedOrigins) + sumStringBytes(allowedOperations) + sumStringBytes(allowedHeaders ?? []) + sumStringBytes(exposeHeaders ?? []);
59
+ if (ruleBytes >= 1e3) throw new B2BucketConfigurationError("corsRules", `${rulePath} size ${ruleBytes} UTF-8 bytes must be less than ${CORS_RULE_MAX_BYTES} bytes`);
60
+ }
61
+ }
62
+ /**
63
+ * Validates the bucket configuration fields common to create and update calls.
64
+ *
65
+ * @param request - Bucket create/update request.
66
+ *
67
+ * @throws {@link B2BucketConfigurationError} When any provided bucketInfo or
68
+ * CORS field violates B2 limits.
69
+ */
70
+ function assertValidBucketConfiguration(request) {
71
+ if (request.bucketInfo !== void 0) assertValidBucketInfo(request.bucketInfo);
72
+ if (request.corsRules !== void 0) assertValidCorsRules(request.corsRules);
73
+ }
74
+ function isObjectRecord(value) {
75
+ return typeof value === "object" && value !== null && !Array.isArray(value);
76
+ }
77
+ function matchesEntirePattern(regex, value) {
78
+ return regex.exec(value)?.[0] === value;
79
+ }
80
+ function readRequiredString(record, key, path) {
81
+ const value = record[key];
82
+ if (typeof value !== "string") throw new B2BucketConfigurationError("corsRules", `${path} must be a string`);
83
+ return value;
84
+ }
85
+ function readRequiredStringArray(record, key, path) {
86
+ const value = record[key];
87
+ if (!Array.isArray(value)) throw new B2BucketConfigurationError("corsRules", `${path} must be an array`);
88
+ for (const [index, item] of value.entries()) if (typeof item !== "string") throw new B2BucketConfigurationError("corsRules", `${path}[${index}] must be a string`);
89
+ return value;
90
+ }
91
+ function readNullableStringArray(record, key, path) {
92
+ const value = record[key];
93
+ if (value === null || value === void 0) return null;
94
+ if (!Array.isArray(value)) throw new B2BucketConfigurationError("corsRules", `${path} must be an array, null, or omitted`);
95
+ for (const [index, item] of value.entries()) if (typeof item !== "string") throw new B2BucketConfigurationError("corsRules", `${path}[${index}] must be a string`);
96
+ return value;
97
+ }
98
+ function sumStringBytes(values) {
99
+ let total = 0;
100
+ for (const value of values) total += utf8ByteLength(value);
101
+ return total;
102
+ }
103
+ function utf8ByteLength(value) {
104
+ return utf8Encoder.encode(value).byteLength;
105
+ }
106
+ //#endregion
107
+ export { assertValidBucketConfiguration, assertValidBucketInfo, assertValidCorsRules };
108
+
109
+ //# sourceMappingURL=bucket-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bucket-validation.js","names":[],"sources":["../src/bucket-validation.ts"],"sourcesContent":["import { B2BucketConfigurationError } from './errors/index.ts'\nimport {\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 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 type CorsRule,\n type CreateBucketRequest,\n type UpdateBucketRequest,\n} from './types/bucket.ts'\nimport { utf8Encoder } from './util/text-codec.ts'\n\nconst BUCKET_INFO_KEY_REGEX = new RegExp(BUCKET_INFO_KEY_PATTERN)\nconst CORS_RULE_NAME_REGEX = new RegExp(CORS_RULE_NAME_PATTERN)\nconst CORS_OPERATION_SET = new Set<string>(CORS_ALLOWED_OPERATIONS)\n\n/**\n * Validates a bucketInfo record against B2's documented bucket metadata limits.\n *\n * @param bucketInfo - Caller-supplied bucketInfo record.\n *\n * @throws {@link B2BucketConfigurationError} When the record violates B2 limits.\n */\nexport function assertValidBucketInfo(bucketInfo: Record<string, string>): void {\n if (!isObjectRecord(bucketInfo)) {\n throw new B2BucketConfigurationError(\n 'bucketInfo',\n 'bucketInfo must be an object',\n 'invalid_bucket_info',\n )\n }\n\n let totalValueBytes = 0\n for (const [key, value] of Object.entries(bucketInfo)) {\n const keyBytes = utf8ByteLength(key)\n if (keyBytes < BUCKET_INFO_KEY_MIN_BYTES || keyBytes > BUCKET_INFO_KEY_MAX_BYTES) {\n throw new B2BucketConfigurationError(\n 'bucketInfo',\n `bucketInfo key \"${key}\" must be ${BUCKET_INFO_KEY_MIN_BYTES}-${BUCKET_INFO_KEY_MAX_BYTES} UTF-8 bytes`,\n 'invalid_bucket_info',\n )\n }\n if (key.startsWith(BUCKET_INFO_RESERVED_PREFIX)) {\n throw new B2BucketConfigurationError(\n 'bucketInfo',\n `bucketInfo key \"${key}\" must not start with reserved prefix \"${BUCKET_INFO_RESERVED_PREFIX}\"`,\n 'invalid_bucket_info',\n )\n }\n if (!matchesEntirePattern(BUCKET_INFO_KEY_REGEX, key)) {\n throw new B2BucketConfigurationError(\n 'bucketInfo',\n `bucketInfo key \"${key}\" must match ${BUCKET_INFO_KEY_PATTERN}`,\n 'invalid_bucket_info',\n )\n }\n if (typeof value !== 'string') {\n throw new B2BucketConfigurationError(\n 'bucketInfo',\n `bucketInfo value for \"${key}\" must be a string`,\n 'invalid_bucket_info',\n )\n }\n\n totalValueBytes += utf8ByteLength(value)\n if (totalValueBytes > BUCKET_INFO_VALUES_MAX_BYTES) {\n throw new B2BucketConfigurationError(\n 'bucketInfo',\n `bucketInfo values total ${totalValueBytes} UTF-8 bytes exceeds the ${BUCKET_INFO_VALUES_MAX_BYTES}-byte limit`,\n 'invalid_bucket_info',\n )\n }\n }\n}\n\n/**\n * Validates CORS rules against B2's documented bucket CORS limits.\n *\n * @param corsRules - Caller-supplied CORS rule list.\n *\n * @throws {@link B2BucketConfigurationError} When any rule violates B2 limits.\n */\nexport function assertValidCorsRules(corsRules: readonly CorsRule[]): void {\n if (!Array.isArray(corsRules)) {\n throw new B2BucketConfigurationError('corsRules', 'corsRules must be an array')\n }\n if (corsRules.length > CORS_RULES_MAX_COUNT) {\n throw new B2BucketConfigurationError(\n 'corsRules',\n `corsRules cannot have more than ${CORS_RULES_MAX_COUNT} rules (got ${corsRules.length})`,\n )\n }\n\n const names = new Set<string>()\n for (const [index, rule] of corsRules.entries()) {\n const rulePath = `corsRules[${index}]`\n if (!isObjectRecord(rule)) {\n throw new B2BucketConfigurationError('corsRules', `${rulePath} must be an object`)\n }\n\n const ruleName = readRequiredString(rule, 'corsRuleName', `${rulePath}.corsRuleName`)\n if (\n ruleName.length < CORS_RULE_NAME_MIN_LENGTH ||\n ruleName.length > CORS_RULE_NAME_MAX_LENGTH\n ) {\n throw new B2BucketConfigurationError(\n 'corsRules',\n `${rulePath}.corsRuleName must be ${CORS_RULE_NAME_MIN_LENGTH}-${CORS_RULE_NAME_MAX_LENGTH} characters`,\n )\n }\n if (!matchesEntirePattern(CORS_RULE_NAME_REGEX, ruleName)) {\n throw new B2BucketConfigurationError(\n 'corsRules',\n `${rulePath}.corsRuleName must match ${CORS_RULE_NAME_PATTERN}`,\n )\n }\n if (ruleName.startsWith(CORS_RULE_NAME_RESERVED_PREFIX)) {\n throw new B2BucketConfigurationError(\n 'corsRules',\n `${rulePath}.corsRuleName must not start with reserved prefix \"${CORS_RULE_NAME_RESERVED_PREFIX}\"`,\n )\n }\n if (names.has(ruleName)) {\n throw new B2BucketConfigurationError(\n 'corsRules',\n `${rulePath}.corsRuleName must be unique within the bucket`,\n )\n }\n names.add(ruleName)\n\n const allowedOrigins = readRequiredStringArray(\n rule,\n 'allowedOrigins',\n `${rulePath}.allowedOrigins`,\n )\n if (allowedOrigins.length === 0) {\n throw new B2BucketConfigurationError(\n 'corsRules',\n `${rulePath}.allowedOrigins must contain at least one item`,\n )\n }\n\n const allowedOperations = readRequiredStringArray(\n rule,\n 'allowedOperations',\n `${rulePath}.allowedOperations`,\n )\n if (allowedOperations.length === 0) {\n throw new B2BucketConfigurationError(\n 'corsRules',\n `${rulePath}.allowedOperations must contain at least one item`,\n )\n }\n for (const operation of allowedOperations) {\n if (!CORS_OPERATION_SET.has(operation)) {\n throw new B2BucketConfigurationError(\n 'corsRules',\n `${rulePath}.allowedOperations contains unsupported operation \"${operation}\"`,\n )\n }\n }\n\n const allowedHeaders = readNullableStringArray(\n rule,\n 'allowedHeaders',\n `${rulePath}.allowedHeaders`,\n )\n const exposeHeaders = readNullableStringArray(\n rule,\n 'exposeHeaders',\n `${rulePath}.exposeHeaders`,\n )\n const maxAgeSeconds = (rule as Record<string, unknown>)['maxAgeSeconds']\n if (!Number.isSafeInteger(maxAgeSeconds) || (maxAgeSeconds as number) < 0) {\n throw new B2BucketConfigurationError(\n 'corsRules',\n `${rulePath}.maxAgeSeconds must be a non-negative safe integer`,\n )\n }\n if ((maxAgeSeconds as number) > CORS_MAX_AGE_SECONDS_MAX) {\n throw new B2BucketConfigurationError(\n 'corsRules',\n `${rulePath}.maxAgeSeconds must be at most ${CORS_MAX_AGE_SECONDS_MAX}`,\n )\n }\n\n const ruleBytes =\n utf8ByteLength(ruleName) +\n sumStringBytes(allowedOrigins) +\n sumStringBytes(allowedOperations) +\n sumStringBytes(allowedHeaders ?? []) +\n sumStringBytes(exposeHeaders ?? [])\n if (ruleBytes >= CORS_RULE_MAX_BYTES) {\n throw new B2BucketConfigurationError(\n 'corsRules',\n `${rulePath} size ${ruleBytes} UTF-8 bytes must be less than ${CORS_RULE_MAX_BYTES} bytes`,\n )\n }\n }\n}\n\n/**\n * Validates the bucket configuration fields common to create and update calls.\n *\n * @param request - Bucket create/update request.\n *\n * @throws {@link B2BucketConfigurationError} When any provided bucketInfo or\n * CORS field violates B2 limits.\n */\nexport function assertValidBucketConfiguration(\n request: Pick<CreateBucketRequest | UpdateBucketRequest, 'bucketInfo' | 'corsRules'>,\n): void {\n if (request.bucketInfo !== undefined) assertValidBucketInfo(request.bucketInfo)\n if (request.corsRules !== undefined) assertValidCorsRules(request.corsRules)\n}\n\nfunction isObjectRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction matchesEntirePattern(regex: RegExp, value: string): boolean {\n return regex.exec(value)?.[0] === value\n}\n\nfunction readRequiredString(record: Record<string, unknown>, key: string, path: string): string {\n const value = record[key]\n if (typeof value !== 'string') {\n throw new B2BucketConfigurationError('corsRules', `${path} must be a string`)\n }\n return value\n}\n\nfunction readRequiredStringArray(\n record: Record<string, unknown>,\n key: string,\n path: string,\n): readonly string[] {\n const value = record[key]\n if (!Array.isArray(value)) {\n throw new B2BucketConfigurationError('corsRules', `${path} must be an array`)\n }\n for (const [index, item] of value.entries()) {\n if (typeof item !== 'string') {\n throw new B2BucketConfigurationError('corsRules', `${path}[${index}] must be a string`)\n }\n }\n return value\n}\n\nfunction readNullableStringArray(\n record: Record<string, unknown>,\n key: string,\n path: string,\n): readonly string[] | null {\n const value = record[key]\n if (value === null || value === undefined) return null\n if (!Array.isArray(value)) {\n throw new B2BucketConfigurationError('corsRules', `${path} must be an array, null, or omitted`)\n }\n for (const [index, item] of value.entries()) {\n if (typeof item !== 'string') {\n throw new B2BucketConfigurationError('corsRules', `${path}[${index}] must be a string`)\n }\n }\n return value\n}\n\nfunction sumStringBytes(values: readonly string[]): number {\n let total = 0\n for (const value of values) total += utf8ByteLength(value)\n return total\n}\n\nfunction utf8ByteLength(value: string): number {\n return utf8Encoder.encode(value).byteLength\n}\n"],"mappings":"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"}