@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,8 +1,9 @@
|
|
|
1
|
+
const { formatSuccessLine, formatSuccessParagraph } = require('../utils/cli-test-layout-chalk');
|
|
1
2
|
/**
|
|
2
3
|
* External System Deployment Module
|
|
3
4
|
*
|
|
4
5
|
* Handles deployment of external systems via controller pipeline.
|
|
5
|
-
*
|
|
6
|
+
* After deploy, fetches dataplane list + system for readiness summary.
|
|
6
7
|
*
|
|
7
8
|
* @fileoverview External system deployment for AI Fabrix Builder
|
|
8
9
|
* @author AI Fabrix Team
|
|
@@ -17,69 +18,116 @@ const { detectAppType } = require('../utils/paths');
|
|
|
17
18
|
const { logOfflinePathWhenType } = require('../utils/cli-utils');
|
|
18
19
|
const { resolveDataplaneUrl } = require('../utils/dataplane-resolver');
|
|
19
20
|
const { getExternalSystem } = require('../api/external-systems.api');
|
|
21
|
+
const { listDatasources } = require('../api/datasources-core.api');
|
|
22
|
+
const { testSystemViaPipeline } = require('../api/pipeline.api');
|
|
23
|
+
const { extractDatasources } = require('../datasource/list');
|
|
24
|
+
const { unwrapApiData } = require('../utils/external-system-readiness-core');
|
|
25
|
+
const { logDeployReadinessSummary } = require('../utils/external-system-readiness-deploy-display');
|
|
26
|
+
const { parseControllerDeploymentOutcome } = require('../utils/controller-deployment-outcome');
|
|
20
27
|
const { generateControllerManifest } = require('../generator/external-controller-manifest');
|
|
21
28
|
const { validateExternalSystemComplete } = require('../validation/validate');
|
|
22
29
|
const { displayValidationResults } = require('../validation/validate-display');
|
|
23
30
|
|
|
24
31
|
/**
|
|
25
|
-
*
|
|
32
|
+
* Lists datasources for a system and loads system record for docs URLs.
|
|
26
33
|
* @async
|
|
27
|
-
* @function displayDeploymentDocs
|
|
28
34
|
* @param {string} controllerUrl - Controller base URL
|
|
29
35
|
* @param {string} environment - Environment key
|
|
30
|
-
* @param {Object} authConfig -
|
|
31
|
-
* @param {string} systemKey -
|
|
36
|
+
* @param {Object} authConfig - Auth config
|
|
37
|
+
* @param {string} systemKey - System key
|
|
38
|
+
* @returns {Promise<{ dataplaneUrl: string, datasources: Object[], system: Object|null, error: Error|null }>}
|
|
32
39
|
*/
|
|
33
|
-
async function
|
|
40
|
+
async function fetchDataplaneDeployReadiness(controllerUrl, environment, authConfig, systemKey) {
|
|
41
|
+
let dataplaneUrl;
|
|
34
42
|
try {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
43
|
+
dataplaneUrl = await resolveDataplaneUrl(controllerUrl, environment, authConfig);
|
|
44
|
+
} catch (err) {
|
|
45
|
+
return { dataplaneUrl: null, datasources: [], system: null, error: err };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let datasources = [];
|
|
49
|
+
try {
|
|
50
|
+
const listRes = await listDatasources(dataplaneUrl, authConfig, {
|
|
51
|
+
sourceSystemIdOrKey: systemKey,
|
|
52
|
+
pageSize: 100
|
|
53
|
+
});
|
|
54
|
+
if (listRes.success && listRes.data) {
|
|
55
|
+
try {
|
|
56
|
+
datasources = extractDatasources(listRes);
|
|
57
|
+
} catch (e) {
|
|
58
|
+
logger.log(
|
|
59
|
+
chalk.yellow(
|
|
60
|
+
`ā Unable to parse datasources list from dataplane response: ${e && e.message ? e.message : 'unknown error'}`
|
|
61
|
+
)
|
|
62
|
+
);
|
|
63
|
+
datasources = [];
|
|
64
|
+
}
|
|
53
65
|
}
|
|
66
|
+
} catch (err) {
|
|
67
|
+
return { dataplaneUrl, datasources: [], system: null, error: err };
|
|
68
|
+
}
|
|
54
69
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
70
|
+
try {
|
|
71
|
+
const getRes = await getExternalSystem(dataplaneUrl, systemKey, authConfig);
|
|
72
|
+
const system = unwrapApiData(getRes);
|
|
73
|
+
return {
|
|
74
|
+
dataplaneUrl,
|
|
75
|
+
datasources,
|
|
76
|
+
system: system && typeof system === 'object' ? system : null,
|
|
77
|
+
error: null
|
|
78
|
+
};
|
|
79
|
+
} catch (err) {
|
|
80
|
+
if (datasources.length === 0) {
|
|
81
|
+
return { dataplaneUrl, datasources, system: null, error: err };
|
|
60
82
|
}
|
|
61
|
-
|
|
62
|
-
// Silently ignore: dataplane may be unreachable or docs not configured
|
|
83
|
+
return { dataplaneUrl, datasources, system: null, error: null };
|
|
63
84
|
}
|
|
64
85
|
}
|
|
65
86
|
|
|
66
87
|
/**
|
|
67
|
-
* Deploys via controller and
|
|
88
|
+
* Deploys via controller and prints readiness summary (config / deployment / runtime layers).
|
|
68
89
|
* @async
|
|
69
|
-
* @function executeDeployAndDisplay
|
|
70
90
|
* @param {Object} manifest - Controller manifest
|
|
71
91
|
* @param {string} controllerUrl - Controller base URL
|
|
72
92
|
* @param {string} environment - Environment key
|
|
73
93
|
* @param {Object} authConfig - Authentication configuration
|
|
74
|
-
* @param {Object} options - Deployment options
|
|
94
|
+
* @param {Object} options - Deployment options (poll, probe, probeTimeout)
|
|
75
95
|
* @returns {Promise<Object>} Deployment result
|
|
76
96
|
*/
|
|
97
|
+
/**
|
|
98
|
+
* @param {Object} deploymentOutcome - from parseControllerDeploymentOutcome
|
|
99
|
+
*/
|
|
100
|
+
function logImmediateControllerDeploymentOutcome(deploymentOutcome) {
|
|
101
|
+
if (deploymentOutcome.ok) {
|
|
102
|
+
logger.log(formatSuccessParagraph('Controller deployment OK'));
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
logger.log(chalk.red('\nā Controller deployment did not complete successfully'));
|
|
106
|
+
const parts = [deploymentOutcome.error, deploymentOutcome.message].filter(Boolean);
|
|
107
|
+
if (parts.length > 0) {
|
|
108
|
+
for (const line of parts) {
|
|
109
|
+
logger.log(chalk.red(` ${line}`));
|
|
110
|
+
}
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (deploymentOutcome.statusLabel) {
|
|
114
|
+
logger.log(
|
|
115
|
+
chalk.yellow(
|
|
116
|
+
` Controller status: ${deploymentOutcome.statusLabel} (no message or error in API response)`
|
|
117
|
+
)
|
|
118
|
+
);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
logger.log(chalk.gray(' See Deployment section below for details.'));
|
|
122
|
+
}
|
|
123
|
+
|
|
77
124
|
async function executeDeployAndDisplay(manifest, controllerUrl, environment, authConfig, options) {
|
|
78
125
|
const deployer = require('../deployment/deployer');
|
|
79
126
|
const pollOpts = {
|
|
80
127
|
poll: options.poll,
|
|
81
128
|
pollInterval: options.pollInterval !== undefined ? options.pollInterval : 500,
|
|
82
|
-
|
|
129
|
+
// External-system deploy only: ~10s poll window (matches controllerādataplane publish timeout). Not used for Azure/webapp deploy polling.
|
|
130
|
+
pollMaxAttempts: options.pollMaxAttempts !== undefined ? options.pollMaxAttempts : 22,
|
|
83
131
|
...options
|
|
84
132
|
};
|
|
85
133
|
const result = await deployer.deployToController(
|
|
@@ -89,17 +137,54 @@ async function executeDeployAndDisplay(manifest, controllerUrl, environment, aut
|
|
|
89
137
|
authConfig,
|
|
90
138
|
pollOpts
|
|
91
139
|
);
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
140
|
+
|
|
141
|
+
const deploymentOutcome = parseControllerDeploymentOutcome(result);
|
|
142
|
+
logImmediateControllerDeploymentOutcome(deploymentOutcome);
|
|
143
|
+
|
|
144
|
+
const ctx = await fetchDataplaneDeployReadiness(
|
|
145
|
+
controllerUrl,
|
|
146
|
+
environment,
|
|
147
|
+
authConfig,
|
|
148
|
+
manifest.key
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
let probeData = null;
|
|
152
|
+
if (options.probe && ctx.dataplaneUrl && !ctx.error) {
|
|
153
|
+
logger.log(chalk.blue('\nRunning runtime checks (--probe)...'));
|
|
154
|
+
try {
|
|
155
|
+
const pr = await testSystemViaPipeline(ctx.dataplaneUrl, manifest.key, authConfig, {}, {
|
|
156
|
+
timeout: options.probeTimeout || 120000
|
|
157
|
+
});
|
|
158
|
+
if (pr.success === false) {
|
|
159
|
+
logger.log(
|
|
160
|
+
chalk.yellow(`ā Probe request failed: ${pr.formattedError || pr.error || 'unknown error'}`)
|
|
161
|
+
);
|
|
162
|
+
} else {
|
|
163
|
+
probeData = unwrapApiData(pr);
|
|
164
|
+
}
|
|
165
|
+
} catch (e) {
|
|
166
|
+
logger.log(chalk.yellow(`ā Probe failed: ${e.message}`));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
logDeployReadinessSummary({
|
|
171
|
+
environment,
|
|
172
|
+
dataplaneUrl: ctx.dataplaneUrl,
|
|
173
|
+
manifest,
|
|
174
|
+
datasources: ctx.datasources,
|
|
175
|
+
systemFromDataplane: ctx.system,
|
|
176
|
+
fetchError: ctx.error,
|
|
177
|
+
deploymentOk: deploymentOutcome.ok,
|
|
178
|
+
deploymentDetail: deploymentOutcome.ok ? null : deploymentOutcome,
|
|
179
|
+
probeData
|
|
180
|
+
});
|
|
181
|
+
|
|
96
182
|
return result;
|
|
97
183
|
}
|
|
98
184
|
|
|
99
185
|
/**
|
|
100
186
|
* Prepares deployment configuration (auth, controller URL, environment)
|
|
101
187
|
* @async
|
|
102
|
-
* @function prepareDeploymentConfig
|
|
103
188
|
* @param {string} appName - Application name
|
|
104
189
|
* @param {Object} options - Deployment options
|
|
105
190
|
* @returns {Promise<Object>} Deployment configuration
|
|
@@ -119,16 +204,12 @@ async function prepareDeploymentConfig(appName, _options) {
|
|
|
119
204
|
|
|
120
205
|
/**
|
|
121
206
|
* Deploys external system via controller pipeline (same as regular apps)
|
|
122
|
-
* Uses unified controller pipeline - no direct dataplane calls
|
|
123
207
|
*
|
|
124
208
|
* @async
|
|
125
|
-
* @function deployExternalSystem
|
|
126
209
|
* @param {string} appName - Application name
|
|
127
210
|
* @param {Object} options - Deployment options
|
|
128
|
-
* @param {
|
|
129
|
-
* @param {
|
|
130
|
-
* @param {boolean} [options.poll] - Poll for deployment status
|
|
131
|
-
* @param {number} [options.pollInterval] - Polling interval in milliseconds (default: 500ms for external systems)
|
|
211
|
+
* @param {boolean} [options.probe] - Run dataplane validation/run after deploy
|
|
212
|
+
* @param {number} [options.probeTimeout] - Probe timeout ms (default 120000)
|
|
132
213
|
* @returns {Promise<Object>} Deployment result
|
|
133
214
|
* @throws {Error} If deployment fails
|
|
134
215
|
*/
|
|
@@ -139,7 +220,6 @@ async function deployExternalSystem(appName, options = {}) {
|
|
|
139
220
|
|
|
140
221
|
logger.log(chalk.blue(`\nš Deploying external system: ${appName}`));
|
|
141
222
|
|
|
142
|
-
// Step 0: Validate before deployment (same as validate command)
|
|
143
223
|
logger.log(chalk.blue('š Validating external system before deployment...'));
|
|
144
224
|
const validationResult = await validateExternalSystemComplete(appName, options);
|
|
145
225
|
|
|
@@ -148,15 +228,12 @@ async function deployExternalSystem(appName, options = {}) {
|
|
|
148
228
|
throw new Error('Validation failed. Fix errors before deploying.');
|
|
149
229
|
}
|
|
150
230
|
|
|
151
|
-
logger.log(
|
|
231
|
+
logger.log(formatSuccessLine('Local validation passed, proceeding with deployment...'));
|
|
152
232
|
|
|
153
|
-
// Step 1: Generate controller manifest (validated, ready for deployment)
|
|
154
233
|
const manifest = await generateControllerManifest(appName, options);
|
|
155
234
|
|
|
156
|
-
// Step 2: Get deployment configuration (auth, controller URL, etc.)
|
|
157
235
|
const { environment, controllerUrl, authConfig } = await prepareDeploymentConfig(appName, options);
|
|
158
236
|
|
|
159
|
-
// Step 3: Deploy via controller pipeline (same as regular apps)
|
|
160
237
|
const result = await executeDeployAndDisplay(
|
|
161
238
|
manifest,
|
|
162
239
|
controllerUrl,
|
|
@@ -175,6 +252,7 @@ async function deployExternalSystem(appName, options = {}) {
|
|
|
175
252
|
}
|
|
176
253
|
|
|
177
254
|
module.exports = {
|
|
178
|
-
deployExternalSystem
|
|
255
|
+
deployExternalSystem,
|
|
256
|
+
executeDeployAndDisplay,
|
|
257
|
+
fetchDataplaneDeployReadiness
|
|
179
258
|
};
|
|
180
|
-
|
|
@@ -73,7 +73,7 @@ function generateReadme(systemKey, application, dataSources) {
|
|
|
73
73
|
return {
|
|
74
74
|
entityType: datasourceKeyOnly,
|
|
75
75
|
displayName: ds.displayName || ds.name || ds.key || `Datasource ${index + 1}`,
|
|
76
|
-
fileName: `${systemKey}-datasource-${datasourceKeyOnly}.
|
|
76
|
+
fileName: `${systemKey}-datasource-${datasourceKeyOnly}.json`
|
|
77
77
|
};
|
|
78
78
|
});
|
|
79
79
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { formatSuccessLine, formatSuccessParagraph } = require('../utils/cli-test-layout-chalk');
|
|
1
2
|
/**
|
|
2
3
|
* External System Download Module
|
|
3
4
|
*
|
|
@@ -129,7 +130,7 @@ async function setupAuthenticationAndDataplane(systemKey, _options, _config) {
|
|
|
129
130
|
const { resolveDataplaneUrl } = require('../utils/dataplane-resolver');
|
|
130
131
|
logger.log(chalk.blue('š Resolving dataplane URL...'));
|
|
131
132
|
const dataplaneUrl = await resolveDataplaneUrl(controllerUrl, environment, authConfig);
|
|
132
|
-
logger.log(
|
|
133
|
+
logger.log(formatSuccessLine(`Dataplane URL: ${dataplaneUrl}`));
|
|
133
134
|
|
|
134
135
|
return { authConfig, dataplaneUrl };
|
|
135
136
|
}
|
|
@@ -287,8 +288,8 @@ function validateAndLogDownloadedData(application, dataSources) {
|
|
|
287
288
|
logger.log(chalk.blue('š Validating downloaded data...'));
|
|
288
289
|
validateDownloadedData(application, dataSources);
|
|
289
290
|
const systemType = validateSystemType(application);
|
|
290
|
-
logger.log(
|
|
291
|
-
logger.log(
|
|
291
|
+
logger.log(formatSuccessLine(`System type: ${systemType}`));
|
|
292
|
+
logger.log(formatSuccessLine(`Found ${dataSources.length} datasource(s)`));
|
|
292
293
|
return systemType;
|
|
293
294
|
}
|
|
294
295
|
|
|
@@ -367,7 +368,7 @@ async function processDownloadedSystem(systemKey, manifest, splitOptions = {}) {
|
|
|
367
368
|
const deployJson = buildDeployJsonFromManifest(application, dataSources, version);
|
|
368
369
|
const deployJsonPath = path.join(finalPath, `${systemKey}-deploy.json`);
|
|
369
370
|
await fs.writeFile(deployJsonPath, JSON.stringify(deployJson, null, 2), 'utf8');
|
|
370
|
-
logger.log(
|
|
371
|
+
logger.log(formatSuccessLine(`Created: ${path.relative(process.cwd(), deployJsonPath)}`));
|
|
371
372
|
|
|
372
373
|
logger.log(chalk.blue('š Splitting deploy JSON into component files...'));
|
|
373
374
|
const splitResult = await generator.splitDeployJson(deployJsonPath, finalPath, splitOptions);
|
|
@@ -390,7 +391,7 @@ async function processDownloadedSystem(systemKey, manifest, splitOptions = {}) {
|
|
|
390
391
|
* @param {number} datasourceCount - Number of datasources
|
|
391
392
|
*/
|
|
392
393
|
function displayDownloadSuccess(systemKey, finalPath, datasourceCount) {
|
|
393
|
-
logger.log(
|
|
394
|
+
logger.log(formatSuccessParagraph('External system downloaded successfully!'));
|
|
394
395
|
logger.log(chalk.blue(`Location: ${finalPath}`));
|
|
395
396
|
logger.log(chalk.blue(`System: ${systemKey}`));
|
|
396
397
|
logger.log(chalk.blue(`Datasources: ${datasourceCount}`));
|
|
@@ -414,7 +415,7 @@ async function runConvertToJsonIfRequested(systemKey) {
|
|
|
414
415
|
const { runConvert } = require('../commands/convert');
|
|
415
416
|
try {
|
|
416
417
|
await runConvert(systemKey, { format: 'json', force: true });
|
|
417
|
-
logger.log(
|
|
418
|
+
logger.log(formatSuccessLine('Converted component files to JSON'));
|
|
418
419
|
} catch (convertErr) {
|
|
419
420
|
throw new Error(`Download succeeded but convert to JSON failed: ${convertErr.message}`);
|
|
420
421
|
}
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
* @version 2.0.0
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
12
13
|
const fs = require('fs').promises;
|
|
13
14
|
const path = require('path');
|
|
14
15
|
const handlebars = require('handlebars');
|
|
15
|
-
const chalk = require('chalk');
|
|
16
16
|
const logger = require('../utils/logger');
|
|
17
17
|
const { resolveApplicationConfigPath } = require('../utils/app-config-resolver');
|
|
18
18
|
const { loadConfigFile, writeConfigFile } = require('../utils/config-format');
|
|
@@ -135,6 +135,68 @@ function resourceTypeToSchemaEntityType(resourceType) {
|
|
|
135
135
|
return resourceType === 'document' ? 'documentStorage' : 'recordStorage';
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
+
/**
|
|
139
|
+
* Build { dimKey, field } entries for root dimensions (v2.4+ dimensionBinding).
|
|
140
|
+
* @param {Object} dimensions - Map of dimension key ā attribute path (e.g. metadata.country)
|
|
141
|
+
* @returns {Array<{ dimKey: string, field: string }>}
|
|
142
|
+
*/
|
|
143
|
+
function buildDimensionBindingEntries(dimensions) {
|
|
144
|
+
if (!dimensions || typeof dimensions !== 'object' || Array.isArray(dimensions)) return [];
|
|
145
|
+
return Object.entries(dimensions).map(([dimKey, path]) => {
|
|
146
|
+
const field = typeof path === 'string' && path.startsWith('metadata.')
|
|
147
|
+
? path.slice('metadata.'.length).trim()
|
|
148
|
+
: dimKey;
|
|
149
|
+
return { dimKey, field };
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* @param {string} schemaEntityType - Resolved schema entityType
|
|
155
|
+
* @returns {boolean}
|
|
156
|
+
*/
|
|
157
|
+
function isStorageEntityType(schemaEntityType) {
|
|
158
|
+
return schemaEntityType === 'recordStorage' || schemaEntityType === 'documentStorage';
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Puts externalId first for storage entity types when present (schema v2.4 join identity).
|
|
163
|
+
* @param {string[]} keys - Attribute / metadata property names
|
|
164
|
+
* @param {string} schemaEntityType - Resolved schema entityType
|
|
165
|
+
* @returns {string[]}
|
|
166
|
+
*/
|
|
167
|
+
function orderMetadataAttributeKeys(keys, schemaEntityType) {
|
|
168
|
+
const out = [...keys];
|
|
169
|
+
if (isStorageEntityType(schemaEntityType) && out.includes('externalId')) {
|
|
170
|
+
return ['externalId', ...out.filter(k => k !== 'externalId')];
|
|
171
|
+
}
|
|
172
|
+
return out;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Default fieldMappings.attributes + metadata key order when the wizard/config omits attributes.
|
|
177
|
+
* @param {string} schemaEntityType - Resolved schema entityType
|
|
178
|
+
* @returns {{ merged: Object, keys: string[] }}
|
|
179
|
+
*/
|
|
180
|
+
function defaultAttributesForEntityType(schemaEntityType) {
|
|
181
|
+
if (isStorageEntityType(schemaEntityType)) {
|
|
182
|
+
return {
|
|
183
|
+
merged: {
|
|
184
|
+
externalId: { expression: '{{raw.id}}' },
|
|
185
|
+
id: { expression: '{{raw.id}}' },
|
|
186
|
+
name: { expression: '{{raw.name}}' }
|
|
187
|
+
},
|
|
188
|
+
keys: ['externalId', 'id', 'name']
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
merged: {
|
|
193
|
+
id: { expression: '{{raw.id}}' },
|
|
194
|
+
name: { expression: '{{raw.name}}' }
|
|
195
|
+
},
|
|
196
|
+
keys: ['id', 'name']
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
138
200
|
/**
|
|
139
201
|
* Build datasource context object for template rendering
|
|
140
202
|
* @param {Object} opts - Options
|
|
@@ -151,9 +213,31 @@ function resourceTypeToSchemaEntityType(resourceType) {
|
|
|
151
213
|
function buildDatasourceContext({ config, datasourceKey, dimensions, attributes, fullDatasourceKey, entityKey, schemaEntityType, resourceType }) {
|
|
152
214
|
const displayName = config.datasourceDisplayName || datasourceKey.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
|
|
153
215
|
const description = config.datasourceDescription || `External datasource for ${datasourceKey}`;
|
|
216
|
+
const attrsIn = attributes && typeof attributes === 'object' && !Array.isArray(attributes) ? attributes : {};
|
|
217
|
+
let mergedAttributes = { ...attrsIn };
|
|
218
|
+
|
|
219
|
+
let attributeKeysForMetadata;
|
|
220
|
+
if (Object.keys(mergedAttributes).length > 0) {
|
|
221
|
+
attributeKeysForMetadata = orderMetadataAttributeKeys(Object.keys(mergedAttributes), schemaEntityType);
|
|
222
|
+
} else {
|
|
223
|
+
const defaults = defaultAttributesForEntityType(schemaEntityType);
|
|
224
|
+
mergedAttributes = defaults.merged;
|
|
225
|
+
attributeKeysForMetadata = defaults.keys;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (isStorageEntityType(schemaEntityType) && !mergedAttributes.externalId) {
|
|
229
|
+
mergedAttributes.externalId = { expression: '{{raw.id}}' };
|
|
230
|
+
attributeKeysForMetadata = orderMetadataAttributeKeys(Object.keys(mergedAttributes), schemaEntityType);
|
|
231
|
+
}
|
|
232
|
+
|
|
154
233
|
const primaryKey = Array.isArray(config.primaryKey) && config.primaryKey.length > 0
|
|
155
234
|
? config.primaryKey
|
|
156
|
-
: ['id'];
|
|
235
|
+
: (attributeKeysForMetadata.includes('id') ? ['id'] : [attributeKeysForMetadata[0]]);
|
|
236
|
+
const labelKey = Array.isArray(config.labelKey) && config.labelKey.length > 0
|
|
237
|
+
? config.labelKey
|
|
238
|
+
: attributeKeysForMetadata;
|
|
239
|
+
const dimensionBindingEntries = buildDimensionBindingEntries(dimensions);
|
|
240
|
+
|
|
157
241
|
return {
|
|
158
242
|
fullDatasourceKey,
|
|
159
243
|
entityKey,
|
|
@@ -163,9 +247,11 @@ function buildDatasourceContext({ config, datasourceKey, dimensions, attributes,
|
|
|
163
247
|
schemaEntityType,
|
|
164
248
|
resourceType,
|
|
165
249
|
primaryKey,
|
|
250
|
+
labelKey,
|
|
251
|
+
attributeKeysForMetadata,
|
|
252
|
+
dimensionBindingEntries,
|
|
166
253
|
systemType: config.systemType || 'openapi',
|
|
167
|
-
|
|
168
|
-
attributes: Object.keys(attributes).length > 0 ? attributes : null,
|
|
254
|
+
attributes: mergedAttributes,
|
|
169
255
|
raw: { id: '{{raw.id}}', name: '{{raw.name}}' }
|
|
170
256
|
};
|
|
171
257
|
}
|
|
@@ -250,7 +336,7 @@ async function generateExternalSystemFiles(appPath, appName, config, format = 'y
|
|
|
250
336
|
|
|
251
337
|
// Generate external system file
|
|
252
338
|
const systemPath = await generateExternalSystemTemplate(appPath, systemKey, config, fmt);
|
|
253
|
-
logger.log(
|
|
339
|
+
logger.log(formatSuccessLine(`Generated external system: ${path.basename(systemPath)}`));
|
|
254
340
|
|
|
255
341
|
// Generate datasource JSON files
|
|
256
342
|
const datasourcePaths = [];
|
|
@@ -278,7 +364,7 @@ async function generateExternalSystemFiles(appPath, appName, config, format = 'y
|
|
|
278
364
|
|
|
279
365
|
const datasourcePath = await generateExternalDataSourceTemplate(appPath, datasourceKey, datasourceConfig, fmt);
|
|
280
366
|
datasourcePaths.push(datasourcePath);
|
|
281
|
-
logger.log(
|
|
367
|
+
logger.log(formatSuccessLine(`Generated datasource: ${path.basename(datasourcePath)}`));
|
|
282
368
|
}
|
|
283
369
|
|
|
284
370
|
// Update application config with externalIntegration block
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Dispatch rules for external test-integration (system vs per-datasource POST /validation/run).
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Use one externalSystem-scoped validation run when multiple datasources exist (default).
|
|
9
|
+
* Per-datasource runs when {@code options.perDatasource}, a datasource filter, or custom payload is set.
|
|
10
|
+
*
|
|
11
|
+
* @param {Object} options - CLI options
|
|
12
|
+
* @param {string} [options.datasource] - Single-datasource filter
|
|
13
|
+
* @param {boolean} [options.perDatasource] - Force one POST per datasource (externalDataSource scope)
|
|
14
|
+
* @param {Array<{data?: Object}>} datasourcesToTest - Entries from manifest
|
|
15
|
+
* @param {*} customPayload - Parsed payload from {@code --payload}, or null
|
|
16
|
+
* @returns {boolean}
|
|
17
|
+
*/
|
|
18
|
+
function shouldUseSystemLevelIntegrationCall(options, datasourcesToTest, customPayload) {
|
|
19
|
+
const noDatasourceFilter = !options || !options.datasource;
|
|
20
|
+
const multi = Array.isArray(datasourcesToTest) && datasourcesToTest.length > 1;
|
|
21
|
+
const noCustomPayload = customPayload === null || customPayload === undefined;
|
|
22
|
+
const forcePerDs = options && options.perDatasource === true;
|
|
23
|
+
return noDatasourceFilter && multi && noCustomPayload && !forcePerDs;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = { shouldUseSystemLevelIntegrationCall };
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
const chalk = require('chalk');
|
|
12
12
|
const logger = require('../utils/logger');
|
|
13
13
|
const testHelpers = require('../utils/external-system-test-helpers');
|
|
14
|
+
const { infoLine } = require('../utils/cli-test-layout-chalk');
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* Executes test for a single datasource
|
|
@@ -62,7 +63,10 @@ async function testSingleDatasourceIntegration(datasourceFile, systemKey, datapl
|
|
|
62
63
|
const datasource = datasourceFile.data;
|
|
63
64
|
const datasourceKey = datasource.key;
|
|
64
65
|
|
|
65
|
-
|
|
66
|
+
if (options.verbose) {
|
|
67
|
+
logger.log('');
|
|
68
|
+
logger.log(infoLine(`š” Testing datasource: ${datasourceKey}`));
|
|
69
|
+
}
|
|
66
70
|
|
|
67
71
|
// Determine payload to use
|
|
68
72
|
const payloadTemplate = testHelpers.determinePayloadTemplate(datasource, datasourceKey, customPayload);
|
|
@@ -8,8 +8,6 @@
|
|
|
8
8
|
* @version 2.0.0
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
const chalk = require('chalk');
|
|
12
|
-
const logger = require('../utils/logger');
|
|
13
11
|
const externalSystemSchema = require('../schema/external-system.schema.json');
|
|
14
12
|
const { validateAgainstSchema } = require('../utils/external-system-validators');
|
|
15
13
|
|
|
@@ -63,7 +61,6 @@ function validateSystemFiles(systemFiles, schema) {
|
|
|
63
61
|
* @param {Object} results - Test results object
|
|
64
62
|
*/
|
|
65
63
|
function validateSystemFilesForTest(systemFiles, results) {
|
|
66
|
-
logger.log(chalk.blue('š Validating system files...'));
|
|
67
64
|
const systemValidation = validateSystemFiles(systemFiles, externalSystemSchema);
|
|
68
65
|
results.valid = systemValidation.valid;
|
|
69
66
|
results.errors.push(...systemValidation.errors);
|
|
@@ -81,7 +78,6 @@ function validateSystemFilesForTest(systemFiles, results) {
|
|
|
81
78
|
* @param {Function} determineDatasourcesToTest - Function to determine datasources to test
|
|
82
79
|
*/
|
|
83
80
|
function validateDatasourceFilesForTest(datasourceFiles, systemFiles, results, options, validateSingleDatasource, determineDatasourcesToTest) {
|
|
84
|
-
logger.log(chalk.blue('š Validating datasource files...'));
|
|
85
81
|
const datasourcesToTest = determineDatasourcesToTest(datasourceFiles, options.datasource);
|
|
86
82
|
const systemKey = systemFiles.length > 0 ? systemFiles[0].data.key : null;
|
|
87
83
|
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers for system-level pipeline test mapping (keeps runSystemLevelTest under max-lines-per-function).
|
|
3
|
+
* @fileoverview
|
|
4
|
+
*/
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
const { integrationResultFromEnvelope } = require('../utils/datasource-test-run-legacy-adapter');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Build a single failure-shaped datasource result row.
|
|
11
|
+
* @param {string} error
|
|
12
|
+
* @returns {Object}
|
|
13
|
+
*/
|
|
14
|
+
function systemFailureRow(error) {
|
|
15
|
+
return {
|
|
16
|
+
key: 'system',
|
|
17
|
+
success: false,
|
|
18
|
+
skipped: false,
|
|
19
|
+
validationResults: {},
|
|
20
|
+
fieldMappingResults: {},
|
|
21
|
+
endpointTestResults: {},
|
|
22
|
+
error
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Map unified envelope-style response to datasourceResults.
|
|
28
|
+
* @param {Object} data
|
|
29
|
+
* @param {string} datasourceKey
|
|
30
|
+
* @returns {{ success: boolean, datasourceResults: Object[] }}
|
|
31
|
+
*/
|
|
32
|
+
function mapEnvelopeSingleDatasource(data, datasourceKey) {
|
|
33
|
+
const legacy = integrationResultFromEnvelope(data, datasourceKey);
|
|
34
|
+
return {
|
|
35
|
+
success: legacy.success,
|
|
36
|
+
datasourceResults: [
|
|
37
|
+
{
|
|
38
|
+
key: legacy.key,
|
|
39
|
+
success: legacy.success,
|
|
40
|
+
skipped: legacy.skipped,
|
|
41
|
+
validationResults: legacy.validationResults,
|
|
42
|
+
fieldMappingResults: legacy.fieldMappingResults,
|
|
43
|
+
endpointTestResults: legacy.endpointTestResults,
|
|
44
|
+
error: legacy.error,
|
|
45
|
+
envelope: legacy.envelope
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Map legacy array-shaped results to normalized datasource rows.
|
|
53
|
+
* @param {Array} rawResults
|
|
54
|
+
* @param {Object} data
|
|
55
|
+
* @returns {{ success: boolean, datasourceResults: Object[] }}
|
|
56
|
+
*/
|
|
57
|
+
function mapLegacyRawResults(rawResults, data) {
|
|
58
|
+
const datasourceResults = [];
|
|
59
|
+
let success = true;
|
|
60
|
+
|
|
61
|
+
for (const r of rawResults) {
|
|
62
|
+
const dsKey = r.key || r.sourceKey || r.name || r.datasourceKey;
|
|
63
|
+
const dsResult = {
|
|
64
|
+
key: dsKey,
|
|
65
|
+
success: r.success !== false,
|
|
66
|
+
skipped: !!r.skipped,
|
|
67
|
+
reason: r.reason,
|
|
68
|
+
validationResults: r.validationResults || {},
|
|
69
|
+
fieldMappingResults: r.fieldMappingResults || {},
|
|
70
|
+
endpointTestResults: r.endpointTestResults || {}
|
|
71
|
+
};
|
|
72
|
+
if (r.error) dsResult.error = r.error;
|
|
73
|
+
if (!dsResult.success && !dsResult.skipped) success = false;
|
|
74
|
+
datasourceResults.push(dsResult);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (rawResults.length === 0 && data.success === false) {
|
|
78
|
+
success = false;
|
|
79
|
+
datasourceResults.push(
|
|
80
|
+
systemFailureRow(data.error || data.formattedError || 'System test failed')
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return { success, datasourceResults };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Normalize pipeline response body to { success, datasourceResults }.
|
|
89
|
+
* @param {Object} data
|
|
90
|
+
* @returns {{ success: boolean, datasourceResults: Object[] }}
|
|
91
|
+
*/
|
|
92
|
+
function mapPipelineDataToDatasourceResults(data) {
|
|
93
|
+
if (
|
|
94
|
+
data &&
|
|
95
|
+
typeof data === 'object' &&
|
|
96
|
+
typeof data.status === 'string' &&
|
|
97
|
+
typeof data.datasourceKey === 'string'
|
|
98
|
+
) {
|
|
99
|
+
return mapEnvelopeSingleDatasource(data, data.datasourceKey);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const rawResults =
|
|
103
|
+
data.datasourceResults || data.results || data.data?.datasourceResults || (Array.isArray(data) ? data : []);
|
|
104
|
+
return mapLegacyRawResults(rawResults, data);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
module.exports = {
|
|
108
|
+
systemFailureRow,
|
|
109
|
+
mapPipelineDataToDatasourceResults
|
|
110
|
+
};
|