@voltro/protocol 0.85.0 → 0.87.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/CHANGELOG.md +5987 -0
- package/README.md +14 -0
- package/THIRD-PARTY-NOTICES.md +1122 -31
- package/dist/apiRoleEndpoints.js +108 -0
- package/dist/apiRoleObservation.js +68 -0
- package/dist/apikey.d.ts +10 -0
- package/dist/approval.js +64 -0
- package/dist/approvalDescriptors.js +26 -0
- package/dist/auth.js +389 -0
- package/dist/boundedRing.js +27 -0
- package/dist/businessRule.js +11 -0
- package/dist/canonicalJson.js +14 -0
- package/dist/connection.js +73 -0
- package/dist/devActivity.js +4 -0
- package/dist/errorSchema.js +24 -0
- package/dist/errorValue.js +21 -0
- package/dist/event.js +110 -0
- package/dist/formCapture.js +12 -0
- package/dist/httpStreamMaxDuration.js +9 -0
- package/dist/idempotency.js +121 -0
- package/dist/idempotencyInput.js +123 -0
- package/dist/identity.js +5 -9
- package/dist/index.d.ts +1095 -139
- package/dist/index.js +54 -1700
- package/dist/inspect.d.ts +1 -1
- package/dist/inspect.js +14 -240
- package/dist/inspectBackfill.js +52 -0
- package/dist/inspectCommandRejection.js +21 -0
- package/dist/inspectProjection.js +133 -0
- package/dist/inspectStorageProjection.js +86 -0
- package/dist/inspectValueIdentity.js +4 -0
- package/dist/inspectWorkflowExecution.js +34 -0
- package/dist/inspectWorkflowQueuedStart.js +31 -0
- package/dist/jsonSchema.js +54 -0
- package/dist/jwt.d.ts +10 -0
- package/dist/jwt.js +1 -1
- package/dist/outbox.js +10 -0
- package/dist/pairing.js +75 -0
- package/dist/plugin.js +87 -0
- package/dist/pluginAccountMerge.js +88 -0
- package/dist/pluginNaming.js +32 -0
- package/dist/pluginPrivacy.js +166 -0
- package/dist/procedure.js +280 -0
- package/dist/publicApi.js +325 -0
- package/dist/queryOptionalSources.js +14 -0
- package/dist/reactivityChannel.js +34 -0
- package/dist/rest.d.ts +260 -64
- package/dist/rest.js +345 -499
- package/dist/restFormat.js +163 -0
- package/dist/restReceipt.js +43 -0
- package/dist/revalidate.js +13 -0
- package/dist/rowEquality.js +31 -0
- package/dist/rowPatch.js +182 -0
- package/dist/schemaShape.js +67 -0
- package/dist/scopes.js +273 -0
- package/dist/secretWindows.js +71 -0
- package/dist/serverErrorBus.js +15 -0
- package/dist/serviceCall.js +14 -0
- package/dist/session.d.ts +89 -6
- package/dist/session.js +62 -63
- package/dist/{sessionHeader-DriTZhmv.js → sessionHeader.js} +1 -1
- package/dist/ssrfPolicy.js +30 -0
- package/dist/storageAccess.js +14 -0
- package/dist/storeErrors.js +66 -0
- package/dist/storeScreenshots.js +90 -0
- package/dist/strictInput.js +27 -0
- package/dist/subscriptionEvent.js +37 -0
- package/dist/tenantSelection.js +40 -0
- package/dist/time.js +7 -0
- package/dist/undo.js +38 -0
- package/dist/validation.js +39 -0
- package/dist/webSocketGateway.js +16 -0
- package/dist/workflow.js +297 -0
- package/dist/workflowAccess.js +61 -0
- package/dist/workflowRestart.js +45 -0
- package/dist/workflowRetry.js +44 -0
- package/dist/workflowStartOutcome.js +30 -0
- package/package.json +5 -3
- package/dist/restFormat-BlgTLxm1.js +0 -298
- package/dist/scopes-ClywBij8.js +0 -548
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,23 @@
|
|
|
1
|
+
import { ConnectionKind as ConnectionKind_2 } from '@voltro/kv/connection';
|
|
2
|
+
import { ConnectionRef } from '@voltro/kv/connection';
|
|
3
|
+
import { ConnectionRegistryShape } from '@voltro/kv/connection';
|
|
4
|
+
import { ConnectionUnavailablePolicy } from '@voltro/kv/connection';
|
|
1
5
|
import { Context } from 'effect';
|
|
2
6
|
import { DataStore } from '@voltro/database';
|
|
3
7
|
import { Effect } from 'effect';
|
|
8
|
+
import { HotStoreShape } from '@voltro/kv/hot/contract';
|
|
4
9
|
import { Layer } from 'effect';
|
|
5
10
|
import { Option } from 'effect';
|
|
6
11
|
import { Rpc } from 'effect/rpc';
|
|
7
12
|
import { RpcMiddleware } from 'effect/rpc';
|
|
8
13
|
import { Schema } from 'effect';
|
|
9
14
|
import { SchemaAST } from 'effect';
|
|
15
|
+
import { Scope } from 'effect';
|
|
10
16
|
import { SqlClient } from 'effect/sql';
|
|
17
|
+
import { StorageAddress } from '@voltro/kv/storage';
|
|
18
|
+
import { StorageDestinationRouter } from '@voltro/kv/storage';
|
|
19
|
+
import { StorageError } from '@voltro/kv/storage';
|
|
20
|
+
import { StorageProvider } from '@voltro/kv/storage';
|
|
11
21
|
import { Stream } from 'effect/rpc/RpcSchema';
|
|
12
22
|
import { VersionConflict } from '@voltro/database/wire';
|
|
13
23
|
import { YieldableError } from 'effect/Cause';
|
|
@@ -137,7 +147,7 @@ export declare interface AnyApprovalPolicy {
|
|
|
137
147
|
|
|
138
148
|
/** A guard entry is a scope check, a relationship check, an identity check, a
|
|
139
149
|
* declared no-check-needed decision, or a service-only decision. */
|
|
140
|
-
export declare type AnyCheckSpec = GuardCheckSpec | PolicyCheckSpec | AuthenticatedCheckSpec | OpenAccessSpec | ServiceAccessSpec;
|
|
150
|
+
export declare type AnyCheckSpec = GuardCheckSpec | PolicyCheckSpec | AuthenticatedCheckSpec | UpgradedCheckSpec | OpenAccessSpec | ServiceAccessSpec;
|
|
141
151
|
|
|
142
152
|
/** Any declared event, with the generics erased — for registries and audits. */
|
|
143
153
|
/** The erased descriptor every registry holds. `guards` reads the key type
|
|
@@ -147,7 +157,10 @@ export declare type AnyCheckSpec = GuardCheckSpec | PolicyCheckSpec | Authentica
|
|
|
147
157
|
export declare type AnyEventDescriptor = EventDescriptor<string, Schema.Top, Schema.Top, DeclaredAccess<never>>;
|
|
148
158
|
|
|
149
159
|
/** A guard is a scope check, a relationship check, or an identity check. */
|
|
150
|
-
export declare type AnyGuardSpec<Input = unknown> = GuardSpec<Input> | PolicyGuardSpec<Input> | AuthenticatedGuardSpec;
|
|
160
|
+
export declare type AnyGuardSpec<Input = unknown> = GuardSpec<Input> | PolicyGuardSpec<Input> | AuthenticatedGuardSpec | UpgradedGuardSpec;
|
|
161
|
+
|
|
162
|
+
/** Work performed by an API process; schema and descriptor loading is separate. */
|
|
163
|
+
export declare const API_WORKLOADS: readonly ["rpc", "subscriptions", "events", "presence", "workflows", "schedules", "directors", "drainers", "reapers", "retention", "rest", "webhooks", "inspect", "cdc"];
|
|
151
164
|
|
|
152
165
|
export declare const APIKEY_ISSUE_ORG_SCOPE = "apikeys:issue:org";
|
|
153
166
|
|
|
@@ -180,6 +193,118 @@ export declare const APIKEY_ISSUE_OTHER_SCOPE = "apikeys:issue:other";
|
|
|
180
193
|
*/
|
|
181
194
|
export declare const APIKEY_ISSUE_SELF_SCOPE = "apikeys:issue:self";
|
|
182
195
|
|
|
196
|
+
export declare interface ApiRoleEndpoint {
|
|
197
|
+
readonly role: string;
|
|
198
|
+
readonly routes: ReadonlyArray<string> | null;
|
|
199
|
+
readonly workloads: ReadonlyArray<string>;
|
|
200
|
+
readonly httpPath: string | null;
|
|
201
|
+
readonly webSocketPath: string;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export declare interface ApiRoleEndpoints {
|
|
205
|
+
readonly version: 1;
|
|
206
|
+
readonly transport: 'compose-nginx' | 'kubernetes-nginx';
|
|
207
|
+
readonly roles: ReadonlyArray<ApiRoleEndpoint>;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export declare const apiRoleEndpointUrl: (baseUrl: string, endpoint: ApiRoleEndpoint, transport: "http" | "websocket") => string;
|
|
211
|
+
|
|
212
|
+
export declare interface ApiRoleObservationReport {
|
|
213
|
+
readonly replicaId: string;
|
|
214
|
+
readonly startedAt: number;
|
|
215
|
+
readonly role: string;
|
|
216
|
+
readonly workloads: ReadonlyArray<ApiWorkload>;
|
|
217
|
+
readonly capturedAt: number;
|
|
218
|
+
readonly publisher: {
|
|
219
|
+
readonly ready: boolean;
|
|
220
|
+
readonly stopped: boolean;
|
|
221
|
+
readonly pendingBuckets: number;
|
|
222
|
+
readonly droppedBuckets: number;
|
|
223
|
+
readonly rejectedSegments: number;
|
|
224
|
+
readonly writeFailures: number;
|
|
225
|
+
readonly observationErrors: number;
|
|
226
|
+
};
|
|
227
|
+
readonly currentMeasuredSeconds: ReadonlyArray<{
|
|
228
|
+
readonly role: string;
|
|
229
|
+
readonly workload: ApiWorkload;
|
|
230
|
+
readonly seconds: number;
|
|
231
|
+
}>;
|
|
232
|
+
readonly history: {
|
|
233
|
+
readonly state: 'pending' | 'available' | 'unavailable';
|
|
234
|
+
readonly assessment: ApiRoleWindowAssessment | null;
|
|
235
|
+
/** Measured portions only; no share is inferred from incomplete coverage. */
|
|
236
|
+
readonly measuredSeconds: ReadonlyArray<{
|
|
237
|
+
readonly workload: ApiWorkload;
|
|
238
|
+
readonly seconds: number;
|
|
239
|
+
}>;
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/** Browser-safe wire contract; no runtime or database imports. */
|
|
244
|
+
export declare const ApiRoleObservationSchema: Schema.Struct<{
|
|
245
|
+
readonly replicaId: Schema.NonEmptyString;
|
|
246
|
+
readonly startedAt: Schema.Number;
|
|
247
|
+
readonly role: Schema.NonEmptyString;
|
|
248
|
+
readonly workloads: Schema.$Array<Schema.Literals<readonly ["rpc", "subscriptions", "events", "presence", "workflows", "schedules", "directors", "drainers", "reapers", "retention", "rest", "webhooks", "inspect", "cdc"]>>;
|
|
249
|
+
readonly capturedAt: Schema.Number;
|
|
250
|
+
readonly publisher: Schema.Struct<{
|
|
251
|
+
readonly ready: Schema.Boolean;
|
|
252
|
+
readonly stopped: Schema.Boolean;
|
|
253
|
+
readonly pendingBuckets: Schema.Number;
|
|
254
|
+
readonly droppedBuckets: Schema.Number;
|
|
255
|
+
readonly rejectedSegments: Schema.Number;
|
|
256
|
+
readonly writeFailures: Schema.Number;
|
|
257
|
+
readonly observationErrors: Schema.Number;
|
|
258
|
+
}>;
|
|
259
|
+
readonly currentMeasuredSeconds: Schema.$Array<Schema.Struct<{
|
|
260
|
+
readonly role: Schema.NonEmptyString;
|
|
261
|
+
readonly workload: Schema.Literals<readonly ["rpc", "subscriptions", "events", "presence", "workflows", "schedules", "directors", "drainers", "reapers", "retention", "rest", "webhooks", "inspect", "cdc"]>;
|
|
262
|
+
readonly seconds: Schema.Number;
|
|
263
|
+
}>>;
|
|
264
|
+
readonly history: Schema.Struct<{
|
|
265
|
+
readonly state: Schema.Literals<readonly ["pending", "available", "unavailable"]>;
|
|
266
|
+
readonly measuredSeconds: Schema.$Array<Schema.Struct<{
|
|
267
|
+
readonly workload: Schema.Literals<readonly ["rpc", "subscriptions", "events", "presence", "workflows", "schedules", "directors", "drainers", "reapers", "retention", "rest", "webhooks", "inspect", "cdc"]>;
|
|
268
|
+
readonly seconds: Schema.Number;
|
|
269
|
+
}>>;
|
|
270
|
+
readonly assessment: Schema.NullOr<Schema.Struct<{
|
|
271
|
+
readonly from: Schema.Number;
|
|
272
|
+
readonly until: Schema.Number;
|
|
273
|
+
readonly complete: Schema.Boolean;
|
|
274
|
+
readonly missingBuckets: Schema.Number;
|
|
275
|
+
readonly incompleteWorkloads: Schema.$Array<Schema.Literals<readonly ["rpc", "subscriptions", "events", "presence", "workflows", "schedules", "directors", "drainers", "reapers", "retention", "rest", "webhooks", "inspect", "cdc"]>>;
|
|
276
|
+
readonly reason: Schema.Literals<readonly ["invalid-observation", "incomplete", "idle", "observed"]>;
|
|
277
|
+
readonly totals: Schema.$Array<Schema.Struct<{
|
|
278
|
+
readonly workload: Schema.Literals<readonly ["rpc", "subscriptions", "events", "presence", "workflows", "schedules", "directors", "drainers", "reapers", "retention", "rest", "webhooks", "inspect", "cdc"]>;
|
|
279
|
+
readonly seconds: Schema.Number;
|
|
280
|
+
readonly share: Schema.Number;
|
|
281
|
+
}>>;
|
|
282
|
+
readonly splitCandidates: Schema.$Array<Schema.Literals<readonly ["rpc", "subscriptions", "events", "presence", "workflows", "schedules", "directors", "drainers", "reapers", "retention", "rest", "webhooks", "inspect", "cdc"]>>;
|
|
283
|
+
}>>;
|
|
284
|
+
}>;
|
|
285
|
+
}>;
|
|
286
|
+
|
|
287
|
+
/** Reserved web proxy base; the API name isolates identical role names. */
|
|
288
|
+
export declare const apiRoleProxyBasePath: (apiName: string) => string;
|
|
289
|
+
|
|
290
|
+
export declare type ApiRoleRpcWorkload = 'rpc' | 'subscriptions' | 'events';
|
|
291
|
+
|
|
292
|
+
export declare interface ApiRoleWindowAssessment {
|
|
293
|
+
readonly from: number;
|
|
294
|
+
readonly until: number;
|
|
295
|
+
readonly complete: boolean;
|
|
296
|
+
readonly missingBuckets: number;
|
|
297
|
+
readonly incompleteWorkloads: ReadonlyArray<ApiWorkload>;
|
|
298
|
+
readonly reason: 'invalid-observation' | 'incomplete' | 'idle' | 'observed';
|
|
299
|
+
readonly totals: ReadonlyArray<{
|
|
300
|
+
readonly workload: ApiWorkload;
|
|
301
|
+
readonly seconds: number;
|
|
302
|
+
readonly share: number;
|
|
303
|
+
}>;
|
|
304
|
+
/** Advisory evidence only: no topology mutation and no acceptance claim. */
|
|
305
|
+
readonly splitCandidates: ReadonlyArray<ApiWorkload>;
|
|
306
|
+
}
|
|
307
|
+
|
|
183
308
|
export declare class ApiUnavailable extends ApiUnavailable_base {
|
|
184
309
|
}
|
|
185
310
|
|
|
@@ -193,6 +318,8 @@ declare const ApiUnavailable_base: Schema.Class<ApiUnavailable, Schema.TaggedStr
|
|
|
193
318
|
readonly message: Schema.String;
|
|
194
319
|
}>, YieldableError>;
|
|
195
320
|
|
|
321
|
+
export declare type ApiWorkload = typeof API_WORKLOADS[number];
|
|
322
|
+
|
|
196
323
|
/** The subject a decision produces, plus what the decision took away. `removed`
|
|
197
324
|
* is never non-empty for a `grant`. */
|
|
198
325
|
export declare interface AppliedScopes {
|
|
@@ -546,7 +673,7 @@ export declare interface AuthenticatedGuardSpec {
|
|
|
546
673
|
* an auth resolver before reaching its handler. The application provides
|
|
547
674
|
* the resolver via `Layer.succeed(AuthMiddleware, AuthMiddleware.of(fn))`,
|
|
548
675
|
* where `fn` receives `{headers, payload, rpc, clientId}` and returns an
|
|
549
|
-
* `Effect<Subject, Unauthenticated>` — typically by inspecting headers / Bearer token and
|
|
676
|
+
* `Effect<Subject, Unauthenticated | RequestedTenantRefused>` — typically by inspecting headers / Bearer token and
|
|
550
677
|
* looking the caller up.
|
|
551
678
|
*
|
|
552
679
|
* `provides: SubjectService` means the resolver's return value is placed
|
|
@@ -562,7 +689,7 @@ export declare interface AuthenticatedGuardSpec {
|
|
|
562
689
|
export declare class AuthMiddleware extends AuthMiddleware_base {
|
|
563
690
|
}
|
|
564
691
|
|
|
565
|
-
declare const AuthMiddleware_base: RpcMiddleware.ServiceClass<AuthMiddleware, "@voltro/AuthMiddleware", SubjectService, typeof Unauthenticated, never, never, false>;
|
|
692
|
+
declare const AuthMiddleware_base: RpcMiddleware.ServiceClass<AuthMiddleware, "@voltro/AuthMiddleware", SubjectService, Schema.Union<readonly [typeof Unauthenticated, typeof RequestedTenantRefused]>, never, never, false>;
|
|
566
693
|
|
|
567
694
|
export declare type AuthRouteHandler = (req: AuthRouteRequest) => Promise<AuthRouteResponse>;
|
|
568
695
|
|
|
@@ -625,6 +752,13 @@ export declare interface AuthStrategy {
|
|
|
625
752
|
export declare interface AuthStrategyInput {
|
|
626
753
|
readonly headers: Readonly<Record<string, string | undefined>>;
|
|
627
754
|
readonly clientId: number;
|
|
755
|
+
/** HTTP request target, supplied by REST transports. Request selectors may
|
|
756
|
+
* read an explicit tenant hint here; it is never authentication or authority.
|
|
757
|
+
* Absent for connection transports and non-HTTP callers. */
|
|
758
|
+
readonly http?: {
|
|
759
|
+
readonly path: string;
|
|
760
|
+
readonly query: string;
|
|
761
|
+
};
|
|
628
762
|
/**
|
|
629
763
|
* The app's DataStore, for a strategy that must READ to identify the caller.
|
|
630
764
|
*
|
|
@@ -673,8 +807,9 @@ export declare interface AuthStrategyWithCallback extends AuthStrategy {
|
|
|
673
807
|
export declare type AuthSubjectGuard = (subject: Subject, ctx: AuthSubjectGuardContext) => Promise<AuthSubjectGuardVerdict> | AuthSubjectGuardVerdict;
|
|
674
808
|
|
|
675
809
|
export declare interface AuthSubjectGuardContext {
|
|
676
|
-
/** `'request'` for a live call, `'workflow'` for a durable run being executed
|
|
677
|
-
|
|
810
|
+
/** `'request'` for a live call, `'workflow'` for a durable run being executed,
|
|
811
|
+
* `'room'` for a Room seat redeemed on a Room host (no request headers). */
|
|
812
|
+
readonly origin: 'request' | 'workflow' | 'room';
|
|
678
813
|
/** The request's headers. EMPTY for `origin: 'workflow'`. */
|
|
679
814
|
readonly headers: Readonly<Record<string, string | undefined>>;
|
|
680
815
|
/** `undefined` for `origin: 'workflow'` and for transports with no connection. */
|
|
@@ -724,7 +859,12 @@ export declare type AuthSubjectGuardVerdict = {
|
|
|
724
859
|
* `fresh` the caller runs the handler then calls `finish`/`fail`; on
|
|
725
860
|
* `replay`/`conflict` it returns immediately without touching the handler.
|
|
726
861
|
*/
|
|
727
|
-
export declare const beginIdempotent: (store: IdempotencyStore, scope: string, key: string, ttlMs: number, now: number, inFlightLeaseMs?: number) => Promise<IdempotencyOutcome>;
|
|
862
|
+
export declare const beginIdempotent: (store: IdempotencyStore, scope: string, key: string, inputHash: string, ttlMs: number, now: number, inFlightLeaseMs?: number) => Promise<IdempotencyOutcome>;
|
|
863
|
+
|
|
864
|
+
/** Bind a process-local authority refresh to an independent subject snapshot.
|
|
865
|
+
* Neither the resolver nor its credentials become serializable subject fields.
|
|
866
|
+
* Request and durable-execution hosts use the same identity-preserving refresh. */
|
|
867
|
+
export declare const bindSubjectAuthority: (subject: Subject, resolve: () => Promise<Subject>) => Subject;
|
|
728
868
|
|
|
729
869
|
/** Bounded insertion-order storage. Appending overwrites one slot when full;
|
|
730
870
|
* reads never expose its circular physical order or retained array. */
|
|
@@ -771,6 +911,24 @@ export declare interface CachedScopeDecision {
|
|
|
771
911
|
readonly fresh: boolean;
|
|
772
912
|
}
|
|
773
913
|
|
|
914
|
+
/**
|
|
915
|
+
* Canonical JSON — object keys sorted recursively, so two structurally equal
|
|
916
|
+
* inputs that differ only in key order digest identically. A retry from a
|
|
917
|
+
* different client build must not mint a second approval.
|
|
918
|
+
* Preserve own JSON fields such as `__proto__`; a prototype setter must never
|
|
919
|
+
* discard part of the content that an approval identity binds.
|
|
920
|
+
*
|
|
921
|
+
* Lives here, not in `@voltro/runtime`, so identity digests in modules that
|
|
922
|
+
* must not load the server runtime (storage metadata, browser-safe code) use
|
|
923
|
+
* the same encoding.
|
|
924
|
+
*/
|
|
925
|
+
export declare const canonicalJson: (value: unknown) => string;
|
|
926
|
+
|
|
927
|
+
export declare const captureApiRoleEndpoints: (value: unknown) => ApiRoleEndpoints;
|
|
928
|
+
|
|
929
|
+
/** Capture optional integration observations without changing reactive triggers. */
|
|
930
|
+
export declare const captureOptionalQuerySources: (name: string, source: string | ReadonlyArray<string> | undefined, optional: unknown) => ReadonlyArray<string> | undefined;
|
|
931
|
+
|
|
774
932
|
/**
|
|
775
933
|
* Validate `plugin.framework` (npm-semver range) against the running
|
|
776
934
|
* voltro version. Returns either `{ ok: true }` or
|
|
@@ -809,7 +967,10 @@ export declare const checkGuards: (subject: Subject, guards: ReadonlyArray<AnyCh
|
|
|
809
967
|
* guard has a `resource`, it extracts the resource id from `input` and asks the
|
|
810
968
|
* resolver whether the caller holds each scope on THAT resource. A globally-held
|
|
811
969
|
* scope (or the `admin:full` bypass) still satisfies without a resolver call;
|
|
812
|
-
* only the gap ("no global grant") falls through to the resolver. A
|
|
970
|
+
* only the gap ("no global grant") falls through to the resolver. A guard with
|
|
971
|
+
* `resourceOnly: true` always requires the resource resolver's verdict, even
|
|
972
|
+
* for globally-held scopes or `admin:full`, and refuses if its resource or
|
|
973
|
+
* resolver is unavailable. A failed
|
|
813
974
|
* resolver Effect is treated as a denial (fail-closed).
|
|
814
975
|
*
|
|
815
976
|
* Returns a typed `ScopeError` naming the first unmet scope, or `null` when
|
|
@@ -842,6 +1003,9 @@ export declare interface ClientDescriptor {
|
|
|
842
1003
|
* (`<DataTable>` derives its columns from it) + the capability map can
|
|
843
1004
|
* introspect it. Same browser-safety rationale as `input`. */
|
|
844
1005
|
readonly output?: Schema.Top | undefined;
|
|
1006
|
+
/** The procedure's own declared error schema, by reference like input/output.
|
|
1007
|
+
* This is not the widened framework/plugin wire error union. */
|
|
1008
|
+
readonly error?: Schema.Top | undefined;
|
|
845
1009
|
}
|
|
846
1010
|
|
|
847
1011
|
/**
|
|
@@ -893,15 +1057,15 @@ export declare const composeAuthStrategies: (strategies: ReadonlyArray<AuthStrat
|
|
|
893
1057
|
/** What an unauthenticated caller is — see {@link AnonymousPolicy}.
|
|
894
1058
|
* Default `'no-tenant'`. Ignored when `fallback` is supplied. */
|
|
895
1059
|
readonly anonymous?: AnonymousPolicyOrDevTenant;
|
|
896
|
-
/**
|
|
897
|
-
*
|
|
898
|
-
*
|
|
899
|
-
*
|
|
900
|
-
* membership revoked a moment ago must not keep a selection alive, and a
|
|
901
|
-
* switch made a moment ago must be visible on the next call, so there is
|
|
902
|
-
* no staleness window to configure here. Requires `tenantSelection`.
|
|
903
|
-
*/
|
|
1060
|
+
/** Fresh strategy-independent memberships. Explicit requested tenants are
|
|
1061
|
+
* checked on every resolution, including the credential tenant. Stored
|
|
1062
|
+
* selections read memberships only when they differ from the credential.
|
|
1063
|
+
* Requires `tenantSelection` or `requestedTenant`. */
|
|
904
1064
|
readonly memberships?: MembershipsSource;
|
|
1065
|
+
/** Request-local tenant hint, checked against fresh `memberships` before
|
|
1066
|
+
* scopes and guards. Explicit targets bypass the stored selection without
|
|
1067
|
+
* changing it. Invalid hints fail closed, never fall back. */
|
|
1068
|
+
readonly requestedTenant?: RequestedTenantSource;
|
|
905
1069
|
/**
|
|
906
1070
|
* Where a subject's tenant selection is stored. Read for every matched
|
|
907
1071
|
* user / apiKey / serviceAccount subject (one point lookup); a stored
|
|
@@ -1012,6 +1176,8 @@ export declare const composeAuthStrategies: (strategies: ReadonlyArray<AuthStrat
|
|
|
1012
1176
|
readonly getStore?: () => unknown;
|
|
1013
1177
|
}) => ((input: AuthStrategyInput) => Promise<SubjectResolution>);
|
|
1014
1178
|
|
|
1179
|
+
export declare const composeReplayAuthorityBindings: (plugins: ReadonlyArray<unknown>) => RpcReplayAuthorityBinding | undefined;
|
|
1180
|
+
|
|
1015
1181
|
/**
|
|
1016
1182
|
* Compose a list of Effect-native interceptors into ONE function the
|
|
1017
1183
|
* runtime calls. Reduces right-to-left so the array order reads
|
|
@@ -1082,6 +1248,11 @@ export declare class ConnectionInfoMiddleware extends ConnectionInfoMiddleware_b
|
|
|
1082
1248
|
declare const ConnectionInfoMiddleware_base: RpcMiddleware.ServiceClass<ConnectionInfoMiddleware, "@voltro/ConnectionInfoMiddleware", ConnectionInfo, Schema.Never, never, never, false>;
|
|
1083
1249
|
|
|
1084
1250
|
export declare interface ConnectionInfoValue {
|
|
1251
|
+
/** The effective per-call Cookie header, including current connection
|
|
1252
|
+
* credential patches. Server-only input for app-specific signed-cookie
|
|
1253
|
+
* verification; not a verified identity. Never serialize it into responses
|
|
1254
|
+
* or public page state. Absent when the caller presented no cookies. */
|
|
1255
|
+
readonly cookieHeader?: string;
|
|
1085
1256
|
/** Per-connection identifier assigned by the rpc transport. Stable for the
|
|
1086
1257
|
* lifetime of the underlying WebSocket connection; reused as the key for
|
|
1087
1258
|
* the per-connection subject override map. */
|
|
@@ -1345,8 +1516,9 @@ declare const ConstraintViolation_base: Schema.Class<ConstraintViolation, Schema
|
|
|
1345
1516
|
* plugin wants to cancel EARLY (before shutdown).
|
|
1346
1517
|
*/
|
|
1347
1518
|
export declare interface CoordinatedScheduleHandle {
|
|
1348
|
-
/** Stop
|
|
1349
|
-
|
|
1519
|
+
/** Stop future admission immediately; await completion before releasing the
|
|
1520
|
+
* task dependencies. Idempotent; synchronous handles finish immediately. */
|
|
1521
|
+
readonly stop: () => void | Promise<void>;
|
|
1350
1522
|
/** The task name (for logging / dedup diagnostics). */
|
|
1351
1523
|
readonly name: string;
|
|
1352
1524
|
/**
|
|
@@ -1405,6 +1577,13 @@ export declare interface CoordinatedTickOutcome {
|
|
|
1405
1577
|
readonly nextDueInMs?: number | null;
|
|
1406
1578
|
}
|
|
1407
1579
|
|
|
1580
|
+
/** Capture the complete participant list once. Undeclared SQL tables refuse
|
|
1581
|
+
* before any hook; erasure and merge are distinct policies and never substitute. */
|
|
1582
|
+
export declare const createPluginAccountMergeRegistry: (plugins: ReadonlyArray<VoltroPlugin>) => PluginAccountMergeRegistry;
|
|
1583
|
+
|
|
1584
|
+
/** Captures hooks once. Does not read a store, schedule work, retry or grant authority. */
|
|
1585
|
+
export declare const createPluginPrivacyRegistry: (plugins: ReadonlyArray<VoltroPlugin>) => PluginPrivacyRegistry;
|
|
1586
|
+
|
|
1408
1587
|
/** Index reuse for one subscription's immutable snapshots and returned rows.
|
|
1409
1588
|
* Arbitrary mutable input must use applyRowPatch. A different base rebuilds
|
|
1410
1589
|
* the index; reset releases it on snapshot replacement or owner disposal. */
|
|
@@ -1413,6 +1592,9 @@ export declare const createRowPatchApplier: () => {
|
|
|
1413
1592
|
readonly reset: () => void;
|
|
1414
1593
|
};
|
|
1415
1594
|
|
|
1595
|
+
/** The latest authenticated authority for a request or live subscription. */
|
|
1596
|
+
export declare const currentSubjectAuthority: (subject: Subject) => Subject;
|
|
1597
|
+
|
|
1416
1598
|
/**
|
|
1417
1599
|
* What a descriptor CARRIES: the author's guards, or the erased form of their
|
|
1418
1600
|
* `openAccess:` decision — never both.
|
|
@@ -1425,6 +1607,9 @@ export declare const createRowPatchApplier: () => {
|
|
|
1425
1607
|
*/
|
|
1426
1608
|
export declare type DeclaredAccess<Input = unknown> = ReadonlyArray<AnyGuardSpec<Input> | OpenAccessSpec | ServiceAccessSpec>;
|
|
1427
1609
|
|
|
1610
|
+
/** The `_tag` literals a descriptor's `error:` union declares (empty for none). */
|
|
1611
|
+
export declare const declaredErrorTags: (error: Schema.Top | undefined) => ReadonlySet<string>;
|
|
1612
|
+
|
|
1428
1613
|
/** Every channel declared in this process, by routing key. */
|
|
1429
1614
|
export declare const declaredReactivityChannelKeys: () => ReadonlySet<string>;
|
|
1430
1615
|
|
|
@@ -1597,10 +1782,9 @@ export declare const defineEvent: <const Name extends string, Key extends Schema
|
|
|
1597
1782
|
* resource-scoped rule ("may this terminal watch this arena") stays
|
|
1598
1783
|
* declarative. `ScopeError` is merged into the wire error union automatically.
|
|
1599
1784
|
*
|
|
1600
|
-
*
|
|
1601
|
-
*
|
|
1602
|
-
*
|
|
1603
|
-
* makes throughput scale with the audience instead of the publish rate.
|
|
1785
|
+
* Checked before subscription and each delivery. Resource resolvers can observe
|
|
1786
|
+
* live revocation; captured subject scopes remain bounded by credential expiry.
|
|
1787
|
+
* Additional private payload filtering uses the app-owned clientPolicy.
|
|
1604
1788
|
*/
|
|
1605
1789
|
readonly guards?: Guards<Schema.Schema.Type<Key>>;
|
|
1606
1790
|
/**
|
|
@@ -1661,6 +1845,8 @@ export declare const defineEvent: <const Name extends string, Key extends Schema
|
|
|
1661
1845
|
* to miss one?" — not "is this event frequent?".
|
|
1662
1846
|
*/
|
|
1663
1847
|
readonly delivery?: EventDeliverySemantics;
|
|
1848
|
+
/** Required private-client policy ID, resolved from the installing app. */
|
|
1849
|
+
readonly clientPolicy?: string;
|
|
1664
1850
|
}) => EventDescriptor<Name, Key, Payload>;
|
|
1665
1851
|
|
|
1666
1852
|
export declare const defineMutation: <const Name extends string, Input extends Schema.Top, Output extends Schema.Top, Error extends Schema.Top = typeof Schema.Never>(options: {
|
|
@@ -1693,6 +1879,13 @@ export declare const defineMutation: <const Name extends string, Input extends S
|
|
|
1693
1879
|
* same way. Not a durable outbox, a distributed lock or a cross-tab merge.
|
|
1694
1880
|
*/
|
|
1695
1881
|
readonly serialize?: MutationSerialization<Schema.Schema.Type<Input>>;
|
|
1882
|
+
/** Exclude mutations without a valid row-image inverse (for example a
|
|
1883
|
+
* derived-index rebuild) from automatic undo. Omitted means the normal
|
|
1884
|
+
* environment-controlled capture. Transactions, guards and audit still run. */
|
|
1885
|
+
readonly undo?: {
|
|
1886
|
+
readonly capture: false;
|
|
1887
|
+
readonly reason: string;
|
|
1888
|
+
};
|
|
1696
1889
|
/** Optional declarative target(s) — drives auto-optimistic. */
|
|
1697
1890
|
readonly target?: Target<Schema.Schema.Type<Input>, Schema.Schema.Type<Output>>;
|
|
1698
1891
|
/** Declarative authorization guard(s) — the caller must hold the named
|
|
@@ -1846,6 +2039,9 @@ export declare const defineQuery: <const Name extends string, Input extends Sche
|
|
|
1846
2039
|
* import edge is what makes a channel `source:` impossible to leave stale,
|
|
1847
2040
|
* which a table name (a bare string) can always be. */
|
|
1848
2041
|
readonly source?: ReactivitySource | ReadonlyArray<ReactivitySource>;
|
|
2042
|
+
/** Names in source that observe an optional integration. These remain in
|
|
2043
|
+
* the complete trigger set; unavailable optional tables warn in check. */
|
|
2044
|
+
readonly optionalSource?: ReadonlyArray<string>;
|
|
1849
2045
|
/** Opt into server-side snapshot caching with auto-invalidation. */
|
|
1850
2046
|
readonly cache?: QueryCacheConfig;
|
|
1851
2047
|
/** Declarative authorization guard(s) — the caller must hold the named
|
|
@@ -1990,6 +2186,38 @@ export declare interface DeleteTarget<Input = unknown> extends NestedTargetField
|
|
|
1990
2186
|
readonly identify?: ((input: Input) => string | ReadonlyArray<string>) | undefined;
|
|
1991
2187
|
}
|
|
1992
2188
|
|
|
2189
|
+
/** The HMR custom event `voltro dev` publishes its activity on. */
|
|
2190
|
+
export declare const DEV_ACTIVITY_EVENT = "voltro:dev-activity";
|
|
2191
|
+
|
|
2192
|
+
/** What `voltro dev` reports over {@link DEV_ACTIVITY_EVENT}. A `document`
|
|
2193
|
+
* message describes ONE document request (`id` is per server process); a
|
|
2194
|
+
* `compile` message says whether Vite is transforming browser modules. */
|
|
2195
|
+
export declare type DevActivityMessage = {
|
|
2196
|
+
readonly type: 'document';
|
|
2197
|
+
readonly id: number;
|
|
2198
|
+
/** Path + search exactly as the browser asked for it. */
|
|
2199
|
+
readonly url: string;
|
|
2200
|
+
/** `start` once, when the request arrives; then whichever the server
|
|
2201
|
+
* is doing as it changes — `compiling` while Vite transforms modules
|
|
2202
|
+
* for it, `rendering` once a server render runs, `waiting` for
|
|
2203
|
+
* anything else (Vite's own html, a middleware). */
|
|
2204
|
+
readonly phase: 'start' | 'waiting' | 'compiling' | 'rendering';
|
|
2205
|
+
} | {
|
|
2206
|
+
readonly type: 'document';
|
|
2207
|
+
readonly id: number;
|
|
2208
|
+
readonly url: string;
|
|
2209
|
+
readonly phase: 'end';
|
|
2210
|
+
/** `document`: the browser got a page to show. `redirect`: it will ask
|
|
2211
|
+
* for `location` next. `no-document`: nothing will replace this page
|
|
2212
|
+
* (204/205, an attachment). `aborted`: the browser went away first. */
|
|
2213
|
+
readonly outcome: 'document' | 'redirect' | 'no-document' | 'aborted';
|
|
2214
|
+
readonly location?: string;
|
|
2215
|
+
} | {
|
|
2216
|
+
readonly type: 'compile';
|
|
2217
|
+
readonly consumer: 'client';
|
|
2218
|
+
readonly active: boolean;
|
|
2219
|
+
};
|
|
2220
|
+
|
|
1993
2221
|
/** Pair, list and revoke devices (`devices: true`) for the caller's tenant.
|
|
1994
2222
|
* One scope, not three: a device always acts as itself, in the pairer's
|
|
1995
2223
|
* tenant, so there is no self / org / other distinction to draw.
|
|
@@ -2048,6 +2276,8 @@ export declare const effectiveScopes: (subject: Subject) => ReadonlyArray<string
|
|
|
2048
2276
|
*/
|
|
2049
2277
|
export declare const encodeEventKey: (key: unknown) => string;
|
|
2050
2278
|
|
|
2279
|
+
export declare const encodeNativeFormCapture: (selector: string, presentationDigest: string) => string;
|
|
2280
|
+
|
|
2051
2281
|
/** Encode a failure under `format`: the tagged body the desugar always wrote
|
|
2052
2282
|
* (`{ error, …fields }`), Problem Details, or the format's own encoder. */
|
|
2053
2283
|
export declare const encodeRestError: (format: RestFormat, error: RestFormatError, ctx: RestFormatContext) => RestFormatResponse;
|
|
@@ -2059,6 +2289,17 @@ export declare const encodeRestError: (format: RestFormat, error: RestFormatErro
|
|
|
2059
2289
|
*/
|
|
2060
2290
|
export declare const encodeRestSuccess: (format: RestFormat, value: unknown, ctx: RestFormatContext) => RestFormatResponse;
|
|
2061
2291
|
|
|
2292
|
+
export declare interface EnqueueOptions {
|
|
2293
|
+
/** Deduplicate while an earlier intent is still pending, not permanently. */
|
|
2294
|
+
readonly idempotencyKey?: string;
|
|
2295
|
+
readonly maxAttempts?: number;
|
|
2296
|
+
readonly delayMs?: number;
|
|
2297
|
+
}
|
|
2298
|
+
|
|
2299
|
+
/** The member of an error union that declares `tag`, as a schema of its own —
|
|
2300
|
+
* for the spec's per-status responses. */
|
|
2301
|
+
export declare const errorMemberSchema: (error: Schema.Top | undefined, tag: string) => Schema.Top | undefined;
|
|
2302
|
+
|
|
2062
2303
|
/**
|
|
2063
2304
|
* The text to SHOW for a failure value — its `message`, else its `_tag`, else
|
|
2064
2305
|
* `String(value)`.
|
|
@@ -2076,8 +2317,8 @@ export declare const errorMessage: (err: unknown) => string;
|
|
|
2076
2317
|
/**
|
|
2077
2318
|
* Read the `_tag` off a thrown error value, or `undefined` when it has none.
|
|
2078
2319
|
*
|
|
2079
|
-
* It lives
|
|
2080
|
-
* wire — one
|
|
2320
|
+
* It lives in protocol because `toRpc` (procedure.ts) is what puts the tag on
|
|
2321
|
+
* the wire — one package owns both ends of that contract. It used to live in
|
|
2081
2322
|
* `@voltro/client`, and being there had a cost nobody could see from inside the
|
|
2082
2323
|
* framework: an app's shared error handler lived in a package that pulled only
|
|
2083
2324
|
* `@voltro/i18n`, so reading a tag meant taking a dependency on the whole client
|
|
@@ -2119,6 +2360,34 @@ export declare const eventAttached: Schema.Struct<{
|
|
|
2119
2360
|
readonly _tag: Schema.Literal<"attached">;
|
|
2120
2361
|
}>;
|
|
2121
2362
|
|
|
2363
|
+
/** App-owned, server-only callbacks. Descriptors carry only the policy ID. */
|
|
2364
|
+
export declare interface EventClientPolicy {
|
|
2365
|
+
readonly id: string;
|
|
2366
|
+
/** Before bus subscription, including reattachment/resume. Only true admits. */
|
|
2367
|
+
readonly admit: (input: {
|
|
2368
|
+
readonly subject: Subject;
|
|
2369
|
+
readonly event: string;
|
|
2370
|
+
readonly key: unknown;
|
|
2371
|
+
}) => Effect.Effect<boolean, unknown>;
|
|
2372
|
+
/** Recheck current membership AND payload visibility. Deny ends the stream;
|
|
2373
|
+
* drop withholds this payload but keeps the subscription. No client filtering. */
|
|
2374
|
+
/** Register revocation before initial admission. The returned effect ends when
|
|
2375
|
+
* access may have changed; completion or failure ends the client stream.
|
|
2376
|
+
* Acquire resources in the supplied Scope; no detached background owner. */
|
|
2377
|
+
readonly monitor?: (input: {
|
|
2378
|
+
readonly subject: Subject;
|
|
2379
|
+
readonly event: string;
|
|
2380
|
+
readonly key: unknown;
|
|
2381
|
+
}) => Effect.Effect<Effect.Effect<void, unknown>, unknown, Scope.Scope>;
|
|
2382
|
+
readonly deliver: (input: {
|
|
2383
|
+
readonly subject: Subject;
|
|
2384
|
+
readonly event: string;
|
|
2385
|
+
readonly key: unknown;
|
|
2386
|
+
readonly payload: unknown;
|
|
2387
|
+
readonly emittedAt: number;
|
|
2388
|
+
}) => Effect.Effect<'allow' | 'drop' | 'deny', unknown>;
|
|
2389
|
+
}
|
|
2390
|
+
|
|
2122
2391
|
/**
|
|
2123
2392
|
* What it means for a subscriber to fall behind.
|
|
2124
2393
|
*
|
|
@@ -2155,9 +2424,8 @@ export declare interface EventDescriptor<Name extends string, Key extends Schema
|
|
|
2155
2424
|
readonly key: Key;
|
|
2156
2425
|
readonly payload: Payload;
|
|
2157
2426
|
/** Who may LISTEN — the author's guards, or the erased form of their
|
|
2158
|
-
* `openAccess:` decision, never both (see `DeclaredAccess`).
|
|
2159
|
-
*
|
|
2160
|
-
* why that distinction is deliberate. */
|
|
2427
|
+
* `openAccess:` decision, never both (see `DeclaredAccess`). Resource guards are checked before subscription and delivery; credential
|
|
2428
|
+
* expiry bounds captured subject authority. */
|
|
2161
2429
|
readonly guards: Guards | undefined;
|
|
2162
2430
|
/** The declared `openAccess:` reason, when there is one — what the boot gate
|
|
2163
2431
|
* and `voltro doctor` read. The enforcement paths read `guards`. */
|
|
@@ -2168,6 +2436,8 @@ export declare interface EventDescriptor<Name extends string, Key extends Schema
|
|
|
2168
2436
|
readonly delivery: EventDeliverySemantics | undefined;
|
|
2169
2437
|
/** Opt this event into outbound HTTP delivery. See `EventWebhookSpec`. */
|
|
2170
2438
|
readonly webhook: EventWebhookSpec | undefined;
|
|
2439
|
+
/** Required app-owned server policy, in addition to guards. No server imports in descriptors. */
|
|
2440
|
+
readonly clientPolicy?: string;
|
|
2171
2441
|
}
|
|
2172
2442
|
|
|
2173
2443
|
/**
|
|
@@ -2248,6 +2518,9 @@ export declare const eventResumePoint: Schema.Struct<{
|
|
|
2248
2518
|
|
|
2249
2519
|
export declare const eventRoute: (tenantId: string | null, event: string, key: unknown) => string;
|
|
2250
2520
|
|
|
2521
|
+
/** Browser-safe execution ownership marker; wire schemas remain unchanged. */
|
|
2522
|
+
export declare const EventRpcWorkload: Context.Service<true, true>;
|
|
2523
|
+
|
|
2251
2524
|
export declare type EventStreamEvent<P> = {
|
|
2252
2525
|
readonly _tag: 'attached';
|
|
2253
2526
|
} | {
|
|
@@ -2303,15 +2576,6 @@ export declare const eventSubscribeInput: <K extends Schema.Top>(key: K) => Sche
|
|
|
2303
2576
|
}>>>;
|
|
2304
2577
|
}>;
|
|
2305
2578
|
|
|
2306
|
-
/**
|
|
2307
|
-
* Lift an event descriptor into its rpc.
|
|
2308
|
-
*
|
|
2309
|
-
* A `stream: true` rpc, like a query — the framework's push transport is the
|
|
2310
|
-
* WebSocket a subscription already holds open, and reusing it is why `useEvent`
|
|
2311
|
-
* shares one connection lifecycle, one reconnect policy and one devtools view
|
|
2312
|
-
* with `useSubscription` instead of being a second realtime concept in the same
|
|
2313
|
-
* app.
|
|
2314
|
-
*/
|
|
2315
2579
|
export declare const eventToRpc: <Name extends string, Key extends Schema.Top, Payload extends Schema.Top>(descriptor: EventDescriptor<Name, Key, Payload, ReadonlyArray<unknown>>, extraErrors?: ReadonlyArray<Schema.Top>) => Rpc.Rpc<Name, Schema.Struct<{
|
|
2316
2580
|
readonly key: Key;
|
|
2317
2581
|
readonly resume: Schema.optional<Schema.$Array<Schema.Struct<{
|
|
@@ -2394,8 +2658,8 @@ export declare interface ExposeAsToolSpec {
|
|
|
2394
2658
|
*/
|
|
2395
2659
|
export declare type ExtraErrors = ReadonlyArray<Schema.Top>;
|
|
2396
2660
|
|
|
2397
|
-
/** Release
|
|
2398
|
-
export declare const failIdempotent: (store: IdempotencyStore,
|
|
2661
|
+
/** Release this failed execution's running claim without deleting a successor. */
|
|
2662
|
+
export declare const failIdempotent: (store: IdempotencyStore, claim: IdempotencyClaim) => Promise<boolean>;
|
|
2399
2663
|
|
|
2400
2664
|
/**
|
|
2401
2665
|
* The field-addressed issues carried by a wire error, or `[]` when the error
|
|
@@ -2433,8 +2697,8 @@ export declare const findAdvisoryResourceGuards: (procedures: ReadonlyArray<{
|
|
|
2433
2697
|
readonly guards?: ReadonlyArray<AnyCheckSpec>;
|
|
2434
2698
|
}>) => ReadonlyArray<string>;
|
|
2435
2699
|
|
|
2436
|
-
/** Record a
|
|
2437
|
-
export declare const finishIdempotent: (store: IdempotencyStore,
|
|
2700
|
+
/** Record a response only while this original execution owns the claim. */
|
|
2701
|
+
export declare const finishIdempotent: (store: IdempotencyStore, claim: IdempotencyClaim, response: IdempotencyResponse, now: number) => Promise<boolean>;
|
|
2438
2702
|
|
|
2439
2703
|
/**
|
|
2440
2704
|
* The schema as the generator should see it: every `Number` node checked
|
|
@@ -2466,9 +2730,16 @@ export declare const finiteNumberView: (ast: SchemaAST.AST, memo?: Map<SchemaAST
|
|
|
2466
2730
|
*/
|
|
2467
2731
|
export declare const firstEventValue: (tag: string, value: unknown, label: string) => unknown;
|
|
2468
2732
|
|
|
2733
|
+
export declare const FORM_CAPTURE_FIELD = "__voltro_capture";
|
|
2734
|
+
|
|
2735
|
+
export declare const FORM_CAPTURE_META_NAME = "voltro:form-source";
|
|
2736
|
+
|
|
2469
2737
|
/** A route rendered for humans — logs, the inspect surface, the dashboard. */
|
|
2470
2738
|
export declare const formatEventRoute: (route: string) => string;
|
|
2471
2739
|
|
|
2740
|
+
/** Build selector (snapshot/input/execution) followed by its public class digest. */
|
|
2741
|
+
export declare const formCaptureSource: (value: unknown) => string | undefined;
|
|
2742
|
+
|
|
2472
2743
|
/**
|
|
2473
2744
|
* The framework errors EVERY procedure of a kind carries on its wire union —
|
|
2474
2745
|
* the unconditional members `wireErrorUnion` adds. The conditional ones (a
|
|
@@ -2481,10 +2752,10 @@ export declare const formatEventRoute: (route: string) => string;
|
|
|
2481
2752
|
* test pins it against `wireErrorUnion` per kind, so the two cannot drift.
|
|
2482
2753
|
*/
|
|
2483
2754
|
export declare const FRAMEWORK_WIRE_ERRORS: {
|
|
2484
|
-
readonly query: readonly [typeof ScopeError, typeof Unauthenticated];
|
|
2485
|
-
readonly stream: readonly [typeof ScopeError, typeof Unauthenticated];
|
|
2486
|
-
readonly action: readonly [typeof ScopeError, typeof Unauthenticated, typeof ValidationError, typeof ValidationErrors];
|
|
2487
|
-
readonly mutation: readonly [typeof ScopeError, typeof Unauthenticated, typeof BusinessRuleViolation, typeof MutationInFlight, typeof VersionConflict, typeof ValidationError, typeof ValidationErrors];
|
|
2755
|
+
readonly query: readonly [typeof ScopeError, typeof Unauthenticated, typeof RequestedTenantRefused];
|
|
2756
|
+
readonly stream: readonly [typeof ScopeError, typeof Unauthenticated, typeof RequestedTenantRefused];
|
|
2757
|
+
readonly action: readonly [typeof ScopeError, typeof Unauthenticated, typeof RequestedTenantRefused, typeof MutationInFlight, typeof MutationIdempotencyRefused, typeof ValidationError, typeof ValidationErrors];
|
|
2758
|
+
readonly mutation: readonly [typeof ScopeError, typeof Unauthenticated, typeof RequestedTenantRefused, typeof BusinessRuleViolation, typeof MutationInFlight, typeof MutationIdempotencyRefused, typeof VersionConflict, typeof ValidationError, typeof ValidationErrors];
|
|
2488
2759
|
};
|
|
2489
2760
|
|
|
2490
2761
|
/** The error values {@link FRAMEWORK_WIRE_ERRORS} admits for `Kind`. */
|
|
@@ -2545,6 +2816,9 @@ export declare interface GuardCheckSpec {
|
|
|
2545
2816
|
* global-scope check (the extractor is advisory), exactly as before.
|
|
2546
2817
|
*/
|
|
2547
2818
|
readonly resource?: (input: unknown) => string | undefined;
|
|
2819
|
+
/** Require an explicit resource resolver verdict, even for globally held
|
|
2820
|
+
* scopes and `admin:full`. Missing resolver/resource refuses access. */
|
|
2821
|
+
readonly resourceOnly?: boolean;
|
|
2548
2822
|
}
|
|
2549
2823
|
|
|
2550
2824
|
/**
|
|
@@ -2566,35 +2840,17 @@ export declare interface GuardSpec<Input = unknown> {
|
|
|
2566
2840
|
/** How an array of scopes combines. `'all'` (default) = AND (hold every
|
|
2567
2841
|
* scope); `'any'` = OR (hold at least one). Ignored for a single scope. */
|
|
2568
2842
|
readonly mode?: 'all' | 'any';
|
|
2569
|
-
/**
|
|
2570
|
-
*
|
|
2571
|
-
*
|
|
2572
|
-
*
|
|
2573
|
-
*
|
|
2574
|
-
*
|
|
2575
|
-
*
|
|
2576
|
-
* carried for logging and for a future subject-scope resolver that narrows by
|
|
2577
|
-
* resource. It does not, on its own, make the check per-resource.
|
|
2578
|
-
*
|
|
2579
|
-
* **If your authority is per-resource, you want {@link PolicyGuardSpec}, not
|
|
2580
|
-
* this field** — `guards: [{ action, resourceType, resource }]`, backed by
|
|
2581
|
-
* `defineResourcePolicy` + a tuple source you register. That is built, wired
|
|
2582
|
-
* on both boot paths, fail-closed without a resolver, and documented under
|
|
2583
|
-
* *Authentication → Authorization*. An app whose relationships already live
|
|
2584
|
-
* in its own tables (a `teamMembers` row, say) registers its own tuple source
|
|
2585
|
-
* rather than copying data across; see `policyGuardResolver.ts`.
|
|
2586
|
-
*
|
|
2587
|
-
* That paragraph is here because its absence cost a deployment their access
|
|
2588
|
-
* gate. This comment used to describe the resolver as "a future ReBAC /
|
|
2589
|
-
* `accessPolicy()` resolver" — written before the ReBAC path shipped and
|
|
2590
|
-
* never updated. They read the type, quoted the sentence, concluded there was
|
|
2591
|
-
* "nothing in between" declaring an untruth and turning the gate off, and set
|
|
2592
|
-
* `security: { defaultDeny: false }` on an app with 565 undecided procedures.
|
|
2593
|
-
* The capability they needed was two fields away. A doc comment that says
|
|
2594
|
-
* "future" about something shipped is not a small inaccuracy: it is the only
|
|
2595
|
-
* thing a careful reader has, and it argued them out of a feature.
|
|
2596
|
-
*/
|
|
2843
|
+
/** Pure browser-safe input → target resource id selector. With a registered
|
|
2844
|
+
* setResourceScopeResolver, scopes can be checked on this resource. Without
|
|
2845
|
+
* resourceOnly, an existing global scope or admin:full may satisfy the guard
|
|
2846
|
+
* without consulting that resolver. For per-resource authority over relationships use
|
|
2847
|
+
* PolicyGuardSpec: `defineResourcePolicy` plus a registered tuple source. That is built, wired
|
|
2848
|
+
* on both boot paths and fail-closed without a resolver — an earlier comment called it "future"
|
|
2849
|
+
* and argued a deployment out of its access gate. */
|
|
2597
2850
|
readonly resource?: (input: Input) => string | undefined;
|
|
2851
|
+
/** Require an explicit current resource verdict, including for globally held
|
|
2852
|
+
* scopes or admin:full. Missing resolver/resource refuses access. */
|
|
2853
|
+
readonly resourceOnly?: boolean;
|
|
2598
2854
|
}
|
|
2599
2855
|
|
|
2600
2856
|
/** Does this descriptor declare an access decision — a guard, or a deliberate
|
|
@@ -2624,8 +2880,9 @@ export declare const hasEnforcedGuard: (guards: DeclaredAccess | undefined) => b
|
|
|
2624
2880
|
* the RAW subject scopes — use `hasEffectiveScope` to include rbac roles. */
|
|
2625
2881
|
export declare const hasScope: (subject: Subject, scope: string) => boolean;
|
|
2626
2882
|
|
|
2627
|
-
/** Renew
|
|
2628
|
-
|
|
2883
|
+
/** Renew only the captured execution identity; ownership loss stops renewal.
|
|
2884
|
+
* Stopping this timer never proves a remote business operation has stopped. */
|
|
2885
|
+
export declare const holdIdempotentClaim: (store: IdempotencyStore, claim: IdempotencyClaim, inFlightLeaseMs?: number, now?: () => number) => (() => void);
|
|
2629
2886
|
|
|
2630
2887
|
/**
|
|
2631
2888
|
* Short-circuit response shape. Returning a `HttpInterceptResponse`
|
|
@@ -2696,11 +2953,35 @@ export declare type HttpRequestInterceptor = (next: () => Promise<HttpInterceptR
|
|
|
2696
2953
|
/** Fire-and-forget observer of plugin HTTP route calls — see {@link PluginHttpRouteEvent}. */
|
|
2697
2954
|
export declare type HttpRouteObserver = (event: PluginHttpRouteEvent) => void;
|
|
2698
2955
|
|
|
2956
|
+
/** Identity of one acquired execution, never reused when a key is reclaimed.
|
|
2957
|
+
* This is receipt ownership, not authority to perform a business side effect. */
|
|
2958
|
+
export declare interface IdempotencyClaim {
|
|
2959
|
+
readonly scope: string;
|
|
2960
|
+
readonly key: string;
|
|
2961
|
+
readonly id: string;
|
|
2962
|
+
readonly inputHash: string;
|
|
2963
|
+
}
|
|
2964
|
+
|
|
2965
|
+
export declare type IdempotencyClaimResult = {
|
|
2966
|
+
readonly kind: 'claimed';
|
|
2967
|
+
readonly claim: IdempotencyClaim;
|
|
2968
|
+
} | {
|
|
2969
|
+
readonly kind: 'existing';
|
|
2970
|
+
readonly record: IdempotencyRecord;
|
|
2971
|
+
} | {
|
|
2972
|
+
readonly kind: 'conflict';
|
|
2973
|
+
};
|
|
2974
|
+
|
|
2699
2975
|
export declare type IdempotencyOutcome = {
|
|
2700
2976
|
readonly kind: 'fresh';
|
|
2977
|
+
readonly claim: IdempotencyClaim;
|
|
2701
2978
|
} | {
|
|
2702
2979
|
readonly kind: 'replay';
|
|
2703
2980
|
readonly response: IdempotencyResponse;
|
|
2981
|
+
} | {
|
|
2982
|
+
readonly kind: 'input-conflict';
|
|
2983
|
+
} | {
|
|
2984
|
+
readonly kind: 'input-unbound';
|
|
2704
2985
|
} | {
|
|
2705
2986
|
readonly kind: 'conflict';
|
|
2706
2987
|
};
|
|
@@ -2708,6 +2989,8 @@ export declare type IdempotencyOutcome = {
|
|
|
2708
2989
|
export declare interface IdempotencyRecord {
|
|
2709
2990
|
readonly scope: string;
|
|
2710
2991
|
readonly key: string;
|
|
2992
|
+
/** Null means a retained receipt predates declared-input binding. */
|
|
2993
|
+
readonly inputHash: string | null;
|
|
2711
2994
|
readonly status: 'in_flight' | 'completed';
|
|
2712
2995
|
readonly response: IdempotencyResponse | null;
|
|
2713
2996
|
/** epoch ms */
|
|
@@ -2717,38 +3000,41 @@ export declare interface IdempotencyRecord {
|
|
|
2717
3000
|
export declare interface IdempotencyResponse {
|
|
2718
3001
|
readonly status: number;
|
|
2719
3002
|
readonly body: unknown;
|
|
3003
|
+
/** Framework-owned REST qualification metadata. Custom stores preserve it
|
|
3004
|
+
* unchanged, separately from the arbitrary application output in body. */
|
|
3005
|
+
readonly rest?: unknown;
|
|
2720
3006
|
}
|
|
2721
3007
|
|
|
2722
3008
|
/** Build the scope key — keep keys from colliding across tenants + endpoints. */
|
|
2723
3009
|
export declare const idempotencyScope: (tenantId: string | null | undefined, method: string, path: string) => string;
|
|
2724
3010
|
|
|
2725
3011
|
export declare interface IdempotencyStore {
|
|
2726
|
-
/** Current record for (scope, key), or null. Read-side (inspect/dashboard). */
|
|
2727
3012
|
readonly get: (scope: string, key: string) => Promise<IdempotencyRecord | null>;
|
|
2728
|
-
/**
|
|
2729
|
-
*
|
|
2730
|
-
*
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
*
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
readonly
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
readonly
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
readonly
|
|
2751
|
-
|
|
3013
|
+
/** Atomically acquire an absent/stale key with a new, never-reused identity.
|
|
3014
|
+
* Otherwise return the existing receipt, or conflict if contention prevents
|
|
3015
|
+
* observing a stable record. Expiry does not prove an old executor stopped. */
|
|
3016
|
+
readonly claim: (scope: string, key: string, inputHash: string, now: number, ttlMs: number, inFlightLeaseMs: number) => Promise<IdempotencyClaimResult>;
|
|
3017
|
+
/** Atomically match original scope/key/id AND in_flight status. False means
|
|
3018
|
+
* this execution no longer owns a running receipt; never touch its successor. */
|
|
3019
|
+
readonly renew: (claim: IdempotencyClaim, now: number) => Promise<boolean>;
|
|
3020
|
+
/** Complete only the original running claim and start its replay window now. */
|
|
3021
|
+
readonly complete: (claim: IdempotencyClaim, response: IdempotencyResponse, now: number) => Promise<boolean>;
|
|
3022
|
+
/** Release only the original running claim. Completed receipts are retained. */
|
|
3023
|
+
readonly release: (claim: IdempotencyClaim) => Promise<boolean>;
|
|
3024
|
+
}
|
|
3025
|
+
|
|
3026
|
+
/** What an identity's authority resolved to: the subject to run as, or why not. */
|
|
3027
|
+
export declare type IdentityAuthorityOutcome = {
|
|
3028
|
+
readonly kind: 'resolved';
|
|
3029
|
+
readonly subject: Subject;
|
|
3030
|
+
} | {
|
|
3031
|
+
readonly kind: 'unavailable';
|
|
3032
|
+
readonly reason: string;
|
|
3033
|
+
} | {
|
|
3034
|
+
readonly kind: 'vetoed';
|
|
3035
|
+
readonly code: string;
|
|
3036
|
+
readonly message: string;
|
|
3037
|
+
};
|
|
2752
3038
|
|
|
2753
3039
|
/** `/<id>` — the op path for a row id. Ids are JSON-pointer-escaped
|
|
2754
3040
|
* (`~` → `~0`, `/` → `~1`) so a slash or tilde inside a string id can't
|
|
@@ -2894,6 +3180,10 @@ export declare const isSystemSubject: (subject: Subject) => boolean;
|
|
|
2894
3180
|
|
|
2895
3181
|
export declare const isTenantSelectable: (subject: Subject) => subject is TenantSelectableSubject;
|
|
2896
3182
|
|
|
3183
|
+
export declare const isUpgradedCheck: (g: AnyCheckSpec) => g is UpgradedCheckSpec;
|
|
3184
|
+
|
|
3185
|
+
export declare const isUpgradedGuard: <I>(g: AnyGuardSpec<I>) => g is UpgradedGuardSpec;
|
|
3186
|
+
|
|
2897
3187
|
/**
|
|
2898
3188
|
* Is this descriptor allowed on the wire at all?
|
|
2899
3189
|
*
|
|
@@ -2971,7 +3261,7 @@ export declare interface Membership {
|
|
|
2971
3261
|
* project from wherever it keeps them. `input.store` is the app's DataStore. */
|
|
2972
3262
|
export declare type MembershipsSource = (subject: Subject, input: AuthStrategyInput) => Promise<ReadonlyArray<Membership>> | ReadonlyArray<Membership>;
|
|
2973
3263
|
|
|
2974
|
-
/** In-memory store —
|
|
3264
|
+
/** In-memory store — one process only, with unique ownership per acquisition. */
|
|
2975
3265
|
export declare const memoryIdempotencyStore: () => IdempotencyStore;
|
|
2976
3266
|
|
|
2977
3267
|
/** The refusal a missing access decision produces. Exported so the boot gate
|
|
@@ -2983,6 +3273,25 @@ export declare const missingAccessDecision: (procedure?: string) => ScopeError;
|
|
|
2983
3273
|
* fits several tries. */
|
|
2984
3274
|
export declare const MUTATION_IN_FLIGHT_RETRY_AFTER_MS = 1000;
|
|
2985
3275
|
|
|
3276
|
+
/** Transaction-bound context for a plugin's required database contribution.
|
|
3277
|
+
* The executor result is available before the business transaction commits. */
|
|
3278
|
+
export declare interface MutationCommitContext extends RpcInterceptorContext {
|
|
3279
|
+
readonly kind: 'mutation';
|
|
3280
|
+
readonly store: DataStore;
|
|
3281
|
+
readonly output: unknown;
|
|
3282
|
+
/** Same enqueue facade as the executor, bound to this replay attempt. */
|
|
3283
|
+
readonly outbox?: OutboxEnqueueFacade;
|
|
3284
|
+
/** Runner invocation time, including guards and rolled-back retries. */
|
|
3285
|
+
readonly startedAt?: number;
|
|
3286
|
+
/** Elapsed milliseconds before required contribution work. */
|
|
3287
|
+
readonly durationMs?: number;
|
|
3288
|
+
}
|
|
3289
|
+
|
|
3290
|
+
/** Required transactional work, not an external side effect. A failure rolls
|
|
3291
|
+
* back the mutation. The hook may run again after a rolled-back contention
|
|
3292
|
+
* attempt, so all effects must remain on the supplied transaction store. */
|
|
3293
|
+
export declare type MutationCommitHook = (context: MutationCommitContext) => Effect.Effect<void, unknown>;
|
|
3294
|
+
|
|
2986
3295
|
/** A connection-scoped RPC cannot execute or replay without a live WebSocket.
|
|
2987
3296
|
* This is a transport precondition, not an authorization or membership grant. */
|
|
2988
3297
|
export declare class MutationConnectionRequired extends MutationConnectionRequired_base {
|
|
@@ -2993,6 +3302,18 @@ declare const MutationConnectionRequired_base: Schema.Class<MutationConnectionRe
|
|
|
2993
3302
|
readonly traceId: Schema.String;
|
|
2994
3303
|
}>, YieldableError>;
|
|
2995
3304
|
|
|
3305
|
+
/** Input refusal is terminal for this key, not an in-flight retry invitation.
|
|
3306
|
+
* No stored hash, input or response is disclosed. Check the original operation
|
|
3307
|
+
* before deliberately starting another business action. */
|
|
3308
|
+
export declare class MutationIdempotencyRefused extends MutationIdempotencyRefused_base {
|
|
3309
|
+
get message(): string;
|
|
3310
|
+
}
|
|
3311
|
+
|
|
3312
|
+
declare const MutationIdempotencyRefused_base: Schema.Class<MutationIdempotencyRefused, Schema.TaggedStruct<"MutationIdempotencyRefused", {
|
|
3313
|
+
readonly traceId: Schema.String;
|
|
3314
|
+
readonly reason: Schema.Literals<readonly ["input-conflict", "input-unbound", "input-unavailable"]>;
|
|
3315
|
+
}>, YieldableError>;
|
|
3316
|
+
|
|
2996
3317
|
/** Ordinary writes deduplicate across reconnects. A connection-side effect
|
|
2997
3318
|
* (for example joining a room) must execute once for EACH native connection. */
|
|
2998
3319
|
export declare type MutationIdempotencyScope = 'subject' | 'connection';
|
|
@@ -3020,6 +3341,12 @@ export declare interface MutationProcedureDescriptor<Name extends string, Input
|
|
|
3020
3341
|
readonly idempotencyScope?: MutationIdempotencyScope | undefined;
|
|
3021
3342
|
/** Same-key calls run in invocation order on the client — see `defineMutation`. */
|
|
3022
3343
|
readonly serialize?: MutationSerialization<Schema.Schema.Type<Input>> | undefined;
|
|
3344
|
+
/** Exclude this invocation from automatic row-image undo capture, with an
|
|
3345
|
+
* explicit domain reason. Does not disable transactions, guards or audit. */
|
|
3346
|
+
readonly undo?: {
|
|
3347
|
+
readonly capture: false;
|
|
3348
|
+
readonly reason: string;
|
|
3349
|
+
} | undefined;
|
|
3023
3350
|
/** Declarative target(s) — drives auto-optimistic on the client AND
|
|
3024
3351
|
* surfaces which tables this mutation touches (debug, future
|
|
3025
3352
|
* query-invalidation analytics). Mutations without a target run
|
|
@@ -3081,6 +3408,12 @@ export declare interface MutationSerialization<Input = unknown> {
|
|
|
3081
3408
|
|
|
3082
3409
|
export declare const mutationToRpc: <Name extends string, Input extends Schema.Top, Output extends Schema.Top, Err extends Schema.Top>(descriptor: MutationProcedureDescriptor<Name, Input, Output, Err>, extraErrors?: ExtraErrors) => Rpc.Rpc<Name, Input extends Schema.Struct.Fields ? Schema.Struct<Input> : Input, Output, Schema.Top, never, never>;
|
|
3083
3410
|
|
|
3411
|
+
export declare interface NativeFormCaptureDocument {
|
|
3412
|
+
readonly querySelectorAll: (selector: string) => ArrayLike<{
|
|
3413
|
+
readonly getAttribute: (name: string) => string | null;
|
|
3414
|
+
}>;
|
|
3415
|
+
}
|
|
3416
|
+
|
|
3084
3417
|
export declare interface NestedTargetFields<Input = unknown> {
|
|
3085
3418
|
/** Dot-path to the nested array within the query VALUE to patch (e.g.
|
|
3086
3419
|
* `'snapshot.projects'`). Absent → patch the top-level row array (default). */
|
|
@@ -3252,6 +3585,30 @@ export declare const openAccessSpec: (reason: string) => OpenAccessSpec;
|
|
|
3252
3585
|
*/
|
|
3253
3586
|
export declare const orderByBearerPrefix: (strategies: ReadonlyArray<AuthStrategy>, headers: Readonly<Record<string, string | undefined>>) => ReadonlyArray<AuthStrategy>;
|
|
3254
3587
|
|
|
3588
|
+
/** Enqueue-only capability bound to the caller's actual transaction store. */
|
|
3589
|
+
export declare interface OutboxEnqueueFacade {
|
|
3590
|
+
/** Returns the stable delivery identity. Delivery happens after commit. */
|
|
3591
|
+
enqueue(effect: string, payload: Record<string, unknown>, options?: EnqueueOptions): Promise<string>;
|
|
3592
|
+
}
|
|
3593
|
+
|
|
3594
|
+
/** Stable delivery context, shared by app and plugin handlers. */
|
|
3595
|
+
export declare interface OutboxHandlerContext {
|
|
3596
|
+
readonly outboxId: string;
|
|
3597
|
+
readonly idempotencyKey: string | null;
|
|
3598
|
+
readonly payload: Record<string, unknown>;
|
|
3599
|
+
readonly attempt: number;
|
|
3600
|
+
readonly subjectId: string | null;
|
|
3601
|
+
readonly tenantId: string | null;
|
|
3602
|
+
readonly traceId: string | null;
|
|
3603
|
+
}
|
|
3604
|
+
|
|
3605
|
+
/** Delivery happens after commit and may repeat; handlers must be idempotent. */
|
|
3606
|
+
export declare interface OutboxHandlerDefinition<R = never> {
|
|
3607
|
+
readonly effect: string;
|
|
3608
|
+
readonly handler: (context: OutboxHandlerContext) => Promise<unknown> | Effect.Effect<unknown, unknown, R>;
|
|
3609
|
+
readonly maxAttempts?: number;
|
|
3610
|
+
}
|
|
3611
|
+
|
|
3255
3612
|
export declare interface Pairing {
|
|
3256
3613
|
/** The api's base url as the DEVICE reaches it — a LAN address, never `localhost`. */
|
|
3257
3614
|
readonly api: string;
|
|
@@ -3294,6 +3651,21 @@ export declare const parseEventRoute: (route: string) => {
|
|
|
3294
3651
|
/** The record from a link, or `null` for anything that is not a pairing link. */
|
|
3295
3652
|
export declare const parsePairingLink: (url: string) => Pairing | null;
|
|
3296
3653
|
|
|
3654
|
+
/**
|
|
3655
|
+
* Parse a `revalidate` page export into a duration in milliseconds.
|
|
3656
|
+
*
|
|
3657
|
+
* Accepted shapes:
|
|
3658
|
+
* - number → seconds (Next.js compatibility)
|
|
3659
|
+
* - '<N> seconds' / 's'
|
|
3660
|
+
* - '<N> minutes' / 'm'
|
|
3661
|
+
* - '<N> hours' / 'h'
|
|
3662
|
+
* - '<N> days' / 'd'
|
|
3663
|
+
*
|
|
3664
|
+
* Returns null if the value is missing or unrecognised — caller treats
|
|
3665
|
+
* `null` as "don't cache" (every request re-renders, same as plain SSR).
|
|
3666
|
+
*/
|
|
3667
|
+
export declare const parseRevalidateMs: (value: unknown) => number | null;
|
|
3668
|
+
|
|
3297
3669
|
export declare const patchCellSchema: Schema.decodeTo<Schema.Unknown, Schema.Unknown, never, never>;
|
|
3298
3670
|
|
|
3299
3671
|
/** A single row in a subscription result. Must carry an `id`; everything
|
|
@@ -3339,6 +3711,49 @@ export declare type PendingApproval = Schema.Schema.Type<typeof PendingApproval>
|
|
|
3339
3711
|
/** The normalisation above, applied to any JSON Schema fragment. */
|
|
3340
3712
|
export declare const plainJsonSchema: (value: unknown) => unknown;
|
|
3341
3713
|
|
|
3714
|
+
export declare interface PluginAccountMergeContext extends PluginAccountMergeRequest {
|
|
3715
|
+
/** Borrow the coordinator's existing transaction. No external I/O, separate
|
|
3716
|
+
* pool, nested transaction or session grant belongs in a data hook. */
|
|
3717
|
+
readonly store: DataStore;
|
|
3718
|
+
}
|
|
3719
|
+
|
|
3720
|
+
export declare interface PluginAccountMergeCoverage {
|
|
3721
|
+
readonly participants: ReadonlyArray<{
|
|
3722
|
+
readonly name: string;
|
|
3723
|
+
readonly tables: ReadonlyArray<string>;
|
|
3724
|
+
}>;
|
|
3725
|
+
readonly missing: ReadonlyArray<string>;
|
|
3726
|
+
}
|
|
3727
|
+
|
|
3728
|
+
export declare class PluginAccountMergeFailure extends PluginAccountMergeFailure_base {
|
|
3729
|
+
}
|
|
3730
|
+
|
|
3731
|
+
declare const PluginAccountMergeFailure_base: Schema.Class<PluginAccountMergeFailure, Schema.TaggedStruct<"PluginAccountMergeFailure", {
|
|
3732
|
+
readonly code: Schema.Literals<readonly ["invalid_request", "coverage_missing", "hook_failed"]>;
|
|
3733
|
+
readonly requestId: Schema.String;
|
|
3734
|
+
readonly plugin: Schema.NullOr<Schema.String>;
|
|
3735
|
+
/** Hooks that returned before failure; never evidence of SQL commit. */
|
|
3736
|
+
readonly returned: Schema.$Array<Schema.String>;
|
|
3737
|
+
readonly missing: Schema.$Array<Schema.String>;
|
|
3738
|
+
}>, YieldableError>;
|
|
3739
|
+
|
|
3740
|
+
export declare type PluginAccountMergeHook = (context: PluginAccountMergeContext) => Effect.Effect<void, unknown>;
|
|
3741
|
+
|
|
3742
|
+
export declare interface PluginAccountMergeRegistry {
|
|
3743
|
+
readonly coverage: (kind: 'user' | 'guest') => PluginAccountMergeCoverage;
|
|
3744
|
+
/** The caller owns both-account authorization, confirmation, the transaction
|
|
3745
|
+
* and durable receipt. This registry neither commits nor withdraws identity. */
|
|
3746
|
+
readonly mergeInTransaction: (context: PluginAccountMergeContext) => Effect.Effect<ReadonlyArray<string>, PluginAccountMergeFailure>;
|
|
3747
|
+
}
|
|
3748
|
+
|
|
3749
|
+
export declare interface PluginAccountMergeRequest {
|
|
3750
|
+
readonly requestId: string;
|
|
3751
|
+
readonly tenantId: string;
|
|
3752
|
+
readonly sourceId: string;
|
|
3753
|
+
readonly sourceKind: 'user' | 'guest';
|
|
3754
|
+
readonly targetId: string;
|
|
3755
|
+
}
|
|
3756
|
+
|
|
3342
3757
|
/**
|
|
3343
3758
|
* Called once at app boot, after `voltro dev` resolves the plugin
|
|
3344
3759
|
* list and before the rpc server starts accepting connections. Use
|
|
@@ -3361,6 +3776,37 @@ export declare type PluginActivateHook = (ctx: PluginLifecycleContext) => Effect
|
|
|
3361
3776
|
export declare const pluginAlias: (pluginName: string) => string;
|
|
3362
3777
|
|
|
3363
3778
|
export declare interface PluginBindContext {
|
|
3779
|
+
/** Selected API work; absent custom-host selection means all workloads. */
|
|
3780
|
+
readonly workloads?: ReadonlyArray<ApiWorkload>;
|
|
3781
|
+
/** Starts the app's workflows from server work that has no request, such as
|
|
3782
|
+
* Room results. Present when the app declares workflows. */
|
|
3783
|
+
readonly workflows?: PluginWorkflowStarter;
|
|
3784
|
+
/** Execute an already-provided Effect, preserving typed failures as rejection
|
|
3785
|
+
* values. This does not inject request identity, app services or a new scope. */
|
|
3786
|
+
readonly runEffect?: <A, E>(effect: Effect.Effect<A, E>) => Promise<A>;
|
|
3787
|
+
/** Execute server work with the actual shared app services, including user
|
|
3788
|
+
* Layer overrides, in a scope owned by this call. Available after the host
|
|
3789
|
+
* assembles its service layer, never during store binding or shutdown. No
|
|
3790
|
+
* request Subject, request-local store or transaction is injected. Consume
|
|
3791
|
+
* borrowed services inside the Effect; do not return them beyond its scope.
|
|
3792
|
+
* The host drains admitted calls before plugin/pool teardown. */
|
|
3793
|
+
readonly runWithAppServices?: <A, E, R>(effect: Effect.Effect<A, E, R>) => Promise<A>;
|
|
3794
|
+
/** App-owned subject hook registry. The server caller owns authorization and withdrawal. */
|
|
3795
|
+
readonly privacyRegistry?: PluginPrivacyRegistry;
|
|
3796
|
+
/** App-owned plugin namespace; tenant acquisition remains explicit and isolated. */
|
|
3797
|
+
readonly hotStore?: (context?: {
|
|
3798
|
+
readonly tenantId: string;
|
|
3799
|
+
}) => Promise<HotStoreShape>;
|
|
3800
|
+
/** Same borrowed registry as lifecycle hooks; the API host owns its pools. */
|
|
3801
|
+
readonly connectionRegistry?: ConnectionRegistryShape;
|
|
3802
|
+
readonly connectionReference?: PluginConnectionReference;
|
|
3803
|
+
readonly connectionAvailability?: PluginConnectionAvailability;
|
|
3804
|
+
/** Resolve the registered owner's retained destination for physical reference
|
|
3805
|
+
* protection. Borrowed app wiring; never substitutes the caller's provider. */
|
|
3806
|
+
readonly storageReferenceProvider?: (input: {
|
|
3807
|
+
readonly storageInstance: string;
|
|
3808
|
+
readonly address: StorageAddress;
|
|
3809
|
+
}) => Effect.Effect<StorageProvider, StorageError>;
|
|
3364
3810
|
/**
|
|
3365
3811
|
* This process's replica identity — the same value the event bus stamps as
|
|
3366
3812
|
* its publish `origin` and the membership registry announces under.
|
|
@@ -3380,6 +3826,16 @@ export declare interface PluginBindContext {
|
|
|
3380
3826
|
* who is on the channel, and an instance that dies simply goes quiet.
|
|
3381
3827
|
*/
|
|
3382
3828
|
readonly membership?: {
|
|
3829
|
+
/** Current receiver-observed members from the same app-owned registry.
|
|
3830
|
+
* Optional for custom hosts providing only change notifications. Borrowed:
|
|
3831
|
+
* plugins must not start, stop or replace the membership owner. */
|
|
3832
|
+
readonly list?: () => ReadonlyArray<{
|
|
3833
|
+
readonly instanceId: string;
|
|
3834
|
+
readonly startedAt: number;
|
|
3835
|
+
readonly meta: Readonly<Record<string, string | number>> | undefined;
|
|
3836
|
+
readonly lastHeardAt: number;
|
|
3837
|
+
readonly self: boolean;
|
|
3838
|
+
}>;
|
|
3383
3839
|
readonly onChange: (listener: (event: {
|
|
3384
3840
|
readonly kind: 'joined' | 'left' | 'restarted';
|
|
3385
3841
|
readonly instanceId: string;
|
|
@@ -3487,6 +3943,14 @@ export declare interface PluginCacheHandle {
|
|
|
3487
3943
|
|
|
3488
3944
|
export declare interface PluginCapabilities {
|
|
3489
3945
|
readonly mediaPersist?: PluginMediaPersistCapability;
|
|
3946
|
+
/** Borrow this app instance's bound object transport; the caller owns no pools. */
|
|
3947
|
+
readonly storageProvider?: () => StorageProvider;
|
|
3948
|
+
/** Address-aware object ownership; request tenant resolution is never global. */
|
|
3949
|
+
readonly storageDestinations?: {
|
|
3950
|
+
readonly router: StorageDestinationRouter;
|
|
3951
|
+
readonly directDestination: string | undefined;
|
|
3952
|
+
readonly registry: () => ConnectionRegistryShape | undefined;
|
|
3953
|
+
};
|
|
3490
3954
|
}
|
|
3491
3955
|
|
|
3492
3956
|
/**
|
|
@@ -3608,6 +4072,36 @@ export declare interface PluginCodegenContext {
|
|
|
3608
4072
|
}>;
|
|
3609
4073
|
}
|
|
3610
4074
|
|
|
4075
|
+
/** Resolves only this plugin's admitted role; omitted policy means fail. */
|
|
4076
|
+
export declare type PluginConnectionAvailability = (role: string) => ConnectionUnavailablePolicy;
|
|
4077
|
+
|
|
4078
|
+
export declare interface PluginConnectionNeed {
|
|
4079
|
+
readonly onUnavailable?: ConnectionUnavailablePolicy;
|
|
4080
|
+
readonly kind: ConnectionKind_2;
|
|
4081
|
+
readonly role: string;
|
|
4082
|
+
readonly crossNode?: boolean;
|
|
4083
|
+
/** Use the plugin's direct transport only when no declaration or binding selects this role. */
|
|
4084
|
+
readonly optional?: boolean;
|
|
4085
|
+
}
|
|
4086
|
+
|
|
4087
|
+
/**
|
|
4088
|
+
* Per-app context handed to lifecycle hooks. The shape is intentionally
|
|
4089
|
+
* thin — the framework's deeper services (DataStore, Logger, etc.) are
|
|
4090
|
+
* available via the per-request `AppContext` plugins see in their rpc
|
|
4091
|
+
* interceptors. Lifecycle hooks run OUTSIDE any request, so they
|
|
4092
|
+
* receive a minimal slice:
|
|
4093
|
+
*
|
|
4094
|
+
* - `app`: the resolved app-config metadata
|
|
4095
|
+
* (`{ name, type, voltroVersion }`).
|
|
4096
|
+
* - `logger`: a scoped `@voltro/logger` instance keyed to the
|
|
4097
|
+
* plugin's `name`, so log lines are attributable.
|
|
4098
|
+
* - `env`: the process env (alias of `process.env` for typing).
|
|
4099
|
+
* - `config`: the plugin's own validated config (if `configSchema`
|
|
4100
|
+
* declared) — already decoded against the plugin's Schema, ready
|
|
4101
|
+
* for the hook to consume. Unknown otherwise.
|
|
4102
|
+
*/
|
|
4103
|
+
export declare type PluginConnectionReference = <K extends ConnectionKind_2>(role: string, kind: K) => ConnectionRef<K> | '';
|
|
4104
|
+
|
|
3611
4105
|
/**
|
|
3612
4106
|
* A remote-mounted dashboard surface a plugin contributes. The
|
|
3613
4107
|
* dashboard-host (voltro-cloud / voltro-devtools) renders the mount
|
|
@@ -3718,6 +4212,8 @@ export declare interface PluginEnvVar {
|
|
|
3718
4212
|
readonly generate?: 'base64url' | 'hex' | 'p256';
|
|
3719
4213
|
}
|
|
3720
4214
|
|
|
4215
|
+
export declare type PluginEraseHook = (subjectId: string, context: PluginPrivacyHookContext) => Effect.Effect<void, unknown>;
|
|
4216
|
+
|
|
3721
4217
|
/**
|
|
3722
4218
|
* A cross-cutting error schema a plugin merges into EVERY procedure's
|
|
3723
4219
|
* wire error union. Use when a plugin interceptor can fail with a typed
|
|
@@ -3756,8 +4252,26 @@ export declare interface PluginErrorSchema {
|
|
|
3756
4252
|
};
|
|
3757
4253
|
}
|
|
3758
4254
|
|
|
4255
|
+
/**
|
|
4256
|
+
* Per-call context handed to a plugin-contributed rpc route's
|
|
4257
|
+
* executor. Mirror of the user-handler `AppContext` shape but typed
|
|
4258
|
+
* loosely so the plugin doesn't need to depend on `@voltro/runtime`.
|
|
4259
|
+
*/
|
|
4260
|
+
/** Structural view of the existing request-scoped typed publisher. No runtime import. */
|
|
4261
|
+
export declare interface PluginEventPublisher {
|
|
4262
|
+
publish<Name extends string, Key extends Schema.Top, Payload extends Schema.Top>(descriptor: EventDescriptor<Name, Key, Payload>, key: Schema.Schema.Type<Key>, payload: Schema.Schema.Type<Payload>): Effect.Effect<unknown, unknown>;
|
|
4263
|
+
}
|
|
4264
|
+
|
|
4265
|
+
export declare type PluginExportHook = (subjectId: string, context: PluginPrivacyHookContext) => Effect.Effect<unknown, unknown>;
|
|
4266
|
+
|
|
3759
4267
|
/** A public raw-HTTP route a plugin serves on the framework listener. */
|
|
3760
4268
|
export declare interface PluginHttpRoute {
|
|
4269
|
+
/** Executable API workload owning this route. Omitted means `rpc`.
|
|
4270
|
+
* Discovery and descriptor generation remain independent of role selection. */
|
|
4271
|
+
readonly workload?: ApiWorkload;
|
|
4272
|
+
/** The already-mounted REST projection, retained for SDK/schema inspection.
|
|
4273
|
+
* Do not remount it through generic REST auth or idempotency bindings. */
|
|
4274
|
+
readonly restContract?: RestRouteDescriptor<any, any>;
|
|
3761
4275
|
/** HTTP method, or `'*'` for any (the handler decides). The server mounts the
|
|
3762
4276
|
* path for exactly the methods its routes declare; `'*'` mounts it for every
|
|
3763
4277
|
* method the router knows (34), so keep that for a route that really serves
|
|
@@ -3786,6 +4300,13 @@ export declare interface PluginHttpRoute {
|
|
|
3786
4300
|
*/
|
|
3787
4301
|
readonly match?: 'prefix' | 'exact';
|
|
3788
4302
|
readonly handle: (req: PluginHttpRouteRequest) => Promise<PluginHttpRouteResult>;
|
|
4303
|
+
/** Lazy, backpressured input instead of a buffered rawBody on real HTTP.
|
|
4304
|
+
* Requires match: 'exact' and exclusive ownership of the router-equivalent
|
|
4305
|
+
* path (including other methods). The required handle remains the buffered
|
|
4306
|
+
* in-process entry. Both entries must apply the same authorization/codec.
|
|
4307
|
+
* maxBodyBytes counts consumed bytes; overflow overrides the handler's
|
|
4308
|
+
* response with 413 even when the handler catches the read error. */
|
|
4309
|
+
readonly handleStream?: (req: PluginHttpRouteStreamRequest) => Promise<PluginHttpRouteResult>;
|
|
3789
4310
|
/** Per-route body cap override (bytes) — wins over the listener's shared
|
|
3790
4311
|
* `maxBodyBytes`. NOTE: routes SHARING a path share one body read, so the
|
|
3791
4312
|
* widest override on the path's group applies to the whole group. */
|
|
@@ -3826,6 +4347,9 @@ export declare interface PluginHttpRoute {
|
|
|
3826
4347
|
* handler branches on: exempting `/saml` exempts `POST /saml/anything`.
|
|
3827
4348
|
*/
|
|
3828
4349
|
readonly originGuard?: 'exempt';
|
|
4350
|
+
readonly cors?: RestCors;
|
|
4351
|
+
/** Bearer-only routes must discard cookie authority before authentication. */
|
|
4352
|
+
readonly credentials?: 'bearer';
|
|
3829
4353
|
}
|
|
3830
4354
|
|
|
3831
4355
|
/**
|
|
@@ -4009,11 +4533,23 @@ export declare interface PluginHttpRouteResult {
|
|
|
4009
4533
|
*/
|
|
4010
4534
|
export declare interface PluginHttpRouteStream {
|
|
4011
4535
|
readonly subscribe: (emit: (chunk: string) => void) => () => void;
|
|
4536
|
+
/** Per-connection lifetime in milliseconds (1..2147483647). Ending the
|
|
4537
|
+
* response releases the subscription and keep-alive timer. Absent: no cap. */
|
|
4538
|
+
readonly maxDurationMs?: number;
|
|
4012
4539
|
/** Keep-alive comment interval in ms (default 15000; `0` disables). Without
|
|
4013
4540
|
* it an idle SSE connection is dropped by proxies after ~30–60s. */
|
|
4014
4541
|
readonly keepAliveMs?: number;
|
|
4015
4542
|
}
|
|
4016
4543
|
|
|
4544
|
+
/** A lazy binary request on the framework listener. No body bytes are read
|
|
4545
|
+
* before the handler runs. Consume once, through EOF, before accepting an
|
|
4546
|
+
* upload; returning early drains the unread body without validating it.
|
|
4547
|
+
* The signal ends on disconnect, interruption or handler completion. */
|
|
4548
|
+
export declare interface PluginHttpRouteStreamRequest extends Omit<PluginHttpRouteRequest, 'rawBody'> {
|
|
4549
|
+
readonly body: AsyncIterable<Uint8Array>;
|
|
4550
|
+
readonly signal: AbortSignal;
|
|
4551
|
+
}
|
|
4552
|
+
|
|
4017
4553
|
export declare interface PluginInspectEndpoint {
|
|
4018
4554
|
/** HTTP method. */
|
|
4019
4555
|
readonly method: 'GET' | 'POST' | 'DELETE';
|
|
@@ -4142,23 +4678,9 @@ export declare const pluginInstanceName: (args: {
|
|
|
4142
4678
|
readonly instance?: string | undefined;
|
|
4143
4679
|
}) => string;
|
|
4144
4680
|
|
|
4145
|
-
/**
|
|
4146
|
-
* Per-app context handed to lifecycle hooks. The shape is intentionally
|
|
4147
|
-
* thin — the framework's deeper services (DataStore, Logger, etc.) are
|
|
4148
|
-
* available via the per-request `AppContext` plugins see in their rpc
|
|
4149
|
-
* interceptors. Lifecycle hooks run OUTSIDE any request, so they
|
|
4150
|
-
* receive a minimal slice:
|
|
4151
|
-
*
|
|
4152
|
-
* - `app`: the resolved app-config metadata
|
|
4153
|
-
* (`{ name, type, voltroVersion }`).
|
|
4154
|
-
* - `logger`: a scoped `@voltro/logger` instance keyed to the
|
|
4155
|
-
* plugin's `name`, so log lines are attributable.
|
|
4156
|
-
* - `env`: the process env (alias of `process.env` for typing).
|
|
4157
|
-
* - `config`: the plugin's own validated config (if `configSchema`
|
|
4158
|
-
* declared) — already decoded against the plugin's Schema, ready
|
|
4159
|
-
* for the hook to consume. Unknown otherwise.
|
|
4160
|
-
*/
|
|
4161
4681
|
export declare interface PluginLifecycleContext {
|
|
4682
|
+
/** Selected API work; absent custom-host selection means all workloads. */
|
|
4683
|
+
readonly workloads?: ReadonlyArray<ApiWorkload>;
|
|
4162
4684
|
readonly app: {
|
|
4163
4685
|
readonly name: string;
|
|
4164
4686
|
readonly type: 'api' | 'web';
|
|
@@ -4173,6 +4695,11 @@ export declare interface PluginLifecycleContext {
|
|
|
4173
4695
|
readonly env: NodeJS.ProcessEnv;
|
|
4174
4696
|
/** Validated plugin config (if `configSchema` was declared). */
|
|
4175
4697
|
readonly config: unknown;
|
|
4698
|
+
/** App-owned command registry, available before API plugin activation. Never dispose it. */
|
|
4699
|
+
readonly connectionRegistry?: ConnectionRegistryShape;
|
|
4700
|
+
/** Resolve only this plugin's declared role through the app's binding/default. */
|
|
4701
|
+
readonly connectionReference?: PluginConnectionReference;
|
|
4702
|
+
readonly connectionAvailability?: PluginConnectionAvailability;
|
|
4176
4703
|
}
|
|
4177
4704
|
|
|
4178
4705
|
/** Where the offloaded-inference dispatcher puts a media artifact a provider
|
|
@@ -4257,7 +4784,13 @@ export declare type PluginMigrationSqlClient = SqlClient.SqlClient;
|
|
|
4257
4784
|
* boot log + `/_voltro/inspect/plugins` so operators audit what each
|
|
4258
4785
|
* plugin asks for before installing.
|
|
4259
4786
|
*/
|
|
4260
|
-
export declare type PluginPermission = 'rpc:intercept:mutation' | 'rpc:intercept:query' | 'rpc:intercept:action' | 'rpc:intercept:workflow' | 'schedule:fire' | 'schedule:read' | 'workflow:step' | 'http:intercept' | 'inspect:read' | 'inspect:write' | 'dashboard:mount' | 'store:write' | 'migration:run' | 'store:changes:read' | `secrets:read:${string}` | `network:outbound:${string}` | `plugin:hook:${string}`;
|
|
4787
|
+
export declare type PluginPermission = 'rpc:authority:replay' | 'rpc:intercept:mutation' | 'rpc:intercept:query' | 'rpc:intercept:action' | 'rpc:intercept:workflow' | 'rpc:intercept:stream' | 'schedule:fire' | 'schedule:read' | 'workflow:step' | 'http:intercept' | 'inspect:read' | 'inspect:write' | 'dashboard:mount' | 'outbox:handle' | 'store:write' | 'migration:run' | 'store:changes:read' | `secrets:read:${string}` | `network:outbound:${string}` | `plugin:hook:${string}`;
|
|
4788
|
+
|
|
4789
|
+
export declare interface PluginPrivacyCoverage {
|
|
4790
|
+
readonly participants: ReadonlyArray<PluginPrivacyParticipant>;
|
|
4791
|
+
/** Plugin declarations only. App-owned tables require their own declared hooks. */
|
|
4792
|
+
readonly missing: ReadonlyArray<string>;
|
|
4793
|
+
}
|
|
4261
4794
|
|
|
4262
4795
|
/** What a plugin collects and uses — folded by `voltro compliance generate`
|
|
4263
4796
|
* into PrivacyInfo.xcprivacy and the Play Data-safety answers. A plugin that
|
|
@@ -4267,12 +4800,76 @@ export declare interface PluginPrivacyDeclaration {
|
|
|
4267
4800
|
readonly requiredReasonApis?: ReadonlyArray<PrivacyRequiredReasonApi>;
|
|
4268
4801
|
}
|
|
4269
4802
|
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4803
|
+
export declare type PluginPrivacyErasePhase = typeof PluginPrivacyErasePhaseSchema.Type;
|
|
4804
|
+
|
|
4805
|
+
/** Resource/actor withdrawal must finish before destructive data hooks. */
|
|
4806
|
+
export declare const PluginPrivacyErasePhaseSchema: Schema.Literals<readonly ["prepare", "data", "identity", "finalize"]>;
|
|
4807
|
+
|
|
4808
|
+
export declare interface PluginPrivacyErasure {
|
|
4809
|
+
readonly requestId: string;
|
|
4810
|
+
readonly target: PluginPrivacyTarget;
|
|
4811
|
+
readonly completed: ReadonlyArray<string>;
|
|
4812
|
+
}
|
|
4813
|
+
|
|
4814
|
+
export declare interface PluginPrivacyExport {
|
|
4815
|
+
readonly requestId: string;
|
|
4816
|
+
readonly target: PluginPrivacyTarget;
|
|
4817
|
+
readonly plugins: ReadonlyArray<{
|
|
4818
|
+
readonly name: string;
|
|
4819
|
+
readonly data: unknown;
|
|
4820
|
+
}>;
|
|
4821
|
+
}
|
|
4822
|
+
|
|
4823
|
+
/** Never carries a driver's error, credentials, exported rows or the hook's cause. */
|
|
4824
|
+
export declare class PluginPrivacyFailure extends PluginPrivacyFailure_base {
|
|
4825
|
+
}
|
|
4826
|
+
|
|
4827
|
+
declare const PluginPrivacyFailure_base: Schema.Class<PluginPrivacyFailure, Schema.TaggedStruct<"PluginPrivacyFailure", {
|
|
4828
|
+
readonly code: Schema.Literals<readonly ["invalid_request", "coverage_missing", "hook_failed", "unavailable"]>;
|
|
4829
|
+
readonly operation: Schema.Literals<readonly ["export", "erase"]>;
|
|
4830
|
+
readonly requestId: Schema.String;
|
|
4831
|
+
readonly plugin: Schema.NullOr<Schema.String>;
|
|
4832
|
+
readonly completed: Schema.$Array<Schema.String>;
|
|
4833
|
+
readonly missing: Schema.$Array<Schema.String>;
|
|
4834
|
+
}>, YieldableError>;
|
|
4835
|
+
|
|
4836
|
+
export declare interface PluginPrivacyHookContext {
|
|
4837
|
+
readonly requestId: string;
|
|
4838
|
+
readonly tenantId: string | null;
|
|
4839
|
+
readonly kind: 'user' | 'guest';
|
|
4840
|
+
/** Only the finalizer receives these immutable, successfully completed hook names. */
|
|
4841
|
+
readonly completed?: ReadonlyArray<string>;
|
|
4842
|
+
}
|
|
4843
|
+
|
|
4844
|
+
export declare interface PluginPrivacyParticipant {
|
|
4845
|
+
readonly name: string;
|
|
4846
|
+
readonly tables: ReadonlyArray<string>;
|
|
4847
|
+
readonly erasePhase: PluginPrivacyErasePhase;
|
|
4848
|
+
}
|
|
4849
|
+
|
|
4850
|
+
/** Borrowed app-owned hook port. Authorization and durable withdrawal belong to the caller. */
|
|
4851
|
+
export declare interface PluginPrivacyRegistry {
|
|
4852
|
+
readonly coverage: (kind: PluginPrivacyTarget['kind']) => PluginPrivacyCoverage;
|
|
4853
|
+
readonly exportSubject: (request: PluginPrivacyRequest) => Effect.Effect<PluginPrivacyExport, PluginPrivacyFailure>;
|
|
4854
|
+
readonly eraseSubject: (request: PluginPrivacyRequest) => Effect.Effect<PluginPrivacyErasure, PluginPrivacyFailure>;
|
|
4855
|
+
}
|
|
4856
|
+
|
|
4857
|
+
/** Reuse the request identity on recovery; hooks must be idempotent. */
|
|
4858
|
+
export declare interface PluginPrivacyRequest {
|
|
4859
|
+
readonly requestId: string;
|
|
4860
|
+
readonly target: PluginPrivacyTarget;
|
|
4861
|
+
}
|
|
4862
|
+
|
|
4863
|
+
/** A server-authorized subject, never an identity accepted from a client body. */
|
|
4864
|
+
export declare interface PluginPrivacyTarget {
|
|
4865
|
+
readonly subjectId: string;
|
|
4866
|
+
readonly tenantId: string | null;
|
|
4867
|
+
readonly kind: 'user' | 'guest';
|
|
4868
|
+
}
|
|
4869
|
+
|
|
4275
4870
|
export declare interface PluginRouteContext {
|
|
4871
|
+
/** Borrows the host request publisher, preserving tenant and transaction ownership. */
|
|
4872
|
+
readonly events?: PluginEventPublisher;
|
|
4276
4873
|
/** Request-scoped transaction for mutation routes. Reuse it instead of opening
|
|
4277
4874
|
* a transaction on the plugin's bound root store. Absent on direct calls. */
|
|
4278
4875
|
readonly mutationStore?: DataStore;
|
|
@@ -4375,6 +4972,8 @@ export declare interface PluginRpcRoute {
|
|
|
4375
4972
|
* checking.
|
|
4376
4973
|
*/
|
|
4377
4974
|
readonly source?: ReactivitySourceValue | ReadonlyArray<ReactivitySourceValue> | undefined;
|
|
4975
|
+
/** Optional integration observers; each name must also occur in source. */
|
|
4976
|
+
readonly optionalSource?: ReadonlyArray<string> | undefined;
|
|
4378
4977
|
/**
|
|
4379
4978
|
* The route's ACCESS DECISION — the same two-field vocabulary user
|
|
4380
4979
|
* procedures carry, because a plugin route is dispatched through the exact
|
|
@@ -4441,6 +5040,23 @@ export declare interface PluginSchemaContribution {
|
|
|
4441
5040
|
*/
|
|
4442
5041
|
export declare const pluginSlug: (pluginName: string) => string;
|
|
4443
5042
|
|
|
5043
|
+
export declare interface PluginSubjectMerge {
|
|
5044
|
+
readonly tables: ReadonlyArray<string>;
|
|
5045
|
+
/** Source kinds whose data this implementation can reconcile. */
|
|
5046
|
+
readonly kinds: ReadonlyArray<'user' | 'guest'>;
|
|
5047
|
+
}
|
|
5048
|
+
|
|
5049
|
+
/** SQL tables owned by this hook pair. External resources belong in the hooks too. */
|
|
5050
|
+
export declare interface PluginSubjectPrivacy {
|
|
5051
|
+
readonly tables: ReadonlyArray<string>;
|
|
5052
|
+
readonly kinds: ReadonlyArray<PluginPrivacyTarget['kind']>;
|
|
5053
|
+
/** Preparation withdraws active work before data hooks. Identity/session
|
|
5054
|
+
* deletion follows every data hook, regardless of plugin order. */
|
|
5055
|
+
/** Terminal request bookkeeping follows every data and identity hook.
|
|
5056
|
+
* At most one finalizer may own completion for each subject kind. */
|
|
5057
|
+
readonly erasePhase?: PluginPrivacyErasePhase;
|
|
5058
|
+
}
|
|
5059
|
+
|
|
4444
5060
|
/**
|
|
4445
5061
|
* The wire tag a plugin's own client code must call for one of its routes.
|
|
4446
5062
|
*
|
|
@@ -4523,6 +5139,20 @@ export declare interface PluginTemplate {
|
|
|
4523
5139
|
*/
|
|
4524
5140
|
export declare type PluginUninstallHook = (ctx: PluginLifecycleContext) => Effect.Effect<void, unknown> | Promise<void> | void;
|
|
4525
5141
|
|
|
5142
|
+
/** Starts app workflows from plugin server work outside a request. */
|
|
5143
|
+
export declare interface PluginWorkflowStarter {
|
|
5144
|
+
/** Resolves once the run is accepted. Runs as the plugin's system subject
|
|
5145
|
+
* (`plugin:<name>`); rejects while the host's workflow runtime is not ready. */
|
|
5146
|
+
start(workflowName: string, payload: unknown): Promise<unknown>;
|
|
5147
|
+
}
|
|
5148
|
+
|
|
5149
|
+
export declare type PluginWorkloadHook = (context: PluginLifecycleContext) => Effect.Effect<PluginWorkloadResource, unknown> | Promise<PluginWorkloadResource> | PluginWorkloadResource;
|
|
5150
|
+
|
|
5151
|
+
export declare interface PluginWorkloadResource {
|
|
5152
|
+
/** Await drainage; rejection retains ownership and must be retryable. */
|
|
5153
|
+
stop(): Effect.Effect<void, unknown> | Promise<void> | void;
|
|
5154
|
+
}
|
|
5155
|
+
|
|
4526
5156
|
/** The runtime-erased form of `PolicyGuardSpec` — a relationship check. */
|
|
4527
5157
|
export declare interface PolicyCheckSpec {
|
|
4528
5158
|
readonly action: string | ((input: unknown) => string);
|
|
@@ -4579,6 +5209,17 @@ export declare interface PolicyGuardSpec<Input = unknown> {
|
|
|
4579
5209
|
readonly resource: (input: Input) => string | undefined;
|
|
4580
5210
|
}
|
|
4581
5211
|
|
|
5212
|
+
export declare interface PreparedIdempotentInput {
|
|
5213
|
+
readonly input: unknown;
|
|
5214
|
+
readonly fingerprint: string;
|
|
5215
|
+
}
|
|
5216
|
+
|
|
5217
|
+
/** Capture the declared schema's wire input before waiting for a receipt.
|
|
5218
|
+
* Decode an independent snapshot for execution and require an equal round trip.
|
|
5219
|
+
* The principal comes from server authentication, never a client digest/header.
|
|
5220
|
+
* This binds identity and input, not current permissions or a business lease. */
|
|
5221
|
+
export declare const prepareIdempotentInput: (schema: Schema.Top, offered: unknown, subject: Subject, transportInput?: unknown) => Promise<PreparedIdempotentInput>;
|
|
5222
|
+
|
|
4582
5223
|
/**
|
|
4583
5224
|
* An environment variable a plugin reads. DECLARATION ONLY — metadata, not a
|
|
4584
5225
|
* read path: the plugin still reads the value itself (typically
|
|
@@ -4673,6 +5314,9 @@ export declare interface PublicApiClientConfig {
|
|
|
4673
5314
|
readonly baseUrl?: string;
|
|
4674
5315
|
}
|
|
4675
5316
|
|
|
5317
|
+
/** A descriptor kind that can be projected to REST (streams are not, in v1). */
|
|
5318
|
+
declare type PublicApiDescriptor = QueryProcedureDescriptor<string, Schema.Top, Schema.Top, Schema.Top> | MutationProcedureDescriptor<string, Schema.Top, Schema.Top, Schema.Top> | ActionProcedureDescriptor<string, Schema.Top, Schema.Top, Schema.Top>;
|
|
5319
|
+
|
|
4676
5320
|
/** The `publicApi:` block of an api `app.config.ts`, and the shape of a
|
|
4677
5321
|
* descriptor's `publicApi.format` override (every field optional there). */
|
|
4678
5322
|
export declare interface PublicApiProfileConfig {
|
|
@@ -4749,6 +5393,10 @@ export declare interface PublicApiSpec {
|
|
|
4749
5393
|
/** Streaming queries over request/response: 'snapshot' (default — first
|
|
4750
5394
|
* snapshot, like POST /rpc) | 'sse' (Server-Sent Events of snapshot+deltas). */
|
|
4751
5395
|
readonly stream?: 'snapshot' | 'sse';
|
|
5396
|
+
/** Per-connection SSE lifetime in milliseconds (1..2147483647). Requires
|
|
5397
|
+
* an SSE query projection. Clients may reconnect for a freshly authorized
|
|
5398
|
+
* snapshot; expiry does not cancel a domain operation. */
|
|
5399
|
+
readonly streamMaxDurationMs?: number;
|
|
4752
5400
|
/**
|
|
4753
5401
|
* HTTP status per DECLARED typed error tag, for the projection. A typed
|
|
4754
5402
|
* error the handler fails with — one of the descriptor's `error:` union —
|
|
@@ -4760,6 +5408,11 @@ export declare interface PublicApiSpec {
|
|
|
4760
5408
|
* publicApi: { errorStatus: { AccessDeniedError: 403, NotFoundError: 404 } }
|
|
4761
5409
|
*/
|
|
4762
5410
|
readonly errorStatus?: Readonly<Record<string, number>>;
|
|
5411
|
+
/** Additional HTTP failure statuses for the same declared error schema.
|
|
5412
|
+
* Documents dedicated handlers that choose a status from the error's fields;
|
|
5413
|
+
* does not change `errorStatus` or the generic projection's runtime mapping.
|
|
5414
|
+
* Values must be integer HTTP error statuses (400–599); duplicates are omitted. */
|
|
5415
|
+
readonly additionalErrorStatuses?: Readonly<Record<string, ReadonlyArray<number>>>;
|
|
4763
5416
|
/**
|
|
4764
5417
|
* The spec's tag group(s) for this operation. Default: the rpc tag's prefix
|
|
4765
5418
|
* (`teams.list` → `teams`) — the first path segment, what a consumer looks
|
|
@@ -4861,6 +5514,16 @@ export declare interface QueryCacheConfig {
|
|
|
4861
5514
|
* cardinality of a cache the author sized per org.
|
|
4862
5515
|
*/
|
|
4863
5516
|
readonly scope: 'subject' | 'tenant' | 'global';
|
|
5517
|
+
/**
|
|
5518
|
+
* The handler's result also depends on something no table write
|
|
5519
|
+
* invalidates — the clock, randomness, `ctx.connections`, an outgoing HTTP
|
|
5520
|
+
* call, `ctx.kv`. Applies to a COMPUTED query (a handler that returns a
|
|
5521
|
+
* value): without it such a result is computed but NOT kept, and the dev log
|
|
5522
|
+
* names what was used. With it, `ttl` is the bound on how stale that part may
|
|
5523
|
+
* be. `Date.now()`, `Math.random()` and a `fetch` outside the framework's
|
|
5524
|
+
* HTTP client are not observable — a handler that uses them must say so here.
|
|
5525
|
+
*/
|
|
5526
|
+
readonly volatile?: boolean | undefined;
|
|
4864
5527
|
}
|
|
4865
5528
|
|
|
4866
5529
|
export declare interface QueryProcedureDescriptor<Name extends string, Input extends Schema.Top, Output extends Schema.Top, Error extends Schema.Top> {
|
|
@@ -4875,6 +5538,9 @@ export declare interface QueryProcedureDescriptor<Name extends string, Input ext
|
|
|
4875
5538
|
* listed table changes (pass an array to depend on several). Optional:
|
|
4876
5539
|
* queries without a source never receive auto-patches (joins, aggregates). */
|
|
4877
5540
|
readonly source: string | ReadonlyArray<string> | undefined;
|
|
5541
|
+
/** Optional integration observers, all also present in source. They keep
|
|
5542
|
+
* invalidation active when installed; absence is a visible graph warning. */
|
|
5543
|
+
readonly optionalSource?: ReadonlyArray<string>;
|
|
4878
5544
|
/** Server-side snapshot cache config. Absent → never cached (the
|
|
4879
5545
|
* default; the dispatcher already keeps live subscriptions fresh). */
|
|
4880
5546
|
readonly cache: QueryCacheConfig | undefined;
|
|
@@ -4950,7 +5616,7 @@ export declare const queryToRpc: <Name extends string, Input extends Schema.Top,
|
|
|
4950
5616
|
}>;
|
|
4951
5617
|
}>, Schema.Struct<{
|
|
4952
5618
|
readonly _tag: Schema.Literal<"error">;
|
|
4953
|
-
readonly error: Schema.Unknown
|
|
5619
|
+
readonly error: Schema.decodeTo<Schema.Unknown, Schema.Codec<Schema.Json, Schema.Json, never, never>, never, never>;
|
|
4954
5620
|
readonly revision: Schema.optional<Schema.Number>;
|
|
4955
5621
|
}>]>, Schema.Top>, Schema.Never, never, never>;
|
|
4956
5622
|
|
|
@@ -5029,8 +5695,24 @@ export declare type ReactivitySource = TableName | ReactivityChannel;
|
|
|
5029
5695
|
*/
|
|
5030
5696
|
export declare type ReactivitySourceValue = string | ReactivityChannel;
|
|
5031
5697
|
|
|
5698
|
+
export declare const readFormCaptureSource: (document?: NativeFormCaptureDocument | undefined) => string | undefined;
|
|
5699
|
+
|
|
5032
5700
|
export declare const readPairing: (storage: PairingStorage) => Promise<Pairing | null>;
|
|
5033
5701
|
|
|
5702
|
+
/**
|
|
5703
|
+
* Reauthenticate a live grant through its original strategy chain. Tenant and
|
|
5704
|
+
* principal identity stay bound to the original subscription: changing either
|
|
5705
|
+
* requires a new subscription, never reuse of an already scoped descriptor.
|
|
5706
|
+
* Runtime-owned subjects without a request binding retain their explicit grant.
|
|
5707
|
+
*/
|
|
5708
|
+
export declare const reauthorizeSubject: (subject: Subject, prepare?: (fresh: Subject) => Promise<void>) => Promise<Subject>;
|
|
5709
|
+
|
|
5710
|
+
/** Recheck a live grant through fresh authentication and derived authority. */
|
|
5711
|
+
export declare const recheckGuardsEffect: (subject: Subject, guards: ReadonlyArray<AnyCheckSpec> | undefined, input: unknown, options?: GuardCheckOptions) => Effect.Effect<ScopeError | Unauthenticated | RequestedTenantRefused | NoSuchResource | null>;
|
|
5712
|
+
|
|
5713
|
+
/** Refresh derived authority without replaying unrelated RPC plugin hooks. */
|
|
5714
|
+
export declare const refreshEffectiveScopes: (original: Subject, fresh: Subject) => Promise<void>;
|
|
5715
|
+
|
|
5034
5716
|
/** Every error a plugin registers, as one union (`never` before codegen). */
|
|
5035
5717
|
export declare type RegisteredPluginError = VoltroPluginErrors[keyof VoltroPluginErrors];
|
|
5036
5718
|
|
|
@@ -5063,13 +5745,48 @@ export declare const registerPluginAliases: (aliases: Readonly<Record<string, st
|
|
|
5063
5745
|
*/
|
|
5064
5746
|
export declare const reportableError: (err: unknown) => Error;
|
|
5065
5747
|
|
|
5748
|
+
/** An authenticated request cannot use its requested workspace. This is
|
|
5749
|
+
* scoped access refusal, not evidence that the credential or session ended.
|
|
5750
|
+
* Consumers must keep unrelated workspace sessions intact. */
|
|
5751
|
+
export declare class RequestedTenantRefused extends RequestedTenantRefused_base {
|
|
5752
|
+
}
|
|
5753
|
+
|
|
5754
|
+
declare const RequestedTenantRefused_base: Schema.Class<RequestedTenantRefused, Schema.TaggedStruct<"RequestedTenantRefused", {
|
|
5755
|
+
readonly reason: Schema.Literals<readonly ["target-unavailable", "invalid-target", "memberships-unavailable", "not-a-member", "subject-has-no-tenant"]>;
|
|
5756
|
+
}>, YieldableError>;
|
|
5757
|
+
|
|
5758
|
+
/** A request's tenant hint, read only after a strategy authenticates the caller.
|
|
5759
|
+
* Return null for the credential / stored selection. A non-null target is
|
|
5760
|
+
* checked against fresh memberships on every resolution, including when it
|
|
5761
|
+
* equals the credential's tenant. It never writes a persistent selection.
|
|
5762
|
+
* Do not return a tenant default for an absent hint: that would silently change
|
|
5763
|
+
* the authority of requests which did not select a workspace.
|
|
5764
|
+
*/
|
|
5765
|
+
export declare type RequestedTenantSource = (subject: Subject, input: AuthStrategyInput) => Promise<string | null> | string | null;
|
|
5766
|
+
|
|
5066
5767
|
/** Gate a handler on a scope; fails with a typed `ScopeError` if missing.
|
|
5067
5768
|
* Checks the EFFECTIVE set so role-derived scopes count. */
|
|
5068
5769
|
export declare const requireScope: (subject: Subject, scope: string) => Effect.Effect<void, ScopeError>;
|
|
5069
5770
|
|
|
5771
|
+
/** Browser-safe descriptor guard for capabilities that require registration. */
|
|
5772
|
+
export declare const requireUpgraded: () => UpgradedGuardSpec;
|
|
5773
|
+
|
|
5070
5774
|
/** Drop every registration. Tests only — production registers once at module load. */
|
|
5071
5775
|
export declare const resetPluginAliases: () => void;
|
|
5072
5776
|
|
|
5777
|
+
/**
|
|
5778
|
+
* Put authority back onto an IDENTITY that arrived without it — a resumed
|
|
5779
|
+
* durable run, a redeemed Room seat — through the app's own `resolveScopes`
|
|
5780
|
+
* and `subjectGuards`, the same seam a request uses. Credentials never carry
|
|
5781
|
+
* scopes (`subjectIdentity`), so every non-request consumer resolves here
|
|
5782
|
+
* rather than trusting authority frozen at mint time. With no resolver the
|
|
5783
|
+
* identity keeps what it carries (nothing), the fail-closed default.
|
|
5784
|
+
*/
|
|
5785
|
+
export declare const resolveIdentityAuthority: (identity: Subject, ctx: AuthSubjectGuardContext, authority: {
|
|
5786
|
+
readonly resolveScopes?: ((subject: Subject, ctx: AuthSubjectGuardContext) => Promise<ScopeResolverResult> | ScopeResolverResult) | undefined;
|
|
5787
|
+
readonly subjectGuards?: ReadonlyArray<AuthSubjectGuard> | undefined;
|
|
5788
|
+
} | undefined) => Promise<IdentityAuthorityOutcome>;
|
|
5789
|
+
|
|
5073
5790
|
/** Resolve the input-selected action once. Invalid selectors deny rather than
|
|
5074
5791
|
* widening to any action the subject happens to hold. Also used when an
|
|
5075
5792
|
* approval persists the resolved guard for its later recheck. */
|
|
@@ -5179,6 +5896,16 @@ declare interface RestCache {
|
|
|
5179
5896
|
readonly audience?: (output: unknown, input: unknown, subject: Subject) => 'public' | 'private';
|
|
5180
5897
|
}
|
|
5181
5898
|
|
|
5899
|
+
/** Cross-origin browser access for one route. Origins are exact, including opaque `null`. */
|
|
5900
|
+
declare interface RestCors {
|
|
5901
|
+
readonly origins: ReadonlyArray<string>;
|
|
5902
|
+
readonly headers?: ReadonlyArray<string>;
|
|
5903
|
+
readonly methods?: ReadonlyArray<RestMethod>;
|
|
5904
|
+
/** Preflight cache lifetime in seconds. */
|
|
5905
|
+
readonly maxAge?: number;
|
|
5906
|
+
readonly exposeHeaders?: ReadonlyArray<string>;
|
|
5907
|
+
}
|
|
5908
|
+
|
|
5182
5909
|
export declare type RestDates = 'iso' | 'epoch-ms';
|
|
5183
5910
|
|
|
5184
5911
|
export declare type RestEnvelope = 'none' | 'data' | 'jsonapi';
|
|
@@ -5256,7 +5983,7 @@ export declare interface RestFormatResponse {
|
|
|
5256
5983
|
readonly contentType?: string;
|
|
5257
5984
|
}
|
|
5258
5985
|
|
|
5259
|
-
declare type RestGuard = (ctx: RestRouteContext) => RestGuardRejection | undefined | Promise<RestGuardRejection | undefined>;
|
|
5986
|
+
declare type RestGuard = (ctx: RestRouteContext, request?: RestGuardRequest) => RestGuardRejection | undefined | Promise<RestGuardRejection | undefined>;
|
|
5260
5987
|
|
|
5261
5988
|
/**
|
|
5262
5989
|
* A guard runs after input decode + ctx resolution, before the handler.
|
|
@@ -5268,6 +5995,13 @@ declare interface RestGuardRejection {
|
|
|
5268
5995
|
readonly message: string;
|
|
5269
5996
|
}
|
|
5270
5997
|
|
|
5998
|
+
/** Guard input is the decoded execution snapshot. Guards are read-only
|
|
5999
|
+
* admission checks and may run again after awaited admission/storage work. */
|
|
6000
|
+
declare interface RestGuardRequest {
|
|
6001
|
+
readonly input: unknown;
|
|
6002
|
+
readonly defaultDeny: boolean;
|
|
6003
|
+
}
|
|
6004
|
+
|
|
5271
6005
|
/** What a REST handler may return: the decoded output, a `response(...)` with
|
|
5272
6006
|
* its own status and headers, an `sse(...)` stream, or `bytes(...)` for a
|
|
5273
6007
|
* non-JSON body (a file, an export, an XML document). */
|
|
@@ -5279,6 +6013,13 @@ export declare type RestNaming = 'camelCase' | 'snake_case';
|
|
|
5279
6013
|
|
|
5280
6014
|
export declare type RestPagination = 'link-header' | 'body-cursor';
|
|
5281
6015
|
|
|
6016
|
+
/** Uses the mounted rate-limit plugin's store, algorithms and dynamic policy. */
|
|
6017
|
+
declare interface RestRateLimit {
|
|
6018
|
+
readonly limit: number;
|
|
6019
|
+
readonly window: string;
|
|
6020
|
+
readonly by?: 'subject' | 'tenant' | 'apiKey' | 'ip' | 'global';
|
|
6021
|
+
}
|
|
6022
|
+
|
|
5282
6023
|
/** A schema-encoded REST body with an application-selected HTTP status and
|
|
5283
6024
|
* response headers. The marker keeps ordinary domain objects unambiguous.
|
|
5284
6025
|
* `output` still validates/encodes `body`; use `Schema.Void` with a 204 when
|
|
@@ -5300,6 +6041,8 @@ declare interface RestResponse<O> {
|
|
|
5300
6041
|
* stays free of the database dep).
|
|
5301
6042
|
*/
|
|
5302
6043
|
declare interface RestRouteContext {
|
|
6044
|
+
/** Server-owned invocation trace, stable through readmission and projection. */
|
|
6045
|
+
readonly traceId: string;
|
|
5303
6046
|
readonly subject: Subject;
|
|
5304
6047
|
readonly headers: Readonly<Record<string, string>>;
|
|
5305
6048
|
/** Request metadata and the byte-exact body as received by the HTTP
|
|
@@ -5324,6 +6067,9 @@ declare interface RestRouteContext {
|
|
|
5324
6067
|
}
|
|
5325
6068
|
|
|
5326
6069
|
declare interface RestRouteDescriptor<I, O> {
|
|
6070
|
+
/** Original schemas for client generation. Metadata only: never mounts a
|
|
6071
|
+
* second handler or selects authentication/idempotency bindings. */
|
|
6072
|
+
readonly publicApiDescriptor?: PublicApiDescriptor;
|
|
5327
6073
|
readonly method: RestMethod;
|
|
5328
6074
|
/** Absolute path, e.g. `/v1/customers`. Matches that path exactly. */
|
|
5329
6075
|
readonly path: string;
|
|
@@ -5337,6 +6083,12 @@ declare interface RestRouteDescriptor<I, O> {
|
|
|
5337
6083
|
* encodes it to JSON for the `200` response. */
|
|
5338
6084
|
readonly output: Schema.Codec<O, any, never, never>;
|
|
5339
6085
|
readonly handler: (input: I, ctx: RestRouteContext) => Promise<RestHandlerResult<O>> | RestHandlerResult<O>;
|
|
6086
|
+
/** Pure synchronous normalization of thrown admission/handler failures.
|
|
6087
|
+
* Return a mapped thrown value (for example RestRouteError), not an HTTP
|
|
6088
|
+
* response; undefined keeps the original failure. Available before authentication,
|
|
6089
|
+
* so only request metadata is given.
|
|
6090
|
+
* Public projections supply their existing typed/profile error mapper here. */
|
|
6091
|
+
readonly mapFailure?: (error: unknown, request: Pick<PluginHttpRouteRequest, 'method' | 'path' | 'query'>) => unknown;
|
|
5340
6092
|
readonly summary?: string;
|
|
5341
6093
|
readonly description?: string;
|
|
5342
6094
|
readonly example?: RestRouteExample;
|
|
@@ -5377,6 +6129,10 @@ declare interface RestRouteDescriptor<I, O> {
|
|
|
5377
6129
|
*/
|
|
5378
6130
|
readonly version?: `v${number}`;
|
|
5379
6131
|
readonly guards?: ReadonlyArray<RestGuard>;
|
|
6132
|
+
readonly cors?: RestCors;
|
|
6133
|
+
/** Only an explicit bearer header may authenticate; cookies are removed before auth and context construction. */
|
|
6134
|
+
readonly credentials?: 'bearer';
|
|
6135
|
+
readonly rateLimit?: RestRateLimit;
|
|
5380
6136
|
/**
|
|
5381
6137
|
* This route STREAMS (Server-Sent Events) rather than resolving one value — its
|
|
5382
6138
|
* handler returns `sse(...)`. Declared on the descriptor, not left implicit in
|
|
@@ -5436,6 +6192,44 @@ declare interface RestRouteProjection {
|
|
|
5436
6192
|
readonly format: RestFormat;
|
|
5437
6193
|
}
|
|
5438
6194
|
|
|
6195
|
+
/**
|
|
6196
|
+
* Default ctx resolver used when the serve pipeline doesn't inject one
|
|
6197
|
+
* (e.g. unit tests). Real mounts pass a resolver that reads the framework's
|
|
6198
|
+
* auth subject + the bound DataStore.
|
|
6199
|
+
*/
|
|
6200
|
+
declare interface RestServeBindings {
|
|
6201
|
+
/** Pure scope-refresher registration, shared with native RPC admission. */
|
|
6202
|
+
readonly bindReplayAuthority?: RpcReplayAuthorityBinding;
|
|
6203
|
+
/** Actual host policy for projected procedure guards; raw routes own guards. */
|
|
6204
|
+
readonly defaultDeny?: boolean;
|
|
6205
|
+
/** Full runtime hosts supply their existing trace generator. */
|
|
6206
|
+
readonly traceId?: () => string;
|
|
6207
|
+
/** Bound once from the app's mounted rate-limit plugin. */
|
|
6208
|
+
readonly rateLimit?: (policy: RestRateLimit, ctx: RestRouteContext, route: RestRouteDescriptor<any, any>) => Effect.Effect<void, unknown>;
|
|
6209
|
+
/** Resolve the calling subject and request-local selection before guards. */
|
|
6210
|
+
readonly resolveSubject?: (headers: Readonly<Record<string, string>>, request: {
|
|
6211
|
+
readonly path: string;
|
|
6212
|
+
readonly query: string;
|
|
6213
|
+
}) => Subject | Promise<Subject>;
|
|
6214
|
+
/** The bound framework DataStore. */
|
|
6215
|
+
readonly store?: unknown;
|
|
6216
|
+
/** Build the full per-request app context after authentication. */
|
|
6217
|
+
readonly buildContext?: (subject: Subject, headers: Readonly<Record<string, string>>, request: Pick<RestRouteContext, 'traceId' | 'remoteAddr'>) => unknown | Promise<unknown>;
|
|
6218
|
+
/**
|
|
6219
|
+
* HTTP idempotency — when set, a mutating request (POST/PUT/PATCH/DELETE)
|
|
6220
|
+
* carrying the `header` is deduplicated: the first call runs + caches its
|
|
6221
|
+
* response; a replay within `ttlMs` returns the cached response
|
|
6222
|
+
* (`Idempotency-Replayed: true`); an in-flight duplicate gets `409`. Scoped
|
|
6223
|
+
* per (tenant, method, path). The serve path injects the store + config from
|
|
6224
|
+
* `app.config.ts`'s `idempotency` field.
|
|
6225
|
+
*/
|
|
6226
|
+
readonly idempotency?: {
|
|
6227
|
+
readonly store: IdempotencyStore;
|
|
6228
|
+
readonly header: string;
|
|
6229
|
+
readonly ttlMs: number;
|
|
6230
|
+
};
|
|
6231
|
+
}
|
|
6232
|
+
|
|
5439
6233
|
/**
|
|
5440
6234
|
* What a REST handler returns to stream its response instead of resolving one
|
|
5441
6235
|
* value: `sse((emit) => unsubscribe)`. The route's schema `output` is not used
|
|
@@ -5584,9 +6378,13 @@ export declare type RpcInterceptor = (next: Effect.Effect<unknown, unknown>, con
|
|
|
5584
6378
|
* them automatically.
|
|
5585
6379
|
*/
|
|
5586
6380
|
export declare interface RpcInterceptorContext {
|
|
6381
|
+
/** Enqueue a settled invocation outcome on the host's root store, outside
|
|
6382
|
+
* the business transaction. Required transactional success capture must use
|
|
6383
|
+
* MutationCommitContext.outbox instead. Older/custom hosts may omit this. */
|
|
6384
|
+
readonly enqueueOutcome?: OutboxEnqueueFacade['enqueue'];
|
|
5587
6385
|
/** Procedure tag, e.g. `todos.create`. */
|
|
5588
6386
|
readonly tag: string;
|
|
5589
|
-
/**
|
|
6387
|
+
/** Procedure kind, including finite stream admission. */
|
|
5590
6388
|
readonly kind: RpcKind;
|
|
5591
6389
|
/** The validated input the executor is about to (or already did) receive. */
|
|
5592
6390
|
readonly input: unknown;
|
|
@@ -5622,10 +6420,20 @@ export declare interface RpcInterceptorContext {
|
|
|
5622
6420
|
* Which kind of rpc the interceptor is wrapping. The runtime passes
|
|
5623
6421
|
* `kind: 'mutation'` to interceptors registered as `interceptMutation`,
|
|
5624
6422
|
* `kind: 'query'` to `interceptQuery`, `kind: 'action'` to
|
|
5625
|
-
* `interceptAction`,
|
|
6423
|
+
* `interceptAction`, `kind: 'workflow'` to `interceptWorkflow`, and
|
|
6424
|
+
* `kind: 'stream'` to `interceptStream` — one
|
|
5626
6425
|
* plugin can implement any combination.
|
|
5627
6426
|
*/
|
|
5628
|
-
export declare type RpcKind = 'mutation' | 'query' | 'action' | 'workflow';
|
|
6427
|
+
export declare type RpcKind = 'mutation' | 'query' | 'action' | 'workflow' | 'stream';
|
|
6428
|
+
|
|
6429
|
+
export declare type RpcReplayAuthorityBinding = (context: RpcReplayAuthorityContext) => undefined;
|
|
6430
|
+
|
|
6431
|
+
/** Pure synchronous authority-refresher binding for RPC and REST admission.
|
|
6432
|
+
* No business work, I/O, grants or side effects belong in this hook. The host
|
|
6433
|
+
* calls the existing guard rechecker after every binding. */
|
|
6434
|
+
export declare interface RpcReplayAuthorityContext extends Pick<RpcInterceptorContext, 'tag' | 'input' | 'subject' | 'traceId' | 'surface' | 'publicApi' | 'remoteAddr'> {
|
|
6435
|
+
readonly kind: RpcKind | 'rest';
|
|
6436
|
+
}
|
|
5629
6437
|
|
|
5630
6438
|
/**
|
|
5631
6439
|
* Per-firing context passed to schedule-fire interceptors. Shape
|
|
@@ -5774,6 +6582,10 @@ declare const ScopeError_base: Schema.Class<ScopeError, Schema.TaggedStruct<"Sco
|
|
|
5774
6582
|
* resolver already has. */
|
|
5775
6583
|
export declare type ScopeResolverResult = ReadonlyArray<string> | ScopeDecision;
|
|
5776
6584
|
|
|
6585
|
+
/** Exact tags outrank namespace filters; deeper namespaces outrank broader ones.
|
|
6586
|
+
* Equal specificity is an ambiguity, never an implicit failover/credential hop. */
|
|
6587
|
+
export declare const selectApiRoleEndpoint: (endpoints: ApiRoleEndpoints, tag: string, workload: ApiRoleRpcWorkload) => ApiRoleEndpoint;
|
|
6588
|
+
|
|
5777
6589
|
/**
|
|
5778
6590
|
* The subject with `tenantId` selected — or a refusal.
|
|
5779
6591
|
*
|
|
@@ -5977,6 +6789,9 @@ export declare const sessionValueFromHeaders: (headers: Readonly<Record<string,
|
|
|
5977
6789
|
*/
|
|
5978
6790
|
export declare const setEffectiveScopes: (subject: Subject, scopes: ReadonlyArray<string>) => void;
|
|
5979
6791
|
|
|
6792
|
+
/** Register a request's dynamic role/permission resolver for live delivery. */
|
|
6793
|
+
export declare const setEffectiveScopesRefresher: (subject: Subject, refresh: (fresh: Subject) => Promise<void>) => void;
|
|
6794
|
+
|
|
5980
6795
|
/** Register (or clear) the process-global policy-guard resolver. Last write
|
|
5981
6796
|
* wins. The runtime installs one backed by the resource-policy registry and
|
|
5982
6797
|
* the registered tuple source. */
|
|
@@ -6007,6 +6822,33 @@ export declare const shapeDigest: (text: string) => string;
|
|
|
6007
6822
|
*/
|
|
6008
6823
|
export declare const sourceKeys: (source: ReactivitySourceValue | ReadonlyArray<ReactivitySourceValue> | undefined) => ReadonlyArray<string>;
|
|
6009
6824
|
|
|
6825
|
+
export declare interface SsrfPolicy {
|
|
6826
|
+
/**
|
|
6827
|
+
* Hosts that bypass the guard. An entry may be an exact hostname
|
|
6828
|
+
* (`billing.internal`), a suffix wildcard (`*.svc.cluster.local`), or a
|
|
6829
|
+
* host:port (`127.0.0.1:8787`) when only one port should be reachable.
|
|
6830
|
+
*
|
|
6831
|
+
* This is the one escape hatch, and it is deliberately per-HOST rather than a
|
|
6832
|
+
* boolean: "we call one internal service" and "we do not check URLs" are very
|
|
6833
|
+
* different postures, and a boolean cannot tell them apart six months later.
|
|
6834
|
+
*/
|
|
6835
|
+
readonly allowHosts?: ReadonlyArray<string>;
|
|
6836
|
+
/** Max redirect hops to follow. Each one is revalidated. Default 5. */
|
|
6837
|
+
readonly maxRedirects?: number;
|
|
6838
|
+
}
|
|
6839
|
+
|
|
6840
|
+
/**
|
|
6841
|
+
* Decide whether a URL may be fetched. Returns `null` when allowed, else the
|
|
6842
|
+
* reason. Fails CLOSED: a URL that will not parse is blocked.
|
|
6843
|
+
*
|
|
6844
|
+
* DNS is deliberately NOT resolved — this is a synchronous check on the literal
|
|
6845
|
+
* target, so a hostname that RESOLVES to a private address (DNS rebinding) is not
|
|
6846
|
+
* caught here. Blocking the direct-IP vector is the high-severity, cheap half;
|
|
6847
|
+
* rebinding needs network-layer egress control and is called out in the docs
|
|
6848
|
+
* rather than silently implied.
|
|
6849
|
+
*/
|
|
6850
|
+
export declare const ssrfReason: (rawUrl: string, policy?: SsrfPolicy) => string | null;
|
|
6851
|
+
|
|
6010
6852
|
export declare type StorageAccessPolicy = typeof StorageAccessPolicySchema.Type;
|
|
6011
6853
|
|
|
6012
6854
|
export declare const StorageAccessPolicySchema: Schema.$Array<Schema.Struct<{
|
|
@@ -6185,6 +7027,9 @@ export declare const strictInput: <S extends Schema.Top>(input: S, procedure?: s
|
|
|
6185
7027
|
|
|
6186
7028
|
export declare const Subject: Schema.Union<readonly [Schema.Struct<{
|
|
6187
7029
|
readonly type: Schema.Literal<"user">;
|
|
7030
|
+
/** A guest has a stable identity but has not linked a registered account.
|
|
7031
|
+
* This identity mark survives session signing; it never grants authority. */
|
|
7032
|
+
readonly kind: Schema.optional<Schema.Literal<"guest">>;
|
|
6188
7033
|
readonly id: Schema.String;
|
|
6189
7034
|
readonly tenantId: Schema.String;
|
|
6190
7035
|
readonly scopes: Schema.optional<Schema.$Array<Schema.String>>;
|
|
@@ -6251,6 +7096,7 @@ export declare const subjectAuditActorId: (subject: Subject) => string | null;
|
|
|
6251
7096
|
export declare const SubjectIdentity: Schema.Union<readonly [Schema.Struct<{
|
|
6252
7097
|
readonly type: Schema.Literal<"user">;
|
|
6253
7098
|
readonly id: Schema.String;
|
|
7099
|
+
readonly kind: Schema.optional<Schema.Literal<"guest">>;
|
|
6254
7100
|
readonly tenantId: Schema.String;
|
|
6255
7101
|
readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
|
|
6256
7102
|
}>, Schema.Struct<{
|
|
@@ -6293,9 +7139,9 @@ export declare const SubjectIdentity: Schema.Union<readonly [Schema.Struct<{
|
|
|
6293
7139
|
}>, Schema.Struct<{
|
|
6294
7140
|
readonly type: Schema.Literal<"service">;
|
|
6295
7141
|
readonly id: Schema.String;
|
|
7142
|
+
readonly service: Schema.String;
|
|
6296
7143
|
readonly tenantId: Schema.Null;
|
|
6297
7144
|
readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
|
|
6298
|
-
readonly service: Schema.String;
|
|
6299
7145
|
}>]>;
|
|
6300
7146
|
|
|
6301
7147
|
export declare type SubjectIdentity = typeof SubjectIdentity.Type;
|
|
@@ -6334,6 +7180,7 @@ declare const SubjectService_base: Context.ServiceClass<SubjectService, "@voltro
|
|
|
6334
7180
|
readonly type: "user";
|
|
6335
7181
|
readonly id: string;
|
|
6336
7182
|
readonly tenantId: string;
|
|
7183
|
+
readonly kind?: "guest" | undefined;
|
|
6337
7184
|
readonly scopes?: readonly string[] | undefined;
|
|
6338
7185
|
readonly metadata?: {
|
|
6339
7186
|
readonly [x: string]: unknown;
|
|
@@ -6371,8 +7218,8 @@ declare const SubjectService_base: Context.ServiceClass<SubjectService, "@voltro
|
|
|
6371
7218
|
} | {
|
|
6372
7219
|
readonly type: "service";
|
|
6373
7220
|
readonly id: string;
|
|
6374
|
-
readonly tenantId: null;
|
|
6375
7221
|
readonly service: string;
|
|
7222
|
+
readonly tenantId: null;
|
|
6376
7223
|
readonly scopes?: readonly string[] | undefined;
|
|
6377
7224
|
readonly metadata?: {
|
|
6378
7225
|
readonly [x: string]: unknown;
|
|
@@ -6430,7 +7277,7 @@ export declare const subscriptionEvent: <D extends Schema.Top>(data: D) => Schem
|
|
|
6430
7277
|
}>;
|
|
6431
7278
|
}>, Schema.Struct<{
|
|
6432
7279
|
readonly _tag: Schema.Literal<"error">;
|
|
6433
|
-
readonly error: Schema.Unknown
|
|
7280
|
+
readonly error: Schema.decodeTo<Schema.Unknown, Schema.Codec<Schema.Json, Schema.Json, never, never>, never, never>;
|
|
6434
7281
|
readonly revision: Schema.optional<Schema.Number>;
|
|
6435
7282
|
}>]>;
|
|
6436
7283
|
|
|
@@ -6710,7 +7557,7 @@ export declare const toRpc: <Name extends string, Input extends Schema.Top, Outp
|
|
|
6710
7557
|
}>;
|
|
6711
7558
|
}>, Schema.Struct<{
|
|
6712
7559
|
readonly _tag: Schema.Literal<"error">;
|
|
6713
|
-
readonly error: Schema.Unknown
|
|
7560
|
+
readonly error: Schema.decodeTo<Schema.Unknown, Schema.Codec<Schema.Json, Schema.Json, never, never>, never, never>;
|
|
6714
7561
|
readonly revision: Schema.optional<Schema.Number>;
|
|
6715
7562
|
}>]>, Schema.Top>, Schema.Never, never, never> | Rpc.Rpc<Name, Input extends Schema.Struct.Fields ? Schema.Struct<Input> : Input, Output, Schema.Top, never, never> | Rpc.Rpc<Name, Input extends Schema.Struct.Fields ? Schema.Struct<Input> : Input, Stream<Output, Schema.Top>, Schema.Never, never, never>;
|
|
6716
7563
|
|
|
@@ -6865,6 +7712,29 @@ export declare interface UpdateTarget<Input = unknown, Row = unknown, Item = Rec
|
|
|
6865
7712
|
readonly shapeItem?: ((input: Input, current: Item) => Item) | undefined;
|
|
6866
7713
|
}
|
|
6867
7714
|
|
|
7715
|
+
/** Runtime form of the registered-human identity requirement. */
|
|
7716
|
+
export declare interface UpgradedCheckSpec {
|
|
7717
|
+
readonly upgraded: true;
|
|
7718
|
+
}
|
|
7719
|
+
|
|
7720
|
+
/** Reject an upgraded marker combined with another guard variant in one entry.
|
|
7721
|
+
* Structural guard unions allow such objects to compile. Keep independent
|
|
7722
|
+
* requirements in separate entries so dispatch and persistence retain both. */
|
|
7723
|
+
export declare const upgradedGuardShapeError: (guard: unknown) => ScopeError | null;
|
|
7724
|
+
|
|
7725
|
+
/** Require a registered human identity. Guest and machine credentials cannot
|
|
7726
|
+
* satisfy this requirement, including credentials holding admin scopes. */
|
|
7727
|
+
export declare interface UpgradedGuardSpec {
|
|
7728
|
+
readonly upgraded: true;
|
|
7729
|
+
}
|
|
7730
|
+
|
|
7731
|
+
/** Validate an optional per-connection SSE lifetime before acquiring resources.
|
|
7732
|
+
* The timer ceiling also prevents millisecond overflow becoming a 1ms timer. */
|
|
7733
|
+
export declare const validateHttpStreamMaxDuration: (value: unknown) => number | undefined;
|
|
7734
|
+
|
|
7735
|
+
/** Refuse malformed runtime contributions before starting a worker. */
|
|
7736
|
+
export declare function validateOutboxHandlerDefinition(value: unknown, owner: string): asserts value is OutboxHandlerDefinition<unknown>;
|
|
7737
|
+
|
|
6868
7738
|
/**
|
|
6869
7739
|
* A server-side validation failure pinned to ONE field.
|
|
6870
7740
|
*
|
|
@@ -6908,6 +7778,26 @@ export declare const ValidationIssue: Schema.Struct<{
|
|
|
6908
7778
|
export declare type ValidationIssueShape = Schema.Schema.Type<typeof ValidationIssue>;
|
|
6909
7779
|
|
|
6910
7780
|
export declare interface VoltroPlugin {
|
|
7781
|
+
/** Server callbacks for explicitly policy-bound event client streams. */
|
|
7782
|
+
readonly eventClientPolicies?: ReadonlyArray<EventClientPolicy>;
|
|
7783
|
+
/** Declared background/listener work. Omitted means rpc-only for role admission.
|
|
7784
|
+
* Metadata alone does not suppress hooks; hosts must apply the role plan. */
|
|
7785
|
+
readonly workloads?: ReadonlyArray<ApiWorkload>;
|
|
7786
|
+
/** Separately owned API work, started after shared activation. A failed start
|
|
7787
|
+
* must release partial acquisitions before rejecting. Returned resources drain
|
|
7788
|
+
* before shared deactivation; stop failures retain them for retry. */
|
|
7789
|
+
readonly workloadHooks?: Readonly<Partial<Record<ApiWorkload, PluginWorkloadHook>>>;
|
|
7790
|
+
/** App-supplied connection references for this configured plugin instance.
|
|
7791
|
+
* Registry bindings override these selections. Library plugins must not set
|
|
7792
|
+
* topology defaults here; populate only from explicit app options. */
|
|
7793
|
+
readonly connectionBindings?: Readonly<Record<string, ConnectionRef>>;
|
|
7794
|
+
/** Backend-independent requirements. Cross-node HotStore requires Redis; broker roles require their native transport. */
|
|
7795
|
+
readonly needs?: {
|
|
7796
|
+
readonly hot?: 'local' | 'crossNode';
|
|
7797
|
+
readonly connections?: ReadonlyArray<PluginConnectionNeed>;
|
|
7798
|
+
readonly pubsub?: boolean;
|
|
7799
|
+
readonly atomicMulti?: boolean;
|
|
7800
|
+
};
|
|
6911
7801
|
/**
|
|
6912
7802
|
* Plugin identifier — printed in `voltro dev` boot logs + surfaced in
|
|
6913
7803
|
* the inspect manifest. Use a stable string scoped to the package
|
|
@@ -7006,6 +7896,16 @@ export declare interface VoltroPlugin {
|
|
|
7006
7896
|
readonly declaredEnv?: ReadonlyArray<PluginEnvVar>;
|
|
7007
7897
|
/** What this plugin collects and uses — see `PluginPrivacyDeclaration`. */
|
|
7008
7898
|
readonly privacy?: PluginPrivacyDeclaration;
|
|
7899
|
+
/** Subject-data ownership; distinct from the platform privacy disclosure above. */
|
|
7900
|
+
readonly subjectPrivacy?: PluginSubjectPrivacy;
|
|
7901
|
+
/** Idempotent server hook. Identity hooks run after all declared data hooks. */
|
|
7902
|
+
readonly onErase?: PluginEraseHook;
|
|
7903
|
+
/** Server-authorized JSON export. Omit credentials, hashes and session tokens. */
|
|
7904
|
+
readonly onExport?: PluginExportHook;
|
|
7905
|
+
/** Transactional account-data reconciliation; distinct from privacy erasure. */
|
|
7906
|
+
readonly subjectMerge?: PluginSubjectMerge;
|
|
7907
|
+
/** Trusted coordinator must authenticate both accounts and confirmation. */
|
|
7908
|
+
readonly onMergeAccounts?: PluginAccountMergeHook;
|
|
7009
7909
|
/** Where this plugin sends data outside the installation — see `PluginEgressDeclaration`. Omit when it sends nothing. */
|
|
7010
7910
|
readonly egress?: ReadonlyArray<PluginEgressDeclaration>;
|
|
7011
7911
|
/**
|
|
@@ -7047,7 +7947,21 @@ export declare interface VoltroPlugin {
|
|
|
7047
7947
|
* Absent → the plugin contributes nothing at the mutation boundary
|
|
7048
7948
|
* (schema-only / lifecycle-only plugins are fine).
|
|
7049
7949
|
*/
|
|
7950
|
+
/** Register pure authority refreshers for native and REST admission,
|
|
7951
|
+
* including queries and raw REST routes, before/after receipt waits. Requires rpc:authority:replay; never run the executor
|
|
7952
|
+
* or normal interceptors to reconstruct an authorization decision. */
|
|
7953
|
+
readonly bindReplayAuthority?: RpcReplayAuthorityBinding;
|
|
7050
7954
|
readonly interceptMutation?: RpcInterceptor;
|
|
7955
|
+
/** Runs after successful executor and business-rule evaluation, before the
|
|
7956
|
+
* transaction commits. Use only the supplied store for required records or
|
|
7957
|
+
* durable intents. External I/O is prohibited; transaction retries replay
|
|
7958
|
+
* this hook. Requires rpc:intercept:mutation and store:write permissions.
|
|
7959
|
+
* Ordinary RPC interceptors retain their existing outside-transaction scope. */
|
|
7960
|
+
readonly beforeMutationCommit?: MutationCommitHook;
|
|
7961
|
+
/** Post-commit delivery handlers, registered with the shared app worker in
|
|
7962
|
+
* Dev and serve. Requires outbox:handle; effects must not collide with app,
|
|
7963
|
+
* framework or other plugin contributions. Handlers must be idempotent. */
|
|
7964
|
+
readonly outboxHandlers?: ReadonlyArray<OutboxHandlerDefinition<unknown>>;
|
|
7051
7965
|
/**
|
|
7052
7966
|
* Wraps every QUERY (streaming subscription handler) call. Same
|
|
7053
7967
|
* composition semantics as `interceptMutation`. Most observability
|
|
@@ -7078,6 +7992,11 @@ export declare interface VoltroPlugin {
|
|
|
7078
7992
|
* plugins carry a parity test that fails when one does.
|
|
7079
7993
|
*/
|
|
7080
7994
|
readonly interceptWorkflow?: RpcInterceptor;
|
|
7995
|
+
/** Wraps finite stream admission and construction, once per subscription,
|
|
7996
|
+
* before guards and executor side effects. The successful value is the
|
|
7997
|
+
* Stream itself; element delivery retains ordinary live guard rechecks.
|
|
7998
|
+
* Requires rpc:intercept:stream. */
|
|
7999
|
+
readonly interceptStream?: RpcInterceptor;
|
|
7081
8000
|
/**
|
|
7082
8001
|
* Effect Layer that contributes services into the per-request
|
|
7083
8002
|
* context. Anything declared here is yieldable from any handler in
|
|
@@ -7258,7 +8177,7 @@ export declare interface VoltroPlugin {
|
|
|
7258
8177
|
*/
|
|
7259
8178
|
readonly extendSchema?: PluginSchemaContribution;
|
|
7260
8179
|
/**
|
|
7261
|
-
*
|
|
8180
|
+
* An absolute directory or named directories of APP-SHAPED primitives this plugin brings with it — the same
|
|
7262
8181
|
* file conventions an app uses (`*.query.ts` + `.server.ts`, `*.mutation.ts`,
|
|
7263
8182
|
* `*.workflow.tsx`, `*.cron.tsx`, `*.subscribe.ts`, `*.reaction.ts`,
|
|
7264
8183
|
* `schema.ts` / `*.entity.ts`, …).
|
|
@@ -7277,9 +8196,12 @@ export declare interface VoltroPlugin {
|
|
|
7277
8196
|
*
|
|
7278
8197
|
* The block's procedures keep the names their descriptors declare; a name
|
|
7279
8198
|
* that collides with the app's own is refused at codegen, as any collision is.
|
|
7280
|
-
*
|
|
8199
|
+
* A directory or a plain named map of directories. Named roots use stable
|
|
8200
|
+
* per-plugin module identities independent of declaration order; choose names
|
|
8201
|
+
* explicitly when optional subsystems contribute separate folders. Each value
|
|
8202
|
+
* must be an absolute existing directory; missing/overlapping roots refuse boot.
|
|
7281
8203
|
*/
|
|
7282
|
-
readonly sources?: string
|
|
8204
|
+
readonly sources?: string | Readonly<Record<string, string>>;
|
|
7283
8205
|
/**
|
|
7284
8206
|
* Cross-cutting error schemas merged into every procedure's wire error
|
|
7285
8207
|
* union. Lets a plugin interceptor fail with a typed error (e.g.
|
|
@@ -7332,6 +8254,8 @@ export declare interface VoltroPlugin {
|
|
|
7332
8254
|
* SDK here). Returns of `undefined`/empty are no-ops.
|
|
7333
8255
|
*/
|
|
7334
8256
|
readonly contributeObservability?: (ctx: PluginLifecycleContext) => Promise<ObservabilityContribution | undefined> | ObservabilityContribution | undefined;
|
|
8257
|
+
/** Enforce a hand-authored REST route's quota through this plugin. */
|
|
8258
|
+
readonly restRateLimit?: RestServeBindings['rateLimit'];
|
|
7335
8259
|
/**
|
|
7336
8260
|
* Told the app's mounted REST surface — hand-authored `restRoutes` AND the
|
|
7337
8261
|
* routes projected from `publicApi` annotations — once the boot has built it,
|
|
@@ -7416,15 +8340,17 @@ export declare interface WebSocketGatewayConnection {
|
|
|
7416
8340
|
readonly send: (data: string | Uint8Array) => void;
|
|
7417
8341
|
/** Await the local transport write, NOT peer receipt. Rejects on close or
|
|
7418
8342
|
* overflow. Await each send to propagate backpressure to the producer. */
|
|
7419
|
-
readonly sendAsync: (data: string | Uint8Array) => Promise<
|
|
8343
|
+
readonly sendAsync: (data: string | Uint8Array) => Promise<WebSocketGatewaySendResult>;
|
|
8344
|
+
/** Active plus queued frame bytes, excluding WebSocket framing overhead. */
|
|
8345
|
+
readonly queuedBytes: number;
|
|
7420
8346
|
/** Aborted on close, expiry, shutdown or setup failure, including while
|
|
7421
8347
|
* onConnection is still awaiting an upstream connection. */
|
|
7422
8348
|
readonly signal: AbortSignal;
|
|
7423
8349
|
/** Close the connection (application close codes 4000-4999 are yours). */
|
|
7424
8350
|
readonly close: (code?: number, reason?: string) => void;
|
|
7425
8351
|
/** Register a message listener (binary-safe; text arrives as bytes). */
|
|
7426
|
-
readonly onMessage: (listener: (data: Uint8Array) => void) => void;
|
|
7427
|
-
/** The
|
|
8352
|
+
readonly onMessage: (listener: (data: Uint8Array, receivedAt: number) => void) => void;
|
|
8353
|
+
/** The verified subject — `null` only on an `auth: 'public'` route. */
|
|
7428
8354
|
readonly subject: Subject | null;
|
|
7429
8355
|
/** Lowercased request headers of the upgrade. */
|
|
7430
8356
|
readonly headers: Readonly<Record<string, string>>;
|
|
@@ -7445,11 +8371,27 @@ export declare interface WebSocketGatewayRoute {
|
|
|
7445
8371
|
* expires.
|
|
7446
8372
|
* - `'public'` — deliberately unauthenticated (a device fleet with its own
|
|
7447
8373
|
* protocol-level auth). A decision somebody wrote down, not a default.
|
|
7448
|
-
|
|
7449
|
-
|
|
8374
|
+
* - `'token'` — upgrades after the origin check, then verifies the first
|
|
8375
|
+
* assembled frame before starting onConnection. The credential frame
|
|
8376
|
+
* never reaches message listeners. Clients wait for an application
|
|
8377
|
+
* acknowledgement before sending more frames; early frames close 1008.
|
|
8378
|
+
*/
|
|
8379
|
+
readonly auth: 'subject' | 'public' | 'token';
|
|
8380
|
+
/** Required only for auth: 'token'. Return null to refuse (1008), or the
|
|
8381
|
+
* verified SubjectResolution (credentialExpiresAt is Unix SECONDS).
|
|
8382
|
+
* Throw/rejection closes 1011 with a generic reason. Respect context.signal:
|
|
8383
|
+
* timeout, disconnect and shutdown abort it, and late results are ignored. */
|
|
8384
|
+
readonly verify?: (firstFrame: Uint8Array, context: WebSocketGatewayVerificationContext) => SubjectResolution | null | Promise<SubjectResolution | null>;
|
|
8385
|
+
/** Only for auth: 'token'. Deadline from socket open, including waiting for
|
|
8386
|
+
* the first frame and verification; default 5000 ms, maximum 2147483647. */
|
|
8387
|
+
readonly verificationTimeoutMs?: number;
|
|
7450
8388
|
/** Per-connection bounds. Inbound size is checked before app dispatch,
|
|
7451
8389
|
* not before the platform assembles a WebSocket message. */
|
|
7452
8390
|
readonly limits?: {
|
|
8391
|
+
/** Optional per-connection token refill rate. Omitted means no rate limit. */
|
|
8392
|
+
readonly maxInboundMessagesPerSecond?: number;
|
|
8393
|
+
/** Initial and maximum token capacity; defaults to the configured rate. */
|
|
8394
|
+
readonly burst?: number;
|
|
7453
8395
|
/** Maximum inbound/outbound frame bytes; default 1 MiB. */
|
|
7454
8396
|
readonly maxMessageBytes?: number;
|
|
7455
8397
|
/** Active plus queued outbound bytes; default 4 MiB. */
|
|
@@ -7468,6 +8410,20 @@ export declare interface WebSocketGatewayRoute {
|
|
|
7468
8410
|
readonly onConnection: (connection: WebSocketGatewayConnection) => void | (() => void) | Promise<void | (() => void)>;
|
|
7469
8411
|
}
|
|
7470
8412
|
|
|
8413
|
+
/** Local queue pressure after the frame's transport write; not peer receipt. */
|
|
8414
|
+
export declare interface WebSocketGatewaySendResult {
|
|
8415
|
+
readonly queuedBytes: number;
|
|
8416
|
+
}
|
|
8417
|
+
|
|
8418
|
+
/** Cancellation and upgrade metadata for first-frame credential verification. */
|
|
8419
|
+
export declare interface WebSocketGatewayVerificationContext {
|
|
8420
|
+
readonly signal: AbortSignal;
|
|
8421
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
8422
|
+
readonly path: string;
|
|
8423
|
+
/** Process-monotonic reception time in milliseconds, not a Unix timestamp. */
|
|
8424
|
+
readonly receivedAt: number;
|
|
8425
|
+
}
|
|
8426
|
+
|
|
7471
8427
|
/**
|
|
7472
8428
|
* Who may call a procedure over the wire: the app's own clients, or only other
|
|
7473
8429
|
* apps of the project.
|