@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
|
@@ -15,12 +15,19 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
const { handleCommandError } = require('../utils/cli-utils');
|
|
18
|
+
const { cliOptsSkipSync } = require('../utils/cli-sync-options');
|
|
18
19
|
const { cliOptsSkipCertSync } = require('../certification/cli-cert-sync-skip');
|
|
19
20
|
const { TEST_INTEGRATION_HELP_AFTER } = require('./setup-app.help');
|
|
21
|
+
const {
|
|
22
|
+
UPLOAD_HELP_AFTER,
|
|
23
|
+
DOWNLOAD_HELP_AFTER,
|
|
24
|
+
DELETE_HELP_AFTER
|
|
25
|
+
} = require('./setup-external-system-help');
|
|
20
26
|
|
|
21
27
|
function setupDownloadCommand(program) {
|
|
22
28
|
program.command('download <systemKey>')
|
|
23
29
|
.description('Pull external system from dataplane into integration/<key>/')
|
|
30
|
+
.addHelpText('after', DOWNLOAD_HELP_AFTER)
|
|
24
31
|
.option('--format <format>', 'Output format: json | yaml (default: yaml or config format)')
|
|
25
32
|
.option('--dry-run', 'Show what would be downloaded without actually downloading')
|
|
26
33
|
.option('--force', 'Overwrite existing README.md without prompting')
|
|
@@ -43,6 +50,7 @@ function setupDownloadCommand(program) {
|
|
|
43
50
|
function setupUploadCommand(program) {
|
|
44
51
|
program.command('upload <systemKey>')
|
|
45
52
|
.description('Validate, publish to dataplane, and register with controller (draft application); or upload .protection batch')
|
|
53
|
+
.addHelpText('after', UPLOAD_HELP_AFTER)
|
|
46
54
|
.option('--dry-run', 'Validate and build payload only; no API calls')
|
|
47
55
|
.option('--no-sync', 'For .protection: skip datasource sync after upload')
|
|
48
56
|
.option('--json', 'For .protection: JSON output')
|
|
@@ -55,6 +63,10 @@ function setupUploadCommand(program) {
|
|
|
55
63
|
'--no-cert-sync',
|
|
56
64
|
'Skip updating the system file certification block from the dataplane active certificate after publish'
|
|
57
65
|
)
|
|
66
|
+
.option(
|
|
67
|
+
'--force',
|
|
68
|
+
'Bypass schema guards on active datasources during publish (dangerous; shows a warning)'
|
|
69
|
+
)
|
|
58
70
|
.action(async(systemKey, options) => {
|
|
59
71
|
try {
|
|
60
72
|
const { isProtectionScope } = require('../protection/scope');
|
|
@@ -97,6 +109,7 @@ function setupUploadCommand(program) {
|
|
|
97
109
|
function setupDeleteCommand(program) {
|
|
98
110
|
program.command('delete <systemKey>')
|
|
99
111
|
.description('Remove external system and its datasources from dataplane')
|
|
112
|
+
.addHelpText('after', DELETE_HELP_AFTER)
|
|
100
113
|
.option('--type <type>', 'Application type (default: external; use "external" to target integration/<systemKey>)')
|
|
101
114
|
.option('--yes', 'Skip confirmation prompt')
|
|
102
115
|
.option('--force', 'Skip confirmation prompt (alias for --yes)')
|
|
@@ -168,7 +181,7 @@ async function runExternalSystemTestIntegration(appName, options) {
|
|
|
168
181
|
environment: options.env || options.environment,
|
|
169
182
|
debug: options.debug,
|
|
170
183
|
perDatasource: options.perDatasource,
|
|
171
|
-
|
|
184
|
+
noSync: cliOptsSkipSync(options)
|
|
172
185
|
};
|
|
173
186
|
const results = await test.testExternalSystemIntegration(appName, opts);
|
|
174
187
|
test.displayIntegrationTestResults(results, options.verbose, { debug: options.debug, runType: 'integration' });
|
|
@@ -225,9 +238,17 @@ function setupExternalSystemTestCommands(program) {
|
|
|
225
238
|
.option('-e, --env <env>', 'Environment: dev, tst, or pro (builder: dev/tst for container)', 'dev')
|
|
226
239
|
.option('-v, --verbose', 'Show detailed test output')
|
|
227
240
|
.option('-d, --debug', 'Include debug output and write log to integration/<systemKey>/logs/')
|
|
241
|
+
.option(
|
|
242
|
+
'--no-sync',
|
|
243
|
+
'Skip publishing local integration files; use system config already on the dataplane'
|
|
244
|
+
)
|
|
228
245
|
.option(
|
|
229
246
|
'--sync',
|
|
230
|
-
'Publish local system and datasource files
|
|
247
|
+
'Publish local system and datasource files before tests (default for external integration; same as upload)'
|
|
248
|
+
)
|
|
249
|
+
.option(
|
|
250
|
+
'--force',
|
|
251
|
+
'With --sync, pass force to upload (bypass active-datasource schema replacement guards; same as aifabrix upload --force)'
|
|
231
252
|
)
|
|
232
253
|
.option('--warnings-as-errors', 'Treat aggregate warn as failure (exit 1)')
|
|
233
254
|
.option('--require-cert', 'Require certification passed on every datasource (exit 2 if not)')
|
|
@@ -242,7 +263,8 @@ function setupExternalSystemTestCommands(program) {
|
|
|
242
263
|
const envExplicit = rawArgs.includes('-e') || rawArgs.includes('--env');
|
|
243
264
|
const opts = {
|
|
244
265
|
...options,
|
|
245
|
-
env: envExplicit ? options.env : undefined
|
|
266
|
+
env: envExplicit ? options.env : undefined,
|
|
267
|
+
noSync: cliOptsSkipSync(options, cmd)
|
|
246
268
|
};
|
|
247
269
|
await runTestIntegrationCommand(appName, opts);
|
|
248
270
|
} catch (error) {
|
|
@@ -15,7 +15,7 @@ const { handleCommandError, isAuthenticationError } = require('../utils/cli-util
|
|
|
15
15
|
const { resolveControllerUrl } = require('../utils/controller-url');
|
|
16
16
|
const { handleLogin } = require('../commands/login');
|
|
17
17
|
const { handleUpDataplane } = require('../commands/up-dataplane');
|
|
18
|
-
const { cleanBuilderAppDirs } = require('../commands/up-common');
|
|
18
|
+
const { cleanBuilderAppDirs, DATAPLANE_BUILDER_APP_KEYS } = require('../commands/up-common');
|
|
19
19
|
const { runGuidedUpDataplane } = require('./infra-guided');
|
|
20
20
|
const { recordInfraInstallationCommand } = require('./installation-log-command');
|
|
21
21
|
|
|
@@ -26,7 +26,7 @@ const { recordInfraInstallationCommand } = require('./installation-log-command')
|
|
|
26
26
|
async function runUpDataplaneWork(options) {
|
|
27
27
|
let cleanedAppKeys = [];
|
|
28
28
|
if (options.force) {
|
|
29
|
-
const c = await cleanBuilderAppDirs([
|
|
29
|
+
const c = await cleanBuilderAppDirs([...DATAPLANE_BUILDER_APP_KEYS]);
|
|
30
30
|
cleanedAppKeys = Array.isArray(c) ? c : [];
|
|
31
31
|
}
|
|
32
32
|
if (!options.verbose) {
|
|
@@ -19,6 +19,7 @@ const { handleUpDataplane } = require('../commands/up-dataplane');
|
|
|
19
19
|
const {
|
|
20
20
|
applyUpPlatformForceConfig,
|
|
21
21
|
cleanBuilderAppDirs,
|
|
22
|
+
PLATFORM_BUILDER_CLEAN_APP_KEYS,
|
|
22
23
|
prepareUrlsLocalRegistryForUpPlatform
|
|
23
24
|
} = require('../commands/up-common');
|
|
24
25
|
const { runGuidedUpPlatform } = require('./infra-guided');
|
|
@@ -35,7 +36,7 @@ async function runUpPlatformWork(options) {
|
|
|
35
36
|
let platformForceCleanSummary = null;
|
|
36
37
|
if (options.force) {
|
|
37
38
|
const forceSummary = await applyUpPlatformForceConfig({ silent: !options.verbose });
|
|
38
|
-
const cleanedApps = await cleanBuilderAppDirs(
|
|
39
|
+
const cleanedApps = await cleanBuilderAppDirs(PLATFORM_BUILDER_CLEAN_APP_KEYS, {
|
|
39
40
|
silent: !options.verbose
|
|
40
41
|
});
|
|
41
42
|
cleanedAppKeys = Array.isArray(cleanedApps) ? cleanedApps : [];
|
package/lib/cli/setup-infra.js
CHANGED
|
@@ -134,6 +134,8 @@ async function runUpInfraCommand(options) {
|
|
|
134
134
|
const cfg = await config.getConfig();
|
|
135
135
|
await persistOptionalInfraFlagsFromCli(options, cfg);
|
|
136
136
|
await maybePersistTlsFromUpInfra(options, cfg);
|
|
137
|
+
const { passwordBundleFromCliOptions } = require('../core/admin-secrets-bundle');
|
|
138
|
+
const bundle = passwordBundleFromCliOptions(options);
|
|
137
139
|
const adminPass = options.adminPassword || options.adminPwd;
|
|
138
140
|
const tlsEnabledEffective = cfg.tlsEnabled === true;
|
|
139
141
|
const effective = computeEffectiveInfraOptionalFlags(cfg, options);
|
|
@@ -145,6 +147,8 @@ async function runUpInfraCommand(options) {
|
|
|
145
147
|
adminPwd: adminPass,
|
|
146
148
|
adminEmail: options.adminEmail,
|
|
147
149
|
userPassword: options.userPassword,
|
|
150
|
+
passwordBundle: bundle,
|
|
151
|
+
syncAdminKv: options.syncAdminKv === true,
|
|
148
152
|
tlsEnabled: tlsEnabledEffective
|
|
149
153
|
});
|
|
150
154
|
await persistMissingInfraOptionalServiceFlags(cfg, effective);
|
|
@@ -156,8 +160,12 @@ function setupUpInfraCommand(program) {
|
|
|
156
160
|
.addHelpText('after', UP_INFRA_HELP_AFTER)
|
|
157
161
|
.option('-d, --developer <id>', 'Set developer ID and start infrastructure')
|
|
158
162
|
.option('--verbose', 'Show full orchestration output (default is guided summary)')
|
|
159
|
-
.option('--adminPassword <password>', 'Override
|
|
163
|
+
.option('--adminPassword <password>', 'Override admin password (dev: all roles; pro manual-single)')
|
|
160
164
|
.option('--adminEmail <email>', 'Override {{adminEmail}} default (e.g. pgAdmin login email)')
|
|
165
|
+
.option('--infraAdminPassword <password>', 'Pro profile: infra DB/pgAdmin/Redis Commander password')
|
|
166
|
+
.option('--keycloakAdminPassword <password>', 'Pro profile: Keycloak install admin password')
|
|
167
|
+
.option('--platformAdminPassword <password>', 'Pro profile: platform UI login password (user admin)')
|
|
168
|
+
.option('--syncAdminKv', 'Also sync {{adminPassword}} catalog keys into secrets.local.yaml (legacy)')
|
|
161
169
|
.option('--userPassword <password>', 'Override {{userPassword}} default (e.g. Keycloak default user password)')
|
|
162
170
|
.option('--pgAdmin', 'Include pgAdmin web UI and save to config')
|
|
163
171
|
.option('--no-pgAdmin', 'Exclude pgAdmin and save to config')
|
|
@@ -23,7 +23,7 @@ const { handleTeardown } = require('../commands/teardown');
|
|
|
23
23
|
|
|
24
24
|
const SETUP_HELP_AFTER = `
|
|
25
25
|
What this command does:
|
|
26
|
-
- With no infra running: prompts for
|
|
26
|
+
- With no infra running: prompts for installation profile (dev = one password for infra + Keycloak + platform UI; pro = autogen or manual split passwords). Credentials are stored in admin-secrets.env (encrypted secure:// values), not in secrets.local.yaml unless you pass --syncAdminKv on up-infra. The admin email is saved in config.yaml for the next run. Prompts for an AI tool (OpenAI or Azure OpenAI) only when keys are not already set, then runs up-infra and up-platform.
|
|
27
27
|
- With infra running: shows a mode menu:
|
|
28
28
|
1) Re-install — stop infra and remove all volumes, then up-infra + up-platform --force.
|
|
29
29
|
2) Wipe data — drop every database and DB user, then up-infra + up-platform --force.
|
|
@@ -54,6 +54,11 @@ function registerSetup(program) {
|
|
|
54
54
|
.command('setup')
|
|
55
55
|
.description('Install or refresh the full AI Fabrix platform (infra + miso + dataplane)')
|
|
56
56
|
.option('-d, --developer <id>', 'Pin developer ID before fresh install (fresh path only; ignored when infra is already up)')
|
|
57
|
+
.option('--platform <mode>', 'Platform mode: single, single-traefik (Traefik + TLS), or full (multi-env; advanced)')
|
|
58
|
+
.option('--installation <profile>', 'Installation profile: dev (one password) or pro (autogen/manual)')
|
|
59
|
+
.option('--pro-password-mode <mode>', 'Pro profile only: autogen or manual')
|
|
60
|
+
.option('--admin-email <email>', 'Admin email (non-interactive fresh install)')
|
|
61
|
+
.option('--admin-password <password>', 'Admin password for dev or pro manual-single (non-interactive)')
|
|
57
62
|
.option('-y, --yes', 'Skip destructive confirmation prompts (re-install, wipe data, teardown)')
|
|
58
63
|
.addHelpText('after', SETUP_HELP_AFTER)
|
|
59
64
|
.action(async(options) => {
|
package/lib/cli/setup-secrets.js
CHANGED
|
@@ -10,6 +10,7 @@ const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
|
10
10
|
const { handleCommandError } = require('../utils/cli-utils');
|
|
11
11
|
const { handleSecretsSet } = require('../commands/secrets-set');
|
|
12
12
|
const { handleSecretsList } = require('../commands/secrets-list');
|
|
13
|
+
const { handleSecretsGet } = require('../commands/secrets-get');
|
|
13
14
|
const { handleSecretsRemove } = require('../commands/secrets-remove');
|
|
14
15
|
const { handleSecretsValidate } = require('../commands/secrets-validate');
|
|
15
16
|
const { handleSecure } = require('../commands/secure');
|
|
@@ -18,7 +19,7 @@ const logger = require('../utils/logger');
|
|
|
18
19
|
|
|
19
20
|
const SECRET_GROUP_HELP_AFTER = `
|
|
20
21
|
Subcommands:
|
|
21
|
-
list, set, remove, remove-all User secrets.local.yaml (add --shared for shared/remote)
|
|
22
|
+
list, get, set, remove, remove-all User secrets.local.yaml (add --shared for shared/remote)
|
|
22
23
|
set-secrets-file Point config at a shared secrets file or https URL
|
|
23
24
|
validate YAML structure (+ optional --naming)
|
|
24
25
|
|
|
@@ -38,6 +39,17 @@ Examples:
|
|
|
38
39
|
Shared over https: key BASH_NPM_TOKEN --shared → NPM_TOKEN available in terminal (exported).
|
|
39
40
|
`;
|
|
40
41
|
|
|
42
|
+
const SECRET_GET_HELP_AFTER = `
|
|
43
|
+
Examples:
|
|
44
|
+
$ aifabrix secret get hubspot-demo/token --shared --exists
|
|
45
|
+
$ aifabrix secret get myapp/clientSecret
|
|
46
|
+
$ aifabrix secret get hubspot/apiKey --shared --json
|
|
47
|
+
|
|
48
|
+
--exists Script mode: exit 0 when the key is present and non-empty; no output.
|
|
49
|
+
Default Local user secrets.local.yaml only (same target as secret set without --shared).
|
|
50
|
+
--shared aifabrix-secrets store only (team file or remote API; same as secret set --shared).
|
|
51
|
+
`;
|
|
52
|
+
|
|
41
53
|
const SECRET_LIST_HELP_AFTER = `
|
|
42
54
|
Examples:
|
|
43
55
|
$ aifabrix secret list
|
|
@@ -168,6 +180,25 @@ function setupSecureCommand(program) {
|
|
|
168
180
|
});
|
|
169
181
|
}
|
|
170
182
|
|
|
183
|
+
function setupSecretGetCommand(secretCmd) {
|
|
184
|
+
secretCmd
|
|
185
|
+
.command('get <key>')
|
|
186
|
+
.description('Get one secret (local user file by default; --shared for team store; --exists for scripts)')
|
|
187
|
+
.addHelpText('after', SECRET_GET_HELP_AFTER)
|
|
188
|
+
.option('--shared', 'Read from shared secrets (config aifabrix-secrets or remote API)')
|
|
189
|
+
.option('--exists', 'Exit 0 when key is present and non-empty; print nothing (for scripts)')
|
|
190
|
+
.option('--json', 'Output JSON { key, exists, value }')
|
|
191
|
+
.action(async(key, options) => {
|
|
192
|
+
try {
|
|
193
|
+
await config.ensureSecretsEncryptionKey();
|
|
194
|
+
await handleSecretsGet(key, options);
|
|
195
|
+
} catch (error) {
|
|
196
|
+
handleCommandError(error, 'secret get');
|
|
197
|
+
process.exit(1);
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
171
202
|
function setupSecretListCommand(secretCmd) {
|
|
172
203
|
secretCmd
|
|
173
204
|
.command('list')
|
|
@@ -196,6 +227,7 @@ function setupSecretsCommands(program) {
|
|
|
196
227
|
.addHelpText('after', SECRET_GROUP_HELP_AFTER);
|
|
197
228
|
|
|
198
229
|
setupSecretListCommand(secretCmd);
|
|
230
|
+
setupSecretGetCommand(secretCmd);
|
|
199
231
|
|
|
200
232
|
secretCmd
|
|
201
233
|
.command('set <key> <value>')
|
|
@@ -26,8 +26,11 @@ Examples:
|
|
|
26
26
|
$ aifabrix repair hubspot-demo --dry-run
|
|
27
27
|
Show what would change without writing files.
|
|
28
28
|
|
|
29
|
+
$ aifabrix repair hubspot-demo --auth bearerToken
|
|
30
|
+
Private-app style apikey: Authorization + Bearer prefix; preserves baseUrl/testEndpoint when present. Warns if testEndpoint is missing.
|
|
31
|
+
|
|
29
32
|
$ aifabrix repair hubspot-demo --auth oauth2
|
|
30
|
-
Set authentication method; updates the system file and env.template (oauth2, aad, apikey, basic, …).
|
|
33
|
+
Set authentication method; updates the system file and env.template (oauth2, aad, apikey, bearerToken, basic, …).
|
|
31
34
|
|
|
32
35
|
$ aifabrix repair hubspot-demo --rbac --expose --sync --test
|
|
33
36
|
Optional datasource fixes: RBAC roles/permissions, exposed.schema from attributes, default sync block, testPayload stubs.
|
|
@@ -38,8 +41,28 @@ Examples:
|
|
|
38
41
|
Before overwriting files, repair writes timestamped backups under integration/<systemKey>/backup/ (same as datasource capability copy). Use --no-backup to skip.
|
|
39
42
|
`;
|
|
40
43
|
|
|
44
|
+
const RESOLVE_HELP_AFTER = `
|
|
45
|
+
Examples:
|
|
46
|
+
$ aifabrix resolve hubspot-demo
|
|
47
|
+
External integration: resolves integration/<systemKey>/env.template to .env using local host ports (no Docker rewrite).
|
|
48
|
+
|
|
49
|
+
$ aifabrix resolve dataplane --force
|
|
50
|
+
Seed missing secret keys and replace the full .env from env.template (no merge with an existing file).
|
|
51
|
+
|
|
52
|
+
$ aifabrix resolve dataplane --fresh
|
|
53
|
+
Replace the full .env only (no merge; does not seed missing secret keys). Same .env output as --force when secrets are already set.
|
|
54
|
+
|
|
55
|
+
$ aifabrix secret set hubspot-demo/token "<your-token>"
|
|
56
|
+
Store a secret when resolve reports a missing kv:// reference.
|
|
57
|
+
|
|
58
|
+
If a key is not required by your system file, comment out its line in env.template instead of creating a secret.
|
|
59
|
+
$ aifabrix repair hubspot-demo
|
|
60
|
+
Align env.template with authentication.security and comment stale OAuth KV lines after --auth bearerToken.
|
|
61
|
+
`;
|
|
62
|
+
|
|
41
63
|
module.exports = {
|
|
42
64
|
JSON_HELP_AFTER,
|
|
43
65
|
VALIDATE_HELP_AFTER,
|
|
44
|
-
REPAIR_HELP_AFTER
|
|
66
|
+
REPAIR_HELP_AFTER,
|
|
67
|
+
RESOLVE_HELP_AFTER
|
|
45
68
|
};
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `aifabrix repair` command wiring and CLI output (split from setup-utility for size limits).
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Repair CLI command
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const chalk = require('chalk');
|
|
12
|
+
const logger = require('../utils/logger');
|
|
13
|
+
const { handleCommandError, logOfflinePathWhenType } = require('../utils/cli-utils');
|
|
14
|
+
const { detectAppType } = require('../utils/paths');
|
|
15
|
+
const { formatSuccessParagraph, formatWarningLine } = require('../utils/cli-test-layout-chalk');
|
|
16
|
+
const { REPAIR_HELP_AFTER } = require('./setup-utility-help-after');
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param {string} appName
|
|
20
|
+
* @param {object} options
|
|
21
|
+
* @param {string} format
|
|
22
|
+
* @returns {object}
|
|
23
|
+
*/
|
|
24
|
+
function buildRepairExternalIntegrationOptions(appName, options, format) {
|
|
25
|
+
const all = options.all === true;
|
|
26
|
+
return {
|
|
27
|
+
auth: options.auth,
|
|
28
|
+
doc: options.doc || all,
|
|
29
|
+
dryRun: options.dryRun,
|
|
30
|
+
format,
|
|
31
|
+
rbac: options.rbac || all,
|
|
32
|
+
expose: options.expose || all,
|
|
33
|
+
sync: options.sync || all,
|
|
34
|
+
api: options.api || all,
|
|
35
|
+
test: options.test || all,
|
|
36
|
+
backup: options.backup,
|
|
37
|
+
noBackup: options.noBackup
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {string[]} changedFiles
|
|
43
|
+
* @param {boolean} dryRun
|
|
44
|
+
*/
|
|
45
|
+
function logRepairChangedFiles(changedFiles, dryRun) {
|
|
46
|
+
if (!Array.isArray(changedFiles) || changedFiles.length === 0) return;
|
|
47
|
+
const title = dryRun ? '\nWould change files:' : '\nChanged files:';
|
|
48
|
+
logger.log(chalk.white(title));
|
|
49
|
+
changedFiles.forEach((filePath) => logger.log(chalk.cyan(` ${filePath}`)));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @param {string[]} warnings
|
|
54
|
+
*/
|
|
55
|
+
function logRepairWarnings(warnings) {
|
|
56
|
+
if (!Array.isArray(warnings) || warnings.length === 0) return;
|
|
57
|
+
warnings.forEach((msg) => logger.log(formatWarningLine(msg)));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @param {string[]} changedFiles
|
|
62
|
+
* @param {string[]} warnings
|
|
63
|
+
*/
|
|
64
|
+
function logRepairNextActions(changedFiles, warnings) {
|
|
65
|
+
const hasFiles = Array.isArray(changedFiles) && changedFiles.length > 0;
|
|
66
|
+
const hasWarnings = Array.isArray(warnings) && warnings.length > 0;
|
|
67
|
+
if (!hasFiles && !hasWarnings) return;
|
|
68
|
+
logger.log(chalk.white('\nNext actions:'));
|
|
69
|
+
if (hasFiles) {
|
|
70
|
+
logger.log(chalk.gray(' • Open the paths above in your editor and review the diff'));
|
|
71
|
+
logger.log(chalk.gray(' • Run: aifabrix validate <systemKey>'));
|
|
72
|
+
}
|
|
73
|
+
if (hasWarnings) {
|
|
74
|
+
logger.log(chalk.gray(' • Fix warnings in the system file (especially authentication.variables.testEndpoint)'));
|
|
75
|
+
logger.log(chalk.gray(' • Run: aifabrix json <systemKey> && aifabrix upload <systemKey>'));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @param {object} options
|
|
81
|
+
* @param {object} result
|
|
82
|
+
* @param {string[]} changedFiles
|
|
83
|
+
*/
|
|
84
|
+
function logRepairDryRunOutcome(options, result, changedFiles) {
|
|
85
|
+
logger.log(chalk.yellow('\nWould apply:'));
|
|
86
|
+
result.changes.forEach((c) => logger.log(chalk.gray(` ${c}`)));
|
|
87
|
+
logRepairChangedFiles(changedFiles, true);
|
|
88
|
+
logRepairWarnings(result.warnings);
|
|
89
|
+
logRepairNextActions(changedFiles, result.warnings);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @param {object} result
|
|
94
|
+
* @param {string[]} changedFiles
|
|
95
|
+
*/
|
|
96
|
+
function logRepairSuccessOutcome(result, changedFiles) {
|
|
97
|
+
if (result.updated) {
|
|
98
|
+
logger.log(formatSuccessParagraph('Repaired external integration config.'));
|
|
99
|
+
logRepairChangedFiles(changedFiles, false);
|
|
100
|
+
logRepairNextActions(changedFiles, result.warnings);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (Array.isArray(result.changes) && result.changes.length > 0) {
|
|
104
|
+
logger.log(formatSuccessParagraph('Repair actions completed.'));
|
|
105
|
+
result.changes.forEach((c) => logger.log(chalk.gray(` ${c}`)));
|
|
106
|
+
logRepairChangedFiles(changedFiles, false);
|
|
107
|
+
logRepairNextActions(changedFiles, result.warnings);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (result.readmeRegenerated) {
|
|
111
|
+
logger.log(formatSuccessParagraph('Regenerated README.md from deployment manifest.'));
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (Array.isArray(result.warnings) && result.warnings.length > 0) {
|
|
115
|
+
logRepairNextActions(changedFiles, result.warnings);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
logger.log(chalk.gray('No changes needed; config already matches files on disk.'));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* @param {object} options
|
|
123
|
+
* @param {object} result
|
|
124
|
+
*/
|
|
125
|
+
function logRepairResult(options, result) {
|
|
126
|
+
const changedFiles = result.changedFiles;
|
|
127
|
+
if (options.dryRun && result.updated && result.changes.length > 0) {
|
|
128
|
+
logRepairDryRunOutcome(options, result, changedFiles);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (Array.isArray(result.backupPaths) && result.backupPaths.length > 0) {
|
|
132
|
+
result.backupPaths.forEach((p) => logger.log(chalk.gray(`Backup: ${p}`)));
|
|
133
|
+
}
|
|
134
|
+
logRepairWarnings(result.warnings);
|
|
135
|
+
logRepairSuccessOutcome(result, changedFiles);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @param {string} appName
|
|
140
|
+
* @param {object} options
|
|
141
|
+
* @returns {Promise<void>}
|
|
142
|
+
*/
|
|
143
|
+
async function handleRepairCommand(appName, options) {
|
|
144
|
+
const { repairExternalIntegration } = require('../commands/repair');
|
|
145
|
+
const { appPath } = await detectAppType(appName);
|
|
146
|
+
logOfflinePathWhenType(appPath);
|
|
147
|
+
let format = 'yaml';
|
|
148
|
+
try {
|
|
149
|
+
const config = require('../core/config');
|
|
150
|
+
format = (await config.getFormat()) || format;
|
|
151
|
+
} catch (_) {
|
|
152
|
+
/* default yaml when config unavailable */
|
|
153
|
+
}
|
|
154
|
+
const result = await repairExternalIntegration(
|
|
155
|
+
appName,
|
|
156
|
+
buildRepairExternalIntegrationOptions(appName, options, format)
|
|
157
|
+
);
|
|
158
|
+
logRepairResult(options, result);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* @param {import('commander').Command} program
|
|
163
|
+
*/
|
|
164
|
+
function setupRepairCommand(program) {
|
|
165
|
+
program.command('repair <systemKey>')
|
|
166
|
+
.description('Fix external integration drift (files, RBAC, manifest, …)')
|
|
167
|
+
.option('--all', 'Run all repair actions (api, doc, expose, rbac, sync, test)')
|
|
168
|
+
.option(
|
|
169
|
+
'--api',
|
|
170
|
+
'Validate and sync API contracts needed for OpenAPI/MCP (uses local OpenAPI specs at integration/<systemKey>/openapi/*.json when present)'
|
|
171
|
+
)
|
|
172
|
+
.option(
|
|
173
|
+
'--auth <method>',
|
|
174
|
+
'Set authentication method (oauth2, aad, apikey, bearerToken, basic, queryParam, oidc, hmac, none); updates system file and env.template'
|
|
175
|
+
)
|
|
176
|
+
.option('--doc', 'Regenerate README.md from deployment manifest')
|
|
177
|
+
.option('--expose', 'Set exposed.schema on each datasource from all fieldMappings.attributes keys (metadata.<key>); removes deprecated exposed.attributes if present')
|
|
178
|
+
.option('--rbac', 'Ensure RBAC permissions per datasource and add default Admin/Reader roles if none exist')
|
|
179
|
+
.option('--sync', 'Add default sync section to datasources that lack it')
|
|
180
|
+
.option('--test', 'Generate testPayload.payloadTemplate and testPayload.expectedResult from attributes')
|
|
181
|
+
.option('--no-backup', 'Skip timestamped copies under integration/<systemKey>/backup/')
|
|
182
|
+
.option('--dry-run', 'Report changes only; do not write')
|
|
183
|
+
.addHelpText('after', REPAIR_HELP_AFTER)
|
|
184
|
+
.action(async(appName, options) => {
|
|
185
|
+
try {
|
|
186
|
+
await handleRepairCommand(appName, options);
|
|
187
|
+
} catch (error) {
|
|
188
|
+
handleCommandError(error, 'repair');
|
|
189
|
+
process.exit(1);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
module.exports = {
|
|
195
|
+
setupRepairCommand,
|
|
196
|
+
buildRepairExternalIntegrationOptions,
|
|
197
|
+
logRepairResult
|
|
198
|
+
};
|
|
@@ -8,13 +8,18 @@
|
|
|
8
8
|
|
|
9
9
|
'use strict';
|
|
10
10
|
|
|
11
|
+
const path = require('path');
|
|
11
12
|
const chalk = require('chalk');
|
|
12
13
|
const secrets = require('../core/secrets');
|
|
14
|
+
const secretsEnsure = require('../core/secrets-ensure');
|
|
13
15
|
const logger = require('../utils/logger');
|
|
14
16
|
const { handleCommandError } = require('../utils/cli-utils');
|
|
15
17
|
const coreConfig = require('../core/config');
|
|
18
|
+
const pathsUtil = require('../utils/paths');
|
|
16
19
|
const { resolvePreferLocalEnvOutputPathFlag } = require('../utils/applications-config-defaults');
|
|
17
20
|
const { getResolveAppPath } = require('../utils/paths');
|
|
21
|
+
const { resolveGenerateEnvEnvironment } = require('../utils/resolve-env-mode');
|
|
22
|
+
const { RESOLVE_HELP_AFTER } = require('./setup-utility-help-after');
|
|
18
23
|
|
|
19
24
|
/**
|
|
20
25
|
* @param {string} appName
|
|
@@ -50,10 +55,17 @@ async function runResolveJsonOutput(appName, appPath, envOnly, envPath, options,
|
|
|
50
55
|
* @param {string} envPath
|
|
51
56
|
* @param {boolean} envOnly
|
|
52
57
|
* @param {{ skipValidation?: boolean }} options
|
|
58
|
+
* @param {'local'|'docker'} environment
|
|
53
59
|
* @returns {Promise<void>}
|
|
54
60
|
*/
|
|
55
|
-
async function runResolveHumanOutput(appName, envPath, envOnly, options) {
|
|
61
|
+
async function runResolveHumanOutput(appName, envPath, envOnly, options, environment) {
|
|
56
62
|
logger.log(`✔ Generated .env file: ${envPath}`);
|
|
63
|
+
if (options.fresh || options.force) {
|
|
64
|
+
logger.log(chalk.gray(' Wrote full resolved content (replaced existing .env from env.template; no merge).'));
|
|
65
|
+
}
|
|
66
|
+
if (environment === 'local') {
|
|
67
|
+
logger.log(chalk.gray(' Resolved for local use (host ports; no Docker port rewrite).'));
|
|
68
|
+
}
|
|
57
69
|
logger.log(chalk.gray(' Note: up-platform / up-miso / up-dataplane / register / build resolve secrets in memory only.'));
|
|
58
70
|
logger.log(chalk.gray(` Re-run "aifabrix resolve ${appName}" whenever you need an on-disk .env again.`));
|
|
59
71
|
if (envOnly) {
|
|
@@ -77,9 +89,26 @@ async function runResolveHumanOutput(appName, envPath, envOnly, options) {
|
|
|
77
89
|
* @param {{ force?: boolean, skipValidation?: boolean, json?: boolean }} options
|
|
78
90
|
* @returns {Promise<void>}
|
|
79
91
|
*/
|
|
92
|
+
async function ensureResolveSecretsFromEnvTemplate(appPath, appName) {
|
|
93
|
+
const templatePath = path.join(appPath, 'env.template');
|
|
94
|
+
let emptyValuesForCredentials = false;
|
|
95
|
+
try {
|
|
96
|
+
const appType = await pathsUtil.detectAppType(appName);
|
|
97
|
+
emptyValuesForCredentials = appType?.baseDir === 'integration';
|
|
98
|
+
} catch {
|
|
99
|
+
emptyValuesForCredentials = false;
|
|
100
|
+
}
|
|
101
|
+
await secretsEnsure.ensureSecretsFromEnvTemplate(templatePath, {
|
|
102
|
+
preferredFilePath: pathsUtil.getPrimaryUserSecretsLocalPath(),
|
|
103
|
+
placeholderContext: secretsEnsure.buildInfraPlaceholderContext({}),
|
|
104
|
+
emptyValuesForCredentials
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
80
108
|
async function runResolveAppAction(appName, options) {
|
|
81
109
|
const jsonMode = options.json === true;
|
|
82
110
|
const { appPath, envOnly } = await getResolveAppPath(appName);
|
|
111
|
+
await ensureResolveSecretsFromEnvTemplate(appPath, appName);
|
|
83
112
|
const manifestEmit = require('../utils/manifest-source-emit');
|
|
84
113
|
manifestEmit.emitManifestMetadataLineIfTTY(logger, {
|
|
85
114
|
appKey: appName,
|
|
@@ -89,24 +118,26 @@ async function runResolveAppAction(appName, options) {
|
|
|
89
118
|
});
|
|
90
119
|
const userCfg = await coreConfig.getConfig();
|
|
91
120
|
const preferLocalEnvOutputPath = await resolvePreferLocalEnvOutputPathFlag(userCfg, appName);
|
|
121
|
+
const environment = resolveGenerateEnvEnvironment(appPath, appName);
|
|
92
122
|
const envPath = await secrets.generateEnvFile(
|
|
93
123
|
appName,
|
|
94
124
|
undefined,
|
|
95
|
-
|
|
125
|
+
environment,
|
|
96
126
|
options.force,
|
|
97
127
|
{
|
|
98
128
|
appPath,
|
|
99
129
|
envOnly,
|
|
100
130
|
skipOutputPath: false,
|
|
101
131
|
preserveFromPath: null,
|
|
102
|
-
preferLocalEnvOutputPath
|
|
132
|
+
preferLocalEnvOutputPath,
|
|
133
|
+
freshEnv: options.fresh === true || options.force === true
|
|
103
134
|
}
|
|
104
135
|
);
|
|
105
136
|
if (jsonMode) {
|
|
106
137
|
await runResolveJsonOutput(appName, appPath, envOnly, envPath, options, manifestEmit);
|
|
107
138
|
return;
|
|
108
139
|
}
|
|
109
|
-
await runResolveHumanOutput(appName, envPath, envOnly, options);
|
|
140
|
+
await runResolveHumanOutput(appName, envPath, envOnly, options, environment);
|
|
110
141
|
}
|
|
111
142
|
|
|
112
143
|
/**
|
|
@@ -116,7 +147,15 @@ async function runResolveAppAction(appName, options) {
|
|
|
116
147
|
function setupResolveCommand(program) {
|
|
117
148
|
program.command('resolve <appKey|systemKey>')
|
|
118
149
|
.description('Generate .env from template (builder/<appKey>/ or integration/<systemKey>/); optional validate after')
|
|
119
|
-
.
|
|
150
|
+
.addHelpText('after', RESOLVE_HELP_AFTER)
|
|
151
|
+
.option(
|
|
152
|
+
'-f, --force',
|
|
153
|
+
'Seed missing secret keys and replace .env from env.template (no merge with existing .env or envOutputPath)'
|
|
154
|
+
)
|
|
155
|
+
.option(
|
|
156
|
+
'--fresh',
|
|
157
|
+
'Same full .env replace as --force without seeding missing secret keys in the secrets file'
|
|
158
|
+
)
|
|
120
159
|
.option('--skip-validation', 'Skip file validation after generating .env')
|
|
121
160
|
.option('--json', 'Print JSON summary (envPath, manifestSource, optional validation)')
|
|
122
161
|
.action(async(appName, options) => {
|