@keboola/api-client 25.0.0 → 29.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 +623 -0
- package/API-SURFACE.md +133 -57
- package/README.md +81 -42
- package/dist/ManagementClientAuthError-B97OtOQ7.js +15 -0
- package/dist/ManagementClientAuthError-B97OtOQ7.js.map +1 -0
- package/dist/ManagementClientAuthError-ZJ2-RoKT.cjs +20 -0
- package/dist/ManagementClientAuthError-ZJ2-RoKT.cjs.map +1 -0
- package/dist/QueryJobTimeoutError-C7JbNGOM.js +38 -0
- package/dist/QueryJobTimeoutError-C7JbNGOM.js.map +1 -0
- package/dist/QueryJobTimeoutError-CVNPdCWX.cjs +61 -0
- package/dist/QueryJobTimeoutError-CVNPdCWX.cjs.map +1 -0
- package/dist/SyncActionError-BG0zwchi.cjs +35 -0
- package/dist/SyncActionError-BG0zwchi.cjs.map +1 -0
- package/dist/SyncActionError-CoZFsdUk.js +24 -0
- package/dist/SyncActionError-CoZFsdUk.js.map +1 -0
- package/dist/UserError-By_Zckmc.js +10 -0
- package/dist/UserError-By_Zckmc.js.map +1 -0
- package/dist/UserError-CSGO1qII.cjs +15 -0
- package/dist/UserError-CSGO1qII.cjs.map +1 -0
- package/dist/ValidationError-CzPWydEb.js +44 -0
- package/dist/ValidationError-CzPWydEb.js.map +1 -0
- package/dist/ValidationError-h5qvwahi.cjs +61 -0
- package/dist/ValidationError-h5qvwahi.cjs.map +1 -0
- package/dist/adminRoles-B40yBcmq.js +14 -0
- package/dist/adminRoles-B40yBcmq.js.map +1 -0
- package/dist/adminRoles-C696kD_U.d.cts +14 -0
- package/dist/adminRoles-C696kD_U.d.ts +14 -0
- package/dist/adminRoles-CO7J5qAy.cjs +19 -0
- package/dist/adminRoles-CO7J5qAy.cjs.map +1 -0
- package/dist/ai/index.cjs +62 -12
- package/dist/ai/index.cjs.map +1 -1
- package/dist/ai/index.d.cts +52 -50
- package/dist/ai/index.d.ts +52 -50
- package/dist/ai/index.js +62 -4
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/types.cjs +0 -4
- package/dist/ai/types.d.cts +2 -2
- package/dist/ai/types.d.ts +2 -2
- package/dist/ai/types.js +1 -3
- package/dist/appLogs-CNG3yby-.cjs +153 -0
- package/dist/appLogs-CNG3yby-.cjs.map +1 -0
- package/dist/appLogs-Dl5BcCSD.d.cts +10 -0
- package/dist/appLogs-VdgP08aX.d.ts +10 -0
- package/dist/appLogs-enL9XR9r.js +132 -0
- package/dist/appLogs-enL9XR9r.js.map +1 -0
- package/dist/apps/index.cjs +231 -0
- package/dist/apps/index.cjs.map +1 -0
- package/dist/apps/index.d.cts +248 -0
- package/dist/apps/index.d.ts +248 -0
- package/dist/apps/index.js +230 -0
- package/dist/apps/index.js.map +1 -0
- package/dist/apps/types.cjs +0 -0
- package/dist/apps/types.d.cts +3 -0
- package/dist/apps/types.d.ts +3 -0
- package/dist/apps/types.js +1 -0
- package/dist/assets/index.cjs +33 -38
- package/dist/assets/index.cjs.map +1 -1
- package/dist/assets/index.d.cts +22 -22
- package/dist/assets/index.d.ts +22 -22
- package/dist/assets/index.js +32 -36
- package/dist/assets/index.js.map +1 -1
- package/dist/assets/schema.cjs +23 -13
- package/dist/assets/schema.cjs.map +1 -1
- package/dist/assets/schema.d.cts +29 -28
- package/dist/assets/schema.d.ts +29 -28
- package/dist/assets/schema.js +21 -2
- package/dist/assets/schema.js.map +1 -1
- package/dist/auth/index.cjs +14 -53
- package/dist/auth/index.d.cts +2 -305
- package/dist/auth/index.d.ts +2 -305
- package/dist/auth/index.js +2 -4
- package/dist/auth/types.cjs +0 -4
- package/dist/auth/types.d.cts +2 -7
- package/dist/auth/types.d.ts +2 -7
- package/dist/auth/types.js +1 -3
- package/dist/auth-5HCvCsZO.cjs +18 -0
- package/dist/auth-5HCvCsZO.cjs.map +1 -0
- package/dist/auth-D2jfNlpX.js +13 -0
- package/dist/{chunk-EDX5D6UY.js.map → auth-D2jfNlpX.js.map} +1 -1
- package/dist/authClient-Bgj2Ay7h.d.cts +320 -0
- package/dist/authClient-DOk6VKdV.js +332 -0
- package/dist/authClient-DOk6VKdV.js.map +1 -0
- package/dist/authClient-Dsd7W99W.d.ts +320 -0
- package/dist/authClient-Z8Eg8rlN.cjs +405 -0
- package/dist/authClient-Z8Eg8rlN.cjs.map +1 -0
- package/dist/backends-DKBz5OxE.d.cts +9 -0
- package/dist/backends-DKBz5OxE.d.ts +9 -0
- package/dist/chat/index.cjs +134 -13
- package/dist/chat/index.cjs.map +1 -1
- package/dist/chat/index.d.cts +49 -48
- package/dist/chat/index.d.ts +49 -48
- package/dist/chat/index.js +134 -5
- package/dist/chat/index.js.map +1 -1
- package/dist/chat/suggestions.cjs +152 -74
- package/dist/chat/suggestions.cjs.map +1 -1
- package/dist/chat/suggestions.d.cts +2 -437
- package/dist/chat/suggestions.d.ts +2 -437
- package/dist/chat/suggestions.js +136 -2
- package/dist/chat/suggestions.js.map +1 -1
- package/dist/chat/types.cjs +6 -8
- package/dist/chat/types.cjs.map +1 -1
- package/dist/chat/types.d.cts +2 -3
- package/dist/chat/types.d.ts +2 -3
- package/dist/chat/types.js +5 -6
- package/dist/chat/types.js.map +1 -1
- package/dist/componentId-DkyQ8PM0.cjs +73 -0
- package/dist/componentId-DkyQ8PM0.cjs.map +1 -0
- package/dist/componentId-vJz-kWs6.js +68 -0
- package/dist/componentId-vJz-kWs6.js.map +1 -0
- package/dist/concurrent-CH9fbNr3.js +34 -0
- package/dist/concurrent-CH9fbNr3.js.map +1 -0
- package/dist/concurrent-tbiIa0UL.cjs +39 -0
- package/dist/concurrent-tbiIa0UL.cjs.map +1 -0
- package/dist/configurations-Byt59bIa.js +726 -0
- package/dist/{chunk-IAYPOSMM.cjs.map → configurations-Byt59bIa.js.map} +1 -1
- package/dist/configurations-CujCwDcB.cjs +743 -0
- package/dist/configurations-CujCwDcB.cjs.map +1 -0
- package/dist/configurations-DCOJONZZ.cjs +313 -0
- package/dist/configurations-DCOJONZZ.cjs.map +1 -0
- package/dist/configurations-iCbhe0tb.js +158 -0
- package/dist/configurations-iCbhe0tb.js.map +1 -0
- package/dist/constants/index.cjs +10 -34
- package/dist/constants/index.d.cts +4 -92
- package/dist/constants/index.d.ts +4 -92
- package/dist/constants/index.js +4 -5
- package/dist/constants-CqyyBkXW.cjs +197 -0
- package/dist/constants-CqyyBkXW.cjs.map +1 -0
- package/dist/constants-_HhqKvBg.js +174 -0
- package/dist/constants-_HhqKvBg.js.map +1 -0
- package/dist/createFetchClient-BK0TZK-U.js +184 -0
- package/dist/createFetchClient-BK0TZK-U.js.map +1 -0
- package/dist/createFetchClient-BsG719K1.cjs +263 -0
- package/dist/createFetchClient-BsG719K1.cjs.map +1 -0
- package/dist/createGenericFetchClient-CVZYekDk.js +7 -0
- package/dist/createGenericFetchClient-CVZYekDk.js.map +1 -0
- package/dist/createGenericFetchClient-DLbjX0eM.cjs +12 -0
- package/dist/createGenericFetchClient-DLbjX0eM.cjs.map +1 -0
- package/dist/createOpenapiFetchClient-B5U1fCHS.js +7 -0
- package/dist/createOpenapiFetchClient-B5U1fCHS.js.map +1 -0
- package/dist/createOpenapiFetchClient-Cr90VXY4.cjs +12 -0
- package/dist/createOpenapiFetchClient-Cr90VXY4.cjs.map +1 -0
- package/dist/createStore-BNiCRQXa.js +148 -0
- package/dist/createStore-BNiCRQXa.js.map +1 -0
- package/dist/createStore-MQbboXcB.cjs +177 -0
- package/dist/createStore-MQbboXcB.cjs.map +1 -0
- package/dist/credential-0c6yFwtp.cjs +44 -0
- package/dist/credential-0c6yFwtp.cjs.map +1 -0
- package/dist/credential-kEGLnVez.js +33 -0
- package/dist/credential-kEGLnVez.js.map +1 -0
- package/dist/dataScience/index.cjs +5 -19
- package/dist/dataScience/index.d.cts +3 -207
- package/dist/dataScience/index.d.ts +3 -207
- package/dist/dataScience/index.js +3 -6
- package/dist/dataScience/types.cjs +0 -4
- package/dist/dataScience/types.d.cts +3 -2
- package/dist/dataScience/types.d.ts +3 -2
- package/dist/dataScience/types.js +1 -3
- package/dist/dataScience-C-JrA0Uk.cjs +114 -0
- package/dist/dataScience-C-JrA0Uk.cjs.map +1 -0
- package/dist/dataScience-CE0pSWbl.js +109 -0
- package/dist/dataScience-CE0pSWbl.js.map +1 -0
- package/dist/dedupe-CiskLkGR.cjs +30 -0
- package/dist/dedupe-CiskLkGR.cjs.map +1 -0
- package/dist/dedupe-DYIHgZoG.js +25 -0
- package/dist/dedupe-DYIHgZoG.js.map +1 -0
- package/dist/developerPortal/index.cjs +6 -0
- package/dist/developerPortal/index.d.cts +3 -0
- package/dist/developerPortal/index.d.ts +3 -0
- package/dist/developerPortal/index.js +2 -0
- package/dist/developerPortal/types.cjs +0 -0
- package/dist/developerPortal/types.d.cts +2 -0
- package/dist/developerPortal/types.d.ts +2 -0
- package/dist/developerPortal/types.js +1 -0
- package/dist/developerPortalClient-BPPEAdJW.js +485 -0
- package/dist/developerPortalClient-BPPEAdJW.js.map +1 -0
- package/dist/developerPortalClient-C8oq48xW.cjs +508 -0
- package/dist/developerPortalClient-C8oq48xW.cjs.map +1 -0
- package/dist/domain/permissions/index.cjs +31 -122
- package/dist/domain/permissions/index.d.cts +19 -51
- package/dist/domain/permissions/index.d.ts +19 -51
- package/dist/domain/permissions/index.js +3 -5
- package/dist/domain/storageTable/index.cjs +4 -16
- package/dist/domain/storageTable/index.d.cts +2 -131
- package/dist/domain/storageTable/index.d.ts +2 -131
- package/dist/domain/storageTable/index.js +2 -3
- package/dist/editor/index.cjs +96 -12
- package/dist/editor/index.cjs.map +1 -1
- package/dist/editor/index.d.cts +163 -161
- package/dist/editor/index.d.ts +163 -161
- package/dist/editor/index.js +96 -4
- package/dist/editor/index.js.map +1 -1
- package/dist/editor/types.cjs +0 -4
- package/dist/editor/types.d.cts +2 -2
- package/dist/editor/types.d.ts +2 -2
- package/dist/editor/types.js +1 -3
- package/dist/encryption/index.cjs +58 -11
- package/dist/encryption/index.cjs.map +1 -1
- package/dist/encryption/index.d.cts +2 -18
- package/dist/encryption/index.d.ts +2 -18
- package/dist/encryption/index.js +58 -3
- package/dist/encryption/index.js.map +1 -1
- package/dist/encryption/types.cjs +0 -4
- package/dist/encryption/types.d.cts +2 -68
- package/dist/encryption/types.d.ts +2 -68
- package/dist/encryption/types.js +1 -3
- package/dist/generateUUID-C6qKBPIv.cjs +11 -0
- package/dist/generateUUID-C6qKBPIv.cjs.map +1 -0
- package/dist/generateUUID-Dr8l-aoc.js +6 -0
- package/dist/generateUUID-Dr8l-aoc.js.map +1 -0
- package/dist/import/index.cjs +3 -14
- package/dist/import/index.d.cts +41 -38
- package/dist/import/index.d.ts +41 -38
- package/dist/import/index.js +2 -5
- package/dist/import-Cf0W-7YD.js +116 -0
- package/dist/import-Cf0W-7YD.js.map +1 -0
- package/dist/import-KLH1uRtx.cjs +121 -0
- package/dist/import-KLH1uRtx.cjs.map +1 -0
- package/dist/index-8pN6Emos.d.ts +218 -0
- package/dist/index-BEKaJ7Cc.d.cts +1388 -0
- package/dist/index-BMqLPS6S.d.cts +135 -0
- package/dist/index-BMqLPS6S.d.ts +135 -0
- package/dist/index-BWBScAYc.d.cts +16 -0
- package/dist/index-BmjeNd9u.d.ts +1075 -0
- package/dist/index-BthgbVdd.d.ts +31 -0
- package/dist/index-CLPrlyIz.d.cts +218 -0
- package/dist/index-CXQRvZ-f.d.cts +31 -0
- package/dist/index-CeistZnj.d.ts +1388 -0
- package/dist/index-Cfrl7sd5.d.ts +65 -0
- package/dist/index-DIM8KZly.d.ts +16 -0
- package/dist/index-DNlX-H1V.d.ts +208 -0
- package/dist/index-DVsnxZap.d.cts +65 -0
- package/dist/index-DXi6wsr5.d.cts +77 -0
- package/dist/index-DYQt4zxC.d.ts +77 -0
- package/dist/index-DplMbm9E.d.cts +19882 -0
- package/dist/index-Dwp8tF6O.d.ts +19882 -0
- package/dist/index-IN0qzs52.d.cts +208 -0
- package/dist/index-KKJkrxjx.d.ts +26 -0
- package/dist/index-NC1dXRTD.d.cts +40 -0
- package/dist/index-NC1dXRTD.d.ts +40 -0
- package/dist/index-WQkVzx5e.d.cts +1075 -0
- package/dist/index-eEBVG5s3.d.cts +26 -0
- package/dist/index-vb9Rfqca.d.cts +115 -0
- package/dist/index-vb9Rfqca.d.ts +115 -0
- package/dist/index.cjs +1728 -1802
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -15301
- package/dist/index.d.ts +7 -15301
- package/dist/index.js +1678 -1675
- package/dist/index.js.map +1 -1
- package/dist/isPlainObject-BB3iy87C.cjs +16 -0
- package/dist/isPlainObject-BB3iy87C.cjs.map +1 -0
- package/dist/isPlainObject-LYW-03uB.js +11 -0
- package/dist/isPlainObject-LYW-03uB.js.map +1 -0
- package/dist/jobStatus-DbMupQEK.js +423 -0
- package/dist/jobStatus-DbMupQEK.js.map +1 -0
- package/dist/jobStatus-kQ9JqF8t.cjs +494 -0
- package/dist/jobStatus-kQ9JqF8t.cjs.map +1 -0
- package/dist/management/index.cjs +4 -18
- package/dist/management/index.d.cts +2 -1083
- package/dist/management/index.d.ts +2 -1083
- package/dist/management/index.js +2 -5
- package/dist/management/types.cjs +0 -4
- package/dist/management/types.d.cts +2 -12
- package/dist/management/types.d.ts +2 -12
- package/dist/management/types.js +1 -3
- package/dist/management-DqwQcDCx.js +1065 -0
- package/dist/management-DqwQcDCx.js.map +1 -0
- package/dist/management-WOmlBt6H.cjs +1076 -0
- package/dist/management-WOmlBt6H.cjs.map +1 -0
- package/dist/metastore/index.cjs +3 -14
- package/dist/metastore/index.d.cts +2 -33
- package/dist/metastore/index.d.ts +2 -33
- package/dist/metastore/index.js +2 -5
- package/dist/metastore/types.cjs +0 -4
- package/dist/metastore/types.d.cts +2 -2
- package/dist/metastore/types.d.ts +2 -2
- package/dist/metastore/types.js +1 -3
- package/dist/metastore-CNEhL66f.js +134 -0
- package/dist/metastore-CNEhL66f.js.map +1 -0
- package/dist/metastore-CkQluyX1.cjs +139 -0
- package/dist/metastore-CkQluyX1.cjs.map +1 -0
- package/dist/notifications/index.cjs +67 -13
- package/dist/notifications/index.cjs.map +1 -1
- package/dist/notifications/index.d.cts +56 -56
- package/dist/notifications/index.d.ts +56 -56
- package/dist/notifications/index.js +67 -5
- package/dist/notifications/index.js.map +1 -1
- package/dist/notifications/types.cjs +0 -4
- package/dist/notifications/types.d.cts +2 -2
- package/dist/notifications/types.d.ts +2 -2
- package/dist/notifications/types.js +1 -3
- package/dist/oauth/index.cjs +3 -14
- package/dist/oauth/index.d.cts +49 -49
- package/dist/oauth/index.d.ts +49 -49
- package/dist/oauth/index.js +2 -5
- package/dist/oauth/types.cjs +0 -4
- package/dist/oauth/types.d.cts +2 -725
- package/dist/oauth/types.d.ts +2 -725
- package/dist/oauth/types.js +1 -3
- package/dist/oauth-DTvrqe6P.cjs +88 -0
- package/dist/oauth-DTvrqe6P.cjs.map +1 -0
- package/dist/oauth-DYDObUX9.js +83 -0
- package/dist/oauth-DYDObUX9.js.map +1 -0
- package/dist/omnisearch/index.cjs +49 -0
- package/dist/omnisearch/index.cjs.map +1 -0
- package/dist/omnisearch/index.d.cts +30 -0
- package/dist/omnisearch/index.d.ts +30 -0
- package/dist/omnisearch/index.js +48 -0
- package/dist/omnisearch/index.js.map +1 -0
- package/dist/omnisearch/types.cjs +0 -0
- package/dist/omnisearch/types.d.cts +2 -0
- package/dist/omnisearch/types.d.ts +2 -0
- package/dist/omnisearch/types.js +1 -0
- package/dist/project-BvFi19K_.cjs +56 -0
- package/dist/project-BvFi19K_.cjs.map +1 -0
- package/dist/project-CcGxXIW_.d.cts +18 -0
- package/dist/project-DWwZv66D.js +39 -0
- package/dist/project-DWwZv66D.js.map +1 -0
- package/dist/project-io1pY-hW.d.ts +18 -0
- package/dist/queryService/index.cjs +3 -14
- package/dist/queryService/index.d.cts +2 -39
- package/dist/queryService/index.d.ts +2 -39
- package/dist/queryService/index.js +2 -5
- package/dist/queryService/types.cjs +0 -4
- package/dist/queryService/types.d.cts +2 -2
- package/dist/queryService/types.d.ts +2 -2
- package/dist/queryService/types.js +1 -3
- package/dist/queryService-BHV_OZI2.js +114 -0
- package/dist/queryService-BHV_OZI2.js.map +1 -0
- package/dist/queryService-CvqDqigW.cjs +119 -0
- package/dist/queryService-CvqDqigW.cjs.map +1 -0
- package/dist/queue/index.cjs +3 -15
- package/dist/queue/index.d.cts +411 -334
- package/dist/queue/index.d.ts +411 -334
- package/dist/queue/index.js +2 -6
- package/dist/queue/types.cjs +0 -4
- package/dist/queue/types.d.cts +2 -2
- package/dist/queue/types.d.ts +2 -2
- package/dist/queue/types.js +1 -3
- package/dist/queue-CUHKupTA.cjs +137 -0
- package/dist/queue-CUHKupTA.cjs.map +1 -0
- package/dist/queue-uofE4Eu6.js +126 -0
- package/dist/queue-uofE4Eu6.js.map +1 -0
- package/dist/rolldown-runtime-VH7oDXx4.cjs +28 -0
- package/dist/scheduler/index.cjs +61 -13
- package/dist/scheduler/index.cjs.map +1 -1
- package/dist/scheduler/index.d.cts +73 -73
- package/dist/scheduler/index.d.ts +73 -73
- package/dist/scheduler/index.js +61 -5
- package/dist/scheduler/index.js.map +1 -1
- package/dist/scheduler/types.cjs +0 -4
- package/dist/scheduler/types.d.cts +2 -372
- package/dist/scheduler/types.d.ts +2 -372
- package/dist/scheduler/types.js +1 -3
- package/dist/sdk/configurations/index.cjs +3 -16
- package/dist/sdk/configurations/index.d.cts +3066 -3077
- package/dist/sdk/configurations/index.d.ts +3066 -3077
- package/dist/sdk/configurations/index.js +2 -7
- package/dist/sdk/developerPortal/index.cjs +203 -0
- package/dist/sdk/developerPortal/index.cjs.map +1 -0
- package/dist/sdk/developerPortal/index.d.cts +1371 -0
- package/dist/sdk/developerPortal/index.d.ts +1371 -0
- package/dist/sdk/developerPortal/index.js +202 -0
- package/dist/sdk/developerPortal/index.js.map +1 -0
- package/dist/sdk/queryService/index.cjs +93 -0
- package/dist/sdk/queryService/index.cjs.map +1 -0
- package/dist/sdk/queryService/index.d.cts +2 -0
- package/dist/sdk/queryService/index.d.ts +2 -0
- package/dist/sdk/queryService/index.js +92 -0
- package/dist/sdk/queryService/index.js.map +1 -0
- package/dist/sdk/semanticLayer/index.cjs +352 -50
- package/dist/sdk/semanticLayer/index.cjs.map +1 -1
- package/dist/sdk/semanticLayer/index.d.cts +105 -94
- package/dist/sdk/semanticLayer/index.d.ts +105 -94
- package/dist/sdk/semanticLayer/index.js +346 -4
- package/dist/sdk/semanticLayer/index.js.map +1 -1
- package/dist/sdk/semanticLayer/types.cjs +0 -4
- package/dist/sdk/semanticLayer/types.d.cts +2 -132
- package/dist/sdk/semanticLayer/types.d.ts +2 -132
- package/dist/sdk/semanticLayer/types.js +1 -3
- package/dist/sdk/storage/index.cjs +267 -47
- package/dist/sdk/storage/index.cjs.map +1 -1
- package/dist/sdk/storage/index.d.cts +2 -119
- package/dist/sdk/storage/index.d.ts +2 -119
- package/dist/sdk/storage/index.js +258 -3
- package/dist/sdk/storage/index.js.map +1 -1
- package/dist/sdk/tag/index.cjs +3 -14
- package/dist/sdk/tag/index.d.cts +16 -20
- package/dist/sdk/tag/index.d.ts +16 -20
- package/dist/sdk/tag/index.js +2 -5
- package/dist/sdk/tag/types.cjs +0 -4
- package/dist/sdk/tag/types.d.cts +2 -30
- package/dist/sdk/tag/types.d.ts +2 -30
- package/dist/sdk/tag/types.js +1 -3
- package/dist/sdk/vault/index.cjs +93 -31
- package/dist/sdk/vault/index.cjs.map +1 -1
- package/dist/sdk/vault/index.d.cts +2 -72
- package/dist/sdk/vault/index.d.ts +2 -72
- package/dist/sdk/vault/index.js +88 -3
- package/dist/sdk/vault/index.js.map +1 -1
- package/dist/status/index.cjs +16 -20
- package/dist/status/index.cjs.map +1 -1
- package/dist/status/index.d.cts +8 -9
- package/dist/status/index.d.ts +8 -9
- package/dist/status/index.js +15 -18
- package/dist/status/index.js.map +1 -1
- package/dist/status/types.cjs +0 -6
- package/dist/status/types.d.cts +17 -15
- package/dist/status/types.d.ts +17 -15
- package/dist/status/types.js +1 -3
- package/dist/storage/index.cjs +27 -54
- package/dist/storage/index.d.cts +3 -43
- package/dist/storage/index.d.ts +3 -43
- package/dist/storage/index.js +8 -9
- package/dist/storage/types.cjs +0 -4
- package/dist/storage/types.d.cts +5 -1654
- package/dist/storage/types.d.ts +5 -1654
- package/dist/storage/types.js +1 -3
- package/dist/storage-DbyNnkIJ.cjs +2458 -0
- package/dist/storage-DbyNnkIJ.cjs.map +1 -0
- package/dist/storage-luq7YBZF.js +2429 -0
- package/dist/storage-luq7YBZF.js.map +1 -0
- package/dist/storageTable-C9crh4Ef.cjs +310 -0
- package/dist/storageTable-C9crh4Ef.cjs.map +1 -0
- package/dist/storageTable-DslXtqNL.js +299 -0
- package/dist/storageTable-DslXtqNL.js.map +1 -0
- package/dist/stream/index.cjs +363 -12
- package/dist/stream/index.cjs.map +1 -1
- package/dist/stream/index.d.cts +345 -345
- package/dist/stream/index.d.ts +345 -345
- package/dist/stream/index.js +363 -4
- package/dist/stream/index.js.map +1 -1
- package/dist/stream/types.cjs +0 -4
- package/dist/stream/types.d.cts +2 -2
- package/dist/stream/types.d.ts +2 -2
- package/dist/stream/types.js +1 -3
- package/dist/suggestions-BH3x7xU7.d.cts +438 -0
- package/dist/suggestions-BH3x7xU7.d.ts +438 -0
- package/dist/syncActions/index.cjs +3 -18
- package/dist/syncActions/index.d.cts +2 -112
- package/dist/syncActions/index.d.ts +2 -112
- package/dist/syncActions/index.js +2 -9
- package/dist/syncActions/types.cjs +0 -4
- package/dist/syncActions/types.d.cts +2 -298
- package/dist/syncActions/types.d.ts +2 -298
- package/dist/syncActions/types.js +1 -3
- package/dist/syncActions-DKWeJ8GH.cjs +504 -0
- package/dist/syncActions-DKWeJ8GH.cjs.map +1 -0
- package/dist/syncActions-ssWWVN_4.js +497 -0
- package/dist/syncActions-ssWWVN_4.js.map +1 -0
- package/dist/tag-CsoOZWB_.cjs +175 -0
- package/dist/tag-CsoOZWB_.cjs.map +1 -0
- package/dist/tag-DCsoewjL.js +164 -0
- package/dist/{chunk-DHOVQ2TW.js.map → tag-DCsoewjL.js.map} +1 -1
- package/dist/telemetry/index.cjs +3 -14
- package/dist/telemetry/index.d.cts +10 -10
- package/dist/telemetry/index.d.ts +10 -10
- package/dist/telemetry/index.js +2 -5
- package/dist/telemetry/types.cjs +0 -4
- package/dist/telemetry/types.d.cts +2 -12
- package/dist/telemetry/types.d.ts +2 -12
- package/dist/telemetry/types.js +1 -3
- package/dist/telemetry-2IrE8HaZ.cjs +29 -0
- package/dist/telemetry-2IrE8HaZ.cjs.map +1 -0
- package/dist/telemetry-yQfQxBBI.js +24 -0
- package/dist/telemetry-yQfQxBBI.js.map +1 -0
- package/dist/types--T-vBqdd.d.cts +2835 -0
- package/dist/{types-CM1zHzgm.d.ts → types-2mHlPakp.d.cts} +893 -69
- package/dist/types-7H6Dnz0Y.d.ts +23 -0
- package/dist/types-B06L4-WE.d.cts +2124 -0
- package/dist/types-B1S2H7q1.d.ts +373 -0
- package/dist/types-B1glyy_Q.d.ts +726 -0
- package/dist/{utils-DK7uJcmR.d.cts → types-BCt0EMiO.d.ts} +16 -905
- package/dist/{types-BX1xr4CX.d.cts → types-BD6czYPH.d.ts} +43 -108
- package/dist/{types-BEnE7LHB.d.cts → types-BO-mTxKb.d.cts} +57 -81
- package/dist/{types-BieLFMW1.d.cts → types-BREBK0xX.d.ts} +9 -8
- package/dist/types-BRQAKEC1.d.cts +32 -0
- package/dist/types-BXK6Ebtm.d.ts +32 -0
- package/dist/types-BefwoXik.d.cts +373 -0
- package/dist/{types-DeoA45gz.d.cts → types-BhBvnvqe.d.ts} +632 -464
- package/dist/{types-Cgh3jqrV.d.cts → types-BmFyDKe6.d.ts} +893 -69
- package/dist/types-BpWqpMkL.d.ts +66 -0
- package/dist/types-C8XiTXxi.d.cts +23 -0
- package/dist/{types-BfuVN8Pk.d.cts → types-CAOvDtMC.d.cts} +11 -16
- package/dist/types-CC0wymfG.d.ts +2088 -0
- package/dist/{types-YzkNUuYo.d.ts → types-CI1mW2lA.d.ts} +11 -16
- package/dist/{types-00IaLn3S.d.ts → types-CRYtdj5w.d.ts} +876 -374
- package/dist/{types-CrLjE5xf.d.ts → types-CSmttcZ_.d.ts} +10 -12
- package/dist/{types-DgSyBwP3.d.cts → types-CbZ8aMKW.d.cts} +11 -14
- package/dist/{types-DwMezEHT.d.ts → types-CexuN7Mw.d.cts} +43 -108
- package/dist/types-CjAia48k.d.ts +386 -0
- package/dist/{types-D-MuJHwl.d.cts → types-CtdyAkzI.d.cts} +28 -16
- package/dist/{types-DpUcInCX.d.ts → types-CvADp-x-.d.ts} +11 -14
- package/dist/types-CwvOcTOm.d.cts +2088 -0
- package/dist/types-CyRK5z-E.d.cts +386 -0
- package/dist/{types-DbAO-Tgk.d.ts → types-D2n3h1gp.d.ts} +57 -81
- package/dist/types-DBOEA7l0.d.cts +148 -0
- package/dist/{types-DYnHIm7m.d.cts → types-DCBKso0t.d.cts} +10 -12
- package/dist/{types-Hj1CaKtV.d.ts → types-DEKF5pbg.d.cts} +632 -464
- package/dist/{types-B30y9Lhc.d.ts → types-DMvU4kZ2.d.cts} +208 -24
- package/dist/{types-B-vmDlWB.d.cts → types-DS8uFAeq.d.cts} +10 -15
- package/dist/types-DeApSCzx.d.cts +602 -0
- package/dist/types-DebL68-g.d.ts +148 -0
- package/dist/types-DgaYUtu_.d.cts +726 -0
- package/dist/{types-CiJ5ULtS.d.ts → types-DkbfBOBr.d.cts} +9 -8
- package/dist/types-DvsGS8By.d.cts +66 -0
- package/dist/{types-DHXZZKb3.d.ts → types-DwX1uxp_.d.ts} +10 -15
- package/dist/{types-sVyfECai.d.cts → types-ISUNM_BR.d.cts} +876 -374
- package/dist/{utils-B_SOM1XR.d.ts → types-QOIQ-dZU.d.cts} +16 -905
- package/dist/types-SGuvOEV8.d.ts +2124 -0
- package/dist/types-V8rC5if7.d.cts +621 -0
- package/dist/{types-CSZoV4lM.d.cts → types-Z-vUwgym.d.ts} +208 -24
- package/dist/types-bws2RtKq.d.ts +602 -0
- package/dist/types-h9TTimS_.d.ts +2835 -0
- package/dist/types-lFsTSkhe.d.cts +14 -0
- package/dist/types-lFsTSkhe.d.ts +14 -0
- package/dist/types-n4FFKqa4.d.ts +621 -0
- package/dist/{types-DeS-oVdn.d.ts → types-x4xPlrr0.d.ts} +28 -16
- package/dist/vault/index.cjs +49 -13
- package/dist/vault/index.cjs.map +1 -1
- package/dist/vault/index.d.cts +2 -26
- package/dist/vault/index.d.ts +2 -26
- package/dist/vault/index.js +49 -5
- package/dist/vault/index.js.map +1 -1
- package/dist/vault/types.cjs +0 -4
- package/dist/vault/types.d.cts +2 -385
- package/dist/vault/types.d.ts +2 -385
- package/dist/vault/types.js +1 -3
- package/package.json +113 -7
- package/surface/ai.md +1 -0
- package/surface/apps.md +32 -0
- package/surface/auth.md +6 -4
- package/surface/chat.md +3 -2
- package/surface/dataScience.md +3 -2
- package/surface/editor.md +1 -0
- package/surface/encryption.md +1 -0
- package/surface/import.md +1 -0
- package/surface/kaiAgent.md +2 -1
- package/surface/management.md +17 -16
- package/surface/metastore.md +2 -1
- package/surface/notifications.md +1 -0
- package/surface/oauth.md +1 -0
- package/surface/omnisearch.md +9 -0
- package/surface/queryService.md +5 -3
- package/surface/queue.md +8 -6
- package/surface/scheduler.md +1 -0
- package/surface/sdk.md +22 -22
- package/surface/storage.md +147 -106
- package/surface/stream.md +1 -0
- package/surface/syncActions.md +13 -6
- package/surface/vault.md +1 -0
- package/dist/ManagementClientAuthError-4J0S5tV-.d.ts +0 -9
- package/dist/ManagementClientAuthError-CyDpa4NS.d.cts +0 -9
- package/dist/adminRoles-Cil1lavB.d.cts +0 -18
- package/dist/adminRoles-Cil1lavB.d.ts +0 -18
- package/dist/ai/types.cjs.map +0 -1
- package/dist/ai/types.js.map +0 -1
- package/dist/auth/index.cjs.map +0 -1
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/types.cjs.map +0 -1
- package/dist/auth/types.js.map +0 -1
- package/dist/chunk-22E6IGXR.js +0 -6
- package/dist/chunk-22E6IGXR.js.map +0 -1
- package/dist/chunk-2BOG5U7C.js +0 -75
- package/dist/chunk-2BOG5U7C.js.map +0 -1
- package/dist/chunk-2CFM7K4U.cjs +0 -55
- package/dist/chunk-2CFM7K4U.cjs.map +0 -1
- package/dist/chunk-34GM6NXB.js +0 -77
- package/dist/chunk-34GM6NXB.js.map +0 -1
- package/dist/chunk-3BFPNM2J.js +0 -61
- package/dist/chunk-3BFPNM2J.js.map +0 -1
- package/dist/chunk-3PVERYSF.js +0 -16
- package/dist/chunk-3PVERYSF.js.map +0 -1
- package/dist/chunk-3YWQQ3OG.cjs +0 -79
- package/dist/chunk-3YWQQ3OG.cjs.map +0 -1
- package/dist/chunk-4RC5E3SL.js +0 -140
- package/dist/chunk-4RC5E3SL.js.map +0 -1
- package/dist/chunk-4VVF2PIX.js +0 -110
- package/dist/chunk-4VVF2PIX.js.map +0 -1
- package/dist/chunk-552FC4ZV.js +0 -14
- package/dist/chunk-552FC4ZV.js.map +0 -1
- package/dist/chunk-5XWVWFTC.js +0 -33
- package/dist/chunk-5XWVWFTC.js.map +0 -1
- package/dist/chunk-6YZQIMML.cjs +0 -163
- package/dist/chunk-6YZQIMML.cjs.map +0 -1
- package/dist/chunk-77LILJYX.js +0 -110
- package/dist/chunk-77LILJYX.js.map +0 -1
- package/dist/chunk-7J2R6XHB.js +0 -3
- package/dist/chunk-7J2R6XHB.js.map +0 -1
- package/dist/chunk-7R22VKV7.cjs +0 -62
- package/dist/chunk-7R22VKV7.cjs.map +0 -1
- package/dist/chunk-7RO6PKZ4.cjs +0 -16
- package/dist/chunk-7RO6PKZ4.cjs.map +0 -1
- package/dist/chunk-7YXL4FKN.cjs +0 -340
- package/dist/chunk-7YXL4FKN.cjs.map +0 -1
- package/dist/chunk-7Z4MU7ZB.js +0 -1294
- package/dist/chunk-7Z4MU7ZB.js.map +0 -1
- package/dist/chunk-AFJGNBVM.cjs +0 -63
- package/dist/chunk-AFJGNBVM.cjs.map +0 -1
- package/dist/chunk-AVH6F5LB.js +0 -1492
- package/dist/chunk-AVH6F5LB.js.map +0 -1
- package/dist/chunk-AXEANGGK.js +0 -226
- package/dist/chunk-AXEANGGK.js.map +0 -1
- package/dist/chunk-BCZPCMGL.cjs +0 -49
- package/dist/chunk-BCZPCMGL.cjs.map +0 -1
- package/dist/chunk-BR6WZE3O.cjs +0 -42
- package/dist/chunk-BR6WZE3O.cjs.map +0 -1
- package/dist/chunk-BZA3FGO6.js +0 -40
- package/dist/chunk-BZA3FGO6.js.map +0 -1
- package/dist/chunk-CV2JGHBN.js +0 -183
- package/dist/chunk-CV2JGHBN.js.map +0 -1
- package/dist/chunk-CWCUQACX.cjs +0 -18
- package/dist/chunk-CWCUQACX.cjs.map +0 -1
- package/dist/chunk-CWUQ6ZAO.cjs +0 -185
- package/dist/chunk-CWUQ6ZAO.cjs.map +0 -1
- package/dist/chunk-D4WOOKMI.js +0 -350
- package/dist/chunk-D4WOOKMI.js.map +0 -1
- package/dist/chunk-DHOVQ2TW.js +0 -177
- package/dist/chunk-DRNOCC6W.cjs +0 -295
- package/dist/chunk-DRNOCC6W.cjs.map +0 -1
- package/dist/chunk-EDX5D6UY.js +0 -14
- package/dist/chunk-EWMXK3EI.cjs +0 -8
- package/dist/chunk-EWMXK3EI.cjs.map +0 -1
- package/dist/chunk-EYIPM2XB.cjs +0 -82
- package/dist/chunk-EYIPM2XB.cjs.map +0 -1
- package/dist/chunk-F6ZAYTBX.cjs +0 -364
- package/dist/chunk-F6ZAYTBX.cjs.map +0 -1
- package/dist/chunk-FJBP3MRI.cjs +0 -63
- package/dist/chunk-FJBP3MRI.cjs.map +0 -1
- package/dist/chunk-FMS5PNM2.cjs +0 -37
- package/dist/chunk-FMS5PNM2.cjs.map +0 -1
- package/dist/chunk-FPB6OGTV.js +0 -26
- package/dist/chunk-FPB6OGTV.js.map +0 -1
- package/dist/chunk-FRLSKIUI.cjs +0 -180
- package/dist/chunk-FRLSKIUI.cjs.map +0 -1
- package/dist/chunk-G3N5KDEY.js +0 -10
- package/dist/chunk-G3N5KDEY.js.map +0 -1
- package/dist/chunk-G66EP527.js +0 -59
- package/dist/chunk-G66EP527.js.map +0 -1
- package/dist/chunk-GF4XZK5N.cjs +0 -43
- package/dist/chunk-GF4XZK5N.cjs.map +0 -1
- package/dist/chunk-HITKHHWN.cjs +0 -174
- package/dist/chunk-HITKHHWN.cjs.map +0 -1
- package/dist/chunk-HMCZUHR7.js +0 -53
- package/dist/chunk-HMCZUHR7.js.map +0 -1
- package/dist/chunk-HTVJR5WS.cjs +0 -305
- package/dist/chunk-HTVJR5WS.cjs.map +0 -1
- package/dist/chunk-HY7J3OD3.cjs +0 -1298
- package/dist/chunk-HY7J3OD3.cjs.map +0 -1
- package/dist/chunk-IAYPOSMM.cjs +0 -472
- package/dist/chunk-IDWGBCSB.cjs +0 -61
- package/dist/chunk-IDWGBCSB.cjs.map +0 -1
- package/dist/chunk-J3NLKXQ5.cjs +0 -79
- package/dist/chunk-J3NLKXQ5.cjs.map +0 -1
- package/dist/chunk-KEFXOJD7.js +0 -61
- package/dist/chunk-KEFXOJD7.js.map +0 -1
- package/dist/chunk-KUYVBCUM.cjs +0 -231
- package/dist/chunk-KUYVBCUM.cjs.map +0 -1
- package/dist/chunk-L262THNK.cjs +0 -253
- package/dist/chunk-L262THNK.cjs.map +0 -1
- package/dist/chunk-LD3JERYP.js +0 -77
- package/dist/chunk-LD3JERYP.js.map +0 -1
- package/dist/chunk-LIXSIM3H.cjs +0 -113
- package/dist/chunk-LIXSIM3H.cjs.map +0 -1
- package/dist/chunk-LNZP2O4P.js +0 -169
- package/dist/chunk-LNZP2O4P.js.map +0 -1
- package/dist/chunk-MMOAH3EH.cjs +0 -288
- package/dist/chunk-MMOAH3EH.cjs.map +0 -1
- package/dist/chunk-MRHQJNWF.cjs +0 -8
- package/dist/chunk-MRHQJNWF.cjs.map +0 -1
- package/dist/chunk-MSI6FVGG.js +0 -6
- package/dist/chunk-MSI6FVGG.js.map +0 -1
- package/dist/chunk-N4COL54U.cjs +0 -22
- package/dist/chunk-N4COL54U.cjs.map +0 -1
- package/dist/chunk-NVQ6LGDO.cjs +0 -35
- package/dist/chunk-NVQ6LGDO.cjs.map +0 -1
- package/dist/chunk-NVRVPWNY.js +0 -148
- package/dist/chunk-NVRVPWNY.js.map +0 -1
- package/dist/chunk-OUSPQ55W.js +0 -263
- package/dist/chunk-OUSPQ55W.js.map +0 -1
- package/dist/chunk-PPQF7LTS.cjs +0 -63
- package/dist/chunk-PPQF7LTS.cjs.map +0 -1
- package/dist/chunk-PSR3N4NC.js +0 -136
- package/dist/chunk-PSR3N4NC.js.map +0 -1
- package/dist/chunk-QHD4LPAQ.cjs +0 -8
- package/dist/chunk-QHD4LPAQ.cjs.map +0 -1
- package/dist/chunk-RRC5RKF7.cjs +0 -12
- package/dist/chunk-RRC5RKF7.cjs.map +0 -1
- package/dist/chunk-RVBGE2Z4.js +0 -468
- package/dist/chunk-RVBGE2Z4.js.map +0 -1
- package/dist/chunk-S4JK7DKM.js +0 -61
- package/dist/chunk-S4JK7DKM.js.map +0 -1
- package/dist/chunk-SJZ66FD5.js +0 -35
- package/dist/chunk-SJZ66FD5.js.map +0 -1
- package/dist/chunk-T242YFMT.cjs +0 -150
- package/dist/chunk-T242YFMT.cjs.map +0 -1
- package/dist/chunk-T526LPBK.js +0 -6
- package/dist/chunk-T526LPBK.js.map +0 -1
- package/dist/chunk-U5SE6W5M.cjs +0 -158
- package/dist/chunk-U5SE6W5M.cjs.map +0 -1
- package/dist/chunk-UABYNGBZ.js +0 -39
- package/dist/chunk-UABYNGBZ.js.map +0 -1
- package/dist/chunk-UP5SEEYZ.js +0 -218
- package/dist/chunk-UP5SEEYZ.js.map +0 -1
- package/dist/chunk-UQ5CACMW.js +0 -283
- package/dist/chunk-UQ5CACMW.js.map +0 -1
- package/dist/chunk-UUY6LQT6.cjs +0 -267
- package/dist/chunk-UUY6LQT6.cjs.map +0 -1
- package/dist/chunk-UWQUHP3T.cjs +0 -112
- package/dist/chunk-UWQUHP3T.cjs.map +0 -1
- package/dist/chunk-XHDYLUM4.js +0 -268
- package/dist/chunk-XHDYLUM4.js.map +0 -1
- package/dist/chunk-XIIER7QQ.js +0 -60
- package/dist/chunk-XIIER7QQ.js.map +0 -1
- package/dist/chunk-XKIENBIE.js +0 -338
- package/dist/chunk-XKIENBIE.js.map +0 -1
- package/dist/chunk-XPDEQND7.cjs +0 -4
- package/dist/chunk-XPDEQND7.cjs.map +0 -1
- package/dist/chunk-YGEJDWGG.js +0 -19
- package/dist/chunk-YGEJDWGG.js.map +0 -1
- package/dist/chunk-YXGBD4WP.cjs +0 -16
- package/dist/chunk-YXGBD4WP.cjs.map +0 -1
- package/dist/chunk-Z3HZ4MP4.cjs +0 -1496
- package/dist/chunk-Z3HZ4MP4.cjs.map +0 -1
- package/dist/chunk-ZOREOLGE.js +0 -264
- package/dist/chunk-ZOREOLGE.js.map +0 -1
- package/dist/constants/index.cjs.map +0 -1
- package/dist/constants/index.js.map +0 -1
- package/dist/createGenericFetchClient-JcbIIqwF.d.cts +0 -18
- package/dist/createGenericFetchClient-ZGG5wbAC.d.ts +0 -18
- package/dist/createOpenapiFetchClient-6RX67Hws.d.ts +0 -24
- package/dist/createOpenapiFetchClient-BFmiJ9C5.d.cts +0 -24
- package/dist/dataScience/index.cjs.map +0 -1
- package/dist/dataScience/index.js.map +0 -1
- package/dist/dataScience/types.cjs.map +0 -1
- package/dist/dataScience/types.js.map +0 -1
- package/dist/domain/permissions/index.cjs.map +0 -1
- package/dist/domain/permissions/index.js.map +0 -1
- package/dist/domain/storageTable/index.cjs.map +0 -1
- package/dist/domain/storageTable/index.js.map +0 -1
- package/dist/editor/types.cjs.map +0 -1
- package/dist/editor/types.js.map +0 -1
- package/dist/encryption/types.cjs.map +0 -1
- package/dist/encryption/types.js.map +0 -1
- package/dist/import/index.cjs.map +0 -1
- package/dist/import/index.js.map +0 -1
- package/dist/keboolaUID-D1DGSbge.d.cts +0 -19
- package/dist/keboolaUID-D1DGSbge.d.ts +0 -19
- package/dist/management/index.cjs.map +0 -1
- package/dist/management/index.js.map +0 -1
- package/dist/management/types.cjs.map +0 -1
- package/dist/management/types.js.map +0 -1
- package/dist/metastore/index.cjs.map +0 -1
- package/dist/metastore/index.js.map +0 -1
- package/dist/metastore/types.cjs.map +0 -1
- package/dist/metastore/types.js.map +0 -1
- package/dist/notifications/types.cjs.map +0 -1
- package/dist/notifications/types.js.map +0 -1
- package/dist/oauth/index.cjs.map +0 -1
- package/dist/oauth/index.js.map +0 -1
- package/dist/oauth/types.cjs.map +0 -1
- package/dist/oauth/types.js.map +0 -1
- package/dist/project-CXqPYo4T.d.ts +0 -17
- package/dist/project-CZPvcxRW.d.cts +0 -17
- package/dist/queryService/index.cjs.map +0 -1
- package/dist/queryService/index.js.map +0 -1
- package/dist/queryService/types.cjs.map +0 -1
- package/dist/queryService/types.js.map +0 -1
- package/dist/queue/index.cjs.map +0 -1
- package/dist/queue/index.js.map +0 -1
- package/dist/queue/types.cjs.map +0 -1
- package/dist/queue/types.js.map +0 -1
- package/dist/registry-CcKlB-yY.d.ts +0 -1046
- package/dist/registry-Cg0Yng1z.d.cts +0 -1046
- package/dist/scheduler/types.cjs.map +0 -1
- package/dist/scheduler/types.js.map +0 -1
- package/dist/sdk/configurations/index.cjs.map +0 -1
- package/dist/sdk/configurations/index.js.map +0 -1
- package/dist/sdk/semanticLayer/types.cjs.map +0 -1
- package/dist/sdk/semanticLayer/types.js.map +0 -1
- package/dist/sdk/tag/index.cjs.map +0 -1
- package/dist/sdk/tag/index.js.map +0 -1
- package/dist/sdk/tag/types.cjs.map +0 -1
- package/dist/sdk/tag/types.js.map +0 -1
- package/dist/status/types.cjs.map +0 -1
- package/dist/status/types.js.map +0 -1
- package/dist/storage/index.cjs.map +0 -1
- package/dist/storage/index.js.map +0 -1
- package/dist/storage/types.cjs.map +0 -1
- package/dist/storage/types.js.map +0 -1
- package/dist/storageClient-Cd4jVt58.d.ts +0 -1519
- package/dist/storageClient-Dkcg7hKa.d.cts +0 -1519
- package/dist/storageSdk-15_Fbucc.d.cts +0 -746
- package/dist/storageSdk-L6NOdgSJ.d.ts +0 -746
- package/dist/stream/types.cjs.map +0 -1
- package/dist/stream/types.js.map +0 -1
- package/dist/syncActions/index.cjs.map +0 -1
- package/dist/syncActions/index.js.map +0 -1
- package/dist/syncActions/types.cjs.map +0 -1
- package/dist/syncActions/types.js.map +0 -1
- package/dist/telemetry/index.cjs.map +0 -1
- package/dist/telemetry/index.js.map +0 -1
- package/dist/telemetry/types.cjs.map +0 -1
- package/dist/telemetry/types.js.map +0 -1
- package/dist/types-BqC3U0k0.d.cts +0 -12
- package/dist/types-Dkipk6NN.d.ts +0 -12
- package/dist/types-UwuKN9Kx.d.cts +0 -60
- package/dist/types-UwuKN9Kx.d.ts +0 -60
- package/dist/types-gcShAmmi.d.cts +0 -90
- package/dist/types-gcShAmmi.d.ts +0 -90
- package/dist/vault/types.cjs.map +0 -1
- package/dist/vault/types.js.map +0 -1
package/AGENTS.md
ADDED
|
@@ -0,0 +1,623 @@
|
|
|
1
|
+
# @keboola/api-client
|
|
2
|
+
|
|
3
|
+
TypeScript SDK wrapping all Keboola platform HTTP APIs with typed clients and middleware.
|
|
4
|
+
|
|
5
|
+
This file is the **usage** guide — how to get a client, call it, and handle errors. For SDK internals (architecture, middleware authoring, adding a client, type generation) see [Development](#development) at the bottom.
|
|
6
|
+
|
|
7
|
+
`CLAUDE.md` is a symlink to this file (`AGENTS.md`). Always edit `AGENTS.md`.
|
|
8
|
+
|
|
9
|
+
## Commands
|
|
10
|
+
|
|
11
|
+
All commands run from monorepo root using `--filter`:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pnpm build --filter=@keboola/api-client # Build with tsdown (ESM + CJS + .d.ts)
|
|
15
|
+
pnpm test --filter=@keboola/api-client # Vitest
|
|
16
|
+
pnpm type-check --filter=@keboola/api-client # tsc --noEmit
|
|
17
|
+
pnpm --filter @keboola/api-client gen:types # Regenerate OpenAPI types from redocly.yaml
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Getting a client
|
|
21
|
+
|
|
22
|
+
**React (the common case).** In `apps/kbc-ui` and other React apps, use `useApiClient()` from [`@keboola/api-client-react`](../api-client-react/AGENTS.md) — it returns the flow-agnostic `api` (auth + management + product namespaces). At startup an auth provider (`LegacyAuthProvider` for SAPI, `AuthProvider` for bearer) drives the module-load singleton's `session` to ready and renders a fallback until then; `ApiClientProvider` propagates that `api` to the tree. Don't create a client per component.
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
const api = useApiClient();
|
|
26
|
+
const { data } = useQuery({
|
|
27
|
+
queryKey: storageApiKey.getTable(id),
|
|
28
|
+
queryFn: ({ signal }) => api.storage.tables.getTable({ branchId, tableId: id }, signal),
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Scripts / CLIs / non-React.** Create one directly — pick the smallest that covers you:
|
|
33
|
+
|
|
34
|
+
- **`createStorageClient`** — Storage-only. Needs only `baseUrl` + `token`, skipping the stack-info round-trip. Start here when in doubt; upgrading later is mechanical, downgrading is not. (React apps still get their client via `ApiClientProvider` + `useApiClient()` — see above; this section is about the non-React/single-service case.)
|
|
35
|
+
- **`createLegacyKeboola` / `createKeboola`** — full SDK across all stack services. Each returns `{ api, session }`; drive the `session` to ready, then use `api`. Bootstrap (`getStackInfo` + `tokens.verify()` to discover services against the actual stack) runs while the storage build resolves, after which `api.context` is synchronous. Every stack service — including `metastore` — is resolved from the stack's advertised service URLs. See the lifecycle section below for the per-flow `session` verbs. The token-less public clients `createAssetsClient` / `createStatusClient` are **not** part of this — import them directly from `@keboola/api-client/assets` and `@keboola/api-client/status`.
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
// Storage-only — imports from the /storage sub-path
|
|
39
|
+
import { createStorageClient } from '@keboola/api-client/storage';
|
|
40
|
+
|
|
41
|
+
const storage = createStorageClient({
|
|
42
|
+
baseUrl: process.env.KEBOOLA_STACK_URL!, // canonical form, no trailing slash
|
|
43
|
+
auth: { type: 'sapi-token', token: process.env.KEBOOLA_STORAGE_TOKEN! },
|
|
44
|
+
});
|
|
45
|
+
const tables = await storage.tables.getTables();
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
// Full SDK across all services — drive the session to ready, then use `api`
|
|
50
|
+
import { createLegacyKeboola } from '@keboola/api-client';
|
|
51
|
+
|
|
52
|
+
const { api, session } = createLegacyKeboola({ baseUrl: process.env.KEBOOLA_STACK_URL! });
|
|
53
|
+
await session.authenticateStorageAsync(process.env.KEBOOLA_STORAGE_TOKEN!);
|
|
54
|
+
const stack = api.context.stack; // synchronous — the storage build has resolved
|
|
55
|
+
const buckets = await api.storage.buckets.getBuckets();
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Lifecycle & auth (the stateful client)
|
|
59
|
+
|
|
60
|
+
Two flow-specific factories back the SDK, and **both return `{ api, session }`**:
|
|
61
|
+
|
|
62
|
+
- `createKeboola(opts?)` — the **bearer (OAuth)** flow.
|
|
63
|
+
- `createLegacyKeboola(opts?)` — the **legacy (SAPI-token)** flow.
|
|
64
|
+
|
|
65
|
+
`api` is the same **flow-agnostic** product surface for both — a state-gating proxy:
|
|
66
|
+
|
|
67
|
+
- **`api.auth.*`** — auth-service client, live once a `baseUrl` is configured.
|
|
68
|
+
- **`api.management.*`** — management client, live once the management realm authenticates.
|
|
69
|
+
- **`api.storage` / `api.queue` / `api.context` / `api.sdk` / …** — product namespaces, live only once
|
|
70
|
+
the async storage build reaches `ready` (throw `KeboolaError` (`NotReady`) before that).
|
|
71
|
+
|
|
72
|
+
`session` is **flow-specific** lifecycle machinery. Both share `setBaseUrl`, `isStorageReady()`,
|
|
73
|
+
`subscribe(cb)` (fires on config **and** storage-build transitions), and `debug()`. Then:
|
|
74
|
+
|
|
75
|
+
- bearer: `authenticate(token)` → `setProject(projectId)` / `setProjectAsync(projectId)` (awaits the
|
|
76
|
+
build) / `reset()`.
|
|
77
|
+
- legacy: `authenticateStorage(sapiToken)` / `authenticateStorageAsync(sapiToken)` (awaits the build),
|
|
78
|
+
`authenticateManagement(manageToken)`.
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
// Legacy (SAPI token in hand): one step to ready
|
|
82
|
+
const { api, session } = createLegacyKeboola({ baseUrl });
|
|
83
|
+
await session.authenticateStorageAsync(token);
|
|
84
|
+
const buckets = await api.storage.buckets.getBuckets(defaultBranchId);
|
|
85
|
+
|
|
86
|
+
// Bearer (OAuth) login flow (browser)
|
|
87
|
+
const { api, session } = createKeboola({ baseUrl });
|
|
88
|
+
await api.auth.login({ email, password }); // → carries the bearer token
|
|
89
|
+
const projects = await api.auth.getProjects(); // introspect → picker
|
|
90
|
+
await session.authenticate(bearerToken);
|
|
91
|
+
await session.setProjectAsync(projects[0].id); // → ready
|
|
92
|
+
session.setProject(otherId); // runtime re-scope (rebuilds against the new project)
|
|
93
|
+
|
|
94
|
+
session.debug(); // { baseUrl, authReady, managementReady, storage, config }
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
In React, `useApiClient()` returns `api`; `AuthProvider` (bearer) / `LegacyAuthProvider` (legacy) own
|
|
98
|
+
driving the `session` to ready and gate on a `fallback`. See
|
|
99
|
+
[`@keboola/api-client-react`](../api-client-react/AGENTS.md).
|
|
100
|
+
|
|
101
|
+
**Persisting the bearer session.** `createKeboola` accepts a `storage` adapter (bearer only). Omit it
|
|
102
|
+
and the session is in-memory (lost on reload); pass a storage adapter to make it durable:
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
import { createLocalStorage } from '@keboola/api-client';
|
|
106
|
+
|
|
107
|
+
const { api, session } = createKeboola({ baseUrl, storage: createLocalStorage() });
|
|
108
|
+
// On startup, call `session.restore()` to rehydrate: it exchanges the persisted refresh token for a
|
|
109
|
+
// fresh credential eagerly (before any request), then re-scopes to the stored project. It resolves
|
|
110
|
+
// `{ status: 'restored' | 'empty' | 'expired' }` — `expired` means the refresh token was dead and the
|
|
111
|
+
// stored session was cleared; route to login. `session.reset()` clears the stored session.
|
|
112
|
+
const result = await session.restore();
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Every credential change (login, project switch, token rotation, sign-out) is written back — only the
|
|
116
|
+
durable subset `{ baseUrl, projectId, refreshToken }`, never the access token or user identity. A
|
|
117
|
+
single fixed key holds one bearer session, tagged with the stack (`baseUrl`) it belongs to. The
|
|
118
|
+
configured stack is authoritative: `restore()` adopts the stored `baseUrl` only when you construct
|
|
119
|
+
without one; if you pass a `baseUrl` that differs from the stored session's stack, that session is
|
|
120
|
+
**discarded** (a stored refresh token is only ever sent to the stack that issued it, never another).
|
|
121
|
+
Adapters: `createLocalStorage` / `createSessionStorage` (browser, memory fallback on Node/SSR),
|
|
122
|
+
`createMemoryStorage`, `createNullStorage`. In Node, supply your own adapter or default to memory.
|
|
123
|
+
|
|
124
|
+
**`localStorage` vs `sessionStorage` — scope, not safety.** Neither is more secure: both are readable
|
|
125
|
+
by any script on the origin (XSS), so the choice is purely about lifetime. `createLocalStorage()`
|
|
126
|
+
survives a browser restart ("stay signed in") and is shared across tabs; `createSessionStorage()` is
|
|
127
|
+
per-tab and cleared when the tab closes. Because neither is XSS-proof, the persisted blob is kept
|
|
128
|
+
minimal — the rotating **refresh token** plus `baseUrl`/`projectId`, never the access token or
|
|
129
|
+
identity; the access token lives only in memory, and the stored refresh token is single-use (rotated
|
|
130
|
+
on every refresh) and server-revocable, so a leaked snapshot has limited, revocable value. The
|
|
131
|
+
genuinely secure option — keeping the refresh token out of JS entirely behind a BFF
|
|
132
|
+
(backend-for-frontend) with an HttpOnly cookie — is out of scope for now.
|
|
133
|
+
|
|
134
|
+
`createStorageClient` exposes the same Storage surface as `api.storage.*` but no lifecycle and no `context` helpers (`baseUrl` / `stack` / `project` / `defaultBranch`). Per-service factories (`@keboola/api-client/storage`, `@keboola/api-client/management`, …) also exist for standalone single-service use.
|
|
135
|
+
|
|
136
|
+
**Need the stack URL? Use `api.context.baseUrl`, not `api.context.stack.host`.** `baseUrl` is the absolute URL the client is configured against and builds every request on, canonical form (no trailing slash). `stack.host` is a bare hostname the stack reports about itself in its index response — no scheme, and not what routes a request, so the two can legitimately differ on a proxied or custom-domain deployment.
|
|
137
|
+
|
|
138
|
+
Import paths:
|
|
139
|
+
|
|
140
|
+
| Export path | Purpose |
|
|
141
|
+
| ----------------------------------------- | ---------------------------------------------------------------- |
|
|
142
|
+
| `@keboola/api-client` | Full SDK: `createKeboola` / `createLegacyKeboola`, errors, utils |
|
|
143
|
+
| `@keboola/api-client/<client>` | Per-client factory (e.g. `storage`) |
|
|
144
|
+
| `@keboola/api-client/<client>/types` | Per-client type imports |
|
|
145
|
+
| `@keboola/api-client/sdk/tag` | Tag SDK (composes multiple clients) |
|
|
146
|
+
| `@keboola/api-client/sdk/developerPortal` | Developer Portal SDK (client + its session) |
|
|
147
|
+
| `@keboola/api-client/sdk/configurations` | Core configuration SDK |
|
|
148
|
+
| `@keboola/api-client/domain/permissions` | Permission primitives |
|
|
149
|
+
|
|
150
|
+
## Consumption Hierarchy
|
|
151
|
+
|
|
152
|
+
When implementing an action that talks to a Keboola API, pick the highest layer that already covers it:
|
|
153
|
+
|
|
154
|
+
1. **Prefer `sdks/`** — if an SDK exists (e.g. `@keboola/api-client/sdk/tag`), use it. SDKs encapsulate multi-client orchestration so consumers don't re-derive it.
|
|
155
|
+
2. **Fallback to `clients/`** — when no SDK covers the action, compose it from the per-service client methods (e.g. `api.storage.tables.create(...)`).
|
|
156
|
+
|
|
157
|
+
Never reach below `clients/` to `fetchClient` directly — all HTTP must flow through a typed client factory so middleware and types stay consistent.
|
|
158
|
+
|
|
159
|
+
## Writing a configuration safely (agents / Node)
|
|
160
|
+
|
|
161
|
+
When a caller writes a component configuration on a user's behalf — an agent-generated payload, a BE/Node process, a script — go through `api.sdk.configuration`, **never** `api.storage.configurations.createConfiguration` directly. The SDK method carries the config-write business logic that would otherwise have to be re-implemented (and kept in sync) per consumer:
|
|
162
|
+
|
|
163
|
+
1. **Validate** — parses `configuration` against the component's registered **input schema** (a deep-partial of the runnable schema) from `sdks/configurations/registry.ts`.
|
|
164
|
+
2. **Encrypt** — hands every `#`-prefixed secret field to the encryption service (a remote call) and writes back the ciphertext, so a **plaintext secret is never sent to Storage**.
|
|
165
|
+
3. **Write** — only then calls Storage.
|
|
166
|
+
|
|
167
|
+
`api.sdk.configuration` is auto-wired (storage + encryption + project context) by `createKeboola` / `createLegacyKeboola`, so a Node consumer constructs nothing by hand:
|
|
168
|
+
|
|
169
|
+
```ts
|
|
170
|
+
import { createLegacyKeboola } from '@keboola/api-client';
|
|
171
|
+
|
|
172
|
+
const { api, session } = createLegacyKeboola({ baseUrl });
|
|
173
|
+
await session.authenticateStorageAsync(sapiToken); // → ready
|
|
174
|
+
|
|
175
|
+
// componentId must be a registered id; `#`-prefixed fields are encrypted before the write.
|
|
176
|
+
const result = await api.sdk.configuration.createConfiguration({
|
|
177
|
+
componentId: 'keboola.ex-db-mysql',
|
|
178
|
+
name: 'Orders DB',
|
|
179
|
+
configuration: {
|
|
180
|
+
parameters: { db: { host: 'db.example.com', user: 'svc', '#password': 'hunter2' } },
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
// result: { data, runnable, error } — `data` is the created config;
|
|
184
|
+
// `runnable` is false + `error` set when the stored config doesn't satisfy the full schema.
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Two boundaries to know before relying on it:
|
|
188
|
+
|
|
189
|
+
- **Registered components only.** `createConfiguration` looks the id up in the registry and **throws** for an unregistered one (`No configuration registered for component "…"`) — there is no generic pass-through path. The registered set is whatever `registry.ts` lists (DB writers/extractors plus others like `scheduler` and `app-data-gateway`); a component absent from it has no safe typed path yet.
|
|
190
|
+
- **Permission-guarded before any side effect.** `createConfiguration` / `updateConfiguration` call `assertCanCreateConfiguration` / `assertCanUpdateConfiguration` as their first step and throw [`PermissionDeniedError`](#error-handling) for a caller whose token can't write to the target branch — before validation, encryption, or the network. The branch's dev-vs-production mode is derived from the input's `branchId`. You get this for free; only pre-check with the [`domain/permissions`](#permissions) predicates yourself if you want to gate UI _before_ calling.
|
|
191
|
+
|
|
192
|
+
## Calling the API
|
|
193
|
+
|
|
194
|
+
**Narrow type imports.** Prefer per-service sub-paths over the barrel — the barrel re-exports everything and inflates autocomplete:
|
|
195
|
+
|
|
196
|
+
```ts
|
|
197
|
+
// PREFERRED — tree-shakes correctly
|
|
198
|
+
import type { Table, Bucket } from '@keboola/api-client/storage/types';
|
|
199
|
+
import type { DataApp } from '@keboola/api-client/dataScience/types';
|
|
200
|
+
|
|
201
|
+
// ACCEPTABLE for runtime values / error guards (no type-only equivalent)
|
|
202
|
+
import { isApiError, isAbortError, isFetchClientError } from '@keboola/api-client';
|
|
203
|
+
|
|
204
|
+
// AVOID for types
|
|
205
|
+
import type { Table } from '@keboola/api-client';
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Always forward `signal`.** Every TanStack Query `queryFn` must forward the provided `signal` to the API call — otherwise inflight requests outlive the component or the query-key change, leaking network activity and potentially writing stale data:
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
useQuery({
|
|
212
|
+
queryKey: storageApiKey.getTable(id),
|
|
213
|
+
queryFn: ({ signal }) => api.storage.tables.getTable({ branchId, tableId: id }, signal), // ← forwarded
|
|
214
|
+
});
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Conditional queries** — use `skipToken`, not `enabled: false`, so TypeScript narrows `data` and the query never fires with an `undefined` key:
|
|
218
|
+
|
|
219
|
+
```ts
|
|
220
|
+
import { skipToken } from '@tanstack/react-query';
|
|
221
|
+
|
|
222
|
+
queryOptions({
|
|
223
|
+
queryKey: sandboxesApiKey.getSandbox(id ?? ''),
|
|
224
|
+
queryFn: !id ? skipToken : async ({ signal }) => api.dataScience.getApp(id, signal),
|
|
225
|
+
});
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**Mutations.** Use `useMutation` for writes; invalidate affected queries in `onSuccess`:
|
|
229
|
+
|
|
230
|
+
```ts
|
|
231
|
+
const queryClient = useQueryClient();
|
|
232
|
+
|
|
233
|
+
const saveSettings = useMutation({
|
|
234
|
+
mutationFn: (values: FormValues) =>
|
|
235
|
+
api.management.projects.setProjectMetadata({ projectId, ...values }),
|
|
236
|
+
onSuccess: async () => {
|
|
237
|
+
await queryClient.invalidateQueries({
|
|
238
|
+
queryKey: managementApiKey.getProjectMetadata(projectId),
|
|
239
|
+
exact: false, // invalidates all sub-keys too
|
|
240
|
+
});
|
|
241
|
+
toast.success('Settings saved.');
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Reach for **optimistic updates** only for frequent, latency-sensitive mutations (e.g. deleting from a long list): `onMutate` snapshots + applies, `onError` rolls back, `onSettled` invalidates. For rare or slow mutations (save, deploy) skip them — just show `isPending`.
|
|
247
|
+
|
|
248
|
+
## Error handling
|
|
249
|
+
|
|
250
|
+
Three type guards live in `createFetchClient.ts`, re-exported from `@keboola/api-client`:
|
|
251
|
+
|
|
252
|
+
| Guard | Catches | UX outcome |
|
|
253
|
+
| -------------------- | --------------------------------------------------------------- | ------------------------------------------------- |
|
|
254
|
+
| `isAbortError` | `DOMException { name: 'AbortError' }` | Silently ignore — user/unmount cancelled |
|
|
255
|
+
| `isApiError` | HTTP error responses parsed by the SDK | Surface `err.message` (HTTP `statusText`) |
|
|
256
|
+
| `isFetchClientError` | `TypeError` (DNS/CORS), `SyntaxError` (bad JSON), or `ApiError` | Show a "Network problem" message; do not re-throw |
|
|
257
|
+
|
|
258
|
+
> `DOMException` is in the `FetchClientError` _type_ but **not** matched by the `isFetchClientError` _guard_ — abort `DOMException`s are reachable only through `isAbortError`, so always check `isAbortError` first.
|
|
259
|
+
|
|
260
|
+
Error classes the SDK can throw — branch on these instead of a catch-all `unknown`:
|
|
261
|
+
|
|
262
|
+
| Class | Exported from | Branch specifically when… |
|
|
263
|
+
| --------------------------- | ---------------------------------------- | --------------------------------------------------------------------------- |
|
|
264
|
+
| `ApiError` | `@keboola/api-client` | You need raw `response` / `request` / parsed `data` (e.g. 4xx payload) |
|
|
265
|
+
| `UserError` | `@keboola/api-client` | You want to surface `err.message` verbatim — already phrased for users |
|
|
266
|
+
| `ServiceUnavailableError` | `@keboola/api-client` | A namespace was accessed on a stack that doesn't host it — hide the feature |
|
|
267
|
+
| `ManagementClientAuthError` | `@keboola/api-client` | Session expired (management redirected to login) — global re-login UX |
|
|
268
|
+
| `PermissionDeniedError` | `@keboola/api-client/domain/permissions` | A client-side `assertCan*` refused before any HTTP round-trip |
|
|
269
|
+
|
|
270
|
+
There is **no** `ServerError` class — server-originated failures surface as `ApiError`; discriminate 5xx from 4xx via `err.response.status` inside `isApiError(err)`. `ManagementClientAuthError` extends `ApiError`, so check `isManagementClientAuthError` first.
|
|
271
|
+
|
|
272
|
+
Canonical try/catch — order guards most-specific first:
|
|
273
|
+
|
|
274
|
+
```ts
|
|
275
|
+
import {
|
|
276
|
+
isAbortError,
|
|
277
|
+
isApiError,
|
|
278
|
+
isFetchClientError,
|
|
279
|
+
isManagementClientAuthError,
|
|
280
|
+
} from '@keboola/api-client';
|
|
281
|
+
|
|
282
|
+
try {
|
|
283
|
+
await api.storage.tables.getTable({ branchId, tableId: id }, signal);
|
|
284
|
+
} catch (err) {
|
|
285
|
+
if (isAbortError(err)) return; // cancelled — no UI
|
|
286
|
+
if (isManagementClientAuthError(err)) return redirectToLogin();
|
|
287
|
+
if (isApiError(err)) return toast.error(err.message); // HTTP error from server
|
|
288
|
+
if (isFetchClientError(err)) return toast.error('Network problem');
|
|
289
|
+
throw err; // unexpected — propagate
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
TanStack Query's `onError` / `throwOnError` handles most cases; the explicit try/catch applies to `mutationFn`, event handlers, or one-off `await`s outside queries. **Let Query handle retries and state; let the component decide UX.** Retry by status:
|
|
294
|
+
|
|
295
|
+
- **Transport (`TypeError`)** → transient; retry up to 3× with backoff (`retryDelay: (a) => Math.min(1000 * 2 ** a, 30_000)`). Skip `SyntaxError` (server contract bug, not transient).
|
|
296
|
+
- **401 / 403** → never retry. Session expiry surfaces as `ManagementClientAuthError` (check `isManagementClientAuthError`) — branch to a global re-login.
|
|
297
|
+
- **404 on a `GET`** → normal product state; render an empty state, not "Something went wrong". A 404 on a _mutation_ (deleting an already-gone resource) can be treated as success.
|
|
298
|
+
- **5xx** → server-side, often transient. The default client wires **no** transport-level retry (the keboola client sets only the storage-token middleware). Add `createRetryMiddleware` to the client's `middlewares` for automatic 5xx retry, and then keep `retry: false` at the query level so attempts don't multiply (query `retry: 2` × the middleware's 6 transport attempts = 18 requests). Surface `err.message` (`statusText`); richer detail may be on `err.data` (typed `unknown` — narrow before reading).
|
|
299
|
+
|
|
300
|
+
```ts
|
|
301
|
+
useQuery({
|
|
302
|
+
queryKey: storageApiKey.getTable(id),
|
|
303
|
+
queryFn: ({ signal }) => api.storage.tables.getTable({ branchId, tableId: id }, signal),
|
|
304
|
+
retry: (failureCount, err) => {
|
|
305
|
+
if (isApiError(err)) return false; // HTTP errors handled per-status above
|
|
306
|
+
return err instanceof TypeError && failureCount < 3; // retry transport failures only
|
|
307
|
+
},
|
|
308
|
+
retryDelay: (attempt) => Math.min(1000 * 2 ** attempt, 30_000), // exponential backoff
|
|
309
|
+
});
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
Surfacing — toast vs inline:
|
|
313
|
+
|
|
314
|
+
| Trigger | Surface | Why |
|
|
315
|
+
| ------------------------------------------- | -------- | ----------------------------------------- |
|
|
316
|
+
| Mutation failure (user-initiated write) | Toast | Action-scoped — user just clicked |
|
|
317
|
+
| Query failure on a page or panel | Inline | Page-scoped — the region knows it's empty |
|
|
318
|
+
| 404 in a `useQuery` | Empty UI | Not an error |
|
|
319
|
+
| `isAbortError` (cancellation, route change) | Silent | The user caused it |
|
|
320
|
+
| Background refetch failure | Silent | Stale data is still useful; log only |
|
|
321
|
+
|
|
322
|
+
## Permissions
|
|
323
|
+
|
|
324
|
+
`@keboola/api-client/domain/permissions` holds token-only capability predicates: `canX` (boolean, safe in any UI condition) paired with `assertCanX` (throws `PermissionDeniedError` before any HTTP round-trip). Catch the error to gate UI without a network call; let it propagate from `useQuery` to surface a "no access" empty state.
|
|
325
|
+
|
|
326
|
+
Implemented today: `admin.ts` (`isAdmin`, `isProductionManager`, … + matching `assertCan*`, all `(token)`-only) and `configurations.ts` (`canCreate/canCopy/canMigrateFromTemplate/canPurge/canAssignFolder` + `assertCan*`, taking a trailing `ctx: ConfigurationCtx`). `storage.ts`, `devBranches.ts`, `sandboxes.ts`, `organization.ts` are still `export {}` placeholders.
|
|
327
|
+
|
|
328
|
+
```ts
|
|
329
|
+
import { PermissionDeniedError } from '@keboola/api-client/domain/permissions';
|
|
330
|
+
|
|
331
|
+
try {
|
|
332
|
+
assertCanCreateConfiguration(token, ctx);
|
|
333
|
+
await api.storage.configurations.createConfiguration(payload);
|
|
334
|
+
} catch (err) {
|
|
335
|
+
if (err instanceof PermissionDeniedError) return toast.error(err.reason ?? 'No permission');
|
|
336
|
+
throw err;
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
`PermissionDeniedError` shape (stable public contract): `{ action: string; reason?: string; subject?: string }`. `action` is a stable kebab-case id (`assertCanCreateConfiguration` → `'create-configuration'`) consumers may pattern-match on — renames are breaking. `subject` **must not** carry the full `StorageToken`, raw tokens, or secrets.
|
|
341
|
+
|
|
342
|
+
## What NOT to Do
|
|
343
|
+
|
|
344
|
+
| Anti-pattern | Why it's wrong | Replacement |
|
|
345
|
+
| ------------------------------------------------ | ------------------------------------------ | ------------------------------------------------- |
|
|
346
|
+
| `fetch('/api/...')` directly | Bypasses auth, middleware, and type safety | `useApiClient()` + `api.*` methods |
|
|
347
|
+
| `import axios from 'axios'` | Not installed; circumvents the SDK layer | `useApiClient()` from `@keboola/api-client-react` |
|
|
348
|
+
| `import { Api } from '@/api'` | Legacy hand-rolled client being removed | `useApiClient()` + typed service client |
|
|
349
|
+
| Importing from `@keboola/api-client/fetchClient` | Internal transport layer, not public API | Use the `clients/` or `sdks/` layer |
|
|
350
|
+
| `enabled: false` for conditional queries | Does not narrow `data` type | `queryFn: !ready ? skipToken : ...` |
|
|
351
|
+
|
|
352
|
+
The `fetch()`, `axios`, and legacy `@/api` bans are mechanically enforced by oxlint — see `apps/kbc-ui/oxlint.config.ts`.
|
|
353
|
+
|
|
354
|
+
## Common Pitfalls
|
|
355
|
+
|
|
356
|
+
**Trailing slashes in base URLs.** `createFetchRequest` strips trailing slashes via `normalizeBaseUrl` at the `baseUrl + path` join, so `https://connection.keboola.com/` no longer produces a double-slash 404 — every client gets this for free. Clients take the plain stack host as `baseUrl` and put the service prefix in the request path (e.g. `management` calls `/manage/...`), so no client hand-builds a composite base URL. Still pass the canonical form (no trailing `/`) to keep the contract clear.
|
|
357
|
+
|
|
358
|
+
**Listing tables by bucket.** The Storage API exposes no `GET /buckets/{id}/tables`, and `GET /tables` takes no `bucketId` param. `api.storage.tables.getTables()` returns every table in the project; filter client-side by `table.bucket?.id` or the `{bucketId}.` prefix in `table.id` (IDs use `{bucketId}.{tableName}`, e.g. `in.c-main.users`).
|
|
359
|
+
|
|
360
|
+
## Service Discovery
|
|
361
|
+
|
|
362
|
+
**Authoritative surface index: [`API-SURFACE.md`](./API-SURFACE.md)** — a compact list of every namespace and method **name** (no signatures), generated from the `KeboolaApi` type by `scripts/gen-surface.mjs`. Read it to confirm a namespace/method exists before calling it — don't guess. For the **full resolved signature**, open the per-namespace detail file it links to, [`surface/<namespace>.md`](./surface) (e.g. `surface/storage.md`) — split per namespace so you load only the slice you need rather than every signature at once. A CI drift check (`surface:check`, wired into the package's `ci-checks`) fails if either goes stale; regenerate with `pnpm --filter @keboola/api-client surface`.
|
|
363
|
+
|
|
364
|
+
The full namespace set is the `KeboolaApi` type in `src/keboola/createApi.ts`. Quick top-level reference (see the index for the complete, current list):
|
|
365
|
+
|
|
366
|
+
```
|
|
367
|
+
api.storage.* api.management.* api.vault.*
|
|
368
|
+
api.queue.* api.dataScience.* api.encryption.*
|
|
369
|
+
api.editor.* api.syncActions.* api.telemetry.*
|
|
370
|
+
api.queryService.* api.chat.* api.ai.*
|
|
371
|
+
api.import.* api.kaiAgent.* api.oauth.*
|
|
372
|
+
api.stream.* api.omnisearch.* api.apps.*
|
|
373
|
+
api.sdk.tag.* api.sdk.storage.*
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
`api.apps` is the data-apps `/v2` App Deployments surface (apps + deployments); `api.dataScience` is the same service's `/v1` surface, which still owns workspaces (`/sandboxes`, `/runtimes`) and the data-app endpoints the UI has not moved off yet.
|
|
377
|
+
|
|
378
|
+
**`hasService('data-science')` is not the availability check for `api.apps`, and neither is `api.apps.healthCheck()`.** Both clients resolve off that one service id, so `api.apps` is live on every stack that advertises it — while `/v2` itself is implemented only where sandboxes-service serves it (canary at the time of writing). Nothing cheap discriminates: `apps` is absent from the service index on every stack including canary; the `/v2/*` routes are scaffolded everywhere (unauthenticated they 401, so the route exists); and `healthCheck()` answers 200 everywhere because `GET /v2/` falls through to the same root handler as `GET /`, down to an `apiDocs` pointing at the v1 swagger. The one thing that differs is the implementation: off canary, a real call answers `501 {"error":"This endpoint is not implemented yet."}` — measured on three production stacks (AJDA-3140). So gate a data-apps feature on a real call's 501, or on a stack feature flag once one exists.
|
|
379
|
+
|
|
380
|
+
Clients backing optional stack services (vault, queue, …) throw `ServiceUnavailableError` if absent from the current stack — check `api.context.stack.hasService(...)` before assuming a namespace exists.
|
|
381
|
+
|
|
382
|
+
**Liveness: every service client exposes a root-level `healthCheck()`** (all but `telemetry`, which has no such endpoint). It resolves with the service's payload when up and throws like any other call when not, and it needs no session — every one of these endpoints answers unauthenticated, so a probe works before login and is indifferent to whether a token rides along. Probe a service that way rather than by calling a real endpoint and interpreting the failure. **A 200 means up and a throw means down — that is the whole contract.** The payload is incidental, so **never hand-roll a response type** to make it look useful. Adding a client means adding its `healthCheck` too, and which client you probe through follows from the spec:
|
|
383
|
+
|
|
384
|
+
- the service's spec declares the probe path → **probe through the client's own OpenAPI client** (`client.get('/health-check', {}, { signal })`). The return type comes from the spec for free — no type argument, no alias in `types.ts`, and no generic client to construct. Five do today: `ai`, `editor`, `import`, `chat` (which probes `/ping`) and `apps` (which probes `/`, the only unauthenticated root the `/v2` surface declares).
|
|
385
|
+
- it doesn't → fall back to a generic fetch client over the service `baseUrl` and **pass no type argument.** The payload resolves as `unknown`, which is honest: callers only need the 200.
|
|
386
|
+
|
|
387
|
+
Both clients run the same middleware chain; the OpenAPI one additionally sends auth headers, which is fine — these endpoints answer the same with a valid token, a bogus one, or none.
|
|
388
|
+
|
|
389
|
+
Don't invent a shape for the second case. These specs are uneven and, where present, often wrong — `vault` declares the path POST-only though a GET answers 200; `metastore` and `queryService` type the body as a bare index signature; `dataScience` and `oauth` declare a service-info shape with no `status` field at all, despite really answering `{"status":"ok"}`. A client moves to a generated type only once its spec matches what the endpoint actually returns, which you confirm by probing it, not by reading the spec.
|
|
390
|
+
|
|
391
|
+
## Off-session clients: the Developer Portal (apps-api)
|
|
392
|
+
|
|
393
|
+
`apps-api.keboola.com` (the Developer Portal / `components.keboola.com` backend) authenticates with its
|
|
394
|
+
**own Cognito pool**, issuing a token trio — `token` (id), `accessToken`, `refreshToken` — not a
|
|
395
|
+
Connection storage token. `createKeboola`'s session cannot drive it: driving to ready runs
|
|
396
|
+
`tokens.verify()` against Connection, and `setProjectAsync` is meaningless. So it is not registered in
|
|
397
|
+
`createServiceClients.ts` and never appears on the `api` proxy — `api.developerPortal` does not exist.
|
|
398
|
+
|
|
399
|
+
Two layers, as everywhere else in this package:
|
|
400
|
+
|
|
401
|
+
| Layer | Subpath | What it is |
|
|
402
|
+
| ---------- | ------------------------------------------- | ---------------------------------------------------------------- |
|
|
403
|
+
| **SDK** | `@keboola/api-client/sdk/developerPortal` | `createDeveloperPortalSdk` → `{ api, session }`. **Start here.** |
|
|
404
|
+
| **Client** | `@keboola/api-client/developerPortal` | One method per endpoint, no state |
|
|
405
|
+
| Types | `@keboola/api-client/developerPortal/types` | Response and `Input` types |
|
|
406
|
+
|
|
407
|
+
```ts
|
|
408
|
+
import { createDeveloperPortalSdk } from '@keboola/api-client/sdk/developerPortal';
|
|
409
|
+
import { isMfaChallengeResponse } from '@keboola/api-client/developerPortal';
|
|
410
|
+
import type { App, Vendor } from '@keboola/api-client/developerPortal/types';
|
|
411
|
+
|
|
412
|
+
const { api, session } = createDeveloperPortalSdk({
|
|
413
|
+
baseUrl: 'https://apps-api.keboola.com',
|
|
414
|
+
tokens: readPersistedTokens(),
|
|
415
|
+
onTokensChange: persistTokens, // the SDK never touches storage
|
|
416
|
+
onSessionExpired: () => redirectToLogin(),
|
|
417
|
+
});
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
An endpoint goes on the client; anything that has to _know a token over time_ goes in the SDK, which
|
|
421
|
+
owns the store, `credential.ts`, `middleware.ts` and `tokenExpiry.ts` — the analogue of
|
|
422
|
+
`keboola/bearer/` for Connection. The client alone covers every operation the spec marks `security: []`.
|
|
423
|
+
|
|
424
|
+
Three things about it are unusual:
|
|
425
|
+
|
|
426
|
+
- **Generated from the spec, like every other client.** `https://apps-api.keboola.com/docs/openapi.yaml`
|
|
427
|
+
is registered in `redocly.yaml`, so `pnpm gen:types` refreshes
|
|
428
|
+
`developerPortal/__generated__/schema.d.ts` and `types.ts` derives from it. **The spec is the source of
|
|
429
|
+
truth** — if it is wrong, fix it in `keboola/developer-portal` and regenerate, rather than
|
|
430
|
+
hand-writing a parallel shape here.
|
|
431
|
+
- **No `Bearer` prefix** — the spec's security schemes are `type: apiKey` and say "passed verbatim", so
|
|
432
|
+
`createBearerAuthMiddleware` is not reusable and the SDK ships `createDeveloperPortalAuthMiddleware`.
|
|
433
|
+
- **Two fetch clients.** The authenticated one carries the auth middleware, which stamps the **id**
|
|
434
|
+
token. The other carries none and backs the `security: []` operations plus the four calls that supply
|
|
435
|
+
their own `Authorization` (`GET /auth/token` takes the refresh token, `POST /auth/logout` the access
|
|
436
|
+
token, and `/auth/mfa` + `/auth/mfa/confirm` the id token alongside an access token in the **body**).
|
|
437
|
+
Those four take the token as an argument — the client holds no session — and the SDK binds them from
|
|
438
|
+
the store, so `api.auth.logout()` needs nothing from the caller. Keeping `/auth/mfa*` off the
|
|
439
|
+
authenticated client is what keeps them out of refresh-and-replay: restamping a header cannot fix a
|
|
440
|
+
stale token in a body.
|
|
441
|
+
|
|
442
|
+
## Testing with `@keboola/api-fixtures`
|
|
443
|
+
|
|
444
|
+
`@keboola/api-fixtures` provides typed, endpoint-keyed fixtures so tests don't hand-roll response shapes. Early today (storage tables only); extend it as more services need coverage.
|
|
445
|
+
|
|
446
|
+
```ts
|
|
447
|
+
import { fixtures, getTable, listTables, tableFixtures } from '@keboola/api-fixtures';
|
|
448
|
+
import type { Table, TableDetail } from '@keboola/api-fixtures';
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
To mock the client itself, mock at the module boundary with `vi.mock` against `@keboola/api-client` or the `useApiClient` hook.
|
|
452
|
+
|
|
453
|
+
## Authoring types — the generated schema is the source
|
|
454
|
+
|
|
455
|
+
Every request and response shape starts from `__generated__/schema.d.ts`, never from reading a JSON payload and transcribing it. Derive with the `Openapi*Type` helpers (`OpenapiPathType`, `OpenapiQueryType`, `OpenapiBodyType`, `OpenapiReturnType`, `OpenapiFormDataType`, all from `../../fetchClient`) over an **inlined** `paths['…']['method']`, in the namespace's own `types.ts`:
|
|
456
|
+
|
|
457
|
+
```ts
|
|
458
|
+
import type { OpenapiBodyType, OpenapiPathType } from '../../../fetchClient';
|
|
459
|
+
import type { paths } from '../__generated__/schema';
|
|
460
|
+
|
|
461
|
+
export type CreateWidgetPath = OpenapiPathType<paths['/v2/storage/widgets']['post']>;
|
|
462
|
+
export type CreateWidgetSchemaBody = OpenapiBodyType<paths['/v2/storage/widgets']['post']>;
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
- **Repeat the full `paths['…']` in every type.** Don't introduce an intermediate `type WidgetEndpoint = paths['…']` to shorten them — the whole path is what makes the type greppable against the spec. Group the aliases that share a path together instead.
|
|
466
|
+
- **Never reference `components['schemas'][…]` from a client file.** A cast in `foo.ts` points at a named alias in `foo/types.ts`; the generated namespace is only ever touched by that alias.
|
|
467
|
+
- **Never hardcode what the generator emitted.** `body as Record<string, never>` freezes today's broken spec into our source. Alias it (`OpenapiBodyType<paths[…]>`) and cast to the alias, so the day the spec grows a real body the cast either becomes unnecessary or fails loudly.
|
|
468
|
+
|
|
469
|
+
### Tighten with a hybrid, don't trust the document
|
|
470
|
+
|
|
471
|
+
These specs are routinely looser than the API: fields the server requires come through optional and nullable, and free-form objects render as `Record<string, never>`. So derive, then re-tighten the parts we rely on — keeping the enums spec-derived so they can't drift:
|
|
472
|
+
|
|
473
|
+
```ts
|
|
474
|
+
export type BackendType = NonNullable<CreateWidgetSchemaBody['backend']>;
|
|
475
|
+
|
|
476
|
+
export type CreateWidgetBody = Omit<CreateWidgetSchemaBody, 'backend' | 'size'> & {
|
|
477
|
+
backend: BackendType; // required in practice, optional in the spec
|
|
478
|
+
size: number;
|
|
479
|
+
};
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
The hybrid is the default because it fails in the right direction — new spec fields arrive for free, while the constraints we actually depend on stay enforced. Note in a comment _which_ fields you tightened and why, since the next reader will otherwise "fix" it back to the spec.
|
|
483
|
+
|
|
484
|
+
Where the spec is outright wrong or stubs the operation (`content?: never` on the success response, a `Record<string, never>` body), keep the hand-authored type and bridge with **`as`** at the call site. That is the sanctioned use of `as` in this package — it records a known spec defect at one line rather than spreading a wrong type through consumers. Prefer a single `as`; reach for `as unknown as` only when TypeScript refuses the direct conversion.
|
|
485
|
+
|
|
486
|
+
### The `*Input` pattern
|
|
487
|
+
|
|
488
|
+
A public method takes **one** object. Compose it from the path and body aliases rather than spelling an intersection at the signature:
|
|
489
|
+
|
|
490
|
+
```ts
|
|
491
|
+
export type CreateWidgetInput = CreateWidgetPath & CreateWidgetBody;
|
|
492
|
+
|
|
493
|
+
const createWidget = async ({ widgetId, branchId, ...body }: CreateWidgetInput) => { … };
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
Name them `<Verb><Entity>Path` / `…Query` / `…Body` / `…Input`, with `…SchemaBody` / `…SchemaQuery` reserved for the raw spec-derived alias when a tightened sibling shares the name. Because `Input` is built from the spec's `Path`, path parameters keep the spec's own names (`configurationId`, not a local `configId`) — that keeps a call site diffable against the endpoint it hits.
|
|
497
|
+
|
|
498
|
+
### A method that returns a job ends in `Async`
|
|
499
|
+
|
|
500
|
+
If the resolved value is a `Job` — the request only _enqueues_ the work — the method name **must** end in `Async`: `deleteBucketAsync`, `importAsync`, `createSnapshotAsync`. Never `*Job` (that names the return type, not what the call does) and never a bare verb, which reads like the work is finished when the promise resolves.
|
|
501
|
+
|
|
502
|
+
The suffix is the only thing at a call site that says "you are not done yet — poll this." Anything that returns a job needs a follow-up (`jobs.getJob`, `pollStorageJob`, a `jobPoller`), and a bare name is what makes a caller forget. Correspondingly, **don't** use `Async` on a method that resolves to the finished resource; every method here is `async` in the JavaScript sense, so the suffix would carry no information.
|
|
503
|
+
|
|
504
|
+
```ts
|
|
505
|
+
const deleteBucketAsync = async (…): Promise<Job<'bucketDelete'>> => { … }; // enqueues
|
|
506
|
+
const getBucket = async (…): Promise<BucketDetail> => { … }; // done on resolve
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
One shape needs a judgement call: an endpoint that answers _either_ the resource or a job depending on a parameter (`createAliasTable` → `Table | CreateAliasJob`). Prefer splitting it into a sync method and an `*Async` sibling; where that isn't worth it, leave the bare name and say so in a comment, because a caller that must branch on the response can't be told anything useful by the name alone.
|
|
510
|
+
|
|
511
|
+
### A method that waits for its job ends in `AndWait`
|
|
512
|
+
|
|
513
|
+
The sibling of an `*Async` method that also waits for the enqueued job to finish ends in `AndWait`: `createTableAndWait`, `importAndWait`, `unshareBucketAndWait`. It lives on the client, next to the `*Async` it mirrors.
|
|
514
|
+
|
|
515
|
+
| What the call does | Name shape | Example |
|
|
516
|
+
| ------------------------------------------------ | ---------- | --------------------------- |
|
|
517
|
+
| returns the finished resource in one request | bare verb | `getBucket`, `deleteBucket` |
|
|
518
|
+
| enqueues the work and hands back a `Job` to poll | `*Async` | `createTableAsync` |
|
|
519
|
+
| enqueues the work and polls it to completion | `*AndWait` | `createTableAndWait` |
|
|
520
|
+
|
|
521
|
+
- **Never a bare verb.** `buckets.deleteBucket` is a real single-request endpoint sitting next to `deleteBucketAsync`, so a bare name would mean "one request" on one resource and "poll loop" on the next.
|
|
522
|
+
- **Never `Sync`.** In JavaScript that suffix promises no yielding (`readFileSync`); this is the method that yields most.
|
|
523
|
+
- **Never a `{ wait: true }` option.** Both branches return `Job` — the same TS type — so nothing discriminates work that is merely enqueued from work that is done, and the name is the only signal a call site gets.
|
|
524
|
+
- **Never `AndPoll`.** That names the transport, not the contract. A route that later grows long-poll or SSE turns every `AndPoll` into a lie.
|
|
525
|
+
|
|
526
|
+
It is a suffix, not a prefix, because a suffix means "same endpoint, different completion contract" — the variant shares its sibling's prefix and so sorts beside it in autocomplete, where a `waitForTableCreate` would sort nowhere near `createTableAsync`.
|
|
527
|
+
|
|
528
|
+
Storage's wait helpers currently live in `sdks/storage` under bare-verb names (`createTable`); the clients are where new ones belong.
|
|
529
|
+
|
|
530
|
+
**What an `*AndWait` resolves with is not settled** — the job, its `results`, and whether a failed job throws are all open. Don't document a return contract until it is decided.
|
|
531
|
+
|
|
532
|
+
## Extending the SDK (endpoint not in the client yet)
|
|
533
|
+
|
|
534
|
+
When a backend endpoint you need has no method on any client, the sanctioned path is to **add it to `@keboola/api-client` first, then consume it** — never drop to `fetch()` in the app. A one-off `fetch()` skips the middleware chain (storage-token, auth, retry, logging), the typed error guards, and `signal` forwarding, and it can't be mocked with `@keboola/api-fixtures`. The [What NOT to Do](#what-not-to-do) `fetch()` ban is enforced by oxlint precisely so this stays the only route.
|
|
535
|
+
|
|
536
|
+
Decision:
|
|
537
|
+
|
|
538
|
+
| Situation | Do this |
|
|
539
|
+
| ------------------------------------------------------ | ----------------------------------------------------------------------------- |
|
|
540
|
+
| Endpoint belongs to an existing service (`storage`, …) | Add the method to that client; cover it with an `@keboola/api-fixtures` entry |
|
|
541
|
+
| Endpoint belongs to a brand-new service | Add a new client/namespace under `src/clients/<x>/`, then wire its sub-path |
|
|
542
|
+
| Multi-client orchestration, or any session/token state | Add (or extend) an `sdks/` SDK that composes the clients |
|
|
543
|
+
|
|
544
|
+
### Eight rules for a new client or SDK
|
|
545
|
+
|
|
546
|
+
Every one of these was a round of review on a single PR (#7953). They are not style
|
|
547
|
+
preferences — each cost a rewrite. Work them in order; the first three decide the shape of
|
|
548
|
+
everything after.
|
|
549
|
+
|
|
550
|
+
**1. Find the spec before you write a single type.** Probe the service directly —
|
|
551
|
+
`/docs/openapi.yaml`, `/docs/swagger.yaml`, `/openapi.json`, `/api/docs` — and only then conclude
|
|
552
|
+
there isn't one. A README, a wiki page or an Apiary link is not evidence of absence. A
|
|
553
|
+
hand-written client on a service that turned out to publish a spec is a full rewrite, and the
|
|
554
|
+
generated types immediately found 15 wrong path placeholders, a `healthCheck` on the wrong
|
|
555
|
+
endpoint, and 12 operations that had simply been missed.
|
|
556
|
+
|
|
557
|
+
**2. The spec is the source of truth, including where it is wrong.** When it disagrees with
|
|
558
|
+
production, **fix it in the service's repo** — do not carry a corrected shape here. Overlays look
|
|
559
|
+
cheap and are not: they force an `as` cast at every call site (23 of them, in that PR), and they
|
|
560
|
+
silently absorb the real bugs the generated types would have caught. Verify the divergence against
|
|
561
|
+
production **and** against the handler that builds the response before claiming it, then open the
|
|
562
|
+
backend PR. To prove a spec fix before it deploys: run `openapi-typescript` over the fixed file and
|
|
563
|
+
`oxfmt` the result, having first round-tripped the _live_ spec the same way and reproduced the
|
|
564
|
+
committed schema byte-for-byte.
|
|
565
|
+
|
|
566
|
+
**3. Client and SDK are different things, and the split is not negotiable.** A client is one method
|
|
567
|
+
per endpoint, holds **no state and never holds a token** — if it takes a credential, it is not a
|
|
568
|
+
client. Anything that knows a token over time (a store, refresh-and-replay, expiry) belongs in
|
|
569
|
+
`sdks/`, the way `keboola/bearer/` does for Connection. A client that needs auth takes a
|
|
570
|
+
`MiddlewareFn`, not an `auth: AuthStrategy` and not a credential; the SDK supplies it. Endpoints
|
|
571
|
+
that authenticate with something other than the default credential take that token **as an
|
|
572
|
+
argument** and the SDK binds it, so the consumer surface stays argument-free.
|
|
573
|
+
|
|
574
|
+
**4. Naming — read [`API-SURFACE.md`](./API-SURFACE.md) before inventing a shape.**
|
|
575
|
+
|
|
576
|
+
- **`get*`, never `list*`.** 180 methods start with `get`, 7 with `list`, and those 7 are strays.
|
|
577
|
+
A collection read is the plural noun: `getBuckets`, `getDeletedProjects`, `getAllFeatures`.
|
|
578
|
+
`delete*` (62) over `remove*` (11), except when unlinking a relation rather than destroying a row.
|
|
579
|
+
- **One level of sub-namespace, and the method carries the noun** — `buckets.getBucket`,
|
|
580
|
+
`currentUser.getProjectInvitations`. Not `buckets.get`, and not `admin.apps.get`. If a namespace
|
|
581
|
+
is growing a second level, add a sibling namespace instead. (`auth.mfa.totp.*` is the one
|
|
582
|
+
exception in the package; don't copy it.)
|
|
583
|
+
- Query and input types follow their method: `GetAppsQuery`, not `ListAppsQuery`.
|
|
584
|
+
|
|
585
|
+
**5. Never send a credential to an endpoint the spec marks `security: []`.** Those responses are
|
|
586
|
+
public and cacheable; a token on one buys nothing and leaks into any shared cache in front of it.
|
|
587
|
+
When the spec splits its operations, build **two fetch clients** — one carrying the auth
|
|
588
|
+
middleware, one carrying none — and put each endpoint on the side the spec says.
|
|
589
|
+
|
|
590
|
+
**6. Test the logic, not the transport.** A test asserting that a method called its URL, or
|
|
591
|
+
substituted its path parameters, tests the generated client and the mock server. Delete it. Test
|
|
592
|
+
where a decision lives: which credential an endpoint gets, refresh-and-replay, dedupe, what happens
|
|
593
|
+
when the session is cleared mid-rotation. If the generated `paths` type already makes a mistake a
|
|
594
|
+
compile error, a runtime assertion of the same thing proves nothing.
|
|
595
|
+
|
|
596
|
+
**7. Comment what the code cannot say, and nothing else.** Package median is **9%** of lines,
|
|
597
|
+
p90 32%; `vaultClient.ts` and `queueClient.ts` are at 0%. Past ~20% you are narrating the code. Keep
|
|
598
|
+
the comment that explains why sign-out has to win a race against an in-flight rotation; delete the
|
|
599
|
+
one that says a method issues a GET.
|
|
600
|
+
|
|
601
|
+
**8. Read your own diff before pushing.** `git add -A` swallows build output when a `.gitignore`
|
|
602
|
+
is not on the branch you switched to. Stage explicit paths, and check the pushed file list against
|
|
603
|
+
the GitHub API rather than trusting the local working tree.
|
|
604
|
+
|
|
605
|
+
A new client/namespace means touching four places that must stay in lock-step — **guarded by the [`subpathExportParity` test](./src/subpathExportParity.test.ts)**, so forgetting one fails CI instead of silently breaking resolution:
|
|
606
|
+
|
|
607
|
+
1. `tsdown.config.ts` — add `<x>/index` and (if you ship a `types.ts`) `<x>/types` build entries
|
|
608
|
+
2. `package.json` `exports` — add `./<x>` and `./<x>/types`
|
|
609
|
+
3. `package.json` `typesVersions` — add `<x>` and `<x>/types`
|
|
610
|
+
4. `src/keboola/createServiceClients.ts` — register the client in the registry with `.add({ serviceId, clientName, clientFn })` (+ `src/keboola/createMiddlewareFor.ts` for its `ServiceClientName` entry and any bespoke middleware)
|
|
611
|
+
|
|
612
|
+
Full mechanical steps (redocly registration, `pnpm gen:types`, file templates) live in [`README.md` → Adding a New OpenAPI Client](./README.md#adding-a-new-openapi-client). Add typed fixtures to `@keboola/api-fixtures` alongside the client so consumers can test against it.
|
|
613
|
+
|
|
614
|
+
**Worked example — the `auth` client.** `packages/api-client/src/clients/auth/*` (`authClient.ts`, `pkce.ts`, `index.ts`, `types.ts`) is a self-contained new service added this way: it exposes `./auth` + `./auth/types` sub-paths and is surfaced by `src/keboola/createApi.ts`. Read it as the reference shape for a new client rather than copying boilerplate. **Bearer auth lives in `keboola/bearer/`, not the auth client**, since it's specific to the bearer engine: `credential.ts` is a token provider (`getAccessToken({ forceRefresh })` returns a valid token, refreshing — deduped — when near expiry or forced), and `middleware.ts` is a thin policy that on every request asks the credential for a token and stamps the `Authorization` header, and on 401 force-refreshes and replays once. Session-expiry is latched (fire-once, re-armed per session) in `createConfig.notifyExpired`, not the credential — the credential and middleware are long-lived singletons. The middleware holds no token and reads no config — all token state is in the credential, whose `getToken` reads live from `config` so a rotation is picked up without rebuilding. See `keboola/bearer/keboola.ts` for the wiring.
|
|
615
|
+
|
|
616
|
+
## Development
|
|
617
|
+
|
|
618
|
+
SDK internals — layered architecture, middleware authoring, adding a new client, OpenAPI type generation, `redocly.yaml`, ownership/versioning — live in the package docs, not here:
|
|
619
|
+
|
|
620
|
+
- [`README.md` → Architecture](./README.md#architecture), [Middleware](./README.md#middleware), [Service Clients](./README.md#service-clients), [Utilities](./README.md#utilities)
|
|
621
|
+
- [`README.md` → Contributing](./README.md#contributing) — adding an OpenAPI/generic client, type generation, `redocly.yaml`
|
|
622
|
+
- [`README.md` → Ownership](./README.md#ownership) — UI team, npm Trusted Publisher, Changesets
|
|
623
|
+
- [`docs/regenerate-api-types.md`](./docs/regenerate-api-types.md) — regenerating types from a local backend
|