@aifabrix/builder 2.42.1 → 2.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursor/rules/anchor-docs.mdc +15 -0
- package/README.md +2 -2
- package/anchor-docs/README.md +10 -0
- package/anchor-docs/_TEMPLATE +24 -0
- package/bin/aifabrix.js +13 -4
- package/integration/hubspot-test/README.md +157 -0
- package/integration/{hubspot → hubspot-test}/application.json +6 -6
- package/integration/{hubspot → hubspot-test}/create-hubspot.js +10 -10
- package/integration/hubspot-test/env.template +4 -0
- package/integration/hubspot-test/hubspot-test-datasource-company.json +138 -0
- package/integration/hubspot-test/hubspot-test-datasource-contact.json +146 -0
- package/integration/hubspot-test/hubspot-test-datasource-deal.json +146 -0
- package/integration/hubspot-test/hubspot-test-datasource-users.json +76 -0
- package/integration/{hubspot/hubspot-deploy.json → hubspot-test/hubspot-test-deploy.json} +201 -24
- package/integration/{hubspot/hubspot-system.json → hubspot-test/hubspot-test-system.json} +8 -7
- package/integration/hubspot-test/rbac.json +166 -0
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-hubspot-credential-real.yaml +3 -3
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-hubspot-env-vars.yaml +2 -2
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-add-datasource.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-credential-create.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-credential-select.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-known-platform.yaml +1 -1
- package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-source.yaml +2 -0
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-mode.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-openapi-file.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-openapi-url.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-source.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-dimension-array-test.yaml +1 -1
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-key-test.yaml +5 -0
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-path-test.yaml +5 -0
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-dimension-test.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-rbac-test.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-rbac-yaml-test.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-dataplane-down-tests.js +1 -7
- package/integration/{hubspot → hubspot-test}/test-dataplane-down.js +3 -3
- package/integration/{hubspot → hubspot-test}/test.js +137 -102
- package/integration/{hubspot → hubspot-test}/wizard-hubspot-e2e.yaml +2 -2
- package/integration/{hubspot → hubspot-test}/wizard-hubspot-platform.yaml +1 -1
- package/integration/hubspot-test/wizard-hubspot-test-headless.yaml +23 -0
- package/integration/roundtrip-test-local/README.md +144 -0
- package/integration/roundtrip-test-local/application.yaml +13 -0
- package/integration/roundtrip-test-local/env.template +15 -0
- package/integration/roundtrip-test-local/roundtrip-test-local-datasource-roundtrip-test-company.yaml +14 -0
- package/integration/roundtrip-test-local/roundtrip-test-local-deploy.json +61 -0
- package/integration/roundtrip-test-local/roundtrip-test-local-system.yaml +25 -0
- package/integration/roundtrip-test-local2/README.md +144 -0
- package/integration/roundtrip-test-local2/application.yaml +13 -0
- package/integration/roundtrip-test-local2/env.template +15 -0
- package/integration/roundtrip-test-local2/roundtrip-test-local2-datasource-company.yaml +31 -0
- package/integration/roundtrip-test-local2/roundtrip-test-local2-deploy.json +86 -0
- package/integration/roundtrip-test-local2/roundtrip-test-local2-system.yaml +25 -0
- package/integration/test/wizard.yaml +8 -0
- package/jest.config.default.js +10 -0
- package/jest.config.integration.fixtures.js +22 -0
- package/jest.config.integration.js +21 -18
- package/jest.config.isolated.js +10 -0
- package/jest.projects.js +288 -0
- package/lib/api/datasources-core.api.js +3 -3
- package/lib/api/dev-mtls-request.js +110 -0
- package/lib/api/dev-server-https.js +145 -0
- package/lib/api/dev.api.js +133 -144
- package/lib/api/index.js +0 -1
- package/lib/api/pipeline.api.js +67 -20
- package/lib/api/service-users.api.js +111 -2
- package/lib/api/types/dev.types.js +4 -3
- package/lib/api/types/pipeline.types.js +8 -5
- package/lib/api/types/service-users.types.js +41 -0
- package/lib/api/types/validation-run.types.js +56 -0
- package/lib/api/validation-run.api.js +99 -0
- package/lib/api/validation-runner.js +99 -0
- package/lib/app/config.js +1 -1
- package/lib/app/deploy-status-display.js +2 -2
- package/lib/app/deploy.js +7 -6
- package/lib/app/display.js +2 -1
- package/lib/app/dockerfile.js +3 -2
- package/lib/app/down.js +2 -1
- package/lib/app/helpers.js +6 -5
- package/lib/app/index.js +27 -8
- package/lib/app/list.js +7 -6
- package/lib/app/push.js +4 -3
- package/lib/app/register.js +19 -8
- package/lib/app/rotate-secret.js +17 -13
- package/lib/app/run-container-start.js +184 -0
- package/lib/app/run-docker-fallback.js +108 -0
- package/lib/app/run-env-compose.js +30 -42
- package/lib/app/run-helpers.js +49 -126
- package/lib/app/run-infra-requirements.js +30 -0
- package/lib/app/run-resolve-image.js +21 -0
- package/lib/app/run.js +74 -21
- package/lib/app/show-display.js +1 -1
- package/lib/app/show.js +1 -1
- package/lib/build/index.js +13 -10
- package/lib/cli/index.js +2 -0
- package/lib/cli/setup-app.help.js +67 -0
- package/lib/cli/setup-app.js +59 -123
- package/lib/cli/setup-app.test-commands.js +179 -0
- package/lib/cli/setup-auth.js +36 -14
- package/lib/cli/setup-credential-deployment.js +22 -8
- package/lib/cli/setup-dev-path-commands.js +124 -0
- package/lib/cli/setup-dev.js +190 -103
- package/lib/cli/setup-environment.js +11 -20
- package/lib/cli/setup-external-system.js +62 -22
- package/lib/cli/setup-infra.js +139 -47
- package/lib/cli/setup-parameters.js +32 -0
- package/lib/cli/setup-secrets.js +147 -10
- package/lib/cli/setup-service-user.js +146 -20
- package/lib/cli/setup-utility.js +47 -19
- package/lib/commands/app-down.js +5 -7
- package/lib/commands/app-install.js +14 -7
- package/lib/commands/app-logs.js +13 -10
- package/lib/commands/app-shell.js +4 -1
- package/lib/commands/app-test.js +25 -19
- package/lib/commands/app.js +22 -10
- package/lib/commands/auth-config.js +10 -14
- package/lib/commands/auth-status.js +4 -3
- package/lib/commands/credential-env.js +4 -3
- package/lib/commands/credential-list.js +5 -4
- package/lib/commands/credential-push.js +4 -3
- package/lib/commands/datasource-unified-test-cli.js +495 -0
- package/lib/commands/datasource-unified-test-cli.options.js +149 -0
- package/lib/commands/datasource-validation-cli.js +129 -0
- package/lib/commands/datasource.js +123 -71
- package/lib/commands/deployment-list.js +6 -5
- package/lib/commands/dev-cli-handlers.js +122 -18
- package/lib/commands/dev-down.js +4 -3
- package/lib/commands/dev-init.js +231 -116
- package/lib/commands/dev-show-display.js +473 -0
- package/lib/commands/login-credentials.js +3 -2
- package/lib/commands/login-device.js +4 -3
- package/lib/commands/login.js +5 -4
- package/lib/commands/logout.js +8 -7
- package/lib/commands/parameters-validate.js +54 -0
- package/lib/commands/repair-datasource.js +314 -68
- package/lib/commands/repair-env-template.js +16 -10
- package/lib/commands/repair-rbac.js +25 -19
- package/lib/commands/repair.js +116 -32
- package/lib/commands/secrets-list.js +23 -12
- package/lib/commands/secrets-remove-all.js +220 -0
- package/lib/commands/secrets-remove.js +22 -13
- package/lib/commands/secrets-set.js +21 -12
- package/lib/commands/secrets-validate.js +20 -7
- package/lib/commands/secure.js +10 -9
- package/lib/commands/service-user.js +243 -13
- package/lib/commands/test-e2e-external.js +27 -1
- package/lib/commands/up-common.js +28 -2
- package/lib/commands/up-dataplane.js +31 -18
- package/lib/commands/up-miso.js +19 -29
- package/lib/commands/upload.js +138 -39
- package/lib/commands/wizard-core-helpers.js +1 -1
- package/lib/commands/wizard-dataplane.js +4 -3
- package/lib/commands/wizard-helpers.js +3 -3
- package/lib/commands/wizard.js +2 -2
- package/lib/core/admin-secrets.js +16 -5
- package/lib/core/audit-logger.js +12 -4
- package/lib/core/config-attach-extensions.js +46 -0
- package/lib/core/config-runtime-paths.js +29 -0
- package/lib/core/config.js +59 -58
- package/lib/core/diff.js +3 -2
- package/lib/core/ensure-encryption-key.js +2 -4
- package/lib/core/secrets-ensure-infra.js +77 -0
- package/lib/core/secrets-ensure.js +120 -64
- package/lib/core/secrets-env-write.js +35 -7
- package/lib/core/secrets-infra-placeholder-sync.js +61 -0
- package/lib/core/secrets.js +228 -42
- package/lib/core/templates-env.js +4 -3
- package/lib/core/templates.js +1 -1
- package/lib/datasource/abac-validator.js +148 -0
- package/lib/datasource/deploy.js +75 -53
- package/lib/datasource/field-reference-validator.js +77 -36
- package/lib/datasource/integration-context.js +63 -0
- package/lib/datasource/list.js +8 -7
- package/lib/datasource/log-viewer.js +252 -0
- package/lib/datasource/resolve-app.js +109 -0
- package/lib/datasource/test-e2e.js +95 -155
- package/lib/datasource/test-integration.js +121 -109
- package/lib/datasource/unified-validation-run-body.js +65 -0
- package/lib/datasource/unified-validation-run-post.js +23 -0
- package/lib/datasource/unified-validation-run-resolve.js +43 -0
- package/lib/datasource/unified-validation-run.js +92 -0
- package/lib/datasource/validate.js +162 -15
- package/lib/deployment/deployer.js +4 -3
- package/lib/deployment/environment.js +7 -6
- package/lib/deployment/push.js +17 -8
- package/lib/external-system/delete.js +4 -3
- package/lib/external-system/deploy.js +131 -53
- package/lib/external-system/download-helpers.js +1 -1
- package/lib/external-system/download.js +7 -6
- package/lib/external-system/generator.js +104 -14
- package/lib/external-system/integration-test-dispatch.js +26 -0
- package/lib/external-system/test-execution.js +5 -1
- package/lib/external-system/test-helpers.js +0 -4
- package/lib/external-system/test-system-level-helpers.js +110 -0
- package/lib/external-system/test-system-level.js +83 -44
- package/lib/external-system/test.js +59 -8
- package/lib/generator/builders.js +23 -11
- package/lib/generator/deploy-manifest-azure-kv.js +81 -0
- package/lib/generator/external-controller-manifest.js +3 -3
- package/lib/generator/external.js +23 -11
- package/lib/generator/helpers.js +71 -12
- package/lib/generator/index.js +8 -4
- package/lib/generator/split-readme.js +12 -7
- package/lib/generator/split-variables.js +2 -1
- package/lib/generator/split.js +46 -11
- package/lib/generator/wizard-readme.js +3 -3
- package/lib/generator/wizard.js +16 -13
- package/lib/infrastructure/compose.js +60 -6
- package/lib/infrastructure/helpers.js +238 -51
- package/lib/infrastructure/index.js +64 -37
- package/lib/infrastructure/services.js +21 -15
- package/lib/internal/fs-real-sync.js +104 -0
- package/lib/internal/node-fs.js +98 -0
- package/lib/parameters/database-secret-values.js +173 -0
- package/lib/parameters/infra-kv-discovery.js +121 -0
- package/lib/parameters/infra-parameter-catalog.js +458 -0
- package/lib/parameters/infra-parameter-validate.js +64 -0
- package/lib/schema/application-schema.json +37 -17
- package/lib/schema/datasource-test-run.schema.json +493 -0
- package/lib/schema/deployment-rules.yaml +102 -63
- package/lib/schema/external-datasource.schema.json +1201 -433
- package/lib/schema/external-system.schema.json +181 -5
- package/lib/schema/flag-map-validation-run.json +31 -0
- package/lib/schema/infra-parameter.schema.json +106 -0
- package/lib/schema/infra.parameter.yaml +421 -0
- package/lib/schema/type/credential-auth-templates.json +40 -0
- package/lib/schema/type/document-storage.json +213 -0
- package/lib/schema/type/message-service.json +123 -0
- package/lib/schema/type/vector-store.json +88 -0
- package/lib/utils/aifabrix-runtime-config-dir.js +132 -0
- package/lib/utils/api-error-handler.js +2 -2
- package/lib/utils/api.js +49 -14
- package/lib/utils/app-config-resolver.js +23 -1
- package/lib/utils/app-register-api.js +3 -2
- package/lib/utils/app-register-auth.js +1 -1
- package/lib/utils/app-register-config.js +4 -4
- package/lib/utils/app-register-display.js +3 -2
- package/lib/utils/app-register-validator.js +3 -2
- package/lib/utils/app-run-containers.js +26 -22
- package/lib/utils/app-scoped-config.js +31 -0
- package/lib/utils/app-service-env-from-builder.js +164 -0
- package/lib/utils/build-copy.js +1 -1
- package/lib/utils/build-helpers.js +20 -20
- package/lib/utils/build-resolve-image.js +165 -0
- package/lib/utils/cli-layout-chalk.js +8 -0
- package/lib/utils/cli-test-layout-chalk.js +267 -0
- package/lib/utils/cli-utils.js +88 -11
- package/lib/utils/compose-db-passwords.js +138 -0
- package/lib/utils/compose-generate-docker-compose.js +216 -0
- package/lib/utils/compose-generator.js +197 -291
- package/lib/utils/compose-miso-env.js +18 -0
- package/lib/utils/compose-traefik-ingress-base.js +158 -0
- package/lib/utils/config-paths.js +209 -6
- package/lib/utils/config-scoped-resources-preference.js +41 -0
- package/lib/utils/controller-deployment-outcome.js +68 -0
- package/lib/utils/credential-display.js +2 -2
- package/lib/utils/credential-secrets-env.js +16 -1
- package/lib/utils/dataplane-pipeline-warning.js +4 -3
- package/lib/utils/datasource-test-run-capability-scope.js +43 -0
- package/lib/utils/datasource-test-run-debug-display.js +137 -0
- package/lib/utils/datasource-test-run-debug-slice.js +93 -0
- package/lib/utils/datasource-test-run-display.js +442 -0
- package/lib/utils/datasource-test-run-exit.js +58 -0
- package/lib/utils/datasource-test-run-legacy-adapter.js +93 -0
- package/lib/utils/datasource-test-run-report-version.js +51 -0
- package/lib/utils/datasource-test-run-schema-sync.js +59 -0
- package/lib/utils/datasource-test-run-tty-log.js +81 -0
- package/lib/utils/datasource-validation-watch.js +266 -0
- package/lib/utils/declarative-url-ports.js +47 -0
- package/lib/utils/derive-env-key-from-client-id.js +41 -0
- package/lib/utils/dev-ca-install.js +185 -23
- package/lib/utils/dev-cert-helper.js +266 -17
- package/lib/utils/dev-hosts-helper.js +307 -0
- package/lib/utils/dev-init-cert-hints.js +37 -0
- package/lib/utils/dev-init-health-messages.js +52 -0
- package/lib/utils/dev-init-resolve.js +86 -0
- package/lib/utils/dev-init-ssh-merge.js +65 -0
- package/lib/utils/dev-ssh-config-helper.js +196 -0
- package/lib/utils/dev-user-groups.js +93 -0
- package/lib/utils/docker-build.js +42 -17
- package/lib/utils/docker-exec.js +28 -0
- package/lib/utils/docker-manifest-public-port.js +116 -0
- package/lib/utils/docker-not-running-hint.js +52 -0
- package/lib/utils/docker.js +98 -11
- package/lib/utils/ensure-dev-certs-for-remote-docker.js +192 -0
- package/lib/utils/env-config-loader.js +10 -91
- package/lib/utils/env-copy.js +19 -10
- package/lib/utils/env-map.js +42 -11
- package/lib/utils/env-template.js +2 -2
- package/lib/utils/environment-scoped-resources.js +144 -0
- package/lib/utils/error-formatter.js +125 -9
- package/lib/utils/error-formatters/http-status-errors.js +6 -5
- package/lib/utils/error-formatters/network-errors.js +2 -1
- package/lib/utils/error-formatters/permission-errors.js +2 -1
- package/lib/utils/error-formatters/validation-errors.js +2 -1
- package/lib/utils/external-env-template.js +180 -0
- package/lib/utils/external-readme.js +8 -1
- package/lib/utils/external-system-display.js +277 -136
- package/lib/utils/external-system-local-test-tty.js +389 -0
- package/lib/utils/external-system-readiness-core.js +377 -0
- package/lib/utils/external-system-readiness-deploy-display.js +270 -0
- package/lib/utils/external-system-readiness-display-internals.js +150 -0
- package/lib/utils/external-system-readiness-display.js +186 -0
- package/lib/utils/external-system-test-helpers.js +24 -6
- package/lib/utils/external-system-validators.js +32 -14
- package/lib/utils/health-check-url.js +119 -0
- package/lib/utils/health-check.js +59 -25
- package/lib/utils/help-builder.js +14 -13
- package/lib/utils/image-version.js +4 -8
- package/lib/utils/infra-containers.js +4 -7
- package/lib/utils/infra-env-defaults.js +162 -0
- package/lib/utils/infra-status-display.js +167 -0
- package/lib/utils/infra-status.js +16 -8
- package/lib/utils/local-secrets.js +29 -7
- package/lib/utils/paths.js +136 -48
- package/lib/utils/port-resolver.js +10 -23
- package/lib/utils/redis-env-scope.js +62 -0
- package/lib/utils/register-aifabrix-shell-env.js +204 -0
- package/lib/utils/remote-builder-validation.js +99 -0
- package/lib/utils/remote-dev-auth.js +117 -21
- package/lib/utils/remote-docker-env.js +67 -15
- package/lib/utils/remote-secrets-loader.js +13 -4
- package/lib/utils/resolve-docker-image-ref.js +124 -0
- package/lib/utils/schema-loader.js +22 -9
- package/lib/utils/secrets-bash-kv.js +25 -0
- package/lib/utils/secrets-generator.js +171 -51
- package/lib/utils/secrets-helpers.js +70 -59
- package/lib/utils/secrets-kv-scope.js +60 -0
- package/lib/utils/secrets-utils.js +35 -37
- package/lib/utils/secrets-validation.js +3 -1
- package/lib/utils/secrets-yaml-preserve.js +109 -0
- package/lib/utils/secure-file-permissions.js +91 -0
- package/lib/utils/ssh-key-helper.js +4 -2
- package/lib/utils/template-helpers.js +2 -2
- package/lib/utils/test-log-writer.js +3 -3
- package/lib/utils/token-manager.js +37 -5
- package/lib/utils/url-declarative-public-base.js +188 -0
- package/lib/utils/url-declarative-resolve-build.js +493 -0
- package/lib/utils/url-declarative-resolve-load-doc.js +51 -0
- package/lib/utils/url-declarative-resolve.js +220 -0
- package/lib/utils/url-declarative-token-parse.js +74 -0
- package/lib/utils/url-declarative-url-flags.js +50 -0
- package/lib/utils/url-declarative-vdir-inactive-env.js +99 -0
- package/lib/utils/url-public-path-prefix.js +34 -0
- package/lib/utils/urls-local-registry.js +220 -0
- package/lib/utils/validation-report-tty-kit.js +77 -0
- package/lib/utils/validation-run-poll.js +89 -0
- package/lib/utils/validation-run-post-retry.js +73 -0
- package/lib/utils/validation-run-request.js +98 -0
- package/lib/utils/variable-transformer.js +21 -4
- package/lib/utils/yaml-preserve.js +78 -1
- package/lib/validation/datasource-warnings.js +56 -0
- package/lib/validation/env-template-auth.js +50 -2
- package/lib/validation/external-manifest-validator.js +35 -7
- package/lib/validation/validate-display.js +37 -31
- package/lib/validation/validate.js +9 -10
- package/lib/validation/validator-unresolved-placeholders.js +98 -0
- package/lib/validation/validator.js +32 -78
- package/lib/validation/wizard-config-validator.js +2 -1
- package/package.json +11 -3
- package/scripts/check-datasource-test-run-schema-sync.js +34 -0
- package/scripts/diagnose-cli.js +150 -0
- package/scripts/install-local.js +304 -55
- package/templates/README.md +15 -2
- package/templates/applications/dataplane/application.yaml +52 -2
- package/templates/applications/dataplane/env.template +80 -18
- package/templates/applications/dataplane/rbac.yaml +8 -0
- package/templates/applications/keycloak/application.yaml +9 -1
- package/templates/applications/keycloak/env.template +15 -6
- package/templates/applications/miso-controller/application.yaml +10 -2
- package/templates/applications/miso-controller/env.template +55 -14
- package/templates/applications/miso-controller/rbac.yaml +5 -0
- package/templates/external-system/README.md.hbs +20 -7
- package/templates/external-system/deploy.js.hbs +5 -5
- package/templates/external-system/env.template.hbs +22 -0
- package/templates/external-system/external-datasource.yaml.hbs +197 -118
- package/templates/infra/compose.yaml.hbs +20 -4
- package/templates/python/docker-compose.hbs +16 -0
- package/templates/typescript/docker-compose.hbs +16 -0
- package/integration/hubspot/README.md +0 -102
- package/integration/hubspot/env.template +0 -4
- package/integration/hubspot/hubspot-datasource-company.json +0 -541
- package/integration/hubspot/hubspot-datasource-contact.json +0 -639
- package/integration/hubspot/hubspot-datasource-deal.json +0 -588
- package/integration/hubspot/hubspot-datasource-users.json +0 -116
- package/integration/hubspot/test-artifacts/wizard-invalid-missing-source.yaml +0 -2
- package/integration/hubspot/test-artifacts/wizard-valid-for-dimension-key-test.yaml +0 -5
- package/integration/hubspot/test-artifacts/wizard-valid-for-dimension-path-test.yaml +0 -5
- package/lib/api/external-test.api.js +0 -111
- package/lib/schema/env-config.yaml +0 -43
- /package/integration/{hubspot → hubspot-test}/companies.json +0 -0
- /package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-app-name.yaml +0 -0
- /package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-missing-app.yaml +0 -0
- /package/integration/{hubspot → hubspot-test}/test-dataplane-down-helpers.js +0 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared chalk helpers for external system readiness CLI blocks.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Internals for upload and deploy readiness display
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 2.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const chalk = require('chalk');
|
|
10
|
+
const { failureGlyph, successGlyph } = require('./cli-test-layout-chalk');
|
|
11
|
+
const logger = require('./logger');
|
|
12
|
+
const { extractIdentitySummary, resolveCredentialTestEndpointDisplay } = require('./external-system-readiness-core');
|
|
13
|
+
|
|
14
|
+
const SEP = chalk.gray('────────────────────────────────');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {string} title
|
|
18
|
+
*/
|
|
19
|
+
function logSectionTitle(title) {
|
|
20
|
+
logger.log('');
|
|
21
|
+
logger.log(chalk.bold(title));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function logSeparator() {
|
|
25
|
+
logger.log('');
|
|
26
|
+
logger.log(SEP);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @param {'ready'|'partial'|'failed'} tier
|
|
31
|
+
* @returns {string}
|
|
32
|
+
*/
|
|
33
|
+
function tierGlyph(tier) {
|
|
34
|
+
if (tier === 'ready') return successGlyph();
|
|
35
|
+
if (tier === 'failed') return failureGlyph();
|
|
36
|
+
return chalk.yellow('⚠');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param {'READY'|'PARTIAL'|'FAILED'} v
|
|
41
|
+
* @returns {string}
|
|
42
|
+
*/
|
|
43
|
+
function verdictLine(v) {
|
|
44
|
+
const label = chalk.bold('System Readiness: ');
|
|
45
|
+
if (v === 'READY') return label + chalk.green('READY');
|
|
46
|
+
if (v === 'FAILED') return label + chalk.red('FAILED');
|
|
47
|
+
return label + chalk.yellow('PARTIAL');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @param {Array<{ key: string, tier: string }>} rows
|
|
52
|
+
* @param {{ ready: number, partial: number, failed: number }} counts
|
|
53
|
+
*/
|
|
54
|
+
function logDatasourceTable(rows, counts) {
|
|
55
|
+
logSectionTitle('Datasources:');
|
|
56
|
+
for (const r of rows) {
|
|
57
|
+
const statusLabel = r.tier === 'ready' ? 'Ready' : r.tier === 'failed' ? 'Failed' : 'Partial';
|
|
58
|
+
logger.log(
|
|
59
|
+
`${tierGlyph(r.tier)} ${r.key.padEnd(14, ' ')} ${chalk.gray('(' + statusLabel + ')')}`
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
logger.log('');
|
|
63
|
+
logger.log(
|
|
64
|
+
chalk.gray('Summary:') +
|
|
65
|
+
` ${chalk.green('Ready: ' + counts.ready)} · ${chalk.yellow('Partial: ' + counts.partial)} · ${chalk.red('Failed: ' + counts.failed)}`
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @param {Object} system - manifest.system
|
|
71
|
+
*/
|
|
72
|
+
function logIdentityBlock(system) {
|
|
73
|
+
const { mode, attribution, tokenBroker } = extractIdentitySummary(system || {});
|
|
74
|
+
logSectionTitle('Identity:');
|
|
75
|
+
logger.log(`${chalk.gray('Mode:')} ${mode}`);
|
|
76
|
+
const attrColor = attribution === 'enabled' ? chalk.white : chalk.yellow;
|
|
77
|
+
logger.log(`${chalk.gray('Attribution:')} ${attrColor(attribution)}`);
|
|
78
|
+
logger.log(`${chalk.gray('Token broker:')} ${tokenBroker === 'configured' ? chalk.white(tokenBroker) : chalk.gray(tokenBroker)}`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @param {Object} system - manifest.system
|
|
83
|
+
* @param {boolean} probed
|
|
84
|
+
* @param {boolean} [willProbe] - True when caller will run --probe immediately after this block
|
|
85
|
+
*/
|
|
86
|
+
function logCredentialIntentBlock(system, probed, willProbe = false) {
|
|
87
|
+
const url = resolveCredentialTestEndpointDisplay(system || {});
|
|
88
|
+
logSectionTitle('Credential (intent):');
|
|
89
|
+
if (url) {
|
|
90
|
+
logger.log(chalk.gray('Test endpoint:'));
|
|
91
|
+
logger.log(chalk.cyan(`GET ${url}`));
|
|
92
|
+
} else {
|
|
93
|
+
logger.log(chalk.gray('Test endpoint: (not configured — defaults may apply on server)'));
|
|
94
|
+
}
|
|
95
|
+
if (!probed) {
|
|
96
|
+
if (willProbe) {
|
|
97
|
+
logger.log(chalk.gray('⏳ Connectivity will be tested next (--probe)'));
|
|
98
|
+
} else {
|
|
99
|
+
logger.log(chalk.yellow('⚠ Connectivity not tested (use --probe)'));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @param {string[]} actions
|
|
106
|
+
* @param {string} [extraLine]
|
|
107
|
+
*/
|
|
108
|
+
function logNextActions(actions, extraLine) {
|
|
109
|
+
logSectionTitle('Next actions:');
|
|
110
|
+
for (const a of actions) {
|
|
111
|
+
if (a.startsWith('Run:')) {
|
|
112
|
+
logger.log(chalk.cyan('- ') + chalk.white(a));
|
|
113
|
+
} else {
|
|
114
|
+
logger.log(chalk.cyan('- ') + a);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (extraLine) {
|
|
118
|
+
logger.log(chalk.cyan('- ') + chalk.white(extraLine));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @param {Object} sys - ExternalSystemResponse
|
|
124
|
+
*/
|
|
125
|
+
function logDocsBlock(sys) {
|
|
126
|
+
if (!sys) return;
|
|
127
|
+
const urls = [];
|
|
128
|
+
if (sys.openApiDocsPageUrl) urls.push({ label: 'OpenAPI Docs Page', url: sys.openApiDocsPageUrl });
|
|
129
|
+
if (sys.apiDocumentUrl) urls.push({ label: 'API Docs', url: sys.apiDocumentUrl });
|
|
130
|
+
if (sys.mcpServerUrl) urls.push({ label: 'MCP Server', url: sys.mcpServerUrl });
|
|
131
|
+
if (urls.length === 0) return;
|
|
132
|
+
logSeparator();
|
|
133
|
+
logSectionTitle('Docs:');
|
|
134
|
+
for (const { label, url } of urls) {
|
|
135
|
+
logger.log(`${chalk.gray(label + ':')} ${chalk.cyan(url)}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
module.exports = {
|
|
140
|
+
SEP,
|
|
141
|
+
logSeparator,
|
|
142
|
+
logSectionTitle,
|
|
143
|
+
tierGlyph,
|
|
144
|
+
verdictLine,
|
|
145
|
+
logDatasourceTable,
|
|
146
|
+
logIdentityBlock,
|
|
147
|
+
logCredentialIntentBlock,
|
|
148
|
+
logNextActions,
|
|
149
|
+
logDocsBlock
|
|
150
|
+
};
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
const { formatBlockingError, formatSuccessLine } = require('./cli-test-layout-chalk');
|
|
2
|
+
/**
|
|
3
|
+
* Chalk-based CLI output for external system upload readiness (+ upload-time probe).
|
|
4
|
+
* Deploy summary lives in external-system-readiness-deploy-display.js.
|
|
5
|
+
*
|
|
6
|
+
* @fileoverview Readiness display for upload and optional probe after upload
|
|
7
|
+
* @author AI Fabrix Team
|
|
8
|
+
* @version 2.0.0
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const chalk = require('chalk');
|
|
12
|
+
const logger = require('./logger');
|
|
13
|
+
const {
|
|
14
|
+
summarizeDatasourceTiersA,
|
|
15
|
+
summarizeProbeResults,
|
|
16
|
+
buildNextActionsTierA,
|
|
17
|
+
coerceProbeRunToResultRows
|
|
18
|
+
} = require('./external-system-readiness-core');
|
|
19
|
+
const {
|
|
20
|
+
logSeparator,
|
|
21
|
+
logSectionTitle,
|
|
22
|
+
logDatasourceTable,
|
|
23
|
+
logIdentityBlock,
|
|
24
|
+
logCredentialIntentBlock,
|
|
25
|
+
logNextActions,
|
|
26
|
+
logDocsBlock,
|
|
27
|
+
verdictLine,
|
|
28
|
+
SEP
|
|
29
|
+
} = require('./external-system-readiness-display-internals');
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @param {Object} publication - PublicationResult
|
|
33
|
+
*/
|
|
34
|
+
function logPublishResultBlock(publication) {
|
|
35
|
+
const genMcp = publication.generateMcpContract === true;
|
|
36
|
+
logSectionTitle('Publish Result:');
|
|
37
|
+
logger.log(formatSuccessLine('System registered (controller + dataplane)'));
|
|
38
|
+
if (publication.uploadId) {
|
|
39
|
+
logger.log(`${chalk.gray('Upload ID:')} ${chalk.cyan(String(publication.uploadId))}`);
|
|
40
|
+
}
|
|
41
|
+
const sys = publication.system || {};
|
|
42
|
+
if (sys.status) {
|
|
43
|
+
logger.log(`${chalk.gray('System status:')} ${sys.status}`);
|
|
44
|
+
}
|
|
45
|
+
logSeparator();
|
|
46
|
+
logSectionTitle('MCP Contract:');
|
|
47
|
+
logger.log(genMcp ? formatSuccessLine('Generated') : chalk.gray('○ Not requested (generateMcpContract false)'));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @param {string} systemKey
|
|
52
|
+
* @param {{ ready: number, partial: number, failed: number }} summary
|
|
53
|
+
* @param {boolean} willProbe
|
|
54
|
+
*/
|
|
55
|
+
function logUploadReadinessSummaryMinimal(systemKey, summary, willProbe) {
|
|
56
|
+
logger.log(chalk.green(`\nUpload complete: ${systemKey}`));
|
|
57
|
+
logger.log(
|
|
58
|
+
chalk.gray('Summary:') +
|
|
59
|
+
` ${chalk.green('Ready: ' + summary.ready)} · ${chalk.yellow('Partial: ' + summary.partial)} · ${chalk.red('Failed: ' + summary.failed)}`
|
|
60
|
+
);
|
|
61
|
+
if (!willProbe) logger.log(chalk.gray('Use --probe for runtime verification'));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @param {string} systemKey
|
|
66
|
+
* @param {Object} publication
|
|
67
|
+
* @param {Object} manifest
|
|
68
|
+
* @param {{ rows: Array<{ key: string, tier: string }>, ready: number, partial: number, failed: number }} summary
|
|
69
|
+
* @param {boolean} genMcp
|
|
70
|
+
* @param {boolean} willProbe
|
|
71
|
+
*/
|
|
72
|
+
function logUploadReadinessSummaryExpanded(systemKey, publication, manifest, summary, genMcp, willProbe) {
|
|
73
|
+
const systemCfg = manifest.system || {};
|
|
74
|
+
logSeparator();
|
|
75
|
+
logPublishResultBlock(publication);
|
|
76
|
+
logSeparator();
|
|
77
|
+
logDatasourceTable(summary.rows, summary);
|
|
78
|
+
logSeparator();
|
|
79
|
+
logIdentityBlock(systemCfg);
|
|
80
|
+
logSeparator();
|
|
81
|
+
logCredentialIntentBlock(systemCfg, false, !!willProbe);
|
|
82
|
+
logSeparator();
|
|
83
|
+
let hints = buildNextActionsTierA(systemKey, summary, genMcp);
|
|
84
|
+
if (willProbe) {
|
|
85
|
+
hints = hints.filter(h => !h.includes(`Run: aifabrix upload ${systemKey} --probe`));
|
|
86
|
+
}
|
|
87
|
+
logNextActions(hints);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @param {Object} ctx
|
|
92
|
+
* @param {string} ctx.systemKey
|
|
93
|
+
* @param {Object} ctx.publication - PublicationResult
|
|
94
|
+
* @param {Object} ctx.manifest
|
|
95
|
+
* @param {boolean} [ctx.minimal] - One-line summary + probe hint only
|
|
96
|
+
* @param {boolean} [ctx.willProbe] - True when caller will run --probe immediately after this summary
|
|
97
|
+
*/
|
|
98
|
+
function logUploadReadinessSummary(ctx) {
|
|
99
|
+
const { systemKey, publication, manifest, minimal, willProbe } = ctx;
|
|
100
|
+
const genMcp = publication.generateMcpContract === true;
|
|
101
|
+
const summary = summarizeDatasourceTiersA(publication.datasources || [], genMcp);
|
|
102
|
+
if (minimal) {
|
|
103
|
+
logUploadReadinessSummaryMinimal(systemKey, summary, willProbe);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
logUploadReadinessSummaryExpanded(systemKey, publication, manifest, summary, genMcp, willProbe);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @param {Object} validationBody - Unwrapped pipeline/validate response
|
|
111
|
+
*/
|
|
112
|
+
function logServerValidationWarnings(validationBody) {
|
|
113
|
+
const warnings = validationBody?.warnings;
|
|
114
|
+
if (!Array.isArray(warnings) || warnings.length === 0) return;
|
|
115
|
+
logSeparator();
|
|
116
|
+
logSectionTitle('Server validation:');
|
|
117
|
+
for (const w of warnings) {
|
|
118
|
+
logger.log(chalk.yellow(`⚠ Warning: ${typeof w === 'string' ? w : JSON.stringify(w)}`));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @param {Object} results - Probe result rows
|
|
124
|
+
* @param {Object} summary - summarizeProbeResults output
|
|
125
|
+
*/
|
|
126
|
+
function logProbeCredentialLine(results, summary) {
|
|
127
|
+
logSeparator();
|
|
128
|
+
logSectionTitle('Credential Test:');
|
|
129
|
+
const anyEndpointFail = results.some(row => row?.endpointTestResults?.success === false);
|
|
130
|
+
if (anyEndpointFail) {
|
|
131
|
+
logger.log(formatBlockingError('Failed (see Key Issues / endpoint test)'));
|
|
132
|
+
} else if (summary.failed > 0) {
|
|
133
|
+
logger.log(formatBlockingError('Some datasource checks failed'));
|
|
134
|
+
} else if (summary.partial > 0) {
|
|
135
|
+
logger.log(chalk.yellow('⚠ Completed with warnings'));
|
|
136
|
+
} else {
|
|
137
|
+
logger.log(formatSuccessLine('Passed'));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* @param {Object} probeRaw - Unwrapped POST /validation/run body
|
|
143
|
+
* @param {string} systemKey
|
|
144
|
+
*/
|
|
145
|
+
function logProbeRuntimeBlock(probeRaw, systemKey) {
|
|
146
|
+
const results = coerceProbeRunToResultRows(probeRaw);
|
|
147
|
+
const summary = summarizeProbeResults(results);
|
|
148
|
+
logSeparator();
|
|
149
|
+
logger.log(chalk.bold('Runtime Readiness:'));
|
|
150
|
+
if (results.length === 0) {
|
|
151
|
+
logger.log(chalk.yellow('⚠ No runtime datasource results were returned by the dataplane probe.'));
|
|
152
|
+
logger.log(chalk.gray(' Endpoint credential test may still pass even if datasource checks were not reported.'));
|
|
153
|
+
}
|
|
154
|
+
logDatasourceTable(summary.rows, summary);
|
|
155
|
+
if (summary.issues.length > 0) {
|
|
156
|
+
logSeparator();
|
|
157
|
+
logSectionTitle('Key Issues:');
|
|
158
|
+
for (const { key, lines } of summary.issues) {
|
|
159
|
+
logger.log(chalk.white(key));
|
|
160
|
+
for (const line of lines) {
|
|
161
|
+
logger.log(chalk.red(`- ${line}`));
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
logProbeCredentialLine(results, summary);
|
|
166
|
+
logSeparator();
|
|
167
|
+
logNextActions(
|
|
168
|
+
['Fix API credentials or permissions if endpoint tests failed'],
|
|
169
|
+
`Run: aifabrix datasource test-e2e <datasourceKey> --app ${systemKey}`
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
module.exports = {
|
|
174
|
+
logUploadReadinessSummary,
|
|
175
|
+
logServerValidationWarnings,
|
|
176
|
+
logProbeRuntimeBlock,
|
|
177
|
+
SEP,
|
|
178
|
+
logSeparator,
|
|
179
|
+
logSectionTitle,
|
|
180
|
+
logDatasourceTable,
|
|
181
|
+
logIdentityBlock,
|
|
182
|
+
logCredentialIntentBlock,
|
|
183
|
+
logNextActions,
|
|
184
|
+
logDocsBlock,
|
|
185
|
+
verdictLine
|
|
186
|
+
};
|
|
@@ -12,9 +12,32 @@
|
|
|
12
12
|
const fs = require('fs').promises;
|
|
13
13
|
const path = require('path');
|
|
14
14
|
const { testDatasourceViaPipeline } = require('../api/pipeline.api');
|
|
15
|
+
const { integrationResultFromEnvelope, firstIssueMessage } = require('./datasource-test-run-legacy-adapter');
|
|
15
16
|
|
|
16
17
|
/** Pipeline test endpoints accept client credentials; do not enforce Bearer-only */
|
|
17
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Parse successful pipeline test body (envelope or legacy).
|
|
21
|
+
* @param {Object} body
|
|
22
|
+
* @param {string} datasourceKey
|
|
23
|
+
* @returns {Object}
|
|
24
|
+
* @throws {Error} When body indicates failure
|
|
25
|
+
*/
|
|
26
|
+
function parsePipelineTestResponseBody(body, datasourceKey) {
|
|
27
|
+
if (body && typeof body === 'object' && typeof body.status === 'string' && body.datasourceKey) {
|
|
28
|
+
if (body.status === 'fail') {
|
|
29
|
+
const errMsg = firstIssueMessage(body) || 'Test failed';
|
|
30
|
+
throw new Error(`Test endpoint failed: ${errMsg}`);
|
|
31
|
+
}
|
|
32
|
+
return integrationResultFromEnvelope(body, datasourceKey);
|
|
33
|
+
}
|
|
34
|
+
if (body.success === false) {
|
|
35
|
+
const errMsg = body.error || body.formattedError || 'Test failed';
|
|
36
|
+
throw new Error(`Test endpoint failed: ${errMsg}`);
|
|
37
|
+
}
|
|
38
|
+
return body.data || body;
|
|
39
|
+
}
|
|
40
|
+
|
|
18
41
|
/**
|
|
19
42
|
* Retry API call with exponential backoff
|
|
20
43
|
* @async
|
|
@@ -73,13 +96,8 @@ async function callPipelineTestEndpoint({ systemKey, datasourceKey, payloadTempl
|
|
|
73
96
|
if (!response.success || !response.data) {
|
|
74
97
|
throw new Error(`Test endpoint failed: ${response.error || response.formattedError || 'Unknown error'}`);
|
|
75
98
|
}
|
|
76
|
-
// When 200 with success: false in body, pass through; caller interprets via data.success
|
|
77
|
-
if (response.data?.success === false) {
|
|
78
|
-
const errMsg = response.data?.error || response.data?.formattedError || 'Test failed';
|
|
79
|
-
throw new Error(`Test endpoint failed: ${errMsg}`);
|
|
80
|
-
}
|
|
81
99
|
|
|
82
|
-
return response.data
|
|
100
|
+
return parsePipelineTestResponseBody(response.data, datasourceKey);
|
|
83
101
|
}
|
|
84
102
|
|
|
85
103
|
/**
|
|
@@ -119,31 +119,45 @@ function checkPathExistsInPayload(fieldPath, payloadTemplate) {
|
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
/**
|
|
122
|
-
*
|
|
123
|
-
* @param {Object}
|
|
122
|
+
* Root dimensions (dimensionBinding): local bindings as dimKey → metadata path string for validateDimensions.
|
|
123
|
+
* @param {Object} datasource - Datasource config
|
|
124
|
+
* @returns {Object} Map suitable for validateDimensions
|
|
125
|
+
*/
|
|
126
|
+
function getDimensionsMapForValidation(datasource) {
|
|
127
|
+
const root = datasource?.dimensions;
|
|
128
|
+
if (!root || typeof root !== 'object' || Array.isArray(root)) return {};
|
|
129
|
+
const out = {};
|
|
130
|
+
for (const [dimKey, binding] of Object.entries(root)) {
|
|
131
|
+
if (binding && typeof binding === 'object' && typeof binding.field === 'string') {
|
|
132
|
+
out[dimKey] = `metadata.${binding.field}`;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return out;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Validates dimensions object structure and content (path strings).
|
|
140
|
+
* @param {Object} dimensions - dimKey → path (e.g. metadata.country)
|
|
124
141
|
* @param {Object} results - Results object to update
|
|
125
142
|
*/
|
|
126
143
|
function validateDimensions(dimensions, results) {
|
|
127
|
-
if (!dimensions) {
|
|
128
|
-
results.
|
|
129
|
-
results.valid = false;
|
|
144
|
+
if (!dimensions || typeof dimensions !== 'object' || Array.isArray(dimensions)) {
|
|
145
|
+
results.warnings.push('No dimensions configured (schema v2.4: use root dimensions; optional but recommended for ABAC)');
|
|
130
146
|
return;
|
|
131
147
|
}
|
|
132
148
|
|
|
133
|
-
if (
|
|
134
|
-
results.
|
|
135
|
-
results.valid = false;
|
|
149
|
+
if (Object.keys(dimensions).length === 0) {
|
|
150
|
+
results.warnings.push('Dimensions object is empty');
|
|
136
151
|
return;
|
|
137
152
|
}
|
|
138
153
|
|
|
139
|
-
// Validate dimension keys and values
|
|
140
154
|
for (const [dimensionKey, attributePath] of Object.entries(dimensions)) {
|
|
141
155
|
if (!/^[a-zA-Z0-9_]+$/.test(dimensionKey)) {
|
|
142
|
-
results.errors.push(`Invalid dimension key '${dimensionKey}': must
|
|
156
|
+
results.errors.push(`Invalid dimension key '${dimensionKey}': dimension key must contain only letters, numbers, and underscores`);
|
|
143
157
|
results.valid = false;
|
|
144
158
|
}
|
|
145
159
|
if (typeof attributePath !== 'string' || !/^[a-zA-Z0-9_.]+$/.test(attributePath)) {
|
|
146
|
-
results.errors.push(`Invalid attribute path '${attributePath}' for dimension '${dimensionKey}': must
|
|
160
|
+
results.errors.push(`Invalid attribute path '${attributePath}' for dimension '${dimensionKey}': attribute path must contain only letters, numbers, underscores, and dots`);
|
|
147
161
|
results.valid = false;
|
|
148
162
|
}
|
|
149
163
|
}
|
|
@@ -180,7 +194,7 @@ function validateAttributesStructure(attributes, results) {
|
|
|
180
194
|
*/
|
|
181
195
|
function validateSingleAttribute(attributeName, attributeConfig, payloadTemplate, results) {
|
|
182
196
|
if (!attributeConfig || typeof attributeConfig !== 'object') {
|
|
183
|
-
results.errors.push(`Attribute '${attributeName}' must be an object with expression
|
|
197
|
+
results.errors.push(`Attribute '${attributeName}' must be an object with expression`);
|
|
184
198
|
results.valid = false;
|
|
185
199
|
return;
|
|
186
200
|
}
|
|
@@ -224,8 +238,7 @@ function validateFieldMappings(datasource, testPayload) {
|
|
|
224
238
|
return results;
|
|
225
239
|
}
|
|
226
240
|
|
|
227
|
-
|
|
228
|
-
validateDimensions(datasource.fieldMappings.dimensions, results);
|
|
241
|
+
validateDimensions(getDimensionsMapForValidation(datasource), results);
|
|
229
242
|
|
|
230
243
|
// Validate attributes structure (required in new schema)
|
|
231
244
|
const attributes = validateAttributesStructure(datasource.fieldMappings.attributes, results);
|
|
@@ -322,6 +335,11 @@ function validateAgainstSchema(data, schema) {
|
|
|
322
335
|
validateSchema: false
|
|
323
336
|
});
|
|
324
337
|
addFormats(ajv);
|
|
338
|
+
// Some schemas (e.g. external-datasource.schema.json) reference these by $id (aifabrix://schema/type/*).
|
|
339
|
+
// Adding them up-front keeps validation offline-safe and avoids unresolved $ref failures.
|
|
340
|
+
ajv.addSchema(require('../schema/type/document-storage.json'));
|
|
341
|
+
ajv.addSchema(require('../schema/type/message-service.json'));
|
|
342
|
+
ajv.addSchema(require('../schema/type/vector-store.json'));
|
|
325
343
|
// Remove $schema for draft-2020-12 to avoid AJV issues
|
|
326
344
|
const schemaCopy = { ...schema };
|
|
327
345
|
if (schemaCopy.$schema && schemaCopy.$schema.includes('2020-12')) {
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Health check URL resolution helpers.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Compute health check URL using declarative public URL logic (Traefik/frontDoorRouting)
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const { computePublicUrlBaseString } = require('./url-declarative-public-base');
|
|
10
|
+
const { parseDeveloperIdNum } = require('./declarative-url-ports');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Join URL path segments with exactly one slash between them.
|
|
14
|
+
* @param {string} a
|
|
15
|
+
* @param {string} b
|
|
16
|
+
* @returns {string}
|
|
17
|
+
*/
|
|
18
|
+
function joinUrlPath(a, b) {
|
|
19
|
+
const left = String(a || '').replace(/\/+$/, '');
|
|
20
|
+
const right = String(b || '').replace(/^\/+/, '');
|
|
21
|
+
if (!left) return `/${right}`;
|
|
22
|
+
if (!right) return left || '/';
|
|
23
|
+
return `${left}/${right}`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Convert a frontDoorRouting.pattern (Traefik/Front Door wildcard route) into a concrete mount path.
|
|
28
|
+
* Example: "/auth/*" -> "/auth"
|
|
29
|
+
*
|
|
30
|
+
* @param {string} pattern
|
|
31
|
+
* @returns {string}
|
|
32
|
+
*/
|
|
33
|
+
function normalizeFrontDoorPatternForHealth(pattern) {
|
|
34
|
+
let p = String(pattern || '').trim();
|
|
35
|
+
if (!p) return '/';
|
|
36
|
+
if (!p.startsWith('/')) p = `/${p}`;
|
|
37
|
+
// Drop wildcard suffixes used for routing.
|
|
38
|
+
p = p.replace(/\/\*+$/, '');
|
|
39
|
+
p = p.replace(/\*+$/, '');
|
|
40
|
+
// Drop trailing path params like "/foo/{bar}" if present (health is mounted at the base).
|
|
41
|
+
p = p.replace(/\/\{[^}]+\}$/, '');
|
|
42
|
+
// Normalize slashes and trailing slash.
|
|
43
|
+
p = p.replace(/\/{2,}/g, '/');
|
|
44
|
+
p = p.replace(/\/+$/, '');
|
|
45
|
+
return p || '/';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @param {Object|null} appConfig
|
|
50
|
+
* @returns {boolean}
|
|
51
|
+
*/
|
|
52
|
+
function frontDoorEnabled(appConfig) {
|
|
53
|
+
return Boolean(appConfig && appConfig.frontDoorRouting && appConfig.frontDoorRouting.enabled === true);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @param {Object|null} appConfig
|
|
58
|
+
* @returns {string|null}
|
|
59
|
+
*/
|
|
60
|
+
function frontDoorPattern(appConfig) {
|
|
61
|
+
const p = appConfig && appConfig.frontDoorRouting ? appConfig.frontDoorRouting.pattern : null;
|
|
62
|
+
return (typeof p === 'string' && p.trim()) ? p.trim() : null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Compute the Traefik front-door health check URL when applicable.
|
|
67
|
+
*
|
|
68
|
+
* Returns null when Traefik/frontDoorRouting isn't active or cannot be resolved.
|
|
69
|
+
*
|
|
70
|
+
* @async
|
|
71
|
+
* @param {string} appName
|
|
72
|
+
* @param {number} healthCheckPort
|
|
73
|
+
* @param {Object|null} appConfig
|
|
74
|
+
* @returns {Promise<string|null>}
|
|
75
|
+
*/
|
|
76
|
+
async function computeTraefikHealthCheckUrl(appName, healthCheckPort, appConfig) {
|
|
77
|
+
if (!frontDoorEnabled(appConfig)) return null;
|
|
78
|
+
const pattern = frontDoorPattern(appConfig);
|
|
79
|
+
if (!pattern) return null;
|
|
80
|
+
|
|
81
|
+
const coreConfig = require('../core/config');
|
|
82
|
+
const userCfg = await coreConfig.getConfig();
|
|
83
|
+
if (!(userCfg && userCfg.traefik)) return null;
|
|
84
|
+
|
|
85
|
+
const infraTlsEnabled = Boolean(userCfg && userCfg.tlsEnabled);
|
|
86
|
+
const remoteServer = await coreConfig.getRemoteServer();
|
|
87
|
+
const developerIdRaw = await coreConfig.getDeveloperId();
|
|
88
|
+
const developerIdNum = parseDeveloperIdNum(developerIdRaw);
|
|
89
|
+
|
|
90
|
+
// Health checks originate from the CLI on the host, not from inside a container.
|
|
91
|
+
const profile = 'local';
|
|
92
|
+
const fd = appConfig.frontDoorRouting;
|
|
93
|
+
const listenPort = Number(appConfig?.port || 3000);
|
|
94
|
+
|
|
95
|
+
const publicBase = computePublicUrlBaseString({
|
|
96
|
+
traefik: true,
|
|
97
|
+
pathActive: true,
|
|
98
|
+
hostTemplate: fd.host,
|
|
99
|
+
tls: fd.tls,
|
|
100
|
+
developerIdRaw,
|
|
101
|
+
remoteServer,
|
|
102
|
+
profile,
|
|
103
|
+
listenPort,
|
|
104
|
+
developerIdNum,
|
|
105
|
+
infraTlsEnabled
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const healthCheckPath = appConfig?.healthCheck?.path || '/health';
|
|
109
|
+
const mountPath = normalizeFrontDoorPatternForHealth(pattern);
|
|
110
|
+
const baseWithFrontDoor = joinUrlPath(publicBase, mountPath);
|
|
111
|
+
return joinUrlPath(baseWithFrontDoor, healthCheckPath);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
module.exports = {
|
|
115
|
+
joinUrlPath,
|
|
116
|
+
normalizeFrontDoorPatternForHealth,
|
|
117
|
+
computeTraefikHealthCheckUrl
|
|
118
|
+
};
|
|
119
|
+
|