@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
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate integration deploy.js from Handlebars template.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview ESLint-clean deploy script for external integrations
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const fs = require('../internal/fs-real-sync');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const Handlebars = require('handlebars');
|
|
14
|
+
|
|
15
|
+
const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
16
|
+
const logger = require('../utils/logger');
|
|
17
|
+
|
|
18
|
+
const templatesExternalDir = path.join(__dirname, '..', '..', 'templates', 'external-system');
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {string} templateName
|
|
22
|
+
* @param {string} outputPath
|
|
23
|
+
* @param {Object} context
|
|
24
|
+
*/
|
|
25
|
+
async function writeDeployScriptFromTemplate(templateName, outputPath, context) {
|
|
26
|
+
const templatePath = path.join(templatesExternalDir, templateName);
|
|
27
|
+
const content = Handlebars.compile(fs.readFileSync(templatePath, 'utf8'))(context);
|
|
28
|
+
fs.writeFileSync(outputPath, content, { mode: 0o644, encoding: 'utf8' });
|
|
29
|
+
logger.log(formatSuccessLine(`Generated ${path.basename(outputPath)}`));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @param {string} appPath
|
|
34
|
+
* @param {string} systemKey
|
|
35
|
+
* @param {string} systemFileName
|
|
36
|
+
* @param {string[]} datasourceFileNames
|
|
37
|
+
* @returns {Promise<{ deployJsPath: string }>}
|
|
38
|
+
*/
|
|
39
|
+
async function generateDeployScripts(appPath, systemKey, systemFileName, datasourceFileNames) {
|
|
40
|
+
try {
|
|
41
|
+
const allJsonFiles = [systemFileName, ...datasourceFileNames];
|
|
42
|
+
const context = { systemKey, allJsonFiles, datasourceFileNames };
|
|
43
|
+
const deployJsPath = path.join(appPath, 'deploy.js');
|
|
44
|
+
await writeDeployScriptFromTemplate('deploy.js.hbs', deployJsPath, context);
|
|
45
|
+
return { deployJsPath };
|
|
46
|
+
} catch (error) {
|
|
47
|
+
throw new Error(`Failed to generate deployment scripts: ${error.message}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Regenerate deploy.js from integration manifest file lists.
|
|
53
|
+
*
|
|
54
|
+
* @param {Object} params
|
|
55
|
+
* @param {string} params.appPath
|
|
56
|
+
* @param {string} params.systemKey
|
|
57
|
+
* @param {string[]} params.systemFiles
|
|
58
|
+
* @param {string[]} params.datasourceFiles
|
|
59
|
+
* @returns {Promise<{ deployJsPath: string }>}
|
|
60
|
+
*/
|
|
61
|
+
async function regenerateDeployScriptFromIntegration(params) {
|
|
62
|
+
const { appPath, systemKey, systemFiles, datasourceFiles } = params;
|
|
63
|
+
if (!systemFiles?.length) {
|
|
64
|
+
throw new Error('externalIntegration.systems is empty — cannot generate deploy.js');
|
|
65
|
+
}
|
|
66
|
+
return generateDeployScripts(appPath, systemKey, systemFiles[0], datasourceFiles || []);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
module.exports = {
|
|
70
|
+
writeDeployScriptFromTemplate,
|
|
71
|
+
generateDeployScripts,
|
|
72
|
+
regenerateDeployScriptFromIntegration
|
|
73
|
+
};
|
package/lib/generator/helpers.js
CHANGED
|
@@ -156,10 +156,10 @@ function validatePortalInput(portalInput, variableName) {
|
|
|
156
156
|
* @throws {Error} If portalInput structure is invalid
|
|
157
157
|
*/
|
|
158
158
|
/**
|
|
159
|
-
* Creates a map of
|
|
159
|
+
* Creates a map of portal overlay metadata from variables config
|
|
160
160
|
* @function createPortalInputMap
|
|
161
161
|
* @param {Object|null} variablesConfig - Configuration from application.yaml
|
|
162
|
-
* @returns {Map} Map of variable names to portalInput
|
|
162
|
+
* @returns {Map} Map of variable names to { portalInput, category? }
|
|
163
163
|
*/
|
|
164
164
|
function createPortalInputMap(variablesConfig) {
|
|
165
165
|
const portalInputMap = new Map();
|
|
@@ -168,7 +168,11 @@ function createPortalInputMap(variablesConfig) {
|
|
|
168
168
|
if (configItem.name && configItem.portalInput) {
|
|
169
169
|
// Validate portalInput before adding to map
|
|
170
170
|
validatePortalInput(configItem.portalInput, configItem.name);
|
|
171
|
-
|
|
171
|
+
const overlay = { portalInput: configItem.portalInput };
|
|
172
|
+
if (typeof configItem.category === 'string' && configItem.category.trim().length > 0) {
|
|
173
|
+
overlay.category = configItem.category.trim();
|
|
174
|
+
}
|
|
175
|
+
portalInputMap.set(configItem.name, overlay);
|
|
172
176
|
}
|
|
173
177
|
}
|
|
174
178
|
}
|
|
@@ -291,9 +295,13 @@ function createConfigItem(key, value, location, required, portalInputMap, appKey
|
|
|
291
295
|
required
|
|
292
296
|
};
|
|
293
297
|
|
|
294
|
-
// Merge portalInput if
|
|
298
|
+
// Merge portalInput / category if present in application config
|
|
295
299
|
if (portalInputMap.has(key)) {
|
|
296
|
-
|
|
300
|
+
const overlay = portalInputMap.get(key);
|
|
301
|
+
configItem.portalInput = overlay.portalInput;
|
|
302
|
+
if (typeof overlay.category === 'string' && overlay.category.length > 0) {
|
|
303
|
+
configItem.category = overlay.category;
|
|
304
|
+
}
|
|
297
305
|
}
|
|
298
306
|
|
|
299
307
|
return configItem;
|
package/lib/generator/index.js
CHANGED
|
@@ -302,7 +302,22 @@ async function generateDeployJson(appName, options = {}) {
|
|
|
302
302
|
if (!appName || typeof appName !== 'string') {
|
|
303
303
|
throw new Error('App name is required and must be a string');
|
|
304
304
|
}
|
|
305
|
-
|
|
305
|
+
let appPath;
|
|
306
|
+
let isExternal;
|
|
307
|
+
let appType;
|
|
308
|
+
if (options.appPath) {
|
|
309
|
+
appPath = path.resolve(options.appPath);
|
|
310
|
+
const configPath = resolveApplicationConfigPath(appPath);
|
|
311
|
+
const { loadConfigFile } = require('../utils/config-format');
|
|
312
|
+
const variables = loadConfigFile(configPath);
|
|
313
|
+
appType = variables?.app?.type || 'external';
|
|
314
|
+
isExternal = appType === 'external';
|
|
315
|
+
} else {
|
|
316
|
+
const detected = await detectAppType(appName, options);
|
|
317
|
+
appPath = detected.appPath;
|
|
318
|
+
isExternal = detected.isExternal;
|
|
319
|
+
appType = detected.appType;
|
|
320
|
+
}
|
|
306
321
|
logOfflinePathWhenType(appPath);
|
|
307
322
|
if (isExternal) {
|
|
308
323
|
return writeExternalDeployJson(appName, appPath, options);
|
|
@@ -315,7 +330,7 @@ async function generateDeployJsonWithValidation(appName, options = {}) {
|
|
|
315
330
|
const jsonContent = fs.readFileSync(jsonPath, 'utf8');
|
|
316
331
|
const deployment = JSON.parse(jsonContent);
|
|
317
332
|
|
|
318
|
-
const { isExternal } = await detectAppType(appName);
|
|
333
|
+
const { isExternal } = await detectAppType(appName, options);
|
|
319
334
|
|
|
320
335
|
// For external systems, skip deployment JSON validation (they use external system JSON structure)
|
|
321
336
|
if (isExternal) {
|
|
@@ -66,15 +66,21 @@ function extractOptionalSections(deployment) {
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
/**
|
|
69
|
-
* Portal-only configuration for application.yaml (name +
|
|
69
|
+
* Portal-only configuration for application.yaml (name + optional category + portalInput).
|
|
70
70
|
* @param {Array} configuration - Configuration array from deployment JSON
|
|
71
|
-
* @returns {Array<{ name: string, portalInput: Object }>}
|
|
71
|
+
* @returns {Array<{ name: string, category?: string, portalInput: Object }>}
|
|
72
72
|
*/
|
|
73
73
|
function extractPortalInputConfiguration(configuration) {
|
|
74
74
|
if (!Array.isArray(configuration) || configuration.length === 0) return [];
|
|
75
75
|
return configuration
|
|
76
76
|
.filter(item => item && item.portalInput && typeof item.name === 'string')
|
|
77
|
-
.map(item =>
|
|
77
|
+
.map(item => {
|
|
78
|
+
const entry = { name: item.name, portalInput: item.portalInput };
|
|
79
|
+
if (typeof item.category === 'string' && item.category.trim().length > 0) {
|
|
80
|
+
entry.category = item.category.trim();
|
|
81
|
+
}
|
|
82
|
+
return entry;
|
|
83
|
+
});
|
|
78
84
|
}
|
|
79
85
|
|
|
80
86
|
/**
|
package/lib/generator/wizard.js
CHANGED
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
12
12
|
const fs = require('fs').promises;
|
|
13
13
|
const path = require('path');
|
|
14
|
-
const Handlebars = require('handlebars');
|
|
15
14
|
const logger = require('../utils/logger');
|
|
16
15
|
const { resolveApplicationConfigPath } = require('../utils/app-config-resolver');
|
|
17
16
|
const { loadConfigFile, writeConfigFile } = require('../utils/config-format');
|
|
@@ -178,7 +177,8 @@ async function generateConfigFilesForWizard(params) {
|
|
|
178
177
|
}
|
|
179
178
|
|
|
180
179
|
async function prepareWizardContext(appName, systemConfig, datasourceConfigs) {
|
|
181
|
-
const
|
|
180
|
+
const { getIntegrationPath } = require('../utils/paths');
|
|
181
|
+
const appPath = getIntegrationPath(appName);
|
|
182
182
|
await fs.mkdir(appPath, { recursive: true });
|
|
183
183
|
const finalSystemKey = appName;
|
|
184
184
|
const originalSystemKey = systemConfig.key || finalSystemKey;
|
|
@@ -430,40 +430,7 @@ async function _generateEnvTemplate(appPath, systemConfig, finalSystemKey) {
|
|
|
430
430
|
}
|
|
431
431
|
}
|
|
432
432
|
|
|
433
|
-
|
|
434
|
-
* Generate deployment script (deploy.js) from template
|
|
435
|
-
* @async
|
|
436
|
-
* @function generateDeployScripts
|
|
437
|
-
* @param {string} appPath - Application directory path
|
|
438
|
-
* @param {string} systemKey - System key
|
|
439
|
-
* @param {string} systemFileName - System file name
|
|
440
|
-
* @param {string[]} datasourceFileNames - Array of datasource file names
|
|
441
|
-
* @returns {Promise<Object>} Object with deployJsPath
|
|
442
|
-
* @throws {Error} If generation fails
|
|
443
|
-
*/
|
|
444
|
-
const templatesExternalDir = path.join(__dirname, '..', '..', 'templates', 'external-system');
|
|
445
|
-
|
|
446
|
-
async function writeDeployScriptFromTemplate(templateName, outputPath, context) {
|
|
447
|
-
const templatePath = path.join(templatesExternalDir, templateName);
|
|
448
|
-
const content = Handlebars.compile(await fs.readFile(templatePath, 'utf8'))(context);
|
|
449
|
-
await fs.writeFile(outputPath, content, 'utf8');
|
|
450
|
-
logger.log(formatSuccessLine(`Generated ${path.basename(outputPath)}`));
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
async function generateDeployScripts(appPath, systemKey, systemFileName, datasourceFileNames) {
|
|
454
|
-
try {
|
|
455
|
-
const allJsonFiles = [systemFileName, ...datasourceFileNames];
|
|
456
|
-
const context = { systemKey, allJsonFiles, datasourceFileNames };
|
|
457
|
-
|
|
458
|
-
await writeDeployScriptFromTemplate('deploy.js.hbs', path.join(appPath, 'deploy.js'), context);
|
|
459
|
-
|
|
460
|
-
return {
|
|
461
|
-
deployJsPath: path.join(appPath, 'deploy.js')
|
|
462
|
-
};
|
|
463
|
-
} catch (error) {
|
|
464
|
-
throw new Error(`Failed to generate deployment scripts: ${error.message}`);
|
|
465
|
-
}
|
|
466
|
-
}
|
|
433
|
+
const { generateDeployScripts } = require('./deploy-script');
|
|
467
434
|
|
|
468
435
|
module.exports = {
|
|
469
436
|
generateWizardFiles,
|
|
@@ -53,6 +53,12 @@ function formatDockerInfrastructureFailure(detail) {
|
|
|
53
53
|
*/
|
|
54
54
|
async function checkDockerAvailability() {
|
|
55
55
|
await ensureDevCertsIfNeededForRemoteDocker();
|
|
56
|
+
try {
|
|
57
|
+
const { ensureDevCertFreshIfDue } = require('../commands/dev-refresh');
|
|
58
|
+
await ensureDevCertFreshIfDue({ quiet: true });
|
|
59
|
+
} catch {
|
|
60
|
+
// Best-effort renew for remote Docker TLS; docker check reports real failures
|
|
61
|
+
}
|
|
56
62
|
try {
|
|
57
63
|
await dockerUtils.ensureDockerAndCompose();
|
|
58
64
|
} catch (error) {
|
|
@@ -181,7 +181,7 @@ function generatePgAdminConfig(infraDir, postgresPassword) {
|
|
|
181
181
|
* @returns {string} Escaped string
|
|
182
182
|
*/
|
|
183
183
|
function escapePgString(s) {
|
|
184
|
-
if (
|
|
184
|
+
if (typeof s !== 'string') return '';
|
|
185
185
|
return s.replace(/'/g, '\'\'');
|
|
186
186
|
}
|
|
187
187
|
|
|
@@ -118,6 +118,25 @@ function unlinkSync(p) {
|
|
|
118
118
|
return delegate('unlinkSync', [p]);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
/**
|
|
122
|
+
* @param {string} src
|
|
123
|
+
* @param {string} dest
|
|
124
|
+
* @returns {void}
|
|
125
|
+
*/
|
|
126
|
+
function copyFileSync(src, dest) {
|
|
127
|
+
return delegate('copyFileSync', [src, dest]);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @param {string} p
|
|
132
|
+
* @param {string|Buffer} data
|
|
133
|
+
* @param {object|string} [opts]
|
|
134
|
+
* @returns {void}
|
|
135
|
+
*/
|
|
136
|
+
function appendFileSync(p, data, opts) {
|
|
137
|
+
return delegate('appendFileSync', opts !== undefined ? [p, data, opts] : [p, data]);
|
|
138
|
+
}
|
|
139
|
+
|
|
121
140
|
module.exports = {
|
|
122
141
|
existsSync,
|
|
123
142
|
readFileSync,
|
|
@@ -128,5 +147,7 @@ module.exports = {
|
|
|
128
147
|
readdirSync,
|
|
129
148
|
mkdtempSync,
|
|
130
149
|
rmSync,
|
|
131
|
-
unlinkSync
|
|
150
|
+
unlinkSync,
|
|
151
|
+
copyFileSync,
|
|
152
|
+
appendFileSync
|
|
132
153
|
};
|
package/lib/internal/node-fs.js
CHANGED
|
@@ -73,6 +73,7 @@ function buildBoundFs() {
|
|
|
73
73
|
readdirSync: snap.readdirSync,
|
|
74
74
|
statSync: snap.statSync,
|
|
75
75
|
renameSync: snap.renameSync,
|
|
76
|
+
copyFileSync: snap.copyFileSync,
|
|
76
77
|
watch: (...args) => live.watch(...args),
|
|
77
78
|
promises: boundPromises
|
|
78
79
|
};
|
|
@@ -85,6 +86,7 @@ function buildBoundFs() {
|
|
|
85
86
|
readdirSync: bindSync(rf, 'readdirSync'),
|
|
86
87
|
statSync: bindSync(rf, 'statSync'),
|
|
87
88
|
renameSync: bindSync(rf, 'renameSync'),
|
|
89
|
+
copyFileSync: bindSync(rf, 'copyFileSync'),
|
|
88
90
|
watch: (...args) => live.watch(...args),
|
|
89
91
|
promises: boundPromises
|
|
90
92
|
};
|
|
@@ -34,7 +34,7 @@ function buildGovernanceOptsFromLifecycle(options, context = {}) {
|
|
|
34
34
|
env: options.env || 'dev',
|
|
35
35
|
verbose: options.verbose === true,
|
|
36
36
|
debug: options.debug === true,
|
|
37
|
-
|
|
37
|
+
noPublish: true,
|
|
38
38
|
force: options.force === true,
|
|
39
39
|
certificationProfile: options.certificationProfile || 'bronze',
|
|
40
40
|
subjectEmails: options.subjectEmail || options.subjectEmails || [],
|
|
@@ -53,7 +53,7 @@ function formatVerifyStepLabel(label) {
|
|
|
53
53
|
* @returns {Promise<T>}
|
|
54
54
|
*/
|
|
55
55
|
async function runWithVerifyStepProgress(label, work, options = {}) {
|
|
56
|
-
if (!shouldShowVerifyStepProgress(options)) {
|
|
56
|
+
if (options.quietProgress === true || !shouldShowVerifyStepProgress(options)) {
|
|
57
57
|
return withQuietLogs(() => work({ setLabel: () => {} }));
|
|
58
58
|
}
|
|
59
59
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured access logging for builder-api requests.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview JSON logs without tokens or manifest bodies
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const { redactForLog } = require('./log-redaction');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param {Object} entry
|
|
15
|
+
*/
|
|
16
|
+
function writeAccessLog(entry) {
|
|
17
|
+
const payload = redactForLog({
|
|
18
|
+
timestamp: new Date().toISOString(),
|
|
19
|
+
...entry
|
|
20
|
+
});
|
|
21
|
+
process.stdout.write(`${JSON.stringify(payload)}\n`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
module.exports = {
|
|
25
|
+
writeAccessLog
|
|
26
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bearer auth config for programmatic Dataplane calls.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Build authConfig from user Bearer token (no device token store)
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param {string} bearerToken
|
|
13
|
+
* @returns {{ type: 'bearer', token: string, preserveBearer: true }}
|
|
14
|
+
*/
|
|
15
|
+
function buildBearerAuthConfig(bearerToken) {
|
|
16
|
+
if (!bearerToken || typeof bearerToken !== 'string') {
|
|
17
|
+
throw new Error('Bearer token is required');
|
|
18
|
+
}
|
|
19
|
+
const token = bearerToken.startsWith('Bearer ') ? bearerToken.slice(7).trim() : bearerToken.trim();
|
|
20
|
+
if (!token) {
|
|
21
|
+
throw new Error('Bearer token is required');
|
|
22
|
+
}
|
|
23
|
+
// Token-forward: caller JWT must reach dataplane CIP/pipeline unchanged (no API_KEY swap).
|
|
24
|
+
return { type: 'bearer', token, preserveBearer: true };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @param {import('./workspace-context').WorkspaceContext} ctx
|
|
29
|
+
* @returns {{ authConfig: Object, dataplaneUrl: string, environment: string }}
|
|
30
|
+
*/
|
|
31
|
+
function buildProgrammaticAuthContext(ctx) {
|
|
32
|
+
if (!ctx.dataplaneUrl) {
|
|
33
|
+
throw new Error('dataplaneUrl is required on WorkspaceContext');
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
authConfig: buildBearerAuthConfig(ctx.bearerToken),
|
|
37
|
+
dataplaneUrl: ctx.dataplaneUrl,
|
|
38
|
+
environment: ctx.environment
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
module.exports = {
|
|
43
|
+
buildBearerAuthConfig,
|
|
44
|
+
buildProgrammaticAuthContext
|
|
45
|
+
};
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bearer token validation for builder-api via @aifabrix/miso-client (controller-backed).
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Same model as dataplane: registered app client + MISO_CONTROLLER_URL
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
/** @type {import('@aifabrix/miso-client').MisoClient | null} */
|
|
12
|
+
let misoClientSingleton = null;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param {import('http').IncomingMessage} req
|
|
16
|
+
* @returns {string|null}
|
|
17
|
+
*/
|
|
18
|
+
function extractBearerToken(req) {
|
|
19
|
+
const auth = req.headers.authorization || req.headers.Authorization;
|
|
20
|
+
if (!auth || typeof auth !== 'string') {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
const match = auth.match(/^Bearer\s+([^\s]+)\s*$/i);
|
|
24
|
+
return match ? match[1].trim() : null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @param {import('http').IncomingMessage} req
|
|
29
|
+
*/
|
|
30
|
+
function assertNoForbiddenAuthHeaders(req) {
|
|
31
|
+
if (req.headers['x-client-token'] || req.headers['x-client-id']) {
|
|
32
|
+
const err = new Error('Client credential headers are not supported in builder-api V1');
|
|
33
|
+
err.statusCode = 401;
|
|
34
|
+
throw err;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @returns {string}
|
|
40
|
+
*/
|
|
41
|
+
function resolveControllerUrlFromEnv() {
|
|
42
|
+
const raw =
|
|
43
|
+
process.env.MISO_CONTROLLER_URL ||
|
|
44
|
+
process.env.CONTROLLER_URL ||
|
|
45
|
+
process.env.MISO_WEB_SERVER_URL ||
|
|
46
|
+
'';
|
|
47
|
+
const url = String(raw).trim().replace(/\/$/, '');
|
|
48
|
+
if (!url) {
|
|
49
|
+
throw new Error('MISO_CONTROLLER_URL (or CONTROLLER_URL) is required for token validation');
|
|
50
|
+
}
|
|
51
|
+
return url;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @returns {import('@aifabrix/miso-client/dist/types/config.types').MisoClientConfig}
|
|
56
|
+
*/
|
|
57
|
+
function buildMisoClientConfigFromEnv() {
|
|
58
|
+
const clientId = (process.env.MISO_CLIENTID || '').trim();
|
|
59
|
+
const clientSecret = (process.env.MISO_CLIENTSECRET || '').trim();
|
|
60
|
+
if (!clientId || !clientSecret) {
|
|
61
|
+
throw new Error('MISO_CLIENTID and MISO_CLIENTSECRET are required for builder-api auth');
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
clientId,
|
|
65
|
+
clientSecret,
|
|
66
|
+
controllerUrl: resolveControllerUrlFromEnv(),
|
|
67
|
+
logLevel: (process.env.LOG_LEVEL || 'info').toLowerCase()
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Test hook — reset cached MisoClient between Jest cases.
|
|
73
|
+
*/
|
|
74
|
+
function resetMisoClientForTests() {
|
|
75
|
+
misoClientSingleton = null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @returns {Promise<import('@aifabrix/miso-client').MisoClient>}
|
|
80
|
+
*/
|
|
81
|
+
async function getMisoClientForAuth() {
|
|
82
|
+
let MisoClient;
|
|
83
|
+
try {
|
|
84
|
+
({ MisoClient } = require('@aifabrix/miso-client'));
|
|
85
|
+
} catch {
|
|
86
|
+
const err = new Error('@aifabrix/miso-client is required for builder-api auth');
|
|
87
|
+
err.statusCode = 503;
|
|
88
|
+
throw err;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (!misoClientSingleton) {
|
|
92
|
+
misoClientSingleton = new MisoClient(buildMisoClientConfigFromEnv());
|
|
93
|
+
}
|
|
94
|
+
if (!misoClientSingleton.isInitialized()) {
|
|
95
|
+
await misoClientSingleton.initialize();
|
|
96
|
+
}
|
|
97
|
+
return misoClientSingleton;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* @param {import('@aifabrix/miso-client/dist/types/config.types').UserInfo} userInfo
|
|
102
|
+
* @returns {string}
|
|
103
|
+
*/
|
|
104
|
+
function userIdFromUserInfo(userInfo) {
|
|
105
|
+
const userId = userInfo?.id || userInfo?.username;
|
|
106
|
+
if (!userId) {
|
|
107
|
+
const err = new Error('Token validation returned no user id');
|
|
108
|
+
err.statusCode = 401;
|
|
109
|
+
throw err;
|
|
110
|
+
}
|
|
111
|
+
return String(userId);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @param {string} token
|
|
116
|
+
* @param {Object} [opts]
|
|
117
|
+
* @returns {Promise<{ userId: string, payload: Object }>}
|
|
118
|
+
*/
|
|
119
|
+
async function validateBearerToken(token, opts = {}) {
|
|
120
|
+
if (!token) {
|
|
121
|
+
const err = new Error('Missing Bearer token');
|
|
122
|
+
err.statusCode = 401;
|
|
123
|
+
throw err;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const client = opts.misoClient || (await getMisoClientForAuth());
|
|
127
|
+
const valid = await client.validateToken(token, opts.authStrategy);
|
|
128
|
+
if (!valid) {
|
|
129
|
+
const err = new Error('Invalid token');
|
|
130
|
+
err.statusCode = 401;
|
|
131
|
+
throw err;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const userInfo = await client.getUser(token, opts.authStrategy);
|
|
135
|
+
if (!userInfo) {
|
|
136
|
+
const err = new Error('Invalid token');
|
|
137
|
+
err.statusCode = 401;
|
|
138
|
+
throw err;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const payload = {
|
|
142
|
+
sub: userInfo.id,
|
|
143
|
+
preferredUsername: userInfo.username,
|
|
144
|
+
email: userInfo.email,
|
|
145
|
+
roles: userInfo.roles || []
|
|
146
|
+
};
|
|
147
|
+
return { userId: userIdFromUserInfo(userInfo), payload };
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* @param {import('http').IncomingMessage} req
|
|
152
|
+
* @param {Object} [opts]
|
|
153
|
+
* @returns {Promise<{ userId: string, bearerToken: string, payload: Object }>}
|
|
154
|
+
*/
|
|
155
|
+
async function authenticateRequest(req, opts = {}) {
|
|
156
|
+
assertNoForbiddenAuthHeaders(req);
|
|
157
|
+
const bearerToken = extractBearerToken(req);
|
|
158
|
+
if (!bearerToken) {
|
|
159
|
+
const err = new Error('Authorization Bearer token required');
|
|
160
|
+
err.statusCode = 401;
|
|
161
|
+
throw err;
|
|
162
|
+
}
|
|
163
|
+
const { userId, payload } = await validateBearerToken(bearerToken, opts);
|
|
164
|
+
return { userId, bearerToken, payload };
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
module.exports = {
|
|
168
|
+
extractBearerToken,
|
|
169
|
+
assertNoForbiddenAuthHeaders,
|
|
170
|
+
resolveControllerUrlFromEnv,
|
|
171
|
+
buildMisoClientConfigFromEnv,
|
|
172
|
+
resetMisoClientForTests,
|
|
173
|
+
getMisoClientForAuth,
|
|
174
|
+
validateBearerToken,
|
|
175
|
+
authenticateRequest
|
|
176
|
+
};
|