@aifabrix/builder 2.42.1 → 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 +2 -2
- 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 +157 -0
- package/integration/{hubspot → hubspot-test}/application.json +6 -6
- package/integration/{hubspot → hubspot-test}/create-hubspot.js +10 -10
- package/integration/hubspot-test/env.template +4 -0
- package/integration/hubspot-test/hubspot-test-datasource-company.json +138 -0
- package/integration/hubspot-test/hubspot-test-datasource-contact.json +146 -0
- package/integration/hubspot-test/hubspot-test-datasource-deal.json +146 -0
- package/integration/hubspot-test/hubspot-test-datasource-users.json +76 -0
- package/integration/{hubspot/hubspot-deploy.json → hubspot-test/hubspot-test-deploy.json} +201 -24
- package/integration/{hubspot/hubspot-system.json → hubspot-test/hubspot-test-system.json} +8 -7
- package/integration/hubspot-test/rbac.json +166 -0
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-hubspot-credential-real.yaml +3 -3
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-hubspot-env-vars.yaml +2 -2
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-add-datasource.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-credential-create.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-credential-select.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-known-platform.yaml +1 -1
- package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-source.yaml +2 -0
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-mode.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-openapi-file.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-openapi-url.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-source.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-dimension-array-test.yaml +1 -1
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-key-test.yaml +5 -0
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-path-test.yaml +5 -0
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-dimension-test.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-rbac-test.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-rbac-yaml-test.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-dataplane-down-tests.js +1 -7
- package/integration/{hubspot → hubspot-test}/test-dataplane-down.js +3 -3
- package/integration/{hubspot → hubspot-test}/test.js +137 -102
- package/integration/{hubspot → hubspot-test}/wizard-hubspot-e2e.yaml +2 -2
- package/integration/{hubspot → hubspot-test}/wizard-hubspot-platform.yaml +1 -1
- 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/service-users.api.js +111 -2
- package/lib/api/types/dev.types.js +4 -3
- package/lib/api/types/pipeline.types.js +8 -5
- package/lib/api/types/service-users.types.js +41 -0
- 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 +19 -8
- package/lib/app/rotate-secret.js +17 -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 +59 -123
- package/lib/cli/setup-app.test-commands.js +179 -0
- package/lib/cli/setup-auth.js +36 -14
- 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 +190 -103
- package/lib/cli/setup-environment.js +11 -20
- package/lib/cli/setup-external-system.js +62 -22
- package/lib/cli/setup-infra.js +139 -47
- package/lib/cli/setup-parameters.js +32 -0
- package/lib/cli/setup-secrets.js +147 -10
- package/lib/cli/setup-service-user.js +146 -20
- package/lib/cli/setup-utility.js +47 -19
- 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 +10 -14
- 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 +123 -71
- 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 +16 -10
- package/lib/commands/repair-rbac.js +25 -19
- package/lib/commands/repair.js +116 -32
- package/lib/commands/secrets-list.js +23 -12
- package/lib/commands/secrets-remove-all.js +220 -0
- package/lib/commands/secrets-remove.js +22 -13
- package/lib/commands/secrets-set.js +21 -12
- package/lib/commands/secrets-validate.js +20 -7
- package/lib/commands/secure.js +10 -9
- package/lib/commands/service-user.js +243 -13
- package/lib/commands/test-e2e-external.js +27 -1
- package/lib/commands/up-common.js +28 -2
- package/lib/commands/up-dataplane.js +31 -18
- 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 +16 -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 +59 -58
- package/lib/core/diff.js +3 -2
- package/lib/core/ensure-encryption-key.js +2 -4
- 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 +228 -42
- package/lib/core/templates-env.js +4 -3
- package/lib/core/templates.js +1 -1
- package/lib/datasource/abac-validator.js +148 -0
- package/lib/datasource/deploy.js +75 -53
- package/lib/datasource/field-reference-validator.js +77 -36
- package/lib/datasource/integration-context.js +63 -0
- package/lib/datasource/list.js +8 -7
- package/lib/datasource/log-viewer.js +252 -0
- package/lib/datasource/resolve-app.js +109 -0
- package/lib/datasource/test-e2e.js +95 -155
- package/lib/datasource/test-integration.js +121 -109
- 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 +162 -15
- 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 +104 -14
- 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-controller-manifest.js +3 -3
- package/lib/generator/external.js +23 -11
- package/lib/generator/helpers.js +71 -12
- package/lib/generator/index.js +8 -4
- package/lib/generator/split-readme.js +12 -7
- package/lib/generator/split-variables.js +2 -1
- package/lib/generator/split.js +46 -11
- package/lib/generator/wizard-readme.js +3 -3
- package/lib/generator/wizard.js +16 -13
- package/lib/infrastructure/compose.js +60 -6
- package/lib/infrastructure/helpers.js +238 -51
- package/lib/infrastructure/index.js +64 -37
- 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 +1201 -433
- 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-config-resolver.js +23 -1
- 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 +209 -6
- 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/credential-secrets-env.js +16 -1
- 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 +42 -11
- package/lib/utils/env-template.js +2 -2
- package/lib/utils/environment-scoped-resources.js +144 -0
- package/lib/utils/error-formatter.js +125 -9
- 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-env-template.js +180 -0
- package/lib/utils/external-readme.js +8 -1
- package/lib/utils/external-system-display.js +277 -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 +32 -14
- package/lib/utils/health-check-url.js +119 -0
- package/lib/utils/health-check.js +59 -25
- package/lib/utils/help-builder.js +14 -13
- 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 +29 -7
- package/lib/utils/paths.js +136 -48
- 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 +171 -51
- package/lib/utils/secrets-helpers.js +70 -59
- package/lib/utils/secrets-kv-scope.js +60 -0
- package/lib/utils/secrets-utils.js +35 -37
- package/lib/utils/secrets-validation.js +3 -1
- package/lib/utils/secrets-yaml-preserve.js +109 -0
- package/lib/utils/secure-file-permissions.js +91 -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 +37 -5
- 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 +78 -1
- package/lib/validation/datasource-warnings.js +56 -0
- package/lib/validation/env-template-auth.js +50 -2
- package/lib/validation/external-manifest-validator.js +35 -7
- package/lib/validation/validate-display.js +37 -31
- package/lib/validation/validate.js +9 -10
- package/lib/validation/validator-unresolved-placeholders.js +98 -0
- package/lib/validation/validator.js +32 -78
- package/lib/validation/wizard-config-validator.js +2 -1
- package/package.json +11 -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 +80 -18
- 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 +55 -14
- 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/env.template.hbs +22 -0
- 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/integration/hubspot/README.md +0 -102
- package/integration/hubspot/env.template +0 -4
- package/integration/hubspot/hubspot-datasource-company.json +0 -541
- package/integration/hubspot/hubspot-datasource-contact.json +0 -639
- package/integration/hubspot/hubspot-datasource-deal.json +0 -588
- package/integration/hubspot/hubspot-datasource-users.json +0 -116
- package/integration/hubspot/test-artifacts/wizard-invalid-missing-source.yaml +0 -2
- package/integration/hubspot/test-artifacts/wizard-valid-for-dimension-key-test.yaml +0 -5
- package/integration/hubspot/test-artifacts/wizard-valid-for-dimension-path-test.yaml +0 -5
- package/lib/api/external-test.api.js +0 -111
- package/lib/schema/env-config.yaml +0 -43
- /package/integration/{hubspot → hubspot-test}/companies.json +0 -0
- /package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-app-name.yaml +0 -0
- /package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-missing-app.yaml +0 -0
- /package/integration/{hubspot → hubspot-test}/test-dataplane-down-helpers.js +0 -0
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
const { formatBlockingError } = require('../utils/cli-test-layout-chalk');
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview CLI wiring for `datasource test`, `test-integration`, and `test-e2e` (unified validation + watch).
|
|
4
|
+
* @author AI Fabrix Team
|
|
5
|
+
* @version 2.0.0
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const chalk = require('chalk');
|
|
9
|
+
const logger = require('../utils/logger');
|
|
10
|
+
const { runDatasourceTestIntegration } = require('../datasource/test-integration');
|
|
11
|
+
const { runDatasourceTestE2E } = require('../datasource/test-e2e');
|
|
12
|
+
const { runUnifiedDatasourceValidation } = require('../datasource/unified-validation-run');
|
|
13
|
+
const { displayIntegrationTestResults, displayE2EResults } = require('../utils/external-system-display');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const { getIntegrationPath } = require('../utils/paths');
|
|
16
|
+
const { writeTestLog } = require('../utils/test-log-writer');
|
|
17
|
+
const { includeDebugForRequest } = require('../utils/validation-run-request');
|
|
18
|
+
const {
|
|
19
|
+
exitFromUnifiedValidationResult,
|
|
20
|
+
finalizeUnifiedValidationResult,
|
|
21
|
+
unifiedCliResultFromIntegrationReturn,
|
|
22
|
+
exitAfterIntegrationDisplay,
|
|
23
|
+
finalizeAfterIntegrationDisplay,
|
|
24
|
+
emitCapabilityScopeDiagnostics
|
|
25
|
+
} = require('./datasource-validation-cli');
|
|
26
|
+
const { resolveAppKeyForDatasource } = require('../datasource/resolve-app');
|
|
27
|
+
const { runDatasourceValidationWatchLoop } = require('../utils/datasource-validation-watch');
|
|
28
|
+
const { computeExitCodeFromDatasourceTestRun } = require('../utils/datasource-test-run-exit');
|
|
29
|
+
const { analyzeCapabilityScope } = require('../utils/datasource-test-run-capability-scope');
|
|
30
|
+
const {
|
|
31
|
+
resolveDebugDisplayMode,
|
|
32
|
+
formatDatasourceTestRunDebugBlock
|
|
33
|
+
} = require('../utils/datasource-test-run-debug-display');
|
|
34
|
+
const { formatCapabilityFocusSection } = require('../utils/datasource-test-run-display');
|
|
35
|
+
const {
|
|
36
|
+
datasourceTestHelpAfter,
|
|
37
|
+
datasourceTestIntegrationHelpAfter,
|
|
38
|
+
datasourceTestE2eHelpAfter,
|
|
39
|
+
attachDatasourceWatchOptions,
|
|
40
|
+
attachDatasourceTestCommonOptions
|
|
41
|
+
} = require('./datasource-unified-test-cli.options');
|
|
42
|
+
|
|
43
|
+
function integrationBaseDirForLogs(appKey) {
|
|
44
|
+
return path.dirname(getIntegrationPath(appKey));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function writeDatasourceTestDebugLogIfRequested(appKey, datasourceKey, result, options) {
|
|
48
|
+
if (!options || !options.debug) return;
|
|
49
|
+
const requestMeta = {
|
|
50
|
+
datasourceKey,
|
|
51
|
+
runType: 'test',
|
|
52
|
+
includeDebug: includeDebugForRequest(options.debug)
|
|
53
|
+
};
|
|
54
|
+
const envelope = result && typeof result === 'object' ? result.envelope : null;
|
|
55
|
+
const apiError = result && typeof result === 'object' ? result.apiError : null;
|
|
56
|
+
const errorMessage = apiError
|
|
57
|
+
? apiError.formattedError || apiError.error || 'Request failed'
|
|
58
|
+
: null;
|
|
59
|
+
const data = errorMessage
|
|
60
|
+
? { request: requestMeta, error: errorMessage }
|
|
61
|
+
: { request: requestMeta, response: envelope };
|
|
62
|
+
const logPath = await writeTestLog(
|
|
63
|
+
appKey,
|
|
64
|
+
data,
|
|
65
|
+
'test',
|
|
66
|
+
integrationBaseDirForLogs(appKey)
|
|
67
|
+
);
|
|
68
|
+
logger.log(chalk.gray(` Debug log: ${logPath}`));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function logDatasourceTestRunDebugAppendix(envelope, debugOpt) {
|
|
72
|
+
const mode = resolveDebugDisplayMode(debugOpt);
|
|
73
|
+
if (!mode || !envelope) return;
|
|
74
|
+
const block = formatDatasourceTestRunDebugBlock(envelope, mode, process.stdout.isTTY);
|
|
75
|
+
if (block) logger.log(block);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function logE2eCapabilityFocusFromEnvelope(env, capabilityOpt) {
|
|
79
|
+
if (!env) return;
|
|
80
|
+
const capKey =
|
|
81
|
+
capabilityOpt !== undefined && capabilityOpt !== null
|
|
82
|
+
? String(capabilityOpt).trim()
|
|
83
|
+
: '';
|
|
84
|
+
if (!capKey) return;
|
|
85
|
+
const sec = formatCapabilityFocusSection(env, capKey);
|
|
86
|
+
if (sec) logger.log(sec);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Exit code from envelope only (no stderr diagnostics; use when TTY output already ran emit via logEnvelope).
|
|
91
|
+
* @param {Object|null|undefined} env
|
|
92
|
+
* @param {Object} options
|
|
93
|
+
* @returns {number|null} null if no envelope
|
|
94
|
+
*/
|
|
95
|
+
function exitCodeFromDatasourceTestRunEnvelope(env, options) {
|
|
96
|
+
if (!env || typeof env !== 'object') return null;
|
|
97
|
+
let code = computeExitCodeFromDatasourceTestRun(env, {
|
|
98
|
+
warningsAsErrors: false,
|
|
99
|
+
requireCert: false
|
|
100
|
+
});
|
|
101
|
+
const scope = analyzeCapabilityScope(env, options.capability);
|
|
102
|
+
if (options.strictCapabilityScope === true && scope.violated) {
|
|
103
|
+
code = Math.max(code, 1);
|
|
104
|
+
}
|
|
105
|
+
return code;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Legacy E2E display + exit code (no process.exit; watch mode).
|
|
110
|
+
* @param {Object} data
|
|
111
|
+
* @param {Object} options
|
|
112
|
+
* @returns {number}
|
|
113
|
+
*/
|
|
114
|
+
function finalizeDatasourceTestE2ELegacyPath(data, options) {
|
|
115
|
+
displayE2EResults(data, options.verbose);
|
|
116
|
+
logDatasourceTestRunDebugAppendix(data.datasourceTestRun, options.debug);
|
|
117
|
+
logE2eCapabilityFocusFromEnvelope(data.datasourceTestRun, options.capability);
|
|
118
|
+
const env = data.datasourceTestRun;
|
|
119
|
+
if (env) {
|
|
120
|
+
emitCapabilityScopeDiagnostics(env, { requestedCapabilityKey: options.capability });
|
|
121
|
+
const code = exitCodeFromDatasourceTestRunEnvelope(env, options);
|
|
122
|
+
return code === null ? 1 : code;
|
|
123
|
+
}
|
|
124
|
+
const steps = data.steps || data.completedActions || [];
|
|
125
|
+
const failed = data.success === false || steps.some(s => s.success === false || s.error);
|
|
126
|
+
return failed ? 1 : 0;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Human TTY for single-datasource E2E when DatasourceTestRun envelope is present.
|
|
131
|
+
* @param {string} datasourceKey
|
|
132
|
+
* @param {Object} env
|
|
133
|
+
* @param {Object} options
|
|
134
|
+
*/
|
|
135
|
+
function displayDatasourceTestE2EEnvelopeResults(datasourceKey, env, options) {
|
|
136
|
+
const success = env.status !== 'fail';
|
|
137
|
+
displayIntegrationTestResults(
|
|
138
|
+
{
|
|
139
|
+
systemKey: env.systemKey || 'unknown',
|
|
140
|
+
success,
|
|
141
|
+
datasourceResults: [{ key: datasourceKey, success, datasourceTestRun: env }]
|
|
142
|
+
},
|
|
143
|
+
options.verbose,
|
|
144
|
+
{
|
|
145
|
+
debug: options.debug,
|
|
146
|
+
runType: 'e2e',
|
|
147
|
+
requestedCapabilityKey: options.capability
|
|
148
|
+
}
|
|
149
|
+
);
|
|
150
|
+
logE2eCapabilityFocusFromEnvelope(env, options.capability);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function buildDatasourceTestRunOpts(options) {
|
|
154
|
+
return {
|
|
155
|
+
app: options.app,
|
|
156
|
+
environment: options.env,
|
|
157
|
+
runType: 'test',
|
|
158
|
+
payload: options.payload,
|
|
159
|
+
debug: options.debug,
|
|
160
|
+
verbose: options.verbose,
|
|
161
|
+
timeout: options.timeout,
|
|
162
|
+
async: options.async !== false,
|
|
163
|
+
noAsync: options.async === false,
|
|
164
|
+
sync: options.sync === true
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function buildDatasourceTestDisplayOpts(options) {
|
|
169
|
+
return {
|
|
170
|
+
json: options.json,
|
|
171
|
+
summary: options.summary,
|
|
172
|
+
warningsAsErrors: options.warningsAsErrors,
|
|
173
|
+
requireCert: options.requireCert,
|
|
174
|
+
debug: options.debug
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async function runDatasourceUnifiedTestOnceForWatch(datasourceKey, runOpts, displayOpts) {
|
|
179
|
+
try {
|
|
180
|
+
const result = await runUnifiedDatasourceValidation(datasourceKey, runOpts);
|
|
181
|
+
return {
|
|
182
|
+
exitCode: finalizeUnifiedValidationResult(result, displayOpts),
|
|
183
|
+
envelope: result.envelope
|
|
184
|
+
};
|
|
185
|
+
} catch (err) {
|
|
186
|
+
logger.error(formatBlockingError('Datasource test failed:'), err.message);
|
|
187
|
+
return { exitCode: 4, envelope: null };
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async function datasourceTestCommandAction(datasourceKey, options) {
|
|
192
|
+
const runOpts = buildDatasourceTestRunOpts(options);
|
|
193
|
+
const displayOpts = buildDatasourceTestDisplayOpts(options);
|
|
194
|
+
try {
|
|
195
|
+
if (options.watch) {
|
|
196
|
+
const { appKey } = await resolveAppKeyForDatasource(datasourceKey, options.app);
|
|
197
|
+
await runDatasourceValidationWatchLoop({
|
|
198
|
+
appKey,
|
|
199
|
+
extraPaths: options.watchPath || [],
|
|
200
|
+
includeApplicationYaml: options.watchApplicationYaml === true,
|
|
201
|
+
watchCi: options.watchCi === true,
|
|
202
|
+
watchFullDiff: options.watchFullDiff === true,
|
|
203
|
+
runOnce: async() => {
|
|
204
|
+
const result = await runUnifiedDatasourceValidation(datasourceKey, runOpts);
|
|
205
|
+
await writeDatasourceTestDebugLogIfRequested(appKey, datasourceKey, result, options);
|
|
206
|
+
return {
|
|
207
|
+
exitCode: finalizeUnifiedValidationResult(result, displayOpts),
|
|
208
|
+
envelope: result.envelope
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const result = await runUnifiedDatasourceValidation(datasourceKey, runOpts);
|
|
215
|
+
if (options.debug) {
|
|
216
|
+
try {
|
|
217
|
+
const { appKey } = await resolveAppKeyForDatasource(datasourceKey, options.app);
|
|
218
|
+
await writeDatasourceTestDebugLogIfRequested(appKey, datasourceKey, result, options);
|
|
219
|
+
} catch (e) {
|
|
220
|
+
logger.warn(chalk.yellow(`⚠ Could not write debug log: ${e.message}`));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
exitFromUnifiedValidationResult(result, displayOpts);
|
|
224
|
+
} catch (error) {
|
|
225
|
+
logger.error(formatBlockingError('Datasource test failed:'), error.message);
|
|
226
|
+
process.exit(4);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function chainDatasourceTestCommand(datasource) {
|
|
231
|
+
const cmd = datasource
|
|
232
|
+
.command('test <datasourceKey>')
|
|
233
|
+
.description('Structural/policy validation for one datasource (unified dataplane API, runType=test)');
|
|
234
|
+
attachDatasourceTestCommonOptions(cmd, {
|
|
235
|
+
includeNoAsync: true,
|
|
236
|
+
verboseHelp: 'Set explain=true on validation request',
|
|
237
|
+
timeoutHelp: 'Aggregate timeout for POST + polls'
|
|
238
|
+
});
|
|
239
|
+
return cmd.addHelpText('after', datasourceTestHelpAfter());
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function setupDatasourceTestCommand(datasource) {
|
|
243
|
+
// watch flags are already attached by attachDatasourceTestCommonOptions()
|
|
244
|
+
chainDatasourceTestCommand(datasource).action(datasourceTestCommandAction);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function buildIntegrationTestOpts(options) {
|
|
248
|
+
return {
|
|
249
|
+
app: options.app,
|
|
250
|
+
payload: options.payload,
|
|
251
|
+
environment: options.env,
|
|
252
|
+
debug: options.debug,
|
|
253
|
+
verbose: options.verbose,
|
|
254
|
+
timeout: options.timeout,
|
|
255
|
+
sync: options.sync === true
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function buildIntegrationUnifiedDisplayOpts(options) {
|
|
260
|
+
return {
|
|
261
|
+
json: options.json,
|
|
262
|
+
summary: options.summary,
|
|
263
|
+
warningsAsErrors: options.warningsAsErrors,
|
|
264
|
+
requireCert: options.requireCert,
|
|
265
|
+
debug: options.debug
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
async function runIntegrationOnceForWatch(datasourceKey, integOpts, options, unifiedDisplayOpts) {
|
|
270
|
+
try {
|
|
271
|
+
const result = await runDatasourceTestIntegration(datasourceKey, integOpts);
|
|
272
|
+
const unifiedModes =
|
|
273
|
+
options.json || options.summary || options.warningsAsErrors || options.requireCert;
|
|
274
|
+
if (unifiedModes) {
|
|
275
|
+
const uni = unifiedCliResultFromIntegrationReturn(result);
|
|
276
|
+
const exitCode = finalizeUnifiedValidationResult(uni, unifiedDisplayOpts);
|
|
277
|
+
return { exitCode, envelope: uni.envelope };
|
|
278
|
+
}
|
|
279
|
+
displayIntegrationTestResults(
|
|
280
|
+
{
|
|
281
|
+
systemKey: result.systemKey || 'unknown',
|
|
282
|
+
datasourceResults: [result],
|
|
283
|
+
success: result.success
|
|
284
|
+
},
|
|
285
|
+
options.verbose,
|
|
286
|
+
{ debug: options.debug, runType: 'integration' }
|
|
287
|
+
);
|
|
288
|
+
const exitCode = finalizeAfterIntegrationDisplay(result, {});
|
|
289
|
+
return { exitCode, envelope: result.datasourceTestRun || null };
|
|
290
|
+
} catch (err) {
|
|
291
|
+
logger.error(formatBlockingError('Integration test failed:'), err.message);
|
|
292
|
+
return { exitCode: 4, envelope: null };
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
async function integrationTestCommandAction(datasourceKey, options) {
|
|
297
|
+
const integOpts = buildIntegrationTestOpts(options);
|
|
298
|
+
const unifiedDisplayOpts = buildIntegrationUnifiedDisplayOpts(options);
|
|
299
|
+
try {
|
|
300
|
+
if (options.watch) {
|
|
301
|
+
const { appKey } = await resolveAppKeyForDatasource(datasourceKey, options.app);
|
|
302
|
+
await runDatasourceValidationWatchLoop({
|
|
303
|
+
appKey,
|
|
304
|
+
extraPaths: options.watchPath || [],
|
|
305
|
+
includeApplicationYaml: options.watchApplicationYaml === true,
|
|
306
|
+
watchCi: options.watchCi === true,
|
|
307
|
+
watchFullDiff: options.watchFullDiff === true,
|
|
308
|
+
runOnce: () => runIntegrationOnceForWatch(datasourceKey, integOpts, options, unifiedDisplayOpts)
|
|
309
|
+
});
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
const result = await runDatasourceTestIntegration(datasourceKey, integOpts);
|
|
313
|
+
const unifiedModes =
|
|
314
|
+
options.json || options.summary || options.warningsAsErrors || options.requireCert;
|
|
315
|
+
if (unifiedModes) {
|
|
316
|
+
exitFromUnifiedValidationResult(unifiedCliResultFromIntegrationReturn(result), unifiedDisplayOpts);
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
displayIntegrationTestResults(
|
|
320
|
+
{
|
|
321
|
+
systemKey: result.systemKey || 'unknown',
|
|
322
|
+
datasourceResults: [result],
|
|
323
|
+
success: result.success
|
|
324
|
+
},
|
|
325
|
+
options.verbose,
|
|
326
|
+
{ debug: options.debug, runType: 'integration' }
|
|
327
|
+
);
|
|
328
|
+
exitAfterIntegrationDisplay(result, {});
|
|
329
|
+
} catch (error) {
|
|
330
|
+
logger.error(formatBlockingError('Integration test failed:'), error.message);
|
|
331
|
+
process.exit(4);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function chainDatasourceTestIntegrationCommand(datasource) {
|
|
336
|
+
const cmd = datasource
|
|
337
|
+
.command('test-integration <datasourceKey>')
|
|
338
|
+
.description('Integration test one datasource (unified validation API, runType=integration)');
|
|
339
|
+
attachDatasourceTestCommonOptions(cmd, {
|
|
340
|
+
includeNoAsync: false,
|
|
341
|
+
debugHelp: 'includeDebug + log under integration/<systemKey>/logs/; TTY appendix: summary, full, or raw'
|
|
342
|
+
});
|
|
343
|
+
return cmd.addHelpText('after', datasourceTestIntegrationHelpAfter());
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function setupDatasourceTestIntegrationCommand(datasource) {
|
|
347
|
+
// watch flags are already attached by attachDatasourceTestCommonOptions()
|
|
348
|
+
chainDatasourceTestIntegrationCommand(datasource).action(integrationTestCommandAction);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* @param {string} datasourceKey
|
|
353
|
+
* @param {Object} options
|
|
354
|
+
* @returns {Promise<{ exitCode: number, envelope: Object|null }>}
|
|
355
|
+
*/
|
|
356
|
+
async function runDatasourceTestE2ECliOnce(datasourceKey, options) {
|
|
357
|
+
const data = await runDatasourceTestE2E(datasourceKey, {
|
|
358
|
+
app: options.app,
|
|
359
|
+
environment: options.env,
|
|
360
|
+
debug: options.debug,
|
|
361
|
+
verbose: options.verbose,
|
|
362
|
+
async: options.async !== false,
|
|
363
|
+
testCrud: options.testCrud,
|
|
364
|
+
recordId: options.recordId,
|
|
365
|
+
cleanup: options.cleanup,
|
|
366
|
+
primaryKeyValue: options.primaryKeyValue,
|
|
367
|
+
timeout: options.timeout,
|
|
368
|
+
capabilityKey: options.capability,
|
|
369
|
+
sync: options.sync === true
|
|
370
|
+
});
|
|
371
|
+
const unifiedModes =
|
|
372
|
+
options.json || options.summary || options.warningsAsErrors || options.requireCert;
|
|
373
|
+
if (unifiedModes && data.datasourceTestRun) {
|
|
374
|
+
const exitCode = finalizeUnifiedValidationResult(
|
|
375
|
+
{
|
|
376
|
+
apiError: null,
|
|
377
|
+
pollTimedOut: false,
|
|
378
|
+
incompleteNoAsync: false,
|
|
379
|
+
envelope: data.datasourceTestRun
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
json: options.json,
|
|
383
|
+
summary: options.summary,
|
|
384
|
+
warningsAsErrors: options.warningsAsErrors,
|
|
385
|
+
requireCert: options.requireCert,
|
|
386
|
+
debug: options.debug,
|
|
387
|
+
requestedCapabilityKey: options.capability,
|
|
388
|
+
strictCapabilityScope: options.strictCapabilityScope === true
|
|
389
|
+
}
|
|
390
|
+
);
|
|
391
|
+
return { exitCode, envelope: data.datasourceTestRun };
|
|
392
|
+
}
|
|
393
|
+
const env = data.datasourceTestRun;
|
|
394
|
+
if (env && !unifiedModes) {
|
|
395
|
+
displayDatasourceTestE2EEnvelopeResults(datasourceKey, env, options);
|
|
396
|
+
const exitCode = exitCodeFromDatasourceTestRunEnvelope(env, options);
|
|
397
|
+
return { exitCode: exitCode === null ? 1 : exitCode, envelope: env };
|
|
398
|
+
}
|
|
399
|
+
const exitCode = finalizeDatasourceTestE2ELegacyPath(data, options);
|
|
400
|
+
return { exitCode, envelope: data.datasourceTestRun || null };
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
async function runDatasourceTestE2ECliAction(datasourceKey, options) {
|
|
404
|
+
const { exitCode } = await runDatasourceTestE2ECliOnce(datasourceKey, options);
|
|
405
|
+
process.exit(exitCode);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
async function e2eTestCommandAction(datasourceKey, capabilityKey, options) {
|
|
409
|
+
const optObj = options && typeof options === 'object' ? options : {};
|
|
410
|
+
const capFromArg = typeof capabilityKey === 'string' ? capabilityKey.trim() : '';
|
|
411
|
+
const capFromFlag = optObj.capability !== undefined && optObj.capability !== null
|
|
412
|
+
? String(optObj.capability).trim()
|
|
413
|
+
: '';
|
|
414
|
+
const requestedCapability = capFromArg || capFromFlag;
|
|
415
|
+
if (capFromArg && capFromFlag && capFromArg !== capFromFlag) {
|
|
416
|
+
logger.warn(
|
|
417
|
+
chalk.yellow('⚠ Capability mismatch:'),
|
|
418
|
+
`using positional '${capFromArg}' instead of --capability '${capFromFlag}'.`
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
const mergedOptions = { ...optObj, capability: requestedCapability || undefined };
|
|
422
|
+
try {
|
|
423
|
+
if (mergedOptions.watch) {
|
|
424
|
+
const { appKey } = await resolveAppKeyForDatasource(datasourceKey, mergedOptions.app);
|
|
425
|
+
await runDatasourceValidationWatchLoop({
|
|
426
|
+
appKey,
|
|
427
|
+
extraPaths: mergedOptions.watchPath || [],
|
|
428
|
+
includeApplicationYaml: mergedOptions.watchApplicationYaml === true,
|
|
429
|
+
watchCi: mergedOptions.watchCi === true,
|
|
430
|
+
watchFullDiff: mergedOptions.watchFullDiff === true,
|
|
431
|
+
runOnce: async() => {
|
|
432
|
+
try {
|
|
433
|
+
return await runDatasourceTestE2ECliOnce(datasourceKey, mergedOptions);
|
|
434
|
+
} catch (err) {
|
|
435
|
+
logger.error(formatBlockingError('E2E test failed:'), err.message);
|
|
436
|
+
return { exitCode: 3, envelope: null };
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
await runDatasourceTestE2ECliAction(datasourceKey, mergedOptions);
|
|
443
|
+
} catch (error) {
|
|
444
|
+
logger.error(formatBlockingError('E2E test failed:'), error.message);
|
|
445
|
+
process.exit(3);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
function chainDatasourceTestE2ECommand(datasource) {
|
|
450
|
+
const cmd = datasource
|
|
451
|
+
.command('test-e2e <datasourceKey> [capabilityKey]')
|
|
452
|
+
.description('E2E test one datasource (unified validation API, runType=e2e)');
|
|
453
|
+
attachDatasourceTestCommonOptions(cmd, {
|
|
454
|
+
includeNoAsync: true,
|
|
455
|
+
includePayload: false,
|
|
456
|
+
appHelp: 'Integration folder name (default: resolve from cwd if inside integration/<systemKey>/)',
|
|
457
|
+
verboseHelp: 'Audit / explain-oriented request flags where applicable',
|
|
458
|
+
debugHelp: 'includeDebug + log under integration/<systemKey>/logs/; TTY appendix: summary, full, or raw',
|
|
459
|
+
timeoutHelp: 'Aggregate timeout for POST + polls (default 15m)',
|
|
460
|
+
timeoutDefault: String(15 * 60 * 1000)
|
|
461
|
+
});
|
|
462
|
+
return cmd
|
|
463
|
+
.option('--test-crud', 'Enable CRUD lifecycle test (e2eOptions.testCrud)')
|
|
464
|
+
.option('--record-id <id>', 'Record ID for test (e2eOptions.recordId)')
|
|
465
|
+
.option('--no-cleanup', 'Disable cleanup after test (e2eOptions.cleanup: false)')
|
|
466
|
+
.option(
|
|
467
|
+
'--primary-key-value <value|@path>',
|
|
468
|
+
'Primary key value or path to JSON file (e.g. @pk.json) for e2eOptions.primaryKeyValue'
|
|
469
|
+
)
|
|
470
|
+
.option('--capability <key>', 'Capability drill-down (deprecated; use positional [capabilityKey])')
|
|
471
|
+
.option(
|
|
472
|
+
'--strict-capability-scope',
|
|
473
|
+
'Exit 1 if a capability drill-down is requested but the report lists more than one capabilities[] row (plan §2.3)'
|
|
474
|
+
)
|
|
475
|
+
.addHelpText('after', datasourceTestE2eHelpAfter());
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
function setupDatasourceTestE2ECommand(datasource) {
|
|
479
|
+
// watch flags are already attached by attachDatasourceTestCommonOptions()
|
|
480
|
+
chainDatasourceTestE2ECommand(datasource).action(e2eTestCommandAction);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
module.exports = {
|
|
484
|
+
setupDatasourceTestCommand,
|
|
485
|
+
setupDatasourceTestIntegrationCommand,
|
|
486
|
+
setupDatasourceTestE2ECommand,
|
|
487
|
+
attachDatasourceWatchOptions,
|
|
488
|
+
/** @internal Exported for Jest: CLI action coverage without Commander. */
|
|
489
|
+
runDatasourceUnifiedTestOnceForWatch,
|
|
490
|
+
datasourceTestCommandAction,
|
|
491
|
+
runIntegrationOnceForWatch,
|
|
492
|
+
integrationTestCommandAction,
|
|
493
|
+
runDatasourceTestE2ECliOnce,
|
|
494
|
+
e2eTestCommandAction
|
|
495
|
+
};
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared option builders + help text for datasource test CLI commands.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
function datasourceTestHelpAfter() {
|
|
8
|
+
return `
|
|
9
|
+
Examples:
|
|
10
|
+
$ aifabrix datasource test hubspot-users
|
|
11
|
+
$ aifabrix datasource test hubspot-users --app test-e2e-hubspot -v
|
|
12
|
+
$ aifabrix datasource test hubspot-users -a test-e2e-hubspot --debug full
|
|
13
|
+
$ aifabrix datasource test hubspot-users --json
|
|
14
|
+
|
|
15
|
+
Notes:
|
|
16
|
+
- For integration pipeline tests, use:
|
|
17
|
+
aifabrix datasource test-integration <datasourceKey>
|
|
18
|
+
- For system-level rollup across datasources, use:
|
|
19
|
+
aifabrix test <systemKey>
|
|
20
|
+
`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function datasourceTestIntegrationHelpAfter() {
|
|
24
|
+
return `
|
|
25
|
+
Examples:
|
|
26
|
+
$ aifabrix datasource test-integration hubspot-users
|
|
27
|
+
$ aifabrix datasource test-integration hubspot-users --app test-e2e-hubspot --debug
|
|
28
|
+
$ aifabrix datasource test-integration hubspot-users -a test-e2e-hubspot -e tst --timeout 60000
|
|
29
|
+
|
|
30
|
+
Notes:
|
|
31
|
+
- For structural/policy validation, use:
|
|
32
|
+
aifabrix datasource test <datasourceKey>
|
|
33
|
+
- For E2E capability execution, use:
|
|
34
|
+
aifabrix datasource test-e2e <datasourceKey>
|
|
35
|
+
- For system-level integration rollup across datasources, use:
|
|
36
|
+
aifabrix test-integration <systemKey>
|
|
37
|
+
`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function datasourceTestE2eHelpAfter() {
|
|
41
|
+
return `
|
|
42
|
+
Examples:
|
|
43
|
+
$ aifabrix datasource test-e2e hubspot-users
|
|
44
|
+
$ aifabrix datasource test-e2e hubspot-users --app test-e2e-hubspot -v --debug
|
|
45
|
+
$ aifabrix datasource test-e2e hubspot-users -a test-e2e-hubspot --no-async
|
|
46
|
+
$ aifabrix datasource test-e2e hubspot-users read
|
|
47
|
+
|
|
48
|
+
Notes:
|
|
49
|
+
- For structural/policy validation, use:
|
|
50
|
+
aifabrix datasource test <datasourceKey>
|
|
51
|
+
- For integration pipeline tests, use:
|
|
52
|
+
aifabrix datasource test-integration <datasourceKey>
|
|
53
|
+
- For system-level E2E rollup across datasources, use:
|
|
54
|
+
aifabrix test-e2e <systemKey>
|
|
55
|
+
`;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @param {object} cmd - Commander command (chainable)
|
|
60
|
+
* @returns {object}
|
|
61
|
+
*/
|
|
62
|
+
function attachDatasourceWatchOptions(cmd) {
|
|
63
|
+
return cmd
|
|
64
|
+
.option(
|
|
65
|
+
'--watch',
|
|
66
|
+
'Re-run when watched files change (debounced; integration tree + optional paths)'
|
|
67
|
+
)
|
|
68
|
+
.option(
|
|
69
|
+
'--watch-path <path>',
|
|
70
|
+
'Extra file or directory to watch (repeatable)',
|
|
71
|
+
(value, previous) => (Array.isArray(previous) ? previous : []).concat(value),
|
|
72
|
+
[]
|
|
73
|
+
)
|
|
74
|
+
.option('--watch-application-yaml', 'Include integration/<app>/application.yaml in the watch set')
|
|
75
|
+
.option('--watch-ci', 'Exit after the first run with the normal exit code (CI one-shot)')
|
|
76
|
+
.option('--watch-full-diff', 'Print full before/after fingerprint lines when the result changes');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Shared options for datasource-level `test`, `test-integration`, and `test-e2e`.
|
|
81
|
+
*
|
|
82
|
+
* Registration order matches intended `--help` order: core run flags → payload/timeout →
|
|
83
|
+
* `--sync` (pre-run publish) → machine/exit modifiers → async → watch (last before `--help`).
|
|
84
|
+
* Callers must append `addHelpText('after', …)` **after** any command-specific options (e.g. E2E).
|
|
85
|
+
*
|
|
86
|
+
* @param {object} cmd - Commander command (chainable)
|
|
87
|
+
* @param {Object} opts
|
|
88
|
+
* @param {boolean} [opts.includeNoAsync]
|
|
89
|
+
* @param {boolean} [opts.includePayload]
|
|
90
|
+
* @param {string} [opts.appHelp]
|
|
91
|
+
* @param {string} [opts.verboseHelp]
|
|
92
|
+
* @param {string} [opts.debugHelp]
|
|
93
|
+
* @param {string} [opts.timeoutHelp]
|
|
94
|
+
* @param {string} [opts.timeoutDefault]
|
|
95
|
+
* @returns {object}
|
|
96
|
+
*/
|
|
97
|
+
function attachDatasourceTestCommonOptions(cmd, opts) {
|
|
98
|
+
const includeNoAsync = opts.includeNoAsync === true;
|
|
99
|
+
const includePayload = opts.includePayload !== false;
|
|
100
|
+
|
|
101
|
+
cmd
|
|
102
|
+
.option(
|
|
103
|
+
'-a, --app <app>',
|
|
104
|
+
opts.appHelp ||
|
|
105
|
+
'Integration folder name (optional: resolve from cwd or datasource key if single match)'
|
|
106
|
+
)
|
|
107
|
+
.option('-e, --env <env>', 'Environment: dev, tst, or pro')
|
|
108
|
+
.option('-v, --verbose', opts.verboseHelp || 'Explain mode and detailed output where available')
|
|
109
|
+
.option(
|
|
110
|
+
'-d, --debug [level]',
|
|
111
|
+
opts.debugHelp ||
|
|
112
|
+
'includeDebug on request; TTY appendix: summary (default), full, or raw (not with --json)'
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
if (includePayload) {
|
|
116
|
+
cmd.option('-p, --payload <file>', 'Optional custom payload file (sets payloadTemplate on request)');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
cmd
|
|
120
|
+
.option(
|
|
121
|
+
'--timeout <ms>',
|
|
122
|
+
opts.timeoutHelp || 'Aggregate timeout for POST + polls (ms)',
|
|
123
|
+
opts.timeoutDefault || '30000'
|
|
124
|
+
)
|
|
125
|
+
.option(
|
|
126
|
+
'--sync',
|
|
127
|
+
'Publish this datasource JSON from disk to the dataplane before running the test (requires login / same auth as upload)'
|
|
128
|
+
)
|
|
129
|
+
.option('--json', 'Print raw DatasourceTestRun JSON to stdout')
|
|
130
|
+
.option('--summary', 'Print compact summary line')
|
|
131
|
+
.option('--warnings-as-errors', 'Exit 1 when root status is warn')
|
|
132
|
+
.option('--require-cert', 'Exit 2 when certificate missing or not_passed');
|
|
133
|
+
|
|
134
|
+
if (includeNoAsync) {
|
|
135
|
+
cmd.option('--no-async', 'Do not poll; fail if report is not complete in first response');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
attachDatasourceWatchOptions(cmd);
|
|
139
|
+
return cmd;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
module.exports = {
|
|
143
|
+
datasourceTestHelpAfter,
|
|
144
|
+
datasourceTestIntegrationHelpAfter,
|
|
145
|
+
datasourceTestE2eHelpAfter,
|
|
146
|
+
attachDatasourceWatchOptions,
|
|
147
|
+
attachDatasourceTestCommonOptions
|
|
148
|
+
};
|
|
149
|
+
|