@aifabrix/builder 2.49.2 → 2.51.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/plans/157.1-security-quality-violations-by-type.csv +374 -0
- package/.cursor/rules/assistant-driven-integration-build.mdc +40 -0
- package/.cursor/rules/deploy-rules/docker-image-ip-policy.mdc +49 -0
- package/.cursor/rules/plan-rules/application-lifecycle.mdc +30 -0
- package/.cursor/rules/plan-rules/plan-frontmatter.mdc +35 -0
- package/.cursor/rules/plan-rules/plan-lifecycle.mdc +31 -0
- package/.cursor/rules/plan-rules/plan-validation-gate.mdc +34 -0
- package/.cursor/skills/README.md +1 -0
- package/.dockerignore +52 -0
- package/.eslintignore +22 -0
- package/README.md +2 -0
- package/bin/builder-api-cleanup.js +26 -0
- package/bin/builder-api-nest.js +10 -0
- package/bin/builder-api-spike.js +19 -0
- package/enterprise-knowledge/README.md +50 -0
- package/enterprise-knowledge/enterprise-integration-lifecycle/README.md +22 -0
- package/enterprise-knowledge/enterprise-integration-lifecycle/application.json +15 -0
- package/enterprise-knowledge/enterprise-integration-lifecycle/deploy.js +69 -0
- package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-deploy.json +52 -0
- package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-system.json +29 -0
- package/enterprise-knowledge/enterprise-integration-lifecycle/env.template +2 -0
- package/integration/README.md +81 -0
- package/integration/github/README.md +53 -0
- package/integration/github/application.json +21 -0
- package/integration/github/deploy.js +72 -0
- package/integration/github/env.template +11 -0
- package/integration/github/github-datasource-issue-comments.json +239 -0
- package/integration/github/github-datasource-issues.json +399 -0
- package/integration/github/github-datasource-repository.json +354 -0
- package/integration/github/github-deploy.json +1202 -0
- package/integration/github/github-system.json +82 -0
- package/integration/hubspot-test/README.md +1 -1
- package/integration/hubspot-test/create-hubspot.js +1 -16
- package/jest.isolated-projects.js +31 -1
- package/jest.projects.js +87 -1
- package/lib/api/dev-server-https.js +1 -1
- package/lib/api/enterprise-knowledge.api.js +63 -0
- package/lib/api/evidence-kinds.api.js +128 -0
- package/lib/api/evidence.api.js +172 -0
- package/lib/api/external-systems.api.js +8 -2
- package/lib/api/pipeline.api.js +5 -1
- package/lib/api/resource-types.api.js +5 -4
- package/lib/api/roles.api.js +121 -0
- package/lib/api/types/enterprise-knowledge.types.js +46 -0
- package/lib/api/types/evidence-kinds.types.js +42 -0
- package/lib/api/types/evidence.types.js +67 -0
- package/lib/api/types/resource-types.types.js +2 -0
- package/lib/api/types/roles.types.js +36 -0
- package/lib/app/certification-verify-rows.js +1 -1
- package/lib/app/controller-application-filter.js +36 -0
- package/lib/app/deploy.js +1 -1
- package/lib/app/list-external-systems.js +130 -0
- package/lib/app/list.js +20 -8
- package/lib/app/run.js +3 -1
- package/lib/app/show-display.js +8 -3
- package/lib/app/show-online.js +178 -0
- package/lib/app/show.js +39 -90
- package/lib/build/builder-api-docker-staging.js +47 -0
- package/lib/build/miso-controller-npm-sdk-guard.js +2 -2
- package/lib/build/standard-docker-build.js +2 -0
- package/lib/certification/merge-certification-from-artifact.js +1 -1
- package/lib/certification/post-unified-cert-sync.js +4 -31
- package/lib/certification/sync-after-external-command.js +0 -1
- package/lib/certification/sync-system-certification.js +0 -3
- package/lib/channels/add-channel.js +40 -34
- package/lib/channels/approval-guides/chatgpt.js +33 -0
- package/lib/channels/approval-guides/credential-portal.js +38 -0
- package/lib/channels/approval-guides/index.js +110 -0
- package/lib/channels/approval-guides/microsoft-copilot.js +34 -0
- package/lib/channels/approval-guides/slack.js +34 -0
- package/lib/channels/approval-guides/teams-bot.js +35 -0
- package/lib/channels/approval-guides/web-embed.js +32 -0
- package/lib/channels/channel-approval-guide.js +11 -0
- package/lib/channels/channel-artifact-generator.js +18 -5
- package/lib/channels/channel-audit.js +3 -0
- package/lib/channels/channel-auth-context.js +1 -1
- package/lib/channels/channel-description.js +59 -0
- package/lib/channels/channel-integration-generator.js +13 -230
- package/lib/channels/channel-integration-template.js +94 -0
- package/lib/channels/channel-runtime-resolver.js +43 -3
- package/lib/channels/channel-status-display.js +66 -26
- package/lib/channels/channel-targets.js +3 -3
- package/lib/cli/index.js +31 -3
- package/lib/cli/infra-guided.js +5 -1
- package/lib/cli/setup-app-external-create.js +111 -0
- package/lib/cli/setup-app.help.js +1 -1
- package/lib/cli/setup-app.js +60 -130
- package/lib/cli/setup-app.test-commands.js +26 -52
- package/lib/cli/setup-certification-commands.js +4 -4
- package/lib/cli/setup-certification.help.js +9 -9
- package/lib/cli/setup-dev.js +30 -9
- package/lib/cli/setup-external-system-help.js +4 -6
- package/lib/cli/setup-external-system.js +58 -52
- package/lib/cli/setup-infra-up-builder-api-action.js +64 -0
- package/lib/cli/setup-infra-up-platform-action.js +3 -1
- package/lib/cli/setup-infra.js +15 -0
- package/lib/cli/setup-list.js +43 -0
- package/lib/cli/setup-utility-help-after.js +12 -0
- package/lib/cli/setup-utility-repair.js +26 -7
- package/lib/cli/setup-utility-validate.js +41 -2
- package/lib/cli/setup-utility.js +5 -3
- package/lib/commands/app.js +15 -43
- package/lib/commands/channel-add-setup.js +110 -0
- package/lib/commands/channel.js +42 -8
- package/lib/commands/datasource-sync-display.js +96 -0
- package/lib/commands/datasource-sync-policy.js +210 -0
- package/lib/commands/datasource-test-trust-cli.js +6 -6
- package/lib/commands/datasource-unified-test-cli.js +2 -1
- package/lib/commands/datasource-unified-test-cli.options.js +33 -23
- package/lib/commands/deploy-gate-failure-details.js +184 -0
- package/lib/commands/deploy-gate-orchestrator.js +368 -0
- package/lib/commands/dev-cli-handlers.js +7 -62
- package/lib/commands/dev-host-ops-params.js +91 -0
- package/lib/commands/dev-host-ops-poll.js +111 -0
- package/lib/commands/dev-host-ops.js +107 -94
- package/lib/commands/dev-init.js +6 -106
- package/lib/commands/dev-refresh.js +197 -0
- package/lib/commands/enterprise-knowledge.js +284 -0
- package/lib/commands/evidence-cli-leaves.js +250 -0
- package/lib/commands/evidence-kind.js +428 -0
- package/lib/commands/evidence.js +51 -0
- package/lib/commands/governance-cli-shared.js +2 -2
- package/lib/commands/governance-command-action.js +5 -3
- package/lib/commands/governance-fixture-subjects.js +85 -0
- package/lib/commands/governance.js +1 -1
- package/lib/commands/lifecycle-command-action.js +2 -2
- package/lib/commands/lifecycle-external.js +3 -3
- package/lib/commands/manifest-cli-auth.js +29 -0
- package/lib/commands/manifest-cli-commands.js +170 -0
- package/lib/commands/manifest-cli-integration-path.js +63 -0
- package/lib/commands/manifest.js +21 -0
- package/lib/commands/protection-cli-leaves.js +3 -3
- package/lib/commands/repair-auth-apply.js +15 -1
- package/lib/commands/repair-authentications-454.js +169 -0
- package/lib/commands/repair-capability-openapi-warnings.js +126 -0
- package/lib/commands/repair-datasource-apply.js +135 -0
- package/lib/commands/repair-datasource-auto-rbac.js +62 -1
- package/lib/commands/repair-datasource-http-service-contract.js +239 -0
- package/lib/commands/repair-datasource-operation-security.js +180 -0
- package/lib/commands/repair-datasource-run.js +7 -2
- package/lib/commands/repair-datasource-sync-operations.js +177 -0
- package/lib/commands/repair-datasource-webhooks-sync-bridge.js +133 -0
- package/lib/commands/repair-datasource.js +12 -68
- package/lib/commands/repair-env-template.js +11 -1
- package/lib/commands/repair-external-run.js +121 -31
- package/lib/commands/repair-internal.js +1 -1
- package/lib/commands/repair-openapi-export.js +156 -0
- package/lib/commands/repair-openapi-sync.js +33 -8
- package/lib/commands/repair-orchestration-datasource-split.js +259 -0
- package/lib/commands/repair-persist.js +22 -1
- package/lib/commands/repair-rbac-platform-preset.js +204 -0
- package/lib/commands/repair-rbac-reader-roles.js +191 -0
- package/lib/commands/repair-rbac.js +163 -86
- package/lib/commands/repair-steps.js +83 -18
- package/lib/commands/repair-system-permissions.js +1 -0
- package/lib/commands/repair.js +1 -1
- package/lib/commands/resource-type.js +166 -44
- package/lib/commands/role.js +452 -0
- package/lib/commands/run-post-publish-data-sync.js +68 -0
- package/lib/commands/setup-modes.js +1 -1
- package/lib/commands/setup.js +1 -1
- package/lib/commands/test-e2e-external.js +21 -8
- package/lib/commands/test-governance-cli-options.js +2 -2
- package/lib/commands/test-trust-cli-options.js +2 -2
- package/lib/commands/up-builder-api-bootstrap.js +71 -0
- package/lib/commands/up-builder-api-provision.js +241 -0
- package/lib/commands/up-builder-api.js +88 -0
- package/lib/commands/up-common.js +25 -1
- package/lib/commands/upload-credential-push-log.js +117 -0
- package/lib/commands/upload-data-sync-finalize.js +60 -0
- package/lib/commands/upload-probe.js +66 -0
- package/lib/commands/upload-publish-context.js +4 -1
- package/lib/commands/upload-sidecar-followups.js +55 -27
- package/lib/commands/upload.js +116 -157
- package/lib/commands/validate-json.js +230 -0
- package/lib/commands/verify-governance-combined-external.js +1 -1
- package/lib/commands/verify-governance-db.js +2 -2
- package/lib/commands/verify-operations-command-action.js +2 -2
- package/lib/commands/verify-operations-step-plan.js +79 -41
- package/lib/commands/verify-operations-steps.js +2 -2
- package/lib/commands/verify-trust-command-action.js +1 -1
- package/lib/commands/wizard-core.js +1 -1
- package/lib/commands/wizard-headless.js +2 -1
- package/lib/core/admin-secrets.js +2 -6
- package/lib/core/audit-logger.js +1 -1
- package/lib/core/secrets-env-content.js +10 -4
- package/lib/core/secrets-env-write.js +2 -13
- package/lib/core/secrets-load.js +1 -3
- package/lib/datasource/agent-trust-run.js +3 -3
- package/lib/datasource/capability/relate-operations.js +1 -1
- package/lib/datasource/deploy.js +3 -1
- package/lib/datasource/test-e2e.js +6 -1
- package/lib/datasource/unified-validation-run-body.js +4 -1
- package/lib/datasource/unified-validation-run.js +1 -1
- package/lib/deployment/deploy-poll-ui.js +73 -12
- package/lib/deployment/deployer-poll-run.js +113 -0
- package/lib/deployment/deployer.js +17 -87
- package/lib/evidence/dataplane-context.js +21 -0
- package/lib/evidence/evidence-display.js +78 -0
- package/lib/evidence/evidence-service.js +392 -0
- package/lib/external-system/deploy.js +290 -112
- package/lib/external-system/download.js +7 -3
- package/lib/external-system/test-execution.js +1 -1
- package/lib/external-system/test-system-level.js +8 -10
- package/lib/external-system/test.js +12 -6
- package/lib/generator/deploy-script.js +73 -0
- package/lib/generator/external.js +2 -1
- package/lib/generator/helpers.js +13 -5
- package/lib/generator/index.js +17 -2
- package/lib/generator/split-variables.js +9 -3
- package/lib/generator/wizard.js +3 -36
- package/lib/infrastructure/helpers-docker-check.js +6 -0
- package/lib/infrastructure/helpers.js +1 -1
- package/lib/internal/fs-real-sync.js +22 -1
- package/lib/internal/node-fs.js +2 -0
- package/lib/lifecycle/lifecycle-governance-options.js +1 -1
- package/lib/lifecycle/verify-step-progress.js +1 -1
- package/lib/programmatic/access-log.js +26 -0
- package/lib/programmatic/auth-config.js +45 -0
- package/lib/programmatic/bearer-auth.js +176 -0
- package/lib/programmatic/builder-api-request.js +175 -0
- package/lib/programmatic/builder-api-route-dispatch.js +82 -0
- package/lib/programmatic/builder-api-runtime-config.js +42 -0
- package/lib/programmatic/builder-api-server.js +230 -0
- package/lib/programmatic/builder-help-authentication-catalog.js +282 -0
- package/lib/programmatic/builder-help-connected-system-ui.js +266 -0
- package/lib/programmatic/builder-help-enterprise-sync-fabrix.js +60 -0
- package/lib/programmatic/builder-help-envelope.js +36 -0
- package/lib/programmatic/builder-help-fixtures.js +200 -0
- package/lib/programmatic/builder-help-governance.js +172 -0
- package/lib/programmatic/builder-help-schema-catalog.js +92 -0
- package/lib/programmatic/builder-help.js +361 -0
- package/lib/programmatic/capability-registry.js +77 -0
- package/lib/programmatic/command-options.js +32 -0
- package/lib/programmatic/enterprise-mcp-client.js +114 -0
- package/lib/programmatic/http-problem-details.js +99 -0
- package/lib/programmatic/http-route-match.js +40 -0
- package/lib/programmatic/idempotency-cache.js +69 -0
- package/lib/programmatic/index.js +53 -0
- package/lib/programmatic/integration-path-scope.js +39 -0
- package/lib/programmatic/log-redaction.js +66 -0
- package/lib/programmatic/manifest-get-section.js +146 -0
- package/lib/programmatic/manifest-patch-section.js +252 -0
- package/lib/programmatic/manifest-repair.js +122 -0
- package/lib/programmatic/manifest-section-dependency-graph.js +160 -0
- package/lib/programmatic/manifest-section-io.js +225 -0
- package/lib/programmatic/manifest-section-quality.js +171 -0
- package/lib/programmatic/manifest-section-registry-data.js +269 -0
- package/lib/programmatic/manifest-section-registry.js +222 -0
- package/lib/programmatic/nest-http-bridge.js +34 -0
- package/lib/programmatic/openapi-component-schemas.js +68 -0
- package/lib/programmatic/openapi-description-enricher.js +117 -0
- package/lib/programmatic/openapi-descriptions.js +190 -0
- package/lib/programmatic/openapi-docs-serving.js +123 -0
- package/lib/programmatic/openapi-help-schemas.js +63 -0
- package/lib/programmatic/openapi-manifest-schemas.js +141 -0
- package/lib/programmatic/openapi-operation-bindings.js +274 -0
- package/lib/programmatic/openapi-request-schemas.js +155 -0
- package/lib/programmatic/openapi-result-schemas.js +493 -0
- package/lib/programmatic/openapi-schema-descriptions-certify.js +139 -0
- package/lib/programmatic/openapi-schema-descriptions-core.js +162 -0
- package/lib/programmatic/openapi-schema-descriptions-help.js +40 -0
- package/lib/programmatic/openapi-schema-descriptions-manifest.js +143 -0
- package/lib/programmatic/openapi-schema-descriptions-mcp.js +118 -0
- package/lib/programmatic/openapi-schema-descriptions-operations.js +281 -0
- package/lib/programmatic/openapi-schema-helpers.js +108 -0
- package/lib/programmatic/openapi-spec.js +203 -0
- package/lib/programmatic/orchestration-openapi-meta.js +159 -0
- package/lib/programmatic/platform-rbac-catalog.js +90 -0
- package/lib/programmatic/request-timeout.js +53 -0
- package/lib/programmatic/route-handler-map.js +143 -0
- package/lib/programmatic/route-handlers-context.js +29 -0
- package/lib/programmatic/route-handlers.js +33 -0
- package/lib/programmatic/run-certify.js +57 -0
- package/lib/programmatic/run-enterprise-mcp.js +32 -0
- package/lib/programmatic/run-lifecycle.js +29 -0
- package/lib/programmatic/run-repair.js +41 -0
- package/lib/programmatic/run-repository-emcp.js +62 -0
- package/lib/programmatic/run-template-workspace.js +74 -0
- package/lib/programmatic/run-test.js +49 -0
- package/lib/programmatic/run-upload.js +63 -0
- package/lib/programmatic/run-validate.js +53 -0
- package/lib/programmatic/run-wizard.js +40 -0
- package/lib/programmatic/system-key.js +48 -0
- package/lib/programmatic/wizard-config-normalize.js +118 -0
- package/lib/programmatic/workspace-cleanup.js +128 -0
- package/lib/programmatic/workspace-context.js +145 -0
- package/lib/programmatic/workspace-lock.js +75 -0
- package/lib/programmatic/workspace-meta.js +64 -0
- package/lib/programmatic/workspace-ops.js +149 -0
- package/lib/protection/run-commands-upload-sync.js +35 -0
- package/lib/protection/run-commands.js +2 -20
- package/lib/protection/upload-batch.js +11 -7
- package/lib/resolvers/evidence-kind-file.js +230 -0
- package/lib/resolvers/resource-type-file.js +58 -1
- package/lib/resolvers/role-file.js +227 -0
- package/lib/schema/application-schema.json +22 -2
- package/lib/schema/external-datasource.schema.json +245 -2
- package/lib/schema/external-system.schema.json +259 -119
- package/lib/schema/flag-map-validation-run.json +3 -0
- package/lib/schema/infra.parameter.yaml +25 -1
- package/lib/schema/type/credential-field-registry.json +21 -5
- package/lib/schema/type/document-storage.json +9 -0
- package/lib/utils/agent-trust-run-display.js +1 -1
- package/lib/utils/api.js +8 -2
- package/lib/utils/app-path-resolve.js +168 -0
- package/lib/utils/app-register-config.js +4 -3
- package/lib/utils/authentication-env-template.js +222 -0
- package/lib/utils/cli-sync-options.js +62 -10
- package/lib/utils/cli-utils.js +15 -3
- package/lib/utils/cli-workspace-options.js +29 -0
- package/lib/utils/compose-generate-docker-compose.js +102 -0
- package/lib/utils/configuration-env-resolver.js +203 -27
- package/lib/utils/datasource-test-run-certificate-tty.js +28 -2
- package/lib/utils/datasource-test-run-certification-debug.js +130 -0
- package/lib/utils/datasource-test-run-debug-display.js +2 -0
- package/lib/utils/datasource-test-run-debug-slice.js +7 -0
- package/lib/utils/datasource-test-run-display.js +2 -1
- package/lib/utils/dev-ca-install.js +5 -6
- package/lib/utils/dev-config.js +2 -2
- package/lib/utils/dev-init-ssh-merge.js +165 -23
- package/lib/utils/dev-list-sort.js +145 -0
- package/lib/utils/dev-pin-share-instructions.js +110 -0
- package/lib/utils/dev-platform-tls.js +0 -63
- package/lib/utils/dev-ssh-config-helper.js +177 -33
- package/lib/utils/docker-build.js +46 -27
- package/lib/utils/docker-daemon-tls-ca.js +1 -1
- package/lib/utils/docker-exec.js +91 -6
- package/lib/utils/enterprise-knowledge-paths.js +142 -0
- package/lib/utils/env-copy.js +3 -4
- package/lib/utils/env-dotenv-format.js +103 -0
- package/lib/utils/error-formatters/error-parser.js +0 -3
- package/lib/utils/external-env-template.js +5 -2
- package/lib/utils/external-system-display.js +5 -1
- package/lib/utils/external-system-readiness-compact-blocks.js +248 -0
- package/lib/utils/external-system-readiness-compact-display.js +324 -0
- package/lib/utils/external-system-readiness-core.js +16 -0
- package/lib/utils/external-system-readiness-deploy-display.js +29 -11
- package/lib/utils/external-system-readiness-display-internals.js +3 -1
- package/lib/utils/external-system-readiness-display.js +20 -30
- package/lib/utils/external-system-system-test-tty-certification.js +135 -0
- package/lib/utils/external-system-system-test-tty.js +5 -41
- package/lib/utils/health-check-request.js +2 -3
- package/lib/utils/help-builder.js +9 -1
- package/lib/utils/host-ops-job-labels.js +236 -0
- package/lib/utils/host-ops-job-result.js +61 -0
- package/lib/utils/host-ops-poll-ui.js +163 -0
- package/lib/utils/image-name.js +22 -4
- package/lib/utils/integration-path-resolve.js +112 -0
- package/lib/utils/logger.js +37 -4
- package/lib/utils/manifest-source-emit.js +1 -1
- package/lib/utils/paths-reload-source.js +148 -0
- package/lib/utils/paths-system-builder-keys.js +25 -0
- package/lib/utils/paths.js +183 -30
- package/lib/utils/pipeline-upload-auth-retry.js +4 -0
- package/lib/utils/postgres-platform-bootstrap.js +24 -17
- package/lib/utils/postgres-wipe.js +5 -2
- package/lib/utils/remote-dev-auth.js +39 -4
- package/lib/utils/resolve-docker-image-ref.js +36 -6
- package/lib/utils/runtime-configuration-values.js +64 -2
- package/lib/utils/secrets-helpers.js +5 -1
- package/lib/utils/ssh-known-hosts.js +130 -0
- package/lib/utils/test-target-cli-options.js +75 -0
- package/lib/utils/token-manager.js +16 -0
- package/lib/utils/upload-sync-options.js +20 -2
- package/lib/utils/validation-run-request.js +11 -2
- package/lib/validation/external-manifest-validator.js +11 -1
- package/lib/validation/openapi-contract-surface-validator.js +430 -0
- package/lib/validation/openapi-contract-vendor-validation.js +238 -0
- package/lib/validation/validate-external-file.js +160 -0
- package/lib/validation/validate.js +6 -117
- package/lib/validation/validator.js +6 -5
- package/package.json +76 -37
- package/packages/builder-api/README.md +120 -0
- package/packages/builder-api/package.json +30 -0
- package/packages/builder-api/src/app.module.ts +7 -0
- package/packages/builder-api/src/auth/auth.module.ts +5 -0
- package/packages/builder-api/src/external-system/external-system.module.ts +5 -0
- package/packages/builder-api/src/main.ts +16 -0
- package/packages/builder-api/tsconfig.json +15 -0
- package/scripts/check-builder-api-architecture-grep.js +79 -0
- package/scripts/docker_image_content_gate.js +47 -0
- package/scripts/docker_image_content_gate.sh +5 -0
- package/scripts/export-builder-api-evidence.js +262 -0
- package/scripts/lib/builder-api-docker-staging-copy.js +60 -0
- package/scripts/lib/builder-api-docker-staging-core.js +183 -0
- package/scripts/lib/docker-image-content-gate-core.js +166 -0
- package/scripts/lib/plan-actor.js +109 -0
- package/scripts/lib/plan-config.js +20 -0
- package/scripts/lib/plan-gates.js +154 -0
- package/scripts/lib/plan-meta.js +104 -0
- package/scripts/lib/plan-parse.js +162 -0
- package/scripts/lib/plan-prevalidate-gates.js +337 -0
- package/scripts/lib/plan-run-core.js +125 -0
- package/scripts/lib/plan-run-report.js +119 -0
- package/scripts/plan-approve.js +24 -0
- package/scripts/plan-archive.js +49 -0
- package/scripts/plan-run.js +13 -0
- package/scripts/plan-set-actor.js +21 -0
- package/scripts/plan-validate.js +80 -0
- package/scripts/pnpm/af.mjs +110 -0
- package/scripts/pnpm/check-quiet.mjs +32 -0
- package/scripts/pnpm/dev-install.mjs +29 -0
- package/scripts/pnpm/dev-reload.mjs +18 -0
- package/scripts/pnpm/help.mjs +55 -0
- package/scripts/pnpm/lib/dev-reload-core.mjs +189 -0
- package/scripts/pnpm/lib/dev-reload-log-capture.mjs +67 -0
- package/scripts/pnpm/lib/dev-reload-log-utils.mjs +32 -0
- package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +124 -0
- package/scripts/pnpm/lib/resolve-app-url.mjs +183 -0
- package/scripts/pnpm/lib/spinner.mjs +42 -0
- package/scripts/stage_builder_api_for_docker.js +65 -0
- package/scripts/sync-builder-api-template.js +44 -0
- package/templates/README.md +3 -0
- package/templates/applications/builder-api/Dockerfile +38 -0
- package/templates/applications/builder-api/application.yaml +75 -0
- package/templates/applications/builder-api/env.template +48 -0
- package/templates/applications/dataplane/application.yaml +27 -5
- package/templates/applications/dataplane/env.template +38 -15
- package/templates/applications/dataplane/rbac.yaml +85 -3
- package/templates/applications/miso-controller/application.yaml +10 -1
- package/templates/applications/miso-controller/env.template +11 -10
- package/templates/applications/miso-controller/rbac.yaml +72 -0
- package/templates/channels/README.md +18 -0
- package/templates/channels/ai-fabrix-icon.jpg +0 -0
- package/templates/channels/chatgpt/install.template.md.hbs +21 -24
- package/templates/channels/chatgpt/integration/README.md +11 -0
- package/templates/channels/chatgpt/integration/application.json +15 -0
- package/templates/channels/chatgpt/integration/chatgpt-system.json +29 -0
- package/templates/channels/chatgpt/integration/env.template +4 -0
- package/templates/channels/microsoft-copilot/install.template.md.hbs +20 -25
- package/templates/channels/microsoft-copilot/integration/README.md +11 -0
- package/templates/channels/microsoft-copilot/integration/application.json +15 -0
- package/templates/channels/microsoft-copilot/integration/env.template +6 -0
- package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +34 -0
- package/templates/channels/slack/install.template.md.hbs +48 -18
- package/templates/channels/slack/integration/README.md +38 -0
- package/templates/channels/slack/integration/application.json +18 -0
- package/templates/channels/slack/integration/env.template +29 -0
- package/templates/channels/slack/integration/slack-datasource-conversations.json +226 -0
- package/templates/channels/slack/integration/slack-datasource-messages.json +269 -0
- package/templates/channels/slack/integration/slack-system.json +144 -0
- package/templates/channels/slack/manifest.template.json.hbs +20 -10
- package/templates/channels/teams-bot/install.template.md.hbs +31 -17
- package/templates/channels/teams-bot/integration/README.md +18 -0
- package/templates/channels/teams-bot/integration/application.json +17 -0
- package/templates/channels/teams-bot/integration/env.template +5 -0
- package/templates/channels/teams-bot/integration/teams-bot-system.json +55 -0
- package/templates/channels/teams-bot/manifest.template.json.hbs +27 -0
- package/templates/channels/web-embed/install.template.md.hbs +16 -26
- package/templates/channels/web-embed/integration/README.md +11 -0
- package/templates/channels/web-embed/integration/application.json +15 -0
- package/templates/channels/web-embed/integration/env.template +4 -0
- package/templates/channels/web-embed/integration/web-embed-system.json +29 -0
- package/templates/openapi/redoc_page.html +86 -0
- package/templates/python/docker-compose.hbs +11 -0
- package/templates/python/requirements.txt +2 -2
- package/templates/typescript/docker-compose.hbs +11 -0
- package/lib/certification/cli-cert-sync-skip.js +0 -21
|
@@ -68,29 +68,37 @@ function extractPasswordFromUrlOrValue(urlOrPassword) {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
71
|
+
* Run psql -c inside the Postgres container without a shell.
|
|
72
|
+
* Passes SQL as an argv element so dollar-quoting (DO $$ … $$) is not mangled.
|
|
73
73
|
*
|
|
74
|
-
* @param {string} s
|
|
75
|
-
* @returns {string}
|
|
76
|
-
*/
|
|
77
|
-
function escapeShellDoubleQuoted(s) {
|
|
78
|
-
return s.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\$/g, '\\$');
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
74
|
* @async
|
|
83
75
|
* @param {string} container
|
|
84
76
|
* @param {string} sql
|
|
85
77
|
* @param {string} adminPassword
|
|
78
|
+
* @param {string} [database='postgres']
|
|
86
79
|
* @returns {Promise<void>}
|
|
87
80
|
*/
|
|
88
81
|
async function runPsqlCommand(container, sql, adminPassword, database = 'postgres') {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
82
|
+
await dockerExec.execFileWithDockerEnv(
|
|
83
|
+
'docker',
|
|
84
|
+
[
|
|
85
|
+
'exec',
|
|
86
|
+
'-e',
|
|
87
|
+
'PGPASSWORD',
|
|
88
|
+
'-i',
|
|
89
|
+
container,
|
|
90
|
+
'psql',
|
|
91
|
+
'-U',
|
|
92
|
+
SUPERUSER_ROLE,
|
|
93
|
+
'-d',
|
|
94
|
+
database,
|
|
95
|
+
'-v',
|
|
96
|
+
'ON_ERROR_STOP=1',
|
|
97
|
+
'-c',
|
|
98
|
+
sql
|
|
99
|
+
],
|
|
100
|
+
{ env: { PGPASSWORD: adminPassword } }
|
|
101
|
+
);
|
|
94
102
|
}
|
|
95
103
|
|
|
96
104
|
/**
|
|
@@ -194,6 +202,5 @@ module.exports = {
|
|
|
194
202
|
PLATFORM_DATABASE_SLOTS,
|
|
195
203
|
bootstrapPlatformPostgresDatabases,
|
|
196
204
|
pgRoleName,
|
|
197
|
-
extractPasswordFromUrlOrValue
|
|
198
|
-
escapeShellDoubleQuoted
|
|
205
|
+
extractPasswordFromUrlOrValue
|
|
199
206
|
};
|
|
@@ -86,9 +86,12 @@ async function runPsql(container, sql, adminPassword) {
|
|
|
86
86
|
if (!adminPassword || typeof adminPassword !== 'string') {
|
|
87
87
|
throw new Error('Admin password is required');
|
|
88
88
|
}
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
if (!/^[a-z0-9][a-z0-9._-]*$/i.test(container)) {
|
|
90
|
+
throw new Error(`Unsafe Postgres container name: ${container}`);
|
|
91
|
+
}
|
|
91
92
|
const env = { PGPASSWORD: adminPassword };
|
|
93
|
+
const safeSqlToken = JSON.stringify(String(sql));
|
|
94
|
+
const cmd = `docker exec -e PGPASSWORD -i ${container} psql -U ${SUPERUSER_ROLE} -d postgres -tAc ${safeSqlToken}`;
|
|
92
95
|
const result = (await dockerExec.execWithDockerEnv(cmd, { env })) || {};
|
|
93
96
|
return String(result.stdout || '').trim();
|
|
94
97
|
}
|
|
@@ -24,6 +24,17 @@ function expandConfiguredSecretsTilde(filePath) {
|
|
|
24
24
|
return filePath;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
/** One auto-renew attempt per CLI process (shared by concurrent getRemoteDevAuth callers). */
|
|
28
|
+
let autoRenewPromise = null;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Reset process-level auto-renew gate (tests only).
|
|
32
|
+
* @returns {void}
|
|
33
|
+
*/
|
|
34
|
+
function resetDevCertAutoRenewGateForTests() {
|
|
35
|
+
autoRenewPromise = null;
|
|
36
|
+
}
|
|
37
|
+
|
|
27
38
|
/**
|
|
28
39
|
* Single API object so resolveSharedSecretsEndpoint and callers share one getRemoteDevAuth
|
|
29
40
|
* (Jest spies and partial mocks work reliably).
|
|
@@ -39,12 +50,11 @@ const remoteDevAuth = {
|
|
|
39
50
|
},
|
|
40
51
|
|
|
41
52
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* Use for cert-authenticated dev API calls (settings, users, ssh-keys, secrets).
|
|
53
|
+
* Read remote server URL + client cert from disk without auto-renew.
|
|
54
|
+
* Use when renewing (avoids recursion) or when only a local presence check is needed.
|
|
45
55
|
* @returns {Promise<{ serverUrl: string, clientCertPem: string, serverCaPem: string|null }|null>}
|
|
46
56
|
*/
|
|
47
|
-
async
|
|
57
|
+
async readRemoteDevAuth() {
|
|
48
58
|
const serverUrl = await config.getRemoteServer();
|
|
49
59
|
if (!serverUrl) return null;
|
|
50
60
|
const devId = await config.getDeveloperId();
|
|
@@ -55,6 +65,30 @@ const remoteDevAuth = {
|
|
|
55
65
|
return { serverUrl, clientCertPem, serverCaPem };
|
|
56
66
|
},
|
|
57
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Get Builder Server URL, client cert PEM, and optional dev root CA when remote is configured; otherwise null.
|
|
70
|
+
* When the client cert is still valid but expires within 14 days, renews it once per process before returning.
|
|
71
|
+
* serverCaPem comes from ca.pem (saved at dev init); required for Node TLS to private-CA servers.
|
|
72
|
+
* Use for cert-authenticated dev API calls (settings, users, ssh-keys, secrets).
|
|
73
|
+
* @returns {Promise<{ serverUrl: string, clientCertPem: string, serverCaPem: string|null }|null>}
|
|
74
|
+
*/
|
|
75
|
+
async getRemoteDevAuth() {
|
|
76
|
+
const existing = await remoteDevAuth.readRemoteDevAuth();
|
|
77
|
+
if (!existing) return null;
|
|
78
|
+
if (!autoRenewPromise) {
|
|
79
|
+
autoRenewPromise = (async() => {
|
|
80
|
+
const { ensureDevCertFreshIfDue } = require('../commands/dev-refresh');
|
|
81
|
+
return ensureDevCertFreshIfDue({ quiet: false });
|
|
82
|
+
})();
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
await autoRenewPromise;
|
|
86
|
+
} catch {
|
|
87
|
+
// ensureDevCertFreshIfDue already handles failures; keep using current cert
|
|
88
|
+
}
|
|
89
|
+
return remoteDevAuth.readRemoteDevAuth();
|
|
90
|
+
},
|
|
91
|
+
|
|
58
92
|
/**
|
|
59
93
|
* Resolve where shared secrets read/write should go. After dev init, config may still hold a
|
|
60
94
|
* server-side filesystem path from GET /api/dev/settings (not an http URL) if merge did not rewrite it.
|
|
@@ -148,3 +182,4 @@ function normalizeSharedSecretsFilePath(configured) {
|
|
|
148
182
|
}
|
|
149
183
|
|
|
150
184
|
module.exports = remoteDevAuth;
|
|
185
|
+
module.exports.resetDevCertAutoRenewGateForTests = resetDevCertAutoRenewGateForTests;
|
|
@@ -12,6 +12,32 @@
|
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
14
|
const { parseImageOverride } = require('./parse-image-ref');
|
|
15
|
+
const DOCKER_REPOSITORY_RE = /^[a-z0-9][a-z0-9._/-]*$/i;
|
|
16
|
+
const DOCKER_TAG_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param {string} repository
|
|
20
|
+
* @returns {string}
|
|
21
|
+
*/
|
|
22
|
+
function assertSafeRepository(repository) {
|
|
23
|
+
const trimmed = String(repository || '').trim();
|
|
24
|
+
if (!trimmed || !DOCKER_REPOSITORY_RE.test(trimmed)) {
|
|
25
|
+
throw new Error(`Invalid Docker repository path: ${repository}`);
|
|
26
|
+
}
|
|
27
|
+
return trimmed;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @param {string} tag
|
|
32
|
+
* @returns {string}
|
|
33
|
+
*/
|
|
34
|
+
function assertSafeTag(tag) {
|
|
35
|
+
const trimmed = String(tag || '').trim();
|
|
36
|
+
if (!trimmed || !DOCKER_TAG_RE.test(trimmed)) {
|
|
37
|
+
throw new Error(`Invalid Docker image tag: ${tag}`);
|
|
38
|
+
}
|
|
39
|
+
return trimmed;
|
|
40
|
+
}
|
|
15
41
|
|
|
16
42
|
/**
|
|
17
43
|
* Repository path without host (same rules as compose-generator getImageName).
|
|
@@ -59,7 +85,11 @@ function normalizeDockerRegistryPrefix(registry) {
|
|
|
59
85
|
if (!t) {
|
|
60
86
|
return '';
|
|
61
87
|
}
|
|
62
|
-
|
|
88
|
+
let end = t.length;
|
|
89
|
+
while (end > 0 && t[end - 1] === '/') {
|
|
90
|
+
end -= 1;
|
|
91
|
+
}
|
|
92
|
+
return t.slice(0, end);
|
|
63
93
|
}
|
|
64
94
|
|
|
65
95
|
/**
|
|
@@ -81,18 +111,18 @@ function resolveDockerImageRef(appName, appConfig, runOptions = {}) {
|
|
|
81
111
|
if (opts.image) {
|
|
82
112
|
const parsed = parseImageOverride(opts.image);
|
|
83
113
|
return {
|
|
84
|
-
imageName: parsed ? parsed.name : getRepositoryPathFromConfig(appConfig, appName),
|
|
85
|
-
imageTag: parsed ? parsed.tag : tagFromOpts || imageTagFromConfig(appConfig)
|
|
114
|
+
imageName: assertSafeRepository(parsed ? parsed.name : getRepositoryPathFromConfig(appConfig, appName)),
|
|
115
|
+
imageTag: assertSafeTag(parsed ? parsed.tag : tagFromOpts || imageTagFromConfig(appConfig))
|
|
86
116
|
};
|
|
87
117
|
}
|
|
88
118
|
|
|
89
|
-
const baseRepo = getRepositoryPathFromConfig(appConfig, appName);
|
|
90
|
-
const imageTag = tagFromOpts || imageTagFromConfig(appConfig);
|
|
119
|
+
const baseRepo = assertSafeRepository(getRepositoryPathFromConfig(appConfig, appName));
|
|
120
|
+
const imageTag = assertSafeTag(tagFromOpts || imageTagFromConfig(appConfig));
|
|
91
121
|
const prefix =
|
|
92
122
|
normalizeDockerRegistryPrefix(opts.registry) ||
|
|
93
123
|
normalizeDockerRegistryPrefix(appConfig?.image?.registry ?? '');
|
|
94
124
|
if (prefix) {
|
|
95
|
-
return { imageName: `${prefix}/${baseRepo}
|
|
125
|
+
return { imageName: assertSafeRepository(`${prefix}/${baseRepo}`), imageTag };
|
|
96
126
|
}
|
|
97
127
|
return { imageName: baseRepo, imageTag };
|
|
98
128
|
}
|
|
@@ -44,6 +44,65 @@ function collectSystemVariablePutRequests(systemConfiguration, envMap) {
|
|
|
44
44
|
return requests;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
/** OpenAPI path param names resolved from env.template (not valid configuration[] names). */
|
|
48
|
+
const OPENAPI_PATH_PARAM_ENV_KEYS = ['systemKey', 'pillar'];
|
|
49
|
+
|
|
50
|
+
const PATH_PARAM_FALLBACK_ENV_KEYS = {
|
|
51
|
+
systemKey: 'E2E_SYSTEM_KEY',
|
|
52
|
+
pillar: 'E2E_CERTIFY_PILLAR'
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @param {unknown} raw
|
|
57
|
+
* @param {{ allowKv?: boolean }} [options]
|
|
58
|
+
* @returns {string|null}
|
|
59
|
+
*/
|
|
60
|
+
function resolvedEnvLiteral(raw, options = {}) {
|
|
61
|
+
if (raw === undefined || raw === null) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
const value = String(raw).trim();
|
|
65
|
+
if (!value || value.includes('{{')) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
if (!options.allowKv && value.startsWith('kv://')) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
return value;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function resolvePathParamValue(envMap, name) {
|
|
75
|
+
const direct = resolvedEnvLiteral(envMap[name]);
|
|
76
|
+
if (direct) {
|
|
77
|
+
return direct;
|
|
78
|
+
}
|
|
79
|
+
const fallbackKey = PATH_PARAM_FALLBACK_ENV_KEYS[name];
|
|
80
|
+
if (!fallbackKey) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
return resolvedEnvLiteral(envMap[fallbackKey], { allowKv: true });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @param {Object.<string, string>} envMap
|
|
88
|
+
* @param {Set<string>} [alreadyPushed]
|
|
89
|
+
* @returns {Array<{ name: string, value: string }>}
|
|
90
|
+
*/
|
|
91
|
+
function collectOpenApiPathParamAliasPutRequests(envMap, alreadyPushed = new Set()) {
|
|
92
|
+
const requests = [];
|
|
93
|
+
for (const name of OPENAPI_PATH_PARAM_ENV_KEYS) {
|
|
94
|
+
if (alreadyPushed.has(name)) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const value = resolvePathParamValue(envMap, name);
|
|
98
|
+
if (!value) {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
requests.push({ name, value });
|
|
102
|
+
}
|
|
103
|
+
return requests;
|
|
104
|
+
}
|
|
105
|
+
|
|
47
106
|
/**
|
|
48
107
|
* Datasource overrides are name+value only; values may already be resolved in upload payload.
|
|
49
108
|
*
|
|
@@ -83,7 +142,7 @@ function collectDatasourceOverridePutRequests(datasourceConfiguration) {
|
|
|
83
142
|
* @returns {Promise<{ pushed: number, names: string[] }>}
|
|
84
143
|
*/
|
|
85
144
|
async function pushRuntimeConfigurationValues(dataplaneUrl, authConfig, systemKey, payload) {
|
|
86
|
-
const { envMap } = await buildResolvedEnvMapForIntegration(systemKey);
|
|
145
|
+
const { envMap } = await buildResolvedEnvMapForIntegration(systemKey, { dataplaneRuntime: true });
|
|
87
146
|
const names = [];
|
|
88
147
|
let pushed = 0;
|
|
89
148
|
|
|
@@ -91,7 +150,9 @@ async function pushRuntimeConfigurationValues(dataplaneUrl, authConfig, systemKe
|
|
|
91
150
|
payload?.application?.configuration,
|
|
92
151
|
envMap
|
|
93
152
|
);
|
|
94
|
-
|
|
153
|
+
const pushedNames = new Set(systemRequests.map((r) => r.name));
|
|
154
|
+
const aliasRequests = collectOpenApiPathParamAliasPutRequests(envMap, pushedNames);
|
|
155
|
+
for (const body of [...systemRequests, ...aliasRequests]) {
|
|
95
156
|
await putExternalSystemConfiguration(dataplaneUrl, systemKey, authConfig, body);
|
|
96
157
|
names.push(body.name);
|
|
97
158
|
pushed += 1;
|
|
@@ -114,6 +175,7 @@ async function pushRuntimeConfigurationValues(dataplaneUrl, authConfig, systemKe
|
|
|
114
175
|
|
|
115
176
|
module.exports = {
|
|
116
177
|
collectSystemVariablePutRequests,
|
|
178
|
+
collectOpenApiPathParamAliasPutRequests,
|
|
117
179
|
collectDatasourceOverridePutRequests,
|
|
118
180
|
pushRuntimeConfigurationValues
|
|
119
181
|
};
|
|
@@ -226,7 +226,11 @@ function replaceKvInContent(content, secrets, envVars, scopedKv = null) {
|
|
|
226
226
|
return envVars[envVar] || m;
|
|
227
227
|
});
|
|
228
228
|
}
|
|
229
|
-
|
|
229
|
+
if (value !== null && value !== undefined) {
|
|
230
|
+
const { formatDotenvSubstitutionValue } = require('./env-dotenv-format');
|
|
231
|
+
return formatDotenvSubstitutionValue(String(value));
|
|
232
|
+
}
|
|
233
|
+
return match;
|
|
230
234
|
});
|
|
231
235
|
return replaced + suffix;
|
|
232
236
|
});
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remove stale OpenSSH known_hosts entries after server reprovision or Host alias rename.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview ssh-keygen -R helpers for dev init / refresh
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const { execFile } = require('child_process');
|
|
12
|
+
const { promisify } = require('util');
|
|
13
|
+
const path = require('path');
|
|
14
|
+
const { getDefaultSshDir } = require('./ssh-key-helper');
|
|
15
|
+
const { getDevSshHostAlias, resolveDevSshHostAlias } = require('./dev-ssh-config-helper');
|
|
16
|
+
|
|
17
|
+
const execFileAsync = promisify(execFile);
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {string} baseUrl
|
|
21
|
+
* @returns {string|null}
|
|
22
|
+
*/
|
|
23
|
+
function hostnameFromBaseUrl(baseUrl) {
|
|
24
|
+
if (!baseUrl || typeof baseUrl !== 'string') return null;
|
|
25
|
+
const s = baseUrl.trim().replace(/\/+$/, '');
|
|
26
|
+
const withProtocol = /^https?:\/\//i.test(s) ? s : `https://${s}`;
|
|
27
|
+
try {
|
|
28
|
+
return new URL(withProtocol).hostname || null;
|
|
29
|
+
} catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @param {string} hostname
|
|
36
|
+
* @param {string} knownHostsPath
|
|
37
|
+
* @returns {Promise<{ hostname: string, ok: boolean, error?: string }>}
|
|
38
|
+
*/
|
|
39
|
+
async function removeKnownHostEntry(hostname, knownHostsPath) {
|
|
40
|
+
const host = String(hostname || '').trim();
|
|
41
|
+
if (!host) {
|
|
42
|
+
return { hostname: host, ok: false, error: 'empty hostname' };
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
await execFileAsync('ssh-keygen', ['-R', host, '-f', knownHostsPath], {
|
|
46
|
+
encoding: 'utf8'
|
|
47
|
+
});
|
|
48
|
+
return { hostname: host, ok: true };
|
|
49
|
+
} catch (err) {
|
|
50
|
+
if (err && err.code === 'ENOENT') {
|
|
51
|
+
return { hostname: host, ok: false, error: 'ssh-keygen not found' };
|
|
52
|
+
}
|
|
53
|
+
return { hostname: host, ok: false, error: err.message || String(err) };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Hostnames that may appear in known_hosts for a Builder dev SSH connection.
|
|
59
|
+
* Includes current Host alias, HostName (sync-ssh-host), remote-server host, and legacy Host aliases.
|
|
60
|
+
*
|
|
61
|
+
* @param {Object} p
|
|
62
|
+
* @param {string} p.syncHost - sync-ssh-host / HostName
|
|
63
|
+
* @param {string} p.syncUser - sync-ssh-user
|
|
64
|
+
* @param {string} [p.hostAlias] - Preferred ssh config Host alias
|
|
65
|
+
* @param {string} [p.baseUrl] - remote-server URL
|
|
66
|
+
* @param {string} [p.developerId]
|
|
67
|
+
* @param {string} [p.developerRootDomain]
|
|
68
|
+
* @param {string[]} [p.legacyHostAliases] - Previous Host keywords from ~/.ssh/config
|
|
69
|
+
* @returns {string[]}
|
|
70
|
+
*/
|
|
71
|
+
function collectDevSshKnownHostCandidates(p) {
|
|
72
|
+
const syncHost = String(p.syncHost || '').trim();
|
|
73
|
+
const syncUser = String(p.syncUser || '').trim();
|
|
74
|
+
const candidates = new Set();
|
|
75
|
+
if (syncHost) {
|
|
76
|
+
candidates.add(syncHost);
|
|
77
|
+
}
|
|
78
|
+
if (p.hostAlias) {
|
|
79
|
+
candidates.add(String(p.hostAlias).trim());
|
|
80
|
+
}
|
|
81
|
+
const preferred = resolveDevSshHostAlias({
|
|
82
|
+
syncUser,
|
|
83
|
+
syncHost,
|
|
84
|
+
developerId: p.developerId,
|
|
85
|
+
developerRootDomain: p.developerRootDomain
|
|
86
|
+
});
|
|
87
|
+
if (preferred) {
|
|
88
|
+
candidates.add(preferred);
|
|
89
|
+
}
|
|
90
|
+
if (syncUser && syncHost) {
|
|
91
|
+
candidates.add(getDevSshHostAlias(syncUser, syncHost));
|
|
92
|
+
}
|
|
93
|
+
const fromUrl = hostnameFromBaseUrl(p.baseUrl);
|
|
94
|
+
if (fromUrl) {
|
|
95
|
+
candidates.add(fromUrl);
|
|
96
|
+
}
|
|
97
|
+
for (const alias of p.legacyHostAliases || []) {
|
|
98
|
+
const trimmed = String(alias || '').trim();
|
|
99
|
+
if (trimmed) {
|
|
100
|
+
candidates.add(trimmed);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return [...candidates].filter(Boolean);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @param {string[]} hostnames
|
|
108
|
+
* @param {string} [sshDir]
|
|
109
|
+
* @returns {Promise<{ cleared: string[], failed: Array<{ hostname: string, error: string }> }>}
|
|
110
|
+
*/
|
|
111
|
+
async function refreshDevSshKnownHosts(hostnames, sshDir) {
|
|
112
|
+
const knownHostsPath = path.join(sshDir || getDefaultSshDir(), 'known_hosts');
|
|
113
|
+
const cleared = [];
|
|
114
|
+
const failed = [];
|
|
115
|
+
for (const hostname of hostnames) {
|
|
116
|
+
const result = await removeKnownHostEntry(hostname, knownHostsPath);
|
|
117
|
+
if (result.ok) {
|
|
118
|
+
cleared.push(result.hostname);
|
|
119
|
+
} else if (result.error && result.error !== 'empty hostname') {
|
|
120
|
+
failed.push({ hostname: result.hostname, error: result.error });
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return { cleared, failed };
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
module.exports = {
|
|
127
|
+
collectDevSshKnownHostCandidates,
|
|
128
|
+
removeKnownHostEntry,
|
|
129
|
+
refreshDevSshKnownHosts
|
|
130
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview CLI normalization for manifest version target and test sync policy (456.17).
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const SYNC_MODES = new Set(['auto', 'never', 'force']);
|
|
10
|
+
const VERSION_KEYWORDS = new Set(['latest', 'running']);
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @param {string|undefined|null} raw
|
|
14
|
+
* @param {string} [defaultValue='latest']
|
|
15
|
+
* @returns {string}
|
|
16
|
+
*/
|
|
17
|
+
function normalizeVersionTarget(raw, defaultValue = 'latest') {
|
|
18
|
+
const value = String(raw ?? defaultValue).trim();
|
|
19
|
+
if (!value) {
|
|
20
|
+
throw new Error('--version is required (latest, running, or explicit version id).');
|
|
21
|
+
}
|
|
22
|
+
const lower = value.toLowerCase();
|
|
23
|
+
if (VERSION_KEYWORDS.has(lower)) {
|
|
24
|
+
return lower;
|
|
25
|
+
}
|
|
26
|
+
if (!/^[a-zA-Z0-9._-]+$/.test(value)) {
|
|
27
|
+
throw new Error(
|
|
28
|
+
'--version must be latest, running, or an explicit version id (letters, numbers, ., _, -).'
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
return value;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @param {string|undefined|null} raw
|
|
36
|
+
* @param {string} [defaultValue='auto']
|
|
37
|
+
* @returns {string}
|
|
38
|
+
*/
|
|
39
|
+
function normalizeSyncMode(raw, defaultValue = 'auto') {
|
|
40
|
+
const value = String(raw ?? defaultValue).trim().toLowerCase();
|
|
41
|
+
if (!SYNC_MODES.has(value)) {
|
|
42
|
+
throw new Error('--sync-mode must be auto, never, or force.');
|
|
43
|
+
}
|
|
44
|
+
return value;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Merge versionTarget and syncMode from CLI options into e2eOptions for ValidationRunRequest.
|
|
49
|
+
*
|
|
50
|
+
* @param {Object} cliOptions - Commander-parsed options
|
|
51
|
+
* @param {Object} [e2eOptions={}]
|
|
52
|
+
* @returns {Object}
|
|
53
|
+
*/
|
|
54
|
+
function mergeTestTargetIntoE2eOptions(cliOptions, e2eOptions = {}) {
|
|
55
|
+
const merged = { ...e2eOptions };
|
|
56
|
+
if (cliOptions && cliOptions.version !== undefined && cliOptions.version !== null) {
|
|
57
|
+
merged.versionTarget = normalizeVersionTarget(cliOptions.version);
|
|
58
|
+
} else {
|
|
59
|
+
merged.versionTarget = normalizeVersionTarget(undefined, 'latest');
|
|
60
|
+
}
|
|
61
|
+
if (cliOptions && cliOptions.syncMode !== undefined && cliOptions.syncMode !== null) {
|
|
62
|
+
merged.syncMode = normalizeSyncMode(cliOptions.syncMode);
|
|
63
|
+
} else {
|
|
64
|
+
merged.syncMode = normalizeSyncMode(undefined, 'auto');
|
|
65
|
+
}
|
|
66
|
+
return merged;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
module.exports = {
|
|
70
|
+
SYNC_MODES,
|
|
71
|
+
VERSION_KEYWORDS,
|
|
72
|
+
normalizeVersionTarget,
|
|
73
|
+
normalizeSyncMode,
|
|
74
|
+
mergeTestTargetIntoE2eOptions
|
|
75
|
+
};
|
|
@@ -409,13 +409,29 @@ function applyLabDataplaneApiKeyBearer(authConfig) {
|
|
|
409
409
|
}
|
|
410
410
|
|
|
411
411
|
function requireBearerForDataplanePipeline(authConfig) {
|
|
412
|
+
if (!authConfig || typeof authConfig !== 'object') {
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
|
|
412
416
|
if (authConfig.type === 'client-token' && authConfig.token) {
|
|
413
417
|
return;
|
|
414
418
|
}
|
|
415
419
|
|
|
420
|
+
// Token-forward (builder-api / bearerForward): never substitute lab API_KEY for the caller JWT.
|
|
421
|
+
if (authConfig.preserveBearer && authConfig.token) {
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
|
|
416
425
|
const preferAppClientToken =
|
|
417
426
|
String(process.env.AIFABRIX_DEPLOYMENT_AUTH || '').toLowerCase() === 'client-credentials';
|
|
418
427
|
|
|
428
|
+
const existing = authConfig.token ? String(authConfig.token) : '';
|
|
429
|
+
const looksLikeJwt = existing.split('.').length === 3 && existing.length > 80;
|
|
430
|
+
// Enterprise path: keep a real OAuth JWT; do not overwrite with process.env.API_KEY.
|
|
431
|
+
if (looksLikeJwt) {
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
|
|
419
435
|
if (!preferAppClientToken && process.env.API_KEY) {
|
|
420
436
|
const apiKey = String(process.env.API_KEY);
|
|
421
437
|
if (authConfig.type === 'bearer' && authConfig.token !== apiKey) {
|
|
@@ -10,20 +10,38 @@
|
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* @param {Object} [options] - CLI options from test / sync callers
|
|
13
|
-
* @returns {{ minimal: true, verbose: boolean, silentResolve: true, syncMode: true, force?: true }}
|
|
13
|
+
* @returns {{ minimal: true, verbose: boolean, silentResolve: true, syncMode: true, force?: true, authConfig?: Object, dataplaneUrl?: string, environment?: string }}
|
|
14
14
|
*/
|
|
15
15
|
function buildMinimalUploadSyncOptions(options = {}) {
|
|
16
|
+
const deployPreflight = options.uploadContext === 'deploy-preflight';
|
|
16
17
|
const out = {
|
|
17
18
|
minimal: true,
|
|
18
19
|
// CLI -v on verify-* / test-* is for run output, not preflight upload banners.
|
|
19
20
|
verbose: false,
|
|
20
21
|
silentResolve: true,
|
|
21
22
|
syncMode: true,
|
|
22
|
-
|
|
23
|
+
skipDataSync: true,
|
|
24
|
+
suppressPipelineSpinner:
|
|
25
|
+
options.suppressPipelineSpinner === true || deployPreflight === true
|
|
23
26
|
};
|
|
24
27
|
if (options.force === true) {
|
|
25
28
|
out.force = true;
|
|
26
29
|
}
|
|
30
|
+
if (options.suppressSummary === true || deployPreflight === true) {
|
|
31
|
+
out.suppressSummary = true;
|
|
32
|
+
}
|
|
33
|
+
if (deployPreflight) {
|
|
34
|
+
out.uploadContext = 'deploy-preflight';
|
|
35
|
+
}
|
|
36
|
+
// Builder-api / programmatic callers: keep request Bearer — do not fall back to
|
|
37
|
+
// getDeploymentAuth against a stale mount AIFABRIX_CONFIG device token.
|
|
38
|
+
if (options.authConfig && options.dataplaneUrl) {
|
|
39
|
+
out.authConfig = options.authConfig;
|
|
40
|
+
out.dataplaneUrl = options.dataplaneUrl;
|
|
41
|
+
if (options.environment) {
|
|
42
|
+
out.environment = options.environment;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
27
45
|
return out;
|
|
28
46
|
}
|
|
29
47
|
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* @version 2.0.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
const { mergeTestTargetIntoE2eOptions, normalizeVersionTarget } = require('./test-target-cli-options');
|
|
8
|
+
|
|
7
9
|
/**
|
|
8
10
|
* Whether the unified validation request should set includeDebug (any `--debug` or `--debug <level>`).
|
|
9
11
|
* @param {*} debugOpt - Commander `options.debug`
|
|
@@ -60,7 +62,7 @@ function buildE2eOptionsFromCli(options = {}) {
|
|
|
60
62
|
if (options.e2eOptionsExtra && typeof options.e2eOptionsExtra === 'object') {
|
|
61
63
|
Object.assign(e2e, options.e2eOptionsExtra);
|
|
62
64
|
}
|
|
63
|
-
return e2e;
|
|
65
|
+
return mergeTestTargetIntoE2eOptions(options, e2e);
|
|
64
66
|
}
|
|
65
67
|
|
|
66
68
|
/**
|
|
@@ -73,6 +75,8 @@ function buildE2eOptionsFromCli(options = {}) {
|
|
|
73
75
|
* @param {boolean} [params.asyncRun]
|
|
74
76
|
* @param {boolean} [params.includeDebug]
|
|
75
77
|
* @param {boolean} [params.explain]
|
|
78
|
+
* @param {boolean} [params.explainCertification]
|
|
79
|
+
* @param {boolean} [params.explainMetrics]
|
|
76
80
|
* @param {Object} [params.e2eOptions] - Merged with buildE2eOptionsFromCli when both used by caller
|
|
77
81
|
* @returns {import('../api/types/validation-run.types').ValidationRunRequestBody}
|
|
78
82
|
*/
|
|
@@ -85,6 +89,8 @@ function buildExternalDataSourceValidationRequest(params) {
|
|
|
85
89
|
asyncRun,
|
|
86
90
|
includeDebug,
|
|
87
91
|
explain,
|
|
92
|
+
explainCertification,
|
|
93
|
+
explainMetrics,
|
|
88
94
|
e2eOptions
|
|
89
95
|
} = params;
|
|
90
96
|
if (!systemKey || !datasourceKey || !runType) {
|
|
@@ -101,6 +107,8 @@ function buildExternalDataSourceValidationRequest(params) {
|
|
|
101
107
|
if (asyncRun === true) body.asyncRun = true;
|
|
102
108
|
if (includeDebug === true) body.includeDebug = true;
|
|
103
109
|
if (explain === true) body.explain = true;
|
|
110
|
+
if (explainCertification === true) body.explainCertification = true;
|
|
111
|
+
if (explainMetrics === true) body.explainMetrics = true;
|
|
104
112
|
if (e2eOptions && typeof e2eOptions === 'object' && Object.keys(e2eOptions).length > 0) {
|
|
105
113
|
body.e2eOptions = e2eOptions;
|
|
106
114
|
}
|
|
@@ -110,5 +118,6 @@ function buildExternalDataSourceValidationRequest(params) {
|
|
|
110
118
|
module.exports = {
|
|
111
119
|
includeDebugForRequest,
|
|
112
120
|
buildE2eOptionsFromCli,
|
|
113
|
-
buildExternalDataSourceValidationRequest
|
|
121
|
+
buildExternalDataSourceValidationRequest,
|
|
122
|
+
normalizeVersionTarget
|
|
114
123
|
};
|