@aifabrix/builder 2.42.1 → 2.44.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 (392) hide show
  1. package/.cursor/rules/anchor-docs.mdc +15 -0
  2. package/README.md +2 -2
  3. package/anchor-docs/README.md +10 -0
  4. package/anchor-docs/_TEMPLATE +24 -0
  5. package/bin/aifabrix.js +13 -4
  6. package/integration/hubspot-test/README.md +157 -0
  7. package/integration/{hubspot → hubspot-test}/application.json +6 -6
  8. package/integration/{hubspot → hubspot-test}/create-hubspot.js +10 -10
  9. package/integration/hubspot-test/env.template +4 -0
  10. package/integration/hubspot-test/hubspot-test-datasource-company.json +138 -0
  11. package/integration/hubspot-test/hubspot-test-datasource-contact.json +146 -0
  12. package/integration/hubspot-test/hubspot-test-datasource-deal.json +146 -0
  13. package/integration/hubspot-test/hubspot-test-datasource-users.json +76 -0
  14. package/integration/{hubspot/hubspot-deploy.json → hubspot-test/hubspot-test-deploy.json} +201 -24
  15. package/integration/{hubspot/hubspot-system.json → hubspot-test/hubspot-test-system.json} +8 -7
  16. package/integration/hubspot-test/rbac.json +166 -0
  17. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-hubspot-credential-real.yaml +3 -3
  18. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-hubspot-env-vars.yaml +2 -2
  19. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-add-datasource.yaml +1 -1
  20. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-credential-create.yaml +1 -1
  21. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-credential-select.yaml +1 -1
  22. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-known-platform.yaml +1 -1
  23. package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-source.yaml +2 -0
  24. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-mode.yaml +1 -1
  25. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-openapi-file.yaml +1 -1
  26. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-openapi-url.yaml +1 -1
  27. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-source.yaml +1 -1
  28. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-dimension-array-test.yaml +1 -1
  29. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-key-test.yaml +5 -0
  30. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-path-test.yaml +5 -0
  31. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-dimension-test.yaml +1 -1
  32. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-rbac-test.yaml +1 -1
  33. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-rbac-yaml-test.yaml +1 -1
  34. package/integration/{hubspot → hubspot-test}/test-dataplane-down-tests.js +1 -7
  35. package/integration/{hubspot → hubspot-test}/test-dataplane-down.js +3 -3
  36. package/integration/{hubspot → hubspot-test}/test.js +137 -102
  37. package/integration/{hubspot → hubspot-test}/wizard-hubspot-e2e.yaml +2 -2
  38. package/integration/{hubspot → hubspot-test}/wizard-hubspot-platform.yaml +1 -1
  39. package/integration/hubspot-test/wizard-hubspot-test-headless.yaml +23 -0
  40. package/integration/roundtrip-test-local/README.md +144 -0
  41. package/integration/roundtrip-test-local/application.yaml +13 -0
  42. package/integration/roundtrip-test-local/env.template +15 -0
  43. package/integration/roundtrip-test-local/roundtrip-test-local-datasource-roundtrip-test-company.yaml +14 -0
  44. package/integration/roundtrip-test-local/roundtrip-test-local-deploy.json +61 -0
  45. package/integration/roundtrip-test-local/roundtrip-test-local-system.yaml +25 -0
  46. package/integration/roundtrip-test-local2/README.md +144 -0
  47. package/integration/roundtrip-test-local2/application.yaml +13 -0
  48. package/integration/roundtrip-test-local2/env.template +15 -0
  49. package/integration/roundtrip-test-local2/roundtrip-test-local2-datasource-company.yaml +31 -0
  50. package/integration/roundtrip-test-local2/roundtrip-test-local2-deploy.json +86 -0
  51. package/integration/roundtrip-test-local2/roundtrip-test-local2-system.yaml +25 -0
  52. package/integration/test/wizard.yaml +8 -0
  53. package/jest.config.default.js +10 -0
  54. package/jest.config.integration.fixtures.js +22 -0
  55. package/jest.config.integration.js +21 -18
  56. package/jest.config.isolated.js +10 -0
  57. package/jest.projects.js +288 -0
  58. package/lib/api/datasources-core.api.js +3 -3
  59. package/lib/api/dev-mtls-request.js +110 -0
  60. package/lib/api/dev-server-https.js +145 -0
  61. package/lib/api/dev.api.js +133 -144
  62. package/lib/api/index.js +0 -1
  63. package/lib/api/pipeline.api.js +67 -20
  64. package/lib/api/service-users.api.js +111 -2
  65. package/lib/api/types/dev.types.js +4 -3
  66. package/lib/api/types/pipeline.types.js +8 -5
  67. package/lib/api/types/service-users.types.js +41 -0
  68. package/lib/api/types/validation-run.types.js +56 -0
  69. package/lib/api/validation-run.api.js +99 -0
  70. package/lib/api/validation-runner.js +99 -0
  71. package/lib/app/config.js +1 -1
  72. package/lib/app/deploy-status-display.js +2 -2
  73. package/lib/app/deploy.js +7 -6
  74. package/lib/app/display.js +2 -1
  75. package/lib/app/dockerfile.js +3 -2
  76. package/lib/app/down.js +2 -1
  77. package/lib/app/helpers.js +6 -5
  78. package/lib/app/index.js +27 -8
  79. package/lib/app/list.js +7 -6
  80. package/lib/app/push.js +4 -3
  81. package/lib/app/register.js +19 -8
  82. package/lib/app/rotate-secret.js +17 -13
  83. package/lib/app/run-container-start.js +184 -0
  84. package/lib/app/run-docker-fallback.js +108 -0
  85. package/lib/app/run-env-compose.js +30 -42
  86. package/lib/app/run-helpers.js +49 -126
  87. package/lib/app/run-infra-requirements.js +30 -0
  88. package/lib/app/run-resolve-image.js +21 -0
  89. package/lib/app/run.js +74 -21
  90. package/lib/app/show-display.js +1 -1
  91. package/lib/app/show.js +1 -1
  92. package/lib/build/index.js +13 -10
  93. package/lib/cli/index.js +2 -0
  94. package/lib/cli/setup-app.help.js +67 -0
  95. package/lib/cli/setup-app.js +59 -123
  96. package/lib/cli/setup-app.test-commands.js +179 -0
  97. package/lib/cli/setup-auth.js +36 -14
  98. package/lib/cli/setup-credential-deployment.js +22 -8
  99. package/lib/cli/setup-dev-path-commands.js +124 -0
  100. package/lib/cli/setup-dev.js +190 -103
  101. package/lib/cli/setup-environment.js +11 -20
  102. package/lib/cli/setup-external-system.js +62 -22
  103. package/lib/cli/setup-infra.js +139 -47
  104. package/lib/cli/setup-parameters.js +32 -0
  105. package/lib/cli/setup-secrets.js +147 -10
  106. package/lib/cli/setup-service-user.js +146 -20
  107. package/lib/cli/setup-utility.js +47 -19
  108. package/lib/commands/app-down.js +5 -7
  109. package/lib/commands/app-install.js +14 -7
  110. package/lib/commands/app-logs.js +13 -10
  111. package/lib/commands/app-shell.js +4 -1
  112. package/lib/commands/app-test.js +25 -19
  113. package/lib/commands/app.js +22 -10
  114. package/lib/commands/auth-config.js +10 -14
  115. package/lib/commands/auth-status.js +4 -3
  116. package/lib/commands/credential-env.js +4 -3
  117. package/lib/commands/credential-list.js +5 -4
  118. package/lib/commands/credential-push.js +4 -3
  119. package/lib/commands/datasource-unified-test-cli.js +495 -0
  120. package/lib/commands/datasource-unified-test-cli.options.js +149 -0
  121. package/lib/commands/datasource-validation-cli.js +129 -0
  122. package/lib/commands/datasource.js +123 -71
  123. package/lib/commands/deployment-list.js +6 -5
  124. package/lib/commands/dev-cli-handlers.js +122 -18
  125. package/lib/commands/dev-down.js +4 -3
  126. package/lib/commands/dev-init.js +231 -116
  127. package/lib/commands/dev-show-display.js +473 -0
  128. package/lib/commands/login-credentials.js +3 -2
  129. package/lib/commands/login-device.js +4 -3
  130. package/lib/commands/login.js +5 -4
  131. package/lib/commands/logout.js +8 -7
  132. package/lib/commands/parameters-validate.js +54 -0
  133. package/lib/commands/repair-datasource.js +314 -68
  134. package/lib/commands/repair-env-template.js +16 -10
  135. package/lib/commands/repair-rbac.js +25 -19
  136. package/lib/commands/repair.js +116 -32
  137. package/lib/commands/secrets-list.js +23 -12
  138. package/lib/commands/secrets-remove-all.js +220 -0
  139. package/lib/commands/secrets-remove.js +22 -13
  140. package/lib/commands/secrets-set.js +21 -12
  141. package/lib/commands/secrets-validate.js +20 -7
  142. package/lib/commands/secure.js +10 -9
  143. package/lib/commands/service-user.js +243 -13
  144. package/lib/commands/test-e2e-external.js +27 -1
  145. package/lib/commands/up-common.js +28 -2
  146. package/lib/commands/up-dataplane.js +31 -18
  147. package/lib/commands/up-miso.js +19 -29
  148. package/lib/commands/upload.js +138 -39
  149. package/lib/commands/wizard-core-helpers.js +1 -1
  150. package/lib/commands/wizard-dataplane.js +4 -3
  151. package/lib/commands/wizard-helpers.js +3 -3
  152. package/lib/commands/wizard.js +2 -2
  153. package/lib/core/admin-secrets.js +16 -5
  154. package/lib/core/audit-logger.js +12 -4
  155. package/lib/core/config-attach-extensions.js +46 -0
  156. package/lib/core/config-runtime-paths.js +29 -0
  157. package/lib/core/config.js +59 -58
  158. package/lib/core/diff.js +3 -2
  159. package/lib/core/ensure-encryption-key.js +2 -4
  160. package/lib/core/secrets-ensure-infra.js +77 -0
  161. package/lib/core/secrets-ensure.js +120 -64
  162. package/lib/core/secrets-env-write.js +35 -7
  163. package/lib/core/secrets-infra-placeholder-sync.js +61 -0
  164. package/lib/core/secrets.js +228 -42
  165. package/lib/core/templates-env.js +4 -3
  166. package/lib/core/templates.js +1 -1
  167. package/lib/datasource/abac-validator.js +148 -0
  168. package/lib/datasource/deploy.js +75 -53
  169. package/lib/datasource/field-reference-validator.js +77 -36
  170. package/lib/datasource/integration-context.js +63 -0
  171. package/lib/datasource/list.js +8 -7
  172. package/lib/datasource/log-viewer.js +252 -0
  173. package/lib/datasource/resolve-app.js +109 -0
  174. package/lib/datasource/test-e2e.js +95 -155
  175. package/lib/datasource/test-integration.js +121 -109
  176. package/lib/datasource/unified-validation-run-body.js +65 -0
  177. package/lib/datasource/unified-validation-run-post.js +23 -0
  178. package/lib/datasource/unified-validation-run-resolve.js +43 -0
  179. package/lib/datasource/unified-validation-run.js +92 -0
  180. package/lib/datasource/validate.js +162 -15
  181. package/lib/deployment/deployer.js +4 -3
  182. package/lib/deployment/environment.js +7 -6
  183. package/lib/deployment/push.js +17 -8
  184. package/lib/external-system/delete.js +4 -3
  185. package/lib/external-system/deploy.js +131 -53
  186. package/lib/external-system/download-helpers.js +1 -1
  187. package/lib/external-system/download.js +7 -6
  188. package/lib/external-system/generator.js +104 -14
  189. package/lib/external-system/integration-test-dispatch.js +26 -0
  190. package/lib/external-system/test-execution.js +5 -1
  191. package/lib/external-system/test-helpers.js +0 -4
  192. package/lib/external-system/test-system-level-helpers.js +110 -0
  193. package/lib/external-system/test-system-level.js +83 -44
  194. package/lib/external-system/test.js +59 -8
  195. package/lib/generator/builders.js +23 -11
  196. package/lib/generator/deploy-manifest-azure-kv.js +81 -0
  197. package/lib/generator/external-controller-manifest.js +3 -3
  198. package/lib/generator/external.js +23 -11
  199. package/lib/generator/helpers.js +71 -12
  200. package/lib/generator/index.js +8 -4
  201. package/lib/generator/split-readme.js +12 -7
  202. package/lib/generator/split-variables.js +2 -1
  203. package/lib/generator/split.js +46 -11
  204. package/lib/generator/wizard-readme.js +3 -3
  205. package/lib/generator/wizard.js +16 -13
  206. package/lib/infrastructure/compose.js +60 -6
  207. package/lib/infrastructure/helpers.js +238 -51
  208. package/lib/infrastructure/index.js +64 -37
  209. package/lib/infrastructure/services.js +21 -15
  210. package/lib/internal/fs-real-sync.js +104 -0
  211. package/lib/internal/node-fs.js +98 -0
  212. package/lib/parameters/database-secret-values.js +173 -0
  213. package/lib/parameters/infra-kv-discovery.js +121 -0
  214. package/lib/parameters/infra-parameter-catalog.js +458 -0
  215. package/lib/parameters/infra-parameter-validate.js +64 -0
  216. package/lib/schema/application-schema.json +37 -17
  217. package/lib/schema/datasource-test-run.schema.json +493 -0
  218. package/lib/schema/deployment-rules.yaml +102 -63
  219. package/lib/schema/external-datasource.schema.json +1201 -433
  220. package/lib/schema/external-system.schema.json +181 -5
  221. package/lib/schema/flag-map-validation-run.json +31 -0
  222. package/lib/schema/infra-parameter.schema.json +106 -0
  223. package/lib/schema/infra.parameter.yaml +421 -0
  224. package/lib/schema/type/credential-auth-templates.json +40 -0
  225. package/lib/schema/type/document-storage.json +213 -0
  226. package/lib/schema/type/message-service.json +123 -0
  227. package/lib/schema/type/vector-store.json +88 -0
  228. package/lib/utils/aifabrix-runtime-config-dir.js +132 -0
  229. package/lib/utils/api-error-handler.js +2 -2
  230. package/lib/utils/api.js +49 -14
  231. package/lib/utils/app-config-resolver.js +23 -1
  232. package/lib/utils/app-register-api.js +3 -2
  233. package/lib/utils/app-register-auth.js +1 -1
  234. package/lib/utils/app-register-config.js +4 -4
  235. package/lib/utils/app-register-display.js +3 -2
  236. package/lib/utils/app-register-validator.js +3 -2
  237. package/lib/utils/app-run-containers.js +26 -22
  238. package/lib/utils/app-scoped-config.js +31 -0
  239. package/lib/utils/app-service-env-from-builder.js +164 -0
  240. package/lib/utils/build-copy.js +1 -1
  241. package/lib/utils/build-helpers.js +20 -20
  242. package/lib/utils/build-resolve-image.js +165 -0
  243. package/lib/utils/cli-layout-chalk.js +8 -0
  244. package/lib/utils/cli-test-layout-chalk.js +267 -0
  245. package/lib/utils/cli-utils.js +88 -11
  246. package/lib/utils/compose-db-passwords.js +138 -0
  247. package/lib/utils/compose-generate-docker-compose.js +216 -0
  248. package/lib/utils/compose-generator.js +197 -291
  249. package/lib/utils/compose-miso-env.js +18 -0
  250. package/lib/utils/compose-traefik-ingress-base.js +158 -0
  251. package/lib/utils/config-paths.js +209 -6
  252. package/lib/utils/config-scoped-resources-preference.js +41 -0
  253. package/lib/utils/controller-deployment-outcome.js +68 -0
  254. package/lib/utils/credential-display.js +2 -2
  255. package/lib/utils/credential-secrets-env.js +16 -1
  256. package/lib/utils/dataplane-pipeline-warning.js +4 -3
  257. package/lib/utils/datasource-test-run-capability-scope.js +43 -0
  258. package/lib/utils/datasource-test-run-debug-display.js +137 -0
  259. package/lib/utils/datasource-test-run-debug-slice.js +93 -0
  260. package/lib/utils/datasource-test-run-display.js +442 -0
  261. package/lib/utils/datasource-test-run-exit.js +58 -0
  262. package/lib/utils/datasource-test-run-legacy-adapter.js +93 -0
  263. package/lib/utils/datasource-test-run-report-version.js +51 -0
  264. package/lib/utils/datasource-test-run-schema-sync.js +59 -0
  265. package/lib/utils/datasource-test-run-tty-log.js +81 -0
  266. package/lib/utils/datasource-validation-watch.js +266 -0
  267. package/lib/utils/declarative-url-ports.js +47 -0
  268. package/lib/utils/derive-env-key-from-client-id.js +41 -0
  269. package/lib/utils/dev-ca-install.js +185 -23
  270. package/lib/utils/dev-cert-helper.js +266 -17
  271. package/lib/utils/dev-hosts-helper.js +307 -0
  272. package/lib/utils/dev-init-cert-hints.js +37 -0
  273. package/lib/utils/dev-init-health-messages.js +52 -0
  274. package/lib/utils/dev-init-resolve.js +86 -0
  275. package/lib/utils/dev-init-ssh-merge.js +65 -0
  276. package/lib/utils/dev-ssh-config-helper.js +196 -0
  277. package/lib/utils/dev-user-groups.js +93 -0
  278. package/lib/utils/docker-build.js +42 -17
  279. package/lib/utils/docker-exec.js +28 -0
  280. package/lib/utils/docker-manifest-public-port.js +116 -0
  281. package/lib/utils/docker-not-running-hint.js +52 -0
  282. package/lib/utils/docker.js +98 -11
  283. package/lib/utils/ensure-dev-certs-for-remote-docker.js +192 -0
  284. package/lib/utils/env-config-loader.js +10 -91
  285. package/lib/utils/env-copy.js +19 -10
  286. package/lib/utils/env-map.js +42 -11
  287. package/lib/utils/env-template.js +2 -2
  288. package/lib/utils/environment-scoped-resources.js +144 -0
  289. package/lib/utils/error-formatter.js +125 -9
  290. package/lib/utils/error-formatters/http-status-errors.js +6 -5
  291. package/lib/utils/error-formatters/network-errors.js +2 -1
  292. package/lib/utils/error-formatters/permission-errors.js +2 -1
  293. package/lib/utils/error-formatters/validation-errors.js +2 -1
  294. package/lib/utils/external-env-template.js +180 -0
  295. package/lib/utils/external-readme.js +8 -1
  296. package/lib/utils/external-system-display.js +277 -136
  297. package/lib/utils/external-system-local-test-tty.js +389 -0
  298. package/lib/utils/external-system-readiness-core.js +377 -0
  299. package/lib/utils/external-system-readiness-deploy-display.js +270 -0
  300. package/lib/utils/external-system-readiness-display-internals.js +150 -0
  301. package/lib/utils/external-system-readiness-display.js +186 -0
  302. package/lib/utils/external-system-test-helpers.js +24 -6
  303. package/lib/utils/external-system-validators.js +32 -14
  304. package/lib/utils/health-check-url.js +119 -0
  305. package/lib/utils/health-check.js +59 -25
  306. package/lib/utils/help-builder.js +14 -13
  307. package/lib/utils/image-version.js +4 -8
  308. package/lib/utils/infra-containers.js +4 -7
  309. package/lib/utils/infra-env-defaults.js +162 -0
  310. package/lib/utils/infra-status-display.js +167 -0
  311. package/lib/utils/infra-status.js +16 -8
  312. package/lib/utils/local-secrets.js +29 -7
  313. package/lib/utils/paths.js +136 -48
  314. package/lib/utils/port-resolver.js +10 -23
  315. package/lib/utils/redis-env-scope.js +62 -0
  316. package/lib/utils/register-aifabrix-shell-env.js +204 -0
  317. package/lib/utils/remote-builder-validation.js +99 -0
  318. package/lib/utils/remote-dev-auth.js +117 -21
  319. package/lib/utils/remote-docker-env.js +67 -15
  320. package/lib/utils/remote-secrets-loader.js +13 -4
  321. package/lib/utils/resolve-docker-image-ref.js +124 -0
  322. package/lib/utils/schema-loader.js +22 -9
  323. package/lib/utils/secrets-bash-kv.js +25 -0
  324. package/lib/utils/secrets-generator.js +171 -51
  325. package/lib/utils/secrets-helpers.js +70 -59
  326. package/lib/utils/secrets-kv-scope.js +60 -0
  327. package/lib/utils/secrets-utils.js +35 -37
  328. package/lib/utils/secrets-validation.js +3 -1
  329. package/lib/utils/secrets-yaml-preserve.js +109 -0
  330. package/lib/utils/secure-file-permissions.js +91 -0
  331. package/lib/utils/ssh-key-helper.js +4 -2
  332. package/lib/utils/template-helpers.js +2 -2
  333. package/lib/utils/test-log-writer.js +3 -3
  334. package/lib/utils/token-manager.js +37 -5
  335. package/lib/utils/url-declarative-public-base.js +188 -0
  336. package/lib/utils/url-declarative-resolve-build.js +493 -0
  337. package/lib/utils/url-declarative-resolve-load-doc.js +51 -0
  338. package/lib/utils/url-declarative-resolve.js +220 -0
  339. package/lib/utils/url-declarative-token-parse.js +74 -0
  340. package/lib/utils/url-declarative-url-flags.js +50 -0
  341. package/lib/utils/url-declarative-vdir-inactive-env.js +99 -0
  342. package/lib/utils/url-public-path-prefix.js +34 -0
  343. package/lib/utils/urls-local-registry.js +220 -0
  344. package/lib/utils/validation-report-tty-kit.js +77 -0
  345. package/lib/utils/validation-run-poll.js +89 -0
  346. package/lib/utils/validation-run-post-retry.js +73 -0
  347. package/lib/utils/validation-run-request.js +98 -0
  348. package/lib/utils/variable-transformer.js +21 -4
  349. package/lib/utils/yaml-preserve.js +78 -1
  350. package/lib/validation/datasource-warnings.js +56 -0
  351. package/lib/validation/env-template-auth.js +50 -2
  352. package/lib/validation/external-manifest-validator.js +35 -7
  353. package/lib/validation/validate-display.js +37 -31
  354. package/lib/validation/validate.js +9 -10
  355. package/lib/validation/validator-unresolved-placeholders.js +98 -0
  356. package/lib/validation/validator.js +32 -78
  357. package/lib/validation/wizard-config-validator.js +2 -1
  358. package/package.json +11 -3
  359. package/scripts/check-datasource-test-run-schema-sync.js +34 -0
  360. package/scripts/diagnose-cli.js +150 -0
  361. package/scripts/install-local.js +304 -55
  362. package/templates/README.md +15 -2
  363. package/templates/applications/dataplane/application.yaml +52 -2
  364. package/templates/applications/dataplane/env.template +80 -18
  365. package/templates/applications/dataplane/rbac.yaml +8 -0
  366. package/templates/applications/keycloak/application.yaml +9 -1
  367. package/templates/applications/keycloak/env.template +15 -6
  368. package/templates/applications/miso-controller/application.yaml +10 -2
  369. package/templates/applications/miso-controller/env.template +55 -14
  370. package/templates/applications/miso-controller/rbac.yaml +5 -0
  371. package/templates/external-system/README.md.hbs +20 -7
  372. package/templates/external-system/deploy.js.hbs +5 -5
  373. package/templates/external-system/env.template.hbs +22 -0
  374. package/templates/external-system/external-datasource.yaml.hbs +197 -118
  375. package/templates/infra/compose.yaml.hbs +20 -4
  376. package/templates/python/docker-compose.hbs +16 -0
  377. package/templates/typescript/docker-compose.hbs +16 -0
  378. package/integration/hubspot/README.md +0 -102
  379. package/integration/hubspot/env.template +0 -4
  380. package/integration/hubspot/hubspot-datasource-company.json +0 -541
  381. package/integration/hubspot/hubspot-datasource-contact.json +0 -639
  382. package/integration/hubspot/hubspot-datasource-deal.json +0 -588
  383. package/integration/hubspot/hubspot-datasource-users.json +0 -116
  384. package/integration/hubspot/test-artifacts/wizard-invalid-missing-source.yaml +0 -2
  385. package/integration/hubspot/test-artifacts/wizard-valid-for-dimension-key-test.yaml +0 -5
  386. package/integration/hubspot/test-artifacts/wizard-valid-for-dimension-path-test.yaml +0 -5
  387. package/lib/api/external-test.api.js +0 -111
  388. package/lib/schema/env-config.yaml +0 -43
  389. /package/integration/{hubspot → hubspot-test}/companies.json +0 -0
  390. /package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-app-name.yaml +0 -0
  391. /package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-missing-app.yaml +0 -0
  392. /package/integration/{hubspot → hubspot-test}/test-dataplane-down-helpers.js +0 -0
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @fileoverview Service users API functions (create service user with one-time secret)
2
+ * @fileoverview Service users API functions (create, list, rotate-secret, delete, update)
3
3
  * @author AI Fabrix Team
4
4
  * @version 2.0.0
5
5
  */
@@ -36,6 +36,115 @@ async function createServiceUser(controllerUrl, authConfig, body) {
36
36
  });
37
37
  }
38
38
 
39
+ /**
40
+ * List service users with optional pagination and search
41
+ * GET /api/v1/service-users
42
+ * @requiresPermission {Controller} service-user:read
43
+ * @async
44
+ * @function listServiceUsers
45
+ * @param {string} controllerUrl - Controller base URL
46
+ * @param {Object} authConfig - Authentication configuration (bearer or client-credentials)
47
+ * @param {Object} [options] - Query options
48
+ * @param {number} [options.page] - Page number
49
+ * @param {number} [options.pageSize] - Items per page
50
+ * @param {string} [options.sort] - Sort field/direction
51
+ * @param {string} [options.filter] - Filter expression
52
+ * @param {string} [options.search] - Search term
53
+ * @returns {Promise<Object>} Response with data (array), meta, links
54
+ * @throws {Error} If request fails (401/403 or network)
55
+ */
56
+ async function listServiceUsers(controllerUrl, authConfig, options = {}) {
57
+ const client = new ApiClient(controllerUrl, authConfig);
58
+ const params = {};
59
+ if (options.page !== undefined && options.page !== null) params.page = options.page;
60
+ if (options.pageSize !== undefined && options.pageSize !== null) params.pageSize = options.pageSize;
61
+ if (options.sort) params.sort = options.sort;
62
+ if (options.filter) params.filter = options.filter;
63
+ if (options.search) params.search = options.search;
64
+ return await client.get('/api/v1/service-users', { params });
65
+ }
66
+
67
+ /**
68
+ * Regenerate (rotate) secret for a service user. New secret is returned once only.
69
+ * POST /api/v1/service-users/{id}/regenerate-secret
70
+ * @requiresPermission {Controller} service-user:update
71
+ * @async
72
+ * @function regenerateSecretServiceUser
73
+ * @param {string} controllerUrl - Controller base URL
74
+ * @param {Object} authConfig - Authentication configuration
75
+ * @param {string} id - Service user ID (UUID)
76
+ * @returns {Promise<Object>} Response with data.clientSecret
77
+ * @throws {Error} If request fails (401/403/404 or network)
78
+ */
79
+ async function regenerateSecretServiceUser(controllerUrl, authConfig, id) {
80
+ const client = new ApiClient(controllerUrl, authConfig);
81
+ return await client.post(`/api/v1/service-users/${encodeURIComponent(id)}/regenerate-secret`);
82
+ }
83
+
84
+ /**
85
+ * Delete (deactivate) a service user
86
+ * DELETE /api/v1/service-users/{id}
87
+ * @requiresPermission {Controller} service-user:delete
88
+ * @async
89
+ * @function deleteServiceUser
90
+ * @param {string} controllerUrl - Controller base URL
91
+ * @param {Object} authConfig - Authentication configuration
92
+ * @param {string} id - Service user ID (UUID)
93
+ * @returns {Promise<Object>} Response (data may be null)
94
+ * @throws {Error} If request fails (401/403/404 or network)
95
+ */
96
+ async function deleteServiceUser(controllerUrl, authConfig, id) {
97
+ const client = new ApiClient(controllerUrl, authConfig);
98
+ return await client.delete(`/api/v1/service-users/${encodeURIComponent(id)}`);
99
+ }
100
+
101
+ /**
102
+ * Update group assignments for a service user
103
+ * PUT /api/v1/service-users/{id}/groups
104
+ * @requiresPermission {Controller} service-user:update
105
+ * @async
106
+ * @function updateGroupsServiceUser
107
+ * @param {string} controllerUrl - Controller base URL
108
+ * @param {Object} authConfig - Authentication configuration
109
+ * @param {string} id - Service user ID (UUID)
110
+ * @param {Object} body - Request body
111
+ * @param {string[]} body.groupNames - Group names to set
112
+ * @returns {Promise<Object>} Response with data.id, data.groupNames
113
+ * @throws {Error} If request fails (400/401/403/404 or network)
114
+ */
115
+ async function updateGroupsServiceUser(controllerUrl, authConfig, id, body) {
116
+ const client = new ApiClient(controllerUrl, authConfig);
117
+ return await client.put(`/api/v1/service-users/${encodeURIComponent(id)}/groups`, {
118
+ body: { groupNames: body.groupNames }
119
+ });
120
+ }
121
+
122
+ /**
123
+ * Update redirect URIs for a service user (min 1). Controller merges in its callback URL.
124
+ * PUT /api/v1/service-users/{id}/redirect-uris
125
+ * @requiresPermission {Controller} service-user:update
126
+ * @async
127
+ * @function updateRedirectUrisServiceUser
128
+ * @param {string} controllerUrl - Controller base URL
129
+ * @param {Object} authConfig - Authentication configuration
130
+ * @param {string} id - Service user ID (UUID)
131
+ * @param {Object} body - Request body
132
+ * @param {string[]} body.redirectUris - Redirect URIs (min 1)
133
+ * @returns {Promise<Object>} Response with data.id, data.redirectUris
134
+ * @throws {Error} If request fails (400/401/403/404 or network)
135
+ */
136
+ async function updateRedirectUrisServiceUser(controllerUrl, authConfig, id, body) {
137
+ const client = new ApiClient(controllerUrl, authConfig);
138
+ return await client.put(`/api/v1/service-users/${encodeURIComponent(id)}/redirect-uris`, {
139
+ body: { redirectUris: body.redirectUris }
140
+ });
141
+ }
142
+
39
143
  module.exports = {
40
- createServiceUser
144
+ createServiceUser,
145
+ listServiceUsers,
146
+ regenerateSecretServiceUser,
147
+ deleteServiceUser,
148
+ updateGroupsServiceUser,
149
+ updateRedirectUrisServiceUser
41
150
  };
@@ -27,10 +27,11 @@
27
27
  * @typedef {Object} SettingsResponseDto
28
28
  * @property {string} user-mutagen-folder - Server path to workspace root (no app segment)
29
29
  * @property {string} secrets-encryption - Encryption key (hex)
30
- * @property {string} aifabrix-secrets - Path or URL for secrets
30
+ * @property {string} aifabrix-secrets - Local filesystem path or https URL for shared secrets (file vs remote API)
31
31
  * @property {string} aifabrix-env-config - Env config path
32
32
  * @property {string} remote-server - Builder-server base URL
33
33
  * @property {string} docker-endpoint - Docker API endpoint
34
+ * @property {boolean} [docker-tls-skip-verify] - When true and ca.pem is absent, Docker uses DOCKER_TLS_VERIFY=0; if ca.pem exists, daemon is always verified
34
35
  * @property {string} sync-ssh-user - SSH user for Mutagen
35
36
  * @property {string} sync-ssh-host - SSH host for Mutagen
36
37
  */
@@ -44,7 +45,7 @@
44
45
  * @property {string} createdAt - ISO 8601
45
46
  * @property {boolean} certificateIssued - Whether cert was issued
46
47
  * @property {string} [certificateValidNotAfter] - Cert validity end (optional)
47
- * @property {string[]} groups - Access groups (admin, secret-manager, developer)
48
+ * @property {string[]} groups - Access groups (admin, secret-manager, developer, docker)
48
49
  */
49
50
 
50
51
  /**
@@ -53,7 +54,7 @@
53
54
  * @property {string} developerId - Unique developer ID (numeric string)
54
55
  * @property {string} name - Display name
55
56
  * @property {string} email - Email
56
- * @property {string[]} [groups] - Default [developer]
57
+ * @property {string[]} [groups] - Default [developer]; tokens: admin, secret-manager, developer, docker
57
58
  */
58
59
 
59
60
  /**
@@ -131,13 +131,16 @@
131
131
  */
132
132
 
133
133
  /**
134
- * Dataplane pipeline upload response (publication result; no uploadId).
134
+ * Dataplane pipeline upload API envelope (makeApiCall / ApiClient).
135
+ * Body in `data` matches dataplane PublicationResult (uploadId, uploadStatus, system, datasources, generateMcpContract, …).
135
136
  * @typedef {Object} PipelineUploadResponse
136
137
  * @property {boolean} success - Request success flag
137
- * @property {Object} [data] - Publication result (system, datasources, warnings)
138
- * @property {string} [data.systemKey] - Published system key
139
- * @property {string[]} [data.datasourceKeys] - Published datasource keys
140
- * @property {string[]} [data.warnings] - Warnings if any
138
+ * @property {Object} [data] - PublicationResult from dataplane (not a generic wrapper with datasourceKeys/warnings)
139
+ * @property {string} [data.uploadId] - Upload / publication id
140
+ * @property {string} [data.uploadStatus] - e.g. published
141
+ * @property {Object} [data.system] - Published external system
142
+ * @property {Object[]} [data.datasources] - Published datasources
143
+ * @property {boolean} [data.generateMcpContract] - MCP generation flag
141
144
  * @property {string} [formattedError] - Formatted error message on failure
142
145
  */
143
146
 
@@ -22,3 +22,44 @@
22
22
  * @property {boolean} [success] - Optional wrapper flag
23
23
  * @property {string} [createdAt] - Optional creation timestamp (ISO 8601)
24
24
  */
25
+
26
+ /**
27
+ * Single service user item in list response
28
+ * @typedef {Object} ListServiceUserItem
29
+ * @property {string} id - Service user ID (UUID)
30
+ * @property {string} [username] - Username
31
+ * @property {string} [email] - Email
32
+ * @property {string} [clientId] - OAuth2 client ID
33
+ * @property {boolean} [active] - Whether the service user is active
34
+ */
35
+
36
+ /**
37
+ * List service users response (Controller GET /api/v1/service-users)
38
+ * @typedef {Object} ListServiceUsersResponse
39
+ * @property {ListServiceUserItem[]} data - Array of service users
40
+ * @property {Object} [meta] - Pagination metadata (e.g. total, page, pageSize)
41
+ * @property {Object} [links] - Pagination links
42
+ */
43
+
44
+ /**
45
+ * Regenerate secret response (Controller POST .../regenerate-secret). clientSecret is one-time-only.
46
+ * @typedef {Object} RegenerateSecretServiceUserResponse
47
+ * @property {Object} data - Response data
48
+ * @property {string} data.clientSecret - New client secret (shown once only)
49
+ */
50
+
51
+ /**
52
+ * Update groups response (Controller PUT .../groups)
53
+ * @typedef {Object} UpdateGroupsServiceUserResponse
54
+ * @property {Object} data - Response data
55
+ * @property {string} data.id - Service user ID
56
+ * @property {string[]} data.groupNames - Updated group names
57
+ */
58
+
59
+ /**
60
+ * Update redirect URIs response (Controller PUT .../redirect-uris)
61
+ * @typedef {Object} UpdateRedirectUrisServiceUserResponse
62
+ * @property {Object} data - Response data
63
+ * @property {string} data.id - Service user ID
64
+ * @property {string[]} data.redirectUris - Updated redirect URIs
65
+ */
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @fileoverview JSDoc types for unified validation run (POST /api/v1/validation/run).
3
+ * @author AI Fabrix Team
4
+ * @version 2.0.0
5
+ */
6
+
7
+ /**
8
+ * @typedef {'externalSystem'|'externalDataSource'} ValidationScope
9
+ */
10
+
11
+ /**
12
+ * @typedef {'test'|'integration'|'e2e'} ValidationRunKind
13
+ */
14
+
15
+ /**
16
+ * Request body for POST /api/v1/validation/run (camelCase; see Dataplane OpenAPI).
17
+ * @typedef {Object} ValidationRunRequestBody
18
+ * @property {string} [systemIdOrKey]
19
+ * @property {string} [systemKey]
20
+ * @property {string[]} [datasourceKeys]
21
+ * @property {string} [datasourceKey]
22
+ * @property {boolean} [explain]
23
+ * @property {boolean} [includeLiveChecks]
24
+ * @property {boolean} [includeLiveDebug]
25
+ * @property {boolean} [showCapabilities]
26
+ * @property {boolean} [explainMetrics]
27
+ * @property {boolean} [explainCertification]
28
+ * @property {boolean} [includeMetrics]
29
+ * @property {boolean} [includeCertification]
30
+ * @property {Object} [systemConfig]
31
+ * @property {Object[]} [datasourceConfigs]
32
+ * @property {ValidationScope} [validationScope]
33
+ * @property {ValidationRunKind} [runType]
34
+ * @property {Object} [payloadTemplate]
35
+ * @property {boolean} [asyncRun]
36
+ * @property {Object} [e2eOptions]
37
+ * @property {boolean} [includeDebug]
38
+ */
39
+
40
+ /**
41
+ * Minimal DatasourceTestRun shape for CLI exit / display (full schema in lib/schema).
42
+ * @typedef {Object} DatasourceTestRunLike
43
+ * @property {string} [reportVersion]
44
+ * @property {string} datasourceKey
45
+ * @property {string} systemKey
46
+ * @property {ValidationRunKind} runType
47
+ * @property {'ok'|'warn'|'fail'|'skipped'} status
48
+ * @property {'minimal'|'partial'|'full'} [reportCompleteness]
49
+ * @property {string} [runId]
50
+ * @property {string} [testRunId]
51
+ * @property {Object} [certificate]
52
+ * @property {string} [certificate.status]
53
+ * @property {Object} [developer]
54
+ */
55
+
56
+ module.exports = {};
@@ -0,0 +1,99 @@
1
+ /**
2
+ * @fileoverview Unified dataplane validation API — POST /api/v1/validation/run and poll GET.
3
+ * @author AI Fabrix Team
4
+ * @version 2.0.0
5
+ */
6
+
7
+ const { ApiClient } = require('./index');
8
+
9
+ const POST_PATH = '/api/v1/validation/run';
10
+
11
+ function buildClientCredentialHeaders(authConfig) {
12
+ if (!authConfig || typeof authConfig !== 'object') return null;
13
+ if (authConfig.type !== 'client-credentials') return null;
14
+ if (!authConfig.clientId || !authConfig.clientSecret) return null;
15
+ return {
16
+ 'x-client-id': String(authConfig.clientId),
17
+ 'x-client-secret': String(authConfig.clientSecret)
18
+ };
19
+ }
20
+
21
+ /**
22
+ * Normalize auth for dataplane: Bearer user token, x-client-token app token, or API key as Bearer.
23
+ * @param {Object} authConfig - Auth configuration
24
+ * @returns {Object} Auth for ApiClient
25
+ */
26
+ function normalizeDataplaneAuth(authConfig) {
27
+ if (!authConfig || typeof authConfig !== 'object') {
28
+ throw new Error('authConfig is required');
29
+ }
30
+ if (authConfig.token) {
31
+ return authConfig;
32
+ }
33
+ if (authConfig.apiKey) {
34
+ return { ...authConfig, token: authConfig.apiKey, type: authConfig.type || 'bearer' };
35
+ }
36
+ throw new Error(
37
+ 'Validation run requires Bearer token or API key. Run \'aifabrix login\' or configure API key.'
38
+ );
39
+ }
40
+
41
+ /**
42
+ * @requiresPermission {Dataplane} external-system:read
43
+ * @async
44
+ * @function postValidationRun
45
+ * @param {string} dataplaneUrl - Dataplane base URL
46
+ * @param {Object} authConfig - Authentication (token or apiKey)
47
+ * @param {import('./types/validation-run.types').ValidationRunRequestBody} body - Request JSON body
48
+ * @returns {Promise<Object>} ApiClient result: { success, data, status, ... }
49
+ */
50
+ async function postValidationRun(dataplaneUrl, authConfig, body) {
51
+ const hdrs = buildClientCredentialHeaders(authConfig);
52
+ const clientAuth = hdrs ? {} : normalizeDataplaneAuth(authConfig);
53
+ const client = new ApiClient(dataplaneUrl, clientAuth);
54
+ return client.post(POST_PATH, { body, headers: hdrs || undefined });
55
+ }
56
+
57
+ /**
58
+ * @requiresPermission {Dataplane} external-system:read
59
+ * @async
60
+ * @function getValidationRun
61
+ * @param {string} dataplaneUrl - Dataplane base URL
62
+ * @param {Object} authConfig - Authentication
63
+ * @param {string} testRunId - Poll id from 202 / envelope
64
+ * @returns {Promise<Object>} ApiClient result
65
+ */
66
+ async function getValidationRun(dataplaneUrl, authConfig, testRunId) {
67
+ if (!testRunId || typeof testRunId !== 'string') {
68
+ throw new Error('testRunId is required for validation run poll');
69
+ }
70
+ const hdrs = buildClientCredentialHeaders(authConfig);
71
+ const clientAuth = hdrs ? {} : normalizeDataplaneAuth(authConfig);
72
+ const client = new ApiClient(dataplaneUrl, clientAuth);
73
+ const path = `${POST_PATH}/${encodeURIComponent(testRunId)}`;
74
+ return client.get(path, { headers: hdrs || undefined });
75
+ }
76
+
77
+ /**
78
+ * Extract async poll id from POST 202 body or partial DatasourceTestRun.
79
+ * @param {Object} data - Parsed JSON body
80
+ * @returns {string|null}
81
+ */
82
+ function extractTestRunId(data) {
83
+ if (!data || typeof data !== 'object') return null;
84
+ if (typeof data.testRunId === 'string' && data.testRunId.trim()) return data.testRunId.trim();
85
+ if (data.testRunId && typeof data.testRunId === 'object') {
86
+ const id = data.testRunId.id || data.testRunId.key;
87
+ if (typeof id === 'string' && id.trim()) return id.trim();
88
+ }
89
+ return null;
90
+ }
91
+
92
+ module.exports = {
93
+ postValidationRun,
94
+ getValidationRun,
95
+ extractTestRunId,
96
+ normalizeDataplaneAuth,
97
+ buildClientCredentialHeaders,
98
+ POST_PATH
99
+ };
@@ -0,0 +1,99 @@
1
+ /**
2
+ * @fileoverview Single reusable module for unified validation POST + optional poll.
3
+ *
4
+ * Used by datasource- and system-scoped CLI flows to enforce plan §9 behavior consistently.
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { extractTestRunId } = require('./validation-run.api');
10
+ const { postValidationRunWithTransportRetry } = require('../utils/validation-run-post-retry');
11
+ const { pollValidationRunUntilComplete } = require('../utils/validation-run-poll');
12
+
13
+ /**
14
+ * POST /api/v1/validation/run and (when async) poll GET until reportCompleteness is full.
15
+ *
16
+ * @param {Object} opts
17
+ * @param {string} opts.dataplaneUrl
18
+ * @param {Object} opts.authConfig
19
+ * @param {Object} opts.body
20
+ * @param {number} opts.timeoutMs
21
+ * @param {boolean} opts.useAsync
22
+ * @param {boolean} opts.noAsync
23
+ * @returns {Promise<{ envelope: Object|null, apiError: Object|null, pollTimedOut: boolean, incompleteNoAsync: boolean }>}
24
+ */
25
+ /* eslint-disable max-lines-per-function, max-statements, complexity -- POST + poll orchestration */
26
+ async function postValidationRunAndOptionalPoll(opts) {
27
+ const { dataplaneUrl, authConfig, body, timeoutMs, useAsync, noAsync } = opts;
28
+ const started = Date.now();
29
+ const postRes = await postValidationRunWithTransportRetry(dataplaneUrl, authConfig, body);
30
+ if (!postRes.success) {
31
+ return {
32
+ envelope: null,
33
+ apiError: postRes,
34
+ pollTimedOut: false,
35
+ incompleteNoAsync: false
36
+ };
37
+ }
38
+
39
+ let envelope = postRes.data;
40
+ const httpStatus = postRes.status;
41
+ const testRunId = extractTestRunId(envelope);
42
+ const completeness = envelope && envelope.reportCompleteness;
43
+ const needsPoll =
44
+ httpStatus === 202 ||
45
+ (testRunId && completeness && completeness !== 'full' && useAsync);
46
+
47
+ if (needsPoll && testRunId) {
48
+ const elapsed = Date.now() - started;
49
+ const remaining = Math.max(0, timeoutMs - elapsed);
50
+ const pollResult = await pollValidationRunUntilComplete({
51
+ dataplaneUrl,
52
+ authConfig,
53
+ testRunId,
54
+ budgetMs: remaining
55
+ });
56
+ if (!pollResult.lastApiResult || !pollResult.lastApiResult.success) {
57
+ return {
58
+ envelope: pollResult.envelope,
59
+ apiError: pollResult.lastApiResult,
60
+ pollTimedOut: pollResult.timedOut,
61
+ incompleteNoAsync: false
62
+ };
63
+ }
64
+ envelope = pollResult.envelope;
65
+ if (pollResult.timedOut) {
66
+ return {
67
+ envelope,
68
+ apiError: null,
69
+ pollTimedOut: true,
70
+ incompleteNoAsync: false
71
+ };
72
+ }
73
+ }
74
+
75
+ if (
76
+ noAsync &&
77
+ envelope &&
78
+ envelope.reportCompleteness &&
79
+ envelope.reportCompleteness !== 'full'
80
+ ) {
81
+ return {
82
+ envelope,
83
+ apiError: null,
84
+ pollTimedOut: false,
85
+ incompleteNoAsync: true
86
+ };
87
+ }
88
+
89
+ return {
90
+ envelope,
91
+ apiError: null,
92
+ pollTimedOut: false,
93
+ incompleteNoAsync: false
94
+ };
95
+ }
96
+ /* eslint-enable max-lines-per-function, max-statements, complexity */
97
+
98
+ module.exports = { postValidationRunAndOptionalPoll };
99
+
package/lib/app/config.js CHANGED
@@ -135,7 +135,7 @@ async function generateEnvTemplateFile(appPath, appName, config, existingEnv) {
135
135
  envTemplate = envResult.template;
136
136
 
137
137
  if (envResult.warnings.length > 0) {
138
- logger.log(chalk.yellow('\n⚠️ Environment conversion warnings:'));
138
+ logger.log(chalk.yellow('\n Environment conversion warnings:'));
139
139
  envResult.warnings.forEach(warning => logger.log(chalk.yellow(` - ${warning}`)));
140
140
  }
141
141
  } else {
@@ -69,9 +69,9 @@ async function displayAppUrlFromController(controllerUrl, envKey, appKey, authCo
69
69
  url = buildAppUrlFromControllerAndPort(controllerUrl, port);
70
70
  }
71
71
  if (url) {
72
- logger.log(chalk.green(` App running at ${url}`));
72
+ logger.log(chalk.green(` App running at ${url}`));
73
73
  } else {
74
- logger.log(chalk.blue(' App deployed. Get URL from controller dashboard.'));
74
+ logger.log(chalk.blue(' App deployed. Get URL from controller dashboard.'));
75
75
  }
76
76
  }
77
77
 
package/lib/app/deploy.js CHANGED
@@ -1,3 +1,4 @@
1
+ const { formatSuccessLine, formatSuccessParagraph } = require('../utils/cli-test-layout-chalk');
1
2
  /**
2
3
  * AI Fabrix Builder Application Deployment Module
3
4
  *
@@ -79,7 +80,7 @@ async function validatePushPrerequisites(appName, registry) {
79
80
  */
80
81
  async function executePush(appName, registry, tags) {
81
82
  if (await pushUtils.checkACRAuthentication(registry)) {
82
- logger.log(chalk.green(`✓ Already authenticated with ${registry}`));
83
+ logger.log(formatSuccessLine(`Already authenticated with ${registry}`));
83
84
  } else {
84
85
  await pushUtils.authenticateACR(registry);
85
86
  }
@@ -98,7 +99,7 @@ async function executePush(appName, registry, tags) {
98
99
  * @param {string} appName - Application name
99
100
  */
100
101
  function verifyPushResult(tags, registry, appName) {
101
- logger.log(chalk.green(`\n✓ Successfully pushed ${tags.length} tag(s) to ${registry}`));
102
+ logger.log(formatSuccessParagraph(`Successfully pushed ${tags.length} tag(s) to ${registry}`));
102
103
  logger.log(chalk.gray(`Image: ${registry}/${appName}:*`));
103
104
  logger.log(chalk.gray(`Tags: ${tags.join(', ')}`));
104
105
  }
@@ -173,7 +174,7 @@ async function generateAndValidateManifest(appName, options = {}) {
173
174
  * @param {string} manifestPath - Path to manifest file
174
175
  */
175
176
  function displayDeploymentInfo(manifest, manifestPath) {
176
- logger.log(chalk.green(`✓ Manifest generated: ${manifestPath}`));
177
+ logger.log(formatSuccessLine(`Manifest generated: ${manifestPath}`));
177
178
  logger.log(chalk.blue(` Key: ${manifest.key}`));
178
179
  logger.log(chalk.blue(` Display Name: ${manifest.displayName}`));
179
180
  logger.log(chalk.blue(` Image: ${manifest.image}`));
@@ -216,8 +217,8 @@ function displayDeploymentResults(result) {
216
217
  logger.log(chalk.blue(` Deployment ID: ${result.deploymentId}`));
217
218
  }
218
219
  if (result.status) {
219
- const statusIcon = result.status.status === 'completed' ? '' :
220
- result.status.status === 'failed' ? '' : '⏳';
220
+ const statusIcon = result.status.status === 'completed' ? '' :
221
+ result.status.status === 'failed' ? '' : '⏳';
221
222
  logger.log(chalk.blue(` Status: ${statusIcon} ${result.status.status}`));
222
223
  }
223
224
  }
@@ -368,7 +369,7 @@ async function executeStandardDeployment(appName, options) {
368
369
  }
369
370
 
370
371
  /**
371
- * Tries external deploy when builder/<app> does not exist but integration/<app> does.
372
+ * Tries external deploy when builder/<appKey> does not exist but integration/<systemKey> does.
372
373
  * @async
373
374
  * @param {string} appName - Application name
374
375
  * @param {Object} options - Deployment options
@@ -1,3 +1,4 @@
1
+ const { formatSuccessParagraph } = require('../utils/cli-test-layout-chalk');
1
2
  /**
2
3
  * Application Display Utilities
3
4
  *
@@ -64,7 +65,7 @@ function displayWebappSuccess(appName, config, envConversionMessage) {
64
65
  * @param {string} appPath - Application path
65
66
  */
66
67
  function displaySuccessMessage(appName, config, envConversionMessage, hasAppFiles = false, appPath = null) {
67
- logger.log(chalk.green('\n✓ Application created successfully!'));
68
+ logger.log(formatSuccessParagraph('Application created successfully!'));
68
69
  logger.log(chalk.blue(`\nApplication: ${appName}`));
69
70
 
70
71
  // Determine location based on app type
@@ -1,3 +1,4 @@
1
+ const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
1
2
  /**
2
3
  * Application Dockerfile Generation
3
4
  *
@@ -74,7 +75,7 @@ async function generateAndCopyDockerfile(appPath, dockerfilePath, config) {
74
75
  const buildConfig = config.build || {};
75
76
  const generatedPath = await build.generateDockerfile(appPath, config.language, config, buildConfig);
76
77
  await fs.copyFile(generatedPath, dockerfilePath);
77
- logger.log(chalk.green('Generated Dockerfile from template'));
78
+ logger.log(formatSuccessLine('Generated Dockerfile from template'));
78
79
  return dockerfilePath;
79
80
  }
80
81
 
@@ -90,7 +91,7 @@ async function generateDockerfileForApp(appName, options = {}) {
90
91
  try {
91
92
  const { isExternal } = await detectAppType(appName);
92
93
  if (isExternal) {
93
- logger.log(chalk.yellow('⚠️ External systems don\'t require Dockerfiles. Skipping...'));
94
+ logger.log(chalk.yellow(' External systems don\'t require Dockerfiles. Skipping...'));
94
95
  return null;
95
96
  }
96
97
  } catch (error) {
package/lib/app/down.js CHANGED
@@ -10,6 +10,7 @@
10
10
  */
11
11
 
12
12
  'use strict';
13
+ const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
13
14
 
14
15
  const chalk = require('chalk');
15
16
  const { exec } = require('child_process');
@@ -104,7 +105,7 @@ async function downApp(appName, options = {}) {
104
105
  logger.log(chalk.yellow(`Removing volume ${volumeName}...`));
105
106
  try {
106
107
  await execAsync(`docker volume rm -f ${volumeName}`);
107
- logger.log(chalk.green(`✓ Volume ${volumeName} removed`));
108
+ logger.log(formatSuccessLine(`Volume ${volumeName} removed`));
108
109
  } catch (volErr) {
109
110
  // Swallow errors for missing volume; provide neutral message
110
111
  logger.log(chalk.gray(`Volume ${volumeName} not found or already removed`));
@@ -1,3 +1,4 @@
1
+ const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
1
2
  /**
2
3
  * Application Helper Utilities
3
4
  *
@@ -21,7 +22,7 @@ const { getIntegrationPath, getBuilderPath } = require('../utils/paths');
21
22
  *
22
23
  * @async
23
24
  * @param {string} appName - Application or external system name
24
- * @throws {Error} If integration/<appName> or builder/<appName> already exists
25
+ * @throws {Error} If integration/<systemKey> or builder/<appKey> already exists
25
26
  */
26
27
  async function validateAppOrExternalNameNotExists(appName) {
27
28
  const integrationPath = getIntegrationPath(appName);
@@ -104,7 +105,7 @@ async function handleGitHubWorkflows(options, config) {
104
105
  }
105
106
  );
106
107
 
107
- logger.log(chalk.green('Generated GitHub Actions workflows:'));
108
+ logger.log(formatSuccessLine('Generated GitHub Actions workflows:'));
108
109
  workflowFiles.forEach(file => logger.log(chalk.gray(` - ${file}`)));
109
110
  }
110
111
 
@@ -157,7 +158,7 @@ async function processTemplateFiles(template, appPath, appName, options, config)
157
158
 
158
159
  await validateTemplate(template);
159
160
  const copiedFiles = await copyTemplateFiles(template, appPath);
160
- logger.log(chalk.green(`✓ Copied ${copiedFiles.length} file(s) from template '${template}'`));
161
+ logger.log(formatSuccessLine(`Copied ${copiedFiles.length} file(s) from template '${template}'`));
161
162
  const { updateTemplateVariables } = require('../utils/template-helpers');
162
163
  await updateTemplateVariables(appPath, appName, options, config);
163
164
  }
@@ -190,7 +191,7 @@ async function updateVariablesForAppFlag(appPath, appName) {
190
191
  writeConfigFile(variablesPath, variables);
191
192
  } catch (error) {
192
193
  if (!error.message.includes('not found')) {
193
- logger.warn(chalk.yellow(`⚠️ Warning: Could not update application config: ${error.message}`));
194
+ logger.warn(chalk.yellow(`⚠ Warning: Could not update application config: ${error.message}`));
194
195
  }
195
196
  }
196
197
  }
@@ -239,7 +240,7 @@ async function setupAppFiles(appName, appPath, config, options) {
239
240
 
240
241
  const language = await getLanguageForAppFiles(config.language || options.language, appPath);
241
242
  const copiedFiles = await copyAppFiles(language, appsPath);
242
- logger.log(chalk.green(`✓ Copied ${copiedFiles.length} application file(s) to apps/${appName}/`));
243
+ logger.log(formatSuccessLine(`Copied ${copiedFiles.length} application file(s) to apps/${appName}/`));
243
244
  }
244
245
 
245
246
  module.exports = {