@backblaze-labs/b2-sdk 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (701) hide show
  1. package/CHANGELOG.md +110 -5
  2. package/README.md +144 -33
  3. package/dist/_virtual/_b2-sdk-version-json.cjs +4 -0
  4. package/dist/_virtual/_b2-sdk-version-json.js +4 -0
  5. package/dist/auth/account-info.d.cts +32 -0
  6. package/dist/auth/account-info.d.cts.map +1 -1
  7. package/dist/auth/account-info.d.ts +32 -0
  8. package/dist/auth/account-info.d.ts.map +1 -1
  9. package/dist/auth/file.cjs +408 -207
  10. package/dist/auth/file.cjs.map +1 -1
  11. package/dist/auth/file.d.cts +77 -3
  12. package/dist/auth/file.d.cts.map +1 -1
  13. package/dist/auth/file.d.ts +77 -3
  14. package/dist/auth/file.d.ts.map +1 -1
  15. package/dist/auth/file.js +407 -207
  16. package/dist/auth/file.js.map +1 -1
  17. package/dist/auth/in-memory.cjs +212 -183
  18. package/dist/auth/in-memory.cjs.map +1 -1
  19. package/dist/auth/in-memory.d.cts +8 -0
  20. package/dist/auth/in-memory.d.cts.map +1 -1
  21. package/dist/auth/in-memory.d.ts +8 -0
  22. package/dist/auth/in-memory.d.ts.map +1 -1
  23. package/dist/auth/in-memory.js +211 -182
  24. package/dist/auth/in-memory.js.map +1 -1
  25. package/dist/auth/index.cjs +7 -9
  26. package/dist/auth/index.d.cts +3 -2
  27. package/dist/auth/index.d.cts.map +1 -1
  28. package/dist/auth/index.d.ts +3 -2
  29. package/dist/auth/index.d.ts.map +1 -1
  30. package/dist/auth/index.js +2 -8
  31. package/dist/auth/realms.cjs +80 -7
  32. package/dist/auth/realms.cjs.map +1 -1
  33. package/dist/auth/realms.d.cts +27 -4
  34. package/dist/auth/realms.d.cts.map +1 -1
  35. package/dist/auth/realms.d.ts +27 -4
  36. package/dist/auth/realms.d.ts.map +1 -1
  37. package/dist/auth/realms.js +80 -9
  38. package/dist/auth/realms.js.map +1 -1
  39. package/dist/auth/upload-url-pool.cjs +55 -51
  40. package/dist/auth/upload-url-pool.cjs.map +1 -1
  41. package/dist/auth/upload-url-pool.js +55 -51
  42. package/dist/auth/upload-url-pool.js.map +1 -1
  43. package/dist/bucket.cjs +785 -787
  44. package/dist/bucket.cjs.map +1 -1
  45. package/dist/bucket.d.cts +35 -47
  46. package/dist/bucket.d.cts.map +1 -1
  47. package/dist/bucket.d.ts +35 -47
  48. package/dist/bucket.d.ts.map +1 -1
  49. package/dist/bucket.js +780 -782
  50. package/dist/bucket.js.map +1 -1
  51. package/dist/client.cjs +246 -228
  52. package/dist/client.cjs.map +1 -1
  53. package/dist/client.d.cts +25 -17
  54. package/dist/client.d.cts.map +1 -1
  55. package/dist/client.d.ts +25 -17
  56. package/dist/client.d.ts.map +1 -1
  57. package/dist/client.js +243 -225
  58. package/dist/client.js.map +1 -1
  59. package/dist/copy/large.cjs +114 -71
  60. package/dist/copy/large.cjs.map +1 -1
  61. package/dist/copy/large.d.cts +6 -0
  62. package/dist/copy/large.d.cts.map +1 -1
  63. package/dist/copy/large.d.ts +6 -0
  64. package/dist/copy/large.d.ts.map +1 -1
  65. package/dist/copy/large.js +112 -69
  66. package/dist/copy/large.js.map +1 -1
  67. package/dist/download/checksum.cjs +89 -0
  68. package/dist/download/checksum.cjs.map +1 -0
  69. package/dist/download/checksum.d.cts +40 -0
  70. package/dist/download/checksum.d.cts.map +1 -0
  71. package/dist/download/checksum.d.ts +40 -0
  72. package/dist/download/checksum.d.ts.map +1 -0
  73. package/dist/download/checksum.js +87 -0
  74. package/dist/download/checksum.js.map +1 -0
  75. package/dist/download/parallel.cjs +214 -118
  76. package/dist/download/parallel.cjs.map +1 -1
  77. package/dist/download/parallel.d.cts +5 -1
  78. package/dist/download/parallel.d.cts.map +1 -1
  79. package/dist/download/parallel.d.ts +5 -1
  80. package/dist/download/parallel.d.ts.map +1 -1
  81. package/dist/download/parallel.js +212 -116
  82. package/dist/download/parallel.js.map +1 -1
  83. package/dist/download/single.cjs +188 -97
  84. package/dist/download/single.cjs.map +1 -1
  85. package/dist/download/single.d.cts +6 -1
  86. package/dist/download/single.d.cts.map +1 -1
  87. package/dist/download/single.d.ts +6 -1
  88. package/dist/download/single.d.ts.map +1 -1
  89. package/dist/download/single.js +186 -98
  90. package/dist/download/single.js.map +1 -1
  91. package/dist/errors/index.cjs +699 -243
  92. package/dist/errors/index.cjs.map +1 -1
  93. package/dist/errors/index.d.cts +285 -82
  94. package/dist/errors/index.d.cts.map +1 -1
  95. package/dist/errors/index.d.ts +285 -82
  96. package/dist/errors/index.d.ts.map +1 -1
  97. package/dist/errors/index.js +678 -261
  98. package/dist/errors/index.js.map +1 -1
  99. package/dist/http/retry.cjs +45 -28
  100. package/dist/http/retry.cjs.map +1 -1
  101. package/dist/http/retry.d.cts +15 -2
  102. package/dist/http/retry.d.cts.map +1 -1
  103. package/dist/http/retry.d.ts +15 -2
  104. package/dist/http/retry.d.ts.map +1 -1
  105. package/dist/http/retry.js +46 -31
  106. package/dist/http/retry.js.map +1 -1
  107. package/dist/http/transport.cjs +438 -140
  108. package/dist/http/transport.cjs.map +1 -1
  109. package/dist/http/transport.d.cts +21 -2
  110. package/dist/http/transport.d.cts.map +1 -1
  111. package/dist/http/transport.d.ts +21 -2
  112. package/dist/http/transport.d.ts.map +1 -1
  113. package/dist/http/transport.js +437 -140
  114. package/dist/http/transport.js.map +1 -1
  115. package/dist/http/url-guard.cjs +154 -89
  116. package/dist/http/url-guard.cjs.map +1 -1
  117. package/dist/http/url-guard.d.cts +25 -3
  118. package/dist/http/url-guard.d.cts.map +1 -1
  119. package/dist/http/url-guard.d.ts +25 -3
  120. package/dist/http/url-guard.d.ts.map +1 -1
  121. package/dist/http/url-guard.js +152 -90
  122. package/dist/http/url-guard.js.map +1 -1
  123. package/dist/http/user-agent.cjs +84 -44
  124. package/dist/http/user-agent.cjs.map +1 -1
  125. package/dist/http/user-agent.js +84 -46
  126. package/dist/http/user-agent.js.map +1 -1
  127. package/dist/index.cjs +101 -77
  128. package/dist/index.d.cts +27 -21
  129. package/dist/index.d.cts.map +1 -1
  130. package/dist/index.d.ts +27 -21
  131. package/dist/index.d.ts.map +1 -1
  132. package/dist/index.js +15 -71
  133. package/dist/internal/b2-naming.cjs +66 -0
  134. package/dist/internal/b2-naming.cjs.map +1 -0
  135. package/dist/internal/b2-naming.d.cts +43 -0
  136. package/dist/internal/b2-naming.d.cts.map +1 -0
  137. package/dist/internal/b2-naming.d.ts +43 -0
  138. package/dist/internal/b2-naming.d.ts.map +1 -0
  139. package/dist/internal/b2-naming.js +60 -0
  140. package/dist/internal/b2-naming.js.map +1 -0
  141. package/dist/internal/upload-retry-options.cjs +21 -0
  142. package/dist/internal/upload-retry-options.cjs.map +1 -0
  143. package/dist/internal/upload-retry-options.d.cts +12 -0
  144. package/dist/internal/upload-retry-options.d.cts.map +1 -0
  145. package/dist/internal/upload-retry-options.d.ts +12 -0
  146. package/dist/internal/upload-retry-options.d.ts.map +1 -0
  147. package/dist/internal/upload-retry-options.js +21 -0
  148. package/dist/internal/upload-retry-options.js.map +1 -0
  149. package/dist/internal/url-redaction.cjs +31 -0
  150. package/dist/internal/url-redaction.cjs.map +1 -0
  151. package/dist/internal/url-redaction.d.cts +17 -0
  152. package/dist/internal/url-redaction.d.cts.map +1 -0
  153. package/dist/internal/url-redaction.d.ts +17 -0
  154. package/dist/internal/url-redaction.d.ts.map +1 -0
  155. package/dist/internal/url-redaction.js +31 -0
  156. package/dist/internal/url-redaction.js.map +1 -0
  157. package/dist/notifications/index.cjs +4 -6
  158. package/dist/notifications/index.d.cts +1 -1
  159. package/dist/notifications/index.d.cts.map +1 -1
  160. package/dist/notifications/index.d.ts +1 -1
  161. package/dist/notifications/index.d.ts.map +1 -1
  162. package/dist/notifications/index.js +1 -6
  163. package/dist/notifications/webhook.cjs +195 -85
  164. package/dist/notifications/webhook.cjs.map +1 -1
  165. package/dist/notifications/webhook.d.cts.map +1 -1
  166. package/dist/notifications/webhook.d.ts.map +1 -1
  167. package/dist/notifications/webhook.js +195 -87
  168. package/dist/notifications/webhook.js.map +1 -1
  169. package/dist/object.cjs +253 -210
  170. package/dist/object.cjs.map +1 -1
  171. package/dist/object.d.cts +9 -55
  172. package/dist/object.d.cts.map +1 -1
  173. package/dist/object.d.ts +9 -55
  174. package/dist/object.d.ts.map +1 -1
  175. package/dist/object.js +249 -206
  176. package/dist/object.js.map +1 -1
  177. package/dist/raw/encoding.cjs +74 -35
  178. package/dist/raw/encoding.cjs.map +1 -1
  179. package/dist/raw/encoding.js +74 -38
  180. package/dist/raw/encoding.js.map +1 -1
  181. package/dist/raw/index.cjs +678 -587
  182. package/dist/raw/index.cjs.map +1 -1
  183. package/dist/raw/index.d.cts +121 -18
  184. package/dist/raw/index.d.cts.map +1 -1
  185. package/dist/raw/index.d.ts +121 -18
  186. package/dist/raw/index.d.ts.map +1 -1
  187. package/dist/raw/index.js +674 -589
  188. package/dist/raw/index.js.map +1 -1
  189. package/dist/s3/index.cjs +355 -18
  190. package/dist/s3/index.cjs.map +1 -1
  191. package/dist/s3/index.d.cts +233 -5
  192. package/dist/s3/index.d.cts.map +1 -1
  193. package/dist/s3/index.d.ts +233 -5
  194. package/dist/s3/index.d.ts.map +1 -1
  195. package/dist/s3/index.js +351 -22
  196. package/dist/s3/index.js.map +1 -1
  197. package/dist/s3/sigv4.cjs +149 -0
  198. package/dist/s3/sigv4.cjs.map +1 -0
  199. package/dist/s3/sigv4.d.cts +43 -0
  200. package/dist/s3/sigv4.d.cts.map +1 -0
  201. package/dist/s3/sigv4.d.ts +43 -0
  202. package/dist/s3/sigv4.d.ts.map +1 -0
  203. package/dist/s3/sigv4.js +148 -0
  204. package/dist/s3/sigv4.js.map +1 -0
  205. package/dist/s3/validation.cjs +69 -0
  206. package/dist/s3/validation.cjs.map +1 -0
  207. package/dist/s3/validation.d.cts +43 -0
  208. package/dist/s3/validation.d.cts.map +1 -0
  209. package/dist/s3/validation.d.ts +43 -0
  210. package/dist/s3/validation.d.ts.map +1 -0
  211. package/dist/s3/validation.js +66 -0
  212. package/dist/s3/validation.js.map +1 -0
  213. package/dist/simulator/capabilities.cjs +63 -48
  214. package/dist/simulator/capabilities.cjs.map +1 -1
  215. package/dist/simulator/capabilities.js +63 -49
  216. package/dist/simulator/capabilities.js.map +1 -1
  217. package/dist/simulator/index.cjs +2124 -1548
  218. package/dist/simulator/index.cjs.map +1 -1
  219. package/dist/simulator/index.d.cts +79 -11
  220. package/dist/simulator/index.d.cts.map +1 -1
  221. package/dist/simulator/index.d.ts +79 -11
  222. package/dist/simulator/index.d.ts.map +1 -1
  223. package/dist/simulator/index.js +2112 -1546
  224. package/dist/simulator/index.js.map +1 -1
  225. package/dist/simulator/validation.cjs +191 -153
  226. package/dist/simulator/validation.cjs.map +1 -1
  227. package/dist/simulator/validation.d.cts +3 -21
  228. package/dist/simulator/validation.d.cts.map +1 -1
  229. package/dist/simulator/validation.d.ts +3 -21
  230. package/dist/simulator/validation.d.ts.map +1 -1
  231. package/dist/simulator/validation.js +188 -162
  232. package/dist/simulator/validation.js.map +1 -1
  233. package/dist/streams/collect.cjs +74 -24
  234. package/dist/streams/collect.cjs.map +1 -1
  235. package/dist/streams/collect.d.cts +14 -1
  236. package/dist/streams/collect.d.cts.map +1 -1
  237. package/dist/streams/collect.d.ts +14 -1
  238. package/dist/streams/collect.d.ts.map +1 -1
  239. package/dist/streams/collect.js +74 -25
  240. package/dist/streams/collect.js.map +1 -1
  241. package/dist/streams/file-source.cjs +287 -0
  242. package/dist/streams/file-source.cjs.map +1 -0
  243. package/dist/streams/file-source.d.cts +96 -0
  244. package/dist/streams/file-source.d.cts.map +1 -0
  245. package/dist/streams/file-source.d.ts +96 -0
  246. package/dist/streams/file-source.d.ts.map +1 -0
  247. package/dist/streams/file-source.js +286 -0
  248. package/dist/streams/file-source.js.map +1 -0
  249. package/dist/streams/hash.cjs +207 -115
  250. package/dist/streams/hash.cjs.map +1 -1
  251. package/dist/streams/hash.d.cts +5 -4
  252. package/dist/streams/hash.d.cts.map +1 -1
  253. package/dist/streams/hash.d.ts +5 -4
  254. package/dist/streams/hash.d.ts.map +1 -1
  255. package/dist/streams/hash.js +208 -95
  256. package/dist/streams/hash.js.map +1 -1
  257. package/dist/streams/index.cjs +12 -12
  258. package/dist/streams/index.d.cts +3 -3
  259. package/dist/streams/index.d.cts.map +1 -1
  260. package/dist/streams/index.d.ts +3 -3
  261. package/dist/streams/index.d.ts.map +1 -1
  262. package/dist/streams/index.js +2 -10
  263. package/dist/streams/progress.cjs +60 -46
  264. package/dist/streams/progress.cjs.map +1 -1
  265. package/dist/streams/progress.js +60 -46
  266. package/dist/streams/progress.js.map +1 -1
  267. package/dist/streams/source.cjs +316 -146
  268. package/dist/streams/source.cjs.map +1 -1
  269. package/dist/streams/source.d.cts +56 -18
  270. package/dist/streams/source.d.cts.map +1 -1
  271. package/dist/streams/source.d.ts +56 -18
  272. package/dist/streams/source.d.ts.map +1 -1
  273. package/dist/streams/source.js +312 -149
  274. package/dist/streams/source.js.map +1 -1
  275. package/dist/sync/actions/index.cjs +236 -184
  276. package/dist/sync/actions/index.cjs.map +1 -1
  277. package/dist/sync/actions/index.d.cts +29 -21
  278. package/dist/sync/actions/index.d.cts.map +1 -1
  279. package/dist/sync/actions/index.d.ts +29 -21
  280. package/dist/sync/actions/index.d.ts.map +1 -1
  281. package/dist/sync/actions/index.js +236 -190
  282. package/dist/sync/actions/index.js.map +1 -1
  283. package/dist/sync/b2-sha1-reader.cjs +148 -0
  284. package/dist/sync/b2-sha1-reader.cjs.map +1 -0
  285. package/dist/sync/b2-sha1-reader.d.cts +58 -0
  286. package/dist/sync/b2-sha1-reader.d.cts.map +1 -0
  287. package/dist/sync/b2-sha1-reader.d.ts +58 -0
  288. package/dist/sync/b2-sha1-reader.d.ts.map +1 -0
  289. package/dist/sync/b2-sha1-reader.js +145 -0
  290. package/dist/sync/b2-sha1-reader.js.map +1 -0
  291. package/dist/sync/download-staging.cjs +265 -0
  292. package/dist/sync/download-staging.cjs.map +1 -0
  293. package/dist/sync/download-staging.d.cts +54 -0
  294. package/dist/sync/download-staging.d.cts.map +1 -0
  295. package/dist/sync/download-staging.d.ts +54 -0
  296. package/dist/sync/download-staging.d.ts.map +1 -0
  297. package/dist/sync/download-staging.js +259 -0
  298. package/dist/sync/download-staging.js.map +1 -0
  299. package/dist/sync/filesystem-errors.cjs +32 -0
  300. package/dist/sync/filesystem-errors.cjs.map +1 -0
  301. package/dist/sync/filesystem-errors.d.cts +8 -0
  302. package/dist/sync/filesystem-errors.d.cts.map +1 -0
  303. package/dist/sync/filesystem-errors.d.ts +8 -0
  304. package/dist/sync/filesystem-errors.d.ts.map +1 -0
  305. package/dist/sync/filesystem-errors.js +32 -0
  306. package/dist/sync/filesystem-errors.js.map +1 -0
  307. package/dist/sync/filters.cjs +217 -0
  308. package/dist/sync/filters.cjs.map +1 -0
  309. package/dist/sync/filters.d.cts +51 -0
  310. package/dist/sync/filters.d.cts.map +1 -0
  311. package/dist/sync/filters.d.ts +51 -0
  312. package/dist/sync/filters.d.ts.map +1 -0
  313. package/dist/sync/filters.js +213 -0
  314. package/dist/sync/filters.js.map +1 -0
  315. package/dist/sync/index.cjs +39 -22
  316. package/dist/sync/index.d.cts +14 -9
  317. package/dist/sync/index.d.cts.map +1 -1
  318. package/dist/sync/index.d.ts +14 -9
  319. package/dist/sync/index.d.ts.map +1 -1
  320. package/dist/sync/index.js +9 -20
  321. package/dist/sync/local-file-identity.cjs +61 -0
  322. package/dist/sync/local-file-identity.cjs.map +1 -0
  323. package/dist/sync/local-file-identity.d.cts +37 -0
  324. package/dist/sync/local-file-identity.d.cts.map +1 -0
  325. package/dist/sync/local-file-identity.d.ts +37 -0
  326. package/dist/sync/local-file-identity.d.ts.map +1 -0
  327. package/dist/sync/local-file-identity.js +60 -0
  328. package/dist/sync/local-file-identity.js.map +1 -0
  329. package/dist/sync/local-file-io.cjs +364 -0
  330. package/dist/sync/local-file-io.cjs.map +1 -0
  331. package/dist/sync/local-file-io.d.cts +75 -0
  332. package/dist/sync/local-file-io.d.cts.map +1 -0
  333. package/dist/sync/local-file-io.d.ts +75 -0
  334. package/dist/sync/local-file-io.d.ts.map +1 -0
  335. package/dist/sync/local-file-io.js +360 -0
  336. package/dist/sync/local-file-io.js.map +1 -0
  337. package/dist/sync/local-filesystem-root.cjs +27 -0
  338. package/dist/sync/local-filesystem-root.cjs.map +1 -0
  339. package/dist/sync/local-filesystem-root.d.cts +18 -0
  340. package/dist/sync/local-filesystem-root.d.cts.map +1 -0
  341. package/dist/sync/local-filesystem-root.d.ts +18 -0
  342. package/dist/sync/local-filesystem-root.d.ts.map +1 -0
  343. package/dist/sync/local-filesystem-root.js +26 -0
  344. package/dist/sync/local-filesystem-root.js.map +1 -0
  345. package/dist/sync/local-sha1.cjs +119 -0
  346. package/dist/sync/local-sha1.cjs.map +1 -0
  347. package/dist/sync/local-sha1.d.cts +39 -0
  348. package/dist/sync/local-sha1.d.cts.map +1 -0
  349. package/dist/sync/local-sha1.d.ts +39 -0
  350. package/dist/sync/local-sha1.d.ts.map +1 -0
  351. package/dist/sync/local-sha1.js +117 -0
  352. package/dist/sync/local-sha1.js.map +1 -0
  353. package/dist/sync/pairing.cjs +118 -29
  354. package/dist/sync/pairing.cjs.map +1 -1
  355. package/dist/sync/pairing.d.cts +7 -2
  356. package/dist/sync/pairing.d.cts.map +1 -1
  357. package/dist/sync/pairing.d.ts +7 -2
  358. package/dist/sync/pairing.d.ts.map +1 -1
  359. package/dist/sync/pairing.js +120 -31
  360. package/dist/sync/pairing.js.map +1 -1
  361. package/dist/sync/path-order.cjs +30 -0
  362. package/dist/sync/path-order.cjs.map +1 -0
  363. package/dist/sync/path-order.d.cts +28 -0
  364. package/dist/sync/path-order.d.cts.map +1 -0
  365. package/dist/sync/path-order.d.ts +28 -0
  366. package/dist/sync/path-order.d.ts.map +1 -0
  367. package/dist/sync/path-order.js +29 -0
  368. package/dist/sync/path-order.js.map +1 -0
  369. package/dist/sync/path-safety.cjs +111 -0
  370. package/dist/sync/path-safety.cjs.map +1 -0
  371. package/dist/sync/path-safety.d.cts +78 -0
  372. package/dist/sync/path-safety.d.cts.map +1 -0
  373. package/dist/sync/path-safety.d.ts +78 -0
  374. package/dist/sync/path-safety.d.ts.map +1 -0
  375. package/dist/sync/path-safety.js +105 -0
  376. package/dist/sync/path-safety.js.map +1 -0
  377. package/dist/sync/paths.d.cts +19 -0
  378. package/dist/sync/paths.d.cts.map +1 -0
  379. package/dist/sync/paths.d.ts +19 -0
  380. package/dist/sync/paths.d.ts.map +1 -0
  381. package/dist/sync/policies/compare.cjs +389 -11
  382. package/dist/sync/policies/compare.cjs.map +1 -1
  383. package/dist/sync/policies/compare.d.cts +100 -2
  384. package/dist/sync/policies/compare.d.cts.map +1 -1
  385. package/dist/sync/policies/compare.d.ts +100 -2
  386. package/dist/sync/policies/compare.d.ts.map +1 -1
  387. package/dist/sync/policies/compare.js +387 -13
  388. package/dist/sync/policies/compare.js.map +1 -1
  389. package/dist/sync/policies/index.cjs +76 -65
  390. package/dist/sync/policies/index.cjs.map +1 -1
  391. package/dist/sync/policies/index.d.cts +35 -6
  392. package/dist/sync/policies/index.d.cts.map +1 -1
  393. package/dist/sync/policies/index.d.ts +35 -6
  394. package/dist/sync/policies/index.d.ts.map +1 -1
  395. package/dist/sync/policies/index.js +76 -65
  396. package/dist/sync/policies/index.js.map +1 -1
  397. package/dist/sync/prefix.cjs +96 -0
  398. package/dist/sync/prefix.cjs.map +1 -0
  399. package/dist/sync/prefix.d.cts +55 -0
  400. package/dist/sync/prefix.d.cts.map +1 -0
  401. package/dist/sync/prefix.d.ts +55 -0
  402. package/dist/sync/prefix.d.ts.map +1 -0
  403. package/dist/sync/prefix.js +92 -0
  404. package/dist/sync/prefix.js.map +1 -0
  405. package/dist/sync/regexp-safety.cjs +192 -0
  406. package/dist/sync/regexp-safety.cjs.map +1 -0
  407. package/dist/sync/regexp-safety.d.cts +29 -0
  408. package/dist/sync/regexp-safety.d.cts.map +1 -0
  409. package/dist/sync/regexp-safety.d.ts +29 -0
  410. package/dist/sync/regexp-safety.d.ts.map +1 -0
  411. package/dist/sync/regexp-safety.js +190 -0
  412. package/dist/sync/regexp-safety.js.map +1 -0
  413. package/dist/sync/scan-events.cjs +33 -0
  414. package/dist/sync/scan-events.cjs.map +1 -0
  415. package/dist/sync/scan-events.d.cts +17 -0
  416. package/dist/sync/scan-events.d.cts.map +1 -0
  417. package/dist/sync/scan-events.d.ts +17 -0
  418. package/dist/sync/scan-events.d.ts.map +1 -0
  419. package/dist/sync/scan-events.js +32 -0
  420. package/dist/sync/scan-events.js.map +1 -0
  421. package/dist/sync/scan-limit.cjs +33 -0
  422. package/dist/sync/scan-limit.cjs.map +1 -0
  423. package/dist/sync/scan-limit.d.cts +21 -0
  424. package/dist/sync/scan-limit.d.cts.map +1 -0
  425. package/dist/sync/scan-limit.d.ts +21 -0
  426. package/dist/sync/scan-limit.d.ts.map +1 -0
  427. package/dist/sync/scan-limit.js +31 -0
  428. package/dist/sync/scan-limit.js.map +1 -0
  429. package/dist/sync/scanners/b2.cjs +239 -55
  430. package/dist/sync/scanners/b2.cjs.map +1 -1
  431. package/dist/sync/scanners/b2.d.cts +26 -7
  432. package/dist/sync/scanners/b2.d.cts.map +1 -1
  433. package/dist/sync/scanners/b2.d.ts +26 -7
  434. package/dist/sync/scanners/b2.d.ts.map +1 -1
  435. package/dist/sync/scanners/b2.js +239 -55
  436. package/dist/sync/scanners/b2.js.map +1 -1
  437. package/dist/sync/scanners/local.cjs +215 -56
  438. package/dist/sync/scanners/local.cjs.map +1 -1
  439. package/dist/sync/scanners/local.d.cts +22 -7
  440. package/dist/sync/scanners/local.d.cts.map +1 -1
  441. package/dist/sync/scanners/local.d.ts +22 -7
  442. package/dist/sync/scanners/local.d.ts.map +1 -1
  443. package/dist/sync/scanners/local.js +216 -57
  444. package/dist/sync/scanners/local.js.map +1 -1
  445. package/dist/sync/sha1-metadata.cjs +94 -0
  446. package/dist/sync/sha1-metadata.cjs.map +1 -0
  447. package/dist/sync/sha1-metadata.d.cts +82 -0
  448. package/dist/sync/sha1-metadata.d.cts.map +1 -0
  449. package/dist/sync/sha1-metadata.d.ts +82 -0
  450. package/dist/sync/sha1-metadata.d.ts.map +1 -0
  451. package/dist/sync/sha1-metadata.js +89 -0
  452. package/dist/sync/sha1-metadata.js.map +1 -0
  453. package/dist/sync/sha1-options.cjs +23 -0
  454. package/dist/sync/sha1-options.cjs.map +1 -0
  455. package/dist/sync/sha1-options.d.cts +14 -0
  456. package/dist/sync/sha1-options.d.cts.map +1 -0
  457. package/dist/sync/sha1-options.d.ts +14 -0
  458. package/dist/sync/sha1-options.d.ts.map +1 -0
  459. package/dist/sync/sha1-options.js +21 -0
  460. package/dist/sync/sha1-options.js.map +1 -0
  461. package/dist/sync/synchronizer.cjs +782 -197
  462. package/dist/sync/synchronizer.cjs.map +1 -1
  463. package/dist/sync/synchronizer.d.cts +47 -1
  464. package/dist/sync/synchronizer.d.cts.map +1 -1
  465. package/dist/sync/synchronizer.d.ts +47 -1
  466. package/dist/sync/synchronizer.d.ts.map +1 -1
  467. package/dist/sync/synchronizer.js +779 -173
  468. package/dist/sync/synchronizer.js.map +1 -1
  469. package/dist/sync/types.d.cts +208 -16
  470. package/dist/sync/types.d.cts.map +1 -1
  471. package/dist/sync/types.d.ts +208 -16
  472. package/dist/sync/types.d.ts.map +1 -1
  473. package/dist/types/auth.cjs +76 -56
  474. package/dist/types/auth.cjs.map +1 -1
  475. package/dist/types/auth.d.cts +67 -9
  476. package/dist/types/auth.d.cts.map +1 -1
  477. package/dist/types/auth.d.ts +67 -9
  478. package/dist/types/auth.d.ts.map +1 -1
  479. package/dist/types/auth.js +77 -57
  480. package/dist/types/auth.js.map +1 -1
  481. package/dist/types/bucket.cjs +74 -38
  482. package/dist/types/bucket.cjs.map +1 -1
  483. package/dist/types/bucket.js +75 -41
  484. package/dist/types/bucket.js.map +1 -1
  485. package/dist/types/encryption.cjs +364 -327
  486. package/dist/types/encryption.cjs.map +1 -1
  487. package/dist/types/encryption.d.cts +16 -0
  488. package/dist/types/encryption.d.cts.map +1 -1
  489. package/dist/types/encryption.d.ts +16 -0
  490. package/dist/types/encryption.d.ts.map +1 -1
  491. package/dist/types/encryption.js +364 -310
  492. package/dist/types/encryption.js.map +1 -1
  493. package/dist/types/errors.cjs +47 -0
  494. package/dist/types/errors.cjs.map +1 -0
  495. package/dist/types/errors.d.cts +13 -4
  496. package/dist/types/errors.d.cts.map +1 -1
  497. package/dist/types/errors.d.ts +13 -4
  498. package/dist/types/errors.d.ts.map +1 -1
  499. package/dist/types/errors.js +47 -0
  500. package/dist/types/errors.js.map +1 -0
  501. package/dist/types/file.cjs +36 -19
  502. package/dist/types/file.cjs.map +1 -1
  503. package/dist/types/file.d.cts +2 -2
  504. package/dist/types/file.d.cts.map +1 -1
  505. package/dist/types/file.d.ts +2 -2
  506. package/dist/types/file.d.ts.map +1 -1
  507. package/dist/types/file.js +37 -21
  508. package/dist/types/file.js.map +1 -1
  509. package/dist/types/ids.cjs +53 -9
  510. package/dist/types/ids.cjs.map +1 -1
  511. package/dist/types/ids.js +54 -15
  512. package/dist/types/ids.js.map +1 -1
  513. package/dist/types/index.d.cts +12 -11
  514. package/dist/types/index.d.cts.map +1 -1
  515. package/dist/types/index.d.ts +12 -11
  516. package/dist/types/index.d.ts.map +1 -1
  517. package/dist/types/key.d.cts +44 -8
  518. package/dist/types/key.d.cts.map +1 -1
  519. package/dist/types/key.d.ts +44 -8
  520. package/dist/types/key.d.ts.map +1 -1
  521. package/dist/types/lock.cjs +33 -13
  522. package/dist/types/lock.cjs.map +1 -1
  523. package/dist/types/lock.js +34 -15
  524. package/dist/types/lock.js.map +1 -1
  525. package/dist/types/notifications.cjs +44 -22
  526. package/dist/types/notifications.cjs.map +1 -1
  527. package/dist/types/notifications.js +45 -23
  528. package/dist/types/notifications.js.map +1 -1
  529. package/dist/types/upload.d.cts +39 -5
  530. package/dist/types/upload.d.cts.map +1 -1
  531. package/dist/types/upload.d.ts +39 -5
  532. package/dist/types/upload.d.ts.map +1 -1
  533. package/dist/upload/abort-scope.cjs +91 -0
  534. package/dist/upload/abort-scope.cjs.map +1 -0
  535. package/dist/upload/abort-scope.d.cts +48 -0
  536. package/dist/upload/abort-scope.d.cts.map +1 -0
  537. package/dist/upload/abort-scope.d.ts +48 -0
  538. package/dist/upload/abort-scope.d.ts.map +1 -0
  539. package/dist/upload/abort-scope.js +88 -0
  540. package/dist/upload/abort-scope.js.map +1 -0
  541. package/dist/upload/cancel.cjs +183 -8
  542. package/dist/upload/cancel.cjs.map +1 -1
  543. package/dist/upload/cancel.d.cts +110 -2
  544. package/dist/upload/cancel.d.cts.map +1 -1
  545. package/dist/upload/cancel.d.ts +110 -2
  546. package/dist/upload/cancel.d.ts.map +1 -1
  547. package/dist/upload/cancel.js +178 -9
  548. package/dist/upload/cancel.js.map +1 -1
  549. package/dist/upload/concurrency.cjs +79 -52
  550. package/dist/upload/concurrency.cjs.map +1 -1
  551. package/dist/upload/concurrency.js +79 -53
  552. package/dist/upload/concurrency.js.map +1 -1
  553. package/dist/upload/finish.cjs +59 -0
  554. package/dist/upload/finish.cjs.map +1 -0
  555. package/dist/upload/finish.d.cts +26 -0
  556. package/dist/upload/finish.d.cts.map +1 -0
  557. package/dist/upload/finish.d.ts +26 -0
  558. package/dist/upload/finish.d.ts.map +1 -0
  559. package/dist/upload/finish.js +59 -0
  560. package/dist/upload/finish.js.map +1 -0
  561. package/dist/upload/large.cjs +301 -218
  562. package/dist/upload/large.cjs.map +1 -1
  563. package/dist/upload/large.d.cts +76 -9
  564. package/dist/upload/large.d.cts.map +1 -1
  565. package/dist/upload/large.d.ts +76 -9
  566. package/dist/upload/large.d.ts.map +1 -1
  567. package/dist/upload/large.js +301 -218
  568. package/dist/upload/large.js.map +1 -1
  569. package/dist/upload/options.cjs +28 -0
  570. package/dist/upload/options.cjs.map +1 -0
  571. package/dist/upload/options.d.cts +104 -0
  572. package/dist/upload/options.d.cts.map +1 -0
  573. package/dist/upload/options.d.ts +104 -0
  574. package/dist/upload/options.d.ts.map +1 -0
  575. package/dist/upload/options.js +27 -0
  576. package/dist/upload/options.js.map +1 -0
  577. package/dist/upload/resume.cjs +333 -33
  578. package/dist/upload/resume.cjs.map +1 -1
  579. package/dist/upload/resume.d.cts +82 -12
  580. package/dist/upload/resume.d.cts.map +1 -1
  581. package/dist/upload/resume.d.ts +82 -12
  582. package/dist/upload/resume.d.ts.map +1 -1
  583. package/dist/upload/resume.js +330 -33
  584. package/dist/upload/resume.js.map +1 -1
  585. package/dist/upload/retry.cjs +186 -0
  586. package/dist/upload/retry.cjs.map +1 -0
  587. package/dist/upload/retry.d.cts +127 -0
  588. package/dist/upload/retry.d.cts.map +1 -0
  589. package/dist/upload/retry.d.ts +127 -0
  590. package/dist/upload/retry.d.ts.map +1 -0
  591. package/dist/upload/retry.js +182 -0
  592. package/dist/upload/retry.js.map +1 -0
  593. package/dist/upload/single.cjs +68 -44
  594. package/dist/upload/single.cjs.map +1 -1
  595. package/dist/upload/single.d.cts +2 -1
  596. package/dist/upload/single.d.cts.map +1 -1
  597. package/dist/upload/single.d.ts +2 -1
  598. package/dist/upload/single.d.ts.map +1 -1
  599. package/dist/upload/single.js +68 -44
  600. package/dist/upload/single.js.map +1 -1
  601. package/dist/upload/stream.cjs +317 -193
  602. package/dist/upload/stream.cjs.map +1 -1
  603. package/dist/upload/stream.d.cts +3 -1
  604. package/dist/upload/stream.d.cts.map +1 -1
  605. package/dist/upload/stream.d.ts +3 -1
  606. package/dist/upload/stream.d.ts.map +1 -1
  607. package/dist/upload/stream.js +316 -192
  608. package/dist/upload/stream.js.map +1 -1
  609. package/dist/util/best-effort.cjs +42 -8
  610. package/dist/util/best-effort.cjs.map +1 -1
  611. package/dist/util/best-effort.d.cts +2 -1
  612. package/dist/util/best-effort.d.cts.map +1 -1
  613. package/dist/util/best-effort.d.ts +2 -1
  614. package/dist/util/best-effort.d.ts.map +1 -1
  615. package/dist/util/best-effort.js +43 -9
  616. package/dist/util/best-effort.js.map +1 -1
  617. package/dist/util/bytes.cjs +23 -0
  618. package/dist/util/bytes.cjs.map +1 -0
  619. package/dist/util/bytes.d.cts +15 -0
  620. package/dist/util/bytes.d.cts.map +1 -0
  621. package/dist/util/bytes.d.ts +15 -0
  622. package/dist/util/bytes.d.ts.map +1 -0
  623. package/dist/util/bytes.js +23 -0
  624. package/dist/util/bytes.js.map +1 -0
  625. package/dist/util/crypto.cjs +68 -0
  626. package/dist/util/crypto.cjs.map +1 -0
  627. package/dist/util/crypto.d.cts +26 -0
  628. package/dist/util/crypto.d.cts.map +1 -0
  629. package/dist/util/crypto.d.ts +26 -0
  630. package/dist/util/crypto.d.ts.map +1 -0
  631. package/dist/util/crypto.js +66 -0
  632. package/dist/util/crypto.js.map +1 -0
  633. package/dist/util/defaults.cjs +25 -9
  634. package/dist/util/defaults.cjs.map +1 -1
  635. package/dist/util/defaults.js +26 -11
  636. package/dist/util/defaults.js.map +1 -1
  637. package/dist/util/error-reason.cjs +41 -0
  638. package/dist/util/error-reason.cjs.map +1 -0
  639. package/dist/util/error-reason.d.cts +9 -0
  640. package/dist/util/error-reason.d.cts.map +1 -0
  641. package/dist/util/error-reason.d.ts +9 -0
  642. package/dist/util/error-reason.d.ts.map +1 -0
  643. package/dist/util/error-reason.js +41 -0
  644. package/dist/util/error-reason.js.map +1 -0
  645. package/dist/util/http.cjs +23 -0
  646. package/dist/util/http.cjs.map +1 -0
  647. package/dist/util/http.d.cts +13 -0
  648. package/dist/util/http.d.cts.map +1 -0
  649. package/dist/util/http.d.ts +13 -0
  650. package/dist/util/http.d.ts.map +1 -0
  651. package/dist/util/http.js +23 -0
  652. package/dist/util/http.js.map +1 -0
  653. package/dist/util/normalize.cjs +66 -7
  654. package/dist/util/normalize.cjs.map +1 -1
  655. package/dist/util/normalize.js +67 -10
  656. package/dist/util/normalize.js.map +1 -1
  657. package/dist/util/paginator.cjs +63 -14
  658. package/dist/util/paginator.cjs.map +1 -1
  659. package/dist/util/paginator.js +64 -16
  660. package/dist/util/paginator.js.map +1 -1
  661. package/dist/util/plan-ranges.cjs +47 -22
  662. package/dist/util/plan-ranges.cjs.map +1 -1
  663. package/dist/util/plan-ranges.js +48 -24
  664. package/dist/util/plan-ranges.js.map +1 -1
  665. package/dist/util/sha1.cjs +27 -0
  666. package/dist/util/sha1.cjs.map +1 -0
  667. package/dist/util/sha1.d.cts +17 -0
  668. package/dist/util/sha1.d.cts.map +1 -0
  669. package/dist/util/sha1.d.ts +17 -0
  670. package/dist/util/sha1.d.ts.map +1 -0
  671. package/dist/util/sha1.js +26 -0
  672. package/dist/util/sha1.js.map +1 -0
  673. package/dist/util/text-codec.cjs +29 -5
  674. package/dist/util/text-codec.cjs.map +1 -1
  675. package/dist/util/text-codec.js +30 -7
  676. package/dist/util/text-codec.js.map +1 -1
  677. package/dist/util/to-error.cjs +18 -4
  678. package/dist/util/to-error.cjs.map +1 -1
  679. package/dist/util/to-error.js +19 -5
  680. package/dist/util/to-error.js.map +1 -1
  681. package/dist/version.cjs +17 -5
  682. package/dist/version.cjs.map +1 -1
  683. package/dist/version.d.cts +3 -3
  684. package/dist/version.d.ts +3 -3
  685. package/dist/version.js +19 -6
  686. package/dist/version.js.map +1 -1
  687. package/package.json +19 -16
  688. package/dist/auth/index.cjs.map +0 -1
  689. package/dist/auth/index.js.map +0 -1
  690. package/dist/index.cjs.map +0 -1
  691. package/dist/index.js.map +0 -1
  692. package/dist/notifications/index.cjs.map +0 -1
  693. package/dist/notifications/index.js.map +0 -1
  694. package/dist/package.json.cjs +0 -9
  695. package/dist/package.json.cjs.map +0 -1
  696. package/dist/package.json.js +0 -9
  697. package/dist/package.json.js.map +0 -1
  698. package/dist/streams/index.cjs.map +0 -1
  699. package/dist/streams/index.js.map +0 -1
  700. package/dist/sync/index.cjs.map +0 -1
  701. package/dist/sync/index.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sigv4.cjs","names":[],"sources":["../../src/s3/sigv4.ts"],"sourcesContent":["import { redactUrlForError } from '../internal/url-redaction.ts'\nimport { hexEncode, hmacSha256, sha256Hex } from '../util/crypto.ts'\nimport { hasHttpHeaderControlCharacter } from '../util/http.ts'\nimport { assertSafeBucketName, assertValidB2FileName } from './validation.ts'\n\nconst MAX_PRESIGN_EXPIRES_IN = 604_800\nconst UNSIGNED_PAYLOAD = 'UNSIGNED-PAYLOAD'\nconst SERVICE = 's3'\nconst TERMINATOR = 'aws4_request'\n/** Default S3 presigned URL validity duration in seconds. */\nexport const DEFAULT_PRESIGN_EXPIRES_IN = 3600\n\n/** Date input accepted by SigV4 presign internals and deterministic tests. */\nexport type S3PresignDate = Date | number\n\n/** Query parameter included in the SigV4 canonical query string. */\nexport type QueryParam = readonly [name: string, value: string]\n\n/** HTTP header included in the SigV4 signed headers list. */\nexport type SignedHeader = readonly [name: string, value: string]\n\n/** Internal inputs required to presign one S3-compatible object request. */\nexport interface SigV4PresignRequestOptions {\n /** S3-compatible endpoint URL. */\n readonly endpoint: string\n /** S3 signing region. */\n readonly region: string\n /** S3 access key ID. */\n readonly accessKeyId: string\n /** S3 secret access key. */\n readonly secretAccessKey: string\n /** Bucket containing the object. */\n readonly bucketName: string\n /** Object key / B2 file name. */\n readonly fileName: string\n /** Optional URL validity duration in seconds. */\n readonly expiresIn?: number\n /** Optional signing clock override. */\n readonly signingDate?: S3PresignDate\n}\n\n/**\n * Generates an AWS Signature Version 4 presigned S3-compatible request URL.\n *\n * This module owns only canonical SigV4 mechanics: canonical URI/query/header\n * construction, signing-key derivation, and signature encoding. Public B2 S3\n * option validation and naming stay in `index.ts`.\n *\n * @param method - HTTP method to presign.\n * @param options - S3 endpoint, credentials, object key, and signing options.\n * @param extraQuery - Operation-specific query parameters to sign.\n * @param extraHeaders - Operation-specific request headers to sign.\n *\n * @returns The presigned request URL.\n */\nexport async function presignS3Request(\n method: 'GET' | 'PUT',\n options: SigV4PresignRequestOptions,\n extraQuery: readonly QueryParam[],\n extraHeaders: readonly SignedHeader[],\n): Promise<string> {\n const endpoint = parseEndpoint(options.endpoint)\n assertHttpsEndpoint(endpoint)\n const expiresIn = normalizeExpiresIn(options.expiresIn)\n const { shortDate, longDate } = formatSigningDate(options.signingDate)\n const credentialScope = `${shortDate}/${options.region}/${SERVICE}/${TERMINATOR}`\n const credential = `${options.accessKeyId}/${credentialScope}`\n assertSafeBucketName(options.bucketName)\n assertValidB2FileName(options.fileName)\n const canonicalUri = buildCanonicalUri(endpoint.pathname, options.bucketName, options.fileName)\n const headers = normalizeSignedHeaders([['host', canonicalHostHeader(endpoint)], ...extraHeaders])\n const signedHeaders = headers.map(([name]) => name).join(';')\n\n const query: QueryParam[] = [\n ['X-Amz-Algorithm', 'AWS4-HMAC-SHA256'],\n ['X-Amz-Credential', credential],\n ['X-Amz-Content-Sha256', UNSIGNED_PAYLOAD],\n ['X-Amz-Date', longDate],\n ['X-Amz-Expires', String(expiresIn)],\n ['X-Amz-SignedHeaders', signedHeaders],\n ...extraQuery,\n ]\n const canonicalQuery = canonicalQueryString(query)\n const canonicalHeaders = headers.map(([name, value]) => `${name}:${value}\\n`).join('')\n const canonicalRequest = [\n method,\n canonicalUri,\n canonicalQuery,\n canonicalHeaders,\n signedHeaders,\n UNSIGNED_PAYLOAD,\n ].join('\\n')\n const stringToSign = [\n 'AWS4-HMAC-SHA256',\n longDate,\n credentialScope,\n await sha256Hex(canonicalRequest),\n ].join('\\n')\n const signingKey = await deriveSigningKey(options.secretAccessKey, shortDate, options.region)\n const signature = hexEncode(await hmacSha256(signingKey, stringToSign))\n const finalQuery = canonicalQueryString([...query, ['X-Amz-Signature', signature]])\n\n return `${endpoint.origin}${canonicalUri}?${finalQuery}`\n}\n\nfunction normalizeExpiresIn(expiresIn: number | undefined): number {\n const value = expiresIn ?? DEFAULT_PRESIGN_EXPIRES_IN\n if (!Number.isInteger(value) || value < 1 || value > MAX_PRESIGN_EXPIRES_IN) {\n throw new RangeError(\n `expiresIn must be an integer from 1 to ${MAX_PRESIGN_EXPIRES_IN} seconds; received ${String(value)}.`,\n )\n }\n return value\n}\n\nfunction formatSigningDate(input: S3PresignDate | undefined): {\n readonly shortDate: string\n readonly longDate: string\n} {\n const date = input === undefined ? new Date() : new Date(input)\n if (!Number.isFinite(date.getTime())) {\n throw new RangeError('signingDate must be a valid Date or timestamp.')\n }\n\n const year = String(date.getUTCFullYear()).padStart(4, '0')\n const month = String(date.getUTCMonth() + 1).padStart(2, '0')\n const day = String(date.getUTCDate()).padStart(2, '0')\n const hour = String(date.getUTCHours()).padStart(2, '0')\n const minute = String(date.getUTCMinutes()).padStart(2, '0')\n const second = String(date.getUTCSeconds()).padStart(2, '0')\n const shortDate = `${year}${month}${day}`\n return {\n shortDate,\n longDate: `${shortDate}T${hour}${minute}${second}Z`,\n }\n}\n\nfunction buildCanonicalUri(endpointPath: string, bucketName: string, fileName: string): string {\n const basePath =\n endpointPath === '' || endpointPath === '/' ? '' : endpointPath.replace(/\\/+$/, '')\n return `${basePath}/${awsPercentEncode(bucketName)}/${encodePath(fileName)}`\n}\n\nfunction canonicalHostHeader(endpoint: URL): string {\n const host = endpoint.host\n if (endpoint.protocol === 'https:' && host.endsWith(':443')) {\n return host.slice(0, -4)\n }\n return host\n}\n\nfunction parseEndpoint(endpoint: string): URL {\n try {\n return new URL(endpoint)\n } catch (cause) {\n throw new TypeError(\n `S3 presigned URL endpoint must be a valid URL; received \"${redactUrlForError(endpoint, {\n invalidUrlLabel: '<invalid S3 endpoint URL>',\n })}\".`,\n { cause },\n )\n }\n}\n\nfunction assertHttpsEndpoint(endpoint: URL): void {\n if (endpoint.protocol !== 'https:') {\n throw new TypeError(\n `S3 presigned URLs require an https: endpoint; received \"${redactUrlForError(endpoint)}\".`,\n )\n }\n}\n\nfunction encodePath(path: string): string {\n return path.split('/').map(awsPercentEncode).join('/')\n}\n\nfunction canonicalQueryString(query: readonly QueryParam[]): string {\n return query\n .map(([name, value]) => [awsPercentEncode(name), awsPercentEncode(value)] as const)\n .sort(([aName, aValue], [bName, bValue]) => {\n if (aName < bName) return -1\n if (aName > bName) return 1\n if (aValue < bValue) return -1\n if (aValue > bValue) return 1\n return 0\n })\n .map(([name, value]) => `${name}=${value}`)\n .join('&')\n}\n\n/**\n * Percent-encode according to AWS SigV4 canonical request rules.\n *\n * @param value - Raw value to encode.\n *\n * @returns AWS-compatible percent-encoded value.\n */\nfunction awsPercentEncode(value: string): string {\n return encodeURIComponent(value).replace(\n /[!'()*]/g,\n (char) => `%${char.charCodeAt(0).toString(16).toUpperCase()}`,\n )\n}\n\nfunction normalizeSignedHeaders(headers: readonly SignedHeader[]): SignedHeader[] {\n const combinedHeaders = new Map<string, string[]>()\n for (const [name, value] of headers) {\n const normalizedName = name.toLowerCase()\n const values = combinedHeaders.get(normalizedName)\n if (values) {\n values.push(normalizeHeaderValue(value))\n } else {\n combinedHeaders.set(normalizedName, [normalizeHeaderValue(value)])\n }\n }\n\n return [...combinedHeaders.entries()]\n .map(([name, values]) => [name, values.join(',')] as const)\n .sort(([a], [b]) => {\n if (a < b) return -1\n if (a > b) return 1\n return 0\n })\n}\n\nfunction normalizeHeaderValue(value: string): string {\n if (hasHttpHeaderControlCharacter(value)) {\n throw new TypeError('signed header values must not contain control characters.')\n }\n\n return value.trim().replace(/ +/g, ' ')\n}\n\nasync function deriveSigningKey(\n secretAccessKey: string,\n shortDate: string,\n region: string,\n): Promise<Uint8Array> {\n const dateKey = await hmacSha256(`AWS4${secretAccessKey}`, shortDate)\n const dateRegionKey = await hmacSha256(dateKey, region)\n const dateRegionServiceKey = await hmacSha256(dateRegionKey, SERVICE)\n return await hmacSha256(dateRegionServiceKey, TERMINATOR)\n}\n"],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /** Default S3 presigned URL validity duration in seconds. */
2
+ export declare const DEFAULT_PRESIGN_EXPIRES_IN = 3600;
3
+ /** Date input accepted by SigV4 presign internals and deterministic tests. */
4
+ export type S3PresignDate = Date | number;
5
+ /** Query parameter included in the SigV4 canonical query string. */
6
+ export type QueryParam = readonly [name: string, value: string];
7
+ /** HTTP header included in the SigV4 signed headers list. */
8
+ export type SignedHeader = readonly [name: string, value: string];
9
+ /** Internal inputs required to presign one S3-compatible object request. */
10
+ export interface SigV4PresignRequestOptions {
11
+ /** S3-compatible endpoint URL. */
12
+ readonly endpoint: string;
13
+ /** S3 signing region. */
14
+ readonly region: string;
15
+ /** S3 access key ID. */
16
+ readonly accessKeyId: string;
17
+ /** S3 secret access key. */
18
+ readonly secretAccessKey: string;
19
+ /** Bucket containing the object. */
20
+ readonly bucketName: string;
21
+ /** Object key / B2 file name. */
22
+ readonly fileName: string;
23
+ /** Optional URL validity duration in seconds. */
24
+ readonly expiresIn?: number;
25
+ /** Optional signing clock override. */
26
+ readonly signingDate?: S3PresignDate;
27
+ }
28
+ /**
29
+ * Generates an AWS Signature Version 4 presigned S3-compatible request URL.
30
+ *
31
+ * This module owns only canonical SigV4 mechanics: canonical URI/query/header
32
+ * construction, signing-key derivation, and signature encoding. Public B2 S3
33
+ * option validation and naming stay in `index.ts`.
34
+ *
35
+ * @param method - HTTP method to presign.
36
+ * @param options - S3 endpoint, credentials, object key, and signing options.
37
+ * @param extraQuery - Operation-specific query parameters to sign.
38
+ * @param extraHeaders - Operation-specific request headers to sign.
39
+ *
40
+ * @returns The presigned request URL.
41
+ */
42
+ export declare function presignS3Request(method: 'GET' | 'PUT', options: SigV4PresignRequestOptions, extraQuery: readonly QueryParam[], extraHeaders: readonly SignedHeader[]): Promise<string>;
43
+ //# sourceMappingURL=sigv4.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sigv4.d.ts","sourceRoot":"","sources":["../../src/s3/sigv4.js"],"names":[],"mappings":"AASA,6DAA6D;AAC7D,eAAO,MAAM,0BAA0B,OAAO,CAAA;AAE9C,8EAA8E;AAC9E,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,MAAM,CAAA;AAEzC,oEAAoE;AACpE,MAAM,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;AAE/D,6DAA6D;AAC7D,MAAM,MAAM,YAAY,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;AAEjE,4EAA4E;AAC5E,MAAM,WAAW,0BAA0B;IACzC,kCAAkC;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,yBAAyB;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,wBAAwB;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,4BAA4B;IAC5B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,oCAAoC;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,iCAAiC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,iDAAiD;IACjD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,uCAAuC;IACvC,QAAQ,CAAC,WAAW,CAAC,EAAE,aAAa,CAAA;CACrC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,KAAK,GAAG,KAAK,EACrB,OAAO,EAAE,0BAA0B,EACnC,UAAU,EAAE,SAAS,UAAU,EAAE,EACjC,YAAY,EAAE,SAAS,YAAY,EAAE,GACpC,OAAO,CAAC,MAAM,CAAC,CA2CjB"}
@@ -0,0 +1,43 @@
1
+ /** Default S3 presigned URL validity duration in seconds. */
2
+ export declare const DEFAULT_PRESIGN_EXPIRES_IN = 3600;
3
+ /** Date input accepted by SigV4 presign internals and deterministic tests. */
4
+ export type S3PresignDate = Date | number;
5
+ /** Query parameter included in the SigV4 canonical query string. */
6
+ export type QueryParam = readonly [name: string, value: string];
7
+ /** HTTP header included in the SigV4 signed headers list. */
8
+ export type SignedHeader = readonly [name: string, value: string];
9
+ /** Internal inputs required to presign one S3-compatible object request. */
10
+ export interface SigV4PresignRequestOptions {
11
+ /** S3-compatible endpoint URL. */
12
+ readonly endpoint: string;
13
+ /** S3 signing region. */
14
+ readonly region: string;
15
+ /** S3 access key ID. */
16
+ readonly accessKeyId: string;
17
+ /** S3 secret access key. */
18
+ readonly secretAccessKey: string;
19
+ /** Bucket containing the object. */
20
+ readonly bucketName: string;
21
+ /** Object key / B2 file name. */
22
+ readonly fileName: string;
23
+ /** Optional URL validity duration in seconds. */
24
+ readonly expiresIn?: number;
25
+ /** Optional signing clock override. */
26
+ readonly signingDate?: S3PresignDate;
27
+ }
28
+ /**
29
+ * Generates an AWS Signature Version 4 presigned S3-compatible request URL.
30
+ *
31
+ * This module owns only canonical SigV4 mechanics: canonical URI/query/header
32
+ * construction, signing-key derivation, and signature encoding. Public B2 S3
33
+ * option validation and naming stay in `index.ts`.
34
+ *
35
+ * @param method - HTTP method to presign.
36
+ * @param options - S3 endpoint, credentials, object key, and signing options.
37
+ * @param extraQuery - Operation-specific query parameters to sign.
38
+ * @param extraHeaders - Operation-specific request headers to sign.
39
+ *
40
+ * @returns The presigned request URL.
41
+ */
42
+ export declare function presignS3Request(method: 'GET' | 'PUT', options: SigV4PresignRequestOptions, extraQuery: readonly QueryParam[], extraHeaders: readonly SignedHeader[]): Promise<string>;
43
+ //# sourceMappingURL=sigv4.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sigv4.d.ts","sourceRoot":"","sources":["../../src/s3/sigv4.js"],"names":[],"mappings":"AASA,6DAA6D;AAC7D,eAAO,MAAM,0BAA0B,OAAO,CAAA;AAE9C,8EAA8E;AAC9E,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,MAAM,CAAA;AAEzC,oEAAoE;AACpE,MAAM,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;AAE/D,6DAA6D;AAC7D,MAAM,MAAM,YAAY,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;AAEjE,4EAA4E;AAC5E,MAAM,WAAW,0BAA0B;IACzC,kCAAkC;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,yBAAyB;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,wBAAwB;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,4BAA4B;IAC5B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,oCAAoC;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,iCAAiC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,iDAAiD;IACjD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,uCAAuC;IACvC,QAAQ,CAAC,WAAW,CAAC,EAAE,aAAa,CAAA;CACrC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,KAAK,GAAG,KAAK,EACrB,OAAO,EAAE,0BAA0B,EACnC,UAAU,EAAE,SAAS,UAAU,EAAE,EACjC,YAAY,EAAE,SAAS,YAAY,EAAE,GACpC,OAAO,CAAC,MAAM,CAAC,CA2CjB"}
@@ -0,0 +1,148 @@
1
+ import { redactUrlForError } from "../internal/url-redaction.js";
2
+ import { hexEncode, hmacSha256, sha256Hex } from "../util/crypto.js";
3
+ import { hasHttpHeaderControlCharacter } from "../util/http.js";
4
+ import { assertSafeBucketName, assertValidB2FileName } from "./validation.js";
5
+ //#region src/s3/sigv4.ts
6
+ var MAX_PRESIGN_EXPIRES_IN = 604800;
7
+ var UNSIGNED_PAYLOAD = "UNSIGNED-PAYLOAD";
8
+ var SERVICE = "s3";
9
+ var TERMINATOR = "aws4_request";
10
+ /** Default S3 presigned URL validity duration in seconds. */
11
+ var DEFAULT_PRESIGN_EXPIRES_IN = 3600;
12
+ /**
13
+ * Generates an AWS Signature Version 4 presigned S3-compatible request URL.
14
+ *
15
+ * This module owns only canonical SigV4 mechanics: canonical URI/query/header
16
+ * construction, signing-key derivation, and signature encoding. Public B2 S3
17
+ * option validation and naming stay in `index.ts`.
18
+ *
19
+ * @param method - HTTP method to presign.
20
+ * @param options - S3 endpoint, credentials, object key, and signing options.
21
+ * @param extraQuery - Operation-specific query parameters to sign.
22
+ * @param extraHeaders - Operation-specific request headers to sign.
23
+ *
24
+ * @returns The presigned request URL.
25
+ */
26
+ async function presignS3Request(method, options, extraQuery, extraHeaders) {
27
+ const endpoint = parseEndpoint(options.endpoint);
28
+ assertHttpsEndpoint(endpoint);
29
+ const expiresIn = normalizeExpiresIn(options.expiresIn);
30
+ const { shortDate, longDate } = formatSigningDate(options.signingDate);
31
+ const credentialScope = `${shortDate}/${options.region}/${SERVICE}/${TERMINATOR}`;
32
+ const credential = `${options.accessKeyId}/${credentialScope}`;
33
+ assertSafeBucketName(options.bucketName);
34
+ assertValidB2FileName(options.fileName);
35
+ const canonicalUri = buildCanonicalUri(endpoint.pathname, options.bucketName, options.fileName);
36
+ const headers = normalizeSignedHeaders([["host", canonicalHostHeader(endpoint)], ...extraHeaders]);
37
+ const signedHeaders = headers.map(([name]) => name).join(";");
38
+ const query = [
39
+ ["X-Amz-Algorithm", "AWS4-HMAC-SHA256"],
40
+ ["X-Amz-Credential", credential],
41
+ ["X-Amz-Content-Sha256", UNSIGNED_PAYLOAD],
42
+ ["X-Amz-Date", longDate],
43
+ ["X-Amz-Expires", String(expiresIn)],
44
+ ["X-Amz-SignedHeaders", signedHeaders],
45
+ ...extraQuery
46
+ ];
47
+ const stringToSign = [
48
+ "AWS4-HMAC-SHA256",
49
+ longDate,
50
+ credentialScope,
51
+ await sha256Hex([
52
+ method,
53
+ canonicalUri,
54
+ canonicalQueryString(query),
55
+ headers.map(([name, value]) => `${name}:${value}\n`).join(""),
56
+ signedHeaders,
57
+ UNSIGNED_PAYLOAD
58
+ ].join("\n"))
59
+ ].join("\n");
60
+ const signature = hexEncode(await hmacSha256(await deriveSigningKey(options.secretAccessKey, shortDate, options.region), stringToSign));
61
+ const finalQuery = canonicalQueryString([...query, ["X-Amz-Signature", signature]]);
62
+ return `${endpoint.origin}${canonicalUri}?${finalQuery}`;
63
+ }
64
+ function normalizeExpiresIn(expiresIn) {
65
+ const value = expiresIn ?? 3600;
66
+ if (!Number.isInteger(value) || value < 1 || value > MAX_PRESIGN_EXPIRES_IN) throw new RangeError(`expiresIn must be an integer from 1 to ${MAX_PRESIGN_EXPIRES_IN} seconds; received ${String(value)}.`);
67
+ return value;
68
+ }
69
+ function formatSigningDate(input) {
70
+ const date = input === void 0 ? /* @__PURE__ */ new Date() : new Date(input);
71
+ if (!Number.isFinite(date.getTime())) throw new RangeError("signingDate must be a valid Date or timestamp.");
72
+ const year = String(date.getUTCFullYear()).padStart(4, "0");
73
+ const month = String(date.getUTCMonth() + 1).padStart(2, "0");
74
+ const day = String(date.getUTCDate()).padStart(2, "0");
75
+ const hour = String(date.getUTCHours()).padStart(2, "0");
76
+ const minute = String(date.getUTCMinutes()).padStart(2, "0");
77
+ const second = String(date.getUTCSeconds()).padStart(2, "0");
78
+ const shortDate = `${year}${month}${day}`;
79
+ return {
80
+ shortDate,
81
+ longDate: `${shortDate}T${hour}${minute}${second}Z`
82
+ };
83
+ }
84
+ function buildCanonicalUri(endpointPath, bucketName, fileName) {
85
+ return `${endpointPath === "" || endpointPath === "/" ? "" : endpointPath.replace(/\/+$/, "")}/${awsPercentEncode(bucketName)}/${encodePath(fileName)}`;
86
+ }
87
+ function canonicalHostHeader(endpoint) {
88
+ const host = endpoint.host;
89
+ if (endpoint.protocol === "https:" && host.endsWith(":443")) return host.slice(0, -4);
90
+ return host;
91
+ }
92
+ function parseEndpoint(endpoint) {
93
+ try {
94
+ return new URL(endpoint);
95
+ } catch (cause) {
96
+ throw new TypeError(`S3 presigned URL endpoint must be a valid URL; received "${redactUrlForError(endpoint, { invalidUrlLabel: "<invalid S3 endpoint URL>" })}".`, { cause });
97
+ }
98
+ }
99
+ function assertHttpsEndpoint(endpoint) {
100
+ if (endpoint.protocol !== "https:") throw new TypeError(`S3 presigned URLs require an https: endpoint; received "${redactUrlForError(endpoint)}".`);
101
+ }
102
+ function encodePath(path) {
103
+ return path.split("/").map(awsPercentEncode).join("/");
104
+ }
105
+ function canonicalQueryString(query) {
106
+ return query.map(([name, value]) => [awsPercentEncode(name), awsPercentEncode(value)]).sort(([aName, aValue], [bName, bValue]) => {
107
+ if (aName < bName) return -1;
108
+ if (aName > bName) return 1;
109
+ if (aValue < bValue) return -1;
110
+ if (aValue > bValue) return 1;
111
+ return 0;
112
+ }).map(([name, value]) => `${name}=${value}`).join("&");
113
+ }
114
+ /**
115
+ * Percent-encode according to AWS SigV4 canonical request rules.
116
+ *
117
+ * @param value - Raw value to encode.
118
+ *
119
+ * @returns AWS-compatible percent-encoded value.
120
+ */
121
+ function awsPercentEncode(value) {
122
+ return encodeURIComponent(value).replace(/[!'()*]/g, (char) => `%${char.charCodeAt(0).toString(16).toUpperCase()}`);
123
+ }
124
+ function normalizeSignedHeaders(headers) {
125
+ const combinedHeaders = /* @__PURE__ */ new Map();
126
+ for (const [name, value] of headers) {
127
+ const normalizedName = name.toLowerCase();
128
+ const values = combinedHeaders.get(normalizedName);
129
+ if (values) values.push(normalizeHeaderValue(value));
130
+ else combinedHeaders.set(normalizedName, [normalizeHeaderValue(value)]);
131
+ }
132
+ return [...combinedHeaders.entries()].map(([name, values]) => [name, values.join(",")]).sort(([a], [b]) => {
133
+ if (a < b) return -1;
134
+ if (a > b) return 1;
135
+ return 0;
136
+ });
137
+ }
138
+ function normalizeHeaderValue(value) {
139
+ if (hasHttpHeaderControlCharacter(value)) throw new TypeError("signed header values must not contain control characters.");
140
+ return value.trim().replace(/ +/g, " ");
141
+ }
142
+ async function deriveSigningKey(secretAccessKey, shortDate, region) {
143
+ return await hmacSha256(await hmacSha256(await hmacSha256(await hmacSha256(`AWS4${secretAccessKey}`, shortDate), region), SERVICE), TERMINATOR);
144
+ }
145
+ //#endregion
146
+ export { DEFAULT_PRESIGN_EXPIRES_IN, presignS3Request };
147
+
148
+ //# sourceMappingURL=sigv4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sigv4.js","names":[],"sources":["../../src/s3/sigv4.ts"],"sourcesContent":["import { redactUrlForError } from '../internal/url-redaction.ts'\nimport { hexEncode, hmacSha256, sha256Hex } from '../util/crypto.ts'\nimport { hasHttpHeaderControlCharacter } from '../util/http.ts'\nimport { assertSafeBucketName, assertValidB2FileName } from './validation.ts'\n\nconst MAX_PRESIGN_EXPIRES_IN = 604_800\nconst UNSIGNED_PAYLOAD = 'UNSIGNED-PAYLOAD'\nconst SERVICE = 's3'\nconst TERMINATOR = 'aws4_request'\n/** Default S3 presigned URL validity duration in seconds. */\nexport const DEFAULT_PRESIGN_EXPIRES_IN = 3600\n\n/** Date input accepted by SigV4 presign internals and deterministic tests. */\nexport type S3PresignDate = Date | number\n\n/** Query parameter included in the SigV4 canonical query string. */\nexport type QueryParam = readonly [name: string, value: string]\n\n/** HTTP header included in the SigV4 signed headers list. */\nexport type SignedHeader = readonly [name: string, value: string]\n\n/** Internal inputs required to presign one S3-compatible object request. */\nexport interface SigV4PresignRequestOptions {\n /** S3-compatible endpoint URL. */\n readonly endpoint: string\n /** S3 signing region. */\n readonly region: string\n /** S3 access key ID. */\n readonly accessKeyId: string\n /** S3 secret access key. */\n readonly secretAccessKey: string\n /** Bucket containing the object. */\n readonly bucketName: string\n /** Object key / B2 file name. */\n readonly fileName: string\n /** Optional URL validity duration in seconds. */\n readonly expiresIn?: number\n /** Optional signing clock override. */\n readonly signingDate?: S3PresignDate\n}\n\n/**\n * Generates an AWS Signature Version 4 presigned S3-compatible request URL.\n *\n * This module owns only canonical SigV4 mechanics: canonical URI/query/header\n * construction, signing-key derivation, and signature encoding. Public B2 S3\n * option validation and naming stay in `index.ts`.\n *\n * @param method - HTTP method to presign.\n * @param options - S3 endpoint, credentials, object key, and signing options.\n * @param extraQuery - Operation-specific query parameters to sign.\n * @param extraHeaders - Operation-specific request headers to sign.\n *\n * @returns The presigned request URL.\n */\nexport async function presignS3Request(\n method: 'GET' | 'PUT',\n options: SigV4PresignRequestOptions,\n extraQuery: readonly QueryParam[],\n extraHeaders: readonly SignedHeader[],\n): Promise<string> {\n const endpoint = parseEndpoint(options.endpoint)\n assertHttpsEndpoint(endpoint)\n const expiresIn = normalizeExpiresIn(options.expiresIn)\n const { shortDate, longDate } = formatSigningDate(options.signingDate)\n const credentialScope = `${shortDate}/${options.region}/${SERVICE}/${TERMINATOR}`\n const credential = `${options.accessKeyId}/${credentialScope}`\n assertSafeBucketName(options.bucketName)\n assertValidB2FileName(options.fileName)\n const canonicalUri = buildCanonicalUri(endpoint.pathname, options.bucketName, options.fileName)\n const headers = normalizeSignedHeaders([['host', canonicalHostHeader(endpoint)], ...extraHeaders])\n const signedHeaders = headers.map(([name]) => name).join(';')\n\n const query: QueryParam[] = [\n ['X-Amz-Algorithm', 'AWS4-HMAC-SHA256'],\n ['X-Amz-Credential', credential],\n ['X-Amz-Content-Sha256', UNSIGNED_PAYLOAD],\n ['X-Amz-Date', longDate],\n ['X-Amz-Expires', String(expiresIn)],\n ['X-Amz-SignedHeaders', signedHeaders],\n ...extraQuery,\n ]\n const canonicalQuery = canonicalQueryString(query)\n const canonicalHeaders = headers.map(([name, value]) => `${name}:${value}\\n`).join('')\n const canonicalRequest = [\n method,\n canonicalUri,\n canonicalQuery,\n canonicalHeaders,\n signedHeaders,\n UNSIGNED_PAYLOAD,\n ].join('\\n')\n const stringToSign = [\n 'AWS4-HMAC-SHA256',\n longDate,\n credentialScope,\n await sha256Hex(canonicalRequest),\n ].join('\\n')\n const signingKey = await deriveSigningKey(options.secretAccessKey, shortDate, options.region)\n const signature = hexEncode(await hmacSha256(signingKey, stringToSign))\n const finalQuery = canonicalQueryString([...query, ['X-Amz-Signature', signature]])\n\n return `${endpoint.origin}${canonicalUri}?${finalQuery}`\n}\n\nfunction normalizeExpiresIn(expiresIn: number | undefined): number {\n const value = expiresIn ?? DEFAULT_PRESIGN_EXPIRES_IN\n if (!Number.isInteger(value) || value < 1 || value > MAX_PRESIGN_EXPIRES_IN) {\n throw new RangeError(\n `expiresIn must be an integer from 1 to ${MAX_PRESIGN_EXPIRES_IN} seconds; received ${String(value)}.`,\n )\n }\n return value\n}\n\nfunction formatSigningDate(input: S3PresignDate | undefined): {\n readonly shortDate: string\n readonly longDate: string\n} {\n const date = input === undefined ? new Date() : new Date(input)\n if (!Number.isFinite(date.getTime())) {\n throw new RangeError('signingDate must be a valid Date or timestamp.')\n }\n\n const year = String(date.getUTCFullYear()).padStart(4, '0')\n const month = String(date.getUTCMonth() + 1).padStart(2, '0')\n const day = String(date.getUTCDate()).padStart(2, '0')\n const hour = String(date.getUTCHours()).padStart(2, '0')\n const minute = String(date.getUTCMinutes()).padStart(2, '0')\n const second = String(date.getUTCSeconds()).padStart(2, '0')\n const shortDate = `${year}${month}${day}`\n return {\n shortDate,\n longDate: `${shortDate}T${hour}${minute}${second}Z`,\n }\n}\n\nfunction buildCanonicalUri(endpointPath: string, bucketName: string, fileName: string): string {\n const basePath =\n endpointPath === '' || endpointPath === '/' ? '' : endpointPath.replace(/\\/+$/, '')\n return `${basePath}/${awsPercentEncode(bucketName)}/${encodePath(fileName)}`\n}\n\nfunction canonicalHostHeader(endpoint: URL): string {\n const host = endpoint.host\n if (endpoint.protocol === 'https:' && host.endsWith(':443')) {\n return host.slice(0, -4)\n }\n return host\n}\n\nfunction parseEndpoint(endpoint: string): URL {\n try {\n return new URL(endpoint)\n } catch (cause) {\n throw new TypeError(\n `S3 presigned URL endpoint must be a valid URL; received \"${redactUrlForError(endpoint, {\n invalidUrlLabel: '<invalid S3 endpoint URL>',\n })}\".`,\n { cause },\n )\n }\n}\n\nfunction assertHttpsEndpoint(endpoint: URL): void {\n if (endpoint.protocol !== 'https:') {\n throw new TypeError(\n `S3 presigned URLs require an https: endpoint; received \"${redactUrlForError(endpoint)}\".`,\n )\n }\n}\n\nfunction encodePath(path: string): string {\n return path.split('/').map(awsPercentEncode).join('/')\n}\n\nfunction canonicalQueryString(query: readonly QueryParam[]): string {\n return query\n .map(([name, value]) => [awsPercentEncode(name), awsPercentEncode(value)] as const)\n .sort(([aName, aValue], [bName, bValue]) => {\n if (aName < bName) return -1\n if (aName > bName) return 1\n if (aValue < bValue) return -1\n if (aValue > bValue) return 1\n return 0\n })\n .map(([name, value]) => `${name}=${value}`)\n .join('&')\n}\n\n/**\n * Percent-encode according to AWS SigV4 canonical request rules.\n *\n * @param value - Raw value to encode.\n *\n * @returns AWS-compatible percent-encoded value.\n */\nfunction awsPercentEncode(value: string): string {\n return encodeURIComponent(value).replace(\n /[!'()*]/g,\n (char) => `%${char.charCodeAt(0).toString(16).toUpperCase()}`,\n )\n}\n\nfunction normalizeSignedHeaders(headers: readonly SignedHeader[]): SignedHeader[] {\n const combinedHeaders = new Map<string, string[]>()\n for (const [name, value] of headers) {\n const normalizedName = name.toLowerCase()\n const values = combinedHeaders.get(normalizedName)\n if (values) {\n values.push(normalizeHeaderValue(value))\n } else {\n combinedHeaders.set(normalizedName, [normalizeHeaderValue(value)])\n }\n }\n\n return [...combinedHeaders.entries()]\n .map(([name, values]) => [name, values.join(',')] as const)\n .sort(([a], [b]) => {\n if (a < b) return -1\n if (a > b) return 1\n return 0\n })\n}\n\nfunction normalizeHeaderValue(value: string): string {\n if (hasHttpHeaderControlCharacter(value)) {\n throw new TypeError('signed header values must not contain control characters.')\n }\n\n return value.trim().replace(/ +/g, ' ')\n}\n\nasync function deriveSigningKey(\n secretAccessKey: string,\n shortDate: string,\n region: string,\n): Promise<Uint8Array> {\n const dateKey = await hmacSha256(`AWS4${secretAccessKey}`, shortDate)\n const dateRegionKey = await hmacSha256(dateKey, region)\n const dateRegionServiceKey = await hmacSha256(dateRegionKey, SERVICE)\n return await hmacSha256(dateRegionServiceKey, TERMINATOR)\n}\n"],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ const require_b2_naming = require("../internal/b2-naming.cjs");
2
+ //#region src/s3/validation.ts
3
+ /**
4
+ * Validate a B2 bucket name before signing or embedding it in a URL path.
5
+ *
6
+ * @param bucketName - Bucket name supplied by the caller.
7
+ *
8
+ * @throws TypeError when the bucket name is empty, contains control characters,
9
+ * is a dot-only path segment, contains path separators, or violates B2 bucket
10
+ * naming rules.
11
+ */
12
+ function assertSafeBucketName(bucketName) {
13
+ if (typeof bucketName !== "string" || bucketName.length === 0) throw new TypeError("bucketName must be a non-empty string.");
14
+ if (require_b2_naming.hasB2FileNameControlCharacter(bucketName)) throw new TypeError("bucketName must not contain control characters.");
15
+ if (bucketName === "." || bucketName === ".." || /[/\\]/.test(bucketName)) throw new TypeError("bucketName must not be \".\" or \"..\" and must not contain path separators.");
16
+ if (bucketName.length < 6 || bucketName.length > 63) throw new TypeError(`bucketName must be 6-63 characters.`);
17
+ if (require_b2_naming.isB2BucketNameIpv4Address(bucketName)) throw new TypeError("bucketName must not be formatted as an IPv4 address.");
18
+ if (!require_b2_naming.hasValidB2BucketNameShape(bucketName)) throw new TypeError("bucketName must contain only letters, digits, hyphens, and periods, cannot start or end with punctuation, and cannot contain consecutive periods.");
19
+ if (bucketName.startsWith("b2-")) throw new TypeError(`bucketName cannot start with the reserved prefix "b2-".`);
20
+ }
21
+ /**
22
+ * Validate a B2-native download URL file name.
23
+ *
24
+ * Native download-authorization URLs use path-preserving B2 file-name encoding,
25
+ * so this stricter guard rejects slash boundary patterns that would make the
26
+ * URL path ambiguous in common clients.
27
+ *
28
+ * @param fileName - B2 file name supplied by the caller.
29
+ *
30
+ * @throws TypeError when the file name is not valid for the native download
31
+ * authorization URL path.
32
+ */
33
+ function assertNativeDownloadFileName(fileName) {
34
+ assertValidB2FileName(fileName);
35
+ if (fileName.startsWith("/") || fileName.endsWith("/") || fileName.includes("//")) throw new TypeError("fileName cannot start with \"/\", end with \"/\", or contain \"//\".");
36
+ }
37
+ /**
38
+ * Validate a B2 file name for URL signing safety.
39
+ *
40
+ * This is presign-safety validation, not full native B2 file-name validation.
41
+ * S3-compatible object keys may use leading, trailing, or repeated slash
42
+ * patterns that native B2 download URLs reject. Native download URLs apply the
43
+ * stricter {@link assertNativeDownloadFileName} path-boundary guard. This guard
44
+ * only enforces size, control-character, and dot-segment constraints needed
45
+ * before signing. Dot-only path segments are rejected because URL parsers can
46
+ * normalize them before the request is sent.
47
+ *
48
+ * @param fileName - B2 file name supplied by the caller.
49
+ *
50
+ * @throws TypeError when the file name is empty, too large, contains control
51
+ * characters, or contains dot-only path segments.
52
+ */
53
+ function assertValidB2FileName(fileName) {
54
+ assertB2FileNameCore(fileName);
55
+ if (fileName.split("/").some((segment) => segment === "." || segment === "..")) throw new TypeError("fileName must not contain dot-only path segments because URL parsers can normalize presigned paths.");
56
+ }
57
+ function assertB2FileNameCore(fileName) {
58
+ if (typeof fileName !== "string" || fileName.length === 0) throw new TypeError("fileName must be a non-empty string.");
59
+ if (fileName === "." || fileName === "..") throw new TypeError("fileName cannot be exactly \".\" or \"..\".");
60
+ if (require_b2_naming.getB2FileNameByteLength(fileName) === null) throw new TypeError(`fileName must be at most ${require_b2_naming.FILE_NAME_MAX_BYTES} UTF-8 bytes.`);
61
+ if (require_b2_naming.hasB2FileNameControlCharacter(fileName)) throw new TypeError("fileName must not contain control characters (U+0000-U+001F or U+007F).");
62
+ }
63
+ //#endregion
64
+ exports.FILE_NAME_MAX_BYTES = require_b2_naming.FILE_NAME_MAX_BYTES;
65
+ exports.assertNativeDownloadFileName = assertNativeDownloadFileName;
66
+ exports.assertSafeBucketName = assertSafeBucketName;
67
+ exports.assertValidB2FileName = assertValidB2FileName;
68
+
69
+ //# sourceMappingURL=validation.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.cjs","names":[],"sources":["../../src/s3/validation.ts"],"sourcesContent":["import {\n BUCKET_NAME_MAX,\n BUCKET_NAME_MIN,\n BUCKET_NAME_RESERVED_PREFIX,\n FILE_NAME_MAX_BYTES,\n getB2FileNameByteLength,\n hasB2FileNameControlCharacter,\n hasValidB2BucketNameShape,\n isB2BucketNameIpv4Address,\n} from '../internal/b2-naming.ts'\n\nexport { FILE_NAME_MAX_BYTES }\n\n/**\n * Validate a B2 bucket name before signing or embedding it in a URL path.\n *\n * @param bucketName - Bucket name supplied by the caller.\n *\n * @throws TypeError when the bucket name is empty, contains control characters,\n * is a dot-only path segment, contains path separators, or violates B2 bucket\n * naming rules.\n */\nexport function assertSafeBucketName(bucketName: string): void {\n if (typeof bucketName !== 'string' || bucketName.length === 0) {\n throw new TypeError('bucketName must be a non-empty string.')\n }\n if (hasB2FileNameControlCharacter(bucketName)) {\n throw new TypeError('bucketName must not contain control characters.')\n }\n if (bucketName === '.' || bucketName === '..' || /[/\\\\]/.test(bucketName)) {\n throw new TypeError('bucketName must not be \".\" or \"..\" and must not contain path separators.')\n }\n if (bucketName.length < BUCKET_NAME_MIN || bucketName.length > BUCKET_NAME_MAX) {\n throw new TypeError(`bucketName must be ${BUCKET_NAME_MIN}-${BUCKET_NAME_MAX} characters.`)\n }\n if (isB2BucketNameIpv4Address(bucketName)) {\n throw new TypeError('bucketName must not be formatted as an IPv4 address.')\n }\n if (!hasValidB2BucketNameShape(bucketName)) {\n throw new TypeError(\n 'bucketName must contain only letters, digits, hyphens, and periods, cannot start or end with punctuation, and cannot contain consecutive periods.',\n )\n }\n if (bucketName.startsWith(BUCKET_NAME_RESERVED_PREFIX)) {\n throw new TypeError(\n `bucketName cannot start with the reserved prefix \"${BUCKET_NAME_RESERVED_PREFIX}\".`,\n )\n }\n}\n\n/**\n * Validate a B2-native download URL file name.\n *\n * Native download-authorization URLs use path-preserving B2 file-name encoding,\n * so this stricter guard rejects slash boundary patterns that would make the\n * URL path ambiguous in common clients.\n *\n * @param fileName - B2 file name supplied by the caller.\n *\n * @throws TypeError when the file name is not valid for the native download\n * authorization URL path.\n */\nexport function assertNativeDownloadFileName(fileName: string): void {\n assertValidB2FileName(fileName)\n\n if (fileName.startsWith('/') || fileName.endsWith('/') || fileName.includes('//')) {\n throw new TypeError('fileName cannot start with \"/\", end with \"/\", or contain \"//\".')\n }\n}\n\n/**\n * Validate a B2 file name for URL signing safety.\n *\n * This is presign-safety validation, not full native B2 file-name validation.\n * S3-compatible object keys may use leading, trailing, or repeated slash\n * patterns that native B2 download URLs reject. Native download URLs apply the\n * stricter {@link assertNativeDownloadFileName} path-boundary guard. This guard\n * only enforces size, control-character, and dot-segment constraints needed\n * before signing. Dot-only path segments are rejected because URL parsers can\n * normalize them before the request is sent.\n *\n * @param fileName - B2 file name supplied by the caller.\n *\n * @throws TypeError when the file name is empty, too large, contains control\n * characters, or contains dot-only path segments.\n */\nexport function assertValidB2FileName(fileName: string): void {\n assertB2FileNameCore(fileName)\n\n if (fileName.split('/').some((segment) => segment === '.' || segment === '..')) {\n throw new TypeError(\n 'fileName must not contain dot-only path segments because URL parsers can normalize presigned paths.',\n )\n }\n}\n\nfunction assertB2FileNameCore(fileName: string): void {\n if (typeof fileName !== 'string' || fileName.length === 0) {\n throw new TypeError('fileName must be a non-empty string.')\n }\n\n if (fileName === '.' || fileName === '..') {\n throw new TypeError('fileName cannot be exactly \".\" or \"..\".')\n }\n\n const byteLength = getB2FileNameByteLength(fileName)\n if (byteLength === null) {\n throw new TypeError(`fileName must be at most ${FILE_NAME_MAX_BYTES} UTF-8 bytes.`)\n }\n\n if (hasB2FileNameControlCharacter(fileName)) {\n throw new TypeError('fileName must not contain control characters (U+0000-U+001F or U+007F).')\n }\n}\n"],"mappings":";;;;;;;;;;;AAsBA,SAAgB,qBAAqB,YAA0B;CAC7D,IAAI,OAAO,eAAe,YAAY,WAAW,WAAW,GAC1D,MAAM,IAAI,UAAU,wCAAwC;CAE9D,IAAI,kBAAA,8BAA8B,UAAU,GAC1C,MAAM,IAAI,UAAU,iDAAiD;CAEvE,IAAI,eAAe,OAAO,eAAe,QAAQ,QAAQ,KAAK,UAAU,GACtE,MAAM,IAAI,UAAU,8EAA0E;CAEhG,IAAI,WAAW,SAAA,KAA4B,WAAW,SAAA,IACpD,MAAM,IAAI,UAAU,qCAAsE;CAE5F,IAAI,kBAAA,0BAA0B,UAAU,GACtC,MAAM,IAAI,UAAU,sDAAsD;CAE5E,IAAI,CAAC,kBAAA,0BAA0B,UAAU,GACvC,MAAM,IAAI,UACR,mJACF;CAEF,IAAI,WAAW,WAAA,KAAsC,GACnD,MAAM,IAAI,UACR,yDACF;AAEJ;;;;;;;;;;;;;AAcA,SAAgB,6BAA6B,UAAwB;CACnE,sBAAsB,QAAQ;CAE9B,IAAI,SAAS,WAAW,GAAG,KAAK,SAAS,SAAS,GAAG,KAAK,SAAS,SAAS,IAAI,GAC9E,MAAM,IAAI,UAAU,sEAAgE;AAExF;;;;;;;;;;;;;;;;;AAkBA,SAAgB,sBAAsB,UAAwB;CAC5D,qBAAqB,QAAQ;CAE7B,IAAI,SAAS,MAAM,GAAG,CAAC,CAAC,MAAM,YAAY,YAAY,OAAO,YAAY,IAAI,GAC3E,MAAM,IAAI,UACR,qGACF;AAEJ;AAEA,SAAS,qBAAqB,UAAwB;CACpD,IAAI,OAAO,aAAa,YAAY,SAAS,WAAW,GACtD,MAAM,IAAI,UAAU,sCAAsC;CAG5D,IAAI,aAAa,OAAO,aAAa,MACnC,MAAM,IAAI,UAAU,6CAAyC;CAI/D,IADmB,kBAAA,wBAAwB,QACvC,MAAe,MACjB,MAAM,IAAI,UAAU,4BAA4B,kBAAA,oBAAoB,cAAc;CAGpF,IAAI,kBAAA,8BAA8B,QAAQ,GACxC,MAAM,IAAI,UAAU,yEAAyE;AAEjG"}
@@ -0,0 +1,43 @@
1
+ import { FILE_NAME_MAX_BYTES } from '../internal/b2-naming.js';
2
+ export { FILE_NAME_MAX_BYTES };
3
+ /**
4
+ * Validate a B2 bucket name before signing or embedding it in a URL path.
5
+ *
6
+ * @param bucketName - Bucket name supplied by the caller.
7
+ *
8
+ * @throws TypeError when the bucket name is empty, contains control characters,
9
+ * is a dot-only path segment, contains path separators, or violates B2 bucket
10
+ * naming rules.
11
+ */
12
+ export declare function assertSafeBucketName(bucketName: string): void;
13
+ /**
14
+ * Validate a B2-native download URL file name.
15
+ *
16
+ * Native download-authorization URLs use path-preserving B2 file-name encoding,
17
+ * so this stricter guard rejects slash boundary patterns that would make the
18
+ * URL path ambiguous in common clients.
19
+ *
20
+ * @param fileName - B2 file name supplied by the caller.
21
+ *
22
+ * @throws TypeError when the file name is not valid for the native download
23
+ * authorization URL path.
24
+ */
25
+ export declare function assertNativeDownloadFileName(fileName: string): void;
26
+ /**
27
+ * Validate a B2 file name for URL signing safety.
28
+ *
29
+ * This is presign-safety validation, not full native B2 file-name validation.
30
+ * S3-compatible object keys may use leading, trailing, or repeated slash
31
+ * patterns that native B2 download URLs reject. Native download URLs apply the
32
+ * stricter {@link assertNativeDownloadFileName} path-boundary guard. This guard
33
+ * only enforces size, control-character, and dot-segment constraints needed
34
+ * before signing. Dot-only path segments are rejected because URL parsers can
35
+ * normalize them before the request is sent.
36
+ *
37
+ * @param fileName - B2 file name supplied by the caller.
38
+ *
39
+ * @throws TypeError when the file name is empty, too large, contains control
40
+ * characters, or contains dot-only path segments.
41
+ */
42
+ export declare function assertValidB2FileName(fileName: string): void;
43
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/s3/validation.js"],"names":[],"mappings":"AAAA,OAAO,EAIL,mBAAmB,EAKpB,MAAM,0BAA0B,CAAA;AAEjC,OAAO,EAAE,mBAAmB,EAAE,CAAA;AAE9B;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CA0B7D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAMnE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAQ5D"}
@@ -0,0 +1,43 @@
1
+ import { FILE_NAME_MAX_BYTES } from '../internal/b2-naming.js';
2
+ export { FILE_NAME_MAX_BYTES };
3
+ /**
4
+ * Validate a B2 bucket name before signing or embedding it in a URL path.
5
+ *
6
+ * @param bucketName - Bucket name supplied by the caller.
7
+ *
8
+ * @throws TypeError when the bucket name is empty, contains control characters,
9
+ * is a dot-only path segment, contains path separators, or violates B2 bucket
10
+ * naming rules.
11
+ */
12
+ export declare function assertSafeBucketName(bucketName: string): void;
13
+ /**
14
+ * Validate a B2-native download URL file name.
15
+ *
16
+ * Native download-authorization URLs use path-preserving B2 file-name encoding,
17
+ * so this stricter guard rejects slash boundary patterns that would make the
18
+ * URL path ambiguous in common clients.
19
+ *
20
+ * @param fileName - B2 file name supplied by the caller.
21
+ *
22
+ * @throws TypeError when the file name is not valid for the native download
23
+ * authorization URL path.
24
+ */
25
+ export declare function assertNativeDownloadFileName(fileName: string): void;
26
+ /**
27
+ * Validate a B2 file name for URL signing safety.
28
+ *
29
+ * This is presign-safety validation, not full native B2 file-name validation.
30
+ * S3-compatible object keys may use leading, trailing, or repeated slash
31
+ * patterns that native B2 download URLs reject. Native download URLs apply the
32
+ * stricter {@link assertNativeDownloadFileName} path-boundary guard. This guard
33
+ * only enforces size, control-character, and dot-segment constraints needed
34
+ * before signing. Dot-only path segments are rejected because URL parsers can
35
+ * normalize them before the request is sent.
36
+ *
37
+ * @param fileName - B2 file name supplied by the caller.
38
+ *
39
+ * @throws TypeError when the file name is empty, too large, contains control
40
+ * characters, or contains dot-only path segments.
41
+ */
42
+ export declare function assertValidB2FileName(fileName: string): void;
43
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/s3/validation.js"],"names":[],"mappings":"AAAA,OAAO,EAIL,mBAAmB,EAKpB,MAAM,0BAA0B,CAAA;AAEjC,OAAO,EAAE,mBAAmB,EAAE,CAAA;AAE9B;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CA0B7D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAMnE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAQ5D"}
@@ -0,0 +1,66 @@
1
+ import { FILE_NAME_MAX_BYTES, getB2FileNameByteLength, hasB2FileNameControlCharacter, hasValidB2BucketNameShape, isB2BucketNameIpv4Address } from "../internal/b2-naming.js";
2
+ //#region src/s3/validation.ts
3
+ /**
4
+ * Validate a B2 bucket name before signing or embedding it in a URL path.
5
+ *
6
+ * @param bucketName - Bucket name supplied by the caller.
7
+ *
8
+ * @throws TypeError when the bucket name is empty, contains control characters,
9
+ * is a dot-only path segment, contains path separators, or violates B2 bucket
10
+ * naming rules.
11
+ */
12
+ function assertSafeBucketName(bucketName) {
13
+ if (typeof bucketName !== "string" || bucketName.length === 0) throw new TypeError("bucketName must be a non-empty string.");
14
+ if (hasB2FileNameControlCharacter(bucketName)) throw new TypeError("bucketName must not contain control characters.");
15
+ if (bucketName === "." || bucketName === ".." || /[/\\]/.test(bucketName)) throw new TypeError("bucketName must not be \".\" or \"..\" and must not contain path separators.");
16
+ if (bucketName.length < 6 || bucketName.length > 63) throw new TypeError(`bucketName must be 6-63 characters.`);
17
+ if (isB2BucketNameIpv4Address(bucketName)) throw new TypeError("bucketName must not be formatted as an IPv4 address.");
18
+ if (!hasValidB2BucketNameShape(bucketName)) throw new TypeError("bucketName must contain only letters, digits, hyphens, and periods, cannot start or end with punctuation, and cannot contain consecutive periods.");
19
+ if (bucketName.startsWith("b2-")) throw new TypeError(`bucketName cannot start with the reserved prefix "b2-".`);
20
+ }
21
+ /**
22
+ * Validate a B2-native download URL file name.
23
+ *
24
+ * Native download-authorization URLs use path-preserving B2 file-name encoding,
25
+ * so this stricter guard rejects slash boundary patterns that would make the
26
+ * URL path ambiguous in common clients.
27
+ *
28
+ * @param fileName - B2 file name supplied by the caller.
29
+ *
30
+ * @throws TypeError when the file name is not valid for the native download
31
+ * authorization URL path.
32
+ */
33
+ function assertNativeDownloadFileName(fileName) {
34
+ assertValidB2FileName(fileName);
35
+ if (fileName.startsWith("/") || fileName.endsWith("/") || fileName.includes("//")) throw new TypeError("fileName cannot start with \"/\", end with \"/\", or contain \"//\".");
36
+ }
37
+ /**
38
+ * Validate a B2 file name for URL signing safety.
39
+ *
40
+ * This is presign-safety validation, not full native B2 file-name validation.
41
+ * S3-compatible object keys may use leading, trailing, or repeated slash
42
+ * patterns that native B2 download URLs reject. Native download URLs apply the
43
+ * stricter {@link assertNativeDownloadFileName} path-boundary guard. This guard
44
+ * only enforces size, control-character, and dot-segment constraints needed
45
+ * before signing. Dot-only path segments are rejected because URL parsers can
46
+ * normalize them before the request is sent.
47
+ *
48
+ * @param fileName - B2 file name supplied by the caller.
49
+ *
50
+ * @throws TypeError when the file name is empty, too large, contains control
51
+ * characters, or contains dot-only path segments.
52
+ */
53
+ function assertValidB2FileName(fileName) {
54
+ assertB2FileNameCore(fileName);
55
+ if (fileName.split("/").some((segment) => segment === "." || segment === "..")) throw new TypeError("fileName must not contain dot-only path segments because URL parsers can normalize presigned paths.");
56
+ }
57
+ function assertB2FileNameCore(fileName) {
58
+ if (typeof fileName !== "string" || fileName.length === 0) throw new TypeError("fileName must be a non-empty string.");
59
+ if (fileName === "." || fileName === "..") throw new TypeError("fileName cannot be exactly \".\" or \"..\".");
60
+ if (getB2FileNameByteLength(fileName) === null) throw new TypeError(`fileName must be at most ${FILE_NAME_MAX_BYTES} UTF-8 bytes.`);
61
+ if (hasB2FileNameControlCharacter(fileName)) throw new TypeError("fileName must not contain control characters (U+0000-U+001F or U+007F).");
62
+ }
63
+ //#endregion
64
+ export { FILE_NAME_MAX_BYTES, assertNativeDownloadFileName, assertSafeBucketName, assertValidB2FileName };
65
+
66
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","names":[],"sources":["../../src/s3/validation.ts"],"sourcesContent":["import {\n BUCKET_NAME_MAX,\n BUCKET_NAME_MIN,\n BUCKET_NAME_RESERVED_PREFIX,\n FILE_NAME_MAX_BYTES,\n getB2FileNameByteLength,\n hasB2FileNameControlCharacter,\n hasValidB2BucketNameShape,\n isB2BucketNameIpv4Address,\n} from '../internal/b2-naming.ts'\n\nexport { FILE_NAME_MAX_BYTES }\n\n/**\n * Validate a B2 bucket name before signing or embedding it in a URL path.\n *\n * @param bucketName - Bucket name supplied by the caller.\n *\n * @throws TypeError when the bucket name is empty, contains control characters,\n * is a dot-only path segment, contains path separators, or violates B2 bucket\n * naming rules.\n */\nexport function assertSafeBucketName(bucketName: string): void {\n if (typeof bucketName !== 'string' || bucketName.length === 0) {\n throw new TypeError('bucketName must be a non-empty string.')\n }\n if (hasB2FileNameControlCharacter(bucketName)) {\n throw new TypeError('bucketName must not contain control characters.')\n }\n if (bucketName === '.' || bucketName === '..' || /[/\\\\]/.test(bucketName)) {\n throw new TypeError('bucketName must not be \".\" or \"..\" and must not contain path separators.')\n }\n if (bucketName.length < BUCKET_NAME_MIN || bucketName.length > BUCKET_NAME_MAX) {\n throw new TypeError(`bucketName must be ${BUCKET_NAME_MIN}-${BUCKET_NAME_MAX} characters.`)\n }\n if (isB2BucketNameIpv4Address(bucketName)) {\n throw new TypeError('bucketName must not be formatted as an IPv4 address.')\n }\n if (!hasValidB2BucketNameShape(bucketName)) {\n throw new TypeError(\n 'bucketName must contain only letters, digits, hyphens, and periods, cannot start or end with punctuation, and cannot contain consecutive periods.',\n )\n }\n if (bucketName.startsWith(BUCKET_NAME_RESERVED_PREFIX)) {\n throw new TypeError(\n `bucketName cannot start with the reserved prefix \"${BUCKET_NAME_RESERVED_PREFIX}\".`,\n )\n }\n}\n\n/**\n * Validate a B2-native download URL file name.\n *\n * Native download-authorization URLs use path-preserving B2 file-name encoding,\n * so this stricter guard rejects slash boundary patterns that would make the\n * URL path ambiguous in common clients.\n *\n * @param fileName - B2 file name supplied by the caller.\n *\n * @throws TypeError when the file name is not valid for the native download\n * authorization URL path.\n */\nexport function assertNativeDownloadFileName(fileName: string): void {\n assertValidB2FileName(fileName)\n\n if (fileName.startsWith('/') || fileName.endsWith('/') || fileName.includes('//')) {\n throw new TypeError('fileName cannot start with \"/\", end with \"/\", or contain \"//\".')\n }\n}\n\n/**\n * Validate a B2 file name for URL signing safety.\n *\n * This is presign-safety validation, not full native B2 file-name validation.\n * S3-compatible object keys may use leading, trailing, or repeated slash\n * patterns that native B2 download URLs reject. Native download URLs apply the\n * stricter {@link assertNativeDownloadFileName} path-boundary guard. This guard\n * only enforces size, control-character, and dot-segment constraints needed\n * before signing. Dot-only path segments are rejected because URL parsers can\n * normalize them before the request is sent.\n *\n * @param fileName - B2 file name supplied by the caller.\n *\n * @throws TypeError when the file name is empty, too large, contains control\n * characters, or contains dot-only path segments.\n */\nexport function assertValidB2FileName(fileName: string): void {\n assertB2FileNameCore(fileName)\n\n if (fileName.split('/').some((segment) => segment === '.' || segment === '..')) {\n throw new TypeError(\n 'fileName must not contain dot-only path segments because URL parsers can normalize presigned paths.',\n )\n }\n}\n\nfunction assertB2FileNameCore(fileName: string): void {\n if (typeof fileName !== 'string' || fileName.length === 0) {\n throw new TypeError('fileName must be a non-empty string.')\n }\n\n if (fileName === '.' || fileName === '..') {\n throw new TypeError('fileName cannot be exactly \".\" or \"..\".')\n }\n\n const byteLength = getB2FileNameByteLength(fileName)\n if (byteLength === null) {\n throw new TypeError(`fileName must be at most ${FILE_NAME_MAX_BYTES} UTF-8 bytes.`)\n }\n\n if (hasB2FileNameControlCharacter(fileName)) {\n throw new TypeError('fileName must not contain control characters (U+0000-U+001F or U+007F).')\n }\n}\n"],"mappings":";;;;;;;;;;;AAsBA,SAAgB,qBAAqB,YAA0B;CAC7D,IAAI,OAAO,eAAe,YAAY,WAAW,WAAW,GAC1D,MAAM,IAAI,UAAU,wCAAwC;CAE9D,IAAI,8BAA8B,UAAU,GAC1C,MAAM,IAAI,UAAU,iDAAiD;CAEvE,IAAI,eAAe,OAAO,eAAe,QAAQ,QAAQ,KAAK,UAAU,GACtE,MAAM,IAAI,UAAU,8EAA0E;CAEhG,IAAI,WAAW,SAAA,KAA4B,WAAW,SAAA,IACpD,MAAM,IAAI,UAAU,qCAAsE;CAE5F,IAAI,0BAA0B,UAAU,GACtC,MAAM,IAAI,UAAU,sDAAsD;CAE5E,IAAI,CAAC,0BAA0B,UAAU,GACvC,MAAM,IAAI,UACR,mJACF;CAEF,IAAI,WAAW,WAAA,KAAsC,GACnD,MAAM,IAAI,UACR,yDACF;AAEJ;;;;;;;;;;;;;AAcA,SAAgB,6BAA6B,UAAwB;CACnE,sBAAsB,QAAQ;CAE9B,IAAI,SAAS,WAAW,GAAG,KAAK,SAAS,SAAS,GAAG,KAAK,SAAS,SAAS,IAAI,GAC9E,MAAM,IAAI,UAAU,sEAAgE;AAExF;;;;;;;;;;;;;;;;;AAkBA,SAAgB,sBAAsB,UAAwB;CAC5D,qBAAqB,QAAQ;CAE7B,IAAI,SAAS,MAAM,GAAG,CAAC,CAAC,MAAM,YAAY,YAAY,OAAO,YAAY,IAAI,GAC3E,MAAM,IAAI,UACR,qGACF;AAEJ;AAEA,SAAS,qBAAqB,UAAwB;CACpD,IAAI,OAAO,aAAa,YAAY,SAAS,WAAW,GACtD,MAAM,IAAI,UAAU,sCAAsC;CAG5D,IAAI,aAAa,OAAO,aAAa,MACnC,MAAM,IAAI,UAAU,6CAAyC;CAI/D,IADmB,wBAAwB,QACvC,MAAe,MACjB,MAAM,IAAI,UAAU,4BAA4B,oBAAoB,cAAc;CAGpF,IAAI,8BAA8B,QAAQ,GACxC,MAAM,IAAI,UAAU,yEAAyE;AAEjG"}