@taicode/common-server 3.7.7 → 3.7.8

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.
Files changed (61) hide show
  1. package/output/context/index.d.ts +6 -0
  2. package/output/context/index.d.ts.map +1 -0
  3. package/output/context/index.js +14 -0
  4. package/output/context/index.test.d.ts +2 -0
  5. package/output/context/index.test.d.ts.map +1 -0
  6. package/output/context/index.test.js +14 -0
  7. package/output/index.d.ts +5 -0
  8. package/output/index.d.ts.map +1 -0
  9. package/output/index.js +5 -0
  10. package/output/rate-limiter/index.d.ts +4 -0
  11. package/output/rate-limiter/index.d.ts.map +1 -0
  12. package/output/rate-limiter/index.js +3 -0
  13. package/output/rate-limiter/memory-store.d.ts +12 -0
  14. package/output/rate-limiter/memory-store.d.ts.map +1 -0
  15. package/output/rate-limiter/memory-store.js +46 -0
  16. package/output/rate-limiter/rate-limiter.d.ts +17 -0
  17. package/output/rate-limiter/rate-limiter.d.ts.map +1 -0
  18. package/output/rate-limiter/rate-limiter.js +64 -0
  19. package/output/rate-limiter/types.d.ts +27 -0
  20. package/output/rate-limiter/types.d.ts.map +1 -0
  21. package/output/rate-limiter/types.js +1 -0
  22. package/output/redis-queue/index.d.ts +8 -0
  23. package/output/redis-queue/index.d.ts.map +1 -0
  24. package/output/redis-queue/index.js +6 -0
  25. package/output/redis-queue/redis-queue-batch-consumer.d.ts +97 -0
  26. package/output/redis-queue/redis-queue-batch-consumer.d.ts.map +1 -0
  27. package/output/redis-queue/redis-queue-batch-consumer.js +341 -0
  28. package/output/redis-queue/redis-queue-batch-consumer.test.d.ts +26 -0
  29. package/output/redis-queue/redis-queue-batch-consumer.test.d.ts.map +1 -0
  30. package/output/redis-queue/redis-queue-batch-consumer.test.js +341 -0
  31. package/output/redis-queue/redis-queue-common.d.ts +73 -0
  32. package/output/redis-queue/redis-queue-common.d.ts.map +1 -0
  33. package/output/redis-queue/redis-queue-common.js +303 -0
  34. package/output/redis-queue/redis-queue-common.test.d.ts +19 -0
  35. package/output/redis-queue/redis-queue-common.test.d.ts.map +1 -0
  36. package/output/redis-queue/redis-queue-common.test.js +585 -0
  37. package/output/redis-queue/redis-queue-consumer.d.ts +95 -0
  38. package/output/redis-queue/redis-queue-consumer.d.ts.map +1 -0
  39. package/output/redis-queue/redis-queue-consumer.js +327 -0
  40. package/output/redis-queue/redis-queue-consumer.test.d.ts +26 -0
  41. package/output/redis-queue/redis-queue-consumer.test.d.ts.map +1 -0
  42. package/output/redis-queue/redis-queue-consumer.test.js +316 -0
  43. package/output/redis-queue/redis-queue-provider.d.ts +69 -0
  44. package/output/redis-queue/redis-queue-provider.d.ts.map +1 -0
  45. package/output/redis-queue/redis-queue-provider.js +205 -0
  46. package/output/redis-queue/redis-queue-provider.test.d.ts +28 -0
  47. package/output/redis-queue/redis-queue-provider.test.d.ts.map +1 -0
  48. package/output/redis-queue/redis-queue-provider.test.js +149 -0
  49. package/output/redis-queue/test-helpers.d.ts +112 -0
  50. package/output/redis-queue/test-helpers.d.ts.map +1 -0
  51. package/output/redis-queue/test-helpers.js +242 -0
  52. package/output/redis-queue/test-helpers.test.d.ts +28 -0
  53. package/output/redis-queue/test-helpers.test.d.ts.map +1 -0
  54. package/output/redis-queue/test-helpers.test.js +572 -0
  55. package/output/redis-queue/types.d.ts +146 -0
  56. package/output/redis-queue/types.d.ts.map +1 -0
  57. package/output/redis-queue/types.js +1 -0
  58. package/output/schema/index.d.ts +177 -0
  59. package/output/schema/index.d.ts.map +1 -0
  60. package/output/schema/index.js +180 -0
  61. package/package.json +2 -2
@@ -0,0 +1,146 @@
1
+ import type { CatchResult } from '@taicode/common-base';
2
+ import type { RedisClientType } from 'redis';
3
+ /**
4
+ * 队列注册表(默认)
5
+ *
6
+ * 支持两种使用方式:
7
+ *
8
+ * **方式 1: 模块声明扩展(常规,全局生效)**
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * // types/redis-queue.d.ts
13
+ * import '@taicode/common-server'
14
+ *
15
+ * declare module '@taicode/common-server/redis-queue' {
16
+ * interface RedisQueueRegistry {
17
+ * 'email-queue': { to: string; subject: string; body: string }
18
+ * 'sms-queue': { phone: string; message: string }
19
+ * }
20
+ * }
21
+ *
22
+ * // 使用时自动类型检查
23
+ * const provider = new RedisQueueProvider('email-queue', { redisUrl: '...' })
24
+ * const consumer = new RedisQueueConsumer('email-queue', {
25
+ * handler: async (data) => {
26
+ * // data 类型自动推断为 { to: string; subject: string; body: string }
27
+ * console.log(data.to)
28
+ * }
29
+ * })
30
+ * ```
31
+ *
32
+ * **方式 2: 泛型参数(灵活,局部使用)**
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * // 定义自定义 Registry
37
+ * interface MyQueueRegistry {
38
+ * 'order-queue': { orderId: string; amount: number }
39
+ * 'notify-queue': { userId: string; message: string }
40
+ * }
41
+ *
42
+ * // 使用时传入泛型参数
43
+ * const provider = new RedisQueueProvider<MyQueueRegistry>(
44
+ * 'order-queue',
45
+ * { redisUrl: '...' }
46
+ * )
47
+ *
48
+ * const consumer = new RedisQueueConsumer<MyQueueRegistry>(
49
+ * 'order-queue',
50
+ * {
51
+ * handler: async (data) => {
52
+ * // data 类型自动推断为 { orderId: string; amount: number }
53
+ * console.log(data.orderId)
54
+ * }
55
+ * }
56
+ * )
57
+ * ```
58
+ */
59
+ export interface RedisQueueRegistry {
60
+ }
61
+ /**
62
+ * 任务状态
63
+ */
64
+ export type Status = 'pending' | 'processing' | 'completed' | 'failed';
65
+ /**
66
+ * 任务数据类型,支持可选的 id 字段用于幂等性
67
+ */
68
+ export type TaskData = {
69
+ id?: string;
70
+ [key: string]: any;
71
+ };
72
+ /**
73
+ * 任务数据结构
74
+ */
75
+ export interface Task<T = TaskData> {
76
+ id: string;
77
+ data: T;
78
+ status: Status;
79
+ retryCount: number;
80
+ maxRetries: number;
81
+ createdTime: string;
82
+ delayUntil?: number;
83
+ processingStartTime?: number;
84
+ }
85
+ /**
86
+ * 队列统计信息
87
+ */
88
+ export interface QueueStats {
89
+ failed: number;
90
+ pending: number;
91
+ completed: number;
92
+ processing: number;
93
+ }
94
+ /**
95
+ * Redis 队列基础配置
96
+ */
97
+ export interface RedisQueueCommonConfig {
98
+ redisUrl?: string;
99
+ redisClient?: RedisClientType;
100
+ cleanupDelay?: number;
101
+ }
102
+ /**
103
+ * 队列生产者配置
104
+ */
105
+ export interface RedisQueueProviderConfig {
106
+ redisUrl?: string;
107
+ redisClient?: RedisClientType;
108
+ cleanupDelay?: number;
109
+ processingDelay?: number;
110
+ }
111
+ /**
112
+ * 队列消费者配置
113
+ */
114
+ export interface RedisQueueConsumerConfig<T extends TaskData = TaskData> {
115
+ redisUrl?: string;
116
+ redisClient?: RedisClientType;
117
+ handler: TaskHandler<T>;
118
+ maxRetries?: number;
119
+ concurrency?: number;
120
+ consumerInterval?: number;
121
+ processingTimeout?: number;
122
+ cleanupDelay?: number;
123
+ }
124
+ /**
125
+ * 任务处理器函数
126
+ */
127
+ export type TaskHandler<T extends TaskData = TaskData> = (data: T) => Promise<CatchResult<unknown, string>>;
128
+ /**
129
+ * 批量消费者配置
130
+ */
131
+ export interface BatchConsumerConfig<T extends TaskData = TaskData> {
132
+ redisUrl?: string;
133
+ redisClient?: RedisClientType;
134
+ handler: BatchTaskHandler<T>;
135
+ batchSize?: number;
136
+ maxRetries?: number;
137
+ concurrency?: number;
138
+ cleanupDelay?: number;
139
+ consumerInterval?: number;
140
+ processingTimeout?: number;
141
+ }
142
+ /**
143
+ * 批量任务处理器函数
144
+ */
145
+ export type BatchTaskHandler<T extends TaskData = TaskData> = (dataList: T[]) => Promise<CatchResult<unknown, string>>;
146
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../source/redis-queue/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,177 @@
1
+ import type { FastifySchema } from 'fastify';
2
+ import { z, ZodEnum, ZodType } from 'zod';
3
+ /**
4
+ * 标准查询请求体 Schema
5
+ * 用于定义包含过滤条件、分页参数和排序条件的查询请求
6
+ * @param f - 过滤条件的类型
7
+ * @param e - 排序字段的枚举类型(可选)
8
+ * @returns 查询请求体的 Schema
9
+ */
10
+ export declare function queryParamsSchema<F extends ZodType, E extends ZodEnum>(f: F, e?: E): z.ZodObject<{
11
+ filter: F;
12
+ paging: z.ZodObject<{
13
+ size: z.ZodNumber;
14
+ index: z.ZodNumber;
15
+ }, z.core.$strip>;
16
+ sort: z.ZodArray<z.ZodObject<{
17
+ key: E;
18
+ order: z.ZodEnum<{
19
+ ASC: "ASC";
20
+ DESC: "DESC";
21
+ }>;
22
+ }, z.core.$strip>> | z.ZodUndefined;
23
+ }, z.core.$strip>;
24
+ /**
25
+ * 查询结果 Schema
26
+ * 用于定义分页查询的返回结果结构
27
+ * @param t - 数据项的类型
28
+ * @returns 包含总数和数据列表的 Schema
29
+ */
30
+ export declare function queryResultSchema<T extends ZodType>(t: T): z.ZodObject<{
31
+ total: z.ZodNumber;
32
+ list: z.ZodArray<T>;
33
+ }, z.core.$strip>;
34
+ /**
35
+ * 列表查询参数 Schema
36
+ * 一次性列出全部数据
37
+ * @returns 列表查询参数的 Schema
38
+ */
39
+ export declare function listParamsSchema(): z.ZodNullable<z.ZodUndefined>;
40
+ /**
41
+ * 列表结果 Schema
42
+ * 用于定义列表查询的返回结果结构(与 queryResultSchema 功能相同)
43
+ * @param t - 数据项的类型
44
+ * @returns 包含总数和数据列表的 Schema
45
+ */
46
+ export declare function listResultSchema<T extends ZodType>(t: T): z.ZodObject<{
47
+ total: z.ZodNumber;
48
+ list: z.ZodArray<T>;
49
+ }, z.core.$strip>;
50
+ /**
51
+ * 指定时间范围查询请求体 Schema
52
+ * 用于定义包含过滤条件、时间范围和排序条件的查询请求(不包含分页)
53
+ * @param f - 过滤条件的类型
54
+ * @param e - 排序字段的枚举类型(可选)
55
+ * @returns 范围查询请求体的 Schema
56
+ */
57
+ export declare function rangeQueryParamsSchema<F extends ZodType, E extends ZodEnum>(f: F, e?: E): z.ZodObject<{
58
+ filter: F;
59
+ sort: z.ZodUndefined | z.ZodArray<z.ZodObject<{
60
+ key: E;
61
+ order: z.ZodEnum<{
62
+ ASC: "ASC";
63
+ DESC: "DESC";
64
+ }>;
65
+ }, z.core.$strip>>;
66
+ range: z.ZodTuple<[z.ZodISODateTime, z.ZodISODateTime], null>;
67
+ }, z.core.$strip>;
68
+ /**
69
+ * 范围查询结果 Schema
70
+ * 用于定义范围查询的返回结果结构
71
+ * @param t - 数据项的类型
72
+ * @returns 包含时间点和数据的数组 Schema
73
+ */
74
+ export declare function rangeQueryResultSchema<T extends ZodType>(t: T): z.ZodArray<z.ZodObject<{
75
+ data: T;
76
+ time: z.ZodISODateTime;
77
+ }, z.core.$strip>>;
78
+ /**
79
+ * 统计查询参数 Schema
80
+ * 用于定义统计查询的请求参数
81
+ * @param f - 过滤条件的类型
82
+ * @param e - 排序字段的枚举类型(可选)
83
+ * @returns 统计查询参数的 Schema
84
+ */
85
+ export declare function statisticQueryParamsSchema<F extends ZodType>(f: F): z.ZodObject<{
86
+ filter: F;
87
+ step: z.ZodEnum<{
88
+ minute: "minute";
89
+ hour: "hour";
90
+ day: "day";
91
+ week: "week";
92
+ month: "month";
93
+ year: "year";
94
+ }>;
95
+ range: z.ZodTuple<[z.ZodISODateTime, z.ZodISODateTime], null>;
96
+ }, z.core.$strip>;
97
+ /**
98
+ * 统计查询结果 Schema
99
+ * 用于定义统计查询的返回结果结构
100
+ * @param t - 数据项的类型
101
+ * @returns 包含时间点和数据的数组 Schema
102
+ */
103
+ export declare function statisticQueryResultSchema<T extends ZodType>(t: T): z.ZodArray<z.ZodObject<{
104
+ data: T;
105
+ time: z.ZodISODateTime;
106
+ }, z.core.$strip>>;
107
+ /**
108
+ * 模糊查询请求体 Schema
109
+ * 用于定义包含模糊搜索关键词、时间范围和排序条件的查询请求
110
+ * @param f - 过滤条件的类型(此处为字符串类型,用作搜索关键词)
111
+ * @param e - 排序字段的枚举类型(可选)
112
+ * @returns 模糊查询请求体的 Schema
113
+ */
114
+ export declare function fuzzQueryParamsSchema<F extends ZodType, E extends ZodEnum>(f: F, e?: E): z.ZodObject<{
115
+ filter: F;
116
+ paging: z.ZodObject<{
117
+ size: z.ZodNumber;
118
+ index: z.ZodNumber;
119
+ }, z.core.$strip>;
120
+ sort: z.ZodUndefined | z.ZodArray<z.ZodObject<{
121
+ key: E;
122
+ order: z.ZodEnum<{
123
+ ASC: "ASC";
124
+ DESC: "DESC";
125
+ }>;
126
+ }, z.core.$strip>>;
127
+ }, z.core.$strip>;
128
+ /**
129
+ * 模糊查询结果 Schema
130
+ * 用于定义模糊查询的返回结果结构
131
+ * @param t - 数据项的类型
132
+ * @returns 包含总数和数据列表的 Schema
133
+ */
134
+ export declare function fuzzQueryResultSchema<T extends ZodType>(t: T): z.ZodObject<{
135
+ total: z.ZodNumber;
136
+ list: z.ZodArray<T>;
137
+ }, z.core.$strip>;
138
+ /**
139
+ * 标准响应数据内容 Schema
140
+ * 用于定义统一的 API 响应结构
141
+ * @param t - 响应数据的类型
142
+ * @param s - 状态码的枚举类型
143
+ * @returns 标准响应的 Schema
144
+ */
145
+ export declare function responseDataSchema<T extends ZodType, S extends ZodEnum>(t: T, s: S): z.ZodObject<{
146
+ data: T;
147
+ status: S;
148
+ message: z.ZodString;
149
+ }, z.core.$strip>;
150
+ export declare function responseSchema<T extends ZodType, S extends ZodEnum, E extends ZodEnum>(t: T, u: S, e: E): {
151
+ '200': z.ZodObject<{
152
+ data: T;
153
+ status: z.ZodEnum<{
154
+ SUCCESS: "SUCCESS";
155
+ }>;
156
+ message: z.ZodString;
157
+ }, z.core.$strip>;
158
+ '400': z.ZodObject<{
159
+ data: z.ZodNull;
160
+ status: S;
161
+ message: z.ZodString;
162
+ }, z.core.$strip>;
163
+ '500': z.ZodObject<{
164
+ data: z.ZodNull;
165
+ status: E;
166
+ message: z.ZodString;
167
+ }, z.core.$strip>;
168
+ };
169
+ interface RouterSchema extends FastifySchema {
170
+ tags: string[];
171
+ summary: string;
172
+ operationId: string;
173
+ description: string;
174
+ }
175
+ export declare function routerSchema<T extends RouterSchema>(schema: T & RouterSchema): T & RouterSchema;
176
+ export {};
177
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../source/schema/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC5C,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AA2BzC;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;;;;;;;;;;;;;kBAMlF;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,CAAC;;;kBAKxD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,kCAE/B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,CAAC;;;kBAKvD;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;;;;;;;;;;kBAMvF;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,CAAC;;;mBAK7D;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,CAAC;;;;;;;;;;;kBAMjE;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,CAAC;;;mBAKjE;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;;;;;;;;;;;;;kBAMtF;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,CAAC;;;kBAK5D;AAGD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;;;;kBAMlF;AAED,wBAAgB,cAAc,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,SAAS,OAAO,EAAE,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;;;;;;;;;;;;;;;;;;EAMvG;AAED,UAAU,YAAa,SAAQ,aAAa;IAC1C,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,wBAAgB,YAAY,CAAC,CAAC,SAAS,YAAY,EAAE,MAAM,EAAE,CAAC,GAAG,YAAY,GAAG,CAAC,GAAG,YAAY,CAY/F"}
@@ -0,0 +1,180 @@
1
+ import { z, ZodEnum, ZodType } from 'zod';
2
+ /**
3
+ * 分页查询参数 Schema
4
+ * 用于定义分页查询时的页面大小和页面索引
5
+ * @private
6
+ */
7
+ function _pagingSchema() {
8
+ return z.object({
9
+ size: z.number().max(100).describe('每页数据量,最大100条'),
10
+ index: z.number().min(1).describe('页面索引,从1开始')
11
+ });
12
+ }
13
+ /**
14
+ * 排序查询参数 Schema
15
+ * 用于定义排序条件,支持多字段排序
16
+ * @private
17
+ * @param t - 排序字段的枚举类型
18
+ */
19
+ function _sortSchema(t) {
20
+ return z.array(z.object({
21
+ key: t.describe('排序字段'),
22
+ order: z.enum(['ASC', 'DESC']).describe('排序方向:ASC-升序,DESC-降序')
23
+ }));
24
+ }
25
+ /**
26
+ * 标准查询请求体 Schema
27
+ * 用于定义包含过滤条件、分页参数和排序条件的查询请求
28
+ * @param f - 过滤条件的类型
29
+ * @param e - 排序字段的枚举类型(可选)
30
+ * @returns 查询请求体的 Schema
31
+ */
32
+ export function queryParamsSchema(f, e) {
33
+ return z.object({
34
+ filter: f.describe('过滤条件'),
35
+ paging: _pagingSchema().describe('分页参数'),
36
+ sort: e ? _sortSchema(e).describe('排序条件') : z.undefined(),
37
+ });
38
+ }
39
+ /**
40
+ * 查询结果 Schema
41
+ * 用于定义分页查询的返回结果结构
42
+ * @param t - 数据项的类型
43
+ * @returns 包含总数和数据列表的 Schema
44
+ */
45
+ export function queryResultSchema(t) {
46
+ return z.object({
47
+ total: z.number().describe('数据总数'),
48
+ list: z.array(t).describe('数据列表')
49
+ });
50
+ }
51
+ /**
52
+ * 列表查询参数 Schema
53
+ * 一次性列出全部数据
54
+ * @returns 列表查询参数的 Schema
55
+ */
56
+ export function listParamsSchema() {
57
+ return z.undefined().nullable();
58
+ }
59
+ /**
60
+ * 列表结果 Schema
61
+ * 用于定义列表查询的返回结果结构(与 queryResultSchema 功能相同)
62
+ * @param t - 数据项的类型
63
+ * @returns 包含总数和数据列表的 Schema
64
+ */
65
+ export function listResultSchema(t) {
66
+ return z.object({
67
+ total: z.number().describe('数据总数'),
68
+ list: z.array(t).describe('数据列表')
69
+ });
70
+ }
71
+ /**
72
+ * 指定时间范围查询请求体 Schema
73
+ * 用于定义包含过滤条件、时间范围和排序条件的查询请求(不包含分页)
74
+ * @param f - 过滤条件的类型
75
+ * @param e - 排序字段的枚举类型(可选)
76
+ * @returns 范围查询请求体的 Schema
77
+ */
78
+ export function rangeQueryParamsSchema(f, e) {
79
+ return z.object({
80
+ filter: f.describe('过滤条件'),
81
+ sort: e ? _sortSchema(e).describe('排序条件') : z.undefined(),
82
+ range: z.tuple([z.iso.datetime(), z.iso.datetime()]).describe('时间范围,格式为 [开始时间, 结束时间]'),
83
+ });
84
+ }
85
+ /**
86
+ * 范围查询结果 Schema
87
+ * 用于定义范围查询的返回结果结构
88
+ * @param t - 数据项的类型
89
+ * @returns 包含时间点和数据的数组 Schema
90
+ */
91
+ export function rangeQueryResultSchema(t) {
92
+ return z.array(z.object({
93
+ data: t,
94
+ time: z.iso.datetime().describe('时间点'),
95
+ }));
96
+ }
97
+ /**
98
+ * 统计查询参数 Schema
99
+ * 用于定义统计查询的请求参数
100
+ * @param f - 过滤条件的类型
101
+ * @param e - 排序字段的枚举类型(可选)
102
+ * @returns 统计查询参数的 Schema
103
+ */
104
+ export function statisticQueryParamsSchema(f) {
105
+ return z.object({
106
+ filter: f.describe('过滤条件'),
107
+ step: z.enum(['minute', 'hour', 'day', 'week', 'month', 'year']).describe('统计粒度'),
108
+ range: z.tuple([z.iso.datetime(), z.iso.datetime()]).describe('时间范围,格式为 [开始时间, 结束时间]'),
109
+ });
110
+ }
111
+ /**
112
+ * 统计查询结果 Schema
113
+ * 用于定义统计查询的返回结果结构
114
+ * @param t - 数据项的类型
115
+ * @returns 包含时间点和数据的数组 Schema
116
+ */
117
+ export function statisticQueryResultSchema(t) {
118
+ return z.array(z.object({
119
+ data: t,
120
+ time: z.iso.datetime().describe('时间点'),
121
+ }));
122
+ }
123
+ /**
124
+ * 模糊查询请求体 Schema
125
+ * 用于定义包含模糊搜索关键词、时间范围和排序条件的查询请求
126
+ * @param f - 过滤条件的类型(此处为字符串类型,用作搜索关键词)
127
+ * @param e - 排序字段的枚举类型(可选)
128
+ * @returns 模糊查询请求体的 Schema
129
+ */
130
+ export function fuzzQueryParamsSchema(f, e) {
131
+ return z.object({
132
+ filter: f.describe('模糊搜索关键词,长度1-50字符'),
133
+ paging: _pagingSchema().describe('分页参数'),
134
+ sort: e ? _sortSchema(e).describe('排序条件') : z.undefined(),
135
+ });
136
+ }
137
+ /**
138
+ * 模糊查询结果 Schema
139
+ * 用于定义模糊查询的返回结果结构
140
+ * @param t - 数据项的类型
141
+ * @returns 包含总数和数据列表的 Schema
142
+ */
143
+ export function fuzzQueryResultSchema(t) {
144
+ return z.object({
145
+ total: z.number().describe('数据总数'),
146
+ list: z.array(t).describe('数据列表')
147
+ });
148
+ }
149
+ /**
150
+ * 标准响应数据内容 Schema
151
+ * 用于定义统一的 API 响应结构
152
+ * @param t - 响应数据的类型
153
+ * @param s - 状态码的枚举类型
154
+ * @returns 标准响应的 Schema
155
+ */
156
+ export function responseDataSchema(t, s) {
157
+ return z.object({
158
+ data: t.describe('响应数据'),
159
+ status: s.describe('响应状态码'),
160
+ message: z.string().describe('响应消息'),
161
+ });
162
+ }
163
+ export function responseSchema(t, u, e) {
164
+ return {
165
+ '200': responseDataSchema(t, z.enum(['SUCCESS'])),
166
+ '400': responseDataSchema(z.null(), u),
167
+ '500': responseDataSchema(z.null(), e),
168
+ };
169
+ }
170
+ export function routerSchema(schema) {
171
+ // 验证必需字段
172
+ if (!schema.operationId) {
173
+ throw new Error('routerSchema requires operationId');
174
+ }
175
+ // 如果没有提供 tags,设置默认值
176
+ if (!schema.tags) {
177
+ schema.tags = ['默认'];
178
+ }
179
+ return { ...schema };
180
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taicode/common-server",
3
- "version": "3.7.7",
3
+ "version": "3.7.8",
4
4
  "author": "Alain",
5
5
  "license": "ISC",
6
6
  "description": "",
@@ -27,7 +27,7 @@
27
27
  "fastify": "^5.5.0",
28
28
  "redis": "^5.11.0",
29
29
  "zod": "^4.1.0",
30
- "@taicode/common-base": "^3.7.7"
30
+ "@taicode/common-base": "^3.7.8"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/node": "^22.19.13",