@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,154 +1,166 @@
1
1
  /**
2
- * Datasource integration test - run config test for one datasource via pipeline
2
+ * Datasource integration test unified dataplane validation (runType=integration).
3
3
  * @fileoverview Datasource integration test logic
4
4
  * @author AI Fabrix Team
5
5
  * @version 2.0.0
6
6
  */
7
- /* eslint-disable max-lines-per-function,max-statements,complexity -- Load config, resolve datasource, call pipeline test */
8
7
 
9
- const path = require('path');
10
8
  const chalk = require('chalk');
11
9
  const logger = require('../utils/logger');
12
- const { getIntegrationPath, resolveIntegrationAppKeyFromCwd } = require('../utils/paths');
13
- const { resolveApplicationConfigPath } = require('../utils/app-config-resolver');
14
- const { loadConfigFile } = require('../utils/config-format');
15
- const { setupIntegrationTestAuth } = require('../external-system/test-auth');
16
- const { getConfig } = require('../core/config');
17
- const { testDatasourceViaPipeline } = require('../api/pipeline.api');
10
+ const { resolveAppKeyForDatasource } = require('./resolve-app');
11
+ const { infoLine } = require('../utils/cli-test-layout-chalk');
12
+ const {
13
+ getSystemKeyFromAppKey,
14
+ findDatasourceFileByKey
15
+ } = require('./integration-context');
16
+ const { runUnifiedDatasourceValidation } = require('./unified-validation-run');
17
+ const { integrationResultFromEnvelope } = require('../utils/datasource-test-run-legacy-adapter');
18
18
  const { writeTestLog } = require('../utils/test-log-writer');
19
- const testHelpers = require('../utils/external-system-test-helpers');
20
- const fs = require('fs').promises;
21
19
 
22
20
  /**
23
- * Resolve systemKey and appKey for datasource test-integration
24
- * @param {string} [appKey] - Explicit app key from --app
25
- * @returns {Promise<{appKey: string, systemKey: string}>}
21
+ * @param {string} appKey - Integration folder name (same as --app; system key in publish flows)
22
+ * @returns {Promise<string>} systemKey
26
23
  */
27
- async function resolveSystemKey(appKey) {
28
- let resolvedAppKey = appKey;
29
- if (!resolvedAppKey) {
30
- resolvedAppKey = resolveIntegrationAppKeyFromCwd();
24
+ async function getSystemKeyFromAppKeyExport(appKey) {
25
+ return getSystemKeyFromAppKey(appKey);
26
+ }
27
+
28
+ function legacyFailureShell(datasourceKey, systemKey, error, datasourceTestRun, runMeta) {
29
+ return {
30
+ key: datasourceKey,
31
+ systemKey,
32
+ success: false,
33
+ skipped: false,
34
+ validationResults: {},
35
+ fieldMappingResults: {},
36
+ endpointTestResults: {},
37
+ error,
38
+ datasourceTestRun,
39
+ runMeta
40
+ };
41
+ }
42
+
43
+ /**
44
+ * @returns {{ body: Object, apiErrMsg?: string }|null}
45
+ */
46
+ function integrationEarlyExitBody(datasourceKey, systemKey, unifiedResult, runMeta) {
47
+ if (unifiedResult.apiError) {
48
+ const errMsg =
49
+ unifiedResult.apiError.formattedError ||
50
+ unifiedResult.apiError.error ||
51
+ 'Request failed';
52
+ return {
53
+ body: legacyFailureShell(datasourceKey, systemKey, errMsg, null, runMeta),
54
+ apiErrMsg: errMsg
55
+ };
31
56
  }
32
- if (!resolvedAppKey) {
33
- throw new Error(
34
- 'Could not determine app context. Use --app <appKey> or run from integration/<appKey>/ directory.'
35
- );
57
+ if (unifiedResult.pollTimedOut) {
58
+ return {
59
+ body: legacyFailureShell(
60
+ datasourceKey,
61
+ systemKey,
62
+ 'Report incomplete: timeout',
63
+ unifiedResult.envelope,
64
+ runMeta
65
+ )
66
+ };
36
67
  }
37
- const appPath = getIntegrationPath(resolvedAppKey);
38
- const configPath = resolveApplicationConfigPath(appPath);
39
- const config = loadConfigFile(configPath);
40
- if (!config.externalIntegration || !config.externalIntegration.systems || config.externalIntegration.systems.length === 0) {
41
- throw new Error(`No externalIntegration.systems found in ${configPath}`);
68
+ if (unifiedResult.incompleteNoAsync) {
69
+ return {
70
+ body: legacyFailureShell(
71
+ datasourceKey,
72
+ systemKey,
73
+ 'Report incomplete (async required)',
74
+ unifiedResult.envelope,
75
+ runMeta
76
+ )
77
+ };
42
78
  }
43
- const systemFile = config.externalIntegration.systems[0];
44
- const systemPath = path.isAbsolute(systemFile)
45
- ? systemFile
46
- : path.join(appPath, systemFile);
47
- const systemContent = await fs.readFile(systemPath, 'utf8');
48
- const yaml = require('js-yaml');
49
- const systemConfig = yaml.load(systemContent);
50
- const systemKey = systemConfig?.key || path.basename(systemFile, '-system.yaml').replace('-system', '');
51
- return { appKey: resolvedAppKey, systemKey };
79
+ return null;
52
80
  }
53
81
 
54
82
  /**
55
- * Run integration test for one datasource
83
+ * Run integration test for one datasource (unified validation API).
56
84
  * @async
57
85
  * @param {string} datasourceKey - Datasource key
58
86
  * @param {Object} options - Options
59
87
  * @param {string} [options.app] - App key (or resolve from cwd)
60
88
  * @param {string} [options.payload] - Path to custom payload file
61
89
  * @param {string} [options.environment] - Environment (dev, tst, pro)
62
- * @param {boolean} [options.debug] - Include debug, write log file
63
- * @param {number} [options.timeout] - Request timeout ms
64
- * @returns {Promise<Object>} Test result
90
+ * @param {boolean} [options.verbose] - explain=true on request
91
+ * @param {boolean|string} [options.debug] - Truthy enables includeDebug and log file; string `summary`|`full`|`raw` selects TTY appendix (CLI)
92
+ * @param {number|string} [options.timeout] - Aggregate timeout ms
93
+ * @param {boolean} [options.sync] - Publish local datasource JSON before validation when true
94
+ * @returns {Promise<Object>} Legacy-shaped result + datasourceTestRun / runMeta when present
65
95
  */
96
+ function logIntegrationDatasourceBanner(datasourceKey, systemKey, verbose) {
97
+ if (!verbose) return;
98
+ logger.log('');
99
+ logger.log(infoLine(`📡 Testing datasource: ${datasourceKey} (system: ${systemKey})`));
100
+ }
101
+
66
102
  async function runDatasourceTestIntegration(datasourceKey, options = {}) {
67
103
  if (!datasourceKey || typeof datasourceKey !== 'string') {
68
104
  throw new Error('Datasource key is required');
69
105
  }
70
- const { appKey, systemKey } = await resolveSystemKey(options.app);
71
- const appPath = getIntegrationPath(appKey);
72
- const config = loadConfigFile(resolveApplicationConfigPath(appPath));
73
- const schemaBasePath = config.externalIntegration?.schemaBasePath || './';
74
- const datasourceFiles = config.externalIntegration?.dataSources || [];
75
- const datasourceFile = datasourceFiles.find(f => {
76
- const base = path.basename(f, path.extname(f));
77
- return base === datasourceKey || base.includes(datasourceKey);
78
- });
79
- if (!datasourceFile) {
80
- throw new Error(`Datasource '${datasourceKey}' not found in application config`);
81
- }
82
- const datasourcePath = path.isAbsolute(schemaBasePath)
83
- ? path.join(schemaBasePath, datasourceFile)
84
- : path.join(appPath, schemaBasePath, datasourceFile);
85
- const datasourceContent = await fs.readFile(datasourcePath, 'utf8');
86
- const datasource = JSON.parse(datasourceContent);
87
- if (datasource.key !== datasourceKey) {
88
- throw new Error(`Datasource key mismatch: file has '${datasource.key}', expected '${datasourceKey}'`);
89
- }
106
+ const { appKey } = await resolveAppKeyForDatasource(datasourceKey, options.app);
107
+ const systemKey = await getSystemKeyFromAppKey(appKey);
90
108
 
91
- const configObj = await getConfig();
92
- const { authConfig, dataplaneUrl } = await setupIntegrationTestAuth(appKey, options, configObj);
93
- const customPayload = await testHelpers.loadCustomPayload(options.payload);
94
- const payloadTemplate = testHelpers.determinePayloadTemplate(datasource, datasourceKey, customPayload);
95
- if (!payloadTemplate) {
96
- throw new Error(`No test payload found for datasource '${datasourceKey}'`);
97
- }
109
+ logIntegrationDatasourceBanner(datasourceKey, systemKey, options.verbose);
98
110
 
99
- logger.log(chalk.blue(`\n📡 Testing datasource: ${datasourceKey} (system: ${systemKey})`));
111
+ const unifiedResult = await runUnifiedDatasourceValidation(datasourceKey, {
112
+ app: options.app,
113
+ environment: options.environment,
114
+ runType: 'integration',
115
+ payload: options.payload,
116
+ debug: options.debug,
117
+ verbose: options.verbose,
118
+ timeout: options.timeout,
119
+ async: true,
120
+ noAsync: false,
121
+ sync: options.sync === true
122
+ });
100
123
 
101
- const testData = { payloadTemplate };
102
- if (options.debug) {
103
- testData.includeDebug = true;
104
- }
105
- const timeout = parseInt(options.timeout, 10) || 30000;
124
+ const runMeta = {
125
+ apiError: unifiedResult.apiError,
126
+ pollTimedOut: unifiedResult.pollTimedOut,
127
+ incompleteNoAsync: unifiedResult.incompleteNoAsync
128
+ };
106
129
 
107
- let response;
108
- try {
109
- response = await testDatasourceViaPipeline({
110
- dataplaneUrl,
111
- systemKey,
112
- datasourceKey,
113
- authConfig,
114
- testData,
115
- options: { timeout }
116
- });
117
- } catch (error) {
118
- const result = { key: datasourceKey, success: false, error: error.message };
119
- if (options.debug) {
120
- await writeTestLog(appKey, { request: { systemKey, datasourceKey }, error: error.message }, 'test-integration');
130
+ const early = integrationEarlyExitBody(datasourceKey, systemKey, unifiedResult, runMeta);
131
+ if (early) {
132
+ if (early.apiErrMsg && options.debug) {
133
+ await writeTestLog(
134
+ appKey,
135
+ { request: { systemKey, datasourceKey }, error: early.apiErrMsg },
136
+ 'test-integration'
137
+ );
121
138
  }
122
- return result;
139
+ return early.body;
123
140
  }
124
141
 
125
- const data = response.data || response;
126
- const success = data.success !== false;
127
- const result = {
128
- key: datasourceKey,
129
- systemKey,
130
- success,
131
- skipped: false,
132
- validationResults: data.validationResults || {},
133
- fieldMappingResults: data.fieldMappingResults || {},
134
- endpointTestResults: data.endpointTestResults || {}
135
- };
136
- if (data.error) {
137
- result.error = data.error;
138
- }
142
+ const legacy = integrationResultFromEnvelope(unifiedResult.envelope, datasourceKey);
143
+ legacy.systemKey = systemKey;
144
+ legacy.datasourceTestRun = unifiedResult.envelope;
145
+ legacy.runMeta = { apiError: null, pollTimedOut: false, incompleteNoAsync: false };
139
146
 
140
- if (options.debug) {
141
- const logPath = await writeTestLog(appKey, {
142
- request: { systemKey, datasourceKey, includeDebug: true },
143
- response: data
144
- }, 'test-integration');
147
+ if (options.debug && unifiedResult.envelope) {
148
+ const logPath = await writeTestLog(
149
+ appKey,
150
+ {
151
+ request: { systemKey, datasourceKey, includeDebug: true },
152
+ response: unifiedResult.envelope
153
+ },
154
+ 'test-integration'
155
+ );
145
156
  logger.log(chalk.gray(` Debug log: ${logPath}`));
146
157
  }
147
158
 
148
- return result;
159
+ return legacy;
149
160
  }
150
161
 
151
162
  module.exports = {
152
163
  runDatasourceTestIntegration,
153
- resolveSystemKey
164
+ getSystemKeyFromAppKey: getSystemKeyFromAppKeyExport,
165
+ findDatasourceFileByKey
154
166
  };
@@ -0,0 +1,65 @@
1
+ /**
2
+ * @fileoverview Build ValidationRunRequest body for unified datasource runs.
3
+ * @author AI Fabrix Team
4
+ * @version 2.0.0
5
+ */
6
+
7
+ const {
8
+ buildExternalDataSourceValidationRequest,
9
+ buildE2eOptionsFromCli,
10
+ includeDebugForRequest
11
+ } = require('../utils/validation-run-request');
12
+ const testHelpers = require('../utils/external-system-test-helpers');
13
+
14
+ /**
15
+ * @param {Object} params
16
+ * @param {string} params.systemKey
17
+ * @param {string} params.datasourceKey
18
+ * @param {'test'|'integration'|'e2e'} params.runType
19
+ * @param {Object} params.datasource - Loaded datasource config
20
+ * @param {string} [params.payloadPath]
21
+ * @param {boolean} params.useAsync
22
+ * @param {Object} params.options - CLI options (debug, verbose, e2e fields, capabilityKey)
23
+ * @returns {Promise<import('../api/types/validation-run.types').ValidationRunRequestBody>}
24
+ */
25
+ async function buildUnifiedValidationBody(params) {
26
+ const { systemKey, datasourceKey, runType, datasource, payloadPath, useAsync, options } = params;
27
+
28
+ let payloadTemplate;
29
+ if (payloadPath || runType === 'integration') {
30
+ const customPayload = await testHelpers.loadCustomPayload(payloadPath);
31
+ payloadTemplate = testHelpers.determinePayloadTemplate(datasource, datasourceKey, customPayload);
32
+ if (runType === 'integration' && !payloadTemplate) {
33
+ throw new Error(`No test payload found for datasource '${datasourceKey}'`);
34
+ }
35
+ }
36
+
37
+ const e2eExtra = options.capabilityKey
38
+ ? { capabilityKeys: [String(options.capabilityKey).trim()] }
39
+ : undefined;
40
+ const e2eOptions =
41
+ runType === 'e2e'
42
+ ? buildE2eOptionsFromCli({
43
+ debug: options.debug,
44
+ verbose: options.verbose,
45
+ testCrud: options.testCrud,
46
+ recordId: options.recordId,
47
+ cleanup: options.cleanup,
48
+ primaryKeyValue: options.primaryKeyValue,
49
+ e2eOptionsExtra: e2eExtra
50
+ })
51
+ : undefined;
52
+
53
+ return buildExternalDataSourceValidationRequest({
54
+ systemKey,
55
+ datasourceKey,
56
+ runType,
57
+ payloadTemplate,
58
+ asyncRun: runType === 'e2e' && useAsync === true,
59
+ includeDebug: includeDebugForRequest(options.debug),
60
+ explain: options.verbose === true,
61
+ e2eOptions: e2eOptions && Object.keys(e2eOptions).length > 0 ? e2eOptions : undefined
62
+ });
63
+ }
64
+
65
+ module.exports = { buildUnifiedValidationBody };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @fileoverview POST + optional poll for unified validation run (keeps main module small).
3
+ * @author AI Fabrix Team
4
+ * @version 2.0.0
5
+ */
6
+
7
+ const { postValidationRunAndOptionalPoll } = require('../api/validation-runner');
8
+
9
+ /**
10
+ * @param {Object} opts
11
+ * @param {string} opts.dataplaneUrl
12
+ * @param {Object} opts.authConfig
13
+ * @param {Object} opts.body
14
+ * @param {number} opts.timeoutMs
15
+ * @param {boolean} opts.useAsync
16
+ * @param {boolean} opts.noAsync
17
+ * @returns {Promise<{ envelope: Object|null, apiError: Object|null, pollTimedOut: boolean, incompleteNoAsync: boolean }>}
18
+ */
19
+ /* eslint-disable max-lines-per-function, max-statements, complexity -- POST + poll orchestration */
20
+ // Re-exported thin wrapper; single implementation lives in lib/api/validation-runner.js
21
+ /* eslint-enable max-lines-per-function, max-statements, complexity */
22
+
23
+ module.exports = { postValidationRunAndOptionalPoll };
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @fileoverview Resolve datasource file path + parsed config for unified validation.
3
+ * @author AI Fabrix Team
4
+ * @version 2.0.0
5
+ */
6
+
7
+ const path = require('path');
8
+ const { getIntegrationPath } = require('../utils/paths');
9
+ const { resolveApplicationConfigPath } = require('../utils/app-config-resolver');
10
+ const { loadConfigFile } = require('../utils/config-format');
11
+
12
+ /**
13
+ * @param {string} appKey
14
+ * @param {string} datasourceKey
15
+ * @param {Function} findDatasourceFileByKey - From integration-context
16
+ * @returns {{ datasource: Object, datasourcePath: string }}
17
+ */
18
+ function loadDatasourceForApp(appKey, datasourceKey, findDatasourceFileByKey) {
19
+ const appPath = getIntegrationPath(appKey);
20
+ const config = loadConfigFile(resolveApplicationConfigPath(appPath));
21
+ const schemaBasePath = config.externalIntegration?.schemaBasePath || './';
22
+ const datasourceFiles = config.externalIntegration?.dataSources || [];
23
+ let datasourceFile = datasourceFiles.find(f => {
24
+ const base = path.basename(f, path.extname(f));
25
+ return base === datasourceKey || base.includes(datasourceKey);
26
+ });
27
+ if (!datasourceFile) {
28
+ datasourceFile = findDatasourceFileByKey(appPath, schemaBasePath, datasourceFiles, datasourceKey);
29
+ }
30
+ if (!datasourceFile) {
31
+ throw new Error(`Datasource '${datasourceKey}' not found in application config`);
32
+ }
33
+ const datasourcePath = path.isAbsolute(schemaBasePath)
34
+ ? path.join(schemaBasePath, datasourceFile)
35
+ : path.join(appPath, schemaBasePath, datasourceFile);
36
+ const datasource = loadConfigFile(datasourcePath);
37
+ if (datasource.key !== datasourceKey) {
38
+ throw new Error(`Datasource key mismatch: file has '${datasource.key}', expected '${datasourceKey}'`);
39
+ }
40
+ return { datasource, datasourcePath };
41
+ }
42
+
43
+ module.exports = { loadDatasourceForApp };
@@ -0,0 +1,92 @@
1
+ const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
2
+ /**
3
+ * @fileoverview Run one persisted datasource through the dataplane unified validation flow (POST + optional poll via `lib/api/validation-run.api.js`).
4
+ *
5
+ * **CLI:** `aifabrix datasource test`, `test-integration`, and `test-e2e` use this module with different `runType` values.
6
+ * **User-facing permissions:** see `docs/commands/permissions.md` (Dataplane scopes may differ from the minimum noted on the HTTP helper JSDoc).
7
+ * @author AI Fabrix Team
8
+ * @version 2.0.0
9
+ */
10
+
11
+ const chalk = require('chalk');
12
+ const { resolveAppKeyForDatasource } = require('./resolve-app');
13
+ const { setupIntegrationTestAuth } = require('../external-system/test-auth');
14
+ const { getConfig } = require('../core/config');
15
+ const { getSystemKeyFromAppKey, findDatasourceFileByKey } = require('./integration-context');
16
+ const { loadDatasourceForApp } = require('./unified-validation-run-resolve');
17
+ const { buildUnifiedValidationBody } = require('./unified-validation-run-body');
18
+ const { postValidationRunAndOptionalPoll } = require('./unified-validation-run-post');
19
+ const { publishDatasourceViaPipeline } = require('../api/pipeline.api');
20
+ const { requireBearerForDataplanePipeline } = require('../utils/token-manager');
21
+ const { formatApiError } = require('../utils/api-error-handler');
22
+ const logger = require('../utils/logger');
23
+
24
+ /**
25
+ * Resolve datasource JSON path and loaded object (same rules as test-integration).
26
+ * Re-export for tests.
27
+ */
28
+ function loadDatasourceForAppExport(appKey, datasourceKey) {
29
+ return loadDatasourceForApp(appKey, datasourceKey, findDatasourceFileByKey);
30
+ }
31
+
32
+ /**
33
+ * Run unified validation for one persisted datasource.
34
+ * @async
35
+ * @param {string} datasourceKey
36
+ * @param {Object} options
37
+ * @param {boolean} [options.sync] - Publish local datasource JSON via pipeline before POST validation/run
38
+ * @returns {Promise<{ envelope: Object|null, apiError: Object|null, pollTimedOut: boolean, incompleteNoAsync: boolean }>}
39
+ */
40
+ async function runUnifiedDatasourceValidation(datasourceKey, options) {
41
+ if (!datasourceKey || typeof datasourceKey !== 'string') {
42
+ throw new Error('Datasource key is required');
43
+ }
44
+ const runType = options.runType || 'test';
45
+ const { appKey } = await resolveAppKeyForDatasource(datasourceKey, options.app);
46
+ const systemKey = await getSystemKeyFromAppKey(appKey);
47
+ const { datasource } = loadDatasourceForAppExport(appKey, datasourceKey);
48
+
49
+ const configObj = await getConfig();
50
+ const { authConfig, dataplaneUrl } = await setupIntegrationTestAuth(appKey, options, configObj);
51
+
52
+ if (options.sync === true) {
53
+ requireBearerForDataplanePipeline(authConfig);
54
+ logger.log(chalk.cyan('Syncing local config to dataplane…'));
55
+ const publishResponse = await publishDatasourceViaPipeline(dataplaneUrl, systemKey, authConfig, datasource);
56
+ if (!publishResponse || publishResponse.success === false) {
57
+ const msg =
58
+ (publishResponse && (publishResponse.formattedError || publishResponse.error)) ||
59
+ formatApiError(publishResponse, dataplaneUrl) ||
60
+ 'Publish failed';
61
+ throw new Error(`Sync failed: ${msg}`);
62
+ }
63
+ logger.log(formatSuccessLine('Sync complete'));
64
+ }
65
+
66
+ const useAsync = options.noAsync ? false : options.async !== false;
67
+ const timeoutMs = parseInt(String(options.timeout || '30000'), 10) || 30000;
68
+
69
+ const body = await buildUnifiedValidationBody({
70
+ systemKey,
71
+ datasourceKey,
72
+ runType,
73
+ datasource,
74
+ payloadPath: options.payload,
75
+ useAsync,
76
+ options
77
+ });
78
+
79
+ return postValidationRunAndOptionalPoll({
80
+ dataplaneUrl,
81
+ authConfig,
82
+ body,
83
+ timeoutMs,
84
+ useAsync,
85
+ noAsync: options.noAsync === true || options.async === false
86
+ });
87
+ }
88
+
89
+ module.exports = {
90
+ runUnifiedDatasourceValidation,
91
+ loadDatasourceForApp: loadDatasourceForAppExport
92
+ };