@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
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Identity and RBAC commands (Controller users, groups, sync, cache).
3
+ *
4
+ * @fileoverview `aifabrix identity` command group
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const { setupIdentityUserCommands } = require('./identity-user-cli');
12
+ const { setupIdentityGroupCommands } = require('./identity-group-cli');
13
+ const {
14
+ setupIdentityMembershipCommands,
15
+ setupIdentityRoleCommands,
16
+ setupIdentityCacheCommands
17
+ } = require('./identity-membership-role-cache');
18
+ const { setupIdentityApplyCommand, setupIdentitySyncCommand } = require('./identity-apply-sync');
19
+ const { IDENTITY_HELP_AFTER } = require('../cli/setup-app.help');
20
+
21
+ /**
22
+ * @param {import('commander').Command} program
23
+ */
24
+ function setupIdentityCommands(program) {
25
+ const identityCmd = program
26
+ .command('identity')
27
+ .description('Manage controller users, groups, RBAC mappings, cache, and dataplane identity sync')
28
+ .addHelpText('after', IDENTITY_HELP_AFTER);
29
+
30
+ setupIdentityUserCommands(identityCmd.command('user').description('User commands'));
31
+ setupIdentityGroupCommands(identityCmd.command('group').description('Group commands'));
32
+ setupIdentityMembershipCommands(
33
+ identityCmd.command('membership').description('User–group membership commands')
34
+ );
35
+ setupIdentityRoleCommands(identityCmd.command('role').description('Environment role commands'));
36
+ setupIdentityCacheCommands(identityCmd.command('cache').description('Controller cache commands'));
37
+ setupIdentityApplyCommand(identityCmd);
38
+ setupIdentitySyncCommand(identityCmd);
39
+ }
40
+
41
+ module.exports = {
42
+ setupIdentityCommands
43
+ };
@@ -0,0 +1,123 @@
1
+ /**
2
+ * @fileoverview CLI action for `aifabrix lifecycle` certification report (plan 150.0).
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const logger = require('../utils/logger');
10
+ const { handleCommandError } = require('../utils/cli-utils');
11
+ const { cliOptsSkipSync } = require('../utils/cli-sync-options');
12
+ const { runLifecycleForExternalSystem } = require('./lifecycle-external');
13
+ const { displayLifecycleReportTTY } = require('../lifecycle/report-display');
14
+ const { VERDICT } = require('../lifecycle/product-model');
15
+ const { exitCodeFromVerdict } = require('../lifecycle/exit-codes');
16
+ const { lifecycleHasGovernanceSubjects } = require('../lifecycle/lifecycle-governance-options');
17
+
18
+ /**
19
+ * @param {Object} options
20
+ * @param {import('commander').Command} [cmd]
21
+ * @returns {Object}
22
+ */
23
+ function normalizeLifecycleCliOptions(options, cmd) {
24
+ const raw = cmd && Array.isArray(cmd.rawArgs) ? cmd.rawArgs : [];
25
+ const has = flag => raw.includes(flag);
26
+ return {
27
+ env: options.env || 'dev',
28
+ verbose: options.verbose === true || has('-v') || has('--verbose'),
29
+ debug: options.debug === true || has('-d') || has('--debug'),
30
+ json: options.json === true || has('--json'),
31
+ run: options.run === true || has('--run'),
32
+ noSync: cliOptsSkipSync(options, cmd),
33
+ force: options.force === true || has('--force'),
34
+ subjectUserId: options.subjectUserId || [],
35
+ subjectEmail: options.subjectEmail || [],
36
+ certificationProfile: options.certificationProfile || 'bronze'
37
+ };
38
+ }
39
+
40
+ /**
41
+ * @param {Object} report
42
+ * @returns {string}
43
+ */
44
+ function lifecycleVerdictFromReport(report) {
45
+ const ops = report.operations?.verdict;
46
+ const trust = report.trust?.verdict;
47
+ const gov = report.governance?.verdict;
48
+ if (ops === VERDICT.FAILED || trust === VERDICT.FAILED || gov === VERDICT.FAILED) {
49
+ return VERDICT.FAILED;
50
+ }
51
+ if (
52
+ ops === VERDICT.VERIFIED &&
53
+ trust === VERDICT.VERIFIED &&
54
+ gov === VERDICT.VERIFIED
55
+ ) {
56
+ return VERDICT.VERIFIED;
57
+ }
58
+ return VERDICT.NOT_VERIFIED;
59
+ }
60
+
61
+ async function runLifecycleCommandAction(appName, options, cmd) {
62
+ const opts = normalizeLifecycleCliOptions(options, cmd);
63
+ if (lifecycleHasGovernanceSubjects(opts) && !opts.run) {
64
+ throw new Error(
65
+ '--subject-user-id and --subject-email require --run on lifecycle (use verify-governance for governance-only)'
66
+ );
67
+ }
68
+ const result = await runLifecycleForExternalSystem(appName, opts);
69
+ const report = result.report;
70
+
71
+ if (opts.json) {
72
+ const envelope = {
73
+ systemKey: result.systemKey,
74
+ command: 'lifecycle',
75
+ certification: report.certification,
76
+ operations: report.operations,
77
+ trust: report.trust,
78
+ governance: report.governance,
79
+ recommendations: report.recommendations,
80
+ warnings: report.warnings,
81
+ openApiPublished: result.openApiPublished === true,
82
+ certificationProgress: result.certificationProgress ?? null,
83
+ stepsRun: result.stepsRun
84
+ };
85
+ if (opts.verbose) {
86
+ envelope.datasources = report.datasources;
87
+ }
88
+ logger.log(JSON.stringify(envelope, null, 2));
89
+ } else {
90
+ displayLifecycleReportTTY(result.systemKey, report, {
91
+ details: opts.verbose,
92
+ openApiPublished: result.openApiPublished === true,
93
+ certificationProgress: result.certificationProgress ?? null,
94
+ dataplaneUrl: result.dataplaneUrl ?? null,
95
+ dataplaneUiBaseUrl: result.dataplaneUiBaseUrl ?? null
96
+ });
97
+ }
98
+
99
+ const pillarVerdict = lifecycleVerdictFromReport(report);
100
+ const exitCode =
101
+ pillarVerdict === VERDICT.VERIFIED
102
+ ? 0
103
+ : exitCodeFromVerdict(pillarVerdict, { partial: pillarVerdict === VERDICT.NOT_VERIFIED });
104
+ if (exitCode !== 0) {
105
+ process.exit(exitCode);
106
+ }
107
+ }
108
+
109
+ async function lifecycleCommandHandler(appName, options, cmd) {
110
+ try {
111
+ await runLifecycleCommandAction(appName, options, cmd);
112
+ } catch (error) {
113
+ handleCommandError(error, 'lifecycle');
114
+ process.exit(3);
115
+ }
116
+ }
117
+
118
+ module.exports = {
119
+ normalizeLifecycleCliOptions,
120
+ runLifecycleCommandAction,
121
+ lifecycleCommandHandler,
122
+ lifecycleVerdictFromReport
123
+ };
@@ -0,0 +1,268 @@
1
+ /**
2
+ * @fileoverview lifecycle certification report — GET default, --run optional (plan 150.0).
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { getSystemLifecycleReport, runSystemLifecycle } = require('../api/lifecycle.api');
10
+ const { setupIntegrationTestAuth } = require('../external-system/test-auth');
11
+ const { getConfig } = require('../core/config');
12
+ const { cliOptsSkipSync } = require('../utils/cli-sync-options');
13
+ const { syncLocalIfRequested } = require('./test-e2e-external');
14
+ const { runVerifyOperationsForExternalSystem } = require('./verify-operations-external');
15
+ const { runVerifyTrustForExternalSystem } = require('./verify-trust-external');
16
+ const { runGovernanceVerifyForExternalSystem } = require('./governance-verify-external');
17
+ const { VERDICT } = require('../lifecycle/product-model');
18
+ const { buildCertificationProgress } = require('../lifecycle/certification-progress');
19
+ const { resolveOpenApiPublished } = require('../lifecycle/open-api-published');
20
+ const { runWithVerifyStepProgress } = require('../lifecycle/verify-step-progress');
21
+ const { resolveDataplaneUiBaseUrl } = require('../lifecycle/dataplane-ui-url');
22
+ const {
23
+ lifecycleHasGovernanceSubjects,
24
+ lifecycleGovernanceNeedsWork,
25
+ buildGovernanceOptsFromLifecycle
26
+ } = require('../lifecycle/lifecycle-governance-options');
27
+
28
+ /**
29
+ * @async
30
+ * @param {string|null|undefined} dataplaneUrl
31
+ * @returns {Promise<string|null>}
32
+ */
33
+ async function resolveLifecycleDataplaneUiBaseUrl(dataplaneUrl) {
34
+ try {
35
+ return await resolveDataplaneUiBaseUrl(dataplaneUrl);
36
+ } catch {
37
+ return null;
38
+ }
39
+ }
40
+
41
+ /**
42
+ * @async
43
+ * @param {string} systemKey
44
+ * @param {Object} options
45
+ * @returns {Promise<{ authConfig: Object, dataplaneUrl: string }>}
46
+ */
47
+ async function resolveLifecycleAuth(systemKey, options) {
48
+ if (!cliOptsSkipSync(options) && options.run === true) {
49
+ options.lifecycleProgress?.setLabel?.('Checking config on dataplane');
50
+ const uploadCtx = await syncLocalIfRequested(systemKey, {
51
+ ...options,
52
+ suppressPipelineSpinner: true
53
+ });
54
+ if (uploadCtx) {
55
+ options.lifecycleProgress?.setLabel?.('Processing');
56
+ return { authConfig: uploadCtx.authConfig, dataplaneUrl: uploadCtx.dataplaneUrl };
57
+ }
58
+ }
59
+ const configObj = await getConfig();
60
+ return setupIntegrationTestAuth(systemKey, { environment: options.env }, configObj);
61
+ }
62
+
63
+ /**
64
+ * Generate + verify governance when lifecycle --run includes subject selectors.
65
+ * @async
66
+ * @param {string} systemKey
67
+ * @param {Object} report
68
+ * @param {Object} authConfig
69
+ * @param {string} dataplaneUrl
70
+ * @param {Object} options
71
+ */
72
+ async function runLifecycleGovernanceCombinedIfNeeded(
73
+ systemKey,
74
+ report,
75
+ authConfig,
76
+ dataplaneUrl,
77
+ options
78
+ ) {
79
+ if (!lifecycleHasGovernanceSubjects(options)) {
80
+ return;
81
+ }
82
+ if (!lifecycleGovernanceNeedsWork(report)) {
83
+ return;
84
+ }
85
+ const { runVerifyGovernanceCombined } = require('./verify-governance-combined-external');
86
+ await runVerifyGovernanceCombined(
87
+ systemKey,
88
+ buildGovernanceOptsFromLifecycle(options, { authConfig, dataplaneUrl })
89
+ );
90
+ }
91
+
92
+ /**
93
+ * Run missing verify pillars locally when lifecycle/run API unavailable.
94
+ * @async
95
+ * @param {string} systemKey
96
+ * @param {Object} report
97
+ * @param {Object} options
98
+ */
99
+ async function runMissingVerifyStepsLocally(systemKey, report, options) {
100
+ const runOpts = { ...options, noSync: true };
101
+ if (report.operations?.verdict !== VERDICT.VERIFIED) {
102
+ await runVerifyOperationsForExternalSystem(systemKey, runOpts);
103
+ }
104
+ if (report.trust?.verdict !== VERDICT.VERIFIED) {
105
+ await runVerifyTrustForExternalSystem(systemKey, runOpts);
106
+ }
107
+ if (report.governance?.verdict !== VERDICT.VERIFIED) {
108
+ if (lifecycleHasGovernanceSubjects(options)) {
109
+ const { runVerifyGovernanceCombined } = require('./verify-governance-combined-external');
110
+ await runVerifyGovernanceCombined(
111
+ systemKey,
112
+ buildGovernanceOptsFromLifecycle(options, {
113
+ authConfig: options.authConfig,
114
+ dataplaneUrl: options.dataplaneUrl
115
+ })
116
+ );
117
+ } else {
118
+ await runGovernanceVerifyForExternalSystem(systemKey, runOpts);
119
+ }
120
+ }
121
+ }
122
+
123
+ /**
124
+ * @async
125
+ * @param {string} systemKey
126
+ * @param {Object} report
127
+ * @param {string} dataplaneUrl
128
+ * @param {string|null} dataplaneUiBaseUrl
129
+ * @param {Object} authConfig
130
+ * @param {Object} [extra]
131
+ * @returns {Promise<Object>}
132
+ */
133
+ async function buildLifecycleResult(
134
+ systemKey,
135
+ report,
136
+ dataplaneUrl,
137
+ dataplaneUiBaseUrl,
138
+ authConfig,
139
+ extra = {}
140
+ ) {
141
+ const openApiPublished = await resolveOpenApiPublished(dataplaneUrl, authConfig, systemKey);
142
+ return {
143
+ systemKey,
144
+ command: 'lifecycle',
145
+ report,
146
+ dataplaneUrl,
147
+ dataplaneUiBaseUrl,
148
+ openApiPublished,
149
+ certificationProgress: buildCertificationProgress(report, { openApiPublished }),
150
+ ...extra
151
+ };
152
+ }
153
+
154
+ /**
155
+ * @async
156
+ * @param {string} systemKey
157
+ * @param {Object} authConfig
158
+ * @param {string} dataplaneUrl
159
+ * @param {string|null} dataplaneUiBaseUrl
160
+ * @param {Object} options
161
+ * @returns {Promise<Object>}
162
+ */
163
+ async function runLifecycleViaDataplaneApi(
164
+ systemKey,
165
+ authConfig,
166
+ dataplaneUrl,
167
+ dataplaneUiBaseUrl,
168
+ options
169
+ ) {
170
+ if (lifecycleHasGovernanceSubjects(options)) {
171
+ const preReport = await getSystemLifecycleReport(dataplaneUrl, authConfig, systemKey, {
172
+ details: options.verbose === true
173
+ });
174
+ await runLifecycleGovernanceCombinedIfNeeded(
175
+ systemKey,
176
+ preReport,
177
+ authConfig,
178
+ dataplaneUrl,
179
+ options
180
+ );
181
+ }
182
+ const runRes = await runSystemLifecycle(dataplaneUrl, authConfig, systemKey, {});
183
+ return buildLifecycleResult(
184
+ systemKey,
185
+ runRes.report,
186
+ dataplaneUrl,
187
+ dataplaneUiBaseUrl,
188
+ authConfig,
189
+ { stepsRun: runRes.stepsRun || [], source: 'api' }
190
+ );
191
+ }
192
+
193
+ /**
194
+ * @async
195
+ * @param {string} systemKey
196
+ * @param {Object} options
197
+ * @returns {Promise<Object>}
198
+ */
199
+ async function executeLifecycleWork(systemKey, options = {}) {
200
+ const { authConfig, dataplaneUrl } = await resolveLifecycleAuth(systemKey, options);
201
+ const dataplaneUiBaseUrl = await resolveLifecycleDataplaneUiBaseUrl(dataplaneUrl);
202
+
203
+ if (options.run === true) {
204
+ try {
205
+ return await runLifecycleViaDataplaneApi(
206
+ systemKey,
207
+ authConfig,
208
+ dataplaneUrl,
209
+ dataplaneUiBaseUrl,
210
+ options
211
+ );
212
+ } catch {
213
+ const preReport = await getSystemLifecycleReport(dataplaneUrl, authConfig, systemKey, {
214
+ details: options.verbose === true
215
+ });
216
+ await runMissingVerifyStepsLocally(systemKey, preReport, {
217
+ ...options,
218
+ authConfig,
219
+ dataplaneUrl
220
+ });
221
+ }
222
+ }
223
+
224
+ const report = await getSystemLifecycleReport(dataplaneUrl, authConfig, systemKey, {
225
+ details: options.verbose === true
226
+ });
227
+ return buildLifecycleResult(
228
+ systemKey,
229
+ report,
230
+ dataplaneUrl,
231
+ dataplaneUiBaseUrl,
232
+ authConfig,
233
+ { source: options.run ? 'local-fallback' : 'api' }
234
+ );
235
+ }
236
+
237
+ /**
238
+ * @async
239
+ * @param {string} systemKey
240
+ * @param {Object} options
241
+ * @returns {Promise<Object>}
242
+ */
243
+ async function runLifecycleForExternalSystem(systemKey, options = {}) {
244
+ const pathsUtil = require('../utils/paths');
245
+ const appType = await pathsUtil.detectAppType(systemKey).catch(() => null);
246
+ if (!appType || appType.baseDir !== 'integration') {
247
+ throw new Error(
248
+ 'lifecycle applies to external integration folders only (integration/<systemKey>/).'
249
+ );
250
+ }
251
+
252
+ if (options.run === true) {
253
+ return runWithVerifyStepProgress(
254
+ 'Processing',
255
+ async(progress) => executeLifecycleWork(systemKey, { ...options, lifecycleProgress: progress }),
256
+ { json: options.json === true }
257
+ );
258
+ }
259
+
260
+ return executeLifecycleWork(systemKey, options);
261
+ }
262
+
263
+ module.exports = {
264
+ runLifecycleForExternalSystem,
265
+ runMissingVerifyStepsLocally,
266
+ runLifecycleGovernanceCombinedIfNeeded,
267
+ resolveLifecycleAuth
268
+ };
@@ -17,6 +17,7 @@ const logger = require('../utils/logger');
17
17
  const { handleCredentialsLogin } = require('./login-credentials');
18
18
  const { handleDeviceCodeLogin } = require('./login-device');
19
19
  const { resolveControllerUrl } = require('../utils/controller-url');
20
+ const { tryRefreshDataplaneVersionAfterLogin } = require('./auth-status-dataplane-version');
20
21
 
21
22
  /**
22
23
  * Determine and validate authentication method
@@ -84,7 +85,7 @@ async function normalizeControllerUrl(options) {
84
85
  if (!controllerUrl) {
85
86
  controllerUrl = await resolveControllerUrl();
86
87
  }
87
- controllerUrl = String(controllerUrl).replace(/\/+$/, '');
88
+ controllerUrl = String(controllerUrl).trim().replace(/\/+$/, '');
88
89
  // Save controller URL to config
89
90
  await setControllerUrl(controllerUrl);
90
91
  if (!options.compact) {
@@ -161,6 +162,55 @@ async function handleDeviceCodeLoginFlow(controllerUrl, environment, options) {
161
162
  });
162
163
  }
163
164
 
165
+ /**
166
+ * @param {string} controllerUrl
167
+ * @param {Object} options
168
+ * @param {boolean} skipRefresh
169
+ * @returns {Promise<void>}
170
+ */
171
+ async function refreshDataplaneVersionIfNeeded(controllerUrl, options, skipRefresh) {
172
+ if (skipRefresh) return;
173
+ if (!options.compact) {
174
+ const { LOGIN_POST_REFRESH_BUDGET_MS } = require('./auth-status-dataplane-version');
175
+ logger.log(
176
+ chalk.gray(
177
+ `Syncing dataplane version cache (optional, up to ${Math.round(LOGIN_POST_REFRESH_BUDGET_MS / 1000)}s)...`
178
+ )
179
+ );
180
+ }
181
+ await tryRefreshDataplaneVersionAfterLogin(controllerUrl, options);
182
+ }
183
+
184
+ /**
185
+ * @returns {Promise<'credentials'|'device'>}
186
+ */
187
+ async function executeLoginMethod(method, controllerUrl, environment, options, skipRefresh) {
188
+ if (method === 'credentials') {
189
+ await handleCredentialsLoginFlow(controllerUrl, environment, options);
190
+ await refreshDataplaneVersionIfNeeded(controllerUrl, options, skipRefresh);
191
+ return 'credentials';
192
+ }
193
+ await handleDeviceCodeLoginFlow(controllerUrl, environment, options);
194
+ await refreshDataplaneVersionIfNeeded(controllerUrl, options, skipRefresh);
195
+ return 'device';
196
+ }
197
+
198
+ /**
199
+ * @param {Object} options
200
+ * @param {string} controllerUrl
201
+ * @param {string} environment
202
+ */
203
+ function logLoginSuccessFooter(options, controllerUrl, environment) {
204
+ if (options.compact) return;
205
+ logger.log(formatSuccessParagraph('Successfully logged in!'));
206
+ logger.log(chalk.gray(`Controller: ${controllerUrl}`));
207
+ logger.log(chalk.gray(`Environment: ${environment}`));
208
+ if (options.app) {
209
+ logger.log(chalk.gray(`App: ${options.app}`));
210
+ }
211
+ logger.log(chalk.gray('Token stored securely in ~/.aifabrix/config.yaml\n'));
212
+ }
213
+
164
214
  async function handleLogin(options) {
165
215
  if (!options.compact) {
166
216
  logger.log(chalk.blue('\nšŸ” Logging in to Miso Controller...\n'));
@@ -169,25 +219,14 @@ async function handleLogin(options) {
169
219
  const controllerUrl = await normalizeControllerUrl(options);
170
220
  const environment = await handleEnvironmentConfig(options);
171
221
  const method = await determineAuthMethod(options.method);
172
-
173
222
  validateScopeOptions(method, options);
174
223
 
175
- if (method === 'credentials') {
176
- await handleCredentialsLoginFlow(controllerUrl, environment, options);
177
- } else if (method === 'device') {
178
- await handleDeviceCodeLoginFlow(controllerUrl, environment, options);
179
- return; // Early return for device flow (already saved config)
180
- }
224
+ const skipRefresh =
225
+ options.skipDataplaneVersionRefresh === true || options.skipVersionCache === true;
226
+ const flow = await executeLoginMethod(method, controllerUrl, environment, options, skipRefresh);
227
+ if (flow === 'device') return;
181
228
 
182
- if (!options.compact) {
183
- logger.log(formatSuccessParagraph('Successfully logged in!'));
184
- logger.log(chalk.gray(`Controller: ${controllerUrl}`));
185
- logger.log(chalk.gray(`Environment: ${environment}`));
186
- if (options.app) {
187
- logger.log(chalk.gray(`App: ${options.app}`));
188
- }
189
- logger.log(chalk.gray('Token stored securely in ~/.aifabrix/config.yaml\n'));
190
- }
229
+ logLoginSuccessFooter(options, controllerUrl, environment);
191
230
  }
192
231
 
193
232
  module.exports = { handleLogin };