// Generated by build script export const readme = `# router 一个轻量级的路由框架,支持链式调用、中间件、嵌套路由等功能。 ## 快速开始 \`\`\`ts import { App } from '@kevisual/router'; const app = new App(); app.listen(4002); app .route({ path: 'demo', key: '02' }) .define(async (ctx) => { ctx.body = '02'; }) .addTo(app); app .route({ path: 'demo', key: '03' }) .define(async (ctx) => { ctx.body = '03'; }) .addTo(app); \`\`\` ## 核心概念 ### RouteContext 属性说明 在 route handler 中,你可以通过 \`ctx\` 访问以下属性: | 属性 | 类型 | 说明 | |------|------|------| | \`query\` | \`object\` | 请求参数,会自动合并 payload | | \`body\` | \`number \\| string \\| Object\` | 响应内容 | | \`code\` | \`number\` | 响应状态码,默认为 200 | | \`message\` | \`string\` | 响应消息 | | \`state\` | \`any\` | 状态数据,可在路由间传递 | | \`appId\` | \`string\` | 应用标识 | | \`currentPath\` | \`string\` | 当前路由路径 | | \`currentKey\` | \`string\` | 当前路由 key | | \`currentRoute\` | \`Route\` | 当前 Route 实例 | | \`progress\` | \`[string, string][]\` | 路由执行路径记录 | | \`nextQuery\` | \`object\` | 传递给下一个路由的参数 | | \`end\` | \`boolean\` | 是否提前结束路由执行 | | \`app\` | \`QueryRouter\` | 路由实例引用 | | \`error\` | \`any\` | 错误信息 | | \`index\` | \`number\` | 当前路由执行深度 | | \`needSerialize\` | \`boolean\` | 是否需要序列化响应数据 | ### 上下文方法 | 方法 | 参数 | 说明 | |------|------|------| | \`ctx.call(msg, ctx?)\` | \`{ path, key?, payload?, ... } \\| { id }\` | 调用其他路由,返回完整 context | | \`ctx.run(msg, ctx?)\` | \`{ path, key?, payload? }\` | 调用其他路由,返回 \`{ code, data, message }\` | | \`ctx.forward(res)\` | \`{ code, data?, message? }\` | 设置响应结果 | | \`ctx.throw(code?, message?, tips?)\` | - | 抛出自定义错误 | ## 完整示例 \`\`\`ts import { App } from '@kevisual/router'; const app = new App(); app.listen(4002); // 基本路由 app .route({ path: 'user', key: 'info' }) .define(async (ctx) => { // ctx.query 包含请求参数 const { id } = ctx.query; ctx.body = { id, name: '张三' }; ctx.code = 200; }) .addTo(app); // 使用 state 在路由间传递数据 app .route({ path: 'order', key: 'create' }) .define(async (ctx) => { ctx.state = { orderId: '12345' }; }) .addTo(app); app .route({ path: 'order', key: 'pay' }) .define(async (ctx) => { // 可以获取前一个路由设置的 state const { orderId } = ctx.state; ctx.body = { orderId, status: 'paid' }; }) .addTo(app); // 链式调用 app .route({ path: 'product', key: 'list' }) .define(async (ctx) => { ctx.body = [{ id: 1, name: '商品A' }]; }) .addTo(app); // 调用其他路由 app .route({ path: 'dashboard', key: 'stats' }) .define(async (ctx) => { // 调用 user/info 路由 const userRes = await ctx.run({ path: 'user', key: 'info', payload: { id: 1 } }); // 调用 product/list 路由 const productRes = await ctx.run({ path: 'product', key: 'list' }); ctx.body = { user: userRes.data, products: productRes.data }; }) .addTo(app); // 使用 throw 抛出错误 app .route({ path: 'admin', key: 'delete' }) .define(async (ctx) => { const { id } = ctx.query; if (!id) { ctx.throw(400, '缺少参数', 'id is required'); } ctx.body = { success: true }; }) .addTo(app); \`\`\` ## 中间件 \`\`\`ts import { App, Route } from '@kevisual/router'; const app = new App(); // 定义中间件 app.route({ id: 'auth-example', description: '权限校验中间件' }).define(async(ctx) => { const token = ctx.query.token; if (!token) { ctx.throw(401, '未登录', '需要 token'); } // 验证通过,设置用户信息到 state ctx.state.tokenUser = { id: 1, name: '用户A' }; }).addTo(app); // 使用中间件(通过 id 引用) app .route({ path: 'admin', key: 'panel', middleware: ['auth-example'] }) .define(async (ctx) => { // 可以访问中间件设置的 state const { tokenUser } = ctx.state; ctx.body = { tokenUser }; }) .addTo(app); \`\`\` ## 注意事项 1. **path 和 key 的组合是路由的唯一标识**,同一个 path+key 只能添加一个路由,后添加的会覆盖之前的。 2. **ctx.call vs ctx.run**: - \`call\` 返回完整 context,包含所有属性 - \`run\` 返回 \`{ code, data, message }\` 格式,data 即 body 3. **ctx.throw 会自动结束执行**,抛出自定义错误。 4. **state 不会自动继承**,每个路由的 state 是独立的,除非显式传递或使用 nextRoute。 5. **payload 会自动合并到 query**,调用 \`ctx.run({ path, key, payload })\` 时,payload 会合并到 query。 6. **nextQuery 用于传递给 nextRoute**,在当前路由中设置 \`ctx.nextQuery\`,会在执行 nextRoute 时合并到 query。 7. **避免 nextRoute 循环调用**,默认最大深度为 40 次,超过会返回 500 错误。 8. **needSerialize 默认为 true**,会自动对 body 进行 JSON 序列化和反序列化。 9. **progress 记录执行路径**,可用于调试和追踪路由调用链。 10. **中间件找不到会返回 404**,错误信息中会包含找不到的中间件列表。 `; export const examples_base = `# 最基本的用法 \`\`\`ts import { App } from '@kevisual/router'; const app = new App(); app.listen(4002); app .route({ path: 'demo', key: '02' }) .define(async (ctx) => { ctx.body = '02'; }) .addTo(app); \`\`\``;