@aifabrix/builder 2.45.0 → 2.46.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 (352) hide show
  1. package/.cursor/rules/cli-layout.mdc +2 -0
  2. package/.cursor/rules/cli-product-neutral.mdc +43 -0
  3. package/.cursor/rules/docs-rules.mdc +3 -1
  4. package/.cursor/rules/project-rules.mdc +1 -0
  5. package/README.md +43 -17
  6. package/integration/hubspot-test/wizard-hubspot-e2e.yaml +1 -1
  7. package/jest.config.default.js +2 -1
  8. package/jest.config.isolated.js +2 -1
  9. package/jest.global-live-fabrix-hooks.js +36 -0
  10. package/jest.isolated-projects.js +130 -0
  11. package/jest.projects.js +69 -121
  12. package/lib/api/agent-metadata-validation.api.js +93 -0
  13. package/lib/api/api-response-errors.js +124 -0
  14. package/lib/api/audit-api-helpers.js +68 -0
  15. package/lib/api/audit.api.js +119 -0
  16. package/lib/api/auth-cache.api.js +44 -0
  17. package/lib/api/certificates.api.js +4 -4
  18. package/lib/api/credential.api.js +2 -2
  19. package/lib/api/dataplane-health.api.js +137 -0
  20. package/lib/api/dataplane-sync.api.js +27 -0
  21. package/lib/api/datasources-core.api.js +21 -18
  22. package/lib/api/datasources-extended.api.js +22 -22
  23. package/lib/api/dimensions.api.js +3 -0
  24. package/lib/api/external-systems.api.js +13 -13
  25. package/lib/api/governance-scenario-pack.api.js +159 -0
  26. package/lib/api/governance-scenarios.api.js +39 -0
  27. package/lib/api/groups.api.js +79 -0
  28. package/lib/api/index.js +88 -5
  29. package/lib/api/lifecycle.api.js +77 -0
  30. package/lib/api/pipeline.api.js +7 -5
  31. package/lib/api/protection.api.js +157 -0
  32. package/lib/api/records-bulk.api.js +43 -0
  33. package/lib/api/records-search-parse.js +49 -0
  34. package/lib/api/records-search.api.js +29 -0
  35. package/lib/api/types/agent-metadata-validation.types.js +67 -0
  36. package/lib/api/types/audit.types.js +72 -0
  37. package/lib/api/types/dataplane-health.types.js +27 -0
  38. package/lib/api/types/dimensions.types.js +2 -0
  39. package/lib/api/types/governance-scenarios.types.js +39 -0
  40. package/lib/api/types/protection.types.js +69 -0
  41. package/lib/api/types/records-bulk.types.js +35 -0
  42. package/lib/api/types/records-search.types.js +28 -0
  43. package/lib/api/user-groups.api.js +50 -0
  44. package/lib/api/users.api.js +95 -0
  45. package/lib/api/validation-run.api.js +3 -3
  46. package/lib/api/validation-runner.js +5 -3
  47. package/lib/api/wizard-platform.api.js +3 -3
  48. package/lib/api/wizard.api.js +21 -21
  49. package/lib/app/deploy-config.js +4 -1
  50. package/lib/app/deploy.js +34 -19
  51. package/lib/app/down.js +20 -1
  52. package/lib/app/push.js +4 -5
  53. package/lib/app/register.js +7 -4
  54. package/lib/app/run-env-compose.js +84 -30
  55. package/lib/build/index.js +5 -0
  56. package/lib/certification/sync-system-certification.js +13 -6
  57. package/lib/cli/index.js +8 -2
  58. package/lib/cli/infra-guided-auth.js +109 -0
  59. package/lib/cli/infra-guided.js +91 -69
  60. package/lib/cli/setup-app.help.js +19 -2
  61. package/lib/cli/setup-app.js +58 -23
  62. package/lib/cli/setup-app.test-commands.js +28 -21
  63. package/lib/cli/setup-auth.js +55 -3
  64. package/lib/cli/setup-certification-commands.js +147 -0
  65. package/lib/cli/setup-certification.help.js +141 -0
  66. package/lib/cli/setup-environment.js +19 -2
  67. package/lib/cli/setup-external-system-help.js +62 -0
  68. package/lib/cli/setup-external-system.js +62 -6
  69. package/lib/cli/setup-infra.js +9 -1
  70. package/lib/cli/setup-platform.js +6 -1
  71. package/lib/cli/setup-secrets.js +33 -1
  72. package/lib/cli/setup-utility-help-after.js +65 -0
  73. package/lib/cli/setup-utility-repair.js +198 -0
  74. package/lib/cli/setup-utility-resolve.js +42 -6
  75. package/lib/cli/setup-utility-validate.js +197 -0
  76. package/lib/cli/setup-utility.js +41 -258
  77. package/lib/commands/auth-status-client-tokens.js +214 -0
  78. package/lib/commands/auth-status-dataplane-version.js +269 -0
  79. package/lib/commands/auth-status-display.js +94 -0
  80. package/lib/commands/auth-status.js +111 -53
  81. package/lib/commands/credential-push.js +10 -5
  82. package/lib/commands/datasource-load-export-cli.js +178 -0
  83. package/lib/commands/datasource-test-trust-cli.js +118 -0
  84. package/lib/commands/datasource-unified-test-cli.js +31 -20
  85. package/lib/commands/datasource-unified-test-cli.options.js +22 -3
  86. package/lib/commands/datasource-unified-test-e2e-cli-helpers.js +5 -5
  87. package/lib/commands/datasource-verify-audit-cli.js +96 -0
  88. package/lib/commands/datasource.js +68 -1
  89. package/lib/commands/dev-show-display.js +8 -1
  90. package/lib/commands/dimension-value.js +43 -13
  91. package/lib/commands/dimension.js +38 -7
  92. package/lib/commands/governance-cli-shared.js +94 -0
  93. package/lib/commands/governance-command-action.js +132 -0
  94. package/lib/commands/governance-download-external.js +34 -0
  95. package/lib/commands/governance-generate-external.js +71 -0
  96. package/lib/commands/governance-upload-external.js +36 -0
  97. package/lib/commands/governance-verify-external.js +64 -0
  98. package/lib/commands/governance.js +144 -0
  99. package/lib/commands/identity-apply-sync.js +131 -0
  100. package/lib/commands/identity-group-cli.js +146 -0
  101. package/lib/commands/identity-membership-role-cache.js +175 -0
  102. package/lib/commands/identity-shared.js +94 -0
  103. package/lib/commands/identity-user-cli.js +158 -0
  104. package/lib/commands/identity.js +43 -0
  105. package/lib/commands/lifecycle-command-action.js +123 -0
  106. package/lib/commands/lifecycle-external.js +268 -0
  107. package/lib/commands/login.js +56 -17
  108. package/lib/commands/protection-cli-leaves.js +286 -0
  109. package/lib/commands/protection.js +50 -0
  110. package/lib/commands/repair-auth-apply.js +127 -0
  111. package/lib/commands/repair-changed-files.js +41 -0
  112. package/lib/commands/repair-datasource-keys.js +4 -1
  113. package/lib/commands/repair-datasource-run.js +59 -0
  114. package/lib/commands/repair-datasource-test-payload.js +259 -0
  115. package/lib/commands/repair-datasource.js +1 -51
  116. package/lib/commands/repair-env-template.js +64 -13
  117. package/lib/commands/repair-external-run.js +216 -0
  118. package/lib/commands/repair-openapi-sync.js +23 -0
  119. package/lib/commands/repair-persist.js +4 -0
  120. package/lib/commands/repair-rbac.js +52 -1
  121. package/lib/commands/repair-steps.js +145 -0
  122. package/lib/commands/repair.js +29 -286
  123. package/lib/commands/secrets-get.js +184 -0
  124. package/lib/commands/secrets-remove-all.js +3 -1
  125. package/lib/commands/setup-image-refresh.js +146 -0
  126. package/lib/commands/setup-modes.js +158 -162
  127. package/lib/commands/setup-platform-auth.js +76 -0
  128. package/lib/commands/setup-prompts-admin.js +244 -0
  129. package/lib/commands/setup-prompts-platform-mode.js +67 -0
  130. package/lib/commands/setup-prompts-validators.js +36 -0
  131. package/lib/commands/setup-prompts.js +24 -76
  132. package/lib/commands/setup-run-context.js +45 -0
  133. package/lib/commands/setup-spinners.js +39 -0
  134. package/lib/commands/setup.js +27 -5
  135. package/lib/commands/teardown.js +39 -0
  136. package/lib/commands/test-e2e-external.js +61 -14
  137. package/lib/commands/test-governance-cli-options.js +47 -0
  138. package/lib/commands/test-governance-external.js +67 -0
  139. package/lib/commands/test-trust-cli-options.js +32 -0
  140. package/lib/commands/test-trust-external.js +126 -0
  141. package/lib/commands/up-common.js +25 -13
  142. package/lib/commands/up-dataplane.js +50 -13
  143. package/lib/commands/upload-publish-context.js +75 -0
  144. package/lib/commands/upload-sidecar-followups.js +89 -0
  145. package/lib/commands/upload.js +108 -105
  146. package/lib/commands/verify-governance-combined-external.js +61 -0
  147. package/lib/commands/verify-governance-command-action.js +64 -0
  148. package/lib/commands/verify-governance-db.js +102 -0
  149. package/lib/commands/verify-governance-external.js +77 -0
  150. package/lib/commands/verify-governance-result-builders.js +71 -0
  151. package/lib/commands/verify-operations-command-action.js +68 -0
  152. package/lib/commands/verify-operations-external.js +268 -0
  153. package/lib/commands/verify-operations-persist.js +75 -0
  154. package/lib/commands/verify-operations-step-plan.js +68 -0
  155. package/lib/commands/verify-operations-steps.js +111 -0
  156. package/lib/commands/verify-trust-command-action.js +70 -0
  157. package/lib/commands/verify-trust-external.js +67 -0
  158. package/lib/commands/wizard-config-normalizer.js +43 -23
  159. package/lib/commands/wizard-core.js +5 -0
  160. package/lib/core/admin-password-generator.js +38 -0
  161. package/lib/core/admin-secrets-bundle.js +111 -0
  162. package/lib/core/admin-secrets-env-overlay.js +62 -0
  163. package/lib/core/admin-secrets.js +32 -4
  164. package/lib/core/config-attach-extensions.js +3 -0
  165. package/lib/core/config-device-dataplane.js +185 -0
  166. package/lib/core/config-platform-controller.js +44 -0
  167. package/lib/core/config-setup-installation-profile.js +42 -0
  168. package/lib/core/config-setup-platform-mode.js +46 -0
  169. package/lib/core/config.js +46 -36
  170. package/lib/core/secrets-admin-env.js +6 -2
  171. package/lib/core/secrets-ensure.js +4 -0
  172. package/lib/core/secrets-env-content.js +54 -48
  173. package/lib/core/secrets-env-write.js +10 -1
  174. package/lib/core/secrets-infra-placeholder-sync.js +2 -0
  175. package/lib/core/setup-installation-profile.js +43 -0
  176. package/lib/core/setup-platform-mode.js +55 -0
  177. package/lib/datasource/agent-trust-debug-log.js +45 -0
  178. package/lib/datasource/agent-trust-fetch.js +115 -0
  179. package/lib/datasource/agent-trust-map.js +101 -0
  180. package/lib/datasource/agent-trust-mock.js +44 -0
  181. package/lib/datasource/agent-trust-run.js +95 -0
  182. package/lib/datasource/agent-trust-timeout.js +25 -0
  183. package/lib/datasource/audit-evidence-display.js +80 -0
  184. package/lib/datasource/audit-evidence-extract-debug.js +115 -0
  185. package/lib/datasource/audit-evidence-extract.js +180 -0
  186. package/lib/datasource/audit-evidence-matrix-rows.js +158 -0
  187. package/lib/datasource/audit-evidence-operation-aliases.js +63 -0
  188. package/lib/datasource/audit-evidence-poll.js +109 -0
  189. package/lib/datasource/audit-evidence-run.js +177 -0
  190. package/lib/datasource/audit-evidence-verify-helpers.js +167 -0
  191. package/lib/datasource/audit-evidence-verify-matrix.js +205 -0
  192. package/lib/datasource/audit-evidence-verify.js +108 -0
  193. package/lib/datasource/bulk-loader-run-batches.js +100 -0
  194. package/lib/datasource/bulk-loader-service-retry.js +52 -0
  195. package/lib/datasource/bulk-loader-service.js +127 -0
  196. package/lib/datasource/capability/run-capability-dimension.js +2 -1
  197. package/lib/datasource/datasource-exporter-resolve.js +82 -0
  198. package/lib/datasource/datasource-exporter-service.js +144 -0
  199. package/lib/datasource/datasource-identifier.js +148 -0
  200. package/lib/datasource/datasource-load-export-context.js +95 -0
  201. package/lib/datasource/integration-context.js +6 -4
  202. package/lib/datasource/local-data-paths.js +145 -0
  203. package/lib/datasource/log-cleaner.js +241 -0
  204. package/lib/datasource/log-viewer.js +111 -6
  205. package/lib/datasource/record-file-parser.js +85 -0
  206. package/lib/datasource/record-mapper.js +129 -0
  207. package/lib/datasource/resolve-app.js +74 -55
  208. package/lib/datasource/test-e2e.js +29 -2
  209. package/lib/datasource/unified-validation-run-body.js +3 -1
  210. package/lib/datasource/unified-validation-run-resolve.js +45 -12
  211. package/lib/datasource/unified-validation-run.js +47 -18
  212. package/lib/datasource/validate.js +37 -20
  213. package/lib/deployment/environment-poll-status.js +138 -0
  214. package/lib/deployment/environment.js +42 -34
  215. package/lib/external-system/download.js +21 -20
  216. package/lib/external-system/generator.js +5 -1
  217. package/lib/external-system/integration-auth-context.js +45 -0
  218. package/lib/external-system/test-auth.js +12 -5
  219. package/lib/external-system/test-system-level.js +25 -4
  220. package/lib/external-system/test.js +9 -7
  221. package/lib/generator/external-controller-manifest.js +15 -0
  222. package/lib/governance/governance-cli-errors.js +96 -0
  223. package/lib/governance/governance-download-display.js +38 -0
  224. package/lib/governance/governance-pack-loader.js +70 -0
  225. package/lib/governance/governance-run-display.js +309 -0
  226. package/lib/identity/identity-apply-core.js +108 -0
  227. package/lib/identity/identity-apply-phases.js +244 -0
  228. package/lib/identity/identity-apply-service.js +77 -0
  229. package/lib/identity/identity-csv-parser.js +114 -0
  230. package/lib/infrastructure/admin-secrets-apply.js +84 -0
  231. package/lib/infrastructure/admin-secrets-ensure.js +130 -0
  232. package/lib/infrastructure/admin-secrets-resolve.js +95 -0
  233. package/lib/infrastructure/admin-secrets-sync.js +91 -0
  234. package/lib/infrastructure/helpers.js +23 -129
  235. package/lib/infrastructure/index.js +5 -6
  236. package/lib/infrastructure/orphan-infra-docker-teardown.js +11 -5
  237. package/lib/internal/fs-real-sync.js +29 -1
  238. package/lib/lifecycle/certification-progress.js +231 -0
  239. package/lib/lifecycle/dataplane-ui-url.js +145 -0
  240. package/lib/lifecycle/exit-codes.js +24 -0
  241. package/lib/lifecycle/json-envelope.js +25 -0
  242. package/lib/lifecycle/lifecycle-governance-options.js +51 -0
  243. package/lib/lifecycle/logger-quiet.js +29 -0
  244. package/lib/lifecycle/open-api-published.js +59 -0
  245. package/lib/lifecycle/operations-readiness-metrics.js +101 -0
  246. package/lib/lifecycle/product-model.js +196 -0
  247. package/lib/lifecycle/report-display.js +471 -0
  248. package/lib/lifecycle/scenario-upload.js +191 -0
  249. package/lib/lifecycle/verify-step-progress.js +87 -0
  250. package/lib/parameters/infra-kv-discovery.js +27 -2
  251. package/lib/protection/auth-context.js +51 -0
  252. package/lib/protection/convert-batch.js +90 -0
  253. package/lib/protection/load.js +41 -0
  254. package/lib/protection/paths.js +158 -0
  255. package/lib/protection/preflight-datasource-ready.js +46 -0
  256. package/lib/protection/protection-create-probe-lines.js +142 -0
  257. package/lib/protection/protection-create-probes.js +95 -0
  258. package/lib/protection/protection-create-scaffold.js +281 -0
  259. package/lib/protection/protection-display-helpers.js +445 -0
  260. package/lib/protection/protection-display.js +215 -0
  261. package/lib/protection/protection-preset-registry.js +97 -0
  262. package/lib/protection/report-exit.js +62 -0
  263. package/lib/protection/resolve.js +202 -0
  264. package/lib/protection/run-commands-validate.js +130 -0
  265. package/lib/protection/run-commands.js +216 -0
  266. package/lib/protection/run-protection-create-helpers.js +134 -0
  267. package/lib/protection/run-protection-create-probes-flow.js +43 -0
  268. package/lib/protection/run-protection-create.js +191 -0
  269. package/lib/protection/scope.js +22 -0
  270. package/lib/protection/sync-after-upload.js +64 -0
  271. package/lib/protection/upload-batch.js +127 -0
  272. package/lib/protection/validate-batch.js +113 -0
  273. package/lib/protection/validate-local.js +65 -0
  274. package/lib/resolvers/dimension-file.js +29 -4
  275. package/lib/schema/application-schema.json +1 -1
  276. package/lib/schema/datasource-test-run.schema.json +89 -6
  277. package/lib/schema/external-datasource.schema.json +2636 -2588
  278. package/lib/schema/external-system.schema.json +1089 -761
  279. package/lib/schema/flag-map-validation-run.json +2 -2
  280. package/lib/schema/infra.parameter.yaml +45 -0
  281. package/lib/schema/protection.schema.json +374 -0
  282. package/lib/schema/type/credential-field-registry.json +642 -0
  283. package/lib/schema/wizard-config.schema.json +1 -1
  284. package/lib/utils/agent-trust-run-display.js +231 -0
  285. package/lib/utils/agent-trust-run-exit.js +59 -0
  286. package/lib/utils/agent-trust-wait-ui.js +94 -0
  287. package/lib/utils/aifabrix-test-runtime-guard.js +125 -0
  288. package/lib/utils/api.js +55 -31
  289. package/lib/utils/app-relative-path-env.js +112 -0
  290. package/lib/utils/cli-exit-codes.js +30 -0
  291. package/lib/utils/cli-secrets-error-format.js +83 -21
  292. package/lib/utils/cli-sync-options.js +33 -0
  293. package/lib/utils/cli-utils.js +16 -4
  294. package/lib/utils/compose-generate-docker-compose.js +4 -0
  295. package/lib/utils/compose-traefik-ingress-base.js +16 -1
  296. package/lib/utils/config-secrets-path.js +46 -0
  297. package/lib/utils/controller-url.js +88 -1
  298. package/lib/utils/credential-push-ui.js +90 -0
  299. package/lib/utils/credential-secrets-env.js +137 -9
  300. package/lib/utils/dataplane-cli-version-gate.js +202 -0
  301. package/lib/utils/dataplane-cli-version-help.js +74 -0
  302. package/lib/utils/dataplane-resolver.js +129 -2
  303. package/lib/utils/datasource-export-display.js +137 -0
  304. package/lib/utils/datasource-load-display.js +174 -0
  305. package/lib/utils/datasource-load-export-ui.js +120 -0
  306. package/lib/utils/datasource-test-run-capability-scope.js +3 -3
  307. package/lib/utils/datasource-test-run-display.js +3 -3
  308. package/lib/utils/datasource-test-run-tty-log.js +5 -1
  309. package/lib/utils/declarative-url-ports.js +3 -3
  310. package/lib/utils/deployment-auth-mode.js +41 -0
  311. package/lib/utils/developer-volume-id.js +33 -0
  312. package/lib/utils/env-copy.js +14 -9
  313. package/lib/utils/env-kv-orphan-lines.js +43 -0
  314. package/lib/utils/error-formatters/network-errors.js +13 -4
  315. package/lib/utils/external-env-template.js +1 -0
  316. package/lib/utils/external-system-readiness-core.js +10 -0
  317. package/lib/utils/external-system-readiness-display.js +80 -23
  318. package/lib/utils/health-check.js +4 -1
  319. package/lib/utils/help-builder.js +35 -26
  320. package/lib/utils/keycloak-realm-ready.js +101 -0
  321. package/lib/utils/load-cip-capacity-display-config.js +61 -15
  322. package/lib/utils/manifest-source-emit.js +24 -0
  323. package/lib/utils/pipeline-upload-auth-retry.js +82 -0
  324. package/lib/utils/platform-controller-url.js +156 -0
  325. package/lib/utils/postgres-platform-bootstrap.js +199 -0
  326. package/lib/utils/postgres-wipe.js +9 -2
  327. package/lib/utils/resolve-env-mode.js +47 -0
  328. package/lib/utils/secrets-generator.js +31 -25
  329. package/lib/utils/secrets-missing-error.js +164 -0
  330. package/lib/utils/semver-compare.js +127 -0
  331. package/lib/utils/service-url-label.js +81 -0
  332. package/lib/utils/setup-quiet-output.js +25 -0
  333. package/lib/utils/template-helpers.js +15 -0
  334. package/lib/utils/token-manager-client-credentials.js +201 -0
  335. package/lib/utils/token-manager-messages.js +8 -0
  336. package/lib/utils/token-manager-refresh.js +12 -2
  337. package/lib/utils/token-manager.js +86 -105
  338. package/lib/utils/upload-pipeline-ui.js +98 -0
  339. package/lib/utils/upload-sync-options.js +42 -0
  340. package/lib/utils/url-declarative-public-base.js +21 -3
  341. package/lib/utils/url-declarative-vdir-inactive-env.js +14 -4
  342. package/lib/utils/validation-poll-ui.js +22 -7
  343. package/lib/utils/validation-run-stage.js +45 -0
  344. package/lib/validation/wizard-config-validator.js +58 -19
  345. package/package.json +1 -1
  346. package/templates/applications/dataplane/application.yaml +2 -1
  347. package/templates/applications/dataplane/env.template +36 -1
  348. package/templates/applications/dataplane/rbac.yaml +4 -0
  349. package/templates/applications/miso-controller/env.template +16 -0
  350. package/templates/external-system/README.md.hbs +116 -11
  351. package/templates/python/docker-compose.hbs +19 -18
  352. package/templates/typescript/docker-compose.hbs +18 -17
@@ -118,6 +118,37 @@ function cleanAifabrixSystemDir() {
118
118
  return { removed, failed };
119
119
  }
120
120
 
121
+ /**
122
+ * Remove materialized `builder/` trees (aifabrix-work, aifabrix-home / config dir, cwd).
123
+ * Complements {@link cleanAifabrixSystemDir} when `builder/` lives under `aifabrix-work` outside
124
+ * the config directory.
125
+ *
126
+ * @returns {{ removed: string[], failed: string[] }}
127
+ */
128
+ function cleanMaterializedBuilderTrees() {
129
+ const candidates = [
130
+ pathsUtil.getBuilderRoot(),
131
+ path.join(pathsUtil.getAifabrixSystemDir(), 'builder'),
132
+ path.join(process.cwd(), 'builder')
133
+ ];
134
+ const seen = new Set();
135
+ const removed = [];
136
+ const failed = [];
137
+ for (const candidate of candidates) {
138
+ const resolved = path.resolve(candidate);
139
+ if (seen.has(resolved)) continue;
140
+ seen.add(resolved);
141
+ if (!fs.existsSync(resolved)) continue;
142
+ try {
143
+ fs.rmSync(resolved, { recursive: true, force: true });
144
+ removed.push(resolved);
145
+ } catch {
146
+ failed.push(resolved);
147
+ }
148
+ }
149
+ return { removed, failed };
150
+ }
151
+
121
152
  /**
122
153
  * Stop infra with `down-infra -v` semantics. Tolerates already-down state.
123
154
  * @async
@@ -259,6 +290,13 @@ async function handleTeardown(options = {}) {
259
290
  try {
260
291
  await stopInfraQuietly();
261
292
  const { removed, failed } = cleanFilesWithSpinner();
293
+ const builderClean = cleanMaterializedBuilderTrees();
294
+ for (const p of builderClean.removed) {
295
+ removed.push(p);
296
+ }
297
+ for (const p of builderClean.failed) {
298
+ failed.push(p);
299
+ }
262
300
  const devStr = await buildDeveloperLabel();
263
301
  logTeardownFooter({ devStr, removedCount: removed.length, failedCount: failed.length });
264
302
 
@@ -271,6 +309,7 @@ async function handleTeardown(options = {}) {
271
309
  module.exports = {
272
310
  handleTeardown,
273
311
  cleanAifabrixSystemDir,
312
+ cleanMaterializedBuilderTrees,
274
313
  stopInfraQuietly,
275
314
  PRESERVE_FILE,
276
315
  PRESERVE_CERTS_DIR
@@ -18,6 +18,10 @@ const { resolveApplicationConfigPath } = require('../utils/app-config-resolver')
18
18
  const { loadConfigFile } = require('../utils/config-format');
19
19
  const { discoverIntegrationFiles, buildEffectiveDatasourceFiles } = require('./repair-internal');
20
20
  const { runDatasourceTestE2E } = require('../datasource/test-e2e');
21
+ const { cliOptsSkipSync } = require('../utils/cli-sync-options');
22
+ const { buildMinimalUploadSyncOptions, isQuietMinimalSync } = require('../utils/upload-sync-options');
23
+ const { getConfig } = require('../core/config');
24
+ const { setupIntegrationTestAuth } = require('../external-system/test-auth');
21
25
 
22
26
  /**
23
27
  * Derives datasource key from filename when file has no key (same logic as repair).
@@ -89,17 +93,17 @@ function getDatasourceKeys(appPath, configPath, variables, systemKey, systemPars
89
93
  * unless ``options.noSync`` is true.
90
94
  * @param {string} systemKey
91
95
  * @param {Object} options
92
- * @returns {Promise<void>}
96
+ * @returns {Promise<{ authConfig: Object, dataplaneUrl: string, environment?: string }|null>}
93
97
  */
94
98
  async function syncLocalIfRequested(systemKey, options) {
95
- if (options.noSync === true) return;
96
- logger.log(chalk.cyan('Syncing local config to dataplane…'));
99
+ if (cliOptsSkipSync(options)) return null;
97
100
  const { uploadExternalSystem } = require('./upload');
98
- await uploadExternalSystem(systemKey, {
99
- verbose: !!options.verbose,
100
- minimal: true
101
- });
102
- logger.log(formatSuccessLine('Sync complete'));
101
+ const uploadOpts = buildMinimalUploadSyncOptions(options);
102
+ const uploadCtx = await uploadExternalSystem(systemKey, uploadOpts);
103
+ if (uploadCtx?.uploadSkipped !== true && !isQuietMinimalSync(uploadOpts)) {
104
+ logger.log(formatSuccessLine('Sync complete'));
105
+ }
106
+ return uploadCtx && uploadCtx.dataplaneUrl && uploadCtx.authConfig ? uploadCtx : null;
103
107
  }
104
108
 
105
109
  /* eslint-disable max-lines-per-function, max-statements -- Load context, then loop over keys */
@@ -116,7 +120,12 @@ async function syncLocalIfRequested(systemKey, options) {
116
120
  * @param {boolean} [options.noSync] - When true, skip upload (E2E uses dataplane config already deployed)
117
121
  * @returns {Promise<{ success: boolean, results: Array<{ key: string, success: boolean, error?: string }> }>}
118
122
  */
119
- async function runTestE2EForExternalSystem(externalSystem, options = {}) {
123
+ /**
124
+ * Resolve integration folder, system key, and datasource keys for system-level tests.
125
+ * @param {string} externalSystem
126
+ * @returns {{ systemKey: string, keys: string[] }}
127
+ */
128
+ function resolveExternalIntegrationContext(externalSystem) {
120
129
  if (!externalSystem || typeof externalSystem !== 'string') {
121
130
  throw new Error('External system name is required');
122
131
  }
@@ -140,9 +149,9 @@ async function runTestE2EForExternalSystem(externalSystem, options = {}) {
140
149
  );
141
150
  const systemPath = path.join(appPath, systemFiles[0]);
142
151
  const systemParsed = loadConfigFile(systemPath);
143
- const systemKey = systemParsed.key ||
152
+ const systemKey =
153
+ systemParsed.key ||
144
154
  path.basename(systemFiles[0], path.extname(systemFiles[0])).replace(/-system$/, '');
145
-
146
155
  const keys = getDatasourceKeys(
147
156
  appPath,
148
157
  configPath,
@@ -151,12 +160,37 @@ async function runTestE2EForExternalSystem(externalSystem, options = {}) {
151
160
  systemParsed,
152
161
  datasourceFiles
153
162
  );
163
+ return { systemKey, keys };
164
+ }
165
+
166
+ async function runTestE2EForExternalSystem(externalSystem, options = {}) {
167
+ const { systemKey, keys } = resolveExternalIntegrationContext(externalSystem);
154
168
  if (keys.length === 0) {
155
169
  logger.log(chalk.yellow(`No datasources found for ${externalSystem}. Add datasource files and run aifabrix repair.`));
156
170
  return { success: true, results: [] };
157
171
  }
158
172
 
159
- await syncLocalIfRequested(systemKey, options);
173
+ const uploadCtx = await syncLocalIfRequested(systemKey, options);
174
+
175
+ let authConfig;
176
+ let dataplaneUrl;
177
+ if (uploadCtx) {
178
+ ({ authConfig, dataplaneUrl } = uploadCtx);
179
+ } else if (options.authConfig && options.dataplaneUrl) {
180
+ ({ authConfig, dataplaneUrl } = options);
181
+ } else {
182
+ const configObj = await getConfig();
183
+ ({ authConfig, dataplaneUrl } = await setupIntegrationTestAuth(
184
+ externalSystem,
185
+ {
186
+ environment: options.env,
187
+ authConfig: options.authConfig,
188
+ dataplaneUrl: options.dataplaneUrl,
189
+ silentResolve: options.silentResolve === true
190
+ },
191
+ configObj
192
+ ));
193
+ }
160
194
 
161
195
  const results = [];
162
196
  const opts = {
@@ -164,9 +198,20 @@ async function runTestE2EForExternalSystem(externalSystem, options = {}) {
164
198
  environment: options.env,
165
199
  debug: options.debug,
166
200
  verbose: options.verbose,
167
- async: options.async !== false
201
+ async: options.async !== false,
202
+ authConfig,
203
+ dataplaneUrl,
204
+ quietPollUi: options.quietPollUi === true,
205
+ onPollProgress: options.onPollProgress
168
206
  };
169
207
  for (const key of keys) {
208
+ if (typeof options.onDatasourceProgress === 'function') {
209
+ options.onDatasourceProgress({
210
+ key,
211
+ index: results.length,
212
+ total: keys.length
213
+ });
214
+ }
170
215
  try {
171
216
  const data = await runDatasourceTestE2E(key, opts);
172
217
  const steps = data.steps || data.completedActions || [];
@@ -187,5 +232,7 @@ async function runTestE2EForExternalSystem(externalSystem, options = {}) {
187
232
 
188
233
  module.exports = {
189
234
  runTestE2EForExternalSystem,
190
- getDatasourceKeys
235
+ getDatasourceKeys,
236
+ resolveExternalIntegrationContext,
237
+ syncLocalIfRequested
191
238
  };
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @fileoverview Normalize test-governance Commander flags
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { cliOptsSkipSync } = require('../utils/cli-sync-options');
10
+
11
+ /**
12
+ * @param {string[]} [raw]
13
+ * @param {string[]} [fallback]
14
+ * @returns {string[]|undefined}
15
+ */
16
+ function collectScenarioIds(raw, fallback) {
17
+ const list = Array.isArray(raw) && raw.length > 0 ? raw : fallback;
18
+ if (!list || list.length === 0) {
19
+ return undefined;
20
+ }
21
+ return list.map(id => String(id).trim()).filter(Boolean);
22
+ }
23
+
24
+ /**
25
+ * @param {Object} options
26
+ * @param {import('commander').Command} [cmd]
27
+ * @returns {Object}
28
+ */
29
+ function normalizeTestGovernanceCliOptions(options, cmd) {
30
+ const raw = cmd && Array.isArray(cmd.rawArgs) ? cmd.rawArgs : [];
31
+ const has = flag => raw.includes(flag);
32
+ return {
33
+ ...options,
34
+ env: options.env || 'dev',
35
+ verbose: options.verbose === true || has('-v') || has('--verbose'),
36
+ json: options.json === true || has('--json'),
37
+ noSync: cliOptsSkipSync(options, cmd),
38
+ pack: options.pack,
39
+ app: options.app,
40
+ scenarioIds: collectScenarioIds(options.scenario)
41
+ };
42
+ }
43
+
44
+ module.exports = {
45
+ normalizeTestGovernanceCliOptions,
46
+ collectScenarioIds
47
+ };
@@ -0,0 +1,67 @@
1
+ /**
2
+ * @fileoverview test-governance — run governance scenario pack via dataplane API
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { getConfig } = require('../core/config');
10
+ const { setupIntegrationTestAuth } = require('../external-system/test-auth');
11
+ const { runGovernanceScenarios } = require('../api/governance-scenarios.api');
12
+ const {
13
+ resolveGovernancePackPath,
14
+ loadGovernancePackYaml
15
+ } = require('../governance/governance-pack-loader');
16
+ const { syncLocalIfRequested } = require('./test-e2e-external');
17
+
18
+ /**
19
+ * @async
20
+ * @param {string} externalSystem
21
+ * @param {Object} options
22
+ * @returns {Promise<{ result: Object, packPath: string, systemKey: string }>}
23
+ */
24
+ async function runTestGovernanceForExternalSystem(externalSystem, options = {}) {
25
+ const pathsUtil = require('../utils/paths');
26
+ const appType = await pathsUtil.detectAppType(externalSystem).catch(() => null);
27
+ if (!appType || appType.baseDir !== 'integration') {
28
+ throw new Error(
29
+ 'verify-governance applies to external integration folders only (integration/<systemKey>/).'
30
+ );
31
+ }
32
+
33
+ const systemKey = externalSystem;
34
+ const packPath = resolveGovernancePackPath(systemKey, {
35
+ pack: options.pack,
36
+ app: options.app
37
+ });
38
+ const pack = loadGovernancePackYaml(packPath);
39
+
40
+ const uploadCtx = await syncLocalIfRequested(systemKey, options);
41
+
42
+ let authConfig;
43
+ let dataplaneUrl;
44
+ if (uploadCtx) {
45
+ ({ authConfig, dataplaneUrl } = uploadCtx);
46
+ } else {
47
+ const configObj = await getConfig();
48
+ ({ authConfig, dataplaneUrl } = await setupIntegrationTestAuth(
49
+ externalSystem,
50
+ { environment: options.env },
51
+ configObj
52
+ ));
53
+ }
54
+
55
+ const body = {
56
+ systemKey,
57
+ pack,
58
+ scenarios: options.scenarioIds
59
+ };
60
+ const result = await runGovernanceScenarios(dataplaneUrl, authConfig, body);
61
+ return { result, packPath, systemKey, packDocument: pack };
62
+ }
63
+
64
+ module.exports = {
65
+ runTestGovernanceForExternalSystem,
66
+ syncLocalIfRequested
67
+ };
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @fileoverview Normalize test-trust Commander flags (defensive for -d/-v/--revalidate).
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ const { cliOptsSkipSync } = require('../utils/cli-sync-options');
8
+
9
+ /**
10
+ * @param {Object} options - Commander-parsed options
11
+ * @param {import('commander').Command} [cmd]
12
+ * @returns {Object}
13
+ */
14
+ function normalizeTestTrustCliOptions(options, cmd) {
15
+ const raw = cmd && Array.isArray(cmd.rawArgs) ? cmd.rawArgs : [];
16
+ const has = flag => raw.includes(flag);
17
+ return {
18
+ ...options,
19
+ debug: options.debug === true || has('-d') || has('--debug'),
20
+ verbose: options.verbose === true || has('-v') || has('--verbose'),
21
+ revalidate: options.revalidate === true || has('--revalidate'),
22
+ noSync: cliOptsSkipSync(options, cmd),
23
+ strict: options.strict === true || has('--strict'),
24
+ summary: options.summary === true || has('--summary'),
25
+ json: options.json === true || has('--json'),
26
+ warningsAsErrors: options.warningsAsErrors === true || has('--warnings-as-errors')
27
+ };
28
+ }
29
+
30
+ module.exports = {
31
+ normalizeTestTrustCliOptions
32
+ };
@@ -0,0 +1,126 @@
1
+ /**
2
+ * @fileoverview verify-trust <systemKey> — semantic agent metadata validation for all datasources.
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const chalk = require('chalk');
10
+ const logger = require('../utils/logger');
11
+ const { getConfig } = require('../core/config');
12
+ const { setupIntegrationTestAuth } = require('../external-system/test-auth');
13
+ const { runDatasourceAgentTrust } = require('../datasource/agent-trust-run');
14
+ const {
15
+ resolveExternalIntegrationContext,
16
+ syncLocalIfRequested
17
+ } = require('./test-e2e-external');
18
+
19
+ function pushTrustResult(results, key, trustRun, apiError) {
20
+ const failed =
21
+ apiError ||
22
+ !trustRun ||
23
+ trustRun.trustDecision === 'notTrusted' ||
24
+ trustRun.validationStatus === 'failed';
25
+ results.push({
26
+ key,
27
+ success: !failed,
28
+ error: failed
29
+ ? apiError
30
+ ? apiError.message || String(apiError)
31
+ : trustRun.summary || 'Trust validation failed'
32
+ : undefined,
33
+ trustRun
34
+ });
35
+ }
36
+
37
+ /**
38
+ * @async
39
+ * @param {Object|null} uploadCtx
40
+ * @param {string} externalSystem
41
+ * @param {Object} options
42
+ * @returns {Promise<{ authConfig: Object, dataplaneUrl: string }>}
43
+ */
44
+ async function resolveTrustAuthContext(uploadCtx, externalSystem, options) {
45
+ if (uploadCtx) {
46
+ return { authConfig: uploadCtx.authConfig, dataplaneUrl: uploadCtx.dataplaneUrl };
47
+ }
48
+ const configObj = await getConfig();
49
+ return setupIntegrationTestAuth(
50
+ externalSystem,
51
+ {
52
+ environment: options.env,
53
+ authConfig: options.authConfig,
54
+ dataplaneUrl: options.dataplaneUrl,
55
+ silentResolve: options.silentResolve === true
56
+ },
57
+ configObj
58
+ );
59
+ }
60
+
61
+ /**
62
+ * @async
63
+ * @param {string[]} keys
64
+ * @param {Object} runOpts
65
+ * @param {Array<Object>} results
66
+ */
67
+ async function runTrustForDatasourceKeys(keys, runOpts, results) {
68
+ for (const key of keys) {
69
+ try {
70
+ const { trustRun, apiError } = await runDatasourceAgentTrust(key, runOpts);
71
+ pushTrustResult(results, key, trustRun, apiError);
72
+ } catch (err) {
73
+ results.push({ key, success: false, error: err.message, trustRun: null });
74
+ }
75
+ }
76
+ }
77
+
78
+ /**
79
+ * @async
80
+ * @param {string} externalSystem
81
+ * @param {Object} options
82
+ * @returns {Promise<{ success: boolean, results: Array<Object>, systemKey: string }>}
83
+ */
84
+ async function runTestTrustForExternalSystem(externalSystem, options = {}) {
85
+ const { systemKey, keys } = resolveExternalIntegrationContext(externalSystem);
86
+ if (keys.length === 0) {
87
+ logger.log(chalk.yellow(`No datasources found for ${externalSystem}.`));
88
+ return { success: true, results: [], systemKey };
89
+ }
90
+
91
+ const uploadCtx = await syncLocalIfRequested(systemKey, options);
92
+ if (uploadCtx?.authConfig && uploadCtx?.dataplaneUrl) {
93
+ options.authConfig = uploadCtx.authConfig;
94
+ options.dataplaneUrl = uploadCtx.dataplaneUrl;
95
+ options.silentResolve = true;
96
+ }
97
+ if (options.revalidate === true) {
98
+ logger.log(chalk.cyan('Forcing revalidation (cache bypass) for each datasource…'));
99
+ }
100
+
101
+ const { authConfig, dataplaneUrl } = await resolveTrustAuthContext(
102
+ uploadCtx,
103
+ externalSystem,
104
+ options
105
+ );
106
+ const results = [];
107
+ await runTrustForDatasourceKeys(
108
+ keys,
109
+ {
110
+ app: externalSystem,
111
+ environment: options.env,
112
+ noSync: true,
113
+ revalidate: options.revalidate === true,
114
+ summary: options.summary === true,
115
+ timeout: options.timeout,
116
+ authConfig,
117
+ dataplaneUrl
118
+ },
119
+ results
120
+ );
121
+ return { success: results.every(r => r.success), results, systemKey };
122
+ }
123
+
124
+ module.exports = {
125
+ runTestTrustForExternalSystem
126
+ };
@@ -14,7 +14,7 @@ const fs = require('fs');
14
14
  const chalk = require('chalk');
15
15
  const logger = require('../utils/logger');
16
16
  const config = require('../core/config');
17
- const { getDefaultControllerUrl } = require('../utils/controller-url');
17
+ const { resolvePlatformControllerUrl } = require('../utils/platform-controller-url');
18
18
  const pathsUtil = require('../utils/paths');
19
19
  const { loadConfigFile, writeConfigFile } = require('../utils/config-format');
20
20
  const { isYamlPath } = require('../utils/config-format');
@@ -189,19 +189,29 @@ function patchEnvOutputPathForDeployOnly(appName) {
189
189
 
190
190
  /**
191
191
  * For ``up-platform --force`` only: clear all stored auth tokens, set ``environment`` to ``dev``,
192
- * set ``controller`` to the default URL for the current ``developer-id`` (``http://localhost`` +
193
- * app port = 3000 + developerId × 100), and persist config. Does not change ``developer-id``.
192
+ * set ``controller`` and ``platform-controller`` to the default URL (or ``defaultControllerUrl`` when
193
+ * provided), and persist config. Does not change ``developer-id``. Pass ``clearTokens: false`` to
194
+ * keep device/client tokens (setup when already logged in to the platform controller).
194
195
  * Builder dirs (keycloak, miso-controller, dataplane) are cleaned separately.
195
196
  *
196
197
  * @returns {Promise<void>}
197
198
  */
198
199
  async function applyUpPlatformForceConfig(opts = {}) {
199
200
  const silent = Boolean(opts.silent);
200
- const deviceCleared = await config.clearAllDeviceTokens();
201
- const clientCleared = await config.clearAllClientTokens();
201
+ const clearTokens = opts.clearTokens !== false;
202
+ let deviceCleared = 0;
203
+ let clientCleared = 0;
204
+ if (clearTokens) {
205
+ deviceCleared = await config.clearAllDeviceTokens();
206
+ clientCleared = await config.clearAllClientTokens();
207
+ }
202
208
  await config.setCurrentEnvironment('dev');
203
- const defaultControllerUrl = await getDefaultControllerUrl();
209
+ const defaultControllerUrl =
210
+ opts.defaultControllerUrl && typeof opts.defaultControllerUrl === 'string'
211
+ ? String(opts.defaultControllerUrl).replace(/\/+$/, '')
212
+ : await resolvePlatformControllerUrl();
204
213
  await config.setControllerUrl(defaultControllerUrl);
214
+ await config.setPlatformControllerUrl(defaultControllerUrl);
205
215
 
206
216
  const summary = { deviceCleared, clientCleared, defaultControllerUrl, environment: 'dev' };
207
217
  if (!silent) {
@@ -287,14 +297,15 @@ async function cleanBuilderAppDirs(appNames, opts = {}) {
287
297
  * @example
288
298
  * await ensureAppFromTemplate('keycloak');
289
299
  */
290
- async function ensureAppFromTemplate(appName) {
300
+ async function ensureAppFromTemplate(appName, opts = {}) {
291
301
  if (!appName || typeof appName !== 'string') {
292
302
  throw new Error('Application name is required and must be a string');
293
303
  }
304
+ const silent = Boolean(opts.silent);
294
305
 
295
306
  const appPath = pathsUtil.getBuilderPath(appName);
296
307
  const primaryCopied = await ensureTemplateAtPath(appName, appPath);
297
- if (primaryCopied) {
308
+ if (primaryCopied && !silent) {
298
309
  logger.log(chalk.blue(`Creating builder/${appName} from template...`));
299
310
  logger.log(formatSuccessLine(`Copied template for ${appName}`));
300
311
  }
@@ -307,7 +318,7 @@ async function ensureAppFromTemplate(appName) {
307
318
  !pathsUtil.isSystemBuilderAppName(appName)
308
319
  ) {
309
320
  const cwdCopied = await ensureTemplateAtPath(appName, cwdBuilderPath);
310
- if (cwdCopied) {
321
+ if (cwdCopied && !silent) {
311
322
  logger.log(chalk.blue(`Creating builder/${appName} in project (from template)...`));
312
323
  logger.log(formatSuccessLine(`Copied template for ${appName} into builder/`));
313
324
  }
@@ -339,10 +350,11 @@ function refreshUrlsLocalRegistryForCurrentProject() {
339
350
  *
340
351
  * @returns {Promise<void>}
341
352
  */
342
- async function prepareUrlsLocalRegistryForUpPlatform() {
343
- await ensureAppFromTemplate('keycloak');
344
- await ensureAppFromTemplate('miso-controller');
345
- await ensureAppFromTemplate('dataplane');
353
+ async function prepareUrlsLocalRegistryForUpPlatform(opts = {}) {
354
+ const templateOpts = { silent: Boolean(opts.silent) };
355
+ await ensureAppFromTemplate('keycloak', templateOpts);
356
+ await ensureAppFromTemplate('miso-controller', templateOpts);
357
+ await ensureAppFromTemplate('dataplane', templateOpts);
346
358
  refreshUrlsLocalRegistryForCurrentProject();
347
359
  }
348
360
 
@@ -103,6 +103,22 @@ async function resolveControllerUrlWithHealthCheck() {
103
103
  return normalizedNew;
104
104
  }
105
105
 
106
+ async function resolveUpDataplaneAuthContext(options, environmentKey) {
107
+ if (options.skipInfraCheck !== true) {
108
+ await assertDevInfraUp();
109
+ }
110
+
111
+ const controllerUrl = await resolveControllerUrlWithHealthCheck();
112
+ const authConfig = await checkAuthentication(controllerUrl, environmentKey, { throwOnFailure: true });
113
+
114
+ const cfg = await config.getConfig();
115
+ if (options.allowNonDev !== true) {
116
+ assertDevEnvironmentForDataplane(cfg);
117
+ }
118
+ logger.log(formatSuccessLine(`Logged in (environment: ${environmentKey})`));
119
+ return { controllerUrl, authConfig };
120
+ }
121
+
106
122
  /**
107
123
  * Register or rotate dataplane: if app exists in controller, rotate secret; otherwise register.
108
124
  * @async
@@ -118,7 +134,12 @@ async function registerOrRotateDataplane(options, controllerUrl, environmentKey,
118
134
  await rotateSecret('dataplane', options);
119
135
  } else {
120
136
  const imageOverride = options.image || buildDataplaneImageRef(options);
121
- const registerOpts = { imageOverride, image: imageOverride, registryMode: options.registryMode };
137
+ const registerOpts = {
138
+ imageOverride,
139
+ image: imageOverride,
140
+ registryMode: options.registryMode,
141
+ envKey: environmentKey
142
+ };
122
143
  await registerApplication('dataplane', registerOpts);
123
144
  }
124
145
  }
@@ -134,6 +155,7 @@ async function deployDataplaneToController(options) {
134
155
  imageOverride,
135
156
  image: imageOverride,
136
157
  registryMode: options.registryMode,
158
+ envKey: options.envKey ? String(options.envKey).trim().toLowerCase() : undefined,
137
159
  // Guided up-platform already shows a top-level spinner for the dataplane step.
138
160
  // Avoid nested deploy polling spinners/logs.
139
161
  silentPoll: options.platformInstall === true
@@ -172,6 +194,14 @@ function emitDataplaneManifestLineFromBuilder() {
172
194
  emitSystemBuilderAppManifestLineIfTTY(logger, 'dataplane');
173
195
  }
174
196
 
197
+ function computeDataplanePortOverride(runEnvKey, developerIdNum) {
198
+ if (runEnvKey !== 'dev' && runEnvKey !== 'tst') {
199
+ return undefined;
200
+ }
201
+ const baseHostPort = 3001 + (Number.isFinite(developerIdNum) ? developerIdNum : 0) * 100;
202
+ return runEnvKey === 'dev' ? baseHostPort + 10 : baseHostPort + 20;
203
+ }
204
+
175
205
  function assertDevEnvironmentForDataplane(cfg) {
176
206
  const environment = (cfg && cfg.environment) ? cfg.environment : 'dev';
177
207
  if (environment !== 'dev') {
@@ -181,6 +211,14 @@ function assertDevEnvironmentForDataplane(cfg) {
181
211
  }
182
212
  }
183
213
 
214
+ async function computeDataplaneRunOverrides(options) {
215
+ const runEnvKey = options.runEnvKey ? String(options.runEnvKey).trim().toLowerCase() : undefined;
216
+ const developerIdRaw = await config.getDeveloperId();
217
+ const developerIdNum = typeof developerIdRaw === 'string' ? parseInt(developerIdRaw, 10) : developerIdRaw;
218
+ const portOverride = computeDataplanePortOverride(runEnvKey, developerIdNum);
219
+ return { runEnvKey, portOverride };
220
+ }
221
+
184
222
  /**
185
223
  * Handle up-dataplane command: ensure logged in, environment dev, ensure dataplane,
186
224
  * register or rotate (if already registered), deploy (send manifest to controller),
@@ -199,17 +237,11 @@ function assertDevEnvironmentForDataplane(cfg) {
199
237
  async function handleUpDataplane(options = {}) {
200
238
  logger.log(chalk.blue('Starting up-dataplane (register/rotate, deploy, then run dataplane locally)...\n'));
201
239
 
202
- if (options.skipInfraCheck !== true) {
203
- await assertDevInfraUp();
204
- }
205
-
206
- const controllerUrl = await resolveControllerUrlWithHealthCheck();
207
- const environmentKey = await resolveEnvironment();
208
- const authConfig = await checkAuthentication(controllerUrl, environmentKey, { throwOnFailure: true });
209
-
210
- const cfg = await config.getConfig();
211
- assertDevEnvironmentForDataplane(cfg);
212
- logger.log(formatSuccessLine('Logged in and environment is dev'));
240
+ const environmentKey =
241
+ options && options.envKey
242
+ ? String(options.envKey).trim().toLowerCase()
243
+ : await resolveEnvironment();
244
+ const { controllerUrl, authConfig } = await resolveUpDataplaneAuthContext(options, environmentKey);
213
245
 
214
246
  await ensureAppFromTemplate('dataplane');
215
247
  // If envOutputPath target folder does not exist, set envOutputPath to null
@@ -223,10 +255,15 @@ async function handleUpDataplane(options = {}) {
223
255
 
224
256
  await registerOrRotateDataplane(options, controllerUrl, environmentKey, authConfig);
225
257
 
226
- await deployDataplaneToController(options);
258
+ await deployDataplaneToController({ ...options, envKey: environmentKey });
227
259
  logger.log('');
260
+
261
+ const { runEnvKey, portOverride } = await computeDataplaneRunOverrides(options);
262
+
228
263
  await app.runApp('dataplane', {
229
264
  skipEnvOutputPath: true,
265
+ env: runEnvKey,
266
+ port: portOverride,
230
267
  registry: options.registry || undefined,
231
268
  base: options.base !== false,
232
269
  skipManifestMetadataLine: true