@proseql/rpc 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,819 @@
1
+ /**
2
+ * RPC Group derivation for proseql databases.
3
+ *
4
+ * Derives RPC request schemas and router from a DatabaseConfig, creating typed
5
+ * procedures for each collection. Each procedure's payload, success, and error
6
+ * schemas are derived from the collection's Effect Schema.
7
+ *
8
+ * Uses `Schema.TaggedRequest` pattern as required by @effect/rpc v0.51.x.
9
+ *
10
+ * @module
11
+ */
12
+ import { Rpc, RpcRouter } from "@effect/rpc";
13
+ import type { CollectionConfig, DatabaseConfig } from "@proseql/core";
14
+ import { Schema } from "effect";
15
+ import { DanglingReferenceErrorSchema, DuplicateKeyErrorSchema, ForeignKeyErrorSchema, HookErrorSchema, NotFoundErrorSchema, OperationErrorSchema, UniqueConstraintErrorSchema, ValidationErrorSchema } from "./rpc-errors.js";
16
+ import { AggregatePayloadSchema, CreateManyPayloadSchema, CreateManyResultSchema, CreatePayloadSchema, DeleteManyPayloadSchema, DeleteManyResultSchema, DeletePayloadSchema, QueryPayloadSchema, UpdateManyPayloadSchema, UpdateManyResultSchema, UpdatePayloadSchema, UpsertManyPayloadSchema, UpsertManyResultSchema, UpsertPayloadSchema, UpsertResultSchema } from "./rpc-schemas.js";
17
+ /**
18
+ * Creates a FindById TaggedRequest class for a collection.
19
+ *
20
+ * The returned class extends Schema.TaggedRequest and can be used to:
21
+ * 1. Create request instances: new FindByIdRequest({ id: "123" })
22
+ * 2. Define RPC handlers: Rpc.effect(FindByIdRequest, (req) => ...)
23
+ * 3. Build RPC routers: RpcRouter.make(findByIdRpc, ...)
24
+ *
25
+ * @param collectionName - The name of the collection (used as the request _tag prefix)
26
+ * @param entitySchema - The Effect Schema for the collection's entities
27
+ * @returns A TaggedRequest class for findById operations
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * const BookSchema = Schema.Struct({
32
+ * id: Schema.String,
33
+ * title: Schema.String,
34
+ * })
35
+ *
36
+ * const FindByIdRequest = makeFindByIdRequest("books", BookSchema)
37
+ * // _tag: "books.findById"
38
+ * // payload: { id: string }
39
+ * // success: Book
40
+ * // failure: NotFoundError
41
+ * ```
42
+ */
43
+ export declare function makeFindByIdRequest<CollectionName extends string, EntitySchema extends Schema.Schema.Any>(collectionName: CollectionName, entitySchema: EntitySchema): FindByIdRequestClass<CollectionName, EntitySchema>;
44
+ /**
45
+ * Type for a FindById TaggedRequest class.
46
+ * This is the class type returned by makeFindByIdRequest.
47
+ */
48
+ export type FindByIdRequestClass<CollectionName extends string, EntitySchema extends Schema.Schema.Any> = {
49
+ /**
50
+ * The request _tag (e.g., "books.findById")
51
+ */
52
+ readonly _tag: `${CollectionName}.findById`;
53
+ /**
54
+ * The success schema (entity type)
55
+ */
56
+ readonly success: EntitySchema;
57
+ /**
58
+ * The failure schema (NotFoundError)
59
+ */
60
+ readonly failure: typeof NotFoundErrorSchema;
61
+ /**
62
+ * Create a new request instance
63
+ */
64
+ new (props: {
65
+ readonly id: string;
66
+ }): Schema.TaggedRequest.Any & {
67
+ readonly _tag: `${CollectionName}.findById`;
68
+ readonly id: string;
69
+ };
70
+ };
71
+ /**
72
+ * Union schema for query errors (DanglingReferenceError | ValidationError).
73
+ */
74
+ declare const QueryErrorUnionSchema: Schema.Union<[typeof DanglingReferenceErrorSchema, typeof ValidationErrorSchema]>;
75
+ /**
76
+ * Union schema for create errors (ValidationError | DuplicateKeyError | UniqueConstraintError | ForeignKeyError | HookError).
77
+ */
78
+ declare const CreateErrorUnionSchema: Schema.Union<[typeof ValidationErrorSchema, typeof DuplicateKeyErrorSchema, typeof UniqueConstraintErrorSchema, typeof ForeignKeyErrorSchema, typeof HookErrorSchema]>;
79
+ /**
80
+ * Union schema for update errors (ValidationError | NotFoundError | UniqueConstraintError | HookError).
81
+ */
82
+ declare const UpdateErrorUnionSchema: Schema.Union<[typeof ValidationErrorSchema, typeof NotFoundErrorSchema, typeof UniqueConstraintErrorSchema, typeof HookErrorSchema]>;
83
+ /**
84
+ * Union schema for delete errors (NotFoundError | HookError).
85
+ */
86
+ declare const DeleteErrorUnionSchema: Schema.Union<[typeof NotFoundErrorSchema, typeof HookErrorSchema]>;
87
+ /**
88
+ * Union schema for createMany errors (ValidationError | DuplicateKeyError | UniqueConstraintError | ForeignKeyError | HookError).
89
+ * Same as CreateErrorUnionSchema.
90
+ */
91
+ declare const CreateManyErrorUnionSchema: Schema.Union<[typeof ValidationErrorSchema, typeof DuplicateKeyErrorSchema, typeof UniqueConstraintErrorSchema, typeof ForeignKeyErrorSchema, typeof HookErrorSchema]>;
92
+ /**
93
+ * Union schema for updateMany errors (ValidationError | ForeignKeyError | HookError | UniqueConstraintError).
94
+ */
95
+ declare const UpdateManyErrorUnionSchema: Schema.Union<[typeof ValidationErrorSchema, typeof ForeignKeyErrorSchema, typeof HookErrorSchema, typeof UniqueConstraintErrorSchema]>;
96
+ /**
97
+ * Union schema for deleteMany errors (OperationError | ForeignKeyError | HookError).
98
+ */
99
+ declare const DeleteManyErrorUnionSchema: Schema.Union<[typeof OperationErrorSchema, typeof ForeignKeyErrorSchema, typeof HookErrorSchema]>;
100
+ /**
101
+ * Union schema for upsert errors (ValidationError | ForeignKeyError | HookError | UniqueConstraintError).
102
+ */
103
+ declare const UpsertErrorUnionSchema: Schema.Union<[typeof ValidationErrorSchema, typeof ForeignKeyErrorSchema, typeof HookErrorSchema, typeof UniqueConstraintErrorSchema]>;
104
+ /**
105
+ * Union schema for upsertMany errors (ValidationError | ForeignKeyError | HookError | UniqueConstraintError).
106
+ * Same as UpsertErrorUnionSchema.
107
+ */
108
+ declare const UpsertManyErrorUnionSchema: Schema.Union<[typeof ValidationErrorSchema, typeof ForeignKeyErrorSchema, typeof HookErrorSchema, typeof UniqueConstraintErrorSchema]>;
109
+ /**
110
+ * Creates a Query TaggedRequest class for a collection.
111
+ *
112
+ * The returned class extends Schema.TaggedRequest and can be used to:
113
+ * 1. Create request instances: new QueryRequest({ where: { ... } })
114
+ * 2. Define RPC handlers: Rpc.effect(QueryRequest, (req) => ...)
115
+ * 3. Build RPC routers: RpcRouter.make(queryRpc, ...)
116
+ *
117
+ * @param collectionName - The name of the collection (used as the request _tag prefix)
118
+ * @param entitySchema - The Effect Schema for the collection's entities
119
+ * @returns A TaggedRequest class for query operations
120
+ *
121
+ * @example
122
+ * ```ts
123
+ * const BookSchema = Schema.Struct({
124
+ * id: Schema.String,
125
+ * title: Schema.String,
126
+ * })
127
+ *
128
+ * const QueryRequest = makeQueryRequest("books", BookSchema)
129
+ * // _tag: "books.query"
130
+ * // payload: QueryPayload
131
+ * // success: ReadonlyArray<Book>
132
+ * // failure: DanglingReferenceError | ValidationError
133
+ * ```
134
+ */
135
+ export declare function makeQueryRequest<CollectionName extends string, EntitySchema extends Schema.Schema.Any>(collectionName: CollectionName, entitySchema: EntitySchema): QueryRequestClass<CollectionName, EntitySchema>;
136
+ /**
137
+ * Type for a Query TaggedRequest class.
138
+ * This is the class type returned by makeQueryRequest.
139
+ */
140
+ export type QueryRequestClass<CollectionName extends string, EntitySchema extends Schema.Schema.Any> = {
141
+ /**
142
+ * The request _tag (e.g., "books.query")
143
+ */
144
+ readonly _tag: `${CollectionName}.query`;
145
+ /**
146
+ * The success schema (array of entity type)
147
+ */
148
+ readonly success: Schema.Array$<EntitySchema>;
149
+ /**
150
+ * The failure schema (DanglingReferenceError | ValidationError)
151
+ */
152
+ readonly failure: typeof QueryErrorUnionSchema;
153
+ /**
154
+ * Create a new request instance
155
+ */
156
+ new (props: {
157
+ readonly where?: typeof QueryPayloadSchema.Type.where;
158
+ readonly sort?: typeof QueryPayloadSchema.Type.sort;
159
+ readonly select?: typeof QueryPayloadSchema.Type.select;
160
+ readonly populate?: typeof QueryPayloadSchema.Type.populate;
161
+ readonly limit?: typeof QueryPayloadSchema.Type.limit;
162
+ readonly offset?: typeof QueryPayloadSchema.Type.offset;
163
+ readonly cursor?: typeof QueryPayloadSchema.Type.cursor;
164
+ }): Schema.TaggedRequest.Any & {
165
+ readonly _tag: `${CollectionName}.query`;
166
+ readonly where?: typeof QueryPayloadSchema.Type.where;
167
+ readonly sort?: typeof QueryPayloadSchema.Type.sort;
168
+ readonly select?: typeof QueryPayloadSchema.Type.select;
169
+ readonly populate?: typeof QueryPayloadSchema.Type.populate;
170
+ readonly limit?: typeof QueryPayloadSchema.Type.limit;
171
+ readonly offset?: typeof QueryPayloadSchema.Type.offset;
172
+ readonly cursor?: typeof QueryPayloadSchema.Type.cursor;
173
+ };
174
+ };
175
+ /**
176
+ * Creates a streaming Query TaggedRequest class for a collection.
177
+ *
178
+ * Unlike makeQueryRequest which returns an array-collecting RPC,
179
+ * this creates an RPC that streams results incrementally, allowing
180
+ * large result sets to flow through the transport without buffering.
181
+ *
182
+ * Uses `Rpc.StreamRequest` which marks the request for streaming handling.
183
+ * Handlers must return a `Stream<Entity, Error>` instead of `Effect<Array<Entity>, Error>`.
184
+ *
185
+ * @param collectionName - The name of the collection (used as the request _tag prefix)
186
+ * @param entitySchema - The Effect Schema for the collection's entities
187
+ * @returns A StreamRequest class for streaming query operations
188
+ *
189
+ * @example
190
+ * ```ts
191
+ * const BookSchema = Schema.Struct({
192
+ * id: Schema.String,
193
+ * title: Schema.String,
194
+ * })
195
+ *
196
+ * const QueryStreamRequest = makeQueryStreamRequest("books", BookSchema)
197
+ * // _tag: "books.queryStream"
198
+ * // payload: QueryPayload
199
+ * // success: Stream<Book, DanglingReferenceError | ValidationError>
200
+ *
201
+ * // Use with Rpc.stream to create a handler
202
+ * const handler = Rpc.stream(QueryStreamRequest, (req) =>
203
+ * db.books.query({ where: req.where, sort: req.sort })
204
+ * )
205
+ * ```
206
+ */
207
+ export declare function makeQueryStreamRequest<CollectionName extends string, EntitySchema extends Schema.Schema.Any>(collectionName: CollectionName, entitySchema: EntitySchema): QueryStreamRequestClass<CollectionName, EntitySchema>;
208
+ /**
209
+ * Instance type for a QueryStream request.
210
+ */
211
+ interface QueryStreamRequestInstance<CollectionName extends string, EntitySchema extends Schema.Schema.Any> extends Rpc.StreamRequest<`${CollectionName}.queryStream`, never, {
212
+ readonly _tag: `${CollectionName}.queryStream`;
213
+ readonly where?: typeof QueryPayloadSchema.Type.where;
214
+ readonly sort?: typeof QueryPayloadSchema.Type.sort;
215
+ readonly select?: typeof QueryPayloadSchema.Type.select;
216
+ readonly populate?: typeof QueryPayloadSchema.Type.populate;
217
+ readonly limit?: typeof QueryPayloadSchema.Type.limit;
218
+ readonly offset?: typeof QueryPayloadSchema.Type.offset;
219
+ readonly cursor?: typeof QueryPayloadSchema.Type.cursor;
220
+ readonly streamingOptions?: typeof QueryPayloadSchema.Type.streamingOptions;
221
+ }, QueryStreamRequestInstance<CollectionName, EntitySchema>, never, Schema.Schema.Encoded<typeof QueryErrorUnionSchema>, Schema.Schema.Type<typeof QueryErrorUnionSchema>, Schema.Schema.Encoded<EntitySchema>, Schema.Schema.Type<EntitySchema>> {
222
+ readonly _tag: `${CollectionName}.queryStream`;
223
+ readonly where?: typeof QueryPayloadSchema.Type.where;
224
+ readonly sort?: typeof QueryPayloadSchema.Type.sort;
225
+ readonly select?: typeof QueryPayloadSchema.Type.select;
226
+ readonly populate?: typeof QueryPayloadSchema.Type.populate;
227
+ readonly limit?: typeof QueryPayloadSchema.Type.limit;
228
+ readonly offset?: typeof QueryPayloadSchema.Type.offset;
229
+ readonly cursor?: typeof QueryPayloadSchema.Type.cursor;
230
+ readonly streamingOptions?: typeof QueryPayloadSchema.Type.streamingOptions;
231
+ }
232
+ /**
233
+ * Type for a streaming Query TaggedRequest class.
234
+ * This is the class type returned by makeQueryStreamRequest.
235
+ */
236
+ export type QueryStreamRequestClass<CollectionName extends string, EntitySchema extends Schema.Schema.Any> = Rpc.StreamRequestConstructor<`${CollectionName}.queryStream`, QueryStreamRequestInstance<CollectionName, EntitySchema>, never, {
237
+ readonly where?: typeof QueryPayloadSchema.Encoded.where;
238
+ readonly sort?: typeof QueryPayloadSchema.Encoded.sort;
239
+ readonly select?: typeof QueryPayloadSchema.Encoded.select;
240
+ readonly populate?: typeof QueryPayloadSchema.Encoded.populate;
241
+ readonly limit?: typeof QueryPayloadSchema.Encoded.limit;
242
+ readonly offset?: typeof QueryPayloadSchema.Encoded.offset;
243
+ readonly cursor?: typeof QueryPayloadSchema.Encoded.cursor;
244
+ readonly streamingOptions?: typeof QueryPayloadSchema.Encoded.streamingOptions;
245
+ }, {
246
+ readonly where?: typeof QueryPayloadSchema.Type.where;
247
+ readonly sort?: typeof QueryPayloadSchema.Type.sort;
248
+ readonly select?: typeof QueryPayloadSchema.Type.select;
249
+ readonly populate?: typeof QueryPayloadSchema.Type.populate;
250
+ readonly limit?: typeof QueryPayloadSchema.Type.limit;
251
+ readonly offset?: typeof QueryPayloadSchema.Type.offset;
252
+ readonly cursor?: typeof QueryPayloadSchema.Type.cursor;
253
+ readonly streamingOptions?: typeof QueryPayloadSchema.Type.streamingOptions;
254
+ }, never, Schema.Schema.Encoded<typeof QueryErrorUnionSchema>, Schema.Schema.Type<typeof QueryErrorUnionSchema>, Schema.Schema.Encoded<EntitySchema>, Schema.Schema.Type<EntitySchema>>;
255
+ /**
256
+ * Creates a Create TaggedRequest class for a collection.
257
+ *
258
+ * The returned class extends Schema.TaggedRequest and can be used to:
259
+ * 1. Create request instances: new CreateRequest({ data: { ... } })
260
+ * 2. Define RPC handlers: Rpc.effect(CreateRequest, (req) => ...)
261
+ * 3. Build RPC routers: RpcRouter.make(createRpc, ...)
262
+ *
263
+ * @param collectionName - The name of the collection (used as the request _tag prefix)
264
+ * @param entitySchema - The Effect Schema for the collection's entities
265
+ * @returns A TaggedRequest class for create operations
266
+ *
267
+ * @example
268
+ * ```ts
269
+ * const BookSchema = Schema.Struct({
270
+ * id: Schema.String,
271
+ * title: Schema.String,
272
+ * })
273
+ *
274
+ * const CreateRequest = makeCreateRequest("books", BookSchema)
275
+ * // _tag: "books.create"
276
+ * // payload: { data: Record<string, unknown> }
277
+ * // success: Book
278
+ * // failure: ValidationError | DuplicateKeyError | UniqueConstraintError | ForeignKeyError | HookError
279
+ * ```
280
+ */
281
+ export declare function makeCreateRequest<CollectionName extends string, EntitySchema extends Schema.Schema.Any>(collectionName: CollectionName, entitySchema: EntitySchema): CreateRequestClass<CollectionName, EntitySchema>;
282
+ /**
283
+ * Type for a Create TaggedRequest class.
284
+ * This is the class type returned by makeCreateRequest.
285
+ */
286
+ export type CreateRequestClass<CollectionName extends string, EntitySchema extends Schema.Schema.Any> = {
287
+ /**
288
+ * The request _tag (e.g., "books.create")
289
+ */
290
+ readonly _tag: `${CollectionName}.create`;
291
+ /**
292
+ * The success schema (entity type)
293
+ */
294
+ readonly success: EntitySchema;
295
+ /**
296
+ * The failure schema (ValidationError | DuplicateKeyError | UniqueConstraintError | ForeignKeyError | HookError)
297
+ */
298
+ readonly failure: typeof CreateErrorUnionSchema;
299
+ /**
300
+ * Create a new request instance
301
+ */
302
+ new (props: {
303
+ readonly data: typeof CreatePayloadSchema.Type.data;
304
+ }): Schema.TaggedRequest.Any & {
305
+ readonly _tag: `${CollectionName}.create`;
306
+ readonly data: typeof CreatePayloadSchema.Type.data;
307
+ };
308
+ };
309
+ /**
310
+ * Creates an Update TaggedRequest class for a collection.
311
+ *
312
+ * The returned class extends Schema.TaggedRequest and can be used to:
313
+ * 1. Create request instances: new UpdateRequest({ id: "123", updates: { ... } })
314
+ * 2. Define RPC handlers: Rpc.effect(UpdateRequest, (req) => ...)
315
+ * 3. Build RPC routers: RpcRouter.make(updateRpc, ...)
316
+ *
317
+ * @param collectionName - The name of the collection (used as the request _tag prefix)
318
+ * @param entitySchema - The Effect Schema for the collection's entities
319
+ * @returns A TaggedRequest class for update operations
320
+ *
321
+ * @example
322
+ * ```ts
323
+ * const BookSchema = Schema.Struct({
324
+ * id: Schema.String,
325
+ * title: Schema.String,
326
+ * })
327
+ *
328
+ * const UpdateRequest = makeUpdateRequest("books", BookSchema)
329
+ * // _tag: "books.update"
330
+ * // payload: { id: string, updates: Record<string, unknown> }
331
+ * // success: Book
332
+ * // failure: ValidationError | NotFoundError | UniqueConstraintError | HookError
333
+ * ```
334
+ */
335
+ export declare function makeUpdateRequest<CollectionName extends string, EntitySchema extends Schema.Schema.Any>(collectionName: CollectionName, entitySchema: EntitySchema): UpdateRequestClass<CollectionName, EntitySchema>;
336
+ /**
337
+ * Type for an Update TaggedRequest class.
338
+ * This is the class type returned by makeUpdateRequest.
339
+ */
340
+ export type UpdateRequestClass<CollectionName extends string, EntitySchema extends Schema.Schema.Any> = {
341
+ /**
342
+ * The request _tag (e.g., "books.update")
343
+ */
344
+ readonly _tag: `${CollectionName}.update`;
345
+ /**
346
+ * The success schema (entity type)
347
+ */
348
+ readonly success: EntitySchema;
349
+ /**
350
+ * The failure schema (ValidationError | NotFoundError | UniqueConstraintError | HookError)
351
+ */
352
+ readonly failure: typeof UpdateErrorUnionSchema;
353
+ /**
354
+ * Create a new request instance
355
+ */
356
+ new (props: {
357
+ readonly id: typeof UpdatePayloadSchema.Type.id;
358
+ readonly updates: typeof UpdatePayloadSchema.Type.updates;
359
+ }): Schema.TaggedRequest.Any & {
360
+ readonly _tag: `${CollectionName}.update`;
361
+ readonly id: typeof UpdatePayloadSchema.Type.id;
362
+ readonly updates: typeof UpdatePayloadSchema.Type.updates;
363
+ };
364
+ };
365
+ /**
366
+ * Creates a Delete TaggedRequest class for a collection.
367
+ *
368
+ * The returned class extends Schema.TaggedRequest and can be used to:
369
+ * 1. Create request instances: new DeleteRequest({ id: "123" })
370
+ * 2. Define RPC handlers: Rpc.effect(DeleteRequest, (req) => ...)
371
+ * 3. Build RPC routers: RpcRouter.make(deleteRpc, ...)
372
+ *
373
+ * @param collectionName - The name of the collection (used as the request _tag prefix)
374
+ * @param entitySchema - The Effect Schema for the collection's entities
375
+ * @returns A TaggedRequest class for delete operations
376
+ *
377
+ * @example
378
+ * ```ts
379
+ * const BookSchema = Schema.Struct({
380
+ * id: Schema.String,
381
+ * title: Schema.String,
382
+ * })
383
+ *
384
+ * const DeleteRequest = makeDeleteRequest("books", BookSchema)
385
+ * // _tag: "books.delete"
386
+ * // payload: { id: string }
387
+ * // success: Book
388
+ * // failure: NotFoundError | HookError
389
+ * ```
390
+ */
391
+ export declare function makeDeleteRequest<CollectionName extends string, EntitySchema extends Schema.Schema.Any>(collectionName: CollectionName, entitySchema: EntitySchema): DeleteRequestClass<CollectionName, EntitySchema>;
392
+ /**
393
+ * Type for a Delete TaggedRequest class.
394
+ * This is the class type returned by makeDeleteRequest.
395
+ */
396
+ export type DeleteRequestClass<CollectionName extends string, EntitySchema extends Schema.Schema.Any> = {
397
+ /**
398
+ * The request _tag (e.g., "books.delete")
399
+ */
400
+ readonly _tag: `${CollectionName}.delete`;
401
+ /**
402
+ * The success schema (entity type)
403
+ */
404
+ readonly success: EntitySchema;
405
+ /**
406
+ * The failure schema (NotFoundError | HookError)
407
+ */
408
+ readonly failure: typeof DeleteErrorUnionSchema;
409
+ /**
410
+ * Create a new request instance
411
+ */
412
+ new (props: {
413
+ readonly id: typeof DeletePayloadSchema.Type.id;
414
+ }): Schema.TaggedRequest.Any & {
415
+ readonly _tag: `${CollectionName}.delete`;
416
+ readonly id: typeof DeletePayloadSchema.Type.id;
417
+ };
418
+ };
419
+ /**
420
+ * Union schema for aggregate results (AggregateResult | GroupedAggregateResult).
421
+ * The aggregate operation never fails, so we use Schema.Never for failure.
422
+ */
423
+ declare const AggregateResultUnionSchema: Schema.Union<[Schema.Struct<{
424
+ count: Schema.optional<typeof Schema.Number>;
425
+ sum: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Number>>;
426
+ avg: Schema.optional<Schema.Record$<typeof Schema.String, Schema.NullOr<typeof Schema.Number>>>;
427
+ min: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
428
+ max: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
429
+ }>, Schema.Array$<Schema.Struct<{
430
+ group: Schema.Record$<typeof Schema.String, typeof Schema.Unknown>;
431
+ count: Schema.optional<typeof Schema.Number>;
432
+ sum: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Number>>;
433
+ avg: Schema.optional<Schema.Record$<typeof Schema.String, Schema.NullOr<typeof Schema.Number>>>;
434
+ min: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
435
+ max: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
436
+ }>>]>;
437
+ /**
438
+ * Creates an Aggregate TaggedRequest class for a collection.
439
+ *
440
+ * The returned class extends Schema.TaggedRequest and can be used to:
441
+ * 1. Create request instances: new AggregateRequest({ count: true })
442
+ * 2. Define RPC handlers: Rpc.effect(AggregateRequest, (req) => ...)
443
+ * 3. Build RPC routers: RpcRouter.make(aggregateRpc, ...)
444
+ *
445
+ * @param collectionName - The name of the collection (used as the request _tag prefix)
446
+ * @returns A TaggedRequest class for aggregate operations
447
+ *
448
+ * @example
449
+ * ```ts
450
+ * const AggregateRequest = makeAggregateRequest("books")
451
+ * // _tag: "books.aggregate"
452
+ * // payload: AggregateConfig
453
+ * // success: AggregateResult | GroupedAggregateResult
454
+ * // failure: never (aggregate operations cannot fail)
455
+ * ```
456
+ */
457
+ export declare function makeAggregateRequest<CollectionName extends string>(collectionName: CollectionName): AggregateRequestClass<CollectionName>;
458
+ /**
459
+ * Type for an Aggregate TaggedRequest class.
460
+ * This is the class type returned by makeAggregateRequest.
461
+ */
462
+ export type AggregateRequestClass<CollectionName extends string> = {
463
+ /**
464
+ * The request _tag (e.g., "books.aggregate")
465
+ */
466
+ readonly _tag: `${CollectionName}.aggregate`;
467
+ /**
468
+ * The success schema (AggregateResult | GroupedAggregateResult)
469
+ */
470
+ readonly success: typeof AggregateResultUnionSchema;
471
+ /**
472
+ * The failure schema (never - aggregate operations cannot fail)
473
+ */
474
+ readonly failure: typeof Schema.Never;
475
+ /**
476
+ * Create a new request instance
477
+ */
478
+ new (props: {
479
+ readonly where?: typeof AggregatePayloadSchema.Type.where;
480
+ readonly groupBy?: typeof AggregatePayloadSchema.Type.groupBy;
481
+ readonly count?: typeof AggregatePayloadSchema.Type.count;
482
+ readonly sum?: typeof AggregatePayloadSchema.Type.sum;
483
+ readonly avg?: typeof AggregatePayloadSchema.Type.avg;
484
+ readonly min?: typeof AggregatePayloadSchema.Type.min;
485
+ readonly max?: typeof AggregatePayloadSchema.Type.max;
486
+ }): Schema.TaggedRequest.Any & {
487
+ readonly _tag: `${CollectionName}.aggregate`;
488
+ readonly where?: typeof AggregatePayloadSchema.Type.where;
489
+ readonly groupBy?: typeof AggregatePayloadSchema.Type.groupBy;
490
+ readonly count?: typeof AggregatePayloadSchema.Type.count;
491
+ readonly sum?: typeof AggregatePayloadSchema.Type.sum;
492
+ readonly avg?: typeof AggregatePayloadSchema.Type.avg;
493
+ readonly min?: typeof AggregatePayloadSchema.Type.min;
494
+ readonly max?: typeof AggregatePayloadSchema.Type.max;
495
+ };
496
+ };
497
+ /**
498
+ * Creates a CreateMany TaggedRequest class for a collection.
499
+ *
500
+ * @param collectionName - The name of the collection (used as the request _tag prefix)
501
+ * @returns A TaggedRequest class for createMany operations
502
+ *
503
+ * @example
504
+ * ```ts
505
+ * const CreateManyRequest = makeCreateManyRequest("books")
506
+ * // _tag: "books.createMany"
507
+ * // payload: { data: Array<Record<string, unknown>>, options?: { skipDuplicates?: boolean } }
508
+ * // success: CreateManyResult
509
+ * // failure: ValidationError | DuplicateKeyError | UniqueConstraintError | ForeignKeyError | HookError
510
+ * ```
511
+ */
512
+ export declare function makeCreateManyRequest<CollectionName extends string>(collectionName: CollectionName): CreateManyRequestClass<CollectionName>;
513
+ /**
514
+ * Type for a CreateMany TaggedRequest class.
515
+ */
516
+ export type CreateManyRequestClass<CollectionName extends string> = {
517
+ readonly _tag: `${CollectionName}.createMany`;
518
+ readonly success: typeof CreateManyResultSchema;
519
+ readonly failure: typeof CreateManyErrorUnionSchema;
520
+ new (props: {
521
+ readonly data: typeof CreateManyPayloadSchema.Type.data;
522
+ readonly options?: typeof CreateManyPayloadSchema.Type.options;
523
+ }): Schema.TaggedRequest.Any & {
524
+ readonly _tag: `${CollectionName}.createMany`;
525
+ readonly data: typeof CreateManyPayloadSchema.Type.data;
526
+ readonly options?: typeof CreateManyPayloadSchema.Type.options;
527
+ };
528
+ };
529
+ /**
530
+ * Creates an UpdateMany TaggedRequest class for a collection.
531
+ *
532
+ * @param collectionName - The name of the collection (used as the request _tag prefix)
533
+ * @returns A TaggedRequest class for updateMany operations
534
+ *
535
+ * @example
536
+ * ```ts
537
+ * const UpdateManyRequest = makeUpdateManyRequest("books")
538
+ * // _tag: "books.updateMany"
539
+ * // payload: { where: Record<string, unknown>, updates: Record<string, unknown> }
540
+ * // success: UpdateManyResult
541
+ * // failure: ValidationError | ForeignKeyError | HookError | UniqueConstraintError
542
+ * ```
543
+ */
544
+ export declare function makeUpdateManyRequest<CollectionName extends string>(collectionName: CollectionName): UpdateManyRequestClass<CollectionName>;
545
+ /**
546
+ * Type for an UpdateMany TaggedRequest class.
547
+ */
548
+ export type UpdateManyRequestClass<CollectionName extends string> = {
549
+ readonly _tag: `${CollectionName}.updateMany`;
550
+ readonly success: typeof UpdateManyResultSchema;
551
+ readonly failure: typeof UpdateManyErrorUnionSchema;
552
+ new (props: {
553
+ readonly where: typeof UpdateManyPayloadSchema.Type.where;
554
+ readonly updates: typeof UpdateManyPayloadSchema.Type.updates;
555
+ }): Schema.TaggedRequest.Any & {
556
+ readonly _tag: `${CollectionName}.updateMany`;
557
+ readonly where: typeof UpdateManyPayloadSchema.Type.where;
558
+ readonly updates: typeof UpdateManyPayloadSchema.Type.updates;
559
+ };
560
+ };
561
+ /**
562
+ * Creates a DeleteMany TaggedRequest class for a collection.
563
+ *
564
+ * @param collectionName - The name of the collection (used as the request _tag prefix)
565
+ * @returns A TaggedRequest class for deleteMany operations
566
+ *
567
+ * @example
568
+ * ```ts
569
+ * const DeleteManyRequest = makeDeleteManyRequest("books")
570
+ * // _tag: "books.deleteMany"
571
+ * // payload: { where: Record<string, unknown>, options?: { limit?: number } }
572
+ * // success: DeleteManyResult
573
+ * // failure: OperationError | ForeignKeyError | HookError
574
+ * ```
575
+ */
576
+ export declare function makeDeleteManyRequest<CollectionName extends string>(collectionName: CollectionName): DeleteManyRequestClass<CollectionName>;
577
+ /**
578
+ * Type for a DeleteMany TaggedRequest class.
579
+ */
580
+ export type DeleteManyRequestClass<CollectionName extends string> = {
581
+ readonly _tag: `${CollectionName}.deleteMany`;
582
+ readonly success: typeof DeleteManyResultSchema;
583
+ readonly failure: typeof DeleteManyErrorUnionSchema;
584
+ new (props: {
585
+ readonly where: typeof DeleteManyPayloadSchema.Type.where;
586
+ readonly options?: typeof DeleteManyPayloadSchema.Type.options;
587
+ }): Schema.TaggedRequest.Any & {
588
+ readonly _tag: `${CollectionName}.deleteMany`;
589
+ readonly where: typeof DeleteManyPayloadSchema.Type.where;
590
+ readonly options?: typeof DeleteManyPayloadSchema.Type.options;
591
+ };
592
+ };
593
+ /**
594
+ * Creates an Upsert TaggedRequest class for a collection.
595
+ *
596
+ * @param collectionName - The name of the collection (used as the request _tag prefix)
597
+ * @returns A TaggedRequest class for upsert operations
598
+ *
599
+ * @example
600
+ * ```ts
601
+ * const UpsertRequest = makeUpsertRequest("books")
602
+ * // _tag: "books.upsert"
603
+ * // payload: { where: Record<string, unknown>, create: Record<string, unknown>, update: Record<string, unknown> }
604
+ * // success: UpsertResult
605
+ * // failure: ValidationError | ForeignKeyError | HookError | UniqueConstraintError
606
+ * ```
607
+ */
608
+ export declare function makeUpsertRequest<CollectionName extends string>(collectionName: CollectionName): UpsertRequestClass<CollectionName>;
609
+ /**
610
+ * Type for an Upsert TaggedRequest class.
611
+ */
612
+ export type UpsertRequestClass<CollectionName extends string> = {
613
+ readonly _tag: `${CollectionName}.upsert`;
614
+ readonly success: typeof UpsertResultSchema;
615
+ readonly failure: typeof UpsertErrorUnionSchema;
616
+ new (props: {
617
+ readonly where: typeof UpsertPayloadSchema.Type.where;
618
+ readonly create: typeof UpsertPayloadSchema.Type.create;
619
+ readonly update: typeof UpsertPayloadSchema.Type.update;
620
+ }): Schema.TaggedRequest.Any & {
621
+ readonly _tag: `${CollectionName}.upsert`;
622
+ readonly where: typeof UpsertPayloadSchema.Type.where;
623
+ readonly create: typeof UpsertPayloadSchema.Type.create;
624
+ readonly update: typeof UpsertPayloadSchema.Type.update;
625
+ };
626
+ };
627
+ /**
628
+ * Creates an UpsertMany TaggedRequest class for a collection.
629
+ *
630
+ * @param collectionName - The name of the collection (used as the request _tag prefix)
631
+ * @returns A TaggedRequest class for upsertMany operations
632
+ *
633
+ * @example
634
+ * ```ts
635
+ * const UpsertManyRequest = makeUpsertManyRequest("books")
636
+ * // _tag: "books.upsertMany"
637
+ * // payload: { data: Array<{ where, create, update }> }
638
+ * // success: UpsertManyResult
639
+ * // failure: ValidationError | ForeignKeyError | HookError | UniqueConstraintError
640
+ * ```
641
+ */
642
+ export declare function makeUpsertManyRequest<CollectionName extends string>(collectionName: CollectionName): UpsertManyRequestClass<CollectionName>;
643
+ /**
644
+ * Type for an UpsertMany TaggedRequest class.
645
+ */
646
+ export type UpsertManyRequestClass<CollectionName extends string> = {
647
+ readonly _tag: `${CollectionName}.upsertMany`;
648
+ readonly success: typeof UpsertManyResultSchema;
649
+ readonly failure: typeof UpsertManyErrorUnionSchema;
650
+ new (props: {
651
+ readonly data: typeof UpsertManyPayloadSchema.Type.data;
652
+ }): Schema.TaggedRequest.Any & {
653
+ readonly _tag: `${CollectionName}.upsertMany`;
654
+ readonly data: typeof UpsertManyPayloadSchema.Type.data;
655
+ };
656
+ };
657
+ /**
658
+ * Type for collection RPC definitions.
659
+ * Contains the request schemas for all RPC operations on a collection.
660
+ */
661
+ export interface CollectionRpcDefinitions<CollectionName extends string, EntitySchema extends Schema.Schema.Any> {
662
+ /**
663
+ * TaggedRequest class for findById operations.
664
+ * Use with Rpc.effect() to create an RPC handler.
665
+ */
666
+ readonly FindByIdRequest: FindByIdRequestClass<CollectionName, EntitySchema>;
667
+ /**
668
+ * TaggedRequest class for query operations.
669
+ * Use with Rpc.effect() to create an RPC handler.
670
+ */
671
+ readonly QueryRequest: QueryRequestClass<CollectionName, EntitySchema>;
672
+ /**
673
+ * StreamRequest class for streaming query operations.
674
+ * Unlike QueryRequest which collects all results, this streams results incrementally.
675
+ * Use with Rpc.stream() to create a handler that returns a Stream.
676
+ */
677
+ readonly QueryStreamRequest: QueryStreamRequestClass<CollectionName, EntitySchema>;
678
+ /**
679
+ * TaggedRequest class for create operations.
680
+ * Use with Rpc.effect() to create an RPC handler.
681
+ */
682
+ readonly CreateRequest: CreateRequestClass<CollectionName, EntitySchema>;
683
+ /**
684
+ * TaggedRequest class for update operations.
685
+ * Use with Rpc.effect() to create an RPC handler.
686
+ */
687
+ readonly UpdateRequest: UpdateRequestClass<CollectionName, EntitySchema>;
688
+ /**
689
+ * TaggedRequest class for delete operations.
690
+ * Use with Rpc.effect() to create an RPC handler.
691
+ */
692
+ readonly DeleteRequest: DeleteRequestClass<CollectionName, EntitySchema>;
693
+ /**
694
+ * TaggedRequest class for aggregate operations.
695
+ * Use with Rpc.effect() to create an RPC handler.
696
+ */
697
+ readonly AggregateRequest: AggregateRequestClass<CollectionName>;
698
+ /**
699
+ * TaggedRequest class for createMany operations.
700
+ * Use with Rpc.effect() to create an RPC handler.
701
+ */
702
+ readonly CreateManyRequest: CreateManyRequestClass<CollectionName>;
703
+ /**
704
+ * TaggedRequest class for updateMany operations.
705
+ * Use with Rpc.effect() to create an RPC handler.
706
+ */
707
+ readonly UpdateManyRequest: UpdateManyRequestClass<CollectionName>;
708
+ /**
709
+ * TaggedRequest class for deleteMany operations.
710
+ * Use with Rpc.effect() to create an RPC handler.
711
+ */
712
+ readonly DeleteManyRequest: DeleteManyRequestClass<CollectionName>;
713
+ /**
714
+ * TaggedRequest class for upsert operations.
715
+ * Use with Rpc.effect() to create an RPC handler.
716
+ */
717
+ readonly UpsertRequest: UpsertRequestClass<CollectionName>;
718
+ /**
719
+ * TaggedRequest class for upsertMany operations.
720
+ * Use with Rpc.effect() to create an RPC handler.
721
+ */
722
+ readonly UpsertManyRequest: UpsertManyRequestClass<CollectionName>;
723
+ /** The collection name */
724
+ readonly collectionName: CollectionName;
725
+ /** The entity schema for this collection */
726
+ readonly entitySchema: EntitySchema;
727
+ }
728
+ /**
729
+ * Creates RPC definitions for a collection.
730
+ *
731
+ * Returns an object containing the request schemas that can be used to
732
+ * create RPC handlers and add them to an RpcRouter.
733
+ *
734
+ * @param collectionName - The name of the collection
735
+ * @param entitySchema - The Effect Schema for the collection's entities
736
+ * @returns Object with request schemas
737
+ */
738
+ export declare function makeCollectionRpcs<CollectionName extends string, EntitySchema extends Schema.Schema.Any>(collectionName: CollectionName, entitySchema: EntitySchema): CollectionRpcDefinitions<CollectionName, EntitySchema>;
739
+ /**
740
+ * Creates a mapping of collection RPC definitions from a DatabaseConfig.
741
+ *
742
+ * This is the primary entry point for deriving RPC schemas from a database config.
743
+ * Each collection gets typed request schemas for:
744
+ * - findById: Find entity by ID
745
+ * - query: Query entities with filtering, sorting, pagination (collected array result)
746
+ * - queryStream: Query entities with streaming results (incremental delivery)
747
+ * - create: Create a new entity
748
+ * - update: Update an existing entity by ID
749
+ * - delete: Delete an entity by ID
750
+ * - aggregate: Compute aggregates (count, sum, avg, min, max) with optional groupBy
751
+ * - createMany: Create multiple entities in batch
752
+ * - updateMany: Update multiple entities matching a predicate
753
+ * - deleteMany: Delete multiple entities matching a predicate
754
+ * - upsert: Create or update an entity based on a where clause
755
+ * - upsertMany: Create or update multiple entities in batch
756
+ *
757
+ * @param config - The database configuration
758
+ * @returns A mapping of collection names to their RPC definitions
759
+ *
760
+ * @example
761
+ * ```ts
762
+ * import { makeRpcGroup } from "@proseql/rpc"
763
+ * import { Rpc, RpcRouter } from "@effect/rpc"
764
+ *
765
+ * const config = {
766
+ * books: { schema: BookSchema, relationships: {} },
767
+ * authors: { schema: AuthorSchema, relationships: {} },
768
+ * } as const
769
+ *
770
+ * const rpcs = makeRpcGroup(config)
771
+ *
772
+ * // Create handlers using the request schemas
773
+ * const findBookById = Rpc.effect(rpcs.books.FindByIdRequest, (req) =>
774
+ * db.books.findById(req.id)
775
+ * )
776
+ *
777
+ * const queryBooks = Rpc.effect(rpcs.books.QueryRequest, (req) =>
778
+ * db.books.query({ where: req.where, sort: req.sort }).runPromise
779
+ * )
780
+ *
781
+ * const createBook = Rpc.effect(rpcs.books.CreateRequest, (req) =>
782
+ * db.books.create(req.data)
783
+ * )
784
+ *
785
+ * const updateBook = Rpc.effect(rpcs.books.UpdateRequest, (req) =>
786
+ * db.books.update(req.id, req.updates)
787
+ * )
788
+ *
789
+ * const deleteBook = Rpc.effect(rpcs.books.DeleteRequest, (req) =>
790
+ * db.books.delete(req.id)
791
+ * )
792
+ *
793
+ * const aggregateBooks = Rpc.effect(rpcs.books.AggregateRequest, (req) =>
794
+ * db.books.aggregate({ count: req.count, groupBy: req.groupBy, ...req })
795
+ * )
796
+ *
797
+ * const createManyBooks = Rpc.effect(rpcs.books.CreateManyRequest, (req) =>
798
+ * db.books.createMany(req.data, req.options)
799
+ * )
800
+ *
801
+ * // Build a router
802
+ * const router = RpcRouter.make(findBookById, queryBooks, createBook, updateBook, deleteBook, aggregateBooks, createManyBooks)
803
+ * ```
804
+ */
805
+ export declare function makeRpcGroup<Config extends DatabaseConfig>(config: Config): RpcGroupFromConfig<Config>;
806
+ /**
807
+ * Helper type to extract the Schema from a collection config.
808
+ */
809
+ type ExtractCollectionSchema<C extends CollectionConfig> = C["schema"];
810
+ /**
811
+ * Type for the RPC group derived from a DatabaseConfig.
812
+ * Maps each collection name to its RPC definitions.
813
+ */
814
+ export type RpcGroupFromConfig<Config extends DatabaseConfig> = {
815
+ readonly [K in keyof Config]: CollectionRpcDefinitions<K & string, ExtractCollectionSchema<Config[K]> extends Schema.Schema.Any ? ExtractCollectionSchema<Config[K]> : Schema.Schema<unknown, unknown, never>>;
816
+ };
817
+ export type { DatabaseConfig, CollectionConfig };
818
+ export { RpcRouter };
819
+ //# sourceMappingURL=rpc-group.d.ts.map