@aifabrix/builder 2.43.0 → 2.44.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/anchor-docs.mdc +15 -0
- package/README.md +1 -1
- package/anchor-docs/README.md +10 -0
- package/anchor-docs/_TEMPLATE +24 -0
- package/bin/aifabrix.js +13 -4
- package/integration/hubspot-test/README.md +31 -0
- package/integration/hubspot-test/create-hubspot.js +5 -5
- package/integration/hubspot-test/hubspot-test-datasource-company.json +58 -462
- package/integration/hubspot-test/hubspot-test-datasource-contact.json +61 -555
- package/integration/hubspot-test/hubspot-test-datasource-deal.json +63 -506
- package/integration/hubspot-test/hubspot-test-datasource-users.json +42 -83
- package/integration/hubspot-test/hubspot-test-deploy.json +3 -3
- package/integration/hubspot-test/test-dataplane-down-tests.js +1 -7
- package/integration/hubspot-test/test-dataplane-down.js +3 -3
- package/integration/hubspot-test/test.js +35 -43
- package/integration/hubspot-test/wizard-hubspot-test-headless.yaml +23 -0
- package/integration/roundtrip-test-local/README.md +144 -0
- package/integration/roundtrip-test-local/application.yaml +13 -0
- package/integration/roundtrip-test-local/env.template +15 -0
- package/integration/roundtrip-test-local/roundtrip-test-local-datasource-roundtrip-test-company.yaml +14 -0
- package/integration/roundtrip-test-local/roundtrip-test-local-deploy.json +61 -0
- package/integration/roundtrip-test-local/roundtrip-test-local-system.yaml +25 -0
- package/integration/roundtrip-test-local2/README.md +144 -0
- package/integration/roundtrip-test-local2/application.yaml +13 -0
- package/integration/roundtrip-test-local2/env.template +15 -0
- package/integration/roundtrip-test-local2/roundtrip-test-local2-datasource-company.yaml +31 -0
- package/integration/roundtrip-test-local2/roundtrip-test-local2-deploy.json +86 -0
- package/integration/roundtrip-test-local2/roundtrip-test-local2-system.yaml +25 -0
- package/integration/test/wizard.yaml +8 -0
- package/jest.config.default.js +10 -0
- package/jest.config.integration.fixtures.js +22 -0
- package/jest.config.integration.js +21 -18
- package/jest.config.isolated.js +10 -0
- package/jest.projects.js +288 -0
- package/lib/api/datasources-core.api.js +3 -3
- package/lib/api/dev-mtls-request.js +110 -0
- package/lib/api/dev-server-https.js +145 -0
- package/lib/api/dev.api.js +133 -144
- package/lib/api/index.js +0 -1
- package/lib/api/pipeline.api.js +67 -20
- package/lib/api/types/dev.types.js +4 -3
- package/lib/api/types/pipeline.types.js +8 -5
- package/lib/api/types/validation-run.types.js +56 -0
- package/lib/api/validation-run.api.js +99 -0
- package/lib/api/validation-runner.js +99 -0
- package/lib/app/config.js +1 -1
- package/lib/app/deploy-status-display.js +2 -2
- package/lib/app/deploy.js +7 -6
- package/lib/app/display.js +2 -1
- package/lib/app/dockerfile.js +3 -2
- package/lib/app/down.js +2 -1
- package/lib/app/helpers.js +6 -5
- package/lib/app/index.js +27 -8
- package/lib/app/list.js +7 -6
- package/lib/app/push.js +4 -3
- package/lib/app/register.js +16 -7
- package/lib/app/rotate-secret.js +14 -13
- package/lib/app/run-container-start.js +184 -0
- package/lib/app/run-docker-fallback.js +108 -0
- package/lib/app/run-env-compose.js +30 -42
- package/lib/app/run-helpers.js +49 -126
- package/lib/app/run-infra-requirements.js +30 -0
- package/lib/app/run-resolve-image.js +21 -0
- package/lib/app/run.js +74 -21
- package/lib/app/show-display.js +1 -1
- package/lib/app/show.js +1 -1
- package/lib/build/index.js +13 -10
- package/lib/cli/index.js +2 -0
- package/lib/cli/setup-app.help.js +67 -0
- package/lib/cli/setup-app.js +57 -121
- package/lib/cli/setup-app.test-commands.js +179 -0
- package/lib/cli/setup-auth.js +19 -5
- package/lib/cli/setup-credential-deployment.js +22 -8
- package/lib/cli/setup-dev-path-commands.js +124 -0
- package/lib/cli/setup-dev.js +170 -113
- package/lib/cli/setup-environment.js +7 -1
- package/lib/cli/setup-external-system.js +62 -22
- package/lib/cli/setup-infra.js +126 -47
- package/lib/cli/setup-parameters.js +32 -0
- package/lib/cli/setup-secrets.js +106 -8
- package/lib/cli/setup-service-user.js +1 -1
- package/lib/cli/setup-utility.js +36 -20
- package/lib/commands/app-down.js +5 -7
- package/lib/commands/app-install.js +14 -7
- package/lib/commands/app-logs.js +13 -10
- package/lib/commands/app-shell.js +4 -1
- package/lib/commands/app-test.js +25 -19
- package/lib/commands/app.js +22 -10
- package/lib/commands/auth-config.js +6 -6
- package/lib/commands/auth-status.js +4 -3
- package/lib/commands/credential-env.js +4 -3
- package/lib/commands/credential-list.js +5 -4
- package/lib/commands/credential-push.js +4 -3
- package/lib/commands/datasource-unified-test-cli.js +495 -0
- package/lib/commands/datasource-unified-test-cli.options.js +149 -0
- package/lib/commands/datasource-validation-cli.js +129 -0
- package/lib/commands/datasource.js +105 -98
- package/lib/commands/deployment-list.js +6 -5
- package/lib/commands/dev-cli-handlers.js +122 -18
- package/lib/commands/dev-down.js +4 -3
- package/lib/commands/dev-init.js +231 -116
- package/lib/commands/dev-show-display.js +473 -0
- package/lib/commands/login-credentials.js +3 -2
- package/lib/commands/login-device.js +4 -3
- package/lib/commands/login.js +5 -4
- package/lib/commands/logout.js +8 -7
- package/lib/commands/parameters-validate.js +54 -0
- package/lib/commands/repair-datasource.js +314 -68
- package/lib/commands/repair-env-template.js +2 -2
- package/lib/commands/repair.js +21 -3
- package/lib/commands/secrets-list.js +23 -12
- package/lib/commands/secrets-remove-all.js +220 -0
- package/lib/commands/secrets-remove.js +21 -12
- package/lib/commands/secrets-set.js +21 -12
- package/lib/commands/secrets-validate.js +4 -4
- package/lib/commands/secure.js +10 -9
- package/lib/commands/service-user.js +26 -25
- package/lib/commands/test-e2e-external.js +27 -1
- package/lib/commands/up-common.js +3 -2
- package/lib/commands/up-dataplane.js +29 -16
- package/lib/commands/up-miso.js +19 -29
- package/lib/commands/upload.js +138 -39
- package/lib/commands/wizard-core-helpers.js +1 -1
- package/lib/commands/wizard-dataplane.js +4 -3
- package/lib/commands/wizard-helpers.js +3 -3
- package/lib/commands/wizard.js +2 -2
- package/lib/core/admin-secrets.js +14 -5
- package/lib/core/audit-logger.js +12 -4
- package/lib/core/config-attach-extensions.js +46 -0
- package/lib/core/config-runtime-paths.js +29 -0
- package/lib/core/config.js +55 -56
- package/lib/core/diff.js +3 -2
- package/lib/core/ensure-encryption-key.js +1 -1
- package/lib/core/secrets-ensure-infra.js +77 -0
- package/lib/core/secrets-ensure.js +120 -64
- package/lib/core/secrets-env-write.js +35 -7
- package/lib/core/secrets-infra-placeholder-sync.js +61 -0
- package/lib/core/secrets.js +200 -37
- package/lib/core/templates-env.js +4 -3
- package/lib/datasource/abac-validator.js +1 -10
- package/lib/datasource/deploy.js +75 -53
- package/lib/datasource/field-reference-validator.js +9 -6
- package/lib/datasource/integration-context.js +63 -0
- package/lib/datasource/list.js +8 -7
- package/lib/datasource/log-viewer.js +84 -53
- package/lib/datasource/resolve-app.js +4 -4
- package/lib/datasource/test-e2e.js +95 -146
- package/lib/datasource/test-integration.js +114 -122
- package/lib/datasource/unified-validation-run-body.js +65 -0
- package/lib/datasource/unified-validation-run-post.js +23 -0
- package/lib/datasource/unified-validation-run-resolve.js +43 -0
- package/lib/datasource/unified-validation-run.js +92 -0
- package/lib/datasource/validate.js +157 -13
- package/lib/deployment/deployer.js +4 -3
- package/lib/deployment/environment.js +7 -6
- package/lib/deployment/push.js +17 -8
- package/lib/external-system/delete.js +4 -3
- package/lib/external-system/deploy.js +131 -53
- package/lib/external-system/download-helpers.js +1 -1
- package/lib/external-system/download.js +7 -6
- package/lib/external-system/generator.js +92 -6
- package/lib/external-system/integration-test-dispatch.js +26 -0
- package/lib/external-system/test-execution.js +5 -1
- package/lib/external-system/test-helpers.js +0 -4
- package/lib/external-system/test-system-level-helpers.js +110 -0
- package/lib/external-system/test-system-level.js +83 -44
- package/lib/external-system/test.js +59 -8
- package/lib/generator/builders.js +23 -11
- package/lib/generator/deploy-manifest-azure-kv.js +81 -0
- package/lib/generator/external.js +16 -4
- package/lib/generator/helpers.js +58 -3
- package/lib/generator/index.js +4 -0
- package/lib/generator/split-readme.js +12 -7
- package/lib/generator/split-variables.js +2 -1
- package/lib/generator/split.js +1 -1
- package/lib/generator/wizard-readme.js +3 -3
- package/lib/generator/wizard.js +8 -8
- package/lib/infrastructure/compose.js +60 -6
- package/lib/infrastructure/helpers.js +201 -29
- package/lib/infrastructure/index.js +28 -17
- package/lib/infrastructure/services.js +21 -15
- package/lib/internal/fs-real-sync.js +104 -0
- package/lib/internal/node-fs.js +98 -0
- package/lib/parameters/database-secret-values.js +173 -0
- package/lib/parameters/infra-kv-discovery.js +121 -0
- package/lib/parameters/infra-parameter-catalog.js +458 -0
- package/lib/parameters/infra-parameter-validate.js +64 -0
- package/lib/schema/application-schema.json +37 -17
- package/lib/schema/datasource-test-run.schema.json +493 -0
- package/lib/schema/deployment-rules.yaml +102 -63
- package/lib/schema/external-datasource.schema.json +1200 -442
- package/lib/schema/external-system.schema.json +181 -5
- package/lib/schema/flag-map-validation-run.json +31 -0
- package/lib/schema/infra-parameter.schema.json +106 -0
- package/lib/schema/infra.parameter.yaml +421 -0
- package/lib/schema/type/credential-auth-templates.json +40 -0
- package/lib/schema/type/document-storage.json +213 -0
- package/lib/schema/type/message-service.json +123 -0
- package/lib/schema/type/vector-store.json +88 -0
- package/lib/utils/aifabrix-runtime-config-dir.js +132 -0
- package/lib/utils/api-error-handler.js +2 -2
- package/lib/utils/api.js +49 -14
- package/lib/utils/app-register-api.js +3 -2
- package/lib/utils/app-register-auth.js +1 -1
- package/lib/utils/app-register-config.js +4 -4
- package/lib/utils/app-register-display.js +3 -2
- package/lib/utils/app-register-validator.js +3 -2
- package/lib/utils/app-run-containers.js +26 -22
- package/lib/utils/app-scoped-config.js +31 -0
- package/lib/utils/app-service-env-from-builder.js +164 -0
- package/lib/utils/build-copy.js +1 -1
- package/lib/utils/build-helpers.js +20 -20
- package/lib/utils/build-resolve-image.js +165 -0
- package/lib/utils/cli-layout-chalk.js +8 -0
- package/lib/utils/cli-test-layout-chalk.js +267 -0
- package/lib/utils/cli-utils.js +88 -11
- package/lib/utils/compose-db-passwords.js +138 -0
- package/lib/utils/compose-generate-docker-compose.js +216 -0
- package/lib/utils/compose-generator.js +197 -291
- package/lib/utils/compose-miso-env.js +18 -0
- package/lib/utils/compose-traefik-ingress-base.js +158 -0
- package/lib/utils/config-paths.js +166 -7
- package/lib/utils/config-scoped-resources-preference.js +41 -0
- package/lib/utils/controller-deployment-outcome.js +68 -0
- package/lib/utils/credential-display.js +2 -2
- package/lib/utils/dataplane-pipeline-warning.js +4 -3
- package/lib/utils/datasource-test-run-capability-scope.js +43 -0
- package/lib/utils/datasource-test-run-debug-display.js +137 -0
- package/lib/utils/datasource-test-run-debug-slice.js +93 -0
- package/lib/utils/datasource-test-run-display.js +442 -0
- package/lib/utils/datasource-test-run-exit.js +58 -0
- package/lib/utils/datasource-test-run-legacy-adapter.js +93 -0
- package/lib/utils/datasource-test-run-report-version.js +51 -0
- package/lib/utils/datasource-test-run-schema-sync.js +59 -0
- package/lib/utils/datasource-test-run-tty-log.js +81 -0
- package/lib/utils/datasource-validation-watch.js +266 -0
- package/lib/utils/declarative-url-ports.js +47 -0
- package/lib/utils/derive-env-key-from-client-id.js +41 -0
- package/lib/utils/dev-ca-install.js +185 -23
- package/lib/utils/dev-cert-helper.js +266 -17
- package/lib/utils/dev-hosts-helper.js +307 -0
- package/lib/utils/dev-init-cert-hints.js +37 -0
- package/lib/utils/dev-init-health-messages.js +52 -0
- package/lib/utils/dev-init-resolve.js +86 -0
- package/lib/utils/dev-init-ssh-merge.js +65 -0
- package/lib/utils/dev-ssh-config-helper.js +196 -0
- package/lib/utils/dev-user-groups.js +93 -0
- package/lib/utils/docker-build.js +42 -17
- package/lib/utils/docker-exec.js +28 -0
- package/lib/utils/docker-manifest-public-port.js +116 -0
- package/lib/utils/docker-not-running-hint.js +52 -0
- package/lib/utils/docker.js +98 -11
- package/lib/utils/ensure-dev-certs-for-remote-docker.js +192 -0
- package/lib/utils/env-config-loader.js +10 -91
- package/lib/utils/env-copy.js +19 -10
- package/lib/utils/env-map.js +35 -8
- package/lib/utils/env-template.js +2 -2
- package/lib/utils/environment-scoped-resources.js +144 -0
- package/lib/utils/error-formatter.js +92 -13
- package/lib/utils/error-formatters/http-status-errors.js +6 -5
- package/lib/utils/error-formatters/network-errors.js +2 -1
- package/lib/utils/error-formatters/permission-errors.js +2 -1
- package/lib/utils/error-formatters/validation-errors.js +2 -1
- package/lib/utils/external-readme.js +8 -1
- package/lib/utils/external-system-display.js +234 -136
- package/lib/utils/external-system-local-test-tty.js +389 -0
- package/lib/utils/external-system-readiness-core.js +377 -0
- package/lib/utils/external-system-readiness-deploy-display.js +270 -0
- package/lib/utils/external-system-readiness-display-internals.js +150 -0
- package/lib/utils/external-system-readiness-display.js +186 -0
- package/lib/utils/external-system-test-helpers.js +24 -6
- package/lib/utils/external-system-validators.js +30 -12
- package/lib/utils/health-check-url.js +119 -0
- package/lib/utils/health-check.js +59 -25
- package/lib/utils/help-builder.js +11 -8
- package/lib/utils/image-version.js +4 -8
- package/lib/utils/infra-containers.js +4 -7
- package/lib/utils/infra-env-defaults.js +162 -0
- package/lib/utils/infra-status-display.js +167 -0
- package/lib/utils/infra-status.js +16 -8
- package/lib/utils/local-secrets.js +3 -4
- package/lib/utils/paths.js +134 -47
- package/lib/utils/port-resolver.js +10 -23
- package/lib/utils/redis-env-scope.js +62 -0
- package/lib/utils/register-aifabrix-shell-env.js +204 -0
- package/lib/utils/remote-builder-validation.js +99 -0
- package/lib/utils/remote-dev-auth.js +117 -21
- package/lib/utils/remote-docker-env.js +67 -15
- package/lib/utils/remote-secrets-loader.js +13 -4
- package/lib/utils/resolve-docker-image-ref.js +124 -0
- package/lib/utils/schema-loader.js +22 -9
- package/lib/utils/secrets-bash-kv.js +25 -0
- package/lib/utils/secrets-generator.js +169 -49
- package/lib/utils/secrets-helpers.js +70 -59
- package/lib/utils/secrets-kv-scope.js +60 -0
- package/lib/utils/secrets-utils.js +32 -38
- package/lib/utils/secrets-validation.js +3 -1
- package/lib/utils/secrets-yaml-preserve.js +109 -0
- package/lib/utils/ssh-key-helper.js +4 -2
- package/lib/utils/template-helpers.js +2 -2
- package/lib/utils/test-log-writer.js +3 -3
- package/lib/utils/token-manager.js +1 -2
- package/lib/utils/url-declarative-public-base.js +188 -0
- package/lib/utils/url-declarative-resolve-build.js +493 -0
- package/lib/utils/url-declarative-resolve-load-doc.js +51 -0
- package/lib/utils/url-declarative-resolve.js +220 -0
- package/lib/utils/url-declarative-token-parse.js +74 -0
- package/lib/utils/url-declarative-url-flags.js +50 -0
- package/lib/utils/url-declarative-vdir-inactive-env.js +99 -0
- package/lib/utils/url-public-path-prefix.js +34 -0
- package/lib/utils/urls-local-registry.js +220 -0
- package/lib/utils/validation-report-tty-kit.js +77 -0
- package/lib/utils/validation-run-poll.js +89 -0
- package/lib/utils/validation-run-post-retry.js +73 -0
- package/lib/utils/validation-run-request.js +98 -0
- package/lib/utils/variable-transformer.js +21 -4
- package/lib/utils/yaml-preserve.js +33 -14
- package/lib/validation/datasource-warnings.js +56 -0
- package/lib/validation/env-template-auth.js +1 -1
- package/lib/validation/external-manifest-validator.js +27 -7
- package/lib/validation/validate-display.js +37 -31
- package/lib/validation/validate.js +4 -13
- package/lib/validation/validator-unresolved-placeholders.js +98 -0
- package/lib/validation/validator.js +22 -65
- package/lib/validation/wizard-config-validator.js +2 -1
- package/package.json +7 -3
- package/scripts/check-datasource-test-run-schema-sync.js +34 -0
- package/scripts/diagnose-cli.js +150 -0
- package/scripts/install-local.js +304 -55
- package/templates/README.md +15 -2
- package/templates/applications/dataplane/application.yaml +52 -2
- package/templates/applications/dataplane/env.template +75 -17
- package/templates/applications/dataplane/rbac.yaml +8 -0
- package/templates/applications/keycloak/application.yaml +9 -1
- package/templates/applications/keycloak/env.template +15 -6
- package/templates/applications/miso-controller/application.yaml +10 -2
- package/templates/applications/miso-controller/env.template +42 -12
- package/templates/applications/miso-controller/rbac.yaml +5 -0
- package/templates/external-system/README.md.hbs +20 -7
- package/templates/external-system/deploy.js.hbs +5 -5
- package/templates/external-system/external-datasource.yaml.hbs +197 -118
- package/templates/infra/compose.yaml.hbs +20 -4
- package/templates/python/docker-compose.hbs +16 -0
- package/templates/typescript/docker-compose.hbs +16 -0
- package/lib/api/external-test.api.js +0 -111
- package/lib/schema/env-config.yaml +0 -60
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Datasource E2E test
|
|
3
|
-
* @fileoverview Datasource E2E
|
|
2
|
+
* Datasource E2E test — unified POST /api/v1/validation/run (runType=e2e).
|
|
3
|
+
* @fileoverview Datasource E2E via DatasourceTestRun envelope
|
|
4
4
|
* @author AI Fabrix Team
|
|
5
5
|
* @version 2.0.0
|
|
6
6
|
*/
|
|
7
|
-
/* eslint-disable max-statements -- Auth setup, API call, polling, debug log */
|
|
8
7
|
|
|
9
8
|
const path = require('path');
|
|
10
9
|
const fs = require('fs').promises;
|
|
@@ -12,19 +11,24 @@ const chalk = require('chalk');
|
|
|
12
11
|
const logger = require('../utils/logger');
|
|
13
12
|
const { getIntegrationPath } = require('../utils/paths');
|
|
14
13
|
const { resolveAppKeyForDatasource } = require('./resolve-app');
|
|
15
|
-
const {
|
|
16
|
-
const {
|
|
17
|
-
const {
|
|
18
|
-
const {
|
|
14
|
+
const { infoLine } = require('../utils/cli-test-layout-chalk');
|
|
15
|
+
const { runUnifiedDatasourceValidation } = require('./unified-validation-run');
|
|
16
|
+
const { includeDebugForRequest } = require('../utils/validation-run-request');
|
|
17
|
+
const { e2eShapeFromEnvelope } = require('../utils/datasource-test-run-legacy-adapter');
|
|
19
18
|
const { writeTestLog } = require('../utils/test-log-writer');
|
|
20
19
|
|
|
21
|
-
const DEFAULT_POLL_INTERVAL_MS = 2500;
|
|
22
20
|
const DEFAULT_POLL_TIMEOUT_MS = 15 * 60 * 1000;
|
|
23
21
|
|
|
22
|
+
function logE2eDatasourceBanner(datasourceKey, verbose) {
|
|
23
|
+
if (!verbose) return;
|
|
24
|
+
logger.log('');
|
|
25
|
+
logger.log(infoLine(`🧪 Running E2E test for datasource: ${datasourceKey}`));
|
|
26
|
+
}
|
|
27
|
+
|
|
24
28
|
/**
|
|
25
29
|
* Resolve primaryKeyValue for request body: string as-is, or read and parse JSON from @path
|
|
26
|
-
* @param {string} [value]
|
|
27
|
-
* @returns {Promise<string|Object|null>}
|
|
30
|
+
* @param {string} [value]
|
|
31
|
+
* @returns {Promise<string|Object|null>}
|
|
28
32
|
*/
|
|
29
33
|
async function resolvePrimaryKeyValue(value) {
|
|
30
34
|
if (value === null || value === undefined || value === '') return null;
|
|
@@ -37,174 +41,119 @@ async function resolvePrimaryKeyValue(value) {
|
|
|
37
41
|
return str;
|
|
38
42
|
}
|
|
39
43
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
* @param {Object} options - Command options
|
|
43
|
-
* @returns {Promise<Object>} Request body
|
|
44
|
-
*/
|
|
45
|
-
async function buildE2EBody(options) {
|
|
46
|
-
const body = {};
|
|
47
|
-
if (options.debug) body.includeDebug = true;
|
|
48
|
-
if (options.verbose) body.audit = true;
|
|
49
|
-
if (options.testCrud === true) body.testCrud = true;
|
|
50
|
-
if (options.recordId !== undefined && options.recordId !== null && options.recordId !== '') body.recordId = String(options.recordId);
|
|
51
|
-
if (options.cleanup === false) body.cleanup = false;
|
|
52
|
-
else if (options.cleanup === true) body.cleanup = true;
|
|
53
|
-
const pk = await resolvePrimaryKeyValue(options.primaryKeyValue);
|
|
54
|
-
if (pk !== null && pk !== undefined) body.primaryKeyValue = pk;
|
|
55
|
-
return body;
|
|
44
|
+
function e2eIntegrationLogDir(appKey) {
|
|
45
|
+
return path.dirname(getIntegrationPath(appKey));
|
|
56
46
|
}
|
|
57
47
|
|
|
58
48
|
/**
|
|
59
|
-
*
|
|
60
|
-
* @
|
|
61
|
-
* @param {string} sourceIdOrKey - Source ID or key
|
|
62
|
-
* @param {string} testRunId - Test run ID
|
|
63
|
-
* @param {Object} authConfig - Auth config
|
|
64
|
-
* @param {Object} opts - Poll options
|
|
65
|
-
* @param {number} [opts.intervalMs] - Poll interval (ms)
|
|
66
|
-
* @param {number} [opts.timeoutMs] - Max wait (ms)
|
|
67
|
-
* @param {boolean} [opts.verbose] - Log each poll
|
|
68
|
-
* @returns {Promise<Object>} Final poll result (status completed or failed)
|
|
49
|
+
* Throw when unified run failed, timed out, or needs async; optionally write debug log.
|
|
50
|
+
* @returns {Promise<void>}
|
|
69
51
|
*/
|
|
70
|
-
async function
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
52
|
+
async function throwIfUnifiedE2EBlocked(unifiedResult, appKey, options, requestMeta) {
|
|
53
|
+
if (unifiedResult.apiError) {
|
|
54
|
+
const msg =
|
|
55
|
+
unifiedResult.apiError.formattedError ||
|
|
56
|
+
unifiedResult.apiError.error ||
|
|
57
|
+
'E2E request failed';
|
|
58
|
+
if (options.debug) {
|
|
59
|
+
await writeTestLog(
|
|
60
|
+
appKey,
|
|
61
|
+
{ request: requestMeta, error: msg },
|
|
62
|
+
'test-e2e',
|
|
63
|
+
e2eIntegrationLogDir(appKey)
|
|
64
|
+
);
|
|
80
65
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
66
|
+
throw new Error(msg);
|
|
67
|
+
}
|
|
68
|
+
if (unifiedResult.pollTimedOut) {
|
|
69
|
+
const err = new Error('Report incomplete: timeout');
|
|
70
|
+
if (options.debug) {
|
|
71
|
+
await writeTestLog(
|
|
72
|
+
appKey,
|
|
73
|
+
{ request: requestMeta, error: err.message },
|
|
74
|
+
'test-e2e',
|
|
75
|
+
e2eIntegrationLogDir(appKey)
|
|
76
|
+
);
|
|
84
77
|
}
|
|
85
|
-
|
|
78
|
+
throw err;
|
|
79
|
+
}
|
|
80
|
+
if (unifiedResult.incompleteNoAsync) {
|
|
81
|
+
throw new Error(
|
|
82
|
+
'Report incomplete: async polling disabled (--no-async) but server returned partial report.'
|
|
83
|
+
);
|
|
86
84
|
}
|
|
87
|
-
throw new Error(
|
|
88
|
-
`E2E test run did not complete within ${timeoutMs / 1000}s (run ID: ${testRunId})`
|
|
89
|
-
);
|
|
90
85
|
}
|
|
91
86
|
|
|
92
87
|
/**
|
|
93
|
-
* Run E2E test for one datasource (
|
|
94
|
-
* Default: async start + polling until completed/failed. Use options.async === false for sync.
|
|
95
|
-
*
|
|
88
|
+
* Run E2E test for one datasource (unified validation API; deployment auth like test-integration).
|
|
96
89
|
* @async
|
|
97
|
-
* @param {string} datasourceKey
|
|
98
|
-
* @param {Object} options
|
|
99
|
-
* @param {
|
|
100
|
-
* @
|
|
101
|
-
* @param {boolean} [options.debug] - Include debug, write log file
|
|
102
|
-
* @param {boolean} [options.verbose] - Verbose output (e.g. poll progress)
|
|
103
|
-
* @param {boolean} [options.async] - If false, use sync mode (no polling). Default true.
|
|
104
|
-
* @param {boolean} [options.testCrud] - Set body testCrud true
|
|
105
|
-
* @param {string} [options.recordId] - Set body recordId
|
|
106
|
-
* @param {boolean} [options.cleanup] - Set body cleanup (default true)
|
|
107
|
-
* @param {string} [options.primaryKeyValue] - Set body primaryKeyValue (string or @path to JSON)
|
|
108
|
-
* @param {number} [options.pollIntervalMs] - Poll interval in ms (default 2500)
|
|
109
|
-
* @param {number} [options.pollTimeoutMs] - Poll timeout in ms (default 15 min)
|
|
110
|
-
* @returns {Promise<Object>} E2E test result (steps, success, error, etc.)
|
|
90
|
+
* @param {string} datasourceKey
|
|
91
|
+
* @param {Object} options
|
|
92
|
+
* @param {boolean} [options.sync] - Publish local datasource JSON before validation when true
|
|
93
|
+
* @returns {Promise<Object>} Shape compatible with displayE2EResults (steps, success, status)
|
|
111
94
|
*/
|
|
112
95
|
async function runDatasourceTestE2E(datasourceKey, options = {}) {
|
|
113
96
|
if (!datasourceKey || typeof datasourceKey !== 'string') {
|
|
114
97
|
throw new Error('Datasource key is required');
|
|
115
98
|
}
|
|
116
99
|
const { appKey } = await resolveAppKeyForDatasource(datasourceKey, options.app);
|
|
117
|
-
const controllerUrl = await resolveControllerUrl();
|
|
118
|
-
const { resolveEnvironment } = require('../core/config');
|
|
119
|
-
const environment = options.environment || await resolveEnvironment();
|
|
120
|
-
const authConfig = await getDeviceOnlyAuth(controllerUrl);
|
|
121
|
-
const dataplaneUrl = await resolveDataplaneUrl(controllerUrl, environment, authConfig);
|
|
122
100
|
|
|
123
|
-
|
|
101
|
+
logE2eDatasourceBanner(datasourceKey, options.verbose);
|
|
102
|
+
|
|
103
|
+
const pk = await resolvePrimaryKeyValue(options.primaryKeyValue);
|
|
104
|
+
const timeoutRaw =
|
|
105
|
+
options.timeout !== undefined && options.timeout !== null && options.timeout !== ''
|
|
106
|
+
? parseInt(String(options.timeout), 10)
|
|
107
|
+
: options.pollTimeoutMs;
|
|
108
|
+
const timeoutMs =
|
|
109
|
+
Number.isFinite(timeoutRaw) && timeoutRaw > 0 ? timeoutRaw : DEFAULT_POLL_TIMEOUT_MS;
|
|
124
110
|
|
|
125
|
-
const body = await buildE2EBody(options);
|
|
126
|
-
const useAsync = options.async !== false;
|
|
127
111
|
const requestMeta = {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
includeDebug: options.debug,
|
|
112
|
+
datasourceKey,
|
|
113
|
+
runType: 'e2e',
|
|
114
|
+
includeDebug: includeDebugForRequest(options.debug),
|
|
131
115
|
testCrud: options.testCrud,
|
|
132
116
|
recordId: options.recordId,
|
|
133
117
|
cleanup: options.cleanup,
|
|
134
|
-
primaryKeyValue:
|
|
118
|
+
primaryKeyValue: pk !== undefined && pk !== null
|
|
135
119
|
};
|
|
136
120
|
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
useAsync,
|
|
121
|
+
const unifiedResult = await runUnifiedDatasourceValidation(datasourceKey, {
|
|
122
|
+
app: options.app,
|
|
123
|
+
environment: options.environment,
|
|
124
|
+
runType: 'e2e',
|
|
125
|
+
debug: options.debug,
|
|
143
126
|
verbose: options.verbose,
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
await writeTestLog(appKey, { request: requestMeta, error: error.message }, 'test-e2e', integrationDir);
|
|
155
|
-
}
|
|
156
|
-
throw error;
|
|
157
|
-
}
|
|
127
|
+
async: options.async !== false,
|
|
128
|
+
noAsync: options.async === false,
|
|
129
|
+
testCrud: options.testCrud,
|
|
130
|
+
recordId: options.recordId,
|
|
131
|
+
cleanup: options.cleanup,
|
|
132
|
+
primaryKeyValue: pk,
|
|
133
|
+
capabilityKey: options.capabilityKey,
|
|
134
|
+
timeout: timeoutMs,
|
|
135
|
+
sync: options.sync === true
|
|
136
|
+
});
|
|
158
137
|
|
|
159
|
-
|
|
160
|
-
const appPath = getIntegrationPath(appKey);
|
|
161
|
-
const integrationDir = path.dirname(appPath);
|
|
162
|
-
const logPath = await writeTestLog(appKey, { request: requestMeta, response: data }, 'test-e2e', integrationDir);
|
|
163
|
-
logger.log(chalk.gray(` Debug log: ${logPath}`));
|
|
164
|
-
}
|
|
138
|
+
await throwIfUnifiedE2EBlocked(unifiedResult, appKey, options, requestMeta);
|
|
165
139
|
|
|
166
|
-
|
|
167
|
-
}
|
|
140
|
+
const display = e2eShapeFromEnvelope(unifiedResult.envelope);
|
|
141
|
+
Object.assign(display, { datasourceTestRun: unifiedResult.envelope });
|
|
168
142
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
* @param {Object} opts.body - Request body
|
|
176
|
-
* @param {boolean} opts.useAsync - Whether to use async + poll
|
|
177
|
-
* @param {boolean} opts.verbose - Verbose poll progress
|
|
178
|
-
* @param {number} [opts.pollIntervalMs] - Override poll interval (ms)
|
|
179
|
-
* @param {number} [opts.pollTimeoutMs] - Override poll timeout (ms)
|
|
180
|
-
* @returns {Promise<Object>} Final result data
|
|
181
|
-
*/
|
|
182
|
-
/* eslint-disable-next-line max-params -- single opts object; destructuring in body */
|
|
183
|
-
async function executeE2EWithOptionalPoll(opts) {
|
|
184
|
-
const { dataplaneUrl, datasourceKey, authConfig, body, useAsync, verbose, pollIntervalMs, pollTimeoutMs } = opts;
|
|
185
|
-
const response = await testDatasourceE2E(dataplaneUrl, datasourceKey, authConfig, body, {
|
|
186
|
-
asyncRun: useAsync
|
|
187
|
-
});
|
|
188
|
-
let data = response.data || response;
|
|
189
|
-
const runId = (data?.testRunId !== null && data?.testRunId !== undefined)
|
|
190
|
-
? (typeof data.testRunId === 'string' ? data.testRunId : data.testRunId.id || data.testRunId.key)
|
|
191
|
-
: null;
|
|
192
|
-
if (useAsync && runId) {
|
|
193
|
-
data = await pollE2ETestRun(
|
|
194
|
-
dataplaneUrl,
|
|
195
|
-
datasourceKey,
|
|
196
|
-
runId,
|
|
197
|
-
authConfig,
|
|
198
|
-
{
|
|
199
|
-
intervalMs: pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS,
|
|
200
|
-
timeoutMs: pollTimeoutMs ?? DEFAULT_POLL_TIMEOUT_MS,
|
|
201
|
-
verbose
|
|
202
|
-
}
|
|
143
|
+
if (options.debug) {
|
|
144
|
+
const logPath = await writeTestLog(
|
|
145
|
+
appKey,
|
|
146
|
+
{ request: requestMeta, response: unifiedResult.envelope },
|
|
147
|
+
'test-e2e',
|
|
148
|
+
e2eIntegrationLogDir(appKey)
|
|
203
149
|
);
|
|
150
|
+
logger.log(chalk.gray(` Debug log: ${logPath}`));
|
|
204
151
|
}
|
|
205
|
-
|
|
152
|
+
|
|
153
|
+
return display;
|
|
206
154
|
}
|
|
207
155
|
|
|
208
156
|
module.exports = {
|
|
209
|
-
runDatasourceTestE2E
|
|
157
|
+
runDatasourceTestE2E,
|
|
158
|
+
resolvePrimaryKeyValue
|
|
210
159
|
};
|
|
@@ -1,174 +1,166 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Datasource integration test
|
|
2
|
+
* Datasource integration test — unified dataplane validation (runType=integration).
|
|
3
3
|
* @fileoverview Datasource integration test logic
|
|
4
4
|
* @author AI Fabrix Team
|
|
5
5
|
* @version 2.0.0
|
|
6
6
|
*/
|
|
7
|
-
/* eslint-disable max-lines-per-function,max-statements,complexity -- Load config, resolve datasource, call pipeline test */
|
|
8
7
|
|
|
9
|
-
const path = require('path');
|
|
10
8
|
const chalk = require('chalk');
|
|
11
9
|
const logger = require('../utils/logger');
|
|
12
|
-
const { getIntegrationPath } = require('../utils/paths');
|
|
13
10
|
const { resolveAppKeyForDatasource } = require('./resolve-app');
|
|
14
|
-
const {
|
|
15
|
-
const {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
const { infoLine } = require('../utils/cli-test-layout-chalk');
|
|
12
|
+
const {
|
|
13
|
+
getSystemKeyFromAppKey,
|
|
14
|
+
findDatasourceFileByKey
|
|
15
|
+
} = require('./integration-context');
|
|
16
|
+
const { runUnifiedDatasourceValidation } = require('./unified-validation-run');
|
|
17
|
+
const { integrationResultFromEnvelope } = require('../utils/datasource-test-run-legacy-adapter');
|
|
19
18
|
const { writeTestLog } = require('../utils/test-log-writer');
|
|
20
|
-
const testHelpers = require('../utils/external-system-test-helpers');
|
|
21
|
-
const fs = require('fs').promises;
|
|
22
19
|
|
|
23
20
|
/**
|
|
24
|
-
*
|
|
25
|
-
* @param {string} appKey - Integration app key
|
|
21
|
+
* @param {string} appKey - Integration folder name (same as --app; system key in publish flows)
|
|
26
22
|
* @returns {Promise<string>} systemKey
|
|
27
23
|
*/
|
|
28
|
-
async function
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
:
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
24
|
+
async function getSystemKeyFromAppKeyExport(appKey) {
|
|
25
|
+
return getSystemKeyFromAppKey(appKey);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function legacyFailureShell(datasourceKey, systemKey, error, datasourceTestRun, runMeta) {
|
|
29
|
+
return {
|
|
30
|
+
key: datasourceKey,
|
|
31
|
+
systemKey,
|
|
32
|
+
success: false,
|
|
33
|
+
skipped: false,
|
|
34
|
+
validationResults: {},
|
|
35
|
+
fieldMappingResults: {},
|
|
36
|
+
endpointTestResults: {},
|
|
37
|
+
error,
|
|
38
|
+
datasourceTestRun,
|
|
39
|
+
runMeta
|
|
40
|
+
};
|
|
43
41
|
}
|
|
44
42
|
|
|
45
43
|
/**
|
|
46
|
-
*
|
|
47
|
-
* @param {string} appPath - Integration app directory path
|
|
48
|
-
* @param {string} schemaBasePath - Schema base path (relative or absolute)
|
|
49
|
-
* @param {string[]} datasourceFiles - List of datasource filenames from application config
|
|
50
|
-
* @param {string} datasourceKey - Datasource key to find
|
|
51
|
-
* @returns {string|null} Filename if found, null otherwise
|
|
44
|
+
* @returns {{ body: Object, apiErrMsg?: string }|null}
|
|
52
45
|
*/
|
|
53
|
-
function
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
46
|
+
function integrationEarlyExitBody(datasourceKey, systemKey, unifiedResult, runMeta) {
|
|
47
|
+
if (unifiedResult.apiError) {
|
|
48
|
+
const errMsg =
|
|
49
|
+
unifiedResult.apiError.formattedError ||
|
|
50
|
+
unifiedResult.apiError.error ||
|
|
51
|
+
'Request failed';
|
|
52
|
+
return {
|
|
53
|
+
body: legacyFailureShell(datasourceKey, systemKey, errMsg, null, runMeta),
|
|
54
|
+
apiErrMsg: errMsg
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
if (unifiedResult.pollTimedOut) {
|
|
58
|
+
return {
|
|
59
|
+
body: legacyFailureShell(
|
|
60
|
+
datasourceKey,
|
|
61
|
+
systemKey,
|
|
62
|
+
'Report incomplete: timeout',
|
|
63
|
+
unifiedResult.envelope,
|
|
64
|
+
runMeta
|
|
65
|
+
)
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
if (unifiedResult.incompleteNoAsync) {
|
|
69
|
+
return {
|
|
70
|
+
body: legacyFailureShell(
|
|
71
|
+
datasourceKey,
|
|
72
|
+
systemKey,
|
|
73
|
+
'Report incomplete (async required)',
|
|
74
|
+
unifiedResult.envelope,
|
|
75
|
+
runMeta
|
|
76
|
+
)
|
|
77
|
+
};
|
|
67
78
|
}
|
|
68
79
|
return null;
|
|
69
80
|
}
|
|
70
81
|
|
|
71
82
|
/**
|
|
72
|
-
* Run integration test for one datasource
|
|
83
|
+
* Run integration test for one datasource (unified validation API).
|
|
73
84
|
* @async
|
|
74
85
|
* @param {string} datasourceKey - Datasource key
|
|
75
86
|
* @param {Object} options - Options
|
|
76
87
|
* @param {string} [options.app] - App key (or resolve from cwd)
|
|
77
88
|
* @param {string} [options.payload] - Path to custom payload file
|
|
78
89
|
* @param {string} [options.environment] - Environment (dev, tst, pro)
|
|
79
|
-
* @param {boolean} [options.
|
|
80
|
-
* @param {
|
|
81
|
-
* @
|
|
90
|
+
* @param {boolean} [options.verbose] - explain=true on request
|
|
91
|
+
* @param {boolean|string} [options.debug] - Truthy enables includeDebug and log file; string `summary`|`full`|`raw` selects TTY appendix (CLI)
|
|
92
|
+
* @param {number|string} [options.timeout] - Aggregate timeout ms
|
|
93
|
+
* @param {boolean} [options.sync] - Publish local datasource JSON before validation when true
|
|
94
|
+
* @returns {Promise<Object>} Legacy-shaped result + datasourceTestRun / runMeta when present
|
|
82
95
|
*/
|
|
96
|
+
function logIntegrationDatasourceBanner(datasourceKey, systemKey, verbose) {
|
|
97
|
+
if (!verbose) return;
|
|
98
|
+
logger.log('');
|
|
99
|
+
logger.log(infoLine(`📡 Testing datasource: ${datasourceKey} (system: ${systemKey})`));
|
|
100
|
+
}
|
|
101
|
+
|
|
83
102
|
async function runDatasourceTestIntegration(datasourceKey, options = {}) {
|
|
84
103
|
if (!datasourceKey || typeof datasourceKey !== 'string') {
|
|
85
104
|
throw new Error('Datasource key is required');
|
|
86
105
|
}
|
|
87
106
|
const { appKey } = await resolveAppKeyForDatasource(datasourceKey, options.app);
|
|
88
107
|
const systemKey = await getSystemKeyFromAppKey(appKey);
|
|
89
|
-
const appPath = getIntegrationPath(appKey);
|
|
90
|
-
const config = loadConfigFile(resolveApplicationConfigPath(appPath));
|
|
91
|
-
const schemaBasePath = config.externalIntegration?.schemaBasePath || './';
|
|
92
|
-
const datasourceFiles = config.externalIntegration?.dataSources || [];
|
|
93
|
-
let datasourceFile = datasourceFiles.find(f => {
|
|
94
|
-
const base = path.basename(f, path.extname(f));
|
|
95
|
-
return base === datasourceKey || base.includes(datasourceKey);
|
|
96
|
-
});
|
|
97
|
-
if (!datasourceFile) {
|
|
98
|
-
datasourceFile = findDatasourceFileByKey(appPath, schemaBasePath, datasourceFiles, datasourceKey);
|
|
99
|
-
}
|
|
100
|
-
if (!datasourceFile) {
|
|
101
|
-
throw new Error(`Datasource '${datasourceKey}' not found in application config`);
|
|
102
|
-
}
|
|
103
|
-
const datasourcePath = path.isAbsolute(schemaBasePath)
|
|
104
|
-
? path.join(schemaBasePath, datasourceFile)
|
|
105
|
-
: path.join(appPath, schemaBasePath, datasourceFile);
|
|
106
|
-
const datasource = loadConfigFile(datasourcePath);
|
|
107
|
-
if (datasource.key !== datasourceKey) {
|
|
108
|
-
throw new Error(`Datasource key mismatch: file has '${datasource.key}', expected '${datasourceKey}'`);
|
|
109
|
-
}
|
|
110
108
|
|
|
111
|
-
|
|
112
|
-
const { authConfig, dataplaneUrl } = await setupIntegrationTestAuth(appKey, options, configObj);
|
|
113
|
-
const customPayload = await testHelpers.loadCustomPayload(options.payload);
|
|
114
|
-
const payloadTemplate = testHelpers.determinePayloadTemplate(datasource, datasourceKey, customPayload);
|
|
115
|
-
if (!payloadTemplate) {
|
|
116
|
-
throw new Error(`No test payload found for datasource '${datasourceKey}'`);
|
|
117
|
-
}
|
|
109
|
+
logIntegrationDatasourceBanner(datasourceKey, systemKey, options.verbose);
|
|
118
110
|
|
|
119
|
-
|
|
111
|
+
const unifiedResult = await runUnifiedDatasourceValidation(datasourceKey, {
|
|
112
|
+
app: options.app,
|
|
113
|
+
environment: options.environment,
|
|
114
|
+
runType: 'integration',
|
|
115
|
+
payload: options.payload,
|
|
116
|
+
debug: options.debug,
|
|
117
|
+
verbose: options.verbose,
|
|
118
|
+
timeout: options.timeout,
|
|
119
|
+
async: true,
|
|
120
|
+
noAsync: false,
|
|
121
|
+
sync: options.sync === true
|
|
122
|
+
});
|
|
120
123
|
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
124
|
+
const runMeta = {
|
|
125
|
+
apiError: unifiedResult.apiError,
|
|
126
|
+
pollTimedOut: unifiedResult.pollTimedOut,
|
|
127
|
+
incompleteNoAsync: unifiedResult.incompleteNoAsync
|
|
128
|
+
};
|
|
126
129
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
options: { timeout }
|
|
136
|
-
});
|
|
137
|
-
} catch (error) {
|
|
138
|
-
const result = { key: datasourceKey, success: false, error: error.message };
|
|
139
|
-
if (options.debug) {
|
|
140
|
-
await writeTestLog(appKey, { request: { systemKey, datasourceKey }, error: error.message }, 'test-integration');
|
|
130
|
+
const early = integrationEarlyExitBody(datasourceKey, systemKey, unifiedResult, runMeta);
|
|
131
|
+
if (early) {
|
|
132
|
+
if (early.apiErrMsg && options.debug) {
|
|
133
|
+
await writeTestLog(
|
|
134
|
+
appKey,
|
|
135
|
+
{ request: { systemKey, datasourceKey }, error: early.apiErrMsg },
|
|
136
|
+
'test-integration'
|
|
137
|
+
);
|
|
141
138
|
}
|
|
142
|
-
return
|
|
139
|
+
return early.body;
|
|
143
140
|
}
|
|
144
141
|
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
systemKey,
|
|
150
|
-
success,
|
|
151
|
-
skipped: false,
|
|
152
|
-
validationResults: data.validationResults || {},
|
|
153
|
-
fieldMappingResults: data.fieldMappingResults || {},
|
|
154
|
-
endpointTestResults: data.endpointTestResults || {}
|
|
155
|
-
};
|
|
156
|
-
if (data.error) {
|
|
157
|
-
result.error = data.error;
|
|
158
|
-
}
|
|
142
|
+
const legacy = integrationResultFromEnvelope(unifiedResult.envelope, datasourceKey);
|
|
143
|
+
legacy.systemKey = systemKey;
|
|
144
|
+
legacy.datasourceTestRun = unifiedResult.envelope;
|
|
145
|
+
legacy.runMeta = { apiError: null, pollTimedOut: false, incompleteNoAsync: false };
|
|
159
146
|
|
|
160
|
-
if (options.debug) {
|
|
161
|
-
const logPath = await writeTestLog(
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
147
|
+
if (options.debug && unifiedResult.envelope) {
|
|
148
|
+
const logPath = await writeTestLog(
|
|
149
|
+
appKey,
|
|
150
|
+
{
|
|
151
|
+
request: { systemKey, datasourceKey, includeDebug: true },
|
|
152
|
+
response: unifiedResult.envelope
|
|
153
|
+
},
|
|
154
|
+
'test-integration'
|
|
155
|
+
);
|
|
165
156
|
logger.log(chalk.gray(` Debug log: ${logPath}`));
|
|
166
157
|
}
|
|
167
158
|
|
|
168
|
-
return
|
|
159
|
+
return legacy;
|
|
169
160
|
}
|
|
170
161
|
|
|
171
162
|
module.exports = {
|
|
172
163
|
runDatasourceTestIntegration,
|
|
173
|
-
getSystemKeyFromAppKey
|
|
164
|
+
getSystemKeyFromAppKey: getSystemKeyFromAppKeyExport,
|
|
165
|
+
findDatasourceFileByKey
|
|
174
166
|
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Build ValidationRunRequest body for unified datasource runs.
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 2.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
buildExternalDataSourceValidationRequest,
|
|
9
|
+
buildE2eOptionsFromCli,
|
|
10
|
+
includeDebugForRequest
|
|
11
|
+
} = require('../utils/validation-run-request');
|
|
12
|
+
const testHelpers = require('../utils/external-system-test-helpers');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param {Object} params
|
|
16
|
+
* @param {string} params.systemKey
|
|
17
|
+
* @param {string} params.datasourceKey
|
|
18
|
+
* @param {'test'|'integration'|'e2e'} params.runType
|
|
19
|
+
* @param {Object} params.datasource - Loaded datasource config
|
|
20
|
+
* @param {string} [params.payloadPath]
|
|
21
|
+
* @param {boolean} params.useAsync
|
|
22
|
+
* @param {Object} params.options - CLI options (debug, verbose, e2e fields, capabilityKey)
|
|
23
|
+
* @returns {Promise<import('../api/types/validation-run.types').ValidationRunRequestBody>}
|
|
24
|
+
*/
|
|
25
|
+
async function buildUnifiedValidationBody(params) {
|
|
26
|
+
const { systemKey, datasourceKey, runType, datasource, payloadPath, useAsync, options } = params;
|
|
27
|
+
|
|
28
|
+
let payloadTemplate;
|
|
29
|
+
if (payloadPath || runType === 'integration') {
|
|
30
|
+
const customPayload = await testHelpers.loadCustomPayload(payloadPath);
|
|
31
|
+
payloadTemplate = testHelpers.determinePayloadTemplate(datasource, datasourceKey, customPayload);
|
|
32
|
+
if (runType === 'integration' && !payloadTemplate) {
|
|
33
|
+
throw new Error(`No test payload found for datasource '${datasourceKey}'`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const e2eExtra = options.capabilityKey
|
|
38
|
+
? { capabilityKeys: [String(options.capabilityKey).trim()] }
|
|
39
|
+
: undefined;
|
|
40
|
+
const e2eOptions =
|
|
41
|
+
runType === 'e2e'
|
|
42
|
+
? buildE2eOptionsFromCli({
|
|
43
|
+
debug: options.debug,
|
|
44
|
+
verbose: options.verbose,
|
|
45
|
+
testCrud: options.testCrud,
|
|
46
|
+
recordId: options.recordId,
|
|
47
|
+
cleanup: options.cleanup,
|
|
48
|
+
primaryKeyValue: options.primaryKeyValue,
|
|
49
|
+
e2eOptionsExtra: e2eExtra
|
|
50
|
+
})
|
|
51
|
+
: undefined;
|
|
52
|
+
|
|
53
|
+
return buildExternalDataSourceValidationRequest({
|
|
54
|
+
systemKey,
|
|
55
|
+
datasourceKey,
|
|
56
|
+
runType,
|
|
57
|
+
payloadTemplate,
|
|
58
|
+
asyncRun: runType === 'e2e' && useAsync === true,
|
|
59
|
+
includeDebug: includeDebugForRequest(options.debug),
|
|
60
|
+
explain: options.verbose === true,
|
|
61
|
+
e2eOptions: e2eOptions && Object.keys(e2eOptions).length > 0 ? e2eOptions : undefined
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
module.exports = { buildUnifiedValidationBody };
|