diff --git a/package.json b/package.json index c33652d..b556fdd 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "access": "public" }, "peerDependencies": { - "@kevisual/query": "^0.0.14" + "@kevisual/query": "^0.0.15" }, "devDependencies": { "@types/node": "^22.13.11", diff --git a/src/login-cache.ts b/src/login-cache.ts index bfedb61..0fa5e5f 100644 --- a/src/login-cache.ts +++ b/src/login-cache.ts @@ -11,6 +11,10 @@ export interface Cache { * @update 删除缓存 */ del(): Promise; + /** + * 初始化 + */ + init?: () => Promise; } export type CacheLoginUser = { @@ -23,7 +27,7 @@ type CacheLogin = { loginUsers: CacheLoginUser[]; } & CacheLoginUser; -export type CacheStore = { +export type CacheStore = { name: string; cacheData: CacheLogin; /** @@ -51,10 +55,6 @@ export type CacheStore = { * 获取缓存的accessToken */ getAccessToken(): Promise; - /** - * 初始化 - */ - init(): Promise; /** * 清除当前用户 */ @@ -63,9 +63,14 @@ export type CacheStore = { * 清除所有用户 */ clearAll(): Promise; -} & Cache; -type LoginCacheStoreOpts = { + getValue(): Promise; + setValue(value: CacheLogin): Promise; + delValue(): Promise; + init(): Promise; +}; + +export type LoginCacheStoreOpts = { name: string; cache: Cache; }; @@ -94,28 +99,41 @@ export class LoginCacheStore implements CacheStore { * @param value * @returns */ - async set(key: string, value: CacheLogin) { - await this.cache.set(key, value); + async setValue(value: CacheLogin) { + await this.cache.set(this.name, value); + this.cacheData = value; return value; } /** * 删除缓存 */ - async del() { + async delValue() { await this.cache.del(); } - get(key: string): Promise { - return this.cache.get(key); + getValue(): Promise { + return this.cache.get(this.name); } - + /** + * 初始化,设置默认值 + */ async init() { - this.cacheData = (await this.get(this.name)) || { + const defaultData = { loginUsers: [], user: null, id: null, accessToken: null, refreshToken: null, }; + if (this.cache.init) { + try { + const cacheData = await this.cache.init(); + this.cacheData = cacheData || defaultData; + } catch (error) { + console.log('cacheInit error', error); + } + } else { + this.cacheData = (await this.getValue()) || defaultData; + } } /** * 设置当前用户 @@ -131,7 +149,7 @@ export class LoginCacheStore implements CacheStore { this.cacheData.id = user.id; this.cacheData.accessToken = user.accessToken; this.cacheData.refreshToken = user.refreshToken; - await this.set(this.name, this.cacheData); + await this.setValue(this.cacheData); } getCurrentUser(): Promise { @@ -160,7 +178,7 @@ export class LoginCacheStore implements CacheStore { this.cacheData.id = undefined; this.cacheData.accessToken = undefined; this.cacheData.refreshToken = undefined; - await this.set(this.name, this.cacheData); + await this.setValue(this.cacheData); } async clearAll() { this.cacheData.loginUsers = []; @@ -168,6 +186,6 @@ export class LoginCacheStore implements CacheStore { this.cacheData.id = undefined; this.cacheData.accessToken = undefined; this.cacheData.refreshToken = undefined; - await this.set(this.name, this.cacheData); + await this.setValue(this.cacheData); } } diff --git a/src/login-node-cache.ts b/src/login-node-cache.ts index f10ebee..11bff14 100644 --- a/src/login-node-cache.ts +++ b/src/login-node-cache.ts @@ -1,11 +1,12 @@ -import { Cache } from './login-cache.ts'; +import { Cache, LoginCacheStore, LoginCacheStoreOpts } from './login-cache.ts'; import { homedir } from 'node:os'; import { join, dirname } from 'node:path'; -import { readFileSync } from 'node:fs'; -import { readFile, writeFile, unlink, stat, mkdir } from 'node:fs/promises'; +import fs from 'node:fs'; +import { readFileSync, writeFileSync, accessSync } from 'node:fs'; +import { readFile, writeFile, unlink, mkdir } from 'node:fs/promises'; export const fileExists = async (filePath: string, createIfNotExists = false) => { try { - await stat(filePath); + accessSync(filePath, fs.constants.F_OK); return true; } catch (error) { if (createIfNotExists) { @@ -76,37 +77,48 @@ export class StorageNode implements Storage { } } export class LoginNodeCache implements Cache { - name: string; - cacheData: any; - filePath: string; - constructor(name: string) { - this.name = name; - const hostname = getHostName(); - this.filePath = join(homedir(), '.config', 'envision', 'config', `${hostname}-${name}.json`); - fileExists(this.filePath, true); - this.loadCache(this.filePath); - } + filepath: string; + constructor(filepath?: string) { + this.filepath = filepath || join(homedir(), '.config', 'envision', 'config', `${getHostName()}-login.json`); + fileExists(this.filepath, true); + } + async get(_key: string) { + const data = readFileSync(this.filepath, 'utf-8'); + try { + const jsonData = JSON.parse(data); + return jsonData; + } catch (error) { + console.log('get error', error); + return null; + } + } + async set(_key: string, value: any) { + const data = readFileSync(this.filepath, 'utf-8'); + try { + const jsonData = JSON.parse(data); + const newData = { ...jsonData, ...value }; + writeFileSync(this.filepath, JSON.stringify(newData, null, 2)); + } catch (error) { + console.log('set error', error); + } + } + async del() { + await unlink(this.filepath); + } async loadCache(filePath: string) { try { const data = await readFile(filePath, 'utf-8'); const jsonData = JSON.parse(data); - this.cacheData = jsonData; + return jsonData; } catch (error) { + console.log('loadCache error', error); const defaultData = { loginUsers: [] }; - this.cacheData = defaultData; await writeFile(filePath, JSON.stringify(defaultData, null, 2)); + return defaultData; } } - - async get() { - return this.cacheData; - } - async set(key: string, value: any) { - this.cacheData = value; - await writeFile(this.filePath, JSON.stringify(this.cacheData, null, 2)); - } - async del() { - await unlink(this.filePath); + async init() { + return await this.loadCache(this.filepath); } } diff --git a/src/query-login-node.ts b/src/query-login-node.ts index d90cabb..5cb6527 100644 --- a/src/query-login-node.ts +++ b/src/query-login-node.ts @@ -8,7 +8,7 @@ export class QueryLoginNode extends QueryLogin { super({ ...opts, storage, - cache: new LoginNodeCache('login'), + cache: new LoginNodeCache(), }); } } diff --git a/src/query-login.ts b/src/query-login.ts index f0ed7d6..380df1c 100644 --- a/src/query-login.ts +++ b/src/query-login.ts @@ -26,7 +26,7 @@ export class QueryLogin { /** * query login cache, 非实际操作, 一个cache的包裹模块 */ - cache: CacheStore; + cacheStore: CacheStore; isBrowser: boolean; load?: boolean; storage: Storage; @@ -34,7 +34,7 @@ export class QueryLogin { constructor(opts?: QueryLoginOpts) { this.query = opts?.query || new Query(); - this.cache = new LoginCacheStore({ name: 'login', cache: opts.cache }); + this.cacheStore = new LoginCacheStore({ name: 'login', cache: opts.cache }); this.isBrowser = opts?.isBrowser ?? true; this.init(); this.onLoad = opts?.onLoad; @@ -44,12 +44,19 @@ export class QueryLogin { this.query = query; } private async init() { - await this.cache.init(); + await this.cacheStore.init() this.load = true; this.onLoad?.(); } async post(data: any, opts?: DataOpts) { - return this.query.post({ path: 'user', ...data }, opts); + try { + return this.query.post({ path: 'user', ...data }, opts); + } catch (error) { + console.log('error', error); + return { + code: 400, + } as any; + } } /** * 登录, @@ -89,7 +96,7 @@ export class QueryLogin { if (resUser.code === 200) { const user = resUser.data; if (user) { - this.cache.setLoginUser({ + this.cacheStore.setLoginUser({ user, id: user.id, accessToken, @@ -107,10 +114,10 @@ export class QueryLogin { * @returns */ async queryRefreshToken(refreshToken?: string) { - const _refreshToken = refreshToken || this.cache.getRefreshToken(); + const _refreshToken = refreshToken || this.cacheStore.getRefreshToken(); let data = { refreshToken: _refreshToken }; if (!_refreshToken) { - await this.cache.clearCurrentUser(); + await this.cacheStore.clearCurrentUser(); return { code: 401, message: '请先登录', @@ -137,7 +144,7 @@ export class QueryLogin { async afterCheck401ToRefreshToken(response: Result, ctx?: { req?: any; res?: any; fetch?: any }, refetch?: boolean) { const that = this; if (response?.code === 401) { - const hasRefreshToken = await that.cache.getRefreshToken(); + const hasRefreshToken = await that.cacheStore.getRefreshToken(); if (hasRefreshToken) { const res = await that.queryRefreshToken(hasRefreshToken); if (res.code === 200) { @@ -159,7 +166,7 @@ export class QueryLogin { } } else { that.storage.removeItem('token'); - await that.cache.clearCurrentUser(); + await that.cacheStore.clearCurrentUser(); } return res; } @@ -250,7 +257,7 @@ export class QueryLogin { * @returns */ async switchUser(username: string) { - const localUserList = await this.cache.getCurrentUserList(); + const localUserList = await this.cacheStore.getCurrentUserList(); const user = localUserList.find((userItem) => userItem.user.username === username); if (user) { this.storage.setItem('token', user.accessToken || ''); @@ -275,18 +282,18 @@ export class QueryLogin { return res; } /** - * 退出登陆,去掉token, 并删除缓存 + * 退出登陆,去掉token, 并删除缓存 * @returns */ async logout() { this.storage.removeItem('token'); - const users = await this.cache.getCurrentUserList(); + const users = await this.cacheStore.getCurrentUserList(); const tokens = users .map((user) => { return user?.accessToken; }) .filter(Boolean); - this.cache.del(); + this.cacheStore.delValue(); return this.post({ key: 'logout', data: { tokens } }); } /**