@aifabrix/builder 2.45.5 → 2.47.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/project-rules.mdc +1 -0
- package/.npmrc.token +1 -0
- package/.temp/jest-protection-convert/run-IFN2nv/.protection/hubspot-companies.json +1 -0
- package/.temp/jest-protection-convert/run-IvmKLO/.protection/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-convert/run-SdvblF/.protection/hubspot-companies.json +1 -0
- package/.temp/jest-protection-convert/run-b51TsW/.protection/hubspot-companies.json +1 -0
- package/.temp/jest-protection-convert/run-fiLmb1/.protection/hubspot-companies.json +1 -0
- package/.temp/jest-protection-convert/run-qYGHMU/.protection/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-Mq5re8/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-f3u4YL/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-iQtd1O/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-mdmz5M/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-qbKYxQ/hubspot-companies.yaml +17 -0
- package/.temp/jest-protection-fixtures/hubspot-yzlJy6/hubspot-companies.yaml +17 -0
- package/.temp/validation/summary.txt +5 -0
- package/README.md +43 -17
- package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +1 -1
- package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.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 +146 -0
- package/jest.projects.js +65 -136
- package/lib/api/api-response-errors.js +124 -0
- package/lib/api/dataplane-health.api.js +19 -7
- package/lib/api/governance-scenario-pack.api.js +159 -0
- package/lib/api/index.js +43 -3
- package/lib/api/lifecycle.api.js +98 -0
- package/lib/api/pipeline.api.js +3 -1
- package/lib/api/records-bulk.api.js +14 -1
- package/lib/api/resource-types.api.js +107 -0
- package/lib/api/runtime-configuration.api.js +72 -0
- package/lib/api/types/resource-types.types.js +45 -0
- package/lib/api/user-groups.api.js +9 -9
- package/lib/api/users.api.js +8 -8
- package/lib/api/validation-runner.js +3 -1
- package/lib/api/wizard.api.js +10 -2
- package/lib/app/deploy-config.js +4 -1
- package/lib/app/down.js +78 -27
- package/lib/app/index.js +2 -2
- 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/app/run-resolve-image.js +2 -1
- package/lib/app/run-stop-containers.js +113 -0
- package/lib/app/run.js +1 -31
- package/lib/app/show-display.js +35 -0
- package/lib/app/show.js +32 -1
- package/lib/build/index.js +22 -5
- package/lib/build/miso-controller-npm-sdk-guard.js +25 -0
- package/lib/certification/sync-system-certification.js +13 -6
- package/lib/channels/add-channel.js +348 -0
- package/lib/channels/channel-artifact-generator.js +141 -0
- package/lib/channels/channel-audit.js +101 -0
- package/lib/channels/channel-auth-context.js +37 -0
- package/lib/channels/channel-credential.js +200 -0
- package/lib/channels/channel-display-name.js +64 -0
- package/lib/channels/channel-external-system.js +106 -0
- package/lib/channels/channel-integration-generator.js +274 -0
- package/lib/channels/channel-probe.js +89 -0
- package/lib/channels/channel-runtime-resolver.js +152 -0
- package/lib/channels/channel-status-display.js +141 -0
- package/lib/channels/channel-targets.js +115 -0
- package/lib/cli/index.js +20 -4
- package/lib/cli/infra-guided-auth.js +109 -0
- package/lib/cli/infra-guided.js +84 -81
- package/lib/cli/setup-app.help.js +0 -31
- package/lib/cli/setup-app.js +82 -5
- package/lib/cli/setup-app.test-commands.js +5 -57
- package/lib/cli/setup-auth.js +25 -0
- 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 +25 -3
- package/lib/cli/setup-infra-up-dataplane-action.js +2 -2
- package/lib/cli/setup-infra-up-platform-action.js +2 -1
- 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 +25 -2
- package/lib/cli/setup-utility-repair.js +198 -0
- package/lib/cli/setup-utility-resolve.js +44 -5
- package/lib/cli/setup-utility-validate.js +197 -0
- package/lib/cli/setup-utility.js +4 -239
- package/lib/commands/app-logs.js +54 -26
- package/lib/commands/app.js +41 -0
- package/lib/commands/auth-status-client-tokens.js +214 -0
- package/lib/commands/auth-status-dataplane-version.js +142 -68
- package/lib/commands/auth-status.js +43 -54
- package/lib/commands/channel.js +58 -0
- package/lib/commands/datasource-test-trust-cli.js +27 -23
- package/lib/commands/datasource-unified-test-cli.js +6 -3
- package/lib/commands/datasource-unified-test-cli.options.js +5 -1
- package/lib/commands/datasource.js +8 -8
- package/lib/commands/dev-show-display.js +8 -1
- 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 +49 -8
- package/lib/commands/identity-group-cli.js +66 -26
- package/lib/commands/identity-membership-role-cache.js +58 -37
- package/lib/commands/identity-shared.js +22 -1
- package/lib/commands/identity-user-cli.js +80 -34
- package/lib/commands/lifecycle-command-action.js +123 -0
- package/lib/commands/lifecycle-external.js +268 -0
- package/lib/commands/login.js +11 -2
- package/lib/commands/repair-auth-apply.js +153 -0
- package/lib/commands/repair-auth-config.js +8 -13
- package/lib/commands/repair-changed-files.js +41 -0
- package/lib/commands/repair-datasource-com-v2.js +15 -0
- package/lib/commands/repair-datasource-keys.js +4 -1
- package/lib/commands/repair-datasource-run.js +59 -0
- package/lib/commands/repair-datasource-service-contract.js +206 -0
- package/lib/commands/repair-datasource-test-payload.js +259 -0
- package/lib/commands/repair-datasource.js +49 -64
- package/lib/commands/repair-env-template.js +76 -25
- package/lib/commands/repair-external-run.js +216 -0
- package/lib/commands/repair-openapi-sync.js +49 -4
- package/lib/commands/repair-persist.js +4 -0
- package/lib/commands/repair-rbac.js +52 -1
- package/lib/commands/repair-steps.js +160 -0
- package/lib/commands/repair-system-alignment.js +7 -4
- package/lib/commands/repair.js +29 -296
- package/lib/commands/resource-type.js +371 -0
- 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 +70 -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 +24 -8
- package/lib/commands/test-governance-external.js +3 -24
- package/lib/commands/test-trust-external.js +48 -100
- package/lib/commands/up-common.js +57 -13
- package/lib/commands/up-dataplane.js +56 -15
- package/lib/commands/upload-publish-context.js +75 -0
- package/lib/commands/upload-sidecar-followups.js +89 -0
- package/lib/commands/upload.js +113 -110
- 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 +73 -0
- package/lib/commands/verify-trust-external.js +59 -0
- package/lib/commands/wizard-config-normalizer.js +43 -23
- package/lib/commands/wizard-core.js +2 -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-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 +90 -0
- package/lib/datasource/agent-trust-debug-log.js +1 -1
- package/lib/datasource/agent-trust-run.js +5 -3
- package/lib/datasource/audit-evidence-extract-debug.js +30 -18
- package/lib/datasource/audit-evidence-extract.js +7 -4
- package/lib/datasource/audit-evidence-verify-matrix.js +54 -26
- package/lib/datasource/bulk-loader-run-batches.js +15 -3
- package/lib/datasource/capability/capability-diff-slice.js +2 -2
- package/lib/datasource/capability/capability-manifest.js +254 -0
- package/lib/datasource/capability/capability-resolve.js +3 -4
- package/lib/datasource/capability/copy-operations.js +5 -3
- package/lib/datasource/capability/remove-operations.js +2 -1
- package/lib/datasource/capability/run-capability-copy.js +32 -4
- package/lib/datasource/capability/run-capability-diff.js +3 -3
- package/lib/datasource/capability/run-capability-dimension.js +2 -4
- package/lib/datasource/capability/run-capability-edit.js +4 -7
- package/lib/datasource/capability/run-capability-relate.js +2 -4
- package/lib/datasource/capability/run-capability-remove.js +2 -4
- package/lib/datasource/capability/validate-capability-slice.js +2 -1
- package/lib/datasource/datasource-identifier.js +2 -1
- package/lib/datasource/datasource-load-export-context.js +3 -0
- package/lib/datasource/datasource-validate-display.js +1 -1
- package/lib/datasource/field-reference-validator.js +24 -3
- package/lib/datasource/log-cleaner.js +2 -2
- package/lib/datasource/log-viewer.js +8 -8
- package/lib/datasource/orphan-profiles-validator.js +98 -0
- package/lib/datasource/test-e2e.js +4 -1
- package/lib/datasource/unified-validation-run-body.js +3 -1
- package/lib/datasource/unified-validation-run.js +5 -2
- package/lib/datasource/validate.js +41 -23
- package/lib/deployment/environment-poll-status.js +138 -0
- package/lib/deployment/environment.js +42 -34
- package/lib/external-system/download-helpers.js +87 -0
- package/lib/external-system/download.js +78 -138
- package/lib/external-system/generator.js +1 -55
- package/lib/external-system/integration-auth-context.js +45 -0
- package/lib/external-system/test-auth.js +12 -5
- package/lib/external-system/test.js +16 -21
- package/lib/generator/builders.js +11 -1
- package/lib/generator/external-controller-manifest.js +18 -0
- package/lib/generator/split.js +3 -1
- package/lib/generator/wizard.js +1 -28
- package/lib/governance/governance-cli-errors.js +96 -0
- package/lib/governance/governance-download-display.js +38 -0
- package/lib/governance/governance-run-display.js +215 -25
- package/lib/identity/fk-reference.js +65 -0
- package/lib/identity/identity-apply-core.js +13 -58
- package/lib/identity/identity-apply-phases.js +5 -1
- package/lib/identity/identity-display.js +243 -0
- package/lib/identity/identity-response-helpers.js +52 -0
- package/lib/identity/identity-sync-errors.js +62 -0
- package/lib/identity/resolve-user-id.js +129 -0
- package/lib/identity/username-default.js +31 -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/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-trust.js +70 -0
- package/lib/lifecycle/report-display.js +472 -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 +10 -4
- package/lib/resolvers/datasource-resolver.js +2 -3
- package/lib/resolvers/resource-type-file.js +159 -0
- package/lib/schema/application-schema.json +17 -1
- package/lib/schema/datasource-test-run.schema.json +89 -6
- package/lib/schema/deployment-rules.yaml +2 -1
- package/lib/schema/external-datasource.schema.json +2947 -2619
- package/lib/schema/external-system.schema.json +1418 -761
- package/lib/schema/infra.parameter.yaml +45 -0
- package/lib/schema/type/credential-field-registry.json +103 -97
- package/lib/schema/type/document-storage.json +9 -5
- 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/app-run-containers.js +25 -2
- package/lib/utils/authentication-shape.js +224 -0
- package/lib/utils/build-copy.js +36 -5
- package/lib/utils/build-resolve-image.js +66 -12
- package/lib/utils/celery-companion-apps.js +53 -0
- package/lib/utils/cli-secrets-error-format.js +83 -21
- package/lib/utils/cli-utils.js +20 -4
- package/lib/utils/compose-celery-worker.js +23 -0
- package/lib/utils/compose-generate-docker-compose.js +13 -1
- package/lib/utils/compose-traefik-ingress-base.js +16 -1
- package/lib/utils/config-secrets-path.js +46 -0
- package/lib/utils/configuration-env-resolver.js +36 -0
- package/lib/utils/controller-url.js +88 -1
- package/lib/utils/credential-secrets-env-kv.js +216 -0
- package/lib/utils/credential-secrets-env.js +175 -257
- package/lib/utils/dataplane-resolver.js +18 -2
- package/lib/utils/declarative-url-ports.js +27 -4
- package/lib/utils/deployment-auth-mode.js +41 -0
- package/lib/utils/developer-volume-id.js +33 -0
- package/lib/utils/docker-build.js +1 -4
- 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 +11 -3
- package/lib/utils/external-system-readiness-core.js +10 -0
- package/lib/utils/external-system-readiness-display.js +80 -23
- package/lib/utils/external-system-validators.js +8 -2
- package/lib/utils/health-check.js +4 -1
- package/lib/utils/help-builder.js +13 -8
- 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 +2 -0
- package/lib/utils/paths.js +25 -0
- package/lib/utils/pipeline-upload-auth-retry.js +82 -0
- package/lib/utils/platform-controller-url.js +157 -0
- package/lib/utils/platform-kv-ref.js +57 -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/runtime-configuration-download.js +189 -0
- package/lib/utils/runtime-configuration-values.js +119 -0
- package/lib/utils/schema-loader.js +19 -4
- package/lib/utils/secrets-generator.js +31 -25
- package/lib/utils/secrets-missing-error.js +164 -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 +12 -5
- 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 +8 -0
- package/lib/utils/validation-run-stage.js +45 -0
- package/lib/utils/worker-sidecars.js +142 -0
- package/lib/validation/external-manifest-validator.js +2 -0
- package/lib/validation/runtime-configuration-rules.js +98 -0
- package/lib/validation/validate-display-dimensions.js +154 -0
- package/lib/validation/validate-display-sections.js +276 -0
- package/lib/validation/validate-display-steps.js +67 -0
- package/lib/validation/validate-display.js +24 -402
- package/package.json +1 -1
- package/templates/applications/dataplane/application.yaml +7 -1
- package/templates/applications/dataplane/env.template +50 -14
- package/templates/applications/dataplane/rbac.yaml +108 -1
- package/templates/applications/miso-controller/application.yaml +2 -2
- package/templates/applications/miso-controller/env.template +53 -122
- package/templates/applications/miso-controller/rbac.yaml +28 -13
- package/templates/channels/chatgpt/install.template.md.hbs +49 -0
- package/templates/channels/chatgpt/manifest.template.json.hbs +9 -0
- package/templates/channels/microsoft-copilot/install.template.md.hbs +49 -0
- package/templates/channels/microsoft-copilot/manifest.template.json.hbs +8 -0
- package/templates/channels/slack/install.template.md.hbs +49 -0
- package/templates/channels/slack/manifest.template.json.hbs +66 -0
- package/templates/channels/teams-bot/install.template.md.hbs +49 -0
- package/templates/channels/teams-bot/manifest.template.json.hbs +13 -0
- package/templates/channels/web-embed/install.template.md.hbs +49 -0
- package/templates/channels/web-embed/manifest.template.json.hbs +8 -0
- package/templates/external-system/README.md.hbs +74 -17
- package/templates/python/docker-compose.hbs +75 -18
- package/templates/typescript/docker-compose.hbs +70 -17
- package/lib/commands/test-governance-command-action.js +0 -55
- package/lib/commands/test-trust-command-action.js +0 -118
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `aifabrix validate` and `diff` command wiring (split from setup-utility for size limits).
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Validate and diff CLI commands
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const chalk = require('chalk');
|
|
13
|
+
const logger = require('../utils/logger');
|
|
14
|
+
const { handleCommandError } = require('../utils/cli-utils');
|
|
15
|
+
const { VALIDATE_HELP_AFTER } = require('./setup-utility-help-after');
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param {string} appOrFile
|
|
19
|
+
* @param {object} result
|
|
20
|
+
* @param {string} outFormat
|
|
21
|
+
*/
|
|
22
|
+
function emitManifestAfterValidateIfApplicable(appOrFile, result, outFormat) {
|
|
23
|
+
if (outFormat === 'json' || !result?.appPath || !appOrFile || typeof appOrFile !== 'string') {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
if (fs.existsSync(appOrFile) && fs.statSync(appOrFile).isFile()) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const { emitManifestMetadataLineIfTTY } = require('../utils/manifest-source-emit');
|
|
31
|
+
emitManifestMetadataLineIfTTY(logger, {
|
|
32
|
+
appKey: appOrFile,
|
|
33
|
+
appPath: result.appPath,
|
|
34
|
+
envOnly: false,
|
|
35
|
+
json: false
|
|
36
|
+
});
|
|
37
|
+
} catch {
|
|
38
|
+
/* ignore emit failures */
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @param {object} validate
|
|
44
|
+
* @param {object} opts
|
|
45
|
+
* @returns {Promise<boolean>}
|
|
46
|
+
*/
|
|
47
|
+
async function runValidateBatchBranch(validate, opts) {
|
|
48
|
+
const integration = opts.integration === true;
|
|
49
|
+
const builder = opts.builder === true;
|
|
50
|
+
if (!integration && !builder) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
const outFormat = (opts.format || 'default').toLowerCase();
|
|
54
|
+
const batchResult = integration && builder
|
|
55
|
+
? await validate.validateAll(opts)
|
|
56
|
+
: integration
|
|
57
|
+
? await validate.validateAllIntegrations(opts)
|
|
58
|
+
: await validate.validateAllBuilderApps(opts);
|
|
59
|
+
if (outFormat === 'json') {
|
|
60
|
+
logger.log(JSON.stringify(batchResult, null, 2));
|
|
61
|
+
} else {
|
|
62
|
+
validate.displayBatchValidationResults(batchResult);
|
|
63
|
+
}
|
|
64
|
+
if (!batchResult.valid) process.exit(1);
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* @param {string} appOrFile
|
|
70
|
+
* @param {object} opts
|
|
71
|
+
* @returns {Promise<void>}
|
|
72
|
+
*/
|
|
73
|
+
async function runProtectionValidateBranch(appOrFile, opts) {
|
|
74
|
+
const { validateProtectionBatchCommand } = require('../protection/validate-batch');
|
|
75
|
+
const code = await validateProtectionBatchCommand(
|
|
76
|
+
{
|
|
77
|
+
env: opts.env,
|
|
78
|
+
json: (opts.format || '').toLowerCase() === 'json',
|
|
79
|
+
warningsAsErrors: opts.warningsAsErrors === true,
|
|
80
|
+
simulate: opts.simulate === true,
|
|
81
|
+
verbose: opts.verbose === true
|
|
82
|
+
},
|
|
83
|
+
logger
|
|
84
|
+
);
|
|
85
|
+
if (code !== 0) {
|
|
86
|
+
process.exit(code);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @param {object} result
|
|
92
|
+
* @param {string} appOrFile
|
|
93
|
+
* @returns {object}
|
|
94
|
+
*/
|
|
95
|
+
function buildValidateJsonPayload(result, appOrFile) {
|
|
96
|
+
let payload = result;
|
|
97
|
+
try {
|
|
98
|
+
if (result?.appPath && appOrFile && typeof appOrFile === 'string') {
|
|
99
|
+
if (!(fs.existsSync(appOrFile) && fs.statSync(appOrFile).isFile())) {
|
|
100
|
+
const { getManifestSourcePayload } = require('../utils/manifest-source-emit');
|
|
101
|
+
payload = { ...result, manifestSource: getManifestSourcePayload(appOrFile, result.appPath) };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
} catch {
|
|
105
|
+
/* keep plain result */
|
|
106
|
+
}
|
|
107
|
+
return payload;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @param {string} appOrFile
|
|
112
|
+
* @param {object} result
|
|
113
|
+
* @param {string} outFormat
|
|
114
|
+
* @param {object} validate
|
|
115
|
+
*/
|
|
116
|
+
function displaySingleValidateResult(appOrFile, result, outFormat, validate) {
|
|
117
|
+
emitManifestAfterValidateIfApplicable(appOrFile, result, outFormat);
|
|
118
|
+
if (outFormat === 'json') {
|
|
119
|
+
logger.log(JSON.stringify(buildValidateJsonPayload(result, appOrFile), null, 2));
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
validate.displayValidationResults(result);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* @param {string} appOrFile
|
|
127
|
+
* @param {object} options
|
|
128
|
+
* @returns {Promise<void>}
|
|
129
|
+
*/
|
|
130
|
+
async function runValidateCommand(appOrFile, options) {
|
|
131
|
+
const validate = require('../validation/validate');
|
|
132
|
+
const opts = options.opts ? options.opts() : options;
|
|
133
|
+
const { isProtectionScope } = require('../protection/scope');
|
|
134
|
+
if (isProtectionScope(appOrFile)) {
|
|
135
|
+
await runProtectionValidateBranch(appOrFile, opts);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (await runValidateBatchBranch(validate, opts)) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const outFormat = (opts.format || 'default').toLowerCase();
|
|
142
|
+
if (!appOrFile || typeof appOrFile !== 'string') {
|
|
143
|
+
logger.log(chalk.red('App name or file path is required, or use --integration / --builder'));
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
const result = await validate.validateAppOrFile(appOrFile, {
|
|
147
|
+
...opts,
|
|
148
|
+
certSync: opts.certSync === true
|
|
149
|
+
});
|
|
150
|
+
displaySingleValidateResult(appOrFile, result, outFormat, validate);
|
|
151
|
+
if (!result.valid) process.exit(1);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @param {import('commander').Command} program
|
|
156
|
+
*/
|
|
157
|
+
function setupValidateDiffCommands(program) {
|
|
158
|
+
program.command('validate [appKey|systemKey|file]')
|
|
159
|
+
.description('Validate appKey, systemKey, file path, .protection batch, or all under integration/ and builder/')
|
|
160
|
+
.addHelpText('after', VALIDATE_HELP_AFTER)
|
|
161
|
+
.option('--format <format>', 'Output format: json | default (human-readable)')
|
|
162
|
+
.option('--integration', 'Validate all applications under integration/')
|
|
163
|
+
.option('--builder', 'Validate all applications under builder/')
|
|
164
|
+
.option('--warnings-as-errors', 'For .protection: pass strict=true to dataplane validate')
|
|
165
|
+
.option('--simulate', 'For .protection: run simulate after validate')
|
|
166
|
+
.option(
|
|
167
|
+
'--cert-sync',
|
|
168
|
+
'After successful validation of an external integration, refresh the system file certification block from the dataplane (requires login)'
|
|
169
|
+
)
|
|
170
|
+
.action((appOrFile, options) => {
|
|
171
|
+
runValidateCommand(appOrFile, options).catch((error) => {
|
|
172
|
+
handleCommandError(error, 'validate');
|
|
173
|
+
process.exit(1);
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
program.command('diff <file1> <file2>')
|
|
178
|
+
.description('Diff two config files (optional schema validate)')
|
|
179
|
+
.option('--no-validate', 'Skip schema validation (type check still applied)')
|
|
180
|
+
.action(async(file1, file2, cmd) => {
|
|
181
|
+
try {
|
|
182
|
+
const diff = require('../core/diff');
|
|
183
|
+
const opts = cmd.opts();
|
|
184
|
+
const result = await diff.compareFiles(file1, file2, { validate: opts.validate !== false });
|
|
185
|
+
diff.formatDiffOutput(result);
|
|
186
|
+
if (!result.identical) process.exit(1);
|
|
187
|
+
} catch (error) {
|
|
188
|
+
handleCommandError(error, 'diff');
|
|
189
|
+
process.exit(1);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
module.exports = {
|
|
195
|
+
setupValidateDiffCommands,
|
|
196
|
+
runValidateCommand
|
|
197
|
+
};
|
package/lib/cli/setup-utility.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const { formatSuccessParagraph } = require('../utils/cli-test-layout-chalk');
|
|
2
1
|
/**
|
|
3
2
|
* CLI utility command setup (resolve, json, split-json, show, validate, diff).
|
|
4
3
|
*
|
|
@@ -10,12 +9,15 @@ const { formatSuccessParagraph } = require('../utils/cli-test-layout-chalk');
|
|
|
10
9
|
const path = require('path');
|
|
11
10
|
const fs = require('fs');
|
|
12
11
|
const chalk = require('chalk');
|
|
12
|
+
const { formatSuccessParagraph } = require('../utils/cli-test-layout-chalk');
|
|
13
13
|
const generator = require('../generator');
|
|
14
14
|
const logger = require('../utils/logger');
|
|
15
15
|
const { handleCommandError, logOfflinePathWhenType } = require('../utils/cli-utils');
|
|
16
16
|
const { detectAppType, getDeployJsonPath, getResolveAppPath } = require('../utils/paths');
|
|
17
17
|
const { setupResolveCommand } = require('./setup-utility-resolve');
|
|
18
|
-
const {
|
|
18
|
+
const { setupRepairCommand } = require('./setup-utility-repair');
|
|
19
|
+
const { setupValidateDiffCommands } = require('./setup-utility-validate');
|
|
20
|
+
const { JSON_HELP_AFTER } = require('./setup-utility-help-after');
|
|
19
21
|
|
|
20
22
|
/**
|
|
21
23
|
* Resolve app path and type for split-json (integration first, then builder).
|
|
@@ -136,100 +138,6 @@ function setupSplitJsonCommand(program) {
|
|
|
136
138
|
});
|
|
137
139
|
}
|
|
138
140
|
|
|
139
|
-
function buildRepairExternalIntegrationOptions(appName, options, format) {
|
|
140
|
-
const all = options.all === true;
|
|
141
|
-
return {
|
|
142
|
-
auth: options.auth,
|
|
143
|
-
doc: options.doc || all,
|
|
144
|
-
dryRun: options.dryRun,
|
|
145
|
-
format,
|
|
146
|
-
rbac: options.rbac || all,
|
|
147
|
-
expose: options.expose || all,
|
|
148
|
-
sync: options.sync || all,
|
|
149
|
-
api: options.api || all,
|
|
150
|
-
test: options.test || all,
|
|
151
|
-
backup: options.backup,
|
|
152
|
-
noBackup: options.noBackup
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
function logRepairResult(options, result) {
|
|
157
|
-
if (options.dryRun && result.updated && result.changes.length > 0) {
|
|
158
|
-
logger.log(chalk.yellow('\nWould apply:'));
|
|
159
|
-
result.changes.forEach(c => logger.log(chalk.gray(` ${c}`)));
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
if (Array.isArray(result.backupPaths) && result.backupPaths.length > 0) {
|
|
163
|
-
result.backupPaths.forEach((p) => logger.log(chalk.gray(`Backup: ${p}`)));
|
|
164
|
-
}
|
|
165
|
-
if (result.updated) {
|
|
166
|
-
logger.log(formatSuccessParagraph('Repaired external integration config.'));
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
if (Array.isArray(result.changes) && result.changes.length > 0) {
|
|
170
|
-
logger.log(formatSuccessParagraph('Repair actions completed.'));
|
|
171
|
-
result.changes.forEach(c => logger.log(chalk.gray(` ${c}`)));
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
if (result.readmeRegenerated) {
|
|
175
|
-
logger.log(formatSuccessParagraph('Regenerated README.md from deployment manifest.'));
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
logger.log(chalk.gray('No changes needed; config already matches files on disk.'));
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Handler for `aifabrix repair <systemKey>`.
|
|
183
|
-
* @param {string} appName
|
|
184
|
-
* @param {object} options - Commander options
|
|
185
|
-
* @returns {Promise<void>}
|
|
186
|
-
*/
|
|
187
|
-
async function handleRepairCommand(appName, options) {
|
|
188
|
-
const { repairExternalIntegration } = require('../commands/repair');
|
|
189
|
-
const { detectAppType } = require('../utils/paths');
|
|
190
|
-
const { appPath } = await detectAppType(appName);
|
|
191
|
-
logOfflinePathWhenType(appPath);
|
|
192
|
-
let format = 'yaml';
|
|
193
|
-
try {
|
|
194
|
-
const config = require('../core/config');
|
|
195
|
-
format = (await config.getFormat()) || format;
|
|
196
|
-
} catch (_) {
|
|
197
|
-
/* default yaml when config unavailable */
|
|
198
|
-
}
|
|
199
|
-
const result = await repairExternalIntegration(
|
|
200
|
-
appName,
|
|
201
|
-
buildRepairExternalIntegrationOptions(appName, options, format)
|
|
202
|
-
);
|
|
203
|
-
logRepairResult(options, result);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
function setupRepairCommand(program) {
|
|
207
|
-
program.command('repair <systemKey>')
|
|
208
|
-
.description('Fix external integration drift (files, RBAC, manifest, …)')
|
|
209
|
-
.option('--all', 'Run all repair actions (api, doc, expose, rbac, sync, test)')
|
|
210
|
-
.option(
|
|
211
|
-
'--api',
|
|
212
|
-
'Validate and sync API contracts needed for OpenAPI/MCP (uses local OpenAPI specs at integration/<systemKey>/openapi/*.json when present)'
|
|
213
|
-
)
|
|
214
|
-
.option('--auth <method>', 'Set authentication method (oauth2, aad, apikey, basic, queryParam, oidc, hmac, none); updates system file and env.template')
|
|
215
|
-
.option('--doc', 'Regenerate README.md from deployment manifest')
|
|
216
|
-
.option('--expose', 'Set exposed.schema on each datasource from all fieldMappings.attributes keys (metadata.<key>); removes deprecated exposed.attributes if present')
|
|
217
|
-
.option('--rbac', 'Ensure RBAC permissions per datasource and add default Admin/Reader roles if none exist')
|
|
218
|
-
.option('--sync', 'Add default sync section to datasources that lack it')
|
|
219
|
-
.option('--test', 'Generate testPayload.payloadTemplate and testPayload.expectedResult from attributes')
|
|
220
|
-
.option('--no-backup', 'Skip timestamped copies under integration/<systemKey>/backup/')
|
|
221
|
-
.option('--dry-run', 'Report changes only; do not write')
|
|
222
|
-
.addHelpText('after', REPAIR_HELP_AFTER)
|
|
223
|
-
.action(async(appName, options) => {
|
|
224
|
-
try {
|
|
225
|
-
await handleRepairCommand(appName, options);
|
|
226
|
-
} catch (error) {
|
|
227
|
-
handleCommandError(error, 'repair');
|
|
228
|
-
process.exit(1);
|
|
229
|
-
}
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
|
|
233
141
|
async function resolveConvertTargetFormat(options) {
|
|
234
142
|
const config = require('../core/config');
|
|
235
143
|
const effectiveFormat = options.format || (await config.getFormat());
|
|
@@ -316,149 +224,6 @@ function setupSplitJsonConvertShowCommands(program) {
|
|
|
316
224
|
setupShowCommand(program);
|
|
317
225
|
}
|
|
318
226
|
|
|
319
|
-
function emitManifestAfterValidateIfApplicable(appOrFile, result, outFormat) {
|
|
320
|
-
if (outFormat === 'json' || !result?.appPath || !appOrFile || typeof appOrFile !== 'string') {
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
try {
|
|
324
|
-
if (fs.existsSync(appOrFile) && fs.statSync(appOrFile).isFile()) {
|
|
325
|
-
return;
|
|
326
|
-
}
|
|
327
|
-
const { emitManifestMetadataLineIfTTY } = require('../utils/manifest-source-emit');
|
|
328
|
-
emitManifestMetadataLineIfTTY(logger, {
|
|
329
|
-
appKey: appOrFile,
|
|
330
|
-
appPath: result.appPath,
|
|
331
|
-
envOnly: false,
|
|
332
|
-
json: false
|
|
333
|
-
});
|
|
334
|
-
} catch {
|
|
335
|
-
/* ignore emit failures */
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
async function runValidateBatchBranch(validate, opts) {
|
|
340
|
-
const integration = opts.integration === true;
|
|
341
|
-
const builder = opts.builder === true;
|
|
342
|
-
if (!integration && !builder) {
|
|
343
|
-
return false;
|
|
344
|
-
}
|
|
345
|
-
const outFormat = (opts.format || 'default').toLowerCase();
|
|
346
|
-
const batchResult = integration && builder
|
|
347
|
-
? await validate.validateAll(opts)
|
|
348
|
-
: integration
|
|
349
|
-
? await validate.validateAllIntegrations(opts)
|
|
350
|
-
: await validate.validateAllBuilderApps(opts);
|
|
351
|
-
if (outFormat === 'json') {
|
|
352
|
-
logger.log(JSON.stringify(batchResult, null, 2));
|
|
353
|
-
} else {
|
|
354
|
-
validate.displayBatchValidationResults(batchResult);
|
|
355
|
-
}
|
|
356
|
-
if (!batchResult.valid) process.exit(1);
|
|
357
|
-
return true;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
async function runProtectionValidateBranch(appOrFile, opts) {
|
|
361
|
-
const { validateProtectionBatchCommand } = require('../protection/validate-batch');
|
|
362
|
-
const code = await validateProtectionBatchCommand(
|
|
363
|
-
{
|
|
364
|
-
env: opts.env,
|
|
365
|
-
json: (opts.format || '').toLowerCase() === 'json',
|
|
366
|
-
warningsAsErrors: opts.warningsAsErrors === true,
|
|
367
|
-
simulate: opts.simulate === true,
|
|
368
|
-
verbose: opts.verbose === true
|
|
369
|
-
},
|
|
370
|
-
logger
|
|
371
|
-
);
|
|
372
|
-
if (code !== 0) {
|
|
373
|
-
process.exit(code);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
function buildValidateJsonPayload(result, appOrFile) {
|
|
378
|
-
let payload = result;
|
|
379
|
-
try {
|
|
380
|
-
if (result?.appPath && appOrFile && typeof appOrFile === 'string') {
|
|
381
|
-
if (!(fs.existsSync(appOrFile) && fs.statSync(appOrFile).isFile())) {
|
|
382
|
-
const { getManifestSourcePayload } = require('../utils/manifest-source-emit');
|
|
383
|
-
payload = { ...result, manifestSource: getManifestSourcePayload(appOrFile, result.appPath) };
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
} catch {
|
|
387
|
-
/* keep plain result */
|
|
388
|
-
}
|
|
389
|
-
return payload;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
function displaySingleValidateResult(appOrFile, result, outFormat, validate) {
|
|
393
|
-
emitManifestAfterValidateIfApplicable(appOrFile, result, outFormat);
|
|
394
|
-
if (outFormat === 'json') {
|
|
395
|
-
logger.log(JSON.stringify(buildValidateJsonPayload(result, appOrFile), null, 2));
|
|
396
|
-
return;
|
|
397
|
-
}
|
|
398
|
-
validate.displayValidationResults(result);
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
async function runValidateCommand(appOrFile, options) {
|
|
402
|
-
const validate = require('../validation/validate');
|
|
403
|
-
const opts = options.opts ? options.opts() : options;
|
|
404
|
-
const { isProtectionScope } = require('../protection/scope');
|
|
405
|
-
if (isProtectionScope(appOrFile)) {
|
|
406
|
-
await runProtectionValidateBranch(appOrFile, opts);
|
|
407
|
-
return;
|
|
408
|
-
}
|
|
409
|
-
if (await runValidateBatchBranch(validate, opts)) {
|
|
410
|
-
return;
|
|
411
|
-
}
|
|
412
|
-
const outFormat = (opts.format || 'default').toLowerCase();
|
|
413
|
-
if (!appOrFile || typeof appOrFile !== 'string') {
|
|
414
|
-
logger.log(chalk.red('App name or file path is required, or use --integration / --builder'));
|
|
415
|
-
process.exit(1);
|
|
416
|
-
}
|
|
417
|
-
const result = await validate.validateAppOrFile(appOrFile, {
|
|
418
|
-
...opts,
|
|
419
|
-
certSync: opts.certSync === true
|
|
420
|
-
});
|
|
421
|
-
displaySingleValidateResult(appOrFile, result, outFormat, validate);
|
|
422
|
-
if (!result.valid) process.exit(1);
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
function setupValidateDiffCommands(program) {
|
|
426
|
-
program.command('validate [appKey|systemKey|file]')
|
|
427
|
-
.description('Validate appKey, systemKey, file path, .protection batch, or all under integration/ and builder/')
|
|
428
|
-
.addHelpText('after', VALIDATE_HELP_AFTER)
|
|
429
|
-
.option('--format <format>', 'Output format: json | default (human-readable)')
|
|
430
|
-
.option('--integration', 'Validate all applications under integration/')
|
|
431
|
-
.option('--builder', 'Validate all applications under builder/')
|
|
432
|
-
.option('--warnings-as-errors', 'For .protection: pass strict=true to dataplane validate')
|
|
433
|
-
.option('--simulate', 'For .protection: run simulate after validate')
|
|
434
|
-
.option(
|
|
435
|
-
'--cert-sync',
|
|
436
|
-
'After successful validation of an external integration, refresh the system file certification block from the dataplane (requires login)'
|
|
437
|
-
)
|
|
438
|
-
.action((appOrFile, options) => {
|
|
439
|
-
runValidateCommand(appOrFile, options).catch((error) => {
|
|
440
|
-
handleCommandError(error, 'validate');
|
|
441
|
-
process.exit(1);
|
|
442
|
-
});
|
|
443
|
-
});
|
|
444
|
-
|
|
445
|
-
program.command('diff <file1> <file2>')
|
|
446
|
-
.description('Diff two config files (optional schema validate)')
|
|
447
|
-
.option('--no-validate', 'Skip schema validation (type check still applied)')
|
|
448
|
-
.action(async(file1, file2, cmd) => {
|
|
449
|
-
try {
|
|
450
|
-
const diff = require('../core/diff');
|
|
451
|
-
const opts = cmd.opts();
|
|
452
|
-
const result = await diff.compareFiles(file1, file2, { validate: opts.validate !== false });
|
|
453
|
-
diff.formatDiffOutput(result);
|
|
454
|
-
if (!result.identical) process.exit(1);
|
|
455
|
-
} catch (error) {
|
|
456
|
-
handleCommandError(error, 'diff');
|
|
457
|
-
process.exit(1);
|
|
458
|
-
}
|
|
459
|
-
});
|
|
460
|
-
}
|
|
461
|
-
|
|
462
227
|
/**
|
|
463
228
|
* Sets up utility commands
|
|
464
229
|
* @param {Command} program - Commander program instance
|
package/lib/commands/app-logs.js
CHANGED
|
@@ -13,6 +13,10 @@ const logger = require('../utils/logger');
|
|
|
13
13
|
const config = require('../core/config');
|
|
14
14
|
const containerHelpers = require('../utils/app-run-containers');
|
|
15
15
|
const { validateAppName } = require('../app/push');
|
|
16
|
+
const {
|
|
17
|
+
getCeleryCompanionAppKeys,
|
|
18
|
+
loadBuilderApplicationConfig
|
|
19
|
+
} = require('../utils/celery-companion-apps');
|
|
16
20
|
|
|
17
21
|
const { execWithDockerEnv } = require('../utils/docker-exec');
|
|
18
22
|
const { maskEnvLine } = require('../utils/log-redaction');
|
|
@@ -295,6 +299,36 @@ async function runDockerLogsFollow(containerName, tail, minLevel) {
|
|
|
295
299
|
});
|
|
296
300
|
}
|
|
297
301
|
|
|
302
|
+
function parseLogLevelOption(options) {
|
|
303
|
+
const rawLevel =
|
|
304
|
+
options.level !== undefined && options.level !== null && options.level !== ''
|
|
305
|
+
? String(options.level).trim()
|
|
306
|
+
: undefined;
|
|
307
|
+
const level = rawLevel ? rawLevel.toLowerCase() : undefined;
|
|
308
|
+
if (level !== undefined && level !== null && !LOG_LEVELS.includes(level)) {
|
|
309
|
+
throw new Error(
|
|
310
|
+
`Invalid log level '${rawLevel}'; use one of: ${LOG_LEVELS.join(', ')}`
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
return level;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
async function logFollowStream(companionKeys, containerName, tail, level) {
|
|
317
|
+
await runDockerLogsFollow(containerName, tail, level);
|
|
318
|
+
if (companionKeys.length > 0) {
|
|
319
|
+
const hint = companionKeys.map((key) => `aifabrix logs ${key}`).join(' or ');
|
|
320
|
+
logger.log(chalk.gray(`Tip: sidecar logs — ${hint}`));
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
async function logContainerSnapshot(containerName, tail, level) {
|
|
325
|
+
try {
|
|
326
|
+
await runDockerLogs(containerName, { tail, level });
|
|
327
|
+
} catch (err) {
|
|
328
|
+
logger.log(chalk.yellow(`No logs for ${containerName}: ${err.message}`));
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
298
332
|
/**
|
|
299
333
|
* Run app logs command: optional env dump (masked), then docker logs
|
|
300
334
|
* @async
|
|
@@ -307,39 +341,33 @@ async function runDockerLogsFollow(containerName, tail, minLevel) {
|
|
|
307
341
|
*/
|
|
308
342
|
async function runAppLogs(appKey, options = {}) {
|
|
309
343
|
validateAppName(appKey);
|
|
310
|
-
const
|
|
311
|
-
options.level !== undefined && options.level !== null && options.level !== ''
|
|
312
|
-
? String(options.level).trim()
|
|
313
|
-
: undefined;
|
|
314
|
-
const level = rawLevel ? rawLevel.toLowerCase() : undefined;
|
|
315
|
-
if (level !== undefined && level !== null && !LOG_LEVELS.includes(level)) {
|
|
316
|
-
throw new Error(
|
|
317
|
-
`Invalid log level '${rawLevel}'; use one of: ${LOG_LEVELS.join(', ')}`
|
|
318
|
-
);
|
|
319
|
-
}
|
|
320
|
-
|
|
344
|
+
const level = parseLogLevelOption(options);
|
|
321
345
|
const developerId = await config.getDeveloperId();
|
|
322
|
-
const containerName = containerHelpers.getContainerName(appKey, developerId);
|
|
323
|
-
|
|
324
346
|
const follow = !!options.follow;
|
|
325
347
|
const tail = typeof options.tail === 'number' ? options.tail : DEFAULT_TAIL_LINES;
|
|
348
|
+
const appConfig = loadBuilderApplicationConfig(appKey);
|
|
349
|
+
const companionKeys = getCeleryCompanionAppKeys(appKey, appConfig);
|
|
350
|
+
const appKeysToLog = follow ? [appKey] : [appKey, ...companionKeys];
|
|
326
351
|
|
|
327
|
-
|
|
352
|
+
for (const key of appKeysToLog) {
|
|
353
|
+
const containerName = containerHelpers.getContainerName(key, developerId);
|
|
328
354
|
|
|
329
|
-
|
|
330
|
-
await dumpMaskedEnv(containerName);
|
|
331
|
-
}
|
|
355
|
+
logger.log(chalk.blue(`Container: ${containerName}\n`));
|
|
332
356
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
}
|
|
357
|
+
if (!follow) {
|
|
358
|
+
await dumpMaskedEnv(containerName);
|
|
359
|
+
}
|
|
337
360
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
361
|
+
if (follow) {
|
|
362
|
+
await logFollowStream(companionKeys, containerName, tail, level);
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
await logContainerSnapshot(containerName, tail, level);
|
|
367
|
+
|
|
368
|
+
if (key !== appKeysToLog[appKeysToLog.length - 1]) {
|
|
369
|
+
logger.log('');
|
|
370
|
+
}
|
|
343
371
|
}
|
|
344
372
|
}
|
|
345
373
|
|
package/lib/commands/app.js
CHANGED
|
@@ -17,6 +17,8 @@ const { registerApplication } = require('../app/register');
|
|
|
17
17
|
const { rotateSecret } = require('../app/rotate-secret');
|
|
18
18
|
const { showApp } = require('../app/show');
|
|
19
19
|
const { runAppDeploymentList } = require('./deployment-list');
|
|
20
|
+
const { isChannelTargetKey } = require('../channels/channel-targets');
|
|
21
|
+
const { addChannelCommand } = require('../channels/add-channel');
|
|
20
22
|
|
|
21
23
|
const APP_HELP_AFTER = `
|
|
22
24
|
Subcommands:
|
|
@@ -25,6 +27,7 @@ Subcommands:
|
|
|
25
27
|
rotate-secret <key> New ClientSecret (shown once)
|
|
26
28
|
show <key> From controller (like show --online)
|
|
27
29
|
deployment <key> Deployment history for app
|
|
30
|
+
add-channel <target> Configure assistant channel install (after deploy)
|
|
28
31
|
|
|
29
32
|
Requires: aifabrix login
|
|
30
33
|
`;
|
|
@@ -118,6 +121,43 @@ function setupAppDeploymentCommand(app) {
|
|
|
118
121
|
});
|
|
119
122
|
}
|
|
120
123
|
|
|
124
|
+
function setupAppAddChannelCommand(app) {
|
|
125
|
+
app.command('add-channel <channelTarget>')
|
|
126
|
+
.description(
|
|
127
|
+
'Configure assistant channel install (teams-bot, slack, …) after aifabrix deploy <target>'
|
|
128
|
+
)
|
|
129
|
+
.requiredOption('-n, --name <name>', 'Customer-visible channel name')
|
|
130
|
+
.option('-d, --description <text>', 'Channel description (default generated)')
|
|
131
|
+
.option('--icon <path>', 'Path to channel icon asset')
|
|
132
|
+
.option('--template <name>', 'Template override (default from channel target)')
|
|
133
|
+
.option('--dry-run', 'Generate artifacts only; do not patch external system or credentials')
|
|
134
|
+
.option('--force', 'Regenerate artifacts and patch config (does not rotate secrets)')
|
|
135
|
+
.option('--probe', 'After install, validate callbacks and assistant catalog')
|
|
136
|
+
.action(async(channelTarget, options) => {
|
|
137
|
+
try {
|
|
138
|
+
if (!isChannelTargetKey(channelTarget)) {
|
|
139
|
+
throw new Error(
|
|
140
|
+
`Unknown channel target "${channelTarget}". Use teams-bot, slack, microsoft-copilot, or chatgpt.`
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
await addChannelCommand(channelTarget, {
|
|
144
|
+
name: options.name,
|
|
145
|
+
description: options.description,
|
|
146
|
+
icon: options.icon,
|
|
147
|
+
template: options.template,
|
|
148
|
+
dryRun: options.dryRun === true,
|
|
149
|
+
force: options.force === true,
|
|
150
|
+
probe: options.probe === true
|
|
151
|
+
});
|
|
152
|
+
} catch (error) {
|
|
153
|
+
if (!error.message?.includes('Authentication required')) {
|
|
154
|
+
logger.error(formatBlockingError('Channel install failed:'), error.message);
|
|
155
|
+
}
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
121
161
|
/**
|
|
122
162
|
* Setup application management commands
|
|
123
163
|
* @param {Command} program - Commander program instance
|
|
@@ -129,6 +169,7 @@ function setupAppCommands(program) {
|
|
|
129
169
|
setupAppRotateSecretCommand(app);
|
|
130
170
|
setupAppShowCommand(app);
|
|
131
171
|
setupAppDeploymentCommand(app);
|
|
172
|
+
setupAppAddChannelCommand(app);
|
|
132
173
|
}
|
|
133
174
|
|
|
134
175
|
module.exports = { setupAppCommands };
|