@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
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Synchronous fs helpers that use `global.__AIFABRIX_NODE_FS_UNMOCKED__` from
3
+ * `tests/capture-real-fs.js` when present so Jest `jest.mock('fs')` and partial
4
+ * `jest.mock('internal/node-fs')` cannot break config, schema, or builder scans.
5
+ *
6
+ * @fileoverview Real filesystem sync for config, schemas, urls.local registry, url:// resolution
7
+ */
8
+ 'use strict';
9
+
10
+ /**
11
+ * @returns {import('node:fs')|null}
12
+ */
13
+ function unmockedFsSnapshot() {
14
+ const g = typeof globalThis !== 'undefined' ? globalThis : global;
15
+ return g && g.__AIFABRIX_NODE_FS_UNMOCKED__ ? g.__AIFABRIX_NODE_FS_UNMOCKED__ : null;
16
+ }
17
+
18
+ function delegate(name, args) {
19
+ const snap = unmockedFsSnapshot();
20
+ if (snap && typeof snap[name] === 'function') {
21
+ return snap[name](...args);
22
+ }
23
+ // When Jest is active, bypass any manual module mocks of node:fs.
24
+ // This keeps schema/catalog reads stable even if a suite does jest.mock('node:fs').
25
+ const fs =
26
+ typeof jest !== 'undefined' && typeof jest.requireActual === 'function'
27
+ ? jest.requireActual('node:fs')
28
+ : require('node:fs');
29
+ return fs[name](...args);
30
+ }
31
+
32
+ /**
33
+ * @param {string} p
34
+ * @returns {boolean}
35
+ */
36
+ function existsSync(p) {
37
+ return delegate('existsSync', [p]);
38
+ }
39
+
40
+ /**
41
+ * Read file via snapshot/delegate only — not the same binding as {@link readFileSync} on `module.exports`.
42
+ * Tests may `jest.spyOn(exports, 'readFileSync')`; this function stays the real implementation for env/PIN paths.
43
+ * @param {string} p
44
+ * @param {string|import('node:fs').ObjectEncodingOptions} [enc]
45
+ * @returns {string|Buffer}
46
+ */
47
+ function readFileSyncDirect(p, enc) {
48
+ return delegate('readFileSync', enc !== undefined ? [p, enc] : [p]);
49
+ }
50
+
51
+ /**
52
+ * @param {string} p
53
+ * @param {string|import('node:fs').ObjectEncodingOptions} [enc]
54
+ * @returns {string|Buffer}
55
+ */
56
+ function readFileSync(p, enc) {
57
+ return readFileSyncDirect(p, enc);
58
+ }
59
+
60
+ /**
61
+ * @param {string} p
62
+ * @param {string|Buffer} data
63
+ * @param {object|string} [opts]
64
+ * @returns {void}
65
+ */
66
+ function writeFileSync(p, data, opts) {
67
+ return delegate('writeFileSync', opts !== undefined ? [p, data, opts] : [p, data]);
68
+ }
69
+
70
+ /**
71
+ * @param {string} p
72
+ * @param {object} [opts]
73
+ * @returns {string|undefined}
74
+ */
75
+ function mkdirSync(p, opts) {
76
+ return delegate('mkdirSync', opts !== undefined ? [p, opts] : [p]);
77
+ }
78
+
79
+ /**
80
+ * @param {string} p
81
+ * @returns {import('node:fs').Stats}
82
+ */
83
+ function statSync(p) {
84
+ return delegate('statSync', [p]);
85
+ }
86
+
87
+ /**
88
+ * @param {string} p
89
+ * @param {object} [opts]
90
+ * @returns {string[]|import('node:fs').Dirent[]}
91
+ */
92
+ function readdirSync(p, opts) {
93
+ return delegate('readdirSync', opts !== undefined ? [p, opts] : [p]);
94
+ }
95
+
96
+ module.exports = {
97
+ existsSync,
98
+ readFileSync,
99
+ readFileSyncDirect,
100
+ writeFileSync,
101
+ mkdirSync,
102
+ statSync,
103
+ readdirSync
104
+ };
@@ -0,0 +1,98 @@
1
+ /**
2
+ * @fileoverview Filesystem helpers that ignore jest.spyOn on require('node:fs') for sync reads.
3
+ * Uses jest.requireActual when Jest is active so .bind() captures native implementations even if
4
+ * this module loads after another suite spied fs. watch still delegates to live fs so tests can spy it.
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ /**
10
+ * Bound native fs from tests/capture-real-fs.js (Jest setupFiles, before mocks).
11
+ * @returns {Record<string, unknown>|null}
12
+ */
13
+ function getUnmockedFsSnapshot() {
14
+ const g = typeof globalThis !== 'undefined' ? globalThis : global;
15
+ return g && g.__AIFABRIX_NODE_FS_UNMOCKED__ ? g.__AIFABRIX_NODE_FS_UNMOCKED__ : null;
16
+ }
17
+
18
+ function getRealFs() {
19
+ const snap = getUnmockedFsSnapshot();
20
+ if (snap) {
21
+ return snap;
22
+ }
23
+ // When Jest is active, bypass manual module mocks (singleton may still carry spyOn).
24
+ if (typeof jest !== 'undefined' && typeof jest.requireActual === 'function') {
25
+ return jest.requireActual('node:fs');
26
+ }
27
+ return require('node:fs');
28
+ }
29
+
30
+ /**
31
+ * @param {import('node:fs')} fsModule
32
+ * @param {string} name
33
+ * @returns {unknown}
34
+ */
35
+ function bindSync(fsModule, name) {
36
+ const fn = fsModule[name];
37
+ return typeof fn === 'function' ? fn.bind(fsModule) : fn;
38
+ }
39
+
40
+ function liveFs() {
41
+ return require('node:fs');
42
+ }
43
+
44
+ /**
45
+ * Resolve real fs on each access so callers still see the filesystem after other
46
+ * suites replace require('fs') with mocks (schema-loader, schema sync helpers).
47
+ * @returns {typeof import('node:fs')}
48
+ */
49
+ function freshRealFs() {
50
+ return getRealFs();
51
+ }
52
+
53
+ /**
54
+ * @returns {Record<string, unknown>}
55
+ */
56
+ function buildBoundFs() {
57
+ const snap = getUnmockedFsSnapshot();
58
+ const rf = freshRealFs();
59
+ const live = liveFs();
60
+ const promiseHost = live.promises || {};
61
+ const boundPromises = {
62
+ mkdir: bindSync(promiseHost, 'mkdir'),
63
+ writeFile: bindSync(promiseHost, 'writeFile'),
64
+ appendFile: bindSync(promiseHost, 'appendFile'),
65
+ readFile: bindSync(promiseHost, 'readFile')
66
+ };
67
+ if (snap) {
68
+ return {
69
+ existsSync: snap.existsSync,
70
+ readFileSync: snap.readFileSync,
71
+ writeFileSync: snap.writeFileSync,
72
+ mkdirSync: snap.mkdirSync,
73
+ readdirSync: snap.readdirSync,
74
+ statSync: snap.statSync,
75
+ watch: (...args) => live.watch(...args),
76
+ promises: boundPromises
77
+ };
78
+ }
79
+ return {
80
+ existsSync: bindSync(rf, 'existsSync'),
81
+ readFileSync: bindSync(rf, 'readFileSync'),
82
+ writeFileSync: bindSync(rf, 'writeFileSync'),
83
+ mkdirSync: bindSync(rf, 'mkdirSync'),
84
+ readdirSync: bindSync(rf, 'readdirSync'),
85
+ statSync: bindSync(rf, 'statSync'),
86
+ watch: (...args) => live.watch(...args),
87
+ promises: boundPromises
88
+ };
89
+ }
90
+
91
+ /**
92
+ * @returns {ReturnType<typeof buildBoundFs>}
93
+ */
94
+ function nodeFs() {
95
+ return buildBoundFs();
96
+ }
97
+
98
+ module.exports = { nodeFs };
@@ -0,0 +1,173 @@
1
+ /**
2
+ * @fileoverview Index-aware local PostgreSQL URL/password defaults for databases-{app}-{i}-* keys
3
+ * @author AI Fabrix Team
4
+ * @version 2.1.0
5
+ */
6
+
7
+ const path = require('path');
8
+ const { nodeFs } = require('../internal/node-fs');
9
+ const yaml = require('js-yaml');
10
+
11
+ /**
12
+ * Shipped platform templates (when builder/<app> does not exist yet).
13
+ * Prefer Jest/global.PROJECT_ROOT when that tree contains templates (stable under isolated projects).
14
+ * @returns {string}
15
+ */
16
+ function getTemplatesApplicationsRoot() {
17
+ const fallback = path.join(__dirname, '..', '..', 'templates', 'applications');
18
+ try {
19
+ if (typeof global !== 'undefined' && global.PROJECT_ROOT) {
20
+ const g = path.join(path.resolve(String(global.PROJECT_ROOT)), 'templates', 'applications');
21
+ const marker = path.join(g, 'miso-controller', 'application.yaml');
22
+ if (nodeFs().existsSync(marker)) {
23
+ return g;
24
+ }
25
+ }
26
+ } catch {
27
+ /* ignore */
28
+ }
29
+ return fallback;
30
+ }
31
+
32
+ /**
33
+ * PostgreSQL role name from database name (same as compose pgUserName helper).
34
+ * @param {string} dbName - Logical database name (e.g. miso-logs)
35
+ * @returns {string}
36
+ */
37
+ function pgUserFromDbName(dbName) {
38
+ if (!dbName) return '';
39
+ return `${String(dbName).replace(/-/g, '_')}_user`;
40
+ }
41
+
42
+ /**
43
+ * Local dev password aligned with infra init scripts (user base + _pass123).
44
+ * @param {string} userName - e.g. miso_user, miso_logs_user
45
+ * @returns {string}
46
+ */
47
+ function localDevPasswordFromPgUser(userName) {
48
+ const base = String(userName).replace(/_user$/i, '');
49
+ return `${base}_pass123`;
50
+ }
51
+
52
+ /**
53
+ * Load requires.databases from application config if present (read-only; no rename).
54
+ * @param {string} appDir - Absolute path to builder/integration app folder
55
+ * @returns {Array<{name?: string}>|null}
56
+ */
57
+ function loadRequiresDatabasesArray(appDir) {
58
+ if (!appDir || !nodeFs().existsSync(appDir)) return null;
59
+ const candidates = ['application.yaml', 'application.yml', 'variables.yaml'];
60
+ for (const name of candidates) {
61
+ const p = path.join(appDir, name);
62
+ if (!nodeFs().existsSync(p)) continue;
63
+ try {
64
+ const doc = yaml.load(nodeFs().readFileSync(p, 'utf8'));
65
+ const dbs = doc?.requires?.databases;
66
+ if (Array.isArray(dbs) && dbs.length > 0) return dbs;
67
+ } catch {
68
+ /* ignore */
69
+ }
70
+ }
71
+ return null;
72
+ }
73
+
74
+ /**
75
+ * Load requires.databases from shipped Builder template (templates/applications/<appKey>/application.yaml).
76
+ * @param {string} appKey - Application key
77
+ * @returns {Array<{name?: string}>|null}
78
+ */
79
+ function loadShippedRequiresDatabases(appKey) {
80
+ if (!appKey || typeof appKey !== 'string') return null;
81
+ const p = path.join(getTemplatesApplicationsRoot(), appKey, 'application.yaml');
82
+ if (!nodeFs().existsSync(p)) return null;
83
+ try {
84
+ const doc = yaml.load(nodeFs().readFileSync(p, 'utf8'));
85
+ const dbs = doc?.requires?.databases;
86
+ return Array.isArray(dbs) && dbs.length > 0 ? dbs : null;
87
+ } catch {
88
+ return null;
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Resolve logical PostgreSQL database name for a databases-{appKey}-{index}-* key.
94
+ * @param {string} appKey - App key segment from secret key
95
+ * @param {number} index - Database index
96
+ * @param {string|null} appDir - Optional app directory to read application.yaml
97
+ * @returns {string}
98
+ */
99
+ function resolveLogicalDbName(appKey, index, appDir) {
100
+ const fromDir = appDir ? loadRequiresDatabasesArray(appDir) : null;
101
+ const dbs = fromDir || loadShippedRequiresDatabases(appKey);
102
+ if (dbs && dbs[index] && dbs[index].name) {
103
+ return String(dbs[index].name);
104
+ }
105
+ if (index === 0) {
106
+ return String(appKey).replace(/-/g, '_');
107
+ }
108
+ return `${String(appKey).replace(/-/g, '_')}_${index}`;
109
+ }
110
+
111
+ /**
112
+ * Parse databases-{appKey}-{index}-(urlKeyVault|passwordKeyVault).
113
+ * @param {string} key - Secret key
114
+ * @returns {{ appKey: string, index: number, kind: 'url'|'password' }|null}
115
+ */
116
+ function parseDatabaseSecretKey(key) {
117
+ const m = String(key).match(/^databases-([a-z0-9-]+)-(\d+)-(urlKeyVault|passwordKeyVault)$/i);
118
+ if (!m) return null;
119
+ return {
120
+ appKey: m[1],
121
+ index: parseInt(m[2], 10),
122
+ kind: m[3].toLowerCase().startsWith('url') ? 'url' : 'password'
123
+ };
124
+ }
125
+
126
+ /**
127
+ * Build postgres URL with unresolved host/port placeholders.
128
+ * @param {string} dbName - Database name in connection path (may contain hyphens)
129
+ * @param {string} userName - DB user
130
+ * @param {string} password - DB password
131
+ * @returns {string}
132
+ */
133
+ function buildPostgresUrlTemplate(dbName, userName, password) {
134
+ return `postgresql://${userName}:${password}@\${DB_HOST}:\${DB_PORT}/${dbName}`;
135
+ }
136
+
137
+ /**
138
+ * Generate password value for databases-*-passwordKeyVault.
139
+ * @param {string} key - Full secret key
140
+ * @param {string|null} appDir - Optional app directory for YAML lookup
141
+ * @returns {string|null} Value or null if key does not match
142
+ */
143
+ function generateDatabasePasswordValueForKey(key, appDir = null) {
144
+ const parsed = parseDatabaseSecretKey(key);
145
+ if (!parsed || parsed.kind !== 'password') return null;
146
+ const dbName = resolveLogicalDbName(parsed.appKey, parsed.index, appDir);
147
+ const user = pgUserFromDbName(dbName);
148
+ return localDevPasswordFromPgUser(user);
149
+ }
150
+
151
+ /**
152
+ * Generate URL value for databases-*-urlKeyVault.
153
+ * @param {string} key - Full secret key
154
+ * @param {string|null} appDir - Optional app directory for YAML lookup
155
+ * @returns {string|null} Value or null if key does not match
156
+ */
157
+ function generateDatabaseUrlValueForKey(key, appDir = null) {
158
+ const parsed = parseDatabaseSecretKey(key);
159
+ if (!parsed || parsed.kind !== 'url') return null;
160
+ const dbName = resolveLogicalDbName(parsed.appKey, parsed.index, appDir);
161
+ const user = pgUserFromDbName(dbName);
162
+ const pass = localDevPasswordFromPgUser(user);
163
+ return buildPostgresUrlTemplate(dbName, user, pass);
164
+ }
165
+
166
+ module.exports = {
167
+ parseDatabaseSecretKey,
168
+ generateDatabasePasswordValueForKey,
169
+ generateDatabaseUrlValueForKey,
170
+ loadRequiresDatabasesArray,
171
+ loadShippedRequiresDatabases,
172
+ resolveLogicalDbName
173
+ };
@@ -0,0 +1,121 @@
1
+ /**
2
+ * @fileoverview Discover kv:// keys for up-infra from workspace templates and application.yaml
3
+ * @author AI Fabrix Team
4
+ * @version 2.0.0
5
+ */
6
+
7
+ const fsRealSync = require('../internal/fs-real-sync');
8
+ const path = require('path');
9
+ const { loadRequiresDatabasesArray } = require('./database-secret-values');
10
+
11
+ /**
12
+ * Extract kv:// secret key names from env template content (active lines only).
13
+ * @param {string} content - env.template body
14
+ * @returns {string[]}
15
+ */
16
+ function extractKvKeysFromEnvContent(content) {
17
+ if (!content || typeof content !== 'string') return [];
18
+ const keys = new Set();
19
+ const kvPattern = /kv:\/\/([a-zA-Z0-9-_]+)/g;
20
+ const lines = content.split('\n');
21
+ for (const line of lines) {
22
+ const t = line.trim();
23
+ if (t === '' || t.startsWith('#')) continue;
24
+ let m;
25
+ kvPattern.lastIndex = 0;
26
+ while ((m = kvPattern.exec(line)) !== null) {
27
+ keys.add(m[1]);
28
+ }
29
+ }
30
+ return [...keys];
31
+ }
32
+
33
+ /**
34
+ * List app directories for discovery (builder first, then integration-only apps).
35
+ * @param {object} pathsUtil - paths module
36
+ * @returns {{ appKey: string, dir: string }[]}
37
+ */
38
+ function listAppDirsForDiscovery(pathsUtil) {
39
+ const out = [];
40
+ const seen = new Set();
41
+ for (const name of pathsUtil.listBuilderAppNames()) {
42
+ const dir = pathsUtil.getBuilderPath(name);
43
+ if (fsRealSync.existsSync(dir)) {
44
+ out.push({ appKey: name, dir });
45
+ seen.add(name);
46
+ }
47
+ }
48
+ for (const name of pathsUtil.listIntegrationAppNames()) {
49
+ if (seen.has(name)) continue;
50
+ const dir = pathsUtil.getIntegrationPath(name);
51
+ if (fsRealSync.existsSync(dir)) {
52
+ out.push({ appKey: name, dir });
53
+ }
54
+ }
55
+ return out;
56
+ }
57
+
58
+ /**
59
+ * Derive databases-{appKey}-{i}-url/password keys from requires.databases length.
60
+ * @param {object} pathsUtil - paths module
61
+ * @returns {string[]}
62
+ */
63
+ function deriveDatabaseKvKeysFromWorkspace(pathsUtil) {
64
+ const keys = new Set();
65
+ for (const { appKey, dir } of listAppDirsForDiscovery(pathsUtil)) {
66
+ const dbs = loadRequiresDatabasesArray(dir);
67
+ if (!Array.isArray(dbs) || dbs.length === 0) continue;
68
+ for (let i = 0; i < dbs.length; i++) {
69
+ keys.add(`databases-${appKey}-${i}-urlKeyVault`);
70
+ keys.add(`databases-${appKey}-${i}-passwordKeyVault`);
71
+ }
72
+ }
73
+ return [...keys];
74
+ }
75
+
76
+ /**
77
+ * Keys from env.template files whose catalog entry includes the given hook (e.g. upInfra).
78
+ * @param {object} pathsUtil - paths module
79
+ * @param {string} hook - ensureOn hook name
80
+ * @param {{ keyMatchesEnsureHook: Function }} catalog - loaded catalog API
81
+ * @returns {string[]}
82
+ */
83
+ function discoverKvKeysFromEnvTemplatesForHook(pathsUtil, hook, catalog) {
84
+ const keys = new Set();
85
+ for (const { dir } of listAppDirsForDiscovery(pathsUtil)) {
86
+ const envPath = path.join(dir, 'env.template');
87
+ if (!fsRealSync.existsSync(envPath)) continue;
88
+ let content;
89
+ try {
90
+ content = fsRealSync.readFileSync(envPath, 'utf8');
91
+ } catch {
92
+ continue;
93
+ }
94
+ for (const k of extractKvKeysFromEnvContent(content)) {
95
+ if (catalog.keyMatchesEnsureHook(k, hook)) keys.add(k);
96
+ }
97
+ }
98
+ return [...keys];
99
+ }
100
+
101
+ /**
102
+ * Full key list for ensureInfraSecrets: catalog exact upInfra + standard miso DB + derived DB + template hooks.
103
+ * @param {{ getEnsureOnKeys: Function, keyMatchesEnsureHook: Function }} catalog
104
+ * @param {object} pathsUtil - paths module
105
+ * @returns {string[]}
106
+ */
107
+ function getAllInfraEnsureKeys(catalog, pathsUtil) {
108
+ const set = new Set(catalog.getEnsureOnKeys('upInfra'));
109
+ for (const k of catalog.getStandardUpInfraBootstrapKeys()) set.add(k);
110
+ for (const k of deriveDatabaseKvKeysFromWorkspace(pathsUtil)) set.add(k);
111
+ for (const k of discoverKvKeysFromEnvTemplatesForHook(pathsUtil, 'upInfra', catalog)) set.add(k);
112
+ return [...set].sort();
113
+ }
114
+
115
+ module.exports = {
116
+ extractKvKeysFromEnvContent,
117
+ deriveDatabaseKvKeysFromWorkspace,
118
+ discoverKvKeysFromEnvTemplatesForHook,
119
+ getAllInfraEnsureKeys,
120
+ listAppDirsForDiscovery
121
+ };