@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
@@ -10,118 +10,29 @@
10
10
 
11
11
  const chalk = require('chalk');
12
12
  const logger = require('./logger');
13
+ const { SEP, statusGlyph } = require('./datasource-test-run-display');
14
+ const { logEnvelopeForInteractiveCli } = require('./datasource-test-run-tty-log');
15
+ const { displayLocalExternalTestPlanLayout } = require('./external-system-local-test-tty');
16
+ const {
17
+ sectionTitle,
18
+ headerKeyValue,
19
+ formatStatusKeyValue,
20
+ formatDatasourceListRow,
21
+ integrationFooterLine,
22
+ formatSuccessParagraph,
23
+ formatBlockingError,
24
+ successGlyph,
25
+ failureGlyph
26
+ } = require('./cli-test-layout-chalk');
13
27
 
14
28
  /**
15
- * Displays system file results
16
- * @function displaySystemResults
17
- * @param {Object[]} systemResults - System file results
18
- */
19
- function displaySystemResults(systemResults) {
20
- if (systemResults.length === 0) {
21
- return;
22
- }
23
- logger.log(chalk.blue('System Files:'));
24
- for (const systemResult of systemResults) {
25
- if (systemResult.valid) {
26
- logger.log(chalk.green(` ✓ ${systemResult.file}`));
27
- } else {
28
- logger.log(chalk.red(` ✗ ${systemResult.file}`));
29
- }
30
- }
31
- }
32
-
33
- /**
34
- * Displays verbose datasource details
35
- * @function displayVerboseDatasourceDetails
36
- * @param {Object} dsResult - Datasource result
37
- */
38
- function displayVerboseDatasourceDetails(dsResult) {
39
- if (dsResult.warnings.length > 0) {
40
- dsResult.warnings.forEach(warn => logger.log(chalk.yellow(` ⚠ ${warn}`)));
41
- }
42
-
43
- if (dsResult.fieldMappingResults) {
44
- const fm = dsResult.fieldMappingResults;
45
- logger.log(chalk.gray(` Field mappings: ${Object.keys(fm.mappedFields || {}).length} fields`));
46
- }
47
-
48
- if (dsResult.metadataSchemaResults) {
49
- const ms = dsResult.metadataSchemaResults;
50
- const statusMsg = ms.valid ? ' Metadata schema: ✓ Valid' : ' Metadata schema: ✗ Invalid';
51
- logger.log(ms.valid ? chalk.gray(statusMsg) : chalk.red(statusMsg));
52
- }
53
- }
54
-
55
- /**
56
- * Displays datasource file results
57
- * @function displayDatasourceResults
58
- * @param {Object[]} datasourceResults - Datasource file results
59
- * @param {boolean} verbose - Show detailed output
60
- */
61
- function displayDatasourceResults(datasourceResults, verbose) {
62
- if (datasourceResults.length === 0) {
63
- return;
64
- }
65
- logger.log(chalk.blue('\nDatasource Files:'));
66
- for (const dsResult of datasourceResults) {
67
- if (dsResult.valid) {
68
- logger.log(chalk.green(` ✓ ${dsResult.key} (${dsResult.file})`));
69
- } else {
70
- logger.log(chalk.red(` ✗ ${dsResult.key} (${dsResult.file})`));
71
- if (verbose && dsResult.errors.length > 0) {
72
- dsResult.errors.forEach(err => logger.log(chalk.red(` - ${err}`)));
73
- }
74
- }
75
-
76
- if (verbose) {
77
- displayVerboseDatasourceDetails(dsResult);
78
- }
79
- }
80
- }
81
-
82
- /**
83
- * Displays errors and warnings
84
- * @function displayErrorsAndWarnings
85
- * @param {string[]} errors - Error messages
86
- * @param {string[]} warnings - Warning messages
87
- */
88
- function displayErrorsAndWarnings(errors, warnings) {
89
- if (errors.length > 0) {
90
- logger.log(chalk.red('\n❌ Errors:'));
91
- errors.forEach(err => logger.log(chalk.red(` - ${err}`)));
92
- }
93
-
94
- if (warnings.length > 0) {
95
- logger.log(chalk.yellow('\n⚠ Warnings:'));
96
- warnings.forEach(warn => logger.log(chalk.yellow(` - ${warn}`)));
97
- }
98
- }
99
-
100
- /**
101
- * Displays final test status
102
- * @function displayFinalTestStatus
103
- * @param {boolean} valid - Whether all tests passed
104
- */
105
- function displayFinalTestStatus(valid) {
106
- if (valid) {
107
- logger.log(chalk.green('\n✅ All tests passed!'));
108
- } else {
109
- logger.log(chalk.red('\n❌ Some tests failed'));
110
- }
111
- }
112
-
113
- /**
114
- * Displays formatted test results
29
+ * Displays formatted test results (local external `aifabrix test` — structured report layout).
115
30
  * @param {Object} results - Test results
116
31
  * @param {boolean} verbose - Show detailed output
32
+ * @param {string} [appName] - Integration folder / app key for header
117
33
  */
118
- function displayTestResults(results, verbose = false) {
119
- logger.log(chalk.blue('\n📊 Test Results\n'));
120
-
121
- displaySystemResults(results.systemResults);
122
- displayDatasourceResults(results.datasourceResults, verbose);
123
- displayErrorsAndWarnings(results.errors, results.warnings);
124
- displayFinalTestStatus(results.valid);
34
+ function displayTestResults(results, verbose = false, appName = '') {
35
+ displayLocalExternalTestPlanLayout(results, verbose, appName || results.appName || results.systemKey || 'unknown');
125
36
  }
126
37
 
127
38
  /**
@@ -131,9 +42,9 @@ function displayTestResults(results, verbose = false) {
131
42
  */
132
43
  function displayVerboseValidationResults(vr) {
133
44
  if (vr.isValid) {
134
- logger.log(chalk.gray(' Validation: Valid'));
45
+ logger.log(chalk.gray(' Validation: Valid'));
135
46
  } else {
136
- logger.log(chalk.red(' Validation: Invalid'));
47
+ logger.log(chalk.red(' Validation: Invalid'));
137
48
  }
138
49
  if (vr.errors && vr.errors.length > 0) {
139
50
  vr.errors.forEach(err => logger.log(chalk.red(` - ${err}`)));
@@ -163,7 +74,7 @@ function displayVerboseFieldMappingResults(fmr) {
163
74
  */
164
75
  function displayVerboseEndpointResults(etr) {
165
76
  if (etr.endpointConfigured) {
166
- logger.log(chalk.gray(' Endpoint: Configured'));
77
+ logger.log(chalk.gray(' Endpoint: Configured'));
167
78
  } else {
168
79
  logger.log(chalk.gray(' Endpoint: Not configured'));
169
80
  }
@@ -191,54 +102,237 @@ function displayVerboseIntegrationDetails(dsResult) {
191
102
  }
192
103
 
193
104
  /**
194
- * Displays a single datasource integration test result
195
- * @function displayDatasourceIntegrationResult
105
+ * @param {Object} dsResult
106
+ * @returns {'ok'|'warn'|'fail'|'skipped'}
107
+ */
108
+ function legacyIntegrationRowStatus(dsResult) {
109
+ if (dsResult.skipped) return 'skipped';
110
+ if (!dsResult.success) return 'fail';
111
+ const w = dsResult.validationResults && dsResult.validationResults.warnings;
112
+ if (Array.isArray(w) && w.length > 0) return 'warn';
113
+ return 'ok';
114
+ }
115
+
116
+ function legacyIntegrationRowHint(dsResult) {
117
+ if (dsResult.skipped) return dsResult.reason || 'Skipped';
118
+ if (!dsResult.success) return 'Failed';
119
+ return legacyIntegrationRowStatus(dsResult) === 'warn' ? 'Partial' : 'Ready';
120
+ }
121
+
122
+ /**
123
+ * Displays a single datasource integration test result (legacy pipeline row).
196
124
  * @param {Object} dsResult - Datasource result
197
125
  * @param {boolean} verbose - Show detailed output
198
126
  */
199
127
  function displayDatasourceIntegrationResult(dsResult, verbose) {
128
+ const rowSt = legacyIntegrationRowStatus(dsResult);
129
+ const hint = legacyIntegrationRowHint(dsResult);
130
+ logger.log(formatDatasourceListRow(rowSt, dsResult.key, hint));
131
+
132
+ if (!dsResult.skipped && !dsResult.success && dsResult.error) {
133
+ logger.log(chalk.red(` Error: ${dsResult.error}`));
134
+ }
135
+
136
+ if (verbose) {
137
+ displayVerboseIntegrationDetails(dsResult);
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Worst status across server runs (envelope.status or transport failure).
143
+ * @param {Object} results
144
+ * @returns {'ok'|'warn'|'fail'}
145
+ */
146
+ function serverRowFails(r) {
147
+ if (r.skipped) return false;
148
+ if (r.datasourceTestRun && r.datasourceTestRun.status === 'fail') return true;
149
+ return !r.datasourceTestRun && r.success === false;
150
+ }
151
+
152
+ function serverRowWarns(r) {
153
+ if (r.skipped) return false;
154
+ return !!(r.datasourceTestRun && r.datasourceTestRun.status === 'warn');
155
+ }
156
+
157
+ function deriveAggregateServerStatus(results) {
158
+ const ds = results.datasourceResults || [];
159
+ if (ds.length === 0) {
160
+ return results.success === false ? 'fail' : 'ok';
161
+ }
162
+ if (ds.some(serverRowFails)) return 'fail';
163
+ if (ds.some(serverRowWarns)) return 'warn';
164
+ return results.success === false ? 'fail' : 'ok';
165
+ }
166
+
167
+ /**
168
+ * Aggregate status for legacy pipeline integration results (no DatasourceTestRun envelope).
169
+ * @param {Object} results
170
+ * @returns {'ok'|'warn'|'fail'}
171
+ */
172
+ function deriveAggregateLegacyIntegrationStatus(results) {
173
+ const ds = results.datasourceResults || [];
174
+ if (ds.length === 0) {
175
+ return results.success === false ? 'fail' : 'ok';
176
+ }
177
+ if (ds.some(r => !r.skipped && r.success === false)) return 'fail';
178
+ if (ds.some(r => legacyIntegrationRowStatus(r) === 'warn')) return 'warn';
179
+ return results.success === false ? 'fail' : 'ok';
180
+ }
181
+
182
+ function integrationResultsHaveEnvelope(results) {
183
+ return (results.datasourceResults || []).some(
184
+ r => r.datasourceTestRun && typeof r.datasourceTestRun === 'object'
185
+ );
186
+ }
187
+
188
+ /**
189
+ * One datasource with DatasourceTestRun — same display path as `aifabrix datasource test` (no server wrapper).
190
+ * @param {Object} results
191
+ * @returns {boolean}
192
+ */
193
+ function isSingleUnskippedEnvelopeRun(results) {
194
+ const rows = results.datasourceResults || [];
195
+ if (rows.length !== 1) return false;
196
+ const r = rows[0];
197
+ return Boolean(
198
+ r && !r.skipped && r.datasourceTestRun && typeof r.datasourceTestRun === 'object'
199
+ );
200
+ }
201
+
202
+ function runLabelForServerRun(runType) {
203
+ return runType === 'e2e' ? 'test-e2e (dataplane)' : 'test-integration (dataplane)';
204
+ }
205
+
206
+ function renderOneServerDatasourceRow(dsResult, verbose, opts) {
207
+ logger.log('');
208
+ if (!dsResult.datasourceTestRun) {
209
+ logger.log(headerKeyValue('Datasource:', dsResult.key));
210
+ }
200
211
  if (dsResult.skipped) {
201
- logger.log(chalk.yellow(` ⚠ ${dsResult.key}: ${dsResult.reason}`));
212
+ logger.log(formatDatasourceListRow('skipped', dsResult.key, dsResult.reason || 'Skipped'));
213
+ return;
214
+ }
215
+ if (dsResult.datasourceTestRun) {
216
+ logEnvelopeForInteractiveCli(dsResult.datasourceTestRun, {
217
+ json: false,
218
+ summary: false,
219
+ debug: opts.debug,
220
+ requestedCapabilityKey: opts.requestedCapabilityKey
221
+ });
202
222
  return;
203
223
  }
224
+ displayDatasourceIntegrationResult(dsResult, verbose);
225
+ }
204
226
 
205
- if (dsResult.success) {
206
- logger.log(chalk.green(` ✓ ${dsResult.key}`));
207
- } else {
208
- logger.log(chalk.red(` ✗ ${dsResult.key}`));
209
- if (dsResult.error) {
210
- logger.log(chalk.red(` Error: ${dsResult.error}`));
211
- }
227
+ function logServerDatasourceTestRunHeader(results, runType, agg) {
228
+ logger.log('');
229
+ logger.log(sectionTitle('Server test results'));
230
+ logger.log('');
231
+ logger.log(headerKeyValue('System:', results.systemKey));
232
+ logger.log(headerKeyValue('Run:', runLabelForServerRun(runType)));
233
+ logger.log(formatStatusKeyValue(agg, statusGlyph(agg)));
234
+ logger.log('');
235
+ logger.log(chalk.gray(SEP));
236
+ }
237
+
238
+ function logServerDatasourceTestRunFooter(success, agg) {
239
+ logger.log(
240
+ integrationFooterLine(
241
+ success,
242
+ agg,
243
+ 'All server tests passed.',
244
+ 'Server tests completed with warnings.',
245
+ 'Some server tests failed.'
246
+ )
247
+ );
248
+ }
249
+
250
+ /**
251
+ * Dataplane DatasourceTestRun layout (multi- or single-datasource).
252
+ * @param {Object} results
253
+ * @param {boolean} verbose
254
+ * @param {Object} opts
255
+ * @param {boolean|string} [opts.debug]
256
+ * @param {'integration'|'e2e'} [opts.runType]
257
+ */
258
+ function displayServerDatasourceTestRunResults(results, verbose, opts = {}) {
259
+ const runType = opts.runType === 'e2e' ? 'e2e' : 'integration';
260
+
261
+ if (isSingleUnskippedEnvelopeRun(results)) {
262
+ const row = results.datasourceResults[0];
263
+ logEnvelopeForInteractiveCli(row.datasourceTestRun, {
264
+ json: false,
265
+ summary: false,
266
+ debug: opts.debug,
267
+ requestedCapabilityKey: opts.requestedCapabilityKey
268
+ });
269
+ return;
212
270
  }
213
271
 
214
- if (verbose) {
215
- displayVerboseIntegrationDetails(dsResult);
272
+ const agg = deriveAggregateServerStatus(results);
273
+ logServerDatasourceTestRunHeader(results, runType, agg);
274
+
275
+ if (results.datasourceResults.length === 0) {
276
+ logger.log('');
277
+ logger.log(chalk.yellow('No datasources tested'));
278
+ logger.log('');
279
+ return;
216
280
  }
281
+
282
+ for (const dsResult of results.datasourceResults) {
283
+ renderOneServerDatasourceRow(dsResult, verbose, opts);
284
+ logger.log('');
285
+ logger.log(chalk.gray(SEP));
286
+ }
287
+
288
+ logServerDatasourceTestRunFooter(results.success, agg);
217
289
  }
218
290
 
219
291
  /**
220
- * Displays formatted integration test results
292
+ * Displays formatted integration / E2E test results (legacy or DatasourceTestRun TTY).
221
293
  * @param {Object} results - Integration test results
222
294
  * @param {boolean} verbose - Show detailed output
295
+ * @param {Object} [displayOpts]
296
+ * @param {boolean|string} [displayOpts.debug] - Debug appendix for each envelope
297
+ * @param {'integration'|'e2e'} [displayOpts.runType]
298
+ * @param {string} [displayOpts.requestedCapabilityKey]
223
299
  */
224
- function displayIntegrationTestResults(results, verbose = false) {
225
- logger.log(chalk.blue('\n📊 Integration Test Results\n'));
226
- logger.log(chalk.blue(`System: ${results.systemKey}`));
300
+ function displayIntegrationTestResults(results, verbose = false, displayOpts = {}) {
301
+ if (integrationResultsHaveEnvelope(results)) {
302
+ displayServerDatasourceTestRunResults(results, verbose, displayOpts);
303
+ return;
304
+ }
305
+
306
+ const agg = deriveAggregateLegacyIntegrationStatus(results);
307
+ logger.log('');
308
+ logger.log(sectionTitle('Integration test results'));
309
+ logger.log('');
310
+ logger.log(headerKeyValue('System:', results.systemKey));
311
+ logger.log(headerKeyValue('Run:', 'test-integration (pipeline)'));
312
+ logger.log(formatStatusKeyValue(agg, statusGlyph(agg)));
313
+ logger.log('');
314
+ logger.log(chalk.gray(SEP));
227
315
 
228
316
  if (results.datasourceResults.length === 0) {
317
+ logger.log('');
229
318
  logger.log(chalk.yellow('No datasources tested'));
230
319
  return;
231
320
  }
232
321
 
322
+ logger.log('');
233
323
  for (const dsResult of results.datasourceResults) {
234
324
  displayDatasourceIntegrationResult(dsResult, verbose);
235
325
  }
236
326
 
237
- if (results.success) {
238
- logger.log(chalk.green('\n✅ All integration tests passed!'));
239
- } else {
240
- logger.log(chalk.red('\n❌ Some integration tests failed'));
241
- }
327
+ logger.log(
328
+ integrationFooterLine(
329
+ results.success,
330
+ agg,
331
+ 'All integration tests passed.',
332
+ 'Integration tests completed with warnings.',
333
+ 'Some integration tests failed.'
334
+ )
335
+ );
242
336
  }
243
337
 
244
338
  /**
@@ -256,7 +350,9 @@ function displayIntegrationTestResults(results, verbose = false) {
256
350
  */
257
351
  /* eslint-disable max-statements,complexity -- Step iteration and status display */
258
352
  function displayE2EResults(data, verbose = false) {
259
- logger.log(chalk.blue('\n📊 E2E Test Results\n'));
353
+ logger.log('');
354
+ logger.log(sectionTitle('E2E test results'));
355
+ logger.log('');
260
356
  if (data.status) {
261
357
  const statusLabel = data.status === 'running'
262
358
  ? chalk.yellow('running')
@@ -265,12 +361,12 @@ function displayE2EResults(data, verbose = false) {
265
361
  : data.status === 'failed'
266
362
  ? chalk.red('failed')
267
363
  : data.status;
268
- logger.log(`Status: ${statusLabel}`);
364
+ logger.log(`${chalk.gray('Status:')} ${statusLabel}`);
269
365
  }
270
366
  const steps = data.steps || data.completedActions || [];
271
367
  if (steps.length === 0) {
272
368
  if (data.success === false) {
273
- logger.log(chalk.red('E2E test failed'));
369
+ logger.log(formatBlockingError('E2E test failed.'));
274
370
  if (data.error) logger.log(chalk.red(` Error: ${data.error}`));
275
371
  } else if (data.status === 'running') {
276
372
  logger.log(chalk.gray(' No steps completed yet'));
@@ -286,15 +382,60 @@ function displayE2EResults(data, verbose = false) {
286
382
  for (const step of steps) {
287
383
  const name = step.name || step.step || 'unknown';
288
384
  const ok = step.success !== false && !step.error;
289
- logger.log(` ${ok ? chalk.green('✓') : chalk.red('✗')} ${name}`);
385
+ logger.log(` ${ok ? successGlyph() : failureGlyph()} ${chalk.white(name)}`);
290
386
  if (!ok && (step.error || step.message)) logger.log(chalk.red(` ${step.error || step.message}`));
291
387
  if (verbose && step.message && ok) logger.log(chalk.gray(` ${step.message}`));
388
+ if (verbose && ok && (name === 'sync' || step.step === 'sync') && step.evidence && step.evidence.jobs) {
389
+ formatSyncStepEvidence(step.evidence.jobs);
390
+ }
391
+ }
392
+ if (verbose && data.auditLog && Array.isArray(data.auditLog) && data.auditLog.length > 0) {
393
+ const n = data.auditLog.length;
394
+ const first = data.auditLog[0];
395
+ const execId = (first && (first.executionId || first.id || first.traceId)) ? String(first.executionId || first.id || first.traceId) : null;
396
+ if (execId) {
397
+ const short = execId.length > 10 ? `${execId.slice(0, 8)}…` : execId;
398
+ logger.log(chalk.gray(` CIP execution trace(s): ${n} (executionId: ${short})`));
399
+ } else {
400
+ logger.log(chalk.gray(` CIP execution trace(s): ${n}`));
401
+ }
292
402
  }
293
403
  if (isRunning) {
294
404
  return;
295
405
  }
296
406
  const allPassed = steps.every(s => s.success !== false && !s.error);
297
- logger.log(allPassed ? chalk.green('\n✅ E2E test passed!') : chalk.red('\n❌ E2E test failed'));
407
+ logger.log(
408
+ allPassed ? formatSuccessParagraph('E2E test passed.') : `\n${formatBlockingError('E2E test failed.')}`
409
+ );
410
+ }
411
+
412
+ /**
413
+ * Log sync step job evidence (record counts) in verbose E2E output
414
+ * @param {Object[]} jobs - evidence.jobs from sync step
415
+ */
416
+ function formatSyncStepEvidence(jobs) {
417
+ for (const job of jobs) {
418
+ const rec = job.recordsProcessed ?? job.totalProcessed;
419
+ const total = job.totalRecords ?? (job.audit && job.audit.totalProcessed);
420
+ const parts = [];
421
+ if (rec !== undefined && rec !== null) parts.push(`${rec} processed`);
422
+ if (total !== undefined && total !== null) parts.push(`total: ${total}`);
423
+ const audit = job.audit || {};
424
+ const ins = audit.inserted ?? job.insertedCount;
425
+ const upd = audit.updated ?? job.updatedCount;
426
+ const del = audit.deleted ?? job.deletedCount;
427
+ const tot = audit.totalProcessed ?? total;
428
+ if (ins !== undefined || upd !== undefined || del !== undefined || tot !== undefined) {
429
+ const a = [`inserted: ${ins ?? 0}`, `updated: ${upd ?? 0}`, `deleted: ${del ?? 0}`];
430
+ if (tot !== undefined) a.push(`totalProcessed: ${tot}`);
431
+ parts.push(`(${a.join(', ')})`);
432
+ }
433
+ if (job.skippedCount !== undefined) parts.push(`skipped: ${job.skippedCount}`);
434
+ if (job.rejectedByQualityCount !== undefined) parts.push(`rejectedByQuality: ${job.rejectedByQualityCount}`);
435
+ if (parts.length > 0) {
436
+ logger.log(chalk.gray(` Managed records: ${parts.join(' ')}`));
437
+ }
438
+ }
298
439
  }
299
440
 
300
441
  module.exports = {