@aifabrix/builder 2.45.0 → 2.46.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/cli-layout.mdc +2 -0
- package/.cursor/rules/cli-product-neutral.mdc +43 -0
- package/.cursor/rules/docs-rules.mdc +3 -1
- package/.cursor/rules/project-rules.mdc +1 -0
- package/README.md +43 -17
- package/integration/hubspot-test/wizard-hubspot-e2e.yaml +1 -1
- package/jest.config.default.js +2 -1
- package/jest.config.isolated.js +2 -1
- package/jest.global-live-fabrix-hooks.js +36 -0
- package/jest.isolated-projects.js +130 -0
- package/jest.projects.js +69 -121
- package/lib/api/agent-metadata-validation.api.js +93 -0
- package/lib/api/api-response-errors.js +124 -0
- package/lib/api/audit-api-helpers.js +68 -0
- package/lib/api/audit.api.js +119 -0
- package/lib/api/auth-cache.api.js +44 -0
- package/lib/api/certificates.api.js +4 -4
- package/lib/api/credential.api.js +2 -2
- package/lib/api/dataplane-health.api.js +137 -0
- package/lib/api/dataplane-sync.api.js +27 -0
- package/lib/api/datasources-core.api.js +21 -18
- package/lib/api/datasources-extended.api.js +22 -22
- package/lib/api/dimensions.api.js +3 -0
- package/lib/api/external-systems.api.js +13 -13
- package/lib/api/governance-scenario-pack.api.js +159 -0
- package/lib/api/governance-scenarios.api.js +39 -0
- package/lib/api/groups.api.js +79 -0
- package/lib/api/index.js +88 -5
- package/lib/api/lifecycle.api.js +77 -0
- package/lib/api/pipeline.api.js +7 -5
- package/lib/api/protection.api.js +157 -0
- package/lib/api/records-bulk.api.js +43 -0
- package/lib/api/records-search-parse.js +49 -0
- package/lib/api/records-search.api.js +29 -0
- package/lib/api/types/agent-metadata-validation.types.js +67 -0
- package/lib/api/types/audit.types.js +72 -0
- package/lib/api/types/dataplane-health.types.js +27 -0
- package/lib/api/types/dimensions.types.js +2 -0
- package/lib/api/types/governance-scenarios.types.js +39 -0
- package/lib/api/types/protection.types.js +69 -0
- package/lib/api/types/records-bulk.types.js +35 -0
- package/lib/api/types/records-search.types.js +28 -0
- package/lib/api/user-groups.api.js +50 -0
- package/lib/api/users.api.js +95 -0
- package/lib/api/validation-run.api.js +3 -3
- package/lib/api/validation-runner.js +5 -3
- package/lib/api/wizard-platform.api.js +3 -3
- package/lib/api/wizard.api.js +21 -21
- package/lib/app/deploy-config.js +4 -1
- package/lib/app/deploy.js +34 -19
- package/lib/app/down.js +20 -1
- package/lib/app/push.js +4 -5
- package/lib/app/register.js +7 -4
- package/lib/app/run-env-compose.js +84 -30
- package/lib/build/index.js +5 -0
- package/lib/certification/sync-system-certification.js +13 -6
- package/lib/cli/index.js +8 -2
- package/lib/cli/infra-guided-auth.js +109 -0
- package/lib/cli/infra-guided.js +91 -69
- package/lib/cli/setup-app.help.js +19 -2
- package/lib/cli/setup-app.js +58 -23
- package/lib/cli/setup-app.test-commands.js +28 -21
- package/lib/cli/setup-auth.js +55 -3
- package/lib/cli/setup-certification-commands.js +147 -0
- package/lib/cli/setup-certification.help.js +141 -0
- package/lib/cli/setup-environment.js +19 -2
- package/lib/cli/setup-external-system-help.js +62 -0
- package/lib/cli/setup-external-system.js +62 -6
- package/lib/cli/setup-infra.js +9 -1
- package/lib/cli/setup-platform.js +6 -1
- package/lib/cli/setup-secrets.js +33 -1
- package/lib/cli/setup-utility-help-after.js +65 -0
- package/lib/cli/setup-utility-repair.js +198 -0
- package/lib/cli/setup-utility-resolve.js +42 -6
- package/lib/cli/setup-utility-validate.js +197 -0
- package/lib/cli/setup-utility.js +41 -258
- package/lib/commands/auth-status-client-tokens.js +214 -0
- package/lib/commands/auth-status-dataplane-version.js +269 -0
- package/lib/commands/auth-status-display.js +94 -0
- package/lib/commands/auth-status.js +111 -53
- package/lib/commands/credential-push.js +10 -5
- package/lib/commands/datasource-load-export-cli.js +178 -0
- package/lib/commands/datasource-test-trust-cli.js +118 -0
- package/lib/commands/datasource-unified-test-cli.js +31 -20
- package/lib/commands/datasource-unified-test-cli.options.js +22 -3
- package/lib/commands/datasource-unified-test-e2e-cli-helpers.js +5 -5
- package/lib/commands/datasource-verify-audit-cli.js +96 -0
- package/lib/commands/datasource.js +68 -1
- package/lib/commands/dev-show-display.js +8 -1
- package/lib/commands/dimension-value.js +43 -13
- package/lib/commands/dimension.js +38 -7
- package/lib/commands/governance-cli-shared.js +94 -0
- package/lib/commands/governance-command-action.js +132 -0
- package/lib/commands/governance-download-external.js +34 -0
- package/lib/commands/governance-generate-external.js +71 -0
- package/lib/commands/governance-upload-external.js +36 -0
- package/lib/commands/governance-verify-external.js +64 -0
- package/lib/commands/governance.js +144 -0
- package/lib/commands/identity-apply-sync.js +131 -0
- package/lib/commands/identity-group-cli.js +146 -0
- package/lib/commands/identity-membership-role-cache.js +175 -0
- package/lib/commands/identity-shared.js +94 -0
- package/lib/commands/identity-user-cli.js +158 -0
- package/lib/commands/identity.js +43 -0
- package/lib/commands/lifecycle-command-action.js +123 -0
- package/lib/commands/lifecycle-external.js +268 -0
- package/lib/commands/login.js +56 -17
- package/lib/commands/protection-cli-leaves.js +286 -0
- package/lib/commands/protection.js +50 -0
- package/lib/commands/repair-auth-apply.js +127 -0
- package/lib/commands/repair-changed-files.js +41 -0
- package/lib/commands/repair-datasource-keys.js +4 -1
- package/lib/commands/repair-datasource-run.js +59 -0
- package/lib/commands/repair-datasource-test-payload.js +259 -0
- package/lib/commands/repair-datasource.js +1 -51
- package/lib/commands/repair-env-template.js +64 -13
- package/lib/commands/repair-external-run.js +216 -0
- package/lib/commands/repair-openapi-sync.js +23 -0
- package/lib/commands/repair-persist.js +4 -0
- package/lib/commands/repair-rbac.js +52 -1
- package/lib/commands/repair-steps.js +145 -0
- package/lib/commands/repair.js +29 -286
- package/lib/commands/secrets-get.js +184 -0
- package/lib/commands/secrets-remove-all.js +3 -1
- package/lib/commands/setup-image-refresh.js +146 -0
- package/lib/commands/setup-modes.js +158 -162
- package/lib/commands/setup-platform-auth.js +76 -0
- package/lib/commands/setup-prompts-admin.js +244 -0
- package/lib/commands/setup-prompts-platform-mode.js +67 -0
- package/lib/commands/setup-prompts-validators.js +36 -0
- package/lib/commands/setup-prompts.js +24 -76
- package/lib/commands/setup-run-context.js +45 -0
- package/lib/commands/setup-spinners.js +39 -0
- package/lib/commands/setup.js +27 -5
- package/lib/commands/teardown.js +39 -0
- package/lib/commands/test-e2e-external.js +61 -14
- package/lib/commands/test-governance-cli-options.js +47 -0
- package/lib/commands/test-governance-external.js +67 -0
- package/lib/commands/test-trust-cli-options.js +32 -0
- package/lib/commands/test-trust-external.js +126 -0
- package/lib/commands/up-common.js +25 -13
- package/lib/commands/up-dataplane.js +50 -13
- package/lib/commands/upload-publish-context.js +75 -0
- package/lib/commands/upload-sidecar-followups.js +89 -0
- package/lib/commands/upload.js +108 -105
- package/lib/commands/verify-governance-combined-external.js +61 -0
- package/lib/commands/verify-governance-command-action.js +64 -0
- package/lib/commands/verify-governance-db.js +102 -0
- package/lib/commands/verify-governance-external.js +77 -0
- package/lib/commands/verify-governance-result-builders.js +71 -0
- package/lib/commands/verify-operations-command-action.js +68 -0
- package/lib/commands/verify-operations-external.js +268 -0
- package/lib/commands/verify-operations-persist.js +75 -0
- package/lib/commands/verify-operations-step-plan.js +68 -0
- package/lib/commands/verify-operations-steps.js +111 -0
- package/lib/commands/verify-trust-command-action.js +70 -0
- package/lib/commands/verify-trust-external.js +67 -0
- package/lib/commands/wizard-config-normalizer.js +43 -23
- package/lib/commands/wizard-core.js +5 -0
- package/lib/core/admin-password-generator.js +38 -0
- package/lib/core/admin-secrets-bundle.js +111 -0
- package/lib/core/admin-secrets-env-overlay.js +62 -0
- package/lib/core/admin-secrets.js +32 -4
- package/lib/core/config-attach-extensions.js +3 -0
- package/lib/core/config-device-dataplane.js +185 -0
- package/lib/core/config-platform-controller.js +44 -0
- package/lib/core/config-setup-installation-profile.js +42 -0
- package/lib/core/config-setup-platform-mode.js +46 -0
- package/lib/core/config.js +46 -36
- package/lib/core/secrets-admin-env.js +6 -2
- package/lib/core/secrets-ensure.js +4 -0
- package/lib/core/secrets-env-content.js +54 -48
- package/lib/core/secrets-env-write.js +10 -1
- package/lib/core/secrets-infra-placeholder-sync.js +2 -0
- package/lib/core/setup-installation-profile.js +43 -0
- package/lib/core/setup-platform-mode.js +55 -0
- package/lib/datasource/agent-trust-debug-log.js +45 -0
- package/lib/datasource/agent-trust-fetch.js +115 -0
- package/lib/datasource/agent-trust-map.js +101 -0
- package/lib/datasource/agent-trust-mock.js +44 -0
- package/lib/datasource/agent-trust-run.js +95 -0
- package/lib/datasource/agent-trust-timeout.js +25 -0
- package/lib/datasource/audit-evidence-display.js +80 -0
- package/lib/datasource/audit-evidence-extract-debug.js +115 -0
- package/lib/datasource/audit-evidence-extract.js +180 -0
- package/lib/datasource/audit-evidence-matrix-rows.js +158 -0
- package/lib/datasource/audit-evidence-operation-aliases.js +63 -0
- package/lib/datasource/audit-evidence-poll.js +109 -0
- package/lib/datasource/audit-evidence-run.js +177 -0
- package/lib/datasource/audit-evidence-verify-helpers.js +167 -0
- package/lib/datasource/audit-evidence-verify-matrix.js +205 -0
- package/lib/datasource/audit-evidence-verify.js +108 -0
- package/lib/datasource/bulk-loader-run-batches.js +100 -0
- package/lib/datasource/bulk-loader-service-retry.js +52 -0
- package/lib/datasource/bulk-loader-service.js +127 -0
- package/lib/datasource/capability/run-capability-dimension.js +2 -1
- package/lib/datasource/datasource-exporter-resolve.js +82 -0
- package/lib/datasource/datasource-exporter-service.js +144 -0
- package/lib/datasource/datasource-identifier.js +148 -0
- package/lib/datasource/datasource-load-export-context.js +95 -0
- package/lib/datasource/integration-context.js +6 -4
- package/lib/datasource/local-data-paths.js +145 -0
- package/lib/datasource/log-cleaner.js +241 -0
- package/lib/datasource/log-viewer.js +111 -6
- package/lib/datasource/record-file-parser.js +85 -0
- package/lib/datasource/record-mapper.js +129 -0
- package/lib/datasource/resolve-app.js +74 -55
- package/lib/datasource/test-e2e.js +29 -2
- package/lib/datasource/unified-validation-run-body.js +3 -1
- package/lib/datasource/unified-validation-run-resolve.js +45 -12
- package/lib/datasource/unified-validation-run.js +47 -18
- package/lib/datasource/validate.js +37 -20
- package/lib/deployment/environment-poll-status.js +138 -0
- package/lib/deployment/environment.js +42 -34
- package/lib/external-system/download.js +21 -20
- package/lib/external-system/generator.js +5 -1
- package/lib/external-system/integration-auth-context.js +45 -0
- package/lib/external-system/test-auth.js +12 -5
- package/lib/external-system/test-system-level.js +25 -4
- package/lib/external-system/test.js +9 -7
- package/lib/generator/external-controller-manifest.js +15 -0
- package/lib/governance/governance-cli-errors.js +96 -0
- package/lib/governance/governance-download-display.js +38 -0
- package/lib/governance/governance-pack-loader.js +70 -0
- package/lib/governance/governance-run-display.js +309 -0
- package/lib/identity/identity-apply-core.js +108 -0
- package/lib/identity/identity-apply-phases.js +244 -0
- package/lib/identity/identity-apply-service.js +77 -0
- package/lib/identity/identity-csv-parser.js +114 -0
- package/lib/infrastructure/admin-secrets-apply.js +84 -0
- package/lib/infrastructure/admin-secrets-ensure.js +130 -0
- package/lib/infrastructure/admin-secrets-resolve.js +95 -0
- package/lib/infrastructure/admin-secrets-sync.js +91 -0
- package/lib/infrastructure/helpers.js +23 -129
- package/lib/infrastructure/index.js +5 -6
- package/lib/infrastructure/orphan-infra-docker-teardown.js +11 -5
- package/lib/internal/fs-real-sync.js +29 -1
- package/lib/lifecycle/certification-progress.js +231 -0
- package/lib/lifecycle/dataplane-ui-url.js +145 -0
- package/lib/lifecycle/exit-codes.js +24 -0
- package/lib/lifecycle/json-envelope.js +25 -0
- package/lib/lifecycle/lifecycle-governance-options.js +51 -0
- package/lib/lifecycle/logger-quiet.js +29 -0
- package/lib/lifecycle/open-api-published.js +59 -0
- package/lib/lifecycle/operations-readiness-metrics.js +101 -0
- package/lib/lifecycle/product-model.js +196 -0
- package/lib/lifecycle/report-display.js +471 -0
- package/lib/lifecycle/scenario-upload.js +191 -0
- package/lib/lifecycle/verify-step-progress.js +87 -0
- package/lib/parameters/infra-kv-discovery.js +27 -2
- package/lib/protection/auth-context.js +51 -0
- package/lib/protection/convert-batch.js +90 -0
- package/lib/protection/load.js +41 -0
- package/lib/protection/paths.js +158 -0
- package/lib/protection/preflight-datasource-ready.js +46 -0
- package/lib/protection/protection-create-probe-lines.js +142 -0
- package/lib/protection/protection-create-probes.js +95 -0
- package/lib/protection/protection-create-scaffold.js +281 -0
- package/lib/protection/protection-display-helpers.js +445 -0
- package/lib/protection/protection-display.js +215 -0
- package/lib/protection/protection-preset-registry.js +97 -0
- package/lib/protection/report-exit.js +62 -0
- package/lib/protection/resolve.js +202 -0
- package/lib/protection/run-commands-validate.js +130 -0
- package/lib/protection/run-commands.js +216 -0
- package/lib/protection/run-protection-create-helpers.js +134 -0
- package/lib/protection/run-protection-create-probes-flow.js +43 -0
- package/lib/protection/run-protection-create.js +191 -0
- package/lib/protection/scope.js +22 -0
- package/lib/protection/sync-after-upload.js +64 -0
- package/lib/protection/upload-batch.js +127 -0
- package/lib/protection/validate-batch.js +113 -0
- package/lib/protection/validate-local.js +65 -0
- package/lib/resolvers/dimension-file.js +29 -4
- package/lib/schema/application-schema.json +1 -1
- package/lib/schema/datasource-test-run.schema.json +89 -6
- package/lib/schema/external-datasource.schema.json +2636 -2588
- package/lib/schema/external-system.schema.json +1089 -761
- package/lib/schema/flag-map-validation-run.json +2 -2
- package/lib/schema/infra.parameter.yaml +45 -0
- package/lib/schema/protection.schema.json +374 -0
- package/lib/schema/type/credential-field-registry.json +642 -0
- package/lib/schema/wizard-config.schema.json +1 -1
- package/lib/utils/agent-trust-run-display.js +231 -0
- package/lib/utils/agent-trust-run-exit.js +59 -0
- package/lib/utils/agent-trust-wait-ui.js +94 -0
- package/lib/utils/aifabrix-test-runtime-guard.js +125 -0
- package/lib/utils/api.js +55 -31
- package/lib/utils/app-relative-path-env.js +112 -0
- package/lib/utils/cli-exit-codes.js +30 -0
- package/lib/utils/cli-secrets-error-format.js +83 -21
- package/lib/utils/cli-sync-options.js +33 -0
- package/lib/utils/cli-utils.js +16 -4
- package/lib/utils/compose-generate-docker-compose.js +4 -0
- package/lib/utils/compose-traefik-ingress-base.js +16 -1
- package/lib/utils/config-secrets-path.js +46 -0
- package/lib/utils/controller-url.js +88 -1
- package/lib/utils/credential-push-ui.js +90 -0
- package/lib/utils/credential-secrets-env.js +137 -9
- package/lib/utils/dataplane-cli-version-gate.js +202 -0
- package/lib/utils/dataplane-cli-version-help.js +74 -0
- package/lib/utils/dataplane-resolver.js +129 -2
- package/lib/utils/datasource-export-display.js +137 -0
- package/lib/utils/datasource-load-display.js +174 -0
- package/lib/utils/datasource-load-export-ui.js +120 -0
- package/lib/utils/datasource-test-run-capability-scope.js +3 -3
- package/lib/utils/datasource-test-run-display.js +3 -3
- package/lib/utils/datasource-test-run-tty-log.js +5 -1
- package/lib/utils/declarative-url-ports.js +3 -3
- package/lib/utils/deployment-auth-mode.js +41 -0
- package/lib/utils/developer-volume-id.js +33 -0
- package/lib/utils/env-copy.js +14 -9
- package/lib/utils/env-kv-orphan-lines.js +43 -0
- package/lib/utils/error-formatters/network-errors.js +13 -4
- package/lib/utils/external-env-template.js +1 -0
- package/lib/utils/external-system-readiness-core.js +10 -0
- package/lib/utils/external-system-readiness-display.js +80 -23
- package/lib/utils/health-check.js +4 -1
- package/lib/utils/help-builder.js +35 -26
- package/lib/utils/keycloak-realm-ready.js +101 -0
- package/lib/utils/load-cip-capacity-display-config.js +61 -15
- package/lib/utils/manifest-source-emit.js +24 -0
- package/lib/utils/pipeline-upload-auth-retry.js +82 -0
- package/lib/utils/platform-controller-url.js +156 -0
- package/lib/utils/postgres-platform-bootstrap.js +199 -0
- package/lib/utils/postgres-wipe.js +9 -2
- package/lib/utils/resolve-env-mode.js +47 -0
- package/lib/utils/secrets-generator.js +31 -25
- package/lib/utils/secrets-missing-error.js +164 -0
- package/lib/utils/semver-compare.js +127 -0
- package/lib/utils/service-url-label.js +81 -0
- package/lib/utils/setup-quiet-output.js +25 -0
- package/lib/utils/template-helpers.js +15 -0
- package/lib/utils/token-manager-client-credentials.js +201 -0
- package/lib/utils/token-manager-messages.js +8 -0
- package/lib/utils/token-manager-refresh.js +12 -2
- package/lib/utils/token-manager.js +86 -105
- package/lib/utils/upload-pipeline-ui.js +98 -0
- package/lib/utils/upload-sync-options.js +42 -0
- package/lib/utils/url-declarative-public-base.js +21 -3
- package/lib/utils/url-declarative-vdir-inactive-env.js +14 -4
- package/lib/utils/validation-poll-ui.js +22 -7
- package/lib/utils/validation-run-stage.js +45 -0
- package/lib/validation/wizard-config-validator.js +58 -19
- package/package.json +1 -1
- package/templates/applications/dataplane/application.yaml +2 -1
- package/templates/applications/dataplane/env.template +36 -1
- package/templates/applications/dataplane/rbac.yaml +4 -0
- package/templates/applications/miso-controller/env.template +16 -0
- package/templates/external-system/README.md.hbs +116 -11
- package/templates/python/docker-compose.hbs +19 -18
- package/templates/typescript/docker-compose.hbs +18 -17
|
@@ -44,6 +44,7 @@ Examples:
|
|
|
44
44
|
$ aifabrix datasource test-e2e hubspot-users --app test-e2e-hubspot -v --debug
|
|
45
45
|
$ aifabrix datasource test-e2e my-documents-ds --min-vector-hits 7 -v --debug
|
|
46
46
|
$ aifabrix datasource test-e2e hubspot-users -a test-e2e-hubspot --no-async
|
|
47
|
+
$ aifabrix datasource test-e2e hubspot-users --sync --force --verify-audit -v
|
|
47
48
|
$ aifabrix datasource test-e2e hubspot-users read
|
|
48
49
|
|
|
49
50
|
Notes:
|
|
@@ -53,6 +54,7 @@ Notes:
|
|
|
53
54
|
aifabrix datasource test-integration <datasourceKey>
|
|
54
55
|
- For system-level E2E rollup across datasources, use:
|
|
55
56
|
aifabrix test-e2e <systemKey>
|
|
57
|
+
- To prove governance audit evidence after a green E2E, add --verify-audit (see verify-audit command).
|
|
56
58
|
`;
|
|
57
59
|
}
|
|
58
60
|
|
|
@@ -127,6 +129,10 @@ function attachDatasourceTestCommonOptions(cmd, opts) {
|
|
|
127
129
|
'--sync',
|
|
128
130
|
'Publish local integration config to the dataplane before running the test (same as aifabrix upload <systemKey>; requires login)'
|
|
129
131
|
)
|
|
132
|
+
.option(
|
|
133
|
+
'--force',
|
|
134
|
+
'With --sync, pass force to upload (bypass active-datasource schema replacement guards; same as aifabrix upload --force)'
|
|
135
|
+
)
|
|
130
136
|
.option('--json', 'Print raw DatasourceTestRun JSON to stdout')
|
|
131
137
|
.option('--summary', 'Print compact summary line')
|
|
132
138
|
.option('--warnings-as-errors', 'Exit 1 when root status is warn')
|
|
@@ -175,11 +181,24 @@ function attachDatasourceTestE2eExclusiveOptions(cmd) {
|
|
|
175
181
|
'--primary-key-value <value|@path>',
|
|
176
182
|
'Primary key value or path to JSON file (e.g. @pk.json) for e2eOptions.primaryKeyValue'
|
|
177
183
|
)
|
|
178
|
-
.option('--capability <key>', 'Capability drill-down (deprecated; use positional [capabilityKey])')
|
|
179
184
|
.option(
|
|
180
185
|
'--strict-capability-scope',
|
|
181
|
-
'Exit 1
|
|
182
|
-
)
|
|
186
|
+
'Exit 1 when positional [capabilityKey] is set but the report lists more than one capabilities[] row'
|
|
187
|
+
)
|
|
188
|
+
.option(
|
|
189
|
+
'--verify-audit',
|
|
190
|
+
'After successful E2E, verify the nine-row audit evidence matrix on the dataplane (requires audit:read)'
|
|
191
|
+
)
|
|
192
|
+
.option(
|
|
193
|
+
'--no-verify-audit',
|
|
194
|
+
'Skip audit evidence verification even if enabled by default in a future release'
|
|
195
|
+
)
|
|
196
|
+
.option(
|
|
197
|
+
'--audit-poll-ms <ms>',
|
|
198
|
+
'Max wait for audit rows after E2E when using --verify-audit (default 15000)',
|
|
199
|
+
'15000'
|
|
200
|
+
)
|
|
201
|
+
.option('--audit-poll-interval-ms <ms>', 'Audit poll interval when using --verify-audit (default 2000)', '2000');
|
|
183
202
|
}
|
|
184
203
|
|
|
185
204
|
module.exports = {
|
|
@@ -46,7 +46,7 @@ function exitCodeFromDatasourceTestRunEnvelope(env, options) {
|
|
|
46
46
|
warningsAsErrors: options.warningsAsErrors === true,
|
|
47
47
|
requireCert: options.requireCert === true
|
|
48
48
|
});
|
|
49
|
-
const scope = analyzeCapabilityScope(env, options.
|
|
49
|
+
const scope = analyzeCapabilityScope(env, options.capabilityKey);
|
|
50
50
|
if (options.strictCapabilityScope === true && scope.violated) {
|
|
51
51
|
code = Math.max(code, 1);
|
|
52
52
|
}
|
|
@@ -62,10 +62,10 @@ function exitCodeFromDatasourceTestRunEnvelope(env, options) {
|
|
|
62
62
|
function finalizeDatasourceTestE2ELegacyPath(data, options) {
|
|
63
63
|
displayE2EResults(data, options.verbose);
|
|
64
64
|
logDatasourceTestRunDebugAppendix(data.datasourceTestRun, options.debug);
|
|
65
|
-
logE2eCapabilityFocusFromEnvelope(data.datasourceTestRun, options.
|
|
65
|
+
logE2eCapabilityFocusFromEnvelope(data.datasourceTestRun, options.capabilityKey);
|
|
66
66
|
const env = data.datasourceTestRun;
|
|
67
67
|
if (env) {
|
|
68
|
-
emitCapabilityScopeDiagnostics(env, { requestedCapabilityKey: options.
|
|
68
|
+
emitCapabilityScopeDiagnostics(env, { requestedCapabilityKey: options.capabilityKey });
|
|
69
69
|
const code = exitCodeFromDatasourceTestRunEnvelope(env, options);
|
|
70
70
|
return code === null ? 1 : code;
|
|
71
71
|
}
|
|
@@ -91,10 +91,10 @@ function displayDatasourceTestE2EEnvelopeResults(datasourceKey, env, options) {
|
|
|
91
91
|
{
|
|
92
92
|
debug: options.debug,
|
|
93
93
|
runType: 'e2e',
|
|
94
|
-
requestedCapabilityKey: options.
|
|
94
|
+
requestedCapabilityKey: options.capabilityKey
|
|
95
95
|
}
|
|
96
96
|
);
|
|
97
|
-
logE2eCapabilityFocusFromEnvelope(env, options.
|
|
97
|
+
logE2eCapabilityFocusFromEnvelope(env, options.capabilityKey);
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
module.exports = {
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `aifabrix datasource verify-audit` — re-run 407.1 matrix from last E2E log
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const logger = require('../utils/logger');
|
|
10
|
+
const { formatBlockingError } = require('../utils/cli-test-layout-chalk');
|
|
11
|
+
const { runAuditEvidenceVerification } = require('../datasource/audit-evidence-run');
|
|
12
|
+
const { loadEnvelopeFromLatestE2eLog } = require('../datasource/audit-evidence-extract');
|
|
13
|
+
|
|
14
|
+
const VERIFY_AUDIT_HELP_AFTER = `
|
|
15
|
+
Examples:
|
|
16
|
+
$ aifabrix datasource verify-audit test-e2e-hubspot-companies
|
|
17
|
+
$ aifabrix datasource verify-audit test-e2e-hubspot-companies --app test-e2e-hubspot -v
|
|
18
|
+
$ aifabrix datasource verify-audit test-e2e-hubspot-companies --correlation-id <testRunId>
|
|
19
|
+
$ aifabrix datasource verify-audit test-e2e-hubspot-companies --json
|
|
20
|
+
|
|
21
|
+
Notes:
|
|
22
|
+
- Re-checks audit evidence from the latest test-e2e debug log (or --file) without re-running E2E.
|
|
23
|
+
- Requires audit:read on the dataplane (same login as test-e2e).
|
|
24
|
+
- Pair with: aifabrix datasource test-e2e <datasourceKey> --verify-audit
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @param {string} datasourceKey
|
|
29
|
+
* @param {Object} options
|
|
30
|
+
*/
|
|
31
|
+
async function verifyAuditCommandAction(datasourceKey, options) {
|
|
32
|
+
const envelope = await loadEnvelopeFromLatestE2eLog(datasourceKey, options);
|
|
33
|
+
if (!envelope) {
|
|
34
|
+
logger.error(
|
|
35
|
+
formatBlockingError('verify-audit failed:'),
|
|
36
|
+
'No test-e2e debug log found (run test-e2e with --debug first)'
|
|
37
|
+
);
|
|
38
|
+
process.exit(3);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const pollMs = parseInt(String(options.auditPollMs || '15000'), 10);
|
|
42
|
+
const pollInterval = parseInt(String(options.auditPollIntervalMs || '2000'), 10);
|
|
43
|
+
const { exitCode } = await runAuditEvidenceVerification(datasourceKey, envelope, {
|
|
44
|
+
app: options.app,
|
|
45
|
+
env: options.env,
|
|
46
|
+
verbose: options.verbose,
|
|
47
|
+
json: options.json,
|
|
48
|
+
correlationId: options.correlationId,
|
|
49
|
+
executionId: options.executionId,
|
|
50
|
+
quiet: false,
|
|
51
|
+
auditPollMaxWaitMs: Number.isFinite(pollMs) ? pollMs : 15000,
|
|
52
|
+
auditPollIntervalMs: Number.isFinite(pollInterval) ? pollInterval : 2000
|
|
53
|
+
});
|
|
54
|
+
process.exit(exitCode);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @param {import('commander').Command} datasource
|
|
59
|
+
*/
|
|
60
|
+
function setupDatasourceVerifyAuditCommand(datasource) {
|
|
61
|
+
datasource
|
|
62
|
+
.command('verify-audit <datasourceKey>')
|
|
63
|
+
.description(
|
|
64
|
+
'Verify audit evidence matrix from latest E2E log (or --file) without re-running E2E'
|
|
65
|
+
)
|
|
66
|
+
.option(
|
|
67
|
+
'-a, --app <app>',
|
|
68
|
+
'Integration folder name (optional: resolve from cwd or datasource key if single match)'
|
|
69
|
+
)
|
|
70
|
+
.option('-e, --env <env>', 'Environment: dev, tst, or pro')
|
|
71
|
+
.option('-v, --verbose', 'Show matrix row codes and execution id count')
|
|
72
|
+
.option('--json', 'Print auditEvidenceVerification JSON block')
|
|
73
|
+
.option('-f, --file <path>', 'Path to test-e2e debug log JSON')
|
|
74
|
+
.option('--correlation-id <id>', 'Override correlation/testRunId filter')
|
|
75
|
+
.option('--execution-id <id>', 'Include execution id for sub-resource checks')
|
|
76
|
+
.option(
|
|
77
|
+
'--audit-poll-ms <ms>',
|
|
78
|
+
'Max wait for audit rows to appear (default 15000)',
|
|
79
|
+
'15000'
|
|
80
|
+
)
|
|
81
|
+
.option('--audit-poll-interval-ms <ms>', 'Poll interval (default 2000)', '2000')
|
|
82
|
+
.addHelpText('after', VERIFY_AUDIT_HELP_AFTER)
|
|
83
|
+
.action(async(datasourceKey, options) => {
|
|
84
|
+
try {
|
|
85
|
+
await verifyAuditCommandAction(datasourceKey, options);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
logger.error(formatBlockingError('verify-audit failed:'), error.message);
|
|
88
|
+
process.exit(3);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
module.exports = {
|
|
94
|
+
setupDatasourceVerifyAuditCommand,
|
|
95
|
+
verifyAuditCommandAction
|
|
96
|
+
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* AI Fabrix Builder - Datasource Commands
|
|
3
3
|
*
|
|
4
4
|
* Handles datasource validation, listing, comparison, deployment, and online validation runs.
|
|
5
|
-
* Subcommands `test`, `test-integration`,
|
|
5
|
+
* Subcommands `test`, `test-integration`, `test-e2e`, and `verify-trust` call the dataplane; `log-*` read saved debug JSON locally; `clean-logs` removes those files. Permissions are summarized in `docs/commands/permissions.md`.
|
|
6
6
|
*
|
|
7
7
|
* @fileoverview Datasource management commands for AI Fabrix Builder
|
|
8
8
|
* @author AI Fabrix Team
|
|
@@ -18,11 +18,15 @@ const { listDatasources } = require('../datasource/list');
|
|
|
18
18
|
const { compareDatasources } = require('../datasource/diff');
|
|
19
19
|
const { deployDatasource } = require('../datasource/deploy');
|
|
20
20
|
const { runLogViewer } = require('../datasource/log-viewer');
|
|
21
|
+
const { runCleanLogs } = require('../datasource/log-cleaner');
|
|
21
22
|
const {
|
|
22
23
|
setupDatasourceTestCommand,
|
|
23
24
|
setupDatasourceTestIntegrationCommand,
|
|
24
25
|
setupDatasourceTestE2ECommand
|
|
25
26
|
} = require('./datasource-unified-test-cli');
|
|
27
|
+
const { setupDatasourceVerifyTrustCommand } = require('./datasource-test-trust-cli');
|
|
28
|
+
const { setupDatasourceVerifyAuditCommand } = require('./datasource-verify-audit-cli');
|
|
29
|
+
const { setupDatasourceLoadExportCommands } = require('./datasource-load-export-cli');
|
|
26
30
|
const { setupDatasourceCapabilityCommands } = require('./datasource-capability');
|
|
27
31
|
|
|
28
32
|
/**
|
|
@@ -38,10 +42,17 @@ Examples:
|
|
|
38
42
|
$ af ds upload <datasourceKey> # same as: aifabrix datasource upload …
|
|
39
43
|
$ af ds test <datasourceKey> --app <integrationFolder> --debug
|
|
40
44
|
$ af ds test-e2e <datasourceKey> --app <integrationFolder> -v
|
|
45
|
+
$ af ds test-e2e <datasourceKey> --verify-audit
|
|
46
|
+
$ af ds verify-audit <datasourceKey>
|
|
47
|
+
$ af ds verify-trust <datasourceKey> --app <integrationFolder> -v
|
|
48
|
+
$ af ds load <datasourceKey> --app <integrationFolder> --dry-run
|
|
49
|
+
$ af ds export <datasourceKey> --app <integrationFolder> --format ndjson -v
|
|
41
50
|
$ aifabrix datasource capability copy <file-or-key> --from create --as createBasicTrial --dry-run
|
|
42
51
|
$ aifabrix datasource capability remove <file-or-key> --capability createTrial --dry-run
|
|
43
52
|
$ aifabrix datasource capability diff ./a.json ./b.json --capability list
|
|
44
53
|
$ aifabrix datasource capability edit <file-or-key> --capability create --section openapi
|
|
54
|
+
$ aifabrix datasource clean-logs --app test-e2e-hubspot --dry-run
|
|
55
|
+
$ aifabrix datasource clean-logs --all --type e2e
|
|
45
56
|
|
|
46
57
|
Per-command help: aifabrix datasource <command> --help
|
|
47
58
|
Shorthand: af ds (alias for datasource)
|
|
@@ -220,6 +231,57 @@ function setupDatasourceLogTestCommand(datasource) {
|
|
|
220
231
|
});
|
|
221
232
|
}
|
|
222
233
|
|
|
234
|
+
function setupDatasourceCleanLogsCommand(datasource) {
|
|
235
|
+
datasource
|
|
236
|
+
.command('clean-logs')
|
|
237
|
+
.description('Remove saved test debug JSON under integration/<app>/logs/')
|
|
238
|
+
.option('-a, --app <app>', 'Integration folder name (system key)')
|
|
239
|
+
.option('--all', 'Clean logs under every integration/<app>/logs/ folder')
|
|
240
|
+
.option(
|
|
241
|
+
'-t, --type <type>',
|
|
242
|
+
'Log kind: test, integration, e2e, trust, or all (default: all)',
|
|
243
|
+
'all'
|
|
244
|
+
)
|
|
245
|
+
.option('--dry-run', 'List files that would be removed without deleting')
|
|
246
|
+
.option('--json', 'Machine-readable summary on stdout')
|
|
247
|
+
.action(async options => {
|
|
248
|
+
try {
|
|
249
|
+
await runCleanLogs({
|
|
250
|
+
app: options.app,
|
|
251
|
+
all: options.all,
|
|
252
|
+
type: options.type,
|
|
253
|
+
dryRun: options.dryRun,
|
|
254
|
+
json: options.json
|
|
255
|
+
});
|
|
256
|
+
} catch (error) {
|
|
257
|
+
logger.error(formatBlockingError('clean-logs failed:'), error.message);
|
|
258
|
+
process.exit(1);
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function setupDatasourceLogTrustCommand(datasource) {
|
|
264
|
+
datasource.command('log-trust <datasourceKey>')
|
|
265
|
+
.description('Show agent trust log from datasource verify-trust (latest verify-trust-*.json or --file)')
|
|
266
|
+
.option(
|
|
267
|
+
'-a, --app <app>',
|
|
268
|
+
'Integration folder name (optional: resolve from cwd or datasource key if single match)'
|
|
269
|
+
)
|
|
270
|
+
.option('-f, --file <path>', 'Path to log file (default: latest verify-trust log in app logs folder)')
|
|
271
|
+
.action(async(datasourceKey, options) => {
|
|
272
|
+
try {
|
|
273
|
+
await runLogViewer(datasourceKey, {
|
|
274
|
+
app: options.app,
|
|
275
|
+
file: options.file,
|
|
276
|
+
logType: 'verify-trust'
|
|
277
|
+
});
|
|
278
|
+
} catch (error) {
|
|
279
|
+
logger.error(formatBlockingError('log-trust failed:'), error.message);
|
|
280
|
+
process.exit(1);
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
|
|
223
285
|
/**
|
|
224
286
|
* Setup datasource management commands
|
|
225
287
|
* @param {Command} program - Commander program instance
|
|
@@ -237,12 +299,17 @@ function setupDatasourceCommands(program) {
|
|
|
237
299
|
setupDatasourceListCommand(datasource);
|
|
238
300
|
setupDatasourceDiffCommand(datasource);
|
|
239
301
|
setupDatasourceUploadCommand(datasource);
|
|
302
|
+
setupDatasourceLoadExportCommands(datasource);
|
|
240
303
|
setupDatasourceTestCommand(datasource);
|
|
241
304
|
setupDatasourceTestIntegrationCommand(datasource);
|
|
242
305
|
setupDatasourceTestE2ECommand(datasource);
|
|
306
|
+
setupDatasourceVerifyAuditCommand(datasource);
|
|
307
|
+
setupDatasourceVerifyTrustCommand(datasource);
|
|
243
308
|
setupDatasourceLogE2ECommand(datasource);
|
|
244
309
|
setupDatasourceLogIntegrationCommand(datasource);
|
|
245
310
|
setupDatasourceLogTestCommand(datasource);
|
|
311
|
+
setupDatasourceLogTrustCommand(datasource);
|
|
312
|
+
setupDatasourceCleanLogsCommand(datasource);
|
|
246
313
|
}
|
|
247
314
|
|
|
248
315
|
module.exports = { setupDatasourceCommands };
|
|
@@ -336,6 +336,8 @@ function logConfigurationSection(p) {
|
|
|
336
336
|
logRow('Environment', p.environment);
|
|
337
337
|
logRow('Controller', p.controller);
|
|
338
338
|
logRow('Format', p.formatVal);
|
|
339
|
+
logRow('Platform mode', p.setupPlatformMode);
|
|
340
|
+
logRow('Traefik', p.traefikEnabled ? 'on' : 'off');
|
|
339
341
|
logRow('Scoped resources', p.scopedResourcesLabel);
|
|
340
342
|
logRow('URLs registry', p.urlsLocalPath);
|
|
341
343
|
if (!p.hasRemote) {
|
|
@@ -386,11 +388,12 @@ async function loadDevShowData(devIdStr) {
|
|
|
386
388
|
const devIdNum = parseInt(devIdStr, 10);
|
|
387
389
|
const ports = devConfig.getDevPorts(Number.isNaN(devIdNum) ? 0 : devIdNum);
|
|
388
390
|
const [
|
|
389
|
-
environment, tlsEnabled, controller, formatRaw, useScoped, secretsRaw,
|
|
391
|
+
environment, tlsEnabled, controller, formatRaw, useScoped, secretsRaw, setupPlatformMode, traefikEnabled,
|
|
390
392
|
remoteServer, dockerEndpoint, dockerTlsSkipVerify, mutagenFolder, syncSshUser, syncSshHost
|
|
391
393
|
] = await Promise.all([
|
|
392
394
|
config.getCurrentEnvironment(), config.getTlsEnabled(), config.getControllerUrl(),
|
|
393
395
|
config.getFormat(), config.getUseEnvironmentScopedResources(), config.getAifabrixSecretsPath(),
|
|
396
|
+
config.getSetupPlatformMode(), config.getTraefikEnabled(),
|
|
394
397
|
config.getRemoteServer(), config.getDockerEndpoint(), config.getDockerTlsSkipVerify(),
|
|
395
398
|
config.getUserMutagenFolder(), config.getSyncSshUser(), config.getSyncSshHost()
|
|
396
399
|
]);
|
|
@@ -410,6 +413,8 @@ async function loadDevShowData(devIdStr) {
|
|
|
410
413
|
controller,
|
|
411
414
|
formatVal: formatRaw ?? null,
|
|
412
415
|
scopedResourcesLabel,
|
|
416
|
+
setupPlatformMode,
|
|
417
|
+
traefikEnabled,
|
|
413
418
|
workResolved,
|
|
414
419
|
homeResolved,
|
|
415
420
|
secretsMain,
|
|
@@ -446,6 +451,8 @@ function renderDevShow(data) {
|
|
|
446
451
|
tlsEnabled: data.tlsEnabled,
|
|
447
452
|
controller: data.controller,
|
|
448
453
|
formatVal: data.formatVal,
|
|
454
|
+
setupPlatformMode: data.setupPlatformMode,
|
|
455
|
+
traefikEnabled: data.traefikEnabled,
|
|
449
456
|
scopedResourcesLabel: data.scopedResourcesLabel,
|
|
450
457
|
urlsLocalPath: data.urlsLocalPath,
|
|
451
458
|
hasRemote: data.hasRemote,
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Dimension value commands (Controller).
|
|
3
3
|
*
|
|
4
4
|
* Commands:
|
|
5
|
-
* - aifabrix dimension
|
|
6
|
-
* - aifabrix dimension
|
|
7
|
-
* - aifabrix dimension
|
|
5
|
+
* - aifabrix dimension value create
|
|
6
|
+
* - aifabrix dimension value list
|
|
7
|
+
* - aifabrix dimension value delete
|
|
8
8
|
*
|
|
9
9
|
* @fileoverview Dimension value CLI commands
|
|
10
10
|
* @author AI Fabrix Team
|
|
@@ -25,29 +25,39 @@ const {
|
|
|
25
25
|
deleteDimensionValue
|
|
26
26
|
} = require('../api/dimension-values.api');
|
|
27
27
|
|
|
28
|
+
const DIMENSION_VALUE_HELP_AFTER = `
|
|
29
|
+
|
|
30
|
+
Examples:
|
|
31
|
+
$ aifabrix dimension value create customerRegion --value emea --display-name "EMEA"
|
|
32
|
+
$ aifabrix dimension value list customerRegion
|
|
33
|
+
$ aifabrix dimension value delete clx1234567890abcdef
|
|
34
|
+
|
|
35
|
+
Per-command help: aifabrix dimension value <command> --help
|
|
36
|
+
`;
|
|
37
|
+
|
|
28
38
|
const DIMENSION_VALUE_CREATE_HELP_AFTER = `
|
|
29
39
|
|
|
30
40
|
Examples:
|
|
31
|
-
$ aifabrix dimension
|
|
32
|
-
$ aifabrix dimension
|
|
41
|
+
$ aifabrix dimension value create customerRegion --value emea --display-name "EMEA"
|
|
42
|
+
$ aifabrix dimension value create customerRegion --value na --display-name "North America"
|
|
33
43
|
|
|
34
44
|
`;
|
|
35
45
|
|
|
36
46
|
const DIMENSION_VALUE_LIST_HELP_AFTER = `
|
|
37
47
|
|
|
38
48
|
Examples:
|
|
39
|
-
$ aifabrix dimension
|
|
40
|
-
$ aifabrix dimension
|
|
41
|
-
$ aifabrix dimension
|
|
49
|
+
$ aifabrix dimension value list customerRegion
|
|
50
|
+
$ aifabrix dimension value list customerRegion --page 1 --page-size 50
|
|
51
|
+
$ aifabrix dimension value list customerRegion --search emea
|
|
42
52
|
|
|
43
53
|
`;
|
|
44
54
|
|
|
45
55
|
const DIMENSION_VALUE_DELETE_HELP_AFTER = `
|
|
46
56
|
|
|
47
57
|
Examples:
|
|
48
|
-
$ aifabrix dimension
|
|
58
|
+
$ aifabrix dimension value delete clx1234567890abcdef
|
|
49
59
|
|
|
50
|
-
Tip: Find ids via "aifabrix dimension get <key>" (it prints values) or "aifabrix dimension
|
|
60
|
+
Tip: Find ids via "aifabrix dimension get <key>" (it prints values) or "aifabrix dimension value list <key>".
|
|
51
61
|
|
|
52
62
|
`;
|
|
53
63
|
|
|
@@ -62,6 +72,17 @@ function requireNonEmpty(raw, label) {
|
|
|
62
72
|
return s;
|
|
63
73
|
}
|
|
64
74
|
|
|
75
|
+
/**
|
|
76
|
+
* @param {Object} response - Controller API response
|
|
77
|
+
* @throws {Error} When response.success === false
|
|
78
|
+
*/
|
|
79
|
+
function throwIfApiFailed(response) {
|
|
80
|
+
if (!response || response.success !== false) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
throw new Error(response.formattedError || response.error || 'Request failed');
|
|
84
|
+
}
|
|
85
|
+
|
|
65
86
|
async function resolveControllerAndAuth() {
|
|
66
87
|
const controllerUrl = await resolveControllerUrl();
|
|
67
88
|
if (!controllerUrl) {
|
|
@@ -100,6 +121,7 @@ function setupDimensionValueCreateCommand(cmd) {
|
|
|
100
121
|
displayName: options.displayName,
|
|
101
122
|
description: options.description
|
|
102
123
|
});
|
|
124
|
+
throwIfApiFailed(res);
|
|
103
125
|
const row = unwrapControllerData(res);
|
|
104
126
|
logger.log(formatSuccessLine(`Dimension value created: ${dimKey}.${row.value}`));
|
|
105
127
|
} catch (e) {
|
|
@@ -126,6 +148,7 @@ function setupDimensionValueListCommand(cmd) {
|
|
|
126
148
|
pageSize: options.pageSize,
|
|
127
149
|
search: options.search
|
|
128
150
|
});
|
|
151
|
+
throwIfApiFailed(res);
|
|
129
152
|
const payload = unwrapControllerData(res);
|
|
130
153
|
const items = payload?.data ?? payload ?? [];
|
|
131
154
|
logger.log(chalk.bold('\n🏷 Dimension values:\n'));
|
|
@@ -157,7 +180,8 @@ function setupDimensionValueDeleteCommand(cmd) {
|
|
|
157
180
|
try {
|
|
158
181
|
const { controllerUrl, authConfig } = await resolveControllerAndAuth();
|
|
159
182
|
const id = requireNonEmpty(dimensionValueId, 'dimensionValueId');
|
|
160
|
-
await deleteDimensionValue(controllerUrl, authConfig, id);
|
|
183
|
+
const res = await deleteDimensionValue(controllerUrl, authConfig, id);
|
|
184
|
+
throwIfApiFailed(res);
|
|
161
185
|
logger.log(formatSuccessLine(`Dimension value deleted: ${id}`));
|
|
162
186
|
} catch (e) {
|
|
163
187
|
logger.error(formatBlockingError(e.message));
|
|
@@ -166,8 +190,14 @@ function setupDimensionValueDeleteCommand(cmd) {
|
|
|
166
190
|
});
|
|
167
191
|
}
|
|
168
192
|
|
|
169
|
-
|
|
170
|
-
|
|
193
|
+
/**
|
|
194
|
+
* @param {import('commander').Command} dimensionCmd - Parent `dimension` command
|
|
195
|
+
*/
|
|
196
|
+
function setupDimensionValueCommands(dimensionCmd) {
|
|
197
|
+
const cmd = dimensionCmd
|
|
198
|
+
.command('value')
|
|
199
|
+
.description('Manage dimension values (static dimensions)')
|
|
200
|
+
.addHelpText('after', DIMENSION_VALUE_HELP_AFTER);
|
|
171
201
|
setupDimensionValueCreateCommand(cmd);
|
|
172
202
|
setupDimensionValueListCommand(cmd);
|
|
173
203
|
setupDimensionValueDeleteCommand(cmd);
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* - aifabrix dimension create
|
|
6
6
|
* - aifabrix dimension get
|
|
7
7
|
* - aifabrix dimension list
|
|
8
|
+
* - aifabrix dimension value create|list|delete
|
|
8
9
|
*
|
|
9
10
|
* @fileoverview Dimension CLI commands
|
|
10
11
|
* @author AI Fabrix Team
|
|
@@ -18,7 +19,7 @@ const logger = require('../utils/logger');
|
|
|
18
19
|
const { resolveControllerUrl } = require('../utils/controller-url');
|
|
19
20
|
const { normalizeControllerUrl, resolveEnvironment } = require('../core/config');
|
|
20
21
|
const { getOrRefreshDeviceToken } = require('../utils/token-manager');
|
|
21
|
-
const { readDimensionCreateFile } = require('../resolvers/dimension-file');
|
|
22
|
+
const { readDimensionCreateFile, normalizeValueType } = require('../resolvers/dimension-file');
|
|
22
23
|
const {
|
|
23
24
|
formatBlockingError,
|
|
24
25
|
formatSuccessLine,
|
|
@@ -31,8 +32,23 @@ const {
|
|
|
31
32
|
createDimensionIdempotent
|
|
32
33
|
} = require('../api/dimensions.api');
|
|
33
34
|
const { createDimensionValue } = require('../api/dimension-values.api');
|
|
35
|
+
const { setupDimensionValueCommands } = require('./dimension-value');
|
|
34
36
|
|
|
35
37
|
const DIMENSION_KEY_PATTERN = /^[a-zA-Z][a-zA-Z0-9-_]*$/;
|
|
38
|
+
|
|
39
|
+
/** Parent help for `aifabrix dimension -h` (leaf commands have their own Examples blocks). */
|
|
40
|
+
const DIMENSION_HELP_AFTER = `
|
|
41
|
+
|
|
42
|
+
Examples:
|
|
43
|
+
$ aifabrix dimension create --key customerRegion --display-name "Customer Region" --data-type string
|
|
44
|
+
$ aifabrix dimension get customerRegion
|
|
45
|
+
$ aifabrix dimension list --search region
|
|
46
|
+
$ aifabrix dimension value create customerRegion --value emea --display-name "EMEA"
|
|
47
|
+
$ aifabrix dimension value list customerRegion
|
|
48
|
+
|
|
49
|
+
Per-command help: aifabrix dimension <command> --help
|
|
50
|
+
`;
|
|
51
|
+
|
|
36
52
|
const DATA_TYPES = new Set(['string', 'number', 'boolean']);
|
|
37
53
|
|
|
38
54
|
const DIMENSION_CREATE_HELP_AFTER = `
|
|
@@ -139,6 +155,11 @@ function buildCreatePayload(options) {
|
|
|
139
155
|
if (options.displayName) payload.displayName = options.displayName;
|
|
140
156
|
if (options.description !== undefined) payload.description = options.description;
|
|
141
157
|
if (options.dataType) payload.dataType = options.dataType;
|
|
158
|
+
if (options.valueType) {
|
|
159
|
+
payload.valueType = normalizeValueType(options.valueType);
|
|
160
|
+
} else if (payload.valueType === undefined) {
|
|
161
|
+
payload.valueType = 'static';
|
|
162
|
+
}
|
|
142
163
|
if (options.required !== undefined && options.required !== null) {
|
|
143
164
|
payload.isRequired = Boolean(options.required);
|
|
144
165
|
}
|
|
@@ -197,6 +218,7 @@ function setupDimensionCreateCommand(dim) {
|
|
|
197
218
|
.option('--display-name <name>', 'Display name')
|
|
198
219
|
.option('--description <text>', 'Description')
|
|
199
220
|
.option('--data-type <type>', 'string | number | boolean')
|
|
221
|
+
.option('--value-type <mode>', 'static | dynamic | both (catalog assignment mode)')
|
|
200
222
|
.option('--required', 'Mark dimension required (isRequired=true)')
|
|
201
223
|
.option('--no-required', 'Mark dimension not required (isRequired=false)')
|
|
202
224
|
.action(async(options) => {
|
|
@@ -206,11 +228,12 @@ function setupDimensionCreateCommand(dim) {
|
|
|
206
228
|
const out = await createDimensionIdempotent(controllerUrl, authConfig, payload);
|
|
207
229
|
const dimRow = unwrapControllerData(out.response);
|
|
208
230
|
await maybeCreateValuesFromFile(controllerUrl, authConfig, payload);
|
|
231
|
+
const vt = dimRow.valueType || payload.valueType || 'static';
|
|
209
232
|
if (out.created) {
|
|
210
|
-
logger.log(formatSuccessLine(`Dimension created: ${dimRow.key}`));
|
|
233
|
+
logger.log(formatSuccessLine(`Dimension created: ${dimRow.key} (valueType: ${vt})`));
|
|
211
234
|
return;
|
|
212
235
|
}
|
|
213
|
-
logger.log(formatSuccessLine(`Dimension exists: ${dimRow.key}`));
|
|
236
|
+
logger.log(formatSuccessLine(`Dimension exists: ${dimRow.key} (valueType: ${vt})`));
|
|
214
237
|
logger.log(infoLine('No changes were needed.'));
|
|
215
238
|
} catch (e) {
|
|
216
239
|
logger.error(formatBlockingError(e.message));
|
|
@@ -236,6 +259,7 @@ function setupDimensionGetCommand(dim) {
|
|
|
236
259
|
logger.log(headerKeyValue('Key:', row.key || '—'));
|
|
237
260
|
logger.log(headerKeyValue('Display:', row.displayName || '—'));
|
|
238
261
|
logger.log(headerKeyValue('Type:', row.dataType || '—'));
|
|
262
|
+
logger.log(headerKeyValue('Value type:', row.valueType || '—'));
|
|
239
263
|
logger.log(headerKeyValue('Required:', String(row.isRequired)));
|
|
240
264
|
if (row.description) {
|
|
241
265
|
logger.log(headerKeyValue('Description:', row.description));
|
|
@@ -268,22 +292,25 @@ function setupDimensionListCommand(dim) {
|
|
|
268
292
|
const KEY_WIDTH = 26;
|
|
269
293
|
const DISPLAY_WIDTH = 34;
|
|
270
294
|
const TYPE_WIDTH = 10;
|
|
295
|
+
const VTYPE_WIDTH = 8;
|
|
271
296
|
const REQ_WIDTH = 10;
|
|
272
|
-
const SEP_LEN = KEY_WIDTH + DISPLAY_WIDTH + TYPE_WIDTH + REQ_WIDTH;
|
|
297
|
+
const SEP_LEN = KEY_WIDTH + DISPLAY_WIDTH + TYPE_WIDTH + VTYPE_WIDTH + REQ_WIDTH;
|
|
273
298
|
|
|
274
299
|
const keyCol = 'Key'.padEnd(KEY_WIDTH);
|
|
275
300
|
const displayCol = 'Display'.padEnd(DISPLAY_WIDTH);
|
|
276
301
|
const typeCol = 'Type'.padEnd(TYPE_WIDTH);
|
|
302
|
+
const vtypeCol = 'VType'.padEnd(VTYPE_WIDTH);
|
|
277
303
|
const reqCol = 'Required'.padEnd(REQ_WIDTH);
|
|
278
|
-
logger.log(chalk.gray(`${keyCol}${displayCol}${typeCol}${reqCol}`));
|
|
304
|
+
logger.log(chalk.gray(`${keyCol}${displayCol}${typeCol}${vtypeCol}${reqCol}`));
|
|
279
305
|
logger.log(chalk.gray('-'.repeat(SEP_LEN)));
|
|
280
306
|
|
|
281
307
|
items.forEach((d) => {
|
|
282
308
|
const key = (d?.key ?? '—').toString().padEnd(KEY_WIDTH);
|
|
283
309
|
const displayName = (d?.displayName ?? '—').toString().padEnd(DISPLAY_WIDTH);
|
|
284
310
|
const dataType = (d?.dataType ?? '—').toString().padEnd(TYPE_WIDTH);
|
|
311
|
+
const valueType = (d?.valueType ?? '—').toString().padEnd(VTYPE_WIDTH);
|
|
285
312
|
const required = (d?.isRequired ?? '—').toString().padEnd(REQ_WIDTH);
|
|
286
|
-
logger.log(`${key}${displayName}${dataType}${required}`);
|
|
313
|
+
logger.log(`${key}${displayName}${dataType}${valueType}${required}`);
|
|
287
314
|
});
|
|
288
315
|
logger.log('');
|
|
289
316
|
}
|
|
@@ -318,10 +345,14 @@ function setupDimensionListCommand(dim) {
|
|
|
318
345
|
* @param {import('commander').Command} program
|
|
319
346
|
*/
|
|
320
347
|
function setupDimensionCommands(program) {
|
|
321
|
-
const dim = program
|
|
348
|
+
const dim = program
|
|
349
|
+
.command('dimension')
|
|
350
|
+
.description('Manage the Controller Dimension Catalog')
|
|
351
|
+
.addHelpText('after', DIMENSION_HELP_AFTER);
|
|
322
352
|
setupDimensionCreateCommand(dim);
|
|
323
353
|
setupDimensionGetCommand(dim);
|
|
324
354
|
setupDimensionListCommand(dim);
|
|
355
|
+
setupDimensionValueCommands(dim);
|
|
325
356
|
}
|
|
326
357
|
|
|
327
358
|
module.exports = {
|