@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.
- package/.cursor/rules/cli-layout.mdc +2 -0
- package/.cursor/rules/cli-product-neutral.mdc +43 -0
- package/.cursor/rules/project-rules.mdc +1 -0
- package/.npmrc.token +1 -0
- package/.temp/jest-protection-convert/run-IFN2nv/.protection/hubspot-companies.json +1 -0
- package/.temp/jest-protection-convert/run-IvmKLO/.protection/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-convert/run-SdvblF/.protection/hubspot-companies.json +1 -0
- package/.temp/jest-protection-convert/run-b51TsW/.protection/hubspot-companies.json +1 -0
- package/.temp/jest-protection-convert/run-fiLmb1/.protection/hubspot-companies.json +1 -0
- package/.temp/jest-protection-convert/run-qYGHMU/.protection/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-Mq5re8/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-f3u4YL/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-iQtd1O/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-mdmz5M/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-qbKYxQ/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-yzlJy6/hubspot-companies.yaml +17 -0
- package/.temp/validation/summary.txt +5 -0
- package/README.md +43 -17
- package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +1 -1
- package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.yaml +1 -1
- package/jest.config.default.js +2 -1
- package/jest.config.isolated.js +2 -1
- package/jest.global-live-fabrix-hooks.js +36 -0
- package/jest.isolated-projects.js +146 -0
- package/jest.projects.js +65 -136
- package/lib/api/api-response-errors.js +124 -0
- package/lib/api/dataplane-health.api.js +19 -7
- package/lib/api/governance-scenario-pack.api.js +159 -0
- package/lib/api/index.js +43 -3
- package/lib/api/lifecycle.api.js +98 -0
- package/lib/api/pipeline.api.js +3 -1
- package/lib/api/records-bulk.api.js +14 -1
- package/lib/api/resource-types.api.js +107 -0
- package/lib/api/runtime-configuration.api.js +72 -0
- package/lib/api/types/resource-types.types.js +45 -0
- package/lib/api/user-groups.api.js +9 -9
- package/lib/api/users.api.js +8 -8
- package/lib/api/validation-runner.js +3 -1
- package/lib/api/wizard.api.js +10 -2
- package/lib/app/deploy-config.js +4 -1
- package/lib/app/down.js +78 -27
- package/lib/app/index.js +2 -2
- package/lib/app/push.js +4 -5
- package/lib/app/register.js +7 -4
- package/lib/app/run-env-compose.js +84 -30
- package/lib/app/run-resolve-image.js +2 -1
- package/lib/app/run-stop-containers.js +113 -0
- package/lib/app/run.js +1 -31
- package/lib/app/show-display.js +35 -0
- package/lib/app/show.js +32 -1
- package/lib/build/index.js +22 -5
- package/lib/build/miso-controller-npm-sdk-guard.js +25 -0
- package/lib/certification/sync-system-certification.js +13 -6
- package/lib/channels/add-channel.js +348 -0
- package/lib/channels/channel-artifact-generator.js +141 -0
- package/lib/channels/channel-audit.js +101 -0
- package/lib/channels/channel-auth-context.js +37 -0
- package/lib/channels/channel-credential.js +200 -0
- package/lib/channels/channel-display-name.js +64 -0
- package/lib/channels/channel-external-system.js +106 -0
- package/lib/channels/channel-integration-generator.js +274 -0
- package/lib/channels/channel-probe.js +89 -0
- package/lib/channels/channel-runtime-resolver.js +152 -0
- package/lib/channels/channel-status-display.js +141 -0
- package/lib/channels/channel-targets.js +115 -0
- package/lib/cli/index.js +20 -4
- package/lib/cli/infra-guided-auth.js +109 -0
- package/lib/cli/infra-guided.js +84 -81
- package/lib/cli/setup-app.help.js +0 -31
- package/lib/cli/setup-app.js +82 -5
- package/lib/cli/setup-app.test-commands.js +5 -57
- package/lib/cli/setup-auth.js +25 -0
- package/lib/cli/setup-certification-commands.js +147 -0
- package/lib/cli/setup-certification.help.js +141 -0
- package/lib/cli/setup-environment.js +19 -2
- package/lib/cli/setup-external-system-help.js +62 -0
- package/lib/cli/setup-external-system.js +25 -3
- package/lib/cli/setup-infra-up-dataplane-action.js +2 -2
- package/lib/cli/setup-infra-up-platform-action.js +2 -1
- package/lib/cli/setup-infra.js +9 -1
- package/lib/cli/setup-platform.js +6 -1
- package/lib/cli/setup-secrets.js +33 -1
- package/lib/cli/setup-utility-help-after.js +25 -2
- package/lib/cli/setup-utility-repair.js +198 -0
- package/lib/cli/setup-utility-resolve.js +44 -5
- package/lib/cli/setup-utility-validate.js +197 -0
- package/lib/cli/setup-utility.js +4 -239
- package/lib/commands/app-logs.js +54 -26
- package/lib/commands/app.js +41 -0
- package/lib/commands/auth-status-client-tokens.js +214 -0
- package/lib/commands/auth-status-dataplane-version.js +142 -68
- package/lib/commands/auth-status.js +43 -54
- package/lib/commands/channel.js +58 -0
- package/lib/commands/datasource-test-trust-cli.js +27 -23
- package/lib/commands/datasource-unified-test-cli.js +6 -3
- package/lib/commands/datasource-unified-test-cli.options.js +5 -1
- package/lib/commands/datasource.js +8 -8
- package/lib/commands/dev-show-display.js +8 -1
- package/lib/commands/governance-cli-shared.js +94 -0
- package/lib/commands/governance-command-action.js +132 -0
- package/lib/commands/governance-download-external.js +34 -0
- package/lib/commands/governance-generate-external.js +71 -0
- package/lib/commands/governance-upload-external.js +36 -0
- package/lib/commands/governance-verify-external.js +64 -0
- package/lib/commands/governance.js +144 -0
- package/lib/commands/identity-apply-sync.js +49 -8
- package/lib/commands/identity-group-cli.js +66 -26
- package/lib/commands/identity-membership-role-cache.js +58 -37
- package/lib/commands/identity-shared.js +22 -1
- package/lib/commands/identity-user-cli.js +80 -34
- package/lib/commands/lifecycle-command-action.js +123 -0
- package/lib/commands/lifecycle-external.js +268 -0
- package/lib/commands/login.js +11 -2
- package/lib/commands/repair-auth-apply.js +153 -0
- package/lib/commands/repair-auth-config.js +8 -13
- package/lib/commands/repair-changed-files.js +41 -0
- package/lib/commands/repair-datasource-com-v2.js +15 -0
- package/lib/commands/repair-datasource-keys.js +4 -1
- package/lib/commands/repair-datasource-run.js +59 -0
- package/lib/commands/repair-datasource-service-contract.js +206 -0
- package/lib/commands/repair-datasource-test-payload.js +259 -0
- package/lib/commands/repair-datasource.js +49 -64
- package/lib/commands/repair-env-template.js +76 -25
- package/lib/commands/repair-external-run.js +216 -0
- package/lib/commands/repair-openapi-sync.js +49 -4
- package/lib/commands/repair-persist.js +4 -0
- package/lib/commands/repair-rbac.js +52 -1
- package/lib/commands/repair-steps.js +160 -0
- package/lib/commands/repair-system-alignment.js +7 -4
- package/lib/commands/repair.js +29 -296
- package/lib/commands/resource-type.js +371 -0
- package/lib/commands/secrets-get.js +184 -0
- package/lib/commands/secrets-remove-all.js +3 -1
- package/lib/commands/setup-image-refresh.js +146 -0
- package/lib/commands/setup-modes.js +158 -162
- package/lib/commands/setup-platform-auth.js +76 -0
- package/lib/commands/setup-prompts-admin.js +244 -0
- package/lib/commands/setup-prompts-platform-mode.js +70 -0
- package/lib/commands/setup-prompts-validators.js +36 -0
- package/lib/commands/setup-prompts.js +24 -76
- package/lib/commands/setup-run-context.js +45 -0
- package/lib/commands/setup-spinners.js +39 -0
- package/lib/commands/setup.js +27 -5
- package/lib/commands/teardown.js +39 -0
- package/lib/commands/test-e2e-external.js +24 -8
- package/lib/commands/test-governance-external.js +3 -24
- package/lib/commands/test-trust-external.js +48 -100
- package/lib/commands/up-common.js +57 -13
- package/lib/commands/up-dataplane.js +56 -15
- package/lib/commands/upload-publish-context.js +75 -0
- package/lib/commands/upload-sidecar-followups.js +89 -0
- package/lib/commands/upload.js +113 -110
- package/lib/commands/verify-governance-combined-external.js +61 -0
- package/lib/commands/verify-governance-command-action.js +64 -0
- package/lib/commands/verify-governance-db.js +102 -0
- package/lib/commands/verify-governance-external.js +77 -0
- package/lib/commands/verify-governance-result-builders.js +71 -0
- package/lib/commands/verify-operations-command-action.js +68 -0
- package/lib/commands/verify-operations-external.js +268 -0
- package/lib/commands/verify-operations-persist.js +75 -0
- package/lib/commands/verify-operations-step-plan.js +68 -0
- package/lib/commands/verify-operations-steps.js +111 -0
- package/lib/commands/verify-trust-command-action.js +73 -0
- package/lib/commands/verify-trust-external.js +59 -0
- package/lib/commands/wizard-config-normalizer.js +43 -23
- package/lib/commands/wizard-core.js +2 -0
- package/lib/core/admin-password-generator.js +38 -0
- package/lib/core/admin-secrets-bundle.js +111 -0
- package/lib/core/admin-secrets-env-overlay.js +62 -0
- package/lib/core/admin-secrets.js +32 -4
- package/lib/core/config-attach-extensions.js +3 -0
- package/lib/core/config-platform-controller.js +44 -0
- package/lib/core/config-setup-installation-profile.js +42 -0
- package/lib/core/config-setup-platform-mode.js +46 -0
- package/lib/core/config.js +46 -36
- package/lib/core/secrets-admin-env.js +6 -2
- package/lib/core/secrets-ensure.js +4 -0
- package/lib/core/secrets-env-content.js +54 -48
- package/lib/core/secrets-env-write.js +10 -1
- package/lib/core/secrets-infra-placeholder-sync.js +2 -0
- package/lib/core/setup-installation-profile.js +43 -0
- package/lib/core/setup-platform-mode.js +90 -0
- package/lib/datasource/agent-trust-debug-log.js +1 -1
- package/lib/datasource/agent-trust-run.js +5 -3
- package/lib/datasource/audit-evidence-extract-debug.js +30 -18
- package/lib/datasource/audit-evidence-extract.js +7 -4
- package/lib/datasource/audit-evidence-verify-matrix.js +54 -26
- package/lib/datasource/bulk-loader-run-batches.js +15 -3
- package/lib/datasource/capability/capability-diff-slice.js +2 -2
- package/lib/datasource/capability/capability-manifest.js +254 -0
- package/lib/datasource/capability/capability-resolve.js +3 -4
- package/lib/datasource/capability/copy-operations.js +5 -3
- package/lib/datasource/capability/remove-operations.js +2 -1
- package/lib/datasource/capability/run-capability-copy.js +32 -4
- package/lib/datasource/capability/run-capability-diff.js +3 -3
- package/lib/datasource/capability/run-capability-dimension.js +2 -4
- package/lib/datasource/capability/run-capability-edit.js +4 -7
- package/lib/datasource/capability/run-capability-relate.js +2 -4
- package/lib/datasource/capability/run-capability-remove.js +2 -4
- package/lib/datasource/capability/validate-capability-slice.js +2 -1
- package/lib/datasource/datasource-identifier.js +2 -1
- package/lib/datasource/datasource-load-export-context.js +3 -0
- package/lib/datasource/datasource-validate-display.js +1 -1
- package/lib/datasource/field-reference-validator.js +24 -3
- package/lib/datasource/log-cleaner.js +2 -2
- package/lib/datasource/log-viewer.js +8 -8
- package/lib/datasource/orphan-profiles-validator.js +98 -0
- package/lib/datasource/test-e2e.js +4 -1
- package/lib/datasource/unified-validation-run-body.js +3 -1
- package/lib/datasource/unified-validation-run.js +5 -2
- package/lib/datasource/validate.js +41 -23
- package/lib/deployment/environment-poll-status.js +138 -0
- package/lib/deployment/environment.js +42 -34
- package/lib/external-system/download-helpers.js +87 -0
- package/lib/external-system/download.js +78 -138
- package/lib/external-system/generator.js +1 -55
- package/lib/external-system/integration-auth-context.js +45 -0
- package/lib/external-system/test-auth.js +12 -5
- package/lib/external-system/test.js +16 -21
- package/lib/generator/builders.js +11 -1
- package/lib/generator/external-controller-manifest.js +18 -0
- package/lib/generator/split.js +3 -1
- package/lib/generator/wizard.js +1 -28
- package/lib/governance/governance-cli-errors.js +96 -0
- package/lib/governance/governance-download-display.js +38 -0
- package/lib/governance/governance-run-display.js +215 -25
- package/lib/identity/fk-reference.js +65 -0
- package/lib/identity/identity-apply-core.js +13 -58
- package/lib/identity/identity-apply-phases.js +5 -1
- package/lib/identity/identity-display.js +243 -0
- package/lib/identity/identity-response-helpers.js +52 -0
- package/lib/identity/identity-sync-errors.js +62 -0
- package/lib/identity/resolve-user-id.js +129 -0
- package/lib/identity/username-default.js +31 -0
- package/lib/infrastructure/admin-secrets-apply.js +84 -0
- package/lib/infrastructure/admin-secrets-ensure.js +130 -0
- package/lib/infrastructure/admin-secrets-resolve.js +95 -0
- package/lib/infrastructure/admin-secrets-sync.js +91 -0
- package/lib/infrastructure/helpers.js +23 -129
- package/lib/infrastructure/index.js +5 -6
- package/lib/infrastructure/orphan-infra-docker-teardown.js +11 -5
- package/lib/lifecycle/certification-progress.js +231 -0
- package/lib/lifecycle/dataplane-ui-url.js +145 -0
- package/lib/lifecycle/exit-codes.js +24 -0
- package/lib/lifecycle/json-envelope.js +25 -0
- package/lib/lifecycle/lifecycle-governance-options.js +51 -0
- package/lib/lifecycle/logger-quiet.js +29 -0
- package/lib/lifecycle/open-api-published.js +59 -0
- package/lib/lifecycle/operations-readiness-metrics.js +101 -0
- package/lib/lifecycle/product-model.js +196 -0
- package/lib/lifecycle/report-display-trust.js +70 -0
- package/lib/lifecycle/report-display.js +472 -0
- package/lib/lifecycle/scenario-upload.js +191 -0
- package/lib/lifecycle/verify-step-progress.js +87 -0
- package/lib/parameters/infra-kv-discovery.js +27 -2
- package/lib/protection/auth-context.js +10 -4
- package/lib/resolvers/datasource-resolver.js +2 -3
- package/lib/resolvers/resource-type-file.js +159 -0
- package/lib/schema/application-schema.json +17 -1
- package/lib/schema/datasource-test-run.schema.json +89 -6
- package/lib/schema/deployment-rules.yaml +2 -1
- package/lib/schema/external-datasource.schema.json +2947 -2619
- package/lib/schema/external-system.schema.json +1418 -761
- package/lib/schema/infra.parameter.yaml +45 -0
- package/lib/schema/type/credential-field-registry.json +103 -97
- package/lib/schema/type/document-storage.json +9 -5
- package/lib/utils/aifabrix-test-runtime-guard.js +125 -0
- package/lib/utils/api.js +55 -31
- package/lib/utils/app-relative-path-env.js +112 -0
- package/lib/utils/app-run-containers.js +25 -2
- package/lib/utils/authentication-shape.js +224 -0
- package/lib/utils/build-copy.js +36 -5
- package/lib/utils/build-resolve-image.js +66 -12
- package/lib/utils/celery-companion-apps.js +53 -0
- package/lib/utils/cli-secrets-error-format.js +83 -21
- package/lib/utils/cli-utils.js +20 -4
- package/lib/utils/compose-celery-worker.js +23 -0
- package/lib/utils/compose-generate-docker-compose.js +13 -1
- package/lib/utils/compose-traefik-ingress-base.js +16 -1
- package/lib/utils/config-secrets-path.js +46 -0
- package/lib/utils/configuration-env-resolver.js +36 -0
- package/lib/utils/controller-url.js +88 -1
- package/lib/utils/credential-secrets-env-kv.js +216 -0
- package/lib/utils/credential-secrets-env.js +175 -257
- package/lib/utils/dataplane-resolver.js +18 -2
- package/lib/utils/declarative-url-ports.js +27 -4
- package/lib/utils/deployment-auth-mode.js +41 -0
- package/lib/utils/developer-volume-id.js +33 -0
- package/lib/utils/docker-build.js +1 -4
- package/lib/utils/env-copy.js +14 -9
- package/lib/utils/env-kv-orphan-lines.js +43 -0
- package/lib/utils/error-formatters/network-errors.js +13 -4
- package/lib/utils/external-env-template.js +11 -3
- package/lib/utils/external-system-readiness-core.js +10 -0
- package/lib/utils/external-system-readiness-display.js +80 -23
- package/lib/utils/external-system-validators.js +8 -2
- package/lib/utils/health-check.js +4 -1
- package/lib/utils/help-builder.js +13 -8
- package/lib/utils/keycloak-realm-ready.js +101 -0
- package/lib/utils/load-cip-capacity-display-config.js +61 -15
- package/lib/utils/manifest-source-emit.js +2 -0
- package/lib/utils/paths.js +25 -0
- package/lib/utils/pipeline-upload-auth-retry.js +82 -0
- package/lib/utils/platform-controller-url.js +157 -0
- package/lib/utils/platform-kv-ref.js +57 -0
- package/lib/utils/postgres-platform-bootstrap.js +199 -0
- package/lib/utils/postgres-wipe.js +9 -2
- package/lib/utils/resolve-env-mode.js +47 -0
- package/lib/utils/runtime-configuration-download.js +189 -0
- package/lib/utils/runtime-configuration-values.js +119 -0
- package/lib/utils/schema-loader.js +19 -4
- package/lib/utils/secrets-generator.js +31 -25
- package/lib/utils/secrets-missing-error.js +164 -0
- package/lib/utils/service-url-label.js +81 -0
- package/lib/utils/setup-quiet-output.js +25 -0
- package/lib/utils/template-helpers.js +15 -0
- package/lib/utils/token-manager-client-credentials.js +201 -0
- package/lib/utils/token-manager-messages.js +8 -0
- package/lib/utils/token-manager-refresh.js +12 -2
- package/lib/utils/token-manager.js +86 -105
- package/lib/utils/upload-pipeline-ui.js +12 -5
- package/lib/utils/upload-sync-options.js +42 -0
- package/lib/utils/url-declarative-public-base.js +21 -3
- package/lib/utils/url-declarative-vdir-inactive-env.js +14 -4
- package/lib/utils/validation-poll-ui.js +8 -0
- package/lib/utils/validation-run-stage.js +45 -0
- package/lib/utils/worker-sidecars.js +142 -0
- package/lib/validation/external-manifest-validator.js +2 -0
- package/lib/validation/runtime-configuration-rules.js +98 -0
- package/lib/validation/validate-display-dimensions.js +154 -0
- package/lib/validation/validate-display-sections.js +276 -0
- package/lib/validation/validate-display-steps.js +67 -0
- package/lib/validation/validate-display.js +24 -402
- package/package.json +1 -1
- package/templates/applications/dataplane/application.yaml +7 -1
- package/templates/applications/dataplane/env.template +50 -14
- package/templates/applications/dataplane/rbac.yaml +108 -1
- package/templates/applications/miso-controller/application.yaml +2 -2
- package/templates/applications/miso-controller/env.template +53 -122
- package/templates/applications/miso-controller/rbac.yaml +28 -13
- package/templates/channels/chatgpt/install.template.md.hbs +49 -0
- package/templates/channels/chatgpt/manifest.template.json.hbs +9 -0
- package/templates/channels/microsoft-copilot/install.template.md.hbs +49 -0
- package/templates/channels/microsoft-copilot/manifest.template.json.hbs +8 -0
- package/templates/channels/slack/install.template.md.hbs +49 -0
- package/templates/channels/slack/manifest.template.json.hbs +66 -0
- package/templates/channels/teams-bot/install.template.md.hbs +49 -0
- package/templates/channels/teams-bot/manifest.template.json.hbs +13 -0
- package/templates/channels/web-embed/install.template.md.hbs +49 -0
- package/templates/channels/web-embed/manifest.template.json.hbs +8 -0
- package/templates/external-system/README.md.hbs +74 -17
- package/templates/python/docker-compose.hbs +75 -18
- package/templates/typescript/docker-compose.hbs +70 -17
- package/lib/commands/test-governance-command-action.js +0 -55
- 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
|
-
`
|
|
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,
|
|
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 {
|
|
73
|
+
* @returns {Object|null}
|
|
73
74
|
*/
|
|
74
|
-
function
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
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
|
|
87
|
-
|
|
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
|
|
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 (
|
|
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 {
|
|
117
|
-
* @
|
|
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
|
|
119
|
+
async function buildPerExecutionSubRows(ctx, execIds) {
|
|
121
120
|
const { dataplaneUrl, authConfig } = ctx;
|
|
122
|
-
const
|
|
123
|
-
|
|
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
|
-
|
|
145
|
+
const row8Pool = corrQueryRows.length ? corrQueryRows : executions;
|
|
141
146
|
const expected = ctx.expectedOperations || [];
|
|
142
|
-
if (expected.length
|
|
143
|
-
|
|
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
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
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];
|