@substrat-run/kernel 0.139.0 → 0.140.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin-log-ddl.d.ts +21 -0
- package/dist/admin-log-ddl.d.ts.map +1 -0
- package/dist/admin-log-ddl.js +32 -0
- package/dist/admin-log-ddl.js.map +1 -0
- package/dist/attachment-extractor.d.ts +12 -1
- package/dist/attachment-extractor.d.ts.map +1 -1
- package/dist/attachment-extractor.js +10 -5
- package/dist/attachment-extractor.js.map +1 -1
- package/dist/audit-outcome.d.ts +149 -0
- package/dist/audit-outcome.d.ts.map +1 -0
- package/dist/audit-outcome.js +233 -0
- package/dist/audit-outcome.js.map +1 -0
- package/dist/connect-links.d.ts +91 -0
- package/dist/connect-links.d.ts.map +1 -0
- package/dist/connect-links.js +189 -0
- package/dist/connect-links.js.map +1 -0
- package/dist/connect-state.d.ts +12 -3
- package/dist/connect-state.d.ts.map +1 -1
- package/dist/connect-state.js +8 -3
- package/dist/connect-state.js.map +1 -1
- package/dist/derived-object.d.ts +14 -0
- package/dist/derived-object.d.ts.map +1 -0
- package/dist/derived-object.js +2 -0
- package/dist/derived-object.js.map +1 -0
- package/dist/derived-objects.d.ts +108 -0
- package/dist/derived-objects.d.ts.map +1 -0
- package/dist/derived-objects.js +199 -0
- package/dist/derived-objects.js.map +1 -0
- package/dist/email-intent.d.ts +56 -0
- package/dist/email-intent.d.ts.map +1 -0
- package/dist/email-intent.js +71 -0
- package/dist/email-intent.js.map +1 -0
- package/dist/entity-edges.d.ts +6 -1
- package/dist/entity-edges.d.ts.map +1 -1
- package/dist/entity-edges.js +13 -0
- package/dist/entity-edges.js.map +1 -1
- package/dist/entity-grant-shape.d.ts +94 -0
- package/dist/entity-grant-shape.d.ts.map +1 -0
- package/dist/entity-grant-shape.js +329 -0
- package/dist/entity-grant-shape.js.map +1 -0
- package/dist/entity-grant.d.ts +45 -0
- package/dist/entity-grant.d.ts.map +1 -0
- package/dist/entity-grant.js +71 -0
- package/dist/entity-grant.js.map +1 -0
- package/dist/entity-state-reads.d.ts +4 -7
- package/dist/entity-state-reads.d.ts.map +1 -1
- package/dist/entity-state-reads.js +13 -57
- package/dist/entity-state-reads.js.map +1 -1
- package/dist/entity-state.d.ts +37 -10
- package/dist/entity-state.d.ts.map +1 -1
- package/dist/entity-state.js +80 -69
- package/dist/entity-state.js.map +1 -1
- package/dist/entity-trash.d.ts +245 -0
- package/dist/entity-trash.d.ts.map +1 -0
- package/dist/entity-trash.js +380 -0
- package/dist/entity-trash.js.map +1 -0
- package/dist/grant-scoped-read.d.ts +41 -0
- package/dist/grant-scoped-read.d.ts.map +1 -0
- package/dist/grant-scoped-read.js +100 -0
- package/dist/grant-scoped-read.js.map +1 -0
- package/dist/index.d.ts +31 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -4
- package/dist/index.js.map +1 -1
- package/dist/kernel-outbox.d.ts +14 -0
- package/dist/kernel-outbox.d.ts.map +1 -0
- package/dist/kernel-outbox.js +37 -0
- package/dist/kernel-outbox.js.map +1 -0
- package/dist/list-index.d.ts +11 -2
- package/dist/list-index.d.ts.map +1 -1
- package/dist/list-index.js +29 -21
- package/dist/list-index.js.map +1 -1
- package/dist/mail-sender.d.ts +78 -0
- package/dist/mail-sender.d.ts.map +1 -0
- package/dist/mail-sender.js +2 -0
- package/dist/mail-sender.js.map +1 -0
- package/dist/membership-executor.d.ts +0 -52
- package/dist/membership-executor.d.ts.map +1 -1
- package/dist/membership-executor.js +19 -59
- package/dist/membership-executor.js.map +1 -1
- package/dist/migration-digest.d.ts +161 -0
- package/dist/migration-digest.d.ts.map +1 -0
- package/dist/migration-digest.js +237 -0
- package/dist/migration-digest.js.map +1 -0
- package/dist/module-erasure.d.ts +156 -0
- package/dist/module-erasure.d.ts.map +1 -0
- package/dist/module-erasure.js +440 -0
- package/dist/module-erasure.js.map +1 -0
- package/dist/peer.d.ts +9 -1
- package/dist/peer.d.ts.map +1 -1
- package/dist/peer.js +29 -0
- package/dist/peer.js.map +1 -1
- package/dist/permission-checker.d.ts +6 -0
- package/dist/permission-checker.d.ts.map +1 -1
- package/dist/permission-checker.js.map +1 -1
- package/dist/permission-eval.d.ts +10 -1
- package/dist/permission-eval.d.ts.map +1 -1
- package/dist/permission-eval.js +51 -2
- package/dist/permission-eval.js.map +1 -1
- package/dist/platform-sweep.d.ts +1 -1
- package/dist/platform-sweep.d.ts.map +1 -1
- package/dist/platform-sweep.js +5 -0
- package/dist/platform-sweep.js.map +1 -1
- package/dist/scope-host.d.ts +301 -22
- package/dist/scope-host.d.ts.map +1 -1
- package/dist/scope-host.js +72 -5
- package/dist/scope-host.js.map +1 -1
- package/dist/search-index.d.ts +8 -0
- package/dist/search-index.d.ts.map +1 -1
- package/dist/search-index.js +51 -21
- package/dist/search-index.js.map +1 -1
- package/dist/spine-guard.d.ts +7 -0
- package/dist/spine-guard.d.ts.map +1 -1
- package/dist/spine-guard.js +54 -6
- package/dist/spine-guard.js.map +1 -1
- package/dist/spine-restore.d.ts.map +1 -1
- package/dist/spine-restore.js +5 -0
- package/dist/spine-restore.js.map +1 -1
- package/dist/sql-statements.d.ts +71 -0
- package/dist/sql-statements.d.ts.map +1 -0
- package/dist/sql-statements.js +191 -0
- package/dist/sql-statements.js.map +1 -0
- package/dist/subject-redaction.d.ts +9 -1
- package/dist/subject-redaction.d.ts.map +1 -1
- package/dist/subject-redaction.js.map +1 -1
- package/dist/system-switch-record.d.ts +3 -0
- package/dist/system-switch-record.d.ts.map +1 -1
- package/dist/system-switch-record.js +2 -0
- package/dist/system-switch-record.js.map +1 -1
- package/dist/table-ownership.d.ts +103 -0
- package/dist/table-ownership.d.ts.map +1 -0
- package/dist/table-ownership.js +285 -0
- package/dist/table-ownership.js.map +1 -0
- package/dist/timeline.d.ts +4 -4
- package/dist/timeline.js +4 -4
- package/dist/visible-continuation.d.ts +38 -0
- package/dist/visible-continuation.d.ts.map +1 -0
- package/dist/visible-continuation.js +162 -0
- package/dist/visible-continuation.js.map +1 -0
- package/package.json +2 -2
package/dist/scope-host.d.ts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import type { ModuleLog } from './module-log.js';
|
|
2
2
|
import type { DeliveryRefusal } from './delivery-refusal.js';
|
|
3
3
|
import type { ScopeRoleHolder } from './scope-role-admin.js';
|
|
4
|
-
import type { OnBehalfOf, ExportReadInput, ExportedBatch, ImportBatch, ImportedEvent, ImportResult, ImportState, ImportCursorMove, ImportCursorMoved, AdminAction, BecomeCapabilityInput, CapabilityExchange, CapabilityFilter, CapabilityId, CapabilityPage, MintedCapability, ListPage, Connection, ConnectionFilter, ConnectionId, ConnectionGrant, ConnectionGrantRecord, ConnectionSecret, CreateConnectionInput, OpenConnection, ProjectedConnectionGrant, ProjectedConnectionKey, AccessLogEntry, DelegatedReadRecord, OwnerTransferAudit, MemberChangeAudit, CopyMarkAudit, BindHostnameInput, AdminLogEntry, OpsFailureEntry, PlatformRequestDrainTotalsEntry, SweepRunEntry, SweepRunKind, SweepRunOutcome, ModelUsageEntry, ModelUsageSummary, CapabilityGrant, CreateTenantInput, Decision, Instant, DomainEvent, DomainEventInput, PlatformRequestInput, PlatformRequestId, PlatformRequest, PlatformRequestFilter, PlatformRequestStatus, PlatformRequestFailure, EntitlementGrant, EntitlementGrantInput, EntitlementView, MeterReading, EntityRef, IdentityLink, IdentityPool, Jurisdiction, ModuleId, ModuleManifest, ScheduleSpec, SystemGrant, PeerGrantsStatusEntry, SystemGrantsStatusEntry, SystemSwitchRecord, SystemSwitch, SystemSwitchResult, PeerCoverage, PeerSwitch, PeerSwitchResult, VerticalCaller, VerticalResolution, CreateOrgInput, Node, Org, OrgId, OrgMembership, PermissionKey, PlatformActorId, ChannelName, ExportBreak, ChannelHistoryEntry, DnsRecord, HostnameBinding, HostnameStatus, PromotionAcknowledgement, BindAcknowledgement, PublishVersionInput, RegisterVerticalInput, VerticalServingState, RouteTarget, DirectoryDump, IdentityMembership, PrincipalId, ResolvedIdentity, RoleAssignment, RoleDefinition, QueryScopeInput, ReadScopeTableInput, Scope, ScopeDump, SubjectShredReceipt, ScopeQueryResult, ScopeId, ScopeStatus, ScopeTable, DenialFilter, DenialSummary, RefusalFilter, RefusalRecord, PermissionDenial, Coverage, BeginImpersonationInput, ImpersonationFilter, ImpersonationSession, ImpersonationSessionId, ScopeTablePage, StorageShape, Tenant, TenantId, TenantRole, TenantStoreHandle, AttachmentRecord, BlobStoreHandle, Visibility, Vertical, VerticalChannel, VerticalVersion, TenantStatus, Page, CountedPage, FreshnessSpec, EntityHistoryInput, EventFacetInput, EventCauseInput, EventEffectsInput, EffectsTree, InvocationEventsInput, InvocationEvents, DeadLettersInput, DeadLetter, LifecycleFlowInput, LifecycleFlowResult, OperationSeriesInput, OperationSeriesResult, CauseChain, EventFacetResult, HistoryEntry, ErrorCode, PlatformRequestFailureOrigin, IssueEntry, IssueStatus, IssueStatusInput, FindingEntry, FindingFilter, FindingRuleEntry, FindingRuleInput, FindingStatusInput, DeclaredMigration, CheckSubject } from '@substrat-run/contracts';
|
|
4
|
+
import type { OnBehalfOf, ExportReadInput, ExportedBatch, ImportBatch, ImportedEvent, ImportResult, ImportState, ImportCursorMove, ImportCursorMoved, AdminAction, BecomeCapabilityInput, CapabilityExchange, CapabilityFilter, CapabilityId, CapabilityPage, MintedCapability, ListPage, ConnectLink, ConnectLinkConsume, ConnectLinkFilter, ConnectLinkKey, ConsumeConnectLinkInput, MintConnectLinkInput, Connection, ConnectionFilter, ConnectionId, ConnectionGrant, ConnectionGrantRecord, ConnectionSecret, CreateConnectionInput, OpenConnection, ProjectedConnectionGrant, ProjectedConnectionKey, AccessLogEntry, DelegatedReadRecord, OwnerTransferAudit, MemberChangeAudit, PeerBindingAudit, CopyMarkAudit, BindHostnameInput, AdminLogEntry, OpsFailureEntry, PlatformRequestDrainTotalsEntry, SweepRunEntry, SweepRunKind, SweepRunOutcome, ModelUsageEntry, ModelUsageSummary, CapabilityGrant, CreateTenantInput, Decision, Instant, DomainEvent, DomainEventInput, PlatformRequestInput, PlatformRequestId, PlatformRequest, PlatformRequestFilter, PlatformRequestStatus, PlatformRequestFailure, PlatformOutcomeEvent, EntitlementGrant, EntitlementGrantInput, EntitlementView, MeterReading, EntityRef, IdentityLink, IdentityPool, Jurisdiction, ModuleId, ModuleManifest, ScheduleSpec, SystemGrant, PeerGrantsStatusEntry, SystemGrantsStatusEntry, SystemSwitchRecord, SystemSwitch, SystemSwitchResult, PeerCoverage, PeerSwitch, PeerSwitchResult, VerticalCaller, VerticalResolution, PeerBinding, PeerInstanceResolution, CreateOrgInput, Node, Org, OrgId, OrgMembership, PermissionKey, PlatformActorId, ChannelName, ExportBreak, ChannelHistoryEntry, DnsRecord, HostnameBinding, HostnameStatus, PromotionAcknowledgement, BindAcknowledgement, PublishVersionInput, RegisterVerticalInput, VerticalServingState, RouteTarget, DirectoryDump, IdentityMembership, PrincipalId, ResolvedIdentity, RoleAssignment, RoleDefinition, QueryScopeInput, ReadScopeTableInput, Scope, ScopeDump, SubjectShredReceipt, ScopeQueryResult, ScopeId, ScopeStatus, ScopeTable, DenialFilter, DenialSummary, RefusalFilter, RefusalRecord, PermissionDenial, Coverage, BeginImpersonationInput, ImpersonationFilter, ImpersonationSession, ImpersonationSessionId, ScopeTablePage, StorageShape, Tenant, TenantId, TenantRole, TenantStoreHandle, AttachmentRecord, BlobStoreHandle, Visibility, Vertical, VerticalChannel, VerticalVersion, TenantStatus, Page, CountedPage, FreshnessSpec, EntityHistoryInput, EventFacetInput, EventCauseInput, EventEffectsInput, EffectsTree, InvocationEventsInput, InvocationEvents, DeadLettersInput, DeadLetter, LifecycleFlowInput, LifecycleFlowResult, OperationSeriesInput, OperationSeriesResult, CauseChain, EventFacetResult, HistoryEntry, ErrorCode, PlatformRequestFailureOrigin, IssueEntry, IssueStatus, IssueStatusInput, FindingEntry, FindingFilter, FindingRuleEntry, FindingRuleInput, FindingStatusInput, DeclaredMigration, CheckSubject, EntityGrantShape } from '@substrat-run/contracts';
|
|
5
5
|
import type { ConnectionUseOutcome } from './connector-calls.js';
|
|
6
6
|
import type { CapabilityVerbs } from './capability.js';
|
|
7
|
+
import type { AuditedOperationRef, AuditedOperationRow } from './audit-outcome.js';
|
|
7
8
|
import { type EntityStateName } from '@substrat-run/contracts';
|
|
8
9
|
import type { ModelUsageFilter, ModelUsageInput, ModelUsageWindow } from './model-usage.js';
|
|
9
10
|
import type { FindingPruneReport } from './findings.js';
|
|
10
11
|
import type { SealedSecret } from './secret-box.js';
|
|
12
|
+
import type { OnSubjectErased } from './module-erasure.js';
|
|
11
13
|
import type { SystemSwitchReassert, SystemSwitchReassertOptions, SystemSwitchRecordFilter } from './system-switch-record.js';
|
|
12
14
|
import type { SearchHit, SearchOptions } from './search-index.js';
|
|
15
|
+
import type { GrantedEntitiesPage } from './grant-scoped-read.js';
|
|
13
16
|
import type { EntityVersion } from './entity-version.js';
|
|
14
17
|
import type { UndrainedEvents } from './outbox-event.js';
|
|
15
18
|
import type { JobDriveReport, JobHandler, JobRun, JobRunFilter, StartJobRunInput } from './job-run.js';
|
|
@@ -40,6 +43,11 @@ export interface PageParams {
|
|
|
40
43
|
* archive. Refused for an entity that declares no archive. The bin is `ctx.pageTrashed`.
|
|
41
44
|
*/
|
|
42
45
|
readonly view?: Exclude<EntityStateName, 'trashed'>;
|
|
46
|
+
/**
|
|
47
|
+
* Also return each row's own cursor, as `rowCursors` (#2073) — asked for by `pageVisible`,
|
|
48
|
+
* which may stop partway through a page. Off by default, so an ordinary page is unchanged.
|
|
49
|
+
*/
|
|
50
|
+
readonly rowCursors?: boolean;
|
|
43
51
|
}
|
|
44
52
|
/**
|
|
45
53
|
* The scope-host contract — the adapter seam (§5.1 of the design doc).
|
|
@@ -90,6 +98,13 @@ export interface OperationContext {
|
|
|
90
98
|
readonly tenantId: TenantId;
|
|
91
99
|
readonly scopeId: ScopeId;
|
|
92
100
|
readonly principal: PrincipalId;
|
|
101
|
+
/** Seal positions for one filtered list under this scope, caller and operation. */
|
|
102
|
+
pageContinuation(list: string, query: unknown): {
|
|
103
|
+
/** Read-only and copy walks cannot persist a hidden budget-stop position. */
|
|
104
|
+
writable?: boolean;
|
|
105
|
+
open(cursor: string): Promise<string>;
|
|
106
|
+
seal(position: string, hidden: boolean): Promise<string | null>;
|
|
107
|
+
};
|
|
93
108
|
readonly sql: ScopedSql;
|
|
94
109
|
/**
|
|
95
110
|
* The operation's instant (#812) — the ONLY clock module code may read.
|
|
@@ -209,6 +224,18 @@ export interface OperationContext {
|
|
|
209
224
|
* than returning a denial, and records none (#1642, `assertPermissionKey`).
|
|
210
225
|
*/
|
|
211
226
|
check(permission: PermissionKey, entity?: EntityRef): Promise<Decision>;
|
|
227
|
+
/**
|
|
228
|
+
* Page entity ids reachable through this caller's live grants and declared parent edges.
|
|
229
|
+
* `all` means a node grant makes every entity of this type visible; `incomplete` means
|
|
230
|
+
* this checker cannot enumerate the path, so callers must use a checked full walk.
|
|
231
|
+
* An `ids` page is complete only after its cursor becomes null. Ids may repeat across
|
|
232
|
+
* pages on multiple parent paths: accumulate a Set, and do not treat page lengths as
|
|
233
|
+
* a count or total. The union of all pages is complete. Every id passes `ctx.check`.
|
|
234
|
+
*/
|
|
235
|
+
grantedEntities(permission: PermissionKey, entityType: string, options?: {
|
|
236
|
+
limit?: number;
|
|
237
|
+
cursor?: string;
|
|
238
|
+
}): Promise<GrantedEntitiesPage>;
|
|
212
239
|
/**
|
|
213
240
|
* Find entities of one type by what a person typed (#827) — the read a picker
|
|
214
241
|
* over 40 000 customers needs and `ctx.sql` cannot express without every
|
|
@@ -265,9 +292,9 @@ export interface OperationContext {
|
|
|
265
292
|
*
|
|
266
293
|
* **This does not check permission** — nothing on `ctx` does, and a paged read
|
|
267
294
|
* is not an exception. The operation's own `assertAllowed` still comes first.
|
|
268
|
-
* A read that filters per ROW after the fact (a portal walk) cannot
|
|
269
|
-
*
|
|
270
|
-
*
|
|
295
|
+
* A read that filters per ROW after the fact (a portal walk) cannot hand this
|
|
296
|
+
* page on as it is: a page of 20 filtered down to 3 is not a page, and its cursor
|
|
297
|
+
* may be a refused row's. It walks this read with `pageVisible` instead (#2073).
|
|
271
298
|
*
|
|
272
299
|
* Throws `NotListable` for an entity no operation declared `paged.over` on,
|
|
273
300
|
* `SortNotDeclared` for a `?sort=` outside the vocabulary, and
|
|
@@ -334,6 +361,12 @@ export interface OperationContext {
|
|
|
334
361
|
* revives it and records that as one `entity.linked` spine event, since access resumes.
|
|
335
362
|
*
|
|
336
363
|
* Checks no permission: the operation does, in its own vocabulary.
|
|
364
|
+
*
|
|
365
|
+
* A parent in the TRASH (#119) is refused `not_found`: nothing new hangs off a binned
|
|
366
|
+
* entity, since it is gone from everyone's view until restored. A MISSING parent of a type that
|
|
367
|
+
* declares trash gets the identical refusal, so the two cannot be told apart. An ARCHIVED parent
|
|
368
|
+
* is allowed — archived is filed away and still readable, and whether one may still be added to
|
|
369
|
+
* is the vertical's rule, not the kernel's.
|
|
337
370
|
*/
|
|
338
371
|
link(child: EntityRef, parent: EntityRef): void;
|
|
339
372
|
/**
|
|
@@ -346,6 +379,9 @@ export interface OperationContext {
|
|
|
346
379
|
* move would make the child its own ancestor.
|
|
347
380
|
* - `from` must be a live parent edge of `child`; `conflict` otherwise. Every other
|
|
348
381
|
* parent a multi-parent entity has is left alone.
|
|
382
|
+
* - A `to` in the TRASH is refused `not_found`, as `link` refuses one (#119) — the same refusal a
|
|
383
|
+
* missing `to` of that type gets. `from` is not: moving a child out from under a binned
|
|
384
|
+
* parent is how it is rescued.
|
|
349
385
|
* - `from` equal to `to` is a no-op: nothing written, nothing emitted.
|
|
350
386
|
* - A `to` that is ALREADY a live parent of `child` is the way to detach one parent of a
|
|
351
387
|
* multi-parent child (#2044): the `from` edge is tombstoned, the live `to` edge stays
|
|
@@ -876,9 +912,9 @@ export type MembershipChangeResult = {
|
|
|
876
912
|
* It receives `HostAdmin`, not `ctx`: it acts with platform authority, which is
|
|
877
913
|
* precisely what module code must never hold. Admin writes it makes through the `admin`
|
|
878
914
|
* it is handed are stamped with the causing event's id (`causedBy`), so the split trail
|
|
879
|
-
* joins. That `admin` is bound to this one event, never the host's own
|
|
880
|
-
* writes
|
|
881
|
-
*
|
|
915
|
+
* joins. That `admin` is bound to this one event, never the host's own (#2055). A handler
|
|
916
|
+
* that writes for a person attributes from it — `admin.attributed(onBehalfOf)` — which keeps
|
|
917
|
+
* the event (#2069); a view of the HOST knows nothing of the event.
|
|
882
918
|
*
|
|
883
919
|
* A handler that decides an event must never be effected RETURNS `refuseDelivery(reason)`
|
|
884
920
|
* (#1184). The delivery is journaled terminal with the reason, never retried. A return
|
|
@@ -1491,6 +1527,11 @@ export interface ModuleRegistration<C extends readonly EventContract[] = []> {
|
|
|
1491
1527
|
* nothing, and it reads as coverage. A bound operation with no entry is
|
|
1492
1528
|
* allowed and means what it always meant — nothing was declared to parse.
|
|
1493
1529
|
*
|
|
1530
|
+
* **It also carries the declared surface (#119).** `operationInputsOf` records, for the frozen
|
|
1531
|
+
* map it returns, every declared operation and the entity each addresses by id. The host DERIVES
|
|
1532
|
+
* its trash refusal from that — nothing else is handed over — and a module with a trashable
|
|
1533
|
+
* entity must pass that map as returned, with every operation it binds declared in it.
|
|
1534
|
+
*
|
|
1494
1535
|
* Typed structurally rather than as `z.ZodType` so the kernel keeps its single
|
|
1495
1536
|
* dependency and no zod version is pinned by the scope-host contract. The
|
|
1496
1537
|
* shape is the whole surface the host uses: throw to refuse, return the value
|
|
@@ -1567,6 +1608,15 @@ export interface ModuleRegistration<C extends readonly EventContract[] = []> {
|
|
|
1567
1608
|
* contribute the same name.
|
|
1568
1609
|
*/
|
|
1569
1610
|
predicates?: Record<string, GuardPredicate>;
|
|
1611
|
+
/**
|
|
1612
|
+
* This module's own step in a subject erasure (#2068), for the rows its declared
|
|
1613
|
+
* `erasure: { subjects }` cannot reach — a link the row does not hold itself. Run by
|
|
1614
|
+
* `shredSubject` inside the erasure's one transaction, after the declared entities and
|
|
1615
|
+
* before the key is destroyed; a throw refuses the whole erasure and rolls it back.
|
|
1616
|
+
* Synchronous, idempotent, and handed a `sql` that reaches the module's own tables only
|
|
1617
|
+
* (`module-erasure.ts`). Requires `manifest.erasure`, whose `tables` is that reach.
|
|
1618
|
+
*/
|
|
1619
|
+
onSubjectErased?: OnSubjectErased;
|
|
1570
1620
|
}
|
|
1571
1621
|
/**
|
|
1572
1622
|
* Admin surface for enforcement input (design doc §4; control-plane.md §4.4).
|
|
@@ -1591,6 +1641,16 @@ export interface ModuleRegistration<C extends readonly EventContract[] = []> {
|
|
|
1591
1641
|
* stay sync — they are code-time bookkeeping, not control-plane state.)
|
|
1592
1642
|
*/
|
|
1593
1643
|
export interface HostAdmin {
|
|
1644
|
+
/**
|
|
1645
|
+
* This same admin, with every row written through it also naming `onBehalfOf` (#977, #2069),
|
|
1646
|
+
* and keeping whatever this one already carries — for the `admin` an executor handler is
|
|
1647
|
+
* handed, the event (`causedBy`). A handler that writes for a person attributes from that
|
|
1648
|
+
* `admin`, so the cause comes along by construction and there is no option to forget.
|
|
1649
|
+
*
|
|
1650
|
+
* Optional so an admin that predates it still satisfies the interface; a caller that finds it
|
|
1651
|
+
* absent writes through the admin it holds, unattributed to a person.
|
|
1652
|
+
*/
|
|
1653
|
+
attributed?(onBehalfOf: OnBehalfOf): HostAdmin;
|
|
1594
1654
|
defineRole(actor: PlatformActorId, tenantId: TenantId, role: RoleDefinition): Promise<void>;
|
|
1595
1655
|
/**
|
|
1596
1656
|
* Every role the directory holds, ordered by (tenantId, key).
|
|
@@ -1622,6 +1682,57 @@ export interface HostAdmin {
|
|
|
1622
1682
|
*/
|
|
1623
1683
|
unassignRole(actor: PlatformActorId, assignment: RoleAssignment): Promise<void>;
|
|
1624
1684
|
grant(actor: PlatformActorId, grant: CapabilityGrant): Promise<void>;
|
|
1685
|
+
/**
|
|
1686
|
+
* Give a person a vertical's declared entity-grant SHAPE on one entity (#2071): every key in
|
|
1687
|
+
* `permissions`, plus the marker that makes them a holder of the shape, so a key the shape
|
|
1688
|
+
* gains later reaches them at the next {@link reconcileEntityGrantShapes}. What a vertical
|
|
1689
|
+
* calls where it used to `grant` its `ENTITY_GRANTS` keys one at a time. It brings back a key
|
|
1690
|
+
* or marker a revoke tombstoned, as `grant` does, and leaves a live row as it is, expiry
|
|
1691
|
+
* included, as `ctx.grant` does. Audited as `grantEntityShape`.
|
|
1692
|
+
*/
|
|
1693
|
+
grantEntityShape(actor: PlatformActorId, grant: {
|
|
1694
|
+
principalId: PrincipalId;
|
|
1695
|
+
node: {
|
|
1696
|
+
tenantId: TenantId;
|
|
1697
|
+
scopeId: ScopeId;
|
|
1698
|
+
};
|
|
1699
|
+
entity: EntityRef;
|
|
1700
|
+
permissions: readonly PermissionKey[];
|
|
1701
|
+
grantedBy: PrincipalId;
|
|
1702
|
+
}): Promise<void>;
|
|
1703
|
+
/**
|
|
1704
|
+
* Top every holder of each declared shape up to the shape as it is now (#2071): a key the
|
|
1705
|
+
* shape gained is granted to each person holding the shape's marker on an entity of that
|
|
1706
|
+
* type. Never a key revoked from that person there (its K-21 tombstone stays). A key merely
|
|
1707
|
+
* dropped from the shape is left in place; a key the shape declares `retired` (#2082) is taken
|
|
1708
|
+
* back from every holder instead, its row tombstoned, once per scope — including a direct grant
|
|
1709
|
+
* of that key to the holder on the same entity, which is the same row. Until it is done on a scope, a
|
|
1710
|
+
* shape that declares a `holder` is also backfilled: each person its holder relationship names
|
|
1711
|
+
* as the owner of an entity (`'self'`, or the vertical's own column) is marked if they hold a
|
|
1712
|
+
* key of the shape there. Never inferred from key sets, so a grant delegated on someone else's
|
|
1713
|
+
* record is never marked. Without a `holder`, there is no backfill.
|
|
1714
|
+
*
|
|
1715
|
+
* Only shapes declared `bootstrap: true` are reconciled — those given with
|
|
1716
|
+
* {@link grantEntityShape} on a person's own record. A SHARING shape, reached through
|
|
1717
|
+
* `ctx.grant` (todo's `list`), is skipped whole: reconciling one would mark every person
|
|
1718
|
+
* something was fully shared with as a holder.
|
|
1719
|
+
*
|
|
1720
|
+
* Bounded: `batch` rows of work (default 500, an integer from 1 to 5000, or `validation_failed`)
|
|
1721
|
+
* per scope transaction, backfill included, repeated until a pass finishes — so it is safe
|
|
1722
|
+
* on a large scope, and finishes on a re-run if interrupted. Each (person, entity) topped up is
|
|
1723
|
+
* an `entity.grants-topped-up` event on the entity, and each one retired keys were taken from an
|
|
1724
|
+
* `entity.grants-retired` event. Audited as `reconcileEntityGrantShapes` when it changed
|
|
1725
|
+
* anything. Returns how many (person, entity) it topped up, and how many it retired keys from.
|
|
1726
|
+
*/
|
|
1727
|
+
reconcileEntityGrantShapes(actor: PlatformActorId, node: {
|
|
1728
|
+
tenantId: TenantId;
|
|
1729
|
+
scopeId: ScopeId;
|
|
1730
|
+
}, shapes: readonly EntityGrantShape[], opts?: {
|
|
1731
|
+
batch?: number;
|
|
1732
|
+
}): Promise<{
|
|
1733
|
+
toppedUp: number;
|
|
1734
|
+
retired: number;
|
|
1735
|
+
}>;
|
|
1625
1736
|
/** Grant to an organization (portal customers); members reach it via membership tuples. */
|
|
1626
1737
|
/**
|
|
1627
1738
|
* Grant a permission to a CONNECTION (#97) — how a connector is allowed to
|
|
@@ -2308,6 +2419,17 @@ export interface HostAdmin {
|
|
|
2308
2419
|
* per-call path, before any staff member is involved.
|
|
2309
2420
|
*/
|
|
2310
2421
|
resolveVerticalInstance(tenantId: TenantId, vertical: string): Promise<VerticalResolution>;
|
|
2422
|
+
/** Resolve for one caller at execution time. An explicit stale binding refuses without fallback. */
|
|
2423
|
+
resolvePeerInstance(tenantId: TenantId, callerScopeId: ScopeId, vertical: string): Promise<PeerInstanceResolution>;
|
|
2424
|
+
/** Read the caller's explicit choice, if any. Tenant-scoped and recorded as an admin read. */
|
|
2425
|
+
peerBinding(actor: PlatformActorId, tenantId: TenantId, callerScopeId: ScopeId, vertical: string): Promise<PeerBinding | undefined>;
|
|
2426
|
+
/** Every explicit target choice this calling scope currently holds. */
|
|
2427
|
+
peerBindings(actor: PlatformActorId, tenantId: TenantId, callerScopeId: ScopeId): Promise<PeerBinding[]>;
|
|
2428
|
+
/** Bind or clear this caller's target. Both endpoints are checked in the directory at write. */
|
|
2429
|
+
setPeerBinding(actor: PlatformActorId, tenantId: TenantId, callerScopeId: ScopeId, vertical: string, targetScopeId: ScopeId | null): Promise<{
|
|
2430
|
+
changed: boolean;
|
|
2431
|
+
previous: ScopeId | null;
|
|
2432
|
+
}>;
|
|
2311
2433
|
/**
|
|
2312
2434
|
* Persist a tenant. Idempotent on the id — re-creating an existing tenant is a
|
|
2313
2435
|
* no-op, not an error (control-plane.md §4.1). `status` starts `active` and
|
|
@@ -2952,8 +3074,11 @@ export interface HostAdmin {
|
|
|
2952
3074
|
* the audit metadata — the rotate-side analogue of `createdBy` on create
|
|
2953
3075
|
* (§3.5.1). Omitted ⇒ the effecting actor stands alone, the platform-driven
|
|
2954
3076
|
* refresh path.
|
|
3077
|
+
*
|
|
3078
|
+
* `expiresAt`: a date replaces the connection's expiry, `null` clears it (the credential
|
|
3079
|
+
* that had one was replaced by one that has none), and omitted keeps it.
|
|
2955
3080
|
*/
|
|
2956
|
-
updateConnectionSecret(actor: PlatformActorId, id: ConnectionId, secret: ConnectionSecret, expiresAt?: string, opts?: {
|
|
3081
|
+
updateConnectionSecret(actor: PlatformActorId, id: ConnectionId, secret: ConnectionSecret, expiresAt?: string | null, opts?: {
|
|
2957
3082
|
rotatedBy?: string;
|
|
2958
3083
|
}): Promise<void>;
|
|
2959
3084
|
/**
|
|
@@ -2963,6 +3088,37 @@ export interface HostAdmin {
|
|
|
2963
3088
|
* constraint ignores revoked rows.
|
|
2964
3089
|
*/
|
|
2965
3090
|
revokeConnection(actor: PlatformActorId, id: ConnectionId): Promise<void>;
|
|
3091
|
+
/**
|
|
3092
|
+
* A vertical's MAILED connect link (connections.md §3.5.4) — the row that makes a consent
|
|
3093
|
+
* round single-use and revocable when it lives days rather than minutes. Beside the
|
|
3094
|
+
* connections because it is their front door: the round it starts ends in
|
|
3095
|
+
* `createConnection` (or a rotation) for the same tenant and scope.
|
|
3096
|
+
*
|
|
3097
|
+
* Every verb below is keyed by (tenant, scope): a link of another scope or tenant is
|
|
3098
|
+
* `undefined` / `unknown`, never a refusal that admits it exists. Expiry is judged against
|
|
3099
|
+
* the host's own clock. Mint, revoke, consume and restore are each audited — metadata
|
|
3100
|
+
* only, though nothing here is secret: the credential does not exist until a round is
|
|
3101
|
+
* consumed, and it never touches this row.
|
|
3102
|
+
*/
|
|
3103
|
+
mintConnectLink(actor: PlatformActorId, input: MintConnectLinkInput): Promise<ConnectLink>;
|
|
3104
|
+
getConnectLink(actor: PlatformActorId, key: ConnectLinkKey): Promise<ConnectLink | undefined>;
|
|
3105
|
+
/** Newest first. `outstandingOnly`: outstanding AND unexpired — the links that still open. */
|
|
3106
|
+
listConnectLinks(actor: PlatformActorId, filter: ConnectLinkFilter): Promise<ConnectLink[]>;
|
|
3107
|
+
/**
|
|
3108
|
+
* Outstanding → revoked. Idempotent: a revoked or used link is answered as it stands and
|
|
3109
|
+
* nothing is written. `undefined` when the scope holds no such link.
|
|
3110
|
+
*/
|
|
3111
|
+
revokeConnectLink(actor: PlatformActorId, key: ConnectLinkKey): Promise<ConnectLink | undefined>;
|
|
3112
|
+
/**
|
|
3113
|
+
* Outstanding and unexpired → used, recording what the consent attached. Atomic: of two
|
|
3114
|
+
* concurrent consumes exactly one answers `ok`. Otherwise the typed reason.
|
|
3115
|
+
*/
|
|
3116
|
+
consumeConnectLink(actor: PlatformActorId, input: ConsumeConnectLinkInput): Promise<ConnectLinkConsume>;
|
|
3117
|
+
/**
|
|
3118
|
+
* Used → outstanding, the best-effort undo after the credential store failed. Only a
|
|
3119
|
+
* used, unexpired link moves; `false` for anything else, a revoked link included.
|
|
3120
|
+
*/
|
|
3121
|
+
restoreConnectLink(actor: PlatformActorId, key: ConnectLinkKey): Promise<boolean>;
|
|
2966
3122
|
/**
|
|
2967
3123
|
* Open the credential for one (tenant, vertical, provider[, account]) — the
|
|
2968
3124
|
* connector's read, and the only path in the system that yields plaintext.
|
|
@@ -3263,6 +3419,27 @@ export interface HostAdmin {
|
|
|
3263
3419
|
* cannot be written.
|
|
3264
3420
|
*/
|
|
3265
3421
|
recordMemberChange(actor: PlatformActorId, entry: MemberChangeAudit): Promise<void>;
|
|
3422
|
+
/** One intent or outcome of a tenant's peer-instance binding change (#1720). */
|
|
3423
|
+
recordPeerBindingChange(actor: PlatformActorId, entry: PeerBindingAudit): Promise<void>;
|
|
3424
|
+
/**
|
|
3425
|
+
* Close one audited change whose intent has no outcome (#2064): in ONE transaction, read the
|
|
3426
|
+
* intent `intentId` names, and if no outcome row exists for its operation, write an `unknown`
|
|
3427
|
+
* outcome carrying `error` and an ops-failure row (`audit.<action>`, stage `outcome-unknown`)
|
|
3428
|
+
* for the staff digest. Answers `true` when it wrote them, `false` when an outcome was already
|
|
3429
|
+
* there, so concurrent callers settle an operation once. Throws `not_found` for an id that is
|
|
3430
|
+
* not an audited-change intent. See `audit-outcome.ts` for why a later real outcome still wins.
|
|
3431
|
+
*/
|
|
3432
|
+
settleUnrecordedOutcome(actor: PlatformActorId, input: {
|
|
3433
|
+
intentId: string;
|
|
3434
|
+
error: string;
|
|
3435
|
+
}): Promise<boolean>;
|
|
3436
|
+
/**
|
|
3437
|
+
* Every admin-log row of the given audited operations (#2064), read through the operation-id
|
|
3438
|
+
* index in bounded batches — one statement per `AUDITED_OPERATIONS_BATCH` ids, never a scan of
|
|
3439
|
+
* the log. Only rows of the exact (action, operation, tenant, scope) asked about are returned.
|
|
3440
|
+
* Reading the audit trail is itself recorded, once per call.
|
|
3441
|
+
*/
|
|
3442
|
+
auditedOperations(actor: PlatformActorId, refs: readonly AuditedOperationRef[]): Promise<AuditedOperationRow[]>;
|
|
3266
3443
|
/**
|
|
3267
3444
|
* Stamp `drainedAt` on every not-yet-drained access row up to and including
|
|
3268
3445
|
* `upToId`, marking them shipped to Tier 2. Returns how many rows moved.
|
|
@@ -3908,10 +4085,19 @@ export interface ScopeHost {
|
|
|
3908
4085
|
* Optional so a host that predates it still satisfies the interface; a transport
|
|
3909
4086
|
* that finds it absent writes unattributed rows, which is what every row was before.
|
|
3910
4087
|
*
|
|
3911
|
-
*
|
|
3912
|
-
*
|
|
3913
|
-
|
|
3914
|
-
|
|
4088
|
+
* A view of the host knows nothing of any event: an executor handler attributes from the
|
|
4089
|
+
* `admin` it is handed instead (`HostAdmin.attributed`), which keeps its `causedBy`.
|
|
4090
|
+
*/
|
|
4091
|
+
attributed?(onBehalfOf: OnBehalfOf): ScopeHost;
|
|
4092
|
+
/**
|
|
4093
|
+
* The same view, its rows also naming `options.causedBy` as the event they are the effect
|
|
4094
|
+
* of (K-22, #2055).
|
|
4095
|
+
*
|
|
4096
|
+
* @deprecated since #2069: an executor handler attributes from the `admin` it is handed —
|
|
4097
|
+
* `admin.attributed(onBehalfOf)` — which carries its event by construction. This form needs
|
|
4098
|
+
* the event passed again, and a handler that forgets writes `causedBy` NULL with nothing
|
|
4099
|
+
* failing. It stays because it shipped, and because it is how the membership executor still
|
|
4100
|
+
* attributes on a host whose handed admin predates `HostAdmin.attributed`.
|
|
3915
4101
|
*/
|
|
3916
4102
|
attributed?(onBehalfOf: OnBehalfOf, options?: {
|
|
3917
4103
|
causedBy?: string;
|
|
@@ -4618,6 +4804,11 @@ export interface ScopeHost {
|
|
|
4618
4804
|
lastError?: string | null;
|
|
4619
4805
|
/** WHO refused (#841). Omitted by a caller too old to attribute — stored as NULL. */
|
|
4620
4806
|
failure?: PlatformRequestFailure | null;
|
|
4807
|
+
/**
|
|
4808
|
+
* #2102: an outcome event written into the scope with the settle, in its transaction,
|
|
4809
|
+
* and only when this settle moves the row out of `pending` (`settlePlatformRequestIn`).
|
|
4810
|
+
*/
|
|
4811
|
+
event?: PlatformOutcomeEvent | null;
|
|
4621
4812
|
}): Promise<void>;
|
|
4622
4813
|
/**
|
|
4623
4814
|
* Live reads (#938) — a subscription to this scope's change feed, or absent.
|
|
@@ -4671,10 +4862,12 @@ export interface ScopeHost {
|
|
|
4671
4862
|
* changed at 14:02 is information about that row, so "the body was empty" is not a
|
|
4672
4863
|
* defence: the filter runs whether or not there is a payload to withhold.
|
|
4673
4864
|
*
|
|
4674
|
-
* A subscription may be narrowed `within` one entity (#1853), which only removes frames
|
|
4675
|
-
*
|
|
4676
|
-
*
|
|
4677
|
-
*
|
|
4865
|
+
* A subscription may be narrowed `within` one entity (#1853), which only removes frames.
|
|
4866
|
+
* Two built roots replace the per-row check with one about the ROOT, and their subscribers
|
|
4867
|
+
* are sent bare `LiveNudge` frames that name no entity: `checkedWithin`, whose principal must
|
|
4868
|
+
* pass a stated key on the root at the handshake and again on every pass that has something
|
|
4869
|
+
* to send (#938), and `vouchedWithin`, which the vertical asserts once and nothing re-checks
|
|
4870
|
+
* (#1853). Which to use is on `checkedWithin`.
|
|
4678
4871
|
*
|
|
4679
4872
|
* **Generic over the runtime's request and response, because the kernel names
|
|
4680
4873
|
* neither.** This package has one dependency and no DOM or workers lib
|
|
@@ -4727,10 +4920,51 @@ export interface LiveReadSurface<Req extends LiveUpgradeRequest = LiveUpgradeReq
|
|
|
4727
4920
|
* the same trust it already extends in naming `principal`, and the scope's walk is
|
|
4728
4921
|
* the whole filter. Such a subscriber receives `LiveNudge` frames only, which name
|
|
4729
4922
|
* no event type and no entity.
|
|
4923
|
+
* - **A `checkedWithin(…)` value replaces the per-row check with one on the root**
|
|
4924
|
+
* (#938). The principal must pass the stated key on the root, at the handshake (a
|
|
4925
|
+
* `403` otherwise) and again on every pass that has a row beneath it to announce,
|
|
4926
|
+
* so a grant withdrawn, or a root moved out from under it, closes the socket
|
|
4927
|
+
* instead of nudging it. `LiveNudge` frames only, as for a vouched root.
|
|
4928
|
+
*
|
|
4929
|
+
* **Freshness (Codex #2077 r5).** A decision is reused within a pass only while the
|
|
4930
|
+
* scope has had no write and nothing it holds has reached its `expires_at` since the
|
|
4931
|
+
* decision. It is never reused while the scope reads its permissions from the directory.
|
|
4932
|
+
* Both are checked against the clock immediately before each send. A change that lands
|
|
4933
|
+
* while a check is still being evaluated can let that one frame through. Frames name
|
|
4934
|
+
* nothing the subscriber could not read when checked, and the next frame, pass and poll
|
|
4935
|
+
* see the change: a push is a hint at most one evaluation stale.
|
|
4936
|
+
*/
|
|
4937
|
+
within?: EntityRef | VouchedWithin | CheckedWithin;
|
|
4938
|
+
/**
|
|
4939
|
+
* When the credential that proved `principal` stops being valid (ISO 8601), so the
|
|
4940
|
+
* socket never outlives it (#938). Pass the session's or the bearer's expiry
|
|
4941
|
+
* (`AuthSubject.expiresAt`). A handshake at or past it is refused, and the scope closes
|
|
4942
|
+
* the socket (`1008`) on its first pass at or past it, before sending anything on that
|
|
4943
|
+
* pass. Absent: the socket lives until either end closes it, as before.
|
|
4730
4944
|
*/
|
|
4731
|
-
|
|
4945
|
+
expiresAt?: string;
|
|
4732
4946
|
}): Promise<Res>;
|
|
4733
4947
|
}
|
|
4948
|
+
/**
|
|
4949
|
+
* The close codes a live socket ends with, so a client can tell "try again" from "poll".
|
|
4950
|
+
*
|
|
4951
|
+
* - `1008` (policy): the subscriber may no longer watch what it subscribed to — a
|
|
4952
|
+
* `checkedWithin` gate refused, or the session that opened it ended. A reconnect meets
|
|
4953
|
+
* the handshake's own refusal.
|
|
4954
|
+
* - `4429`: this principal already holds `LIVE_SOCKETS_PER_PRINCIPAL` sockets on the scope.
|
|
4955
|
+
* Not a reason to retry: the client should poll, which it does anyway, and stop asking.
|
|
4956
|
+
*/
|
|
4957
|
+
export declare const LIVE_CLOSE: {
|
|
4958
|
+
readonly revoked: 1008;
|
|
4959
|
+
readonly tooMany: 4429;
|
|
4960
|
+
};
|
|
4961
|
+
/**
|
|
4962
|
+
* How many live sockets one principal may hold on one scope (#938). A tab holds one per
|
|
4963
|
+
* feed (the desk's, and one per open conversation in ticket0's portal), and each socket is
|
|
4964
|
+
* work on every post-commit pass, so a principal opening more is a cost on everybody else
|
|
4965
|
+
* writing to the scope. Eight covers several tabs; past it a socket is closed `4429`.
|
|
4966
|
+
*/
|
|
4967
|
+
export declare const LIVE_SOCKETS_PER_PRINCIPAL = 8;
|
|
4734
4968
|
/** The brand only `vouchedWithin` can apply — a literal cannot type-check as one. */
|
|
4735
4969
|
declare const vouchedBrand: unique symbol;
|
|
4736
4970
|
/**
|
|
@@ -4762,6 +4996,50 @@ export declare function vouchedWithin(entity: EntityRef, opts: {
|
|
|
4762
4996
|
}): VouchedWithin;
|
|
4763
4997
|
/** Was this value built by `vouchedWithin`? A host asks before it drops the principal's check. */
|
|
4764
4998
|
export declare function isVouchedWithin(value: unknown): value is VouchedWithin;
|
|
4999
|
+
/** The brand only `checkedWithin` can apply. */
|
|
5000
|
+
declare const checkedBrand: unique symbol;
|
|
5001
|
+
/**
|
|
5002
|
+
* A `within` root the PRINCIPAL must be allowed `permission` on, re-checked for as long
|
|
5003
|
+
* as the socket is open (#938). Built only by `checkedWithin`.
|
|
5004
|
+
*/
|
|
5005
|
+
export interface CheckedWithin {
|
|
5006
|
+
readonly [checkedBrand]: true;
|
|
5007
|
+
readonly entity: EntityRef;
|
|
5008
|
+
readonly permission: PermissionKey;
|
|
5009
|
+
}
|
|
5010
|
+
/**
|
|
5011
|
+
* Watch `entity` and everything beneath it, for as long as the subscriber may
|
|
5012
|
+
* `permission` on `entity` itself.
|
|
5013
|
+
*
|
|
5014
|
+
* For a subscriber whose grant reaches the ROOT but not each row under it the way a
|
|
5015
|
+
* `liveTargets` key would: ticket0's portal customer holds `conversation:read-own` on
|
|
5016
|
+
* their contact, which reaches the conversation's public thread, while the per-row key
|
|
5017
|
+
* on a message is the staff read. Rooted at an entity whose subtree is exactly what that
|
|
5018
|
+
* key's read returns, the walk is the row filter and the key is the gate.
|
|
5019
|
+
*
|
|
5020
|
+
* The gate is asked at the handshake (`403` if it refuses) and again, once per socket,
|
|
5021
|
+
* on every post-commit pass that has a row beneath the root to announce. A refusal or a
|
|
5022
|
+
* check that throws closes the socket (`1008`) and sends nothing on that pass, so a
|
|
5023
|
+
* revoked grant, a principal who is gone, or a root relinked out of the grant's reach
|
|
5024
|
+
* ends the subscription instead of nudging it, and the client's reconnect meets the
|
|
5025
|
+
* handshake's `403`. A pass with nothing beneath the root asks nothing, so an idle
|
|
5026
|
+
* subscription costs no checks.
|
|
5027
|
+
*
|
|
5028
|
+
* **`checkedWithin` or `vouchedWithin`?** Use `checkedWithin` whenever the subscriber is
|
|
5029
|
+
* a principal with a grant that reaches the root: authority leaves with the grant. Use
|
|
5030
|
+
* `vouchedWithin` only when there is no such grant to ask, as for ticket0's widget
|
|
5031
|
+
* visitor, who holds a session token rather than a principal of their own. A vouched
|
|
5032
|
+
* socket is asserted once, so a token revoked mid-socket keeps receiving content-free
|
|
5033
|
+
* nudges until the socket closes. That is known and accepted for the widget: the nudge
|
|
5034
|
+
* names nothing, and every re-read it causes is checked again.
|
|
5035
|
+
*
|
|
5036
|
+
* Both send `LiveNudge` frames only: the subscriber may not read each row, so it is
|
|
5037
|
+
* never told which one changed. Only rows of a type some module declared in
|
|
5038
|
+
* `liveTargets` are announced, as for every other subscriber.
|
|
5039
|
+
*/
|
|
5040
|
+
export declare function checkedWithin(entity: EntityRef, permission: string): CheckedWithin;
|
|
5041
|
+
/** Was this value built by `checkedWithin`? */
|
|
5042
|
+
export declare function isCheckedWithin(value: unknown): value is CheckedWithin;
|
|
4765
5043
|
/**
|
|
4766
5044
|
* Is this request asking to be upgraded to a WebSocket?
|
|
4767
5045
|
*
|
|
@@ -4822,12 +5100,13 @@ export interface LiveChange {
|
|
|
4822
5100
|
readonly at: string;
|
|
4823
5101
|
}
|
|
4824
5102
|
/**
|
|
4825
|
-
* What a vouched subscriber is told (#1853): something beneath its root
|
|
4826
|
-
* nothing else.
|
|
5103
|
+
* What a vouched or checked subscriber is told (#1853, #938): something beneath its root
|
|
5104
|
+
* changed, and nothing else.
|
|
4827
5105
|
*
|
|
4828
|
-
* No event type and no entity, deliberately.
|
|
4829
|
-
* entities its frames are about — the vertical vouched for the ROOT,
|
|
4830
|
-
* cannot know which rows under it the vertical's
|
|
5106
|
+
* No event type and no entity, deliberately. Such a subscriber holds no read on the
|
|
5107
|
+
* entities its frames are about — the vertical vouched for the ROOT, or the principal was
|
|
5108
|
+
* checked on the root alone, and the scope cannot know which rows under it the vertical's
|
|
5109
|
+
* own read would show. Naming the type
|
|
4831
5110
|
* or the id would tell it what it never asked to read. The client re-reads, as it does
|
|
4832
5111
|
* on a `LiveChange`.
|
|
4833
5112
|
*/
|