@aifabrix/builder 2.45.0 → 2.46.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 (352) hide show
  1. package/.cursor/rules/cli-layout.mdc +2 -0
  2. package/.cursor/rules/cli-product-neutral.mdc +43 -0
  3. package/.cursor/rules/docs-rules.mdc +3 -1
  4. package/.cursor/rules/project-rules.mdc +1 -0
  5. package/README.md +43 -17
  6. package/integration/hubspot-test/wizard-hubspot-e2e.yaml +1 -1
  7. package/jest.config.default.js +2 -1
  8. package/jest.config.isolated.js +2 -1
  9. package/jest.global-live-fabrix-hooks.js +36 -0
  10. package/jest.isolated-projects.js +130 -0
  11. package/jest.projects.js +69 -121
  12. package/lib/api/agent-metadata-validation.api.js +93 -0
  13. package/lib/api/api-response-errors.js +124 -0
  14. package/lib/api/audit-api-helpers.js +68 -0
  15. package/lib/api/audit.api.js +119 -0
  16. package/lib/api/auth-cache.api.js +44 -0
  17. package/lib/api/certificates.api.js +4 -4
  18. package/lib/api/credential.api.js +2 -2
  19. package/lib/api/dataplane-health.api.js +137 -0
  20. package/lib/api/dataplane-sync.api.js +27 -0
  21. package/lib/api/datasources-core.api.js +21 -18
  22. package/lib/api/datasources-extended.api.js +22 -22
  23. package/lib/api/dimensions.api.js +3 -0
  24. package/lib/api/external-systems.api.js +13 -13
  25. package/lib/api/governance-scenario-pack.api.js +159 -0
  26. package/lib/api/governance-scenarios.api.js +39 -0
  27. package/lib/api/groups.api.js +79 -0
  28. package/lib/api/index.js +88 -5
  29. package/lib/api/lifecycle.api.js +77 -0
  30. package/lib/api/pipeline.api.js +7 -5
  31. package/lib/api/protection.api.js +157 -0
  32. package/lib/api/records-bulk.api.js +43 -0
  33. package/lib/api/records-search-parse.js +49 -0
  34. package/lib/api/records-search.api.js +29 -0
  35. package/lib/api/types/agent-metadata-validation.types.js +67 -0
  36. package/lib/api/types/audit.types.js +72 -0
  37. package/lib/api/types/dataplane-health.types.js +27 -0
  38. package/lib/api/types/dimensions.types.js +2 -0
  39. package/lib/api/types/governance-scenarios.types.js +39 -0
  40. package/lib/api/types/protection.types.js +69 -0
  41. package/lib/api/types/records-bulk.types.js +35 -0
  42. package/lib/api/types/records-search.types.js +28 -0
  43. package/lib/api/user-groups.api.js +50 -0
  44. package/lib/api/users.api.js +95 -0
  45. package/lib/api/validation-run.api.js +3 -3
  46. package/lib/api/validation-runner.js +5 -3
  47. package/lib/api/wizard-platform.api.js +3 -3
  48. package/lib/api/wizard.api.js +21 -21
  49. package/lib/app/deploy-config.js +4 -1
  50. package/lib/app/deploy.js +34 -19
  51. package/lib/app/down.js +20 -1
  52. package/lib/app/push.js +4 -5
  53. package/lib/app/register.js +7 -4
  54. package/lib/app/run-env-compose.js +84 -30
  55. package/lib/build/index.js +5 -0
  56. package/lib/certification/sync-system-certification.js +13 -6
  57. package/lib/cli/index.js +8 -2
  58. package/lib/cli/infra-guided-auth.js +109 -0
  59. package/lib/cli/infra-guided.js +91 -69
  60. package/lib/cli/setup-app.help.js +19 -2
  61. package/lib/cli/setup-app.js +58 -23
  62. package/lib/cli/setup-app.test-commands.js +28 -21
  63. package/lib/cli/setup-auth.js +55 -3
  64. package/lib/cli/setup-certification-commands.js +147 -0
  65. package/lib/cli/setup-certification.help.js +141 -0
  66. package/lib/cli/setup-environment.js +19 -2
  67. package/lib/cli/setup-external-system-help.js +62 -0
  68. package/lib/cli/setup-external-system.js +62 -6
  69. package/lib/cli/setup-infra.js +9 -1
  70. package/lib/cli/setup-platform.js +6 -1
  71. package/lib/cli/setup-secrets.js +33 -1
  72. package/lib/cli/setup-utility-help-after.js +65 -0
  73. package/lib/cli/setup-utility-repair.js +198 -0
  74. package/lib/cli/setup-utility-resolve.js +42 -6
  75. package/lib/cli/setup-utility-validate.js +197 -0
  76. package/lib/cli/setup-utility.js +41 -258
  77. package/lib/commands/auth-status-client-tokens.js +214 -0
  78. package/lib/commands/auth-status-dataplane-version.js +269 -0
  79. package/lib/commands/auth-status-display.js +94 -0
  80. package/lib/commands/auth-status.js +111 -53
  81. package/lib/commands/credential-push.js +10 -5
  82. package/lib/commands/datasource-load-export-cli.js +178 -0
  83. package/lib/commands/datasource-test-trust-cli.js +118 -0
  84. package/lib/commands/datasource-unified-test-cli.js +31 -20
  85. package/lib/commands/datasource-unified-test-cli.options.js +22 -3
  86. package/lib/commands/datasource-unified-test-e2e-cli-helpers.js +5 -5
  87. package/lib/commands/datasource-verify-audit-cli.js +96 -0
  88. package/lib/commands/datasource.js +68 -1
  89. package/lib/commands/dev-show-display.js +8 -1
  90. package/lib/commands/dimension-value.js +43 -13
  91. package/lib/commands/dimension.js +38 -7
  92. package/lib/commands/governance-cli-shared.js +94 -0
  93. package/lib/commands/governance-command-action.js +132 -0
  94. package/lib/commands/governance-download-external.js +34 -0
  95. package/lib/commands/governance-generate-external.js +71 -0
  96. package/lib/commands/governance-upload-external.js +36 -0
  97. package/lib/commands/governance-verify-external.js +64 -0
  98. package/lib/commands/governance.js +144 -0
  99. package/lib/commands/identity-apply-sync.js +131 -0
  100. package/lib/commands/identity-group-cli.js +146 -0
  101. package/lib/commands/identity-membership-role-cache.js +175 -0
  102. package/lib/commands/identity-shared.js +94 -0
  103. package/lib/commands/identity-user-cli.js +158 -0
  104. package/lib/commands/identity.js +43 -0
  105. package/lib/commands/lifecycle-command-action.js +123 -0
  106. package/lib/commands/lifecycle-external.js +268 -0
  107. package/lib/commands/login.js +56 -17
  108. package/lib/commands/protection-cli-leaves.js +286 -0
  109. package/lib/commands/protection.js +50 -0
  110. package/lib/commands/repair-auth-apply.js +127 -0
  111. package/lib/commands/repair-changed-files.js +41 -0
  112. package/lib/commands/repair-datasource-keys.js +4 -1
  113. package/lib/commands/repair-datasource-run.js +59 -0
  114. package/lib/commands/repair-datasource-test-payload.js +259 -0
  115. package/lib/commands/repair-datasource.js +1 -51
  116. package/lib/commands/repair-env-template.js +64 -13
  117. package/lib/commands/repair-external-run.js +216 -0
  118. package/lib/commands/repair-openapi-sync.js +23 -0
  119. package/lib/commands/repair-persist.js +4 -0
  120. package/lib/commands/repair-rbac.js +52 -1
  121. package/lib/commands/repair-steps.js +145 -0
  122. package/lib/commands/repair.js +29 -286
  123. package/lib/commands/secrets-get.js +184 -0
  124. package/lib/commands/secrets-remove-all.js +3 -1
  125. package/lib/commands/setup-image-refresh.js +146 -0
  126. package/lib/commands/setup-modes.js +158 -162
  127. package/lib/commands/setup-platform-auth.js +76 -0
  128. package/lib/commands/setup-prompts-admin.js +244 -0
  129. package/lib/commands/setup-prompts-platform-mode.js +67 -0
  130. package/lib/commands/setup-prompts-validators.js +36 -0
  131. package/lib/commands/setup-prompts.js +24 -76
  132. package/lib/commands/setup-run-context.js +45 -0
  133. package/lib/commands/setup-spinners.js +39 -0
  134. package/lib/commands/setup.js +27 -5
  135. package/lib/commands/teardown.js +39 -0
  136. package/lib/commands/test-e2e-external.js +61 -14
  137. package/lib/commands/test-governance-cli-options.js +47 -0
  138. package/lib/commands/test-governance-external.js +67 -0
  139. package/lib/commands/test-trust-cli-options.js +32 -0
  140. package/lib/commands/test-trust-external.js +126 -0
  141. package/lib/commands/up-common.js +25 -13
  142. package/lib/commands/up-dataplane.js +50 -13
  143. package/lib/commands/upload-publish-context.js +75 -0
  144. package/lib/commands/upload-sidecar-followups.js +89 -0
  145. package/lib/commands/upload.js +108 -105
  146. package/lib/commands/verify-governance-combined-external.js +61 -0
  147. package/lib/commands/verify-governance-command-action.js +64 -0
  148. package/lib/commands/verify-governance-db.js +102 -0
  149. package/lib/commands/verify-governance-external.js +77 -0
  150. package/lib/commands/verify-governance-result-builders.js +71 -0
  151. package/lib/commands/verify-operations-command-action.js +68 -0
  152. package/lib/commands/verify-operations-external.js +268 -0
  153. package/lib/commands/verify-operations-persist.js +75 -0
  154. package/lib/commands/verify-operations-step-plan.js +68 -0
  155. package/lib/commands/verify-operations-steps.js +111 -0
  156. package/lib/commands/verify-trust-command-action.js +70 -0
  157. package/lib/commands/verify-trust-external.js +67 -0
  158. package/lib/commands/wizard-config-normalizer.js +43 -23
  159. package/lib/commands/wizard-core.js +5 -0
  160. package/lib/core/admin-password-generator.js +38 -0
  161. package/lib/core/admin-secrets-bundle.js +111 -0
  162. package/lib/core/admin-secrets-env-overlay.js +62 -0
  163. package/lib/core/admin-secrets.js +32 -4
  164. package/lib/core/config-attach-extensions.js +3 -0
  165. package/lib/core/config-device-dataplane.js +185 -0
  166. package/lib/core/config-platform-controller.js +44 -0
  167. package/lib/core/config-setup-installation-profile.js +42 -0
  168. package/lib/core/config-setup-platform-mode.js +46 -0
  169. package/lib/core/config.js +46 -36
  170. package/lib/core/secrets-admin-env.js +6 -2
  171. package/lib/core/secrets-ensure.js +4 -0
  172. package/lib/core/secrets-env-content.js +54 -48
  173. package/lib/core/secrets-env-write.js +10 -1
  174. package/lib/core/secrets-infra-placeholder-sync.js +2 -0
  175. package/lib/core/setup-installation-profile.js +43 -0
  176. package/lib/core/setup-platform-mode.js +55 -0
  177. package/lib/datasource/agent-trust-debug-log.js +45 -0
  178. package/lib/datasource/agent-trust-fetch.js +115 -0
  179. package/lib/datasource/agent-trust-map.js +101 -0
  180. package/lib/datasource/agent-trust-mock.js +44 -0
  181. package/lib/datasource/agent-trust-run.js +95 -0
  182. package/lib/datasource/agent-trust-timeout.js +25 -0
  183. package/lib/datasource/audit-evidence-display.js +80 -0
  184. package/lib/datasource/audit-evidence-extract-debug.js +115 -0
  185. package/lib/datasource/audit-evidence-extract.js +180 -0
  186. package/lib/datasource/audit-evidence-matrix-rows.js +158 -0
  187. package/lib/datasource/audit-evidence-operation-aliases.js +63 -0
  188. package/lib/datasource/audit-evidence-poll.js +109 -0
  189. package/lib/datasource/audit-evidence-run.js +177 -0
  190. package/lib/datasource/audit-evidence-verify-helpers.js +167 -0
  191. package/lib/datasource/audit-evidence-verify-matrix.js +205 -0
  192. package/lib/datasource/audit-evidence-verify.js +108 -0
  193. package/lib/datasource/bulk-loader-run-batches.js +100 -0
  194. package/lib/datasource/bulk-loader-service-retry.js +52 -0
  195. package/lib/datasource/bulk-loader-service.js +127 -0
  196. package/lib/datasource/capability/run-capability-dimension.js +2 -1
  197. package/lib/datasource/datasource-exporter-resolve.js +82 -0
  198. package/lib/datasource/datasource-exporter-service.js +144 -0
  199. package/lib/datasource/datasource-identifier.js +148 -0
  200. package/lib/datasource/datasource-load-export-context.js +95 -0
  201. package/lib/datasource/integration-context.js +6 -4
  202. package/lib/datasource/local-data-paths.js +145 -0
  203. package/lib/datasource/log-cleaner.js +241 -0
  204. package/lib/datasource/log-viewer.js +111 -6
  205. package/lib/datasource/record-file-parser.js +85 -0
  206. package/lib/datasource/record-mapper.js +129 -0
  207. package/lib/datasource/resolve-app.js +74 -55
  208. package/lib/datasource/test-e2e.js +29 -2
  209. package/lib/datasource/unified-validation-run-body.js +3 -1
  210. package/lib/datasource/unified-validation-run-resolve.js +45 -12
  211. package/lib/datasource/unified-validation-run.js +47 -18
  212. package/lib/datasource/validate.js +37 -20
  213. package/lib/deployment/environment-poll-status.js +138 -0
  214. package/lib/deployment/environment.js +42 -34
  215. package/lib/external-system/download.js +21 -20
  216. package/lib/external-system/generator.js +5 -1
  217. package/lib/external-system/integration-auth-context.js +45 -0
  218. package/lib/external-system/test-auth.js +12 -5
  219. package/lib/external-system/test-system-level.js +25 -4
  220. package/lib/external-system/test.js +9 -7
  221. package/lib/generator/external-controller-manifest.js +15 -0
  222. package/lib/governance/governance-cli-errors.js +96 -0
  223. package/lib/governance/governance-download-display.js +38 -0
  224. package/lib/governance/governance-pack-loader.js +70 -0
  225. package/lib/governance/governance-run-display.js +309 -0
  226. package/lib/identity/identity-apply-core.js +108 -0
  227. package/lib/identity/identity-apply-phases.js +244 -0
  228. package/lib/identity/identity-apply-service.js +77 -0
  229. package/lib/identity/identity-csv-parser.js +114 -0
  230. package/lib/infrastructure/admin-secrets-apply.js +84 -0
  231. package/lib/infrastructure/admin-secrets-ensure.js +130 -0
  232. package/lib/infrastructure/admin-secrets-resolve.js +95 -0
  233. package/lib/infrastructure/admin-secrets-sync.js +91 -0
  234. package/lib/infrastructure/helpers.js +23 -129
  235. package/lib/infrastructure/index.js +5 -6
  236. package/lib/infrastructure/orphan-infra-docker-teardown.js +11 -5
  237. package/lib/internal/fs-real-sync.js +29 -1
  238. package/lib/lifecycle/certification-progress.js +231 -0
  239. package/lib/lifecycle/dataplane-ui-url.js +145 -0
  240. package/lib/lifecycle/exit-codes.js +24 -0
  241. package/lib/lifecycle/json-envelope.js +25 -0
  242. package/lib/lifecycle/lifecycle-governance-options.js +51 -0
  243. package/lib/lifecycle/logger-quiet.js +29 -0
  244. package/lib/lifecycle/open-api-published.js +59 -0
  245. package/lib/lifecycle/operations-readiness-metrics.js +101 -0
  246. package/lib/lifecycle/product-model.js +196 -0
  247. package/lib/lifecycle/report-display.js +471 -0
  248. package/lib/lifecycle/scenario-upload.js +191 -0
  249. package/lib/lifecycle/verify-step-progress.js +87 -0
  250. package/lib/parameters/infra-kv-discovery.js +27 -2
  251. package/lib/protection/auth-context.js +51 -0
  252. package/lib/protection/convert-batch.js +90 -0
  253. package/lib/protection/load.js +41 -0
  254. package/lib/protection/paths.js +158 -0
  255. package/lib/protection/preflight-datasource-ready.js +46 -0
  256. package/lib/protection/protection-create-probe-lines.js +142 -0
  257. package/lib/protection/protection-create-probes.js +95 -0
  258. package/lib/protection/protection-create-scaffold.js +281 -0
  259. package/lib/protection/protection-display-helpers.js +445 -0
  260. package/lib/protection/protection-display.js +215 -0
  261. package/lib/protection/protection-preset-registry.js +97 -0
  262. package/lib/protection/report-exit.js +62 -0
  263. package/lib/protection/resolve.js +202 -0
  264. package/lib/protection/run-commands-validate.js +130 -0
  265. package/lib/protection/run-commands.js +216 -0
  266. package/lib/protection/run-protection-create-helpers.js +134 -0
  267. package/lib/protection/run-protection-create-probes-flow.js +43 -0
  268. package/lib/protection/run-protection-create.js +191 -0
  269. package/lib/protection/scope.js +22 -0
  270. package/lib/protection/sync-after-upload.js +64 -0
  271. package/lib/protection/upload-batch.js +127 -0
  272. package/lib/protection/validate-batch.js +113 -0
  273. package/lib/protection/validate-local.js +65 -0
  274. package/lib/resolvers/dimension-file.js +29 -4
  275. package/lib/schema/application-schema.json +1 -1
  276. package/lib/schema/datasource-test-run.schema.json +89 -6
  277. package/lib/schema/external-datasource.schema.json +2636 -2588
  278. package/lib/schema/external-system.schema.json +1089 -761
  279. package/lib/schema/flag-map-validation-run.json +2 -2
  280. package/lib/schema/infra.parameter.yaml +45 -0
  281. package/lib/schema/protection.schema.json +374 -0
  282. package/lib/schema/type/credential-field-registry.json +642 -0
  283. package/lib/schema/wizard-config.schema.json +1 -1
  284. package/lib/utils/agent-trust-run-display.js +231 -0
  285. package/lib/utils/agent-trust-run-exit.js +59 -0
  286. package/lib/utils/agent-trust-wait-ui.js +94 -0
  287. package/lib/utils/aifabrix-test-runtime-guard.js +125 -0
  288. package/lib/utils/api.js +55 -31
  289. package/lib/utils/app-relative-path-env.js +112 -0
  290. package/lib/utils/cli-exit-codes.js +30 -0
  291. package/lib/utils/cli-secrets-error-format.js +83 -21
  292. package/lib/utils/cli-sync-options.js +33 -0
  293. package/lib/utils/cli-utils.js +16 -4
  294. package/lib/utils/compose-generate-docker-compose.js +4 -0
  295. package/lib/utils/compose-traefik-ingress-base.js +16 -1
  296. package/lib/utils/config-secrets-path.js +46 -0
  297. package/lib/utils/controller-url.js +88 -1
  298. package/lib/utils/credential-push-ui.js +90 -0
  299. package/lib/utils/credential-secrets-env.js +137 -9
  300. package/lib/utils/dataplane-cli-version-gate.js +202 -0
  301. package/lib/utils/dataplane-cli-version-help.js +74 -0
  302. package/lib/utils/dataplane-resolver.js +129 -2
  303. package/lib/utils/datasource-export-display.js +137 -0
  304. package/lib/utils/datasource-load-display.js +174 -0
  305. package/lib/utils/datasource-load-export-ui.js +120 -0
  306. package/lib/utils/datasource-test-run-capability-scope.js +3 -3
  307. package/lib/utils/datasource-test-run-display.js +3 -3
  308. package/lib/utils/datasource-test-run-tty-log.js +5 -1
  309. package/lib/utils/declarative-url-ports.js +3 -3
  310. package/lib/utils/deployment-auth-mode.js +41 -0
  311. package/lib/utils/developer-volume-id.js +33 -0
  312. package/lib/utils/env-copy.js +14 -9
  313. package/lib/utils/env-kv-orphan-lines.js +43 -0
  314. package/lib/utils/error-formatters/network-errors.js +13 -4
  315. package/lib/utils/external-env-template.js +1 -0
  316. package/lib/utils/external-system-readiness-core.js +10 -0
  317. package/lib/utils/external-system-readiness-display.js +80 -23
  318. package/lib/utils/health-check.js +4 -1
  319. package/lib/utils/help-builder.js +35 -26
  320. package/lib/utils/keycloak-realm-ready.js +101 -0
  321. package/lib/utils/load-cip-capacity-display-config.js +61 -15
  322. package/lib/utils/manifest-source-emit.js +24 -0
  323. package/lib/utils/pipeline-upload-auth-retry.js +82 -0
  324. package/lib/utils/platform-controller-url.js +156 -0
  325. package/lib/utils/postgres-platform-bootstrap.js +199 -0
  326. package/lib/utils/postgres-wipe.js +9 -2
  327. package/lib/utils/resolve-env-mode.js +47 -0
  328. package/lib/utils/secrets-generator.js +31 -25
  329. package/lib/utils/secrets-missing-error.js +164 -0
  330. package/lib/utils/semver-compare.js +127 -0
  331. package/lib/utils/service-url-label.js +81 -0
  332. package/lib/utils/setup-quiet-output.js +25 -0
  333. package/lib/utils/template-helpers.js +15 -0
  334. package/lib/utils/token-manager-client-credentials.js +201 -0
  335. package/lib/utils/token-manager-messages.js +8 -0
  336. package/lib/utils/token-manager-refresh.js +12 -2
  337. package/lib/utils/token-manager.js +86 -105
  338. package/lib/utils/upload-pipeline-ui.js +98 -0
  339. package/lib/utils/upload-sync-options.js +42 -0
  340. package/lib/utils/url-declarative-public-base.js +21 -3
  341. package/lib/utils/url-declarative-vdir-inactive-env.js +14 -4
  342. package/lib/utils/validation-poll-ui.js +22 -7
  343. package/lib/utils/validation-run-stage.js +45 -0
  344. package/lib/validation/wizard-config-validator.js +58 -19
  345. package/package.json +1 -1
  346. package/templates/applications/dataplane/application.yaml +2 -1
  347. package/templates/applications/dataplane/env.template +36 -1
  348. package/templates/applications/dataplane/rbac.yaml +4 -0
  349. package/templates/applications/miso-controller/env.template +16 -0
  350. package/templates/external-system/README.md.hbs +116 -11
  351. package/templates/python/docker-compose.hbs +19 -18
  352. package/templates/typescript/docker-compose.hbs +18 -17
@@ -17,6 +17,7 @@ const { getDeployJsonPath } = require('../utils/paths');
17
17
  const { resolveApplicationConfigPath } = require('../utils/app-config-resolver');
18
18
  const { writeConfigFile, writeYamlPreservingComments, isYamlPath } = require('../utils/config-format');
19
19
  const { backupIntegrationFile } = require('../utils/integration-file-backup');
20
+ const { trackRepairWrite } = require('./repair-changed-files');
20
21
  const logger = require('../utils/logger');
21
22
  const generator = require('../generator');
22
23
  const { generateReadmeFromDeployJson } = require('../generator/split-readme');
@@ -40,6 +41,7 @@ function inferExternalReadmeFileExt(appPath) {
40
41
  async function regenerateManifest(appName, appPath, changes, backupCtx) {
41
42
  try {
42
43
  const deployPath = getDeployJsonPath(appName, 'external', true);
44
+ trackRepairWrite(deployPath, backupCtx);
43
45
  backupIntegrationFile(deployPath, backupCtx);
44
46
  const outPath = await generator.generateDeployJson(appName, { appPath });
45
47
  changes.push(`Regenerated ${path.basename(outPath)}`);
@@ -70,6 +72,7 @@ async function regenerateReadmeIfRequested(appName, appPath, options, changes) {
70
72
  const fileExt = inferExternalReadmeFileExt(appPath);
71
73
  const readmeContent = generateReadmeFromDeployJson(deployment, { fileExt });
72
74
  const readmePath = path.join(appPath, 'README.md');
75
+ trackRepairWrite(readmePath, options.backupCtx);
73
76
  if (!options.dryRun) {
74
77
  backupIntegrationFile(readmePath, options.backupCtx);
75
78
  fs.writeFileSync(readmePath, readmeContent, { mode: 0o644, encoding: 'utf8' });
@@ -84,6 +87,7 @@ async function regenerateReadmeIfRequested(appName, appPath, options, changes) {
84
87
 
85
88
  function persistChangesAndRegenerate(opts) {
86
89
  const { configPath, variables, appName, appPath, changes, originalYamlContent, backupCtx } = opts;
90
+ trackRepairWrite(configPath, backupCtx);
87
91
  backupIntegrationFile(configPath, backupCtx);
88
92
  if (originalYamlContent !== null && originalYamlContent !== undefined && typeof originalYamlContent === 'string' && isYamlPath(configPath)) {
89
93
  writeYamlPreservingComments(configPath, originalYamlContent, variables);
@@ -361,10 +361,61 @@ function mergeRbacFromDatasources(appPath, systemParsed, datasourceFiles, extrac
361
361
  }
362
362
 
363
363
  const { migrateSystemRbacIntoRbacFile } = require('./repair-rbac-migrate');
364
+ const { resolveRbacPath } = require('../utils/app-config-resolver');
365
+
366
+ /**
367
+ * @param {Object} opts
368
+ * @returns {boolean}
369
+ */
370
+ function createRbacFromSystemIfNeeded(opts) {
371
+ const { appPath, systemFilePath, systemParsed, dryRun, changes, format, backupCtx } = opts;
372
+ if (resolveRbacPath(appPath)) return false;
373
+ const rbacFromSystem = extractRbacFromSystem(systemParsed);
374
+ if (!rbacFromSystem) return false;
375
+ if (!dryRun) {
376
+ const rbacFormat = format === 'json' ? 'json' : 'yaml';
377
+ const defaultRbacPath = path.join(appPath, rbacFormat === 'json' ? 'rbac.json' : 'rbac.yaml');
378
+ writeConfigFile(defaultRbacPath, rbacFromSystem, rbacFormat);
379
+ delete systemParsed.roles;
380
+ delete systemParsed.permissions;
381
+ backupIntegrationFile(systemFilePath, backupCtx);
382
+ writeConfigFile(systemFilePath, systemParsed);
383
+ }
384
+ changes.push('Created rbac.yaml from system roles/permissions');
385
+ changes.push('Removed roles/permissions from system file (now in rbac file)');
386
+ return true;
387
+ }
388
+
389
+ /**
390
+ * @param {string} appPath
391
+ * @param {string} systemFilePath
392
+ * @param {Object} systemParsed
393
+ * @param {string[]} datasourceFiles
394
+ * @param {Object} options
395
+ * @returns {{ rbacMigratedFromSystem: boolean, rbacMergeUpdated: boolean }}
396
+ */
397
+ function maybeRepairRbac(appPath, systemFilePath, systemParsed, datasourceFiles, options) {
398
+ if (!options.rbac) return { rbacMigratedFromSystem: false, rbacMergeUpdated: false };
399
+ const { dryRun, changes, backupCtx, rbacFmt } = options;
400
+ const rbacMigratedFromSystem = migrateSystemRbacIntoRbacFile(appPath, systemFilePath, systemParsed, {
401
+ dryRun,
402
+ changes,
403
+ backupCtx
404
+ });
405
+ const rbacMergeUpdated = mergeRbacFromDatasources(appPath, systemParsed, datasourceFiles, extractRbacFromSystem, {
406
+ format: rbacFmt,
407
+ dryRun,
408
+ changes,
409
+ backupCtx
410
+ });
411
+ return { rbacMigratedFromSystem, rbacMergeUpdated };
412
+ }
364
413
 
365
414
  module.exports = {
366
415
  extractRbacFromSystem,
367
416
  getCapabilitiesFromDatasource,
368
417
  mergeRbacFromDatasources,
369
- migrateSystemRbacIntoRbacFile
418
+ migrateSystemRbacIntoRbacFile,
419
+ createRbacFromSystemIfNeeded,
420
+ maybeRepairRbac
370
421
  };
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Core repair step runner (integration block, system alignment, auth, RBAC file, env.template).
3
+ *
4
+ * @fileoverview Repair step orchestration
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const { backupIntegrationFile } = require('../utils/integration-file-backup');
12
+ const { writeConfigFile } = require('../utils/config-format');
13
+ const { trackRepairWrite } = require('./repair-changed-files');
14
+ const { repairEnvTemplate, normalizeSystemFileAuthAndConfig } = require('./repair-env-template');
15
+ const { createRbacFromSystemIfNeeded } = require('./repair-rbac');
16
+ const {
17
+ alignAppKeyWithSystem,
18
+ alignDatasourceSystemKeys,
19
+ alignSystemFileDataSources,
20
+ ensureExternalIntegrationBlock,
21
+ removeAuthVarsFromConfiguration
22
+ } = require('./repair-system-alignment');
23
+ const {
24
+ isAllowedRepairAuth,
25
+ normalizeRepairAuthOption,
26
+ buildAuthenticationForRepair,
27
+ mergePreservedAuthVariables,
28
+ repairAuthChangeLabel,
29
+ auditRepairAuthenticationWarnings
30
+ } = require('./repair-auth-apply');
31
+
32
+ /**
33
+ * Apply --auth: replace system file authentication with canonical block for the given method.
34
+ * @param {Object} ctx - Context with systemParsed, systemKey, auth, dryRun, changes
35
+ * @returns {boolean} True if auth was replaced
36
+ */
37
+ function applyAuthMethod(ctx) {
38
+ if (!ctx.auth || typeof ctx.auth !== 'string') return false;
39
+ const authOption = normalizeRepairAuthOption(ctx.auth);
40
+ if (!isAllowedRepairAuth(authOption)) {
41
+ throw new Error(
42
+ 'Invalid --auth "' +
43
+ `${ctx.auth}". Allowed methods: oauth2, aad, apikey, bearerToken, basic, queryParam, oidc, hmac, none`
44
+ );
45
+ }
46
+ const existingAuth = ctx.systemParsed.authentication || ctx.systemParsed.auth || {};
47
+ const newAuth = buildAuthenticationForRepair(ctx.systemKey, authOption);
48
+ const existingVars =
49
+ existingAuth.variables && typeof existingAuth.variables === 'object'
50
+ ? existingAuth.variables
51
+ : {};
52
+ const mergedVariables = { ...newAuth.variables };
53
+ mergePreservedAuthVariables(mergedVariables, existingVars);
54
+ ctx.systemParsed.authentication = {
55
+ ...newAuth,
56
+ variables: mergedVariables
57
+ };
58
+ if (existingAuth.displayName !== undefined) {
59
+ ctx.systemParsed.authentication.displayName = existingAuth.displayName;
60
+ }
61
+ ctx.changes.push(`Set authentication method to ${repairAuthChangeLabel(authOption)}`);
62
+ return true;
63
+ }
64
+
65
+ /**
66
+ * @param {Object} ctx
67
+ * @param {Object} flags
68
+ * @returns {boolean}
69
+ */
70
+ function persistSystemFileRepair(ctx, flags) {
71
+ const systemFileUpdated =
72
+ flags.authReplaced ||
73
+ flags.systemAuthConfigNormalized ||
74
+ flags.systemDataSourcesAligned ||
75
+ flags.authVarsRemoved;
76
+ if (!systemFileUpdated) {
77
+ return false;
78
+ }
79
+ trackRepairWrite(ctx.systemFilePath, ctx.backupCtx);
80
+ if (!ctx.dryRun) {
81
+ backupIntegrationFile(ctx.systemFilePath, ctx.backupCtx);
82
+ writeConfigFile(ctx.systemFilePath, ctx.systemParsed);
83
+ }
84
+ return true;
85
+ }
86
+
87
+ /**
88
+ * @param {Object} ctx
89
+ * @returns {{ updated: boolean, appKeyFixed: boolean, datasourceKeysFixed: boolean, rbacFileCreated: boolean, envTemplateRepaired: boolean }}
90
+ */
91
+ function runRepairSteps(ctx) {
92
+ const bc = ctx.backupCtx;
93
+ let updated = ensureExternalIntegrationBlock(
94
+ ctx.variables, ctx.systemFiles, ctx.datasourceFiles, ctx.changes
95
+ );
96
+ const authReplaced = applyAuthMethod(ctx);
97
+ updated = updated || authReplaced;
98
+ const systemAuthConfigNormalized = normalizeSystemFileAuthAndConfig(
99
+ ctx.systemParsed, ctx.systemKey, ctx.changes
100
+ );
101
+ const systemDataSourcesAligned = alignSystemFileDataSources(
102
+ ctx.appPath, ctx.systemParsed, ctx.datasourceFiles, ctx.systemKey, ctx.dryRun, ctx.changes
103
+ );
104
+ const authVarsRemoved = removeAuthVarsFromConfiguration(
105
+ ctx.systemParsed, ctx.systemKey, ctx.dryRun, ctx.changes
106
+ );
107
+ const systemFileUpdated = persistSystemFileRepair(ctx, {
108
+ authReplaced,
109
+ systemAuthConfigNormalized,
110
+ systemDataSourcesAligned,
111
+ authVarsRemoved
112
+ });
113
+ updated = updated || systemFileUpdated;
114
+ const appKeyFixed = alignAppKeyWithSystem(
115
+ ctx.variables, ctx.systemKey, ctx.systemParsed, ctx.changes
116
+ );
117
+ const datasourceKeysFixed = alignDatasourceSystemKeys(
118
+ ctx.appPath, ctx.datasourceFiles, ctx.systemKey, ctx.dryRun, ctx.changes, bc
119
+ );
120
+ const rbacFileCreated = createRbacFromSystemIfNeeded({
121
+ appPath: ctx.appPath,
122
+ systemFilePath: ctx.systemFilePath,
123
+ systemParsed: ctx.systemParsed,
124
+ dryRun: ctx.dryRun,
125
+ changes: ctx.changes,
126
+ format: ctx.format,
127
+ backupCtx: bc
128
+ });
129
+ const envTemplateRepaired = repairEnvTemplate(
130
+ ctx.appPath, ctx.systemParsed, ctx.systemKey, ctx.dryRun, ctx.changes, bc
131
+ );
132
+ updated = updated || appKeyFixed || datasourceKeysFixed || rbacFileCreated || envTemplateRepaired;
133
+ auditRepairAuthenticationWarnings(ctx.systemParsed, ctx.warnings);
134
+ return {
135
+ updated,
136
+ appKeyFixed,
137
+ datasourceKeysFixed,
138
+ rbacFileCreated,
139
+ envTemplateRepaired
140
+ };
141
+ }
142
+
143
+ module.exports = {
144
+ runRepairSteps
145
+ };
@@ -12,197 +12,13 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- const path = require('path');
16
15
  const fs = require('fs');
17
- const chalk = require('chalk');
18
16
  const { detectAppType } = require('../utils/paths');
19
- const { resolveApplicationConfigPath, resolveRbacPath } = require('../utils/app-config-resolver');
20
- const { loadConfigFile, writeConfigFile, isYamlPath } = require('../utils/config-format');
21
- const logger = require('../utils/logger');
22
- const { repairEnvTemplate, normalizeSystemFileAuthAndConfig } = require('./repair-env-template');
23
- const { repairDatasourceFile } = require('./repair-datasource');
24
- const { mergeRbacFromDatasources, extractRbacFromSystem, migrateSystemRbacIntoRbacFile } = require('./repair-rbac');
17
+ const { resolveApplicationConfigPath } = require('../utils/app-config-resolver');
18
+ const { loadConfigFile, isYamlPath } = require('../utils/config-format');
25
19
  const { discoverIntegrationFiles, buildEffectiveDatasourceFiles } = require('./repair-internal');
26
- const { normalizeDatasourceKeysAndFilenames } = require('./repair-datasource-keys');
27
- const { backupIntegrationFile } = require('../utils/integration-file-backup');
28
- const { maybeSyncOpenApiFilesForMcp } = require('./repair-openapi-sync');
29
- const {
30
- alignAppKeyWithSystem,
31
- alignDatasourceSystemKeys,
32
- alignSystemFileDataSources,
33
- ensureExternalIntegrationBlock,
34
- removeAuthVarsFromConfiguration,
35
- resolveSystemContext
36
- } = require('./repair-system-alignment');
37
- const { persistChangesAndRegenerate, regenerateReadmeIfRequested } = require('./repair-persist');
20
+ const { runRepairExternalIntegration } = require('./repair-external-run');
38
21
 
39
- /** Allowed authentication methods for repair --auth (matches external-system schema) */
40
- const ALLOWED_AUTH = ['oauth2', 'aad', 'apikey', 'basic', 'queryParam', 'oidc', 'hmac', 'none'];
41
-
42
- function createRbacFromSystemIfNeeded(opts) {
43
- const { appPath, systemFilePath, systemParsed, dryRun, changes, format, backupCtx } = opts;
44
- if (resolveRbacPath(appPath)) return false;
45
- const rbacFromSystem = extractRbacFromSystem(systemParsed);
46
- if (!rbacFromSystem) return false;
47
- if (!dryRun) {
48
- const rbacFormat = format === 'json' ? 'json' : 'yaml';
49
- const defaultRbacPath = path.join(appPath, rbacFormat === 'json' ? 'rbac.json' : 'rbac.yaml');
50
- writeConfigFile(defaultRbacPath, rbacFromSystem, rbacFormat);
51
- delete systemParsed.roles;
52
- delete systemParsed.permissions;
53
- backupIntegrationFile(systemFilePath, backupCtx);
54
- writeConfigFile(systemFilePath, systemParsed);
55
- }
56
- changes.push('Created rbac.yaml from system roles/permissions');
57
- changes.push('Removed roles/permissions from system file (now in rbac file)');
58
- return true;
59
- }
60
-
61
- /**
62
- * Runs datasource repair for each file (v2.4 root dimensions, metadataSchema; optional expose/sync/test).
63
- * @param {string} appPath - Application path
64
- * @param {string[]} datasourceFiles - Datasource file names
65
- * @param {Object} options - { expose?: boolean, sync?: boolean, test?: boolean }
66
- * @param {boolean} dryRun - If true, do not write
67
- * @param {string[]} changes - Array to append change descriptions to
68
- * @returns {boolean} True if any datasource was updated
69
- */
70
- function runDatasourceRepairs(appPath, datasourceFiles, options, dryRun, changes) {
71
- if (!datasourceFiles || datasourceFiles.length === 0) return false;
72
- let updated = false;
73
- for (const fileName of datasourceFiles) {
74
- const filePath = path.join(appPath, fileName);
75
- if (!fs.existsSync(filePath)) continue;
76
- try {
77
- const parsed = loadConfigFile(filePath);
78
- const { updated: fileUpdated, changes: fileChanges } = repairDatasourceFile(parsed, {
79
- expose: options.expose,
80
- sync: options.sync,
81
- test: options.test
82
- });
83
- if (fileUpdated) {
84
- updated = true;
85
- fileChanges.forEach(c => changes.push(`${fileName}: ${c}`));
86
- if (!dryRun) {
87
- backupIntegrationFile(filePath, options.backupCtx);
88
- writeConfigFile(filePath, parsed);
89
- }
90
- }
91
- } catch (err) {
92
- logger.log(chalk.yellow(`⚠ Could not repair datasource ${fileName}: ${err.message}`));
93
- }
94
- }
95
- return updated;
96
- }
97
-
98
- function maybeRepairRbac(appPath, systemFilePath, systemParsed, datasourceFiles, options) {
99
- if (!options.rbac) return { rbacMigratedFromSystem: false, rbacMergeUpdated: false };
100
- const { dryRun, changes, backupCtx, rbacFmt } = options;
101
- const rbacMigratedFromSystem = migrateSystemRbacIntoRbacFile(appPath, systemFilePath, systemParsed, { dryRun, changes, backupCtx });
102
- const rbacMergeUpdated = mergeRbacFromDatasources(appPath, systemParsed, datasourceFiles, extractRbacFromSystem, {
103
- format: rbacFmt,
104
- dryRun,
105
- changes,
106
- backupCtx
107
- });
108
- return { rbacMigratedFromSystem, rbacMergeUpdated };
109
- }
110
-
111
- /**
112
- * Apply --auth: replace system file authentication with canonical block for the given method.
113
- * Preserves existing authentication.variables (e.g. baseUrl, tokenUrl) from the current system file.
114
- * @param {Object} ctx - Context with systemParsed, systemKey, auth, dryRun, changes
115
- * @returns {boolean} True if auth was replaced
116
- */
117
- function applyAuthMethod(ctx) {
118
- if (!ctx.auth || typeof ctx.auth !== 'string') return false;
119
- const method = ctx.auth.trim().toLowerCase();
120
- if (!ALLOWED_AUTH.includes(method)) {
121
- throw new Error(
122
- `Invalid --auth "${ctx.auth}". Allowed methods: ${ALLOWED_AUTH.join(', ')}`
123
- );
124
- }
125
- const existingAuth = ctx.systemParsed.authentication || ctx.systemParsed.auth || {};
126
- const { buildAuthenticationFromMethod } = require('../external-system/generator');
127
- const newAuth = buildAuthenticationFromMethod(ctx.systemKey, method);
128
- const existingVars = existingAuth.variables && typeof existingAuth.variables === 'object' ? existingAuth.variables : {};
129
- const mergedVariables = { ...newAuth.variables, ...existingVars };
130
- ctx.systemParsed.authentication = {
131
- ...newAuth,
132
- variables: Object.keys(mergedVariables).length ? mergedVariables : newAuth.variables
133
- };
134
- if (existingAuth.displayName !== undefined) {
135
- ctx.systemParsed.authentication.displayName = existingAuth.displayName;
136
- }
137
- ctx.changes.push(`Set authentication method to ${method}`);
138
- return true;
139
- }
140
-
141
- /**
142
- * Runs all repair steps (integration block, system dataSources, auth/config, app key, datasource keys, rbac, env.template).
143
- * @param {Object} ctx - Context with appPath, configPath, variables, systemFilePath, systemParsed, systemKey, systemFiles, datasourceFiles, dryRun, changes, auth?, backupCtx?
144
- * @returns {{ updated: boolean, appKeyFixed: boolean, datasourceKeysFixed: boolean, rbacFileCreated: boolean, envTemplateRepaired: boolean }}
145
- */
146
- function runRepairSteps(ctx) {
147
- const bc = ctx.backupCtx;
148
- let updated = ensureExternalIntegrationBlock(
149
- ctx.variables, ctx.systemFiles, ctx.datasourceFiles, ctx.changes
150
- );
151
- const authReplaced = applyAuthMethod(ctx);
152
- updated = updated || authReplaced;
153
- const systemAuthConfigNormalized = normalizeSystemFileAuthAndConfig(
154
- ctx.systemParsed, ctx.systemKey, ctx.changes
155
- );
156
- const systemDataSourcesAligned = alignSystemFileDataSources(
157
- ctx.appPath, ctx.systemParsed, ctx.datasourceFiles, ctx.systemKey, ctx.dryRun, ctx.changes
158
- );
159
- const authVarsRemoved = removeAuthVarsFromConfiguration(
160
- ctx.systemParsed, ctx.systemKey, ctx.dryRun, ctx.changes
161
- );
162
- const systemFileUpdated =
163
- authReplaced || systemAuthConfigNormalized || systemDataSourcesAligned || authVarsRemoved;
164
- if (systemFileUpdated && !ctx.dryRun) {
165
- backupIntegrationFile(ctx.systemFilePath, bc);
166
- writeConfigFile(ctx.systemFilePath, ctx.systemParsed);
167
- }
168
- updated = updated || systemFileUpdated;
169
- const appKeyFixed = alignAppKeyWithSystem(
170
- ctx.variables, ctx.systemKey, ctx.systemParsed, ctx.changes
171
- );
172
- const datasourceKeysFixed = alignDatasourceSystemKeys(
173
- ctx.appPath, ctx.datasourceFiles, ctx.systemKey, ctx.dryRun, ctx.changes, bc
174
- );
175
- const rbacFileCreated = createRbacFromSystemIfNeeded({
176
- appPath: ctx.appPath,
177
- systemFilePath: ctx.systemFilePath,
178
- systemParsed: ctx.systemParsed,
179
- dryRun: ctx.dryRun,
180
- changes: ctx.changes,
181
- format: ctx.format,
182
- backupCtx: bc
183
- });
184
- const envTemplateRepaired = repairEnvTemplate(
185
- ctx.appPath, ctx.systemParsed, ctx.systemKey, ctx.dryRun, ctx.changes, bc
186
- );
187
- updated = updated || appKeyFixed || datasourceKeysFixed || rbacFileCreated || envTemplateRepaired;
188
- return {
189
- updated,
190
- appKeyFixed,
191
- datasourceKeysFixed,
192
- rbacFileCreated,
193
- envTemplateRepaired
194
- };
195
- }
196
-
197
- /**
198
- * Repairs external integration config: syncs files, aligns keys, creates rbac, regenerates manifest
199
- * @async
200
- * @param {string} appName - Application/integration name
201
- * @param {Object} [options] - Options
202
- * @param {boolean} [options.dryRun] - If true, only report changes; do not write
203
- * @param {boolean} [options.doc] - If true, regenerate README.md from deployment manifest
204
- * @returns {Promise<{ updated: boolean, changes: string[], systemFiles: string[], datasourceFiles: string[], appKeyFixed?: boolean, datasourceKeysFixed?: boolean, rbacFileCreated?: boolean, envTemplateRepaired?: boolean, manifestRegenerated?: boolean, readmeRegenerated?: boolean }>}
205
- */
206
22
  /**
207
23
  * Loads application config and discovers integration files; validates at least one system file exists.
208
24
  * @param {string} appPath - Application path
@@ -216,43 +32,13 @@ function loadConfigAndDiscover(appPath, configPath) {
216
32
  originalYamlContent = fs.readFileSync(configPath, 'utf8');
217
33
  }
218
34
  const { systemFiles, datasourceFiles: discoveredDatasourceFiles } = discoverIntegrationFiles(appPath);
219
- if (systemFiles.length === 0) {
35
+ if (!systemFiles || systemFiles.length === 0) {
220
36
  throw new Error(`No system file found in ${appPath}. Expected *-system.yaml or *-system.json`);
221
37
  }
222
38
  const datasourceFiles = buildEffectiveDatasourceFiles(appPath, discoveredDatasourceFiles, variables.externalIntegration?.dataSources);
223
39
  return { variables, originalYamlContent, systemFiles, datasourceFiles };
224
40
  }
225
41
 
226
- /**
227
- * Builds the repair result object from steps and flags.
228
- * @param {Object} steps - Result of runRepairSteps
229
- * @param {boolean} anyUpdated - Whether any repair made changes
230
- * @param {boolean} manifestRegenerated - Whether manifest was regenerated
231
- * @param {boolean} readmeRegenerated - Whether README was regenerated
232
- * @param {{ changes: string[], systemFiles: string[], datasourceFiles: string[] }} ctx - changes and file lists
233
- * @returns {Object} Combined result object
234
- */
235
- function buildRepairResult(steps, anyUpdated, manifestRegenerated, readmeRegenerated, ctx) {
236
- return Object.assign(
237
- {
238
- updated: anyUpdated,
239
- actionsPerformed: ctx.actionsPerformed === true,
240
- changes: ctx.changes,
241
- systemFiles: ctx.systemFiles,
242
- datasourceFiles: ctx.datasourceFiles,
243
- backupPaths: ctx.backupPaths || []
244
- },
245
- {
246
- appKeyFixed: steps.appKeyFixed,
247
- datasourceKeysFixed: steps.datasourceKeysFixed,
248
- rbacFileCreated: steps.rbacFileCreated,
249
- envTemplateRepaired: steps.envTemplateRepaired,
250
- manifestRegenerated,
251
- readmeRegenerated
252
- }
253
- );
254
- }
255
-
256
42
  /**
257
43
  * Validates repair inputs and resolves app path and config path.
258
44
  * @param {string} appName - Application name
@@ -281,83 +67,40 @@ function createRepairBackupContext(options, dryRun) {
281
67
  const noBackup = options.noBackup === true || options.backup === false;
282
68
  const backupPaths = [];
283
69
  const backedUpFiles = new Set();
284
- const backupCtx = { dryRun, noBackup, backupPaths, backedUpFiles };
70
+ const backupCtx = {
71
+ dryRun,
72
+ noBackup,
73
+ backupPaths,
74
+ backedUpFiles,
75
+ changedFiles: [],
76
+ wouldChangeFiles: []
77
+ };
285
78
  return { backupPaths, backupCtx };
286
79
  }
287
80
 
288
- async function maybeRunOpenApiSyncForMcp({ options, dryRun, appPath, systemKey, datasourceFiles, changes }) {
289
- if (!options.api) return false;
290
- try {
291
- const openapiLines = await maybeSyncOpenApiFilesForMcp({
292
- enabled: true,
293
- dryRun,
294
- appPath,
295
- systemKey,
296
- datasourceFiles
297
- });
298
- openapiLines.forEach((l) => changes.push(l));
299
- return openapiLines.length > 0;
300
- } catch (err) {
301
- changes.push(`OpenAPI upload for MCP failed: ${err.message}`);
302
- return false;
303
- }
304
- }
305
-
81
+ /**
82
+ * Repairs external integration config: syncs files, aligns keys, creates rbac, regenerates manifest
83
+ * @async
84
+ * @param {string} appName - Application/integration name
85
+ * @param {Object} [options] - Options
86
+ * @param {boolean} [options.dryRun] - If true, only report changes; do not write
87
+ * @param {boolean} [options.doc] - If true, regenerate README.md from deployment manifest
88
+ * @returns {Promise<Object>}
89
+ */
306
90
  async function repairExternalIntegration(appName, options = {}) {
307
91
  const { appPath, configPath, dryRun, authOption } = await validateAndResolveRepairPaths(appName, options);
308
92
  const { backupPaths, backupCtx } = createRepairBackupContext(options, dryRun);
309
- const { variables, originalYamlContent, systemFiles, datasourceFiles: initialDatasourceFiles } = loadConfigAndDiscover(appPath, configPath);
310
- const changes = [];
311
- const { systemFilePath, systemParsed, systemKey } = resolveSystemContext(appPath, systemFiles);
312
- const rbacFmt = options.format === 'json' ? 'json' : 'yaml';
313
- const { updated: keysNormalized, datasourceFiles } = normalizeDatasourceKeysAndFilenames(appPath, initialDatasourceFiles, systemKey, { variables, dryRun, changes, backupCtx });
314
- const steps = runRepairSteps({
93
+ const loaded = loadConfigAndDiscover(appPath, configPath);
94
+ return runRepairExternalIntegration({
95
+ appName,
96
+ options,
315
97
  appPath,
316
98
  configPath,
317
- variables,
318
- systemFilePath,
319
- systemParsed,
320
- systemKey,
321
- systemFiles,
322
- datasourceFiles,
323
- dryRun,
324
- changes,
325
- auth: authOption,
326
- format: rbacFmt,
327
- backupCtx
328
- });
329
- const datasourceRepairUpdated = runDatasourceRepairs(appPath, datasourceFiles, {
330
- expose: Boolean(options.expose),
331
- sync: Boolean(options.sync),
332
- test: Boolean(options.test),
333
- backupCtx
334
- }, dryRun, changes);
335
- const openapiActionsPerformed = await maybeRunOpenApiSyncForMcp({
336
- options,
337
99
  dryRun,
338
- appPath,
339
- systemKey,
340
- datasourceFiles,
341
- changes
342
- });
343
- const { rbacMigratedFromSystem, rbacMergeUpdated } = maybeRepairRbac(
344
- appPath,
345
- systemFilePath,
346
- systemParsed,
347
- datasourceFiles,
348
- { rbac: Boolean(options.rbac), rbacFmt, dryRun, changes, backupCtx }
349
- );
350
- const anyLocalUpdated = keysNormalized || steps.updated || datasourceRepairUpdated || rbacMigratedFromSystem || rbacMergeUpdated;
351
- const manifestRegenerated = (anyLocalUpdated && !dryRun) ? await persistChangesAndRegenerate(
352
- { configPath, variables, appName, appPath, changes, originalYamlContent, backupCtx }
353
- ) : false;
354
- const readmeRegenerated = await regenerateReadmeIfRequested(appName, appPath, { ...options, backupCtx }, changes);
355
- return buildRepairResult(steps, anyLocalUpdated, manifestRegenerated, readmeRegenerated, {
356
- actionsPerformed: openapiActionsPerformed,
357
- changes,
358
- systemFiles,
359
- datasourceFiles,
360
- backupPaths
100
+ authOption,
101
+ backupPaths,
102
+ backupCtx,
103
+ ...loaded
361
104
  });
362
105
  }
363
106