@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
@@ -17,6 +17,7 @@ const {
17
17
  findMatchingOpsKeys,
18
18
  resolveProfileKeyForLogical
19
19
  } = require('./capability-resolve');
20
+ const { capabilityKeyFromEntry } = require('./capability-manifest');
20
21
 
21
22
  /**
22
23
  * @param {unknown} capabilities
@@ -28,7 +29,7 @@ function findCapabilityIndex(capabilities, logicalName) {
28
29
  return -1;
29
30
  }
30
31
  return capabilities.findIndex(
31
- (c) => String(c).toLowerCase() === String(logicalName).toLowerCase()
32
+ (c) => capabilityKeyFromEntry(c).toLowerCase() === String(logicalName).toLowerCase()
32
33
  );
33
34
  }
34
35
 
@@ -8,6 +8,7 @@
8
8
 
9
9
  const fs = require('node:fs');
10
10
  const path = require('path');
11
+ const { loadConfigFile, writeConfigFile } = require('../../utils/config-format');
11
12
  const { writeBackup } = require('../../utils/integration-file-backup');
12
13
  const {
13
14
  resolveValidateInputPath,
@@ -46,6 +47,33 @@ function resolveCapabilityCopyInputPath(identifier) {
46
47
  return resolveValidateInputPath(trimmed);
47
48
  }
48
49
 
50
+ /**
51
+ * Read a datasource config file (.json, .yaml, or .yml).
52
+ *
53
+ * @param {string} filePath
54
+ * @returns {object}
55
+ */
56
+ function readDatasourceConfigFile(filePath) {
57
+ return loadConfigFile(filePath);
58
+ }
59
+
60
+ /**
61
+ * @param {string} filePath
62
+ * @returns {'json'|'yaml'}
63
+ */
64
+ function inferDatasourceConfigFormat(filePath) {
65
+ const ext = path.extname(filePath).toLowerCase();
66
+ if (ext === '.json') {
67
+ return 'json';
68
+ }
69
+ if (ext === '.yaml' || ext === '.yml') {
70
+ return 'yaml';
71
+ }
72
+ throw new Error(
73
+ `Unsupported datasource config extension: ${ext || '(none)'}. Use .json, .yaml, or .yml`
74
+ );
75
+ }
76
+
49
77
  /**
50
78
  * @param {string} filePath
51
79
  * @param {object} obj
@@ -53,9 +81,9 @@ function resolveCapabilityCopyInputPath(identifier) {
53
81
  */
54
82
  function atomicWriteJson(filePath, obj) {
55
83
  const dir = path.dirname(filePath);
84
+ const format = inferDatasourceConfigFormat(filePath);
56
85
  const tmp = path.join(dir, `.${path.basename(filePath)}.${process.pid}.tmp`);
57
- const payload = `${JSON.stringify(obj, null, 2)}\n`;
58
- fs.writeFileSync(tmp, payload, 'utf8');
86
+ writeConfigFile(tmp, obj, format);
59
87
  fs.renameSync(tmp, filePath);
60
88
  }
61
89
 
@@ -89,8 +117,7 @@ function atomicWriteJson(filePath, obj) {
89
117
  */
90
118
  async function runCapabilityCopy(opts) {
91
119
  const resolvedPath = resolveCapabilityCopyInputPath(opts.fileOrKey.trim());
92
- const raw = fs.readFileSync(resolvedPath, 'utf8');
93
- const parsed = JSON.parse(raw);
120
+ const parsed = readDatasourceConfigFile(resolvedPath);
94
121
 
95
122
  const to = normalizeCapabilityKey(opts.as, 'Target (--as)');
96
123
  const fromRaw = opts.from !== undefined && opts.from !== null ? String(opts.from).trim() : '';
@@ -148,5 +175,6 @@ async function runCapabilityCopy(opts) {
148
175
  module.exports = {
149
176
  runCapabilityCopy,
150
177
  writeBackup,
178
+ readDatasourceConfigFile,
151
179
  atomicWriteJson
152
180
  };
@@ -6,8 +6,8 @@
6
6
  * @version 2.0.0
7
7
  */
8
8
 
9
- const fs = require('fs');
10
9
  const path = require('path');
10
+ const { readDatasourceConfigFile } = require('./run-capability-copy');
11
11
  const { resolveValidateInputPath } = require('../validate');
12
12
  const { normalizeCapabilityKey } = require('./capability-key');
13
13
  const { extractCapabilitySliceForDiff } = require('./capability-diff-slice');
@@ -108,8 +108,8 @@ function resolveProfileKeys(opts) {
108
108
  function runCapabilityDiff(opts) {
109
109
  const pathA = resolveValidateInputPath(opts.fileA.trim());
110
110
  const pathB = resolveValidateInputPath(opts.fileB.trim());
111
- const docA = JSON.parse(fs.readFileSync(pathA, 'utf8'));
112
- const docB = JSON.parse(fs.readFileSync(pathB, 'utf8'));
111
+ const docA = readDatasourceConfigFile(pathA);
112
+ const docB = readDatasourceConfigFile(pathB);
113
113
 
114
114
  const { capA, capB } = resolveCapabilityKeys(opts);
115
115
  const { profA, profB } = resolveProfileKeys(opts);
@@ -8,7 +8,6 @@
8
8
 
9
9
  'use strict';
10
10
 
11
- const fs = require('fs');
12
11
  const { resolveControllerUrl } = require('../../utils/controller-url');
13
12
  const { normalizeControllerUrl } = require('../../core/config');
14
13
  const { getOrRefreshDeviceToken } = require('../../utils/token-manager');
@@ -19,7 +18,7 @@ const {
19
18
  } = require('../validate');
20
19
  const { applyCapabilityDimension } = require('./dimension-operations');
21
20
  const { validateDimensionSemantics } = require('./dimension-validate');
22
- const { writeBackup, atomicWriteJson } = require('./run-capability-copy');
21
+ const { writeBackup, atomicWriteJson, readDatasourceConfigFile } = require('./run-capability-copy');
23
22
  const { tryResolveDatasourceKeyToLocalPath, readJsonFile } = require('../../resolvers/datasource-resolver');
24
23
  const { tryFetchDatasourceConfig } = require('../../resolvers/manifest-resolver');
25
24
 
@@ -231,8 +230,7 @@ function applyBindingAndValidateSchema({ parsed, opts, semanticWarnings, remoteF
231
230
  async function runCapabilityDimension(rawOpts) {
232
231
  const opts = normalizeRunOptions(rawOpts);
233
232
  const resolvedPath = resolveValidateInputPath(opts.fileOrKey);
234
- const raw = fs.readFileSync(resolvedPath, 'utf8');
235
- const parsed = JSON.parse(raw);
233
+ const parsed = readDatasourceConfigFile(resolvedPath);
236
234
 
237
235
  const systemKeyForAuth = resolveSystemKeyForAuth(parsed);
238
236
  const { remoteTargetsByKey, remoteFetchMeta } = await loadRemoteTargetsByKey({
@@ -6,7 +6,6 @@
6
6
  * @version 2.0.0
7
7
  */
8
8
 
9
- const fs = require('fs');
10
9
  const { execSync } = require('child_process');
11
10
  const inquirer = require('inquirer');
12
11
  const {
@@ -19,7 +18,8 @@ const {
19
18
  resolveSingleOpsKey,
20
19
  resolveProfileKeyForLogical
21
20
  } = require('./capability-resolve');
22
- const { writeBackup, atomicWriteJson } = require('./run-capability-copy');
21
+ const { writeBackup, atomicWriteJson, readDatasourceConfigFile } = require('./run-capability-copy');
22
+ const { listCapabilityKeys } = require('./capability-manifest');
23
23
 
24
24
  /**
25
25
  * @typedef {object} RunCapabilityEditOpts
@@ -35,10 +35,7 @@ const { writeBackup, atomicWriteJson } = require('./run-capability-copy');
35
35
  * @returns {string[]}
36
36
  */
37
37
  function collectCapabilityKeys(doc) {
38
- const s = new Set();
39
- if (Array.isArray(doc.capabilities)) {
40
- doc.capabilities.forEach((c) => s.add(String(c)));
41
- }
38
+ const s = new Set(listCapabilityKeys(doc.capabilities));
42
39
  if (doc.openapi?.operations) {
43
40
  Object.keys(doc.openapi.operations).forEach((k) => s.add(k));
44
41
  }
@@ -351,7 +348,7 @@ async function runCapabilityEdit(opts) {
351
348
  throw new Error('capability edit requires an interactive terminal (TTY). Use a terminal or SSH with -t.');
352
349
  }
353
350
  const resolvedPath = resolveValidateInputPath(opts.fileOrKey.trim());
354
- const doc = JSON.parse(fs.readFileSync(resolvedPath, 'utf8'));
351
+ const doc = readDatasourceConfigFile(resolvedPath);
355
352
  const { capKey, section, profileKey } = await resolveEditTargets(doc, opts);
356
353
  const initial = getEditableJson(doc, capKey, section, profileKey);
357
354
  const body = await promptEditorJson(initial);
@@ -6,14 +6,13 @@
6
6
  * @version 2.0.0
7
7
  */
8
8
 
9
- const fs = require('fs');
10
9
  const {
11
10
  resolveValidateInputPath,
12
11
  validateDatasourceParsed
13
12
  } = require('../validate');
14
13
  const { applyCapabilityRelate } = require('./relate-operations');
15
14
  const { validateRelateSemantics } = require('./relate-validate');
16
- const { writeBackup, atomicWriteJson } = require('./run-capability-copy');
15
+ const { writeBackup, atomicWriteJson, readDatasourceConfigFile } = require('./run-capability-copy');
17
16
  const { tryResolveDatasourceKeyToLocalPath, readJsonFile } = require('../../resolvers/datasource-resolver');
18
17
  const { tryFetchDatasourceConfig } = require('../../resolvers/manifest-resolver');
19
18
 
@@ -134,8 +133,7 @@ function applyRelateAndValidateSchema(parsed, opts, semanticWarnings, remoteVali
134
133
  */
135
134
  async function runCapabilityRelate(opts) {
136
135
  const resolvedPath = resolveValidateInputPath(opts.fileOrKey.trim());
137
- const raw = fs.readFileSync(resolvedPath, 'utf8');
138
- const parsed = JSON.parse(raw);
136
+ const parsed = readDatasourceConfigFile(resolvedPath);
139
137
 
140
138
  const targetDocLocal = loadTargetDocLocal(opts.targetDatasource);
141
139
  const systemKeyForAuth = resolveSystemKeyForAuth(parsed);
@@ -6,14 +6,13 @@
6
6
  * @version 2.0.0
7
7
  */
8
8
 
9
- const fs = require('fs');
10
9
  const {
11
10
  resolveValidateInputPath,
12
11
  validateDatasourceParsed
13
12
  } = require('../validate');
14
13
  const { normalizeCapabilityKey } = require('./capability-key');
15
14
  const { applyCapabilityRemove } = require('./remove-operations');
16
- const { writeBackup, atomicWriteJson } = require('./run-capability-copy');
15
+ const { writeBackup, atomicWriteJson, readDatasourceConfigFile } = require('./run-capability-copy');
17
16
 
18
17
  /**
19
18
  * @param {{ valid: boolean, errors: string[] }} validation
@@ -67,8 +66,7 @@ function makeRemoveResult(resolvedPath, capability, result, validation, dryRun,
67
66
  */
68
67
  async function runCapabilityRemove(opts) {
69
68
  const resolvedPath = resolveValidateInputPath(opts.fileOrKey.trim());
70
- const raw = fs.readFileSync(resolvedPath, 'utf8');
71
- const parsed = JSON.parse(raw);
69
+ const parsed = readDatasourceConfigFile(resolvedPath);
72
70
 
73
71
  const capability = normalizeCapabilityKey(opts.capability, 'Capability (--capability)');
74
72
 
@@ -7,6 +7,7 @@
7
7
  */
8
8
 
9
9
  const { normalizeCapabilityKey } = require('./capability-key');
10
+ const { capabilitiesIncludes } = require('./capability-manifest');
10
11
 
11
12
  /**
12
13
  * Lists structural locations where a capability key should appear.
@@ -18,7 +19,7 @@ const { normalizeCapabilityKey } = require('./capability-key');
18
19
  function checkCapabilitySlices(parsed, rawKey) {
19
20
  const key = normalizeCapabilityKey(rawKey, 'capability');
20
21
  const missing = [];
21
- if (!Array.isArray(parsed.capabilities) || !parsed.capabilities.includes(key)) {
22
+ if (!capabilitiesIncludes(parsed.capabilities, key)) {
22
23
  missing.push(`capabilities[] (missing "${key}")`);
23
24
  }
24
25
  if (!parsed.openapi?.operations?.[key]) {
@@ -38,7 +38,8 @@ function datasourceIdentifierMatchesFile(identifier, fileRef, parsed) {
38
38
  if (stem === id) {
39
39
  return true;
40
40
  }
41
- if (`${stem}.json` === id.toLowerCase()) {
41
+ const lowerId = id.toLowerCase();
42
+ if (`${stem}.json` === lowerId || `${stem}.yaml` === lowerId || `${stem}.yml` === lowerId) {
42
43
  return true;
43
44
  }
44
45
  return false;
@@ -8,6 +8,7 @@
8
8
 
9
9
  const { getConfig } = require('../core/config');
10
10
  const { setupIntegrationTestAuth } = require('../external-system/test-auth');
11
+ const { applyLabDataplaneApiKeyBearer } = require('../utils/token-manager');
11
12
  const { resolveAppKeyForDatasource } = require('./resolve-app');
12
13
  const { getSystemKeyFromAppKey } = require('./integration-context');
13
14
  const { loadDatasourceForApp } = require('./unified-validation-run-resolve');
@@ -62,6 +63,8 @@ async function resolveLoadExportContext(datasourceKey, options = {}) {
62
63
  dataplaneUrl = auth.dataplaneUrl;
63
64
  }
64
65
 
66
+ authConfig = applyLabDataplaneApiKeyBearer(authConfig);
67
+
65
68
  return {
66
69
  appKey,
67
70
  systemKey,
@@ -30,7 +30,7 @@ function logHeaderAndIdentity(result, trimmed, showMapping) {
30
30
  const { resolvedPath, summary } = result;
31
31
  logger.log('');
32
32
  logger.log(sectionTitle('Datasource validation'));
33
- logger.log(metadata('Offline — JSON schema and integration wiring'));
33
+ logger.log(metadata('Offline — YAML/JSON schema and integration wiring'));
34
34
  logger.log('');
35
35
  if (summary) {
36
36
  logger.log(` ${headerKeyValue('Key:', summary.key)}`);
@@ -10,6 +10,8 @@
10
10
  * @version 2.0.0
11
11
  */
12
12
 
13
+ const { validateOrphanExposedProfiles } = require('./orphan-profiles-validator');
14
+
13
15
  /**
14
16
  * Set of attribute names plus root dimension keys valid for field references.
15
17
  * Used for primaryKey (schema allows dimension keys or attributes) and other paths (attributes only).
@@ -40,16 +42,34 @@ function checkPrimaryKey(parsed, attributesAndDimensions, errors) {
40
42
  });
41
43
  }
42
44
 
45
+ /** @returns {Set<string>} */
46
+ function profileReferenceSet(parsed) {
47
+ if (parsed?.entityType === 'serviceContract') {
48
+ const schema = parsed?.exposed?.schema;
49
+ if (schema && typeof schema === 'object' && !Array.isArray(schema)) {
50
+ return new Set(
51
+ Object.keys(schema).filter(key => typeof key === 'string' && key !== '')
52
+ );
53
+ }
54
+ }
55
+ return new Set(Object.keys(parsed?.fieldMappings?.attributes ?? {}));
56
+ }
57
+
43
58
  /** @param {string[]} errors */
44
- function checkExposedProfiles(parsed, attrSet, errors) {
59
+ function checkExposedProfiles(parsed, _attrSet, errors) {
45
60
  const profiles = parsed?.exposed?.profiles;
46
61
  if (!profiles || typeof profiles !== 'object' || Array.isArray(profiles)) return;
62
+ const profileRefSet = profileReferenceSet(parsed);
63
+ const referenceLabel =
64
+ parsed?.entityType === 'serviceContract'
65
+ ? 'exposed.schema'
66
+ : 'fieldMappings.attributes';
47
67
  Object.entries(profiles).forEach(([profileName, fields]) => {
48
68
  if (!Array.isArray(fields)) return;
49
69
  fields.forEach((field, idx) => {
50
- if (typeof field === 'string' && !attrSet.has(field)) {
70
+ if (typeof field === 'string' && !profileRefSet.has(field)) {
51
71
  errors.push(
52
- `exposed.profiles.${profileName}[${idx}]: field '${field}' does not exist in fieldMappings.attributes. Add the attribute or remove the reference.`
72
+ `exposed.profiles.${profileName}[${idx}]: field '${field}' does not exist in ${referenceLabel}. Add the attribute or remove the reference.`
53
73
  );
54
74
  }
55
75
  });
@@ -121,6 +141,7 @@ function validateFieldReferences(parsed) {
121
141
 
122
142
  checkPrimaryKey(parsed, attributesAndDimensions, errors);
123
143
  checkExposedProfiles(parsed, attrSet, errors);
144
+ errors.push(...validateOrphanExposedProfiles(parsed));
124
145
  if (normalizedAttributes.length === 0) return errors;
125
146
 
126
147
  checkIndexingAndValidation(parsed, normalizedAttributes, errors);
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Remove saved datasource test debug JSON under integration/<app>/logs/.
3
- * @fileoverview Local cleanup for test / test-integration / test-e2e / test-trust logs
3
+ * @fileoverview Local cleanup for test / test-integration / test-e2e / verify-trust logs
4
4
  * @author AI Fabrix Team
5
5
  * @version 1.0.0
6
6
  */
@@ -42,7 +42,7 @@ function matchesLogCleanType(fileName, type) {
42
42
  return fileName.startsWith('test-integration-');
43
43
  }
44
44
  if (type === 'e2e') return fileName.startsWith('test-e2e-');
45
- if (type === 'trust') return fileName.startsWith('test-trust-');
45
+ if (type === 'trust') return fileName.startsWith('verify-trust-');
46
46
  return false;
47
47
  }
48
48
 
@@ -59,7 +59,7 @@ function isStructuralTestLogFileName(name) {
59
59
  if (
60
60
  name.startsWith('test-e2e-') ||
61
61
  name.startsWith('test-integration-') ||
62
- name.startsWith('test-trust-')
62
+ name.startsWith('verify-trust-')
63
63
  ) {
64
64
  return false;
65
65
  }
@@ -276,7 +276,7 @@ function logTrustFindingsSection(run) {
276
276
  }
277
277
 
278
278
  /**
279
- * Format agent trust log (`datasource test-trust --debug` → `test-trust-*.json`).
279
+ * Format agent trust log (`datasource verify-trust --debug` → `verify-trust-*.json`).
280
280
  * @param {Object} data - Parsed JSON { request, response?, error? }
281
281
  * @param {string} [fileName] - Log file name for header
282
282
  */
@@ -356,7 +356,7 @@ function formatStructuralTestLog(data, fileName) {
356
356
  /**
357
357
  * Format log content by type
358
358
  * @param {Object} parsed - Parsed JSON log
359
- * @param {'test'|'test-e2e'|'test-integration'|'test-trust'} logType - Log type
359
+ * @param {'test'|'test-e2e'|'test-integration'|'verify-trust'} logType - Log type
360
360
  * @param {string} [fileName] - File name for header
361
361
  */
362
362
  function formatLogContent(parsed, logType, fileName) {
@@ -364,7 +364,7 @@ function formatLogContent(parsed, logType, fileName) {
364
364
  formatStructuralTestLog(parsed, fileName);
365
365
  return;
366
366
  }
367
- if (logType === 'test-trust') {
367
+ if (logType === 'verify-trust') {
368
368
  formatTrustLog(parsed, fileName);
369
369
  return;
370
370
  }
@@ -410,7 +410,7 @@ function parseDatasourceLogJson(content, logPath) {
410
410
  * @param {Object} options - Options
411
411
  * @param {string} [options.app] - App key (optional, resolved from key if omitted)
412
412
  * @param {string} [options.file] - Path to log file (overrides app resolution)
413
- * @param {'test'|'test-e2e'|'test-integration'|'test-trust'} options.logType - Log type
413
+ * @param {'test'|'test-e2e'|'test-integration'|'verify-trust'} options.logType - Log type
414
414
  * @throws {Error} When file not found or invalid JSON
415
415
  */
416
416
  /* eslint-disable-next-line max-statements -- Resolve path, read, parse, format */
@@ -433,11 +433,11 @@ async function runLogViewer(datasourceKey, options) {
433
433
  `No structural validation log found in ${logsDir}. Run: aifabrix datasource test <key> --debug`
434
434
  );
435
435
  }
436
- } else if (logType === 'test-trust') {
437
- logPath = await getLatestLogPath(logsDir, 'test-trust-');
436
+ } else if (logType === 'verify-trust') {
437
+ logPath = await getLatestLogPath(logsDir, 'verify-trust-');
438
438
  if (!logPath) {
439
439
  throw new Error(
440
- `No test-trust log found in ${logsDir}. Run: aifabrix datasource test-trust <key> --debug`
440
+ `No verify-trust log found in ${logsDir}. Run: aifabrix datasource verify-trust <key> --debug`
441
441
  );
442
442
  }
443
443
  } else {
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Validate exposed.profiles keys against capabilities (346 §13 — no orphan profiles).
3
+ *
4
+ * @fileoverview Orphan exposed profile validation for datasource manifests
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const { listCapabilityKeys } = require('./capability/capability-manifest');
12
+
13
+ const FORBIDDEN_ORPHAN_PROFILE_KEYS = new Set(['minimal', 'analytics', 'metadata']);
14
+
15
+ /**
16
+ * @param {string} name
17
+ * @returns {string}
18
+ */
19
+ function normalizeProfileKey(name) {
20
+ return String(name).trim().toLowerCase();
21
+ }
22
+
23
+ /**
24
+ * @param {object} parsed
25
+ * @returns {Set<string>}
26
+ */
27
+ function operationKeysFromConfig(parsed) {
28
+ const keys = new Set();
29
+ const openapiOps = parsed?.openapi?.operations;
30
+ if (openapiOps && typeof openapiOps === 'object') {
31
+ Object.keys(openapiOps).forEach((k) => keys.add(normalizeProfileKey(k)));
32
+ }
33
+ const cipOps = parsed?.execution?.cip?.operations;
34
+ if (cipOps && typeof cipOps === 'object') {
35
+ Object.keys(cipOps).forEach((k) => keys.add(normalizeProfileKey(k)));
36
+ }
37
+ return keys;
38
+ }
39
+
40
+ /**
41
+ * @param {object} parsed
42
+ * @returns {Set<string>}
43
+ */
44
+ function allowedExposedProfileKeys(parsed) {
45
+ const allowed = new Set(['default']);
46
+ const capabilityKeys = listCapabilityKeys(parsed?.capabilities).map(normalizeProfileKey);
47
+ if (capabilityKeys.length > 0) {
48
+ capabilityKeys.forEach((k) => allowed.add(k));
49
+ } else {
50
+ operationKeysFromConfig(parsed).forEach((k) => allowed.add(k));
51
+ }
52
+ return allowed;
53
+ }
54
+
55
+ /**
56
+ * @param {object} parsed - Parsed datasource manifest
57
+ * @returns {string[]} Error messages; empty when valid
58
+ */
59
+ function validateOrphanExposedProfiles(parsed) {
60
+ const errors = [];
61
+ const profiles = parsed?.exposed?.profiles;
62
+ if (!profiles || typeof profiles !== 'object' || Array.isArray(profiles)) {
63
+ return errors;
64
+ }
65
+
66
+ const allowed = allowedExposedProfileKeys(parsed);
67
+ const orphans = Object.keys(profiles).filter((name) => {
68
+ const normalized = normalizeProfileKey(name);
69
+ return FORBIDDEN_ORPHAN_PROFILE_KEYS.has(normalized) || !allowed.has(normalized);
70
+ });
71
+
72
+ if (orphans.length === 0) {
73
+ return errors;
74
+ }
75
+
76
+ const decorative = orphans.filter((name) =>
77
+ FORBIDDEN_ORPHAN_PROFILE_KEYS.has(normalizeProfileKey(name))
78
+ );
79
+ if (decorative.length > 0) {
80
+ errors.push(
81
+ `exposed.profiles: orphan exposed profiles are forbidden: ${decorative.join(', ')}. ` +
82
+ 'Use exposed.profiles.default and one profile per capabilities[].key only.'
83
+ );
84
+ return errors;
85
+ }
86
+
87
+ errors.push(
88
+ `exposed.profiles: orphan profile keys must match capabilities[].key or default: ${orphans.join(', ')}. ` +
89
+ `Allowed profile keys: ${[...allowed].sort().join(', ')}.`
90
+ );
91
+ return errors;
92
+ }
93
+
94
+ module.exports = {
95
+ FORBIDDEN_ORPHAN_PROFILE_KEYS,
96
+ allowedExposedProfileKeys,
97
+ validateOrphanExposedProfiles
98
+ };
@@ -42,8 +42,11 @@ function buildUnifiedE2eRunOptions(options, timeoutMs, pk) {
42
42
  capabilityKey: options.capabilityKey,
43
43
  timeout: timeoutMs,
44
44
  sync: options.sync === true,
45
+ force: options.force === true,
45
46
  authConfig: options.authConfig,
46
- dataplaneUrl: options.dataplaneUrl || options.dataplane
47
+ dataplaneUrl: options.dataplaneUrl || options.dataplane,
48
+ quietPollUi: options.quietPollUi === true,
49
+ onPollProgress: options.onPollProgress
47
50
  };
48
51
  }
49
52
 
@@ -10,6 +10,7 @@ const {
10
10
  includeDebugForRequest
11
11
  } = require('../utils/validation-run-request');
12
12
  const testHelpers = require('../utils/external-system-test-helpers');
13
+ const { withStageOnValidationRunBody } = require('../utils/validation-run-stage');
13
14
 
14
15
  /**
15
16
  * @param {Object} params
@@ -52,7 +53,7 @@ async function buildUnifiedValidationBody(params) {
52
53
  })
53
54
  : undefined;
54
55
 
55
- return buildExternalDataSourceValidationRequest({
56
+ const body = buildExternalDataSourceValidationRequest({
56
57
  systemKey,
57
58
  datasourceKey,
58
59
  runType,
@@ -62,6 +63,7 @@ async function buildUnifiedValidationBody(params) {
62
63
  explain: options.verbose === true,
63
64
  e2eOptions: e2eOptions && Object.keys(e2eOptions).length > 0 ? e2eOptions : undefined
64
65
  });
66
+ return withStageOnValidationRunBody(body, runType);
65
67
  }
66
68
 
67
69
  module.exports = { buildUnifiedValidationBody };
@@ -18,6 +18,7 @@ const { buildUnifiedValidationBody } = require('./unified-validation-run-body');
18
18
  const { postValidationRunAndOptionalPoll } = require('./unified-validation-run-post');
19
19
  const { requireBearerForDataplanePipeline } = require('../utils/token-manager');
20
20
  const logger = require('../utils/logger');
21
+ const { buildMinimalUploadSyncOptions } = require('../utils/upload-sync-options');
21
22
 
22
23
  function _resourceTypeFromDatasource(datasource) {
23
24
  return datasource && typeof datasource === 'object' && typeof datasource.resourceType === 'string'
@@ -59,7 +60,7 @@ async function maybeSyncDatasourceToDataplane({ options, authConfig, systemKey }
59
60
  // are updated before validation runs. Datasource-only publish can still fail DP-SEC-013 when the
60
61
  // dataplane system permissions[] are stale.
61
62
  const { uploadExternalSystem } = require('../commands/upload');
62
- await uploadExternalSystem(systemKey, { minimal: true });
63
+ await uploadExternalSystem(systemKey, buildMinimalUploadSyncOptions(options));
63
64
  logger.log(formatSuccessLine('Sync complete'));
64
65
  }
65
66
 
@@ -139,7 +140,9 @@ async function runUnifiedDatasourceValidation(datasourceKey, options) {
139
140
  useAsync,
140
141
  noAsync: options.noAsync === true || options.async === false,
141
142
  verbosePoll: options.verbose === true,
142
- pollSubject: datasourceKey
143
+ quietPollUi: options.quietPollUi === true,
144
+ pollSubject: datasourceKey,
145
+ onPollProgress: options.onPollProgress
143
146
  });
144
147
 
145
148
  if (result && result.envelope) {