@noodleseed/one 0.162.0 → 0.164.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/dist/banner.d.ts +6 -0
- package/dist/banner.d.ts.map +1 -0
- package/dist/banner.js +29 -0
- package/dist/banner.js.map +1 -0
- package/dist/commands/billing-catalog-ops.d.ts +4 -0
- package/dist/commands/billing-catalog-ops.d.ts.map +1 -0
- package/dist/commands/billing-catalog-ops.js +58 -0
- package/dist/commands/billing-catalog-ops.js.map +1 -0
- package/dist/commands/billing-ops.d.ts.map +1 -1
- package/dist/commands/billing-ops.js +3 -0
- package/dist/commands/billing-ops.js.map +1 -1
- package/dist/commands/catalog.d.ts.map +1 -1
- package/dist/commands/catalog.js +2 -0
- package/dist/commands/catalog.js.map +1 -1
- package/dist/commands/config-values.d.ts.map +1 -1
- package/dist/commands/config-values.js +16 -0
- package/dist/commands/config-values.js.map +1 -1
- package/dist/commands/installation-variables.d.ts +26 -0
- package/dist/commands/installation-variables.d.ts.map +1 -0
- package/dist/commands/installation-variables.js +171 -0
- package/dist/commands/installation-variables.js.map +1 -0
- package/dist/commands/project-setup.d.ts.map +1 -1
- package/dist/commands/project-setup.js +2 -0
- package/dist/commands/project-setup.js.map +1 -1
- package/dist/commands/solutions-activity.d.ts +5 -0
- package/dist/commands/solutions-activity.d.ts.map +1 -0
- package/dist/commands/solutions-activity.js +116 -0
- package/dist/commands/solutions-activity.js.map +1 -0
- package/dist/commands/solutions-connections.d.ts +7 -0
- package/dist/commands/solutions-connections.d.ts.map +1 -0
- package/dist/commands/solutions-connections.js +88 -0
- package/dist/commands/solutions-connections.js.map +1 -0
- package/dist/commands/solutions-installation-options.d.ts +5 -0
- package/dist/commands/solutions-installation-options.d.ts.map +1 -0
- package/dist/commands/solutions-installation-options.js +52 -0
- package/dist/commands/solutions-installation-options.js.map +1 -0
- package/dist/commands/solutions-onboarding.d.ts +5 -0
- package/dist/commands/solutions-onboarding.d.ts.map +1 -0
- package/dist/commands/solutions-onboarding.js +113 -0
- package/dist/commands/solutions-onboarding.js.map +1 -0
- package/dist/commands/solutions-ops.d.ts.map +1 -1
- package/dist/commands/solutions-ops.js +278 -17
- package/dist/commands/solutions-ops.js.map +1 -1
- package/dist/first-run.d.ts.map +1 -1
- package/dist/first-run.js +2 -0
- package/dist/first-run.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/node_modules/@noodle-borg/admission-limits/dist/counter-store.d.ts +21 -2
- package/node_modules/@noodle-borg/admission-limits/dist/counter-store.js +10 -1
- package/node_modules/@noodle-borg/admission-limits/dist/in-memory-counter-store.d.ts +5 -1
- package/node_modules/@noodle-borg/admission-limits/dist/in-memory-counter-store.js +31 -2
- package/node_modules/@noodle-borg/admission-limits/dist/portable.d.ts +3 -0
- package/node_modules/@noodle-borg/admission-limits/dist/portable.js +3 -0
- package/node_modules/@noodle-borg/admission-limits/dist/public-admission-assertion.d.ts +28 -0
- package/node_modules/@noodle-borg/admission-limits/dist/public-admission-assertion.js +124 -0
- package/node_modules/@noodle-borg/admission-limits/dist/public-record-admission.d.ts +54 -0
- package/node_modules/@noodle-borg/admission-limits/dist/public-record-admission.js +74 -0
- package/node_modules/@noodle-borg/admission-limits/dist/request-attribution.d.ts +11 -0
- package/node_modules/@noodle-borg/admission-limits/dist/request-attribution.js +19 -0
- package/node_modules/@noodle-borg/agent-kit/dist/curated/error-fixes.js +2 -0
- package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js +5 -5
- package/node_modules/@noodle-borg/agent-kit/dist/generated/surface.js +3 -0
- package/node_modules/@noodle-borg/agent-kit/dist/index.d.ts +1 -0
- package/node_modules/@noodle-borg/agent-kit/dist/index.js +1 -0
- package/node_modules/@noodle-borg/agent-kit/dist/plugin-bootstrap-skill.js +10 -0
- package/node_modules/@noodle-borg/agent-kit/dist/skill-authoring-refs.js +15 -3
- package/node_modules/@noodle-borg/agent-kit/dist/skill-content.js +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/welcome-wordmark.d.ts +3 -0
- package/node_modules/@noodle-borg/agent-kit/dist/welcome-wordmark.js +10 -0
- package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-configuration.d.ts +9 -1
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-configuration.js +33 -2
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-execution-bound.d.ts +3 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-execution-bound.js +29 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-interaction-state.d.ts +5 -3
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-interaction-state.js +21 -10
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-store.d.ts +1 -1
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-store.js +3 -3
- package/node_modules/@noodle-borg/assistant-gateway/dist/portable.d.ts +1 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/portable.js +1 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/session-target.js +5 -4
- package/node_modules/@noodle-borg/assistant-gateway/package.json +1 -1
- package/node_modules/@noodle-borg/authoring/dist/config.d.ts +20 -0
- package/node_modules/@noodle-borg/authoring/dist/config.js +29 -2
- package/node_modules/@noodle-borg/authoring/dist/connectors.d.ts +6 -1
- package/node_modules/@noodle-borg/authoring/dist/connectors.js +5 -0
- package/node_modules/@noodle-borg/authoring/dist/index.d.ts +2 -2
- package/node_modules/@noodle-borg/authoring/dist/json-schema.d.ts +1 -1
- package/node_modules/@noodle-borg/authoring/dist/json-schema.js +15 -2
- package/node_modules/@noodle-borg/authoring/dist/load-authored.js +1 -1
- package/node_modules/@noodle-borg/authoring/dist/managed-collection.d.ts +18 -4
- package/node_modules/@noodle-borg/authoring/dist/managed-collection.js +22 -3
- package/node_modules/@noodle-borg/authoring/dist/platform.d.ts +3 -0
- package/node_modules/@noodle-borg/authoring/dist/platform.js +4 -0
- package/node_modules/@noodle-borg/authoring/dist/server-presentation.js +43 -0
- package/node_modules/@noodle-borg/authoring/dist/server.d.ts +3 -1
- package/node_modules/@noodle-borg/authoring/dist/server.js +4 -44
- package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-billing.js +18 -0
- package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-config.js +31 -4
- package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-solutions.js +778 -0
- package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-tenant-resources.js +0 -241
- package/node_modules/@noodle-borg/cli-catalog/dist/catalog-types.js +7 -0
- package/node_modules/@noodle-borg/cli-catalog/dist/index.js +20 -0
- package/node_modules/@noodle-borg/compiler/dist/artifact/assemble.js +2 -1
- package/node_modules/@noodle-borg/compiler/dist/artifact/catalog-emission.js +3 -1
- package/node_modules/@noodle-borg/compiler/dist/artifact/config.js +3 -0
- package/node_modules/@noodle-borg/compiler/dist/artifact/types.d.ts +17 -1
- package/node_modules/@noodle-borg/compiler/dist/artifact/version.d.ts +6 -1
- package/node_modules/@noodle-borg/compiler/dist/artifact/version.js +6 -1
- package/node_modules/@noodle-borg/compiler/dist/business-variables.d.ts +27 -0
- package/node_modules/@noodle-borg/compiler/dist/business-variables.js +230 -0
- package/node_modules/@noodle-borg/compiler/dist/compile.js +7 -1
- package/node_modules/@noodle-borg/compiler/dist/errors.d.ts +1 -1
- package/node_modules/@noodle-borg/compiler/dist/index.d.ts +3 -0
- package/node_modules/@noodle-borg/compiler/dist/index.js +3 -0
- package/node_modules/@noodle-borg/compiler/dist/managed-collection-controls.d.ts +52 -0
- package/node_modules/@noodle-borg/compiler/dist/managed-collection-controls.js +92 -0
- package/node_modules/@noodle-borg/compiler/dist/managed-collections.d.ts +26 -1
- package/node_modules/@noodle-borg/compiler/dist/managed-collections.js +190 -1
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts +100 -36
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js +2 -0
- package/node_modules/@noodle-borg/compiler/dist/native-record-operations.d.ts +7 -0
- package/node_modules/@noodle-borg/compiler/dist/native-record-operations.js +59 -0
- package/node_modules/@noodle-borg/connector-defs/dist/compile-http.js +83 -8
- package/node_modules/@noodle-borg/connector-defs/dist/schema.d.ts +31 -1
- package/node_modules/@noodle-borg/connector-defs/dist/schema.js +16 -0
- package/node_modules/@noodle-borg/connector-http/dist/http-connector.d.ts +12 -3
- package/node_modules/@noodle-borg/connector-http/dist/http-connector.js +41 -2
- package/node_modules/@noodle-borg/connector-http/dist/http-response.js +3 -2
- package/node_modules/@noodle-borg/connector-http/dist/mcp/config.js +1 -1
- package/node_modules/@noodle-borg/connector-http/dist/url-resolution.js +1 -1
- package/node_modules/@noodle-borg/control-plane/dist/contracts.d.ts +4 -1
- package/node_modules/@noodle-borg/control-plane/dist/deploy-gates.js +1 -0
- package/node_modules/@noodle-borg/control-plane/dist/in-memory-organization-store.d.ts +3 -0
- package/node_modules/@noodle-borg/control-plane/dist/in-memory-organization-store.js +11 -0
- package/node_modules/@noodle-borg/control-plane/dist/organization-agreements.d.ts +45 -0
- package/node_modules/@noodle-borg/control-plane/dist/organization-agreements.js +74 -0
- package/node_modules/@noodle-borg/control-plane/dist/portable.d.ts +1 -0
- package/node_modules/@noodle-borg/control-plane/dist/portable.js +1 -0
- package/node_modules/@noodle-borg/module/dist/contract.d.ts +22 -0
- package/node_modules/@noodle-borg/module/dist/platform-human-identity.d.ts +2 -0
- package/node_modules/@noodle-borg/protocol/dist/request-deps.js +1 -0
- package/node_modules/@noodle-borg/protocol/dist/request-state.d.ts +1 -0
- package/node_modules/@noodle-borg/protocol/dist/request-state.js +11 -2
- package/node_modules/@noodle-borg/protocol/dist/sdk-server.d.ts +2 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/input-required.js +2 -1
- package/node_modules/@noodle-borg/protocol/dist/v2/server.js +2 -1
- package/node_modules/@noodle-borg/runtime/dist/ambient-context.js +6 -1
- package/node_modules/@noodle-borg/runtime/dist/broker/types.d.ts +2 -0
- package/node_modules/@noodle-borg/runtime/dist/business-variables.d.ts +15 -0
- package/node_modules/@noodle-borg/runtime/dist/business-variables.js +75 -0
- package/node_modules/@noodle-borg/runtime/dist/confirmation-continuation.js +2 -1
- package/node_modules/@noodle-borg/runtime/dist/confirmation.js +23 -3
- package/node_modules/@noodle-borg/runtime/dist/connector/types.d.ts +17 -1
- package/node_modules/@noodle-borg/runtime/dist/connector-snapshot.js +6 -0
- package/node_modules/@noodle-borg/runtime/dist/execute.d.ts +18 -3
- package/node_modules/@noodle-borg/runtime/dist/execute.js +13 -3
- package/node_modules/@noodle-borg/runtime/dist/index.d.ts +2 -0
- package/node_modules/@noodle-borg/runtime/dist/index.js +1 -0
- package/node_modules/@noodle-borg/runtime/dist/interactive.js +11 -0
- package/node_modules/@noodle-borg/runtime/dist/managed-origins.d.ts +3 -1
- package/node_modules/@noodle-borg/runtime/dist/managed-origins.js +32 -7
- package/node_modules/@noodle-borg/runtime/dist/operation-credential.js +6 -0
- package/node_modules/@noodle-borg/runtime/dist/operation-evidence.d.ts +30 -0
- package/node_modules/@noodle-borg/runtime/dist/operation-evidence.js +68 -0
- package/node_modules/@noodle-borg/runtime/dist/operation-execution.d.ts +2 -2
- package/node_modules/@noodle-borg/runtime/dist/operation-execution.js +142 -71
- package/node_modules/@noodle-borg/runtime/dist/result.d.ts +6 -4
- package/node_modules/@noodle-borg/runtime/dist/tool-dispatch.d.ts +7 -0
- package/node_modules/@noodle-borg/runtime/dist/tool-dispatch.js +48 -4
- package/node_modules/@noodle-borg/service/dist/admission.js +2 -1
- package/node_modules/@noodle-borg/service/dist/application-activity.js +236 -0
- package/node_modules/@noodle-borg/service/dist/application-business-notice.js +28 -0
- package/node_modules/@noodle-borg/service/dist/application-runtime-target.js +141 -0
- package/node_modules/@noodle-borg/service/dist/application-settings-targets.js +72 -0
- package/node_modules/@noodle-borg/service/dist/application-settings.js +210 -0
- package/node_modules/@noodle-borg/service/dist/business-api-admission.js +121 -0
- package/node_modules/@noodle-borg/service/dist/business-information/activity-pagination.js +73 -0
- package/node_modules/@noodle-borg/service/dist/business-information/business-notice.d.ts +24 -0
- package/node_modules/@noodle-borg/service/dist/business-information/business-notice.js +18 -0
- package/node_modules/@noodle-borg/service/dist/business-information/collection-controls.js +51 -0
- package/node_modules/@noodle-borg/service/dist/business-information/contracts.d.ts +439 -0
- package/node_modules/@noodle-borg/service/dist/business-information/definition-resolver.js +94 -0
- package/node_modules/@noodle-borg/service/dist/business-information/in-memory-installation-lifecycle.js +136 -0
- package/node_modules/@noodle-borg/service/dist/business-information/in-memory-invitations.js +160 -0
- package/node_modules/@noodle-borg/service/dist/business-information/in-memory-locks.js +23 -0
- package/node_modules/@noodle-borg/service/dist/business-information/in-memory-store.js +287 -132
- package/node_modules/@noodle-borg/service/dist/business-information/installation-capacity.js +10 -0
- package/node_modules/@noodle-borg/service/dist/business-information/invitations.js +68 -0
- package/node_modules/@noodle-borg/service/dist/business-information/legacy-request-migration.js +60 -0
- package/node_modules/@noodle-borg/service/dist/business-information/managed-releases.js +245 -0
- package/node_modules/@noodle-borg/service/dist/business-information/managed-solution-blueprints.js +51 -0
- package/node_modules/@noodle-borg/service/dist/business-information/managed-solution-executable.js +76 -0
- package/node_modules/@noodle-borg/service/dist/business-information/model.js +124 -23
- package/node_modules/@noodle-borg/service/dist/business-information/native-query.js +162 -0
- package/node_modules/@noodle-borg/service/dist/business-information/native-storage-budget.js +60 -0
- package/node_modules/@noodle-borg/service/dist/business-information/pagination.js +28 -0
- package/node_modules/@noodle-borg/service/dist/business-information/portable.js +9 -0
- package/node_modules/@noodle-borg/service/dist/business-information/principal-authority.d.ts +11 -0
- package/node_modules/@noodle-borg/service/dist/business-information/principal-authority.js +42 -0
- package/node_modules/@noodle-borg/service/dist/business-information/profiles.js +137 -6
- package/node_modules/@noodle-borg/service/dist/business-information/reader-floor.js +26 -0
- package/node_modules/@noodle-borg/service/dist/business-information/source-credential-fence.js +79 -0
- package/node_modules/@noodle-borg/service/dist/business-information/source-custody-budget.js +30 -0
- package/node_modules/@noodle-borg/service/dist/business-information/source-custody-memory.js +122 -0
- package/node_modules/@noodle-borg/service/dist/business-information/source-executor.js +191 -0
- package/node_modules/@noodle-borg/service/dist/business-information/source-ingestion-contracts.js +2 -0
- package/node_modules/@noodle-borg/service/dist/business-information/source-ingestion-coordinator.js +136 -0
- package/node_modules/@noodle-borg/service/dist/business-information/source-ingestion-failures.js +32 -0
- package/node_modules/@noodle-borg/service/dist/business-information/source-ingestion-memory-state.js +154 -0
- package/node_modules/@noodle-borg/service/dist/business-information/source-ingestion-memory-store.js +568 -0
- package/node_modules/@noodle-borg/service/dist/business-information/source-ingestion-memory-types.js +26 -0
- package/node_modules/@noodle-borg/service/dist/business-information/source-ingestion-memory-values.js +59 -0
- package/node_modules/@noodle-borg/service/dist/business-information/source-ingestion-pagination.js +54 -0
- package/node_modules/@noodle-borg/service/dist/business-information/source-ingestion-validation.js +163 -0
- package/node_modules/@noodle-borg/service/dist/business-information/source-refresh-retention.js +29 -0
- package/node_modules/@noodle-borg/service/dist/business-information-runtime.js +80 -0
- package/node_modules/@noodle-borg/service/dist/business-onboarding.js +73 -0
- package/node_modules/@noodle-borg/service/dist/connections/types.js +8 -0
- package/node_modules/@noodle-borg/service/dist/credential-binding-index.js +38 -33
- package/node_modules/@noodle-borg/service/dist/deployment-execution.js +275 -0
- package/node_modules/@noodle-borg/service/dist/external-credential-binding-broker.js +19 -1
- package/node_modules/@noodle-borg/service/dist/external-credential-exchange.d.ts +16 -1
- package/node_modules/@noodle-borg/service/dist/modules/host.js +4 -1
- package/node_modules/@noodle-borg/service/dist/native-record-connector.d.ts +20 -0
- package/node_modules/@noodle-borg/service/dist/native-record-connector.js +206 -0
- package/node_modules/@noodle-borg/service/dist/oauth/store.d.ts +3 -0
- package/node_modules/@noodle-borg/service/dist/operation-evidence.js +89 -0
- package/node_modules/@noodle-borg/service/dist/recovery-quarantine.js +49 -0
- package/node_modules/@noodle-borg/service/dist/registry-compile.js +60 -11
- package/node_modules/@noodle-borg/service/dist/registry-deploy-transaction.js +18 -0
- package/node_modules/@noodle-borg/service/dist/registry-rollback.js +2 -1
- package/node_modules/@noodle-borg/service/dist/registry-state.d.ts +1 -1
- package/node_modules/@noodle-borg/service/dist/registry-state.js +6 -3
- package/node_modules/@noodle-borg/service/dist/registry-targets.js +49 -0
- package/node_modules/@noodle-borg/service/dist/registry-types.d.ts +2 -0
- package/node_modules/@noodle-borg/service/dist/registry.d.ts +15 -3
- package/node_modules/@noodle-borg/service/dist/registry.js +177 -137
- package/node_modules/@noodle-borg/service/dist/routes/assistant-appearance.js +3 -2
- package/node_modules/@noodle-borg/service/dist/routes/assistant-clients.js +2 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant-doctor.js +2 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant-embeds.js +8 -3
- package/node_modules/@noodle-borg/service/dist/routes/assistant-interaction-replay.js +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant-interactions.js +48 -36
- package/node_modules/@noodle-borg/service/dist/routes/assistant-public-configuration.js +3 -2
- package/node_modules/@noodle-borg/service/dist/routes/assistant-public-session.js +10 -10
- package/node_modules/@noodle-borg/service/dist/routes/assistant-session-target.js +32 -3
- package/node_modules/@noodle-borg/service/dist/routes/assistant-suggestions.js +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant-transcript.js +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant.js +10 -10
- package/node_modules/@noodle-borg/service/dist/routes/business-information-activity.js +83 -0
- package/node_modules/@noodle-borg/service/dist/routes/business-information-admission.js +26 -0
- package/node_modules/@noodle-borg/service/dist/routes/business-information-channels.js +153 -0
- package/node_modules/@noodle-borg/service/dist/routes/business-information-connections.js +107 -0
- package/node_modules/@noodle-borg/service/dist/routes/business-information-dispatch.js +87 -4
- package/node_modules/@noodle-borg/service/dist/routes/business-information-external.js +79 -0
- package/node_modules/@noodle-borg/service/dist/routes/business-information-installation.js +24 -0
- package/node_modules/@noodle-borg/service/dist/routes/business-information-notice.js +69 -0
- package/node_modules/@noodle-borg/service/dist/routes/business-information-onboarding.js +58 -0
- package/node_modules/@noodle-borg/service/dist/routes/business-information-paths.js +76 -0
- package/node_modules/@noodle-borg/service/dist/routes/business-information-public.js +151 -0
- package/node_modules/@noodle-borg/service/dist/routes/business-information-reader-floor.js +15 -0
- package/node_modules/@noodle-borg/service/dist/routes/business-information-record-create.js +29 -0
- package/node_modules/@noodle-borg/service/dist/routes/business-information-record-reads.js +36 -0
- package/node_modules/@noodle-borg/service/dist/routes/business-information-request.js +64 -0
- package/node_modules/@noodle-borg/service/dist/routes/business-information-settings.js +64 -0
- package/node_modules/@noodle-borg/service/dist/routes/business-information-source.js +249 -0
- package/node_modules/@noodle-borg/service/dist/routes/business-information-staff.js +258 -0
- package/node_modules/@noodle-borg/service/dist/routes/business-information-wire.js +226 -26
- package/node_modules/@noodle-borg/service/dist/routes/business-information.js +238 -197
- package/node_modules/@noodle-borg/service/dist/routes/config-values-dispatch.js +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/config-values.js +26 -4
- package/node_modules/@noodle-borg/service/dist/routes/control-plane.js +33 -234
- package/node_modules/@noodle-borg/service/dist/routes/deployment-activation-response.js +13 -4
- package/node_modules/@noodle-borg/service/dist/service-resource-cleanup.js +4 -0
- package/node_modules/@noodle-borg/service/dist/service.js +57 -11
- package/node_modules/@noodle-borg/service/dist/solution-installation-activation.js +149 -0
- package/node_modules/@noodle-borg/service/dist/source-configuration-authority.js +94 -0
- package/node_modules/@noodle-borg/service/dist/state-catalog.js +6 -5
- package/node_modules/@noodle-borg/service/dist/store/config-values.d.ts +42 -17
- package/node_modules/@noodle-borg/service/dist/store/config-values.js +123 -24
- package/node_modules/@noodle-borg/service/dist/store/in-memory.d.ts +1 -0
- package/node_modules/@noodle-borg/service/dist/store/in-memory.js +3 -0
- package/node_modules/@noodle-borg/service/dist/store/json-file.d.ts +1 -0
- package/node_modules/@noodle-borg/service/dist/store/json-file.js +3 -0
- package/node_modules/@noodle-borg/service/dist/store.d.ts +3 -1
- package/node_modules/@noodle-borg/service/package.json +2 -2
- package/node_modules/@noodle-borg/transport-http/dist/serve-request.js +9 -0
- package/node_modules/@noodle-borg/transport-http/package.json +1 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/application-activity.d.ts +143 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/application-activity.js +90 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/application-channels.d.ts +130 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/application-channels.js +77 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/application-connections.d.ts +105 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/application-connections.js +67 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/application-onboarding.d.ts +27 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/application-onboarding.js +28 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/application-settings.d.ts +112 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/application-settings.js +88 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/assistant.d.ts +1 -1
- package/node_modules/@noodle-borg/wire-contracts/dist/billing-catalog.d.ts +62 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/billing-catalog.js +57 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/billing-enforcement.d.ts +12 -12
- package/node_modules/@noodle-borg/wire-contracts/dist/billing-metering.d.ts +4 -4
- package/node_modules/@noodle-borg/wire-contracts/dist/billing-org-transfer.d.ts +3 -3
- package/node_modules/@noodle-borg/wire-contracts/dist/business-information-query.d.ts +25 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/business-information-query.js +37 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/business-information.d.ts +1816 -158
- package/node_modules/@noodle-borg/wire-contracts/dist/business-information.js +416 -41
- package/node_modules/@noodle-borg/wire-contracts/dist/control-plane.d.ts +2 -2
- package/node_modules/@noodle-borg/wire-contracts/dist/distribution.d.ts +5 -5
- package/node_modules/@noodle-borg/wire-contracts/dist/index.d.ts +8 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/index.js +8 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/knowledge.d.ts +3 -3
- package/node_modules/@noodle-borg/wire-contracts/dist/managed-assistant-sponsorship.d.ts +7 -7
- package/node_modules/@noodle-borg/wire-contracts/dist/platform-account-reset.d.ts +5 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/platform-account-reset.js +1 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/platform-auth.d.ts +66 -66
- package/node_modules/@noodle-borg/wire-contracts/dist/solution-onboarding.d.ts +143 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/solution-onboarding.js +94 -0
- package/node_modules/@noodleseed/assistant/README.md +5 -0
- package/node_modules/@noodleseed/assistant/package.json +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { cspFaultsInManifest } from '@noodle-borg/compiler';
|
|
2
|
+
import { noopLogger } from '@noodle-borg/transport-http';
|
|
3
|
+
import { BUSINESS_SETUP_MESSAGE, BusinessOnboarding } from './business-onboarding.js';
|
|
4
|
+
import { manifestUsesUserRoot } from './registry-access.js';
|
|
5
|
+
import { isIdentityAccessMode } from './routes/access-mode.js';
|
|
6
|
+
import { provisionPublicEmbed } from './routes/deploy-public-embed.js';
|
|
7
|
+
import { deploymentActivationRejection } from './routes/deployment-activation-response.js';
|
|
8
|
+
/** Shared post-authorization deploy flow. Both API deploys and installations retain registry activation hooks. */
|
|
9
|
+
export async function executeAuthorizedDeployment(input, dependencies) {
|
|
10
|
+
const { tenant, manifest, connectors, accessMode, identity, ownerSubject, orgMembershipSources, deploymentSource, serverVersion, automationId, } = input;
|
|
11
|
+
let hostedAssets = input.hostedAssets;
|
|
12
|
+
const idempotency = { key: input.idempotencyKey };
|
|
13
|
+
const { registry, options, controlPlane, audit } = dependencies;
|
|
14
|
+
if (options.businessOnboarding && options.businessInformationStore) {
|
|
15
|
+
const onboarding = new BusinessOnboarding(options.businessOnboarding, controlPlane, options.businessInformationStore);
|
|
16
|
+
for (const installation of await options.businessInformationStore.listInstallations(tenant.org)) {
|
|
17
|
+
if (installation.scope.app === tenant.app &&
|
|
18
|
+
installation.scope.env === tenant.env &&
|
|
19
|
+
!(await onboarding.ready(installation)))
|
|
20
|
+
return reject(409, { code: 'business_setup_required', error: BUSINESS_SETUP_MESSAGE });
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (input.assetSourceScope !== undefined && input.assetSourceScope.org !== tenant.org)
|
|
24
|
+
return reject(403, {
|
|
25
|
+
code: 'asset_source_forbidden',
|
|
26
|
+
error: 'Asset source must belong to the authorized installation organization.',
|
|
27
|
+
});
|
|
28
|
+
const assetScope = input.assetSourceScope ?? tenant;
|
|
29
|
+
if ((await registry.getAppArchivedAt(tenant.org, tenant.app)) !== undefined) {
|
|
30
|
+
await audit.emit({
|
|
31
|
+
eventType: 'deploy.rejected',
|
|
32
|
+
...tenant,
|
|
33
|
+
decision: 'deny',
|
|
34
|
+
status: 409,
|
|
35
|
+
reasonCode: 'app_archived',
|
|
36
|
+
...(identity?.subject === undefined ? {} : { actorSubject: identity.subject }),
|
|
37
|
+
});
|
|
38
|
+
return reject(409, {
|
|
39
|
+
error: 'app is archived; restore it before deploying',
|
|
40
|
+
code: 'app_archived',
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
// Identity access modes bind the data plane to verified identity, so the deployer must be authenticated.
|
|
44
|
+
// (Localhost dev runs the gate open; such deploys are rejected for lack of an owner/audit actor.)
|
|
45
|
+
if (isIdentityAccessMode(accessMode) && !identity) {
|
|
46
|
+
return reject(401, {
|
|
47
|
+
error: `${accessMode} deployments require an authenticated deployer`,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
if (accessMode === 'public' && manifestUsesUserRoot(manifest)) {
|
|
51
|
+
return reject(400, {
|
|
52
|
+
error: 'public access mode cannot reference ${user}; use mixed for optional identity',
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
// Widget CSP gate (deploy-only): a CSP origin the host renderer will silently drop breaks the widget
|
|
56
|
+
// for end users, so the deploy is refused here. The compiler surfaces the same faults as non-blocking
|
|
57
|
+
// warnings, so `noodle dev`/`validate` still render the widget locally — only shipping is gated.
|
|
58
|
+
const [cspFault] = cspFaultsInManifest(manifest);
|
|
59
|
+
if (cspFault !== undefined) {
|
|
60
|
+
return reject(400, {
|
|
61
|
+
error: `widget "${cspFault.widget}" CSP ${cspFault.list} origin "${cspFault.value}" is not an ` +
|
|
62
|
+
`absolute https:// origin and would be dropped by the host renderer` +
|
|
63
|
+
(cspFault.suggestion !== undefined ? `; use "${cspFault.suggestion}"` : ''),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
if ((await controlPlane.getOrg(tenant.org)) === undefined) {
|
|
67
|
+
await audit.emit({
|
|
68
|
+
eventType: 'deploy.rejected',
|
|
69
|
+
org: tenant.org,
|
|
70
|
+
app: tenant.app,
|
|
71
|
+
env: tenant.env,
|
|
72
|
+
decision: 'deny',
|
|
73
|
+
status: 404,
|
|
74
|
+
reasonCode: 'organization_not_found',
|
|
75
|
+
...(identity?.subject !== undefined ? { actorSubject: identity.subject } : {}),
|
|
76
|
+
...(identity?.email !== undefined ? { actorEmail: identity.email } : {}),
|
|
77
|
+
});
|
|
78
|
+
return reject(404, {
|
|
79
|
+
code: 'organization_not_found',
|
|
80
|
+
error: 'organization must be created before deploy',
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
const logger = options.logger ?? noopLogger;
|
|
84
|
+
if (hostedAssets !== undefined && hostedAssets.length > 0) {
|
|
85
|
+
if (options.assetStore === undefined) {
|
|
86
|
+
await audit.emit({
|
|
87
|
+
eventType: 'asset.rejected',
|
|
88
|
+
org: tenant.org,
|
|
89
|
+
app: tenant.app,
|
|
90
|
+
env: tenant.env,
|
|
91
|
+
decision: 'deny',
|
|
92
|
+
status: 400,
|
|
93
|
+
reasonCode: 'asset_store_not_configured',
|
|
94
|
+
...(identity?.subject !== undefined ? { actorSubject: identity.subject } : {}),
|
|
95
|
+
...(identity?.email !== undefined ? { actorEmail: identity.email } : {}),
|
|
96
|
+
details: { assetCount: hostedAssets.length },
|
|
97
|
+
});
|
|
98
|
+
return reject(400, { error: 'hosted assets are not configured for this service' });
|
|
99
|
+
}
|
|
100
|
+
const verified = await options.assetStore.verifyUploadedAssets({
|
|
101
|
+
scope: assetScope,
|
|
102
|
+
assets: hostedAssets,
|
|
103
|
+
});
|
|
104
|
+
if (!verified.ok) {
|
|
105
|
+
await audit.emit({
|
|
106
|
+
eventType: 'asset.rejected',
|
|
107
|
+
org: tenant.org,
|
|
108
|
+
app: tenant.app,
|
|
109
|
+
env: tenant.env,
|
|
110
|
+
decision: 'deny',
|
|
111
|
+
status: 400,
|
|
112
|
+
reasonCode: 'asset_verification_failed',
|
|
113
|
+
...(identity?.subject !== undefined ? { actorSubject: identity.subject } : {}),
|
|
114
|
+
...(identity?.email !== undefined ? { actorEmail: identity.email } : {}),
|
|
115
|
+
details: { assetCount: hostedAssets.length },
|
|
116
|
+
});
|
|
117
|
+
return reject(400, { error: verified.error });
|
|
118
|
+
}
|
|
119
|
+
hostedAssets = verified.assets;
|
|
120
|
+
}
|
|
121
|
+
let result;
|
|
122
|
+
try {
|
|
123
|
+
result = await registry.deploy(tenant, manifest, {
|
|
124
|
+
connectors,
|
|
125
|
+
actor: identity || undefined,
|
|
126
|
+
accessMode,
|
|
127
|
+
ownerSubject,
|
|
128
|
+
...(orgMembershipSources !== undefined ? { orgMembershipSources } : {}),
|
|
129
|
+
hostedAssets,
|
|
130
|
+
serverVersion,
|
|
131
|
+
deploymentSource: automationId === undefined ? (deploymentSource ?? 'api') : 'github',
|
|
132
|
+
...(idempotency.key !== undefined ? { idempotencyKey: idempotency.key } : {}),
|
|
133
|
+
...(automationId === undefined ? {} : { automationId }),
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
const rejected = await deploymentActivationRejection(error, {
|
|
138
|
+
audit,
|
|
139
|
+
eventType: 'deploy.rejected',
|
|
140
|
+
org: tenant.org,
|
|
141
|
+
app: tenant.app,
|
|
142
|
+
env: tenant.env,
|
|
143
|
+
...(identity?.subject !== undefined ? { actorSubject: identity.subject } : {}),
|
|
144
|
+
...(identity?.email !== undefined ? { actorEmail: identity.email } : {}),
|
|
145
|
+
});
|
|
146
|
+
if (rejected !== undefined)
|
|
147
|
+
return reject(rejected.status, rejected.body);
|
|
148
|
+
throw error;
|
|
149
|
+
}
|
|
150
|
+
if (!result.ok) {
|
|
151
|
+
if ('conflict' in result) {
|
|
152
|
+
if (result.code === 'deployment_locked') {
|
|
153
|
+
await audit.emit({
|
|
154
|
+
eventType: 'deploy.rejected',
|
|
155
|
+
org: tenant.org,
|
|
156
|
+
app: tenant.app,
|
|
157
|
+
env: tenant.env,
|
|
158
|
+
decision: 'deny',
|
|
159
|
+
status: 409,
|
|
160
|
+
reasonCode: result.code,
|
|
161
|
+
...(identity?.subject !== undefined ? { actorSubject: identity.subject } : {}),
|
|
162
|
+
...(identity?.email !== undefined ? { actorEmail: identity.email } : {}),
|
|
163
|
+
details: { serverVersion },
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
return reject(409, {
|
|
167
|
+
ok: false,
|
|
168
|
+
code: result.code,
|
|
169
|
+
error: result.message,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
if ('superseded' in result) {
|
|
173
|
+
if (automationId !== undefined) {
|
|
174
|
+
await options.deploymentAutomation
|
|
175
|
+
?.recordSuperseded?.({ automationId, target: tenant })
|
|
176
|
+
.catch(() => undefined);
|
|
177
|
+
}
|
|
178
|
+
return reject(409, {
|
|
179
|
+
ok: false,
|
|
180
|
+
code: 'run_superseded',
|
|
181
|
+
error: 'a newer GitHub deploy run exists for this app/env; this run was not activated',
|
|
182
|
+
deploymentId: result.deploymentId,
|
|
183
|
+
...(result.serverVersion !== undefined ? { serverVersion: result.serverVersion } : {}),
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
// Codes are safe enum strings; never a path-with-value. No secret name or value is logged.
|
|
187
|
+
const codes = result.errors.map((error) => error.code).join(',');
|
|
188
|
+
logger.warn('deploy.rejected', {
|
|
189
|
+
status: 400,
|
|
190
|
+
errorCount: result.errors.length,
|
|
191
|
+
codes,
|
|
192
|
+
});
|
|
193
|
+
// Durable audit: a rejected deploy is a governance event. Safe fields only — no manifest body.
|
|
194
|
+
await audit.emit({
|
|
195
|
+
eventType: 'deploy.rejected',
|
|
196
|
+
org: tenant.org,
|
|
197
|
+
app: tenant.app,
|
|
198
|
+
env: tenant.env,
|
|
199
|
+
decision: 'deny',
|
|
200
|
+
status: 400,
|
|
201
|
+
reasonCode: 'compile_failed',
|
|
202
|
+
...(identity?.subject !== undefined ? { actorSubject: identity.subject } : {}),
|
|
203
|
+
...(identity?.email !== undefined ? { actorEmail: identity.email } : {}),
|
|
204
|
+
details: { errorCount: result.errors.length, codes },
|
|
205
|
+
});
|
|
206
|
+
return reject(400, { ok: false, errors: result.errors });
|
|
207
|
+
}
|
|
208
|
+
// Counts only — never secret names or values.
|
|
209
|
+
logger.info('deploy.ok', {
|
|
210
|
+
deploymentId: result.deploymentId,
|
|
211
|
+
serverVersion: result.serverVersion,
|
|
212
|
+
org: tenant.org,
|
|
213
|
+
app: tenant.app,
|
|
214
|
+
env: tenant.env,
|
|
215
|
+
hasConnectors: connectors !== undefined,
|
|
216
|
+
});
|
|
217
|
+
await audit.emit({
|
|
218
|
+
eventType: 'deploy.accepted',
|
|
219
|
+
org: tenant.org,
|
|
220
|
+
app: tenant.app,
|
|
221
|
+
env: tenant.env,
|
|
222
|
+
decision: 'allow',
|
|
223
|
+
status: 201,
|
|
224
|
+
...(result.deploymentId !== undefined ? { deploymentId: result.deploymentId } : {}),
|
|
225
|
+
...(identity?.subject !== undefined ? { actorSubject: identity.subject } : {}),
|
|
226
|
+
...(identity?.email !== undefined ? { actorEmail: identity.email } : {}),
|
|
227
|
+
details: {
|
|
228
|
+
accessMode: result.accessMode ?? accessMode,
|
|
229
|
+
deploymentSource: automationId === undefined ? (deploymentSource ?? 'api') : 'github',
|
|
230
|
+
...(ownerSubject !== undefined ? { ownerSubject } : {}),
|
|
231
|
+
serverVersion: result.serverVersion,
|
|
232
|
+
hasConnectors: connectors !== undefined,
|
|
233
|
+
},
|
|
234
|
+
});
|
|
235
|
+
// Tenant-safe developer-facing log (M3, ADR 0101): a safe deploy-lifecycle record the developer can read
|
|
236
|
+
// via `noodle logs`. Only scalar metadata, no manifest/secret/payload material.
|
|
237
|
+
await options.userAppLogStore?.emit({
|
|
238
|
+
level: 'info',
|
|
239
|
+
message: 'deployment live',
|
|
240
|
+
org: tenant.org,
|
|
241
|
+
app: tenant.app,
|
|
242
|
+
env: tenant.env,
|
|
243
|
+
...(result.deploymentId !== undefined ? { deploymentId: result.deploymentId } : {}),
|
|
244
|
+
details: { accessMode: result.accessMode ?? accessMode, serverVersion: result.serverVersion },
|
|
245
|
+
});
|
|
246
|
+
if (result.ok && hostedAssets !== undefined && hostedAssets.length > 0) {
|
|
247
|
+
await audit.emit({
|
|
248
|
+
eventType: 'asset.activation.accepted',
|
|
249
|
+
org: tenant.org,
|
|
250
|
+
app: tenant.app,
|
|
251
|
+
env: tenant.env,
|
|
252
|
+
decision: 'allow',
|
|
253
|
+
status: 201,
|
|
254
|
+
deploymentId: result.deploymentId,
|
|
255
|
+
...(identity?.subject !== undefined ? { actorSubject: identity.subject } : {}),
|
|
256
|
+
...(identity?.email !== undefined ? { actorEmail: identity.email } : {}),
|
|
257
|
+
details: {
|
|
258
|
+
assetCount: hostedAssets.length,
|
|
259
|
+
totalBytes: hostedAssets.reduce((sum, asset) => sum + asset.byteLength, 0),
|
|
260
|
+
},
|
|
261
|
+
});
|
|
262
|
+
await options.assetStore?.recordReachability({
|
|
263
|
+
scope: assetScope,
|
|
264
|
+
deploymentId: result.deploymentId,
|
|
265
|
+
deploymentVersion: result.deploymentVersion,
|
|
266
|
+
assets: hostedAssets,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
const embedId = await provisionPublicEmbed(registry, options, tenant, result.deploymentId);
|
|
270
|
+
return { ok: true, result, ...(embedId === undefined ? {} : { embedId }) };
|
|
271
|
+
}
|
|
272
|
+
function reject(status, body) {
|
|
273
|
+
return { ok: false, status, body };
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=deployment-execution.js.map
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { externalCredentialExchangeResponseSchema } from '@noodle-borg/external-credential-provider';
|
|
1
2
|
import { CredentialUnavailableError, MapServiceBroker, } from '@noodle-borg/runtime';
|
|
2
3
|
import { routeBoundCredentialKey } from './credential-route-key.js';
|
|
3
4
|
import { exchangeExternalCredential, resolveExternalCredentialProviderConfig, } from './external-credential-exchange.js';
|
|
@@ -17,6 +18,23 @@ export class ExternalCredentialBindingBroker {
|
|
|
17
18
|
request.deploymentId !== this.options.deployment) {
|
|
18
19
|
throw new CredentialUnavailableError('credential_not_configured');
|
|
19
20
|
}
|
|
21
|
+
if ('localProvider' in this.options) {
|
|
22
|
+
try {
|
|
23
|
+
const value = externalCredentialExchangeResponseSchema.parse(await this.options.localProvider.getCredential({
|
|
24
|
+
tenantId: this.options.tenant,
|
|
25
|
+
deploymentId: this.options.deployment,
|
|
26
|
+
descriptor: allowed.descriptor,
|
|
27
|
+
...(request.expectedConnectionGeneration === undefined
|
|
28
|
+
? {}
|
|
29
|
+
: { expectedConnectionGeneration: request.expectedConnectionGeneration }),
|
|
30
|
+
}));
|
|
31
|
+
return { token: value.access_token };
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
throw new CredentialUnavailableError('credential_exchange_failed');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const options = this.options;
|
|
20
38
|
const pinOrVerify = resolveSubjectPinCallable(this.options.subjectPins);
|
|
21
39
|
if (pinOrVerify === undefined) {
|
|
22
40
|
throw new CredentialUnavailableError('credential_not_configured');
|
|
@@ -57,7 +75,7 @@ export class ExternalCredentialBindingBroker {
|
|
|
57
75
|
let exchanged;
|
|
58
76
|
try {
|
|
59
77
|
exchanged = await exchangeExternalCredential({
|
|
60
|
-
options
|
|
78
|
+
options,
|
|
61
79
|
descriptor: allowed.descriptor,
|
|
62
80
|
config,
|
|
63
81
|
nowMs: this.now(),
|
|
@@ -69,7 +69,22 @@ export interface ExternalCredentialExchangeOptions {
|
|
|
69
69
|
readonly dnsLookup?: DnsLookup;
|
|
70
70
|
readonly timeoutSignal?: (timeoutMs: number) => AbortSignal;
|
|
71
71
|
}
|
|
72
|
-
|
|
72
|
+
/** In-process portable authority; the same compiled binding is still enforced by ManagedConfigBroker. */
|
|
73
|
+
export interface LocalExternalCredentialProvider {
|
|
74
|
+
getCredential(input: {
|
|
75
|
+
readonly tenantId: string;
|
|
76
|
+
readonly deploymentId: string;
|
|
77
|
+
readonly descriptor: CredentialBindingDescriptor;
|
|
78
|
+
readonly expectedConnectionGeneration?: string;
|
|
79
|
+
}): Promise<ExternalCredentialExchangeResponse>;
|
|
80
|
+
}
|
|
81
|
+
export interface LocalExternalCredentialExchangeOptions {
|
|
82
|
+
readonly tenant: string;
|
|
83
|
+
readonly deployment: string;
|
|
84
|
+
readonly localProvider: LocalExternalCredentialProvider;
|
|
85
|
+
}
|
|
86
|
+
export type BoundExternalCredentialExchangeOptions = ExternalCredentialExchangeOptions | LocalExternalCredentialExchangeOptions;
|
|
87
|
+
export type ExternalCredentialExchangeRuntimeOptions = Pick<ExternalCredentialExchangeOptions, 'issuer' | 'signer' | 'providers' | 'subjectPins'> | Pick<LocalExternalCredentialExchangeOptions, 'localProvider'>;
|
|
73
88
|
export declare function resolveExternalCredentialProviderConfig(options: ExternalCredentialExchangeOptions, descriptor: CredentialBindingDescriptor): Promise<ExternalCredentialProviderConfig | undefined>;
|
|
74
89
|
export declare function exchangeExternalCredential(input: {
|
|
75
90
|
readonly options: ExternalCredentialExchangeOptions;
|
|
@@ -13,6 +13,7 @@ export class ModuleHost {
|
|
|
13
13
|
toolDispatch;
|
|
14
14
|
deploymentActivation;
|
|
15
15
|
organizationProvisioning;
|
|
16
|
+
resolveActivityHistoryAllowance;
|
|
16
17
|
admissionGate;
|
|
17
18
|
moduleCapabilities;
|
|
18
19
|
moduleCapabilityDetails;
|
|
@@ -32,6 +33,7 @@ export class ModuleHost {
|
|
|
32
33
|
this.toolDispatch = toolDispatchFor(modules, options.toolDispatch);
|
|
33
34
|
this.deploymentActivation = collectDeploymentActivation(modules);
|
|
34
35
|
this.organizationProvisioning = singleContribution(modules, 'organizationProvisioning');
|
|
36
|
+
this.resolveActivityHistoryAllowance = singleContribution(modules, 'resolveActivityHistoryAllowance');
|
|
35
37
|
if (this.deploymentAutomation !== undefined &&
|
|
36
38
|
!this.deploymentActivation.some((hook) => hook.phase === DEPLOYMENT_ACTIVATION_PHASE.AUTOMATION_FRESHNESS)) {
|
|
37
39
|
throw new Error('deployment automation requires an automation-freshness activation hook');
|
|
@@ -125,7 +127,8 @@ function deriveModuleCapabilities(modules) {
|
|
|
125
127
|
contributions.toolDispatch !== undefined ||
|
|
126
128
|
contributions.deploymentActivation !== undefined ||
|
|
127
129
|
contributions.organizationProvisioning !== undefined ||
|
|
128
|
-
contributions.deploymentAutomation !== undefined
|
|
130
|
+
contributions.deploymentAutomation !== undefined ||
|
|
131
|
+
contributions.resolveActivityHistoryAllowance !== undefined) {
|
|
129
132
|
found.add('controls');
|
|
130
133
|
}
|
|
131
134
|
if (contributions.auditStore !== undefined ||
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type DailyCounterStore } from '@noodle-borg/admission-limits/portable';
|
|
2
|
+
import { type RuntimeArtifact } from '@noodle-borg/compiler';
|
|
3
|
+
import { type Connector } from '@noodle-borg/runtime';
|
|
4
|
+
import type { BusinessInformationStore } from './business-information/contracts.js';
|
|
5
|
+
import type { TenantRef } from './store.js';
|
|
6
|
+
export interface NativeRecordConnectorInput {
|
|
7
|
+
readonly tenant: TenantRef;
|
|
8
|
+
readonly artifact: RuntimeArtifact;
|
|
9
|
+
readonly deploymentId?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface NativeRecordConnectorDependencies {
|
|
12
|
+
readonly store: BusinessInformationStore;
|
|
13
|
+
readonly counters: DailyCounterStore;
|
|
14
|
+
readonly publicIntakeEnabled?: boolean;
|
|
15
|
+
readonly now?: () => Date;
|
|
16
|
+
}
|
|
17
|
+
export type NativeRecordConnectorFactory = (input: NativeRecordConnectorInput) => Connector | undefined;
|
|
18
|
+
/** Platform composition supplies storage; an authored declaration alone grants no installed authority. */
|
|
19
|
+
export declare function createDeploymentNativeRecordConnector(input: NativeRecordConnectorInput, dependencies: NativeRecordConnectorDependencies): Connector | undefined;
|
|
20
|
+
//# sourceMappingURL=native-record-connector.d.ts.map
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { admitPublicRecord } from '@noodle-borg/admission-limits/portable';
|
|
2
|
+
import { RECORD_CONNECTOR_ID, RECORD_CONNECTOR_VERSION, RECORD_OPERATION_SIGNATURES, validateJsonSchema, } from '@noodle-borg/compiler';
|
|
3
|
+
import { ConnectorInvocationError } from '@noodle-borg/runtime';
|
|
4
|
+
import { creationPayload } from './business-information/collection-controls.js';
|
|
5
|
+
import { businessGrantAllows, idempotencyDigest, requestFingerprint, } from './business-information/model.js';
|
|
6
|
+
import { NativeStorageLimitError } from './business-information/native-storage-budget.js';
|
|
7
|
+
import { CursorValidationError, PayloadValidationError, } from './business-information/validation.js';
|
|
8
|
+
import { recordToWire } from './routes/business-information-wire.js';
|
|
9
|
+
/** Platform composition supplies storage; an authored declaration alone grants no installed authority. */
|
|
10
|
+
export function createDeploymentNativeRecordConnector(input, dependencies) {
|
|
11
|
+
if (!input.artifact.server.managedCollections?.some((collection) => collection.source.authority === 'native'))
|
|
12
|
+
return undefined;
|
|
13
|
+
return new NativeRecordConnector(input, dependencies);
|
|
14
|
+
}
|
|
15
|
+
class NativeRecordConnector {
|
|
16
|
+
input;
|
|
17
|
+
dependencies;
|
|
18
|
+
id = RECORD_CONNECTOR_ID;
|
|
19
|
+
version = RECORD_CONNECTOR_VERSION;
|
|
20
|
+
constructor(input, dependencies) {
|
|
21
|
+
this.input = input;
|
|
22
|
+
this.dependencies = dependencies;
|
|
23
|
+
}
|
|
24
|
+
signature(operation) {
|
|
25
|
+
return RECORD_OPERATION_SIGNATURES[operation];
|
|
26
|
+
}
|
|
27
|
+
executionBoundMs(operation) {
|
|
28
|
+
return this.signature(operation)?.type === 'action' ? 10_000 : undefined;
|
|
29
|
+
}
|
|
30
|
+
async invoke(call) {
|
|
31
|
+
const signature = this.signature(call.operation);
|
|
32
|
+
if (signature === undefined || validateJsonSchema(signature.input, call.args).length > 0)
|
|
33
|
+
return fail(call, 400, 'Invalid native record operation arguments.');
|
|
34
|
+
if (signature.type === 'action' && !/^[a-f0-9]{64}$/.test(call.execution?.id ?? ''))
|
|
35
|
+
return fail(call, 503, 'A trusted execution identity is required before a native record write.');
|
|
36
|
+
const installations = (await this.dependencies.store.listInstallations(this.input.tenant.org)).filter((installation) => installation.scope.app === this.input.tenant.app &&
|
|
37
|
+
installation.scope.env === this.input.tenant.env);
|
|
38
|
+
if (installations.length !== 1)
|
|
39
|
+
return fail(call, 503, 'Native record installation is unavailable.');
|
|
40
|
+
const installation = installations[0];
|
|
41
|
+
if (installation === undefined)
|
|
42
|
+
return fail(call, 503, 'Native record installation is unavailable.');
|
|
43
|
+
const collection = installation.definition.collections.find((entry) => entry.key === call.args.collection);
|
|
44
|
+
const authored = this.input.artifact.server.managedCollections?.find((entry) => entry.name === call.args.collection);
|
|
45
|
+
if (collection === undefined ||
|
|
46
|
+
authored === undefined ||
|
|
47
|
+
!installation.managedCollections.includes(collection.key))
|
|
48
|
+
return fail(call, 404, 'Native collection is not enabled for this application.');
|
|
49
|
+
if (collection.authority.authority !== 'native' || authored.source.authority !== 'native')
|
|
50
|
+
return fail(call, 405, 'External reference collections do not accept native record operations.');
|
|
51
|
+
if (collection.schemaDigest.replace(/^sha256:/, '') !==
|
|
52
|
+
authored.schemaDigest.replace(/^sha256:/, ''))
|
|
53
|
+
return fail(call, 409, 'Collection definition changed; activate the current application before continuing.');
|
|
54
|
+
const publicInput = call.operation === 'submit_record';
|
|
55
|
+
if (!publicInput)
|
|
56
|
+
await this.authorize(call, installation);
|
|
57
|
+
try {
|
|
58
|
+
return await this.execute(call, installation, collection, publicInput);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
if (error instanceof CursorValidationError)
|
|
62
|
+
return fail(call, 400, 'Invalid or stale record cursor; restart the query.');
|
|
63
|
+
if (error instanceof NativeStorageLimitError)
|
|
64
|
+
return fail(call, 409, error.message);
|
|
65
|
+
if (error instanceof PayloadValidationError)
|
|
66
|
+
return fail(call, 400, 'Record fields do not match the declared collection permissions and schema.');
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async authorize(call, installation) {
|
|
71
|
+
if (call.caller?.identityKind !== 'platform')
|
|
72
|
+
return fail(call, 403, 'A live business grant is required for staff record operations.');
|
|
73
|
+
const permission = call.operation === 'create_record'
|
|
74
|
+
? 'records:create'
|
|
75
|
+
: call.operation === 'update_record'
|
|
76
|
+
? 'records:update'
|
|
77
|
+
: call.operation === 'delete_record'
|
|
78
|
+
? 'records:delete'
|
|
79
|
+
: 'records:read';
|
|
80
|
+
const grant = await this.dependencies.store.getGrant(installation.scope, call.caller.subject);
|
|
81
|
+
if (!businessGrantAllows(grant, permission))
|
|
82
|
+
return fail(call, 403, 'A live business grant is required for this record operation.');
|
|
83
|
+
}
|
|
84
|
+
async execute(call, installation, collection, publicInput) {
|
|
85
|
+
const store = this.dependencies.store;
|
|
86
|
+
const scope = installation.scope;
|
|
87
|
+
const actorSubject = call.caller?.subject ?? 'anonymous';
|
|
88
|
+
if (call.operation === 'submit_record' || call.operation === 'create_record') {
|
|
89
|
+
// Validate before receipt probing/admission, and preserve the admitted payload as the replay fingerprint.
|
|
90
|
+
creationPayload(collection, call.args.payload, publicInput);
|
|
91
|
+
const payload = call.args.payload;
|
|
92
|
+
const key = call.execution?.id;
|
|
93
|
+
if (key === undefined)
|
|
94
|
+
return fail(call, 503, 'A trusted execution identity is required.');
|
|
95
|
+
const request = {
|
|
96
|
+
scope,
|
|
97
|
+
collectionKey: collection.key,
|
|
98
|
+
idempotencyKey: key,
|
|
99
|
+
payload,
|
|
100
|
+
...(publicInput ? { publicInput: true } : {}),
|
|
101
|
+
origin: { kind: 'mcp', reference: 'native-tool' },
|
|
102
|
+
actorSubject,
|
|
103
|
+
};
|
|
104
|
+
const completed = await store.probeRequest(request);
|
|
105
|
+
if (completed.disposition === 'conflict')
|
|
106
|
+
return fail(call, 409, 'This execution identity was already used with different record content.');
|
|
107
|
+
if (completed.disposition === 'replayed') {
|
|
108
|
+
call.reportOutcome?.({ outcome: 'completed', reference: completed.record.id });
|
|
109
|
+
return publicInput
|
|
110
|
+
? receipt(completed.record)
|
|
111
|
+
: { ok: true, record: recordToWire(completed.record) };
|
|
112
|
+
}
|
|
113
|
+
if (publicInput) {
|
|
114
|
+
if (!installation.intakeActive || this.dependencies.publicIntakeEnabled === false)
|
|
115
|
+
return fail(call, 503, 'Public record intake is paused.');
|
|
116
|
+
if (call.publicAdmission === undefined || !call.publicAdmission.network)
|
|
117
|
+
return fail(call, 503, 'Trusted network admission context is required for public record writes.');
|
|
118
|
+
const quota = await admitPublicRecord({
|
|
119
|
+
counters: this.dependencies.counters,
|
|
120
|
+
surfaceId: installation.publicId,
|
|
121
|
+
attempt: {
|
|
122
|
+
key: `solution-intake:logical:${installation.publicId}:${idempotencyDigest(key)}`,
|
|
123
|
+
fingerprint: requestFingerprint(request),
|
|
124
|
+
},
|
|
125
|
+
buckets: call.publicAdmission,
|
|
126
|
+
now: this.dependencies.now?.() ?? new Date(),
|
|
127
|
+
});
|
|
128
|
+
if (!quota.allowed)
|
|
129
|
+
return fail(call, quota.reason === 'quota_exceeded'
|
|
130
|
+
? 429
|
|
131
|
+
: quota.reason === 'idempotency_conflict'
|
|
132
|
+
? 409
|
|
133
|
+
: 503, quota.reason === 'quota_exceeded'
|
|
134
|
+
? 'Public record admission limit exceeded.'
|
|
135
|
+
: 'Public record admission is unavailable.');
|
|
136
|
+
}
|
|
137
|
+
else
|
|
138
|
+
await this.authorize(call, installation);
|
|
139
|
+
if (call.signal?.aborted)
|
|
140
|
+
return fail(call, 503, 'Native record write was cancelled before dispatch.');
|
|
141
|
+
const created = await store.createRequest(request);
|
|
142
|
+
if (created.disposition === 'conflict')
|
|
143
|
+
return fail(call, 409, 'Record creation conflicts with the original execution.');
|
|
144
|
+
if (created.disposition === 'paused')
|
|
145
|
+
return fail(call, 503, 'Public record intake is paused.');
|
|
146
|
+
call.reportOutcome?.({ outcome: 'completed', reference: created.record.id });
|
|
147
|
+
return publicInput
|
|
148
|
+
? receipt(created.record)
|
|
149
|
+
: { ok: true, record: recordToWire(created.record) };
|
|
150
|
+
}
|
|
151
|
+
if (call.operation === 'list_records') {
|
|
152
|
+
const result = await store.listRequests({
|
|
153
|
+
scope,
|
|
154
|
+
collectionKey: collection.key,
|
|
155
|
+
...(call.args.cursor === undefined ? {} : { cursor: String(call.args.cursor) }),
|
|
156
|
+
...(call.args.limit === undefined ? {} : { limit: Number(call.args.limit) }),
|
|
157
|
+
});
|
|
158
|
+
return {
|
|
159
|
+
ok: true,
|
|
160
|
+
records: result.records.map(recordToWire),
|
|
161
|
+
...(result.nextCursor === undefined ? {} : { nextCursor: result.nextCursor }),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
const id = String(call.args.id);
|
|
165
|
+
if (call.operation === 'get_record') {
|
|
166
|
+
const record = await store.getRequest(scope, collection.key, id);
|
|
167
|
+
if (record === undefined)
|
|
168
|
+
return fail(call, 404, 'Native record was not found.');
|
|
169
|
+
return { ok: true, record: recordToWire(record) };
|
|
170
|
+
}
|
|
171
|
+
await this.authorize(call, installation);
|
|
172
|
+
const mutation = {
|
|
173
|
+
scope,
|
|
174
|
+
collectionKey: collection.key,
|
|
175
|
+
id,
|
|
176
|
+
expectedRevision: Number(call.args.expectedRevision),
|
|
177
|
+
actorSubject,
|
|
178
|
+
};
|
|
179
|
+
if (call.signal?.aborted)
|
|
180
|
+
return fail(call, 503, 'Native record write was cancelled before dispatch.');
|
|
181
|
+
const result = call.operation === 'delete_record'
|
|
182
|
+
? await store.deleteRequest({ ...mutation, reason: 'customer_request' })
|
|
183
|
+
: await store.mutateRequest({
|
|
184
|
+
...mutation,
|
|
185
|
+
operation: {
|
|
186
|
+
kind: 'update',
|
|
187
|
+
payload: call.args.patch,
|
|
188
|
+
...(call.args.unset === undefined ? {} : { unset: call.args.unset }),
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
if (!result.ok)
|
|
192
|
+
return fail(call, result.reason === 'not_found' ? 404 : result.reason === 'conflict' ? 409 : 422, 'Native record operation was not applied; inspect the current record and revision.');
|
|
193
|
+
call.reportOutcome?.({ outcome: 'completed', reference: result.record.id });
|
|
194
|
+
return call.operation === 'delete_record'
|
|
195
|
+
? receipt(result.record)
|
|
196
|
+
: { ok: true, record: recordToWire(result.record) };
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
function receipt(record) {
|
|
200
|
+
return { ok: true, recordId: record.id, revision: record.revision };
|
|
201
|
+
}
|
|
202
|
+
function fail(call, status, message) {
|
|
203
|
+
call.reportOutcome?.({ outcome: 'rejected' });
|
|
204
|
+
throw new ConnectorInvocationError(message, { status, retryable: false });
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=native-record-connector.js.map
|
|
@@ -169,6 +169,8 @@ export interface DelegatedCredentialLookup {
|
|
|
169
169
|
export interface OAuthStore extends DeviceAuthorizationStore {
|
|
170
170
|
/** Dynamic client registration (RFC 7591): persist + read the SDK-generated client info. */
|
|
171
171
|
getClient(clientId: string): Promise<OAuthClientInformationFull | undefined>;
|
|
172
|
+
/** Durable server-owned purpose; absent registration is distinct from a known dynamic client. */
|
|
173
|
+
getClientPurpose(clientId: string): Promise<'console' | 'portal' | 'dynamic' | undefined>;
|
|
172
174
|
putClient(client: OAuthClientInformationFull): Promise<OAuthClientInformationFull>;
|
|
173
175
|
/** Atomically reserves or reconciles a server-owned client without taking over a DCR registration. */
|
|
174
176
|
putFirstPartyClient(owner: 'console' | 'portal', client: OAuthClientInformationFull): Promise<OAuthClientInformationFull>;
|
|
@@ -219,6 +221,7 @@ export interface OAuthStore extends DeviceAuthorizationStore {
|
|
|
219
221
|
export declare class InMemoryOAuthStore implements OAuthStore {
|
|
220
222
|
#private;
|
|
221
223
|
getClient(clientId: string): Promise<OAuthClientInformationFull | undefined>;
|
|
224
|
+
getClientPurpose(clientId: string): Promise<'console' | 'portal' | 'dynamic' | undefined>;
|
|
222
225
|
putClient(client: OAuthClientInformationFull): Promise<OAuthClientInformationFull>;
|
|
223
226
|
putFirstPartyClient(owner: 'console' | 'portal', client: OAuthClientInformationFull): Promise<OAuthClientInformationFull>;
|
|
224
227
|
createPendingAuthorization(record: PendingAuthorizationRecord): Promise<void>;
|