@keboola/api-client 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (265) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +456 -0
  3. package/dist/ai/index.cjs +203 -0
  4. package/dist/ai/index.cjs.map +1 -0
  5. package/dist/ai/index.d.cts +35 -0
  6. package/dist/ai/index.d.ts +35 -0
  7. package/dist/ai/index.js +197 -0
  8. package/dist/ai/index.js.map +1 -0
  9. package/dist/ai/types.cjs +4 -0
  10. package/dist/ai/types.cjs.map +1 -0
  11. package/dist/ai/types.d.cts +2 -0
  12. package/dist/ai/types.d.ts +2 -0
  13. package/dist/ai/types.js +3 -0
  14. package/dist/ai/types.js.map +1 -0
  15. package/dist/assets/index.cjs +182 -0
  16. package/dist/assets/index.cjs.map +1 -0
  17. package/dist/assets/index.d.cts +9 -0
  18. package/dist/assets/index.d.ts +9 -0
  19. package/dist/assets/index.js +176 -0
  20. package/dist/assets/index.js.map +1 -0
  21. package/dist/assets/types.cjs +4 -0
  22. package/dist/assets/types.cjs.map +1 -0
  23. package/dist/assets/types.d.cts +8 -0
  24. package/dist/assets/types.d.ts +8 -0
  25. package/dist/assets/types.js +3 -0
  26. package/dist/assets/types.js.map +1 -0
  27. package/dist/authMiddleware-BTFSCMTE.d.ts +11 -0
  28. package/dist/authMiddleware-BteBe1Bt.d.cts +11 -0
  29. package/dist/chat/index.cjs +428 -0
  30. package/dist/chat/index.cjs.map +1 -0
  31. package/dist/chat/index.d.cts +51 -0
  32. package/dist/chat/index.d.ts +51 -0
  33. package/dist/chat/index.js +422 -0
  34. package/dist/chat/index.js.map +1 -0
  35. package/dist/chat/suggestions.cjs +158 -0
  36. package/dist/chat/suggestions.cjs.map +1 -0
  37. package/dist/chat/suggestions.d.cts +437 -0
  38. package/dist/chat/suggestions.d.ts +437 -0
  39. package/dist/chat/suggestions.js +140 -0
  40. package/dist/chat/suggestions.js.map +1 -0
  41. package/dist/chat/types.cjs +10 -0
  42. package/dist/chat/types.cjs.map +1 -0
  43. package/dist/chat/types.d.cts +3 -0
  44. package/dist/chat/types.d.ts +3 -0
  45. package/dist/chat/types.js +8 -0
  46. package/dist/chat/types.js.map +1 -0
  47. package/dist/createGenericFetchClient-CLUzu-jY.d.cts +18 -0
  48. package/dist/createGenericFetchClient-DEakI3F1.d.ts +18 -0
  49. package/dist/createOpenapiFetchClient-CpXmAIFB.d.cts +24 -0
  50. package/dist/createOpenapiFetchClient-_sm4bchL.d.ts +24 -0
  51. package/dist/dataScience/index.cjs +416 -0
  52. package/dist/dataScience/index.cjs.map +1 -0
  53. package/dist/dataScience/index.d.cts +191 -0
  54. package/dist/dataScience/index.d.ts +191 -0
  55. package/dist/dataScience/index.js +388 -0
  56. package/dist/dataScience/index.js.map +1 -0
  57. package/dist/dataScience/types.cjs +4 -0
  58. package/dist/dataScience/types.cjs.map +1 -0
  59. package/dist/dataScience/types.d.cts +2 -0
  60. package/dist/dataScience/types.d.ts +2 -0
  61. package/dist/dataScience/types.js +3 -0
  62. package/dist/dataScience/types.js.map +1 -0
  63. package/dist/editor/index.cjs +275 -0
  64. package/dist/editor/index.cjs.map +1 -0
  65. package/dist/editor/index.d.cts +172 -0
  66. package/dist/editor/index.d.ts +172 -0
  67. package/dist/editor/index.js +269 -0
  68. package/dist/editor/index.js.map +1 -0
  69. package/dist/editor/types.cjs +4 -0
  70. package/dist/editor/types.cjs.map +1 -0
  71. package/dist/editor/types.d.cts +2 -0
  72. package/dist/editor/types.d.ts +2 -0
  73. package/dist/editor/types.js +3 -0
  74. package/dist/editor/types.js.map +1 -0
  75. package/dist/encryption/index.cjs +192 -0
  76. package/dist/encryption/index.cjs.map +1 -0
  77. package/dist/encryption/index.d.cts +14 -0
  78. package/dist/encryption/index.d.ts +14 -0
  79. package/dist/encryption/index.js +186 -0
  80. package/dist/encryption/index.js.map +1 -0
  81. package/dist/encryption/types.cjs +4 -0
  82. package/dist/encryption/types.cjs.map +1 -0
  83. package/dist/encryption/types.d.cts +8 -0
  84. package/dist/encryption/types.d.ts +8 -0
  85. package/dist/encryption/types.js +3 -0
  86. package/dist/encryption/types.js.map +1 -0
  87. package/dist/import/index.cjs +198 -0
  88. package/dist/import/index.cjs.map +1 -0
  89. package/dist/import/index.d.cts +9 -0
  90. package/dist/import/index.d.ts +9 -0
  91. package/dist/import/index.js +192 -0
  92. package/dist/import/index.js.map +1 -0
  93. package/dist/index.cjs +3910 -0
  94. package/dist/index.cjs.map +1 -0
  95. package/dist/index.d.cts +3108 -0
  96. package/dist/index.d.ts +3108 -0
  97. package/dist/index.js +3858 -0
  98. package/dist/index.js.map +1 -0
  99. package/dist/keboolaUID-D1DGSbge.d.cts +19 -0
  100. package/dist/keboolaUID-D1DGSbge.d.ts +19 -0
  101. package/dist/management/index.cjs +872 -0
  102. package/dist/management/index.cjs.map +1 -0
  103. package/dist/management/index.d.cts +440 -0
  104. package/dist/management/index.d.ts +440 -0
  105. package/dist/management/index.js +865 -0
  106. package/dist/management/index.js.map +1 -0
  107. package/dist/management/types.cjs +4 -0
  108. package/dist/management/types.cjs.map +1 -0
  109. package/dist/management/types.d.cts +9 -0
  110. package/dist/management/types.d.ts +9 -0
  111. package/dist/management/types.js +3 -0
  112. package/dist/management/types.js.map +1 -0
  113. package/dist/metastore/index.cjs +339 -0
  114. package/dist/metastore/index.cjs.map +1 -0
  115. package/dist/metastore/index.d.cts +52 -0
  116. package/dist/metastore/index.d.ts +52 -0
  117. package/dist/metastore/index.js +333 -0
  118. package/dist/metastore/index.js.map +1 -0
  119. package/dist/metastore/types.cjs +4 -0
  120. package/dist/metastore/types.cjs.map +1 -0
  121. package/dist/metastore/types.d.cts +2 -0
  122. package/dist/metastore/types.d.ts +2 -0
  123. package/dist/metastore/types.js +3 -0
  124. package/dist/metastore/types.js.map +1 -0
  125. package/dist/queryService/index.cjs +250 -0
  126. package/dist/queryService/index.cjs.map +1 -0
  127. package/dist/queryService/index.d.cts +39 -0
  128. package/dist/queryService/index.d.ts +39 -0
  129. package/dist/queryService/index.js +244 -0
  130. package/dist/queryService/index.js.map +1 -0
  131. package/dist/queryService/types.cjs +4 -0
  132. package/dist/queryService/types.cjs.map +1 -0
  133. package/dist/queryService/types.d.cts +2 -0
  134. package/dist/queryService/types.d.ts +2 -0
  135. package/dist/queryService/types.js +3 -0
  136. package/dist/queryService/types.js.map +1 -0
  137. package/dist/queue/index.cjs +192 -0
  138. package/dist/queue/index.cjs.map +1 -0
  139. package/dist/queue/index.d.cts +133 -0
  140. package/dist/queue/index.d.ts +133 -0
  141. package/dist/queue/index.js +186 -0
  142. package/dist/queue/index.js.map +1 -0
  143. package/dist/queue/types.cjs +4 -0
  144. package/dist/queue/types.cjs.map +1 -0
  145. package/dist/queue/types.d.cts +2 -0
  146. package/dist/queue/types.d.ts +2 -0
  147. package/dist/queue/types.js +3 -0
  148. package/dist/queue/types.js.map +1 -0
  149. package/dist/sdk/storage/index.cjs +96 -0
  150. package/dist/sdk/storage/index.cjs.map +1 -0
  151. package/dist/sdk/storage/index.d.cts +24 -0
  152. package/dist/sdk/storage/index.d.ts +24 -0
  153. package/dist/sdk/storage/index.js +94 -0
  154. package/dist/sdk/storage/index.js.map +1 -0
  155. package/dist/sdk/tag/index.cjs +210 -0
  156. package/dist/sdk/tag/index.cjs.map +1 -0
  157. package/dist/sdk/tag/index.d.cts +25 -0
  158. package/dist/sdk/tag/index.d.ts +25 -0
  159. package/dist/sdk/tag/index.js +208 -0
  160. package/dist/sdk/tag/index.js.map +1 -0
  161. package/dist/sdk/tag/types.cjs +4 -0
  162. package/dist/sdk/tag/types.cjs.map +1 -0
  163. package/dist/sdk/tag/types.d.cts +30 -0
  164. package/dist/sdk/tag/types.d.ts +30 -0
  165. package/dist/sdk/tag/types.js +3 -0
  166. package/dist/sdk/tag/types.js.map +1 -0
  167. package/dist/status/index.cjs +178 -0
  168. package/dist/status/index.cjs.map +1 -0
  169. package/dist/status/index.d.cts +10 -0
  170. package/dist/status/index.d.ts +10 -0
  171. package/dist/status/index.js +172 -0
  172. package/dist/status/index.js.map +1 -0
  173. package/dist/status/types.cjs +4 -0
  174. package/dist/status/types.cjs.map +1 -0
  175. package/dist/status/types.d.cts +19 -0
  176. package/dist/status/types.d.ts +19 -0
  177. package/dist/status/types.js +3 -0
  178. package/dist/status/types.js.map +1 -0
  179. package/dist/storage/index.cjs +1021 -0
  180. package/dist/storage/index.cjs.map +1 -0
  181. package/dist/storage/index.d.cts +12 -0
  182. package/dist/storage/index.d.ts +12 -0
  183. package/dist/storage/index.js +1014 -0
  184. package/dist/storage/index.js.map +1 -0
  185. package/dist/storage/types.cjs +4 -0
  186. package/dist/storage/types.cjs.map +1 -0
  187. package/dist/storage/types.d.cts +10976 -0
  188. package/dist/storage/types.d.ts +10976 -0
  189. package/dist/storage/types.js +3 -0
  190. package/dist/storage/types.js.map +1 -0
  191. package/dist/storageClient-DPLh_p0V.d.cts +608 -0
  192. package/dist/storageClient-YVWer22Y.d.ts +608 -0
  193. package/dist/syncActions/index.cjs +366 -0
  194. package/dist/syncActions/index.cjs.map +1 -0
  195. package/dist/syncActions/index.d.cts +94 -0
  196. package/dist/syncActions/index.d.ts +94 -0
  197. package/dist/syncActions/index.js +341 -0
  198. package/dist/syncActions/index.js.map +1 -0
  199. package/dist/syncActions/types.cjs +4 -0
  200. package/dist/syncActions/types.cjs.map +1 -0
  201. package/dist/syncActions/types.d.cts +261 -0
  202. package/dist/syncActions/types.d.ts +261 -0
  203. package/dist/syncActions/types.js +3 -0
  204. package/dist/syncActions/types.js.map +1 -0
  205. package/dist/telemetry/index.cjs +189 -0
  206. package/dist/telemetry/index.cjs.map +1 -0
  207. package/dist/telemetry/index.d.cts +13 -0
  208. package/dist/telemetry/index.d.ts +13 -0
  209. package/dist/telemetry/index.js +183 -0
  210. package/dist/telemetry/index.js.map +1 -0
  211. package/dist/telemetry/types.cjs +4 -0
  212. package/dist/telemetry/types.cjs.map +1 -0
  213. package/dist/telemetry/types.d.cts +12 -0
  214. package/dist/telemetry/types.d.ts +12 -0
  215. package/dist/telemetry/types.js +3 -0
  216. package/dist/telemetry/types.js.map +1 -0
  217. package/dist/types-B51cQMrX.d.ts +1408 -0
  218. package/dist/types-B7k8S4ki.d.ts +1520 -0
  219. package/dist/types-BNQK_jR_.d.cts +1520 -0
  220. package/dist/types-BY0tjg2Q.d.ts +1079 -0
  221. package/dist/types-BeShtGlc.d.cts +8591 -0
  222. package/dist/types-BeShtGlc.d.ts +8591 -0
  223. package/dist/types-BjrNNn5I.d.ts +1643 -0
  224. package/dist/types-C-bd4ArM.d.cts +1079 -0
  225. package/dist/types-C7mpAfq-.d.cts +64 -0
  226. package/dist/types-C7mpAfq-.d.ts +64 -0
  227. package/dist/types-CGMJT3JL.d.ts +943 -0
  228. package/dist/types-CRSKcua9.d.cts +1314 -0
  229. package/dist/types-DJ6nbNq5.d.cts +1643 -0
  230. package/dist/types-DJkU9gvB.d.cts +943 -0
  231. package/dist/types-DYMMsuU0.d.cts +78 -0
  232. package/dist/types-DYMMsuU0.d.ts +78 -0
  233. package/dist/types-Dg1tEsVR.d.cts +17 -0
  234. package/dist/types-Dg1tEsVR.d.ts +17 -0
  235. package/dist/types-DgaMV8FF.d.cts +60 -0
  236. package/dist/types-DgaMV8FF.d.ts +60 -0
  237. package/dist/types-Dws8mFNY.d.cts +1408 -0
  238. package/dist/types-cH0_hkCW.d.ts +1314 -0
  239. package/dist/utils-BNQZiNOu.d.ts +1657 -0
  240. package/dist/utils-DE09pDTi.d.cts +1657 -0
  241. package/dist/vault/index.cjs +225 -0
  242. package/dist/vault/index.cjs.map +1 -0
  243. package/dist/vault/index.d.cts +26 -0
  244. package/dist/vault/index.d.ts +26 -0
  245. package/dist/vault/index.js +219 -0
  246. package/dist/vault/index.js.map +1 -0
  247. package/dist/vault/types.cjs +4 -0
  248. package/dist/vault/types.cjs.map +1 -0
  249. package/dist/vault/types.d.cts +390 -0
  250. package/dist/vault/types.d.ts +390 -0
  251. package/dist/vault/types.js +3 -0
  252. package/dist/vault/types.js.map +1 -0
  253. package/dist/verify/index.cjs +190 -0
  254. package/dist/verify/index.cjs.map +1 -0
  255. package/dist/verify/index.d.cts +9 -0
  256. package/dist/verify/index.d.ts +9 -0
  257. package/dist/verify/index.js +184 -0
  258. package/dist/verify/index.js.map +1 -0
  259. package/dist/verify/types.cjs +4 -0
  260. package/dist/verify/types.cjs.map +1 -0
  261. package/dist/verify/types.d.cts +29 -0
  262. package/dist/verify/types.d.ts +29 -0
  263. package/dist/verify/types.js +3 -0
  264. package/dist/verify/types.js.map +1 -0
  265. package/package.json +570 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Keboola s.r.o.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,456 @@
1
+ # @keboola/api-client
2
+
3
+ TypeScript SDK for Keboola APIs. Provides typed clients for all Keboola platform services.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @keboola/api-client
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ### Full client initialization (browser)
14
+
15
+ ```typescript
16
+ import { createApiClient } from '@keboola/api-client';
17
+
18
+ const api = createApiClient();
19
+
20
+ await api.init({
21
+ baseUrl: 'https://connection.keboola.com',
22
+ token: {
23
+ storageApi: 'your-storage-token',
24
+ managementApi: 'your-management-token', // optional
25
+ },
26
+ assetsBaseUrl: 'https://assets.keboola.com',
27
+ statusBaseUrl: 'https://status.keboola.com',
28
+ metastoreBaseUrl: 'https://metastore.keboola.com',
29
+ callbacks: {
30
+ onError: (error) => console.error('API Error:', error),
31
+ onSuccess: () => {},
32
+ onSettled: () => {},
33
+ },
34
+ });
35
+
36
+ const tables = await api.storage.tables.list();
37
+ const jobs = await api.queue.searchJobs();
38
+ ```
39
+
40
+ ### Individual client (Node.js)
41
+
42
+ ```typescript
43
+ import { createStorageClient, createStorageTokenMiddleware } from '@keboola/api-client/storage';
44
+
45
+ const tokenMiddleware = createStorageTokenMiddleware('your-storage-token');
46
+ const storage = createStorageClient({
47
+ baseUrl: 'https://connection.keboola.com',
48
+ middlewares: [tokenMiddleware],
49
+ });
50
+
51
+ const stackInfo = await storage.getStackInfo();
52
+ const files = await storage.files.list();
53
+ ```
54
+
55
+ ### Type imports
56
+
57
+ ```typescript
58
+ import type { ApiClientOptions, ApiClient } from '@keboola/api-client';
59
+ import type { StackInfo, ServiceId } from '@keboola/api-client/storage/types';
60
+ import type { GetQueueJobPath } from '@keboola/api-client/queue/types';
61
+ import type { VariableWithHash } from '@keboola/api-client/vault/types';
62
+ ```
63
+
64
+ ## Architecture
65
+
66
+ ```
67
+ src/
68
+ client.ts # createApiClient() factory — top-level entry
69
+ devClient.ts # Lightweight dev/verify client
70
+ constants.ts # HTTP headers, prefixes
71
+ fetchClient/
72
+ createFetchClient/ # Core fetch wrapper, middleware composition
73
+ createGenericFetchClient.ts # Untyped HTTP client (manual generics)
74
+ createOpenapiFetchClient.ts # Typed HTTP client (from OpenAPI schemas)
75
+ types.ts # OpenAPI type-level helpers
76
+ clients/
77
+ storage/ # Storage API (buckets, tables, files, branches, ...)
78
+ management/ # Management API (projects, features, users)
79
+ vault/ # Vault secrets
80
+ dataScience/ # Data apps, sandboxes, runtimes
81
+ editor/ # SQL sessions, queries
82
+ encryption/ # Value/secret encryption
83
+ chat/ # Kai Assistant chat
84
+ kaiAgent/ # Kai Agent (agentic assistant)
85
+ ai/ # AI describe/explain/suggest
86
+ queue/ # Job Queue
87
+ queryService/ # SQL query service
88
+ syncActions/ # Sync actions, MFA, git repos
89
+ telemetry/ # Telemetry provisioning
90
+ metastore/ # Metastore repository/schema
91
+ assets/ # Platform changelog
92
+ status/ # Status page summary
93
+ import/ # File upload
94
+ verify/ # Token verification
95
+ domain/
96
+ stack.ts # Stack info, service discovery, feature flags
97
+ project.ts # Project info, backend/feature checks
98
+ sdks/
99
+ tag/ # High-level tag CRUD (composes metastore client)
100
+ errors/
101
+ ApiError.ts # HTTP error with response/request/data
102
+ UserError.ts # User-facing validation error
103
+ ServiceUnavailableError.ts # Service not available in current stack
104
+ ManagementClientAuthError.ts
105
+ utils/
106
+ concurrent.ts # Concurrent task runner with middleware
107
+ series.ts # Sequential task runner
108
+ poll.ts # Polling with isDone/isFailed predicates
109
+ delay.ts # Abortable delay
110
+ keboolaUID.ts # Keboola object ID serialization
111
+ generateUUID.ts # crypto.randomUUID wrapper
112
+ assert.ts # Runtime assertions
113
+ ```
114
+
115
+ ## Service Clients
116
+
117
+ After calling `api.init(...)`, the following clients are available on the `api` object.
118
+ Clients backed by OpenAPI specs are marked with (OpenAPI); the rest use the generic fetch client.
119
+
120
+ | Accessor | Service | Key methods |
121
+ | ------------------ | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
122
+ | `api.storage` | Storage API | `buckets.*`, `tables.*`, `files.*`, `branches.*`, `workspaces.*`, `mergeRequests.*`, `jobs.*`, `componentsAndConfigurations.*`, `tokens.*`, `getStackInfo()` |
123
+ | `api.management` | Management API | `projects.*`, `features.*`, `users.*` |
124
+ | `api.vault` | Vault (OpenAPI) | `getVariables()`, `createVariable()`, `deleteVariable()`, `getVariablesByBranchId()`, `getProjectWideVariables()` |
125
+ | `api.dataScience` | Data Science (OpenAPI) | `getApps()`, `getApp()`, `createApp()`, `patchApp()`, `deleteApp()`, `getAppRuns()`, `getAppRun()`, `getAppLogsTail()`, `getAppLogsDownload()`, `getRuntimes()`, `getSandbox()` |
126
+ | `api.editor` | SQL Editor (OpenAPI) | `createSession()`, `getSession()`, `getSessions()`, `getSessionSchema()`, `createQueryJob()`, `tablePreview()`, `tableDefinition()`, `load()`, `unload()` |
127
+ | `api.encryption` | Encryption | `encrypt()`, `encryptSecrets()` |
128
+ | `api.chat` | Kai Assistant (OpenAPI) | `getHistory()`, `getChat()`, `createChat()`, `deleteChat()`, `getVotes()`, `submitVote()`, `getUsage()`, `getSuggestions()`, `getAgentSettings()`, `getToolsList()` |
129
+ | `api.kaiAgent` | Kai Agent (OpenAPI) | `getHistory()`, `getChat()`, `createChat()`, `deleteChat()`, `approveToolCall()`, `submitToolOutput()`, `getSuggestions()`, `getAgentSettings()` |
130
+ | `api.ai` | AI Service (OpenAPI) | `describeConfiguration()`, `describeConfigurationVersion()`, `describeConfigurationMerge()`, `explainError()`, `suggestComponent()`, `feedback()` |
131
+ | `api.queue` | Job Queue (OpenAPI) | `getJob()`, `searchJobs()` |
132
+ | `api.queryService` | Query Service (OpenAPI) | `createQueryJob()`, `cancelQueryJob()`, `getQueryJob()`, `getQueryResults()`, `getQueryHistory()`, `exportResults()` |
133
+ | `api.syncActions` | Sync Actions (OpenAPI) | `enrollMFA()`, `gitRepository.*` |
134
+ | `api.telemetry` | Telemetry | `provisioning.*` |
135
+ | `api.assets` | Assets | `getPublishedChangelogPosts()` |
136
+ | `api.status` | Status | `getSummary()` |
137
+ | `api.import` | Import | `uploadFile()` |
138
+
139
+ Additional accessors on the initialized client:
140
+
141
+ | Accessor | Purpose |
142
+ | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
143
+ | `api.stack` | Stack info: `hasFeature()`, `hasService()`, `getServiceUrl()`, `hasComponent()`, `getComponent()`, `services`, `features`, `components` |
144
+ | `api.project` | Project info: `hasFeature()`, `hasAdminFeature()`, `hasBackend()`, `sapiToken` |
145
+ | `api.sdk.tag` | Tag SDK: `getTags()`, `getTagsByObjectId()`, `createTag()`, `updateTag()`, `deleteTag()`, `assignTags()`, `unassignTags()`, `createAndAssignTag()` |
146
+ | `api.serviceMeta` | Service availability metadata from the registry |
147
+
148
+ ## Entry Points
149
+
150
+ ```typescript
151
+ // Main entry — full ApiClient + all exports
152
+ import { createApiClient, isApiError, concurrent, poll } from '@keboola/api-client';
153
+
154
+ // Per-client imports — individual client factories
155
+ import { createStorageClient } from '@keboola/api-client/storage';
156
+ import { createVerifyClient } from '@keboola/api-client/verify';
157
+
158
+ // Per-service type imports (tree-shakeable)
159
+ import type { StackInfo } from '@keboola/api-client/storage/types';
160
+ import type { GetQueueJobPath } from '@keboola/api-client/queue/types';
161
+ ```
162
+
163
+ ## Error Handling
164
+
165
+ ```typescript
166
+ import {
167
+ isApiError,
168
+ isFetchClientError,
169
+ isAbortError,
170
+ ApiError,
171
+ UserError,
172
+ ServiceUnavailableError,
173
+ } from '@keboola/api-client';
174
+
175
+ try {
176
+ await api.storage.tables.list();
177
+ } catch (error) {
178
+ if (isApiError(error)) {
179
+ // HTTP error — has response, request, and parsed data
180
+ console.error(error.response.status, error.data);
181
+ } else if (isFetchClientError(error)) {
182
+ // Network-level error
183
+ console.error(error.message);
184
+ } else if (isAbortError(error)) {
185
+ // Request was aborted via AbortSignal
186
+ } else if (error instanceof ServiceUnavailableError) {
187
+ // Service not available in the current stack
188
+ } else if (error instanceof UserError) {
189
+ // Validation error safe to show to end users
190
+ }
191
+ }
192
+ ```
193
+
194
+ ## Middleware
195
+
196
+ Middleware functions wrap every HTTP request. They execute in registration order (first registered = outermost).
197
+
198
+ ```typescript
199
+ import type { MiddlewareFn } from '@keboola/api-client';
200
+
201
+ const loggingMiddleware: MiddlewareFn = (next) => async (request) => {
202
+ console.log('Request:', request.url);
203
+ const response = await next(request);
204
+ console.log('Response:', response.response.status);
205
+ return response;
206
+ };
207
+ ```
208
+
209
+ ### Callback middleware
210
+
211
+ The built-in callback middleware provides `onError`, `onSuccess`, and `onSettled` hooks:
212
+
213
+ ```typescript
214
+ import { createApiClient } from '@keboola/api-client';
215
+
216
+ const api = createApiClient();
217
+ await api.init({
218
+ baseUrl: 'https://connection.keboola.com',
219
+ token: { storageApi: 'your-token' },
220
+ assetsBaseUrl: 'https://assets.keboola.com',
221
+ statusBaseUrl: 'https://status.keboola.com',
222
+ metastoreBaseUrl: 'https://metastore.keboola.com',
223
+ callbacks: {
224
+ onError: (error) => {
225
+ /* handle error */
226
+ },
227
+ onSuccess: () => {
228
+ /* e.g. reset idle timer */
229
+ },
230
+ onSettled: () => {
231
+ /* e.g. hide loading indicator */
232
+ },
233
+ },
234
+ });
235
+ ```
236
+
237
+ ## Utilities
238
+
239
+ ### concurrent / series
240
+
241
+ ```typescript
242
+ import { concurrent, series } from '@keboola/api-client';
243
+
244
+ // Process items with concurrency limit (default: 2)
245
+ const results = await concurrent({
246
+ items: ['a', 'b', 'c', 'd'],
247
+ process: async (item) => fetchData(item),
248
+ concurrency: 3,
249
+ });
250
+
251
+ // Process items one at a time
252
+ const ordered = await series({
253
+ items: ['a', 'b', 'c'],
254
+ process: async (item) => fetchData(item),
255
+ });
256
+ ```
257
+
258
+ ### poll
259
+
260
+ ```typescript
261
+ import { poll, PollException } from '@keboola/api-client';
262
+
263
+ const controller = new AbortController();
264
+
265
+ try {
266
+ const { data, callCount } = await poll({
267
+ pollFn: (signal) => api.queue.getJob(jobId, signal),
268
+ isDone: (job) => job.status === 'success',
269
+ isFailed: (job) => job.status === 'error',
270
+ interval: 2000,
271
+ maxAttempts: 30,
272
+ abortSignal: controller.signal,
273
+ });
274
+ } catch (error) {
275
+ if (error instanceof PollException) {
276
+ console.error(error.message, error.result);
277
+ }
278
+ }
279
+ ```
280
+
281
+ ### keboolaUID
282
+
283
+ ```typescript
284
+ import { keboolaUID } from '@keboola/api-client';
285
+
286
+ const uid = keboolaUID.serialize({
287
+ type: 'table',
288
+ projectId: 123,
289
+ uid: 'in.c-main.users',
290
+ });
291
+ // "KID--123--table--in.c-main.users"
292
+
293
+ const parsed = keboolaUID.deserialize(uid);
294
+ // { type: 'table', projectId: 123, uid: 'in.c-main.users' }
295
+ ```
296
+
297
+ ### Other utilities
298
+
299
+ ```typescript
300
+ import { delay, generateUUID, assert } from '@keboola/api-client';
301
+
302
+ // Abortable delay
303
+ await delay(1000, abortSignal);
304
+
305
+ // crypto.randomUUID wrapper
306
+ const id = generateUUID();
307
+
308
+ // Runtime assertion (throws if falsy)
309
+ assert(value, 'value must be defined');
310
+ ```
311
+
312
+ ## React Bindings
313
+
314
+ React bindings (provider, hooks, query integration) are in the separate `@keboola/api-client-react` package.
315
+
316
+ ```typescript
317
+ import { ApiClientProvider, useApiClient } from '@keboola/api-client-react';
318
+ ```
319
+
320
+ ## License
321
+
322
+ MIT. See [LICENSE](./LICENSE).
323
+
324
+ ---
325
+
326
+ ## Contributing
327
+
328
+ Internal guide for adding new service clients to this package.
329
+
330
+ ### Adding a New OpenAPI Client
331
+
332
+ #### Step 1: Register the API in `redocly.yaml`
333
+
334
+ Add your API specification to the `redocly.yaml` file:
335
+
336
+ ```yaml
337
+ apis:
338
+ # Existing APIs...
339
+ yourNewService:
340
+ root: https://your-service.keboola.com/docs/swagger.yaml
341
+ x-openapi-ts:
342
+ output: ./src/clients/yourNewService/__generated__/schema.d.ts
343
+ ```
344
+
345
+ #### Step 2: Generate Types
346
+
347
+ Run the type generation command:
348
+
349
+ ```bash
350
+ yarn gen:types
351
+ ```
352
+
353
+ This will create the TypeScript definitions at the specified output path.
354
+
355
+ #### Step 3: Create the Client Implementation
356
+
357
+ Create `src/clients/yourNewService/yourNewServiceClient.ts`:
358
+
359
+ ```typescript
360
+ import { createOpenapiFetchClient } from '../../fetchClient';
361
+ import type { ClientInitOptions } from '../types';
362
+
363
+ import type { paths } from './__generated__/schema';
364
+
365
+ export const createYourNewServiceClient = ({ baseUrl, middlewares }: ClientInitOptions) => {
366
+ const client = createOpenapiFetchClient<paths>({
367
+ baseUrl,
368
+ middlewares,
369
+ });
370
+
371
+ const listItems = async (signal?: AbortSignal) => {
372
+ const { data } = await client.get('/items', {}, { signal });
373
+ return data;
374
+ };
375
+
376
+ return {
377
+ listItems,
378
+ };
379
+ };
380
+ ```
381
+
382
+ #### Step 4: Create the Types Export File
383
+
384
+ Create `src/clients/yourNewService/types.ts` to re-export all types:
385
+
386
+ ```typescript
387
+ export type * from './__generated__/schema';
388
+ export type { YourNewServiceClient } from './yourNewServiceClient';
389
+ ```
390
+
391
+ #### Step 5: Create the Index File
392
+
393
+ Create `src/clients/yourNewService/index.ts`:
394
+
395
+ ```typescript
396
+ export * from './yourNewServiceClient';
397
+ ```
398
+
399
+ #### Step 6: Add Type Export to package.json
400
+
401
+ Add the type export path to `package.json` exports and add the entry to `tsup.config.ts`:
402
+
403
+ ```json
404
+ {
405
+ "exports": {
406
+ "./types/yourNewService": {
407
+ "import": {
408
+ "types": "./dist/types/yourNewService.d.ts",
409
+ "default": "./dist/types/yourNewService.js"
410
+ },
411
+ "require": {
412
+ "types": "./dist/types/yourNewService.d.cts",
413
+ "default": "./dist/types/yourNewService.cjs"
414
+ }
415
+ }
416
+ }
417
+ }
418
+ ```
419
+
420
+ #### Step 7: Integrate with Main ApiClient
421
+
422
+ Update `src/client.ts` to register the client in the `createServiceClientRegistry` call:
423
+
424
+ ```typescript
425
+ import { createYourNewServiceClient } from './clients/yourNewService';
426
+
427
+ // Inside createClients, add to the clients array:
428
+ {
429
+ serviceId: 'your-service',
430
+ clientName: 'yourNewService',
431
+ clientFn: (serviceBaseUrl) =>
432
+ createYourNewServiceClient({ baseUrl: serviceBaseUrl, middlewares: commonMiddlewares }),
433
+ },
434
+ ```
435
+
436
+ ### Adding a New Generic Client
437
+
438
+ Follow the same steps but use `createGenericFetchClient` instead of `createOpenapiFetchClient`. No `redocly.yaml` registration or `yarn gen:types` step is needed. Define request/response types manually.
439
+
440
+ ### OpenAPI Type Generation Workflow
441
+
442
+ 1. Update API specifications (if needed, edit `redocly.yaml`)
443
+ 2. Run `yarn gen:types` to regenerate TypeScript definitions
444
+ 3. Review generated files in `__generated__/` directories
445
+ 4. Update client implementation if the API surface changed
446
+ 5. Always commit generated files to version control
447
+
448
+ ### redocly.yaml Configuration Reference
449
+
450
+ ```yaml
451
+ apis:
452
+ serviceName:
453
+ root: https://api.example.com/swagger.yaml
454
+ x-openapi-ts:
455
+ output: ./src/clients/serviceName/__generated__/schema.d.ts
456
+ ```
@@ -0,0 +1,203 @@
1
+ 'use strict';
2
+
3
+ var qs = require('qs');
4
+
5
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
+
7
+ var qs__default = /*#__PURE__*/_interopDefault(qs);
8
+
9
+ // src/errors/ApiError.ts
10
+ var ApiError = class extends Error {
11
+ response;
12
+ request;
13
+ data;
14
+ constructor({ response, request, data }) {
15
+ super(response.statusText);
16
+ this.response = response;
17
+ this.request = request;
18
+ this.data = data;
19
+ }
20
+ };
21
+ var HttpHeader = {
22
+ CONTENT_TYPE: "content-type"};
23
+ var HttpContentType = {
24
+ JSON: "application/json"};
25
+ var defaultValidateStatus = ({ response }) => response.status >= 200 && response.status <= 299;
26
+ function removeUndefined(obj) {
27
+ const objCopy = { ...obj };
28
+ for (const [key, value] of Object.entries(objCopy)) {
29
+ if (value == null) delete objCopy[key];
30
+ }
31
+ return objCopy;
32
+ }
33
+ var parseData = async (response) => {
34
+ if (response.status === 204) return null;
35
+ const contentType = response.headers.get(HttpHeader.CONTENT_TYPE);
36
+ if (contentType && contentType == HttpContentType.JSON) {
37
+ return response.json();
38
+ }
39
+ const text = await response.text();
40
+ try {
41
+ return JSON.parse(text);
42
+ } catch {
43
+ return text;
44
+ }
45
+ };
46
+ var cleanHeadersInit = (headersInit) => {
47
+ if (Array.isArray(headersInit)) return headersInit;
48
+ if (headersInit instanceof Headers) return headersInit;
49
+ if (headersInit == null) return headersInit;
50
+ return removeUndefined(headersInit);
51
+ };
52
+ var createHeaders = (headersInitA, headersInitB) => {
53
+ const headersA = new Headers(cleanHeadersInit(headersInitA));
54
+ const headersB = new Headers(cleanHeadersInit(headersInitB));
55
+ headersB.forEach((value, key) => {
56
+ headersA.set(key, value);
57
+ });
58
+ return headersA;
59
+ };
60
+ var createPath = (path, pathParam = {}) => path.replace(/\{([^}]+)}/g, (_, key) => {
61
+ if (!(key in pathParam))
62
+ throw new Error(`Path parameter "${key}" is missing in the path "${path}"`);
63
+ return encodeURIComponent(pathParam[key]);
64
+ });
65
+ var createSearch = (query, options = {}) => {
66
+ return qs__default.default.stringify(query, {
67
+ encodeValuesOnly: true,
68
+ skipNulls: true,
69
+ ...options
70
+ });
71
+ };
72
+ var createBody = (body, headers) => {
73
+ if (body == null) return null;
74
+ if (body instanceof FormData) return body;
75
+ if (typeof body === "string") return body;
76
+ const stringifyBody = JSON.stringify(body);
77
+ const stringBody = stringifyBody === "{}" ? null : stringifyBody;
78
+ if (stringBody) headers.set(HttpHeader.CONTENT_TYPE, HttpContentType.JSON);
79
+ return stringBody;
80
+ };
81
+ var createFetchRequest = ({
82
+ url,
83
+ method,
84
+ params,
85
+ options = {},
86
+ defaultOptions
87
+ }) => {
88
+ const {
89
+ baseUrl,
90
+ validateStatus: defValidateStatus = defaultValidateStatus,
91
+ headers: defaultHeaders,
92
+ ...restDefaultOptions
93
+ } = defaultOptions;
94
+ const { validateStatus, queryArrayFormat, headers: endpointHeaders, ...restOptions } = options;
95
+ const headers = createHeaders(defaultHeaders, endpointHeaders);
96
+ const path = createPath(url, params.path);
97
+ const search = createSearch(params.query ?? {}, { arrayFormat: queryArrayFormat });
98
+ const body = createBody(params.body, headers);
99
+ const urlInstance = new URL(baseUrl + path);
100
+ urlInstance.search = search;
101
+ const request = new Request(urlInstance, {
102
+ ...restDefaultOptions,
103
+ ...restOptions,
104
+ headers,
105
+ method: method.toUpperCase(),
106
+ body
107
+ });
108
+ return { request, validateStatus: validateStatus ?? defValidateStatus };
109
+ };
110
+
111
+ // src/fetchClient/createFetchClient/createFetchClient.ts
112
+ var isApiError = (error) => error instanceof ApiError;
113
+ var createCoreFetch = (fetchFn) => async ({ request, validateStatus }) => {
114
+ const response = await fetchFn(request);
115
+ const data = await parseData(response);
116
+ const apiResponse = {
117
+ request,
118
+ response,
119
+ data
120
+ };
121
+ const boolOrError = validateStatus(apiResponse);
122
+ if (isApiError(boolOrError)) throw boolOrError;
123
+ if (!boolOrError) throw new ApiError(apiResponse);
124
+ return apiResponse;
125
+ };
126
+ var createFetchClient = ({
127
+ middlewares = [],
128
+ ...defaultOptions
129
+ }) => {
130
+ const coreFetch = createCoreFetch(defaultOptions.fetchFn ?? fetch);
131
+ const fetchWithMiddlewares = middlewares.reduceRight(
132
+ (next, middleware) => middleware(next),
133
+ coreFetch
134
+ );
135
+ const createFetchMethod = (method) => async (url, params, options = {}) => {
136
+ const request = createFetchRequest({
137
+ url,
138
+ method,
139
+ params,
140
+ defaultOptions,
141
+ options
142
+ });
143
+ const methodMiddlewares = options?.middlewares ?? [];
144
+ return methodMiddlewares.reduceRight(
145
+ (next, middleware) => middleware(next),
146
+ fetchWithMiddlewares
147
+ )(request);
148
+ };
149
+ return {
150
+ get: createFetchMethod("get"),
151
+ post: createFetchMethod("post"),
152
+ put: createFetchMethod("put"),
153
+ patch: createFetchMethod("patch"),
154
+ delete: createFetchMethod("delete")
155
+ };
156
+ };
157
+
158
+ // src/fetchClient/createOpenapiFetchClient.ts
159
+ var createOpenapiFetchClient = (defaultOptions) => createFetchClient(defaultOptions);
160
+
161
+ // src/clients/ai/aiClient.ts
162
+ var createAiClient = ({ baseUrl, middlewares }) => {
163
+ const client = createOpenapiFetchClient({
164
+ baseUrl,
165
+ middlewares
166
+ });
167
+ const describeConfigurationVersion = async (body) => {
168
+ const { data } = await client.post("/describe/configuration-version", { body });
169
+ return data;
170
+ };
171
+ const describeConfigurationMerge = async (body) => {
172
+ const { data } = await client.post("/describe/configuration-merge", { body });
173
+ return data;
174
+ };
175
+ const explainError = async (body) => {
176
+ const { data } = await client.post("/explain", { body });
177
+ return data;
178
+ };
179
+ const describeConfiguration = async (body) => {
180
+ const { data } = await client.post("/describe/configuration", { body });
181
+ return data;
182
+ };
183
+ const suggestComponent = async (body) => {
184
+ const { data } = await client.post("/suggest/component", { body });
185
+ return data;
186
+ };
187
+ const feedback = async (body) => {
188
+ const { data } = await client.post("/feedback", { body });
189
+ return data;
190
+ };
191
+ return {
192
+ describeConfigurationVersion,
193
+ describeConfigurationMerge,
194
+ explainError,
195
+ describeConfiguration,
196
+ suggestComponent,
197
+ feedback
198
+ };
199
+ };
200
+
201
+ exports.createAiClient = createAiClient;
202
+ //# sourceMappingURL=index.cjs.map
203
+ //# sourceMappingURL=index.cjs.map