feat: setup barrelsby for automatic barrel file generation
Add barrelsby as a dev dependency with a `generate-barrels` npm script and a `barrelesby.json` config targeting `./src`. This automates creation of barrel/index files to simplify imports across the project.
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Apple 登录请求
|
||||
* 原始 Dart: AppleLoginRequest (lib/data/models/auth/auth_request.dart)
|
||||
*/
|
||||
export class AppleLoginRequest {
|
||||
readonly identityToken: string;
|
||||
readonly platform: string;
|
||||
|
||||
constructor(params: { identityToken: string; platform: string }) {
|
||||
this.identityToken = params.identityToken;
|
||||
this.platform = params.platform;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
identityToken: this.identityToken,
|
||||
platform: this.platform,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): AppleLoginRequest {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`AppleLoginRequest.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new AppleLoginRequest({
|
||||
identityToken: requireString("identityToken"),
|
||||
platform: requireString("platform"),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Facebook 登录请求
|
||||
* 原始 Dart: FacebookLoginRequest (lib/data/models/auth/auth_request.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `guestId` 为 `String?`,按"全部非空"约定统一兜底为空串。
|
||||
*/
|
||||
export class FacebookLoginRequest {
|
||||
readonly accessToken: string;
|
||||
readonly platform: string;
|
||||
readonly guestId: string;
|
||||
|
||||
constructor(params: {
|
||||
accessToken: string;
|
||||
platform: string;
|
||||
guestId?: string;
|
||||
}) {
|
||||
this.accessToken = params.accessToken;
|
||||
this.platform = params.platform;
|
||||
this.guestId = params.guestId ?? "";
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
accessToken: this.accessToken,
|
||||
platform: this.platform,
|
||||
guestId: this.guestId,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): FacebookLoginRequest {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`FacebookLoginRequest.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new FacebookLoginRequest({
|
||||
accessToken: requireString("accessToken"),
|
||||
platform: requireString("platform"),
|
||||
guestId: typeof json.guestId === "string" ? json.guestId : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Facebook ID 登录请求
|
||||
* 原始 Dart: FbIdLoginRequest (lib/data/models/auth/auth_request.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `avatarUrl` 为 `String?`,按"全部非空"约定统一兜底为空串。
|
||||
*/
|
||||
export class FbIdLoginRequest {
|
||||
readonly fbId: string;
|
||||
readonly avatarUrl: string;
|
||||
|
||||
constructor(params: { fbId: string; avatarUrl?: string }) {
|
||||
this.fbId = params.fbId;
|
||||
this.avatarUrl = params.avatarUrl ?? "";
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
fbId: this.fbId,
|
||||
avatarUrl: this.avatarUrl,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): FbIdLoginRequest {
|
||||
const fbId = json.fbId;
|
||||
if (typeof fbId !== "string") {
|
||||
throw new Error(
|
||||
"FbIdLoginRequest.fbId is required and must be a string"
|
||||
);
|
||||
}
|
||||
return new FbIdLoginRequest({
|
||||
fbId,
|
||||
avatarUrl:
|
||||
typeof json.avatarUrl === "string" ? json.avatarUrl : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Google 登录请求
|
||||
* 原始 Dart: GoogleLoginRequest (lib/data/models/auth/auth_request.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `guestId` 为 `String?`,按"全部非空"约定统一兜底为空串。
|
||||
*/
|
||||
export class GoogleLoginRequest {
|
||||
readonly idToken: string;
|
||||
readonly platform: string;
|
||||
readonly guestId: string;
|
||||
|
||||
constructor(params: {
|
||||
idToken: string;
|
||||
platform: string;
|
||||
guestId?: string;
|
||||
}) {
|
||||
this.idToken = params.idToken;
|
||||
this.platform = params.platform;
|
||||
this.guestId = params.guestId ?? "";
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
idToken: this.idToken,
|
||||
platform: this.platform,
|
||||
guestId: this.guestId,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): GoogleLoginRequest {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`GoogleLoginRequest.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new GoogleLoginRequest({
|
||||
idToken: requireString("idToken"),
|
||||
platform: requireString("platform"),
|
||||
guestId: typeof json.guestId === "string" ? json.guestId : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 游客登录请求
|
||||
* 原始 Dart: GuestLoginRequest (lib/data/models/auth/auth_request.dart)
|
||||
*/
|
||||
export class GuestLoginRequest {
|
||||
readonly deviceId: string;
|
||||
|
||||
constructor(params: { deviceId: string }) {
|
||||
this.deviceId = params.deviceId;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return { deviceId: this.deviceId };
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): GuestLoginRequest {
|
||||
const deviceId = json.deviceId;
|
||||
if (typeof deviceId !== "string") {
|
||||
throw new Error(
|
||||
"GuestLoginRequest.deviceId is required and must be a string"
|
||||
);
|
||||
}
|
||||
return new GuestLoginRequest({ deviceId });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* 游客登录响应
|
||||
* 原始 Dart: GuestLoginResponse (lib/data/models/auth/auth_response.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `user` 为 `User?`,按"全部非空"约定兜底为默认 User 实例
|
||||
* (id/username 为空串,使用方可通过 user.id === "" 判定无用户数据)。
|
||||
*/
|
||||
import { User } from "../user/user";
|
||||
|
||||
export class GuestLoginResponse {
|
||||
readonly token: string;
|
||||
readonly deviceId: string;
|
||||
readonly userId: string;
|
||||
readonly isDeviceUser: boolean;
|
||||
readonly expiresIn: number;
|
||||
readonly user: User;
|
||||
|
||||
constructor(params: {
|
||||
token: string;
|
||||
deviceId: string;
|
||||
userId: string;
|
||||
isDeviceUser?: boolean;
|
||||
expiresIn?: number;
|
||||
user?: User;
|
||||
}) {
|
||||
this.token = params.token;
|
||||
this.deviceId = params.deviceId;
|
||||
this.userId = params.userId;
|
||||
this.isDeviceUser = params.isDeviceUser ?? true;
|
||||
this.expiresIn = params.expiresIn ?? 2592000;
|
||||
this.user = params.user ?? new User({ id: "", username: "" });
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
token: this.token,
|
||||
deviceId: this.deviceId,
|
||||
userId: this.userId,
|
||||
isDeviceUser: this.isDeviceUser,
|
||||
expiresIn: this.expiresIn,
|
||||
user: this.user.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): GuestLoginResponse {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`GuestLoginResponse.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
const userJson = json.user;
|
||||
const user: User =
|
||||
typeof userJson === "object" && userJson !== null
|
||||
? User.fromJson(userJson as Record<string, unknown>)
|
||||
: new User({ id: "", username: "" });
|
||||
return new GuestLoginResponse({
|
||||
token: requireString("token"),
|
||||
deviceId: requireString("deviceId"),
|
||||
userId: requireString("userId"),
|
||||
isDeviceUser:
|
||||
typeof json.isDeviceUser === "boolean"
|
||||
? json.isDeviceUser
|
||||
: undefined,
|
||||
expiresIn: typeof json.expiresIn === "number" ? json.expiresIn : undefined,
|
||||
user,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// auth 子目录 barrel export
|
||||
export { AppleLoginRequest } from "./apple_login_request";
|
||||
export { FbIdLoginRequest } from "./fb_id_login_request";
|
||||
export { FacebookLoginRequest } from "./facebook_login_request";
|
||||
export { GoogleLoginRequest } from "./google_login_request";
|
||||
export { GuestLoginRequest } from "./guest_login_request";
|
||||
export { GuestLoginResponse } from "./guest_login_response";
|
||||
export { LoginRequest } from "./login_request";
|
||||
export { LoginResponse } from "./login_response";
|
||||
export { LogoutResponse } from "./logout_response";
|
||||
export { RefreshTokenRequest } from "./refresh_token_request";
|
||||
export { RefreshTokenResponse } from "./refresh_token_response";
|
||||
export { RegisterRequest } from "./register_request";
|
||||
export { SendCodeRequest } from "./send_code_request";
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* 登录请求 - 支持用户名或邮箱登录
|
||||
* 原始 Dart: LoginRequest (lib/data/models/auth/auth_request.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `email`/`username`/`guestId` 为 `String?`,按"全部非空"约定统一兜底为空串。
|
||||
* 后端校验 email 与 username 至少传入一个。
|
||||
*/
|
||||
export class LoginRequest {
|
||||
readonly email: string;
|
||||
readonly username: string;
|
||||
readonly password: string;
|
||||
readonly platform: string;
|
||||
readonly guestId: string;
|
||||
|
||||
constructor(params: {
|
||||
email?: string;
|
||||
username?: string;
|
||||
password: string;
|
||||
platform: string;
|
||||
guestId?: string;
|
||||
}) {
|
||||
this.email = params.email ?? "";
|
||||
this.username = params.username ?? "";
|
||||
this.password = params.password;
|
||||
this.platform = params.platform;
|
||||
this.guestId = params.guestId ?? "";
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
email: this.email,
|
||||
username: this.username,
|
||||
password: this.password,
|
||||
platform: this.platform,
|
||||
guestId: this.guestId,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): LoginRequest {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`LoginRequest.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new LoginRequest({
|
||||
email: typeof json.email === "string" ? json.email : undefined,
|
||||
username: typeof json.username === "string" ? json.username : undefined,
|
||||
password: requireString("password"),
|
||||
platform: requireString("platform"),
|
||||
guestId: typeof json.guestId === "string" ? json.guestId : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* 登录响应
|
||||
* 原始 Dart: LoginResponse (lib/data/models/auth/auth_response.dart)
|
||||
*/
|
||||
import { User } from "../user/user";
|
||||
|
||||
export class LoginResponse {
|
||||
readonly user: User;
|
||||
readonly token: string;
|
||||
readonly refreshToken: string;
|
||||
|
||||
constructor(params: { user: User; token: string; refreshToken?: string }) {
|
||||
this.user = params.user;
|
||||
this.token = params.token;
|
||||
this.refreshToken = params.refreshToken ?? "";
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
user: this.user.toJson(),
|
||||
token: this.token,
|
||||
refreshToken: this.refreshToken,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): LoginResponse {
|
||||
const token = json.token;
|
||||
if (typeof token !== "string") {
|
||||
throw new Error("LoginResponse.token is required and must be a string");
|
||||
}
|
||||
const userJson = json.user;
|
||||
if (typeof userJson !== "object" || userJson === null) {
|
||||
throw new Error("LoginResponse.user is required and must be an object");
|
||||
}
|
||||
return new LoginResponse({
|
||||
user: User.fromJson(userJson as Record<string, unknown>),
|
||||
token,
|
||||
refreshToken:
|
||||
typeof json.refreshToken === "string" ? json.refreshToken : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* 退出登录响应
|
||||
* 原始 Dart: LogoutResponse (lib/data/models/auth/auth_response.dart)
|
||||
*/
|
||||
export class LogoutResponse {
|
||||
readonly success: boolean;
|
||||
|
||||
constructor(params: { success?: boolean }) {
|
||||
this.success = params.success ?? true;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return { success: this.success };
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): LogoutResponse {
|
||||
return new LogoutResponse({
|
||||
success: typeof json.success === "boolean" ? json.success : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 刷新 Token 请求
|
||||
* 原始 Dart: RefreshTokenRequest (lib/data/models/auth/auth_request.dart)
|
||||
*/
|
||||
export class RefreshTokenRequest {
|
||||
readonly refreshToken: string;
|
||||
|
||||
constructor(params: { refreshToken: string }) {
|
||||
this.refreshToken = params.refreshToken;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return { refreshToken: this.refreshToken };
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): RefreshTokenRequest {
|
||||
const refreshToken = json.refreshToken;
|
||||
if (typeof refreshToken !== "string") {
|
||||
throw new Error(
|
||||
"RefreshTokenRequest.refreshToken is required and must be a string"
|
||||
);
|
||||
}
|
||||
return new RefreshTokenRequest({ refreshToken });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* 刷新 Token 响应
|
||||
* 原始 Dart: RefreshTokenResponse (lib/data/models/auth/auth_response.dart)
|
||||
*/
|
||||
export class RefreshTokenResponse {
|
||||
readonly token: string;
|
||||
readonly refreshToken: string;
|
||||
readonly userId: string;
|
||||
|
||||
constructor(params: {
|
||||
token: string;
|
||||
refreshToken: string;
|
||||
userId: string;
|
||||
}) {
|
||||
this.token = params.token;
|
||||
this.refreshToken = params.refreshToken;
|
||||
this.userId = params.userId;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
token: this.token,
|
||||
refreshToken: this.refreshToken,
|
||||
userId: this.userId,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): RefreshTokenResponse {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`RefreshTokenResponse.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new RefreshTokenResponse({
|
||||
token: requireString("token"),
|
||||
refreshToken: requireString("refreshToken"),
|
||||
userId: requireString("userId"),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 注册请求
|
||||
* 原始 Dart: RegisterRequest (lib/data/models/auth/auth_request.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `guestId` 为 `String?`,按"全部非空"约定统一兜底为空串。
|
||||
*/
|
||||
export class RegisterRequest {
|
||||
readonly username: string;
|
||||
readonly email: string;
|
||||
readonly password: string;
|
||||
readonly platform: string;
|
||||
readonly guestId: string;
|
||||
|
||||
constructor(params: {
|
||||
username: string;
|
||||
email: string;
|
||||
password: string;
|
||||
platform: string;
|
||||
guestId?: string;
|
||||
}) {
|
||||
this.username = params.username;
|
||||
this.email = params.email;
|
||||
this.password = params.password;
|
||||
this.platform = params.platform;
|
||||
this.guestId = params.guestId ?? "";
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
username: this.username,
|
||||
email: this.email,
|
||||
password: this.password,
|
||||
platform: this.platform,
|
||||
guestId: this.guestId,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): RegisterRequest {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`RegisterRequest.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new RegisterRequest({
|
||||
username: requireString("username"),
|
||||
email: requireString("email"),
|
||||
password: requireString("password"),
|
||||
platform: requireString("platform"),
|
||||
guestId: typeof json.guestId === "string" ? json.guestId : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 发送验证码请求
|
||||
* 原始 Dart: SendCodeRequest (lib/data/models/auth/auth_request.dart)
|
||||
*/
|
||||
export class SendCodeRequest {
|
||||
readonly email: string;
|
||||
|
||||
constructor(params: { email: string }) {
|
||||
this.email = params.email;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return { email: this.email };
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): SendCodeRequest {
|
||||
const email = json.email;
|
||||
if (typeof email !== "string") {
|
||||
throw new Error(
|
||||
"SendCodeRequest.email is required and must be a string"
|
||||
);
|
||||
}
|
||||
return new SendCodeRequest({ email });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* 聊天历史响应
|
||||
* 原始 Dart: ChatHistoryResponse (lib/data/models/chat/chat_response.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `total` 为 `int?`,按"全部非空"约定兜底为 0。
|
||||
*/
|
||||
import { ChatMessage } from "./chat_message";
|
||||
|
||||
export class ChatHistoryResponse {
|
||||
readonly messages: ChatMessage[];
|
||||
readonly total: number;
|
||||
readonly limit: number;
|
||||
readonly offset: number;
|
||||
|
||||
constructor(params: {
|
||||
messages: ChatMessage[];
|
||||
total?: number;
|
||||
limit: number;
|
||||
offset: number;
|
||||
}) {
|
||||
this.messages = params.messages;
|
||||
this.total = params.total ?? 0;
|
||||
this.limit = params.limit;
|
||||
this.offset = params.offset;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
messages: this.messages.map((m) => m.toJson()),
|
||||
total: this.total,
|
||||
limit: this.limit,
|
||||
offset: this.offset,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): ChatHistoryResponse {
|
||||
const requireNumber = (key: string): number => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "number") {
|
||||
throw new Error(
|
||||
`ChatHistoryResponse.${key} is required and must be a number`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
const rawMessages = json.messages;
|
||||
const messages: ChatMessage[] = Array.isArray(rawMessages)
|
||||
? (rawMessages as Record<string, unknown>[]).map((m) =>
|
||||
ChatMessage.fromJson(m)
|
||||
)
|
||||
: [];
|
||||
return new ChatHistoryResponse({
|
||||
messages,
|
||||
total: typeof json.total === "number" ? json.total : undefined,
|
||||
limit: requireNumber("limit"),
|
||||
offset: requireNumber("offset"),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* 聊天历史中的单条消息
|
||||
* 原始 Dart: ChatMessage (lib/data/models/chat/chat_response.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `id`/`createdAt` 为 `String?`,按"全部非空"约定兜底为空串。
|
||||
*/
|
||||
export class ChatMessage {
|
||||
readonly role: string;
|
||||
readonly content: string;
|
||||
readonly id: string;
|
||||
readonly createdAt: string;
|
||||
|
||||
constructor(params: {
|
||||
role: string;
|
||||
content: string;
|
||||
id?: string;
|
||||
createdAt?: string;
|
||||
}) {
|
||||
this.role = params.role;
|
||||
this.content = params.content;
|
||||
this.id = params.id ?? "";
|
||||
this.createdAt = params.createdAt ?? "";
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
role: this.role,
|
||||
content: this.content,
|
||||
id: this.id,
|
||||
createdAt: this.createdAt,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): ChatMessage {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`ChatMessage.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new ChatMessage({
|
||||
role: requireString("role"),
|
||||
content: requireString("content"),
|
||||
id: typeof json.id === "string" ? json.id : undefined,
|
||||
createdAt:
|
||||
typeof json.createdAt === "string" ? json.createdAt : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* 发送消息响应
|
||||
* 原始 Dart: ChatSendResponse (lib/data/models/chat/chat_response.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `mode`/`currentMood`/`isGuest` 为可空字段,按"全部非空"约定兜底:
|
||||
* - 字符串 → ""
|
||||
* - bool → false
|
||||
* - int → 0
|
||||
*/
|
||||
export class ChatSendResponse {
|
||||
readonly mode: string;
|
||||
readonly reply: string;
|
||||
readonly voiceUrl: string;
|
||||
readonly audioUrl: string;
|
||||
readonly intimacyChange: number;
|
||||
readonly newIntimacy: number;
|
||||
readonly relationshipStage: string;
|
||||
readonly currentMood: string;
|
||||
readonly messageId: string;
|
||||
readonly isGuest: boolean;
|
||||
readonly timestamp: number;
|
||||
|
||||
constructor(params: {
|
||||
mode?: string;
|
||||
reply: string;
|
||||
voiceUrl?: string;
|
||||
audioUrl?: string;
|
||||
intimacyChange?: number;
|
||||
newIntimacy?: number;
|
||||
relationshipStage: string;
|
||||
currentMood?: string;
|
||||
messageId: string;
|
||||
isGuest?: boolean;
|
||||
timestamp?: number;
|
||||
}) {
|
||||
this.mode = params.mode ?? "";
|
||||
this.reply = params.reply;
|
||||
this.voiceUrl = params.voiceUrl ?? "";
|
||||
this.audioUrl = params.audioUrl ?? "";
|
||||
this.intimacyChange = params.intimacyChange ?? 0;
|
||||
this.newIntimacy = params.newIntimacy ?? 0;
|
||||
this.relationshipStage = params.relationshipStage;
|
||||
this.currentMood = params.currentMood ?? "";
|
||||
this.messageId = params.messageId;
|
||||
this.isGuest = params.isGuest ?? false;
|
||||
this.timestamp = params.timestamp ?? 0;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
mode: this.mode,
|
||||
reply: this.reply,
|
||||
voiceUrl: this.voiceUrl,
|
||||
audioUrl: this.audioUrl,
|
||||
intimacyChange: this.intimacyChange,
|
||||
newIntimacy: this.newIntimacy,
|
||||
relationshipStage: this.relationshipStage,
|
||||
currentMood: this.currentMood,
|
||||
messageId: this.messageId,
|
||||
isGuest: this.isGuest,
|
||||
timestamp: this.timestamp,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): ChatSendResponse {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`ChatSendResponse.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new ChatSendResponse({
|
||||
mode: typeof json.mode === "string" ? json.mode : undefined,
|
||||
reply: requireString("reply"),
|
||||
voiceUrl:
|
||||
typeof json.voiceUrl === "string" ? json.voiceUrl : undefined,
|
||||
audioUrl:
|
||||
typeof json.audioUrl === "string" ? json.audioUrl : undefined,
|
||||
intimacyChange:
|
||||
typeof json.intimacyChange === "number"
|
||||
? json.intimacyChange
|
||||
: undefined,
|
||||
newIntimacy:
|
||||
typeof json.newIntimacy === "number" ? json.newIntimacy : undefined,
|
||||
relationshipStage: requireString("relationshipStage"),
|
||||
currentMood:
|
||||
typeof json.currentMood === "string" ? json.currentMood : undefined,
|
||||
messageId: requireString("messageId"),
|
||||
isGuest: typeof json.isGuest === "boolean" ? json.isGuest : undefined,
|
||||
timestamp:
|
||||
typeof json.timestamp === "number" ? json.timestamp : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* 消息同步响应
|
||||
* 原始 Dart: ChatSyncData (lib/data/models/chat/chat_sync.dart)
|
||||
*/
|
||||
export class ChatSyncData {
|
||||
readonly syncedCount: number;
|
||||
readonly totalHistory: number;
|
||||
|
||||
constructor(params: { syncedCount: number; totalHistory: number }) {
|
||||
this.syncedCount = params.syncedCount;
|
||||
this.totalHistory = params.totalHistory;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
syncedCount: this.syncedCount,
|
||||
totalHistory: this.totalHistory,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): ChatSyncData {
|
||||
const requireNumber = (key: string): number => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "number") {
|
||||
throw new Error(
|
||||
`ChatSyncData.${key} is required and must be a number`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new ChatSyncData({
|
||||
syncedCount: requireNumber("syncedCount"),
|
||||
totalHistory: requireNumber("totalHistory"),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* 消息同步请求
|
||||
* 原始 Dart: ChatSyncRequest (lib/data/models/chat/chat_sync.dart)
|
||||
*/
|
||||
import { SyncMessage } from "./sync_message";
|
||||
|
||||
export class ChatSyncRequest {
|
||||
readonly messages: SyncMessage[];
|
||||
|
||||
constructor(params: { messages: SyncMessage[] }) {
|
||||
this.messages = params.messages;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return { messages: this.messages.map((m) => m.toJson()) };
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): ChatSyncRequest {
|
||||
const rawMessages = json.messages;
|
||||
const messages: SyncMessage[] = Array.isArray(rawMessages)
|
||||
? (rawMessages as Record<string, unknown>[]).map((m) =>
|
||||
SyncMessage.fromJson(m)
|
||||
)
|
||||
: [];
|
||||
return new ChatSyncRequest({ messages });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* 游客每日聊天配额数据
|
||||
* 原始 Dart: GuestChatQuota (lib/data/models/chat/guest_chat_quota.dart)
|
||||
*
|
||||
* 注:原始 Dart 中的静态常量与运行时环境判断方法(isDevelopment)已迁移为
|
||||
* 静态成员。环境检测逻辑(threshold / totalQuotaDefault 等)保留为方法,
|
||||
* 内部使用 `process.env.NODE_ENV` 替代 Dart 中的 `AppEnvUtil.isDevelopment`。
|
||||
* `initial()` 工厂方法已迁移为静态方法;`needReset` getter 保留为实例方法。
|
||||
*
|
||||
* Dart 中 `initial()` 依赖 `app_date.DateUtils.todayString()`,
|
||||
* 在 TS 中由调用方通过 `date` 字段传入。
|
||||
*/
|
||||
export class GuestChatQuota {
|
||||
readonly remaining: number;
|
||||
readonly date: string;
|
||||
|
||||
// 静态常量
|
||||
static readonly maxQuotaPerDay = 40;
|
||||
static readonly maxQuotaPerDayTest = 4;
|
||||
static readonly quotaWarningThreshold = 20;
|
||||
static readonly quotaWarningThresholdTest = 2;
|
||||
static readonly defaultTotalQuota = 50;
|
||||
static readonly defaultTotalQuotaDev = 5;
|
||||
static readonly quotaExhausted = 0;
|
||||
|
||||
constructor(params: { remaining: number; date: string }) {
|
||||
this.remaining = params.remaining;
|
||||
this.date = params.date;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 配额耗尽状态值(便捷引用)
|
||||
*/
|
||||
static get exhausted(): number {
|
||||
return GuestChatQuota.quotaExhausted;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否处于开发环境
|
||||
* 通过 `process.env.NODE_ENV` 判断,替代 Dart 中的 `AppEnvUtil.isDevelopment`
|
||||
*/
|
||||
static get isDevelopment(): boolean {
|
||||
return process.env.NODE_ENV !== "production";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前环境的配额警告阈值
|
||||
*/
|
||||
static get warningThreshold(): number {
|
||||
return GuestChatQuota.isDevelopment
|
||||
? GuestChatQuota.quotaWarningThresholdTest
|
||||
: GuestChatQuota.quotaWarningThreshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前环境的每日最大配额
|
||||
*/
|
||||
static get threshold(): number {
|
||||
return GuestChatQuota.isDevelopment
|
||||
? GuestChatQuota.maxQuotaPerDayTest
|
||||
: GuestChatQuota.maxQuotaPerDay;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前环境的总配额默认值
|
||||
*/
|
||||
static get totalQuotaDefault(): number {
|
||||
return GuestChatQuota.isDevelopment
|
||||
? GuestChatQuota.defaultTotalQuotaDev
|
||||
: GuestChatQuota.defaultTotalQuota;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建初始配额实例
|
||||
* @param todayString 当天日期字符串(YYYY-MM-DD),由调用方提供
|
||||
*/
|
||||
static initial(todayString: string): GuestChatQuota {
|
||||
return new GuestChatQuota({
|
||||
remaining: GuestChatQuota.threshold,
|
||||
date: todayString,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否需要重置(跨天)
|
||||
* @param todayString 当天日期字符串(YYYY-MM-DD),由调用方提供
|
||||
*/
|
||||
needsReset(todayString: string): boolean {
|
||||
return this.date !== todayString;
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
remaining: this.remaining,
|
||||
date: this.date,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): GuestChatQuota {
|
||||
const remaining = json.remaining;
|
||||
const date = json.date;
|
||||
if (typeof remaining !== "number") {
|
||||
throw new Error(
|
||||
"GuestChatQuota.remaining is required and must be a number"
|
||||
);
|
||||
}
|
||||
if (typeof date !== "string") {
|
||||
throw new Error("GuestChatQuota.date is required and must be a string");
|
||||
}
|
||||
return new GuestChatQuota({ remaining, date });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* 图片上传响应
|
||||
* 原始 Dart: ImageUploadResponse (lib/data/models/chat/image_upload_response.dart)
|
||||
*/
|
||||
export class ImageUploadResponse {
|
||||
readonly success: boolean;
|
||||
readonly imageId: string;
|
||||
readonly thumbUrl: string;
|
||||
readonly mediumUrl: string;
|
||||
readonly originalUrl: string;
|
||||
readonly width: number;
|
||||
readonly height: number;
|
||||
readonly bytes: number;
|
||||
|
||||
constructor(params: {
|
||||
success?: boolean;
|
||||
imageId: string;
|
||||
thumbUrl: string;
|
||||
mediumUrl: string;
|
||||
originalUrl: string;
|
||||
width: number;
|
||||
height: number;
|
||||
bytes: number;
|
||||
}) {
|
||||
this.success = params.success ?? true;
|
||||
this.imageId = params.imageId;
|
||||
this.thumbUrl = params.thumbUrl;
|
||||
this.mediumUrl = params.mediumUrl;
|
||||
this.originalUrl = params.originalUrl;
|
||||
this.width = params.width;
|
||||
this.height = params.height;
|
||||
this.bytes = params.bytes;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
success: this.success,
|
||||
imageId: this.imageId,
|
||||
thumbUrl: this.thumbUrl,
|
||||
mediumUrl: this.mediumUrl,
|
||||
originalUrl: this.originalUrl,
|
||||
width: this.width,
|
||||
height: this.height,
|
||||
bytes: this.bytes,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): ImageUploadResponse {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`ImageUploadResponse.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
const requireNumber = (key: string): number => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "number") {
|
||||
throw new Error(
|
||||
`ImageUploadResponse.${key} is required and must be a number`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new ImageUploadResponse({
|
||||
success: typeof json.success === "boolean" ? json.success : undefined,
|
||||
imageId: requireString("imageId"),
|
||||
thumbUrl: requireString("thumbUrl"),
|
||||
mediumUrl: requireString("mediumUrl"),
|
||||
originalUrl: requireString("originalUrl"),
|
||||
width: requireNumber("width"),
|
||||
height: requireNumber("height"),
|
||||
bytes: requireNumber("bytes"),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// chat 子目录 barrel export
|
||||
export { ChatHistoryResponse } from "./chat_history_response";
|
||||
export { ChatMessage } from "./chat_message";
|
||||
export { ChatSendResponse } from "./chat_send_response";
|
||||
export { ChatSyncData } from "./chat_sync_data";
|
||||
export { ChatSyncRequest } from "./chat_sync_request";
|
||||
export { GuestChatQuota } from "./guest_chat_quota";
|
||||
export { ImageUploadResponse } from "./image_upload_response";
|
||||
export { SendMessageRequest } from "./send_message_request";
|
||||
export { SttData } from "./stt_data";
|
||||
export { SyncMessage } from "./sync_message";
|
||||
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* 发送消息请求 - 用于 /api/chat/send 接口
|
||||
* 原始 Dart: SendMessageRequest (lib/data/models/chat/send_message_request.dart)
|
||||
*
|
||||
* 注:原始 Dart 中所有图片相关字段为可空,按"全部非空"约定兜底:
|
||||
* - 字符串 → ""
|
||||
* - 数字 → 0
|
||||
*/
|
||||
export class SendMessageRequest {
|
||||
readonly message: string;
|
||||
readonly image: string;
|
||||
readonly imageId: string;
|
||||
readonly imageThumbUrl: string;
|
||||
readonly imageMediumUrl: string;
|
||||
readonly imageOriginalUrl: string;
|
||||
readonly imageWidth: number;
|
||||
readonly imageHeight: number;
|
||||
readonly useWebSocket: boolean;
|
||||
|
||||
constructor(params: {
|
||||
message?: string;
|
||||
image?: string;
|
||||
imageId?: string;
|
||||
imageThumbUrl?: string;
|
||||
imageMediumUrl?: string;
|
||||
imageOriginalUrl?: string;
|
||||
imageWidth?: number;
|
||||
imageHeight?: number;
|
||||
useWebSocket?: boolean;
|
||||
}) {
|
||||
this.message = params.message ?? "";
|
||||
this.image = params.image ?? "";
|
||||
this.imageId = params.imageId ?? "";
|
||||
this.imageThumbUrl = params.imageThumbUrl ?? "";
|
||||
this.imageMediumUrl = params.imageMediumUrl ?? "";
|
||||
this.imageOriginalUrl = params.imageOriginalUrl ?? "";
|
||||
this.imageWidth = params.imageWidth ?? 0;
|
||||
this.imageHeight = params.imageHeight ?? 0;
|
||||
this.useWebSocket = params.useWebSocket ?? false;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
message: this.message,
|
||||
image: this.image,
|
||||
imageId: this.imageId,
|
||||
imageThumbUrl: this.imageThumbUrl,
|
||||
imageMediumUrl: this.imageMediumUrl,
|
||||
imageOriginalUrl: this.imageOriginalUrl,
|
||||
imageWidth: this.imageWidth,
|
||||
imageHeight: this.imageHeight,
|
||||
useWebSocket: this.useWebSocket,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): SendMessageRequest {
|
||||
return new SendMessageRequest({
|
||||
message: typeof json.message === "string" ? json.message : undefined,
|
||||
image: typeof json.image === "string" ? json.image : undefined,
|
||||
imageId: typeof json.imageId === "string" ? json.imageId : undefined,
|
||||
imageThumbUrl:
|
||||
typeof json.imageThumbUrl === "string"
|
||||
? json.imageThumbUrl
|
||||
: undefined,
|
||||
imageMediumUrl:
|
||||
typeof json.imageMediumUrl === "string"
|
||||
? json.imageMediumUrl
|
||||
: undefined,
|
||||
imageOriginalUrl:
|
||||
typeof json.imageOriginalUrl === "string"
|
||||
? json.imageOriginalUrl
|
||||
: undefined,
|
||||
imageWidth:
|
||||
typeof json.imageWidth === "number" ? json.imageWidth : undefined,
|
||||
imageHeight:
|
||||
typeof json.imageHeight === "number" ? json.imageHeight : undefined,
|
||||
useWebSocket:
|
||||
typeof json.useWebSocket === "boolean" ? json.useWebSocket : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* STT(语音转文字)响应
|
||||
* 原始 Dart: SttData (lib/data/models/chat/stt_response.dart)
|
||||
*/
|
||||
export class SttData {
|
||||
readonly text: string;
|
||||
|
||||
constructor(params: { text: string }) {
|
||||
this.text = params.text;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return { text: this.text };
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): SttData {
|
||||
const text = json.text;
|
||||
if (typeof text !== "string") {
|
||||
throw new Error("SttData.text is required and must be a string");
|
||||
}
|
||||
return new SttData({ text });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* 待同步的单条消息
|
||||
* 原始 Dart: SyncMessage (lib/data/models/chat/chat_sync.dart)
|
||||
*/
|
||||
export class SyncMessage {
|
||||
readonly role: string;
|
||||
readonly content: string;
|
||||
readonly timestamp: string;
|
||||
|
||||
constructor(params: { role: string; content: string; timestamp: string }) {
|
||||
this.role = params.role;
|
||||
this.content = params.content;
|
||||
this.timestamp = params.timestamp;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
role: this.role,
|
||||
content: this.content,
|
||||
timestamp: this.timestamp,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): SyncMessage {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`SyncMessage.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new SyncMessage({
|
||||
role: requireString("role"),
|
||||
content: requireString("content"),
|
||||
timestamp: requireString("timestamp"),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// models 顶层 barrel export - 集中导出所有分类
|
||||
export * from "./auth";
|
||||
export * from "./chat";
|
||||
export * from "./metrics";
|
||||
export * from "./user";
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* 应用事件上报请求 - 用于 /api/data/report-user-info 接口
|
||||
* 原始 Dart: AppEvent (lib/data/models/metrics/app_event.dart)
|
||||
*/
|
||||
export class AppEvent {
|
||||
readonly userId: string;
|
||||
readonly browser: string;
|
||||
readonly userAgent: string;
|
||||
|
||||
constructor(params: { userId: string; browser: string; userAgent: string }) {
|
||||
this.userId = params.userId;
|
||||
this.browser = params.browser;
|
||||
this.userAgent = params.userAgent;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
userId: this.userId,
|
||||
browser: this.browser,
|
||||
userAgent: this.userAgent,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): AppEvent {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`AppEvent.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new AppEvent({
|
||||
userId: requireString("userId"),
|
||||
browser: requireString("browser"),
|
||||
userAgent: requireString("userAgent"),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
// metrics 子目录 barrel export
|
||||
export { AppEvent } from "./app_event";
|
||||
export { PwaEvent } from "./pwa_event";
|
||||
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* PWA 事件上报请求 - 用于 /api/metrics/pwa/event 接口
|
||||
* 原始 Dart: PwaEvent (lib/data/models/metrics/pwa_event.dart)
|
||||
*/
|
||||
export class PwaEvent {
|
||||
readonly deviceId: string;
|
||||
readonly deviceType: string;
|
||||
readonly timestamp: number;
|
||||
readonly pwaInstalled: boolean;
|
||||
readonly pwaSupported: boolean;
|
||||
|
||||
constructor(params: {
|
||||
deviceId: string;
|
||||
deviceType: string;
|
||||
timestamp: number;
|
||||
pwaInstalled?: boolean;
|
||||
pwaSupported?: boolean;
|
||||
}) {
|
||||
this.deviceId = params.deviceId;
|
||||
this.deviceType = params.deviceType;
|
||||
this.timestamp = params.timestamp;
|
||||
this.pwaInstalled = params.pwaInstalled ?? false;
|
||||
this.pwaSupported = params.pwaSupported ?? false;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
deviceId: this.deviceId,
|
||||
deviceType: this.deviceType,
|
||||
timestamp: this.timestamp,
|
||||
pwaInstalled: this.pwaInstalled,
|
||||
pwaSupported: this.pwaSupported,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): PwaEvent {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`PwaEvent.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
const requireNumber = (key: string): number => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "number") {
|
||||
throw new Error(`PwaEvent.${key} is required and must be a number`);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new PwaEvent({
|
||||
deviceId: requireString("deviceId"),
|
||||
deviceType: requireString("deviceType"),
|
||||
timestamp: requireNumber("timestamp"),
|
||||
pwaInstalled:
|
||||
typeof json.pwaInstalled === "boolean"
|
||||
? json.pwaInstalled
|
||||
: undefined,
|
||||
pwaSupported:
|
||||
typeof json.pwaSupported === "boolean"
|
||||
? json.pwaSupported
|
||||
: undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* 头像数据模型 - 对应后端 AvatarData schema
|
||||
* 原始 Dart: AvatarData (lib/data/models/user/user.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `avatarUrl` 为 `String?`,按"全部非空"约定兜底为空串。
|
||||
*/
|
||||
export class AvatarData {
|
||||
readonly avatarUrl: string;
|
||||
readonly userId: string;
|
||||
|
||||
constructor(params: { avatarUrl?: string; userId: string }) {
|
||||
this.avatarUrl = params.avatarUrl ?? "";
|
||||
this.userId = params.userId;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
avatarUrl: this.avatarUrl,
|
||||
userId: this.userId,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): AvatarData {
|
||||
const userId = json.userId;
|
||||
if (typeof userId !== "string") {
|
||||
throw new Error("AvatarData.userId is required and must be a string");
|
||||
}
|
||||
return new AvatarData({
|
||||
userId,
|
||||
avatarUrl:
|
||||
typeof json.avatarUrl === "string" ? json.avatarUrl : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* 积分数据模型 - 对应后端 CreditsData schema
|
||||
* 原始 Dart: CreditsData (lib/data/models/user/user.dart)
|
||||
*/
|
||||
export class CreditsData {
|
||||
readonly userId: string;
|
||||
readonly dolBalance: number;
|
||||
|
||||
constructor(params: { userId: string; dolBalance: number }) {
|
||||
this.userId = params.userId;
|
||||
this.dolBalance = params.dolBalance;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
userId: this.userId,
|
||||
dolBalance: this.dolBalance,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): CreditsData {
|
||||
const userId = json.userId;
|
||||
const dolBalance = json.dolBalance;
|
||||
if (typeof userId !== "string") {
|
||||
throw new Error("CreditsData.userId is required and must be a string");
|
||||
}
|
||||
if (typeof dolBalance !== "number") {
|
||||
throw new Error(
|
||||
"CreditsData.dolBalance is required and must be a number"
|
||||
);
|
||||
}
|
||||
return new CreditsData({ userId, dolBalance });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 积分历史记录模型 - 对应后端 CreditsHistoryData schema
|
||||
* 原始 Dart: CreditsHistoryData (lib/data/models/user/user.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `records` 为 `List<Map<String, dynamic>>`,
|
||||
* 迁移为 `Record<string, unknown>[]`。
|
||||
*/
|
||||
export class CreditsHistoryData {
|
||||
readonly records: Record<string, unknown>[];
|
||||
readonly total: number;
|
||||
readonly limit: number;
|
||||
readonly offset: number;
|
||||
|
||||
constructor(params: {
|
||||
records: Record<string, unknown>[];
|
||||
total: number;
|
||||
limit: number;
|
||||
offset: number;
|
||||
}) {
|
||||
this.records = params.records;
|
||||
this.total = params.total;
|
||||
this.limit = params.limit;
|
||||
this.offset = params.offset;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
records: this.records,
|
||||
total: this.total,
|
||||
limit: this.limit,
|
||||
offset: this.offset,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): CreditsHistoryData {
|
||||
const requireNumber = (key: string): number => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "number") {
|
||||
throw new Error(
|
||||
`CreditsHistoryData.${key} is required and must be a number`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
const rawRecords = json.records;
|
||||
const records: Record<string, unknown>[] = Array.isArray(rawRecords)
|
||||
? (rawRecords as Record<string, unknown>[])
|
||||
: [];
|
||||
return new CreditsHistoryData({
|
||||
records,
|
||||
total: requireNumber("total"),
|
||||
limit: requireNumber("limit"),
|
||||
offset: requireNumber("offset"),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// user 子目录 barrel export
|
||||
export { AvatarData } from "./avatar_data";
|
||||
export { CreditsData } from "./credits_data";
|
||||
export { CreditsHistoryData } from "./credits_history_data";
|
||||
export { PersonalityTraits } from "./personality_traits";
|
||||
export { RecentMemory } from "./recent_memory";
|
||||
export { UpdateProfileRequest } from "./update_profile_request";
|
||||
export { User } from "./user";
|
||||
export { UserStatsResponse } from "./user_stats_response";
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* 个性特征模型
|
||||
* 原始 Dart: PersonalityTraits (lib/data/models/user/user.dart)
|
||||
*
|
||||
* 注:所有 double 字段在 Dart 中使用 @Default(0.5)。
|
||||
*/
|
||||
export class PersonalityTraits {
|
||||
readonly cheerful: number;
|
||||
readonly caring: number;
|
||||
readonly playful: number;
|
||||
readonly serious: number;
|
||||
readonly romantic: number;
|
||||
|
||||
constructor(params: {
|
||||
cheerful?: number;
|
||||
caring?: number;
|
||||
playful?: number;
|
||||
serious?: number;
|
||||
romantic?: number;
|
||||
}) {
|
||||
this.cheerful = params.cheerful ?? 0.5;
|
||||
this.caring = params.caring ?? 0.5;
|
||||
this.playful = params.playful ?? 0.5;
|
||||
this.serious = params.serious ?? 0.5;
|
||||
this.romantic = params.romantic ?? 0.5;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
cheerful: this.cheerful,
|
||||
caring: this.caring,
|
||||
playful: this.playful,
|
||||
serious: this.serious,
|
||||
romantic: this.romantic,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): PersonalityTraits {
|
||||
return new PersonalityTraits({
|
||||
cheerful: typeof json.cheerful === "number" ? json.cheerful : undefined,
|
||||
caring: typeof json.caring === "number" ? json.caring : undefined,
|
||||
playful: typeof json.playful === "number" ? json.playful : undefined,
|
||||
serious: typeof json.serious === "number" ? json.serious : undefined,
|
||||
romantic: typeof json.romantic === "number" ? json.romantic : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* 最近记忆模型
|
||||
* 原始 Dart: RecentMemory (lib/data/models/user/recent_memory.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `createdAt` 为 `String?`,按"全部非空"约定兜底为空串。
|
||||
*/
|
||||
export class RecentMemory {
|
||||
readonly type: string;
|
||||
readonly content: string;
|
||||
readonly importance: number;
|
||||
readonly createdAt: string;
|
||||
|
||||
constructor(params: {
|
||||
type: string;
|
||||
content: string;
|
||||
importance: number;
|
||||
createdAt?: string;
|
||||
}) {
|
||||
this.type = params.type;
|
||||
this.content = params.content;
|
||||
this.importance = params.importance;
|
||||
this.createdAt = params.createdAt ?? "";
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
type: this.type,
|
||||
content: this.content,
|
||||
importance: this.importance,
|
||||
createdAt: this.createdAt,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): RecentMemory {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`RecentMemory.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
const importance = json.importance;
|
||||
if (typeof importance !== "number") {
|
||||
throw new Error(
|
||||
"RecentMemory.importance is required and must be a number"
|
||||
);
|
||||
}
|
||||
return new RecentMemory({
|
||||
type: requireString("type"),
|
||||
content: requireString("content"),
|
||||
importance,
|
||||
createdAt:
|
||||
typeof json.createdAt === "string" ? json.createdAt : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* 更新个人资料请求
|
||||
* 原始 Dart: UpdateProfileRequest (lib/data/models/user/user.dart)
|
||||
*
|
||||
* 注:原始 Dart 中所有字段为 `String?`,按"全部非空"约定兜底为空串。
|
||||
*/
|
||||
export class UpdateProfileRequest {
|
||||
readonly username: string;
|
||||
readonly nickname: string;
|
||||
readonly preferredLanguage: string;
|
||||
readonly currentMood: string;
|
||||
|
||||
constructor(params: {
|
||||
username?: string;
|
||||
nickname?: string;
|
||||
preferredLanguage?: string;
|
||||
currentMood?: string;
|
||||
}) {
|
||||
this.username = params.username ?? "";
|
||||
this.nickname = params.nickname ?? "";
|
||||
this.preferredLanguage = params.preferredLanguage ?? "";
|
||||
this.currentMood = params.currentMood ?? "";
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
username: this.username,
|
||||
nickname: this.nickname,
|
||||
preferredLanguage: this.preferredLanguage,
|
||||
currentMood: this.currentMood,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): UpdateProfileRequest {
|
||||
return new UpdateProfileRequest({
|
||||
username: typeof json.username === "string" ? json.username : undefined,
|
||||
nickname: typeof json.nickname === "string" ? json.nickname : undefined,
|
||||
preferredLanguage:
|
||||
typeof json.preferredLanguage === "string"
|
||||
? json.preferredLanguage
|
||||
: undefined,
|
||||
currentMood:
|
||||
typeof json.currentMood === "string" ? json.currentMood : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
* 用户模型 - 对应后端 UserData schema
|
||||
* 原始 Dart: User (lib/data/models/user/user.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `email`/`personalityTraits`/`preferredLanguage`/`createdAt`/
|
||||
* `lastMessageAt`/`avatarUrl` 为可空字段,按"全部非空"约定统一兜底:
|
||||
* - 字符串字段 → 空串 ""
|
||||
* - PersonalityTraits → 默认实例(全 0.5)
|
||||
*/
|
||||
import { PersonalityTraits } from "./personality_traits";
|
||||
|
||||
export class User {
|
||||
readonly id: string;
|
||||
readonly username: string;
|
||||
readonly email: string;
|
||||
readonly platform: string;
|
||||
readonly intimacy: number;
|
||||
readonly dolBalance: number;
|
||||
readonly relationshipStage: string;
|
||||
readonly currentMood: string;
|
||||
readonly personalityTraits: PersonalityTraits;
|
||||
readonly preferredLanguage: string;
|
||||
readonly createdAt: string;
|
||||
readonly lastMessageAt: string;
|
||||
readonly avatarUrl: string;
|
||||
readonly loginProvider: string;
|
||||
readonly isGuest: boolean;
|
||||
|
||||
constructor(params: {
|
||||
id: string;
|
||||
username: string;
|
||||
email?: string;
|
||||
platform?: string;
|
||||
intimacy?: number;
|
||||
dolBalance?: number;
|
||||
relationshipStage?: string;
|
||||
currentMood?: string;
|
||||
personalityTraits?: PersonalityTraits;
|
||||
preferredLanguage?: string;
|
||||
createdAt?: string;
|
||||
lastMessageAt?: string;
|
||||
avatarUrl?: string;
|
||||
loginProvider?: string;
|
||||
isGuest?: boolean;
|
||||
}) {
|
||||
this.id = params.id;
|
||||
this.username = params.username;
|
||||
this.email = params.email ?? "";
|
||||
this.platform = params.platform ?? "web";
|
||||
this.intimacy = params.intimacy ?? 0;
|
||||
this.dolBalance = params.dolBalance ?? 0;
|
||||
this.relationshipStage = params.relationshipStage ?? "密友";
|
||||
this.currentMood = params.currentMood ?? "happy";
|
||||
this.personalityTraits = params.personalityTraits ?? new PersonalityTraits({});
|
||||
this.preferredLanguage = params.preferredLanguage ?? "";
|
||||
this.createdAt = params.createdAt ?? "";
|
||||
this.lastMessageAt = params.lastMessageAt ?? "";
|
||||
this.avatarUrl = params.avatarUrl ?? "";
|
||||
this.loginProvider = params.loginProvider ?? "email";
|
||||
this.isGuest = params.isGuest ?? false;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
id: this.id,
|
||||
username: this.username,
|
||||
email: this.email,
|
||||
platform: this.platform,
|
||||
intimacy: this.intimacy,
|
||||
dolBalance: this.dolBalance,
|
||||
relationshipStage: this.relationshipStage,
|
||||
currentMood: this.currentMood,
|
||||
personalityTraits: this.personalityTraits.toJson(),
|
||||
preferredLanguage: this.preferredLanguage,
|
||||
createdAt: this.createdAt,
|
||||
lastMessageAt: this.lastMessageAt,
|
||||
avatarUrl: this.avatarUrl,
|
||||
loginProvider: this.loginProvider,
|
||||
isGuest: this.isGuest,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): User {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(`User.${key} is required and must be a string`);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
return new User({
|
||||
id: requireString("id"),
|
||||
username: requireString("username"),
|
||||
email: typeof json.email === "string" ? json.email : undefined,
|
||||
platform: typeof json.platform === "string" ? json.platform : undefined,
|
||||
intimacy: typeof json.intimacy === "number" ? json.intimacy : undefined,
|
||||
dolBalance:
|
||||
typeof json.dolBalance === "number" ? json.dolBalance : undefined,
|
||||
relationshipStage:
|
||||
typeof json.relationshipStage === "string"
|
||||
? json.relationshipStage
|
||||
: undefined,
|
||||
currentMood:
|
||||
typeof json.currentMood === "string" ? json.currentMood : undefined,
|
||||
personalityTraits: json.personalityTraits
|
||||
? PersonalityTraits.fromJson(
|
||||
json.personalityTraits as Record<string, unknown>
|
||||
)
|
||||
: undefined,
|
||||
preferredLanguage:
|
||||
typeof json.preferredLanguage === "string"
|
||||
? json.preferredLanguage
|
||||
: undefined,
|
||||
createdAt:
|
||||
typeof json.createdAt === "string" ? json.createdAt : undefined,
|
||||
lastMessageAt:
|
||||
typeof json.lastMessageAt === "string" ? json.lastMessageAt : undefined,
|
||||
avatarUrl:
|
||||
typeof json.avatarUrl === "string" ? json.avatarUrl : undefined,
|
||||
loginProvider:
|
||||
typeof json.loginProvider === "string"
|
||||
? json.loginProvider
|
||||
: undefined,
|
||||
isGuest: typeof json.isGuest === "boolean" ? json.isGuest : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* 用户统计响应
|
||||
* 原始 Dart: UserStatsResponse (lib/data/models/user/user_stats_response.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `lastMessageAt`/`accountCreatedAt`/`currentMood` 为 `String?`,
|
||||
* `personalityTraits` 为 `PersonalityTraits?`,按"全部非空"约定兜底:
|
||||
* - 字符串 → ""
|
||||
* - PersonalityTraits → 默认实例
|
||||
* - recentMemories 缺失或 null 时使用 []
|
||||
*/
|
||||
import { PersonalityTraits } from "./personality_traits";
|
||||
import { RecentMemory } from "./recent_memory";
|
||||
|
||||
export class UserStatsResponse {
|
||||
readonly userId: string;
|
||||
readonly username: string;
|
||||
readonly platform: string;
|
||||
readonly intimacy: number;
|
||||
readonly relationshipStage: string;
|
||||
readonly dolBalance: number;
|
||||
readonly totalMessages: number;
|
||||
readonly lastMessageAt: string;
|
||||
readonly accountCreatedAt: string;
|
||||
readonly currentMood: string;
|
||||
readonly personalityTraits: PersonalityTraits;
|
||||
readonly recentMemories: RecentMemory[];
|
||||
readonly promptTokensTotal: number;
|
||||
readonly completionTokensTotal: number;
|
||||
readonly cacheHitTokensTotal: number;
|
||||
readonly tokensTotal: number;
|
||||
|
||||
constructor(params: {
|
||||
userId: string;
|
||||
username: string;
|
||||
platform: string;
|
||||
intimacy: number;
|
||||
relationshipStage: string;
|
||||
dolBalance: number;
|
||||
totalMessages: number;
|
||||
lastMessageAt?: string;
|
||||
accountCreatedAt?: string;
|
||||
currentMood?: string;
|
||||
personalityTraits?: PersonalityTraits;
|
||||
recentMemories?: RecentMemory[];
|
||||
promptTokensTotal?: number;
|
||||
completionTokensTotal?: number;
|
||||
cacheHitTokensTotal?: number;
|
||||
tokensTotal?: number;
|
||||
}) {
|
||||
this.userId = params.userId;
|
||||
this.username = params.username;
|
||||
this.platform = params.platform;
|
||||
this.intimacy = params.intimacy;
|
||||
this.relationshipStage = params.relationshipStage;
|
||||
this.dolBalance = params.dolBalance;
|
||||
this.totalMessages = params.totalMessages;
|
||||
this.lastMessageAt = params.lastMessageAt ?? "";
|
||||
this.accountCreatedAt = params.accountCreatedAt ?? "";
|
||||
this.currentMood = params.currentMood ?? "";
|
||||
this.personalityTraits =
|
||||
params.personalityTraits ?? new PersonalityTraits({});
|
||||
this.recentMemories = params.recentMemories ?? [];
|
||||
this.promptTokensTotal = params.promptTokensTotal ?? 0;
|
||||
this.completionTokensTotal = params.completionTokensTotal ?? 0;
|
||||
this.cacheHitTokensTotal = params.cacheHitTokensTotal ?? 0;
|
||||
this.tokensTotal = params.tokensTotal ?? 0;
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
userId: this.userId,
|
||||
username: this.username,
|
||||
platform: this.platform,
|
||||
intimacy: this.intimacy,
|
||||
relationshipStage: this.relationshipStage,
|
||||
dolBalance: this.dolBalance,
|
||||
totalMessages: this.totalMessages,
|
||||
lastMessageAt: this.lastMessageAt,
|
||||
accountCreatedAt: this.accountCreatedAt,
|
||||
currentMood: this.currentMood,
|
||||
personalityTraits: this.personalityTraits.toJson(),
|
||||
recentMemories: this.recentMemories.map((m) => m.toJson()),
|
||||
promptTokensTotal: this.promptTokensTotal,
|
||||
completionTokensTotal: this.completionTokensTotal,
|
||||
cacheHitTokensTotal: this.cacheHitTokensTotal,
|
||||
tokensTotal: this.tokensTotal,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): UserStatsResponse {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`UserStatsResponse.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
const requireNumber = (key: string): number => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "number") {
|
||||
throw new Error(
|
||||
`UserStatsResponse.${key} is required and must be a number`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
const rawMemories = json.recentMemories;
|
||||
const recentMemories: RecentMemory[] = Array.isArray(rawMemories)
|
||||
? (rawMemories as Record<string, unknown>[]).map((m) =>
|
||||
RecentMemory.fromJson(m)
|
||||
)
|
||||
: [];
|
||||
return new UserStatsResponse({
|
||||
userId: requireString("userId"),
|
||||
username: requireString("username"),
|
||||
platform: requireString("platform"),
|
||||
intimacy: requireNumber("intimacy"),
|
||||
relationshipStage: requireString("relationshipStage"),
|
||||
dolBalance: requireNumber("dolBalance"),
|
||||
totalMessages: requireNumber("totalMessages"),
|
||||
lastMessageAt:
|
||||
typeof json.lastMessageAt === "string"
|
||||
? json.lastMessageAt
|
||||
: undefined,
|
||||
accountCreatedAt:
|
||||
typeof json.accountCreatedAt === "string"
|
||||
? json.accountCreatedAt
|
||||
: undefined,
|
||||
currentMood:
|
||||
typeof json.currentMood === "string" ? json.currentMood : undefined,
|
||||
personalityTraits: json.personalityTraits
|
||||
? PersonalityTraits.fromJson(
|
||||
json.personalityTraits as Record<string, unknown>
|
||||
)
|
||||
: undefined,
|
||||
recentMemories,
|
||||
promptTokensTotal:
|
||||
typeof json.promptTokensTotal === "number"
|
||||
? json.promptTokensTotal
|
||||
: undefined,
|
||||
completionTokensTotal:
|
||||
typeof json.completionTokensTotal === "number"
|
||||
? json.completionTokensTotal
|
||||
: undefined,
|
||||
cacheHitTokensTotal:
|
||||
typeof json.cacheHitTokensTotal === "number"
|
||||
? json.cacheHitTokensTotal
|
||||
: undefined,
|
||||
tokensTotal:
|
||||
typeof json.tokensTotal === "number" ? json.tokensTotal : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user