@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
package/lib/datasource/deploy.js
CHANGED
|
@@ -17,6 +17,16 @@ const { publishDatasourceViaPipeline } = require('../api/pipeline.api');
|
|
|
17
17
|
const { formatApiError } = require('../utils/api-error-handler');
|
|
18
18
|
const logger = require('../utils/logger');
|
|
19
19
|
const { logDataplanePipelineWarning } = require('../utils/dataplane-pipeline-warning');
|
|
20
|
+
const {
|
|
21
|
+
sectionTitle,
|
|
22
|
+
headerKeyValue,
|
|
23
|
+
metadata,
|
|
24
|
+
infoLine,
|
|
25
|
+
formatStatusKeyValue,
|
|
26
|
+
formatBlockingError,
|
|
27
|
+
successGlyph,
|
|
28
|
+
failureGlyph
|
|
29
|
+
} = require('../utils/cli-test-layout-chalk');
|
|
20
30
|
const {
|
|
21
31
|
buildResolvedEnvMapForIntegration,
|
|
22
32
|
resolveConfigurationValues
|
|
@@ -64,41 +74,41 @@ async function getDataplaneUrl(controllerUrl, appKey, environment, authConfig) {
|
|
|
64
74
|
}
|
|
65
75
|
|
|
66
76
|
/**
|
|
67
|
-
* Validate
|
|
68
|
-
* @param {string}
|
|
69
|
-
* @param {string} filePath - File path
|
|
70
|
-
* @param {Object} options - Options
|
|
77
|
+
* Validate deploy CLI input (file path or datasource key, same rules as `datasource validate`).
|
|
78
|
+
* @param {string} fileOrKey - Path to JSON or datasource `key` under integration/<app>/
|
|
71
79
|
* @throws {Error} If validation fails
|
|
72
80
|
*/
|
|
73
|
-
function
|
|
74
|
-
if (!
|
|
75
|
-
throw new Error('
|
|
76
|
-
}
|
|
77
|
-
if (!filePath || typeof filePath !== 'string') {
|
|
78
|
-
throw new Error('File path is required');
|
|
81
|
+
function validateDeployFileOrKeyInput(fileOrKey) {
|
|
82
|
+
if (!fileOrKey || typeof fileOrKey !== 'string' || !fileOrKey.trim()) {
|
|
83
|
+
throw new Error('File path or datasource key is required');
|
|
79
84
|
}
|
|
80
85
|
}
|
|
81
86
|
|
|
82
87
|
/**
|
|
83
|
-
* Validate and load datasource file
|
|
88
|
+
* Validate and load datasource file (path or datasource key, resolved like `datasource validate`).
|
|
84
89
|
* @async
|
|
85
|
-
* @param {string}
|
|
90
|
+
* @param {string} filePathOrKey - Path to datasource JSON or datasource `key`
|
|
86
91
|
* @returns {Promise<Object>} Datasource configuration
|
|
87
92
|
* @throws {Error} If validation or loading fails
|
|
88
93
|
*/
|
|
89
|
-
async function validateAndLoadDatasourceFile(
|
|
90
|
-
logger.log(
|
|
91
|
-
const validation = await validateDatasourceFile(
|
|
94
|
+
async function validateAndLoadDatasourceFile(filePathOrKey) {
|
|
95
|
+
logger.log(infoLine('ℹ Validating datasource file'));
|
|
96
|
+
const validation = await validateDatasourceFile(filePathOrKey);
|
|
92
97
|
if (!validation.valid) {
|
|
93
|
-
logger.
|
|
98
|
+
logger.log('');
|
|
99
|
+
logger.error(formatBlockingError('Datasource validation failed'));
|
|
94
100
|
validation.errors.forEach(error => {
|
|
95
|
-
logger.error(
|
|
101
|
+
logger.error(formatBlockingError(error));
|
|
96
102
|
});
|
|
97
103
|
throw new Error('Datasource file validation failed');
|
|
98
104
|
}
|
|
99
|
-
logger.log(chalk.green('✓ Datasource file is valid'));
|
|
100
105
|
|
|
101
|
-
const
|
|
106
|
+
const resolvedPath = validation.resolvedPath;
|
|
107
|
+
logger.log(headerKeyValue('File:', resolvedPath));
|
|
108
|
+
logger.log(`${successGlyph()} ${chalk.white('Datasource file is valid.')}`);
|
|
109
|
+
logger.log('');
|
|
110
|
+
|
|
111
|
+
const content = fs.readFileSync(resolvedPath, 'utf8');
|
|
102
112
|
try {
|
|
103
113
|
return JSON.parse(content);
|
|
104
114
|
} catch (error) {
|
|
@@ -116,28 +126,28 @@ async function validateAndLoadDatasourceFile(filePath) {
|
|
|
116
126
|
*/
|
|
117
127
|
async function setupDeploymentAuth(controllerUrl, environment, appKey) {
|
|
118
128
|
const { resolveDataplaneUrl } = require('../utils/dataplane-resolver');
|
|
119
|
-
logger.log(
|
|
129
|
+
logger.log(infoLine('ℹ Resolving authentication'));
|
|
120
130
|
const authConfig = await getDeploymentAuth(controllerUrl, environment, appKey);
|
|
121
|
-
logger.log(chalk.
|
|
131
|
+
logger.log(`${successGlyph()} ${chalk.white('Authentication ready')}`);
|
|
122
132
|
|
|
123
|
-
logger.log(
|
|
133
|
+
logger.log(infoLine('ℹ Resolving dataplane URL'));
|
|
124
134
|
let dataplaneUrl;
|
|
125
135
|
try {
|
|
126
136
|
dataplaneUrl = await resolveDataplaneUrl(controllerUrl, environment, authConfig);
|
|
127
|
-
logger.log(
|
|
137
|
+
logger.log(`${metadata('Dataplane:')} ${chalk.cyan(dataplaneUrl)}`);
|
|
128
138
|
} catch (error) {
|
|
129
|
-
logger.error(chalk.red('
|
|
130
|
-
logger.error(
|
|
131
|
-
logger.error(
|
|
132
|
-
logger.error(
|
|
139
|
+
logger.error(`${failureGlyph()} ${chalk.red('Failed to resolve dataplane URL:')} ${chalk.red(error.message)}`);
|
|
140
|
+
logger.error(metadata('The dataplane URL is automatically discovered from the controller.'));
|
|
141
|
+
logger.error(metadata('If discovery fails, ensure you are logged in and the controller is accessible:'));
|
|
142
|
+
logger.error(metadata('aifabrix login'));
|
|
133
143
|
throw error;
|
|
134
144
|
}
|
|
135
145
|
|
|
136
146
|
// Validate dataplane URL
|
|
137
147
|
if (!dataplaneUrl || !dataplaneUrl.trim()) {
|
|
138
|
-
logger.error(chalk.red('
|
|
139
|
-
logger.error(
|
|
140
|
-
logger.error(
|
|
148
|
+
logger.error(`${failureGlyph()} ${chalk.red('Dataplane URL is empty.')}`);
|
|
149
|
+
logger.error(metadata('The dataplane URL could not be discovered from the controller.'));
|
|
150
|
+
logger.error(metadata('Ensure the dataplane service is registered in the controller.'));
|
|
141
151
|
throw new Error('Dataplane URL is empty');
|
|
142
152
|
}
|
|
143
153
|
|
|
@@ -156,30 +166,32 @@ async function setupDeploymentAuth(controllerUrl, environment, appKey) {
|
|
|
156
166
|
*/
|
|
157
167
|
async function publishDatasourceToDataplane(dataplaneUrl, systemKey, authConfig, datasourceConfig) {
|
|
158
168
|
requireBearerForDataplanePipeline(authConfig);
|
|
159
|
-
logger.log(
|
|
169
|
+
logger.log('');
|
|
170
|
+
logger.log(sectionTitle('Publish'));
|
|
160
171
|
logDataplanePipelineWarning();
|
|
161
172
|
|
|
162
173
|
const publishResponse = await publishDatasourceViaPipeline(dataplaneUrl, systemKey, authConfig, datasourceConfig);
|
|
163
174
|
|
|
164
175
|
if (!publishResponse.success) {
|
|
165
176
|
const formattedError = publishResponse.formattedError || formatApiError(publishResponse);
|
|
166
|
-
logger.error(chalk.red('
|
|
167
|
-
logger.error(formattedError);
|
|
177
|
+
logger.error(`${failureGlyph()} ${chalk.red('Publish failed:')} ${chalk.red(formattedError)}`);
|
|
168
178
|
|
|
169
179
|
// Show dataplane URL and endpoint information
|
|
170
180
|
if (publishResponse.errorData && publishResponse.errorData.endpointUrl) {
|
|
171
|
-
logger.error(
|
|
181
|
+
logger.error(
|
|
182
|
+
`\n${metadata('Endpoint URL:')} ${chalk.cyan(publishResponse.errorData.endpointUrl)}`
|
|
183
|
+
);
|
|
172
184
|
} else if (dataplaneUrl) {
|
|
173
|
-
logger.error(
|
|
174
|
-
logger.error(
|
|
185
|
+
logger.error(`\n${metadata('Dataplane URL:')} ${chalk.cyan(dataplaneUrl)}`);
|
|
186
|
+
logger.error(headerKeyValue('System Key:', systemKey));
|
|
175
187
|
}
|
|
176
188
|
|
|
177
|
-
logger.error(
|
|
178
|
-
logger.error(
|
|
189
|
+
logger.error(metadata('\nFull response for debugging:'));
|
|
190
|
+
logger.error(metadata(JSON.stringify(publishResponse, null, 2)));
|
|
179
191
|
throw new Error(`Dataplane publish failed: ${formattedError}`);
|
|
180
192
|
}
|
|
181
193
|
|
|
182
|
-
logger.log(chalk.
|
|
194
|
+
logger.log(`${successGlyph()} ${chalk.white('Configuration published to dataplane.')}`);
|
|
183
195
|
return publishResponse;
|
|
184
196
|
}
|
|
185
197
|
|
|
@@ -190,9 +202,21 @@ async function publishDatasourceToDataplane(dataplaneUrl, systemKey, authConfig,
|
|
|
190
202
|
* @param {string} environment - Environment key
|
|
191
203
|
*/
|
|
192
204
|
function displayDeploymentResults(datasourceConfig, systemKey, environment) {
|
|
193
|
-
|
|
194
|
-
logger.log(
|
|
195
|
-
logger.log(
|
|
205
|
+
const datasourceLabel = datasourceConfig.key || datasourceConfig.displayName || '(unknown)';
|
|
206
|
+
logger.log('');
|
|
207
|
+
logger.log(sectionTitle('Result'));
|
|
208
|
+
logger.log(headerKeyValue('Datasource:', datasourceLabel));
|
|
209
|
+
logger.log(headerKeyValue('System:', systemKey));
|
|
210
|
+
logger.log(headerKeyValue('Environment:', environment));
|
|
211
|
+
logger.log('');
|
|
212
|
+
logger.log(formatStatusKeyValue('ok', '✔'));
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function logDatasourceUploadSectionHeader() {
|
|
216
|
+
logger.log('');
|
|
217
|
+
logger.log(sectionTitle('Datasource upload'));
|
|
218
|
+
logger.log(metadata('Publish one datasource JSON to the dataplane'));
|
|
219
|
+
logger.log('');
|
|
196
220
|
}
|
|
197
221
|
|
|
198
222
|
/**
|
|
@@ -201,18 +225,17 @@ function displayDeploymentResults(datasourceConfig, systemKey, environment) {
|
|
|
201
225
|
*
|
|
202
226
|
* @async
|
|
203
227
|
* @function deployDatasource
|
|
204
|
-
* @param {string}
|
|
205
|
-
* @param {string} filePath - Path to datasource JSON file
|
|
228
|
+
* @param {string} fileOrKey - Path to datasource JSON file, or datasource `key` under integration/<app>/ (same resolution as `datasource validate`)
|
|
206
229
|
* @param {Object} [_options] - Deployment options (reserved)
|
|
207
230
|
* @returns {Promise<Object>} Deployment result
|
|
208
231
|
* @throws {Error} If deployment fails
|
|
209
232
|
*/
|
|
210
|
-
async function deployDatasource(
|
|
233
|
+
async function deployDatasource(fileOrKey, _options) {
|
|
211
234
|
const { resolveControllerUrl } = require('../utils/controller-url');
|
|
212
235
|
const { resolveEnvironment } = require('../core/config');
|
|
213
236
|
const { displayCommandHeader } = require('../utils/command-header');
|
|
214
237
|
|
|
215
|
-
|
|
238
|
+
validateDeployFileOrKeyInput(fileOrKey);
|
|
216
239
|
|
|
217
240
|
// Resolve controller and environment from config
|
|
218
241
|
const controllerUrl = await resolveControllerUrl();
|
|
@@ -220,13 +243,12 @@ async function deployDatasource(appKey, filePath, _options) {
|
|
|
220
243
|
|
|
221
244
|
// Display command header
|
|
222
245
|
displayCommandHeader(controllerUrl, environment);
|
|
246
|
+
logDatasourceUploadSectionHeader();
|
|
223
247
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
// Validate and load datasource file
|
|
227
|
-
const datasourceConfig = await validateAndLoadDatasourceFile(filePath);
|
|
248
|
+
// Validate and load datasource file (resolves key → path like validate)
|
|
249
|
+
const datasourceConfig = await validateAndLoadDatasourceFile(fileOrKey.trim());
|
|
228
250
|
|
|
229
|
-
// Extract systemKey
|
|
251
|
+
// Extract systemKey (required in JSON; also used as controller app key for external systems)
|
|
230
252
|
const systemKey = datasourceConfig.systemKey;
|
|
231
253
|
if (!systemKey) {
|
|
232
254
|
throw new Error('systemKey is required in datasource configuration');
|
|
@@ -237,8 +259,8 @@ async function deployDatasource(appKey, filePath, _options) {
|
|
|
237
259
|
resolveConfigurationValues(datasourceConfig.configuration, envMap, secrets, systemKey);
|
|
238
260
|
}
|
|
239
261
|
|
|
240
|
-
// Setup authentication and get dataplane URL
|
|
241
|
-
const { authConfig, dataplaneUrl } = await setupDeploymentAuth(controllerUrl, environment,
|
|
262
|
+
// Setup authentication and get dataplane URL (application key matches systemKey for external integrations)
|
|
263
|
+
const { authConfig, dataplaneUrl } = await setupDeploymentAuth(controllerUrl, environment, systemKey);
|
|
242
264
|
|
|
243
265
|
// Publish to dataplane
|
|
244
266
|
await publishDatasourceToDataplane(dataplaneUrl, systemKey, authConfig, datasourceConfig);
|
|
@@ -11,78 +11,119 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* or empty, returns no errors (skip check, matching dataplane behavior).
|
|
14
|
+
* Set of attribute names plus root dimension keys valid for field references.
|
|
15
|
+
* Used for primaryKey (schema allows dimension keys or attributes) and other paths (attributes only).
|
|
17
16
|
*
|
|
18
|
-
* @
|
|
19
|
-
* @
|
|
20
|
-
* @returns {string[]} Array of error messages; empty if no invalid references
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* const errors = validateFieldReferences(parsed);
|
|
24
|
-
* if (errors.length > 0) {
|
|
25
|
-
* errors.forEach(e => console.error(e));
|
|
26
|
-
* }
|
|
17
|
+
* @param {Object} parsed - Parsed datasource object
|
|
18
|
+
* @returns {{ attributes: string[], attributesAndDimensions: Set<string> }}
|
|
27
19
|
*/
|
|
28
|
-
function
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
20
|
+
function getNormalizedSets(parsed) {
|
|
21
|
+
const attributes = Object.keys(parsed?.fieldMappings?.attributes ?? {});
|
|
22
|
+
const rootDims = Object.keys(parsed?.dimensions ?? {}).filter(k => {
|
|
23
|
+
const b = parsed.dimensions[k];
|
|
24
|
+
return b && typeof b === 'object';
|
|
25
|
+
});
|
|
26
|
+
const attributesAndDimensions = new Set([...attributes, ...rootDims]);
|
|
27
|
+
return { attributes, attributesAndDimensions };
|
|
28
|
+
}
|
|
33
29
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
/** @param {string[]} errors */
|
|
31
|
+
function checkPrimaryKey(parsed, attributesAndDimensions, errors) {
|
|
32
|
+
const primaryKey = parsed?.primaryKey;
|
|
33
|
+
if (!Array.isArray(primaryKey)) return;
|
|
34
|
+
primaryKey.forEach((field, i) => {
|
|
35
|
+
if (typeof field === 'string' && field !== '' && !attributesAndDimensions.has(field)) {
|
|
36
|
+
errors.push(
|
|
37
|
+
`primaryKey[${i}]: field '${field}' does not exist in fieldMappings.attributes or root dimensions. Each primaryKey value must reference an attribute or dimension key.`
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** @param {string[]} errors */
|
|
44
|
+
function checkExposedProfiles(parsed, attrSet, errors) {
|
|
45
|
+
const profiles = parsed?.exposed?.profiles;
|
|
46
|
+
if (!profiles || typeof profiles !== 'object' || Array.isArray(profiles)) return;
|
|
47
|
+
Object.entries(profiles).forEach(([profileName, fields]) => {
|
|
48
|
+
if (!Array.isArray(fields)) return;
|
|
49
|
+
fields.forEach((field, idx) => {
|
|
50
|
+
if (typeof field === 'string' && !attrSet.has(field)) {
|
|
51
|
+
errors.push(
|
|
52
|
+
`exposed.profiles.${profileName}[${idx}]: field '${field}' does not exist in fieldMappings.attributes. Add the attribute or remove the reference.`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
37
58
|
|
|
38
|
-
|
|
59
|
+
/** @param {string[]} errors */
|
|
60
|
+
function checkIndexingAndValidation(parsed, normalizedAttributes, errors) {
|
|
39
61
|
const embedding = parsed?.indexing?.embedding;
|
|
40
62
|
if (Array.isArray(embedding)) {
|
|
41
63
|
embedding.forEach((field, i) => {
|
|
42
64
|
if (typeof field === 'string' && !normalizedAttributes.includes(field)) {
|
|
43
65
|
errors.push(
|
|
44
|
-
`indexing.embedding[${i}]: field '${field}' does not exist in fieldMappings.attributes
|
|
66
|
+
`indexing.embedding[${i}]: field '${field}' does not exist in fieldMappings.attributes. Add the attribute or remove the reference.`
|
|
45
67
|
);
|
|
46
68
|
}
|
|
47
69
|
});
|
|
48
70
|
}
|
|
49
|
-
|
|
50
|
-
// indexing.uniqueKey: single field name
|
|
51
71
|
const uniqueKey = parsed?.indexing?.uniqueKey;
|
|
52
|
-
if (typeof uniqueKey === 'string' && uniqueKey !== '') {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
);
|
|
57
|
-
}
|
|
72
|
+
if (typeof uniqueKey === 'string' && uniqueKey !== '' && !normalizedAttributes.includes(uniqueKey)) {
|
|
73
|
+
errors.push(
|
|
74
|
+
`indexing.uniqueKey: field '${uniqueKey}' does not exist in fieldMappings.attributes. Add the attribute or remove the reference.`
|
|
75
|
+
);
|
|
58
76
|
}
|
|
59
|
-
|
|
60
|
-
// validation.repeatingValues[].field
|
|
61
77
|
const repeatingValues = parsed?.validation?.repeatingValues;
|
|
62
78
|
if (Array.isArray(repeatingValues)) {
|
|
63
79
|
repeatingValues.forEach((rule, index) => {
|
|
64
80
|
const field = rule?.field;
|
|
65
81
|
if (typeof field === 'string' && !normalizedAttributes.includes(field)) {
|
|
66
82
|
errors.push(
|
|
67
|
-
`validation.repeatingValues[${index}].field: field '${field}' does not exist in fieldMappings.attributes
|
|
83
|
+
`validation.repeatingValues[${index}].field: field '${field}' does not exist in fieldMappings.attributes. Add the attribute or remove the reference.`
|
|
68
84
|
);
|
|
69
85
|
}
|
|
70
86
|
});
|
|
71
87
|
}
|
|
72
|
-
|
|
73
|
-
// quality.rejectIf[].field
|
|
74
88
|
const rejectIf = parsed?.quality?.rejectIf;
|
|
75
89
|
if (Array.isArray(rejectIf)) {
|
|
76
90
|
rejectIf.forEach((rule, index) => {
|
|
77
91
|
const field = rule?.field;
|
|
78
92
|
if (typeof field === 'string' && !normalizedAttributes.includes(field)) {
|
|
79
93
|
errors.push(
|
|
80
|
-
`quality.rejectIf[${index}].field: field '${field}' does not exist in fieldMappings.attributes
|
|
94
|
+
`quality.rejectIf[${index}].field: field '${field}' does not exist in fieldMappings.attributes. Add the attribute or remove the reference.`
|
|
81
95
|
);
|
|
82
96
|
}
|
|
83
97
|
});
|
|
84
98
|
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Validates that all field references in indexing, validation, quality,
|
|
103
|
+
* primaryKey, and exposed.profiles exist in fieldMappings.attributes (or
|
|
104
|
+
* root dimension keys for primaryKey per schema). When fieldMappings.attributes is
|
|
105
|
+
* missing or empty, returns no errors (skip check, matching dataplane behavior).
|
|
106
|
+
*
|
|
107
|
+
* @function validateFieldReferences
|
|
108
|
+
* @param {Object} parsed - Parsed datasource object (after JSON parse)
|
|
109
|
+
* @returns {string[]} Array of error messages; empty if no invalid references
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* const errors = validateFieldReferences(parsed);
|
|
113
|
+
* if (errors.length > 0) {
|
|
114
|
+
* errors.forEach(e => console.error(e));
|
|
115
|
+
* }
|
|
116
|
+
*/
|
|
117
|
+
function validateFieldReferences(parsed) {
|
|
118
|
+
const errors = [];
|
|
119
|
+
const { attributes: normalizedAttributes, attributesAndDimensions } = getNormalizedSets(parsed);
|
|
120
|
+
const attrSet = new Set(normalizedAttributes);
|
|
121
|
+
|
|
122
|
+
checkPrimaryKey(parsed, attributesAndDimensions, errors);
|
|
123
|
+
checkExposedProfiles(parsed, attrSet, errors);
|
|
124
|
+
if (normalizedAttributes.length === 0) return errors;
|
|
85
125
|
|
|
126
|
+
checkIndexingAndValidation(parsed, normalizedAttributes, errors);
|
|
86
127
|
return errors;
|
|
87
128
|
}
|
|
88
129
|
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared integration app resolution (system key, datasource file lookup).
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 2.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const fs = require('fs').promises;
|
|
9
|
+
const { getIntegrationPath } = require('../utils/paths');
|
|
10
|
+
const { resolveApplicationConfigPath } = require('../utils/app-config-resolver');
|
|
11
|
+
const { loadConfigFile } = require('../utils/config-format');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param {string} appKey - Integration app key
|
|
15
|
+
* @returns {Promise<string>} systemKey
|
|
16
|
+
*/
|
|
17
|
+
async function getSystemKeyFromAppKey(appKey) {
|
|
18
|
+
const appPath = getIntegrationPath(appKey);
|
|
19
|
+
const configPath = resolveApplicationConfigPath(appPath);
|
|
20
|
+
const config = loadConfigFile(configPath);
|
|
21
|
+
if (!config.externalIntegration || !config.externalIntegration.systems || config.externalIntegration.systems.length === 0) {
|
|
22
|
+
throw new Error(`No externalIntegration.systems found in ${configPath}`);
|
|
23
|
+
}
|
|
24
|
+
const systemFile = config.externalIntegration.systems[0];
|
|
25
|
+
const systemPath = path.isAbsolute(systemFile)
|
|
26
|
+
? systemFile
|
|
27
|
+
: path.join(appPath, systemFile);
|
|
28
|
+
const systemContent = await fs.readFile(systemPath, 'utf8');
|
|
29
|
+
const yaml = require('js-yaml');
|
|
30
|
+
const systemConfig = yaml.load(systemContent);
|
|
31
|
+
return systemConfig?.key || path.basename(systemFile, '-system.yaml').replace('-system', '');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Find a datasource filename by matching the key inside the file.
|
|
36
|
+
* @param {string} appPath
|
|
37
|
+
* @param {string} schemaBasePath
|
|
38
|
+
* @param {string[]} datasourceFiles
|
|
39
|
+
* @param {string} datasourceKey
|
|
40
|
+
* @returns {string|null}
|
|
41
|
+
*/
|
|
42
|
+
function findDatasourceFileByKey(appPath, schemaBasePath, datasourceFiles, datasourceKey) {
|
|
43
|
+
const fsSync = require('fs');
|
|
44
|
+
for (const f of datasourceFiles) {
|
|
45
|
+
if (!f || typeof f !== 'string') continue;
|
|
46
|
+
const fullPath = path.isAbsolute(schemaBasePath)
|
|
47
|
+
? path.join(schemaBasePath, f)
|
|
48
|
+
: path.join(appPath, schemaBasePath, f);
|
|
49
|
+
if (!fsSync.existsSync(fullPath)) continue;
|
|
50
|
+
try {
|
|
51
|
+
const parsed = loadConfigFile(fullPath);
|
|
52
|
+
if (parsed && parsed.key === datasourceKey) return f;
|
|
53
|
+
} catch {
|
|
54
|
+
// skip unreadable or invalid files
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module.exports = {
|
|
61
|
+
getSystemKeyFromAppKey,
|
|
62
|
+
findDatasourceFileByKey
|
|
63
|
+
};
|
package/lib/datasource/list.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
const { formatBlockingError } = require('../utils/cli-test-layout-chalk');
|
|
1
2
|
/**
|
|
2
3
|
* Datasource List Command
|
|
3
4
|
*
|
|
4
|
-
* Lists datasources from the dataplane (GET /api/v1/external
|
|
5
|
+
* Lists datasources from the dataplane (GET /api/v1/external).
|
|
5
6
|
* Resolves dataplane URL from the controller, then calls the dataplane list API.
|
|
6
7
|
*
|
|
7
8
|
* @fileoverview Datasource listing for AI Fabrix Builder
|
|
@@ -74,7 +75,7 @@ function extractFromPaginatedFormat(apiResponse) {
|
|
|
74
75
|
* @param {Object} apiResponse - API response object
|
|
75
76
|
*/
|
|
76
77
|
function logInvalidResponseError(apiResponse) {
|
|
77
|
-
logger.error(
|
|
78
|
+
logger.error(formatBlockingError('Invalid response: expected data array or items array'));
|
|
78
79
|
logger.error(chalk.gray('\nAPI response type:'), typeof apiResponse);
|
|
79
80
|
logger.error(chalk.gray('API response:'), JSON.stringify(apiResponse, null, 2));
|
|
80
81
|
}
|
|
@@ -177,7 +178,7 @@ async function getDeviceTokenFromConfig(config) {
|
|
|
177
178
|
*/
|
|
178
179
|
function validateDatasourceListingAuth(token, controllerUrl) {
|
|
179
180
|
if (!token || !controllerUrl || (typeof controllerUrl === 'string' && !controllerUrl.trim())) {
|
|
180
|
-
logger.error(
|
|
181
|
+
logger.error(formatBlockingError('Not logged in. Run: aifabrix login'));
|
|
181
182
|
logger.error(chalk.gray(' Use device code flow: aifabrix login --method device --controller <url>'));
|
|
182
183
|
process.exit(1);
|
|
183
184
|
}
|
|
@@ -215,7 +216,7 @@ function handleDatasourceApiError(response, dataplaneUrl = null) {
|
|
|
215
216
|
function validateControllerUrl(controllerUrl) {
|
|
216
217
|
const trimmed = controllerUrl.trim();
|
|
217
218
|
if (!trimmed) {
|
|
218
|
-
logger.error(
|
|
219
|
+
logger.error(formatBlockingError('Controller URL is empty.'));
|
|
219
220
|
logger.error(chalk.gray(` Controller URL from config: ${JSON.stringify(controllerUrl)}`));
|
|
220
221
|
logger.error(chalk.gray(' Run: aifabrix login --method device --controller <url>'));
|
|
221
222
|
process.exit(1);
|
|
@@ -238,7 +239,7 @@ async function resolveAndValidateDataplaneUrl(controllerUrl, environment, authCo
|
|
|
238
239
|
// discoverDataplaneUrl already logs progress and success messages
|
|
239
240
|
dataplaneUrl = await resolveDataplaneUrl(controllerUrl, environment, authConfig);
|
|
240
241
|
} catch (error) {
|
|
241
|
-
logger.error(
|
|
242
|
+
logger.error(formatBlockingError('Failed to resolve dataplane URL:'), error.message);
|
|
242
243
|
logger.error(chalk.gray('\nThe dataplane URL is automatically discovered from the controller.'));
|
|
243
244
|
logger.error(chalk.gray('If discovery fails, ensure you are logged in and the controller is accessible:'));
|
|
244
245
|
logger.error(chalk.gray(' aifabrix login'));
|
|
@@ -248,7 +249,7 @@ async function resolveAndValidateDataplaneUrl(controllerUrl, environment, authCo
|
|
|
248
249
|
}
|
|
249
250
|
|
|
250
251
|
if (!dataplaneUrl || typeof dataplaneUrl !== 'string' || !dataplaneUrl.trim()) {
|
|
251
|
-
logger.error(
|
|
252
|
+
logger.error(formatBlockingError('Dataplane URL is empty.'));
|
|
252
253
|
logger.error(chalk.gray('The dataplane URL could not be discovered from the controller.'));
|
|
253
254
|
logger.error(chalk.gray('Ensure the dataplane service is registered in the controller.'));
|
|
254
255
|
process.exit(1);
|
|
@@ -295,7 +296,7 @@ async function listDatasources(_options) {
|
|
|
295
296
|
// Resolve dataplane URL first (required for list call)
|
|
296
297
|
const dataplaneUrl = await resolveAndValidateDataplaneUrl(controllerUrl, environment, authConfig);
|
|
297
298
|
|
|
298
|
-
// List datasources from dataplane (GET /api/v1/external
|
|
299
|
+
// List datasources from dataplane (GET /api/v1/external)
|
|
299
300
|
const response = await listDatasourcesFromDataplane(dataplaneUrl, authConfig);
|
|
300
301
|
|
|
301
302
|
if (!response.success || !response.data) {
|