@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,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment-scoped resource naming (shared infra: dev/tst on same Postgres/Redis/Docker).
|
|
3
|
+
* Effective only when user gate AND app flag AND run env is dev|tst.
|
|
4
|
+
*
|
|
5
|
+
* @fileoverview environmentScopedResources + useEnvironmentScopedResources helpers
|
|
6
|
+
* @author AI Fabrix Team
|
|
7
|
+
* @version 1.0.0
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
'use strict';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Run/env keys that participate in resource prefixing (not pro).
|
|
14
|
+
* @param {string} envKey - Normalized lowercase env key
|
|
15
|
+
* @returns {boolean}
|
|
16
|
+
*/
|
|
17
|
+
function isScopedRunEnvironmentKey(envKey) {
|
|
18
|
+
if (!envKey || typeof envKey !== 'string') return false;
|
|
19
|
+
const k = envKey.toLowerCase();
|
|
20
|
+
return k === 'dev' || k === 'tst';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Effective local/deploy prefix behavior: user gate ∧ app flag ∧ dev|tst.
|
|
25
|
+
*
|
|
26
|
+
* @param {boolean} useEnvironmentScopedResources - ~/.aifabrix/config.yaml
|
|
27
|
+
* @param {boolean} appEnvironmentScopedResources - application.yaml
|
|
28
|
+
* @param {string} runEnvKey - dev | tst | pro | other (lowercase)
|
|
29
|
+
* @returns {boolean}
|
|
30
|
+
*/
|
|
31
|
+
function computeEffectiveEnvironmentScopedResources(
|
|
32
|
+
useEnvironmentScopedResources,
|
|
33
|
+
appEnvironmentScopedResources,
|
|
34
|
+
runEnvKey
|
|
35
|
+
) {
|
|
36
|
+
return (
|
|
37
|
+
Boolean(useEnvironmentScopedResources) &&
|
|
38
|
+
Boolean(appEnvironmentScopedResources) &&
|
|
39
|
+
isScopedRunEnvironmentKey(runEnvKey)
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Redis logical DB index when env-scoped resources are effective.
|
|
45
|
+
* dev → 0, tst → 1 (single shared Redis instance).
|
|
46
|
+
*
|
|
47
|
+
* @param {string} runEnvKey - dev | tst
|
|
48
|
+
* @returns {number|null} Index or null if not applicable
|
|
49
|
+
*/
|
|
50
|
+
function redisDbIndexForScopedRunEnv(runEnvKey) {
|
|
51
|
+
if (!runEnvKey || typeof runEnvKey !== 'string') return null;
|
|
52
|
+
const k = runEnvKey.toLowerCase();
|
|
53
|
+
if (k === 'dev') return 0;
|
|
54
|
+
if (k === 'tst') return 1;
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Docker container name for local `aifabrix run` when env-scoping applies.
|
|
60
|
+
*
|
|
61
|
+
* @param {string} appName - Application key
|
|
62
|
+
* @param {string|number} devId - Developer id
|
|
63
|
+
* @param {number} idNum - Parsed numeric developer id
|
|
64
|
+
* @param {string} envKey - dev | tst
|
|
65
|
+
* @returns {string}
|
|
66
|
+
*/
|
|
67
|
+
function buildScopedLocalContainerName(appName, devId, idNum, envKey) {
|
|
68
|
+
const e = String(envKey).toLowerCase();
|
|
69
|
+
if (idNum === 0) {
|
|
70
|
+
return `aifabrix-${e}-${appName}`;
|
|
71
|
+
}
|
|
72
|
+
return `aifabrix-dev${devId}-${e}-${appName}`;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Default local container name (no env scope).
|
|
77
|
+
*
|
|
78
|
+
* @param {string} appName - Application key
|
|
79
|
+
* @param {string|number} devId - Developer id
|
|
80
|
+
* @param {number} idNum - Parsed numeric developer id
|
|
81
|
+
* @returns {string}
|
|
82
|
+
*/
|
|
83
|
+
function buildDefaultLocalContainerName(appName, devId, idNum) {
|
|
84
|
+
if (idNum === 0) {
|
|
85
|
+
return `aifabrix-${appName}`;
|
|
86
|
+
}
|
|
87
|
+
return `aifabrix-dev${devId}-${appName}`;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Resolved container name for run/stop/status.
|
|
92
|
+
*
|
|
93
|
+
* @param {string} appName - Application key
|
|
94
|
+
* @param {string|number} developerId - Developer id
|
|
95
|
+
* @param {boolean} effectiveScoped - From {@link computeEffectiveEnvironmentScopedResources}
|
|
96
|
+
* @param {string} [runEnvKey] - dev | tst (required when effectiveScoped)
|
|
97
|
+
* @returns {string}
|
|
98
|
+
*/
|
|
99
|
+
function resolveRunContainerName(appName, developerId, effectiveScoped, runEnvKey) {
|
|
100
|
+
const idNum = typeof developerId === 'string' ? parseInt(developerId, 10) : developerId;
|
|
101
|
+
if (effectiveScoped && runEnvKey) {
|
|
102
|
+
return buildScopedLocalContainerName(appName, developerId, idNum, runEnvKey);
|
|
103
|
+
}
|
|
104
|
+
return buildDefaultLocalContainerName(appName, developerId, idNum);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Traefik PathPrefix: prefix /{envKey} before pattern base (e.g. /api → /dev/api).
|
|
109
|
+
*
|
|
110
|
+
* @param {string} basePath - From derivePathFromPattern
|
|
111
|
+
* @param {string} envKey - dev | tst
|
|
112
|
+
* @returns {string}
|
|
113
|
+
*/
|
|
114
|
+
function buildEnvScopedTraefikPath(basePath, envKey) {
|
|
115
|
+
const e = String(envKey).toLowerCase();
|
|
116
|
+
const trimmed = (basePath || '/').trim() || '/';
|
|
117
|
+
if (trimmed === '/') {
|
|
118
|
+
return `/${e}`;
|
|
119
|
+
}
|
|
120
|
+
const withSlash = trimmed.startsWith('/') ? trimmed : `/${trimmed}`;
|
|
121
|
+
return `/${e}${withSlash}`.replace(/\/{2,}/g, '/');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Compose service + Traefik router key when env-scoped (unique per env on shared host).
|
|
126
|
+
*
|
|
127
|
+
* @param {string} appName - Application key
|
|
128
|
+
* @param {string} envKey - dev | tst
|
|
129
|
+
* @returns {string}
|
|
130
|
+
*/
|
|
131
|
+
function composeTraefikServiceKey(appName, envKey) {
|
|
132
|
+
return `${String(envKey).toLowerCase()}-${appName}`;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
module.exports = {
|
|
136
|
+
isScopedRunEnvironmentKey,
|
|
137
|
+
computeEffectiveEnvironmentScopedResources,
|
|
138
|
+
redisDbIndexForScopedRunEnv,
|
|
139
|
+
buildScopedLocalContainerName,
|
|
140
|
+
buildDefaultLocalContainerName,
|
|
141
|
+
resolveRunContainerName,
|
|
142
|
+
buildEnvScopedTraefikPath,
|
|
143
|
+
composeTraefikServiceKey
|
|
144
|
+
};
|
|
@@ -47,15 +47,52 @@ function getFieldName(error) {
|
|
|
47
47
|
return path ? `Field "${path}"` : 'Configuration';
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Resolves a value from root using an AJV instancePath (JSON Pointer, e.g. /roles/0/value).
|
|
52
|
+
* @param {*} root - Object or array validated at root
|
|
53
|
+
* @param {string} instancePath - AJV instancePath (leading slash or empty)
|
|
54
|
+
* @returns {*|undefined}
|
|
55
|
+
*/
|
|
56
|
+
function getValueAtInstancePath(root, instancePath) {
|
|
57
|
+
if (root === undefined || root === null) return undefined;
|
|
58
|
+
if (!instancePath || instancePath === '' || instancePath === '/') return root;
|
|
59
|
+
const parts = instancePath.split('/').filter(Boolean);
|
|
60
|
+
let cur = root;
|
|
61
|
+
for (const p of parts) {
|
|
62
|
+
if (cur === undefined || cur === null) return undefined;
|
|
63
|
+
const key = /^\d+$/.test(p) ? parseInt(p, 10) : p;
|
|
64
|
+
cur = cur[key];
|
|
65
|
+
}
|
|
66
|
+
return cur;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Resolves the failing value for display (AJV may omit `data` depending on compile options).
|
|
71
|
+
* @param {Object} error - AJV error
|
|
72
|
+
* @param {Object} [options] - rootData or deploymentManifest (same shape as validated root)
|
|
73
|
+
* @returns {*|undefined}
|
|
74
|
+
*/
|
|
75
|
+
function resolveErrorDataValue(error, options = {}) {
|
|
76
|
+
if (error && error.data !== undefined) return error.data;
|
|
77
|
+
const root = options.rootData !== undefined ? options.rootData : options.deploymentManifest;
|
|
78
|
+
if (!root) return undefined;
|
|
79
|
+
return getValueAtInstancePath(root, error.instancePath || '');
|
|
80
|
+
}
|
|
81
|
+
|
|
50
82
|
/**
|
|
51
83
|
* Formats a pattern validation error with the actual invalid value
|
|
52
84
|
* @function formatPatternError
|
|
53
85
|
* @param {string} field - Field name
|
|
54
86
|
* @param {Object} error - Validation error object
|
|
87
|
+
* @param {Object} [options] - Pass rootData or deploymentManifest to show value when error.data is missing
|
|
55
88
|
* @returns {string} Formatted error message
|
|
56
89
|
*/
|
|
57
|
-
function formatPatternError(field, error) {
|
|
58
|
-
const
|
|
90
|
+
function formatPatternError(field, error, options = {}) {
|
|
91
|
+
const actual = resolveErrorDataValue(error, options);
|
|
92
|
+
const invalidValue =
|
|
93
|
+
actual === undefined
|
|
94
|
+
? '(unavailable — pass rootData/deploymentManifest to formatValidationErrors to show it)'
|
|
95
|
+
: JSON.stringify(actual);
|
|
59
96
|
const patternDesc = getPatternDescription(error.params?.pattern);
|
|
60
97
|
return `${field}: Invalid value ${invalidValue} - ${patternDesc}`;
|
|
61
98
|
}
|
|
@@ -121,19 +158,16 @@ function createKeywordFormatters(field, error) {
|
|
|
121
158
|
? `${field}: Must be at most ${params.limit} characters`
|
|
122
159
|
: `${field}: Too long`,
|
|
123
160
|
|
|
161
|
+
minItems: params.limit !== undefined
|
|
162
|
+
? `${field}: must have at least ${params.limit} item(s)`
|
|
163
|
+
: `${field}: too few items`,
|
|
164
|
+
|
|
124
165
|
enum: params.allowedValues && params.allowedValues.length > 0
|
|
125
166
|
? `${field}: Must be one of: ${params.allowedValues.join(', ')}`
|
|
126
167
|
: `${field}: Must be one of: unknown`
|
|
127
168
|
};
|
|
128
169
|
}
|
|
129
170
|
|
|
130
|
-
/**
|
|
131
|
-
* Formats a single validation error into a developer-friendly message
|
|
132
|
-
*
|
|
133
|
-
* @function formatSingleError
|
|
134
|
-
* @param {Object} error - Raw validation error from Ajv
|
|
135
|
-
* @returns {string} Formatted error message
|
|
136
|
-
*/
|
|
137
171
|
/**
|
|
138
172
|
* Formats oneOf/anyOf validation errors with actionable message
|
|
139
173
|
* @param {string} field - Field name
|
|
@@ -163,12 +197,55 @@ function formatConstError(field, error) {
|
|
|
163
197
|
return `${field}: invalid value (constraint violation)`;
|
|
164
198
|
}
|
|
165
199
|
|
|
166
|
-
|
|
200
|
+
/** JSON Pointer: /permissions/<index>/roles */
|
|
201
|
+
const PERMISSION_ROLES_INSTANCE_PATH = /^\/permissions\/(\d+)\/roles$/;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Clear message when permissions[i].roles is [] (schema minItems: 1).
|
|
205
|
+
* @param {Object} error - AJV error
|
|
206
|
+
* @param {Object} [options] - Optional context
|
|
207
|
+
* @param {Object} [options.deploymentManifest] - Deploy JSON being validated (for permission name)
|
|
208
|
+
* @returns {string|null}
|
|
209
|
+
*/
|
|
210
|
+
function tryFormatPermissionRolesMinItemsError(error, options) {
|
|
211
|
+
if (error.keyword !== 'minItems') {
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
const m = (error.instancePath || '').match(PERMISSION_ROLES_INSTANCE_PATH);
|
|
215
|
+
if (!m) {
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
const idx = parseInt(m[1], 10);
|
|
219
|
+
const perms = options?.deploymentManifest?.permissions;
|
|
220
|
+
const perm = Array.isArray(perms) ? perms[idx] : null;
|
|
221
|
+
const named =
|
|
222
|
+
perm && typeof perm.name === 'string' && perm.name.trim()
|
|
223
|
+
? ` "${perm.name.trim()}"`
|
|
224
|
+
: ` at permissions[${idx}]`;
|
|
225
|
+
return (
|
|
226
|
+
`RBAC: permission${named} has an empty "roles" array. ` +
|
|
227
|
+
'Each permission must list at least one role, and each string must match a role "value" from your "roles" list ' +
|
|
228
|
+
'(in application.yaml or rbac.yaml under the app folder). ' +
|
|
229
|
+
'Add roles, e.g. roles: ["admin"], or remove the permission if it is unused.'
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* @param {Object} error - Raw validation error from Ajv
|
|
235
|
+
* @param {Object} [options] - Optional; use deploymentManifest for richer RBAC messages
|
|
236
|
+
* @returns {string} Formatted error message
|
|
237
|
+
*/
|
|
238
|
+
function formatSingleError(error, options) {
|
|
167
239
|
const field = getFieldName(error);
|
|
168
240
|
|
|
241
|
+
const rbacRolesMsg = tryFormatPermissionRolesMinItemsError(error, options);
|
|
242
|
+
if (rbacRolesMsg) {
|
|
243
|
+
return rbacRolesMsg;
|
|
244
|
+
}
|
|
245
|
+
|
|
169
246
|
// Handle pattern errors with special formatting
|
|
170
247
|
if (error.keyword === 'pattern') {
|
|
171
|
-
return formatPatternError(field, error);
|
|
248
|
+
return formatPatternError(field, error, options);
|
|
172
249
|
}
|
|
173
250
|
if (error.keyword === 'additionalProperties') {
|
|
174
251
|
return formatAdditionalPropertiesError(field, error);
|
|
@@ -194,18 +271,19 @@ function formatSingleError(error) {
|
|
|
194
271
|
*
|
|
195
272
|
* @function formatValidationErrors
|
|
196
273
|
* @param {Array} errors - Raw validation errors from Ajv
|
|
274
|
+
* @param {Object} [options] - Optional; pass `{ deploymentManifest }` or `{ rootData }` for RBAC/pattern detail
|
|
197
275
|
* @returns {Array} Formatted error messages
|
|
198
276
|
*
|
|
199
277
|
* @example
|
|
200
278
|
* const messages = formatValidationErrors(ajvErrors);
|
|
201
279
|
* // Returns: ['Port must be between 1 and 65535', 'Missing required field: displayName']
|
|
202
280
|
*/
|
|
203
|
-
function formatValidationErrors(errors) {
|
|
281
|
+
function formatValidationErrors(errors, options) {
|
|
204
282
|
if (!Array.isArray(errors)) {
|
|
205
283
|
return ['Unknown validation error'];
|
|
206
284
|
}
|
|
207
285
|
|
|
208
|
-
return errors.map(formatSingleError);
|
|
286
|
+
return errors.map((e) => formatSingleError(e, options));
|
|
209
287
|
}
|
|
210
288
|
|
|
211
289
|
/**
|
|
@@ -232,5 +310,6 @@ module.exports = {
|
|
|
232
310
|
formatValidationErrors,
|
|
233
311
|
formatMissingDbPasswordError,
|
|
234
312
|
getPatternDescription,
|
|
313
|
+
getValueAtInstancePath,
|
|
235
314
|
PATTERN_DESCRIPTIONS
|
|
236
315
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { formatBlockingError } = require('../cli-test-layout-chalk');
|
|
1
2
|
/**
|
|
2
3
|
* HTTP Status Error Formatters
|
|
3
4
|
*
|
|
@@ -123,7 +124,7 @@ function addAuthenticationGuidance(lines, errorData) {
|
|
|
123
124
|
|
|
124
125
|
function formatAuthenticationError(errorData) {
|
|
125
126
|
const lines = [];
|
|
126
|
-
lines.push(
|
|
127
|
+
lines.push(formatBlockingError('Authentication Failed\n'));
|
|
127
128
|
|
|
128
129
|
addControllerUrlInfo(lines, errorData);
|
|
129
130
|
addAttemptedUrlsInfo(lines, errorData);
|
|
@@ -148,7 +149,7 @@ function formatAuthenticationError(errorData) {
|
|
|
148
149
|
*/
|
|
149
150
|
function formatServerError(errorData) {
|
|
150
151
|
const lines = [];
|
|
151
|
-
lines.push(
|
|
152
|
+
lines.push(formatBlockingError('Server Error\n'));
|
|
152
153
|
|
|
153
154
|
// Show controller URL if available
|
|
154
155
|
if (errorData.controllerUrl) {
|
|
@@ -183,7 +184,7 @@ function formatServerError(errorData) {
|
|
|
183
184
|
*/
|
|
184
185
|
function formatConflictError(errorData) {
|
|
185
186
|
const lines = [];
|
|
186
|
-
lines.push(
|
|
187
|
+
lines.push(formatBlockingError('Conflict\n'));
|
|
187
188
|
|
|
188
189
|
// Show controller URL if available
|
|
189
190
|
if (errorData.controllerUrl) {
|
|
@@ -252,7 +253,7 @@ function getNotFoundGuidance(detail) {
|
|
|
252
253
|
*/
|
|
253
254
|
function formatNotFoundError(errorData) {
|
|
254
255
|
const lines = [];
|
|
255
|
-
lines.push(
|
|
256
|
+
lines.push(formatBlockingError('Not Found\n'));
|
|
256
257
|
|
|
257
258
|
// Show controller URL if available
|
|
258
259
|
if (errorData.controllerUrl) {
|
|
@@ -289,7 +290,7 @@ function formatNotFoundError(errorData) {
|
|
|
289
290
|
*/
|
|
290
291
|
function formatGenericError(errorData, statusCode) {
|
|
291
292
|
const lines = [];
|
|
292
|
-
lines.push(chalk.red(
|
|
293
|
+
lines.push(chalk.red(`✖ Error (HTTP ${statusCode})\n`));
|
|
293
294
|
|
|
294
295
|
// Show controller URL if available
|
|
295
296
|
if (errorData.controllerUrl) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { formatBlockingError } = require('../cli-test-layout-chalk');
|
|
1
2
|
/**
|
|
2
3
|
* Network Error Formatters
|
|
3
4
|
*
|
|
@@ -135,7 +136,7 @@ function addCorrelationId(lines, errorData) {
|
|
|
135
136
|
*/
|
|
136
137
|
function formatNetworkError(errorMessage, errorData) {
|
|
137
138
|
const lines = [];
|
|
138
|
-
lines.push(
|
|
139
|
+
lines.push(formatBlockingError('Network Error\n'));
|
|
139
140
|
|
|
140
141
|
addControllerUrlHeader(lines, errorData);
|
|
141
142
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { formatBlockingError } = require('../cli-test-layout-chalk');
|
|
1
2
|
/**
|
|
2
3
|
* Permission Error Formatters
|
|
3
4
|
*
|
|
@@ -103,7 +104,7 @@ function getPermissionDetailLines(errorData) {
|
|
|
103
104
|
*/
|
|
104
105
|
function formatPermissionError(errorData) {
|
|
105
106
|
const lines = [];
|
|
106
|
-
lines.push(
|
|
107
|
+
lines.push(formatBlockingError('Permission Denied\n'));
|
|
107
108
|
|
|
108
109
|
if (errorData.detail) {
|
|
109
110
|
lines.push(chalk.yellow(errorData.detail));
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { formatBlockingError } = require('../cli-test-layout-chalk');
|
|
1
2
|
/**
|
|
2
3
|
* Validation Error Formatters
|
|
3
4
|
*
|
|
@@ -111,7 +112,7 @@ function addValidationGuidance(lines, hasErrors) {
|
|
|
111
112
|
*/
|
|
112
113
|
function formatValidationError(errorData) {
|
|
113
114
|
const lines = [];
|
|
114
|
-
lines.push(
|
|
115
|
+
lines.push(formatBlockingError('Validation Error\n'));
|
|
115
116
|
|
|
116
117
|
addValidationErrorMessage(lines, errorData);
|
|
117
118
|
addValidationErrorsList(lines, errorData.errors);
|
|
@@ -133,6 +133,10 @@ function buildSecretPaths(systemKey, authType) {
|
|
|
133
133
|
* @param {Object} [params.authentication] - Full authentication object (authType used if authType not set)
|
|
134
134
|
* @returns {Object} Template context
|
|
135
135
|
*/
|
|
136
|
+
function rbacOptionalFilename(normalizedExt) {
|
|
137
|
+
return normalizedExt === '.yaml' || normalizedExt === '.yml' ? 'rbac.yaml' : 'rbac.json';
|
|
138
|
+
}
|
|
139
|
+
|
|
136
140
|
function buildExternalReadmeContext(params = {}) {
|
|
137
141
|
const appName = params.appName || params.systemKey || 'external-system';
|
|
138
142
|
const systemKey = params.systemKey || appName;
|
|
@@ -140,9 +144,11 @@ function buildExternalReadmeContext(params = {}) {
|
|
|
140
144
|
const description = params.description || `External system integration for ${systemKey}`;
|
|
141
145
|
const systemType = params.systemType || 'openapi';
|
|
142
146
|
const fileExt = params.fileExt !== undefined ? params.fileExt : '.json';
|
|
147
|
+
const normalizedExt = fileExt && fileExt.startsWith('.') ? fileExt : `.${fileExt || 'json'}`;
|
|
143
148
|
const datasources = normalizeDatasources(params.datasources, systemKey, fileExt);
|
|
144
149
|
const authType = params.authType || params.authentication?.type || params.authentication?.method || params.authentication?.authType;
|
|
145
150
|
const secretPaths = buildSecretPaths(systemKey, authType);
|
|
151
|
+
const rbacOptionalFile = rbacOptionalFilename(normalizedExt);
|
|
146
152
|
|
|
147
153
|
return {
|
|
148
154
|
appName,
|
|
@@ -150,7 +156,8 @@ function buildExternalReadmeContext(params = {}) {
|
|
|
150
156
|
displayName,
|
|
151
157
|
description,
|
|
152
158
|
systemType,
|
|
153
|
-
fileExt:
|
|
159
|
+
fileExt: normalizedExt,
|
|
160
|
+
rbacOptionalFile,
|
|
154
161
|
datasourceCount: datasources.length,
|
|
155
162
|
hasDatasources: datasources.length > 0,
|
|
156
163
|
datasources,
|