@fitzzero/quickdraw-core 5.1.2 → 5.1.3

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.
Files changed (124) hide show
  1. package/README.md +793 -57
  2. package/dist/{admin-DWWrT1h6.d.ts → admin-CS7JB_UH.d.ts} +2 -2
  3. package/dist/{adminSchemas-D4bFKsrb.d.ts → adminSchemas-29cGgrg5.d.ts} +1 -1
  4. package/dist/{auth-DXiSJZaf.d.ts → auth-DtdYjrZ9.d.ts} +11 -7
  5. package/dist/{caller-BT-Mv4bD.d.ts → caller-BTwGl7vm.d.ts} +183 -15
  6. package/dist/chunk-2FDSKLBO.js +82 -0
  7. package/dist/chunk-2FDSKLBO.js.map +1 -0
  8. package/dist/{chunk-GSIPUNJL.js → chunk-64I6MYBC.js} +139 -792
  9. package/dist/chunk-64I6MYBC.js.map +1 -0
  10. package/dist/chunk-7473HK24.js +17 -0
  11. package/dist/chunk-7473HK24.js.map +1 -0
  12. package/dist/chunk-7Y5ROPXL.js +33 -0
  13. package/dist/chunk-7Y5ROPXL.js.map +1 -0
  14. package/dist/chunk-A2RBQD66.js +7 -0
  15. package/dist/chunk-A2RBQD66.js.map +1 -0
  16. package/dist/chunk-ASAMUGHG.js +651 -0
  17. package/dist/chunk-ASAMUGHG.js.map +1 -0
  18. package/dist/{chunk-B2P7AZ25.js → chunk-CYE4UBOB.js} +6 -4
  19. package/dist/chunk-CYE4UBOB.js.map +1 -0
  20. package/dist/chunk-DNP65TD5.js +832 -0
  21. package/dist/chunk-DNP65TD5.js.map +1 -0
  22. package/dist/{chunk-5CGO426C.js → chunk-GYLWEJHW.js} +5 -1
  23. package/dist/chunk-GYLWEJHW.js.map +1 -0
  24. package/dist/{chunk-AONAFOYU.js → chunk-I3JCFS7H.js} +25 -13
  25. package/dist/chunk-I3JCFS7H.js.map +1 -0
  26. package/dist/{chunk-X5CWPX7H.js → chunk-IIQ3WMJK.js} +13 -2
  27. package/dist/chunk-IIQ3WMJK.js.map +1 -0
  28. package/dist/{chunk-6K5BY47X.js → chunk-JVTONQFI.js} +1277 -277
  29. package/dist/chunk-JVTONQFI.js.map +1 -0
  30. package/dist/{chunk-RL4VKLBX.js → chunk-KKQANRLG.js} +2 -2
  31. package/dist/{chunk-RL4VKLBX.js.map → chunk-KKQANRLG.js.map} +1 -1
  32. package/dist/{chunk-GKH3LJ7N.js → chunk-MPQAT55F.js} +38 -205
  33. package/dist/chunk-MPQAT55F.js.map +1 -0
  34. package/dist/chunk-NX2V6SIL.js +202 -0
  35. package/dist/chunk-NX2V6SIL.js.map +1 -0
  36. package/dist/{chunk-7QCUX4TK.js → chunk-NZHA4TZD.js} +72 -175
  37. package/dist/chunk-NZHA4TZD.js.map +1 -0
  38. package/dist/{chunk-MBH6IDSM.js → chunk-OCZJ4EYV.js} +40 -17
  39. package/dist/chunk-OCZJ4EYV.js.map +1 -0
  40. package/dist/{chunk-RJ5I2VO3.js → chunk-PHCURHC7.js} +6 -6
  41. package/dist/chunk-PHCURHC7.js.map +1 -0
  42. package/dist/{chunk-4YO5H5ON.js → chunk-Q4OGQM5I.js} +4 -10
  43. package/dist/chunk-Q4OGQM5I.js.map +1 -0
  44. package/dist/chunk-QSU47XEX.js +13 -0
  45. package/dist/chunk-QSU47XEX.js.map +1 -0
  46. package/dist/{chunk-LCC7HNFP.js → chunk-RZXJTDH5.js} +2 -2
  47. package/dist/{chunk-Z2LZ7IZ7.js → chunk-SN3OZVEQ.js} +5 -31
  48. package/dist/chunk-SN3OZVEQ.js.map +1 -0
  49. package/dist/{chunk-Z5ILULF2.js → chunk-SQ5VUG77.js} +4 -3
  50. package/dist/{chunk-Z5ILULF2.js.map → chunk-SQ5VUG77.js.map} +1 -1
  51. package/dist/chunk-STH5DLQP.js +1192 -0
  52. package/dist/chunk-STH5DLQP.js.map +1 -0
  53. package/dist/{chunk-NMXYENH4.js → chunk-VZFJTKIW.js} +6 -6
  54. package/dist/{chunk-753VJIUP.js → chunk-X4ZU4QH5.js} +43 -9
  55. package/dist/chunk-X4ZU4QH5.js.map +1 -0
  56. package/dist/chunk-XD7SRDUY.js +188 -0
  57. package/dist/chunk-XD7SRDUY.js.map +1 -0
  58. package/dist/chunk-Z7I6SONO.js +825 -0
  59. package/dist/chunk-Z7I6SONO.js.map +1 -0
  60. package/dist/cli/quickdraw-docs.js +131 -113
  61. package/dist/cli/quickdraw-docs.js.map +1 -1
  62. package/dist/client/core.d.ts +387 -0
  63. package/dist/client/core.js +109 -0
  64. package/dist/client/core.js.map +1 -0
  65. package/dist/client/index.d.ts +30 -193
  66. package/dist/client/index.js +56 -217
  67. package/dist/client/index.js.map +1 -1
  68. package/dist/{clientTypes-hWcPUVS9.d.ts → clientTypes-CUUNJwWs.d.ts} +3 -3
  69. package/dist/{connection-CgijdGpT.d.ts → connection-2EeQ_Et0.d.ts} +16 -9
  70. package/dist/{createServer-Cp-Wk500.d.ts → createServer-Bx5HOcYK.d.ts} +37 -9
  71. package/dist/{createTestApp-BB_PkqQ7.d.ts → createTestApp-DAMANT79.d.ts} +36 -9
  72. package/dist/{envelope-DzWyIXjj.d.ts → envelope-BMBaxppV.d.ts} +200 -8
  73. package/dist/{http-DotQ5bj8.d.ts → http-YzLAar3w.d.ts} +15 -50
  74. package/dist/index.d.ts +7 -6
  75. package/dist/index.js +61 -28
  76. package/dist/index.js.map +1 -1
  77. package/dist/{infer-BmoZsL9a.d.ts → infer-Br62cnyW.d.ts} +39 -1
  78. package/dist/{metrics-DW80Exve.d.ts → metrics-CTVpw0gu.d.ts} +2 -2
  79. package/dist/parser.js +2 -1
  80. package/dist/prisma/index.d.ts +13 -6
  81. package/dist/prisma/index.js +155 -9
  82. package/dist/prisma/index.js.map +1 -1
  83. package/dist/remote-N7OUAGOW.js +15 -0
  84. package/dist/remote-N7OUAGOW.js.map +1 -0
  85. package/dist/server/auth/index.d.ts +3 -3
  86. package/dist/server/auth/index.js +5 -3
  87. package/dist/server/auth/index.js.map +1 -1
  88. package/dist/server/index.d.ts +140 -36
  89. package/dist/server/index.js +162 -55
  90. package/dist/server/index.js.map +1 -1
  91. package/dist/server/mcp/index.d.ts +34 -18
  92. package/dist/server/mcp/index.js +29 -12
  93. package/dist/server/mcp/index.js.map +1 -1
  94. package/dist/server/otel.d.ts +3 -3
  95. package/dist/{sharing-UDLn1049.d.ts → sharing-BrsmlDv_.d.ts} +3 -3
  96. package/dist/testing/client.d.ts +13 -13
  97. package/dist/testing/client.js +17 -10
  98. package/dist/testing/client.js.map +1 -1
  99. package/dist/testing/index.d.ts +49 -12
  100. package/dist/testing/index.js +102 -19
  101. package/dist/testing/index.js.map +1 -1
  102. package/dist/testing/mock.d.ts +5 -5
  103. package/dist/testing/mock.js +15 -9
  104. package/dist/tracked-BR5b2O-U.d.ts +43 -0
  105. package/dist/{types-CYliTP65.d.ts → types-CLRCQGnO.d.ts} +4 -3
  106. package/dist/types-tMagHbjy.d.ts +151 -0
  107. package/dist/utils/index.d.ts +16 -4
  108. package/dist/utils/index.js +6 -3
  109. package/package.json +5 -1
  110. package/dist/chunk-4YO5H5ON.js.map +0 -1
  111. package/dist/chunk-5CGO426C.js.map +0 -1
  112. package/dist/chunk-6K5BY47X.js.map +0 -1
  113. package/dist/chunk-753VJIUP.js.map +0 -1
  114. package/dist/chunk-7QCUX4TK.js.map +0 -1
  115. package/dist/chunk-AONAFOYU.js.map +0 -1
  116. package/dist/chunk-B2P7AZ25.js.map +0 -1
  117. package/dist/chunk-GKH3LJ7N.js.map +0 -1
  118. package/dist/chunk-GSIPUNJL.js.map +0 -1
  119. package/dist/chunk-MBH6IDSM.js.map +0 -1
  120. package/dist/chunk-RJ5I2VO3.js.map +0 -1
  121. package/dist/chunk-X5CWPX7H.js.map +0 -1
  122. package/dist/chunk-Z2LZ7IZ7.js.map +0 -1
  123. /package/dist/{chunk-LCC7HNFP.js.map → chunk-RZXJTDH5.js.map} +0 -0
  124. /package/dist/{chunk-NMXYENH4.js.map → chunk-VZFJTKIW.js.map} +0 -0
@@ -1,19 +1,19 @@
1
- import { J as AnyContract, at as ProjectionName, ai as FullProjectionOf, ac as CollectionName, ap as MethodName, d as StandardSchemaV1, c as InferOutput, N as NullableProjection, P as ProjectionList, aq as MethodOf, as as ParsedInputOf, ao as KindOf, A as AccessLevel, af as EntityOf, ar as OutputOf } from '../infer-BmoZsL9a.js';
2
- import { M as ModelName, v as PolicyFor, w as RowForms, x as AccessFor, H as HandlerContext, y as ModelColumn, z as WatchAccess, B as PublicAccess, E as HandlerArgs, G as CustomAccess, I as ShareMode, J as ChannelOptions, K as StreamOptions, u as RoomLeaveHandler, L as ChannelsRequired, h as Service, N as BaseContext, O as CallerFor, l as RunContext, m as RunOptions, o as StreamHandle, P as Presence, n as ServerRooms, Q as AccessPolicy, T as AnyAccessPolicy, V as PolicyColumns, X as PolicyForeign, Y as PolicyTools, k as AccessFilter, Z as RowAccess, q as AccessEngine, b as StorageWhere } from '../caller-BT-Mv4bD.js';
3
- export { aI as ANY_FIELD, aA as AccessForm, aB as AccessRequest, _ as AffectsLink, p as AnyContext, A as AnyService, r as AppRooms, aC as AuthenticatedAccess, aq as CallOptions, d as Caller, a9 as ChannelAccess, aa as ChannelContext, ab as ChannelHandler, ac as ChannelImplementation, ad as ChannelRoomOf, a4 as CollectionScope, a6 as ContextRooms, a7 as ContextServices, C as CountArgs, a3 as DEFAULT_BULK_THRESHOLD, i as DevWarning, D as DevWarningError, j as DevWarningKind, aD as EntryAccess, F as FindManyArgs, f as FlushInfo, e as FlushSink, at as ForeignColumns, au as ForeignColumnsOf, aE as IdKeyOf, aF as IdSelector, aL as LinkInterest, av as MembershipRead, ar as MethodCaller, aN as N_PLUS_ONE_STATEMENTS, aw as ParentLink, ax as PolicyKind, ay as PolicyReads, $ as ProjectedOutput, a0 as Projection, ae as RoomLeave, af as RoomLeaveReason, ag as RoomLeft, ah as RoomTarget, az as RowLevel, R as RowLevels, aG as ScopeAccess, aH as ServiceAccess, as as ServiceCaller, ai as ServiceChannel, a5 as ServiceCollection, g as ServiceMethod, aj as ServiceStream, c as StatementCount, S as StorageAdapter, a as StorageRow, ak as StreamImplementation, al as StreamPushArgs, am as StreamPushManyArgs, an as StreamSeed, ao as StreamSeedContext, t as StreamSubscriptions, ap as StreamValidation, a1 as TierGroup, a2 as Tiers, a8 as TouchOptions, aJ as UnitOfWork, U as UnitOfWorkFactory, aK as UnitOfWorkScope, W as WriteRecord, aM as formatDevWarning, s as storageOf } from '../caller-BT-Mv4bD.js';
4
- import { S as ServerOptions, Q as QuickdrawServer } from '../createServer-Cp-Wk500.js';
5
- export { C as ClusterClient, u as ClusterOptions, D as DEFAULT_STALL_INTERVAL_MS, e as DEFAULT_STALL_MAX_MS, f as DEFAULT_STALL_THRESHOLD_MS, p as DisconnectUserOptions, E as EntitySubscription, a as EntitySubscriptions, H as HttpApp, I as IoRedisLike, L as LegacyReply, t as LegacyWireOptions, M as MIN_STALL_INTERVAL_MS, m as QuickdrawIo, n as QuickdrawServerSocket, o as QuickdrawSocketData, y as RateLimitOptions, z as RateLimiter, R as RotateOptions, g as STALL_RESOLUTION_MS, b as ScopeSubscription, c as ScopeSubscriptions, l as ServerOnlyOptions, h as SlowMethod, q as SocketCors, r as SocketOptions, s as SocketRateLimitOptions, i as StallReport, j as StallWatchdogOptions, T as TopicWatch, d as TopicWatches, w as applyRateLimitMiddleware, v as createRateLimiter, k as createServer, x as createTieredRateLimiter } from '../createServer-Cp-Wk500.js';
6
- import { ad as Version } from '../envelope-DzWyIXjj.js';
7
- export { ag as MAX_ENTITY_IDS_PER_SOCKET, ah as MAX_SCOPES_PER_SOCKET, ai as MAX_TOPICS_PER_SOCKET } from '../envelope-DzWyIXjj.js';
8
- import { Q as QuickdrawTypes, D as DbOf, d as PrincipalKindOf, c as PrincipalOf, M as MaybePromise, b as McpContextOf, C as ContextExtensionOf, P as Principal } from '../types-CYliTP65.js';
9
- export { a as McpContext, T as Transport } from '../types-CYliTP65.js';
10
- import { c as DispatcherOptions, D as Dispatcher, d as DispatcherCollections } from '../http-DotQ5bj8.js';
11
- export { p as AccessChange, q as AccessChangeListener, A as AccessOptions, e as ChangeLogOptions, C as ContractOfServices, k as DEFAULT_LIMITS, g as DbOfServices, i as DispatchRequest, j as DispatchResult, o as DispatcherAccess, a as DispatcherBaseOptions, l as DispatcherLimits, u as HttpMiddleware, H as HttpRouter, v as HttpRouterOptions, b as HttpTransportOptions, L as LimitsOptions, m as PipelineOptions, P as PrincipalOfServices, R as RegisteredMethod, h as Registry, S as SharedData, n as SubscriptionLimits, T as TrackingOptions, V as VersionRequest, r as VersionSource, f as createDispatcher, s as createHttpRouter, t as toCallReply } from '../http-DotQ5bj8.js';
12
- import { l as CrudMethodName, d as CrudContractOptions, S as ScalarFieldOf, N as NumberFieldOf, m as CrudMethods, H as AdminMethodsOf, w as AdminContractOptions, G as AdminMethods } from '../admin-DWWrT1h6.js';
13
- import { S as SearchContractOptions, T as TextFieldOf, b as SearchMethods, n as SharingMethodName, f as SharingByNameMethod, g as SharingContractOptions, o as SharingMethods } from '../sharing-UDLn1049.js';
14
- import { x as AdminNeverWritable, l as AdminFieldConfig } from '../adminSchemas-D4bFKsrb.js';
15
- export { a as CallOutcome, C as CallRecord } from '../metrics-DW80Exve.js';
16
- export { b as AuthenticateRequest, A as AuthenticateResult, c as HttpAuthenticateRequest, d as HttpCredentialSource, S as ServerAuth, e as ServiceAccessSource, a as ServiceGrants, f as SocketAuthenticateRequest, r as recordSocketSession } from '../auth-DXiSJZaf.js';
1
+ import { J as AnyContract, at as ProjectionName, ai as FullProjectionOf, ac as CollectionName, A as AccessLevel, ap as MethodName, d as StandardSchemaV1, c as InferOutput, N as NullableProjection, P as ProjectionList, aq as MethodOf, as as ParsedInputOf, ao as KindOf, af as EntityOf, ar as OutputOf } from '../infer-Br62cnyW.js';
2
+ import { M as ModelName, u as PolicyFor, v as RowForms, w as AccessFor, x as HandlerContext, y as ModelColumn, z as WatchAccess, B as PublicAccess, E as HandlerArgs, G as CustomAccess, I as ShareMode, J as ChannelOptions, K as StreamOptions, t as RoomLeaveHandler, H as HostLeaveHandler, L as ChannelsRequired, h as Service, N as BaseContext, O as CallerFor, R as RunContext, k as RunOptions, n as StreamHandle, P as Presence, m as ServerRooms, Q as AccessPolicy, T as AnyAccessPolicy, V as PolicyColumns, X as PolicyForeign, Y as PolicyTools, Z as AccessFilter, _ as RowAccess, p as AccessEngine, b as StorageWhere } from '../caller-BTwGl7vm.js';
3
+ export { aP as ANY_FIELD, aF as AccessChange, aG as AccessChangeListener, aH as AccessForm, aI as AccessRequest, $ as AffectsLink, o as AnyContext, A as AnyService, q as AppRooms, aJ as AuthenticatedAccess, au as CallOptions, d as Caller, ab as ChannelAccess, ac as ChannelContext, ad as ChannelHandler, ae as ChannelImplementation, af as ChannelRoomOf, a5 as CollectionScope, a7 as ContextAccess, a8 as ContextRooms, a9 as ContextServices, C as CountArgs, a4 as DEFAULT_BULK_THRESHOLD, i as DevWarning, D as DevWarningError, j as DevWarningKind, l as DispatcherAccess, aK as EntryAccess, F as FindManyArgs, f as FlushInfo, e as FlushSink, ax as ForeignColumns, ay as ForeignColumnsOf, ag as HostLeave, aL as IdKeyOf, aM as IdSelector, aS as LinkInterest, az as MembershipRead, av as MethodCaller, aU as N_PLUS_ONE_STATEMENTS, aA as ParentLink, aB as PolicyKind, aC as PolicyReads, a0 as ProjectedOutput, a1 as Projection, ah as RoomLeave, ai as RoomLeaveReason, aj as RoomLeft, ak as RoomTarget, aD as RowLevel, aE as RowLevels, aN as ScopeAccess, aO as ServiceAccess, aw as ServiceCaller, al as ServiceChannel, a6 as ServiceCollection, g as ServiceMethod, am as ServiceStream, c as StatementCount, S as StorageAdapter, a as StorageRow, an as StreamImplementation, ao as StreamPushArgs, ap as StreamPushManyArgs, aq as StreamSeed, ar as StreamSeedContext, as as StreamSubscribersArgs, r as StreamSubscriptions, at as StreamValidation, a2 as TierGroup, a3 as Tiers, aa as TouchOptions, aQ as UnitOfWork, U as UnitOfWorkFactory, aR as UnitOfWorkScope, W as WriteRecord, aT as formatDevWarning, s as storageOf } from '../caller-BTwGl7vm.js';
4
+ import { S as ServerOptions, Q as QuickdrawServer } from '../createServer-Bx5HOcYK.js';
5
+ export { C as ClusterClient, u as ClusterOptions, D as DEFAULT_STALL_INTERVAL_MS, e as DEFAULT_STALL_MAX_MS, f as DEFAULT_STALL_THRESHOLD_MS, p as DisconnectUserOptions, E as EntitySubscription, a as EntitySubscriptions, H as HttpApp, I as IoRedisLike, L as LegacyReply, t as LegacyWireOptions, M as MIN_STALL_INTERVAL_MS, m as QuickdrawIo, n as QuickdrawServerSocket, o as QuickdrawSocketData, y as RateLimitOptions, z as RateLimiter, R as RotateOptions, g as STALL_RESOLUTION_MS, b as ScopeSubscription, c as ScopeSubscriptions, l as ServerOnlyOptions, h as SlowMethod, q as SocketCors, r as SocketOptions, s as SocketRateLimitOptions, i as StallReport, j as StallWatchdogOptions, T as TopicWatch, d as TopicWatches, w as applyRateLimitMiddleware, v as createRateLimiter, k as createServer, x as createTieredRateLimiter } from '../createServer-Bx5HOcYK.js';
6
+ import { aA as Version } from '../envelope-BMBaxppV.js';
7
+ export { aD as MAX_ENTITY_IDS_PER_SOCKET, aE as MAX_SCOPES_PER_SOCKET, aF as MAX_TOPICS_PER_SOCKET } from '../envelope-BMBaxppV.js';
8
+ import { Q as QuickdrawTypes, D as DbOf, d as PrincipalKindOf, b as PrincipalOf, M as MaybePromise, c as McpContextOf, C as ContextExtensionOf, P as Principal } from '../types-CLRCQGnO.js';
9
+ export { a as McpContext, T as Transport } from '../types-CLRCQGnO.js';
10
+ import { c as DispatcherOptions, D as Dispatcher, d as DispatcherCollections } from '../http-YzLAar3w.js';
11
+ export { A as AccessOptions, e as ChangeLogOptions, C as ContractOfServices, k as DEFAULT_LIMITS, g as DbOfServices, i as DispatchRequest, j as DispatchResult, a as DispatcherBaseOptions, l as DispatcherLimits, q as HttpMiddleware, H as HttpRouter, r as HttpRouterOptions, b as HttpTransportOptions, L as LimitsOptions, m as PipelineOptions, P as PrincipalOfServices, R as RegisteredMethod, h as Registry, S as SharedData, n as SubscriptionLimits, T as TrackingOptions, V as VersionRequest, o as VersionSource, f as createDispatcher, p as createHttpRouter, t as toCallReply } from '../http-YzLAar3w.js';
12
+ import { l as CrudMethodName, d as CrudContractOptions, S as ScalarFieldOf, N as NumberFieldOf, m as CrudMethods, H as AdminMethodsOf, w as AdminContractOptions, G as AdminMethods } from '../admin-CS7JB_UH.js';
13
+ import { S as SearchContractOptions, T as TextFieldOf, b as SearchMethods, n as SharingMethodName, f as SharingByNameMethod, g as SharingContractOptions, o as SharingMethods } from '../sharing-BrsmlDv_.js';
14
+ import { x as AdminNeverWritable, l as AdminFieldConfig, t as AdminData } from '../adminSchemas-29cGgrg5.js';
15
+ export { a as CallOutcome, C as CallRecord } from '../metrics-CTVpw0gu.js';
16
+ export { b as AuthenticateRequest, A as AuthenticateResult, c as HttpAuthenticateRequest, d as HttpCredentialSource, S as ServerAuth, e as ServiceAccessSource, a as ServiceGrants, f as SocketAuthenticateRequest, r as recordSocketSession } from '../auth-DtdYjrZ9.js';
17
17
  import { Server } from 'socket.io';
18
18
  import { L as Logger } from '../logger-Yz93KzdV.js';
19
19
  import 'node:http';
@@ -101,6 +101,14 @@ type HandlerResult<C extends AnyContract, Output, Proj> = Output extends Standar
101
101
  * wrapped by `nullable` and `listOf`.
102
102
  */
103
103
  type HandlerOutputOf<C extends AnyContract, M extends MethodName<C>, Proj = Record<never, never>> = HandlerResult<C, MethodOf<C, M>["output"], Proj>;
104
+ /**
105
+ * A service-wide grant a collection's subscribers need besides the anchor or
106
+ * self check: `{ service: L }`, the caller's grant on the collection's own
107
+ * service at least `L`, as a method's `{ service: L }` form counts it.
108
+ */
109
+ interface CollectionRequires {
110
+ readonly service: AccessLevel;
111
+ }
104
112
  /**
105
113
  * How one collection's scopes are authorized (RFC 0003 section 7.1), in
106
114
  * `defineService`'s `collections` option.
@@ -114,8 +122,14 @@ type HandlerOutputOf<C extends AnyContract, M extends MethodName<C>, Proj = Reco
114
122
  * On a service with an access policy its items still follow that policy:
115
123
  * only the rows its user may read at `Read`, and a row the user loses goes
116
124
  * out `removed`.
125
+ * - `requires: { service: L }`, beside either: the subscriber also needs a
126
+ * service-wide grant of at least `L` on this service, as the service's
127
+ * methods under `{ service: L }` do (`{ scopeAccess: "self", requires:
128
+ * { service: "Read" } }`: the user's own rows, for holders of the Read
129
+ * grant). Without it the scope is `FORBIDDEN`, and a socket whose grants
130
+ * reload below it leaves the scope (`qd:revoked`, reason `"access"`).
117
131
  *
118
- * A service-wide `Admin` grant on this service passes either check, as it
132
+ * A service-wide `Admin` grant on this service passes every check, as it
119
133
  * passes every check of the service. `bulkThreshold` (default 200) is how
120
134
  * many changed rows of one scope one flush may send as deltas; past it the
121
135
  * scope gets one `reset` and its clients load it again.
@@ -123,10 +137,12 @@ type HandlerOutputOf<C extends AnyContract, M extends MethodName<C>, Proj = Reco
123
137
  type CollectionOption = {
124
138
  readonly anchor: AnyContract;
125
139
  readonly scopeAccess?: undefined;
140
+ readonly requires?: CollectionRequires;
126
141
  readonly bulkThreshold?: number;
127
142
  } | {
128
143
  readonly scopeAccess: "self";
129
144
  readonly anchor?: undefined;
145
+ readonly requires?: CollectionRequires;
130
146
  readonly bulkThreshold?: number;
131
147
  };
132
148
  /** `defineService`'s `collections` option: one entry per collection of the contract. */
@@ -212,7 +228,7 @@ type ShareOptions<A> = {
212
228
  * handler runs with the first caller's `ctx`, and every caller gets its
213
229
  * result, so a `"all"` result must depend on the input only: its
214
230
  * handler reads nothing of the caller (in development, reading
215
- * `ctx.principal`, `ctx.services` or `ctx.mcp` warns
231
+ * `ctx.principal`, `ctx.services`, `ctx.mcp` or `ctx.access` warns
216
232
  * `[quickdraw:shared-principal]`, and a strict test app fails the
217
233
  * call). `"all"` is not allowed with `custom` access, nor on the kit
218
234
  * methods whose result depends on who asks (the read/write kit's
@@ -341,9 +357,10 @@ interface ServiceDefinition<T extends QuickdrawTypes, C extends AnyContract, A,
341
357
  * How each collection of the contract authorizes its scopes (RFC 0003
342
358
  * section 7.1): `{ anchor: contract }`, the contract whose rows the scope
343
359
  * values are ids of, or `{ scopeAccess: "self" }` for a scope that is the
344
- * subscriber's user id; plus `bulkThreshold`. Required when the contract
345
- * declares collections. Needs `model`. A self scope's items still follow
346
- * the service's `access` policy, when it has one.
360
+ * subscriber's user id; plus `requires: { service: L }`, a service-wide
361
+ * grant every subscriber needs besides, and `bulkThreshold`. Required
362
+ * when the contract declares collections. Needs `model`. A self scope's
363
+ * items still follow the service's `access` policy, when it has one.
347
364
  */
348
365
  readonly collections?: CollectionOptions<C>;
349
366
  /**
@@ -400,6 +417,20 @@ interface ServiceDefinition<T extends QuickdrawTypes, C extends AnyContract, A,
400
417
  * },
401
418
  */
402
419
  readonly onRoomLeave?: RoomLeaveHandler<PrincipalOf<T>>;
420
+ /**
421
+ * Called once when the host of an app room leaves it (host mode, RFC 0003
422
+ * section 12.5): its own leave, a removal, or a disconnect, with the room,
423
+ * the host's socket and principal and the reason. The room has no host
424
+ * then, and its sockets heard `qd:host [room, null]`; the app decides
425
+ * what follows (another host, the game's end). Run as `onRoomLeave` is,
426
+ * beside `createServer`'s own, in a unit of work of its own.
427
+ *
428
+ * @example
429
+ * onHostLeave: ({ room }) => {
430
+ * qd.rooms.emit(room, game, "hostLeft", { room });
431
+ * },
432
+ */
433
+ readonly onHostLeave?: HostLeaveHandler<PrincipalOf<T>>;
403
434
  /**
404
435
  * Whether a service-wide `Admin` grant passes every access check of this
405
436
  * service (RFC 0003 section 4.1). Default `true`.
@@ -513,10 +544,12 @@ interface Quickdraw<T extends QuickdrawTypes> {
513
544
  /**
514
545
  * The handle of a stream (RFC 0003 section 12.5), for handlers, jobs and
515
546
  * timers: `qd.stream(task, "logs").push(taskId, line)` (`push(item)` for a
516
- * global stream; `pushMany(taskId, lines)` for several at once). Each push
517
- * goes through the dispatcher this instance created last, so a handle can
518
- * be made when a module loads; pushing before any dispatcher exists, or to
519
- * a stream it does not serve, throws.
547
+ * global stream; `pushMany(taskId, lines)` for several at once), and
548
+ * `await qd.stream(task, "logs").subscribers(taskId)`, how many sockets
549
+ * watch the feed on every node. Each use goes through the dispatcher this
550
+ * instance created last, so a handle can be made when a module loads;
551
+ * pushing before any dispatcher exists, or to a stream it does not serve,
552
+ * throws (`subscribers` rejects).
520
553
  * Throws a `TypeError` at once for a stream the contract does not declare.
521
554
  */
522
555
  stream<C extends AnyContract, K extends keyof C["streams"] & string>(contract: C, name: K): StreamHandle<C, K>;
@@ -844,8 +877,12 @@ type CrudMethodsOf<C extends AnyContract> = {
844
877
  type CrudKindOf<C extends AnyContract, M extends MethodName<C>> = C["methods"][M] extends {
845
878
  readonly "~crud"?: infer Kind;
846
879
  } ? Extract<Kind, CrudMethodName> : never;
847
- /** What a `custom` access check of a kit method reads from `ctx`. */
848
- type KitContext = Pick<BaseContext<Principal>, "principal" | "signal" | "log" | "requestId" | "transport">;
880
+ /**
881
+ * What a `custom` access check of a kit method, and the app's callbacks a
882
+ * kit calls (`prepare`, `onWrite`, `onChange`, ...), read from `ctx`:
883
+ * `ctx.access` asks the caller's level on another row.
884
+ */
885
+ type KitContext = Pick<BaseContext<Principal>, "principal" | "signal" | "log" | "requestId" | "transport" | "access">;
849
886
  /** One access form per kit method of `C`: what `crud.handlers`' `access` must give. */
850
887
  type CrudAccess<C extends AnyContract> = {
851
888
  readonly [M in CrudMethodsOf<C>]: AccessFor<ParsedInputOf<C, M>, KitContext>;
@@ -1232,6 +1269,35 @@ declare function labelOf(name: string): string;
1232
1269
  /** A service's name for people: "taskService" is "Tasks" (4.1's `toDisplayName`). */
1233
1270
  declare function displayNameOf(serviceName: string): string;
1234
1271
 
1272
+ /**
1273
+ * A write the admin kit is about to make, as `prepare` hears it: `data` is
1274
+ * the caller's data, checked; `before` is the row before the write, every
1275
+ * field, read in the write's transaction (as `onWrite` hears it).
1276
+ */
1277
+ type AdminPrepareCall<Row = unknown> = {
1278
+ readonly method: "adminCreate";
1279
+ readonly data: AdminData<Row>;
1280
+ } | {
1281
+ readonly method: "adminUpdate";
1282
+ readonly id: string;
1283
+ readonly data: AdminData<Row>;
1284
+ readonly before: Row;
1285
+ } | {
1286
+ readonly method: "adminDelete";
1287
+ readonly id: string;
1288
+ readonly before: Row;
1289
+ };
1290
+ /**
1291
+ * `admin.handlers`' `prepare`: runs before each write the kit makes, inside
1292
+ * one transaction with it, after the caller's access and data were checked,
1293
+ * with that transaction's tracked client as `db` (the app's client type
1294
+ * `Db`, when `db` is annotated): its own writes commit with the edit, and a
1295
+ * throw undoes them and the edit and fails the call. Before `adminCreate`
1296
+ * and `adminUpdate` it may return column values, merged over the caller's
1297
+ * data (each anchor column among them checked at the method's row level);
1298
+ * what it returns before `adminDelete` is ignored.
1299
+ */
1300
+ type AdminPrepare<Row = unknown, Db = unknown> = (call: AdminPrepareCall<Row>, ctx: KitContext, db: Db) => MaybePromise<Readonly<Record<string, unknown>> | void>;
1235
1301
  /** A write the admin kit made, as `onWrite` hears it. */
1236
1302
  interface AdminWrite<Row = unknown> {
1237
1303
  /** The method that wrote. */
@@ -1289,7 +1355,7 @@ type AdminFieldOverride = Partial<Pick<AdminFieldConfig, "type" | "label" | "req
1289
1355
  type NotAnAdminMethod<C extends AnyContract, A> = [Exclude<keyof A, AdminMethodsOf<C>>] extends [
1290
1356
  never
1291
1357
  ] ? unknown : `admin.handlers: ${Exclude<keyof A, AdminMethodsOf<C>> & string} is not a method admin.contract made for ${C["name"]}`;
1292
- /** The options of `admin.handlers(contract, options)`. `Db` comes from an annotated `onWrite` `db`. */
1358
+ /** The options of `admin.handlers(contract, options)`. `Db` comes from an annotated `db` of `prepare` or `onWrite`. */
1293
1359
  interface AdminHandlersOptions<C extends AnyContract, A, Db = unknown> {
1294
1360
  /**
1295
1361
  * Forms that replace the kit's default, `{ service: "Admin" }`, per method.
@@ -1351,14 +1417,49 @@ interface AdminHandlersOptions<C extends AnyContract, A, Db = unknown> {
1351
1417
  * here, since any caller the form admits reaches any row by its id.
1352
1418
  */
1353
1419
  readonly rowless?: readonly AdminMethodsOf<C>[];
1420
+ /**
1421
+ * Runs before each write `adminCreate`, `adminUpdate` or `adminDelete`
1422
+ * makes, in one transaction with it and `onWrite`, once the caller's
1423
+ * access and data were checked: `{ method: "adminCreate", data }`,
1424
+ * `{ method: "adminUpdate", id, data, before }` or
1425
+ * `{ method: "adminDelete", id, before }` (`data` the caller's, `before`
1426
+ * the row, every field), the call's `ctx`, and the transaction's tracked
1427
+ * client as `db`. A throw fails the call and undoes everything.
1428
+ *
1429
+ * Before `adminCreate` and `adminUpdate` it may return column values,
1430
+ * merged over the caller's data and written: a column the server computes
1431
+ * (a hash, a slug), even one the caller may not write (hidden, not
1432
+ * editable, above the caller's level, an owner column the policy reads),
1433
+ * but never `id`, a timestamp, a relation or a nested write (`VALIDATION`).
1434
+ * An anchor column it sets (an `inherit` parent, an anchored collection's
1435
+ * scope) must name a row on which the caller has the method's row level
1436
+ * (`FORBIDDEN`), as for the caller's data and the read/write kit's
1437
+ * `prepare`: a lowered form never moves a row into a parent its caller
1438
+ * cannot reach. Returning nothing, or `undefined` for a key, keeps the
1439
+ * caller's data. What it returns before `adminDelete` is ignored.
1440
+ *
1441
+ * Its writes through `db` are tracked like any other: before a delete,
1442
+ * delete or clear there the rows the database would delete or clear with
1443
+ * the row (a cascade, `SET NULL`), which the tracked client never sees,
1444
+ * so the rows and lists open on them are told.
1445
+ *
1446
+ * @example
1447
+ * prepare: async (call, ctx, db: PrismaClient) => {
1448
+ * if (call.method === "adminDelete") {
1449
+ * // the database deletes a project's tasks with it: delete them first, tracked
1450
+ * await db.task.deleteMany({ where: { projectId: call.id } });
1451
+ * }
1452
+ * },
1453
+ */
1454
+ readonly prepare?: AdminPrepare<EntityOf<C>, Db>;
1354
1455
  /**
1355
1456
  * Runs after each write `adminCreate`, `adminUpdate` or `adminDelete`
1356
1457
  * makes, in one transaction with it: `{ method, id, before?, after }` and
1357
1458
  * the call's `ctx`, with the transaction's tracked client as `db`. A
1358
1459
  * throw undoes the write and fails the call. For what an admin edit must
1359
1460
  * set off (a game reloading its tunables, an audit row) without wrapping
1360
- * the kit's handlers. Without it the kit opens no transaction and reads
1361
- * no `before`.
1461
+ * the kit's handlers. Without it, `prepare` or `onCommitted`, the kit
1462
+ * opens no transaction and reads no `before`.
1362
1463
  *
1363
1464
  * @example
1364
1465
  * onWrite: ({ method, after }) => {
@@ -1407,10 +1508,11 @@ type Empty = Record<never, never>;
1407
1508
  declare function handlers<C extends AnyContract, const A extends AdminAccess<C> = Empty, Db = unknown>(contract: C & NoInfer<AdminContract<C>>, options?: AdminHandlersOptions<C, A, Db>): AdminImplementations<C, A, Db>;
1408
1509
  /**
1409
1510
  * The admin kit: `admin.handlers(contract, { access?, displayName?,
1410
- * hiddenFields?, editable?, fieldOverrides?, rowless?, grants? })` implements the
1411
- * methods `admin.contract` made in `contract`, each open to a service-wide
1412
- * `Admin` grant unless `access` gives another form. `admin.contract` is here
1413
- * too, for server code; a shared package imports it from the root export.
1511
+ * hiddenFields?, editable?, fieldOverrides?, rowless?, grants?, prepare?,
1512
+ * onWrite?, onCommitted? })` implements the methods `admin.contract` made in
1513
+ * `contract`, each open to a service-wide `Admin` grant unless `access` gives
1514
+ * another form. `admin.contract` is here too, for server code; a shared
1515
+ * package imports it from the root export.
1414
1516
  */
1415
1517
  declare const admin: Readonly<{
1416
1518
  contract: <const O extends AdminContractOptions>(options: O & NoInfer<O extends {
@@ -1447,7 +1549,9 @@ declare const admin: Readonly<{
1447
1549
  * option; docs/deploying.md). When the subscribing connection comes back
1448
1550
  * after a drop, the node's clients are told to reconnect within 2 seconds,
1449
1551
  * so they catch up on what the node missed; a publish Valkey did not take
1450
- * is logged rather than left unhandled (`cluster/adapterClients.ts`).
1552
+ * is logged rather than left unhandled (`cluster/adapterClients.ts`). Once
1553
+ * the adapter is set, the node asks the others for the hosts of their app
1554
+ * rooms, as a node started with a cluster adapter does (`realtime/hosts.ts`).
1451
1555
  *
1452
1556
  * @example
1453
1557
  * ```typescript
@@ -1658,4 +1762,4 @@ declare function decryptIfEncrypted(value: string): string;
1658
1762
  /** Safe wrapper that returns `null` instead of throwing on invalid/stale ciphertext. */
1659
1763
  declare function tryDecrypt(ciphertext: string, logger?: Logger): string | null;
1660
1764
 
1661
- export { ADMIN_HIDDEN_FIELDS, AccessEngine, AccessFilter, AccessFor, type AccessMap, AccessPolicy, type AdminAccess, type AdminContract, type AdminDefaultAccess, type AdminFieldOf, type AdminFieldOverride, type AdminHandlersOptions, type AdminImplementations, type AdminOnCommitted, type AdminOnWrite, type AdminOutputOf, type AdminWrite, type AffectsOption, AnyAccessPolicy, BaseContext, type BasicAccessEngineOptions, CHANNEL_ABUSE_MULTIPLIER, CHANNEL_ABUSE_WINDOW_MS, CallerFor, ChannelOptions, ChannelsRequired, type CollectionOption, type CollectionOptions, type CollectionsRequired, ContextExtensionOf, type ContextFactory, type CrudAccess, type CrudCreateOf, type CrudHandlersOptions, type CrudImplementations, type CrudKindOf, type CrudMethodsOf, type CrudPrepare, CustomAccess, DbOf, type DefineService, Dispatcher, DispatcherCollections, DispatcherOptions, type EnvValidationResult, HandlerArgs, HandlerContext, type HandlerOutputOf, type HandlerRow, INDEX_MAX_ROWS, type InheritOptions, type InitArgs, type InitOptions, type JsonAclOptions, type JsonColumnValue, type KitContext, type KitHandler, type KitHandlerArgs, MAX_APP_ROOMS, MAX_ITEM_IDS, MAX_STREAMS_PER_SOCKET, MaybePromise, McpContextOf, type MembersOptions, type MethodAccess, type MethodImplementation, ModelColumn, ModelName, type NextOrdinalOptions, ORDINAL_STEP, PRESENCE_MAX_LAST_SEEN, PolicyFor, PolicyTools, Presence, Principal, type PrincipalFor, PrincipalKindOf, PrincipalOf, type ProjectCheck, type ProjectionOption, PublicAccess, type Quickdraw, QuickdrawServer, QuickdrawTypes, RESUME_MAX_AGE_MS, RESUME_MAX_DELTAS, type RedisAdapterOptions, type RedisAdapterResult, type ResolverMembership, type ResolverOptions, type ResolverReads, RoomLeaveHandler, RowAccess, type RowFor, RowForms, type RowFormsOf, RunContext, RunOptions, STREAM_MAX_SCOPES, type SearchAccess, type SearchContract, type SearchHandlersOptions, type SearchIdsOptions, type SearchImplementations, type SearchMethodsOf, type SearchStrategy, type SearchStrategyContext, ServerOptions, ServerRooms, Service, type ServiceDefinition, ShareMode, type SharingAccess, type SharingByNameOf, type SharingChange, type SharingChangeKind, type SharingContract, type SharingDefaultAccess, type SharingHandlersOptions, type SharingImplementations, type SharingKindOf, type SharingMethodsOf, type SharingOnChange, type SharingOptionsArgs, type SharingResolveUser, type SharingUserLookup, StorageWhere, StreamHandle, StreamOptions, type ValidateEnvOptions, WatchAccess, admin, anyOf, checkEnv, createBasicAccessEngine, crud, custom, decrypt, decryptIfEncrypted, displayNameOf, encrypt, everyone, inherit, initQuickdraw, isEncrypted, isRedisAdapterAvailable, jsonAcl, labelOf, meetsLevel, members, nextOrdinal, owner, requireEnv, requireRow, resolver, search, serviceGrant, setupRedisAdapter, sharing, tryDecrypt, validateEnv };
1765
+ export { ADMIN_HIDDEN_FIELDS, AccessEngine, AccessFilter, AccessFor, type AccessMap, AccessPolicy, type AdminAccess, type AdminContract, type AdminDefaultAccess, type AdminFieldOf, type AdminFieldOverride, type AdminHandlersOptions, type AdminImplementations, type AdminOnCommitted, type AdminOnWrite, type AdminOutputOf, type AdminPrepare, type AdminPrepareCall, type AdminWrite, type AffectsOption, AnyAccessPolicy, BaseContext, type BasicAccessEngineOptions, CHANNEL_ABUSE_MULTIPLIER, CHANNEL_ABUSE_WINDOW_MS, CallerFor, ChannelOptions, ChannelsRequired, type CollectionOption, type CollectionOptions, type CollectionRequires, type CollectionsRequired, ContextExtensionOf, type ContextFactory, type CrudAccess, type CrudCreateOf, type CrudHandlersOptions, type CrudImplementations, type CrudKindOf, type CrudMethodsOf, type CrudPrepare, CustomAccess, DbOf, type DefineService, Dispatcher, DispatcherCollections, DispatcherOptions, type EnvValidationResult, HandlerArgs, HandlerContext, type HandlerOutputOf, type HandlerRow, HostLeaveHandler, INDEX_MAX_ROWS, type InheritOptions, type InitArgs, type InitOptions, type JsonAclOptions, type JsonColumnValue, type KitContext, type KitHandler, type KitHandlerArgs, MAX_APP_ROOMS, MAX_ITEM_IDS, MAX_STREAMS_PER_SOCKET, MaybePromise, McpContextOf, type MembersOptions, type MethodAccess, type MethodImplementation, ModelColumn, ModelName, type NextOrdinalOptions, ORDINAL_STEP, PRESENCE_MAX_LAST_SEEN, PolicyFor, PolicyTools, Presence, Principal, type PrincipalFor, PrincipalKindOf, PrincipalOf, type ProjectCheck, type ProjectionOption, PublicAccess, type Quickdraw, QuickdrawServer, QuickdrawTypes, RESUME_MAX_AGE_MS, RESUME_MAX_DELTAS, type RedisAdapterOptions, type RedisAdapterResult, type ResolverMembership, type ResolverOptions, type ResolverReads, RoomLeaveHandler, RowAccess, type RowFor, RowForms, type RowFormsOf, RunContext, RunOptions, STREAM_MAX_SCOPES, type SearchAccess, type SearchContract, type SearchHandlersOptions, type SearchIdsOptions, type SearchImplementations, type SearchMethodsOf, type SearchStrategy, type SearchStrategyContext, ServerOptions, ServerRooms, Service, type ServiceDefinition, ShareMode, type SharingAccess, type SharingByNameOf, type SharingChange, type SharingChangeKind, type SharingContract, type SharingDefaultAccess, type SharingHandlersOptions, type SharingImplementations, type SharingKindOf, type SharingMethodsOf, type SharingOnChange, type SharingOptionsArgs, type SharingResolveUser, type SharingUserLookup, StorageWhere, StreamHandle, StreamOptions, type ValidateEnvOptions, WatchAccess, admin, anyOf, checkEnv, createBasicAccessEngine, crud, custom, decrypt, decryptIfEncrypted, displayNameOf, encrypt, everyone, inherit, initQuickdraw, isEncrypted, isRedisAdapterAvailable, jsonAcl, labelOf, meetsLevel, members, nextOrdinal, owner, requireEnv, requireRow, resolver, search, serviceGrant, setupRedisAdapter, sharing, tryDecrypt, validateEnv };