@fitzzero/quickdraw-core 5.1.1 → 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 (152) hide show
  1. package/README.md +1308 -219
  2. package/dist/{admin-DKwkIh5i.d.ts → admin-CS7JB_UH.d.ts} +2 -2
  3. package/dist/{adminSchemas-2DUA_hZ8.d.ts → adminSchemas-29cGgrg5.d.ts} +6 -4
  4. package/dist/{auth-BhWqdyb-.d.ts → auth-DtdYjrZ9.d.ts} +51 -21
  5. package/dist/{caller-CXTFswBO.d.ts → caller-BTwGl7vm.d.ts} +296 -33
  6. package/dist/chunk-2FDSKLBO.js +82 -0
  7. package/dist/chunk-2FDSKLBO.js.map +1 -0
  8. package/dist/{chunk-RT6OILOI.js → chunk-4D2DOGAW.js} +2 -14
  9. package/dist/chunk-4D2DOGAW.js.map +1 -0
  10. package/dist/{chunk-OECZPRPW.js → chunk-64I6MYBC.js} +162 -775
  11. package/dist/chunk-64I6MYBC.js.map +1 -0
  12. package/dist/chunk-7473HK24.js +17 -0
  13. package/dist/chunk-7473HK24.js.map +1 -0
  14. package/dist/chunk-7Y5ROPXL.js +33 -0
  15. package/dist/chunk-7Y5ROPXL.js.map +1 -0
  16. package/dist/chunk-A2RBQD66.js +7 -0
  17. package/dist/chunk-A2RBQD66.js.map +1 -0
  18. package/dist/chunk-AK23XSWD.js +16 -0
  19. package/dist/chunk-AK23XSWD.js.map +1 -0
  20. package/dist/chunk-ASAMUGHG.js +651 -0
  21. package/dist/chunk-ASAMUGHG.js.map +1 -0
  22. package/dist/{chunk-B2P7AZ25.js → chunk-CYE4UBOB.js} +6 -4
  23. package/dist/chunk-CYE4UBOB.js.map +1 -0
  24. package/dist/chunk-DKE6QO26.js +136 -0
  25. package/dist/chunk-DKE6QO26.js.map +1 -0
  26. package/dist/chunk-DNP65TD5.js +832 -0
  27. package/dist/chunk-DNP65TD5.js.map +1 -0
  28. package/dist/{chunk-H23KEFBA.js → chunk-DUBU3BB3.js} +30 -1
  29. package/dist/chunk-DUBU3BB3.js.map +1 -0
  30. package/dist/chunk-GYLWEJHW.js +19 -0
  31. package/dist/chunk-GYLWEJHW.js.map +1 -0
  32. package/dist/{chunk-SHEGLZEP.js → chunk-I3JCFS7H.js} +34 -13
  33. package/dist/chunk-I3JCFS7H.js.map +1 -0
  34. package/dist/{chunk-X5CWPX7H.js → chunk-IIQ3WMJK.js} +13 -2
  35. package/dist/chunk-IIQ3WMJK.js.map +1 -0
  36. package/dist/{chunk-RZTP4IEW.js → chunk-JVTONQFI.js} +6339 -4226
  37. package/dist/chunk-JVTONQFI.js.map +1 -0
  38. package/dist/{chunk-QEKVYG5F.js → chunk-KKQANRLG.js} +2 -2
  39. package/dist/chunk-KKQANRLG.js.map +1 -0
  40. package/dist/{chunk-CDKG4TFA.js → chunk-MPQAT55F.js} +38 -205
  41. package/dist/chunk-MPQAT55F.js.map +1 -0
  42. package/dist/chunk-NO4M6PO5.js +101 -0
  43. package/dist/chunk-NO4M6PO5.js.map +1 -0
  44. package/dist/{chunk-TBMKJ26R.js → chunk-NW6U45HX.js} +3 -1
  45. package/dist/chunk-NW6U45HX.js.map +1 -0
  46. package/dist/chunk-NX2V6SIL.js +202 -0
  47. package/dist/chunk-NX2V6SIL.js.map +1 -0
  48. package/dist/{chunk-ZIVPHYRG.js → chunk-NZHA4TZD.js} +72 -175
  49. package/dist/chunk-NZHA4TZD.js.map +1 -0
  50. package/dist/{chunk-2PWMUVC7.js → chunk-OCZJ4EYV.js} +518 -27
  51. package/dist/chunk-OCZJ4EYV.js.map +1 -0
  52. package/dist/{chunk-REX5YPHX.js → chunk-PHCURHC7.js} +76 -21
  53. package/dist/chunk-PHCURHC7.js.map +1 -0
  54. package/dist/{chunk-4YO5H5ON.js → chunk-Q4OGQM5I.js} +4 -10
  55. package/dist/chunk-Q4OGQM5I.js.map +1 -0
  56. package/dist/chunk-QSU47XEX.js +13 -0
  57. package/dist/chunk-QSU47XEX.js.map +1 -0
  58. package/dist/{chunk-DD4SKCNO.js → chunk-RZXJTDH5.js} +13 -2
  59. package/dist/chunk-RZXJTDH5.js.map +1 -0
  60. package/dist/{chunk-Z2LZ7IZ7.js → chunk-SN3OZVEQ.js} +5 -31
  61. package/dist/chunk-SN3OZVEQ.js.map +1 -0
  62. package/dist/{chunk-4DIQHASK.js → chunk-SQ5VUG77.js} +28 -8
  63. package/dist/chunk-SQ5VUG77.js.map +1 -0
  64. package/dist/chunk-STH5DLQP.js +1192 -0
  65. package/dist/chunk-STH5DLQP.js.map +1 -0
  66. package/dist/{chunk-QCHKWIRS.js → chunk-VZFJTKIW.js} +13 -13
  67. package/dist/{chunk-QCHKWIRS.js.map → chunk-VZFJTKIW.js.map} +1 -1
  68. package/dist/{chunk-VSQBHPWH.js → chunk-X4ZU4QH5.js} +54 -22
  69. package/dist/chunk-X4ZU4QH5.js.map +1 -0
  70. package/dist/chunk-XD7SRDUY.js +188 -0
  71. package/dist/chunk-XD7SRDUY.js.map +1 -0
  72. package/dist/chunk-XH2IZVLT.js +62 -0
  73. package/dist/chunk-XH2IZVLT.js.map +1 -0
  74. package/dist/chunk-Z7I6SONO.js +825 -0
  75. package/dist/chunk-Z7I6SONO.js.map +1 -0
  76. package/dist/cli/quickdraw-docs.js +132 -112
  77. package/dist/cli/quickdraw-docs.js.map +1 -1
  78. package/dist/client/core.d.ts +387 -0
  79. package/dist/client/core.js +109 -0
  80. package/dist/client/index.d.ts +52 -203
  81. package/dist/client/index.js +59 -218
  82. package/dist/client/index.js.map +1 -1
  83. package/dist/{clientTypes-Bc-G8n-U.d.ts → clientTypes-CUUNJwWs.d.ts} +3 -3
  84. package/dist/{connection-Cr1BU07W.d.ts → connection-2EeQ_Et0.d.ts} +22 -11
  85. package/dist/{createServer-CP9eDHZZ.d.ts → createServer-Bx5HOcYK.d.ts} +67 -17
  86. package/dist/{createTestApp-UKVGEmOf.d.ts → createTestApp-DAMANT79.d.ts} +46 -13
  87. package/dist/{envelope-Cp3YcVxC.d.ts → envelope-BMBaxppV.d.ts} +216 -10
  88. package/dist/{http-Djj2Inuu.d.ts → http-YzLAar3w.d.ts} +76 -60
  89. package/dist/index.d.ts +8 -7
  90. package/dist/index.js +82 -25
  91. package/dist/index.js.map +1 -1
  92. package/dist/{infer-Teo1xpsd.d.ts → infer-Br62cnyW.d.ts} +82 -11
  93. package/dist/logger-Yz93KzdV.d.ts +30 -0
  94. package/dist/{metrics-BdBu5o8G.d.ts → metrics-CTVpw0gu.d.ts} +2 -2
  95. package/dist/origins-kvpxnVcW.d.ts +8 -0
  96. package/dist/parser.js +2 -1
  97. package/dist/prisma/index.d.ts +14 -7
  98. package/dist/prisma/index.js +279 -70
  99. package/dist/prisma/index.js.map +1 -1
  100. package/dist/{rateLimit-ZMIZJUZF.js → rateLimit-5RKBFLUR.js} +2 -2
  101. package/dist/rateLimit-5RKBFLUR.js.map +1 -0
  102. package/dist/remote-N7OUAGOW.js +15 -0
  103. package/dist/remote-N7OUAGOW.js.map +1 -0
  104. package/dist/server/auth/index.d.ts +82 -33
  105. package/dist/server/auth/index.js +277 -270
  106. package/dist/server/auth/index.js.map +1 -1
  107. package/dist/server/express/index.d.ts +9 -2
  108. package/dist/server/express/index.js +1 -1
  109. package/dist/server/index.d.ts +268 -84
  110. package/dist/server/index.js +664 -418
  111. package/dist/server/index.js.map +1 -1
  112. package/dist/server/mcp/index.d.ts +89 -27
  113. package/dist/server/mcp/index.js +281 -62
  114. package/dist/server/mcp/index.js.map +1 -1
  115. package/dist/server/otel.d.ts +3 -3
  116. package/dist/{sharing-DVa8W-yR.d.ts → sharing-BrsmlDv_.d.ts} +3 -3
  117. package/dist/testing/client.d.ts +14 -14
  118. package/dist/testing/client.js +19 -10
  119. package/dist/testing/client.js.map +1 -1
  120. package/dist/testing/index.d.ts +50 -13
  121. package/dist/testing/index.js +113 -21
  122. package/dist/testing/index.js.map +1 -1
  123. package/dist/testing/mock.d.ts +5 -5
  124. package/dist/testing/mock.js +17 -9
  125. package/dist/tracked-BR5b2O-U.d.ts +43 -0
  126. package/dist/{types-Cu0vmx7c.d.ts → types-CLRCQGnO.d.ts} +4 -3
  127. package/dist/types-tMagHbjy.d.ts +151 -0
  128. package/dist/utils/index.d.ts +16 -4
  129. package/dist/utils/index.js +6 -3
  130. package/package.json +5 -1
  131. package/dist/chunk-2PWMUVC7.js.map +0 -1
  132. package/dist/chunk-4DIQHASK.js.map +0 -1
  133. package/dist/chunk-4YO5H5ON.js.map +0 -1
  134. package/dist/chunk-B2P7AZ25.js.map +0 -1
  135. package/dist/chunk-CDKG4TFA.js.map +0 -1
  136. package/dist/chunk-DD4SKCNO.js.map +0 -1
  137. package/dist/chunk-H23KEFBA.js.map +0 -1
  138. package/dist/chunk-OECZPRPW.js.map +0 -1
  139. package/dist/chunk-QEKVYG5F.js.map +0 -1
  140. package/dist/chunk-REX5YPHX.js.map +0 -1
  141. package/dist/chunk-RT6OILOI.js.map +0 -1
  142. package/dist/chunk-RZTP4IEW.js.map +0 -1
  143. package/dist/chunk-SHEGLZEP.js.map +0 -1
  144. package/dist/chunk-TBMKJ26R.js.map +0 -1
  145. package/dist/chunk-VSQBHPWH.js.map +0 -1
  146. package/dist/chunk-X5CWPX7H.js.map +0 -1
  147. package/dist/chunk-YSWH776Y.js +0 -13
  148. package/dist/chunk-YSWH776Y.js.map +0 -1
  149. package/dist/chunk-Z2LZ7IZ7.js.map +0 -1
  150. package/dist/chunk-ZIVPHYRG.js.map +0 -1
  151. package/dist/logger-BY28acW-.d.ts +0 -16
  152. /package/dist/{rateLimit-ZMIZJUZF.js.map → client/core.js.map} +0 -0
@@ -1,20 +1,21 @@
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-Teo1xpsd.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-CXTFswBO.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, av as MembershipRead, ar as MethodCaller, aM 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, aL as formatDevWarning, s as storageOf } from '../caller-CXTFswBO.js';
4
- import { S as ServerOptions, Q as QuickdrawServer } from '../createServer-CP9eDHZZ.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-CP9eDHZZ.js';
6
- import { ad as Version } from '../envelope-Cp3YcVxC.js';
7
- 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-Cu0vmx7c.js';
8
- export { a as McpContext, T as Transport } from '../types-Cu0vmx7c.js';
9
- import { a as DispatcherOptions, D as Dispatcher, c as DispatcherCollections } from '../http-Djj2Inuu.js';
10
- export { o as AccessChange, p as AccessChangeListener, A as AccessOptions, d as ChangeLogOptions, C as ContractOfServices, j as DEFAULT_LIMITS, f as DbOfServices, h as DispatchRequest, i as DispatchResult, n as DispatcherAccess, k as DispatcherLimits, s as HttpMiddleware, H as HttpRouter, u as HttpRouterOptions, b as HttpTransportOptions, L as LimitsOptions, l as PipelineOptions, P as PrincipalOfServices, R as RegisteredMethod, g as Registry, S as SharedData, m as SubscriptionLimits, T as TrackingOptions, V as VersionRequest, q as VersionSource, e as createDispatcher, r as createHttpRouter, t as toCallReply } from '../http-Djj2Inuu.js';
11
- 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-DKwkIh5i.js';
12
- import { S as SearchContractOptions, T as TextFieldOf, b as SearchMethods, n as SharingMethodName, f as SharingByNameMethod, g as SharingContractOptions, o as SharingMethods } from '../sharing-DVa8W-yR.js';
13
- import { x as AdminNeverWritable, l as AdminFieldConfig } from '../adminSchemas-2DUA_hZ8.js';
14
- export { a as CallOutcome, C as CallRecord } from '../metrics-BdBu5o8G.js';
15
- 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-BhWqdyb-.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';
16
17
  import { Server } from 'socket.io';
17
- import { L as Logger } from '../logger-BY28acW-.js';
18
+ import { L as Logger } from '../logger-Yz93KzdV.js';
18
19
  import 'node:http';
19
20
  import '../errors-S-bxEIBC.js';
20
21
 
@@ -31,9 +32,6 @@ declare const MAX_APP_ROOMS = 100;
31
32
  /** The most scopes one stream keeps a seed for; the scope pushed to least recently goes first. */
32
33
  declare const STREAM_MAX_SCOPES = 10000;
33
34
 
34
- /** The most stream feeds one socket may subscribe to at once. */
35
- declare const MAX_STREAMS_PER_SOCKET = 500;
36
-
37
35
  /**
38
36
  * A JSON column's value as a database client types it: structurally
39
37
  * Prisma's `JsonValue` (and its `InputJsonValue` objects and arrays). A row
@@ -103,6 +101,14 @@ type HandlerResult<C extends AnyContract, Output, Proj> = Output extends Standar
103
101
  * wrapped by `nullable` and `listOf`.
104
102
  */
105
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
+ }
106
112
  /**
107
113
  * How one collection's scopes are authorized (RFC 0003 section 7.1), in
108
114
  * `defineService`'s `collections` option.
@@ -113,8 +119,17 @@ type HandlerOutputOf<C extends AnyContract, M extends MethodName<C>, Proj = Reco
113
119
  * that row, through its service's policy. Deleting the row closes its
114
120
  * scopes (`qd:revoked` with reason `"anchor-deleted"`).
115
121
  * - `scopeAccess: "self"`: the scope value is the subscriber's own user id.
122
+ * On a service with an access policy its items still follow that policy:
123
+ * only the rows its user may read at `Read`, and a row the user loses goes
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"`).
116
131
  *
117
- * 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
118
133
  * passes every check of the service. `bulkThreshold` (default 200) is how
119
134
  * many changed rows of one scope one flush may send as deltas; past it the
120
135
  * scope gets one `reset` and its clients load it again.
@@ -122,10 +137,12 @@ type HandlerOutputOf<C extends AnyContract, M extends MethodName<C>, Proj = Reco
122
137
  type CollectionOption = {
123
138
  readonly anchor: AnyContract;
124
139
  readonly scopeAccess?: undefined;
140
+ readonly requires?: CollectionRequires;
125
141
  readonly bulkThreshold?: number;
126
142
  } | {
127
143
  readonly scopeAccess: "self";
128
144
  readonly anchor?: undefined;
145
+ readonly requires?: CollectionRequires;
129
146
  readonly bulkThreshold?: number;
130
147
  };
131
148
  /** `defineService`'s `collections` option: one entry per collection of the contract. */
@@ -208,9 +225,15 @@ type ShareOptions<A> = {
208
225
  /**
209
226
  * Run identical concurrent calls once: `"caller"` per principal, `"all"`
210
227
  * across principals. Every caller is authorized before it joins; the
211
- * handler runs with the first caller's `ctx`, so a `"all"` handler must
212
- * not depend on who asks. `"all"` is not allowed with `custom` access,
213
- * whose result may depend on who asks.
228
+ * handler runs with the first caller's `ctx`, and every caller gets its
229
+ * result, so a `"all"` result must depend on the input only: its
230
+ * handler reads nothing of the caller (in development, reading
231
+ * `ctx.principal`, `ctx.services`, `ctx.mcp` or `ctx.access` warns
232
+ * `[quickdraw:shared-principal]`, and a strict test app fails the
233
+ * call). `"all"` is not allowed with `custom` access, nor on the kit
234
+ * methods whose result depends on who asks (the read/write kit's
235
+ * `list` and `getMany`, `search`, the sharing kit's `listShares` and
236
+ * `listMembers`, the admin kit's `adminList` and `adminGet`).
214
237
  */
215
238
  readonly share: A extends CustomAccess<never, never> ? "caller" : ShareMode;
216
239
  /** Reuse a successful result for this long after its run, in milliseconds. */
@@ -252,6 +275,22 @@ type MethodImplementation<T extends QuickdrawTypes, C extends AnyContract, M ext
252
275
  * signed out. Leave it out for the service's list.
253
276
  */
254
277
  readonly kinds?: readonly PrincipalKindOf<T>[];
278
+ /**
279
+ * A requirement on the caller's verified claims (`principal.claims`, a
280
+ * token's `scope`), beside `access`: the call passes only when it returns
281
+ * `true`. It adds to the form, so `{ entry: "Moderate" }` with `claims`
282
+ * needs Moderate on the row and the claims. It runs right after `kinds`,
283
+ * outside the access engine, so no grant passes it, a service-wide
284
+ * `Admin` grant included. Without a principal the call is
285
+ * `UNAUTHENTICATED`; when it returns anything but `true`, `FORBIDDEN`. It
286
+ * is synchronous, and a `"public"` method takes none. Never write a check
287
+ * on claims as `custom`: that form replaces the row check, and an Admin
288
+ * grant skips it.
289
+ *
290
+ * @example
291
+ * claims: (claims) => claims?.scope === "triage",
292
+ */
293
+ readonly claims?: (claims: PrincipalOf<T>["claims"], input: ParsedInputOf<C, M>) => boolean;
255
294
  /**
256
295
  * Runs the method. For a projection output it returns the database row
257
296
  * (or rows, or `null`), which the framework projects: only the
@@ -263,11 +302,15 @@ type MethodImplementation<T extends QuickdrawTypes, C extends AnyContract, M ext
263
302
  /**
264
303
  * Says the access form is this method's whole check on purpose. On a
265
304
  * service with an access policy, `defineService` refuses a method whose
266
- * input has `id` while its access is `"public"`, `"authenticated"` or `{
267
- * service: L }` below `Admin`, since any caller the form admits could then
268
- * reach any row by its id: give it `{ entry: L }` so the policy decides,
269
- * or `rowless: true` when every such caller may reach any row (public
270
- * profiles, lookups by an id that tells nothing).
305
+ * input has `id` while its access checks some other row or none:
306
+ * `"public"`, `"authenticated"`, `{ service: L }` below `Admin`,
307
+ * `custom(fn)`, `{ scope, of, id }`, or `{ entry, id }` naming another
308
+ * key. Any caller the form admits could then reach any row by its id:
309
+ * give it `{ entry: L }` so the policy decides (with `claims` beside it
310
+ * for a check on the caller's claims), or `rowless: true` when every such
311
+ * caller may reach any row (public profiles, lookups by an id that tells
312
+ * nothing), or when `id` names a row the method creates (an id the client
313
+ * made).
271
314
  */
272
315
  readonly rowless?: true;
273
316
  } & (KindOf<C, M> extends "query" ? QueryOptions<T, C, M, A> : MutationOptions);
@@ -314,8 +357,10 @@ interface ServiceDefinition<T extends QuickdrawTypes, C extends AnyContract, A,
314
357
  * How each collection of the contract authorizes its scopes (RFC 0003
315
358
  * section 7.1): `{ anchor: contract }`, the contract whose rows the scope
316
359
  * values are ids of, or `{ scopeAccess: "self" }` for a scope that is the
317
- * subscriber's user id; plus `bulkThreshold`. Required when the contract
318
- * declares collections. Needs `model`.
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.
319
364
  */
320
365
  readonly collections?: CollectionOptions<C>;
321
366
  /**
@@ -372,6 +417,20 @@ interface ServiceDefinition<T extends QuickdrawTypes, C extends AnyContract, A,
372
417
  * },
373
418
  */
374
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>>;
375
434
  /**
376
435
  * Whether a service-wide `Admin` grant passes every access check of this
377
436
  * service (RFC 0003 section 4.1). Default `true`.
@@ -485,10 +544,12 @@ interface Quickdraw<T extends QuickdrawTypes> {
485
544
  /**
486
545
  * The handle of a stream (RFC 0003 section 12.5), for handlers, jobs and
487
546
  * timers: `qd.stream(task, "logs").push(taskId, line)` (`push(item)` for a
488
- * global stream; `pushMany(taskId, lines)` for several at once). Each push
489
- * goes through the dispatcher this instance created last, so a handle can
490
- * be made when a module loads; pushing before any dispatcher exists, or to
491
- * 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).
492
553
  * Throws a `TypeError` at once for a stream the contract does not declare.
493
554
  */
494
555
  stream<C extends AnyContract, K extends keyof C["streams"] & string>(contract: C, name: K): StreamHandle<C, K>;
@@ -535,6 +596,9 @@ declare const CHANNEL_ABUSE_WINDOW_MS = 10000;
535
596
  /** A socket is disconnected once its drops within the window exceed this many times the channel's rate. */
536
597
  declare const CHANNEL_ABUSE_MULTIPLIER = 100;
537
598
 
599
+ /** The most stream feeds one socket may subscribe to at once. */
600
+ declare const MAX_STREAMS_PER_SOCKET = 500;
601
+
538
602
  /**
539
603
  * A custom access check: the call passes when `check(ctx, input)` resolves
540
604
  * `true`. The caller must be authenticated first, so `ctx.principal` is
@@ -543,6 +607,11 @@ declare const CHANNEL_ABUSE_MULTIPLIER = 100;
543
607
  * custom access cannot `share: "all"`, because its result may depend on who
544
608
  * asks.
545
609
  *
610
+ * It replaces the row check: on a service with an access policy,
611
+ * `defineService` refuses it on a method whose input has `id` unless the
612
+ * method says `rowless: true`. A check on the caller's claims is the
613
+ * method's `claims`, beside an `entry` form: no grant skips that.
614
+ *
546
615
  * @example
547
616
  * access: custom((ctx, input) => ctx.principal.userId === input.ownerId),
548
617
  */
@@ -578,7 +647,11 @@ declare function jsonAcl<const Field extends string, const Owner extends string
578
647
 
579
648
  /** Options of {@link members}. */
580
649
  interface MembersOptions<Model extends string = string, Entry extends string = string, User extends string = string, Level extends string = string> {
581
- /** The membership model, named as the client names it: `"projectMember"`. */
650
+ /**
651
+ * The membership model, named as the client names it: `"projectMember"`.
652
+ * It needs an `id` column (keep the pair unique with `@@unique`, never a
653
+ * composite `@@id`), or its writes are not tracked and never revoke.
654
+ */
582
655
  readonly model: Model;
583
656
  /** The column holding the id of the row the membership is on: `"projectId"`. */
584
657
  readonly entry: Entry;
@@ -589,14 +662,20 @@ interface MembersOptions<Model extends string = string, Entry extends string = s
589
662
  /**
590
663
  * Maps stored roles to access levels: `{ owner: "Admin", editor: "Moderate", viewer: "Read" }`.
591
664
  * Without it a stored role must be a level name. A role that maps to no
592
- * level grants nothing.
665
+ * level grants nothing. Roles that map to one level are peers: with
666
+ * `{ owner: "Admin", admin: "Admin" }` the sharing kit lets an `admin`
667
+ * demote or remove the `owner`. To make an owner untouchable, give the
668
+ * row an owner column (`anyOf(owner("ownerId"), members(...))`, or
669
+ * `jsonAcl(..., { owner })`).
593
670
  */
594
671
  readonly levels?: Readonly<Record<string, AccessLevel>>;
595
672
  }
596
673
  /**
597
674
  * The level comes from the principal's row in a membership table: one query
598
675
  * per lookup, filtered by the entry ids and the user id. Several rows for one
599
- * user and entry give the highest level among them.
676
+ * user and entry give the highest level among them. The table needs an `id`
677
+ * column, or no write to it is tracked and a removed member keeps what they
678
+ * subscribed to; `createServer` names such a table at start.
600
679
  *
601
680
  * @example
602
681
  * access: members({ model: "projectMember", entry: "projectId", user: "userId", level: "role" }),
@@ -666,7 +745,8 @@ interface ResolverOptions<P extends Principal = Principal, Column extends string
666
745
  /**
667
746
  * A filter matching exactly the rows on which the principal has at least
668
747
  * `level`, or `"none"`. Without it, list filters through this policy match
669
- * no row.
748
+ * no row, and the read/write kit's `reorder` moves none below a
749
+ * service-wide grant.
670
750
  */
671
751
  readonly where?: (principal: P, level: AccessLevel, tools: PolicyTools) => MaybePromise<AccessFilter>;
672
752
  /**
@@ -797,8 +877,12 @@ type CrudMethodsOf<C extends AnyContract> = {
797
877
  type CrudKindOf<C extends AnyContract, M extends MethodName<C>> = C["methods"][M] extends {
798
878
  readonly "~crud"?: infer Kind;
799
879
  } ? Extract<Kind, CrudMethodName> : never;
800
- /** What a `custom` access check of a kit method reads from `ctx`. */
801
- 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">;
802
886
  /** One access form per kit method of `C`: what `crud.handlers`' `access` must give. */
803
887
  type CrudAccess<C extends AnyContract> = {
804
888
  readonly [M in CrudMethodsOf<C>]: AccessFor<ParsedInputOf<C, M>, KitContext>;
@@ -819,22 +903,31 @@ interface CrudHandlersOptions<C extends AnyContract, A, Db = unknown> {
819
903
  * Who may call each of the kit's methods: one form per method, required.
820
904
  * `get`, `update`, `delete` and `reorder` take `{ entry: L }` to check the
821
905
  * row; the methods on many rows also keep only the rows the service's
822
- * policy gives the caller at the form's level.
906
+ * policy gives the caller at the form's level. A bulk method whose form
907
+ * names no level takes its single-row counterpart's row level (`delete`'s
908
+ * for `bulkDelete`, `update`'s for `bulkUpdate`) when it is higher than
909
+ * `Moderate`; give `{ entry: L, id: "ids" }` to refuse the whole call
910
+ * instead of skipping rows.
823
911
  */
824
912
  readonly access: A & NoInfer<NotAKitMethod<C, A>>;
825
913
  /**
826
914
  * What `create` writes, from its parsed input: set owner or scope columns
827
915
  * from `ctx.principal`, an ordinal from `nextOrdinal`. `create` writes the
828
- * input as it is without it.
916
+ * input as it is without it. An owner or access-list column (one the
917
+ * policy reads) comes only from here: the caller may not send one. The
918
+ * anchors of what it returns (each `inherit` parent and anchored
919
+ * collection's scope it sets) are checked at the method's row level, and
920
+ * it returns column values only, never a relation or a nested write.
829
921
  */
830
922
  readonly prepare?: [CrudCreateOf<C>] extends [never] ? `crud.handlers: prepare is for the kit's create, which ${C["name"]} does not have` : CrudPrepare<ParsedInputOf<C, CrudCreateOf<C>>, KitContext, Db>;
831
923
  /**
832
924
  * The kit's methods whose access form is their whole check on purpose:
833
925
  * each gets `rowless: true`. On a service with an access policy,
834
- * `defineService` refuses `get` under `"public"`, `"authenticated"` or
835
- * `{ service: L }` below `Admin` (any such caller could read any row by
836
- * its id) unless it is named here: `rowless: ["get"]` for public
837
- * profiles, say. `update`, `delete` and `reorder` check the row whatever
926
+ * `defineService` refuses `get` under a form that asks the policy nothing
927
+ * about the row its `id` names (`"public"`, `"authenticated"`,
928
+ * `{ service: L }` below `Admin`, `custom`, `{ scope }`, or `{ entry }` on
929
+ * another key: any such caller could read any row by its id) unless it is
930
+ * named here: `rowless: ["get"]` for public profiles, say. `update`, `delete` and `reorder` check the row whatever
838
931
  * their form, and need nothing.
839
932
  */
840
933
  readonly rowless?: readonly CrudMethodsOf<C>[];
@@ -963,7 +1056,8 @@ type SearchStrategy<Ctx = SearchStrategyContext> = {
963
1056
  * The filter of the rows that match `q`, in the database client's
964
1057
  * `where` shape: a Postgres full-text condition, say. The kit adds the
965
1058
  * access filter and the scope, and pages the rows by keyset cursor in
966
- * the scope collection's order (else by id).
1059
+ * the scope collection's order when the call passes a scope, else by
1060
+ * id.
967
1061
  */
968
1062
  readonly where: (q: string, ctx: Ctx) => MaybePromise<StorageWhere>;
969
1063
  readonly ids?: never;
@@ -1086,9 +1180,13 @@ interface SharingUserLookup {
1086
1180
  readonly email?: string;
1087
1181
  }
1088
1182
  /**
1089
- * Finds the user a by-name method means: their user id, or `null` (or
1183
+ * Finds the one user a by-name method means: their user id, or `null` (or
1090
1184
  * `undefined`) when there is no such user, which fails the call with
1091
- * `NOT_FOUND`.
1185
+ * `NOT_FOUND`. It must name exactly one user: look a user up by something
1186
+ * unique and verified (an email, with `findUnique`), and take a display
1187
+ * name's user only when exactly one user has that name, else `null`. A
1188
+ * `findFirst` by name hands the share to whoever registered the name first
1189
+ * (the 5.1 audit's SHARE-2).
1092
1190
  */
1093
1191
  type SharingResolveUser<Db = unknown> = (lookup: SharingUserLookup, ctx: KitContext, db: Db) => MaybePromise<string | null | undefined>;
1094
1192
  type NotASharingMethod<C extends AnyContract, A> = [Exclude<keyof A, SharingMethodsOf<C>>] extends [
@@ -1110,17 +1208,25 @@ type SharingHandlersOptions<C extends AnyContract, A, Db = unknown> = {
1110
1208
  readonly onChange?: SharingOnChange<Db>;
1111
1209
  /**
1112
1210
  * The kit's methods whose access form is their whole check on purpose:
1113
- * each gets `rowless: true`. On a service with an access policy,
1211
+ * each gets `rowless: true`. A change still never touches a user above
1212
+ * the caller's own level on the row, which under such a form is their
1213
+ * level on the row (often none): name `service` in the form for a
1214
+ * service-wide grant to count. On a service with an access policy,
1114
1215
  * `defineService` refuses an access-list method (`share`, `unshare`,
1115
1216
  * `setLevel`, `listShares`, `shareByName`: their input names the row as
1116
- * `id`) under `"public"`, `"authenticated"` or `{ service: L }` below
1117
- * `Admin` unless it is named here.
1217
+ * `id`) under a form that asks the policy nothing about that row
1218
+ * (`"public"`, `"authenticated"`, `{ service: L }` below `Admin`,
1219
+ * `custom`, `{ scope }`, or `{ entry }` on another key) unless it is named
1220
+ * here.
1118
1221
  */
1119
1222
  readonly rowless?: readonly SharingMethodsOf<C>[];
1120
1223
  } & ([SharingByNameOf<C>] extends [never] ? {
1121
1224
  readonly resolveUser?: `sharing.handlers: resolveUser is for shareByName and inviteByName, which ${C["name"]} does not have`;
1122
1225
  } : {
1123
- /** Finds the user `shareByName` and `inviteByName` mean, by name or email. */
1226
+ /**
1227
+ * Finds the one user `shareByName` and `inviteByName` mean, by name or
1228
+ * email, or `null`: never the first of several (`SharingResolveUser`).
1229
+ */
1124
1230
  readonly resolveUser: SharingResolveUser<Db>;
1125
1231
  });
1126
1232
  /** `sharing.handlers`' options argument: required when the contract has a by-name method. */
@@ -1163,6 +1269,35 @@ declare function labelOf(name: string): string;
1163
1269
  /** A service's name for people: "taskService" is "Tasks" (4.1's `toDisplayName`). */
1164
1270
  declare function displayNameOf(serviceName: string): string;
1165
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>;
1166
1301
  /** A write the admin kit made, as `onWrite` hears it. */
1167
1302
  interface AdminWrite<Row = unknown> {
1168
1303
  /** The method that wrote. */
@@ -1220,7 +1355,7 @@ type AdminFieldOverride = Partial<Pick<AdminFieldConfig, "type" | "label" | "req
1220
1355
  type NotAnAdminMethod<C extends AnyContract, A> = [Exclude<keyof A, AdminMethodsOf<C>>] extends [
1221
1356
  never
1222
1357
  ] ? unknown : `admin.handlers: ${Exclude<keyof A, AdminMethodsOf<C>> & string} is not a method admin.contract made for ${C["name"]}`;
1223
- /** 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`. */
1224
1359
  interface AdminHandlersOptions<C extends AnyContract, A, Db = unknown> {
1225
1360
  /**
1226
1361
  * Forms that replace the kit's default, `{ service: "Admin" }`, per method.
@@ -1233,26 +1368,29 @@ interface AdminHandlersOptions<C extends AnyContract, A, Db = unknown> {
1233
1368
  readonly displayName?: string;
1234
1369
  /**
1235
1370
  * Fields the kit leaves out entirely: from `adminMeta`, from the rows it
1236
- * returns and from what it writes. `acl`, `serviceAccess` and
1237
- * `service_access` are always hidden, as in 4.1, unless `grants` shows
1238
- * the last two.
1371
+ * returns and from what it writes. `acl`, `serviceAccess`,
1372
+ * `service_access` and the column the dispatcher's `serviceAccessSource`
1373
+ * names on this service's model are always hidden (the first three as in
1374
+ * 4.1), unless `grants` shows the grants field.
1239
1375
  */
1240
1376
  readonly hiddenFields?: readonly Exclude<AdminFieldOf<C>, "id">[];
1241
1377
  /**
1242
- * Show and write the entity's `serviceAccess` (or `service_access`), the
1243
- * user's service-wide grants, which the kit hides by default: an admin
1244
- * screen then edits grants through `adminUpdate` (a JSON field, checked by
1245
- * the entity's schema). Only a caller whose own service-wide grant on this
1246
- * service is `Admin` reads or writes it, whatever `access` gives a method;
1247
- * anyone else is refused a write, filter or sort naming it (`FORBIDDEN`)
1248
- * and gets rows without it. Such an Admin can grant any service,
1249
- * themself included, so give that grant only to those who may. With
1250
- * `auth.serviceAccessSource` naming the column, a change reaches the
1251
- * user's open sockets on every node at once (`qd:access`, their
1252
- * subscriptions resolved again), as any tracked write to it does. Only for
1253
- * an entity with such a field. Default `false`.
1254
- */
1255
- readonly grants?: [Extract<AdminFieldOf<C>, "serviceAccess" | "service_access">] extends [never] ? never : boolean;
1378
+ * Show and write the entity's grants field, the user's service-wide
1379
+ * grants, which the kit hides by default: `serviceAccess`,
1380
+ * `service_access`, or the column `auth.serviceAccessSource` names on this
1381
+ * service's model, whatever its name. An admin screen then edits grants
1382
+ * through `adminUpdate` (a JSON field, checked by the entity's schema).
1383
+ * Only a caller whose own service-wide grant on this service is `Admin`
1384
+ * reads or writes it, whatever `access` gives a method; anyone else is
1385
+ * refused a write, filter or sort naming it (`FORBIDDEN`) and gets rows
1386
+ * without it. Such an Admin can grant any service, themself included, so
1387
+ * give that grant only to those who may. With `auth.serviceAccessSource`
1388
+ * naming the column, a change reaches the user's open sockets on every
1389
+ * node at once (`qd:access`, their subscriptions resolved again), as any
1390
+ * tracked write to it does. The dispatcher refuses `true` for an entity
1391
+ * without a grants field, when it is made. Default `false`.
1392
+ */
1393
+ readonly grants?: boolean;
1256
1394
  /**
1257
1395
  * The only fields `adminCreate` and `adminUpdate` write (finding R1.4 of
1258
1396
  * the 5.0.0 review): `adminMeta` reports every other field `editable:
@@ -1273,19 +1411,55 @@ interface AdminHandlersOptions<C extends AnyContract, A, Db = unknown> {
1273
1411
  * The kit's methods whose access form is their whole check on purpose:
1274
1412
  * each gets `rowless: true`. On a service with an access policy,
1275
1413
  * `defineService` refuses `adminGet`, `adminUpdate` or `adminDelete`
1276
- * under a form below the default that checks no row (`{ service:
1277
- * "Moderate" }`, `"authenticated"`) unless it is named here, since any
1278
- * caller the form admits reaches any row by its id.
1414
+ * under a form below the default that asks the policy nothing about the
1415
+ * row its `id` names (`{ service: "Moderate" }`, `"authenticated"`,
1416
+ * `custom`, `{ scope }`, or `{ entry }` on another key) unless it is named
1417
+ * here, since any caller the form admits reaches any row by its id.
1279
1418
  */
1280
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>;
1281
1455
  /**
1282
1456
  * Runs after each write `adminCreate`, `adminUpdate` or `adminDelete`
1283
1457
  * makes, in one transaction with it: `{ method, id, before?, after }` and
1284
1458
  * the call's `ctx`, with the transaction's tracked client as `db`. A
1285
1459
  * throw undoes the write and fails the call. For what an admin edit must
1286
1460
  * set off (a game reloading its tunables, an audit row) without wrapping
1287
- * the kit's handlers. Without it the kit opens no transaction and reads
1288
- * no `before`.
1461
+ * the kit's handlers. Without it, `prepare` or `onCommitted`, the kit
1462
+ * opens no transaction and reads no `before`.
1289
1463
  *
1290
1464
  * @example
1291
1465
  * onWrite: ({ method, after }) => {
@@ -1334,10 +1508,11 @@ type Empty = Record<never, never>;
1334
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>;
1335
1509
  /**
1336
1510
  * The admin kit: `admin.handlers(contract, { access?, displayName?,
1337
- * hiddenFields?, editable?, fieldOverrides?, rowless?, grants? })` implements the
1338
- * methods `admin.contract` made in `contract`, each open to a service-wide
1339
- * `Admin` grant unless `access` gives another form. `admin.contract` is here
1340
- * 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.
1341
1516
  */
1342
1517
  declare const admin: Readonly<{
1343
1518
  contract: <const O extends AdminContractOptions>(options: O & NoInfer<O extends {
@@ -1374,7 +1549,9 @@ declare const admin: Readonly<{
1374
1549
  * option; docs/deploying.md). When the subscribing connection comes back
1375
1550
  * after a drop, the node's clients are told to reconnect within 2 seconds,
1376
1551
  * so they catch up on what the node missed; a publish Valkey did not take
1377
- * 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`).
1378
1555
  *
1379
1556
  * @example
1380
1557
  * ```typescript
@@ -1411,11 +1588,18 @@ interface RedisAdapterOptions {
1411
1588
  */
1412
1589
  password?: string;
1413
1590
  /**
1414
- * Redis database number (default: 0)
1591
+ * Redis database number (default: 0). It does not separate deployments:
1592
+ * pub/sub is shared across a server's databases, so two deployments on one
1593
+ * Valkey hear each other's events whatever their `db`; give each its own
1594
+ * Valkey, or its own `cluster.keyPrefix` (docs/deploying.md).
1415
1595
  */
1416
1596
  db?: number;
1417
1597
  /**
1418
- * Key prefix for Socket.io adapter (default: 'socket.io')
1598
+ * The adapter's key, which names its pub/sub channels. Default: the
1599
+ * server's `cluster.keyPrefix` ("quickdraw" without one), so deployments
1600
+ * with their own prefixes use their own channels. 5.1.0 and earlier used
1601
+ * "socket.io": pass `keyPrefix: "socket.io"` for the deploy that moves a
1602
+ * cluster from such nodes, so old and new nodes keep hearing each other.
1419
1603
  */
1420
1604
  keyPrefix?: string;
1421
1605
  /**
@@ -1578,4 +1762,4 @@ declare function decryptIfEncrypted(value: string): string;
1578
1762
  /** Safe wrapper that returns `null` instead of throwing on invalid/stale ciphertext. */
1579
1763
  declare function tryDecrypt(ciphertext: string, logger?: Logger): string | null;
1580
1764
 
1581
- 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 };