@voltro/protocol 0.71.1 → 0.72.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 +383 -0
- package/THIRD-PARTY-NOTICES.md +29 -1
- package/dist/index.d.ts +146 -0
- package/dist/index.js +549 -536
- package/dist/inspect.js +1 -0
- package/dist/rest.js +1 -1
- package/dist/{scopes-CW9_LbDO.js → scopes-Dj7KCJab.js} +202 -132
- package/dist/session.js +6 -6
- package/package.json +4 -3
package/dist/index.d.ts
CHANGED
|
@@ -835,6 +835,32 @@ export declare const composeAuthStrategies: (strategies: ReadonlyArray<AuthStrat
|
|
|
835
835
|
* `fallback` is supplied (the fallback owns that decision).
|
|
836
836
|
*/
|
|
837
837
|
readonly anonymousTenantRequired?: boolean;
|
|
838
|
+
/**
|
|
839
|
+
* The ONE tenant every anonymous caller resolves to — chosen by the server,
|
|
840
|
+
* never by the request. When set, the `x-tenant` header is not consulted:
|
|
841
|
+
* a client naming its own tenant is exactly the thing a fixed anonymous
|
|
842
|
+
* tenant exists to rule out. Ignored when `fallback` is supplied (that
|
|
843
|
+
* function owns the anonymous subject).
|
|
844
|
+
*/
|
|
845
|
+
readonly anonymousTenantId?: string;
|
|
846
|
+
/**
|
|
847
|
+
* The subject's memberships — the ONE source, strategy-independent. Read
|
|
848
|
+
* only when a stored tenant selection exists for the subject and names a
|
|
849
|
+
* tenant other than the credential's, and then on every such request: a
|
|
850
|
+
* membership revoked a moment ago must not keep a selection alive, and a
|
|
851
|
+
* switch made a moment ago must be visible on the next call, so there is
|
|
852
|
+
* no staleness window to configure here. Requires `tenantSelection`.
|
|
853
|
+
*/
|
|
854
|
+
readonly memberships?: MembershipsSource;
|
|
855
|
+
/**
|
|
856
|
+
* Where a subject's tenant selection is stored. Read for every matched
|
|
857
|
+
* user / apiKey / serviceAccount subject (one point lookup); a stored
|
|
858
|
+
* tenant the memberships no longer cover is ignored AND cleared here —
|
|
859
|
+
* the revocation of a membership revokes the selection. Requires
|
|
860
|
+
* `memberships`; with only one of the two configured the step does not
|
|
861
|
+
* run, and the composer says so at compose time.
|
|
862
|
+
*/
|
|
863
|
+
readonly tenantSelection?: TenantSelectionStore;
|
|
838
864
|
/**
|
|
839
865
|
* Add scopes to a resolved Subject from a source the strategy could not
|
|
840
866
|
* see — typically a role stored in the app's own database.
|
|
@@ -1828,6 +1854,12 @@ export declare interface DeleteTarget<Input = unknown> extends NestedTargetField
|
|
|
1828
1854
|
readonly identify?: ((input: Input) => string | ReadonlyArray<string>) | undefined;
|
|
1829
1855
|
}
|
|
1830
1856
|
|
|
1857
|
+
/** Pair, list and revoke devices (`devices: true`) for the caller's tenant.
|
|
1858
|
+
* One scope, not three: a device always acts as itself, in the pairer's
|
|
1859
|
+
* tenant, so there is no self / org / other distinction to draw.
|
|
1860
|
+
* `admin:full` satisfies it, as it does every scope. */
|
|
1861
|
+
export declare const DEVICES_MANAGE_SCOPE = "devices:manage";
|
|
1862
|
+
|
|
1831
1863
|
export declare const diffRows: (prev: ReadonlyArray<PatchRow>, next: ReadonlyArray<PatchRow>, options?: DiffRowsOptions) => RowPatch;
|
|
1832
1864
|
|
|
1833
1865
|
/**
|
|
@@ -2622,6 +2654,8 @@ export declare const isReactivityChannelKey: (key: string) => boolean;
|
|
|
2622
2654
|
|
|
2623
2655
|
export declare const isSystemSubject: (subject: Subject) => boolean;
|
|
2624
2656
|
|
|
2657
|
+
export declare const isTenantSelectable: (subject: Subject) => subject is TenantSelectableSubject;
|
|
2658
|
+
|
|
2625
2659
|
/**
|
|
2626
2660
|
* Is this descriptor allowed on the wire at all?
|
|
2627
2661
|
*
|
|
@@ -2670,6 +2704,19 @@ export declare const makeScopeCache: (options?: ScopeCacheOptions) => ScopeCache
|
|
|
2670
2704
|
*/
|
|
2671
2705
|
export declare const MAX_EVENT_ENVELOPE_BYTES = 7500;
|
|
2672
2706
|
|
|
2707
|
+
/** One tenant a subject belongs to. `role` is whatever the app's membership
|
|
2708
|
+
* source knows — it rides along onto `metadata.memberships` and nothing here
|
|
2709
|
+
* interprets it. */
|
|
2710
|
+
export declare interface Membership {
|
|
2711
|
+
readonly tenantId: string;
|
|
2712
|
+
readonly role?: string;
|
|
2713
|
+
}
|
|
2714
|
+
|
|
2715
|
+
/** The app's ONE source of memberships, strategy-independent: the auth plugin
|
|
2716
|
+
* answers from its `memberships` table (`authMemberships(userStore)`), an IdP
|
|
2717
|
+
* project from wherever it keeps them. `input.store` is the app's DataStore. */
|
|
2718
|
+
export declare type MembershipsSource = (subject: Subject, input: AuthStrategyInput) => Promise<ReadonlyArray<Membership>> | ReadonlyArray<Membership>;
|
|
2719
|
+
|
|
2673
2720
|
/** In-memory store — the default for single-process dev + the test double. */
|
|
2674
2721
|
export declare const memoryIdempotencyStore: () => IdempotencyStore;
|
|
2675
2722
|
|
|
@@ -3121,6 +3168,10 @@ export declare interface PluginCacheHandle {
|
|
|
3121
3168
|
}) => Effect.Effect<void, unknown>;
|
|
3122
3169
|
}
|
|
3123
3170
|
|
|
3171
|
+
export declare interface PluginCapabilities {
|
|
3172
|
+
readonly mediaPersist?: PluginMediaPersistCapability;
|
|
3173
|
+
}
|
|
3174
|
+
|
|
3124
3175
|
/**
|
|
3125
3176
|
* Post-commit change event delivered to a plugin's `onChangeEvent` tap.
|
|
3126
3177
|
* Minimal, browser-safe shape (protocol must not depend on the database
|
|
@@ -3788,6 +3839,31 @@ export declare interface PluginLifecycleContext {
|
|
|
3788
3839
|
readonly config: unknown;
|
|
3789
3840
|
}
|
|
3790
3841
|
|
|
3842
|
+
/** Where the offloaded-inference dispatcher puts a media artifact a provider
|
|
3843
|
+
* produced. Every call names its `operationId` — the queued job, its attempt
|
|
3844
|
+
* and the artifact's index — so a store that supports resumable puts stores
|
|
3845
|
+
* one object however often the dispatcher is retried. */
|
|
3846
|
+
export declare interface PluginMediaPersistCapability {
|
|
3847
|
+
readonly put: (args: {
|
|
3848
|
+
readonly bytes: Uint8Array;
|
|
3849
|
+
readonly mediaType: string;
|
|
3850
|
+
readonly tenantId: string | null;
|
|
3851
|
+
readonly operationId: string;
|
|
3852
|
+
}) => Promise<{
|
|
3853
|
+
readonly url: string;
|
|
3854
|
+
readonly refId: string;
|
|
3855
|
+
}>;
|
|
3856
|
+
/** Re-host a provider URL. Absent → the provider's URL is handed on as-is. */
|
|
3857
|
+
readonly ingestUrl?: (args: {
|
|
3858
|
+
readonly url: string;
|
|
3859
|
+
readonly tenantId: string | null;
|
|
3860
|
+
readonly operationId: string;
|
|
3861
|
+
}) => Promise<{
|
|
3862
|
+
readonly url: string;
|
|
3863
|
+
readonly refId: string;
|
|
3864
|
+
}>;
|
|
3865
|
+
}
|
|
3866
|
+
|
|
3791
3867
|
export declare interface PluginMigration {
|
|
3792
3868
|
readonly id: string;
|
|
3793
3869
|
readonly description?: string;
|
|
@@ -5217,6 +5293,23 @@ declare const ScopeError_base: Schema.TaggedErrorClass<ScopeError, "ScopeError",
|
|
|
5217
5293
|
* resolver already has. */
|
|
5218
5294
|
export declare type ScopeResolverResult = ReadonlyArray<string> | ScopeDecision;
|
|
5219
5295
|
|
|
5296
|
+
/**
|
|
5297
|
+
* The subject with `tenantId` selected — or a refusal.
|
|
5298
|
+
*
|
|
5299
|
+
* The memberships are the caller's to supply because they are the caller's to
|
|
5300
|
+
* know: the auth plugin reads its `memberships` table, an IdP project reads
|
|
5301
|
+
* its own. Whatever the source, the check is this one line, and the list is
|
|
5302
|
+
* written onto `metadata.memberships` in the shape the auth plugin already
|
|
5303
|
+
* uses (`subjectMemberships(subject)` reads it), so a client can render the
|
|
5304
|
+
* switch from any subject the same way.
|
|
5305
|
+
*
|
|
5306
|
+
* Everything else on the subject — scopes, other metadata — passes through
|
|
5307
|
+
* untouched: a selection changes WHERE the subject acts, not what it may do.
|
|
5308
|
+
* Authority for the selected tenant is the resolver's business, which is why
|
|
5309
|
+
* `composeAuthStrategies` applies the selection BEFORE `resolveScopes`.
|
|
5310
|
+
*/
|
|
5311
|
+
export declare const selectSubjectTenant: (subject: Subject, tenantId: string, memberships: ReadonlyArray<Membership>) => Subject;
|
|
5312
|
+
|
|
5220
5313
|
export declare interface ServerErrorEvent {
|
|
5221
5314
|
/** The thrown value (Error | tagged error | anything). */
|
|
5222
5315
|
readonly error: unknown;
|
|
@@ -5861,6 +5954,48 @@ declare const TenantScopeViolation_base: Schema.TaggedErrorClass<TenantScopeViol
|
|
|
5861
5954
|
reason: typeof Schema.String;
|
|
5862
5955
|
}>;
|
|
5863
5956
|
|
|
5957
|
+
/** The subject types a selection can apply to: those with an id AND a tenant.
|
|
5958
|
+
* `anonymous` has no id to remember a selection under; `system` has no
|
|
5959
|
+
* tenant by construction. */
|
|
5960
|
+
export declare type TenantSelectableSubject = Extract<Subject, {
|
|
5961
|
+
type: 'user' | 'apiKey' | 'serviceAccount';
|
|
5962
|
+
}>;
|
|
5963
|
+
|
|
5964
|
+
/** The identity a selection is remembered under — the two fields that name a
|
|
5965
|
+
* subject across credentials. A selection outlives the credential that made
|
|
5966
|
+
* it, which is the point: the next JWT, the next API-key call, finds it. */
|
|
5967
|
+
export declare interface TenantSelectionIdentity {
|
|
5968
|
+
readonly type: TenantSelectableSubject['type'];
|
|
5969
|
+
readonly id: string;
|
|
5970
|
+
}
|
|
5971
|
+
|
|
5972
|
+
/** Refused by name: the target is not among the subject's memberships, or the
|
|
5973
|
+
* subject is of a type that has no tenant to select. A typed error so a
|
|
5974
|
+
* mutation can map it to a response instead of matching on a message. */
|
|
5975
|
+
export declare class TenantSelectionRefused extends TenantSelectionRefused_base {
|
|
5976
|
+
}
|
|
5977
|
+
|
|
5978
|
+
declare const TenantSelectionRefused_base: Schema.TaggedErrorClass<TenantSelectionRefused, "TenantSelectionRefused", {
|
|
5979
|
+
readonly _tag: Schema.tag<"TenantSelectionRefused">;
|
|
5980
|
+
} & {
|
|
5981
|
+
subjectType: typeof Schema.String;
|
|
5982
|
+
subjectId: Schema.NullOr<typeof Schema.String>;
|
|
5983
|
+
tenantId: typeof Schema.String;
|
|
5984
|
+
reason: Schema.Literal<["not-a-member", "subject-has-no-tenant"]>;
|
|
5985
|
+
}>;
|
|
5986
|
+
|
|
5987
|
+
/** Where `composeAuthStrategies` finds a stored selection. `@voltro/runtime`'s
|
|
5988
|
+
* `tenantSelectionStore(store)` is the framework's implementation over the
|
|
5989
|
+
* `_voltro_tenant_selections` table; the interface is here so the composer
|
|
5990
|
+
* stays free of any store. */
|
|
5991
|
+
export declare interface TenantSelectionStore {
|
|
5992
|
+
/** The selected tenant, or null when none is stored. */
|
|
5993
|
+
readonly read: (identity: TenantSelectionIdentity) => Promise<string | null>;
|
|
5994
|
+
/** Forget a selection — called by the composer when the stored tenant is no
|
|
5995
|
+
* longer among the subject's memberships. */
|
|
5996
|
+
readonly clear: (identity: TenantSelectionIdentity) => Promise<void>;
|
|
5997
|
+
}
|
|
5998
|
+
|
|
5864
5999
|
export declare const toRpc: <Name extends string, Input extends Schema.Schema.Any, Output extends Schema.Schema.Any, Err extends Schema.Schema.All>(descriptor: QueryProcedureDescriptor<Name, Input, Output, Err> | MutationProcedureDescriptor<Name, Input, Output, Err> | ActionProcedureDescriptor<Name, Input, Output, Err> | StreamProcedureDescriptor<Name, Input, Output, Err>) => Rpc.Rpc<Name, Input extends Schema.Struct.Fields ? Schema.Struct<Input> : Input, Stream<Schema.Union<[Schema.Struct<{
|
|
5865
6000
|
_tag: Schema.Literal<["snapshot"]>;
|
|
5866
6001
|
revision: typeof Schema.Number;
|
|
@@ -6350,6 +6485,17 @@ export declare interface VoltroPlugin {
|
|
|
6350
6485
|
* keeps working unchanged.
|
|
6351
6486
|
*/
|
|
6352
6487
|
readonly bindDataStore?: (store: DataStore, ctx?: PluginBindContext) => void;
|
|
6488
|
+
/**
|
|
6489
|
+
* Capabilities this plugin offers to OTHER framework machinery, by name.
|
|
6490
|
+
*
|
|
6491
|
+
* The framework reads them from the plugin instance at boot — a plugin that
|
|
6492
|
+
* holds the app's storage can hand the offloaded-inference dispatcher the
|
|
6493
|
+
* function that persists a generated media artifact, without the dispatcher
|
|
6494
|
+
* depending on the plugin or the plugin on the dispatcher. Functions here
|
|
6495
|
+
* close over the plugin's bound state, so they are read lazily and called
|
|
6496
|
+
* after `bindDataStore`.
|
|
6497
|
+
*/
|
|
6498
|
+
readonly capabilities?: PluginCapabilities;
|
|
6353
6499
|
/**
|
|
6354
6500
|
* Post-commit ChangeEvent tap — an `Effect<void, E>` the runtime SUPERVISES.
|
|
6355
6501
|
* Fires for EVERY committed store change (insert/update/delete on any table),
|