@aifabrix/builder 2.45.5 → 2.47.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 (355) 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/project-rules.mdc +1 -0
  4. package/.npmrc.token +1 -0
  5. package/.temp/jest-protection-convert/run-IFN2nv/.protection/hubspot-companies.json +1 -0
  6. package/.temp/jest-protection-convert/run-IvmKLO/.protection/hubspot-companies.yaml +17 -0
  7. package/.temp/jest-protection-convert/run-SdvblF/.protection/hubspot-companies.json +1 -0
  8. package/.temp/jest-protection-convert/run-b51TsW/.protection/hubspot-companies.json +1 -0
  9. package/.temp/jest-protection-convert/run-fiLmb1/.protection/hubspot-companies.json +1 -0
  10. package/.temp/jest-protection-convert/run-qYGHMU/.protection/hubspot-companies.yaml +17 -0
  11. package/.temp/jest-protection-fixtures/hubspot-Mq5re8/hubspot-companies.yaml +17 -0
  12. package/.temp/jest-protection-fixtures/hubspot-f3u4YL/hubspot-companies.yaml +17 -0
  13. package/.temp/jest-protection-fixtures/hubspot-iQtd1O/hubspot-companies.yaml +17 -0
  14. package/.temp/jest-protection-fixtures/hubspot-mdmz5M/hubspot-companies.yaml +17 -0
  15. package/.temp/jest-protection-fixtures/hubspot-qbKYxQ/hubspot-companies.yaml +17 -0
  16. package/.temp/jest-protection-fixtures/hubspot-yzlJy6/hubspot-companies.yaml +17 -0
  17. package/.temp/validation/summary.txt +5 -0
  18. package/README.md +43 -17
  19. package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +1 -1
  20. package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.yaml +1 -1
  21. package/jest.config.default.js +2 -1
  22. package/jest.config.isolated.js +2 -1
  23. package/jest.global-live-fabrix-hooks.js +36 -0
  24. package/jest.isolated-projects.js +146 -0
  25. package/jest.projects.js +65 -136
  26. package/lib/api/api-response-errors.js +124 -0
  27. package/lib/api/dataplane-health.api.js +19 -7
  28. package/lib/api/governance-scenario-pack.api.js +159 -0
  29. package/lib/api/index.js +43 -3
  30. package/lib/api/lifecycle.api.js +98 -0
  31. package/lib/api/pipeline.api.js +3 -1
  32. package/lib/api/records-bulk.api.js +14 -1
  33. package/lib/api/resource-types.api.js +107 -0
  34. package/lib/api/runtime-configuration.api.js +72 -0
  35. package/lib/api/types/resource-types.types.js +45 -0
  36. package/lib/api/user-groups.api.js +9 -9
  37. package/lib/api/users.api.js +8 -8
  38. package/lib/api/validation-runner.js +3 -1
  39. package/lib/api/wizard.api.js +10 -2
  40. package/lib/app/deploy-config.js +4 -1
  41. package/lib/app/down.js +78 -27
  42. package/lib/app/index.js +2 -2
  43. package/lib/app/push.js +4 -5
  44. package/lib/app/register.js +7 -4
  45. package/lib/app/run-env-compose.js +84 -30
  46. package/lib/app/run-resolve-image.js +2 -1
  47. package/lib/app/run-stop-containers.js +113 -0
  48. package/lib/app/run.js +1 -31
  49. package/lib/app/show-display.js +35 -0
  50. package/lib/app/show.js +32 -1
  51. package/lib/build/index.js +22 -5
  52. package/lib/build/miso-controller-npm-sdk-guard.js +25 -0
  53. package/lib/certification/sync-system-certification.js +13 -6
  54. package/lib/channels/add-channel.js +348 -0
  55. package/lib/channels/channel-artifact-generator.js +141 -0
  56. package/lib/channels/channel-audit.js +101 -0
  57. package/lib/channels/channel-auth-context.js +37 -0
  58. package/lib/channels/channel-credential.js +200 -0
  59. package/lib/channels/channel-display-name.js +64 -0
  60. package/lib/channels/channel-external-system.js +106 -0
  61. package/lib/channels/channel-integration-generator.js +274 -0
  62. package/lib/channels/channel-probe.js +89 -0
  63. package/lib/channels/channel-runtime-resolver.js +152 -0
  64. package/lib/channels/channel-status-display.js +141 -0
  65. package/lib/channels/channel-targets.js +115 -0
  66. package/lib/cli/index.js +20 -4
  67. package/lib/cli/infra-guided-auth.js +109 -0
  68. package/lib/cli/infra-guided.js +84 -81
  69. package/lib/cli/setup-app.help.js +0 -31
  70. package/lib/cli/setup-app.js +82 -5
  71. package/lib/cli/setup-app.test-commands.js +5 -57
  72. package/lib/cli/setup-auth.js +25 -0
  73. package/lib/cli/setup-certification-commands.js +147 -0
  74. package/lib/cli/setup-certification.help.js +141 -0
  75. package/lib/cli/setup-environment.js +19 -2
  76. package/lib/cli/setup-external-system-help.js +62 -0
  77. package/lib/cli/setup-external-system.js +25 -3
  78. package/lib/cli/setup-infra-up-dataplane-action.js +2 -2
  79. package/lib/cli/setup-infra-up-platform-action.js +2 -1
  80. package/lib/cli/setup-infra.js +9 -1
  81. package/lib/cli/setup-platform.js +6 -1
  82. package/lib/cli/setup-secrets.js +33 -1
  83. package/lib/cli/setup-utility-help-after.js +25 -2
  84. package/lib/cli/setup-utility-repair.js +198 -0
  85. package/lib/cli/setup-utility-resolve.js +44 -5
  86. package/lib/cli/setup-utility-validate.js +197 -0
  87. package/lib/cli/setup-utility.js +4 -239
  88. package/lib/commands/app-logs.js +54 -26
  89. package/lib/commands/app.js +41 -0
  90. package/lib/commands/auth-status-client-tokens.js +214 -0
  91. package/lib/commands/auth-status-dataplane-version.js +142 -68
  92. package/lib/commands/auth-status.js +43 -54
  93. package/lib/commands/channel.js +58 -0
  94. package/lib/commands/datasource-test-trust-cli.js +27 -23
  95. package/lib/commands/datasource-unified-test-cli.js +6 -3
  96. package/lib/commands/datasource-unified-test-cli.options.js +5 -1
  97. package/lib/commands/datasource.js +8 -8
  98. package/lib/commands/dev-show-display.js +8 -1
  99. package/lib/commands/governance-cli-shared.js +94 -0
  100. package/lib/commands/governance-command-action.js +132 -0
  101. package/lib/commands/governance-download-external.js +34 -0
  102. package/lib/commands/governance-generate-external.js +71 -0
  103. package/lib/commands/governance-upload-external.js +36 -0
  104. package/lib/commands/governance-verify-external.js +64 -0
  105. package/lib/commands/governance.js +144 -0
  106. package/lib/commands/identity-apply-sync.js +49 -8
  107. package/lib/commands/identity-group-cli.js +66 -26
  108. package/lib/commands/identity-membership-role-cache.js +58 -37
  109. package/lib/commands/identity-shared.js +22 -1
  110. package/lib/commands/identity-user-cli.js +80 -34
  111. package/lib/commands/lifecycle-command-action.js +123 -0
  112. package/lib/commands/lifecycle-external.js +268 -0
  113. package/lib/commands/login.js +11 -2
  114. package/lib/commands/repair-auth-apply.js +153 -0
  115. package/lib/commands/repair-auth-config.js +8 -13
  116. package/lib/commands/repair-changed-files.js +41 -0
  117. package/lib/commands/repair-datasource-com-v2.js +15 -0
  118. package/lib/commands/repair-datasource-keys.js +4 -1
  119. package/lib/commands/repair-datasource-run.js +59 -0
  120. package/lib/commands/repair-datasource-service-contract.js +206 -0
  121. package/lib/commands/repair-datasource-test-payload.js +259 -0
  122. package/lib/commands/repair-datasource.js +49 -64
  123. package/lib/commands/repair-env-template.js +76 -25
  124. package/lib/commands/repair-external-run.js +216 -0
  125. package/lib/commands/repair-openapi-sync.js +49 -4
  126. package/lib/commands/repair-persist.js +4 -0
  127. package/lib/commands/repair-rbac.js +52 -1
  128. package/lib/commands/repair-steps.js +160 -0
  129. package/lib/commands/repair-system-alignment.js +7 -4
  130. package/lib/commands/repair.js +29 -296
  131. package/lib/commands/resource-type.js +371 -0
  132. package/lib/commands/secrets-get.js +184 -0
  133. package/lib/commands/secrets-remove-all.js +3 -1
  134. package/lib/commands/setup-image-refresh.js +146 -0
  135. package/lib/commands/setup-modes.js +158 -162
  136. package/lib/commands/setup-platform-auth.js +76 -0
  137. package/lib/commands/setup-prompts-admin.js +244 -0
  138. package/lib/commands/setup-prompts-platform-mode.js +70 -0
  139. package/lib/commands/setup-prompts-validators.js +36 -0
  140. package/lib/commands/setup-prompts.js +24 -76
  141. package/lib/commands/setup-run-context.js +45 -0
  142. package/lib/commands/setup-spinners.js +39 -0
  143. package/lib/commands/setup.js +27 -5
  144. package/lib/commands/teardown.js +39 -0
  145. package/lib/commands/test-e2e-external.js +24 -8
  146. package/lib/commands/test-governance-external.js +3 -24
  147. package/lib/commands/test-trust-external.js +48 -100
  148. package/lib/commands/up-common.js +57 -13
  149. package/lib/commands/up-dataplane.js +56 -15
  150. package/lib/commands/upload-publish-context.js +75 -0
  151. package/lib/commands/upload-sidecar-followups.js +89 -0
  152. package/lib/commands/upload.js +113 -110
  153. package/lib/commands/verify-governance-combined-external.js +61 -0
  154. package/lib/commands/verify-governance-command-action.js +64 -0
  155. package/lib/commands/verify-governance-db.js +102 -0
  156. package/lib/commands/verify-governance-external.js +77 -0
  157. package/lib/commands/verify-governance-result-builders.js +71 -0
  158. package/lib/commands/verify-operations-command-action.js +68 -0
  159. package/lib/commands/verify-operations-external.js +268 -0
  160. package/lib/commands/verify-operations-persist.js +75 -0
  161. package/lib/commands/verify-operations-step-plan.js +68 -0
  162. package/lib/commands/verify-operations-steps.js +111 -0
  163. package/lib/commands/verify-trust-command-action.js +73 -0
  164. package/lib/commands/verify-trust-external.js +59 -0
  165. package/lib/commands/wizard-config-normalizer.js +43 -23
  166. package/lib/commands/wizard-core.js +2 -0
  167. package/lib/core/admin-password-generator.js +38 -0
  168. package/lib/core/admin-secrets-bundle.js +111 -0
  169. package/lib/core/admin-secrets-env-overlay.js +62 -0
  170. package/lib/core/admin-secrets.js +32 -4
  171. package/lib/core/config-attach-extensions.js +3 -0
  172. package/lib/core/config-platform-controller.js +44 -0
  173. package/lib/core/config-setup-installation-profile.js +42 -0
  174. package/lib/core/config-setup-platform-mode.js +46 -0
  175. package/lib/core/config.js +46 -36
  176. package/lib/core/secrets-admin-env.js +6 -2
  177. package/lib/core/secrets-ensure.js +4 -0
  178. package/lib/core/secrets-env-content.js +54 -48
  179. package/lib/core/secrets-env-write.js +10 -1
  180. package/lib/core/secrets-infra-placeholder-sync.js +2 -0
  181. package/lib/core/setup-installation-profile.js +43 -0
  182. package/lib/core/setup-platform-mode.js +90 -0
  183. package/lib/datasource/agent-trust-debug-log.js +1 -1
  184. package/lib/datasource/agent-trust-run.js +5 -3
  185. package/lib/datasource/audit-evidence-extract-debug.js +30 -18
  186. package/lib/datasource/audit-evidence-extract.js +7 -4
  187. package/lib/datasource/audit-evidence-verify-matrix.js +54 -26
  188. package/lib/datasource/bulk-loader-run-batches.js +15 -3
  189. package/lib/datasource/capability/capability-diff-slice.js +2 -2
  190. package/lib/datasource/capability/capability-manifest.js +254 -0
  191. package/lib/datasource/capability/capability-resolve.js +3 -4
  192. package/lib/datasource/capability/copy-operations.js +5 -3
  193. package/lib/datasource/capability/remove-operations.js +2 -1
  194. package/lib/datasource/capability/run-capability-copy.js +32 -4
  195. package/lib/datasource/capability/run-capability-diff.js +3 -3
  196. package/lib/datasource/capability/run-capability-dimension.js +2 -4
  197. package/lib/datasource/capability/run-capability-edit.js +4 -7
  198. package/lib/datasource/capability/run-capability-relate.js +2 -4
  199. package/lib/datasource/capability/run-capability-remove.js +2 -4
  200. package/lib/datasource/capability/validate-capability-slice.js +2 -1
  201. package/lib/datasource/datasource-identifier.js +2 -1
  202. package/lib/datasource/datasource-load-export-context.js +3 -0
  203. package/lib/datasource/datasource-validate-display.js +1 -1
  204. package/lib/datasource/field-reference-validator.js +24 -3
  205. package/lib/datasource/log-cleaner.js +2 -2
  206. package/lib/datasource/log-viewer.js +8 -8
  207. package/lib/datasource/orphan-profiles-validator.js +98 -0
  208. package/lib/datasource/test-e2e.js +4 -1
  209. package/lib/datasource/unified-validation-run-body.js +3 -1
  210. package/lib/datasource/unified-validation-run.js +5 -2
  211. package/lib/datasource/validate.js +41 -23
  212. package/lib/deployment/environment-poll-status.js +138 -0
  213. package/lib/deployment/environment.js +42 -34
  214. package/lib/external-system/download-helpers.js +87 -0
  215. package/lib/external-system/download.js +78 -138
  216. package/lib/external-system/generator.js +1 -55
  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.js +16 -21
  220. package/lib/generator/builders.js +11 -1
  221. package/lib/generator/external-controller-manifest.js +18 -0
  222. package/lib/generator/split.js +3 -1
  223. package/lib/generator/wizard.js +1 -28
  224. package/lib/governance/governance-cli-errors.js +96 -0
  225. package/lib/governance/governance-download-display.js +38 -0
  226. package/lib/governance/governance-run-display.js +215 -25
  227. package/lib/identity/fk-reference.js +65 -0
  228. package/lib/identity/identity-apply-core.js +13 -58
  229. package/lib/identity/identity-apply-phases.js +5 -1
  230. package/lib/identity/identity-display.js +243 -0
  231. package/lib/identity/identity-response-helpers.js +52 -0
  232. package/lib/identity/identity-sync-errors.js +62 -0
  233. package/lib/identity/resolve-user-id.js +129 -0
  234. package/lib/identity/username-default.js +31 -0
  235. package/lib/infrastructure/admin-secrets-apply.js +84 -0
  236. package/lib/infrastructure/admin-secrets-ensure.js +130 -0
  237. package/lib/infrastructure/admin-secrets-resolve.js +95 -0
  238. package/lib/infrastructure/admin-secrets-sync.js +91 -0
  239. package/lib/infrastructure/helpers.js +23 -129
  240. package/lib/infrastructure/index.js +5 -6
  241. package/lib/infrastructure/orphan-infra-docker-teardown.js +11 -5
  242. package/lib/lifecycle/certification-progress.js +231 -0
  243. package/lib/lifecycle/dataplane-ui-url.js +145 -0
  244. package/lib/lifecycle/exit-codes.js +24 -0
  245. package/lib/lifecycle/json-envelope.js +25 -0
  246. package/lib/lifecycle/lifecycle-governance-options.js +51 -0
  247. package/lib/lifecycle/logger-quiet.js +29 -0
  248. package/lib/lifecycle/open-api-published.js +59 -0
  249. package/lib/lifecycle/operations-readiness-metrics.js +101 -0
  250. package/lib/lifecycle/product-model.js +196 -0
  251. package/lib/lifecycle/report-display-trust.js +70 -0
  252. package/lib/lifecycle/report-display.js +472 -0
  253. package/lib/lifecycle/scenario-upload.js +191 -0
  254. package/lib/lifecycle/verify-step-progress.js +87 -0
  255. package/lib/parameters/infra-kv-discovery.js +27 -2
  256. package/lib/protection/auth-context.js +10 -4
  257. package/lib/resolvers/datasource-resolver.js +2 -3
  258. package/lib/resolvers/resource-type-file.js +159 -0
  259. package/lib/schema/application-schema.json +17 -1
  260. package/lib/schema/datasource-test-run.schema.json +89 -6
  261. package/lib/schema/deployment-rules.yaml +2 -1
  262. package/lib/schema/external-datasource.schema.json +2947 -2619
  263. package/lib/schema/external-system.schema.json +1418 -761
  264. package/lib/schema/infra.parameter.yaml +45 -0
  265. package/lib/schema/type/credential-field-registry.json +103 -97
  266. package/lib/schema/type/document-storage.json +9 -5
  267. package/lib/utils/aifabrix-test-runtime-guard.js +125 -0
  268. package/lib/utils/api.js +55 -31
  269. package/lib/utils/app-relative-path-env.js +112 -0
  270. package/lib/utils/app-run-containers.js +25 -2
  271. package/lib/utils/authentication-shape.js +224 -0
  272. package/lib/utils/build-copy.js +36 -5
  273. package/lib/utils/build-resolve-image.js +66 -12
  274. package/lib/utils/celery-companion-apps.js +53 -0
  275. package/lib/utils/cli-secrets-error-format.js +83 -21
  276. package/lib/utils/cli-utils.js +20 -4
  277. package/lib/utils/compose-celery-worker.js +23 -0
  278. package/lib/utils/compose-generate-docker-compose.js +13 -1
  279. package/lib/utils/compose-traefik-ingress-base.js +16 -1
  280. package/lib/utils/config-secrets-path.js +46 -0
  281. package/lib/utils/configuration-env-resolver.js +36 -0
  282. package/lib/utils/controller-url.js +88 -1
  283. package/lib/utils/credential-secrets-env-kv.js +216 -0
  284. package/lib/utils/credential-secrets-env.js +175 -257
  285. package/lib/utils/dataplane-resolver.js +18 -2
  286. package/lib/utils/declarative-url-ports.js +27 -4
  287. package/lib/utils/deployment-auth-mode.js +41 -0
  288. package/lib/utils/developer-volume-id.js +33 -0
  289. package/lib/utils/docker-build.js +1 -4
  290. package/lib/utils/env-copy.js +14 -9
  291. package/lib/utils/env-kv-orphan-lines.js +43 -0
  292. package/lib/utils/error-formatters/network-errors.js +13 -4
  293. package/lib/utils/external-env-template.js +11 -3
  294. package/lib/utils/external-system-readiness-core.js +10 -0
  295. package/lib/utils/external-system-readiness-display.js +80 -23
  296. package/lib/utils/external-system-validators.js +8 -2
  297. package/lib/utils/health-check.js +4 -1
  298. package/lib/utils/help-builder.js +13 -8
  299. package/lib/utils/keycloak-realm-ready.js +101 -0
  300. package/lib/utils/load-cip-capacity-display-config.js +61 -15
  301. package/lib/utils/manifest-source-emit.js +2 -0
  302. package/lib/utils/paths.js +25 -0
  303. package/lib/utils/pipeline-upload-auth-retry.js +82 -0
  304. package/lib/utils/platform-controller-url.js +157 -0
  305. package/lib/utils/platform-kv-ref.js +57 -0
  306. package/lib/utils/postgres-platform-bootstrap.js +199 -0
  307. package/lib/utils/postgres-wipe.js +9 -2
  308. package/lib/utils/resolve-env-mode.js +47 -0
  309. package/lib/utils/runtime-configuration-download.js +189 -0
  310. package/lib/utils/runtime-configuration-values.js +119 -0
  311. package/lib/utils/schema-loader.js +19 -4
  312. package/lib/utils/secrets-generator.js +31 -25
  313. package/lib/utils/secrets-missing-error.js +164 -0
  314. package/lib/utils/service-url-label.js +81 -0
  315. package/lib/utils/setup-quiet-output.js +25 -0
  316. package/lib/utils/template-helpers.js +15 -0
  317. package/lib/utils/token-manager-client-credentials.js +201 -0
  318. package/lib/utils/token-manager-messages.js +8 -0
  319. package/lib/utils/token-manager-refresh.js +12 -2
  320. package/lib/utils/token-manager.js +86 -105
  321. package/lib/utils/upload-pipeline-ui.js +12 -5
  322. package/lib/utils/upload-sync-options.js +42 -0
  323. package/lib/utils/url-declarative-public-base.js +21 -3
  324. package/lib/utils/url-declarative-vdir-inactive-env.js +14 -4
  325. package/lib/utils/validation-poll-ui.js +8 -0
  326. package/lib/utils/validation-run-stage.js +45 -0
  327. package/lib/utils/worker-sidecars.js +142 -0
  328. package/lib/validation/external-manifest-validator.js +2 -0
  329. package/lib/validation/runtime-configuration-rules.js +98 -0
  330. package/lib/validation/validate-display-dimensions.js +154 -0
  331. package/lib/validation/validate-display-sections.js +276 -0
  332. package/lib/validation/validate-display-steps.js +67 -0
  333. package/lib/validation/validate-display.js +24 -402
  334. package/package.json +1 -1
  335. package/templates/applications/dataplane/application.yaml +7 -1
  336. package/templates/applications/dataplane/env.template +50 -14
  337. package/templates/applications/dataplane/rbac.yaml +108 -1
  338. package/templates/applications/miso-controller/application.yaml +2 -2
  339. package/templates/applications/miso-controller/env.template +53 -122
  340. package/templates/applications/miso-controller/rbac.yaml +28 -13
  341. package/templates/channels/chatgpt/install.template.md.hbs +49 -0
  342. package/templates/channels/chatgpt/manifest.template.json.hbs +9 -0
  343. package/templates/channels/microsoft-copilot/install.template.md.hbs +49 -0
  344. package/templates/channels/microsoft-copilot/manifest.template.json.hbs +8 -0
  345. package/templates/channels/slack/install.template.md.hbs +49 -0
  346. package/templates/channels/slack/manifest.template.json.hbs +66 -0
  347. package/templates/channels/teams-bot/install.template.md.hbs +49 -0
  348. package/templates/channels/teams-bot/manifest.template.json.hbs +13 -0
  349. package/templates/channels/web-embed/install.template.md.hbs +49 -0
  350. package/templates/channels/web-embed/manifest.template.json.hbs +8 -0
  351. package/templates/external-system/README.md.hbs +74 -17
  352. package/templates/python/docker-compose.hbs +75 -18
  353. package/templates/typescript/docker-compose.hbs +70 -17
  354. package/lib/commands/test-governance-command-action.js +0 -55
  355. package/lib/commands/test-trust-command-action.js +0 -118
@@ -29,7 +29,12 @@ const { checkHealthEndpoint } = require('../utils/health-check');
29
29
  const { validateControllerUrl } = require('../utils/auth-config-validator');
30
30
  const app = require('../app');
31
31
  const { assertDevInfraUp } = require('./dev-infra-gate');
32
- const { ensureAppFromTemplate, validateEnvOutputPathFolderOrNull, refreshUrlsLocalRegistryForCurrentProject } = require('./up-common');
32
+ const { dataplaneDockerHostPort } = require('../utils/declarative-url-ports');
33
+ const {
34
+ ensureDataplaneAppsFromTemplate,
35
+ validateEnvOutputPathFolderOrNull,
36
+ refreshUrlsLocalRegistryForCurrentProject
37
+ } = require('./up-common');
33
38
 
34
39
  const CONTROLLER_HEALTH_PATH = '/health';
35
40
 
@@ -103,6 +108,22 @@ async function resolveControllerUrlWithHealthCheck() {
103
108
  return normalizedNew;
104
109
  }
105
110
 
111
+ async function resolveUpDataplaneAuthContext(options, environmentKey) {
112
+ if (options.skipInfraCheck !== true) {
113
+ await assertDevInfraUp();
114
+ }
115
+
116
+ const controllerUrl = await resolveControllerUrlWithHealthCheck();
117
+ const authConfig = await checkAuthentication(controllerUrl, environmentKey, { throwOnFailure: true });
118
+
119
+ const cfg = await config.getConfig();
120
+ if (options.allowNonDev !== true) {
121
+ assertDevEnvironmentForDataplane(cfg);
122
+ }
123
+ logger.log(formatSuccessLine(`Logged in (environment: ${environmentKey})`));
124
+ return { controllerUrl, authConfig };
125
+ }
126
+
106
127
  /**
107
128
  * Register or rotate dataplane: if app exists in controller, rotate secret; otherwise register.
108
129
  * @async
@@ -118,7 +139,12 @@ async function registerOrRotateDataplane(options, controllerUrl, environmentKey,
118
139
  await rotateSecret('dataplane', options);
119
140
  } else {
120
141
  const imageOverride = options.image || buildDataplaneImageRef(options);
121
- const registerOpts = { imageOverride, image: imageOverride, registryMode: options.registryMode };
142
+ const registerOpts = {
143
+ imageOverride,
144
+ image: imageOverride,
145
+ registryMode: options.registryMode,
146
+ envKey: environmentKey
147
+ };
122
148
  await registerApplication('dataplane', registerOpts);
123
149
  }
124
150
  }
@@ -134,6 +160,7 @@ async function deployDataplaneToController(options) {
134
160
  imageOverride,
135
161
  image: imageOverride,
136
162
  registryMode: options.registryMode,
163
+ envKey: options.envKey ? String(options.envKey).trim().toLowerCase() : undefined,
137
164
  // Guided up-platform already shows a top-level spinner for the dataplane step.
138
165
  // Avoid nested deploy polling spinners/logs.
139
166
  silentPoll: options.platformInstall === true
@@ -172,6 +199,13 @@ function emitDataplaneManifestLineFromBuilder() {
172
199
  emitSystemBuilderAppManifestLineIfTTY(logger, 'dataplane');
173
200
  }
174
201
 
202
+ function computeDataplanePortOverride(runEnvKey, developerIdNum) {
203
+ if (runEnvKey !== 'dev' && runEnvKey !== 'tst') {
204
+ return undefined;
205
+ }
206
+ return dataplaneDockerHostPort(3001, developerIdNum, runEnvKey);
207
+ }
208
+
175
209
  function assertDevEnvironmentForDataplane(cfg) {
176
210
  const environment = (cfg && cfg.environment) ? cfg.environment : 'dev';
177
211
  if (environment !== 'dev') {
@@ -181,6 +215,14 @@ function assertDevEnvironmentForDataplane(cfg) {
181
215
  }
182
216
  }
183
217
 
218
+ async function computeDataplaneRunOverrides(options) {
219
+ const runEnvKey = options.runEnvKey ? String(options.runEnvKey).trim().toLowerCase() : undefined;
220
+ const developerIdRaw = await config.getDeveloperId();
221
+ const developerIdNum = typeof developerIdRaw === 'string' ? parseInt(developerIdRaw, 10) : developerIdRaw;
222
+ const portOverride = computeDataplanePortOverride(runEnvKey, developerIdNum);
223
+ return { runEnvKey, portOverride };
224
+ }
225
+
184
226
  /**
185
227
  * Handle up-dataplane command: ensure logged in, environment dev, ensure dataplane,
186
228
  * register or rotate (if already registered), deploy (send manifest to controller),
@@ -199,19 +241,13 @@ function assertDevEnvironmentForDataplane(cfg) {
199
241
  async function handleUpDataplane(options = {}) {
200
242
  logger.log(chalk.blue('Starting up-dataplane (register/rotate, deploy, then run dataplane locally)...\n'));
201
243
 
202
- if (options.skipInfraCheck !== true) {
203
- await assertDevInfraUp();
204
- }
244
+ const environmentKey =
245
+ options && options.envKey
246
+ ? String(options.envKey).trim().toLowerCase()
247
+ : await resolveEnvironment();
248
+ const { controllerUrl, authConfig } = await resolveUpDataplaneAuthContext(options, environmentKey);
205
249
 
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'));
213
-
214
- await ensureAppFromTemplate('dataplane');
250
+ await ensureDataplaneAppsFromTemplate();
215
251
  // If envOutputPath target folder does not exist, set envOutputPath to null
216
252
  validateEnvOutputPathFolderOrNull('dataplane');
217
253
 
@@ -223,10 +259,15 @@ async function handleUpDataplane(options = {}) {
223
259
 
224
260
  await registerOrRotateDataplane(options, controllerUrl, environmentKey, authConfig);
225
261
 
226
- await deployDataplaneToController(options);
262
+ await deployDataplaneToController({ ...options, envKey: environmentKey });
227
263
  logger.log('');
264
+
265
+ const { runEnvKey, portOverride } = await computeDataplaneRunOverrides(options);
266
+
228
267
  await app.runApp('dataplane', {
229
268
  skipEnvOutputPath: true,
269
+ env: runEnvKey,
270
+ port: portOverride,
230
271
  registry: options.registry || undefined,
231
272
  base: options.base !== false,
232
273
  skipManifestMetadataLine: true
@@ -0,0 +1,75 @@
1
+ /**
2
+ * @fileoverview Upload publish preflight: auth resolve, CLI gate, target logging.
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 { sectionTitle, headerKeyValue } = require('../utils/cli-test-layout-chalk');
12
+ const { resolveControllerUrl } = require('../utils/controller-url');
13
+ const { requireBearerForDataplanePipeline } = require('../utils/token-manager');
14
+ const { logDataplanePipelineWarning } = require('../utils/dataplane-pipeline-warning');
15
+ const { assertDataplaneCliVersionCompatible } = require('../utils/dataplane-cli-version-gate');
16
+
17
+ const SEP = chalk.gray('────────────────────────────────────────');
18
+
19
+ function logForcePublishWarning() {
20
+ logger.log(
21
+ chalk.yellow(
22
+ 'Warning: --force bypasses active-datasource schema replacement guards on publish. '
23
+ + 'Existing records and ABAC may be inconsistent; run validation/sync after upload.'
24
+ )
25
+ );
26
+ }
27
+
28
+ function logUploadTargetSection(environment, dataplaneUrl) {
29
+ logger.log('');
30
+ logger.log(sectionTitle('Target'));
31
+ logger.log(SEP);
32
+ logger.log(headerKeyValue('Environment:', environment));
33
+ logger.log(headerKeyValue('Dataplane:', dataplaneUrl));
34
+ logDataplanePipelineWarning();
35
+ }
36
+
37
+ /**
38
+ * Resolve dataplane auth and run upload preflight checks.
39
+ * @param {Function} resolveDataplaneAndAuth
40
+ * @param {Function} maybeRunVerboseServerValidation
41
+ * @param {string} systemKey
42
+ * @param {Object} options
43
+ * @param {Object} payload
44
+ * @returns {Promise<{ dataplaneUrl: string, authConfig: Object, environment: string }>}
45
+ */
46
+ async function resolveUploadPublishContext(
47
+ resolveDataplaneAndAuth,
48
+ maybeRunVerboseServerValidation,
49
+ systemKey,
50
+ options,
51
+ payload
52
+ ) {
53
+ const resolved = await resolveDataplaneAndAuth(systemKey, {
54
+ silent: options.silentResolve === true
55
+ });
56
+ requireBearerForDataplanePipeline(resolved.authConfig);
57
+ if (options.force === true) {
58
+ logForcePublishWarning();
59
+ }
60
+ const controllerUrl = await resolveControllerUrl();
61
+ await assertDataplaneCliVersionCompatible(resolved.dataplaneUrl, { controllerUrl });
62
+ if (options.minimal !== true) {
63
+ logUploadTargetSection(resolved.environment, resolved.dataplaneUrl);
64
+ }
65
+ if (options.verbose) {
66
+ await maybeRunVerboseServerValidation(resolved.dataplaneUrl, resolved.authConfig, payload);
67
+ }
68
+ return resolved;
69
+ }
70
+
71
+ module.exports = {
72
+ logForcePublishWarning,
73
+ logUploadTargetSection,
74
+ resolveUploadPublishContext
75
+ };
@@ -0,0 +1,89 @@
1
+ /**
2
+ * @fileoverview Upload sidecar follow-ups (governance packs, certification sync).
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const logger = require('../utils/logger');
10
+ const { formatWarningLine } = require('../utils/cli-test-layout-chalk');
11
+ const { unwrapPublicationResult, isPublicationUnchanged } = require('../utils/external-system-readiness-core');
12
+ const { logUploadReadinessSummary } = require('../utils/external-system-readiness-display');
13
+ const { maybeSyncSystemCertificationFromDataplane } = require('../certification/sync-system-certification');
14
+ const { cliOptsSkipCertSync } = require('../certification/cli-cert-sync-skip');
15
+ const { isQuietMinimalSync } = require('../utils/upload-sync-options');
16
+
17
+ /**
18
+ * Sidecar follow-ups that are independent of pipeline publish hash (scenario packs, cert sync).
19
+ * @param {Object} ctx
20
+ * @returns {Promise<void>}
21
+ */
22
+ async function runUploadSidecarFollowups(ctx) {
23
+ const { systemKey, options, payload, dataplaneUrl, authConfig } = ctx;
24
+ const quietSidecar = isQuietMinimalSync(options);
25
+ const dsKeys = (payload.dataSources || []).map((ds) => ds && ds.key).filter(Boolean);
26
+ try {
27
+ const { uploadGovernanceScenarioPacks } = require('../lifecycle/scenario-upload');
28
+ await uploadGovernanceScenarioPacks(systemKey, dataplaneUrl, authConfig, { silent: quietSidecar });
29
+ } catch (err) {
30
+ if (!quietSidecar) {
31
+ logger.log(formatWarningLine(`Governance scenario upload skipped: ${err.message}`));
32
+ }
33
+ }
34
+ await maybeSyncSystemCertificationFromDataplane({
35
+ label: 'upload',
36
+ noCertSync: cliOptsSkipCertSync(options),
37
+ systemKey,
38
+ dataplaneUrl,
39
+ authConfig,
40
+ datasourceKeys: dsKeys,
41
+ silent: quietSidecar
42
+ });
43
+ }
44
+
45
+ /**
46
+ * @param {Object} ctx
47
+ * @param {Function} maybeRunUploadProbe
48
+ * @returns {Promise<void>}
49
+ */
50
+ async function handlePublicationAndFollowups(ctx, maybeRunUploadProbe) {
51
+ const {
52
+ systemKey,
53
+ options,
54
+ manifest,
55
+ payload,
56
+ environment,
57
+ dataplaneUrl,
58
+ authConfig,
59
+ rawRes
60
+ } = ctx;
61
+ const publication = unwrapPublicationResult(rawRes);
62
+ if (!publication) {
63
+ throw new Error(
64
+ 'Unexpected response from dataplane upload: missing publication result (uploadId/system/datasources).'
65
+ );
66
+ }
67
+ if (isPublicationUnchanged(publication)) {
68
+ await runUploadSidecarFollowups({ systemKey, options, payload, dataplaneUrl, authConfig });
69
+ return;
70
+ }
71
+ logUploadReadinessSummary({
72
+ environment,
73
+ dataplaneUrl,
74
+ systemKey,
75
+ publication,
76
+ manifest,
77
+ minimal: !!options.minimal,
78
+ willProbe: !!options.probe
79
+ });
80
+ if (options.probe) {
81
+ await maybeRunUploadProbe(dataplaneUrl, systemKey, authConfig, options.probeTimeout);
82
+ }
83
+ await runUploadSidecarFollowups({ systemKey, options, payload, dataplaneUrl, authConfig });
84
+ }
85
+
86
+ module.exports = {
87
+ runUploadSidecarFollowups,
88
+ handlePublicationAndFollowups
89
+ };
@@ -21,7 +21,7 @@ const logger = require('../utils/logger');
21
21
 
22
22
  const SEP = chalk.gray('────────────────────────────────────────');
23
23
  const { resolveControllerUrl } = require('../utils/controller-url');
24
- const { getDeploymentAuth, requireBearerForDataplanePipeline } = require('../utils/token-manager');
24
+ const { getDeploymentAuth } = require('../utils/token-manager');
25
25
  const { resolveDataplaneUrl } = require('../utils/dataplane-resolver');
26
26
  const { getIntegrationPath } = require('../utils/paths');
27
27
  const { pushCredentialSecrets } = require('../utils/credential-secrets-env');
@@ -32,26 +32,29 @@ const {
32
32
  resolveConfigurationValues,
33
33
  collectResolvedVariableConfigurationNames
34
34
  } = require('../utils/configuration-env-resolver');
35
+ const { pushRuntimeConfigurationValues } = require('../utils/runtime-configuration-values');
35
36
  const { validateExternalSystemComplete } = require('../validation/validate');
36
37
  const { displayValidationResults } = require('../validation/validate-display');
37
38
  const { generateControllerManifest } = require('../generator/external-controller-manifest');
38
39
  const {
39
- uploadApplicationViaPipeline,
40
40
  validatePipelineConfig,
41
41
  testSystemViaPipeline
42
42
  } = require('../api/pipeline.api');
43
+ const { uploadApplicationViaPipelineWithAuthRetry } = require('../utils/pipeline-upload-auth-retry');
43
44
  const { formatApiError } = require('../utils/api-error-handler');
44
- const { logDataplanePipelineWarning } = require('../utils/dataplane-pipeline-warning');
45
- const { unwrapPublicationResult, unwrapApiData } = require('../utils/external-system-readiness-core');
45
+ const { unwrapPublicationResult, unwrapApiData, isPublicationUnchanged } = require('../utils/external-system-readiness-core');
46
46
  const {
47
- logUploadReadinessSummary,
48
47
  logServerValidationWarnings,
49
48
  logProbeRuntimeBlock
50
49
  } = require('../utils/external-system-readiness-display');
51
- const { maybeSyncSystemCertificationFromDataplane } = require('../certification/sync-system-certification');
52
- const { cliOptsSkipCertSync } = require('../certification/cli-cert-sync-skip');
53
50
  const { maybeSyncOpenApiFilesForMcp } = require('./repair-openapi-sync');
54
- const { assertDataplaneCliVersionCompatible } = require('../utils/dataplane-cli-version-gate');
51
+ const { resolveUploadPublishContext } = require('./upload-publish-context');
52
+ const { syncDeployJsonFromSources } = require('../external-system/sync-deploy-manifest');
53
+ const { isQuietMinimalSync } = require('../utils/upload-sync-options');
54
+ const {
55
+ runUploadSidecarFollowups,
56
+ handlePublicationAndFollowups
57
+ } = require('./upload-sidecar-followups');
55
58
 
56
59
  /**
57
60
  * Validates system-key format (same as download).
@@ -73,13 +76,22 @@ function validateSystemKeyFormat(systemKey) {
73
76
  * @param {Object} manifest - Controller manifest from generateControllerManifest
74
77
  * @returns {Object} { version, application, dataSources, status: "draft" }
75
78
  */
76
- function buildUploadPayload(manifest) {
77
- return {
79
+ /**
80
+ * @param {Object} manifest - Controller manifest from generateControllerManifest
81
+ * @param {{ force?: boolean }} [opts]
82
+ * @returns {Object}
83
+ */
84
+ function buildUploadPayload(manifest, opts = {}) {
85
+ const payload = {
78
86
  version: manifest.version || '1.0.0',
79
87
  application: manifest.system,
80
88
  dataSources: manifest.dataSources || [],
81
89
  status: 'draft'
82
90
  };
91
+ if (opts.force === true) {
92
+ payload.force = true;
93
+ }
94
+ return payload;
83
95
  }
84
96
 
85
97
  /**
@@ -113,11 +125,15 @@ async function resolveDataplaneAndAuth(systemKey, opts = {}) {
113
125
  * @param {Object} payload - { version, application, dataSources, status: "draft" }
114
126
  * @returns {Promise<Object>} Raw API response envelope
115
127
  */
116
- async function runUploadValidatePublish(dataplaneUrl, authConfig, payload) {
117
- const res = await uploadApplicationViaPipeline(dataplaneUrl, authConfig, payload);
128
+ async function runUploadValidatePublish(dataplaneUrl, authConfig, payload, systemKey) {
129
+ const res = await uploadApplicationViaPipelineWithAuthRetry(
130
+ dataplaneUrl,
131
+ authConfig,
132
+ payload,
133
+ systemKey
134
+ );
118
135
  if (res?.success === false) {
119
- const msg = formatApiError(res, dataplaneUrl);
120
- throw new Error(msg);
136
+ throw new Error(formatApiError(res, dataplaneUrl));
121
137
  }
122
138
  return res;
123
139
  }
@@ -204,6 +220,24 @@ async function pushAndLogCredentialSecrets(dataplaneUrl, authConfig, systemKey,
204
220
  if (pushResult.warning) {
205
221
  logger.log(chalk.yellow(`Warning: ${pushResult.warning}`));
206
222
  }
223
+ try {
224
+ const configPush = await pushRuntimeConfigurationValues(
225
+ dataplaneUrl,
226
+ authConfig,
227
+ systemKey,
228
+ payload
229
+ );
230
+ if (configPush.pushed > 0) {
231
+ const nameList = configPush.names.length ? ` (${configPush.names.join(', ')})` : '';
232
+ logger.log(
233
+ formatSuccessLine(
234
+ `Stored ${configPush.pushed} runtime configuration value(s) in dataplane${nameList}.`
235
+ )
236
+ );
237
+ }
238
+ } catch (err) {
239
+ logger.log(chalk.yellow(`Warning: runtime configuration store skipped: ${err.message}`));
240
+ }
207
241
  }
208
242
 
209
243
  /**
@@ -269,18 +303,22 @@ async function maybeRunUploadProbe(dataplaneUrl, systemKey, authConfig, probeTim
269
303
 
270
304
  /**
271
305
  * Local validation, manifest, payload, and configuration resolution.
272
- * Does not write *-deploy.json; run `aifabrix json <systemKey>` to regenerate the deployment manifest from sources.
306
+ * Regenerates integration/<systemKey>/<systemKey>-deploy.json from sources (same as `aifabrix json`).
273
307
  *
274
308
  * @param {string} systemKey
275
309
  * @param {{ dryRun?: boolean }} [_opts] - Reserved for callers (e.g. dry-run); manifest is always built from current disk files
276
310
  * @returns {Promise<{ manifest: Object, payload: Object }>}
277
311
  */
278
- async function buildValidatedUploadManifestPayload(systemKey, _opts = {}) {
312
+ async function buildValidatedUploadManifestPayload(systemKey, opts = {}) {
313
+ const quiet = opts.minimal === true || opts.quiet === true;
279
314
  const validationResult = await validateExternalSystemComplete(systemKey, { type: 'external' });
280
315
  throwIfValidationFailed(validationResult);
281
- logger.log(formatSuccessLine('Local validation passed'));
316
+ if (!quiet) {
317
+ logger.log(formatSuccessLine('Local validation passed'));
318
+ }
319
+ await syncDeployJsonFromSources(systemKey, { quiet });
282
320
  const manifest = await generateControllerManifest(systemKey, { type: 'external' });
283
- const payload = buildUploadPayload(manifest);
321
+ const payload = buildUploadPayload(manifest, { force: opts.force === true });
284
322
  await resolvePayloadConfiguration(systemKey, payload);
285
323
  return { manifest, payload };
286
324
  }
@@ -295,7 +333,7 @@ async function buildValidatedUploadManifestPayload(systemKey, _opts = {}) {
295
333
  * @param {Object} manifest
296
334
  * @returns {Promise<void>}
297
335
  */
298
- async function logAndSyncLocalOpenApiForUpload(systemKey, manifest) {
336
+ async function logAndSyncLocalOpenApiForUpload(systemKey, manifest, uploadContext = {}) {
299
337
  const appPath = getIntegrationPath(systemKey);
300
338
  const ei = manifest && manifest.externalIntegration;
301
339
  const datasourceFiles = ei && Array.isArray(ei.dataSources) ? ei.dataSources : [];
@@ -304,65 +342,15 @@ async function logAndSyncLocalOpenApiForUpload(systemKey, manifest) {
304
342
  dryRun: false,
305
343
  appPath,
306
344
  systemKey,
307
- datasourceFiles
345
+ datasourceFiles,
346
+ dataplaneUrl: uploadContext.dataplaneUrl,
347
+ authConfig: uploadContext.authConfig
308
348
  });
309
349
  for (const line of openapiSyncLines) {
310
350
  logger.log(line.startsWith('Skipped') ? formatWarningLine(line) : formatSuccessLine(line));
311
351
  }
312
352
  }
313
353
 
314
- /**
315
- * @param {Object} ctx
316
- * @param {string} ctx.systemKey
317
- * @param {Object} ctx.options
318
- * @param {Object} ctx.manifest
319
- * @param {Object} ctx.payload
320
- * @param {string} ctx.environment
321
- * @param {string} ctx.dataplaneUrl
322
- * @param {Object} ctx.authConfig
323
- * @param {Object} ctx.rawRes
324
- * @returns {Promise<void>}
325
- */
326
- async function handlePublicationAndFollowups(ctx) {
327
- const {
328
- systemKey,
329
- options,
330
- manifest,
331
- payload,
332
- environment,
333
- dataplaneUrl,
334
- authConfig,
335
- rawRes
336
- } = ctx;
337
- const publication = unwrapPublicationResult(rawRes);
338
- if (!publication) {
339
- throw new Error(
340
- 'Unexpected response from dataplane upload: missing publication result (uploadId/system/datasources).'
341
- );
342
- }
343
- logUploadReadinessSummary({
344
- environment,
345
- dataplaneUrl,
346
- systemKey,
347
- publication,
348
- manifest,
349
- minimal: !!options.minimal,
350
- willProbe: !!options.probe
351
- });
352
- if (options.probe) {
353
- await maybeRunUploadProbe(dataplaneUrl, systemKey, authConfig, options.probeTimeout);
354
- }
355
- const dsKeys = (payload.dataSources || []).map((ds) => ds && ds.key).filter(Boolean);
356
- await maybeSyncSystemCertificationFromDataplane({
357
- label: 'upload',
358
- noCertSync: cliOptsSkipCertSync(options),
359
- systemKey,
360
- dataplaneUrl,
361
- authConfig,
362
- datasourceKeys: dsKeys
363
- });
364
- }
365
-
366
354
  /**
367
355
  * Upload path after dry-run check.
368
356
  * @param {string} systemKey
@@ -371,45 +359,55 @@ async function handlePublicationAndFollowups(ctx) {
371
359
  * @param {Object} payload
372
360
  */
373
361
  async function runUploadPublishAndSummary(systemKey, options, manifest, payload) {
374
- const { dataplaneUrl, authConfig, environment } = await resolveDataplaneAndAuth(systemKey, {
375
- silent: options.silentResolve === true
376
- });
377
- requireBearerForDataplanePipeline(authConfig);
378
- const controllerUrl = await resolveControllerUrl();
379
- // Plan 142.0: gate dataplane API entrypoints by the dataplane-advertised minimum Builder CLI version.
380
- await assertDataplaneCliVersionCompatible(dataplaneUrl, { controllerUrl });
381
- logger.log('');
382
- logger.log(sectionTitle('Target'));
383
- logger.log(SEP);
384
- logger.log(headerKeyValue('Environment:', environment));
385
- logger.log(headerKeyValue('Dataplane:', dataplaneUrl));
386
- logDataplanePipelineWarning();
387
- if (options.verbose) {
388
- await maybeRunVerboseServerValidation(dataplaneUrl, authConfig, payload);
362
+ const { dataplaneUrl, authConfig, environment } = await resolveUploadPublishContext(
363
+ resolveDataplaneAndAuth,
364
+ maybeRunVerboseServerValidation,
365
+ systemKey,
366
+ options,
367
+ payload
368
+ );
369
+ const rawRes = await runWithUploadPipelineSpinner(
370
+ async() => runUploadValidatePublish(dataplaneUrl, authConfig, payload, systemKey),
371
+ {
372
+ systemKey,
373
+ json: options.json === true,
374
+ syncMode: options.syncMode === true,
375
+ suppressPipelineSpinner: options.suppressPipelineSpinner === true
376
+ }
377
+ );
378
+ const publication = unwrapPublicationResult(rawRes);
379
+ if (isPublicationUnchanged(publication)) {
380
+ if (!isQuietMinimalSync(options)) {
381
+ logger.log(formatSuccessLine('Config unchanged on dataplane — upload skipped.'));
382
+ }
383
+ await runUploadSidecarFollowups({
384
+ systemKey,
385
+ options,
386
+ payload,
387
+ dataplaneUrl,
388
+ authConfig
389
+ });
390
+ return { dataplaneUrl, authConfig, environment, uploadSkipped: true };
389
391
  }
392
+
390
393
  await pushAndLogCredentialSecrets(dataplaneUrl, authConfig, systemKey, payload, {
391
394
  json: options.json === true
392
395
  });
393
-
394
- const rawRes = await runWithUploadPipelineSpinner(
395
- async() => {
396
- const res = await runUploadValidatePublish(dataplaneUrl, authConfig, payload);
397
- await logAndSyncLocalOpenApiForUpload(systemKey, manifest);
398
- return res;
396
+ await logAndSyncLocalOpenApiForUpload(systemKey, manifest, { dataplaneUrl, authConfig });
397
+ await handlePublicationAndFollowups(
398
+ {
399
+ systemKey,
400
+ options,
401
+ manifest,
402
+ payload,
403
+ environment,
404
+ dataplaneUrl,
405
+ authConfig,
406
+ rawRes
399
407
  },
400
- { systemKey, json: options.json === true }
408
+ maybeRunUploadProbe
401
409
  );
402
- await handlePublicationAndFollowups({
403
- systemKey,
404
- options,
405
- manifest,
406
- payload,
407
- environment,
408
- dataplaneUrl,
409
- authConfig,
410
- rawRes
411
- });
412
- return { dataplaneUrl, authConfig, environment };
410
+ return { dataplaneUrl, authConfig, environment, uploadSkipped: false };
413
411
  }
414
412
 
415
413
  /**
@@ -426,12 +424,17 @@ async function runUploadPublishAndSummary(systemKey, options, manifest, payload)
426
424
  */
427
425
  async function uploadExternalSystem(systemKey, options = {}) {
428
426
  validateSystemKeyFormat(systemKey);
429
- logger.log('');
430
- logger.log(sectionTitle('Upload external system'));
431
- logger.log(SEP);
432
- logger.log(headerKeyValue('System:', systemKey));
427
+ const minimal = options.minimal === true;
428
+ if (!minimal) {
429
+ logger.log('');
430
+ logger.log(sectionTitle('Upload external system'));
431
+ logger.log(SEP);
432
+ logger.log(headerKeyValue('System:', systemKey));
433
+ }
433
434
  const { manifest, payload } = await buildValidatedUploadManifestPayload(systemKey, {
434
- dryRun: !!options.dryRun
435
+ dryRun: !!options.dryRun,
436
+ force: options.force === true,
437
+ minimal
435
438
  });
436
439
  if (options.dryRun) {
437
440
  logger.log(chalk.yellow('Dry run: would upload payload (no API calls).'));
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @fileoverview verify-governance — sync, generate, verify (424.0 dataplane-first).
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ const { runGovernanceGenerateForExternalSystem } = require('./governance-generate-external');
8
+ const { runVerifyGovernanceForExternalSystem } = require('./verify-governance-external');
9
+ const {
10
+ buildSubjectsFromOptions,
11
+ resolveGovernanceIntegrationContext
12
+ } = require('./governance-cli-shared');
13
+
14
+ /**
15
+ * @async
16
+ * @param {string} systemKey
17
+ * @param {Object} options
18
+ * @returns {Promise<Object>}
19
+ */
20
+ async function runVerifyGovernanceCombined(systemKey, options = {}) {
21
+ if (options.pack) {
22
+ return runVerifyGovernanceForExternalSystem(systemKey, options);
23
+ }
24
+
25
+ const subjects = buildSubjectsFromOptions(options);
26
+ if (subjects.length === 0) {
27
+ throw new Error(
28
+ 'At least one --subject-user-id or --subject-email is required for verify-governance'
29
+ );
30
+ }
31
+
32
+ const { resolvedKey, authConfig, dataplaneUrl } = await resolveGovernanceIntegrationContext(
33
+ systemKey,
34
+ options
35
+ );
36
+
37
+ const pipelineOpts = {
38
+ ...options,
39
+ noSync: true,
40
+ authConfig,
41
+ dataplaneUrl
42
+ };
43
+
44
+ const generateResult = await runGovernanceGenerateForExternalSystem(
45
+ resolvedKey,
46
+ pipelineOpts
47
+ );
48
+
49
+ const verifyResult = await runVerifyGovernanceForExternalSystem(resolvedKey, pipelineOpts);
50
+
51
+ return {
52
+ ...verifyResult,
53
+ command: 'verify-governance',
54
+ generated: generateResult.generated,
55
+ generateResults: generateResult.results
56
+ };
57
+ }
58
+
59
+ module.exports = {
60
+ runVerifyGovernanceCombined
61
+ };