@wordrhyme/auto-crud-server 0.6.0 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,6 +1,5 @@
1
- import * as _trpc_server5 from "@trpc/server";
1
+ import * as _trpc_server2 from "@trpc/server";
2
2
  import { PostgresJsDatabase } from "drizzle-orm/postgres-js";
3
- import * as node_modules__trpc_server_dist_unstable_core_do_not_import_d_CjQPvBRI_mjs0 from "node_modules/@trpc/server/dist/unstable-core-do-not-import.d-CjQPvBRI.mjs";
4
3
  import { SQL } from "drizzle-orm";
5
4
  import { PgTable } from "drizzle-orm/pg-core";
6
5
  import { z } from "zod";
@@ -13,16 +12,16 @@ import { z } from "zod";
13
12
  interface Context {
14
13
  db: PostgresJsDatabase<Record<string, never>>;
15
14
  }
16
- declare const router: _trpc_server5.TRPCRouterBuilder<{
15
+ declare const router: _trpc_server2.TRPCRouterBuilder<{
17
16
  ctx: Context;
18
17
  meta: object;
19
- errorShape: _trpc_server5.TRPCDefaultErrorShape;
18
+ errorShape: _trpc_server2.TRPCDefaultErrorShape;
20
19
  transformer: true;
21
20
  }>;
22
- declare const publicProcedure: _trpc_server5.TRPCProcedureBuilder<Context, object, object, _trpc_server5.TRPCUnsetMarker, _trpc_server5.TRPCUnsetMarker, _trpc_server5.TRPCUnsetMarker, _trpc_server5.TRPCUnsetMarker, false>;
21
+ declare const publicProcedure: _trpc_server2.TRPCProcedureBuilder<Context, object, object, _trpc_server2.TRPCUnsetMarker, _trpc_server2.TRPCUnsetMarker, _trpc_server2.TRPCUnsetMarker, _trpc_server2.TRPCUnsetMarker, false>;
23
22
  //#endregion
24
23
  //#region src/types/config.d.ts
25
- type CrudOperation = "list" | "get" | "create" | "update" | "delete" | "deleteMany" | "updateMany";
24
+ type CrudOperation = "list" | "get" | "create" | "update" | "delete" | "deleteMany" | "updateMany" | "upsert";
26
25
  type WriteOperation = "create" | "update";
27
26
  type AnyProcedure = any;
28
27
  interface SoftDeleteConfig {
@@ -71,6 +70,57 @@ interface ListResult<TSelect> {
71
70
  perPage: number;
72
71
  pageCount: number;
73
72
  }
73
+ interface ListMiddlewareParams<TContext, TSelect> {
74
+ ctx: TContext;
75
+ input: ListInput;
76
+ next: (input?: ListInput) => Promise<ListResult<TSelect>>;
77
+ }
78
+ interface GetMiddlewareParams<TContext, TSelect> {
79
+ ctx: TContext;
80
+ id: string;
81
+ next: () => Promise<TSelect | null>;
82
+ }
83
+ interface CreateMiddlewareParams<TContext, TSelect, TInsert> {
84
+ ctx: TContext;
85
+ input: TInsert;
86
+ next: (input?: TInsert) => Promise<TSelect>;
87
+ }
88
+ interface UpdateMiddlewareParams<TContext, TSelect, TUpdate> {
89
+ ctx: TContext;
90
+ id: string;
91
+ data: TUpdate;
92
+ existing: TSelect;
93
+ next: (data?: TUpdate) => Promise<TSelect>;
94
+ }
95
+ interface DeleteMiddlewareParams<TContext, TSelect> {
96
+ ctx: TContext;
97
+ id: string;
98
+ existing: TSelect;
99
+ next: () => Promise<TSelect>;
100
+ }
101
+ interface DeleteManyMiddlewareParams<TContext> {
102
+ ctx: TContext;
103
+ ids: string[];
104
+ next: () => Promise<{
105
+ deleted: number;
106
+ }>;
107
+ }
108
+ interface UpdateManyMiddlewareParams<TContext, TUpdate> {
109
+ ctx: TContext;
110
+ ids: string[];
111
+ data: TUpdate;
112
+ next: (data?: TUpdate) => Promise<{
113
+ updated: number;
114
+ }>;
115
+ }
116
+ interface UpsertMiddlewareParams<TContext, TSelect, TInsert> {
117
+ ctx: TContext;
118
+ input: TInsert;
119
+ next: (input?: TInsert) => Promise<{
120
+ data: TSelect;
121
+ isNew: boolean;
122
+ }>;
123
+ }
74
124
  /**
75
125
  * 操作包装器 - 类似 tRPC middleware 的 next 模式
76
126
  *
@@ -81,6 +131,11 @@ interface ListResult<TSelect> {
81
131
  * - 条件拦截(不调用 next 直接返回/抛错)
82
132
  * - 包装事务(try/catch 包裹 next)
83
133
  *
134
+ * @typeParam TContext - 上下文类型
135
+ * @typeParam TSelect - 查询返回类型(从 selectSchema 推断)
136
+ * @typeParam TInsert - 创建输入类型(从 insertSchema 推断)
137
+ * @typeParam TUpdate - 更新输入类型(从 updateSchema 推断)
138
+ *
84
139
  * @example
85
140
  * // 修改输入 + 执行副作用
86
141
  * middleware: {
@@ -91,98 +146,60 @@ interface ListResult<TSelect> {
91
146
  * return result;
92
147
  * },
93
148
  * }
94
- *
95
- * @example
96
- * // 简单副作用 - 使用工具函数
97
- * import { afterMiddleware } from "@wordrhyme/auto-crud-server";
98
- *
99
- * middleware: {
100
- * create: afterMiddleware(async (ctx, result) => {
101
- * await sendEmail(result);
102
- * }),
103
- * }
104
149
  */
105
- interface CrudMiddleware<TContext = unknown> {
150
+ interface CrudMiddleware<TContext = unknown, TSelect = unknown, TInsert = unknown, TUpdate = unknown> {
106
151
  /**
107
152
  * 列表查询包装器
108
153
  */
109
- list?: (params: {
110
- ctx: TContext;
111
- input: ListInput;
112
- next: (input?: ListInput) => Promise<ListResult<unknown>>;
113
- }) => Promise<ListResult<unknown>>;
154
+ list?: (params: ListMiddlewareParams<TContext, TSelect>) => Promise<ListResult<TSelect>>;
114
155
  /**
115
156
  * 单条查询包装器
116
157
  */
117
- get?: (params: {
118
- ctx: TContext;
119
- id: string;
120
- next: () => Promise<unknown | null>;
121
- }) => Promise<unknown | null>;
158
+ get?: (params: GetMiddlewareParams<TContext, TSelect>) => Promise<TSelect | null>;
122
159
  /**
123
160
  * 创建包装器
124
161
  */
125
- create?: (params: {
126
- ctx: TContext;
127
- input: unknown;
128
- next: (input?: unknown) => Promise<unknown>;
129
- }) => Promise<unknown>;
162
+ create?: (params: CreateMiddlewareParams<TContext, TSelect, TInsert>) => Promise<TSelect>;
130
163
  /**
131
164
  * 更新包装器
132
165
  * existing: 更新前的记录
133
166
  */
134
- update?: (params: {
135
- ctx: TContext;
136
- id: string;
137
- data: unknown;
138
- existing: unknown;
139
- next: (data?: unknown) => Promise<unknown>;
140
- }) => Promise<unknown>;
167
+ update?: (params: UpdateMiddlewareParams<TContext, TSelect, TUpdate>) => Promise<TSelect>;
141
168
  /**
142
169
  * 删除包装器
143
170
  * existing: 删除前的记录
144
171
  */
145
- delete?: (params: {
146
- ctx: TContext;
147
- id: string;
148
- existing: unknown;
149
- next: () => Promise<unknown>;
150
- }) => Promise<unknown>;
172
+ delete?: (params: DeleteMiddlewareParams<TContext, TSelect>) => Promise<TSelect>;
151
173
  /**
152
174
  * 批量删除包装器
153
175
  */
154
- deleteMany?: (params: {
155
- ctx: TContext;
156
- ids: string[];
157
- next: () => Promise<{
158
- deleted: number;
159
- }>;
160
- }) => Promise<{
176
+ deleteMany?: (params: DeleteManyMiddlewareParams<TContext>) => Promise<{
161
177
  deleted: number;
162
178
  }>;
163
179
  /**
164
180
  * 批量更新包装器
165
181
  */
166
- updateMany?: (params: {
167
- ctx: TContext;
168
- ids: string[];
169
- data: unknown;
170
- next: (data?: unknown) => Promise<{
171
- updated: number;
172
- }>;
173
- }) => Promise<{
182
+ updateMany?: (params: UpdateManyMiddlewareParams<TContext, TUpdate>) => Promise<{
174
183
  updated: number;
175
184
  }>;
185
+ /**
186
+ * Upsert 包装器
187
+ * isNew: 是否为新建(冲突检测后)
188
+ */
189
+ upsert?: (params: UpsertMiddlewareParams<TContext, TSelect, TInsert>) => Promise<{
190
+ data: TSelect;
191
+ isNew: boolean;
192
+ }>;
176
193
  }
177
- interface CrudRouterConfigBase<TContext = unknown> {
194
+ interface CrudRouterConfigBase<TContext = unknown, TSelect = unknown, TInsert = unknown, TUpdate = unknown> {
178
195
  /** Drizzle 表定义 */
179
196
  table: PgTable;
180
197
  /** 查询返回 Schema */
181
- selectSchema?: z.ZodType;
198
+ selectSchema?: z.ZodType<TSelect>;
182
199
  /** 创建输入 Schema */
183
- insertSchema: z.ZodType;
200
+ insertSchema: z.ZodType<TInsert>;
184
201
  /** 更新输入 Schema */
185
- updateSchema: z.ZodType;
202
+ updateSchema: z.ZodType<TUpdate>;
186
203
  /** ID 字段名,默认 "id" */
187
204
  idField?: string;
188
205
  /** 可过滤的列白名单 */
@@ -237,9 +254,9 @@ interface CrudRouterConfigBase<TContext = unknown> {
237
254
  * }),
238
255
  * }
239
256
  */
240
- middleware?: CrudMiddleware<TContext>;
257
+ middleware?: CrudMiddleware<TContext, TSelect, TInsert, TUpdate>;
241
258
  }
242
- interface DeclarativeConfig<TContext = unknown> extends CrudRouterConfigBase<TContext> {
259
+ interface DeclarativeConfig<TContext = unknown, TSelect = unknown, TInsert = unknown, TUpdate = unknown> extends CrudRouterConfigBase<TContext, TSelect, TInsert, TUpdate> {
243
260
  mode?: "declarative";
244
261
  /**
245
262
  * 基础 procedure(认证)
@@ -277,9 +294,9 @@ interface DeclarativeConfig<TContext = unknown> extends CrudRouterConfigBase<TCo
277
294
  * @example
278
295
  * authorize: (ctx, resource, op) => resource.ownerId === ctx.user.id
279
296
  */
280
- authorize?: (ctx: TContext, resource: Record<string, unknown>, operation: CrudOperation) => boolean | Promise<boolean>;
297
+ authorize?: (ctx: TContext, resource: TSelect, operation: CrudOperation) => boolean | Promise<boolean>;
281
298
  }
282
- interface FactoryConfig<TContext = unknown> extends CrudRouterConfigBase<TContext> {
299
+ interface FactoryConfig<TContext = unknown, TSelect = unknown, TInsert = unknown, TUpdate = unknown> extends CrudRouterConfigBase<TContext, TSelect, TInsert, TUpdate> {
283
300
  mode: "factory";
284
301
  /**
285
302
  * Procedure 工厂函数
@@ -298,7 +315,7 @@ interface FactoryConfig<TContext = unknown> extends CrudRouterConfigBase<TContex
298
315
  */
299
316
  inject?: (ctx: TContext, operation: WriteOperation) => Record<string, unknown>;
300
317
  }
301
- interface ProceduresConfig<TContext = unknown> extends CrudRouterConfigBase<TContext> {
318
+ interface ProceduresConfig<TContext = unknown, TSelect = unknown, TInsert = unknown, TUpdate = unknown> extends CrudRouterConfigBase<TContext, TSelect, TInsert, TUpdate> {
302
319
  mode: "procedures";
303
320
  /**
304
321
  * 按操作指定不同的 procedure
@@ -322,49 +339,36 @@ interface ProceduresConfig<TContext = unknown> extends CrudRouterConfigBase<TCon
322
339
  */
323
340
  inject?: (ctx: TContext, operation: WriteOperation) => Record<string, unknown>;
324
341
  }
325
- type CrudRouterConfig<TContext = unknown> = DeclarativeConfig<TContext> | FactoryConfig<TContext> | ProceduresConfig<TContext>;
342
+ type CrudRouterConfig<TContext = unknown, TSelect = unknown, TInsert = unknown, TUpdate = unknown> = DeclarativeConfig<TContext, TSelect, TInsert, TUpdate> | FactoryConfig<TContext, TSelect, TInsert, TUpdate> | ProceduresConfig<TContext, TSelect, TInsert, TUpdate>;
343
+ interface CrudProcedures<TSelect, TInsert, TUpdate> {
344
+ list: AnyProcedure;
345
+ get: AnyProcedure;
346
+ create: AnyProcedure;
347
+ update: AnyProcedure;
348
+ delete: AnyProcedure;
349
+ deleteMany: AnyProcedure;
350
+ updateMany: AnyProcedure;
351
+ upsert: AnyProcedure;
352
+ }
326
353
  //#endregion
327
354
  //#region src/routers/_factory.d.ts
328
- declare function createCrudRouter<TContext = unknown>(config: CrudRouterConfig<TContext>): node_modules__trpc_server_dist_unstable_core_do_not_import_d_CjQPvBRI_mjs0.Router<{
329
- ctx: Context;
330
- meta: object;
331
- errorShape: _trpc_server5.TRPCDefaultErrorShape;
332
- transformer: true;
333
- }, _trpc_server5.TRPCDecorateCreateRouterOptions<{
334
- list: any;
335
- getById: any;
336
- create: any;
337
- update: any;
338
- delete: any;
339
- deleteMany: any;
340
- updateMany: any;
341
- }>> & _trpc_server5.TRPCDecorateCreateRouterOptions<{
342
- list: any;
343
- getById: any;
344
- create: any;
345
- update: any;
346
- delete: any;
347
- deleteMany: any;
348
- updateMany: any;
349
- }> & {
350
- procedures: {
351
- list: any;
352
- getById: any;
353
- create: any;
354
- update: any;
355
- delete: any;
356
- deleteMany: any;
357
- updateMany: any;
358
- };
355
+ /**
356
+ * 创建 CRUD Router
357
+ *
358
+ * @typeParam TContext - 上下文类型(包含 db)
359
+ * @typeParam TSelect - 查询返回类型(从 selectSchema 或 insertSchema 推断)
360
+ * @typeParam TInsert - 创建输入类型(从 insertSchema 推断)
361
+ * @typeParam TUpdate - 更新输入类型(从 updateSchema 推断)
362
+ */
363
+ declare function createCrudRouter<TContext = unknown, TSelect = unknown, TInsert = unknown, TUpdate = unknown>(config: CrudRouterConfig<TContext, TSelect, TInsert, TUpdate>): ReturnType<typeof router> & {
364
+ procedures: CrudProcedures<TSelect, TInsert, TUpdate>;
359
365
  };
360
366
  //#endregion
361
367
  //#region src/lib/middleware-helpers.d.ts
362
- type NextFn<TInput, TResult> = (input?: TInput) => Promise<TResult>;
363
- interface MiddlewareParams<TContext, TInput, TResult> {
364
- ctx: TContext;
365
- input?: TInput;
366
- next: NextFn<TInput, TResult>;
367
- }
368
+ /**
369
+ * Middleware 便捷工具函数
370
+ * 简化常见场景的 middleware 创建
371
+ */
368
372
  /**
369
373
  * 创建 after-only 的 middleware(最常见场景)
370
374
  * 在操作完成后执行副作用,不修改返回值
@@ -377,29 +381,10 @@ interface MiddlewareParams<TContext, TInput, TResult> {
377
381
  * }),
378
382
  * }
379
383
  */
380
- declare function afterMiddleware<TContext, TResult>(fn: (ctx: TContext, result: TResult) => void | Promise<void>): ({
381
- ctx,
382
- next
383
- }: {
384
- ctx: TContext;
385
- next: () => Promise<TResult>;
386
- }) => Promise<TResult>;
387
- /**
388
- * 创建 after-only 的 middleware,可修改返回值
389
- *
390
- * @example
391
- * middleware: {
392
- * get: afterMiddlewareTransform(async (ctx, result) => {
393
- * return { ...result, computed: calculateSomething(result) };
394
- * }),
395
- * }
396
- */
397
- declare function afterMiddlewareTransform<TContext, TResult>(fn: (ctx: TContext, result: TResult) => TResult | Promise<TResult>): ({
398
- ctx,
399
- next
400
- }: {
384
+ declare function afterMiddleware<TContext, TResult>(fn: (ctx: TContext, result: TResult) => void | Promise<void>): (params: {
401
385
  ctx: TContext;
402
386
  next: () => Promise<TResult>;
387
+ [key: string]: any;
403
388
  }) => Promise<TResult>;
404
389
  /**
405
390
  * 创建 before-only 的 middleware
@@ -412,11 +397,17 @@ declare function afterMiddlewareTransform<TContext, TResult>(fn: (ctx: TContext,
412
397
  * }),
413
398
  * }
414
399
  */
415
- declare function beforeMiddleware<TContext, TInput>(fn: (ctx: TContext, input: TInput) => TInput | Promise<TInput>): <TResult>({
416
- ctx,
417
- input,
418
- next
419
- }: MiddlewareParams<TContext, TInput, TResult>) => Promise<TResult>;
400
+ declare function beforeMiddleware<TContext, TInput>(fn: (ctx: TContext, input: TInput) => TInput | Promise<TInput>): <TResult>(params: {
401
+ ctx: TContext;
402
+ input: TInput;
403
+ next: (input?: TInput) => Promise<TResult>;
404
+ [key: string]: any;
405
+ }) => Promise<TResult>;
406
+ type AnyMiddlewareParams<TContext> = {
407
+ ctx: TContext;
408
+ next: (...args: any[]) => Promise<any>;
409
+ [key: string]: any;
410
+ };
420
411
  /**
421
412
  * 组合多个 middleware 为一个
422
413
  *
@@ -428,71 +419,15 @@ declare function beforeMiddleware<TContext, TInput>(fn: (ctx: TContext, input: T
428
419
  * ),
429
420
  * }
430
421
  */
431
- declare function composeMiddleware<TContext, TInput, TResult>(...middlewares: Array<(params: MiddlewareParams<TContext, TInput, TResult>) => Promise<TResult>>): (params: MiddlewareParams<TContext, TInput, TResult>) => Promise<TResult>;
432
- /**
433
- * 创建 list 操作的 after middleware
434
- */
435
- declare function afterList<TContext, TSelect>(fn: (ctx: TContext, result: ListResult<TSelect>) => void | Promise<void>): ({
436
- ctx,
437
- next
438
- }: {
439
- ctx: TContext;
440
- next: () => Promise<ListResult<TSelect>>;
441
- }) => Promise<ListResult<TSelect>>;
442
- /**
443
- * 创建 list 操作的 before middleware
444
- */
445
- declare function beforeList<TContext>(fn: (ctx: TContext, input: ListInput) => ListInput | Promise<ListInput>): <TResult>({
446
- ctx,
447
- input,
448
- next
449
- }: MiddlewareParams<TContext, ListInput, TResult>) => Promise<TResult>;
450
- /**
451
- * 创建 create 操作的 after middleware
452
- */
453
- declare function afterCreate<TContext, TSelect>(fn: (ctx: TContext, created: TSelect) => void | Promise<void>): ({
454
- ctx,
455
- next
456
- }: {
457
- ctx: TContext;
458
- next: () => Promise<TSelect>;
459
- }) => Promise<TSelect>;
460
- /**
461
- * 创建 create 操作的 before middleware
462
- */
463
- declare function beforeCreate<TContext, TInsert>(fn: (ctx: TContext, input: TInsert) => TInsert | Promise<TInsert>): <TResult>({
464
- ctx,
465
- input,
466
- next
467
- }: MiddlewareParams<TContext, TInsert, TResult>) => Promise<TResult>;
468
- /**
469
- * 创建 update 操作的 after middleware
470
- */
471
- declare function afterUpdate<TContext, TSelect>(fn: (ctx: TContext, updated: TSelect) => void | Promise<void>): ({
472
- ctx,
473
- next
474
- }: {
475
- ctx: TContext;
476
- next: () => Promise<TSelect>;
477
- }) => Promise<TSelect>;
478
- /**
479
- * 创建 delete 操作的 after middleware
480
- */
481
- declare function afterDelete<TContext, TSelect>(fn: (ctx: TContext, deleted: TSelect) => void | Promise<void>): ({
482
- ctx,
483
- next
484
- }: {
485
- ctx: TContext;
486
- next: () => Promise<TSelect>;
487
- }) => Promise<TSelect>;
422
+ declare function composeMiddleware<TContext, TResult>(...middlewares: Array<(params: AnyMiddlewareParams<TContext>) => Promise<any>>): (params: AnyMiddlewareParams<TContext>) => Promise<TResult>;
488
423
  //#endregion
489
424
  //#region src/routers/index.d.ts
490
- declare const appRouter: _trpc_server5.TRPCBuiltRouter<{
425
+ declare const appRouter: _trpc_server2.TRPCBuiltRouter<{
491
426
  ctx: Context;
492
427
  meta: object;
493
- errorShape: _trpc_server5.TRPCDefaultErrorShape;
428
+ errorShape: _trpc_server2.TRPCDefaultErrorShape;
494
429
  transformer: true;
495
- }, _trpc_server5.TRPCDecorateCreateRouterOptions<{}>>;
430
+ }, _trpc_server2.TRPCDecorateCreateRouterOptions<{}>>;
496
431
  type AppRouter = typeof appRouter;
497
432
  //#endregion
498
- export { type AnyProcedure, type AppRouter, type CrudMiddleware, type CrudOperation, type CrudRouterConfig, type DeclarativeConfig, type FactoryConfig, type ListInput, type ListResult, type ProceduresConfig, type SoftDeleteConfig, type SoftDeleteOption, type WriteOperation, afterCreate, afterDelete, afterList, afterMiddleware, afterMiddlewareTransform, afterUpdate, appRouter, beforeCreate, beforeList, beforeMiddleware, composeMiddleware, createCrudRouter, publicProcedure, router };
433
+ export { type AnyProcedure, type AppRouter, type CreateMiddlewareParams, type CrudMiddleware, type CrudOperation, type CrudProcedures, type CrudRouterConfig, type CrudRouterConfigBase, type DeclarativeConfig, type DeleteManyMiddlewareParams, type DeleteMiddlewareParams, type FactoryConfig, type GetMiddlewareParams, type ListInput, type ListMiddlewareParams, type ListResult, type ProceduresConfig, type SoftDeleteConfig, type SoftDeleteOption, type UpdateManyMiddlewareParams, type UpdateMiddlewareParams, type UpsertMiddlewareParams, type WriteOperation, afterMiddleware, appRouter, beforeMiddleware, composeMiddleware, createCrudRouter, publicProcedure, router };