@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
@@ -1,97 +1,159 @@
1
1
  import { B2SsrfError } from "../errors/index.js";
2
- class UrlGuard {
3
- allowedSuffixes = [];
4
- /**
5
- * Lock the guard to the given host suffixes. A suffix matches a host
6
- * either exactly or as a `*.suffix` subdomain. For example,
7
- * `backblazeb2.com` allows `api.backblazeb2.com` and
8
- * `s3.us-west-004.backblazeb2.com`.
9
- *
10
- * Passing an empty array disables the guard (used by the simulator and
11
- * other test setups). Production code should always lock the guard after
12
- * a successful `b2_authorize_account`.
13
- *
14
- * @param suffixes - Allowed host suffixes.
15
- */
16
- setAllowedSuffixes(suffixes) {
17
- this.allowedSuffixes = suffixes;
18
- }
19
- /**
20
- * Returns the current allowed-suffix list (for tests and diagnostics).
21
- *
22
- * @returns The currently-configured list of allowed host suffixes.
23
- */
24
- getAllowedSuffixes() {
25
- return this.allowedSuffixes;
26
- }
27
- /**
28
- * Validate `rawUrl` against the allow-list. Throws {@link B2SsrfError} if
29
- * the URL points at a literal IP, a known-internal hostname, or a host
30
- * outside the allowed suffixes. Permissive (no-op) when no suffixes have
31
- * been configured yet.
32
- *
33
- * @param rawUrl - The URL the caller is about to fetch.
34
- *
35
- * @throws A `B2SsrfError` when the URL is rejected.
36
- */
37
- check(rawUrl) {
38
- if (this.allowedSuffixes.length === 0) return;
39
- let parsed;
40
- try {
41
- parsed = new URL(rawUrl);
42
- } catch {
43
- throw new B2SsrfError(`malformed URL rejected by SSRF guard: ${rawUrl}`, rawUrl);
44
- }
45
- const host = parsed.hostname.toLowerCase();
46
- if (isLiteralIp(host)) {
47
- throw new B2SsrfError(
48
- `literal IP host not allowed by SSRF guard (use a hostname): ${host}`,
49
- rawUrl
50
- );
51
- }
52
- if (isInternalHostname(host)) {
53
- throw new B2SsrfError(`internal hostname not allowed by SSRF guard: ${host}`, rawUrl);
54
- }
55
- for (const suffix of this.allowedSuffixes) {
56
- const lowered = suffix.toLowerCase();
57
- if (host === lowered || host.endsWith(`.${lowered}`)) return;
58
- }
59
- throw new B2SsrfError(
60
- `host outside allowed B2 realm: ${host} (allowed suffixes: ${this.allowedSuffixes.join(", ")})`,
61
- rawUrl
62
- );
63
- }
64
- }
2
+ //#region src/http/url-guard.ts
3
+ /**
4
+ * URL allow-list guard. Defends against SSRF / URL-substitution attacks where
5
+ * a compromised or hostile B2 endpoint returns an upload URL pointing at an
6
+ * internal service (e.g. cloud metadata at `169.254.169.254`).
7
+ *
8
+ * The guard is built once per `B2Client` and updated by `B2Client.authorize()`.
9
+ * Before authorization it is permissive (so the very first
10
+ * `b2_authorize_account` request, whose URL the user configured, can succeed).
11
+ * After authorization it is locked to host suffixes derived from the realm's
12
+ * apiUrl/downloadUrl/s3ApiUrl, plus the well-known B2 upload-pod parent
13
+ * domain `backblaze.com`.
14
+ *
15
+ * The guard runs in `FetchTransport` before any outgoing request. It rejects:
16
+ *
17
+ * 1. Literal IPv4/IPv6 addresses (defense in depth, covers attempts to
18
+ * bypass DNS-based checks with raw IPs).
19
+ * 2. Well-known internal hostnames (`localhost`, `metadata`,
20
+ * `metadata.google.internal`, `.internal`, `.local`).
21
+ * 3. Hosts not matching any allowed suffix once the SDK is locked.
22
+ *
23
+ * Users supplying a custom `transport` to `B2Client` bypass the guard. That
24
+ * is their responsibility to document for their threat model.
25
+ *
26
+ * Threat-model note: the guard checks the URL's hostname before the
27
+ * `fetch()` call. It does NOT pin the resolved IP. A DNS rebinding attack
28
+ * could in principle resolve a permitted hostname to an internal IP between
29
+ * the guard's check and `fetch()`'s own resolution. This is theoretical
30
+ * against B2 because the allow-list is locked to a small set of stable
31
+ * Backblaze hostnames (the realm's apiUrl/downloadUrl/s3ApiUrl plus the
32
+ * `backblaze.com` parent), and DNS rebinding requires a hostname under
33
+ * attacker control. Defense in depth — pinning the IP from the first
34
+ * resolution and rejecting subsequent mismatches — would break legitimate
35
+ * CDN failovers and is not justified at this surface area. If your
36
+ * threat model requires it, supply a custom transport that does.
37
+ */
38
+ /** A URL allow-list that can be reconfigured after construction. */
39
+ var UrlGuard = class {
40
+ allowedSuffixes = [];
41
+ /**
42
+ * Lock the guard to the given host suffixes. A suffix matches a host
43
+ * either exactly or as a `*.suffix` subdomain. For example,
44
+ * `backblazeb2.com` allows `api.backblazeb2.com` and
45
+ * `s3.us-west-004.backblazeb2.com`.
46
+ *
47
+ * Passing an empty array disables the guard (used by the simulator and
48
+ * other test setups). Production code should always lock the guard after
49
+ * a successful `b2_authorize_account`.
50
+ *
51
+ * @param suffixes - Allowed host suffixes.
52
+ */
53
+ setAllowedSuffixes(suffixes) {
54
+ this.allowedSuffixes = suffixes;
55
+ }
56
+ /**
57
+ * Returns the current allowed-suffix list (for tests and diagnostics).
58
+ *
59
+ * @returns The currently-configured list of allowed host suffixes.
60
+ */
61
+ getAllowedSuffixes() {
62
+ return this.allowedSuffixes;
63
+ }
64
+ /**
65
+ * Validate `rawUrl` against the allow-list. Throws {@link B2SsrfError} if
66
+ * the URL points at a literal IP, a known-internal hostname, or a host
67
+ * outside the allowed suffixes. Permissive (no-op) when no suffixes have
68
+ * been configured yet.
69
+ *
70
+ * @param rawUrl - The URL the caller is about to fetch.
71
+ *
72
+ * @throws A `B2SsrfError` when the URL is rejected.
73
+ */
74
+ check(rawUrl) {
75
+ if (this.allowedSuffixes.length === 0) return;
76
+ let parsed;
77
+ try {
78
+ parsed = new URL(rawUrl);
79
+ } catch {
80
+ throw new B2SsrfError(`malformed URL rejected by SSRF guard: ${rawUrl}`, rawUrl);
81
+ }
82
+ const host = parsed.hostname.toLowerCase();
83
+ if (isLiteralIp(host)) throw new B2SsrfError(`literal IP host not allowed by SSRF guard (use a hostname): ${host}`, rawUrl);
84
+ if (isInternalHostname(host)) throw new B2SsrfError(`internal hostname not allowed by SSRF guard: ${host}`, rawUrl);
85
+ if (hostMatchesAnyAllowedSuffix(host, this.allowedSuffixes)) return;
86
+ throw new B2SsrfError(`host outside allowed B2 realm: ${host} (allowed suffixes: ${this.allowedSuffixes.join(", ")})`, rawUrl);
87
+ }
88
+ };
89
+ /**
90
+ * Extract host suffixes to allow from a B2 authorize-account response.
91
+ *
92
+ * Known B2 realm hosts under `backblazeb2.com` are collapsed to that parent.
93
+ * Unknown or custom realm hosts are used as scoped suffixes: the returned
94
+ * hostname and its subdomains are allowed, but sibling hosts and parent
95
+ * domains are not. This avoids accidentally trusting broad public suffixes
96
+ * such as `co.uk`.
97
+ *
98
+ * Always includes `backblaze.com` because upload-pod URLs returned by
99
+ * `b2_get_upload_url` use that parent domain (`pod-NNN-NNNN-NN.backblaze.com`)
100
+ * rather than `backblazeb2.com`.
101
+ *
102
+ * @param storageApi - The `apiInfo.storageApi` portion of the authorize response.
103
+ *
104
+ * @returns Sorted list of unique host suffixes to allow.
105
+ */
65
106
  function deriveAllowedSuffixes(storageApi) {
66
- const suffixes = /* @__PURE__ */ new Set(["backblaze.com"]);
67
- for (const url of [storageApi.apiUrl, storageApi.downloadUrl, storageApi.s3ApiUrl]) {
68
- try {
69
- const host = new URL(url).hostname;
70
- const parts = host.split(".");
71
- if (parts.length >= 2) {
72
- suffixes.add(parts.slice(-2).join("."));
73
- }
74
- } catch {
75
- }
76
- }
77
- return Array.from(suffixes).sort();
107
+ const suffixes = /* @__PURE__ */ new Set(["backblaze.com"]);
108
+ for (const url of [
109
+ storageApi.apiUrl,
110
+ storageApi.downloadUrl,
111
+ storageApi.s3ApiUrl
112
+ ]) try {
113
+ const host = new URL(url).hostname;
114
+ suffixes.add(host === "backblazeb2.com" || host.endsWith(".backblazeb2.com") ? "backblazeb2.com" : host);
115
+ } catch {}
116
+ return Array.from(suffixes).sort();
117
+ }
118
+ /**
119
+ * Checks a hostname against one allowed suffix using the SDK's exact-or-subdomain rule.
120
+ *
121
+ * @param hostname - URL hostname to check.
122
+ * @param suffix - Domain suffix that may match exactly or as a parent domain.
123
+ *
124
+ * @returns Whether the hostname is exactly the suffix or a subdomain of it.
125
+ */
126
+ function hostMatchesAllowedSuffix(hostname, suffix) {
127
+ const host = hostname.toLowerCase();
128
+ const lowered = suffix.toLowerCase();
129
+ return host === lowered || host.endsWith(`.${lowered}`);
130
+ }
131
+ /**
132
+ * Checks a hostname against an allowed-suffix list.
133
+ *
134
+ * @param hostname - URL hostname to check.
135
+ * @param suffixes - Domain suffixes to test with the SDK's suffix-matching rule.
136
+ *
137
+ * @returns Whether any suffix matches the hostname.
138
+ */
139
+ function hostMatchesAnyAllowedSuffix(hostname, suffixes) {
140
+ return suffixes.some((suffix) => hostMatchesAllowedSuffix(hostname, suffix));
78
141
  }
79
142
  function isLiteralIp(host) {
80
- if (/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(host)) return true;
81
- if (host.includes(":")) return true;
82
- return false;
143
+ if (/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(host)) return true;
144
+ if (host.includes(":")) return true;
145
+ return false;
83
146
  }
84
147
  function isInternalHostname(host) {
85
- if (host === "localhost") return true;
86
- if (host.endsWith(".localhost")) return true;
87
- if (host === "metadata") return true;
88
- if (host === "metadata.google.internal") return true;
89
- if (host.endsWith(".internal")) return true;
90
- if (host.endsWith(".local")) return true;
91
- return false;
148
+ if (host === "localhost") return true;
149
+ if (host.endsWith(".localhost")) return true;
150
+ if (host === "metadata") return true;
151
+ if (host === "metadata.google.internal") return true;
152
+ if (host.endsWith(".internal")) return true;
153
+ if (host.endsWith(".local")) return true;
154
+ return false;
92
155
  }
93
- export {
94
- UrlGuard,
95
- deriveAllowedSuffixes
96
- };
97
- //# sourceMappingURL=url-guard.js.map
156
+ //#endregion
157
+ export { UrlGuard, deriveAllowedSuffixes, hostMatchesAllowedSuffix, hostMatchesAnyAllowedSuffix };
158
+
159
+ //# sourceMappingURL=url-guard.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"url-guard.js","sources":["../../src/http/url-guard.ts"],"sourcesContent":["/**\n * URL allow-list guard. Defends against SSRF / URL-substitution attacks where\n * a compromised or hostile B2 endpoint returns an upload URL pointing at an\n * internal service (e.g. cloud metadata at `169.254.169.254`).\n *\n * The guard is built once per `B2Client` and updated by `B2Client.authorize()`.\n * Before authorization it is permissive (so the very first\n * `b2_authorize_account` request, whose URL the user configured, can succeed).\n * After authorization it is locked to host suffixes derived from the realm's\n * apiUrl/downloadUrl/s3ApiUrl, plus the well-known B2 upload-pod parent\n * domain `backblaze.com`.\n *\n * The guard runs in `FetchTransport` before any outgoing request. It rejects:\n *\n * 1. Literal IPv4/IPv6 addresses (defense in depth, covers attempts to\n * bypass DNS-based checks with raw IPs).\n * 2. Well-known internal hostnames (`localhost`, `metadata`,\n * `metadata.google.internal`, `.internal`, `.local`).\n * 3. Hosts not matching any allowed suffix once the SDK is locked.\n *\n * Users supplying a custom `transport` to `B2Client` bypass the guard. That\n * is their responsibility to document for their threat model.\n *\n * Threat-model note: the guard checks the URL's hostname before the\n * `fetch()` call. It does NOT pin the resolved IP. A DNS rebinding attack\n * could in principle resolve a permitted hostname to an internal IP between\n * the guard's check and `fetch()`'s own resolution. This is theoretical\n * against B2 because the allow-list is locked to a small set of stable\n * Backblaze hostnames (the realm's apiUrl/downloadUrl/s3ApiUrl plus the\n * `backblaze.com` parent), and DNS rebinding requires a hostname under\n * attacker control. Defense in depth — pinning the IP from the first\n * resolution and rejecting subsequent mismatches — would break legitimate\n * CDN failovers and is not justified at this surface area. If your\n * threat model requires it, supply a custom transport that does.\n */\n\nimport { B2SsrfError } from '../errors/index.ts'\n\n/** A URL allow-list that can be reconfigured after construction. */\nexport class UrlGuard {\n private allowedSuffixes: readonly string[] = []\n\n /**\n * Lock the guard to the given host suffixes. A suffix matches a host\n * either exactly or as a `*.suffix` subdomain. For example,\n * `backblazeb2.com` allows `api.backblazeb2.com` and\n * `s3.us-west-004.backblazeb2.com`.\n *\n * Passing an empty array disables the guard (used by the simulator and\n * other test setups). Production code should always lock the guard after\n * a successful `b2_authorize_account`.\n *\n * @param suffixes - Allowed host suffixes.\n */\n setAllowedSuffixes(suffixes: readonly string[]): void {\n this.allowedSuffixes = suffixes\n }\n\n /**\n * Returns the current allowed-suffix list (for tests and diagnostics).\n *\n * @returns The currently-configured list of allowed host suffixes.\n */\n getAllowedSuffixes(): readonly string[] {\n return this.allowedSuffixes\n }\n\n /**\n * Validate `rawUrl` against the allow-list. Throws {@link B2SsrfError} if\n * the URL points at a literal IP, a known-internal hostname, or a host\n * outside the allowed suffixes. Permissive (no-op) when no suffixes have\n * been configured yet.\n *\n * @param rawUrl - The URL the caller is about to fetch.\n *\n * @throws A `B2SsrfError` when the URL is rejected.\n */\n check(rawUrl: string): void {\n if (this.allowedSuffixes.length === 0) return\n\n let parsed: URL\n try {\n parsed = new URL(rawUrl)\n } catch {\n throw new B2SsrfError(`malformed URL rejected by SSRF guard: ${rawUrl}`, rawUrl)\n }\n\n const host = parsed.hostname.toLowerCase()\n\n if (isLiteralIp(host)) {\n throw new B2SsrfError(\n `literal IP host not allowed by SSRF guard (use a hostname): ${host}`,\n rawUrl,\n )\n }\n\n if (isInternalHostname(host)) {\n throw new B2SsrfError(`internal hostname not allowed by SSRF guard: ${host}`, rawUrl)\n }\n\n for (const suffix of this.allowedSuffixes) {\n const lowered = suffix.toLowerCase()\n if (host === lowered || host.endsWith(`.${lowered}`)) return\n }\n\n throw new B2SsrfError(\n `host outside allowed B2 realm: ${host} (allowed suffixes: ${this.allowedSuffixes.join(', ')})`,\n rawUrl,\n )\n }\n}\n\n/**\n * Extract host suffixes to allow from a B2 authorize-account response.\n *\n * Derives the parent domain (last two labels) of each realm URL so\n * `api.us-west-004.backblazeb2.com` becomes `backblazeb2.com`. Always\n * includes `backblaze.com` because upload-pod URLs returned by\n * `b2_get_upload_url` use that parent domain (`pod-NNN-NNNN-NN.backblaze.com`)\n * rather than `backblazeb2.com`.\n *\n * @param storageApi - The `apiInfo.storageApi` portion of the authorize response.\n *\n * @returns Sorted list of unique host suffixes to allow.\n */\nexport function deriveAllowedSuffixes(storageApi: {\n apiUrl: string\n downloadUrl: string\n s3ApiUrl: string\n}): readonly string[] {\n const suffixes = new Set<string>(['backblaze.com'])\n for (const url of [storageApi.apiUrl, storageApi.downloadUrl, storageApi.s3ApiUrl]) {\n try {\n const host = new URL(url).hostname\n const parts = host.split('.')\n if (parts.length >= 2) {\n suffixes.add(parts.slice(-2).join('.'))\n }\n } catch {\n // Skip malformed URLs. The auth response is from B2 itself; malformed\n // entries would already have caused other failures upstream.\n }\n }\n return Array.from(suffixes).sort()\n}\n\nfunction isLiteralIp(host: string): boolean {\n // IPv4 dotted quad: e.g. 169.254.169.254\n if (/^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(host)) return true\n // IPv6: URL.hostname strips the brackets but keeps colons. Any colon in a\n // hostname is an IPv6 literal.\n if (host.includes(':')) return true\n return false\n}\n\nfunction isInternalHostname(host: string): boolean {\n if (host === 'localhost') return true\n if (host.endsWith('.localhost')) return true\n if (host === 'metadata') return true\n if (host === 'metadata.google.internal') return true\n if (host.endsWith('.internal')) return true\n if (host.endsWith('.local')) return true\n return false\n}\n"],"names":[],"mappings":";AAuCO,MAAM,SAAS;AAAA,EACZ,kBAAqC,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAc7C,mBAAmB,UAAmC;AACpD,SAAK,kBAAkB;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,qBAAwC;AACtC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,QAAsB;AAC1B,QAAI,KAAK,gBAAgB,WAAW,EAAG;AAEvC,QAAI;AACJ,QAAI;AACF,eAAS,IAAI,IAAI,MAAM;AAAA,IACzB,QAAQ;AACN,YAAM,IAAI,YAAY,yCAAyC,MAAM,IAAI,MAAM;AAAA,IACjF;AAEA,UAAM,OAAO,OAAO,SAAS,YAAA;AAE7B,QAAI,YAAY,IAAI,GAAG;AACrB,YAAM,IAAI;AAAA,QACR,+DAA+D,IAAI;AAAA,QACnE;AAAA,MAAA;AAAA,IAEJ;AAEA,QAAI,mBAAmB,IAAI,GAAG;AAC5B,YAAM,IAAI,YAAY,gDAAgD,IAAI,IAAI,MAAM;AAAA,IACtF;AAEA,eAAW,UAAU,KAAK,iBAAiB;AACzC,YAAM,UAAU,OAAO,YAAA;AACvB,UAAI,SAAS,WAAW,KAAK,SAAS,IAAI,OAAO,EAAE,EAAG;AAAA,IACxD;AAEA,UAAM,IAAI;AAAA,MACR,kCAAkC,IAAI,uBAAuB,KAAK,gBAAgB,KAAK,IAAI,CAAC;AAAA,MAC5F;AAAA,IAAA;AAAA,EAEJ;AACF;AAeO,SAAS,sBAAsB,YAIhB;AACpB,QAAM,WAAW,oBAAI,IAAY,CAAC,eAAe,CAAC;AAClD,aAAW,OAAO,CAAC,WAAW,QAAQ,WAAW,aAAa,WAAW,QAAQ,GAAG;AAClF,QAAI;AACF,YAAM,OAAO,IAAI,IAAI,GAAG,EAAE;AAC1B,YAAM,QAAQ,KAAK,MAAM,GAAG;AAC5B,UAAI,MAAM,UAAU,GAAG;AACrB,iBAAS,IAAI,MAAM,MAAM,EAAE,EAAE,KAAK,GAAG,CAAC;AAAA,MACxC;AAAA,IACF,QAAQ;AAAA,IAGR;AAAA,EACF;AACA,SAAO,MAAM,KAAK,QAAQ,EAAE,KAAA;AAC9B;AAEA,SAAS,YAAY,MAAuB;AAE1C,MAAI,uCAAuC,KAAK,IAAI,EAAG,QAAO;AAG9D,MAAI,KAAK,SAAS,GAAG,EAAG,QAAO;AAC/B,SAAO;AACT;AAEA,SAAS,mBAAmB,MAAuB;AACjD,MAAI,SAAS,YAAa,QAAO;AACjC,MAAI,KAAK,SAAS,YAAY,EAAG,QAAO;AACxC,MAAI,SAAS,WAAY,QAAO;AAChC,MAAI,SAAS,2BAA4B,QAAO;AAChD,MAAI,KAAK,SAAS,WAAW,EAAG,QAAO;AACvC,MAAI,KAAK,SAAS,QAAQ,EAAG,QAAO;AACpC,SAAO;AACT;"}
1
+ {"version":3,"file":"url-guard.js","names":[],"sources":["../../src/http/url-guard.ts"],"sourcesContent":["/**\n * URL allow-list guard. Defends against SSRF / URL-substitution attacks where\n * a compromised or hostile B2 endpoint returns an upload URL pointing at an\n * internal service (e.g. cloud metadata at `169.254.169.254`).\n *\n * The guard is built once per `B2Client` and updated by `B2Client.authorize()`.\n * Before authorization it is permissive (so the very first\n * `b2_authorize_account` request, whose URL the user configured, can succeed).\n * After authorization it is locked to host suffixes derived from the realm's\n * apiUrl/downloadUrl/s3ApiUrl, plus the well-known B2 upload-pod parent\n * domain `backblaze.com`.\n *\n * The guard runs in `FetchTransport` before any outgoing request. It rejects:\n *\n * 1. Literal IPv4/IPv6 addresses (defense in depth, covers attempts to\n * bypass DNS-based checks with raw IPs).\n * 2. Well-known internal hostnames (`localhost`, `metadata`,\n * `metadata.google.internal`, `.internal`, `.local`).\n * 3. Hosts not matching any allowed suffix once the SDK is locked.\n *\n * Users supplying a custom `transport` to `B2Client` bypass the guard. That\n * is their responsibility to document for their threat model.\n *\n * Threat-model note: the guard checks the URL's hostname before the\n * `fetch()` call. It does NOT pin the resolved IP. A DNS rebinding attack\n * could in principle resolve a permitted hostname to an internal IP between\n * the guard's check and `fetch()`'s own resolution. This is theoretical\n * against B2 because the allow-list is locked to a small set of stable\n * Backblaze hostnames (the realm's apiUrl/downloadUrl/s3ApiUrl plus the\n * `backblaze.com` parent), and DNS rebinding requires a hostname under\n * attacker control. Defense in depth — pinning the IP from the first\n * resolution and rejecting subsequent mismatches — would break legitimate\n * CDN failovers and is not justified at this surface area. If your\n * threat model requires it, supply a custom transport that does.\n */\n\nimport { B2SsrfError } from '../errors/index.ts'\n\n/** A URL allow-list that can be reconfigured after construction. */\nexport class UrlGuard {\n private allowedSuffixes: readonly string[] = []\n\n /**\n * Lock the guard to the given host suffixes. A suffix matches a host\n * either exactly or as a `*.suffix` subdomain. For example,\n * `backblazeb2.com` allows `api.backblazeb2.com` and\n * `s3.us-west-004.backblazeb2.com`.\n *\n * Passing an empty array disables the guard (used by the simulator and\n * other test setups). Production code should always lock the guard after\n * a successful `b2_authorize_account`.\n *\n * @param suffixes - Allowed host suffixes.\n */\n setAllowedSuffixes(suffixes: readonly string[]): void {\n this.allowedSuffixes = suffixes\n }\n\n /**\n * Returns the current allowed-suffix list (for tests and diagnostics).\n *\n * @returns The currently-configured list of allowed host suffixes.\n */\n getAllowedSuffixes(): readonly string[] {\n return this.allowedSuffixes\n }\n\n /**\n * Validate `rawUrl` against the allow-list. Throws {@link B2SsrfError} if\n * the URL points at a literal IP, a known-internal hostname, or a host\n * outside the allowed suffixes. Permissive (no-op) when no suffixes have\n * been configured yet.\n *\n * @param rawUrl - The URL the caller is about to fetch.\n *\n * @throws A `B2SsrfError` when the URL is rejected.\n */\n check(rawUrl: string): void {\n if (this.allowedSuffixes.length === 0) return\n\n let parsed: URL\n try {\n parsed = new URL(rawUrl)\n } catch {\n throw new B2SsrfError(`malformed URL rejected by SSRF guard: ${rawUrl}`, rawUrl)\n }\n\n const host = parsed.hostname.toLowerCase()\n\n if (isLiteralIp(host)) {\n throw new B2SsrfError(\n `literal IP host not allowed by SSRF guard (use a hostname): ${host}`,\n rawUrl,\n )\n }\n\n if (isInternalHostname(host)) {\n throw new B2SsrfError(`internal hostname not allowed by SSRF guard: ${host}`, rawUrl)\n }\n\n if (hostMatchesAnyAllowedSuffix(host, this.allowedSuffixes)) return\n\n throw new B2SsrfError(\n `host outside allowed B2 realm: ${host} (allowed suffixes: ${this.allowedSuffixes.join(', ')})`,\n rawUrl,\n )\n }\n}\n\n/**\n * Extract host suffixes to allow from a B2 authorize-account response.\n *\n * Known B2 realm hosts under `backblazeb2.com` are collapsed to that parent.\n * Unknown or custom realm hosts are used as scoped suffixes: the returned\n * hostname and its subdomains are allowed, but sibling hosts and parent\n * domains are not. This avoids accidentally trusting broad public suffixes\n * such as `co.uk`.\n *\n * Always includes `backblaze.com` because upload-pod URLs returned by\n * `b2_get_upload_url` use that parent domain (`pod-NNN-NNNN-NN.backblaze.com`)\n * rather than `backblazeb2.com`.\n *\n * @param storageApi - The `apiInfo.storageApi` portion of the authorize response.\n *\n * @returns Sorted list of unique host suffixes to allow.\n */\nexport function deriveAllowedSuffixes(storageApi: {\n apiUrl: string\n downloadUrl: string\n s3ApiUrl: string\n}): readonly string[] {\n const suffixes = new Set<string>(['backblaze.com'])\n for (const url of [storageApi.apiUrl, storageApi.downloadUrl, storageApi.s3ApiUrl]) {\n try {\n const host = new URL(url).hostname\n suffixes.add(\n host === 'backblazeb2.com' || host.endsWith('.backblazeb2.com') ? 'backblazeb2.com' : host,\n )\n } catch {\n // Skip malformed URLs. The auth response is from B2 itself; malformed\n // entries would already have caused other failures upstream.\n }\n }\n return Array.from(suffixes).sort()\n}\n\n/**\n * Checks a hostname against one allowed suffix using the SDK's exact-or-subdomain rule.\n *\n * @param hostname - URL hostname to check.\n * @param suffix - Domain suffix that may match exactly or as a parent domain.\n *\n * @returns Whether the hostname is exactly the suffix or a subdomain of it.\n */\nexport function hostMatchesAllowedSuffix(hostname: string, suffix: string): boolean {\n const host = hostname.toLowerCase()\n const lowered = suffix.toLowerCase()\n return host === lowered || host.endsWith(`.${lowered}`)\n}\n\n/**\n * Checks a hostname against an allowed-suffix list.\n *\n * @param hostname - URL hostname to check.\n * @param suffixes - Domain suffixes to test with the SDK's suffix-matching rule.\n *\n * @returns Whether any suffix matches the hostname.\n */\nexport function hostMatchesAnyAllowedSuffix(\n hostname: string,\n suffixes: readonly string[],\n): boolean {\n return suffixes.some((suffix) => hostMatchesAllowedSuffix(hostname, suffix))\n}\n\nfunction isLiteralIp(host: string): boolean {\n // IPv4 dotted quad: e.g. 169.254.169.254\n if (/^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(host)) return true\n // IPv6: URL.hostname strips the brackets but keeps colons. Any colon in a\n // hostname is an IPv6 literal.\n if (host.includes(':')) return true\n return false\n}\n\nfunction isInternalHostname(host: string): boolean {\n if (host === 'localhost') return true\n if (host.endsWith('.localhost')) return true\n if (host === 'metadata') return true\n if (host === 'metadata.google.internal') return true\n if (host.endsWith('.internal')) return true\n if (host.endsWith('.local')) return true\n return false\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCA,IAAa,WAAb,MAAsB;CACpB,kBAA6C,CAAC;;;;;;;;;;;;;CAc9C,mBAAmB,UAAmC;EACpD,KAAK,kBAAkB;CACzB;;;;;;CAOA,qBAAwC;EACtC,OAAO,KAAK;CACd;;;;;;;;;;;CAYA,MAAM,QAAsB;EAC1B,IAAI,KAAK,gBAAgB,WAAW,GAAG;EAEvC,IAAI;EACJ,IAAI;GACF,SAAS,IAAI,IAAI,MAAM;EACzB,QAAQ;GACN,MAAM,IAAI,YAAY,yCAAyC,UAAU,MAAM;EACjF;EAEA,MAAM,OAAO,OAAO,SAAS,YAAY;EAEzC,IAAI,YAAY,IAAI,GAClB,MAAM,IAAI,YACR,+DAA+D,QAC/D,MACF;EAGF,IAAI,mBAAmB,IAAI,GACzB,MAAM,IAAI,YAAY,gDAAgD,QAAQ,MAAM;EAGtF,IAAI,4BAA4B,MAAM,KAAK,eAAe,GAAG;EAE7D,MAAM,IAAI,YACR,kCAAkC,KAAK,sBAAsB,KAAK,gBAAgB,KAAK,IAAI,EAAE,IAC7F,MACF;CACF;AACF;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,sBAAsB,YAIhB;CACpB,MAAM,2BAAW,IAAI,IAAY,CAAC,eAAe,CAAC;CAClD,KAAK,MAAM,OAAO;EAAC,WAAW;EAAQ,WAAW;EAAa,WAAW;CAAQ,GAC/E,IAAI;EACF,MAAM,OAAO,IAAI,IAAI,GAAG,CAAC,CAAC;EAC1B,SAAS,IACP,SAAS,qBAAqB,KAAK,SAAS,kBAAkB,IAAI,oBAAoB,IACxF;CACF,QAAQ,CAGR;CAEF,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,KAAK;AACnC;;;;;;;;;AAUA,SAAgB,yBAAyB,UAAkB,QAAyB;CAClF,MAAM,OAAO,SAAS,YAAY;CAClC,MAAM,UAAU,OAAO,YAAY;CACnC,OAAO,SAAS,WAAW,KAAK,SAAS,IAAI,SAAS;AACxD;;;;;;;;;AAUA,SAAgB,4BACd,UACA,UACS;CACT,OAAO,SAAS,MAAM,WAAW,yBAAyB,UAAU,MAAM,CAAC;AAC7E;AAEA,SAAS,YAAY,MAAuB;CAE1C,IAAI,uCAAuC,KAAK,IAAI,GAAG,OAAO;CAG9D,IAAI,KAAK,SAAS,GAAG,GAAG,OAAO;CAC/B,OAAO;AACT;AAEA,SAAS,mBAAmB,MAAuB;CACjD,IAAI,SAAS,aAAa,OAAO;CACjC,IAAI,KAAK,SAAS,YAAY,GAAG,OAAO;CACxC,IAAI,SAAS,YAAY,OAAO;CAChC,IAAI,SAAS,4BAA4B,OAAO;CAChD,IAAI,KAAK,SAAS,WAAW,GAAG,OAAO;CACvC,IAAI,KAAK,SAAS,QAAQ,GAAG,OAAO;CACpC,OAAO;AACT"}
@@ -1,51 +1,91 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const version = require("../version.cjs");
4
- const SDK_PRODUCT = "b2-sdk-typescript";
5
- const SDK_PACKAGE = "@backblaze-labs/b2-sdk";
1
+ const require_version = require("../version.cjs");
2
+ //#region src/http/user-agent.ts
3
+ /**
4
+ * Stable identifier Backblaze can grep server logs for to find every request
5
+ * issued by this SDK regardless of how the User-Agent comment evolves.
6
+ * Treat as part of the public contract: do NOT rename without coordinating.
7
+ */
8
+ var SDK_PRODUCT = "b2-sdk-typescript";
9
+ /**
10
+ * The npm package name. Embedded in the User-Agent comment alongside
11
+ * {@link SDK_PRODUCT} so log queries that grep on either token work.
12
+ */
13
+ var SDK_PACKAGE = "@backblaze-labs/b2-sdk";
14
+ /**
15
+ * Best-effort detection of the JS runtime and host OS. Used to populate the
16
+ * User-Agent comment so server-side logs can spot Bun/Deno adoption and
17
+ * triage OS-specific issues without asking for a repro environment.
18
+ *
19
+ * @returns The detected runtime, OS, and architecture tokens.
20
+ */
6
21
  function detectPlatform() {
7
- const g = globalThis;
8
- if (typeof g["Deno"] !== "undefined") {
9
- const deno = g["Deno"];
10
- return {
11
- runtime: deno.version?.deno ? `deno/${deno.version.deno}` : "deno",
12
- os: deno.build?.os,
13
- arch: deno.build?.arch
14
- };
15
- }
16
- if (typeof g["Bun"] !== "undefined") {
17
- const bun = g["Bun"];
18
- const proc = g["process"];
19
- return {
20
- runtime: bun.version ? `bun/${bun.version}` : "bun",
21
- os: proc?.platform,
22
- arch: proc?.arch
23
- };
24
- }
25
- if (typeof g["process"] !== "undefined") {
26
- const proc = g["process"];
27
- if (proc.versions?.node) {
28
- return {
29
- runtime: `node/${proc.versions.node}`,
30
- os: proc.platform,
31
- arch: proc.arch
32
- };
33
- }
34
- }
35
- if (typeof g["navigator"] !== "undefined") {
36
- return { runtime: "browser", os: void 0, arch: void 0 };
37
- }
38
- return { runtime: "unknown", os: void 0, arch: void 0 };
22
+ const g = globalThis;
23
+ if (typeof g["Deno"] !== "undefined") {
24
+ const deno = g["Deno"];
25
+ return {
26
+ runtime: deno.version?.deno ? `deno/${deno.version.deno}` : "deno",
27
+ os: deno.build?.os,
28
+ arch: deno.build?.arch
29
+ };
30
+ }
31
+ if (typeof g["Bun"] !== "undefined") {
32
+ const bun = g["Bun"];
33
+ const proc = g["process"];
34
+ return {
35
+ runtime: bun.version ? `bun/${bun.version}` : "bun",
36
+ os: proc?.platform,
37
+ arch: proc?.arch
38
+ };
39
+ }
40
+ if (typeof g["process"] !== "undefined") {
41
+ const proc = g["process"];
42
+ if (proc.versions?.node) return {
43
+ runtime: `node/${proc.versions.node}`,
44
+ os: proc.platform,
45
+ arch: proc.arch
46
+ };
47
+ }
48
+ if (typeof g["navigator"] !== "undefined") return {
49
+ runtime: "browser",
50
+ os: void 0,
51
+ arch: void 0
52
+ };
53
+ return {
54
+ runtime: "unknown",
55
+ os: void 0,
56
+ arch: void 0
57
+ };
39
58
  }
59
+ /**
60
+ * Build the User-Agent header value the SDK sends on every B2 request.
61
+ *
62
+ * The product token, npm package name, language label, runtime, OS, and
63
+ * architecture are emitted in that order, separated by semicolons inside a
64
+ * single parenthesised comment block. OS and architecture are omitted on
65
+ * runtimes that don't expose them (notably browsers). A custom prefix passed
66
+ * via `B2ClientOptions.userAgent` is prepended verbatim so app-level
67
+ * identifiers come first. See the README "Identifying your traffic" section
68
+ * for examples.
69
+ *
70
+ * @param custom - Optional prefix prepended to the default User-Agent.
71
+ *
72
+ * @returns The formatted User-Agent header string.
73
+ */
40
74
  function getUserAgent(custom) {
41
- const { runtime, os, arch } = detectPlatform();
42
- const parts = ["typescript", SDK_PACKAGE, runtime];
43
- if (os !== void 0) parts.push(os);
44
- if (arch !== void 0) parts.push(arch);
45
- const base = `${SDK_PRODUCT}/${version.VERSION} (${parts.join("; ")})`;
46
- return custom ? `${custom} ${base}` : base;
75
+ const { runtime, os, arch } = detectPlatform();
76
+ const parts = [
77
+ "typescript",
78
+ SDK_PACKAGE,
79
+ runtime
80
+ ];
81
+ if (os !== void 0) parts.push(os);
82
+ if (arch !== void 0) parts.push(arch);
83
+ const base = `${SDK_PRODUCT}/${require_version.VERSION} (${parts.join("; ")})`;
84
+ return custom ? `${custom} ${base}` : base;
47
85
  }
86
+ //#endregion
48
87
  exports.SDK_PACKAGE = SDK_PACKAGE;
49
88
  exports.SDK_PRODUCT = SDK_PRODUCT;
50
89
  exports.getUserAgent = getUserAgent;
51
- //# sourceMappingURL=user-agent.cjs.map
90
+
91
+ //# sourceMappingURL=user-agent.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"user-agent.cjs","sources":["../../src/http/user-agent.ts"],"sourcesContent":["import { VERSION } from '../version.ts'\n\n/**\n * Stable identifier Backblaze can grep server logs for to find every request\n * issued by this SDK regardless of how the User-Agent comment evolves.\n * Treat as part of the public contract: do NOT rename without coordinating.\n */\nexport const SDK_PRODUCT = 'b2-sdk-typescript'\n\n/**\n * The npm package name. Embedded in the User-Agent comment alongside\n * {@link SDK_PRODUCT} so log queries that grep on either token work.\n */\nexport const SDK_PACKAGE = '@backblaze-labs/b2-sdk'\n\n/** Detected runtime + OS information for the User-Agent comment. */\ninterface Platform {\n /** Runtime identifier: `node/<x.y.z>`, `bun/<x.y.z>`, `deno/<x.y.z>`, `browser`, or `unknown`. */\n readonly runtime: string\n /** OS identifier (`linux`, `darwin`, `win32`, etc.) when available, or `undefined`. */\n readonly os: string | undefined\n /** CPU architecture (`x64`, `arm64`, etc.) when available, or `undefined`. */\n readonly arch: string | undefined\n}\n\n/**\n * Best-effort detection of the JS runtime and host OS. Used to populate the\n * User-Agent comment so server-side logs can spot Bun/Deno adoption and\n * triage OS-specific issues without asking for a repro environment.\n *\n * @returns The detected runtime, OS, and architecture tokens.\n */\nfunction detectPlatform(): Platform {\n const g = globalThis as Record<string, unknown>\n\n // Deno: Deno.version.deno, Deno.build.{os,arch}.\n if (typeof g['Deno'] !== 'undefined') {\n const deno = g['Deno'] as {\n version?: { deno?: string }\n build?: { os?: string; arch?: string }\n }\n return {\n runtime: deno.version?.deno ? `deno/${deno.version.deno}` : 'deno',\n os: deno.build?.os,\n arch: deno.build?.arch,\n }\n }\n\n // Bun: globalThis.Bun.version, process.platform/arch (Bun is Node-compat).\n if (typeof g['Bun'] !== 'undefined') {\n const bun = g['Bun'] as { version?: string }\n const proc = g['process'] as { platform?: string; arch?: string } | undefined\n return {\n runtime: bun.version ? `bun/${bun.version}` : 'bun',\n os: proc?.platform,\n arch: proc?.arch,\n }\n }\n\n // Node: process.versions.node, process.platform, process.arch.\n if (typeof g['process'] !== 'undefined') {\n const proc = g['process'] as {\n versions?: { node?: string }\n platform?: string\n arch?: string\n }\n if (proc.versions?.node) {\n return {\n runtime: `node/${proc.versions.node}`,\n os: proc.platform,\n arch: proc.arch,\n }\n }\n }\n\n // Browsers (and other navigator-only runtimes like Cloudflare Workers,\n // Vercel Edge, etc.). We deliberately do NOT parse the existing navigator\n // UA — that's noisy, often spoofed, and the request layer already adds the\n // browser's own UA on top.\n if (typeof g['navigator'] !== 'undefined') {\n return { runtime: 'browser', os: undefined, arch: undefined }\n }\n\n return { runtime: 'unknown', os: undefined, arch: undefined }\n}\n\n/**\n * Build the User-Agent header value the SDK sends on every B2 request.\n *\n * The product token, npm package name, language label, runtime, OS, and\n * architecture are emitted in that order, separated by semicolons inside a\n * single parenthesised comment block. OS and architecture are omitted on\n * runtimes that don't expose them (notably browsers). A custom prefix passed\n * via `B2ClientOptions.userAgent` is prepended verbatim so app-level\n * identifiers come first. See the README \"Identifying your traffic\" section\n * for examples.\n *\n * @param custom - Optional prefix prepended to the default User-Agent.\n *\n * @returns The formatted User-Agent header string.\n */\nexport function getUserAgent(custom?: string): string {\n const { runtime, os, arch } = detectPlatform()\n const parts = ['typescript', SDK_PACKAGE, runtime]\n if (os !== undefined) parts.push(os)\n if (arch !== undefined) parts.push(arch)\n const base = `${SDK_PRODUCT}/${VERSION} (${parts.join('; ')})`\n return custom ? `${custom} ${base}` : base\n}\n"],"names":["VERSION"],"mappings":";;;AAOO,MAAM,cAAc;AAMpB,MAAM,cAAc;AAmB3B,SAAS,iBAA2B;AAClC,QAAM,IAAI;AAGV,MAAI,OAAO,EAAE,MAAM,MAAM,aAAa;AACpC,UAAM,OAAO,EAAE,MAAM;AAIrB,WAAO;AAAA,MACL,SAAS,KAAK,SAAS,OAAO,QAAQ,KAAK,QAAQ,IAAI,KAAK;AAAA,MAC5D,IAAI,KAAK,OAAO;AAAA,MAChB,MAAM,KAAK,OAAO;AAAA,IAAA;AAAA,EAEtB;AAGA,MAAI,OAAO,EAAE,KAAK,MAAM,aAAa;AACnC,UAAM,MAAM,EAAE,KAAK;AACnB,UAAM,OAAO,EAAE,SAAS;AACxB,WAAO;AAAA,MACL,SAAS,IAAI,UAAU,OAAO,IAAI,OAAO,KAAK;AAAA,MAC9C,IAAI,MAAM;AAAA,MACV,MAAM,MAAM;AAAA,IAAA;AAAA,EAEhB;AAGA,MAAI,OAAO,EAAE,SAAS,MAAM,aAAa;AACvC,UAAM,OAAO,EAAE,SAAS;AAKxB,QAAI,KAAK,UAAU,MAAM;AACvB,aAAO;AAAA,QACL,SAAS,QAAQ,KAAK,SAAS,IAAI;AAAA,QACnC,IAAI,KAAK;AAAA,QACT,MAAM,KAAK;AAAA,MAAA;AAAA,IAEf;AAAA,EACF;AAMA,MAAI,OAAO,EAAE,WAAW,MAAM,aAAa;AACzC,WAAO,EAAE,SAAS,WAAW,IAAI,QAAW,MAAM,OAAA;AAAA,EACpD;AAEA,SAAO,EAAE,SAAS,WAAW,IAAI,QAAW,MAAM,OAAA;AACpD;AAiBO,SAAS,aAAa,QAAyB;AACpD,QAAM,EAAE,SAAS,IAAI,KAAA,IAAS,eAAA;AAC9B,QAAM,QAAQ,CAAC,cAAc,aAAa,OAAO;AACjD,MAAI,OAAO,OAAW,OAAM,KAAK,EAAE;AACnC,MAAI,SAAS,OAAW,OAAM,KAAK,IAAI;AACvC,QAAM,OAAO,GAAG,WAAW,IAAIA,QAAAA,OAAO,KAAK,MAAM,KAAK,IAAI,CAAC;AAC3D,SAAO,SAAS,GAAG,MAAM,IAAI,IAAI,KAAK;AACxC;;;;"}
1
+ {"version":3,"file":"user-agent.cjs","names":[],"sources":["../../src/http/user-agent.ts"],"sourcesContent":["import { VERSION } from '../version.ts'\n\n/**\n * Stable identifier Backblaze can grep server logs for to find every request\n * issued by this SDK regardless of how the User-Agent comment evolves.\n * Treat as part of the public contract: do NOT rename without coordinating.\n */\nexport const SDK_PRODUCT = 'b2-sdk-typescript'\n\n/**\n * The npm package name. Embedded in the User-Agent comment alongside\n * {@link SDK_PRODUCT} so log queries that grep on either token work.\n */\nexport const SDK_PACKAGE = '@backblaze-labs/b2-sdk'\n\n/** Detected runtime + OS information for the User-Agent comment. */\ninterface Platform {\n /** Runtime identifier: `node/<x.y.z>`, `bun/<x.y.z>`, `deno/<x.y.z>`, `browser`, or `unknown`. */\n readonly runtime: string\n /** OS identifier (`linux`, `darwin`, `win32`, etc.) when available, or `undefined`. */\n readonly os: string | undefined\n /** CPU architecture (`x64`, `arm64`, etc.) when available, or `undefined`. */\n readonly arch: string | undefined\n}\n\n/**\n * Best-effort detection of the JS runtime and host OS. Used to populate the\n * User-Agent comment so server-side logs can spot Bun/Deno adoption and\n * triage OS-specific issues without asking for a repro environment.\n *\n * @returns The detected runtime, OS, and architecture tokens.\n */\nfunction detectPlatform(): Platform {\n const g = globalThis as Record<string, unknown>\n\n // Deno: Deno.version.deno, Deno.build.{os,arch}.\n if (typeof g['Deno'] !== 'undefined') {\n const deno = g['Deno'] as {\n version?: { deno?: string }\n build?: { os?: string; arch?: string }\n }\n return {\n runtime: deno.version?.deno ? `deno/${deno.version.deno}` : 'deno',\n os: deno.build?.os,\n arch: deno.build?.arch,\n }\n }\n\n // Bun: globalThis.Bun.version, process.platform/arch (Bun is Node-compat).\n if (typeof g['Bun'] !== 'undefined') {\n const bun = g['Bun'] as { version?: string }\n const proc = g['process'] as { platform?: string; arch?: string } | undefined\n return {\n runtime: bun.version ? `bun/${bun.version}` : 'bun',\n os: proc?.platform,\n arch: proc?.arch,\n }\n }\n\n // Node: process.versions.node, process.platform, process.arch.\n if (typeof g['process'] !== 'undefined') {\n const proc = g['process'] as {\n versions?: { node?: string }\n platform?: string\n arch?: string\n }\n if (proc.versions?.node) {\n return {\n runtime: `node/${proc.versions.node}`,\n os: proc.platform,\n arch: proc.arch,\n }\n }\n }\n\n // Browsers (and other navigator-only runtimes like Cloudflare Workers,\n // Vercel Edge, etc.). We deliberately do NOT parse the existing navigator\n // UA — that's noisy, often spoofed, and the request layer already adds the\n // browser's own UA on top.\n if (typeof g['navigator'] !== 'undefined') {\n return { runtime: 'browser', os: undefined, arch: undefined }\n }\n\n return { runtime: 'unknown', os: undefined, arch: undefined }\n}\n\n/**\n * Build the User-Agent header value the SDK sends on every B2 request.\n *\n * The product token, npm package name, language label, runtime, OS, and\n * architecture are emitted in that order, separated by semicolons inside a\n * single parenthesised comment block. OS and architecture are omitted on\n * runtimes that don't expose them (notably browsers). A custom prefix passed\n * via `B2ClientOptions.userAgent` is prepended verbatim so app-level\n * identifiers come first. See the README \"Identifying your traffic\" section\n * for examples.\n *\n * @param custom - Optional prefix prepended to the default User-Agent.\n *\n * @returns The formatted User-Agent header string.\n */\nexport function getUserAgent(custom?: string): string {\n const { runtime, os, arch } = detectPlatform()\n const parts = ['typescript', SDK_PACKAGE, runtime]\n if (os !== undefined) parts.push(os)\n if (arch !== undefined) parts.push(arch)\n const base = `${SDK_PRODUCT}/${VERSION} (${parts.join('; ')})`\n return custom ? `${custom} ${base}` : base\n}\n"],"mappings":";;;;;;;AAOA,IAAa,cAAc;;;;;AAM3B,IAAa,cAAc;;;;;;;;AAmB3B,SAAS,iBAA2B;CAClC,MAAM,IAAI;CAGV,IAAI,OAAO,EAAE,YAAY,aAAa;EACpC,MAAM,OAAO,EAAE;EAIf,OAAO;GACL,SAAS,KAAK,SAAS,OAAO,QAAQ,KAAK,QAAQ,SAAS;GAC5D,IAAI,KAAK,OAAO;GAChB,MAAM,KAAK,OAAO;EACpB;CACF;CAGA,IAAI,OAAO,EAAE,WAAW,aAAa;EACnC,MAAM,MAAM,EAAE;EACd,MAAM,OAAO,EAAE;EACf,OAAO;GACL,SAAS,IAAI,UAAU,OAAO,IAAI,YAAY;GAC9C,IAAI,MAAM;GACV,MAAM,MAAM;EACd;CACF;CAGA,IAAI,OAAO,EAAE,eAAe,aAAa;EACvC,MAAM,OAAO,EAAE;EAKf,IAAI,KAAK,UAAU,MACjB,OAAO;GACL,SAAS,QAAQ,KAAK,SAAS;GAC/B,IAAI,KAAK;GACT,MAAM,KAAK;EACb;CAEJ;CAMA,IAAI,OAAO,EAAE,iBAAiB,aAC5B,OAAO;EAAE,SAAS;EAAW,IAAI,KAAA;EAAW,MAAM,KAAA;CAAU;CAG9D,OAAO;EAAE,SAAS;EAAW,IAAI,KAAA;EAAW,MAAM,KAAA;CAAU;AAC9D;;;;;;;;;;;;;;;;AAiBA,SAAgB,aAAa,QAAyB;CACpD,MAAM,EAAE,SAAS,IAAI,SAAS,eAAe;CAC7C,MAAM,QAAQ;EAAC;EAAc;EAAa;CAAO;CACjD,IAAI,OAAO,KAAA,GAAW,MAAM,KAAK,EAAE;CACnC,IAAI,SAAS,KAAA,GAAW,MAAM,KAAK,IAAI;CACvC,MAAM,OAAO,GAAG,YAAY,GAAG,gBAAA,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE;CAC5D,OAAO,SAAS,GAAG,OAAO,GAAG,SAAS;AACxC"}
@@ -1,51 +1,89 @@
1
1
  import { VERSION } from "../version.js";
2
- const SDK_PRODUCT = "b2-sdk-typescript";
3
- const SDK_PACKAGE = "@backblaze-labs/b2-sdk";
2
+ //#region src/http/user-agent.ts
3
+ /**
4
+ * Stable identifier Backblaze can grep server logs for to find every request
5
+ * issued by this SDK regardless of how the User-Agent comment evolves.
6
+ * Treat as part of the public contract: do NOT rename without coordinating.
7
+ */
8
+ var SDK_PRODUCT = "b2-sdk-typescript";
9
+ /**
10
+ * The npm package name. Embedded in the User-Agent comment alongside
11
+ * {@link SDK_PRODUCT} so log queries that grep on either token work.
12
+ */
13
+ var SDK_PACKAGE = "@backblaze-labs/b2-sdk";
14
+ /**
15
+ * Best-effort detection of the JS runtime and host OS. Used to populate the
16
+ * User-Agent comment so server-side logs can spot Bun/Deno adoption and
17
+ * triage OS-specific issues without asking for a repro environment.
18
+ *
19
+ * @returns The detected runtime, OS, and architecture tokens.
20
+ */
4
21
  function detectPlatform() {
5
- const g = globalThis;
6
- if (typeof g["Deno"] !== "undefined") {
7
- const deno = g["Deno"];
8
- return {
9
- runtime: deno.version?.deno ? `deno/${deno.version.deno}` : "deno",
10
- os: deno.build?.os,
11
- arch: deno.build?.arch
12
- };
13
- }
14
- if (typeof g["Bun"] !== "undefined") {
15
- const bun = g["Bun"];
16
- const proc = g["process"];
17
- return {
18
- runtime: bun.version ? `bun/${bun.version}` : "bun",
19
- os: proc?.platform,
20
- arch: proc?.arch
21
- };
22
- }
23
- if (typeof g["process"] !== "undefined") {
24
- const proc = g["process"];
25
- if (proc.versions?.node) {
26
- return {
27
- runtime: `node/${proc.versions.node}`,
28
- os: proc.platform,
29
- arch: proc.arch
30
- };
31
- }
32
- }
33
- if (typeof g["navigator"] !== "undefined") {
34
- return { runtime: "browser", os: void 0, arch: void 0 };
35
- }
36
- return { runtime: "unknown", os: void 0, arch: void 0 };
22
+ const g = globalThis;
23
+ if (typeof g["Deno"] !== "undefined") {
24
+ const deno = g["Deno"];
25
+ return {
26
+ runtime: deno.version?.deno ? `deno/${deno.version.deno}` : "deno",
27
+ os: deno.build?.os,
28
+ arch: deno.build?.arch
29
+ };
30
+ }
31
+ if (typeof g["Bun"] !== "undefined") {
32
+ const bun = g["Bun"];
33
+ const proc = g["process"];
34
+ return {
35
+ runtime: bun.version ? `bun/${bun.version}` : "bun",
36
+ os: proc?.platform,
37
+ arch: proc?.arch
38
+ };
39
+ }
40
+ if (typeof g["process"] !== "undefined") {
41
+ const proc = g["process"];
42
+ if (proc.versions?.node) return {
43
+ runtime: `node/${proc.versions.node}`,
44
+ os: proc.platform,
45
+ arch: proc.arch
46
+ };
47
+ }
48
+ if (typeof g["navigator"] !== "undefined") return {
49
+ runtime: "browser",
50
+ os: void 0,
51
+ arch: void 0
52
+ };
53
+ return {
54
+ runtime: "unknown",
55
+ os: void 0,
56
+ arch: void 0
57
+ };
37
58
  }
59
+ /**
60
+ * Build the User-Agent header value the SDK sends on every B2 request.
61
+ *
62
+ * The product token, npm package name, language label, runtime, OS, and
63
+ * architecture are emitted in that order, separated by semicolons inside a
64
+ * single parenthesised comment block. OS and architecture are omitted on
65
+ * runtimes that don't expose them (notably browsers). A custom prefix passed
66
+ * via `B2ClientOptions.userAgent` is prepended verbatim so app-level
67
+ * identifiers come first. See the README "Identifying your traffic" section
68
+ * for examples.
69
+ *
70
+ * @param custom - Optional prefix prepended to the default User-Agent.
71
+ *
72
+ * @returns The formatted User-Agent header string.
73
+ */
38
74
  function getUserAgent(custom) {
39
- const { runtime, os, arch } = detectPlatform();
40
- const parts = ["typescript", SDK_PACKAGE, runtime];
41
- if (os !== void 0) parts.push(os);
42
- if (arch !== void 0) parts.push(arch);
43
- const base = `${SDK_PRODUCT}/${VERSION} (${parts.join("; ")})`;
44
- return custom ? `${custom} ${base}` : base;
75
+ const { runtime, os, arch } = detectPlatform();
76
+ const parts = [
77
+ "typescript",
78
+ SDK_PACKAGE,
79
+ runtime
80
+ ];
81
+ if (os !== void 0) parts.push(os);
82
+ if (arch !== void 0) parts.push(arch);
83
+ const base = `${SDK_PRODUCT}/${VERSION} (${parts.join("; ")})`;
84
+ return custom ? `${custom} ${base}` : base;
45
85
  }
46
- export {
47
- SDK_PACKAGE,
48
- SDK_PRODUCT,
49
- getUserAgent
50
- };
51
- //# sourceMappingURL=user-agent.js.map
86
+ //#endregion
87
+ export { SDK_PACKAGE, SDK_PRODUCT, getUserAgent };
88
+
89
+ //# sourceMappingURL=user-agent.js.map