@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
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
const path = require('path');
|
|
12
12
|
const fs = require('fs');
|
|
13
|
+
const { loadConfigFile } = require('../utils/config-format');
|
|
13
14
|
const pathsUtil = require('../utils/paths');
|
|
14
15
|
const {
|
|
15
16
|
datasourceIdentifierMatchesFile,
|
|
@@ -22,7 +23,16 @@ const { validateFieldReferences } = require('./field-reference-validator');
|
|
|
22
23
|
const { validateAbac } = require('./abac-validator');
|
|
23
24
|
const { buildDatasourceValidateSummary } = require('./datasource-validate-summary');
|
|
24
25
|
|
|
25
|
-
const
|
|
26
|
+
const DATASOURCE_CONFIG_EXTENSIONS = new Set(['.json', '.yaml', '.yml']);
|
|
27
|
+
const EXCLUDE_CONFIG_NAMES = new Set([
|
|
28
|
+
'application.json',
|
|
29
|
+
'application.yaml',
|
|
30
|
+
'application.yml',
|
|
31
|
+
'rbac.json',
|
|
32
|
+
'rbac.yaml',
|
|
33
|
+
'package.json',
|
|
34
|
+
'package-lock.json'
|
|
35
|
+
]);
|
|
26
36
|
|
|
27
37
|
/**
|
|
28
38
|
* Resolve identifier to an existing file path, or null.
|
|
@@ -64,11 +74,14 @@ function pickIntegrationAppForDatasourceKey(datasourceKey, appNames) {
|
|
|
64
74
|
* @param {string} fileName
|
|
65
75
|
* @returns {boolean}
|
|
66
76
|
*/
|
|
67
|
-
function
|
|
77
|
+
function shouldScanDatasourceConfigCandidate(fileName) {
|
|
68
78
|
const lower = fileName.toLowerCase();
|
|
69
|
-
|
|
70
|
-
if (
|
|
79
|
+
const ext = path.extname(lower);
|
|
80
|
+
if (!DATASOURCE_CONFIG_EXTENSIONS.has(ext)) return false;
|
|
81
|
+
if (EXCLUDE_CONFIG_NAMES.has(fileName)) return false;
|
|
71
82
|
if (lower.endsWith('-deploy.json') || lower.endsWith('-system.json')) return false;
|
|
83
|
+
if (lower.endsWith('-deploy.yaml') || lower.endsWith('-deploy.yml')) return false;
|
|
84
|
+
if (lower.endsWith('-system.yaml') || lower.endsWith('-system.yml')) return false;
|
|
72
85
|
return true;
|
|
73
86
|
}
|
|
74
87
|
|
|
@@ -86,13 +99,13 @@ function isDatasourceNamedJson(fileName) {
|
|
|
86
99
|
* @param {string} datasourceKey
|
|
87
100
|
* @returns {string[]}
|
|
88
101
|
*/
|
|
89
|
-
function
|
|
102
|
+
function collectConfigPathsMatchingDatasourceKey(dir, scanOrder, datasourceKey) {
|
|
90
103
|
const hits = [];
|
|
91
104
|
for (const name of scanOrder) {
|
|
92
105
|
const full = path.join(dir, name);
|
|
93
106
|
let parsed;
|
|
94
107
|
try {
|
|
95
|
-
parsed =
|
|
108
|
+
parsed = loadConfigFile(full);
|
|
96
109
|
} catch {
|
|
97
110
|
continue;
|
|
98
111
|
}
|
|
@@ -115,14 +128,14 @@ function resolvePathFromIntegrationFolderScan(appName, datasourceKey) {
|
|
|
115
128
|
throw new Error(`Integration folder not found: ${dir}`);
|
|
116
129
|
}
|
|
117
130
|
const entries = fs.readdirSync(dir);
|
|
118
|
-
const
|
|
119
|
-
const prefer =
|
|
120
|
-
const scanOrder = [...prefer, ...
|
|
121
|
-
const hits =
|
|
131
|
+
const configFiles = entries.filter(shouldScanDatasourceConfigCandidate);
|
|
132
|
+
const prefer = configFiles.filter(isDatasourceNamedJson);
|
|
133
|
+
const scanOrder = [...prefer, ...configFiles.filter((f) => !prefer.includes(f))];
|
|
134
|
+
const hits = collectConfigPathsMatchingDatasourceKey(dir, scanOrder, datasourceKey);
|
|
122
135
|
if (hits.length === 0) {
|
|
123
136
|
throw new Error(
|
|
124
|
-
`No datasource
|
|
125
|
-
`Checked: ${scanOrder.length ? scanOrder.join(', ') : '(no JSON candidates)'}`
|
|
137
|
+
`No datasource config matching "${datasourceKey}" under integration/${appName}/. ` +
|
|
138
|
+
`Checked: ${scanOrder.length ? scanOrder.join(', ') : '(no JSON/YAML candidates)'}`
|
|
126
139
|
);
|
|
127
140
|
}
|
|
128
141
|
if (hits.length > 1) {
|
|
@@ -167,7 +180,8 @@ function resolveValidateInputPath(identifier) {
|
|
|
167
180
|
}
|
|
168
181
|
const asFile = tryResolveAsExistingFile(trimmed);
|
|
169
182
|
if (asFile) return asFile;
|
|
170
|
-
|
|
183
|
+
const ext = path.extname(trimmed).toLowerCase();
|
|
184
|
+
if (DATASOURCE_CONFIG_EXTENSIONS.has(ext)) {
|
|
171
185
|
throw new Error(`File not found: ${trimmed}`);
|
|
172
186
|
}
|
|
173
187
|
return resolvePathFromIntegrationDatasourceKey(trimmed);
|
|
@@ -187,6 +201,18 @@ function resolveValidateInputPath(identifier) {
|
|
|
187
201
|
* const result = await validateDatasourceFile('./hubspot-deal.json');
|
|
188
202
|
* // Returns: { valid: true, errors: [], warnings: [], resolvedPath: '...' }
|
|
189
203
|
*/
|
|
204
|
+
function buildParseFailureResult(filePath, error) {
|
|
205
|
+
const message =
|
|
206
|
+
error && error.message ? String(error.message) : 'Invalid config file';
|
|
207
|
+
return {
|
|
208
|
+
valid: false,
|
|
209
|
+
errors: [message],
|
|
210
|
+
warnings: [],
|
|
211
|
+
resolvedPath: filePath,
|
|
212
|
+
summary: null
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
190
216
|
async function validateDatasourceFile(filePathOrKey) {
|
|
191
217
|
if (!filePathOrKey || typeof filePathOrKey !== 'string') {
|
|
192
218
|
throw new Error('File path is required and must be a string');
|
|
@@ -194,19 +220,11 @@ async function validateDatasourceFile(filePathOrKey) {
|
|
|
194
220
|
|
|
195
221
|
const filePath = resolveValidateInputPath(filePathOrKey.trim());
|
|
196
222
|
|
|
197
|
-
const content = fs.readFileSync(filePath, 'utf8');
|
|
198
223
|
let parsed;
|
|
199
|
-
|
|
200
224
|
try {
|
|
201
|
-
parsed =
|
|
225
|
+
parsed = loadConfigFile(filePath);
|
|
202
226
|
} catch (error) {
|
|
203
|
-
return
|
|
204
|
-
valid: false,
|
|
205
|
-
errors: [`Invalid JSON syntax: ${error.message}`],
|
|
206
|
-
warnings: [],
|
|
207
|
-
resolvedPath: filePath,
|
|
208
|
-
summary: null
|
|
209
|
-
};
|
|
227
|
+
return buildParseFailureResult(filePath, error);
|
|
210
228
|
}
|
|
211
229
|
|
|
212
230
|
const summary = buildDatasourceValidateSummary(parsed);
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Poll helpers for environment deploy status (deployment-by-ID).
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Parse pipeline/environments deployment poll responses and fail fast on terminal HTTP errors
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const TERMINAL_POLL_HTTP_STATUSES = new Set([400, 401, 403, 404, 410, 422]);
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param {Object|null|undefined} response - API client response
|
|
13
|
+
* @returns {boolean}
|
|
14
|
+
*/
|
|
15
|
+
function isTerminalPollApiResponse(response) {
|
|
16
|
+
return Boolean(
|
|
17
|
+
response &&
|
|
18
|
+
response.success === false &&
|
|
19
|
+
typeof response.status === 'number' &&
|
|
20
|
+
TERMINAL_POLL_HTTP_STATUSES.has(response.status)
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @param {Object|null|undefined} response - Successful API client response
|
|
26
|
+
* @returns {Object|null} Deployment record or null
|
|
27
|
+
*/
|
|
28
|
+
function extractDeploymentRecord(response) {
|
|
29
|
+
if (!response || response.success === false) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
if (response?.data?.data) {
|
|
33
|
+
return response.data.data;
|
|
34
|
+
}
|
|
35
|
+
if (response?.data && typeof response.data === 'object' && response.data.status) {
|
|
36
|
+
return response.data;
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {Object|null|undefined} pipelineRes
|
|
43
|
+
* @param {Object|null|undefined} envRes
|
|
44
|
+
* @returns {Error}
|
|
45
|
+
*/
|
|
46
|
+
/**
|
|
47
|
+
* @param {string} requestedEnvKey
|
|
48
|
+
* @param {Error} error
|
|
49
|
+
* @returns {Error}
|
|
50
|
+
*/
|
|
51
|
+
function enrichPollTerminalError(requestedEnvKey, error) {
|
|
52
|
+
if (!error?.pollTerminal || error.status !== 404) {
|
|
53
|
+
return error;
|
|
54
|
+
}
|
|
55
|
+
const base = error.message || '';
|
|
56
|
+
if (!base.includes('Environment with key')) {
|
|
57
|
+
return error;
|
|
58
|
+
}
|
|
59
|
+
error.message =
|
|
60
|
+
`${base}\n\n` +
|
|
61
|
+
'The deployment may have been created under a different environment key ' +
|
|
62
|
+
'(for example evaluation-mode fallback to miso). Check controller logs for ' +
|
|
63
|
+
`effectiveEnvironmentKey, register '${requestedEnvKey}' in the controller, or run ` +
|
|
64
|
+
'aifabrix env deploy miso.';
|
|
65
|
+
return error;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function buildPollStatusError(pipelineRes, envRes) {
|
|
69
|
+
const terminal = [pipelineRes, envRes].filter(isTerminalPollApiResponse);
|
|
70
|
+
const source = terminal[0] || pipelineRes || envRes;
|
|
71
|
+
const message = source?.formattedError || source?.error || 'Unable to retrieve deployment status';
|
|
72
|
+
const err = new Error(message);
|
|
73
|
+
err.pollTerminal = true;
|
|
74
|
+
if (typeof source?.status === 'number') {
|
|
75
|
+
err.status = source.status;
|
|
76
|
+
}
|
|
77
|
+
return err;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Fetches deployment status by ID (pipeline endpoint first, then environments).
|
|
82
|
+
*
|
|
83
|
+
* @async
|
|
84
|
+
* @param {Function} getPipelineDeployment - pipeline.api getPipelineDeployment
|
|
85
|
+
* @param {Function} getDeployment - deployments.api getDeployment
|
|
86
|
+
* @param {string} controllerUrl
|
|
87
|
+
* @param {string} envKey
|
|
88
|
+
* @param {string} deploymentId
|
|
89
|
+
* @param {Object} apiAuthConfig
|
|
90
|
+
* @returns {Promise<Object|null>} Deployment record or null when status is not yet available (retry)
|
|
91
|
+
* @throws {Error} When both endpoints return a terminal HTTP error (e.g. environment not found)
|
|
92
|
+
*/
|
|
93
|
+
async function fetchDeploymentStatusById(
|
|
94
|
+
getPipelineDeployment,
|
|
95
|
+
getDeployment,
|
|
96
|
+
controllerUrl,
|
|
97
|
+
envKey,
|
|
98
|
+
deploymentId,
|
|
99
|
+
apiAuthConfig
|
|
100
|
+
) {
|
|
101
|
+
let pipelineRes;
|
|
102
|
+
let envRes;
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
pipelineRes = await getPipelineDeployment(controllerUrl, envKey, deploymentId, apiAuthConfig);
|
|
106
|
+
const fromPipeline = extractDeploymentRecord(pipelineRes);
|
|
107
|
+
if (fromPipeline) {
|
|
108
|
+
return fromPipeline;
|
|
109
|
+
}
|
|
110
|
+
} catch (err) {
|
|
111
|
+
pipelineRes = { success: false, error: err?.message || String(err) };
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
envRes = await getDeployment(controllerUrl, envKey, deploymentId, apiAuthConfig);
|
|
116
|
+
const fromEnv = extractDeploymentRecord(envRes);
|
|
117
|
+
if (fromEnv) {
|
|
118
|
+
return fromEnv;
|
|
119
|
+
}
|
|
120
|
+
} catch (err) {
|
|
121
|
+
envRes = { success: false, error: err?.message || String(err) };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (isTerminalPollApiResponse(pipelineRes) || isTerminalPollApiResponse(envRes)) {
|
|
125
|
+
throw buildPollStatusError(pipelineRes, envRes);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
module.exports = {
|
|
132
|
+
TERMINAL_POLL_HTTP_STATUSES,
|
|
133
|
+
isTerminalPollApiResponse,
|
|
134
|
+
extractDeploymentRecord,
|
|
135
|
+
enrichPollTerminalError,
|
|
136
|
+
buildPollStatusError,
|
|
137
|
+
fetchDeploymentStatusById
|
|
138
|
+
};
|
|
@@ -25,6 +25,7 @@ const {
|
|
|
25
25
|
buildEnvironmentConfigFromPreset,
|
|
26
26
|
loadAndValidateEnvironmentDeployConfig
|
|
27
27
|
} = require('./environment-config');
|
|
28
|
+
const { fetchDeploymentStatusById, enrichPollTerminalError } = require('./environment-poll-status');
|
|
28
29
|
|
|
29
30
|
/**
|
|
30
31
|
* Validates environment deployment prerequisites
|
|
@@ -161,31 +162,24 @@ async function sendEnvironmentDeployment(controllerUrl, envKey, authConfig, opti
|
|
|
161
162
|
}
|
|
162
163
|
|
|
163
164
|
/**
|
|
164
|
-
* Fetches deployment status by ID (pipeline endpoint first, then environments)
|
|
165
|
-
* Mirrors miso-controller manual test: GET pipeline/deployments/:id then GET environments/deployments/:id
|
|
165
|
+
* Fetches deployment status by ID (pipeline endpoint first, then environments).
|
|
166
166
|
* @async
|
|
167
167
|
* @param {string} controllerUrl - Controller URL
|
|
168
168
|
* @param {string} envKey - Environment key
|
|
169
169
|
* @param {string} deploymentId - Deployment ID
|
|
170
170
|
* @param {Object} apiAuthConfig - Auth config { type: 'bearer', token }
|
|
171
|
-
* @returns {Promise<Object|null>} Deployment record
|
|
171
|
+
* @returns {Promise<Object|null>} Deployment record or null when still in progress
|
|
172
|
+
* @throws {Error} On terminal poll errors (e.g. environment or deployment not found)
|
|
172
173
|
*/
|
|
173
174
|
async function getDeploymentStatusById(controllerUrl, envKey, deploymentId, apiAuthConfig) {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
const envRes = await getDeployment(controllerUrl, envKey, deploymentId, apiAuthConfig);
|
|
183
|
-
if (envRes?.data?.data) return envRes.data.data;
|
|
184
|
-
if (envRes?.data && typeof envRes.data === 'object' && envRes.data.status) return envRes.data;
|
|
185
|
-
} catch {
|
|
186
|
-
// Ignore
|
|
187
|
-
}
|
|
188
|
-
return null;
|
|
175
|
+
return fetchDeploymentStatusById(
|
|
176
|
+
getPipelineDeployment,
|
|
177
|
+
getDeployment,
|
|
178
|
+
controllerUrl,
|
|
179
|
+
envKey,
|
|
180
|
+
deploymentId,
|
|
181
|
+
apiAuthConfig
|
|
182
|
+
);
|
|
189
183
|
}
|
|
190
184
|
|
|
191
185
|
/**
|
|
@@ -218,6 +212,33 @@ function processDeploymentStatusResponse(deployment, validatedEnvKey) {
|
|
|
218
212
|
return null;
|
|
219
213
|
}
|
|
220
214
|
|
|
215
|
+
/**
|
|
216
|
+
* @param {number} attempt
|
|
217
|
+
* @param {number} maxAttempts
|
|
218
|
+
* @param {Object|null} deployment
|
|
219
|
+
*/
|
|
220
|
+
function logPollAttemptProgress(attempt, maxAttempts, deployment) {
|
|
221
|
+
const progress = deployment?.progress ?? 0;
|
|
222
|
+
const statusLabel = deployment?.status ?? 'pending';
|
|
223
|
+
logger.log(chalk.gray(` Attempt ${attempt}/${maxAttempts}... Status: ${statusLabel} (${progress}%)`));
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* @param {Error} error
|
|
228
|
+
* @param {string} validatedEnvKey
|
|
229
|
+
* @throws {Error}
|
|
230
|
+
*/
|
|
231
|
+
function handlePollIterationError(error, validatedEnvKey) {
|
|
232
|
+
const msg = error?.message || '';
|
|
233
|
+
const isDeploymentFailed =
|
|
234
|
+
msg.includes('Environment deployment failed') ||
|
|
235
|
+
(msg.includes('failed') && !error.pollTerminal);
|
|
236
|
+
if (error.pollTerminal || isDeploymentFailed) {
|
|
237
|
+
throw enrichPollTerminalError(validatedEnvKey, error);
|
|
238
|
+
}
|
|
239
|
+
logger.log(chalk.yellow(` ⚠ Status check failed (will retry): ${msg}`));
|
|
240
|
+
}
|
|
241
|
+
|
|
221
242
|
/**
|
|
222
243
|
* Polls environment deployment status
|
|
223
244
|
* @async
|
|
@@ -231,44 +252,31 @@ function processDeploymentStatusResponse(deployment, validatedEnvKey) {
|
|
|
231
252
|
async function pollEnvironmentStatus(deploymentId, controllerUrl, envKey, authConfig, options = {}) {
|
|
232
253
|
const validatedUrl = validateControllerUrl(controllerUrl);
|
|
233
254
|
const validatedEnvKey = validateEnvironmentKey(envKey);
|
|
234
|
-
|
|
235
255
|
const pollInterval = options.pollInterval || 5000;
|
|
236
256
|
const maxAttempts = options.maxAttempts || 60;
|
|
257
|
+
const apiAuthConfig = { type: 'bearer', token: authConfig.token };
|
|
237
258
|
|
|
238
259
|
logger.log(chalk.blue(`⏳ Polling environment status (${pollInterval}ms intervals)...`));
|
|
239
260
|
|
|
240
|
-
// Use centralized API client
|
|
241
|
-
const apiAuthConfig = { type: 'bearer', token: authConfig.token };
|
|
242
|
-
|
|
243
261
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
244
262
|
try {
|
|
245
263
|
await new Promise(resolve => setTimeout(resolve, pollInterval));
|
|
246
|
-
|
|
247
264
|
const deployment = await getDeploymentStatusById(
|
|
248
265
|
validatedUrl,
|
|
249
266
|
validatedEnvKey,
|
|
250
267
|
deploymentId,
|
|
251
268
|
apiAuthConfig
|
|
252
269
|
);
|
|
253
|
-
|
|
254
|
-
const statusLabel = deployment?.status ?? 'pending';
|
|
255
|
-
if (attempt <= maxAttempts) {
|
|
256
|
-
logger.log(chalk.gray(` Attempt ${attempt}/${maxAttempts}... Status: ${statusLabel} (${progress}%)`));
|
|
257
|
-
}
|
|
270
|
+
logPollAttemptProgress(attempt, maxAttempts, deployment);
|
|
258
271
|
const statusResult = processDeploymentStatusResponse(deployment, validatedEnvKey);
|
|
259
272
|
if (statusResult) {
|
|
260
273
|
return statusResult;
|
|
261
274
|
}
|
|
262
275
|
} catch (error) {
|
|
263
|
-
|
|
264
|
-
if (error.message && error.message.includes('failed')) {
|
|
265
|
-
throw error;
|
|
266
|
-
}
|
|
267
|
-
// Otherwise, continue polling
|
|
276
|
+
handlePollIterationError(error, validatedEnvKey);
|
|
268
277
|
}
|
|
269
278
|
}
|
|
270
279
|
|
|
271
|
-
// Timeout
|
|
272
280
|
throw new Error(`Environment deployment timeout after ${maxAttempts} attempts. Check controller logs for status.`);
|
|
273
281
|
}
|
|
274
282
|
|
|
@@ -8,8 +8,90 @@
|
|
|
8
8
|
* @version 2.0.0
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
const {
|
|
12
|
+
formatSuccessLine,
|
|
13
|
+
formatSuccessParagraph,
|
|
14
|
+
sectionTitle,
|
|
15
|
+
headerKeyValue
|
|
16
|
+
} = require('../utils/cli-test-layout-chalk');
|
|
17
|
+
const logger = require('../utils/logger');
|
|
11
18
|
const { generateExternalReadmeContent } = require('../utils/external-readme');
|
|
12
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Validates system type from downloaded application
|
|
22
|
+
* @param {Object} application - External system configuration
|
|
23
|
+
* @returns {string} System type (openapi, mcp, custom)
|
|
24
|
+
*/
|
|
25
|
+
function validateSystemType(application) {
|
|
26
|
+
if (!application || typeof application !== 'object') {
|
|
27
|
+
throw new Error('Application configuration is required');
|
|
28
|
+
}
|
|
29
|
+
const validTypes = ['openapi', 'mcp', 'custom'];
|
|
30
|
+
const systemType = application.type;
|
|
31
|
+
if (!systemType || !validTypes.includes(systemType)) {
|
|
32
|
+
throw new Error(`Invalid system type: ${systemType}. Must be one of: ${validTypes.join(', ')}`);
|
|
33
|
+
}
|
|
34
|
+
return systemType;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function validateApplicationConfig(application) {
|
|
38
|
+
if (!application || typeof application !== 'object') {
|
|
39
|
+
throw new Error('Application configuration is required');
|
|
40
|
+
}
|
|
41
|
+
if (!application.key || typeof application.key !== 'string') {
|
|
42
|
+
throw new Error('Application key is required');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function validateDatasourceConfig(datasource, applicationKey) {
|
|
47
|
+
if (!datasource.key || typeof datasource.key !== 'string') {
|
|
48
|
+
throw new Error('Datasource key is required for all datasources');
|
|
49
|
+
}
|
|
50
|
+
if (!datasource.systemKey || typeof datasource.systemKey !== 'string') {
|
|
51
|
+
throw new Error('Datasource systemKey is required for all datasources');
|
|
52
|
+
}
|
|
53
|
+
if (datasource.systemKey !== applicationKey) {
|
|
54
|
+
throw new Error(
|
|
55
|
+
`Datasource systemKey (${datasource.systemKey}) does not match application key (${applicationKey})`
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function validateDownloadedData(application, dataSources) {
|
|
61
|
+
validateApplicationConfig(application);
|
|
62
|
+
if (!Array.isArray(dataSources)) {
|
|
63
|
+
throw new Error('DataSources must be an array');
|
|
64
|
+
}
|
|
65
|
+
for (const datasource of dataSources) {
|
|
66
|
+
validateDatasourceConfig(datasource, application.key);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function logDownloadCommandHeader(systemKey) {
|
|
71
|
+
logger.log('');
|
|
72
|
+
logger.log(sectionTitle('Download'));
|
|
73
|
+
logger.log(headerKeyValue('System:', systemKey));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function displayDownloadSuccess(systemKey, finalPath, datasourceCount) {
|
|
77
|
+
logger.log(
|
|
78
|
+
formatSuccessParagraph(
|
|
79
|
+
`Downloaded ${systemKey} (${datasourceCount} datasource${datasourceCount === 1 ? '' : 's'})`
|
|
80
|
+
)
|
|
81
|
+
);
|
|
82
|
+
logger.log(headerKeyValue('Location:', finalPath));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async function runConvertToJsonIfRequested(systemKey) {
|
|
86
|
+
const { runConvert } = require('../commands/convert');
|
|
87
|
+
try {
|
|
88
|
+
await runConvert(systemKey, { format: 'json', force: true });
|
|
89
|
+
logger.log(formatSuccessLine('Converted component files to JSON'));
|
|
90
|
+
} catch (convertErr) {
|
|
91
|
+
throw new Error(`Download succeeded but convert to JSON failed: ${convertErr.message}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
13
95
|
/**
|
|
14
96
|
* Generates application.yaml content for downloaded system
|
|
15
97
|
* @param {string} systemKey - System key
|
|
@@ -90,6 +172,11 @@ function generateReadme(systemKey, application, dataSources) {
|
|
|
90
172
|
}
|
|
91
173
|
|
|
92
174
|
module.exports = {
|
|
175
|
+
validateSystemType,
|
|
176
|
+
validateDownloadedData,
|
|
177
|
+
logDownloadCommandHeader,
|
|
178
|
+
displayDownloadSuccess,
|
|
179
|
+
runConvertToJsonIfRequested,
|
|
93
180
|
generateVariablesYaml,
|
|
94
181
|
generateReadme
|
|
95
182
|
};
|