@aifabrix/builder 2.44.6 → 2.45.5

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 (257) hide show
  1. package/.cursor/rules/cli-layout.mdc +7 -3
  2. package/.cursor/rules/docs-rules.mdc +3 -1
  3. package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +1 -1
  4. package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.yaml +1 -1
  5. package/integration/hubspot-test/wizard-hubspot-e2e.yaml +1 -1
  6. package/jest.projects.js +100 -1
  7. package/lib/api/agent-metadata-validation.api.js +93 -0
  8. package/lib/api/audit-api-helpers.js +68 -0
  9. package/lib/api/audit.api.js +119 -0
  10. package/lib/api/auth-cache.api.js +44 -0
  11. package/lib/api/certificates.api.js +4 -4
  12. package/lib/api/credential.api.js +2 -2
  13. package/lib/api/dataplane-health.api.js +137 -0
  14. package/lib/api/dataplane-sync.api.js +27 -0
  15. package/lib/api/datasources-core.api.js +21 -18
  16. package/lib/api/datasources-extended.api.js +22 -22
  17. package/lib/api/dimensions.api.js +3 -0
  18. package/lib/api/external-systems.api.js +13 -13
  19. package/lib/api/governance-scenarios.api.js +39 -0
  20. package/lib/api/groups.api.js +79 -0
  21. package/lib/api/index.js +45 -2
  22. package/lib/api/pipeline.api.js +4 -4
  23. package/lib/api/protection.api.js +157 -0
  24. package/lib/api/records-bulk.api.js +30 -0
  25. package/lib/api/records-search-parse.js +49 -0
  26. package/lib/api/records-search.api.js +29 -0
  27. package/lib/api/types/agent-metadata-validation.types.js +67 -0
  28. package/lib/api/types/audit.types.js +72 -0
  29. package/lib/api/types/dataplane-health.types.js +27 -0
  30. package/lib/api/types/dimensions.types.js +2 -0
  31. package/lib/api/types/governance-scenarios.types.js +39 -0
  32. package/lib/api/types/protection.types.js +69 -0
  33. package/lib/api/types/records-bulk.types.js +35 -0
  34. package/lib/api/types/records-search.types.js +28 -0
  35. package/lib/api/user-groups.api.js +50 -0
  36. package/lib/api/users.api.js +95 -0
  37. package/lib/api/validation-run.api.js +3 -3
  38. package/lib/api/validation-runner.js +3 -3
  39. package/lib/api/wizard-platform.api.js +3 -3
  40. package/lib/api/wizard.api.js +21 -21
  41. package/lib/app/deploy.js +34 -19
  42. package/lib/app/helpers.js +3 -3
  43. package/lib/app/index.js +3 -3
  44. package/lib/app/register.js +7 -6
  45. package/lib/app/restart-display.js +52 -21
  46. package/lib/app/rotate-secret.js +7 -6
  47. package/lib/app/run-helpers.js +15 -8
  48. package/lib/app/run.js +57 -9
  49. package/lib/app/show-display.js +7 -0
  50. package/lib/app/show.js +87 -5
  51. package/lib/build/index.js +9 -5
  52. package/lib/cli/index.js +4 -2
  53. package/lib/cli/infra-guided.js +62 -28
  54. package/lib/cli/installation-log-command.js +73 -0
  55. package/lib/cli/setup-app.help.js +50 -2
  56. package/lib/cli/setup-app.js +44 -25
  57. package/lib/cli/setup-app.test-commands.js +80 -21
  58. package/lib/cli/setup-auth.js +124 -52
  59. package/lib/cli/setup-external-system.js +37 -3
  60. package/lib/cli/setup-infra-up-dataplane-action.js +111 -0
  61. package/lib/cli/setup-infra-up-platform-action.js +131 -0
  62. package/lib/cli/setup-infra.js +60 -119
  63. package/lib/cli/setup-platform.js +1 -1
  64. package/lib/cli/setup-utility-help-after.js +45 -0
  65. package/lib/cli/setup-utility-resolve.js +132 -0
  66. package/lib/cli/setup-utility.js +148 -116
  67. package/lib/commands/app-logs.js +81 -33
  68. package/lib/commands/auth-config.js +116 -18
  69. package/lib/commands/auth-status-dataplane-version.js +231 -0
  70. package/lib/commands/auth-status-display.js +94 -0
  71. package/lib/commands/auth-status.js +70 -6
  72. package/lib/commands/credential-push.js +10 -5
  73. package/lib/commands/datasource-load-export-cli.js +178 -0
  74. package/lib/commands/datasource-test-trust-cli.js +114 -0
  75. package/lib/commands/datasource-unified-test-cli.js +25 -17
  76. package/lib/commands/datasource-unified-test-cli.options.js +18 -3
  77. package/lib/commands/datasource-unified-test-e2e-cli-helpers.js +5 -5
  78. package/lib/commands/datasource-verify-audit-cli.js +96 -0
  79. package/lib/commands/datasource.js +68 -1
  80. package/lib/commands/dimension-value.js +43 -13
  81. package/lib/commands/dimension.js +38 -7
  82. package/lib/commands/identity-apply-sync.js +131 -0
  83. package/lib/commands/identity-group-cli.js +146 -0
  84. package/lib/commands/identity-membership-role-cache.js +175 -0
  85. package/lib/commands/identity-shared.js +94 -0
  86. package/lib/commands/identity-user-cli.js +158 -0
  87. package/lib/commands/identity.js +43 -0
  88. package/lib/commands/login.js +46 -16
  89. package/lib/commands/protection-cli-leaves.js +286 -0
  90. package/lib/commands/protection.js +50 -0
  91. package/lib/commands/repair.js +13 -3
  92. package/lib/commands/setup-modes.js +19 -6
  93. package/lib/commands/setup-prompts.js +41 -8
  94. package/lib/commands/setup.js +114 -9
  95. package/lib/commands/teardown.js +54 -5
  96. package/lib/commands/test-e2e-external.js +40 -9
  97. package/lib/commands/test-governance-cli-options.js +47 -0
  98. package/lib/commands/test-governance-command-action.js +55 -0
  99. package/lib/commands/test-governance-external.js +88 -0
  100. package/lib/commands/test-trust-cli-options.js +32 -0
  101. package/lib/commands/test-trust-command-action.js +118 -0
  102. package/lib/commands/test-trust-external.js +127 -0
  103. package/lib/commands/up-common.js +48 -14
  104. package/lib/commands/up-dataplane.js +21 -18
  105. package/lib/commands/up-miso.js +12 -8
  106. package/lib/commands/upload.js +38 -15
  107. package/lib/commands/wizard-core.js +3 -0
  108. package/lib/core/audit-logger.js +1 -34
  109. package/lib/core/config-admin-email.js +56 -0
  110. package/lib/core/config-device-dataplane.js +185 -0
  111. package/lib/core/config-normalize.js +60 -0
  112. package/lib/core/config-registered-controller-urls.js +54 -0
  113. package/lib/core/config.js +33 -50
  114. package/lib/core/secrets-ensure-infra.js +1 -1
  115. package/lib/core/secrets-env-content.js +86 -90
  116. package/lib/core/secrets-env-declarative-expand.js +170 -0
  117. package/lib/core/secrets-env-write.js +2 -0
  118. package/lib/core/secrets-load.js +106 -102
  119. package/lib/datasource/agent-trust-debug-log.js +45 -0
  120. package/lib/datasource/agent-trust-fetch.js +115 -0
  121. package/lib/datasource/agent-trust-map.js +101 -0
  122. package/lib/datasource/agent-trust-mock.js +44 -0
  123. package/lib/datasource/agent-trust-run.js +93 -0
  124. package/lib/datasource/agent-trust-timeout.js +25 -0
  125. package/lib/datasource/audit-evidence-display.js +80 -0
  126. package/lib/datasource/audit-evidence-extract-debug.js +103 -0
  127. package/lib/datasource/audit-evidence-extract.js +177 -0
  128. package/lib/datasource/audit-evidence-matrix-rows.js +158 -0
  129. package/lib/datasource/audit-evidence-operation-aliases.js +63 -0
  130. package/lib/datasource/audit-evidence-poll.js +109 -0
  131. package/lib/datasource/audit-evidence-run.js +177 -0
  132. package/lib/datasource/audit-evidence-verify-helpers.js +167 -0
  133. package/lib/datasource/audit-evidence-verify-matrix.js +177 -0
  134. package/lib/datasource/audit-evidence-verify.js +108 -0
  135. package/lib/datasource/bulk-loader-run-batches.js +88 -0
  136. package/lib/datasource/bulk-loader-service-retry.js +52 -0
  137. package/lib/datasource/bulk-loader-service.js +127 -0
  138. package/lib/datasource/capability/run-capability-dimension.js +2 -1
  139. package/lib/datasource/datasource-exporter-resolve.js +82 -0
  140. package/lib/datasource/datasource-exporter-service.js +144 -0
  141. package/lib/datasource/datasource-identifier.js +148 -0
  142. package/lib/datasource/datasource-load-export-context.js +92 -0
  143. package/lib/datasource/integration-context.js +6 -4
  144. package/lib/datasource/local-data-paths.js +145 -0
  145. package/lib/datasource/log-cleaner.js +241 -0
  146. package/lib/datasource/log-viewer.js +111 -6
  147. package/lib/datasource/record-file-parser.js +85 -0
  148. package/lib/datasource/record-mapper.js +129 -0
  149. package/lib/datasource/resolve-app.js +74 -55
  150. package/lib/datasource/test-e2e.js +26 -2
  151. package/lib/datasource/unified-validation-run-resolve.js +45 -12
  152. package/lib/datasource/unified-validation-run.js +43 -17
  153. package/lib/datasource/validate.js +37 -20
  154. package/lib/external-system/deploy.js +5 -1
  155. package/lib/external-system/test-system-level.js +25 -4
  156. package/lib/external-system/test.js +3 -1
  157. package/lib/governance/governance-pack-loader.js +70 -0
  158. package/lib/governance/governance-run-display.js +119 -0
  159. package/lib/identity/identity-apply-core.js +108 -0
  160. package/lib/identity/identity-apply-phases.js +244 -0
  161. package/lib/identity/identity-apply-service.js +77 -0
  162. package/lib/identity/identity-csv-parser.js +114 -0
  163. package/lib/internal/fs-real-sync.js +29 -1
  164. package/lib/internal/node-fs.js +2 -0
  165. package/lib/protection/auth-context.js +45 -0
  166. package/lib/protection/convert-batch.js +90 -0
  167. package/lib/protection/load.js +41 -0
  168. package/lib/protection/paths.js +158 -0
  169. package/lib/protection/preflight-datasource-ready.js +46 -0
  170. package/lib/protection/protection-create-probe-lines.js +142 -0
  171. package/lib/protection/protection-create-probes.js +95 -0
  172. package/lib/protection/protection-create-scaffold.js +281 -0
  173. package/lib/protection/protection-display-helpers.js +445 -0
  174. package/lib/protection/protection-display.js +215 -0
  175. package/lib/protection/protection-preset-registry.js +97 -0
  176. package/lib/protection/report-exit.js +62 -0
  177. package/lib/protection/resolve.js +202 -0
  178. package/lib/protection/run-commands-validate.js +130 -0
  179. package/lib/protection/run-commands.js +216 -0
  180. package/lib/protection/run-protection-create-helpers.js +134 -0
  181. package/lib/protection/run-protection-create-probes-flow.js +43 -0
  182. package/lib/protection/run-protection-create.js +191 -0
  183. package/lib/protection/scope.js +22 -0
  184. package/lib/protection/sync-after-upload.js +64 -0
  185. package/lib/protection/upload-batch.js +127 -0
  186. package/lib/protection/validate-batch.js +113 -0
  187. package/lib/protection/validate-local.js +65 -0
  188. package/lib/resolvers/dimension-file.js +29 -4
  189. package/lib/schema/application-schema.json +4 -0
  190. package/lib/schema/external-datasource.schema.json +47 -13
  191. package/lib/schema/flag-map-validation-run.json +2 -2
  192. package/lib/schema/infra.parameter.yaml +10 -0
  193. package/lib/schema/protection.schema.json +374 -0
  194. package/lib/schema/type/credential-field-registry.json +636 -0
  195. package/lib/schema/wizard-config.schema.json +1 -1
  196. package/lib/utils/agent-trust-run-display.js +231 -0
  197. package/lib/utils/agent-trust-run-exit.js +59 -0
  198. package/lib/utils/agent-trust-wait-ui.js +94 -0
  199. package/lib/utils/app-config-resolver.js +24 -1
  200. package/lib/utils/applications-config-defaults.js +206 -0
  201. package/lib/utils/auth-config-validator.js +2 -12
  202. package/lib/utils/bash-secret-env.js +1 -1
  203. package/lib/utils/cli-exit-codes.js +30 -0
  204. package/lib/utils/cli-sync-options.js +33 -0
  205. package/lib/utils/compose-generate-docker-compose.js +111 -6
  206. package/lib/utils/compose-generator.js +17 -8
  207. package/lib/utils/controller-url.js +50 -7
  208. package/lib/utils/credential-push-ui.js +90 -0
  209. package/lib/utils/dataplane-cli-version-gate.js +202 -0
  210. package/lib/utils/dataplane-cli-version-help.js +74 -0
  211. package/lib/utils/datasource-export-display.js +137 -0
  212. package/lib/utils/datasource-load-display.js +174 -0
  213. package/lib/utils/datasource-load-export-ui.js +120 -0
  214. package/lib/utils/datasource-test-run-capability-scope.js +3 -3
  215. package/lib/utils/datasource-test-run-display.js +3 -3
  216. package/lib/utils/datasource-test-run-tty-log.js +5 -1
  217. package/lib/utils/env-copy.js +99 -14
  218. package/lib/utils/env-template.js +5 -1
  219. package/lib/utils/health-check-url.js +18 -15
  220. package/lib/utils/health-check.js +7 -5
  221. package/lib/utils/help-builder.js +30 -24
  222. package/lib/utils/infra-optional-service-flags.js +69 -0
  223. package/lib/utils/installation-log-core.js +282 -0
  224. package/lib/utils/installation-log-record.js +237 -0
  225. package/lib/utils/installation-log.js +123 -0
  226. package/lib/utils/log-redaction.js +105 -0
  227. package/lib/utils/manifest-location.js +164 -0
  228. package/lib/utils/manifest-source-emit.js +184 -0
  229. package/lib/utils/paths.js +238 -89
  230. package/lib/utils/remote-secrets-loader.js +7 -1
  231. package/lib/utils/run-cli-flags.js +29 -0
  232. package/lib/utils/secrets-canonical.js +10 -3
  233. package/lib/utils/secrets-path.js +3 -4
  234. package/lib/utils/secrets-utils.js +20 -10
  235. package/lib/utils/semver-compare.js +127 -0
  236. package/lib/utils/system-builder-root.js +10 -2
  237. package/lib/utils/upload-pipeline-ui.js +91 -0
  238. package/lib/utils/url-declarative-public-base.js +80 -12
  239. package/lib/utils/url-declarative-resolve-build-urls.js +238 -0
  240. package/lib/utils/url-declarative-resolve-build.js +24 -393
  241. package/lib/utils/url-declarative-resolve-expand-token.js +189 -0
  242. package/lib/utils/url-declarative-resolve-load-doc.js +12 -3
  243. package/lib/utils/url-declarative-resolve-surface-state.js +102 -0
  244. package/lib/utils/url-declarative-resolve.js +47 -7
  245. package/lib/utils/url-declarative-runtime-base-path.js +21 -1
  246. package/lib/utils/urls-local-registry-scan.js +103 -0
  247. package/lib/utils/urls-local-registry.js +161 -90
  248. package/lib/utils/validation-poll-ui.js +14 -7
  249. package/lib/validation/wizard-config-validator.js +58 -19
  250. package/package.json +3 -1
  251. package/templates/applications/dataplane/application.yaml +4 -0
  252. package/templates/applications/dataplane/env.template +13 -1
  253. package/templates/applications/dataplane/rbac.yaml +4 -0
  254. package/templates/applications/miso-controller/application.yaml +2 -0
  255. package/templates/applications/miso-controller/env.template +27 -29
  256. package/templates/external-system/README.md.hbs +56 -8
  257. package/.npmrc.token +0 -1
@@ -0,0 +1,69 @@
1
+ /**
2
+ * @fileoverview Protection API type definitions (dataplane /api/v1/protection/*).
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ /**
8
+ * @typedef {Object} ProtectionUploadRequest
9
+ * @property {Object} manifest - Full protection manifest document
10
+ */
11
+
12
+ /**
13
+ * @typedef {Object} ProtectionValidateOptions
14
+ * @property {boolean} [strict] - Promote WARN to FAIL
15
+ * @property {boolean} [explain]
16
+ * @property {number} [sampleSize] - For simulate
17
+ */
18
+
19
+ /**
20
+ * @typedef {Object} ProtectionDeployResponse
21
+ * @property {string} protectionKey
22
+ * @property {string} deploymentId
23
+ * @property {number} revision
24
+ * @property {string} configHash
25
+ * @property {string} deployedAt
26
+ * @property {Object} manifest
27
+ */
28
+
29
+ /**
30
+ * @typedef {Object} ProtectionManifestResponse
31
+ * @property {string} key
32
+ * @property {string} displayName
33
+ * @property {Object} spec
34
+ * @property {boolean} enabled
35
+ * @property {string} datasourceKey
36
+ * @property {number} [currentRevision]
37
+ * @property {string} [lastDeployedAt]
38
+ */
39
+
40
+ /**
41
+ * @typedef {Object} ProtectionListResult
42
+ * @property {ProtectionManifestResponse[]} items
43
+ * @property {Object|null} meta
44
+ * @property {*} raw
45
+ */
46
+
47
+ /**
48
+ * @typedef {Object} ProtectionGrantStatusSummary
49
+ * @property {string} dimensionKey
50
+ * @property {string} effectiveValueType
51
+ * @property {string} projectionRuleKey
52
+ */
53
+
54
+ /**
55
+ * @typedef {Object} ProtectionStatusResponse
56
+ * @property {string} protectionKey
57
+ * @property {boolean} enabled
58
+ * @property {string} datasourceKey
59
+ * @property {number} [currentRevision]
60
+ * @property {string} [configHash]
61
+ * @property {string} [lastDeployedAt]
62
+ * @property {string} [lastProjectionRunAt]
63
+ * @property {string} [lastSuccessfulProjectionRunAt]
64
+ * @property {number} [dynamicValueCount]
65
+ * @property {number} [grantCount]
66
+ * @property {ProtectionGrantStatusSummary[]} [grants]
67
+ */
68
+
69
+ module.exports = {};
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @fileoverview Types for dataplane bulk record sync API
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ /**
8
+ * Single record in a bulk sync request
9
+ * @typedef {Object} ExternalBulkRecord
10
+ * @property {string} key - External record key
11
+ * @property {string} displayName - Human-readable label
12
+ * @property {string} recordType - Resource type from datasource manifest
13
+ * @property {Object} metadata - Record metadata payload
14
+ */
15
+
16
+ /**
17
+ * Bulk sync request body
18
+ * @typedef {Object} ExternalRecordBulkRequest
19
+ * @property {'incremental'|'bulk'|'validate'} syncType - Sync mode
20
+ * @property {boolean} [sync] - Create linked sync job when true
21
+ * @property {ExternalBulkRecord[]} records - Records to process
22
+ */
23
+
24
+ /**
25
+ * Bulk sync response
26
+ * @typedef {Object} ExternalRecordBulkResponse
27
+ * @property {number} insertedCount
28
+ * @property {number} updatedCount
29
+ * @property {number} deletedCount
30
+ * @property {number} totalProcessed
31
+ * @property {number} [skippedCount]
32
+ * @property {Object} [recordSkipSummary]
33
+ */
34
+
35
+ module.exports = {};
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @fileoverview Types for dataplane Records Search API
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ /**
8
+ * Records search request
9
+ * @typedef {Object} RecordsSearchRequest
10
+ * @property {'retrieval'|'grounding'|'analytics'|'validation'} intent
11
+ * @property {string[]} [datasourceKeys]
12
+ * @property {string[]} [resourceTypes]
13
+ * @property {string|Object} [filters]
14
+ * @property {string|Object} [exclude]
15
+ * @property {'ids'|'full'} [searchMode]
16
+ * @property {number} [limit]
17
+ * @property {boolean} [dryRun]
18
+ */
19
+
20
+ /**
21
+ * Records search response
22
+ * @typedef {Object} RecordsSearchResponse
23
+ * @property {Array<string|Object>} data
24
+ * @property {Object} meta
25
+ * @property {Object} [links]
26
+ */
27
+
28
+ module.exports = {};
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @fileoverview User–group membership API (Controller)
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { ApiClient } = require('./index');
10
+
11
+ /**
12
+ * Add user to group
13
+ * @requiresPermission {Controller} users:update
14
+ * @async
15
+ * @param {string} controllerUrl
16
+ * @param {Object} authConfig
17
+ * @param {string} userId
18
+ * @param {string} groupId
19
+ * @param {Object} [body]
20
+ * @returns {Promise<Object>}
21
+ */
22
+ async function addUserToGroup(controllerUrl, authConfig, userId, groupId, body = {}) {
23
+ const client = new ApiClient(controllerUrl, authConfig);
24
+ return await client.post(
25
+ `/api/v1/users/${encodeURIComponent(userId)}/groups/${encodeURIComponent(groupId)}`,
26
+ { body }
27
+ );
28
+ }
29
+
30
+ /**
31
+ * Remove user from group
32
+ * @requiresPermission {Controller} users:update
33
+ * @async
34
+ * @param {string} controllerUrl
35
+ * @param {Object} authConfig
36
+ * @param {string} userId
37
+ * @param {string} groupId
38
+ * @returns {Promise<Object>}
39
+ */
40
+ async function removeUserFromGroup(controllerUrl, authConfig, userId, groupId) {
41
+ const client = new ApiClient(controllerUrl, authConfig);
42
+ return await client.delete(
43
+ `/api/v1/users/${encodeURIComponent(userId)}/groups/${encodeURIComponent(groupId)}`
44
+ );
45
+ }
46
+
47
+ module.exports = {
48
+ addUserToGroup,
49
+ removeUserFromGroup
50
+ };
@@ -0,0 +1,95 @@
1
+ /**
2
+ * @fileoverview Users API (Controller /api/v1/users)
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { ApiClient } = require('./index');
10
+
11
+ const BASE = '/api/v1/users';
12
+
13
+ /**
14
+ * List users (paginated)
15
+ * @requiresPermission {Controller} users:read
16
+ * @async
17
+ * @param {string} controllerUrl
18
+ * @param {Object} authConfig
19
+ * @param {Object} [options]
20
+ * @returns {Promise<Object>}
21
+ */
22
+ async function listUsers(controllerUrl, authConfig, options = {}) {
23
+ const client = new ApiClient(controllerUrl, authConfig);
24
+ return await client.get(BASE, { params: options });
25
+ }
26
+
27
+ /**
28
+ * Get user by id
29
+ * @requiresPermission {Controller} users:read
30
+ * @async
31
+ * @param {string} controllerUrl
32
+ * @param {Object} authConfig
33
+ * @param {string} userId
34
+ * @param {Object} [options]
35
+ * @returns {Promise<Object>}
36
+ */
37
+ async function getUser(controllerUrl, authConfig, userId, options = {}) {
38
+ const client = new ApiClient(controllerUrl, authConfig);
39
+ const params = {};
40
+ if (options.includeGroups) {
41
+ params.includeGroups = 'true';
42
+ }
43
+ return await client.get(`${BASE}/${encodeURIComponent(userId)}`, { params });
44
+ }
45
+
46
+ /**
47
+ * Create user
48
+ * @requiresPermission {Controller} users:create
49
+ * @async
50
+ * @param {string} controllerUrl
51
+ * @param {Object} authConfig
52
+ * @param {Object} body
53
+ * @returns {Promise<Object>}
54
+ */
55
+ async function createUser(controllerUrl, authConfig, body) {
56
+ const client = new ApiClient(controllerUrl, authConfig);
57
+ return await client.post(BASE, { body });
58
+ }
59
+
60
+ /**
61
+ * Patch user
62
+ * @requiresPermission {Controller} users:update
63
+ * @async
64
+ * @param {string} controllerUrl
65
+ * @param {Object} authConfig
66
+ * @param {string} userId
67
+ * @param {Object} body
68
+ * @returns {Promise<Object>}
69
+ */
70
+ async function updateUser(controllerUrl, authConfig, userId, body) {
71
+ const client = new ApiClient(controllerUrl, authConfig);
72
+ return await client.patch(`${BASE}/${encodeURIComponent(userId)}`, { body });
73
+ }
74
+
75
+ /**
76
+ * List groups for a user
77
+ * @requiresPermission {Controller} users:read
78
+ * @async
79
+ * @param {string} controllerUrl
80
+ * @param {Object} authConfig
81
+ * @param {string} userId
82
+ * @returns {Promise<Object>}
83
+ */
84
+ async function listUserGroups(controllerUrl, authConfig, userId) {
85
+ const client = new ApiClient(controllerUrl, authConfig);
86
+ return await client.get(`${BASE}/${encodeURIComponent(userId)}/groups`);
87
+ }
88
+
89
+ module.exports = {
90
+ listUsers,
91
+ getUser,
92
+ createUser,
93
+ updateUser,
94
+ listUserGroups
95
+ };
@@ -4,7 +4,7 @@
4
4
  * @version 2.0.0
5
5
  */
6
6
 
7
- const { ApiClient } = require('./index');
7
+ const { createDataplaneApiClient } = require('./index');
8
8
 
9
9
  const POST_PATH = '/api/v1/validation/run';
10
10
 
@@ -52,7 +52,7 @@ function normalizeDataplaneAuth(authConfig) {
52
52
  async function postValidationRun(dataplaneUrl, authConfig, body, transportOpts = {}) {
53
53
  const hdrs = buildClientCredentialHeaders(authConfig);
54
54
  const clientAuth = hdrs ? {} : normalizeDataplaneAuth(authConfig);
55
- const client = new ApiClient(dataplaneUrl, clientAuth);
55
+ const client = createDataplaneApiClient(dataplaneUrl, clientAuth);
56
56
  const postOpts = { body, headers: hdrs || undefined };
57
57
  if (Number.isFinite(transportOpts.timeoutMs) && transportOpts.timeoutMs > 0) {
58
58
  postOpts.timeoutMs = transportOpts.timeoutMs;
@@ -77,7 +77,7 @@ async function getValidationRun(dataplaneUrl, authConfig, testRunId, transportOp
77
77
  }
78
78
  const hdrs = buildClientCredentialHeaders(authConfig);
79
79
  const clientAuth = hdrs ? {} : normalizeDataplaneAuth(authConfig);
80
- const client = new ApiClient(dataplaneUrl, clientAuth);
80
+ const client = createDataplaneApiClient(dataplaneUrl, clientAuth);
81
81
  const path = `${POST_PATH}/${encodeURIComponent(testRunId)}`;
82
82
  const getOpts = { headers: hdrs || undefined };
83
83
  if (Number.isFinite(transportOpts.timeoutMs) && transportOpts.timeoutMs > 0) {
@@ -10,7 +10,6 @@ const { extractTestRunId } = require('./validation-run.api');
10
10
  const { postValidationRunWithTransportRetry } = require('../utils/validation-run-post-retry');
11
11
  const { pollValidationRunUntilComplete } = require('../utils/validation-run-poll');
12
12
  const { createValidationPollHandlers } = require('../utils/validation-poll-ui');
13
- const logger = require('../utils/logger');
14
13
 
15
14
  /**
16
15
  * POST /api/v1/validation/run and (when async) poll GET until reportCompleteness is full.
@@ -60,8 +59,9 @@ async function postValidationRunAndOptionalPoll(opts) {
60
59
  const remaining = Math.max(0, timeoutMs - elapsed);
61
60
  const deadlineMs = Date.now() + remaining;
62
61
 
63
- logger.log('');
64
- const pollUi = createValidationPollHandlers(deadlineMs);
62
+ const pollUi = createValidationPollHandlers(deadlineMs, {
63
+ subject: opts.pollSubject
64
+ });
65
65
  const mergeOnPollProgress =
66
66
  typeof opts.onPollProgress === 'function'
67
67
  ? (envelope, attemptIndex, meta) => {
@@ -4,7 +4,7 @@
4
4
  * @version 2.0.0
5
5
  */
6
6
 
7
- const { ApiClient } = require('./index');
7
+ const { createDataplaneApiClient } = require('./index');
8
8
 
9
9
  /**
10
10
  * Get platform details including available datasources
@@ -19,7 +19,7 @@ const { ApiClient } = require('./index');
19
19
  * @throws {Error} If request fails or platform not found (404)
20
20
  */
21
21
  async function getPlatformDetails(dataplaneUrl, authConfig, platformKey) {
22
- const client = new ApiClient(dataplaneUrl, authConfig);
22
+ const client = createDataplaneApiClient(dataplaneUrl, authConfig);
23
23
  const response = await client.get(`/api/v1/wizard/platforms/${encodeURIComponent(platformKey)}`);
24
24
  if (!response.success) {
25
25
  const msg = response.status === 404
@@ -45,7 +45,7 @@ async function getPlatformDetails(dataplaneUrl, authConfig, platformKey) {
45
45
  * @throws {Error} If request fails
46
46
  */
47
47
  async function discoverEntities(dataplaneUrl, authConfig, openapiSpec) {
48
- const client = new ApiClient(dataplaneUrl, authConfig);
48
+ const client = createDataplaneApiClient(dataplaneUrl, authConfig);
49
49
  const response = await client.post('/api/v1/wizard/discover-entities', {
50
50
  body: { openapiSpec }
51
51
  });
@@ -4,7 +4,7 @@
4
4
  * @version 2.0.0
5
5
  */
6
6
 
7
- const { ApiClient } = require('./index');
7
+ const { createDataplaneApiClient } = require('./index');
8
8
  const { uploadFile } = require('../utils/file-upload');
9
9
  const { getPlatformDetails, discoverEntities } = require('./wizard-platform.api');
10
10
 
@@ -22,7 +22,7 @@ const { getPlatformDetails, discoverEntities } = require('./wizard-platform.api'
22
22
  * @throws {Error} If request fails
23
23
  */
24
24
  async function createWizardSession(dataplaneUrl, authConfig, mode, systemIdOrKey = null) {
25
- const client = new ApiClient(dataplaneUrl, authConfig);
25
+ const client = createDataplaneApiClient(dataplaneUrl, authConfig);
26
26
  const body = { mode };
27
27
  if (systemIdOrKey) {
28
28
  body.systemIdOrKey = systemIdOrKey;
@@ -45,7 +45,7 @@ async function createWizardSession(dataplaneUrl, authConfig, mode, systemIdOrKey
45
45
  * @throws {Error} If request fails
46
46
  */
47
47
  async function getWizardSession(dataplaneUrl, sessionId, authConfig) {
48
- const client = new ApiClient(dataplaneUrl, authConfig);
48
+ const client = createDataplaneApiClient(dataplaneUrl, authConfig);
49
49
  return await client.get(`/api/v1/wizard/sessions/${sessionId}`);
50
50
  }
51
51
 
@@ -75,7 +75,7 @@ async function getWizardSession(dataplaneUrl, sessionId, authConfig) {
75
75
  * @throws {Error} If request fails
76
76
  */
77
77
  async function updateWizardSession(dataplaneUrl, sessionId, authConfig, updateData) {
78
- const client = new ApiClient(dataplaneUrl, authConfig);
78
+ const client = createDataplaneApiClient(dataplaneUrl, authConfig);
79
79
  return await client.put(`/api/v1/wizard/sessions/${sessionId}`, {
80
80
  body: updateData
81
81
  });
@@ -94,7 +94,7 @@ async function updateWizardSession(dataplaneUrl, sessionId, authConfig, updateDa
94
94
  * @throws {Error} If request fails
95
95
  */
96
96
  async function deleteWizardSession(dataplaneUrl, sessionId, authConfig) {
97
- const client = new ApiClient(dataplaneUrl, authConfig);
97
+ const client = createDataplaneApiClient(dataplaneUrl, authConfig);
98
98
  return await client.delete(`/api/v1/wizard/sessions/${sessionId}`);
99
99
  }
100
100
 
@@ -111,7 +111,7 @@ async function deleteWizardSession(dataplaneUrl, sessionId, authConfig) {
111
111
  * @throws {Error} If request fails
112
112
  */
113
113
  async function getWizardProgress(dataplaneUrl, sessionId, authConfig) {
114
- const client = new ApiClient(dataplaneUrl, authConfig);
114
+ const client = createDataplaneApiClient(dataplaneUrl, authConfig);
115
115
  return await client.get(`/api/v1/wizard/sessions/${sessionId}/progress`);
116
116
  }
117
117
 
@@ -130,7 +130,7 @@ async function getWizardProgress(dataplaneUrl, sessionId, authConfig) {
130
130
  */
131
131
  async function parseOpenApi(dataplaneUrl, authConfig, openApiFilePathOrUrl, isUrl = false) {
132
132
  if (isUrl) {
133
- const client = new ApiClient(dataplaneUrl, authConfig);
133
+ const client = createDataplaneApiClient(dataplaneUrl, authConfig);
134
134
  return await client.post(`/api/v1/wizard/parse-openapi?url=${encodeURIComponent(openApiFilePathOrUrl)}`);
135
135
  }
136
136
  const url = `${dataplaneUrl.replace(/\/$/, '')}/api/v1/wizard/parse-openapi`;
@@ -153,7 +153,7 @@ async function parseOpenApi(dataplaneUrl, authConfig, openApiFilePathOrUrl, isUr
153
153
  * @throws {Error} If request fails
154
154
  */
155
155
  async function credentialSelection(dataplaneUrl, authConfig, selectionData) {
156
- const client = new ApiClient(dataplaneUrl, authConfig);
156
+ const client = createDataplaneApiClient(dataplaneUrl, authConfig);
157
157
  return await client.post('/api/v1/wizard/credential-selection', {
158
158
  body: selectionData
159
159
  });
@@ -172,7 +172,7 @@ async function credentialSelection(dataplaneUrl, authConfig, selectionData) {
172
172
  * @throws {Error} If request fails
173
173
  */
174
174
  async function detectType(dataplaneUrl, authConfig, openapiSpec) {
175
- const client = new ApiClient(dataplaneUrl, authConfig);
175
+ const client = createDataplaneApiClient(dataplaneUrl, authConfig);
176
176
  return await client.post('/api/v1/wizard/detect-type', {
177
177
  body: { openapiSpec }
178
178
  });
@@ -199,7 +199,7 @@ async function detectType(dataplaneUrl, authConfig, openapiSpec) {
199
199
  * @throws {Error} If request fails
200
200
  */
201
201
  async function getPlatformConfig(dataplaneUrl, authConfig, platformKey, config) {
202
- const client = new ApiClient(dataplaneUrl, authConfig);
202
+ const client = createDataplaneApiClient(dataplaneUrl, authConfig);
203
203
  return await client.post(`/api/v1/wizard/platforms/${encodeURIComponent(platformKey)}/config`, {
204
204
  body: config
205
205
  });
@@ -233,7 +233,7 @@ async function getPlatformConfig(dataplaneUrl, authConfig, platformKey, config)
233
233
  * @throws {Error} If request fails
234
234
  */
235
235
  async function generateConfig(dataplaneUrl, authConfig, config) {
236
- const client = new ApiClient(dataplaneUrl, authConfig);
236
+ const client = createDataplaneApiClient(dataplaneUrl, authConfig);
237
237
  return await client.post('/api/v1/wizard/generate-config', {
238
238
  body: config
239
239
  });
@@ -252,7 +252,7 @@ async function generateConfig(dataplaneUrl, authConfig, config) {
252
252
  * @throws {Error} If request fails
253
253
  */
254
254
  async function generateConfigStream(dataplaneUrl, authConfig, config) {
255
- const client = new ApiClient(dataplaneUrl, authConfig);
255
+ const client = createDataplaneApiClient(dataplaneUrl, authConfig);
256
256
  return await client.post('/api/v1/wizard/generate-config-stream', {
257
257
  body: config
258
258
  });
@@ -272,7 +272,7 @@ async function generateConfigStream(dataplaneUrl, authConfig, config) {
272
272
  * @throws {Error} If request fails
273
273
  */
274
274
  async function validateWizardConfig(dataplaneUrl, authConfig, systemConfig, datasourceConfig) {
275
- const client = new ApiClient(dataplaneUrl, authConfig);
275
+ const client = createDataplaneApiClient(dataplaneUrl, authConfig);
276
276
  return await client.post('/api/v1/wizard/validate', {
277
277
  body: {
278
278
  systemConfig,
@@ -294,7 +294,7 @@ async function validateWizardConfig(dataplaneUrl, authConfig, systemConfig, data
294
294
  * @throws {Error} If request fails
295
295
  */
296
296
  async function validateAllSteps(dataplaneUrl, sessionId, authConfig) {
297
- const client = new ApiClient(dataplaneUrl, authConfig);
297
+ const client = createDataplaneApiClient(dataplaneUrl, authConfig);
298
298
  return await client.get(`/api/v1/wizard/sessions/${sessionId}/validate`);
299
299
  }
300
300
 
@@ -312,7 +312,7 @@ async function validateAllSteps(dataplaneUrl, sessionId, authConfig) {
312
312
  * @throws {Error} If request fails
313
313
  */
314
314
  async function validateStep(dataplaneUrl, sessionId, authConfig, stepNumber) {
315
- const client = new ApiClient(dataplaneUrl, authConfig);
315
+ const client = createDataplaneApiClient(dataplaneUrl, authConfig);
316
316
  return await client.post(`/api/v1/wizard/sessions/${sessionId}/validate-step?step=${stepNumber}`);
317
317
  }
318
318
 
@@ -329,7 +329,7 @@ async function validateStep(dataplaneUrl, sessionId, authConfig, stepNumber) {
329
329
  * @throws {Error} If request fails
330
330
  */
331
331
  async function getPreview(dataplaneUrl, sessionId, authConfig) {
332
- const client = new ApiClient(dataplaneUrl, authConfig);
332
+ const client = createDataplaneApiClient(dataplaneUrl, authConfig);
333
333
  return await client.get(`/api/v1/wizard/preview/${sessionId}`);
334
334
  }
335
335
 
@@ -347,7 +347,7 @@ async function getPreview(dataplaneUrl, sessionId, authConfig) {
347
347
  * @throws {Error} If request fails
348
348
  */
349
349
  async function testMcpConnection(dataplaneUrl, authConfig, serverUrl, token) {
350
- const client = new ApiClient(dataplaneUrl, authConfig);
350
+ const client = createDataplaneApiClient(dataplaneUrl, authConfig);
351
351
  return await client.post('/api/v1/wizard/test-mcp-connection', {
352
352
  body: {
353
353
  serverUrl,
@@ -369,7 +369,7 @@ async function testMcpConnection(dataplaneUrl, authConfig, serverUrl, token) {
369
369
  * @throws {Error} If request fails
370
370
  */
371
371
  async function getDeploymentDocs(dataplaneUrl, authConfig, systemKey) {
372
- const client = new ApiClient(dataplaneUrl, authConfig);
372
+ const client = createDataplaneApiClient(dataplaneUrl, authConfig);
373
373
  return await client.get(`/api/v1/wizard/deployment-docs/${systemKey}`);
374
374
  }
375
375
 
@@ -390,7 +390,7 @@ async function getDeploymentDocs(dataplaneUrl, authConfig, systemKey) {
390
390
  * @throws {Error} If request fails
391
391
  */
392
392
  async function postDeploymentDocs(dataplaneUrl, authConfig, systemKey, body = null) {
393
- const client = new ApiClient(dataplaneUrl, authConfig);
393
+ const client = createDataplaneApiClient(dataplaneUrl, authConfig);
394
394
  return await client.post(`/api/v1/wizard/deployment-docs/${systemKey}`, {
395
395
  body: body || {}
396
396
  });
@@ -410,7 +410,7 @@ async function postDeploymentDocs(dataplaneUrl, authConfig, systemKey, body = nu
410
410
  */
411
411
  async function getWizardPlatforms(dataplaneUrl, authConfig) {
412
412
  try {
413
- const client = new ApiClient(dataplaneUrl, authConfig);
413
+ const client = createDataplaneApiClient(dataplaneUrl, authConfig);
414
414
  const response = await client.get('/api/v1/wizard/platforms');
415
415
  const platforms = response?.data?.platforms ?? response?.platforms ?? [];
416
416
  return Array.isArray(platforms) ? platforms : [];
@@ -433,7 +433,7 @@ async function getWizardPlatforms(dataplaneUrl, authConfig) {
433
433
  * @throws {Error} If request fails
434
434
  */
435
435
  async function listWizardCredentials(dataplaneUrl, authConfig, options = {}) {
436
- const client = new ApiClient(dataplaneUrl, authConfig);
436
+ const client = createDataplaneApiClient(dataplaneUrl, authConfig);
437
437
  return await client.get('/api/v1/wizard/credentials', {
438
438
  params: options
439
439
  });
package/lib/app/deploy.js CHANGED
@@ -421,6 +421,35 @@ async function tryExternalDeployFallback(appName, options) {
421
421
  return { usedExternalDeploy: false, result: null };
422
422
  }
423
423
 
424
+ function assertDeployNotProtectionScope(appName) {
425
+ const { isProtectionScope } = require('../protection/scope');
426
+ if (!isProtectionScope(appName)) {
427
+ return;
428
+ }
429
+ const { formatDeployProtectionNotImplementedTTY } = require('../protection/protection-display');
430
+ logger.error(formatDeployProtectionNotImplementedTTY());
431
+ process.exit(1);
432
+ }
433
+
434
+ /**
435
+ * Run external, fallback, or standard deployment paths.
436
+ * @param {string} appName
437
+ * @param {Object} options
438
+ * @returns {Promise<{ result: Object, usedExternalDeploy: boolean, controllerUrl?: string }>}
439
+ */
440
+ async function executeDeployPipeline(appName, options) {
441
+ const externalResult = await handleExternalDeployment(appName, options);
442
+ if (externalResult) {
443
+ return { result: externalResult, usedExternalDeploy: true };
444
+ }
445
+ const fallback = await tryExternalDeployFallback(appName, options);
446
+ if (fallback.result) {
447
+ return { result: fallback.result, usedExternalDeploy: fallback.usedExternalDeploy };
448
+ }
449
+ const { result, controllerUrl } = await executeStandardDeployment(appName, options);
450
+ return { result, usedExternalDeploy: false, controllerUrl };
451
+ }
452
+
424
453
  /**
425
454
  * Deploys application to Miso Controller
426
455
  * Orchestrates manifest generation, key creation, and deployment
@@ -446,26 +475,12 @@ async function deployApp(appName, options = {}) {
446
475
  let usedExternalDeploy = false;
447
476
 
448
477
  try {
449
- if (!appName || typeof appName !== 'string' || appName.trim().length === 0) {
450
- throw new Error('App name is required');
451
- }
478
+ assertDeployNotProtectionScope(appName);
452
479
  validateAppName(appName);
453
-
454
- const externalResult = await handleExternalDeployment(appName, options);
455
- if (externalResult) {
456
- usedExternalDeploy = true;
457
- return { result: externalResult, usedExternalDeploy: true };
458
- }
459
-
460
- const fallback = await tryExternalDeployFallback(appName, options);
461
- if (fallback.result) {
462
- usedExternalDeploy = fallback.usedExternalDeploy;
463
- return { result: fallback.result, usedExternalDeploy };
464
- }
465
-
466
- const { result, controllerUrl: url } = await executeStandardDeployment(appName, options);
467
- controllerUrl = url;
468
- return { result, usedExternalDeploy: false };
480
+ const pipeline = await executeDeployPipeline(appName, options);
481
+ controllerUrl = pipeline.controllerUrl ?? null;
482
+ usedExternalDeploy = pipeline.usedExternalDeploy;
483
+ return { result: pipeline.result, usedExternalDeploy };
469
484
  } catch (error) {
470
485
  await handleDeploymentError(error, appName, controllerUrl, usedExternalDeploy);
471
486
  }
@@ -14,7 +14,7 @@ const path = require('path');
14
14
  const chalk = require('chalk');
15
15
  const { validateTemplate, copyTemplateFiles, copyAppFiles } = require('../validation/template');
16
16
  const logger = require('../utils/logger');
17
- const { getIntegrationPath, getBuilderPath } = require('../utils/paths');
17
+ const paths = require('../utils/paths');
18
18
 
19
19
  /**
20
20
  * Validates that no app or external system with this name exists in integration/ or builder/.
@@ -25,8 +25,8 @@ const { getIntegrationPath, getBuilderPath } = require('../utils/paths');
25
25
  * @throws {Error} If integration/<systemKey> or builder/<appKey> already exists
26
26
  */
27
27
  async function validateAppOrExternalNameNotExists(appName) {
28
- const integrationPath = getIntegrationPath(appName);
29
- const builderPath = getBuilderPath(appName);
28
+ const integrationPath = paths.getIntegrationPath(appName);
29
+ const builderPath = paths.getBuilderPath(appName);
30
30
  try {
31
31
  await fs.access(integrationPath);
32
32
  throw new Error(
package/lib/app/index.js CHANGED
@@ -21,7 +21,7 @@ const { loadTemplateVariables, updateTemplateVariables, mergeTemplateVariables }
21
21
  const { validateTemplate } = require('../validation/template');
22
22
  const auditLogger = require('../core/audit-logger');
23
23
  const { downApp } = require('./down');
24
- const { getAppPath } = require('../utils/paths');
24
+ const paths = require('../utils/paths');
25
25
  const { displaySuccessMessage } = require('./display');
26
26
  const {
27
27
  validateAppDirectoryNotExists,
@@ -93,7 +93,7 @@ function validateAppNameAndSetup(appName, options) {
93
93
 
94
94
  const initialType = options.type || 'external';
95
95
  const baseDir = getBaseDirForAppType(initialType);
96
- const appPath = getAppPath(appName, initialType);
96
+ const appPath = paths.getAppPath(appName, initialType);
97
97
 
98
98
  return { initialType, baseDir, appPath };
99
99
  }
@@ -124,7 +124,7 @@ async function handleTemplateSetup(options) {
124
124
  */
125
125
  async function prepareFinalAppPath(appName, config, initialAppPath) {
126
126
  const finalBaseDir = getBaseDirForAppType(config.type);
127
- const finalAppPath = getAppPath(appName, config.type);
127
+ const finalAppPath = paths.getAppPath(appName, config.type);
128
128
 
129
129
  // If path changed, validate the new path
130
130
  if (finalAppPath !== initialAppPath) {