@keboola/api-client 56.0.0 → 57.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.
- package/AGENTS.md +110 -229
- package/API-SURFACE.md +10 -2
- package/CHANGELOG.md +45 -0
- package/README.md +20 -133
- package/dist/{ManagementSessionMintError-Bc9bc7Ai.cjs → ManagementSessionMintError-BCOLLaJi.cjs} +3 -2
- package/dist/ManagementSessionMintError-BCOLLaJi.cjs.map +1 -0
- package/dist/{ManagementSessionMintError-BMHDcEqV.js → ManagementSessionMintError-KUX3utTV.js} +3 -2
- package/dist/ManagementSessionMintError-KUX3utTV.js.map +1 -0
- package/dist/{adminRoles-CUB0JddB.d.ts → adminRoles-CnfGDvjN.d.ts} +2 -2
- package/dist/{adminRoles-BFOPSedO.d.cts → adminRoles-D6AS9Bzx.d.cts} +2 -2
- package/dist/ai/index.d.cts +2 -2
- package/dist/ai/index.d.ts +2 -2
- package/dist/ai/types.d.cts +1 -1
- package/dist/ai/types.d.ts +1 -1
- package/dist/apps/index.cjs +1 -1
- package/dist/apps/index.d.cts +2 -2
- package/dist/apps/index.d.ts +2 -2
- package/dist/apps/index.js +1 -1
- package/dist/apps/types.d.cts +2 -2
- package/dist/apps/types.d.ts +2 -2
- package/dist/{apps-C1x5IKNQ.cjs → apps-BA9JRLAZ.cjs} +55 -1
- package/dist/apps-BA9JRLAZ.cjs.map +1 -0
- package/dist/{apps-BN7fWtSm.js → apps-DDcguJ1i.js} +55 -1
- package/dist/apps-DDcguJ1i.js.map +1 -0
- package/dist/assets/index.d.cts +1 -1
- package/dist/assets/index.d.ts +1 -1
- package/dist/auth/index.cjs +1 -1
- package/dist/auth/index.d.cts +1 -1
- package/dist/auth/index.d.ts +1 -1
- package/dist/auth/index.js +1 -1
- package/dist/auth/types.d.cts +2 -2
- package/dist/auth/types.d.ts +2 -2
- package/dist/{authClient-B_Mb4Vzs.js → authClient-BKGpJI5L.js} +13 -2
- package/dist/authClient-BKGpJI5L.js.map +1 -0
- package/dist/{authClient-C9QqhT2M.cjs → authClient-C3KG9hXw.cjs} +17 -6
- package/dist/authClient-C3KG9hXw.cjs.map +1 -0
- package/dist/{authClient-Dgyb0EFi.d.ts → authClient-CbWpMmdX.d.ts} +7 -4
- package/dist/{authClient-DOetdp2k.d.cts → authClient-UKeopxZZ.d.cts} +7 -4
- package/dist/billing/index.d.cts +1 -1
- package/dist/billing/index.d.ts +1 -1
- package/dist/billing/types.d.cts +1 -1
- package/dist/billing/types.d.ts +1 -1
- package/dist/chat/index.d.cts +2 -2
- package/dist/chat/index.d.ts +2 -2
- package/dist/chat/types.d.cts +1 -1
- package/dist/chat/types.d.ts +1 -1
- package/dist/componentsMcp/index.d.cts +1 -1
- package/dist/componentsMcp/index.d.ts +1 -1
- package/dist/componentsMcp/types.d.cts +1 -1
- package/dist/componentsMcp/types.d.ts +1 -1
- package/dist/constants/index.cjs +2 -2
- package/dist/constants/index.d.cts +3 -3
- package/dist/constants/index.d.ts +3 -3
- package/dist/constants/index.js +2 -2
- package/dist/{constants-HccvU5kx.js → constants-CxEaHCyt.js} +4 -3
- package/dist/constants-CxEaHCyt.js.map +1 -0
- package/dist/{constants-V9hAyPTo.cjs → constants-fiyOLyZE.cjs} +4 -3
- package/dist/constants-fiyOLyZE.cjs.map +1 -0
- package/dist/dataScience/index.d.cts +3 -3
- package/dist/dataScience/index.d.ts +3 -3
- package/dist/dataScience/types.d.cts +1 -1
- package/dist/dataScience/types.d.ts +1 -1
- package/dist/developerPortal/index.cjs +1 -1
- package/dist/developerPortal/index.d.cts +3 -3
- package/dist/developerPortal/index.d.ts +3 -3
- package/dist/developerPortal/index.js +1 -1
- package/dist/developerPortal/types.d.cts +2 -2
- package/dist/developerPortal/types.d.ts +2 -2
- package/dist/{developerPortalClient-CzCJ5sE3.js → developerPortalClient-3Q7049-4.js} +19 -1
- package/dist/developerPortalClient-3Q7049-4.js.map +1 -0
- package/dist/{developerPortalClient-BcK9F-Fs.cjs → developerPortalClient-Cj9bStCS.cjs} +19 -1
- package/dist/developerPortalClient-Cj9bStCS.cjs.map +1 -0
- package/dist/domain/permissions/index.d.cts +1 -1
- package/dist/domain/permissions/index.d.ts +1 -1
- package/dist/editor/index.d.cts +2 -2
- package/dist/editor/index.d.ts +2 -2
- package/dist/editor/types.d.cts +1 -1
- package/dist/editor/types.d.ts +1 -1
- package/dist/{emitter-raKkIqRp.d.ts → emitter-yaYzJOdh.d.cts} +1 -2
- package/dist/{emitter-raKkIqRp.d.cts → emitter-yaYzJOdh.d.ts} +1 -2
- package/dist/encryption/index.d.cts +1 -1
- package/dist/encryption/index.d.ts +1 -1
- package/dist/encryption/types.d.cts +1 -1
- package/dist/encryption/types.d.ts +1 -1
- package/dist/import/index.d.cts +3 -3
- package/dist/import/index.d.ts +3 -3
- package/dist/{index-DcKc3_Y1.d.cts → index-9p4O-clX.d.cts} +2033 -72
- package/dist/{index-DcKc3_Y1.d.ts → index-9p4O-clX.d.ts} +2033 -72
- package/dist/{index-CLqZfRpv.d.cts → index-B-HCh7LL.d.cts} +3 -3
- package/dist/{index-CxoJuIzB.d.cts → index-B0e42GnK.d.cts} +4 -3
- package/dist/{index-Bgu3hnMO.d.ts → index-BbXGsspe.d.ts} +4 -4
- package/dist/{index-B7Ogo2SK.d.ts → index-Bg9BWpIY.d.ts} +4 -3
- package/dist/{index-DPhGNQC5.d.cts → index-BgEu7wGk.d.cts} +2559 -7319
- package/dist/{index-C_A0JS9s.d.ts → index-Btft3BFn.d.ts} +29 -3
- package/dist/{index-DXNRd61K.d.cts → index-ByaAn_lm.d.cts} +4 -4
- package/dist/{index-A8udJCGv.d.ts → index-C92Ct6K5.d.ts} +178 -4
- package/dist/{index-B30dBBBH.d.ts → index-CBq59Aif.d.ts} +3 -3
- package/dist/{index-DAb1g6je.d.cts → index-CGUPsu_R.d.cts} +29 -3
- package/dist/{index-CLxvW_pn.d.ts → index-CIA6-x2Q.d.ts} +4 -4
- package/dist/{index-B2YNTI4p.d.ts → index-CeWVf3d1.d.ts} +4 -4
- package/dist/{index-GlHJ4j3a.d.ts → index-Cj0l_DL_.d.ts} +2559 -7319
- package/dist/{index-BUZ-vTRt.d.ts → index-Ck0UPKMM.d.ts} +2 -2
- package/dist/{index-B-HhOTVk.d.cts → index-D0ACg_Pp.d.cts} +7 -4
- package/dist/{index-Dx02AUpZ.d.cts → index-D8nMnVp1.d.cts} +4 -4
- package/dist/{index-24GpnYhn.d.cts → index-DENUPo51.d.cts} +2 -2
- package/dist/{index-RHYdFrfn.d.cts → index-DGjxLWZ-.d.cts} +3 -3
- package/dist/{index-BH1jo-bb.d.ts → index-Dse6Psvc.d.ts} +7 -4
- package/dist/{index-BaJ-GMa7.d.ts → index-DxcaEIhU.d.ts} +3 -3
- package/dist/{index-CpidrJQc.d.cts → index-OCEoQ1Y-.d.cts} +4 -4
- package/dist/{index-DxbqDi_0.d.cts → index-jR69kGUZ.d.cts} +178 -4
- package/dist/index.cjs +615 -867
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -9
- package/dist/index.d.ts +9 -9
- package/dist/index.js +611 -860
- package/dist/index.js.map +1 -1
- package/dist/kaiAgent/index.cjs +1 -1
- package/dist/kaiAgent/index.d.cts +2 -2
- package/dist/kaiAgent/index.d.ts +2 -2
- package/dist/kaiAgent/index.js +1 -1
- package/dist/kaiAgent/types.d.cts +2 -2
- package/dist/kaiAgent/types.d.ts +2 -2
- package/dist/{kaiAgent-De2T6G4G.cjs → kaiAgent-Q00g6S1v.cjs} +16 -1
- package/dist/kaiAgent-Q00g6S1v.cjs.map +1 -0
- package/dist/{kaiAgent-D0MoKqXe.js → kaiAgent-aqylPZHY.js} +16 -1
- package/dist/kaiAgent-aqylPZHY.js.map +1 -0
- package/dist/management/index.cjs +1 -1
- package/dist/management/index.d.cts +1 -1
- package/dist/management/index.d.ts +1 -1
- package/dist/management/index.js +1 -1
- package/dist/management/types.d.cts +1 -1
- package/dist/management/types.d.ts +1 -1
- package/dist/{management-BlMQnPNS.js → management-CIK5-Aq5.js} +14 -7
- package/dist/management-CIK5-Aq5.js.map +1 -0
- package/dist/{management-dIMrTTpI.cjs → management-Dqrc516s.cjs} +14 -7
- package/dist/management-Dqrc516s.cjs.map +1 -0
- package/dist/{metaObject-qWyZAD-5.d.ts → metaObject-AQ7wKDOu.d.ts} +2 -2
- package/dist/{metaObject-BsBMgWRt.d.cts → metaObject-I35_krxf.d.cts} +2 -2
- package/dist/metastore/index.d.cts +1 -1
- package/dist/metastore/index.d.ts +1 -1
- package/dist/metastore/types.d.cts +1 -1
- package/dist/metastore/types.d.ts +1 -1
- package/dist/microsoftGraph/index.d.cts +3 -3
- package/dist/microsoftGraph/index.d.ts +3 -3
- package/dist/microsoftGraph/types.d.cts +2 -2
- package/dist/microsoftGraph/types.d.ts +2 -2
- package/dist/{middleware-DxGv7DG8.js → middleware-DWmhthX0.js} +2 -2
- package/dist/middleware-DWmhthX0.js.map +1 -0
- package/dist/{middleware-vIaPDtQI.cjs → middleware-DYdDD4O6.cjs} +2 -2
- package/dist/middleware-DYdDD4O6.cjs.map +1 -0
- package/dist/notifications/index.d.cts +2 -2
- package/dist/notifications/index.d.ts +2 -2
- package/dist/notifications/types.d.cts +1 -1
- package/dist/notifications/types.d.ts +1 -1
- package/dist/oauth/index.d.cts +2 -2
- package/dist/oauth/index.d.ts +2 -2
- package/dist/oauth/types.d.cts +1 -1
- package/dist/oauth/types.d.ts +1 -1
- package/dist/omnisearch/index.d.cts +2 -2
- package/dist/omnisearch/index.d.ts +2 -2
- package/dist/omnisearch/types.d.cts +1 -1
- package/dist/omnisearch/types.d.ts +1 -1
- package/dist/{project-CmV1OhK4.d.ts → project-DwRvx_zN.d.ts} +3 -3
- package/dist/{project-F6eHCACz.d.cts → project-ERH0FTGW.d.cts} +3 -3
- package/dist/queryService/index.cjs +1 -1
- package/dist/queryService/index.d.cts +1 -1
- package/dist/queryService/index.d.ts +1 -1
- package/dist/queryService/index.js +1 -1
- package/dist/queryService/types.d.cts +1 -1
- package/dist/queryService/types.d.ts +1 -1
- package/dist/{queryService-C3BQ6GKW.cjs → queryService-CECWubS0.cjs} +2 -2
- package/dist/{queryService-C3BQ6GKW.cjs.map → queryService-CECWubS0.cjs.map} +1 -1
- package/dist/{queryService-DQHtHy2-.js → queryService-CIxb_mcP.js} +2 -2
- package/dist/{queryService-DQHtHy2-.js.map → queryService-CIxb_mcP.js.map} +1 -1
- package/dist/queue/index.cjs +1 -1
- package/dist/queue/index.d.cts +11 -4
- package/dist/queue/index.d.ts +11 -4
- package/dist/queue/index.js +1 -1
- package/dist/queue/types.d.cts +1 -1
- package/dist/queue/types.d.ts +1 -1
- package/dist/{queue-6cywDnA-.js → queue-BBihD5qQ.js} +2 -2
- package/dist/{queue-6cywDnA-.js.map → queue-BBihD5qQ.js.map} +1 -1
- package/dist/{queue-J2uXzXR9.cjs → queue-PmTfoniJ.cjs} +2 -2
- package/dist/{queue-J2uXzXR9.cjs.map → queue-PmTfoniJ.cjs.map} +1 -1
- package/dist/scheduler/index.d.cts +2 -2
- package/dist/scheduler/index.d.ts +2 -2
- package/dist/scheduler/types.d.cts +1 -1
- package/dist/scheduler/types.d.ts +1 -1
- package/dist/{schema-DLmBEgPM.d.cts → schema-CqzWi5cO.d.cts} +14 -4
- package/dist/{schema-DLmBEgPM.d.ts → schema-CqzWi5cO.d.ts} +14 -4
- package/dist/sdk/configurations/index.d.cts +2 -3
- package/dist/sdk/configurations/index.d.ts +2 -3
- package/dist/sdk/dataAppServer/index.cjs +3 -3
- package/dist/sdk/dataAppServer/index.d.cts +1 -1
- package/dist/sdk/dataAppServer/index.d.ts +1 -1
- package/dist/sdk/dataAppServer/index.js +3 -3
- package/dist/sdk/developerPortal/index.cjs +3 -3
- package/dist/sdk/developerPortal/index.cjs.map +1 -1
- package/dist/sdk/developerPortal/index.d.cts +178 -4
- package/dist/sdk/developerPortal/index.d.ts +178 -4
- package/dist/sdk/developerPortal/index.js +3 -3
- package/dist/sdk/developerPortal/index.js.map +1 -1
- package/dist/sdk/kaiMemory/index.d.cts +1 -1
- package/dist/sdk/kaiMemory/index.d.ts +1 -1
- package/dist/sdk/kaiMemory/types.d.cts +1 -1
- package/dist/sdk/kaiMemory/types.d.ts +1 -1
- package/dist/sdk/queryService/index.d.cts +1 -1
- package/dist/sdk/queryService/index.d.ts +1 -1
- package/dist/sdk/securityPolicy/index.d.cts +2 -2
- package/dist/sdk/securityPolicy/index.d.ts +2 -2
- package/dist/sdk/securityPolicy/types.d.cts +1 -1
- package/dist/sdk/securityPolicy/types.d.ts +1 -1
- package/dist/sdk/semanticLayer/index.d.cts +1 -1
- package/dist/sdk/semanticLayer/index.d.ts +1 -1
- package/dist/sdk/semanticLayer/types.d.cts +1 -1
- package/dist/sdk/semanticLayer/types.d.ts +1 -1
- package/dist/sdk/tag/index.d.cts +3 -3
- package/dist/sdk/tag/index.d.ts +3 -3
- package/dist/sdk/tag/types.d.cts +1 -1
- package/dist/sdk/tag/types.d.ts +1 -1
- package/dist/sdk/vault/index.d.cts +1 -1
- package/dist/sdk/vault/index.d.ts +1 -1
- package/dist/status/index.d.cts +1 -1
- package/dist/status/index.d.ts +1 -1
- package/dist/storage/index.cjs +5 -5
- package/dist/storage/index.d.cts +2 -3
- package/dist/storage/index.d.ts +2 -3
- package/dist/storage/index.js +3 -3
- package/dist/storage/types.d.cts +5 -5
- package/dist/storage/types.d.ts +5 -5
- package/dist/{storage-jLhVrKZh.cjs → storage-chxoWtAL.cjs} +44 -56
- package/dist/storage-chxoWtAL.cjs.map +1 -0
- package/dist/{storage-Bw-HSnPp.js → storage-o9teEKl_.js} +42 -54
- package/dist/storage-o9teEKl_.js.map +1 -0
- package/dist/{store-2OyH1XOP.cjs → store-7xlVu4qF.cjs} +3 -14
- package/dist/store-7xlVu4qF.cjs.map +1 -0
- package/dist/{store-HP0zRcLz.js → store-DDUzPeCm.js} +3 -14
- package/dist/store-DDUzPeCm.js.map +1 -0
- package/dist/stream/index.d.cts +2 -2
- package/dist/stream/index.d.ts +2 -2
- package/dist/stream/types.d.cts +1 -1
- package/dist/stream/types.d.ts +1 -1
- package/dist/syncActions/index.d.cts +2 -2
- package/dist/syncActions/index.d.ts +2 -2
- package/dist/syncActions/types.d.cts +1 -1
- package/dist/syncActions/types.d.ts +1 -1
- package/dist/telemetry/index.d.cts +2 -2
- package/dist/telemetry/index.d.ts +2 -2
- package/dist/telemetry/types.d.cts +1 -1
- package/dist/telemetry/types.d.ts +1 -1
- package/dist/{transientRetries-BORv47mH.js → transientRetries-dssygpwU.js} +2 -2
- package/dist/{transientRetries-BORv47mH.js.map → transientRetries-dssygpwU.js.map} +1 -1
- package/dist/{transientRetries-CBorl4Ue.cjs → transientRetries-yVaQgKqP.cjs} +2 -2
- package/dist/{transientRetries-CBorl4Ue.cjs.map → transientRetries-yVaQgKqP.cjs.map} +1 -1
- package/dist/{types-LOf_GCej.d.cts → types-B1kernzE.d.cts} +2 -2
- package/dist/{types-Cvbcjdgf.d.ts → types-BBmS7-IS.d.ts} +151 -4
- package/dist/{types-DaRxZt3v.d.ts → types-BJyWTgXX.d.ts} +2 -2
- package/dist/{types-CnKiVVb8.d.ts → types-BPNFTA63.d.cts} +21 -7
- package/dist/{types-BJRRAQ9R.d.cts → types-BPSExpye.d.cts} +244 -4
- package/dist/{types-Cg_66Toy.d.ts → types-BiXonOK6.d.ts} +2 -2
- package/dist/{types-CNDemlfn.d.cts → types-BimRBONo.d.cts} +3 -3
- package/dist/{types-CrXoqs8E.d.cts → types-BuEC58u3.d.cts} +2 -2
- package/dist/{types-BnkHyxdp.d.ts → types-BzHyi99r.d.cts} +5 -3
- package/dist/{types-2CMPwArl.d.ts → types-C4T_2JdN.d.cts} +40 -27
- package/dist/{types-lZRyNwOH.d.ts → types-C53aKnWt.d.ts} +2 -2
- package/dist/{types-6oLbURTK.d.cts → types-CEjgqmr2.d.cts} +2 -2
- package/dist/{types-BEEGI4aq.d.ts → types-CGtpwTJk.d.ts} +2 -2
- package/dist/{types-B_yv00AL.d.ts → types-CH1uguug.d.cts} +2 -163
- package/dist/{types-DMEl2iet.d.ts → types-CP8-CssY.d.ts} +2 -2
- package/dist/{types-DgAMVyiT.d.ts → types-CPQ6RkiZ.d.ts} +244 -4
- package/dist/{types-EdL0Eb0B.d.ts → types-CPwofeyq.d.ts} +3 -3
- package/dist/{types-CFuT8zr3.d.cts → types-CQAEOq-K.d.cts} +2 -2
- package/dist/{types-DslO1S5E.d.cts → types-CVWoP_PC.d.cts} +3 -3
- package/dist/{types-BqJycQNM.d.cts → types-CbM2MApW.d.cts} +2 -2
- package/dist/{types-BDGkMVWf.d.cts → types-CbOfT6lb.d.ts} +21 -7
- package/dist/{types-B6OG1lLf.d.cts → types-CcPpqVhm.d.cts} +2 -2
- package/dist/{types-D2J3SaoY.d.ts → types-CeqpzbBH.d.ts} +2 -2
- package/dist/{types-C_JO7FI9.d.cts → types-CjJYZaMO.d.cts} +2 -2
- package/dist/{types-D0Gqu-Xz.d.cts → types-CjP8RcFN.d.cts} +2 -2
- package/dist/{types-CUovU--e.d.ts → types-CjfsPtwk.d.ts} +2 -2
- package/dist/{types-DPFG6AAA.d.ts → types-CnSBLcZB.d.ts} +163 -3
- package/dist/{types-D4knWlwr.d.ts → types-CsXLdnfV.d.ts} +2 -2
- package/dist/{types-C3Kf_ggm.d.cts → types-CzAh5-0z.d.cts} +2 -2
- package/dist/{types-D6Fbf_y3.d.ts → types-D0F_c5KI.d.ts} +4 -4
- package/dist/{types-DykEfF2N.d.cts → types-D3L3CqKl.d.cts} +151 -4
- package/dist/{types--mz2z0Zm.d.cts → types-D4oIei5M.d.cts} +163 -3
- package/dist/{types-Cm1iOHE5.d.cts → types-D6ilG8sC.d.cts} +3 -3
- package/dist/{types-DtS7qAdz.d.cts → types-DEGkXcw2.d.ts} +5 -3
- package/dist/{types-DQguGTlM.d.cts → types-DEhAcO1Z.d.cts} +2 -2
- package/dist/{types-CuYaiy4R.d.cts → types-DaIfg9Mb.d.cts} +4 -4
- package/dist/{types-ByKSM08P.d.ts → types-DhofEmWy.d.ts} +2 -2
- package/dist/{types-B5FgsIiY.d.ts → types-Dp61pYgP.d.ts} +3 -3
- package/dist/{types-BhGr9OQ4.d.ts → types-Dteot3tT.d.ts} +757 -112
- package/dist/{types-3ZE32k8V.d.cts → types-K-JISUUI.d.cts} +757 -112
- package/dist/{types-CjqFLXVx.d.cts → types-TywAc1ow.d.ts} +40 -27
- package/dist/{types-DiXeO0yB.d.ts → types-UBpth6_9.d.ts} +2 -2
- package/dist/{types-D0BOES7q.d.cts → types-Vw-tduOH.d.ts} +2 -163
- package/dist/{types-CF5ZROX5.d.cts → types-ZyLTqgpa.d.cts} +2 -2
- package/dist/{types-BmcZyKgM.d.cts → types-aylD1zQz.d.cts} +3 -3
- package/dist/{types-CbPO9cGq.d.cts → types-fYY4q7dC.d.cts} +2 -2
- package/dist/{types-Foy0RnqF.d.ts → types-jYn3e3Du.d.ts} +3 -3
- package/dist/{types-p6UYqJo_.d.ts → types-qXqJRPHj.d.ts} +2 -2
- package/dist/{types-B452bFfS.d.ts → types-r-Qa3y8e.d.ts} +2 -2
- package/dist/{types-DhE7iY90.d.ts → types-z82j5aNW.d.ts} +3 -3
- package/dist/{collectByCursor-2-8SuJ-8.js → validateConnectionStatus-DgJwuEy9.js} +32 -22
- package/dist/validateConnectionStatus-DgJwuEy9.js.map +1 -0
- package/dist/{collectByCursor-D58__WD1.cjs → validateConnectionStatus-DpYRsU-e.cjs} +37 -21
- package/dist/validateConnectionStatus-DpYRsU-e.cjs.map +1 -0
- package/dist/vault/index.d.cts +1 -1
- package/dist/vault/index.d.ts +1 -1
- package/dist/vault/types.d.cts +1 -1
- package/dist/vault/types.d.ts +1 -1
- package/package.json +2 -2
- package/surface/apps.md +8 -3
- package/surface/auth.md +3 -2
- package/surface/chat.md +3 -3
- package/surface/dataScience.md +2 -2
- package/surface/kaiAgent.md +4 -3
- package/surface/management.md +4 -4
- package/surface/queue.md +7 -7
- package/surface/storage.md +27 -26
- package/dist/ManagementSessionMintError-BMHDcEqV.js.map +0 -1
- package/dist/ManagementSessionMintError-Bc9bc7Ai.cjs.map +0 -1
- package/dist/apps-BN7fWtSm.js.map +0 -1
- package/dist/apps-C1x5IKNQ.cjs.map +0 -1
- package/dist/authClient-B_Mb4Vzs.js.map +0 -1
- package/dist/authClient-C9QqhT2M.cjs.map +0 -1
- package/dist/collectByCursor-2-8SuJ-8.js.map +0 -1
- package/dist/collectByCursor-D58__WD1.cjs.map +0 -1
- package/dist/constants-HccvU5kx.js.map +0 -1
- package/dist/constants-V9hAyPTo.cjs.map +0 -1
- package/dist/developerPortalClient-BcK9F-Fs.cjs.map +0 -1
- package/dist/developerPortalClient-CzCJ5sE3.js.map +0 -1
- package/dist/index-C6FI_Lc7.d.ts +0 -10
- package/dist/index-CmtqbTse.d.cts +0 -10
- package/dist/kaiAgent-D0MoKqXe.js.map +0 -1
- package/dist/kaiAgent-De2T6G4G.cjs.map +0 -1
- package/dist/management-BlMQnPNS.js.map +0 -1
- package/dist/management-dIMrTTpI.cjs.map +0 -1
- package/dist/middleware-DxGv7DG8.js.map +0 -1
- package/dist/middleware-vIaPDtQI.cjs.map +0 -1
- package/dist/storage-Bw-HSnPp.js.map +0 -1
- package/dist/storage-jLhVrKZh.cjs.map +0 -1
- package/dist/store-2OyH1XOP.cjs.map +0 -1
- package/dist/store-HP0zRcLz.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,50 +1,50 @@
|
|
|
1
1
|
import { t as UserError } from "./UserError-BxoOJJ_u.js";
|
|
2
2
|
import { _ as HttpStatus, a as isTimeoutError, d as normalizeBaseUrl, h as CREDENTIAL_HEADERS, i as isFetchClientError, n as isAbortError, o as HttpContentType, p as ApiError, r as isApiError, s as HttpHeader, v as KeboolaHttpHeader, x as redactHeaders, y as REDACTED } from "./createFetchClient-Dc_ZMuq7.js";
|
|
3
|
-
import { a as
|
|
4
|
-
import { a as series, c as ServiceUnavailableError, d as isManageError, f as manageErrorCode, l as retryAfterSeconds, o as StorageJobError, s as isStorageJobError, t as createStorageClient, u as readableReason } from "./storage-
|
|
5
|
-
import { n as ManagementClientAuthError, t as ManagementSessionMintError } from "./ManagementSessionMintError-
|
|
3
|
+
import { a as HtmlResponseError, i as nextCursorOf, n as collectByCursor, o as isHtmlResponseError, r as iterateByCursor } from "./validateConnectionStatus-DgJwuEy9.js";
|
|
4
|
+
import { a as series, c as ServiceUnavailableError, d as isManageError, f as manageErrorCode, l as retryAfterSeconds, o as StorageJobError, s as isStorageJobError, t as createStorageClient, u as readableReason } from "./storage-o9teEKl_.js";
|
|
5
|
+
import { n as ManagementClientAuthError, t as ManagementSessionMintError } from "./ManagementSessionMintError-KUX3utTV.js";
|
|
6
6
|
import { i as isQueryJobError, n as isRowLevelSecurityError, r as QueryJobError, t as RowLevelSecurityError } from "./RowLevelSecurityError-CObFqj3E.js";
|
|
7
7
|
import { n as isQueueJobError, t as QueueJobError } from "./QueueJobError-BJNUINXW.js";
|
|
8
8
|
import { n as isSyncActionError, t as SyncActionError } from "./SyncActionError-DuGcDbkd.js";
|
|
9
9
|
import { i as parseOrThrow, n as formatValidationIssues, r as isValidationError, t as ValidationError } from "./ValidationError-BsdFDGY2.js";
|
|
10
10
|
import { t as createGenericFetchClient } from "./createGenericFetchClient-Ba4E4T-Y.js";
|
|
11
11
|
import { t as createImportClient } from "./import-DxN6CJzJ.js";
|
|
12
|
-
import { t as createAuthClient } from "./authClient-B_Mb4Vzs.js";
|
|
13
12
|
import { t as collectByOffset } from "./collectByOffset-i8Tdoze7.js";
|
|
14
13
|
import { t as concurrent } from "./concurrent-BtsT10Xe.js";
|
|
15
14
|
import { t as dedupe } from "./dedupe-Bu0d2i_w.js";
|
|
16
|
-
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-
|
|
17
|
-
import { n as createEmitter, t as createStore } from "./store-
|
|
15
|
+
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-dssygpwU.js";
|
|
16
|
+
import { n as createEmitter, t as createStore } from "./store-DDUzPeCm.js";
|
|
18
17
|
import { n as keboolaUID, t as createTagSdk } from "./tag-BwjbG3tT.js";
|
|
19
18
|
import { t as generateUUID } from "./generateUUID-DE9sNyJF.js";
|
|
20
19
|
import { t as isPlainObject } from "./isPlainObject-BxsT8_t2.js";
|
|
21
20
|
import { n as isEmptyDeep, t as schemaGuidedMerge } from "./schemaGuidedMerge-DFNqj9Nz.js";
|
|
22
|
-
import {
|
|
23
|
-
import { t as
|
|
21
|
+
import { t as createAuthClient } from "./authClient-BKGpJI5L.js";
|
|
22
|
+
import { n as isUnauthorized, t as createBearerAuthMiddleware } from "./middleware-DWmhthX0.js";
|
|
24
23
|
import { i as createKaiMemorySdk } from "./kaiMemory-B1wIwH8Y.js";
|
|
25
24
|
import { i as createSemanticLayerSdk } from "./semanticLayer-Btj1Qy9O.js";
|
|
26
25
|
import { createVaultSdk } from "./sdk/vault/index.js";
|
|
27
26
|
import { createAiClient } from "./ai/index.js";
|
|
28
|
-
import { n as parseLogLines, t as createAppsClient } from "./apps-
|
|
27
|
+
import { n as parseLogLines, t as createAppsClient } from "./apps-DDcguJ1i.js";
|
|
29
28
|
import { createBillingClient } from "./billing/index.js";
|
|
30
29
|
import { createChatClient } from "./chat/index.js";
|
|
31
30
|
import { t as createComponentsMcpClient } from "./componentsMcp-CAmrCpzV.js";
|
|
32
31
|
import { createDataScienceClient } from "./dataScience/index.js";
|
|
33
32
|
import { createEditorClient } from "./editor/index.js";
|
|
34
33
|
import { createEncryptionClient } from "./encryption/index.js";
|
|
35
|
-
import { t as createKaiAgentClient } from "./kaiAgent-
|
|
34
|
+
import { t as createKaiAgentClient } from "./kaiAgent-aqylPZHY.js";
|
|
36
35
|
import { t as createMetastoreClient } from "./metastore-CkqFnEfu.js";
|
|
37
36
|
import { createNotificationsClient } from "./notifications/index.js";
|
|
38
37
|
import { n as createOauthClient } from "./oauth-Fri6IthS.js";
|
|
39
38
|
import { createOmnisearchClient } from "./omnisearch/index.js";
|
|
40
|
-
import { t as createQueryServiceClient } from "./queryService-
|
|
41
|
-
import { t as createQueueClient } from "./queue-
|
|
39
|
+
import { t as createQueryServiceClient } from "./queryService-CIxb_mcP.js";
|
|
40
|
+
import { t as createQueueClient } from "./queue-BBihD5qQ.js";
|
|
42
41
|
import { createSchedulerClient } from "./scheduler/index.js";
|
|
43
42
|
import { createStreamClient } from "./stream/index.js";
|
|
44
43
|
import { t as createSyncActionsClient } from "./syncActions-W98Jme2Z.js";
|
|
44
|
+
import { t as ServiceId } from "./serviceIds-RAVtP4nK.js";
|
|
45
45
|
import { createTelemetryClient } from "./telemetry/index.js";
|
|
46
46
|
import { createVaultClient } from "./vault/index.js";
|
|
47
|
-
import { n as
|
|
47
|
+
import { n as isManagementClientAuthError, r as isManagementSessionMintError, t as createManagementClient } from "./management-CIK5-Aq5.js";
|
|
48
48
|
import { t as createProject } from "./project-aAVAOcmx.js";
|
|
49
49
|
import { n as createQueryServiceSdk } from "./queryService-DE_yE_S4.js";
|
|
50
50
|
import * as z$1 from "zod";
|
|
@@ -58,24 +58,14 @@ const KeboolaErrorType = {
|
|
|
58
58
|
NotAuthenticated: "not-authenticated",
|
|
59
59
|
SignInEnded: "sign-in-ended",
|
|
60
60
|
AlreadyAuthenticated: "already-authenticated",
|
|
61
|
-
|
|
62
|
-
NoManagementToken: "no-management-token",
|
|
63
|
-
MissingProject: "missing-project",
|
|
64
|
-
NotBearer: "not-bearer",
|
|
65
|
-
NotReady: "not-ready",
|
|
66
|
-
InvalidBuildTransition: "invalid-build-transition"
|
|
61
|
+
NotReady: "not-ready"
|
|
67
62
|
};
|
|
68
63
|
const MESSAGES = {
|
|
69
|
-
[KeboolaErrorType.Unconfigured]: "
|
|
64
|
+
[KeboolaErrorType.Unconfigured]: "This stack has not been selected — call session.stack.select(baseUrl) first.",
|
|
70
65
|
[KeboolaErrorType.NotAuthenticated]: "The session is not authenticated — sign in first.",
|
|
71
66
|
[KeboolaErrorType.SignInEnded]: "The sign-in this operation started under has ended — its result belongs to nobody.",
|
|
72
|
-
[KeboolaErrorType.AlreadyAuthenticated]: "
|
|
73
|
-
[KeboolaErrorType.
|
|
74
|
-
[KeboolaErrorType.NoManagementToken]: "No management token — authenticate the management realm first.",
|
|
75
|
-
[KeboolaErrorType.MissingProject]: "A bearer storage session requires a project — call setProject(projectId) first.",
|
|
76
|
-
[KeboolaErrorType.NotBearer]: "This operation requires a bearer (OAuth) session.",
|
|
77
|
-
[KeboolaErrorType.NotReady]: "The client is not ready — authenticate the storage realm first.",
|
|
78
|
-
[KeboolaErrorType.InvalidBuildTransition]: "Invalid storage build transition — the build goes idle → initializing → ready | failed."
|
|
67
|
+
[KeboolaErrorType.AlreadyAuthenticated]: "This stack is already signed in — sign out or use auth.replace first.",
|
|
68
|
+
[KeboolaErrorType.NotReady]: "The stack index has not loaded yet."
|
|
79
69
|
};
|
|
80
70
|
var KeboolaError = class KeboolaError extends Error {
|
|
81
71
|
type;
|
|
@@ -140,109 +130,6 @@ const coalesce = (task) => {
|
|
|
140
130
|
return waiter.promise;
|
|
141
131
|
};
|
|
142
132
|
};
|
|
143
|
-
// src/utils/store/derivedStore.ts
|
|
144
|
-
const isPlainObjectOrArray = (value) => {
|
|
145
|
-
if (Array.isArray(value)) return true;
|
|
146
|
-
const proto = Object.getPrototypeOf(value);
|
|
147
|
-
return proto === Object.prototype || proto === null;
|
|
148
|
-
};
|
|
149
|
-
const shallowEqual = (a, b) => {
|
|
150
|
-
if (Object.is(a, b)) return true;
|
|
151
|
-
if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) return false;
|
|
152
|
-
if (!isPlainObjectOrArray(a) || !isPlainObjectOrArray(b)) return false;
|
|
153
|
-
const aKeys = Object.keys(a);
|
|
154
|
-
const bKeys = Object.keys(b);
|
|
155
|
-
return aKeys.length === bKeys.length && aKeys.every((key) => Object.is(a[key], b[key]));
|
|
156
|
-
};
|
|
157
|
-
const createDerivedStore = ({ source, dependsOn, build, keyEquals = shallowEqual }) => {
|
|
158
|
-
let key = dependsOn(source.get());
|
|
159
|
-
const store = createStore(build(key));
|
|
160
|
-
const unsubscribe = source.subscribe((state) => {
|
|
161
|
-
const next = dependsOn(state);
|
|
162
|
-
if (keyEquals(key, next)) return;
|
|
163
|
-
key = next;
|
|
164
|
-
store.set(build(next));
|
|
165
|
-
});
|
|
166
|
-
const get = store.get;
|
|
167
|
-
const subscribe = store.subscribe;
|
|
168
|
-
const dispose = () => {
|
|
169
|
-
unsubscribe();
|
|
170
|
-
store.dispose();
|
|
171
|
-
};
|
|
172
|
-
return {
|
|
173
|
-
get,
|
|
174
|
-
subscribe,
|
|
175
|
-
dispose
|
|
176
|
-
};
|
|
177
|
-
};
|
|
178
|
-
// src/utils/store/derivedAsyncStore.ts
|
|
179
|
-
const createDerivedAsyncStore = ({ source, dependsOn, build, keyEquals = shallowEqual }) => {
|
|
180
|
-
const store = createStore({ state: "idle" });
|
|
181
|
-
let currentKey = null;
|
|
182
|
-
let generation = 0;
|
|
183
|
-
let controller = null;
|
|
184
|
-
const run = (key) => {
|
|
185
|
-
controller?.abort();
|
|
186
|
-
controller = new AbortController();
|
|
187
|
-
const runGeneration = ++generation;
|
|
188
|
-
store.set({ state: "pending" });
|
|
189
|
-
build(key, controller.signal).then((value) => {
|
|
190
|
-
if (runGeneration === generation) store.set({
|
|
191
|
-
state: "ready",
|
|
192
|
-
value
|
|
193
|
-
});
|
|
194
|
-
}, (error) => {
|
|
195
|
-
if (runGeneration === generation) store.set({
|
|
196
|
-
state: "errored",
|
|
197
|
-
error
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
};
|
|
201
|
-
const sync = (state) => {
|
|
202
|
-
const next = dependsOn(state);
|
|
203
|
-
if (next === null) {
|
|
204
|
-
if (currentKey === null) return;
|
|
205
|
-
controller?.abort();
|
|
206
|
-
controller = null;
|
|
207
|
-
generation += 1;
|
|
208
|
-
currentKey = null;
|
|
209
|
-
store.set({ state: "idle" });
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
if (currentKey !== null && keyEquals(currentKey, next)) return;
|
|
213
|
-
currentKey = next;
|
|
214
|
-
run(next);
|
|
215
|
-
};
|
|
216
|
-
sync(source.get());
|
|
217
|
-
const unsubscribe = source.subscribe(sync);
|
|
218
|
-
const get = store.get;
|
|
219
|
-
const subscribe = store.subscribe;
|
|
220
|
-
const dispose = () => {
|
|
221
|
-
controller?.abort();
|
|
222
|
-
unsubscribe();
|
|
223
|
-
store.dispose();
|
|
224
|
-
};
|
|
225
|
-
const readable = {
|
|
226
|
-
get,
|
|
227
|
-
subscribe,
|
|
228
|
-
dispose
|
|
229
|
-
};
|
|
230
|
-
const settled = () => new Promise((resolve) => {
|
|
231
|
-
let unsubscribeSettled = () => {};
|
|
232
|
-
const check = (state) => {
|
|
233
|
-
if (state.state === "ready" || state.state === "errored") {
|
|
234
|
-
unsubscribeSettled();
|
|
235
|
-
resolve(state);
|
|
236
|
-
}
|
|
237
|
-
};
|
|
238
|
-
unsubscribeSettled = store.subscribe(check);
|
|
239
|
-
check(store.get());
|
|
240
|
-
});
|
|
241
|
-
return {
|
|
242
|
-
store: readable,
|
|
243
|
-
settled
|
|
244
|
-
};
|
|
245
|
-
};
|
|
246
133
|
// src/utils/async/poll/registry.ts
|
|
247
134
|
const DEFAULT_LIMIT = 50;
|
|
248
135
|
const isFinished = ({ snapshot }) => snapshot.state !== "idle" && snapshot.state !== "requesting" && snapshot.state !== "polling";
|
|
@@ -454,721 +341,175 @@ const createPersistor = ({ storage = createNullStorage(), key, schema, defaultVa
|
|
|
454
341
|
locked
|
|
455
342
|
};
|
|
456
343
|
};
|
|
457
|
-
// src/serviceClientRegistry/utils.ts
|
|
458
|
-
const isBuiltInProperty = (property) => typeof property === "symbol" || property === "then" || property === "constructor" || property === "toString" || property === "valueOf";
|
|
459
|
-
/**
|
|
460
|
-
* Creates a dummy client that intercepts method calls and invokes the provided onCall callback.
|
|
461
|
-
*/
|
|
462
|
-
const createDummyClient = ({ onCall }) => {
|
|
463
|
-
const createProxy = (path = []) => new Proxy(() => {}, {
|
|
464
|
-
get: (_target, prop) => {
|
|
465
|
-
if (isBuiltInProperty(prop)) return void 0;
|
|
466
|
-
return createProxy([...path, prop]);
|
|
467
|
-
},
|
|
468
|
-
apply: (_target, _thisArgs, args) => onCall(path, args)
|
|
469
|
-
});
|
|
470
|
-
return createProxy();
|
|
471
|
-
};
|
|
472
|
-
// src/serviceClientRegistry/createServiceClientRegistry.ts
|
|
473
|
-
const createServiceClientRegistry = () => ({ getServiceBaseUrl, onUnavailable }) => {
|
|
474
|
-
const dummy = (serviceId, clientName) => createDummyClient({ onCall: (path, args) => {
|
|
475
|
-
onUnavailable?.({
|
|
476
|
-
serviceId,
|
|
477
|
-
path,
|
|
478
|
-
args,
|
|
479
|
-
clientName
|
|
480
|
-
});
|
|
481
|
-
} });
|
|
482
|
-
const configs = [];
|
|
483
|
-
const resolveClient = ({ serviceId, clientFn, clientName }) => {
|
|
484
|
-
const serviceBaseUrl = getServiceBaseUrl(serviceId);
|
|
485
|
-
return serviceBaseUrl ? clientFn(serviceBaseUrl) : dummy(serviceId, clientName);
|
|
486
|
-
};
|
|
487
|
-
const registry = {
|
|
488
|
-
add: (config) => {
|
|
489
|
-
configs.push(config);
|
|
490
|
-
return registry;
|
|
491
|
-
},
|
|
492
|
-
build: () => {
|
|
493
|
-
const clientMap = {};
|
|
494
|
-
const clientMeta = [];
|
|
495
|
-
configs.forEach((config) => {
|
|
496
|
-
clientMap[config.clientName] = resolveClient(config);
|
|
497
|
-
clientMeta.push({
|
|
498
|
-
clientName: config.clientName,
|
|
499
|
-
serviceId: config.serviceId,
|
|
500
|
-
isAvailable: !!getServiceBaseUrl(config.serviceId)
|
|
501
|
-
});
|
|
502
|
-
});
|
|
503
|
-
return {
|
|
504
|
-
client: clientMap,
|
|
505
|
-
meta: clientMeta
|
|
506
|
-
};
|
|
507
|
-
}
|
|
508
|
-
};
|
|
509
|
-
return registry;
|
|
510
|
-
};
|
|
511
|
-
// src/keboola/createApi.ts
|
|
512
|
-
const createApi = (state) => new Proxy({}, { get(_target, property) {
|
|
513
|
-
if (isBuiltInProperty(property)) return void 0;
|
|
514
|
-
if (property === "auth") {
|
|
515
|
-
const authClient = state.getAuthClient();
|
|
516
|
-
assert$1(authClient, KeboolaErrorType.Unconfigured);
|
|
517
|
-
return authClient;
|
|
518
|
-
}
|
|
519
|
-
if (property === "management") {
|
|
520
|
-
const management = state.getManagementClient();
|
|
521
|
-
assert$1(management, KeboolaErrorType.NoManagementToken);
|
|
522
|
-
return management;
|
|
523
|
-
}
|
|
524
|
-
const clients = state.getProjectClients();
|
|
525
|
-
assert$1(clients, KeboolaErrorType.NotReady);
|
|
526
|
-
return clients[property];
|
|
527
|
-
} });
|
|
528
344
|
// src/keboola/createMiddlewareFor.ts
|
|
529
345
|
const createMiddlewareFor = (middlewares) => {
|
|
530
346
|
return (target, baseline = []) => {
|
|
531
347
|
if (Array.isArray(middlewares)) return [...baseline, ...middlewares];
|
|
532
|
-
|
|
533
|
-
const targeted = middlewares?.[target] ?? [];
|
|
534
|
-
return [
|
|
535
|
-
...baseline,
|
|
536
|
-
...all,
|
|
537
|
-
...targeted
|
|
538
|
-
];
|
|
348
|
+
return [...baseline, ...middlewares?.[target] ?? []];
|
|
539
349
|
};
|
|
540
350
|
};
|
|
541
|
-
// src/keboola/
|
|
542
|
-
const
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
351
|
+
// src/keboola/state/auth.ts
|
|
352
|
+
const grantOf = (credential) => credential.type === "token" ? {
|
|
353
|
+
type: "token",
|
|
354
|
+
refreshToken: credential.refreshToken
|
|
355
|
+
} : {
|
|
356
|
+
type: "cookie",
|
|
357
|
+
sessionId: credential.sessionId
|
|
358
|
+
};
|
|
359
|
+
const stamped = (input) => ({
|
|
360
|
+
...input,
|
|
361
|
+
issuedAt: Date.now()
|
|
362
|
+
});
|
|
363
|
+
const credentialOf = (auth) => auth.status === "authenticated" ? Result.success(auth.credential) : Result.failure(new KeboolaError(KeboolaErrorType.NotAuthenticated));
|
|
364
|
+
/**
|
|
365
|
+
* The stack's credential and its sign-in pin.
|
|
366
|
+
*
|
|
367
|
+
* - `epoch` moves on `authenticate` and `signOut` and never on a rotation, so it is exactly "which
|
|
368
|
+
* sign-in is this" — what an in-flight exchange compares itself against.
|
|
369
|
+
*/
|
|
370
|
+
const createAuth = (stacks) => {
|
|
371
|
+
const expired = /* @__PURE__ */ new Set();
|
|
372
|
+
const requireCredential = (baseUrl) => Result.andThen(stacks.get(baseUrl), (stack) => credentialOf(stack.auth));
|
|
373
|
+
const requireUnauthenticated = (baseUrl) => Result.andThen(stacks.get(baseUrl), (stack) => stack.auth.status === "authenticated" ? Result.failure(new KeboolaError(KeboolaErrorType.AlreadyAuthenticated)) : Result.success(stack));
|
|
374
|
+
const requireAnonymous = (baseUrl) => Result.andThen(requireUnauthenticated(baseUrl), (stack) => stack.auth.status === "restoring" ? Result.failure(/* @__PURE__ */ new Error(`Stack "${baseUrl}" is already being restored`)) : Result.success(stack));
|
|
375
|
+
const requireRestoring = (baseUrl) => Result.andThen(stacks.get(baseUrl), (stack) => stack.auth.status === "restoring" ? Result.success(stack) : Result.failure(/* @__PURE__ */ new Error(`Stack "${baseUrl}" is not being restored`)));
|
|
376
|
+
const startRestore = (baseUrl) => Result.map(requireAnonymous(baseUrl), (stack) => stacks.set({
|
|
377
|
+
...stack,
|
|
378
|
+
auth: { status: "restoring" }
|
|
379
|
+
}));
|
|
380
|
+
const cancelRestore = (baseUrl) => Result.map(requireRestoring(baseUrl), (stack) => stacks.set({
|
|
381
|
+
...stack,
|
|
382
|
+
auth: { status: "anonymous" }
|
|
383
|
+
}));
|
|
384
|
+
const authenticate = (baseUrl, input) => Result.map(requireUnauthenticated(baseUrl), (stack) => {
|
|
385
|
+
expired.delete(baseUrl);
|
|
386
|
+
return stacks.set({
|
|
387
|
+
...stack,
|
|
388
|
+
epoch: stack.epoch + 1,
|
|
389
|
+
auth: {
|
|
390
|
+
status: "authenticated",
|
|
391
|
+
credential: stamped(input)
|
|
392
|
+
},
|
|
393
|
+
retained: null
|
|
552
394
|
});
|
|
553
|
-
};
|
|
554
|
-
const
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
395
|
+
});
|
|
396
|
+
const applyRefresh = (baseUrl, input) => Result.andThen(requireCredential(baseUrl), (credential) => credential.type !== input.type ? Result.failure(/* @__PURE__ */ new Error(`A ${credential.type} grant cannot become ${input.type}`)) : Result.map(stacks.get(baseUrl), (stack) => stacks.set({
|
|
397
|
+
...stack,
|
|
398
|
+
auth: {
|
|
399
|
+
status: "authenticated",
|
|
400
|
+
credential: stamped(input)
|
|
401
|
+
}
|
|
402
|
+
})));
|
|
403
|
+
const forceExpire = (baseUrl) => Result.andThen(requireCredential(baseUrl), (credential) => Result.map(stacks.get(baseUrl), (stack) => stacks.set({
|
|
404
|
+
...stack,
|
|
405
|
+
auth: {
|
|
406
|
+
status: "authenticated",
|
|
407
|
+
credential: {
|
|
408
|
+
...credential,
|
|
409
|
+
issuedAt: Date.now() - credential.expiresIn * 1e3
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
})));
|
|
413
|
+
const signOut = (baseUrl, { retain = false } = {}) => Result.map(stacks.get(baseUrl), (stack) => {
|
|
414
|
+
const retained = retain ? Result.unwrapOr(Result.map(credentialOf(stack.auth), (credential) => ({ grant: grantOf(credential) })), stack.retained) : null;
|
|
415
|
+
return stacks.set({
|
|
416
|
+
...stack,
|
|
417
|
+
epoch: stack.epoch + 1,
|
|
418
|
+
auth: { status: "anonymous" },
|
|
419
|
+
retained
|
|
560
420
|
});
|
|
561
|
-
};
|
|
562
|
-
const getStorageToken = () => store.get().sapiToken ?? "";
|
|
563
|
-
const setStorageToken = (sapiToken) => store.set({
|
|
564
|
-
...store.get(),
|
|
565
|
-
sapiToken
|
|
566
421
|
});
|
|
567
|
-
|
|
568
|
-
|
|
422
|
+
const retain = (baseUrl, retained) => Result.map(stacks.get(baseUrl), (stack) => stacks.set({
|
|
423
|
+
...stack,
|
|
424
|
+
retained
|
|
425
|
+
}));
|
|
426
|
+
const dropRetained = (baseUrl) => Result.map(stacks.get(baseUrl), (stack) => stacks.set({
|
|
427
|
+
...stack,
|
|
428
|
+
retained: null
|
|
429
|
+
}));
|
|
430
|
+
const requireRetained = (baseUrl) => Result.andThen(stacks.get(baseUrl), (stack) => stack.retained ? Result.success(stack.retained) : Result.failure(/* @__PURE__ */ new Error(`Stack "${baseUrl}" retains no credential`)));
|
|
431
|
+
const notifyExpired = (baseUrl) => {
|
|
432
|
+
if (expired.has(baseUrl)) return false;
|
|
433
|
+
expired.add(baseUrl);
|
|
434
|
+
return true;
|
|
435
|
+
};
|
|
436
|
+
const getEpoch = (baseUrl) => Result.map(stacks.get(baseUrl), (stack) => stack.epoch);
|
|
437
|
+
const getAccessToken = (baseUrl) => Result.unwrapOr(Result.map(requireCredential(baseUrl), ({ accessToken }) => accessToken), null);
|
|
569
438
|
return {
|
|
570
|
-
|
|
571
|
-
|
|
439
|
+
startRestore,
|
|
440
|
+
cancelRestore,
|
|
572
441
|
authenticate,
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
442
|
+
applyRefresh,
|
|
443
|
+
forceExpire,
|
|
444
|
+
signOut,
|
|
445
|
+
retain,
|
|
446
|
+
dropRetained,
|
|
447
|
+
requireRetained,
|
|
448
|
+
notifyExpired,
|
|
449
|
+
requireCredential,
|
|
450
|
+
getEpoch,
|
|
451
|
+
getAccessToken
|
|
576
452
|
};
|
|
577
453
|
};
|
|
578
|
-
// src/
|
|
579
|
-
const
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
const featureSet = new Set(features);
|
|
592
|
-
const hasFeature = (...feature) => {
|
|
593
|
-
if (feature.length === 0) return false;
|
|
594
|
-
return feature.every((x) => featureSet.has(x));
|
|
454
|
+
// src/keboola/state/stacks.ts
|
|
455
|
+
const newStack = (baseUrl) => ({
|
|
456
|
+
baseUrl,
|
|
457
|
+
context: "idle",
|
|
458
|
+
epoch: 0,
|
|
459
|
+
auth: { status: "anonymous" },
|
|
460
|
+
retained: null
|
|
461
|
+
});
|
|
462
|
+
/** One entry per stack, and the verbs that open and select them. */
|
|
463
|
+
const createStacks = (store) => {
|
|
464
|
+
const get = (baseUrl) => {
|
|
465
|
+
const stack = store.get().stacks[baseUrl];
|
|
466
|
+
return stack ? Result.success(stack) : Result.failure(new KeboolaError(KeboolaErrorType.Unconfigured));
|
|
595
467
|
};
|
|
596
|
-
const
|
|
597
|
-
|
|
598
|
-
|
|
468
|
+
const set = (stack) => {
|
|
469
|
+
const state = store.get();
|
|
470
|
+
store.set({
|
|
471
|
+
...state,
|
|
472
|
+
stacks: {
|
|
473
|
+
...state.stacks,
|
|
474
|
+
[stack.baseUrl]: stack
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
return stack;
|
|
599
478
|
};
|
|
600
|
-
const
|
|
601
|
-
|
|
602
|
-
|
|
479
|
+
const ensure = (baseUrl) => {
|
|
480
|
+
const existing = get(baseUrl);
|
|
481
|
+
if (existing.success) return existing.data;
|
|
482
|
+
return set(newStack(baseUrl));
|
|
483
|
+
};
|
|
484
|
+
const getActive = () => {
|
|
485
|
+
const { active } = store.get();
|
|
486
|
+
const stack = get(active);
|
|
487
|
+
if (!stack.success) throw new Error(`The active stack has no row: ${active}`);
|
|
488
|
+
return stack.data;
|
|
489
|
+
};
|
|
490
|
+
const select = (baseUrl) => {
|
|
491
|
+
const stack = ensure(baseUrl);
|
|
492
|
+
const state = store.get();
|
|
493
|
+
if (state.active !== baseUrl) store.set({
|
|
494
|
+
...state,
|
|
495
|
+
active: baseUrl
|
|
496
|
+
});
|
|
497
|
+
return stack;
|
|
498
|
+
};
|
|
499
|
+
const updateContext = (baseUrl, context) => Result.map(get(baseUrl), (stack) => set({
|
|
500
|
+
...stack,
|
|
501
|
+
context
|
|
502
|
+
}));
|
|
603
503
|
return {
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
hasService,
|
|
611
|
-
getComponent,
|
|
612
|
-
hasComponent
|
|
504
|
+
get,
|
|
505
|
+
set,
|
|
506
|
+
ensure,
|
|
507
|
+
getActive,
|
|
508
|
+
select,
|
|
509
|
+
updateContext
|
|
613
510
|
};
|
|
614
511
|
};
|
|
615
|
-
// src/
|
|
616
|
-
const VARIABLES_COMPONENT_ID = "keboola.variables";
|
|
617
|
-
/** Union the definitions by name; on a name conflict the target's definition is kept. */
|
|
618
|
-
const mergeVariableDefinitions = (target, source) => {
|
|
619
|
-
const targetNames = new Set(target.map((definition) => definition.name));
|
|
620
|
-
return [...target, ...source.filter((definition) => !targetNames.has(definition.name))];
|
|
621
|
-
};
|
|
622
|
-
/** Add values missing in the target; on a name conflict the value is updated to the source's. */
|
|
623
|
-
const mergeVariableValues = (target, source) => {
|
|
624
|
-
const sourceByName = new Map(source.map((value) => [value.name, value.value]));
|
|
625
|
-
const targetNames = new Set(target.map((value) => value.name));
|
|
626
|
-
return [...target.map((value) => sourceByName.has(value.name) ? {
|
|
627
|
-
...value,
|
|
628
|
-
value: sourceByName.get(value.name)
|
|
629
|
-
} : value), ...source.filter((value) => !targetNames.has(value.name))];
|
|
630
|
-
};
|
|
631
|
-
/**
|
|
632
|
-
* Orchestration for `keboola.variables` configs: copy a config, or merge two configs into a fresh
|
|
633
|
-
* one (union definitions, upsert values — source wins on a name conflict). Each result is a brand
|
|
634
|
-
* new config + values row, so the caller can reference it without sharing lineage with the source.
|
|
635
|
-
*/
|
|
636
|
-
const createVariablesSdk = ({ storageClient }) => {
|
|
637
|
-
const configs = storageClient.configurations;
|
|
638
|
-
const rows = storageClient.configurationRows;
|
|
639
|
-
const readVariables = async (configId, valuesRowId, branchId) => {
|
|
640
|
-
const config = await configs.getConfiguration({
|
|
641
|
-
componentId: VARIABLES_COMPONENT_ID,
|
|
642
|
-
configId,
|
|
643
|
-
branchId
|
|
644
|
-
});
|
|
645
|
-
const row = config.rows.find((candidate) => candidate.id === valuesRowId) ?? config.rows[0];
|
|
646
|
-
const rawDefinitions = config.configuration?.variables;
|
|
647
|
-
const rawValues = row?.configuration?.values;
|
|
648
|
-
return {
|
|
649
|
-
definitions: Array.isArray(rawDefinitions) ? rawDefinitions : [],
|
|
650
|
-
values: Array.isArray(rawValues) ? rawValues : []
|
|
651
|
-
};
|
|
652
|
-
};
|
|
653
|
-
const createVariables = async (definitions, values, branchId) => {
|
|
654
|
-
const config = await configs.createConfiguration({
|
|
655
|
-
branchId,
|
|
656
|
-
componentId: VARIABLES_COMPONENT_ID,
|
|
657
|
-
name: "Variables definition",
|
|
658
|
-
configuration: { variables: definitions }
|
|
659
|
-
});
|
|
660
|
-
try {
|
|
661
|
-
const row = await rows.createConfigurationRow({
|
|
662
|
-
branchId: String(branchId),
|
|
663
|
-
componentId: VARIABLES_COMPONENT_ID,
|
|
664
|
-
configurationId: config.id,
|
|
665
|
-
name: "Default values",
|
|
666
|
-
configuration: { values }
|
|
667
|
-
});
|
|
668
|
-
return {
|
|
669
|
-
variablesId: config.id,
|
|
670
|
-
variablesValuesId: row.id
|
|
671
|
-
};
|
|
672
|
-
} catch (error) {
|
|
673
|
-
await configs.deleteConfiguration({
|
|
674
|
-
branchId,
|
|
675
|
-
componentId: VARIABLES_COMPONENT_ID,
|
|
676
|
-
configId: config.id
|
|
677
|
-
}).catch((cleanupError) => {
|
|
678
|
-
if (error instanceof Error && error.cause === void 0) error.cause = cleanupError;
|
|
679
|
-
});
|
|
680
|
-
throw error;
|
|
681
|
-
}
|
|
682
|
-
};
|
|
683
|
-
return {
|
|
684
|
-
/** Copy a variables config into a fresh, independent config + values row. */
|
|
685
|
-
copy: async ({ variablesId, variablesValuesId, branchId = "default" }) => {
|
|
686
|
-
const { definitions, values } = await readVariables(variablesId, variablesValuesId, branchId);
|
|
687
|
-
return createVariables(definitions, values, branchId);
|
|
688
|
-
},
|
|
689
|
-
/** Merge the source's variables into the target's and create a fresh merged config + values row. */
|
|
690
|
-
merge: async ({ targetVariablesId, targetValuesId, sourceVariablesId, sourceValuesId, branchId = "default" }) => {
|
|
691
|
-
const [target, source] = await Promise.all([readVariables(targetVariablesId, targetValuesId, branchId), readVariables(sourceVariablesId, sourceValuesId, branchId)]);
|
|
692
|
-
return createVariables(mergeVariableDefinitions(target.definitions, source.definitions), mergeVariableValues(target.values, source.values), branchId);
|
|
693
|
-
}
|
|
694
|
-
};
|
|
695
|
-
};
|
|
696
|
-
// src/keboola/createSdk.ts
|
|
697
|
-
const createSdk = ({ storage, services }) => ({
|
|
698
|
-
tag: createTagSdk({ metastoreClient: services.metastore }),
|
|
699
|
-
semanticLayer: createSemanticLayerSdk({ metastoreClient: services.metastore }),
|
|
700
|
-
kaiMemory: createKaiMemorySdk({ metastoreClient: services.metastore }),
|
|
701
|
-
vault: createVaultSdk({
|
|
702
|
-
vaultClient: services.vault,
|
|
703
|
-
encryptionClient: services.encryption
|
|
704
|
-
}),
|
|
705
|
-
variables: createVariablesSdk({ storageClient: storage })
|
|
706
|
-
});
|
|
707
|
-
// src/keboola/createServiceClients.ts
|
|
708
|
-
const withPath = (serviceBaseUrl, path) => typeof serviceBaseUrl === "string" ? `${serviceBaseUrl}${path}` : async () => `${await serviceBaseUrl()}${path}`;
|
|
709
|
-
const createServiceClients = ({ baseUrl, auth, getServiceBaseUrl, middlewareFor, attachTokenMiddleware }) => createServiceClientRegistry()({
|
|
710
|
-
getServiceBaseUrl,
|
|
711
|
-
onUnavailable: ({ serviceId, path, clientName }) => {
|
|
712
|
-
throw new ServiceUnavailableError(serviceId, path, clientName);
|
|
713
|
-
}
|
|
714
|
-
}).add({
|
|
715
|
-
serviceId: "vault",
|
|
716
|
-
clientName: "vault",
|
|
717
|
-
clientFn: (serviceBaseUrl) => createVaultClient({
|
|
718
|
-
baseUrl: serviceBaseUrl,
|
|
719
|
-
middlewares: middlewareFor("vault", [attachTokenMiddleware]),
|
|
720
|
-
auth
|
|
721
|
-
})
|
|
722
|
-
}).add({
|
|
723
|
-
serviceId: "data-science",
|
|
724
|
-
clientName: "dataScience",
|
|
725
|
-
clientFn: (serviceBaseUrl) => createDataScienceClient({
|
|
726
|
-
baseUrl: serviceBaseUrl,
|
|
727
|
-
middlewares: middlewareFor("dataScience", [attachTokenMiddleware]),
|
|
728
|
-
auth
|
|
729
|
-
})
|
|
730
|
-
}).add({
|
|
731
|
-
serviceId: "data-science",
|
|
732
|
-
clientName: "apps",
|
|
733
|
-
clientFn: (serviceBaseUrl) => createAppsClient({
|
|
734
|
-
baseUrl: withPath(serviceBaseUrl, "/v2"),
|
|
735
|
-
middlewares: middlewareFor("apps", [attachTokenMiddleware]),
|
|
736
|
-
auth
|
|
737
|
-
})
|
|
738
|
-
}).add({
|
|
739
|
-
serviceId: "encryption",
|
|
740
|
-
clientName: "encryption",
|
|
741
|
-
clientFn: (serviceBaseUrl) => createEncryptionClient({
|
|
742
|
-
baseUrl: serviceBaseUrl,
|
|
743
|
-
middlewares: middlewareFor("encryption")
|
|
744
|
-
})
|
|
745
|
-
}).add({
|
|
746
|
-
serviceId: "editor",
|
|
747
|
-
clientName: "editor",
|
|
748
|
-
clientFn: (serviceBaseUrl) => createEditorClient({
|
|
749
|
-
baseUrl: serviceBaseUrl,
|
|
750
|
-
middlewares: middlewareFor("editor", [attachTokenMiddleware]),
|
|
751
|
-
auth
|
|
752
|
-
})
|
|
753
|
-
}).add({
|
|
754
|
-
serviceId: "sync-actions",
|
|
755
|
-
clientName: "syncActions",
|
|
756
|
-
clientFn: (serviceBaseUrl) => createSyncActionsClient({
|
|
757
|
-
baseUrl: serviceBaseUrl,
|
|
758
|
-
middlewares: middlewareFor("syncActions", [attachTokenMiddleware]),
|
|
759
|
-
auth
|
|
760
|
-
})
|
|
761
|
-
}).add({
|
|
762
|
-
serviceId: "telemetry",
|
|
763
|
-
clientName: "telemetry",
|
|
764
|
-
clientFn: (serviceBaseUrl) => createTelemetryClient({
|
|
765
|
-
baseUrl: serviceBaseUrl,
|
|
766
|
-
middlewares: middlewareFor("telemetry", [attachTokenMiddleware]),
|
|
767
|
-
auth
|
|
768
|
-
})
|
|
769
|
-
}).add({
|
|
770
|
-
serviceId: "query",
|
|
771
|
-
clientName: "queryService",
|
|
772
|
-
clientFn: (serviceBaseUrl) => createQueryServiceClient({
|
|
773
|
-
baseUrl: serviceBaseUrl,
|
|
774
|
-
middlewares: middlewareFor("queryService", [attachTokenMiddleware]),
|
|
775
|
-
auth
|
|
776
|
-
})
|
|
777
|
-
}).add({
|
|
778
|
-
serviceId: "queue",
|
|
779
|
-
clientName: "queue",
|
|
780
|
-
clientFn: (serviceBaseUrl) => createQueueClient({
|
|
781
|
-
baseUrl: serviceBaseUrl,
|
|
782
|
-
middlewares: middlewareFor("queue", [attachTokenMiddleware]),
|
|
783
|
-
auth
|
|
784
|
-
})
|
|
785
|
-
}).add({
|
|
786
|
-
serviceId: "kai-assistant",
|
|
787
|
-
clientName: "chat",
|
|
788
|
-
clientFn: (serviceBaseUrl) => createChatClient({
|
|
789
|
-
storageApiUrl: baseUrl,
|
|
790
|
-
baseUrl: serviceBaseUrl,
|
|
791
|
-
middlewares: middlewareFor("chat", [attachTokenMiddleware]),
|
|
792
|
-
auth
|
|
793
|
-
})
|
|
794
|
-
}).add({
|
|
795
|
-
serviceId: "ai",
|
|
796
|
-
clientName: "ai",
|
|
797
|
-
clientFn: (serviceBaseUrl) => createAiClient({
|
|
798
|
-
baseUrl: serviceBaseUrl,
|
|
799
|
-
middlewares: middlewareFor("ai", [attachTokenMiddleware]),
|
|
800
|
-
auth
|
|
801
|
-
})
|
|
802
|
-
}).add({
|
|
803
|
-
serviceId: "ai",
|
|
804
|
-
clientName: "omnisearch",
|
|
805
|
-
clientFn: (serviceBaseUrl) => createOmnisearchClient({
|
|
806
|
-
baseUrl: withPath(serviceBaseUrl, "/omnisearch"),
|
|
807
|
-
middlewares: middlewareFor("omnisearch", [attachTokenMiddleware]),
|
|
808
|
-
auth
|
|
809
|
-
})
|
|
810
|
-
}).add({
|
|
811
|
-
serviceId: "import",
|
|
812
|
-
clientName: "import",
|
|
813
|
-
clientFn: (serviceBaseUrl) => createImportClient({
|
|
814
|
-
baseUrl: serviceBaseUrl,
|
|
815
|
-
middlewares: middlewareFor("import", [attachTokenMiddleware]),
|
|
816
|
-
auth
|
|
817
|
-
})
|
|
818
|
-
}).add({
|
|
819
|
-
serviceId: "kai-agent",
|
|
820
|
-
clientName: "kaiAgent",
|
|
821
|
-
clientFn: (serviceBaseUrl) => createKaiAgentClient({
|
|
822
|
-
baseUrl: serviceBaseUrl,
|
|
823
|
-
middlewares: middlewareFor("kaiAgent", [attachTokenMiddleware]),
|
|
824
|
-
auth
|
|
825
|
-
})
|
|
826
|
-
}).add({
|
|
827
|
-
serviceId: "components-mcp",
|
|
828
|
-
clientName: "componentsMcp",
|
|
829
|
-
clientFn: (serviceBaseUrl) => createComponentsMcpClient({
|
|
830
|
-
baseUrl: serviceBaseUrl,
|
|
831
|
-
middlewares: middlewareFor("componentsMcp", [attachTokenMiddleware]),
|
|
832
|
-
auth
|
|
833
|
-
})
|
|
834
|
-
}).add({
|
|
835
|
-
serviceId: "oauth",
|
|
836
|
-
clientName: "oauth",
|
|
837
|
-
clientFn: (serviceBaseUrl) => createOauthClient({
|
|
838
|
-
baseUrl: serviceBaseUrl,
|
|
839
|
-
middlewares: middlewareFor("oauth", [attachTokenMiddleware]),
|
|
840
|
-
auth
|
|
841
|
-
})
|
|
842
|
-
}).add({
|
|
843
|
-
serviceId: "scheduler",
|
|
844
|
-
clientName: "scheduler",
|
|
845
|
-
clientFn: (serviceBaseUrl) => createSchedulerClient({
|
|
846
|
-
baseUrl: serviceBaseUrl,
|
|
847
|
-
middlewares: middlewareFor("scheduler", [attachTokenMiddleware]),
|
|
848
|
-
auth
|
|
849
|
-
})
|
|
850
|
-
}).add({
|
|
851
|
-
serviceId: "stream",
|
|
852
|
-
clientName: "stream",
|
|
853
|
-
clientFn: (serviceBaseUrl) => createStreamClient({
|
|
854
|
-
baseUrl: serviceBaseUrl,
|
|
855
|
-
middlewares: middlewareFor("stream", [attachTokenMiddleware]),
|
|
856
|
-
auth
|
|
857
|
-
})
|
|
858
|
-
}).add({
|
|
859
|
-
serviceId: "notification",
|
|
860
|
-
clientName: "notifications",
|
|
861
|
-
clientFn: (serviceBaseUrl) => createNotificationsClient({
|
|
862
|
-
baseUrl: serviceBaseUrl,
|
|
863
|
-
middlewares: middlewareFor("notifications", [attachTokenMiddleware]),
|
|
864
|
-
auth
|
|
865
|
-
})
|
|
866
|
-
}).add({
|
|
867
|
-
serviceId: "billing",
|
|
868
|
-
clientName: "billing",
|
|
869
|
-
clientFn: (serviceBaseUrl) => createBillingClient({
|
|
870
|
-
baseUrl: serviceBaseUrl,
|
|
871
|
-
middlewares: middlewareFor("billing", [attachTokenMiddleware]),
|
|
872
|
-
auth
|
|
873
|
-
})
|
|
874
|
-
}).add({
|
|
875
|
-
serviceId: "metastore",
|
|
876
|
-
clientName: "metastore",
|
|
877
|
-
clientFn: (serviceBaseUrl) => createMetastoreClient({
|
|
878
|
-
baseUrl: serviceBaseUrl,
|
|
879
|
-
middlewares: middlewareFor("metastore", [attachTokenMiddleware]),
|
|
880
|
-
auth
|
|
881
|
-
})
|
|
882
|
-
}).build();
|
|
883
|
-
// src/keboola/legacy/createProjectClients.ts
|
|
884
|
-
const createAttachStorageToken = (getToken) => (next) => (request) => {
|
|
885
|
-
request.request.headers.set(KeboolaHttpHeader.STORAGE_API_TOKEN, getToken());
|
|
886
|
-
return next(request);
|
|
887
|
-
};
|
|
888
|
-
const createProjectClients = async ({ baseUrl, getStorageToken, onStorageTokenRefreshed, middlewareFor, clientServiceUrls }) => {
|
|
889
|
-
const auth = {
|
|
890
|
-
type: "sapi-token",
|
|
891
|
-
token: getStorageToken()
|
|
892
|
-
};
|
|
893
|
-
const attach = createAttachStorageToken(getStorageToken);
|
|
894
|
-
const stackInfo = await createStorageClient({
|
|
895
|
-
baseUrl,
|
|
896
|
-
auth,
|
|
897
|
-
middlewares: [attach]
|
|
898
|
-
}).getStackInfo({ exclude: "componentDetails" });
|
|
899
|
-
const stack = createStack({
|
|
900
|
-
stackInfo,
|
|
901
|
-
clientServiceUrls
|
|
902
|
-
});
|
|
903
|
-
const storage = createStorageClient({
|
|
904
|
-
baseUrl,
|
|
905
|
-
auth,
|
|
906
|
-
middlewares: middlewareFor("storage", []),
|
|
907
|
-
onRefreshToken: onStorageTokenRefreshed
|
|
908
|
-
});
|
|
909
|
-
const { client: services, meta: serviceMeta } = createServiceClients({
|
|
910
|
-
baseUrl,
|
|
911
|
-
auth,
|
|
912
|
-
getServiceBaseUrl: stack.getServiceUrl,
|
|
913
|
-
middlewareFor,
|
|
914
|
-
attachTokenMiddleware: attach
|
|
915
|
-
});
|
|
916
|
-
return {
|
|
917
|
-
baseUrl: normalizeBaseUrl(baseUrl),
|
|
918
|
-
stack,
|
|
919
|
-
serviceMeta,
|
|
920
|
-
storage,
|
|
921
|
-
...services,
|
|
922
|
-
sdk: createSdk({
|
|
923
|
-
storage,
|
|
924
|
-
services
|
|
925
|
-
})
|
|
926
|
-
};
|
|
927
|
-
};
|
|
928
|
-
// src/keboola/legacy/keboola.ts
|
|
929
|
-
const createLegacyKeboola = (options = {}) => {
|
|
930
|
-
const config = createConfig();
|
|
931
|
-
const middlewareFor = createMiddlewareFor(options.middlewares);
|
|
932
|
-
const authClient = createDerivedStore({
|
|
933
|
-
source: config.store,
|
|
934
|
-
dependsOn: (state) => state.baseUrl,
|
|
935
|
-
build: (baseUrl) => baseUrl ? createAuthClient({
|
|
936
|
-
baseUrl,
|
|
937
|
-
middlewares: middlewareFor("auth", [])
|
|
938
|
-
}) : null
|
|
939
|
-
});
|
|
940
|
-
const management = createDerivedStore({
|
|
941
|
-
source: config.store,
|
|
942
|
-
dependsOn: (state) => ({
|
|
943
|
-
baseUrl: state.baseUrl,
|
|
944
|
-
token: state.managementToken
|
|
945
|
-
}),
|
|
946
|
-
build: ({ baseUrl, token }) => baseUrl ? createManagementClient({
|
|
947
|
-
baseUrl,
|
|
948
|
-
auth: token ? {
|
|
949
|
-
type: "management-token",
|
|
950
|
-
token
|
|
951
|
-
} : { type: "management-token" },
|
|
952
|
-
middlewares: middlewareFor("management", [])
|
|
953
|
-
}) : null
|
|
954
|
-
});
|
|
955
|
-
const build = createDerivedAsyncStore({
|
|
956
|
-
source: config.store,
|
|
957
|
-
dependsOn: (state) => state.sapiToken && state.baseUrl ? state.baseUrl : null,
|
|
958
|
-
build: (baseUrl) => createProjectClients({
|
|
959
|
-
baseUrl,
|
|
960
|
-
getStorageToken: config.getStorageToken,
|
|
961
|
-
onStorageTokenRefreshed: config.setStorageToken,
|
|
962
|
-
middlewareFor,
|
|
963
|
-
clientServiceUrls: options.clientServiceUrls
|
|
964
|
-
})
|
|
965
|
-
});
|
|
966
|
-
if (options.baseUrl) config.setBaseUrl(options.baseUrl);
|
|
967
|
-
const debug = () => {
|
|
968
|
-
const info = config.debug();
|
|
969
|
-
return {
|
|
970
|
-
type: "Sapi",
|
|
971
|
-
config: info,
|
|
972
|
-
authReady: authClient.get() !== null,
|
|
973
|
-
managementReady: !!info.managementToken,
|
|
974
|
-
storage: build.store.get().state
|
|
975
|
-
};
|
|
976
|
-
};
|
|
977
|
-
const session = {
|
|
978
|
-
setBaseUrl: config.setBaseUrl,
|
|
979
|
-
isStorageReady: () => build.store.get().state === "ready",
|
|
980
|
-
authenticateStorage: (sapiToken) => config.authenticate({ sapiToken }),
|
|
981
|
-
authenticateStorageAsync: async (sapiToken) => {
|
|
982
|
-
config.authenticate({ sapiToken });
|
|
983
|
-
await build.settled();
|
|
984
|
-
},
|
|
985
|
-
authenticateManagement: (managementToken) => config.authenticate({ managementToken }),
|
|
986
|
-
subscribe: (listener) => {
|
|
987
|
-
const unsubscribeConfig = config.store.subscribe(() => listener(debug()));
|
|
988
|
-
const unsubscribeBuild = build.store.subscribe(() => listener(debug()));
|
|
989
|
-
return () => {
|
|
990
|
-
unsubscribeConfig();
|
|
991
|
-
unsubscribeBuild();
|
|
992
|
-
};
|
|
993
|
-
},
|
|
994
|
-
debug
|
|
995
|
-
};
|
|
996
|
-
return {
|
|
997
|
-
api: createApi({
|
|
998
|
-
getAuthClient: () => authClient.get(),
|
|
999
|
-
getManagementClient: () => management.get(),
|
|
1000
|
-
getProjectClients: () => {
|
|
1001
|
-
const state = build.store.get();
|
|
1002
|
-
return state.state === "ready" ? state.value : null;
|
|
1003
|
-
}
|
|
1004
|
-
}),
|
|
1005
|
-
session
|
|
1006
|
-
};
|
|
1007
|
-
};
|
|
1008
|
-
// src/keboola/bearer/state/auth.ts
|
|
1009
|
-
const grantOf = (credential) => credential.type === "token" ? {
|
|
1010
|
-
type: "token",
|
|
1011
|
-
refreshToken: credential.refreshToken
|
|
1012
|
-
} : {
|
|
1013
|
-
type: "cookie",
|
|
1014
|
-
sessionId: credential.sessionId
|
|
1015
|
-
};
|
|
1016
|
-
const stamped = (input) => ({
|
|
1017
|
-
...input,
|
|
1018
|
-
issuedAt: Date.now()
|
|
1019
|
-
});
|
|
1020
|
-
const credentialOf = (auth) => auth.status === "authenticated" ? Result.success(auth.credential) : Result.failure(new KeboolaError(KeboolaErrorType.NotAuthenticated));
|
|
1021
|
-
/**
|
|
1022
|
-
* The stack's credential and its sign-in pin.
|
|
1023
|
-
*
|
|
1024
|
-
* - `epoch` moves on `authenticate` and `signOut` and never on a rotation, so it is exactly "which
|
|
1025
|
-
* sign-in is this" — what an in-flight exchange compares itself against.
|
|
1026
|
-
*/
|
|
1027
|
-
const createAuth = (stacks) => {
|
|
1028
|
-
const expired = /* @__PURE__ */ new Set();
|
|
1029
|
-
const requireCredential = (baseUrl) => Result.andThen(stacks.get(baseUrl), (stack) => credentialOf(stack.auth));
|
|
1030
|
-
const requireUnauthenticated = (baseUrl) => Result.andThen(stacks.get(baseUrl), (stack) => stack.auth.status === "authenticated" ? Result.failure(new KeboolaError(KeboolaErrorType.AlreadyAuthenticated)) : Result.success(stack));
|
|
1031
|
-
const requireAnonymous = (baseUrl) => Result.andThen(requireUnauthenticated(baseUrl), (stack) => stack.auth.status === "restoring" ? Result.failure(/* @__PURE__ */ new Error(`Stack "${baseUrl}" is already being restored`)) : Result.success(stack));
|
|
1032
|
-
const requireRestoring = (baseUrl) => Result.andThen(stacks.get(baseUrl), (stack) => stack.auth.status === "restoring" ? Result.success(stack) : Result.failure(/* @__PURE__ */ new Error(`Stack "${baseUrl}" is not being restored`)));
|
|
1033
|
-
const startRestore = (baseUrl) => Result.map(requireAnonymous(baseUrl), (stack) => stacks.set({
|
|
1034
|
-
...stack,
|
|
1035
|
-
auth: { status: "restoring" }
|
|
1036
|
-
}));
|
|
1037
|
-
const cancelRestore = (baseUrl) => Result.map(requireRestoring(baseUrl), (stack) => stacks.set({
|
|
1038
|
-
...stack,
|
|
1039
|
-
auth: { status: "anonymous" }
|
|
1040
|
-
}));
|
|
1041
|
-
const authenticate = (baseUrl, input) => Result.map(requireUnauthenticated(baseUrl), (stack) => {
|
|
1042
|
-
expired.delete(baseUrl);
|
|
1043
|
-
return stacks.set({
|
|
1044
|
-
...stack,
|
|
1045
|
-
epoch: stack.epoch + 1,
|
|
1046
|
-
auth: {
|
|
1047
|
-
status: "authenticated",
|
|
1048
|
-
credential: stamped(input)
|
|
1049
|
-
},
|
|
1050
|
-
retained: null
|
|
1051
|
-
});
|
|
1052
|
-
});
|
|
1053
|
-
const applyRefresh = (baseUrl, input) => Result.andThen(requireCredential(baseUrl), (credential) => credential.type !== input.type ? Result.failure(/* @__PURE__ */ new Error(`A ${credential.type} grant cannot become ${input.type}`)) : Result.map(stacks.get(baseUrl), (stack) => stacks.set({
|
|
1054
|
-
...stack,
|
|
1055
|
-
auth: {
|
|
1056
|
-
status: "authenticated",
|
|
1057
|
-
credential: stamped(input)
|
|
1058
|
-
}
|
|
1059
|
-
})));
|
|
1060
|
-
const forceExpire = (baseUrl) => Result.andThen(requireCredential(baseUrl), (credential) => Result.map(stacks.get(baseUrl), (stack) => stacks.set({
|
|
1061
|
-
...stack,
|
|
1062
|
-
auth: {
|
|
1063
|
-
status: "authenticated",
|
|
1064
|
-
credential: {
|
|
1065
|
-
...credential,
|
|
1066
|
-
issuedAt: Date.now() - credential.expiresIn * 1e3
|
|
1067
|
-
}
|
|
1068
|
-
}
|
|
1069
|
-
})));
|
|
1070
|
-
const signOut = (baseUrl, { retain = false } = {}) => Result.map(stacks.get(baseUrl), (stack) => {
|
|
1071
|
-
const retained = retain ? Result.unwrapOr(Result.map(credentialOf(stack.auth), (credential) => ({ grant: grantOf(credential) })), stack.retained) : null;
|
|
1072
|
-
return stacks.set({
|
|
1073
|
-
...stack,
|
|
1074
|
-
epoch: stack.epoch + 1,
|
|
1075
|
-
auth: { status: "anonymous" },
|
|
1076
|
-
retained
|
|
1077
|
-
});
|
|
1078
|
-
});
|
|
1079
|
-
const retain = (baseUrl, retained) => Result.map(stacks.get(baseUrl), (stack) => stacks.set({
|
|
1080
|
-
...stack,
|
|
1081
|
-
retained
|
|
1082
|
-
}));
|
|
1083
|
-
const dropRetained = (baseUrl) => Result.map(stacks.get(baseUrl), (stack) => stacks.set({
|
|
1084
|
-
...stack,
|
|
1085
|
-
retained: null
|
|
1086
|
-
}));
|
|
1087
|
-
const requireRetained = (baseUrl) => Result.andThen(stacks.get(baseUrl), (stack) => stack.retained ? Result.success(stack.retained) : Result.failure(/* @__PURE__ */ new Error(`Stack "${baseUrl}" retains no credential`)));
|
|
1088
|
-
const notifyExpired = (baseUrl) => {
|
|
1089
|
-
if (expired.has(baseUrl)) return false;
|
|
1090
|
-
expired.add(baseUrl);
|
|
1091
|
-
return true;
|
|
1092
|
-
};
|
|
1093
|
-
const getEpoch = (baseUrl) => Result.map(stacks.get(baseUrl), (stack) => stack.epoch);
|
|
1094
|
-
const getAccessToken = (baseUrl) => Result.unwrapOr(Result.map(requireCredential(baseUrl), ({ accessToken }) => accessToken), null);
|
|
1095
|
-
return {
|
|
1096
|
-
startRestore,
|
|
1097
|
-
cancelRestore,
|
|
1098
|
-
authenticate,
|
|
1099
|
-
applyRefresh,
|
|
1100
|
-
forceExpire,
|
|
1101
|
-
signOut,
|
|
1102
|
-
retain,
|
|
1103
|
-
dropRetained,
|
|
1104
|
-
requireRetained,
|
|
1105
|
-
notifyExpired,
|
|
1106
|
-
requireCredential,
|
|
1107
|
-
getEpoch,
|
|
1108
|
-
getAccessToken
|
|
1109
|
-
};
|
|
1110
|
-
};
|
|
1111
|
-
// src/keboola/bearer/state/stacks.ts
|
|
1112
|
-
const newStack = (baseUrl) => ({
|
|
1113
|
-
baseUrl,
|
|
1114
|
-
context: "idle",
|
|
1115
|
-
epoch: 0,
|
|
1116
|
-
auth: { status: "anonymous" },
|
|
1117
|
-
retained: null
|
|
1118
|
-
});
|
|
1119
|
-
/** One entry per stack, and the verbs that open and select them. */
|
|
1120
|
-
const createStacks = (store) => {
|
|
1121
|
-
const get = (baseUrl) => {
|
|
1122
|
-
const stack = store.get().stacks[baseUrl];
|
|
1123
|
-
return stack ? Result.success(stack) : Result.failure(new KeboolaError(KeboolaErrorType.Unconfigured));
|
|
1124
|
-
};
|
|
1125
|
-
const set = (stack) => {
|
|
1126
|
-
const state = store.get();
|
|
1127
|
-
store.set({
|
|
1128
|
-
...state,
|
|
1129
|
-
stacks: {
|
|
1130
|
-
...state.stacks,
|
|
1131
|
-
[stack.baseUrl]: stack
|
|
1132
|
-
}
|
|
1133
|
-
});
|
|
1134
|
-
return stack;
|
|
1135
|
-
};
|
|
1136
|
-
const update = (baseUrl, updater) => Result.map(get(baseUrl), (stack) => set(updater(stack)));
|
|
1137
|
-
const ensure = (baseUrl) => {
|
|
1138
|
-
const existing = get(baseUrl);
|
|
1139
|
-
if (existing.success) return existing.data;
|
|
1140
|
-
return set(newStack(baseUrl));
|
|
1141
|
-
};
|
|
1142
|
-
const getActive = () => {
|
|
1143
|
-
const { active } = store.get();
|
|
1144
|
-
const stack = get(active);
|
|
1145
|
-
if (!stack.success) throw new Error(`The active stack has no row: ${active}`);
|
|
1146
|
-
return stack.data;
|
|
1147
|
-
};
|
|
1148
|
-
const select = (baseUrl) => {
|
|
1149
|
-
const stack = ensure(baseUrl);
|
|
1150
|
-
const state = store.get();
|
|
1151
|
-
if (state.active !== baseUrl) store.set({
|
|
1152
|
-
...state,
|
|
1153
|
-
active: baseUrl
|
|
1154
|
-
});
|
|
1155
|
-
return stack;
|
|
1156
|
-
};
|
|
1157
|
-
const updateContext = (baseUrl, context) => update(baseUrl, (stack) => ({
|
|
1158
|
-
...stack,
|
|
1159
|
-
context
|
|
1160
|
-
}));
|
|
1161
|
-
return {
|
|
1162
|
-
get,
|
|
1163
|
-
set,
|
|
1164
|
-
update,
|
|
1165
|
-
ensure,
|
|
1166
|
-
getActive,
|
|
1167
|
-
select,
|
|
1168
|
-
updateContext
|
|
1169
|
-
};
|
|
1170
|
-
};
|
|
1171
|
-
// src/keboola/bearer/state/state.ts
|
|
512
|
+
// src/keboola/state/state.ts
|
|
1172
513
|
/**
|
|
1173
514
|
* The stack table and the rules over it, one namespace per concern.
|
|
1174
515
|
*
|
|
@@ -1187,8 +528,9 @@ const createState = (defaultBaseUrl) => {
|
|
|
1187
528
|
auth
|
|
1188
529
|
};
|
|
1189
530
|
};
|
|
1190
|
-
// src/keboola/
|
|
531
|
+
// src/keboola/credentials/credentials.ts
|
|
1191
532
|
const DEFAULT_REFRESH_THRESHOLD = .9;
|
|
533
|
+
const END_SESSION_TIMEOUT_MS = 1e4;
|
|
1192
534
|
const signInEnded = () => new KeboolaError(KeboolaErrorType.SignInEnded);
|
|
1193
535
|
const toRestoreStatus = (outcome) => {
|
|
1194
536
|
if (outcome === void 0 || outcome === "skipped") return "empty";
|
|
@@ -1229,13 +571,18 @@ const createCredentials = ({ state, persistor, middlewares, refreshThreshold = D
|
|
|
1229
571
|
const refreshed = await Result.tryCatchAsync(() => renew(client, grant));
|
|
1230
572
|
return isSameSignIn() ? refreshed : Result.failure(signInEnded());
|
|
1231
573
|
};
|
|
574
|
+
/**
|
|
575
|
+
* The grant to rotate, or the sign-out another tab stored.
|
|
576
|
+
*
|
|
577
|
+
* - `{ retained }`: the stored sign-in ended; `retained` is what a retained sign-out kept.
|
|
578
|
+
*/
|
|
1232
579
|
const getGrantForRotation = async (store, baseUrl, credential) => {
|
|
1233
580
|
const isSameSignIn = markSignIn(baseUrl);
|
|
1234
581
|
const hydrated = await Result.tryCatchAsync(() => store.read());
|
|
1235
582
|
if (!hydrated.success) return hydrated;
|
|
1236
583
|
if (!isSameSignIn()) return Result.failure(signInEnded());
|
|
1237
584
|
const persistedStack = hydrated.data.stacks.find((stack) => stack.baseUrl === baseUrl);
|
|
1238
|
-
if (persistedStack && persistedStack.credential === null) return Result.
|
|
585
|
+
if (persistedStack && persistedStack.credential === null) return Result.success({ retained: persistedStack.retained ?? null });
|
|
1239
586
|
return Result.success(persistedStack?.credential ?? grantOf(credential));
|
|
1240
587
|
};
|
|
1241
588
|
const rotateOnce = async (baseUrl) => persistor.locked(async (store) => {
|
|
@@ -1243,6 +590,10 @@ const createCredentials = ({ state, persistor, middlewares, refreshThreshold = D
|
|
|
1243
590
|
if (!credential.success) return credential;
|
|
1244
591
|
const grant = await getGrantForRotation(store, baseUrl, credential.data);
|
|
1245
592
|
if (!grant.success) return grant;
|
|
593
|
+
if ("retained" in grant.data) {
|
|
594
|
+
await expire(baseUrl, store, grant.data.retained);
|
|
595
|
+
return Result.failure(signInEnded());
|
|
596
|
+
}
|
|
1246
597
|
const refreshed = await refresh(baseUrl, grant.data);
|
|
1247
598
|
if (!refreshed.success) {
|
|
1248
599
|
if (isUnauthorized(refreshed.error)) await expire(baseUrl, store);
|
|
@@ -1314,9 +665,10 @@ const createCredentials = ({ state, persistor, middlewares, refreshThreshold = D
|
|
|
1314
665
|
onSignedOut?.(baseUrl);
|
|
1315
666
|
return signedOut;
|
|
1316
667
|
};
|
|
1317
|
-
const expire = async (baseUrl, store) => {
|
|
668
|
+
const expire = async (baseUrl, store, retained = null) => {
|
|
1318
669
|
if (!state.auth.notifyExpired(baseUrl)) return;
|
|
1319
670
|
signOut(baseUrl);
|
|
671
|
+
if (retained) state.auth.retain(baseUrl, retained);
|
|
1320
672
|
await store.persistStack(baseUrl, state.store.get());
|
|
1321
673
|
onExpired?.(baseUrl);
|
|
1322
674
|
};
|
|
@@ -1329,19 +681,360 @@ const createCredentials = ({ state, persistor, middlewares, refreshThreshold = D
|
|
|
1329
681
|
if (!state.auth.requireCredential(baseUrl).success) return null;
|
|
1330
682
|
return Result.unwrap(await rotate(baseUrl));
|
|
1331
683
|
}
|
|
1332
|
-
await renewIfStale(baseUrl);
|
|
1333
|
-
return state.auth.getAccessToken(baseUrl);
|
|
1334
|
-
} });
|
|
684
|
+
await renewIfStale(baseUrl);
|
|
685
|
+
return state.auth.getAccessToken(baseUrl);
|
|
686
|
+
} });
|
|
687
|
+
/**
|
|
688
|
+
* Ends a signed-out grant's server session: its refresh, derived PATs and paired browser session.
|
|
689
|
+
*
|
|
690
|
+
* 1. `token`: revokes the refresh token; the server also takes the one before the last rotation.
|
|
691
|
+
* 2. `cookie`: renews off the session cookie, then revokes that fresh access token.
|
|
692
|
+
* - Never an access token held from before: one rotation later the server no longer knows it.
|
|
693
|
+
* - Best effort, bounded by `END_SESSION_TIMEOUT_MS`: a failure is logged, the sign-out stands.
|
|
694
|
+
*/
|
|
695
|
+
const endSession = async (baseUrl, grant) => {
|
|
696
|
+
const client = createAuthClient({
|
|
697
|
+
baseUrl,
|
|
698
|
+
middlewares
|
|
699
|
+
});
|
|
700
|
+
const signal = AbortSignal.timeout(END_SESSION_TIMEOUT_MS);
|
|
701
|
+
try {
|
|
702
|
+
const body = grant.type === "token" ? {
|
|
703
|
+
token: grant.refreshToken,
|
|
704
|
+
tokenTypeHint: "refreshToken"
|
|
705
|
+
} : {
|
|
706
|
+
token: (await client.token.refreshWithSession({ sessionId: grant.sessionId }, signal)).accessToken,
|
|
707
|
+
tokenTypeHint: "accessToken"
|
|
708
|
+
};
|
|
709
|
+
await client.token.revoke(body, signal);
|
|
710
|
+
} catch (error) {
|
|
711
|
+
console.warn("createCredentials: the session could not be ended", error);
|
|
712
|
+
}
|
|
713
|
+
};
|
|
714
|
+
return {
|
|
715
|
+
middleware,
|
|
716
|
+
rotate,
|
|
717
|
+
renewIfStale,
|
|
718
|
+
restore,
|
|
719
|
+
restoreRetained,
|
|
720
|
+
signOut,
|
|
721
|
+
endSession
|
|
722
|
+
};
|
|
723
|
+
};
|
|
724
|
+
// src/serviceClientRegistry/utils.ts
|
|
725
|
+
const isBuiltInProperty = (property) => typeof property === "symbol" || property === "then" || property === "constructor" || property === "toString" || property === "valueOf";
|
|
726
|
+
/**
|
|
727
|
+
* Creates a dummy client that intercepts method calls and invokes the provided onCall callback.
|
|
728
|
+
*/
|
|
729
|
+
const createDummyClient = ({ onCall }) => {
|
|
730
|
+
const createProxy = (path = []) => new Proxy(() => {}, {
|
|
731
|
+
get: (_target, prop) => {
|
|
732
|
+
if (isBuiltInProperty(prop)) return void 0;
|
|
733
|
+
return createProxy([...path, prop]);
|
|
734
|
+
},
|
|
735
|
+
apply: (_target, _thisArgs, args) => onCall(path, args)
|
|
736
|
+
});
|
|
737
|
+
return createProxy();
|
|
738
|
+
};
|
|
739
|
+
// src/serviceClientRegistry/createServiceClientRegistry.ts
|
|
740
|
+
const createServiceClientRegistry = () => ({ getServiceBaseUrl, onUnavailable }) => {
|
|
741
|
+
const dummy = (serviceId, clientName) => createDummyClient({ onCall: (path, args) => {
|
|
742
|
+
onUnavailable?.({
|
|
743
|
+
serviceId,
|
|
744
|
+
path,
|
|
745
|
+
args,
|
|
746
|
+
clientName
|
|
747
|
+
});
|
|
748
|
+
} });
|
|
749
|
+
const configs = [];
|
|
750
|
+
const resolveClient = ({ serviceId, clientFn, clientName }) => {
|
|
751
|
+
const serviceBaseUrl = getServiceBaseUrl(serviceId);
|
|
752
|
+
return serviceBaseUrl ? clientFn(serviceBaseUrl) : dummy(serviceId, clientName);
|
|
753
|
+
};
|
|
754
|
+
const registry = {
|
|
755
|
+
add: (config) => {
|
|
756
|
+
configs.push(config);
|
|
757
|
+
return registry;
|
|
758
|
+
},
|
|
759
|
+
build: () => {
|
|
760
|
+
const clientMap = {};
|
|
761
|
+
configs.forEach((config) => {
|
|
762
|
+
clientMap[config.clientName] = resolveClient(config);
|
|
763
|
+
});
|
|
764
|
+
return { client: clientMap };
|
|
765
|
+
}
|
|
766
|
+
};
|
|
767
|
+
return registry;
|
|
768
|
+
};
|
|
769
|
+
// src/sdks/variables/variablesSdk.ts
|
|
770
|
+
const VARIABLES_COMPONENT_ID = "keboola.variables";
|
|
771
|
+
/** Union the definitions by name; on a name conflict the target's definition is kept. */
|
|
772
|
+
const mergeVariableDefinitions = (target, source) => {
|
|
773
|
+
const targetNames = new Set(target.map((definition) => definition.name));
|
|
774
|
+
return [...target, ...source.filter((definition) => !targetNames.has(definition.name))];
|
|
775
|
+
};
|
|
776
|
+
/** Add values missing in the target; on a name conflict the value is updated to the source's. */
|
|
777
|
+
const mergeVariableValues = (target, source) => {
|
|
778
|
+
const sourceByName = new Map(source.map((value) => [value.name, value.value]));
|
|
779
|
+
const targetNames = new Set(target.map((value) => value.name));
|
|
780
|
+
return [...target.map((value) => sourceByName.has(value.name) ? {
|
|
781
|
+
...value,
|
|
782
|
+
value: sourceByName.get(value.name)
|
|
783
|
+
} : value), ...source.filter((value) => !targetNames.has(value.name))];
|
|
784
|
+
};
|
|
785
|
+
/**
|
|
786
|
+
* Orchestration for `keboola.variables` configs: copy a config, or merge two configs into a fresh
|
|
787
|
+
* one (union definitions, upsert values — source wins on a name conflict). Each result is a brand
|
|
788
|
+
* new config + values row, so the caller can reference it without sharing lineage with the source.
|
|
789
|
+
*/
|
|
790
|
+
const createVariablesSdk = ({ storageClient }) => {
|
|
791
|
+
const configs = storageClient.configurations;
|
|
792
|
+
const rows = storageClient.configurationRows;
|
|
793
|
+
const readVariables = async (configId, valuesRowId, branchId) => {
|
|
794
|
+
const config = await configs.getConfiguration({
|
|
795
|
+
componentId: VARIABLES_COMPONENT_ID,
|
|
796
|
+
configId,
|
|
797
|
+
branchId
|
|
798
|
+
});
|
|
799
|
+
const row = config.rows.find((candidate) => candidate.id === valuesRowId) ?? config.rows[0];
|
|
800
|
+
const rawDefinitions = config.configuration?.variables;
|
|
801
|
+
const rawValues = row?.configuration?.values;
|
|
802
|
+
return {
|
|
803
|
+
definitions: Array.isArray(rawDefinitions) ? rawDefinitions : [],
|
|
804
|
+
values: Array.isArray(rawValues) ? rawValues : []
|
|
805
|
+
};
|
|
806
|
+
};
|
|
807
|
+
const createVariables = async (definitions, values, branchId) => {
|
|
808
|
+
const config = await configs.createConfiguration({
|
|
809
|
+
branchId,
|
|
810
|
+
componentId: VARIABLES_COMPONENT_ID,
|
|
811
|
+
name: "Variables definition",
|
|
812
|
+
configuration: { variables: definitions }
|
|
813
|
+
});
|
|
814
|
+
try {
|
|
815
|
+
const row = await rows.createConfigurationRow({
|
|
816
|
+
branchId: String(branchId),
|
|
817
|
+
componentId: VARIABLES_COMPONENT_ID,
|
|
818
|
+
configurationId: config.id,
|
|
819
|
+
name: "Default values",
|
|
820
|
+
configuration: { values }
|
|
821
|
+
});
|
|
822
|
+
return {
|
|
823
|
+
variablesId: config.id,
|
|
824
|
+
variablesValuesId: row.id
|
|
825
|
+
};
|
|
826
|
+
} catch (error) {
|
|
827
|
+
await configs.deleteConfiguration({
|
|
828
|
+
branchId,
|
|
829
|
+
componentId: VARIABLES_COMPONENT_ID,
|
|
830
|
+
configId: config.id
|
|
831
|
+
}).catch((cleanupError) => {
|
|
832
|
+
if (error instanceof Error && error.cause === void 0) error.cause = cleanupError;
|
|
833
|
+
});
|
|
834
|
+
throw error;
|
|
835
|
+
}
|
|
836
|
+
};
|
|
1335
837
|
return {
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
838
|
+
/** Copy a variables config into a fresh, independent config + values row. */
|
|
839
|
+
copy: async ({ variablesId, variablesValuesId, branchId = "default" }) => {
|
|
840
|
+
const { definitions, values } = await readVariables(variablesId, variablesValuesId, branchId);
|
|
841
|
+
return createVariables(definitions, values, branchId);
|
|
842
|
+
},
|
|
843
|
+
/** Merge the source's variables into the target's and create a fresh merged config + values row. */
|
|
844
|
+
merge: async ({ targetVariablesId, targetValuesId, sourceVariablesId, sourceValuesId, branchId = "default" }) => {
|
|
845
|
+
const [target, source] = await Promise.all([readVariables(targetVariablesId, targetValuesId, branchId), readVariables(sourceVariablesId, sourceValuesId, branchId)]);
|
|
846
|
+
return createVariables(mergeVariableDefinitions(target.definitions, source.definitions), mergeVariableValues(target.values, source.values), branchId);
|
|
847
|
+
}
|
|
1342
848
|
};
|
|
1343
849
|
};
|
|
1344
|
-
// src/keboola/
|
|
850
|
+
// src/keboola/createSdk.ts
|
|
851
|
+
const createSdk = ({ storage, services }) => ({
|
|
852
|
+
tag: createTagSdk({ metastoreClient: services.metastore }),
|
|
853
|
+
semanticLayer: createSemanticLayerSdk({ metastoreClient: services.metastore }),
|
|
854
|
+
kaiMemory: createKaiMemorySdk({ metastoreClient: services.metastore }),
|
|
855
|
+
vault: createVaultSdk({
|
|
856
|
+
vaultClient: services.vault,
|
|
857
|
+
encryptionClient: services.encryption
|
|
858
|
+
}),
|
|
859
|
+
variables: createVariablesSdk({ storageClient: storage })
|
|
860
|
+
});
|
|
861
|
+
// src/keboola/createServiceClients.ts
|
|
862
|
+
const withPath = (serviceBaseUrl, path) => typeof serviceBaseUrl === "string" ? `${serviceBaseUrl}${path}` : async () => `${await serviceBaseUrl()}${path}`;
|
|
863
|
+
const createServiceClients = ({ baseUrl, auth, getServiceBaseUrl, middlewareFor, attachTokenMiddleware }) => createServiceClientRegistry()({
|
|
864
|
+
getServiceBaseUrl,
|
|
865
|
+
onUnavailable: ({ serviceId, path, clientName }) => {
|
|
866
|
+
throw new ServiceUnavailableError(serviceId, path, clientName);
|
|
867
|
+
}
|
|
868
|
+
}).add({
|
|
869
|
+
serviceId: "vault",
|
|
870
|
+
clientName: "vault",
|
|
871
|
+
clientFn: (serviceBaseUrl) => createVaultClient({
|
|
872
|
+
baseUrl: serviceBaseUrl,
|
|
873
|
+
middlewares: middlewareFor("vault", [attachTokenMiddleware]),
|
|
874
|
+
auth
|
|
875
|
+
})
|
|
876
|
+
}).add({
|
|
877
|
+
serviceId: "data-science",
|
|
878
|
+
clientName: "dataScience",
|
|
879
|
+
clientFn: (serviceBaseUrl) => createDataScienceClient({
|
|
880
|
+
baseUrl: serviceBaseUrl,
|
|
881
|
+
middlewares: middlewareFor("dataScience", [attachTokenMiddleware]),
|
|
882
|
+
auth
|
|
883
|
+
})
|
|
884
|
+
}).add({
|
|
885
|
+
serviceId: "data-science",
|
|
886
|
+
clientName: "apps",
|
|
887
|
+
clientFn: (serviceBaseUrl) => createAppsClient({
|
|
888
|
+
baseUrl: withPath(serviceBaseUrl, "/v2"),
|
|
889
|
+
middlewares: middlewareFor("apps", [attachTokenMiddleware]),
|
|
890
|
+
auth
|
|
891
|
+
})
|
|
892
|
+
}).add({
|
|
893
|
+
serviceId: "encryption",
|
|
894
|
+
clientName: "encryption",
|
|
895
|
+
clientFn: (serviceBaseUrl) => createEncryptionClient({
|
|
896
|
+
baseUrl: serviceBaseUrl,
|
|
897
|
+
middlewares: middlewareFor("encryption")
|
|
898
|
+
})
|
|
899
|
+
}).add({
|
|
900
|
+
serviceId: "editor",
|
|
901
|
+
clientName: "editor",
|
|
902
|
+
clientFn: (serviceBaseUrl) => createEditorClient({
|
|
903
|
+
baseUrl: serviceBaseUrl,
|
|
904
|
+
middlewares: middlewareFor("editor", [attachTokenMiddleware]),
|
|
905
|
+
auth
|
|
906
|
+
})
|
|
907
|
+
}).add({
|
|
908
|
+
serviceId: "sync-actions",
|
|
909
|
+
clientName: "syncActions",
|
|
910
|
+
clientFn: (serviceBaseUrl) => createSyncActionsClient({
|
|
911
|
+
baseUrl: serviceBaseUrl,
|
|
912
|
+
middlewares: middlewareFor("syncActions", [attachTokenMiddleware]),
|
|
913
|
+
auth
|
|
914
|
+
})
|
|
915
|
+
}).add({
|
|
916
|
+
serviceId: "telemetry",
|
|
917
|
+
clientName: "telemetry",
|
|
918
|
+
clientFn: (serviceBaseUrl) => createTelemetryClient({
|
|
919
|
+
baseUrl: serviceBaseUrl,
|
|
920
|
+
middlewares: middlewareFor("telemetry", [attachTokenMiddleware]),
|
|
921
|
+
auth
|
|
922
|
+
})
|
|
923
|
+
}).add({
|
|
924
|
+
serviceId: "query",
|
|
925
|
+
clientName: "queryService",
|
|
926
|
+
clientFn: (serviceBaseUrl) => createQueryServiceClient({
|
|
927
|
+
baseUrl: serviceBaseUrl,
|
|
928
|
+
middlewares: middlewareFor("queryService", [attachTokenMiddleware]),
|
|
929
|
+
auth
|
|
930
|
+
})
|
|
931
|
+
}).add({
|
|
932
|
+
serviceId: "queue",
|
|
933
|
+
clientName: "queue",
|
|
934
|
+
clientFn: (serviceBaseUrl) => createQueueClient({
|
|
935
|
+
baseUrl: serviceBaseUrl,
|
|
936
|
+
middlewares: middlewareFor("queue", [attachTokenMiddleware]),
|
|
937
|
+
auth
|
|
938
|
+
})
|
|
939
|
+
}).add({
|
|
940
|
+
serviceId: "kai-assistant",
|
|
941
|
+
clientName: "chat",
|
|
942
|
+
clientFn: (serviceBaseUrl) => createChatClient({
|
|
943
|
+
storageApiUrl: baseUrl,
|
|
944
|
+
baseUrl: serviceBaseUrl,
|
|
945
|
+
middlewares: middlewareFor("chat", [attachTokenMiddleware]),
|
|
946
|
+
auth
|
|
947
|
+
})
|
|
948
|
+
}).add({
|
|
949
|
+
serviceId: "ai",
|
|
950
|
+
clientName: "ai",
|
|
951
|
+
clientFn: (serviceBaseUrl) => createAiClient({
|
|
952
|
+
baseUrl: serviceBaseUrl,
|
|
953
|
+
middlewares: middlewareFor("ai", [attachTokenMiddleware]),
|
|
954
|
+
auth
|
|
955
|
+
})
|
|
956
|
+
}).add({
|
|
957
|
+
serviceId: "ai",
|
|
958
|
+
clientName: "omnisearch",
|
|
959
|
+
clientFn: (serviceBaseUrl) => createOmnisearchClient({
|
|
960
|
+
baseUrl: withPath(serviceBaseUrl, "/omnisearch"),
|
|
961
|
+
middlewares: middlewareFor("omnisearch", [attachTokenMiddleware]),
|
|
962
|
+
auth
|
|
963
|
+
})
|
|
964
|
+
}).add({
|
|
965
|
+
serviceId: "import",
|
|
966
|
+
clientName: "import",
|
|
967
|
+
clientFn: (serviceBaseUrl) => createImportClient({
|
|
968
|
+
baseUrl: serviceBaseUrl,
|
|
969
|
+
middlewares: middlewareFor("import", [attachTokenMiddleware]),
|
|
970
|
+
auth
|
|
971
|
+
})
|
|
972
|
+
}).add({
|
|
973
|
+
serviceId: "kai-agent",
|
|
974
|
+
clientName: "kaiAgent",
|
|
975
|
+
clientFn: (serviceBaseUrl) => createKaiAgentClient({
|
|
976
|
+
baseUrl: serviceBaseUrl,
|
|
977
|
+
middlewares: middlewareFor("kaiAgent", [attachTokenMiddleware]),
|
|
978
|
+
auth
|
|
979
|
+
})
|
|
980
|
+
}).add({
|
|
981
|
+
serviceId: "components-mcp",
|
|
982
|
+
clientName: "componentsMcp",
|
|
983
|
+
clientFn: (serviceBaseUrl) => createComponentsMcpClient({
|
|
984
|
+
baseUrl: serviceBaseUrl,
|
|
985
|
+
middlewares: middlewareFor("componentsMcp", [attachTokenMiddleware]),
|
|
986
|
+
auth
|
|
987
|
+
})
|
|
988
|
+
}).add({
|
|
989
|
+
serviceId: "oauth",
|
|
990
|
+
clientName: "oauth",
|
|
991
|
+
clientFn: (serviceBaseUrl) => createOauthClient({
|
|
992
|
+
baseUrl: serviceBaseUrl,
|
|
993
|
+
middlewares: middlewareFor("oauth", [attachTokenMiddleware]),
|
|
994
|
+
auth
|
|
995
|
+
})
|
|
996
|
+
}).add({
|
|
997
|
+
serviceId: "scheduler",
|
|
998
|
+
clientName: "scheduler",
|
|
999
|
+
clientFn: (serviceBaseUrl) => createSchedulerClient({
|
|
1000
|
+
baseUrl: serviceBaseUrl,
|
|
1001
|
+
middlewares: middlewareFor("scheduler", [attachTokenMiddleware]),
|
|
1002
|
+
auth
|
|
1003
|
+
})
|
|
1004
|
+
}).add({
|
|
1005
|
+
serviceId: "stream",
|
|
1006
|
+
clientName: "stream",
|
|
1007
|
+
clientFn: (serviceBaseUrl) => createStreamClient({
|
|
1008
|
+
baseUrl: serviceBaseUrl,
|
|
1009
|
+
middlewares: middlewareFor("stream", [attachTokenMiddleware]),
|
|
1010
|
+
auth
|
|
1011
|
+
})
|
|
1012
|
+
}).add({
|
|
1013
|
+
serviceId: "notification",
|
|
1014
|
+
clientName: "notifications",
|
|
1015
|
+
clientFn: (serviceBaseUrl) => createNotificationsClient({
|
|
1016
|
+
baseUrl: serviceBaseUrl,
|
|
1017
|
+
middlewares: middlewareFor("notifications", [attachTokenMiddleware]),
|
|
1018
|
+
auth
|
|
1019
|
+
})
|
|
1020
|
+
}).add({
|
|
1021
|
+
serviceId: "billing",
|
|
1022
|
+
clientName: "billing",
|
|
1023
|
+
clientFn: (serviceBaseUrl) => createBillingClient({
|
|
1024
|
+
baseUrl: serviceBaseUrl,
|
|
1025
|
+
middlewares: middlewareFor("billing", [attachTokenMiddleware]),
|
|
1026
|
+
auth
|
|
1027
|
+
})
|
|
1028
|
+
}).add({
|
|
1029
|
+
serviceId: "metastore",
|
|
1030
|
+
clientName: "metastore",
|
|
1031
|
+
clientFn: (serviceBaseUrl) => createMetastoreClient({
|
|
1032
|
+
baseUrl: serviceBaseUrl,
|
|
1033
|
+
middlewares: middlewareFor("metastore", [attachTokenMiddleware]),
|
|
1034
|
+
auth
|
|
1035
|
+
})
|
|
1036
|
+
}).build();
|
|
1037
|
+
// src/keboola/perProject.ts
|
|
1345
1038
|
const projectKey = ({ baseUrl, projectId }) => `${baseUrl}#${projectId}`;
|
|
1346
1039
|
/**
|
|
1347
1040
|
* One handle per project, and the one call that drops it.
|
|
@@ -1376,12 +1069,12 @@ const createPerProject = ({ state, credentials, middlewareFor, stack }) => {
|
|
|
1376
1069
|
auth: authFor(project),
|
|
1377
1070
|
middlewares: middlewareFor("storage", [attach])
|
|
1378
1071
|
});
|
|
1379
|
-
const { client
|
|
1072
|
+
const { client } = createServiceClients({
|
|
1380
1073
|
baseUrl: project.baseUrl,
|
|
1381
1074
|
auth: authFor(project),
|
|
1382
1075
|
getServiceBaseUrl: (serviceId) => async () => {
|
|
1383
1076
|
const serviceUrl = (await stack.context.getAsync(project.baseUrl)).getServiceUrl(serviceId);
|
|
1384
|
-
|
|
1077
|
+
if (!serviceUrl) throw new ServiceUnavailableError(serviceId);
|
|
1385
1078
|
return serviceUrl;
|
|
1386
1079
|
},
|
|
1387
1080
|
middlewareFor,
|
|
@@ -1400,7 +1093,6 @@ const createPerProject = ({ state, credentials, middlewareFor, stack }) => {
|
|
|
1400
1093
|
if (property === "stack" || property === "auth" || property === "management") return stack.get(project.baseUrl)[property];
|
|
1401
1094
|
if (property === "storage") return storage;
|
|
1402
1095
|
if (property === "sdk") return sdk;
|
|
1403
|
-
if (property === "serviceMeta") return meta;
|
|
1404
1096
|
return client[property];
|
|
1405
1097
|
} }),
|
|
1406
1098
|
end: () => {
|
|
@@ -1422,13 +1114,13 @@ const createPerProject = ({ state, credentials, middlewareFor, stack }) => {
|
|
|
1422
1114
|
forgetUnder
|
|
1423
1115
|
};
|
|
1424
1116
|
};
|
|
1425
|
-
// src/keboola/
|
|
1117
|
+
// src/keboola/persistor.ts
|
|
1426
1118
|
/**
|
|
1427
1119
|
* Where a bearer session is persisted, under whichever adapter the client was given.
|
|
1428
1120
|
*
|
|
1429
1121
|
* Exported because a consumer sometimes has to drop a session a client cannot reach: the adapter is
|
|
1430
1122
|
* chosen at construction, so a client built without one holds no handle to the storage its own
|
|
1431
|
-
* session is sitting in.
|
|
1123
|
+
* session is sitting in.
|
|
1432
1124
|
*/
|
|
1433
1125
|
const SESSION_STORAGE_KEY = "keboola:session";
|
|
1434
1126
|
/**
|
|
@@ -1555,7 +1247,44 @@ const createSessionPersistor = (storage) => {
|
|
|
1555
1247
|
snapshot
|
|
1556
1248
|
};
|
|
1557
1249
|
};
|
|
1558
|
-
// src/
|
|
1250
|
+
// src/domain/stack.ts
|
|
1251
|
+
const isServiceId = (id) => Object.values(ServiceId).includes(id);
|
|
1252
|
+
const SERVICE_URL_OVERRIDES = { "kai-assistant": (url) => `${url}/api` };
|
|
1253
|
+
const createStack = ({ stackInfo, clientServiceUrls }) => {
|
|
1254
|
+
const { services, components, features, ...infoRest } = stackInfo;
|
|
1255
|
+
const serviceMap = new Map(services.map((service) => {
|
|
1256
|
+
if (!isServiceId(service.id)) return [service.id, service.url];
|
|
1257
|
+
const devOverride = clientServiceUrls?.[service.id]?.(service.url);
|
|
1258
|
+
const prodOverride = SERVICE_URL_OVERRIDES[service.id]?.(service.url);
|
|
1259
|
+
const url = devOverride ?? prodOverride ?? service.url;
|
|
1260
|
+
return [service.id, url];
|
|
1261
|
+
}));
|
|
1262
|
+
const componentMap = new Map(components.map((component) => [component.id, component]));
|
|
1263
|
+
const featureSet = new Set(features);
|
|
1264
|
+
const hasFeature = (...feature) => {
|
|
1265
|
+
if (feature.length === 0) return false;
|
|
1266
|
+
return feature.every((x) => featureSet.has(x));
|
|
1267
|
+
};
|
|
1268
|
+
const hasComponent = (...componentId) => {
|
|
1269
|
+
if (componentId.length === 0) return false;
|
|
1270
|
+
return componentId.every((x) => componentMap.has(x));
|
|
1271
|
+
};
|
|
1272
|
+
const getComponent = (componentId) => componentMap.get(componentId) ?? null;
|
|
1273
|
+
const hasService = (serviceId) => serviceMap.has(serviceId);
|
|
1274
|
+
const getServiceUrl = (serviceId) => serviceMap.get(serviceId) ?? null;
|
|
1275
|
+
return {
|
|
1276
|
+
...infoRest,
|
|
1277
|
+
services,
|
|
1278
|
+
features,
|
|
1279
|
+
components,
|
|
1280
|
+
hasFeature,
|
|
1281
|
+
getServiceUrl,
|
|
1282
|
+
hasService,
|
|
1283
|
+
getComponent,
|
|
1284
|
+
hasComponent
|
|
1285
|
+
};
|
|
1286
|
+
};
|
|
1287
|
+
// src/keboola/context.ts
|
|
1559
1288
|
const STACK_INDEX_TIMEOUT_MS = 3e4;
|
|
1560
1289
|
/**
|
|
1561
1290
|
* One parsed stack index per stack; `createStack` applies the dev and production overrides.
|
|
@@ -1621,7 +1350,7 @@ const createStackContext = ({ state, clientServiceUrls }) => {
|
|
|
1621
1350
|
getAsync
|
|
1622
1351
|
};
|
|
1623
1352
|
};
|
|
1624
|
-
// src/keboola/
|
|
1353
|
+
// src/keboola/perStack.ts
|
|
1625
1354
|
/**
|
|
1626
1355
|
* Everything one stack derives.
|
|
1627
1356
|
*
|
|
@@ -1659,7 +1388,7 @@ const createPerStack = ({ state, credentials, middlewareFor, clientServiceUrls }
|
|
|
1659
1388
|
get
|
|
1660
1389
|
};
|
|
1661
1390
|
};
|
|
1662
|
-
// src/keboola/
|
|
1391
|
+
// src/keboola/keboola.ts
|
|
1663
1392
|
/**
|
|
1664
1393
|
* The bearer client: the session table, its two scopes, and the surface they back.
|
|
1665
1394
|
*
|
|
@@ -1747,20 +1476,39 @@ const createKeboola = ({ defaultBaseUrl, storage, middlewares, clientServiceUrls
|
|
|
1747
1476
|
return active().management;
|
|
1748
1477
|
}
|
|
1749
1478
|
};
|
|
1750
|
-
const
|
|
1751
|
-
const getProjectApi = (projectId) => perProject.get(onActiveStack(projectId));
|
|
1479
|
+
const projectApi = (projectId) => perProject.get(onActiveStack(projectId));
|
|
1752
1480
|
/**
|
|
1753
1481
|
* The scope's sign-in, or a named stack's — and everything that sign-in derived.
|
|
1754
1482
|
*
|
|
1483
|
+
* - Ends the server session too (`credentials.endSession`).
|
|
1755
1484
|
* - `retain` keeps the grant on the stack, persisted beside the sign-in it ended, for
|
|
1756
|
-
* `restoreRetained
|
|
1757
|
-
* - The table is signed out on return; the promise resolves once that is stored
|
|
1758
|
-
* leaving the document waits for
|
|
1485
|
+
* `restoreRetained`, and so leaves the server session live; the next sign-in replaces it.
|
|
1486
|
+
* - The table is signed out on return; the promise resolves once that is stored and the
|
|
1487
|
+
* session's end was attempted, so a caller leaving the document waits for both.
|
|
1759
1488
|
*/
|
|
1760
|
-
const signOut = ({ baseUrl, ...options } = {}) =>
|
|
1761
|
-
|
|
1489
|
+
const signOut = ({ baseUrl, ...options } = {}) => endSignIn(requireStackUrl(baseUrl), options, !options.retain);
|
|
1490
|
+
const endingSessions = /* @__PURE__ */ new Map();
|
|
1491
|
+
/** `signOut`; `endSession: false` leaves the server session alone. */
|
|
1492
|
+
const endSignIn = (target, options, endSession) => {
|
|
1493
|
+
const held = endSession ? Result.unwrapOr(state.auth.requireCredential(target), null) : null;
|
|
1762
1494
|
const signedOut = Result.unwrap(credentials.signOut(target, options));
|
|
1763
|
-
|
|
1495
|
+
let newest = held && grantOf(held);
|
|
1496
|
+
const ended = persistor.locked(async (store) => {
|
|
1497
|
+
if (held !== null) newest = (await store.read()).stacks.find((stack) => stack.baseUrl === target)?.credential ?? newest;
|
|
1498
|
+
await store.persistStack(target, state.store.get());
|
|
1499
|
+
}).then(() => newest ? credentials.endSession(target, newest) : void 0, async (error) => {
|
|
1500
|
+
if (newest) await credentials.endSession(target, newest);
|
|
1501
|
+
throw error;
|
|
1502
|
+
});
|
|
1503
|
+
const earlier = endingSessions.get(target);
|
|
1504
|
+
if (held !== null) {
|
|
1505
|
+
endingSessions.set(target, ended);
|
|
1506
|
+
const forget = () => {
|
|
1507
|
+
if (endingSessions.get(target) === ended) endingSessions.delete(target);
|
|
1508
|
+
};
|
|
1509
|
+
ended.then(forget, forget);
|
|
1510
|
+
}
|
|
1511
|
+
return Promise.all([ended, earlier]).then(() => signedOut);
|
|
1764
1512
|
};
|
|
1765
1513
|
/** Signs a stack back in from what a retained sign-out kept; `unreachable` leaves it to retry. */
|
|
1766
1514
|
const restoreRetained = (baseUrl) => credentials.restoreRetained(normalizeBaseUrl(baseUrl));
|
|
@@ -1769,9 +1517,12 @@ const createKeboola = ({ defaultBaseUrl, storage, middlewares, clientServiceUrls
|
|
|
1769
1517
|
*
|
|
1770
1518
|
* - Signs out first, always: a sign-out moves the epoch even on an anonymous stack, so a stored
|
|
1771
1519
|
* session still being restored cannot land on top of this one.
|
|
1520
|
+
* - Locally only: the replaced sign-in can share a browser session with `input`.
|
|
1772
1521
|
*/
|
|
1773
1522
|
const replace = (input) => {
|
|
1774
|
-
|
|
1523
|
+
endSignIn(requireStackUrl(), {}, false).catch((error) => {
|
|
1524
|
+
console.warn("createKeboola: the replaced sign-in could not be stored", error);
|
|
1525
|
+
});
|
|
1775
1526
|
return authenticate(input);
|
|
1776
1527
|
};
|
|
1777
1528
|
let persisting = false;
|
|
@@ -1837,8 +1588,8 @@ const createKeboola = ({ defaultBaseUrl, storage, middlewares, clientServiceUrls
|
|
|
1837
1588
|
return verb(...args);
|
|
1838
1589
|
};
|
|
1839
1590
|
return {
|
|
1840
|
-
|
|
1841
|
-
|
|
1591
|
+
stackApi,
|
|
1592
|
+
projectApi,
|
|
1842
1593
|
session: {
|
|
1843
1594
|
getState: state.store.get,
|
|
1844
1595
|
subscribe: state.store.subscribe,
|
|
@@ -2061,6 +1812,6 @@ const createBranchRefs = ({ devBranches }) => {
|
|
|
2061
1812
|
resolve: (ref) => getType(ref) === "default" ? defaultBranch.id : Number(ref)
|
|
2062
1813
|
};
|
|
2063
1814
|
};
|
|
2064
|
-
export { ApiError, HtmlResponseError, HttpContentType, HttpHeader, KeboolaError, KeboolaErrorType, KeboolaHttpHeader, ManagementClientAuthError, ManagementSessionMintError, QueryJobError, QueueJobError, Result, RowLevelSecurityError, SESSION_STORAGE_KEY, ServiceUnavailableError, StorageJobError, SyncActionError, UserError, ValidationError, asError, assert, coalesce, collectByCursor, collectByOffset, concurrent, createAdminAccount, createBranchRefs,
|
|
1815
|
+
export { ApiError, HtmlResponseError, HttpContentType, HttpHeader, KeboolaError, KeboolaErrorType, KeboolaHttpHeader, ManagementClientAuthError, ManagementSessionMintError, QueryJobError, QueueJobError, Result, RowLevelSecurityError, SESSION_STORAGE_KEY, ServiceUnavailableError, StorageJobError, SyncActionError, UserError, ValidationError, asError, assert, coalesce, collectByCursor, collectByOffset, concurrent, createAdminAccount, createBranchRefs, createEmitter, createGenericFetchClient, createKeboola, createLocalStorage, createLoggingMiddleware, createMemoryStorage, createNullStorage, createPersistor, createPollRegistry, createProject, createQueryServiceSdk, createRetryMiddleware, createSessionStorage, createStore, createUiVersionMiddleware, dedupe, deepMerge, delay, emitter, ensure, failureOf, formatValidationIssues, generateUUID, isAbortError, isApiError, isEmptyDeep, isFetchClientError, isHtmlResponseError, isKeboolaError, isManageError, isManagementClientAuthError, isManagementSessionMintError, isPlainObject, isQueryJobError, isQueueJobError, isRowLevelSecurityError, isStorageJobError, isSyncActionError, isTimeoutError, isValidationError, iterateByCursor, jobStatus, keboolaUID, lazy, manageErrorCode, nextCursorOf, parseLogLines, parseOrThrow, poller, queueSeries, readableReason, retryAfterSeconds, schemaGuidedMerge, series };
|
|
2065
1816
|
|
|
2066
1817
|
//# sourceMappingURL=index.js.map
|