refactor(data): replace schema classes with readonly models
This commit is contained in:
@@ -34,7 +34,7 @@ describe("FeedbackApi", () => {
|
||||
images: [image],
|
||||
});
|
||||
|
||||
expect(response.toJson()).toEqual({ feedbackId: "feedback-123" });
|
||||
expect(response).toEqual({ feedbackId: "feedback-123" });
|
||||
expect(httpClientMock).toHaveBeenCalledWith(
|
||||
"/api/feedback",
|
||||
expect.objectContaining({ method: "POST", body: expect.any(FormData) }),
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import {
|
||||
SendMessageRequest,
|
||||
UnlockHistoryRequest,
|
||||
UnlockPrivateRequest,
|
||||
SendMessageRequestSchema,
|
||||
UnlockHistoryRequestSchema,
|
||||
UnlockPrivateRequestSchema,
|
||||
} from "@/data/schemas/chat";
|
||||
|
||||
const httpClientMock = vi.hoisted(() => vi.fn());
|
||||
@@ -34,7 +34,7 @@ describe("multi-character API contract", () => {
|
||||
});
|
||||
|
||||
await new ChatApi().sendMessage(
|
||||
SendMessageRequest.from({
|
||||
SendMessageRequestSchema.parse({
|
||||
characterId: CHARACTER_ID,
|
||||
message: "Hello",
|
||||
}),
|
||||
@@ -76,13 +76,13 @@ describe("multi-character API contract", () => {
|
||||
});
|
||||
|
||||
await api.unlockPrivateMessage(
|
||||
UnlockPrivateRequest.from({
|
||||
UnlockPrivateRequestSchema.parse({
|
||||
characterId: CHARACTER_ID,
|
||||
messageId: "message-1",
|
||||
}),
|
||||
);
|
||||
await api.unlockHistory(
|
||||
UnlockHistoryRequest.from({ characterId: CHARACTER_ID }),
|
||||
UnlockHistoryRequestSchema.parse({ characterId: CHARACTER_ID }),
|
||||
);
|
||||
|
||||
expect(httpClientMock).toHaveBeenNthCalledWith(
|
||||
|
||||
@@ -37,7 +37,7 @@ describe("PaymentApi", () => {
|
||||
const response = await new PaymentApi().getTipPlans();
|
||||
|
||||
expect(httpClientMock).toHaveBeenCalledWith("/api/payment/tip-plans");
|
||||
expect(response.toJson()).toEqual({
|
||||
expect(response).toEqual({
|
||||
plans: [
|
||||
{
|
||||
planId: "tip_coffee_usd_19_99",
|
||||
|
||||
@@ -2,32 +2,37 @@
|
||||
* Auth API
|
||||
*
|
||||
* 认证相关接口
|
||||
*
|
||||
*
|
||||
*/
|
||||
import { z } from "zod";
|
||||
|
||||
import { httpClient } from "./http_client";
|
||||
import { ApiPath } from "./api_path";
|
||||
import { ApiEnvelope, unwrap } from "./response_helper";
|
||||
import {
|
||||
FacebookIdentityRequest,
|
||||
FacebookIdentityResponse,
|
||||
FacebookIdentityResponseSchema,
|
||||
FacebookLoginRequest,
|
||||
FacebookPsidLoginRequest,
|
||||
FacebookPsidLoginResponse,
|
||||
FacebookPsidLoginResponseSchema,
|
||||
FbIdLoginRequest,
|
||||
GoogleLoginRequest,
|
||||
GuestLoginRequest,
|
||||
GuestLoginResponse,
|
||||
GuestLoginResponseSchema,
|
||||
LoginRequest,
|
||||
LoginResponse,
|
||||
LoginResponseSchema,
|
||||
RefreshTokenRequest,
|
||||
RefreshTokenResponse,
|
||||
RefreshTokenResponseSchema,
|
||||
RegisterRequest,
|
||||
} from "@/data/schemas/auth";
|
||||
import { User } from "@/data/schemas/user";
|
||||
import { User, UserSchema } from "@/data/schemas/user";
|
||||
import type { UserData } from "@/data/schemas/user/user";
|
||||
import { Logger } from "@/utils/logger";
|
||||
import { ApiPath } from "./api_path";
|
||||
import { httpClient } from "./http_client";
|
||||
import { ApiEnvelope, unwrap } from "./response_helper";
|
||||
|
||||
const log = new Logger("DataServicesApiAuthApi");
|
||||
|
||||
@@ -36,11 +41,11 @@ export class AuthApi {
|
||||
* 邮箱密码登录
|
||||
*/
|
||||
async emailLogin(body: LoginRequest): Promise<LoginResponse> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(
|
||||
ApiPath.emailLogin,
|
||||
{ method: "POST", body: body.toJson() }
|
||||
);
|
||||
return LoginResponse.fromJson(unwrap(env) as Record<string, unknown>);
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(ApiPath.emailLogin, {
|
||||
method: "POST",
|
||||
body,
|
||||
});
|
||||
return LoginResponseSchema.parse(unwrap(env) as Record<string, unknown>);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,7 +54,7 @@ export class AuthApi {
|
||||
async register(body: RegisterRequest): Promise<void> {
|
||||
await httpClient<ApiEnvelope<unknown>>(ApiPath.register, {
|
||||
method: "POST",
|
||||
body: body.toJson(),
|
||||
body,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -59,20 +64,20 @@ export class AuthApi {
|
||||
async googleLogin(body: GoogleLoginRequest): Promise<LoginResponse> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(ApiPath.googleLogin, {
|
||||
method: "POST",
|
||||
body: body.toJson(),
|
||||
body,
|
||||
});
|
||||
return LoginResponse.fromJson(unwrap(env) as Record<string, unknown>);
|
||||
return LoginResponseSchema.parse(unwrap(env) as Record<string, unknown>);
|
||||
}
|
||||
|
||||
/**
|
||||
* Facebook 登录
|
||||
*/
|
||||
async facebookLogin(body: FacebookLoginRequest): Promise<LoginResponse> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(
|
||||
ApiPath.facebookLogin,
|
||||
{ method: "POST", body: body.toJson() }
|
||||
);
|
||||
return LoginResponse.fromJson(unwrap(env) as Record<string, unknown>);
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(ApiPath.facebookLogin, {
|
||||
method: "POST",
|
||||
body,
|
||||
});
|
||||
return LoginResponseSchema.parse(unwrap(env) as Record<string, unknown>);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,9 +86,9 @@ export class AuthApi {
|
||||
async facebookIdLogin(body: FbIdLoginRequest): Promise<LoginResponse> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(
|
||||
ApiPath.facebookIdLogin,
|
||||
{ method: "POST", body: body.toJson() }
|
||||
{ method: "POST", body },
|
||||
);
|
||||
return LoginResponse.fromJson(unwrap(env) as Record<string, unknown>);
|
||||
return LoginResponseSchema.parse(unwrap(env) as Record<string, unknown>);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,9 +99,9 @@ export class AuthApi {
|
||||
): Promise<FacebookPsidLoginResponse> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(
|
||||
ApiPath.facebookPsidLogin,
|
||||
{ method: "POST", body: body.toJson() },
|
||||
{ method: "POST", body },
|
||||
);
|
||||
return FacebookPsidLoginResponse.fromJson(
|
||||
return FacebookPsidLoginResponseSchema.parse(
|
||||
unwrap(env) as Record<string, unknown>,
|
||||
);
|
||||
}
|
||||
@@ -109,9 +114,9 @@ export class AuthApi {
|
||||
): Promise<FacebookIdentityResponse> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(
|
||||
ApiPath.userFacebookIdentity,
|
||||
{ method: "POST", body: body.toJson() },
|
||||
{ method: "POST", body },
|
||||
);
|
||||
return FacebookIdentityResponse.fromJson(
|
||||
return FacebookIdentityResponseSchema.parse(
|
||||
unwrap(env) as Record<string, unknown>,
|
||||
);
|
||||
}
|
||||
@@ -120,7 +125,7 @@ export class AuthApi {
|
||||
* 退出登录(fire-and-forget)
|
||||
*
|
||||
* 后端 logout 端点的 envelope `data` 字段常为 `null`(登出端点没有业务数据),
|
||||
* 不要再用 `unwrap` + `LogoutResponse.fromJson` 解析 —— Zod schema 是 z.object,
|
||||
* 不要再用 `unwrap` + `LogoutResponseSchema.parse` 解析 —— Zod schema 是 z.object,
|
||||
* 对 null 会抛 ZodError "Invalid input: expected object, received null"。
|
||||
*
|
||||
* 对齐 `register` 的写法:调通就完事,不解析响应体。
|
||||
@@ -137,19 +142,20 @@ export class AuthApi {
|
||||
async guestLogin(body: GuestLoginRequest): Promise<GuestLoginResponse> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(ApiPath.guestLogin, {
|
||||
method: "POST",
|
||||
body: body.toJson(),
|
||||
body,
|
||||
});
|
||||
log.debug("[AuthApi.guestLogin] raw envelope from backend", env);
|
||||
const unwrapped = unwrap(env) as Record<string, unknown>;
|
||||
const userObj = unwrapped.user as { lastMessageAt?: unknown } | undefined;
|
||||
log.debug("[AuthApi.guestLogin] unwrapped data (pre-parse)", {
|
||||
hasUser: "user" in unwrapped,
|
||||
userKeys: userObj && typeof userObj === "object" ? Object.keys(userObj) : null,
|
||||
userKeys:
|
||||
userObj && typeof userObj === "object" ? Object.keys(userObj) : null,
|
||||
lastMessageAt: userObj?.lastMessageAt,
|
||||
lastMessageAtType: typeof userObj?.lastMessageAt,
|
||||
});
|
||||
try {
|
||||
return GuestLoginResponse.fromJson(unwrapped);
|
||||
return GuestLoginResponseSchema.parse(unwrapped);
|
||||
} catch (e) {
|
||||
if (e instanceof z.ZodError) {
|
||||
log.error("[AuthApi.guestLogin] ZodError parsing response", {
|
||||
@@ -167,15 +173,13 @@ export class AuthApi {
|
||||
/**
|
||||
* 刷新 Token
|
||||
*/
|
||||
async refreshToken(
|
||||
body: RefreshTokenRequest
|
||||
): Promise<RefreshTokenResponse> {
|
||||
async refreshToken(body: RefreshTokenRequest): Promise<RefreshTokenResponse> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(ApiPath.refresh, {
|
||||
method: "POST",
|
||||
body: body.toJson(),
|
||||
body,
|
||||
});
|
||||
return RefreshTokenResponse.fromJson(
|
||||
unwrap(env) as Record<string, unknown>
|
||||
return RefreshTokenResponseSchema.parse(
|
||||
unwrap(env) as Record<string, unknown>,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -183,10 +187,8 @@ export class AuthApi {
|
||||
* 获取当前用户信息
|
||||
*/
|
||||
async getCurrentUser(): Promise<User> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(
|
||||
ApiPath.getCurrentUser
|
||||
);
|
||||
return User.fromJson(unwrap(env) as UserData);
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(ApiPath.getCurrentUser);
|
||||
return UserSchema.parse(unwrap(env) as UserData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { CharactersResponse } from "@/data/schemas/character";
|
||||
import {
|
||||
CharactersResponse,
|
||||
CharactersResponseSchema,
|
||||
} from "@/data/schemas/character";
|
||||
|
||||
import { ApiPath } from "./api_path";
|
||||
import { httpClient } from "./http_client";
|
||||
@@ -7,7 +10,7 @@ import { type ApiEnvelope, unwrap } from "./response_helper";
|
||||
export class CharacterApi {
|
||||
async getCharacters(): Promise<CharactersResponse> {
|
||||
const envelope = await httpClient<ApiEnvelope<unknown>>(ApiPath.characters);
|
||||
return CharactersResponse.fromJson(unwrap(envelope));
|
||||
return CharactersResponseSchema.parse(unwrap(envelope));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,20 +2,24 @@
|
||||
* Chat API
|
||||
*
|
||||
* 聊天相关接口
|
||||
*
|
||||
*
|
||||
*/
|
||||
import { httpClient } from "./http_client";
|
||||
import { ApiPath } from "./api_path";
|
||||
import { ApiEnvelope, unwrap } from "./response_helper";
|
||||
import {
|
||||
ChatHistoryResponse,
|
||||
ChatHistoryResponseSchema,
|
||||
ChatSendResponse,
|
||||
ChatSendResponseSchema,
|
||||
SendMessageRequest,
|
||||
UnlockHistoryRequest,
|
||||
UnlockHistoryResponse,
|
||||
UnlockHistoryResponseSchema,
|
||||
UnlockPrivateRequest,
|
||||
UnlockPrivateResponse,
|
||||
UnlockPrivateResponseSchema,
|
||||
} from "@/data/schemas/chat";
|
||||
import { ApiPath } from "./api_path";
|
||||
import { httpClient } from "./http_client";
|
||||
import { ApiEnvelope, unwrap } from "./response_helper";
|
||||
|
||||
export class ChatApi {
|
||||
/**
|
||||
@@ -24,9 +28,9 @@ export class ChatApi {
|
||||
async sendMessage(body: SendMessageRequest): Promise<ChatSendResponse> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(ApiPath.chatSend, {
|
||||
method: "POST",
|
||||
body: body.toJson(),
|
||||
body,
|
||||
});
|
||||
return ChatSendResponse.fromJson(unwrap(env) as Record<string, unknown>);
|
||||
return ChatSendResponseSchema.parse(unwrap(env) as Record<string, unknown>);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40,8 +44,8 @@ export class ChatApi {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(ApiPath.chatHistory, {
|
||||
query: { characterId, limit, offset },
|
||||
});
|
||||
return ChatHistoryResponse.fromJson(
|
||||
unwrap(env) as Record<string, unknown>
|
||||
return ChatHistoryResponseSchema.parse(
|
||||
unwrap(env) as Record<string, unknown>,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -55,10 +59,10 @@ export class ChatApi {
|
||||
ApiPath.chatUnlockPrivate,
|
||||
{
|
||||
method: "POST",
|
||||
body: body.toJson(),
|
||||
body,
|
||||
},
|
||||
);
|
||||
return UnlockPrivateResponse.fromJson(
|
||||
return UnlockPrivateResponseSchema.parse(
|
||||
unwrap(env) as Record<string, unknown>,
|
||||
);
|
||||
}
|
||||
@@ -73,10 +77,10 @@ export class ChatApi {
|
||||
ApiPath.chatUnlockHistory,
|
||||
{
|
||||
method: "POST",
|
||||
body: body.toJson(),
|
||||
body,
|
||||
},
|
||||
);
|
||||
return UnlockHistoryResponse.fromJson(
|
||||
return UnlockHistoryResponseSchema.parse(
|
||||
unwrap(env) as Record<string, unknown>,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
FeedbackSubmitResponse,
|
||||
FeedbackSubmitResponseSchema,
|
||||
type SubmitFeedbackInput,
|
||||
} from "@/data/schemas/feedback";
|
||||
|
||||
@@ -19,7 +20,7 @@ export class FeedbackApi {
|
||||
method: "POST",
|
||||
body,
|
||||
});
|
||||
return FeedbackSubmitResponse.fromJson(unwrap(envelope));
|
||||
return FeedbackSubmitResponseSchema.parse(unwrap(envelope));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
* Metrics API
|
||||
*
|
||||
* 数据看板/上报相关接口
|
||||
*
|
||||
*
|
||||
*/
|
||||
import { httpClient } from "./http_client";
|
||||
import { ApiPath } from "./api_path";
|
||||
import { ApiEnvelope, unwrapOptional } from "./response_helper";
|
||||
import { AppEvent, PwaEvent } from "@/data/schemas/metrics";
|
||||
import { ApiPath } from "./api_path";
|
||||
import { httpClient } from "./http_client";
|
||||
import { ApiEnvelope, unwrapOptional } from "./response_helper";
|
||||
|
||||
export class MetricsApi {
|
||||
/**
|
||||
@@ -16,7 +16,7 @@ export class MetricsApi {
|
||||
async reportPwaEvent(body: PwaEvent): Promise<void> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(
|
||||
ApiPath.metricsPwaEvent,
|
||||
{ method: "POST", body: body.toJson() }
|
||||
{ method: "POST", body },
|
||||
);
|
||||
unwrapOptional(env);
|
||||
}
|
||||
@@ -25,10 +25,10 @@ export class MetricsApi {
|
||||
* 上报用户信息
|
||||
*/
|
||||
async reportUserInfo(body: AppEvent): Promise<void> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(
|
||||
ApiPath.reportUserInfo,
|
||||
{ method: "POST", body: body.toJson() }
|
||||
);
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(ApiPath.reportUserInfo, {
|
||||
method: "POST",
|
||||
body,
|
||||
});
|
||||
unwrapOptional(env);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,13 @@
|
||||
import {
|
||||
CreatePaymentOrderRequest,
|
||||
CreatePaymentOrderResponse,
|
||||
CreatePaymentOrderResponseSchema,
|
||||
PaymentOrderStatusResponse,
|
||||
PaymentOrderStatusResponseSchema,
|
||||
PaymentPlansResponse,
|
||||
PaymentPlansResponseSchema,
|
||||
TipPaymentPlansResponse,
|
||||
TipPaymentPlansResponseSchema,
|
||||
} from "@/data/schemas/payment";
|
||||
|
||||
import { ApiPath } from "./api_path";
|
||||
@@ -21,17 +25,15 @@ export class PaymentApi {
|
||||
*/
|
||||
async getPlans(): Promise<PaymentPlansResponse> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(ApiPath.paymentPlans);
|
||||
return PaymentPlansResponse.fromJson(
|
||||
return PaymentPlansResponseSchema.parse(
|
||||
unwrap(env) as Record<string, unknown>,
|
||||
);
|
||||
}
|
||||
|
||||
/** 获取咖啡打赏套餐列表。 */
|
||||
async getTipPlans(): Promise<TipPaymentPlansResponse> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(
|
||||
ApiPath.paymentTipPlans,
|
||||
);
|
||||
return TipPaymentPlansResponse.fromJson(
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(ApiPath.paymentTipPlans);
|
||||
return TipPaymentPlansResponseSchema.parse(
|
||||
unwrap(env) as Record<string, unknown>,
|
||||
);
|
||||
}
|
||||
@@ -46,10 +48,10 @@ export class PaymentApi {
|
||||
ApiPath.paymentCreateOrder,
|
||||
{
|
||||
method: "POST",
|
||||
body: body.toJson(),
|
||||
body,
|
||||
},
|
||||
);
|
||||
return CreatePaymentOrderResponse.fromJson(
|
||||
return CreatePaymentOrderResponseSchema.parse(
|
||||
unwrap(env) as Record<string, unknown>,
|
||||
);
|
||||
}
|
||||
@@ -57,20 +59,17 @@ export class PaymentApi {
|
||||
/**
|
||||
* 查询支付订单状态
|
||||
*/
|
||||
async getOrderStatus(
|
||||
orderId: string,
|
||||
): Promise<PaymentOrderStatusResponse> {
|
||||
async getOrderStatus(orderId: string): Promise<PaymentOrderStatusResponse> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(
|
||||
ApiPath.paymentOrderStatus,
|
||||
{
|
||||
query: { order_id: orderId },
|
||||
},
|
||||
);
|
||||
return PaymentOrderStatusResponse.fromJson(
|
||||
return PaymentOrderStatusResponseSchema.parse(
|
||||
unwrap(env) as Record<string, unknown>,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { DEFAULT_CHARACTER_ID } from "@/data/constants/character";
|
||||
import {
|
||||
PrivateAlbumsResponse,
|
||||
PrivateAlbumsResponseSchema,
|
||||
PrivateAlbumUnlockResponse,
|
||||
PrivateAlbumUnlockResponseSchema,
|
||||
UnlockPrivateAlbumRequest,
|
||||
} from "@/data/schemas/private-room";
|
||||
import { DEFAULT_CHARACTER_ID } from "@/data/constants/character";
|
||||
|
||||
import { ApiPath } from "./api_path";
|
||||
import { httpClient } from "./http_client";
|
||||
@@ -27,7 +29,7 @@ export class PrivateRoomApi {
|
||||
},
|
||||
},
|
||||
);
|
||||
return PrivateAlbumsResponse.fromJson(unwrap(env));
|
||||
return PrivateAlbumsResponseSchema.parse(unwrap(env));
|
||||
}
|
||||
|
||||
async unlockAlbum(
|
||||
@@ -38,10 +40,10 @@ export class PrivateRoomApi {
|
||||
ApiPath.privateRoomAlbumUnlock(albumId),
|
||||
{
|
||||
method: "POST",
|
||||
body: body.toJson(),
|
||||
body,
|
||||
},
|
||||
);
|
||||
return PrivateAlbumUnlockResponse.fromJson(unwrap(env));
|
||||
return PrivateAlbumUnlockResponseSchema.parse(unwrap(env));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,16 +2,18 @@
|
||||
* User API
|
||||
*
|
||||
* 用户相关接口
|
||||
*
|
||||
*
|
||||
*/
|
||||
import { httpClient } from "./http_client";
|
||||
import { ApiPath } from "./api_path";
|
||||
import { ApiEnvelope, unwrap } from "./response_helper";
|
||||
import {
|
||||
User,
|
||||
UserEntitlements,
|
||||
UserEntitlementsSchema,
|
||||
UserSchema,
|
||||
} from "@/data/schemas/user";
|
||||
import type { UserData } from "@/data/schemas/user/user";
|
||||
import { ApiPath } from "./api_path";
|
||||
import { httpClient } from "./http_client";
|
||||
import { ApiEnvelope, unwrap } from "./response_helper";
|
||||
|
||||
export class UserApi {
|
||||
/**
|
||||
@@ -19,15 +21,17 @@ export class UserApi {
|
||||
*/
|
||||
async getCurrentUser(): Promise<User> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(ApiPath.userProfile);
|
||||
return User.fromJson(unwrap(env) as UserData);
|
||||
return UserSchema.parse(unwrap(env) as UserData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户权益快照
|
||||
*/
|
||||
async getEntitlements(): Promise<UserEntitlements> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(ApiPath.userEntitlements);
|
||||
return UserEntitlements.fromJson(unwrap(env) as Record<string, unknown>);
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(
|
||||
ApiPath.userEntitlements,
|
||||
);
|
||||
return UserEntitlementsSchema.parse(unwrap(env) as Record<string, unknown>);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user