@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,452 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Business role commands (Controller).
|
|
3
|
+
*
|
|
4
|
+
* Commands:
|
|
5
|
+
* - aifabrix role create|import|export|get|list
|
|
6
|
+
*
|
|
7
|
+
* Distinct from `aifabrix identity role` (environment RBAC mappings).
|
|
8
|
+
*
|
|
9
|
+
* @fileoverview Business role CLI commands
|
|
10
|
+
* @author AI Fabrix Team
|
|
11
|
+
* @version 1.0.0
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
'use strict';
|
|
15
|
+
|
|
16
|
+
const chalk = require('chalk');
|
|
17
|
+
const logger = require('../utils/logger');
|
|
18
|
+
const { resolveControllerUrl } = require('../utils/controller-url');
|
|
19
|
+
const { normalizeControllerUrl, resolveEnvironment } = require('../core/config');
|
|
20
|
+
const { getOrRefreshDeviceToken } = require('../utils/token-manager');
|
|
21
|
+
const {
|
|
22
|
+
readRoleCreateFile,
|
|
23
|
+
readRoleCatalogFile,
|
|
24
|
+
writeRoleCatalogFile,
|
|
25
|
+
mapRoleFileToApiPayload,
|
|
26
|
+
mapRoleApiToFileRow
|
|
27
|
+
} = require('../resolvers/role-file');
|
|
28
|
+
const {
|
|
29
|
+
formatBlockingError,
|
|
30
|
+
formatSuccessLine,
|
|
31
|
+
infoLine,
|
|
32
|
+
headerKeyValue
|
|
33
|
+
} = require('../utils/cli-layout-chalk');
|
|
34
|
+
const { listRoles, getRole, createRoleIdempotent } = require('../api/roles.api');
|
|
35
|
+
|
|
36
|
+
const ROLE_KEY_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
37
|
+
|
|
38
|
+
const ROLE_HELP_AFTER = `
|
|
39
|
+
|
|
40
|
+
Examples:
|
|
41
|
+
$ aifabrix role create --key sales-manager --display-name "Sales Manager" --domain sales
|
|
42
|
+
$ aifabrix role get sales-manager
|
|
43
|
+
$ aifabrix role list --search sales
|
|
44
|
+
|
|
45
|
+
Per-command help: aifabrix role <command> --help
|
|
46
|
+
`;
|
|
47
|
+
|
|
48
|
+
const ROLE_IMPORT_HELP_AFTER = `
|
|
49
|
+
|
|
50
|
+
Examples:
|
|
51
|
+
$ aifabrix role import --file ./baseline-roles.json
|
|
52
|
+
`;
|
|
53
|
+
|
|
54
|
+
const ROLE_EXPORT_HELP_AFTER = `
|
|
55
|
+
|
|
56
|
+
Examples:
|
|
57
|
+
$ aifabrix role export --file ./roles-export.json
|
|
58
|
+
`;
|
|
59
|
+
|
|
60
|
+
const ROLE_CREATE_HELP_AFTER = `
|
|
61
|
+
|
|
62
|
+
Examples:
|
|
63
|
+
$ aifabrix role create --key sales-manager --display-name "Sales Manager" --domain sales
|
|
64
|
+
$ aifabrix role create --key cfo --display-name "CFO" --domain finance --purpose "..." --business-outcome "..."
|
|
65
|
+
$ aifabrix role create --file ./sales-manager.json
|
|
66
|
+
`;
|
|
67
|
+
|
|
68
|
+
const ROLE_GET_HELP_AFTER = `
|
|
69
|
+
|
|
70
|
+
Examples:
|
|
71
|
+
$ aifabrix role get sales-manager
|
|
72
|
+
$ aifabrix role get clx1234567890abcdef
|
|
73
|
+
`;
|
|
74
|
+
|
|
75
|
+
const ROLE_LIST_HELP_AFTER = `
|
|
76
|
+
|
|
77
|
+
Examples:
|
|
78
|
+
$ aifabrix role list
|
|
79
|
+
$ aifabrix role list --page 1 --page-size 50
|
|
80
|
+
$ aifabrix role list --search sales
|
|
81
|
+
`;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @param {string} raw
|
|
85
|
+
* @returns {string}
|
|
86
|
+
*/
|
|
87
|
+
function requireRoleKey(raw) {
|
|
88
|
+
const key = String(raw || '').trim();
|
|
89
|
+
if (!key) {
|
|
90
|
+
throw new Error('Role key is required (--key <key> or --file <path>).');
|
|
91
|
+
}
|
|
92
|
+
if (!ROLE_KEY_PATTERN.test(key)) {
|
|
93
|
+
throw new Error(
|
|
94
|
+
'Role key must start with a lowercase letter and contain only lowercase letters, numbers, and hyphens.'
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
return key;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* @param {Object} _options
|
|
102
|
+
* @returns {Promise<{ controllerUrl: string, authConfig: Object }>}
|
|
103
|
+
*/
|
|
104
|
+
async function resolveControllerAndAuth(_options) {
|
|
105
|
+
const controllerUrl = await resolveControllerUrl();
|
|
106
|
+
if (!controllerUrl) {
|
|
107
|
+
throw new Error('Controller URL is required. Run "aifabrix login" first.');
|
|
108
|
+
}
|
|
109
|
+
const normalized = normalizeControllerUrl(controllerUrl);
|
|
110
|
+
const deviceToken = await getOrRefreshDeviceToken(normalized);
|
|
111
|
+
if (!deviceToken || !deviceToken.token) {
|
|
112
|
+
throw new Error(
|
|
113
|
+
`Not authenticated for controller: ${controllerUrl}. ` +
|
|
114
|
+
'Run "aifabrix login" and try again.'
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
controllerUrl: deviceToken.controller || normalized,
|
|
119
|
+
authConfig: { type: 'bearer', token: deviceToken.token }
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async function resolveHeaderContext() {
|
|
124
|
+
const env = await resolveEnvironment();
|
|
125
|
+
const controllerUrl = await resolveControllerUrl();
|
|
126
|
+
const normalized = normalizeControllerUrl(controllerUrl);
|
|
127
|
+
return { environment: env || 'dev', controllerUrl: normalized };
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @param {Object} response
|
|
132
|
+
* @returns {any}
|
|
133
|
+
*/
|
|
134
|
+
function unwrapControllerData(response) {
|
|
135
|
+
return response?.data?.data ?? response?.data ?? response;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @param {Object|null|undefined} response
|
|
140
|
+
* @param {string} label
|
|
141
|
+
* @returns {void}
|
|
142
|
+
*/
|
|
143
|
+
function assertControllerListSuccess(response, label) {
|
|
144
|
+
if (response && response.success !== false) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const message =
|
|
148
|
+
response?.formattedError || response?.error || `Failed to list ${label}`;
|
|
149
|
+
throw new Error(message);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Extract items from a Controller paginated list response.
|
|
154
|
+
* @param {Object} response
|
|
155
|
+
* @returns {Object[]}
|
|
156
|
+
*/
|
|
157
|
+
function extractControllerListItems(response) {
|
|
158
|
+
if (response?.data && Array.isArray(response.data.data)) {
|
|
159
|
+
return response.data.data;
|
|
160
|
+
}
|
|
161
|
+
const unwrapped = unwrapControllerData(response);
|
|
162
|
+
if (Array.isArray(unwrapped)) {
|
|
163
|
+
return unwrapped;
|
|
164
|
+
}
|
|
165
|
+
if (unwrapped && Array.isArray(unwrapped.data)) {
|
|
166
|
+
return unwrapped.data;
|
|
167
|
+
}
|
|
168
|
+
throw new Error('Unexpected list response from controller');
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Build create payload from flags and optional --file (maps domain → domainKey).
|
|
173
|
+
* @param {Object} options
|
|
174
|
+
* @returns {Object}
|
|
175
|
+
*/
|
|
176
|
+
function buildCreatePayload(options) {
|
|
177
|
+
let base = {};
|
|
178
|
+
if (options.file) {
|
|
179
|
+
base = readRoleCreateFile(options.file);
|
|
180
|
+
}
|
|
181
|
+
const merged = { ...base };
|
|
182
|
+
if (options.key) merged.key = options.key;
|
|
183
|
+
if (options.displayName) merged.displayName = options.displayName;
|
|
184
|
+
if (options.description !== undefined) merged.description = options.description;
|
|
185
|
+
if (options.purpose !== undefined) merged.purpose = options.purpose;
|
|
186
|
+
if (options.businessOutcome !== undefined) merged.businessOutcome = options.businessOutcome;
|
|
187
|
+
if (options.domain) {
|
|
188
|
+
merged.domain = options.domain;
|
|
189
|
+
delete merged.domainKey;
|
|
190
|
+
}
|
|
191
|
+
if (options.file && !options.domain && base.domainKey) {
|
|
192
|
+
return { ...base, key: requireRoleKey(merged.key || base.key) };
|
|
193
|
+
}
|
|
194
|
+
const payload = mapRoleFileToApiPayload(
|
|
195
|
+
{
|
|
196
|
+
...merged,
|
|
197
|
+
domain: merged.domain || merged.domainKey
|
|
198
|
+
},
|
|
199
|
+
0
|
|
200
|
+
);
|
|
201
|
+
payload.key = requireRoleKey(payload.key);
|
|
202
|
+
return payload;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* @param {Object[]} rows
|
|
207
|
+
* @param {string} controllerUrl
|
|
208
|
+
* @param {Object} authConfig
|
|
209
|
+
* @returns {Promise<{ created: number, existed: number, total: number }>}
|
|
210
|
+
*/
|
|
211
|
+
async function importRoleRows(rows, controllerUrl, authConfig) {
|
|
212
|
+
let created = 0;
|
|
213
|
+
let existed = 0;
|
|
214
|
+
for (const payload of rows) {
|
|
215
|
+
payload.key = requireRoleKey(payload.key);
|
|
216
|
+
const out = await createRoleIdempotent(controllerUrl, authConfig, payload);
|
|
217
|
+
if (out.created) {
|
|
218
|
+
created += 1;
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
existed += 1;
|
|
222
|
+
}
|
|
223
|
+
return { created, existed, total: rows.length };
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* @param {string} controllerUrl
|
|
228
|
+
* @param {Object} authConfig
|
|
229
|
+
* @returns {Promise<Object[]>}
|
|
230
|
+
*/
|
|
231
|
+
async function fetchAllRoles(controllerUrl, authConfig) {
|
|
232
|
+
const all = [];
|
|
233
|
+
let page = 1;
|
|
234
|
+
const pageSize = 100;
|
|
235
|
+
for (;;) {
|
|
236
|
+
const res = await listRoles(controllerUrl, authConfig, { page, pageSize });
|
|
237
|
+
assertControllerListSuccess(res, 'roles');
|
|
238
|
+
const items = extractControllerListItems(res);
|
|
239
|
+
if (items.length === 0) {
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
all.push(...items);
|
|
243
|
+
if (items.length < pageSize) {
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
page += 1;
|
|
247
|
+
}
|
|
248
|
+
return all;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function setupRoleImportCommand(role) {
|
|
252
|
+
role
|
|
253
|
+
.command('import')
|
|
254
|
+
.description('Import business roles from baseline JSON (idempotent)')
|
|
255
|
+
.addHelpText('after', ROLE_IMPORT_HELP_AFTER)
|
|
256
|
+
.requiredOption('--file <path>', 'Baseline catalog (roles[]) or JSON array')
|
|
257
|
+
.action(async(options) => {
|
|
258
|
+
try {
|
|
259
|
+
const { controllerUrl, authConfig } = await resolveControllerAndAuth(options);
|
|
260
|
+
const rows = readRoleCatalogFile(options.file);
|
|
261
|
+
const summary = await importRoleRows(rows, controllerUrl, authConfig);
|
|
262
|
+
logger.log(
|
|
263
|
+
formatSuccessLine(
|
|
264
|
+
`Roles imported: ${summary.total} total ` +
|
|
265
|
+
`(${summary.created} created, ${summary.existed} already existed)`
|
|
266
|
+
)
|
|
267
|
+
);
|
|
268
|
+
} catch (e) {
|
|
269
|
+
logger.error(formatBlockingError(e.message));
|
|
270
|
+
process.exit(1);
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function setupRoleExportCommand(role) {
|
|
276
|
+
role
|
|
277
|
+
.command('export')
|
|
278
|
+
.description('Export business roles to baseline-shaped JSON')
|
|
279
|
+
.addHelpText('after', ROLE_EXPORT_HELP_AFTER)
|
|
280
|
+
.requiredOption('--file <path>', 'Output path for baseline catalog JSON')
|
|
281
|
+
.action(async(options) => {
|
|
282
|
+
try {
|
|
283
|
+
const { controllerUrl, authConfig } = await resolveControllerAndAuth(options);
|
|
284
|
+
const records = await fetchAllRoles(controllerUrl, authConfig);
|
|
285
|
+
const rows = records.map(mapRoleApiToFileRow);
|
|
286
|
+
writeRoleCatalogFile(options.file, rows);
|
|
287
|
+
if (rows.length === 0) {
|
|
288
|
+
logger.log(
|
|
289
|
+
infoLine(
|
|
290
|
+
'No business roles on the controller. Create or import roles, then re-run export.'
|
|
291
|
+
)
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
logger.log(formatSuccessLine(`Roles exported: ${rows.length} written to ${options.file}`));
|
|
295
|
+
} catch (e) {
|
|
296
|
+
logger.error(formatBlockingError(e.message));
|
|
297
|
+
process.exit(1);
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function setupRoleCreateCommand(role) {
|
|
303
|
+
role
|
|
304
|
+
.command('create')
|
|
305
|
+
.description('Create business role (idempotent; success if it already exists)')
|
|
306
|
+
.addHelpText('after', ROLE_CREATE_HELP_AFTER)
|
|
307
|
+
.option('--file <path>', 'Read role create payload from JSON file')
|
|
308
|
+
.option('--key <key>', 'Catalog key (lowercase letters, digits, hyphens)')
|
|
309
|
+
.option('--display-name <name>', 'Display name')
|
|
310
|
+
.option('--domain <domain>', 'Enterprise domain key (e.g. sales, finance, platform)')
|
|
311
|
+
.option('--purpose <text>', 'Role purpose')
|
|
312
|
+
.option('--business-outcome <text>', 'Business outcome')
|
|
313
|
+
.option('--description <text>', 'Description')
|
|
314
|
+
.action(async(options) => {
|
|
315
|
+
try {
|
|
316
|
+
const { controllerUrl, authConfig } = await resolveControllerAndAuth(options);
|
|
317
|
+
const payload = buildCreatePayload(options);
|
|
318
|
+
const out = await createRoleIdempotent(controllerUrl, authConfig, payload);
|
|
319
|
+
const row = unwrapControllerData(out.response);
|
|
320
|
+
const domain = row.domainKey || payload.domainKey || '—';
|
|
321
|
+
if (out.created) {
|
|
322
|
+
logger.log(formatSuccessLine(`Role created: ${row.key} (domain: ${domain})`));
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
logger.log(formatSuccessLine(`Role exists: ${row.key} (domain: ${domain})`));
|
|
326
|
+
logger.log(infoLine('No changes were needed.'));
|
|
327
|
+
} catch (e) {
|
|
328
|
+
logger.error(formatBlockingError(e.message));
|
|
329
|
+
process.exit(1);
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function setupRoleGetCommand(role) {
|
|
335
|
+
role
|
|
336
|
+
.command('get <roleIdOrKey>')
|
|
337
|
+
.description('Get business role by id or key')
|
|
338
|
+
.addHelpText('after', ROLE_GET_HELP_AFTER)
|
|
339
|
+
.action(async(roleIdOrKey, options) => {
|
|
340
|
+
try {
|
|
341
|
+
const { environment, controllerUrl: headerControllerUrl } = await resolveHeaderContext();
|
|
342
|
+
const { controllerUrl, authConfig } = await resolveControllerAndAuth(options);
|
|
343
|
+
const res = await getRole(controllerUrl, authConfig, String(roleIdOrKey).trim());
|
|
344
|
+
const row = unwrapControllerData(res);
|
|
345
|
+
logger.log(
|
|
346
|
+
chalk.bold(`\n👤 Business role in ${environment} environment (${headerControllerUrl}):\n`)
|
|
347
|
+
);
|
|
348
|
+
logger.log(headerKeyValue('Key:', row.key || '—'));
|
|
349
|
+
logger.log(headerKeyValue('Display:', row.displayName || '—'));
|
|
350
|
+
logger.log(headerKeyValue('Domain:', row.domainKey || '—'));
|
|
351
|
+
logger.log(headerKeyValue('Active:', row.isActive === false ? 'false' : 'true'));
|
|
352
|
+
if (row.purpose) logger.log(headerKeyValue('Purpose:', row.purpose));
|
|
353
|
+
if (row.businessOutcome) logger.log(headerKeyValue('Business outcome:', row.businessOutcome));
|
|
354
|
+
if (row.description) logger.log(headerKeyValue('Description:', row.description));
|
|
355
|
+
logger.log('');
|
|
356
|
+
} catch (e) {
|
|
357
|
+
logger.error(formatBlockingError(e.message));
|
|
358
|
+
process.exit(1);
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
const ROLE_LIST_COLUMNS = { key: 28, display: 28, domain: 14, active: 8 };
|
|
364
|
+
|
|
365
|
+
function logRoleListHeader(columns) {
|
|
366
|
+
const keyCol = 'Key'.padEnd(columns.key);
|
|
367
|
+
const displayCol = 'Display'.padEnd(columns.display);
|
|
368
|
+
const domainCol = 'Domain'.padEnd(columns.domain);
|
|
369
|
+
const activeCol = 'Active'.padEnd(columns.active);
|
|
370
|
+
logger.log(chalk.gray(`${keyCol}${displayCol}${domainCol}${activeCol}`));
|
|
371
|
+
logger.log(
|
|
372
|
+
chalk.gray('-'.repeat(columns.key + columns.display + columns.domain + columns.active))
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
function logRoleListRows(items, columns) {
|
|
377
|
+
items.forEach((d) => {
|
|
378
|
+
const key = (d?.key ?? '—').toString().padEnd(columns.key);
|
|
379
|
+
const displayName = (d?.displayName ?? '—').toString().padEnd(columns.display);
|
|
380
|
+
const domain = (d?.domainKey ?? '—').toString().padEnd(columns.domain);
|
|
381
|
+
const active = (d?.isActive === false ? 'false' : 'true').padEnd(columns.active);
|
|
382
|
+
logger.log(`${key}${displayName}${domain}${active}`);
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function displayRoleList(items, environment, controllerUrl) {
|
|
387
|
+
logger.log(chalk.bold(`\n👤 Business roles in ${environment} environment (${controllerUrl}):\n`));
|
|
388
|
+
if (!Array.isArray(items) || items.length === 0) {
|
|
389
|
+
logger.log(chalk.gray(' No business roles found.\n'));
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
logRoleListHeader(ROLE_LIST_COLUMNS);
|
|
393
|
+
logRoleListRows(items, ROLE_LIST_COLUMNS);
|
|
394
|
+
logger.log('');
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
function setupRoleListCommand(role) {
|
|
398
|
+
role
|
|
399
|
+
.command('list')
|
|
400
|
+
.description('List business roles')
|
|
401
|
+
.addHelpText('after', ROLE_LIST_HELP_AFTER)
|
|
402
|
+
.option('--page <n>', 'Page', (v) => parseInt(v, 10))
|
|
403
|
+
.option('--page-size <n>', 'Page size', (v) => parseInt(v, 10))
|
|
404
|
+
.option('--search <text>', 'Search by key/displayName/description')
|
|
405
|
+
.option('--domain-key <domain>', 'Filter by domain key')
|
|
406
|
+
.action(async(options) => {
|
|
407
|
+
try {
|
|
408
|
+
const { environment, controllerUrl: headerControllerUrl } = await resolveHeaderContext();
|
|
409
|
+
const { controllerUrl, authConfig } = await resolveControllerAndAuth(options);
|
|
410
|
+
const res = await listRoles(controllerUrl, authConfig, {
|
|
411
|
+
page: options.page,
|
|
412
|
+
pageSize: options.pageSize,
|
|
413
|
+
search: options.search,
|
|
414
|
+
domainKey: options.domainKey
|
|
415
|
+
});
|
|
416
|
+
assertControllerListSuccess(res, 'roles');
|
|
417
|
+
const items = extractControllerListItems(res);
|
|
418
|
+
displayRoleList(items, environment, headerControllerUrl);
|
|
419
|
+
} catch (e) {
|
|
420
|
+
logger.error(formatBlockingError(e.message));
|
|
421
|
+
process.exit(1);
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* @param {import('commander').Command} program
|
|
428
|
+
*/
|
|
429
|
+
function setupRoleCommands(program) {
|
|
430
|
+
const role = program
|
|
431
|
+
.command('role')
|
|
432
|
+
.description('Manage the Controller Role Catalog (COM)')
|
|
433
|
+
.addHelpText('after', ROLE_HELP_AFTER);
|
|
434
|
+
setupRoleCreateCommand(role);
|
|
435
|
+
setupRoleImportCommand(role);
|
|
436
|
+
setupRoleExportCommand(role);
|
|
437
|
+
setupRoleGetCommand(role);
|
|
438
|
+
setupRoleListCommand(role);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
module.exports = {
|
|
442
|
+
setupRoleCommands,
|
|
443
|
+
requireRoleKey,
|
|
444
|
+
buildCreatePayload,
|
|
445
|
+
unwrapControllerData,
|
|
446
|
+
assertControllerListSuccess,
|
|
447
|
+
extractControllerListItems,
|
|
448
|
+
importRoleRows,
|
|
449
|
+
fetchAllRoles,
|
|
450
|
+
mapRoleFileToApiPayload,
|
|
451
|
+
mapRoleApiToFileRow
|
|
452
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Post-publish/deploy datasource data sync hook.
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const { resolveSyncPlan, executeSyncPlan } = require('./datasource-sync-policy');
|
|
10
|
+
const { logDatasourceSyncSummary } = require('./datasource-sync-display');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @param {string[]} datasourceKeys
|
|
14
|
+
* @param {Object|null|undefined} payload
|
|
15
|
+
* @returns {string[]}
|
|
16
|
+
*/
|
|
17
|
+
function extractDatasourceKeysFromPayload(payload, datasourceKeys) {
|
|
18
|
+
if (Array.isArray(datasourceKeys) && datasourceKeys.length > 0) {
|
|
19
|
+
return datasourceKeys;
|
|
20
|
+
}
|
|
21
|
+
const fromPayload = Array.isArray(payload?.dataSources)
|
|
22
|
+
? payload.dataSources.map((row) => row && row.key).filter(Boolean)
|
|
23
|
+
: [];
|
|
24
|
+
return fromPayload;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @async
|
|
29
|
+
* @param {Object} params
|
|
30
|
+
* @param {string[]} [params.datasourceKeys]
|
|
31
|
+
* @param {Object} [params.payload]
|
|
32
|
+
* @param {string} params.dataplaneUrl
|
|
33
|
+
* @param {Object} params.authConfig
|
|
34
|
+
* @param {Object} [params.options]
|
|
35
|
+
* @param {string} [params.label]
|
|
36
|
+
* @returns {Promise<Object|null>}
|
|
37
|
+
*/
|
|
38
|
+
async function runPostPublishDataSync(params) {
|
|
39
|
+
const { dataplaneUrl, authConfig, payload, options = {}, label } = params;
|
|
40
|
+
if (!dataplaneUrl || !authConfig || options.dryRun === true || options.skipDataSync === true) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const keys = extractDatasourceKeysFromPayload(payload, params.datasourceKeys);
|
|
45
|
+
if (keys.length === 0) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const plan = await resolveSyncPlan({
|
|
50
|
+
syncExplicit: options.sync === true,
|
|
51
|
+
skipSync: options.skipDataSync === true,
|
|
52
|
+
datasourceKeys: keys,
|
|
53
|
+
dataplaneUrl,
|
|
54
|
+
authConfig
|
|
55
|
+
});
|
|
56
|
+
const result = await executeSyncPlan(plan, dataplaneUrl, authConfig);
|
|
57
|
+
logDatasourceSyncSummary(result, {
|
|
58
|
+
json: options.json === true,
|
|
59
|
+
label,
|
|
60
|
+
syncExplicit: options.sync === true
|
|
61
|
+
});
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
module.exports = {
|
|
66
|
+
runPostPublishDataSync,
|
|
67
|
+
extractDatasourceKeysFromPayload
|
|
68
|
+
};
|
|
@@ -58,7 +58,7 @@ const {
|
|
|
58
58
|
} = require('../utils/infra-optional-service-flags');
|
|
59
59
|
|
|
60
60
|
/** Builder app keys touched by `up-platform --force`. */
|
|
61
|
-
const PLATFORM_APPS = ['keycloak', 'miso-controller', 'dataplane'];
|
|
61
|
+
const PLATFORM_APPS = ['keycloak', 'miso-controller', 'dataplane', 'builder-api'];
|
|
62
62
|
|
|
63
63
|
function formatBackupSuffix() {
|
|
64
64
|
const d = new Date();
|
package/lib/commands/setup.js
CHANGED
|
@@ -291,7 +291,7 @@ async function appendSetupInstallationRecord(payload) {
|
|
|
291
291
|
async function handleSetup(options = {}) {
|
|
292
292
|
const assumeYes = options.yes === true || options.assumeYes === true;
|
|
293
293
|
const startedAt = new Date();
|
|
294
|
-
let outcome
|
|
294
|
+
let outcome;
|
|
295
295
|
let setupMode = null;
|
|
296
296
|
let err = null;
|
|
297
297
|
|
|
@@ -13,12 +13,12 @@ const path = require('path');
|
|
|
13
13
|
const fs = require('fs');
|
|
14
14
|
const chalk = require('chalk');
|
|
15
15
|
const logger = require('../utils/logger');
|
|
16
|
-
const {
|
|
16
|
+
const { resolveExternalSystemPath } = require('../utils/app-path-resolve');
|
|
17
17
|
const { resolveApplicationConfigPath } = require('../utils/app-config-resolver');
|
|
18
18
|
const { loadConfigFile } = require('../utils/config-format');
|
|
19
19
|
const { discoverIntegrationFiles, buildEffectiveDatasourceFiles } = require('./repair-internal');
|
|
20
20
|
const { runDatasourceTestE2E } = require('../datasource/test-e2e');
|
|
21
|
-
const {
|
|
21
|
+
const { cliOptsSkipPublish } = require('../utils/cli-sync-options');
|
|
22
22
|
const { buildMinimalUploadSyncOptions, isQuietMinimalSync } = require('../utils/upload-sync-options');
|
|
23
23
|
const { getConfig } = require('../core/config');
|
|
24
24
|
const { setupIntegrationTestAuth } = require('../external-system/test-auth');
|
|
@@ -90,15 +90,26 @@ function getDatasourceKeys(appPath, configPath, variables, systemKey, systemPars
|
|
|
90
90
|
|
|
91
91
|
/**
|
|
92
92
|
* Publish local integration files to the dataplane before E2E (same path as `aifabrix upload <systemKey>`),
|
|
93
|
-
* unless ``options.
|
|
93
|
+
* unless ``options.noPublish`` is true.
|
|
94
94
|
* @param {string} systemKey
|
|
95
95
|
* @param {Object} options
|
|
96
96
|
* @returns {Promise<{ authConfig: Object, dataplaneUrl: string, environment?: string }|null>}
|
|
97
97
|
*/
|
|
98
98
|
async function syncLocalIfRequested(systemKey, options) {
|
|
99
|
-
if (
|
|
99
|
+
if (cliOptsSkipPublish(options)) return null;
|
|
100
100
|
const { uploadExternalSystem } = require('./upload');
|
|
101
|
-
const uploadOpts =
|
|
101
|
+
const uploadOpts = {
|
|
102
|
+
...buildMinimalUploadSyncOptions(options),
|
|
103
|
+
uploadStatus: options.uploadStatus === 'published' ? 'published' : 'draft',
|
|
104
|
+
pathOptions: {},
|
|
105
|
+
...(options.authConfig && options.dataplaneUrl
|
|
106
|
+
? {
|
|
107
|
+
authConfig: options.authConfig,
|
|
108
|
+
dataplaneUrl: options.dataplaneUrl,
|
|
109
|
+
environment: options.environment
|
|
110
|
+
}
|
|
111
|
+
: {})
|
|
112
|
+
};
|
|
102
113
|
const uploadCtx = await uploadExternalSystem(systemKey, uploadOpts);
|
|
103
114
|
if (uploadCtx?.uploadSkipped !== true && !isQuietMinimalSync(uploadOpts)) {
|
|
104
115
|
logger.log(formatSuccessLine('Sync complete'));
|
|
@@ -117,7 +128,7 @@ async function syncLocalIfRequested(systemKey, options) {
|
|
|
117
128
|
* @param {boolean} [options.debug] - Include debug, write log
|
|
118
129
|
* @param {boolean} [options.verbose] - Verbose output
|
|
119
130
|
* @param {boolean} [options.async] - If false, sync mode (default true)
|
|
120
|
-
* @param {boolean} [options.
|
|
131
|
+
* @param {boolean} [options.noPublish] - When true, skip upload (E2E uses dataplane config already deployed)
|
|
121
132
|
* @returns {Promise<{ success: boolean, results: Array<{ key: string, success: boolean, error?: string }> }>}
|
|
122
133
|
*/
|
|
123
134
|
/**
|
|
@@ -125,11 +136,11 @@ async function syncLocalIfRequested(systemKey, options) {
|
|
|
125
136
|
* @param {string} externalSystem
|
|
126
137
|
* @returns {{ systemKey: string, keys: string[] }}
|
|
127
138
|
*/
|
|
128
|
-
function resolveExternalIntegrationContext(externalSystem) {
|
|
139
|
+
function resolveExternalIntegrationContext(externalSystem, pathOptions = {}) {
|
|
129
140
|
if (!externalSystem || typeof externalSystem !== 'string') {
|
|
130
141
|
throw new Error('External system name is required');
|
|
131
142
|
}
|
|
132
|
-
const appPath =
|
|
143
|
+
const appPath = resolveExternalSystemPath(externalSystem, pathOptions);
|
|
133
144
|
if (!fs.existsSync(appPath)) {
|
|
134
145
|
throw new Error(`Integration path not found: ${appPath}`);
|
|
135
146
|
}
|
|
@@ -199,6 +210,8 @@ async function runTestE2EForExternalSystem(externalSystem, options = {}) {
|
|
|
199
210
|
debug: options.debug,
|
|
200
211
|
verbose: options.verbose,
|
|
201
212
|
async: options.async !== false,
|
|
213
|
+
version: options.version,
|
|
214
|
+
syncMode: options.syncMode,
|
|
202
215
|
authConfig,
|
|
203
216
|
dataplaneUrl,
|
|
204
217
|
quietPollUi: options.quietPollUi === true,
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
-
const {
|
|
9
|
+
const { cliOptsSkipPublish } = require('../utils/cli-sync-options');
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* @param {string[]} [raw]
|
|
@@ -34,7 +34,7 @@ function normalizeTestGovernanceCliOptions(options, cmd) {
|
|
|
34
34
|
env: options.env || 'dev',
|
|
35
35
|
verbose: options.verbose === true || has('-v') || has('--verbose'),
|
|
36
36
|
json: options.json === true || has('--json'),
|
|
37
|
-
|
|
37
|
+
noPublish: cliOptsSkipPublish(options, cmd),
|
|
38
38
|
pack: options.pack,
|
|
39
39
|
app: options.app,
|
|
40
40
|
scenarioIds: collectScenarioIds(options.scenario)
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
'use strict';
|
|
6
6
|
|
|
7
|
-
const {
|
|
7
|
+
const { cliOptsSkipPublish } = require('../utils/cli-sync-options');
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* @param {Object} options - Commander-parsed options
|
|
@@ -19,7 +19,7 @@ function normalizeTestTrustCliOptions(options, cmd) {
|
|
|
19
19
|
debug: options.debug === true || has('-d') || has('--debug'),
|
|
20
20
|
verbose: options.verbose === true || has('-v') || has('--verbose'),
|
|
21
21
|
revalidate: options.revalidate === true || has('--revalidate'),
|
|
22
|
-
|
|
22
|
+
noPublish: cliOptsSkipPublish(options, cmd),
|
|
23
23
|
strict: options.strict === true || has('--strict'),
|
|
24
24
|
summary: options.summary === true || has('--summary'),
|
|
25
25
|
json: options.json === true || has('--json'),
|