@aifabrix/builder 2.45.0 → 2.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (352) hide show
  1. package/.cursor/rules/cli-layout.mdc +2 -0
  2. package/.cursor/rules/cli-product-neutral.mdc +43 -0
  3. package/.cursor/rules/docs-rules.mdc +3 -1
  4. package/.cursor/rules/project-rules.mdc +1 -0
  5. package/README.md +43 -17
  6. package/integration/hubspot-test/wizard-hubspot-e2e.yaml +1 -1
  7. package/jest.config.default.js +2 -1
  8. package/jest.config.isolated.js +2 -1
  9. package/jest.global-live-fabrix-hooks.js +36 -0
  10. package/jest.isolated-projects.js +130 -0
  11. package/jest.projects.js +69 -121
  12. package/lib/api/agent-metadata-validation.api.js +93 -0
  13. package/lib/api/api-response-errors.js +124 -0
  14. package/lib/api/audit-api-helpers.js +68 -0
  15. package/lib/api/audit.api.js +119 -0
  16. package/lib/api/auth-cache.api.js +44 -0
  17. package/lib/api/certificates.api.js +4 -4
  18. package/lib/api/credential.api.js +2 -2
  19. package/lib/api/dataplane-health.api.js +137 -0
  20. package/lib/api/dataplane-sync.api.js +27 -0
  21. package/lib/api/datasources-core.api.js +21 -18
  22. package/lib/api/datasources-extended.api.js +22 -22
  23. package/lib/api/dimensions.api.js +3 -0
  24. package/lib/api/external-systems.api.js +13 -13
  25. package/lib/api/governance-scenario-pack.api.js +159 -0
  26. package/lib/api/governance-scenarios.api.js +39 -0
  27. package/lib/api/groups.api.js +79 -0
  28. package/lib/api/index.js +88 -5
  29. package/lib/api/lifecycle.api.js +77 -0
  30. package/lib/api/pipeline.api.js +7 -5
  31. package/lib/api/protection.api.js +157 -0
  32. package/lib/api/records-bulk.api.js +43 -0
  33. package/lib/api/records-search-parse.js +49 -0
  34. package/lib/api/records-search.api.js +29 -0
  35. package/lib/api/types/agent-metadata-validation.types.js +67 -0
  36. package/lib/api/types/audit.types.js +72 -0
  37. package/lib/api/types/dataplane-health.types.js +27 -0
  38. package/lib/api/types/dimensions.types.js +2 -0
  39. package/lib/api/types/governance-scenarios.types.js +39 -0
  40. package/lib/api/types/protection.types.js +69 -0
  41. package/lib/api/types/records-bulk.types.js +35 -0
  42. package/lib/api/types/records-search.types.js +28 -0
  43. package/lib/api/user-groups.api.js +50 -0
  44. package/lib/api/users.api.js +95 -0
  45. package/lib/api/validation-run.api.js +3 -3
  46. package/lib/api/validation-runner.js +5 -3
  47. package/lib/api/wizard-platform.api.js +3 -3
  48. package/lib/api/wizard.api.js +21 -21
  49. package/lib/app/deploy-config.js +4 -1
  50. package/lib/app/deploy.js +34 -19
  51. package/lib/app/down.js +20 -1
  52. package/lib/app/push.js +4 -5
  53. package/lib/app/register.js +7 -4
  54. package/lib/app/run-env-compose.js +84 -30
  55. package/lib/build/index.js +5 -0
  56. package/lib/certification/sync-system-certification.js +13 -6
  57. package/lib/cli/index.js +8 -2
  58. package/lib/cli/infra-guided-auth.js +109 -0
  59. package/lib/cli/infra-guided.js +91 -69
  60. package/lib/cli/setup-app.help.js +19 -2
  61. package/lib/cli/setup-app.js +58 -23
  62. package/lib/cli/setup-app.test-commands.js +28 -21
  63. package/lib/cli/setup-auth.js +55 -3
  64. package/lib/cli/setup-certification-commands.js +147 -0
  65. package/lib/cli/setup-certification.help.js +141 -0
  66. package/lib/cli/setup-environment.js +19 -2
  67. package/lib/cli/setup-external-system-help.js +62 -0
  68. package/lib/cli/setup-external-system.js +62 -6
  69. package/lib/cli/setup-infra.js +9 -1
  70. package/lib/cli/setup-platform.js +6 -1
  71. package/lib/cli/setup-secrets.js +33 -1
  72. package/lib/cli/setup-utility-help-after.js +65 -0
  73. package/lib/cli/setup-utility-repair.js +198 -0
  74. package/lib/cli/setup-utility-resolve.js +42 -6
  75. package/lib/cli/setup-utility-validate.js +197 -0
  76. package/lib/cli/setup-utility.js +41 -258
  77. package/lib/commands/auth-status-client-tokens.js +214 -0
  78. package/lib/commands/auth-status-dataplane-version.js +269 -0
  79. package/lib/commands/auth-status-display.js +94 -0
  80. package/lib/commands/auth-status.js +111 -53
  81. package/lib/commands/credential-push.js +10 -5
  82. package/lib/commands/datasource-load-export-cli.js +178 -0
  83. package/lib/commands/datasource-test-trust-cli.js +118 -0
  84. package/lib/commands/datasource-unified-test-cli.js +31 -20
  85. package/lib/commands/datasource-unified-test-cli.options.js +22 -3
  86. package/lib/commands/datasource-unified-test-e2e-cli-helpers.js +5 -5
  87. package/lib/commands/datasource-verify-audit-cli.js +96 -0
  88. package/lib/commands/datasource.js +68 -1
  89. package/lib/commands/dev-show-display.js +8 -1
  90. package/lib/commands/dimension-value.js +43 -13
  91. package/lib/commands/dimension.js +38 -7
  92. package/lib/commands/governance-cli-shared.js +94 -0
  93. package/lib/commands/governance-command-action.js +132 -0
  94. package/lib/commands/governance-download-external.js +34 -0
  95. package/lib/commands/governance-generate-external.js +71 -0
  96. package/lib/commands/governance-upload-external.js +36 -0
  97. package/lib/commands/governance-verify-external.js +64 -0
  98. package/lib/commands/governance.js +144 -0
  99. package/lib/commands/identity-apply-sync.js +131 -0
  100. package/lib/commands/identity-group-cli.js +146 -0
  101. package/lib/commands/identity-membership-role-cache.js +175 -0
  102. package/lib/commands/identity-shared.js +94 -0
  103. package/lib/commands/identity-user-cli.js +158 -0
  104. package/lib/commands/identity.js +43 -0
  105. package/lib/commands/lifecycle-command-action.js +123 -0
  106. package/lib/commands/lifecycle-external.js +268 -0
  107. package/lib/commands/login.js +56 -17
  108. package/lib/commands/protection-cli-leaves.js +286 -0
  109. package/lib/commands/protection.js +50 -0
  110. package/lib/commands/repair-auth-apply.js +127 -0
  111. package/lib/commands/repair-changed-files.js +41 -0
  112. package/lib/commands/repair-datasource-keys.js +4 -1
  113. package/lib/commands/repair-datasource-run.js +59 -0
  114. package/lib/commands/repair-datasource-test-payload.js +259 -0
  115. package/lib/commands/repair-datasource.js +1 -51
  116. package/lib/commands/repair-env-template.js +64 -13
  117. package/lib/commands/repair-external-run.js +216 -0
  118. package/lib/commands/repair-openapi-sync.js +23 -0
  119. package/lib/commands/repair-persist.js +4 -0
  120. package/lib/commands/repair-rbac.js +52 -1
  121. package/lib/commands/repair-steps.js +145 -0
  122. package/lib/commands/repair.js +29 -286
  123. package/lib/commands/secrets-get.js +184 -0
  124. package/lib/commands/secrets-remove-all.js +3 -1
  125. package/lib/commands/setup-image-refresh.js +146 -0
  126. package/lib/commands/setup-modes.js +158 -162
  127. package/lib/commands/setup-platform-auth.js +76 -0
  128. package/lib/commands/setup-prompts-admin.js +244 -0
  129. package/lib/commands/setup-prompts-platform-mode.js +67 -0
  130. package/lib/commands/setup-prompts-validators.js +36 -0
  131. package/lib/commands/setup-prompts.js +24 -76
  132. package/lib/commands/setup-run-context.js +45 -0
  133. package/lib/commands/setup-spinners.js +39 -0
  134. package/lib/commands/setup.js +27 -5
  135. package/lib/commands/teardown.js +39 -0
  136. package/lib/commands/test-e2e-external.js +61 -14
  137. package/lib/commands/test-governance-cli-options.js +47 -0
  138. package/lib/commands/test-governance-external.js +67 -0
  139. package/lib/commands/test-trust-cli-options.js +32 -0
  140. package/lib/commands/test-trust-external.js +126 -0
  141. package/lib/commands/up-common.js +25 -13
  142. package/lib/commands/up-dataplane.js +50 -13
  143. package/lib/commands/upload-publish-context.js +75 -0
  144. package/lib/commands/upload-sidecar-followups.js +89 -0
  145. package/lib/commands/upload.js +108 -105
  146. package/lib/commands/verify-governance-combined-external.js +61 -0
  147. package/lib/commands/verify-governance-command-action.js +64 -0
  148. package/lib/commands/verify-governance-db.js +102 -0
  149. package/lib/commands/verify-governance-external.js +77 -0
  150. package/lib/commands/verify-governance-result-builders.js +71 -0
  151. package/lib/commands/verify-operations-command-action.js +68 -0
  152. package/lib/commands/verify-operations-external.js +268 -0
  153. package/lib/commands/verify-operations-persist.js +75 -0
  154. package/lib/commands/verify-operations-step-plan.js +68 -0
  155. package/lib/commands/verify-operations-steps.js +111 -0
  156. package/lib/commands/verify-trust-command-action.js +70 -0
  157. package/lib/commands/verify-trust-external.js +67 -0
  158. package/lib/commands/wizard-config-normalizer.js +43 -23
  159. package/lib/commands/wizard-core.js +5 -0
  160. package/lib/core/admin-password-generator.js +38 -0
  161. package/lib/core/admin-secrets-bundle.js +111 -0
  162. package/lib/core/admin-secrets-env-overlay.js +62 -0
  163. package/lib/core/admin-secrets.js +32 -4
  164. package/lib/core/config-attach-extensions.js +3 -0
  165. package/lib/core/config-device-dataplane.js +185 -0
  166. package/lib/core/config-platform-controller.js +44 -0
  167. package/lib/core/config-setup-installation-profile.js +42 -0
  168. package/lib/core/config-setup-platform-mode.js +46 -0
  169. package/lib/core/config.js +46 -36
  170. package/lib/core/secrets-admin-env.js +6 -2
  171. package/lib/core/secrets-ensure.js +4 -0
  172. package/lib/core/secrets-env-content.js +54 -48
  173. package/lib/core/secrets-env-write.js +10 -1
  174. package/lib/core/secrets-infra-placeholder-sync.js +2 -0
  175. package/lib/core/setup-installation-profile.js +43 -0
  176. package/lib/core/setup-platform-mode.js +55 -0
  177. package/lib/datasource/agent-trust-debug-log.js +45 -0
  178. package/lib/datasource/agent-trust-fetch.js +115 -0
  179. package/lib/datasource/agent-trust-map.js +101 -0
  180. package/lib/datasource/agent-trust-mock.js +44 -0
  181. package/lib/datasource/agent-trust-run.js +95 -0
  182. package/lib/datasource/agent-trust-timeout.js +25 -0
  183. package/lib/datasource/audit-evidence-display.js +80 -0
  184. package/lib/datasource/audit-evidence-extract-debug.js +115 -0
  185. package/lib/datasource/audit-evidence-extract.js +180 -0
  186. package/lib/datasource/audit-evidence-matrix-rows.js +158 -0
  187. package/lib/datasource/audit-evidence-operation-aliases.js +63 -0
  188. package/lib/datasource/audit-evidence-poll.js +109 -0
  189. package/lib/datasource/audit-evidence-run.js +177 -0
  190. package/lib/datasource/audit-evidence-verify-helpers.js +167 -0
  191. package/lib/datasource/audit-evidence-verify-matrix.js +205 -0
  192. package/lib/datasource/audit-evidence-verify.js +108 -0
  193. package/lib/datasource/bulk-loader-run-batches.js +100 -0
  194. package/lib/datasource/bulk-loader-service-retry.js +52 -0
  195. package/lib/datasource/bulk-loader-service.js +127 -0
  196. package/lib/datasource/capability/run-capability-dimension.js +2 -1
  197. package/lib/datasource/datasource-exporter-resolve.js +82 -0
  198. package/lib/datasource/datasource-exporter-service.js +144 -0
  199. package/lib/datasource/datasource-identifier.js +148 -0
  200. package/lib/datasource/datasource-load-export-context.js +95 -0
  201. package/lib/datasource/integration-context.js +6 -4
  202. package/lib/datasource/local-data-paths.js +145 -0
  203. package/lib/datasource/log-cleaner.js +241 -0
  204. package/lib/datasource/log-viewer.js +111 -6
  205. package/lib/datasource/record-file-parser.js +85 -0
  206. package/lib/datasource/record-mapper.js +129 -0
  207. package/lib/datasource/resolve-app.js +74 -55
  208. package/lib/datasource/test-e2e.js +29 -2
  209. package/lib/datasource/unified-validation-run-body.js +3 -1
  210. package/lib/datasource/unified-validation-run-resolve.js +45 -12
  211. package/lib/datasource/unified-validation-run.js +47 -18
  212. package/lib/datasource/validate.js +37 -20
  213. package/lib/deployment/environment-poll-status.js +138 -0
  214. package/lib/deployment/environment.js +42 -34
  215. package/lib/external-system/download.js +21 -20
  216. package/lib/external-system/generator.js +5 -1
  217. package/lib/external-system/integration-auth-context.js +45 -0
  218. package/lib/external-system/test-auth.js +12 -5
  219. package/lib/external-system/test-system-level.js +25 -4
  220. package/lib/external-system/test.js +9 -7
  221. package/lib/generator/external-controller-manifest.js +15 -0
  222. package/lib/governance/governance-cli-errors.js +96 -0
  223. package/lib/governance/governance-download-display.js +38 -0
  224. package/lib/governance/governance-pack-loader.js +70 -0
  225. package/lib/governance/governance-run-display.js +309 -0
  226. package/lib/identity/identity-apply-core.js +108 -0
  227. package/lib/identity/identity-apply-phases.js +244 -0
  228. package/lib/identity/identity-apply-service.js +77 -0
  229. package/lib/identity/identity-csv-parser.js +114 -0
  230. package/lib/infrastructure/admin-secrets-apply.js +84 -0
  231. package/lib/infrastructure/admin-secrets-ensure.js +130 -0
  232. package/lib/infrastructure/admin-secrets-resolve.js +95 -0
  233. package/lib/infrastructure/admin-secrets-sync.js +91 -0
  234. package/lib/infrastructure/helpers.js +23 -129
  235. package/lib/infrastructure/index.js +5 -6
  236. package/lib/infrastructure/orphan-infra-docker-teardown.js +11 -5
  237. package/lib/internal/fs-real-sync.js +29 -1
  238. package/lib/lifecycle/certification-progress.js +231 -0
  239. package/lib/lifecycle/dataplane-ui-url.js +145 -0
  240. package/lib/lifecycle/exit-codes.js +24 -0
  241. package/lib/lifecycle/json-envelope.js +25 -0
  242. package/lib/lifecycle/lifecycle-governance-options.js +51 -0
  243. package/lib/lifecycle/logger-quiet.js +29 -0
  244. package/lib/lifecycle/open-api-published.js +59 -0
  245. package/lib/lifecycle/operations-readiness-metrics.js +101 -0
  246. package/lib/lifecycle/product-model.js +196 -0
  247. package/lib/lifecycle/report-display.js +471 -0
  248. package/lib/lifecycle/scenario-upload.js +191 -0
  249. package/lib/lifecycle/verify-step-progress.js +87 -0
  250. package/lib/parameters/infra-kv-discovery.js +27 -2
  251. package/lib/protection/auth-context.js +51 -0
  252. package/lib/protection/convert-batch.js +90 -0
  253. package/lib/protection/load.js +41 -0
  254. package/lib/protection/paths.js +158 -0
  255. package/lib/protection/preflight-datasource-ready.js +46 -0
  256. package/lib/protection/protection-create-probe-lines.js +142 -0
  257. package/lib/protection/protection-create-probes.js +95 -0
  258. package/lib/protection/protection-create-scaffold.js +281 -0
  259. package/lib/protection/protection-display-helpers.js +445 -0
  260. package/lib/protection/protection-display.js +215 -0
  261. package/lib/protection/protection-preset-registry.js +97 -0
  262. package/lib/protection/report-exit.js +62 -0
  263. package/lib/protection/resolve.js +202 -0
  264. package/lib/protection/run-commands-validate.js +130 -0
  265. package/lib/protection/run-commands.js +216 -0
  266. package/lib/protection/run-protection-create-helpers.js +134 -0
  267. package/lib/protection/run-protection-create-probes-flow.js +43 -0
  268. package/lib/protection/run-protection-create.js +191 -0
  269. package/lib/protection/scope.js +22 -0
  270. package/lib/protection/sync-after-upload.js +64 -0
  271. package/lib/protection/upload-batch.js +127 -0
  272. package/lib/protection/validate-batch.js +113 -0
  273. package/lib/protection/validate-local.js +65 -0
  274. package/lib/resolvers/dimension-file.js +29 -4
  275. package/lib/schema/application-schema.json +1 -1
  276. package/lib/schema/datasource-test-run.schema.json +89 -6
  277. package/lib/schema/external-datasource.schema.json +2636 -2588
  278. package/lib/schema/external-system.schema.json +1089 -761
  279. package/lib/schema/flag-map-validation-run.json +2 -2
  280. package/lib/schema/infra.parameter.yaml +45 -0
  281. package/lib/schema/protection.schema.json +374 -0
  282. package/lib/schema/type/credential-field-registry.json +642 -0
  283. package/lib/schema/wizard-config.schema.json +1 -1
  284. package/lib/utils/agent-trust-run-display.js +231 -0
  285. package/lib/utils/agent-trust-run-exit.js +59 -0
  286. package/lib/utils/agent-trust-wait-ui.js +94 -0
  287. package/lib/utils/aifabrix-test-runtime-guard.js +125 -0
  288. package/lib/utils/api.js +55 -31
  289. package/lib/utils/app-relative-path-env.js +112 -0
  290. package/lib/utils/cli-exit-codes.js +30 -0
  291. package/lib/utils/cli-secrets-error-format.js +83 -21
  292. package/lib/utils/cli-sync-options.js +33 -0
  293. package/lib/utils/cli-utils.js +16 -4
  294. package/lib/utils/compose-generate-docker-compose.js +4 -0
  295. package/lib/utils/compose-traefik-ingress-base.js +16 -1
  296. package/lib/utils/config-secrets-path.js +46 -0
  297. package/lib/utils/controller-url.js +88 -1
  298. package/lib/utils/credential-push-ui.js +90 -0
  299. package/lib/utils/credential-secrets-env.js +137 -9
  300. package/lib/utils/dataplane-cli-version-gate.js +202 -0
  301. package/lib/utils/dataplane-cli-version-help.js +74 -0
  302. package/lib/utils/dataplane-resolver.js +129 -2
  303. package/lib/utils/datasource-export-display.js +137 -0
  304. package/lib/utils/datasource-load-display.js +174 -0
  305. package/lib/utils/datasource-load-export-ui.js +120 -0
  306. package/lib/utils/datasource-test-run-capability-scope.js +3 -3
  307. package/lib/utils/datasource-test-run-display.js +3 -3
  308. package/lib/utils/datasource-test-run-tty-log.js +5 -1
  309. package/lib/utils/declarative-url-ports.js +3 -3
  310. package/lib/utils/deployment-auth-mode.js +41 -0
  311. package/lib/utils/developer-volume-id.js +33 -0
  312. package/lib/utils/env-copy.js +14 -9
  313. package/lib/utils/env-kv-orphan-lines.js +43 -0
  314. package/lib/utils/error-formatters/network-errors.js +13 -4
  315. package/lib/utils/external-env-template.js +1 -0
  316. package/lib/utils/external-system-readiness-core.js +10 -0
  317. package/lib/utils/external-system-readiness-display.js +80 -23
  318. package/lib/utils/health-check.js +4 -1
  319. package/lib/utils/help-builder.js +35 -26
  320. package/lib/utils/keycloak-realm-ready.js +101 -0
  321. package/lib/utils/load-cip-capacity-display-config.js +61 -15
  322. package/lib/utils/manifest-source-emit.js +24 -0
  323. package/lib/utils/pipeline-upload-auth-retry.js +82 -0
  324. package/lib/utils/platform-controller-url.js +156 -0
  325. package/lib/utils/postgres-platform-bootstrap.js +199 -0
  326. package/lib/utils/postgres-wipe.js +9 -2
  327. package/lib/utils/resolve-env-mode.js +47 -0
  328. package/lib/utils/secrets-generator.js +31 -25
  329. package/lib/utils/secrets-missing-error.js +164 -0
  330. package/lib/utils/semver-compare.js +127 -0
  331. package/lib/utils/service-url-label.js +81 -0
  332. package/lib/utils/setup-quiet-output.js +25 -0
  333. package/lib/utils/template-helpers.js +15 -0
  334. package/lib/utils/token-manager-client-credentials.js +201 -0
  335. package/lib/utils/token-manager-messages.js +8 -0
  336. package/lib/utils/token-manager-refresh.js +12 -2
  337. package/lib/utils/token-manager.js +86 -105
  338. package/lib/utils/upload-pipeline-ui.js +98 -0
  339. package/lib/utils/upload-sync-options.js +42 -0
  340. package/lib/utils/url-declarative-public-base.js +21 -3
  341. package/lib/utils/url-declarative-vdir-inactive-env.js +14 -4
  342. package/lib/utils/validation-poll-ui.js +22 -7
  343. package/lib/utils/validation-run-stage.js +45 -0
  344. package/lib/validation/wizard-config-validator.js +58 -19
  345. package/package.json +1 -1
  346. package/templates/applications/dataplane/application.yaml +2 -1
  347. package/templates/applications/dataplane/env.template +36 -1
  348. package/templates/applications/dataplane/rbac.yaml +4 -0
  349. package/templates/applications/miso-controller/env.template +16 -0
  350. package/templates/external-system/README.md.hbs +116 -11
  351. package/templates/python/docker-compose.hbs +19 -18
  352. package/templates/typescript/docker-compose.hbs +18 -17
@@ -11,14 +11,30 @@
11
11
  const chalk = require('chalk');
12
12
  const { failureGlyph, successGlyph } = require('../utils/cli-test-layout-chalk');
13
13
  const logger = require('../utils/logger');
14
- const config = require('../core/config');
15
- const { getConfig } = config;
16
14
  const { getOrRefreshDeviceToken } = require('../utils/token-manager');
17
15
  const { getAuthUser } = require('../api/auth.api');
18
16
  const { resolveControllerUrl } = require('../utils/controller-url');
19
17
  const { findDataplaneServiceAppKey } = require('./wizard-dataplane');
20
18
  const { getDataplaneUrl } = require('../datasource/deploy');
21
19
  const { checkDataplaneHealth } = require('../utils/dataplane-health');
20
+ const {
21
+ displayDataplaneVersionSection,
22
+ displayCliUpgradeRequired
23
+ } = require('./auth-status-display');
24
+ const {
25
+ refreshDataplaneVersionInfo,
26
+ loadCachedVersionInfo
27
+ } = require('./auth-status-dataplane-version');
28
+ const {
29
+ EXIT_NOT_AUTHENTICATED,
30
+ EXIT_CLI_VERSION_INCOMPATIBLE,
31
+ EXIT_OK
32
+ } = require('../utils/cli-exit-codes');
33
+ const {
34
+ refreshExpiredClientTokensWherePossible,
35
+ displayStoredClientTokensSection,
36
+ tryResolveClientTokenAuth
37
+ } = require('./auth-status-client-tokens');
22
38
 
23
39
  /**
24
40
  * Format expiration date for display
@@ -81,22 +97,6 @@ async function checkDeviceToken(controllerUrl) {
81
97
  }
82
98
  }
83
99
 
84
- /**
85
- * Decrypt token if encrypted
86
- * @async
87
- * @param {string} token - Token to decrypt
88
- * @returns {Promise<string>} Decrypted token
89
- */
90
- async function decryptTokenIfNeeded(token) {
91
- const { decryptToken, isTokenEncrypted } = require('../utils/token-encryption');
92
- const encryptionKey = await config.getSecretsEncryptionKey();
93
-
94
- if (encryptionKey && isTokenEncrypted(token)) {
95
- return await decryptToken(token, encryptionKey);
96
- }
97
- return token;
98
- }
99
-
100
100
  /**
101
101
  * Validate client token and return result
102
102
  * @async
@@ -143,29 +143,14 @@ async function validateClientToken(token, controllerUrl, environment, appName, e
143
143
  }
144
144
 
145
145
  /**
146
- * Check and validate client token
146
+ * Check and validate client token (refreshes when expired if client credentials exist).
147
147
  * @async
148
148
  * @param {string} controllerUrl - Controller URL
149
149
  * @param {string} environment - Environment key
150
150
  * @returns {Promise<Object|null>} Token validation result or null
151
151
  */
152
152
  async function checkClientToken(controllerUrl, environment) {
153
- const configData = await getConfig();
154
- const environments = configData.environments || {};
155
- const envConfig = environments[environment];
156
-
157
- if (!envConfig || !envConfig.clients) {
158
- return null;
159
- }
160
-
161
- for (const [appName, tokenData] of Object.entries(envConfig.clients)) {
162
- if (tokenData.controller === controllerUrl && tokenData.token) {
163
- const token = await decryptTokenIfNeeded(tokenData.token);
164
- return await validateClientToken(token, controllerUrl, environment, appName, tokenData.expiresAt);
165
- }
166
- }
167
-
168
- return null;
153
+ return tryResolveClientTokenAuth(controllerUrl, environment, validateClientToken);
169
154
  }
170
155
 
171
156
  /**
@@ -290,6 +275,10 @@ function displayOpenApiDocs(controllerUrl, dataplaneUrl) {
290
275
  * @param {Object} [dataplaneInfo] - Optional dataplane URL and health
291
276
  * @param {string|null} [dataplaneInfo.url] - Dataplane URL
292
277
  * @param {boolean} [dataplaneInfo.connected] - Whether dataplane is reachable
278
+ * @param {string|undefined} [dataplaneInfo.dataplaneVersion]
279
+ * @param {string|undefined} [dataplaneInfo.minBuilderCliVersion]
280
+ * @param {string} [dataplaneInfo.cliVersion]
281
+ * @param {boolean} [dataplaneInfo.compatible]
293
282
  */
294
283
  function displayStatus(controllerUrl, environment, tokenInfo, dataplaneInfo) {
295
284
  logger.log(chalk.bold('\n🔐 Authentication Status\n'));
@@ -308,45 +297,109 @@ function displayStatus(controllerUrl, environment, tokenInfo, dataplaneInfo) {
308
297
 
309
298
  if (tokenInfo.authenticated && dataplaneInfo) {
310
299
  displayDataplaneSection(dataplaneInfo.url, dataplaneInfo.connected);
300
+ displayDataplaneVersionSection({
301
+ connected: dataplaneInfo.connected,
302
+ dataplaneVersion: dataplaneInfo.dataplaneVersion,
303
+ minBuilderCliVersion: dataplaneInfo.minBuilderCliVersion,
304
+ cliVersion: dataplaneInfo.cliVersion,
305
+ compatible: dataplaneInfo.compatible
306
+ });
307
+ if (dataplaneInfo.minBuilderCliVersion && dataplaneInfo.compatible === false) {
308
+ displayCliUpgradeRequired({
309
+ required: dataplaneInfo.minBuilderCliVersion,
310
+ installed: dataplaneInfo.cliVersion
311
+ });
312
+ }
311
313
  }
312
314
 
313
315
  logger.log('');
314
316
  }
315
317
 
318
+ /**
319
+ * Resolve the dataplane block for auth status (URL, reachability, versions,
320
+ * compatibility). Returns null when no dataplane is discovered.
321
+ *
322
+ * @async
323
+ * @function buildDataplaneInfo
324
+ * @param {string} controllerUrl
325
+ * @param {string} environment
326
+ * @param {Object} authConfig - Bearer auth config built from a valid token
327
+ * @returns {Promise<Object|null>}
328
+ */
329
+ async function buildDataplaneInfo(controllerUrl, environment, authConfig) {
330
+ const dataplaneUrl = await resolveDataplaneUrlSilent(controllerUrl, environment, authConfig);
331
+ if (!dataplaneUrl) {
332
+ return { url: null, connected: false };
333
+ }
334
+ const connected = await checkDataplaneHealth(dataplaneUrl, 5000);
335
+ const versionInfo = connected
336
+ ? await refreshDataplaneVersionInfo(controllerUrl, dataplaneUrl)
337
+ : await loadCachedVersionInfo(controllerUrl);
338
+ return {
339
+ url: dataplaneUrl,
340
+ connected,
341
+ dataplaneVersion: versionInfo.dataplaneVersion,
342
+ minBuilderCliVersion: versionInfo.minBuilderCliVersion,
343
+ cliVersion: versionInfo.cliVersion,
344
+ compatible: versionInfo.compatible
345
+ };
346
+ }
347
+
316
348
  /**
317
349
  * Handle auth status command
318
350
  * Controller and environment come from config.yaml (set via aifabrix login or aifabrix auth config).
319
351
  * @async
320
352
  * @function handleAuthStatus
321
353
  * @param {Object} options - Command options
322
- * @param {boolean} [options.validate] - If true, exit with code 1 when not authenticated
354
+ * @param {boolean} [options.validate] - If true, exit with code 1 when not authenticated, or code 3 when CLI is older than dataplane minimum
323
355
  * @returns {Promise<void>} Resolves when status is displayed
324
356
  */
357
+ /**
358
+ * Prefer a working device token; fall back to environment client credentials when the
359
+ * stored device token is expired or rejected (common in long-lived dev VMs).
360
+ *
361
+ * @async
362
+ * @param {string} controllerUrl
363
+ * @param {string} environment
364
+ * @returns {Promise<Object|null>}
365
+ */
366
+ async function resolveAuthenticatedTokenInfo(controllerUrl, environment) {
367
+ const deviceResult = await checkDeviceToken(controllerUrl);
368
+ if (deviceResult && deviceResult.authenticated) {
369
+ return deviceResult;
370
+ }
371
+ const clientResult = await checkClientToken(controllerUrl, environment);
372
+ if (clientResult && clientResult.authenticated) {
373
+ return clientResult;
374
+ }
375
+ return deviceResult || clientResult || null;
376
+ }
377
+
325
378
  async function handleAuthStatus(options = {}) {
326
379
  const { resolveEnvironment } = require('../core/config');
327
380
  const controllerUrl = await resolveControllerUrl();
328
381
  const environment = await resolveEnvironment();
329
382
 
330
- // Check device token first (preferred)
331
- let tokenInfo = await checkDeviceToken(controllerUrl);
332
-
333
- // If no device token, check client token
334
- if (!tokenInfo) {
335
- tokenInfo = await checkClientToken(controllerUrl, environment);
336
- }
383
+ const refreshedCount = await refreshExpiredClientTokensWherePossible(environment, controllerUrl);
384
+ const tokenInfo = await resolveAuthenticatedTokenInfo(controllerUrl, environment);
337
385
 
338
386
  let dataplaneInfo = null;
339
387
  if (tokenInfo && tokenInfo.authenticated && tokenInfo.token) {
340
388
  const authConfig = { type: 'bearer', token: tokenInfo.token };
341
- const dataplaneUrl = await resolveDataplaneUrlSilent(controllerUrl, environment, authConfig);
342
- const connected = dataplaneUrl ? await checkDataplaneHealth(dataplaneUrl, 5000) : false;
343
- dataplaneInfo = { url: dataplaneUrl, connected };
389
+ dataplaneInfo = await buildDataplaneInfo(controllerUrl, environment, authConfig);
344
390
  }
345
391
 
346
392
  displayStatus(controllerUrl, environment, tokenInfo, dataplaneInfo);
393
+ await displayStoredClientTokensSection(environment, controllerUrl, refreshedCount);
347
394
 
348
- if (options.validate && (!tokenInfo || !tokenInfo.authenticated)) {
349
- process.exit(1);
395
+ if (options.validate) {
396
+ if (!tokenInfo || !tokenInfo.authenticated) {
397
+ process.exit(EXIT_NOT_AUTHENTICATED);
398
+ }
399
+ if (dataplaneInfo && dataplaneInfo.minBuilderCliVersion && dataplaneInfo.compatible === false) {
400
+ process.exit(EXIT_CLI_VERSION_INCOMPATIBLE);
401
+ }
402
+ process.exit(EXIT_OK);
350
403
  }
351
404
  }
352
405
 
@@ -363,10 +416,7 @@ async function getValidatedAuthContext() {
363
416
  const controllerUrl = await resolveControllerUrl();
364
417
  const environment = await resolveEnvironment();
365
418
 
366
- let tokenInfo = await checkDeviceToken(controllerUrl);
367
- if (!tokenInfo) {
368
- tokenInfo = await checkClientToken(controllerUrl, environment);
369
- }
419
+ const tokenInfo = await resolveAuthenticatedTokenInfo(controllerUrl, environment);
370
420
 
371
421
  if (!tokenInfo || !tokenInfo.authenticated || !tokenInfo.token) {
372
422
  throw new Error('Not authenticated. Run "aifabrix login" or configure client credentials.');
@@ -378,4 +428,12 @@ async function getValidatedAuthContext() {
378
428
  return { controllerUrl, environment, authConfig, dataplaneUrl };
379
429
  }
380
430
 
381
- module.exports = { handleAuthStatus, getValidatedAuthContext };
431
+ module.exports = {
432
+ handleAuthStatus,
433
+ getValidatedAuthContext,
434
+ resolveAuthenticatedTokenInfo,
435
+ checkDeviceToken,
436
+ checkClientToken,
437
+ refreshExpiredClientTokensWherePossible,
438
+ displayStoredClientTokensSection
439
+ };
@@ -16,6 +16,7 @@ const { getDeploymentAuth, requireBearerForDataplanePipeline } = require('../uti
16
16
  const { resolveDataplaneUrl } = require('../utils/dataplane-resolver');
17
17
  const { getIntegrationPath } = require('../utils/paths');
18
18
  const { pushCredentialSecrets } = require('../utils/credential-secrets-env');
19
+ const { runWithCredentialPushSpinner } = require('../utils/credential-push-ui');
19
20
  const { generateControllerManifest } = require('../generator/external-controller-manifest');
20
21
 
21
22
  /**
@@ -84,11 +85,15 @@ async function runCredentialPush(systemKey) {
84
85
  const dataplaneUrl = await resolveDataplaneUrl(controllerUrl, environment, authConfig);
85
86
 
86
87
  const payload = await buildPayload(systemKey);
87
- const pushResult = await pushCredentialSecrets(dataplaneUrl, authConfig, {
88
- envFilePath,
89
- appName: systemKey,
90
- payload
91
- });
88
+ const pushResult = await runWithCredentialPushSpinner(
89
+ () =>
90
+ pushCredentialSecrets(dataplaneUrl, authConfig, {
91
+ envFilePath,
92
+ appName: systemKey,
93
+ payload
94
+ }),
95
+ { systemKey }
96
+ );
92
97
 
93
98
  logPushResult(pushResult);
94
99
  return { pushed: pushResult.pushed || 0 };
@@ -0,0 +1,178 @@
1
+ /**
2
+ * @fileoverview CLI for `datasource load` and `datasource export` (plan 144)
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const logger = require('../utils/logger');
10
+ const { formatBlockingError } = require('../utils/cli-test-layout-chalk');
11
+ const { runDatasourceLoad } = require('../datasource/bulk-loader-service');
12
+ const { runDatasourceExport } = require('../datasource/datasource-exporter-service');
13
+ const { displayDatasourceLoadTTY } = require('../utils/datasource-load-display');
14
+ const { displayDatasourceExportTTY } = require('../utils/datasource-export-display');
15
+
16
+ function loadHelpAfter() {
17
+ return `
18
+ Examples:
19
+ $ aifabrix datasource load hubspot-test-datasource-company
20
+ $ aifabrix datasource load hubspot-test-company --file ./fixtures/rows.ndjson -v
21
+ $ aifabrix datasource load hubspot-test-company --dry-run
22
+ $ af ds load hubspot-test-company --batch-size 50 --sync-type incremental
23
+
24
+ Notes:
25
+ - Imports local JSON/NDJSON via dataplane bulk record sync (not direct DB).
26
+ - Default file: integration/.data/<systemKey>-data-<entity>.json or .ndjson
27
+ - External integration folders only (integration/<systemKey>/).
28
+ `;
29
+ }
30
+
31
+ function exportHelpAfter() {
32
+ return `
33
+ Examples:
34
+ $ aifabrix datasource export hubspot-test-datasource-company
35
+ $ aifabrix datasource export hubspot-test-company --format ndjson --limit 500
36
+ $ aifabrix datasource export hubspot-test-company --filter '{"status":{"eq":"active"}}' -v
37
+ $ af ds export hubspot-test-company --fields email,name --strict
38
+
39
+ Notes:
40
+ - Exports governed records search results (ABAC applied), not a raw DB dump.
41
+ - Default output: integration/.data/<systemKey>-data-<entity>.json or .ndjson
42
+ - Maximum 10000 rows per run (dataplane search limit).
43
+ `;
44
+ }
45
+
46
+ /**
47
+ * @param {Object} result
48
+ * @returns {number}
49
+ */
50
+ function computeLoadExitCode(result) {
51
+ if (result.dryRun) {
52
+ return 0;
53
+ }
54
+ return (result.totals.failedCount || 0) > 0 ? 1 : 0;
55
+ }
56
+
57
+ /**
58
+ * @param {Object} result
59
+ * @param {Object} options
60
+ * @returns {number}
61
+ */
62
+ function computeExportExitCode(result, options) {
63
+ if (options.strict === true && result.recordCount === 0) {
64
+ return 1;
65
+ }
66
+ return 0;
67
+ }
68
+
69
+ async function datasourceLoadAction(datasourceKey, options) {
70
+ try {
71
+ const result = await runDatasourceLoad(datasourceKey, {
72
+ app: options.app,
73
+ env: options.env,
74
+ file: options.file,
75
+ verbose: options.verbose,
76
+ dryRun: options.dryRun,
77
+ batchSize: options.batchSize,
78
+ syncType: options.syncType,
79
+ format: options.format
80
+ });
81
+
82
+ if (options.json) {
83
+ const { context: _ctx, ...payload } = result;
84
+ logger.log(JSON.stringify(payload, null, 2));
85
+ } else {
86
+ displayDatasourceLoadTTY(result, { environment: options.env, verbose: options.verbose });
87
+ }
88
+
89
+ process.exit(computeLoadExitCode(result));
90
+ } catch (err) {
91
+ logger.error(formatBlockingError(`Load failed: ${err.message}`));
92
+ const code = err.message && /auth|login|token|version|unreachable/i.test(err.message) ? 3 : 1;
93
+ process.exit(code);
94
+ }
95
+ }
96
+
97
+ async function datasourceExportAction(datasourceKey, options) {
98
+ try {
99
+ const result = await runDatasourceExport(datasourceKey, {
100
+ app: options.app,
101
+ env: options.env,
102
+ file: options.file,
103
+ verbose: options.verbose,
104
+ format: options.format,
105
+ filter: options.filter,
106
+ fields: options.fields,
107
+ limit: options.limit,
108
+ intent: options.intent,
109
+ strict: options.strict
110
+ });
111
+
112
+ if (options.json) {
113
+ const { context: _ctx, ...payload } = result;
114
+ logger.log(JSON.stringify(payload, null, 2));
115
+ } else {
116
+ displayDatasourceExportTTY(result, { environment: options.env, verbose: options.verbose });
117
+ }
118
+
119
+ process.exit(computeExportExitCode(result, options));
120
+ } catch (err) {
121
+ logger.error(formatBlockingError(`Export failed: ${err.message}`));
122
+ const code = err.message && /auth|login|token|version|unreachable/i.test(err.message) ? 3 : 1;
123
+ process.exit(code);
124
+ }
125
+ }
126
+
127
+ /**
128
+ * @param {import('commander').Command} datasource
129
+ */
130
+ function setupDatasourceLoadExportCommands(datasource) {
131
+ datasource
132
+ .command('load <datasourceKey>')
133
+ .description('Import local JSON/NDJSON records via dataplane bulk sync')
134
+ .option('-a, --app <app>', 'Integration folder name')
135
+ .option('-e, --env <env>', 'Environment: dev, tst, or pro')
136
+ .option('--file <path>', 'Input file (default: integration/.data/...)')
137
+ .option('--format <json|ndjson>', 'File format when extension is ambiguous')
138
+ .option('--batch-size <n>', 'Records per bulk request', '100')
139
+ .option(
140
+ '--sync-type <incremental|bulk|validate>',
141
+ 'Dataplane syncType',
142
+ 'incremental'
143
+ )
144
+ .option('--dry-run', 'Parse and validate only; no upload')
145
+ .option('-v, --verbose', 'Per-batch progress')
146
+ .option('--json', 'Machine-readable result JSON')
147
+ .addHelpText('after', loadHelpAfter())
148
+ .action(datasourceLoadAction);
149
+
150
+ datasource
151
+ .command('export <datasourceKey>')
152
+ .description('Export governed records to local JSON/NDJSON via records search')
153
+ .option('-a, --app <app>', 'Integration folder name')
154
+ .option('-e, --env <env>', 'Environment: dev, tst, or pro')
155
+ .option('--file <path>', 'Output file (default: integration/.data/...)')
156
+ .option('--format <json|ndjson>', 'Output format')
157
+ .option('--filter <json>', 'Records search filters (JSON object)')
158
+ .option('--fields <csv>', 'Project metadata keys in export rows')
159
+ .option('--limit <n>', 'Max records (1–10000)', '1000')
160
+ .option(
161
+ '--intent <retrieval|grounding|analytics|validation>',
162
+ 'Search intent',
163
+ 'validation'
164
+ )
165
+ .option('--strict', 'Exit 1 when zero rows are exported')
166
+ .option('-v, --verbose', 'Search stats and file size')
167
+ .option('--json', 'Machine-readable result JSON')
168
+ .addHelpText('after', exportHelpAfter())
169
+ .action(datasourceExportAction);
170
+ }
171
+
172
+ module.exports = {
173
+ setupDatasourceLoadExportCommands,
174
+ datasourceLoadAction,
175
+ datasourceExportAction,
176
+ computeLoadExitCode,
177
+ computeExportExitCode
178
+ };
@@ -0,0 +1,118 @@
1
+ /**
2
+ * @fileoverview CLI wiring for `datasource verify-trust` (404.5 / plan 143).
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const logger = require('../utils/logger');
10
+ const { formatBlockingError } = require('../utils/cli-test-layout-chalk');
11
+ const { runDatasourceAgentTrust } = require('../datasource/agent-trust-run');
12
+ const { writeTrustDebugLogAndPrint } = require('../datasource/agent-trust-debug-log');
13
+ const { displayAgentTrustRunTTY } = require('../utils/agent-trust-run-display');
14
+ const { computeExitCodeFromTrustRun } = require('../utils/agent-trust-run-exit');
15
+ const { attachDatasourceTestCommonOptions } = require('./datasource-unified-test-cli.options');
16
+ const { cliOptsSkipSync } = require('../utils/cli-sync-options');
17
+
18
+ function datasourceVerifyTrustHelpAfter() {
19
+ return `
20
+ Examples:
21
+ $ aifabrix datasource verify-trust hubspot-companies
22
+ $ aifabrix datasource verify-trust hubspot-companies --app test-e2e-hubspot -v
23
+ $ aifabrix datasource verify-trust hubspot-companies --revalidate --strict
24
+ $ aifabrix verify-trust test-e2e-hubspot
25
+
26
+ Notes:
27
+ - Semantic trust only (agent metadata validation). For live API proof use test-e2e.
28
+ - Local files are published before run unless --no-sync.
29
+ - With --debug, JSON is saved under integration/<app>/logs/ (verify-trust-<key>-*.json). View with: aifabrix datasource log-trust <key>
30
+ `;
31
+ }
32
+
33
+ async function runDatasourceVerifyTrustOnce(datasourceKey, options) {
34
+ const { trustRun, apiError } = await runDatasourceAgentTrust(datasourceKey, {
35
+ app: options.app,
36
+ environment: options.env,
37
+ noSync: options.noSync === true,
38
+ force: options.force === true,
39
+ revalidate: options.revalidate === true,
40
+ summary: options.summary === true,
41
+ timeout: options.timeout
42
+ });
43
+ return { trustRun, apiError };
44
+ }
45
+
46
+ async function finalizeDatasourceVerifyTrust(datasourceKey, options, result) {
47
+ const displayOpts = {
48
+ json: options.json,
49
+ verbose: options.verbose,
50
+ environment: options.env,
51
+ noSync: options.noSync === true,
52
+ strict: options.strict === true
53
+ };
54
+ if (options.json) {
55
+ logger.log(JSON.stringify(result.trustRun, null, 2));
56
+ } else if (options.summary) {
57
+ const tr = result.trustRun;
58
+ logger.log(
59
+ `${tr.datasourceKey}: ${tr.trustDecision} (${tr.validationStatus}, ${Math.round((tr.confidence || 0) * 100)}%)`
60
+ );
61
+ } else {
62
+ displayAgentTrustRunTTY(result.trustRun, displayOpts);
63
+ }
64
+ const exitOpts = {
65
+ warningsAsErrors: options.warningsAsErrors === true,
66
+ strict: options.strict === true
67
+ };
68
+ return computeExitCodeFromTrustRun(result.trustRun, exitOpts);
69
+ }
70
+
71
+ async function datasourceVerifyTrustAction(datasourceKey, options, cmd) {
72
+ try {
73
+ const merged = { ...options, noSync: cliOptsSkipSync(options, cmd) };
74
+ const result = await runDatasourceVerifyTrustOnce(datasourceKey, merged);
75
+ const { resolveAppKeyForDatasource } = require('../datasource/resolve-app');
76
+ const { appKey } = await resolveAppKeyForDatasource(datasourceKey, options.app);
77
+ if (options.debug) {
78
+ await writeTrustDebugLogAndPrint(appKey, datasourceKey, {
79
+ request: { datasourceKey, revalidate: options.revalidate === true },
80
+ response: result.trustRun,
81
+ error: result.apiError ? result.apiError.message : null
82
+ });
83
+ }
84
+ const exitCode = await finalizeDatasourceVerifyTrust(datasourceKey, merged, result);
85
+ process.exit(exitCode);
86
+ } catch (err) {
87
+ logger.error(formatBlockingError('Agent trust validation failed:'), err.message);
88
+ process.exit(3);
89
+ }
90
+ }
91
+
92
+ function attachDatasourceTrustOptions(cmd) {
93
+ attachDatasourceTestCommonOptions(cmd, {
94
+ includeNoAsync: false,
95
+ includePayload: false,
96
+ timeoutHelp: 'HTTP timeout for validate request (ms)',
97
+ timeoutDefault: '120000'
98
+ });
99
+ cmd
100
+ .option('--no-sync', 'Skip publishing local integration files before validate')
101
+ .option('--revalidate', 'Force new validation (ignore inputHash cache)')
102
+ .option('--strict', 'Exit 1 unless trustDecision is trusted');
103
+ }
104
+
105
+ function setupDatasourceVerifyTrustCommand(datasource) {
106
+ const cmd = datasource
107
+ .command('verify-trust <datasourceKey>')
108
+ .description('Semantic agent metadata validation for one datasource');
109
+ attachDatasourceTrustOptions(cmd);
110
+ cmd.addHelpText('after', datasourceVerifyTrustHelpAfter()).action(datasourceVerifyTrustAction);
111
+ }
112
+
113
+ module.exports = {
114
+ setupDatasourceVerifyTrustCommand,
115
+ runDatasourceVerifyTrustOnce,
116
+ finalizeDatasourceVerifyTrust,
117
+ datasourceVerifyTrustAction
118
+ };
@@ -28,6 +28,7 @@ const {
28
28
  finalizeDatasourceTestE2ELegacyPath,
29
29
  displayDatasourceTestE2EEnvelopeResults
30
30
  } = require('./datasource-unified-test-e2e-cli-helpers');
31
+ const { maybeVerifyAuditAfterE2E } = require('../datasource/audit-evidence-run');
31
32
  const {
32
33
  datasourceTestHelpAfter,
33
34
  datasourceTestIntegrationHelpAfter,
@@ -76,7 +77,8 @@ function buildDatasourceTestRunOpts(options) {
76
77
  timeout: options.timeout,
77
78
  async: options.async !== false,
78
79
  noAsync: options.async === false,
79
- sync: options.sync === true
80
+ sync: options.sync === true,
81
+ force: options.force === true
80
82
  };
81
83
  }
82
84
 
@@ -173,7 +175,8 @@ function buildIntegrationTestOpts(options) {
173
175
  debug: options.debug,
174
176
  verbose: options.verbose,
175
177
  timeout: options.timeout,
176
- sync: options.sync === true
178
+ sync: options.sync === true,
179
+ force: options.force === true
177
180
  };
178
181
  }
179
182
 
@@ -333,8 +336,9 @@ async function runDatasourceTestE2ECliOnce(datasourceKey, options) {
333
336
  minProcessed: options.minProcessed,
334
337
  minRecordCount: options.minRecordCount,
335
338
  timeout: options.timeout,
336
- capabilityKey: options.capability,
337
- sync: options.sync === true
339
+ capabilityKey: options.capabilityKey,
340
+ sync: options.sync === true,
341
+ force: options.force === true
338
342
  });
339
343
  const unifiedModes =
340
344
  options.json || options.summary || options.warningsAsErrors || options.requireCert;
@@ -352,7 +356,7 @@ async function runDatasourceTestE2ECliOnce(datasourceKey, options) {
352
356
  warningsAsErrors: options.warningsAsErrors,
353
357
  requireCert: options.requireCert,
354
358
  debug: options.debug,
355
- requestedCapabilityKey: options.capability,
359
+ requestedCapabilityKey: options.capabilityKey,
356
360
  strictCapabilityScope: options.strictCapabilityScope === true
357
361
  }
358
362
  );
@@ -370,24 +374,24 @@ async function runDatasourceTestE2ECliOnce(datasourceKey, options) {
370
374
 
371
375
  async function runDatasourceTestE2ECliAction(datasourceKey, options) {
372
376
  const { exitCode, envelope } = await runDatasourceTestE2ECliOnce(datasourceKey, options);
373
- await afterUnifiedValidationCertSync(exitCode, datasourceKey, options, 'datasource test-e2e', envelope);
374
- process.exit(exitCode);
377
+ const finalExit = await maybeVerifyAuditAfterE2E(exitCode, datasourceKey, envelope, options);
378
+ await afterUnifiedValidationCertSync(
379
+ finalExit,
380
+ datasourceKey,
381
+ options,
382
+ 'datasource test-e2e',
383
+ envelope
384
+ );
385
+ process.exit(finalExit);
375
386
  }
376
387
 
377
388
  async function e2eTestCommandAction(datasourceKey, capabilityKey, options) {
378
389
  const optObj = options && typeof options === 'object' ? options : {};
379
390
  const capFromArg = typeof capabilityKey === 'string' ? capabilityKey.trim() : '';
380
- const capFromFlag = optObj.capability !== undefined && optObj.capability !== null
381
- ? String(optObj.capability).trim()
382
- : '';
383
- const requestedCapability = capFromArg || capFromFlag;
384
- if (capFromArg && capFromFlag && capFromArg !== capFromFlag) {
385
- logger.warn(
386
- chalk.yellow('⚠ Capability mismatch:'),
387
- `using positional '${capFromArg}' instead of --capability '${capFromFlag}'.`
388
- );
389
- }
390
- const mergedOptions = { ...optObj, capability: requestedCapability || undefined };
391
+ const mergedOptions = {
392
+ ...optObj,
393
+ capabilityKey: capFromArg || undefined
394
+ };
391
395
  try {
392
396
  if (mergedOptions.watch) {
393
397
  const { appKey } = await resolveAppKeyForDatasource(datasourceKey, mergedOptions.app);
@@ -400,14 +404,20 @@ async function e2eTestCommandAction(datasourceKey, capabilityKey, options) {
400
404
  runOnce: async() => {
401
405
  try {
402
406
  const r = await runDatasourceTestE2ECliOnce(datasourceKey, mergedOptions);
403
- await afterUnifiedValidationCertSync(
407
+ const finalExit = await maybeVerifyAuditAfterE2E(
404
408
  r.exitCode,
405
409
  datasourceKey,
410
+ r.envelope,
411
+ mergedOptions
412
+ );
413
+ await afterUnifiedValidationCertSync(
414
+ finalExit,
415
+ datasourceKey,
406
416
  mergedOptions,
407
417
  'datasource test-e2e (watch)',
408
418
  r.envelope
409
419
  );
410
- return r;
420
+ return { exitCode: finalExit, envelope: r.envelope };
411
421
  } catch (err) {
412
422
  logger.error(formatBlockingError('E2E test failed:'), err.message);
413
423
  return { exitCode: 3, envelope: null };
@@ -459,5 +469,6 @@ module.exports = {
459
469
  runIntegrationOnceForWatch,
460
470
  integrationTestCommandAction,
461
471
  runDatasourceTestE2ECliOnce,
472
+ maybeVerifyAuditAfterE2E,
462
473
  e2eTestCommandAction
463
474
  };