@aifabrix/builder 2.42.1 → 2.44.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/anchor-docs.mdc +15 -0
- package/README.md +2 -2
- package/anchor-docs/README.md +10 -0
- package/anchor-docs/_TEMPLATE +24 -0
- package/bin/aifabrix.js +13 -4
- package/integration/hubspot-test/README.md +157 -0
- package/integration/{hubspot → hubspot-test}/application.json +6 -6
- package/integration/{hubspot → hubspot-test}/create-hubspot.js +10 -10
- package/integration/hubspot-test/env.template +4 -0
- package/integration/hubspot-test/hubspot-test-datasource-company.json +138 -0
- package/integration/hubspot-test/hubspot-test-datasource-contact.json +146 -0
- package/integration/hubspot-test/hubspot-test-datasource-deal.json +146 -0
- package/integration/hubspot-test/hubspot-test-datasource-users.json +76 -0
- package/integration/{hubspot/hubspot-deploy.json → hubspot-test/hubspot-test-deploy.json} +201 -24
- package/integration/{hubspot/hubspot-system.json → hubspot-test/hubspot-test-system.json} +8 -7
- package/integration/hubspot-test/rbac.json +166 -0
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-hubspot-credential-real.yaml +3 -3
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-hubspot-env-vars.yaml +2 -2
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-add-datasource.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-credential-create.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-credential-select.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-known-platform.yaml +1 -1
- package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-source.yaml +2 -0
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-mode.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-openapi-file.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-openapi-url.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-source.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-dimension-array-test.yaml +1 -1
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-key-test.yaml +5 -0
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-path-test.yaml +5 -0
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-dimension-test.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-rbac-test.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-rbac-yaml-test.yaml +1 -1
- package/integration/{hubspot → hubspot-test}/test-dataplane-down-tests.js +1 -7
- package/integration/{hubspot → hubspot-test}/test-dataplane-down.js +3 -3
- package/integration/{hubspot → hubspot-test}/test.js +137 -102
- package/integration/{hubspot → hubspot-test}/wizard-hubspot-e2e.yaml +2 -2
- package/integration/{hubspot → hubspot-test}/wizard-hubspot-platform.yaml +1 -1
- package/integration/hubspot-test/wizard-hubspot-test-headless.yaml +23 -0
- package/integration/roundtrip-test-local/README.md +144 -0
- package/integration/roundtrip-test-local/application.yaml +13 -0
- package/integration/roundtrip-test-local/env.template +15 -0
- package/integration/roundtrip-test-local/roundtrip-test-local-datasource-roundtrip-test-company.yaml +14 -0
- package/integration/roundtrip-test-local/roundtrip-test-local-deploy.json +61 -0
- package/integration/roundtrip-test-local/roundtrip-test-local-system.yaml +25 -0
- package/integration/roundtrip-test-local2/README.md +144 -0
- package/integration/roundtrip-test-local2/application.yaml +13 -0
- package/integration/roundtrip-test-local2/env.template +15 -0
- package/integration/roundtrip-test-local2/roundtrip-test-local2-datasource-company.yaml +31 -0
- package/integration/roundtrip-test-local2/roundtrip-test-local2-deploy.json +86 -0
- package/integration/roundtrip-test-local2/roundtrip-test-local2-system.yaml +25 -0
- package/integration/test/wizard.yaml +8 -0
- package/jest.config.default.js +10 -0
- package/jest.config.integration.fixtures.js +22 -0
- package/jest.config.integration.js +21 -18
- package/jest.config.isolated.js +10 -0
- package/jest.projects.js +288 -0
- package/lib/api/datasources-core.api.js +3 -3
- package/lib/api/dev-mtls-request.js +110 -0
- package/lib/api/dev-server-https.js +145 -0
- package/lib/api/dev.api.js +133 -144
- package/lib/api/index.js +0 -1
- package/lib/api/pipeline.api.js +67 -20
- package/lib/api/service-users.api.js +111 -2
- package/lib/api/types/dev.types.js +4 -3
- package/lib/api/types/pipeline.types.js +8 -5
- package/lib/api/types/service-users.types.js +41 -0
- package/lib/api/types/validation-run.types.js +56 -0
- package/lib/api/validation-run.api.js +99 -0
- package/lib/api/validation-runner.js +99 -0
- package/lib/app/config.js +1 -1
- package/lib/app/deploy-status-display.js +2 -2
- package/lib/app/deploy.js +7 -6
- package/lib/app/display.js +2 -1
- package/lib/app/dockerfile.js +3 -2
- package/lib/app/down.js +2 -1
- package/lib/app/helpers.js +6 -5
- package/lib/app/index.js +27 -8
- package/lib/app/list.js +7 -6
- package/lib/app/push.js +4 -3
- package/lib/app/register.js +19 -8
- package/lib/app/rotate-secret.js +17 -13
- package/lib/app/run-container-start.js +184 -0
- package/lib/app/run-docker-fallback.js +108 -0
- package/lib/app/run-env-compose.js +30 -42
- package/lib/app/run-helpers.js +49 -126
- package/lib/app/run-infra-requirements.js +30 -0
- package/lib/app/run-resolve-image.js +21 -0
- package/lib/app/run.js +74 -21
- package/lib/app/show-display.js +1 -1
- package/lib/app/show.js +1 -1
- package/lib/build/index.js +13 -10
- package/lib/cli/index.js +2 -0
- package/lib/cli/setup-app.help.js +67 -0
- package/lib/cli/setup-app.js +59 -123
- package/lib/cli/setup-app.test-commands.js +179 -0
- package/lib/cli/setup-auth.js +36 -14
- package/lib/cli/setup-credential-deployment.js +22 -8
- package/lib/cli/setup-dev-path-commands.js +124 -0
- package/lib/cli/setup-dev.js +190 -103
- package/lib/cli/setup-environment.js +11 -20
- package/lib/cli/setup-external-system.js +62 -22
- package/lib/cli/setup-infra.js +139 -47
- package/lib/cli/setup-parameters.js +32 -0
- package/lib/cli/setup-secrets.js +147 -10
- package/lib/cli/setup-service-user.js +146 -20
- package/lib/cli/setup-utility.js +47 -19
- package/lib/commands/app-down.js +5 -7
- package/lib/commands/app-install.js +14 -7
- package/lib/commands/app-logs.js +13 -10
- package/lib/commands/app-shell.js +4 -1
- package/lib/commands/app-test.js +25 -19
- package/lib/commands/app.js +22 -10
- package/lib/commands/auth-config.js +10 -14
- package/lib/commands/auth-status.js +4 -3
- package/lib/commands/credential-env.js +4 -3
- package/lib/commands/credential-list.js +5 -4
- package/lib/commands/credential-push.js +4 -3
- package/lib/commands/datasource-unified-test-cli.js +495 -0
- package/lib/commands/datasource-unified-test-cli.options.js +149 -0
- package/lib/commands/datasource-validation-cli.js +129 -0
- package/lib/commands/datasource.js +123 -71
- package/lib/commands/deployment-list.js +6 -5
- package/lib/commands/dev-cli-handlers.js +122 -18
- package/lib/commands/dev-down.js +4 -3
- package/lib/commands/dev-init.js +231 -116
- package/lib/commands/dev-show-display.js +473 -0
- package/lib/commands/login-credentials.js +3 -2
- package/lib/commands/login-device.js +4 -3
- package/lib/commands/login.js +5 -4
- package/lib/commands/logout.js +8 -7
- package/lib/commands/parameters-validate.js +54 -0
- package/lib/commands/repair-datasource.js +314 -68
- package/lib/commands/repair-env-template.js +16 -10
- package/lib/commands/repair-rbac.js +25 -19
- package/lib/commands/repair.js +116 -32
- package/lib/commands/secrets-list.js +23 -12
- package/lib/commands/secrets-remove-all.js +220 -0
- package/lib/commands/secrets-remove.js +22 -13
- package/lib/commands/secrets-set.js +21 -12
- package/lib/commands/secrets-validate.js +20 -7
- package/lib/commands/secure.js +10 -9
- package/lib/commands/service-user.js +243 -13
- package/lib/commands/test-e2e-external.js +27 -1
- package/lib/commands/up-common.js +28 -2
- package/lib/commands/up-dataplane.js +31 -18
- package/lib/commands/up-miso.js +19 -29
- package/lib/commands/upload.js +138 -39
- package/lib/commands/wizard-core-helpers.js +1 -1
- package/lib/commands/wizard-dataplane.js +4 -3
- package/lib/commands/wizard-helpers.js +3 -3
- package/lib/commands/wizard.js +2 -2
- package/lib/core/admin-secrets.js +16 -5
- package/lib/core/audit-logger.js +12 -4
- package/lib/core/config-attach-extensions.js +46 -0
- package/lib/core/config-runtime-paths.js +29 -0
- package/lib/core/config.js +59 -58
- package/lib/core/diff.js +3 -2
- package/lib/core/ensure-encryption-key.js +2 -4
- package/lib/core/secrets-ensure-infra.js +77 -0
- package/lib/core/secrets-ensure.js +120 -64
- package/lib/core/secrets-env-write.js +35 -7
- package/lib/core/secrets-infra-placeholder-sync.js +61 -0
- package/lib/core/secrets.js +228 -42
- package/lib/core/templates-env.js +4 -3
- package/lib/core/templates.js +1 -1
- package/lib/datasource/abac-validator.js +148 -0
- package/lib/datasource/deploy.js +75 -53
- package/lib/datasource/field-reference-validator.js +77 -36
- package/lib/datasource/integration-context.js +63 -0
- package/lib/datasource/list.js +8 -7
- package/lib/datasource/log-viewer.js +252 -0
- package/lib/datasource/resolve-app.js +109 -0
- package/lib/datasource/test-e2e.js +95 -155
- package/lib/datasource/test-integration.js +121 -109
- package/lib/datasource/unified-validation-run-body.js +65 -0
- package/lib/datasource/unified-validation-run-post.js +23 -0
- package/lib/datasource/unified-validation-run-resolve.js +43 -0
- package/lib/datasource/unified-validation-run.js +92 -0
- package/lib/datasource/validate.js +162 -15
- package/lib/deployment/deployer.js +4 -3
- package/lib/deployment/environment.js +7 -6
- package/lib/deployment/push.js +17 -8
- package/lib/external-system/delete.js +4 -3
- package/lib/external-system/deploy.js +131 -53
- package/lib/external-system/download-helpers.js +1 -1
- package/lib/external-system/download.js +7 -6
- package/lib/external-system/generator.js +104 -14
- package/lib/external-system/integration-test-dispatch.js +26 -0
- package/lib/external-system/test-execution.js +5 -1
- package/lib/external-system/test-helpers.js +0 -4
- package/lib/external-system/test-system-level-helpers.js +110 -0
- package/lib/external-system/test-system-level.js +83 -44
- package/lib/external-system/test.js +59 -8
- package/lib/generator/builders.js +23 -11
- package/lib/generator/deploy-manifest-azure-kv.js +81 -0
- package/lib/generator/external-controller-manifest.js +3 -3
- package/lib/generator/external.js +23 -11
- package/lib/generator/helpers.js +71 -12
- package/lib/generator/index.js +8 -4
- package/lib/generator/split-readme.js +12 -7
- package/lib/generator/split-variables.js +2 -1
- package/lib/generator/split.js +46 -11
- package/lib/generator/wizard-readme.js +3 -3
- package/lib/generator/wizard.js +16 -13
- package/lib/infrastructure/compose.js +60 -6
- package/lib/infrastructure/helpers.js +238 -51
- package/lib/infrastructure/index.js +64 -37
- package/lib/infrastructure/services.js +21 -15
- package/lib/internal/fs-real-sync.js +104 -0
- package/lib/internal/node-fs.js +98 -0
- package/lib/parameters/database-secret-values.js +173 -0
- package/lib/parameters/infra-kv-discovery.js +121 -0
- package/lib/parameters/infra-parameter-catalog.js +458 -0
- package/lib/parameters/infra-parameter-validate.js +64 -0
- package/lib/schema/application-schema.json +37 -17
- package/lib/schema/datasource-test-run.schema.json +493 -0
- package/lib/schema/deployment-rules.yaml +102 -63
- package/lib/schema/external-datasource.schema.json +1201 -433
- package/lib/schema/external-system.schema.json +181 -5
- package/lib/schema/flag-map-validation-run.json +31 -0
- package/lib/schema/infra-parameter.schema.json +106 -0
- package/lib/schema/infra.parameter.yaml +421 -0
- package/lib/schema/type/credential-auth-templates.json +40 -0
- package/lib/schema/type/document-storage.json +213 -0
- package/lib/schema/type/message-service.json +123 -0
- package/lib/schema/type/vector-store.json +88 -0
- package/lib/utils/aifabrix-runtime-config-dir.js +132 -0
- package/lib/utils/api-error-handler.js +2 -2
- package/lib/utils/api.js +49 -14
- package/lib/utils/app-config-resolver.js +23 -1
- package/lib/utils/app-register-api.js +3 -2
- package/lib/utils/app-register-auth.js +1 -1
- package/lib/utils/app-register-config.js +4 -4
- package/lib/utils/app-register-display.js +3 -2
- package/lib/utils/app-register-validator.js +3 -2
- package/lib/utils/app-run-containers.js +26 -22
- package/lib/utils/app-scoped-config.js +31 -0
- package/lib/utils/app-service-env-from-builder.js +164 -0
- package/lib/utils/build-copy.js +1 -1
- package/lib/utils/build-helpers.js +20 -20
- package/lib/utils/build-resolve-image.js +165 -0
- package/lib/utils/cli-layout-chalk.js +8 -0
- package/lib/utils/cli-test-layout-chalk.js +267 -0
- package/lib/utils/cli-utils.js +88 -11
- package/lib/utils/compose-db-passwords.js +138 -0
- package/lib/utils/compose-generate-docker-compose.js +216 -0
- package/lib/utils/compose-generator.js +197 -291
- package/lib/utils/compose-miso-env.js +18 -0
- package/lib/utils/compose-traefik-ingress-base.js +158 -0
- package/lib/utils/config-paths.js +209 -6
- package/lib/utils/config-scoped-resources-preference.js +41 -0
- package/lib/utils/controller-deployment-outcome.js +68 -0
- package/lib/utils/credential-display.js +2 -2
- package/lib/utils/credential-secrets-env.js +16 -1
- package/lib/utils/dataplane-pipeline-warning.js +4 -3
- package/lib/utils/datasource-test-run-capability-scope.js +43 -0
- package/lib/utils/datasource-test-run-debug-display.js +137 -0
- package/lib/utils/datasource-test-run-debug-slice.js +93 -0
- package/lib/utils/datasource-test-run-display.js +442 -0
- package/lib/utils/datasource-test-run-exit.js +58 -0
- package/lib/utils/datasource-test-run-legacy-adapter.js +93 -0
- package/lib/utils/datasource-test-run-report-version.js +51 -0
- package/lib/utils/datasource-test-run-schema-sync.js +59 -0
- package/lib/utils/datasource-test-run-tty-log.js +81 -0
- package/lib/utils/datasource-validation-watch.js +266 -0
- package/lib/utils/declarative-url-ports.js +47 -0
- package/lib/utils/derive-env-key-from-client-id.js +41 -0
- package/lib/utils/dev-ca-install.js +185 -23
- package/lib/utils/dev-cert-helper.js +266 -17
- package/lib/utils/dev-hosts-helper.js +307 -0
- package/lib/utils/dev-init-cert-hints.js +37 -0
- package/lib/utils/dev-init-health-messages.js +52 -0
- package/lib/utils/dev-init-resolve.js +86 -0
- package/lib/utils/dev-init-ssh-merge.js +65 -0
- package/lib/utils/dev-ssh-config-helper.js +196 -0
- package/lib/utils/dev-user-groups.js +93 -0
- package/lib/utils/docker-build.js +42 -17
- package/lib/utils/docker-exec.js +28 -0
- package/lib/utils/docker-manifest-public-port.js +116 -0
- package/lib/utils/docker-not-running-hint.js +52 -0
- package/lib/utils/docker.js +98 -11
- package/lib/utils/ensure-dev-certs-for-remote-docker.js +192 -0
- package/lib/utils/env-config-loader.js +10 -91
- package/lib/utils/env-copy.js +19 -10
- package/lib/utils/env-map.js +42 -11
- package/lib/utils/env-template.js +2 -2
- package/lib/utils/environment-scoped-resources.js +144 -0
- package/lib/utils/error-formatter.js +125 -9
- package/lib/utils/error-formatters/http-status-errors.js +6 -5
- package/lib/utils/error-formatters/network-errors.js +2 -1
- package/lib/utils/error-formatters/permission-errors.js +2 -1
- package/lib/utils/error-formatters/validation-errors.js +2 -1
- package/lib/utils/external-env-template.js +180 -0
- package/lib/utils/external-readme.js +8 -1
- package/lib/utils/external-system-display.js +277 -136
- package/lib/utils/external-system-local-test-tty.js +389 -0
- package/lib/utils/external-system-readiness-core.js +377 -0
- package/lib/utils/external-system-readiness-deploy-display.js +270 -0
- package/lib/utils/external-system-readiness-display-internals.js +150 -0
- package/lib/utils/external-system-readiness-display.js +186 -0
- package/lib/utils/external-system-test-helpers.js +24 -6
- package/lib/utils/external-system-validators.js +32 -14
- package/lib/utils/health-check-url.js +119 -0
- package/lib/utils/health-check.js +59 -25
- package/lib/utils/help-builder.js +14 -13
- package/lib/utils/image-version.js +4 -8
- package/lib/utils/infra-containers.js +4 -7
- package/lib/utils/infra-env-defaults.js +162 -0
- package/lib/utils/infra-status-display.js +167 -0
- package/lib/utils/infra-status.js +16 -8
- package/lib/utils/local-secrets.js +29 -7
- package/lib/utils/paths.js +136 -48
- package/lib/utils/port-resolver.js +10 -23
- package/lib/utils/redis-env-scope.js +62 -0
- package/lib/utils/register-aifabrix-shell-env.js +204 -0
- package/lib/utils/remote-builder-validation.js +99 -0
- package/lib/utils/remote-dev-auth.js +117 -21
- package/lib/utils/remote-docker-env.js +67 -15
- package/lib/utils/remote-secrets-loader.js +13 -4
- package/lib/utils/resolve-docker-image-ref.js +124 -0
- package/lib/utils/schema-loader.js +22 -9
- package/lib/utils/secrets-bash-kv.js +25 -0
- package/lib/utils/secrets-generator.js +171 -51
- package/lib/utils/secrets-helpers.js +70 -59
- package/lib/utils/secrets-kv-scope.js +60 -0
- package/lib/utils/secrets-utils.js +35 -37
- package/lib/utils/secrets-validation.js +3 -1
- package/lib/utils/secrets-yaml-preserve.js +109 -0
- package/lib/utils/secure-file-permissions.js +91 -0
- package/lib/utils/ssh-key-helper.js +4 -2
- package/lib/utils/template-helpers.js +2 -2
- package/lib/utils/test-log-writer.js +3 -3
- package/lib/utils/token-manager.js +37 -5
- package/lib/utils/url-declarative-public-base.js +188 -0
- package/lib/utils/url-declarative-resolve-build.js +493 -0
- package/lib/utils/url-declarative-resolve-load-doc.js +51 -0
- package/lib/utils/url-declarative-resolve.js +220 -0
- package/lib/utils/url-declarative-token-parse.js +74 -0
- package/lib/utils/url-declarative-url-flags.js +50 -0
- package/lib/utils/url-declarative-vdir-inactive-env.js +99 -0
- package/lib/utils/url-public-path-prefix.js +34 -0
- package/lib/utils/urls-local-registry.js +220 -0
- package/lib/utils/validation-report-tty-kit.js +77 -0
- package/lib/utils/validation-run-poll.js +89 -0
- package/lib/utils/validation-run-post-retry.js +73 -0
- package/lib/utils/validation-run-request.js +98 -0
- package/lib/utils/variable-transformer.js +21 -4
- package/lib/utils/yaml-preserve.js +78 -1
- package/lib/validation/datasource-warnings.js +56 -0
- package/lib/validation/env-template-auth.js +50 -2
- package/lib/validation/external-manifest-validator.js +35 -7
- package/lib/validation/validate-display.js +37 -31
- package/lib/validation/validate.js +9 -10
- package/lib/validation/validator-unresolved-placeholders.js +98 -0
- package/lib/validation/validator.js +32 -78
- package/lib/validation/wizard-config-validator.js +2 -1
- package/package.json +11 -3
- package/scripts/check-datasource-test-run-schema-sync.js +34 -0
- package/scripts/diagnose-cli.js +150 -0
- package/scripts/install-local.js +304 -55
- package/templates/README.md +15 -2
- package/templates/applications/dataplane/application.yaml +52 -2
- package/templates/applications/dataplane/env.template +80 -18
- package/templates/applications/dataplane/rbac.yaml +8 -0
- package/templates/applications/keycloak/application.yaml +9 -1
- package/templates/applications/keycloak/env.template +15 -6
- package/templates/applications/miso-controller/application.yaml +10 -2
- package/templates/applications/miso-controller/env.template +55 -14
- package/templates/applications/miso-controller/rbac.yaml +5 -0
- package/templates/external-system/README.md.hbs +20 -7
- package/templates/external-system/deploy.js.hbs +5 -5
- package/templates/external-system/env.template.hbs +22 -0
- package/templates/external-system/external-datasource.yaml.hbs +197 -118
- package/templates/infra/compose.yaml.hbs +20 -4
- package/templates/python/docker-compose.hbs +16 -0
- package/templates/typescript/docker-compose.hbs +16 -0
- package/integration/hubspot/README.md +0 -102
- package/integration/hubspot/env.template +0 -4
- package/integration/hubspot/hubspot-datasource-company.json +0 -541
- package/integration/hubspot/hubspot-datasource-contact.json +0 -639
- package/integration/hubspot/hubspot-datasource-deal.json +0 -588
- package/integration/hubspot/hubspot-datasource-users.json +0 -116
- package/integration/hubspot/test-artifacts/wizard-invalid-missing-source.yaml +0 -2
- package/integration/hubspot/test-artifacts/wizard-valid-for-dimension-key-test.yaml +0 -5
- package/integration/hubspot/test-artifacts/wizard-valid-for-dimension-path-test.yaml +0 -5
- package/lib/api/external-test.api.js +0 -111
- package/lib/schema/env-config.yaml +0 -43
- /package/integration/{hubspot → hubspot-test}/companies.json +0 -0
- /package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-app-name.yaml +0 -0
- /package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-missing-app.yaml +0 -0
- /package/integration/{hubspot → hubspot-test}/test-dataplane-down-helpers.js +0 -0
package/lib/generator/helpers.js
CHANGED
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
const fs = require('fs');
|
|
12
|
-
const
|
|
12
|
+
const path = require('path');
|
|
13
13
|
const { loadConfigFile } = require('../utils/config-format');
|
|
14
|
+
const { urlTokenToKeyVaultSecretName } = require('./deploy-manifest-azure-kv');
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* Loads application config file (application.yaml, application.json, or legacy path) via converter.
|
|
@@ -37,21 +38,25 @@ function loadEnvTemplate(templatePath) {
|
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
/**
|
|
40
|
-
* Loads rbac.yaml
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* @
|
|
41
|
+
* Loads RBAC config file (rbac.yaml, rbac.yml, or rbac.json) if it exists.
|
|
42
|
+
* Uses loadConfigFile so format is inferred from extension.
|
|
43
|
+
*
|
|
44
|
+
* @param {string} rbacPath - Path to RBAC file (e.g. from resolveRbacPath)
|
|
45
|
+
* @returns {Object|null} Parsed RBAC configuration or null if path is falsy or file does not exist
|
|
46
|
+
* @throws {Error} If file exists but has invalid syntax (message references actual filename, e.g. rbac.json)
|
|
44
47
|
*/
|
|
45
48
|
function loadRbac(rbacPath) {
|
|
49
|
+
if (!rbacPath || typeof rbacPath !== 'string') {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
46
52
|
if (!fs.existsSync(rbacPath)) {
|
|
47
53
|
return null;
|
|
48
54
|
}
|
|
49
|
-
|
|
50
|
-
const rbacContent = fs.readFileSync(rbacPath, 'utf8');
|
|
51
55
|
try {
|
|
52
|
-
return
|
|
56
|
+
return loadConfigFile(rbacPath);
|
|
53
57
|
} catch (error) {
|
|
54
|
-
|
|
58
|
+
const basename = path.basename(rbacPath);
|
|
59
|
+
throw new Error(`Invalid syntax in ${basename}: ${error.message}`);
|
|
55
60
|
}
|
|
56
61
|
}
|
|
57
62
|
|
|
@@ -214,6 +219,9 @@ function determineVariableLocation(value, key) {
|
|
|
214
219
|
if (value.startsWith('kv://')) {
|
|
215
220
|
location = 'keyvault';
|
|
216
221
|
required = true;
|
|
222
|
+
} else if (value.startsWith('url://')) {
|
|
223
|
+
location = 'keyvault';
|
|
224
|
+
required = true;
|
|
217
225
|
}
|
|
218
226
|
|
|
219
227
|
// Check if it's a sensitive variable
|
|
@@ -225,6 +233,31 @@ function determineVariableLocation(value, key) {
|
|
|
225
233
|
return { location, required };
|
|
226
234
|
}
|
|
227
235
|
|
|
236
|
+
/**
|
|
237
|
+
* Maps env.template url:// value(s) to Key Vault secret name(s) for deploy JSON.
|
|
238
|
+
* Comma-separated lists are supported (e.g. CORS ALLOWED_ORIGINS): each segment
|
|
239
|
+
* starting with url:// is mapped; other segments are left unchanged (e.g. http://localhost:*).
|
|
240
|
+
*
|
|
241
|
+
* @param {string} appKey - application.yaml app.key
|
|
242
|
+
* @param {string} value - Full value after KEY= (must start with url:// for caller)
|
|
243
|
+
* @returns {string} Comma-joined secret names / literals
|
|
244
|
+
*/
|
|
245
|
+
function mapUrlTemplateValueToKeyVaultNames(appKey, value) {
|
|
246
|
+
const segments = value
|
|
247
|
+
.split(',')
|
|
248
|
+
.map((s) => s.trim())
|
|
249
|
+
.filter((s) => s.length > 0);
|
|
250
|
+
return segments
|
|
251
|
+
.map((seg) => {
|
|
252
|
+
if (seg.startsWith('url://')) {
|
|
253
|
+
const token = seg.slice('url://'.length).trim();
|
|
254
|
+
return urlTokenToKeyVaultSecretName(appKey, token);
|
|
255
|
+
}
|
|
256
|
+
return seg;
|
|
257
|
+
})
|
|
258
|
+
.join(',');
|
|
259
|
+
}
|
|
260
|
+
|
|
228
261
|
/**
|
|
229
262
|
* Creates a configuration item from parsed variable
|
|
230
263
|
* @function createConfigItem
|
|
@@ -233,12 +266,27 @@ function determineVariableLocation(value, key) {
|
|
|
233
266
|
* @param {string} location - Variable location
|
|
234
267
|
* @param {boolean} required - Whether variable is required
|
|
235
268
|
* @param {Map} portalInputMap - Map of portalInput configurations
|
|
269
|
+
* @param {string|null} appKey - application.yaml app.key (required when value uses url://)
|
|
236
270
|
* @returns {Object} Configuration item
|
|
237
271
|
*/
|
|
238
|
-
function createConfigItem(key, value, location, required, portalInputMap) {
|
|
272
|
+
function createConfigItem(key, value, location, required, portalInputMap, appKey) {
|
|
273
|
+
let storedValue = value;
|
|
274
|
+
if (location === 'keyvault') {
|
|
275
|
+
if (value.startsWith('kv://')) {
|
|
276
|
+
storedValue = value.replace('kv://', '');
|
|
277
|
+
} else if (value.startsWith('url://')) {
|
|
278
|
+
if (!appKey) {
|
|
279
|
+
throw new Error(
|
|
280
|
+
`Cannot resolve ${key}=${value}: application app.key is required to map url:// to a Key Vault secret name`
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
storedValue = mapUrlTemplateValueToKeyVaultNames(appKey, value);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
239
287
|
const configItem = {
|
|
240
288
|
name: key,
|
|
241
|
-
value:
|
|
289
|
+
value: storedValue,
|
|
242
290
|
location,
|
|
243
291
|
required
|
|
244
292
|
};
|
|
@@ -255,6 +303,10 @@ function parseEnvironmentVariables(envTemplate, variablesConfig = null) {
|
|
|
255
303
|
const configuration = [];
|
|
256
304
|
const lines = envTemplate.split('\n');
|
|
257
305
|
const portalInputMap = createPortalInputMap(variablesConfig);
|
|
306
|
+
const appKey =
|
|
307
|
+
variablesConfig && variablesConfig.app && variablesConfig.app.key
|
|
308
|
+
? String(variablesConfig.app.key).trim()
|
|
309
|
+
: null;
|
|
258
310
|
|
|
259
311
|
for (const line of lines) {
|
|
260
312
|
const parsed = parseEnvironmentVariableLine(line);
|
|
@@ -263,7 +315,14 @@ function parseEnvironmentVariables(envTemplate, variablesConfig = null) {
|
|
|
263
315
|
}
|
|
264
316
|
|
|
265
317
|
const { location, required } = determineVariableLocation(parsed.value, parsed.key);
|
|
266
|
-
const configItem = createConfigItem(
|
|
318
|
+
const configItem = createConfigItem(
|
|
319
|
+
parsed.key,
|
|
320
|
+
parsed.value,
|
|
321
|
+
location,
|
|
322
|
+
required,
|
|
323
|
+
portalInputMap,
|
|
324
|
+
appKey
|
|
325
|
+
);
|
|
267
326
|
configuration.push(configItem);
|
|
268
327
|
}
|
|
269
328
|
|
package/lib/generator/index.js
CHANGED
|
@@ -13,7 +13,7 @@ const fs = require('fs');
|
|
|
13
13
|
const path = require('path');
|
|
14
14
|
const _validator = require('../validation/validator');
|
|
15
15
|
const builders = require('./builders');
|
|
16
|
-
const { detectAppType, getDeployJsonPath, resolveApplicationConfigPath } = require('../utils/paths');
|
|
16
|
+
const { detectAppType, getDeployJsonPath, resolveApplicationConfigPath, resolveRbacPath } = require('../utils/paths');
|
|
17
17
|
const { logOfflinePathWhenType } = require('../utils/cli-utils');
|
|
18
18
|
const splitFunctions = require('./split');
|
|
19
19
|
const { loadVariables, loadEnvTemplate, loadRbac, parseEnvironmentVariables } = require('./helpers');
|
|
@@ -22,6 +22,7 @@ const { generateControllerManifest } = require('./external-controller-manifest')
|
|
|
22
22
|
const { resolveVersionForApp } = require('../utils/image-version');
|
|
23
23
|
const { getContainerPort } = require('../utils/port-resolver');
|
|
24
24
|
const { buildEnvVarMap } = require('../utils/env-map');
|
|
25
|
+
const { rewriteFrontDoorHostForAzureDeploy } = require('./deploy-manifest-azure-kv');
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
28
|
* Generates deployment JSON from application configuration files
|
|
@@ -39,7 +40,7 @@ const { buildEnvVarMap } = require('../utils/env-map');
|
|
|
39
40
|
*
|
|
40
41
|
* @example
|
|
41
42
|
* const jsonPath = await generateDeployJson('myapp');
|
|
42
|
-
* // Returns: './builder/myapp/myapp-deploy.json' or './integration/hubspot/application-schema.json'
|
|
43
|
+
* // Returns: './builder/myapp/myapp-deploy.json' or './integration/hubspot-test/application-schema.json'
|
|
43
44
|
*/
|
|
44
45
|
/**
|
|
45
46
|
* Loads configuration files for deployment generation
|
|
@@ -51,12 +52,12 @@ const { buildEnvVarMap } = require('../utils/env-map');
|
|
|
51
52
|
function loadDeploymentConfigFiles(appPath, appType, appName) {
|
|
52
53
|
const variablesPath = resolveApplicationConfigPath(appPath);
|
|
53
54
|
const templatePath = path.join(appPath, 'env.template');
|
|
54
|
-
const rbacPath =
|
|
55
|
+
const rbacPath = resolveRbacPath(appPath);
|
|
55
56
|
const jsonPath = getDeployJsonPath(appName, appType, true); // Use new naming
|
|
56
57
|
|
|
57
58
|
const { parsed: variables } = loadVariables(variablesPath);
|
|
58
59
|
const envTemplate = loadEnvTemplate(templatePath);
|
|
59
|
-
const rbac = loadRbac(rbacPath);
|
|
60
|
+
const rbac = rbacPath ? loadRbac(rbacPath) : null;
|
|
60
61
|
|
|
61
62
|
return { variables, envTemplate, rbac, jsonPath };
|
|
62
63
|
}
|
|
@@ -191,6 +192,8 @@ function buildAndValidateDeployment(appName, variables, envTemplate, rbac, optio
|
|
|
191
192
|
substituteEnvVarsInDeployment(deployment, envVarMap);
|
|
192
193
|
}
|
|
193
194
|
|
|
195
|
+
rewriteFrontDoorHostForAzureDeploy(deployment);
|
|
196
|
+
|
|
194
197
|
// Ensure no other ${...} placeholders remain in manifest
|
|
195
198
|
_validator.validateNoUnresolvedVariablesInDeployment(deployment);
|
|
196
199
|
|
|
@@ -236,6 +239,7 @@ async function buildDeploymentManifestInMemory(appName, options = {}) {
|
|
|
236
239
|
}
|
|
237
240
|
const envVarMap = await buildEnvVarMap('docker', null, null, { appPort: effectivePort });
|
|
238
241
|
substituteEnvVarsInDeployment(deployment, envVarMap);
|
|
242
|
+
rewriteFrontDoorHostForAzureDeploy(deployment);
|
|
239
243
|
_validator.validateNoUnresolvedVariablesInDeployment(deployment);
|
|
240
244
|
return { deployment, appPath };
|
|
241
245
|
}
|
|
@@ -13,10 +13,15 @@ const { parseImageReference } = require('./parse-image');
|
|
|
13
13
|
* @param {Object} deployment - Deployment JSON object
|
|
14
14
|
* @returns {{ appName: string, config: Object }}
|
|
15
15
|
*/
|
|
16
|
-
function buildReadmeConfigForExternal(deployment) {
|
|
16
|
+
function buildReadmeConfigForExternal(deployment, options = {}) {
|
|
17
17
|
const system = deployment.system;
|
|
18
18
|
const appName = system.key || deployment.key || 'external-system';
|
|
19
19
|
const dataSources = deployment.dataSources || deployment.datasources || [];
|
|
20
|
+
const rawExt = options.fileExt;
|
|
21
|
+
const fileExt =
|
|
22
|
+
rawExt !== undefined && rawExt !== null && String(rawExt).trim() !== ''
|
|
23
|
+
? (String(rawExt).startsWith('.') ? String(rawExt) : `.${String(rawExt)}`)
|
|
24
|
+
: '.json';
|
|
20
25
|
return {
|
|
21
26
|
appName,
|
|
22
27
|
config: {
|
|
@@ -25,7 +30,7 @@ function buildReadmeConfigForExternal(deployment) {
|
|
|
25
30
|
systemType: system.type || 'openapi',
|
|
26
31
|
systemDisplayName: system.displayName || appName,
|
|
27
32
|
systemDescription: system.description || `External system integration for ${appName}`,
|
|
28
|
-
fileExt
|
|
33
|
+
fileExt,
|
|
29
34
|
datasourceCount: dataSources.length,
|
|
30
35
|
datasources: dataSources
|
|
31
36
|
}
|
|
@@ -49,7 +54,7 @@ function buildReadmeConfigForApp(deployment) {
|
|
|
49
54
|
displayName: deployment.displayName,
|
|
50
55
|
description: deployment.description,
|
|
51
56
|
port,
|
|
52
|
-
build: {
|
|
57
|
+
build: {},
|
|
53
58
|
image: { name: imageName, registry },
|
|
54
59
|
registry,
|
|
55
60
|
database: deployment.requiresDatabase,
|
|
@@ -80,9 +85,9 @@ function buildReadmeConfigForApp(deployment) {
|
|
|
80
85
|
* @param {Object} deployment - Deployment JSON object
|
|
81
86
|
* @returns {{ appName: string, config: Object }}
|
|
82
87
|
*/
|
|
83
|
-
function buildReadmeConfigFromDeployment(deployment) {
|
|
88
|
+
function buildReadmeConfigFromDeployment(deployment, options = {}) {
|
|
84
89
|
if (deployment.system && typeof deployment.system === 'object') {
|
|
85
|
-
return buildReadmeConfigForExternal(deployment);
|
|
90
|
+
return buildReadmeConfigForExternal(deployment, options);
|
|
86
91
|
}
|
|
87
92
|
return buildReadmeConfigForApp(deployment);
|
|
88
93
|
}
|
|
@@ -92,11 +97,11 @@ function buildReadmeConfigFromDeployment(deployment) {
|
|
|
92
97
|
* @param {Object} deployment - Deployment JSON object
|
|
93
98
|
* @returns {string} README.md content
|
|
94
99
|
*/
|
|
95
|
-
function generateReadmeFromDeployJson(deployment) {
|
|
100
|
+
function generateReadmeFromDeployJson(deployment, options = {}) {
|
|
96
101
|
if (!deployment || typeof deployment !== 'object') {
|
|
97
102
|
throw new Error('Deployment object is required');
|
|
98
103
|
}
|
|
99
|
-
const { appName, config } = buildReadmeConfigFromDeployment(deployment);
|
|
104
|
+
const { appName, config } = buildReadmeConfigFromDeployment(deployment, options);
|
|
100
105
|
return generateReadmeMd(appName, config);
|
|
101
106
|
}
|
|
102
107
|
|
|
@@ -56,7 +56,8 @@ function extractOptionalSections(deployment) {
|
|
|
56
56
|
const optional = {};
|
|
57
57
|
const names = [
|
|
58
58
|
'healthCheck', 'authentication', 'build', 'repository', 'deployment',
|
|
59
|
-
'startupCommand', 'runtimeVersion', 'scaling', 'frontDoorRouting'
|
|
59
|
+
'startupCommand', 'runtimeVersion', 'scaling', 'frontDoorRouting',
|
|
60
|
+
'environmentScopedResources'
|
|
60
61
|
];
|
|
61
62
|
for (const sectionName of names) {
|
|
62
63
|
extractOptionalSection(deployment, sectionName, optional);
|
package/lib/generator/split.js
CHANGED
|
@@ -14,6 +14,7 @@ const yaml = require('js-yaml');
|
|
|
14
14
|
const { parseImageReference } = require('./parse-image');
|
|
15
15
|
const { generateReadmeFromDeployJson } = require('./split-readme');
|
|
16
16
|
const { extractVariablesYaml, getExternalDatasourceFileName } = require('./split-variables');
|
|
17
|
+
const { generateExternalEnvTemplateContent } = require('../utils/external-env-template');
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* Converts configuration array back to env.template format
|
|
@@ -207,24 +208,49 @@ function mergeEnvTemplateWithExisting(existingContent, expectedByKey) {
|
|
|
207
208
|
return updatedLines.join('\n') + (updatedLines.length > 0 ? '\n' : '');
|
|
208
209
|
}
|
|
209
210
|
|
|
211
|
+
/**
|
|
212
|
+
* Builds key -> line map from env.template content (for merge when using external system template).
|
|
213
|
+
* @param {string} content - Full env.template content
|
|
214
|
+
* @returns {Map<string, string>} Key to full KEY=value line
|
|
215
|
+
*/
|
|
216
|
+
function buildExpectedByKeyFromEnvContent(content) {
|
|
217
|
+
const expectedByKey = new Map();
|
|
218
|
+
if (!content || typeof content !== 'string') return expectedByKey;
|
|
219
|
+
const lines = content.split(/\r?\n/);
|
|
220
|
+
for (const line of lines) {
|
|
221
|
+
const trimmed = line.trim();
|
|
222
|
+
if (!trimmed || trimmed.startsWith('#')) continue;
|
|
223
|
+
const eq = trimmed.indexOf('=');
|
|
224
|
+
if (eq > 0) {
|
|
225
|
+
const key = trimmed.substring(0, eq).trim();
|
|
226
|
+
expectedByKey.set(key, trimmed);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return expectedByKey;
|
|
230
|
+
}
|
|
231
|
+
|
|
210
232
|
/**
|
|
211
233
|
* Writes env.template (merge or overwrite).
|
|
212
234
|
* @param {string} outputDir - Output directory
|
|
213
235
|
* @param {string} envTemplate - Default env.template content
|
|
214
|
-
* @param {Object} options - Options (mergeEnvTemplate, configuration)
|
|
236
|
+
* @param {Object} options - Options (mergeEnvTemplate, configuration, expectedByKey for external)
|
|
215
237
|
* @returns {Promise<string>} Path to env.template
|
|
216
238
|
*/
|
|
217
239
|
async function writeEnvTemplateToDir(outputDir, envTemplate, options) {
|
|
218
240
|
const envTemplatePath = path.join(outputDir, 'env.template');
|
|
219
241
|
const fsSync = require('fs');
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
242
|
+
const useMerge = options.mergeEnvTemplate && fsSync.existsSync(envTemplatePath);
|
|
243
|
+
if (useMerge) {
|
|
244
|
+
const expectedByKey = options.expectedByKey ||
|
|
245
|
+
(options.configuration ? buildEnvTemplateExpectedByKey(options.configuration) : new Map());
|
|
246
|
+
if (expectedByKey.size > 0) {
|
|
247
|
+
const existingContent = await fs.readFile(envTemplatePath, 'utf8');
|
|
248
|
+
const merged = mergeEnvTemplateWithExisting(existingContent, expectedByKey);
|
|
249
|
+
await writeComponentFile(envTemplatePath, merged);
|
|
250
|
+
return envTemplatePath;
|
|
251
|
+
}
|
|
227
252
|
}
|
|
253
|
+
await writeComponentFile(envTemplatePath, envTemplate);
|
|
228
254
|
return envTemplatePath;
|
|
229
255
|
}
|
|
230
256
|
|
|
@@ -401,12 +427,21 @@ async function splitDeployJson(deployJsonPath, outputDir = null, splitOptions =
|
|
|
401
427
|
normalizeDeploymentForSplit(deployment);
|
|
402
428
|
|
|
403
429
|
const configArray = deployment.configuration || [];
|
|
404
|
-
|
|
430
|
+
let envTemplate;
|
|
431
|
+
const writeOptions = buildSplitWriteOptions(splitOptions, configArray);
|
|
432
|
+
if (deployment.system && typeof deployment.system === 'object') {
|
|
433
|
+
envTemplate = generateExternalEnvTemplateContent(deployment.system);
|
|
434
|
+
if (writeOptions.mergeEnvTemplate) {
|
|
435
|
+
writeOptions.expectedByKey = buildExpectedByKeyFromEnvContent(envTemplate);
|
|
436
|
+
}
|
|
437
|
+
} else {
|
|
438
|
+
envTemplate = extractEnvTemplate(configArray);
|
|
439
|
+
}
|
|
440
|
+
|
|
405
441
|
const variables = extractVariablesYaml(deployment);
|
|
406
442
|
const rbac = extractRbacYaml(deployment);
|
|
407
|
-
const readme = generateReadmeFromDeployJson(deployment);
|
|
443
|
+
const readme = generateReadmeFromDeployJson(deployment, { fileExt: '.yaml' });
|
|
408
444
|
|
|
409
|
-
const writeOptions = buildSplitWriteOptions(splitOptions, configArray);
|
|
410
445
|
const result = await writeComponentFiles(finalOutputDir, envTemplate, variables, rbac, readme, writeOptions);
|
|
411
446
|
await applyExternalSystemFilesToResult(finalOutputDir, deployment, result);
|
|
412
447
|
return result;
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
'use strict';
|
|
9
|
+
const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
9
10
|
|
|
10
11
|
const fs = require('fs').promises;
|
|
11
12
|
const path = require('path');
|
|
12
|
-
const chalk = require('chalk');
|
|
13
13
|
const logger = require('../utils/logger');
|
|
14
14
|
const { generateExternalReadmeContent } = require('../utils/external-readme');
|
|
15
15
|
|
|
@@ -48,7 +48,7 @@ async function generateReadme(options) {
|
|
|
48
48
|
|
|
49
49
|
if (aiGeneratedContent) {
|
|
50
50
|
await fs.writeFile(readmePath, aiGeneratedContent, 'utf8');
|
|
51
|
-
logger.log(
|
|
51
|
+
logger.log(formatSuccessLine('Generated README.md (AI-generated from dataplane)'));
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
54
|
|
|
@@ -82,7 +82,7 @@ async function generateReadme(options) {
|
|
|
82
82
|
});
|
|
83
83
|
|
|
84
84
|
await fs.writeFile(readmePath, readmeContent, 'utf8');
|
|
85
|
-
logger.log(
|
|
85
|
+
logger.log(formatSuccessLine('Generated README.md (template)'));
|
|
86
86
|
} catch (error) {
|
|
87
87
|
throw new Error(`Failed to generate README.md: ${error.message}`);
|
|
88
88
|
}
|
package/lib/generator/wizard.js
CHANGED
|
@@ -8,14 +8,15 @@
|
|
|
8
8
|
* PASSWORD, BASEURL. See docs/external-systems.md and docs/wizard.md.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
11
12
|
const fs = require('fs').promises;
|
|
12
13
|
const path = require('path');
|
|
13
14
|
const Handlebars = require('handlebars');
|
|
14
|
-
const chalk = require('chalk');
|
|
15
15
|
const logger = require('../utils/logger');
|
|
16
16
|
const { resolveApplicationConfigPath } = require('../utils/app-config-resolver');
|
|
17
17
|
const { loadConfigFile, writeConfigFile } = require('../utils/config-format');
|
|
18
18
|
const { systemKeyToKvPrefix, securityKeyToVar, isValidKvPath } = require('../utils/credential-secrets-env');
|
|
19
|
+
const { generateExternalEnvTemplateContent } = require('../utils/external-env-template');
|
|
19
20
|
const { generateReadme } = require('./wizard-readme');
|
|
20
21
|
|
|
21
22
|
/**
|
|
@@ -60,7 +61,7 @@ async function writeSystemYamlFile(appPath, finalSystemKey, systemConfig, format
|
|
|
60
61
|
const systemFileName = `${finalSystemKey}-system${ext}`;
|
|
61
62
|
const systemFilePath = path.join(appPath, systemFileName);
|
|
62
63
|
writeConfigFile(systemFilePath, systemConfig, format === 'json' ? 'json' : 'yaml');
|
|
63
|
-
logger.log(
|
|
64
|
+
logger.log(formatSuccessLine(`Generated system file: ${systemFileName}`));
|
|
64
65
|
return systemFilePath;
|
|
65
66
|
}
|
|
66
67
|
|
|
@@ -96,7 +97,7 @@ async function writeDatasourceYamlFiles(appPath, finalSystemKey, datasourceConfi
|
|
|
96
97
|
const datasourceFilePath = path.join(appPath, datasourceFileName);
|
|
97
98
|
writeConfigFile(datasourceFilePath, datasourceConfig, fmt);
|
|
98
99
|
datasourceFileNames.push(datasourceFileName);
|
|
99
|
-
logger.log(
|
|
100
|
+
logger.log(formatSuccessLine(`Generated datasource file: ${datasourceFileName}`));
|
|
100
101
|
}
|
|
101
102
|
return datasourceFileNames;
|
|
102
103
|
}
|
|
@@ -130,10 +131,12 @@ async function generateConfigFilesForWizard(params) {
|
|
|
130
131
|
format: format || 'yaml'
|
|
131
132
|
});
|
|
132
133
|
|
|
133
|
-
// Generate env.template with
|
|
134
|
-
await generateEnvTemplate(appPath, systemConfig, finalSystemKey);
|
|
135
|
-
|
|
134
|
+
// Generate env.template with Authentication and Configuration sections (Handlebars)
|
|
136
135
|
const envTemplatePath = path.join(appPath, 'env.template');
|
|
136
|
+
const envTemplateContent = generateExternalEnvTemplateContent(systemConfig);
|
|
137
|
+
await fs.writeFile(envTemplatePath, envTemplateContent, 'utf8');
|
|
138
|
+
logger.log(formatSuccessLine('Generated env.template'));
|
|
139
|
+
|
|
137
140
|
try {
|
|
138
141
|
const secretsEnsure = require('../core/secrets-ensure');
|
|
139
142
|
await secretsEnsure.ensureSecretsFromEnvTemplate(envTemplatePath, { emptyValuesForCredentials: true });
|
|
@@ -161,7 +164,7 @@ async function generateConfigFilesForWizard(params) {
|
|
|
161
164
|
const deployJson = toDeployJsonShape(manifest);
|
|
162
165
|
const deployManifestPath = path.join(appPath, `${finalSystemKey}-deploy.json`);
|
|
163
166
|
await fs.writeFile(deployManifestPath, JSON.stringify(deployJson, null, 2), 'utf8');
|
|
164
|
-
logger.log(
|
|
167
|
+
logger.log(formatSuccessLine(`Generated deployment manifest: ${finalSystemKey}-deploy.json`));
|
|
165
168
|
|
|
166
169
|
return {
|
|
167
170
|
variablesPath: configPath,
|
|
@@ -290,7 +293,7 @@ async function generateOrUpdateVariablesYaml(params) {
|
|
|
290
293
|
const fsSync = require('fs');
|
|
291
294
|
if (fsSync.existsSync(configPath)) fsSync.unlinkSync(configPath);
|
|
292
295
|
}
|
|
293
|
-
logger.log(
|
|
296
|
+
logger.log(formatSuccessLine(`Generated/updated application${ext}`));
|
|
294
297
|
return targetPath;
|
|
295
298
|
} catch (error) {
|
|
296
299
|
throw new Error(`Failed to generate application config: ${error.message}`);
|
|
@@ -393,15 +396,15 @@ function addBaseUrlLines(lines, systemConfig) {
|
|
|
393
396
|
}
|
|
394
397
|
|
|
395
398
|
/**
|
|
396
|
-
* Generate env.template with KV_* authentication variables
|
|
399
|
+
* Generate env.template with KV_* authentication variables (legacy; prefer generateExternalEnvTemplateContent).
|
|
397
400
|
* @async
|
|
398
|
-
* @function
|
|
401
|
+
* @function _generateEnvTemplate
|
|
399
402
|
* @param {string} appPath - Application directory path
|
|
400
403
|
* @param {Object} systemConfig - System configuration (must have key for systemKey)
|
|
401
404
|
* @param {string} [finalSystemKey] - Final system key for KV_ prefix (default: systemConfig.key)
|
|
402
405
|
* @throws {Error} If generation fails
|
|
403
406
|
*/
|
|
404
|
-
async function
|
|
407
|
+
async function _generateEnvTemplate(appPath, systemConfig, finalSystemKey) {
|
|
405
408
|
try {
|
|
406
409
|
const envTemplatePath = path.join(appPath, 'env.template');
|
|
407
410
|
const systemKey = finalSystemKey || systemConfig?.key;
|
|
@@ -414,7 +417,7 @@ async function generateEnvTemplate(appPath, systemConfig, finalSystemKey) {
|
|
|
414
417
|
addBaseUrlLines(lines, systemConfig);
|
|
415
418
|
|
|
416
419
|
await fs.writeFile(envTemplatePath, lines.join('\n'), 'utf8');
|
|
417
|
-
logger.log(
|
|
420
|
+
logger.log(formatSuccessLine('Generated env.template'));
|
|
418
421
|
} catch (error) {
|
|
419
422
|
throw new Error(`Failed to generate env.template: ${error.message}`);
|
|
420
423
|
}
|
|
@@ -437,7 +440,7 @@ async function writeDeployScriptFromTemplate(templateName, outputPath, context)
|
|
|
437
440
|
const templatePath = path.join(templatesExternalDir, templateName);
|
|
438
441
|
const content = Handlebars.compile(await fs.readFile(templatePath, 'utf8'))(context);
|
|
439
442
|
await fs.writeFile(outputPath, content, 'utf8');
|
|
440
|
-
logger.log(
|
|
443
|
+
logger.log(formatSuccessLine(`Generated ${path.basename(outputPath)}`));
|
|
441
444
|
}
|
|
442
445
|
|
|
443
446
|
async function generateDeployScripts(appPath, systemKey, systemFileName, datasourceFileNames) {
|
|
@@ -12,6 +12,32 @@ const fs = require('fs');
|
|
|
12
12
|
const handlebars = require('handlebars');
|
|
13
13
|
const path = require('path');
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Normalize a host path for Docker Compose bind mounts. Docker Desktop sends
|
|
17
|
+
* mounts to a Linux VM; backslashes in Windows paths yield "invalid volume
|
|
18
|
+
* specification" from the daemon.
|
|
19
|
+
*
|
|
20
|
+
* On Windows, Compose often forwards binds as "SOURCE:TARGET:rw". A SOURCE
|
|
21
|
+
* like "C:/Users/..." is split at the first colon, so the engine must receive
|
|
22
|
+
* paths in Linux-VM form (e.g. "/c/Users/...") instead.
|
|
23
|
+
*
|
|
24
|
+
* @param {string} fsPath - Host path (absolute or relative)
|
|
25
|
+
* @returns {string} Path with forward slashes, resolved when relative
|
|
26
|
+
*/
|
|
27
|
+
function toDockerBindMountSource(fsPath) {
|
|
28
|
+
if (!fsPath || typeof fsPath !== 'string') {
|
|
29
|
+
return fsPath;
|
|
30
|
+
}
|
|
31
|
+
let resolved = path.resolve(fsPath).split(path.sep).join('/');
|
|
32
|
+
if (process.platform === 'win32') {
|
|
33
|
+
const drive = /^([a-zA-Z]):(\/.*)$/.exec(resolved);
|
|
34
|
+
if (drive) {
|
|
35
|
+
resolved = `/${drive[1].toLowerCase()}${drive[2]}`;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return resolved;
|
|
39
|
+
}
|
|
40
|
+
|
|
15
41
|
/**
|
|
16
42
|
* Builds Traefik configuration from environment variables
|
|
17
43
|
* @param {boolean} enabled - Whether Traefik should be included
|
|
@@ -22,7 +48,8 @@ function buildTraefikConfig(enabled) {
|
|
|
22
48
|
enabled: !!enabled,
|
|
23
49
|
certStore: process.env.TRAEFIK_CERT_STORE || null,
|
|
24
50
|
certFile: process.env.TRAEFIK_CERT_FILE || null,
|
|
25
|
-
keyFile: process.env.TRAEFIK_KEY_FILE || null
|
|
51
|
+
keyFile: process.env.TRAEFIK_KEY_FILE || null,
|
|
52
|
+
trustForwardedHeaders: false
|
|
26
53
|
};
|
|
27
54
|
}
|
|
28
55
|
|
|
@@ -40,13 +67,23 @@ function validateTraefikConfig(traefikConfig) {
|
|
|
40
67
|
|
|
41
68
|
if (traefikConfig.certStore) {
|
|
42
69
|
if (!traefikConfig.certFile || !traefikConfig.keyFile) {
|
|
43
|
-
errors.push(
|
|
70
|
+
errors.push(
|
|
71
|
+
'TLS is enabled for Traefik but certificate files are missing or invalid. ' +
|
|
72
|
+
'Set TRAEFIK_CERT_FILE and TRAEFIK_KEY_FILE (and TRAEFIK_CERT_STORE if used) to your local cert and key, ' +
|
|
73
|
+
'or disable TLS in application/frontDoorRouting for local development.'
|
|
74
|
+
);
|
|
44
75
|
} else {
|
|
45
76
|
if (!fs.existsSync(traefikConfig.certFile)) {
|
|
46
|
-
errors.push(
|
|
77
|
+
errors.push(
|
|
78
|
+
'TLS is enabled for Traefik but certificate files are missing or invalid. ' +
|
|
79
|
+
`Certificate file not found: ${traefikConfig.certFile}`
|
|
80
|
+
);
|
|
47
81
|
}
|
|
48
82
|
if (!fs.existsSync(traefikConfig.keyFile)) {
|
|
49
|
-
errors.push(
|
|
83
|
+
errors.push(
|
|
84
|
+
'TLS is enabled for Traefik but certificate files are missing or invalid. ' +
|
|
85
|
+
`Private key file not found: ${traefikConfig.keyFile}`
|
|
86
|
+
);
|
|
50
87
|
}
|
|
51
88
|
}
|
|
52
89
|
}
|
|
@@ -82,6 +119,20 @@ function generateComposeFile(templatePath, devId, idNum, ports, infraDir, option
|
|
|
82
119
|
const redisCommanderConfig = options.redisCommander && typeof options.redisCommander.enabled === 'boolean'
|
|
83
120
|
? options.redisCommander
|
|
84
121
|
: { enabled: true };
|
|
122
|
+
const traefikForCompose = traefikConfig && typeof traefikConfig === 'object'
|
|
123
|
+
? {
|
|
124
|
+
...traefikConfig,
|
|
125
|
+
trustForwardedHeaders: !!traefikConfig.trustForwardedHeaders,
|
|
126
|
+
...(traefikConfig.certFile
|
|
127
|
+
? { certFile: toDockerBindMountSource(traefikConfig.certFile) }
|
|
128
|
+
: {}),
|
|
129
|
+
...(traefikConfig.keyFile
|
|
130
|
+
? { keyFile: toDockerBindMountSource(traefikConfig.keyFile) }
|
|
131
|
+
: {})
|
|
132
|
+
}
|
|
133
|
+
: traefikConfig;
|
|
134
|
+
const initScriptsBind = toDockerBindMountSource(path.join(infraDir, 'init-scripts'));
|
|
135
|
+
const infraDirBind = toDockerBindMountSource(infraDir);
|
|
85
136
|
const composeContent = template({
|
|
86
137
|
devId: devId,
|
|
87
138
|
postgresPort: ports.postgres,
|
|
@@ -94,7 +145,9 @@ function generateComposeFile(templatePath, devId, idNum, ports, infraDir, option
|
|
|
94
145
|
serversJsonPath: serversJsonPath,
|
|
95
146
|
pgpassPath: pgpassPath,
|
|
96
147
|
infraDir: infraDir,
|
|
97
|
-
|
|
148
|
+
initScriptsBind: initScriptsBind,
|
|
149
|
+
infraDirBind: infraDirBind,
|
|
150
|
+
traefik: traefikForCompose,
|
|
98
151
|
pgadmin: pgadminConfig,
|
|
99
152
|
redisCommander: redisCommanderConfig
|
|
100
153
|
});
|
|
@@ -106,5 +159,6 @@ function generateComposeFile(templatePath, devId, idNum, ports, infraDir, option
|
|
|
106
159
|
module.exports = {
|
|
107
160
|
buildTraefikConfig,
|
|
108
161
|
validateTraefikConfig,
|
|
109
|
-
generateComposeFile
|
|
162
|
+
generateComposeFile,
|
|
163
|
+
toDockerBindMountSource
|
|
110
164
|
};
|