@keboola/api-client 47.0.0 → 48.0.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 (277) hide show
  1. package/AGENTS.md +9 -3
  2. package/API-SURFACE.md +4 -2
  3. package/CHANGELOG.md +31 -0
  4. package/README.md +1 -1
  5. package/dist/{adminRoles-DGM8SuuF.d.cts → adminRoles-BgpaBE7h.d.cts} +2 -2
  6. package/dist/{adminRoles-CvdIUkiC.d.ts → adminRoles-DsoGQipO.d.ts} +2 -2
  7. package/dist/ai/index.cjs +0 -5
  8. package/dist/ai/index.cjs.map +1 -1
  9. package/dist/ai/index.d.cts +2 -3
  10. package/dist/ai/index.d.ts +2 -3
  11. package/dist/ai/index.js +0 -5
  12. package/dist/ai/index.js.map +1 -1
  13. package/dist/ai/types.d.cts +2 -2
  14. package/dist/ai/types.d.ts +2 -2
  15. package/dist/{appLogs-xW0-JQXg.d.ts → appLogs-DpcqeOe5.d.ts} +2 -2
  16. package/dist/{appLogs-Cxhm2Rkn.d.cts → appLogs-SjrflOHk.d.cts} +2 -2
  17. package/dist/apps/index.cjs +2 -2
  18. package/dist/apps/index.cjs.map +1 -1
  19. package/dist/apps/index.d.cts +3 -3
  20. package/dist/apps/index.d.ts +3 -3
  21. package/dist/apps/index.js +2 -2
  22. package/dist/apps/index.js.map +1 -1
  23. package/dist/apps/types.d.cts +2 -2
  24. package/dist/apps/types.d.ts +2 -2
  25. package/dist/assets/index.d.cts +1 -1
  26. package/dist/assets/index.d.ts +1 -1
  27. package/dist/auth/index.d.cts +1 -1
  28. package/dist/auth/index.d.ts +1 -1
  29. package/dist/auth/types.d.cts +1 -1
  30. package/dist/auth/types.d.ts +1 -1
  31. package/dist/{authClient-Bso5UaXS.d.ts → authClient-BYIGzL_u.d.ts} +4 -4
  32. package/dist/{authClient-aud2dUZd.d.cts → authClient-D06srBQE.d.cts} +4 -4
  33. package/dist/billing/index.d.cts +1 -1
  34. package/dist/billing/index.d.ts +1 -1
  35. package/dist/billing/types.d.cts +1 -1
  36. package/dist/billing/types.d.ts +1 -1
  37. package/dist/chat/index.d.cts +2 -2
  38. package/dist/chat/index.d.ts +2 -2
  39. package/dist/chat/types.d.cts +1 -1
  40. package/dist/chat/types.d.ts +1 -1
  41. package/dist/componentsMcp/index.d.cts +1 -1
  42. package/dist/componentsMcp/index.d.ts +1 -1
  43. package/dist/componentsMcp/types.d.cts +1 -1
  44. package/dist/componentsMcp/types.d.ts +1 -1
  45. package/dist/{configurations-D_Rbs0Wl.cjs → configurations-B2O8AAy0.cjs} +2 -2
  46. package/dist/{configurations-D_Rbs0Wl.cjs.map → configurations-B2O8AAy0.cjs.map} +1 -1
  47. package/dist/{configurations-Chg_JwJ1.js → configurations-CL0ouUMa.js} +3 -3
  48. package/dist/configurations-CL0ouUMa.js.map +1 -0
  49. package/dist/{configurations-BTRHVSRq.cjs → configurations-D9J3jh3g.cjs} +3 -3
  50. package/dist/configurations-D9J3jh3g.cjs.map +1 -0
  51. package/dist/{configurations-DcpUlC8I.js → configurations-DKINmjA3.js} +2 -2
  52. package/dist/{configurations-DcpUlC8I.js.map → configurations-DKINmjA3.js.map} +1 -1
  53. package/dist/constants/index.d.cts +2 -2
  54. package/dist/constants/index.d.ts +2 -2
  55. package/dist/dataScience/index.d.cts +2 -2
  56. package/dist/dataScience/index.d.ts +2 -2
  57. package/dist/dataScience/types.d.cts +2 -2
  58. package/dist/dataScience/types.d.ts +2 -2
  59. package/dist/developerPortal/index.d.cts +2 -2
  60. package/dist/developerPortal/index.d.ts +2 -2
  61. package/dist/developerPortal/types.d.cts +1 -1
  62. package/dist/developerPortal/types.d.ts +1 -1
  63. package/dist/domain/permissions/index.cjs +1 -1
  64. package/dist/domain/permissions/index.d.cts +2 -2
  65. package/dist/domain/permissions/index.d.ts +2 -2
  66. package/dist/domain/permissions/index.js +1 -1
  67. package/dist/editor/index.d.cts +2 -2
  68. package/dist/editor/index.d.ts +2 -2
  69. package/dist/editor/types.d.cts +1 -1
  70. package/dist/editor/types.d.ts +1 -1
  71. package/dist/encryption/index.d.cts +1 -1
  72. package/dist/encryption/index.d.ts +1 -1
  73. package/dist/encryption/types.d.cts +1 -1
  74. package/dist/encryption/types.d.ts +1 -1
  75. package/dist/import/index.d.cts +3 -3
  76. package/dist/import/index.d.ts +3 -3
  77. package/dist/{index-CAWy1qjR.d.ts → index-B3QTeqfL.d.ts} +300 -140
  78. package/dist/{index-Ds0tViQS.d.cts → index-BCjU-g9t.d.cts} +3 -3
  79. package/dist/{index-BGEuaZqI.d.cts → index-BHiJu8LF.d.cts} +9 -4
  80. package/dist/{index-BeOd45XE.d.ts → index-BIldED4N.d.ts} +4 -4
  81. package/dist/{index-B_MzjCeE.d.ts → index-BLvmyehw.d.ts} +3 -3
  82. package/dist/{index-DloFSSj3.d.ts → index-BTrxCk90.d.ts} +3 -3
  83. package/dist/{index-x_kS_5x_.d.cts → index-ByLCYBaw.d.cts} +4 -4
  84. package/dist/{index-CkwZ5x7E.d.cts → index-C40Fbj-6.d.cts} +300 -140
  85. package/dist/{index-Dp-a2DdI.d.ts → index-CIqWOEWD.d.ts} +4 -4
  86. package/dist/{index-DTysQ_yn.d.cts → index-Cc5wSIRJ.d.cts} +5 -5
  87. package/dist/{index-XaPb6unB.d.cts → index-ChDl6ig5.d.cts} +256 -33
  88. package/dist/{index-URgNfi5L.d.cts → index-Co2Cd-nw.d.cts} +3 -3
  89. package/dist/{index-DUB0BwQv.d.cts → index-CpGmmJbt.d.cts} +4 -4
  90. package/dist/{index-ZYvgoqgW.d.cts → index-CpUYVB-d.d.cts} +4 -4
  91. package/dist/{index-BnPmXDVP.d.ts → index-CzHrIfZS.d.ts} +2 -2
  92. package/dist/{index-XG5cO-4H.d.cts → index-D91RxB_S.d.cts} +18 -13
  93. package/dist/{index-_Va9wynk.d.ts → index-DlZiWfQb.d.ts} +9 -4
  94. package/dist/{index-HSkjm3QW.d.ts → index-DzLXtE4Q.d.ts} +5 -5
  95. package/dist/{index-8ZjY7YD8.d.cts → index-VlzlOBkc.d.cts} +2 -2
  96. package/dist/{index-BIP0PoMW.d.ts → index-avzO5sLa.d.ts} +18 -13
  97. package/dist/{index-C2OAOK0s.d.ts → index-m7fX76x3.d.ts} +4 -4
  98. package/dist/{index-r6YSe8B-.d.ts → index-sDHBkJhU.d.ts} +256 -33
  99. package/dist/index.cjs +451 -256
  100. package/dist/index.cjs.map +1 -1
  101. package/dist/index.d.cts +6 -6
  102. package/dist/index.d.ts +6 -6
  103. package/dist/index.js +451 -257
  104. package/dist/index.js.map +1 -1
  105. package/dist/kaiAgent/index.cjs +1 -1
  106. package/dist/kaiAgent/index.d.cts +3 -3
  107. package/dist/kaiAgent/index.d.ts +3 -3
  108. package/dist/kaiAgent/index.js +1 -1
  109. package/dist/kaiAgent/types.d.cts +1 -1
  110. package/dist/kaiAgent/types.d.ts +1 -1
  111. package/dist/{kaiAgent-CBPbMwBh.js → kaiAgent-CYvrS8oZ.js} +12 -3
  112. package/dist/kaiAgent-CYvrS8oZ.js.map +1 -0
  113. package/dist/{kaiAgent-BmfUG8bB.cjs → kaiAgent-N2qbUFZm.cjs} +12 -3
  114. package/dist/kaiAgent-N2qbUFZm.cjs.map +1 -0
  115. package/dist/management/index.cjs +1 -1
  116. package/dist/management/index.d.cts +1 -1
  117. package/dist/management/index.d.ts +1 -1
  118. package/dist/management/index.js +1 -1
  119. package/dist/management/types.d.cts +2 -2
  120. package/dist/management/types.d.ts +2 -2
  121. package/dist/{management-BUGPJ1Bu.cjs → management-CXHnxVaZ.cjs} +12 -5
  122. package/dist/management-CXHnxVaZ.cjs.map +1 -0
  123. package/dist/{management-DAg2obYt.js → management-NYAD6ej4.js} +12 -5
  124. package/dist/management-NYAD6ej4.js.map +1 -0
  125. package/dist/metastore/index.d.cts +1 -1
  126. package/dist/metastore/index.d.ts +1 -1
  127. package/dist/metastore/types.d.cts +1 -1
  128. package/dist/metastore/types.d.ts +1 -1
  129. package/dist/microsoftGraph/index.d.cts +2 -2
  130. package/dist/microsoftGraph/index.d.ts +2 -2
  131. package/dist/microsoftGraph/types.d.cts +1 -1
  132. package/dist/microsoftGraph/types.d.ts +1 -1
  133. package/dist/{middleware-DU_5pFDW.cjs → middleware-CEP6uu_D.cjs} +4 -4
  134. package/dist/middleware-CEP6uu_D.cjs.map +1 -0
  135. package/dist/{middleware-CWaLMlG1.js → middleware-GOfx8Apu.js} +4 -4
  136. package/dist/middleware-GOfx8Apu.js.map +1 -0
  137. package/dist/notifications/index.d.cts +2 -2
  138. package/dist/notifications/index.d.ts +2 -2
  139. package/dist/notifications/types.d.cts +1 -1
  140. package/dist/notifications/types.d.ts +1 -1
  141. package/dist/oauth/index.d.cts +2 -2
  142. package/dist/oauth/index.d.ts +2 -2
  143. package/dist/oauth/types.d.cts +1 -1
  144. package/dist/oauth/types.d.ts +1 -1
  145. package/dist/omnisearch/index.d.cts +2 -2
  146. package/dist/omnisearch/index.d.ts +2 -2
  147. package/dist/omnisearch/types.d.cts +1 -1
  148. package/dist/omnisearch/types.d.ts +1 -1
  149. package/dist/{project-dxCJbFay.d.cts → project-Dzu85cqr.d.cts} +3 -3
  150. package/dist/{project-BMmfPhXg.d.ts → project-nbv9yjpl.d.ts} +3 -3
  151. package/dist/queryService/index.d.cts +1 -1
  152. package/dist/queryService/index.d.ts +1 -1
  153. package/dist/queryService/types.d.cts +1 -1
  154. package/dist/queryService/types.d.ts +1 -1
  155. package/dist/queue/index.d.cts +3 -3
  156. package/dist/queue/index.d.ts +3 -3
  157. package/dist/queue/types.d.cts +1 -1
  158. package/dist/queue/types.d.ts +1 -1
  159. package/dist/scheduler/index.d.cts +2 -2
  160. package/dist/scheduler/index.d.ts +2 -2
  161. package/dist/scheduler/types.d.cts +1 -1
  162. package/dist/scheduler/types.d.ts +1 -1
  163. package/dist/sdk/configurations/index.cjs +1 -1
  164. package/dist/sdk/configurations/index.d.cts +2 -2
  165. package/dist/sdk/configurations/index.d.ts +2 -2
  166. package/dist/sdk/configurations/index.js +1 -1
  167. package/dist/sdk/developerPortal/index.cjs +1 -1
  168. package/dist/sdk/developerPortal/index.d.cts +3 -3
  169. package/dist/sdk/developerPortal/index.d.ts +3 -3
  170. package/dist/sdk/developerPortal/index.js +1 -1
  171. package/dist/sdk/kaiMemory/index.d.cts +1 -1
  172. package/dist/sdk/kaiMemory/index.d.ts +1 -1
  173. package/dist/sdk/kaiMemory/types.d.cts +1 -1
  174. package/dist/sdk/kaiMemory/types.d.ts +1 -1
  175. package/dist/sdk/queryService/index.d.cts +1 -1
  176. package/dist/sdk/queryService/index.d.ts +1 -1
  177. package/dist/sdk/semanticLayer/index.d.cts +1 -1
  178. package/dist/sdk/semanticLayer/index.d.ts +1 -1
  179. package/dist/sdk/semanticLayer/types.d.cts +1 -1
  180. package/dist/sdk/semanticLayer/types.d.ts +1 -1
  181. package/dist/sdk/tag/index.d.cts +2 -2
  182. package/dist/sdk/tag/index.d.ts +2 -2
  183. package/dist/sdk/tag/types.d.cts +1 -1
  184. package/dist/sdk/tag/types.d.ts +1 -1
  185. package/dist/sdk/vault/index.d.cts +1 -1
  186. package/dist/sdk/vault/index.d.ts +1 -1
  187. package/dist/status/index.d.cts +1 -1
  188. package/dist/status/index.d.ts +1 -1
  189. package/dist/storage/index.cjs +1 -1
  190. package/dist/storage/index.d.cts +2 -2
  191. package/dist/storage/index.d.ts +2 -2
  192. package/dist/storage/index.js +1 -1
  193. package/dist/storage/types.d.cts +6 -6
  194. package/dist/storage/types.d.ts +6 -6
  195. package/dist/{storage-DyR7hDdv.js → storage-BR-Kgi-6.js} +7 -2
  196. package/dist/storage-BR-Kgi-6.js.map +1 -0
  197. package/dist/{storage-yovv11k6.cjs → storage-CVBXivpB.cjs} +7 -2
  198. package/dist/storage-CVBXivpB.cjs.map +1 -0
  199. package/dist/stream/index.d.cts +2 -2
  200. package/dist/stream/index.d.ts +2 -2
  201. package/dist/stream/types.d.cts +1 -1
  202. package/dist/stream/types.d.ts +1 -1
  203. package/dist/syncActions/index.d.cts +2 -2
  204. package/dist/syncActions/index.d.ts +2 -2
  205. package/dist/syncActions/types.d.cts +1 -1
  206. package/dist/syncActions/types.d.ts +1 -1
  207. package/dist/telemetry/index.d.cts +2 -2
  208. package/dist/telemetry/index.d.ts +2 -2
  209. package/dist/telemetry/types.d.cts +1 -1
  210. package/dist/telemetry/types.d.ts +1 -1
  211. package/dist/{types-L50Y6ATu.d.cts → types-0ZAMQhva.d.cts} +3 -3
  212. package/dist/{types-BoH7NFCh.d.ts → types-1LENlL5h.d.ts} +3 -3
  213. package/dist/{types-kbyIaA7p.d.cts → types-6KabdIyO.d.cts} +3 -3
  214. package/dist/{types-Bx0TSdwF.d.cts → types-9d8ihjZh.d.cts} +2 -2
  215. package/dist/{types-COQOzyac.d.ts → types-B7L6uSYb.d.ts} +7 -3
  216. package/dist/{types-DWJVbskE.d.ts → types-BTy_FFSu.d.ts} +2 -2
  217. package/dist/{types-4HmtNuJf.d.ts → types-BWYtQkHu.d.ts} +2 -2
  218. package/dist/{types-BIDKSQdc.d.ts → types-BXHZQvGy.d.ts} +169 -31
  219. package/dist/{types-B2ZLjagf.d.ts → types-BYFU_6Iz.d.ts} +2 -2
  220. package/dist/{types-BNPvFLgC.d.ts → types-BaqdM92a.d.ts} +3 -4
  221. package/dist/{types-BKIcow3B.d.cts → types-BbwrMl0Q.d.cts} +2 -2
  222. package/dist/{types-Dg8a7m7f.d.ts → types-Bt8CEZ6K.d.ts} +2 -2
  223. package/dist/{types-4bSZLxq3.d.cts → types-BtS3DhGu.d.cts} +169 -31
  224. package/dist/{types-C2j6Jsie.d.ts → types-C-GSYDTN.d.ts} +3 -3
  225. package/dist/{types-BwsE-pFo.d.cts → types-C4eQ-Zcx.d.cts} +2 -2
  226. package/dist/{types-ij6BpTzR.d.ts → types-C9VaQSqV.d.ts} +2 -2
  227. package/dist/{types-BZBU3mwz.d.cts → types-CNkQuWnO.d.cts} +3 -3
  228. package/dist/{types-TRJiPqJr.d.cts → types-CXv_e6xC.d.cts} +2 -2
  229. package/dist/{types-CMKIdreQ.d.cts → types-C_raqbl-.d.cts} +3 -3
  230. package/dist/{types-BjEiUOL6.d.ts → types-Cc4yTEdK.d.ts} +2 -2
  231. package/dist/{types-ituiCs8g.d.ts → types-Ce5Blzhg.d.ts} +2 -2
  232. package/dist/{types-CBrNIgEy.d.ts → types-CfZLdfAL.d.ts} +3 -3
  233. package/dist/{types-4CjbcUdD.d.cts → types-Cfc-fYbq.d.cts} +2 -2
  234. package/dist/{types-DHlXKVEM.d.ts → types-Cn8I0vcr.d.ts} +3 -3
  235. package/dist/{types-C7t_6FLh.d.ts → types-CpWE6Yg2.d.ts} +2 -2
  236. package/dist/{types-DBJ8c3hN.d.cts → types-CrJIILXf.d.cts} +2 -2
  237. package/dist/{types-B_3zoXA1.d.cts → types-CwGbiMF-.d.cts} +3 -3
  238. package/dist/{types-BiTn_JVW.d.cts → types-CwQ8_n8q.d.ts} +94 -13
  239. package/dist/{types-Cw9UISvM.d.ts → types-D3H3EAre.d.ts} +2 -2
  240. package/dist/{types-BG0oWq8u.d.cts → types-D3mj56iq.d.cts} +2 -2
  241. package/dist/{types-D51g4h9w.d.cts → types-D8d5tyGi.d.cts} +2 -2
  242. package/dist/{types-CZCPdPqv.d.cts → types-DMpiG2q4.d.cts} +3 -3
  243. package/dist/{types-DPDq8C4q.d.cts → types-DSBrhK_K.d.cts} +2 -2
  244. package/dist/{types--qQPfxWt.d.cts → types-DXF6faow.d.cts} +2 -2
  245. package/dist/{types-BXgINefw.d.ts → types-DfJP6Dti.d.ts} +2 -2
  246. package/dist/{types-C3IQu1gV.d.ts → types-DgOLSRiy.d.ts} +3 -3
  247. package/dist/{types-BdF6NDvo.d.cts → types-DlgqPU_4.d.cts} +2 -2
  248. package/dist/{types-C2JMisvL.d.ts → types-Dn1G-qv4.d.cts} +94 -13
  249. package/dist/{types-B6ozaDkl.d.cts → types-EkyQ0_10.d.cts} +2 -2
  250. package/dist/{types-B_1plf0y.d.cts → types-EmIcG-8K.d.cts} +2 -2
  251. package/dist/{types-D8w9lyb8.d.cts → types-NSxpnYW5.d.cts} +7 -3
  252. package/dist/{types-CEw2IzWk.d.ts → types-QPW-7dPm.d.ts} +2 -2
  253. package/dist/{types-BcQ3j8xK.d.ts → types-UySfduQo.d.ts} +2 -2
  254. package/dist/{types-7DBpH7Rf.d.ts → types-VehpPOQX.d.ts} +2 -2
  255. package/dist/{types-BiBBKcin.d.ts → types-Vu09EUZs.d.ts} +3 -3
  256. package/dist/{types-DgIzXY-Y.d.ts → types-c4h2YDMC.d.ts} +2 -2
  257. package/dist/{types-OkQWmonU.d.cts → types-sOM2_KPc.d.cts} +2 -2
  258. package/dist/{types-BBbzWczQ.d.cts → types-wNuJUhco.d.cts} +3 -4
  259. package/dist/vault/index.d.cts +1 -1
  260. package/dist/vault/index.d.ts +1 -1
  261. package/dist/vault/types.d.cts +1 -1
  262. package/dist/vault/types.d.ts +1 -1
  263. package/package.json +1 -1
  264. package/surface/ai.md +0 -1
  265. package/surface/kaiAgent.md +5 -4
  266. package/surface/management.md +1 -0
  267. package/surface/storage.md +3 -2
  268. package/dist/configurations-BTRHVSRq.cjs.map +0 -1
  269. package/dist/configurations-Chg_JwJ1.js.map +0 -1
  270. package/dist/kaiAgent-BmfUG8bB.cjs.map +0 -1
  271. package/dist/kaiAgent-CBPbMwBh.js.map +0 -1
  272. package/dist/management-BUGPJ1Bu.cjs.map +0 -1
  273. package/dist/management-DAg2obYt.js.map +0 -1
  274. package/dist/middleware-CWaLMlG1.js.map +0 -1
  275. package/dist/middleware-DU_5pFDW.cjs.map +0 -1
  276. package/dist/storage-DyR7hDdv.js.map +0 -1
  277. package/dist/storage-yovv11k6.cjs.map +0 -1
package/dist/index.js CHANGED
@@ -5,11 +5,11 @@ import { t as concurrent } from "./concurrent-BacWxPwi.js";
5
5
  import { t as dedupe } from "./dedupe-Cky1gSUu.js";
6
6
  import { a as poller, c as Result, d as delay, i as failureOf, l as asError, n as jobStatus, o as clamp, r as emitter, s as finiteOr, u as lazy } from "./transientRetries-B4iusp69.js";
7
7
  import { n as createEmitter, t as createStore } from "./store-C9FQCHGe.js";
8
- import { a as StorageJobError, c as readableReason, l as series, o as isStorageJobError, s as ServiceUnavailableError, t as createStorageClient } from "./storage-DyR7hDdv.js";
8
+ import { a as StorageJobError, c as readableReason, l as series, o as isStorageJobError, s as ServiceUnavailableError, t as createStorageClient } from "./storage-BR-Kgi-6.js";
9
9
  import { n as keboolaUID, t as createTagSdk } from "./tag-hh-1nhNr.js";
10
10
  import { t as generateUUID } from "./generateUUID-Dr8l-aoc.js";
11
11
  import { t as isPlainObject } from "./isPlainObject-LYW-03uB.js";
12
- import { n as schemaGuidedMerge, r as isEmptyDeep, t as createConfigurationSdk } from "./configurations-DcpUlC8I.js";
12
+ import { n as schemaGuidedMerge, r as isEmptyDeep, t as createConfigurationSdk } from "./configurations-DKINmjA3.js";
13
13
  import { t as UserError } from "./UserError-By_Zckmc.js";
14
14
  import { _ as KeboolaHttpHeader, a as isTimeoutError, d as normalizeBaseUrl, g as HttpStatus, i as isFetchClientError, m as CREDENTIAL_HEADERS, n as isAbortError, o as HttpContentType, p as ApiError, r as isApiError, s as HttpHeader, v as REDACTED, y as redactHeaders } from "./createFetchClient-CkHdS_IG.js";
15
15
  import { n as HtmlResponseError, r as isHtmlResponseError } from "./validateConnectionStatus-DyrYpn0G.js";
@@ -20,7 +20,7 @@ import { n as isSyncActionError, t as SyncActionError } from "./SyncActionError-
20
20
  import { i as parseOrThrow, n as formatValidationIssues, r as isValidationError, t as ValidationError } from "./ValidationError-DjhtNMfZ.js";
21
21
  import { t as createGenericFetchClient } from "./createGenericFetchClient-CQdNcPC3.js";
22
22
  import { t as createImportClient } from "./import-FWy_wQZ1.js";
23
- import { n as isManagementClientAuthError, r as isManagementSessionMintError, t as createManagementClient } from "./management-DAg2obYt.js";
23
+ import { n as isManagementClientAuthError, r as isManagementSessionMintError, t as createManagementClient } from "./management-NYAD6ej4.js";
24
24
  import { o as ServiceId, s as ProjectFeature } from "./constants-CA4UN2Xv.js";
25
25
  import { t as createStorageTable } from "./storageTable-BldTNyEk.js";
26
26
  import { i as createKaiMemorySdk } from "./kaiMemory-C9di17bd.js";
@@ -35,7 +35,7 @@ import { t as createComponentsMcpClient } from "./componentsMcp-CHobIsuU.js";
35
35
  import { t as createDataScienceClient } from "./dataScience-AwPMeGfz.js";
36
36
  import { createEditorClient } from "./editor/index.js";
37
37
  import { createEncryptionClient } from "./encryption/index.js";
38
- import { t as createKaiAgentClient } from "./kaiAgent-CBPbMwBh.js";
38
+ import { t as createKaiAgentClient } from "./kaiAgent-CYvrS8oZ.js";
39
39
  import { t as createMetastoreClient } from "./metastore-Ywq08DBz.js";
40
40
  import { createNotificationsClient } from "./notifications/index.js";
41
41
  import { t as createOauthClient } from "./oauth-GXmZ9agP.js";
@@ -47,7 +47,7 @@ import { createStreamClient } from "./stream/index.js";
47
47
  import { t as createSyncActionsClient } from "./syncActions-DM8vP7p3.js";
48
48
  import { createTelemetryClient } from "./telemetry/index.js";
49
49
  import { createVaultClient } from "./vault/index.js";
50
- import { n as isUnauthorized, t as createBearerAuthMiddleware } from "./middleware-CWaLMlG1.js";
50
+ import { n as isUnauthorized, t as createBearerAuthMiddleware } from "./middleware-GOfx8Apu.js";
51
51
  import { createQueryServiceSdk } from "./sdk/queryService/index.js";
52
52
  import * as z$1 from "zod";
53
53
  //#region src/utils/assert.ts
@@ -260,6 +260,47 @@ const createPollRegistry = ({ limit = DEFAULT_LIMIT } = {}) => {
260
260
  };
261
261
  };
262
262
  //#endregion
263
+ //#region src/utils/async/queueSeries.ts
264
+ const isPromiseLike = (value) => (typeof value === "object" && value !== null || typeof value === "function") && "then" in value && typeof value.then === "function";
265
+ /**
266
+ * Queues tasks added over time so a slower earlier task cannot finish after and overwrite a later one.
267
+ * Each `add` returns its task's result; a rejection does not stop the remaining queue.
268
+ */
269
+ const queueSeries = () => {
270
+ let tail = null;
271
+ const add = (task) => {
272
+ if (tail !== null) {
273
+ const result = tail.then(task);
274
+ tail = result.then(() => void 0, () => void 0);
275
+ return result;
276
+ }
277
+ let value;
278
+ try {
279
+ value = task();
280
+ } catch (error) {
281
+ return Promise.reject(error);
282
+ }
283
+ if (!isPromiseLike(value)) return Promise.resolve(value);
284
+ const result = Promise.resolve(value);
285
+ tail = result.then(() => void 0, () => void 0);
286
+ return result;
287
+ };
288
+ const onIdle = async () => {
289
+ while (tail !== null) {
290
+ const current = tail;
291
+ await current;
292
+ if (tail === current) {
293
+ tail = null;
294
+ return;
295
+ }
296
+ }
297
+ };
298
+ return {
299
+ add,
300
+ onIdle
301
+ };
302
+ };
303
+ //#endregion
263
304
  //#region src/utils/deepMerge.ts
264
305
  /**
265
306
  * Recursively merge `patch` into `base`. Plain-object values are merged key-by-key; every
@@ -317,6 +358,10 @@ const createWebStorage = (pick) => {
317
358
  },
318
359
  removeItem: (key) => {
319
360
  storage.removeItem(key);
361
+ },
362
+ withLock: async (name, task) => {
363
+ if (typeof navigator === "undefined" || !("locks" in navigator)) return task();
364
+ return navigator.locks.request(`keboola:${name}`, { mode: "exclusive" }, task);
320
365
  }
321
366
  };
322
367
  };
@@ -325,62 +370,56 @@ const createSessionStorage = () => createWebStorage(() => "sessionStorage" in gl
325
370
  //#endregion
326
371
  //#region src/utils/persistor/persistor.ts
327
372
  const createPersistor = ({ storage = createNullStorage(), key, schema, defaultValue, encode = JSON.stringify, decode = JSON.parse }) => {
328
- const clear = () => {
329
- try {
330
- storage.removeItem(key);
331
- } catch (err) {
332
- console.warn(`createPersistor: failed to clear "${key}"`, err);
333
- }
334
- };
335
- const hasPersistedValue = () => {
336
- try {
337
- return !!storage.getItem(key);
338
- } catch (err) {
339
- console.warn(`createPersistor: failed to read "${key}", assuming empty`, err);
340
- return false;
341
- }
342
- };
343
- const hydrate = () => {
344
- let raw;
345
- try {
346
- raw = storage.getItem(key);
347
- } catch (err) {
348
- console.warn(`createPersistor: failed to read "${key}", using default`, err);
349
- return defaultValue;
350
- }
351
- if (raw === null) return defaultValue;
373
+ const writes = queueSeries();
374
+ const _load = async () => {
375
+ const raw = await storage.getItem(key);
376
+ if (raw === null) return {
377
+ value: defaultValue,
378
+ corrupt: false
379
+ };
352
380
  let decoded;
353
381
  try {
354
382
  decoded = decode(raw);
355
383
  } catch (err) {
356
- console.warn(`createPersistor: failed to decode "${key}", resetting`, err);
357
- clear();
358
- return defaultValue;
384
+ console.warn(`createPersistor: failed to decode "${key}"`, err);
385
+ return {
386
+ value: defaultValue,
387
+ corrupt: true
388
+ };
359
389
  }
360
390
  const parsed = schema.safeParse(decoded);
361
- if (parsed.success) return parsed.data;
362
- clear();
363
- return defaultValue;
391
+ return parsed.success ? {
392
+ value: parsed.data,
393
+ corrupt: false
394
+ } : {
395
+ value: defaultValue,
396
+ corrupt: true
397
+ };
364
398
  };
365
- const persist = (value) => {
366
- let raw;
367
- try {
368
- raw = encode(value);
369
- } catch (err) {
370
- console.warn(`createPersistor: failed to encode "${key}", not persisting`, err);
371
- return;
372
- }
373
- try {
374
- storage.setItem(key, raw);
375
- } catch (err) {
376
- console.warn(`createPersistor: failed to write "${key}"`, err);
377
- }
399
+ const remove = () => writes.add(() => storage.removeItem(key));
400
+ const write = (value) => writes.add(() => storage.setItem(key, encode(value)));
401
+ const read = async () => {
402
+ await writes.onIdle();
403
+ const parsed = await _load();
404
+ if (parsed.corrupt) remove().catch((err) => {
405
+ console.warn(`createPersistor: failed to drop the corrupt "${key}"`, err);
406
+ });
407
+ return parsed.value;
378
408
  };
409
+ const modify = (change) => writes.add(async () => {
410
+ const next = change((await _load()).value);
411
+ await storage.setItem(key, encode(next));
412
+ });
413
+ const cell = {
414
+ read,
415
+ write,
416
+ modify,
417
+ remove
418
+ };
419
+ const locked = (task) => storage.withLock ? storage.withLock(key, () => task(cell)) : task(cell);
379
420
  return {
380
- hydrate,
381
- persist,
382
- clear,
383
- hasPersistedValue
421
+ ...cell,
422
+ locked
384
423
  };
385
424
  };
386
425
  //#endregion
@@ -1072,159 +1111,6 @@ const createLegacyKeboola = (options = {}) => {
1072
1111
  };
1073
1112
  };
1074
1113
  //#endregion
1075
- //#region src/keboola/bearer/credentials/renewal.ts
1076
- const renewalGrant = (credential) => credential.type === "token" ? {
1077
- type: "token",
1078
- refreshToken: credential.refreshToken
1079
- } : {
1080
- type: "cookie",
1081
- sessionId: credential.sessionId
1082
- };
1083
- const renew = async (client, grant) => {
1084
- if (grant.type === "cookie") {
1085
- const { accessToken, expiresIn, sessionId } = await client.token.refreshWithSession({ sessionId: grant.sessionId });
1086
- return {
1087
- type: "cookie",
1088
- accessToken,
1089
- expiresIn,
1090
- sessionId
1091
- };
1092
- }
1093
- const { accessToken, expiresIn, refreshToken } = await client.token.refreshWithToken({ refreshToken: grant.refreshToken });
1094
- if (!refreshToken) throw new KeboolaError(KeboolaErrorType.NotAuthenticated);
1095
- return {
1096
- type: "token",
1097
- accessToken,
1098
- expiresIn,
1099
- refreshToken
1100
- };
1101
- };
1102
- //#endregion
1103
- //#region src/keboola/bearer/credentials/credentials.ts
1104
- const DEFAULT_REFRESH_THRESHOLD = .9;
1105
- const signInEnded = () => new KeboolaError(KeboolaErrorType.SignInEnded);
1106
- const toRestoreStatus = (outcome) => {
1107
- if (outcome === void 0 || outcome === "skipped") return "empty";
1108
- if (outcome === "refused") return "expired";
1109
- return outcome;
1110
- };
1111
- const createCredentials = ({ state, persistor, middlewares, refreshThreshold = DEFAULT_REFRESH_THRESHOLD, onSignedOut, onExpired }) => {
1112
- const rotationMap = /* @__PURE__ */ new Map();
1113
- const generations = /* @__PURE__ */ new Map();
1114
- const generationOf = (baseUrl) => generations.get(baseUrl) ?? 0;
1115
- const refresh = async (baseUrl, grant) => {
1116
- const client = createAuthClient({
1117
- baseUrl,
1118
- middlewares
1119
- });
1120
- const epochBefore = Result.unwrap(state.auth.getEpoch(baseUrl));
1121
- const generationBefore = generationOf(baseUrl);
1122
- const refreshed = await Result.tryCatchAsync(() => renew(client, grant));
1123
- return Result.unwrapOr(state.auth.getEpoch(baseUrl), -1) === epochBefore && generationOf(baseUrl) === generationBefore ? refreshed : Result.failure(signInEnded());
1124
- };
1125
- /**
1126
- * A stack's teardown, from the credential's side.
1127
- *
1128
- * - Bumps the generation, so an in-flight rotation can no longer write.
1129
- * - Drops the deduped entry, so nothing joins that rotation.
1130
- */
1131
- const forget = (baseUrl) => {
1132
- generations.set(baseUrl, generationOf(baseUrl) + 1);
1133
- rotationMap.delete(baseUrl);
1134
- };
1135
- /**
1136
- * The rotation, and the one place a credential is declared dead.
1137
- *
1138
- * - Renews by the credential's own kind: the refresh token, or the session id with the cookie.
1139
- * - A refused refresh token or session is unambiguous.
1140
- * - The triggering 401 is not (an unreachable project answers the same), so never sign out on a replay.
1141
- */
1142
- const rotateOnce = async (baseUrl) => {
1143
- const credential = state.auth.requireCredential(baseUrl);
1144
- if (!credential.success) return credential;
1145
- const refreshed = await refresh(baseUrl, renewalGrant(credential.data));
1146
- if (!refreshed.success) {
1147
- if (isUnauthorized(refreshed.error)) expire(baseUrl);
1148
- return refreshed;
1149
- }
1150
- return Result.map(state.auth.applyRefresh(baseUrl, refreshed.data), () => refreshed.data.accessToken);
1151
- };
1152
- const rotate = (baseUrl) => ensure(rotationMap, baseUrl, () => dedupe(() => rotateOnce(baseUrl)))();
1153
- const restoreStack = async (baseUrl, grant) => {
1154
- if (!state.auth.startRestore(baseUrl).success) return "unreachable";
1155
- const refreshed = await refresh(baseUrl, grant);
1156
- if (!refreshed.success) {
1157
- state.auth.cancelRestore(baseUrl);
1158
- return isUnauthorized(refreshed.error) ? "refused" : "unreachable";
1159
- }
1160
- state.auth.authenticate(baseUrl, refreshed.data);
1161
- return "restored";
1162
- };
1163
- const restoreProjects = (baseUrl, projects) => {
1164
- for (const { projectId } of projects) state.projects.open(baseUrl, projectId);
1165
- };
1166
- /**
1167
- * Every persisted stack back into the table, with whatever credential it can hand back.
1168
- *
1169
- * - Never writes the scope. `lastActive` is what was scoped when the session was stored, for the
1170
- * caller to select.
1171
- * - `status` reports what became of `lastActive`'s credential; the client reads it to decide
1172
- * when persistence may start.
1173
- */
1174
- const restore = async () => {
1175
- const { stacks, current } = persistor.hydrate();
1176
- const scoped = stacks.find(({ baseUrl }) => baseUrl === current?.baseUrl);
1177
- const restored = stacks.map(async ({ baseUrl, credential, projects }) => {
1178
- state.stacks.ensure(baseUrl);
1179
- if (!credential) return "unreachable";
1180
- if (Result.unwrapOr(state.auth.getEpoch(baseUrl), 0) > 0) return "skipped";
1181
- const outcome = await restoreStack(baseUrl, credential);
1182
- if (outcome === "restored") restoreProjects(baseUrl, projects);
1183
- return outcome;
1184
- });
1185
- const results = await Promise.all(restored);
1186
- const scopedOutcome = scoped?.credential ? results[stacks.indexOf(scoped)] : void 0;
1187
- return {
1188
- lastActive: current,
1189
- status: toRestoreStatus(scopedOutcome)
1190
- };
1191
- };
1192
- const isStale = (baseUrl) => {
1193
- const ageing = Result.map(state.auth.requireCredential(baseUrl), ({ issuedAt, expiresIn }) => Date.now() >= issuedAt + expiresIn * 1e3 * refreshThreshold);
1194
- return Result.unwrapOr(ageing, false);
1195
- };
1196
- const signOut = (baseUrl) => {
1197
- rotationMap.delete(baseUrl);
1198
- const signedOut = state.auth.signOut(baseUrl);
1199
- onSignedOut?.(baseUrl);
1200
- return signedOut;
1201
- };
1202
- const expire = (baseUrl) => {
1203
- if (!state.auth.notifyExpired(baseUrl)) return;
1204
- signOut(baseUrl);
1205
- onExpired?.(baseUrl);
1206
- };
1207
- const renewIfStale = async (baseUrl) => {
1208
- if (isStale(baseUrl)) await rotate(baseUrl);
1209
- };
1210
- const middleware = (baseUrl) => createBearerAuthMiddleware({ getAccessToken: async ({ forceRefresh = false } = {}) => {
1211
- if (forceRefresh) {
1212
- if (!state.auth.requireCredential(baseUrl).success) return null;
1213
- return Result.unwrap(await rotate(baseUrl));
1214
- }
1215
- await renewIfStale(baseUrl);
1216
- return state.auth.getAccessToken(baseUrl);
1217
- } });
1218
- return {
1219
- middleware,
1220
- rotate,
1221
- renewIfStale,
1222
- restore,
1223
- signOut,
1224
- forget
1225
- };
1226
- };
1227
- //#endregion
1228
1114
  //#region src/keboola/bearer/state/factories.ts
1229
1115
  /**
1230
1116
  * Everything the table constructs: the entries themselves, and the failures reading them produces.
@@ -1242,10 +1128,17 @@ const authenticatedAuth = (credential) => ({
1242
1128
  status: "authenticated",
1243
1129
  credential
1244
1130
  });
1245
- const bearerCredential = (input) => ({
1131
+ const credential = (input) => ({
1246
1132
  ...input,
1247
1133
  issuedAt: Date.now()
1248
1134
  });
1135
+ const grant = (credential) => credential.type === "token" ? {
1136
+ type: "token",
1137
+ refreshToken: credential.refreshToken
1138
+ } : {
1139
+ type: "cookie",
1140
+ sessionId: credential.sessionId
1141
+ };
1249
1142
  const expiredCredential = (credential) => ({
1250
1143
  ...credential,
1251
1144
  issuedAt: Date.now() - credential.expiresIn * 1e3
@@ -1254,7 +1147,8 @@ const stack = (baseUrl) => ({
1254
1147
  baseUrl,
1255
1148
  context: "idle",
1256
1149
  epoch: 0,
1257
- auth: anonymousAuth()
1150
+ auth: anonymousAuth(),
1151
+ retained: null
1258
1152
  });
1259
1153
  const project = (baseUrl, projectId) => ({
1260
1154
  id: projectEntryId(baseUrl, projectId),
@@ -1286,7 +1180,8 @@ const Entry = {
1286
1180
  anonymousAuth,
1287
1181
  restoringAuth,
1288
1182
  authenticatedAuth,
1289
- bearerCredential,
1183
+ credential,
1184
+ grant,
1290
1185
  expiredCredential
1291
1186
  };
1292
1187
  /**
@@ -1304,7 +1199,8 @@ const Errors = {
1304
1199
  notReady: () => new KeboolaError(KeboolaErrorType.NotReady),
1305
1200
  alreadyRestoring: (baseUrl) => /* @__PURE__ */ new Error(`Stack "${baseUrl}" is already being restored`),
1306
1201
  notRestoring: (baseUrl) => /* @__PURE__ */ new Error(`Stack "${baseUrl}" is not being restored`),
1307
- credentialKindChanged: (from, to) => /* @__PURE__ */ new Error(`A ${from} credential cannot become ${to}`),
1202
+ grantTypeChanged: (from, to) => /* @__PURE__ */ new Error(`A ${from} grant cannot become ${to}`),
1203
+ nothingRetained: (baseUrl) => /* @__PURE__ */ new Error(`Stack "${baseUrl}" retains no credential`),
1308
1204
  missingProject: (id) => /* @__PURE__ */ new Error(`No project "${id}"`)
1309
1205
  };
1310
1206
  const authenticated = (auth) => auth.status === "authenticated" ? Result.success(auth.credential) : Result.failure(Errors.notAuthenticated());
@@ -1349,25 +1245,37 @@ const createAuth = ({ stacks, projects, expiry }) => {
1349
1245
  return stacks.set({
1350
1246
  ...stack,
1351
1247
  epoch: stack.epoch + 1,
1352
- auth: Entry.authenticatedAuth(Entry.bearerCredential(input))
1248
+ auth: Entry.authenticatedAuth(Entry.credential(input)),
1249
+ retained: null
1353
1250
  });
1354
1251
  });
1355
- const applyRefresh = (baseUrl, input) => Result.andThen(stacks.requireCredential(baseUrl), (credential) => credential.type !== input.type ? Result.failure(Errors.credentialKindChanged(credential.type, input.type)) : Result.map(stacks.get(baseUrl), (stack) => stacks.set({
1252
+ const applyRefresh = (baseUrl, input) => Result.andThen(stacks.requireCredential(baseUrl), (credential) => credential.type !== input.type ? Result.failure(Errors.grantTypeChanged(credential.type, input.type)) : Result.map(stacks.get(baseUrl), (stack) => stacks.set({
1356
1253
  ...stack,
1357
- auth: Entry.authenticatedAuth(Entry.bearerCredential(input))
1254
+ auth: Entry.authenticatedAuth(Entry.credential(input))
1358
1255
  })));
1359
1256
  const forceExpire = (baseUrl) => Result.andThen(stacks.requireCredential(baseUrl), (credential) => Result.map(stacks.get(baseUrl), (stack) => stacks.set({
1360
1257
  ...stack,
1361
1258
  auth: Entry.authenticatedAuth(Entry.expiredCredential(credential))
1362
1259
  })));
1363
- const signOut = (baseUrl) => Result.map(stacks.get(baseUrl), (stack) => {
1260
+ const signOut = (baseUrl, { retain = false } = {}) => Result.map(stacks.get(baseUrl), (stack) => {
1364
1261
  projects.closeAll(baseUrl);
1262
+ const retained = retain ? Result.unwrapOr(Result.map(authenticated(stack.auth), (credential) => ({ grant: Entry.grant(credential) })), stack.retained) : null;
1365
1263
  return stacks.set({
1366
1264
  ...stack,
1367
1265
  epoch: stack.epoch + 1,
1368
- auth: Entry.anonymousAuth()
1266
+ auth: Entry.anonymousAuth(),
1267
+ retained
1369
1268
  });
1370
1269
  });
1270
+ const retain = (baseUrl, retained) => Result.map(stacks.get(baseUrl), (stack) => stacks.set({
1271
+ ...stack,
1272
+ retained
1273
+ }));
1274
+ const dropRetained = (baseUrl) => Result.map(stacks.get(baseUrl), (stack) => stacks.set({
1275
+ ...stack,
1276
+ retained: null
1277
+ }));
1278
+ const requireRetained = (baseUrl) => Result.andThen(stacks.get(baseUrl), (stack) => stack.retained ? Result.success(stack.retained) : Result.failure(Errors.nothingRetained(baseUrl)));
1371
1279
  const getEpoch = (baseUrl) => Result.map(stacks.get(baseUrl), (stack) => stack.epoch);
1372
1280
  const getAccessToken = (baseUrl) => Result.unwrapOr(Result.map(stacks.requireCredential(baseUrl), ({ accessToken }) => accessToken), null);
1373
1281
  return {
@@ -1377,6 +1285,9 @@ const createAuth = ({ stacks, projects, expiry }) => {
1377
1285
  applyRefresh,
1378
1286
  forceExpire,
1379
1287
  signOut,
1288
+ retain,
1289
+ dropRetained,
1290
+ requireRetained,
1380
1291
  notifyExpired: expiry.report,
1381
1292
  requireCredential: stacks.requireCredential,
1382
1293
  getEpoch,
@@ -1630,6 +1541,204 @@ const createState = (defaultBaseUrl) => {
1630
1541
  };
1631
1542
  };
1632
1543
  //#endregion
1544
+ //#region src/keboola/bearer/credentials/renewal.ts
1545
+ const renew = async (client, grant) => {
1546
+ if (grant.type === "cookie") {
1547
+ const { accessToken, expiresIn, sessionId } = await client.token.refreshWithSession({ sessionId: grant.sessionId });
1548
+ return {
1549
+ type: "cookie",
1550
+ accessToken,
1551
+ expiresIn,
1552
+ sessionId
1553
+ };
1554
+ }
1555
+ const { accessToken, expiresIn, refreshToken } = await client.token.refreshWithToken({ refreshToken: grant.refreshToken });
1556
+ if (!refreshToken) throw new KeboolaError(KeboolaErrorType.NotAuthenticated);
1557
+ return {
1558
+ type: "token",
1559
+ accessToken,
1560
+ expiresIn,
1561
+ refreshToken
1562
+ };
1563
+ };
1564
+ //#endregion
1565
+ //#region src/keboola/bearer/credentials/credentials.ts
1566
+ const DEFAULT_REFRESH_THRESHOLD = .9;
1567
+ const signInEnded = () => new KeboolaError(KeboolaErrorType.SignInEnded);
1568
+ const toRestoreStatus = (outcome) => {
1569
+ if (outcome === void 0 || outcome === "skipped") return "empty";
1570
+ if (outcome === "refused") return "expired";
1571
+ return outcome;
1572
+ };
1573
+ const createCredentials = ({ state, persistor, middlewares, refreshThreshold = DEFAULT_REFRESH_THRESHOLD, onSignedOut, onExpired }) => {
1574
+ const rotationMap = /* @__PURE__ */ new Map();
1575
+ const generations = /* @__PURE__ */ new Map();
1576
+ const generationOf = (baseUrl) => generations.get(baseUrl) ?? 0;
1577
+ const refresh = async (baseUrl, grant) => {
1578
+ const client = createAuthClient({
1579
+ baseUrl,
1580
+ middlewares
1581
+ });
1582
+ const epochBefore = Result.unwrap(state.auth.getEpoch(baseUrl));
1583
+ const generationBefore = generationOf(baseUrl);
1584
+ const refreshed = await Result.tryCatchAsync(() => renew(client, grant));
1585
+ return Result.unwrapOr(state.auth.getEpoch(baseUrl), -1) === epochBefore && generationOf(baseUrl) === generationBefore ? refreshed : Result.failure(signInEnded());
1586
+ };
1587
+ /**
1588
+ * A stack's teardown, from the credential's side.
1589
+ *
1590
+ * - Bumps the generation, so an in-flight rotation can no longer write.
1591
+ * - Drops the deduped entry, so nothing joins that rotation.
1592
+ */
1593
+ const forget = (baseUrl) => {
1594
+ generations.set(baseUrl, generationOf(baseUrl) + 1);
1595
+ rotationMap.delete(baseUrl);
1596
+ };
1597
+ /**
1598
+ * The rotation, and the one place a credential is declared dead.
1599
+ *
1600
+ * - Renews by the credential's grant: the refresh token, or the session id with the cookie.
1601
+ * - A refused refresh token or session is unambiguous.
1602
+ * - The triggering 401 is not (an unreachable project answers the same), so never sign out on a replay.
1603
+ */
1604
+ const getGrantForRotation = async (store, baseUrl, credential) => {
1605
+ const epochBefore = Result.unwrap(state.auth.getEpoch(baseUrl));
1606
+ const generationBefore = generationOf(baseUrl);
1607
+ const hydrated = await Result.tryCatchAsync(() => store.read());
1608
+ if (!hydrated.success) return hydrated;
1609
+ if (Result.unwrapOr(state.auth.getEpoch(baseUrl), -1) !== epochBefore || generationOf(baseUrl) !== generationBefore) return Result.failure(signInEnded());
1610
+ const persistedStack = hydrated.data.stacks.find((stack) => stack.baseUrl === baseUrl);
1611
+ if (persistedStack && persistedStack.credential === null) return Result.failure(signInEnded());
1612
+ return Result.success(persistedStack?.credential ?? Entry.grant(credential));
1613
+ };
1614
+ const rotateOnce = async (baseUrl) => persistor.locked(async (store) => {
1615
+ const credential = state.auth.requireCredential(baseUrl);
1616
+ if (!credential.success) return credential;
1617
+ const grant = await getGrantForRotation(store, baseUrl, credential.data);
1618
+ if (!grant.success) return grant;
1619
+ const refreshed = await refresh(baseUrl, grant.data);
1620
+ if (!refreshed.success) {
1621
+ if (isUnauthorized(refreshed.error)) await expire(baseUrl, store);
1622
+ return refreshed;
1623
+ }
1624
+ const accessToken = Result.map(state.auth.applyRefresh(baseUrl, refreshed.data), () => refreshed.data.accessToken);
1625
+ await store.persistStack(baseUrl, state.store.get());
1626
+ return accessToken;
1627
+ });
1628
+ const rotate = (baseUrl) => ensure(rotationMap, baseUrl, () => dedupe(() => rotateOnce(baseUrl)))();
1629
+ const restoreStack = async (baseUrl, grant, retained = false) => persistor.locked(async (store) => {
1630
+ const storedStack = (await store.read()).stacks.find((stack) => stack.baseUrl === baseUrl);
1631
+ const latestGrant = retained ? storedStack?.retained?.grant : storedStack?.credential;
1632
+ if (storedStack && !latestGrant) return "skipped";
1633
+ if (!state.auth.startRestore(baseUrl).success) return "unreachable";
1634
+ const refreshed = await refresh(baseUrl, latestGrant ?? grant);
1635
+ if (!refreshed.success) {
1636
+ state.auth.cancelRestore(baseUrl);
1637
+ if (isUnauthorized(refreshed.error)) {
1638
+ if (retained) state.auth.dropRetained(baseUrl);
1639
+ await store.persistStack(baseUrl, state.store.get());
1640
+ return "refused";
1641
+ }
1642
+ return "unreachable";
1643
+ }
1644
+ state.auth.authenticate(baseUrl, refreshed.data);
1645
+ if (!state.auth.requireCredential(baseUrl).success) return "unreachable";
1646
+ if (retained) state.auth.dropRetained(baseUrl);
1647
+ await store.persistStack(baseUrl, state.store.get());
1648
+ return "restored";
1649
+ });
1650
+ const restoreProjects = (baseUrl, projects) => {
1651
+ for (const { projectId } of projects) state.projects.open(baseUrl, projectId);
1652
+ };
1653
+ /**
1654
+ * Every persisted stack back into the table, with whatever credential it can hand back.
1655
+ *
1656
+ * - Never writes the scope. `lastActive` is what was scoped when the session was stored, for the
1657
+ * caller to select.
1658
+ * - `status` reports what became of `lastActive`'s credential; the client reads it to decide
1659
+ * when persistence may start.
1660
+ */
1661
+ const restore = async () => {
1662
+ const hydrated = await persistor.locked((store) => store.read()).catch((error) => {
1663
+ console.warn("createCredentials: the stored session could not be read", error);
1664
+ return null;
1665
+ });
1666
+ if (hydrated === null) return {
1667
+ lastActive: null,
1668
+ status: "unreachable"
1669
+ };
1670
+ const { stacks, current } = hydrated;
1671
+ const scoped = stacks.find(({ baseUrl }) => baseUrl === current?.baseUrl);
1672
+ const restored = stacks.map(async ({ baseUrl, credential, retained, projects }) => {
1673
+ state.stacks.ensure(baseUrl);
1674
+ if (!credential && !retained) return "unreachable";
1675
+ if (Result.unwrapOr(state.auth.getEpoch(baseUrl), 0) > 0) return "skipped";
1676
+ if (retained) state.auth.retain(baseUrl, retained);
1677
+ if (!credential) return "unreachable";
1678
+ const outcome = await restoreStack(baseUrl, credential);
1679
+ if (outcome === "restored") restoreProjects(baseUrl, projects);
1680
+ return outcome;
1681
+ });
1682
+ const results = await Promise.all(restored);
1683
+ const scopedOutcome = scoped?.credential ? results[stacks.indexOf(scoped)] : void 0;
1684
+ return {
1685
+ lastActive: current,
1686
+ status: toRestoreStatus(scopedOutcome)
1687
+ };
1688
+ };
1689
+ /**
1690
+ * Signs a retained stack back in from the grant it kept.
1691
+ *
1692
+ * - `restored` and `refused` empty the slot; `unreachable` keeps it for another try.
1693
+ * - Throws when the stack retains nothing.
1694
+ */
1695
+ const restoreRetained = async (baseUrl) => {
1696
+ const { grant } = Result.unwrap(state.auth.requireRetained(baseUrl));
1697
+ return restoreStack(baseUrl, grant, true);
1698
+ };
1699
+ const isStale = (baseUrl) => {
1700
+ const ageing = Result.map(state.auth.requireCredential(baseUrl), ({ issuedAt, expiresIn }) => Date.now() >= issuedAt + expiresIn * 1e3 * refreshThreshold);
1701
+ return Result.unwrapOr(ageing, false);
1702
+ };
1703
+ /**
1704
+ * Drops the slot so the next sign-in's requests don't join the dying rotation.
1705
+ *
1706
+ * - Writes nothing: the caller persists the stack, under the lock it holds or takes.
1707
+ */
1708
+ const signOut = (baseUrl, options) => {
1709
+ rotationMap.delete(baseUrl);
1710
+ const signedOut = state.auth.signOut(baseUrl, options);
1711
+ onSignedOut?.(baseUrl);
1712
+ return signedOut;
1713
+ };
1714
+ const expire = async (baseUrl, store) => {
1715
+ if (!state.auth.notifyExpired(baseUrl)) return;
1716
+ signOut(baseUrl);
1717
+ await store.persistStack(baseUrl, state.store.get());
1718
+ onExpired?.(baseUrl);
1719
+ };
1720
+ const renewIfStale = async (baseUrl) => {
1721
+ if (isStale(baseUrl)) await rotate(baseUrl);
1722
+ };
1723
+ const middleware = (baseUrl) => createBearerAuthMiddleware({ getAccessToken: async ({ forceRefresh = false } = {}) => {
1724
+ if (forceRefresh) {
1725
+ if (!state.auth.requireCredential(baseUrl).success) return null;
1726
+ return Result.unwrap(await rotate(baseUrl));
1727
+ }
1728
+ await renewIfStale(baseUrl);
1729
+ return state.auth.getAccessToken(baseUrl);
1730
+ } });
1731
+ return {
1732
+ middleware,
1733
+ rotate,
1734
+ renewIfStale,
1735
+ restore,
1736
+ restoreRetained,
1737
+ signOut,
1738
+ forget
1739
+ };
1740
+ };
1741
+ //#endregion
1633
1742
  //#region src/keboola/bearer/context/resource.ts
1634
1743
  /**
1635
1744
  * Owns fetching one async value per key — a caller names what it needs and never orchestrates the
@@ -1946,14 +2055,16 @@ const createPerProject = ({ state, credentials, middlewareFor, stack, clientServ
1946
2055
  */
1947
2056
  const SESSION_STORAGE_KEY = "keboola:session";
1948
2057
  /**
1949
- * What survives a reload, per credential kind.
2058
+ * What survives a reload, per grant type.
2059
+ *
2060
+ * - Written under `credential`: the key every blob already stored carries.
1950
2061
  *
1951
2062
  * - `token`: the refresh token. It rotates, is single-use and is server-revocable, so a leaked
1952
2063
  * snapshot has limited and revocable value. The access token is never written.
1953
2064
  * - `cookie`: the session id. The session cookie is the durable half and the browser keeps it;
1954
2065
  * the id alone renews nothing.
1955
2066
  */
1956
- const persistedCredentialSchema = z$1.discriminatedUnion("type", [z$1.object({
2067
+ const persistedGrantSchema = z$1.discriminatedUnion("type", [z$1.object({
1957
2068
  type: z$1.literal("token"),
1958
2069
  refreshToken: z$1.string()
1959
2070
  }), z$1.object({
@@ -1962,32 +2073,68 @@ const persistedCredentialSchema = z$1.discriminatedUnion("type", [z$1.object({
1962
2073
  })]);
1963
2074
  /** A record per project rather than a bare id, so a project can grow a field without a migration. */
1964
2075
  const persistedProjectSchema = z$1.object({ projectId: z$1.number() });
2076
+ const persistedStackSchema = z$1.object({
2077
+ baseUrl: z$1.string(),
2078
+ credential: persistedGrantSchema.nullable().catch(null),
2079
+ retained: z$1.object({ grant: persistedGrantSchema }).nullable().default(null).catch(null),
2080
+ projects: z$1.array(persistedProjectSchema)
2081
+ });
1965
2082
  const persistedSessionSchema = z$1.object({
1966
2083
  current: z$1.object({
1967
2084
  baseUrl: z$1.string(),
1968
2085
  projectId: z$1.number().nullable()
1969
2086
  }).nullable(),
1970
- stacks: z$1.array(z$1.object({
1971
- baseUrl: z$1.string(),
1972
- credential: persistedCredentialSchema.nullable().catch(null),
1973
- projects: z$1.array(persistedProjectSchema)
1974
- }))
2087
+ stacks: z$1.array(persistedStackSchema)
1975
2088
  });
1976
2089
  const EMPTY_PERSISTED_SESSION = {
1977
2090
  current: null,
1978
2091
  stacks: []
1979
2092
  };
1980
- const durableCredential = (stack) => {
1981
- if (stack.auth.status !== "authenticated") return null;
1982
- const { credential } = stack.auth;
1983
- return credential.type === "token" ? {
1984
- type: "token",
1985
- refreshToken: credential.refreshToken
1986
- } : {
1987
- type: "cookie",
1988
- sessionId: credential.sessionId
2093
+ const projectsOf = (projects, baseUrl) => Object.values(projects).filter((project) => project.baseUrl === baseUrl).map(({ projectId }) => ({ projectId }));
2094
+ const grantsOf = (stack) => ({
2095
+ credential: stack.auth.status === "authenticated" ? Entry.grant(stack.auth.credential) : null,
2096
+ retained: stack.retained
2097
+ });
2098
+ /**
2099
+ * The stored session, rewritten from the table except for the grants.
2100
+ *
2101
+ * - Scope, stack list and open projects come from memory.
2102
+ * - `credential` and `retained` stay as stored: a grant another document rotated must not be put
2103
+ * back by a snapshot of this one's older table.
2104
+ */
2105
+ const mergeSnapshot = (stored, { active, stacks, projects }) => ({
2106
+ current: {
2107
+ baseUrl: active.baseUrl,
2108
+ projectId: active.projectId
2109
+ },
2110
+ stacks: Object.values(stacks).map(({ baseUrl }) => {
2111
+ const kept = stored.stacks.find((stack) => stack.baseUrl === baseUrl);
2112
+ return {
2113
+ baseUrl,
2114
+ credential: kept?.credential ?? null,
2115
+ retained: kept?.retained ?? null,
2116
+ projects: projectsOf(projects, baseUrl)
2117
+ };
2118
+ })
2119
+ });
2120
+ const upsertStack = (stored, baseUrl, update) => {
2121
+ const index = stored.stacks.findIndex((stack) => stack.baseUrl === baseUrl);
2122
+ const stacks = [...stored.stacks];
2123
+ if (index < 0) stacks.push(update(void 0));
2124
+ else stacks[index] = update(stacks[index]);
2125
+ return {
2126
+ ...stored,
2127
+ stacks
1989
2128
  };
1990
2129
  };
2130
+ /**
2131
+ * The stored session, reached in two ways.
2132
+ *
2133
+ * - `locked`: the only way to read, and the only way to a grant write. Rotation and restore hold
2134
+ * it across the refresh; sign-in, sign-out and the boot restore open it for one step.
2135
+ * - `snapshot`: the table minus its grants, under the lock, coalesced; what the store subscription
2136
+ * feeds, and what a scope change awaits before the document leaves.
2137
+ */
1991
2138
  const createSessionPersistor = (storage) => {
1992
2139
  const persistor = createPersistor({
1993
2140
  storage,
@@ -1995,20 +2142,35 @@ const createSessionPersistor = (storage) => {
1995
2142
  schema: persistedSessionSchema,
1996
2143
  defaultValue: EMPTY_PERSISTED_SESSION
1997
2144
  });
1998
- const persist = ({ active, stacks, projects }) => persistor.persist({
1999
- current: {
2000
- baseUrl: active.baseUrl,
2001
- projectId: active.projectId
2002
- },
2003
- stacks: Object.values(stacks).map((stack) => ({
2004
- baseUrl: stack.baseUrl,
2005
- credential: durableCredential(stack),
2006
- projects: Object.values(projects).filter((project) => project.baseUrl === stack.baseUrl).map(({ projectId }) => ({ projectId }))
2007
- }))
2008
- });
2145
+ const persistStack = (cell, baseUrl, { stacks, projects }) => {
2146
+ const stack = stacks[baseUrl];
2147
+ if (stack === void 0) return Promise.resolve();
2148
+ return cell.modify((stored) => upsertStack(stored, baseUrl, (existing) => ({
2149
+ baseUrl,
2150
+ ...grantsOf(stack),
2151
+ projects: existing?.projects ?? projectsOf(projects, baseUrl)
2152
+ })));
2153
+ };
2154
+ const locked = (task) => persistor.locked((cell) => task({
2155
+ read: cell.read,
2156
+ persistStack: (baseUrl, state) => persistStack(cell, baseUrl, state)
2157
+ }));
2158
+ let latest = null;
2159
+ let pending = null;
2160
+ const snapshot = (state) => {
2161
+ latest = state;
2162
+ if (pending) return pending;
2163
+ const write = persistor.locked((cell) => {
2164
+ pending = null;
2165
+ const table = latest ?? state;
2166
+ return cell.modify((stored) => mergeSnapshot(stored, table));
2167
+ });
2168
+ pending = write;
2169
+ return write;
2170
+ };
2009
2171
  return {
2010
- ...persistor,
2011
- persist
2172
+ locked,
2173
+ snapshot
2012
2174
  };
2013
2175
  };
2014
2176
  //#endregion
@@ -2126,15 +2288,22 @@ const createKeboola = ({ defaultBaseUrl, storage, middlewares, clientServiceUrls
2126
2288
  await credentials.renewIfStale(project.baseUrl);
2127
2289
  return headersFor(Result.unwrap(state.projects.get(project.id)));
2128
2290
  };
2129
- const authenticate = (input) => {
2130
- const stack = state.scope.getActiveStack();
2131
- if (input.type !== "token") return Result.unwrap(state.auth.authenticate(stack.baseUrl, input));
2291
+ const toCredential = (input) => {
2292
+ if (input.type !== "token") return input;
2132
2293
  const { refreshToken } = input;
2133
2294
  if (!refreshToken) throw new KeboolaError(KeboolaErrorType.NotAuthenticated);
2134
- return Result.unwrap(state.auth.authenticate(stack.baseUrl, {
2295
+ return {
2135
2296
  ...input,
2136
2297
  refreshToken
2137
- }));
2298
+ };
2299
+ };
2300
+ const authenticate = (input) => {
2301
+ const { baseUrl } = state.scope.getActiveStack();
2302
+ const signedIn = Result.unwrap(state.auth.authenticate(baseUrl, toCredential(input)));
2303
+ persistor.locked((store) => store.persistStack(baseUrl, state.store.get())).catch((error) => {
2304
+ console.warn("createKeboola: the sign-in could not be stored", error);
2305
+ });
2306
+ return signedIn;
2138
2307
  };
2139
2308
  /**
2140
2309
  * The flat product surface: `auth` and `management` per stack, the rest per project.
@@ -2174,11 +2343,21 @@ const createKeboola = ({ defaultBaseUrl, storage, middlewares, clientServiceUrls
2174
2343
  Result.unwrapOr(state.projects.open(baseUrl, projectId), null);
2175
2344
  return perProject.get(project).api;
2176
2345
  };
2177
- /** The scope's sign-in, or a named stack's — and everything that sign-in derived. */
2178
- const signOut = (baseUrl) => {
2346
+ /**
2347
+ * The scope's sign-in, or a named stack's — and everything that sign-in derived.
2348
+ *
2349
+ * - `retain` keeps the grant on the stack, persisted beside the sign-in it ended, for
2350
+ * `restoreRetained`; the next sign-in on the stack replaces it.
2351
+ * - The table is signed out on return; the promise resolves once that is stored, so a caller
2352
+ * leaving the document waits for it.
2353
+ */
2354
+ const signOut = ({ baseUrl, ...options } = {}) => {
2179
2355
  const target = requireStackUrl(baseUrl);
2180
- return Result.unwrap(credentials.signOut(target));
2356
+ const signedOut = Result.unwrap(credentials.signOut(target, options));
2357
+ return persistor.locked((store) => store.persistStack(target, state.store.get())).then(() => signedOut);
2181
2358
  };
2359
+ /** Signs a stack back in from what a retained sign-out kept; `unreachable` leaves it to retry. */
2360
+ const restoreRetained = (baseUrl) => credentials.restoreRetained(normalizeBaseUrl(baseUrl));
2182
2361
  /**
2183
2362
  * `input` replaces the active stack's sign-in, whatever it holds.
2184
2363
  *
@@ -2215,16 +2394,22 @@ const createKeboola = ({ defaultBaseUrl, storage, middlewares, clientServiceUrls
2215
2394
  /**
2216
2395
  * Persistence starts only once the restore has settled.
2217
2396
  *
2218
- * - Mid-hydration an unexchanged stack is `anonymous`; `durableCredential` would erase the
2397
+ * - Mid-hydration an unexchanged stack is `anonymous`; the persistor would erase the
2219
2398
  * refresh token the exchange is about to spend.
2220
2399
  * - Writes the settled table once: the subscription fires only on the next change.
2221
2400
  */
2222
2401
  const enablePersistence = () => {
2223
2402
  if (persisting) return;
2224
2403
  persisting = true;
2225
- persistor.persist(state.store.get());
2226
- state.store.subscribe(persistor.persist);
2404
+ snapshot(state.store.get());
2405
+ state.store.subscribe(snapshot);
2406
+ };
2407
+ const snapshot = (table) => {
2408
+ persistor.snapshot(table).catch((error) => {
2409
+ console.warn("createKeboola: the session could not be stored", error);
2410
+ });
2227
2411
  };
2412
+ const persistScope = () => persisting ? persistor.snapshot(state.store.get()) : Promise.resolve();
2228
2413
  /**
2229
2414
  * The same, deferred until a sign-in.
2230
2415
  *
@@ -2278,14 +2463,22 @@ const createKeboola = ({ defaultBaseUrl, storage, middlewares, clientServiceUrls
2278
2463
  resume,
2279
2464
  stack: {
2280
2465
  getActive: getActiveStack,
2281
- select: byCaller(selectStack),
2466
+ /** Scoped on return; resolves once that is stored, for a caller leaving the document. */
2467
+ select: byCaller((baseUrl) => {
2468
+ const stack = selectStack(baseUrl);
2469
+ return persistScope().then(() => stack);
2470
+ }),
2282
2471
  close: closeStack,
2283
2472
  retryContext: perStack.context.retry,
2284
2473
  getContext: (baseUrl) => perStack.context.get(requireStackUrl(baseUrl)),
2285
2474
  getContextAsync: (baseUrl) => perStack.context.getAsync(requireStackUrl(baseUrl))
2286
2475
  },
2287
2476
  project: {
2288
- select: byCaller(selectProject),
2477
+ /** Scoped on return; resolves once that is stored, for a caller leaving the document. */
2478
+ select: byCaller((projectId) => {
2479
+ const project = selectProject(projectId);
2480
+ return persistScope().then(() => project);
2481
+ }),
2289
2482
  close: closeProject,
2290
2483
  deactivate: state.scope.deactivate,
2291
2484
  retryContext: perProject.context.retry,
@@ -2296,6 +2489,7 @@ const createKeboola = ({ defaultBaseUrl, storage, middlewares, clientServiceUrls
2296
2489
  authenticate: byCaller(authenticate),
2297
2490
  replace: byCaller(replace),
2298
2491
  signOut: byCaller(signOut),
2492
+ restoreRetained: byCaller(restoreRetained),
2299
2493
  /** Whether the active stack holds a credential — `restoring` is not one yet. */
2300
2494
  isAuthenticated,
2301
2495
  isAuthenticatedAsync: () => resume().then(isAuthenticated),
@@ -2489,6 +2683,6 @@ const createAdminAccount = ({ managementToken }) => {
2489
2683
  };
2490
2684
  };
2491
2685
  //#endregion
2492
- export { ApiError, HtmlResponseError, HttpContentType, HttpHeader, KeboolaError, KeboolaErrorType, KeboolaHttpHeader, ManagementClientAuthError, ManagementSessionMintError, QueryJobError, QueueJobError, Result, SESSION_STORAGE_KEY, ServiceUnavailableError, StorageJobError, SyncActionError, UserError, ValidationError, asError, assert, coalesce, collectByCursor, collectByOffset, concurrent, createAdminAccount, createDerivedAsyncStore, createDerivedStore, createEmitter, createGenericFetchClient, createKeboola, createLegacyKeboola, createLocalStorage, createLoggingMiddleware, createMemoryStorage, createNullStorage, createPersistor, createPollRegistry, createQueryServiceSdk, createRetryMiddleware, createSessionStorage, createStore, createUiVersionMiddleware, dedupe, deepMerge, delay, emitter, ensure, failureOf, formatValidationIssues, generateUUID, isAbortError, isApiError, isEmptyDeep, isFetchClientError, isHtmlResponseError, isKeboolaError, isManagementClientAuthError, isManagementSessionMintError, isPlainObject, isQueryJobError, isQueueJobError, isStorageJobError, isStorageTokenMutatingRequest, isSyncActionError, isTimeoutError, isValidationError, jobStatus, keboolaUID, lazy, nextCursorOf, parseLogLines, parseOrThrow, poller, readableReason, schemaGuidedMerge, series, shallowEqual };
2686
+ export { ApiError, HtmlResponseError, HttpContentType, HttpHeader, KeboolaError, KeboolaErrorType, KeboolaHttpHeader, ManagementClientAuthError, ManagementSessionMintError, QueryJobError, QueueJobError, Result, SESSION_STORAGE_KEY, ServiceUnavailableError, StorageJobError, SyncActionError, UserError, ValidationError, asError, assert, coalesce, collectByCursor, collectByOffset, concurrent, createAdminAccount, createDerivedAsyncStore, createDerivedStore, createEmitter, createGenericFetchClient, createKeboola, createLegacyKeboola, createLocalStorage, createLoggingMiddleware, createMemoryStorage, createNullStorage, createPersistor, createPollRegistry, createQueryServiceSdk, createRetryMiddleware, createSessionStorage, createStore, createUiVersionMiddleware, dedupe, deepMerge, delay, emitter, ensure, failureOf, formatValidationIssues, generateUUID, isAbortError, isApiError, isEmptyDeep, isFetchClientError, isHtmlResponseError, isKeboolaError, isManagementClientAuthError, isManagementSessionMintError, isPlainObject, isQueryJobError, isQueueJobError, isStorageJobError, isStorageTokenMutatingRequest, isSyncActionError, isTimeoutError, isValidationError, jobStatus, keboolaUID, lazy, nextCursorOf, parseLogLines, parseOrThrow, poller, queueSeries, readableReason, schemaGuidedMerge, series, shallowEqual };
2493
2687
 
2494
2688
  //# sourceMappingURL=index.js.map