@aifabrix/builder 2.45.0 → 2.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursor/rules/cli-layout.mdc +2 -0
- package/.cursor/rules/cli-product-neutral.mdc +43 -0
- package/.cursor/rules/docs-rules.mdc +3 -1
- package/.cursor/rules/project-rules.mdc +1 -0
- package/README.md +43 -17
- package/integration/hubspot-test/wizard-hubspot-e2e.yaml +1 -1
- package/jest.config.default.js +2 -1
- package/jest.config.isolated.js +2 -1
- package/jest.global-live-fabrix-hooks.js +36 -0
- package/jest.isolated-projects.js +130 -0
- package/jest.projects.js +69 -121
- package/lib/api/agent-metadata-validation.api.js +93 -0
- package/lib/api/api-response-errors.js +124 -0
- package/lib/api/audit-api-helpers.js +68 -0
- package/lib/api/audit.api.js +119 -0
- package/lib/api/auth-cache.api.js +44 -0
- package/lib/api/certificates.api.js +4 -4
- package/lib/api/credential.api.js +2 -2
- package/lib/api/dataplane-health.api.js +137 -0
- package/lib/api/dataplane-sync.api.js +27 -0
- package/lib/api/datasources-core.api.js +21 -18
- package/lib/api/datasources-extended.api.js +22 -22
- package/lib/api/dimensions.api.js +3 -0
- package/lib/api/external-systems.api.js +13 -13
- package/lib/api/governance-scenario-pack.api.js +159 -0
- package/lib/api/governance-scenarios.api.js +39 -0
- package/lib/api/groups.api.js +79 -0
- package/lib/api/index.js +88 -5
- package/lib/api/lifecycle.api.js +77 -0
- package/lib/api/pipeline.api.js +7 -5
- package/lib/api/protection.api.js +157 -0
- package/lib/api/records-bulk.api.js +43 -0
- package/lib/api/records-search-parse.js +49 -0
- package/lib/api/records-search.api.js +29 -0
- package/lib/api/types/agent-metadata-validation.types.js +67 -0
- package/lib/api/types/audit.types.js +72 -0
- package/lib/api/types/dataplane-health.types.js +27 -0
- package/lib/api/types/dimensions.types.js +2 -0
- package/lib/api/types/governance-scenarios.types.js +39 -0
- package/lib/api/types/protection.types.js +69 -0
- package/lib/api/types/records-bulk.types.js +35 -0
- package/lib/api/types/records-search.types.js +28 -0
- package/lib/api/user-groups.api.js +50 -0
- package/lib/api/users.api.js +95 -0
- package/lib/api/validation-run.api.js +3 -3
- package/lib/api/validation-runner.js +5 -3
- package/lib/api/wizard-platform.api.js +3 -3
- package/lib/api/wizard.api.js +21 -21
- package/lib/app/deploy-config.js +4 -1
- package/lib/app/deploy.js +34 -19
- package/lib/app/down.js +20 -1
- package/lib/app/push.js +4 -5
- package/lib/app/register.js +7 -4
- package/lib/app/run-env-compose.js +84 -30
- package/lib/build/index.js +5 -0
- package/lib/certification/sync-system-certification.js +13 -6
- package/lib/cli/index.js +8 -2
- package/lib/cli/infra-guided-auth.js +109 -0
- package/lib/cli/infra-guided.js +91 -69
- package/lib/cli/setup-app.help.js +19 -2
- package/lib/cli/setup-app.js +58 -23
- package/lib/cli/setup-app.test-commands.js +28 -21
- package/lib/cli/setup-auth.js +55 -3
- package/lib/cli/setup-certification-commands.js +147 -0
- package/lib/cli/setup-certification.help.js +141 -0
- package/lib/cli/setup-environment.js +19 -2
- package/lib/cli/setup-external-system-help.js +62 -0
- package/lib/cli/setup-external-system.js +62 -6
- package/lib/cli/setup-infra.js +9 -1
- package/lib/cli/setup-platform.js +6 -1
- package/lib/cli/setup-secrets.js +33 -1
- package/lib/cli/setup-utility-help-after.js +65 -0
- package/lib/cli/setup-utility-repair.js +198 -0
- package/lib/cli/setup-utility-resolve.js +42 -6
- package/lib/cli/setup-utility-validate.js +197 -0
- package/lib/cli/setup-utility.js +41 -258
- package/lib/commands/auth-status-client-tokens.js +214 -0
- package/lib/commands/auth-status-dataplane-version.js +269 -0
- package/lib/commands/auth-status-display.js +94 -0
- package/lib/commands/auth-status.js +111 -53
- package/lib/commands/credential-push.js +10 -5
- package/lib/commands/datasource-load-export-cli.js +178 -0
- package/lib/commands/datasource-test-trust-cli.js +118 -0
- package/lib/commands/datasource-unified-test-cli.js +31 -20
- package/lib/commands/datasource-unified-test-cli.options.js +22 -3
- package/lib/commands/datasource-unified-test-e2e-cli-helpers.js +5 -5
- package/lib/commands/datasource-verify-audit-cli.js +96 -0
- package/lib/commands/datasource.js +68 -1
- package/lib/commands/dev-show-display.js +8 -1
- package/lib/commands/dimension-value.js +43 -13
- package/lib/commands/dimension.js +38 -7
- package/lib/commands/governance-cli-shared.js +94 -0
- package/lib/commands/governance-command-action.js +132 -0
- package/lib/commands/governance-download-external.js +34 -0
- package/lib/commands/governance-generate-external.js +71 -0
- package/lib/commands/governance-upload-external.js +36 -0
- package/lib/commands/governance-verify-external.js +64 -0
- package/lib/commands/governance.js +144 -0
- package/lib/commands/identity-apply-sync.js +131 -0
- package/lib/commands/identity-group-cli.js +146 -0
- package/lib/commands/identity-membership-role-cache.js +175 -0
- package/lib/commands/identity-shared.js +94 -0
- package/lib/commands/identity-user-cli.js +158 -0
- package/lib/commands/identity.js +43 -0
- package/lib/commands/lifecycle-command-action.js +123 -0
- package/lib/commands/lifecycle-external.js +268 -0
- package/lib/commands/login.js +56 -17
- package/lib/commands/protection-cli-leaves.js +286 -0
- package/lib/commands/protection.js +50 -0
- package/lib/commands/repair-auth-apply.js +127 -0
- package/lib/commands/repair-changed-files.js +41 -0
- package/lib/commands/repair-datasource-keys.js +4 -1
- package/lib/commands/repair-datasource-run.js +59 -0
- package/lib/commands/repair-datasource-test-payload.js +259 -0
- package/lib/commands/repair-datasource.js +1 -51
- package/lib/commands/repair-env-template.js +64 -13
- package/lib/commands/repair-external-run.js +216 -0
- package/lib/commands/repair-openapi-sync.js +23 -0
- package/lib/commands/repair-persist.js +4 -0
- package/lib/commands/repair-rbac.js +52 -1
- package/lib/commands/repair-steps.js +145 -0
- package/lib/commands/repair.js +29 -286
- package/lib/commands/secrets-get.js +184 -0
- package/lib/commands/secrets-remove-all.js +3 -1
- package/lib/commands/setup-image-refresh.js +146 -0
- package/lib/commands/setup-modes.js +158 -162
- package/lib/commands/setup-platform-auth.js +76 -0
- package/lib/commands/setup-prompts-admin.js +244 -0
- package/lib/commands/setup-prompts-platform-mode.js +67 -0
- package/lib/commands/setup-prompts-validators.js +36 -0
- package/lib/commands/setup-prompts.js +24 -76
- package/lib/commands/setup-run-context.js +45 -0
- package/lib/commands/setup-spinners.js +39 -0
- package/lib/commands/setup.js +27 -5
- package/lib/commands/teardown.js +39 -0
- package/lib/commands/test-e2e-external.js +61 -14
- package/lib/commands/test-governance-cli-options.js +47 -0
- package/lib/commands/test-governance-external.js +67 -0
- package/lib/commands/test-trust-cli-options.js +32 -0
- package/lib/commands/test-trust-external.js +126 -0
- package/lib/commands/up-common.js +25 -13
- package/lib/commands/up-dataplane.js +50 -13
- package/lib/commands/upload-publish-context.js +75 -0
- package/lib/commands/upload-sidecar-followups.js +89 -0
- package/lib/commands/upload.js +108 -105
- package/lib/commands/verify-governance-combined-external.js +61 -0
- package/lib/commands/verify-governance-command-action.js +64 -0
- package/lib/commands/verify-governance-db.js +102 -0
- package/lib/commands/verify-governance-external.js +77 -0
- package/lib/commands/verify-governance-result-builders.js +71 -0
- package/lib/commands/verify-operations-command-action.js +68 -0
- package/lib/commands/verify-operations-external.js +268 -0
- package/lib/commands/verify-operations-persist.js +75 -0
- package/lib/commands/verify-operations-step-plan.js +68 -0
- package/lib/commands/verify-operations-steps.js +111 -0
- package/lib/commands/verify-trust-command-action.js +70 -0
- package/lib/commands/verify-trust-external.js +67 -0
- package/lib/commands/wizard-config-normalizer.js +43 -23
- package/lib/commands/wizard-core.js +5 -0
- package/lib/core/admin-password-generator.js +38 -0
- package/lib/core/admin-secrets-bundle.js +111 -0
- package/lib/core/admin-secrets-env-overlay.js +62 -0
- package/lib/core/admin-secrets.js +32 -4
- package/lib/core/config-attach-extensions.js +3 -0
- package/lib/core/config-device-dataplane.js +185 -0
- package/lib/core/config-platform-controller.js +44 -0
- package/lib/core/config-setup-installation-profile.js +42 -0
- package/lib/core/config-setup-platform-mode.js +46 -0
- package/lib/core/config.js +46 -36
- package/lib/core/secrets-admin-env.js +6 -2
- package/lib/core/secrets-ensure.js +4 -0
- package/lib/core/secrets-env-content.js +54 -48
- package/lib/core/secrets-env-write.js +10 -1
- package/lib/core/secrets-infra-placeholder-sync.js +2 -0
- package/lib/core/setup-installation-profile.js +43 -0
- package/lib/core/setup-platform-mode.js +55 -0
- package/lib/datasource/agent-trust-debug-log.js +45 -0
- package/lib/datasource/agent-trust-fetch.js +115 -0
- package/lib/datasource/agent-trust-map.js +101 -0
- package/lib/datasource/agent-trust-mock.js +44 -0
- package/lib/datasource/agent-trust-run.js +95 -0
- package/lib/datasource/agent-trust-timeout.js +25 -0
- package/lib/datasource/audit-evidence-display.js +80 -0
- package/lib/datasource/audit-evidence-extract-debug.js +115 -0
- package/lib/datasource/audit-evidence-extract.js +180 -0
- package/lib/datasource/audit-evidence-matrix-rows.js +158 -0
- package/lib/datasource/audit-evidence-operation-aliases.js +63 -0
- package/lib/datasource/audit-evidence-poll.js +109 -0
- package/lib/datasource/audit-evidence-run.js +177 -0
- package/lib/datasource/audit-evidence-verify-helpers.js +167 -0
- package/lib/datasource/audit-evidence-verify-matrix.js +205 -0
- package/lib/datasource/audit-evidence-verify.js +108 -0
- package/lib/datasource/bulk-loader-run-batches.js +100 -0
- package/lib/datasource/bulk-loader-service-retry.js +52 -0
- package/lib/datasource/bulk-loader-service.js +127 -0
- package/lib/datasource/capability/run-capability-dimension.js +2 -1
- package/lib/datasource/datasource-exporter-resolve.js +82 -0
- package/lib/datasource/datasource-exporter-service.js +144 -0
- package/lib/datasource/datasource-identifier.js +148 -0
- package/lib/datasource/datasource-load-export-context.js +95 -0
- package/lib/datasource/integration-context.js +6 -4
- package/lib/datasource/local-data-paths.js +145 -0
- package/lib/datasource/log-cleaner.js +241 -0
- package/lib/datasource/log-viewer.js +111 -6
- package/lib/datasource/record-file-parser.js +85 -0
- package/lib/datasource/record-mapper.js +129 -0
- package/lib/datasource/resolve-app.js +74 -55
- package/lib/datasource/test-e2e.js +29 -2
- package/lib/datasource/unified-validation-run-body.js +3 -1
- package/lib/datasource/unified-validation-run-resolve.js +45 -12
- package/lib/datasource/unified-validation-run.js +47 -18
- package/lib/datasource/validate.js +37 -20
- package/lib/deployment/environment-poll-status.js +138 -0
- package/lib/deployment/environment.js +42 -34
- package/lib/external-system/download.js +21 -20
- package/lib/external-system/generator.js +5 -1
- package/lib/external-system/integration-auth-context.js +45 -0
- package/lib/external-system/test-auth.js +12 -5
- package/lib/external-system/test-system-level.js +25 -4
- package/lib/external-system/test.js +9 -7
- package/lib/generator/external-controller-manifest.js +15 -0
- package/lib/governance/governance-cli-errors.js +96 -0
- package/lib/governance/governance-download-display.js +38 -0
- package/lib/governance/governance-pack-loader.js +70 -0
- package/lib/governance/governance-run-display.js +309 -0
- package/lib/identity/identity-apply-core.js +108 -0
- package/lib/identity/identity-apply-phases.js +244 -0
- package/lib/identity/identity-apply-service.js +77 -0
- package/lib/identity/identity-csv-parser.js +114 -0
- package/lib/infrastructure/admin-secrets-apply.js +84 -0
- package/lib/infrastructure/admin-secrets-ensure.js +130 -0
- package/lib/infrastructure/admin-secrets-resolve.js +95 -0
- package/lib/infrastructure/admin-secrets-sync.js +91 -0
- package/lib/infrastructure/helpers.js +23 -129
- package/lib/infrastructure/index.js +5 -6
- package/lib/infrastructure/orphan-infra-docker-teardown.js +11 -5
- package/lib/internal/fs-real-sync.js +29 -1
- package/lib/lifecycle/certification-progress.js +231 -0
- package/lib/lifecycle/dataplane-ui-url.js +145 -0
- package/lib/lifecycle/exit-codes.js +24 -0
- package/lib/lifecycle/json-envelope.js +25 -0
- package/lib/lifecycle/lifecycle-governance-options.js +51 -0
- package/lib/lifecycle/logger-quiet.js +29 -0
- package/lib/lifecycle/open-api-published.js +59 -0
- package/lib/lifecycle/operations-readiness-metrics.js +101 -0
- package/lib/lifecycle/product-model.js +196 -0
- package/lib/lifecycle/report-display.js +471 -0
- package/lib/lifecycle/scenario-upload.js +191 -0
- package/lib/lifecycle/verify-step-progress.js +87 -0
- package/lib/parameters/infra-kv-discovery.js +27 -2
- package/lib/protection/auth-context.js +51 -0
- package/lib/protection/convert-batch.js +90 -0
- package/lib/protection/load.js +41 -0
- package/lib/protection/paths.js +158 -0
- package/lib/protection/preflight-datasource-ready.js +46 -0
- package/lib/protection/protection-create-probe-lines.js +142 -0
- package/lib/protection/protection-create-probes.js +95 -0
- package/lib/protection/protection-create-scaffold.js +281 -0
- package/lib/protection/protection-display-helpers.js +445 -0
- package/lib/protection/protection-display.js +215 -0
- package/lib/protection/protection-preset-registry.js +97 -0
- package/lib/protection/report-exit.js +62 -0
- package/lib/protection/resolve.js +202 -0
- package/lib/protection/run-commands-validate.js +130 -0
- package/lib/protection/run-commands.js +216 -0
- package/lib/protection/run-protection-create-helpers.js +134 -0
- package/lib/protection/run-protection-create-probes-flow.js +43 -0
- package/lib/protection/run-protection-create.js +191 -0
- package/lib/protection/scope.js +22 -0
- package/lib/protection/sync-after-upload.js +64 -0
- package/lib/protection/upload-batch.js +127 -0
- package/lib/protection/validate-batch.js +113 -0
- package/lib/protection/validate-local.js +65 -0
- package/lib/resolvers/dimension-file.js +29 -4
- package/lib/schema/application-schema.json +1 -1
- package/lib/schema/datasource-test-run.schema.json +89 -6
- package/lib/schema/external-datasource.schema.json +2636 -2588
- package/lib/schema/external-system.schema.json +1089 -761
- package/lib/schema/flag-map-validation-run.json +2 -2
- package/lib/schema/infra.parameter.yaml +45 -0
- package/lib/schema/protection.schema.json +374 -0
- package/lib/schema/type/credential-field-registry.json +642 -0
- package/lib/schema/wizard-config.schema.json +1 -1
- package/lib/utils/agent-trust-run-display.js +231 -0
- package/lib/utils/agent-trust-run-exit.js +59 -0
- package/lib/utils/agent-trust-wait-ui.js +94 -0
- package/lib/utils/aifabrix-test-runtime-guard.js +125 -0
- package/lib/utils/api.js +55 -31
- package/lib/utils/app-relative-path-env.js +112 -0
- package/lib/utils/cli-exit-codes.js +30 -0
- package/lib/utils/cli-secrets-error-format.js +83 -21
- package/lib/utils/cli-sync-options.js +33 -0
- package/lib/utils/cli-utils.js +16 -4
- package/lib/utils/compose-generate-docker-compose.js +4 -0
- package/lib/utils/compose-traefik-ingress-base.js +16 -1
- package/lib/utils/config-secrets-path.js +46 -0
- package/lib/utils/controller-url.js +88 -1
- package/lib/utils/credential-push-ui.js +90 -0
- package/lib/utils/credential-secrets-env.js +137 -9
- package/lib/utils/dataplane-cli-version-gate.js +202 -0
- package/lib/utils/dataplane-cli-version-help.js +74 -0
- package/lib/utils/dataplane-resolver.js +129 -2
- package/lib/utils/datasource-export-display.js +137 -0
- package/lib/utils/datasource-load-display.js +174 -0
- package/lib/utils/datasource-load-export-ui.js +120 -0
- package/lib/utils/datasource-test-run-capability-scope.js +3 -3
- package/lib/utils/datasource-test-run-display.js +3 -3
- package/lib/utils/datasource-test-run-tty-log.js +5 -1
- package/lib/utils/declarative-url-ports.js +3 -3
- package/lib/utils/deployment-auth-mode.js +41 -0
- package/lib/utils/developer-volume-id.js +33 -0
- package/lib/utils/env-copy.js +14 -9
- package/lib/utils/env-kv-orphan-lines.js +43 -0
- package/lib/utils/error-formatters/network-errors.js +13 -4
- package/lib/utils/external-env-template.js +1 -0
- package/lib/utils/external-system-readiness-core.js +10 -0
- package/lib/utils/external-system-readiness-display.js +80 -23
- package/lib/utils/health-check.js +4 -1
- package/lib/utils/help-builder.js +35 -26
- package/lib/utils/keycloak-realm-ready.js +101 -0
- package/lib/utils/load-cip-capacity-display-config.js +61 -15
- package/lib/utils/manifest-source-emit.js +24 -0
- package/lib/utils/pipeline-upload-auth-retry.js +82 -0
- package/lib/utils/platform-controller-url.js +156 -0
- package/lib/utils/postgres-platform-bootstrap.js +199 -0
- package/lib/utils/postgres-wipe.js +9 -2
- package/lib/utils/resolve-env-mode.js +47 -0
- package/lib/utils/secrets-generator.js +31 -25
- package/lib/utils/secrets-missing-error.js +164 -0
- package/lib/utils/semver-compare.js +127 -0
- package/lib/utils/service-url-label.js +81 -0
- package/lib/utils/setup-quiet-output.js +25 -0
- package/lib/utils/template-helpers.js +15 -0
- package/lib/utils/token-manager-client-credentials.js +201 -0
- package/lib/utils/token-manager-messages.js +8 -0
- package/lib/utils/token-manager-refresh.js +12 -2
- package/lib/utils/token-manager.js +86 -105
- package/lib/utils/upload-pipeline-ui.js +98 -0
- package/lib/utils/upload-sync-options.js +42 -0
- package/lib/utils/url-declarative-public-base.js +21 -3
- package/lib/utils/url-declarative-vdir-inactive-env.js +14 -4
- package/lib/utils/validation-poll-ui.js +22 -7
- package/lib/utils/validation-run-stage.js +45 -0
- package/lib/validation/wizard-config-validator.js +58 -19
- package/package.json +1 -1
- package/templates/applications/dataplane/application.yaml +2 -1
- package/templates/applications/dataplane/env.template +36 -1
- package/templates/applications/dataplane/rbac.yaml +4 -0
- package/templates/applications/miso-controller/env.template +16 -0
- package/templates/external-system/README.md.hbs +116 -11
- package/templates/python/docker-compose.hbs +19 -18
- package/templates/typescript/docker-compose.hbs +18 -17
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Admin credential prompts for `aifabrix setup` (dev / pro installation profiles).
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Setup installation profile + password bundle prompts
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const chalk = require('chalk');
|
|
12
|
+
const inquirer = require('inquirer');
|
|
13
|
+
const logger = require('../utils/logger');
|
|
14
|
+
const config = require('../core/config');
|
|
15
|
+
const { generateProAdminPasswords } = require('../core/admin-password-generator');
|
|
16
|
+
const {
|
|
17
|
+
singlePasswordBundle,
|
|
18
|
+
splitPasswordBundle
|
|
19
|
+
} = require('../core/admin-secrets-bundle');
|
|
20
|
+
const {
|
|
21
|
+
INSTALLATION_PROFILE,
|
|
22
|
+
normalizeInstallationProfile,
|
|
23
|
+
isProInstallationProfile
|
|
24
|
+
} = require('../core/setup-installation-profile');
|
|
25
|
+
const { validateEmail, validatePassword } = require('./setup-prompts-validators');
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Resolve installation profile from CLI options or config (interactive fallback in orchestrator).
|
|
29
|
+
* @param {Object} [options]
|
|
30
|
+
* @returns {Promise<'dev'|'pro'>}
|
|
31
|
+
*/
|
|
32
|
+
async function resolveInstallationProfileFromOptions(options = {}) {
|
|
33
|
+
const cli = options.installation ?? options.installationProfile;
|
|
34
|
+
if (cli !== undefined && cli !== null && String(cli).trim() !== '') {
|
|
35
|
+
return normalizeInstallationProfile(cli);
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
return await config.getSetupInstallationProfile();
|
|
39
|
+
} catch {
|
|
40
|
+
return INSTALLATION_PROFILE.DEV;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @async
|
|
46
|
+
* @returns {Promise<'dev'|'pro'>}
|
|
47
|
+
*/
|
|
48
|
+
async function promptInstallationProfile() {
|
|
49
|
+
const { profile } = await inquirer.prompt([
|
|
50
|
+
{
|
|
51
|
+
type: 'list',
|
|
52
|
+
name: 'profile',
|
|
53
|
+
message: 'Installation profile:',
|
|
54
|
+
choices: [
|
|
55
|
+
{
|
|
56
|
+
name: 'Development (dev) — one admin password for all services',
|
|
57
|
+
value: INSTALLATION_PROFILE.DEV
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: 'Production (pro) — autogenerate strong passwords or enter manually',
|
|
61
|
+
value: INSTALLATION_PROFILE.PRO
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
default: INSTALLATION_PROFILE.DEV
|
|
65
|
+
}
|
|
66
|
+
]);
|
|
67
|
+
return profile;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @param {Object} [options]
|
|
72
|
+
* @returns {Promise<string>}
|
|
73
|
+
*/
|
|
74
|
+
async function promptAdminEmail(options = {}) {
|
|
75
|
+
const cli = String(options.adminEmail || '').trim();
|
|
76
|
+
if (cli) return cli;
|
|
77
|
+
|
|
78
|
+
let defaultEmail;
|
|
79
|
+
try {
|
|
80
|
+
const saved = await config.getAdminEmail();
|
|
81
|
+
defaultEmail = saved && saved.trim() ? saved.trim() : undefined;
|
|
82
|
+
} catch {
|
|
83
|
+
defaultEmail = undefined;
|
|
84
|
+
}
|
|
85
|
+
const emailQuestion = {
|
|
86
|
+
type: 'input',
|
|
87
|
+
name: 'adminEmail',
|
|
88
|
+
message: 'Admin email (Keycloak / pgAdmin login):',
|
|
89
|
+
validate: validateEmail
|
|
90
|
+
};
|
|
91
|
+
if (defaultEmail !== undefined) {
|
|
92
|
+
emailQuestion.default = defaultEmail;
|
|
93
|
+
}
|
|
94
|
+
const { adminEmail } = await inquirer.prompt([emailQuestion]);
|
|
95
|
+
return String(adminEmail).trim();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @async
|
|
100
|
+
* @returns {Promise<import('../core/admin-secrets-bundle').AdminPasswordBundleSingle>}
|
|
101
|
+
*/
|
|
102
|
+
async function promptDevPasswordBundle() {
|
|
103
|
+
const answers = await inquirer.prompt([
|
|
104
|
+
{
|
|
105
|
+
type: 'password',
|
|
106
|
+
name: 'adminPassword',
|
|
107
|
+
message: 'Admin password (Postgres / Keycloak / pgAdmin / platform login):',
|
|
108
|
+
mask: '*',
|
|
109
|
+
validate: validatePassword
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
type: 'password',
|
|
113
|
+
name: 'adminPasswordConfirm',
|
|
114
|
+
message: 'Confirm admin password:',
|
|
115
|
+
mask: '*',
|
|
116
|
+
validate(input, all) {
|
|
117
|
+
if (input !== all.adminPassword) return 'Passwords do not match';
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
]);
|
|
122
|
+
return singlePasswordBundle(answers.adminPassword);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Print pro autogenerated passwords once (never log plaintext elsewhere).
|
|
127
|
+
* @param {{ infra: string, keycloak: string, platform: string }} passwords
|
|
128
|
+
*/
|
|
129
|
+
function displayProPasswordsOnce(passwords) {
|
|
130
|
+
logger.log('');
|
|
131
|
+
logger.log(chalk.bold.yellow('Save these passwords now — they will not be shown again.'));
|
|
132
|
+
logger.log(chalk.gray('────────────────────────────────────────'));
|
|
133
|
+
logger.log(` Infra (Postgres / pgAdmin / Redis Commander): ${passwords.infra}`);
|
|
134
|
+
logger.log(` Keycloak install admin: ${passwords.keycloak}`);
|
|
135
|
+
logger.log(` Platform UI login (user admin): ${passwords.platform}`);
|
|
136
|
+
logger.log(chalk.gray('────────────────────────────────────────'));
|
|
137
|
+
logger.log('');
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* @param {Object} [options]
|
|
142
|
+
* @returns {Promise<import('../core/admin-secrets-bundle').AdminPasswordBundleSingle|import('../core/admin-secrets-bundle').AdminPasswordBundleSplit>}
|
|
143
|
+
*/
|
|
144
|
+
async function promptProPasswordBundle(options = {}) {
|
|
145
|
+
const modeCli = String(options.proPasswordMode || '').trim().toLowerCase();
|
|
146
|
+
if (modeCli === 'autogen') {
|
|
147
|
+
const generated = generateProAdminPasswords();
|
|
148
|
+
if (options.quiet !== true) {
|
|
149
|
+
displayProPasswordsOnce(generated);
|
|
150
|
+
}
|
|
151
|
+
return splitPasswordBundle(generated);
|
|
152
|
+
}
|
|
153
|
+
if (modeCli === 'manual' && String(options.adminPassword || '').trim()) {
|
|
154
|
+
return singlePasswordBundle(String(options.adminPassword).trim());
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const { method } = await inquirer.prompt([
|
|
158
|
+
{
|
|
159
|
+
type: 'list',
|
|
160
|
+
name: 'method',
|
|
161
|
+
message: 'How do you want to set admin passwords (pro installation)?',
|
|
162
|
+
choices: [
|
|
163
|
+
{ name: 'Autogenerate strong passwords (recommended, shown once)', value: 'autogen' },
|
|
164
|
+
{ name: 'Enter one password manually (same for all roles)', value: 'manual-single' },
|
|
165
|
+
{ name: 'Enter separate passwords (infra / Keycloak / platform)', value: 'manual-split' }
|
|
166
|
+
],
|
|
167
|
+
default: 'autogen'
|
|
168
|
+
}
|
|
169
|
+
]);
|
|
170
|
+
|
|
171
|
+
if (method === 'autogen') {
|
|
172
|
+
const generated = generateProAdminPasswords();
|
|
173
|
+
displayProPasswordsOnce(generated);
|
|
174
|
+
return splitPasswordBundle(generated);
|
|
175
|
+
}
|
|
176
|
+
if (method === 'manual-split') {
|
|
177
|
+
return promptProManualSplitBundle();
|
|
178
|
+
}
|
|
179
|
+
return promptDevPasswordBundle();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* @async
|
|
184
|
+
* @returns {Promise<import('../core/admin-secrets-bundle').AdminPasswordBundleSplit>}
|
|
185
|
+
*/
|
|
186
|
+
async function promptProManualSplitBundle() {
|
|
187
|
+
const answers = await inquirer.prompt([
|
|
188
|
+
{
|
|
189
|
+
type: 'password',
|
|
190
|
+
name: 'infra',
|
|
191
|
+
message: 'Infra password (Postgres / pgAdmin / Redis Commander):',
|
|
192
|
+
mask: '*',
|
|
193
|
+
validate: validatePassword
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
type: 'password',
|
|
197
|
+
name: 'keycloak',
|
|
198
|
+
message: 'Keycloak install admin password:',
|
|
199
|
+
mask: '*',
|
|
200
|
+
validate: validatePassword
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
type: 'password',
|
|
204
|
+
name: 'platform',
|
|
205
|
+
message: 'Platform UI login password (user admin):',
|
|
206
|
+
mask: '*',
|
|
207
|
+
validate: validatePassword
|
|
208
|
+
}
|
|
209
|
+
]);
|
|
210
|
+
return splitPasswordBundle(answers);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* @param {Object} [options]
|
|
215
|
+
* @returns {Promise<{ adminEmail: string, passwordBundle: object, profile: 'dev'|'pro' }>}
|
|
216
|
+
*/
|
|
217
|
+
async function promptAdminCredentialsWithProfile(options = {}) {
|
|
218
|
+
let profile = await resolveInstallationProfileFromOptions(options);
|
|
219
|
+
const hasCliProfile =
|
|
220
|
+
options.installation !== undefined ||
|
|
221
|
+
options.installationProfile !== undefined;
|
|
222
|
+
if (!hasCliProfile) {
|
|
223
|
+
profile = await promptInstallationProfile();
|
|
224
|
+
}
|
|
225
|
+
await config.setSetupInstallationProfile(profile);
|
|
226
|
+
|
|
227
|
+
const adminEmail = await promptAdminEmail(options);
|
|
228
|
+
const passwordBundle = isProInstallationProfile(profile)
|
|
229
|
+
? await promptProPasswordBundle(options)
|
|
230
|
+
: await promptDevPasswordBundle();
|
|
231
|
+
|
|
232
|
+
return { adminEmail, passwordBundle, profile };
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
module.exports = {
|
|
236
|
+
INSTALLATION_PROFILE,
|
|
237
|
+
resolveInstallationProfileFromOptions,
|
|
238
|
+
promptInstallationProfile,
|
|
239
|
+
promptAdminEmail,
|
|
240
|
+
promptDevPasswordBundle,
|
|
241
|
+
promptProPasswordBundle,
|
|
242
|
+
displayProPasswordsOnce,
|
|
243
|
+
promptAdminCredentialsWithProfile
|
|
244
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Setup prompts for platform topology mode (single vs full).
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Setup platform mode prompt + CLI option normalization
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const inquirer = require('inquirer');
|
|
12
|
+
const { normalizeSetupPlatformMode, SETUP_PLATFORM_MODE } = require('../core/setup-platform-mode');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Resolve platform mode from CLI options, if provided.
|
|
16
|
+
* @param {Object} [options]
|
|
17
|
+
* @returns {'single'|'full'|null}
|
|
18
|
+
*/
|
|
19
|
+
function resolvePlatformModeFromOptions(options = {}) {
|
|
20
|
+
const raw = options.platform;
|
|
21
|
+
if (raw === undefined || raw === null || String(raw).trim() === '') {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
const normalized = normalizeSetupPlatformMode(raw);
|
|
25
|
+
// Guard: only accept exact canonical values from CLI; reject unexpected to avoid silent typos.
|
|
26
|
+
const rawNorm = String(raw).trim().toLowerCase();
|
|
27
|
+
if (rawNorm !== 'single' && rawNorm !== 'full') {
|
|
28
|
+
throw new Error('--platform must be single or full (example: aifabrix setup --platform full)');
|
|
29
|
+
}
|
|
30
|
+
return normalized;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @async
|
|
35
|
+
* @param {Object} [options]
|
|
36
|
+
* @returns {Promise<'single'|'full'>}
|
|
37
|
+
*/
|
|
38
|
+
async function promptSetupPlatformMode(options = {}) {
|
|
39
|
+
const fromCli = resolvePlatformModeFromOptions(options);
|
|
40
|
+
if (fromCli) return fromCli;
|
|
41
|
+
|
|
42
|
+
const { mode } = await inquirer.prompt([
|
|
43
|
+
{
|
|
44
|
+
type: 'list',
|
|
45
|
+
name: 'mode',
|
|
46
|
+
message: 'Platform mode:',
|
|
47
|
+
choices: [
|
|
48
|
+
{
|
|
49
|
+
name: 'Single environment — direct ports (no Traefik front door)',
|
|
50
|
+
value: SETUP_PLATFORM_MODE.SINGLE
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: 'Full platform — Traefik front door + miso/dev/tst/pro (shared infra)',
|
|
54
|
+
value: SETUP_PLATFORM_MODE.FULL
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
default: SETUP_PLATFORM_MODE.SINGLE
|
|
58
|
+
}
|
|
59
|
+
]);
|
|
60
|
+
return normalizeSetupPlatformMode(mode);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
module.exports = {
|
|
64
|
+
resolvePlatformModeFromOptions,
|
|
65
|
+
promptSetupPlatformMode
|
|
66
|
+
};
|
|
67
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared validators for setup prompts.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Email/password validation for setup wizard
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param {string} input
|
|
13
|
+
* @returns {true|string}
|
|
14
|
+
*/
|
|
15
|
+
function validateEmail(input) {
|
|
16
|
+
const value = (input || '').trim();
|
|
17
|
+
if (!value) return 'Admin email is required';
|
|
18
|
+
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) return 'Enter a valid email address';
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @param {string} input
|
|
24
|
+
* @returns {true|string}
|
|
25
|
+
*/
|
|
26
|
+
function validatePassword(input) {
|
|
27
|
+
const value = String(input ?? '');
|
|
28
|
+
if (value.length === 0) return 'Admin password is required';
|
|
29
|
+
if (value.length < 8) return 'Admin password must be at least 8 characters';
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
module.exports = {
|
|
34
|
+
validateEmail,
|
|
35
|
+
validatePassword
|
|
36
|
+
};
|
|
@@ -28,16 +28,20 @@ const path = require('path');
|
|
|
28
28
|
const inquirer = require('inquirer');
|
|
29
29
|
const chalk = require('chalk');
|
|
30
30
|
const logger = require('../utils/logger');
|
|
31
|
-
const config = require('../core/config');
|
|
32
31
|
const secretsCore = require('../core/secrets');
|
|
33
32
|
const secretsEnsure = require('../core/secrets-ensure');
|
|
34
33
|
const { formatSuccessLine, infoLine } = require('../utils/cli-test-layout-chalk');
|
|
34
|
+
const { validateEmail, validatePassword } = require('./setup-prompts-validators');
|
|
35
|
+
const {
|
|
36
|
+
promptAdminCredentialsWithProfile,
|
|
37
|
+
promptInstallationProfile,
|
|
38
|
+
INSTALLATION_PROFILE
|
|
39
|
+
} = require('./setup-prompts-admin');
|
|
35
40
|
|
|
36
41
|
/** Mode identifiers. Public so callers can switch on them without string typos. */
|
|
37
42
|
const MODE = Object.freeze({
|
|
38
43
|
REINSTALL: 'reinstall',
|
|
39
44
|
WIPE_DATA: 'wipe-data',
|
|
40
|
-
CLEAN_FILES: 'clean-files',
|
|
41
45
|
UPDATE_IMAGES: 'update-images'
|
|
42
46
|
});
|
|
43
47
|
|
|
@@ -76,10 +80,6 @@ async function promptModeSelection() {
|
|
|
76
80
|
name: 'Reset databases (keeps volumes, removes DBs/users)',
|
|
77
81
|
value: MODE.WIPE_DATA
|
|
78
82
|
},
|
|
79
|
-
{
|
|
80
|
-
name: 'Refresh platform config (keeps data, re-copy platform files)',
|
|
81
|
-
value: MODE.CLEAN_FILES
|
|
82
|
-
},
|
|
83
83
|
{
|
|
84
84
|
name: 'Update images + restart services (keeps data)',
|
|
85
85
|
value: MODE.UPDATE_IMAGES
|
|
@@ -111,79 +111,23 @@ async function confirmDestructiveMode(mode, assumeYes) {
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
/**
|
|
114
|
-
*
|
|
115
|
-
* @param {string} input
|
|
116
|
-
* @returns {true|string}
|
|
117
|
-
*/
|
|
118
|
-
function validateEmail(input) {
|
|
119
|
-
const value = (input || '').trim();
|
|
120
|
-
if (!value) return 'Admin email is required';
|
|
121
|
-
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) return 'Enter a valid email address';
|
|
122
|
-
return true;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Validate a password (non-empty, at least 8 chars).
|
|
127
|
-
* @param {string} input
|
|
128
|
-
* @returns {true|string}
|
|
129
|
-
*/
|
|
130
|
-
function validatePassword(input) {
|
|
131
|
-
const value = String(input ?? '');
|
|
132
|
-
if (value.length === 0) return 'Admin password is required';
|
|
133
|
-
if (value.length < 8) return 'Admin password must be at least 8 characters';
|
|
134
|
-
return true;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Prompt for admin email + password (fresh install only).
|
|
139
|
-
* Reads {@link module:lib/core/config.getAdminEmail} so a previous `aifabrix setup` can prefill the
|
|
140
|
-
* email field (user may change it before continuing).
|
|
141
|
-
* Asks once for the password and once for confirmation; returns trimmed email
|
|
142
|
-
* and the verbatim password (never logged).
|
|
114
|
+
* Prompt for admin credentials (dev or pro installation profile).
|
|
143
115
|
*
|
|
144
116
|
* @async
|
|
145
|
-
* @
|
|
117
|
+
* @param {Object} [options] - CLI options (`installation`, `proPasswordMode`, `adminEmail`, `adminPassword`, `quiet`)
|
|
118
|
+
* @returns {Promise<{ adminEmail: string, adminPassword: string, passwordBundle: object, profile: string }>}
|
|
146
119
|
*/
|
|
147
|
-
async function promptAdminCredentials() {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
defaultEmail = undefined;
|
|
154
|
-
}
|
|
155
|
-
const emailQuestion = {
|
|
156
|
-
type: 'input',
|
|
157
|
-
name: 'adminEmail',
|
|
158
|
-
message: 'Admin email (Keycloak / pgAdmin login):',
|
|
159
|
-
validate: validateEmail
|
|
160
|
-
};
|
|
161
|
-
if (defaultEmail !== undefined) {
|
|
162
|
-
emailQuestion.default = defaultEmail;
|
|
163
|
-
}
|
|
164
|
-
const answers = await inquirer.prompt([
|
|
165
|
-
emailQuestion,
|
|
166
|
-
{
|
|
167
|
-
type: 'password',
|
|
168
|
-
name: 'adminPassword',
|
|
169
|
-
message: 'Admin password (Postgres / Keycloak / pgAdmin):',
|
|
170
|
-
mask: '*',
|
|
171
|
-
validate: validatePassword
|
|
172
|
-
},
|
|
173
|
-
{
|
|
174
|
-
type: 'password',
|
|
175
|
-
name: 'adminPasswordConfirm',
|
|
176
|
-
message: 'Confirm admin password:',
|
|
177
|
-
mask: '*',
|
|
178
|
-
validate(input, all) {
|
|
179
|
-
if (input !== all.adminPassword) return 'Passwords do not match';
|
|
180
|
-
return true;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
]);
|
|
120
|
+
async function promptAdminCredentials(options = {}) {
|
|
121
|
+
const result = await promptAdminCredentialsWithProfile(options);
|
|
122
|
+
const legacyPassword =
|
|
123
|
+
result.passwordBundle.mode === 'single'
|
|
124
|
+
? result.passwordBundle.password
|
|
125
|
+
: result.passwordBundle.platform;
|
|
184
126
|
return {
|
|
185
|
-
adminEmail:
|
|
186
|
-
adminPassword:
|
|
127
|
+
adminEmail: result.adminEmail,
|
|
128
|
+
adminPassword: legacyPassword,
|
|
129
|
+
passwordBundle: result.passwordBundle,
|
|
130
|
+
profile: result.profile
|
|
187
131
|
};
|
|
188
132
|
}
|
|
189
133
|
|
|
@@ -411,11 +355,15 @@ module.exports = {
|
|
|
411
355
|
MODE,
|
|
412
356
|
AI_KEYS,
|
|
413
357
|
BUILDER_DIR_ACTION,
|
|
358
|
+
INSTALLATION_PROFILE,
|
|
414
359
|
formatBuilderPlatformReplaceLines,
|
|
415
360
|
promptModeSelection,
|
|
416
361
|
confirmDestructiveMode,
|
|
362
|
+
promptInstallationProfile,
|
|
417
363
|
promptAdminCredentials,
|
|
418
364
|
promptAiTool,
|
|
419
365
|
detectAiToolStatus,
|
|
420
|
-
promptBuilderDirConflict
|
|
366
|
+
promptBuilderDirConflict,
|
|
367
|
+
validateEmail,
|
|
368
|
+
validatePassword
|
|
421
369
|
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Marks when `aifabrix setup` is running platform bring-up (suppress noisy token refresh warnings).
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Setup flow context flag
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
let setupPlatformFlowActive = false;
|
|
12
|
+
let setupCommandFlowActive = false;
|
|
13
|
+
|
|
14
|
+
function beginSetupCommandFlow() {
|
|
15
|
+
setupCommandFlowActive = true;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function endSetupCommandFlow() {
|
|
19
|
+
setupCommandFlowActive = false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function isSetupCommandFlow() {
|
|
23
|
+
return setupCommandFlowActive === true;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function beginSetupPlatformFlow() {
|
|
27
|
+
setupPlatformFlowActive = true;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function endSetupPlatformFlow() {
|
|
31
|
+
setupPlatformFlowActive = false;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function isSetupPlatformFlow() {
|
|
35
|
+
return setupPlatformFlowActive === true;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = {
|
|
39
|
+
beginSetupCommandFlow,
|
|
40
|
+
endSetupCommandFlow,
|
|
41
|
+
isSetupCommandFlow,
|
|
42
|
+
beginSetupPlatformFlow,
|
|
43
|
+
endSetupPlatformFlow,
|
|
44
|
+
isSetupPlatformFlow
|
|
45
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spinner helpers for `aifabrix setup` mode handlers.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview TTY progress spinners for setup commands
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const ora = require('ora');
|
|
12
|
+
const logger = require('../utils/logger');
|
|
13
|
+
const { formatProgress, formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
14
|
+
|
|
15
|
+
function shouldUseSpinner() {
|
|
16
|
+
return Boolean(process && process.stdout && process.stdout.isTTY);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function startSpinner(text) {
|
|
20
|
+
if (!shouldUseSpinner()) {
|
|
21
|
+
logger.log(formatProgress(text));
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
return ora({ text, spinner: 'dots' }).start();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function stopSpinnerSuccess(spinner, text) {
|
|
28
|
+
if (!spinner) {
|
|
29
|
+
logger.log(formatSuccessLine(text));
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
spinner.succeed(text);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = {
|
|
36
|
+
shouldUseSpinner,
|
|
37
|
+
startSpinner,
|
|
38
|
+
stopSpinnerSuccess
|
|
39
|
+
};
|
package/lib/commands/setup.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Top-level handler for `aifabrix setup`.
|
|
3
3
|
*
|
|
4
4
|
* Decides between:
|
|
5
|
-
* - fresh install (no infra running) — wizard for admin creds + AI tool, then up-infra + up-platform.
|
|
6
|
-
* - mode menu (infra already running) — dispatch one of
|
|
5
|
+
* - fresh install (no infra running) — wipe volumes, wizard for admin creds + AI tool, then up-infra + up-platform.
|
|
6
|
+
* - mode menu (infra already running) — dispatch one of three destructive/refresh paths.
|
|
7
7
|
*
|
|
8
8
|
* The mode handlers live in `setup-modes.js`; the prompts live in
|
|
9
9
|
* `setup-prompts.js`. This module is a thin orchestrator so it stays well
|
|
@@ -28,8 +28,12 @@ const {
|
|
|
28
28
|
} = require('../utils/cli-test-layout-chalk');
|
|
29
29
|
|
|
30
30
|
const setupPrompts = require('./setup-prompts');
|
|
31
|
+
const setupPlatformModePrompts = require('./setup-prompts-platform-mode');
|
|
32
|
+
const { flagsForSetupPlatformMode } = require('../core/setup-platform-mode');
|
|
31
33
|
const setupModes = require('./setup-modes');
|
|
34
|
+
const { syncPlatformControllerUrlsInConfig } = require('./setup-platform-auth');
|
|
32
35
|
const installationLog = require('../utils/installation-log');
|
|
36
|
+
const { beginSetupCommandFlow, endSetupCommandFlow } = require('./setup-run-context');
|
|
33
37
|
|
|
34
38
|
const MODE = setupPrompts.MODE;
|
|
35
39
|
|
|
@@ -54,10 +58,24 @@ async function maybePinDeveloperIdForFreshInstall(rawDeveloper) {
|
|
|
54
58
|
logger.log(infoLine(`Developer ID pinned to ${dev}.`));
|
|
55
59
|
}
|
|
56
60
|
|
|
61
|
+
async function applySetupPlatformMode(options) {
|
|
62
|
+
const mode = await setupPlatformModePrompts.promptSetupPlatformMode(options);
|
|
63
|
+
await config.setSetupPlatformMode(mode);
|
|
64
|
+
const derived = flagsForSetupPlatformMode(mode);
|
|
65
|
+
// These are the user gates that control full-mode behavior.
|
|
66
|
+
const cfg = await config.getConfig();
|
|
67
|
+
cfg.traefik = derived.traefik;
|
|
68
|
+
cfg.useEnvironmentScopedResources = derived.useEnvironmentScopedResources;
|
|
69
|
+
await config.saveConfig(cfg);
|
|
70
|
+
await syncPlatformControllerUrlsInConfig();
|
|
71
|
+
return mode;
|
|
72
|
+
}
|
|
73
|
+
|
|
57
74
|
async function runFreshInstallFlow(options) {
|
|
58
75
|
await maybePinDeveloperIdForFreshInstall(options.developer);
|
|
59
76
|
logger.log(infoLine('No infrastructure detected; starting fresh install.'));
|
|
60
|
-
|
|
77
|
+
await applySetupPlatformMode(options);
|
|
78
|
+
const adminCreds = await setupPrompts.promptAdminCredentials(options);
|
|
61
79
|
await config.setAdminEmail(adminCreds.adminEmail);
|
|
62
80
|
await setupModes.runFreshInstall(adminCreds);
|
|
63
81
|
logger.log(formatSuccessParagraph('aifabrix setup complete (fresh install).'));
|
|
@@ -74,6 +92,10 @@ async function runExistingInfraFlow(assumeYes) {
|
|
|
74
92
|
logger.log(chalk.yellow('Aborted by user.'));
|
|
75
93
|
return { aborted: true, mode };
|
|
76
94
|
}
|
|
95
|
+
// Re-install / wipe-data can change platform topology; re-prompt so the next up-platform matches intent.
|
|
96
|
+
if (mode === MODE.REINSTALL || mode === MODE.WIPE_DATA) {
|
|
97
|
+
await applySetupPlatformMode({});
|
|
98
|
+
}
|
|
77
99
|
await dispatchMode(mode);
|
|
78
100
|
logger.log(formatSuccessParagraph(`aifabrix setup complete (mode: ${mode}).`));
|
|
79
101
|
return { aborted: false, mode };
|
|
@@ -114,8 +136,6 @@ async function dispatchMode(mode) {
|
|
|
114
136
|
return setupModes.runReinstall();
|
|
115
137
|
case MODE.WIPE_DATA:
|
|
116
138
|
return setupModes.runWipeData();
|
|
117
|
-
case MODE.CLEAN_FILES:
|
|
118
|
-
return setupModes.runCleanInstallFiles();
|
|
119
139
|
case MODE.UPDATE_IMAGES:
|
|
120
140
|
return setupModes.runUpdateImages();
|
|
121
141
|
default:
|
|
@@ -224,6 +244,7 @@ async function handleSetup(options = {}) {
|
|
|
224
244
|
let setupMode = null;
|
|
225
245
|
let err = null;
|
|
226
246
|
|
|
247
|
+
beginSetupCommandFlow();
|
|
227
248
|
try {
|
|
228
249
|
const main = await runSetupMainPath(options, assumeYes);
|
|
229
250
|
outcome = main.outcome;
|
|
@@ -232,6 +253,7 @@ async function handleSetup(options = {}) {
|
|
|
232
253
|
outcome = 'failure';
|
|
233
254
|
err = e;
|
|
234
255
|
} finally {
|
|
256
|
+
endSetupCommandFlow();
|
|
235
257
|
await appendSetupInstallationRecord({
|
|
236
258
|
outcome,
|
|
237
259
|
startedAt,
|