@backblaze-labs/b2-sdk 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (393) hide show
  1. package/CHANGELOG.md +45 -1
  2. package/README.md +18 -5
  3. package/dist/_virtual/_b2-sdk-version-json.cjs +1 -1
  4. package/dist/_virtual/_b2-sdk-version-json.js +1 -1
  5. package/dist/auth/reauth-coalescer.cjs +65 -0
  6. package/dist/auth/reauth-coalescer.cjs.map +1 -0
  7. package/dist/auth/reauth-coalescer.d.cts +34 -0
  8. package/dist/auth/reauth-coalescer.d.cts.map +1 -0
  9. package/dist/auth/reauth-coalescer.d.ts +34 -0
  10. package/dist/auth/reauth-coalescer.d.ts.map +1 -0
  11. package/dist/auth/reauth-coalescer.js +65 -0
  12. package/dist/auth/reauth-coalescer.js.map +1 -0
  13. package/dist/backup/raw.cjs +37 -15
  14. package/dist/backup/raw.cjs.map +1 -1
  15. package/dist/backup/raw.d.cts +2 -2
  16. package/dist/backup/raw.d.cts.map +1 -1
  17. package/dist/backup/raw.d.ts +2 -2
  18. package/dist/backup/raw.d.ts.map +1 -1
  19. package/dist/backup/raw.js +37 -15
  20. package/dist/backup/raw.js.map +1 -1
  21. package/dist/bucket-validation.cjs +111 -0
  22. package/dist/bucket-validation.cjs.map +1 -0
  23. package/dist/bucket-validation.d.cts +27 -0
  24. package/dist/bucket-validation.d.cts.map +1 -0
  25. package/dist/bucket-validation.d.ts +27 -0
  26. package/dist/bucket-validation.d.ts.map +1 -0
  27. package/dist/bucket-validation.js +109 -0
  28. package/dist/bucket-validation.js.map +1 -0
  29. package/dist/bucket.cjs +123 -73
  30. package/dist/bucket.cjs.map +1 -1
  31. package/dist/bucket.d.cts +156 -61
  32. package/dist/bucket.d.cts.map +1 -1
  33. package/dist/bucket.d.ts +156 -61
  34. package/dist/bucket.d.ts.map +1 -1
  35. package/dist/bucket.js +123 -73
  36. package/dist/bucket.js.map +1 -1
  37. package/dist/client.cjs +29 -8
  38. package/dist/client.cjs.map +1 -1
  39. package/dist/client.d.cts +30 -9
  40. package/dist/client.d.cts.map +1 -1
  41. package/dist/client.d.ts +30 -9
  42. package/dist/client.d.ts.map +1 -1
  43. package/dist/client.js +29 -8
  44. package/dist/client.js.map +1 -1
  45. package/dist/download/single.cjs +38 -13
  46. package/dist/download/single.cjs.map +1 -1
  47. package/dist/download/single.d.cts +10 -4
  48. package/dist/download/single.d.cts.map +1 -1
  49. package/dist/download/single.d.ts +10 -4
  50. package/dist/download/single.d.ts.map +1 -1
  51. package/dist/download/single.js +38 -13
  52. package/dist/download/single.js.map +1 -1
  53. package/dist/errors/index.cjs +27 -4
  54. package/dist/errors/index.cjs.map +1 -1
  55. package/dist/errors/index.d.cts +15 -0
  56. package/dist/errors/index.d.cts.map +1 -1
  57. package/dist/errors/index.d.ts +15 -0
  58. package/dist/errors/index.d.ts.map +1 -1
  59. package/dist/errors/index.js +27 -5
  60. package/dist/errors/index.js.map +1 -1
  61. package/dist/http/non-idempotent-mutations.cjs +38 -0
  62. package/dist/http/non-idempotent-mutations.cjs.map +1 -0
  63. package/dist/http/non-idempotent-mutations.d.cts +25 -0
  64. package/dist/http/non-idempotent-mutations.d.cts.map +1 -0
  65. package/dist/http/non-idempotent-mutations.d.ts +25 -0
  66. package/dist/http/non-idempotent-mutations.d.ts.map +1 -0
  67. package/dist/http/non-idempotent-mutations.js +35 -0
  68. package/dist/http/non-idempotent-mutations.js.map +1 -0
  69. package/dist/http/transport.cjs +9 -8
  70. package/dist/http/transport.cjs.map +1 -1
  71. package/dist/http/transport.d.cts +5 -0
  72. package/dist/http/transport.d.cts.map +1 -1
  73. package/dist/http/transport.d.ts +5 -0
  74. package/dist/http/transport.d.ts.map +1 -1
  75. package/dist/http/transport.js +9 -8
  76. package/dist/http/transport.js.map +1 -1
  77. package/dist/http/user-agent.cjs +12 -1
  78. package/dist/http/user-agent.cjs.map +1 -1
  79. package/dist/http/user-agent.d.cts +8 -0
  80. package/dist/http/user-agent.d.cts.map +1 -1
  81. package/dist/http/user-agent.d.ts +8 -0
  82. package/dist/http/user-agent.d.ts.map +1 -1
  83. package/dist/http/user-agent.js +13 -3
  84. package/dist/http/user-agent.js.map +1 -1
  85. package/dist/index.cjs +25 -0
  86. package/dist/index.d.cts +10 -9
  87. package/dist/index.d.cts.map +1 -1
  88. package/dist/index.d.ts +10 -9
  89. package/dist/index.d.ts.map +1 -1
  90. package/dist/index.js +7 -6
  91. package/dist/notifications/index.cjs +3 -0
  92. package/dist/notifications/index.d.cts +2 -0
  93. package/dist/notifications/index.d.cts.map +1 -1
  94. package/dist/notifications/index.d.ts +2 -0
  95. package/dist/notifications/index.d.ts.map +1 -1
  96. package/dist/notifications/index.js +2 -1
  97. package/dist/object.cjs +12 -1
  98. package/dist/object.cjs.map +1 -1
  99. package/dist/object.d.cts +7 -1
  100. package/dist/object.d.cts.map +1 -1
  101. package/dist/object.d.ts +7 -1
  102. package/dist/object.d.ts.map +1 -1
  103. package/dist/object.js +12 -1
  104. package/dist/object.js.map +1 -1
  105. package/dist/partner/auth-core.cjs +4 -23
  106. package/dist/partner/auth-core.cjs.map +1 -1
  107. package/dist/partner/auth-core.d.cts +1 -1
  108. package/dist/partner/auth-core.d.cts.map +1 -1
  109. package/dist/partner/auth-core.d.ts +1 -1
  110. package/dist/partner/auth-core.d.ts.map +1 -1
  111. package/dist/partner/auth-core.js +5 -24
  112. package/dist/partner/auth-core.js.map +1 -1
  113. package/dist/partner/client.cjs +25 -10
  114. package/dist/partner/client.cjs.map +1 -1
  115. package/dist/partner/client.d.cts +32 -10
  116. package/dist/partner/client.d.cts.map +1 -1
  117. package/dist/partner/client.d.ts +32 -10
  118. package/dist/partner/client.d.ts.map +1 -1
  119. package/dist/partner/client.js +25 -10
  120. package/dist/partner/client.js.map +1 -1
  121. package/dist/partner/endpoint-url.cjs +1 -0
  122. package/dist/partner/endpoint-url.cjs.map +1 -1
  123. package/dist/partner/endpoint-url.d.cts +2 -0
  124. package/dist/partner/endpoint-url.d.cts.map +1 -1
  125. package/dist/partner/endpoint-url.d.ts +2 -0
  126. package/dist/partner/endpoint-url.d.ts.map +1 -1
  127. package/dist/partner/endpoint-url.js +1 -0
  128. package/dist/partner/endpoint-url.js.map +1 -1
  129. package/dist/partner/in-memory.cjs.map +1 -1
  130. package/dist/partner/in-memory.js.map +1 -1
  131. package/dist/partner/index.cjs +9 -0
  132. package/dist/partner/index.d.cts +11 -2
  133. package/dist/partner/index.d.cts.map +1 -1
  134. package/dist/partner/index.d.ts +11 -2
  135. package/dist/partner/index.d.ts.map +1 -1
  136. package/dist/partner/index.js +3 -1
  137. package/dist/partner/raw.cjs +52 -44
  138. package/dist/partner/raw.cjs.map +1 -1
  139. package/dist/partner/raw.d.cts +16 -19
  140. package/dist/partner/raw.d.cts.map +1 -1
  141. package/dist/partner/raw.d.ts +16 -19
  142. package/dist/partner/raw.d.ts.map +1 -1
  143. package/dist/partner/raw.js +52 -44
  144. package/dist/partner/raw.js.map +1 -1
  145. package/dist/partner/redaction.cjs +133 -108
  146. package/dist/partner/redaction.cjs.map +1 -1
  147. package/dist/partner/redaction.d.cts +47 -13
  148. package/dist/partner/redaction.d.cts.map +1 -1
  149. package/dist/partner/redaction.d.ts +47 -13
  150. package/dist/partner/redaction.d.ts.map +1 -1
  151. package/dist/partner/redaction.js +133 -109
  152. package/dist/partner/redaction.js.map +1 -1
  153. package/dist/raw/encoding.cjs +29 -10
  154. package/dist/raw/encoding.cjs.map +1 -1
  155. package/dist/raw/encoding.d.cts +3 -2
  156. package/dist/raw/encoding.d.cts.map +1 -1
  157. package/dist/raw/encoding.d.ts +3 -2
  158. package/dist/raw/encoding.d.ts.map +1 -1
  159. package/dist/raw/encoding.js +29 -10
  160. package/dist/raw/encoding.js.map +1 -1
  161. package/dist/raw/index.cjs +64 -39
  162. package/dist/raw/index.cjs.map +1 -1
  163. package/dist/raw/index.d.cts +21 -19
  164. package/dist/raw/index.d.cts.map +1 -1
  165. package/dist/raw/index.d.ts +21 -19
  166. package/dist/raw/index.d.ts.map +1 -1
  167. package/dist/raw/index.js +47 -40
  168. package/dist/raw/index.js.map +1 -1
  169. package/dist/raw/url.cjs.map +1 -1
  170. package/dist/raw/url.d.cts +3 -3
  171. package/dist/raw/url.d.ts +3 -3
  172. package/dist/raw/url.js.map +1 -1
  173. package/dist/simulator/index.cjs +456 -125
  174. package/dist/simulator/index.cjs.map +1 -1
  175. package/dist/simulator/index.d.cts +16 -1
  176. package/dist/simulator/index.d.cts.map +1 -1
  177. package/dist/simulator/index.d.ts +16 -1
  178. package/dist/simulator/index.d.ts.map +1 -1
  179. package/dist/simulator/index.js +449 -130
  180. package/dist/simulator/index.js.map +1 -1
  181. package/dist/simulator/partner-capabilities.cjs +77 -0
  182. package/dist/simulator/partner-capabilities.cjs.map +1 -0
  183. package/dist/simulator/partner-capabilities.d.cts +53 -0
  184. package/dist/simulator/partner-capabilities.d.cts.map +1 -0
  185. package/dist/simulator/partner-capabilities.d.ts +53 -0
  186. package/dist/simulator/partner-capabilities.d.ts.map +1 -0
  187. package/dist/simulator/partner-capabilities.js +73 -0
  188. package/dist/simulator/partner-capabilities.js.map +1 -0
  189. package/dist/simulator/partner.cjs +55 -61
  190. package/dist/simulator/partner.cjs.map +1 -1
  191. package/dist/simulator/partner.d.cts +5 -2
  192. package/dist/simulator/partner.d.cts.map +1 -1
  193. package/dist/simulator/partner.d.ts +5 -2
  194. package/dist/simulator/partner.d.ts.map +1 -1
  195. package/dist/simulator/partner.js +56 -61
  196. package/dist/simulator/partner.js.map +1 -1
  197. package/dist/simulator/validation.cjs +160 -30
  198. package/dist/simulator/validation.cjs.map +1 -1
  199. package/dist/simulator/validation.d.cts +28 -6
  200. package/dist/simulator/validation.d.cts.map +1 -1
  201. package/dist/simulator/validation.d.ts +28 -6
  202. package/dist/simulator/validation.d.ts.map +1 -1
  203. package/dist/simulator/validation.js +148 -31
  204. package/dist/simulator/validation.js.map +1 -1
  205. package/dist/streams/file-source.cjs +1 -1
  206. package/dist/streams/file-source.cjs.map +1 -1
  207. package/dist/streams/file-source.js +1 -1
  208. package/dist/streams/file-source.js.map +1 -1
  209. package/dist/streams/hash.cjs +246 -13
  210. package/dist/streams/hash.cjs.map +1 -1
  211. package/dist/streams/hash.d.cts +37 -12
  212. package/dist/streams/hash.d.cts.map +1 -1
  213. package/dist/streams/hash.d.ts +37 -12
  214. package/dist/streams/hash.d.ts.map +1 -1
  215. package/dist/streams/hash.js +246 -15
  216. package/dist/streams/hash.js.map +1 -1
  217. package/dist/streams/index.cjs +2 -0
  218. package/dist/streams/index.d.cts +1 -1
  219. package/dist/streams/index.d.cts.map +1 -1
  220. package/dist/streams/index.d.ts +1 -1
  221. package/dist/streams/index.d.ts.map +1 -1
  222. package/dist/streams/index.js +2 -2
  223. package/dist/streams/progress.cjs +63 -4
  224. package/dist/streams/progress.cjs.map +1 -1
  225. package/dist/streams/progress.d.cts +28 -2
  226. package/dist/streams/progress.d.cts.map +1 -1
  227. package/dist/streams/progress.d.ts +28 -2
  228. package/dist/streams/progress.d.ts.map +1 -1
  229. package/dist/streams/progress.js +63 -4
  230. package/dist/streams/progress.js.map +1 -1
  231. package/dist/sync/download-staging.cjs +147 -35
  232. package/dist/sync/download-staging.cjs.map +1 -1
  233. package/dist/sync/download-staging.d.cts +25 -2
  234. package/dist/sync/download-staging.d.cts.map +1 -1
  235. package/dist/sync/download-staging.d.ts +25 -2
  236. package/dist/sync/download-staging.d.ts.map +1 -1
  237. package/dist/sync/download-staging.js +146 -36
  238. package/dist/sync/download-staging.js.map +1 -1
  239. package/dist/sync/index.d.cts +1 -1
  240. package/dist/sync/index.d.cts.map +1 -1
  241. package/dist/sync/index.d.ts +1 -1
  242. package/dist/sync/index.d.ts.map +1 -1
  243. package/dist/sync/local-file-io.cjs +5 -1
  244. package/dist/sync/local-file-io.cjs.map +1 -1
  245. package/dist/sync/local-file-io.d.cts +2 -0
  246. package/dist/sync/local-file-io.d.cts.map +1 -1
  247. package/dist/sync/local-file-io.d.ts +2 -0
  248. package/dist/sync/local-file-io.d.ts.map +1 -1
  249. package/dist/sync/local-file-io.js +5 -1
  250. package/dist/sync/local-file-io.js.map +1 -1
  251. package/dist/sync/pairing.cjs +1 -0
  252. package/dist/sync/pairing.cjs.map +1 -1
  253. package/dist/sync/pairing.js +1 -0
  254. package/dist/sync/pairing.js.map +1 -1
  255. package/dist/sync/scanners/b2.cjs +2 -0
  256. package/dist/sync/scanners/b2.cjs.map +1 -1
  257. package/dist/sync/scanners/b2.d.cts.map +1 -1
  258. package/dist/sync/scanners/b2.d.ts.map +1 -1
  259. package/dist/sync/scanners/b2.js +2 -0
  260. package/dist/sync/scanners/b2.js.map +1 -1
  261. package/dist/sync/scanners/local.cjs +150 -33
  262. package/dist/sync/scanners/local.cjs.map +1 -1
  263. package/dist/sync/scanners/local.d.cts +6 -0
  264. package/dist/sync/scanners/local.d.cts.map +1 -1
  265. package/dist/sync/scanners/local.d.ts +6 -0
  266. package/dist/sync/scanners/local.d.ts.map +1 -1
  267. package/dist/sync/scanners/local.js +150 -33
  268. package/dist/sync/scanners/local.js.map +1 -1
  269. package/dist/sync/synchronizer.cjs +76 -29
  270. package/dist/sync/synchronizer.cjs.map +1 -1
  271. package/dist/sync/synchronizer.d.cts +1 -0
  272. package/dist/sync/synchronizer.d.cts.map +1 -1
  273. package/dist/sync/synchronizer.d.ts +1 -0
  274. package/dist/sync/synchronizer.d.ts.map +1 -1
  275. package/dist/sync/synchronizer.js +76 -29
  276. package/dist/sync/synchronizer.js.map +1 -1
  277. package/dist/sync/types.d.cts +19 -3
  278. package/dist/sync/types.d.cts.map +1 -1
  279. package/dist/sync/types.d.ts +19 -3
  280. package/dist/sync/types.d.ts.map +1 -1
  281. package/dist/types/backup.d.cts +6 -1
  282. package/dist/types/backup.d.cts.map +1 -1
  283. package/dist/types/backup.d.ts +6 -1
  284. package/dist/types/backup.d.ts.map +1 -1
  285. package/dist/types/bucket.cjs +81 -11
  286. package/dist/types/bucket.cjs.map +1 -1
  287. package/dist/types/bucket.d.cts +190 -39
  288. package/dist/types/bucket.d.cts.map +1 -1
  289. package/dist/types/bucket.d.ts +190 -39
  290. package/dist/types/bucket.d.ts.map +1 -1
  291. package/dist/types/bucket.js +67 -12
  292. package/dist/types/bucket.js.map +1 -1
  293. package/dist/types/download.cjs.map +1 -1
  294. package/dist/types/download.d.cts +3 -17
  295. package/dist/types/download.d.cts.map +1 -1
  296. package/dist/types/download.d.ts +3 -17
  297. package/dist/types/download.d.ts.map +1 -1
  298. package/dist/types/download.js.map +1 -1
  299. package/dist/types/encryption.cjs +18 -0
  300. package/dist/types/encryption.cjs.map +1 -1
  301. package/dist/types/encryption.d.cts +21 -11
  302. package/dist/types/encryption.d.cts.map +1 -1
  303. package/dist/types/encryption.d.ts +21 -11
  304. package/dist/types/encryption.d.ts.map +1 -1
  305. package/dist/types/encryption.js +18 -0
  306. package/dist/types/encryption.js.map +1 -1
  307. package/dist/types/file.cjs +3 -0
  308. package/dist/types/file.cjs.map +1 -1
  309. package/dist/types/file.d.cts +125 -16
  310. package/dist/types/file.d.cts.map +1 -1
  311. package/dist/types/file.d.ts +125 -16
  312. package/dist/types/file.d.ts.map +1 -1
  313. package/dist/types/file.js +3 -1
  314. package/dist/types/file.js.map +1 -1
  315. package/dist/types/index.d.cts +7 -7
  316. package/dist/types/index.d.cts.map +1 -1
  317. package/dist/types/index.d.ts +7 -7
  318. package/dist/types/index.d.ts.map +1 -1
  319. package/dist/types/key.d.cts +4 -3
  320. package/dist/types/key.d.cts.map +1 -1
  321. package/dist/types/key.d.ts +4 -3
  322. package/dist/types/key.d.ts.map +1 -1
  323. package/dist/types/notifications.cjs +30 -0
  324. package/dist/types/notifications.cjs.map +1 -1
  325. package/dist/types/notifications.d.cts +26 -1
  326. package/dist/types/notifications.d.cts.map +1 -1
  327. package/dist/types/notifications.d.ts +26 -1
  328. package/dist/types/notifications.d.ts.map +1 -1
  329. package/dist/types/notifications.js +29 -1
  330. package/dist/types/notifications.js.map +1 -1
  331. package/dist/types/partner.cjs.map +1 -1
  332. package/dist/types/partner.d.cts +28 -36
  333. package/dist/types/partner.d.cts.map +1 -1
  334. package/dist/types/partner.d.ts +28 -36
  335. package/dist/types/partner.d.ts.map +1 -1
  336. package/dist/types/partner.js.map +1 -1
  337. package/dist/types/upload.d.cts +4 -0
  338. package/dist/types/upload.d.cts.map +1 -1
  339. package/dist/types/upload.d.ts +4 -0
  340. package/dist/types/upload.d.ts.map +1 -1
  341. package/dist/upload/large.cjs +10 -7
  342. package/dist/upload/large.cjs.map +1 -1
  343. package/dist/upload/large.d.cts +15 -6
  344. package/dist/upload/large.d.cts.map +1 -1
  345. package/dist/upload/large.d.ts +15 -6
  346. package/dist/upload/large.d.ts.map +1 -1
  347. package/dist/upload/large.js +10 -7
  348. package/dist/upload/large.js.map +1 -1
  349. package/dist/upload/options.cjs.map +1 -1
  350. package/dist/upload/options.d.cts +12 -0
  351. package/dist/upload/options.d.cts.map +1 -1
  352. package/dist/upload/options.d.ts +12 -0
  353. package/dist/upload/options.d.ts.map +1 -1
  354. package/dist/upload/options.js.map +1 -1
  355. package/dist/upload/resume.cjs +4 -3
  356. package/dist/upload/resume.cjs.map +1 -1
  357. package/dist/upload/resume.d.cts +6 -4
  358. package/dist/upload/resume.d.cts.map +1 -1
  359. package/dist/upload/resume.d.ts +6 -4
  360. package/dist/upload/resume.d.ts.map +1 -1
  361. package/dist/upload/resume.js +4 -3
  362. package/dist/upload/resume.js.map +1 -1
  363. package/dist/upload/retry.cjs +17 -10
  364. package/dist/upload/retry.cjs.map +1 -1
  365. package/dist/upload/retry.d.cts.map +1 -1
  366. package/dist/upload/retry.d.ts.map +1 -1
  367. package/dist/upload/retry.js +17 -10
  368. package/dist/upload/retry.js.map +1 -1
  369. package/dist/upload/single.cjs +35 -31
  370. package/dist/upload/single.cjs.map +1 -1
  371. package/dist/upload/single.d.cts +6 -0
  372. package/dist/upload/single.d.cts.map +1 -1
  373. package/dist/upload/single.d.ts +6 -0
  374. package/dist/upload/single.d.ts.map +1 -1
  375. package/dist/upload/single.js +35 -31
  376. package/dist/upload/single.js.map +1 -1
  377. package/dist/upload/stream.cjs +12 -1
  378. package/dist/upload/stream.cjs.map +1 -1
  379. package/dist/upload/stream.d.cts +6 -0
  380. package/dist/upload/stream.d.cts.map +1 -1
  381. package/dist/upload/stream.d.ts +6 -0
  382. package/dist/upload/stream.d.ts.map +1 -1
  383. package/dist/upload/stream.js +12 -1
  384. package/dist/upload/stream.js.map +1 -1
  385. package/dist/version.cjs +56 -4
  386. package/dist/version.cjs.map +1 -1
  387. package/dist/version.d.cts +53 -4
  388. package/dist/version.d.cts.map +1 -1
  389. package/dist/version.d.ts +53 -4
  390. package/dist/version.d.ts.map +1 -1
  391. package/dist/version.js +52 -5
  392. package/dist/version.js.map +1 -1
  393. package/package.json +11 -4
@@ -8,14 +8,40 @@ export interface RedactedPartnerAuthorizeResponseJson extends Omit<PartnerAuthor
8
8
  /** Redacted Partner authorization token placeholder. */
9
9
  readonly authorizationToken: string;
10
10
  }
11
+ /**
12
+ * JSON-safe create-group-member result with the one-time application key
13
+ * secret replaced by a placeholder string.
14
+ *
15
+ * @experimental Partner API surface; shape may change as the Partner API docs evolve.
16
+ */
11
17
  export type RedactedCreateGroupMemberResultJson = Omit<CreateGroupMemberResult, 'applicationKey'> & {
18
+ /** Redacted application key secret placeholder. */
12
19
  readonly applicationKey: string;
13
20
  };
14
- export type RedactedCreateGroupMemberResponseJson = readonly RedactedCreateGroupMemberResultJson[];
21
+ /**
22
+ * JSON-safe create-group-member response with the one-time application key
23
+ * secret replaced by a placeholder string.
24
+ *
25
+ * @experimental Partner API surface; shape may change as the Partner API docs evolve.
26
+ */
27
+ export type RedactedCreateGroupMemberResponseJson = RedactedCreateGroupMemberResultJson;
28
+ /**
29
+ * JSON-safe reserve-trial account result with the one-time application key
30
+ * secret replaced by a placeholder string.
31
+ *
32
+ * @experimental Partner API surface; shape may change as the Partner API docs evolve.
33
+ */
15
34
  export type RedactedReserveTrialCreateAccountResultJson = Omit<ReserveTrialCreateAccountResult, 'applicationKey'> & {
35
+ /** Redacted application key secret placeholder. */
16
36
  readonly applicationKey: string;
17
37
  };
18
- export type RedactedReserveTrialCreateAccountResponseJson = readonly RedactedReserveTrialCreateAccountResultJson[];
38
+ /**
39
+ * JSON-safe reserve-trial account response with the one-time application key
40
+ * secret replaced by a placeholder string.
41
+ *
42
+ * @experimental Partner API surface; shape may change as the Partner API docs evolve.
43
+ */
44
+ export type RedactedReserveTrialCreateAccountResponseJson = RedactedReserveTrialCreateAccountResultJson;
19
45
  /**
20
46
  * Returns a redacted copy for log serializers that intentionally hide tokens.
21
47
  *
@@ -30,6 +56,8 @@ export declare function partnerAuthorizeResponseToRedactedJson(auth: PartnerAuth
30
56
  * @param result - Create group member result to render safely.
31
57
  *
32
58
  * @returns A plain object with the application key secret replaced by a placeholder.
59
+ *
60
+ * @experimental Partner API surface; shape may change as the Partner API docs evolve.
33
61
  */
34
62
  export declare function createGroupMemberResultToRedactedJson(result: CreateGroupMemberResult): RedactedCreateGroupMemberResultJson;
35
63
  /**
@@ -37,7 +65,9 @@ export declare function createGroupMemberResultToRedactedJson(result: CreateGrou
37
65
  *
38
66
  * @param response - Create group member response to render safely.
39
67
  *
40
- * @returns A plain array with every application key secret replaced by a placeholder.
68
+ * @returns A plain object with the application key secret replaced by a placeholder.
69
+ *
70
+ * @experimental Partner API surface; shape may change as the Partner API docs evolve.
41
71
  */
42
72
  export declare function createGroupMemberResponseToRedactedJson(response: CreateGroupMemberResponse): RedactedCreateGroupMemberResponseJson;
43
73
  /**
@@ -46,6 +76,8 @@ export declare function createGroupMemberResponseToRedactedJson(response: Create
46
76
  * @param result - Reserve trial account result to render safely.
47
77
  *
48
78
  * @returns A plain object with the application key secret replaced by a placeholder.
79
+ *
80
+ * @experimental Partner API surface; shape may change as the Partner API docs evolve.
49
81
  */
50
82
  export declare function reserveTrialCreateAccountResultToRedactedJson(result: ReserveTrialCreateAccountResult): RedactedReserveTrialCreateAccountResultJson;
51
83
  /**
@@ -53,7 +85,9 @@ export declare function reserveTrialCreateAccountResultToRedactedJson(result: Re
53
85
  *
54
86
  * @param response - Reserve trial account response to render safely.
55
87
  *
56
- * @returns A plain array with every application key secret replaced by a placeholder.
88
+ * @returns A plain object with the application key secret replaced by a placeholder.
89
+ *
90
+ * @experimental Partner API surface; shape may change as the Partner API docs evolve.
57
91
  */
58
92
  export declare function reserveTrialCreateAccountResponseToRedactedJson(response: ReserveTrialCreateAccountResponse): RedactedReserveTrialCreateAccountResponseJson;
59
93
  /**
@@ -86,14 +120,14 @@ export declare function redactPartnerAuthorizeResponse(auth: PartnerAuthorizeRes
86
120
  */
87
121
  export declare function redactCreateGroupMemberResult(result: CreateGroupMemberResult): CreateGroupMemberResult;
88
122
  /**
89
- * Adds non-enumerable serialization and inspection hooks that redact all
90
- * create-group-member application key secrets while preserving direct access.
123
+ * Adds non-enumerable serialization and inspection hooks that redact the
124
+ * create-group-member application key secret while preserving direct access.
91
125
  *
92
126
  * @param response - Create group member response to protect from accidental logging.
93
127
  *
94
- * @returns The same response array with redaction hooks installed when possible.
128
+ * @returns The same response object with redaction hooks installed when possible.
95
129
  *
96
- * @throws B2PartnerAuthorizationError if the response is not an array.
130
+ * @throws B2PartnerAuthorizationError if the response carries no usable application key.
97
131
  */
98
132
  export declare function redactCreateGroupMemberResponse(response: CreateGroupMemberResponse): CreateGroupMemberResponse;
99
133
  /**
@@ -101,7 +135,7 @@ export declare function redactCreateGroupMemberResponse(response: CreateGroupMem
101
135
  * application key secret while preserving direct property access.
102
136
  *
103
137
  * `JSON.stringify` redacts because the response contains newly minted
104
- * application key secrets that are commonly logged as batch results. Callers
138
+ * application key secrets that are commonly logged with responses. Callers
105
139
  * that need to persist the key should read `applicationKey` directly into
106
140
  * secure storage before serializing the object.
107
141
  *
@@ -111,14 +145,14 @@ export declare function redactCreateGroupMemberResponse(response: CreateGroupMem
111
145
  */
112
146
  export declare function redactReserveTrialCreateAccountResult(result: ReserveTrialCreateAccountResult): ReserveTrialCreateAccountResult;
113
147
  /**
114
- * Adds non-enumerable serialization and inspection hooks that redact all
115
- * reserve-trial application key secrets while preserving direct property access.
148
+ * Adds non-enumerable serialization and inspection hooks that redact the
149
+ * reserve-trial application key secret while preserving direct property access.
116
150
  *
117
151
  * @param response - Reserve trial account response to protect from accidental logging.
118
152
  *
119
- * @returns The same response array with redaction hooks installed when possible.
153
+ * @returns The same response object with redaction hooks installed when possible.
120
154
  *
121
- * @throws B2PartnerAuthorizationError if the response is not an array.
155
+ * @throws B2PartnerAuthorizationError if the response carries no usable application key.
122
156
  */
123
157
  export declare function redactReserveTrialCreateAccountResponse(response: ReserveTrialCreateAccountResponse): ReserveTrialCreateAccountResponse;
124
158
  //# sourceMappingURL=redaction.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"redaction.d.ts","sourceRoot":"","sources":["../../src/partner/redaction.js"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,yBAAyB,EACzB,uBAAuB,EACvB,wBAAwB,EACxB,iCAAiC,EACjC,+BAA+B,EAChC,MAAM,qBAAqB,CAAA;AAG5B,OAAO,EACL,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,6BAA6B,CAAA;AAEpC;;;GAGG;AACH,MAAM,WAAW,oCACf,SAAQ,IAAI,CAAC,wBAAwB,EAAE,oBAAoB,CAAC;IAC5D,wDAAwD;IACxD,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAA;CACpC;AAED,MAAM,MAAM,mCAAmC,GAAG,IAAI,CACpD,uBAAuB,EACvB,gBAAgB,CACjB,GAAG;IACF,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;CAChC,CAAA;AAED,MAAM,MAAM,qCAAqC,GAAG,SAAS,mCAAmC,EAAE,CAAA;AAElG,MAAM,MAAM,2CAA2C,GAAG,IAAI,CAC5D,+BAA+B,EAC/B,gBAAgB,CACjB,GAAG;IACF,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;CAChC,CAAA;AAED,MAAM,MAAM,6CAA6C,GACvD,SAAS,2CAA2C,EAAE,CAAA;AAsBxD;;;;;;GAMG;AACH,wBAAgB,sCAAsC,CACpD,IAAI,EAAE,wBAAwB,GAC7B,oCAAoC,CAKtC;AAED;;;;;;GAMG;AACH,wBAAgB,qCAAqC,CACnD,MAAM,EAAE,uBAAuB,GAC9B,mCAAmC,CAKrC;AAED;;;;;;GAMG;AACH,wBAAgB,uCAAuC,CACrD,QAAQ,EAAE,yBAAyB,GAClC,qCAAqC,CAEvC;AAED;;;;;;GAMG;AACH,wBAAgB,6CAA6C,CAC3D,MAAM,EAAE,+BAA+B,GACtC,2CAA2C,CAK7C;AAED;;;;;;GAMG;AACH,wBAAgB,+CAA+C,CAC7D,QAAQ,EAAE,iCAAiC,GAC1C,6CAA6C,CAE/C;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,wBAAwB,GAC7B,wBAAwB,CAqB1B;AAED;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,uBAAuB,GAC9B,uBAAuB,CAqBzB;AAED;;;;;;;;;GASG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,yBAAyB,GAClC,yBAAyB,CAmC3B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qCAAqC,CACnD,MAAM,EAAE,+BAA+B,GACtC,+BAA+B,CAsBjC;AAED;;;;;;;;;GASG;AACH,wBAAgB,uCAAuC,CACrD,QAAQ,EAAE,iCAAiC,GAC1C,iCAAiC,CAsCnC"}
1
+ {"version":3,"file":"redaction.d.ts","sourceRoot":"","sources":["../../src/partner/redaction.js"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,yBAAyB,EACzB,uBAAuB,EAEvB,wBAAwB,EAKxB,iCAAiC,EACjC,+BAA+B,EAChC,MAAM,qBAAqB,CAAA;AAG5B,OAAO,EACL,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,6BAA6B,CAAA;AAEpC;;;GAGG;AACH,MAAM,WAAW,oCACf,SAAQ,IAAI,CAAC,wBAAwB,EAAE,oBAAoB,CAAC;IAC5D,wDAAwD;IACxD,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAA;CACpC;AAED;;;;;GAKG;AACH,MAAM,MAAM,mCAAmC,GAAG,IAAI,CACpD,uBAAuB,EACvB,gBAAgB,CACjB,GAAG;IACF,mDAAmD;IACnD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;CAChC,CAAA;AAED;;;;;GAKG;AACH,MAAM,MAAM,qCAAqC,GAAG,mCAAmC,CAAA;AAEvF;;;;;GAKG;AACH,MAAM,MAAM,2CAA2C,GAAG,IAAI,CAC5D,+BAA+B,EAC/B,gBAAgB,CACjB,GAAG;IACF,mDAAmD;IACnD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;CAChC,CAAA;AAED;;;;;GAKG;AACH,MAAM,MAAM,6CAA6C,GACvD,2CAA2C,CAAA;AAiK7C;;;;;;GAMG;AACH,wBAAgB,sCAAsC,CACpD,IAAI,EAAE,wBAAwB,GAC7B,oCAAoC,CAgBtC;AAED;;;;;;;;GAQG;AACH,wBAAgB,qCAAqC,CACnD,MAAM,EAAE,uBAAuB,GAC9B,mCAAmC,CAMrC;AAED;;;;;;;;GAQG;AACH,wBAAgB,uCAAuC,CACrD,QAAQ,EAAE,yBAAyB,GAClC,qCAAqC,CAEvC;AAED;;;;;;;;GAQG;AACH,wBAAgB,6CAA6C,CAC3D,MAAM,EAAE,+BAA+B,GACtC,2CAA2C,CAY7C;AAED;;;;;;;;GAQG;AACH,wBAAgB,+CAA+C,CAC7D,QAAQ,EAAE,iCAAiC,GAC1C,6CAA6C,CAE/C;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,wBAAwB,GAC7B,wBAAwB,CAqB1B;AAED;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,uBAAuB,GAC9B,uBAAuB,CAMzB;AAED;;;;;;;;;GASG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,yBAAyB,GAClC,yBAAyB,CAiB3B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qCAAqC,CACnD,MAAM,EAAE,+BAA+B,GACtC,+BAA+B,CAMjC;AAED;;;;;;;;;GASG;AACH,wBAAgB,uCAAuC,CACrD,QAAQ,EAAE,iCAAiC,GAC1C,iCAAiC,CAiBnC"}
@@ -2,6 +2,69 @@ import { B2PartnerAuthorizationError } from "../errors/index.js";
2
2
  import { APPLICATION_KEY_REDACTED, PARTNER_TOKEN_REDACTED } from "./redaction-placeholders.js";
3
3
  //#region src/partner/redaction.ts
4
4
  var inspectSymbol = Symbol.for("nodejs.util.inspect.custom");
5
+ function partnerGroupsApiInfoToRedactedJson(info) {
6
+ return {
7
+ capabilities: [...info.capabilities],
8
+ groupsApiUrl: info.groupsApiUrl,
9
+ infoType: info.infoType
10
+ };
11
+ }
12
+ function partnerBackupApiInfoToRedactedJson(info) {
13
+ return {
14
+ capabilities: [...info.capabilities],
15
+ backupApiUrl: info.backupApiUrl,
16
+ infoType: info.infoType
17
+ };
18
+ }
19
+ function partnerStorageApiInfoToRedactedJson(info) {
20
+ return {
21
+ absoluteMinimumPartSize: info.absoluteMinimumPartSize,
22
+ apiUrl: info.apiUrl,
23
+ bucketId: info.bucketId,
24
+ bucketName: info.bucketName,
25
+ capabilities: [...info.capabilities],
26
+ downloadUrl: info.downloadUrl,
27
+ infoType: info.infoType,
28
+ namePrefix: info.namePrefix,
29
+ recommendedPartSize: info.recommendedPartSize,
30
+ s3ApiUrl: info.s3ApiUrl
31
+ };
32
+ }
33
+ function partnerApiInfoToRedactedJson(apiInfo) {
34
+ const redacted = {};
35
+ if (apiInfo.storageApi !== void 0) redacted.storageApi = partnerStorageApiInfoToRedactedJson(apiInfo.storageApi);
36
+ if (apiInfo.groupsApi !== void 0) redacted.groupsApi = partnerGroupsApiInfoToRedactedJson(apiInfo.groupsApi);
37
+ if (apiInfo.backupApi !== void 0) redacted.backupApi = partnerBackupApiInfoToRedactedJson(apiInfo.backupApi);
38
+ return redacted;
39
+ }
40
+ function partnerGroupMemberToRedactedJson(groupMember) {
41
+ return {
42
+ accountId: groupMember.accountId,
43
+ email: groupMember.email,
44
+ groupId: groupMember.groupId,
45
+ groupName: groupMember.groupName,
46
+ region: groupMember.region,
47
+ s3Endpoint: groupMember.s3Endpoint
48
+ };
49
+ }
50
+ function isSingleJsonObject(value) {
51
+ return typeof value === "object" && value !== null && !Array.isArray(value);
52
+ }
53
+ function isCredentialBearing(response) {
54
+ return isSingleJsonObject(response) && typeof response["applicationKey"] === "string" && typeof response["applicationKeyId"] === "string";
55
+ }
56
+ function matchesGroupMemberShape(groupMember) {
57
+ return isSingleJsonObject(groupMember) && typeof groupMember["accountId"] === "string" && typeof groupMember["email"] === "string" && typeof groupMember["groupId"] === "string" && typeof groupMember["groupName"] === "string" && typeof groupMember["region"] === "string" && typeof groupMember["s3Endpoint"] === "string";
58
+ }
59
+ function matchesReserveTrialAccountShape(response) {
60
+ return typeof response.accountId === "string" && typeof response.s3Endpoint === "string" && typeof response.startDate === "string" && typeof response.endDate === "string" && typeof response.email === "string" && typeof response.bucketName === "string" && typeof response.bucketId === "string";
61
+ }
62
+ function redactApplicationKeyShallow(target) {
63
+ return {
64
+ ...target,
65
+ applicationKey: APPLICATION_KEY_REDACTED
66
+ };
67
+ }
5
68
  function installPortableJsonHook(target, toJson) {
6
69
  const originalPrototype = Object.getPrototypeOf(target);
7
70
  const redactionPrototype = Object.create(originalPrototype);
@@ -17,6 +80,24 @@ function installPortableJsonHook(target, toJson) {
17
80
  configurable: true
18
81
  });
19
82
  }
83
+ function redactWithHooks(value, toRedactedJsonForTarget, toRedactedString) {
84
+ const target = Object.isExtensible(value) ? value : { ...value };
85
+ const toRedactedJson = () => toRedactedJsonForTarget(target);
86
+ installPortableJsonHook(target, toRedactedJson);
87
+ Object.defineProperties(target, {
88
+ toString: {
89
+ value: toRedactedString,
90
+ enumerable: false,
91
+ configurable: true
92
+ },
93
+ [inspectSymbol]: {
94
+ value: toRedactedJson,
95
+ enumerable: false,
96
+ configurable: true
97
+ }
98
+ });
99
+ return target;
100
+ }
20
101
  /**
21
102
  * Returns a redacted copy for log serializers that intentionally hide tokens.
22
103
  *
@@ -25,10 +106,17 @@ function installPortableJsonHook(target, toJson) {
25
106
  * @returns A plain object with the Partner token replaced by a placeholder.
26
107
  */
27
108
  function partnerAuthorizeResponseToRedactedJson(auth) {
28
- return {
29
- ...auth,
30
- authorizationToken: PARTNER_TOKEN_REDACTED
109
+ const redacted = {
110
+ accountId: auth.accountId,
111
+ authorizationToken: PARTNER_TOKEN_REDACTED,
112
+ apiInfo: partnerApiInfoToRedactedJson(auth.apiInfo),
113
+ applicationKeyExpirationTimestamp: auth.applicationKeyExpirationTimestamp
31
114
  };
115
+ if (auth.groupsApiUrl !== void 0) redacted.groupsApiUrl = auth.groupsApiUrl;
116
+ if (auth.backupApiUrl !== void 0) redacted.backupApiUrl = auth.backupApiUrl;
117
+ if (auth.groupsCapabilities !== void 0) redacted.groupsCapabilities = [...auth.groupsCapabilities];
118
+ if (auth.backupCapabilities !== void 0) redacted.backupCapabilities = [...auth.backupCapabilities];
119
+ return redacted;
32
120
  }
33
121
  /**
34
122
  * Returns a redacted copy for log serializers that intentionally hide group-member keys.
@@ -36,11 +124,14 @@ function partnerAuthorizeResponseToRedactedJson(auth) {
36
124
  * @param result - Create group member result to render safely.
37
125
  *
38
126
  * @returns A plain object with the application key secret replaced by a placeholder.
127
+ *
128
+ * @experimental Partner API surface; shape may change as the Partner API docs evolve.
39
129
  */
40
130
  function createGroupMemberResultToRedactedJson(result) {
41
131
  return {
42
- ...result,
43
- applicationKey: APPLICATION_KEY_REDACTED
132
+ applicationKeyId: result.applicationKeyId,
133
+ applicationKey: APPLICATION_KEY_REDACTED,
134
+ groupMember: partnerGroupMemberToRedactedJson(result.groupMember)
44
135
  };
45
136
  }
46
137
  /**
@@ -48,10 +139,12 @@ function createGroupMemberResultToRedactedJson(result) {
48
139
  *
49
140
  * @param response - Create group member response to render safely.
50
141
  *
51
- * @returns A plain array with every application key secret replaced by a placeholder.
142
+ * @returns A plain object with the application key secret replaced by a placeholder.
143
+ *
144
+ * @experimental Partner API surface; shape may change as the Partner API docs evolve.
52
145
  */
53
146
  function createGroupMemberResponseToRedactedJson(response) {
54
- return response.map((result) => createGroupMemberResultToRedactedJson(result));
147
+ return createGroupMemberResultToRedactedJson(response);
55
148
  }
56
149
  /**
57
150
  * Returns a redacted copy for log serializers that intentionally hide trial account keys.
@@ -59,11 +152,20 @@ function createGroupMemberResponseToRedactedJson(response) {
59
152
  * @param result - Reserve trial account result to render safely.
60
153
  *
61
154
  * @returns A plain object with the application key secret replaced by a placeholder.
155
+ *
156
+ * @experimental Partner API surface; shape may change as the Partner API docs evolve.
62
157
  */
63
158
  function reserveTrialCreateAccountResultToRedactedJson(result) {
64
159
  return {
65
- ...result,
66
- applicationKey: APPLICATION_KEY_REDACTED
160
+ accountId: result.accountId,
161
+ applicationKey: APPLICATION_KEY_REDACTED,
162
+ applicationKeyId: result.applicationKeyId,
163
+ s3Endpoint: result.s3Endpoint,
164
+ startDate: result.startDate,
165
+ endDate: result.endDate,
166
+ email: result.email,
167
+ bucketName: result.bucketName,
168
+ bucketId: result.bucketId
67
169
  };
68
170
  }
69
171
  /**
@@ -71,10 +173,12 @@ function reserveTrialCreateAccountResultToRedactedJson(result) {
71
173
  *
72
174
  * @param response - Reserve trial account response to render safely.
73
175
  *
74
- * @returns A plain array with every application key secret replaced by a placeholder.
176
+ * @returns A plain object with the application key secret replaced by a placeholder.
177
+ *
178
+ * @experimental Partner API surface; shape may change as the Partner API docs evolve.
75
179
  */
76
180
  function reserveTrialCreateAccountResponseToRedactedJson(response) {
77
- return response.map((result) => reserveTrialCreateAccountResultToRedactedJson(result));
181
+ return reserveTrialCreateAccountResultToRedactedJson(response);
78
182
  }
79
183
  /**
80
184
  * Adds non-enumerable serialization and inspection hooks that redact the
@@ -123,69 +227,29 @@ function redactPartnerAuthorizeResponse(auth) {
123
227
  * @returns The same result object with redaction hooks installed when possible.
124
228
  */
125
229
  function redactCreateGroupMemberResult(result) {
126
- const target = Object.isExtensible(result) ? result : { ...result };
127
- const toRedactedJson = () => createGroupMemberResultToRedactedJson(target);
128
- const toRedactedString = () => `[CreateGroupMemberResult ${APPLICATION_KEY_REDACTED}]`;
129
- installPortableJsonHook(target, toRedactedJson);
130
- Object.defineProperties(target, {
131
- toString: {
132
- value: toRedactedString,
133
- enumerable: false,
134
- configurable: true
135
- },
136
- [inspectSymbol]: {
137
- value: toRedactedJson,
138
- enumerable: false,
139
- configurable: true
140
- }
141
- });
142
- return target;
230
+ return redactWithHooks(result, createGroupMemberResultToRedactedJson, () => `[CreateGroupMemberResult ${APPLICATION_KEY_REDACTED}]`);
143
231
  }
144
232
  /**
145
- * Adds non-enumerable serialization and inspection hooks that redact all
146
- * create-group-member application key secrets while preserving direct access.
233
+ * Adds non-enumerable serialization and inspection hooks that redact the
234
+ * create-group-member application key secret while preserving direct access.
147
235
  *
148
236
  * @param response - Create group member response to protect from accidental logging.
149
237
  *
150
- * @returns The same response array with redaction hooks installed when possible.
238
+ * @returns The same response object with redaction hooks installed when possible.
151
239
  *
152
- * @throws B2PartnerAuthorizationError if the response is not an array.
240
+ * @throws B2PartnerAuthorizationError if the response carries no usable application key.
153
241
  */
154
242
  function redactCreateGroupMemberResponse(response) {
155
- if (!Array.isArray(response)) throw new B2PartnerAuthorizationError("b2_create_group_member response was not a JSON array");
156
- const target = Object.isExtensible(response) ? response : [...response];
157
- const writableTarget = target;
158
- for (let i = 0; i < writableTarget.length; i++) {
159
- const result = writableTarget[i];
160
- if (result !== void 0) writableTarget[i] = redactCreateGroupMemberResult(result);
161
- }
162
- const toRedactedJson = () => createGroupMemberResponseToRedactedJson(target);
163
- const toRedactedString = () => `[CreateGroupMemberResponse ${APPLICATION_KEY_REDACTED}]`;
164
- Object.defineProperties(target, {
165
- toJSON: {
166
- value: toRedactedJson,
167
- enumerable: false,
168
- configurable: true
169
- },
170
- toString: {
171
- value: toRedactedString,
172
- enumerable: false,
173
- configurable: true
174
- },
175
- [inspectSymbol]: {
176
- value: toRedactedJson,
177
- enumerable: false,
178
- configurable: true
179
- }
180
- });
181
- return target;
243
+ if (!isCredentialBearing(response)) throw new B2PartnerAuthorizationError("b2_create_group_member response did not contain a usable application key");
244
+ if (matchesGroupMemberShape(response.groupMember)) return redactCreateGroupMemberResult(response);
245
+ return redactWithHooks(response, redactApplicationKeyShallow, () => `[CreateGroupMemberResponse ${APPLICATION_KEY_REDACTED}]`);
182
246
  }
183
247
  /**
184
248
  * Adds non-enumerable serialization and inspection hooks that redact the
185
249
  * application key secret while preserving direct property access.
186
250
  *
187
251
  * `JSON.stringify` redacts because the response contains newly minted
188
- * application key secrets that are commonly logged as batch results. Callers
252
+ * application key secrets that are commonly logged with responses. Callers
189
253
  * that need to persist the key should read `applicationKey` directly into
190
254
  * secure storage before serializing the object.
191
255
  *
@@ -194,64 +258,24 @@ function redactCreateGroupMemberResponse(response) {
194
258
  * @returns The same result object with redaction hooks installed when possible.
195
259
  */
196
260
  function redactReserveTrialCreateAccountResult(result) {
197
- const target = Object.isExtensible(result) ? result : { ...result };
198
- const toRedactedJson = () => reserveTrialCreateAccountResultToRedactedJson(target);
199
- const toRedactedString = () => `[ReserveTrialCreateAccountResult ${APPLICATION_KEY_REDACTED}]`;
200
- installPortableJsonHook(target, toRedactedJson);
201
- Object.defineProperties(target, {
202
- toString: {
203
- value: toRedactedString,
204
- enumerable: false,
205
- configurable: true
206
- },
207
- [inspectSymbol]: {
208
- value: toRedactedJson,
209
- enumerable: false,
210
- configurable: true
211
- }
212
- });
213
- return target;
261
+ return redactWithHooks(result, reserveTrialCreateAccountResultToRedactedJson, () => `[ReserveTrialCreateAccountResult ${APPLICATION_KEY_REDACTED}]`);
214
262
  }
215
263
  /**
216
- * Adds non-enumerable serialization and inspection hooks that redact all
217
- * reserve-trial application key secrets while preserving direct property access.
264
+ * Adds non-enumerable serialization and inspection hooks that redact the
265
+ * reserve-trial application key secret while preserving direct property access.
218
266
  *
219
267
  * @param response - Reserve trial account response to protect from accidental logging.
220
268
  *
221
- * @returns The same response array with redaction hooks installed when possible.
269
+ * @returns The same response object with redaction hooks installed when possible.
222
270
  *
223
- * @throws B2PartnerAuthorizationError if the response is not an array.
271
+ * @throws B2PartnerAuthorizationError if the response carries no usable application key.
224
272
  */
225
273
  function redactReserveTrialCreateAccountResponse(response) {
226
- if (!Array.isArray(response)) throw new B2PartnerAuthorizationError("b2_reserve_trial_create_account response was not a JSON array");
227
- const target = Object.isExtensible(response) ? response : [...response];
228
- const writableTarget = target;
229
- for (let i = 0; i < writableTarget.length; i++) {
230
- const result = writableTarget[i];
231
- if (result !== void 0) writableTarget[i] = redactReserveTrialCreateAccountResult(result);
232
- }
233
- const toRedactedJson = () => reserveTrialCreateAccountResponseToRedactedJson(target);
234
- const toRedactedString = () => `[ReserveTrialCreateAccountResponse ${APPLICATION_KEY_REDACTED}]`;
235
- Object.defineProperties(target, {
236
- toJSON: {
237
- value: toRedactedJson,
238
- enumerable: false,
239
- configurable: true
240
- },
241
- toString: {
242
- value: toRedactedString,
243
- enumerable: false,
244
- configurable: true
245
- },
246
- [inspectSymbol]: {
247
- value: toRedactedJson,
248
- enumerable: false,
249
- configurable: true
250
- }
251
- });
252
- return target;
274
+ if (!isCredentialBearing(response)) throw new B2PartnerAuthorizationError("b2_reserve_trial_create_account response did not contain a usable application key");
275
+ if (matchesReserveTrialAccountShape(response)) return redactReserveTrialCreateAccountResult(response);
276
+ return redactWithHooks(response, redactApplicationKeyShallow, () => `[ReserveTrialCreateAccountResponse ${APPLICATION_KEY_REDACTED}]`);
253
277
  }
254
278
  //#endregion
255
- export { PARTNER_TOKEN_REDACTED, createGroupMemberResponseToRedactedJson, createGroupMemberResultToRedactedJson, partnerAuthorizeResponseToRedactedJson, redactCreateGroupMemberResponse, redactCreateGroupMemberResult, redactPartnerAuthorizeResponse, redactReserveTrialCreateAccountResponse, redactReserveTrialCreateAccountResult, reserveTrialCreateAccountResponseToRedactedJson, reserveTrialCreateAccountResultToRedactedJson };
279
+ export { APPLICATION_KEY_REDACTED, PARTNER_TOKEN_REDACTED, createGroupMemberResponseToRedactedJson, createGroupMemberResultToRedactedJson, partnerAuthorizeResponseToRedactedJson, redactCreateGroupMemberResponse, redactCreateGroupMemberResult, redactPartnerAuthorizeResponse, redactReserveTrialCreateAccountResponse, redactReserveTrialCreateAccountResult, reserveTrialCreateAccountResponseToRedactedJson, reserveTrialCreateAccountResultToRedactedJson };
256
280
 
257
281
  //# sourceMappingURL=redaction.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"redaction.js","names":[],"sources":["../../src/partner/redaction.ts"],"sourcesContent":["import { B2PartnerAuthorizationError } from '../errors/index.ts'\nimport type {\n CreateGroupMemberResponse,\n CreateGroupMemberResult,\n PartnerAuthorizeResponse,\n ReserveTrialCreateAccountResponse,\n ReserveTrialCreateAccountResult,\n} from '../types/partner.ts'\nimport { APPLICATION_KEY_REDACTED, PARTNER_TOKEN_REDACTED } from './redaction-placeholders.ts'\n\nexport {\n APPLICATION_KEY_REDACTED,\n PARTNER_TOKEN_REDACTED,\n} from './redaction-placeholders.ts'\n\n/**\n * JSON-safe Partner authorize response with the Partner token replaced by a\n * placeholder string.\n */\nexport interface RedactedPartnerAuthorizeResponseJson\n extends Omit<PartnerAuthorizeResponse, 'authorizationToken'> {\n /** Redacted Partner authorization token placeholder. */\n readonly authorizationToken: string\n}\n\nexport type RedactedCreateGroupMemberResultJson = Omit<\n CreateGroupMemberResult,\n 'applicationKey'\n> & {\n readonly applicationKey: string\n}\n\nexport type RedactedCreateGroupMemberResponseJson = readonly RedactedCreateGroupMemberResultJson[]\n\nexport type RedactedReserveTrialCreateAccountResultJson = Omit<\n ReserveTrialCreateAccountResult,\n 'applicationKey'\n> & {\n readonly applicationKey: string\n}\n\nexport type RedactedReserveTrialCreateAccountResponseJson =\n readonly RedactedReserveTrialCreateAccountResultJson[]\n\nconst inspectSymbol = Symbol.for('nodejs.util.inspect.custom')\n\n// Bun/WebKit only honor object toJSON hooks when they are inherited, while Node\n// honors own hooks. Install both shapes so SDK safe serialization is portable.\nfunction installPortableJsonHook<T extends object>(target: T, toJson: () => unknown): void {\n const originalPrototype = Object.getPrototypeOf(target)\n const redactionPrototype = Object.create(originalPrototype) as object\n Object.defineProperty(redactionPrototype, 'toJSON', {\n value: toJson,\n enumerable: false,\n configurable: true,\n })\n Object.setPrototypeOf(target, redactionPrototype)\n Object.defineProperty(target, 'toJSON', {\n value: toJson,\n enumerable: false,\n configurable: true,\n })\n}\n\n/**\n * Returns a redacted copy for log serializers that intentionally hide tokens.\n *\n * @param auth - Partner authorization response to render safely.\n *\n * @returns A plain object with the Partner token replaced by a placeholder.\n */\nexport function partnerAuthorizeResponseToRedactedJson(\n auth: PartnerAuthorizeResponse,\n): RedactedPartnerAuthorizeResponseJson {\n return {\n ...auth,\n authorizationToken: PARTNER_TOKEN_REDACTED,\n }\n}\n\n/**\n * Returns a redacted copy for log serializers that intentionally hide group-member keys.\n *\n * @param result - Create group member result to render safely.\n *\n * @returns A plain object with the application key secret replaced by a placeholder.\n */\nexport function createGroupMemberResultToRedactedJson(\n result: CreateGroupMemberResult,\n): RedactedCreateGroupMemberResultJson {\n return {\n ...result,\n applicationKey: APPLICATION_KEY_REDACTED,\n }\n}\n\n/**\n * Returns a redacted copy for log serializers that intentionally hide group-member keys.\n *\n * @param response - Create group member response to render safely.\n *\n * @returns A plain array with every application key secret replaced by a placeholder.\n */\nexport function createGroupMemberResponseToRedactedJson(\n response: CreateGroupMemberResponse,\n): RedactedCreateGroupMemberResponseJson {\n return response.map((result) => createGroupMemberResultToRedactedJson(result))\n}\n\n/**\n * Returns a redacted copy for log serializers that intentionally hide trial account keys.\n *\n * @param result - Reserve trial account result to render safely.\n *\n * @returns A plain object with the application key secret replaced by a placeholder.\n */\nexport function reserveTrialCreateAccountResultToRedactedJson(\n result: ReserveTrialCreateAccountResult,\n): RedactedReserveTrialCreateAccountResultJson {\n return {\n ...result,\n applicationKey: APPLICATION_KEY_REDACTED,\n }\n}\n\n/**\n * Returns a redacted copy for log serializers that intentionally hide trial account keys.\n *\n * @param response - Reserve trial account response to render safely.\n *\n * @returns A plain array with every application key secret replaced by a placeholder.\n */\nexport function reserveTrialCreateAccountResponseToRedactedJson(\n response: ReserveTrialCreateAccountResponse,\n): RedactedReserveTrialCreateAccountResponseJson {\n return response.map((result) => reserveTrialCreateAccountResultToRedactedJson(result))\n}\n\n/**\n * Adds non-enumerable serialization and inspection hooks that redact the\n * Partner token through `JSON.stringify`, `toString`, and Node `util.inspect`\n * while preserving direct property access.\n *\n * `JSON.stringify` no longer round-trips `authorizationToken` from protected\n * authorize responses. Persist trusted auth caches with\n * `partnerAuthorizeResponseForPersistence(auth)` only into encrypted or\n * otherwise credential-grade storage, or read `authorizationToken` directly\n * into secure storage before serializing.\n *\n * This does not make the object universally log-safe: object spread,\n * `Object.assign`, `Object.entries`, `structuredClone`, and serializers that\n * walk enumerable properties can still expose the raw token.\n *\n * @param auth - Partner authorization response to protect from accidental inspection.\n *\n * @returns The same auth object with inspection hooks installed when possible.\n */\nexport function redactPartnerAuthorizeResponse(\n auth: PartnerAuthorizeResponse,\n): PartnerAuthorizeResponse {\n const target = Object.isExtensible(auth) ? auth : { ...auth }\n const toRedactedJson = (): RedactedPartnerAuthorizeResponseJson =>\n partnerAuthorizeResponseToRedactedJson(target)\n const toRedactedString = (): string => `[PartnerAuthorizeResponse ${PARTNER_TOKEN_REDACTED}]`\n\n installPortableJsonHook(target, toRedactedJson)\n Object.defineProperties(target, {\n toString: {\n value: toRedactedString,\n enumerable: false,\n configurable: true,\n },\n [inspectSymbol]: {\n value: toRedactedJson,\n enumerable: false,\n configurable: true,\n },\n })\n\n return target\n}\n\n/**\n * Adds non-enumerable serialization and inspection hooks that redact the\n * application key secret while preserving direct property access.\n *\n * @param result - Create group member result to protect from accidental logging.\n *\n * @returns The same result object with redaction hooks installed when possible.\n */\nexport function redactCreateGroupMemberResult(\n result: CreateGroupMemberResult,\n): CreateGroupMemberResult {\n const target = Object.isExtensible(result) ? result : { ...result }\n const toRedactedJson = (): RedactedCreateGroupMemberResultJson =>\n createGroupMemberResultToRedactedJson(target)\n const toRedactedString = (): string => `[CreateGroupMemberResult ${APPLICATION_KEY_REDACTED}]`\n\n installPortableJsonHook(target, toRedactedJson)\n Object.defineProperties(target, {\n toString: {\n value: toRedactedString,\n enumerable: false,\n configurable: true,\n },\n [inspectSymbol]: {\n value: toRedactedJson,\n enumerable: false,\n configurable: true,\n },\n })\n\n return target\n}\n\n/**\n * Adds non-enumerable serialization and inspection hooks that redact all\n * create-group-member application key secrets while preserving direct access.\n *\n * @param response - Create group member response to protect from accidental logging.\n *\n * @returns The same response array with redaction hooks installed when possible.\n *\n * @throws B2PartnerAuthorizationError if the response is not an array.\n */\nexport function redactCreateGroupMemberResponse(\n response: CreateGroupMemberResponse,\n): CreateGroupMemberResponse {\n if (!Array.isArray(response)) {\n throw new B2PartnerAuthorizationError('b2_create_group_member response was not a JSON array')\n }\n\n const target = Object.isExtensible(response) ? response : [...response]\n const writableTarget = target as CreateGroupMemberResult[]\n for (let i = 0; i < writableTarget.length; i++) {\n const result = writableTarget[i]\n if (result !== undefined) writableTarget[i] = redactCreateGroupMemberResult(result)\n }\n\n const toRedactedJson = (): RedactedCreateGroupMemberResponseJson =>\n createGroupMemberResponseToRedactedJson(target)\n const toRedactedString = (): string => `[CreateGroupMemberResponse ${APPLICATION_KEY_REDACTED}]`\n\n Object.defineProperties(target, {\n toJSON: {\n value: toRedactedJson,\n enumerable: false,\n configurable: true,\n },\n toString: {\n value: toRedactedString,\n enumerable: false,\n configurable: true,\n },\n [inspectSymbol]: {\n value: toRedactedJson,\n enumerable: false,\n configurable: true,\n },\n })\n\n return target\n}\n\n/**\n * Adds non-enumerable serialization and inspection hooks that redact the\n * application key secret while preserving direct property access.\n *\n * `JSON.stringify` redacts because the response contains newly minted\n * application key secrets that are commonly logged as batch results. Callers\n * that need to persist the key should read `applicationKey` directly into\n * secure storage before serializing the object.\n *\n * @param result - Reserve trial account result to protect from accidental logging.\n *\n * @returns The same result object with redaction hooks installed when possible.\n */\nexport function redactReserveTrialCreateAccountResult(\n result: ReserveTrialCreateAccountResult,\n): ReserveTrialCreateAccountResult {\n const target = Object.isExtensible(result) ? result : { ...result }\n const toRedactedJson = (): RedactedReserveTrialCreateAccountResultJson =>\n reserveTrialCreateAccountResultToRedactedJson(target)\n const toRedactedString = (): string =>\n `[ReserveTrialCreateAccountResult ${APPLICATION_KEY_REDACTED}]`\n\n installPortableJsonHook(target, toRedactedJson)\n Object.defineProperties(target, {\n toString: {\n value: toRedactedString,\n enumerable: false,\n configurable: true,\n },\n [inspectSymbol]: {\n value: toRedactedJson,\n enumerable: false,\n configurable: true,\n },\n })\n\n return target\n}\n\n/**\n * Adds non-enumerable serialization and inspection hooks that redact all\n * reserve-trial application key secrets while preserving direct property access.\n *\n * @param response - Reserve trial account response to protect from accidental logging.\n *\n * @returns The same response array with redaction hooks installed when possible.\n *\n * @throws B2PartnerAuthorizationError if the response is not an array.\n */\nexport function redactReserveTrialCreateAccountResponse(\n response: ReserveTrialCreateAccountResponse,\n): ReserveTrialCreateAccountResponse {\n if (!Array.isArray(response)) {\n throw new B2PartnerAuthorizationError(\n 'b2_reserve_trial_create_account response was not a JSON array',\n )\n }\n\n const target = Object.isExtensible(response) ? response : [...response]\n const writableTarget = target as ReserveTrialCreateAccountResult[]\n for (let i = 0; i < writableTarget.length; i++) {\n const result = writableTarget[i]\n if (result !== undefined) writableTarget[i] = redactReserveTrialCreateAccountResult(result)\n }\n\n const toRedactedJson = (): RedactedReserveTrialCreateAccountResponseJson =>\n reserveTrialCreateAccountResponseToRedactedJson(target)\n const toRedactedString = (): string =>\n `[ReserveTrialCreateAccountResponse ${APPLICATION_KEY_REDACTED}]`\n\n Object.defineProperties(target, {\n toJSON: {\n value: toRedactedJson,\n enumerable: false,\n configurable: true,\n },\n toString: {\n value: toRedactedString,\n enumerable: false,\n configurable: true,\n },\n [inspectSymbol]: {\n value: toRedactedJson,\n enumerable: false,\n configurable: true,\n },\n })\n\n return target\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"redaction.js","names":[],"sources":["../../src/partner/redaction.ts"],"sourcesContent":["import { B2PartnerAuthorizationError } from '../errors/index.ts'\nimport type {\n CreateGroupMemberResponse,\n CreateGroupMemberResult,\n PartnerApiInfo,\n PartnerAuthorizeResponse,\n PartnerBackupApiInfo,\n PartnerGroupMember,\n PartnerGroupsApiInfo,\n PartnerStorageApiInfo,\n ReserveTrialCreateAccountResponse,\n ReserveTrialCreateAccountResult,\n} from '../types/partner.ts'\nimport { APPLICATION_KEY_REDACTED, PARTNER_TOKEN_REDACTED } from './redaction-placeholders.ts'\n\nexport {\n APPLICATION_KEY_REDACTED,\n PARTNER_TOKEN_REDACTED,\n} from './redaction-placeholders.ts'\n\n/**\n * JSON-safe Partner authorize response with the Partner token replaced by a\n * placeholder string.\n */\nexport interface RedactedPartnerAuthorizeResponseJson\n extends Omit<PartnerAuthorizeResponse, 'authorizationToken'> {\n /** Redacted Partner authorization token placeholder. */\n readonly authorizationToken: string\n}\n\n/**\n * JSON-safe create-group-member result with the one-time application key\n * secret replaced by a placeholder string.\n *\n * @experimental Partner API surface; shape may change as the Partner API docs evolve.\n */\nexport type RedactedCreateGroupMemberResultJson = Omit<\n CreateGroupMemberResult,\n 'applicationKey'\n> & {\n /** Redacted application key secret placeholder. */\n readonly applicationKey: string\n}\n\n/**\n * JSON-safe create-group-member response with the one-time application key\n * secret replaced by a placeholder string.\n *\n * @experimental Partner API surface; shape may change as the Partner API docs evolve.\n */\nexport type RedactedCreateGroupMemberResponseJson = RedactedCreateGroupMemberResultJson\n\n/**\n * JSON-safe reserve-trial account result with the one-time application key\n * secret replaced by a placeholder string.\n *\n * @experimental Partner API surface; shape may change as the Partner API docs evolve.\n */\nexport type RedactedReserveTrialCreateAccountResultJson = Omit<\n ReserveTrialCreateAccountResult,\n 'applicationKey'\n> & {\n /** Redacted application key secret placeholder. */\n readonly applicationKey: string\n}\n\n/**\n * JSON-safe reserve-trial account response with the one-time application key\n * secret replaced by a placeholder string.\n *\n * @experimental Partner API surface; shape may change as the Partner API docs evolve.\n */\nexport type RedactedReserveTrialCreateAccountResponseJson =\n RedactedReserveTrialCreateAccountResultJson\n\nconst inspectSymbol = Symbol.for('nodejs.util.inspect.custom')\n\ntype Writable<T> = { -readonly [K in keyof T]: T[K] }\n\nfunction partnerGroupsApiInfoToRedactedJson(info: PartnerGroupsApiInfo): PartnerGroupsApiInfo {\n return {\n capabilities: [...info.capabilities],\n groupsApiUrl: info.groupsApiUrl,\n infoType: info.infoType,\n }\n}\n\nfunction partnerBackupApiInfoToRedactedJson(info: PartnerBackupApiInfo): PartnerBackupApiInfo {\n return {\n capabilities: [...info.capabilities],\n backupApiUrl: info.backupApiUrl,\n infoType: info.infoType,\n }\n}\n\nfunction partnerStorageApiInfoToRedactedJson(info: PartnerStorageApiInfo): PartnerStorageApiInfo {\n return {\n absoluteMinimumPartSize: info.absoluteMinimumPartSize,\n apiUrl: info.apiUrl,\n bucketId: info.bucketId,\n bucketName: info.bucketName,\n capabilities: [...info.capabilities],\n downloadUrl: info.downloadUrl,\n infoType: info.infoType,\n namePrefix: info.namePrefix,\n recommendedPartSize: info.recommendedPartSize,\n s3ApiUrl: info.s3ApiUrl,\n }\n}\n\nfunction partnerApiInfoToRedactedJson(apiInfo: PartnerApiInfo): PartnerApiInfo {\n const redacted: Writable<PartnerApiInfo> = {}\n if (apiInfo.storageApi !== undefined) {\n redacted.storageApi = partnerStorageApiInfoToRedactedJson(apiInfo.storageApi)\n }\n if (apiInfo.groupsApi !== undefined) {\n redacted.groupsApi = partnerGroupsApiInfoToRedactedJson(apiInfo.groupsApi)\n }\n if (apiInfo.backupApi !== undefined) {\n redacted.backupApi = partnerBackupApiInfoToRedactedJson(apiInfo.backupApi)\n }\n return redacted\n}\n\nfunction partnerGroupMemberToRedactedJson(groupMember: PartnerGroupMember): PartnerGroupMember {\n return {\n accountId: groupMember.accountId,\n email: groupMember.email,\n groupId: groupMember.groupId,\n groupName: groupMember.groupName,\n region: groupMember.region,\n s3Endpoint: groupMember.s3Endpoint,\n }\n}\n\nfunction isSingleJsonObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n// The one invariant a create/reserve redaction wrapper must never violate: a\n// usable one-time credential must survive. B2 mints the application key exactly\n// once, after the (non-deletable) account already exists, so throwing the\n// response away over an unexpected *non-credential* field would destroy an\n// unrecoverable secret — the core hazard of #280. We hard-fail only when there\n// is no usable credential to preserve (nothing is lost in that case).\nfunction isCredentialBearing(\n response: unknown,\n): response is { applicationKey: string; applicationKeyId: string } {\n return (\n isSingleJsonObject(response) &&\n typeof response['applicationKey'] === 'string' &&\n typeof response['applicationKeyId'] === 'string'\n )\n}\n\n// True when `groupMember` matches every documented field type, so the\n// field-specific (allowlist) redaction copies the full shape without dropping\n// unexpected fields. A partial/variant object falls back to shallow redaction.\nfunction matchesGroupMemberShape(groupMember: unknown): groupMember is PartnerGroupMember {\n return (\n isSingleJsonObject(groupMember) &&\n typeof groupMember['accountId'] === 'string' &&\n typeof groupMember['email'] === 'string' &&\n typeof groupMember['groupId'] === 'string' &&\n typeof groupMember['groupName'] === 'string' &&\n typeof groupMember['region'] === 'string' &&\n typeof groupMember['s3Endpoint'] === 'string'\n )\n}\n\n// True when the reserve-trial response also matches every documented\n// non-credential field, so the field-specific (allowlist) redaction is exact.\nfunction matchesReserveTrialAccountShape(response: ReserveTrialCreateAccountResponse): boolean {\n return (\n typeof response.accountId === 'string' &&\n typeof response.s3Endpoint === 'string' &&\n typeof response.startDate === 'string' &&\n typeof response.endDate === 'string' &&\n typeof response.email === 'string' &&\n typeof response.bucketName === 'string' &&\n typeof response.bucketId === 'string'\n )\n}\n\n// Redaction hook for a credential-bearing response whose surrounding shape is\n// unexpected: shallow-copy every field the server sent and redact only the\n// one-time secret, so the response is never discarded and never logs the key.\nfunction redactApplicationKeyShallow<T extends object>(target: T): unknown {\n return { ...target, applicationKey: APPLICATION_KEY_REDACTED }\n}\n\n// Bun/WebKit only honor object toJSON hooks when they are inherited, while Node\n// honors own hooks. Install both shapes so SDK safe serialization is portable.\nfunction installPortableJsonHook<T extends object>(target: T, toJson: () => unknown): void {\n const originalPrototype = Object.getPrototypeOf(target)\n const redactionPrototype = Object.create(originalPrototype) as object\n Object.defineProperty(redactionPrototype, 'toJSON', {\n value: toJson,\n enumerable: false,\n configurable: true,\n })\n Object.setPrototypeOf(target, redactionPrototype)\n Object.defineProperty(target, 'toJSON', {\n value: toJson,\n enumerable: false,\n configurable: true,\n })\n}\n\nfunction redactWithHooks<T extends object>(\n value: T,\n toRedactedJsonForTarget: (target: T) => unknown,\n toRedactedString: () => string,\n): T {\n const target = Object.isExtensible(value) ? value : ({ ...value } as T)\n const toRedactedJson = (): unknown => toRedactedJsonForTarget(target)\n\n installPortableJsonHook(target, toRedactedJson)\n Object.defineProperties(target, {\n toString: {\n value: toRedactedString,\n enumerable: false,\n configurable: true,\n },\n [inspectSymbol]: {\n value: toRedactedJson,\n enumerable: false,\n configurable: true,\n },\n })\n\n return target\n}\n\n/**\n * Returns a redacted copy for log serializers that intentionally hide tokens.\n *\n * @param auth - Partner authorization response to render safely.\n *\n * @returns A plain object with the Partner token replaced by a placeholder.\n */\nexport function partnerAuthorizeResponseToRedactedJson(\n auth: PartnerAuthorizeResponse,\n): RedactedPartnerAuthorizeResponseJson {\n const redacted: Writable<RedactedPartnerAuthorizeResponseJson> = {\n accountId: auth.accountId,\n authorizationToken: PARTNER_TOKEN_REDACTED,\n apiInfo: partnerApiInfoToRedactedJson(auth.apiInfo),\n applicationKeyExpirationTimestamp: auth.applicationKeyExpirationTimestamp,\n }\n if (auth.groupsApiUrl !== undefined) redacted.groupsApiUrl = auth.groupsApiUrl\n if (auth.backupApiUrl !== undefined) redacted.backupApiUrl = auth.backupApiUrl\n if (auth.groupsCapabilities !== undefined) {\n redacted.groupsCapabilities = [...auth.groupsCapabilities]\n }\n if (auth.backupCapabilities !== undefined) {\n redacted.backupCapabilities = [...auth.backupCapabilities]\n }\n return redacted\n}\n\n/**\n * Returns a redacted copy for log serializers that intentionally hide group-member keys.\n *\n * @param result - Create group member result to render safely.\n *\n * @returns A plain object with the application key secret replaced by a placeholder.\n *\n * @experimental Partner API surface; shape may change as the Partner API docs evolve.\n */\nexport function createGroupMemberResultToRedactedJson(\n result: CreateGroupMemberResult,\n): RedactedCreateGroupMemberResultJson {\n return {\n applicationKeyId: result.applicationKeyId,\n applicationKey: APPLICATION_KEY_REDACTED,\n groupMember: partnerGroupMemberToRedactedJson(result.groupMember),\n }\n}\n\n/**\n * Returns a redacted copy for log serializers that intentionally hide group-member keys.\n *\n * @param response - Create group member response to render safely.\n *\n * @returns A plain object with the application key secret replaced by a placeholder.\n *\n * @experimental Partner API surface; shape may change as the Partner API docs evolve.\n */\nexport function createGroupMemberResponseToRedactedJson(\n response: CreateGroupMemberResponse,\n): RedactedCreateGroupMemberResponseJson {\n return createGroupMemberResultToRedactedJson(response)\n}\n\n/**\n * Returns a redacted copy for log serializers that intentionally hide trial account keys.\n *\n * @param result - Reserve trial account result to render safely.\n *\n * @returns A plain object with the application key secret replaced by a placeholder.\n *\n * @experimental Partner API surface; shape may change as the Partner API docs evolve.\n */\nexport function reserveTrialCreateAccountResultToRedactedJson(\n result: ReserveTrialCreateAccountResult,\n): RedactedReserveTrialCreateAccountResultJson {\n return {\n accountId: result.accountId,\n applicationKey: APPLICATION_KEY_REDACTED,\n applicationKeyId: result.applicationKeyId,\n s3Endpoint: result.s3Endpoint,\n startDate: result.startDate,\n endDate: result.endDate,\n email: result.email,\n bucketName: result.bucketName,\n bucketId: result.bucketId,\n }\n}\n\n/**\n * Returns a redacted copy for log serializers that intentionally hide trial account keys.\n *\n * @param response - Reserve trial account response to render safely.\n *\n * @returns A plain object with the application key secret replaced by a placeholder.\n *\n * @experimental Partner API surface; shape may change as the Partner API docs evolve.\n */\nexport function reserveTrialCreateAccountResponseToRedactedJson(\n response: ReserveTrialCreateAccountResponse,\n): RedactedReserveTrialCreateAccountResponseJson {\n return reserveTrialCreateAccountResultToRedactedJson(response)\n}\n\n/**\n * Adds non-enumerable serialization and inspection hooks that redact the\n * Partner token through `JSON.stringify`, `toString`, and Node `util.inspect`\n * while preserving direct property access.\n *\n * `JSON.stringify` no longer round-trips `authorizationToken` from protected\n * authorize responses. Persist trusted auth caches with\n * `partnerAuthorizeResponseForPersistence(auth)` only into encrypted or\n * otherwise credential-grade storage, or read `authorizationToken` directly\n * into secure storage before serializing.\n *\n * This does not make the object universally log-safe: object spread,\n * `Object.assign`, `Object.entries`, `structuredClone`, and serializers that\n * walk enumerable properties can still expose the raw token.\n *\n * @param auth - Partner authorization response to protect from accidental inspection.\n *\n * @returns The same auth object with inspection hooks installed when possible.\n */\nexport function redactPartnerAuthorizeResponse(\n auth: PartnerAuthorizeResponse,\n): PartnerAuthorizeResponse {\n const target = Object.isExtensible(auth) ? auth : { ...auth }\n const toRedactedJson = (): RedactedPartnerAuthorizeResponseJson =>\n partnerAuthorizeResponseToRedactedJson(target)\n const toRedactedString = (): string => `[PartnerAuthorizeResponse ${PARTNER_TOKEN_REDACTED}]`\n\n installPortableJsonHook(target, toRedactedJson)\n Object.defineProperties(target, {\n toString: {\n value: toRedactedString,\n enumerable: false,\n configurable: true,\n },\n [inspectSymbol]: {\n value: toRedactedJson,\n enumerable: false,\n configurable: true,\n },\n })\n\n return target\n}\n\n/**\n * Adds non-enumerable serialization and inspection hooks that redact the\n * application key secret while preserving direct property access.\n *\n * @param result - Create group member result to protect from accidental logging.\n *\n * @returns The same result object with redaction hooks installed when possible.\n */\nexport function redactCreateGroupMemberResult(\n result: CreateGroupMemberResult,\n): CreateGroupMemberResult {\n return redactWithHooks(\n result,\n createGroupMemberResultToRedactedJson,\n () => `[CreateGroupMemberResult ${APPLICATION_KEY_REDACTED}]`,\n )\n}\n\n/**\n * Adds non-enumerable serialization and inspection hooks that redact the\n * create-group-member application key secret while preserving direct access.\n *\n * @param response - Create group member response to protect from accidental logging.\n *\n * @returns The same response object with redaction hooks installed when possible.\n *\n * @throws B2PartnerAuthorizationError if the response carries no usable application key.\n */\nexport function redactCreateGroupMemberResponse(\n response: CreateGroupMemberResponse,\n): CreateGroupMemberResponse {\n if (!isCredentialBearing(response)) {\n throw new B2PartnerAuthorizationError(\n 'b2_create_group_member response did not contain a usable application key',\n )\n }\n // Full documented shape → field-specific (allowlist) redaction.\n if (matchesGroupMemberShape(response.groupMember)) {\n return redactCreateGroupMemberResult(response)\n }\n // Credential present but the surrounding shape is unexpected: never discard a\n // provisioned one-time key. Return it with only the secret redacted for logs.\n return redactWithHooks(\n response,\n redactApplicationKeyShallow,\n () => `[CreateGroupMemberResponse ${APPLICATION_KEY_REDACTED}]`,\n )\n}\n\n/**\n * Adds non-enumerable serialization and inspection hooks that redact the\n * application key secret while preserving direct property access.\n *\n * `JSON.stringify` redacts because the response contains newly minted\n * application key secrets that are commonly logged with responses. Callers\n * that need to persist the key should read `applicationKey` directly into\n * secure storage before serializing the object.\n *\n * @param result - Reserve trial account result to protect from accidental logging.\n *\n * @returns The same result object with redaction hooks installed when possible.\n */\nexport function redactReserveTrialCreateAccountResult(\n result: ReserveTrialCreateAccountResult,\n): ReserveTrialCreateAccountResult {\n return redactWithHooks(\n result,\n reserveTrialCreateAccountResultToRedactedJson,\n () => `[ReserveTrialCreateAccountResult ${APPLICATION_KEY_REDACTED}]`,\n )\n}\n\n/**\n * Adds non-enumerable serialization and inspection hooks that redact the\n * reserve-trial application key secret while preserving direct property access.\n *\n * @param response - Reserve trial account response to protect from accidental logging.\n *\n * @returns The same response object with redaction hooks installed when possible.\n *\n * @throws B2PartnerAuthorizationError if the response carries no usable application key.\n */\nexport function redactReserveTrialCreateAccountResponse(\n response: ReserveTrialCreateAccountResponse,\n): ReserveTrialCreateAccountResponse {\n if (!isCredentialBearing(response)) {\n throw new B2PartnerAuthorizationError(\n 'b2_reserve_trial_create_account response did not contain a usable application key',\n )\n }\n // Full documented shape → field-specific (allowlist) redaction.\n if (matchesReserveTrialAccountShape(response)) {\n return redactReserveTrialCreateAccountResult(response)\n }\n // Credential present but the surrounding shape is unexpected: never discard a\n // provisioned one-time key. Return it with only the secret redacted for logs.\n return redactWithHooks(\n response,\n redactApplicationKeyShallow,\n () => `[ReserveTrialCreateAccountResponse ${APPLICATION_KEY_REDACTED}]`,\n )\n}\n"],"mappings":"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"}
@@ -7,6 +7,16 @@ const require_text_codec = require("../util/text-codec.cjs");
7
7
  * must be percent-encoded using UTF-8 byte values.
8
8
  */
9
9
  var SAFE_CHARS = new Set("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$&'()*+,;=:@/".split(""));
10
+ var FILE_INFO_VALUE_SAFE_CHARS = new Set("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~".split(""));
11
+ function encodeWithSafeChars(value, safeChars) {
12
+ const encoded = [];
13
+ for (const char of value) if (safeChars.has(char)) encoded.push(char);
14
+ else {
15
+ const bytes = require_text_codec.utf8Encoder.encode(char);
16
+ for (const byte of bytes) encoded.push(`%${byte.toString(16).toUpperCase().padStart(2, "0")}`);
17
+ }
18
+ return encoded.join("");
19
+ }
10
20
  /**
11
21
  * Percent-encodes a file name using the B2-specific encoding rules.
12
22
  *
@@ -19,13 +29,21 @@ var SAFE_CHARS = new Set("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01
19
29
  * @returns The percent-encoded file name suitable for `X-Bz-File-Name` headers.
20
30
  */
21
31
  function encodeFileName(name) {
22
- const encoded = [];
23
- for (const char of name) if (SAFE_CHARS.has(char)) encoded.push(char);
24
- else {
25
- const bytes = require_text_codec.utf8Encoder.encode(char);
26
- for (const byte of bytes) encoded.push(`%${byte.toString(16).toUpperCase().padStart(2, "0")}`);
27
- }
28
- return encoded.join("");
32
+ return encodeWithSafeChars(name, SAFE_CHARS);
33
+ }
34
+ /**
35
+ * Percent-encodes a file-info value using the stricter B2 metadata value rules.
36
+ *
37
+ * File-info values must be decoded by B2 before storage. Live B2 rejects comma
38
+ * and other RFC punctuation when left raw in these values, so only RFC 3986
39
+ * unreserved characters are passed through.
40
+ *
41
+ * @param value - The raw (unencoded) file-info value.
42
+ *
43
+ * @returns The percent-encoded value suitable for `X-Bz-Info-*` header values.
44
+ */
45
+ function encodeFileInfoValue(value) {
46
+ return encodeWithSafeChars(value, FILE_INFO_VALUE_SAFE_CHARS);
29
47
  }
30
48
  /**
31
49
  * Decodes a B2 percent-encoded file name back to a plain string.
@@ -43,8 +61,9 @@ function decodeFileName(encoded) {
43
61
  /**
44
62
  * Converts a file-info map into `X-Bz-Info-*` HTTP headers.
45
63
  *
46
- * Both keys and values are percent-encoded with {@link encodeFileName}
47
- * to satisfy B2 header requirements.
64
+ * Keys use B2 file-name encoding. Values use stricter B2 file-info value
65
+ * encoding so punctuation such as commas is percent-encoded before B2 decodes
66
+ * and validates stored metadata.
48
67
  *
49
68
  * @param fileInfo - Key/value pairs to attach as custom file info, or `undefined`.
50
69
  *
@@ -53,7 +72,7 @@ function decodeFileName(encoded) {
53
72
  function buildFileInfoHeaders(fileInfo) {
54
73
  if (!fileInfo) return {};
55
74
  const headers = {};
56
- for (const [key, value] of Object.entries(fileInfo)) headers[`X-Bz-Info-${encodeFileName(key)}`] = encodeFileName(value);
75
+ for (const [key, value] of Object.entries(fileInfo)) headers[`X-Bz-Info-${encodeFileName(key)}`] = encodeFileInfoValue(value);
57
76
  return headers;
58
77
  }
59
78
  /**