@wordrhyme/auto-crud-server 0.2.0 → 0.3.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.
- package/README.md +94 -35
- package/dist/index.cjs +138 -52
- package/dist/index.d.cts +166 -129
- package/dist/index.d.ts +165 -127
- package/dist/index.js +138 -52
- package/package.json +4 -4
package/dist/index.d.cts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import superjson from "superjson";
|
|
1
|
+
import * as _trpc_server5 from "@trpc/server";
|
|
3
2
|
import { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
4
|
-
import
|
|
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
|
+
import { SQL } from "drizzle-orm";
|
|
5
5
|
import { PgTable } from "drizzle-orm/pg-core";
|
|
6
|
+
import { z } from "zod";
|
|
6
7
|
|
|
7
8
|
//#region src/trpc.d.ts
|
|
8
9
|
/**
|
|
@@ -12,161 +13,197 @@ import { PgTable } from "drizzle-orm/pg-core";
|
|
|
12
13
|
interface Context {
|
|
13
14
|
db: PostgresJsDatabase<Record<string, never>>;
|
|
14
15
|
}
|
|
15
|
-
declare const
|
|
16
|
-
transformer: typeof superjson;
|
|
17
|
-
}, {
|
|
18
|
-
ctx: Context;
|
|
19
|
-
meta: object;
|
|
20
|
-
errorShape: _trpc_server12.TRPCDefaultErrorShape;
|
|
21
|
-
transformer: true;
|
|
22
|
-
}>;
|
|
23
|
-
declare const router: _trpc_server12.TRPCRouterBuilder<{
|
|
16
|
+
declare const router: _trpc_server5.TRPCRouterBuilder<{
|
|
24
17
|
ctx: Context;
|
|
25
18
|
meta: object;
|
|
26
|
-
errorShape:
|
|
19
|
+
errorShape: _trpc_server5.TRPCDefaultErrorShape;
|
|
27
20
|
transformer: true;
|
|
28
21
|
}>;
|
|
29
|
-
declare const publicProcedure:
|
|
30
|
-
type AnyProcedure = typeof t.procedure;
|
|
22
|
+
declare const publicProcedure: _trpc_server5.TRPCProcedureBuilder<Context, object, object, _trpc_server5.TRPCUnsetMarker, _trpc_server5.TRPCUnsetMarker, _trpc_server5.TRPCUnsetMarker, _trpc_server5.TRPCUnsetMarker, false>;
|
|
31
23
|
//#endregion
|
|
32
|
-
//#region src/
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
24
|
+
//#region src/types/config.d.ts
|
|
25
|
+
type CrudOperation = "list" | "get" | "create" | "update" | "delete" | "deleteMany" | "updateMany";
|
|
26
|
+
type WriteOperation = "create" | "update";
|
|
27
|
+
type AnyProcedure = any;
|
|
28
|
+
interface SoftDeleteConfig {
|
|
29
|
+
/** 软删除标记列名 */
|
|
30
|
+
column: string;
|
|
31
|
+
/**
|
|
32
|
+
* 删除时设置的值
|
|
33
|
+
* - 默认: () => new Date()
|
|
34
|
+
* - 可自定义为其他值,如 true(用于 isDeleted 布尔字段)
|
|
35
|
+
*/
|
|
36
|
+
value?: () => unknown;
|
|
37
|
+
}
|
|
41
38
|
/**
|
|
42
|
-
*
|
|
39
|
+
* 软删除配置类型
|
|
40
|
+
* - string: 列名(使用默认值 new Date())
|
|
41
|
+
* - boolean: true 表示使用默认列名 'deletedAt'
|
|
42
|
+
* - SoftDeleteConfig: 完整配置
|
|
43
43
|
*/
|
|
44
|
-
|
|
44
|
+
type SoftDeleteOption = string | boolean | SoftDeleteConfig;
|
|
45
|
+
interface CrudRouterConfigBase {
|
|
46
|
+
/** Drizzle 表定义 */
|
|
45
47
|
table: PgTable;
|
|
46
|
-
|
|
48
|
+
/** 查询返回 Schema */
|
|
49
|
+
selectSchema?: z.ZodType;
|
|
50
|
+
/** 创建输入 Schema */
|
|
47
51
|
insertSchema: z.ZodType;
|
|
52
|
+
/** 更新输入 Schema */
|
|
48
53
|
updateSchema: z.ZodType;
|
|
54
|
+
/** ID 字段名,默认 "id" */
|
|
49
55
|
idField?: string;
|
|
56
|
+
/** 可过滤的列白名单 */
|
|
57
|
+
filterableColumns?: string[];
|
|
58
|
+
/** 可排序的列白名单 */
|
|
59
|
+
sortableColumns?: string[];
|
|
60
|
+
/** 批量操作的最大数量限制,默认 100 */
|
|
61
|
+
maxBatchSize?: number;
|
|
50
62
|
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
63
|
+
* 软删除配置
|
|
64
|
+
* 开启后:
|
|
65
|
+
* - delete 操作 → UPDATE ... SET {column} = {value}
|
|
66
|
+
* - deleteMany 操作 → UPDATE ... SET {column} = {value} WHERE id IN (...)
|
|
67
|
+
* - list/get 操作 → 自动添加 WHERE {column} IS NULL
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* // 使用默认列名 'deletedAt'
|
|
71
|
+
* softDelete: true
|
|
72
|
+
*
|
|
73
|
+
* // 指定列名
|
|
74
|
+
* softDelete: 'deletedAt'
|
|
75
|
+
*
|
|
76
|
+
* // 完整配置(用于布尔字段)
|
|
77
|
+
* softDelete: { column: 'isDeleted', value: () => true }
|
|
53
78
|
*/
|
|
54
|
-
|
|
79
|
+
softDelete?: SoftDeleteOption;
|
|
80
|
+
}
|
|
81
|
+
interface DeclarativeConfig<TContext = unknown> extends CrudRouterConfigBase {
|
|
82
|
+
mode?: "declarative";
|
|
55
83
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
84
|
+
* 基础 procedure(认证)
|
|
85
|
+
* 所有操作共用,除非被 guard 拦截
|
|
58
86
|
*/
|
|
59
|
-
|
|
87
|
+
procedure?: AnyProcedure;
|
|
60
88
|
/**
|
|
61
|
-
*
|
|
62
|
-
*
|
|
89
|
+
* 操作级守卫(RBAC)
|
|
90
|
+
* 在 scope 之前执行,快速拒绝无权限请求
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* guard: (ctx, op) => op === 'delete' ? ctx.user.role === 'admin' : true
|
|
63
94
|
*/
|
|
64
|
-
|
|
95
|
+
guard?: (ctx: TContext, operation: CrudOperation) => boolean | Promise<boolean>;
|
|
65
96
|
/**
|
|
66
|
-
*
|
|
67
|
-
*
|
|
97
|
+
* 行级过滤(RLS)
|
|
98
|
+
* 返回 SQL 条件,自动注入到 WHERE 子句
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* scope: (ctx, table) => eq(table.tenantId, ctx.user.tenantId)
|
|
68
102
|
*/
|
|
69
|
-
|
|
103
|
+
scope?: (ctx: TContext, table: PgTable, operation: CrudOperation) => SQL | undefined;
|
|
104
|
+
/**
|
|
105
|
+
* 强制注入字段(写入时)
|
|
106
|
+
* 返回的字段会强制覆盖用户输入(防止伪造)
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* inject: (ctx) => ({ tenantId: ctx.user.tenantId, createdBy: ctx.user.id })
|
|
110
|
+
*/
|
|
111
|
+
inject?: (ctx: TContext, operation: WriteOperation) => Record<string, unknown>;
|
|
70
112
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
113
|
+
* 资源级检查(ABAC)
|
|
114
|
+
* 在 get/update/delete 时,预取资源后调用
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* authorize: (ctx, resource, op) => resource.ownerId === ctx.user.id
|
|
73
118
|
*/
|
|
74
|
-
authorize?:
|
|
119
|
+
authorize?: (ctx: TContext, resource: Record<string, unknown>, operation: CrudOperation) => boolean | Promise<boolean>;
|
|
75
120
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
121
|
+
interface FactoryConfig<TContext = unknown> extends CrudRouterConfigBase {
|
|
122
|
+
mode: "factory";
|
|
123
|
+
/**
|
|
124
|
+
* Procedure 工厂函数
|
|
125
|
+
* 根据操作类型返回对应的 procedure
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* procedureFactory: (op) => {
|
|
129
|
+
* if (['list', 'get'].includes(op)) return publicProcedure;
|
|
130
|
+
* return protectedProcedure.meta({ permission: { action: op, subject: 'Task' } });
|
|
131
|
+
* }
|
|
132
|
+
*/
|
|
133
|
+
procedureFactory: (operation: CrudOperation) => AnyProcedure;
|
|
134
|
+
/**
|
|
135
|
+
* 强制注入字段(可选)
|
|
136
|
+
* 如果 DB 层已处理则不需要
|
|
137
|
+
*/
|
|
138
|
+
inject?: (ctx: TContext, operation: WriteOperation) => Record<string, unknown>;
|
|
139
|
+
}
|
|
140
|
+
interface ProceduresConfig<TContext = unknown> extends CrudRouterConfigBase {
|
|
141
|
+
mode: "procedures";
|
|
142
|
+
/**
|
|
143
|
+
* 按操作指定不同的 procedure
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* procedures: {
|
|
147
|
+
* list: publicProcedure,
|
|
148
|
+
* get: publicProcedure,
|
|
149
|
+
* create: editorProcedure,
|
|
150
|
+
* update: editorProcedure,
|
|
151
|
+
* delete: adminProcedure,
|
|
152
|
+
* }
|
|
153
|
+
*/
|
|
154
|
+
procedures: Partial<Record<CrudOperation, AnyProcedure>>;
|
|
155
|
+
/**
|
|
156
|
+
* 默认 procedure(未指定操作时使用)
|
|
157
|
+
*/
|
|
158
|
+
defaultProcedure?: AnyProcedure;
|
|
159
|
+
/**
|
|
160
|
+
* 强制注入字段(可选)
|
|
161
|
+
*/
|
|
162
|
+
inject?: (ctx: TContext, operation: WriteOperation) => Record<string, unknown>;
|
|
163
|
+
}
|
|
164
|
+
type CrudRouterConfig<TContext = unknown> = DeclarativeConfig<TContext> | FactoryConfig<TContext> | ProceduresConfig<TContext>;
|
|
165
|
+
//#endregion
|
|
166
|
+
//#region src/routers/_factory.d.ts
|
|
167
|
+
declare function createCrudRouter<TContext = unknown>(config: CrudRouterConfig<TContext>): node_modules__trpc_server_dist_unstable_core_do_not_import_d_CjQPvBRI_mjs0.Router<{
|
|
80
168
|
ctx: Context;
|
|
81
169
|
meta: object;
|
|
82
|
-
errorShape:
|
|
170
|
+
errorShape: _trpc_server5.TRPCDefaultErrorShape;
|
|
83
171
|
transformer: true;
|
|
84
|
-
},
|
|
85
|
-
list:
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
meta: object;
|
|
112
|
-
}>;
|
|
113
|
-
getById: _trpc_server12.TRPCQueryProcedure<{
|
|
114
|
-
input: string;
|
|
115
|
-
output: {
|
|
116
|
-
[x: string]: unknown;
|
|
117
|
-
} | null;
|
|
118
|
-
meta: object;
|
|
119
|
-
}>;
|
|
120
|
-
create: _trpc_server12.TRPCMutationProcedure<{
|
|
121
|
-
input: unknown;
|
|
122
|
-
output: {
|
|
123
|
-
[x: string]: unknown;
|
|
124
|
-
} | undefined;
|
|
125
|
-
meta: object;
|
|
126
|
-
}>;
|
|
127
|
-
update: _trpc_server12.TRPCMutationProcedure<{
|
|
128
|
-
input: {
|
|
129
|
-
id: string;
|
|
130
|
-
data: unknown;
|
|
131
|
-
};
|
|
132
|
-
output: {
|
|
133
|
-
[x: string]: unknown;
|
|
134
|
-
} | undefined;
|
|
135
|
-
meta: object;
|
|
136
|
-
}>;
|
|
137
|
-
delete: _trpc_server12.TRPCMutationProcedure<{
|
|
138
|
-
input: string;
|
|
139
|
-
output: {
|
|
140
|
-
[x: string]: unknown;
|
|
141
|
-
} | undefined;
|
|
142
|
-
meta: object;
|
|
143
|
-
}>;
|
|
144
|
-
deleteMany: _trpc_server12.TRPCMutationProcedure<{
|
|
145
|
-
input: string[];
|
|
146
|
-
output: {
|
|
147
|
-
deleted: number;
|
|
148
|
-
};
|
|
149
|
-
meta: object;
|
|
150
|
-
}>;
|
|
151
|
-
updateMany: _trpc_server12.TRPCMutationProcedure<{
|
|
152
|
-
input: {
|
|
153
|
-
ids: string[];
|
|
154
|
-
data: unknown;
|
|
155
|
-
};
|
|
156
|
-
output: {
|
|
157
|
-
updated: number;
|
|
158
|
-
};
|
|
159
|
-
meta: object;
|
|
160
|
-
}>;
|
|
161
|
-
}>>;
|
|
172
|
+
}, _trpc_server5.TRPCDecorateCreateRouterOptions<{
|
|
173
|
+
list: any;
|
|
174
|
+
getById: any;
|
|
175
|
+
create: any;
|
|
176
|
+
update: any;
|
|
177
|
+
delete: any;
|
|
178
|
+
deleteMany: any;
|
|
179
|
+
updateMany: any;
|
|
180
|
+
}>> & _trpc_server5.TRPCDecorateCreateRouterOptions<{
|
|
181
|
+
list: any;
|
|
182
|
+
getById: any;
|
|
183
|
+
create: any;
|
|
184
|
+
update: any;
|
|
185
|
+
delete: any;
|
|
186
|
+
deleteMany: any;
|
|
187
|
+
updateMany: any;
|
|
188
|
+
}> & {
|
|
189
|
+
procedures: {
|
|
190
|
+
list: any;
|
|
191
|
+
getById: any;
|
|
192
|
+
create: any;
|
|
193
|
+
update: any;
|
|
194
|
+
delete: any;
|
|
195
|
+
deleteMany: any;
|
|
196
|
+
updateMany: any;
|
|
197
|
+
};
|
|
198
|
+
};
|
|
162
199
|
//#endregion
|
|
163
200
|
//#region src/routers/index.d.ts
|
|
164
|
-
declare const appRouter:
|
|
201
|
+
declare const appRouter: _trpc_server5.TRPCBuiltRouter<{
|
|
165
202
|
ctx: Context;
|
|
166
203
|
meta: object;
|
|
167
|
-
errorShape:
|
|
204
|
+
errorShape: _trpc_server5.TRPCDefaultErrorShape;
|
|
168
205
|
transformer: true;
|
|
169
|
-
},
|
|
206
|
+
}, _trpc_server5.TRPCDecorateCreateRouterOptions<{}>>;
|
|
170
207
|
type AppRouter = typeof appRouter;
|
|
171
208
|
//#endregion
|
|
172
|
-
export { type AnyProcedure, type AppRouter, type
|
|
209
|
+
export { type AnyProcedure, type AppRouter, type CrudOperation, type CrudRouterConfig, type DeclarativeConfig, type FactoryConfig, type ProceduresConfig, type SoftDeleteConfig, type SoftDeleteOption, type WriteOperation, appRouter, createCrudRouter, publicProcedure, router };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import
|
|
2
|
+
import { SQL } from "drizzle-orm";
|
|
3
|
+
import * as _trpc_server5 from "@trpc/server";
|
|
3
4
|
import superjson from "superjson";
|
|
4
5
|
import { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
6
|
+
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";
|
|
5
7
|
import { PgTable } from "drizzle-orm/pg-core";
|
|
6
8
|
|
|
7
9
|
//#region src/trpc.d.ts
|
|
@@ -12,161 +14,197 @@ import { PgTable } from "drizzle-orm/pg-core";
|
|
|
12
14
|
interface Context {
|
|
13
15
|
db: PostgresJsDatabase<Record<string, never>>;
|
|
14
16
|
}
|
|
15
|
-
declare const
|
|
16
|
-
transformer: typeof superjson;
|
|
17
|
-
}, {
|
|
17
|
+
declare const router: _trpc_server5.TRPCRouterBuilder<{
|
|
18
18
|
ctx: Context;
|
|
19
19
|
meta: object;
|
|
20
|
-
errorShape:
|
|
20
|
+
errorShape: _trpc_server5.TRPCDefaultErrorShape;
|
|
21
21
|
transformer: true;
|
|
22
22
|
}>;
|
|
23
|
-
declare const
|
|
24
|
-
ctx: Context;
|
|
25
|
-
meta: object;
|
|
26
|
-
errorShape: _trpc_server2.TRPCDefaultErrorShape;
|
|
27
|
-
transformer: true;
|
|
28
|
-
}>;
|
|
29
|
-
declare const publicProcedure: _trpc_server2.TRPCProcedureBuilder<Context, object, object, _trpc_server2.TRPCUnsetMarker, _trpc_server2.TRPCUnsetMarker, _trpc_server2.TRPCUnsetMarker, _trpc_server2.TRPCUnsetMarker, false>;
|
|
30
|
-
type AnyProcedure = typeof t.procedure;
|
|
23
|
+
declare const publicProcedure: _trpc_server5.TRPCProcedureBuilder<Context, object, object, _trpc_server5.TRPCUnsetMarker, _trpc_server5.TRPCUnsetMarker, _trpc_server5.TRPCUnsetMarker, _trpc_server5.TRPCUnsetMarker, false>;
|
|
31
24
|
//#endregion
|
|
32
|
-
//#region src/
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
25
|
+
//#region src/types/config.d.ts
|
|
26
|
+
type CrudOperation = "list" | "get" | "create" | "update" | "delete" | "deleteMany" | "updateMany";
|
|
27
|
+
type WriteOperation = "create" | "update";
|
|
28
|
+
type AnyProcedure = any;
|
|
29
|
+
interface SoftDeleteConfig {
|
|
30
|
+
/** 软删除标记列名 */
|
|
31
|
+
column: string;
|
|
32
|
+
/**
|
|
33
|
+
* 删除时设置的值
|
|
34
|
+
* - 默认: () => new Date()
|
|
35
|
+
* - 可自定义为其他值,如 true(用于 isDeleted 布尔字段)
|
|
36
|
+
*/
|
|
37
|
+
value?: () => unknown;
|
|
38
|
+
}
|
|
41
39
|
/**
|
|
42
|
-
*
|
|
40
|
+
* 软删除配置类型
|
|
41
|
+
* - string: 列名(使用默认值 new Date())
|
|
42
|
+
* - boolean: true 表示使用默认列名 'deletedAt'
|
|
43
|
+
* - SoftDeleteConfig: 完整配置
|
|
43
44
|
*/
|
|
44
|
-
|
|
45
|
+
type SoftDeleteOption = string | boolean | SoftDeleteConfig;
|
|
46
|
+
interface CrudRouterConfigBase {
|
|
47
|
+
/** Drizzle 表定义 */
|
|
45
48
|
table: PgTable;
|
|
46
|
-
|
|
49
|
+
/** 查询返回 Schema */
|
|
50
|
+
selectSchema?: z.ZodType;
|
|
51
|
+
/** 创建输入 Schema */
|
|
47
52
|
insertSchema: z.ZodType;
|
|
53
|
+
/** 更新输入 Schema */
|
|
48
54
|
updateSchema: z.ZodType;
|
|
55
|
+
/** ID 字段名,默认 "id" */
|
|
49
56
|
idField?: string;
|
|
57
|
+
/** 可过滤的列白名单 */
|
|
58
|
+
filterableColumns?: string[];
|
|
59
|
+
/** 可排序的列白名单 */
|
|
60
|
+
sortableColumns?: string[];
|
|
61
|
+
/** 批量操作的最大数量限制,默认 100 */
|
|
62
|
+
maxBatchSize?: number;
|
|
50
63
|
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
64
|
+
* 软删除配置
|
|
65
|
+
* 开启后:
|
|
66
|
+
* - delete 操作 → UPDATE ... SET {column} = {value}
|
|
67
|
+
* - deleteMany 操作 → UPDATE ... SET {column} = {value} WHERE id IN (...)
|
|
68
|
+
* - list/get 操作 → 自动添加 WHERE {column} IS NULL
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* // 使用默认列名 'deletedAt'
|
|
72
|
+
* softDelete: true
|
|
73
|
+
*
|
|
74
|
+
* // 指定列名
|
|
75
|
+
* softDelete: 'deletedAt'
|
|
76
|
+
*
|
|
77
|
+
* // 完整配置(用于布尔字段)
|
|
78
|
+
* softDelete: { column: 'isDeleted', value: () => true }
|
|
53
79
|
*/
|
|
54
|
-
|
|
80
|
+
softDelete?: SoftDeleteOption;
|
|
81
|
+
}
|
|
82
|
+
interface DeclarativeConfig<TContext = unknown> extends CrudRouterConfigBase {
|
|
83
|
+
mode?: "declarative";
|
|
55
84
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
85
|
+
* 基础 procedure(认证)
|
|
86
|
+
* 所有操作共用,除非被 guard 拦截
|
|
58
87
|
*/
|
|
59
|
-
|
|
88
|
+
procedure?: AnyProcedure;
|
|
60
89
|
/**
|
|
61
|
-
*
|
|
62
|
-
*
|
|
90
|
+
* 操作级守卫(RBAC)
|
|
91
|
+
* 在 scope 之前执行,快速拒绝无权限请求
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* guard: (ctx, op) => op === 'delete' ? ctx.user.role === 'admin' : true
|
|
63
95
|
*/
|
|
64
|
-
|
|
96
|
+
guard?: (ctx: TContext, operation: CrudOperation) => boolean | Promise<boolean>;
|
|
65
97
|
/**
|
|
66
|
-
*
|
|
67
|
-
*
|
|
98
|
+
* 行级过滤(RLS)
|
|
99
|
+
* 返回 SQL 条件,自动注入到 WHERE 子句
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* scope: (ctx, table) => eq(table.tenantId, ctx.user.tenantId)
|
|
68
103
|
*/
|
|
69
|
-
|
|
104
|
+
scope?: (ctx: TContext, table: PgTable, operation: CrudOperation) => SQL | undefined;
|
|
70
105
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
106
|
+
* 强制注入字段(写入时)
|
|
107
|
+
* 返回的字段会强制覆盖用户输入(防止伪造)
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* inject: (ctx) => ({ tenantId: ctx.user.tenantId, createdBy: ctx.user.id })
|
|
73
111
|
*/
|
|
74
|
-
|
|
112
|
+
inject?: (ctx: TContext, operation: WriteOperation) => Record<string, unknown>;
|
|
113
|
+
/**
|
|
114
|
+
* 资源级检查(ABAC)
|
|
115
|
+
* 在 get/update/delete 时,预取资源后调用
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* authorize: (ctx, resource, op) => resource.ownerId === ctx.user.id
|
|
119
|
+
*/
|
|
120
|
+
authorize?: (ctx: TContext, resource: Record<string, unknown>, operation: CrudOperation) => boolean | Promise<boolean>;
|
|
75
121
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
122
|
+
interface FactoryConfig<TContext = unknown> extends CrudRouterConfigBase {
|
|
123
|
+
mode: "factory";
|
|
124
|
+
/**
|
|
125
|
+
* Procedure 工厂函数
|
|
126
|
+
* 根据操作类型返回对应的 procedure
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* procedureFactory: (op) => {
|
|
130
|
+
* if (['list', 'get'].includes(op)) return publicProcedure;
|
|
131
|
+
* return protectedProcedure.meta({ permission: { action: op, subject: 'Task' } });
|
|
132
|
+
* }
|
|
133
|
+
*/
|
|
134
|
+
procedureFactory: (operation: CrudOperation) => AnyProcedure;
|
|
135
|
+
/**
|
|
136
|
+
* 强制注入字段(可选)
|
|
137
|
+
* 如果 DB 层已处理则不需要
|
|
138
|
+
*/
|
|
139
|
+
inject?: (ctx: TContext, operation: WriteOperation) => Record<string, unknown>;
|
|
140
|
+
}
|
|
141
|
+
interface ProceduresConfig<TContext = unknown> extends CrudRouterConfigBase {
|
|
142
|
+
mode: "procedures";
|
|
143
|
+
/**
|
|
144
|
+
* 按操作指定不同的 procedure
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* procedures: {
|
|
148
|
+
* list: publicProcedure,
|
|
149
|
+
* get: publicProcedure,
|
|
150
|
+
* create: editorProcedure,
|
|
151
|
+
* update: editorProcedure,
|
|
152
|
+
* delete: adminProcedure,
|
|
153
|
+
* }
|
|
154
|
+
*/
|
|
155
|
+
procedures: Partial<Record<CrudOperation, AnyProcedure>>;
|
|
156
|
+
/**
|
|
157
|
+
* 默认 procedure(未指定操作时使用)
|
|
158
|
+
*/
|
|
159
|
+
defaultProcedure?: AnyProcedure;
|
|
160
|
+
/**
|
|
161
|
+
* 强制注入字段(可选)
|
|
162
|
+
*/
|
|
163
|
+
inject?: (ctx: TContext, operation: WriteOperation) => Record<string, unknown>;
|
|
164
|
+
}
|
|
165
|
+
type CrudRouterConfig<TContext = unknown> = DeclarativeConfig<TContext> | FactoryConfig<TContext> | ProceduresConfig<TContext>;
|
|
166
|
+
//#endregion
|
|
167
|
+
//#region src/routers/_factory.d.ts
|
|
168
|
+
declare function createCrudRouter<TContext = unknown>(config: CrudRouterConfig<TContext>): node_modules__trpc_server_dist_unstable_core_do_not_import_d_CjQPvBRI_mjs0.Router<{
|
|
80
169
|
ctx: Context;
|
|
81
170
|
meta: object;
|
|
82
|
-
errorShape:
|
|
171
|
+
errorShape: _trpc_server5.TRPCDefaultErrorShape;
|
|
83
172
|
transformer: true;
|
|
84
|
-
},
|
|
85
|
-
list:
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
meta: object;
|
|
112
|
-
}>;
|
|
113
|
-
getById: _trpc_server2.TRPCQueryProcedure<{
|
|
114
|
-
input: string;
|
|
115
|
-
output: {
|
|
116
|
-
[x: string]: unknown;
|
|
117
|
-
} | null;
|
|
118
|
-
meta: object;
|
|
119
|
-
}>;
|
|
120
|
-
create: _trpc_server2.TRPCMutationProcedure<{
|
|
121
|
-
input: unknown;
|
|
122
|
-
output: {
|
|
123
|
-
[x: string]: unknown;
|
|
124
|
-
} | undefined;
|
|
125
|
-
meta: object;
|
|
126
|
-
}>;
|
|
127
|
-
update: _trpc_server2.TRPCMutationProcedure<{
|
|
128
|
-
input: {
|
|
129
|
-
id: string;
|
|
130
|
-
data: unknown;
|
|
131
|
-
};
|
|
132
|
-
output: {
|
|
133
|
-
[x: string]: unknown;
|
|
134
|
-
} | undefined;
|
|
135
|
-
meta: object;
|
|
136
|
-
}>;
|
|
137
|
-
delete: _trpc_server2.TRPCMutationProcedure<{
|
|
138
|
-
input: string;
|
|
139
|
-
output: {
|
|
140
|
-
[x: string]: unknown;
|
|
141
|
-
} | undefined;
|
|
142
|
-
meta: object;
|
|
143
|
-
}>;
|
|
144
|
-
deleteMany: _trpc_server2.TRPCMutationProcedure<{
|
|
145
|
-
input: string[];
|
|
146
|
-
output: {
|
|
147
|
-
deleted: number;
|
|
148
|
-
};
|
|
149
|
-
meta: object;
|
|
150
|
-
}>;
|
|
151
|
-
updateMany: _trpc_server2.TRPCMutationProcedure<{
|
|
152
|
-
input: {
|
|
153
|
-
ids: string[];
|
|
154
|
-
data: unknown;
|
|
155
|
-
};
|
|
156
|
-
output: {
|
|
157
|
-
updated: number;
|
|
158
|
-
};
|
|
159
|
-
meta: object;
|
|
160
|
-
}>;
|
|
161
|
-
}>>;
|
|
173
|
+
}, _trpc_server5.TRPCDecorateCreateRouterOptions<{
|
|
174
|
+
list: any;
|
|
175
|
+
getById: any;
|
|
176
|
+
create: any;
|
|
177
|
+
update: any;
|
|
178
|
+
delete: any;
|
|
179
|
+
deleteMany: any;
|
|
180
|
+
updateMany: any;
|
|
181
|
+
}>> & _trpc_server5.TRPCDecorateCreateRouterOptions<{
|
|
182
|
+
list: any;
|
|
183
|
+
getById: any;
|
|
184
|
+
create: any;
|
|
185
|
+
update: any;
|
|
186
|
+
delete: any;
|
|
187
|
+
deleteMany: any;
|
|
188
|
+
updateMany: any;
|
|
189
|
+
}> & {
|
|
190
|
+
procedures: {
|
|
191
|
+
list: any;
|
|
192
|
+
getById: any;
|
|
193
|
+
create: any;
|
|
194
|
+
update: any;
|
|
195
|
+
delete: any;
|
|
196
|
+
deleteMany: any;
|
|
197
|
+
updateMany: any;
|
|
198
|
+
};
|
|
199
|
+
};
|
|
162
200
|
//#endregion
|
|
163
201
|
//#region src/routers/index.d.ts
|
|
164
|
-
declare const appRouter:
|
|
202
|
+
declare const appRouter: _trpc_server5.TRPCBuiltRouter<{
|
|
165
203
|
ctx: Context;
|
|
166
204
|
meta: object;
|
|
167
|
-
errorShape:
|
|
205
|
+
errorShape: _trpc_server5.TRPCDefaultErrorShape;
|
|
168
206
|
transformer: true;
|
|
169
|
-
},
|
|
207
|
+
}, _trpc_server5.TRPCDecorateCreateRouterOptions<{}>>;
|
|
170
208
|
type AppRouter = typeof appRouter;
|
|
171
209
|
//#endregion
|
|
172
|
-
export { type AnyProcedure, type AppRouter, type
|
|
210
|
+
export { type AnyProcedure, type AppRouter, type CrudOperation, type CrudRouterConfig, type DeclarativeConfig, type FactoryConfig, type ProceduresConfig, type SoftDeleteConfig, type SoftDeleteOption, type WriteOperation, appRouter, createCrudRouter, publicProcedure, router };
|