@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
|
@@ -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,13 +9,14 @@
|
|
|
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');
|
|
19
|
+
const { getKvPathSegmentForSecurityKey } = require('../utils/credential-secrets-env');
|
|
19
20
|
|
|
20
21
|
// Register Handlebars helper for equality check
|
|
21
22
|
handlebars.registerHelper('eq', (a, b) => a === b);
|
|
@@ -23,36 +24,39 @@ handlebars.registerHelper('json', (obj) => JSON.stringify(obj));
|
|
|
23
24
|
|
|
24
25
|
/**
|
|
25
26
|
* Build authentication object per schema authenticationVariablesByMethod.
|
|
26
|
-
* Security values use kv://<systemKey>/<
|
|
27
|
+
* Security values use canonical kv://<systemKey>/<segment> paths (segment from getKvPathSegmentForSecurityKey).
|
|
27
28
|
* @param {string} systemKey - External system key
|
|
28
29
|
* @param {string} authType - Auth method (oauth2, aad, apikey, basic, queryParam, oidc, hmac, none)
|
|
29
30
|
* @returns {{ method: string, variables: Object, security: Object }} Authentication object
|
|
30
31
|
*/
|
|
31
32
|
function buildAuthenticationFromMethod(systemKey, authType) {
|
|
32
|
-
const
|
|
33
|
+
const kvPath = (securityKey) => {
|
|
34
|
+
const segment = getKvPathSegmentForSecurityKey(securityKey);
|
|
35
|
+
return segment ? `kv://${systemKey}/${segment}` : null;
|
|
36
|
+
};
|
|
33
37
|
const method = authType || 'apikey';
|
|
34
38
|
const base = 'https://api.example.com';
|
|
35
39
|
|
|
36
40
|
const authMap = {
|
|
37
41
|
oauth2: {
|
|
38
42
|
variables: { baseUrl: base, tokenUrl: `${base}/oauth/token`, authorizationUrl: `${base}/oauth/authorize` },
|
|
39
|
-
security: { clientId:
|
|
43
|
+
security: { clientId: kvPath('clientId'), clientSecret: kvPath('clientSecret') }
|
|
40
44
|
},
|
|
41
45
|
aad: {
|
|
42
46
|
variables: { baseUrl: base, tokenUrl: 'https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token', tenantId: '{tenant-id}' },
|
|
43
|
-
security: { clientId:
|
|
47
|
+
security: { clientId: kvPath('clientId'), clientSecret: kvPath('clientSecret') }
|
|
44
48
|
},
|
|
45
49
|
apikey: {
|
|
46
50
|
variables: { baseUrl: base, headerName: 'X-API-Key' },
|
|
47
|
-
security: { apiKey:
|
|
51
|
+
security: { apiKey: kvPath('apiKey') }
|
|
48
52
|
},
|
|
49
53
|
basic: {
|
|
50
54
|
variables: { baseUrl: base },
|
|
51
|
-
security: { username:
|
|
55
|
+
security: { username: kvPath('username'), password: kvPath('password') }
|
|
52
56
|
},
|
|
53
57
|
queryParam: {
|
|
54
58
|
variables: { baseUrl: base, paramName: 'api_key' },
|
|
55
|
-
security: { paramValue:
|
|
59
|
+
security: { paramValue: kvPath('paramValue') }
|
|
56
60
|
},
|
|
57
61
|
oidc: {
|
|
58
62
|
variables: { openIdConfigUrl: 'https://example.com/.well-known/openid-configuration', clientId: 'app-id' },
|
|
@@ -60,7 +64,7 @@ function buildAuthenticationFromMethod(systemKey, authType) {
|
|
|
60
64
|
},
|
|
61
65
|
hmac: {
|
|
62
66
|
variables: { baseUrl: base, algorithm: 'sha256', signatureHeader: 'X-Signature' },
|
|
63
|
-
security: { signingSecret:
|
|
67
|
+
security: { signingSecret: kvPath('signingSecret') }
|
|
64
68
|
},
|
|
65
69
|
none: {
|
|
66
70
|
variables: {},
|
|
@@ -131,6 +135,68 @@ function resourceTypeToSchemaEntityType(resourceType) {
|
|
|
131
135
|
return resourceType === 'document' ? 'documentStorage' : 'recordStorage';
|
|
132
136
|
}
|
|
133
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
|
+
|
|
134
200
|
/**
|
|
135
201
|
* Build datasource context object for template rendering
|
|
136
202
|
* @param {Object} opts - Options
|
|
@@ -147,9 +213,31 @@ function resourceTypeToSchemaEntityType(resourceType) {
|
|
|
147
213
|
function buildDatasourceContext({ config, datasourceKey, dimensions, attributes, fullDatasourceKey, entityKey, schemaEntityType, resourceType }) {
|
|
148
214
|
const displayName = config.datasourceDisplayName || datasourceKey.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
|
|
149
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
|
+
|
|
150
233
|
const primaryKey = Array.isArray(config.primaryKey) && config.primaryKey.length > 0
|
|
151
234
|
? config.primaryKey
|
|
152
|
-
: ['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
|
+
|
|
153
241
|
return {
|
|
154
242
|
fullDatasourceKey,
|
|
155
243
|
entityKey,
|
|
@@ -159,9 +247,11 @@ function buildDatasourceContext({ config, datasourceKey, dimensions, attributes,
|
|
|
159
247
|
schemaEntityType,
|
|
160
248
|
resourceType,
|
|
161
249
|
primaryKey,
|
|
250
|
+
labelKey,
|
|
251
|
+
attributeKeysForMetadata,
|
|
252
|
+
dimensionBindingEntries,
|
|
162
253
|
systemType: config.systemType || 'openapi',
|
|
163
|
-
|
|
164
|
-
attributes: Object.keys(attributes).length > 0 ? attributes : null,
|
|
254
|
+
attributes: mergedAttributes,
|
|
165
255
|
raw: { id: '{{raw.id}}', name: '{{raw.name}}' }
|
|
166
256
|
};
|
|
167
257
|
}
|
|
@@ -246,7 +336,7 @@ async function generateExternalSystemFiles(appPath, appName, config, format = 'y
|
|
|
246
336
|
|
|
247
337
|
// Generate external system file
|
|
248
338
|
const systemPath = await generateExternalSystemTemplate(appPath, systemKey, config, fmt);
|
|
249
|
-
logger.log(
|
|
339
|
+
logger.log(formatSuccessLine(`Generated external system: ${path.basename(systemPath)}`));
|
|
250
340
|
|
|
251
341
|
// Generate datasource JSON files
|
|
252
342
|
const datasourcePaths = [];
|
|
@@ -274,7 +364,7 @@ async function generateExternalSystemFiles(appPath, appName, config, format = 'y
|
|
|
274
364
|
|
|
275
365
|
const datasourcePath = await generateExternalDataSourceTemplate(appPath, datasourceKey, datasourceConfig, fmt);
|
|
276
366
|
datasourcePaths.push(datasourcePath);
|
|
277
|
-
logger.log(
|
|
367
|
+
logger.log(formatSuccessLine(`Generated datasource: ${path.basename(datasourcePath)}`));
|
|
278
368
|
}
|
|
279
369
|
|
|
280
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
|
|