From 68c1976754200fc6f61e64eb4b2fed5947cc135f Mon Sep 17 00:00:00 2001 From: abearxiong Date: Sat, 21 Feb 2026 03:08:39 +0800 Subject: [PATCH] feat: add user info command and package management for assistant app - Implemented a new command 'me' to view current user information in the assistant application. - Created a common configuration file for the assistant app with package details and scripts. - Added functionality to check and update package.json dependencies and devDependencies in the assistant app. - Refactored storage initialization in query module to use StorageNode. --- assistant/kevisual.json | 29 +- assistant/package.json | 14 +- assistant/src/command/plugins/install.ts | 1 - assistant/src/command/user/me.ts | 14 + assistant/src/index.ts | 1 + .../assistant/config/get-assistan-config.ts | 1 - .../src/module/assistant/config/index.ts | 41 +- .../local-app-manager/assistant-app.ts | 2 +- assistant/src/module/assistant/query/index.ts | 28 +- assistant/src/module/npm-install.ts | 4 +- assistant/src/query/index.ts | 7 - assistant/src/query/query-ai/defines/ai.ts | 42 - assistant/src/query/query-ai/query-ai.ts | 101 --- .../src/query/query-login/login-cache.ts | 204 ----- .../src/query/query-login/login-node-cache.ts | 132 --- .../query/query-login/query-login-browser.ts | 12 - .../src/query/query-login/query-login-node.ts | 14 - .../src/query/query-login/query-login.ts | 434 ---------- assistant/src/server.ts | 22 +- assistant/src/services/init/common.ts | 38 + assistant/src/services/init/index.ts | 70 +- assistant/src/services/init/package.json | 25 +- assistant/src/services/init/update-pkgs.ts | 111 +++ package.json | 8 +- pnpm-lock.yaml | 751 ++++++++++-------- src/module/query.ts | 4 +- 26 files changed, 657 insertions(+), 1453 deletions(-) create mode 100644 assistant/src/command/user/me.ts delete mode 100644 assistant/src/query/index.ts delete mode 100644 assistant/src/query/query-ai/defines/ai.ts delete mode 100644 assistant/src/query/query-ai/query-ai.ts delete mode 100644 assistant/src/query/query-login/login-cache.ts delete mode 100644 assistant/src/query/query-login/login-node-cache.ts delete mode 100644 assistant/src/query/query-login/query-login-browser.ts delete mode 100644 assistant/src/query/query-login/query-login-node.ts delete mode 100644 assistant/src/query/query-login/query-login.ts create mode 100644 assistant/src/services/init/common.ts create mode 100644 assistant/src/services/init/update-pkgs.ts diff --git a/assistant/kevisual.json b/assistant/kevisual.json index b51a7fc..801dd07 100644 --- a/assistant/kevisual.json +++ b/assistant/kevisual.json @@ -3,30 +3,7 @@ "metadata": { "share": "public" }, - "checkDir": { - "src/query/query-login": { - "url": "https://kevisual.xiongxiao.me/root/ai/code/registry/query/query-login", - "enabled": true - }, - "src/query/query-ai": { - "url": "https://kevisual.xiongxiao.me/root/ai/code/registry/query/query-ai", - "enabled": true - } - }, - "syncDirectory": [ - { - "files": [ - "src/query/query-login/**/*", - "src/query/query-ai/**/*" - ], - "ignore": [], - "registry": "https://kevisual.xiongxiao.me/root/ai/code/registry", - "replace": { - "src/": "" - } - } - ], - "sync": { - "src/query/index.ts": "https://kevisual.xiongxiao.me/root/ai/code/registry/query/index.ts" - } + "checkDir": {}, + "syncDirectory": [], + "sync": {} } \ No newline at end of file diff --git a/assistant/package.json b/assistant/package.json index 05cac48..4d71323 100644 --- a/assistant/package.json +++ b/assistant/package.json @@ -10,7 +10,7 @@ ], "author": "abearxiong (https://www.xiongxiao.me)", "license": "MIT", - "packageManager": "pnpm@10.30.0", + "packageManager": "pnpm@10.30.1", "type": "module", "files": [ "dist", @@ -44,17 +44,17 @@ "devDependencies": { "@inquirer/prompts": "^8.2.1", "@kevisual/ai": "^0.0.24", - "@kevisual/api": "^0.0.52", + "@kevisual/api": "^0.0.55", "@kevisual/load": "^0.0.6", "@kevisual/local-app-manager": "^0.1.32", "@kevisual/logger": "^0.0.4", "@kevisual/query": "0.0.49", - "@kevisual/router": "^0.0.80", + "@kevisual/router": "^0.0.83", "@kevisual/types": "^0.0.12", "@kevisual/use-config": "^1.0.30", - "@opencode-ai/plugin": "^1.2.6", + "@opencode-ai/plugin": "^1.2.10", "@types/bun": "^1.3.9", - "@types/node": "^25.2.3", + "@types/node": "^25.3.0", "@types/send": "^1.2.1", "@types/ws": "^8.18.1", "chalk": "^5.6.2", @@ -76,11 +76,11 @@ "access": "public" }, "dependencies": { - "@aws-sdk/client-s3": "^3.992.0", + "@aws-sdk/client-s3": "^3.994.0", "@kevisual/js-filter": "^0.0.5", "@kevisual/oss": "^0.0.19", "@kevisual/video-tools": "^0.0.13", - "@opencode-ai/sdk": "^1.2.6", + "@opencode-ai/sdk": "^1.2.10", "es-toolkit": "^1.44.0", "eventemitter3": "^5.0.4", "lowdb": "^7.0.1", diff --git a/assistant/src/command/plugins/install.ts b/assistant/src/command/plugins/install.ts index c5e6600..69a0950 100644 --- a/assistant/src/command/plugins/install.ts +++ b/assistant/src/command/plugins/install.ts @@ -1,5 +1,4 @@ import { program, Command, assistantConfig } from '@/program.ts'; -import { spawnSync } from 'node:child_process'; import { parseHomeArg, HomeConfigDir } from '@/module/assistant/config/args.ts'; import { execCommand } from '@/module/npm-install.ts'; diff --git a/assistant/src/command/user/me.ts b/assistant/src/command/user/me.ts new file mode 100644 index 0000000..1722657 --- /dev/null +++ b/assistant/src/command/user/me.ts @@ -0,0 +1,14 @@ +import { program, Command, assistantConfig } from '@/program.ts'; +import { AssistantQuery } from '@/lib.ts'; +import { logger } from '@/module/logger.ts'; + +const me = new Command('me') + .description('查看当前用户信息') + .action(async () => { + const aq = new AssistantQuery(assistantConfig); + await aq.init() + const info = await aq.queryLogin.checkLocalUser() + logger.info(info); + }); + +program.addCommand(me); \ No newline at end of file diff --git a/assistant/src/index.ts b/assistant/src/index.ts index 11bec8b..6b92baa 100644 --- a/assistant/src/index.ts +++ b/assistant/src/index.ts @@ -6,6 +6,7 @@ import './command/app/index.ts'; import './command/run-scripts/index.ts'; import './command/ai/index.ts'; import './command/plugins/install.ts'; +import './command/user/me.ts'; /** * 通过命令行解析器解析参数 diff --git a/assistant/src/module/assistant/config/get-assistan-config.ts b/assistant/src/module/assistant/config/get-assistan-config.ts index b8359e2..fb7c933 100644 --- a/assistant/src/module/assistant/config/get-assistan-config.ts +++ b/assistant/src/module/assistant/config/get-assistan-config.ts @@ -1,5 +1,4 @@ import fs from 'node:fs'; -import { useKey } from '@kevisual/use-config'; export const getFileConfig = (filePath: string): any => { return JSON.parse(fs.readFileSync(filePath, 'utf8')); } \ No newline at end of file diff --git a/assistant/src/module/assistant/config/index.ts b/assistant/src/module/assistant/config/index.ts index 26821ea..7949787 100644 --- a/assistant/src/module/assistant/config/index.ts +++ b/assistant/src/module/assistant/config/index.ts @@ -1,15 +1,11 @@ import path from 'path'; -import { homedir } from 'os'; import fs from 'fs'; import { checkFileExists, createDir } from '../file/index.ts'; import { ProxyInfo } from '../proxy/proxy.ts'; import dotenv from 'dotenv'; -import { logger } from '@/module/logger.ts'; -import { z } from 'zod' import { HomeConfigDir } from './args.ts' import { getFileConfig } from './get-assistan-config.ts'; import { useKey } from '@kevisual/use-config'; -import { env } from 'pm2'; /** * 助手配置文件路径, 全局配置文件目录 @@ -231,25 +227,15 @@ export class AssistantConfig { getConfig(): AssistantConfigData { try { if (!checkFileExists(this.configPath.configPath)) { - fs.writeFileSync(this.configPath.configPath, JSON.stringify({ proxy: [] }, null, 2)); - return { - app: { - url: 'https://kevisual.cn', - }, - proxy: [], - }; + const defaultConfig = this.getDefaultInitAssistantConfig(); + fs.writeFileSync(this.configPath.configPath, JSON.stringify(defaultConfig, null, 2)); + return defaultConfig; } assistantConfig = getFileConfig(this.configPath.configPath); return assistantConfig; } catch (error) { console.error('file read', error.message); process.exit(1); - return { - app: { - url: 'https://kevisual.cn', - }, - proxy: [], - }; } } getCacheAssistantConfig() { @@ -393,6 +379,23 @@ export class AssistantConfig { // 如果没有找到助手配置文件目录,则返回当前目录, 执行默认创建助手配置文件目录 return checkConfigDir; } + protected getDefaultInitAssistantConfig() { + const id = randomId(); + return { + app: { + url: 'https://kevisual.cn', + id, + }, + description: '助手配置文件', + docs: "https://kevisual.cn/root/cli/docs/", + home: '/root/home', + proxy: [], + share: { + enabled: false, + url: 'https://kevisual.cn/ws/proxy', + }, + } as AssistantConfigData; + } } type AppConfig = { @@ -408,4 +411,6 @@ export const parseIfJson = (content: string) => { } }; -export * from './args.ts'; \ No newline at end of file +export * from './args.ts'; + +const randomId = () => Math.random().toString(36).substring(2, 8); \ No newline at end of file diff --git a/assistant/src/module/assistant/local-app-manager/assistant-app.ts b/assistant/src/module/assistant/local-app-manager/assistant-app.ts index 96cbe21..1ed1f37 100644 --- a/assistant/src/module/assistant/local-app-manager/assistant-app.ts +++ b/assistant/src/module/assistant/local-app-manager/assistant-app.ts @@ -216,7 +216,7 @@ export class AssistantApp extends Manager { const routeStr = typeof route === 'string' ? route : route.path; const resolvedPath = this.resolver.resolve(routeStr); await import(resolvedPath); - console.log('[routes] 路由已初始化', route, resolvedPath); + console.log('[routes] 路由已初始化', route); } catch (err) { console.error('初始化路由失败', route, err); } diff --git a/assistant/src/module/assistant/query/index.ts b/assistant/src/module/assistant/query/index.ts index 4699488..b50a3d8 100644 --- a/assistant/src/module/assistant/query/index.ts +++ b/assistant/src/module/assistant/query/index.ts @@ -1,14 +1,33 @@ import { DataOpts, Query } from "@kevisual/query/query"; import { AssistantConfig } from "../config/index.ts"; - +import { QueryLoginNode } from '@kevisual/api/query-login-node' +import { EventEmitter } from 'eventemitter3' export class AssistantQuery { config: AssistantConfig; - query: Query ; + query: Query; + queryLogin: QueryLoginNode; + emitter = new EventEmitter(); + isLoad = false; constructor(config: AssistantConfig) { config.checkMounted(); this.config = config; - this.query = new Query({ url: config.getRegistry() + '/api/router' }); + this.query = new Query({ url: config.getRegistry() + '/api/router' }); + this.queryLogin = new QueryLoginNode({ + query: this.query, onLoad: () => { + this.isLoad = true; + this.emitter.emit('load') + } + }); + } + async init() { + if (this.isLoad) return true; + return new Promise((resolve) => { + this.emitter.on('load', () => { + this.isLoad = true; + resolve(true); + }) + }) } post(body: any, options?: DataOpts) { return this.query.post(body, options); @@ -16,4 +35,7 @@ export class AssistantQuery { get(body: any, options?: DataOpts) { return this.query.get(body, options); } + getToken() { + return this.queryLogin.getToken(); + } } \ No newline at end of file diff --git a/assistant/src/module/npm-install.ts b/assistant/src/module/npm-install.ts index 32be6e2..4fcdb54 100644 --- a/assistant/src/module/npm-install.ts +++ b/assistant/src/module/npm-install.ts @@ -29,9 +29,9 @@ export const installDeps = async (opts: InstallDepsOptions) => { console.log('installDeps', appPath, params); const syncSpawn = opts.sync ? spawnSync : spawn; if (isPnpm) { - syncSpawn('pnpm', params, { cwd: appPath, stdio: 'inherit', env: process.env }); + syncSpawn('pnpm', params, { cwd: appPath, stdio: 'inherit', env: { ...process.env, CI: 'true' }, shell: true }); } else { - syncSpawn('npm', params, { cwd: appPath, stdio: 'inherit', env: process.env }); + syncSpawn('npm', params, { cwd: appPath, stdio: 'inherit', env: process.env, shell: true }); } }; diff --git a/assistant/src/query/index.ts b/assistant/src/query/index.ts deleted file mode 100644 index cff06fa..0000000 --- a/assistant/src/query/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Query } from '@kevisual/query'; - -export const query = new Query(); - -export const clientQuery = new Query({ url: '/client/router' }); - -export { QueryUtil } from '@kevisual/router/define'; diff --git a/assistant/src/query/query-ai/defines/ai.ts b/assistant/src/query/query-ai/defines/ai.ts deleted file mode 100644 index d8ca83b..0000000 --- a/assistant/src/query/query-ai/defines/ai.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { QueryUtil } from '@/query/index.ts'; - -type Message = { - role?: 'user' | 'assistant' | 'system' | 'tool'; - content?: string; - name?: string; -}; -export type PostChat = { - messages?: Message[]; - model?: string; - group?: string; - user?: string; -}; - -export type ChatDataOpts = { - id?: string; - title?: string; - messages?: any[]; - data?: any; - type?: 'temp' | 'keep' | string; -}; -export type ChatOpts = { - username: string; - model: string; - /** - * 获取完整消息回复 - */ - getFull?: boolean; - group: string; - /** - * openai的参数 - */ - options?: any; -}; - -export const appDefine = QueryUtil.create({ - chat: { - path: 'ai', - key: 'chat', - description: '与 AI 进行对话, 调用 GPT 的AI 服务,生成结果,并返回。', - }, -}); diff --git a/assistant/src/query/query-ai/query-ai.ts b/assistant/src/query/query-ai/query-ai.ts deleted file mode 100644 index 2ede31c..0000000 --- a/assistant/src/query/query-ai/query-ai.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { appDefine } from './defines/ai.ts'; -import { PostChat, ChatOpts, ChatDataOpts } from './defines/ai.ts'; - -import { BaseQuery, DataOpts, Query } from '@kevisual/query/query'; - -export { appDefine }; - -export class QueryApp extends BaseQuery { - constructor(opts?: { query: T }) { - super({ - ...opts, - query: opts?.query!, - queryDefine: appDefine, - }); - } - /** - * 与 AI 进行对话, 调用 GPT 的AI 服务,生成结果,并返回。 - * @param data - * @param opts - * @returns - */ - postChat(data: PostChat, opts?: DataOpts) { - return this.chain('chat').post(data, opts); - } - /** - * 获取模型列表 - * @param opts - * @returns - */ - getModelList(data?: { usernames?: string[] }, opts?: DataOpts) { - return this.query.post( - { - path: 'ai', - key: 'get-model-list', - data, - }, - opts, - ); - } - /** - * 聊天对话模型 - * @param data - * @param chatOpts - * @param opts - * @returns - */ - chat(data: ChatDataOpts, chatOpts: ChatOpts, opts?: DataOpts) { - const { username, model, group, getFull = true } = chatOpts; - if (!username || !model || !group) { - throw new Error('username, model, group is required'); - } - return this.query.post( - { - path: 'ai', - key: 'chat', - ...chatOpts, - getFull, - data, - }, - opts, - ); - } - clearConfigCache(opts?: DataOpts) { - return this.query.post( - { - path: 'ai', - key: 'clear-cache', - }, - opts, - ); - } - /** - * 获取聊天使用情况 - * @param opts - * @returns - */ - getChatUsage(opts?: DataOpts) { - return this.query.post( - { - path: 'ai', - key: 'get-chat-usage', - }, - opts, - ); - } - - /** - * 清除当前用户模型自己的统计 - * @param opts - * @returns - */ - clearSelfUsage(opts?: DataOpts) { - return this.query.post( - { - path: 'ai', - key: 'clear-chat-limit', - }, - opts, - ); - } -} diff --git a/assistant/src/query/query-login/login-cache.ts b/assistant/src/query/query-login/login-cache.ts deleted file mode 100644 index 0ee1bf9..0000000 --- a/assistant/src/query/query-login/login-cache.ts +++ /dev/null @@ -1,204 +0,0 @@ -export interface Cache { - /** - * @update 获取缓存 - */ - get(key: string): Promise; - /** - * @update 设置缓存 - */ - set(key: string, value: any): Promise; - /** - * @update 删除缓存 - */ - del(): Promise; - /** - * 初始化 - */ - init?: () => Promise; -} -type User = { - avatar?: string; - description?: string; - id?: string; - needChangePassword?: boolean; - orgs?: string[]; - type?: string; - username?: string; -}; - -export type CacheLoginUser = { - user?: User; - id?: string; - accessToken?: string; - refreshToken?: string; -}; -type CacheLogin = { - loginUsers: CacheLoginUser[]; -} & CacheLoginUser; - -export type CacheStore = { - name: string; - /** - * 缓存数据 - * @important 需要先调用init - */ - cacheData: CacheLogin; - /** - * 实际操作的cache, 需要先调用init - */ - cache: T; - - /** - * 设置当前用户 - */ - setLoginUser(user: CacheLoginUser): Promise; - /** - * 获取当前用户 - */ - getCurrentUser(): Promise; - /** - * 获取当前用户列表 - */ - getCurrentUserList(): Promise; - /** - * 获取缓存的refreshToken - */ - getRefreshToken(): Promise; - /** - * 获取缓存的accessToken - */ - getAccessToken(): Promise; - /** - * 清除当前用户 - */ - clearCurrentUser(): Promise; - /** - * 清除所有用户 - */ - clearAll(): Promise; - - getValue(): Promise; - setValue(value: CacheLogin): Promise; - delValue(): Promise; - init(): Promise; -}; - -export type LoginCacheStoreOpts = { - name: string; - cache: Cache; -}; -export class LoginCacheStore implements CacheStore { - cache: Cache; - name: string; - cacheData: CacheLogin; - constructor(opts: LoginCacheStoreOpts) { - if (!opts.cache) { - throw new Error('cache is required'); - } - // @ts-ignore - this.cache = opts.cache; - this.cacheData = { - loginUsers: [], - user: undefined, - id: undefined, - accessToken: undefined, - refreshToken: undefined, - }; - this.name = opts.name; - } - /** - * 设置缓存 - * @param key - * @param value - * @returns - */ - async setValue(value: CacheLogin) { - await this.cache.set(this.name, value); - this.cacheData = value; - return value; - } - /** - * 删除缓存 - */ - async delValue() { - await this.cache.del(); - } - getValue(): Promise { - return this.cache.get(this.name); - } - /** - * 初始化,设置默认值 - */ - async init() { - 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; - } - } - /** - * 设置当前用户 - * @param user - */ - async setLoginUser(user: CacheLoginUser) { - const has = this.cacheData.loginUsers.find((u) => u.id === user.id); - if (has) { - this.cacheData.loginUsers = this.cacheData?.loginUsers?.filter((u) => u?.id && u.id !== user.id); - } - this.cacheData.loginUsers.push(user); - this.cacheData.user = user.user; - this.cacheData.id = user.id; - this.cacheData.accessToken = user.accessToken; - this.cacheData.refreshToken = user.refreshToken; - await this.setValue(this.cacheData); - } - - getCurrentUser(): Promise { - const cacheData = this.cacheData; - return Promise.resolve(cacheData.user!); - } - getCurrentUserList(): Promise { - return Promise.resolve(this.cacheData.loginUsers.filter((u) => u?.id)); - } - getRefreshToken(): Promise { - const cacheData = this.cacheData; - return Promise.resolve(cacheData.refreshToken || ''); - } - getAccessToken(): Promise { - const cacheData = this.cacheData; - return Promise.resolve(cacheData.accessToken || ''); - } - - async clearCurrentUser() { - const user = await this.getCurrentUser(); - const has = this.cacheData.loginUsers.find((u) => u.id === user.id); - if (has) { - this.cacheData.loginUsers = this.cacheData?.loginUsers?.filter((u) => u?.id && u.id !== user.id); - } - this.cacheData.user = undefined; - this.cacheData.id = undefined; - this.cacheData.accessToken = undefined; - this.cacheData.refreshToken = undefined; - await this.setValue(this.cacheData); - } - async clearAll() { - this.cacheData.loginUsers = []; - this.cacheData.user = undefined; - this.cacheData.id = undefined; - this.cacheData.accessToken = undefined; - this.cacheData.refreshToken = undefined; - await this.setValue(this.cacheData); - } -} diff --git a/assistant/src/query/query-login/login-node-cache.ts b/assistant/src/query/query-login/login-node-cache.ts deleted file mode 100644 index a0e2b26..0000000 --- a/assistant/src/query/query-login/login-node-cache.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { Cache } from './login-cache.ts'; -import { homedir } from 'node:os'; -import { join, dirname } from 'node:path'; -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 = true, isFile = true, isDir = false }: { createIfNotExists?: boolean; isFile?: boolean; isDir?: boolean } = {}, -) => { - try { - accessSync(filePath, fs.constants.F_OK); - return true; - } catch (error) { - if (createIfNotExists && isDir) { - await mkdir(filePath, { recursive: true }); - return true; - } else if (createIfNotExists && isFile) { - await mkdir(dirname(filePath), { recursive: true }); - return false; - } - return false; - } -}; -export const readConfigFile = (filePath: string) => { - try { - const data = readFileSync(filePath, 'utf-8'); - const jsonData = JSON.parse(data); - return jsonData; - } catch (error) { - return {}; - } -}; -export const writeConfigFile = (filePath: string, data: any) => { - writeFileSync(filePath, JSON.stringify(data, null, 2)); -}; -export const getHostName = () => { - const configDir = join(homedir(), '.config', 'envision'); - const configFile = join(configDir, 'config.json'); - const config = readConfigFile(configFile); - const baseURL = config.baseURL || 'https://kevisual.cn'; - const hostname = new URL(baseURL).hostname; - return hostname; -}; -export class StorageNode implements Storage { - cacheData: any; - filePath: string; - constructor() { - this.cacheData = {}; - const configDir = join(homedir(), '.config', 'envision'); - const hostname = getHostName(); - this.filePath = join(configDir, 'config', `${hostname}-storage.json`); - fileExists(this.filePath, { isFile: true }); - } - async loadCache() { - const filePath = this.filePath; - try { - const data = await readConfigFile(filePath); - this.cacheData = data; - } catch (error) { - this.cacheData = {}; - await writeFile(filePath, JSON.stringify(this.cacheData, null, 2)); - } - } - get length() { - return Object.keys(this.cacheData).length; - } - getItem(key: string) { - return this.cacheData[key]; - } - setItem(key: string, value: any) { - this.cacheData[key] = value; - writeFile(this.filePath, JSON.stringify(this.cacheData, null, 2)); - } - removeItem(key: string) { - delete this.cacheData[key]; - writeFile(this.filePath, JSON.stringify(this.cacheData, null, 2)); - } - clear() { - this.cacheData = {}; - writeFile(this.filePath, JSON.stringify(this.cacheData, null, 2)); - } - key(index: number) { - return Object.keys(this.cacheData)[index]; - } -} -export class LoginNodeCache implements Cache { - filepath: string; - - constructor(filepath?: string) { - this.filepath = filepath || join(homedir(), '.config', 'envision', 'config', `${getHostName()}-login.json`); - fileExists(this.filepath, { isFile: true }); - } - async get(_key: string) { - try { - const filePath = this.filepath; - const data = readConfigFile(filePath); - return data; - } catch (error) { - console.log('get error', error); - return {}; - } - } - async set(_key: string, value: any) { - try { - const data = readConfigFile(this.filepath); - const newData = { ...data, ...value }; - writeConfigFile(this.filepath, newData); - } 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); - return jsonData; - } catch (error) { - // console.log('loadCache error', error); - console.log('create new cache file:', filePath); - const defaultData = { loginUsers: [] }; - writeConfigFile(filePath, defaultData); - return defaultData; - } - } - async init() { - return await this.loadCache(this.filepath); - } -} diff --git a/assistant/src/query/query-login/query-login-browser.ts b/assistant/src/query/query-login/query-login-browser.ts deleted file mode 100644 index 2d131cb..0000000 --- a/assistant/src/query/query-login/query-login-browser.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { QueryLogin, QueryLoginOpts } from './query-login.ts'; -import { MyCache } from '@kevisual/cache'; -type QueryLoginNodeOptsWithoutCache = Omit; - -export class QueryLoginBrowser extends QueryLogin { - constructor(opts: QueryLoginNodeOptsWithoutCache) { - super({ - ...opts, - cache: new MyCache('login'), - }); - } -} diff --git a/assistant/src/query/query-login/query-login-node.ts b/assistant/src/query/query-login/query-login-node.ts deleted file mode 100644 index 5cb6527..0000000 --- a/assistant/src/query/query-login/query-login-node.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { QueryLogin, QueryLoginOpts } from './query-login.ts'; -import { LoginNodeCache, StorageNode } from './login-node-cache.ts'; -type QueryLoginNodeOptsWithoutCache = Omit; -export const storage = new StorageNode(); -await storage.loadCache(); -export class QueryLoginNode extends QueryLogin { - constructor(opts: QueryLoginNodeOptsWithoutCache) { - super({ - ...opts, - storage, - cache: new LoginNodeCache(), - }); - } -} diff --git a/assistant/src/query/query-login/query-login.ts b/assistant/src/query/query-login/query-login.ts deleted file mode 100644 index ce9769b..0000000 --- a/assistant/src/query/query-login/query-login.ts +++ /dev/null @@ -1,434 +0,0 @@ -import { Query, BaseQuery } from '@kevisual/query'; -import type { Result, DataOpts } from '@kevisual/query/query'; -import { setBaseResponse } from '@kevisual/query/query'; -import { LoginCacheStore, CacheStore } from './login-cache.ts'; -import { Cache } from './login-cache.ts'; - -export type QueryLoginOpts = { - query?: Query; - isBrowser?: boolean; - onLoad?: () => void; - storage?: Storage; - cache: Cache; -}; -export type QueryLoginData = { - username?: string; - password: string; - email?: string; -}; -export type QueryLoginResult = { - accessToken: string; - refreshToken: string; -}; - -export class QueryLogin extends BaseQuery { - /** - * query login cache, 非实际操作, 一个cache的包裹模块 - */ - cacheStore: CacheStore; - isBrowser: boolean; - load?: boolean; - storage: Storage; - onLoad?: () => void; - - constructor(opts?: QueryLoginOpts) { - super({ - query: opts?.query || new Query(), - }); - this.cacheStore = new LoginCacheStore({ name: 'login', cache: opts?.cache! }); - this.isBrowser = opts?.isBrowser ?? true; - this.init(); - this.onLoad = opts?.onLoad; - this.storage = opts?.storage || localStorage; - } - setQuery(query: Query) { - this.query = query; - } - private async init() { - await this.cacheStore.init(); - this.load = true; - this.onLoad?.(); - } - async post(data: any, opts?: DataOpts) { - try { - return this.query.post({ path: 'user', ...data }, opts); - } catch (error) { - console.log('error', error); - return { - code: 400, - } as any; - } - } - /** - * 登录, - * @param data - * @returns - */ - async login(data: QueryLoginData) { - const res = await this.post({ key: 'login', ...data }); - if (res.code === 200) { - const { accessToken, refreshToken } = res?.data || {}; - this.storage.setItem('token', accessToken || ''); - await this.beforeSetLoginUser({ accessToken, refreshToken }); - } - return res; - } - /** - * 手机号登录 - * @param data - * @returns - */ - async loginByCode(data: { phone: string; code: string }) { - const res = await this.post({ path: 'sms', key: 'login', data }); - if (res.code === 200) { - const { accessToken, refreshToken } = res?.data || {}; - this.storage.setItem('token', accessToken || ''); - await this.beforeSetLoginUser({ accessToken, refreshToken }); - } - return res; - } - /** - * 设置token - * @param token - */ - async setLoginToken(token: { accessToken: string; refreshToken: string }) { - const { accessToken, refreshToken } = token; - this.storage.setItem('token', accessToken || ''); - await this.beforeSetLoginUser({ accessToken, refreshToken }); - } - async loginByWechat(data: { code: string }) { - const res = await this.post({ path: 'wx', key: 'open-login', code: data.code }); - if (res.code === 200) { - const { accessToken, refreshToken } = res?.data || {}; - this.storage.setItem('token', accessToken || ''); - await this.beforeSetLoginUser({ accessToken, refreshToken }); - } - return res; - } - /** - * 检测微信登录,登陆成功后,调用onSuccess,否则调用onError - * @param param0 - */ - async checkWechat({ onSuccess, onError }: { onSuccess?: (res: QueryLoginResult) => void; onError?: (res: any) => void }) { - const url = new URL(window.location.href); - const code = url.searchParams.get('code'); - const state = url.searchParams.get('state'); - if (code && state) { - const res = await this.loginByWechat({ code }); - if (res.code === 200) { - onSuccess?.(res.data); - } else { - onError?.(res); - } - } - } - /** - * 登陆成功,需要获取用户信息进行缓存 - * @param param0 - */ - async beforeSetLoginUser({ accessToken, refreshToken, check401 }: { accessToken?: string; refreshToken?: string; check401?: boolean }) { - if (accessToken && refreshToken) { - const resUser = await this.getMe(accessToken, check401); - if (resUser.code === 200) { - const user = resUser.data; - if (user) { - this.cacheStore.setLoginUser({ - user, - id: user.id, - accessToken, - refreshToken, - }); - } else { - console.error('登录失败'); - } - } - } - } - /** - * 刷新token - * @param refreshToken - * @returns - */ - async queryRefreshToken(refreshToken?: string) { - const _refreshToken = refreshToken || this.cacheStore.getRefreshToken(); - let data = { refreshToken: _refreshToken }; - if (!_refreshToken) { - await this.cacheStore.clearCurrentUser(); - return { - code: 401, - message: '请先登录', - data: {} as any, - }; - } - return this.post( - { key: 'refreshToken', data }, - { - afterResponse: async (response, ctx) => { - setBaseResponse(response); - return response as any; - }, - }, - ); - } - /** - * 检查401错误,并刷新token, 如果refreshToken存在,则刷新token, 否则返回401 - * 拦截请求,请使用run401Action, 不要直接使用 afterCheck401ToRefreshToken - * @param response - * @param ctx - * @param refetch - * @returns - */ - async afterCheck401ToRefreshToken(response: Result, ctx?: { req?: any; res?: any; fetch?: any }, refetch?: boolean) { - const that = this; - if (response?.code === 401) { - const hasRefreshToken = await that.cacheStore.getRefreshToken(); - if (hasRefreshToken) { - const res = await that.queryRefreshToken(hasRefreshToken); - if (res.code === 200) { - const { accessToken, refreshToken } = res?.data || {}; - that.storage.setItem('token', accessToken || ''); - await that.beforeSetLoginUser({ accessToken, refreshToken, check401: false }); - if (refetch && ctx && ctx.req && ctx.req.url && ctx.fetch) { - await new Promise((resolve) => setTimeout(resolve, 1500)); - const url = ctx.req?.url; - const body = ctx.req?.body; - const headers = ctx.req?.headers; - const res = await ctx.fetch(url, { - method: 'POST', - body: body, - headers: { ...headers, Authorization: `Bearer ${accessToken}` }, - }); - setBaseResponse(res); - return res; - } - } else { - that.storage.removeItem('token'); - await that.cacheStore.clearCurrentUser(); - } - return res; - } - } - return response as any; - } - /** - * 一个简单的401处理, 如果401,则刷新token, 如果refreshToken不存在,则返回401 - * refetch 是否重新请求, 会有bug,无限循环,按需要使用 - * TODO: - * @param response - * @param ctx - * @param opts - * @returns - */ - async run401Action( - response: Result, - ctx?: { req?: any; res?: any; fetch?: any }, - opts?: { - /** - * 是否重新请求, 会有bug,无限循环,按需要使用 - */ - refetch?: boolean; - /** - * check之后的回调 - */ - afterCheck?: (res: Result) => any; - /** - * 401处理后, 还是401, 则回调 - */ - afterAlso401?: (res: Result) => any; - }, - ) { - const that = this; - const refetch = opts?.refetch ?? false; - if (response?.code === 401) { - if (that.query.stop === true) { - return { code: 500, success: false, message: 'refresh token loading...' }; - } - that.query.stop = true; - const res = await that.afterCheck401ToRefreshToken(response, ctx, refetch); - that.query.stop = false; - opts?.afterCheck?.(res); - if (res.code === 401) { - opts?.afterAlso401?.(res); - } - return res; - } else { - return response as any; - } - } - /** - * 获取用户信息 - * @param token - * @returns - */ - async getMe(token?: string, check401: boolean = true) { - const _token = token || this.storage.getItem('token'); - const that = this; - return that.post( - { key: 'me' }, - { - beforeRequest: async (config) => { - if (config.headers) { - config.headers['Authorization'] = `Bearer ${_token}`; - } - if (!_token) { - return false; - } - return config; - }, - afterResponse: async (response, ctx) => { - if (response?.code === 401 && check401 && !token) { - return await that.afterCheck401ToRefreshToken(response, ctx); - } - return response as any; - }, - }, - ); - } - /** - * 检查本地用户,如果本地用户存在,则返回本地用户,否则返回null - * @returns - */ - async checkLocalUser() { - const user = await this.cacheStore.getCurrentUser(); - if (user) { - return user; - } - return null; - } - /** - * 检查本地token是否存在,简单的判断是否已经属于登陆状态 - * @returns - */ - async checkLocalToken() { - const token = this.storage.getItem('token'); - return !!token; - } - /** - * 检查本地用户列表 - * @returns - */ - async getToken() { - const token = this.storage.getItem('token'); - return token || ''; - } - async beforeRequest(opts: any = {}) { - const token = this.storage.getItem('token'); - if (token) { - opts.headers = { ...opts.headers, Authorization: `Bearer ${token}` }; - } - return opts; - } - /** - * 请求更新,切换用户, 使用switchUser - * @param username - * @returns - */ - private async postSwitchUser(username: string) { - return this.post({ key: 'switchCheck', data: { username } }); - } - /** - * 切换用户 - * @param username - * @returns - */ - async switchUser(username: string) { - const localUserList = await this.cacheStore.getCurrentUserList(); - const user = localUserList.find((userItem) => userItem.user!.username === username); - if (user) { - this.storage.setItem('token', user.accessToken || ''); - await this.beforeSetLoginUser({ accessToken: user.accessToken, refreshToken: user.refreshToken }); - return { - code: 200, - data: { - accessToken: user.accessToken, - refreshToken: user.refreshToken, - }, - success: true, - message: '切换用户成功', - }; - } - const res = await this.postSwitchUser(username); - - if (res.code === 200) { - const { accessToken, refreshToken } = res?.data || {}; - this.storage.setItem('token', accessToken || ''); - await this.beforeSetLoginUser({ accessToken, refreshToken }); - } - return res; - } - /** - * 退出登陆,去掉token, 并删除缓存 - * @returns - */ - async logout() { - this.storage.removeItem('token'); - const users = await this.cacheStore.getCurrentUserList(); - const tokens = users - .map((user) => { - return user?.accessToken; - }) - .filter(Boolean); - this.cacheStore.delValue(); - return this.post({ key: 'logout', data: { tokens } }); - } - /** - * 检查用户名的组,这个用户是否存在 - * @param username - * @returns - */ - async hasUser(username: string) { - const that = this; - return this.post( - { - path: 'org', - key: 'hasUser', - data: { - username, - }, - }, - { - afterResponse: async (response, ctx) => { - if (response?.code === 401) { - const res = await that.afterCheck401ToRefreshToken(response, ctx, true); - return res; - } - return response as any; - }, - }, - ); - } - /** - * 检查登录状态 - * @param token - * @returns - */ - async checkLoginStatus(token: string) { - const res = await this.post({ - path: 'user', - key: 'checkLoginStatus', - loginToken: token, - }); - if (res.code === 200) { - const accessToken = res.data?.accessToken; - this.storage.setItem('token', accessToken || ''); - await this.beforeSetLoginUser({ accessToken, refreshToken: res.data?.refreshToken }); - return res; - } - return false; - } - /** - * 使用web登录,创建url地址, 需要MD5和jsonwebtoken - */ - loginWithWeb(baseURL: string, { MD5, jsonwebtoken }: { MD5: any; jsonwebtoken: any }) { - const randomId = Math.random().toString(36).substring(2, 15); - const timestamp = Date.now(); - const tokenSecret = 'xiao' + randomId; - const sign = MD5(`${tokenSecret}${timestamp}`).toString(); - const token = jsonwebtoken.sign({ randomId, timestamp, sign }, tokenSecret, { - // 10分钟过期 - expiresIn: 60 * 10, // 10分钟 - }); - const url = `${baseURL}/api/router?path=user&key=webLogin&p&loginToken=${token}&sign=${sign}&randomId=${randomId}`; - return { url, token, tokenSecret }; - } -} diff --git a/assistant/src/server.ts b/assistant/src/server.ts index 060705d..1e5b18a 100644 --- a/assistant/src/server.ts +++ b/assistant/src/server.ts @@ -30,20 +30,14 @@ export const runServer = async (port: number = 51515, listenPath = '127.0.0.1') } _port = isPortAvailable; } - const hasSocket = listenPath.includes('.sock'); - if (hasSocket) { - app.listen(listenPath, () => { - console.log(`Server is running on ${listenPath}`); - }); - } else { - app.listen(_port, listenPath, () => { - let showListenPath = listenPath; - if (listenPath === '::') { - showListenPath = 'localhost'; - } - console.log(`Server is running on ${'http'}://${showListenPath}:${_port}`); - }); - } + + app.listen(_port, listenPath, () => { + let showListenPath = listenPath; + if (listenPath === '::') { + showListenPath = 'localhost'; + } + console.log(`Server is running on ${'http'}://${showListenPath}:${_port}`); + }); app.server.on([{ id: 'handle-all', func: proxyRoute as any, diff --git a/assistant/src/services/init/common.ts b/assistant/src/services/init/common.ts new file mode 100644 index 0000000..5c0e780 --- /dev/null +++ b/assistant/src/services/init/common.ts @@ -0,0 +1,38 @@ +export const configJson = `{ + "name": "assistant-app", + "version": "1.0.1", + "description": "assistant-app package pnpm, node pkgs projects", + "type": "module", + "scripts": { + "start": "pm2 start apps/code-center/dist/app.mjs --name code-center", + "proxy": "pm2 start apps/page-proxy/dist/app.mjs --name page-proxy", + "preview": "pnpm i && ASSISTANT_CONFIG_DIR=/workspace/kevisual asst server -s" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@aws-sdk/client-s3": "^3.990.0", + "@kevisual/oss": "^0.0.19", + "@kevisual/query": "^0.0.40", + "eventemitter3": "^5.0.4", + "@kevisual/router": "^0.0.70", + "@kevisual/use-config": "^1.0.30", + "ioredis": "^5.9.3", + "pg": "^8.18.0", + "pm2": "^6.0.14", + "crypto-js": "^4.2.0", + "unstorage": "^1.17.4", + "dayjs": "^1.11.19", + "es-toolkit": "^1.44.0", + "node-cron": "^4.2.1", + "dotenv": "^17.3.1" + }, + "devDependencies": { + "@kevisual/types": "^0.0.12", + "@types/bun": "^1.3.9", + "@types/crypto-js": "^4.2.2", + "@types/node": "^25.2.3" + } +} +` \ No newline at end of file diff --git a/assistant/src/services/init/index.ts b/assistant/src/services/init/index.ts index 8d410c1..4ffc3dd 100644 --- a/assistant/src/services/init/index.ts +++ b/assistant/src/services/init/index.ts @@ -3,7 +3,7 @@ import path from 'node:path'; import { checkFileExists, AssistantConfig, AssistantConfigData, parseHomeArg, parseHelpArg } from '@/module/assistant/index.ts'; import { chalk } from '@/module/chalk.ts'; import { Query } from '@kevisual/query/query'; -import { installDeps } from '@/module/npm-install.ts' +import { checkNpmConfg } from './update-pkgs.ts'; export { parseHomeArg, parseHelpArg }; export type AssistantInitOptions = { path?: string; @@ -118,56 +118,7 @@ export class AssistantInit extends AssistantConfig { console.log(chalk.green('助手 pnpm-workspace.yaml 文件创建成功')); } const packagePath = path.join(this.configDir, 'assistant-app', 'package.json'); - if (!checkFileExists(packagePath, true)) { - create = true; - fs.writeFileSync( - packagePath, - `{ - "name": "assistant-app", - "version": "1.0.1", - "description": "assistant-app package pnpm, node pkgs projects", - "type": "module", - "scripts": { - "start": "pm2 start apps/code-center/dist/app.mjs --name code-center", - "proxy": "pm2 start apps/page-proxy/dist/app.mjs --name page-proxy", - "preview": "pnpm i && ASSISTANT_CONFIG_DIR=/workspace/kevisual asst server -s" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "@aws-sdk/client-s3": "^3.990.0", - "@kevisual/oss": "^0.0.19", - "@kevisual/query": "^0.0.40", - "eventemitter3": "^5.0.4", - "@kevisual/router": "^0.0.70", - "@kevisual/use-config": "^1.0.30", - "ioredis": "^5.9.3", - "pg": "^8.18.0", - "pm2": "^6.0.14", - "crypto-js": "^4.2.0", - "unstorage": "^1.17.4", - "dayjs": "^1.11.19", - "es-toolkit": "^1.44.0", - "node-cron": "^4.2.1", - "dotenv": "^17.3.1" - }, - "devDependencies": { - "@kevisual/types": "^0.0.12", - "@types/bun": "^1.3.9", - "@types/crypto-js": "^4.2.2", - "@types/node": "^25.2.3" - } -} -`, - ); - console.log(chalk.green('助手 package.json 文件创建成功, 正在安装依赖...')); - installDeps({ appPath: path.dirname(packagePath), isProduction: true }).then(() => { - console.log('------------------------------------------------'); - console.log(chalk.green('助手依赖安装完成')); - console.log('------------------------------------------------'); - }); - } + checkNpmConfg(packagePath); return { create, }; @@ -205,21 +156,4 @@ export class AssistantInit extends AssistantConfig { console.log(chalk.green('.gitignore 文件更新成功')); } } - protected getDefaultInitAssistantConfig() { - const id = randomId(); - return { - app: { - url: 'https://kevisual.cn', - id, - }, - description: '助手配置文件', - docs: "https://kevisual.cn/root/cli/docs/", - home: '/root/home', - proxy: [], - share: { - enabled: false, - url: 'https://kevisual.cn/ws/proxy', - }, - } as AssistantConfigData; - } } diff --git a/assistant/src/services/init/package.json b/assistant/src/services/init/package.json index 9c9be36..2f64a4c 100644 --- a/assistant/src/services/init/package.json +++ b/assistant/src/services/init/package.json @@ -1,6 +1,6 @@ { "name": "assistant-app", - "version": "1.0.1", + "version": "1.0.3", "description": "assistant-app package pnpm, node pkgs projects", "type": "module", "scripts": { @@ -12,26 +12,25 @@ "author": "", "license": "ISC", "dependencies": { - "@aws-sdk/client-s3": "^3.990.0", + "@aws-sdk/client-s3": "^3.994.0", "@kevisual/oss": "^0.0.19", - "@kevisual/query": "^0.0.40", - "eventemitter3": "^5.0.4", - "@kevisual/router": "^0.0.70", + "@kevisual/query": "^0.0.49", + "@kevisual/router": "^0.0.83", "@kevisual/use-config": "^1.0.30", + "dayjs": "^1.11.19", + "dotenv": "^17.3.1", + "es-toolkit": "^1.44.0", + "eventemitter3": "^5.0.4", "ioredis": "^5.9.3", + "node-cron": "^4.2.1", "pg": "^8.18.0", "pm2": "^6.0.14", - "crypto-js": "^4.2.0", - "unstorage": "^1.17.4", - "dayjs": "^1.11.19", - "es-toolkit": "^1.44.0", - "node-cron": "^4.2.1", - "dotenv": "^17.3.1" + "unstorage": "^1.17.4" }, "devDependencies": { "@kevisual/types": "^0.0.12", "@types/bun": "^1.3.9", - "@types/crypto-js": "^4.2.2", - "@types/node": "^25.2.3" + "@types/node": "^25.3.0", + "semver": "^7.7.4" } } \ No newline at end of file diff --git a/assistant/src/services/init/update-pkgs.ts b/assistant/src/services/init/update-pkgs.ts new file mode 100644 index 0000000..3320f08 --- /dev/null +++ b/assistant/src/services/init/update-pkgs.ts @@ -0,0 +1,111 @@ +import { configJson } from './common.ts'; +import { checkFileExists } from '@/module/assistant/index.ts'; +import { chalk } from '@/module/chalk.ts'; +import { installDeps } from '@/module/npm-install.ts' +import fs from 'node:fs'; +import path from 'node:path'; +import { execSync } from 'node:child_process'; +import semver from 'semver'; + +export const checkNpmConfg = (packagePath: string) => { + let create = false; + if (!checkFileExists(packagePath, true)) { + create = true; + fs.writeFileSync(packagePath, configJson); + console.log(chalk.green('助手 package.json 文件创建成功, 正在安装依赖...')); + installDeps({ appPath: path.dirname(packagePath), isProduction: true }).then(() => { + console.log('------------------------------------------------'); + console.log(chalk.green('助手依赖安装完成')); + console.log('------------------------------------------------'); + }); + } else { + checkNpmFileConfig(packagePath); + } + + return { + create, + } +} + +const checkNpmFileConfig = async (packagePath: string) => { + const existingConfig = JSON.parse(fs.readFileSync(packagePath, 'utf-8')); + const defaultConfig = JSON.parse(configJson); + const appPath = path.dirname(packagePath); + let needUpdate = false; + if (defaultConfig.version !== existingConfig.version) { + existingConfig.version = defaultConfig.version; + existingConfig.scripts = { + ...existingConfig.scripts, + ...defaultConfig.scripts, + }; + needUpdate = true; + fs.writeFileSync(packagePath, JSON.stringify(existingConfig, null, 2)); + console.log(chalk.yellow('助手 package.json 文件版本不匹配,正在更新...')); + } + // 收集需要更新的依赖列表 + const depsToUpdate: string[] = []; + const devDepsToUpdate: string[] = []; + // 收集需要添加的依赖(不存在的) + const depsToAdd: string[] = []; + const devDepsToAdd: string[] = []; + + // 检查 dependencies - 不存在或版本小于 defaultConfig + for (const dep in defaultConfig.dependencies) { + const defaultVersion = defaultConfig.dependencies[dep].replace(/^[~^]/, ''); + const existingVersion = existingConfig.dependencies?.[dep]?.replace(/^[~^]/, ''); + // console.log(chalk.blue(`检查 dependency: ${dep}, defaultVersion: ${defaultVersion}, existingVersion: ${existingVersion}`)); + if (!existingVersion) { + // 依赖不存在,先添加到 package.json + existingConfig.dependencies = existingConfig.dependencies || {}; + existingConfig.dependencies[dep] = defaultConfig.dependencies[dep]; + depsToAdd.push(dep); + } else if (semver.lt(existingVersion, defaultVersion)) { + depsToUpdate.push(dep); + } + } + + // 检查 devDependencies - 不存在或版本小于 defaultConfig + for (const devDep in defaultConfig.devDependencies) { + const defaultVersion = defaultConfig.devDependencies[devDep].replace(/^[~^]/, ''); + const existingVersion = existingConfig.devDependencies?.[devDep]?.replace(/^[~^]/, ''); + // console.log(chalk.blue(`检查 devDependency: ${devDep}, defaultVersion: ${defaultVersion}, existingVersion: ${existingVersion}`)); + if (!existingVersion) { + // 依赖不存在,先添加到 package.json + existingConfig.devDependencies = existingConfig.devDependencies || {}; + existingConfig.devDependencies[devDep] = defaultConfig.devDependencies[devDep]; + devDepsToAdd.push(devDep); + } else if (semver.lt(existingVersion, defaultVersion)) { + devDepsToUpdate.push(devDep); + } + } + + // 如果有新增的依赖,先写入 package.json + if (depsToAdd.length > 0 || devDepsToAdd.length > 0) { + fs.writeFileSync(packagePath, JSON.stringify(existingConfig, null, 2)); + console.log(chalk.yellow(`新增的 dependencies: ${depsToAdd.join(', ') || '无'}`)); + console.log(chalk.yellow(`新增的 devDependencies: ${devDepsToAdd.join(', ') || '无'}`)); + } + + if (depsToUpdate.length > 0 || devDepsToUpdate.length > 0 || needUpdate) { + console.log(chalk.yellow(`需要更新的 dependencies: ${depsToUpdate.join(', ') || '无'}`)); + console.log(chalk.yellow(`需要更新的 devDependencies: ${devDepsToUpdate.join(', ') || '无'}`)); + console.log(chalk.green('正在执行 ncu -u 更新依赖版本...')); + + // 执行 ncu -u 更新 package.json + try { + execSync('ncu -u', { cwd: appPath, stdio: 'inherit' }); + console.log(chalk.green('ncu -u 执行完成')); + } catch (error) { + console.error(chalk.red('ncu -u 执行失败:', error)); + } + + console.log(chalk.green('正在安装依赖...')); + installDeps({ appPath, isProduction: true }).then(() => { + console.log('------------------------------------------------'); + console.log(chalk.green('助手依赖安装完成')); + console.log('------------------------------------------------'); + }); + } else { + console.log(chalk.green('助手 package.json 文件已存在且依赖完整,无需更新')); + } +} \ No newline at end of file diff --git a/package.json b/package.json index 68d7649..4268029 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "@kevisual/auth": "^2.0.3", "@kevisual/context": "^0.0.8", "@kevisual/use-config": "^1.0.30", - "@opencode-ai/sdk": "^1.2.6", + "@opencode-ai/sdk": "^1.2.10", "@types/busboy": "^1.5.4", "busboy": "^1.6.0", "eventemitter3": "^5.0.4", @@ -59,8 +59,8 @@ "unstorage": "^1.17.4" }, "devDependencies": { - "@kevisual/api": "^0.0.52", - "@kevisual/cnb": "^0.0.26", + "@kevisual/api": "^0.0.55", + "@kevisual/cnb": "^0.0.28", "@kevisual/dts": "^0.0.4", "@kevisual/load": "^0.0.6", "@kevisual/logger": "^0.0.4", @@ -69,7 +69,7 @@ "@types/crypto-js": "^4.2.2", "@types/jsonwebtoken": "^9.0.10", "@types/micromatch": "^4.0.10", - "@types/node": "^25.2.3", + "@types/node": "^25.3.0", "@types/semver": "^7.7.1", "chalk": "^5.6.2", "commander": "^14.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d5f1dd9..f9ddbac 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,7 +10,7 @@ importers: dependencies: '@inquirer/prompts': specifier: ^8.2.1 - version: 8.2.1(@types/node@25.2.3) + version: 8.2.1(@types/node@25.3.0) '@kevisual/app': specifier: ^0.0.2 version: 0.0.2(dotenv@17.3.1) @@ -24,8 +24,8 @@ importers: specifier: ^1.0.30 version: 1.0.30(dotenv@17.3.1) '@opencode-ai/sdk': - specifier: ^1.2.6 - version: 1.2.6 + specifier: ^1.2.10 + version: 1.2.10 '@types/busboy': specifier: ^1.5.4 version: 1.5.4 @@ -55,14 +55,14 @@ importers: version: 7.7.4 unstorage: specifier: ^1.17.4 - version: 1.17.4(idb-keyval@6.2.2) + version: 1.17.4(idb-keyval@6.2.2)(ioredis@5.9.3(supports-color@10.2.2)) devDependencies: '@kevisual/api': - specifier: ^0.0.52 - version: 0.0.52(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: ^0.0.55 + version: 0.0.55(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@kevisual/cnb': - specifier: ^0.0.26 - version: 0.0.26(dotenv@17.3.1)(idb-keyval@6.2.2) + specifier: ^0.0.28 + version: 0.0.28(dotenv@17.3.1)(idb-keyval@6.2.2)(ioredis@5.9.3) '@kevisual/dts': specifier: ^0.0.4 version: 0.0.4(typescript@5.8.2) @@ -88,8 +88,8 @@ importers: specifier: ^4.0.10 version: 4.0.10 '@types/node': - specifier: ^25.2.3 - version: 25.2.3 + specifier: ^25.3.0 + version: 25.3.0 '@types/semver': specifier: ^7.7.1 version: 7.7.1 @@ -127,8 +127,8 @@ importers: assistant: dependencies: '@aws-sdk/client-s3': - specifier: ^3.992.0 - version: 3.992.0 + specifier: ^3.994.0 + version: 3.994.0 '@kevisual/js-filter': specifier: ^0.0.5 version: 0.0.5 @@ -139,8 +139,8 @@ importers: specifier: ^0.0.13 version: 0.0.13(dotenv@17.3.1)(supports-color@10.2.2) '@opencode-ai/sdk': - specifier: ^1.2.6 - version: 1.2.6 + specifier: ^1.2.10 + version: 1.2.10 es-toolkit: specifier: ^1.44.0 version: 1.44.0 @@ -158,20 +158,20 @@ importers: version: 6.0.14(supports-color@10.2.2) unstorage: specifier: ^1.17.4 - version: 1.17.4(idb-keyval@6.2.2) + version: 1.17.4(idb-keyval@6.2.2)(ioredis@5.9.3(supports-color@10.2.2)) zod: specifier: ^4.3.6 version: 4.3.6 devDependencies: '@inquirer/prompts': specifier: ^8.2.1 - version: 8.2.1(@types/node@25.2.3) + version: 8.2.1(@types/node@25.3.0) '@kevisual/ai': specifier: ^0.0.24 version: 0.0.24 '@kevisual/api': - specifier: ^0.0.52 - version: 0.0.52(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: ^0.0.55 + version: 0.0.55(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@kevisual/load': specifier: ^0.0.6 version: 0.0.6 @@ -185,8 +185,8 @@ importers: specifier: 0.0.49 version: 0.0.49 '@kevisual/router': - specifier: ^0.0.80 - version: 0.0.80 + specifier: ^0.0.83 + version: 0.0.83 '@kevisual/types': specifier: ^0.0.12 version: 0.0.12 @@ -194,14 +194,14 @@ importers: specifier: ^1.0.30 version: 1.0.30(dotenv@17.3.1) '@opencode-ai/plugin': - specifier: ^1.2.6 - version: 1.2.6 + specifier: ^1.2.10 + version: 1.2.10 '@types/bun': specifier: ^1.3.9 version: 1.3.9 '@types/node': - specifier: ^25.2.3 - version: 25.2.3 + specifier: ^25.3.0 + version: 25.3.0 '@types/send': specifier: ^1.2.1 version: 1.2.1 @@ -246,16 +246,16 @@ importers: dependencies: '@astrojs/mdx': specifier: ^4.3.13 - version: 4.3.13(astro@5.16.15(@types/node@25.2.3)(idb-keyval@6.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.57.1)(typescript@5.8.2)) + version: 4.3.13(astro@5.16.15(@types/node@25.3.0)(idb-keyval@6.2.2)(ioredis@5.9.3)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.57.1)(typescript@5.8.2)) '@astrojs/react': specifier: ^4.4.2 - version: 4.4.2(@types/node@25.2.3)(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(jiti@2.6.1)(lightningcss@1.30.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 4.4.2(@types/node@25.3.0)(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(jiti@2.6.1)(lightningcss@1.30.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@astrojs/sitemap': specifier: ^3.7.0 version: 3.7.0 '@astrojs/vue': specifier: ^5.1.4 - version: 5.1.4(@types/node@25.2.3)(astro@5.16.15(@types/node@25.2.3)(idb-keyval@6.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.57.1)(typescript@5.8.2))(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.57.1)(vue@3.5.27(typescript@5.8.2)) + version: 5.1.4(@types/node@25.3.0)(astro@5.16.15(@types/node@25.3.0)(idb-keyval@6.2.2)(ioredis@5.9.3)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.57.1)(typescript@5.8.2))(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.57.1)(vue@3.5.27(typescript@5.8.2)) '@kevisual/api': specifier: ^0.0.28 version: 0.0.28 @@ -276,7 +276,7 @@ importers: version: 1.2.4(@types/react@19.2.10)(react@19.2.4) '@tailwindcss/vite': specifier: ^4.1.18 - version: 4.1.18(vite@6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2)) + version: 4.1.18(vite@6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2)) '@uiw/react-md-editor': specifier: ^4.0.11 version: 4.0.11(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -285,7 +285,7 @@ importers: version: 6.2.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) astro: specifier: ^5.16.15 - version: 5.16.15(@types/node@25.2.3)(idb-keyval@6.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.57.1)(typescript@5.8.2) + version: 5.16.15(@types/node@25.3.0)(idb-keyval@6.2.2)(ioredis@5.9.3)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.57.1)(typescript@5.8.2) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -459,52 +459,52 @@ packages: '@aws-crypto/util@5.2.0': resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} - '@aws-sdk/client-s3@3.992.0': - resolution: {integrity: sha512-6xfXGCvnWGgy5zZAse64Ru2G2qLKnPY7h8tchlsmGWVcJOWgz7iM3jmsWsQiJ79zH9A8HAPHU+ZD8TYYkwC+0Q==} + '@aws-sdk/client-s3@3.994.0': + resolution: {integrity: sha512-zIVQt/XfE2zTFrcPEf8R+KRaRD1++XHMPRhxXM2kVA6NA6Aq/cFCUyYOYYwSbWLF/XeToaX1auYGn3IoZKruPQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/client-sso@3.990.0': - resolution: {integrity: sha512-xTEaPjZwOqVjGbLOP7qzwbdOWJOo1ne2mUhTZwEBBkPvNk4aXB/vcYwWwrjoSWUqtit4+GDbO75ePc/S6TUJYQ==} + '@aws-sdk/client-sso@3.993.0': + resolution: {integrity: sha512-VLUN+wIeNX24fg12SCbzTUBnBENlL014yMKZvRhPkcn4wHR6LKgNrjsG3fZ03Xs0XoKaGtNFi1VVrq666sGBoQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/core@3.973.10': - resolution: {integrity: sha512-4u/FbyyT3JqzfsESI70iFg6e2yp87MB5kS2qcxIA66m52VSTN1fvuvbCY1h/LKq1LvuxIrlJ1ItcyjvcKoaPLg==} + '@aws-sdk/core@3.973.11': + resolution: {integrity: sha512-wdQ8vrvHkKIV7yNUKXyjPWKCdYEUrZTHJ8Ojd5uJxXp9vqPCkUR1dpi1NtOLcrDgueJH7MUH5lQZxshjFPSbDA==} engines: {node: '>=20.0.0'} '@aws-sdk/crc64-nvme@3.972.0': resolution: {integrity: sha512-ThlLhTqX68jvoIVv+pryOdb5coP1cX1/MaTbB9xkGDCbWbsqQcLqzPxuSoW1DCnAAIacmXCWpzUNOB9pv+xXQw==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-env@3.972.8': - resolution: {integrity: sha512-r91OOPAcHnLCSxaeu/lzZAVRCZ/CtTNuwmJkUwpwSDshUrP7bkX1OmFn2nUMWd9kN53Q4cEo8b7226G4olt2Mg==} + '@aws-sdk/credential-provider-env@3.972.9': + resolution: {integrity: sha512-ZptrOwQynfupubvcngLkbdIq/aXvl/czdpEG8XJ8mN8Nb19BR0jaK0bR+tfuMU36Ez9q4xv7GGkHFqEEP2hUUQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-http@3.972.10': - resolution: {integrity: sha512-DTtuyXSWB+KetzLcWaSahLJCtTUe/3SXtlGp4ik9PCe9xD6swHEkG8n8/BNsQ9dsihb9nhFvuUB4DpdBGDcvVg==} + '@aws-sdk/credential-provider-http@3.972.11': + resolution: {integrity: sha512-hECWoOoH386bGr89NQc9vA/abkGf5TJrMREt+lhNcnSNmoBS04fK7vc3LrJBSQAUGGVj0Tz3f4dHB3w5veovig==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-ini@3.972.8': - resolution: {integrity: sha512-n2dMn21gvbBIEh00E8Nb+j01U/9rSqFIamWRdGm/mE5e+vHQ9g0cBNdrYFlM6AAiryKVHZmShWT9D1JAWJ3ISw==} + '@aws-sdk/credential-provider-ini@3.972.9': + resolution: {integrity: sha512-zr1csEu9n4eDiHMTYJabX1mDGuGLgjgUnNckIivvk43DocJC9/f6DefFrnUPZXE+GHtbW50YuXb+JIxKykU74A==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-login@3.972.8': - resolution: {integrity: sha512-rMFuVids8ICge/X9DF5pRdGMIvkVhDV9IQFQ8aTYk6iF0rl9jOUa1C3kjepxiXUlpgJQT++sLZkT9n0TMLHhQw==} + '@aws-sdk/credential-provider-login@3.972.9': + resolution: {integrity: sha512-m4RIpVgZChv0vWS/HKChg1xLgZPpx8Z+ly9Fv7FwA8SOfuC6I3htcSaBz2Ch4bneRIiBUhwP4ziUo0UZgtJStQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-node@3.972.9': - resolution: {integrity: sha512-LfJfO0ClRAq2WsSnA9JuUsNyIicD2eyputxSlSL0EiMrtxOxELLRG6ZVYDf/a1HCepaYPXeakH4y8D5OLCauag==} + '@aws-sdk/credential-provider-node@3.972.10': + resolution: {integrity: sha512-70nCESlvnzjo4LjJ8By8MYIiBogkYPSXl3WmMZfH9RZcB/Nt9qVWbFpYj6Fk1vLa4Vk8qagFVeXgxdieMxG1QA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-process@3.972.8': - resolution: {integrity: sha512-6cg26ffFltxM51OOS8NH7oE41EccaYiNlbd5VgUYwhiGCySLfHoGuGrLm2rMB4zhy+IO5nWIIG0HiodX8zdvHA==} + '@aws-sdk/credential-provider-process@3.972.9': + resolution: {integrity: sha512-gOWl0Fe2gETj5Bk151+LYKpeGi2lBDLNu+NMNpHRlIrKHdBmVun8/AalwMK8ci4uRfG5a3/+zvZBMpuen1SZ0A==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-sso@3.972.8': - resolution: {integrity: sha512-35kqmFOVU1n26SNv+U37sM8b2TzG8LyqAcd6iM9gprqxyHEh/8IM3gzN4Jzufs3qM6IrH8e43ryZWYdvfVzzKQ==} + '@aws-sdk/credential-provider-sso@3.972.9': + resolution: {integrity: sha512-ey7S686foGTArvFhi3ifQXmgptKYvLSGE2250BAQceMSXZddz7sUSNERGJT2S7u5KIe/kgugxrt01hntXVln6w==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-web-identity@3.972.8': - resolution: {integrity: sha512-CZhN1bOc1J3ubQPqbmr5b4KaMJBgdDvYsmEIZuX++wFlzmZsKj1bwkaiTEb5U2V7kXuzLlpF5HJSOM9eY/6nGA==} + '@aws-sdk/credential-provider-web-identity@3.972.9': + resolution: {integrity: sha512-8LnfS76nHXoEc9aRRiMMpxZxJeDG0yusdyo3NvPhCgESmBUgpMa4luhGbClW5NoX/qRcGxxM6Z/esqANSNMTow==} engines: {node: '>=20.0.0'} '@aws-sdk/middleware-bucket-endpoint@3.972.3': @@ -515,8 +515,8 @@ packages: resolution: {integrity: sha512-4msC33RZsXQpUKR5QR4HnvBSNCPLGHmB55oDiROqqgyOc+TOfVu2xgi5goA7ms6MdZLeEh2905UfWMnMMF4mRg==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-flexible-checksums@3.972.8': - resolution: {integrity: sha512-Hn6gumcN/3/8Fzo9z7N1pA2PRfE8S+qAqdb4g3MqzXjIOIe+VxD7edO/DKAJ1YH11639EGQIHBz0wdOb5btjtw==} + '@aws-sdk/middleware-flexible-checksums@3.972.9': + resolution: {integrity: sha512-E663+r/UQpvF3aJkD40p5ZANVQFsUcbE39jifMtN7wc0t1M0+2gJJp3i75R49aY9OiSX5lfVyPUNjN/BNRCCZA==} engines: {node: '>=20.0.0'} '@aws-sdk/middleware-host-header@3.972.3': @@ -535,32 +535,32 @@ packages: resolution: {integrity: sha512-PY57QhzNuXHnwbJgbWYTrqIDHYSeOlhfYERTAuc16LKZpTZRJUjzBFokp9hF7u1fuGeE3D70ERXzdbMBOqQz7Q==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-sdk-s3@3.972.10': - resolution: {integrity: sha512-wLkB4bshbBtsAiC2WwlHzOWXu1fx3ftL63fQl0DxEda48Q6B8bcHydZppE3KjEIpPyiNOllByfSnb07cYpIgmw==} + '@aws-sdk/middleware-sdk-s3@3.972.11': + resolution: {integrity: sha512-Qr0T7ZQTRMOuR6ahxEoJR1thPVovfWrKB2a6KBGR+a8/ELrFodrgHwhq50n+5VMaGuLtGhHiISU3XGsZmtmVXQ==} engines: {node: '>=20.0.0'} '@aws-sdk/middleware-ssec@3.972.3': resolution: {integrity: sha512-dU6kDuULN3o3jEHcjm0c4zWJlY1zWVkjG9NPe9qxYLLpcbdj5kRYBS2DdWYD+1B9f910DezRuws7xDEqKkHQIg==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-user-agent@3.972.10': - resolution: {integrity: sha512-bBEL8CAqPQkI91ZM5a9xnFAzedpzH6NYCOtNyLarRAzTUTFN2DKqaC60ugBa7pnU1jSi4mA7WAXBsrod7nJltg==} + '@aws-sdk/middleware-user-agent@3.972.11': + resolution: {integrity: sha512-R8CvPsPHXwzIHCAza+bllY6PrctEk4lYq/SkHJz9NLoBHCcKQrbOcsfXxO6xmipSbUNIbNIUhH0lBsJGgsRdiw==} engines: {node: '>=20.0.0'} - '@aws-sdk/nested-clients@3.990.0': - resolution: {integrity: sha512-3NA0s66vsy8g7hPh36ZsUgO4SiMyrhwcYvuuNK1PezO52vX3hXDW4pQrC6OQLGKGJV0o6tbEyQtXb/mPs8zg8w==} + '@aws-sdk/nested-clients@3.993.0': + resolution: {integrity: sha512-iOq86f2H67924kQUIPOAvlmMaOAvOLoDOIb66I2YqSUpMYB6ufiuJW3RlREgskxv86S5qKzMnfy/X6CqMjK6XQ==} engines: {node: '>=20.0.0'} '@aws-sdk/region-config-resolver@3.972.3': resolution: {integrity: sha512-v4J8qYAWfOMcZ4MJUyatntOicTzEMaU7j3OpkRCGGFSL2NgXQ5VbxauIyORA+pxdKZ0qQG2tCQjQjZDlXEC3Ow==} engines: {node: '>=20.0.0'} - '@aws-sdk/signature-v4-multi-region@3.992.0': - resolution: {integrity: sha512-jWoaM89xH2cYOY6O+PWMa0yqjzKlE61Ehea1hJe34kHg9QvZOkcSA5OT9CNaFXsAvafeAAHBhSE8XlDiNaJFuw==} + '@aws-sdk/signature-v4-multi-region@3.994.0': + resolution: {integrity: sha512-8y04Lv497KKd7f2TVlm2RaKQaNfnY17ZH8d3m+7sW/3R3BhZvHgWQZyqTb/vcN2ERz1YAnWx6woJyB3ZNFvakw==} engines: {node: '>=20.0.0'} - '@aws-sdk/token-providers@3.990.0': - resolution: {integrity: sha512-L3BtUb2v9XmYgQdfGBzbBtKMXaP5fV973y3Qdxeevs6oUTVXFmi/mV1+LnScA/1wVPJC9/hlK+1o5vbt7cG7EQ==} + '@aws-sdk/token-providers@3.993.0': + resolution: {integrity: sha512-+35g4c+8r7sB9Sjp1KPdM8qxGn6B/shBjJtEUN4e+Edw9UEQlZKIzioOGu3UAbyE0a/s450LdLZr4wbJChtmww==} engines: {node: '>=20.0.0'} '@aws-sdk/types@3.973.1': @@ -571,12 +571,12 @@ packages: resolution: {integrity: sha512-VkykWbqMjlSgBFDyrY3nOSqupMc6ivXuGmvci6Q3NnLq5kC+mKQe2QBZ4nrWRE/jqOxeFP2uYzLtwncYYcvQDg==} engines: {node: '>=20.0.0'} - '@aws-sdk/util-endpoints@3.990.0': - resolution: {integrity: sha512-kVwtDc9LNI3tQZHEMNbkLIOpeDK8sRSTuT8eMnzGY+O+JImPisfSTjdh+jw9OTznu+MYZjQsv0258sazVKunYg==} + '@aws-sdk/util-endpoints@3.993.0': + resolution: {integrity: sha512-j6vioBeRZ4eHX4SWGvGPpwGg/xSOcK7f1GL0VM+rdf3ZFTIsUEhCFmD78B+5r2PgztcECSzEfvHQX01k8dPQPw==} engines: {node: '>=20.0.0'} - '@aws-sdk/util-endpoints@3.992.0': - resolution: {integrity: sha512-FHgdMVbTZ2Lu7hEIoGYfkd5UazNSsAgPcupEnh15vsWKFKhuw6w/6tM1k/yNaa7l1wx0Wt1UuK0m+gQ0BJpuvg==} + '@aws-sdk/util-endpoints@3.994.0': + resolution: {integrity: sha512-L2obUBw4ACMMd1F/SG5LdfPyZ0xJNs9Maifwr3w0uWO+4YvHmk9FfRskfSfE/SLZ9S387oSZ+1xiP7BfVCP/Og==} engines: {node: '>=20.0.0'} '@aws-sdk/util-locate-window@3.965.2': @@ -586,8 +586,8 @@ packages: '@aws-sdk/util-user-agent-browser@3.972.3': resolution: {integrity: sha512-JurOwkRUcXD/5MTDBcqdyQ9eVedtAsZgw5rBwktsPTN7QtPiS2Ld1jkJepNgYoCufz1Wcut9iup7GJDoIHp8Fw==} - '@aws-sdk/util-user-agent-node@3.972.8': - resolution: {integrity: sha512-XJZuT0LWsFCW1C8dEpPAXSa7h6Pb3krr2y//1X0Zidpcl0vmgY5nL/X0JuBZlntpBzaN3+U4hvKjuijyiiR8zw==} + '@aws-sdk/util-user-agent-node@3.972.9': + resolution: {integrity: sha512-JNswdsLdQemxqaSIBL2HRhsHPUBBziAgoi5RQv6/9avmE5g5RSdt1hWr3mHJ7OxqRYf+KeB11ExWbiqfrnoeaA==} engines: {node: '>=20.0.0'} peerDependencies: aws-crt: '>=1.0.0' @@ -595,8 +595,8 @@ packages: aws-crt: optional: true - '@aws-sdk/xml-builder@3.972.4': - resolution: {integrity: sha512-0zJ05ANfYqI6+rGqj8samZBFod0dPPousBjLEqg8WdxSgbMAkRgLyn81lP215Do0rFJ/17LIXwr7q0yK24mP6Q==} + '@aws-sdk/xml-builder@3.972.5': + resolution: {integrity: sha512-mCae5Ys6Qm1LDu0qdGwx2UQ63ONUe+FHw908fJzLDqFKTDBK4LDZUqKWm4OkTCNFq19bftjsBSESIGLD/s3/rA==} engines: {node: '>=20.0.0'} '@aws/lambda-invoke-store@0.2.3': @@ -1258,6 +1258,9 @@ packages: '@types/node': optional: true + '@ioredis/commands@1.5.0': + resolution: {integrity: sha512-eUgLqrMf8nJkZxT24JvVRrQya1vZkQh8BBeYNwGDqa5I0VUi8ACx7uFvAaLxintokpTenkK6DASvo/bvNbBGow==} + '@isaacs/fs-minipass@4.0.1': resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} engines: {node: '>=18.0.0'} @@ -1287,8 +1290,8 @@ packages: '@kevisual/api@0.0.28': resolution: {integrity: sha512-WQluRlu2qGM1qktIhPLODie8x382a6jEMfFOcay/rnkCgXK0BRpnqOKwlX7IMLdMqka7GY/BD69kSMnK1Exf5g==} - '@kevisual/api@0.0.52': - resolution: {integrity: sha512-xWajr5lPqBpAwyWseXqE25tNiD/GUZcFdcQJB/oRtObjRa3rog1/U/otV098WZUZVYPGGeAMriKSd3MFdPFcjQ==} + '@kevisual/api@0.0.55': + resolution: {integrity: sha512-ylWpX12tzAULuvxJHhvt7N21SmVOiIV2eVbKSdJ51soo9XO2J7rGNrLcczQ1vPdaSHzCq+9RlAUyd0ogleGJCA==} '@kevisual/app@0.0.1': resolution: {integrity: sha512-PEx8P3l0iNSqrz9Ib9kVCYfqNMX6/LfNu+cEafmY6ECP1cV5Vmv+TH2fuasMosKjtbH2fAdDi97sbd29tdEK+g==} @@ -1299,15 +1302,12 @@ packages: '@kevisual/auth@2.0.3': resolution: {integrity: sha512-4xpijaIhlCTr/DlJaV/gmkCQeg45EO1yxWpRvUX+1jCdVbuxSR0wZrF0SD9oybnjmKWMKDNPLsXyduFjMGcItA==} - '@kevisual/cnb@0.0.26': - resolution: {integrity: sha512-IpyhCkC/Szls1hYfkvvj0kJRY86rdJVPXT95+/QWl7HI9mV6W+kiZE8Q1zJqXjhLQ5d6Szfi1zI+Wh0Re/ao2Q==} + '@kevisual/cnb@0.0.28': + resolution: {integrity: sha512-mv45B68D/lliPBUXEnxbofV+Ds/KSYXuGzzG7S8yEekwp31PwRjecP2dyE0Mxe+DlhFmsSYN09liVUHcCXDbOg==} '@kevisual/context@0.0.4': resolution: {integrity: sha512-HJeLeZQLU+7tCluSfOyvkgKLs0HjCZrdJlZgEgKRSa8XTwZfMAUt6J7qZTbrZAHBlPtX68EPu/PI8JMCeu3WAQ==} - '@kevisual/context@0.0.6': - resolution: {integrity: sha512-w7HBOuO3JH37n6xT6W3FD7ykqHTwtyxOQzTzfEcKDCbsvGB1wVreSxFm2bvoFnnFLuxT/5QMpKlnPrwvmcTGnw==} - '@kevisual/context@0.0.8': resolution: {integrity: sha512-DTJpyHI34NE76B7g6f+QlIqiCCyqI2qkBMQE736dzeRDGxOjnbe2iQY9W+Rt2PE6kmymM3qyOmSfNovyWyWrkA==} @@ -1345,9 +1345,6 @@ packages: '@kevisual/query@0.0.38': resolution: {integrity: sha512-bfvbSodsZyMfwY+1T2SvDeOCKsT/AaIxlVe0+B1R/fNhlg2MDq2CP0L9HKiFkEm+OXrvXcYDMKPUituVUM5J6Q==} - '@kevisual/query@0.0.40': - resolution: {integrity: sha512-7m5BgDzd01m51hCHUId6ugQHdwgrLTb6fI7DSuMY17VjWb0+zGnkYmvRBqkTXzoIjjYbP5iwtRnrooEoToQfhg==} - '@kevisual/query@0.0.49': resolution: {integrity: sha512-GrWW+QlBO5lkiqvb7PjOstNtpTQVSR74EHHWjm7YoL9UdT1wuPQXGUApZHmMBSh3NIWCf0AL2G1hPWZMC7YeOQ==} @@ -1363,12 +1360,12 @@ packages: '@kevisual/router@0.0.51': resolution: {integrity: sha512-i9qYBeS/um78oC912oWJD3iElB+5NTKyTrz1Hzf4DckiUFnjLL81UPwjIh5I2l9+ul0IZ/Pxx+sFSF99fJkzKg==} - '@kevisual/router@0.0.70': - resolution: {integrity: sha512-vXlIj9jRufhcIfeuPWemjSI+dxdzSmIBq5eRxQzqEfAJ7k+mBPhoI4KxH8vHnwyL30bqm8EdODL/p6Wg8uBw3g==} - '@kevisual/router@0.0.80': resolution: {integrity: sha512-rVwi6Yf411bnNm2x94lMm+s4Csw0Yb7u/aj+VJJ59iouAYhjLuL7Rs1EcARhnQf47cegBJi6zozfGHgLsLHN2w==} + '@kevisual/router@0.0.83': + resolution: {integrity: sha512-CVazzM1rXVyvU7QcMQr0/EuqacRNEGalThDDLGQcvKEVHyduJ9yWddn6kezgWFCpNlPKhzSCKkIFuZVixNVxDQ==} + '@kevisual/types@0.0.12': resolution: {integrity: sha512-zJXH2dosir3jVrQ6QG4i0+iLQeT9gJ3H+cKXs8ReWboxBSYzUZO78XssVeVrFPsJ33iaAqo4q3DWbSS1dWGn7Q==} @@ -1441,11 +1438,11 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@opencode-ai/plugin@1.2.6': - resolution: {integrity: sha512-CJEp3k17yWsjyfivm3zQof8L42pdze3a7iTqMOyesHgJplSuLiBYAMndbBYMDuJkyAh0dHYjw8v10vVw7Kfl4Q==} + '@opencode-ai/plugin@1.2.10': + resolution: {integrity: sha512-Z1BMqNHnD8AGAEb+kUz0b2SOuiODwdQLdCA4aVGTXqkGzhiD44OVxr85MeoJ5AMTnnea9SnJ3jp9GAQ5riXA5g==} - '@opencode-ai/sdk@1.2.6': - resolution: {integrity: sha512-dWMF8Aku4h7fh8sw5tQ2FtbqRLbIFT8FcsukpxTird49ax7oUXP+gzqxM/VdxHjfksQvzLBjLZyMdDStc5g7xA==} + '@opencode-ai/sdk@1.2.10': + resolution: {integrity: sha512-SyXcVqry2hitPVvQtvXOhqsWyFhSycG/+LTLYXrcq8AFmd9FR7dyBSDB3f5Ol6IPkYOegk8P2Eg2kKPNSNiKGw==} '@oslojs/encoding@1.1.0': resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} @@ -2150,8 +2147,8 @@ packages: resolution: {integrity: sha512-qJpzYC64kaj3S0fueiu3kXm8xPrR3PcXDPEgnaNMRn0EjNSZFoFjvbUp0YUDsRhN1CB90EnHJtbxWKevnH99UQ==} engines: {node: '>=18.0.0'} - '@smithy/core@3.23.0': - resolution: {integrity: sha512-Yq4UPVoQICM9zHnByLmG8632t2M0+yap4T7ANVw482J0W7HW0pOuxwVmeOwzJqX2Q89fkXz0Vybz55Wj2Xzrsg==} + '@smithy/core@3.23.2': + resolution: {integrity: sha512-HaaH4VbGie4t0+9nY3tNBRSxVTr96wzIqexUa6C2qx3MPePAuz7lIxPxYtt1Wc//SPfJLNoZJzfdt0B6ksj2jA==} engines: {node: '>=18.0.0'} '@smithy/credential-provider-imds@4.2.8': @@ -2214,12 +2211,12 @@ packages: resolution: {integrity: sha512-RO0jeoaYAB1qBRhfVyq0pMgBoUK34YEJxVxyjOWYZiOKOq2yMZ4MnVXMZCUDenpozHue207+9P5ilTV1zeda0A==} engines: {node: '>=18.0.0'} - '@smithy/middleware-endpoint@4.4.14': - resolution: {integrity: sha512-FUFNE5KVeaY6U/GL0nzAAHkaCHzXLZcY1EhtQnsAqhD8Du13oPKtMB9/0WK4/LK6a/T5OZ24wPoSShff5iI6Ag==} + '@smithy/middleware-endpoint@4.4.16': + resolution: {integrity: sha512-L5GICFCSsNhbJ5JSKeWFGFy16Q2OhoBizb3X2DrxaJwXSEujVvjG9Jt386dpQn2t7jINglQl0b4K/Su69BdbMA==} engines: {node: '>=18.0.0'} - '@smithy/middleware-retry@4.4.31': - resolution: {integrity: sha512-RXBzLpMkIrxBPe4C8OmEOHvS8aH9RUuCOH++Acb5jZDEblxDjyg6un72X9IcbrGTJoiUwmI7hLypNfuDACypbg==} + '@smithy/middleware-retry@4.4.33': + resolution: {integrity: sha512-jLqZOdJhtIL4lnA9hXnAG6GgnJlo1sD3FqsTxm9wSfjviqgWesY/TMBVnT84yr4O0Vfe0jWoXlfFbzsBVph3WA==} engines: {node: '>=18.0.0'} '@smithy/middleware-serde@4.2.9': @@ -2266,8 +2263,8 @@ packages: resolution: {integrity: sha512-6A4vdGj7qKNRF16UIcO8HhHjKW27thsxYci+5r/uVRkdcBEkOEiY8OMPuydLX4QHSrJqGHPJzPRwwVTqbLZJhg==} engines: {node: '>=18.0.0'} - '@smithy/smithy-client@4.11.3': - resolution: {integrity: sha512-Q7kY5sDau8OoE6Y9zJoRGgje8P4/UY0WzH8R2ok0PDh+iJ+ZnEKowhjEqYafVcubkbYxQVaqwm3iufktzhprGg==} + '@smithy/smithy-client@4.11.5': + resolution: {integrity: sha512-xixwBRqoeP2IUgcAl3U9dvJXc+qJum4lzo3maaJxifsZxKUYLfVfCXvhT4/jD01sRrHg5zjd1cw2Zmjr4/SuKQ==} engines: {node: '>=18.0.0'} '@smithy/types@4.12.0': @@ -2302,12 +2299,12 @@ packages: resolution: {integrity: sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-browser@4.3.30': - resolution: {integrity: sha512-cMni0uVU27zxOiU8TuC8pQLC1pYeZ/xEMxvchSK/ILwleRd1ugobOcIRr5vXtcRqKd4aBLWlpeBoDPJJ91LQng==} + '@smithy/util-defaults-mode-browser@4.3.32': + resolution: {integrity: sha512-092sjYfFMQ/iaPH798LY/OJFBcYu0sSK34Oy9vdixhsU36zlZu8OcYjF3TD4e2ARupyK7xaxPXl+T0VIJTEkkg==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-node@4.2.33': - resolution: {integrity: sha512-LEb2aq5F4oZUSzWBG7S53d4UytZSkOEJPXcBq/xbG2/TmK9EW5naUZ8lKu1BEyWMzdHIzEVN16M3k8oxDq+DJA==} + '@smithy/util-defaults-mode-node@4.2.35': + resolution: {integrity: sha512-miz/ggz87M8VuM29y7jJZMYkn7+IErM5p5UgKIf8OtqVs/h2bXr1Bt3uTsREsI/4nK8a0PQERbAPsVPVNIsG7Q==} engines: {node: '>=18.0.0'} '@smithy/util-endpoints@3.2.8': @@ -2510,8 +2507,8 @@ packages: '@types/node@17.0.45': resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} - '@types/node@25.2.3': - resolution: {integrity: sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==} + '@types/node@25.3.0': + resolution: {integrity: sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A==} '@types/prismjs@1.26.5': resolution: {integrity: sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==} @@ -2894,6 +2891,10 @@ packages: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} + cluster-key-slot@1.1.2: + resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} + engines: {node: '>=0.10.0'} + codemirror@6.0.2: resolution: {integrity: sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==} @@ -3083,6 +3084,10 @@ packages: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} + denque@2.1.0: + resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} + engines: {node: '>=0.10'} + depd@2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} @@ -3328,8 +3333,8 @@ packages: fast-wrap-ansi@0.2.0: resolution: {integrity: sha512-rLV8JHxTyhVmFYhBJuMujcrHqOT2cnO5Zxj37qROj23CP39GXubJRBUFF0z8KFK77Uc0SukZUf7JZhsVEQ6n8w==} - fast-xml-parser@5.3.4: - resolution: {integrity: sha512-EFd6afGmXlCx8H8WTZHhAoDaWaGyuIBoZJ2mknrNxug+aZKjkp0a0dlars9Izl+jF+7Gu1/5f/2h68cQpe0IiA==} + fast-xml-parser@5.3.6: + resolution: {integrity: sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA==} hasBin: true fastq@1.17.1: @@ -3615,6 +3620,10 @@ packages: inline-style-parser@0.2.7: resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + ioredis@5.9.3: + resolution: {integrity: sha512-VI5tMCdeoxZWU5vjHWsiE/Su76JGhBvWF1MJnV9ZtGltHk9BmD48oDq8Tj8haZ85aceXZMxLNDQZRVo5QKNgXA==} + engines: {node: '>=12.22.0'} + ip-address@9.0.5: resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} engines: {node: '>= 12'} @@ -3836,9 +3845,15 @@ packages: lit-html@3.3.1: resolution: {integrity: sha512-S9hbyDu/vs1qNrithiNyeyv64c9yqiW9l+DBgI18fL+MTvOtWoFR0FWiyq1TxaYef5wNlpEmzlXoBlZEO+WjoA==} + lodash.defaults@4.2.0: + resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} + lodash.includes@4.3.0: resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} + lodash.isarguments@3.1.0: + resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} + lodash.isboolean@3.0.3: resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} @@ -4454,6 +4469,14 @@ packages: recma-stringify@1.0.0: resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + redis-errors@1.2.0: + resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} + engines: {node: '>=4'} + + redis-parser@3.0.0: + resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} + engines: {node: '>=4'} + reflect-metadata@0.2.2: resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} @@ -4732,6 +4755,9 @@ packages: sprintf-js@1.1.3: resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + standard-as-callback@2.1.0: + resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} + statuses@2.0.2: resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} engines: {node: '>= 0.8'} @@ -4908,9 +4934,6 @@ packages: engines: {node: '>=14.17'} hasBin: true - ufo@1.6.1: - resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} - ufo@1.6.3: resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} @@ -4920,8 +4943,8 @@ packages: uncrypto@0.1.3: resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} - undici-types@7.16.0: - resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + undici-types@7.18.2: + resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} unicorn-magic@0.3.0: resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} @@ -5350,12 +5373,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@astrojs/mdx@4.3.13(astro@5.16.15(@types/node@25.2.3)(idb-keyval@6.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.57.1)(typescript@5.8.2))': + '@astrojs/mdx@4.3.13(astro@5.16.15(@types/node@25.3.0)(idb-keyval@6.2.2)(ioredis@5.9.3)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.57.1)(typescript@5.8.2))': dependencies: '@astrojs/markdown-remark': 6.3.10 '@mdx-js/mdx': 3.1.1 acorn: 8.15.0 - astro: 5.16.15(@types/node@25.2.3)(idb-keyval@6.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.57.1)(typescript@5.8.2) + astro: 5.16.15(@types/node@25.3.0)(idb-keyval@6.2.2)(ioredis@5.9.3)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.57.1)(typescript@5.8.2) es-module-lexer: 1.7.0 estree-util-visit: 2.0.0 hast-util-to-html: 9.0.5 @@ -5373,15 +5396,15 @@ snapshots: dependencies: prismjs: 1.30.0 - '@astrojs/react@4.4.2(@types/node@25.2.3)(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(jiti@2.6.1)(lightningcss@1.30.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@astrojs/react@4.4.2(@types/node@25.3.0)(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(jiti@2.6.1)(lightningcss@1.30.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@types/react': 19.2.10 '@types/react-dom': 19.2.3(@types/react@19.2.10) - '@vitejs/plugin-react': 4.7.0(vite@6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2)) + '@vitejs/plugin-react': 4.7.0(vite@6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2)) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) ultrahtml: 1.6.0 - vite: 6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2) transitivePeerDependencies: - '@types/node' - jiti @@ -5414,14 +5437,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@astrojs/vue@5.1.4(@types/node@25.2.3)(astro@5.16.15(@types/node@25.2.3)(idb-keyval@6.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.57.1)(typescript@5.8.2))(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.57.1)(vue@3.5.27(typescript@5.8.2))': + '@astrojs/vue@5.1.4(@types/node@25.3.0)(astro@5.16.15(@types/node@25.3.0)(idb-keyval@6.2.2)(ioredis@5.9.3)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.57.1)(typescript@5.8.2))(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.57.1)(vue@3.5.27(typescript@5.8.2))': dependencies: - '@vitejs/plugin-vue': 5.2.4(vite@6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.27(typescript@5.8.2)) - '@vitejs/plugin-vue-jsx': 4.2.0(vite@6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.27(typescript@5.8.2)) + '@vitejs/plugin-vue': 5.2.4(vite@6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.27(typescript@5.8.2)) + '@vitejs/plugin-vue-jsx': 4.2.0(vite@6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.27(typescript@5.8.2)) '@vue/compiler-sfc': 3.5.27 - astro: 5.16.15(@types/node@25.2.3)(idb-keyval@6.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.57.1)(typescript@5.8.2) - vite: 6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2) - vite-plugin-vue-devtools: 7.7.9(rollup@4.57.1)(vite@6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.27(typescript@5.8.2)) + astro: 5.16.15(@types/node@25.3.0)(idb-keyval@6.2.2)(ioredis@5.9.3)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.57.1)(typescript@5.8.2) + vite: 6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2) + vite-plugin-vue-devtools: 7.7.9(rollup@4.57.1)(vite@6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.27(typescript@5.8.2)) vue: 3.5.27(typescript@5.8.2) transitivePeerDependencies: - '@nuxt/kit' @@ -5486,31 +5509,31 @@ snapshots: '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 - '@aws-sdk/client-s3@3.992.0': + '@aws-sdk/client-s3@3.994.0': dependencies: '@aws-crypto/sha1-browser': 5.2.0 '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.973.10 - '@aws-sdk/credential-provider-node': 3.972.9 + '@aws-sdk/core': 3.973.11 + '@aws-sdk/credential-provider-node': 3.972.10 '@aws-sdk/middleware-bucket-endpoint': 3.972.3 '@aws-sdk/middleware-expect-continue': 3.972.3 - '@aws-sdk/middleware-flexible-checksums': 3.972.8 + '@aws-sdk/middleware-flexible-checksums': 3.972.9 '@aws-sdk/middleware-host-header': 3.972.3 '@aws-sdk/middleware-location-constraint': 3.972.3 '@aws-sdk/middleware-logger': 3.972.3 '@aws-sdk/middleware-recursion-detection': 3.972.3 - '@aws-sdk/middleware-sdk-s3': 3.972.10 + '@aws-sdk/middleware-sdk-s3': 3.972.11 '@aws-sdk/middleware-ssec': 3.972.3 - '@aws-sdk/middleware-user-agent': 3.972.10 + '@aws-sdk/middleware-user-agent': 3.972.11 '@aws-sdk/region-config-resolver': 3.972.3 - '@aws-sdk/signature-v4-multi-region': 3.992.0 + '@aws-sdk/signature-v4-multi-region': 3.994.0 '@aws-sdk/types': 3.973.1 - '@aws-sdk/util-endpoints': 3.992.0 + '@aws-sdk/util-endpoints': 3.994.0 '@aws-sdk/util-user-agent-browser': 3.972.3 - '@aws-sdk/util-user-agent-node': 3.972.8 + '@aws-sdk/util-user-agent-node': 3.972.9 '@smithy/config-resolver': 4.4.6 - '@smithy/core': 3.23.0 + '@smithy/core': 3.23.2 '@smithy/eventstream-serde-browser': 4.2.8 '@smithy/eventstream-serde-config-resolver': 4.3.8 '@smithy/eventstream-serde-node': 4.2.8 @@ -5521,21 +5544,21 @@ snapshots: '@smithy/invalid-dependency': 4.2.8 '@smithy/md5-js': 4.2.8 '@smithy/middleware-content-length': 4.2.8 - '@smithy/middleware-endpoint': 4.4.14 - '@smithy/middleware-retry': 4.4.31 + '@smithy/middleware-endpoint': 4.4.16 + '@smithy/middleware-retry': 4.4.33 '@smithy/middleware-serde': 4.2.9 '@smithy/middleware-stack': 4.2.8 '@smithy/node-config-provider': 4.3.8 '@smithy/node-http-handler': 4.4.10 '@smithy/protocol-http': 5.3.8 - '@smithy/smithy-client': 4.11.3 + '@smithy/smithy-client': 4.11.5 '@smithy/types': 4.12.0 '@smithy/url-parser': 4.2.8 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.30 - '@smithy/util-defaults-mode-node': 4.2.33 + '@smithy/util-defaults-mode-browser': 4.3.32 + '@smithy/util-defaults-mode-node': 4.2.35 '@smithy/util-endpoints': 3.2.8 '@smithy/util-middleware': 4.2.8 '@smithy/util-retry': 4.2.8 @@ -5546,41 +5569,41 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sso@3.990.0': + '@aws-sdk/client-sso@3.993.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.973.10 + '@aws-sdk/core': 3.973.11 '@aws-sdk/middleware-host-header': 3.972.3 '@aws-sdk/middleware-logger': 3.972.3 '@aws-sdk/middleware-recursion-detection': 3.972.3 - '@aws-sdk/middleware-user-agent': 3.972.10 + '@aws-sdk/middleware-user-agent': 3.972.11 '@aws-sdk/region-config-resolver': 3.972.3 '@aws-sdk/types': 3.973.1 - '@aws-sdk/util-endpoints': 3.990.0 + '@aws-sdk/util-endpoints': 3.993.0 '@aws-sdk/util-user-agent-browser': 3.972.3 - '@aws-sdk/util-user-agent-node': 3.972.8 + '@aws-sdk/util-user-agent-node': 3.972.9 '@smithy/config-resolver': 4.4.6 - '@smithy/core': 3.23.0 + '@smithy/core': 3.23.2 '@smithy/fetch-http-handler': 5.3.9 '@smithy/hash-node': 4.2.8 '@smithy/invalid-dependency': 4.2.8 '@smithy/middleware-content-length': 4.2.8 - '@smithy/middleware-endpoint': 4.4.14 - '@smithy/middleware-retry': 4.4.31 + '@smithy/middleware-endpoint': 4.4.16 + '@smithy/middleware-retry': 4.4.33 '@smithy/middleware-serde': 4.2.9 '@smithy/middleware-stack': 4.2.8 '@smithy/node-config-provider': 4.3.8 '@smithy/node-http-handler': 4.4.10 '@smithy/protocol-http': 5.3.8 - '@smithy/smithy-client': 4.11.3 + '@smithy/smithy-client': 4.11.5 '@smithy/types': 4.12.0 '@smithy/url-parser': 4.2.8 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.30 - '@smithy/util-defaults-mode-node': 4.2.33 + '@smithy/util-defaults-mode-browser': 4.3.32 + '@smithy/util-defaults-mode-node': 4.2.35 '@smithy/util-endpoints': 3.2.8 '@smithy/util-middleware': 4.2.8 '@smithy/util-retry': 4.2.8 @@ -5589,16 +5612,16 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/core@3.973.10': + '@aws-sdk/core@3.973.11': dependencies: '@aws-sdk/types': 3.973.1 - '@aws-sdk/xml-builder': 3.972.4 - '@smithy/core': 3.23.0 + '@aws-sdk/xml-builder': 3.972.5 + '@smithy/core': 3.23.2 '@smithy/node-config-provider': 4.3.8 '@smithy/property-provider': 4.2.8 '@smithy/protocol-http': 5.3.8 '@smithy/signature-v4': 5.3.8 - '@smithy/smithy-client': 4.11.3 + '@smithy/smithy-client': 4.11.5 '@smithy/types': 4.12.0 '@smithy/util-base64': 4.3.0 '@smithy/util-middleware': 4.2.8 @@ -5610,37 +5633,37 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 - '@aws-sdk/credential-provider-env@3.972.8': + '@aws-sdk/credential-provider-env@3.972.9': dependencies: - '@aws-sdk/core': 3.973.10 + '@aws-sdk/core': 3.973.11 '@aws-sdk/types': 3.973.1 '@smithy/property-provider': 4.2.8 '@smithy/types': 4.12.0 tslib: 2.8.1 - '@aws-sdk/credential-provider-http@3.972.10': + '@aws-sdk/credential-provider-http@3.972.11': dependencies: - '@aws-sdk/core': 3.973.10 + '@aws-sdk/core': 3.973.11 '@aws-sdk/types': 3.973.1 '@smithy/fetch-http-handler': 5.3.9 '@smithy/node-http-handler': 4.4.10 '@smithy/property-provider': 4.2.8 '@smithy/protocol-http': 5.3.8 - '@smithy/smithy-client': 4.11.3 + '@smithy/smithy-client': 4.11.5 '@smithy/types': 4.12.0 '@smithy/util-stream': 4.5.12 tslib: 2.8.1 - '@aws-sdk/credential-provider-ini@3.972.8': + '@aws-sdk/credential-provider-ini@3.972.9': dependencies: - '@aws-sdk/core': 3.973.10 - '@aws-sdk/credential-provider-env': 3.972.8 - '@aws-sdk/credential-provider-http': 3.972.10 - '@aws-sdk/credential-provider-login': 3.972.8 - '@aws-sdk/credential-provider-process': 3.972.8 - '@aws-sdk/credential-provider-sso': 3.972.8 - '@aws-sdk/credential-provider-web-identity': 3.972.8 - '@aws-sdk/nested-clients': 3.990.0 + '@aws-sdk/core': 3.973.11 + '@aws-sdk/credential-provider-env': 3.972.9 + '@aws-sdk/credential-provider-http': 3.972.11 + '@aws-sdk/credential-provider-login': 3.972.9 + '@aws-sdk/credential-provider-process': 3.972.9 + '@aws-sdk/credential-provider-sso': 3.972.9 + '@aws-sdk/credential-provider-web-identity': 3.972.9 + '@aws-sdk/nested-clients': 3.993.0 '@aws-sdk/types': 3.973.1 '@smithy/credential-provider-imds': 4.2.8 '@smithy/property-provider': 4.2.8 @@ -5650,10 +5673,10 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-login@3.972.8': + '@aws-sdk/credential-provider-login@3.972.9': dependencies: - '@aws-sdk/core': 3.973.10 - '@aws-sdk/nested-clients': 3.990.0 + '@aws-sdk/core': 3.973.11 + '@aws-sdk/nested-clients': 3.993.0 '@aws-sdk/types': 3.973.1 '@smithy/property-provider': 4.2.8 '@smithy/protocol-http': 5.3.8 @@ -5663,14 +5686,14 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-node@3.972.9': + '@aws-sdk/credential-provider-node@3.972.10': dependencies: - '@aws-sdk/credential-provider-env': 3.972.8 - '@aws-sdk/credential-provider-http': 3.972.10 - '@aws-sdk/credential-provider-ini': 3.972.8 - '@aws-sdk/credential-provider-process': 3.972.8 - '@aws-sdk/credential-provider-sso': 3.972.8 - '@aws-sdk/credential-provider-web-identity': 3.972.8 + '@aws-sdk/credential-provider-env': 3.972.9 + '@aws-sdk/credential-provider-http': 3.972.11 + '@aws-sdk/credential-provider-ini': 3.972.9 + '@aws-sdk/credential-provider-process': 3.972.9 + '@aws-sdk/credential-provider-sso': 3.972.9 + '@aws-sdk/credential-provider-web-identity': 3.972.9 '@aws-sdk/types': 3.973.1 '@smithy/credential-provider-imds': 4.2.8 '@smithy/property-provider': 4.2.8 @@ -5680,20 +5703,20 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-process@3.972.8': + '@aws-sdk/credential-provider-process@3.972.9': dependencies: - '@aws-sdk/core': 3.973.10 + '@aws-sdk/core': 3.973.11 '@aws-sdk/types': 3.973.1 '@smithy/property-provider': 4.2.8 '@smithy/shared-ini-file-loader': 4.4.3 '@smithy/types': 4.12.0 tslib: 2.8.1 - '@aws-sdk/credential-provider-sso@3.972.8': + '@aws-sdk/credential-provider-sso@3.972.9': dependencies: - '@aws-sdk/client-sso': 3.990.0 - '@aws-sdk/core': 3.973.10 - '@aws-sdk/token-providers': 3.990.0 + '@aws-sdk/client-sso': 3.993.0 + '@aws-sdk/core': 3.973.11 + '@aws-sdk/token-providers': 3.993.0 '@aws-sdk/types': 3.973.1 '@smithy/property-provider': 4.2.8 '@smithy/shared-ini-file-loader': 4.4.3 @@ -5702,10 +5725,10 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-web-identity@3.972.8': + '@aws-sdk/credential-provider-web-identity@3.972.9': dependencies: - '@aws-sdk/core': 3.973.10 - '@aws-sdk/nested-clients': 3.990.0 + '@aws-sdk/core': 3.973.11 + '@aws-sdk/nested-clients': 3.993.0 '@aws-sdk/types': 3.973.1 '@smithy/property-provider': 4.2.8 '@smithy/shared-ini-file-loader': 4.4.3 @@ -5731,12 +5754,12 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 - '@aws-sdk/middleware-flexible-checksums@3.972.8': + '@aws-sdk/middleware-flexible-checksums@3.972.9': dependencies: '@aws-crypto/crc32': 5.2.0 '@aws-crypto/crc32c': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/core': 3.973.10 + '@aws-sdk/core': 3.973.11 '@aws-sdk/crc64-nvme': 3.972.0 '@aws-sdk/types': 3.973.1 '@smithy/is-array-buffer': 4.2.0 @@ -5775,16 +5798,16 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 - '@aws-sdk/middleware-sdk-s3@3.972.10': + '@aws-sdk/middleware-sdk-s3@3.972.11': dependencies: - '@aws-sdk/core': 3.973.10 + '@aws-sdk/core': 3.973.11 '@aws-sdk/types': 3.973.1 '@aws-sdk/util-arn-parser': 3.972.2 - '@smithy/core': 3.23.0 + '@smithy/core': 3.23.2 '@smithy/node-config-provider': 4.3.8 '@smithy/protocol-http': 5.3.8 '@smithy/signature-v4': 5.3.8 - '@smithy/smithy-client': 4.11.3 + '@smithy/smithy-client': 4.11.5 '@smithy/types': 4.12.0 '@smithy/util-config-provider': 4.2.0 '@smithy/util-middleware': 4.2.8 @@ -5798,51 +5821,51 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 - '@aws-sdk/middleware-user-agent@3.972.10': + '@aws-sdk/middleware-user-agent@3.972.11': dependencies: - '@aws-sdk/core': 3.973.10 + '@aws-sdk/core': 3.973.11 '@aws-sdk/types': 3.973.1 - '@aws-sdk/util-endpoints': 3.990.0 - '@smithy/core': 3.23.0 + '@aws-sdk/util-endpoints': 3.993.0 + '@smithy/core': 3.23.2 '@smithy/protocol-http': 5.3.8 '@smithy/types': 4.12.0 tslib: 2.8.1 - '@aws-sdk/nested-clients@3.990.0': + '@aws-sdk/nested-clients@3.993.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.973.10 + '@aws-sdk/core': 3.973.11 '@aws-sdk/middleware-host-header': 3.972.3 '@aws-sdk/middleware-logger': 3.972.3 '@aws-sdk/middleware-recursion-detection': 3.972.3 - '@aws-sdk/middleware-user-agent': 3.972.10 + '@aws-sdk/middleware-user-agent': 3.972.11 '@aws-sdk/region-config-resolver': 3.972.3 '@aws-sdk/types': 3.973.1 - '@aws-sdk/util-endpoints': 3.990.0 + '@aws-sdk/util-endpoints': 3.993.0 '@aws-sdk/util-user-agent-browser': 3.972.3 - '@aws-sdk/util-user-agent-node': 3.972.8 + '@aws-sdk/util-user-agent-node': 3.972.9 '@smithy/config-resolver': 4.4.6 - '@smithy/core': 3.23.0 + '@smithy/core': 3.23.2 '@smithy/fetch-http-handler': 5.3.9 '@smithy/hash-node': 4.2.8 '@smithy/invalid-dependency': 4.2.8 '@smithy/middleware-content-length': 4.2.8 - '@smithy/middleware-endpoint': 4.4.14 - '@smithy/middleware-retry': 4.4.31 + '@smithy/middleware-endpoint': 4.4.16 + '@smithy/middleware-retry': 4.4.33 '@smithy/middleware-serde': 4.2.9 '@smithy/middleware-stack': 4.2.8 '@smithy/node-config-provider': 4.3.8 '@smithy/node-http-handler': 4.4.10 '@smithy/protocol-http': 5.3.8 - '@smithy/smithy-client': 4.11.3 + '@smithy/smithy-client': 4.11.5 '@smithy/types': 4.12.0 '@smithy/url-parser': 4.2.8 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.30 - '@smithy/util-defaults-mode-node': 4.2.33 + '@smithy/util-defaults-mode-browser': 4.3.32 + '@smithy/util-defaults-mode-node': 4.2.35 '@smithy/util-endpoints': 3.2.8 '@smithy/util-middleware': 4.2.8 '@smithy/util-retry': 4.2.8 @@ -5859,19 +5882,19 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 - '@aws-sdk/signature-v4-multi-region@3.992.0': + '@aws-sdk/signature-v4-multi-region@3.994.0': dependencies: - '@aws-sdk/middleware-sdk-s3': 3.972.10 + '@aws-sdk/middleware-sdk-s3': 3.972.11 '@aws-sdk/types': 3.973.1 '@smithy/protocol-http': 5.3.8 '@smithy/signature-v4': 5.3.8 '@smithy/types': 4.12.0 tslib: 2.8.1 - '@aws-sdk/token-providers@3.990.0': + '@aws-sdk/token-providers@3.993.0': dependencies: - '@aws-sdk/core': 3.973.10 - '@aws-sdk/nested-clients': 3.990.0 + '@aws-sdk/core': 3.973.11 + '@aws-sdk/nested-clients': 3.993.0 '@aws-sdk/types': 3.973.1 '@smithy/property-provider': 4.2.8 '@smithy/shared-ini-file-loader': 4.4.3 @@ -5889,7 +5912,7 @@ snapshots: dependencies: tslib: 2.8.1 - '@aws-sdk/util-endpoints@3.990.0': + '@aws-sdk/util-endpoints@3.993.0': dependencies: '@aws-sdk/types': 3.973.1 '@smithy/types': 4.12.0 @@ -5897,7 +5920,7 @@ snapshots: '@smithy/util-endpoints': 3.2.8 tslib: 2.8.1 - '@aws-sdk/util-endpoints@3.992.0': + '@aws-sdk/util-endpoints@3.994.0': dependencies: '@aws-sdk/types': 3.973.1 '@smithy/types': 4.12.0 @@ -5916,18 +5939,18 @@ snapshots: bowser: 2.13.1 tslib: 2.8.1 - '@aws-sdk/util-user-agent-node@3.972.8': + '@aws-sdk/util-user-agent-node@3.972.9': dependencies: - '@aws-sdk/middleware-user-agent': 3.972.10 + '@aws-sdk/middleware-user-agent': 3.972.11 '@aws-sdk/types': 3.973.1 '@smithy/node-config-provider': 4.3.8 '@smithy/types': 4.12.0 tslib: 2.8.1 - '@aws-sdk/xml-builder@3.972.4': + '@aws-sdk/xml-builder@3.972.5': dependencies: '@smithy/types': 4.12.0 - fast-xml-parser: 5.3.4 + fast-xml-parser: 5.3.6 tslib: 2.8.1 '@aws/lambda-invoke-store@0.2.3': {} @@ -6422,122 +6445,125 @@ snapshots: '@inquirer/ansi@2.0.3': {} - '@inquirer/checkbox@5.0.6(@types/node@25.2.3)': + '@inquirer/checkbox@5.0.6(@types/node@25.3.0)': dependencies: '@inquirer/ansi': 2.0.3 - '@inquirer/core': 11.1.3(@types/node@25.2.3) + '@inquirer/core': 11.1.3(@types/node@25.3.0) '@inquirer/figures': 2.0.3 - '@inquirer/type': 4.0.3(@types/node@25.2.3) + '@inquirer/type': 4.0.3(@types/node@25.3.0) optionalDependencies: - '@types/node': 25.2.3 + '@types/node': 25.3.0 - '@inquirer/confirm@6.0.6(@types/node@25.2.3)': + '@inquirer/confirm@6.0.6(@types/node@25.3.0)': dependencies: - '@inquirer/core': 11.1.3(@types/node@25.2.3) - '@inquirer/type': 4.0.3(@types/node@25.2.3) + '@inquirer/core': 11.1.3(@types/node@25.3.0) + '@inquirer/type': 4.0.3(@types/node@25.3.0) optionalDependencies: - '@types/node': 25.2.3 + '@types/node': 25.3.0 - '@inquirer/core@11.1.3(@types/node@25.2.3)': + '@inquirer/core@11.1.3(@types/node@25.3.0)': dependencies: '@inquirer/ansi': 2.0.3 '@inquirer/figures': 2.0.3 - '@inquirer/type': 4.0.3(@types/node@25.2.3) + '@inquirer/type': 4.0.3(@types/node@25.3.0) cli-width: 4.1.0 fast-wrap-ansi: 0.2.0 mute-stream: 3.0.0 signal-exit: 4.1.0 optionalDependencies: - '@types/node': 25.2.3 + '@types/node': 25.3.0 - '@inquirer/editor@5.0.6(@types/node@25.2.3)': + '@inquirer/editor@5.0.6(@types/node@25.3.0)': dependencies: - '@inquirer/core': 11.1.3(@types/node@25.2.3) - '@inquirer/external-editor': 2.0.3(@types/node@25.2.3) - '@inquirer/type': 4.0.3(@types/node@25.2.3) + '@inquirer/core': 11.1.3(@types/node@25.3.0) + '@inquirer/external-editor': 2.0.3(@types/node@25.3.0) + '@inquirer/type': 4.0.3(@types/node@25.3.0) optionalDependencies: - '@types/node': 25.2.3 + '@types/node': 25.3.0 - '@inquirer/expand@5.0.6(@types/node@25.2.3)': + '@inquirer/expand@5.0.6(@types/node@25.3.0)': dependencies: - '@inquirer/core': 11.1.3(@types/node@25.2.3) - '@inquirer/type': 4.0.3(@types/node@25.2.3) + '@inquirer/core': 11.1.3(@types/node@25.3.0) + '@inquirer/type': 4.0.3(@types/node@25.3.0) optionalDependencies: - '@types/node': 25.2.3 + '@types/node': 25.3.0 - '@inquirer/external-editor@2.0.3(@types/node@25.2.3)': + '@inquirer/external-editor@2.0.3(@types/node@25.3.0)': dependencies: chardet: 2.1.1 iconv-lite: 0.7.2 optionalDependencies: - '@types/node': 25.2.3 + '@types/node': 25.3.0 '@inquirer/figures@2.0.3': {} - '@inquirer/input@5.0.6(@types/node@25.2.3)': + '@inquirer/input@5.0.6(@types/node@25.3.0)': dependencies: - '@inquirer/core': 11.1.3(@types/node@25.2.3) - '@inquirer/type': 4.0.3(@types/node@25.2.3) + '@inquirer/core': 11.1.3(@types/node@25.3.0) + '@inquirer/type': 4.0.3(@types/node@25.3.0) optionalDependencies: - '@types/node': 25.2.3 + '@types/node': 25.3.0 - '@inquirer/number@4.0.6(@types/node@25.2.3)': + '@inquirer/number@4.0.6(@types/node@25.3.0)': dependencies: - '@inquirer/core': 11.1.3(@types/node@25.2.3) - '@inquirer/type': 4.0.3(@types/node@25.2.3) + '@inquirer/core': 11.1.3(@types/node@25.3.0) + '@inquirer/type': 4.0.3(@types/node@25.3.0) optionalDependencies: - '@types/node': 25.2.3 + '@types/node': 25.3.0 - '@inquirer/password@5.0.6(@types/node@25.2.3)': + '@inquirer/password@5.0.6(@types/node@25.3.0)': dependencies: '@inquirer/ansi': 2.0.3 - '@inquirer/core': 11.1.3(@types/node@25.2.3) - '@inquirer/type': 4.0.3(@types/node@25.2.3) + '@inquirer/core': 11.1.3(@types/node@25.3.0) + '@inquirer/type': 4.0.3(@types/node@25.3.0) optionalDependencies: - '@types/node': 25.2.3 + '@types/node': 25.3.0 - '@inquirer/prompts@8.2.1(@types/node@25.2.3)': + '@inquirer/prompts@8.2.1(@types/node@25.3.0)': dependencies: - '@inquirer/checkbox': 5.0.6(@types/node@25.2.3) - '@inquirer/confirm': 6.0.6(@types/node@25.2.3) - '@inquirer/editor': 5.0.6(@types/node@25.2.3) - '@inquirer/expand': 5.0.6(@types/node@25.2.3) - '@inquirer/input': 5.0.6(@types/node@25.2.3) - '@inquirer/number': 4.0.6(@types/node@25.2.3) - '@inquirer/password': 5.0.6(@types/node@25.2.3) - '@inquirer/rawlist': 5.2.2(@types/node@25.2.3) - '@inquirer/search': 4.1.2(@types/node@25.2.3) - '@inquirer/select': 5.0.6(@types/node@25.2.3) + '@inquirer/checkbox': 5.0.6(@types/node@25.3.0) + '@inquirer/confirm': 6.0.6(@types/node@25.3.0) + '@inquirer/editor': 5.0.6(@types/node@25.3.0) + '@inquirer/expand': 5.0.6(@types/node@25.3.0) + '@inquirer/input': 5.0.6(@types/node@25.3.0) + '@inquirer/number': 4.0.6(@types/node@25.3.0) + '@inquirer/password': 5.0.6(@types/node@25.3.0) + '@inquirer/rawlist': 5.2.2(@types/node@25.3.0) + '@inquirer/search': 4.1.2(@types/node@25.3.0) + '@inquirer/select': 5.0.6(@types/node@25.3.0) optionalDependencies: - '@types/node': 25.2.3 + '@types/node': 25.3.0 - '@inquirer/rawlist@5.2.2(@types/node@25.2.3)': + '@inquirer/rawlist@5.2.2(@types/node@25.3.0)': dependencies: - '@inquirer/core': 11.1.3(@types/node@25.2.3) - '@inquirer/type': 4.0.3(@types/node@25.2.3) + '@inquirer/core': 11.1.3(@types/node@25.3.0) + '@inquirer/type': 4.0.3(@types/node@25.3.0) optionalDependencies: - '@types/node': 25.2.3 + '@types/node': 25.3.0 - '@inquirer/search@4.1.2(@types/node@25.2.3)': + '@inquirer/search@4.1.2(@types/node@25.3.0)': dependencies: - '@inquirer/core': 11.1.3(@types/node@25.2.3) + '@inquirer/core': 11.1.3(@types/node@25.3.0) '@inquirer/figures': 2.0.3 - '@inquirer/type': 4.0.3(@types/node@25.2.3) + '@inquirer/type': 4.0.3(@types/node@25.3.0) optionalDependencies: - '@types/node': 25.2.3 + '@types/node': 25.3.0 - '@inquirer/select@5.0.6(@types/node@25.2.3)': + '@inquirer/select@5.0.6(@types/node@25.3.0)': dependencies: '@inquirer/ansi': 2.0.3 - '@inquirer/core': 11.1.3(@types/node@25.2.3) + '@inquirer/core': 11.1.3(@types/node@25.3.0) '@inquirer/figures': 2.0.3 - '@inquirer/type': 4.0.3(@types/node@25.2.3) + '@inquirer/type': 4.0.3(@types/node@25.3.0) optionalDependencies: - '@types/node': 25.2.3 + '@types/node': 25.3.0 - '@inquirer/type@4.0.3(@types/node@25.2.3)': + '@inquirer/type@4.0.3(@types/node@25.3.0)': optionalDependencies: - '@types/node': 25.2.3 + '@types/node': 25.3.0 + + '@ioredis/commands@1.5.0': + optional: true '@isaacs/fs-minipass@4.0.1': dependencies: @@ -6583,9 +6609,9 @@ snapshots: fuse.js: 7.1.0 nanoid: 5.1.6 - '@kevisual/api@0.0.52(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@kevisual/api@0.0.55(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@kevisual/context': 0.0.6 + '@kevisual/context': 0.0.8 '@kevisual/js-filter': 0.0.5 '@kevisual/load': 0.0.6 '@paralleldrive/cuid2': 3.3.0 @@ -6631,14 +6657,14 @@ snapshots: '@kevisual/auth@2.0.3': {} - '@kevisual/cnb@0.0.26(dotenv@17.3.1)(idb-keyval@6.2.2)': + '@kevisual/cnb@0.0.28(dotenv@17.3.1)(idb-keyval@6.2.2)(ioredis@5.9.3)': dependencies: - '@kevisual/query': 0.0.40 - '@kevisual/router': 0.0.70 + '@kevisual/query': 0.0.49 + '@kevisual/router': 0.0.80 '@kevisual/use-config': 1.0.30(dotenv@17.3.1) es-toolkit: 1.44.0 nanoid: 5.1.6 - unstorage: 1.17.4(idb-keyval@6.2.2) + unstorage: 1.17.4(idb-keyval@6.2.2)(ioredis@5.9.3(supports-color@10.2.2)) ws: '@kevisual/ws@8.19.0' zod: 4.3.6 transitivePeerDependencies: @@ -6665,8 +6691,6 @@ snapshots: '@kevisual/context@0.0.4': {} - '@kevisual/context@0.0.6': {} - '@kevisual/context@0.0.8': {} '@kevisual/dts@0.0.4(typescript@5.8.2)': @@ -6737,10 +6761,6 @@ snapshots: dependencies: tslib: 2.8.1 - '@kevisual/query@0.0.40': - dependencies: - tslib: 2.8.1 - '@kevisual/query@0.0.49': {} '@kevisual/registry@0.0.1(typescript@5.8.2)': @@ -6785,11 +6805,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@kevisual/router@0.0.70': + '@kevisual/router@0.0.80': dependencies: es-toolkit: 1.44.0 - '@kevisual/router@0.0.80': + '@kevisual/router@0.0.83': dependencies: es-toolkit: 1.44.0 @@ -6913,12 +6933,12 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 - '@opencode-ai/plugin@1.2.6': + '@opencode-ai/plugin@1.2.10': dependencies: - '@opencode-ai/sdk': 1.2.6 + '@opencode-ai/sdk': 1.2.10 zod: 4.1.8 - '@opencode-ai/sdk@1.2.6': {} + '@opencode-ai/sdk@1.2.10': {} '@oslojs/encoding@1.1.0': {} @@ -7669,7 +7689,7 @@ snapshots: '@smithy/util-middleware': 4.2.8 tslib: 2.8.1 - '@smithy/core@3.23.0': + '@smithy/core@3.23.2': dependencies: '@smithy/middleware-serde': 4.2.9 '@smithy/protocol-http': 5.3.8 @@ -7773,9 +7793,9 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 - '@smithy/middleware-endpoint@4.4.14': + '@smithy/middleware-endpoint@4.4.16': dependencies: - '@smithy/core': 3.23.0 + '@smithy/core': 3.23.2 '@smithy/middleware-serde': 4.2.9 '@smithy/node-config-provider': 4.3.8 '@smithy/shared-ini-file-loader': 4.4.3 @@ -7784,12 +7804,12 @@ snapshots: '@smithy/util-middleware': 4.2.8 tslib: 2.8.1 - '@smithy/middleware-retry@4.4.31': + '@smithy/middleware-retry@4.4.33': dependencies: '@smithy/node-config-provider': 4.3.8 '@smithy/protocol-http': 5.3.8 '@smithy/service-error-classification': 4.2.8 - '@smithy/smithy-client': 4.11.3 + '@smithy/smithy-client': 4.11.5 '@smithy/types': 4.12.0 '@smithy/util-middleware': 4.2.8 '@smithy/util-retry': 4.2.8 @@ -7863,10 +7883,10 @@ snapshots: '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@smithy/smithy-client@4.11.3': + '@smithy/smithy-client@4.11.5': dependencies: - '@smithy/core': 3.23.0 - '@smithy/middleware-endpoint': 4.4.14 + '@smithy/core': 3.23.2 + '@smithy/middleware-endpoint': 4.4.16 '@smithy/middleware-stack': 4.2.8 '@smithy/protocol-http': 5.3.8 '@smithy/types': 4.12.0 @@ -7911,20 +7931,20 @@ snapshots: dependencies: tslib: 2.8.1 - '@smithy/util-defaults-mode-browser@4.3.30': + '@smithy/util-defaults-mode-browser@4.3.32': dependencies: '@smithy/property-provider': 4.2.8 - '@smithy/smithy-client': 4.11.3 + '@smithy/smithy-client': 4.11.5 '@smithy/types': 4.12.0 tslib: 2.8.1 - '@smithy/util-defaults-mode-node@4.2.33': + '@smithy/util-defaults-mode-node@4.2.35': dependencies: '@smithy/config-resolver': 4.4.6 '@smithy/credential-provider-imds': 4.2.8 '@smithy/node-config-provider': 4.3.8 '@smithy/property-provider': 4.2.8 - '@smithy/smithy-client': 4.11.3 + '@smithy/smithy-client': 4.11.5 '@smithy/types': 4.12.0 tslib: 2.8.1 @@ -8045,12 +8065,12 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.1.18 '@tailwindcss/oxide-win32-x64-msvc': 4.1.18 - '@tailwindcss/vite@4.1.18(vite@6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2))': + '@tailwindcss/vite@4.1.18(vite@6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2))': dependencies: '@tailwindcss/node': 4.1.18 '@tailwindcss/oxide': 4.1.18 tailwindcss: 4.1.18 - vite: 6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2) '@tootallnate/quickjs-emscripten@0.23.0': {} @@ -8083,7 +8103,7 @@ snapshots: '@types/busboy@1.5.4': dependencies: - '@types/node': 25.2.3 + '@types/node': 25.3.0 '@types/crypto-js@4.2.2': {} @@ -8110,7 +8130,7 @@ snapshots: '@types/jsonwebtoken@9.0.10': dependencies: '@types/ms': 0.7.34 - '@types/node': 25.2.3 + '@types/node': 25.3.0 '@types/mdast@4.0.4': dependencies: @@ -8130,9 +8150,9 @@ snapshots: '@types/node@17.0.45': {} - '@types/node@25.2.3': + '@types/node@25.3.0': dependencies: - undici-types: 7.16.0 + undici-types: 7.18.2 '@types/prismjs@1.26.5': {} @@ -8148,13 +8168,13 @@ snapshots: '@types/sax@1.2.7': dependencies: - '@types/node': 25.2.3 + '@types/node': 25.3.0 '@types/semver@7.7.1': {} '@types/send@1.2.1': dependencies: - '@types/node': 25.2.3 + '@types/node': 25.3.0 '@types/trusted-types@2.0.7': {} @@ -8164,7 +8184,7 @@ snapshots: '@types/ws@8.18.1': dependencies: - '@types/node': 25.2.3 + '@types/node': 25.3.0 '@uiw/copy-to-clipboard@1.0.19': {} @@ -8203,7 +8223,7 @@ snapshots: '@ungap/structured-clone@1.3.0': {} - '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2))': + '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2))': dependencies: '@babel/core': 7.28.5 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) @@ -8211,24 +8231,24 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue-jsx@4.2.0(vite@6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.27(typescript@5.8.2))': + '@vitejs/plugin-vue-jsx@4.2.0(vite@6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.27(typescript@5.8.2))': dependencies: '@babel/core': 7.28.5 '@babel/plugin-transform-typescript': 7.28.5(@babel/core@7.28.5) '@rolldown/pluginutils': 1.0.0-beta.55 '@vue/babel-plugin-jsx': 1.5.0(@babel/core@7.28.5) - vite: 6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2) vue: 3.5.27(typescript@5.8.2) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@5.2.4(vite@6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.27(typescript@5.8.2))': + '@vitejs/plugin-vue@5.2.4(vite@6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.27(typescript@5.8.2))': dependencies: - vite: 6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2) vue: 3.5.27(typescript@5.8.2) '@vue/babel-helper-vue-transform-on@1.5.0': {} @@ -8290,14 +8310,14 @@ snapshots: '@vue/compiler-dom': 3.5.27 '@vue/shared': 3.5.27 - '@vue/devtools-core@7.7.9(vite@6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.27(typescript@5.8.2))': + '@vue/devtools-core@7.7.9(vite@6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.27(typescript@5.8.2))': dependencies: '@vue/devtools-kit': 7.7.9 '@vue/devtools-shared': 7.7.9 mitt: 3.0.1 nanoid: 5.1.6 pathe: 2.0.3 - vite-hot-client: 2.1.0(vite@6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2)) + vite-hot-client: 2.1.0(vite@6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2)) vue: 3.5.27(typescript@5.8.2) transitivePeerDependencies: - vite @@ -8463,7 +8483,7 @@ snapshots: astring@1.9.0: {} - astro@5.16.15(@types/node@25.2.3)(idb-keyval@6.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.57.1)(typescript@5.8.2): + astro@5.16.15(@types/node@25.3.0)(idb-keyval@6.2.2)(ioredis@5.9.3)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.57.1)(typescript@5.8.2): dependencies: '@astrojs/compiler': 2.13.0 '@astrojs/internal-helpers': 0.7.5 @@ -8518,10 +8538,10 @@ snapshots: ultrahtml: 1.6.0 unifont: 0.7.3 unist-util-visit: 5.0.0 - unstorage: 1.17.4(idb-keyval@6.2.2) + unstorage: 1.17.4(idb-keyval@6.2.2)(ioredis@5.9.3(supports-color@10.2.2)) vfile: 6.0.3 - vite: 6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2) - vitefu: 1.1.1(vite@6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2)) + vite: 6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2) + vitefu: 1.1.1(vite@6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2)) xxhash-wasm: 1.1.0 yargs-parser: 21.1.1 yocto-spinner: 0.2.3 @@ -8626,7 +8646,7 @@ snapshots: bun-types@1.3.9: dependencies: - '@types/node': 25.2.3 + '@types/node': 25.3.0 bundle-name@4.1.0: dependencies: @@ -8702,6 +8722,9 @@ snapshots: clsx@2.1.1: {} + cluster-key-slot@1.1.2: + optional: true + codemirror@6.0.2: dependencies: '@codemirror/autocomplete': 6.20.0 @@ -8864,6 +8887,9 @@ snapshots: delayed-stream@1.0.0: {} + denque@2.1.0: + optional: true + depd@2.0.0: {} dequal@2.0.3: {} @@ -9125,7 +9151,7 @@ snapshots: dependencies: fast-string-width: 3.0.2 - fast-xml-parser@5.3.4: + fast-xml-parser@5.3.6: dependencies: strnum: 2.1.2 @@ -9514,6 +9540,21 @@ snapshots: inline-style-parser@0.2.7: {} + ioredis@5.9.3(supports-color@10.2.2): + dependencies: + '@ioredis/commands': 1.5.0 + cluster-key-slot: 1.1.2 + debug: 4.4.3(supports-color@10.2.2) + denque: 2.1.0 + lodash.defaults: 4.2.0 + lodash.isarguments: 3.1.0 + redis-errors: 1.2.0 + redis-parser: 3.0.0 + standard-as-callback: 2.1.0 + transitivePeerDependencies: + - supports-color + optional: true + ip-address@9.0.5: dependencies: jsbn: 1.1.0 @@ -9697,8 +9738,14 @@ snapshots: dependencies: '@types/trusted-types': 2.0.7 + lodash.defaults@4.2.0: + optional: true + lodash.includes@4.3.0: {} + lodash.isarguments@3.1.0: + optional: true + lodash.isboolean@3.0.3: {} lodash.isinteger@4.0.4: {} @@ -10284,7 +10331,7 @@ snapshots: dependencies: destr: 2.0.5 node-fetch-native: 1.6.7 - ufo: 1.6.1 + ufo: 1.6.3 ohash@2.0.11: {} @@ -10617,6 +10664,14 @@ snapshots: unified: 11.0.5 vfile: 6.0.3 + redis-errors@1.2.0: + optional: true + + redis-parser@3.0.0: + dependencies: + redis-errors: 1.2.0 + optional: true + reflect-metadata@0.2.2: {} refractor@4.9.0: @@ -11060,6 +11115,9 @@ snapshots: sprintf-js@1.1.3: {} + standard-as-callback@2.1.0: + optional: true + statuses@2.0.2: {} steno@4.0.2: {} @@ -11208,15 +11266,13 @@ snapshots: typescript@5.8.2: {} - ufo@1.6.1: {} - ufo@1.6.3: {} ultrahtml@1.6.0: {} uncrypto@0.1.3: {} - undici-types@7.16.0: {} + undici-types@7.18.2: {} unicorn-magic@0.3.0: {} @@ -11290,7 +11346,7 @@ snapshots: universalify@2.0.1: {} - unstorage@1.17.4(idb-keyval@6.2.2): + unstorage@1.17.4(idb-keyval@6.2.2)(ioredis@5.9.3(supports-color@10.2.2)): dependencies: anymatch: 3.1.3 chokidar: 5.0.0 @@ -11302,6 +11358,7 @@ snapshots: ufo: 1.6.3 optionalDependencies: idb-keyval: 6.2.2 + ioredis: 5.9.3(supports-color@10.2.2) update-browserslist-db@1.2.3(browserslist@4.28.1): dependencies: @@ -11324,11 +11381,11 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite-hot-client@2.1.0(vite@6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2)): + vite-hot-client@2.1.0(vite@6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2)): dependencies: - vite: 6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2) - vite-plugin-inspect@0.8.9(rollup@4.57.1)(vite@6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2)): + vite-plugin-inspect@0.8.9(rollup@4.57.1)(vite@6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2)): dependencies: '@antfu/utils': 0.7.10 '@rollup/pluginutils': 5.3.0(rollup@4.57.1) @@ -11339,28 +11396,28 @@ snapshots: perfect-debounce: 1.0.0 picocolors: 1.1.1 sirv: 3.0.2 - vite: 6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2) transitivePeerDependencies: - rollup - supports-color - vite-plugin-vue-devtools@7.7.9(rollup@4.57.1)(vite@6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.27(typescript@5.8.2)): + vite-plugin-vue-devtools@7.7.9(rollup@4.57.1)(vite@6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.27(typescript@5.8.2)): dependencies: - '@vue/devtools-core': 7.7.9(vite@6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.27(typescript@5.8.2)) + '@vue/devtools-core': 7.7.9(vite@6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.27(typescript@5.8.2)) '@vue/devtools-kit': 7.7.9 '@vue/devtools-shared': 7.7.9 execa: 9.6.1 sirv: 3.0.2 - vite: 6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2) - vite-plugin-inspect: 0.8.9(rollup@4.57.1)(vite@6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2)) - vite-plugin-vue-inspector: 5.3.2(vite@6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2)) + vite: 6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2) + vite-plugin-inspect: 0.8.9(rollup@4.57.1)(vite@6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2)) + vite-plugin-vue-inspector: 5.3.2(vite@6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2)) transitivePeerDependencies: - '@nuxt/kit' - rollup - supports-color - vue - vite-plugin-vue-inspector@5.3.2(vite@6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2)): + vite-plugin-vue-inspector@5.3.2(vite@6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2)): dependencies: '@babel/core': 7.28.5 '@babel/plugin-proposal-decorators': 7.28.0(@babel/core@7.28.5) @@ -11371,11 +11428,11 @@ snapshots: '@vue/compiler-dom': 3.5.27 kolorist: 1.8.0 magic-string: 0.30.21 - vite: 6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2) transitivePeerDependencies: - supports-color - vite@6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2): + vite@6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) @@ -11384,14 +11441,14 @@ snapshots: rollup: 4.43.0 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 25.2.3 + '@types/node': 25.3.0 fsevents: 2.3.3 jiti: 2.6.1 lightningcss: 1.30.2 - vitefu@1.1.1(vite@6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2)): + vitefu@1.1.1(vite@6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2)): optionalDependencies: - vite: 6.4.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 6.4.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.30.2) vizion@2.2.1: dependencies: diff --git a/src/module/query.ts b/src/module/query.ts index 763f02c..57f3de9 100644 --- a/src/module/query.ts +++ b/src/module/query.ts @@ -1,9 +1,9 @@ import { Query } from '@kevisual/query/query'; import { getConfig, getEnvToken } from './get-config.ts'; -import { QueryLoginNode, storage } from '@kevisual/api/login-node'; +import { QueryLoginNode, StorageNode } from '@kevisual/api/login-node'; const config = getConfig(); export const baseURL = config?.baseURL || 'https://kevisual.cn'; -export { storage }; +export const storage = new StorageNode({ load: true }); export const getBaseURL = () => { return baseURL; };