@backblaze-labs/b2-sdk 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (590) hide show
  1. package/CHANGELOG.md +86 -1
  2. package/README.md +38 -7
  3. package/dist/_virtual/_b2-sdk-version-json.cjs +1 -1
  4. package/dist/_virtual/_b2-sdk-version-json.js +1 -1
  5. package/dist/auth/file.cjs.map +1 -1
  6. package/dist/auth/reauth-coalescer.cjs +65 -0
  7. package/dist/auth/reauth-coalescer.cjs.map +1 -0
  8. package/dist/auth/reauth-coalescer.d.cts +34 -0
  9. package/dist/auth/reauth-coalescer.d.cts.map +1 -0
  10. package/dist/auth/reauth-coalescer.d.ts +34 -0
  11. package/dist/auth/reauth-coalescer.d.ts.map +1 -0
  12. package/dist/auth/reauth-coalescer.js +65 -0
  13. package/dist/auth/reauth-coalescer.js.map +1 -0
  14. package/dist/backup/client.cjs +206 -0
  15. package/dist/backup/client.cjs.map +1 -0
  16. package/dist/backup/client.d.cts +238 -0
  17. package/dist/backup/client.d.cts.map +1 -0
  18. package/dist/backup/client.d.ts +238 -0
  19. package/dist/backup/client.d.ts.map +1 -0
  20. package/dist/backup/client.js +206 -0
  21. package/dist/backup/client.js.map +1 -0
  22. package/dist/backup/index.cjs +15 -0
  23. package/dist/backup/index.d.cts +22 -0
  24. package/dist/backup/index.d.cts.map +1 -0
  25. package/dist/backup/index.d.ts +22 -0
  26. package/dist/backup/index.d.ts.map +1 -0
  27. package/dist/backup/index.js +7 -0
  28. package/dist/backup/raw.cjs +168 -0
  29. package/dist/backup/raw.cjs.map +1 -0
  30. package/dist/backup/raw.d.cts +122 -0
  31. package/dist/backup/raw.d.cts.map +1 -0
  32. package/dist/backup/raw.d.ts +122 -0
  33. package/dist/backup/raw.d.ts.map +1 -0
  34. package/dist/backup/raw.js +168 -0
  35. package/dist/backup/raw.js.map +1 -0
  36. package/dist/bucket-validation.cjs +111 -0
  37. package/dist/bucket-validation.cjs.map +1 -0
  38. package/dist/bucket-validation.d.cts +27 -0
  39. package/dist/bucket-validation.d.cts.map +1 -0
  40. package/dist/bucket-validation.d.ts +27 -0
  41. package/dist/bucket-validation.d.ts.map +1 -0
  42. package/dist/bucket-validation.js +109 -0
  43. package/dist/bucket-validation.js.map +1 -0
  44. package/dist/bucket.cjs +125 -74
  45. package/dist/bucket.cjs.map +1 -1
  46. package/dist/bucket.d.cts +156 -61
  47. package/dist/bucket.d.cts.map +1 -1
  48. package/dist/bucket.d.ts +156 -61
  49. package/dist/bucket.d.ts.map +1 -1
  50. package/dist/bucket.js +125 -74
  51. package/dist/bucket.js.map +1 -1
  52. package/dist/client.cjs +29 -8
  53. package/dist/client.cjs.map +1 -1
  54. package/dist/client.d.cts +30 -9
  55. package/dist/client.d.cts.map +1 -1
  56. package/dist/client.d.ts +30 -9
  57. package/dist/client.d.ts.map +1 -1
  58. package/dist/client.js +29 -8
  59. package/dist/client.js.map +1 -1
  60. package/dist/copy/large.cjs +5 -3
  61. package/dist/copy/large.cjs.map +1 -1
  62. package/dist/copy/large.d.cts.map +1 -1
  63. package/dist/copy/large.d.ts.map +1 -1
  64. package/dist/copy/large.js +5 -3
  65. package/dist/copy/large.js.map +1 -1
  66. package/dist/download/checksum.cjs +6 -2
  67. package/dist/download/checksum.cjs.map +1 -1
  68. package/dist/download/checksum.js +6 -2
  69. package/dist/download/checksum.js.map +1 -1
  70. package/dist/download/parallel.cjs +52 -15
  71. package/dist/download/parallel.cjs.map +1 -1
  72. package/dist/download/parallel.d.cts +8 -1
  73. package/dist/download/parallel.d.cts.map +1 -1
  74. package/dist/download/parallel.d.ts +8 -1
  75. package/dist/download/parallel.d.ts.map +1 -1
  76. package/dist/download/parallel.js +52 -15
  77. package/dist/download/parallel.js.map +1 -1
  78. package/dist/download/single.cjs +179 -19
  79. package/dist/download/single.cjs.map +1 -1
  80. package/dist/download/single.d.cts +10 -4
  81. package/dist/download/single.d.cts.map +1 -1
  82. package/dist/download/single.d.ts +10 -4
  83. package/dist/download/single.d.ts.map +1 -1
  84. package/dist/download/single.js +179 -19
  85. package/dist/download/single.js.map +1 -1
  86. package/dist/errors/index.cjs +196 -3
  87. package/dist/errors/index.cjs.map +1 -1
  88. package/dist/errors/index.d.cts +134 -0
  89. package/dist/errors/index.d.cts.map +1 -1
  90. package/dist/errors/index.d.ts +134 -0
  91. package/dist/errors/index.d.ts.map +1 -1
  92. package/dist/errors/index.js +183 -4
  93. package/dist/errors/index.js.map +1 -1
  94. package/dist/http/non-idempotent-mutations.cjs +38 -0
  95. package/dist/http/non-idempotent-mutations.cjs.map +1 -0
  96. package/dist/http/non-idempotent-mutations.d.cts +25 -0
  97. package/dist/http/non-idempotent-mutations.d.cts.map +1 -0
  98. package/dist/http/non-idempotent-mutations.d.ts +25 -0
  99. package/dist/http/non-idempotent-mutations.d.ts.map +1 -0
  100. package/dist/http/non-idempotent-mutations.js +35 -0
  101. package/dist/http/non-idempotent-mutations.js.map +1 -0
  102. package/dist/http/retry.cjs +1 -1
  103. package/dist/http/retry.cjs.map +1 -1
  104. package/dist/http/retry.js +1 -1
  105. package/dist/http/retry.js.map +1 -1
  106. package/dist/http/transport.cjs +62 -23
  107. package/dist/http/transport.cjs.map +1 -1
  108. package/dist/http/transport.d.cts +30 -3
  109. package/dist/http/transport.d.cts.map +1 -1
  110. package/dist/http/transport.d.ts +30 -3
  111. package/dist/http/transport.d.ts.map +1 -1
  112. package/dist/http/transport.js +60 -22
  113. package/dist/http/transport.js.map +1 -1
  114. package/dist/http/user-agent.cjs +12 -1
  115. package/dist/http/user-agent.cjs.map +1 -1
  116. package/dist/http/user-agent.d.cts +8 -0
  117. package/dist/http/user-agent.d.cts.map +1 -1
  118. package/dist/http/user-agent.d.ts +8 -0
  119. package/dist/http/user-agent.d.ts.map +1 -1
  120. package/dist/http/user-agent.js +13 -3
  121. package/dist/http/user-agent.js.map +1 -1
  122. package/dist/index.cjs +50 -2
  123. package/dist/index.d.cts +15 -12
  124. package/dist/index.d.cts.map +1 -1
  125. package/dist/index.d.ts +15 -12
  126. package/dist/index.d.ts.map +1 -1
  127. package/dist/index.js +13 -10
  128. package/dist/notifications/index.cjs +3 -0
  129. package/dist/notifications/index.d.cts +2 -0
  130. package/dist/notifications/index.d.cts.map +1 -1
  131. package/dist/notifications/index.d.ts +2 -0
  132. package/dist/notifications/index.d.ts.map +1 -1
  133. package/dist/notifications/index.js +2 -1
  134. package/dist/object.cjs +13 -2
  135. package/dist/object.cjs.map +1 -1
  136. package/dist/object.d.cts +11 -3
  137. package/dist/object.d.cts.map +1 -1
  138. package/dist/object.d.ts +11 -3
  139. package/dist/object.d.ts.map +1 -1
  140. package/dist/object.js +13 -2
  141. package/dist/object.js.map +1 -1
  142. package/dist/partner/account-info.d.cts +43 -0
  143. package/dist/partner/account-info.d.cts.map +1 -0
  144. package/dist/partner/account-info.d.ts +43 -0
  145. package/dist/partner/account-info.d.ts.map +1 -0
  146. package/dist/partner/auth-clone.cjs +64 -0
  147. package/dist/partner/auth-clone.cjs.map +1 -0
  148. package/dist/partner/auth-clone.d.cts +27 -0
  149. package/dist/partner/auth-clone.d.cts.map +1 -0
  150. package/dist/partner/auth-clone.d.ts +27 -0
  151. package/dist/partner/auth-clone.d.ts.map +1 -0
  152. package/dist/partner/auth-clone.js +63 -0
  153. package/dist/partner/auth-clone.js.map +1 -0
  154. package/dist/partner/auth-core.cjs +156 -0
  155. package/dist/partner/auth-core.cjs.map +1 -0
  156. package/dist/partner/auth-core.d.cts +111 -0
  157. package/dist/partner/auth-core.d.cts.map +1 -0
  158. package/dist/partner/auth-core.d.ts +111 -0
  159. package/dist/partner/auth-core.d.ts.map +1 -0
  160. package/dist/partner/auth-core.js +156 -0
  161. package/dist/partner/auth-core.js.map +1 -0
  162. package/dist/partner/auth-shape.cjs +36 -0
  163. package/dist/partner/auth-shape.cjs.map +1 -0
  164. package/dist/partner/auth-shape.d.cts +12 -0
  165. package/dist/partner/auth-shape.d.cts.map +1 -0
  166. package/dist/partner/auth-shape.d.ts +12 -0
  167. package/dist/partner/auth-shape.d.ts.map +1 -0
  168. package/dist/partner/auth-shape.js +36 -0
  169. package/dist/partner/auth-shape.js.map +1 -0
  170. package/dist/partner/client.cjs +270 -0
  171. package/dist/partner/client.cjs.map +1 -0
  172. package/dist/partner/client.d.cts +357 -0
  173. package/dist/partner/client.d.cts.map +1 -0
  174. package/dist/partner/client.d.ts +357 -0
  175. package/dist/partner/client.d.ts.map +1 -0
  176. package/dist/partner/client.js +270 -0
  177. package/dist/partner/client.js.map +1 -0
  178. package/dist/partner/endpoint-url.cjs +109 -0
  179. package/dist/partner/endpoint-url.cjs.map +1 -0
  180. package/dist/partner/endpoint-url.d.cts +74 -0
  181. package/dist/partner/endpoint-url.d.cts.map +1 -0
  182. package/dist/partner/endpoint-url.d.ts +74 -0
  183. package/dist/partner/endpoint-url.d.ts.map +1 -0
  184. package/dist/partner/endpoint-url.js +106 -0
  185. package/dist/partner/endpoint-url.js.map +1 -0
  186. package/dist/partner/in-memory.cjs +135 -0
  187. package/dist/partner/in-memory.cjs.map +1 -0
  188. package/dist/partner/in-memory.d.cts +99 -0
  189. package/dist/partner/in-memory.d.cts.map +1 -0
  190. package/dist/partner/in-memory.d.ts +99 -0
  191. package/dist/partner/in-memory.d.ts.map +1 -0
  192. package/dist/partner/in-memory.js +135 -0
  193. package/dist/partner/in-memory.js.map +1 -0
  194. package/dist/partner/index.cjs +27 -0
  195. package/dist/partner/index.d.cts +32 -0
  196. package/dist/partner/index.d.cts.map +1 -0
  197. package/dist/partner/index.d.ts +32 -0
  198. package/dist/partner/index.d.ts.map +1 -0
  199. package/dist/partner/index.js +9 -0
  200. package/dist/partner/raw.cjs +400 -0
  201. package/dist/partner/raw.cjs.map +1 -0
  202. package/dist/partner/raw.d.cts +220 -0
  203. package/dist/partner/raw.d.cts.map +1 -0
  204. package/dist/partner/raw.d.ts +220 -0
  205. package/dist/partner/raw.d.ts.map +1 -0
  206. package/dist/partner/raw.js +398 -0
  207. package/dist/partner/raw.js.map +1 -0
  208. package/dist/partner/redaction-placeholders.cjs +10 -0
  209. package/dist/partner/redaction-placeholders.cjs.map +1 -0
  210. package/dist/partner/redaction-placeholders.d.cts +5 -0
  211. package/dist/partner/redaction-placeholders.d.cts.map +1 -0
  212. package/dist/partner/redaction-placeholders.d.ts +5 -0
  213. package/dist/partner/redaction-placeholders.d.ts.map +1 -0
  214. package/dist/partner/redaction-placeholders.js +9 -0
  215. package/dist/partner/redaction-placeholders.js.map +1 -0
  216. package/dist/partner/redaction.cjs +292 -0
  217. package/dist/partner/redaction.cjs.map +1 -0
  218. package/dist/partner/redaction.d.cts +158 -0
  219. package/dist/partner/redaction.d.cts.map +1 -0
  220. package/dist/partner/redaction.d.ts +158 -0
  221. package/dist/partner/redaction.d.ts.map +1 -0
  222. package/dist/partner/redaction.js +281 -0
  223. package/dist/partner/redaction.js.map +1 -0
  224. package/dist/raw/encoding.cjs +29 -10
  225. package/dist/raw/encoding.cjs.map +1 -1
  226. package/dist/raw/encoding.d.cts +3 -2
  227. package/dist/raw/encoding.d.cts.map +1 -1
  228. package/dist/raw/encoding.d.ts +3 -2
  229. package/dist/raw/encoding.d.ts.map +1 -1
  230. package/dist/raw/encoding.js +29 -10
  231. package/dist/raw/encoding.js.map +1 -1
  232. package/dist/raw/index.cjs +131 -44
  233. package/dist/raw/index.cjs.map +1 -1
  234. package/dist/raw/index.d.cts +21 -15
  235. package/dist/raw/index.d.cts.map +1 -1
  236. package/dist/raw/index.d.ts +21 -15
  237. package/dist/raw/index.d.ts.map +1 -1
  238. package/dist/raw/index.js +114 -45
  239. package/dist/raw/index.js.map +1 -1
  240. package/dist/raw/url.cjs +111 -0
  241. package/dist/raw/url.cjs.map +1 -0
  242. package/dist/raw/url.d.cts +41 -0
  243. package/dist/raw/url.d.cts.map +1 -0
  244. package/dist/raw/url.d.ts +41 -0
  245. package/dist/raw/url.d.ts.map +1 -0
  246. package/dist/raw/url.js +110 -0
  247. package/dist/raw/url.js.map +1 -0
  248. package/dist/s3/sigv4.cjs +15 -10
  249. package/dist/s3/sigv4.cjs.map +1 -1
  250. package/dist/s3/sigv4.js +15 -10
  251. package/dist/s3/sigv4.js.map +1 -1
  252. package/dist/simulator/index.cjs +1579 -257
  253. package/dist/simulator/index.cjs.map +1 -1
  254. package/dist/simulator/index.d.cts +124 -11
  255. package/dist/simulator/index.d.cts.map +1 -1
  256. package/dist/simulator/index.d.ts +124 -11
  257. package/dist/simulator/index.d.ts.map +1 -1
  258. package/dist/simulator/index.js +1568 -262
  259. package/dist/simulator/index.js.map +1 -1
  260. package/dist/simulator/partner-capabilities.cjs +77 -0
  261. package/dist/simulator/partner-capabilities.cjs.map +1 -0
  262. package/dist/simulator/partner-capabilities.d.cts +53 -0
  263. package/dist/simulator/partner-capabilities.d.cts.map +1 -0
  264. package/dist/simulator/partner-capabilities.d.ts +53 -0
  265. package/dist/simulator/partner-capabilities.d.ts.map +1 -0
  266. package/dist/simulator/partner-capabilities.js +73 -0
  267. package/dist/simulator/partner-capabilities.js.map +1 -0
  268. package/dist/simulator/partner.cjs +713 -0
  269. package/dist/simulator/partner.cjs.map +1 -0
  270. package/dist/simulator/partner.d.cts +186 -0
  271. package/dist/simulator/partner.d.cts.map +1 -0
  272. package/dist/simulator/partner.d.ts +186 -0
  273. package/dist/simulator/partner.d.ts.map +1 -0
  274. package/dist/simulator/partner.js +713 -0
  275. package/dist/simulator/partner.js.map +1 -0
  276. package/dist/simulator/validation.cjs +732 -25
  277. package/dist/simulator/validation.cjs.map +1 -1
  278. package/dist/simulator/validation.d.cts +145 -6
  279. package/dist/simulator/validation.d.cts.map +1 -1
  280. package/dist/simulator/validation.d.ts +145 -6
  281. package/dist/simulator/validation.d.ts.map +1 -1
  282. package/dist/simulator/validation.js +705 -26
  283. package/dist/simulator/validation.js.map +1 -1
  284. package/dist/streams/file-source.cjs +2 -2
  285. package/dist/streams/file-source.cjs.map +1 -1
  286. package/dist/streams/file-source.js +2 -2
  287. package/dist/streams/file-source.js.map +1 -1
  288. package/dist/streams/hash.cjs +246 -13
  289. package/dist/streams/hash.cjs.map +1 -1
  290. package/dist/streams/hash.d.cts +37 -12
  291. package/dist/streams/hash.d.cts.map +1 -1
  292. package/dist/streams/hash.d.ts +37 -12
  293. package/dist/streams/hash.d.ts.map +1 -1
  294. package/dist/streams/hash.js +246 -15
  295. package/dist/streams/hash.js.map +1 -1
  296. package/dist/streams/index.cjs +3 -1
  297. package/dist/streams/index.d.cts +1 -1
  298. package/dist/streams/index.d.cts.map +1 -1
  299. package/dist/streams/index.d.ts +1 -1
  300. package/dist/streams/index.d.ts.map +1 -1
  301. package/dist/streams/index.js +3 -3
  302. package/dist/streams/progress.cjs +63 -4
  303. package/dist/streams/progress.cjs.map +1 -1
  304. package/dist/streams/progress.d.cts +28 -2
  305. package/dist/streams/progress.d.cts.map +1 -1
  306. package/dist/streams/progress.d.ts +28 -2
  307. package/dist/streams/progress.d.ts.map +1 -1
  308. package/dist/streams/progress.js +63 -4
  309. package/dist/streams/progress.js.map +1 -1
  310. package/dist/streams/source.cjs +2 -1
  311. package/dist/streams/source.cjs.map +1 -1
  312. package/dist/streams/source.js +2 -1
  313. package/dist/streams/source.js.map +1 -1
  314. package/dist/sync/b2-sha1-reader.cjs +6 -2
  315. package/dist/sync/b2-sha1-reader.cjs.map +1 -1
  316. package/dist/sync/b2-sha1-reader.d.cts.map +1 -1
  317. package/dist/sync/b2-sha1-reader.d.ts.map +1 -1
  318. package/dist/sync/b2-sha1-reader.js +6 -2
  319. package/dist/sync/b2-sha1-reader.js.map +1 -1
  320. package/dist/sync/download-staging.cjs +156 -43
  321. package/dist/sync/download-staging.cjs.map +1 -1
  322. package/dist/sync/download-staging.d.cts +26 -2
  323. package/dist/sync/download-staging.d.cts.map +1 -1
  324. package/dist/sync/download-staging.d.ts +26 -2
  325. package/dist/sync/download-staging.d.ts.map +1 -1
  326. package/dist/sync/download-staging.js +155 -44
  327. package/dist/sync/download-staging.js.map +1 -1
  328. package/dist/sync/filters.cjs.map +1 -1
  329. package/dist/sync/filters.js.map +1 -1
  330. package/dist/sync/index.d.cts +1 -1
  331. package/dist/sync/index.d.cts.map +1 -1
  332. package/dist/sync/index.d.ts +1 -1
  333. package/dist/sync/index.d.ts.map +1 -1
  334. package/dist/sync/local-file-io.cjs +15 -6
  335. package/dist/sync/local-file-io.cjs.map +1 -1
  336. package/dist/sync/local-file-io.d.cts +3 -0
  337. package/dist/sync/local-file-io.d.cts.map +1 -1
  338. package/dist/sync/local-file-io.d.ts +3 -0
  339. package/dist/sync/local-file-io.d.ts.map +1 -1
  340. package/dist/sync/local-file-io.js +15 -6
  341. package/dist/sync/local-file-io.js.map +1 -1
  342. package/dist/sync/local-sha1.cjs +6 -15
  343. package/dist/sync/local-sha1.cjs.map +1 -1
  344. package/dist/sync/local-sha1.d.cts +0 -8
  345. package/dist/sync/local-sha1.d.cts.map +1 -1
  346. package/dist/sync/local-sha1.d.ts +0 -8
  347. package/dist/sync/local-sha1.d.ts.map +1 -1
  348. package/dist/sync/local-sha1.js +7 -15
  349. package/dist/sync/local-sha1.js.map +1 -1
  350. package/dist/sync/pairing.cjs +1 -0
  351. package/dist/sync/pairing.cjs.map +1 -1
  352. package/dist/sync/pairing.js +1 -0
  353. package/dist/sync/pairing.js.map +1 -1
  354. package/dist/sync/policies/compare.cjs +5 -3
  355. package/dist/sync/policies/compare.cjs.map +1 -1
  356. package/dist/sync/policies/compare.d.cts.map +1 -1
  357. package/dist/sync/policies/compare.d.ts.map +1 -1
  358. package/dist/sync/policies/compare.js +6 -4
  359. package/dist/sync/policies/compare.js.map +1 -1
  360. package/dist/sync/policies/index.cjs +4 -10
  361. package/dist/sync/policies/index.cjs.map +1 -1
  362. package/dist/sync/policies/index.js +4 -10
  363. package/dist/sync/policies/index.js.map +1 -1
  364. package/dist/sync/scanners/b2.cjs +4 -2
  365. package/dist/sync/scanners/b2.cjs.map +1 -1
  366. package/dist/sync/scanners/b2.d.cts.map +1 -1
  367. package/dist/sync/scanners/b2.d.ts.map +1 -1
  368. package/dist/sync/scanners/b2.js +4 -2
  369. package/dist/sync/scanners/b2.js.map +1 -1
  370. package/dist/sync/scanners/local.cjs +150 -33
  371. package/dist/sync/scanners/local.cjs.map +1 -1
  372. package/dist/sync/scanners/local.d.cts +6 -0
  373. package/dist/sync/scanners/local.d.cts.map +1 -1
  374. package/dist/sync/scanners/local.d.ts +6 -0
  375. package/dist/sync/scanners/local.d.ts.map +1 -1
  376. package/dist/sync/scanners/local.js +150 -33
  377. package/dist/sync/scanners/local.js.map +1 -1
  378. package/dist/sync/synchronizer.cjs +79 -31
  379. package/dist/sync/synchronizer.cjs.map +1 -1
  380. package/dist/sync/synchronizer.d.cts +1 -0
  381. package/dist/sync/synchronizer.d.cts.map +1 -1
  382. package/dist/sync/synchronizer.d.ts +1 -0
  383. package/dist/sync/synchronizer.d.ts.map +1 -1
  384. package/dist/sync/synchronizer.js +79 -31
  385. package/dist/sync/synchronizer.js.map +1 -1
  386. package/dist/sync/types.d.cts +19 -3
  387. package/dist/sync/types.d.cts.map +1 -1
  388. package/dist/sync/types.d.ts +19 -3
  389. package/dist/sync/types.d.ts.map +1 -1
  390. package/dist/types/auth.cjs +4 -0
  391. package/dist/types/auth.cjs.map +1 -1
  392. package/dist/types/auth.d.cts +4 -0
  393. package/dist/types/auth.d.cts.map +1 -1
  394. package/dist/types/auth.d.ts +4 -0
  395. package/dist/types/auth.d.ts.map +1 -1
  396. package/dist/types/auth.js +4 -0
  397. package/dist/types/auth.js.map +1 -1
  398. package/dist/types/backup.d.cts +85 -0
  399. package/dist/types/backup.d.cts.map +1 -0
  400. package/dist/types/backup.d.ts +85 -0
  401. package/dist/types/backup.d.ts.map +1 -0
  402. package/dist/types/bucket.cjs +81 -11
  403. package/dist/types/bucket.cjs.map +1 -1
  404. package/dist/types/bucket.d.cts +194 -41
  405. package/dist/types/bucket.d.cts.map +1 -1
  406. package/dist/types/bucket.d.ts +194 -41
  407. package/dist/types/bucket.d.ts.map +1 -1
  408. package/dist/types/bucket.js +67 -12
  409. package/dist/types/bucket.js.map +1 -1
  410. package/dist/types/download.cjs +62 -0
  411. package/dist/types/download.cjs.map +1 -0
  412. package/dist/types/download.d.cts +100 -16
  413. package/dist/types/download.d.cts.map +1 -1
  414. package/dist/types/download.d.ts +100 -16
  415. package/dist/types/download.d.ts.map +1 -1
  416. package/dist/types/download.js +61 -0
  417. package/dist/types/download.js.map +1 -0
  418. package/dist/types/encryption.cjs +76 -229
  419. package/dist/types/encryption.cjs.map +1 -1
  420. package/dist/types/encryption.d.cts +48 -6
  421. package/dist/types/encryption.d.cts.map +1 -1
  422. package/dist/types/encryption.d.ts +48 -6
  423. package/dist/types/encryption.d.ts.map +1 -1
  424. package/dist/types/encryption.js +74 -229
  425. package/dist/types/encryption.js.map +1 -1
  426. package/dist/types/errors.cjs +9 -0
  427. package/dist/types/errors.cjs.map +1 -1
  428. package/dist/types/errors.d.cts +1 -1
  429. package/dist/types/errors.d.cts.map +1 -1
  430. package/dist/types/errors.d.ts +1 -1
  431. package/dist/types/errors.d.ts.map +1 -1
  432. package/dist/types/errors.js +9 -0
  433. package/dist/types/errors.js.map +1 -1
  434. package/dist/types/file.cjs +3 -0
  435. package/dist/types/file.cjs.map +1 -1
  436. package/dist/types/file.d.cts +140 -18
  437. package/dist/types/file.d.cts.map +1 -1
  438. package/dist/types/file.d.ts +140 -18
  439. package/dist/types/file.d.ts.map +1 -1
  440. package/dist/types/file.js +3 -1
  441. package/dist/types/file.js.map +1 -1
  442. package/dist/types/ids.cjs +30 -0
  443. package/dist/types/ids.cjs.map +1 -1
  444. package/dist/types/ids.d.cts +32 -0
  445. package/dist/types/ids.d.cts.map +1 -1
  446. package/dist/types/ids.d.ts +32 -0
  447. package/dist/types/ids.d.ts.map +1 -1
  448. package/dist/types/ids.js +28 -1
  449. package/dist/types/ids.js.map +1 -1
  450. package/dist/types/index.d.cts +16 -12
  451. package/dist/types/index.d.cts.map +1 -1
  452. package/dist/types/index.d.ts +16 -12
  453. package/dist/types/index.d.ts.map +1 -1
  454. package/dist/types/key.d.cts +4 -3
  455. package/dist/types/key.d.cts.map +1 -1
  456. package/dist/types/key.d.ts +4 -3
  457. package/dist/types/key.d.ts.map +1 -1
  458. package/dist/types/lock.cjs.map +1 -1
  459. package/dist/types/lock.d.cts +14 -0
  460. package/dist/types/lock.d.cts.map +1 -1
  461. package/dist/types/lock.d.ts +14 -0
  462. package/dist/types/lock.d.ts.map +1 -1
  463. package/dist/types/lock.js.map +1 -1
  464. package/dist/types/notifications.cjs +31 -1
  465. package/dist/types/notifications.cjs.map +1 -1
  466. package/dist/types/notifications.d.cts +31 -4
  467. package/dist/types/notifications.d.cts.map +1 -1
  468. package/dist/types/notifications.d.ts +31 -4
  469. package/dist/types/notifications.d.ts.map +1 -1
  470. package/dist/types/notifications.js +30 -2
  471. package/dist/types/notifications.js.map +1 -1
  472. package/dist/types/partner.cjs +32 -0
  473. package/dist/types/partner.cjs.map +1 -0
  474. package/dist/types/partner.d.cts +386 -0
  475. package/dist/types/partner.d.cts.map +1 -0
  476. package/dist/types/partner.d.ts +386 -0
  477. package/dist/types/partner.d.ts.map +1 -0
  478. package/dist/types/partner.js +29 -0
  479. package/dist/types/partner.js.map +1 -0
  480. package/dist/types/upload.d.cts +35 -18
  481. package/dist/types/upload.d.cts.map +1 -1
  482. package/dist/types/upload.d.ts +35 -18
  483. package/dist/types/upload.d.ts.map +1 -1
  484. package/dist/upload/abort-scope.cjs +0 -45
  485. package/dist/upload/abort-scope.cjs.map +1 -1
  486. package/dist/upload/abort-scope.d.cts +0 -22
  487. package/dist/upload/abort-scope.d.cts.map +1 -1
  488. package/dist/upload/abort-scope.d.ts +0 -22
  489. package/dist/upload/abort-scope.d.ts.map +1 -1
  490. package/dist/upload/abort-scope.js +1 -44
  491. package/dist/upload/abort-scope.js.map +1 -1
  492. package/dist/upload/finish.cjs +3 -8
  493. package/dist/upload/finish.cjs.map +1 -1
  494. package/dist/upload/finish.d.cts.map +1 -1
  495. package/dist/upload/finish.d.ts.map +1 -1
  496. package/dist/upload/finish.js +1 -6
  497. package/dist/upload/finish.js.map +1 -1
  498. package/dist/upload/large.cjs +15 -8
  499. package/dist/upload/large.cjs.map +1 -1
  500. package/dist/upload/large.d.cts +31 -8
  501. package/dist/upload/large.d.cts.map +1 -1
  502. package/dist/upload/large.d.ts +31 -8
  503. package/dist/upload/large.d.ts.map +1 -1
  504. package/dist/upload/large.js +15 -8
  505. package/dist/upload/large.js.map +1 -1
  506. package/dist/upload/options.cjs.map +1 -1
  507. package/dist/upload/options.d.cts +24 -0
  508. package/dist/upload/options.d.cts.map +1 -1
  509. package/dist/upload/options.d.ts +24 -0
  510. package/dist/upload/options.d.ts.map +1 -1
  511. package/dist/upload/options.js.map +1 -1
  512. package/dist/upload/resume.cjs +6 -4
  513. package/dist/upload/resume.cjs.map +1 -1
  514. package/dist/upload/resume.d.cts +9 -5
  515. package/dist/upload/resume.d.cts.map +1 -1
  516. package/dist/upload/resume.d.ts +9 -5
  517. package/dist/upload/resume.d.ts.map +1 -1
  518. package/dist/upload/resume.js +6 -4
  519. package/dist/upload/resume.js.map +1 -1
  520. package/dist/upload/retry.cjs +25 -13
  521. package/dist/upload/retry.cjs.map +1 -1
  522. package/dist/upload/retry.d.cts.map +1 -1
  523. package/dist/upload/retry.d.ts.map +1 -1
  524. package/dist/upload/retry.js +25 -13
  525. package/dist/upload/retry.js.map +1 -1
  526. package/dist/upload/single.cjs +35 -30
  527. package/dist/upload/single.cjs.map +1 -1
  528. package/dist/upload/single.d.cts +12 -0
  529. package/dist/upload/single.d.cts.map +1 -1
  530. package/dist/upload/single.d.ts +12 -0
  531. package/dist/upload/single.d.ts.map +1 -1
  532. package/dist/upload/single.js +35 -30
  533. package/dist/upload/single.js.map +1 -1
  534. package/dist/upload/stream.cjs +18 -5
  535. package/dist/upload/stream.cjs.map +1 -1
  536. package/dist/upload/stream.d.cts +12 -0
  537. package/dist/upload/stream.d.cts.map +1 -1
  538. package/dist/upload/stream.d.ts +12 -0
  539. package/dist/upload/stream.d.ts.map +1 -1
  540. package/dist/upload/stream.js +15 -2
  541. package/dist/upload/stream.js.map +1 -1
  542. package/dist/util/abort.cjs +114 -0
  543. package/dist/util/abort.cjs.map +1 -0
  544. package/dist/util/abort.d.cts +65 -0
  545. package/dist/util/abort.d.cts.map +1 -0
  546. package/dist/util/abort.d.ts +65 -0
  547. package/dist/util/abort.d.ts.map +1 -0
  548. package/dist/util/abort.js +109 -0
  549. package/dist/util/abort.js.map +1 -0
  550. package/dist/util/defaults.cjs +3 -0
  551. package/dist/util/defaults.cjs.map +1 -1
  552. package/dist/util/defaults.d.cts +2 -0
  553. package/dist/util/defaults.d.cts.map +1 -1
  554. package/dist/util/defaults.d.ts +2 -0
  555. package/dist/util/defaults.d.ts.map +1 -1
  556. package/dist/util/defaults.js +3 -1
  557. package/dist/util/defaults.js.map +1 -1
  558. package/dist/util/md5.cjs +211 -0
  559. package/dist/util/md5.cjs.map +1 -0
  560. package/dist/util/md5.d.cts +43 -0
  561. package/dist/util/md5.d.cts.map +1 -0
  562. package/dist/util/md5.d.ts +43 -0
  563. package/dist/util/md5.d.ts.map +1 -0
  564. package/dist/util/md5.js +209 -0
  565. package/dist/util/md5.js.map +1 -0
  566. package/dist/util/normalize.cjs +5 -5
  567. package/dist/util/normalize.cjs.map +1 -1
  568. package/dist/util/normalize.d.cts +7 -7
  569. package/dist/util/normalize.d.cts.map +1 -1
  570. package/dist/util/normalize.d.ts +7 -7
  571. package/dist/util/normalize.d.ts.map +1 -1
  572. package/dist/util/normalize.js +5 -5
  573. package/dist/util/normalize.js.map +1 -1
  574. package/dist/util/paginator.cjs +7 -1
  575. package/dist/util/paginator.cjs.map +1 -1
  576. package/dist/util/paginator.d.cts +3 -1
  577. package/dist/util/paginator.d.cts.map +1 -1
  578. package/dist/util/paginator.d.ts +3 -1
  579. package/dist/util/paginator.d.ts.map +1 -1
  580. package/dist/util/paginator.js +7 -1
  581. package/dist/util/paginator.js.map +1 -1
  582. package/dist/version.cjs +56 -4
  583. package/dist/version.cjs.map +1 -1
  584. package/dist/version.d.cts +53 -4
  585. package/dist/version.d.cts.map +1 -1
  586. package/dist/version.d.ts +53 -4
  587. package/dist/version.d.ts.map +1 -1
  588. package/dist/version.js +52 -5
  589. package/dist/version.js.map +1 -1
  590. package/package.json +47 -18
@@ -0,0 +1,713 @@
1
+ const require_ids = require("../types/ids.cjs");
2
+ const require_auth = require("../types/auth.cjs");
3
+ const require_partner = require("../types/partner.cjs");
4
+ const require_partner_capabilities = require("./partner-capabilities.cjs");
5
+ //#region src/simulator/partner.ts
6
+ var DAY_MS = 864e5;
7
+ var PARTNER_REGIONS = new Set(Object.values(require_partner.Region));
8
+ var PARTNER_API_ENDPOINTS = new Set(require_partner_capabilities.PARTNER_ENDPOINT_NAMES);
9
+ var DEFAULT_GROUP_COUNT = 3;
10
+ var MAX_GROUPS_PER_ADMIN = 500;
11
+ var DEFAULT_MAX_GROUP_COUNT = 100;
12
+ var MAX_GROUP_COUNT = 100;
13
+ var MAX_AUTO_PROVISIONED_ADMINS = 100;
14
+ var MAX_GROUP_MEMBERS = 5e3;
15
+ var DEFAULT_MAX_MEMBER_COUNT = 100;
16
+ var MAX_MEMBER_COUNT = 1e3;
17
+ var DEFAULT_MAX_COMPUTER_COUNT = 100;
18
+ var MIN_COMPUTER_COUNT = 1;
19
+ var MAX_COMPUTER_COUNT = 500;
20
+ var DEFAULT_COMPUTER_COUNT = 3;
21
+ var MAX_AUTO_PROVISIONED_BACKUP_ACCOUNTS = 100;
22
+ var PARTNER_CREATED_STORAGE_KEY_CAPABILITIES = Object.freeze([
23
+ require_auth.Capability.ListBuckets,
24
+ require_auth.Capability.ReadBuckets,
25
+ require_auth.Capability.WriteBuckets,
26
+ require_auth.Capability.ListFiles,
27
+ require_auth.Capability.ReadFiles,
28
+ require_auth.Capability.WriteFiles,
29
+ require_auth.Capability.DeleteFiles
30
+ ]);
31
+ function isPartnerApiEndpoint(endpoint) {
32
+ return PARTNER_API_ENDPOINTS.has(endpoint);
33
+ }
34
+ require_partner_capabilities.PartnerEndpoint.ListGroups, require_partner_capabilities.PartnerEndpoint.ListGroupMembers, require_partner_capabilities.PartnerEndpoint.ListComputers;
35
+ function utcDateString(ms) {
36
+ return new Date(ms).toISOString().slice(0, 10);
37
+ }
38
+ function b2FriendlyTimestamp(ms) {
39
+ const date = new Date(ms);
40
+ const pad = (n, width = 2) => String(n).padStart(width, "0");
41
+ return `d${`${pad(date.getUTCFullYear(), 4)}${pad(date.getUTCMonth() + 1)}${pad(date.getUTCDate())}`}_m${`${pad(date.getUTCHours())}${pad(date.getUTCMinutes())}${pad(date.getUTCSeconds())}`}`;
42
+ }
43
+ function utcDayStartMs(ms) {
44
+ const date = new Date(ms);
45
+ return Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
46
+ }
47
+ function requestObject(body) {
48
+ return typeof body === "object" && body !== null ? body : {};
49
+ }
50
+ function normalizeEmail(email) {
51
+ return email.trim().toLowerCase();
52
+ }
53
+ function isValidEmailAddress(email) {
54
+ const trimmed = email.trim();
55
+ if (trimmed !== email || trimmed.length < 3 || trimmed.length > 254) return false;
56
+ const at = trimmed.indexOf("@");
57
+ if (at <= 0 || at !== trimmed.lastIndexOf("@") || at === trimmed.length - 1) return false;
58
+ const domain = trimmed.slice(at + 1);
59
+ if (!domain.includes(".") || domain.startsWith(".") || domain.endsWith(".")) return false;
60
+ return !/\s/.test(trimmed);
61
+ }
62
+ function compareStrings(left, right) {
63
+ if (left < right) return -1;
64
+ if (left > right) return 1;
65
+ return 0;
66
+ }
67
+ function clonePartnerCapabilities(capabilities) {
68
+ return Object.freeze([...capabilities]);
69
+ }
70
+ /**
71
+ * Handles Partner and Computer Backup simulator state and endpoint logic.
72
+ *
73
+ * B2Simulator owns dispatch and shared storage primitives. This collaborator
74
+ * intentionally keeps both Partner and Backup surfaces together because one
75
+ * Partner token authorizes both products. Product-specific state remains split
76
+ * by map: groups/trials/members for Partner, computers for Backup.
77
+ *
78
+ * Auth has two modes:
79
+ *
80
+ * - default `new B2Simulator()` endpoint tests are permissive and accept any
81
+ * non-empty Partner token without binding request account IDs;
82
+ * - `partnerAuthorize: true` or `strictAuth: true` turns on issued-token
83
+ * validation so client auth-error tests can still exercise 401 responses.
84
+ */
85
+ var PartnerSimulator = class {
86
+ host;
87
+ issuedTokens = /* @__PURE__ */ new Map();
88
+ knownEmails = /* @__PURE__ */ new Set();
89
+ groups = /* @__PURE__ */ new Map();
90
+ groupsByAdmin = /* @__PURE__ */ new Map();
91
+ groupMembers = /* @__PURE__ */ new Map();
92
+ groupMembersByAccountId = /* @__PURE__ */ new Map();
93
+ computersByAccount = /* @__PURE__ */ new Map();
94
+ authorizeEnabled;
95
+ validateIssuedTokens;
96
+ apiEnabled;
97
+ accountHasValidPhone;
98
+ accountInGoodStanding;
99
+ groupsCapabilities;
100
+ backupCapabilities;
101
+ /**
102
+ * Creates the Partner/Backup simulator facade.
103
+ *
104
+ * @param host - Narrow callbacks into the parent B2 simulator.
105
+ * @param options - Parent simulator options relevant to Partner behavior.
106
+ */
107
+ constructor(host, options) {
108
+ this.host = host;
109
+ this.authorizeEnabled = options.partnerAuthorize ?? false;
110
+ this.validateIssuedTokens = this.authorizeEnabled || (options.strictAuth ?? false);
111
+ this.apiEnabled = options.partnerApiEnabled ?? true;
112
+ this.accountHasValidPhone = options.partnerAccountHasValidPhone ?? true;
113
+ this.accountInGoodStanding = options.partnerAccountInGoodStanding ?? true;
114
+ this.groupsCapabilities = clonePartnerCapabilities(options.partnerGroupsCapabilities ?? [require_partner.PartnerCapability.All]);
115
+ this.backupCapabilities = clonePartnerCapabilities(options.partnerBackupCapabilities ?? [require_partner.PartnerCapability.All]);
116
+ }
117
+ /**
118
+ * Reports whether v3 authorize should return Partner/Backup suites.
119
+ *
120
+ * @returns `true` when Partner authorization is enabled.
121
+ */
122
+ isAuthorizeEnabled() {
123
+ return this.authorizeEnabled;
124
+ }
125
+ /**
126
+ * Checks whether an endpoint name belongs to Partner or Backup APIs.
127
+ *
128
+ * @param endpoint - Endpoint name parsed from the request path.
129
+ *
130
+ * @returns `true` when this simulator should handle the endpoint.
131
+ */
132
+ isEndpoint(endpoint) {
133
+ return isPartnerApiEndpoint(endpoint);
134
+ }
135
+ /**
136
+ * Authorizes a Partner administrator and mints a Partner token.
137
+ *
138
+ * @param authzHeader - Basic authorization header from b2_authorize_account.
139
+ * @param origin - Request origin used to build simulator endpoint URLs.
140
+ *
141
+ * @returns JSON response with Partner, Backup, and storage API information.
142
+ */
143
+ authorize(authzHeader, origin = "http://localhost:0") {
144
+ if (!this.host.canAuthorize(authzHeader)) return this.host.error(401, "bad_auth_token", "missing or invalid Partner authorize credentials");
145
+ const tokenStr = this.host.genId("sim_partner_auth_token");
146
+ this.issuedTokens.set(tokenStr, {
147
+ accountId: this.host.accountId,
148
+ backupCapabilities: this.backupCapabilities,
149
+ expiresAt: this.host.now() + this.host.authTokenTtlMs,
150
+ groupsCapabilities: this.groupsCapabilities
151
+ });
152
+ return {
153
+ status: 200,
154
+ body: {
155
+ accountId: require_ids.accountId(this.host.accountId),
156
+ authorizationToken: tokenStr,
157
+ apiInfo: {
158
+ storageApi: {
159
+ absoluteMinimumPartSize: this.host.minimumPartSize,
160
+ apiUrl: origin,
161
+ bucketId: null,
162
+ bucketName: null,
163
+ capabilities: [
164
+ require_auth.Capability.ListBuckets,
165
+ require_auth.Capability.ReadBuckets,
166
+ require_auth.Capability.WriteBuckets,
167
+ require_auth.Capability.DeleteBuckets,
168
+ require_auth.Capability.ListFiles,
169
+ require_auth.Capability.ReadFiles,
170
+ require_auth.Capability.WriteFiles,
171
+ require_auth.Capability.DeleteFiles
172
+ ],
173
+ downloadUrl: origin,
174
+ infoType: "storageApi",
175
+ namePrefix: null,
176
+ recommendedPartSize: this.host.recommendedPartSize,
177
+ s3ApiUrl: origin
178
+ },
179
+ groupsApi: {
180
+ capabilities: this.groupsCapabilities,
181
+ groupsApiUrl: `${origin}/partner`,
182
+ infoType: "groupsApi"
183
+ },
184
+ backupApi: {
185
+ backupApiUrl: `${origin}/backup`,
186
+ capabilities: this.backupCapabilities,
187
+ infoType: "backupApi"
188
+ }
189
+ },
190
+ applicationKeyExpirationTimestamp: null
191
+ }
192
+ };
193
+ }
194
+ /**
195
+ * Handles b2_reserve_trial_create_account.
196
+ *
197
+ * @param body - Parsed JSON request body.
198
+ * @param authToken - Partner authorization token.
199
+ *
200
+ * @returns Simulator JSON response.
201
+ */
202
+ reserveTrialCreateAccount(body, authToken) {
203
+ const auth = this.authorizeRequest(require_partner_capabilities.PartnerEndpoint.ReserveTrialCreateAccount, authToken);
204
+ if ("status" in auth) return auth;
205
+ const parsed = this.parseReserveTrialCreateAccountRequest(body);
206
+ if (parsed.error !== null) return parsed.error;
207
+ const startDayMs = utcDayStartMs(this.host.now());
208
+ return {
209
+ status: 200,
210
+ body: this.createReserveTrialAccount(parsed.entry, parsed.normalizedEmail, startDayMs)
211
+ };
212
+ }
213
+ /**
214
+ * Handles b2_create_group_member.
215
+ *
216
+ * @param body - Parsed JSON request body.
217
+ * @param authToken - Partner authorization token.
218
+ *
219
+ * @returns Simulator JSON response.
220
+ */
221
+ createGroupMember(body, authToken) {
222
+ const auth = this.authorizeRequest(require_partner_capabilities.PartnerEndpoint.CreateGroupMember, authToken, { checkPhone: false });
223
+ if ("status" in auth) return auth;
224
+ const record = requestObject(body);
225
+ const request = this.parseCreateGroupMemberRequest(record);
226
+ if ("error" in request) return request.error;
227
+ const accountError = this.authorizeAccount(auth, request.adminAccountId);
228
+ if (accountError !== null) return accountError;
229
+ const group = this.activeGroup(request.groupId, request.adminAccountId);
230
+ if (group === null) return this.host.error(401, "invalid_group_id", "group ID is invalid or deleted");
231
+ if (!this.accountHasValidPhone) return this.host.error(401, "invalid_sms_phone", "account is missing a valid SMS phone");
232
+ const normalizedEmail = normalizeEmail(request.memberEmail);
233
+ if (!isValidEmailAddress(request.memberEmail) || this.knownEmails.has(normalizedEmail)) return this.host.error(401, "invalid_email", "email address is invalid or already exists");
234
+ const members = this.membersForGroup(group.groupId);
235
+ if (this.activeMembersForGroup(group.groupId).length >= MAX_GROUP_MEMBERS) return this.host.error(401, "too_many_members", "group member count limit exceeded");
236
+ const accountId$1 = require_ids.accountId(this.host.genId("sim_group_member_account"));
237
+ const applicationKeyId$1 = require_ids.applicationKeyId(this.host.genId("sim_key"));
238
+ const applicationKey = this.host.genId("sim_secret");
239
+ const region = request.region ?? require_partner.Region.UsWest;
240
+ const stored = {
241
+ accountId: accountId$1,
242
+ email: request.memberEmail,
243
+ normalizedEmail,
244
+ groupId: group.groupId,
245
+ groupName: group.groupName,
246
+ region,
247
+ s3Endpoint: `s3.${region}-001.backblazeb2.com`,
248
+ applicationKeyId: applicationKeyId$1,
249
+ applicationKey,
250
+ createdTimestamp: this.host.monotonicTimestamp(),
251
+ ejected: false
252
+ };
253
+ members.set(normalizedEmail, stored);
254
+ this.groupMembersByAccountId.set(accountId$1, stored);
255
+ this.knownEmails.add(normalizedEmail);
256
+ this.host.storeKey({
257
+ applicationKeyId: applicationKeyId$1,
258
+ keyName: `group-member-${accountId$1}`,
259
+ capabilities: PARTNER_CREATED_STORAGE_KEY_CAPABILITIES,
260
+ accountId: accountId$1,
261
+ applicationKey,
262
+ bucketIds: null,
263
+ namePrefix: null,
264
+ expirationTimestamp: null
265
+ });
266
+ return {
267
+ status: 200,
268
+ body: {
269
+ applicationKeyId: applicationKeyId$1,
270
+ applicationKey,
271
+ groupMember: this.publicGroupMember(stored)
272
+ }
273
+ };
274
+ }
275
+ /**
276
+ * Handles b2_eject_group_member.
277
+ *
278
+ * @param body - Parsed JSON request body.
279
+ * @param authToken - Partner authorization token.
280
+ *
281
+ * @returns Simulator JSON response.
282
+ */
283
+ ejectGroupMember(body, authToken) {
284
+ const auth = this.authorizeRequest(require_partner_capabilities.PartnerEndpoint.EjectGroupMember, authToken);
285
+ if ("status" in auth) return auth;
286
+ const record = requestObject(body);
287
+ const request = this.parseEjectGroupMemberRequest(record);
288
+ if ("error" in request) return request.error;
289
+ const accountError = this.authorizeAccount(auth, request.adminAccountId);
290
+ if (accountError !== null) return accountError;
291
+ const group = this.activeGroup(request.groupId, request.adminAccountId);
292
+ if (group === null) return this.host.error(401, "invalid_group_id", "group ID is invalid or deleted");
293
+ const member = this.groupMembersByAccountId.get(request.memberAccountId);
294
+ if (member === void 0 || member.ejected || member.groupId !== group.groupId) return this.host.error(401, "invalid_member_account_id", "group member account ID is invalid");
295
+ const previousNormalizedEmail = member.normalizedEmail;
296
+ if (request.email !== void 0 && request.email !== null) {
297
+ const normalizedEmail = normalizeEmail(request.email);
298
+ const keepsSameEmail = normalizedEmail === previousNormalizedEmail;
299
+ if (!isValidEmailAddress(request.email) || !keepsSameEmail && this.knownEmails.has(normalizedEmail)) return this.host.error(401, "invalid_email", "email address is invalid or already exists");
300
+ if (!keepsSameEmail) {
301
+ this.knownEmails.delete(previousNormalizedEmail);
302
+ this.knownEmails.add(normalizedEmail);
303
+ }
304
+ member.email = request.email;
305
+ member.normalizedEmail = normalizedEmail;
306
+ }
307
+ member.ejected = true;
308
+ this.groupMembers.get(group.groupId)?.delete(previousNormalizedEmail);
309
+ return {
310
+ status: 200,
311
+ body: this.publicGroupMember(member)
312
+ };
313
+ }
314
+ /**
315
+ * Handles b2_list_groups.
316
+ *
317
+ * @param body - Parsed GET query parameters or JSON body.
318
+ * @param authToken - Partner authorization token.
319
+ *
320
+ * @returns Simulator JSON response.
321
+ */
322
+ listGroups(body, authToken) {
323
+ const auth = this.authorizeRequest(require_partner_capabilities.PartnerEndpoint.ListGroups, authToken, { checkPhone: false });
324
+ if ("status" in auth) return auth;
325
+ const record = requestObject(body);
326
+ const adminAccountId = this.requiredString(record, "adminAccountId", 400, "bad_request");
327
+ if ("error" in adminAccountId) return adminAccountId.error;
328
+ const accountError = this.authorizeAccount(auth, adminAccountId.value);
329
+ if (accountError !== null) return accountError;
330
+ const maxGroupCount = this.optionalInteger(record, "maxGroupCount", DEFAULT_MAX_GROUP_COUNT, 1, MAX_GROUP_COUNT, 401, "out_of_range");
331
+ if ("error" in maxGroupCount) return maxGroupCount.error;
332
+ const groupSeedError = this.ensureGroupsForAdmin(adminAccountId.value);
333
+ if (groupSeedError !== null) return groupSeedError;
334
+ const groupNameValue = record["groupName"];
335
+ const groupName = typeof groupNameValue === "string" ? groupNameValue : void 0;
336
+ const startGroupIdValue = record["startGroupId"];
337
+ const startGroupId = typeof startGroupIdValue === "string" ? startGroupIdValue : void 0;
338
+ if (startGroupId !== void 0 && this.activeGroup(startGroupId, adminAccountId.value) === null) return this.host.error(401, "invalid_group_id", "group ID is invalid or deleted");
339
+ const allGroups = this.activeGroupsForAdmin(adminAccountId.value).filter((group) => groupName === void 0 || group.groupName === groupName).sort((left, right) => compareStrings(left.groupId, right.groupId));
340
+ const startIndex = startGroupId === void 0 ? 0 : allGroups.findIndex((group) => group.groupId >= startGroupId);
341
+ const normalizedStartIndex = startIndex === -1 ? allGroups.length : startIndex;
342
+ const page = allGroups.slice(normalizedStartIndex, normalizedStartIndex + maxGroupCount.value);
343
+ const next = allGroups[normalizedStartIndex + maxGroupCount.value];
344
+ return {
345
+ status: 200,
346
+ body: {
347
+ accountId: require_ids.accountId(adminAccountId.value),
348
+ groups: page.map((group) => this.publicGroup(group)),
349
+ nextGroupId: next === void 0 ? null : require_ids.groupId(next.groupId)
350
+ }
351
+ };
352
+ }
353
+ /**
354
+ * Handles b2_list_group_members.
355
+ *
356
+ * @param body - Parsed GET query parameters or JSON body.
357
+ * @param authToken - Partner authorization token.
358
+ *
359
+ * @returns Simulator JSON response.
360
+ */
361
+ listGroupMembers(body, authToken) {
362
+ const auth = this.authorizeRequest(require_partner_capabilities.PartnerEndpoint.ListGroupMembers, authToken, { checkPhone: false });
363
+ if ("status" in auth) return auth;
364
+ const record = requestObject(body);
365
+ const request = this.parseListGroupMembersRequest(record);
366
+ if ("error" in request) return request.error;
367
+ const accountError = this.authorizeAccount(auth, request.adminAccountId);
368
+ if (accountError !== null) return accountError;
369
+ const group = this.activeGroup(request.groupId, request.adminAccountId);
370
+ if (group === null) return this.host.error(401, "invalid_group_id", "group ID is invalid or deleted");
371
+ const members = this.activeMembersForGroup(group.groupId).sort((left, right) => compareStrings(left.normalizedEmail, right.normalizedEmail));
372
+ const startEmail = request.startEmail === void 0 ? void 0 : normalizeEmail(request.startEmail);
373
+ const startIndex = startEmail === void 0 ? 0 : members.findIndex((member) => member.normalizedEmail >= startEmail);
374
+ const normalizedStartIndex = startIndex === -1 ? members.length : startIndex;
375
+ const page = members.slice(normalizedStartIndex, normalizedStartIndex + request.maxMemberCount);
376
+ const next = members[normalizedStartIndex + request.maxMemberCount];
377
+ return {
378
+ status: 200,
379
+ body: {
380
+ groupId: require_ids.groupId(group.groupId),
381
+ groupName: group.groupName,
382
+ groupMembers: page.map((member) => this.publicListedGroupMember(member)),
383
+ nextEmail: next === void 0 ? null : next.email
384
+ }
385
+ };
386
+ }
387
+ /**
388
+ * Handles bz_list_computers.
389
+ *
390
+ * @param body - Parsed GET query parameters or JSON body.
391
+ * @param authToken - Partner authorization token.
392
+ *
393
+ * @returns Simulator JSON response.
394
+ */
395
+ listComputers(body, authToken) {
396
+ const auth = this.authorizeRequest(require_partner_capabilities.PartnerEndpoint.ListComputers, authToken, { checkPhone: false });
397
+ if ("status" in auth) return auth;
398
+ const record = requestObject(body);
399
+ const accountId = this.requiredString(record, "accountId", 400, "invalid_account_id");
400
+ if ("error" in accountId) return accountId.error;
401
+ const accountError = this.authorizeAccount(auth, accountId.value);
402
+ if (accountError !== null) return accountError;
403
+ const maxComputerCount = this.optionalInteger(record, "maxComputerCount", DEFAULT_MAX_COMPUTER_COUNT, MIN_COMPUTER_COUNT, MAX_COMPUTER_COUNT, 400, "out_of_range");
404
+ if ("error" in maxComputerCount) return maxComputerCount.error;
405
+ const computers = this.ensureComputersForAccount(accountId.value);
406
+ if ("status" in computers) return computers;
407
+ const startComputerIdValue = record["startComputerId"];
408
+ const startComputerId = typeof startComputerIdValue === "string" ? startComputerIdValue : void 0;
409
+ if (startComputerId !== void 0) {
410
+ const start = computers.get(startComputerId);
411
+ if (start === void 0 || start.deleted) return this.host.error(400, "invalid_computer_id", "computer ID is invalid or deleted");
412
+ }
413
+ const activeComputers = [...computers.values()].filter((computer) => !computer.deleted).sort((left, right) => compareStrings(left.computerId, right.computerId));
414
+ const startIndex = startComputerId === void 0 ? 0 : activeComputers.findIndex((computer) => computer.computerId >= startComputerId);
415
+ const normalizedStartIndex = startIndex === -1 ? activeComputers.length : startIndex;
416
+ const page = activeComputers.slice(normalizedStartIndex, normalizedStartIndex + maxComputerCount.value);
417
+ const next = activeComputers[normalizedStartIndex + maxComputerCount.value];
418
+ return {
419
+ status: 200,
420
+ body: {
421
+ nextComputerId: next === void 0 ? null : next.computerId,
422
+ computers: page.map((computer) => this.publicComputer(computer))
423
+ }
424
+ };
425
+ }
426
+ /**
427
+ * Handles bz_delete_computer.
428
+ *
429
+ * @param body - Parsed JSON request body.
430
+ * @param authToken - Partner authorization token.
431
+ *
432
+ * @returns Simulator JSON response.
433
+ */
434
+ deleteComputer(body, authToken) {
435
+ const auth = this.authorizeRequest(require_partner_capabilities.PartnerEndpoint.DeleteComputer, authToken, { checkPhone: false });
436
+ if ("status" in auth) return auth;
437
+ const record = requestObject(body);
438
+ const accountId = this.requiredString(record, "accountId", 400, "invalid_account_id");
439
+ if ("error" in accountId) return accountId.error;
440
+ const computerId = this.requiredString(record, "computerId", 400, "invalid_computer_id");
441
+ if ("error" in computerId) return computerId.error;
442
+ const accountError = this.authorizeAccount(auth, accountId.value);
443
+ if (accountError !== null) return accountError;
444
+ const computer = this.computersByAccount.get(accountId.value)?.get(computerId.value);
445
+ if (computer === void 0 || computer.deleted) return this.host.error(400, "invalid_computer_id", "computer ID is invalid or deleted");
446
+ computer.deleted = true;
447
+ return {
448
+ status: 200,
449
+ body: [this.publicComputer(computer)]
450
+ };
451
+ }
452
+ authorizeRequest(endpoint, authToken, options = {}) {
453
+ if (authToken === void 0 || authToken.trim() === "" || /\s/.test(authToken)) return this.host.error(403, "access_denied", "missing or malformed Partner API Authorization header");
454
+ if (!this.validateIssuedTokens) {
455
+ if (!this.apiEnabled) return this.host.error(403, "access_denied", "account is not enabled for Partner API");
456
+ if (options.checkPhone !== false && !this.accountHasValidPhone) return this.host.error(403, "access_denied", "account does not have a valid phone number");
457
+ if (!this.accountInGoodStanding) return this.host.error(403, "access_denied", "account is not in good standing");
458
+ return { accountId: null };
459
+ }
460
+ const token = this.issuedTokens.get(authToken);
461
+ if (token === void 0 || this.host.now() > token.expiresAt) return this.host.error(401, "unauthorized", "invalid Partner API authorization token");
462
+ if (!this.apiEnabled) return this.host.error(403, "access_denied", "account is not enabled for Partner API");
463
+ if (options.checkPhone !== false && !this.accountHasValidPhone) return this.host.error(403, "access_denied", "account does not have a valid phone number");
464
+ if (!this.accountInGoodStanding) return this.host.error(403, "access_denied", "account is not in good standing");
465
+ const capabilityError = this.authorizeEndpointCapabilities(endpoint, token);
466
+ if (capabilityError !== null) return capabilityError;
467
+ return { accountId: token.accountId };
468
+ }
469
+ authorizeEndpointCapabilities(endpoint, token) {
470
+ const requirement = require_partner_capabilities.partnerEndpointCapabilityRequirementFor(endpoint);
471
+ if (requirement === null) return this.host.error(401, "unauthorized", `no Partner capability policy for ${endpoint}`);
472
+ const granted = requirement.suite === "groups" ? token.groupsCapabilities : token.backupCapabilities;
473
+ const missing = require_partner_capabilities.missingPartnerCapabilities(requirement.capabilities, granted);
474
+ if (missing.length === 0) return null;
475
+ return this.host.error(401, "unauthorized", `Partner token lacks required capabilities: ${missing.join(", ")}`);
476
+ }
477
+ authorizeAccount(auth, requestedAccountId) {
478
+ if (auth.accountId === null) return null;
479
+ if (auth.accountId === requestedAccountId) return null;
480
+ return this.host.error(403, "unauthorized", "Partner token is not authorized for requested account");
481
+ }
482
+ parseReserveTrialCreateAccountRequest(value) {
483
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return { error: this.host.error(400, "bad_request", "trial account request must be an object") };
484
+ const record = value;
485
+ const email = record["email"];
486
+ if (typeof email !== "string") return { error: this.host.error(400, "bad_request", "email is required") };
487
+ if (!isValidEmailAddress(email)) return { error: this.host.error(400, "bad_request", "email address is invalid") };
488
+ const normalizedEmail = normalizeEmail(email);
489
+ if (this.knownEmails.has(normalizedEmail)) return { error: this.host.error(400, "bad_request", "email must not already exist as a Backblaze account") };
490
+ const term = record["term"];
491
+ if (typeof term !== "number" || !Number.isInteger(term) || term < 7 || term > 30) return { error: this.host.error(400, "bad_request", "term must be between 7 and 30 days") };
492
+ const storage = record["storage"];
493
+ if (typeof storage !== "number" || !Number.isInteger(storage) || storage < 1 || storage > 50) return { error: this.host.error(400, "bad_request", "storage must be between 1 and 50 TB") };
494
+ const region = record["region"];
495
+ if (region !== void 0 && region !== null && (typeof region !== "string" || !PARTNER_REGIONS.has(region))) return { error: this.host.error(400, "bad_request", "region is not supported") };
496
+ return {
497
+ entry: {
498
+ email,
499
+ term,
500
+ storage,
501
+ ...region !== void 0 ? { region } : {}
502
+ },
503
+ normalizedEmail,
504
+ error: null
505
+ };
506
+ }
507
+ createReserveTrialAccount(request, normalizedEmail, startDayMs) {
508
+ const accountId$2 = require_ids.accountId(this.host.genId("sim_trial_account"));
509
+ const bucketName = `trial-${this.host.genId("bucket").slice(-8)}`;
510
+ const bucketResponse = this.host.createBucket({
511
+ accountId: accountId$2,
512
+ bucketName,
513
+ bucketType: "allPrivate"
514
+ });
515
+ if (bucketResponse.status !== 200) throw new Error("failed to create simulator reserve trial bucket");
516
+ const bucket = bucketResponse.body;
517
+ const keyId = require_ids.applicationKeyId(this.host.genId("sim_key"));
518
+ const applicationKey = this.host.genId("sim_secret");
519
+ this.host.storeKey({
520
+ applicationKeyId: keyId,
521
+ keyName: `reserve-trial-${bucketName}`,
522
+ capabilities: PARTNER_CREATED_STORAGE_KEY_CAPABILITIES,
523
+ accountId: accountId$2,
524
+ applicationKey,
525
+ bucketIds: [bucket.bucketId],
526
+ namePrefix: null,
527
+ expirationTimestamp: null
528
+ });
529
+ this.knownEmails.add(normalizedEmail);
530
+ return {
531
+ accountId: accountId$2,
532
+ applicationKey,
533
+ applicationKeyId: keyId,
534
+ s3Endpoint: `s3.${request.region ?? require_partner.Region.UsWest}-001.backblazeb2.com`,
535
+ startDate: utcDateString(startDayMs),
536
+ endDate: utcDateString(startDayMs + request.term * DAY_MS),
537
+ email: request.email,
538
+ bucketName: bucket.bucketName,
539
+ bucketId: bucket.bucketId
540
+ };
541
+ }
542
+ parseCreateGroupMemberRequest(record) {
543
+ const adminAccountId = this.requiredString(record, "adminAccountId", 400, "bad_request");
544
+ if ("error" in adminAccountId) return adminAccountId;
545
+ const groupId$1 = this.requiredString(record, "groupId", 401, "invalid_group_id");
546
+ if ("error" in groupId$1) return groupId$1;
547
+ const memberEmail = this.requiredString(record, "memberEmail", 401, "invalid_email");
548
+ if ("error" in memberEmail) return memberEmail;
549
+ const regionValue = record["region"];
550
+ if (regionValue !== void 0 && regionValue !== null && (typeof regionValue !== "string" || !PARTNER_REGIONS.has(regionValue))) return { error: this.host.error(401, "invalid_region", "region is invalid") };
551
+ return {
552
+ adminAccountId: require_ids.accountId(adminAccountId.value),
553
+ groupId: require_ids.groupId(groupId$1.value),
554
+ memberEmail: memberEmail.value,
555
+ ...regionValue !== void 0 ? { region: regionValue } : {}
556
+ };
557
+ }
558
+ parseEjectGroupMemberRequest(record) {
559
+ const adminAccountId = this.requiredString(record, "adminAccountId", 400, "bad_request");
560
+ if ("error" in adminAccountId) return adminAccountId;
561
+ const groupId$2 = this.requiredString(record, "groupId", 401, "invalid_group_id");
562
+ if ("error" in groupId$2) return groupId$2;
563
+ const memberAccountId = this.requiredString(record, "memberAccountId", 401, "invalid_member_account_id");
564
+ if ("error" in memberAccountId) return memberAccountId;
565
+ const email = record["email"];
566
+ if (email !== void 0 && email !== null && typeof email !== "string") return { error: this.host.error(401, "invalid_email", "email address is invalid") };
567
+ return {
568
+ adminAccountId: require_ids.accountId(adminAccountId.value),
569
+ groupId: require_ids.groupId(groupId$2.value),
570
+ memberAccountId: require_ids.accountId(memberAccountId.value),
571
+ ...email !== void 0 ? { email } : {}
572
+ };
573
+ }
574
+ parseListGroupMembersRequest(record) {
575
+ const adminAccountId = this.requiredString(record, "adminAccountId", 400, "bad_request");
576
+ if ("error" in adminAccountId) return adminAccountId;
577
+ const groupId$3 = this.requiredString(record, "groupId", 401, "invalid_group_id");
578
+ if ("error" in groupId$3) return groupId$3;
579
+ const maxMemberCount = this.optionalInteger(record, "maxMemberCount", DEFAULT_MAX_MEMBER_COUNT, 1, MAX_MEMBER_COUNT, 401, "out_of_range", { zeroUsesDefault: true });
580
+ if ("error" in maxMemberCount) return maxMemberCount;
581
+ const startEmail = record["startEmail"];
582
+ if (startEmail !== void 0 && typeof startEmail !== "string") return { error: this.host.error(400, "bad_request", "startEmail must be a string") };
583
+ return {
584
+ adminAccountId: require_ids.accountId(adminAccountId.value),
585
+ groupId: require_ids.groupId(groupId$3.value),
586
+ ...startEmail !== void 0 ? { startEmail } : {},
587
+ maxMemberCount: maxMemberCount.value
588
+ };
589
+ }
590
+ requiredString(record, field, status, code) {
591
+ const value = record[field];
592
+ if (typeof value !== "string" || value === "") return { error: this.host.error(status, code, `${field} is required`) };
593
+ return { value };
594
+ }
595
+ optionalInteger(record, field, defaultValue, min, max, status, code, options = {}) {
596
+ const raw = record[field];
597
+ if (raw === void 0) return { value: defaultValue };
598
+ const value = typeof raw === "number" ? raw : typeof raw === "string" && raw !== "" ? Number(raw) : NaN;
599
+ if (options.zeroUsesDefault === true && value === 0) return { value: defaultValue };
600
+ if (!Number.isInteger(value) || value < min || value > max) return { error: this.host.error(status, code, `${field} must be between ${min} and ${max}`) };
601
+ return { value };
602
+ }
603
+ ensureGroupsForAdmin(adminAccountId) {
604
+ if (this.groupsByAdmin.has(adminAccountId)) return null;
605
+ if (this.groupsByAdmin.size >= MAX_AUTO_PROVISIONED_ADMINS) return this.host.error(400, "too_many_accounts", "simulator Partner account auto-provisioning cap exceeded");
606
+ this.groupsByAdmin.set(adminAccountId, []);
607
+ for (let index = 1; index <= DEFAULT_GROUP_COUNT; index += 1) this.createGroup(adminAccountId, `Simulator Group ${index}`);
608
+ return null;
609
+ }
610
+ createGroup(adminAccountId, groupName) {
611
+ const existingGroupIds = this.groupsByAdmin.get(adminAccountId) ?? [];
612
+ if (existingGroupIds.length >= MAX_GROUPS_PER_ADMIN) throw new Error("simulator Partner group cap exceeded");
613
+ const group = {
614
+ adminAccountId,
615
+ groupId: this.host.genId("sim_group"),
616
+ groupName,
617
+ groupProducts: ["STORAGE", "BACKUP"],
618
+ createdTimestamp: this.host.monotonicTimestamp(),
619
+ deleted: false
620
+ };
621
+ this.groups.set(group.groupId, group);
622
+ existingGroupIds.push(group.groupId);
623
+ this.groupsByAdmin.set(adminAccountId, existingGroupIds);
624
+ this.groupMembers.set(group.groupId, /* @__PURE__ */ new Map());
625
+ return group;
626
+ }
627
+ activeGroup(groupId, adminAccountId) {
628
+ const group = this.groups.get(groupId);
629
+ if (group === void 0 || group.deleted || group.adminAccountId !== adminAccountId) return null;
630
+ return group;
631
+ }
632
+ activeGroupsForAdmin(adminAccountId) {
633
+ return (this.groupsByAdmin.get(adminAccountId) ?? []).map((groupId) => this.groups.get(groupId)).filter((group) => group !== void 0 && !group.deleted);
634
+ }
635
+ membersForGroup(groupId) {
636
+ const existing = this.groupMembers.get(groupId);
637
+ if (existing !== void 0) return existing;
638
+ const created = /* @__PURE__ */ new Map();
639
+ this.groupMembers.set(groupId, created);
640
+ return created;
641
+ }
642
+ activeMembersForGroup(groupId) {
643
+ return [...this.groupMembers.get(groupId)?.values() ?? []].filter((member) => !member.ejected);
644
+ }
645
+ ensureComputersForAccount(accountId) {
646
+ const existing = this.computersByAccount.get(accountId);
647
+ if (existing !== void 0) return existing;
648
+ if (this.computersByAccount.size >= MAX_AUTO_PROVISIONED_BACKUP_ACCOUNTS) return this.host.error(400, "too_many_accounts", "simulator Backup account auto-provisioning cap exceeded");
649
+ const computers = /* @__PURE__ */ new Map();
650
+ for (let index = 1; index <= DEFAULT_COMPUTER_COUNT; index += 1) {
651
+ const computer = {
652
+ accountId,
653
+ computerId: this.host.genId("sim_computer"),
654
+ computerName: `sim-computer-${index}`,
655
+ lastFileUploadedTimestamp: this.host.monotonicTimestamp(),
656
+ deleted: false
657
+ };
658
+ computers.set(computer.computerId, computer);
659
+ }
660
+ this.computersByAccount.set(accountId, computers);
661
+ return computers;
662
+ }
663
+ publicGroup(group) {
664
+ const timestamp = b2FriendlyTimestamp(group.createdTimestamp);
665
+ return {
666
+ accountStandingDetails: { state: "B2_GOOD_STANDING" },
667
+ b2Stats: this.emptyB2Stats(group.createdTimestamp),
668
+ groupId: require_ids.groupId(group.groupId),
669
+ groupName: group.groupName,
670
+ groupProducts: group.groupProducts,
671
+ groupStats: {
672
+ createdTimestamp: timestamp,
673
+ groupStatsAsOfTimestamp: timestamp,
674
+ memberCount: this.activeMembersForGroup(group.groupId).length
675
+ }
676
+ };
677
+ }
678
+ publicGroupMember(member) {
679
+ return {
680
+ accountId: require_ids.accountId(member.accountId),
681
+ email: member.email,
682
+ groupId: require_ids.groupId(member.groupId),
683
+ groupName: member.groupName,
684
+ region: member.region,
685
+ s3Endpoint: member.s3Endpoint
686
+ };
687
+ }
688
+ publicListedGroupMember(member) {
689
+ return {
690
+ ...this.publicGroupMember(member),
691
+ b2Stats: this.emptyB2Stats(member.createdTimestamp)
692
+ };
693
+ }
694
+ publicComputer(computer) {
695
+ return {
696
+ computerId: require_ids.computerId(computer.computerId),
697
+ computerName: computer.computerName,
698
+ lastFileUploadedTimestamp: computer.lastFileUploadedTimestamp
699
+ };
700
+ }
701
+ emptyB2Stats(timestamp) {
702
+ return {
703
+ b2BytesStoredCount: 0,
704
+ b2FilesStoredCount: 0,
705
+ b2StatsAsOfTimestamp: b2FriendlyTimestamp(timestamp),
706
+ bucketCount: 0
707
+ };
708
+ }
709
+ };
710
+ //#endregion
711
+ exports.PartnerSimulator = PartnerSimulator;
712
+
713
+ //# sourceMappingURL=partner.cjs.map