init6
This commit is contained in:
8
shared/dist/index.d.ts
vendored
Normal file
8
shared/dist/index.d.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Shared 包主导出文件
|
||||
* 导出所有类型定义、schemas 和工具函数
|
||||
*/
|
||||
export * from './types/index.js';
|
||||
export { BaseUserSchema, CreateUserSchema, UpdateUserSchema, UserQuerySchema, EmailQuerySchema, UserIdSchema, } from './schemas/index.js';
|
||||
export * from './utils/index.js';
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
shared/dist/index.d.ts.map
vendored
Normal file
1
shared/dist/index.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,cAAc,kBAAkB,CAAA;AAGhC,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,YAAY,GACb,MAAM,oBAAoB,CAAA;AAG3B,cAAc,kBAAkB,CAAA"}
|
||||
11
shared/dist/index.js
vendored
Normal file
11
shared/dist/index.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Shared 包主导出文件
|
||||
* 导出所有类型定义、schemas 和工具函数
|
||||
*/
|
||||
// 导出类型定义
|
||||
export * from './types/index.js';
|
||||
// 导出 schemas(只导出 schema 对象,不导出推断的类型)
|
||||
export { BaseUserSchema, CreateUserSchema, UpdateUserSchema, UserQuerySchema, EmailQuerySchema, UserIdSchema, } from './schemas/index.js';
|
||||
// 导出工具函数
|
||||
export * from './utils/index.js';
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
shared/dist/index.js.map
vendored
Normal file
1
shared/dist/index.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,SAAS;AACT,cAAc,kBAAkB,CAAA;AAEhC,qCAAqC;AACrC,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,YAAY,GACb,MAAM,oBAAoB,CAAA;AAE3B,SAAS;AACT,cAAc,kBAAkB,CAAA"}
|
||||
6
shared/dist/schemas/index.d.ts
vendored
Normal file
6
shared/dist/schemas/index.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Schemas 导出文件
|
||||
* 导出所有验证 schemas
|
||||
*/
|
||||
export { BaseUserSchema, CreateUserSchema, UpdateUserSchema, UserQuerySchema, EmailQuerySchema, UserIdSchema, } from './user.js';
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
shared/dist/schemas/index.d.ts.map
vendored
Normal file
1
shared/dist/schemas/index.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,YAAY,GACb,MAAM,WAAW,CAAA"}
|
||||
7
shared/dist/schemas/index.js
vendored
Normal file
7
shared/dist/schemas/index.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Schemas 导出文件
|
||||
* 导出所有验证 schemas
|
||||
*/
|
||||
// 只导出 schema 对象,不导出推断的类型(类型在 types 目录中定义)
|
||||
export { BaseUserSchema, CreateUserSchema, UpdateUserSchema, UserQuerySchema, EmailQuerySchema, UserIdSchema, } from './user.js';
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
shared/dist/schemas/index.js.map
vendored
Normal file
1
shared/dist/schemas/index.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,0CAA0C;AAC1C,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,YAAY,GACb,MAAM,WAAW,CAAA"}
|
||||
63
shared/dist/schemas/user.d.ts
vendored
Normal file
63
shared/dist/schemas/user.d.ts
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* 用户相关的 Valibot 验证模式
|
||||
* User-related Valibot validation schemas
|
||||
*/
|
||||
import * as v from 'valibot';
|
||||
/**
|
||||
* 基础用户验证模式
|
||||
* Base user validation schema
|
||||
*/
|
||||
export declare const BaseUserSchema: v.ObjectSchema<{
|
||||
readonly name: v.SchemaWithPipe<readonly [v.StringSchema<"姓名必须是字符串">, v.TrimAction, v.MinLengthAction<string, 2, "姓名至少需要2个字符">, v.MaxLengthAction<string, 50, "姓名不能超过50个字符">, v.NonEmptyAction<string, "姓名不能为空">]>;
|
||||
readonly email: v.SchemaWithPipe<readonly [v.StringSchema<"邮箱必须是字符串">, v.TrimAction, v.EmailAction<string, "请输入有效的邮箱地址">, v.MaxLengthAction<string, 100, "邮箱不能超过100个字符">]>;
|
||||
readonly age: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<"年龄必须是数字">, v.IntegerAction<number, "年龄必须是整数">, v.MinValueAction<number, 1, "年龄不能小于1岁">, v.MaxValueAction<number, 150, "年龄不能超过150岁">]>, undefined>;
|
||||
}, undefined>;
|
||||
/**
|
||||
* 创建用户验证模式
|
||||
* Create user validation schema
|
||||
*/
|
||||
export declare const CreateUserSchema: v.ObjectSchema<{
|
||||
readonly name: v.SchemaWithPipe<readonly [v.StringSchema<"姓名必须是字符串">, v.TrimAction, v.MinLengthAction<string, 2, "姓名至少需要2个字符">, v.MaxLengthAction<string, 50, "姓名不能超过50个字符">, v.NonEmptyAction<string, "姓名不能为空">]>;
|
||||
readonly email: v.SchemaWithPipe<readonly [v.StringSchema<"邮箱必须是字符串">, v.TrimAction, v.EmailAction<string, "请输入有效的邮箱地址">, v.MaxLengthAction<string, 100, "邮箱不能超过100个字符">]>;
|
||||
readonly age: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<"年龄必须是数字">, v.IntegerAction<number, "年龄必须是整数">, v.MinValueAction<number, 1, "年龄不能小于1岁">, v.MaxValueAction<number, 150, "年龄不能超过150岁">]>, undefined>;
|
||||
}, undefined>;
|
||||
/**
|
||||
* 更新用户验证模式 - 所有字段都是可选的
|
||||
* Update user validation schema - all fields are optional
|
||||
*/
|
||||
export declare const UpdateUserSchema: v.ObjectSchema<{
|
||||
readonly name: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<"姓名必须是字符串">, v.TrimAction, v.MinLengthAction<string, 2, "姓名至少需要2个字符">, v.MaxLengthAction<string, 50, "姓名不能超过50个字符">, v.NonEmptyAction<string, "姓名不能为空">]>, undefined>;
|
||||
readonly email: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<"邮箱必须是字符串">, v.TrimAction, v.EmailAction<string, "请输入有效的邮箱地址">, v.MaxLengthAction<string, 100, "邮箱不能超过100个字符">]>, undefined>;
|
||||
readonly age: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<"年龄必须是数字">, v.IntegerAction<number, "年龄必须是整数">, v.MinValueAction<number, 1, "年龄不能小于1岁">, v.MaxValueAction<number, 150, "年龄不能超过150岁">]>, undefined>;
|
||||
}, undefined>;
|
||||
/**
|
||||
* 用户查询参数验证模式
|
||||
* User query parameters validation schema
|
||||
*/
|
||||
export declare const UserQuerySchema: v.ObjectSchema<{
|
||||
readonly page: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<"页码必须是数字">, v.IntegerAction<number, "页码必须是整数">, v.MinValueAction<number, 1, "页码不能小于1">]>, 1>;
|
||||
readonly limit: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<"每页数量必须是数字">, v.IntegerAction<number, "每页数量必须是整数">, v.MinValueAction<number, 1, "每页数量不能小于1">, v.MaxValueAction<number, 100, "每页数量不能超过100">]>, 10>;
|
||||
readonly search: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<"搜索关键词必须是字符串">, v.TrimAction, v.MaxLengthAction<string, 100, "搜索关键词不能超过100个字符">]>, undefined>;
|
||||
readonly minAge: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<"最小年龄必须是数字">, v.IntegerAction<number, "最小年龄必须是整数">, v.MinValueAction<number, 1, "最小年龄不能小于1岁">]>, undefined>;
|
||||
readonly maxAge: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<"最大年龄必须是数字">, v.IntegerAction<number, "最大年龄必须是整数">, v.MaxValueAction<number, 150, "最大年龄不能超过150岁">]>, undefined>;
|
||||
}, undefined>;
|
||||
/**
|
||||
* 邮箱查询验证模式
|
||||
* Email query validation schema
|
||||
*/
|
||||
export declare const EmailQuerySchema: v.ObjectSchema<{
|
||||
readonly email: v.SchemaWithPipe<readonly [v.StringSchema<"邮箱必须是字符串">, v.TrimAction, v.EmailAction<string, "请输入有效的邮箱地址">, v.NonEmptyAction<string, "邮箱不能为空">]>;
|
||||
}, undefined>;
|
||||
/**
|
||||
* ID 参数验证模式
|
||||
* ID parameter validation schema
|
||||
*/
|
||||
export declare const UserIdSchema: v.ObjectSchema<{
|
||||
readonly id: v.SchemaWithPipe<readonly [v.NumberSchema<"用户ID必须是数字">, v.IntegerAction<number, "用户ID必须是整数">, v.MinValueAction<number, 1, "用户ID必须大于0">]>;
|
||||
}, undefined>;
|
||||
export type CreateUserInput = v.InferInput<typeof CreateUserSchema>;
|
||||
export type UpdateUserInput = v.InferInput<typeof UpdateUserSchema>;
|
||||
export type UserQueryParams = v.InferInput<typeof UserQuerySchema>;
|
||||
export type EmailQuery = v.InferInput<typeof EmailQuerySchema>;
|
||||
export type UserIdParams = v.InferInput<typeof UserIdSchema>;
|
||||
//# sourceMappingURL=user.d.ts.map
|
||||
1
shared/dist/schemas/user.d.ts.map
vendored
Normal file
1
shared/dist/schemas/user.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../src/schemas/user.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAE5B;;;GAGG;AACH,eAAO,MAAM,cAAc;;;;aAsBzB,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;;aAAiB,CAAA;AAE9C;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;;aA0B3B,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe;;;;;;aAmC1B,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;aAO3B,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,YAAY;;aAMvB,CAAA;AAGF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAA;AACnE,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAA;AACnE,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,UAAU,CAAC,OAAO,eAAe,CAAC,CAAA;AAClE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAC9D,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,UAAU,CAAC,OAAO,YAAY,CAAC,CAAA"}
|
||||
54
shared/dist/schemas/user.js
vendored
Normal file
54
shared/dist/schemas/user.js
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* 用户相关的 Valibot 验证模式
|
||||
* User-related Valibot validation schemas
|
||||
*/
|
||||
import * as v from 'valibot';
|
||||
/**
|
||||
* 基础用户验证模式
|
||||
* Base user validation schema
|
||||
*/
|
||||
export const BaseUserSchema = v.object({
|
||||
name: v.pipe(v.string('姓名必须是字符串'), v.trim(), v.minLength(2, '姓名至少需要2个字符'), v.maxLength(50, '姓名不能超过50个字符'), v.nonEmpty('姓名不能为空')),
|
||||
email: v.pipe(v.string('邮箱必须是字符串'), v.trim(), v.email('请输入有效的邮箱地址'), v.maxLength(100, '邮箱不能超过100个字符')),
|
||||
age: v.optional(v.pipe(v.number('年龄必须是数字'), v.integer('年龄必须是整数'), v.minValue(1, '年龄不能小于1岁'), v.maxValue(150, '年龄不能超过150岁'))),
|
||||
});
|
||||
/**
|
||||
* 创建用户验证模式
|
||||
* Create user validation schema
|
||||
*/
|
||||
export const CreateUserSchema = BaseUserSchema;
|
||||
/**
|
||||
* 更新用户验证模式 - 所有字段都是可选的
|
||||
* Update user validation schema - all fields are optional
|
||||
*/
|
||||
export const UpdateUserSchema = v.object({
|
||||
name: v.optional(v.pipe(v.string('姓名必须是字符串'), v.trim(), v.minLength(2, '姓名至少需要2个字符'), v.maxLength(50, '姓名不能超过50个字符'), v.nonEmpty('姓名不能为空'))),
|
||||
email: v.optional(v.pipe(v.string('邮箱必须是字符串'), v.trim(), v.email('请输入有效的邮箱地址'), v.maxLength(100, '邮箱不能超过100个字符'))),
|
||||
age: v.optional(v.pipe(v.number('年龄必须是数字'), v.integer('年龄必须是整数'), v.minValue(1, '年龄不能小于1岁'), v.maxValue(150, '年龄不能超过150岁'))),
|
||||
});
|
||||
/**
|
||||
* 用户查询参数验证模式
|
||||
* User query parameters validation schema
|
||||
*/
|
||||
export const UserQuerySchema = v.object({
|
||||
page: v.optional(v.pipe(v.number('页码必须是数字'), v.integer('页码必须是整数'), v.minValue(1, '页码不能小于1')), 1),
|
||||
limit: v.optional(v.pipe(v.number('每页数量必须是数字'), v.integer('每页数量必须是整数'), v.minValue(1, '每页数量不能小于1'), v.maxValue(100, '每页数量不能超过100')), 10),
|
||||
search: v.optional(v.pipe(v.string('搜索关键词必须是字符串'), v.trim(), v.maxLength(100, '搜索关键词不能超过100个字符'))),
|
||||
minAge: v.optional(v.pipe(v.number('最小年龄必须是数字'), v.integer('最小年龄必须是整数'), v.minValue(1, '最小年龄不能小于1岁'))),
|
||||
maxAge: v.optional(v.pipe(v.number('最大年龄必须是数字'), v.integer('最大年龄必须是整数'), v.maxValue(150, '最大年龄不能超过150岁'))),
|
||||
});
|
||||
/**
|
||||
* 邮箱查询验证模式
|
||||
* Email query validation schema
|
||||
*/
|
||||
export const EmailQuerySchema = v.object({
|
||||
email: v.pipe(v.string('邮箱必须是字符串'), v.trim(), v.email('请输入有效的邮箱地址'), v.nonEmpty('邮箱不能为空')),
|
||||
});
|
||||
/**
|
||||
* ID 参数验证模式
|
||||
* ID parameter validation schema
|
||||
*/
|
||||
export const UserIdSchema = v.object({
|
||||
id: v.pipe(v.number('用户ID必须是数字'), v.integer('用户ID必须是整数'), v.minValue(1, '用户ID必须大于0')),
|
||||
});
|
||||
//# sourceMappingURL=user.js.map
|
||||
1
shared/dist/schemas/user.js.map
vendored
Normal file
1
shared/dist/schemas/user.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/schemas/user.ts"],"names":[],"mappings":"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"}
|
||||
85
shared/dist/types/base.d.ts
vendored
Normal file
85
shared/dist/types/base.d.ts
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* 基础类型定义
|
||||
* Base type definitions for the application
|
||||
*/
|
||||
/**
|
||||
* 基础实体接口 - 所有实体都应该有的基础字段
|
||||
* Base entity interface - common fields for all entities
|
||||
*/
|
||||
export interface BaseEntity {
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
/**
|
||||
* API 响应基础结构
|
||||
* Base API response structure
|
||||
*/
|
||||
export interface ApiResponse<T = any> {
|
||||
success: boolean;
|
||||
data?: T;
|
||||
message?: string;
|
||||
error?: string;
|
||||
}
|
||||
/**
|
||||
* 分页查询参数
|
||||
* Pagination query parameters
|
||||
*/
|
||||
export interface PaginationParams {
|
||||
page?: number;
|
||||
limit?: number;
|
||||
}
|
||||
/**
|
||||
* 分页响应结构
|
||||
* Paginated response structure
|
||||
*/
|
||||
export interface PaginatedResponse<T> {
|
||||
data: T[];
|
||||
pagination: {
|
||||
page: number;
|
||||
limit: number;
|
||||
total: number;
|
||||
totalPages: number;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* 查询操作符枚举
|
||||
* Query operators enum
|
||||
*/
|
||||
export declare enum QueryOperator {
|
||||
EQUALS = "equals",
|
||||
NOT_EQUALS = "not_equals",
|
||||
CONTAINS = "contains",
|
||||
NOT_CONTAINS = "not_contains",
|
||||
STARTS_WITH = "starts_with",
|
||||
ENDS_WITH = "ends_with",
|
||||
GREATER_THAN = "gt",
|
||||
GREATER_THAN_OR_EQUAL = "gte",
|
||||
LESS_THAN = "lt",
|
||||
LESS_THAN_OR_EQUAL = "lte",
|
||||
IN = "in",
|
||||
NOT_IN = "not_in",
|
||||
IS_NULL = "is_null",
|
||||
IS_NOT_NULL = "is_not_null"
|
||||
}
|
||||
/**
|
||||
* 查询条件接口
|
||||
* Query condition interface
|
||||
*/
|
||||
export interface QueryCondition {
|
||||
field: string;
|
||||
operator: QueryOperator;
|
||||
value?: any;
|
||||
}
|
||||
/**
|
||||
* 通用查询参数
|
||||
* Universal query parameters
|
||||
*/
|
||||
export interface UniversalQueryParams extends PaginationParams {
|
||||
conditions?: QueryCondition[];
|
||||
orderBy?: {
|
||||
field: string;
|
||||
direction: 'asc' | 'desc';
|
||||
}[];
|
||||
}
|
||||
//# sourceMappingURL=base.d.ts.map
|
||||
1
shared/dist/types/base.d.ts.map
vendored
Normal file
1
shared/dist/types/base.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/types/base.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,IAAI,CAAA;IACf,SAAS,EAAE,IAAI,CAAA;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,GAAG;IAClC,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,CAAC,EAAE,CAAC,CAAA;IACR,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,IAAI,EAAE,CAAC,EAAE,CAAA;IACT,UAAU,EAAE;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,KAAK,EAAE,MAAM,CAAA;QACb,KAAK,EAAE,MAAM,CAAA;QACb,UAAU,EAAE,MAAM,CAAA;KACnB,CAAA;CACF;AAED;;;GAGG;AACH,oBAAY,aAAa;IACvB,MAAM,WAAW;IACjB,UAAU,eAAe;IACzB,QAAQ,aAAa;IACrB,YAAY,iBAAiB;IAC7B,WAAW,gBAAgB;IAC3B,SAAS,cAAc;IACvB,YAAY,OAAO;IACnB,qBAAqB,QAAQ;IAC7B,SAAS,OAAO;IAChB,kBAAkB,QAAQ;IAC1B,EAAE,OAAO;IACT,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,WAAW,gBAAgB;CAC5B;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,aAAa,CAAA;IACvB,KAAK,CAAC,EAAE,GAAG,CAAA;CACZ;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAqB,SAAQ,gBAAgB;IAC5D,UAAU,CAAC,EAAE,cAAc,EAAE,CAAA;IAC7B,OAAO,CAAC,EAAE;QACR,KAAK,EAAE,MAAM,CAAA;QACb,SAAS,EAAE,KAAK,GAAG,MAAM,CAAA;KAC1B,EAAE,CAAA;CACJ"}
|
||||
26
shared/dist/types/base.js
vendored
Normal file
26
shared/dist/types/base.js
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 基础类型定义
|
||||
* Base type definitions for the application
|
||||
*/
|
||||
/**
|
||||
* 查询操作符枚举
|
||||
* Query operators enum
|
||||
*/
|
||||
export var QueryOperator;
|
||||
(function (QueryOperator) {
|
||||
QueryOperator["EQUALS"] = "equals";
|
||||
QueryOperator["NOT_EQUALS"] = "not_equals";
|
||||
QueryOperator["CONTAINS"] = "contains";
|
||||
QueryOperator["NOT_CONTAINS"] = "not_contains";
|
||||
QueryOperator["STARTS_WITH"] = "starts_with";
|
||||
QueryOperator["ENDS_WITH"] = "ends_with";
|
||||
QueryOperator["GREATER_THAN"] = "gt";
|
||||
QueryOperator["GREATER_THAN_OR_EQUAL"] = "gte";
|
||||
QueryOperator["LESS_THAN"] = "lt";
|
||||
QueryOperator["LESS_THAN_OR_EQUAL"] = "lte";
|
||||
QueryOperator["IN"] = "in";
|
||||
QueryOperator["NOT_IN"] = "not_in";
|
||||
QueryOperator["IS_NULL"] = "is_null";
|
||||
QueryOperator["IS_NOT_NULL"] = "is_not_null";
|
||||
})(QueryOperator || (QueryOperator = {}));
|
||||
//# sourceMappingURL=base.js.map
|
||||
1
shared/dist/types/base.js.map
vendored
Normal file
1
shared/dist/types/base.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/types/base.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA8CH;;;GAGG;AACH,MAAM,CAAN,IAAY,aAeX;AAfD,WAAY,aAAa;IACvB,kCAAiB,CAAA;IACjB,0CAAyB,CAAA;IACzB,sCAAqB,CAAA;IACrB,8CAA6B,CAAA;IAC7B,4CAA2B,CAAA;IAC3B,wCAAuB,CAAA;IACvB,oCAAmB,CAAA;IACnB,8CAA6B,CAAA;IAC7B,iCAAgB,CAAA;IAChB,2CAA0B,CAAA;IAC1B,0BAAS,CAAA;IACT,kCAAiB,CAAA;IACjB,oCAAmB,CAAA;IACnB,4CAA2B,CAAA;AAC7B,CAAC,EAfW,aAAa,KAAb,aAAa,QAexB"}
|
||||
8
shared/dist/types/index.d.ts
vendored
Normal file
8
shared/dist/types/index.d.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* 类型定义导出索引
|
||||
* Types export index
|
||||
*/
|
||||
export * from './base.js';
|
||||
export * from './post.js';
|
||||
export * from './user.js';
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
shared/dist/types/index.d.ts.map
vendored
Normal file
1
shared/dist/types/index.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA"}
|
||||
8
shared/dist/types/index.js
vendored
Normal file
8
shared/dist/types/index.js
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* 类型定义导出索引
|
||||
* Types export index
|
||||
*/
|
||||
export * from './base.js';
|
||||
export * from './post.js';
|
||||
export * from './user.js';
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
shared/dist/types/index.js.map
vendored
Normal file
1
shared/dist/types/index.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA"}
|
||||
23
shared/dist/types/post.d.ts
vendored
Normal file
23
shared/dist/types/post.d.ts
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Post 类型定义
|
||||
* 基于 Prisma 生成的类型
|
||||
*/
|
||||
export interface Post {
|
||||
id: number;
|
||||
title: string;
|
||||
content: string | null;
|
||||
published: boolean;
|
||||
createdAt: Date | string;
|
||||
updatedAt: Date | string;
|
||||
}
|
||||
export interface CreatePostInput {
|
||||
title: string;
|
||||
content?: string;
|
||||
published?: boolean;
|
||||
}
|
||||
export interface UpdatePostInput {
|
||||
title?: string;
|
||||
content?: string;
|
||||
published?: boolean;
|
||||
}
|
||||
//# sourceMappingURL=post.d.ts.map
|
||||
1
shared/dist/types/post.d.ts.map
vendored
Normal file
1
shared/dist/types/post.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"post.d.ts","sourceRoot":"","sources":["../../src/types/post.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,SAAS,EAAE,OAAO,CAAA;IAClB,SAAS,EAAE,IAAI,GAAG,MAAM,CAAA;IACxB,SAAS,EAAE,IAAI,GAAG,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB"}
|
||||
6
shared/dist/types/post.js
vendored
Normal file
6
shared/dist/types/post.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Post 类型定义
|
||||
* 基于 Prisma 生成的类型
|
||||
*/
|
||||
export {};
|
||||
//# sourceMappingURL=post.js.map
|
||||
1
shared/dist/types/post.js.map
vendored
Normal file
1
shared/dist/types/post.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"post.js","sourceRoot":"","sources":["../../src/types/post.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
||||
58
shared/dist/types/user.d.ts
vendored
Normal file
58
shared/dist/types/user.d.ts
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* 用户相关类型定义
|
||||
* User-related type definitions
|
||||
*/
|
||||
import type { BaseEntity } from './base.js';
|
||||
/**
|
||||
* 用户实体接口
|
||||
* User entity interface
|
||||
*/
|
||||
export interface User extends BaseEntity {
|
||||
name: string;
|
||||
email: string;
|
||||
age?: number;
|
||||
}
|
||||
/**
|
||||
* 创建用户输入类型
|
||||
* Create user input type
|
||||
*/
|
||||
export interface CreateUserInput {
|
||||
name: string;
|
||||
email: string;
|
||||
age?: number;
|
||||
}
|
||||
/**
|
||||
* 更新用户输入类型
|
||||
* Update user input type
|
||||
*/
|
||||
export interface UpdateUserInput {
|
||||
name?: string;
|
||||
email?: string;
|
||||
age?: number;
|
||||
}
|
||||
/**
|
||||
* 用户查询参数类型
|
||||
* User query parameters type
|
||||
*/
|
||||
export interface UserQueryParams {
|
||||
page?: number;
|
||||
limit?: number;
|
||||
search?: string;
|
||||
minAge?: number;
|
||||
maxAge?: number;
|
||||
}
|
||||
/**
|
||||
* 邮箱查询参数类型
|
||||
* Email query parameters type
|
||||
*/
|
||||
export interface EmailQuery {
|
||||
email: string;
|
||||
}
|
||||
/**
|
||||
* 用户ID参数类型
|
||||
* User ID parameters type
|
||||
*/
|
||||
export interface UserIdParams {
|
||||
id: number;
|
||||
}
|
||||
//# sourceMappingURL=user.d.ts.map
|
||||
1
shared/dist/types/user.d.ts.map
vendored
Normal file
1
shared/dist/types/user.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../src/types/user.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAE3C;;;GAGG;AACH,MAAM,WAAW,IAAK,SAAQ,UAAU;IACtC,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;CACX"}
|
||||
6
shared/dist/types/user.js
vendored
Normal file
6
shared/dist/types/user.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* 用户相关类型定义
|
||||
* User-related type definitions
|
||||
*/
|
||||
export {};
|
||||
//# sourceMappingURL=user.js.map
|
||||
1
shared/dist/types/user.js.map
vendored
Normal file
1
shared/dist/types/user.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/types/user.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
||||
6
shared/dist/utils/index.d.ts
vendored
Normal file
6
shared/dist/utils/index.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Utils 导出索引
|
||||
* Utils export index
|
||||
*/
|
||||
export * from './validation.js';
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
shared/dist/utils/index.d.ts.map
vendored
Normal file
1
shared/dist/utils/index.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,iBAAiB,CAAA"}
|
||||
6
shared/dist/utils/index.js
vendored
Normal file
6
shared/dist/utils/index.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Utils 导出索引
|
||||
* Utils export index
|
||||
*/
|
||||
export * from './validation.js';
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
shared/dist/utils/index.js.map
vendored
Normal file
1
shared/dist/utils/index.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,iBAAiB,CAAA"}
|
||||
59
shared/dist/utils/validation.d.ts
vendored
Normal file
59
shared/dist/utils/validation.d.ts
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* 通用验证工具函数
|
||||
* Common validation utility functions
|
||||
*/
|
||||
import * as v from 'valibot';
|
||||
/**
|
||||
* 验证错误接口
|
||||
* Validation error interface
|
||||
*/
|
||||
export interface ValidationError {
|
||||
field: string;
|
||||
message: string;
|
||||
code: string;
|
||||
}
|
||||
/**
|
||||
* 验证结果接口
|
||||
* Validation result interface
|
||||
*/
|
||||
export interface ValidationResult<T> {
|
||||
success: boolean;
|
||||
data?: T;
|
||||
errors?: ValidationError[];
|
||||
}
|
||||
/**
|
||||
* 将 Valibot 验证错误转换为自定义格式
|
||||
* Convert Valibot validation errors to custom format
|
||||
*/
|
||||
export declare function formatValidationErrors(issues: v.BaseIssue<unknown>[]): ValidationError[];
|
||||
/**
|
||||
* 安全解析数据
|
||||
* Safely parse data with validation
|
||||
*/
|
||||
export declare function safeParseData<T>(schema: v.BaseSchema<unknown, T, v.BaseIssue<unknown>>, data: unknown): ValidationResult<T>;
|
||||
/**
|
||||
* 解析并验证数据,失败时抛出错误
|
||||
* Parse and validate data, throw error on failure
|
||||
*/
|
||||
export declare function parseData<T>(schema: v.BaseSchema<unknown, T, v.BaseIssue<unknown>>, data: unknown): T;
|
||||
/**
|
||||
* 创建验证中间件函数(用于 API)
|
||||
* Create validation middleware function (for API)
|
||||
*/
|
||||
export declare function createValidationMiddleware<T>(schema: v.BaseSchema<unknown, T, v.BaseIssue<unknown>>): (data: unknown) => T;
|
||||
/**
|
||||
* 验证查询参数
|
||||
* Validate query parameters
|
||||
*/
|
||||
export declare function validateQuery<T>(schema: v.BaseSchema<unknown, T, v.BaseIssue<unknown>>, query: Record<string, any>): T;
|
||||
/**
|
||||
* 验证请求体数据
|
||||
* Validate request body data
|
||||
*/
|
||||
export declare function validateBody<T>(schema: v.BaseSchema<unknown, T, v.BaseIssue<unknown>>, body: unknown): T;
|
||||
/**
|
||||
* 验证路径参数
|
||||
* Validate path parameters
|
||||
*/
|
||||
export declare function validateParams<T>(schema: v.BaseSchema<unknown, T, v.BaseIssue<unknown>>, params: Record<string, any>): T;
|
||||
//# sourceMappingURL=validation.d.ts.map
|
||||
1
shared/dist/utils/validation.d.ts.map
vendored
Normal file
1
shared/dist/utils/validation.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAE5B;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,CAAC,EAAE,CAAC,CAAA;IACR,MAAM,CAAC,EAAE,eAAe,EAAE,CAAA;CAC3B;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,GAAG,eAAe,EAAE,CAMxF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAC7B,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,EACtD,IAAI,EAAE,OAAO,GACZ,gBAAgB,CAAC,CAAC,CAAC,CA2BrB;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,CAAC,EACzB,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,EACtD,IAAI,EAAE,OAAO,GACZ,CAAC,CAWH;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,CAAC,EAC1C,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,IAE9C,MAAM,OAAO,KAAG,CAAC,CAG1B;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAC7B,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,EACtD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACzB,CAAC,CAqBH;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAC5B,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,EACtD,IAAI,EAAE,OAAO,GACZ,CAAC,CAEH;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC9B,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,EACtD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC1B,CAAC,CAeH"}
|
||||
118
shared/dist/utils/validation.js
vendored
Normal file
118
shared/dist/utils/validation.js
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* 通用验证工具函数
|
||||
* Common validation utility functions
|
||||
*/
|
||||
import * as v from 'valibot';
|
||||
/**
|
||||
* 将 Valibot 验证错误转换为自定义格式
|
||||
* Convert Valibot validation errors to custom format
|
||||
*/
|
||||
export function formatValidationErrors(issues) {
|
||||
return issues.map(issue => ({
|
||||
field: issue.path?.map(p => p.key).join('.') || 'unknown',
|
||||
message: issue.message,
|
||||
code: issue.type || 'VALIDATION_ERROR',
|
||||
}));
|
||||
}
|
||||
/**
|
||||
* 安全解析数据
|
||||
* Safely parse data with validation
|
||||
*/
|
||||
export function safeParseData(schema, data) {
|
||||
try {
|
||||
const result = v.safeParse(schema, data);
|
||||
if (result.success) {
|
||||
return {
|
||||
success: true,
|
||||
data: result.output,
|
||||
};
|
||||
}
|
||||
else {
|
||||
return {
|
||||
success: false,
|
||||
errors: formatValidationErrors(result.issues),
|
||||
};
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
errors: [
|
||||
{
|
||||
field: 'unknown',
|
||||
message: error instanceof Error ? error.message : '验证过程中发生未知错误',
|
||||
code: 'UNKNOWN_ERROR',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 解析并验证数据,失败时抛出错误
|
||||
* Parse and validate data, throw error on failure
|
||||
*/
|
||||
export function parseData(schema, data) {
|
||||
const result = safeParseData(schema, data);
|
||||
if (!result.success) {
|
||||
const error = new Error('数据验证失败');
|
||||
error.statusCode = 400;
|
||||
error.validationErrors = result.errors;
|
||||
throw error;
|
||||
}
|
||||
return result.data;
|
||||
}
|
||||
/**
|
||||
* 创建验证中间件函数(用于 API)
|
||||
* Create validation middleware function (for API)
|
||||
*/
|
||||
export function createValidationMiddleware(schema) {
|
||||
return (data) => {
|
||||
return parseData(schema, data);
|
||||
};
|
||||
}
|
||||
/**
|
||||
* 验证查询参数
|
||||
* Validate query parameters
|
||||
*/
|
||||
export function validateQuery(schema, query) {
|
||||
// 转换查询参数中的数字字符串
|
||||
const processedQuery = Object.entries(query).reduce((acc, [key, value]) => {
|
||||
if (value === undefined || value === null || value === '') {
|
||||
return acc;
|
||||
}
|
||||
// 尝试转换数字
|
||||
if (typeof value === 'string' && !isNaN(Number(value))) {
|
||||
acc[key] = Number(value);
|
||||
}
|
||||
else {
|
||||
acc[key] = value;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
return parseData(schema, processedQuery);
|
||||
}
|
||||
/**
|
||||
* 验证请求体数据
|
||||
* Validate request body data
|
||||
*/
|
||||
export function validateBody(schema, body) {
|
||||
return parseData(schema, body);
|
||||
}
|
||||
/**
|
||||
* 验证路径参数
|
||||
* Validate path parameters
|
||||
*/
|
||||
export function validateParams(schema, params) {
|
||||
// 转换路径参数中的数字字符串
|
||||
const processedParams = Object.entries(params).reduce((acc, [key, value]) => {
|
||||
if (typeof value === 'string' && !isNaN(Number(value))) {
|
||||
acc[key] = Number(value);
|
||||
}
|
||||
else {
|
||||
acc[key] = value;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
return parseData(schema, processedParams);
|
||||
}
|
||||
//# sourceMappingURL=validation.js.map
|
||||
1
shared/dist/utils/validation.js.map
vendored
Normal file
1
shared/dist/utils/validation.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"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"}
|
||||
48
shared/package.json
Normal file
48
shared/package.json
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "@nuxt4crud/shared",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"packageManager": "pnpm@8",
|
||||
"engines": {
|
||||
"node": ">=18.0.0",
|
||||
"pnpm": ">=8.0.0"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/index.js",
|
||||
"require": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts"
|
||||
},
|
||||
"./types": {
|
||||
"import": "./dist/types/index.js",
|
||||
"require": "./dist/types/index.js",
|
||||
"types": "./dist/types/index.d.ts"
|
||||
},
|
||||
"./schemas": {
|
||||
"import": "./dist/schemas/index.js",
|
||||
"require": "./dist/schemas/index.js",
|
||||
"types": "./dist/schemas/index.d.ts"
|
||||
},
|
||||
"./utils": {
|
||||
"import": "./dist/utils/index.js",
|
||||
"require": "./dist/utils/index.js",
|
||||
"types": "./dist/utils/index.d.ts"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"dev": "tsc --watch",
|
||||
"clean": "rimraf dist",
|
||||
"type-check": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"valibot": "^1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.6.3",
|
||||
"rimraf": "^5.0.10",
|
||||
"@types/node": "^20.17.6"
|
||||
}
|
||||
}
|
||||
20
shared/src/index.ts
Normal file
20
shared/src/index.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Shared 包主导出文件
|
||||
* 导出所有类型定义、schemas 和工具函数
|
||||
*/
|
||||
|
||||
// 导出类型定义
|
||||
export * from './types/index.js'
|
||||
|
||||
// 导出 schemas(只导出 schema 对象,不导出推断的类型)
|
||||
export {
|
||||
BaseUserSchema,
|
||||
CreateUserSchema,
|
||||
UpdateUserSchema,
|
||||
UserQuerySchema,
|
||||
EmailQuerySchema,
|
||||
UserIdSchema,
|
||||
} from './schemas/index.js'
|
||||
|
||||
// 导出工具函数
|
||||
export * from './utils/index.js'
|
||||
14
shared/src/schemas/index.ts
Normal file
14
shared/src/schemas/index.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Schemas 导出文件
|
||||
* 导出所有验证 schemas
|
||||
*/
|
||||
|
||||
// 只导出 schema 对象,不导出推断的类型(类型在 types 目录中定义)
|
||||
export {
|
||||
BaseUserSchema,
|
||||
CreateUserSchema,
|
||||
UpdateUserSchema,
|
||||
UserQuerySchema,
|
||||
EmailQuerySchema,
|
||||
UserIdSchema,
|
||||
} from './user.js'
|
||||
145
shared/src/schemas/user.ts
Normal file
145
shared/src/schemas/user.ts
Normal file
@@ -0,0 +1,145 @@
|
||||
/**
|
||||
* 用户相关的 Valibot 验证模式
|
||||
* User-related Valibot validation schemas
|
||||
*/
|
||||
|
||||
import * as v from 'valibot'
|
||||
|
||||
/**
|
||||
* 基础用户验证模式
|
||||
* Base user validation schema
|
||||
*/
|
||||
export const BaseUserSchema = v.object({
|
||||
name: v.pipe(
|
||||
v.string('姓名必须是字符串'),
|
||||
v.trim(),
|
||||
v.minLength(2, '姓名至少需要2个字符'),
|
||||
v.maxLength(50, '姓名不能超过50个字符'),
|
||||
v.nonEmpty('姓名不能为空')
|
||||
),
|
||||
email: v.pipe(
|
||||
v.string('邮箱必须是字符串'),
|
||||
v.trim(),
|
||||
v.email('请输入有效的邮箱地址'),
|
||||
v.maxLength(100, '邮箱不能超过100个字符')
|
||||
),
|
||||
age: v.optional(
|
||||
v.pipe(
|
||||
v.number('年龄必须是数字'),
|
||||
v.integer('年龄必须是整数'),
|
||||
v.minValue(1, '年龄不能小于1岁'),
|
||||
v.maxValue(150, '年龄不能超过150岁')
|
||||
)
|
||||
),
|
||||
})
|
||||
|
||||
/**
|
||||
* 创建用户验证模式
|
||||
* Create user validation schema
|
||||
*/
|
||||
export const CreateUserSchema = BaseUserSchema
|
||||
|
||||
/**
|
||||
* 更新用户验证模式 - 所有字段都是可选的
|
||||
* Update user validation schema - all fields are optional
|
||||
*/
|
||||
export const UpdateUserSchema = v.object({
|
||||
name: v.optional(
|
||||
v.pipe(
|
||||
v.string('姓名必须是字符串'),
|
||||
v.trim(),
|
||||
v.minLength(2, '姓名至少需要2个字符'),
|
||||
v.maxLength(50, '姓名不能超过50个字符'),
|
||||
v.nonEmpty('姓名不能为空')
|
||||
)
|
||||
),
|
||||
email: v.optional(
|
||||
v.pipe(
|
||||
v.string('邮箱必须是字符串'),
|
||||
v.trim(),
|
||||
v.email('请输入有效的邮箱地址'),
|
||||
v.maxLength(100, '邮箱不能超过100个字符')
|
||||
)
|
||||
),
|
||||
age: v.optional(
|
||||
v.pipe(
|
||||
v.number('年龄必须是数字'),
|
||||
v.integer('年龄必须是整数'),
|
||||
v.minValue(1, '年龄不能小于1岁'),
|
||||
v.maxValue(150, '年龄不能超过150岁')
|
||||
)
|
||||
),
|
||||
})
|
||||
|
||||
/**
|
||||
* 用户查询参数验证模式
|
||||
* User query parameters validation schema
|
||||
*/
|
||||
export const UserQuerySchema = v.object({
|
||||
page: v.optional(
|
||||
v.pipe(v.number('页码必须是数字'), v.integer('页码必须是整数'), v.minValue(1, '页码不能小于1')),
|
||||
1
|
||||
),
|
||||
limit: v.optional(
|
||||
v.pipe(
|
||||
v.number('每页数量必须是数字'),
|
||||
v.integer('每页数量必须是整数'),
|
||||
v.minValue(1, '每页数量不能小于1'),
|
||||
v.maxValue(100, '每页数量不能超过100')
|
||||
),
|
||||
10
|
||||
),
|
||||
search: v.optional(
|
||||
v.pipe(
|
||||
v.string('搜索关键词必须是字符串'),
|
||||
v.trim(),
|
||||
v.maxLength(100, '搜索关键词不能超过100个字符')
|
||||
)
|
||||
),
|
||||
minAge: v.optional(
|
||||
v.pipe(
|
||||
v.number('最小年龄必须是数字'),
|
||||
v.integer('最小年龄必须是整数'),
|
||||
v.minValue(1, '最小年龄不能小于1岁')
|
||||
)
|
||||
),
|
||||
maxAge: v.optional(
|
||||
v.pipe(
|
||||
v.number('最大年龄必须是数字'),
|
||||
v.integer('最大年龄必须是整数'),
|
||||
v.maxValue(150, '最大年龄不能超过150岁')
|
||||
)
|
||||
),
|
||||
})
|
||||
|
||||
/**
|
||||
* 邮箱查询验证模式
|
||||
* Email query validation schema
|
||||
*/
|
||||
export const EmailQuerySchema = v.object({
|
||||
email: v.pipe(
|
||||
v.string('邮箱必须是字符串'),
|
||||
v.trim(),
|
||||
v.email('请输入有效的邮箱地址'),
|
||||
v.nonEmpty('邮箱不能为空')
|
||||
),
|
||||
})
|
||||
|
||||
/**
|
||||
* ID 参数验证模式
|
||||
* ID parameter validation schema
|
||||
*/
|
||||
export const UserIdSchema = v.object({
|
||||
id: v.pipe(
|
||||
v.number('用户ID必须是数字'),
|
||||
v.integer('用户ID必须是整数'),
|
||||
v.minValue(1, '用户ID必须大于0')
|
||||
),
|
||||
})
|
||||
|
||||
// 导出类型推断
|
||||
export type CreateUserInput = v.InferInput<typeof CreateUserSchema>
|
||||
export type UpdateUserInput = v.InferInput<typeof UpdateUserSchema>
|
||||
export type UserQueryParams = v.InferInput<typeof UserQuerySchema>
|
||||
export type EmailQuery = v.InferInput<typeof EmailQuerySchema>
|
||||
export type UserIdParams = v.InferInput<typeof UserIdSchema>
|
||||
91
shared/src/types/base.ts
Normal file
91
shared/src/types/base.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* 基础类型定义
|
||||
* Base type definitions for the application
|
||||
*/
|
||||
|
||||
/**
|
||||
* 基础实体接口 - 所有实体都应该有的基础字段
|
||||
* Base entity interface - common fields for all entities
|
||||
*/
|
||||
export interface BaseEntity {
|
||||
id: number
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
}
|
||||
|
||||
/**
|
||||
* API 响应基础结构
|
||||
* Base API response structure
|
||||
*/
|
||||
export interface ApiResponse<T = any> {
|
||||
success: boolean
|
||||
data?: T
|
||||
message?: string
|
||||
error?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询参数
|
||||
* Pagination query parameters
|
||||
*/
|
||||
export interface PaginationParams {
|
||||
page?: number
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页响应结构
|
||||
* Paginated response structure
|
||||
*/
|
||||
export interface PaginatedResponse<T> {
|
||||
data: T[]
|
||||
pagination: {
|
||||
page: number
|
||||
limit: number
|
||||
total: number
|
||||
totalPages: number
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询操作符枚举
|
||||
* Query operators enum
|
||||
*/
|
||||
export enum QueryOperator {
|
||||
EQUALS = 'equals',
|
||||
NOT_EQUALS = 'not_equals',
|
||||
CONTAINS = 'contains',
|
||||
NOT_CONTAINS = 'not_contains',
|
||||
STARTS_WITH = 'starts_with',
|
||||
ENDS_WITH = 'ends_with',
|
||||
GREATER_THAN = 'gt',
|
||||
GREATER_THAN_OR_EQUAL = 'gte',
|
||||
LESS_THAN = 'lt',
|
||||
LESS_THAN_OR_EQUAL = 'lte',
|
||||
IN = 'in',
|
||||
NOT_IN = 'not_in',
|
||||
IS_NULL = 'is_null',
|
||||
IS_NOT_NULL = 'is_not_null',
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询条件接口
|
||||
* Query condition interface
|
||||
*/
|
||||
export interface QueryCondition {
|
||||
field: string
|
||||
operator: QueryOperator
|
||||
value?: any
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用查询参数
|
||||
* Universal query parameters
|
||||
*/
|
||||
export interface UniversalQueryParams extends PaginationParams {
|
||||
conditions?: QueryCondition[]
|
||||
orderBy?: {
|
||||
field: string
|
||||
direction: 'asc' | 'desc'
|
||||
}[]
|
||||
}
|
||||
9
shared/src/types/index.ts
Normal file
9
shared/src/types/index.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* 类型定义导出索引
|
||||
* Types export index
|
||||
*/
|
||||
|
||||
export * from './base.js'
|
||||
export * from './post.js'
|
||||
export * from './user.js'
|
||||
|
||||
25
shared/src/types/post.ts
Normal file
25
shared/src/types/post.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Post 类型定义
|
||||
* 基于 Prisma 生成的类型
|
||||
*/
|
||||
|
||||
export interface Post {
|
||||
id: number
|
||||
title: string
|
||||
content: string | null
|
||||
published: boolean
|
||||
createdAt: Date | string
|
||||
updatedAt: Date | string
|
||||
}
|
||||
|
||||
export interface CreatePostInput {
|
||||
title: string
|
||||
content?: string
|
||||
published?: boolean
|
||||
}
|
||||
|
||||
export interface UpdatePostInput {
|
||||
title?: string
|
||||
content?: string
|
||||
published?: boolean
|
||||
}
|
||||
64
shared/src/types/user.ts
Normal file
64
shared/src/types/user.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* 用户相关类型定义
|
||||
* User-related type definitions
|
||||
*/
|
||||
|
||||
import type { BaseEntity } from './base.js'
|
||||
|
||||
/**
|
||||
* 用户实体接口
|
||||
* User entity interface
|
||||
*/
|
||||
export interface User extends BaseEntity {
|
||||
name: string
|
||||
email: string
|
||||
age?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建用户输入类型
|
||||
* Create user input type
|
||||
*/
|
||||
export interface CreateUserInput {
|
||||
name: string
|
||||
email: string
|
||||
age?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户输入类型
|
||||
* Update user input type
|
||||
*/
|
||||
export interface UpdateUserInput {
|
||||
name?: string
|
||||
email?: string
|
||||
age?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户查询参数类型
|
||||
* User query parameters type
|
||||
*/
|
||||
export interface UserQueryParams {
|
||||
page?: number
|
||||
limit?: number
|
||||
search?: string
|
||||
minAge?: number
|
||||
maxAge?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* 邮箱查询参数类型
|
||||
* Email query parameters type
|
||||
*/
|
||||
export interface EmailQuery {
|
||||
email: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户ID参数类型
|
||||
* User ID parameters type
|
||||
*/
|
||||
export interface UserIdParams {
|
||||
id: number
|
||||
}
|
||||
6
shared/src/utils/index.ts
Normal file
6
shared/src/utils/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Utils 导出索引
|
||||
* Utils export index
|
||||
*/
|
||||
|
||||
export * from './validation.js'
|
||||
171
shared/src/utils/validation.ts
Normal file
171
shared/src/utils/validation.ts
Normal file
@@ -0,0 +1,171 @@
|
||||
/**
|
||||
* 通用验证工具函数
|
||||
* Common validation utility functions
|
||||
*/
|
||||
|
||||
import * as v from 'valibot'
|
||||
|
||||
/**
|
||||
* 验证错误接口
|
||||
* Validation error interface
|
||||
*/
|
||||
export interface ValidationError {
|
||||
field: string
|
||||
message: string
|
||||
code: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证结果接口
|
||||
* Validation result interface
|
||||
*/
|
||||
export interface ValidationResult<T> {
|
||||
success: boolean
|
||||
data?: T
|
||||
errors?: ValidationError[]
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 Valibot 验证错误转换为自定义格式
|
||||
* Convert Valibot validation errors to custom format
|
||||
*/
|
||||
export function formatValidationErrors(issues: v.BaseIssue<unknown>[]): ValidationError[] {
|
||||
return issues.map(issue => ({
|
||||
field: issue.path?.map(p => p.key).join('.') || 'unknown',
|
||||
message: issue.message,
|
||||
code: issue.type || 'VALIDATION_ERROR',
|
||||
}))
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全解析数据
|
||||
* Safely parse data with validation
|
||||
*/
|
||||
export function safeParseData<T>(
|
||||
schema: v.BaseSchema<unknown, T, v.BaseIssue<unknown>>,
|
||||
data: unknown
|
||||
): ValidationResult<T> {
|
||||
try {
|
||||
const result = v.safeParse(schema, data)
|
||||
|
||||
if (result.success) {
|
||||
return {
|
||||
success: true,
|
||||
data: result.output,
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
success: false,
|
||||
errors: formatValidationErrors(result.issues),
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
errors: [
|
||||
{
|
||||
field: 'unknown',
|
||||
message: error instanceof Error ? error.message : '验证过程中发生未知错误',
|
||||
code: 'UNKNOWN_ERROR',
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析并验证数据,失败时抛出错误
|
||||
* Parse and validate data, throw error on failure
|
||||
*/
|
||||
export function parseData<T>(
|
||||
schema: v.BaseSchema<unknown, T, v.BaseIssue<unknown>>,
|
||||
data: unknown
|
||||
): T {
|
||||
const result = safeParseData(schema, data)
|
||||
|
||||
if (!result.success) {
|
||||
const error = new Error('数据验证失败') as any
|
||||
error.statusCode = 400
|
||||
error.validationErrors = result.errors
|
||||
throw error
|
||||
}
|
||||
|
||||
return result.data!
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建验证中间件函数(用于 API)
|
||||
* Create validation middleware function (for API)
|
||||
*/
|
||||
export function createValidationMiddleware<T>(
|
||||
schema: v.BaseSchema<unknown, T, v.BaseIssue<unknown>>
|
||||
) {
|
||||
return (data: unknown): T => {
|
||||
return parseData(schema, data)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证查询参数
|
||||
* Validate query parameters
|
||||
*/
|
||||
export function validateQuery<T>(
|
||||
schema: v.BaseSchema<unknown, T, v.BaseIssue<unknown>>,
|
||||
query: Record<string, any>
|
||||
): T {
|
||||
// 转换查询参数中的数字字符串
|
||||
const processedQuery = Object.entries(query).reduce(
|
||||
(acc, [key, value]) => {
|
||||
if (value === undefined || value === null || value === '') {
|
||||
return acc
|
||||
}
|
||||
|
||||
// 尝试转换数字
|
||||
if (typeof value === 'string' && !isNaN(Number(value))) {
|
||||
acc[key] = Number(value)
|
||||
} else {
|
||||
acc[key] = value
|
||||
}
|
||||
|
||||
return acc
|
||||
},
|
||||
{} as Record<string, any>
|
||||
)
|
||||
|
||||
return parseData(schema, processedQuery)
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证请求体数据
|
||||
* Validate request body data
|
||||
*/
|
||||
export function validateBody<T>(
|
||||
schema: v.BaseSchema<unknown, T, v.BaseIssue<unknown>>,
|
||||
body: unknown
|
||||
): T {
|
||||
return parseData(schema, body)
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证路径参数
|
||||
* Validate path parameters
|
||||
*/
|
||||
export function validateParams<T>(
|
||||
schema: v.BaseSchema<unknown, T, v.BaseIssue<unknown>>,
|
||||
params: Record<string, any>
|
||||
): T {
|
||||
// 转换路径参数中的数字字符串
|
||||
const processedParams = Object.entries(params).reduce(
|
||||
(acc, [key, value]) => {
|
||||
if (typeof value === 'string' && !isNaN(Number(value))) {
|
||||
acc[key] = Number(value)
|
||||
} else {
|
||||
acc[key] = value
|
||||
}
|
||||
return acc
|
||||
},
|
||||
{} as Record<string, any>
|
||||
)
|
||||
|
||||
return parseData(schema, processedParams)
|
||||
}
|
||||
9
shared/tsconfig.json
Normal file
9
shared/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
14
shared/types/base.ts
Normal file
14
shared/types/base.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* 基础类型定义
|
||||
* Base type definitions
|
||||
*/
|
||||
|
||||
/**
|
||||
* 基础实体接口 - 所有实体都应该有的基础字段
|
||||
* Base entity interface - common fields for all entities
|
||||
*/
|
||||
export interface BaseEntity {
|
||||
id: number
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
}
|
||||
129
shared/types/index.ts
Normal file
129
shared/types/index.ts
Normal file
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
* 类型定义统一导出
|
||||
* Unified type definitions export
|
||||
*
|
||||
* 共享类型定义文件
|
||||
* 用于前后端类型一致性
|
||||
*/
|
||||
|
||||
// 基础类型
|
||||
export * from './base'
|
||||
|
||||
// 用户相关类型
|
||||
export * from './user'
|
||||
|
||||
// 飞书相关类型
|
||||
export * from './feishu'
|
||||
|
||||
// 上海CIM相关类型
|
||||
export * from './cim'
|
||||
|
||||
// 验证相关类型和工具
|
||||
export * from '../src/schemas/user'
|
||||
export * from '../utils/validation'
|
||||
|
||||
// ==================== API 响应类型 ====================
|
||||
|
||||
/**
|
||||
* API 响应类型
|
||||
* @template T 响应数据类型
|
||||
*/
|
||||
export interface ApiResponse<T = any> {
|
||||
success: boolean
|
||||
data?: T
|
||||
message?: string
|
||||
error?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页参数类型
|
||||
*/
|
||||
export interface PaginationParams {
|
||||
page?: number
|
||||
limit?: number
|
||||
search?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页响应类型
|
||||
* @template T 数据项类型
|
||||
*/
|
||||
export interface PaginatedResponse<T> {
|
||||
data: T[]
|
||||
total: number
|
||||
page: number
|
||||
limit: number
|
||||
totalPages: number
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单验证规则类型
|
||||
*/
|
||||
export interface FormRule {
|
||||
required?: boolean
|
||||
message?: string
|
||||
trigger?: string | string[]
|
||||
min?: number
|
||||
max?: number
|
||||
pattern?: RegExp
|
||||
}
|
||||
|
||||
/**
|
||||
* 表格列配置类型
|
||||
*/
|
||||
export interface TableColumn {
|
||||
prop: string
|
||||
label: string
|
||||
width?: string | number
|
||||
sortable?: boolean
|
||||
formatter?: (row: any, column: any, cellValue: any) => string
|
||||
}
|
||||
|
||||
// ==================== 通用 CRUD 类型定义 ====================
|
||||
|
||||
/**
|
||||
* 通用查询参数接口
|
||||
*/
|
||||
export interface BaseQueryParams extends PaginationParams {
|
||||
orderBy?: string
|
||||
orderDirection?: 'asc' | 'desc'
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用创建输入类型
|
||||
*/
|
||||
export interface BaseCreateInput {
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用更新输入类型
|
||||
*/
|
||||
export interface BaseUpdateInput {
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
/**
|
||||
* CRUD 操作选项
|
||||
*/
|
||||
export interface CrudOptions {
|
||||
// 是否启用软删除
|
||||
softDelete?: boolean
|
||||
// 默认排序字段
|
||||
defaultOrderBy?: string
|
||||
// 默认排序方向
|
||||
defaultOrderDirection?: 'asc' | 'desc'
|
||||
// 可搜索字段
|
||||
searchableFields?: string[]
|
||||
// 唯一字段验证
|
||||
uniqueFields?: string[]
|
||||
}
|
||||
|
||||
/**
|
||||
* 扩展的API响应类型,包含验证错误
|
||||
* @template T 响应数据类型
|
||||
*/
|
||||
export interface ExtendedApiResponse<T = any> extends ApiResponse<T> {
|
||||
validationErrors?: ValidationError[]
|
||||
}
|
||||
19
shared/types/user.ts
Normal file
19
shared/types/user.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 用户相关类型定义
|
||||
* User-related type definitions
|
||||
*/
|
||||
|
||||
import { BaseEntity } from './base'
|
||||
|
||||
/**
|
||||
* 用户实体接口
|
||||
* User entity interface
|
||||
*/
|
||||
export interface User extends BaseEntity {
|
||||
name: string
|
||||
email: string
|
||||
age: number | null
|
||||
}
|
||||
|
||||
// 注意:CreateUserInput 和 UpdateUserInput 类型现在在 ~/shared/schemas/user.ts 中定义
|
||||
// 请从 ~/shared/schemas/user 导入这些类型
|
||||
Reference in New Issue
Block a user