@wordrhyme/auto-crud-server 0.4.0 → 0.6.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 +124 -1
- package/dist/index.cjs +240 -95
- package/dist/index.d.cts +232 -72
- package/dist/index.d.ts +242 -82
- package/dist/index.js +231 -96
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -608,6 +608,110 @@ export const tasksRouter = router({
|
|
|
608
608
|
|
|
609
609
|
---
|
|
610
610
|
|
|
611
|
+
## 🔄 生命周期中间件
|
|
612
|
+
|
|
613
|
+
使用 `middleware` 配置在 CRUD 操作前后注入自定义逻辑,类似 tRPC middleware 模式。
|
|
614
|
+
|
|
615
|
+
### 完整控制模式
|
|
616
|
+
|
|
617
|
+
```typescript
|
|
618
|
+
import { createCrudRouter } from "@wordrhyme/auto-crud-server";
|
|
619
|
+
|
|
620
|
+
const tasksRouter = createCrudRouter({
|
|
621
|
+
table: tasks,
|
|
622
|
+
insertSchema: insertTaskSchema,
|
|
623
|
+
updateSchema: updateTaskSchema,
|
|
624
|
+
|
|
625
|
+
// 中间件:完全控制操作流程
|
|
626
|
+
middleware: {
|
|
627
|
+
// 创建:修改输入 + 执行副作用
|
|
628
|
+
create: async ({ ctx, input, next }) => {
|
|
629
|
+
// 1. 修改输入数据
|
|
630
|
+
const data = { ...input, slug: slugify(input.title), createdBy: ctx.user.id };
|
|
631
|
+
|
|
632
|
+
// 2. 执行核心操作
|
|
633
|
+
const result = await next(data);
|
|
634
|
+
|
|
635
|
+
// 3. 执行副作用
|
|
636
|
+
await sendNotification(result);
|
|
637
|
+
await logAudit(ctx.user, "create", result);
|
|
638
|
+
|
|
639
|
+
// 4. 返回结果(可修改)
|
|
640
|
+
return result;
|
|
641
|
+
},
|
|
642
|
+
|
|
643
|
+
// 更新:可访问原记录
|
|
644
|
+
update: async ({ ctx, id, data, existing, next }) => {
|
|
645
|
+
// 检查权限
|
|
646
|
+
if (existing.ownerId !== ctx.user.id) {
|
|
647
|
+
throw new Error("Forbidden");
|
|
648
|
+
}
|
|
649
|
+
return next(data);
|
|
650
|
+
},
|
|
651
|
+
|
|
652
|
+
// 删除:条件拦截
|
|
653
|
+
delete: async ({ ctx, id, existing, next }) => {
|
|
654
|
+
if (existing.status === "locked") {
|
|
655
|
+
throw new Error("Cannot delete locked resource");
|
|
656
|
+
}
|
|
657
|
+
return next();
|
|
658
|
+
},
|
|
659
|
+
},
|
|
660
|
+
});
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
### 使用便捷工具函数
|
|
664
|
+
|
|
665
|
+
对于简单场景,使用工具函数简化代码:
|
|
666
|
+
|
|
667
|
+
```typescript
|
|
668
|
+
import {
|
|
669
|
+
createCrudRouter,
|
|
670
|
+
afterMiddleware,
|
|
671
|
+
beforeMiddleware,
|
|
672
|
+
afterCreate,
|
|
673
|
+
beforeCreate,
|
|
674
|
+
} from "@wordrhyme/auto-crud-server";
|
|
675
|
+
|
|
676
|
+
const tasksRouter = createCrudRouter({
|
|
677
|
+
table: tasks,
|
|
678
|
+
insertSchema: insertTaskSchema,
|
|
679
|
+
updateSchema: updateTaskSchema,
|
|
680
|
+
|
|
681
|
+
middleware: {
|
|
682
|
+
// 简单副作用:只在操作后执行
|
|
683
|
+
create: afterMiddleware(async (ctx, result) => {
|
|
684
|
+
await sendEmail(result);
|
|
685
|
+
await logAudit(ctx.user, "create", result);
|
|
686
|
+
}),
|
|
687
|
+
|
|
688
|
+
// 修改输入:只在操作前执行
|
|
689
|
+
update: beforeMiddleware(async (ctx, data) => {
|
|
690
|
+
return { ...data, updatedAt: new Date(), updatedBy: ctx.user.id };
|
|
691
|
+
}),
|
|
692
|
+
|
|
693
|
+
// 类型安全的便捷函数
|
|
694
|
+
delete: afterDelete(async (ctx, deleted) => {
|
|
695
|
+
await cleanupRelatedData(deleted.id);
|
|
696
|
+
}),
|
|
697
|
+
},
|
|
698
|
+
});
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
### 可用的工具函数
|
|
702
|
+
|
|
703
|
+
| 函数 | 用途 | 示例 |
|
|
704
|
+
|------|------|------|
|
|
705
|
+
| `afterMiddleware(fn)` | 操作后执行副作用 | 日志、通知、审计 |
|
|
706
|
+
| `afterMiddlewareTransform(fn)` | 操作后修改返回值 | 添加计算字段 |
|
|
707
|
+
| `beforeMiddleware(fn)` | 操作前修改输入 | 注入用户ID、生成slug |
|
|
708
|
+
| `composeMiddleware(...fns)` | 组合多个中间件 | 复杂场景 |
|
|
709
|
+
| `afterList`, `beforeList` | list 操作专用 | 分页后处理 |
|
|
710
|
+
| `afterCreate`, `beforeCreate` | create 操作专用 | 创建通知 |
|
|
711
|
+
| `afterUpdate`, `afterDelete` | update/delete 专用 | 更新/删除通知 |
|
|
712
|
+
|
|
713
|
+
---
|
|
714
|
+
|
|
611
715
|
## 🔌 与其他库集成
|
|
612
716
|
|
|
613
717
|
### 与 Drizzle ORM 集成
|
|
@@ -698,7 +802,26 @@ export const filterVariants = {
|
|
|
698
802
|
```typescript
|
|
699
803
|
// 主要导出
|
|
700
804
|
export { createCrudRouter } from "./routers/_factory";
|
|
701
|
-
export type {
|
|
805
|
+
export type {
|
|
806
|
+
CrudRouterConfig,
|
|
807
|
+
CrudMiddleware,
|
|
808
|
+
ListInput,
|
|
809
|
+
ListResult,
|
|
810
|
+
} from "./types/config";
|
|
811
|
+
|
|
812
|
+
// Middleware 工具函数
|
|
813
|
+
export {
|
|
814
|
+
afterMiddleware,
|
|
815
|
+
afterMiddlewareTransform,
|
|
816
|
+
beforeMiddleware,
|
|
817
|
+
composeMiddleware,
|
|
818
|
+
afterList,
|
|
819
|
+
beforeList,
|
|
820
|
+
afterCreate,
|
|
821
|
+
beforeCreate,
|
|
822
|
+
afterUpdate,
|
|
823
|
+
afterDelete,
|
|
824
|
+
} from "./lib/middleware-helpers";
|
|
702
825
|
|
|
703
826
|
// tRPC 工具
|
|
704
827
|
export { router, publicProcedure } from "./trpc";
|
package/dist/index.cjs
CHANGED
|
@@ -475,10 +475,10 @@ function validateColumn(columnId, allowedColumns) {
|
|
|
475
475
|
return allowedColumns.includes(columnId);
|
|
476
476
|
}
|
|
477
477
|
function createCrudRouter(config) {
|
|
478
|
-
const { table, insertSchema, updateSchema, idField = "id", filterableColumns, sortableColumns, maxBatchSize = 100, softDelete: softDeleteOption,
|
|
478
|
+
const { table, insertSchema, updateSchema, idField = "id", filterableColumns, sortableColumns, maxBatchSize = 100, softDelete: softDeleteOption, middleware = {} } = config;
|
|
479
479
|
const resolved = resolveConfig(config);
|
|
480
480
|
const softDelete = resolveSoftDelete(softDeleteOption);
|
|
481
|
-
const
|
|
481
|
+
const m = middleware;
|
|
482
482
|
const getIdColumn = () => table[idField];
|
|
483
483
|
const getSoftDeleteColumn = () => softDelete ? table[softDelete.column] : null;
|
|
484
484
|
const buildWhere = (ctx, operation, additionalCondition) => {
|
|
@@ -506,72 +506,75 @@ function createCrudRouter(config) {
|
|
|
506
506
|
const procedures = {
|
|
507
507
|
list: resolved.procedureFactory("list").input(listInputSchema).query(async ({ ctx, input }) => {
|
|
508
508
|
await withGuard(ctx, "list");
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
const
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
table
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
if (sortField && validateColumn(sortField.id, sortableColumns)) {
|
|
526
|
-
const column = table[sortField.id];
|
|
527
|
-
if (column) query = query.orderBy(sortField.desc ? (0, drizzle_orm.desc)(column) : (0, drizzle_orm.asc)(column));
|
|
509
|
+
const doList = async (listInput$1) => {
|
|
510
|
+
const offset = (listInput$1.page - 1) * listInput$1.perPage;
|
|
511
|
+
const validatedFilters = listInput$1.filters?.filter((filter) => validateColumn(filter.id, filterableColumns));
|
|
512
|
+
const where = buildWhere(ctx, "list", validatedFilters?.length ? filterColumns({
|
|
513
|
+
table,
|
|
514
|
+
filters: validatedFilters,
|
|
515
|
+
joinOperator: listInput$1.joinOperator
|
|
516
|
+
}) : void 0);
|
|
517
|
+
let query = ctx.db.select().from(table).$dynamic();
|
|
518
|
+
if (where) query = query.where(where);
|
|
519
|
+
if (listInput$1.sort?.length) {
|
|
520
|
+
const sortField = listInput$1.sort[0];
|
|
521
|
+
if (sortField && validateColumn(sortField.id, sortableColumns)) {
|
|
522
|
+
const column = table[sortField.id];
|
|
523
|
+
if (column) query = query.orderBy(sortField.desc ? (0, drizzle_orm.desc)(column) : (0, drizzle_orm.asc)(column));
|
|
524
|
+
}
|
|
528
525
|
}
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
526
|
+
const data = await query.limit(listInput$1.perPage).offset(offset);
|
|
527
|
+
let countQuery = ctx.db.select({ count: drizzle_orm.sql`count(*)::int` }).from(table).$dynamic();
|
|
528
|
+
if (where) countQuery = countQuery.where(where);
|
|
529
|
+
const count = (await countQuery)[0]?.count ?? 0;
|
|
530
|
+
return {
|
|
531
|
+
data,
|
|
532
|
+
total: count,
|
|
533
|
+
page: listInput$1.page,
|
|
534
|
+
perPage: listInput$1.perPage,
|
|
535
|
+
pageCount: Math.ceil(count / listInput$1.perPage)
|
|
536
|
+
};
|
|
540
537
|
};
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
538
|
+
const listInput = input;
|
|
539
|
+
if (m.list) return m.list({
|
|
540
|
+
ctx,
|
|
541
|
+
input: listInput,
|
|
542
|
+
next: async (modifiedInput) => doList(modifiedInput ?? listInput)
|
|
543
|
+
});
|
|
544
|
+
return doList(listInput);
|
|
546
545
|
}),
|
|
547
546
|
getById: resolved.procedureFactory("get").input(zod.z.string()).query(async ({ ctx, input }) => {
|
|
548
547
|
await withGuard(ctx, "get");
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
548
|
+
const doGet = async () => {
|
|
549
|
+
const where = buildWhere(ctx, "get", (0, drizzle_orm.eq)(getIdColumn(), input));
|
|
550
|
+
const [item] = await ctx.db.select().from(table).where(where);
|
|
551
|
+
await withAuthorize(ctx, item, "get");
|
|
552
|
+
return item ?? null;
|
|
553
|
+
};
|
|
554
|
+
if (m.get) return m.get({
|
|
555
|
+
ctx,
|
|
556
|
+
id: input,
|
|
557
|
+
next: doGet
|
|
558
|
+
});
|
|
559
|
+
return doGet();
|
|
559
560
|
}),
|
|
560
561
|
create: resolved.procedureFactory("create").input(insertSchema).mutation(async ({ ctx, input }) => {
|
|
561
562
|
await withGuard(ctx, "create");
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
const
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
...injectData
|
|
563
|
+
const doCreate = async (inputData) => {
|
|
564
|
+
const injectData = resolved.getInject(ctx, "create");
|
|
565
|
+
const data = {
|
|
566
|
+
...inputData,
|
|
567
|
+
...injectData
|
|
568
|
+
};
|
|
569
|
+
const [created] = await ctx.db.insert(table).values(data).returning();
|
|
570
|
+
return created;
|
|
571
571
|
};
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
572
|
+
if (m.create) return m.create({
|
|
573
|
+
ctx,
|
|
574
|
+
input,
|
|
575
|
+
next: async (modifiedInput) => doCreate(modifiedInput ?? input)
|
|
576
|
+
});
|
|
577
|
+
return doCreate(input);
|
|
575
578
|
}),
|
|
576
579
|
update: resolved.procedureFactory("update").input(zod.z.object({
|
|
577
580
|
id: zod.z.string(),
|
|
@@ -582,19 +585,23 @@ function createCrudRouter(config) {
|
|
|
582
585
|
const [existing] = await ctx.db.select().from(table).where(where);
|
|
583
586
|
await withAuthorize(ctx, existing, "update");
|
|
584
587
|
if (!existing) throw new Error("Resource not found or access denied");
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
const
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
...injectData
|
|
588
|
+
const doUpdate = async (updateData) => {
|
|
589
|
+
const injectData = resolved.getInject(ctx, "update");
|
|
590
|
+
const data = {
|
|
591
|
+
...updateData,
|
|
592
|
+
...injectData
|
|
593
|
+
};
|
|
594
|
+
const [updated] = await ctx.db.update(table).set(data).where(where).returning();
|
|
595
|
+
return updated;
|
|
594
596
|
};
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
597
|
+
if (m.update) return m.update({
|
|
598
|
+
ctx,
|
|
599
|
+
id: input.id,
|
|
600
|
+
data: input.data,
|
|
601
|
+
existing,
|
|
602
|
+
next: async (modifiedData) => doUpdate(modifiedData ?? input.data)
|
|
603
|
+
});
|
|
604
|
+
return doUpdate(input.data);
|
|
598
605
|
}),
|
|
599
606
|
delete: resolved.procedureFactory("delete").input(zod.z.string()).mutation(async ({ ctx, input }) => {
|
|
600
607
|
await withGuard(ctx, "delete");
|
|
@@ -602,54 +609,192 @@ function createCrudRouter(config) {
|
|
|
602
609
|
const [existing] = await ctx.db.select().from(table).where(where);
|
|
603
610
|
await withAuthorize(ctx, existing, "delete");
|
|
604
611
|
if (!existing) throw new Error("Resource not found or access denied");
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
612
|
+
const doDelete = async () => {
|
|
613
|
+
let deleted;
|
|
614
|
+
if (softDelete) [deleted] = await ctx.db.update(table).set({ [softDelete.column]: softDelete.getValue() }).where(where).returning();
|
|
615
|
+
else [deleted] = await ctx.db.delete(table).where(where).returning();
|
|
616
|
+
return deleted;
|
|
617
|
+
};
|
|
618
|
+
if (m.delete) return m.delete({
|
|
619
|
+
ctx,
|
|
620
|
+
id: input,
|
|
621
|
+
existing,
|
|
622
|
+
next: doDelete
|
|
623
|
+
});
|
|
624
|
+
return doDelete();
|
|
611
625
|
}),
|
|
612
626
|
deleteMany: resolved.procedureFactory("deleteMany").input(zod.z.array(zod.z.string()).max(maxBatchSize)).mutation(async ({ ctx, input }) => {
|
|
613
627
|
await withGuard(ctx, "deleteMany");
|
|
614
|
-
if (h.beforeDeleteMany) await h.beforeDeleteMany(ctx, input);
|
|
615
628
|
const where = buildWhere(ctx, "deleteMany", (0, drizzle_orm.inArray)(getIdColumn(), input));
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
return
|
|
629
|
+
const doDeleteMany = async () => {
|
|
630
|
+
if (softDelete) return { deleted: (await ctx.db.update(table).set({ [softDelete.column]: softDelete.getValue() }).where(where).returning()).length };
|
|
631
|
+
else return { deleted: (await ctx.db.delete(table).where(where).returning()).length };
|
|
632
|
+
};
|
|
633
|
+
if (m.deleteMany) return m.deleteMany({
|
|
634
|
+
ctx,
|
|
635
|
+
ids: input,
|
|
636
|
+
next: doDeleteMany
|
|
637
|
+
});
|
|
638
|
+
return doDeleteMany();
|
|
621
639
|
}),
|
|
622
640
|
updateMany: resolved.procedureFactory("updateMany").input(zod.z.object({
|
|
623
641
|
ids: zod.z.array(zod.z.string()).max(maxBatchSize),
|
|
624
642
|
data: updateSchema
|
|
625
643
|
})).mutation(async ({ ctx, input }) => {
|
|
626
644
|
await withGuard(ctx, "updateMany");
|
|
627
|
-
let processedData = input.data;
|
|
628
|
-
if (h.beforeUpdateMany) {
|
|
629
|
-
const result$1 = await h.beforeUpdateMany(ctx, input.ids, processedData);
|
|
630
|
-
if (result$1) processedData = result$1;
|
|
631
|
-
}
|
|
632
645
|
const where = buildWhere(ctx, "updateMany", (0, drizzle_orm.inArray)(getIdColumn(), input.ids));
|
|
633
|
-
const
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
646
|
+
const doUpdateMany = async (updateData) => {
|
|
647
|
+
const injectData = resolved.getInject(ctx, "update");
|
|
648
|
+
const data = {
|
|
649
|
+
...updateData,
|
|
650
|
+
...injectData
|
|
651
|
+
};
|
|
652
|
+
return { updated: (await ctx.db.update(table).set(data).where(where).returning()).length };
|
|
637
653
|
};
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
654
|
+
if (m.updateMany) return m.updateMany({
|
|
655
|
+
ctx,
|
|
656
|
+
ids: input.ids,
|
|
657
|
+
data: input.data,
|
|
658
|
+
next: async (modifiedData) => doUpdateMany(modifiedData ?? input.data)
|
|
659
|
+
});
|
|
660
|
+
return doUpdateMany(input.data);
|
|
641
661
|
})
|
|
642
662
|
};
|
|
643
663
|
const crudRouter = router(procedures);
|
|
644
664
|
return Object.assign(crudRouter, { procedures });
|
|
645
665
|
}
|
|
646
666
|
|
|
667
|
+
//#endregion
|
|
668
|
+
//#region src/lib/middleware-helpers.ts
|
|
669
|
+
/**
|
|
670
|
+
* 创建 after-only 的 middleware(最常见场景)
|
|
671
|
+
* 在操作完成后执行副作用,不修改返回值
|
|
672
|
+
*
|
|
673
|
+
* @example
|
|
674
|
+
* middleware: {
|
|
675
|
+
* create: afterMiddleware(async (ctx, result) => {
|
|
676
|
+
* await sendEmail(result);
|
|
677
|
+
* await logAudit(ctx.user, 'create', result);
|
|
678
|
+
* }),
|
|
679
|
+
* }
|
|
680
|
+
*/
|
|
681
|
+
function afterMiddleware(fn) {
|
|
682
|
+
return async ({ ctx, next }) => {
|
|
683
|
+
const result = await next();
|
|
684
|
+
await fn(ctx, result);
|
|
685
|
+
return result;
|
|
686
|
+
};
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* 创建 after-only 的 middleware,可修改返回值
|
|
690
|
+
*
|
|
691
|
+
* @example
|
|
692
|
+
* middleware: {
|
|
693
|
+
* get: afterMiddlewareTransform(async (ctx, result) => {
|
|
694
|
+
* return { ...result, computed: calculateSomething(result) };
|
|
695
|
+
* }),
|
|
696
|
+
* }
|
|
697
|
+
*/
|
|
698
|
+
function afterMiddlewareTransform(fn) {
|
|
699
|
+
return async ({ ctx, next }) => {
|
|
700
|
+
return fn(ctx, await next());
|
|
701
|
+
};
|
|
702
|
+
}
|
|
703
|
+
/**
|
|
704
|
+
* 创建 before-only 的 middleware
|
|
705
|
+
* 在操作执行前修改输入数据
|
|
706
|
+
*
|
|
707
|
+
* @example
|
|
708
|
+
* middleware: {
|
|
709
|
+
* create: beforeMiddleware(async (ctx, input) => {
|
|
710
|
+
* return { ...input, slug: slugify(input.title), createdBy: ctx.user.id };
|
|
711
|
+
* }),
|
|
712
|
+
* }
|
|
713
|
+
*/
|
|
714
|
+
function beforeMiddleware(fn) {
|
|
715
|
+
return async ({ ctx, input, next }) => {
|
|
716
|
+
return next(await fn(ctx, input));
|
|
717
|
+
};
|
|
718
|
+
}
|
|
719
|
+
/**
|
|
720
|
+
* 组合多个 middleware 为一个
|
|
721
|
+
*
|
|
722
|
+
* @example
|
|
723
|
+
* middleware: {
|
|
724
|
+
* create: composeMiddleware(
|
|
725
|
+
* beforeMiddleware((ctx, input) => ({ ...input, slug: slugify(input.title) })),
|
|
726
|
+
* afterMiddleware((ctx, result) => sendEmail(result)),
|
|
727
|
+
* ),
|
|
728
|
+
* }
|
|
729
|
+
*/
|
|
730
|
+
function composeMiddleware(...middlewares) {
|
|
731
|
+
return async (params) => {
|
|
732
|
+
let index = 0;
|
|
733
|
+
const executeNext = async (input) => {
|
|
734
|
+
if (index >= middlewares.length) return params.next(input);
|
|
735
|
+
const currentMiddleware = middlewares[index++];
|
|
736
|
+
return currentMiddleware({
|
|
737
|
+
ctx: params.ctx,
|
|
738
|
+
input,
|
|
739
|
+
next: executeNext
|
|
740
|
+
});
|
|
741
|
+
};
|
|
742
|
+
return executeNext(params.input);
|
|
743
|
+
};
|
|
744
|
+
}
|
|
745
|
+
/**
|
|
746
|
+
* 创建 list 操作的 after middleware
|
|
747
|
+
*/
|
|
748
|
+
function afterList(fn) {
|
|
749
|
+
return afterMiddleware(fn);
|
|
750
|
+
}
|
|
751
|
+
/**
|
|
752
|
+
* 创建 list 操作的 before middleware
|
|
753
|
+
*/
|
|
754
|
+
function beforeList(fn) {
|
|
755
|
+
return beforeMiddleware(fn);
|
|
756
|
+
}
|
|
757
|
+
/**
|
|
758
|
+
* 创建 create 操作的 after middleware
|
|
759
|
+
*/
|
|
760
|
+
function afterCreate(fn) {
|
|
761
|
+
return afterMiddleware(fn);
|
|
762
|
+
}
|
|
763
|
+
/**
|
|
764
|
+
* 创建 create 操作的 before middleware
|
|
765
|
+
*/
|
|
766
|
+
function beforeCreate(fn) {
|
|
767
|
+
return beforeMiddleware(fn);
|
|
768
|
+
}
|
|
769
|
+
/**
|
|
770
|
+
* 创建 update 操作的 after middleware
|
|
771
|
+
*/
|
|
772
|
+
function afterUpdate(fn) {
|
|
773
|
+
return afterMiddleware(fn);
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* 创建 delete 操作的 after middleware
|
|
777
|
+
*/
|
|
778
|
+
function afterDelete(fn) {
|
|
779
|
+
return afterMiddleware(fn);
|
|
780
|
+
}
|
|
781
|
+
|
|
647
782
|
//#endregion
|
|
648
783
|
//#region src/routers/index.ts
|
|
649
784
|
const appRouter = router({});
|
|
650
785
|
|
|
651
786
|
//#endregion
|
|
787
|
+
exports.afterCreate = afterCreate;
|
|
788
|
+
exports.afterDelete = afterDelete;
|
|
789
|
+
exports.afterList = afterList;
|
|
790
|
+
exports.afterMiddleware = afterMiddleware;
|
|
791
|
+
exports.afterMiddlewareTransform = afterMiddlewareTransform;
|
|
792
|
+
exports.afterUpdate = afterUpdate;
|
|
652
793
|
exports.appRouter = appRouter;
|
|
794
|
+
exports.beforeCreate = beforeCreate;
|
|
795
|
+
exports.beforeList = beforeList;
|
|
796
|
+
exports.beforeMiddleware = beforeMiddleware;
|
|
797
|
+
exports.composeMiddleware = composeMiddleware;
|
|
653
798
|
exports.createCrudRouter = createCrudRouter;
|
|
654
799
|
exports.publicProcedure = publicProcedure;
|
|
655
800
|
exports.router = router;
|