@aifabrix/builder 2.43.0 → 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 +1 -1
- 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 +31 -0
- package/integration/hubspot-test/create-hubspot.js +5 -5
- package/integration/hubspot-test/hubspot-test-datasource-company.json +58 -462
- package/integration/hubspot-test/hubspot-test-datasource-contact.json +61 -555
- package/integration/hubspot-test/hubspot-test-datasource-deal.json +63 -506
- package/integration/hubspot-test/hubspot-test-datasource-users.json +42 -83
- package/integration/hubspot-test/hubspot-test-deploy.json +3 -3
- package/integration/hubspot-test/test-dataplane-down-tests.js +1 -7
- package/integration/hubspot-test/test-dataplane-down.js +3 -3
- package/integration/hubspot-test/test.js +35 -43
- 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/types/dev.types.js +4 -3
- package/lib/api/types/pipeline.types.js +8 -5
- 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 +16 -7
- package/lib/app/rotate-secret.js +14 -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 +57 -121
- package/lib/cli/setup-app.test-commands.js +179 -0
- package/lib/cli/setup-auth.js +19 -5
- 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 +170 -113
- package/lib/cli/setup-environment.js +7 -1
- package/lib/cli/setup-external-system.js +62 -22
- package/lib/cli/setup-infra.js +126 -47
- package/lib/cli/setup-parameters.js +32 -0
- package/lib/cli/setup-secrets.js +106 -8
- package/lib/cli/setup-service-user.js +1 -1
- package/lib/cli/setup-utility.js +36 -20
- 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 +6 -6
- 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 +105 -98
- 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 +2 -2
- package/lib/commands/repair.js +21 -3
- package/lib/commands/secrets-list.js +23 -12
- package/lib/commands/secrets-remove-all.js +220 -0
- package/lib/commands/secrets-remove.js +21 -12
- package/lib/commands/secrets-set.js +21 -12
- package/lib/commands/secrets-validate.js +4 -4
- package/lib/commands/secure.js +10 -9
- package/lib/commands/service-user.js +26 -25
- package/lib/commands/test-e2e-external.js +27 -1
- package/lib/commands/up-common.js +3 -2
- package/lib/commands/up-dataplane.js +29 -16
- 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 +14 -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 +55 -56
- package/lib/core/diff.js +3 -2
- package/lib/core/ensure-encryption-key.js +1 -1
- 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 +200 -37
- package/lib/core/templates-env.js +4 -3
- package/lib/datasource/abac-validator.js +1 -10
- package/lib/datasource/deploy.js +75 -53
- package/lib/datasource/field-reference-validator.js +9 -6
- package/lib/datasource/integration-context.js +63 -0
- package/lib/datasource/list.js +8 -7
- package/lib/datasource/log-viewer.js +84 -53
- package/lib/datasource/resolve-app.js +4 -4
- package/lib/datasource/test-e2e.js +95 -146
- package/lib/datasource/test-integration.js +114 -122
- 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 +157 -13
- 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 +92 -6
- 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.js +16 -4
- package/lib/generator/helpers.js +58 -3
- package/lib/generator/index.js +4 -0
- package/lib/generator/split-readme.js +12 -7
- package/lib/generator/split-variables.js +2 -1
- package/lib/generator/split.js +1 -1
- package/lib/generator/wizard-readme.js +3 -3
- package/lib/generator/wizard.js +8 -8
- package/lib/infrastructure/compose.js +60 -6
- package/lib/infrastructure/helpers.js +201 -29
- package/lib/infrastructure/index.js +28 -17
- 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 +1200 -442
- 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-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 +166 -7
- 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/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 +35 -8
- package/lib/utils/env-template.js +2 -2
- package/lib/utils/environment-scoped-resources.js +144 -0
- package/lib/utils/error-formatter.js +92 -13
- 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-readme.js +8 -1
- package/lib/utils/external-system-display.js +234 -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 +30 -12
- package/lib/utils/health-check-url.js +119 -0
- package/lib/utils/health-check.js +59 -25
- package/lib/utils/help-builder.js +11 -8
- 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 +3 -4
- package/lib/utils/paths.js +134 -47
- 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 +169 -49
- package/lib/utils/secrets-helpers.js +70 -59
- package/lib/utils/secrets-kv-scope.js +60 -0
- package/lib/utils/secrets-utils.js +32 -38
- package/lib/utils/secrets-validation.js +3 -1
- package/lib/utils/secrets-yaml-preserve.js +109 -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 +1 -2
- 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 +33 -14
- package/lib/validation/datasource-warnings.js +56 -0
- package/lib/validation/env-template-auth.js +1 -1
- package/lib/validation/external-manifest-validator.js +27 -7
- package/lib/validation/validate-display.js +37 -31
- package/lib/validation/validate.js +4 -13
- package/lib/validation/validator-unresolved-placeholders.js +98 -0
- package/lib/validation/validator.js +22 -65
- package/lib/validation/wizard-config-validator.js +2 -1
- package/package.json +7 -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 +75 -17
- 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 +42 -12
- 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/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/lib/api/external-test.api.js +0 -111
- package/lib/schema/env-config.yaml +0 -60
|
@@ -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')
|
|
@@ -142,15 +162,15 @@ Examples:
|
|
|
142
162
|
$ aifabrix wizard --config wizard.yaml Run headless from a wizard config file
|
|
143
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
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
|
+
|
package/lib/cli/setup-auth.js
CHANGED
|
@@ -14,9 +14,22 @@ const { handleLogout } = require('../commands/logout');
|
|
|
14
14
|
const { handleAuthStatus } = require('../commands/auth-status');
|
|
15
15
|
const { handleAuthConfig } = require('../commands/auth-config');
|
|
16
16
|
|
|
17
|
+
const LOGIN_HELP_AFTER = `
|
|
18
|
+
Examples:
|
|
19
|
+
$ aifabrix login
|
|
20
|
+
$ aifabrix login -m credentials -a myapp -e dev
|
|
21
|
+
`;
|
|
22
|
+
|
|
23
|
+
const AUTH_HELP_AFTER = `
|
|
24
|
+
Without options: show auth status (same as: aifabrix auth status).
|
|
25
|
+
With --set-controller or --set-environment: write defaults to config.yaml.
|
|
26
|
+
Subcommand: auth status [--validate] for CI/scripts.
|
|
27
|
+
`;
|
|
28
|
+
|
|
17
29
|
function setupLoginCommand(program) {
|
|
18
30
|
program.command('login')
|
|
19
|
-
.description('
|
|
31
|
+
.description('Sign in to Miso Controller (device or credentials flow)')
|
|
32
|
+
.addHelpText('after', LOGIN_HELP_AFTER)
|
|
20
33
|
.option('-c, --controller <url>', 'Controller URL (default: from config or developer ID, e.g. http://localhost:3000)')
|
|
21
34
|
.option('-m, --method <method>', 'Authentication method (device|credentials)', 'device')
|
|
22
35
|
.option('-a, --app <app>', 'Application name (required for credentials method, reads from secrets.local.yaml)')
|
|
@@ -29,7 +42,7 @@ function setupLoginCommand(program) {
|
|
|
29
42
|
try {
|
|
30
43
|
await handleLogin(options);
|
|
31
44
|
} catch (error) {
|
|
32
|
-
logger.error(chalk.red('\n
|
|
45
|
+
logger.error(chalk.red('\n✖ Login failed:'), error.message);
|
|
33
46
|
process.exit(1);
|
|
34
47
|
}
|
|
35
48
|
});
|
|
@@ -37,7 +50,7 @@ function setupLoginCommand(program) {
|
|
|
37
50
|
|
|
38
51
|
function setupLogoutCommand(program) {
|
|
39
52
|
program.command('logout')
|
|
40
|
-
.description('Clear
|
|
53
|
+
.description('Clear stored tokens (optional filter by controller/env/app)')
|
|
41
54
|
.option('-c, --controller <url>', 'Clear device tokens for specific controller')
|
|
42
55
|
.option('-e, --environment <env>', 'Clear client tokens for specific environment')
|
|
43
56
|
.option('-a, --app <app>', 'Clear client tokens for specific app (requires --environment)')
|
|
@@ -61,7 +74,8 @@ function setupAuthSubcommands(program) {
|
|
|
61
74
|
}
|
|
62
75
|
};
|
|
63
76
|
const auth = program.command('auth')
|
|
64
|
-
.description('
|
|
77
|
+
.description('Show auth status or set default controller/environment')
|
|
78
|
+
.addHelpText('after', AUTH_HELP_AFTER)
|
|
65
79
|
.option('--set-controller <url>', 'Set default controller URL in config')
|
|
66
80
|
.option('--set-environment <env>', 'Set default environment in config')
|
|
67
81
|
.action(async(options) => {
|
|
@@ -82,7 +96,7 @@ function setupAuthSubcommands(program) {
|
|
|
82
96
|
}
|
|
83
97
|
});
|
|
84
98
|
auth.command('status')
|
|
85
|
-
.description('
|
|
99
|
+
.description('Show tokens/session for current controller and environment')
|
|
86
100
|
.option('--validate', 'Exit with code 1 when not authenticated (for scripted use, e.g. manual test setup)')
|
|
87
101
|
.action(authStatusHandler);
|
|
88
102
|
}
|
|
@@ -15,10 +15,22 @@ const { runCredentialEnv } = require('../commands/credential-env');
|
|
|
15
15
|
const { runCredentialPush } = require('../commands/credential-push');
|
|
16
16
|
const { runDeploymentList } = require('../commands/deployment-list');
|
|
17
17
|
|
|
18
|
+
const CREDENTIAL_HELP_AFTER = `
|
|
19
|
+
Subcommands:
|
|
20
|
+
env <systemKey> Prompt for KV_* values → integration/<key>/.env
|
|
21
|
+
push <systemKey> Upload secrets from .env to Dataplane
|
|
22
|
+
list List credentials (pagination: --page-size)
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
const DEPLOYMENT_HELP_AFTER = `
|
|
26
|
+
Subcommand:
|
|
27
|
+
list Recent deployments for the current environment
|
|
28
|
+
`;
|
|
29
|
+
|
|
18
30
|
function setupCredentialEnvAndPush(credential) {
|
|
19
31
|
credential
|
|
20
|
-
.command('env <
|
|
21
|
-
.description('
|
|
32
|
+
.command('env <systemKey>')
|
|
33
|
+
.description('Interactive KV_* prompts → integration/<key>/.env')
|
|
22
34
|
.action(async(systemKey, _options) => {
|
|
23
35
|
try {
|
|
24
36
|
await runCredentialEnv(systemKey);
|
|
@@ -29,8 +41,8 @@ function setupCredentialEnvAndPush(credential) {
|
|
|
29
41
|
}
|
|
30
42
|
});
|
|
31
43
|
credential
|
|
32
|
-
.command('push <
|
|
33
|
-
.description('Push
|
|
44
|
+
.command('push <systemKey>')
|
|
45
|
+
.description('Push KV_* secrets from .env to Dataplane')
|
|
34
46
|
.action(async(systemKey, _options) => {
|
|
35
47
|
try {
|
|
36
48
|
await runCredentialPush(systemKey);
|
|
@@ -49,11 +61,12 @@ function setupCredentialEnvAndPush(credential) {
|
|
|
49
61
|
function setupCredentialDeploymentCommands(program) {
|
|
50
62
|
const credential = program
|
|
51
63
|
.command('credential')
|
|
52
|
-
.description('
|
|
64
|
+
.description('Dataplane credentials: env, push, list')
|
|
65
|
+
.addHelpText('after', CREDENTIAL_HELP_AFTER);
|
|
53
66
|
setupCredentialEnvAndPush(credential);
|
|
54
67
|
credential
|
|
55
68
|
.command('list')
|
|
56
|
-
.description('
|
|
69
|
+
.description('List credentials from Dataplane')
|
|
57
70
|
.option('--active-only', 'List only active credentials')
|
|
58
71
|
.option('--page-size <n>', 'Items per page', '50')
|
|
59
72
|
.action(async(options) => {
|
|
@@ -72,11 +85,12 @@ function setupCredentialDeploymentCommands(program) {
|
|
|
72
85
|
|
|
73
86
|
const deployment = program
|
|
74
87
|
.command('deployment')
|
|
75
|
-
.description('
|
|
88
|
+
.description('Controller deployments (list)')
|
|
89
|
+
.addHelpText('after', DEPLOYMENT_HELP_AFTER);
|
|
76
90
|
|
|
77
91
|
deployment
|
|
78
92
|
.command('list')
|
|
79
|
-
.description('List
|
|
93
|
+
.description('List recent deployments for current environment')
|
|
80
94
|
.option('--controller <url>', 'Controller URL (default: from config)')
|
|
81
95
|
.option('--environment <env>', 'Environment key (default: from config)')
|
|
82
96
|
.option('--page-size <n>', 'Items per page', '50')
|