@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/build/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { formatSuccessLine, formatSuccessParagraph } = require('../utils/cli-test-layout-chalk');
|
|
1
2
|
/**
|
|
2
3
|
* AI Fabrix Builder Build Functions
|
|
3
4
|
*
|
|
@@ -127,7 +128,9 @@ async function generateDockerfile(appNameOrPath, language, config, buildConfig =
|
|
|
127
128
|
|
|
128
129
|
const template = dockerfileUtils.loadDockerfileTemplate(language);
|
|
129
130
|
const isAppFlag = buildConfig.context === '../..';
|
|
130
|
-
|
|
131
|
+
// Use "./" (not ".") so Dockerfile lines are "COPY ./requirements*.txt" — a bare "."
|
|
132
|
+
// concatenates with "requirements" and becomes ".requirements*.txt", which matches nothing.
|
|
133
|
+
const appSourcePath = isAppFlag ? `apps/${appName}/` : './';
|
|
131
134
|
|
|
132
135
|
const templateVars = {
|
|
133
136
|
port: config.port || 3000,
|
|
@@ -185,11 +188,11 @@ async function generateDockerfile(appNameOrPath, language, config, buildConfig =
|
|
|
185
188
|
async function postBuildTasks(appName, buildConfig) {
|
|
186
189
|
try {
|
|
187
190
|
const envPath = await secrets.generateEnvFile(appName, buildConfig.secrets, 'docker');
|
|
188
|
-
logger.log(
|
|
191
|
+
logger.log(formatSuccessLine(`Generated .env file: ${envPath}`));
|
|
189
192
|
// Note: processEnvVariables is already called by generateEnvFile to generate local .env
|
|
190
193
|
// at the envOutputPath, so we don't need to manually copy the docker .env file
|
|
191
194
|
} catch (error) {
|
|
192
|
-
logger.log(chalk.yellow(
|
|
195
|
+
logger.log(chalk.yellow(`⚠ Warning: Could not generate .env file: ${error.message}`));
|
|
193
196
|
}
|
|
194
197
|
}
|
|
195
198
|
|
|
@@ -229,7 +232,7 @@ async function copyApplicationSourceFiles(appName, devDir) {
|
|
|
229
232
|
const appsPath = path.join(process.cwd(), 'apps', appName);
|
|
230
233
|
if (fsSync.existsSync(appsPath)) {
|
|
231
234
|
await buildCopy.copyAppSourceFiles(appsPath, devDir);
|
|
232
|
-
logger.log(
|
|
235
|
+
logger.log(formatSuccessLine(`Copied application source files from apps/${appName}`));
|
|
233
236
|
return true;
|
|
234
237
|
}
|
|
235
238
|
return false;
|
|
@@ -253,12 +256,12 @@ async function copyTemplateFilesIfNeeded(devDir, language, buildConfig, options)
|
|
|
253
256
|
const projectRoot = getProjectRoot();
|
|
254
257
|
const templatePath = path.join(projectRoot, 'templates', 'typescript');
|
|
255
258
|
await buildCopy.copyTemplateFilesToDevDir(templatePath, devDir, detectedLanguage);
|
|
256
|
-
logger.log(
|
|
259
|
+
logger.log(formatSuccessLine(`Generated application files from ${detectedLanguage} template`));
|
|
257
260
|
} else if (detectedLanguage === 'python' && !fsSync.existsSync(requirementsPath)) {
|
|
258
261
|
const projectRoot = getProjectRoot();
|
|
259
262
|
const templatePath = path.join(projectRoot, 'templates', 'python');
|
|
260
263
|
await buildCopy.copyTemplateFilesToDevDir(templatePath, devDir, detectedLanguage);
|
|
261
|
-
logger.log(
|
|
264
|
+
logger.log(formatSuccessLine(`Generated application files from ${detectedLanguage} template`));
|
|
262
265
|
}
|
|
263
266
|
}
|
|
264
267
|
|
|
@@ -268,7 +271,7 @@ async function prepareDevDirectory(appName, buildConfig, options) {
|
|
|
268
271
|
const directoryName = idNum === 0 ? 'applications' : `dev-${developerId}`;
|
|
269
272
|
logger.log(chalk.blue(`Copying files to developer-specific directory (${directoryName})...`));
|
|
270
273
|
const devDir = await buildCopy.copyBuilderToDevDirectory(appName, developerId);
|
|
271
|
-
logger.log(
|
|
274
|
+
logger.log(formatSuccessLine(`Files copied to: ${devDir}`));
|
|
272
275
|
|
|
273
276
|
const { config: appConfig, imageName } = await buildHelpers.loadAndValidateConfig(appName);
|
|
274
277
|
const effectiveImageName = buildDevImageName(imageName, developerId);
|
|
@@ -294,7 +297,7 @@ function prepareBuildContext(buildConfig, devDir) {
|
|
|
294
297
|
// Check if context is using old format (../appName) - these are incompatible with dev directory structure
|
|
295
298
|
if (buildConfig.context && buildConfig.context.startsWith('../') && buildConfig.context !== '../..') {
|
|
296
299
|
// Old format detected - always use devDir instead
|
|
297
|
-
logger.log(chalk.yellow(
|
|
300
|
+
logger.log(chalk.yellow(`⚠ Warning: Build context uses old format: ${buildConfig.context}`));
|
|
298
301
|
logger.log(chalk.yellow(` Using dev directory instead: ${devDir}`));
|
|
299
302
|
contextPath = devDir;
|
|
300
303
|
} else if (buildConfig.context && buildConfig.context !== '../..') {
|
|
@@ -353,7 +356,7 @@ async function handleDockerfileGeneration(appName, params, options, buildHelpers
|
|
|
353
356
|
language = 'typescript';
|
|
354
357
|
}
|
|
355
358
|
if (!hasExistingDockerfile) {
|
|
356
|
-
logger.log(
|
|
359
|
+
logger.log(formatSuccessLine(`Detected language: ${language}`));
|
|
357
360
|
}
|
|
358
361
|
|
|
359
362
|
// Determine Dockerfile (needs context path to generate in correct location)
|
|
@@ -425,7 +428,7 @@ async function buildApp(appName, options = {}) {
|
|
|
425
428
|
// 7. Post-build tasks
|
|
426
429
|
await postBuildTasks(appName, buildConfig);
|
|
427
430
|
|
|
428
|
-
logger.log(
|
|
431
|
+
logger.log(formatSuccessParagraph('Build completed successfully!'));
|
|
429
432
|
return `${imageName}:${tag}`;
|
|
430
433
|
|
|
431
434
|
} catch (error) {
|
package/lib/cli/index.js
CHANGED
|
@@ -17,6 +17,7 @@ const { setupEnvironmentCommands } = require('./setup-environment');
|
|
|
17
17
|
const { setupUtilityCommands } = require('./setup-utility');
|
|
18
18
|
const { setupDevCommands } = require('./setup-dev');
|
|
19
19
|
const { setupSecretsCommands } = require('./setup-secrets');
|
|
20
|
+
const { setupParametersCommands } = require('./setup-parameters');
|
|
20
21
|
const { setupExternalSystemCommands } = require('./setup-external-system');
|
|
21
22
|
const { setupAppCommands: setupAppManagementCommands } = require('../commands/app');
|
|
22
23
|
const { setupDatasourceCommands } = require('../commands/datasource');
|
|
@@ -40,6 +41,7 @@ function setupCommands(program) {
|
|
|
40
41
|
setupExternalSystemCommands(program);
|
|
41
42
|
setupDevCommands(program);
|
|
42
43
|
setupSecretsCommands(program);
|
|
44
|
+
setupParametersCommands(program);
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
module.exports = {
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Help text blocks for app-level CLI commands.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
const TEST_HELP_AFTER = `
|
|
8
|
+
Examples:
|
|
9
|
+
# External system (integration/<systemKey>/) — local validation
|
|
10
|
+
$ aifabrix test hubspot
|
|
11
|
+
$ aifabrix test hubspot -v
|
|
12
|
+
$ aifabrix test hubspot -d
|
|
13
|
+
|
|
14
|
+
# Builder app (builder/<app>/) — runs in container
|
|
15
|
+
$ aifabrix test myapp -e dev
|
|
16
|
+
$ aifabrix test myapp -e tst
|
|
17
|
+
|
|
18
|
+
Notes:
|
|
19
|
+
- To run unit test for one datasource, use:
|
|
20
|
+
aifabrix datasource test <datasourceKey>
|
|
21
|
+
- To run integration test, use:
|
|
22
|
+
aifabrix test-integration <app>
|
|
23
|
+
- Option --sync is not supported here (local validation only); use upload or dataplane test commands with --sync.
|
|
24
|
+
`;
|
|
25
|
+
|
|
26
|
+
const TEST_INTEGRATION_HELP_AFTER = `
|
|
27
|
+
Examples:
|
|
28
|
+
# External system (integration/<systemKey>/) — integration health across datasources via dataplane
|
|
29
|
+
$ aifabrix test-integration hubspot
|
|
30
|
+
$ aifabrix test-integration hubspot -v
|
|
31
|
+
$ aifabrix test-integration hubspot -d
|
|
32
|
+
|
|
33
|
+
# Builder app (builder/<app>/) — runs in container
|
|
34
|
+
$ aifabrix test-integration myapp -e dev
|
|
35
|
+
$ aifabrix test-integration myapp -e tst
|
|
36
|
+
|
|
37
|
+
Notes:
|
|
38
|
+
- To run integration test for one datasource, use:
|
|
39
|
+
aifabrix datasource test-integration <datasourceKey>
|
|
40
|
+
- To run E2E test, use:
|
|
41
|
+
aifabrix test-e2e <app>
|
|
42
|
+
- Optional --sync publishes local files to the dataplane first (external integration under integration/<systemKey>/ only).
|
|
43
|
+
`;
|
|
44
|
+
|
|
45
|
+
const TEST_E2E_HELP_AFTER = `
|
|
46
|
+
Examples:
|
|
47
|
+
# External system (integration/<systemKey>/) — E2E across datasources via dataplane
|
|
48
|
+
$ aifabrix test-e2e hubspot
|
|
49
|
+
$ aifabrix test-e2e hubspot -v
|
|
50
|
+
$ aifabrix test-e2e hubspot -d
|
|
51
|
+
|
|
52
|
+
# Builder app (builder/<app>/) — runs in container
|
|
53
|
+
$ aifabrix test-e2e myapp -e dev
|
|
54
|
+
$ aifabrix test-e2e myapp -e tst
|
|
55
|
+
|
|
56
|
+
Notes:
|
|
57
|
+
- To run E2E for one datasource, use:
|
|
58
|
+
aifabrix datasource test-e2e <datasourceKey>
|
|
59
|
+
- Optional --sync publishes local files to the dataplane first (external integration only).
|
|
60
|
+
`;
|
|
61
|
+
|
|
62
|
+
module.exports = {
|
|
63
|
+
TEST_HELP_AFTER,
|
|
64
|
+
TEST_INTEGRATION_HELP_AFTER,
|
|
65
|
+
TEST_E2E_HELP_AFTER
|
|
66
|
+
};
|
|
67
|
+
|
package/lib/cli/setup-app.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { formatSuccessParagraph } = require('../utils/cli-test-layout-chalk');
|
|
1
2
|
/**
|
|
2
3
|
* CLI application lifecycle command setup (create, wizard, build, run, push, deploy, dockerfile).
|
|
3
4
|
*
|
|
@@ -11,6 +12,24 @@ const path = require('path');
|
|
|
11
12
|
const app = require('../app');
|
|
12
13
|
const logger = require('../utils/logger');
|
|
13
14
|
const { handleCommandError } = require('../utils/cli-utils');
|
|
15
|
+
const { setupInstallTestE2eLintCommands } = require('./setup-app.test-commands');
|
|
16
|
+
|
|
17
|
+
const CREATE_HELP_AFTER = `
|
|
18
|
+
Examples:
|
|
19
|
+
$ aifabrix create myapi --type webapp -l typescript
|
|
20
|
+
$ aifabrix create mycrm --wizard
|
|
21
|
+
`;
|
|
22
|
+
|
|
23
|
+
const DEPLOY_HELP_AFTER = `
|
|
24
|
+
Examples:
|
|
25
|
+
$ aifabrix deploy myapp
|
|
26
|
+
$ aifabrix deploy myext --local
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
const PUSH_HELP_AFTER = `
|
|
30
|
+
Example:
|
|
31
|
+
$ aifabrix push myapp -t v1.0.0
|
|
32
|
+
`;
|
|
14
33
|
|
|
15
34
|
/**
|
|
16
35
|
* Normalize options for external system creation
|
|
@@ -102,7 +121,8 @@ async function handleCreateCommand(appName, options) {
|
|
|
102
121
|
|
|
103
122
|
function setupCreateCommand(program) {
|
|
104
123
|
program.command('create <app>')
|
|
105
|
-
.description('
|
|
124
|
+
.description('Scaffold builder or external app (flags or --wizard)')
|
|
125
|
+
.addHelpText('after', CREATE_HELP_AFTER)
|
|
106
126
|
.option('-p, --port <port>', 'Application port', '3000')
|
|
107
127
|
.option('-d, --database', 'Requires database')
|
|
108
128
|
.option('-r, --redis', 'Requires Redis')
|
|
@@ -140,17 +160,17 @@ Examples:
|
|
|
140
160
|
$ aifabrix wizard my-integration --silent Run headless with integration/my-integration/wizard.yaml (no prompts)
|
|
141
161
|
$ aifabrix wizard -a my-integration Same as above (app name set)
|
|
142
162
|
$ aifabrix wizard --config wizard.yaml Run headless from a wizard config file
|
|
143
|
-
$ aifabrix wizard hubspot-test
|
|
163
|
+
$ aifabrix wizard hubspot-test --debug Enable debug output and save debug manifests on validation failure
|
|
144
164
|
|
|
145
|
-
Config path: When appName is provided, integration/<
|
|
165
|
+
Config path: When appName is provided, integration/<systemKey>/wizard.yaml is used for load/save and error.log.
|
|
146
166
|
To change settings after a run, edit that file and run "aifabrix wizard <app>" again.
|
|
147
167
|
Headless config must include: appName, mode (create-system|add-datasource), source (type + filePath/url/platform).
|
|
148
|
-
See integration/hubspot/wizard-hubspot-e2e.yaml for an example.`;
|
|
168
|
+
See integration/hubspot-test/wizard-hubspot-e2e.yaml for an example.`;
|
|
149
169
|
program.command('wizard [appName]')
|
|
150
|
-
.description('
|
|
170
|
+
.description('Guided external system setup (OpenAPI, MCP, HubSpot, …) or headless wizard.yaml')
|
|
151
171
|
.option('-a, --app <app>', 'Application name (synonym for positional appName)')
|
|
152
172
|
.option('--config <file>', 'Run headless using a wizard.yaml file (appName, mode, source, credential, preferences)')
|
|
153
|
-
.option('--silent', 'Run with saved integration/<
|
|
173
|
+
.option('--silent', 'Run with saved integration/<systemKey>/wizard.yaml only; no prompts (requires app name and existing wizard.yaml)')
|
|
154
174
|
.option('--debug', 'Enable debug output and save debug manifests on validation failure')
|
|
155
175
|
.addHelpText('after', wizardHelp)
|
|
156
176
|
.action(async(positionalAppName, options) => {
|
|
@@ -172,9 +192,10 @@ In dev: use --reload for sync and mount (requires remote server with Mutagen, or
|
|
|
172
192
|
Examples:
|
|
173
193
|
$ aifabrix run myapp
|
|
174
194
|
$ aifabrix run myapp --env tst
|
|
195
|
+
$ aifabrix run myapp --tag v1.0.0
|
|
175
196
|
$ aifabrix run myapp --reload`;
|
|
176
197
|
program.command('run <app>')
|
|
177
|
-
.description('Run
|
|
198
|
+
.description('Run app locally or on remote Docker host')
|
|
178
199
|
.option('-p, --port <port>', 'Override local port')
|
|
179
200
|
.option('-d, --debug', 'Enable debug output with detailed container information')
|
|
180
201
|
.option('-t, --tag <tag>', 'Image tag to run (e.g. v1.0.0); overrides application.yaml image.tag')
|
|
@@ -193,14 +214,15 @@ Examples:
|
|
|
193
214
|
|
|
194
215
|
function setupBuildRunLogsDownCommands(program) {
|
|
195
216
|
program.command('build <app>')
|
|
196
|
-
.description('Build
|
|
217
|
+
.description('Build Docker image (auto-detect runtime)')
|
|
197
218
|
.option('-l, --language <lang>', 'Override language detection')
|
|
198
219
|
.option('-f, --force-template', 'Force rebuild from template')
|
|
220
|
+
.option('--no-cache', 'Full Docker rebuild (disable layer cache); use after Dockerfile or context fixes')
|
|
199
221
|
.option('-t, --tag <tag>', 'Image tag (default: latest). Set image.tag in application.yaml to match for deploy.')
|
|
200
222
|
.action(async(appName, options) => {
|
|
201
223
|
try {
|
|
202
224
|
const imageTag = await app.buildApp(appName, options);
|
|
203
|
-
logger.log(
|
|
225
|
+
logger.log(`✔ Built image: ${imageTag}`);
|
|
204
226
|
} catch (error) {
|
|
205
227
|
handleCommandError(error, 'build');
|
|
206
228
|
process.exit(1);
|
|
@@ -210,7 +232,7 @@ function setupBuildRunLogsDownCommands(program) {
|
|
|
210
232
|
registerRunCommand(program);
|
|
211
233
|
|
|
212
234
|
program.command('logs <app>')
|
|
213
|
-
.description('
|
|
235
|
+
.description('Tail app container logs (optional env summary; secrets masked)')
|
|
214
236
|
.option('-f', 'Follow log stream')
|
|
215
237
|
.option('-t, --tail <lines>', 'Number of lines (default: 100); 0 = full list', '100')
|
|
216
238
|
.option('-l, --level <level>', 'Show only logs at this level or above (debug|info|warn|error)')
|
|
@@ -227,7 +249,7 @@ function setupBuildRunLogsDownCommands(program) {
|
|
|
227
249
|
});
|
|
228
250
|
|
|
229
251
|
program.command('down-app <app>')
|
|
230
|
-
.description('Stop and remove
|
|
252
|
+
.description('Stop and remove app container (--volumes removes data volume)')
|
|
231
253
|
.option('--volumes', 'Remove application Docker volume')
|
|
232
254
|
.action(async(appName, options) => {
|
|
233
255
|
try {
|
|
@@ -242,7 +264,7 @@ function setupBuildRunLogsDownCommands(program) {
|
|
|
242
264
|
|
|
243
265
|
function setupShellTestStopCommands(program) {
|
|
244
266
|
program.command('stop <app>')
|
|
245
|
-
.description('
|
|
267
|
+
.description('Alias for down-app: stop and remove container')
|
|
246
268
|
.option('--volumes', 'Remove application Docker volume')
|
|
247
269
|
.action(async(appName, options) => {
|
|
248
270
|
try {
|
|
@@ -255,7 +277,7 @@ function setupShellTestStopCommands(program) {
|
|
|
255
277
|
});
|
|
256
278
|
|
|
257
279
|
program.command('shell <app>')
|
|
258
|
-
.description('
|
|
280
|
+
.description('Interactive shell in running or ephemeral container')
|
|
259
281
|
.option('--env <env>', 'Environment (dev|tst); dev uses running container', 'dev')
|
|
260
282
|
.action(async(appName, options) => {
|
|
261
283
|
try {
|
|
@@ -266,105 +288,20 @@ function setupShellTestStopCommands(program) {
|
|
|
266
288
|
process.exit(1);
|
|
267
289
|
}
|
|
268
290
|
});
|
|
269
|
-
|
|
270
|
-
program.command('test <app>')
|
|
271
|
-
.description('Run tests (builder app: in container; external system: local validation)')
|
|
272
|
-
.option('--env <env>', 'For builder app: dev (running container) or tst (ephemeral)', 'dev')
|
|
273
|
-
.option('-d, --datasource <key>', 'For external system: test specific datasource only')
|
|
274
|
-
.option('-v, --verbose', 'Verbose output')
|
|
275
|
-
.action(async(appName, options) => {
|
|
276
|
-
try {
|
|
277
|
-
const pathsUtil = require('../utils/paths');
|
|
278
|
-
const appType = await pathsUtil.detectAppType(appName).catch(() => null);
|
|
279
|
-
if (appType && appType.baseDir === 'integration') {
|
|
280
|
-
const test = require('../external-system/test');
|
|
281
|
-
const results = await test.testExternalSystem(appName, options);
|
|
282
|
-
test.displayTestResults(results, options.verbose);
|
|
283
|
-
if (!results.valid) process.exit(1);
|
|
284
|
-
} else {
|
|
285
|
-
const { runAppTest } = require('../commands/app-test');
|
|
286
|
-
await runAppTest(appName, { env: options.env });
|
|
287
|
-
}
|
|
288
|
-
} catch (error) {
|
|
289
|
-
handleCommandError(error, 'test');
|
|
290
|
-
process.exit(1);
|
|
291
|
-
}
|
|
292
|
-
});
|
|
293
291
|
}
|
|
294
292
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
const { success, results } = await runTestE2EForExternalSystem(appName, {
|
|
301
|
-
env: options.env,
|
|
302
|
-
debug: options.debug,
|
|
303
|
-
verbose: options.verbose,
|
|
304
|
-
async: options.async !== false
|
|
305
|
-
});
|
|
306
|
-
results.forEach(r => {
|
|
307
|
-
const icon = r.success ? chalk.green('✓') : chalk.red('✗');
|
|
308
|
-
const msg = r.error ? `${r.key}: ${r.error}` : r.key;
|
|
309
|
-
logger.log(` ${icon} ${msg}`);
|
|
310
|
-
});
|
|
311
|
-
if (!success) process.exit(1);
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
314
|
-
const { runAppTestE2e } = require('../commands/app-test');
|
|
315
|
-
await runAppTestE2e(appName, { env: options.env });
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
function setupInstallTestE2eLintCommands(program) {
|
|
319
|
-
program.command('install <app>')
|
|
320
|
-
.description('Install dependencies in container (builder apps only)')
|
|
321
|
-
.option('--env <env>', 'dev (running container) or tst (ephemeral with .env)', 'dev')
|
|
322
|
-
.action(async(appName, options) => {
|
|
323
|
-
try {
|
|
324
|
-
const pathsUtil = require('../utils/paths');
|
|
325
|
-
const appType = await pathsUtil.detectAppType(appName).catch(() => null);
|
|
326
|
-
if (appType && appType.baseDir === 'integration') {
|
|
327
|
-
logger.log(chalk.gray('Install is for builder applications only. Use aifabrix shell <app> to run commands in external setups.'));
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
const { runAppInstall } = require('../commands/app-install');
|
|
331
|
-
await runAppInstall(appName, { env: options.env });
|
|
332
|
-
} catch (error) {
|
|
333
|
-
handleCommandError(error, 'install');
|
|
334
|
-
process.exit(1);
|
|
335
|
-
}
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
program.command('test-e2e <app>')
|
|
339
|
-
.description('Run e2e tests (builder: in container; external system: all datasources via dataplane)')
|
|
340
|
-
.option('-e, --env <env>', 'Environment: dev, tst, or pro (builder: dev/tst for container)')
|
|
341
|
-
.option('-v, --verbose', 'Show detailed step output and poll progress')
|
|
342
|
-
.option('--debug', 'Include debug output and write log to integration/<app>/logs/')
|
|
343
|
-
.option('--no-async', 'Use sync mode (no polling); single POST per datasource')
|
|
344
|
-
.action(async(appName, options) => {
|
|
345
|
-
try {
|
|
346
|
-
await runTestE2ECommand(appName, options);
|
|
347
|
-
} catch (error) {
|
|
348
|
-
handleCommandError(error, 'test-e2e');
|
|
349
|
-
process.exit(1);
|
|
350
|
-
}
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
program.command('lint <app>')
|
|
354
|
-
.description('Run lint in container (builder apps only)')
|
|
355
|
-
.option('--env <env>', 'dev (running container) or tst (ephemeral with .env)', 'dev')
|
|
293
|
+
function setupDockerfileGenerateCommand(program) {
|
|
294
|
+
program.command('dockerfile <app>')
|
|
295
|
+
.description('Generate Dockerfile from detected runtime')
|
|
296
|
+
.option('-l, --language <lang>', 'Override language detection')
|
|
297
|
+
.option('-f, --force', 'Overwrite existing Dockerfile')
|
|
356
298
|
.action(async(appName, options) => {
|
|
357
299
|
try {
|
|
358
|
-
const
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
logger.log(chalk.gray('lint is for builder applications only. Use aifabrix shell <app> then make lint or pnpm lint.'));
|
|
362
|
-
return;
|
|
363
|
-
}
|
|
364
|
-
const { runAppLint } = require('../commands/app-test');
|
|
365
|
-
await runAppLint(appName, { env: options.env });
|
|
300
|
+
const dockerfilePath = await app.generateDockerfileForApp(appName, options);
|
|
301
|
+
logger.log(formatSuccessParagraph('Dockerfile generated successfully!'));
|
|
302
|
+
logger.log(chalk.gray(`Location: ${dockerfilePath}`));
|
|
366
303
|
} catch (error) {
|
|
367
|
-
handleCommandError(error, '
|
|
304
|
+
handleCommandError(error, 'dockerfile');
|
|
368
305
|
process.exit(1);
|
|
369
306
|
}
|
|
370
307
|
});
|
|
@@ -373,6 +310,7 @@ function setupInstallTestE2eLintCommands(program) {
|
|
|
373
310
|
function setupPushDeployDockerfileCommands(program) {
|
|
374
311
|
program.command('push <app>')
|
|
375
312
|
.description('Push image to Azure Container Registry')
|
|
313
|
+
.addHelpText('after', PUSH_HELP_AFTER)
|
|
376
314
|
.option('-r, --registry <registry>', 'ACR registry URL (overrides application.yaml)')
|
|
377
315
|
.option('-t, --tag <tag>', 'Image tag(s) - comma-separated for multiple (default: latest)')
|
|
378
316
|
.action(async(appName, options) => {
|
|
@@ -385,15 +323,26 @@ function setupPushDeployDockerfileCommands(program) {
|
|
|
385
323
|
});
|
|
386
324
|
|
|
387
325
|
program.command('deploy <app>')
|
|
388
|
-
.description('Deploy
|
|
326
|
+
.description('Deploy via Miso Controller (Azure or --local)')
|
|
327
|
+
.addHelpText('after', DEPLOY_HELP_AFTER)
|
|
389
328
|
.option('--local', 'Send manifest to controller then run app locally (app: same as aifabrix run <app>; external: restart dataplane)')
|
|
390
329
|
.option('--client-id <id>', 'Client ID (overrides config)')
|
|
391
330
|
.option('--client-secret <secret>', 'Client Secret (overrides config)')
|
|
392
331
|
.option('--poll', 'Poll for deployment status', true)
|
|
393
332
|
.option('--no-poll', 'Do not poll for status')
|
|
333
|
+
.option('--probe', 'After external deploy, run dataplane runtime checks (validation/run); slower')
|
|
334
|
+
.option('--probe-timeout <ms>', 'Timeout for --probe on external deploy (default: 120000)', '120000')
|
|
394
335
|
.action(async(appName, options) => {
|
|
395
336
|
try {
|
|
396
|
-
const
|
|
337
|
+
const probeTimeout =
|
|
338
|
+
options.probeTimeout === undefined || options.probeTimeout === null
|
|
339
|
+
? 120000
|
|
340
|
+
: Number(options.probeTimeout);
|
|
341
|
+
const opts = {
|
|
342
|
+
...options,
|
|
343
|
+
local: !!options.local,
|
|
344
|
+
probeTimeout: Number.isFinite(probeTimeout) ? probeTimeout : 120000
|
|
345
|
+
};
|
|
397
346
|
const outcome = await app.deployApp(appName, opts);
|
|
398
347
|
if (opts.local && outcome) {
|
|
399
348
|
if (outcome.usedExternalDeploy) await app.restartApp('dataplane');
|
|
@@ -405,20 +354,7 @@ function setupPushDeployDockerfileCommands(program) {
|
|
|
405
354
|
}
|
|
406
355
|
});
|
|
407
356
|
|
|
408
|
-
program
|
|
409
|
-
.description('Generate Dockerfile for an application')
|
|
410
|
-
.option('-l, --language <lang>', 'Override language detection')
|
|
411
|
-
.option('-f, --force', 'Overwrite existing Dockerfile')
|
|
412
|
-
.action(async(appName, options) => {
|
|
413
|
-
try {
|
|
414
|
-
const dockerfilePath = await app.generateDockerfileForApp(appName, options);
|
|
415
|
-
logger.log(chalk.green('\n✅ Dockerfile generated successfully!'));
|
|
416
|
-
logger.log(chalk.gray(`Location: ${dockerfilePath}`));
|
|
417
|
-
} catch (error) {
|
|
418
|
-
handleCommandError(error, 'dockerfile');
|
|
419
|
-
process.exit(1);
|
|
420
|
-
}
|
|
421
|
-
});
|
|
357
|
+
setupDockerfileGenerateCommand(program);
|
|
422
358
|
}
|
|
423
359
|
|
|
424
360
|
/**
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview CLI test/install/lint command setup (builder app + external integration dispatch).
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
const chalk = require('chalk');
|
|
8
|
+
const logger = require('../utils/logger');
|
|
9
|
+
const { handleCommandError } = require('../utils/cli-utils');
|
|
10
|
+
const { TEST_HELP_AFTER, TEST_E2E_HELP_AFTER } = require('./setup-app.help');
|
|
11
|
+
|
|
12
|
+
function setupTestCommand(program) {
|
|
13
|
+
program.command('test <app>')
|
|
14
|
+
.description('Tests: builder in container; external = local validation')
|
|
15
|
+
.option('-e, --env <env>', 'For builder app: dev (running container) or tst (ephemeral)', 'dev')
|
|
16
|
+
.option('-v, --verbose', 'Verbose output')
|
|
17
|
+
.option('-d, --debug', 'Write debug log to integration/<systemKey>/logs/ (external only)')
|
|
18
|
+
.option(
|
|
19
|
+
'--sync',
|
|
20
|
+
'Not supported for this command (local validation only). Use aifabrix upload <systemKey> or dataplane test commands with --sync.'
|
|
21
|
+
)
|
|
22
|
+
.addHelpText('after', TEST_HELP_AFTER)
|
|
23
|
+
.action(async(appName, options, cmd) => {
|
|
24
|
+
try {
|
|
25
|
+
const rawArgs = Array.isArray(cmd?.rawArgs) ? cmd.rawArgs : [];
|
|
26
|
+
const envExplicit = rawArgs.includes('-e') || rawArgs.includes('--env');
|
|
27
|
+
const pathsUtil = require('../utils/paths');
|
|
28
|
+
const appType = await pathsUtil.detectAppType(appName).catch(() => null);
|
|
29
|
+
if (options.sync === true) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
'Option --sync is not supported for aifabrix test (local or container runs do not publish to the dataplane). ' +
|
|
32
|
+
'Use: aifabrix upload <systemKey>, then aifabrix test-integration <systemKey> --sync or aifabrix datasource test-integration <datasourceKey> --sync.'
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
if (appType && appType.baseDir === 'integration') {
|
|
36
|
+
const test = require('../external-system/test');
|
|
37
|
+
const externalOpts = {
|
|
38
|
+
...options,
|
|
39
|
+
// Keep help default but don't override auth/env behavior unless user explicitly set it.
|
|
40
|
+
env: envExplicit ? options.env : undefined
|
|
41
|
+
};
|
|
42
|
+
const results = await test.testExternalSystem(appName, externalOpts);
|
|
43
|
+
test.displayTestResults(results, options.verbose, appName);
|
|
44
|
+
if (!results.valid) process.exit(1);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const { runAppTest } = require('../commands/app-test');
|
|
48
|
+
await runAppTest(appName, { env: options.env });
|
|
49
|
+
} catch (error) {
|
|
50
|
+
handleCommandError(error, 'test');
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function runTestE2ECommand(appName, options) {
|
|
57
|
+
const pathsUtil = require('../utils/paths');
|
|
58
|
+
const appType = await pathsUtil.detectAppType(appName).catch(() => null);
|
|
59
|
+
if (options.sync === true && appType && appType.baseDir === 'builder') {
|
|
60
|
+
throw new Error(
|
|
61
|
+
'Option --sync applies only to external integration E2E (integration/<systemKey>/). ' +
|
|
62
|
+
'Remove --sync for builder app E2E, or use aifabrix upload from the integration folder first.'
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
if (appType && appType.baseDir === 'integration') {
|
|
66
|
+
const { runTestE2EForExternalSystem } = require('../commands/test-e2e-external');
|
|
67
|
+
const { success, results } = await runTestE2EForExternalSystem(appName, {
|
|
68
|
+
env: options.env,
|
|
69
|
+
debug: options.debug,
|
|
70
|
+
verbose: options.verbose,
|
|
71
|
+
async: options.async !== false,
|
|
72
|
+
sync: options.sync === true
|
|
73
|
+
});
|
|
74
|
+
const { displayIntegrationTestResults } = require('../utils/external-system-display');
|
|
75
|
+
displayIntegrationTestResults(
|
|
76
|
+
{
|
|
77
|
+
systemKey: appName,
|
|
78
|
+
success,
|
|
79
|
+
datasourceResults: results.map(r => ({
|
|
80
|
+
key: r.key,
|
|
81
|
+
success: r.success,
|
|
82
|
+
error: r.error,
|
|
83
|
+
skipped: false,
|
|
84
|
+
datasourceTestRun: r.datasourceTestRun
|
|
85
|
+
}))
|
|
86
|
+
},
|
|
87
|
+
options.verbose,
|
|
88
|
+
{ debug: options.debug, runType: 'e2e' }
|
|
89
|
+
);
|
|
90
|
+
if (!success) process.exit(1);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const { runAppTestE2e } = require('../commands/app-test');
|
|
94
|
+
await runAppTestE2e(appName, { env: options.env });
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function setupInstallCommand(program) {
|
|
98
|
+
program.command('install <app>')
|
|
99
|
+
.description('Install deps in container (builder apps only)')
|
|
100
|
+
.option('--env <env>', 'dev (running container) or tst (ephemeral with .env)', 'dev')
|
|
101
|
+
.action(async(appName, options) => {
|
|
102
|
+
try {
|
|
103
|
+
const pathsUtil = require('../utils/paths');
|
|
104
|
+
const appType = await pathsUtil.detectAppType(appName).catch(() => null);
|
|
105
|
+
if (appType && appType.baseDir === 'integration') {
|
|
106
|
+
logger.log(
|
|
107
|
+
chalk.gray('Install is for builder applications only. Use aifabrix shell <app> to run commands in external setups.')
|
|
108
|
+
);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const { runAppInstall } = require('../commands/app-install');
|
|
112
|
+
await runAppInstall(appName, { env: options.env });
|
|
113
|
+
} catch (error) {
|
|
114
|
+
handleCommandError(error, 'install');
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function setupTestE2eCommand(program) {
|
|
121
|
+
program.command('test-e2e <app>')
|
|
122
|
+
.description('E2E: builder in container; external = all datasources via dataplane')
|
|
123
|
+
.option('-e, --env <env>', 'Environment: dev, tst, or pro (builder: dev/tst for container)', 'dev')
|
|
124
|
+
.option('-v, --verbose', 'Show detailed step output and poll progress')
|
|
125
|
+
.option('-d, --debug', 'Include debug output and write log to integration/<systemKey>/logs/')
|
|
126
|
+
.option(
|
|
127
|
+
'--sync',
|
|
128
|
+
'Publish local system and datasource files to the dataplane before running E2E (same as aifabrix upload <systemKey>; external integration only)'
|
|
129
|
+
)
|
|
130
|
+
.addHelpText('after', TEST_E2E_HELP_AFTER)
|
|
131
|
+
.action(async(appName, options, cmd) => {
|
|
132
|
+
try {
|
|
133
|
+
const rawArgs = Array.isArray(cmd?.rawArgs) ? cmd.rawArgs : [];
|
|
134
|
+
const envExplicit = rawArgs.includes('-e') || rawArgs.includes('--env');
|
|
135
|
+
const externalOpts = {
|
|
136
|
+
...options,
|
|
137
|
+
env: envExplicit ? options.env : undefined,
|
|
138
|
+
async: true // system-level command surface omits --no-async; always poll for completeness
|
|
139
|
+
};
|
|
140
|
+
await runTestE2ECommand(appName, externalOpts);
|
|
141
|
+
} catch (error) {
|
|
142
|
+
handleCommandError(error, 'test-e2e');
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function setupLintCommand(program) {
|
|
149
|
+
program.command('lint <app>')
|
|
150
|
+
.description('Lint in container (builder apps only)')
|
|
151
|
+
.option('--env <env>', 'dev (running container) or tst (ephemeral with .env)', 'dev')
|
|
152
|
+
.action(async(appName, options) => {
|
|
153
|
+
try {
|
|
154
|
+
const pathsUtil = require('../utils/paths');
|
|
155
|
+
const appType = await pathsUtil.detectAppType(appName).catch(() => null);
|
|
156
|
+
if (appType && appType.baseDir === 'integration') {
|
|
157
|
+
logger.log(chalk.gray('lint is for builder applications only. Use aifabrix shell <app> then make lint or pnpm lint.'));
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const { runAppLint } = require('../commands/app-test');
|
|
161
|
+
await runAppLint(appName, { env: options.env });
|
|
162
|
+
} catch (error) {
|
|
163
|
+
handleCommandError(error, 'lint');
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function setupInstallTestE2eLintCommands(program) {
|
|
170
|
+
setupInstallCommand(program);
|
|
171
|
+
setupTestCommand(program);
|
|
172
|
+
setupTestE2eCommand(program);
|
|
173
|
+
setupLintCommand(program);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
module.exports = {
|
|
177
|
+
setupInstallTestE2eLintCommands
|
|
178
|
+
};
|
|
179
|
+
|