@aifabrix/builder 2.49.2 → 2.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (409) hide show
  1. package/.cursor/rules/deploy-rules/docker-image-ip-policy.mdc +49 -0
  2. package/.cursor/rules/plan-rules/application-lifecycle.mdc +30 -0
  3. package/.cursor/rules/plan-rules/plan-frontmatter.mdc +35 -0
  4. package/.cursor/rules/plan-rules/plan-lifecycle.mdc +31 -0
  5. package/.cursor/rules/plan-rules/plan-validation-gate.mdc +34 -0
  6. package/.cursor/skills/README.md +1 -0
  7. package/.dockerignore +52 -0
  8. package/.eslintignore +22 -0
  9. package/README.md +2 -0
  10. package/bin/builder-api-cleanup.js +26 -0
  11. package/bin/builder-api-nest.js +10 -0
  12. package/bin/builder-api-spike.js +19 -0
  13. package/enterprise-knowledge/README.md +50 -0
  14. package/enterprise-knowledge/enterprise-integration-lifecycle/README.md +22 -0
  15. package/enterprise-knowledge/enterprise-integration-lifecycle/application.json +15 -0
  16. package/enterprise-knowledge/enterprise-integration-lifecycle/deploy.js +69 -0
  17. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-deploy.json +52 -0
  18. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-system.json +29 -0
  19. package/enterprise-knowledge/enterprise-integration-lifecycle/env.template +2 -0
  20. package/integration/README.md +81 -0
  21. package/integration/github/README.md +53 -0
  22. package/integration/github/application.json +21 -0
  23. package/integration/github/deploy.js +72 -0
  24. package/integration/github/env.template +11 -0
  25. package/integration/github/github-datasource-issue-comments.json +239 -0
  26. package/integration/github/github-datasource-issues.json +399 -0
  27. package/integration/github/github-datasource-repository.json +354 -0
  28. package/integration/github/github-deploy.json +1202 -0
  29. package/integration/github/github-system.json +82 -0
  30. package/integration/hubspot-test/README.md +1 -1
  31. package/jest.isolated-projects.js +31 -1
  32. package/jest.projects.js +87 -1
  33. package/lib/api/dev-server-https.js +1 -1
  34. package/lib/api/enterprise-knowledge.api.js +63 -0
  35. package/lib/api/evidence.api.js +172 -0
  36. package/lib/api/external-systems.api.js +8 -2
  37. package/lib/api/resource-types.api.js +1 -0
  38. package/lib/api/types/enterprise-knowledge.types.js +46 -0
  39. package/lib/api/types/evidence.types.js +67 -0
  40. package/lib/api/types/resource-types.types.js +2 -0
  41. package/lib/app/controller-application-filter.js +36 -0
  42. package/lib/app/deploy.js +1 -1
  43. package/lib/app/list-external-systems.js +130 -0
  44. package/lib/app/list.js +20 -8
  45. package/lib/app/run.js +3 -1
  46. package/lib/app/show-display.js +8 -3
  47. package/lib/app/show-online.js +178 -0
  48. package/lib/app/show.js +37 -88
  49. package/lib/build/builder-api-docker-staging.js +47 -0
  50. package/lib/build/miso-controller-npm-sdk-guard.js +2 -2
  51. package/lib/build/standard-docker-build.js +2 -0
  52. package/lib/certification/post-unified-cert-sync.js +4 -31
  53. package/lib/certification/sync-after-external-command.js +0 -1
  54. package/lib/certification/sync-system-certification.js +0 -3
  55. package/lib/channels/add-channel.js +40 -34
  56. package/lib/channels/approval-guides/chatgpt.js +33 -0
  57. package/lib/channels/approval-guides/credential-portal.js +38 -0
  58. package/lib/channels/approval-guides/index.js +110 -0
  59. package/lib/channels/approval-guides/microsoft-copilot.js +34 -0
  60. package/lib/channels/approval-guides/slack.js +34 -0
  61. package/lib/channels/approval-guides/teams-bot.js +35 -0
  62. package/lib/channels/approval-guides/web-embed.js +32 -0
  63. package/lib/channels/channel-approval-guide.js +11 -0
  64. package/lib/channels/channel-artifact-generator.js +16 -4
  65. package/lib/channels/channel-audit.js +3 -0
  66. package/lib/channels/channel-auth-context.js +1 -1
  67. package/lib/channels/channel-description.js +59 -0
  68. package/lib/channels/channel-integration-generator.js +13 -230
  69. package/lib/channels/channel-integration-template.js +94 -0
  70. package/lib/channels/channel-runtime-resolver.js +43 -3
  71. package/lib/channels/channel-status-display.js +66 -26
  72. package/lib/channels/channel-targets.js +3 -3
  73. package/lib/cli/index.js +27 -3
  74. package/lib/cli/infra-guided.js +5 -1
  75. package/lib/cli/setup-app-external-create.js +111 -0
  76. package/lib/cli/setup-app.help.js +1 -1
  77. package/lib/cli/setup-app.js +38 -125
  78. package/lib/cli/setup-app.test-commands.js +26 -52
  79. package/lib/cli/setup-certification-commands.js +4 -4
  80. package/lib/cli/setup-certification.help.js +9 -9
  81. package/lib/cli/setup-dev.js +7 -2
  82. package/lib/cli/setup-external-system-help.js +4 -6
  83. package/lib/cli/setup-external-system.js +58 -52
  84. package/lib/cli/setup-infra-up-builder-api-action.js +64 -0
  85. package/lib/cli/setup-infra-up-platform-action.js +3 -1
  86. package/lib/cli/setup-infra.js +15 -0
  87. package/lib/cli/setup-list.js +43 -0
  88. package/lib/cli/setup-utility-repair.js +26 -7
  89. package/lib/cli/setup-utility.js +5 -3
  90. package/lib/commands/app.js +15 -43
  91. package/lib/commands/channel-add-setup.js +110 -0
  92. package/lib/commands/channel.js +42 -8
  93. package/lib/commands/datasource-sync-display.js +96 -0
  94. package/lib/commands/datasource-sync-policy.js +210 -0
  95. package/lib/commands/datasource-test-trust-cli.js +6 -6
  96. package/lib/commands/datasource-unified-test-cli.js +2 -1
  97. package/lib/commands/datasource-unified-test-cli.options.js +33 -23
  98. package/lib/commands/deploy-gate-failure-details.js +163 -0
  99. package/lib/commands/deploy-gate-orchestrator.js +322 -0
  100. package/lib/commands/dev-cli-handlers.js +1 -59
  101. package/lib/commands/dev-host-ops-params.js +91 -0
  102. package/lib/commands/dev-host-ops-poll.js +111 -0
  103. package/lib/commands/dev-host-ops.js +107 -94
  104. package/lib/commands/dev-init.js +3 -1
  105. package/lib/commands/enterprise-knowledge.js +284 -0
  106. package/lib/commands/evidence-cli-leaves.js +250 -0
  107. package/lib/commands/evidence.js +51 -0
  108. package/lib/commands/governance-cli-shared.js +2 -2
  109. package/lib/commands/governance-command-action.js +2 -2
  110. package/lib/commands/governance-fixture-subjects.js +85 -0
  111. package/lib/commands/governance.js +1 -1
  112. package/lib/commands/lifecycle-command-action.js +2 -2
  113. package/lib/commands/lifecycle-external.js +3 -3
  114. package/lib/commands/manifest-cli-auth.js +29 -0
  115. package/lib/commands/manifest-cli-commands.js +170 -0
  116. package/lib/commands/manifest-cli-integration-path.js +63 -0
  117. package/lib/commands/manifest.js +21 -0
  118. package/lib/commands/protection-cli-leaves.js +3 -3
  119. package/lib/commands/repair-auth-apply.js +15 -1
  120. package/lib/commands/repair-authentications-454.js +169 -0
  121. package/lib/commands/repair-capability-openapi-warnings.js +126 -0
  122. package/lib/commands/repair-datasource-apply.js +135 -0
  123. package/lib/commands/repair-datasource-auto-rbac.js +62 -1
  124. package/lib/commands/repair-datasource-http-service-contract.js +239 -0
  125. package/lib/commands/repair-datasource-operation-security.js +180 -0
  126. package/lib/commands/repair-datasource-run.js +7 -2
  127. package/lib/commands/repair-datasource-sync-operations.js +177 -0
  128. package/lib/commands/repair-datasource-webhooks-sync-bridge.js +133 -0
  129. package/lib/commands/repair-datasource.js +12 -68
  130. package/lib/commands/repair-env-template.js +11 -1
  131. package/lib/commands/repair-external-run.js +121 -31
  132. package/lib/commands/repair-internal.js +1 -1
  133. package/lib/commands/repair-openapi-export.js +156 -0
  134. package/lib/commands/repair-openapi-sync.js +19 -2
  135. package/lib/commands/repair-orchestration-datasource-split.js +259 -0
  136. package/lib/commands/repair-persist.js +22 -1
  137. package/lib/commands/repair-rbac-platform-preset.js +204 -0
  138. package/lib/commands/repair-rbac-reader-roles.js +191 -0
  139. package/lib/commands/repair-rbac.js +163 -86
  140. package/lib/commands/repair-steps.js +83 -18
  141. package/lib/commands/repair-system-permissions.js +1 -0
  142. package/lib/commands/repair.js +1 -1
  143. package/lib/commands/resource-type.js +65 -26
  144. package/lib/commands/run-post-publish-data-sync.js +68 -0
  145. package/lib/commands/setup-modes.js +1 -1
  146. package/lib/commands/test-e2e-external.js +21 -8
  147. package/lib/commands/test-governance-cli-options.js +2 -2
  148. package/lib/commands/test-trust-cli-options.js +2 -2
  149. package/lib/commands/up-builder-api-bootstrap.js +71 -0
  150. package/lib/commands/up-builder-api-provision.js +241 -0
  151. package/lib/commands/up-builder-api.js +88 -0
  152. package/lib/commands/up-common.js +25 -1
  153. package/lib/commands/upload-credential-push-log.js +117 -0
  154. package/lib/commands/upload-data-sync-finalize.js +60 -0
  155. package/lib/commands/upload-probe.js +66 -0
  156. package/lib/commands/upload-publish-context.js +4 -1
  157. package/lib/commands/upload-sidecar-followups.js +55 -27
  158. package/lib/commands/upload.js +116 -157
  159. package/lib/commands/verify-governance-combined-external.js +1 -1
  160. package/lib/commands/verify-governance-db.js +2 -2
  161. package/lib/commands/verify-operations-command-action.js +2 -2
  162. package/lib/commands/verify-operations-step-plan.js +2 -2
  163. package/lib/commands/verify-operations-steps.js +2 -2
  164. package/lib/commands/verify-trust-command-action.js +1 -1
  165. package/lib/commands/wizard-core.js +1 -1
  166. package/lib/commands/wizard-headless.js +2 -1
  167. package/lib/core/admin-secrets.js +2 -6
  168. package/lib/core/secrets-env-content.js +10 -4
  169. package/lib/core/secrets-env-write.js +2 -13
  170. package/lib/datasource/agent-trust-run.js +3 -3
  171. package/lib/datasource/deploy.js +3 -1
  172. package/lib/datasource/test-e2e.js +6 -1
  173. package/lib/datasource/unified-validation-run-body.js +4 -1
  174. package/lib/datasource/unified-validation-run.js +1 -1
  175. package/lib/deployment/deploy-poll-ui.js +73 -12
  176. package/lib/deployment/deployer-poll-run.js +113 -0
  177. package/lib/deployment/deployer.js +17 -87
  178. package/lib/evidence/dataplane-context.js +21 -0
  179. package/lib/evidence/evidence-display.js +78 -0
  180. package/lib/evidence/evidence-service.js +392 -0
  181. package/lib/external-system/deploy.js +290 -112
  182. package/lib/external-system/download.js +7 -3
  183. package/lib/external-system/test-execution.js +1 -1
  184. package/lib/external-system/test-system-level.js +8 -10
  185. package/lib/external-system/test.js +12 -6
  186. package/lib/generator/deploy-script.js +73 -0
  187. package/lib/generator/external.js +2 -1
  188. package/lib/generator/index.js +17 -2
  189. package/lib/generator/wizard.js +3 -36
  190. package/lib/internal/fs-real-sync.js +22 -1
  191. package/lib/internal/node-fs.js +2 -0
  192. package/lib/lifecycle/lifecycle-governance-options.js +1 -1
  193. package/lib/lifecycle/verify-step-progress.js +1 -1
  194. package/lib/programmatic/access-log.js +26 -0
  195. package/lib/programmatic/auth-config.js +44 -0
  196. package/lib/programmatic/bearer-auth.js +176 -0
  197. package/lib/programmatic/builder-api-request.js +175 -0
  198. package/lib/programmatic/builder-api-route-dispatch.js +82 -0
  199. package/lib/programmatic/builder-api-runtime-config.js +42 -0
  200. package/lib/programmatic/builder-api-server.js +230 -0
  201. package/lib/programmatic/builder-help-authentication-catalog.js +282 -0
  202. package/lib/programmatic/builder-help-connected-system-ui.js +266 -0
  203. package/lib/programmatic/builder-help-enterprise-sync-fabrix.js +60 -0
  204. package/lib/programmatic/builder-help-envelope.js +36 -0
  205. package/lib/programmatic/builder-help-fixtures.js +200 -0
  206. package/lib/programmatic/builder-help-governance.js +172 -0
  207. package/lib/programmatic/builder-help-schema-catalog.js +92 -0
  208. package/lib/programmatic/builder-help.js +361 -0
  209. package/lib/programmatic/capability-registry.js +77 -0
  210. package/lib/programmatic/command-options.js +32 -0
  211. package/lib/programmatic/enterprise-mcp-client.js +98 -0
  212. package/lib/programmatic/http-problem-details.js +99 -0
  213. package/lib/programmatic/http-route-match.js +40 -0
  214. package/lib/programmatic/idempotency-cache.js +69 -0
  215. package/lib/programmatic/index.js +53 -0
  216. package/lib/programmatic/integration-path-scope.js +39 -0
  217. package/lib/programmatic/log-redaction.js +66 -0
  218. package/lib/programmatic/manifest-get-section.js +146 -0
  219. package/lib/programmatic/manifest-patch-section.js +252 -0
  220. package/lib/programmatic/manifest-repair.js +122 -0
  221. package/lib/programmatic/manifest-section-dependency-graph.js +160 -0
  222. package/lib/programmatic/manifest-section-io.js +225 -0
  223. package/lib/programmatic/manifest-section-quality.js +171 -0
  224. package/lib/programmatic/manifest-section-registry-data.js +269 -0
  225. package/lib/programmatic/manifest-section-registry.js +205 -0
  226. package/lib/programmatic/nest-http-bridge.js +34 -0
  227. package/lib/programmatic/openapi-component-schemas.js +68 -0
  228. package/lib/programmatic/openapi-description-enricher.js +117 -0
  229. package/lib/programmatic/openapi-descriptions.js +190 -0
  230. package/lib/programmatic/openapi-docs-serving.js +123 -0
  231. package/lib/programmatic/openapi-help-schemas.js +63 -0
  232. package/lib/programmatic/openapi-manifest-schemas.js +141 -0
  233. package/lib/programmatic/openapi-operation-bindings.js +274 -0
  234. package/lib/programmatic/openapi-request-schemas.js +155 -0
  235. package/lib/programmatic/openapi-result-schemas.js +476 -0
  236. package/lib/programmatic/openapi-schema-descriptions-certify.js +139 -0
  237. package/lib/programmatic/openapi-schema-descriptions-core.js +159 -0
  238. package/lib/programmatic/openapi-schema-descriptions-help.js +40 -0
  239. package/lib/programmatic/openapi-schema-descriptions-manifest.js +143 -0
  240. package/lib/programmatic/openapi-schema-descriptions-mcp.js +118 -0
  241. package/lib/programmatic/openapi-schema-descriptions-operations.js +281 -0
  242. package/lib/programmatic/openapi-schema-helpers.js +93 -0
  243. package/lib/programmatic/openapi-spec.js +203 -0
  244. package/lib/programmatic/orchestration-openapi-meta.js +159 -0
  245. package/lib/programmatic/platform-rbac-catalog.js +90 -0
  246. package/lib/programmatic/request-timeout.js +53 -0
  247. package/lib/programmatic/route-handler-map.js +143 -0
  248. package/lib/programmatic/route-handlers-context.js +29 -0
  249. package/lib/programmatic/route-handlers.js +33 -0
  250. package/lib/programmatic/run-certify.js +57 -0
  251. package/lib/programmatic/run-enterprise-mcp.js +32 -0
  252. package/lib/programmatic/run-lifecycle.js +29 -0
  253. package/lib/programmatic/run-repair.js +41 -0
  254. package/lib/programmatic/run-repository-emcp.js +54 -0
  255. package/lib/programmatic/run-template-workspace.js +61 -0
  256. package/lib/programmatic/run-test.js +49 -0
  257. package/lib/programmatic/run-upload.js +63 -0
  258. package/lib/programmatic/run-validate.js +53 -0
  259. package/lib/programmatic/run-wizard.js +40 -0
  260. package/lib/programmatic/system-key.js +48 -0
  261. package/lib/programmatic/wizard-config-normalize.js +118 -0
  262. package/lib/programmatic/workspace-cleanup.js +128 -0
  263. package/lib/programmatic/workspace-context.js +145 -0
  264. package/lib/programmatic/workspace-lock.js +75 -0
  265. package/lib/programmatic/workspace-meta.js +64 -0
  266. package/lib/programmatic/workspace-ops.js +149 -0
  267. package/lib/protection/run-commands-upload-sync.js +35 -0
  268. package/lib/protection/run-commands.js +2 -20
  269. package/lib/protection/upload-batch.js +11 -7
  270. package/lib/resolvers/resource-type-file.js +22 -0
  271. package/lib/schema/external-datasource.schema.json +161 -1
  272. package/lib/schema/external-system.schema.json +244 -118
  273. package/lib/schema/flag-map-validation-run.json +3 -0
  274. package/lib/schema/type/credential-field-registry.json +2 -2
  275. package/lib/schema/type/document-storage.json +9 -0
  276. package/lib/utils/agent-trust-run-display.js +1 -1
  277. package/lib/utils/app-path-resolve.js +168 -0
  278. package/lib/utils/authentication-env-template.js +222 -0
  279. package/lib/utils/cli-sync-options.js +7 -11
  280. package/lib/utils/cli-utils.js +4 -0
  281. package/lib/utils/cli-workspace-options.js +29 -0
  282. package/lib/utils/compose-generate-docker-compose.js +102 -0
  283. package/lib/utils/configuration-env-resolver.js +203 -27
  284. package/lib/utils/datasource-test-run-certificate-tty.js +28 -2
  285. package/lib/utils/datasource-test-run-certification-debug.js +130 -0
  286. package/lib/utils/datasource-test-run-debug-display.js +2 -0
  287. package/lib/utils/datasource-test-run-debug-slice.js +7 -0
  288. package/lib/utils/datasource-test-run-display.js +2 -1
  289. package/lib/utils/dev-init-ssh-merge.js +165 -23
  290. package/lib/utils/dev-pin-share-instructions.js +110 -0
  291. package/lib/utils/dev-ssh-config-helper.js +177 -33
  292. package/lib/utils/enterprise-knowledge-paths.js +142 -0
  293. package/lib/utils/env-copy.js +2 -1
  294. package/lib/utils/env-dotenv-format.js +103 -0
  295. package/lib/utils/external-env-template.js +4 -1
  296. package/lib/utils/external-system-display.js +5 -1
  297. package/lib/utils/external-system-readiness-compact-blocks.js +221 -0
  298. package/lib/utils/external-system-readiness-compact-display.js +324 -0
  299. package/lib/utils/external-system-readiness-core.js +16 -0
  300. package/lib/utils/external-system-readiness-deploy-display.js +29 -11
  301. package/lib/utils/external-system-readiness-display-internals.js +3 -1
  302. package/lib/utils/external-system-readiness-display.js +20 -30
  303. package/lib/utils/external-system-system-test-tty-certification.js +135 -0
  304. package/lib/utils/external-system-system-test-tty.js +5 -41
  305. package/lib/utils/help-builder.js +6 -1
  306. package/lib/utils/host-ops-job-labels.js +236 -0
  307. package/lib/utils/host-ops-job-result.js +61 -0
  308. package/lib/utils/host-ops-poll-ui.js +163 -0
  309. package/lib/utils/integration-path-resolve.js +112 -0
  310. package/lib/utils/paths-reload-source.js +148 -0
  311. package/lib/utils/paths-system-builder-keys.js +25 -0
  312. package/lib/utils/paths.js +151 -26
  313. package/lib/utils/runtime-configuration-values.js +64 -2
  314. package/lib/utils/secrets-helpers.js +5 -1
  315. package/lib/utils/ssh-known-hosts.js +130 -0
  316. package/lib/utils/test-target-cli-options.js +75 -0
  317. package/lib/utils/upload-sync-options.js +4 -0
  318. package/lib/utils/validation-run-request.js +11 -2
  319. package/lib/validation/external-manifest-validator.js +11 -1
  320. package/lib/validation/openapi-contract-surface-validator.js +426 -0
  321. package/lib/validation/openapi-contract-vendor-validation.js +238 -0
  322. package/lib/validation/validate-external-file.js +160 -0
  323. package/lib/validation/validate.js +6 -117
  324. package/package.json +46 -29
  325. package/packages/builder-api/README.md +120 -0
  326. package/packages/builder-api/package.json +30 -0
  327. package/packages/builder-api/src/app.module.ts +7 -0
  328. package/packages/builder-api/src/auth/auth.module.ts +5 -0
  329. package/packages/builder-api/src/external-system/external-system.module.ts +5 -0
  330. package/packages/builder-api/src/main.ts +16 -0
  331. package/packages/builder-api/tsconfig.json +15 -0
  332. package/scripts/check-builder-api-architecture-grep.js +79 -0
  333. package/scripts/docker_image_content_gate.js +47 -0
  334. package/scripts/docker_image_content_gate.sh +5 -0
  335. package/scripts/export-builder-api-evidence.js +262 -0
  336. package/scripts/lib/builder-api-docker-staging-copy.js +60 -0
  337. package/scripts/lib/builder-api-docker-staging-core.js +183 -0
  338. package/scripts/lib/docker-image-content-gate-core.js +166 -0
  339. package/scripts/lib/plan-actor.js +109 -0
  340. package/scripts/lib/plan-config.js +20 -0
  341. package/scripts/lib/plan-gates.js +154 -0
  342. package/scripts/lib/plan-meta.js +104 -0
  343. package/scripts/lib/plan-parse.js +162 -0
  344. package/scripts/lib/plan-prevalidate-gates.js +326 -0
  345. package/scripts/lib/plan-run-core.js +125 -0
  346. package/scripts/lib/plan-run-report.js +108 -0
  347. package/scripts/plan-approve.js +24 -0
  348. package/scripts/plan-archive.js +49 -0
  349. package/scripts/plan-run.js +13 -0
  350. package/scripts/plan-set-actor.js +21 -0
  351. package/scripts/plan-validate.js +80 -0
  352. package/scripts/pnpm/af.mjs +110 -0
  353. package/scripts/pnpm/check-quiet.mjs +32 -0
  354. package/scripts/pnpm/dev-install.mjs +29 -0
  355. package/scripts/pnpm/dev-reload.mjs +18 -0
  356. package/scripts/pnpm/help.mjs +55 -0
  357. package/scripts/pnpm/lib/dev-reload-core.mjs +189 -0
  358. package/scripts/pnpm/lib/dev-reload-log-capture.mjs +67 -0
  359. package/scripts/pnpm/lib/dev-reload-log-utils.mjs +32 -0
  360. package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +124 -0
  361. package/scripts/pnpm/lib/resolve-app-url.mjs +183 -0
  362. package/scripts/pnpm/lib/spinner.mjs +42 -0
  363. package/scripts/stage_builder_api_for_docker.js +65 -0
  364. package/scripts/sync-builder-api-template.js +44 -0
  365. package/templates/README.md +3 -0
  366. package/templates/applications/builder-api/Dockerfile +38 -0
  367. package/templates/applications/builder-api/application.yaml +75 -0
  368. package/templates/applications/builder-api/env.template +48 -0
  369. package/templates/applications/dataplane/application.yaml +1 -1
  370. package/templates/applications/dataplane/env.template +10 -6
  371. package/templates/applications/dataplane/rbac.yaml +21 -1
  372. package/templates/applications/miso-controller/application.yaml +1 -1
  373. package/templates/applications/miso-controller/env.template +1 -3
  374. package/templates/channels/README.md +18 -0
  375. package/templates/channels/ai-fabrix-icon.jpg +0 -0
  376. package/templates/channels/chatgpt/install.template.md.hbs +21 -24
  377. package/templates/channels/chatgpt/integration/README.md +11 -0
  378. package/templates/channels/chatgpt/integration/application.json +15 -0
  379. package/templates/channels/chatgpt/integration/chatgpt-system.json +29 -0
  380. package/templates/channels/chatgpt/integration/env.template +4 -0
  381. package/templates/channels/microsoft-copilot/install.template.md.hbs +20 -25
  382. package/templates/channels/microsoft-copilot/integration/README.md +11 -0
  383. package/templates/channels/microsoft-copilot/integration/application.json +15 -0
  384. package/templates/channels/microsoft-copilot/integration/env.template +6 -0
  385. package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +34 -0
  386. package/templates/channels/slack/install.template.md.hbs +48 -18
  387. package/templates/channels/slack/integration/README.md +38 -0
  388. package/templates/channels/slack/integration/application.json +18 -0
  389. package/templates/channels/slack/integration/env.template +29 -0
  390. package/templates/channels/slack/integration/slack-datasource-conversations.json +226 -0
  391. package/templates/channels/slack/integration/slack-datasource-messages.json +269 -0
  392. package/templates/channels/slack/integration/slack-system.json +86 -0
  393. package/templates/channels/slack/manifest.template.json.hbs +20 -10
  394. package/templates/channels/teams-bot/install.template.md.hbs +31 -17
  395. package/templates/channels/teams-bot/integration/README.md +18 -0
  396. package/templates/channels/teams-bot/integration/application.json +17 -0
  397. package/templates/channels/teams-bot/integration/env.template +5 -0
  398. package/templates/channels/teams-bot/integration/teams-bot-system.json +55 -0
  399. package/templates/channels/teams-bot/manifest.template.json.hbs +27 -0
  400. package/templates/channels/web-embed/install.template.md.hbs +16 -26
  401. package/templates/channels/web-embed/integration/README.md +11 -0
  402. package/templates/channels/web-embed/integration/application.json +15 -0
  403. package/templates/channels/web-embed/integration/env.template +4 -0
  404. package/templates/channels/web-embed/integration/web-embed-system.json +29 -0
  405. package/templates/openapi/redoc_page.html +86 -0
  406. package/templates/python/docker-compose.hbs +11 -0
  407. package/templates/python/requirements.txt +1 -1
  408. package/templates/typescript/docker-compose.hbs +11 -0
  409. package/lib/certification/cli-cert-sync-skip.js +0 -21
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Datasource repair helpers for webhook and syncBridge manifest sections.
3
+ *
4
+ * @fileoverview Align webhook defaults and syncBridge metadata warnings (454.11)
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const AUTH_USAGE_WEBHOOK_INBOUND = 'webhookInbound';
10
+
11
+ /**
12
+ * @param {object|null|undefined} systemParsed
13
+ * @returns {boolean}
14
+ */
15
+ function systemHasWebhookInboundAuth(systemParsed) {
16
+ if (!systemParsed || typeof systemParsed !== 'object') {
17
+ return false;
18
+ }
19
+ const rows = systemParsed.authentications;
20
+ if (Array.isArray(rows)) {
21
+ return rows.some((row) => row && row.usage === AUTH_USAGE_WEBHOOK_INBOUND);
22
+ }
23
+ return false;
24
+ }
25
+
26
+ /**
27
+ * @param {object} parsed
28
+ * @param {string[]} changes
29
+ * @param {string[]} warnings
30
+ * @returns {boolean}
31
+ */
32
+ function repairWebhookSection(parsed, changes, warnings) {
33
+ if (!parsed?.webhook || typeof parsed.webhook !== 'object') {
34
+ return false;
35
+ }
36
+ const webhook = parsed.webhook;
37
+ let updated = false;
38
+
39
+ if (webhook.enabled === true) {
40
+ if (!webhook.idPath || !String(webhook.idPath).trim()) {
41
+ warnings.push(
42
+ 'webhook.enabled is true but idPath is missing — set idPath (for example $.objectId) before upload.'
43
+ );
44
+ }
45
+ if (!Array.isArray(webhook.events) || webhook.events.length === 0) {
46
+ warnings.push('webhook.enabled is true but events[] is empty — add vendor event names.');
47
+ }
48
+ }
49
+
50
+ if (webhook.enabled === true && !webhook.endpointMode) {
51
+ webhook.endpointMode = 'datasource';
52
+ changes.push('Set webhook.endpointMode default datasource');
53
+ updated = true;
54
+ }
55
+
56
+ return updated;
57
+ }
58
+
59
+ /**
60
+ * @param {object} parsed
61
+ * @param {string[]} changes
62
+ * @param {string[]} warnings
63
+ * @returns {boolean}
64
+ */
65
+ function ensureSyncBridgeExternalIdMetadata(parsed, changes) {
66
+ const mode = parsed?.syncBridge || 'disabled';
67
+ if (mode === 'disabled') {
68
+ return false;
69
+ }
70
+ if (!parsed.metadataSchema || typeof parsed.metadataSchema !== 'object') {
71
+ parsed.metadataSchema = { type: 'object', additionalProperties: true, properties: {} };
72
+ }
73
+ if (!parsed.metadataSchema.properties || typeof parsed.metadataSchema.properties !== 'object') {
74
+ parsed.metadataSchema.properties = {};
75
+ }
76
+ const ext = parsed.metadataSchema.properties.externalId;
77
+ const ok =
78
+ ext && typeof ext === 'object' && ext.type === 'string' && ext.index === true;
79
+ if (ok) {
80
+ return false;
81
+ }
82
+ parsed.metadataSchema.properties.externalId = {
83
+ ...(typeof ext === 'object' && ext !== null ? ext : {}),
84
+ type: 'string',
85
+ index: true
86
+ };
87
+ changes.push('Ensured metadataSchema.properties.externalId for syncBridge participation');
88
+ return true;
89
+ }
90
+
91
+ /**
92
+ * @param {object} parsed
93
+ * @param {string[]} changes
94
+ * @param {string[]} warnings
95
+ * @returns {boolean}
96
+ */
97
+ function repairSyncBridgeSection(parsed, changes, warnings) {
98
+ const mode = parsed?.syncBridge || 'disabled';
99
+ if (mode === 'disabled') {
100
+ return false;
101
+ }
102
+ if (mode === 'master' && !parsed.resourceType) {
103
+ warnings.push('syncBridge=master requires resourceType for propagation grouping.');
104
+ }
105
+ return ensureSyncBridgeExternalIdMetadata(parsed, changes);
106
+ }
107
+
108
+ /**
109
+ * @param {object} parsed
110
+ * @param {object|null|undefined} systemParsed
111
+ * @param {string[]} warnings
112
+ * @returns {void}
113
+ */
114
+ function collectWebhookSyncBridgeSystemWarnings(parsed, systemParsed, warnings) {
115
+ if (!parsed?.webhook?.enabled) {
116
+ return;
117
+ }
118
+ if (systemHasWebhookInboundAuth(systemParsed)) {
119
+ return;
120
+ }
121
+ const dsKey = parsed.key || parsed.datasourceKey || 'datasource';
122
+ warnings.push(
123
+ `${dsKey}: webhook.enabled but system lacks authentications[usage=webhookInbound]. ` +
124
+ 'Run: aifabrix repair <systemKey> --auth-webhook'
125
+ );
126
+ }
127
+
128
+ module.exports = {
129
+ repairWebhookSection,
130
+ repairSyncBridgeSection,
131
+ collectWebhookSyncBridgeSystemWarnings,
132
+ systemHasWebhookInboundAuth
133
+ };
@@ -10,9 +10,7 @@
10
10
  'use strict';
11
11
 
12
12
  const { repairOpenapiSection } = require('./repair-datasource-openapi');
13
- const { normalizeAutoRbacOperationKeys } = require('./repair-datasource-auto-rbac');
14
13
  const { repairTestPayload } = require('./repair-datasource-test-payload');
15
- const { repairComV2Manifest } = require('./repair-datasource-com-v2');
16
14
  const {
17
15
  isDeprecatedNoneLlmManifest,
18
16
  repairNoneLlmToServiceContract,
@@ -386,80 +384,26 @@ function sanitizeTestPayloadTopLevel(parsed, changes) {
386
384
  return true;
387
385
  }
388
386
 
389
- /**
390
- * @param {Object} parsed
391
- * @param {Object} options
392
- * @returns {boolean}
393
- */
394
- function shouldApplyServiceContractRepair(parsed, options) {
395
- return (
396
- isDeprecatedNoneLlmManifest(parsed) ||
397
- (options.serviceContract && parsed?.resourceType === 'llm')
398
- );
399
- }
400
-
401
- /**
402
- * @param {Object} parsed
403
- * @param {Object} options
404
- * @param {boolean} none
405
- * @param {string[]} changes
406
- * @returns {boolean}
407
- */
408
- function applyOptionalDatasourceRepairs(parsed, options, none, changes) {
409
- let updated = false;
410
- if (options.expose) {
411
- updated = repairExposeFromAttributes(parsed, changes) || updated;
412
- }
413
- if (!none && options.sync) {
414
- updated = repairSyncSection(parsed, changes) || updated;
415
- }
416
- if (options.test) {
417
- sanitizeTestPayloadTopLevel(parsed, changes);
418
- updated = repairTestPayload(parsed, changes) || updated;
419
- updated = sanitizeTestPayloadTopLevel(parsed, changes) || updated;
420
- }
421
- return updated;
422
- }
423
-
424
387
  /**
425
388
  * Runs all requested datasource repairs.
426
389
  *
427
390
  * @param {Object} parsed - Parsed datasource object (mutated)
428
- * @param {Object} options - { expose?: boolean, sync?: boolean, test?: boolean }
391
+ * @param {Object} options - { expose?: boolean, sync?: boolean, test?: boolean, operations?: boolean }
429
392
  * @param {string[]} [changes] - Optional array to append change descriptions to
430
393
  * @returns {{ updated: boolean, changes: string[] }}
431
394
  */
432
395
  function repairDatasourceFile(parsed, options = {}, changes = []) {
433
- const out = Array.isArray(changes) ? changes : [];
434
- let updated = stripDeprecatedServiceCategory(parsed, out);
435
-
436
- if (shouldApplyServiceContractRepair(parsed, options)) {
437
- updated = repairNoneLlmToServiceContract(parsed, out) || updated;
438
- }
439
-
440
- const none = isNoneEntityType(parsed?.entityType);
441
-
442
- updated = applyBaseDatasourceRepairs(parsed, none, out) || updated;
443
- updated = applyOpenapiDatasourceRepairs(parsed, out) || updated;
444
- updated = applyOptionalDatasourceRepairs(parsed, options, none, out) || updated;
445
-
446
- return { updated, changes: out };
447
- }
448
-
449
- function applyBaseDatasourceRepairs(parsed, none, changes) {
450
- let updated = repairComV2Manifest(parsed, changes);
451
- if (none) return updated;
452
- updated = repairDimensionBindingShape(parsed, changes) || updated;
453
- updated = repairRootDimensionsFromAttributes(parsed, changes) || updated;
454
- updated = repairMetadataSchemaFromAttributes(parsed, changes) || updated;
455
- return updated;
456
- }
457
-
458
- function applyOpenapiDatasourceRepairs(parsed, changes) {
459
- let updated = false;
460
- updated = repairOpenapiSection(parsed, changes) || updated;
461
- updated = normalizeAutoRbacOperationKeys(parsed, changes) || updated;
462
- return updated;
396
+ const { runRepairDatasourceFile } = require('./repair-datasource-apply');
397
+ return runRepairDatasourceFile(parsed, options, changes, {
398
+ stripDeprecatedServiceCategory,
399
+ isNoneEntityType,
400
+ repairDimensionBindingShape,
401
+ repairRootDimensionsFromAttributes,
402
+ repairMetadataSchemaFromAttributes,
403
+ repairExposeFromAttributes,
404
+ repairSyncSection,
405
+ sanitizeTestPayloadTopLevel
406
+ });
463
407
  }
464
408
 
465
409
  module.exports = {
@@ -15,6 +15,10 @@ const { systemKeyToKvPrefix, kvEnvKeyToPath, securityKeyToVar } = require('../ut
15
15
  const { extractEnvTemplate } = require('../generator/split');
16
16
  const { generateExternalEnvTemplateContent } = require('../utils/external-env-template');
17
17
  const { commentOrphanKvEnvLines } = require('../utils/env-kv-orphan-lines');
18
+ const {
19
+ addFromAuthenticationsArray,
20
+ normalizeAuthenticationsSecurity
21
+ } = require('../utils/authentication-env-template');
18
22
 
19
23
  /**
20
24
  * Normalizes a keyvault config entry to canonical KV_* name and path-style value.
@@ -114,7 +118,12 @@ function buildEffectiveConfiguration(systemParsed, systemKey) {
114
118
  const seenNames = new Set();
115
119
  const config = Array.isArray(systemParsed.configuration) ? systemParsed.configuration : [];
116
120
  addFromConfiguration(effective, config, prefix, seenNames, systemKey);
117
- addFromAuthSecurity(effective, systemParsed, prefix, seenNames, systemKey);
121
+ addFromAuthenticationsArray(effective, systemParsed, prefix, seenNames, systemKey);
122
+ const hasAuthSlots =
123
+ Array.isArray(systemParsed.authentications) && systemParsed.authentications.length > 0;
124
+ if (!hasAuthSlots) {
125
+ addFromAuthSecurity(effective, systemParsed, prefix, seenNames, systemKey);
126
+ }
118
127
  return effective;
119
128
  }
120
129
 
@@ -394,6 +403,7 @@ function normalizeSystemFileAuthAndConfig(systemParsed, systemKey, changes) {
394
403
  const credential = getAuthCredentialTemplate(systemParsed.authentication);
395
404
  const security = credential?.security ?? systemParsed.authentication?.security;
396
405
  let updated = (security && typeof security === 'object' && normalizeSecuritySection(security, prefix, systemKey, changes));
406
+ updated = normalizeAuthenticationsSecurity(systemParsed, systemKey, changes) || updated;
397
407
  const config = systemParsed.configuration;
398
408
  if (Array.isArray(config)) {
399
409
  updated = normalizeConfigurationSection(config, prefix, systemKey, changes) || updated;
@@ -9,12 +9,21 @@
9
9
  'use strict';
10
10
 
11
11
  const { normalizeDatasourceKeysAndFilenames } = require('./repair-datasource-keys');
12
- const { resolveSystemContext } = require('./repair-system-alignment');
13
- const { persistChangesAndRegenerate, regenerateReadmeIfRequested } = require('./repair-persist');
12
+ const {
13
+ resolveSystemContext,
14
+ alignSystemFileDataSources,
15
+ ensureExternalIntegrationBlock
16
+ } = require('./repair-system-alignment');
17
+ const { persistChangesAndRegenerate, regenerateReadmeIfRequested, regenerateDeployScript } = require('./repair-persist');
14
18
  const { runRepairSteps } = require('./repair-steps');
15
19
  const { runDatasourceRepairs } = require('./repair-datasource-run');
20
+ const { repairSplitOrchestrationDatasources } = require('./repair-orchestration-datasource-split');
16
21
  const { maybeRepairRbac } = require('./repair-rbac');
22
+ const { collectCapabilityOpenApiDriftWarnings } = require('./repair-capability-openapi-warnings');
17
23
  const { maybeRunOpenApiSyncForMcp } = require('./repair-openapi-sync');
24
+ const { writeConfigFile } = require('../utils/config-format');
25
+ const { backupIntegrationFile } = require('../utils/integration-file-backup');
26
+ const { trackRepairWrite } = require('./repair-changed-files');
18
27
 
19
28
  /**
20
29
  * @param {Object} steps
@@ -95,25 +104,48 @@ function prepareRepairWorkspace(params) {
95
104
 
96
105
  /**
97
106
  * @param {Object} ws
98
- * @returns {Promise<Object>}
107
+ * @returns {boolean}
99
108
  */
100
- async function runRepairIntegrationFileSteps(ws) {
101
- const steps = runRepairSteps({
102
- appPath: ws.appPath,
103
- configPath: ws.configPath,
104
- variables: ws.variables,
105
- systemFilePath: ws.systemFilePath,
106
- systemParsed: ws.systemParsed,
107
- systemKey: ws.systemKey,
108
- systemFiles: ws.systemFiles,
109
- datasourceFiles: ws.datasourceFiles,
110
- dryRun: ws.dryRun,
111
- changes: ws.changes,
112
- warnings: ws.warnings,
113
- auth: ws.authOption,
114
- format: ws.rbacFmt,
115
- backupCtx: ws.backupCtx
116
- });
109
+ function reconcileManifestsAfterDatasourceSplit(ws) {
110
+ const dataSourcesAligned = alignSystemFileDataSources(
111
+ ws.appPath,
112
+ ws.systemParsed,
113
+ ws.datasourceFiles,
114
+ ws.systemKey,
115
+ ws.dryRun,
116
+ ws.changes
117
+ );
118
+ const extAligned = ensureExternalIntegrationBlock(
119
+ ws.variables,
120
+ ws.systemFiles,
121
+ ws.datasourceFiles,
122
+ ws.changes
123
+ );
124
+ if ((dataSourcesAligned || extAligned) && !ws.dryRun) {
125
+ backupIntegrationFile(ws.systemFilePath, ws.backupCtx);
126
+ writeConfigFile(ws.systemFilePath, ws.systemParsed);
127
+ trackRepairWrite(ws.systemFilePath, ws.backupCtx);
128
+ }
129
+ return dataSourcesAligned || extAligned;
130
+ }
131
+
132
+ /**
133
+ * @param {Object} ws
134
+ * @returns {Promise<{ datasourceRepairUpdated: boolean, openapiActionsPerformed: boolean }>}
135
+ */
136
+ async function runDatasourceOpenApiRepairs(ws) {
137
+ const splitResult = repairSplitOrchestrationDatasources(
138
+ ws.appPath,
139
+ ws.systemKey,
140
+ ws.datasourceFiles,
141
+ ws.options,
142
+ ws.dryRun,
143
+ ws.changes
144
+ );
145
+ if (splitResult.updated) {
146
+ ws.datasourceFiles = splitResult.datasourceFiles;
147
+ reconcileManifestsAfterDatasourceSplit(ws);
148
+ }
117
149
  const datasourceRepairUpdated = runDatasourceRepairs(
118
150
  ws.appPath,
119
151
  ws.datasourceFiles,
@@ -121,10 +153,12 @@ async function runRepairIntegrationFileSteps(ws) {
121
153
  expose: Boolean(ws.options.expose),
122
154
  sync: Boolean(ws.options.sync),
123
155
  test: Boolean(ws.options.test),
156
+ operations: Boolean(ws.options.operations) || Boolean(ws.options.rbac),
124
157
  backupCtx: ws.backupCtx
125
158
  },
126
159
  ws.dryRun,
127
- ws.changes
160
+ ws.changes,
161
+ { systemParsed: ws.systemParsed, warnings: ws.warnings }
128
162
  );
129
163
  const openapiActionsPerformed = await maybeRunOpenApiSyncForMcp({
130
164
  options: ws.options,
@@ -132,23 +166,68 @@ async function runRepairIntegrationFileSteps(ws) {
132
166
  appPath: ws.appPath,
133
167
  systemKey: ws.systemKey,
134
168
  datasourceFiles: ws.datasourceFiles,
135
- changes: ws.changes
169
+ changes: ws.changes,
170
+ backupCtx: ws.backupCtx
136
171
  });
137
- const { rbacMigratedFromSystem, rbacMergeUpdated } = maybeRepairRbac(
138
- ws.appPath,
139
- ws.systemFilePath,
140
- ws.systemParsed,
141
- ws.datasourceFiles,
142
- { rbac: Boolean(ws.options.rbac), rbacFmt: ws.rbacFmt, dryRun: ws.dryRun, changes: ws.changes, backupCtx: ws.backupCtx }
143
- );
172
+ return { datasourceRepairUpdated: datasourceRepairUpdated || splitResult.updated, openapiActionsPerformed };
173
+ }
174
+
175
+ /**
176
+ * @param {Object} ws
177
+ * @returns {Promise<Object>}
178
+ */
179
+ async function runRepairIntegrationFileSteps(ws) {
180
+ const steps = runRepairSteps({
181
+ appPath: ws.appPath,
182
+ configPath: ws.configPath,
183
+ variables: ws.variables,
184
+ systemFilePath: ws.systemFilePath,
185
+ systemParsed: ws.systemParsed,
186
+ systemKey: ws.systemKey,
187
+ systemFiles: ws.systemFiles,
188
+ datasourceFiles: ws.datasourceFiles,
189
+ dryRun: ws.dryRun,
190
+ changes: ws.changes,
191
+ warnings: ws.warnings,
192
+ auth: ws.authOption,
193
+ format: ws.rbacFmt,
194
+ backupCtx: ws.backupCtx,
195
+ options: ws.options
196
+ });
197
+ if (ws.options.rbac) {
198
+ collectCapabilityOpenApiDriftWarnings(ws.appPath, ws.datasourceFiles, ws.warnings);
199
+ }
200
+ const { datasourceRepairUpdated, openapiActionsPerformed } = await runDatasourceOpenApiRepairs(ws);
201
+ const { rbacMigratedFromSystem, rbacMergeUpdated, rbacSyncedIntoSystem, rbacSecurityBound } =
202
+ maybeRepairRbac(
203
+ ws.appPath,
204
+ ws.systemFilePath,
205
+ ws.systemParsed,
206
+ ws.datasourceFiles,
207
+ {
208
+ rbac: Boolean(ws.options.rbac),
209
+ rbacFmt: ws.rbacFmt,
210
+ rbacPreset: ws.options.rbacPreset,
211
+ dryRun: ws.dryRun,
212
+ changes: ws.changes,
213
+ backupCtx: ws.backupCtx
214
+ }
215
+ );
144
216
  const anyLocalUpdated =
145
- ws.keysNormalized || steps.updated || datasourceRepairUpdated || rbacMigratedFromSystem || rbacMergeUpdated;
217
+ ws.keysNormalized ||
218
+ steps.updated ||
219
+ datasourceRepairUpdated ||
220
+ rbacMigratedFromSystem ||
221
+ rbacMergeUpdated ||
222
+ rbacSyncedIntoSystem ||
223
+ rbacSecurityBound;
146
224
  return {
147
225
  steps,
148
226
  anyLocalUpdated,
149
227
  changes: ws.changes,
150
228
  warnings: ws.warnings,
151
229
  openapiActionsPerformed,
230
+ systemKey: ws.systemKey,
152
231
  systemFiles: ws.systemFiles,
153
232
  datasourceFiles: ws.datasourceFiles
154
233
  };
@@ -171,7 +250,8 @@ async function runRepairLocalUpdates(params) {
171
250
  async function finalizeRepairIntegration(params, local) {
172
251
  const { appName, options, appPath, configPath, dryRun, backupPaths, backupCtx, variables, originalYamlContent } =
173
252
  params;
174
- const { steps, anyLocalUpdated, changes, warnings, openapiActionsPerformed, systemFiles, datasourceFiles } = local;
253
+ const { steps, anyLocalUpdated, changes, warnings, openapiActionsPerformed, systemKey, systemFiles, datasourceFiles } =
254
+ local;
175
255
  let manifestRegenerated = false;
176
256
  if (anyLocalUpdated && !dryRun) {
177
257
  manifestRegenerated = await persistChangesAndRegenerate({
@@ -190,6 +270,16 @@ async function finalizeRepairIntegration(params, local) {
190
270
  { ...options, backupCtx },
191
271
  changes
192
272
  );
273
+ if (!dryRun) {
274
+ await regenerateDeployScript(
275
+ appPath,
276
+ systemKey || appName,
277
+ systemFiles,
278
+ datasourceFiles,
279
+ changes,
280
+ backupCtx
281
+ );
282
+ }
193
283
  const changedFiles = dryRun ? backupCtx.wouldChangeFiles : backupCtx.changedFiles;
194
284
  return buildRepairResult(steps, anyLocalUpdated, manifestRegenerated, readmeRegenerated, {
195
285
  actionsPerformed: openapiActionsPerformed,
@@ -9,7 +9,7 @@
9
9
  'use strict';
10
10
 
11
11
  const path = require('path');
12
- const fs = require('fs');
12
+ const fs = require('../internal/fs-real-sync');
13
13
  const chalk = require('chalk');
14
14
  const logger = require('../utils/logger');
15
15
 
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Export full programmatic OpenAPI (components + request/response schemas) for repair --api.
3
+ *
4
+ * @fileoverview Materialize integration/<systemKey>/openapi/*.json from buildOpenApiSpec
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const fs = require('../internal/fs-real-sync');
12
+ const path = require('path');
13
+ const { buildOpenApiSpec } = require('../programmatic/openapi-spec');
14
+ const { loadConfigFile } = require('../utils/config-format');
15
+ const { backupIntegrationFile } = require('../utils/integration-file-backup');
16
+ const { trackRepairWrite } = require('./repair-changed-files');
17
+
18
+ /**
19
+ * @param {string} appPath
20
+ * @param {string} systemKey
21
+ * @param {string} documentKey
22
+ * @returns {string}
23
+ */
24
+ function documentKeyToLocalOpenApiPath(appPath, systemKey, documentKey) {
25
+ const openapiDir = path.join(appPath, 'openapi');
26
+ const suffix = documentKey.startsWith(`${systemKey}-`)
27
+ ? documentKey.slice(systemKey.length + 1)
28
+ : documentKey;
29
+ return path.join(openapiDir, `${suffix}.json`);
30
+ }
31
+
32
+ /** @type {Set<string>} */
33
+ const PROGRAMMATIC_ORCHESTRATION_SYSTEM_KEYS = new Set(['aifabrix-builder-api']);
34
+
35
+ /**
36
+ * @param {string} systemKey
37
+ * @returns {boolean}
38
+ */
39
+ function isProgrammaticOrchestrationSystem(systemKey) {
40
+ return PROGRAMMATIC_ORCHESTRATION_SYSTEM_KEYS.has(String(systemKey || '').trim());
41
+ }
42
+
43
+ /**
44
+ * @param {string} appPath
45
+ * @param {string} fileName
46
+ * @returns {string|null}
47
+ */
48
+ function readDatasourceDocumentKey(appPath, fileName) {
49
+ const dsPath = path.join(appPath, fileName);
50
+ if (!fs.existsSync(dsPath)) {
51
+ return null;
52
+ }
53
+ const parsed = loadConfigFile(dsPath);
54
+ const openapi = parsed && typeof parsed.openapi === 'object' && !Array.isArray(parsed.openapi) ? parsed.openapi : null;
55
+ return openapi && typeof openapi.documentKey === 'string' ? openapi.documentKey.trim() : null;
56
+ }
57
+
58
+ /**
59
+ * @param {string} appPath
60
+ * @param {string[]} datasourceFiles
61
+ * @returns {string|null}
62
+ */
63
+ function resolveSharedDocumentKey(appPath, datasourceFiles) {
64
+ const keys = new Set();
65
+ for (const fileName of datasourceFiles || []) {
66
+ const dk = readDatasourceDocumentKey(appPath, fileName);
67
+ if (dk) {
68
+ keys.add(dk);
69
+ }
70
+ }
71
+ if (keys.size === 1) {
72
+ return [...keys][0];
73
+ }
74
+ return null;
75
+ }
76
+
77
+ /**
78
+ * @param {Object} spec
79
+ * @returns {boolean}
80
+ */
81
+ function specHasComponentSchemas(spec) {
82
+ const schemas = spec && spec.components && spec.components.schemas;
83
+ return Boolean(schemas && typeof schemas === 'object' && Object.keys(schemas).length > 0);
84
+ }
85
+
86
+ /**
87
+ * @param {string} localPath
88
+ * @param {Object} spec
89
+ * @param {boolean} dryRun
90
+ * @param {Object} backupCtx
91
+ * @returns {Promise<void>}
92
+ */
93
+ async function writeOpenApiSpecToDisk(localPath, spec, dryRun, backupCtx) {
94
+ if (dryRun) {
95
+ return;
96
+ }
97
+ const openapiDir = path.dirname(localPath);
98
+ fs.mkdirSync(openapiDir, { recursive: true });
99
+ if (fs.existsSync(localPath)) {
100
+ backupIntegrationFile(localPath, backupCtx);
101
+ }
102
+ fs.writeFileSync(localPath, `${JSON.stringify(spec, null, 2)}\n`, 'utf8');
103
+ trackRepairWrite(localPath, backupCtx);
104
+ }
105
+
106
+ /**
107
+ * @param {string} localPath
108
+ * @param {Object} spec
109
+ * @returns {string}
110
+ */
111
+ function formatOpenApiExportSummary(localPath, spec) {
112
+ const rel = path.relative(process.cwd(), localPath);
113
+ return (
114
+ `Exported full OpenAPI (${Object.keys(spec.paths || {}).length} paths, `
115
+ + `${Object.keys(spec.components.schemas || {}).length} schemas) to ${rel}`
116
+ );
117
+ }
118
+
119
+ /**
120
+ * @param {Object} opts
121
+ * @param {string} opts.appPath
122
+ * @param {string} opts.systemKey
123
+ * @param {string[]} opts.datasourceFiles
124
+ * @param {boolean} opts.dryRun
125
+ * @param {Object} opts.backupCtx
126
+ * @returns {Promise<string[]>}
127
+ */
128
+ async function exportProgrammaticOpenApiForRepair(opts) {
129
+ const { appPath, systemKey, datasourceFiles, dryRun, backupCtx } = opts;
130
+ const lines = [];
131
+ if (!isProgrammaticOrchestrationSystem(systemKey)) {
132
+ return lines;
133
+ }
134
+ const documentKey = resolveSharedDocumentKey(appPath, datasourceFiles);
135
+ if (!documentKey) {
136
+ lines.push('Skipped OpenAPI export: datasources do not share a single openapi.documentKey');
137
+ return lines;
138
+ }
139
+ const localPath = documentKeyToLocalOpenApiPath(appPath, systemKey, documentKey);
140
+ const spec = buildOpenApiSpec();
141
+ if (!specHasComponentSchemas(spec)) {
142
+ lines.push('Skipped OpenAPI export: programmatic buildOpenApiSpec() has no component schemas');
143
+ return lines;
144
+ }
145
+ await writeOpenApiSpecToDisk(localPath, spec, dryRun, backupCtx);
146
+ lines.push(formatOpenApiExportSummary(localPath, spec));
147
+ return lines;
148
+ }
149
+
150
+ module.exports = {
151
+ documentKeyToLocalOpenApiPath,
152
+ exportProgrammaticOpenApiForRepair,
153
+ isProgrammaticOrchestrationSystem,
154
+ resolveSharedDocumentKey,
155
+ specHasComponentSchemas
156
+ };
@@ -24,6 +24,7 @@ const { resolveDataplaneUrl } = require('../utils/dataplane-resolver');
24
24
  const { uploadFileAs } = require('../utils/file-upload');
25
25
  const { listOpenAPIFiles } = require('../api/external-systems.api');
26
26
  const { resolveLabDataplaneApiKey } = require('../utils/credential-secrets-env');
27
+ const { exportProgrammaticOpenApiForRepair } = require('./repair-openapi-export');
27
28
 
28
29
  async function fileExistsAsync(filePath) {
29
30
  try {
@@ -190,9 +191,25 @@ async function maybeSyncOpenApiFilesForMcp(opts) {
190
191
  * @param {Object} args
191
192
  * @returns {Promise<boolean>}
192
193
  */
193
- async function maybeRunOpenApiSyncForMcp({ options, dryRun, appPath, systemKey, datasourceFiles, changes }) {
194
+ async function maybeRunOpenApiSyncForMcp({
195
+ options,
196
+ dryRun,
197
+ appPath,
198
+ systemKey,
199
+ datasourceFiles,
200
+ changes,
201
+ backupCtx
202
+ }) {
194
203
  if (!options.api) return false;
195
204
  try {
205
+ const exportLines = await exportProgrammaticOpenApiForRepair({
206
+ appPath,
207
+ systemKey,
208
+ datasourceFiles,
209
+ dryRun,
210
+ backupCtx
211
+ });
212
+ exportLines.forEach((line) => changes.push(line));
196
213
  const openapiLines = await maybeSyncOpenApiFilesForMcp({
197
214
  enabled: true,
198
215
  dryRun,
@@ -201,7 +218,7 @@ async function maybeRunOpenApiSyncForMcp({ options, dryRun, appPath, systemKey,
201
218
  datasourceFiles
202
219
  });
203
220
  openapiLines.forEach((l) => changes.push(l));
204
- return openapiLines.length > 0;
221
+ return exportLines.length > 0 || openapiLines.length > 0;
205
222
  } catch (err) {
206
223
  changes.push(`OpenAPI upload for MCP failed: ${err.message}`);
207
224
  return false;