@aifabrix/builder 2.43.0 → 2.44.1

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 (371) hide show
  1. package/.cursor/rules/anchor-docs.mdc +15 -0
  2. package/.cursor/rules/cli-layout.mdc +75 -0
  3. package/.cursor/rules/project-rules.mdc +8 -0
  4. package/.npmrc.token +1 -0
  5. package/.nyc_output/55e9d034-ddab-4579-a706-e02a91d75c91.json +1 -0
  6. package/.nyc_output/processinfo/55e9d034-ddab-4579-a706-e02a91d75c91.json +1 -0
  7. package/.nyc_output/processinfo/index.json +1 -0
  8. package/README.md +1 -1
  9. package/anchor-docs/README.md +10 -0
  10. package/anchor-docs/_TEMPLATE +24 -0
  11. package/bin/aifabrix.js +13 -4
  12. package/integration/hubspot-test/README.md +31 -0
  13. package/integration/hubspot-test/create-hubspot.js +5 -5
  14. package/integration/hubspot-test/hubspot-test-datasource-company.json +58 -462
  15. package/integration/hubspot-test/hubspot-test-datasource-contact.json +61 -555
  16. package/integration/hubspot-test/hubspot-test-datasource-deal.json +63 -506
  17. package/integration/hubspot-test/hubspot-test-datasource-users.json +42 -83
  18. package/integration/hubspot-test/hubspot-test-deploy.json +3 -3
  19. package/integration/hubspot-test/test-dataplane-down-tests.js +1 -7
  20. package/integration/hubspot-test/test-dataplane-down.js +3 -3
  21. package/integration/hubspot-test/test.js +35 -43
  22. package/integration/hubspot-test/wizard-hubspot-test-headless.yaml +23 -0
  23. package/integration/roundtrip-test-local/README.md +144 -0
  24. package/integration/roundtrip-test-local/application.yaml +13 -0
  25. package/integration/roundtrip-test-local/env.template +15 -0
  26. package/integration/roundtrip-test-local/roundtrip-test-local-datasource-roundtrip-test-company.yaml +14 -0
  27. package/integration/roundtrip-test-local/roundtrip-test-local-deploy.json +61 -0
  28. package/integration/roundtrip-test-local/roundtrip-test-local-system.yaml +25 -0
  29. package/integration/roundtrip-test-local2/README.md +144 -0
  30. package/integration/roundtrip-test-local2/application.yaml +13 -0
  31. package/integration/roundtrip-test-local2/env.template +15 -0
  32. package/integration/roundtrip-test-local2/roundtrip-test-local2-datasource-company.yaml +31 -0
  33. package/integration/roundtrip-test-local2/roundtrip-test-local2-deploy.json +86 -0
  34. package/integration/roundtrip-test-local2/roundtrip-test-local2-system.yaml +25 -0
  35. package/integration/test/wizard.yaml +8 -0
  36. package/jest.config.default.js +10 -0
  37. package/jest.config.integration.fixtures.js +22 -0
  38. package/jest.config.integration.js +21 -18
  39. package/jest.config.isolated.js +10 -0
  40. package/jest.projects.js +301 -0
  41. package/lib/api/certificates.api.js +62 -0
  42. package/lib/api/datasources-core.api.js +3 -3
  43. package/lib/api/dev-mtls-request.js +110 -0
  44. package/lib/api/dev-server-https.js +145 -0
  45. package/lib/api/dev.api.js +133 -144
  46. package/lib/api/index.js +11 -3
  47. package/lib/api/pipeline.api.js +67 -20
  48. package/lib/api/types/certificates.types.js +48 -0
  49. package/lib/api/types/dev.types.js +4 -3
  50. package/lib/api/types/pipeline.types.js +8 -5
  51. package/lib/api/types/validation-run.types.js +56 -0
  52. package/lib/api/validation-run.api.js +111 -0
  53. package/lib/api/validation-runner.js +109 -0
  54. package/lib/app/certification-show-enrich.js +129 -0
  55. package/lib/app/certification-verify-rows.js +60 -0
  56. package/lib/app/config.js +1 -1
  57. package/lib/app/deploy-status-display.js +2 -2
  58. package/lib/app/deploy.js +7 -6
  59. package/lib/app/display.js +2 -1
  60. package/lib/app/dockerfile.js +3 -2
  61. package/lib/app/down.js +2 -1
  62. package/lib/app/helpers.js +6 -5
  63. package/lib/app/index.js +27 -8
  64. package/lib/app/list.js +7 -6
  65. package/lib/app/push.js +4 -3
  66. package/lib/app/register.js +16 -7
  67. package/lib/app/rotate-secret.js +14 -13
  68. package/lib/app/run-container-start.js +184 -0
  69. package/lib/app/run-docker-fallback.js +108 -0
  70. package/lib/app/run-env-compose.js +30 -42
  71. package/lib/app/run-helpers.js +49 -126
  72. package/lib/app/run-infra-requirements.js +30 -0
  73. package/lib/app/run-resolve-image.js +21 -0
  74. package/lib/app/run.js +74 -21
  75. package/lib/app/show-display.js +44 -1
  76. package/lib/app/show.js +93 -9
  77. package/lib/build/index.js +13 -10
  78. package/lib/certification/cli-cert-sync-skip.js +21 -0
  79. package/lib/certification/merge-certification-from-artifact.js +185 -0
  80. package/lib/certification/post-unified-cert-sync.js +33 -0
  81. package/lib/certification/sync-after-external-command.js +52 -0
  82. package/lib/certification/sync-system-certification.js +197 -0
  83. package/lib/cli/index.js +2 -0
  84. package/lib/cli/setup-app.help.js +67 -0
  85. package/lib/cli/setup-app.js +61 -121
  86. package/lib/cli/setup-app.test-commands.js +195 -0
  87. package/lib/cli/setup-auth.js +19 -5
  88. package/lib/cli/setup-credential-deployment.js +22 -8
  89. package/lib/cli/setup-dev-path-commands.js +124 -0
  90. package/lib/cli/setup-dev.js +170 -113
  91. package/lib/cli/setup-environment.js +7 -1
  92. package/lib/cli/setup-external-system.js +84 -23
  93. package/lib/cli/setup-infra.js +126 -47
  94. package/lib/cli/setup-parameters.js +32 -0
  95. package/lib/cli/setup-secrets.js +137 -18
  96. package/lib/cli/setup-service-user.js +1 -1
  97. package/lib/cli/setup-utility.js +54 -22
  98. package/lib/commands/app-down.js +5 -7
  99. package/lib/commands/app-install.js +14 -7
  100. package/lib/commands/app-logs.js +13 -10
  101. package/lib/commands/app-shell.js +4 -1
  102. package/lib/commands/app-test.js +25 -19
  103. package/lib/commands/app.js +32 -11
  104. package/lib/commands/auth-config.js +6 -6
  105. package/lib/commands/auth-status.js +4 -3
  106. package/lib/commands/credential-env.js +4 -3
  107. package/lib/commands/credential-list.js +5 -4
  108. package/lib/commands/credential-push.js +4 -3
  109. package/lib/commands/datasource-unified-test-cli.js +428 -0
  110. package/lib/commands/datasource-unified-test-cli.options.js +191 -0
  111. package/lib/commands/datasource-unified-test-e2e-cli-helpers.js +106 -0
  112. package/lib/commands/datasource-validation-cli.js +143 -0
  113. package/lib/commands/datasource.js +125 -95
  114. package/lib/commands/deployment-list.js +6 -5
  115. package/lib/commands/dev-cli-handlers.js +122 -18
  116. package/lib/commands/dev-down.js +4 -3
  117. package/lib/commands/dev-init.js +231 -116
  118. package/lib/commands/dev-show-display.js +473 -0
  119. package/lib/commands/login-credentials.js +3 -2
  120. package/lib/commands/login-device.js +4 -3
  121. package/lib/commands/login.js +5 -4
  122. package/lib/commands/logout.js +8 -7
  123. package/lib/commands/parameters-validate.js +54 -0
  124. package/lib/commands/repair-datasource.js +314 -68
  125. package/lib/commands/repair-env-template.js +2 -2
  126. package/lib/commands/repair.js +21 -3
  127. package/lib/commands/secrets-list.js +23 -12
  128. package/lib/commands/secrets-remove-all.js +220 -0
  129. package/lib/commands/secrets-remove.js +21 -12
  130. package/lib/commands/secrets-set.js +21 -12
  131. package/lib/commands/secrets-validate.js +4 -4
  132. package/lib/commands/secure.js +10 -9
  133. package/lib/commands/service-user.js +26 -25
  134. package/lib/commands/test-e2e-external.js +27 -1
  135. package/lib/commands/up-common.js +3 -2
  136. package/lib/commands/up-dataplane.js +29 -16
  137. package/lib/commands/up-miso.js +19 -29
  138. package/lib/commands/upload.js +149 -39
  139. package/lib/commands/wizard-core-helpers.js +1 -1
  140. package/lib/commands/wizard-dataplane.js +4 -3
  141. package/lib/commands/wizard-helpers.js +3 -3
  142. package/lib/commands/wizard.js +2 -2
  143. package/lib/core/admin-secrets.js +14 -5
  144. package/lib/core/audit-logger.js +12 -4
  145. package/lib/core/config-attach-extensions.js +46 -0
  146. package/lib/core/config-runtime-paths.js +29 -0
  147. package/lib/core/config.js +55 -56
  148. package/lib/core/diff.js +3 -2
  149. package/lib/core/ensure-encryption-key.js +1 -1
  150. package/lib/core/secrets-ensure-infra.js +77 -0
  151. package/lib/core/secrets-ensure.js +120 -64
  152. package/lib/core/secrets-env-write.js +35 -7
  153. package/lib/core/secrets-infra-placeholder-sync.js +61 -0
  154. package/lib/core/secrets.js +200 -37
  155. package/lib/core/templates-env.js +4 -3
  156. package/lib/datasource/abac-validator.js +1 -10
  157. package/lib/datasource/deploy.js +75 -53
  158. package/lib/datasource/field-reference-validator.js +9 -6
  159. package/lib/datasource/integration-context.js +63 -0
  160. package/lib/datasource/list.js +8 -7
  161. package/lib/datasource/log-viewer.js +189 -67
  162. package/lib/datasource/resolve-app.js +4 -4
  163. package/lib/datasource/test-e2e.js +113 -146
  164. package/lib/datasource/test-integration.js +114 -122
  165. package/lib/datasource/unified-validation-run-body.js +68 -0
  166. package/lib/datasource/unified-validation-run-post.js +23 -0
  167. package/lib/datasource/unified-validation-run-resolve.js +43 -0
  168. package/lib/datasource/unified-validation-run.js +93 -0
  169. package/lib/datasource/validate.js +157 -13
  170. package/lib/deployment/deployer.js +4 -3
  171. package/lib/deployment/environment.js +7 -6
  172. package/lib/deployment/push.js +17 -8
  173. package/lib/external-system/delete.js +4 -3
  174. package/lib/external-system/deploy.js +166 -53
  175. package/lib/external-system/download-helpers.js +1 -1
  176. package/lib/external-system/download.js +7 -6
  177. package/lib/external-system/generator.js +92 -6
  178. package/lib/external-system/integration-test-dispatch.js +26 -0
  179. package/lib/external-system/test-execution.js +5 -1
  180. package/lib/external-system/test-helpers.js +0 -4
  181. package/lib/external-system/test-system-level-helpers.js +110 -0
  182. package/lib/external-system/test-system-level.js +83 -44
  183. package/lib/external-system/test.js +59 -8
  184. package/lib/generator/builders.js +23 -11
  185. package/lib/generator/deploy-manifest-azure-kv.js +81 -0
  186. package/lib/generator/external.js +16 -4
  187. package/lib/generator/helpers.js +58 -3
  188. package/lib/generator/index.js +4 -0
  189. package/lib/generator/split-readme.js +12 -7
  190. package/lib/generator/split-variables.js +2 -1
  191. package/lib/generator/split.js +1 -1
  192. package/lib/generator/wizard-readme.js +3 -3
  193. package/lib/generator/wizard.js +8 -8
  194. package/lib/infrastructure/compose.js +70 -7
  195. package/lib/infrastructure/helpers-docker-check.js +67 -0
  196. package/lib/infrastructure/helpers.js +203 -42
  197. package/lib/infrastructure/index.js +31 -18
  198. package/lib/infrastructure/services.js +21 -67
  199. package/lib/internal/fs-real-sync.js +104 -0
  200. package/lib/internal/node-fs.js +98 -0
  201. package/lib/parameters/database-secret-values.js +173 -0
  202. package/lib/parameters/infra-kv-discovery.js +121 -0
  203. package/lib/parameters/infra-parameter-catalog.js +458 -0
  204. package/lib/parameters/infra-parameter-validate.js +64 -0
  205. package/lib/schema/application-schema.json +37 -17
  206. package/lib/schema/datasource-test-run.schema.json +493 -0
  207. package/lib/schema/deployment-rules.yaml +102 -63
  208. package/lib/schema/external-datasource.schema.json +1200 -442
  209. package/lib/schema/external-system.schema.json +203 -5
  210. package/lib/schema/flag-map-validation-run.json +31 -0
  211. package/lib/schema/infra-parameter.schema.json +106 -0
  212. package/lib/schema/infra.parameter.yaml +421 -0
  213. package/lib/schema/type/credential-auth-templates.json +40 -0
  214. package/lib/schema/type/document-storage.json +226 -0
  215. package/lib/schema/type/message-service.json +123 -0
  216. package/lib/schema/type/vector-store.json +88 -0
  217. package/lib/utils/aifabrix-runtime-config-dir.js +132 -0
  218. package/lib/utils/api-error-handler.js +2 -2
  219. package/lib/utils/api.js +77 -17
  220. package/lib/utils/app-register-api.js +3 -2
  221. package/lib/utils/app-register-auth.js +1 -1
  222. package/lib/utils/app-register-config.js +4 -4
  223. package/lib/utils/app-register-display.js +3 -2
  224. package/lib/utils/app-register-validator.js +3 -2
  225. package/lib/utils/app-run-containers.js +26 -22
  226. package/lib/utils/app-scoped-config.js +31 -0
  227. package/lib/utils/app-service-env-from-builder.js +164 -0
  228. package/lib/utils/build-copy.js +1 -1
  229. package/lib/utils/build-helpers.js +20 -20
  230. package/lib/utils/build-resolve-image.js +165 -0
  231. package/lib/utils/cli-layout-chalk.js +8 -0
  232. package/lib/utils/cli-test-layout-chalk.js +267 -0
  233. package/lib/utils/cli-utils.js +88 -11
  234. package/lib/utils/compose-db-passwords.js +138 -0
  235. package/lib/utils/compose-generate-docker-compose.js +216 -0
  236. package/lib/utils/compose-generator.js +197 -291
  237. package/lib/utils/compose-miso-env.js +18 -0
  238. package/lib/utils/compose-traefik-ingress-base.js +158 -0
  239. package/lib/utils/config-paths.js +166 -7
  240. package/lib/utils/config-scoped-resources-preference.js +41 -0
  241. package/lib/utils/configuration-env-resolver.js +11 -8
  242. package/lib/utils/controller-deployment-outcome.js +68 -0
  243. package/lib/utils/credential-display.js +2 -2
  244. package/lib/utils/credential-secrets-env.js +5 -5
  245. package/lib/utils/dataplane-pipeline-warning.js +4 -3
  246. package/lib/utils/datasource-test-run-capability-scope.js +43 -0
  247. package/lib/utils/datasource-test-run-certificate-tty.js +82 -0
  248. package/lib/utils/datasource-test-run-debug-display.js +137 -0
  249. package/lib/utils/datasource-test-run-debug-slice.js +93 -0
  250. package/lib/utils/datasource-test-run-display.js +459 -0
  251. package/lib/utils/datasource-test-run-exit.js +83 -0
  252. package/lib/utils/datasource-test-run-legacy-adapter.js +93 -0
  253. package/lib/utils/datasource-test-run-report-version.js +51 -0
  254. package/lib/utils/datasource-test-run-schema-sync.js +59 -0
  255. package/lib/utils/datasource-test-run-tty-log.js +81 -0
  256. package/lib/utils/datasource-validation-watch.js +266 -0
  257. package/lib/utils/declarative-url-ports.js +47 -0
  258. package/lib/utils/derive-env-key-from-client-id.js +41 -0
  259. package/lib/utils/dev-ca-install.js +185 -23
  260. package/lib/utils/dev-cert-helper.js +266 -17
  261. package/lib/utils/dev-hosts-helper.js +307 -0
  262. package/lib/utils/dev-init-cert-hints.js +37 -0
  263. package/lib/utils/dev-init-health-messages.js +52 -0
  264. package/lib/utils/dev-init-resolve.js +86 -0
  265. package/lib/utils/dev-init-ssh-merge.js +65 -0
  266. package/lib/utils/dev-ssh-config-helper.js +196 -0
  267. package/lib/utils/dev-user-groups.js +93 -0
  268. package/lib/utils/docker-build.js +42 -17
  269. package/lib/utils/docker-exec.js +28 -0
  270. package/lib/utils/docker-manifest-public-port.js +116 -0
  271. package/lib/utils/docker-not-running-hint.js +52 -0
  272. package/lib/utils/docker.js +98 -11
  273. package/lib/utils/ensure-dev-certs-for-remote-docker.js +192 -0
  274. package/lib/utils/env-config-loader.js +10 -91
  275. package/lib/utils/env-copy.js +19 -10
  276. package/lib/utils/env-map.js +35 -8
  277. package/lib/utils/env-template.js +2 -2
  278. package/lib/utils/environment-scoped-resources.js +144 -0
  279. package/lib/utils/error-formatter.js +92 -13
  280. package/lib/utils/error-formatters/http-status-errors.js +6 -5
  281. package/lib/utils/error-formatters/network-errors.js +2 -1
  282. package/lib/utils/error-formatters/permission-errors.js +2 -1
  283. package/lib/utils/error-formatters/validation-errors.js +2 -1
  284. package/lib/utils/external-readme.js +8 -1
  285. package/lib/utils/external-system-display.js +242 -136
  286. package/lib/utils/external-system-local-test-tty.js +389 -0
  287. package/lib/utils/external-system-readiness-core.js +377 -0
  288. package/lib/utils/external-system-readiness-deploy-display.js +270 -0
  289. package/lib/utils/external-system-readiness-display-internals.js +150 -0
  290. package/lib/utils/external-system-readiness-display.js +186 -0
  291. package/lib/utils/external-system-system-test-tty-overview.js +120 -0
  292. package/lib/utils/external-system-system-test-tty.js +417 -0
  293. package/lib/utils/external-system-test-helpers.js +24 -6
  294. package/lib/utils/external-system-validators.js +30 -12
  295. package/lib/utils/health-check-url.js +119 -0
  296. package/lib/utils/health-check.js +59 -25
  297. package/lib/utils/help-builder.js +11 -8
  298. package/lib/utils/image-version.js +4 -8
  299. package/lib/utils/infra-containers.js +4 -7
  300. package/lib/utils/infra-env-defaults.js +162 -0
  301. package/lib/utils/infra-status-display.js +167 -0
  302. package/lib/utils/infra-status.js +16 -8
  303. package/lib/utils/local-secrets.js +3 -4
  304. package/lib/utils/paths.js +148 -47
  305. package/lib/utils/port-resolver.js +10 -23
  306. package/lib/utils/redis-env-scope.js +62 -0
  307. package/lib/utils/register-aifabrix-shell-env.js +204 -0
  308. package/lib/utils/remote-builder-validation.js +99 -0
  309. package/lib/utils/remote-dev-auth.js +117 -21
  310. package/lib/utils/remote-docker-env.js +67 -15
  311. package/lib/utils/remote-secrets-loader.js +13 -4
  312. package/lib/utils/resolve-docker-image-ref.js +124 -0
  313. package/lib/utils/schema-loader.js +22 -9
  314. package/lib/utils/secrets-bash-kv.js +25 -0
  315. package/lib/utils/secrets-generator.js +169 -49
  316. package/lib/utils/secrets-helpers.js +70 -59
  317. package/lib/utils/secrets-kv-scope.js +60 -0
  318. package/lib/utils/secrets-utils.js +32 -38
  319. package/lib/utils/secrets-validation.js +3 -1
  320. package/lib/utils/secrets-yaml-preserve.js +109 -0
  321. package/lib/utils/ssh-key-helper.js +4 -2
  322. package/lib/utils/template-helpers.js +2 -2
  323. package/lib/utils/test-log-writer.js +3 -3
  324. package/lib/utils/token-manager.js +1 -2
  325. package/lib/utils/url-declarative-public-base.js +188 -0
  326. package/lib/utils/url-declarative-resolve-build.js +493 -0
  327. package/lib/utils/url-declarative-resolve-load-doc.js +51 -0
  328. package/lib/utils/url-declarative-resolve.js +220 -0
  329. package/lib/utils/url-declarative-token-parse.js +74 -0
  330. package/lib/utils/url-declarative-url-flags.js +50 -0
  331. package/lib/utils/url-declarative-vdir-inactive-env.js +99 -0
  332. package/lib/utils/url-public-path-prefix.js +34 -0
  333. package/lib/utils/urls-local-registry.js +220 -0
  334. package/lib/utils/validation-report-tty-kit.js +77 -0
  335. package/lib/utils/validation-run-poll.js +112 -0
  336. package/lib/utils/validation-run-post-retry.js +85 -0
  337. package/lib/utils/validation-run-request.js +116 -0
  338. package/lib/utils/variable-transformer.js +21 -4
  339. package/lib/utils/yaml-preserve.js +33 -14
  340. package/lib/validation/datasource-warnings.js +56 -0
  341. package/lib/validation/env-template-auth.js +1 -1
  342. package/lib/validation/external-manifest-validator.js +27 -7
  343. package/lib/validation/validate-display.js +37 -31
  344. package/lib/validation/validate-external-cert-sync.js +23 -0
  345. package/lib/validation/validate.js +8 -14
  346. package/lib/validation/validator-unresolved-placeholders.js +98 -0
  347. package/lib/validation/validator.js +22 -65
  348. package/lib/validation/wizard-config-validator.js +2 -1
  349. package/package.json +9 -4
  350. package/scripts/check-datasource-test-run-schema-sync.js +34 -0
  351. package/scripts/diagnose-cli.js +150 -0
  352. package/scripts/install-local.js +307 -55
  353. package/scripts/pnpm-global-remove.js +48 -0
  354. package/templates/README.md +15 -2
  355. package/templates/applications/dataplane/application.yaml +52 -2
  356. package/templates/applications/dataplane/env.template +79 -17
  357. package/templates/applications/dataplane/rbac.yaml +8 -0
  358. package/templates/applications/keycloak/application.yaml +9 -1
  359. package/templates/applications/keycloak/env.template +15 -6
  360. package/templates/applications/miso-controller/application.yaml +10 -2
  361. package/templates/applications/miso-controller/env.template +42 -12
  362. package/templates/applications/miso-controller/rbac.yaml +5 -0
  363. package/templates/external-system/README.md.hbs +20 -7
  364. package/templates/external-system/deploy.js.hbs +5 -5
  365. package/templates/external-system/external-datasource.yaml.hbs +197 -118
  366. package/templates/infra/compose.yaml.hbs +33 -16
  367. package/templates/infra/servers.json.hbs +3 -1
  368. package/templates/python/docker-compose.hbs +16 -0
  369. package/templates/typescript/docker-compose.hbs +16 -0
  370. package/lib/api/external-test.api.js +0 -111
  371. package/lib/schema/env-config.yaml +0 -60
@@ -17,7 +17,7 @@ const os = require('os');
17
17
  const config = require('./config');
18
18
  const pathsUtil = require('../utils/paths');
19
19
  const logger = require('../utils/logger');
20
- const { isRemoteSecretsUrl, getRemoteDevAuth } = require('../utils/remote-dev-auth');
20
+ const remoteDevAuth = require('../utils/remote-dev-auth');
21
21
  const devApi = require('../api/dev.api');
22
22
  const {
23
23
  findMissingSecretKeys,
@@ -28,6 +28,21 @@ const {
28
28
  } = require('../utils/secrets-generator');
29
29
  const { encryptSecret } = require('../utils/secrets-encryption');
30
30
  const { loadEnvTemplate } = require('../utils/secrets-helpers');
31
+ const {
32
+ buildInfraPlaceholderContext,
33
+ isSecretKeyAllowedEmpty,
34
+ getInfraSecretKeysForUpInfra
35
+ } = require('./secrets-ensure-infra');
36
+ const { syncLiteralKvSecretsFromCliOverrides } = require('./secrets-infra-placeholder-sync');
37
+
38
+ /**
39
+ * Lazy require so tests that `jest.mock('../parameters/infra-parameter-catalog')` after other
40
+ * suites loaded secrets-ensure still see the mocked exports (avoids stale destructured refs).
41
+ * @returns {typeof import('../parameters/infra-parameter-catalog')}
42
+ */
43
+ function infraParameterCatalogModule() {
44
+ return require('../parameters/infra-parameter-catalog');
45
+ }
31
46
 
32
47
  /**
33
48
  * Expand leading ~ to home directory.
@@ -49,27 +64,30 @@ function expandTilde(filePath) {
49
64
  * - http(s) URL → remote (fallback: user file)
50
65
  * - No config → user file
51
66
  *
52
- * @returns {Promise<{ type: 'file'|'remote', filePath?: string, serverUrl?: string, clientCertPem?: string }>}
67
+ * @returns {Promise<{ type: 'file'|'remote', filePath?: string, serverUrl?: string|null, secretsEndpointUrl?: string, clientCertPem?: string|null, serverCaPem?: string|null }>}
53
68
  */
54
69
  async function resolveWriteTarget() {
55
70
  const secretsPath = await config.getSecretsPath();
56
- const userFilePath = path.join(pathsUtil.getAifabrixHome(), 'secrets.local.yaml');
71
+ const userFilePath = pathsUtil.getPrimaryUserSecretsLocalPath();
57
72
 
58
73
  if (!secretsPath) {
59
74
  return { type: 'file', filePath: userFilePath };
60
75
  }
61
- if (isRemoteSecretsUrl(secretsPath)) {
62
- const auth = await getRemoteDevAuth();
76
+ const resolvedSecrets = await remoteDevAuth.resolveSharedSecretsEndpoint(secretsPath);
77
+ if (remoteDevAuth.isRemoteSecretsUrl(resolvedSecrets)) {
78
+ const auth = await remoteDevAuth.getRemoteDevAuth();
63
79
  return {
64
80
  type: 'remote',
65
81
  filePath: userFilePath,
66
- serverUrl: secretsPath.replace(/\/+$/, ''),
67
- clientCertPem: auth ? auth.clientCertPem : null
82
+ serverUrl: auth ? auth.serverUrl : null,
83
+ secretsEndpointUrl: resolvedSecrets.trim().replace(/\/+$/, ''),
84
+ clientCertPem: auth ? auth.clientCertPem : null,
85
+ serverCaPem: auth ? auth.serverCaPem : null
68
86
  };
69
87
  }
70
- const filePath = path.isAbsolute(secretsPath)
71
- ? secretsPath
72
- : path.resolve(process.cwd(), expandTilde(secretsPath));
88
+ const filePath = path.isAbsolute(resolvedSecrets)
89
+ ? resolvedSecrets
90
+ : path.resolve(process.cwd(), expandTilde(resolvedSecrets));
73
91
  return { type: 'file', filePath };
74
92
  }
75
93
 
@@ -85,7 +103,12 @@ async function loadExistingFromTarget(target) {
85
103
  }
86
104
  if (target.type === 'remote' && target.serverUrl && target.clientCertPem) {
87
105
  try {
88
- const items = await devApi.listSecrets(target.serverUrl, target.clientCertPem);
106
+ const items = await devApi.listSecrets(
107
+ target.serverUrl,
108
+ target.clientCertPem,
109
+ target.serverCaPem || undefined,
110
+ target.secretsEndpointUrl
111
+ );
89
112
  if (!Array.isArray(items)) return {};
90
113
  const obj = {};
91
114
  for (const item of items) {
@@ -134,11 +157,12 @@ async function writeSecretToFile(filePath, key, value, encryptionKey) {
134
157
  * @param {string} key - Secret key
135
158
  * @param {Object} suggested - Map of suggested values
136
159
  * @param {boolean} emptyForCredentials - Use empty string if true
160
+ * @param {Record<string, string>|undefined} placeholderContext - Catalog defaults + CLI merged map
137
161
  * @returns {string}
138
162
  */
139
- function valueForKey(key, suggested, emptyForCredentials) {
163
+ function valueForKey(key, suggested, emptyForCredentials, placeholderContext) {
140
164
  if (key in suggested) return String(suggested[key]);
141
- return emptyForCredentials ? '' : generateSecretValue(key);
165
+ return emptyForCredentials ? '' : generateSecretValue(key, placeholderContext);
142
166
  }
143
167
 
144
168
  /**
@@ -150,12 +174,18 @@ function valueForKey(key, suggested, emptyForCredentials) {
150
174
  * @param {string|null} encryptionKey - Encryption key for file fallback or null
151
175
  * @returns {Promise<string[]>}
152
176
  */
153
- async function addSecretsRemote(target, toAdd, suggested, added, encryptionKey) {
177
+ async function addSecretsRemote(target, toAdd, suggested, added, encryptionKey, placeholderContext) {
154
178
  const emptyForCredentials = false;
155
179
  for (const key of toAdd) {
156
- const value = valueForKey(key, suggested, emptyForCredentials);
180
+ const value = valueForKey(key, suggested, emptyForCredentials, placeholderContext);
157
181
  try {
158
- await devApi.addSecret(target.serverUrl, target.clientCertPem, { key, value });
182
+ await devApi.addSecret(
183
+ target.serverUrl,
184
+ target.clientCertPem,
185
+ { key, value },
186
+ target.serverCaPem || undefined,
187
+ target.secretsEndpointUrl
188
+ );
159
189
  added.push(key);
160
190
  } catch (err) {
161
191
  logger.warn(`Remote secret "${key}" failed (${err.message}); writing to local file.`);
@@ -168,22 +198,33 @@ async function addSecretsRemote(target, toAdd, suggested, added, encryptionKey)
168
198
 
169
199
  /**
170
200
  * Add secrets to file (with optional encryption).
171
- * @param {string} filePath - File path
172
- * @param {string[]} toAdd - Keys to add
173
- * @param {Object} suggested - Suggested values
174
- * @param {boolean} emptyForCredentials - Use empty for new values
175
- * @param {string|null} encryptionKey - Encryption key or null
176
- * @param {string[]} added - Array to push added keys to
201
+ * @param {Object} batch
202
+ * @param {string} batch.filePath
203
+ * @param {string[]} batch.toAdd
204
+ * @param {Object} batch.suggested
205
+ * @param {boolean} batch.emptyForCredentials
206
+ * @param {string|null} batch.encryptionKey
207
+ * @param {string[]} batch.added
208
+ * @param {Record<string, string>|undefined} batch.placeholderContext
177
209
  * @returns {Promise<string[]>}
178
210
  */
179
- async function addSecretsToFile(filePath, toAdd, suggested, emptyForCredentials, encryptionKey, added) {
211
+ async function addSecretsToFile(batch) {
212
+ const {
213
+ filePath,
214
+ toAdd,
215
+ suggested,
216
+ emptyForCredentials,
217
+ encryptionKey,
218
+ added,
219
+ placeholderContext
220
+ } = batch;
180
221
  for (const key of toAdd) {
181
- const value = valueForKey(key, suggested, emptyForCredentials);
222
+ const value = valueForKey(key, suggested, emptyForCredentials, placeholderContext);
182
223
  await writeSecretToFile(filePath, key, value, encryptionKey);
183
224
  added.push(key);
184
225
  }
185
226
  if (added.length > 0) {
186
- logger.log(`✓ Ensured ${added.length} secret key(s): ${added.join(', ')}`);
227
+ logger.log(`✔ Ensured ${added.length} secret key(s): ${added.join(', ')}`);
187
228
  }
188
229
  return added;
189
230
  }
@@ -210,13 +251,14 @@ async function ensureSecretsForKeys(keys, options = {}) {
210
251
  const suggested = options.suggestedValues && typeof options.suggestedValues === 'object'
211
252
  ? options.suggestedValues
212
253
  : {};
254
+ const placeholderContext = options.placeholderContext;
213
255
 
214
256
  const target = options._targetOverride || await resolveWriteTarget();
215
257
  const existing = await loadExistingFromTarget(target);
216
258
  const toAdd = keys.filter((k) => {
217
259
  const v = existing[k];
218
260
  const missingOrEmpty = v === undefined || v === null || (typeof v === 'string' && v.trim() === '');
219
- return missingOrEmpty && !KEYS_ALLOWED_EMPTY.has(k);
261
+ return missingOrEmpty && !isSecretKeyAllowedEmpty(k);
220
262
  });
221
263
  if (toAdd.length === 0) return [];
222
264
 
@@ -224,9 +266,17 @@ async function ensureSecretsForKeys(keys, options = {}) {
224
266
  const added = [];
225
267
 
226
268
  if (target.type === 'remote' && target.serverUrl && target.clientCertPem) {
227
- return addSecretsRemote(target, toAdd, suggested, added, encryptionKey);
269
+ return addSecretsRemote(target, toAdd, suggested, added, encryptionKey, placeholderContext);
228
270
  }
229
- return addSecretsToFile(target.filePath, toAdd, suggested, emptyForCredentials, encryptionKey, added);
271
+ return addSecretsToFile({
272
+ filePath: target.filePath,
273
+ toAdd,
274
+ suggested,
275
+ emptyForCredentials,
276
+ encryptionKey,
277
+ added,
278
+ placeholderContext
279
+ });
230
280
  }
231
281
 
232
282
  /**
@@ -270,33 +320,6 @@ async function ensureSecretsFromEnvTemplate(envTemplatePathOrContent, options =
270
320
  return ensureSecretsForKeys(missingKeys, { ...options, _targetOverride: target });
271
321
  }
272
322
 
273
- /**
274
- * Infra secret keys used by createDefaultSecrets / keyvault.md for up-infra.
275
- * Includes miso-controller DB keys so ensureMisoInitScript can read from store.
276
- *
277
- * postgres-passwordKeyVault: Postgres superuser/admin password for local Docker Postgres,
278
- * PgAdmin, and Redis Commander (see generateAdminSecretsEnv in lib/core/secrets.js).
279
- *
280
- * @type {string[]}
281
- */
282
- const INFRA_SECRET_KEYS = [
283
- 'postgres-passwordKeyVault',
284
- 'redis-passwordKeyVault',
285
- 'redis-url',
286
- 'keycloak-admin-passwordKeyVault',
287
- 'keycloak-server-url',
288
- 'databases-miso-controller-0-passwordKeyVault',
289
- 'databases-miso-controller-0-urlKeyVault'
290
- ];
291
-
292
- /**
293
- * Keys that are valid when empty (e.g. no Redis password in local dev).
294
- * We do not backfill these when empty, so the file is not appended with a duplicate key.
295
- *
296
- * @type {Set<string>}
297
- */
298
- const KEYS_ALLOWED_EMPTY = new Set(['redis-passwordKeyVault']);
299
-
300
323
  /**
301
324
  * Write one key-value to a file store (load, merge, optionally encrypt, save).
302
325
  * @param {string} filePath - Secrets file path
@@ -325,7 +348,7 @@ async function writeSecretToStoreFile(filePath, key, strValue) {
325
348
 
326
349
  /**
327
350
  * Write a single secret to the configured store (overwrites if key exists).
328
- * Used when syncing e.g. postgres-passwordKeyVault after --adminPwd override.
351
+ * Used when syncing e.g. postgres-passwordKeyVault after --adminPassword override.
329
352
  *
330
353
  * @async
331
354
  * @function setSecretInStore
@@ -339,7 +362,13 @@ async function setSecretInStore(key, value) {
339
362
  const strValue = typeof value === 'string' ? value : String(value);
340
363
  if (target.type === 'remote' && target.serverUrl && target.clientCertPem) {
341
364
  try {
342
- await devApi.addSecret(target.serverUrl, target.clientCertPem, { key, value: strValue });
365
+ await devApi.addSecret(
366
+ target.serverUrl,
367
+ target.clientCertPem,
368
+ { key, value: strValue },
369
+ target.serverCaPem || undefined,
370
+ target.secretsEndpointUrl
371
+ );
343
372
  } catch (err) {
344
373
  logger.warn(`Could not sync secret "${key}" to remote store: ${err.message}`);
345
374
  const encryptionKey = await config.getSecretsEncryptionKey();
@@ -356,15 +385,27 @@ async function setSecretInStore(key, value) {
356
385
  * @async
357
386
  * @function ensureInfraSecrets
358
387
  * @param {Object} [options] - Options
359
- * @param {string} [options.adminPwd] - Override for postgres-passwordKeyVault when creating new secrets
388
+ * @param {string} [options.adminPassword] - Overrides {{adminPassword}} (and alias adminPwd)
389
+ * @param {string} [options.adminPwd] - Alias for adminPassword
390
+ * @param {string} [options.adminEmail] - Overrides {{adminEmail}}
391
+ * @param {string} [options.userPassword] - Overrides {{userPassword}}
392
+ * @param {boolean} [options.tlsEnabled] - Merged into catalog placeholders: TLS_ENABLED / HTTP_ENABLED (HTTP is opposite of TLS; default TLS off)
360
393
  * @returns {Promise<string[]>} Keys that were added
394
+ *
395
+ * After backfill, non-empty `--adminPassword` / `--userPassword` / `--adminEmail` update all catalog
396
+ * literals that reference the same `{{placeholder}}` (see `secrets-infra-placeholder-sync.js`).
361
397
  */
362
398
  async function ensureInfraSecrets(options = {}) {
363
- const suggested = {};
364
- if (options.adminPwd && typeof options.adminPwd === 'string' && options.adminPwd.trim() !== '') {
365
- suggested['postgres-passwordKeyVault'] = options.adminPwd.trim();
366
- }
367
- return ensureSecretsForKeys(INFRA_SECRET_KEYS, { suggestedValues: suggested });
399
+ const keys = getInfraSecretKeysForUpInfra();
400
+ const placeholderContext = buildInfraPlaceholderContext(options);
401
+ const added = await ensureSecretsForKeys(keys, { placeholderContext });
402
+ await syncLiteralKvSecretsFromCliOverrides(
403
+ options,
404
+ placeholderContext,
405
+ setSecretInStore,
406
+ infraParameterCatalogModule
407
+ );
408
+ return added;
368
409
  }
369
410
 
370
411
  module.exports = {
@@ -374,5 +415,20 @@ module.exports = {
374
415
  setSecretInStore,
375
416
  resolveWriteTarget,
376
417
  loadExistingFromTarget,
377
- INFRA_SECRET_KEYS
418
+ getInfraSecretKeysForUpInfra,
419
+ isSecretKeyAllowedEmpty,
420
+ buildInfraPlaceholderContext
378
421
  };
422
+
423
+ /**
424
+ * @deprecated Prefer getInfraSecretKeysForUpInfra(). Names only: relaxed read of infra.parameter.yaml
425
+ * (standardUpInfraEnsureKeys + exact keys with ensureOn upInfra), not workspace discovery.
426
+ */
427
+ Object.defineProperty(module.exports, 'INFRA_SECRET_KEYS', {
428
+ enumerable: true,
429
+ get() {
430
+ const cat = infraParameterCatalogModule();
431
+ const bundledYaml = path.join(__dirname, '..', 'schema', 'infra.parameter.yaml');
432
+ return cat.readRelaxedUpInfraEnsureKeyList(bundledYaml) || [];
433
+ }
434
+ });
@@ -47,7 +47,33 @@ function getSecretForEnvVar(secrets, preferred, alternate) {
47
47
  }
48
48
 
49
49
  /**
50
- * Inject NPM_TOKEN and PYPI_TOKEN from loaded secrets into content when missing.
50
+ * Append KEY=value as its own line (avoids joining with previous line when content ended with newline).
51
+ * @param {string} content
52
+ * @param {string} key
53
+ * @param {string} value
54
+ * @returns {string}
55
+ */
56
+ function appendEnvLine(content, key, value) {
57
+ const line = `${key}=${value}`;
58
+ if (!content || content.length === 0) return `${line}\n`;
59
+ return `${content.replace(/\s+$/, '')}\n${line}\n`;
60
+ }
61
+
62
+ /**
63
+ * Non-empty process.env for registry tokens when template has no kv://BASH_* line (inject fallback).
64
+ * @param {string} name
65
+ * @returns {string|null}
66
+ */
67
+ function getProcessEnvToken(name) {
68
+ const raw = process.env[name];
69
+ if (raw === undefined || raw === null) return null;
70
+ const t = String(raw).trim();
71
+ return t.length > 0 ? t : null;
72
+ }
73
+
74
+ /**
75
+ * Inject NPM_TOKEN and PYPI_TOKEN from loaded secrets, then from process.env when still missing.
76
+ * kv://BASH_* refs are resolved in secrets-helpers (process.env suffix after BASH_) before this runs.
51
77
  * @param {string} content - .env-style content
52
78
  * @param {string|null} secretsPath - Path to secrets file
53
79
  * @param {string} appName - Application name
@@ -59,12 +85,14 @@ async function injectRegistryTokens(content, secretsPath, appName) {
59
85
  const loadedSecrets = await secrets.loadSecrets(secretsPath, appName);
60
86
  let out = content || '';
61
87
  if (!envContentHasKey(out, 'NPM_TOKEN')) {
62
- const v = getSecretForEnvVar(loadedSecrets, 'NPM_TOKEN', 'npm_token');
63
- if (v) out = out.trimEnd() + (out.endsWith('\n') ? '' : '\n') + `NPM_TOKEN=${v}\n`;
88
+ let v = getSecretForEnvVar(loadedSecrets, 'NPM_TOKEN', 'npm_token');
89
+ if (!v) v = getProcessEnvToken('NPM_TOKEN');
90
+ if (v) out = appendEnvLine(out, 'NPM_TOKEN', v);
64
91
  }
65
92
  if (!envContentHasKey(out, 'PYPI_TOKEN')) {
66
- const v = getSecretForEnvVar(loadedSecrets, 'PYPI_TOKEN', 'pypi_token');
67
- if (v) out = out.trimEnd() + (out.endsWith('\n') ? '' : '\n') + `PYPI_TOKEN=${v}\n`;
93
+ let v = getSecretForEnvVar(loadedSecrets, 'PYPI_TOKEN', 'pypi_token');
94
+ if (!v) v = getProcessEnvToken('PYPI_TOKEN');
95
+ if (v) out = appendEnvLine(out, 'PYPI_TOKEN', v);
68
96
  }
69
97
  return out;
70
98
  } catch {
@@ -95,7 +123,7 @@ function parseEnvContentToMap(content) {
95
123
 
96
124
  /**
97
125
  * Resolve .env in memory and write only to envOutputPath or temp (no builder/ or integration/).
98
- * Injects NPM_TOKEN and PYPI_TOKEN from secrets when missing so shell/install/test have registry tokens.
126
+ * Injects NPM_TOKEN and PYPI_TOKEN from secrets when missing, then from process.env, so shell/install/test/build can use exported tokens.
99
127
  *
100
128
  * @async
101
129
  * @function resolveAndWriteEnvFile
@@ -136,7 +164,7 @@ async function resolveAndWriteEnvFile(appName, options = {}) {
136
164
  /**
137
165
  * Resolve app env (template + kv:// secrets) and return as key-value map.
138
166
  * Used by build to pass NPM_TOKEN/PYPI_TOKEN as Docker build-args.
139
- * Injects NPM_TOKEN/PYPI_TOKEN from secrets when missing (same as resolveAndWriteEnvFile).
167
+ * Injects from secrets when missing, then from process.env if set (e.g. exported NPM_TOKEN in shell).
140
168
  *
141
169
  * @async
142
170
  * @function resolveAndGetEnvMap
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @fileoverview Sync secrets store with up-infra CLI placeholder overrides (catalog-driven).
3
+ * @author AI Fabrix Team
4
+ * @version 2.0.0
5
+ */
6
+
7
+ const logger = require('../utils/logger');
8
+
9
+ /**
10
+ * When CLI passes --adminPassword, --userPassword, or --adminEmail, overwrite every catalog literal
11
+ * that embeds the matching {{placeholder}}. ensureSecretsForKeys only backfills missing keys; this
12
+ * keeps the store aligned with explicit CLI overrides (keys come from infra.parameter.yaml).
13
+ *
14
+ * @param {Object} options - Same flags as ensureInfraSecrets
15
+ * @param {Record<string, string>} placeholderContext - Merged catalog defaults + CLI
16
+ * @param {(key: string, value: string) => Promise<void>} setSecretInStore
17
+ * @param {() => typeof import('../parameters/infra-parameter-catalog')} getCatalogModule - Lazy catalog require
18
+ * @returns {Promise<void>}
19
+ */
20
+ async function syncLiteralKvSecretsFromCliOverrides(
21
+ options,
22
+ placeholderContext,
23
+ setSecretInStore,
24
+ getCatalogModule
25
+ ) {
26
+ const crypto = require('crypto');
27
+ const ipc = getCatalogModule();
28
+ let catalog;
29
+ try {
30
+ catalog = ipc.getInfraParameterCatalog();
31
+ } catch {
32
+ return;
33
+ }
34
+
35
+ const runOne = async(placeholder, cliValue) => {
36
+ const trimmed = String(cliValue || '').trim();
37
+ if (!trimmed) return;
38
+ const keys = ipc.listKvKeysWithLiteralPlaceholder(catalog, placeholder);
39
+ if (keys.length === 0) return;
40
+ for (const key of keys) {
41
+ const entry = catalog.findEntryForKey(key);
42
+ if (!entry) continue;
43
+ const val = ipc.generateValueFromCatalogEntry(key, entry, crypto, placeholderContext);
44
+ await setSecretInStore(key, val);
45
+ }
46
+ logger.log(
47
+ `Updated ${keys.length} secret(s) in store (catalog literals using {{${placeholder}}}).`
48
+ );
49
+ };
50
+
51
+ await runOne(
52
+ 'adminPassword',
53
+ options.adminPassword || options.adminPwd || ''
54
+ );
55
+ await runOne('userPassword', options.userPassword || '');
56
+ await runOne('adminEmail', options.adminEmail || '');
57
+ }
58
+
59
+ module.exports = {
60
+ syncLiteralKvSecretsFromCliOverrides
61
+ };