Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -350,3 +350,9 @@ instead」)。`@koa/router` 是官方维护的继任包,API 与 koa-router *
### 影响范围

仅文档生成器(`generate_swagger` / `generate_postman`),不涉及运行时校验、路由绑定或类型推导。已声明 response schema 的项目重新生成文档即可看到变化;未声明的项目输出与之前完全一致。

## v3.2.5 — Markdown 文档展示中间件(issue #4)

### 新增(非 breaking)

- **Markdown 文档输出路由的中间件函数名列表**:`middlewares` 此前已通过 `.middlewares()` 注册并经 `DOC_FIELD` 采集进文档数据,但四个生成器无一渲染。现 Markdown 在「请求地址」行下方输出 `中间件:`<fn1>`, `<fn2>``(取具名函数的 `fn.name`,匿名函数跳过),便于在文档中看到路由的处理链。Swagger/Postman 不受影响(OpenAPI 标准无中间件字段,强行加入反而不被消费方识别)。
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "erest",
"version": "3.2.2",
"version": "3.2.5",
"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",
Expand Down
2 changes: 1 addition & 1 deletion packages/erest-express/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@erest/express",
"version": "3.2.2",
"version": "3.2.5",
"description": "Express adapter for erest",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/erest-gen/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@erest/gen",
"version": "3.2.2",
"version": "3.2.5",
"description": "erest codegen CLI:从 Zod schema 生成 handler 骨架等(实验性,独立于 erest 主版本演进)",
"type": "module",
"bin": {
Expand Down
2 changes: 1 addition & 1 deletion packages/erest-koa/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@erest/koa",
"version": "3.2.2",
"version": "3.2.5",
"description": "Koa adapter for erest",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/erest-leizmweb/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@erest/leizmweb",
"version": "3.2.2",
"version": "3.2.5",
"description": "@leizm/web adapter for erest",
"type": "module",
"main": "./dist/index.js",
Expand Down
11 changes: 11 additions & 0 deletions src/lib/plugin/generate_markdown/apis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,17 @@ export default function apiDocs(data: IDocData) {
const line = [`## ${tit} ${tested}`];
line.push(`\n请求地址:**${method}** \`${item.realPath}\``);

// 中间件(issue #4):输出具名中间件的函数名,匿名函数跳过
const mids = item.middlewares as Set<Function> | undefined;
if (mids && mids.size > 0) {
const names = Array.from(mids)
.map((fn) => (typeof fn === "function" ? fn.name : ""))
.filter((n) => n && n !== "anonymous");
if (names.length > 0) {
line.push(`\n中间件:${names.map((n) => `\`${n}\``).join(", ")}`);
}
}

if (item.description) {
line.push(
(item.description as string)
Expand Down
47 changes: 47 additions & 0 deletions src/test/test-docs-plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -144,3 +145,49 @@ describe("postman response 示例(issue #6)", () => {
expect(item.response).toBeUndefined();
});
});

describe("markdown 中间件展示(issue #4)", () => {
function buildWith(middlewares?: Set<Function>) {
const data = {
info: {},
group: { G: "G" },
types: {},
apis: {
"get_/test": {
method: "get",
path: "/test",
realPath: "/test",
group: "G",
title: "测试路由",
examples: [],
requiredOneOf: [],
...(middlewares ? { middlewares } : {}),
},
},
} as any;
return apiDocs(data);
}

test("有具名中间件时,Markdown 输出中间件名列表", () => {
function authCheck() {}
function logRequest() {}
const { list } = buildWith(new Set([authCheck, logRequest]));
const content = list[0].content;
expect(content).toContain("authCheck");
expect(content).toContain("logRequest");
});

test("无中间件时不报错,且不输出中间件行", () => {
const { list } = buildWith(undefined);
const content = list[0].content;
expect(content).not.toMatch(/中间件/);
});

test("匿名中间件不输出空名(跳过无 name 的函数)", () => {
const anon = function () {};
const { list } = buildWith(new Set([anon]));
const content = list[0].content;
// 不应出现「中间件:」后跟空列表
expect(content).not.toMatch(/中间件:\s*$/);
});
});
Loading