diff --git a/apps/basic/.github/instructions/api.instructions.md b/apps/basic/.github/instructions/api.instructions.md index 4b98d73..24f0c26 100644 --- a/apps/basic/.github/instructions/api.instructions.md +++ b/apps/basic/.github/instructions/api.instructions.md @@ -1,6 +1,7 @@ --- -## applyTo: "src/api/**/*.ts,src/utils/http.ts,src/mocks/handlers/**/*.ts,src/mocks/createHandler.ts" +## applyTo: "src/api/**/\*.ts,src/utils/http.ts,src/mocks/handlers/**/\*.ts,src/mocks/createHandler.ts" + description: "Use when editing API clients, schemas, HTTP behavior, response types, or MSW endpoint handlers. Keywords: api, http, schema, zod, handler, endpoint, auth, users." # API Instructions @@ -26,4 +27,4 @@ Maintain strict API contracts and consistent server/client mock behavior. ## Validation - Verify TypeScript and schema parsing paths compile cleanly. -- Run: `vp check --no-fmt` \ No newline at end of file +- Run: `vp check --no-fmt` diff --git a/apps/basic/.github/instructions/frontend.instructions.md b/apps/basic/.github/instructions/frontend.instructions.md index 36f05ca..1f88597 100644 --- a/apps/basic/.github/instructions/frontend.instructions.md +++ b/apps/basic/.github/instructions/frontend.instructions.md @@ -1,6 +1,7 @@ --- -## applyTo: "src/**/*.{ts,tsx,css}" +## applyTo: "src/\*_/_.{ts,tsx,css}" + description: "Use when editing React UI, route pages, components, styles, layout, i18n text, or Ant Design behavior. Keywords: frontend, component, page, ui, layout, style, antd, i18n." # Frontend Instructions @@ -28,4 +29,4 @@ Keep frontend changes predictable, minimal, and reusable for AI-assisted edits. ## Validation - Run: `vp check --no-fmt` -- For UI flow changes, run focused e2e where possible. \ No newline at end of file +- For UI flow changes, run focused e2e where possible. diff --git a/apps/basic/.github/instructions/refactor.instructions.md b/apps/basic/.github/instructions/refactor.instructions.md index 66e9042..81e74f5 100644 --- a/apps/basic/.github/instructions/refactor.instructions.md +++ b/apps/basic/.github/instructions/refactor.instructions.md @@ -1,6 +1,6 @@ --- -## applyTo: "src/*/*.{ts,tsx}" +## applyTo: "src/_/_.{ts,tsx}" description: "Use when refactoring existing code for deduplication, modularization, naming cleanup, or maintainability improvements without behavior changes. Keywords: refactor, cleanup, simplify, deduplicate, maintainability." @@ -34,4 +34,4 @@ Reduce duplication while preserving behavior and public contracts. - Confirm no new diagnostics in touched files. - Run: `vp check --no-fmt` -- For significant changes, verify bundle size impact: `vp build 2>&1 | grep "kB"` \ No newline at end of file +- For significant changes, verify bundle size impact: `vp build 2>&1 | grep "kB"` diff --git a/apps/basic/.github/instructions/testing.instructions.md b/apps/basic/.github/instructions/testing.instructions.md index c1ce878..b08d024 100644 --- a/apps/basic/.github/instructions/testing.instructions.md +++ b/apps/basic/.github/instructions/testing.instructions.md @@ -1,6 +1,6 @@ --- -## applyTo: "tests/**/.ts,tests/**/*.tsx,src/mocks//*.ts,playwright.config.ts" +## applyTo: "tests/**/.ts,tests/**/_.tsx,src/mocks//_.ts,playwright.config.ts" description: "Use when adding or editing tests, Playwright cases, MSW handlers, mock data, or test configuration. Keywords: test, e2e, playwright, mock, msw, coverage." @@ -27,4 +27,4 @@ Keep tests fast, deterministic, and aligned with core business flows. ## Validation - Run focused tests first, then broader checks if needed. -- Run: `vp check --no-fmt` \ No newline at end of file +- Run: `vp check --no-fmt` diff --git a/apps/basic/.vite-hooks/pre-commit b/apps/basic/.vite-hooks/pre-commit index a54ea02..b64a1f1 100755 --- a/apps/basic/.vite-hooks/pre-commit +++ b/apps/basic/.vite-hooks/pre-commit @@ -1 +1 @@ -pnpm lint && pnpm fmt \ No newline at end of file +vp staged \ No newline at end of file diff --git a/apps/basic/AGENTS.md b/apps/basic/AGENTS.md index 77fb37a..49ea51f 100644 --- a/apps/basic/AGENTS.md +++ b/apps/basic/AGENTS.md @@ -81,4 +81,4 @@ This repository also uses scoped AI instruction files in `.github/instructions/` - `api.instructions.md` for API/schema/handler changes - `refactor.instructions.md` for behavior-preserving cleanup -See `.github/instructions/README.md` for usage and authoring rules. \ No newline at end of file +See `.github/instructions/README.md` for usage and authoring rules. diff --git a/apps/basic/src/routeTree.gen.ts b/apps/basic/src/routeTree.gen.ts index 328b65f..c5d530e 100644 --- a/apps/basic/src/routeTree.gen.ts +++ b/apps/basic/src/routeTree.gen.ts @@ -8,191 +8,184 @@ // You should NOT make any changes in this file as it will be overwritten. // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. -import { Route as rootRouteImport } from './routes/__root' -import { Route as AuthRouteImport } from './routes/_auth' -import { Route as IndexRouteImport } from './routes/index' -import { Route as RegisterIndexRouteImport } from './routes/register/index' -import { Route as LoginIndexRouteImport } from './routes/login/index' -import { Route as R404IndexRouteImport } from './routes/404/index' -import { Route as AuthUsersIndexRouteImport } from './routes/_auth/users/index' -import { Route as AuthDashboardIndexRouteImport } from './routes/_auth/dashboard/index' -import { Route as Auth403IndexRouteImport } from './routes/_auth/403/index' +import { Route as rootRouteImport } from "./routes/__root"; +import { Route as AuthRouteImport } from "./routes/_auth"; +import { Route as IndexRouteImport } from "./routes/index"; +import { Route as RegisterIndexRouteImport } from "./routes/register/index"; +import { Route as LoginIndexRouteImport } from "./routes/login/index"; +import { Route as R404IndexRouteImport } from "./routes/404/index"; +import { Route as AuthUsersIndexRouteImport } from "./routes/_auth/users/index"; +import { Route as AuthDashboardIndexRouteImport } from "./routes/_auth/dashboard/index"; +import { Route as Auth403IndexRouteImport } from "./routes/_auth/403/index"; const AuthRoute = AuthRouteImport.update({ - id: '/_auth', + id: "/_auth", getParentRoute: () => rootRouteImport, -} as any) +} as any); const IndexRoute = IndexRouteImport.update({ - id: '/', - path: '/', + id: "/", + path: "/", getParentRoute: () => rootRouteImport, -} as any) +} as any); const RegisterIndexRoute = RegisterIndexRouteImport.update({ - id: '/register/', - path: '/register/', + id: "/register/", + path: "/register/", getParentRoute: () => rootRouteImport, -} as any) +} as any); const LoginIndexRoute = LoginIndexRouteImport.update({ - id: '/login/', - path: '/login/', + id: "/login/", + path: "/login/", getParentRoute: () => rootRouteImport, -} as any) +} as any); const R404IndexRoute = R404IndexRouteImport.update({ - id: '/404/', - path: '/404/', + id: "/404/", + path: "/404/", getParentRoute: () => rootRouteImport, -} as any) +} as any); const AuthUsersIndexRoute = AuthUsersIndexRouteImport.update({ - id: '/users/', - path: '/users/', + id: "/users/", + path: "/users/", getParentRoute: () => AuthRoute, -} as any) +} as any); const AuthDashboardIndexRoute = AuthDashboardIndexRouteImport.update({ - id: '/dashboard/', - path: '/dashboard/', + id: "/dashboard/", + path: "/dashboard/", getParentRoute: () => AuthRoute, -} as any) +} as any); const Auth403IndexRoute = Auth403IndexRouteImport.update({ - id: '/403/', - path: '/403/', + id: "/403/", + path: "/403/", getParentRoute: () => AuthRoute, -} as any) +} as any); export interface FileRoutesByFullPath { - '/': typeof IndexRoute - '/404/': typeof R404IndexRoute - '/login/': typeof LoginIndexRoute - '/register/': typeof RegisterIndexRoute - '/403/': typeof Auth403IndexRoute - '/dashboard/': typeof AuthDashboardIndexRoute - '/users/': typeof AuthUsersIndexRoute + "/": typeof IndexRoute; + "/404/": typeof R404IndexRoute; + "/login/": typeof LoginIndexRoute; + "/register/": typeof RegisterIndexRoute; + "/403/": typeof Auth403IndexRoute; + "/dashboard/": typeof AuthDashboardIndexRoute; + "/users/": typeof AuthUsersIndexRoute; } export interface FileRoutesByTo { - '/': typeof IndexRoute - '/404': typeof R404IndexRoute - '/login': typeof LoginIndexRoute - '/register': typeof RegisterIndexRoute - '/403': typeof Auth403IndexRoute - '/dashboard': typeof AuthDashboardIndexRoute - '/users': typeof AuthUsersIndexRoute + "/": typeof IndexRoute; + "/404": typeof R404IndexRoute; + "/login": typeof LoginIndexRoute; + "/register": typeof RegisterIndexRoute; + "/403": typeof Auth403IndexRoute; + "/dashboard": typeof AuthDashboardIndexRoute; + "/users": typeof AuthUsersIndexRoute; } export interface FileRoutesById { - __root__: typeof rootRouteImport - '/': typeof IndexRoute - '/_auth': typeof AuthRouteWithChildren - '/404/': typeof R404IndexRoute - '/login/': typeof LoginIndexRoute - '/register/': typeof RegisterIndexRoute - '/_auth/403/': typeof Auth403IndexRoute - '/_auth/dashboard/': typeof AuthDashboardIndexRoute - '/_auth/users/': typeof AuthUsersIndexRoute + __root__: typeof rootRouteImport; + "/": typeof IndexRoute; + "/_auth": typeof AuthRouteWithChildren; + "/404/": typeof R404IndexRoute; + "/login/": typeof LoginIndexRoute; + "/register/": typeof RegisterIndexRoute; + "/_auth/403/": typeof Auth403IndexRoute; + "/_auth/dashboard/": typeof AuthDashboardIndexRoute; + "/_auth/users/": typeof AuthUsersIndexRoute; } export interface FileRouteTypes { - fileRoutesByFullPath: FileRoutesByFullPath - fullPaths: - | '/' - | '/404/' - | '/login/' - | '/register/' - | '/403/' - | '/dashboard/' - | '/users/' - fileRoutesByTo: FileRoutesByTo - to: '/' | '/404' | '/login' | '/register' | '/403' | '/dashboard' | '/users' + fileRoutesByFullPath: FileRoutesByFullPath; + fullPaths: "/" | "/404/" | "/login/" | "/register/" | "/403/" | "/dashboard/" | "/users/"; + fileRoutesByTo: FileRoutesByTo; + to: "/" | "/404" | "/login" | "/register" | "/403" | "/dashboard" | "/users"; id: - | '__root__' - | '/' - | '/_auth' - | '/404/' - | '/login/' - | '/register/' - | '/_auth/403/' - | '/_auth/dashboard/' - | '/_auth/users/' - fileRoutesById: FileRoutesById + | "__root__" + | "/" + | "/_auth" + | "/404/" + | "/login/" + | "/register/" + | "/_auth/403/" + | "/_auth/dashboard/" + | "/_auth/users/"; + fileRoutesById: FileRoutesById; } export interface RootRouteChildren { - IndexRoute: typeof IndexRoute - AuthRoute: typeof AuthRouteWithChildren - R404IndexRoute: typeof R404IndexRoute - LoginIndexRoute: typeof LoginIndexRoute - RegisterIndexRoute: typeof RegisterIndexRoute + IndexRoute: typeof IndexRoute; + AuthRoute: typeof AuthRouteWithChildren; + R404IndexRoute: typeof R404IndexRoute; + LoginIndexRoute: typeof LoginIndexRoute; + RegisterIndexRoute: typeof RegisterIndexRoute; } -declare module '@tanstack/react-router' { +declare module "@tanstack/react-router" { interface FileRoutesByPath { - '/_auth': { - id: '/_auth' - path: '' - fullPath: '/' - preLoaderRoute: typeof AuthRouteImport - parentRoute: typeof rootRouteImport - } - '/': { - id: '/' - path: '/' - fullPath: '/' - preLoaderRoute: typeof IndexRouteImport - parentRoute: typeof rootRouteImport - } - '/register/': { - id: '/register/' - path: '/register' - fullPath: '/register/' - preLoaderRoute: typeof RegisterIndexRouteImport - parentRoute: typeof rootRouteImport - } - '/login/': { - id: '/login/' - path: '/login' - fullPath: '/login/' - preLoaderRoute: typeof LoginIndexRouteImport - parentRoute: typeof rootRouteImport - } - '/404/': { - id: '/404/' - path: '/404' - fullPath: '/404/' - preLoaderRoute: typeof R404IndexRouteImport - parentRoute: typeof rootRouteImport - } - '/_auth/users/': { - id: '/_auth/users/' - path: '/users' - fullPath: '/users/' - preLoaderRoute: typeof AuthUsersIndexRouteImport - parentRoute: typeof AuthRoute - } - '/_auth/dashboard/': { - id: '/_auth/dashboard/' - path: '/dashboard' - fullPath: '/dashboard/' - preLoaderRoute: typeof AuthDashboardIndexRouteImport - parentRoute: typeof AuthRoute - } - '/_auth/403/': { - id: '/_auth/403/' - path: '/403' - fullPath: '/403/' - preLoaderRoute: typeof Auth403IndexRouteImport - parentRoute: typeof AuthRoute - } + "/_auth": { + id: "/_auth"; + path: ""; + fullPath: "/"; + preLoaderRoute: typeof AuthRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/": { + id: "/"; + path: "/"; + fullPath: "/"; + preLoaderRoute: typeof IndexRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/register/": { + id: "/register/"; + path: "/register"; + fullPath: "/register/"; + preLoaderRoute: typeof RegisterIndexRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/login/": { + id: "/login/"; + path: "/login"; + fullPath: "/login/"; + preLoaderRoute: typeof LoginIndexRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/404/": { + id: "/404/"; + path: "/404"; + fullPath: "/404/"; + preLoaderRoute: typeof R404IndexRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/_auth/users/": { + id: "/_auth/users/"; + path: "/users"; + fullPath: "/users/"; + preLoaderRoute: typeof AuthUsersIndexRouteImport; + parentRoute: typeof AuthRoute; + }; + "/_auth/dashboard/": { + id: "/_auth/dashboard/"; + path: "/dashboard"; + fullPath: "/dashboard/"; + preLoaderRoute: typeof AuthDashboardIndexRouteImport; + parentRoute: typeof AuthRoute; + }; + "/_auth/403/": { + id: "/_auth/403/"; + path: "/403"; + fullPath: "/403/"; + preLoaderRoute: typeof Auth403IndexRouteImport; + parentRoute: typeof AuthRoute; + }; } } interface AuthRouteChildren { - Auth403IndexRoute: typeof Auth403IndexRoute - AuthDashboardIndexRoute: typeof AuthDashboardIndexRoute - AuthUsersIndexRoute: typeof AuthUsersIndexRoute + Auth403IndexRoute: typeof Auth403IndexRoute; + AuthDashboardIndexRoute: typeof AuthDashboardIndexRoute; + AuthUsersIndexRoute: typeof AuthUsersIndexRoute; } const AuthRouteChildren: AuthRouteChildren = { Auth403IndexRoute: Auth403IndexRoute, AuthDashboardIndexRoute: AuthDashboardIndexRoute, AuthUsersIndexRoute: AuthUsersIndexRoute, -} +}; -const AuthRouteWithChildren = AuthRoute._addFileChildren(AuthRouteChildren) +const AuthRouteWithChildren = AuthRoute._addFileChildren(AuthRouteChildren); const rootRouteChildren: RootRouteChildren = { IndexRoute: IndexRoute, @@ -200,7 +193,7 @@ const rootRouteChildren: RootRouteChildren = { R404IndexRoute: R404IndexRoute, LoginIndexRoute: LoginIndexRoute, RegisterIndexRoute: RegisterIndexRoute, -} +}; export const routeTree = rootRouteImport ._addFileChildren(rootRouteChildren) - ._addFileTypes() + ._addFileTypes(); diff --git a/apps/basic/src/routes/_auth/users/-Toolbar.tsx b/apps/basic/src/routes/_auth/users/-Toolbar.tsx index ceb9e87..e1fcc71 100644 --- a/apps/basic/src/routes/_auth/users/-Toolbar.tsx +++ b/apps/basic/src/routes/_auth/users/-Toolbar.tsx @@ -66,7 +66,15 @@ export const Toolbar = forwardRef(function Toolbar ), }, ], - [keywordInput, onClearSearch, onKeywordChange, onRoleChange, onSearch, roleValue, token.fontSize], + [ + keywordInput, + onClearSearch, + onKeywordChange, + onRoleChange, + onSearch, + roleValue, + token.fontSize, + ], ); return ( diff --git a/apps/basic/vercel.json b/apps/basic/vercel.json index 70bff2f..1323cda 100644 --- a/apps/basic/vercel.json +++ b/apps/basic/vercel.json @@ -1,8 +1,8 @@ { - "rewrites": [ - { - "source": "/(.*)", - "destination": "/index.html" - } - ] -} \ No newline at end of file + "rewrites": [ + { + "source": "/(.*)", + "destination": "/index.html" + } + ] +} diff --git a/apps/docs/README.md b/apps/docs/README.md index 9da9ff4..7d1e7e5 100644 --- a/apps/docs/README.md +++ b/apps/docs/README.md @@ -2,6 +2,23 @@ 基于 [Next.js](https://nextjs.org) App Router、[Nextra 4](https://nextra.site) 与 `nextra-theme-docs` 的中文文档,与模板应用(Vite+、`apps/basic`、`apps/with-lingui`)同仓维护。 +## 内容目录(侧栏分组) + +| 分组 | 路径(`content/` 下) | +|------|------------------------| +| 概述 | `index.mdx` | +| 欢迎 | `welcome/documentation-intro.mdx` | +| 入门 | `getting-started/`(快速开始、`folder-structure`、`available-scripts` …) | +| 模板 | `templates/`(模板列表、`basic`、`with-lingui`) | +| 开发 | `development/` | +| 样式与资源 | `styles-and-assets/` | +| 构建应用 | `building/` | +| 测试 | `testing/` | +| 后端对接 | `backend/` | +| 部署 | `deployment/` | + +侧边栏顺序与标题由各目录旁 `_meta.js` 及根目录 `content/_meta.js` 配置。 + ## 端口说明 | 项目 | 默认开发地址 | @@ -29,4 +46,4 @@ cd apps/docs && pnpm install && pnpm dev ## 设计说明 -实现与信息架构见:`docs/specs/2026-04-15-apps-docs-nextra-plan.md`(及同目录 design spec,若存在)。 +初始实现见 `docs/specs/2026-04-15-apps-docs-nextra-plan.md`。 diff --git a/apps/docs/content/_meta.js b/apps/docs/content/_meta.js new file mode 100644 index 0000000..5334722 --- /dev/null +++ b/apps/docs/content/_meta.js @@ -0,0 +1,13 @@ +/** @type {import('nextra').MetaRecord} */ +export default { + index: "概述", + welcome: "欢迎", + "getting-started": "入门", + templates: "模板", + development: "开发", + "styles-and-assets": "样式与资源", + building: "构建应用", + testing: "测试", + backend: "后端对接", + deployment: "部署", +}; diff --git a/apps/docs/content/backend/_meta.js b/apps/docs/content/backend/_meta.js new file mode 100644 index 0000000..ce2e8a2 --- /dev/null +++ b/apps/docs/content/backend/_meta.js @@ -0,0 +1,4 @@ +/** @type {import('nextra').MetaRecord} */ +export default { + "proxying-api-requests": "开发代理与 Mock", +}; diff --git a/apps/docs/content/backend/proxying-api-requests.mdx b/apps/docs/content/backend/proxying-api-requests.mdx new file mode 100644 index 0000000..1772bc7 --- /dev/null +++ b/apps/docs/content/backend/proxying-api-requests.mdx @@ -0,0 +1,18 @@ +--- +title: 开发代理与 Mock +description: MSW、API 基地址与对接真实后端 +--- + +# 开发代理与 Mock + +## MSW(开发默认) + +模板在开发环境使用 **MSW** 拦截 HTTP,**handlers** 位于 `src/mocks/handlers`。无后端即可演示登录、菜单、用户 CRUD 等。 + +**Worker 目录**由 `package.json` 的 **`msw.workerDirectory`** 配置为 `public`,与 [public 目录](/styles-and-assets/public-folder) 说明一致。 + +## 对接真实 API + +将 **`src/utils/http.ts`(或项目内统一 HTTP 封装)** 中的 **baseURL** 指向真实网关,并按环境关闭或绕过 MSW 初始化(具体开关以模板 `main.tsx` / 环境变量为准)。 + +跨域时需由**浏览器可访问**的网关配置 **CORS**;或通过开发代理将 `/api` 转发到后端(在 `vite.config.ts` 配置 `server.proxy`,按团队规范填写目标地址)。 diff --git a/apps/docs/content/building/_meta.js b/apps/docs/content/building/_meta.js new file mode 100644 index 0000000..817f3d4 --- /dev/null +++ b/apps/docs/content/building/_meta.js @@ -0,0 +1,7 @@ +/** @type {import('nextra').MetaRecord} */ +export default { + router: "路由", + "environment-variables": "环境变量", + performance: "性能测量", + "production-build": "生产构建", +}; diff --git a/apps/docs/content/building/environment-variables.mdx b/apps/docs/content/building/environment-variables.mdx new file mode 100644 index 0000000..bdf696f --- /dev/null +++ b/apps/docs/content/building/environment-variables.mdx @@ -0,0 +1,12 @@ +--- +title: 环境变量 +description: Vite 环境变量与 import.meta.env +--- + +# 环境变量 + +模板使用 **Vite**,请在 `.env`、`.env.development`、`.env.production` 等文件中定义变量,且 **客户端可访问的变量必须以 `VITE_` 前缀** 暴露。 + +在代码中通过 **`import.meta.env.VITE_*`** 读取。API 基地址等常量见各应用 **`src/utils/constants.ts`** 及 README。 + +不要把密钥写入前端可见的 `VITE_` 变量;敏感逻辑放在后端或构建时注入的服务端配置中。 diff --git a/apps/docs/content/building/performance.mdx b/apps/docs/content/building/performance.mdx new file mode 100644 index 0000000..0b85cff --- /dev/null +++ b/apps/docs/content/building/performance.mdx @@ -0,0 +1,11 @@ +--- +title: 性能测量 +description: 开发与生产环境下的性能关注点 +--- + +# 性能测量 + +- **开发**:关注 React/Ant Design 不必要的重渲染与过大列表;表格场景可结合虚拟滚动等方案(按需引入)。 +- **生产**:使用浏览器 **Performance / Lighthouse** 与 **`vp build`** 产物体积联合判断。 + +模板未内置专用 APM;接入外部监控时请在隐私与合规前提下配置采样率与错误上报范围。 diff --git a/apps/docs/content/building/production-build.mdx b/apps/docs/content/building/production-build.mdx new file mode 100644 index 0000000..c6e852a --- /dev/null +++ b/apps/docs/content/building/production-build.mdx @@ -0,0 +1,17 @@ +--- +title: 生产构建 +description: vp build 与预览 +--- + +# 生产构建 + +在各模板目录: + +```bash +vp build +vp preview +``` + +模板 `package.json` 中 **`build`** 脚本通常包含 **`tsc`** 与 **`vp build`**,请先通过类型检查再部署产物。 + +静态资源托管时,注意 **SPA 回退路由**(所有前端路径回退到 `index.html`)。若部署在子路径,需配置 Vite **`base`** 与路由一致。 diff --git a/apps/docs/content/building/router.mdx b/apps/docs/content/building/router.mdx new file mode 100644 index 0000000..c98e074 --- /dev/null +++ b/apps/docs/content/building/router.mdx @@ -0,0 +1,16 @@ +--- +title: 路由 +description: TanStack Router 文件路由与布局 +--- + +# 路由 + +模板使用 **[TanStack Router](https://tanstack.com/router)** **文件路由**(插件根据 `src/routes` 生成 **`routeTree.gen.ts`**)。 + +常见模式: + +- **根布局**:`__root.tsx` 中包裹 `ConfigProvider`、Outlet 等。 +- **认证布局**:如 `_auth.tsx`,与登录页路由分离。 +- **鉴权**:在路由 `beforeLoad` 或组件内结合 **权限与 `/login` 跳转**(实现以模板代码为准)。 + +新增业务页时,在同目录追加路由文件并遵循现有目录约定;类型安全依赖生成的 route tree。 diff --git a/apps/docs/content/configuration.mdx b/apps/docs/content/configuration.mdx deleted file mode 100644 index 44fc3e9..0000000 --- a/apps/docs/content/configuration.mdx +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: 配置参考 -description: 环境变量与构建相关简短说明 ---- - -# 配置参考 - -## 模板应用(`apps/basic`、`apps/with-lingui`) - -- 使用 **Vite+**(`vp`)管理依赖与开发/构建;具体脚本见各目录 `package.json`。 -- **MSW** 在开发环境拦截 API;worker 目录由各应用 `package.json` 的 `msw.workerDirectory` 配置。 -- 更完整的栈说明、目录树与测试命令见对应应用的 **README**(仓库内 `apps/basic/README.md`、`apps/with-lingui/README.md`)。 - -## 文档站(`apps/docs`) - -- **Next.js + Nextra**,无首期 `basePath`;生产构建:`pnpm run build`。 -- 本地开发端口 **3000**,见 [apps/docs README](https://github.com/zuiidea/antd-admin/blob/master/apps/docs/README.md) 与设计说明 `docs/specs/2026-04-15-apps-docs-nextra-design.md`(若存在于仓库中)。 diff --git a/apps/docs/content/deployment/index.mdx b/apps/docs/content/deployment/index.mdx new file mode 100644 index 0000000..8b394fe --- /dev/null +++ b/apps/docs/content/deployment/index.mdx @@ -0,0 +1,20 @@ +--- +title: 部署 +sidebarTitle: 部署 +description: 静态资源托管与 SPA 路由 +asIndexPage: true +--- + +# 部署 + +## 构建产物 + +执行 **`vp build`** 后,产物默认位于各应用约定的 **`dist/`**(以 Vite 输出为准)。将 **`dist`** 部署到静态文件托管(OSS、CDN、Netlify、Vercel 等)。 + +## SPA 路由 + +前端路由由 **TanStack Router** 管理,服务器需将所有 **文档路径回退到 `index.html`**,否则刷新子路径会 **404**。 + +## 应用若部署在子路径 + +设置 Vite **`base`** 为子路径前缀,并确保静态资源与路由跳转使用该前缀。仓库内若包含 **`vercel.json`** 等,可作为部署规则参考。 diff --git a/apps/docs/content/development/_meta.js b/apps/docs/content/development/_meta.js new file mode 100644 index 0000000..39a4b87 --- /dev/null +++ b/apps/docs/content/development/_meta.js @@ -0,0 +1,5 @@ +/** @type {import('nextra').MetaRecord} */ +export default { + "bundle-analysis": "构建体积分析", + "https-in-development": "开发环境 HTTPS", +}; diff --git a/apps/docs/content/development/bundle-analysis.mdx b/apps/docs/content/development/bundle-analysis.mdx new file mode 100644 index 0000000..e54e116 --- /dev/null +++ b/apps/docs/content/development/bundle-analysis.mdx @@ -0,0 +1,13 @@ +--- +title: 构建体积分析 +description: 查看打包体积与依赖分布的常用方式 +--- + +# 构建体积分析 + +模板使用 **Vite**(经 Vite+ 调用)。分析产物体积的常见做法: + +1. **`vp build`** 后查看终端输出的 chunk 大小汇总。 +2. 需要可视化时,可在应用内按需接入 **rollup-plugin-visualizer**(或等价插件)生成 `stats.html`,再打开报告查看各模块占比。 + +本仓库模板**默认不内置**可视化分析插件;按需添加后记得仅在分析构建 profile 下启用,避免常驻增加配置复杂度。 diff --git a/apps/docs/content/development/https-in-development.mdx b/apps/docs/content/development/https-in-development.mdx new file mode 100644 index 0000000..4270f71 --- /dev/null +++ b/apps/docs/content/development/https-in-development.mdx @@ -0,0 +1,10 @@ +--- +title: 开发环境 HTTPS +description: 本地启用 HTTPS 时的提示 +--- + +# 开发环境 HTTPS + +若需在开发环境启用 **HTTPS**(例如调试安全 Cookie、第三方 OAuth 回调),请参考 [Vite 服务器 HTTPS 配置](https://vite.dev/config/server-options.html#server-https):在模板 `vite.config.ts` 的 `server.https` 中配置证书,或通过 `vp dev` 支持的参数透传(以 Vite+ 当前版本文档为准)。 + +团队应统一证书来源(如 mkcert),并在文档中注明 **勿将私钥提交到仓库**。 diff --git a/apps/docs/content/features.mdx b/apps/docs/content/features.mdx deleted file mode 100644 index 1a602a5..0000000 --- a/apps/docs/content/features.mdx +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: 功能与约定 -description: 能力概览并指向各应用 README 与源码 ---- - -# 功能与约定 - -本 monorepo 在 **`apps/basic`** 与 **`apps/with-lingui`** 中提供同一套产品能力(JWT、动态菜单与 RBAC、表格 URL 状态、MSW、Playwright 等)。差异主要在 **国际化与包名**,详见 [模板对比](/templates)。 - -## 进一步阅读 - -- **Basic 应用说明:** [apps/basic/README.md](https://github.com/zuiidea/antd-admin/blob/master/apps/basic/README.md) -- **Lingui 变体说明:** [apps/with-lingui/README.md](https://github.com/zuiidea/antd-admin/blob/master/apps/with-lingui/README.md) -- **通用 AI 指引(Vite+):** 各应用目录下的 `AGENTS.md` - -## 源码入口(便于跳转) - -| 主题 | 路径(两应用结构类似) | -|------|-------------------------| -| 根路由与 Ant Design 包裹 | `src/routes/__root.tsx` | -| 持久化 Store 工厂 | `src/stores/createPersistentStore.ts` | -| 设置与主题 | `src/stores/settings.ts` | diff --git a/apps/docs/content/getting-started/_meta.js b/apps/docs/content/getting-started/_meta.js new file mode 100644 index 0000000..abecb0f --- /dev/null +++ b/apps/docs/content/getting-started/_meta.js @@ -0,0 +1,8 @@ +/** @type {import('nextra').MetaRecord} */ +export default { + "folder-structure": "目录结构", + "available-scripts": "可用脚本", + "supported-browsers": "浏览器与运行环境", + "supported-features": "模板自带能力", + "updating-releases": "升级与更新", +}; diff --git a/apps/docs/content/getting-started/available-scripts.mdx b/apps/docs/content/getting-started/available-scripts.mdx new file mode 100644 index 0000000..fc4819d --- /dev/null +++ b/apps/docs/content/getting-started/available-scripts.mdx @@ -0,0 +1,43 @@ +--- +title: 可用脚本 +description: package.json 中与开发相关的 npm 脚本 +--- + +# 可用脚本 + +在模板目录执行(需先 `vp install`)。两模板大部分脚本相同;**仅 with-lingui** 含 `i18n:*` 脚本。 + +## 开发与构建 + +| 脚本 | 说明 | +|------|------| +| `vp dev` | 启动开发服务器(默认端口 5173) | +| `vp build` | 生产构建(模板中常与 `tsc` 组合,见各 `package.json`) | +| `vp preview` | 预览构建产物 | + +## 质量 + +| 脚本 | 说明 | +|------|------| +| `vp fmt` | 格式化 | +| `vp lint` | Lint | +| `vp check --no-fmt` | 类型检查等(模板内常用 `check`) | + +## 测试 + +| 脚本 | 说明 | +|------|------| +| `pnpm run test:unit` | Vitest 单元测试 | +| `pnpm run test:e2e` | Playwright 全部 E2E | +| `pnpm run test:e2e:core` | 核心场景子集(登录、users CRUD、refresh、RBAC、URL 状态) | +| `pnpm run test:e2e:ui` | Playwright UI 模式 | + +## With Lingui 专有 + +| 脚本 | 说明 | +|------|------| +| `pnpm run i18n:extract` | 抽取文案 | +| `pnpm run i18n:compile` | 编译 catalog | +| `pnpm run i18n:check` | 抽取后校验 git diff(CI 友好) | + +具体以各应用 **`package.json` 的 `scripts`** 为准。 diff --git a/apps/docs/content/getting-started/folder-structure.mdx b/apps/docs/content/getting-started/folder-structure.mdx new file mode 100644 index 0000000..7444f61 --- /dev/null +++ b/apps/docs/content/getting-started/folder-structure.mdx @@ -0,0 +1,25 @@ +--- +title: 目录结构 +description: 模板应用 src 目录职责说明 +--- + +# 目录结构 + +两个模板的目录高度一致,差异主要在 **i18n(`locales/`)** 与 **部分脚本**。以下以 `apps/with-lingui` 为例(`apps/basic` 无 `locales/`,且无 Lingui 相关脚本)。 + +``` +src/ +├── api/ # Zod schema、接口常量与类型 +├── components/ # 通用 UI(表格壳、表单弹窗、布局等) +├── hooks/ # 主题、权限、CRUD 等组合逻辑 +├── locales/ # Lingui:仅 with-lingui(en/zh .po) +├── mocks/ # MSW handlers 与浏览器 worker +├── routes/ # TanStack Router 文件路由 +├── stores/ # Zustand(auth、settings 等持久化) +└── utils/ # HTTP 客户端、常量等 +``` + +更完整的树状说明见: + +- [apps/basic/README.md](https://github.com/zuiidea/antd-admin/blob/master/apps/basic/README.md) +- [apps/with-lingui/README.md](https://github.com/zuiidea/antd-admin/blob/master/apps/with-lingui/README.md) diff --git a/apps/docs/content/quick-start.mdx b/apps/docs/content/getting-started/index.mdx similarity index 95% rename from apps/docs/content/quick-start.mdx rename to apps/docs/content/getting-started/index.mdx index 58bba7d..eebd165 100644 --- a/apps/docs/content/quick-start.mdx +++ b/apps/docs/content/getting-started/index.mdx @@ -1,6 +1,8 @@ --- title: 快速开始 +sidebarTitle: 快速开始 description: 环境要求、安装与本地运行(文档站与模板端口) +asIndexPage: true --- # 快速开始 diff --git a/apps/docs/content/getting-started/supported-browsers.mdx b/apps/docs/content/getting-started/supported-browsers.mdx new file mode 100644 index 0000000..0743aed --- /dev/null +++ b/apps/docs/content/getting-started/supported-browsers.mdx @@ -0,0 +1,17 @@ +--- +title: 浏览器与运行环境 +description: Node 版本与现代浏览器支持 +--- + +# 浏览器与运行环境 + +## Node.js + +- **要求 ≥ 20**(与仓库及 Vite+ 工具链一致)。 +- 推荐使用与 `package.json` 中 **`packageManager`** 一致的 pnpm 版本,团队协作可减少锁文件漂移。 + +## 浏览器 + +模板面向 **现代 evergreen 浏览器**(Chromium / Firefox / Safari 近年版本)。后台场景通常不要求 IE。 + +本地开发时使用 **HTTPS**、旧版浏览器或嵌入式 WebView 等约束,参见 [开发环境 HTTPS](/development/https-in-development)。 diff --git a/apps/docs/content/getting-started/supported-features.mdx b/apps/docs/content/getting-started/supported-features.mdx new file mode 100644 index 0000000..1ad5e75 --- /dev/null +++ b/apps/docs/content/getting-started/supported-features.mdx @@ -0,0 +1,20 @@ +--- +title: 模板自带能力 +description: 两模板共同具备的产品与技术能力 +--- + +# 模板自带能力 + +**`apps/basic`** 与 **`apps/with-lingui`** 在业务能力上对齐,差异主要在 **国际化与包名、持久化键**等(见 [模板列表](/templates))。 + +两模板均包含: + +- **JWT 登录**:access / refresh,Zustand 持久化 +- **动态菜单与 RBAC**:服务端菜单、路由权限、403 +- **表格 URL 状态**:分页、关键字、排序等与查询参数同步 +- **MSW**:开发环境 Mock,无需真实后端即可跑通流程 +- **Playwright E2E**:覆盖登录、CRUD、鉴权刷新、RBAC、URL 状态等(`test:e2e:core` 为核心子集) + +**With Lingui** 额外包含:LinguiJS 中英文、Ant Design locale 随语言切换、`.po` 抽取/编译工作流。 + +权威细节与代码入口仍以各应用 **README** 与 `src/` 为准;本页用于快速对齐「能做什么」。 diff --git a/apps/docs/content/getting-started/updating-releases.mdx b/apps/docs/content/getting-started/updating-releases.mdx new file mode 100644 index 0000000..b82d72f --- /dev/null +++ b/apps/docs/content/getting-started/updating-releases.mdx @@ -0,0 +1,19 @@ +--- +title: 升级与更新 +description: 依赖与模板演进时的建议 +--- + +# 升级与更新 + +## 依赖升级 + +- 使用 **Vite+**(`vp`)管理依赖,避免绕过 `vp` 直接大面积 `pnpm up` 导致与模板锁定的工具链不一致。 +- 升级 **Ant Design / TanStack / React** 大版本前,建议先阅读官方迁移说明,并在单分支上跑通 `vp check`、`test:unit`、`test:e2e:core` 与 `vp build`。 + +## 跟随本仓库模板 + +若从本 monorepo 拷贝或对比模板代码,可用 `git` 按需 cherry-pick 改动,并注意 **`apps/basic` 与 `apps/with-lingui` 在 i18n 与文案上的差异**,避免把 Lingui 专用改动误合并到 basic。 + +## With Lingui 文案 + +升级 `@lingui/*` 后建议执行 `pnpm run i18n:extract` 与 `pnpm run i18n:compile`,并检查 `src/locales` 是否有冲突或弃用 API。 diff --git a/apps/docs/content/index.mdx b/apps/docs/content/index.mdx index d59e853..a87e7ad 100644 --- a/apps/docs/content/index.mdx +++ b/apps/docs/content/index.mdx @@ -1,8 +1,12 @@ --- title: 概述 -description: antd-admin monorepo 与模板说明 +description: antd-admin monorepo 与文档导读 --- # 概述 -本仓库提供两个可运行模板:**`apps/basic`**(英文-only)与 **`apps/with-lingui`**(Lingui 中英文)。详细对比见「模板对比」。 +本仓库提供两个可运行的后台管理模板:**[`apps/basic`](https://github.com/zuiidea/antd-admin/tree/master/apps/basic)**(英文界面)与 **[`apps/with-lingui`](https://github.com/zuiidea/antd-admin/tree/master/apps/with-lingui)**(Lingui 中英文)。技术栈以 **React 19、Ant Design 6、TanStack Router & Query、Vite+(`vp`)、MSW、Playwright** 为核心。 + +侧栏按「欢迎 → 入门 → 模板 → 开发 → 样式与资源 → 构建 → 测试 → 后端对接 → 部署」组织。建议从 **[入门](/getting-started)** 开始,再在 **[模板](/templates)** 中选择应用。 + +GitHub:[zuiidea/antd-admin](https://github.com/zuiidea/antd-admin) diff --git a/apps/docs/content/styles-and-assets/_meta.js b/apps/docs/content/styles-and-assets/_meta.js new file mode 100644 index 0000000..884bcd3 --- /dev/null +++ b/apps/docs/content/styles-and-assets/_meta.js @@ -0,0 +1,8 @@ +/** @type {import('nextra').MetaRecord} */ +export default { + stylesheet: "添加样式", + "css-modules": "CSS Modules", + "images-fonts-files": "图片、字体与静态文件", + "public-folder": "public 目录", + "code-splitting": "代码分割", +}; diff --git a/apps/docs/content/styles-and-assets/code-splitting.mdx b/apps/docs/content/styles-and-assets/code-splitting.mdx new file mode 100644 index 0000000..141d4f2 --- /dev/null +++ b/apps/docs/content/styles-and-assets/code-splitting.mdx @@ -0,0 +1,10 @@ +--- +title: 代码分割 +description: 动态 import 与路由懒加载 +--- + +# 代码分割 + +基于 **Vite** 与 **TanStack Router**,可按路由或大屏块使用 **`import()` 动态导入** 实现懒加载,减小首屏 bundle。 + +拆分粒度需在「首屏体验」与「请求次数」之间权衡;后台系统常见做法是对低频管理页做 lazy,对登录后首屏必要依赖保持同步加载。 diff --git a/apps/docs/content/styles-and-assets/css-modules.mdx b/apps/docs/content/styles-and-assets/css-modules.mdx new file mode 100644 index 0000000..6b13d24 --- /dev/null +++ b/apps/docs/content/styles-and-assets/css-modules.mdx @@ -0,0 +1,10 @@ +--- +title: CSS Modules +description: 组件旁 *.module.css 的用法提示 +--- + +# CSS Modules + +可在组件旁增加 **`*.module.css`**,由 Vite 按模块作用域编译,避免类名污染全局。 + +布局与侧边栏等目录下已有 **少量 `.css` 与组件同目录** 的写法,可按相同模式扩展。与 Ant Design 共存时,注意层级与 `:global` 的使用范围,避免破坏组件库默认样式。 diff --git a/apps/docs/content/styles-and-assets/images-fonts-files.mdx b/apps/docs/content/styles-and-assets/images-fonts-files.mdx new file mode 100644 index 0000000..e76331b --- /dev/null +++ b/apps/docs/content/styles-and-assets/images-fonts-files.mdx @@ -0,0 +1,11 @@ +--- +title: 图片、字体与静态文件 +description: 资源放置与引用方式 +--- + +# 图片、字体与静态文件 + +- **`src/` 内 import**:图片等可作为模块 import,适合需要哈希与打包优化的资源。 +- **`public/`**:适合固定 URL、不经打包处理的静态文件(见 [public 目录](/styles-and-assets/public-folder))。 + +字体文件若体积较大,注意浏览器加载策略与子集化,避免阻塞首屏。 diff --git a/apps/docs/content/styles-and-assets/public-folder.mdx b/apps/docs/content/styles-and-assets/public-folder.mdx new file mode 100644 index 0000000..28cd65c --- /dev/null +++ b/apps/docs/content/styles-and-assets/public-folder.mdx @@ -0,0 +1,10 @@ +--- +title: public 目录 +description: public 与 MSW Service Worker +--- + +# public 目录 + +模板将 **`public/`** 用于不会被 bundler 改名的静态资源(如 `favicon`)。 + +同时,**MSW** 浏览器端 worker 的路径由 **`package.json` → `msw.workerDirectory`** 指向 `public`(两模板一致)。调整 `public` 结构时注意 **不要破坏 Mock Service Worker** 所需的生成文件与服务注册路径。 diff --git a/apps/docs/content/styles-and-assets/stylesheet.mdx b/apps/docs/content/styles-and-assets/stylesheet.mdx new file mode 100644 index 0000000..fcbdf15 --- /dev/null +++ b/apps/docs/content/styles-and-assets/stylesheet.mdx @@ -0,0 +1,13 @@ +--- +title: 添加样式 +description: 全局样式与 Ant Design 主题入口 +--- + +# 添加样式 + +模板通常包含: + +- **全局样式**:如 `src/index.css`,用于 reset、滚动条或少量全局覆盖。 +- **Ant Design 主题**:通过 `ConfigProvider` 与项目内 **`tokenBuilders` / `useAppTheme`** 等组合(见 `src/hooks`、`src/routes/__root.tsx`)。 + +新增页面级样式时,优先使用 **Ant Design 组件与 token**,减少全局 `!important`;必要时再使用 CSS 文件或 CSS Modules(见下一节)。 diff --git a/apps/docs/content/templates/_meta.js b/apps/docs/content/templates/_meta.js new file mode 100644 index 0000000..4477e5b --- /dev/null +++ b/apps/docs/content/templates/_meta.js @@ -0,0 +1,5 @@ +/** @type {import('nextra').MetaRecord} */ +export default { + basic: "Basic", + "with-lingui": "With Lingui", +}; diff --git a/apps/docs/content/templates/basic.mdx b/apps/docs/content/templates/basic.mdx new file mode 100644 index 0000000..657f956 --- /dev/null +++ b/apps/docs/content/templates/basic.mdx @@ -0,0 +1,30 @@ +--- +title: Basic 模板 +description: apps/basic — 英文-only 模板说明摘要 +--- + +# Basic 模板 + +路径:**[`apps/basic`](https://github.com/zuiidea/antd-admin/tree/master/apps/basic)**。 + +## 定位 + +英文界面、**不包含 Lingui**;Ant Design 使用固定 **`en_US`** locale。依赖相对精简,适合只需英文后台或自行接入其它 i18n 方案的团队。 + +## 技术栈摘要 + +构建:[Vite+](https://viteplus.dev);UI:Ant Design 6;路由:TanStack Router;数据:TanStack Query;本地状态:Zustand;校验:Zod;Mock:MSW;E2E:Playwright。 + +## 常用命令 + +```bash +cd apps/basic +vp install +vp dev +``` + +详见 **[可用脚本](/getting-started/available-scripts)** 与各应用 `package.json`。 + +## 权威文档 + +完整特性、目录树与脚本说明以仓库内 **[apps/basic/README.md](https://github.com/zuiidea/antd-admin/blob/master/apps/basic/README.md)** 为准。 diff --git a/apps/docs/content/templates.mdx b/apps/docs/content/templates/index.mdx similarity index 63% rename from apps/docs/content/templates.mdx rename to apps/docs/content/templates/index.mdx index 43e157e..3352f23 100644 --- a/apps/docs/content/templates.mdx +++ b/apps/docs/content/templates/index.mdx @@ -1,9 +1,11 @@ --- -title: 模板对比 -description: basic 与 with-lingui 的包名、国际化与持久化键对比 +title: 模板列表 +sidebarTitle: 模板列表 +description: Basic 与 With Lingui 的选型与差异总览 +asIndexPage: true --- -# 模板对比 +# 模板列表 以下字段以仓库内 **`package.json`** 与 **`src/stores/settings.ts`** 为准。 @@ -14,7 +16,12 @@ description: basic 与 with-lingui 的包名、国际化与持久化键对比 | **Ant Design `ConfigProvider` locale** | 固定 `antd/locale/en_US` | 随设置切换:`en` → `en_US`,`zh` → `zh_CN`(见 `src/routes/__root.tsx`) | | **Zustand persist(settings)`name`** | `settings-storage-basic` | `settings-storage` | -选型建议: +## 选型建议 -- 只要英文、希望依赖最少:选 **`apps/basic`**。 -- 需要中英文切换、Lingui 工作流与 Ant Design 随语言联动:选 **`apps/with-lingui`**。 +- 只要英文、希望依赖最少:选 **[Basic](/templates/basic)**。 +- 需要中英文切换、Lingui 工作流与 Ant Design 随语言联动:选 **[With Lingui](/templates/with-lingui)**。 + +## 子页面 + +- [Basic 模板](/templates/basic) +- [With Lingui 模板](/templates/with-lingui) diff --git a/apps/docs/content/templates/with-lingui.mdx b/apps/docs/content/templates/with-lingui.mdx new file mode 100644 index 0000000..e220578 --- /dev/null +++ b/apps/docs/content/templates/with-lingui.mdx @@ -0,0 +1,36 @@ +--- +title: With Lingui 模板 +description: apps/with-lingui — 中英双语与 Lingui 工作流 +--- + +# With Lingui 模板 + +路径:**[`apps/with-lingui`](https://github.com/zuiidea/antd-admin/tree/master/apps/with-lingui)**。 + +## 定位 + +在 Basic 能力集之上提供 **LinguiJS** 中英双语文案、**Ant Design locale** 与语言设置联动,以及 **`.po` 抽取/编译** 流程。为仓库中更完整的一号模板(`package.json` 的 `name` 为 `antd-admin`)。 + +## 技术栈补充 + +在 Basic 技术栈基础上增加 Lingui 6;`src/locales/{en,zh}/messages.po` 为翻译源;`lingui.config.ts` 与 Vite 插件见应用内配置。 + +## 国际化命令 + +| 命令 | 作用 | +|------|------| +| `pnpm run i18n:extract` | 从源码抽取可翻译字符串 | +| `pnpm run i18n:compile` | 编译为运行时可加载的 message | +| `pnpm run i18n:check` | 抽取后检查工作区无未提交变更(适合 CI) | + +## 常用命令 + +```bash +cd apps/with-lingui +vp install +vp dev +``` + +## 权威文档 + +完整技术栈表、功能列表、目录树、E2E 子集说明、以及 **Cursor 与 `.github/instructions` 的 AI 指引** 以 **[apps/with-lingui/README.md](https://github.com/zuiidea/antd-admin/blob/master/apps/with-lingui/README.md)** 为准。 diff --git a/apps/docs/content/testing/_meta.js b/apps/docs/content/testing/_meta.js new file mode 100644 index 0000000..90775f5 --- /dev/null +++ b/apps/docs/content/testing/_meta.js @@ -0,0 +1,5 @@ +/** @type {import('nextra').MetaRecord} */ +export default { + "running-tests": "运行测试", + "debugging-tests": "调试测试", +}; diff --git a/apps/docs/content/testing/debugging-tests.mdx b/apps/docs/content/testing/debugging-tests.mdx new file mode 100644 index 0000000..5e5e3c4 --- /dev/null +++ b/apps/docs/content/testing/debugging-tests.mdx @@ -0,0 +1,16 @@ +--- +title: 调试测试 +description: Playwright 调试与 UI 模式 +--- + +# 调试测试 + +- **UI 模式**(模板已提供脚本): + +```bash +pnpm run test:e2e:ui +``` + +- ** headed / debug**:可使用 Playwright CLI 标志对单测文件调试,例如 `pnpm exec playwright test --debug`。 + +MSW 与真实网络环境差异可能导致用例不稳定;调试时可先确认 **Mock 是否按预期拦截**(见 [开发代理与 Mock](/backend/proxying-api-requests))。 diff --git a/apps/docs/content/testing/running-tests.mdx b/apps/docs/content/testing/running-tests.mdx new file mode 100644 index 0000000..ef87278 --- /dev/null +++ b/apps/docs/content/testing/running-tests.mdx @@ -0,0 +1,23 @@ +--- +title: 运行测试 +description: Vitest 单元测试与 Playwright E2E +--- + +# 运行测试 + +## 单元测试(Vitest) + +```bash +pnpm run test:unit +``` + +由 **Vite+** 封装 Vitest,请勿脱离 `vp`/`pnpm scripts` 随意单独安装冲突版本的 Vitest(参见各应用 **`AGENTS.md`**)。 + +## E2E(Playwright) + +```bash +pnpm run test:e2e # 全部 +pnpm run test:e2e:core # 核心子集(登录、users、refresh、RBAC、URL 状态) +``` + +首次在机器上跑 E2E 前,按 Playwright 文档安装浏览器依赖(`pnpm exec playwright install` 等,以官方说明为准)。 diff --git a/apps/docs/content/welcome/_meta.js b/apps/docs/content/welcome/_meta.js new file mode 100644 index 0000000..de623a0 --- /dev/null +++ b/apps/docs/content/welcome/_meta.js @@ -0,0 +1,4 @@ +/** @type {import('nextra').MetaRecord} */ +export default { + "documentation-intro": "文档介绍", +}; diff --git a/apps/docs/content/welcome/documentation-intro.mdx b/apps/docs/content/welcome/documentation-intro.mdx new file mode 100644 index 0000000..c926d97 --- /dev/null +++ b/apps/docs/content/welcome/documentation-intro.mdx @@ -0,0 +1,25 @@ +--- +title: 文档介绍 +description: 本文档的阅读方式与章节说明 +--- + +# 文档介绍 + +欢迎使用 **Antd Admin** 模板文档。本站与模板应用(`apps/basic`、`apps/with-lingui`)同仓维护,面向在前台仓库中选型、运行与扩展模板的开发者。 + +## 章节结构 + +| 章节 | 内容侧重 | +|------|-----------| +| **概述** | 仓库与模板一句话定位 | +| **欢迎 · 文档介绍** | 本节:导航说明 | +| **入门** | 环境、目录、脚本、浏览器支持、模板能力、升级提示 | +| **模板** | [模板列表](/templates):Basic / With Lingui 选型与子页 | +| **开发** | 本地开发、体积分析、HTTPS 等 | +| **样式与资源** | 全局样式、CSS Modules、静态资源、public、代码分割 | +| **构建应用** | 路由、环境变量、性能、生产构建 | +| **测试** | 单元测试与 E2E | +| **后端对接** | MSW Mock、API 基地址与代理思路 | +| **部署** | 构建产物与部署注意点 | + +更完整的模板说明仍以仓库内 **`apps/*/README.md`** 为准;本站用中文串联常用路径,减少在 GitHub 间跳转的成本。 diff --git a/apps/docs/next-env.d.ts b/apps/docs/next-env.d.ts index 830fb59..c4b7818 100644 --- a/apps/docs/next-env.d.ts +++ b/apps/docs/next-env.d.ts @@ -1,6 +1,6 @@ /// /// -/// +import "./.next/dev/types/routes.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/apps/docs/package.json b/apps/docs/package.json index 63b7992..f37b8e5 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -3,25 +3,25 @@ "version": "0.0.0", "private": true, "scripts": { - "dev": "next dev -p 3000", + "dev": "next dev -p 3003", "build": "next build", "start": "next start -p 3000", "lint": "next lint" }, "dependencies": { - "next": "^15.1.0", - "react": "^19.0.0", - "react-dom": "^19.0.0", - "nextra": "^4.0.0", - "nextra-theme-docs": "^4.0.0" + "next": "^16.2.4", + "react": "^19.2.5", + "react-dom": "^19.2.5", + "nextra": "^4.6.1", + "nextra-theme-docs": "^4.6.1" }, "devDependencies": { - "@eslint/eslintrc": "^3.2.0", - "@types/node": "^22.0.0", - "@types/react": "^19.0.0", - "@types/react-dom": "^19.0.0", - "typescript": "~5.9.0", - "eslint": "^9.0.0", - "eslint-config-next": "^15.1.0" + "@eslint/eslintrc": "^3.3.5", + "@types/node": "^25.6.0", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "typescript": "~6.0.3", + "eslint": "^10.2.1", + "eslint-config-next": "^16.2.4" } -} +} \ No newline at end of file diff --git a/apps/docs/middleware.ts b/apps/docs/proxy.ts similarity index 93% rename from apps/docs/middleware.ts rename to apps/docs/proxy.ts index a3df506..c5088b8 100644 --- a/apps/docs/middleware.ts +++ b/apps/docs/proxy.ts @@ -5,7 +5,7 @@ import { NextResponse } from "next/server"; * Browsers or other localhost apps (e.g. MSW) may request `/mockServiceWorker.js`. * Without this, the request hits `[[...mdxPath]]` and Nextra tries to load it as MDX. */ -export function middleware(request: NextRequest) { +export function proxy(request: NextRequest) { if (request.nextUrl.pathname === "/mockServiceWorker.js") { return new NextResponse( "// antd-admin docs: no MSW; unregister stray workers from other localhost apps if needed.\n", diff --git a/apps/docs/tsconfig.json b/apps/docs/tsconfig.json index afedc74..803331c 100644 --- a/apps/docs/tsconfig.json +++ b/apps/docs/tsconfig.json @@ -1,7 +1,11 @@ { "compilerOptions": { "target": "ES2022", - "lib": ["dom", "dom.iterable", "esnext"], + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], "allowJs": true, "skipLibCheck": true, "strict": true, @@ -11,11 +15,27 @@ "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, - "jsx": "preserve", + "jsx": "react-jsx", "incremental": true, - "plugins": [{ "name": "next" }], - "paths": { "@/*": ["./*"] } + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": [ + "./*" + ] + } }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], - "exclude": ["node_modules"] + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + ".next/dev/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 93032d4..eb41ffd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -79,42 +79,42 @@ importers: apps/docs: dependencies: next: - specifier: ^15.1.0 - version: 15.5.15(react-dom@19.2.5)(react@19.2.5) + specifier: ^16.2.4 + version: 16.2.4(@babel/core@7.29.0)(react-dom@19.2.5)(react@19.2.5) nextra: - specifier: ^4.0.0 - version: 4.6.1(next@15.5.15)(react-dom@19.2.5)(react@19.2.5)(typescript@5.9.3) + specifier: ^4.6.1 + version: 4.6.1(next@16.2.4)(react-dom@19.2.5)(react@19.2.5)(typescript@6.0.3) nextra-theme-docs: - specifier: ^4.0.0 - version: 4.6.1(@types/react@19.2.14)(next@15.5.15)(nextra@4.6.1)(react-dom@19.2.5)(react@19.2.5) + specifier: ^4.6.1 + version: 4.6.1(@types/react@19.2.14)(next@16.2.4)(nextra@4.6.1)(react-dom@19.2.5)(react@19.2.5) react: - specifier: ^19.0.0 + specifier: ^19.2.5 version: 19.2.5 react-dom: - specifier: ^19.0.0 + specifier: ^19.2.5 version: 19.2.5(react@19.2.5) devDependencies: '@eslint/eslintrc': - specifier: ^3.2.0 + specifier: ^3.3.5 version: 3.3.5 '@types/node': - specifier: ^22.0.0 - version: 22.19.17 + specifier: ^25.6.0 + version: 25.6.0 '@types/react': - specifier: ^19.0.0 + specifier: ^19.2.14 version: 19.2.14 '@types/react-dom': - specifier: ^19.0.0 + specifier: ^19.2.3 version: 19.2.3(@types/react@19.2.14) eslint: - specifier: ^9.0.0 - version: 9.39.4 + specifier: ^10.2.1 + version: 10.2.1 eslint-config-next: - specifier: ^15.1.0 - version: 15.5.15(eslint@9.39.4)(typescript@5.9.3) + specifier: ^16.2.4 + version: 16.2.4(@typescript-eslint/parser@8.59.1)(eslint@10.2.1)(typescript@6.0.3) typescript: - specifier: ~5.9.0 - version: 5.9.3 + specifier: ~6.0.3 + version: 6.0.3 apps/with-lingui: dependencies: @@ -1004,6 +1004,16 @@ packages: dev: true optional: true + /@eslint-community/eslint-utils@4.9.1(eslint@10.2.1): + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 10.2.1 + eslint-visitor-keys: 3.4.3 + dev: true + /@eslint-community/eslint-utils@4.9.1(eslint@8.57.1): resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1014,42 +1024,32 @@ packages: eslint-visitor-keys: 3.4.3 dev: true - /@eslint-community/eslint-utils@4.9.1(eslint@9.39.4): - resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - dependencies: - eslint: 9.39.4 - eslint-visitor-keys: 3.4.3 - dev: true - /@eslint-community/regexpp@4.12.2: resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true - /@eslint/config-array@0.21.2: - resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + /@eslint/config-array@0.23.5: + resolution: {integrity: sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} dependencies: - '@eslint/object-schema': 2.1.7 + '@eslint/object-schema': 3.0.5 debug: 4.4.3 - minimatch: 3.1.5 + minimatch: 10.2.5 transitivePeerDependencies: - supports-color dev: true - /@eslint/config-helpers@0.4.2: - resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + /@eslint/config-helpers@0.5.5: + resolution: {integrity: sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} dependencies: - '@eslint/core': 0.17.0 + '@eslint/core': 1.2.1 dev: true - /@eslint/core@0.17.0: - resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + /@eslint/core@1.2.1: + resolution: {integrity: sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} dependencies: '@types/json-schema': 7.0.15 dev: true @@ -1093,21 +1093,16 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@eslint/js@9.39.4: - resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + /@eslint/object-schema@3.0.5: + resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} dev: true - /@eslint/object-schema@2.1.7: - resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - dev: true - - /@eslint/plugin-kit@0.4.1: - resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + /@eslint/plugin-kit@0.7.1: + resolution: {integrity: sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} dependencies: - '@eslint/core': 0.17.0 + '@eslint/core': 1.2.1 levn: 0.4.1 dev: true @@ -2150,18 +2145,18 @@ packages: dev: true optional: true - /@next/env@15.5.15: - resolution: {integrity: sha512-vcmyu5/MyFzN7CdqRHO3uHO44p/QPCZkuTUXroeUmhNP8bL5PHFEhik22JUazt+CDDoD6EpBYRCaS2pISL+/hg==} + /@next/env@16.2.4: + resolution: {integrity: sha512-dKkkOzOSwFYe5RX6y26fZgkSpVAlIOJKQHIiydQcrWH6y/97+RceSOAdjZ14Qa3zLduVUy0TXcn+EiM6t4rPgw==} dev: false - /@next/eslint-plugin-next@15.5.15: - resolution: {integrity: sha512-ExQoBfyKMjAUQ2nuF39ryQsG26H374ZfH13dlOZqf6TaE9ycRbIm+qUbUFCliU4BtQhiqtS7cnGA1yWfPMQ+jA==} + /@next/eslint-plugin-next@16.2.4: + resolution: {integrity: sha512-tOX826JJ96gYK/go18sPUgMq9FK1tqxBFfUCEufJb5XIkWFFmpgU7mahJANKGkHs7F41ir3tReJ3Lv5La0RvhA==} dependencies: fast-glob: 3.3.1 dev: true - /@next/swc-darwin-arm64@15.5.15: - resolution: {integrity: sha512-6PvFO2Tzt10GFK2Ro9tAVEtacMqRmTarYMFKAnV2vYMdwWc73xzmDQyAV7SwEdMhzmiRoo7+m88DuiXlJlGeaw==} + /@next/swc-darwin-arm64@16.2.4: + resolution: {integrity: sha512-OXTFFox5EKN1Ym08vfrz+OXxmCcEjT4SFMbNRsWZE99dMqt2Kcusl5MqPXcW232RYkMLQTy0hqgAMEsfEd/l2A==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] @@ -2169,8 +2164,8 @@ packages: dev: false optional: true - /@next/swc-darwin-x64@15.5.15: - resolution: {integrity: sha512-G+YNV+z6FDZTp/+IdGyIMFqalBTaQSnvAA+X/hrt+eaTRFSznRMz9K7rTmzvM6tDmKegNtyzgufZW0HwVzEqaQ==} + /@next/swc-darwin-x64@16.2.4: + resolution: {integrity: sha512-XhpVnUfmYWvD3YrXu55XdcAkQtOnvaI6wtQa8fuF5fGoKoxIUZ0kWPtcOfqJEWngFF/lOS9l3+O9CcownhiQxQ==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] @@ -2178,8 +2173,8 @@ packages: dev: false optional: true - /@next/swc-linux-arm64-gnu@15.5.15: - resolution: {integrity: sha512-eVkrMcVIBqGfXB+QUC7jjZ94Z6uX/dNStbQFabewAnk13Uy18Igd1YZ/GtPRzdhtm7QwC0e6o7zOQecul4iC1w==} + /@next/swc-linux-arm64-gnu@16.2.4: + resolution: {integrity: sha512-Mx/tjlNA3G8kg14QvuGAJ4xBwPk1tUHq56JxZ8CXnZwz1Etz714soCEzGQQzVMz4bEnGPowzkV6Xrp6wAkEWOQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -2187,8 +2182,8 @@ packages: dev: false optional: true - /@next/swc-linux-arm64-musl@15.5.15: - resolution: {integrity: sha512-RwSHKMQ7InLy5GfkY2/n5PcFycKA08qI1VST78n09nN36nUPqCvGSMiLXlfUmzmpQpF6XeBYP2KRWHi0UW3uNg==} + /@next/swc-linux-arm64-musl@16.2.4: + resolution: {integrity: sha512-iVMMp14514u7Nup2umQS03nT/bN9HurK8ufylC3FZNykrwjtx7V1A7+4kvhbDSCeonTVqV3Txnv0Lu+m2oDXNg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -2196,8 +2191,8 @@ packages: dev: false optional: true - /@next/swc-linux-x64-gnu@15.5.15: - resolution: {integrity: sha512-nplqvY86LakS+eeiuWsNWvfmK8pFcOEW7ZtVRt4QH70lL+0x6LG/m1OpJ/tvrbwjmR8HH9/fH2jzW1GlL03TIg==} + /@next/swc-linux-x64-gnu@16.2.4: + resolution: {integrity: sha512-EZOvm1aQWgnI/N/xcWOlnS3RQBk0VtVav5Zo7n4p0A7UKyTDx047k8opDbXgBpHl4CulRqRfbw3QrX2w5UOXMQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -2205,8 +2200,8 @@ packages: dev: false optional: true - /@next/swc-linux-x64-musl@15.5.15: - resolution: {integrity: sha512-eAgl9NKQ84/sww0v81DQINl/vL2IBxD7sMybd0cWRw6wqgouVI53brVRBrggqBRP/NWeIAE1dm5cbKYoiMlqDQ==} + /@next/swc-linux-x64-musl@16.2.4: + resolution: {integrity: sha512-h9FxsngCm9cTBf71AR4fGznDEDx1hS7+kSEiIRjq5kO1oXWm07DxVGZjCvk0SGx7TSjlUqhI8oOyz7NfwAdPoA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -2214,8 +2209,8 @@ packages: dev: false optional: true - /@next/swc-win32-arm64-msvc@15.5.15: - resolution: {integrity: sha512-GJVZC86lzSquh0MtvZT+L7G8+jMnJcldloOjA8Kf3wXvBrvb6OGe2MzPuALxFshSm/IpwUtD2mIoof39ymf52A==} + /@next/swc-win32-arm64-msvc@16.2.4: + resolution: {integrity: sha512-3NdJV5OXMSOeJYijX+bjaLge3mJBlh4ybydbT4GFoB/2hAojWHtMhl3CYlYoMrjPuodp0nzFVi4Tj2+WaMg+Ow==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] @@ -2223,8 +2218,8 @@ packages: dev: false optional: true - /@next/swc-win32-x64-msvc@15.5.15: - resolution: {integrity: sha512-nFucjVdwlFqxh/JG3hWSJ4p8+YJV7Ii8aPDuBQULB6DzUF4UNZETXLfEUk+oI2zEznWWULPt7MeuTE6xtK1HSA==} + /@next/swc-win32-x64-msvc@16.2.4: + resolution: {integrity: sha512-kMVGgsqhO5YTYODD9IPGGhA6iprWidQckK3LmPeW08PIFENRmgfb4MjXHO+p//d+ts2rpjvK5gXWzXSMrPl9cw==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -3585,10 +3580,6 @@ packages: resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} dev: true - /@rushstack/eslint-patch@1.16.1: - resolution: {integrity: sha512-TvZbIpeKqGQQ7X0zSCvPH9riMSFQFSggnfBjFZ1mEoILW+UuXCKwOoPcgjMwiUtRqFZ8jWhPJc4um14vC6I4ag==} - dev: true - /@shikijs/core@3.23.0: resolution: {integrity: sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==} dependencies: @@ -3625,15 +3616,15 @@ packages: '@shikijs/types': 3.23.0 dev: false - /@shikijs/twoslash@3.23.0(typescript@5.9.3): + /@shikijs/twoslash@3.23.0(typescript@6.0.3): resolution: {integrity: sha512-pNaLJWMA3LU7PhT8tm9OQBZ1epy0jmdgeJzntBtr1EVXLbHxGzTj3mnf9vOdcl84l96qnlJXkJ/NGXZYBpXl5g==} peerDependencies: typescript: '>=5.5.0' dependencies: '@shikijs/core': 3.23.0 '@shikijs/types': 3.23.0 - twoslash: 0.3.7(typescript@5.9.3) - typescript: 5.9.3 + twoslash: 0.3.7(typescript@6.0.3) + typescript: 6.0.3 transitivePeerDependencies: - supports-color dev: false @@ -4351,6 +4342,10 @@ packages: resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} dev: true + /@types/esrecurse@4.3.1: + resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} + dev: true + /@types/estree-jsx@1.0.5: resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} dependencies: @@ -4420,6 +4415,12 @@ packages: dependencies: undici-types: 6.21.0 + /@types/node@25.6.0: + resolution: {integrity: sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==} + dependencies: + undici-types: 7.19.2 + dev: true + /@types/react-dom@19.2.3(@types/react@19.2.14): resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} peerDependencies: @@ -4465,153 +4466,153 @@ packages: dependencies: '@types/yargs-parser': 21.0.3 - /@typescript-eslint/eslint-plugin@8.58.2(@typescript-eslint/parser@8.58.2)(eslint@9.39.4)(typescript@5.9.3): - resolution: {integrity: sha512-aC2qc5thQahutKjP+cl8cgN9DWe3ZUqVko30CMSZHnFEHyhOYoZSzkGtAI2mcwZ38xeImDucI4dnqsHiOYuuCw==} + /@typescript-eslint/eslint-plugin@8.59.1(@typescript-eslint/parser@8.59.1)(eslint@10.2.1)(typescript@6.0.3): + resolution: {integrity: sha512-BOziFIfE+6osHO9FoJG4zjoHUcvI7fTNBSpdAwrNH0/TLvzjsk2oo8XSSOT2HhqUyhZPfHv4UOffoJ9oEEQ7Ag==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.58.2 + '@typescript-eslint/parser': ^8.59.1 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.58.2(eslint@9.39.4)(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.58.2 - '@typescript-eslint/type-utils': 8.58.2(eslint@9.39.4)(typescript@5.9.3) - '@typescript-eslint/utils': 8.58.2(eslint@9.39.4)(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.58.2 - eslint: 9.39.4 + '@typescript-eslint/parser': 8.59.1(eslint@10.2.1)(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.59.1 + '@typescript-eslint/type-utils': 8.59.1(eslint@10.2.1)(typescript@6.0.3) + '@typescript-eslint/utils': 8.59.1(eslint@10.2.1)(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.59.1 + eslint: 10.2.1 ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.5.0(typescript@5.9.3) - typescript: 5.9.3 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@8.58.2(eslint@9.39.4)(typescript@5.9.3): - resolution: {integrity: sha512-/Zb/xaIDfxeJnvishjGdcR4jmr7S+bda8PKNhRGdljDM+elXhlvN0FyPSsMnLmJUrVG9aPO6dof80wjMawsASg==} + /@typescript-eslint/parser@8.59.1(eslint@10.2.1)(typescript@6.0.3): + resolution: {integrity: sha512-HDQH9O/47Dxi1ceDhBXdaldtf/WV9yRYMjbjCuNk3qnaTD564qwv61Y7+gTxwxRKzSrgO5uhtw584igXVuuZkA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' dependencies: - '@typescript-eslint/scope-manager': 8.58.2 - '@typescript-eslint/types': 8.58.2 - '@typescript-eslint/typescript-estree': 8.58.2(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.58.2 + '@typescript-eslint/scope-manager': 8.59.1 + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/typescript-estree': 8.59.1(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.59.1 debug: 4.4.3 - eslint: 9.39.4 - typescript: 5.9.3 + eslint: 10.2.1 + typescript: 6.0.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/project-service@8.58.2(typescript@5.9.3): - resolution: {integrity: sha512-Cq6UfpZZk15+r87BkIh5rDpi38W4b+Sjnb8wQCPPDDweS/LRCFjCyViEbzHk5Ck3f2QDfgmlxqSa7S7clDtlfg==} + /@typescript-eslint/project-service@8.59.1(typescript@6.0.3): + resolution: {integrity: sha512-+MuHQlHiEr00Of/IQbE/MmEoi44znZHbR/Pz7Opq4HryUOlRi+/44dro9Ycy8Fyo+/024IWtw8m4JUMCGTYxDg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' dependencies: - '@typescript-eslint/tsconfig-utils': 8.58.2(typescript@5.9.3) - '@typescript-eslint/types': 8.58.2 + '@typescript-eslint/tsconfig-utils': 8.59.1(typescript@6.0.3) + '@typescript-eslint/types': 8.59.1 debug: 4.4.3 - typescript: 5.9.3 + typescript: 6.0.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager@8.58.2: - resolution: {integrity: sha512-SgmyvDPexWETQek+qzZnrG6844IaO02UVyOLhI4wpo82dpZJY9+6YZCKAMFzXb7qhx37mFK1QcPQ18tud+vo6Q==} + /@typescript-eslint/scope-manager@8.59.1: + resolution: {integrity: sha512-LwuHQI4pDOYVKvmH2dkaJo6YZCSgouVgnS/z7yBPKBMvgtBvyLqiLy9Z6b7+m/TRcX1NFYUqZetI5Y+aT4GEfg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dependencies: - '@typescript-eslint/types': 8.58.2 - '@typescript-eslint/visitor-keys': 8.58.2 + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/visitor-keys': 8.59.1 dev: true - /@typescript-eslint/tsconfig-utils@8.58.2(typescript@5.9.3): - resolution: {integrity: sha512-3SR+RukipDvkkKp/d0jP0dyzuls3DbGmwDpVEc5wqk5f38KFThakqAAO0XMirWAE+kT00oTauTbzMFGPoAzB0A==} + /@typescript-eslint/tsconfig-utils@8.59.1(typescript@6.0.3): + resolution: {integrity: sha512-/0nEyPbX7gRsk0Uwfe4ALwwgxuA66d/l2mhRDNlAvaj4U3juhUtJNq0DsY8M2AYwwb9rEq2hrC3IcIcEt++iJA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' dependencies: - typescript: 5.9.3 + typescript: 6.0.3 dev: true - /@typescript-eslint/type-utils@8.58.2(eslint@9.39.4)(typescript@5.9.3): - resolution: {integrity: sha512-Z7EloNR/B389FvabdGeTo2XMs4W9TjtPiO9DAsmT0yom0bwlPyRjkJ1uCdW1DvrrrYP50AJZ9Xc3sByZA9+dcg==} + /@typescript-eslint/type-utils@8.59.1(eslint@10.2.1)(typescript@6.0.3): + resolution: {integrity: sha512-klWPBR2ciQHS3f++ug/mVnWKPjBUo7icEL3FAO1lhAR1Z1i5NQYZ1EannMSRYcq5qCv5wNALlXr6fksRHyYl7w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' dependencies: - '@typescript-eslint/types': 8.58.2 - '@typescript-eslint/typescript-estree': 8.58.2(typescript@5.9.3) - '@typescript-eslint/utils': 8.58.2(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/typescript-estree': 8.59.1(typescript@6.0.3) + '@typescript-eslint/utils': 8.59.1(eslint@10.2.1)(typescript@6.0.3) debug: 4.4.3 - eslint: 9.39.4 - ts-api-utils: 2.5.0(typescript@5.9.3) - typescript: 5.9.3 + eslint: 10.2.1 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types@8.58.2: - resolution: {integrity: sha512-9TukXyATBQf/Jq9AMQXfvurk+G5R2MwfqQGDR2GzGz28HvY/lXNKGhkY+6IOubwcquikWk5cjlgPvD2uAA7htQ==} + /@typescript-eslint/types@8.59.1: + resolution: {integrity: sha512-ZDCjgccSdYPw5Bxh+my4Z0lJU96ZDN7jbBzvmEn0FZx3RtU1C7VWl6NbDx94bwY3V5YsgwRzJPOgeY2Q/nLG8A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dev: true - /@typescript-eslint/typescript-estree@8.58.2(typescript@5.9.3): - resolution: {integrity: sha512-ELGuoofuhhoCvNbQjFFiobFcGgcDCEm0ThWdmO4Z0UzLqPXS3KFvnEZ+SHewwOYHjM09tkzOWXNTv9u6Gqtyuw==} + /@typescript-eslint/typescript-estree@8.59.1(typescript@6.0.3): + resolution: {integrity: sha512-OUd+vJS05sSkOip+BkZ/2NS8RMxrAAJemsC6vU3kmfLyeaJT0TftHkV9mcx2107MmsBVXXexhVu4F0TZXyMl4g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' dependencies: - '@typescript-eslint/project-service': 8.58.2(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.58.2(typescript@5.9.3) - '@typescript-eslint/types': 8.58.2 - '@typescript-eslint/visitor-keys': 8.58.2 + '@typescript-eslint/project-service': 8.59.1(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.59.1(typescript@6.0.3) + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/visitor-keys': 8.59.1 debug: 4.4.3 minimatch: 10.2.5 semver: 7.7.4 tinyglobby: 0.2.16 - ts-api-utils: 2.5.0(typescript@5.9.3) - typescript: 5.9.3 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils@8.58.2(eslint@9.39.4)(typescript@5.9.3): - resolution: {integrity: sha512-QZfjHNEzPY8+l0+fIXMvuQ2sJlplB4zgDZvA+NmvZsZv3EQwOcc1DuIU1VJUTWZ/RKouBMhDyNaBMx4sWvrzRA==} + /@typescript-eslint/utils@8.59.1(eslint@10.2.1)(typescript@6.0.3): + resolution: {integrity: sha512-3pIeoXhCeYH9FSCBI8P3iNwJlGuzPlYKkTlen2O9T1DSeeg8UG8jstq6BLk+Mda0qup7mgk4z4XL4OzRaxZ8LA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) - '@typescript-eslint/scope-manager': 8.58.2 - '@typescript-eslint/types': 8.58.2 - '@typescript-eslint/typescript-estree': 8.58.2(typescript@5.9.3) - eslint: 9.39.4 - typescript: 5.9.3 + '@eslint-community/eslint-utils': 4.9.1(eslint@10.2.1) + '@typescript-eslint/scope-manager': 8.59.1 + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/typescript-estree': 8.59.1(typescript@6.0.3) + eslint: 10.2.1 + typescript: 6.0.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/visitor-keys@8.58.2: - resolution: {integrity: sha512-f1WO2Lx8a9t8DARmcWAUPJbu0G20bJlj8L4z72K00TMeJAoyLr/tHhI/pzYBLrR4dXWkcxO1cWYZEOX8DKHTqA==} + /@typescript-eslint/visitor-keys@8.59.1: + resolution: {integrity: sha512-LdDNl6C5iJExcM0Yh0PwAIBb9PrSiCsWamF/JyEZawm3kFDnRoaq3LGE4bpyRao/fWeGKKyw7icx0YxrLFC5Cg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dependencies: - '@typescript-eslint/types': 8.58.2 + '@typescript-eslint/types': 8.59.1 eslint-visitor-keys: 5.0.1 dev: true - /@typescript/vfs@1.6.4(typescript@5.9.3): + /@typescript/vfs@1.6.4(typescript@6.0.3): resolution: {integrity: sha512-PJFXFS4ZJKiJ9Qiuix6Dz/OwEIqHD7Dme1UwZhTK11vR+5dqW2ACbdndWQexBzCx+CPuMe5WBYQWCsFyGlQLlQ==} peerDependencies: typescript: '*' dependencies: debug: 4.4.3 - typescript: 5.9.3 + typescript: 6.0.3 transitivePeerDependencies: - supports-color dev: false @@ -6719,28 +6720,28 @@ packages: engines: {node: '>=12'} dev: false - /eslint-config-next@15.5.15(eslint@9.39.4)(typescript@5.9.3): - resolution: {integrity: sha512-mI5KIONOIosjF3jK2z9a8fY2LePNeW5C4lRJ+XZoJHAKkwx2MQjMPQ2/kL7tsMRPcQPZc/UBtCfqxElluL1CBg==} + /eslint-config-next@16.2.4(@typescript-eslint/parser@8.59.1)(eslint@10.2.1)(typescript@6.0.3): + resolution: {integrity: sha512-A6ekXYFj/YQxBPMl45g3e+U8zJo+X2+ZQwcz34pPKjpc/3S4roBA2Rd9xWB4FKuSxhofo1/95WjzmUY+wHrOhg==} peerDependencies: - eslint: ^7.23.0 || ^8.0.0 || ^9.0.0 + eslint: '>=9.0.0' typescript: '>=3.3.1' peerDependenciesMeta: typescript: optional: true dependencies: - '@next/eslint-plugin-next': 15.5.15 - '@rushstack/eslint-patch': 1.16.1 - '@typescript-eslint/eslint-plugin': 8.58.2(@typescript-eslint/parser@8.58.2)(eslint@9.39.4)(typescript@5.9.3) - '@typescript-eslint/parser': 8.58.2(eslint@9.39.4)(typescript@5.9.3) - eslint: 9.39.4 + '@next/eslint-plugin-next': 16.2.4 + eslint: 10.2.1 eslint-import-resolver-node: 0.3.10 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.58.2)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4) - eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.4) - eslint-plugin-react: 7.37.5(eslint@9.39.4) - eslint-plugin-react-hooks: 5.2.0(eslint@9.39.4) - typescript: 5.9.3 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@10.2.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.59.1)(eslint-import-resolver-typescript@3.10.1)(eslint@10.2.1) + eslint-plugin-jsx-a11y: 6.10.2(eslint@10.2.1) + eslint-plugin-react: 7.37.5(eslint@10.2.1) + eslint-plugin-react-hooks: 7.1.1(eslint@10.2.1) + globals: 16.4.0 + typescript: 6.0.3 + typescript-eslint: 8.59.1(eslint@10.2.1)(typescript@6.0.3) transitivePeerDependencies: + - '@typescript-eslint/parser' - eslint-import-resolver-webpack - eslint-plugin-import-x - supports-color @@ -6756,7 +6757,7 @@ packages: - supports-color dev: true - /eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4): + /eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@10.2.1): resolution: {integrity: sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -6771,8 +6772,8 @@ packages: dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.3 - eslint: 9.39.4 - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.58.2)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4) + eslint: 10.2.1 + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.59.1)(eslint-import-resolver-typescript@3.10.1)(eslint@10.2.1) get-tsconfig: 4.13.7 is-bun-module: 2.0.0 stable-hash: 0.0.5 @@ -6782,7 +6783,7 @@ packages: - supports-color dev: true - /eslint-module-utils@2.12.1(@typescript-eslint/parser@8.58.2)(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4): + /eslint-module-utils@2.12.1(@typescript-eslint/parser@8.59.1)(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@10.2.1): resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} engines: {node: '>=4'} peerDependencies: @@ -6803,16 +6804,16 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 8.58.2(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/parser': 8.59.1(eslint@10.2.1)(typescript@6.0.3) debug: 3.2.7 - eslint: 9.39.4 + eslint: 10.2.1 eslint-import-resolver-node: 0.3.10 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@10.2.1) transitivePeerDependencies: - supports-color dev: true - /eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.58.2)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4): + /eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.1)(eslint-import-resolver-typescript@3.10.1)(eslint@10.2.1): resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} engines: {node: '>=4'} peerDependencies: @@ -6823,16 +6824,16 @@ packages: optional: true dependencies: '@rtsao/scc': 1.1.0 - '@typescript-eslint/parser': 8.58.2(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/parser': 8.59.1(eslint@10.2.1)(typescript@6.0.3) array-includes: 3.1.9 array.prototype.findlastindex: 1.2.6 array.prototype.flat: 1.3.3 array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 - eslint: 9.39.4 + eslint: 10.2.1 eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.58.2)(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.59.1)(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@10.2.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -6849,7 +6850,7 @@ packages: - supports-color dev: true - /eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4): + /eslint-plugin-jsx-a11y@6.10.2(eslint@10.2.1): resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} engines: {node: '>=4.0'} peerDependencies: @@ -6863,7 +6864,7 @@ packages: axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 9.39.4 + eslint: 10.2.1 hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -6873,16 +6874,23 @@ packages: string.prototype.includes: 2.0.1 dev: true - /eslint-plugin-react-hooks@5.2.0(eslint@9.39.4): - resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} - engines: {node: '>=10'} + /eslint-plugin-react-hooks@7.1.1(eslint@10.2.1): + resolution: {integrity: sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==} + engines: {node: '>=18'} peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0 dependencies: - eslint: 9.39.4 + '@babel/core': 7.29.0 + '@babel/parser': 7.29.2 + eslint: 10.2.1 + hermes-parser: 0.25.1 + zod: 4.3.6 + zod-validation-error: 4.0.2(zod@4.3.6) + transitivePeerDependencies: + - supports-color dev: true - /eslint-plugin-react@7.37.5(eslint@9.39.4): + /eslint-plugin-react@7.37.5(eslint@10.2.1): resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} engines: {node: '>=4'} peerDependencies: @@ -6894,7 +6902,7 @@ packages: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.3.2 - eslint: 9.39.4 + eslint: 10.2.1 estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -6917,10 +6925,12 @@ packages: estraverse: 5.3.0 dev: true - /eslint-scope@8.4.0: - resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + /eslint-scope@9.1.2: + resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} dependencies: + '@types/esrecurse': 4.3.1 + '@types/estree': 1.0.8 esrecurse: 4.3.0 estraverse: 5.3.0 dev: true @@ -6940,6 +6950,50 @@ packages: engines: {node: ^20.19.0 || ^22.13.0 || >=24} dev: true + /eslint@10.2.1: + resolution: {integrity: sha512-wiyGaKsDgqXvF40P8mDwiUp/KQjE1FdrIEJsM8PZ3XCiniTMXS3OHWWUe5FI5agoCnr8x4xPrTDZuxsBlNHl+Q==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@10.2.1) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.23.5 + '@eslint/config-helpers': 0.5.5 + '@eslint/core': 1.2.1 + '@eslint/plugin-kit': 0.7.1 + '@humanfs/node': 0.16.7 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + ajv: 6.14.0 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 9.1.2 + eslint-visitor-keys: 5.0.1 + espree: 11.2.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + minimatch: 10.2.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + dev: true + /eslint@8.57.1: resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -6988,54 +7042,6 @@ packages: - supports-color dev: true - /eslint@9.39.4: - resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - hasBin: true - peerDependencies: - jiti: '*' - peerDependenciesMeta: - jiti: - optional: true - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) - '@eslint-community/regexpp': 4.12.2 - '@eslint/config-array': 0.21.2 - '@eslint/config-helpers': 0.4.2 - '@eslint/core': 0.17.0 - '@eslint/eslintrc': 3.3.5 - '@eslint/js': 9.39.4 - '@eslint/plugin-kit': 0.4.1 - '@humanfs/node': 0.16.7 - '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.3 - '@types/estree': 1.0.8 - ajv: 6.14.0 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.3 - escape-string-regexp: 4.0.0 - eslint-scope: 8.4.0 - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 - esquery: 1.7.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 8.0.0 - find-up: 5.0.0 - glob-parent: 6.0.2 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - json-stable-stringify-without-jsonify: 1.0.1 - lodash.merge: 4.6.2 - minimatch: 3.1.5 - natural-compare: 1.4.0 - optionator: 0.9.4 - transitivePeerDependencies: - - supports-color - dev: true - /esm@3.2.25: resolution: {integrity: sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==} engines: {node: '>=6'} @@ -7051,6 +7057,15 @@ packages: eslint-visitor-keys: 4.2.1 dev: true + /espree@11.2.0: + resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + eslint-visitor-keys: 5.0.1 + dev: true + /espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -7450,6 +7465,11 @@ packages: engines: {node: '>=18'} dev: true + /globals@16.4.0: + resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==} + engines: {node: '>=18'} + dev: true + /globalthis@1.0.4: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} @@ -7703,6 +7723,16 @@ packages: set-cookie-parser: 3.1.0 dev: true + /hermes-estree@0.25.1: + resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==} + dev: true + + /hermes-parser@0.25.1: + resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} + dependencies: + hermes-estree: 0.25.1 + dev: true + /html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} dev: false @@ -9241,9 +9271,9 @@ packages: react-dom: 19.2.5(react@19.2.5) dev: false - /next@15.5.15(react-dom@19.2.5)(react@19.2.5): - resolution: {integrity: sha512-VSqCrJwtLVGwAVE0Sb/yikrQfkwkZW9p+lL/J4+xe+G3ZA+QnWPqgcfH1tDUEuk9y+pthzzVFp4L/U8JerMfMQ==} - engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + /next@16.2.4(@babel/core@7.29.0)(react-dom@19.2.5)(react@19.2.5): + resolution: {integrity: sha512-kPvz56wF5frc+FxlHI5qnklCzbq53HTwORaWBGdT0vNoKh1Aya9XC8aPauH4NJxqtzbWsS5mAbctm4cr+EkQ2Q==} + engines: {node: '>=20.9.0'} hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 @@ -9262,29 +9292,30 @@ packages: sass: optional: true dependencies: - '@next/env': 15.5.15 + '@next/env': 16.2.4 '@swc/helpers': 0.5.15 + baseline-browser-mapping: 2.10.18 caniuse-lite: 1.0.30001788 postcss: 8.4.31 react: 19.2.5 react-dom: 19.2.5(react@19.2.5) - styled-jsx: 5.1.6(react@19.2.5) + styled-jsx: 5.1.6(@babel/core@7.29.0)(react@19.2.5) optionalDependencies: - '@next/swc-darwin-arm64': 15.5.15 - '@next/swc-darwin-x64': 15.5.15 - '@next/swc-linux-arm64-gnu': 15.5.15 - '@next/swc-linux-arm64-musl': 15.5.15 - '@next/swc-linux-x64-gnu': 15.5.15 - '@next/swc-linux-x64-musl': 15.5.15 - '@next/swc-win32-arm64-msvc': 15.5.15 - '@next/swc-win32-x64-msvc': 15.5.15 + '@next/swc-darwin-arm64': 16.2.4 + '@next/swc-darwin-x64': 16.2.4 + '@next/swc-linux-arm64-gnu': 16.2.4 + '@next/swc-linux-arm64-musl': 16.2.4 + '@next/swc-linux-x64-gnu': 16.2.4 + '@next/swc-linux-x64-musl': 16.2.4 + '@next/swc-win32-arm64-msvc': 16.2.4 + '@next/swc-win32-x64-msvc': 16.2.4 sharp: 0.34.5 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros dev: false - /nextra-theme-docs@4.6.1(@types/react@19.2.14)(next@15.5.15)(nextra@4.6.1)(react-dom@19.2.5)(react@19.2.5): + /nextra-theme-docs@4.6.1(@types/react@19.2.14)(next@16.2.4)(nextra@4.6.1)(react-dom@19.2.5)(react@19.2.5): resolution: {integrity: sha512-u5Hh8erVcGOXO1FVrwYBgrEjyzdYQY0k/iAhLd8RofKp+Bru3fyLy9V9W34mfJ0KHKHjv/ldlDTlb4KlL4eIuQ==} peerDependencies: next: '>=14' @@ -9294,9 +9325,9 @@ packages: dependencies: '@headlessui/react': 2.2.10(react-dom@19.2.5)(react@19.2.5) clsx: 2.1.1 - next: 15.5.15(react-dom@19.2.5)(react@19.2.5) + next: 16.2.4(@babel/core@7.29.0)(react-dom@19.2.5)(react@19.2.5) next-themes: 0.4.6(react-dom@19.2.5)(react@19.2.5) - nextra: 4.6.1(next@15.5.15)(react-dom@19.2.5)(react@19.2.5)(typescript@5.9.3) + nextra: 4.6.1(next@16.2.4)(react-dom@19.2.5)(react@19.2.5)(typescript@6.0.3) react: 19.2.5 react-compiler-runtime: 19.1.0-rc.3(react@19.2.5) react-dom: 19.2.5(react@19.2.5) @@ -9309,7 +9340,7 @@ packages: - use-sync-external-store dev: false - /nextra@4.6.1(next@15.5.15)(react-dom@19.2.5)(react@19.2.5)(typescript@5.9.3): + /nextra@4.6.1(next@16.2.4)(react-dom@19.2.5)(react@19.2.5)(typescript@6.0.3): resolution: {integrity: sha512-yz5WMJFZ5c58y14a6Rmwt+SJUYDdIgzWSxwtnpD4XAJTq3mbOqOg3VTaJqLiJjwRSxoFRHNA1yAhnhbvbw9zSg==} engines: {node: '>=18'} peerDependencies: @@ -9321,7 +9352,7 @@ packages: '@headlessui/react': 2.2.10(react-dom@19.2.5)(react@19.2.5) '@mdx-js/mdx': 3.1.1 '@napi-rs/simple-git': 0.1.22 - '@shikijs/twoslash': 3.23.0(typescript@5.9.3) + '@shikijs/twoslash': 3.23.0(typescript@6.0.3) '@theguild/remark-mermaid': 0.3.0(react@19.2.5) '@theguild/remark-npm2yarn': 0.3.3 better-react-mathjax: 2.3.0(react@19.2.5) @@ -9336,7 +9367,7 @@ packages: mdast-util-gfm: 3.1.0 mdast-util-to-hast: 13.2.1 negotiator: 1.0.0 - next: 15.5.15(react-dom@19.2.5)(react@19.2.5) + next: 16.2.4(@babel/core@7.29.0)(react-dom@19.2.5)(react@19.2.5) react: 19.2.5 react-compiler-runtime: 19.1.0-rc.3(react@19.2.5) react-dom: 19.2.5(react@19.2.5) @@ -10722,7 +10753,7 @@ packages: inline-style-parser: 0.2.7 dev: false - /styled-jsx@5.1.6(react@19.2.5): + /styled-jsx@5.1.6(@babel/core@7.29.0)(react@19.2.5): resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} engines: {node: '>= 12.0.0'} peerDependencies: @@ -10735,6 +10766,7 @@ packages: babel-plugin-macros: optional: true dependencies: + '@babel/core': 7.29.0 client-only: 0.0.1 react: 19.2.5 dev: false @@ -10904,13 +10936,13 @@ packages: resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} dev: false - /ts-api-utils@2.5.0(typescript@5.9.3): + /ts-api-utils@2.5.0(typescript@6.0.3): resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} engines: {node: '>=18.12'} peerDependencies: typescript: '>=4.8.4' dependencies: - typescript: 5.9.3 + typescript: 6.0.3 dev: true /ts-dedent@2.2.0: @@ -11012,14 +11044,14 @@ packages: resolution: {integrity: sha512-mwDFdclG7DbFW3aZA/CGATzV2efV2uPai90mmRSblqPbrc1Z1cu+DpI5oKMNciGY4rw8EOXc7QGY8O0iw1hnzg==} dev: false - /twoslash@0.3.7(typescript@5.9.3): + /twoslash@0.3.7(typescript@6.0.3): resolution: {integrity: sha512-f7YgM+6G5e3wRGwMiOV8Z0wfusR4zCcdDPSqgGjpLSiW0ymT9r/dM6g++IvOMtSO0KnP/yGTUFhH04y6uqpL6g==} peerDependencies: typescript: ^5.5.0 || ^6.0.0 dependencies: - '@typescript/vfs': 1.6.4(typescript@5.9.3) + '@typescript/vfs': 1.6.4(typescript@6.0.3) twoslash-protocol: 0.3.7 - typescript: 5.9.3 + typescript: 6.0.3 transitivePeerDependencies: - supports-color dev: false @@ -11088,16 +11120,33 @@ packages: reflect.getprototypeof: 1.0.10 dev: true + /typescript-eslint@8.59.1(eslint@10.2.1)(typescript@6.0.3): + resolution: {integrity: sha512-xqDcFVBmlrltH64lklOVp1wYxgJr6LVdg3NamBgH2OOQDLFdTKfIZXF5PfghrnXQKXZGTQs8tr1vL7fJvq8CTQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + dependencies: + '@typescript-eslint/eslint-plugin': 8.59.1(@typescript-eslint/parser@8.59.1)(eslint@10.2.1)(typescript@6.0.3) + '@typescript-eslint/parser': 8.59.1(eslint@10.2.1)(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.59.1(typescript@6.0.3) + '@typescript-eslint/utils': 8.59.1(eslint@10.2.1)(typescript@6.0.3) + eslint: 10.2.1 + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + dev: true + /typescript@5.9.3: resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} hasBin: true + dev: true /typescript@6.0.3: resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} engines: {node: '>=14.17'} hasBin: true - dev: true /ufo@1.6.3: resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} @@ -11115,6 +11164,10 @@ packages: /undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + /undici-types@7.19.2: + resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==} + dev: true + /unified@11.0.5: resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} dependencies: @@ -11941,13 +11994,21 @@ packages: engines: {node: '>=18'} dev: true + /zod-validation-error@4.0.2(zod@4.3.6): + resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + dependencies: + zod: 4.3.6 + dev: true + /zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} dev: true /zod@4.3.6: resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} - dev: false /zustand@5.0.12(@types/react@19.2.14)(react@19.2.5): resolution: {integrity: sha512-i77ae3aZq4dhMlRhJVCYgMLKuSiZAaUPAct2AksxQ+gOtimhGMdXljRT21P5BNpeT4kXlLIckvkPM029OljD7g==}