@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/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 _trpc_server0 from "@trpc/server";
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: _trpc_server0.TRPCRouterBuilder<{
16
+ declare const router: _trpc_server2.TRPCRouterBuilder<{
17
17
  ctx: Context;
18
18
  meta: object;
19
- errorShape: _trpc_server0.TRPCDefaultErrorShape;
19
+ errorShape: _trpc_server2.TRPCDefaultErrorShape;
20
20
  transformer: true;
21
21
  }>;
22
- declare const publicProcedure: _trpc_server0.TRPCProcedureBuilder<Context, object, object, _trpc_server0.TRPCUnsetMarker, _trpc_server0.TRPCUnsetMarker, _trpc_server0.TRPCUnsetMarker, _trpc_server0.TRPCUnsetMarker, false>;
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 = "list" | "get" | "create" | "update" | "delete" | "deleteMany" | "updateMany" | "upsert" | "export" | "import" | "createMany";
26
- type WriteOperation = "create" | "update";
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["_"]["columns"];
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: "and" | "or";
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?: "and" | "or";
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?: "skip" | "upsert" | "error";
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: ListInput;
146
- next: (input?: ListInput) => Promise<ListResult<TSelect>>;
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
- next: () => Promise<TSelect | null>;
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: ExportInput;
197
- next: (input?: ExportInput) => Promise<ExportResult<TSelect>>;
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: _trpc_server0.TRPCBuiltRouter<{
775
+ declare const appRouter: _trpc_server2.TRPCBuiltRouter<{
617
776
  ctx: Context;
618
777
  meta: object;
619
- errorShape: _trpc_server0.TRPCDefaultErrorShape;
778
+ errorShape: _trpc_server2.TRPCDefaultErrorShape;
620
779
  transformer: true;
621
- }, _trpc_server0.TRPCDecorateCreateRouterOptions<{}>>;
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 listInputSchema = z.object({
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 exportInputSchema = z.object({
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(listInputSchema).output(listOutputSchema).query(async ({ ctx, 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(z.string()).output(entityOutputSchema.nullable()).query(async ({ ctx, 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 where = buildWhere(ctx, "get", eq(getIdColumn(), input));
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: input,
678
- next: doGet
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(exportInputSchema).output(exportOutputSchema).query(async ({ ctx, 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.3",
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": {