refactor(data): replace schema classes with readonly models
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* 聊天历史响应
|
||||
*
|
||||
*
|
||||
*/
|
||||
import { z } from "zod";
|
||||
|
||||
@@ -9,45 +9,26 @@ import {
|
||||
booleanOrFalse,
|
||||
numberOrZero,
|
||||
} from "../../nullable-defaults";
|
||||
import { ChatMessage, ChatMessageSchema } from "../chat_message";
|
||||
import { ChatMessageSchema } from "../chat_message";
|
||||
|
||||
export const ChatHistoryResponseSchema = z.object({
|
||||
messages: arrayOrEmpty(ChatMessageSchema),
|
||||
total: numberOrZero,
|
||||
limit: numberOrZero,
|
||||
offset: numberOrZero,
|
||||
isVip: booleanOrFalse,
|
||||
privateFreeLimit: numberOrZero,
|
||||
privateUsedToday: numberOrZero,
|
||||
privateCanViewFree: booleanOrFalse,
|
||||
});
|
||||
export const ChatHistoryResponseSchema = z
|
||||
.object({
|
||||
messages: arrayOrEmpty(ChatMessageSchema),
|
||||
total: numberOrZero,
|
||||
limit: numberOrZero,
|
||||
offset: numberOrZero,
|
||||
isVip: booleanOrFalse,
|
||||
privateFreeLimit: numberOrZero,
|
||||
privateUsedToday: numberOrZero,
|
||||
privateCanViewFree: booleanOrFalse,
|
||||
})
|
||||
.readonly();
|
||||
|
||||
export type ChatHistoryResponseInput = z.input<typeof ChatHistoryResponseSchema>;
|
||||
export type ChatHistoryResponseData = z.output<typeof ChatHistoryResponseSchema>;
|
||||
export type ChatHistoryResponseInput = z.input<
|
||||
typeof ChatHistoryResponseSchema
|
||||
>;
|
||||
export type ChatHistoryResponseData = z.output<
|
||||
typeof ChatHistoryResponseSchema
|
||||
>;
|
||||
|
||||
export class ChatHistoryResponse {
|
||||
declare readonly messages: ChatMessage[];
|
||||
declare readonly total: number;
|
||||
declare readonly limit: number;
|
||||
|
||||
private constructor(input: ChatHistoryResponseInput) {
|
||||
const data = ChatHistoryResponseSchema.parse(input);
|
||||
Object.assign(this, {
|
||||
...data,
|
||||
messages: data.messages.map((m) => ChatMessage.from(m)),
|
||||
});
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
static from(input: ChatHistoryResponseInput): ChatHistoryResponse {
|
||||
return new ChatHistoryResponse(input);
|
||||
}
|
||||
|
||||
static fromJson(json: unknown): ChatHistoryResponse {
|
||||
return ChatHistoryResponse.from(json as ChatHistoryResponseInput);
|
||||
}
|
||||
|
||||
toJson(): ChatHistoryResponseData {
|
||||
return ChatHistoryResponseSchema.parse(this);
|
||||
}
|
||||
}
|
||||
export type ChatHistoryResponse = ChatHistoryResponseData;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* 发送消息响应
|
||||
*
|
||||
*
|
||||
*/
|
||||
import { z } from "zod";
|
||||
import {
|
||||
@@ -10,60 +10,27 @@ import {
|
||||
numberOrZero,
|
||||
stringOrEmpty,
|
||||
} from "../../nullable-defaults";
|
||||
import {
|
||||
ChatImageSchema,
|
||||
ChatLockDetailSchema,
|
||||
type ChatImageData,
|
||||
type ChatLockDetailData,
|
||||
} from "../chat_payloads";
|
||||
import { ChatImageSchema, ChatLockDetailSchema } from "../chat_payloads";
|
||||
|
||||
export const ChatSendResponseSchema = z.object({
|
||||
reply: stringOrEmpty,
|
||||
audioUrl: stringOrEmpty,
|
||||
messageId: stringOrEmpty,
|
||||
isGuest: booleanOrFalse,
|
||||
// 函数式 default —— 每次 parse 时重新调 Date.now()(后端不返回 timestamp 时用当下时间)
|
||||
timestamp: numberOrLazy(() => Date.now()),
|
||||
image: ChatImageSchema,
|
||||
lockDetail: ChatLockDetailSchema,
|
||||
canSendMessage: booleanOrTrue,
|
||||
creditBalance: numberOrZero,
|
||||
creditsCharged: numberOrZero,
|
||||
requiredCredits: numberOrZero,
|
||||
shortfallCredits: numberOrZero,
|
||||
});
|
||||
export const ChatSendResponseSchema = z
|
||||
.object({
|
||||
reply: stringOrEmpty,
|
||||
audioUrl: stringOrEmpty,
|
||||
messageId: stringOrEmpty,
|
||||
isGuest: booleanOrFalse,
|
||||
// 函数式 default —— 每次 parse 时重新调 Date.now()(后端不返回 timestamp 时用当下时间)
|
||||
timestamp: numberOrLazy(() => Date.now()),
|
||||
image: ChatImageSchema,
|
||||
lockDetail: ChatLockDetailSchema,
|
||||
canSendMessage: booleanOrTrue,
|
||||
creditBalance: numberOrZero,
|
||||
creditsCharged: numberOrZero,
|
||||
requiredCredits: numberOrZero,
|
||||
shortfallCredits: numberOrZero,
|
||||
})
|
||||
.readonly();
|
||||
|
||||
export type ChatSendResponseInput = z.input<typeof ChatSendResponseSchema>;
|
||||
export type ChatSendResponseData = z.output<typeof ChatSendResponseSchema>;
|
||||
|
||||
export class ChatSendResponse {
|
||||
declare readonly reply: string;
|
||||
declare readonly audioUrl: string;
|
||||
declare readonly messageId: string;
|
||||
declare readonly timestamp: number;
|
||||
declare readonly image: ChatImageData;
|
||||
declare readonly lockDetail: ChatLockDetailData;
|
||||
declare readonly canSendMessage: boolean;
|
||||
declare readonly creditBalance: number;
|
||||
declare readonly creditsCharged: number;
|
||||
declare readonly requiredCredits: number;
|
||||
declare readonly shortfallCredits: number;
|
||||
|
||||
private constructor(input: ChatSendResponseInput) {
|
||||
const data = ChatSendResponseSchema.parse(input);
|
||||
Object.assign(this, data);
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
static from(input: ChatSendResponseInput): ChatSendResponse {
|
||||
return new ChatSendResponse(input);
|
||||
}
|
||||
|
||||
static fromJson(json: unknown): ChatSendResponse {
|
||||
return ChatSendResponse.from(json as ChatSendResponseInput);
|
||||
}
|
||||
|
||||
toJson(): ChatSendResponseData {
|
||||
return ChatSendResponseSchema.parse(this);
|
||||
}
|
||||
}
|
||||
export type ChatSendResponse = ChatSendResponseData;
|
||||
|
||||
@@ -18,21 +18,23 @@ export const UnlockHistoryReasonSchema = z.enum([
|
||||
"no_locked_messages",
|
||||
]);
|
||||
|
||||
export const UnlockHistoryResponseSchema = z.object({
|
||||
unlocked: booleanOrFalse,
|
||||
reason: UnlockHistoryReasonSchema,
|
||||
totalLocked: numberOrZero,
|
||||
unlockedCount: numberOrZero,
|
||||
privateCount: numberOrZero,
|
||||
imageCount: numberOrZero,
|
||||
voiceCount: numberOrZero,
|
||||
requiredCredits: numberOrZero,
|
||||
currentCredits: numberOrZero,
|
||||
remainingCredits: numberOrZero,
|
||||
shortfallCredits: numberOrZero,
|
||||
costsByMessage: UnlockHistoryCostsByMessageSchema,
|
||||
messageIds: arrayOrEmpty(z.string()),
|
||||
});
|
||||
export const UnlockHistoryResponseSchema = z
|
||||
.object({
|
||||
unlocked: booleanOrFalse,
|
||||
reason: UnlockHistoryReasonSchema,
|
||||
totalLocked: numberOrZero,
|
||||
unlockedCount: numberOrZero,
|
||||
privateCount: numberOrZero,
|
||||
imageCount: numberOrZero,
|
||||
voiceCount: numberOrZero,
|
||||
requiredCredits: numberOrZero,
|
||||
currentCredits: numberOrZero,
|
||||
remainingCredits: numberOrZero,
|
||||
shortfallCredits: numberOrZero,
|
||||
costsByMessage: UnlockHistoryCostsByMessageSchema,
|
||||
messageIds: arrayOrEmpty(z.string()),
|
||||
})
|
||||
.readonly();
|
||||
|
||||
export type UnlockHistoryReason = z.output<typeof UnlockHistoryReasonSchema>;
|
||||
export type UnlockHistoryResponseInput = z.input<
|
||||
@@ -42,26 +44,4 @@ export type UnlockHistoryResponseData = z.output<
|
||||
typeof UnlockHistoryResponseSchema
|
||||
>;
|
||||
|
||||
export class UnlockHistoryResponse {
|
||||
declare readonly unlocked: boolean;
|
||||
declare readonly reason: UnlockHistoryReason;
|
||||
declare readonly shortfallCredits: number;
|
||||
|
||||
private constructor(input: UnlockHistoryResponseInput) {
|
||||
const data = UnlockHistoryResponseSchema.parse(input);
|
||||
Object.assign(this, data);
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
static from(input: UnlockHistoryResponseInput): UnlockHistoryResponse {
|
||||
return new UnlockHistoryResponse(input);
|
||||
}
|
||||
|
||||
static fromJson(json: unknown): UnlockHistoryResponse {
|
||||
return UnlockHistoryResponse.from(json as UnlockHistoryResponseInput);
|
||||
}
|
||||
|
||||
toJson(): UnlockHistoryResponseData {
|
||||
return UnlockHistoryResponseSchema.parse(this);
|
||||
}
|
||||
}
|
||||
export type UnlockHistoryResponse = UnlockHistoryResponseData;
|
||||
|
||||
@@ -6,28 +6,30 @@ import {
|
||||
stringOrEmpty,
|
||||
stringOrNull,
|
||||
} from "../../nullable-defaults";
|
||||
import { ChatImageSchema, type ChatImageData } from "../chat_payloads";
|
||||
import { ChatLockTypeSchema } from "../chat_lock_type";
|
||||
import { ChatImageSchema } from "../chat_payloads";
|
||||
|
||||
/**
|
||||
* 单条历史付费 / 私密消息解锁响应。
|
||||
*/
|
||||
export const UnlockPrivateReasonSchema = stringOrEmpty;
|
||||
|
||||
export const UnlockPrivateResponseSchema = z.object({
|
||||
unlocked: booleanOrFalse,
|
||||
content: stringOrEmpty,
|
||||
messageId: stringOrEmpty,
|
||||
clientLockId: stringOrNull,
|
||||
lockType: ChatLockTypeSchema.nullable().default(null),
|
||||
audioUrl: stringOrEmpty,
|
||||
image: ChatImageSchema,
|
||||
reason: UnlockPrivateReasonSchema,
|
||||
creditBalance: numberOrZero,
|
||||
creditsCharged: numberOrZero,
|
||||
requiredCredits: numberOrZero,
|
||||
shortfallCredits: numberOrZero,
|
||||
});
|
||||
export const UnlockPrivateResponseSchema = z
|
||||
.object({
|
||||
unlocked: booleanOrFalse,
|
||||
content: stringOrEmpty,
|
||||
messageId: stringOrEmpty,
|
||||
clientLockId: stringOrNull,
|
||||
lockType: ChatLockTypeSchema.nullable().default(null),
|
||||
audioUrl: stringOrEmpty,
|
||||
image: ChatImageSchema,
|
||||
reason: UnlockPrivateReasonSchema,
|
||||
creditBalance: numberOrZero,
|
||||
creditsCharged: numberOrZero,
|
||||
requiredCredits: numberOrZero,
|
||||
shortfallCredits: numberOrZero,
|
||||
})
|
||||
.readonly();
|
||||
|
||||
export type UnlockPrivateReason = z.output<typeof UnlockPrivateReasonSchema>;
|
||||
export type UnlockPrivateResponseInput = z.input<
|
||||
@@ -37,36 +39,4 @@ export type UnlockPrivateResponseData = z.output<
|
||||
typeof UnlockPrivateResponseSchema
|
||||
>;
|
||||
|
||||
/**
|
||||
* 单条历史付费 / 私密消息解锁响应数据类。
|
||||
*/
|
||||
export class UnlockPrivateResponse {
|
||||
declare readonly unlocked: boolean;
|
||||
declare readonly messageId: string;
|
||||
declare readonly content: string;
|
||||
declare readonly audioUrl: string;
|
||||
declare readonly image: ChatImageData;
|
||||
declare readonly reason: UnlockPrivateReason;
|
||||
declare readonly creditBalance: number;
|
||||
declare readonly creditsCharged: number;
|
||||
declare readonly requiredCredits: number;
|
||||
declare readonly shortfallCredits: number;
|
||||
|
||||
private constructor(input: UnlockPrivateResponseInput) {
|
||||
const data = UnlockPrivateResponseSchema.parse(input);
|
||||
Object.assign(this, data);
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
static from(input: UnlockPrivateResponseInput): UnlockPrivateResponse {
|
||||
return new UnlockPrivateResponse(input);
|
||||
}
|
||||
|
||||
static fromJson(json: unknown): UnlockPrivateResponse {
|
||||
return UnlockPrivateResponse.from(json as UnlockPrivateResponseInput);
|
||||
}
|
||||
|
||||
toJson(): UnlockPrivateResponseData {
|
||||
return UnlockPrivateResponseSchema.parse(this);
|
||||
}
|
||||
}
|
||||
export type UnlockPrivateResponse = UnlockPrivateResponseData;
|
||||
|
||||
Reference in New Issue
Block a user