@wordrhyme/auto-crud-server 1.0.3 → 1.0.5
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/README.md +319 -175
- package/dist/index.cjs +21 -10
- package/dist/index.d.cts +182 -23
- package/dist/index.d.ts +188 -29
- package/dist/index.js +19 -11
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { SQL } from "drizzle-orm";
|
|
3
|
-
import * as
|
|
3
|
+
import * as _trpc_server2 from "@trpc/server";
|
|
4
4
|
import superjson from "superjson";
|
|
5
5
|
import { PgTable } from "drizzle-orm/pg-core";
|
|
6
6
|
import { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
@@ -13,22 +13,22 @@ import { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
|
13
13
|
interface Context {
|
|
14
14
|
db: PostgresJsDatabase<Record<string, never>>;
|
|
15
15
|
}
|
|
16
|
-
declare const router:
|
|
16
|
+
declare const router: _trpc_server2.TRPCRouterBuilder<{
|
|
17
17
|
ctx: Context;
|
|
18
18
|
meta: object;
|
|
19
|
-
errorShape:
|
|
19
|
+
errorShape: _trpc_server2.TRPCDefaultErrorShape;
|
|
20
20
|
transformer: true;
|
|
21
21
|
}>;
|
|
22
|
-
declare const publicProcedure:
|
|
22
|
+
declare const publicProcedure: _trpc_server2.TRPCProcedureBuilder<Context, object, object, _trpc_server2.TRPCUnsetMarker, _trpc_server2.TRPCUnsetMarker, _trpc_server2.TRPCUnsetMarker, _trpc_server2.TRPCUnsetMarker, false>;
|
|
23
23
|
//#endregion
|
|
24
24
|
//#region src/types/config.d.ts
|
|
25
|
-
type CrudOperation =
|
|
26
|
-
type WriteOperation =
|
|
25
|
+
type CrudOperation = 'list' | 'get' | 'create' | 'update' | 'delete' | 'deleteMany' | 'updateMany' | 'upsert' | 'export' | 'import' | 'createMany';
|
|
26
|
+
type WriteOperation = 'create' | 'update';
|
|
27
27
|
/**
|
|
28
28
|
* 表字段键类型提取
|
|
29
29
|
* 用于 omitFields 的强类型支持
|
|
30
30
|
*/
|
|
31
|
-
type TableColumnKeys<T extends PgTable> = keyof T[
|
|
31
|
+
type TableColumnKeys<T extends PgTable> = keyof T['_']['columns'];
|
|
32
32
|
type AnyProcedure = any;
|
|
33
33
|
interface SoftDeleteConfig {
|
|
34
34
|
/** 软删除标记列名 */
|
|
@@ -64,7 +64,7 @@ interface ListInput {
|
|
|
64
64
|
operator: string;
|
|
65
65
|
filterId: string;
|
|
66
66
|
}>;
|
|
67
|
-
joinOperator:
|
|
67
|
+
joinOperator: 'and' | 'or';
|
|
68
68
|
}
|
|
69
69
|
/**
|
|
70
70
|
* 列表查询结果类型
|
|
@@ -76,6 +76,14 @@ interface ListResult<TSelect> {
|
|
|
76
76
|
perPage: number;
|
|
77
77
|
pageCount: number;
|
|
78
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* 单条查询输入类型
|
|
81
|
+
* - string: 兼容旧的 get(id) 调用
|
|
82
|
+
* - object: 支持通过 getInputSchema 扩展 include 等控制参数
|
|
83
|
+
*/
|
|
84
|
+
type GetInput = string | {
|
|
85
|
+
id: string;
|
|
86
|
+
};
|
|
79
87
|
/**
|
|
80
88
|
* 导出查询输入类型(复用 ListInput 的筛选/排序,无分页)
|
|
81
89
|
*/
|
|
@@ -91,7 +99,7 @@ interface ExportInput {
|
|
|
91
99
|
operator: string;
|
|
92
100
|
filterId: string;
|
|
93
101
|
}>;
|
|
94
|
-
joinOperator?:
|
|
102
|
+
joinOperator?: 'and' | 'or';
|
|
95
103
|
/** 导出数量限制,会被 clamp 到 [1, maxExportSize] */
|
|
96
104
|
limit?: number;
|
|
97
105
|
}
|
|
@@ -138,17 +146,18 @@ interface ImportInput {
|
|
|
138
146
|
* - "upsert": 存在则更新,不存在则新建
|
|
139
147
|
* - "error": 冲突行计入失败
|
|
140
148
|
*/
|
|
141
|
-
onConflict?:
|
|
149
|
+
onConflict?: 'skip' | 'upsert' | 'error';
|
|
142
150
|
}
|
|
143
|
-
interface ListMiddlewareParams<TContext, TSelect> {
|
|
151
|
+
interface ListMiddlewareParams<TContext, TSelect, TListInput extends ListInput = ListInput> {
|
|
144
152
|
ctx: TContext;
|
|
145
|
-
input:
|
|
146
|
-
next: (input?:
|
|
153
|
+
input: TListInput;
|
|
154
|
+
next: (input?: TListInput) => Promise<ListResult<TSelect>>;
|
|
147
155
|
}
|
|
148
|
-
interface GetMiddlewareParams<TContext, TSelect> {
|
|
156
|
+
interface GetMiddlewareParams<TContext, TSelect, TGetInput extends GetInput = GetInput> {
|
|
149
157
|
ctx: TContext;
|
|
150
158
|
id: string;
|
|
151
|
-
|
|
159
|
+
input: TGetInput;
|
|
160
|
+
next: (input?: TGetInput) => Promise<TSelect | null>;
|
|
152
161
|
}
|
|
153
162
|
interface CreateMiddlewareParams<TContext, TSelect, TInsert> {
|
|
154
163
|
ctx: TContext;
|
|
@@ -191,10 +200,10 @@ interface UpsertMiddlewareParams<TContext, TSelect, TInsert> {
|
|
|
191
200
|
isNew: boolean;
|
|
192
201
|
}>;
|
|
193
202
|
}
|
|
194
|
-
interface ExportMiddlewareParams<TContext, TSelect> {
|
|
203
|
+
interface ExportMiddlewareParams<TContext, TSelect, TExportInput extends ExportInput = ExportInput> {
|
|
195
204
|
ctx: TContext;
|
|
196
|
-
input:
|
|
197
|
-
next: (input?:
|
|
205
|
+
input: TExportInput;
|
|
206
|
+
next: (input?: TExportInput) => Promise<ExportResult<TSelect>>;
|
|
198
207
|
}
|
|
199
208
|
interface ImportMiddlewareParams<TContext> {
|
|
200
209
|
ctx: TContext;
|
|
@@ -235,15 +244,15 @@ interface CreateManyMiddlewareParams<TContext, TSelect, TInsert> {
|
|
|
235
244
|
* },
|
|
236
245
|
* }
|
|
237
246
|
*/
|
|
238
|
-
interface CrudMiddleware<TContext = unknown, TSelect = unknown, TInsert = unknown, TUpdate = unknown> {
|
|
247
|
+
interface CrudMiddleware<TContext = unknown, TSelect = unknown, TInsert = unknown, TUpdate = unknown, TListInput extends ListInput = ListInput, TGetInput extends GetInput = GetInput, TExportInput extends ExportInput = ExportInput> {
|
|
239
248
|
/**
|
|
240
249
|
* 列表查询包装器
|
|
241
250
|
*/
|
|
242
|
-
list?: (params: ListMiddlewareParams<TContext, TSelect>) => Promise<ListResult<TSelect>>;
|
|
251
|
+
list?: (params: ListMiddlewareParams<TContext, TSelect, TListInput>) => Promise<ListResult<TSelect>>;
|
|
243
252
|
/**
|
|
244
253
|
* 单条查询包装器
|
|
245
254
|
*/
|
|
246
|
-
get?: (params: GetMiddlewareParams<TContext, TSelect>) => Promise<TSelect | null>;
|
|
255
|
+
get?: (params: GetMiddlewareParams<TContext, TSelect, TGetInput>) => Promise<TSelect | null>;
|
|
247
256
|
/**
|
|
248
257
|
* 创建包装器
|
|
249
258
|
*/
|
|
@@ -282,7 +291,7 @@ interface CrudMiddleware<TContext = unknown, TSelect = unknown, TInsert = unknow
|
|
|
282
291
|
* 导出包装器
|
|
283
292
|
* 可用于审计日志、限流、异步队列调度
|
|
284
293
|
*/
|
|
285
|
-
export?: (params: ExportMiddlewareParams<TContext, TSelect>) => Promise<ExportResult<TSelect>>;
|
|
294
|
+
export?: (params: ExportMiddlewareParams<TContext, TSelect, TExportInput>) => Promise<ExportResult<TSelect>>;
|
|
286
295
|
/**
|
|
287
296
|
* 导入包装器
|
|
288
297
|
* 可用于审计日志、限流、异步队列调度
|
|
@@ -378,7 +387,7 @@ type ProcedureConfig = AnyProcedure | ProcedureMap | ProcedureFactory;
|
|
|
378
387
|
* authorize: (ctx, resource) => resource.ownerId === ctx.user.id,
|
|
379
388
|
* })
|
|
380
389
|
*/
|
|
381
|
-
interface CrudRouterConfig<TTable extends PgTable = PgTable, TContext = unknown, TSelect = unknown, TInsert = unknown, TUpdate = unknown> {
|
|
390
|
+
interface CrudRouterConfig<TTable extends PgTable = PgTable, TContext = unknown, TSelect = unknown, TInsert = unknown, TUpdate = unknown, TListInput extends ListInput = ListInput, TGetInput extends GetInput = GetInput, TExportInput extends ExportInput = ExportInput> {
|
|
382
391
|
/** Drizzle 表定义 */
|
|
383
392
|
table: TTable;
|
|
384
393
|
/**
|
|
@@ -409,6 +418,35 @@ interface CrudRouterConfig<TTable extends PgTable = PgTable, TContext = unknown,
|
|
|
409
418
|
updateSchema?: z.ZodType<TUpdate>;
|
|
410
419
|
/** 查询返回 Schema */
|
|
411
420
|
selectSchema?: z.ZodType<TSelect>;
|
|
421
|
+
/**
|
|
422
|
+
* 列表查询输入 Schema(可选)
|
|
423
|
+
* - 默认使用内置基础列表输入:page、perPage、sort、filters、joinOperator
|
|
424
|
+
* - 业务侧可以基于 baseListInputSchema.extend(...) 增加自定义参数
|
|
425
|
+
* - 默认查询逻辑只读取基础字段,额外字段会保留给 middleware.list 使用
|
|
426
|
+
*
|
|
427
|
+
* @example
|
|
428
|
+
* listInputSchema: baseListInputSchema.extend({
|
|
429
|
+
* include: z.object({ skus: z.boolean().optional() }).optional(),
|
|
430
|
+
* })
|
|
431
|
+
*/
|
|
432
|
+
listInputSchema?: z.ZodType<TListInput>;
|
|
433
|
+
/**
|
|
434
|
+
* 单条查询输入 Schema(可选)
|
|
435
|
+
* - 默认兼容 get(id) 和 get({ id })
|
|
436
|
+
* - 业务侧可以基于 baseGetInputSchema.extend(...) 增加 include 等控制参数
|
|
437
|
+
* - 配置后仍保留 get(id) 字符串调用兼容性
|
|
438
|
+
* - 默认查询逻辑只读取 id,额外字段会保留给 middleware.get 使用
|
|
439
|
+
*/
|
|
440
|
+
getInputSchema?: z.ZodType<Extract<TGetInput, {
|
|
441
|
+
id: string;
|
|
442
|
+
}>>;
|
|
443
|
+
/**
|
|
444
|
+
* 导出查询输入 Schema(可选)
|
|
445
|
+
* - 默认使用内置基础导出输入:sort、filters、joinOperator、limit
|
|
446
|
+
* - 业务侧可以基于 baseExportInputSchema.extend(...) 增加自定义参数
|
|
447
|
+
* - 默认查询逻辑只读取基础字段,额外字段会保留给 middleware.export 使用
|
|
448
|
+
*/
|
|
449
|
+
exportInputSchema?: z.ZodType<TExportInput>;
|
|
412
450
|
/**
|
|
413
451
|
* Procedure 配置(统一字段)
|
|
414
452
|
*
|
|
@@ -517,7 +555,7 @@ interface CrudRouterConfig<TTable extends PgTable = PgTable, TContext = unknown,
|
|
|
517
555
|
* }),
|
|
518
556
|
* }
|
|
519
557
|
*/
|
|
520
|
-
middleware?: CrudMiddleware<TContext, TSelect, TInsert, TUpdate>;
|
|
558
|
+
middleware?: CrudMiddleware<TContext, TSelect, TInsert, TUpdate, TListInput, TGetInput, TExportInput>;
|
|
521
559
|
}
|
|
522
560
|
interface CrudProcedures {
|
|
523
561
|
list: AnyProcedure;
|
|
@@ -541,6 +579,94 @@ interface CrudProcedures {
|
|
|
541
579
|
type CrudRouterReturn = ReturnType<typeof router> & {
|
|
542
580
|
procedures: CrudProcedures;
|
|
543
581
|
};
|
|
582
|
+
declare const baseListInputSchema: z.ZodObject<{
|
|
583
|
+
page: z.ZodDefault<z.ZodNumber>;
|
|
584
|
+
perPage: z.ZodDefault<z.ZodNumber>;
|
|
585
|
+
sort: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
586
|
+
id: z.ZodString;
|
|
587
|
+
desc: z.ZodBoolean;
|
|
588
|
+
}, z.core.$strip>>>;
|
|
589
|
+
filters: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
590
|
+
id: z.ZodString;
|
|
591
|
+
value: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>;
|
|
592
|
+
variant: z.ZodEnum<{
|
|
593
|
+
number: "number";
|
|
594
|
+
boolean: "boolean";
|
|
595
|
+
date: "date";
|
|
596
|
+
text: "text";
|
|
597
|
+
range: "range";
|
|
598
|
+
dateRange: "dateRange";
|
|
599
|
+
select: "select";
|
|
600
|
+
multiSelect: "multiSelect";
|
|
601
|
+
}>;
|
|
602
|
+
operator: z.ZodEnum<{
|
|
603
|
+
iLike: "iLike";
|
|
604
|
+
notILike: "notILike";
|
|
605
|
+
eq: "eq";
|
|
606
|
+
ne: "ne";
|
|
607
|
+
isEmpty: "isEmpty";
|
|
608
|
+
isNotEmpty: "isNotEmpty";
|
|
609
|
+
lt: "lt";
|
|
610
|
+
lte: "lte";
|
|
611
|
+
gt: "gt";
|
|
612
|
+
gte: "gte";
|
|
613
|
+
isBetween: "isBetween";
|
|
614
|
+
isRelativeToToday: "isRelativeToToday";
|
|
615
|
+
inArray: "inArray";
|
|
616
|
+
notInArray: "notInArray";
|
|
617
|
+
}>;
|
|
618
|
+
filterId: z.ZodString;
|
|
619
|
+
}, z.core.$strip>>>;
|
|
620
|
+
joinOperator: z.ZodDefault<z.ZodEnum<{
|
|
621
|
+
and: "and";
|
|
622
|
+
or: "or";
|
|
623
|
+
}>>;
|
|
624
|
+
}, z.core.$strip>;
|
|
625
|
+
declare const baseGetInputSchema: z.ZodObject<{
|
|
626
|
+
id: z.ZodString;
|
|
627
|
+
}, z.core.$strip>;
|
|
628
|
+
declare const baseExportInputSchema: z.ZodObject<{
|
|
629
|
+
sort: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
630
|
+
id: z.ZodString;
|
|
631
|
+
desc: z.ZodBoolean;
|
|
632
|
+
}, z.core.$strip>>>;
|
|
633
|
+
filters: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
634
|
+
id: z.ZodString;
|
|
635
|
+
value: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>;
|
|
636
|
+
variant: z.ZodEnum<{
|
|
637
|
+
number: "number";
|
|
638
|
+
boolean: "boolean";
|
|
639
|
+
date: "date";
|
|
640
|
+
text: "text";
|
|
641
|
+
range: "range";
|
|
642
|
+
dateRange: "dateRange";
|
|
643
|
+
select: "select";
|
|
644
|
+
multiSelect: "multiSelect";
|
|
645
|
+
}>;
|
|
646
|
+
operator: z.ZodEnum<{
|
|
647
|
+
iLike: "iLike";
|
|
648
|
+
notILike: "notILike";
|
|
649
|
+
eq: "eq";
|
|
650
|
+
ne: "ne";
|
|
651
|
+
isEmpty: "isEmpty";
|
|
652
|
+
isNotEmpty: "isNotEmpty";
|
|
653
|
+
lt: "lt";
|
|
654
|
+
lte: "lte";
|
|
655
|
+
gt: "gt";
|
|
656
|
+
gte: "gte";
|
|
657
|
+
isBetween: "isBetween";
|
|
658
|
+
isRelativeToToday: "isRelativeToToday";
|
|
659
|
+
inArray: "inArray";
|
|
660
|
+
notInArray: "notInArray";
|
|
661
|
+
}>;
|
|
662
|
+
filterId: z.ZodString;
|
|
663
|
+
}, z.core.$strip>>>;
|
|
664
|
+
joinOperator: z.ZodDefault<z.ZodEnum<{
|
|
665
|
+
and: "and";
|
|
666
|
+
or: "or";
|
|
667
|
+
}>>;
|
|
668
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
669
|
+
}, z.core.$strip>;
|
|
544
670
|
/**
|
|
545
671
|
* 创建 CRUD Router
|
|
546
672
|
*
|
|
@@ -553,7 +679,7 @@ type CrudRouterReturn = ReturnType<typeof router> & {
|
|
|
553
679
|
* @typeParam TInsert - 创建输入类型
|
|
554
680
|
* @typeParam TUpdate - 更新输入类型
|
|
555
681
|
*/
|
|
556
|
-
declare function createCrudRouter<TTable extends PgTable = PgTable, TContext = unknown, TSelect = unknown, TInsert = unknown, TUpdate = unknown>(config: CrudRouterConfig<TTable, TContext, TSelect, TInsert, TUpdate>): CrudRouterReturn;
|
|
682
|
+
declare function createCrudRouter<TTable extends PgTable = PgTable, TContext = unknown, TSelect = unknown, TInsert = unknown, TUpdate = unknown, TListInput extends ListInput = ListInput, TGetInput extends GetInput = GetInput, TExportInput extends ExportInput = ExportInput>(config: CrudRouterConfig<TTable, TContext, TSelect, TInsert, TUpdate, TListInput, TGetInput, TExportInput>): CrudRouterReturn;
|
|
557
683
|
//#endregion
|
|
558
684
|
//#region src/lib/middleware-helpers.d.ts
|
|
559
685
|
/**
|
|
@@ -612,13 +738,46 @@ type AnyMiddlewareParams<TContext> = {
|
|
|
612
738
|
*/
|
|
613
739
|
declare function composeMiddleware<TContext, TResult>(...middlewares: Array<(params: AnyMiddlewareParams<TContext>) => Promise<any>>): (params: AnyMiddlewareParams<TContext>) => Promise<TResult>;
|
|
614
740
|
//#endregion
|
|
741
|
+
//#region src/types/hook-types.d.ts
|
|
742
|
+
/**
|
|
743
|
+
* 从 CRUD Schema 类型自动推导 Hook 事件映射
|
|
744
|
+
*
|
|
745
|
+
* 生成两类 hook:
|
|
746
|
+
* 1. 生命周期 hook(beforeCreate / afterCreate 等)— 由 tRPC middleware 自动 emit
|
|
747
|
+
* 2. Procedure hook(create / update / list 等)— 供 emit 自动映射 tRPC 路由使用
|
|
748
|
+
*
|
|
749
|
+
* @typeParam PluginId - 插件标识(如 'crm', 'shop')
|
|
750
|
+
* @typeParam ResourceName - 资源名称(如 'customers', 'products')
|
|
751
|
+
* @typeParam TCreate - 创建输入类型(z.infer<typeof createSchema>)
|
|
752
|
+
* @typeParam TUpdate - 更新输入类型(z.infer<typeof updateSchema>)
|
|
753
|
+
* @typeParam TSelect - 查询返回类型(InferSelectModel<typeof table>)
|
|
754
|
+
* @typeParam TListInput - list procedure 输入类型
|
|
755
|
+
* @typeParam TGetInput - get procedure 输入类型
|
|
756
|
+
* @typeParam TExportInput - export procedure 输入类型
|
|
757
|
+
*/
|
|
758
|
+
type CrudHookEventMap<PluginId extends string, ResourceName extends string, TCreate, TUpdate, TSelect, TListInput extends ListInput = ListInput, TGetInput extends GetInput = string, TExportInput extends ExportInput = ExportInput> = { [K in `${PluginId}.${ResourceName}.beforeCreate`]: TCreate } & { [K in `${PluginId}.${ResourceName}.afterCreate`]: TSelect } & { [K in `${PluginId}.${ResourceName}.beforeUpdate`]: {
|
|
759
|
+
id: string;
|
|
760
|
+
data: TUpdate;
|
|
761
|
+
} } & { [K in `${PluginId}.${ResourceName}.afterUpdate`]: TSelect } & { [K in `${PluginId}.${ResourceName}.beforeDelete`]: {
|
|
762
|
+
id: string;
|
|
763
|
+
} } & { [K in `${PluginId}.${ResourceName}.afterDelete`]: TSelect } & { [K in `${PluginId}.${ResourceName}.create`]: TCreate } & { [K in `${PluginId}.${ResourceName}.update`]: {
|
|
764
|
+
id: string;
|
|
765
|
+
data: TUpdate;
|
|
766
|
+
} } & { [K in `${PluginId}.${ResourceName}.delete`]: string } & { [K in `${PluginId}.${ResourceName}.deleteMany`]: string[] } & { [K in `${PluginId}.${ResourceName}.updateMany`]: {
|
|
767
|
+
ids: string[];
|
|
768
|
+
data: TUpdate;
|
|
769
|
+
} } & { [K in `${PluginId}.${ResourceName}.upsert`]: TCreate } & { [K in `${PluginId}.${ResourceName}.get`]: TGetInput } & { [K in `${PluginId}.${ResourceName}.list`]: TListInput } & { [K in `${PluginId}.${ResourceName}.export`]: TExportInput } & { [K in `${PluginId}.${ResourceName}.import`]: {
|
|
770
|
+
rows: unknown[];
|
|
771
|
+
onConflict?: 'skip' | 'upsert' | 'error';
|
|
772
|
+
} } & { [K in `${PluginId}.${ResourceName}.createMany`]: TCreate[] };
|
|
773
|
+
//#endregion
|
|
615
774
|
//#region src/routers/index.d.ts
|
|
616
|
-
declare const appRouter:
|
|
775
|
+
declare const appRouter: _trpc_server2.TRPCBuiltRouter<{
|
|
617
776
|
ctx: Context;
|
|
618
777
|
meta: object;
|
|
619
|
-
errorShape:
|
|
778
|
+
errorShape: _trpc_server2.TRPCDefaultErrorShape;
|
|
620
779
|
transformer: true;
|
|
621
|
-
},
|
|
780
|
+
}, _trpc_server2.TRPCDecorateCreateRouterOptions<{}>>;
|
|
622
781
|
type AppRouter = typeof appRouter;
|
|
623
782
|
//#endregion
|
|
624
|
-
export { type AnyProcedure, type AppRouter, type CreateManyMiddlewareParams, type CreateMiddlewareParams, type CrudMiddleware, type CrudOperation, type CrudProcedures, type CrudRouterConfig, type DeleteManyMiddlewareParams, type DeleteMiddlewareParams, type ExportInput, type ExportMiddlewareParams, type ExportResult, type GetMiddlewareParams, type ImportFailedRow, type ImportInput, type ImportMiddlewareParams, type ImportResult, type ListInput, type ListMiddlewareParams, type ListResult, type ProcedureConfig, type ProcedureFactory, type ProcedureMap, type SoftDeleteConfig, type SoftDeleteOption, type UpdateManyMiddlewareParams, type UpdateMiddlewareParams, type UpsertMiddlewareParams, type WriteOperation, afterMiddleware, appRouter, beforeMiddleware, composeMiddleware, createCrudRouter, publicProcedure, router };
|
|
783
|
+
export { type AnyProcedure, type AppRouter, type CreateManyMiddlewareParams, type CreateMiddlewareParams, type CrudHookEventMap, type CrudMiddleware, type CrudOperation, type CrudProcedures, type CrudRouterConfig, type DeleteManyMiddlewareParams, type DeleteMiddlewareParams, type ExportInput, type ExportMiddlewareParams, type ExportResult, type GetInput, type GetMiddlewareParams, type ImportFailedRow, type ImportInput, type ImportMiddlewareParams, type ImportResult, type ListInput, type ListMiddlewareParams, type ListResult, type ProcedureConfig, type ProcedureFactory, type ProcedureMap, type SoftDeleteConfig, type SoftDeleteOption, type UpdateManyMiddlewareParams, type UpdateMiddlewareParams, type UpsertMiddlewareParams, type WriteOperation, afterMiddleware, appRouter, baseExportInputSchema, baseGetInputSchema, baseListInputSchema, beforeMiddleware, composeMiddleware, createCrudRouter, publicProcedure, router };
|
package/dist/index.js
CHANGED
|
@@ -471,7 +471,7 @@ const filterItemSchema = z.object({
|
|
|
471
471
|
operator: z.enum(dataTableConfig.operators),
|
|
472
472
|
filterId: z.string()
|
|
473
473
|
});
|
|
474
|
-
const
|
|
474
|
+
const baseListInputSchema = z.object({
|
|
475
475
|
page: z.number().min(1).default(1),
|
|
476
476
|
perPage: z.number().min(1).max(100).default(10),
|
|
477
477
|
sort: z.array(z.object({
|
|
@@ -481,7 +481,9 @@ const listInputSchema = z.object({
|
|
|
481
481
|
filters: z.array(filterItemSchema).optional(),
|
|
482
482
|
joinOperator: z.enum(["and", "or"]).default("and")
|
|
483
483
|
});
|
|
484
|
-
const
|
|
484
|
+
const baseGetInputSchema = z.object({ id: z.string() });
|
|
485
|
+
const defaultGetInputSchema = z.union([z.string(), baseGetInputSchema]);
|
|
486
|
+
const baseExportInputSchema = z.object({
|
|
485
487
|
sort: z.array(z.object({
|
|
486
488
|
id: z.string(),
|
|
487
489
|
desc: z.boolean()
|
|
@@ -584,6 +586,9 @@ function createCrudRouter(config) {
|
|
|
584
586
|
});
|
|
585
587
|
const resolved = resolveConfig(config);
|
|
586
588
|
const softDelete = resolveSoftDelete(softDeleteOption);
|
|
589
|
+
const resolvedListInputSchema = config.listInputSchema ?? baseListInputSchema;
|
|
590
|
+
const resolvedGetInputSchema = config.getInputSchema ? z.union([z.string(), config.getInputSchema]) : defaultGetInputSchema;
|
|
591
|
+
const resolvedExportInputSchema = config.exportInputSchema ?? baseExportInputSchema;
|
|
587
592
|
const m = middleware;
|
|
588
593
|
const getIdColumn = () => table[idField];
|
|
589
594
|
const getSoftDeleteColumn = () => softDelete ? table[softDelete.column] : null;
|
|
@@ -625,7 +630,7 @@ function createCrudRouter(config) {
|
|
|
625
630
|
});
|
|
626
631
|
};
|
|
627
632
|
const procedures = {
|
|
628
|
-
list: resolved.procedureFactory("list").input(
|
|
633
|
+
list: resolved.procedureFactory("list").input(resolvedListInputSchema).output(listOutputSchema).query(async ({ ctx, input }) => {
|
|
629
634
|
await withGuard(ctx, "list");
|
|
630
635
|
const doList = async (listInput$1) => {
|
|
631
636
|
const offset = (listInput$1.page - 1) * listInput$1.perPage;
|
|
@@ -664,20 +669,23 @@ function createCrudRouter(config) {
|
|
|
664
669
|
});
|
|
665
670
|
return doList(listInput);
|
|
666
671
|
}),
|
|
667
|
-
get: resolved.procedureFactory("get").input(
|
|
672
|
+
get: resolved.procedureFactory("get").input(resolvedGetInputSchema).output(entityOutputSchema.nullable()).query(async ({ ctx, input }) => {
|
|
668
673
|
await withGuard(ctx, "get");
|
|
669
|
-
const doGet = async () => {
|
|
670
|
-
const
|
|
674
|
+
const doGet = async (getInput) => {
|
|
675
|
+
const id$1 = typeof getInput === "string" ? getInput : getInput.id;
|
|
676
|
+
const where = buildWhere(ctx, "get", eq(getIdColumn(), id$1));
|
|
671
677
|
const [item] = await ctx.db.select().from(table).where(where);
|
|
672
678
|
await withAuthorize(ctx, item, "get");
|
|
673
679
|
return item ?? null;
|
|
674
680
|
};
|
|
681
|
+
const id = typeof input === "string" ? input : input.id;
|
|
675
682
|
if (m.get) return m.get({
|
|
676
683
|
ctx,
|
|
677
|
-
id
|
|
678
|
-
|
|
684
|
+
id,
|
|
685
|
+
input,
|
|
686
|
+
next: async (modifiedInput) => doGet(modifiedInput ?? input)
|
|
679
687
|
});
|
|
680
|
-
return doGet();
|
|
688
|
+
return doGet(input);
|
|
681
689
|
}),
|
|
682
690
|
create: resolved.procedureFactory("create").input(schema).output(entityOutputSchema).mutation(async ({ ctx, input }) => {
|
|
683
691
|
await withGuard(ctx, "create");
|
|
@@ -823,7 +831,7 @@ function createCrudRouter(config) {
|
|
|
823
831
|
});
|
|
824
832
|
return doUpsert(input);
|
|
825
833
|
}),
|
|
826
|
-
export: resolved.procedureFactory("export").input(
|
|
834
|
+
export: resolved.procedureFactory("export").input(resolvedExportInputSchema).output(exportOutputSchema).query(async ({ ctx, input }) => {
|
|
827
835
|
await withGuard(ctx, "export");
|
|
828
836
|
const doExport = async (exportInput$1) => {
|
|
829
837
|
const effectiveLimit = Math.min(Math.max(exportInput$1.limit ?? maxExportSize, 1), maxExportSize);
|
|
@@ -1026,4 +1034,4 @@ function composeMiddleware(...middlewares) {
|
|
|
1026
1034
|
const appRouter = router({});
|
|
1027
1035
|
|
|
1028
1036
|
//#endregion
|
|
1029
|
-
export { afterMiddleware, appRouter, beforeMiddleware, composeMiddleware, createCrudRouter, publicProcedure, router };
|
|
1037
|
+
export { afterMiddleware, appRouter, baseExportInputSchema, baseGetInputSchema, baseListInputSchema, beforeMiddleware, composeMiddleware, createCrudRouter, publicProcedure, router };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordrhyme/auto-crud-server",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.5",
|
|
5
5
|
"description": "tRPC server utilities for auto-crud - automatic CRUD routers for Drizzle ORM",
|
|
6
6
|
"author": "wordrhyme",
|
|
7
7
|
"license": "MIT",
|
|
@@ -48,10 +48,10 @@
|
|
|
48
48
|
"vitest": "^4.0.18",
|
|
49
49
|
"zod": "^4.1.13",
|
|
50
50
|
"@internal/eslint-config": "0.3.0",
|
|
51
|
-
"@internal/prettier-config": "0.0.1",
|
|
52
|
-
"@internal/tsconfig": "0.1.0",
|
|
53
51
|
"@internal/tsdown-config": "0.1.0",
|
|
54
|
-
"@internal/vitest-config": "0.1.0"
|
|
52
|
+
"@internal/vitest-config": "0.1.0",
|
|
53
|
+
"@internal/tsconfig": "0.1.0",
|
|
54
|
+
"@internal/prettier-config": "0.0.1"
|
|
55
55
|
},
|
|
56
56
|
"prettier": "@internal/prettier-config",
|
|
57
57
|
"scripts": {
|