@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,59 @@
1
+ /**
2
+ * @fileoverview SHA-256 compare Builder vs Dataplane DatasourceTestRun JSON Schema (plan §8.1).
3
+ * @author AI Fabrix Team
4
+ * @version 2.0.0
5
+ */
6
+
7
+ const crypto = require('crypto');
8
+ const { nodeFs } = require('../internal/node-fs');
9
+
10
+ /**
11
+ * @param {string} filePath - Absolute path to file
12
+ * @returns {string} Lowercase hex SHA-256 of file bytes
13
+ */
14
+ function sha256FileSync(filePath) {
15
+ const buf = nodeFs().readFileSync(filePath);
16
+ return crypto.createHash('sha256').update(buf).digest('hex');
17
+ }
18
+
19
+ /**
20
+ * Compare two schema files; throws on mismatch when both exist.
21
+ * @param {string} builderSchemaPath
22
+ * @param {string} dataplaneSchemaPath
23
+ * @returns {{ skipped: boolean, reason?: string, builderSha?: string, dataplaneSha?: string }}
24
+ */
25
+ function assertDatasourceTestRunSchemasInSync(builderSchemaPath, dataplaneSchemaPath) {
26
+ if (!nodeFs().existsSync(builderSchemaPath)) {
27
+ throw new Error(`Builder schema not found: ${builderSchemaPath}`);
28
+ }
29
+ if (!nodeFs().existsSync(dataplaneSchemaPath)) {
30
+ return {
31
+ skipped: true,
32
+ reason: `Dataplane schema not found (set AIFABRIX_DATAPLANE_ROOT or checkout sibling repo): ${dataplaneSchemaPath}`
33
+ };
34
+ }
35
+ const builderSha = sha256FileSync(builderSchemaPath);
36
+ let dataplaneSha;
37
+ try {
38
+ dataplaneSha = sha256FileSync(dataplaneSchemaPath);
39
+ } catch (err) {
40
+ if (err && err.code === 'ENOENT') {
41
+ return {
42
+ skipped: true,
43
+ reason: `Dataplane schema not found (set AIFABRIX_DATAPLANE_ROOT or checkout sibling repo): ${dataplaneSchemaPath}`
44
+ };
45
+ }
46
+ throw err;
47
+ }
48
+ if (builderSha !== dataplaneSha) {
49
+ throw new Error(
50
+ `DatasourceTestRun schema drift: builder ${builderSha} ≠ dataplane ${dataplaneSha}`
51
+ );
52
+ }
53
+ return { skipped: false, builderSha, dataplaneSha };
54
+ }
55
+
56
+ module.exports = {
57
+ sha256FileSync,
58
+ assertDatasourceTestRunSchemasInSync
59
+ };
@@ -0,0 +1,81 @@
1
+ /**
2
+ * @fileoverview Log DatasourceTestRun to TTY — shared by datasource commands and external system server tests.
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ const chalk = require('chalk');
8
+ const logger = require('./logger');
9
+ const { getReportVersionStderrMessage } = require('./datasource-test-run-report-version');
10
+ const {
11
+ formatDatasourceTestRunSummary,
12
+ formatDatasourceTestRunTTY
13
+ } = require('./datasource-test-run-display');
14
+ const {
15
+ resolveDebugDisplayMode,
16
+ formatDatasourceTestRunDebugBlock
17
+ } = require('./datasource-test-run-debug-display');
18
+ const { analyzeCapabilityScope } = require('./datasource-test-run-capability-scope');
19
+
20
+ function emitReportVersionDiagnostics(envelope) {
21
+ if (!envelope || typeof envelope !== 'object') return;
22
+ const msg = getReportVersionStderrMessage(envelope.reportVersion);
23
+ if (!msg) return;
24
+ if (msg.level === 'warn') logger.warn(chalk.yellow(msg.message));
25
+ else if (msg.level === 'info') logger.log(chalk.gray(msg.message));
26
+ }
27
+
28
+ function emitCapabilityScopeDiagnostics(envelope, opts = {}) {
29
+ const scope = analyzeCapabilityScope(envelope, opts.requestedCapabilityKey);
30
+ if (scope.violated && scope.message) {
31
+ logger.warn(chalk.yellow(`⚠ ${scope.message}`));
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Print envelope (JSON, summary, or full TTY + optional debug appendix). Does not emit reportVersion/capability diagnostics.
37
+ * @param {Object} envelope
38
+ * @param {Object} options
39
+ * @param {boolean} [options.json]
40
+ * @param {boolean} [options.summary]
41
+ * @param {boolean|string} [options.debug]
42
+ * @param {string} [options.requestedCapabilityKey]
43
+ */
44
+ function printDatasourceTestRunForTTY(envelope, options = {}) {
45
+ const displayOpts = { focusCapabilityKey: options.requestedCapabilityKey };
46
+ if (options.json) {
47
+ logger.log(JSON.stringify(envelope));
48
+ return;
49
+ }
50
+ if (options.summary) {
51
+ logger.log(formatDatasourceTestRunSummary(envelope, displayOpts));
52
+ } else {
53
+ logger.log(formatDatasourceTestRunTTY(envelope, displayOpts));
54
+ }
55
+ const mode = resolveDebugDisplayMode(options.debug);
56
+ if (mode) {
57
+ const appendix = formatDatasourceTestRunDebugBlock(envelope, mode, process.stdout.isTTY);
58
+ if (appendix) logger.log(appendix);
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Emit diagnostics + human output for one server validation run (integration / test / e2e).
64
+ * @param {Object|null|undefined} envelope
65
+ * @param {Object} options - Same flags as unified CLI (json, summary, debug, requestedCapabilityKey)
66
+ */
67
+ function logEnvelopeForInteractiveCli(envelope, options = {}) {
68
+ if (!envelope || typeof envelope !== 'object') return;
69
+ emitReportVersionDiagnostics(envelope);
70
+ emitCapabilityScopeDiagnostics(envelope, {
71
+ requestedCapabilityKey: options.requestedCapabilityKey
72
+ });
73
+ printDatasourceTestRunForTTY(envelope, options);
74
+ }
75
+
76
+ module.exports = {
77
+ emitReportVersionDiagnostics,
78
+ emitCapabilityScopeDiagnostics,
79
+ printDatasourceTestRunForTTY,
80
+ logEnvelopeForInteractiveCli
81
+ };
@@ -0,0 +1,266 @@
1
+ /**
2
+ * @fileoverview File watch + debounce for datasource validation CLI (plan §3.14).
3
+ * @author AI Fabrix Team
4
+ * @version 2.0.0
5
+ */
6
+
7
+ const path = require('path');
8
+ const { nodeFs } = require('../internal/node-fs');
9
+ const chalk = require('chalk');
10
+ const logger = require('./logger');
11
+
12
+ /**
13
+ * Resolve integration path at call time so tests' jest.mock('./paths') applies even if this module
14
+ * was first loaded in a worker before the mock (eager destructuring would keep the real fn).
15
+ * @param {string} appKey
16
+ * @returns {string}
17
+ */
18
+ function getIntegrationPathForWatch(appKey) {
19
+ return require('./paths').getIntegrationPath(appKey);
20
+ }
21
+
22
+ const DEFAULT_DEBOUNCE_MS = 500;
23
+ const MAX_DIR_DEPTH = 14;
24
+
25
+ const SKIP_DIR_NAMES = new Set(['node_modules', '.git', 'dist', 'logs', '.turbo']);
26
+
27
+ /**
28
+ * @param {Object|null|undefined} envelope
29
+ * @returns {string}
30
+ */
31
+ function fingerprintForWatchDiff(envelope) {
32
+ if (!envelope || typeof envelope !== 'object') return '';
33
+ const capList = (Array.isArray(envelope.capabilities) ? envelope.capabilities : [])
34
+ .map(c =>
35
+ c && c.key !== undefined && c.key !== null ? `${c.key}:${c.status}` : '?'
36
+ )
37
+ .sort()
38
+ .join('|');
39
+ const certSt = envelope.certificate && envelope.certificate.status;
40
+ return `status=${envelope.status}|cert=${certSt || 'none'}|caps=${capList}`;
41
+ }
42
+
43
+ /**
44
+ * @param {string|null} prev
45
+ * @param {string} next
46
+ * @param {boolean} fullDiff
47
+ * @returns {string|null}
48
+ */
49
+ function formatWatchFingerprintDiff(prev, next, fullDiff) {
50
+ if (prev === null || prev === undefined || prev === next) return null;
51
+ if (fullDiff) {
52
+ return `Watch diff:\n before: ${prev}\n after: ${next}`;
53
+ }
54
+ return `Watch diff: ${chalk.yellow(prev)} → ${chalk.green(next)}`;
55
+ }
56
+
57
+ /**
58
+ * @param {string} root
59
+ * @param {number} maxDepth
60
+ * @param {number} depth
61
+ * @returns {string[]}
62
+ */
63
+ function listDirectoriesRecursive(root, maxDepth, depth = 0) {
64
+ const out = [];
65
+ if (depth > maxDepth || !nodeFs().existsSync(root)) return out;
66
+ let st;
67
+ try {
68
+ st = nodeFs().statSync(root);
69
+ } catch {
70
+ return out;
71
+ }
72
+ if (!st.isDirectory()) {
73
+ return [root];
74
+ }
75
+ out.push(root);
76
+ let entries;
77
+ try {
78
+ entries = nodeFs().readdirSync(root, { withFileTypes: true });
79
+ } catch {
80
+ return out;
81
+ }
82
+ for (const ent of entries) {
83
+ if (SKIP_DIR_NAMES.has(ent.name)) continue;
84
+ if (ent.isDirectory()) {
85
+ out.push(...listDirectoriesRecursive(path.join(root, ent.name), maxDepth, depth + 1));
86
+ }
87
+ }
88
+ return out;
89
+ }
90
+
91
+ /**
92
+ * @param {string} appKey
93
+ * @param {string[]} [extraPaths]
94
+ * @param {boolean} [includeApplicationYaml]
95
+ * @returns {{ kind: 'file'|'dir', path: string }[]}
96
+ */
97
+ function buildWatchTargetList(appKey, extraPaths = [], includeApplicationYaml = false) {
98
+ const integrationRoot = getIntegrationPathForWatch(appKey);
99
+ const seen = new Set();
100
+ /** @type {{ kind: 'file'|'dir', path: string }[]} */
101
+ const list = [];
102
+
103
+ function addFile(abs) {
104
+ if (!nodeFs().existsSync(abs) || seen.has(abs)) return;
105
+ seen.add(abs);
106
+ list.push({ kind: 'file', path: abs });
107
+ }
108
+
109
+ function addDirTree(absRoot) {
110
+ if (!nodeFs().existsSync(absRoot)) return;
111
+ const st = nodeFs().statSync(absRoot);
112
+ if (st.isFile()) {
113
+ addFile(absRoot);
114
+ return;
115
+ }
116
+ const dirs = listDirectoriesRecursive(absRoot, MAX_DIR_DEPTH);
117
+ for (const d of dirs) {
118
+ if (seen.has(d)) continue;
119
+ seen.add(d);
120
+ list.push({ kind: 'dir', path: d });
121
+ }
122
+ }
123
+
124
+ addDirTree(integrationRoot);
125
+
126
+ for (const p of extraPaths) {
127
+ if (!p || typeof p !== 'string') continue;
128
+ const abs = path.resolve(p.trim());
129
+ if (!nodeFs().existsSync(abs)) continue;
130
+ const pst = nodeFs().statSync(abs);
131
+ if (pst.isFile()) {
132
+ addFile(abs);
133
+ } else {
134
+ addDirTree(abs);
135
+ }
136
+ }
137
+
138
+ if (includeApplicationYaml) {
139
+ const y = path.join(integrationRoot, 'application.yaml');
140
+ addFile(y);
141
+ }
142
+
143
+ return list;
144
+ }
145
+
146
+ /**
147
+ * @param {() => void} fn
148
+ * @param {number} ms
149
+ * @returns {() => void}
150
+ */
151
+ function debounce(fn, ms) {
152
+ let t = null;
153
+ return () => {
154
+ if (t) clearTimeout(t);
155
+ t = setTimeout(() => {
156
+ t = null;
157
+ fn();
158
+ }, ms);
159
+ };
160
+ }
161
+
162
+ /**
163
+ * @param {{ kind: 'file'|'dir', path: string }[]} targets
164
+ * @param {() => void} onEvent
165
+ * @returns {() => void}
166
+ */
167
+ function startWatchers(targets, onEvent) {
168
+ const handles = [];
169
+ for (const t of targets) {
170
+ try {
171
+ handles.push(nodeFs().watch(t.path, () => onEvent()));
172
+ } catch {
173
+ // ignore unreadable paths
174
+ }
175
+ }
176
+ return () => {
177
+ for (const h of handles) {
178
+ try {
179
+ h.close();
180
+ } catch {
181
+ // ignore
182
+ }
183
+ }
184
+ };
185
+ }
186
+
187
+ /**
188
+ * @param {Object} opts
189
+ * @param {string} opts.appKey
190
+ * @param {string[]} [opts.extraPaths]
191
+ * @param {boolean} [opts.includeApplicationYaml]
192
+ * @param {number} [opts.debounceMs]
193
+ * @param {boolean} [opts.watchCi]
194
+ * @param {boolean} [opts.watchFullDiff]
195
+ * @param {() => Promise<{ exitCode: number, envelope: Object|null }>} opts.runOnce
196
+ * @returns {Promise<void>}
197
+ */
198
+ async function runDatasourceValidationWatchLoop(opts) {
199
+ const {
200
+ appKey,
201
+ extraPaths = [],
202
+ includeApplicationYaml = false,
203
+ debounceMs = DEFAULT_DEBOUNCE_MS,
204
+ watchCi = false,
205
+ watchFullDiff = false,
206
+ runOnce
207
+ } = opts;
208
+
209
+ const targets = buildWatchTargetList(appKey, extraPaths, includeApplicationYaml);
210
+ if (targets.length === 0) {
211
+ logger.warn(chalk.yellow('Watch: no directories or files to watch; check integration path.'));
212
+ process.exit(4);
213
+ return;
214
+ }
215
+
216
+ let prevFp = null;
217
+ let running = false;
218
+
219
+ const execute = async() => {
220
+ if (running) return;
221
+ running = true;
222
+ try {
223
+ logger.log(chalk.blue('\n[watch] Running validation…'));
224
+ const { exitCode, envelope } = await runOnce();
225
+ const fp = fingerprintForWatchDiff(envelope);
226
+ const diffMsg = formatWatchFingerprintDiff(prevFp, fp, watchFullDiff);
227
+ if (diffMsg) logger.log(diffMsg);
228
+ prevFp = fp;
229
+ if (watchCi) {
230
+ process.exit(exitCode);
231
+ return;
232
+ }
233
+ logger.log(chalk.gray(`[watch] exit code ${exitCode} — waiting for file changes (Ctrl+C to stop)`));
234
+ } finally {
235
+ running = false;
236
+ }
237
+ };
238
+
239
+ await execute();
240
+
241
+ // In production, watchCi triggers process.exit inside execute; with a mocked exit (tests),
242
+ // still skip watcher setup so the async function can finish and no duplicate runs occur.
243
+ if (watchCi) {
244
+ return;
245
+ }
246
+
247
+ const onFs = debounce(execute, debounceMs);
248
+ const closeAll = startWatchers(targets, onFs);
249
+
250
+ const onSig = () => {
251
+ closeAll();
252
+ process.exit(130);
253
+ };
254
+ process.on('SIGINT', onSig);
255
+ process.on('SIGTERM', onSig);
256
+ }
257
+
258
+ module.exports = {
259
+ DEFAULT_DEBOUNCE_MS,
260
+ fingerprintForWatchDiff,
261
+ formatWatchFingerprintDiff,
262
+ buildWatchTargetList,
263
+ debounce,
264
+ startWatchers,
265
+ runDatasourceValidationWatchLoop
266
+ };
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Host port math for declarative url:// resolution (plan 122).
3
+ *
4
+ * @fileoverview publishedHostPort vs localHostPort from manifest port + developer-id
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ /**
12
+ * @param {string|number|null|undefined} raw - developer-id from config
13
+ * @returns {number} Numeric id; non-numeric or empty → 0
14
+ */
15
+ function parseDeveloperIdNum(raw) {
16
+ if (raw === null || raw === undefined || raw === '') {
17
+ return 0;
18
+ }
19
+ const parsed = parseInt(String(raw).trim(), 10);
20
+ return Number.isNaN(parsed) ? 0 : parsed;
21
+ }
22
+
23
+ /**
24
+ * Docker published host port: port + devId*100 (dev 0 → base port).
25
+ * @param {number} appPort - Manifest listen port
26
+ * @param {number} developerIdNum
27
+ * @returns {number}
28
+ */
29
+ function publishedHostPort(appPort, developerIdNum) {
30
+ return appPort + developerIdNum * 100;
31
+ }
32
+
33
+ /**
34
+ * Local workstation host port: port + 10 + devId*100 (dev 0 → port+10).
35
+ * @param {number} appPort
36
+ * @param {number} developerIdNum
37
+ * @returns {number}
38
+ */
39
+ function localHostPort(appPort, developerIdNum) {
40
+ return appPort + 10 + developerIdNum * 100;
41
+ }
42
+
43
+ module.exports = {
44
+ parseDeveloperIdNum,
45
+ publishedHostPort,
46
+ localHostPort
47
+ };
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Derive pipeline/env segment (dev|tst|pro|miso) from MISO_CLIENTID convention.
3
+ *
4
+ * @fileoverview Plan 122 — optional MISO_PIPELINE_ENV_KEY override
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const ENV_TOKENS = new Set(['dev', 'tst', 'pro', 'miso']);
12
+
13
+ /**
14
+ * @param {string|null|undefined} clientId - e.g. miso-controller-dev-dataplane
15
+ * @param {string|null|undefined} pipelineOverride - MISO_PIPELINE_ENV_KEY when set in resolved env
16
+ * @returns {string} Lowercase env key (default miso)
17
+ */
18
+ function deriveEnvKeyFromClientId(clientId, pipelineOverride) {
19
+ const o = pipelineOverride !== undefined && pipelineOverride !== null
20
+ ? String(pipelineOverride).trim().toLowerCase()
21
+ : '';
22
+ if (o && ENV_TOKENS.has(o)) {
23
+ return o;
24
+ }
25
+ if (!clientId || typeof clientId !== 'string') {
26
+ return 'miso';
27
+ }
28
+ const parts = clientId.split('-').filter(Boolean);
29
+ for (let i = parts.length - 1; i >= 0; i--) {
30
+ const p = parts[i].toLowerCase();
31
+ if (ENV_TOKENS.has(p)) {
32
+ return p;
33
+ }
34
+ }
35
+ return 'miso';
36
+ }
37
+
38
+ module.exports = {
39
+ deriveEnvKeyFromClientId,
40
+ ENV_TOKENS
41
+ };