From a311cf33423cc4880279f52f4f9006649f9f0556 Mon Sep 17 00:00:00 2001 From: yourtion Date: Wed, 1 Jul 2026 09:15:51 +0800 Subject: [PATCH] =?UTF-8?q?feat(docs):=20Markdown=20=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E6=BA=90=E7=A0=81=E4=BD=8D=E7=BD=AE=20(issue?= =?UTF-8?q?=20#5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sourceFile(relative/absolute)此前已在注册时采集,但未纳入 DOC_FIELD, 文档生成器拿不到。现加入 DOC_FIELD,并在 Markdown「请求地址」下方输出 「源码位置:」,便于从文档定位定义代码。无 sourceFile 时不输出。 - 新增 2 个回归测试(有/无 sourceFile) - bump 版本 3.2.1 → 3.2.4,登记 MIGRATION --- MIGRATION.md | 6 ++++ package.json | 2 +- packages/erest-express/package.json | 2 +- packages/erest-gen/package.json | 2 +- packages/erest-koa/package.json | 2 +- packages/erest-leizmweb/package.json | 2 +- src/lib/extend/docs.ts | 1 + src/lib/plugin/generate_markdown/apis.ts | 6 ++++ src/test/test-docs-plugins.ts | 36 ++++++++++++++++++++++++ 9 files changed, 54 insertions(+), 5 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index 0206afe..7bf7394 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -350,3 +350,9 @@ instead」)。`@koa/router` 是官方维护的继任包,API 与 koa-router * ### 影响范围 仅文档生成器(`generate_swagger` / `generate_postman`),不涉及运行时校验、路由绑定或类型推导。已声明 response schema 的项目重新生成文档即可看到变化;未声明的项目输出与之前完全一致。 + +## v3.2.4 — Markdown 文档展示源码位置(issue #5) + +### 新增(非 breaking) + +- **Markdown 文档在每个 API 标题块下输出源码位置**:`sourceFile`(含 `relative`/`absolute`,由 `getCallerSourceLine` 在路由注册时解析 Error.stack 采集)此前已在 API 构造时记录,但未纳入 `DOC_FIELD`,文档生成器拿不到。现将其加入 `DOC_FIELD`,并在 Markdown 的「请求地址」行下方输出 `源码位置:```,便于从文档快速定位到定义代码。无 `sourceFile` 时不输出该行,行为与之前一致。 diff --git a/package.json b/package.json index 0582519..f84b270 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "erest", - "version": "3.2.2", + "version": "3.2.4", "description": "Framework-agnostic REST API framework with Zod validation, auto docs & test scaffolding. Express/Koa/@leizm/web adapters as separate packages.", "type": "module", "main": "dist/lib/index.js", diff --git a/packages/erest-express/package.json b/packages/erest-express/package.json index 0a48c3f..9997e0b 100644 --- a/packages/erest-express/package.json +++ b/packages/erest-express/package.json @@ -1,6 +1,6 @@ { "name": "@erest/express", - "version": "3.2.2", + "version": "3.2.4", "description": "Express adapter for erest", "type": "module", "main": "./dist/index.js", diff --git a/packages/erest-gen/package.json b/packages/erest-gen/package.json index a4593cf..08b3508 100644 --- a/packages/erest-gen/package.json +++ b/packages/erest-gen/package.json @@ -1,6 +1,6 @@ { "name": "@erest/gen", - "version": "3.2.2", + "version": "3.2.4", "description": "erest codegen CLI:从 Zod schema 生成 handler 骨架等(实验性,独立于 erest 主版本演进)", "type": "module", "bin": { diff --git a/packages/erest-koa/package.json b/packages/erest-koa/package.json index d633e95..fe5acdb 100644 --- a/packages/erest-koa/package.json +++ b/packages/erest-koa/package.json @@ -1,6 +1,6 @@ { "name": "@erest/koa", - "version": "3.2.2", + "version": "3.2.4", "description": "Koa adapter for erest", "type": "module", "main": "./dist/index.js", diff --git a/packages/erest-leizmweb/package.json b/packages/erest-leizmweb/package.json index ec8256e..45e2d4b 100644 --- a/packages/erest-leizmweb/package.json +++ b/packages/erest-leizmweb/package.json @@ -1,6 +1,6 @@ { "name": "@erest/leizmweb", - "version": "3.2.2", + "version": "3.2.4", "description": "@leizm/web adapter for erest", "type": "module", "main": "./dist/index.js", diff --git a/src/lib/extend/docs.ts b/src/lib/extend/docs.ts index 4718c62..a5a55fd 100644 --- a/src/lib/extend/docs.ts +++ b/src/lib/extend/docs.ts @@ -54,6 +54,7 @@ const DOC_FIELD = [ "tested", "responseSchema", "headersSchema", + "sourceFile", ]; /** 文档数据 */ diff --git a/src/lib/plugin/generate_markdown/apis.ts b/src/lib/plugin/generate_markdown/apis.ts index 666f0a6..49c7614 100644 --- a/src/lib/plugin/generate_markdown/apis.ts +++ b/src/lib/plugin/generate_markdown/apis.ts @@ -109,6 +109,12 @@ export default function apiDocs(data: IDocData) { const line = [`## ${tit} ${tested}`]; line.push(`\n请求地址:**${method}** \`${item.realPath}\``); + // 源码位置(issue #5):sourceFile 由 getCallerSourceLine 在注册时采集 + const sourceRel = (item.sourceFile as { relative?: string } | undefined)?.relative; + if (sourceRel) { + line.push(`\n源码位置:\`${sourceRel}\``); + } + if (item.description) { line.push( (item.description as string) diff --git a/src/test/test-docs-plugins.ts b/src/test/test-docs-plugins.ts index 610ab5f..83d4ac8 100644 --- a/src/test/test-docs-plugins.ts +++ b/src/test/test-docs-plugins.ts @@ -9,6 +9,7 @@ import { describe, expect, test } from "vitest"; import { z } from "zod"; import generateAxios from "../lib/plugin/generate_axios"; +import apiDocs from "../lib/plugin/generate_markdown/apis"; import generatePostman from "../lib/plugin/generate_postman"; import generateSwagger, { buildSwagger } from "../lib/plugin/generate_swagger"; @@ -144,3 +145,38 @@ describe("postman response 示例(issue #6)", () => { expect(item.response).toBeUndefined(); }); }); + +describe("markdown 源码位置展示(issue #5)", () => { + function buildWith(sourceFile?: { relative?: string }) { + const data = { + info: {}, + group: { G: "G" }, + types: {}, + apis: { + "get_/test": { + method: "get", + path: "/test", + realPath: "/test", + group: "G", + title: "测试路由", + examples: [], + requiredOneOf: [], + ...(sourceFile ? { sourceFile } : {}), + }, + }, + } as any; + return apiDocs(data); + } + + test("有 sourceFile.relative 时,Markdown 输出含源码位置", () => { + const { list } = buildWith({ relative: "src/api/user.ts" }); + const content = list[0].content; + expect(content).toContain("src/api/user.ts"); + }); + + test("无 sourceFile 时不报错,且不输出源码位置行", () => { + const { list } = buildWith(undefined); + const content = list[0].content; + expect(content).not.toMatch(/源码位置/); + }); +});