@aifabrix/builder 2.38.0 → 2.39.1

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 (49) hide show
  1. package/.cursor/rules/project-rules.mdc +3 -0
  2. package/integration/hubspot/hubspot-deploy.json +0 -3
  3. package/integration/hubspot/hubspot-system.json +0 -3
  4. package/lib/api/applications.api.js +8 -2
  5. package/lib/api/auth.api.js +14 -0
  6. package/lib/api/credentials.api.js +1 -1
  7. package/lib/api/datasources-core.api.js +16 -1
  8. package/lib/api/datasources-extended.api.js +18 -1
  9. package/lib/api/deployments.api.js +6 -1
  10. package/lib/api/environments.api.js +11 -0
  11. package/lib/api/external-systems.api.js +16 -1
  12. package/lib/api/pipeline.api.js +12 -4
  13. package/lib/api/service-users.api.js +41 -0
  14. package/lib/api/types/service-users.types.js +24 -0
  15. package/lib/api/wizard.api.js +19 -0
  16. package/lib/app/deploy-status-display.js +78 -0
  17. package/lib/app/deploy.js +66 -21
  18. package/lib/app/rotate-secret.js +3 -1
  19. package/lib/app/run-helpers.js +7 -2
  20. package/lib/app/show-display.js +30 -11
  21. package/lib/app/show.js +34 -8
  22. package/lib/cli/index.js +2 -0
  23. package/lib/cli/setup-app.js +8 -0
  24. package/lib/cli/setup-infra.js +3 -3
  25. package/lib/cli/setup-service-user.js +61 -0
  26. package/lib/commands/app.js +2 -1
  27. package/lib/commands/service-user.js +199 -0
  28. package/lib/commands/up-common.js +74 -5
  29. package/lib/commands/up-dataplane.js +13 -7
  30. package/lib/commands/up-miso.js +17 -24
  31. package/lib/core/templates.js +0 -1
  32. package/lib/external-system/deploy.js +79 -15
  33. package/lib/generator/builders.js +0 -24
  34. package/lib/schema/application-schema.json +0 -12
  35. package/lib/schema/external-system.schema.json +0 -16
  36. package/lib/utils/app-register-config.js +10 -12
  37. package/lib/utils/deployment-errors.js +10 -0
  38. package/lib/utils/environment-checker.js +25 -6
  39. package/lib/utils/variable-transformer.js +6 -14
  40. package/package.json +1 -1
  41. package/templates/applications/dataplane/README.md +23 -7
  42. package/templates/applications/dataplane/env.template +31 -2
  43. package/templates/applications/dataplane/rbac.yaml +1 -1
  44. package/templates/applications/dataplane/variables.yaml +2 -1
  45. package/templates/applications/keycloak/env.template +6 -3
  46. package/templates/applications/keycloak/variables.yaml +1 -0
  47. package/templates/applications/miso-controller/env.template +22 -15
  48. package/templates/applications/miso-controller/rbac.yaml +15 -0
  49. package/templates/applications/miso-controller/variables.yaml +24 -23
@@ -262,6 +262,8 @@ const appResponse = await registerApplication(controllerUrl, environment, data,
262
262
  - Gradually migrate modules to use centralized API client
263
263
  - Eventually deprecate direct usage of `lib/utils/api.js`
264
264
 
265
+ **API Permissions**: When adding or changing `lib/api` functions that call Controller or Dataplane, document required permissions. See [permissions-guide.md](permissions-guide.md) for how to update `@requiresPermission` JSDoc and [docs/commands/permissions.md](../docs/commands/permissions.md).
266
+
265
267
  ## Code Style
266
268
 
267
269
  ### JavaScript Conventions
@@ -880,6 +882,7 @@ Define request/response types using JSDoc `@typedef`:
880
882
  - ✅ Use centralized API client (`lib/api/`) for new API calls
881
883
  - ✅ Define request/response types using JSDoc `@typedef` in `lib/api/types/`
882
884
  - ✅ Use domain-specific API modules (`lib/api/*.api.js`) instead of direct `makeApiCall`
885
+ - ✅ When adding lib/api functions that call Controller/Dataplane, add `@requiresPermission` JSDoc per [permissions-guide.md](permissions-guide.md)
883
886
 
884
887
  ### Must Not Do (❌)
885
888
  - ❌ Never hardcode secrets, passwords, or tokens
@@ -22,9 +22,6 @@
22
22
  "description": "HubSpot CRM integration with OpenAPI support for companies, contacts, and deals",
23
23
  "type": "openapi",
24
24
  "enabled": true,
25
- "environment": {
26
- "baseUrl": "https://api.hubapi.com"
27
- },
28
25
  "authentication": {
29
26
  "type": "oauth2",
30
27
  "mode": "oauth2",
@@ -4,9 +4,6 @@
4
4
  "description": "HubSpot CRM integration with OpenAPI support for companies, contacts, and deals",
5
5
  "type": "openapi",
6
6
  "enabled": true,
7
- "environment": {
8
- "baseUrl": "https://api.hubapi.com"
9
- },
10
7
  "authentication": {
11
8
  "type": "oauth2",
12
9
  "mode": "oauth2",
@@ -9,6 +9,7 @@ const { ApiClient } = require('./index');
9
9
  /**
10
10
  * List all template applications
11
11
  * GET /api/v1/applications
12
+ * @requiresPermission {Controller} applications:read
12
13
  * @async
13
14
  * @function listApplications
14
15
  * @param {string} controllerUrl - Controller base URL
@@ -32,6 +33,7 @@ async function listApplications(controllerUrl, authConfig, options = {}) {
32
33
  /**
33
34
  * Create new template application
34
35
  * POST /api/v1/applications
36
+ * @requiresPermission {Controller} applications:create
35
37
  * @async
36
38
  * @function createApplication
37
39
  * @param {string} controllerUrl - Controller base URL
@@ -55,6 +57,7 @@ async function createApplication(controllerUrl, authConfig, applicationData) {
55
57
  /**
56
58
  * Get template application details
57
59
  * GET /api/v1/applications/{appKey}
60
+ * @requiresPermission {Controller} applications:read
58
61
  * @async
59
62
  * @function getApplication
60
63
  * @param {string} controllerUrl - Controller base URL
@@ -71,6 +74,7 @@ async function getApplication(controllerUrl, appKey, authConfig) {
71
74
  /**
72
75
  * Update template application
73
76
  * PATCH /api/v1/applications/{appKey}
77
+ * @requiresPermission {Controller} applications:update
74
78
  * @async
75
79
  * @function updateApplication
76
80
  * @param {string} controllerUrl - Controller base URL
@@ -95,6 +99,7 @@ async function updateApplication(controllerUrl, appKey, authConfig, updateData)
95
99
  /**
96
100
  * Delete template application
97
101
  * DELETE /api/v1/applications/{appKey}
102
+ * @requiresPermission {Controller} applications:delete
98
103
  * @async
99
104
  * @function deleteApplication
100
105
  * @param {string} controllerUrl - Controller base URL
@@ -111,6 +116,7 @@ async function deleteApplication(controllerUrl, appKey, authConfig) {
111
116
  /**
112
117
  * Register application in an environment
113
118
  * POST /api/v1/environments/{envKey}/applications/register
119
+ * @requiresPermission {Controller} environments-applications:create
114
120
  * @async
115
121
  * @function registerApplication
116
122
  * @param {string} controllerUrl - Controller base URL
@@ -139,6 +145,7 @@ async function registerApplication(controllerUrl, envKey, authConfig, registrati
139
145
  /**
140
146
  * Rotate application secret
141
147
  * POST /api/v1/environments/{envKey}/applications/{appKey}/rotate-secret
148
+ * @requiresPermission {Controller} environments-applications:update
142
149
  * @async
143
150
  * @function rotateApplicationSecret
144
151
  * @param {string} controllerUrl - Controller base URL
@@ -156,8 +163,7 @@ async function rotateApplicationSecret(controllerUrl, envKey, appKey, authConfig
156
163
  /**
157
164
  * Get application status (metadata only, no configuration)
158
165
  * GET /api/v1/environments/{envKey}/applications/{appKey}/status
159
- * Auth: bearer token or pipeline client credentials for that application.
160
- *
166
+ * @requiresPermission {Controller} Bearer or app client credentials (environments-applications:read)
161
167
  * @async
162
168
  * @function getApplicationStatus
163
169
  * @param {string} controllerUrl - Controller base URL
@@ -9,6 +9,7 @@ const { ApiClient } = require('./index');
9
9
  /**
10
10
  * Get authentication token using client credentials
11
11
  * POST /api/v1/auth/token
12
+ * @requiresPermission {Controller} Client credentials (no scope in spec)
12
13
  * @async
13
14
  * @function getToken
14
15
  * @param {string} clientId - Client ID
@@ -30,6 +31,7 @@ async function getToken(clientId, clientSecret, controllerUrl) {
30
31
  /**
31
32
  * Get client token for frontend application
32
33
  * GET/POST /api/v1/auth/client-token
34
+ * @requiresPermission {Controller} Client credentials or unauthenticated
33
35
  * @async
34
36
  * @function getClientToken
35
37
  * @param {string} controllerUrl - Controller base URL
@@ -50,6 +52,7 @@ async function getClientToken(controllerUrl, method = 'POST') {
50
52
  /**
51
53
  * Get current user information
52
54
  * GET /api/v1/auth/user
55
+ * @requiresPermission {Controller} auth:read
53
56
  * @async
54
57
  * @function getAuthUser
55
58
  * @param {string} controllerUrl - Controller base URL
@@ -65,6 +68,7 @@ async function getAuthUser(controllerUrl, authConfig) {
65
68
  /**
66
69
  * Get login URL for OAuth2 authorization flow
67
70
  * GET /api/v1/auth/login
71
+ * @requiresPermission {Controller} Client credentials
68
72
  * @async
69
73
  * @function getAuthLogin
70
74
  * @param {string} controllerUrl - Controller base URL
@@ -84,6 +88,7 @@ async function getAuthLogin(controllerUrl, redirect, state, authConfig) {
84
88
  /**
85
89
  * Initiate OAuth2 Device Code Flow
86
90
  * POST /api/v1/auth/login
91
+ * @requiresPermission {Controller} Public (no auth required for device code initiation)
87
92
  * @async
88
93
  * @function initiateDeviceCodeFlow
89
94
  * @param {string} controllerUrl - Controller base URL
@@ -122,6 +127,7 @@ async function initiateDeviceCodeFlow(controllerUrl, environment, scope) {
122
127
  /**
123
128
  * Poll for device code token
124
129
  * POST /api/v1/auth/login/device/token
130
+ * @requiresPermission {Controller} Public
125
131
  * @async
126
132
  * @function pollDeviceCodeToken
127
133
  * @param {string} deviceCode - Device code from initiate device code flow
@@ -139,6 +145,7 @@ async function pollDeviceCodeToken(deviceCode, controllerUrl) {
139
145
  /**
140
146
  * Refresh device code access token
141
147
  * POST /api/v1/auth/login/device/refresh
148
+ * @requiresPermission {Controller} Bearer token (refresh token)
142
149
  * @async
143
150
  * @function refreshDeviceToken
144
151
  * @param {string} refreshToken - Refresh token obtained from device code token flow
@@ -156,6 +163,7 @@ async function refreshDeviceToken(refreshToken, controllerUrl) {
156
163
  /**
157
164
  * Refresh user access token
158
165
  * POST /api/v1/auth/refresh
166
+ * @requiresPermission {Controller} Bearer token (refresh token)
159
167
  * @async
160
168
  * @function refreshUserToken
161
169
  * @param {string} refreshToken - Refresh token obtained from OAuth callback flow
@@ -173,6 +181,7 @@ async function refreshUserToken(refreshToken, controllerUrl) {
173
181
  /**
174
182
  * Validate authentication token
175
183
  * POST /api/v1/auth/validate
184
+ * @requiresPermission {Controller} auth:read or client credentials
176
185
  * @async
177
186
  * @function validateToken
178
187
  * @param {string} token - JWT token to validate
@@ -202,6 +211,7 @@ async function validateToken(token, controllerUrl, authConfig, environment, appl
202
211
  /**
203
212
  * Get user roles
204
213
  * GET /api/v1/auth/roles
214
+ * @requiresPermission {Controller} auth:read
205
215
  * @async
206
216
  * @function getAuthRoles
207
217
  * @param {string} controllerUrl - Controller base URL
@@ -221,6 +231,7 @@ async function getAuthRoles(controllerUrl, authConfig, environment, application)
221
231
  /**
222
232
  * Refresh user roles
223
233
  * GET /api/v1/auth/roles/refresh
234
+ * @requiresPermission {Controller} auth:read
224
235
  * @async
225
236
  * @function refreshAuthRoles
226
237
  * @param {string} controllerUrl - Controller base URL
@@ -236,6 +247,7 @@ async function refreshAuthRoles(controllerUrl, authConfig) {
236
247
  /**
237
248
  * Get user permissions
238
249
  * GET /api/v1/auth/permissions
250
+ * @requiresPermission {Controller} auth:read
239
251
  * @async
240
252
  * @function getAuthPermissions
241
253
  * @param {string} controllerUrl - Controller base URL
@@ -255,6 +267,7 @@ async function getAuthPermissions(controllerUrl, authConfig, environment, applic
255
267
  /**
256
268
  * Refresh user permissions
257
269
  * GET /api/v1/auth/permissions/refresh
270
+ * @requiresPermission {Controller} auth:read
258
271
  * @async
259
272
  * @function refreshAuthPermissions
260
273
  * @param {string} controllerUrl - Controller base URL
@@ -270,6 +283,7 @@ async function refreshAuthPermissions(controllerUrl, authConfig) {
270
283
  /**
271
284
  * Get device code login diagnostics
272
285
  * GET /api/v1/auth/login/diagnostics
286
+ * @requiresPermission {Controller} Public
273
287
  * @async
274
288
  * @function getAuthLoginDiagnostics
275
289
  * @param {string} controllerUrl - Controller base URL
@@ -10,7 +10,7 @@ const { ApiClient } = require('./index');
10
10
  * List credentials from controller or dataplane
11
11
  * GET /api/v1/credential
12
12
  * Used by `aifabrix credential list`. Call with controller or dataplane base URL per deployment.
13
- *
13
+ * @requiresPermission {Dataplane} credential:read (when baseUrl is dataplane; controller may differ)
14
14
  * @async
15
15
  * @function listCredentials
16
16
  * @param {string} baseUrl - Controller or dataplane base URL
@@ -1,67 +1,82 @@
1
1
  /**
2
- * @fileoverview Datasources Core API functions
2
+ * @fileoverview Datasources Core API functions (Dataplane /api/v1/external/). All functions require Dataplane auth; scope per endpoint in dataplane OpenAPI (e.g. external-system:read, external-system:create).
3
3
  * @author AI Fabrix Team
4
4
  * @version 2.0.0
5
5
  */
6
6
 
7
7
  const { ApiClient } = require('./index');
8
8
 
9
+ /** @requiresPermission {Dataplane} external-system:read (datasource list) */
9
10
  async function listDatasources(dataplaneUrl, authConfig, options = {}) {
10
11
  const client = new ApiClient(dataplaneUrl, authConfig);
11
12
  return await client.get('/api/v1/external/', { params: options });
12
13
  }
14
+ /** @requiresPermission {Dataplane} external-system:create */
13
15
  async function createDatasource(dataplaneUrl, authConfig, datasourceData) {
14
16
  const client = new ApiClient(dataplaneUrl, authConfig);
15
17
  return await client.post('/api/v1/external/', { body: datasourceData });
16
18
  }
19
+ /** @requiresPermission {Dataplane} external-system:read */
17
20
  async function getDatasource(dataplaneUrl, sourceIdOrKey, authConfig) {
18
21
  const client = new ApiClient(dataplaneUrl, authConfig);
19
22
  return await client.get(`/api/v1/external/${sourceIdOrKey}`);
20
23
  }
24
+ /** @requiresPermission {Dataplane} external-system:update */
21
25
  async function updateDatasource(dataplaneUrl, sourceIdOrKey, authConfig, updateData) {
22
26
  const client = new ApiClient(dataplaneUrl, authConfig);
23
27
  return await client.put(`/api/v1/external/${sourceIdOrKey}`, { body: updateData });
24
28
  }
29
+ /** @requiresPermission {Dataplane} external-system:delete */
25
30
  async function deleteDatasource(dataplaneUrl, sourceIdOrKey, authConfig) {
26
31
  const client = new ApiClient(dataplaneUrl, authConfig);
27
32
  return await client.delete(`/api/v1/external/${sourceIdOrKey}`);
28
33
  }
34
+ /** @requiresPermission {Dataplane} external-system:read */
29
35
  async function getDatasourceConfig(dataplaneUrl, sourceIdOrKey, authConfig) {
30
36
  const client = new ApiClient(dataplaneUrl, authConfig);
31
37
  return await client.get(`/api/v1/external/${sourceIdOrKey}/config`);
32
38
  }
39
+ /** @requiresPermission {Dataplane} external-system:update */
33
40
  async function publishDatasource(dataplaneUrl, sourceIdOrKey, authConfig, publishData = {}) {
34
41
  const client = new ApiClient(dataplaneUrl, authConfig);
35
42
  return await client.post(`/api/v1/external/${sourceIdOrKey}/publish`, { body: publishData });
36
43
  }
44
+ /** @requiresPermission {Dataplane} external-system:update */
37
45
  async function rollbackDatasource(dataplaneUrl, sourceIdOrKey, authConfig, rollbackData) {
38
46
  const client = new ApiClient(dataplaneUrl, authConfig);
39
47
  return await client.post(`/api/v1/external/${sourceIdOrKey}/rollback`, { body: rollbackData });
40
48
  }
49
+ /** @requiresPermission {Dataplane} external-system:read */
41
50
  async function testDatasource(dataplaneUrl, sourceIdOrKey, authConfig, testData = {}) {
42
51
  const client = new ApiClient(dataplaneUrl, authConfig);
43
52
  return await client.post(`/api/v1/external/${sourceIdOrKey}/test`, { body: testData });
44
53
  }
54
+ /** @requiresPermission {Dataplane} external-system:read */
45
55
  async function listDatasourceOpenAPIEndpoints(dataplaneUrl, sourceIdOrKey, authConfig, options = {}) {
46
56
  const client = new ApiClient(dataplaneUrl, authConfig);
47
57
  return await client.get(`/api/v1/external/${sourceIdOrKey}/openapi-endpoints`, { params: options });
48
58
  }
59
+ /** @requiresPermission {Dataplane} audit:read or external-system:read */
49
60
  async function listExecutionLogs(dataplaneUrl, sourceIdOrKey, authConfig, options = {}) {
50
61
  const client = new ApiClient(dataplaneUrl, authConfig);
51
62
  return await client.get(`/api/v1/external/${sourceIdOrKey}/executions`, { params: options });
52
63
  }
64
+ /** @requiresPermission {Dataplane} audit:read or external-system:read */
53
65
  async function getExecutionLog(dataplaneUrl, sourceIdOrKey, executionId, authConfig) {
54
66
  const client = new ApiClient(dataplaneUrl, authConfig);
55
67
  return await client.get(`/api/v1/external/${sourceIdOrKey}/executions/${executionId}`);
56
68
  }
69
+ /** @requiresPermission {Dataplane} audit:read */
57
70
  async function listAllExecutionLogs(dataplaneUrl, authConfig, options = {}) {
58
71
  const client = new ApiClient(dataplaneUrl, authConfig);
59
72
  return await client.get('/api/v1/external/executions', { params: options });
60
73
  }
74
+ /** @requiresPermission {Dataplane} external-system:update */
61
75
  async function bulkOperation(dataplaneUrl, sourceIdOrKey, authConfig, bulkData) {
62
76
  const client = new ApiClient(dataplaneUrl, authConfig);
63
77
  return await client.post(`/api/v1/external/${sourceIdOrKey}/bulk`, { body: bulkData });
64
78
  }
79
+ /** @requiresPermission {Dataplane} external-system:read */
65
80
  async function getDatasourceStatus(dataplaneUrl, sourceIdOrKey, authConfig) {
66
81
  const client = new ApiClient(dataplaneUrl, authConfig);
67
82
  return await client.get(`/api/v1/external/${sourceIdOrKey}/status`);
@@ -1,43 +1,52 @@
1
1
  /**
2
- * @fileoverview Datasources Extended API functions (records, grants, policies, sync, documents)
2
+ * @fileoverview Datasources Extended API functions (records, grants, policies, sync, documents). All require Dataplane; scope per endpoint in dataplane OpenAPI.
3
3
  * @author AI Fabrix Team
4
4
  * @version 2.0.0
5
5
  */
6
6
 
7
7
  const { ApiClient } = require('./index');
8
8
 
9
+ /** @requiresPermission {Dataplane} external-system:read (records) */
9
10
  async function listRecords(dataplaneUrl, sourceIdOrKey, authConfig, options = {}) {
10
11
  const client = new ApiClient(dataplaneUrl, authConfig);
11
12
  return await client.get(`/api/v1/external/${sourceIdOrKey}/records`, { params: options });
12
13
  }
14
+ /** @requiresPermission {Dataplane} external-system:create */
13
15
  async function createRecord(dataplaneUrl, sourceIdOrKey, authConfig, recordData) {
14
16
  const client = new ApiClient(dataplaneUrl, authConfig);
15
17
  return await client.post(`/api/v1/external/${sourceIdOrKey}/records`, { body: recordData });
16
18
  }
19
+ /** @requiresPermission {Dataplane} external-system:read */
17
20
  async function getRecord(dataplaneUrl, sourceIdOrKey, recordIdOrKey, authConfig) {
18
21
  const client = new ApiClient(dataplaneUrl, authConfig);
19
22
  return await client.get(`/api/v1/external/${sourceIdOrKey}/records/${recordIdOrKey}`);
20
23
  }
24
+ /** @requiresPermission {Dataplane} external-system:update */
21
25
  async function updateRecord(dataplaneUrl, sourceIdOrKey, recordIdOrKey, authConfig, updateData) {
22
26
  const client = new ApiClient(dataplaneUrl, authConfig);
23
27
  return await client.put(`/api/v1/external/${sourceIdOrKey}/records/${recordIdOrKey}`, { body: updateData });
24
28
  }
29
+ /** @requiresPermission {Dataplane} external-system:delete */
25
30
  async function deleteRecord(dataplaneUrl, sourceIdOrKey, recordIdOrKey, authConfig) {
26
31
  const client = new ApiClient(dataplaneUrl, authConfig);
27
32
  return await client.delete(`/api/v1/external/${sourceIdOrKey}/records/${recordIdOrKey}`);
28
33
  }
34
+ /** @requiresPermission {Dataplane} external-system:read (grants) */
29
35
  async function listGrants(dataplaneUrl, sourceIdOrKey, authConfig, options = {}) {
30
36
  const client = new ApiClient(dataplaneUrl, authConfig);
31
37
  return await client.get(`/api/v1/external/${sourceIdOrKey}/grants`, { params: options });
32
38
  }
39
+ /** @requiresPermission {Dataplane} external-system:update */
33
40
  async function createGrant(dataplaneUrl, sourceIdOrKey, authConfig, grantData) {
34
41
  const client = new ApiClient(dataplaneUrl, authConfig);
35
42
  return await client.post(`/api/v1/external/${sourceIdOrKey}/grants`, { body: grantData });
36
43
  }
44
+ /** @requiresPermission {Dataplane} external-system:read */
37
45
  async function getGrant(dataplaneUrl, sourceIdOrKey, grantIdOrKey, authConfig) {
38
46
  const client = new ApiClient(dataplaneUrl, authConfig);
39
47
  return await client.get(`/api/v1/external/${sourceIdOrKey}/grants/${grantIdOrKey}`);
40
48
  }
49
+ /** @requiresPermission {Dataplane} external-system:update */
41
50
  async function updateGrant(dataplaneUrl, sourceIdOrKey, grantIdOrKey, authConfig, updateData) {
42
51
  const client = new ApiClient(dataplaneUrl, authConfig);
43
52
  return await client.put(`/api/v1/external/${sourceIdOrKey}/grants/${grantIdOrKey}`, { body: updateData });
@@ -46,10 +55,12 @@ async function deleteGrant(dataplaneUrl, sourceIdOrKey, grantIdOrKey, authConfig
46
55
  const client = new ApiClient(dataplaneUrl, authConfig);
47
56
  return await client.delete(`/api/v1/external/${sourceIdOrKey}/grants/${grantIdOrKey}`);
48
57
  }
58
+ /** @requiresPermission {Dataplane} external-system:read (policies) */
49
59
  async function listPolicies(dataplaneUrl, sourceIdOrKey, authConfig, options = {}) {
50
60
  const client = new ApiClient(dataplaneUrl, authConfig);
51
61
  return await client.get(`/api/v1/external/${sourceIdOrKey}/policies`, { params: options });
52
62
  }
63
+ /** @requiresPermission {Dataplane} external-system:update */
53
64
  async function attachPolicy(dataplaneUrl, sourceIdOrKey, authConfig, policyData) {
54
65
  const client = new ApiClient(dataplaneUrl, authConfig);
55
66
  return await client.post(`/api/v1/external/${sourceIdOrKey}/policies`, { body: policyData });
@@ -58,6 +69,7 @@ async function detachPolicy(dataplaneUrl, sourceIdOrKey, policyIdOrKey, authConf
58
69
  const client = new ApiClient(dataplaneUrl, authConfig);
59
70
  return await client.delete(`/api/v1/external/${sourceIdOrKey}/policies/${policyIdOrKey}`);
60
71
  }
72
+ /** @requiresPermission {Dataplane} external-system:read (sync) */
61
73
  async function listSyncJobs(dataplaneUrl, sourceIdOrKey, authConfig, options = {}) {
62
74
  const client = new ApiClient(dataplaneUrl, authConfig);
63
75
  return await client.get(`/api/v1/external/${sourceIdOrKey}/sync`, { params: options });
@@ -66,10 +78,12 @@ async function createSyncJob(dataplaneUrl, sourceIdOrKey, authConfig, syncData)
66
78
  const client = new ApiClient(dataplaneUrl, authConfig);
67
79
  return await client.post(`/api/v1/external/${sourceIdOrKey}/sync`, { body: syncData });
68
80
  }
81
+ /** @requiresPermission {Dataplane} external-system:read */
69
82
  async function getSyncJob(dataplaneUrl, sourceIdOrKey, syncJobId, authConfig) {
70
83
  const client = new ApiClient(dataplaneUrl, authConfig);
71
84
  return await client.get(`/api/v1/external/${sourceIdOrKey}/sync/${syncJobId}`);
72
85
  }
86
+ /** @requiresPermission {Dataplane} external-system:update */
73
87
  async function updateSyncJob(dataplaneUrl, sourceIdOrKey, syncJobId, authConfig, updateData) {
74
88
  const client = new ApiClient(dataplaneUrl, authConfig);
75
89
  return await client.put(`/api/v1/external/${sourceIdOrKey}/sync/${syncJobId}`, { body: updateData });
@@ -78,14 +92,17 @@ async function executeSyncJob(dataplaneUrl, sourceIdOrKey, syncJobId, authConfig
78
92
  const client = new ApiClient(dataplaneUrl, authConfig);
79
93
  return await client.post(`/api/v1/external/${sourceIdOrKey}/sync/${syncJobId}/execute`);
80
94
  }
95
+ /** @requiresPermission {Dataplane} document-record or external-system scope */
81
96
  async function validateDocuments(dataplaneUrl, sourceIdOrKey, authConfig, validateData) {
82
97
  const client = new ApiClient(dataplaneUrl, authConfig);
83
98
  return await client.post(`/api/v1/external/data-sources/${sourceIdOrKey}/documents/validate`, { body: validateData });
84
99
  }
100
+ /** @requiresPermission {Dataplane} document-record or external-system scope */
85
101
  async function bulkDocuments(dataplaneUrl, sourceIdOrKey, authConfig, bulkData) {
86
102
  const client = new ApiClient(dataplaneUrl, authConfig);
87
103
  return await client.post(`/api/v1/external/data-sources/${sourceIdOrKey}/documents/bulk`, { body: bulkData });
88
104
  }
105
+ /** @requiresPermission {Dataplane} document-record:read or external-system:read */
89
106
  async function listDocuments(dataplaneUrl, sourceIdOrKey, authConfig, options = {}) {
90
107
  const client = new ApiClient(dataplaneUrl, authConfig);
91
108
  return await client.get(`/api/v1/external/data-sources/${sourceIdOrKey}/documents`, { params: options });
@@ -9,6 +9,7 @@ const { ApiClient } = require('./index');
9
9
  /**
10
10
  * Deploy an application to an environment
11
11
  * POST /api/v1/environments/{envKey}/applications/deploy
12
+ * @requiresPermission {Controller} applications:deploy
12
13
  * @async
13
14
  * @function deployApplication
14
15
  * @param {string} controllerUrl - Controller base URL
@@ -32,6 +33,7 @@ async function deployApplication(controllerUrl, envKey, authConfig, deployData)
32
33
  /**
33
34
  * Deploy environment infrastructure
34
35
  * POST /api/v1/environments/{envKey}/deploy
36
+ * @requiresPermission {Controller} controller:deploy
35
37
  * @async
36
38
  * @function deployEnvironment
37
39
  * @param {string} controllerUrl - Controller base URL
@@ -53,6 +55,7 @@ async function deployEnvironment(controllerUrl, envKey, authConfig, deployData)
53
55
  /**
54
56
  * List deployments for an environment
55
57
  * GET /api/v1/environments/{envKey}/deployments
58
+ * @requiresPermission {Controller} deployments:read
56
59
  * @async
57
60
  * @function listDeployments
58
61
  * @param {string} controllerUrl - Controller base URL
@@ -79,6 +82,7 @@ async function listDeployments(controllerUrl, envKey, authConfig, options = {})
79
82
  /**
80
83
  * Get deployment with jobs and logs
81
84
  * GET /api/v1/environments/{envKey}/deployments/{deploymentId}
85
+ * @requiresPermission {Controller} deployments:read
82
86
  * @async
83
87
  * @function getDeployment
84
88
  * @param {string} controllerUrl - Controller base URL
@@ -96,6 +100,7 @@ async function getDeployment(controllerUrl, envKey, deploymentId, authConfig) {
96
100
  /**
97
101
  * Get deployment job logs
98
102
  * GET /api/v1/environments/{envKey}/deployments/{deploymentId}/logs
103
+ * @requiresPermission {Controller} deployments:read
99
104
  * @async
100
105
  * @function getDeploymentLogs
101
106
  * @param {string} controllerUrl - Controller base URL
@@ -119,7 +124,7 @@ async function getDeploymentLogs(controllerUrl, envKey, deploymentId, authConfig
119
124
  /**
120
125
  * List deployments for a single application in an environment
121
126
  * GET /api/v1/environments/{envKey}/applications/{appKey}/deployments
122
- *
127
+ * @requiresPermission {Controller} deployments:read
123
128
  * @async
124
129
  * @function listApplicationDeployments
125
130
  * @param {string} controllerUrl - Controller base URL
@@ -9,6 +9,7 @@ const { ApiClient } = require('./index');
9
9
  /**
10
10
  * List all environments
11
11
  * GET /api/v1/environments
12
+ * @requiresPermission {Controller} environments:read
12
13
  * @async
13
14
  * @function listEnvironments
14
15
  * @param {string} controllerUrl - Controller base URL
@@ -34,6 +35,7 @@ async function listEnvironments(controllerUrl, authConfig, options = {}) {
34
35
  /**
35
36
  * Create new environment
36
37
  * POST /api/v1/environments
38
+ * @requiresPermission {Controller} environments:create
37
39
  * @async
38
40
  * @function createEnvironment
39
41
  * @param {string} controllerUrl - Controller base URL
@@ -55,6 +57,7 @@ async function createEnvironment(controllerUrl, authConfig, environmentData) {
55
57
  /**
56
58
  * Get environment by key
57
59
  * GET /api/v1/environments/{envKey}
60
+ * @requiresPermission {Controller} environments:read
58
61
  * @async
59
62
  * @function getEnvironment
60
63
  * @param {string} controllerUrl - Controller base URL
@@ -71,6 +74,7 @@ async function getEnvironment(controllerUrl, envKey, authConfig) {
71
74
  /**
72
75
  * Update environment by key
73
76
  * PATCH /api/v1/environments/{envKey}
77
+ * @requiresPermission {Controller} environments:update
74
78
  * @async
75
79
  * @function updateEnvironment
76
80
  * @param {string} controllerUrl - Controller base URL
@@ -91,6 +95,7 @@ async function updateEnvironment(controllerUrl, envKey, authConfig, updateData)
91
95
  /**
92
96
  * Get environment status
93
97
  * GET /api/v1/environments/{envKey}/status
98
+ * @requiresPermission {Controller} environments:read
94
99
  * @async
95
100
  * @function getEnvironmentStatus
96
101
  * @param {string} controllerUrl - Controller base URL
@@ -107,6 +112,7 @@ async function getEnvironmentStatus(controllerUrl, envKey, authConfig) {
107
112
  /**
108
113
  * List applications in an environment
109
114
  * GET /api/v1/environments/{envKey}/applications
115
+ * @requiresPermission {Controller} environments-applications:read
110
116
  * @async
111
117
  * @function listEnvironmentApplications
112
118
  * @param {string} controllerUrl - Controller base URL
@@ -131,6 +137,7 @@ async function listEnvironmentApplications(controllerUrl, envKey, authConfig, op
131
137
  /**
132
138
  * List deployments for environment
133
139
  * GET /api/v1/environments/{envKey}/deployments
140
+ * @requiresPermission {Controller} deployments:read
134
141
  * @async
135
142
  * @function listEnvironmentDeployments
136
143
  * @param {string} controllerUrl - Controller base URL
@@ -156,6 +163,7 @@ async function listEnvironmentDeployments(controllerUrl, envKey, authConfig, opt
156
163
  /**
157
164
  * List roles for environment
158
165
  * GET /api/v1/environments/{envKey}/roles
166
+ * @requiresPermission {Controller} environments:read
159
167
  * @async
160
168
  * @function listEnvironmentRoles
161
169
  * @param {string} controllerUrl - Controller base URL
@@ -172,6 +180,7 @@ async function listEnvironmentRoles(controllerUrl, envKey, authConfig) {
172
180
  /**
173
181
  * Map role to groups for environment
174
182
  * PATCH /api/v1/environments/{envKey}/roles/{value}/groups
183
+ * @requiresPermission {Controller} environments:update
175
184
  * @async
176
185
  * @function updateRoleGroups
177
186
  * @param {string} controllerUrl - Controller base URL
@@ -192,6 +201,7 @@ async function updateRoleGroups(controllerUrl, envKey, roleValue, authConfig, gr
192
201
  /**
193
202
  * Get application details in an environment
194
203
  * GET /api/v1/environments/{envKey}/applications/{appKey}
204
+ * @requiresPermission {Controller} environments-applications:read
195
205
  * @async
196
206
  * @function getEnvironmentApplication
197
207
  * @param {string} controllerUrl - Controller base URL
@@ -209,6 +219,7 @@ async function getEnvironmentApplication(controllerUrl, envKey, appKey, authConf
209
219
  /**
210
220
  * List datasources in an environment
211
221
  * GET /api/v1/environments/{envKey}/datasources
222
+ * @requiresPermission {Controller} environments:read (or datasources scope per controller spec)
212
223
  * @async
213
224
  * @function listEnvironmentDatasources
214
225
  * @param {string} controllerUrl - Controller base URL
@@ -9,6 +9,7 @@ const { ApiClient } = require('./index');
9
9
  /**
10
10
  * List external systems
11
11
  * GET /api/v1/external/systems
12
+ * @requiresPermission {Dataplane} external-system:read
12
13
  * @async
13
14
  * @function listExternalSystems
14
15
  * @param {string} dataplaneUrl - Dataplane base URL
@@ -32,6 +33,7 @@ async function listExternalSystems(dataplaneUrl, authConfig, options = {}) {
32
33
  /**
33
34
  * Create external system
34
35
  * POST /api/v1/external/systems
36
+ * @requiresPermission {Dataplane} external-system:create
35
37
  * @async
36
38
  * @function createExternalSystem
37
39
  * @param {string} dataplaneUrl - Dataplane base URL
@@ -50,12 +52,16 @@ async function createExternalSystem(dataplaneUrl, authConfig, systemData) {
50
52
  /**
51
53
  * Get external system details
52
54
  * GET /api/v1/external/systems/{systemIdOrKey}
55
+ * @requiresPermission {Dataplane} external-system:read
53
56
  * @async
54
57
  * @function getExternalSystem
55
58
  * @param {string} dataplaneUrl - Dataplane base URL
56
59
  * @param {string} systemIdOrKey - System ID or key
57
60
  * @param {Object} authConfig - Authentication configuration
58
- * @returns {Promise<Object>} External system details response
61
+ * @returns {Promise<Object>} External system details response. May include optional fields:
62
+ * - {string} [mcpServerUrl] - Full URL of external system MCP server when configured
63
+ * - {string} [apiDocumentUrl] - Full URL of API document (OpenAPI spec) when configured
64
+ * - {string} [openApiDocsPageUrl] - Full URL of dataplane API docs page when showOpenApiDocs is true
59
65
  * @throws {Error} If request fails
60
66
  */
61
67
  async function getExternalSystem(dataplaneUrl, systemIdOrKey, authConfig) {
@@ -66,6 +72,7 @@ async function getExternalSystem(dataplaneUrl, systemIdOrKey, authConfig) {
66
72
  /**
67
73
  * Update external system
68
74
  * PUT /api/v1/external/systems/{systemIdOrKey}
75
+ * @requiresPermission {Dataplane} external-system:update
69
76
  * @async
70
77
  * @function updateExternalSystem
71
78
  * @param {string} dataplaneUrl - Dataplane base URL
@@ -85,6 +92,7 @@ async function updateExternalSystem(dataplaneUrl, systemIdOrKey, authConfig, upd
85
92
  /**
86
93
  * Delete external system (soft delete)
87
94
  * DELETE /api/v1/external/systems/{systemIdOrKey}
95
+ * @requiresPermission {Dataplane} external-system:delete
88
96
  * @async
89
97
  * @function deleteExternalSystem
90
98
  * @param {string} dataplaneUrl - Dataplane base URL
@@ -101,6 +109,7 @@ async function deleteExternalSystem(dataplaneUrl, systemIdOrKey, authConfig) {
101
109
  /**
102
110
  * Get full config with application schema and dataSources
103
111
  * GET /api/v1/external/systems/{systemIdOrKey}/config
112
+ * @requiresPermission {Dataplane} external-system:read
104
113
  * @async
105
114
  * @function getExternalSystemConfig
106
115
  * @param {string} dataplaneUrl - Dataplane base URL
@@ -117,6 +126,7 @@ async function getExternalSystemConfig(dataplaneUrl, systemIdOrKey, authConfig)
117
126
  /**
118
127
  * Create external system from integration template
119
128
  * POST /api/v1/external/systems/from-template
129
+ * @requiresPermission {Dataplane} external-system:create
120
130
  * @async
121
131
  * @function createFromTemplate
122
132
  * @param {string} dataplaneUrl - Dataplane base URL
@@ -138,6 +148,7 @@ async function createFromTemplate(dataplaneUrl, authConfig, templateData) {
138
148
  /**
139
149
  * List OpenAPI files for system
140
150
  * GET /api/v1/external/systems/{systemIdOrKey}/openapi-files
151
+ * @requiresPermission {Dataplane} external-system:read
141
152
  * @async
142
153
  * @function listOpenAPIFiles
143
154
  * @param {string} dataplaneUrl - Dataplane base URL
@@ -157,6 +168,7 @@ async function listOpenAPIFiles(dataplaneUrl, systemIdOrKey, authConfig, options
157
168
  /**
158
169
  * List OpenAPI endpoints for system
159
170
  * GET /api/v1/external/systems/{systemIdOrKey}/openapi-endpoints
171
+ * @requiresPermission {Dataplane} external-system:read
160
172
  * @async
161
173
  * @function listOpenAPIEndpoints
162
174
  * @param {string} dataplaneUrl - Dataplane base URL
@@ -176,6 +188,7 @@ async function listOpenAPIEndpoints(dataplaneUrl, systemIdOrKey, authConfig, opt
176
188
  /**
177
189
  * Publish external system
178
190
  * POST /api/v1/external/systems/{systemIdOrKey}/publish
191
+ * @requiresPermission {Dataplane} external-system:update (or publish scope per dataplane spec)
179
192
  * @async
180
193
  * @function publishExternalSystem
181
194
  * @param {string} dataplaneUrl - Dataplane base URL
@@ -196,6 +209,7 @@ async function publishExternalSystem(dataplaneUrl, systemIdOrKey, authConfig, pu
196
209
  /**
197
210
  * Rollback external system to version
198
211
  * POST /api/v1/external/systems/{systemIdOrKey}/rollback
212
+ * @requiresPermission {Dataplane} external-system:update
199
213
  * @async
200
214
  * @function rollbackExternalSystem
201
215
  * @param {string} dataplaneUrl - Dataplane base URL
@@ -216,6 +230,7 @@ async function rollbackExternalSystem(dataplaneUrl, systemIdOrKey, authConfig, r
216
230
  /**
217
231
  * Save external system as integration template
218
232
  * POST /api/v1/external/systems/{systemIdOrKey}/save-template
233
+ * @requiresPermission {Dataplane} external-system:update
219
234
  * @async
220
235
  * @function saveAsTemplate
221
236
  * @param {string} dataplaneUrl - Dataplane base URL