feat(api): add account mutation clients
This commit is contained in:
@@ -54,6 +54,12 @@ export async function login(input: LoginInput): Promise<User> {
|
|||||||
return res.user
|
return res.user
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function logout(): Promise<void> {
|
||||||
|
await httpJson<unknown>("/api/v1/auth/logout", {
|
||||||
|
method: "POST",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export async function resetPassword(input: {
|
export async function resetPassword(input: {
|
||||||
email: string
|
email: string
|
||||||
vcode: string
|
vcode: string
|
||||||
|
|||||||
@@ -1,3 +1,36 @@
|
|||||||
|
import { isApiError } from "@/lib/errors"
|
||||||
|
|
||||||
|
export type UploadFileType = "avatar" | "chat" | "post" | "verification" | "dispute"
|
||||||
|
|
||||||
|
function getCookieValue(name: string): string | null {
|
||||||
|
if (typeof document === "undefined") return null
|
||||||
|
if (!document.cookie) return null
|
||||||
|
|
||||||
|
for (const part of document.cookie.split("; ")) {
|
||||||
|
if (part.startsWith(`${name}=`)) return part.slice(name.length + 1)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
async function readJsonBody(res: Response): Promise<{ json: unknown | null; text: string }> {
|
||||||
|
const text = await res.text()
|
||||||
|
if (!text) return { json: null, text: "" }
|
||||||
|
|
||||||
|
try {
|
||||||
|
return { json: JSON.parse(text) as unknown, text }
|
||||||
|
} catch {
|
||||||
|
return { json: null, text }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function messageFromJson(json: unknown): string | undefined {
|
||||||
|
if (typeof json !== "object" || json === null) return undefined
|
||||||
|
const value = json as { message?: unknown; msg?: unknown }
|
||||||
|
if (typeof value.message === "string") return value.message
|
||||||
|
if (typeof value.msg === "string") return value.msg
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
export async function getFileById(fileId: string): Promise<Blob> {
|
export async function getFileById(fileId: string): Promise<Blob> {
|
||||||
const res = await fetch(`/api/v1/files?key=${encodeURIComponent(fileId)}`)
|
const res = await fetch(`/api/v1/files?key=${encodeURIComponent(fileId)}`)
|
||||||
|
|
||||||
@@ -31,3 +64,37 @@ export async function getFileById(fileId: string): Promise<Blob> {
|
|||||||
|
|
||||||
throw { code, msg }
|
throw { code, msg }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function uploadFile(file: File, type: UploadFileType): Promise<string> {
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.set("type", type)
|
||||||
|
formData.set("file", file)
|
||||||
|
|
||||||
|
const headers = new Headers()
|
||||||
|
const xsrfToken = getCookieValue("__Host-XSRF-TOKEN")
|
||||||
|
if (xsrfToken) headers.set("XSRF-TOKEN", xsrfToken)
|
||||||
|
|
||||||
|
const res = await fetch("/api/v1/upload", {
|
||||||
|
method: "POST",
|
||||||
|
headers,
|
||||||
|
body: formData,
|
||||||
|
})
|
||||||
|
|
||||||
|
const { json, text } = await readJsonBody(res)
|
||||||
|
|
||||||
|
if (res.ok) {
|
||||||
|
if (typeof json === "object" && json !== null) {
|
||||||
|
const value = json as { url?: unknown }
|
||||||
|
if (typeof value.url === "string") return value.url
|
||||||
|
}
|
||||||
|
throw { code: 500, msg: "上传响应缺少文件地址" }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.status === 401) throw new Error("UNAUTHORIZED")
|
||||||
|
if (isApiError(json)) throw json
|
||||||
|
|
||||||
|
throw {
|
||||||
|
code: res.status,
|
||||||
|
msg: messageFromJson(json) ?? (text || res.statusText || "Request failed"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
export { login, register, resetPassword } from "./auth"
|
export { login, logout, register, resetPassword } from "./auth"
|
||||||
export { sendForgotPasswordCode } from "./auth-extra"
|
export { sendForgotPasswordCode } from "./auth-extra"
|
||||||
export { getChatSessionById, listChatMessages, listChatSessions } from "./chat"
|
export { getChatSessionById, listChatMessages, listChatSessions } from "./chat"
|
||||||
export { requestWithAuth } from "./client"
|
export { requestWithAuth } from "./client"
|
||||||
@@ -6,7 +6,7 @@ export { addComment, listCommentsByPost, toggleCommentLike } from "./comments"
|
|||||||
export { getDisputeByOrderId, listDisputes } from "./disputes"
|
export { getDisputeByOrderId, listDisputes } from "./disputes"
|
||||||
export { sendEmailVerificationCode } from "./email"
|
export { sendEmailVerificationCode } from "./email"
|
||||||
export { isFavorited, listFavorites } from "./favorites"
|
export { isFavorited, listFavorites } from "./favorites"
|
||||||
export { getFileById } from "./files"
|
export { getFileById, uploadFile } from "./files"
|
||||||
export { getGameById, listGames } from "./games"
|
export { getGameById, listGames } from "./games"
|
||||||
export { listNotifications, markNotificationAsRead } from "./notifications"
|
export { listNotifications, markNotificationAsRead } from "./notifications"
|
||||||
export { getOrderById, listOrders, listOrdersByConsumer } from "./orders"
|
export { getOrderById, listOrders, listOrdersByConsumer } from "./orders"
|
||||||
@@ -16,4 +16,4 @@ export { listReviews, listReviewsByOrder, listReviewsByTargetUser } from "./revi
|
|||||||
export { getServiceById, listServices, listServicesByPlayer } from "./services"
|
export { getServiceById, listServices, listServicesByPlayer } from "./services"
|
||||||
export { getShopById, getShopByOwnerId, listShops } from "./shops"
|
export { getShopById, getShopByOwnerId, listShops } from "./shops"
|
||||||
export { getWalletBalance, listWalletTransactions } from "./transactions"
|
export { getWalletBalance, listWalletTransactions } from "./transactions"
|
||||||
export { getCurrentUserForLogin, getUserById } from "./users"
|
export { getCurrentUserForLogin, getUserById, switchCurrentRole, updateCurrentUser } from "./users"
|
||||||
|
|||||||
+22
-2
@@ -1,10 +1,16 @@
|
|||||||
import { httpJson } from "@/lib/api/http"
|
import { httpJson } from "@/lib/api/http"
|
||||||
import { isApiError } from "@/lib/errors"
|
import { isApiError } from "@/lib/errors"
|
||||||
import type { User } from "@/lib/types"
|
import type { User, UserRole } from "@/lib/types"
|
||||||
|
|
||||||
|
export type UpdateCurrentUserInput = {
|
||||||
|
nickname?: string
|
||||||
|
avatar?: string
|
||||||
|
bio?: string
|
||||||
|
}
|
||||||
|
|
||||||
export async function getUserById(userId: string): Promise<User | undefined> {
|
export async function getUserById(userId: string): Promise<User | undefined> {
|
||||||
try {
|
try {
|
||||||
return await httpJson<User>(`/api/v1/users/${userId}`)
|
return await httpJson<User>(`/api/v1/users/${encodeURIComponent(userId)}`)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (isApiError(err) && err.code === 404) return undefined
|
if (isApiError(err) && err.code === 404) return undefined
|
||||||
throw err
|
throw err
|
||||||
@@ -14,3 +20,17 @@ export async function getUserById(userId: string): Promise<User | undefined> {
|
|||||||
export async function getCurrentUserForLogin(): Promise<User> {
|
export async function getCurrentUserForLogin(): Promise<User> {
|
||||||
return httpJson<User>("/api/v1/users/me")
|
return httpJson<User>("/api/v1/users/me")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function updateCurrentUser(input: UpdateCurrentUserInput): Promise<User> {
|
||||||
|
return httpJson<User>("/api/v1/users/me", {
|
||||||
|
method: "PUT",
|
||||||
|
json: input,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function switchCurrentRole(role: UserRole): Promise<void> {
|
||||||
|
await httpJson<unknown>("/api/v1/users/me/switch-role", {
|
||||||
|
method: "POST",
|
||||||
|
json: { role },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user