@aifabrix/builder 2.45.5 → 2.47.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 (355) 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/project-rules.mdc +1 -0
  4. package/.npmrc.token +1 -0
  5. package/.temp/jest-protection-convert/run-IFN2nv/.protection/hubspot-companies.json +1 -0
  6. package/.temp/jest-protection-convert/run-IvmKLO/.protection/hubspot-companies.yaml +17 -0
  7. package/.temp/jest-protection-convert/run-SdvblF/.protection/hubspot-companies.json +1 -0
  8. package/.temp/jest-protection-convert/run-b51TsW/.protection/hubspot-companies.json +1 -0
  9. package/.temp/jest-protection-convert/run-fiLmb1/.protection/hubspot-companies.json +1 -0
  10. package/.temp/jest-protection-convert/run-qYGHMU/.protection/hubspot-companies.yaml +17 -0
  11. package/.temp/jest-protection-fixtures/hubspot-Mq5re8/hubspot-companies.yaml +17 -0
  12. package/.temp/jest-protection-fixtures/hubspot-f3u4YL/hubspot-companies.yaml +17 -0
  13. package/.temp/jest-protection-fixtures/hubspot-iQtd1O/hubspot-companies.yaml +17 -0
  14. package/.temp/jest-protection-fixtures/hubspot-mdmz5M/hubspot-companies.yaml +17 -0
  15. package/.temp/jest-protection-fixtures/hubspot-qbKYxQ/hubspot-companies.yaml +17 -0
  16. package/.temp/jest-protection-fixtures/hubspot-yzlJy6/hubspot-companies.yaml +17 -0
  17. package/.temp/validation/summary.txt +5 -0
  18. package/README.md +43 -17
  19. package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +1 -1
  20. package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.yaml +1 -1
  21. package/jest.config.default.js +2 -1
  22. package/jest.config.isolated.js +2 -1
  23. package/jest.global-live-fabrix-hooks.js +36 -0
  24. package/jest.isolated-projects.js +146 -0
  25. package/jest.projects.js +65 -136
  26. package/lib/api/api-response-errors.js +124 -0
  27. package/lib/api/dataplane-health.api.js +19 -7
  28. package/lib/api/governance-scenario-pack.api.js +159 -0
  29. package/lib/api/index.js +43 -3
  30. package/lib/api/lifecycle.api.js +98 -0
  31. package/lib/api/pipeline.api.js +3 -1
  32. package/lib/api/records-bulk.api.js +14 -1
  33. package/lib/api/resource-types.api.js +107 -0
  34. package/lib/api/runtime-configuration.api.js +72 -0
  35. package/lib/api/types/resource-types.types.js +45 -0
  36. package/lib/api/user-groups.api.js +9 -9
  37. package/lib/api/users.api.js +8 -8
  38. package/lib/api/validation-runner.js +3 -1
  39. package/lib/api/wizard.api.js +10 -2
  40. package/lib/app/deploy-config.js +4 -1
  41. package/lib/app/down.js +78 -27
  42. package/lib/app/index.js +2 -2
  43. package/lib/app/push.js +4 -5
  44. package/lib/app/register.js +7 -4
  45. package/lib/app/run-env-compose.js +84 -30
  46. package/lib/app/run-resolve-image.js +2 -1
  47. package/lib/app/run-stop-containers.js +113 -0
  48. package/lib/app/run.js +1 -31
  49. package/lib/app/show-display.js +35 -0
  50. package/lib/app/show.js +32 -1
  51. package/lib/build/index.js +22 -5
  52. package/lib/build/miso-controller-npm-sdk-guard.js +25 -0
  53. package/lib/certification/sync-system-certification.js +13 -6
  54. package/lib/channels/add-channel.js +348 -0
  55. package/lib/channels/channel-artifact-generator.js +141 -0
  56. package/lib/channels/channel-audit.js +101 -0
  57. package/lib/channels/channel-auth-context.js +37 -0
  58. package/lib/channels/channel-credential.js +200 -0
  59. package/lib/channels/channel-display-name.js +64 -0
  60. package/lib/channels/channel-external-system.js +106 -0
  61. package/lib/channels/channel-integration-generator.js +274 -0
  62. package/lib/channels/channel-probe.js +89 -0
  63. package/lib/channels/channel-runtime-resolver.js +152 -0
  64. package/lib/channels/channel-status-display.js +141 -0
  65. package/lib/channels/channel-targets.js +115 -0
  66. package/lib/cli/index.js +20 -4
  67. package/lib/cli/infra-guided-auth.js +109 -0
  68. package/lib/cli/infra-guided.js +84 -81
  69. package/lib/cli/setup-app.help.js +0 -31
  70. package/lib/cli/setup-app.js +82 -5
  71. package/lib/cli/setup-app.test-commands.js +5 -57
  72. package/lib/cli/setup-auth.js +25 -0
  73. package/lib/cli/setup-certification-commands.js +147 -0
  74. package/lib/cli/setup-certification.help.js +141 -0
  75. package/lib/cli/setup-environment.js +19 -2
  76. package/lib/cli/setup-external-system-help.js +62 -0
  77. package/lib/cli/setup-external-system.js +25 -3
  78. package/lib/cli/setup-infra-up-dataplane-action.js +2 -2
  79. package/lib/cli/setup-infra-up-platform-action.js +2 -1
  80. package/lib/cli/setup-infra.js +9 -1
  81. package/lib/cli/setup-platform.js +6 -1
  82. package/lib/cli/setup-secrets.js +33 -1
  83. package/lib/cli/setup-utility-help-after.js +25 -2
  84. package/lib/cli/setup-utility-repair.js +198 -0
  85. package/lib/cli/setup-utility-resolve.js +44 -5
  86. package/lib/cli/setup-utility-validate.js +197 -0
  87. package/lib/cli/setup-utility.js +4 -239
  88. package/lib/commands/app-logs.js +54 -26
  89. package/lib/commands/app.js +41 -0
  90. package/lib/commands/auth-status-client-tokens.js +214 -0
  91. package/lib/commands/auth-status-dataplane-version.js +142 -68
  92. package/lib/commands/auth-status.js +43 -54
  93. package/lib/commands/channel.js +58 -0
  94. package/lib/commands/datasource-test-trust-cli.js +27 -23
  95. package/lib/commands/datasource-unified-test-cli.js +6 -3
  96. package/lib/commands/datasource-unified-test-cli.options.js +5 -1
  97. package/lib/commands/datasource.js +8 -8
  98. package/lib/commands/dev-show-display.js +8 -1
  99. package/lib/commands/governance-cli-shared.js +94 -0
  100. package/lib/commands/governance-command-action.js +132 -0
  101. package/lib/commands/governance-download-external.js +34 -0
  102. package/lib/commands/governance-generate-external.js +71 -0
  103. package/lib/commands/governance-upload-external.js +36 -0
  104. package/lib/commands/governance-verify-external.js +64 -0
  105. package/lib/commands/governance.js +144 -0
  106. package/lib/commands/identity-apply-sync.js +49 -8
  107. package/lib/commands/identity-group-cli.js +66 -26
  108. package/lib/commands/identity-membership-role-cache.js +58 -37
  109. package/lib/commands/identity-shared.js +22 -1
  110. package/lib/commands/identity-user-cli.js +80 -34
  111. package/lib/commands/lifecycle-command-action.js +123 -0
  112. package/lib/commands/lifecycle-external.js +268 -0
  113. package/lib/commands/login.js +11 -2
  114. package/lib/commands/repair-auth-apply.js +153 -0
  115. package/lib/commands/repair-auth-config.js +8 -13
  116. package/lib/commands/repair-changed-files.js +41 -0
  117. package/lib/commands/repair-datasource-com-v2.js +15 -0
  118. package/lib/commands/repair-datasource-keys.js +4 -1
  119. package/lib/commands/repair-datasource-run.js +59 -0
  120. package/lib/commands/repair-datasource-service-contract.js +206 -0
  121. package/lib/commands/repair-datasource-test-payload.js +259 -0
  122. package/lib/commands/repair-datasource.js +49 -64
  123. package/lib/commands/repair-env-template.js +76 -25
  124. package/lib/commands/repair-external-run.js +216 -0
  125. package/lib/commands/repair-openapi-sync.js +49 -4
  126. package/lib/commands/repair-persist.js +4 -0
  127. package/lib/commands/repair-rbac.js +52 -1
  128. package/lib/commands/repair-steps.js +160 -0
  129. package/lib/commands/repair-system-alignment.js +7 -4
  130. package/lib/commands/repair.js +29 -296
  131. package/lib/commands/resource-type.js +371 -0
  132. package/lib/commands/secrets-get.js +184 -0
  133. package/lib/commands/secrets-remove-all.js +3 -1
  134. package/lib/commands/setup-image-refresh.js +146 -0
  135. package/lib/commands/setup-modes.js +158 -162
  136. package/lib/commands/setup-platform-auth.js +76 -0
  137. package/lib/commands/setup-prompts-admin.js +244 -0
  138. package/lib/commands/setup-prompts-platform-mode.js +70 -0
  139. package/lib/commands/setup-prompts-validators.js +36 -0
  140. package/lib/commands/setup-prompts.js +24 -76
  141. package/lib/commands/setup-run-context.js +45 -0
  142. package/lib/commands/setup-spinners.js +39 -0
  143. package/lib/commands/setup.js +27 -5
  144. package/lib/commands/teardown.js +39 -0
  145. package/lib/commands/test-e2e-external.js +24 -8
  146. package/lib/commands/test-governance-external.js +3 -24
  147. package/lib/commands/test-trust-external.js +48 -100
  148. package/lib/commands/up-common.js +57 -13
  149. package/lib/commands/up-dataplane.js +56 -15
  150. package/lib/commands/upload-publish-context.js +75 -0
  151. package/lib/commands/upload-sidecar-followups.js +89 -0
  152. package/lib/commands/upload.js +113 -110
  153. package/lib/commands/verify-governance-combined-external.js +61 -0
  154. package/lib/commands/verify-governance-command-action.js +64 -0
  155. package/lib/commands/verify-governance-db.js +102 -0
  156. package/lib/commands/verify-governance-external.js +77 -0
  157. package/lib/commands/verify-governance-result-builders.js +71 -0
  158. package/lib/commands/verify-operations-command-action.js +68 -0
  159. package/lib/commands/verify-operations-external.js +268 -0
  160. package/lib/commands/verify-operations-persist.js +75 -0
  161. package/lib/commands/verify-operations-step-plan.js +68 -0
  162. package/lib/commands/verify-operations-steps.js +111 -0
  163. package/lib/commands/verify-trust-command-action.js +73 -0
  164. package/lib/commands/verify-trust-external.js +59 -0
  165. package/lib/commands/wizard-config-normalizer.js +43 -23
  166. package/lib/commands/wizard-core.js +2 -0
  167. package/lib/core/admin-password-generator.js +38 -0
  168. package/lib/core/admin-secrets-bundle.js +111 -0
  169. package/lib/core/admin-secrets-env-overlay.js +62 -0
  170. package/lib/core/admin-secrets.js +32 -4
  171. package/lib/core/config-attach-extensions.js +3 -0
  172. package/lib/core/config-platform-controller.js +44 -0
  173. package/lib/core/config-setup-installation-profile.js +42 -0
  174. package/lib/core/config-setup-platform-mode.js +46 -0
  175. package/lib/core/config.js +46 -36
  176. package/lib/core/secrets-admin-env.js +6 -2
  177. package/lib/core/secrets-ensure.js +4 -0
  178. package/lib/core/secrets-env-content.js +54 -48
  179. package/lib/core/secrets-env-write.js +10 -1
  180. package/lib/core/secrets-infra-placeholder-sync.js +2 -0
  181. package/lib/core/setup-installation-profile.js +43 -0
  182. package/lib/core/setup-platform-mode.js +90 -0
  183. package/lib/datasource/agent-trust-debug-log.js +1 -1
  184. package/lib/datasource/agent-trust-run.js +5 -3
  185. package/lib/datasource/audit-evidence-extract-debug.js +30 -18
  186. package/lib/datasource/audit-evidence-extract.js +7 -4
  187. package/lib/datasource/audit-evidence-verify-matrix.js +54 -26
  188. package/lib/datasource/bulk-loader-run-batches.js +15 -3
  189. package/lib/datasource/capability/capability-diff-slice.js +2 -2
  190. package/lib/datasource/capability/capability-manifest.js +254 -0
  191. package/lib/datasource/capability/capability-resolve.js +3 -4
  192. package/lib/datasource/capability/copy-operations.js +5 -3
  193. package/lib/datasource/capability/remove-operations.js +2 -1
  194. package/lib/datasource/capability/run-capability-copy.js +32 -4
  195. package/lib/datasource/capability/run-capability-diff.js +3 -3
  196. package/lib/datasource/capability/run-capability-dimension.js +2 -4
  197. package/lib/datasource/capability/run-capability-edit.js +4 -7
  198. package/lib/datasource/capability/run-capability-relate.js +2 -4
  199. package/lib/datasource/capability/run-capability-remove.js +2 -4
  200. package/lib/datasource/capability/validate-capability-slice.js +2 -1
  201. package/lib/datasource/datasource-identifier.js +2 -1
  202. package/lib/datasource/datasource-load-export-context.js +3 -0
  203. package/lib/datasource/datasource-validate-display.js +1 -1
  204. package/lib/datasource/field-reference-validator.js +24 -3
  205. package/lib/datasource/log-cleaner.js +2 -2
  206. package/lib/datasource/log-viewer.js +8 -8
  207. package/lib/datasource/orphan-profiles-validator.js +98 -0
  208. package/lib/datasource/test-e2e.js +4 -1
  209. package/lib/datasource/unified-validation-run-body.js +3 -1
  210. package/lib/datasource/unified-validation-run.js +5 -2
  211. package/lib/datasource/validate.js +41 -23
  212. package/lib/deployment/environment-poll-status.js +138 -0
  213. package/lib/deployment/environment.js +42 -34
  214. package/lib/external-system/download-helpers.js +87 -0
  215. package/lib/external-system/download.js +78 -138
  216. package/lib/external-system/generator.js +1 -55
  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.js +16 -21
  220. package/lib/generator/builders.js +11 -1
  221. package/lib/generator/external-controller-manifest.js +18 -0
  222. package/lib/generator/split.js +3 -1
  223. package/lib/generator/wizard.js +1 -28
  224. package/lib/governance/governance-cli-errors.js +96 -0
  225. package/lib/governance/governance-download-display.js +38 -0
  226. package/lib/governance/governance-run-display.js +215 -25
  227. package/lib/identity/fk-reference.js +65 -0
  228. package/lib/identity/identity-apply-core.js +13 -58
  229. package/lib/identity/identity-apply-phases.js +5 -1
  230. package/lib/identity/identity-display.js +243 -0
  231. package/lib/identity/identity-response-helpers.js +52 -0
  232. package/lib/identity/identity-sync-errors.js +62 -0
  233. package/lib/identity/resolve-user-id.js +129 -0
  234. package/lib/identity/username-default.js +31 -0
  235. package/lib/infrastructure/admin-secrets-apply.js +84 -0
  236. package/lib/infrastructure/admin-secrets-ensure.js +130 -0
  237. package/lib/infrastructure/admin-secrets-resolve.js +95 -0
  238. package/lib/infrastructure/admin-secrets-sync.js +91 -0
  239. package/lib/infrastructure/helpers.js +23 -129
  240. package/lib/infrastructure/index.js +5 -6
  241. package/lib/infrastructure/orphan-infra-docker-teardown.js +11 -5
  242. package/lib/lifecycle/certification-progress.js +231 -0
  243. package/lib/lifecycle/dataplane-ui-url.js +145 -0
  244. package/lib/lifecycle/exit-codes.js +24 -0
  245. package/lib/lifecycle/json-envelope.js +25 -0
  246. package/lib/lifecycle/lifecycle-governance-options.js +51 -0
  247. package/lib/lifecycle/logger-quiet.js +29 -0
  248. package/lib/lifecycle/open-api-published.js +59 -0
  249. package/lib/lifecycle/operations-readiness-metrics.js +101 -0
  250. package/lib/lifecycle/product-model.js +196 -0
  251. package/lib/lifecycle/report-display-trust.js +70 -0
  252. package/lib/lifecycle/report-display.js +472 -0
  253. package/lib/lifecycle/scenario-upload.js +191 -0
  254. package/lib/lifecycle/verify-step-progress.js +87 -0
  255. package/lib/parameters/infra-kv-discovery.js +27 -2
  256. package/lib/protection/auth-context.js +10 -4
  257. package/lib/resolvers/datasource-resolver.js +2 -3
  258. package/lib/resolvers/resource-type-file.js +159 -0
  259. package/lib/schema/application-schema.json +17 -1
  260. package/lib/schema/datasource-test-run.schema.json +89 -6
  261. package/lib/schema/deployment-rules.yaml +2 -1
  262. package/lib/schema/external-datasource.schema.json +2947 -2619
  263. package/lib/schema/external-system.schema.json +1418 -761
  264. package/lib/schema/infra.parameter.yaml +45 -0
  265. package/lib/schema/type/credential-field-registry.json +103 -97
  266. package/lib/schema/type/document-storage.json +9 -5
  267. package/lib/utils/aifabrix-test-runtime-guard.js +125 -0
  268. package/lib/utils/api.js +55 -31
  269. package/lib/utils/app-relative-path-env.js +112 -0
  270. package/lib/utils/app-run-containers.js +25 -2
  271. package/lib/utils/authentication-shape.js +224 -0
  272. package/lib/utils/build-copy.js +36 -5
  273. package/lib/utils/build-resolve-image.js +66 -12
  274. package/lib/utils/celery-companion-apps.js +53 -0
  275. package/lib/utils/cli-secrets-error-format.js +83 -21
  276. package/lib/utils/cli-utils.js +20 -4
  277. package/lib/utils/compose-celery-worker.js +23 -0
  278. package/lib/utils/compose-generate-docker-compose.js +13 -1
  279. package/lib/utils/compose-traefik-ingress-base.js +16 -1
  280. package/lib/utils/config-secrets-path.js +46 -0
  281. package/lib/utils/configuration-env-resolver.js +36 -0
  282. package/lib/utils/controller-url.js +88 -1
  283. package/lib/utils/credential-secrets-env-kv.js +216 -0
  284. package/lib/utils/credential-secrets-env.js +175 -257
  285. package/lib/utils/dataplane-resolver.js +18 -2
  286. package/lib/utils/declarative-url-ports.js +27 -4
  287. package/lib/utils/deployment-auth-mode.js +41 -0
  288. package/lib/utils/developer-volume-id.js +33 -0
  289. package/lib/utils/docker-build.js +1 -4
  290. package/lib/utils/env-copy.js +14 -9
  291. package/lib/utils/env-kv-orphan-lines.js +43 -0
  292. package/lib/utils/error-formatters/network-errors.js +13 -4
  293. package/lib/utils/external-env-template.js +11 -3
  294. package/lib/utils/external-system-readiness-core.js +10 -0
  295. package/lib/utils/external-system-readiness-display.js +80 -23
  296. package/lib/utils/external-system-validators.js +8 -2
  297. package/lib/utils/health-check.js +4 -1
  298. package/lib/utils/help-builder.js +13 -8
  299. package/lib/utils/keycloak-realm-ready.js +101 -0
  300. package/lib/utils/load-cip-capacity-display-config.js +61 -15
  301. package/lib/utils/manifest-source-emit.js +2 -0
  302. package/lib/utils/paths.js +25 -0
  303. package/lib/utils/pipeline-upload-auth-retry.js +82 -0
  304. package/lib/utils/platform-controller-url.js +157 -0
  305. package/lib/utils/platform-kv-ref.js +57 -0
  306. package/lib/utils/postgres-platform-bootstrap.js +199 -0
  307. package/lib/utils/postgres-wipe.js +9 -2
  308. package/lib/utils/resolve-env-mode.js +47 -0
  309. package/lib/utils/runtime-configuration-download.js +189 -0
  310. package/lib/utils/runtime-configuration-values.js +119 -0
  311. package/lib/utils/schema-loader.js +19 -4
  312. package/lib/utils/secrets-generator.js +31 -25
  313. package/lib/utils/secrets-missing-error.js +164 -0
  314. package/lib/utils/service-url-label.js +81 -0
  315. package/lib/utils/setup-quiet-output.js +25 -0
  316. package/lib/utils/template-helpers.js +15 -0
  317. package/lib/utils/token-manager-client-credentials.js +201 -0
  318. package/lib/utils/token-manager-messages.js +8 -0
  319. package/lib/utils/token-manager-refresh.js +12 -2
  320. package/lib/utils/token-manager.js +86 -105
  321. package/lib/utils/upload-pipeline-ui.js +12 -5
  322. package/lib/utils/upload-sync-options.js +42 -0
  323. package/lib/utils/url-declarative-public-base.js +21 -3
  324. package/lib/utils/url-declarative-vdir-inactive-env.js +14 -4
  325. package/lib/utils/validation-poll-ui.js +8 -0
  326. package/lib/utils/validation-run-stage.js +45 -0
  327. package/lib/utils/worker-sidecars.js +142 -0
  328. package/lib/validation/external-manifest-validator.js +2 -0
  329. package/lib/validation/runtime-configuration-rules.js +98 -0
  330. package/lib/validation/validate-display-dimensions.js +154 -0
  331. package/lib/validation/validate-display-sections.js +276 -0
  332. package/lib/validation/validate-display-steps.js +67 -0
  333. package/lib/validation/validate-display.js +24 -402
  334. package/package.json +1 -1
  335. package/templates/applications/dataplane/application.yaml +7 -1
  336. package/templates/applications/dataplane/env.template +50 -14
  337. package/templates/applications/dataplane/rbac.yaml +108 -1
  338. package/templates/applications/miso-controller/application.yaml +2 -2
  339. package/templates/applications/miso-controller/env.template +53 -122
  340. package/templates/applications/miso-controller/rbac.yaml +28 -13
  341. package/templates/channels/chatgpt/install.template.md.hbs +49 -0
  342. package/templates/channels/chatgpt/manifest.template.json.hbs +9 -0
  343. package/templates/channels/microsoft-copilot/install.template.md.hbs +49 -0
  344. package/templates/channels/microsoft-copilot/manifest.template.json.hbs +8 -0
  345. package/templates/channels/slack/install.template.md.hbs +49 -0
  346. package/templates/channels/slack/manifest.template.json.hbs +66 -0
  347. package/templates/channels/teams-bot/install.template.md.hbs +49 -0
  348. package/templates/channels/teams-bot/manifest.template.json.hbs +13 -0
  349. package/templates/channels/web-embed/install.template.md.hbs +49 -0
  350. package/templates/channels/web-embed/manifest.template.json.hbs +8 -0
  351. package/templates/external-system/README.md.hbs +74 -17
  352. package/templates/python/docker-compose.hbs +75 -18
  353. package/templates/typescript/docker-compose.hbs +70 -17
  354. package/lib/commands/test-governance-command-action.js +0 -55
  355. package/lib/commands/test-trust-command-action.js +0 -118
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Setup platform topology mode (`single` | `single-traefik` | `full`).
3
+ *
4
+ * This is distinct from `setupInstallationProfile` (dev/pro password bundle) and from
5
+ * the login/run environment (`dev` | `tst` | `pro`).
6
+ *
7
+ * @fileoverview Setup platform mode normalization and defaults
8
+ * @author AI Fabrix Team
9
+ * @version 1.0.0
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ /** @enum {string} */
15
+ const SETUP_PLATFORM_MODE = Object.freeze({
16
+ SINGLE: 'single',
17
+ SINGLE_TRAEFIK: 'single-traefik',
18
+ FULL: 'full'
19
+ });
20
+
21
+ /** @type {readonly string[]} */
22
+ const SETUP_PLATFORM_MODE_CLI_VALUES = Object.freeze([
23
+ SETUP_PLATFORM_MODE.SINGLE,
24
+ SETUP_PLATFORM_MODE.SINGLE_TRAEFIK,
25
+ SETUP_PLATFORM_MODE.FULL
26
+ ]);
27
+
28
+ /**
29
+ * @param {unknown} value
30
+ * @returns {'single'|'single-traefik'|'full'}
31
+ */
32
+ function normalizeSetupPlatformMode(value) {
33
+ const raw = String(value ?? '')
34
+ .trim()
35
+ .toLowerCase();
36
+ if (raw === SETUP_PLATFORM_MODE.FULL) return SETUP_PLATFORM_MODE.FULL;
37
+ if (raw === 'all' || raw === 'full-platform' || raw === 'platform-full') return SETUP_PLATFORM_MODE.FULL;
38
+ if (raw === SETUP_PLATFORM_MODE.SINGLE_TRAEFIK) return SETUP_PLATFORM_MODE.SINGLE_TRAEFIK;
39
+ if (raw === 'ingress' || raw === 'single-ingress' || raw === 'traefik') return SETUP_PLATFORM_MODE.SINGLE_TRAEFIK;
40
+ return SETUP_PLATFORM_MODE.SINGLE;
41
+ }
42
+
43
+ /**
44
+ * Derived config flags for a chosen platform mode.
45
+ *
46
+ * - single: direct ports, no front door ingress
47
+ * - single-traefik: Traefik front door (domain + TLS) for one environment only
48
+ * - full: Traefik ingress + env-scoped resources (multi-env; CLI only until menu returns)
49
+ *
50
+ * @param {'single'|'single-traefik'|'full'} mode
51
+ * @returns {{ traefik: boolean, useEnvironmentScopedResources: boolean }}
52
+ */
53
+ function flagsForSetupPlatformMode(mode) {
54
+ const m = normalizeSetupPlatformMode(mode);
55
+ const traefik =
56
+ m === SETUP_PLATFORM_MODE.SINGLE_TRAEFIK || m === SETUP_PLATFORM_MODE.FULL;
57
+ return {
58
+ traefik,
59
+ useEnvironmentScopedResources: m === SETUP_PLATFORM_MODE.FULL
60
+ };
61
+ }
62
+
63
+ /**
64
+ * Interactive setup menu choices (full platform hidden until multi-env path ships).
65
+ *
66
+ * @returns {{ name: string, value: string }[]}
67
+ */
68
+ function getSetupPlatformModePromptChoices() {
69
+ return [
70
+ {
71
+ name: 'Single environment — direct ports (no Traefik front door)',
72
+ value: SETUP_PLATFORM_MODE.SINGLE
73
+ },
74
+ {
75
+ name: 'Single environment — Traefik front door (domain + TLS)',
76
+ value: SETUP_PLATFORM_MODE.SINGLE_TRAEFIK
77
+ }
78
+ // Full platform — Traefik front door + miso/dev/tst/pro (shared infra) — menu returns soon.
79
+ // { name: 'Full platform — Traefik front door + miso/dev/tst/pro (shared infra)', value: SETUP_PLATFORM_MODE.FULL },
80
+ ];
81
+ }
82
+
83
+ module.exports = {
84
+ SETUP_PLATFORM_MODE,
85
+ SETUP_PLATFORM_MODE_CLI_VALUES,
86
+ normalizeSetupPlatformMode,
87
+ flagsForSetupPlatformMode,
88
+ getSetupPlatformModePromptChoices
89
+ };
90
+
@@ -21,7 +21,7 @@ async function writeTrustDebugLog(appKey, datasourceKey, payload) {
21
21
  const logPath = await writeTestLog(
22
22
  appKey,
23
23
  payload,
24
- `test-trust-${datasourceKey}`,
24
+ `verify-trust-${datasourceKey}`,
25
25
  path.dirname(getIntegrationPath(appKey))
26
26
  );
27
27
  return logPath;
@@ -14,14 +14,15 @@ const { setupIntegrationTestAuth } = require('../external-system/test-auth');
14
14
  const { resolveAppKeyForDatasource } = require('./resolve-app');
15
15
  const { getSystemKeyFromAppKey } = require('./integration-context');
16
16
  const { requireBearerForDataplanePipeline } = require('../utils/token-manager');
17
+ const { buildMinimalUploadSyncOptions } = require('../utils/upload-sync-options');
17
18
  const { fetchTrustRunFromDataplane } = require('./agent-trust-fetch');
18
19
 
19
- async function maybeSyncBeforeTrust({ noSync, authConfig, systemKey }) {
20
+ async function maybeSyncBeforeTrust({ noSync, authConfig, systemKey, options = {} }) {
20
21
  if (noSync === true) return;
21
22
  requireBearerForDataplanePipeline(authConfig);
22
23
  logger.log(chalk.cyan('Syncing local config to dataplane…'));
23
24
  const { uploadExternalSystem } = require('../commands/upload');
24
- await uploadExternalSystem(systemKey, { minimal: true });
25
+ await uploadExternalSystem(systemKey, buildMinimalUploadSyncOptions(options));
25
26
  logger.log(formatSuccessLine('Sync complete'));
26
27
  }
27
28
 
@@ -67,7 +68,8 @@ async function runDatasourceAgentTrust(datasourceKey, options = {}) {
67
68
  await maybeSyncBeforeTrust({
68
69
  noSync: options.noSync === true,
69
70
  authConfig,
70
- systemKey
71
+ systemKey,
72
+ options
71
73
  });
72
74
 
73
75
  try {
@@ -6,6 +6,8 @@
6
6
 
7
7
  'use strict';
8
8
 
9
+ const { parseCapacityDetailKey } = require('../utils/load-cip-capacity-display-config');
10
+
9
11
  /**
10
12
  * @param {Array<*>} ids
11
13
  * @returns {string[]}
@@ -67,32 +69,42 @@ function executionIdsFromDebugEnvelope(envelope) {
67
69
  }
68
70
 
69
71
  /**
70
- * CIP operation names from capacity step (insert, update, list, …).
71
72
  * @param {Object|null|undefined} envelope
72
- * @returns {string[]}
73
+ * @returns {Object|null}
73
74
  */
74
- function cipOperationsFromDebugEnvelope(envelope) {
75
- const dbg = envelope && envelope.debug;
76
- const asyncDbg = dbg && dbg.e2eAsyncDebug;
77
- if (!asyncDbg || !Array.isArray(asyncDbg.stepDebug)) return [];
78
- const capStep = asyncDbg.stepDebug.find(s => s && s.name === 'capacity');
79
- if (!capStep || !capStep.evidence) return [];
75
+ function getCapacityStepFromEnvelope(envelope) {
76
+ const asyncDbg = envelope && envelope.debug && envelope.debug.e2eAsyncDebug;
77
+ if (!asyncDbg || !Array.isArray(asyncDbg.stepDebug)) return null;
78
+ return asyncDbg.stepDebug.find(s => s && s.name === 'capacity') || null;
79
+ }
80
+
81
+ /**
82
+ * Operation names from CIP capacity evidence keys (`capacity:<op>#<index>`), without product aliases.
83
+ * @param {*} details
84
+ * @returns {Set<string>}
85
+ */
86
+ function collectCipOpsFromCapabilityDetails(details) {
80
87
  const ops = new Set();
81
- const details = capStep.evidence.datasources;
82
- if (!Array.isArray(details)) return [];
88
+ if (!Array.isArray(details)) return ops;
83
89
  for (const ds of details) {
84
90
  if (!ds || !Array.isArray(ds.capabilityDetails)) continue;
85
91
  for (const item of ds.capabilityDetails) {
86
- const key = item && item.key ? String(item.key) : '';
87
- const m = key.match(/^capacity:([a-zA-Z]+)/);
88
- if (m && m[1]) {
89
- let op = m[1] === 'updateBasic' ? 'updatebasic' : m[1].toLowerCase();
90
- if (op === 'create') op = 'insert';
91
- ops.add(op);
92
- }
92
+ const parsed = parseCapacityDetailKey(item && item.key);
93
+ if (parsed && parsed.op) ops.add(parsed.op);
93
94
  }
94
95
  }
95
- return [...ops];
96
+ return ops;
97
+ }
98
+
99
+ /**
100
+ * CIP operation names from capacity step (insert, update, list, …).
101
+ * @param {Object|null|undefined} envelope
102
+ * @returns {string[]}
103
+ */
104
+ function cipOperationsFromDebugEnvelope(envelope) {
105
+ const capStep = getCapacityStepFromEnvelope(envelope);
106
+ if (!capStep || !capStep.evidence) return [];
107
+ return [...collectCipOpsFromCapabilityDetails(capStep.evidence.datasources)];
96
108
  }
97
109
 
98
110
  module.exports = {
@@ -16,6 +16,7 @@ const {
16
16
  cipOperationsFromDebugEnvelope,
17
17
  dedupeIds: dedupeIdsFromDebug
18
18
  } = require('./audit-evidence-extract-debug');
19
+ const loadCipCapacityDisplayConfig = require('../utils/load-cip-capacity-display-config');
19
20
 
20
21
  /** @param {Array<*>} ids @returns {string[]} */
21
22
  function dedupeIds(ids) {
@@ -88,14 +89,16 @@ function correlationIdFromEnvelope(envelope) {
88
89
  function expectedOperationsFromEnvelope(envelope) {
89
90
  const fromCapacity = cipOperationsFromDebugEnvelope(envelope);
90
91
  if (fromCapacity.length) return fromCapacity;
92
+ const { standardOrder } = loadCipCapacityDisplayConfig.getCipCapacityDisplayConfig();
93
+ const allowed = new Set(
94
+ (standardOrder || []).map(op => String(op).trim().toLowerCase()).filter(Boolean)
95
+ );
91
96
  const ops = new Set();
92
97
  const caps = envelope && Array.isArray(envelope.capabilities) ? envelope.capabilities : [];
93
98
  for (const cap of caps) {
94
99
  if (!cap || cap.status === 'skipped' || !cap.key) continue;
95
- const key = String(cap.key).trim();
96
- if (['insert', 'update', 'get', 'delete', 'list', 'create'].includes(key)) {
97
- ops.add(key === 'create' ? 'insert' : key);
98
- }
100
+ const key = String(cap.key).trim().toLowerCase();
101
+ if (allowed.has(key)) ops.add(key);
99
102
  }
100
103
  const integration = envelope && envelope.integration;
101
104
  if (integration && integration.sync && integration.sync.status === 'ok') {
@@ -113,22 +113,27 @@ async function buildListMatrixRows(ctx, polled, minExpected) {
113
113
 
114
114
  /**
115
115
  * @param {Object} ctx
116
- * @param {Array} executions
117
- * @param {string[]} executionIds
118
- * @returns {Promise<{ rows: import('../api/types/audit.types').AuditEvidenceMatrixRow[], execIds: string[] }>}
116
+ * @param {string[]} execIds
117
+ * @returns {Promise<import('../api/types/audit.types').AuditEvidenceMatrixRow[]>}
119
118
  */
120
- async function buildPerExecutionAndTailRows(ctx, executions, executionIds) {
119
+ async function buildPerExecutionSubRows(ctx, execIds) {
121
120
  const { dataplaneUrl, authConfig } = ctx;
122
- const execIds = resolveExecutionIdsForChecks(executions, executionIds);
123
- const sampleId = execIds[0];
124
- const base = { dataplaneUrl, authConfig, executionId: sampleId };
125
- const rows = await Promise.all([
121
+ const base = { dataplaneUrl, authConfig, executionId: execIds[0] };
122
+ return Promise.all([
126
123
  checkPerExecutionSub({ ...base, rowNum: 4, label: 'rbac', fetcher: getExecutionRbac, isValid: isRbacSubResourceValid }),
127
124
  checkPerExecutionSub({ ...base, rowNum: 5, label: 'abac', fetcher: getExecutionAbac, isValid: isAbacSubResourceValid }),
128
125
  checkPerExecutionSub({ ...base, rowNum: 6, label: 'errors', fetcher: getExecutionErrors, isValid: isErrorsValid }),
129
126
  checkPerExecutionSub({ ...base, rowNum: 7, label: 'steps', fetcher: getExecutionSteps, isValid: isStepsValid })
130
127
  ]);
128
+ }
131
129
 
130
+ /**
131
+ * @param {Object} ctx
132
+ * @param {Array} executions
133
+ * @returns {Promise<Array>}
134
+ */
135
+ async function resolveRow8PoolForMatrix(ctx, executions) {
136
+ const { dataplaneUrl, authConfig } = ctx;
132
137
  let corrQueryRows = [];
133
138
  if (ctx.correlationId) {
134
139
  const corr = await queryExecutions(dataplaneUrl, authConfig, {
@@ -137,28 +142,30 @@ async function buildPerExecutionAndTailRows(ctx, executions, executionIds) {
137
142
  });
138
143
  corrQueryRows = corr.data || [];
139
144
  }
140
- let row8Pool = corrQueryRows.length ? corrQueryRows : executions;
145
+ const row8Pool = corrQueryRows.length ? corrQueryRows : executions;
141
146
  const expected = ctx.expectedOperations || [];
142
- if (expected.length && ctx.correlationId) {
143
- const byOp = await fetchCorrelationExecutionsByOperation(
144
- dataplaneUrl,
145
- authConfig,
146
- ctx.correlationId,
147
- expected
148
- );
149
- if (byOp.length) row8Pool = byOp;
147
+ if (!expected.length || !ctx.correlationId) {
148
+ return row8Pool;
150
149
  }
151
- const row8Executions = resolveRow8Executions(ctx, executions, row8Pool);
152
- rows.push(
153
- checkRow8CorrelationGroup({
154
- correlationId: ctx.correlationId,
155
- executions: row8Executions,
156
- expectedOperations: ctx.expectedOperations
157
- })
150
+ const byOp = await fetchCorrelationExecutionsByOperation(
151
+ dataplaneUrl,
152
+ authConfig,
153
+ ctx.correlationId,
154
+ expected
158
155
  );
156
+ return byOp.length ? byOp : row8Pool;
157
+ }
159
158
 
159
+ /**
160
+ * @param {Object} ctx
161
+ * @param {string[]} execIds
162
+ * @returns {Promise<Set<string>>}
163
+ */
164
+ async function collectTraceIdsForRow9(ctx, execIds) {
165
+ const { dataplaneUrl, authConfig } = ctx;
160
166
  const traceIds = new Set();
161
- for (const id of execIds.slice(0, Math.min(execIds.length, 12))) {
167
+ const sample = execIds.slice(0, Math.min(execIds.length, 12));
168
+ for (const id of sample) {
162
169
  try {
163
170
  const tr = await getExecutionTrace(dataplaneUrl, authConfig, id);
164
171
  if (tr && tr.executionId) traceIds.add(String(tr.executionId));
@@ -167,7 +174,28 @@ async function buildPerExecutionAndTailRows(ctx, executions, executionIds) {
167
174
  /* row 9 may fail */
168
175
  }
169
176
  }
170
- rows.push(checkRow9Traces(traceIds, execIds));
177
+ return traceIds;
178
+ }
179
+
180
+ /**
181
+ * @param {Object} ctx
182
+ * @param {Array} executions
183
+ * @param {string[]} executionIds
184
+ * @returns {Promise<{ rows: import('../api/types/audit.types').AuditEvidenceMatrixRow[], execIds: string[] }>}
185
+ */
186
+ async function buildPerExecutionAndTailRows(ctx, executions, executionIds) {
187
+ const execIds = resolveExecutionIdsForChecks(executions, executionIds);
188
+ const rows = await buildPerExecutionSubRows(ctx, execIds);
189
+ const row8Pool = await resolveRow8PoolForMatrix(ctx, executions);
190
+ const row8Executions = resolveRow8Executions(ctx, executions, row8Pool);
191
+ rows.push(
192
+ checkRow8CorrelationGroup({
193
+ correlationId: ctx.correlationId,
194
+ executions: row8Executions,
195
+ expectedOperations: ctx.expectedOperations
196
+ })
197
+ );
198
+ rows.push(checkRow9Traces(await collectTraceIdsForRow9(ctx, execIds), execIds));
171
199
  return { rows, execIds };
172
200
  }
173
201
 
@@ -34,9 +34,21 @@ function recordBatchFailure(state, index, err, batchRecords) {
34
34
  * @param {Object[]} batchRecords
35
35
  */
36
36
  function recordBatchSuccess(state, index, response, batchRecords) {
37
- const inserted = response.insertedCount || 0;
38
- const updated = response.updatedCount || 0;
39
- const processed = response.totalProcessed || batchRecords.length;
37
+ if (!response || typeof response !== 'object') {
38
+ throw new Error('Bulk sync returned empty response');
39
+ }
40
+ if (response.success === false) {
41
+ throw new Error(
42
+ response.formattedError ||
43
+ response.error ||
44
+ `Bulk sync failed (HTTP ${response.status || 0})`
45
+ );
46
+ }
47
+ const payload =
48
+ response.data !== undefined && response.data !== null ? response.data : response;
49
+ const inserted = payload.insertedCount || 0;
50
+ const updated = payload.updatedCount || 0;
51
+ const processed = payload.totalProcessed || batchRecords.length;
40
52
  const failedInBatch = Math.max(0, batchRecords.length - processed);
41
53
 
42
54
  state.batches.push({
@@ -7,6 +7,7 @@
7
7
  */
8
8
 
9
9
  const { deepClone } = require('./copy-operations');
10
+ const { capabilitiesIncludes } = require('./capability-manifest');
10
11
 
11
12
  /**
12
13
  * @param {object} doc - Parsed datasource JSON
@@ -16,8 +17,7 @@ const { deepClone } = require('./copy-operations');
16
17
  */
17
18
  function extractCapabilitySliceForDiff(doc, capabilityKey, profileKey) {
18
19
  const cap = capabilityKey;
19
- const listed =
20
- Boolean(Array.isArray(doc.capabilities) && doc.capabilities.includes(cap));
20
+ const listed = capabilitiesIncludes(doc.capabilities, cap);
21
21
  const openapiOp = doc.openapi?.operations?.[cap];
22
22
  const cipOp = doc.execution?.cip?.operations?.[cap];
23
23
  let exposedProfile;
@@ -0,0 +1,254 @@
1
+ /**
2
+ * COM v2 capability object helpers for datasource manifests.
3
+ *
4
+ * @fileoverview capability-manifest
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const FORBIDDEN_ROOT_KEYS = new Set([
12
+ 'context',
13
+ 'origin',
14
+ 'generatedBy',
15
+ 'composition',
16
+ 'generation',
17
+ 'enterpriseResolver'
18
+ ]);
19
+
20
+ const DEFAULT_RISK_BY_KEY = {
21
+ list: 'low',
22
+ get: 'low',
23
+ search: 'low',
24
+ create: 'medium',
25
+ update: 'medium',
26
+ delete: 'high'
27
+ };
28
+
29
+ const RESOURCE_TYPE_MAP = {
30
+ conversation: 'message',
31
+ user: 'employee',
32
+ person: 'employee',
33
+ record: 'document',
34
+ folder: 'document',
35
+ country: 'organization',
36
+ report: 'document',
37
+ calendar: 'event',
38
+ subscription: 'event'
39
+ };
40
+
41
+ /**
42
+ * @param {unknown} entry
43
+ * @returns {string}
44
+ */
45
+ function capabilityKeyFromEntry(entry) {
46
+ if (typeof entry === 'string' && entry.trim()) {
47
+ return entry.trim();
48
+ }
49
+ if (entry && typeof entry === 'object' && typeof entry.key === 'string' && entry.key.trim()) {
50
+ return entry.key.trim();
51
+ }
52
+ return '';
53
+ }
54
+
55
+ /**
56
+ * @param {unknown} capabilities
57
+ * @returns {string[]}
58
+ */
59
+ function listCapabilityKeys(capabilities) {
60
+ if (!Array.isArray(capabilities)) {
61
+ return [];
62
+ }
63
+ return capabilities.map(capabilityKeyFromEntry).filter(Boolean);
64
+ }
65
+
66
+ /**
67
+ * @param {unknown} capabilities
68
+ * @param {string} key
69
+ * @returns {boolean}
70
+ */
71
+ function capabilitiesIncludes(capabilities, key) {
72
+ const target = String(key).toLowerCase();
73
+ return listCapabilityKeys(capabilities).some((item) => item.toLowerCase() === target);
74
+ }
75
+
76
+ /**
77
+ * @param {string} key
78
+ * @param {string} [displayName]
79
+ * @returns {object}
80
+ */
81
+ function buildCapabilityObject(key, displayName) {
82
+ const normalized = String(key || '').trim();
83
+ const label = displayName && String(displayName).trim() ? String(displayName).trim() : 'records';
84
+ return {
85
+ key: normalized,
86
+ description: `${normalized} operation on ${label}`,
87
+ riskLevel: DEFAULT_RISK_BY_KEY[normalized.toLowerCase()] || 'medium',
88
+ approvalRequired: false
89
+ };
90
+ }
91
+
92
+ /**
93
+ * @param {object} parsed
94
+ * @returns {object[]}
95
+ */
96
+ function normalizeCapabilitiesToObjects(parsed) {
97
+ const caps = parsed?.capabilities;
98
+ const displayName = parsed?.displayName || parsed?.key || 'records';
99
+ if (!Array.isArray(caps) || caps.length === 0) {
100
+ return [];
101
+ }
102
+ const out = [];
103
+ const seen = new Set();
104
+ caps.forEach((item) => {
105
+ if (typeof item === 'string' && item.trim()) {
106
+ const key = item.trim();
107
+ if (seen.has(key)) return;
108
+ seen.add(key);
109
+ out.push(buildCapabilityObject(key, displayName));
110
+ return;
111
+ }
112
+ if (!item || typeof item !== 'object') return;
113
+ const key = capabilityKeyFromEntry(item);
114
+ if (!key || seen.has(key)) return;
115
+ seen.add(key);
116
+ const row = buildCapabilityObject(key, displayName);
117
+ if (typeof item.description === 'string' && item.description.trim()) {
118
+ row.description = item.description.trim();
119
+ }
120
+ if (typeof item.riskLevel === 'string' && item.riskLevel.trim()) {
121
+ row.riskLevel = item.riskLevel.trim();
122
+ }
123
+ if (item.approvalRequired === true) {
124
+ row.approvalRequired = true;
125
+ }
126
+ out.push(row);
127
+ });
128
+ return out;
129
+ }
130
+
131
+ /**
132
+ * @param {object} node
133
+ * @returns {void}
134
+ */
135
+ function stripSemanticExtras(node) {
136
+ if (!node || typeof node !== 'object') return;
137
+ const semantic = node.semantic;
138
+ if (semantic && typeof semantic === 'object') {
139
+ delete semantic.categories;
140
+ delete semantic.synonyms;
141
+ if (Object.keys(semantic).length === 0) {
142
+ delete node.semantic;
143
+ }
144
+ }
145
+ Object.values(node).forEach((value) => {
146
+ if (value && typeof value === 'object') {
147
+ if (Array.isArray(value)) {
148
+ value.forEach((item) => stripSemanticExtras(item));
149
+ } else {
150
+ stripSemanticExtras(value);
151
+ }
152
+ }
153
+ });
154
+ }
155
+
156
+ /**
157
+ * @param {object} parsed
158
+ * @param {string[]} changes
159
+ * @returns {boolean}
160
+ */
161
+ function removeForbiddenComRootKeys(parsed, changes) {
162
+ let updated = false;
163
+ FORBIDDEN_ROOT_KEYS.forEach((key) => {
164
+ if (Object.prototype.hasOwnProperty.call(parsed, key)) {
165
+ delete parsed[key];
166
+ changes.push(`Removed forbidden COM v2 root key: ${key}`);
167
+ updated = true;
168
+ }
169
+ });
170
+ return updated;
171
+ }
172
+
173
+ /**
174
+ * @param {object} parsed
175
+ * @param {string[]} changes
176
+ * @returns {boolean}
177
+ */
178
+ function stripFieldMappingSemanticExtras(parsed, changes) {
179
+ if (!parsed.fieldMappings) {
180
+ return false;
181
+ }
182
+ const before = JSON.stringify(parsed.fieldMappings);
183
+ stripSemanticExtras(parsed.fieldMappings);
184
+ if (JSON.stringify(parsed.fieldMappings) === before) {
185
+ return false;
186
+ }
187
+ changes.push('Removed fieldMappings.*.semantic.categories/synonyms (COM v2)');
188
+ return true;
189
+ }
190
+
191
+ /**
192
+ * @param {object} parsed
193
+ * @param {string[]} changes
194
+ * @returns {boolean}
195
+ */
196
+ function applyResourceTypeCatalogMap(parsed, changes) {
197
+ const resourceType = parsed.resourceType;
198
+ if (typeof resourceType !== 'string') {
199
+ return false;
200
+ }
201
+ const mapped = RESOURCE_TYPE_MAP[resourceType.trim()];
202
+ if (!mapped) {
203
+ return false;
204
+ }
205
+ parsed.resourceType = mapped;
206
+ changes.push(`Mapped resourceType ${resourceType} → ${mapped}`);
207
+ return true;
208
+ }
209
+
210
+ /**
211
+ * @param {object} parsed
212
+ * @param {string[]} changes
213
+ * @returns {boolean}
214
+ */
215
+ function migrateCapabilitiesToComObjects(parsed, changes) {
216
+ const caps = parsed.capabilities;
217
+ const needsObjectMigration = Array.isArray(caps)
218
+ && caps.some((item) => typeof item === 'string' || (item && typeof item === 'object' && !item.key));
219
+ const hasStringCapabilities = Array.isArray(caps) && caps.length > 0 && typeof caps[0] === 'string';
220
+ if (!needsObjectMigration && !hasStringCapabilities) {
221
+ return false;
222
+ }
223
+ parsed.capabilities = normalizeCapabilitiesToObjects(parsed);
224
+ changes.push('Migrated capabilities[] to COM v2 capability objects');
225
+ return true;
226
+ }
227
+
228
+ /**
229
+ * @param {object} parsed
230
+ * @param {string[]} changes
231
+ * @returns {boolean}
232
+ */
233
+ function repairComV2Manifest(parsed, changes) {
234
+ if (!parsed || typeof parsed !== 'object') {
235
+ return false;
236
+ }
237
+ return [
238
+ removeForbiddenComRootKeys(parsed, changes),
239
+ stripFieldMappingSemanticExtras(parsed, changes),
240
+ applyResourceTypeCatalogMap(parsed, changes),
241
+ migrateCapabilitiesToComObjects(parsed, changes)
242
+ ].some(Boolean);
243
+ }
244
+
245
+ module.exports = {
246
+ FORBIDDEN_ROOT_KEYS,
247
+ capabilityKeyFromEntry,
248
+ listCapabilityKeys,
249
+ capabilitiesIncludes,
250
+ buildCapabilityObject,
251
+ normalizeCapabilitiesToObjects,
252
+ stripSemanticExtras,
253
+ repairComV2Manifest
254
+ };
@@ -6,6 +6,8 @@
6
6
  * @version 2.0.0
7
7
  */
8
8
 
9
+ const { capabilitiesIncludes } = require('./capability-manifest');
10
+
9
11
  /**
10
12
  * @param {object|undefined} operations
11
13
  * @param {string} logicalKey
@@ -146,10 +148,7 @@ function resolveProfileKeyForLogical(doc, logicalKey) {
146
148
  * @returns {boolean}
147
149
  */
148
150
  function capabilityLogicalExists(doc, name) {
149
- if (
150
- Array.isArray(doc.capabilities) &&
151
- doc.capabilities.some((c) => String(c).toLowerCase() === String(name).toLowerCase())
152
- ) {
151
+ if (capabilitiesIncludes(doc.capabilities, name)) {
153
152
  return true;
154
153
  }
155
154
  if (findMatchingOpsKeys(doc.openapi?.operations, name).length > 0) {
@@ -7,6 +7,7 @@
7
7
  */
8
8
 
9
9
  const { rewriteCapabilityReferences } = require('./reference-rewrite');
10
+ const { capabilityKeyFromEntry } = require('./capability-manifest');
10
11
  const { jsonPointerPath } = require('./json-pointer');
11
12
  const { buildBasicExposureProfileArray } = require('./basic-exposure');
12
13
  const {
@@ -53,9 +54,10 @@ function removeCapability(doc, logicalKey) {
53
54
  const profileKey = resolveProfileKeyForLogical(doc, logicalKey);
54
55
 
55
56
  if (Array.isArray(doc.capabilities)) {
56
- doc.capabilities = doc.capabilities.filter(
57
- (c) => String(c).toLowerCase() !== String(logicalKey).toLowerCase()
58
- );
57
+ doc.capabilities = doc.capabilities.filter((c) => {
58
+ const key = capabilityKeyFromEntry(c);
59
+ return key.toLowerCase() !== String(logicalKey).toLowerCase();
60
+ });
59
61
  }
60
62
  if (openapiKey && oo) {
61
63
  delete oo[openapiKey];