@aifabrix/builder 2.43.0 → 2.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursor/rules/anchor-docs.mdc +15 -0
- package/README.md +1 -1
- package/anchor-docs/README.md +10 -0
- package/anchor-docs/_TEMPLATE +24 -0
- package/bin/aifabrix.js +13 -4
- package/integration/hubspot-test/README.md +31 -0
- package/integration/hubspot-test/create-hubspot.js +5 -5
- package/integration/hubspot-test/hubspot-test-datasource-company.json +58 -462
- package/integration/hubspot-test/hubspot-test-datasource-contact.json +61 -555
- package/integration/hubspot-test/hubspot-test-datasource-deal.json +63 -506
- package/integration/hubspot-test/hubspot-test-datasource-users.json +42 -83
- package/integration/hubspot-test/hubspot-test-deploy.json +3 -3
- package/integration/hubspot-test/test-dataplane-down-tests.js +1 -7
- package/integration/hubspot-test/test-dataplane-down.js +3 -3
- package/integration/hubspot-test/test.js +35 -43
- package/integration/hubspot-test/wizard-hubspot-test-headless.yaml +23 -0
- package/integration/roundtrip-test-local/README.md +144 -0
- package/integration/roundtrip-test-local/application.yaml +13 -0
- package/integration/roundtrip-test-local/env.template +15 -0
- package/integration/roundtrip-test-local/roundtrip-test-local-datasource-roundtrip-test-company.yaml +14 -0
- package/integration/roundtrip-test-local/roundtrip-test-local-deploy.json +61 -0
- package/integration/roundtrip-test-local/roundtrip-test-local-system.yaml +25 -0
- package/integration/roundtrip-test-local2/README.md +144 -0
- package/integration/roundtrip-test-local2/application.yaml +13 -0
- package/integration/roundtrip-test-local2/env.template +15 -0
- package/integration/roundtrip-test-local2/roundtrip-test-local2-datasource-company.yaml +31 -0
- package/integration/roundtrip-test-local2/roundtrip-test-local2-deploy.json +86 -0
- package/integration/roundtrip-test-local2/roundtrip-test-local2-system.yaml +25 -0
- package/integration/test/wizard.yaml +8 -0
- package/jest.config.default.js +10 -0
- package/jest.config.integration.fixtures.js +22 -0
- package/jest.config.integration.js +21 -18
- package/jest.config.isolated.js +10 -0
- package/jest.projects.js +288 -0
- package/lib/api/datasources-core.api.js +3 -3
- package/lib/api/dev-mtls-request.js +110 -0
- package/lib/api/dev-server-https.js +145 -0
- package/lib/api/dev.api.js +133 -144
- package/lib/api/index.js +0 -1
- package/lib/api/pipeline.api.js +67 -20
- package/lib/api/types/dev.types.js +4 -3
- package/lib/api/types/pipeline.types.js +8 -5
- package/lib/api/types/validation-run.types.js +56 -0
- package/lib/api/validation-run.api.js +99 -0
- package/lib/api/validation-runner.js +99 -0
- package/lib/app/config.js +1 -1
- package/lib/app/deploy-status-display.js +2 -2
- package/lib/app/deploy.js +7 -6
- package/lib/app/display.js +2 -1
- package/lib/app/dockerfile.js +3 -2
- package/lib/app/down.js +2 -1
- package/lib/app/helpers.js +6 -5
- package/lib/app/index.js +27 -8
- package/lib/app/list.js +7 -6
- package/lib/app/push.js +4 -3
- package/lib/app/register.js +16 -7
- package/lib/app/rotate-secret.js +14 -13
- package/lib/app/run-container-start.js +184 -0
- package/lib/app/run-docker-fallback.js +108 -0
- package/lib/app/run-env-compose.js +30 -42
- package/lib/app/run-helpers.js +49 -126
- package/lib/app/run-infra-requirements.js +30 -0
- package/lib/app/run-resolve-image.js +21 -0
- package/lib/app/run.js +74 -21
- package/lib/app/show-display.js +1 -1
- package/lib/app/show.js +1 -1
- package/lib/build/index.js +13 -10
- package/lib/cli/index.js +2 -0
- package/lib/cli/setup-app.help.js +67 -0
- package/lib/cli/setup-app.js +57 -121
- package/lib/cli/setup-app.test-commands.js +179 -0
- package/lib/cli/setup-auth.js +19 -5
- package/lib/cli/setup-credential-deployment.js +22 -8
- package/lib/cli/setup-dev-path-commands.js +124 -0
- package/lib/cli/setup-dev.js +170 -113
- package/lib/cli/setup-environment.js +7 -1
- package/lib/cli/setup-external-system.js +62 -22
- package/lib/cli/setup-infra.js +126 -47
- package/lib/cli/setup-parameters.js +32 -0
- package/lib/cli/setup-secrets.js +106 -8
- package/lib/cli/setup-service-user.js +1 -1
- package/lib/cli/setup-utility.js +36 -20
- package/lib/commands/app-down.js +5 -7
- package/lib/commands/app-install.js +14 -7
- package/lib/commands/app-logs.js +13 -10
- package/lib/commands/app-shell.js +4 -1
- package/lib/commands/app-test.js +25 -19
- package/lib/commands/app.js +22 -10
- package/lib/commands/auth-config.js +6 -6
- package/lib/commands/auth-status.js +4 -3
- package/lib/commands/credential-env.js +4 -3
- package/lib/commands/credential-list.js +5 -4
- package/lib/commands/credential-push.js +4 -3
- package/lib/commands/datasource-unified-test-cli.js +495 -0
- package/lib/commands/datasource-unified-test-cli.options.js +149 -0
- package/lib/commands/datasource-validation-cli.js +129 -0
- package/lib/commands/datasource.js +105 -98
- package/lib/commands/deployment-list.js +6 -5
- package/lib/commands/dev-cli-handlers.js +122 -18
- package/lib/commands/dev-down.js +4 -3
- package/lib/commands/dev-init.js +231 -116
- package/lib/commands/dev-show-display.js +473 -0
- package/lib/commands/login-credentials.js +3 -2
- package/lib/commands/login-device.js +4 -3
- package/lib/commands/login.js +5 -4
- package/lib/commands/logout.js +8 -7
- package/lib/commands/parameters-validate.js +54 -0
- package/lib/commands/repair-datasource.js +314 -68
- package/lib/commands/repair-env-template.js +2 -2
- package/lib/commands/repair.js +21 -3
- package/lib/commands/secrets-list.js +23 -12
- package/lib/commands/secrets-remove-all.js +220 -0
- package/lib/commands/secrets-remove.js +21 -12
- package/lib/commands/secrets-set.js +21 -12
- package/lib/commands/secrets-validate.js +4 -4
- package/lib/commands/secure.js +10 -9
- package/lib/commands/service-user.js +26 -25
- package/lib/commands/test-e2e-external.js +27 -1
- package/lib/commands/up-common.js +3 -2
- package/lib/commands/up-dataplane.js +29 -16
- package/lib/commands/up-miso.js +19 -29
- package/lib/commands/upload.js +138 -39
- package/lib/commands/wizard-core-helpers.js +1 -1
- package/lib/commands/wizard-dataplane.js +4 -3
- package/lib/commands/wizard-helpers.js +3 -3
- package/lib/commands/wizard.js +2 -2
- package/lib/core/admin-secrets.js +14 -5
- package/lib/core/audit-logger.js +12 -4
- package/lib/core/config-attach-extensions.js +46 -0
- package/lib/core/config-runtime-paths.js +29 -0
- package/lib/core/config.js +55 -56
- package/lib/core/diff.js +3 -2
- package/lib/core/ensure-encryption-key.js +1 -1
- package/lib/core/secrets-ensure-infra.js +77 -0
- package/lib/core/secrets-ensure.js +120 -64
- package/lib/core/secrets-env-write.js +35 -7
- package/lib/core/secrets-infra-placeholder-sync.js +61 -0
- package/lib/core/secrets.js +200 -37
- package/lib/core/templates-env.js +4 -3
- package/lib/datasource/abac-validator.js +1 -10
- package/lib/datasource/deploy.js +75 -53
- package/lib/datasource/field-reference-validator.js +9 -6
- package/lib/datasource/integration-context.js +63 -0
- package/lib/datasource/list.js +8 -7
- package/lib/datasource/log-viewer.js +84 -53
- package/lib/datasource/resolve-app.js +4 -4
- package/lib/datasource/test-e2e.js +95 -146
- package/lib/datasource/test-integration.js +114 -122
- package/lib/datasource/unified-validation-run-body.js +65 -0
- package/lib/datasource/unified-validation-run-post.js +23 -0
- package/lib/datasource/unified-validation-run-resolve.js +43 -0
- package/lib/datasource/unified-validation-run.js +92 -0
- package/lib/datasource/validate.js +157 -13
- package/lib/deployment/deployer.js +4 -3
- package/lib/deployment/environment.js +7 -6
- package/lib/deployment/push.js +17 -8
- package/lib/external-system/delete.js +4 -3
- package/lib/external-system/deploy.js +131 -53
- package/lib/external-system/download-helpers.js +1 -1
- package/lib/external-system/download.js +7 -6
- package/lib/external-system/generator.js +92 -6
- package/lib/external-system/integration-test-dispatch.js +26 -0
- package/lib/external-system/test-execution.js +5 -1
- package/lib/external-system/test-helpers.js +0 -4
- package/lib/external-system/test-system-level-helpers.js +110 -0
- package/lib/external-system/test-system-level.js +83 -44
- package/lib/external-system/test.js +59 -8
- package/lib/generator/builders.js +23 -11
- package/lib/generator/deploy-manifest-azure-kv.js +81 -0
- package/lib/generator/external.js +16 -4
- package/lib/generator/helpers.js +58 -3
- package/lib/generator/index.js +4 -0
- package/lib/generator/split-readme.js +12 -7
- package/lib/generator/split-variables.js +2 -1
- package/lib/generator/split.js +1 -1
- package/lib/generator/wizard-readme.js +3 -3
- package/lib/generator/wizard.js +8 -8
- package/lib/infrastructure/compose.js +60 -6
- package/lib/infrastructure/helpers.js +201 -29
- package/lib/infrastructure/index.js +28 -17
- package/lib/infrastructure/services.js +21 -15
- package/lib/internal/fs-real-sync.js +104 -0
- package/lib/internal/node-fs.js +98 -0
- package/lib/parameters/database-secret-values.js +173 -0
- package/lib/parameters/infra-kv-discovery.js +121 -0
- package/lib/parameters/infra-parameter-catalog.js +458 -0
- package/lib/parameters/infra-parameter-validate.js +64 -0
- package/lib/schema/application-schema.json +37 -17
- package/lib/schema/datasource-test-run.schema.json +493 -0
- package/lib/schema/deployment-rules.yaml +102 -63
- package/lib/schema/external-datasource.schema.json +1200 -442
- package/lib/schema/external-system.schema.json +181 -5
- package/lib/schema/flag-map-validation-run.json +31 -0
- package/lib/schema/infra-parameter.schema.json +106 -0
- package/lib/schema/infra.parameter.yaml +421 -0
- package/lib/schema/type/credential-auth-templates.json +40 -0
- package/lib/schema/type/document-storage.json +213 -0
- package/lib/schema/type/message-service.json +123 -0
- package/lib/schema/type/vector-store.json +88 -0
- package/lib/utils/aifabrix-runtime-config-dir.js +132 -0
- package/lib/utils/api-error-handler.js +2 -2
- package/lib/utils/api.js +49 -14
- package/lib/utils/app-register-api.js +3 -2
- package/lib/utils/app-register-auth.js +1 -1
- package/lib/utils/app-register-config.js +4 -4
- package/lib/utils/app-register-display.js +3 -2
- package/lib/utils/app-register-validator.js +3 -2
- package/lib/utils/app-run-containers.js +26 -22
- package/lib/utils/app-scoped-config.js +31 -0
- package/lib/utils/app-service-env-from-builder.js +164 -0
- package/lib/utils/build-copy.js +1 -1
- package/lib/utils/build-helpers.js +20 -20
- package/lib/utils/build-resolve-image.js +165 -0
- package/lib/utils/cli-layout-chalk.js +8 -0
- package/lib/utils/cli-test-layout-chalk.js +267 -0
- package/lib/utils/cli-utils.js +88 -11
- package/lib/utils/compose-db-passwords.js +138 -0
- package/lib/utils/compose-generate-docker-compose.js +216 -0
- package/lib/utils/compose-generator.js +197 -291
- package/lib/utils/compose-miso-env.js +18 -0
- package/lib/utils/compose-traefik-ingress-base.js +158 -0
- package/lib/utils/config-paths.js +166 -7
- package/lib/utils/config-scoped-resources-preference.js +41 -0
- package/lib/utils/controller-deployment-outcome.js +68 -0
- package/lib/utils/credential-display.js +2 -2
- package/lib/utils/dataplane-pipeline-warning.js +4 -3
- package/lib/utils/datasource-test-run-capability-scope.js +43 -0
- package/lib/utils/datasource-test-run-debug-display.js +137 -0
- package/lib/utils/datasource-test-run-debug-slice.js +93 -0
- package/lib/utils/datasource-test-run-display.js +442 -0
- package/lib/utils/datasource-test-run-exit.js +58 -0
- package/lib/utils/datasource-test-run-legacy-adapter.js +93 -0
- package/lib/utils/datasource-test-run-report-version.js +51 -0
- package/lib/utils/datasource-test-run-schema-sync.js +59 -0
- package/lib/utils/datasource-test-run-tty-log.js +81 -0
- package/lib/utils/datasource-validation-watch.js +266 -0
- package/lib/utils/declarative-url-ports.js +47 -0
- package/lib/utils/derive-env-key-from-client-id.js +41 -0
- package/lib/utils/dev-ca-install.js +185 -23
- package/lib/utils/dev-cert-helper.js +266 -17
- package/lib/utils/dev-hosts-helper.js +307 -0
- package/lib/utils/dev-init-cert-hints.js +37 -0
- package/lib/utils/dev-init-health-messages.js +52 -0
- package/lib/utils/dev-init-resolve.js +86 -0
- package/lib/utils/dev-init-ssh-merge.js +65 -0
- package/lib/utils/dev-ssh-config-helper.js +196 -0
- package/lib/utils/dev-user-groups.js +93 -0
- package/lib/utils/docker-build.js +42 -17
- package/lib/utils/docker-exec.js +28 -0
- package/lib/utils/docker-manifest-public-port.js +116 -0
- package/lib/utils/docker-not-running-hint.js +52 -0
- package/lib/utils/docker.js +98 -11
- package/lib/utils/ensure-dev-certs-for-remote-docker.js +192 -0
- package/lib/utils/env-config-loader.js +10 -91
- package/lib/utils/env-copy.js +19 -10
- package/lib/utils/env-map.js +35 -8
- package/lib/utils/env-template.js +2 -2
- package/lib/utils/environment-scoped-resources.js +144 -0
- package/lib/utils/error-formatter.js +92 -13
- package/lib/utils/error-formatters/http-status-errors.js +6 -5
- package/lib/utils/error-formatters/network-errors.js +2 -1
- package/lib/utils/error-formatters/permission-errors.js +2 -1
- package/lib/utils/error-formatters/validation-errors.js +2 -1
- package/lib/utils/external-readme.js +8 -1
- package/lib/utils/external-system-display.js +234 -136
- package/lib/utils/external-system-local-test-tty.js +389 -0
- package/lib/utils/external-system-readiness-core.js +377 -0
- package/lib/utils/external-system-readiness-deploy-display.js +270 -0
- package/lib/utils/external-system-readiness-display-internals.js +150 -0
- package/lib/utils/external-system-readiness-display.js +186 -0
- package/lib/utils/external-system-test-helpers.js +24 -6
- package/lib/utils/external-system-validators.js +30 -12
- package/lib/utils/health-check-url.js +119 -0
- package/lib/utils/health-check.js +59 -25
- package/lib/utils/help-builder.js +11 -8
- package/lib/utils/image-version.js +4 -8
- package/lib/utils/infra-containers.js +4 -7
- package/lib/utils/infra-env-defaults.js +162 -0
- package/lib/utils/infra-status-display.js +167 -0
- package/lib/utils/infra-status.js +16 -8
- package/lib/utils/local-secrets.js +3 -4
- package/lib/utils/paths.js +134 -47
- package/lib/utils/port-resolver.js +10 -23
- package/lib/utils/redis-env-scope.js +62 -0
- package/lib/utils/register-aifabrix-shell-env.js +204 -0
- package/lib/utils/remote-builder-validation.js +99 -0
- package/lib/utils/remote-dev-auth.js +117 -21
- package/lib/utils/remote-docker-env.js +67 -15
- package/lib/utils/remote-secrets-loader.js +13 -4
- package/lib/utils/resolve-docker-image-ref.js +124 -0
- package/lib/utils/schema-loader.js +22 -9
- package/lib/utils/secrets-bash-kv.js +25 -0
- package/lib/utils/secrets-generator.js +169 -49
- package/lib/utils/secrets-helpers.js +70 -59
- package/lib/utils/secrets-kv-scope.js +60 -0
- package/lib/utils/secrets-utils.js +32 -38
- package/lib/utils/secrets-validation.js +3 -1
- package/lib/utils/secrets-yaml-preserve.js +109 -0
- package/lib/utils/ssh-key-helper.js +4 -2
- package/lib/utils/template-helpers.js +2 -2
- package/lib/utils/test-log-writer.js +3 -3
- package/lib/utils/token-manager.js +1 -2
- package/lib/utils/url-declarative-public-base.js +188 -0
- package/lib/utils/url-declarative-resolve-build.js +493 -0
- package/lib/utils/url-declarative-resolve-load-doc.js +51 -0
- package/lib/utils/url-declarative-resolve.js +220 -0
- package/lib/utils/url-declarative-token-parse.js +74 -0
- package/lib/utils/url-declarative-url-flags.js +50 -0
- package/lib/utils/url-declarative-vdir-inactive-env.js +99 -0
- package/lib/utils/url-public-path-prefix.js +34 -0
- package/lib/utils/urls-local-registry.js +220 -0
- package/lib/utils/validation-report-tty-kit.js +77 -0
- package/lib/utils/validation-run-poll.js +89 -0
- package/lib/utils/validation-run-post-retry.js +73 -0
- package/lib/utils/validation-run-request.js +98 -0
- package/lib/utils/variable-transformer.js +21 -4
- package/lib/utils/yaml-preserve.js +33 -14
- package/lib/validation/datasource-warnings.js +56 -0
- package/lib/validation/env-template-auth.js +1 -1
- package/lib/validation/external-manifest-validator.js +27 -7
- package/lib/validation/validate-display.js +37 -31
- package/lib/validation/validate.js +4 -13
- package/lib/validation/validator-unresolved-placeholders.js +98 -0
- package/lib/validation/validator.js +22 -65
- package/lib/validation/wizard-config-validator.js +2 -1
- package/package.json +7 -3
- package/scripts/check-datasource-test-run-schema-sync.js +34 -0
- package/scripts/diagnose-cli.js +150 -0
- package/scripts/install-local.js +304 -55
- package/templates/README.md +15 -2
- package/templates/applications/dataplane/application.yaml +52 -2
- package/templates/applications/dataplane/env.template +75 -17
- package/templates/applications/dataplane/rbac.yaml +8 -0
- package/templates/applications/keycloak/application.yaml +9 -1
- package/templates/applications/keycloak/env.template +15 -6
- package/templates/applications/miso-controller/application.yaml +10 -2
- package/templates/applications/miso-controller/env.template +42 -12
- package/templates/applications/miso-controller/rbac.yaml +5 -0
- package/templates/external-system/README.md.hbs +20 -7
- package/templates/external-system/deploy.js.hbs +5 -5
- package/templates/external-system/external-datasource.yaml.hbs +197 -118
- package/templates/infra/compose.yaml.hbs +20 -4
- package/templates/python/docker-compose.hbs +16 -0
- package/templates/typescript/docker-compose.hbs +16 -0
- package/lib/api/external-test.api.js +0 -111
- package/lib/schema/env-config.yaml +0 -60
|
@@ -11,16 +11,19 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* Set of attribute names plus dimension keys valid for field references.
|
|
15
|
-
* Used for primaryKey (schema allows
|
|
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).
|
|
16
16
|
*
|
|
17
17
|
* @param {Object} parsed - Parsed datasource object
|
|
18
18
|
* @returns {{ attributes: string[], attributesAndDimensions: Set<string> }}
|
|
19
19
|
*/
|
|
20
20
|
function getNormalizedSets(parsed) {
|
|
21
21
|
const attributes = Object.keys(parsed?.fieldMappings?.attributes ?? {});
|
|
22
|
-
const
|
|
23
|
-
|
|
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]);
|
|
24
27
|
return { attributes, attributesAndDimensions };
|
|
25
28
|
}
|
|
26
29
|
|
|
@@ -31,7 +34,7 @@ function checkPrimaryKey(parsed, attributesAndDimensions, errors) {
|
|
|
31
34
|
primaryKey.forEach((field, i) => {
|
|
32
35
|
if (typeof field === 'string' && field !== '' && !attributesAndDimensions.has(field)) {
|
|
33
36
|
errors.push(
|
|
34
|
-
`primaryKey[${i}]: field '${field}' does not exist in fieldMappings.attributes or
|
|
37
|
+
`primaryKey[${i}]: field '${field}' does not exist in fieldMappings.attributes or root dimensions. Each primaryKey value must reference an attribute or dimension key.`
|
|
35
38
|
);
|
|
36
39
|
}
|
|
37
40
|
});
|
|
@@ -98,7 +101,7 @@ function checkIndexingAndValidation(parsed, normalizedAttributes, errors) {
|
|
|
98
101
|
/**
|
|
99
102
|
* Validates that all field references in indexing, validation, quality,
|
|
100
103
|
* primaryKey, and exposed.profiles exist in fieldMappings.attributes (or
|
|
101
|
-
*
|
|
104
|
+
* root dimension keys for primaryKey per schema). When fieldMappings.attributes is
|
|
102
105
|
* missing or empty, returns no errors (skip check, matching dataplane behavior).
|
|
103
106
|
*
|
|
104
107
|
* @function validateFieldReferences
|
|
@@ -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) {
|
|
@@ -12,6 +12,7 @@ const chalk = require('chalk');
|
|
|
12
12
|
const logger = require('../utils/logger');
|
|
13
13
|
const { resolveAppKeyForDatasource } = require('./resolve-app');
|
|
14
14
|
const { getIntegrationPath } = require('../utils/paths');
|
|
15
|
+
const { sectionTitle, headerKeyValue, formatBlockingError, successGlyph, failureGlyph } = require('../utils/cli-test-layout-chalk');
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Get the path to the latest log file in a directory matching a glob-like pattern
|
|
@@ -55,62 +56,88 @@ function truncate(s, maxLen = 60) {
|
|
|
55
56
|
* @param {Object} data - Parsed log JSON (request, response, error)
|
|
56
57
|
* @param {string} [fileName] - Log file name for header
|
|
57
58
|
*/
|
|
58
|
-
function
|
|
59
|
-
logger.log(chalk.blue('\n——— E2E Log') + (fileName ? chalk.gray(` ${fileName}`) : ''));
|
|
59
|
+
function logE2ERequestSection(data) {
|
|
60
60
|
const req = data.request || {};
|
|
61
|
-
logger.log(
|
|
62
|
-
logger.log(
|
|
61
|
+
logger.log('');
|
|
62
|
+
logger.log(sectionTitle('Request:'));
|
|
63
|
+
logger.log(headerKeyValue('sourceIdOrKey:', String(req.sourceIdOrKey ?? '—')));
|
|
63
64
|
if (req.includeDebug !== undefined) logger.log(chalk.gray(` includeDebug: ${req.includeDebug}`));
|
|
64
65
|
if (req.cleanup !== undefined) logger.log(chalk.gray(` cleanup: ${req.cleanup}`));
|
|
65
|
-
if (req.primaryKeyValue !== undefined)
|
|
66
|
+
if (req.primaryKeyValue !== undefined) {
|
|
67
|
+
logger.log(chalk.gray(` primaryKeyValue: ${truncate(JSON.stringify(req.primaryKeyValue))}`));
|
|
68
|
+
}
|
|
69
|
+
return req;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function logE2EStepsSection(steps) {
|
|
73
|
+
if (!Array.isArray(steps) || steps.length === 0) return;
|
|
74
|
+
logger.log(sectionTitle('Steps:'));
|
|
75
|
+
for (const step of steps) {
|
|
76
|
+
const name = step.name || step.step || 'unknown';
|
|
77
|
+
const ok = step.success !== false && !step.error;
|
|
78
|
+
logger.log(` ${ok ? successGlyph() : failureGlyph()} ${chalk.white(name)}`);
|
|
79
|
+
if (step.error) logger.log(chalk.red(` ${step.error}`));
|
|
80
|
+
if (step.message && ok) logger.log(chalk.gray(` ${step.message}`));
|
|
81
|
+
if ((name === 'sync' || step.step === 'sync') && step.evidence && step.evidence.jobs) {
|
|
82
|
+
for (const job of step.evidence.jobs) {
|
|
83
|
+
const audit = job.audit || {};
|
|
84
|
+
const parts = [];
|
|
85
|
+
if (job.recordsProcessed !== undefined && job.recordsProcessed !== null) parts.push(`${job.recordsProcessed} processed`);
|
|
86
|
+
if (job.totalRecords !== undefined && job.totalRecords !== null) parts.push(`total: ${job.totalRecords}`);
|
|
87
|
+
if (
|
|
88
|
+
(audit.inserted !== undefined && audit.inserted !== null) ||
|
|
89
|
+
(audit.updated !== undefined && audit.updated !== null) ||
|
|
90
|
+
(audit.deleted !== undefined && audit.deleted !== null)
|
|
91
|
+
) {
|
|
92
|
+
parts.push(`(inserted: ${audit.inserted ?? 0}, updated: ${audit.updated ?? 0}, deleted: ${audit.deleted ?? 0})`);
|
|
93
|
+
}
|
|
94
|
+
if (parts.length) logger.log(chalk.gray(` Job: ${parts.join(' ')}`));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function logE2EAuditTraceSection(req, res) {
|
|
101
|
+
if (!res.auditLog || !Array.isArray(res.auditLog) || res.auditLog.length === 0) return;
|
|
102
|
+
logger.log('');
|
|
103
|
+
logger.log(sectionTitle('CIP execution trace(s):'));
|
|
104
|
+
logger.log(chalk.gray(`${res.auditLog.length}`));
|
|
105
|
+
const baseUrl = (req.dataplaneUrl || '').toString().replace(/\/$/, '');
|
|
106
|
+
const sourceIdOrKey = req.sourceIdOrKey || '';
|
|
107
|
+
res.auditLog.slice(0, 3).forEach((trace, i) => {
|
|
108
|
+
const id = trace.executionId || trace.id || trace.traceId;
|
|
109
|
+
if (!id) return;
|
|
110
|
+
const idStr = String(id);
|
|
111
|
+
logger.log(chalk.gray(` ${i + 1}. executionId: ${idStr}`));
|
|
112
|
+
if (baseUrl && sourceIdOrKey) {
|
|
113
|
+
const executionUrl = `${baseUrl}/api/v1/external/${sourceIdOrKey}/executions/${idStr}`;
|
|
114
|
+
logger.log(chalk.gray(` Link: ${executionUrl}`));
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function logE2EResponseSection(req, data) {
|
|
66
120
|
if (data.error) {
|
|
67
|
-
logger.log(
|
|
121
|
+
logger.log(formatBlockingError(`Error: ${data.error}`));
|
|
68
122
|
return;
|
|
69
123
|
}
|
|
70
124
|
const res = data.response || {};
|
|
71
|
-
logger.log(
|
|
125
|
+
logger.log('');
|
|
126
|
+
logger.log(sectionTitle('Response:'));
|
|
72
127
|
logger.log(chalk.gray(` success: ${res.success}`));
|
|
73
128
|
if (res.status) logger.log(chalk.gray(` status: ${res.status}`));
|
|
74
129
|
if (res.error) logger.log(chalk.red(` error: ${res.error}`));
|
|
75
130
|
const steps = res.steps || res.completedActions || [];
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const audit = job.audit || {};
|
|
87
|
-
const parts = [];
|
|
88
|
-
if (job.recordsProcessed !== undefined && job.recordsProcessed !== null) parts.push(`${job.recordsProcessed} processed`);
|
|
89
|
-
if (job.totalRecords !== undefined && job.totalRecords !== null) parts.push(`total: ${job.totalRecords}`);
|
|
90
|
-
if (audit.inserted !== undefined && audit.inserted !== null || audit.updated !== undefined && audit.updated !== null || audit.deleted !== undefined && audit.deleted !== null) {
|
|
91
|
-
parts.push(`(inserted: ${audit.inserted ?? 0}, updated: ${audit.updated ?? 0}, deleted: ${audit.deleted ?? 0})`);
|
|
92
|
-
}
|
|
93
|
-
if (parts.length) logger.log(chalk.gray(` Job: ${parts.join(' ')}`));
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
if (res.auditLog && Array.isArray(res.auditLog) && res.auditLog.length > 0) {
|
|
99
|
-
logger.log(chalk.cyan('CIP execution trace(s): ') + chalk.gray(`${res.auditLog.length}`));
|
|
100
|
-
const baseUrl = (req.dataplaneUrl || '').toString().replace(/\/$/, '');
|
|
101
|
-
const sourceIdOrKey = req.sourceIdOrKey || '';
|
|
102
|
-
res.auditLog.slice(0, 3).forEach((trace, i) => {
|
|
103
|
-
const id = trace.executionId || trace.id || trace.traceId;
|
|
104
|
-
if (id) {
|
|
105
|
-
const idStr = String(id);
|
|
106
|
-
logger.log(chalk.gray(` ${i + 1}. executionId: ${idStr}`));
|
|
107
|
-
if (baseUrl && sourceIdOrKey) {
|
|
108
|
-
const executionUrl = `${baseUrl}/api/v1/external/${sourceIdOrKey}/executions/${idStr}`;
|
|
109
|
-
logger.log(chalk.gray(` Link: ${executionUrl}`));
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
}
|
|
131
|
+
logE2EStepsSection(steps);
|
|
132
|
+
logE2EAuditTraceSection(req, res);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function formatE2ELog(data, fileName) {
|
|
136
|
+
logger.log('');
|
|
137
|
+
logger.log(sectionTitle('E2E log'));
|
|
138
|
+
if (fileName) logger.log(chalk.gray(fileName));
|
|
139
|
+
const req = logE2ERequestSection(data);
|
|
140
|
+
logE2EResponseSection(req, data);
|
|
114
141
|
}
|
|
115
142
|
|
|
116
143
|
/**
|
|
@@ -119,38 +146,42 @@ function formatE2ELog(data, fileName) {
|
|
|
119
146
|
* @param {string} [fileName] - Log file name for header
|
|
120
147
|
*/
|
|
121
148
|
function formatIntegrationLog(data, fileName) {
|
|
122
|
-
logger.log(
|
|
149
|
+
logger.log('');
|
|
150
|
+
logger.log(sectionTitle('Integration log'));
|
|
151
|
+
if (fileName) logger.log(chalk.gray(fileName));
|
|
123
152
|
const req = data.request || {};
|
|
124
|
-
logger.log(
|
|
153
|
+
logger.log('');
|
|
154
|
+
logger.log(sectionTitle('Request:'));
|
|
125
155
|
logger.log(chalk.gray(` systemKey: ${req.systemKey ?? '—'}, datasourceKey: ${req.datasourceKey ?? '—'}`));
|
|
126
156
|
if (req.includeDebug !== undefined) logger.log(chalk.gray(` includeDebug: ${req.includeDebug}`));
|
|
127
157
|
if (data.error) {
|
|
128
|
-
logger.log(
|
|
158
|
+
logger.log(formatBlockingError(`Error: ${data.error}`));
|
|
129
159
|
return;
|
|
130
160
|
}
|
|
131
161
|
const res = data.response || {};
|
|
132
|
-
logger.log(
|
|
162
|
+
logger.log('');
|
|
163
|
+
logger.log(sectionTitle('Response:'));
|
|
133
164
|
logger.log(chalk.gray(` success: ${res.success}`));
|
|
134
165
|
if (res.error) logger.log(chalk.red(` error: ${res.error}`));
|
|
135
166
|
const vr = res.validationResults || {};
|
|
136
|
-
logger.log(
|
|
167
|
+
logger.log(sectionTitle('Validation:'));
|
|
137
168
|
logger.log(chalk.gray(` isValid: ${vr.isValid}`));
|
|
138
169
|
if (vr.errors && vr.errors.length) vr.errors.forEach(e => logger.log(chalk.red(` - ${e}`)));
|
|
139
170
|
const fmr = res.fieldMappingResults || {};
|
|
140
171
|
if (Object.keys(fmr).length) {
|
|
141
|
-
logger.log(
|
|
172
|
+
logger.log(sectionTitle('Field mapping:'));
|
|
142
173
|
logger.log(chalk.gray(` mappingCount: ${fmr.mappingCount ?? '—'}`));
|
|
143
174
|
if (fmr.dimensions) logger.log(chalk.gray(` dimensions: ${Object.keys(fmr.dimensions).join(', ')}`));
|
|
144
175
|
}
|
|
145
176
|
const etr = res.endpointTestResults || {};
|
|
146
177
|
if (Object.keys(etr).length) {
|
|
147
|
-
logger.log(
|
|
178
|
+
logger.log(sectionTitle('Endpoint:'));
|
|
148
179
|
logger.log(chalk.gray(` endpointConfigured: ${etr.endpointConfigured}`));
|
|
149
180
|
}
|
|
150
181
|
if (res.normalizedOutput || res.normalizedMetadata) {
|
|
151
182
|
const out = res.normalizedOutput || res.normalizedMetadata;
|
|
152
183
|
const keys = typeof out === 'object' && out !== null ? Object.keys(out) : [];
|
|
153
|
-
logger.log(
|
|
184
|
+
logger.log(sectionTitle('Normalized output:') + ' ' + chalk.gray(keys.length ? `${keys.length} fields` : '—'));
|
|
154
185
|
}
|
|
155
186
|
}
|
|
156
187
|
|
|
@@ -17,7 +17,7 @@ const { loadConfigFile } = require('../utils/config-format');
|
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* For one app, check if any of its datasource files has the given key
|
|
20
|
-
* @param {string} appKey - Integration
|
|
20
|
+
* @param {string} appKey - Integration folder name (system key context)
|
|
21
21
|
* @param {string} datasourceKey - Datasource key to match
|
|
22
22
|
* @returns {boolean} True if this app has a datasource with that key
|
|
23
23
|
*/
|
|
@@ -52,7 +52,7 @@ function appHasDatasourceKey(appKey, datasourceKey) {
|
|
|
52
52
|
* Resolve app key for a datasource: explicit --app, cwd, scan by key, or parse key convention.
|
|
53
53
|
* @async
|
|
54
54
|
* @param {string} datasourceKey - Datasource key (e.g. hubspot-test-company)
|
|
55
|
-
* @param {string} [explicitApp] - Explicit
|
|
55
|
+
* @param {string} [explicitApp] - Explicit integration folder from --app
|
|
56
56
|
* @returns {Promise<{appKey: string}>} Resolved app key
|
|
57
57
|
* @throws {Error} When app cannot be determined or multiple apps match
|
|
58
58
|
*/
|
|
@@ -85,7 +85,7 @@ async function resolveAppKeyForDatasource(datasourceKey, explicitApp) {
|
|
|
85
85
|
}
|
|
86
86
|
if (matches.length > 1) {
|
|
87
87
|
throw new Error(
|
|
88
|
-
`More than one app has this datasource; add --app <
|
|
88
|
+
`More than one app has this datasource; add --app <app>. Apps: ${matches.join(', ')}`
|
|
89
89
|
);
|
|
90
90
|
}
|
|
91
91
|
|
|
@@ -99,7 +99,7 @@ async function resolveAppKeyForDatasource(datasourceKey, explicitApp) {
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
throw new Error(
|
|
102
|
-
'Could not determine app context. Use --app <
|
|
102
|
+
'Could not determine app context. Use --app <app> or run from integration/<systemKey>/ directory.'
|
|
103
103
|
);
|
|
104
104
|
}
|
|
105
105
|
|