From d44938e4560d34a968582e230a8a98f5bd318780 Mon Sep 17 00:00:00 2001 From: xRain Date: Wed, 8 Apr 2026 01:07:10 +0800 Subject: [PATCH] 3.0 --- .github/workflows/publish.yml | 14 +- .gitignore | 24 - .npmignore | 25 - AICONTEXT.md | 138 ++++ README.md | 418 +++++++--- package-lock.json | 1453 ++++++++++++--------------------- package.json | 76 +- src/index.ts | 7 - src/simapi.core.ts | 323 ++++++++ src/simapi.pinia.ts | 91 +++ src/simapi.ts | 207 ----- src/types.ts | 70 ++ tsconfig.build.json | 21 + tsconfig.json | 11 +- vite.config.ts | 22 - vite.core.config.ts | 17 + vite.pinia.config.ts | 23 + 17 files changed, 1574 insertions(+), 1366 deletions(-) delete mode 100644 .gitignore delete mode 100644 .npmignore create mode 100644 AICONTEXT.md delete mode 100644 src/index.ts create mode 100644 src/simapi.core.ts create mode 100644 src/simapi.pinia.ts delete mode 100644 src/simapi.ts create mode 100644 src/types.ts create mode 100644 tsconfig.build.json delete mode 100644 vite.config.ts create mode 100644 vite.core.config.ts create mode 100644 vite.pinia.config.ts diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 2c0cf57..6046eaf 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -20,14 +20,14 @@ jobs: node-version: "24" registry-url: "https://registry.npmjs.org" - - name: Get version from tag - id: version + - name: Replace version placeholder run: | VERSION="${GITHUB_REF#refs/tags/}" - echo "version=$VERSION" >> $GITHUB_OUTPUT - - - name: Update package.json version - run: npm pkg set version=${{ steps.version.outputs.version }} + echo "Publishing version: $VERSION" + # Update package.json + npm pkg set version=$VERSION + # Replace version placeholders in source files + sed -i "s/0.0.0-version-placeholder/$VERSION/g" ./src/types.ts - name: Install dependencies run: npm ci @@ -36,4 +36,4 @@ jobs: run: npm run build - name: Publish to npm - run: npm publish --access public + run: npm publish --access public \ No newline at end of file diff --git a/.gitignore b/.gitignore deleted file mode 100644 index cb34e9c..0000000 --- a/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Dependencies -node_modules/ - -# Build output -dist/ - -# IDE -.vscode/ -.idea/ - -# Logs -*.log -npm-debug.log* - -# OS -.DS_Store -Thumbs.db - -# Test -coverage/ - -# Environment -.env -.env.local diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 09b3b8b..0000000 --- a/.npmignore +++ /dev/null @@ -1,25 +0,0 @@ -# 源码不发布 -src/ - -# 开发文件 -tsconfig.json -vite.config.ts -vue.config.js - -# 测试 -**/*.test.ts -**/*.spec.ts -__tests__/ - -# IDE -.vscode/ -.idea/ - -# Git -.git -.gitignore - -# 其他 -*.log -.DS_Store -node_modules/ diff --git a/AICONTEXT.md b/AICONTEXT.md new file mode 100644 index 0000000..613f18e --- /dev/null +++ b/AICONTEXT.md @@ -0,0 +1,138 @@ +# @simcu/simapi — AI 开发指南 + +> 面向 AI Agent 的代码结构说明,帮助理解、修改和扩展本库。 + +--- + +## 项目结构 + +``` +simapi-vue/ +├── src/ +│ ├── types.ts # 类型定义,全部导出 +│ ├── simapi.core.ts # 核心类 SimApiCore,零框架依赖 +│ └── simapi.pinia.ts # Pinia Store,Vue3 适配层 +├── dist/ # 构建产物 +├── package.json # exports: "/" → core, "/pinia" → vue +├── vite.core.config.ts # 构建 core → dist/index.mjs/cjs +├── vite.pinia.config.ts # 构建 pinia → dist/pinia.mjs +└── tsconfig.build.json # tsc 生成类型声明 +``` + +--- + +## 核心类型(types.ts) + +```typescript +SimApiBaseResponse // 标准响应 { code, message, data? } +SimApiOptions // configure() 入参 { debug?, auth?, api? } +SimApiAuthConfig // auth: { token_name, check_url, logout_url, login_url } +SimApiApiConfig // api: { endpoints, defaultEndpoint, businessCallback, responseCallback, timeout? } +SimApiBusinessCallback // { [code]: (data) => void },支持数字码或 'common' +``` + +--- + +## SimApiCore(simapi.core.ts) + +**职责**:纯 TS HTTP 客户端,基于原生 fetch API,不依赖任何框架。 + +**关键设计**: + +- **零依赖**:使用原生 fetch,无 axios 或其他 HTTP 库 +- **无 Cookie**:所有请求使用 `credentials: 'omit'`,避免 CORS 问题 +- **Token 传递**:通过请求头 `Token` 传递认证信息 +- **超时控制**:通过 `fetchWithTimeout` 辅助函数实现 +- `setEndpoints()` 会自动调用 `fetchVersions()` 查询后端版本(`/versions`),打印到控制台 +- `handleResponse()` 在响应非 200 时触发 `businessCallback`,不抛出异常 +- `query()` 抛出异常的只有网络/HTTP 错误,业务错误码通过回调处理 +- `isLoggedIn` 是 getter,基于 localStorage 中的 token 判断 + +**修改建议**: + +- 改请求方法(GET/PUT/DELETE):在 `fetchPost()` 内新增 `method` 参数分支,或新增 `fetchGet()`/`fetchPut()` 方法 +- 改 Token 存储:替换 `localStorage` 为 `sessionStorage` 或内存变量,修改 `getToken()`/`setToken()`/`removeToken()` +- 改登录/登出逻辑:修改 `login()`/`logout()` 方法 +- 改超时处理:修改 `fetchWithTimeout()` 函数 + +**autoInit 设计约束**: + +- 仅读取 `window.simapi` 的三个顶级字段:`endpoints`、`defaultEndpoint`、`debug` +- 业务回调(`businessCallback`/`responseCallback`)不支持从 window 读取,必须在代码中通过 `setBusinessCallback` 注册 + +--- + +## Pinia Store(simapi.pinia.ts) + +**职责**:Vue3 适配层,SimApiCore 的纯代理,不维护任何独立状态。 + +**关键设计**: + +- **无独立状态**:state 中只有一个 `_core` 实例,不维护 `debug`、`versions`、`token` 等独立数据 +- **单例 Core**:在 store state 中实例化 `SimApiCore`,整个应用共享一个实例 +- **纯代理映射**:所有 getters 直接映射到 `this._core` 的属性,所有 actions 直接调用 `this._core` 的方法 +- **响应式**:通过 Pinia 的响应式系统,当 core 状态变化时自动更新 + +**使用方式**: + +```typescript +// 任意组件 +import { useSimApi } from '@simcu/simapi' + +const api = useSimApi() + +// 初始化(二选一) +// 方式一:从 window.simapi 读取 +api.autoInit() + +// 方式二:直接传入配置 +api.configure({ + api: { endpoints: { default: 'https://api.example.com' } }, +}) + +// 所有方法与 SimApiCore 完全一致 +await api.query('/users/list', { page:1 }) +``` + +--- + +## 构建流程 + +``` +npm run build + → vite build vite.core.config.ts 输出 dist/index.mjs / index.cjs + → vite build vite.pinia.config.ts 输出 dist/pinia.mjs + → tsc -p tsconfig.build.json 输出 *.d.ts 类型声明 +``` + +**dist 输出是平铺的**,core 和 pinia 的编译产物全部在同一目录: + +``` +dist/ +├── index.mjs # core ESM (5.59 KB) +├── index.cjs # core CJS (4.15 KB) +├── pinia.mjs # pinia ESM (6.81 KB) +├── simapi.core.d.ts +├── simapi.pinia.d.ts +└── types.d.ts +``` + +--- + +## package.json exports + +```json +".": { "import": "./dist/index.mjs", "require": "./dist/index.cjs", "types": "./dist/simapi.core.d.ts" } +"./pinia": { "import": "./dist/pinia.mjs", "types": "./dist/simapi.pinia.d.ts" } +``` + +--- + +## 注意事项 + +- Core 默认 `debug: true`,生产环境需手动 `configure({ debug: false })` +- `query()` 返回 `Promise>`,code !== 200 时不 reject,通过 `businessCallback` 处理 +- `login()` 成功后将 `result.data` 存入 localStorage +- **无 Cookie**:所有请求不发送 Cookie,Token 通过请求头传递 +- **零依赖**:不需要安装 axios,使用原生 fetch +- 删除了 Angular 支持,如需恢复参考 git 历史 diff --git a/README.md b/README.md index d85b978..eb013b9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# SimApi - 轻量 API 请求库 +# @simcu/simapi -基于 Axios 的 Vue 3 + Pinia HTTP 客户端库。 +> 轻量级 HTTP 请求库,基于原生 fetch,支持任意 JS/TS 环境及 Vue3。 ## 安装 @@ -8,130 +8,344 @@ npm install @simcu/simapi ``` -## 快速开始 +## 架构 -### 1. 安装依赖 - -```bash -npm install @simcu/simapi pinia +``` +src/ +├── types.ts # 类型定义(SimApiBaseResponse、SimApiOptions 等) +├── simapi.core.ts # 纯 TS 核心,无框架依赖 +└── simapi.pinia.ts # Vue3 Pinia Store 封装 ``` -## 快速开始 +## 核心层(框架无关) -### 1. 初始化配置 - -在 Vue 应用入口(如 `main.ts` 或 `App.vue`)中配置端点和调试模式: +适用于浏览器、Node.js、小程序等任意环境。 ```typescript -import { useSimApi } from 'simapi' +import { SimApiCore } from '@simcu/simapi' -const api = useSimApi() +const api = new SimApiCore() -// 设置 API 端点 -api.setEndpoints({ - default: 'https://api.example.com' +// 从 window.simapi 读取配置(可选) +api.autoInit() + +// 或手动配置 +api.configure({ + api: { endpoints: { default: 'https://api.example.com' } }, + debug: true, }) -// 设置调试模式(默认 true) -api.setDebug(true) -``` +// 发起请求 +const res = await api.query('/users/list', { page: 1 }) +// res.code === 200,res.data 为业务数据 -### 2. 发起请求 - -```typescript -import { useSimApi } from 'simapi' - -const api = useSimApi() - -// 简单请求 -const result = await api.query('/users/list', { page: 1 }) - -// 带 Token 认证的请求 -const result = await api.query('/protected/resource', { id: 123 }) -``` - -### 3. 登录/登出 - -```typescript // 登录 -const result = await api.login({ - phone: '13800138000', - code: '123456' -}) +await api.login({ phone: '13800138000', code: '123456' }) // 登出 await api.logout() + +// 注册业务错误码回调 +api.setBusinessCallback(401, () => router.push('/login')) +api.setBusinessCallback('common', (data) => alert(data.message)) +``` + +## Vue3 + +安装 Pinia: + +```bash +npm install pinia +``` + +```typescript +// main.ts +import { createApp } from 'vue' +import { createPinia } from 'pinia' +import App from './App.vue' + +const app = createApp(App) +app.use(createPinia()) +app.mount('#app') +``` + +```typescript +// 任意组件 +import { useSimApi } from '@simcu/simapi' + +const api = useSimApi() + +// 响应式 +console.log(api.token) // 当前 Token +console.log(api.isLoggedIn) // 是否已登录 + +// 发起请求 +const res = await api.query('/users/list', { page: 1 }) +console.log(res.data) + +// 登录 / 登出 +await api.login({ phone: '13800138000', code: '123456' }) +await api.logout() + +// 调试模式 +api.setDebug(true) +``` + +### 多端点 + +```typescript +api.setEndpoints({ + default: 'https://api.example.com', + admin: 'https://admin.example.com', +}) + +// 指定端点发请求 +await api.query('/stats', {}, 'admin') +``` + +## autoInit — 从 window 读取配置 + +仅支持三个字段:`endpoints`、`defaultEndpoint`、`debug`。业务回调需在代码中通过 `setBusinessCallback` 处理。 + +```html + +``` + +初始化时手动调用: + +```typescript +// 方式一:从 window.simapi 读取 +const api = useSimApi() +api.autoInit() + +// 方式二:直接传入配置 +const api = useSimApi() +api.configure({ + api: { endpoints: { default: 'https://api.example.com' } }, +}) +``` + +## SimApiBaseResponse 响应格式 + +```typescript +interface SimApiBaseResponse { + code: number // 200 = 成功,其他为业务错误码 + message: string // 提示信息 + data?: T // 业务数据 +} +``` + +## 完整配置参考 + +### SimApiOptions — 完整配置结构 + +```typescript +interface SimApiOptions { + /** 调试模式,默认 true */ + debug?: boolean + + /** 认证相关配置 */ + auth?: Partial + + /** API 相关配置 */ + api?: Partial +} +``` + +### SimApiAuthConfig — 认证配置 + +```typescript +interface SimApiAuthConfig { + /** localStorage 中存储 Token 的 key */ + token_name: string // 默认 'simapi-auth-token' + + /** 检查登录状态的接口路径 */ + check_url: string // 默认 '/auth/check' + + /** 登出接口路径 */ + logout_url: string // 默认 '/auth/logout' + + /** 登录接口路径 */ + login_url: string // 默认 '/auth/login' +} +``` + +### SimApiApiConfig — API 配置 + +```typescript +interface SimApiApiConfig { + /** 多端点映射,key 为端点名,value 为 baseURL */ + endpoints: { [name: string]: string } + + /** 默认端点名,默认 'default' */ + defaultEndpoint: string + + /** 业务错误码回调,key 为错误码或 'common' */ + businessCallback: SimApiBusinessCallback + + /** 响应拦截回调 */ + responseCallback: SimApiResponseCallback + + /** 请求超时时间(毫秒),默认 10000 */ + timeout?: number +} +``` + +**⚠️ CORS 说明** + +- 本库使用原生 fetch API,默认不发送 Cookie(`credentials: 'omit'`) +- Token 通过请求头 `Token` 传递,无需依赖 Cookie +- 服务器返回 `Access-Control-Allow-Origin: *` 不会有问题 + +### SimApiBusinessCallback — 业务回调 + +key 支持数字错误码或 `'common'`(通用兜底回调): + +```typescript +type SimApiBusinessCallback = { + [code: number | string]: (data: SimApiBaseResponse) => void +} + +// 示例 +{ + 401: (data) => router.push('/login'), // 未授权 + 403: (data) => ElMessage.error('无权限'), // 无权限 + 500: (data) => console.error(data), // 服务器错误 + 'common': (data) => ElMessage.error(data.message) // 其他错误码兜底 +} +``` + +### SimApiResponseCallback — 响应拦截 + +```typescript +interface SimApiResponseCallback { + /** 成功响应拦截,可在此统一处理数据结构 */ + success: (response: any) => any + + /** 网络/HTTP 错误拦截 */ + error: (err: any) => void +} + +// 示例:统一脱敏处理 +{ + success: (res) => { + // fetch 返回 { code, message, data } + return res + }, + error: (err) => { + console.error('请求失败', err) + throw err + } +} +``` + +### SimApiVersions — 版本信息 + +```typescript +interface SimApiVersions { + uiApp: string // 前端应用版本 + uiSimApi: string // 前端 SimApi 版本 + apiApp: string // 后端应用版本(简化版,如 "1.2.3") + apiSimApi: string // 后端 SimApi 版本(简化版) + apiAppFull: string // 后端应用版本(完整版,如 "1.2.3+20240101") + apiSimApiFull: string // 后端 SimApi 版本(完整版) +} +``` + +### 完整配置示例 + +```typescript +api.configure({ + debug: false, + + auth: { + token_name: 'my-app-token', + check_url: '/api/auth/check', + logout_url: '/api/auth/logout', + login_url: '/api/auth/login', + }, + + api: { + endpoints: { + default: 'https://api.example.com', + admin: 'https://admin.example.com', + }, + defaultEndpoint: 'default', + + businessCallback: { + 401: () => router.push('/login'), + 403: () => ElMessage.error('无权限访问'), + 500: (data) => console.error('服务器错误:', data.message), + 'common': (data) => ElMessage.error(data.message || '请求失败'), + }, + + responseCallback: { + success: (res) => res.data ?? res, + error: (err) => { + console.error('网络错误', err) + }, + }, + }, +}) ``` ## API 参考 -### 配置方法 +### SimApiCore(核心类) -| 方法 | 说明 | -| ------------------------------------- | ---------------------------------------------------------- | -| `setEndpoints(endpoints)` | 设置 API 端点,如 `{ default: 'https://api.example.com' }` | -| `setDebug(debug: boolean)` | 开启/关闭调试模式 | -| `setBusinessCallback(code, callback)` | 设置业务错误码回调 | +| 方法/属性 | 说明 | +|-----------|------| +| `configure(options)` | 批量配置(深合并) | +| `autoInit()` | 从 `window.simapi` 读取配置(endpoints、defaultEndpoint、debug) | +| `setEndpoints(map)` | 设置端点,自动触发版本检查 | +| `setBusinessCallback(code, fn)` | 注册业务错误码回调 | +| `setDebug(debug)` | 设置调试模式 | +| `query(uri, params?, endpointKey?, headers?)` | POST 请求,返回 `Promise>` | +| `login(request)` | 登录,自动存 Token | +| `logout(url?)` | 登出,清除 Token | +| `checkLogin(url?)` | 主动检查登录状态 | +| `getToken()` | 获取 Token | +| `setToken(token)` | 手动设置 Token | +| `removeToken()` | 清除 Token | +| `isLoggedIn` | getter,是否已登录 | +| `token` | getter,获取当前 Token | +| `debug` | boolean,调试模式 | +| `versions` | 版本信息对象 | -### 请求方法 +## 构建 -| 方法 | 说明 | -| ------------------------ | -------------- | -| `api.query(uri, params)` | 发起 POST 请求 | -| `api.login(data)` | 登录 | -| `api.logout()` | 登出 | - -### 工具方法 - -| 方法 | 说明 | -| ------------------------ | -------------- | -| `api.getEndpoint(name?)` | 获取端点地址 | -| `api.getToken()` | 获取当前 Token | - -### Getters - -| 属性 | 说明 | -| ---------------- | -------------------- | -| `api.token` | 当前 Token(响应式) | -| `api.isLoggedIn` | 是否已登录(响应式) | - -## 调试日志 - -启用调试模式后,控制台会输出: - -``` -[REQUEST*] queryId -> /uri AUTH: token -[RESPONSE] queryId -> {data: {...}, code: 200} +```bash +npm install +npm run build +npm link # 本地调试 ``` -设置端点后会自动打印版本信息: +--- -``` -UI主应用版本: 1.0.0 -UISimApi版本: 1.0.0 -API主应用版本: x.x.x -APISimApi版本: x.x.x +## 从旧版迁移 + +如果你之前使用的是带 axios 的版本,迁移非常简单: + +```diff +- import axios from 'axios' ++ import { SimApiCore } from '@simcu/simapi' +- // ... 你的 axios 配置 + ++ const api = new SimApiCore() ++ api.setEndpoints({ default: 'https://api.example.com' }) ++ const res = await api.query('/users/list', { page: 1 }) ``` -## 业务错误处理 - -```typescript -const api = useSimApi() - -// 处理 401 未授权 -api.setBusinessCallback(401, (data) => { - console.log('Token 过期', data) - localStorage.removeItem('token') - router.push('/login') -}) - -// 处理 403 禁止访问 -api.setBusinessCallback(403, (data) => { - ElMessage.error('没有权限') -}) - -// 处理所有非 200 错误 -api.setBusinessCallback('common', (data) => { - ElMessage.error(data.message) -}) -``` +API 完全兼容,无需其他改动。主要变化: +- 使用原生 fetch 替代 axios +- Token 通过请求头 `Token` 传递(不是 `Authorization: Bearer`) +- 默认不发送 Cookie,避免 CORS 问题 diff --git a/package-lock.json b/package-lock.json index a5a63cc..a4ccda9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,32 +1,29 @@ { "name": "@simcu/simapi", - "version": "1.0.1", + "version": "0.0.0-version-placeholder", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@simcu/simapi", - "version": "1.0.1", + "version": "0.0.0-version-placeholder", "license": "MIT", "dependencies": { - "axios": "^1.6.0" + "tslib": "^2.3.0" }, "devDependencies": { "@vitejs/plugin-vue": "^5.0.0", - "typescript": "^5.0.0", + "pinia": "^2.2.0", + "typescript": "~5.9.3", "vite": "^5.0.0", - "vue": "^3.4.0", - "vue-tsc": "^2.0.0" - }, - "peerDependencies": { - "pinia": "^2.0.0", - "vue": "^3.0.0" + "vue": "^3.4.0" } }, "node_modules/@babel/helper-string-parser": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -36,6 +33,7 @@ "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -45,6 +43,7 @@ "version": "7.29.2", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.29.0" @@ -60,6 +59,7 @@ "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -69,401 +69,11 @@ "node": ">=6.9.0" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { @@ -837,69 +447,43 @@ "vue": "^3.2.25" } }, - "node_modules/@volar/language-core": { - "version": "2.4.15", - "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.15.tgz", - "integrity": "sha512-3VHw+QZU0ZG9IuQmzT68IyN4hZNd9GchGPhbD9+pa8CVv7rnoOZwo7T8weIbrRmihqy3ATpdfXFnqRrfPVK6CA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@volar/source-map": "2.4.15" - } - }, - "node_modules/@volar/source-map": { - "version": "2.4.15", - "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.15.tgz", - "integrity": "sha512-CPbMWlUN6hVZJYGcU/GSoHu4EnCHiLaXI9n8c9la6RaI9W5JHX+NqG+GSQcB0JdC2FIBLdZJwGsfKyBB71VlTg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@volar/typescript": { - "version": "2.4.15", - "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.15.tgz", - "integrity": "sha512-2aZ8i0cqPGjXb4BhkMsPYDkkuc2ZQ6yOpqwAuNwUoncELqoy5fRgOQtLR9gB0g902iS0NAkvpIzs27geVyVdPg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@volar/language-core": "2.4.15", - "path-browserify": "^1.0.1", - "vscode-uri": "^3.0.8" - } - }, "node_modules/@vue/compiler-core": { - "version": "3.5.31", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.31.tgz", - "integrity": "sha512-k/ueL14aNIEy5Onf0OVzR8kiqF/WThgLdFhxwa4e/KF/0qe38IwIdofoSWBTvvxQOesaz6riAFAUaYjoF9fLLQ==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.32.tgz", + "integrity": "sha512-4x74Tbtqnda8s/NSD6e1Dr5p1c8HdMU5RWSjMSUzb8RTcUQqevDCxVAitcLBKT+ie3o0Dl9crc/S/opJM7qBGQ==", + "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.29.2", - "@vue/shared": "3.5.31", + "@vue/shared": "3.5.32", "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "node_modules/@vue/compiler-dom": { - "version": "3.5.31", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.31.tgz", - "integrity": "sha512-BMY/ozS/xxjYqRFL+tKdRpATJYDTTgWSo0+AJvJNg4ig+Hgb0dOsHPXvloHQ5hmlivUqw1Yt2pPIqp4e0v1GUw==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.32.tgz", + "integrity": "sha512-ybHAu70NtiEI1fvAUz3oXZqkUYEe5J98GjMDpTGl5iHb0T15wQYLR4wE3h9xfuTNA+Cm2f4czfe8B4s+CCH57Q==", + "dev": true, "license": "MIT", "dependencies": { - "@vue/compiler-core": "3.5.31", - "@vue/shared": "3.5.31" + "@vue/compiler-core": "3.5.32", + "@vue/shared": "3.5.32" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.5.31", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.31.tgz", - "integrity": "sha512-M8wpPgR9UJ8MiRGjppvx9uWJfLV7A/T+/rL8s/y3QG3u0c2/YZgff3d6SuimKRIhcYnWg5fTfDMlz2E6seUW8Q==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.32.tgz", + "integrity": "sha512-8UYUYo71cP/0YHMO814TRZlPuUUw3oifHuMR7Wp9SNoRSrxRQnhMLNlCeaODNn6kNTJsjFoQ/kqIj4qGvya4Xg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.29.2", - "@vue/compiler-core": "3.5.31", - "@vue/compiler-dom": "3.5.31", - "@vue/compiler-ssr": "3.5.31", - "@vue/shared": "3.5.31", + "@vue/compiler-core": "3.5.32", + "@vue/compiler-dom": "3.5.32", + "@vue/compiler-ssr": "3.5.32", + "@vue/shared": "3.5.32", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", "postcss": "^8.5.8", @@ -907,214 +491,90 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.5.31", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.31.tgz", - "integrity": "sha512-h0xIMxrt/LHOvJKMri+vdYT92BrK3HFLtDqq9Pr/lVVfE4IyKZKvWf0vJFW10Yr6nX02OR4MkJwI0c1HDa1hog==", - "license": "MIT", - "dependencies": { - "@vue/compiler-dom": "3.5.31", - "@vue/shared": "3.5.31" - } - }, - "node_modules/@vue/compiler-vue2": { - "version": "2.7.16", - "resolved": "https://registry.npmjs.org/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz", - "integrity": "sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.32.tgz", + "integrity": "sha512-Gp4gTs22T3DgRotZ8aA/6m2jMR+GMztvBXUBEUOYOcST+giyGWJ4WvFd7QLHBkzTxkfOt8IELKNdpzITLbA2rw==", "dev": true, "license": "MIT", "dependencies": { - "de-indent": "^1.0.2", - "he": "^1.2.0" + "@vue/compiler-dom": "3.5.32", + "@vue/shared": "3.5.32" } }, "node_modules/@vue/devtools-api": { "version": "6.6.4", "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", - "license": "MIT", - "peer": true + "dev": true, + "license": "MIT" }, - "node_modules/@vue/language-core": { - "version": "2.2.12", - "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.2.12.tgz", - "integrity": "sha512-IsGljWbKGU1MZpBPN+BvPAdr55YPkj2nB/TBNGNC32Vy2qLG25DYu/NBN2vNtZqdRbTRjaoYrahLrToim2NanA==", + "node_modules/@vue/reactivity": { + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.32.tgz", + "integrity": "sha512-/ORasxSGvZ6MN5gc+uE364SxFdJ0+WqVG0CENXaGW58TOCdrAW76WWaplDtECeS1qphvtBZtR+3/o1g1zL4xPQ==", "dev": true, "license": "MIT", "dependencies": { - "@volar/language-core": "2.4.15", - "@vue/compiler-dom": "^3.5.0", - "@vue/compiler-vue2": "^2.7.16", - "@vue/shared": "^3.5.0", - "alien-signals": "^1.0.3", - "minimatch": "^9.0.3", - "muggle-string": "^0.4.1", - "path-browserify": "^1.0.1" - }, - "peerDependencies": { - "typescript": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@vue/reactivity": { - "version": "3.5.31", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.31.tgz", - "integrity": "sha512-DtKXxk9E/KuVvt8VxWu+6Luc9I9ETNcqR1T1oW1gf02nXaZ1kuAx58oVu7uX9XxJR0iJCro6fqBLw9oSBELo5g==", - "license": "MIT", - "dependencies": { - "@vue/shared": "3.5.31" + "@vue/shared": "3.5.32" } }, "node_modules/@vue/runtime-core": { - "version": "3.5.31", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.31.tgz", - "integrity": "sha512-AZPmIHXEAyhpkmN7aWlqjSfYynmkWlluDNPHMCZKFHH+lLtxP/30UJmoVhXmbDoP1Ng0jG0fyY2zCj1PnSSA6Q==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.32.tgz", + "integrity": "sha512-pDrXCejn4UpFDFmMd27AcJEbHaLemaE5o4pbb7sLk79SRIhc6/t34BQA7SGNgYtbMnvbF/HHOftYBgFJtUoJUQ==", + "dev": true, "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.31", - "@vue/shared": "3.5.31" + "@vue/reactivity": "3.5.32", + "@vue/shared": "3.5.32" } }, "node_modules/@vue/runtime-dom": { - "version": "3.5.31", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.31.tgz", - "integrity": "sha512-xQJsNRmGPeDCJq/u813tyonNgWBFjzfVkBwDREdEWndBnGdHLHgkwNBQxLtg4zDrzKTEcnikUy1UUNecb3lJ6g==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.32.tgz", + "integrity": "sha512-1CDVv7tv/IV13V8Nip1k/aaObVbWqRlVCVezTwx3K07p7Vxossp5JU1dcPNhJk3w347gonIUT9jQOGutyJrSVQ==", + "dev": true, "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.31", - "@vue/runtime-core": "3.5.31", - "@vue/shared": "3.5.31", + "@vue/reactivity": "3.5.32", + "@vue/runtime-core": "3.5.32", + "@vue/shared": "3.5.32", "csstype": "^3.2.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.5.31", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.31.tgz", - "integrity": "sha512-GJuwRvMcdZX/CriUnyIIOGkx3rMV3H6sOu0JhdKbduaeCji6zb60iOGMY7tFoN24NfsUYoFBhshZtGxGpxO4iA==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.32.tgz", + "integrity": "sha512-IOjm2+JQwRFS7W28HNuJeXQle9KdZbODFY7hFGVtnnghF51ta20EWAZJHX+zLGtsHhaU6uC9BGPV52KVpYryMQ==", + "dev": true, "license": "MIT", "dependencies": { - "@vue/compiler-ssr": "3.5.31", - "@vue/shared": "3.5.31" + "@vue/compiler-ssr": "3.5.32", + "@vue/shared": "3.5.32" }, "peerDependencies": { - "vue": "3.5.31" + "vue": "3.5.32" } }, "node_modules/@vue/shared": { - "version": "3.5.31", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.31.tgz", - "integrity": "sha512-nBxuiuS9Lj5bPkPbWogPUnjxxWpkRniX7e5UBQDWl6Fsf4roq9wwV+cR7ezQ4zXswNvPIlsdj1slcLB7XCsRAw==", - "license": "MIT" - }, - "node_modules/alien-signals": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-1.0.13.tgz", - "integrity": "sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.32.tgz", + "integrity": "sha512-ksNyrmRQzWJJ8n3cRDuSF7zNNontuJg1YHnmWRJd2AMu8Ij2bqwiiri2lH5rHtYPZjj4STkNcgcmiQqlOjiYGg==", "dev": true, "license": "MIT" }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" - }, - "node_modules/axios": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.14.0.tgz", - "integrity": "sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.11", - "form-data": "^4.0.5", - "proxy-from-env": "^2.1.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", - "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/csstype": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "license": "MIT" - }, - "node_modules/de-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", "dev": true, "license": "MIT" }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/entities": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -1123,132 +583,13 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, "license": "MIT" }, - "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -1264,179 +605,21 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "license": "MIT", - "bin": { - "he": "bin/he" - } - }, "node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.2" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/muggle-string": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz", - "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", - "dev": true, - "license": "MIT" - }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, "funding": [ { "type": "github", @@ -1451,25 +634,19 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true, - "license": "MIT" - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, "license": "ISC" }, "node_modules/pinia": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.3.1.tgz", "integrity": "sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==", + "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@vue/devtools-api": "^6.6.3", "vue-demi": "^0.14.10" @@ -1491,6 +668,7 @@ "version": "8.5.8", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "dev": true, "funding": [ { "type": "opencollective", @@ -1515,15 +693,6 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/proxy-from-env": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", - "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, "node_modules/rollup": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.1.tgz", @@ -1573,16 +742,23 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -1652,24 +828,448 @@ } } }, - "node_modules/vscode-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz", - "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } }, "node_modules/vue": { - "version": "3.5.31", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.31.tgz", - "integrity": "sha512-iV/sU9SzOlmA/0tygSmjkEN6Jbs3nPoIPFhCMLD2STrjgOU8DX7ZtzMhg4ahVwf5Rp9KoFzcXeB1ZrVbLBp5/Q==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.32.tgz", + "integrity": "sha512-vM4z4Q9tTafVfMAK7IVzmxg34rSzTFMyIe0UUEijUCkn9+23lj0WRfA83dg7eQZIUlgOSGrkViIaCfqSAUXsMw==", + "dev": true, "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.31", - "@vue/compiler-sfc": "3.5.31", - "@vue/runtime-dom": "3.5.31", - "@vue/server-renderer": "3.5.31", - "@vue/shared": "3.5.31" + "@vue/compiler-dom": "3.5.32", + "@vue/compiler-sfc": "3.5.32", + "@vue/runtime-dom": "3.5.32", + "@vue/server-renderer": "3.5.32", + "@vue/shared": "3.5.32" }, "peerDependencies": { "typescript": "*" @@ -1684,9 +1284,9 @@ "version": "0.14.10", "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "dev": true, "hasInstallScript": true, "license": "MIT", - "peer": true, "bin": { "vue-demi-fix": "bin/vue-demi-fix.js", "vue-demi-switch": "bin/vue-demi-switch.js" @@ -1706,23 +1306,6 @@ "optional": true } } - }, - "node_modules/vue-tsc": { - "version": "2.2.12", - "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.2.12.tgz", - "integrity": "sha512-P7OP77b2h/Pmk+lZdJ0YWs+5tJ6J2+uOQPo7tlBnY44QqQSPYvS0qVT4wqDJgwrZaLe47etJLLQRFia71GYITw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@volar/typescript": "2.4.15", - "@vue/language-core": "2.2.12" - }, - "bin": { - "vue-tsc": "bin/vue-tsc.js" - }, - "peerDependencies": { - "typescript": ">=5.0.0" - } } } } diff --git a/package.json b/package.json index 535f28a..17d0f8e 100644 --- a/package.json +++ b/package.json @@ -1,46 +1,58 @@ { "name": "@simcu/simapi", - "version": "1.0.1", - "description": "轻量 Vue3 HTTP 客户端库,基于 Axios + Pinia", - "main": "dist/simapi.umd.cjs", - "module": "dist/simapi.js", - "types": "dist/index.d.ts", - "files": [ - "dist", - "README.md" - ], - "scripts": { - "build": "vite build", - "dev": "vite build --watch", - "types": "vue-tsc --declaration --emitDeclarationOnly", - "lint": "vue-tsc --noEmit" - }, - "keywords": [ - "vue3", - "pinia", - "http", - "axios", - "api", - "rest" - ], + "version": "0.0.0-version-placeholder", + "description": "SimApi 统一前端 HTTP 客户端库,支持 Vue3 和常规 JS/TS 项目(基于原生 fetch)", "author": "simcu", "license": "MIT", "repository": { "type": "git", - "url": "git@github.com:simcu/simapi-vue.git" + "url": "git@github.com:simcu/simapi-ts.git" + }, + "keywords": [ + "simapi", + "vue3", + "pinia", + "rxjs", + "http", + "fetch" + ], + "files": [ + "dist", + "simapi.core.ts", + "simapi.pinia.ts", + "README.md", + "package.json" + ], + "exports": { + ".": { + "import": "./dist/index.mjs", + "require": "./dist/index.cjs", + "types": "./dist/simapi.core.d.ts" + }, + "./pinia": { + "import": "./dist/pinia.mjs", + "types": "./dist/simapi.pinia.d.ts" + } + }, + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/simapi.core.d.ts", + "scripts": { + "build": "npm run build:core && npm run build:pinia && npm run types", + "build:core": "vite build --config vite.core.config.ts", + "build:pinia": "vite build --config vite.pinia.config.ts", + "dev": "vite build --config vite.core.config.ts --watch", + "types": "tsc --declaration --emitDeclarationOnly --project tsconfig.build.json", + "lint": "tsc --noEmit" }, "dependencies": { - "axios": "^1.6.0" - }, - "peerDependencies": { - "vue": "^3.0.0", - "pinia": "^2.0.0" + "tslib": "^2.3.0" }, "devDependencies": { "@vitejs/plugin-vue": "^5.0.0", - "typescript": "^5.0.0", + "pinia": "^2.2.0", + "typescript": "~5.9.3", "vite": "^5.0.0", - "vue": "^3.4.0", - "vue-tsc": "^2.0.0" + "vue": "^3.4.0" } } diff --git a/src/index.ts b/src/index.ts deleted file mode 100644 index e725614..0000000 --- a/src/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * SimApi - 轻量 API 请求库 - */ - -export { useSimApi } from './simapi' -export type { SimApiAuthConfig, SimApiConfig, Versions } from './simapi' -export { SimApiVersion, AppVersion } from './simapi' diff --git a/src/simapi.core.ts b/src/simapi.core.ts new file mode 100644 index 0000000..fb6061a --- /dev/null +++ b/src/simapi.core.ts @@ -0,0 +1,323 @@ +/** + * SimApi Core — 纯 TypeScript 核心,无框架依赖 + * + * 支持所有 JS/TS 环境(Node.js、浏览器、小程序等)。 + * + * @example + * import { SimApiCore } from '@simcu/simapi' + * const api = new SimApiCore() + * api.setEndpoints({ default: 'https://api.example.com' }) + * const res = await api.query('/users/list', { page: 1 }) + */ + +import { + AppVersion, + SimApiVersion, + type SimApiVersions, + type SimApiAuthConfig, + type SimApiApiConfig, + type SimApiOptions, + type SimApiBaseResponse, +} from './types' + +export { SimApiVersion, AppVersion } from './types' +export type { + SimApiVersions, + SimApiAuthConfig, + SimApiApiConfig, + SimApiOptions, + SimApiBaseResponse, +} from './types' + +// ── Helper: Fetch with Timeout ──────────────────────────────────────── + +function fetchWithTimeout( + url: string, + options: RequestInit, + timeout: number = 10000 +): Promise { + return Promise.race([ + fetch(url, options), + new Promise((_, reject) => + setTimeout(() => reject(new Error(`Request timeout after ${timeout}ms`)), timeout) + ), + ]) +} + +// ── Helper: Fetch POST with JSON body ──────────────────────────────────── + +async function fetchPost( + url: string, + body: any, + headers: Record, + timeout: number +): Promise> { + const options: RequestInit = { + method: 'POST', + headers: headers as HeadersInit, + body: body instanceof FormData ? body : JSON.stringify(body), + credentials: 'omit', // 从不发送 Cookie + } + + const response = await fetchWithTimeout(url, options, timeout) + + if (!response.ok) { + const errorData = await response.json().catch(() => ({})) + throw { + status: response.status, + statusText: response.statusText, + data: errorData, + message: `HTTP ${response.status}: ${response.statusText}`, + } + } + + return response.json() +} + +// ── SimApiCore ──────────────────────────────────────── + +export class SimApiCore { + debug: boolean = true + uiAppVersion?: string + + auth: SimApiAuthConfig = { + token_name: 'simapi-auth-token', + check_url: '/auth/check', + logout_url: '/auth/logout', + login_url: '/auth/login', + } + + api: SimApiApiConfig = { + endpoints: { default: '' }, + defaultEndpoint: 'default', + businessCallback: { + 401: () => localStorage.removeItem(this.auth.token_name), + common: () => {}, + }, + responseCallback: { + success: (response: any) => response, + error: (_err: any) => {}, + }, + timeout: 10000, + } + + constructor(options?: SimApiOptions) { + if (options) { + this.configure(options) + } + } + + /** + * 从 window.simapi 读取配置并初始化 + * + * 支持字段:endpoints, defaultEndpoint, debug, uiAppVersion + * 业务回调(businessCallback / responseCallback)需在代码中处理 + */ + autoInit(): void { + const config = (window as any).simapi + if (!config) return + + if (config.debug !== undefined) { + this.debug = config.debug + } + if (config.uiAppVersion !== undefined) { + this.uiAppVersion = config.uiAppVersion + } + if (config.endpoints) { + this.api.endpoints = { ...this.api.endpoints, ...config.endpoints } + } + if (config.defaultEndpoint) { + this.api.defaultEndpoint = config.defaultEndpoint + } + } + + configure(options: SimApiOptions): void { + if (options.debug !== undefined) { + this.debug = options.debug + } + if (options.uiAppVersion !== undefined) { + this.uiAppVersion = options.uiAppVersion + } + if (options.auth) { + this.auth = { ...this.auth, ...options.auth } + } + if (options.api) { + this.api = { + ...this.api, + ...options.api, + endpoints: { ...this.api.endpoints, ...(options.api.endpoints ?? {}) }, + businessCallback: { ...this.api.businessCallback, ...(options.api.businessCallback ?? {}) }, + responseCallback: { ...this.api.responseCallback, ...(options.api.responseCallback ?? {}) }, + } + } + } + + setEndpoints(endpoints: { [name: string]: string }): void { + this.api.endpoints = { ...this.api.endpoints, ...endpoints } + } + + getEndpoint(name?: string): string { + return this.api.endpoints[name ?? this.api.defaultEndpoint] ?? '' + } + + setBusinessCallback(code: number | string, callback: (data: any) => void): void { + this.api.businessCallback[code] = callback + } + + getToken(): string { + return localStorage.getItem(this.auth.token_name) ?? '' + } + + setToken(token: string): void { + localStorage.setItem(this.auth.token_name, token) + } + + removeToken(): void { + localStorage.removeItem(this.auth.token_name) + } + + get isLoggedIn(): boolean { + return !!localStorage.getItem(this.auth.token_name) + } + + genS4(): string { + return (((1 + Math.random()) * 0x10000 * Date.parse(new Date().toString())) | 0) + .toString(16) + .substring(1) + } + + /** + * 日志工具(仅在 debug 模式下输出) + * + * @example + * api.logDebug('用户登录', { id: 1, name: 'test' }) + * api.logDebug('请求开始', uri, params) + */ + logDebug(...args: any[]): void { + if (!this.debug) return + console.log('[DEBUG]', ...args) + } + + /** + * 获取版本信息 + * + * @param endpointName - 指定从哪个 endpoint 获取版本,默认使用 default endpoint + * @returns 版本信息对象 + * + * @example + * // 从默认 endpoint 获取 + * const versions = await api.getVersion() + * + * // 从指定 endpoint 获取 + * const versions = await api.getVersion('backup') + */ + async getVersion(endpointName?: string): Promise { + try { + const resp = await this.query('/versions', {}, endpointName) + if (resp?.data) { + const d = resp.data + const versions: SimApiVersions = { + uiApp: this.uiAppVersion ?? AppVersion, + uiSimApi: SimApiVersion, + apiApp: d.App?.split('+')[0] ?? '0.0.0', + apiSimApi: d.SimApi?.split('+')[0] ?? '0.0.0', + apiAppFull: d.App ?? '0.0.0', + apiSimApiFull: d.SimApi ?? '0.0.0', + } + if (this.debug) { + console.log(`UI主应用版本: ${versions.uiApp}\nUISimApi版本: ${versions.uiSimApi}\nAPI主应用版本: ${versions.apiApp}\nAPISimApi版本: ${versions.apiSimApi}`) + } + return versions + } + } catch { + // 版本获取失败返回默认值 + } + return { + uiApp: AppVersion, + uiSimApi: SimApiVersion, + apiApp: '0.0.0', + apiSimApi: '0.0.0', + apiAppFull: '0.0.0', + apiSimApiFull: '0.0.0', + } + } + + async query( + uri: string, + params: any = {}, + endpointKey?: string, + extraHeaders?: Record + ): Promise> { + const headers: Record = { ...extraHeaders, ...{} } + const queryId = this.genS4() + + if (!(params instanceof FormData)) { + headers['Content-Type'] = 'application/json' + } + + const token = this.getToken() + if (token) { + headers['Token'] = token + } + + if (this.debug) { + headers['Query-Id'] = queryId + console.log('[REQUEST*]', queryId, '->', uri, 'AUTH:', localStorage.getItem(this.auth.token_name)) + } + + const url = this.getEndpoint(endpointKey) + uri + + try { + const respData = await fetchPost( + url, + params, + headers, + this.api.timeout ?? 10000 + ) + if (this.debug) { + console.log('[RESPONSE]', queryId, '->', respData) + } + const processedData = this.api.responseCallback.success(respData) as SimApiBaseResponse + + // 业务回调处理 + if (this.api.businessCallback.hasOwnProperty(processedData.code)) { + this.api.businessCallback[processedData.code](processedData) + } else if (this.api.businessCallback['common'] && processedData.code !== 200) { + this.api.businessCallback['common'](processedData) + } + + // 直接返回,不再根据 code 抛出错误 + return processedData + } catch (error) { + if (this.debug) { + console.log('[RESPONSE]', queryId, '->', error) + } + this.api.responseCallback.error(error) + throw error + } + } + + async login(request: Record): Promise> { + const result = await this.query(this.auth.login_url, request) + if (result?.data) { + this.setToken(result.data) + } + return result + } + + async logout(url?: string | null): Promise { + this.removeToken() + if (url !== null) { + return this.query(url ?? this.auth.logout_url).catch(() => true) + } + return true + } + + async checkLogin(url?: string | null): Promise { + if (url !== null) { + await this.query(url ?? this.auth.check_url).catch(() => {}) + } else if (this.getToken()) { + this.api.businessCallback[401]?.(null) + } + } +} diff --git a/src/simapi.pinia.ts b/src/simapi.pinia.ts new file mode 100644 index 0000000..11db0b9 --- /dev/null +++ b/src/simapi.pinia.ts @@ -0,0 +1,91 @@ +import { defineStore } from 'pinia' +import { SimApiCore } from './simapi.core' +import type { SimApiBaseResponse, SimApiOptions, SimApiVersions } from './types' + +// ============ Pinia Store ============ +// 仅作为 core 的代理映射,不维护任何独立状态 + +export const useSimApi = defineStore('simapi', { + state: () => ({ + // 在 state 中实例化 core + _core: new SimApiCore(), + }), + + getters: { + // 直接映射 core 的属性和方法 + debug: (state) => state._core.debug, + token: (state) => state._core.getToken(), + isLoggedIn: (state) => state._core.isLoggedIn, + api: (state) => state._core.api, + auth: (state) => state._core.auth, + }, + + actions: { + // 所有方法直接代理到 core + autoInit(): void { + this._core.autoInit() + }, + + configure(options: SimApiOptions): void { + this._core.configure(options) + }, + + setDebug(debug: boolean): void { + this._core.debug = debug + }, + + setEndpoints(endpoints: { [name: string]: string }): void { + this._core.setEndpoints(endpoints) + }, + + setBusinessCallback( + code: number | string, + callback: (data: SimApiBaseResponse) => void + ): void { + this._core.setBusinessCallback(code, callback) + }, + + getToken(): string { + return this._core.getToken() + }, + + setToken(token: string): void { + this._core.setToken(token) + }, + + removeToken(): void { + this._core.removeToken() + }, + + async login(request: Record): Promise> { + return this._core.login(request) + }, + + async logout(url?: string | null): Promise { + return this._core.logout(url) + }, + + async checkLogin(url?: string | null): Promise { + return this._core.checkLogin(url) + }, + + async query( + uri: string, + params?: any, + endpointKey?: string, + extraHeaders?: Record + ): Promise> { + return this._core.query(uri, params, endpointKey, extraHeaders) + }, + + getEndpoint(name?: string): string { + return this._core.getEndpoint(name) + }, + + async getVersion(endpointName?: string): Promise { + return this._core.getVersion(endpointName) + }, + }, +}) + + diff --git a/src/simapi.ts b/src/simapi.ts deleted file mode 100644 index 5ab4365..0000000 --- a/src/simapi.ts +++ /dev/null @@ -1,207 +0,0 @@ -/** - * SimApi Pinia Store - * - * 使用方法: - * import { useSimApi } from 'simapi' - * const api = useSimApi() - * await api.query('/api/xxx', data) - */ - -import { defineStore } from 'pinia' -import axios, { AxiosRequestHeaders } from 'axios' - -// ============ 类型定义 ============ - -export const SimApiVersion = '1.0.0' -export const AppVersion = '1.0.0' - -export interface Versions { - uiApp: string - uiSimApi: string - apiApp: string - apiSimApi: string - apiAppFull: string - apiSimApiFull: string -} - -export interface BusinessCallback { - [key: number | string]: (data: any) => void -} - -export interface SimApiAuthConfig { - token_name: string - check_url: string - logout_url: string - login_url: string -} - -export interface SimApiConfig { - endpoints: { [name: string]: string } - defaultEndpoint: string - businessCallback: BusinessCallback -} - -// ============ Store 定义 ============ - -export const useSimApi = defineStore('simapi', { - // ============ State ============ - state: () => ({ - debug: true, - - auth: { - token_name: 'simapi-auth-token', - check_url: '/auth/check', - logout_url: '/auth/logout', - login_url: '/auth/login' - } as SimApiAuthConfig, - - api: { - endpoints: { default: '' }, - defaultEndpoint: 'default', - businessCallback: { - 401: () => localStorage.removeItem('simapi-auth-token'), - common: () => {} - } - } as SimApiConfig, - - versions: { - uiApp: AppVersion, - uiSimApi: SimApiVersion, - apiApp: '0.0.0', - apiSimApi: '0.0.0', - apiAppFull: '0.0.0', - apiSimApiFull: '0.0.0' - } as Versions - }), - - // ============ Getters ============ - getters: { - token: (state) => localStorage.getItem(state.auth.token_name) || '', - isLoggedIn: (state) => !!localStorage.getItem(state.auth.token_name) - }, - - // ============ Actions ============ - actions: { - /** 设置端点配置 */ - setEndpoints(endpoints: { [name: string]: string }): void { - this.api.endpoints = { ...this.api.endpoints, ...endpoints } - // 获取并打印版本信息 - this.getVersions() - }, - - /** 设置业务错误回调 */ - setBusinessCallback(code: number | string, callback: (data: any) => void): void { - this.api.businessCallback[code] = callback - }, - - /** 设置调试模式 */ - setDebug(debug: boolean): void { - this.debug = debug - }, - - /** 打印调试日志 */ - debug(title: string, data: any): void { - if (this.debug) { - console.log('[DEBUG]', title, data) - } - }, - - /** 生成随机字符串 */ - genS4(): string { - return (((1 + Math.random()) * 0x10000 * Date.parse(new Date())) | 0).toString(16).substring(1) - }, - - /** 获取端点地址 */ - getEndpoint(name?: string): string { - return this.api.endpoints[name || this.api.defaultEndpoint] || '' - }, - - /** 获取并打印版本信息 */ - async getVersions(): Promise { - try { - const resp = await axios.post(this.getEndpoint() + '/versions', {}, { timeout: 5000 }) - if (resp.data?.data) { - this.versions = { - uiApp: AppVersion, - uiSimApi: SimApiVersion, - apiApp: resp.data.data.App?.split('+')[0] || '0.0.0', - apiSimApi: resp.data.data.SimApi?.split('+')[0] || '0.0.0', - apiAppFull: resp.data.data.App || '0.0.0', - apiSimApiFull: resp.data.data.SimApi || '0.0.0' - } - } - } catch (e) { - // 版本获取失败不影响主流程 - } - // 打印版本信息,格式与 Angular 一致 - console.log(`UI主应用版本: ${this.versions.uiApp}\nUISimApi版本: ${this.versions.uiSimApi}\nAPI主应用版本: ${this.versions.apiApp}\nAPISimApi版本: ${this.versions.apiSimApi}`) - }, - - /** 发起请求 */ - async query(uri: string, params: any = {}): Promise { - const headers: Record = {} - const queryId = this.genS4() - - if (!(params instanceof FormData)) { - headers['Content-Type'] = 'application/json' - } - - const token = this.token - if (token) { - headers['Token'] = token - } - - if (this.debug) { - headers['Query-Id'] = queryId - console.log('[REQUEST*]', queryId, '->', uri, 'AUTH:', token) - } - - const url = this.getEndpoint() + uri - - try { - const response = await axios.post(url, params, { headers: headers as AxiosRequestHeaders }) - if (this.debug) { - console.log('[RESPONSE]', queryId, '->', response.data) - } - return this.handleResponse(response.data) - } catch (error) { - if (this.debug) { - console.log('[RESPONSE]', queryId, '->', error) - } - throw error - } - }, - - /** 处理响应 */ - handleResponse(data: any): any { - if (data.code !== 200) { - const callback = this.api.businessCallback[data.code] || this.api.businessCallback['common'] - callback?.(data) - } - return data - }, - - /** 登录 */ - async login(request: Record): Promise { - const result = await this.query(this.auth.login_url, request) - if (result.data) { - localStorage.setItem(this.auth.token_name, result.data) - } - return result - }, - - /** 登出 */ - async logout(url?: string | null): Promise { - localStorage.removeItem(this.auth.token_name) - if (url !== null) { - return this.query(url ?? this.auth.logout_url).catch(() => true) - } - return true - }, - - /** 获取 Token */ - getToken(): string { - return localStorage.getItem(this.auth.token_name) || '' - } - } -}) diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..7fa42f0 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,70 @@ +/** + * SimApi 类型定义 + */ + +// 版本号占位符,构建时由 GitHub Action 替换 +export const SimApiVersion = '0.0.0-version-placeholder' +export const AppVersion = '0.0.0-version-placeholder' + +/** 版本信息 */ +export interface SimApiVersions { + uiApp: string + uiSimApi: string + apiApp: string + apiSimApi: string + apiAppFull: string + apiSimApiFull: string +} + +/** 认证配置 */ +export interface SimApiAuthConfig { + /** localStorage key,默认 'simapi-auth-token' */ + token_name: string + /** 检查登录接口,默认 '/auth/check' */ + check_url: string + /** 登出接口,默认 '/auth/logout' */ + logout_url: string + /** 登录接口,默认 '/auth/login' */ + login_url: string +} + +/** 业务错误码回调 */ +export interface SimApiBusinessCallback { + [key: number | string]: (data: any) => void +} + +/** 响应拦截回调 */ +export interface SimApiResponseCallback { + success: (response: any) => any + error: (err: any) => void +} + +/** API 配置 */ +export interface SimApiApiConfig { + /** 多端点映射 */ + endpoints: { [name: string]: string } + /** 默认端点名称 */ + defaultEndpoint: string + /** 业务错误码回调 */ + businessCallback: SimApiBusinessCallback + /** 响应拦截器 */ + responseCallback: SimApiResponseCallback + /** 请求超时时间(毫秒),默认 10000 */ + timeout?: number +} + +/** SimApi 完整配置 */ +export interface SimApiOptions { + debug?: boolean + /** UI 应用版本,如果不指定则使用库内置的占位符版本 */ + uiAppVersion?: string + auth?: Partial + api?: Partial +} + +/** SimApi 标准响应格式 */ +export interface SimApiBaseResponse { + code: number + message: string + data?: T +} diff --git a/tsconfig.build.json b/tsconfig.build.json new file mode 100644 index 0000000..994b536 --- /dev/null +++ b/tsconfig.build.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + "moduleResolution": "node", + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true, + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "./dist", + "strict": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "experimentalDecorators": true, + "emitDecoratorMetadata": true + }, + "include": ["src/types.ts", "src/simapi.core.ts", "src/simapi.pinia.ts"] +} diff --git a/tsconfig.json b/tsconfig.json index 1ade947..da27668 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,11 +10,12 @@ "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, - "jsx": "preserve", "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true + "noUnusedLocals": false, + "noUnusedParameters": false, + "noFallthroughCasesInSwitch": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true }, - "include": ["src/**/*.ts", "src/**/*.d.ts"] + "include": ["src/**/*.ts"] } diff --git a/vite.config.ts b/vite.config.ts deleted file mode 100644 index 9a54947..0000000 --- a/vite.config.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { defineConfig } from 'vite' -import vue from '@vitejs/plugin-vue' - -export default defineConfig({ - plugins: [vue()], - build: { - lib: { - entry: 'src/index.ts', - name: 'SimApi', - formats: ['es', 'umd'], - fileName: (format) => `simapi.${format}.${format === 'es' ? 'js' : 'cjs'}` - }, - rollupOptions: { - external: ['vue'], - output: { - globals: { - vue: 'Vue' - } - } - } - } -}) diff --git a/vite.core.config.ts b/vite.core.config.ts new file mode 100644 index 0000000..0e0b407 --- /dev/null +++ b/vite.core.config.ts @@ -0,0 +1,17 @@ +import { defineConfig } from 'vite' + +export default defineConfig({ + build: { + outDir: 'dist', + emptyOutDir: true, + lib: { + entry: 'src/simapi.core.ts', + name: 'SimApiCore', + formats: ['es', 'cjs'], + fileName: (format) => `index.${format === 'es' ? 'mjs' : 'cjs'}` + }, + rollupOptions: { + // 不再需要 external,使用原生 fetch + } + } +}) diff --git a/vite.pinia.config.ts b/vite.pinia.config.ts new file mode 100644 index 0000000..9183a8b --- /dev/null +++ b/vite.pinia.config.ts @@ -0,0 +1,23 @@ +import { defineConfig } from 'vite' + +export default defineConfig({ + build: { + outDir: 'dist', + emptyOutDir: false, + lib: { + entry: 'src/simapi.pinia.ts', + name: 'SimApiPinia', + formats: ['es'], + fileName: () => 'pinia.mjs' + }, + rollupOptions: { + external: ['vue', 'pinia'], + output: { + globals: { + vue: 'Vue', + pinia: 'Pinia' + } + } + } + } +})