@wordrhyme/auto-crud-server 0.3.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 -55
- package/dist/index.d.cts +294 -5
- package/dist/index.d.ts +294 -5
- package/dist/index.js +231 -56
- package/package.json +1 -1
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,9 +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 } = config;
|
|
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 m = middleware;
|
|
481
482
|
const getIdColumn = () => table[idField];
|
|
482
483
|
const getSoftDeleteColumn = () => softDelete ? table[softDelete.column] : null;
|
|
483
484
|
const buildWhere = (ctx, operation, additionalCondition) => {
|
|
@@ -505,50 +506,75 @@ function createCrudRouter(config) {
|
|
|
505
506
|
const procedures = {
|
|
506
507
|
list: resolved.procedureFactory("list").input(listInputSchema).query(async ({ ctx, input }) => {
|
|
507
508
|
await withGuard(ctx, "list");
|
|
508
|
-
const
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
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
|
+
}
|
|
522
525
|
}
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
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
|
+
};
|
|
534
537
|
};
|
|
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);
|
|
535
545
|
}),
|
|
536
546
|
getById: resolved.procedureFactory("get").input(zod.z.string()).query(async ({ ctx, input }) => {
|
|
537
547
|
await withGuard(ctx, "get");
|
|
538
|
-
const
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
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();
|
|
542
560
|
}),
|
|
543
561
|
create: resolved.procedureFactory("create").input(insertSchema).mutation(async ({ ctx, input }) => {
|
|
544
562
|
await withGuard(ctx, "create");
|
|
545
|
-
const
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
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;
|
|
549
571
|
};
|
|
550
|
-
|
|
551
|
-
|
|
572
|
+
if (m.create) return m.create({
|
|
573
|
+
ctx,
|
|
574
|
+
input,
|
|
575
|
+
next: async (modifiedInput) => doCreate(modifiedInput ?? input)
|
|
576
|
+
});
|
|
577
|
+
return doCreate(input);
|
|
552
578
|
}),
|
|
553
579
|
update: resolved.procedureFactory("update").input(zod.z.object({
|
|
554
580
|
id: zod.z.string(),
|
|
@@ -559,13 +585,23 @@ function createCrudRouter(config) {
|
|
|
559
585
|
const [existing] = await ctx.db.select().from(table).where(where);
|
|
560
586
|
await withAuthorize(ctx, existing, "update");
|
|
561
587
|
if (!existing) throw new Error("Resource not found or access denied");
|
|
562
|
-
const
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
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;
|
|
566
596
|
};
|
|
567
|
-
|
|
568
|
-
|
|
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);
|
|
569
605
|
}),
|
|
570
606
|
delete: resolved.procedureFactory("delete").input(zod.z.string()).mutation(async ({ ctx, input }) => {
|
|
571
607
|
await withGuard(ctx, "delete");
|
|
@@ -573,18 +609,33 @@ function createCrudRouter(config) {
|
|
|
573
609
|
const [existing] = await ctx.db.select().from(table).where(where);
|
|
574
610
|
await withAuthorize(ctx, existing, "delete");
|
|
575
611
|
if (!existing) throw new Error("Resource not found or access denied");
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
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();
|
|
582
625
|
}),
|
|
583
626
|
deleteMany: resolved.procedureFactory("deleteMany").input(zod.z.array(zod.z.string()).max(maxBatchSize)).mutation(async ({ ctx, input }) => {
|
|
584
627
|
await withGuard(ctx, "deleteMany");
|
|
585
628
|
const where = buildWhere(ctx, "deleteMany", (0, drizzle_orm.inArray)(getIdColumn(), input));
|
|
586
|
-
|
|
587
|
-
|
|
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();
|
|
588
639
|
}),
|
|
589
640
|
updateMany: resolved.procedureFactory("updateMany").input(zod.z.object({
|
|
590
641
|
ids: zod.z.array(zod.z.string()).max(maxBatchSize),
|
|
@@ -592,24 +643,158 @@ function createCrudRouter(config) {
|
|
|
592
643
|
})).mutation(async ({ ctx, input }) => {
|
|
593
644
|
await withGuard(ctx, "updateMany");
|
|
594
645
|
const where = buildWhere(ctx, "updateMany", (0, drizzle_orm.inArray)(getIdColumn(), input.ids));
|
|
595
|
-
const
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
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 };
|
|
599
653
|
};
|
|
600
|
-
|
|
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);
|
|
601
661
|
})
|
|
602
662
|
};
|
|
603
663
|
const crudRouter = router(procedures);
|
|
604
664
|
return Object.assign(crudRouter, { procedures });
|
|
605
665
|
}
|
|
606
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
|
+
|
|
607
782
|
//#endregion
|
|
608
783
|
//#region src/routers/index.ts
|
|
609
784
|
const appRouter = router({});
|
|
610
785
|
|
|
611
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;
|
|
612
793
|
exports.appRouter = appRouter;
|
|
794
|
+
exports.beforeCreate = beforeCreate;
|
|
795
|
+
exports.beforeList = beforeList;
|
|
796
|
+
exports.beforeMiddleware = beforeMiddleware;
|
|
797
|
+
exports.composeMiddleware = composeMiddleware;
|
|
613
798
|
exports.createCrudRouter = createCrudRouter;
|
|
614
799
|
exports.publicProcedure = publicProcedure;
|
|
615
800
|
exports.router = router;
|