@fitzzero/quickdraw-core 5.0.1 → 5.1.1

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 (60) hide show
  1. package/README.md +303 -32
  2. package/dist/{admin-CBlTY0do.d.ts → admin-DKwkIh5i.d.ts} +2 -2
  3. package/dist/{adminSchemas-zji11V74.d.ts → adminSchemas-2DUA_hZ8.d.ts} +1 -1
  4. package/dist/{auth-CMyRkfjZ.d.ts → auth-BhWqdyb-.d.ts} +2 -2
  5. package/dist/{caller-BqCYnpmC.d.ts → caller-CXTFswBO.d.ts} +27 -5
  6. package/dist/{chunk-2XJFNVHW.js → chunk-2PWMUVC7.js} +1 -1
  7. package/dist/{chunk-2XJFNVHW.js.map → chunk-2PWMUVC7.js.map} +1 -1
  8. package/dist/{chunk-O2PWC2YW.js → chunk-OECZPRPW.js} +3 -3
  9. package/dist/{chunk-3JNMVB2V.js → chunk-QCHKWIRS.js} +2 -2
  10. package/dist/{chunk-5YRQ26LF.js → chunk-RT6OILOI.js} +1 -1
  11. package/dist/chunk-RT6OILOI.js.map +1 -0
  12. package/dist/{chunk-NS5PUHIZ.js → chunk-RZTP4IEW.js} +130 -23
  13. package/dist/chunk-RZTP4IEW.js.map +1 -0
  14. package/dist/{chunk-HQ6WIRE2.js → chunk-SHEGLZEP.js} +4 -4
  15. package/dist/{chunk-WVIRXYI4.js → chunk-VSQBHPWH.js} +2 -2
  16. package/dist/{chunk-WVIRXYI4.js.map → chunk-VSQBHPWH.js.map} +1 -1
  17. package/dist/chunk-XNLWBZIG.js +9 -0
  18. package/dist/chunk-XNLWBZIG.js.map +1 -0
  19. package/dist/{chunk-ZACRRYWL.js → chunk-ZIVPHYRG.js} +4 -4
  20. package/dist/cli/quickdraw-docs.js +241 -27
  21. package/dist/cli/quickdraw-docs.js.map +1 -1
  22. package/dist/client/index.d.ts +7 -7
  23. package/dist/client/index.js +4 -4
  24. package/dist/{clientTypes-DuZW_8mb.d.ts → clientTypes-Bc-G8n-U.d.ts} +3 -3
  25. package/dist/{connection-DuN8GvcD.d.ts → connection-Cr1BU07W.d.ts} +2 -2
  26. package/dist/{createServer-CGsJlxM8.d.ts → createServer-CP9eDHZZ.d.ts} +30 -9
  27. package/dist/{createTestApp-Cg2CZa1g.d.ts → createTestApp-UKVGEmOf.d.ts} +6 -6
  28. package/dist/{envelope-nf5eGB-a.d.ts → envelope-Cp3YcVxC.d.ts} +1 -1
  29. package/dist/{http-D3fSFQ57.d.ts → http-Djj2Inuu.d.ts} +6 -6
  30. package/dist/index.d.ts +6 -6
  31. package/dist/index.js +26 -6
  32. package/dist/index.js.map +1 -1
  33. package/dist/{infer-Dw21kmLw.d.ts → infer-Teo1xpsd.d.ts} +17 -0
  34. package/dist/{metrics-C0WvB7-I.d.ts → metrics-BdBu5o8G.d.ts} +2 -2
  35. package/dist/prisma/index.d.ts +4 -4
  36. package/dist/server/auth/index.d.ts +3 -3
  37. package/dist/server/index.d.ts +47 -26
  38. package/dist/server/index.js +62 -36
  39. package/dist/server/index.js.map +1 -1
  40. package/dist/server/mcp/index.d.ts +51 -11
  41. package/dist/server/mcp/index.js +129 -8
  42. package/dist/server/mcp/index.js.map +1 -1
  43. package/dist/server/otel.d.ts +3 -3
  44. package/dist/{sharing-CoreezAq.d.ts → sharing-DVa8W-yR.d.ts} +3 -3
  45. package/dist/testing/client.d.ts +13 -13
  46. package/dist/testing/client.js +5 -5
  47. package/dist/testing/index.d.ts +156 -12
  48. package/dist/testing/index.js +1036 -21
  49. package/dist/testing/index.js.map +1 -1
  50. package/dist/testing/mock.d.ts +5 -5
  51. package/dist/testing/mock.js +4 -4
  52. package/dist/{types-Bwg3kIEc.d.ts → types-Cu0vmx7c.d.ts} +8 -2
  53. package/dist/utils/index.d.ts +1 -1
  54. package/package.json +1 -1
  55. package/dist/chunk-5YRQ26LF.js.map +0 -1
  56. package/dist/chunk-NS5PUHIZ.js.map +0 -1
  57. /package/dist/{chunk-O2PWC2YW.js.map → chunk-OECZPRPW.js.map} +0 -0
  58. /package/dist/{chunk-3JNMVB2V.js.map → chunk-QCHKWIRS.js.map} +0 -0
  59. /package/dist/{chunk-HQ6WIRE2.js.map → chunk-SHEGLZEP.js.map} +0 -0
  60. /package/dist/{chunk-ZACRRYWL.js.map → chunk-ZIVPHYRG.js.map} +0 -0
@@ -347,6 +347,8 @@ interface CollectionWhere {
347
347
  }
348
348
  /** Any collection of any contract, as `defineContract` stores it. */
349
349
  interface CollectionDef {
350
+ /** What the list holds, in a sentence or two, for the generated docs. */
351
+ readonly describe?: string | undefined;
350
352
  /** A string column of the entity, or `via(...)` for a junction table. */
351
353
  readonly scope: string | ViaScope;
352
354
  /** The projection each item is sent as: `"entity"` or a named projection. */
@@ -434,6 +436,8 @@ interface StreamDef<Item extends StandardSchemaV1 = StandardSchemaV1> {
434
436
  readonly volatile?: boolean;
435
437
  /** Who may subscribe. Without it the stream is closed. */
436
438
  readonly access?: StreamAccess;
439
+ /** What the stream carries, in a sentence or two, for the generated docs. */
440
+ readonly describe?: string;
437
441
  }
438
442
  /**
439
443
  * Where a channel requirement finds its row id or scope value in the parsed
@@ -498,10 +502,14 @@ interface ChannelDef<Payload extends StandardSchemaV1 = StandardSchemaV1> {
498
502
  readonly burst?: number;
499
503
  /** What the sender must already be subscribed to, or the app room it must be in. */
500
504
  readonly requires?: ChannelRequires;
505
+ /** What a message says, in a sentence or two, for the generated docs. */
506
+ readonly describe?: string;
501
507
  }
502
508
  /** A typed custom room event, delivered as `qd:event` (RFC 0003 section 8.3). */
503
509
  interface EventDef<Payload extends StandardSchemaV1 = StandardSchemaV1> {
504
510
  readonly payload: Payload;
511
+ /** What the event announces, in a sentence or two, for the generated docs. */
512
+ readonly describe?: string;
505
513
  }
506
514
  /** True when a stream has one feed per scope value; false for a global stream. */
507
515
  declare function isScopedStream(def: Pick<StreamDef, "scope">): boolean;
@@ -521,6 +529,11 @@ interface ChannelDefinition extends Omit<ChannelDef, "requires"> {
521
529
  }
522
530
  /** The second argument of {@link defineContract}. */
523
531
  interface ContractDefinition {
532
+ /**
533
+ * What the service is for, in a sentence or two. The generated API docs
534
+ * lead the service's page with it and list it in their index.
535
+ */
536
+ readonly describe?: string;
524
537
  /**
525
538
  * The full row; its output must contain `id: string`. Omit it for a service
526
539
  * without a model, which then has no projections, fields or collections.
@@ -567,6 +580,8 @@ type MemberOf<Def, Key extends string, Absent> = Def extends {
567
580
  interface Contract<Name extends string = string, Def extends ContractDefinition = ContractDefinition> {
568
581
  /** The service name, unchanged on the wire and in stored grants. */
569
582
  readonly name: Name;
583
+ /** What the service is for; absent when the definition has none. */
584
+ readonly describe?: string;
570
585
  readonly entity: MemberOf<Def, "entity", undefined>;
571
586
  readonly projections: MemberOf<Def, "projections", Empty>;
572
587
  readonly fields: MemberOf<Def, "fields", Empty>;
@@ -579,6 +594,7 @@ interface Contract<Name extends string = string, Def extends ContractDefinition
579
594
  /** Any contract. Every contract `defineContract` returns is assignable to it. */
580
595
  interface AnyContract {
581
596
  readonly name: string;
597
+ readonly describe?: string;
582
598
  readonly entity: RowSchema | undefined;
583
599
  readonly projections: {
584
600
  readonly [name: string]: RowSchema;
@@ -615,6 +631,7 @@ type IndexRow<Item, Fields> = Pick<Item, Extract<keyof Item, "id" | Fields>>;
615
631
  type ColumnOf<Row> = [Row] extends [never] ? string : keyof Row & string;
616
632
  type ScopeColumnOf<Row> = [Row] extends [never] ? string : StringColumn<Row> & string;
617
633
  interface CollectionContext<Row, Entity, Projections, Item, Index> {
634
+ readonly describe?: string | undefined;
618
635
  readonly scope: NoInfer<ViaScope | ScopeColumnOf<Row>>;
619
636
  readonly item: Item;
620
637
  readonly order: NoInfer<OrderBy<ColumnOf<Row>>>;
@@ -1,6 +1,6 @@
1
- import { k as MethodKind } from './infer-Dw21kmLw.js';
1
+ import { k as MethodKind } from './infer-Teo1xpsd.js';
2
2
  import { a as ErrorCode } from './errors-S-bxEIBC.js';
3
- import { T as Transport } from './types-Bwg3kIEc.js';
3
+ import { T as Transport } from './types-Cu0vmx7c.js';
4
4
 
5
5
  /** How a call ended: `"ok"`, `"not-modified"`, or the error code it failed with. */
6
6
  type CallOutcome = "ok" | "not-modified" | ErrorCode;
@@ -1,9 +1,9 @@
1
1
  import { L as Logger } from '../logger-BY28acW-.js';
2
- export { C as CountArgs, F as FindManyArgs, c as StatementCount, S as StorageAdapter, a as StorageRow, b as StorageWhere, s as storageOf } from '../caller-BqCYnpmC.js';
3
- import '../envelope-nf5eGB-a.js';
4
- import '../infer-Dw21kmLw.js';
2
+ export { C as CountArgs, F as FindManyArgs, c as StatementCount, S as StorageAdapter, a as StorageRow, b as StorageWhere, s as storageOf } from '../caller-CXTFswBO.js';
3
+ import '../envelope-Cp3YcVxC.js';
4
+ import '../infer-Teo1xpsd.js';
5
5
  import '../errors-S-bxEIBC.js';
6
- import '../types-Bwg3kIEc.js';
6
+ import '../types-Cu0vmx7c.js';
7
7
 
8
8
  /** Options of {@link trackPrisma}. */
9
9
  interface TrackPrismaOptions {
@@ -1,8 +1,8 @@
1
1
  import { L as Logger } from '../../logger-BY28acW-.js';
2
2
  import { IncomingHttpHeaders, IncomingMessage, ServerResponse } from 'node:http';
3
- import { M as MaybePromise, P as Principal } from '../../types-Bwg3kIEc.js';
4
- import { b as AuthenticateRequest, H as HttpRequest } from '../../auth-CMyRkfjZ.js';
5
- import '../../infer-Dw21kmLw.js';
3
+ import { M as MaybePromise, P as Principal } from '../../types-Cu0vmx7c.js';
4
+ import { b as AuthenticateRequest, H as HttpRequest } from '../../auth-BhWqdyb-.js';
5
+ import '../../infer-Teo1xpsd.js';
6
6
  import 'socket.io';
7
7
 
8
8
  /**
@@ -1,18 +1,18 @@
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-Dw21kmLw.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, f 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-BqCYnpmC.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, i 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, g as DevWarning, D as DevWarningError, h as DevWarningKind, aD as EntryAccess, F as FindManyArgs, e as FlushInfo, d 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, j 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-BqCYnpmC.js';
4
- import { S as ServerOptions, Q as QuickdrawServer } from '../createServer-CGsJlxM8.js';
5
- export { C as ClusterClient, t 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, M as MIN_STALL_INTERVAL_MS, m as QuickdrawIo, n as QuickdrawServerSocket, o as QuickdrawSocketData, x as RateLimitOptions, y 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, v as applyRateLimitMiddleware, u as createRateLimiter, k as createServer, w as createTieredRateLimiter } from '../createServer-CGsJlxM8.js';
6
- import { ad as Version } from '../envelope-nf5eGB-a.js';
7
- import { Q as QuickdrawTypes, D as DbOf, c as PrincipalOf, M as MaybePromise, b as McpContextOf, C as ContextExtensionOf, P as Principal } from '../types-Bwg3kIEc.js';
8
- export { a as McpContext, T as Transport } from '../types-Bwg3kIEc.js';
9
- import { a as DispatcherOptions, D as Dispatcher, c as DispatcherCollections } from '../http-D3fSFQ57.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-D3fSFQ57.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-CBlTY0do.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-CoreezAq.js';
13
- import { x as AdminNeverWritable, l as AdminFieldConfig } from '../adminSchemas-zji11V74.js';
14
- export { a as CallOutcome, C as CallRecord } from '../metrics-C0WvB7-I.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-CMyRkfjZ.js';
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';
16
16
  import { Server } from 'socket.io';
17
17
  import { L as Logger } from '../logger-BY28acW-.js';
18
18
  import 'node:http';
@@ -34,16 +34,6 @@ declare const STREAM_MAX_SCOPES = 10000;
34
34
  /** The most stream feeds one socket may subscribe to at once. */
35
35
  declare const MAX_STREAMS_PER_SOCKET = 500;
36
36
 
37
- /** 4.x's `ServiceResponse`, the shape every reply of the shim takes. */
38
- type LegacyReply = {
39
- readonly success: true;
40
- readonly data: unknown;
41
- } | {
42
- readonly success: false;
43
- readonly error: string;
44
- readonly code: number;
45
- };
46
-
47
37
  /**
48
38
  * A JSON column's value as a database client types it: structurally
49
39
  * Prisma's `JsonValue` (and its `InputJsonValue` objects and arrays). A row
@@ -252,6 +242,16 @@ interface MutationOptions {
252
242
  type MethodImplementation<T extends QuickdrawTypes, C extends AnyContract, M extends MethodName<C>, A, Rows extends RowForms = "all", Proj = Empty$2> = {
253
243
  /** Who may call: `"public"`, `"authenticated"`, `{ service }`, `{ entry }`, `{ scope, of, id }` or `custom(fn)`. */
254
244
  readonly access: AccessValue<A, MethodAccess<T, C, M, Rows>>;
245
+ /**
246
+ * The kinds of principal that may call this method (RFC 0003 section
247
+ * 4.1), within its service's `kinds` (or the app's): `kinds: ["user"]`
248
+ * keeps an agent's token out of a method that mints tokens. A principal
249
+ * of another kind, or without a `kind`, gets `FORBIDDEN` before `access`
250
+ * is asked, whatever its grants; an anonymous caller is left to `access`.
251
+ * Not on a `"public"` method, which a caller of any kind could call
252
+ * signed out. Leave it out for the service's list.
253
+ */
254
+ readonly kinds?: readonly PrincipalKindOf<T>[];
255
255
  /**
256
256
  * Runs the method. For a projection output it returns the database row
257
257
  * (or rows, or `null`), which the framework projects: only the
@@ -377,6 +377,18 @@ interface ServiceDefinition<T extends QuickdrawTypes, C extends AnyContract, A,
377
377
  * service (RFC 0003 section 4.1). Default `true`.
378
378
  */
379
379
  readonly adminBypass?: boolean;
380
+ /**
381
+ * The kinds of principal that may call the service's methods and
382
+ * subscribe to its live data (RFC 0003 section 4.1): `kinds: ["user"]`.
383
+ * Within the app's `initQuickdraw({ kinds })`, which the service takes
384
+ * when it leaves this out; a method's own `kinds` narrows it further. A
385
+ * principal of another kind, or without a `kind`, gets `FORBIDDEN` before
386
+ * any access form is asked, and a service-wide `Admin` grant does not
387
+ * pass it; an anonymous caller is left to the form. Its entity, collection,
388
+ * topic and stream subscriptions refuse such a principal the same way, and
389
+ * its channels drop its messages.
390
+ */
391
+ readonly kinds?: readonly PrincipalKindOf<T>[];
380
392
  }
381
393
  /** `qd.defineService`, typed by the app's `QuickdrawTypes`. */
382
394
  type DefineService<T extends QuickdrawTypes> = <C extends AnyContract, const Model extends ModelName<DbOf<T>> | undefined = undefined, Policy extends PolicyFor<DbOf<T>, Model> | undefined = undefined, const A extends MethodKeys<C> = AccessMap<T, C, RowFormsOf<Model, Policy>>, const Proj = Empty$2>(contract: C, definition: ServiceDefinition<T, C, A, Model, Policy, Proj> & CollectionsRequired<C> & ChannelsRequired<C>) => Service<T, C>;
@@ -390,6 +402,15 @@ type ContextFactory<T extends QuickdrawTypes> = (base: BaseContext<PrincipalOf<T
390
402
  interface InitOptions<T extends QuickdrawTypes> {
391
403
  /** Adds the app's fields to every handler's `ctx`. Required when the app's types declare `context`. */
392
404
  readonly context?: ContextFactory<T>;
405
+ /**
406
+ * The kinds of principal every service this instance defines admits
407
+ * (RFC 0003 section 4.1), so a new service starts closed to the rest:
408
+ * `kinds: ["user", "agent"]`. A service's `kinds`, and a method's, may
409
+ * only narrow it. A principal of another kind, or without a `kind`, gets
410
+ * `FORBIDDEN` before any access form or `Admin` grant is asked; an
411
+ * anonymous caller is left to the form. Leave it out to admit every kind.
412
+ */
413
+ readonly kinds?: readonly PrincipalKindOf<T>[];
393
414
  }
394
415
  /** `initQuickdraw`'s arguments: the options are required when `T` declares `context`. */
395
416
  type InitArgs<T extends QuickdrawTypes> = T extends {
@@ -1557,4 +1578,4 @@ declare function decryptIfEncrypted(value: string): string;
1557
1578
  /** Safe wrapper that returns `null` instead of throwing on invalid/stale ciphertext. */
1558
1579
  declare function tryDecrypt(ciphertext: string, logger?: Logger): string | null;
1559
1580
 
1560
- 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, type LegacyReply, 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, 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 };
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 };
@@ -51,6 +51,7 @@ import {
51
51
  members,
52
52
  membersWhere,
53
53
  membershipOf,
54
+ narrowKinds,
54
55
  orderByOf,
55
56
  projectRow,
56
57
  projectedOutput,
@@ -60,7 +61,7 @@ import {
60
61
  serviceGrant,
61
62
  strip,
62
63
  watchAdapterClients
63
- } from "../chunk-NS5PUHIZ.js";
64
+ } from "../chunk-RZTP4IEW.js";
64
65
  import {
65
66
  DevWarningError,
66
67
  N_PLUS_ONE_STATEMENTS,
@@ -74,7 +75,7 @@ import {
74
75
  crudSpecOf,
75
76
  sharing,
76
77
  sharingSpecOf
77
- } from "../chunk-3JNMVB2V.js";
78
+ } from "../chunk-QCHKWIRS.js";
78
79
  import "../chunk-QEKVYG5F.js";
79
80
  import {
80
81
  abortError,
@@ -83,7 +84,7 @@ import {
83
84
  kitRuntimeOf,
84
85
  outputSchemaOf,
85
86
  schemaOutputOf
86
- } from "../chunk-2XJFNVHW.js";
87
+ } from "../chunk-2PWMUVC7.js";
87
88
  import "../chunk-DD4SKCNO.js";
88
89
  import {
89
90
  recordSocketSession,
@@ -108,13 +109,13 @@ import {
108
109
  entityRoom,
109
110
  isAccessLevel,
110
111
  reservedRoomPrefix
111
- } from "../chunk-WVIRXYI4.js";
112
+ } from "../chunk-VSQBHPWH.js";
112
113
  import {
113
114
  CHANNEL_DEFAULT_RATE,
114
115
  DEFAULT_COLLECTION_LIMIT,
115
116
  DEFAULT_COLLECTION_MAX_LIMIT,
116
117
  isScopedStream
117
- } from "../chunk-5YRQ26LF.js";
118
+ } from "../chunk-RT6OILOI.js";
118
119
  import "../chunk-47AEXVDM.js";
119
120
  import "../chunk-Z2LZ7IZ7.js";
120
121
  import {
@@ -385,7 +386,7 @@ function checkChannelAccess(owner2, access, fail5) {
385
386
  }
386
387
  return Object.freeze({ service: access.service });
387
388
  }
388
- function checkChannel(service, name, def, entry, fail5) {
389
+ function checkChannel(service, name, def, entry, kinds, fail5) {
389
390
  const owner2 = `channel "${name}"`;
390
391
  const implementation = typeof entry === "function" ? { handler: entry } : entry;
391
392
  if (!isRecord2(implementation) || typeof implementation.handler !== "function") {
@@ -407,10 +408,11 @@ function checkChannel(service, name, def, entry, fail5) {
407
408
  burst: def.burst ?? Math.max(1, ratePerSecond * 2),
408
409
  requires: compileRequires(def),
409
410
  access: checkChannelAccess(owner2, implementation.access, fail5),
411
+ kinds,
410
412
  handler: implementation.handler
411
413
  });
412
414
  }
413
- function compileChannels(contract, value, fail5) {
415
+ function compileChannels(contract, value, kinds, fail5) {
414
416
  const declared = Object.entries(contract.channels);
415
417
  if (value === void 0 && declared.length === 0) {
416
418
  return /* @__PURE__ */ new Map();
@@ -423,12 +425,13 @@ function compileChannels(contract, value, fail5) {
423
425
  fail5(`channels has no implementation for ${missing2.map((name) => `"${name}"`).join(", ")}`);
424
426
  }
425
427
  const channels = /* @__PURE__ */ new Map();
428
+ const admitted = kinds === void 0 ? void 0 : new Set(kinds);
426
429
  for (const [name, entry] of Object.entries(value)) {
427
430
  const def = Object.hasOwn(contract.channels, name) ? contract.channels[name] : void 0;
428
431
  if (def === void 0) {
429
432
  fail5(`"${name}" is not a channel of the contract`);
430
433
  }
431
- channels.set(name, checkChannel(contract.name, name, def, entry, fail5));
434
+ channels.set(name, checkChannel(contract.name, name, def, entry, admitted, fail5));
432
435
  }
433
436
  return channels;
434
437
  }
@@ -615,7 +618,24 @@ function checkWatchAccess(value, fail5) {
615
618
  }
616
619
  return Object.freeze({ service: value.service });
617
620
  }
618
- function checkServiceData(definition, fail5) {
621
+ function checkAppKinds(value) {
622
+ return narrowKinds(value, void 0, (message) => {
623
+ throw new TypeError(`initQuickdraw: ${message}`);
624
+ });
625
+ }
626
+ function checkMethodKinds(owner2, entry, data, fail5) {
627
+ if (entry.kinds !== void 0 && entry.access === "public") {
628
+ fail5(
629
+ `${owner2} is "public", so kinds cannot narrow who may call it: a caller of a kind it left out would call it signed out. Leave kinds out, or give it a form that needs a principal`
630
+ );
631
+ }
632
+ return narrowKinds(
633
+ entry.kinds,
634
+ { kinds: data.kinds, by: "its service" },
635
+ (message) => fail5(`${owner2}: ${message}`)
636
+ );
637
+ }
638
+ function checkServiceData(definition, appKinds, fail5) {
619
639
  const { model, access, versionColumn } = definition;
620
640
  if (model !== void 0 && !isName(model)) {
621
641
  fail5('model must be the database model the rows live in, as the client names it ("task")');
@@ -635,7 +655,8 @@ function checkServiceData(definition, fail5) {
635
655
  writes: checkWrites(definition.writes, fail5),
636
656
  affects: Object.freeze(checkAffects(definition.affects, model, fail5)),
637
657
  versionColumn,
638
- watchAccess: checkWatchAccess(definition.watchAccess, fail5)
658
+ watchAccess: checkWatchAccess(definition.watchAccess, fail5),
659
+ kinds: narrowKinds(definition.kinds, { kinds: appKinds, by: "initQuickdraw" }, fail5)
639
660
  };
640
661
  }
641
662
  function checkWatchedModels(contract, name, models, data, fail5) {
@@ -671,7 +692,8 @@ var DEFINITION_KEYS = /* @__PURE__ */ new Set([
671
692
  "channels",
672
693
  "streams",
673
694
  "onRoomLeave",
674
- "adminBypass"
695
+ "adminBypass",
696
+ "kinds"
675
697
  ]);
676
698
  var METHOD_KEYS = /* @__PURE__ */ new Set([
677
699
  "access",
@@ -680,7 +702,8 @@ var METHOD_KEYS = /* @__PURE__ */ new Set([
680
702
  "ttlMs",
681
703
  "timeoutMs",
682
704
  "version",
683
- "rowless"
705
+ "rowless",
706
+ "kinds"
684
707
  ]);
685
708
  function isRecord4(value) {
686
709
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -727,7 +750,7 @@ function checkQueryOptions(owner2, entry, kind, fail5) {
727
750
  fail5(`${owner2}: version must be a function of (input, ctx)`);
728
751
  }
729
752
  }
730
- function checkMethod(contract, projections, name, entry, fail5) {
753
+ function checkMethod(contract, projections, data, name, entry, fail5) {
731
754
  const owner2 = `method "${name}"`;
732
755
  const def = contract.methods[name];
733
756
  if (def === void 0) {
@@ -753,6 +776,7 @@ function checkMethod(contract, projections, name, entry, fail5) {
753
776
  fail5(`${owner2}: rowless must be true, or left out`);
754
777
  }
755
778
  checkQueryOptions(owner2, entry, def.kind, fail5);
779
+ const kinds = checkMethodKinds(owner2, entry, data, fail5);
756
780
  const projection = projectedOutput(def.output, projections);
757
781
  return Object.freeze({
758
782
  name,
@@ -762,6 +786,7 @@ function checkMethod(contract, projections, name, entry, fail5) {
762
786
  projection,
763
787
  schemaOutput: projection === void 0 ? schemaOutputOf(def.output) : void 0,
764
788
  access: entry.access,
789
+ kinds,
765
790
  handler: entry.handler,
766
791
  share: entry.share,
767
792
  ttlMs: entry.ttlMs,
@@ -770,7 +795,7 @@ function checkMethod(contract, projections, name, entry, fail5) {
770
795
  rowless: entry.rowless === true
771
796
  });
772
797
  }
773
- function checkMethods(contract, projections, value, fail5) {
798
+ function checkMethods(contract, projections, data, value, fail5) {
774
799
  if (!isRecord4(value)) {
775
800
  fail5("methods must be an object with one implementation per contract method");
776
801
  }
@@ -780,7 +805,7 @@ function checkMethods(contract, projections, value, fail5) {
780
805
  }
781
806
  const methods = {};
782
807
  for (const [name, entry] of Object.entries(value)) {
783
- methods[name] = checkMethod(contract, projections, name, entry, fail5);
808
+ methods[name] = checkMethod(contract, projections, data, name, entry, fail5);
784
809
  }
785
810
  return methods;
786
811
  }
@@ -851,6 +876,23 @@ function checkHandlers(service, fail5) {
851
876
  }
852
877
  }
853
878
  }
879
+ function createRuntime(options, adopt) {
880
+ if (options === void 0) {
881
+ return Object.freeze({ extendContext: void 0, kinds: void 0, adopt });
882
+ }
883
+ if (typeof options !== "object" || options === null) {
884
+ throw new TypeError("initQuickdraw: options must be an object");
885
+ }
886
+ const { context, kinds } = options;
887
+ if (context !== void 0 && typeof context !== "function") {
888
+ throw new TypeError("initQuickdraw: context must be a function of the base context");
889
+ }
890
+ return Object.freeze({
891
+ extendContext: context,
892
+ kinds: checkAppKinds(kinds),
893
+ adopt
894
+ });
895
+ }
854
896
  function buildService(runtime, contract, definition) {
855
897
  const checked2 = checkContract(contract);
856
898
  const fail5 = (message) => {
@@ -867,7 +909,7 @@ function buildService(runtime, contract, definition) {
867
909
  if (onRoomLeave !== void 0 && typeof onRoomLeave !== "function") {
868
910
  fail5("onRoomLeave must be a function of the leave and a run context");
869
911
  }
870
- const data = checkServiceData(definition, fail5);
912
+ const data = checkServiceData(definition, runtime.kinds, fail5);
871
913
  const projections = compileProjections(checked2, definition.project, fail5);
872
914
  const collections = compileCollections(
873
915
  checked2,
@@ -877,7 +919,7 @@ function buildService(runtime, contract, definition) {
877
919
  fail5
878
920
  );
879
921
  checkWatches(checked2, collections, data, fail5);
880
- const methods = checkMethods(checked2, projections, definition.methods, fail5);
922
+ const methods = checkMethods(checked2, projections, data, definition.methods, fail5);
881
923
  checkRowForms(methods, data, fail5);
882
924
  checkRowless(methods, data, fail5);
883
925
  const service = Object.freeze({
@@ -888,7 +930,7 @@ function buildService(runtime, contract, definition) {
888
930
  collections,
889
931
  adminBypass,
890
932
  methods: Object.freeze(methods),
891
- channels: compileChannels(checked2, definition.channels, fail5),
933
+ channels: compileChannels(checked2, definition.channels, data.kinds, fail5),
892
934
  streams: compileStreams(
893
935
  checked2,
894
936
  { model: data.model, hasPolicy: data.access !== void 0 },
@@ -903,19 +945,6 @@ function buildService(runtime, contract, definition) {
903
945
  }
904
946
 
905
947
  // src/server/init.ts
906
- function contextOption(options) {
907
- if (options === void 0) {
908
- return void 0;
909
- }
910
- if (typeof options !== "object" || options === null) {
911
- throw new TypeError("initQuickdraw: options must be an object");
912
- }
913
- const { context } = options;
914
- if (context !== void 0 && typeof context !== "function") {
915
- throw new TypeError("initQuickdraw: context must be a function of the base context");
916
- }
917
- return context;
918
- }
919
948
  var NEEDS = Object.freeze({
920
949
  "qd.collections.reset": "send through",
921
950
  "qd.stream": "push through",
@@ -976,11 +1005,8 @@ function roomsOf(current) {
976
1005
  }
977
1006
  function initQuickdraw(...args) {
978
1007
  let current;
979
- const runtime = Object.freeze({
980
- extendContext: contextOption(args[0]),
981
- adopt: (dispatcher) => {
982
- current = dispatcher;
983
- }
1008
+ const runtime = createRuntime(args[0], (dispatcher) => {
1009
+ current = dispatcher;
984
1010
  });
985
1011
  const qd = {
986
1012
  defineService: ((contract, definition) => buildService(runtime, contract, definition)),