chore(deps): add unstorage and migrate ChatStorage to use SpAsyncUtil
This commit is contained in:
@@ -1,32 +1,29 @@
|
||||
"use client";
|
||||
|
||||
/**
|
||||
* AuthStorage 完整实现(示范 1:KV / localStorage)
|
||||
* AuthStorage 完整实现(基于 unstorage 抽象)
|
||||
*
|
||||
* 原始 Dart: lib/data/services/storage/auth_storage.dart
|
||||
*
|
||||
* SECURITY: 当前与 Dart 端行为一致,refresh_token 以明文存于 localStorage。
|
||||
* 后续轮次将升级到 HttpOnly Cookie 方案,参见 `clearAuthData` 处的 TODO 标记。
|
||||
*
|
||||
* 设计说明:
|
||||
* - 组合而非继承 `LocalStorage`(避免多重继承层级)
|
||||
* - 内部使用 `SpAsyncUtil` 静态类(@/utils/storage)
|
||||
* - 浏览器 → `localStorage` driver;SSR → memory driver(unstorage 自动)
|
||||
* - 单例挂在 class 静态字段,规避 HMR 复用污染
|
||||
* - 构造函数接受可选 `LocalStorage` 注入,便于测试时使用 jsdom 的 storage
|
||||
* - `hasXxx` = `token != null && token.length > 0`,对齐 Dart 端 `isNotEmpty` 语义
|
||||
* - `clearAuthData` 顺序清理:loginToken → guestToken → refreshToken,任一失败立即返回
|
||||
*/
|
||||
|
||||
import { Result, type Result as ResultT } from "@/utils/result";
|
||||
import { SpAsyncUtil } from "@/utils/storage";
|
||||
import { StorageKeys } from "../storage_keys";
|
||||
import type { IAuthStorage } from "./iauth_storage";
|
||||
import { LocalStorage } from "@/utils/local-storage";
|
||||
|
||||
export class AuthStorage implements IAuthStorage {
|
||||
private readonly ls: LocalStorage;
|
||||
private static _instance: AuthStorage | null = null;
|
||||
|
||||
constructor(localStorage?: LocalStorage) {
|
||||
this.ls = localStorage ?? LocalStorage.getInstance();
|
||||
}
|
||||
|
||||
static getInstance(): AuthStorage {
|
||||
if (!AuthStorage._instance) AuthStorage._instance = new AuthStorage();
|
||||
return AuthStorage._instance;
|
||||
@@ -40,10 +37,10 @@ export class AuthStorage implements IAuthStorage {
|
||||
// ---- login token ----
|
||||
|
||||
getLoginToken(): Promise<ResultT<string | null>> {
|
||||
return this.ls.getString(StorageKeys.loginToken);
|
||||
return SpAsyncUtil.getString(StorageKeys.loginToken);
|
||||
}
|
||||
setLoginToken(token: string): Promise<ResultT<void>> {
|
||||
return this.ls.setString(StorageKeys.loginToken, token);
|
||||
return SpAsyncUtil.setString(StorageKeys.loginToken, token);
|
||||
}
|
||||
async hasLoginToken(): Promise<ResultT<boolean>> {
|
||||
const r = await this.getLoginToken();
|
||||
@@ -51,16 +48,16 @@ export class AuthStorage implements IAuthStorage {
|
||||
return Result.ok(r.data !== null && r.data.length > 0);
|
||||
}
|
||||
clearLoginToken(): Promise<ResultT<void>> {
|
||||
return this.ls.remove(StorageKeys.loginToken);
|
||||
return SpAsyncUtil.remove(StorageKeys.loginToken);
|
||||
}
|
||||
|
||||
// ---- guest token ----
|
||||
|
||||
getGuestToken(): Promise<ResultT<string | null>> {
|
||||
return this.ls.getString(StorageKeys.guestToken);
|
||||
return SpAsyncUtil.getString(StorageKeys.guestToken);
|
||||
}
|
||||
setGuestToken(token: string): Promise<ResultT<void>> {
|
||||
return this.ls.setString(StorageKeys.guestToken, token);
|
||||
return SpAsyncUtil.setString(StorageKeys.guestToken, token);
|
||||
}
|
||||
async hasGuestToken(): Promise<ResultT<boolean>> {
|
||||
const r = await this.getGuestToken();
|
||||
@@ -68,16 +65,16 @@ export class AuthStorage implements IAuthStorage {
|
||||
return Result.ok(r.data !== null && r.data.length > 0);
|
||||
}
|
||||
clearGuestToken(): Promise<ResultT<void>> {
|
||||
return this.ls.remove(StorageKeys.guestToken);
|
||||
return SpAsyncUtil.remove(StorageKeys.guestToken);
|
||||
}
|
||||
|
||||
// ---- device id ----
|
||||
|
||||
getDeviceId(): Promise<ResultT<string | null>> {
|
||||
return this.ls.getString(StorageKeys.deviceId);
|
||||
return SpAsyncUtil.getString(StorageKeys.deviceId);
|
||||
}
|
||||
setDeviceId(deviceId: string): Promise<ResultT<void>> {
|
||||
return this.ls.setString(StorageKeys.deviceId, deviceId);
|
||||
return SpAsyncUtil.setString(StorageKeys.deviceId, deviceId);
|
||||
}
|
||||
|
||||
// ---- refresh token ----
|
||||
@@ -85,22 +82,22 @@ export class AuthStorage implements IAuthStorage {
|
||||
// SECURITY: 明文存储,仅供本轮与 Dart 行为对齐
|
||||
|
||||
getRefreshToken(): Promise<ResultT<string | null>> {
|
||||
return this.ls.getString(StorageKeys.refreshToken);
|
||||
return SpAsyncUtil.getString(StorageKeys.refreshToken);
|
||||
}
|
||||
setRefreshToken(token: string): Promise<ResultT<void>> {
|
||||
return this.ls.setString(StorageKeys.refreshToken, token);
|
||||
return SpAsyncUtil.setString(StorageKeys.refreshToken, token);
|
||||
}
|
||||
clearRefreshToken(): Promise<ResultT<void>> {
|
||||
return this.ls.remove(StorageKeys.refreshToken);
|
||||
return SpAsyncUtil.remove(StorageKeys.refreshToken);
|
||||
}
|
||||
|
||||
// ---- facebook id ----
|
||||
|
||||
getFacebookId(): Promise<ResultT<string | null>> {
|
||||
return this.ls.getString(StorageKeys.facebookId);
|
||||
return SpAsyncUtil.getString(StorageKeys.facebookId);
|
||||
}
|
||||
setFacebookId(id: string): Promise<ResultT<void>> {
|
||||
return this.ls.setString(StorageKeys.facebookId, id);
|
||||
return SpAsyncUtil.setString(StorageKeys.facebookId, id);
|
||||
}
|
||||
|
||||
// ---- bulk clear ----
|
||||
|
||||
Reference in New Issue
Block a user