@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
|
@@ -17,6 +17,7 @@ const {
|
|
|
17
17
|
findMatchingOpsKeys,
|
|
18
18
|
resolveProfileKeyForLogical
|
|
19
19
|
} = require('./capability-resolve');
|
|
20
|
+
const { capabilityKeyFromEntry } = require('./capability-manifest');
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* @param {unknown} capabilities
|
|
@@ -28,7 +29,7 @@ function findCapabilityIndex(capabilities, logicalName) {
|
|
|
28
29
|
return -1;
|
|
29
30
|
}
|
|
30
31
|
return capabilities.findIndex(
|
|
31
|
-
(c) =>
|
|
32
|
+
(c) => capabilityKeyFromEntry(c).toLowerCase() === String(logicalName).toLowerCase()
|
|
32
33
|
);
|
|
33
34
|
}
|
|
34
35
|
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
const fs = require('node:fs');
|
|
10
10
|
const path = require('path');
|
|
11
|
+
const { loadConfigFile, writeConfigFile } = require('../../utils/config-format');
|
|
11
12
|
const { writeBackup } = require('../../utils/integration-file-backup');
|
|
12
13
|
const {
|
|
13
14
|
resolveValidateInputPath,
|
|
@@ -46,6 +47,33 @@ function resolveCapabilityCopyInputPath(identifier) {
|
|
|
46
47
|
return resolveValidateInputPath(trimmed);
|
|
47
48
|
}
|
|
48
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Read a datasource config file (.json, .yaml, or .yml).
|
|
52
|
+
*
|
|
53
|
+
* @param {string} filePath
|
|
54
|
+
* @returns {object}
|
|
55
|
+
*/
|
|
56
|
+
function readDatasourceConfigFile(filePath) {
|
|
57
|
+
return loadConfigFile(filePath);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @param {string} filePath
|
|
62
|
+
* @returns {'json'|'yaml'}
|
|
63
|
+
*/
|
|
64
|
+
function inferDatasourceConfigFormat(filePath) {
|
|
65
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
66
|
+
if (ext === '.json') {
|
|
67
|
+
return 'json';
|
|
68
|
+
}
|
|
69
|
+
if (ext === '.yaml' || ext === '.yml') {
|
|
70
|
+
return 'yaml';
|
|
71
|
+
}
|
|
72
|
+
throw new Error(
|
|
73
|
+
`Unsupported datasource config extension: ${ext || '(none)'}. Use .json, .yaml, or .yml`
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
49
77
|
/**
|
|
50
78
|
* @param {string} filePath
|
|
51
79
|
* @param {object} obj
|
|
@@ -53,9 +81,9 @@ function resolveCapabilityCopyInputPath(identifier) {
|
|
|
53
81
|
*/
|
|
54
82
|
function atomicWriteJson(filePath, obj) {
|
|
55
83
|
const dir = path.dirname(filePath);
|
|
84
|
+
const format = inferDatasourceConfigFormat(filePath);
|
|
56
85
|
const tmp = path.join(dir, `.${path.basename(filePath)}.${process.pid}.tmp`);
|
|
57
|
-
|
|
58
|
-
fs.writeFileSync(tmp, payload, 'utf8');
|
|
86
|
+
writeConfigFile(tmp, obj, format);
|
|
59
87
|
fs.renameSync(tmp, filePath);
|
|
60
88
|
}
|
|
61
89
|
|
|
@@ -89,8 +117,7 @@ function atomicWriteJson(filePath, obj) {
|
|
|
89
117
|
*/
|
|
90
118
|
async function runCapabilityCopy(opts) {
|
|
91
119
|
const resolvedPath = resolveCapabilityCopyInputPath(opts.fileOrKey.trim());
|
|
92
|
-
const
|
|
93
|
-
const parsed = JSON.parse(raw);
|
|
120
|
+
const parsed = readDatasourceConfigFile(resolvedPath);
|
|
94
121
|
|
|
95
122
|
const to = normalizeCapabilityKey(opts.as, 'Target (--as)');
|
|
96
123
|
const fromRaw = opts.from !== undefined && opts.from !== null ? String(opts.from).trim() : '';
|
|
@@ -148,5 +175,6 @@ async function runCapabilityCopy(opts) {
|
|
|
148
175
|
module.exports = {
|
|
149
176
|
runCapabilityCopy,
|
|
150
177
|
writeBackup,
|
|
178
|
+
readDatasourceConfigFile,
|
|
151
179
|
atomicWriteJson
|
|
152
180
|
};
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* @version 2.0.0
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
const fs = require('fs');
|
|
10
9
|
const path = require('path');
|
|
10
|
+
const { readDatasourceConfigFile } = require('./run-capability-copy');
|
|
11
11
|
const { resolveValidateInputPath } = require('../validate');
|
|
12
12
|
const { normalizeCapabilityKey } = require('./capability-key');
|
|
13
13
|
const { extractCapabilitySliceForDiff } = require('./capability-diff-slice');
|
|
@@ -108,8 +108,8 @@ function resolveProfileKeys(opts) {
|
|
|
108
108
|
function runCapabilityDiff(opts) {
|
|
109
109
|
const pathA = resolveValidateInputPath(opts.fileA.trim());
|
|
110
110
|
const pathB = resolveValidateInputPath(opts.fileB.trim());
|
|
111
|
-
const docA =
|
|
112
|
-
const docB =
|
|
111
|
+
const docA = readDatasourceConfigFile(pathA);
|
|
112
|
+
const docB = readDatasourceConfigFile(pathB);
|
|
113
113
|
|
|
114
114
|
const { capA, capB } = resolveCapabilityKeys(opts);
|
|
115
115
|
const { profA, profB } = resolveProfileKeys(opts);
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
|
|
9
9
|
'use strict';
|
|
10
10
|
|
|
11
|
-
const fs = require('fs');
|
|
12
11
|
const { resolveControllerUrl } = require('../../utils/controller-url');
|
|
13
12
|
const { normalizeControllerUrl } = require('../../core/config');
|
|
14
13
|
const { getOrRefreshDeviceToken } = require('../../utils/token-manager');
|
|
@@ -19,7 +18,7 @@ const {
|
|
|
19
18
|
} = require('../validate');
|
|
20
19
|
const { applyCapabilityDimension } = require('./dimension-operations');
|
|
21
20
|
const { validateDimensionSemantics } = require('./dimension-validate');
|
|
22
|
-
const { writeBackup, atomicWriteJson } = require('./run-capability-copy');
|
|
21
|
+
const { writeBackup, atomicWriteJson, readDatasourceConfigFile } = require('./run-capability-copy');
|
|
23
22
|
const { tryResolveDatasourceKeyToLocalPath, readJsonFile } = require('../../resolvers/datasource-resolver');
|
|
24
23
|
const { tryFetchDatasourceConfig } = require('../../resolvers/manifest-resolver');
|
|
25
24
|
|
|
@@ -231,8 +230,7 @@ function applyBindingAndValidateSchema({ parsed, opts, semanticWarnings, remoteF
|
|
|
231
230
|
async function runCapabilityDimension(rawOpts) {
|
|
232
231
|
const opts = normalizeRunOptions(rawOpts);
|
|
233
232
|
const resolvedPath = resolveValidateInputPath(opts.fileOrKey);
|
|
234
|
-
const
|
|
235
|
-
const parsed = JSON.parse(raw);
|
|
233
|
+
const parsed = readDatasourceConfigFile(resolvedPath);
|
|
236
234
|
|
|
237
235
|
const systemKeyForAuth = resolveSystemKeyForAuth(parsed);
|
|
238
236
|
const { remoteTargetsByKey, remoteFetchMeta } = await loadRemoteTargetsByKey({
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
* @version 2.0.0
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
const fs = require('fs');
|
|
10
9
|
const { execSync } = require('child_process');
|
|
11
10
|
const inquirer = require('inquirer');
|
|
12
11
|
const {
|
|
@@ -19,7 +18,8 @@ const {
|
|
|
19
18
|
resolveSingleOpsKey,
|
|
20
19
|
resolveProfileKeyForLogical
|
|
21
20
|
} = require('./capability-resolve');
|
|
22
|
-
const { writeBackup, atomicWriteJson } = require('./run-capability-copy');
|
|
21
|
+
const { writeBackup, atomicWriteJson, readDatasourceConfigFile } = require('./run-capability-copy');
|
|
22
|
+
const { listCapabilityKeys } = require('./capability-manifest');
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* @typedef {object} RunCapabilityEditOpts
|
|
@@ -35,10 +35,7 @@ const { writeBackup, atomicWriteJson } = require('./run-capability-copy');
|
|
|
35
35
|
* @returns {string[]}
|
|
36
36
|
*/
|
|
37
37
|
function collectCapabilityKeys(doc) {
|
|
38
|
-
const s = new Set();
|
|
39
|
-
if (Array.isArray(doc.capabilities)) {
|
|
40
|
-
doc.capabilities.forEach((c) => s.add(String(c)));
|
|
41
|
-
}
|
|
38
|
+
const s = new Set(listCapabilityKeys(doc.capabilities));
|
|
42
39
|
if (doc.openapi?.operations) {
|
|
43
40
|
Object.keys(doc.openapi.operations).forEach((k) => s.add(k));
|
|
44
41
|
}
|
|
@@ -351,7 +348,7 @@ async function runCapabilityEdit(opts) {
|
|
|
351
348
|
throw new Error('capability edit requires an interactive terminal (TTY). Use a terminal or SSH with -t.');
|
|
352
349
|
}
|
|
353
350
|
const resolvedPath = resolveValidateInputPath(opts.fileOrKey.trim());
|
|
354
|
-
const doc =
|
|
351
|
+
const doc = readDatasourceConfigFile(resolvedPath);
|
|
355
352
|
const { capKey, section, profileKey } = await resolveEditTargets(doc, opts);
|
|
356
353
|
const initial = getEditableJson(doc, capKey, section, profileKey);
|
|
357
354
|
const body = await promptEditorJson(initial);
|
|
@@ -6,14 +6,13 @@
|
|
|
6
6
|
* @version 2.0.0
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
const fs = require('fs');
|
|
10
9
|
const {
|
|
11
10
|
resolveValidateInputPath,
|
|
12
11
|
validateDatasourceParsed
|
|
13
12
|
} = require('../validate');
|
|
14
13
|
const { applyCapabilityRelate } = require('./relate-operations');
|
|
15
14
|
const { validateRelateSemantics } = require('./relate-validate');
|
|
16
|
-
const { writeBackup, atomicWriteJson } = require('./run-capability-copy');
|
|
15
|
+
const { writeBackup, atomicWriteJson, readDatasourceConfigFile } = require('./run-capability-copy');
|
|
17
16
|
const { tryResolveDatasourceKeyToLocalPath, readJsonFile } = require('../../resolvers/datasource-resolver');
|
|
18
17
|
const { tryFetchDatasourceConfig } = require('../../resolvers/manifest-resolver');
|
|
19
18
|
|
|
@@ -134,8 +133,7 @@ function applyRelateAndValidateSchema(parsed, opts, semanticWarnings, remoteVali
|
|
|
134
133
|
*/
|
|
135
134
|
async function runCapabilityRelate(opts) {
|
|
136
135
|
const resolvedPath = resolveValidateInputPath(opts.fileOrKey.trim());
|
|
137
|
-
const
|
|
138
|
-
const parsed = JSON.parse(raw);
|
|
136
|
+
const parsed = readDatasourceConfigFile(resolvedPath);
|
|
139
137
|
|
|
140
138
|
const targetDocLocal = loadTargetDocLocal(opts.targetDatasource);
|
|
141
139
|
const systemKeyForAuth = resolveSystemKeyForAuth(parsed);
|
|
@@ -6,14 +6,13 @@
|
|
|
6
6
|
* @version 2.0.0
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
const fs = require('fs');
|
|
10
9
|
const {
|
|
11
10
|
resolveValidateInputPath,
|
|
12
11
|
validateDatasourceParsed
|
|
13
12
|
} = require('../validate');
|
|
14
13
|
const { normalizeCapabilityKey } = require('./capability-key');
|
|
15
14
|
const { applyCapabilityRemove } = require('./remove-operations');
|
|
16
|
-
const { writeBackup, atomicWriteJson } = require('./run-capability-copy');
|
|
15
|
+
const { writeBackup, atomicWriteJson, readDatasourceConfigFile } = require('./run-capability-copy');
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
18
|
* @param {{ valid: boolean, errors: string[] }} validation
|
|
@@ -67,8 +66,7 @@ function makeRemoveResult(resolvedPath, capability, result, validation, dryRun,
|
|
|
67
66
|
*/
|
|
68
67
|
async function runCapabilityRemove(opts) {
|
|
69
68
|
const resolvedPath = resolveValidateInputPath(opts.fileOrKey.trim());
|
|
70
|
-
const
|
|
71
|
-
const parsed = JSON.parse(raw);
|
|
69
|
+
const parsed = readDatasourceConfigFile(resolvedPath);
|
|
72
70
|
|
|
73
71
|
const capability = normalizeCapabilityKey(opts.capability, 'Capability (--capability)');
|
|
74
72
|
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
const { normalizeCapabilityKey } = require('./capability-key');
|
|
10
|
+
const { capabilitiesIncludes } = require('./capability-manifest');
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Lists structural locations where a capability key should appear.
|
|
@@ -18,7 +19,7 @@ const { normalizeCapabilityKey } = require('./capability-key');
|
|
|
18
19
|
function checkCapabilitySlices(parsed, rawKey) {
|
|
19
20
|
const key = normalizeCapabilityKey(rawKey, 'capability');
|
|
20
21
|
const missing = [];
|
|
21
|
-
if (!
|
|
22
|
+
if (!capabilitiesIncludes(parsed.capabilities, key)) {
|
|
22
23
|
missing.push(`capabilities[] (missing "${key}")`);
|
|
23
24
|
}
|
|
24
25
|
if (!parsed.openapi?.operations?.[key]) {
|
|
@@ -38,7 +38,8 @@ function datasourceIdentifierMatchesFile(identifier, fileRef, parsed) {
|
|
|
38
38
|
if (stem === id) {
|
|
39
39
|
return true;
|
|
40
40
|
}
|
|
41
|
-
|
|
41
|
+
const lowerId = id.toLowerCase();
|
|
42
|
+
if (`${stem}.json` === lowerId || `${stem}.yaml` === lowerId || `${stem}.yml` === lowerId) {
|
|
42
43
|
return true;
|
|
43
44
|
}
|
|
44
45
|
return false;
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
const { getConfig } = require('../core/config');
|
|
10
10
|
const { setupIntegrationTestAuth } = require('../external-system/test-auth');
|
|
11
|
+
const { applyLabDataplaneApiKeyBearer } = require('../utils/token-manager');
|
|
11
12
|
const { resolveAppKeyForDatasource } = require('./resolve-app');
|
|
12
13
|
const { getSystemKeyFromAppKey } = require('./integration-context');
|
|
13
14
|
const { loadDatasourceForApp } = require('./unified-validation-run-resolve');
|
|
@@ -62,6 +63,8 @@ async function resolveLoadExportContext(datasourceKey, options = {}) {
|
|
|
62
63
|
dataplaneUrl = auth.dataplaneUrl;
|
|
63
64
|
}
|
|
64
65
|
|
|
66
|
+
authConfig = applyLabDataplaneApiKeyBearer(authConfig);
|
|
67
|
+
|
|
65
68
|
return {
|
|
66
69
|
appKey,
|
|
67
70
|
systemKey,
|
|
@@ -30,7 +30,7 @@ function logHeaderAndIdentity(result, trimmed, showMapping) {
|
|
|
30
30
|
const { resolvedPath, summary } = result;
|
|
31
31
|
logger.log('');
|
|
32
32
|
logger.log(sectionTitle('Datasource validation'));
|
|
33
|
-
logger.log(metadata('Offline — JSON schema and integration wiring'));
|
|
33
|
+
logger.log(metadata('Offline — YAML/JSON schema and integration wiring'));
|
|
34
34
|
logger.log('');
|
|
35
35
|
if (summary) {
|
|
36
36
|
logger.log(` ${headerKeyValue('Key:', summary.key)}`);
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
* @version 2.0.0
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
+
const { validateOrphanExposedProfiles } = require('./orphan-profiles-validator');
|
|
14
|
+
|
|
13
15
|
/**
|
|
14
16
|
* Set of attribute names plus root dimension keys valid for field references.
|
|
15
17
|
* Used for primaryKey (schema allows dimension keys or attributes) and other paths (attributes only).
|
|
@@ -40,16 +42,34 @@ function checkPrimaryKey(parsed, attributesAndDimensions, errors) {
|
|
|
40
42
|
});
|
|
41
43
|
}
|
|
42
44
|
|
|
45
|
+
/** @returns {Set<string>} */
|
|
46
|
+
function profileReferenceSet(parsed) {
|
|
47
|
+
if (parsed?.entityType === 'serviceContract') {
|
|
48
|
+
const schema = parsed?.exposed?.schema;
|
|
49
|
+
if (schema && typeof schema === 'object' && !Array.isArray(schema)) {
|
|
50
|
+
return new Set(
|
|
51
|
+
Object.keys(schema).filter(key => typeof key === 'string' && key !== '')
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return new Set(Object.keys(parsed?.fieldMappings?.attributes ?? {}));
|
|
56
|
+
}
|
|
57
|
+
|
|
43
58
|
/** @param {string[]} errors */
|
|
44
|
-
function checkExposedProfiles(parsed,
|
|
59
|
+
function checkExposedProfiles(parsed, _attrSet, errors) {
|
|
45
60
|
const profiles = parsed?.exposed?.profiles;
|
|
46
61
|
if (!profiles || typeof profiles !== 'object' || Array.isArray(profiles)) return;
|
|
62
|
+
const profileRefSet = profileReferenceSet(parsed);
|
|
63
|
+
const referenceLabel =
|
|
64
|
+
parsed?.entityType === 'serviceContract'
|
|
65
|
+
? 'exposed.schema'
|
|
66
|
+
: 'fieldMappings.attributes';
|
|
47
67
|
Object.entries(profiles).forEach(([profileName, fields]) => {
|
|
48
68
|
if (!Array.isArray(fields)) return;
|
|
49
69
|
fields.forEach((field, idx) => {
|
|
50
|
-
if (typeof field === 'string' && !
|
|
70
|
+
if (typeof field === 'string' && !profileRefSet.has(field)) {
|
|
51
71
|
errors.push(
|
|
52
|
-
`exposed.profiles.${profileName}[${idx}]: field '${field}' does not exist in
|
|
72
|
+
`exposed.profiles.${profileName}[${idx}]: field '${field}' does not exist in ${referenceLabel}. Add the attribute or remove the reference.`
|
|
53
73
|
);
|
|
54
74
|
}
|
|
55
75
|
});
|
|
@@ -121,6 +141,7 @@ function validateFieldReferences(parsed) {
|
|
|
121
141
|
|
|
122
142
|
checkPrimaryKey(parsed, attributesAndDimensions, errors);
|
|
123
143
|
checkExposedProfiles(parsed, attrSet, errors);
|
|
144
|
+
errors.push(...validateOrphanExposedProfiles(parsed));
|
|
124
145
|
if (normalizedAttributes.length === 0) return errors;
|
|
125
146
|
|
|
126
147
|
checkIndexingAndValidation(parsed, normalizedAttributes, errors);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Remove saved datasource test debug JSON under integration/<app>/logs/.
|
|
3
|
-
* @fileoverview Local cleanup for test / test-integration / test-e2e /
|
|
3
|
+
* @fileoverview Local cleanup for test / test-integration / test-e2e / verify-trust logs
|
|
4
4
|
* @author AI Fabrix Team
|
|
5
5
|
* @version 1.0.0
|
|
6
6
|
*/
|
|
@@ -42,7 +42,7 @@ function matchesLogCleanType(fileName, type) {
|
|
|
42
42
|
return fileName.startsWith('test-integration-');
|
|
43
43
|
}
|
|
44
44
|
if (type === 'e2e') return fileName.startsWith('test-e2e-');
|
|
45
|
-
if (type === 'trust') return fileName.startsWith('
|
|
45
|
+
if (type === 'trust') return fileName.startsWith('verify-trust-');
|
|
46
46
|
return false;
|
|
47
47
|
}
|
|
48
48
|
|
|
@@ -59,7 +59,7 @@ function isStructuralTestLogFileName(name) {
|
|
|
59
59
|
if (
|
|
60
60
|
name.startsWith('test-e2e-') ||
|
|
61
61
|
name.startsWith('test-integration-') ||
|
|
62
|
-
name.startsWith('
|
|
62
|
+
name.startsWith('verify-trust-')
|
|
63
63
|
) {
|
|
64
64
|
return false;
|
|
65
65
|
}
|
|
@@ -276,7 +276,7 @@ function logTrustFindingsSection(run) {
|
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
/**
|
|
279
|
-
* Format agent trust log (`datasource
|
|
279
|
+
* Format agent trust log (`datasource verify-trust --debug` → `verify-trust-*.json`).
|
|
280
280
|
* @param {Object} data - Parsed JSON { request, response?, error? }
|
|
281
281
|
* @param {string} [fileName] - Log file name for header
|
|
282
282
|
*/
|
|
@@ -356,7 +356,7 @@ function formatStructuralTestLog(data, fileName) {
|
|
|
356
356
|
/**
|
|
357
357
|
* Format log content by type
|
|
358
358
|
* @param {Object} parsed - Parsed JSON log
|
|
359
|
-
* @param {'test'|'test-e2e'|'test-integration'|'
|
|
359
|
+
* @param {'test'|'test-e2e'|'test-integration'|'verify-trust'} logType - Log type
|
|
360
360
|
* @param {string} [fileName] - File name for header
|
|
361
361
|
*/
|
|
362
362
|
function formatLogContent(parsed, logType, fileName) {
|
|
@@ -364,7 +364,7 @@ function formatLogContent(parsed, logType, fileName) {
|
|
|
364
364
|
formatStructuralTestLog(parsed, fileName);
|
|
365
365
|
return;
|
|
366
366
|
}
|
|
367
|
-
if (logType === '
|
|
367
|
+
if (logType === 'verify-trust') {
|
|
368
368
|
formatTrustLog(parsed, fileName);
|
|
369
369
|
return;
|
|
370
370
|
}
|
|
@@ -410,7 +410,7 @@ function parseDatasourceLogJson(content, logPath) {
|
|
|
410
410
|
* @param {Object} options - Options
|
|
411
411
|
* @param {string} [options.app] - App key (optional, resolved from key if omitted)
|
|
412
412
|
* @param {string} [options.file] - Path to log file (overrides app resolution)
|
|
413
|
-
* @param {'test'|'test-e2e'|'test-integration'|'
|
|
413
|
+
* @param {'test'|'test-e2e'|'test-integration'|'verify-trust'} options.logType - Log type
|
|
414
414
|
* @throws {Error} When file not found or invalid JSON
|
|
415
415
|
*/
|
|
416
416
|
/* eslint-disable-next-line max-statements -- Resolve path, read, parse, format */
|
|
@@ -433,11 +433,11 @@ async function runLogViewer(datasourceKey, options) {
|
|
|
433
433
|
`No structural validation log found in ${logsDir}. Run: aifabrix datasource test <key> --debug`
|
|
434
434
|
);
|
|
435
435
|
}
|
|
436
|
-
} else if (logType === '
|
|
437
|
-
logPath = await getLatestLogPath(logsDir, '
|
|
436
|
+
} else if (logType === 'verify-trust') {
|
|
437
|
+
logPath = await getLatestLogPath(logsDir, 'verify-trust-');
|
|
438
438
|
if (!logPath) {
|
|
439
439
|
throw new Error(
|
|
440
|
-
`No
|
|
440
|
+
`No verify-trust log found in ${logsDir}. Run: aifabrix datasource verify-trust <key> --debug`
|
|
441
441
|
);
|
|
442
442
|
}
|
|
443
443
|
} else {
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate exposed.profiles keys against capabilities (346 §13 — no orphan profiles).
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Orphan exposed profile validation for datasource manifests
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const { listCapabilityKeys } = require('./capability/capability-manifest');
|
|
12
|
+
|
|
13
|
+
const FORBIDDEN_ORPHAN_PROFILE_KEYS = new Set(['minimal', 'analytics', 'metadata']);
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param {string} name
|
|
17
|
+
* @returns {string}
|
|
18
|
+
*/
|
|
19
|
+
function normalizeProfileKey(name) {
|
|
20
|
+
return String(name).trim().toLowerCase();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {object} parsed
|
|
25
|
+
* @returns {Set<string>}
|
|
26
|
+
*/
|
|
27
|
+
function operationKeysFromConfig(parsed) {
|
|
28
|
+
const keys = new Set();
|
|
29
|
+
const openapiOps = parsed?.openapi?.operations;
|
|
30
|
+
if (openapiOps && typeof openapiOps === 'object') {
|
|
31
|
+
Object.keys(openapiOps).forEach((k) => keys.add(normalizeProfileKey(k)));
|
|
32
|
+
}
|
|
33
|
+
const cipOps = parsed?.execution?.cip?.operations;
|
|
34
|
+
if (cipOps && typeof cipOps === 'object') {
|
|
35
|
+
Object.keys(cipOps).forEach((k) => keys.add(normalizeProfileKey(k)));
|
|
36
|
+
}
|
|
37
|
+
return keys;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @param {object} parsed
|
|
42
|
+
* @returns {Set<string>}
|
|
43
|
+
*/
|
|
44
|
+
function allowedExposedProfileKeys(parsed) {
|
|
45
|
+
const allowed = new Set(['default']);
|
|
46
|
+
const capabilityKeys = listCapabilityKeys(parsed?.capabilities).map(normalizeProfileKey);
|
|
47
|
+
if (capabilityKeys.length > 0) {
|
|
48
|
+
capabilityKeys.forEach((k) => allowed.add(k));
|
|
49
|
+
} else {
|
|
50
|
+
operationKeysFromConfig(parsed).forEach((k) => allowed.add(k));
|
|
51
|
+
}
|
|
52
|
+
return allowed;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @param {object} parsed - Parsed datasource manifest
|
|
57
|
+
* @returns {string[]} Error messages; empty when valid
|
|
58
|
+
*/
|
|
59
|
+
function validateOrphanExposedProfiles(parsed) {
|
|
60
|
+
const errors = [];
|
|
61
|
+
const profiles = parsed?.exposed?.profiles;
|
|
62
|
+
if (!profiles || typeof profiles !== 'object' || Array.isArray(profiles)) {
|
|
63
|
+
return errors;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const allowed = allowedExposedProfileKeys(parsed);
|
|
67
|
+
const orphans = Object.keys(profiles).filter((name) => {
|
|
68
|
+
const normalized = normalizeProfileKey(name);
|
|
69
|
+
return FORBIDDEN_ORPHAN_PROFILE_KEYS.has(normalized) || !allowed.has(normalized);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
if (orphans.length === 0) {
|
|
73
|
+
return errors;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const decorative = orphans.filter((name) =>
|
|
77
|
+
FORBIDDEN_ORPHAN_PROFILE_KEYS.has(normalizeProfileKey(name))
|
|
78
|
+
);
|
|
79
|
+
if (decorative.length > 0) {
|
|
80
|
+
errors.push(
|
|
81
|
+
`exposed.profiles: orphan exposed profiles are forbidden: ${decorative.join(', ')}. ` +
|
|
82
|
+
'Use exposed.profiles.default and one profile per capabilities[].key only.'
|
|
83
|
+
);
|
|
84
|
+
return errors;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
errors.push(
|
|
88
|
+
`exposed.profiles: orphan profile keys must match capabilities[].key or default: ${orphans.join(', ')}. ` +
|
|
89
|
+
`Allowed profile keys: ${[...allowed].sort().join(', ')}.`
|
|
90
|
+
);
|
|
91
|
+
return errors;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
module.exports = {
|
|
95
|
+
FORBIDDEN_ORPHAN_PROFILE_KEYS,
|
|
96
|
+
allowedExposedProfileKeys,
|
|
97
|
+
validateOrphanExposedProfiles
|
|
98
|
+
};
|
|
@@ -42,8 +42,11 @@ function buildUnifiedE2eRunOptions(options, timeoutMs, pk) {
|
|
|
42
42
|
capabilityKey: options.capabilityKey,
|
|
43
43
|
timeout: timeoutMs,
|
|
44
44
|
sync: options.sync === true,
|
|
45
|
+
force: options.force === true,
|
|
45
46
|
authConfig: options.authConfig,
|
|
46
|
-
dataplaneUrl: options.dataplaneUrl || options.dataplane
|
|
47
|
+
dataplaneUrl: options.dataplaneUrl || options.dataplane,
|
|
48
|
+
quietPollUi: options.quietPollUi === true,
|
|
49
|
+
onPollProgress: options.onPollProgress
|
|
47
50
|
};
|
|
48
51
|
}
|
|
49
52
|
|
|
@@ -10,6 +10,7 @@ const {
|
|
|
10
10
|
includeDebugForRequest
|
|
11
11
|
} = require('../utils/validation-run-request');
|
|
12
12
|
const testHelpers = require('../utils/external-system-test-helpers');
|
|
13
|
+
const { withStageOnValidationRunBody } = require('../utils/validation-run-stage');
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* @param {Object} params
|
|
@@ -52,7 +53,7 @@ async function buildUnifiedValidationBody(params) {
|
|
|
52
53
|
})
|
|
53
54
|
: undefined;
|
|
54
55
|
|
|
55
|
-
|
|
56
|
+
const body = buildExternalDataSourceValidationRequest({
|
|
56
57
|
systemKey,
|
|
57
58
|
datasourceKey,
|
|
58
59
|
runType,
|
|
@@ -62,6 +63,7 @@ async function buildUnifiedValidationBody(params) {
|
|
|
62
63
|
explain: options.verbose === true,
|
|
63
64
|
e2eOptions: e2eOptions && Object.keys(e2eOptions).length > 0 ? e2eOptions : undefined
|
|
64
65
|
});
|
|
66
|
+
return withStageOnValidationRunBody(body, runType);
|
|
65
67
|
}
|
|
66
68
|
|
|
67
69
|
module.exports = { buildUnifiedValidationBody };
|
|
@@ -18,6 +18,7 @@ const { buildUnifiedValidationBody } = require('./unified-validation-run-body');
|
|
|
18
18
|
const { postValidationRunAndOptionalPoll } = require('./unified-validation-run-post');
|
|
19
19
|
const { requireBearerForDataplanePipeline } = require('../utils/token-manager');
|
|
20
20
|
const logger = require('../utils/logger');
|
|
21
|
+
const { buildMinimalUploadSyncOptions } = require('../utils/upload-sync-options');
|
|
21
22
|
|
|
22
23
|
function _resourceTypeFromDatasource(datasource) {
|
|
23
24
|
return datasource && typeof datasource === 'object' && typeof datasource.resourceType === 'string'
|
|
@@ -59,7 +60,7 @@ async function maybeSyncDatasourceToDataplane({ options, authConfig, systemKey }
|
|
|
59
60
|
// are updated before validation runs. Datasource-only publish can still fail DP-SEC-013 when the
|
|
60
61
|
// dataplane system permissions[] are stale.
|
|
61
62
|
const { uploadExternalSystem } = require('../commands/upload');
|
|
62
|
-
await uploadExternalSystem(systemKey,
|
|
63
|
+
await uploadExternalSystem(systemKey, buildMinimalUploadSyncOptions(options));
|
|
63
64
|
logger.log(formatSuccessLine('Sync complete'));
|
|
64
65
|
}
|
|
65
66
|
|
|
@@ -139,7 +140,9 @@ async function runUnifiedDatasourceValidation(datasourceKey, options) {
|
|
|
139
140
|
useAsync,
|
|
140
141
|
noAsync: options.noAsync === true || options.async === false,
|
|
141
142
|
verbosePoll: options.verbose === true,
|
|
142
|
-
|
|
143
|
+
quietPollUi: options.quietPollUi === true,
|
|
144
|
+
pollSubject: datasourceKey,
|
|
145
|
+
onPollProgress: options.onPollProgress
|
|
143
146
|
});
|
|
144
147
|
|
|
145
148
|
if (result && result.envelope) {
|