@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,18 +10,28 @@
10
10
  */
11
11
 
12
12
  const fsSync = require('fs');
13
- const fs = require('fs').promises;
14
13
  const path = require('path');
15
14
  const handlebars = require('handlebars');
16
15
  const config = require('../core/config');
17
- const buildCopy = require('./build-copy');
18
- const { formatMissingDbPasswordError } = require('./error-formatter');
16
+ const { readDatabasePasswords } = require('./compose-db-passwords');
19
17
  const { getContainerPort } = require('./port-resolver');
20
18
  const { parseImageOverride } = require('./parse-image-ref');
19
+ const { resolveComposeImageOverrideString } = require('./resolve-docker-image-ref');
21
20
  const { registerComposeHelpers } = require('./compose-handlebars-helpers');
22
21
  const { isVectorDatabaseName } = require('./compose-vector-helper');
23
- const paths = require('./paths');
24
- const { getInfraDirName } = require('../infrastructure/helpers');
22
+ const { resolveMisoEnvironment } = require('./compose-miso-env');
23
+ const {
24
+ buildScopedLocalContainerName,
25
+ composeTraefikServiceKey
26
+ } = require('./environment-scoped-resources');
27
+ const {
28
+ derivePathFromPattern,
29
+ buildDevUsernameForFrontDoorHost,
30
+ expandFrontDoorHostPlaceholders,
31
+ buildTraefikIngressBase,
32
+ computeTraefikStripPathPrefix
33
+ } = require('./compose-traefik-ingress-base');
34
+ const { parseDeveloperIdNum } = require('./declarative-url-ports');
25
35
 
26
36
  registerComposeHelpers();
27
37
  /**
@@ -71,9 +81,9 @@ function getImageName(config, appName) {
71
81
  * @param {Object} config - Application configuration
72
82
  * @returns {Object} App configuration
73
83
  */
74
- function buildAppConfig(appName, config) {
84
+ function buildAppConfig(appName, config, composeKeyOverride = null) {
75
85
  return {
76
- key: appName,
86
+ key: composeKeyOverride || appName,
77
87
  name: config.displayName || appName
78
88
  };
79
89
  }
@@ -98,33 +108,102 @@ function buildImageConfig(config, appName, imageOverride) {
98
108
  }
99
109
 
100
110
  /**
101
- * Builds health check configuration section
102
- * @param {Object} config - Application configuration
103
- * @returns {Object} Health check configuration
111
+ * Docker/local readiness path: same Traefik PathPrefix as url://vdir-public (frontDoorRouting + Plan 117 scope) + suffix.
112
+ * @param {Object} config - Application configuration (application.yaml shape)
113
+ * @param {string|number} devId - Developer id for host expansion
114
+ * @param {Object|null} scopeOpts - Env-scoped Traefik path (effectiveEnvironmentScopedResources, runEnvKey)
115
+ * @param {string|null|undefined} remoteServer - For ${REMOTE_HOST}
116
+ * @param {string|null|undefined} [readinessSuffix] - Path after vdir (default /health/ready or healthCheck.readinessPathSuffix)
117
+ * @returns {string} Absolute path starting with /
104
118
  */
105
- function buildHealthCheckConfig(config) {
106
- return {
107
- path: config.healthCheck?.path || '/health',
108
- interval: config.healthCheck?.interval || 30
109
- };
119
+ function computeAlignedHealthCheckPath(config, devId, scopeOpts, remoteServer, readinessSuffix) {
120
+ const hc = config.healthCheck || {};
121
+ let suffix = '/health/ready';
122
+ if (
123
+ readinessSuffix !== undefined &&
124
+ readinessSuffix !== null &&
125
+ String(readinessSuffix).trim().startsWith('/')
126
+ ) {
127
+ suffix = String(readinessSuffix).trim();
128
+ } else if (typeof hc.readinessPathSuffix === 'string' && hc.readinessPathSuffix.startsWith('/')) {
129
+ suffix = hc.readinessPathSuffix;
130
+ }
131
+ const traefik = buildTraefikIngressBase(config, devId, scopeOpts, remoteServer);
132
+ if (traefik.enabled === true) {
133
+ const p = traefik.path;
134
+ if (!p || p === '/') {
135
+ return suffix;
136
+ }
137
+ return `${String(p).replace(/\/+$/, '')}${suffix}`;
138
+ }
139
+ const fd = config.frontDoorRouting;
140
+ if (!fd || fd.enabled !== true) {
141
+ return suffix;
142
+ }
143
+ const base = derivePathFromPattern(fd.pattern);
144
+ if (!base || base === '/') {
145
+ return suffix;
146
+ }
147
+ return `${String(base).replace(/\/+$/, '')}${suffix}`;
110
148
  }
111
149
 
112
150
  /**
113
- * Derives base path from routing pattern by removing trailing wildcards
114
- * @param {string} pattern - URL pattern (e.g., '/app/*', '/api/v1/*')
115
- * @returns {string} Base path for routing
151
+ * When `frontDoorRouting.enabled` is true, resolves the same vdir as Traefik labels / url://vdir-public
152
+ * (pattern + optional /dev|/tst from scopeOpts) and prepends it to healthCheck.path unless path already starts with that vdir.
153
+ *
154
+ * @param {Object} config - Application configuration (application.yaml shape)
155
+ * @param {string|number} devId - Developer id
156
+ * @param {Object|null} scopeOpts - Env-scoped Traefik path (effectiveEnvironmentScopedResources, runEnvKey)
157
+ * @param {string|null|undefined} remoteServer - For ${REMOTE_HOST}
158
+ * @param {{ skipVdirMergeWhenPathIsBareHealth?: boolean }} [opts] - When `skipVdirMergeWhenPathIsBareHealth`, path `/health` is left as-is (in-container probe; ingress strips vdir for miso/dataplane). Deployment JSON health paths do **not** use this helper — see `buildHealthCheck` in `builders.js` (YAML paths only).
159
+ * @returns {string} Absolute path starting with /
116
160
  */
117
- function derivePathFromPattern(pattern) {
118
- if (!pattern || typeof pattern !== 'string') {
119
- return '/';
161
+ function resolveHealthCheckPathWithFrontDoorVdir(config, devId, scopeOpts, remoteServer, opts) {
162
+ const hc = config.healthCheck || {};
163
+ const raw = typeof hc.path === 'string' && hc.path.startsWith('/') ? hc.path : '/health';
164
+ const fd = config.frontDoorRouting;
165
+ if (!fd || fd.enabled !== true) {
166
+ return raw;
167
+ }
168
+ if (opts && opts.skipVdirMergeWhenPathIsBareHealth === true && raw === '/health') {
169
+ return raw;
170
+ }
171
+ const traefik = buildTraefikIngressBase(config, devId, scopeOpts, remoteServer);
172
+ if (traefik.enabled !== true) {
173
+ return raw;
120
174
  }
121
- const trimmed = pattern.trim();
122
- if (trimmed === '/' || trimmed === '') {
123
- return '/';
175
+ const vdirRaw = traefik.path;
176
+ const vdir =
177
+ !vdirRaw || vdirRaw === '/'
178
+ ? ''
179
+ : String(vdirRaw).replace(/\/+$/, '');
180
+ if (!vdir) {
181
+ return computeAlignedHealthCheckPath(config, devId, scopeOpts, remoteServer, raw);
124
182
  }
125
- const withoutWildcards = trimmed.replace(/\*+$/g, '');
126
- const withoutTrailingSlashes = withoutWildcards.replace(/\/+$/g, '');
127
- return withoutTrailingSlashes || '/';
183
+ if (raw === vdir || raw.startsWith(`${vdir}/`)) {
184
+ return raw;
185
+ }
186
+ return `${vdir}${raw}`;
187
+ }
188
+
189
+ /**
190
+ * Builds health check configuration section
191
+ * @param {Object} config - Application configuration
192
+ * @param {string|number} devId - Developer id
193
+ * @param {Object|null} scopeOpts - Env-scoped compose options
194
+ * @param {string|null|undefined} remoteServer - Remote server URL
195
+ * @returns {Object} Health check configuration
196
+ */
197
+ function buildHealthCheckConfig(config, devId, scopeOpts, remoteServer) {
198
+ const hc = config.healthCheck || {};
199
+ const path = resolveHealthCheckPathWithFrontDoorVdir(config, devId, scopeOpts, remoteServer, {
200
+ skipVdirMergeWhenPathIsBareHealth: true
201
+ });
202
+ return {
203
+ path,
204
+ interval: hc.interval || 30,
205
+ bashProbe: hc.bashProbe === true
206
+ };
128
207
  }
129
208
 
130
209
  /**
@@ -146,31 +225,36 @@ function buildDevUsername(devId) {
146
225
 
147
226
  /**
148
227
  * Builds Traefik ingress configuration from frontDoorRouting
149
- * Resolves ${DEV_USERNAME} variable interpolation in host field
150
228
  * @param {Object} config - Application configuration
151
229
  * @param {string|number} devId - Developer ID
230
+ * @param {Object|null} scopeOpts - Env-scoped Traefik path
231
+ * @param {string|null|undefined} remoteServer - From config (for ${REMOTE_HOST})
232
+ * @param {string|undefined} [resolvedHealthPathForStrip] - Compose health path; when omitted, derived via resolveHealthCheckPathWithFrontDoorVdir (same as probe)
152
233
  * @returns {Object} Traefik configuration object
153
234
  */
154
- function buildTraefikConfig(config, devId) {
155
- const frontDoor = config.frontDoorRouting;
156
- if (!frontDoor || frontDoor.enabled !== true) {
235
+ function buildTraefikConfig(config, devId, scopeOpts = null, remoteServer = null, resolvedHealthPathForStrip) {
236
+ const base = buildTraefikIngressBase(config, devId, scopeOpts, remoteServer);
237
+ if (!base.enabled) {
157
238
  return { enabled: false };
158
239
  }
159
-
160
- if (!frontDoor.host || typeof frontDoor.host !== 'string') {
161
- throw new Error('frontDoorRouting.host is required when frontDoorRouting.enabled is true');
162
- }
163
-
164
- const devUsername = buildDevUsername(devId);
165
- const host = frontDoor.host.replace(/\$\{DEV_USERNAME\}/g, devUsername);
166
- const path = derivePathFromPattern(frontDoor.pattern);
167
-
240
+ const resolvedHealth =
241
+ resolvedHealthPathForStrip !== undefined && resolvedHealthPathForStrip !== null
242
+ ? String(resolvedHealthPathForStrip)
243
+ : resolveHealthCheckPathWithFrontDoorVdir(config, devId, scopeOpts, remoteServer, {
244
+ skipVdirMergeWhenPathIsBareHealth: true
245
+ });
246
+ const devNum = parseDeveloperIdNum(devId);
247
+ // Shared builder host: nginx terminates TLS on :443 and proxies HTTP to per-dev Traefik :80 (e.g. 280).
248
+ // Traefik must only attach routers to `web` for developer-id > 0; `websecure`+tls labels without
249
+ // matching certs break routing on Traefik 3.6+ for HTTP traffic (404 on PathPrefix).
250
+ const terminateTlsAtTraefik = base.tls === true && devNum === 0;
168
251
  return {
169
252
  enabled: true,
170
- host,
171
- path,
172
- tls: frontDoor.tls !== false,
173
- certStore: frontDoor.certStore || null
253
+ host: base.host,
254
+ path: base.path,
255
+ tls: terminateTlsAtTraefik,
256
+ certStore: terminateTlsAtTraefik ? base.certStore || null : null,
257
+ stripPathPrefix: computeTraefikStripPathPrefix(base.path, resolvedHealth)
174
258
  };
175
259
  }
176
260
 
@@ -194,20 +278,40 @@ function buildRequiresConfig(config) {
194
278
  * @param {Object} config - Application configuration
195
279
  * @param {number} port - Application port
196
280
  * @param {string|number} devId - Developer ID
197
- * @param {string} [imageOverride] - Optional full image reference for run (e.g. from --image)
281
+ * @param {Object} [runExtras] - Optional compose run fields
282
+ * @param {string} [runExtras.imageOverride] - Full image reference for run (e.g. from --image)
283
+ * @param {Object|null} [runExtras.scopeOpts] - Traefik / scoped compose options
284
+ * @param {string|null|undefined} [runExtras.remoteServer] - For ${REMOTE_HOST} in frontDoorRouting.host
198
285
  * @returns {Object} Service configuration
199
286
  */
200
- function buildServiceConfig(appName, config, port, devId, imageOverride) {
287
+ function buildServiceConfig(appName, config, port, devId, runExtras = {}) {
288
+ const { imageOverride = null, scopeOpts = null, remoteServer = null } = runExtras;
201
289
  const containerPortValue = getContainerPort(config, 3000);
202
290
  const hostPort = port;
291
+ const useTraefikScope =
292
+ scopeOpts &&
293
+ scopeOpts.effectiveEnvironmentScopedResources &&
294
+ scopeOpts.runEnvKey &&
295
+ (scopeOpts.runEnvKey === 'dev' || scopeOpts.runEnvKey === 'tst');
296
+ const composeAppKey = useTraefikScope
297
+ ? composeTraefikServiceKey(appName, scopeOpts.runEnvKey)
298
+ : null;
299
+ const scopeForHealthAndTraefik = useTraefikScope ? scopeOpts : null;
300
+ const healthCheck = buildHealthCheckConfig(config, devId, scopeForHealthAndTraefik, remoteServer);
203
301
  return {
204
- app: buildAppConfig(appName, config),
302
+ app: buildAppConfig(appName, config, composeAppKey),
205
303
  image: buildImageConfig(config, appName, imageOverride),
206
304
  port: containerPortValue, // Container port (for health check and template)
207
305
  containerPort: containerPortValue, // Container port (always set, equals containerPort if exists, else port)
208
306
  hostPort: hostPort, // Host port (options.port if provided, else config.port)
209
- healthCheck: buildHealthCheckConfig(config),
210
- traefik: buildTraefikConfig(config, devId),
307
+ healthCheck,
308
+ traefik: buildTraefikConfig(
309
+ config,
310
+ devId,
311
+ scopeForHealthAndTraefik,
312
+ remoteServer,
313
+ healthCheck.path
314
+ ),
211
315
  ...buildRequiresConfig(config)
212
316
  };
213
317
  }
@@ -230,127 +334,6 @@ function buildNetworksConfig(config) {
230
334
  return { databases: config.requires?.databases || config.databases || [] };
231
335
  }
232
336
 
233
- /** Reads and parses .env file. @param {string} envPath - Path to .env file. @returns {Promise<Object>} env vars. @throws {Error} If file not found. */
234
- async function readEnvFile(envPath) {
235
- if (!fsSync.existsSync(envPath)) {
236
- throw new Error(`.env file not found: ${envPath}`);
237
- }
238
-
239
- try {
240
- const envContent = await fs.readFile(envPath, 'utf8');
241
- if (envContent === undefined || envContent === null) {
242
- throw new Error('Failed to read .env file: file content is empty or undefined');
243
- }
244
- const lines = envContent.split('\n');
245
- const envVars = {};
246
-
247
- for (const line of lines) {
248
- const trimmed = line.trim();
249
- if (!trimmed || trimmed.startsWith('#')) {
250
- continue;
251
- }
252
-
253
- const equalIndex = trimmed.indexOf('=');
254
- if (equalIndex > 0) {
255
- const key = trimmed.substring(0, equalIndex).trim();
256
- const value = trimmed.substring(equalIndex + 1).trim();
257
- envVars[key] = value;
258
- }
259
- }
260
-
261
- return envVars;
262
- } catch (error) {
263
- throw new Error(`Failed to read .env file: ${error.message}`);
264
- }
265
- }
266
-
267
- /**
268
- * Validates and extracts password from environment variables
269
- * @function extractPassword
270
- * @param {Object} envVars - Environment variables
271
- * @param {string} passwordKey - Password key to look up
272
- * @param {Object} [context] - Optional: { appKey, multi } for clearer error messages
273
- * @returns {string} Password value
274
- * @throws {Error} If password is missing or empty
275
- */
276
- function extractPassword(envVars, passwordKey, context = {}) {
277
- const { appKey, multi } = context;
278
- const appSuffix = appKey ? ` for application '${appKey}'` : '';
279
-
280
- if (!(passwordKey in envVars)) {
281
- throw new Error(multi && appKey ? formatMissingDbPasswordError(appKey, { multiDb: true, passwordKey }) : 'Missing required password variable ' + passwordKey + ' in .env file' + appSuffix + '. Add ' + passwordKey + '=your_secret to your .env file.');
282
- }
283
-
284
- const password = envVars[passwordKey].trim();
285
- if (!password || password.length === 0) {
286
- throw new Error('Password variable ' + passwordKey + ' is empty in .env file' + appSuffix + '. Set a non-empty value.');
287
- }
288
-
289
- return password;
290
- }
291
-
292
- /**
293
- * Processes multiple databases
294
- * @function processMultipleDatabases
295
- * @param {Array} databases - Array of database configurations
296
- * @param {Object} envVars - Environment variables
297
- * @param {string} appKey - Application key
298
- * @returns {Object} Object with passwords map and array
299
- */
300
- function processMultipleDatabases(databases, envVars, appKey) {
301
- const passwords = {};
302
- const passwordsArray = [];
303
- for (let i = 0; i < databases.length; i++) {
304
- const db = databases[i];
305
- const dbName = db.name || appKey;
306
- const passwordKey = `DB_${i}_PASSWORD`;
307
- const password = extractPassword(envVars, passwordKey, { appKey, multi: true });
308
- passwords[dbName] = password;
309
- passwordsArray.push(password);
310
- }
311
- return { passwords, passwordsArray };
312
- }
313
-
314
- /**
315
- * Processes single database case
316
- * @function processSingleDatabase
317
- * @param {Object} envVars - Environment variables
318
- * @param {string} appKey - Application key
319
- * @returns {Object} Object with passwords map and array
320
- */
321
- function processSingleDatabase(envVars, appKey) {
322
- const passwords = {};
323
- const passwordsArray = [];
324
- const passwordKey = ('DB_0_PASSWORD' in envVars) ? 'DB_0_PASSWORD' : 'DB_PASSWORD';
325
- if (!(passwordKey in envVars)) {
326
- throw new Error(formatMissingDbPasswordError(appKey));
327
- }
328
- const password = extractPassword(envVars, passwordKey, { appKey });
329
- passwords[appKey] = password;
330
- passwordsArray.push(password);
331
- return { passwords, passwordsArray };
332
- }
333
-
334
- /**
335
- * Reads database passwords from .env file
336
- * @async
337
- * @function readDatabasePasswords
338
- * @param {string} envPath - Path to .env file
339
- * @param {Array<Object>} databases - Array of database configurations
340
- * @param {string} appKey - Application key (fallback for single database)
341
- * @returns {Promise<Object>} Object with passwords map and array
342
- * @throws {Error} If required password variables are missing
343
- */
344
- async function readDatabasePasswords(envPath, databases, appKey) {
345
- const envVars = await readEnvFile(envPath);
346
- if (databases && databases.length > 0) {
347
- const { passwords, passwordsArray } = processMultipleDatabases(databases, envVars, appKey);
348
- return { map: passwords, array: passwordsArray };
349
- }
350
- const { passwords, passwordsArray } = processSingleDatabase(envVars, appKey);
351
- return { map: passwords, array: passwordsArray };
352
- }
353
-
354
337
  /**
355
338
  * Gets developer ID and calculates numeric ID
356
339
  * @async
@@ -370,131 +353,54 @@ async function getDeveloperIdAndNumeric() {
370
353
  * @param {number} idNum - Numeric developer ID
371
354
  * @returns {Object} Object with networkName and containerName
372
355
  */
373
- function buildNetworkAndContainerNames(appName, devId, idNum) {
356
+ function buildNetworkAndContainerNames(appName, devId, idNum, scopeOpts = null) {
374
357
  const networkName = idNum === 0 ? 'infra-aifabrix-network' : `infra-dev${devId}-aifabrix-network`;
375
- const containerName = idNum === 0 ? `aifabrix-${appName}` : `aifabrix-dev${devId}-${appName}`;
358
+ let containerName;
359
+ if (
360
+ scopeOpts &&
361
+ scopeOpts.effectiveEnvironmentScopedResources &&
362
+ scopeOpts.runEnvKey &&
363
+ (scopeOpts.runEnvKey === 'dev' || scopeOpts.runEnvKey === 'tst')
364
+ ) {
365
+ containerName = buildScopedLocalContainerName(appName, devId, idNum, scopeOpts.runEnvKey);
366
+ } else {
367
+ containerName = idNum === 0 ? `aifabrix-${appName}` : `aifabrix-dev${devId}-${appName}`;
368
+ }
376
369
  return { networkName, containerName };
377
370
  }
378
371
 
379
- /**
380
- * Reads database passwords if needed
381
- * @async
382
- * @function readDatabasePasswordsIfNeeded
383
- * @param {boolean} requiresDatabase - Whether database is required
384
- * @param {Array} databases - Array of databases
385
- * @param {string} envFilePath - Environment file path
386
- * @param {string} appName - Application name
387
- * @returns {Promise<Object>} Database passwords object
388
- */
389
- async function readDatabasePasswordsIfNeeded(requiresDatabase, databases, envFilePath, appName) {
390
- if (requiresDatabase || databases.length > 0) {
391
- return await readDatabasePasswords(envFilePath, databases, appName);
372
+ const { createGenerateDockerCompose } = require('./compose-generate-docker-compose');
373
+ async function getRemoteServerForCompose() {
374
+ try {
375
+ const rs = await config.getRemoteServer();
376
+ return rs && String(rs).trim() ? String(rs).trim() : null;
377
+ } catch {
378
+ return null;
392
379
  }
393
- return { map: {}, array: [] };
394
- }
395
-
396
- /**
397
- * Resolves image override from options (--image, --tag, or null).
398
- * @param {Object} options - Run options
399
- * @param {Object} appConfig - Application configuration
400
- * @param {string} appName - Application name
401
- * @returns {string|null} Full image reference or null
402
- */
403
- function resolveImageOverride(options, appConfig, appName) {
404
- if (options.image) return options.image;
405
- if (options.imageOverride) return options.imageOverride;
406
- if (options.tag) return `${getImageName(appConfig, appName)}:${options.tag}`;
407
- return null;
408
- }
409
-
410
- /**
411
- * Resolves Miso environment from options (tst, pro, or dev).
412
- * @param {Object} options - Run options
413
- * @returns {string} 'dev' | 'tst' | 'pro'
414
- */
415
- function resolveMisoEnvironment(options) {
416
- const env = (options.env && typeof options.env === 'string') ? options.env.toLowerCase() : 'dev';
417
- return (env === 'tst' || env === 'pro') ? env : 'dev';
418
380
  }
419
381
 
420
- /**
421
- * Resolves dev mount path from options.
422
- * @param {Object} options - Run options
423
- * @returns {string|null} Trimmed path or null
424
- */
425
- function resolveDevMountPath(options) {
426
- return (options.devMountPath && typeof options.devMountPath === 'string') ? options.devMountPath.trim() : null;
427
- }
428
-
429
- /**
430
- * Resolves env file path from options or default dev dir (forward slashes).
431
- * @param {Object} options - Run options
432
- * @param {string} devDir - Default dev directory
433
- * @returns {string} Absolute env file path
434
- */
435
- function resolveEnvFilePath(options, devDir) {
436
- const envFilePath = (options.envFilePath && typeof options.envFilePath === 'string')
437
- ? path.resolve(options.envFilePath)
438
- : path.join(devDir, '.env');
439
- return envFilePath.replace(/\\/g, '/');
440
- }
441
-
442
- /**
443
- * Generates Docker Compose configuration from template
444
- * @async
445
- * @function generateDockerCompose
446
- * @param {string} appName - Application name
447
- * @param {Object} appConfig - Application configuration
448
- * @param {Object} options - Run options
449
- * @returns {Promise<string>} Generated compose content
450
- */
451
- async function generateDockerCompose(appName, appConfig, options) {
452
- const language = appConfig.build?.language || appConfig.language || 'typescript';
453
- const template = loadDockerComposeTemplate(language);
454
- const port = options.port || appConfig.port || 3000;
455
- const imageOverride = resolveImageOverride(options, appConfig, appName);
456
- const { devId, idNum } = await getDeveloperIdAndNumeric();
457
- const { networkName, containerName } = buildNetworkAndContainerNames(appName, devId, idNum);
458
- const serviceConfig = buildServiceConfig(appName, appConfig, port, devId, imageOverride);
459
- const volumesConfig = buildVolumesConfig(appName);
460
- const networksConfig = buildNetworksConfig(appConfig);
461
-
462
- const devDir = buildCopy.getDevDirectory(appName, devId);
463
- const envFileAbsolutePath = resolveEnvFilePath(options, devDir);
464
- const dbInitEnvFileAbsolutePath = (options.dbInitEnvFilePath && typeof options.dbInitEnvFilePath === 'string')
465
- ? path.resolve(options.dbInitEnvFilePath).replace(/\\/g, '/')
466
- : null;
467
-
468
- const databasePasswords = await readDatabasePasswordsIfNeeded(
469
- serviceConfig.requiresDatabase || false,
470
- networksConfig.databases || [],
471
- envFileAbsolutePath,
472
- appName
473
- );
474
- const devMountPath = resolveDevMountPath(options);
475
- const reloadStartRaw = appConfig.build?.reloadStart;
476
- const reloadStartCommand =
477
- devMountPath && typeof reloadStartRaw === 'string' && reloadStartRaw.trim().length > 0
478
- ? reloadStartRaw.trim()
479
- : null;
480
-
481
- const infraPgpassPath = path.join(paths.getAifabrixHome(), getInfraDirName(devId), 'pgpass');
482
- const useInfraPgpass = serviceConfig.requiresDatabase && fsSync.existsSync(infraPgpassPath);
483
- return template({
484
- ...serviceConfig,
485
- ...volumesConfig,
486
- ...networksConfig,
487
- envFile: envFileAbsolutePath,
488
- dbInitEnvFile: dbInitEnvFileAbsolutePath,
489
- databasePasswords,
490
- devId: idNum,
491
- networkName,
492
- containerName,
493
- misoEnvironment: resolveMisoEnvironment(options),
494
- devMountPath,
495
- reloadStartCommand,
496
- infraPgpassPath: useInfraPgpass ? infraPgpassPath : null,
497
- useInfraPgpass: !!useInfraPgpass
498
- });
499
- }
500
- module.exports = { generateDockerCompose, getImageName, derivePathFromPattern, buildTraefikConfig, buildDevUsername, isVectorDatabaseName };
382
+ const generateDockerCompose = createGenerateDockerCompose({
383
+ loadDockerComposeTemplate,
384
+ resolveComposeImageOverrideString,
385
+ getDeveloperIdAndNumeric,
386
+ getRemoteServerForCompose,
387
+ buildNetworkAndContainerNames,
388
+ buildServiceConfig,
389
+ buildVolumesConfig,
390
+ buildNetworksConfig,
391
+ readDatabasePasswords
392
+ });
393
+
394
+ module.exports = {
395
+ generateDockerCompose,
396
+ getImageName,
397
+ derivePathFromPattern,
398
+ buildTraefikConfig,
399
+ computeAlignedHealthCheckPath,
400
+ resolveHealthCheckPathWithFrontDoorVdir,
401
+ buildDevUsername,
402
+ buildDevUsernameForFrontDoorHost,
403
+ expandFrontDoorHostPlaceholders,
404
+ isVectorDatabaseName,
405
+ resolveMisoEnvironment
406
+ };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * MISO_ENVIRONMENT value for generated compose / docker run.
3
+ *
4
+ * @fileoverview Extracted from compose-generator to respect max-lines
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ /**
10
+ * @param {Object} options - Run options
11
+ * @returns {'dev'|'tst'|'pro'}
12
+ */
13
+ function resolveMisoEnvironment(options) {
14
+ const env = (options.env && typeof options.env === 'string') ? options.env.toLowerCase() : 'dev';
15
+ return (env === 'tst' || env === 'pro') ? env : 'dev';
16
+ }
17
+
18
+ module.exports = { resolveMisoEnvironment };