@smthrs/control 0.0.0-stage → 1.0.0-rc.4
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/CHANGELOG.md +194 -0
- package/LICENSE +21 -0
- package/README.md +168 -2
- package/dist/cjs/ApprovalAuthority.d.ts +73 -0
- package/dist/cjs/ApprovalAuthority.d.ts.map +1 -0
- package/dist/cjs/ApprovalAuthority.js +62 -0
- package/dist/cjs/ApprovalAuthority.js.map +7 -0
- package/dist/cjs/Cancellation.d.ts +107 -0
- package/dist/cjs/Cancellation.d.ts.map +1 -0
- package/dist/cjs/Cancellation.js +72 -0
- package/dist/cjs/Cancellation.js.map +7 -0
- package/dist/cjs/Channels.d.ts +170 -0
- package/dist/cjs/Channels.d.ts.map +1 -0
- package/dist/cjs/Channels.js +278 -0
- package/dist/cjs/Channels.js.map +7 -0
- package/dist/cjs/Control.d.ts +202 -0
- package/dist/cjs/Control.d.ts.map +1 -0
- package/dist/cjs/Control.js +47 -0
- package/dist/cjs/Control.js.map +7 -0
- package/dist/cjs/ControlClient.d.ts +52 -0
- package/dist/cjs/ControlClient.d.ts.map +1 -0
- package/dist/cjs/ControlClient.js +191 -0
- package/dist/cjs/ControlClient.js.map +7 -0
- package/dist/cjs/ControlError.d.ts +318 -0
- package/dist/cjs/ControlError.d.ts.map +1 -0
- package/dist/cjs/ControlError.js +249 -0
- package/dist/cjs/ControlError.js.map +7 -0
- package/dist/cjs/ControlExecutor.d.ts +372 -0
- package/dist/cjs/ControlExecutor.d.ts.map +1 -0
- package/dist/cjs/ControlExecutor.js +123 -0
- package/dist/cjs/ControlExecutor.js.map +7 -0
- package/dist/cjs/ControlFacts.d.ts +454 -0
- package/dist/cjs/ControlFacts.d.ts.map +1 -0
- package/dist/cjs/ControlFacts.js +261 -0
- package/dist/cjs/ControlFacts.js.map +7 -0
- package/dist/cjs/ControlLive.d.ts +23 -0
- package/dist/cjs/ControlLive.d.ts.map +1 -0
- package/dist/cjs/ControlLive.js +1293 -0
- package/dist/cjs/ControlLive.js.map +7 -0
- package/dist/cjs/ControlRpcs.d.ts +1204 -0
- package/dist/cjs/ControlRpcs.d.ts.map +1 -0
- package/dist/cjs/ControlRpcs.js +247 -0
- package/dist/cjs/ControlRpcs.js.map +7 -0
- package/dist/cjs/ControlRuntime.d.ts +635 -0
- package/dist/cjs/ControlRuntime.d.ts.map +1 -0
- package/dist/cjs/ControlRuntime.js +744 -0
- package/dist/cjs/ControlRuntime.js.map +7 -0
- package/dist/cjs/ControlSchema.d.ts +2642 -0
- package/dist/cjs/ControlSchema.d.ts.map +1 -0
- package/dist/cjs/ControlSchema.js +634 -0
- package/dist/cjs/ControlSchema.js.map +7 -0
- package/dist/cjs/ControlServer.d.ts +51 -0
- package/dist/cjs/ControlServer.d.ts.map +1 -0
- package/dist/cjs/ControlServer.js +121 -0
- package/dist/cjs/ControlServer.js.map +7 -0
- package/dist/cjs/Credential.d.ts +136 -0
- package/dist/cjs/Credential.d.ts.map +1 -0
- package/dist/cjs/Credential.js +168 -0
- package/dist/cjs/Credential.js.map +7 -0
- package/dist/cjs/CredentialCipher.d.ts +90 -0
- package/dist/cjs/CredentialCipher.d.ts.map +1 -0
- package/dist/cjs/CredentialCipher.js +45 -0
- package/dist/cjs/CredentialCipher.js.map +7 -0
- package/dist/cjs/CredentialStore.d.ts +97 -0
- package/dist/cjs/CredentialStore.d.ts.map +1 -0
- package/dist/cjs/CredentialStore.js +81 -0
- package/dist/cjs/CredentialStore.js.map +7 -0
- package/dist/cjs/DispatchReader.d.ts +112 -0
- package/dist/cjs/DispatchReader.d.ts.map +1 -0
- package/dist/cjs/DispatchReader.js +45 -0
- package/dist/cjs/DispatchReader.js.map +7 -0
- package/dist/cjs/Health.d.ts +333 -0
- package/dist/cjs/Health.d.ts.map +1 -0
- package/dist/cjs/Health.js +311 -0
- package/dist/cjs/Health.js.map +7 -0
- package/dist/cjs/JevSessionChecker.d.ts +57 -0
- package/dist/cjs/JevSessionChecker.d.ts.map +1 -0
- package/dist/cjs/JevSessionChecker.js +113 -0
- package/dist/cjs/JevSessionChecker.js.map +7 -0
- package/dist/cjs/Lineage.d.ts +131 -0
- package/dist/cjs/Lineage.d.ts.map +1 -0
- package/dist/cjs/Lineage.js +81 -0
- package/dist/cjs/Lineage.js.map +7 -0
- package/dist/cjs/Migrations.d.ts +34 -0
- package/dist/cjs/Migrations.d.ts.map +1 -0
- package/dist/cjs/Migrations.js +60 -0
- package/dist/cjs/Migrations.js.map +7 -0
- package/dist/cjs/Monitor.d.ts +282 -0
- package/dist/cjs/Monitor.d.ts.map +1 -0
- package/dist/cjs/Monitor.js +283 -0
- package/dist/cjs/Monitor.js.map +7 -0
- package/dist/cjs/ScopedToken.d.ts +193 -0
- package/dist/cjs/ScopedToken.d.ts.map +1 -0
- package/dist/cjs/ScopedToken.js +135 -0
- package/dist/cjs/ScopedToken.js.map +7 -0
- package/dist/cjs/SqlControlRuntime.d.ts +161 -0
- package/dist/cjs/SqlControlRuntime.d.ts.map +1 -0
- package/dist/cjs/SqlControlRuntime.js +1522 -0
- package/dist/cjs/SqlControlRuntime.js.map +7 -0
- package/dist/cjs/SqlCredentialStore.d.ts +43 -0
- package/dist/cjs/SqlCredentialStore.d.ts.map +1 -0
- package/dist/cjs/SqlCredentialStore.js +113 -0
- package/dist/cjs/SqlCredentialStore.js.map +7 -0
- package/dist/cjs/Steering.d.ts +69 -0
- package/dist/cjs/Steering.d.ts.map +1 -0
- package/dist/cjs/Steering.js +49 -0
- package/dist/cjs/Steering.js.map +7 -0
- package/dist/cjs/SystemFlows.d.ts +223 -0
- package/dist/cjs/SystemFlows.d.ts.map +1 -0
- package/dist/cjs/SystemFlows.js +195 -0
- package/dist/cjs/SystemFlows.js.map +7 -0
- package/dist/cjs/WebCryptoCipher.d.ts +49 -0
- package/dist/cjs/WebCryptoCipher.d.ts.map +1 -0
- package/dist/cjs/WebCryptoCipher.js +129 -0
- package/dist/cjs/WebCryptoCipher.js.map +7 -0
- package/dist/cjs/WebhookChannel.d.ts +113 -0
- package/dist/cjs/WebhookChannel.d.ts.map +1 -0
- package/dist/cjs/WebhookChannel.js +98 -0
- package/dist/cjs/WebhookChannel.js.map +7 -0
- package/dist/cjs/index.d.ts +160 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +91 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/internal/MutationBoundary.d.ts +27 -0
- package/dist/cjs/internal/MutationBoundary.d.ts.map +1 -0
- package/dist/cjs/internal/MutationBoundary.js +50 -0
- package/dist/cjs/internal/MutationBoundary.js.map +7 -0
- package/dist/cjs/internal/activeFibers.d.ts +12 -0
- package/dist/cjs/internal/activeFibers.d.ts.map +1 -0
- package/dist/cjs/internal/activeFibers.js +30 -0
- package/dist/cjs/internal/activeFibers.js.map +7 -0
- package/dist/cjs/internal/issues.d.ts +28 -0
- package/dist/cjs/internal/issues.d.ts.map +1 -0
- package/dist/cjs/internal/issues.js +34 -0
- package/dist/cjs/internal/issues.js.map +7 -0
- package/dist/cjs/internal/planning.d.ts +347 -0
- package/dist/cjs/internal/planning.d.ts.map +1 -0
- package/dist/cjs/internal/planning.js +137 -0
- package/dist/cjs/internal/planning.js.map +7 -0
- package/dist/cjs/internal/sqlSchemaErrors.d.ts +18 -0
- package/dist/cjs/internal/sqlSchemaErrors.d.ts.map +1 -0
- package/dist/cjs/internal/sqlSchemaErrors.js +40 -0
- package/dist/cjs/internal/sqlSchemaErrors.js.map +7 -0
- package/dist/cjs/migrations/0001_control_tables.d.ts +18 -0
- package/dist/cjs/migrations/0001_control_tables.d.ts.map +1 -0
- package/dist/cjs/migrations/0001_control_tables.js +115 -0
- package/dist/cjs/migrations/0001_control_tables.js.map +7 -0
- package/dist/cjs/migrations/0002_run_keys.d.ts +15 -0
- package/dist/cjs/migrations/0002_run_keys.d.ts.map +1 -0
- package/dist/cjs/migrations/0002_run_keys.js +44 -0
- package/dist/cjs/migrations/0002_run_keys.js.map +7 -0
- package/dist/cjs/migrations/0003_signal_commands.d.ts +13 -0
- package/dist/cjs/migrations/0003_signal_commands.d.ts.map +1 -0
- package/dist/cjs/migrations/0003_signal_commands.js +50 -0
- package/dist/cjs/migrations/0003_signal_commands.js.map +7 -0
- package/dist/cjs/migrations/0004_approval_decisions.d.ts +13 -0
- package/dist/cjs/migrations/0004_approval_decisions.d.ts.map +1 -0
- package/dist/cjs/migrations/0004_approval_decisions.js +45 -0
- package/dist/cjs/migrations/0004_approval_decisions.js.map +7 -0
- package/dist/cjs/migrations/0005_signal_principals.d.ts +18 -0
- package/dist/cjs/migrations/0005_signal_principals.d.ts.map +1 -0
- package/dist/cjs/migrations/0005_signal_principals.js +45 -0
- package/dist/cjs/migrations/0005_signal_principals.js.map +7 -0
- package/dist/cjs/migrations/0006_run_principals.d.ts +18 -0
- package/dist/cjs/migrations/0006_run_principals.d.ts.map +1 -0
- package/dist/cjs/migrations/0006_run_principals.js +49 -0
- package/dist/cjs/migrations/0006_run_principals.js.map +7 -0
- package/dist/cjs/migrations/0007_resume_consent.d.ts +18 -0
- package/dist/cjs/migrations/0007_resume_consent.d.ts.map +1 -0
- package/dist/cjs/migrations/0007_resume_consent.js +46 -0
- package/dist/cjs/migrations/0007_resume_consent.js.map +7 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/test/TestControl.d.ts +19 -0
- package/dist/cjs/test/TestControl.d.ts.map +1 -0
- package/dist/cjs/test/TestControl.js +62 -0
- package/dist/cjs/test/TestControl.js.map +7 -0
- package/dist/esm/ApprovalAuthority.d.ts +73 -0
- package/dist/esm/ApprovalAuthority.d.ts.map +1 -0
- package/dist/esm/ApprovalAuthority.js +72 -0
- package/dist/esm/ApprovalAuthority.js.map +1 -0
- package/dist/esm/Cancellation.d.ts +107 -0
- package/dist/esm/Cancellation.d.ts.map +1 -0
- package/dist/esm/Cancellation.js +116 -0
- package/dist/esm/Cancellation.js.map +1 -0
- package/dist/esm/Channels.d.ts +170 -0
- package/dist/esm/Channels.d.ts.map +1 -0
- package/dist/esm/Channels.js +312 -0
- package/dist/esm/Channels.js.map +1 -0
- package/dist/esm/Control.d.ts +202 -0
- package/dist/esm/Control.d.ts.map +1 -0
- package/dist/esm/Control.js +42 -0
- package/dist/esm/Control.js.map +1 -0
- package/dist/esm/ControlClient.d.ts +52 -0
- package/dist/esm/ControlClient.d.ts.map +1 -0
- package/dist/esm/ControlClient.js +217 -0
- package/dist/esm/ControlClient.js.map +1 -0
- package/dist/esm/ControlError.d.ts +318 -0
- package/dist/esm/ControlError.d.ts.map +1 -0
- package/dist/esm/ControlError.js +359 -0
- package/dist/esm/ControlError.js.map +1 -0
- package/dist/esm/ControlExecutor.d.ts +372 -0
- package/dist/esm/ControlExecutor.d.ts.map +1 -0
- package/dist/esm/ControlExecutor.js +212 -0
- package/dist/esm/ControlExecutor.js.map +1 -0
- package/dist/esm/ControlFacts.d.ts +454 -0
- package/dist/esm/ControlFacts.d.ts.map +1 -0
- package/dist/esm/ControlFacts.js +324 -0
- package/dist/esm/ControlFacts.js.map +1 -0
- package/dist/esm/ControlLive.d.ts +23 -0
- package/dist/esm/ControlLive.d.ts.map +1 -0
- package/dist/esm/ControlLive.js +1589 -0
- package/dist/esm/ControlLive.js.map +1 -0
- package/dist/esm/ControlRpcs.d.ts +1204 -0
- package/dist/esm/ControlRpcs.d.ts.map +1 -0
- package/dist/esm/ControlRpcs.js +299 -0
- package/dist/esm/ControlRpcs.js.map +1 -0
- package/dist/esm/ControlRuntime.d.ts +635 -0
- package/dist/esm/ControlRuntime.d.ts.map +1 -0
- package/dist/esm/ControlRuntime.js +808 -0
- package/dist/esm/ControlRuntime.js.map +1 -0
- package/dist/esm/ControlSchema.d.ts +2642 -0
- package/dist/esm/ControlSchema.d.ts.map +1 -0
- package/dist/esm/ControlSchema.js +1030 -0
- package/dist/esm/ControlSchema.js.map +1 -0
- package/dist/esm/ControlServer.d.ts +51 -0
- package/dist/esm/ControlServer.d.ts.map +1 -0
- package/dist/esm/ControlServer.js +145 -0
- package/dist/esm/ControlServer.js.map +1 -0
- package/dist/esm/Credential.d.ts +136 -0
- package/dist/esm/Credential.d.ts.map +1 -0
- package/dist/esm/Credential.js +190 -0
- package/dist/esm/Credential.js.map +1 -0
- package/dist/esm/CredentialCipher.d.ts +90 -0
- package/dist/esm/CredentialCipher.d.ts.map +1 -0
- package/dist/esm/CredentialCipher.js +56 -0
- package/dist/esm/CredentialCipher.js.map +1 -0
- package/dist/esm/CredentialStore.d.ts +97 -0
- package/dist/esm/CredentialStore.d.ts.map +1 -0
- package/dist/esm/CredentialStore.js +101 -0
- package/dist/esm/CredentialStore.js.map +1 -0
- package/dist/esm/DispatchReader.d.ts +112 -0
- package/dist/esm/DispatchReader.d.ts.map +1 -0
- package/dist/esm/DispatchReader.js +76 -0
- package/dist/esm/DispatchReader.js.map +1 -0
- package/dist/esm/Health.d.ts +333 -0
- package/dist/esm/Health.d.ts.map +1 -0
- package/dist/esm/Health.js +400 -0
- package/dist/esm/Health.js.map +1 -0
- package/dist/esm/JevSessionChecker.d.ts +57 -0
- package/dist/esm/JevSessionChecker.d.ts.map +1 -0
- package/dist/esm/JevSessionChecker.js +108 -0
- package/dist/esm/JevSessionChecker.js.map +1 -0
- package/dist/esm/Lineage.d.ts +131 -0
- package/dist/esm/Lineage.d.ts.map +1 -0
- package/dist/esm/Lineage.js +174 -0
- package/dist/esm/Lineage.js.map +1 -0
- package/dist/esm/Migrations.d.ts +34 -0
- package/dist/esm/Migrations.d.ts.map +1 -0
- package/dist/esm/Migrations.js +53 -0
- package/dist/esm/Migrations.js.map +1 -0
- package/dist/esm/Monitor.d.ts +282 -0
- package/dist/esm/Monitor.d.ts.map +1 -0
- package/dist/esm/Monitor.js +415 -0
- package/dist/esm/Monitor.js.map +1 -0
- package/dist/esm/ScopedToken.d.ts +193 -0
- package/dist/esm/ScopedToken.d.ts.map +1 -0
- package/dist/esm/ScopedToken.js +224 -0
- package/dist/esm/ScopedToken.js.map +1 -0
- package/dist/esm/SqlControlRuntime.d.ts +161 -0
- package/dist/esm/SqlControlRuntime.d.ts.map +1 -0
- package/dist/esm/SqlControlRuntime.js +1756 -0
- package/dist/esm/SqlControlRuntime.js.map +1 -0
- package/dist/esm/SqlCredentialStore.d.ts +43 -0
- package/dist/esm/SqlCredentialStore.d.ts.map +1 -0
- package/dist/esm/SqlCredentialStore.js +97 -0
- package/dist/esm/SqlCredentialStore.js.map +1 -0
- package/dist/esm/Steering.d.ts +69 -0
- package/dist/esm/Steering.d.ts.map +1 -0
- package/dist/esm/Steering.js +89 -0
- package/dist/esm/Steering.js.map +1 -0
- package/dist/esm/SystemFlows.d.ts +223 -0
- package/dist/esm/SystemFlows.d.ts.map +1 -0
- package/dist/esm/SystemFlows.js +198 -0
- package/dist/esm/SystemFlows.js.map +1 -0
- package/dist/esm/WebCryptoCipher.d.ts +49 -0
- package/dist/esm/WebCryptoCipher.d.ts.map +1 -0
- package/dist/esm/WebCryptoCipher.js +123 -0
- package/dist/esm/WebCryptoCipher.js.map +1 -0
- package/dist/esm/WebhookChannel.d.ts +113 -0
- package/dist/esm/WebhookChannel.d.ts.map +1 -0
- package/dist/esm/WebhookChannel.js +109 -0
- package/dist/esm/WebhookChannel.js.map +1 -0
- package/dist/esm/index.d.ts +160 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +160 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal/MutationBoundary.d.ts +27 -0
- package/dist/esm/internal/MutationBoundary.d.ts.map +1 -0
- package/dist/esm/internal/MutationBoundary.js +40 -0
- package/dist/esm/internal/MutationBoundary.js.map +1 -0
- package/dist/esm/internal/activeFibers.d.ts +12 -0
- package/dist/esm/internal/activeFibers.d.ts.map +1 -0
- package/dist/esm/internal/activeFibers.js +17 -0
- package/dist/esm/internal/activeFibers.js.map +1 -0
- package/dist/esm/internal/issues.d.ts +28 -0
- package/dist/esm/internal/issues.d.ts.map +1 -0
- package/dist/esm/internal/issues.js +35 -0
- package/dist/esm/internal/issues.js.map +1 -0
- package/dist/esm/internal/planning.d.ts +347 -0
- package/dist/esm/internal/planning.d.ts.map +1 -0
- package/dist/esm/internal/planning.js +199 -0
- package/dist/esm/internal/planning.js.map +1 -0
- package/dist/esm/internal/sqlSchemaErrors.d.ts +18 -0
- package/dist/esm/internal/sqlSchemaErrors.d.ts.map +1 -0
- package/dist/esm/internal/sqlSchemaErrors.js +38 -0
- package/dist/esm/internal/sqlSchemaErrors.js.map +1 -0
- package/dist/esm/migrations/0001_control_tables.d.ts +18 -0
- package/dist/esm/migrations/0001_control_tables.d.ts.map +1 -0
- package/dist/esm/migrations/0001_control_tables.js +96 -0
- package/dist/esm/migrations/0001_control_tables.js.map +1 -0
- package/dist/esm/migrations/0002_run_keys.d.ts +15 -0
- package/dist/esm/migrations/0002_run_keys.d.ts.map +1 -0
- package/dist/esm/migrations/0002_run_keys.js +22 -0
- package/dist/esm/migrations/0002_run_keys.js.map +1 -0
- package/dist/esm/migrations/0003_signal_commands.d.ts +13 -0
- package/dist/esm/migrations/0003_signal_commands.d.ts.map +1 -0
- package/dist/esm/migrations/0003_signal_commands.js +26 -0
- package/dist/esm/migrations/0003_signal_commands.js.map +1 -0
- package/dist/esm/migrations/0004_approval_decisions.d.ts +13 -0
- package/dist/esm/migrations/0004_approval_decisions.d.ts.map +1 -0
- package/dist/esm/migrations/0004_approval_decisions.js +25 -0
- package/dist/esm/migrations/0004_approval_decisions.js.map +1 -0
- package/dist/esm/migrations/0005_signal_principals.d.ts +18 -0
- package/dist/esm/migrations/0005_signal_principals.d.ts.map +1 -0
- package/dist/esm/migrations/0005_signal_principals.js +27 -0
- package/dist/esm/migrations/0005_signal_principals.js.map +1 -0
- package/dist/esm/migrations/0006_run_principals.d.ts +18 -0
- package/dist/esm/migrations/0006_run_principals.d.ts.map +1 -0
- package/dist/esm/migrations/0006_run_principals.js +30 -0
- package/dist/esm/migrations/0006_run_principals.js.map +1 -0
- package/dist/esm/migrations/0007_resume_consent.d.ts +18 -0
- package/dist/esm/migrations/0007_resume_consent.d.ts.map +1 -0
- package/dist/esm/migrations/0007_resume_consent.js +27 -0
- package/dist/esm/migrations/0007_resume_consent.js.map +1 -0
- package/dist/esm/test/TestControl.d.ts +19 -0
- package/dist/esm/test/TestControl.d.ts.map +1 -0
- package/dist/esm/test/TestControl.js +30 -0
- package/dist/esm/test/TestControl.js.map +1 -0
- package/docs/README.md +189 -0
- package/docs/api.md +982 -0
- package/docs/concepts/authority.md +109 -0
- package/docs/concepts/cancellation.md +129 -0
- package/docs/concepts/lineage.md +132 -0
- package/docs/concepts/ownership.md +139 -0
- package/docs/concepts/projections.md +203 -0
- package/docs/concepts/receipts.md +128 -0
- package/docs/guides/approvals.md +284 -0
- package/docs/guides/cancel-and-resume.md +162 -0
- package/docs/guides/durable-storage.md +147 -0
- package/docs/guides/implement-an-executor.md +173 -0
- package/docs/guides/ingest-a-webhook.md +177 -0
- package/docs/guides/list-runs.md +160 -0
- package/docs/guides/monitor-runs.md +176 -0
- package/docs/guides/observe-health.md +147 -0
- package/docs/guides/postgres-tests.md +7 -0
- package/docs/guides/serve-over-rpc.md +220 -0
- package/docs/guides/signal-a-run.md +53 -0
- package/docs/guides/steer-a-run.md +138 -0
- package/docs/guides/store-credentials.md +164 -0
- package/docs/guides/testing.md +139 -0
- package/docs/guides/watch-a-run.md +154 -0
- package/docs/installation.md +106 -0
- package/docs/quickstart.md +163 -0
- package/docs/troubleshooting.md +208 -0
- package/package.json +405 -3
- package/src/ApprovalAuthority.ts +114 -0
- package/src/Cancellation.ts +172 -0
- package/src/Channels.ts +493 -0
- package/src/Control.ts +337 -0
- package/src/ControlClient.ts +319 -0
- package/src/ControlError.ts +378 -0
- package/src/ControlExecutor.ts +490 -0
- package/src/ControlFacts.ts +383 -0
- package/src/ControlLive.ts +2127 -0
- package/src/ControlRpcs.ts +443 -0
- package/src/ControlRuntime.ts +1601 -0
- package/src/ControlSchema.ts +1380 -0
- package/src/ControlServer.ts +182 -0
- package/src/Credential.ts +310 -0
- package/src/CredentialCipher.ts +110 -0
- package/src/CredentialStore.ts +152 -0
- package/src/DispatchReader.ts +122 -0
- package/src/Health.ts +591 -0
- package/src/JevSessionChecker.ts +127 -0
- package/src/Lineage.ts +203 -0
- package/src/Migrations.ts +56 -0
- package/src/Monitor.ts +600 -0
- package/src/ScopedToken.ts +306 -0
- package/src/SqlControlRuntime.ts +2478 -0
- package/src/SqlCredentialStore.ts +148 -0
- package/src/Steering.ts +96 -0
- package/src/SystemFlows.ts +225 -0
- package/src/WebCryptoCipher.ts +169 -0
- package/src/WebhookChannel.ts +166 -0
- package/src/index.ts +188 -0
- package/src/internal/MutationBoundary.ts +46 -0
- package/src/internal/activeFibers.ts +22 -0
- package/src/internal/issues.ts +40 -0
- package/src/internal/planning.ts +262 -0
- package/src/internal/sqlSchemaErrors.ts +37 -0
- package/src/migrations/0001_control_tables.ts +99 -0
- package/src/migrations/0002_run_keys.ts +23 -0
- package/src/migrations/0003_signal_commands.ts +27 -0
- package/src/migrations/0004_approval_decisions.ts +25 -0
- package/src/migrations/0005_signal_principals.ts +27 -0
- package/src/migrations/0006_run_principals.ts +31 -0
- package/src/migrations/0007_resume_consent.ts +28 -0
- package/src/test/TestControl.ts +47 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook channel construction over Effect's transport-neutral HTTP request.
|
|
3
|
+
*
|
|
4
|
+
* @since 0.1.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Effect, type Redacted, Schema, Stream } from "effect"
|
|
8
|
+
import * as HttpServerRequest from "effect/unstable/http/HttpServerRequest"
|
|
9
|
+
import { type Channel, Channels, type InboundResult, type RawInbound } from "./Channels.ts"
|
|
10
|
+
import { InvalidInput, type Unauthorized } from "./ControlError.ts"
|
|
11
|
+
import type { IdempotencyKey } from "./ControlSchema.ts"
|
|
12
|
+
import type { CredentialRef } from "./Credential.ts"
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Signature verifier injected by a webhook transport.
|
|
16
|
+
*
|
|
17
|
+
* The credential is intentionally a redacted reference. Resolution belongs at
|
|
18
|
+
* the host adapter boundary, never in webhook input or its persisted record.
|
|
19
|
+
*
|
|
20
|
+
* @category models
|
|
21
|
+
* @since 0.1.0
|
|
22
|
+
*/
|
|
23
|
+
export type SignatureVerifier = (
|
|
24
|
+
raw: RawInbound,
|
|
25
|
+
credential: Redacted.Redacted<CredentialRef>
|
|
26
|
+
) => Effect.Effect<void, Unauthorized>
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Configuration for a schema-declared webhook channel.
|
|
30
|
+
*
|
|
31
|
+
* @category models
|
|
32
|
+
* @since 0.1.0
|
|
33
|
+
*/
|
|
34
|
+
export interface Config<A> {
|
|
35
|
+
readonly name: string
|
|
36
|
+
readonly schema: Schema.Schema<A>
|
|
37
|
+
readonly credential: Redacted.Redacted<CredentialRef>
|
|
38
|
+
readonly fingerprintHeaders?: Channel<A>["fingerprintHeaders"]
|
|
39
|
+
readonly verify: SignatureVerifier
|
|
40
|
+
readonly map: (payload: A) => Effect.Effect<InboundResult, InvalidInput>
|
|
41
|
+
readonly project: Channel<A>["project"]
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const invalidInput = (issue: string): InvalidInput => new InvalidInput({ issue })
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Largest webhook request body one mount reads by default, in bytes.
|
|
48
|
+
*
|
|
49
|
+
* A webhook is the one control-plane ingress a bearer holder reaches with an
|
|
50
|
+
* arbitrary payload, and `handler` used to materialize whatever arrived before
|
|
51
|
+
* anything looked at its size. The default is deliberately smaller than the
|
|
52
|
+
* 4 MiB mutation-identity budget in `internal/mutationBoundary.ts`: a body that
|
|
53
|
+
* cannot become a durable mutation is refused at the door rather than copied,
|
|
54
|
+
* decoded, and refused later.
|
|
55
|
+
*
|
|
56
|
+
* @category constants
|
|
57
|
+
* @since 1.0.0-rc.0
|
|
58
|
+
*/
|
|
59
|
+
export const maximumBodyBytes = 1024 * 1024
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Per-mount overrides for the webhook request handler.
|
|
63
|
+
*
|
|
64
|
+
* @category models
|
|
65
|
+
* @since 1.0.0-rc.0
|
|
66
|
+
*/
|
|
67
|
+
export interface HandlerOptions {
|
|
68
|
+
/** Body ceiling for this mount. Defaults to `maximumBodyBytes`. */
|
|
69
|
+
readonly maximumBodyBytes?: number | undefined
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* The declared body length, when the caller stated one this host can trust.
|
|
74
|
+
*
|
|
75
|
+
* Header names arrive lower-cased from Effect's HTTP layer, but a hand-built
|
|
76
|
+
* request is not obliged to, so the lookup folds case itself. An absent,
|
|
77
|
+
* non-numeric, fractional, or negative declaration is not evidence of
|
|
78
|
+
* anything: it falls through to the streaming measurement rather than being
|
|
79
|
+
* treated as zero.
|
|
80
|
+
*/
|
|
81
|
+
const declaredLength = (headers: Readonly<Record<string, string | undefined>>): number | undefined => {
|
|
82
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
83
|
+
if (name.toLowerCase() !== "content-length" || value === undefined) continue
|
|
84
|
+
const parsed = Number(value.trim())
|
|
85
|
+
return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : undefined
|
|
86
|
+
}
|
|
87
|
+
return undefined
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Builds a webhook channel. Verification receives raw bytes and headers before
|
|
92
|
+
* JSON parsing and schema decoding.
|
|
93
|
+
*
|
|
94
|
+
* @category constructors
|
|
95
|
+
* @since 0.1.0
|
|
96
|
+
*/
|
|
97
|
+
export const make = <A>(config: Config<A>): Channel<A> => {
|
|
98
|
+
const decode = Schema.decodeUnknownEffect(config.schema)
|
|
99
|
+
return {
|
|
100
|
+
name: config.name,
|
|
101
|
+
schema: config.schema,
|
|
102
|
+
...(config.fingerprintHeaders === undefined ? {} : { fingerprintHeaders: config.fingerprintHeaders }),
|
|
103
|
+
verify: Effect.fn("WebhookChannel.verify")((raw) => config.verify(raw, config.credential)),
|
|
104
|
+
decode: Effect.fn("WebhookChannel.decode")((raw) =>
|
|
105
|
+
Effect.try({
|
|
106
|
+
try: () => JSON.parse(new TextDecoder().decode(raw.body)),
|
|
107
|
+
catch: () => invalidInput("invalid webhook JSON")
|
|
108
|
+
}).pipe(
|
|
109
|
+
Effect.flatMap((json) => decode(json)),
|
|
110
|
+
Effect.mapError((cause) => cause instanceof InvalidInput ? cause : invalidInput(String(cause)))
|
|
111
|
+
) as Effect.Effect<A, InvalidInput>
|
|
112
|
+
),
|
|
113
|
+
map: Effect.fn("WebhookChannel.map")((payload) => config.map(payload)),
|
|
114
|
+
project: config.project
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Reads an abstract Effect HTTP request and dispatches it through Channels.
|
|
120
|
+
* This is mountable by any Effect HTTP host; it contains no Node transport
|
|
121
|
+
* dependencies.
|
|
122
|
+
*
|
|
123
|
+
* The body is bounded twice. A `content-length` over the limit is refused
|
|
124
|
+
* before the body is read at all, so a declared flood costs nothing; the
|
|
125
|
+
* measured length is checked before retaining each streamed chunk. Reading
|
|
126
|
+
* stops at the first chunk exceeding the limit, including when the caller
|
|
127
|
+
* understates or omits the length. Both refusals are `InvalidInput` naming the
|
|
128
|
+
* two byte counts and no body content.
|
|
129
|
+
*
|
|
130
|
+
* @category handlers
|
|
131
|
+
* @since 0.1.0
|
|
132
|
+
*/
|
|
133
|
+
export const handler = (
|
|
134
|
+
channel: string,
|
|
135
|
+
idempotencyKey: IdempotencyKey,
|
|
136
|
+
options?: HandlerOptions | undefined
|
|
137
|
+
) =>
|
|
138
|
+
Effect.gen(function*() {
|
|
139
|
+
const limit = options?.maximumBodyBytes ?? maximumBodyBytes
|
|
140
|
+
const request = yield* HttpServerRequest.HttpServerRequest
|
|
141
|
+
const declared = declaredLength(request.headers)
|
|
142
|
+
if (declared !== undefined && declared > limit) {
|
|
143
|
+
return yield* invalidInput(`webhook body: declared ${declared} bytes exceeds the ${limit} byte limit`)
|
|
144
|
+
}
|
|
145
|
+
const chunks: Array<Uint8Array> = []
|
|
146
|
+
let size = 0
|
|
147
|
+
yield* Stream.runForEach(request.stream, (chunk) =>
|
|
148
|
+
Effect.gen(function*() {
|
|
149
|
+
size += chunk.byteLength
|
|
150
|
+
if (size > limit) {
|
|
151
|
+
return yield* invalidInput(`webhook body: ${size} bytes exceeds the ${limit} byte limit`)
|
|
152
|
+
}
|
|
153
|
+
if (chunk.byteLength > 0) chunks.push(chunk.slice())
|
|
154
|
+
}))
|
|
155
|
+
const body = new Uint8Array(size)
|
|
156
|
+
let offset = 0
|
|
157
|
+
for (const chunk of chunks) {
|
|
158
|
+
body.set(chunk, offset)
|
|
159
|
+
offset += chunk.byteLength
|
|
160
|
+
}
|
|
161
|
+
const channels = yield* Channels
|
|
162
|
+
return yield* channels.ingest({
|
|
163
|
+
channel,
|
|
164
|
+
raw: { body, headers: request.headers, idempotencyKey }
|
|
165
|
+
})
|
|
166
|
+
})
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Control-plane contracts and projections for the Smithers harness.
|
|
3
|
+
*
|
|
4
|
+
* This is the public surface of the control plane: the transport-independent
|
|
5
|
+
* `Control` service, the `ControlRuntime` port it writes through, the
|
|
6
|
+
* projections it reads back, and the durable adapter that binds both to a real
|
|
7
|
+
* database.
|
|
8
|
+
*
|
|
9
|
+
* `Control` is authority, not execution. Every mutation it accepts is
|
|
10
|
+
* idempotent, principal-stamped, and recorded in the journal beside the state
|
|
11
|
+
* change it caused, so "who asked for this, and when did it take effect?" is
|
|
12
|
+
* answered from persisted evidence rather than from a log line.
|
|
13
|
+
*
|
|
14
|
+
* @since 0.1.0
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @category services
|
|
19
|
+
* @since 0.1.0
|
|
20
|
+
*/
|
|
21
|
+
export * as Control from "./Control.ts"
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @category services
|
|
25
|
+
* @since 1.0.0
|
|
26
|
+
*/
|
|
27
|
+
export * as ApprovalAuthority from "./ApprovalAuthority.ts"
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @category errors
|
|
31
|
+
* @since 0.1.0
|
|
32
|
+
*/
|
|
33
|
+
export * as ControlError from "./ControlError.ts"
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @category models
|
|
37
|
+
* @since 0.1.0
|
|
38
|
+
*/
|
|
39
|
+
export * as ControlSchema from "./ControlSchema.ts"
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @category projections
|
|
43
|
+
* @since 0.1.0
|
|
44
|
+
*/
|
|
45
|
+
export * as Cancellation from "./Cancellation.ts"
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @category projections
|
|
49
|
+
* @since 0.1.0
|
|
50
|
+
*/
|
|
51
|
+
export * as Lineage from "./Lineage.ts"
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @category projections
|
|
55
|
+
* @since 0.1.0
|
|
56
|
+
*/
|
|
57
|
+
export * as Monitor from "./Monitor.ts"
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @category projections
|
|
61
|
+
* @since 0.1.0
|
|
62
|
+
*/
|
|
63
|
+
export * as Steering from "./Steering.ts"
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @category services
|
|
67
|
+
* @since 0.1.0
|
|
68
|
+
*/
|
|
69
|
+
export * as ControlRuntime from "./ControlRuntime.ts"
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @category services
|
|
73
|
+
* @since 0.1.0
|
|
74
|
+
*/
|
|
75
|
+
export * as ControlExecutor from "./ControlExecutor.ts"
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @category services
|
|
79
|
+
* @since 1.0.0
|
|
80
|
+
*/
|
|
81
|
+
export * as DispatchReader from "./DispatchReader.ts"
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @category layers
|
|
85
|
+
* @since 0.1.0
|
|
86
|
+
*/
|
|
87
|
+
export * as ControlLive from "./ControlLive.ts"
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @category models
|
|
91
|
+
* @since 0.1.0
|
|
92
|
+
*/
|
|
93
|
+
export * as SystemFlows from "./SystemFlows.ts"
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @category rpc
|
|
97
|
+
* @since 0.1.0
|
|
98
|
+
*/
|
|
99
|
+
export * as ControlRpcs from "./ControlRpcs.ts"
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @category layers
|
|
103
|
+
* @since 0.1.0
|
|
104
|
+
*/
|
|
105
|
+
export * as ControlServer from "./ControlServer.ts"
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* @category layers
|
|
109
|
+
* @since 0.1.0
|
|
110
|
+
*/
|
|
111
|
+
export * as ControlClient from "./ControlClient.ts"
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* @category services
|
|
115
|
+
* @since 0.1.0
|
|
116
|
+
*/
|
|
117
|
+
export * as Channels from "./Channels.ts"
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @category channels
|
|
121
|
+
* @since 0.1.0
|
|
122
|
+
*/
|
|
123
|
+
export * as WebhookChannel from "./WebhookChannel.ts"
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* @category services
|
|
127
|
+
* @since 0.1.0
|
|
128
|
+
*/
|
|
129
|
+
export * as Credential from "./Credential.ts"
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @category services
|
|
133
|
+
* @since 0.1.0
|
|
134
|
+
*/
|
|
135
|
+
export * as CredentialCipher from "./CredentialCipher.ts"
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* @category services
|
|
139
|
+
* @since 0.1.0
|
|
140
|
+
*/
|
|
141
|
+
export * as CredentialStore from "./CredentialStore.ts"
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* @category layers
|
|
145
|
+
* @since 0.1.0
|
|
146
|
+
*/
|
|
147
|
+
export * as SqlCredentialStore from "./SqlCredentialStore.ts"
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @category layers
|
|
151
|
+
* @since 0.1.0
|
|
152
|
+
*/
|
|
153
|
+
export * as WebCryptoCipher from "./WebCryptoCipher.ts"
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* @category layers
|
|
157
|
+
* @since 0.1.0
|
|
158
|
+
*/
|
|
159
|
+
export * as SqlControlRuntime from "./SqlControlRuntime.ts"
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* @category authentication
|
|
163
|
+
* @since 1.0.0
|
|
164
|
+
*/
|
|
165
|
+
export * as ScopedToken from "./ScopedToken.ts"
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @category migrations
|
|
169
|
+
* @since 0.1.0
|
|
170
|
+
*/
|
|
171
|
+
export * as Migrations from "./Migrations.ts"
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Observational health contracts.
|
|
175
|
+
* @category health
|
|
176
|
+
* @since 1.0.0
|
|
177
|
+
*/
|
|
178
|
+
export * as Health from "./Health.ts"
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* The Jev-decided session checker a host binds as `jev.session`.
|
|
182
|
+
* @category health
|
|
183
|
+
* @since 1.0.0
|
|
184
|
+
*/
|
|
185
|
+
export * as JevSessionChecker from "./JevSessionChecker.ts"
|
|
186
|
+
|
|
187
|
+
/** Versioned control lifecycle producer and projection contract. */
|
|
188
|
+
export * as ControlFacts from "./ControlFacts.ts"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounded inert JSON admission for control mutations.
|
|
3
|
+
*
|
|
4
|
+
* @since 1.0.0-rc.0
|
|
5
|
+
* @private
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import * as BoundedJson from "@smthrs/canonical/BoundedJson"
|
|
9
|
+
|
|
10
|
+
/** Limits and diagnostic precedence of the control mutation boundary. */
|
|
11
|
+
const limits = {
|
|
12
|
+
maxBytes: 4 * 1024 * 1024,
|
|
13
|
+
maxStringBytes: 4 * 1024 * 1024,
|
|
14
|
+
maxKeyBytes: 4 * 1024 * 1024,
|
|
15
|
+
maxDepth: 128,
|
|
16
|
+
maxNodes: 100_000,
|
|
17
|
+
maxMembers: 100_000,
|
|
18
|
+
maxTotalMembers: 100_000
|
|
19
|
+
} satisfies BoundedJson.Limits
|
|
20
|
+
|
|
21
|
+
/** Result of admitting an unknown mutation value. */
|
|
22
|
+
type Result =
|
|
23
|
+
| { readonly ok: true; readonly value: BoundedJson.Json }
|
|
24
|
+
| { readonly ok: false; readonly complaint: string }
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Copies one mutation without invoking getters or `toJSON`.
|
|
28
|
+
*
|
|
29
|
+
* `bounds` defaults to the control mutation limits. Tests pass smaller ones to
|
|
30
|
+
* reach a byte-exact boundary without building multi-megabyte values.
|
|
31
|
+
*
|
|
32
|
+
* @since 1.0.0-rc.0
|
|
33
|
+
* @private
|
|
34
|
+
*/
|
|
35
|
+
export const admit = (input: unknown, bounds: BoundedJson.Limits = limits): Result => {
|
|
36
|
+
const result = BoundedJson.admit(input, bounds, { preflightObjects: false })
|
|
37
|
+
if (result.ok) return { ok: true, value: result.value }
|
|
38
|
+
const complaint = result.code === "members"
|
|
39
|
+
? `contains more than ${bounds.maxTotalMembers} JSON members`
|
|
40
|
+
: result.code === "string"
|
|
41
|
+
? "contains oversized or ill-formed text"
|
|
42
|
+
: result.code === "key"
|
|
43
|
+
? "contains an oversized or ill-formed object key"
|
|
44
|
+
: result.complaint
|
|
45
|
+
return { ok: false, complaint }
|
|
46
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Completion-aware, replacement-safe ownership of live fibers.
|
|
3
|
+
* @since 1.0.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type * as Fiber from "effect/Fiber"
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A completed predecessor must never unregister its replacement.
|
|
10
|
+
* @category registration
|
|
11
|
+
* @since 1.0.0
|
|
12
|
+
*/
|
|
13
|
+
export const register = <K>(
|
|
14
|
+
fibers: Map<K, Fiber.Fiber<unknown, unknown>>,
|
|
15
|
+
key: K,
|
|
16
|
+
fiber: Fiber.Fiber<unknown, unknown>
|
|
17
|
+
): void => {
|
|
18
|
+
fibers.set(key, fiber)
|
|
19
|
+
fiber.addObserver(() => {
|
|
20
|
+
if (fibers.get(key) === fiber) fibers.delete(key)
|
|
21
|
+
})
|
|
22
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounded diagnostics for failures that cross the control wire boundary.
|
|
3
|
+
*
|
|
4
|
+
* @since 0.1.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { CanonicalError } from "@smthrs/canonical"
|
|
8
|
+
|
|
9
|
+
const maximumIssueLength = 512
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Joins a stable location and reason without allowing an RPC error to grow
|
|
13
|
+
* without bound.
|
|
14
|
+
*
|
|
15
|
+
* @private
|
|
16
|
+
* @since 0.1.0
|
|
17
|
+
*/
|
|
18
|
+
export const cappedIssue = (path: string, reason: string): string => {
|
|
19
|
+
const issue = `${path}: ${reason}`
|
|
20
|
+
return issue.length <= maximumIssueLength ? issue : `${issue.slice(0, maximumIssueLength - 3)}...`
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Renders canonical's stable located failure without copying its rejected
|
|
25
|
+
* value or a nested cause message into an RPC error.
|
|
26
|
+
*
|
|
27
|
+
* @private
|
|
28
|
+
* @since 0.1.0
|
|
29
|
+
*/
|
|
30
|
+
export const canonicalIssue = (cause: unknown): string =>
|
|
31
|
+
cause instanceof CanonicalError
|
|
32
|
+
? cappedIssue(cause.path, cause.code)
|
|
33
|
+
: cappedIssue("$", "canonicalization failed")
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Finds the first rejected field without rendering its value.
|
|
37
|
+
* @private
|
|
38
|
+
* @since 0.1.0
|
|
39
|
+
*/
|
|
40
|
+
export { firstPath as schemaIssuePath } from "@smthrs/canonical/IssuePath"
|