@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
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
|
+
import { managedSolutionBlueprint, managedSolutionVariables, } from './managed-solution-blueprints.js';
|
|
2
3
|
import { PayloadValidationError, validateManagedPayload, validateScalar } from './validation.js';
|
|
3
4
|
const requestSchema = (required, properties) => ({
|
|
4
5
|
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
@@ -7,16 +8,16 @@ const requestSchema = (required, properties) => ({
|
|
|
7
8
|
required,
|
|
8
9
|
properties,
|
|
9
10
|
});
|
|
10
|
-
function collection(key, labels, schema) {
|
|
11
|
+
function collection(key, labels, schema, schemaVersion = 1) {
|
|
11
12
|
return {
|
|
12
13
|
key,
|
|
13
|
-
schemaVersion
|
|
14
|
+
schemaVersion,
|
|
14
15
|
schemaDigest: createHash('sha256').update(stableJson(schema)).digest('hex'),
|
|
15
16
|
labels,
|
|
16
17
|
schema,
|
|
17
18
|
};
|
|
18
19
|
}
|
|
19
|
-
const
|
|
20
|
+
const travelV1 = collection('travel_requests', { singular: 'Travel request', plural: 'Travel requests', navigation: 'Requests' }, requestSchema(['request_type', 'summary'], {
|
|
20
21
|
request_type: {
|
|
21
22
|
type: 'string',
|
|
22
23
|
enum: ['service', 'cancellation', 'refund', 'recovery'],
|
|
@@ -26,6 +27,17 @@ const travel = collection('travel_requests', { singular: 'Travel request', plura
|
|
|
26
27
|
booking_reference: { type: 'string', maxLength: 128 },
|
|
27
28
|
traveler_reference: { type: 'string', maxLength: 128 },
|
|
28
29
|
}));
|
|
30
|
+
const travelV2 = collection('travel_requests', { singular: 'Travel request', plural: 'Travel requests', navigation: 'Requests' }, requestSchema(['request_type', 'summary'], {
|
|
31
|
+
request_type: {
|
|
32
|
+
type: 'string',
|
|
33
|
+
enum: ['service', 'cancellation', 'refund', 'recovery', 'information'],
|
|
34
|
+
maxLength: 32,
|
|
35
|
+
},
|
|
36
|
+
summary: { type: 'string', minLength: 1, maxLength: 2000 },
|
|
37
|
+
booking_reference: { type: 'string', maxLength: 128 },
|
|
38
|
+
traveler_reference: { type: 'string', maxLength: 128 },
|
|
39
|
+
priority: { type: 'string', enum: ['normal', 'urgent'], maxLength: 16 },
|
|
40
|
+
}), 2);
|
|
29
41
|
const service = collection('service_requests', { singular: 'Service request', plural: 'Service requests', navigation: 'Requests' }, requestSchema(['request_type', 'summary'], {
|
|
30
42
|
request_type: {
|
|
31
43
|
type: 'string',
|
|
@@ -56,18 +68,56 @@ const restaurant = collection('guest_requests', { singular: 'Guest request', plu
|
|
|
56
68
|
location_reference: { type: 'string', maxLength: 128 },
|
|
57
69
|
reservation_reference: { type: 'string', maxLength: 128 },
|
|
58
70
|
}));
|
|
71
|
+
export const BUILT_IN_SOLUTION_PROFILE_RELEASES = {
|
|
72
|
+
travel: [
|
|
73
|
+
{ key: 'travel', version: 1, label: 'Travel', collections: [travelV1] },
|
|
74
|
+
{ key: 'travel', version: 2, label: 'Travel', collections: [travelV2] },
|
|
75
|
+
{ key: 'travel', version: 3, label: 'Travel', collections: [lightweightCollection(travelV2)] },
|
|
76
|
+
],
|
|
77
|
+
b2b_saas: [{ key: 'b2b_saas', version: 1, label: 'B2B SaaS', collections: [service] }],
|
|
78
|
+
ecommerce: [
|
|
79
|
+
{ key: 'ecommerce', version: 1, label: 'Ecommerce', collections: [ecommerce] },
|
|
80
|
+
{
|
|
81
|
+
key: 'ecommerce',
|
|
82
|
+
version: 2,
|
|
83
|
+
label: 'Ecommerce',
|
|
84
|
+
collections: [lightweightCollection(ecommerce)],
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
restaurant: [
|
|
88
|
+
{ key: 'restaurant', version: 1, label: 'Restaurant', collections: [restaurant] },
|
|
89
|
+
{
|
|
90
|
+
key: 'restaurant',
|
|
91
|
+
version: 2,
|
|
92
|
+
label: 'Restaurant',
|
|
93
|
+
collections: [lightweightCollection(restaurant)],
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
};
|
|
59
97
|
export const BUILT_IN_SOLUTION_PROFILES = {
|
|
60
|
-
travel:
|
|
98
|
+
travel: currentProfile('travel'),
|
|
61
99
|
b2b_saas: { key: 'b2b_saas', version: 1, label: 'B2B SaaS', collections: [service] },
|
|
62
|
-
ecommerce:
|
|
63
|
-
restaurant:
|
|
100
|
+
ecommerce: currentProfile('ecommerce'),
|
|
101
|
+
restaurant: currentProfile('restaurant'),
|
|
64
102
|
};
|
|
103
|
+
/** Public managed catalog. The legacy SaaS request profile remains readable but cannot be newly sold. */
|
|
104
|
+
export const MANAGED_SOLUTION_PROFILE_KEYS = ['travel', 'ecommerce', 'restaurant'];
|
|
65
105
|
export function builtInProfile(key) {
|
|
66
106
|
const profile = BUILT_IN_SOLUTION_PROFILES[key];
|
|
67
107
|
if (profile === undefined)
|
|
68
108
|
throw new Error(`unknown built-in solution profile "${String(key)}"`);
|
|
69
109
|
return profile;
|
|
70
110
|
}
|
|
111
|
+
export function builtInProfileAtRelease(key, release) {
|
|
112
|
+
const profile = BUILT_IN_SOLUTION_PROFILE_RELEASES[key].find((candidate) => candidate.version === release);
|
|
113
|
+
if (profile === undefined) {
|
|
114
|
+
throw new Error(`unsupported built-in solution profile release "${key}@${release}"`);
|
|
115
|
+
}
|
|
116
|
+
return profile;
|
|
117
|
+
}
|
|
118
|
+
export function isBuiltInProfileKey(value) {
|
|
119
|
+
return (value === 'travel' || value === 'b2b_saas' || value === 'ecommerce' || value === 'restaurant');
|
|
120
|
+
}
|
|
71
121
|
export function builtInCollection(profileKey, collectionKey) {
|
|
72
122
|
const normalized = validateScalar('collection key', collectionKey, 64);
|
|
73
123
|
const found = builtInProfile(profileKey).collections.find((candidate) => candidate.key === normalized);
|
|
@@ -82,6 +132,87 @@ export function validateProfilePayload(profileKey, collectionKey, value) {
|
|
|
82
132
|
validateJsonSchema(collectionProfile.schema, payload);
|
|
83
133
|
return payload;
|
|
84
134
|
}
|
|
135
|
+
export function builtInDefinition(key) {
|
|
136
|
+
return definitionFromProfile(builtInProfile(key));
|
|
137
|
+
}
|
|
138
|
+
export function builtInDefinitionAtRelease(key, release) {
|
|
139
|
+
return definitionFromProfile(builtInProfileAtRelease(key, release));
|
|
140
|
+
}
|
|
141
|
+
function definitionFromProfile(profile) {
|
|
142
|
+
const { key } = profile;
|
|
143
|
+
const blueprint = managedSolutionBlueprint(key, profile.version);
|
|
144
|
+
const variables = blueprint === undefined ? undefined : managedSolutionVariables();
|
|
145
|
+
const digest = createHash('sha256')
|
|
146
|
+
.update(stableJson({
|
|
147
|
+
key: profile.key,
|
|
148
|
+
version: profile.version,
|
|
149
|
+
collections: profile.collections,
|
|
150
|
+
...(blueprint === undefined ? {} : { blueprint, variables }),
|
|
151
|
+
}))
|
|
152
|
+
.digest('hex');
|
|
153
|
+
return {
|
|
154
|
+
reference: key === 'b2b_saas'
|
|
155
|
+
? { kind: 'legacy', definitionId: 'b2b_saas', release: profile.version, digest }
|
|
156
|
+
: {
|
|
157
|
+
kind: 'managed',
|
|
158
|
+
definitionId: key,
|
|
159
|
+
release: profile.version,
|
|
160
|
+
digest,
|
|
161
|
+
},
|
|
162
|
+
title: profile.label,
|
|
163
|
+
description: `Receive and operate ${profile.collections[0]?.labels.plural.toLowerCase() ?? 'business records'}.`,
|
|
164
|
+
collections: profile.collections.map(collectionDefinition),
|
|
165
|
+
...(variables === undefined ? {} : { variables }),
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function currentProfile(key) {
|
|
169
|
+
const releases = BUILT_IN_SOLUTION_PROFILE_RELEASES[key];
|
|
170
|
+
const profile = releases.at(-1);
|
|
171
|
+
if (profile === undefined)
|
|
172
|
+
throw new Error(`built-in solution profile "${key}" has no releases`);
|
|
173
|
+
return profile;
|
|
174
|
+
}
|
|
175
|
+
function collectionDefinition(profile) {
|
|
176
|
+
return {
|
|
177
|
+
key: profile.key,
|
|
178
|
+
title: profile.labels.plural,
|
|
179
|
+
singularTitle: profile.labels.singular,
|
|
180
|
+
description: `Managed ${profile.labels.plural.toLowerCase()} for this application.`,
|
|
181
|
+
schemaVersion: profile.schemaVersion,
|
|
182
|
+
schemaDigest: profile.schemaDigest,
|
|
183
|
+
recordSchema: structuredClone(profile.schema),
|
|
184
|
+
summaryFields: profile.schema.required.slice(0, 6),
|
|
185
|
+
authority: { authority: 'native' },
|
|
186
|
+
...(profile.management === undefined
|
|
187
|
+
? { behavior: { kind: 'request' } }
|
|
188
|
+
: {
|
|
189
|
+
management: profile.management,
|
|
190
|
+
publicFields: profile.publicFields ?? [],
|
|
191
|
+
editableFields: Object.keys(profile.schema.properties),
|
|
192
|
+
fields: { status: { label: 'Status' } },
|
|
193
|
+
filterFields: ['status'],
|
|
194
|
+
sortFields: ['status'],
|
|
195
|
+
}),
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
function lightweightCollection(previous) {
|
|
199
|
+
return {
|
|
200
|
+
...collection(previous.key, previous.labels, {
|
|
201
|
+
...previous.schema,
|
|
202
|
+
properties: {
|
|
203
|
+
...previous.schema.properties,
|
|
204
|
+
status: {
|
|
205
|
+
type: 'string',
|
|
206
|
+
enum: ['new', 'in_progress', 'resolved', 'closed'],
|
|
207
|
+
maxLength: 32,
|
|
208
|
+
default: 'new',
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
}, previous.schemaVersion + 1),
|
|
212
|
+
management: { assignment: true, notes: true },
|
|
213
|
+
publicFields: Object.keys(previous.schema.properties),
|
|
214
|
+
};
|
|
215
|
+
}
|
|
85
216
|
function validateJsonSchema(schema, payload) {
|
|
86
217
|
for (const required of schema.required) {
|
|
87
218
|
if (!(required in payload)) {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { assertManagedRollbackReaders } from './managed-releases.js';
|
|
3
|
+
import { builtInDefinition, MANAGED_SOLUTION_PROFILE_KEYS } from './profiles.js';
|
|
4
|
+
/** Proves the running release can read every managed schema identity ever accepted by the store. */
|
|
5
|
+
export async function proveManagedReaderFloor(store) {
|
|
6
|
+
const inventory = await store.listAcceptedSchemaInventory();
|
|
7
|
+
for (const key of MANAGED_SOLUTION_PROFILE_KEYS) {
|
|
8
|
+
const definition = builtInDefinition(key);
|
|
9
|
+
if (definition.reference.kind !== 'managed') {
|
|
10
|
+
throw new Error(`managed definition resolver returned a non-managed profile for "${key}"`);
|
|
11
|
+
}
|
|
12
|
+
assertManagedRollbackReaders(key, definition.reference.release, inventory);
|
|
13
|
+
}
|
|
14
|
+
const canonical = [...inventory]
|
|
15
|
+
.map((identity) => JSON.stringify(identity))
|
|
16
|
+
.sort()
|
|
17
|
+
.join('\n');
|
|
18
|
+
return {
|
|
19
|
+
inventory: {
|
|
20
|
+
acceptedSchemaIdentities: inventory.length,
|
|
21
|
+
digest: `sha256:${createHash('sha256').update(canonical).digest('hex')}`,
|
|
22
|
+
},
|
|
23
|
+
readerTargets: MANAGED_SOLUTION_PROFILE_KEYS.length,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=reader-floor.js.map
|
package/node_modules/@noodle-borg/service/dist/business-information/source-credential-fence.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export class SourceCredentialError extends Error {
|
|
2
|
+
code = 'source_authorization_lost';
|
|
3
|
+
constructor() {
|
|
4
|
+
super('source_authorization_lost');
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
const fenced = new WeakMap();
|
|
8
|
+
/** Every source consumer uses this same adapter; persisted portable bindings cannot silently fall back. */
|
|
9
|
+
export function fenceSourceStore(store, authority) {
|
|
10
|
+
const prior = fenced.get(store);
|
|
11
|
+
if (prior?.authority === authority && prior !== undefined)
|
|
12
|
+
return store;
|
|
13
|
+
if (prior)
|
|
14
|
+
store = prior.raw;
|
|
15
|
+
const current = (binding, work) => (authority ? authority.withCurrent(binding, work) : work(undefined));
|
|
16
|
+
const guard = (binding, work) => current(binding, (identity) => {
|
|
17
|
+
if (identity?.generation !== binding.credentialIdentity?.generation ||
|
|
18
|
+
identity?.account !== binding.credentialIdentity?.account ||
|
|
19
|
+
identity?.configuration !== binding.credentialIdentity?.configuration)
|
|
20
|
+
throw new SourceCredentialError();
|
|
21
|
+
return work();
|
|
22
|
+
});
|
|
23
|
+
const captured = (binding, work) => current(binding, (identity) => {
|
|
24
|
+
if (!identity && binding.credentialIdentity)
|
|
25
|
+
throw new SourceCredentialError();
|
|
26
|
+
const { credentialIdentity: ignored, ...rest } = binding;
|
|
27
|
+
void ignored;
|
|
28
|
+
return work({ ...rest, ...(identity ? { credentialIdentity: identity } : {}) });
|
|
29
|
+
});
|
|
30
|
+
async function read(input, work) {
|
|
31
|
+
const binding = await store.getBinding(input);
|
|
32
|
+
return binding ? guard(binding, work) : work();
|
|
33
|
+
}
|
|
34
|
+
const result = {
|
|
35
|
+
createBinding: (input) => captured(input, (value) => store.createBinding(value)),
|
|
36
|
+
replaceBinding: async (input) => {
|
|
37
|
+
const previous = await store.getBinding(input);
|
|
38
|
+
if (previous?.credentialIdentity && !input.credentialIdentity)
|
|
39
|
+
input = { ...input, credentialIdentity: previous.credentialIdentity };
|
|
40
|
+
return captured(input, (value) => store.replaceBinding({
|
|
41
|
+
...value,
|
|
42
|
+
expectedRevision: input.expectedRevision,
|
|
43
|
+
now: input.now,
|
|
44
|
+
}));
|
|
45
|
+
},
|
|
46
|
+
getBinding: (input) => store.getBinding(input),
|
|
47
|
+
setBindingState: (input) => store.setBindingState(input),
|
|
48
|
+
requestRefresh: (input) => read(input, () => store.requestRefresh(input)),
|
|
49
|
+
claimDue: async (input) => {
|
|
50
|
+
const lease = await store.claimDue(input);
|
|
51
|
+
if (!lease)
|
|
52
|
+
return undefined;
|
|
53
|
+
try {
|
|
54
|
+
return await guard(lease.binding, async () => lease);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
await store.failLease({
|
|
58
|
+
lease,
|
|
59
|
+
now: input.now,
|
|
60
|
+
errorCode: 'source_authorization_lost',
|
|
61
|
+
retryAt: new Date(input.now.getTime() + 30_000),
|
|
62
|
+
});
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
commitPage: (input) => guard(input.lease.binding, () => store.commitPage(input)),
|
|
67
|
+
resetCheckpoint: (input) => store.resetCheckpoint(input),
|
|
68
|
+
failLease: (input) => store.failLease(input),
|
|
69
|
+
listExternalRecords: (input) => read(input, () => store.listExternalRecords(input)),
|
|
70
|
+
getExternalRecord: (input) => read(input, () => store.getExternalRecord(input)),
|
|
71
|
+
suppressExternalRecord: (input) => store.suppressExternalRecord(input),
|
|
72
|
+
listSuppressions: (input) => store.listSuppressions(input),
|
|
73
|
+
restoreSuppressions: (input) => store.restoreSuppressions(input),
|
|
74
|
+
purgeExpired: (input) => store.purgeExpired(input),
|
|
75
|
+
};
|
|
76
|
+
fenced.set(result, { raw: store, authority });
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=source-credential-fence.js.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** Engineering safeguards, independent of commercial plans and customer Activity retention. */
|
|
2
|
+
export const SOURCE_ORG_CUSTODY_BYTES = 1024 ** 3;
|
|
3
|
+
export const SOURCE_MAX_REPLICA_ROWS = 100_000;
|
|
4
|
+
export const SOURCE_MAX_REFRESH_KEYS = 50_000;
|
|
5
|
+
/** A conservative, validated upper bound for a row's non-payload representation. */
|
|
6
|
+
export const SOURCE_METADATA_BYTES = 4096;
|
|
7
|
+
export const SOURCE_REFRESH_REPLAY_MS = 30 * 86_400_000;
|
|
8
|
+
export class SourceCapacityError extends Error {
|
|
9
|
+
code = 'source_capacity_exceeded';
|
|
10
|
+
constructor() {
|
|
11
|
+
super('Reference storage is full. Retained records remain available. Narrow the source or erase local records; refresh receipts recover capacity after their replay window.');
|
|
12
|
+
this.name = 'SourceCapacityError';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export function sourceDatasetCharge(retained, baseline, projected) {
|
|
16
|
+
return baseline === undefined
|
|
17
|
+
? 2 * retained
|
|
18
|
+
: Math.max(retained, 2 * Math.max(baseline, projected));
|
|
19
|
+
}
|
|
20
|
+
export function sourceRowCost(kind, payloadBytes, live) {
|
|
21
|
+
return (SOURCE_METADATA_BYTES + payloadBytes + (kind === 'record' && live ? SOURCE_METADATA_BYTES : 0));
|
|
22
|
+
}
|
|
23
|
+
export function sourceJsonBytes(value) {
|
|
24
|
+
return Buffer.byteLength(JSON.stringify(value), 'utf8');
|
|
25
|
+
}
|
|
26
|
+
export function assertSourceMetadata(value) {
|
|
27
|
+
if (sourceJsonBytes(value) > SOURCE_METADATA_BYTES)
|
|
28
|
+
throw new Error('Source metadata exceeds its reserved representation');
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=source-custody-budget.js.map
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { assertSourceMetadata, SOURCE_MAX_REFRESH_KEYS, SOURCE_MAX_REPLICA_ROWS, SOURCE_METADATA_BYTES, SOURCE_ORG_CUSTODY_BYTES, SourceCapacityError, sourceDatasetCharge, sourceJsonBytes, sourceRowCost, } from './source-custody-budget.js';
|
|
2
|
+
import { bindingKey } from './source-ingestion-memory-state.js';
|
|
3
|
+
/** Development-only accounting; production maintains the same conservative counters in PostgreSQL. */
|
|
4
|
+
export class SourceMemoryCapacity {
|
|
5
|
+
maximum;
|
|
6
|
+
#baselines = new Map();
|
|
7
|
+
constructor(maximum = SOURCE_ORG_CUSTODY_BYTES) {
|
|
8
|
+
this.maximum = maximum;
|
|
9
|
+
}
|
|
10
|
+
admit(before, after) {
|
|
11
|
+
const baselines = new Map(this.#baselines);
|
|
12
|
+
const previous = measure(before, this.#baselines);
|
|
13
|
+
const raw = measure(after, baselines);
|
|
14
|
+
for (const [key, { record }] of after.bindings) {
|
|
15
|
+
const old = before.bindings.get(key)?.record;
|
|
16
|
+
if (record.scanMode !== 'snapshot')
|
|
17
|
+
baselines.delete(key);
|
|
18
|
+
else if (old?.scanMode !== 'snapshot' || old.scanGeneration !== record.scanGeneration) {
|
|
19
|
+
baselines.set(key, raw.bindings.get(key)?.retained ?? 0);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
for (const key of baselines.keys())
|
|
23
|
+
if (!after.bindings.has(key))
|
|
24
|
+
baselines.delete(key);
|
|
25
|
+
const next = measure(after, baselines);
|
|
26
|
+
for (const [org, bytes] of next.organizations) {
|
|
27
|
+
if (bytes > Math.max(this.maximum, previous.organizations.get(org) ?? 0))
|
|
28
|
+
throw new SourceCapacityError();
|
|
29
|
+
}
|
|
30
|
+
for (const [key, usage] of next.installations) {
|
|
31
|
+
const old = previous.installations.get(key);
|
|
32
|
+
if (usage.rows > Math.max(SOURCE_MAX_REPLICA_ROWS, old?.rows ?? 0) ||
|
|
33
|
+
usage.slots > Math.max(2 * SOURCE_MAX_REPLICA_ROWS, old?.slots ?? 0) ||
|
|
34
|
+
usage.refresh > Math.max(SOURCE_MAX_REFRESH_KEYS, old?.refresh ?? 0))
|
|
35
|
+
throw new SourceCapacityError();
|
|
36
|
+
}
|
|
37
|
+
this.#baselines = baselines;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function measure(state, baselines) {
|
|
41
|
+
const bindings = new Map();
|
|
42
|
+
const organizations = new Map();
|
|
43
|
+
const installations = new Map();
|
|
44
|
+
const installation = (key) => {
|
|
45
|
+
const scope = key.split('\0').slice(0, 4).join('\0');
|
|
46
|
+
let value = installations.get(scope);
|
|
47
|
+
if (value === undefined) {
|
|
48
|
+
value = { rows: 0, slots: 0, refresh: 0 };
|
|
49
|
+
installations.set(scope, value);
|
|
50
|
+
}
|
|
51
|
+
return value;
|
|
52
|
+
};
|
|
53
|
+
for (const [key, { record }] of state.bindings) {
|
|
54
|
+
const { scan, credentialIdentity, bindingReference, configurationReference, cursor, checkpoint, ...metadata } = record;
|
|
55
|
+
assertSourceMetadata(metadata);
|
|
56
|
+
const bytes = 2 * SOURCE_METADATA_BYTES +
|
|
57
|
+
sourceJsonBytes({
|
|
58
|
+
scan,
|
|
59
|
+
credentialIdentity,
|
|
60
|
+
bindingReference,
|
|
61
|
+
configurationReference,
|
|
62
|
+
cursor,
|
|
63
|
+
checkpoint,
|
|
64
|
+
});
|
|
65
|
+
bindings.set(key, { retained: bytes, projected: bytes });
|
|
66
|
+
installation(key);
|
|
67
|
+
}
|
|
68
|
+
for (const stored of state.records.values()) {
|
|
69
|
+
const record = stored.record;
|
|
70
|
+
const key = bindingKey({
|
|
71
|
+
scope: record.scope,
|
|
72
|
+
collectionKey: record.collectionKey,
|
|
73
|
+
id: record.source.bindingId,
|
|
74
|
+
});
|
|
75
|
+
const usage = required(bindings.get(key));
|
|
76
|
+
const { record: payload, source, ...metadata } = record;
|
|
77
|
+
assertSourceMetadata({
|
|
78
|
+
...metadata,
|
|
79
|
+
source: { bindingId: source.bindingId, bindingGeneration: source.bindingGeneration },
|
|
80
|
+
});
|
|
81
|
+
const live = record.deletedAt === undefined;
|
|
82
|
+
const bytes = sourceRowCost('record', live ? sourceJsonBytes({ sourceId: source.id, version: source.version, record: payload }) : 0, live);
|
|
83
|
+
usage.retained += bytes;
|
|
84
|
+
usage.projected +=
|
|
85
|
+
live &&
|
|
86
|
+
state.bindings.get(key)?.record.scanMode === 'snapshot' &&
|
|
87
|
+
stored.lastSeenGeneration !== state.bindings.get(key)?.record.scanGeneration
|
|
88
|
+
? SOURCE_METADATA_BYTES
|
|
89
|
+
: bytes;
|
|
90
|
+
const count = installation(key);
|
|
91
|
+
count.rows += 1;
|
|
92
|
+
count.slots += live ? 2 : 1;
|
|
93
|
+
}
|
|
94
|
+
for (const suppression of state.suppressions.values()) {
|
|
95
|
+
assertSourceMetadata(suppression);
|
|
96
|
+
const key = bindingKey(suppression);
|
|
97
|
+
const usage = required(bindings.get(key));
|
|
98
|
+
usage.retained += SOURCE_METADATA_BYTES;
|
|
99
|
+
usage.projected += SOURCE_METADATA_BYTES;
|
|
100
|
+
installation(key).slots += 1;
|
|
101
|
+
}
|
|
102
|
+
for (const [key, value] of bindings) {
|
|
103
|
+
const org = required(state.bindings.get(key)).record.scope.org;
|
|
104
|
+
organizations.set(org, (organizations.get(org) ?? SOURCE_METADATA_BYTES) +
|
|
105
|
+
sourceDatasetCharge(value.retained, baselines.get(key), value.projected));
|
|
106
|
+
}
|
|
107
|
+
for (const refresh of state.refresh.values()) {
|
|
108
|
+
assertSourceMetadata(refresh);
|
|
109
|
+
const org = refresh.bindingKey.split('\0')[0];
|
|
110
|
+
if (org === undefined)
|
|
111
|
+
throw new Error('Missing source receipt scope');
|
|
112
|
+
organizations.set(org, (organizations.get(org) ?? SOURCE_METADATA_BYTES) + SOURCE_METADATA_BYTES);
|
|
113
|
+
installation(refresh.bindingKey).refresh += 1;
|
|
114
|
+
}
|
|
115
|
+
return { bindings, organizations, installations };
|
|
116
|
+
}
|
|
117
|
+
function required(value) {
|
|
118
|
+
if (value === undefined)
|
|
119
|
+
throw new Error('Source custody scope is missing');
|
|
120
|
+
return value;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=source-custody-memory.js.map
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { sha256Canonical, } from '@noodle-borg/compiler';
|
|
2
|
+
import { executeTool } from '@noodle-borg/runtime';
|
|
3
|
+
import { privateDefinitionFromDeployment } from './definition-resolver.js';
|
|
4
|
+
import { SourceCredentialError, } from './source-credential-fence.js';
|
|
5
|
+
import { normalizeSourceFailureCode } from './source-ingestion-failures.js';
|
|
6
|
+
import { sourceOperationSignatureDigest } from './source-ingestion-validation.js';
|
|
7
|
+
const SOURCE_TOOL = '__collection_source_scan';
|
|
8
|
+
/** Executes a private definition's read-only source operation through the normal governed runtime. */
|
|
9
|
+
export class RegistrySourceReadExecutor {
|
|
10
|
+
sourceAuthority;
|
|
11
|
+
#registry;
|
|
12
|
+
#installations;
|
|
13
|
+
#resolveTarget;
|
|
14
|
+
constructor(registry, installations, resolveTarget, sourceAuthority) {
|
|
15
|
+
this.sourceAuthority = sourceAuthority;
|
|
16
|
+
this.#registry = registry;
|
|
17
|
+
this.#installations = installations;
|
|
18
|
+
this.#resolveTarget = resolveTarget;
|
|
19
|
+
}
|
|
20
|
+
async scan(input) {
|
|
21
|
+
const installation = await this.#installations.getInstallation(input.binding.scope);
|
|
22
|
+
if (installation?.definition.reference.kind !== 'private') {
|
|
23
|
+
throw sourceFailure('source_definition_unavailable');
|
|
24
|
+
}
|
|
25
|
+
if (!installation.intakeActive)
|
|
26
|
+
throw sourceFailure('source_application_paused');
|
|
27
|
+
if (!installation.managedCollections.includes(input.binding.collectionKey)) {
|
|
28
|
+
throw sourceFailure('source_operation_unavailable');
|
|
29
|
+
}
|
|
30
|
+
const reference = installation.definition.reference;
|
|
31
|
+
if (installation.scope.org !== reference.publisherOrg) {
|
|
32
|
+
throw sourceFailure('source_cross_org_binding_unavailable');
|
|
33
|
+
}
|
|
34
|
+
if ((await this.#registry.getAppArchivedAt(reference.publisherOrg, reference.app)) !== undefined) {
|
|
35
|
+
throw sourceFailure('source_app_archived');
|
|
36
|
+
}
|
|
37
|
+
// A private installation pins an immutable deployed artifact. A newer active deployment must not
|
|
38
|
+
// disable source reads for customers still installed on the earlier, non-archived revision.
|
|
39
|
+
const target = await this.#registry.get(reference.deploymentId);
|
|
40
|
+
if (target === undefined ||
|
|
41
|
+
target.org !== reference.publisherOrg ||
|
|
42
|
+
target.app !== reference.app ||
|
|
43
|
+
target.environment !== reference.env) {
|
|
44
|
+
throw sourceFailure('source_definition_unavailable');
|
|
45
|
+
}
|
|
46
|
+
const pinned = privateDefinitionFromDeployment({ ...reference, environment: reference.env }, {
|
|
47
|
+
...target,
|
|
48
|
+
deploymentId: reference.deploymentId,
|
|
49
|
+
org: reference.publisherOrg,
|
|
50
|
+
app: reference.app,
|
|
51
|
+
environment: reference.env,
|
|
52
|
+
artifact: target.served.artifact,
|
|
53
|
+
});
|
|
54
|
+
if (pinned.reference.digest !== reference.digest) {
|
|
55
|
+
throw sourceFailure('source_definition_drift');
|
|
56
|
+
}
|
|
57
|
+
const collection = target.served.artifact.server.managedCollections?.find((candidate) => candidate.name === input.binding.collectionKey);
|
|
58
|
+
const source = collection?.source;
|
|
59
|
+
if (!collection ||
|
|
60
|
+
source === undefined ||
|
|
61
|
+
source.authority !== 'external' ||
|
|
62
|
+
!source.scan.resolved) {
|
|
63
|
+
throw sourceFailure('source_operation_unavailable');
|
|
64
|
+
}
|
|
65
|
+
assertExactOperation(source.scan, input.operation);
|
|
66
|
+
assertConfiguredCredentialBinding(source.scan, input.binding);
|
|
67
|
+
if (collection.schemaVersion !== input.binding.schemaVersion ||
|
|
68
|
+
collection.schemaDigest.replace(/^sha256:/, '') !== input.binding.schemaDigest) {
|
|
69
|
+
throw sourceFailure('source_schema_drift');
|
|
70
|
+
}
|
|
71
|
+
// The immutable publisher artifact grants operation intent only. All executable dependencies,
|
|
72
|
+
// operator values and credentials come from the currently activated installation tenant.
|
|
73
|
+
const scope = installation.scope;
|
|
74
|
+
const generation = await this.#registry.getAppGeneration(scope.org, scope.app);
|
|
75
|
+
if (generation === undefined || generation !== installation.applicationGeneration)
|
|
76
|
+
throw sourceFailure('source_installation_unavailable');
|
|
77
|
+
const current = await this.#registry.getActiveByTenant(scope);
|
|
78
|
+
const installed = current && (await this.#resolveTarget(current));
|
|
79
|
+
if (!installed ||
|
|
80
|
+
installed.org !== scope.org ||
|
|
81
|
+
installed.app !== scope.app ||
|
|
82
|
+
installed.environment !== scope.env ||
|
|
83
|
+
!installed.deploymentId ||
|
|
84
|
+
installed.deploymentId !== current?.deploymentId ||
|
|
85
|
+
installed.served.deps.tenantId !== `${scope.org}/${scope.app}/${scope.env}` ||
|
|
86
|
+
installed.served.deps.deploymentId !== installed.deploymentId) {
|
|
87
|
+
throw sourceFailure('source_installation_unavailable');
|
|
88
|
+
}
|
|
89
|
+
const installedCollection = installed.served.artifact.server.managedCollections?.find((candidate) => candidate.name === collection.name);
|
|
90
|
+
if (!installedCollection ||
|
|
91
|
+
sha256Canonical(installedCollection) !== sha256Canonical(collection)) {
|
|
92
|
+
throw sourceFailure('source_operation_drift');
|
|
93
|
+
}
|
|
94
|
+
// The live resolver pins this generation into broker acquisition. A revocation after this
|
|
95
|
+
// comparison is still rejected by the broker, without holding a database lock during I/O.
|
|
96
|
+
if (input.binding.credentialIdentity?.generation &&
|
|
97
|
+
(!input.binding.bindingReference ||
|
|
98
|
+
input.binding.credentialIdentity.generation !==
|
|
99
|
+
installed.served.deps.executionBinding?.connections[input.binding.bindingReference]))
|
|
100
|
+
throw sourceFailure('source_authorization_lost');
|
|
101
|
+
const artifact = sourceArtifact(installed.served.artifact, source.scan, input.request);
|
|
102
|
+
const check = () => this.sourceAuthority?.withCurrent(input.binding, async (identity) => {
|
|
103
|
+
if (sha256Canonical(identity ?? null) !==
|
|
104
|
+
sha256Canonical(input.binding.credentialIdentity ?? null))
|
|
105
|
+
throw new SourceCredentialError();
|
|
106
|
+
});
|
|
107
|
+
await check();
|
|
108
|
+
const deps = installed.served.deps;
|
|
109
|
+
const result = await executeTool(artifact, SOURCE_TOOL, {}, {
|
|
110
|
+
...deps,
|
|
111
|
+
broker: {
|
|
112
|
+
async getCredential(request) {
|
|
113
|
+
const value = await deps.broker.getCredential(request);
|
|
114
|
+
await check();
|
|
115
|
+
return value;
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
if (!result.ok) {
|
|
120
|
+
const code = result.error.code === 'connector_error' && result.error.reason !== undefined
|
|
121
|
+
? normalizeSourceFailureCode(result.error.reason)
|
|
122
|
+
: normalizeSourceFailureCode(result.error.code);
|
|
123
|
+
throw sourceFailure(code);
|
|
124
|
+
}
|
|
125
|
+
return result.output;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function assertConfiguredCredentialBinding(operation, binding) {
|
|
129
|
+
const credential = operation.credentialBinding;
|
|
130
|
+
if (credential === undefined ||
|
|
131
|
+
binding.bindingReference !== credential.connectionId ||
|
|
132
|
+
binding.configurationReference !== credential.connectionConfigRevision) {
|
|
133
|
+
throw sourceFailure('source_credential_binding_unavailable');
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function sourceArtifact(artifact, operationRef, request) {
|
|
137
|
+
return {
|
|
138
|
+
...artifact,
|
|
139
|
+
tools: [
|
|
140
|
+
{
|
|
141
|
+
name: SOURCE_TOOL,
|
|
142
|
+
description: 'Internal read-only collection source scan.',
|
|
143
|
+
inputSchema: {
|
|
144
|
+
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
145
|
+
type: 'object',
|
|
146
|
+
additionalProperties: false,
|
|
147
|
+
properties: {},
|
|
148
|
+
},
|
|
149
|
+
fulfilment: {
|
|
150
|
+
kind: 'operation',
|
|
151
|
+
operationRef,
|
|
152
|
+
args: literalMap(request),
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
],
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
function literalMap(value) {
|
|
159
|
+
return Object.fromEntries(Object.entries(value)
|
|
160
|
+
.filter(([, item]) => item !== undefined)
|
|
161
|
+
.map(([key, item]) => [key, literal(item)]));
|
|
162
|
+
}
|
|
163
|
+
function literal(value) {
|
|
164
|
+
if (value === null ||
|
|
165
|
+
typeof value === 'string' ||
|
|
166
|
+
typeof value === 'number' ||
|
|
167
|
+
typeof value === 'boolean') {
|
|
168
|
+
return { kind: 'literal', value };
|
|
169
|
+
}
|
|
170
|
+
if (Array.isArray(value))
|
|
171
|
+
return { kind: 'array', items: value.map(literal) };
|
|
172
|
+
if (typeof value === 'object' && value !== null) {
|
|
173
|
+
return {
|
|
174
|
+
kind: 'object',
|
|
175
|
+
entries: Object.entries(value).map(([key, item]) => ({ key, value: literal(item) })),
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
throw sourceFailure('source_request_invalid');
|
|
179
|
+
}
|
|
180
|
+
function assertExactOperation(operation, expected) {
|
|
181
|
+
if (operation.connectorId !== expected.connector ||
|
|
182
|
+
operation.connectorVersion !== expected.connectorVersion ||
|
|
183
|
+
operation.operation !== expected.operation ||
|
|
184
|
+
sourceOperationSignatureDigest(operation.signatureHash) !== expected.signatureDigest) {
|
|
185
|
+
throw sourceFailure('source_operation_drift');
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
function sourceFailure(code) {
|
|
189
|
+
return Object.assign(new Error(code.replaceAll('_', ' ')), { code });
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=source-executor.js.map
|