Skip to content

Commit e8cf37f

Browse files
authored
Merge pull request #146 from yourtion/feat/zod
use zod
2 parents abb58f3 + 0de988f commit e8cf37f

114 files changed

Lines changed: 17710 additions & 2807 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.prettierrc.js

Lines changed: 0 additions & 5 deletions
This file was deleted.

.vscode/launch.json

Lines changed: 0 additions & 38 deletions
This file was deleted.

README.md

Lines changed: 132 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -21,75 +21,161 @@
2121
[download-url]: https://npmjs.org/package/erest
2222
[license-image]: https://img.shields.io/npm/l/erest.svg
2323

24-
# node-erest
24+
# ERest
2525

26-
通过简单的方式构建一个优秀的 API 服务(基于 express、@leizm/web 等)。
26+
🚀 **现代化的 TypeScript API 框架** - 通过简单的方式构建优秀的 API 服务
2727

28-
一个优秀的 API 必须要有优秀的文档、较完整的测试,同时便于开发部署与联调。在文档方面,最大的问题在于,随着 API 的发展需要找人同步更新文档。有个更好的方案是不脱离代码自更新文档
28+
基于 Express、@leizm/web 等主流框架,ERest 提供了一套完整的 API 开发解决方案。支持自动文档生成、类型安全验证、测试脚手架等功能,让 API 开发更加高效和可靠
2929

30-
通过 ERest,你可以在定义 API 的同时,完成参数模型的定义、API格式的定义,同时生成便于写 API 测试的脚手架,像调用本地方法一样写 API 测试,并自动完成 API 文档的生成(包括示例数据),同时生成 Swagger、Postman、基于 axios 的 js-sdk(更多功能支持自定义)。
30+
## ✨ 核心特性
3131

32-
使用 (generator-erest)[https://github.com/yourtion/node-generator-erest] 帮助你快速生成一个 API 项目框架。
32+
* 🔷 **TypeScript 原生支持** - 完整的类型推导和类型安全
3333

34-
## Install
34+
* 🔧 **原生 Zod 集成** - 高性能的参数验证和类型推导
3535

36-
```bash
37-
$ npm install erest --save
38-
```
36+
* 📚 **自动文档生成** - 支持 Swagger、Postman、Markdown 等多种格式
37+
38+
* 🧪 **测试脚手架** - 像调用本地方法一样编写 API 测试
39+
40+
* 🔌 **多框架支持** - 兼容 Express、Koa、@leizm/web 等主流框架
41+
42+
* 📦 **SDK 自动生成** - 自动生成基于 axios 的客户端 SDK
43+
44+
* 🎯 **零配置启动** - 开箱即用的开发体验
45+
46+
## 🛠️ 技术栈
3947

40-
### Use yeoman generator
48+
* **语言**: TypeScript 5.8+
49+
50+
* **运行时**: Node.js 18+
51+
52+
* **验证库**: Zod 4.0+
53+
54+
* **支持框架**: Express 4.x, Koa 3.x, @leizm/web 2.x
55+
56+
* **构建工具**: Vite, Biome
57+
58+
* **测试框架**: Vitest
59+
60+
## 📦 安装
4161

4262
```bash
43-
$ npm install generator-erest -g
44-
# Express
45-
$ yo erest:express
46-
# @leizm/web
47-
$ yo erest:lei-web
63+
# npm
64+
npm install erest
65+
66+
# yarn
67+
yarn add erest
68+
69+
# pnpm
70+
pnpm add erest
4871
```
4972

50-
## How to use
73+
### 快速开始脚手架
5174

52-
```javascript
53-
'use strict';
75+
使用 快速生成项目框架:
5476

55-
const API = require('erest').default;
77+
```bash
78+
npm install generator-erest -g
5679

57-
// API info for document
58-
const INFO = {
59-
title: 'erest-demo',
60-
description: 'Easy to write, easy to test, easy to generate document.',
61-
version: new Date(),
62-
host: 'http://127.0.0.1:3000',
63-
basePath: '/api',
64-
};
80+
# Express 项目
81+
yo erest:express
6582

66-
// API group info
67-
const GROUPS = {
68-
Index: '首页',
69-
};
83+
# @leizm/web 项目
84+
yo erest:lei-web
85+
```
7086

71-
// Init API
72-
const apiService = new API({
73-
info: INFO,
74-
groups: GROUPS,
87+
## 🚀 快速开始
88+
89+
### 基础用法
90+
91+
```typescript
92+
import ERest, { z } from 'erest';
93+
import express from 'express';
94+
95+
// 创建 ERest 实例
96+
const api = new ERest({
97+
info: {
98+
title: 'My API',
99+
description: 'A powerful API built with ERest',
100+
version: new Date(),
101+
host: 'http://localhost:3000',
102+
basePath: '/api',
103+
},
104+
groups: {
105+
user: '用户管理',
106+
post: '文章管理',
107+
},
75108
});
76109

77-
apiService.api.get('/index')
78-
.group('Index')
79-
.title('Test api')
80-
.register((req, res) => {
81-
res.end('Hello, API Framework Index');
110+
// 定义 API 接口
111+
api.api.get('/users/:id')
112+
.group('user')
113+
.title('获取用户信息')
114+
.params(z.object({
115+
id: z.string().describe('用户ID'),
116+
}))
117+
.query(z.object({
118+
include: z.string().optional().describe('包含的关联数据'),
119+
}))
120+
.register(async (req, res) => {
121+
const { id } = req.params;
122+
const { include } = req.query;
123+
124+
// 业务逻辑
125+
const user = await getUserById(id, include);
126+
res.json({ success: true, data: user });
82127
});
83128

84-
const express = require('express');
129+
// 绑定到 Express
85130
const app = express();
86-
const router = new express.Router();
131+
const router = express.Router();
87132
app.use('/api', router);
88133

89-
// bing express router
90-
apiService.bindRouter(router, apiService.checkerExpress);
134+
api.bindRouter(router, api.checkerExpress);
135+
136+
app.listen(3000, () => {
137+
console.log('🚀 Server running on http://localhost:3000');
138+
});
139+
```
140+
141+
### 原生 Zod 类型支持
142+
143+
```typescript
144+
import { z } from 'erest';
145+
146+
// 定义复杂的数据模型
147+
const CreateUserSchema = z.object({
148+
name: z.string().min(1).max(50),
149+
email: z.string().email(),
150+
age: z.number().int().min(18).max(120),
151+
tags: z.array(z.string()).optional(),
152+
profile: z.object({
153+
bio: z.string().optional(),
154+
avatar: z.string().url().optional(),
155+
}).optional(),
156+
});
157+
158+
api.api.post('/users')
159+
.group('user')
160+
.title('创建用户')
161+
.body(CreateUserSchema)
162+
.register(async (req, res) => {
163+
// req.body 自动获得完整的类型推导
164+
const userData = req.body; // 类型安全!
165+
166+
const user = await createUser(userData);
167+
res.json({ success: true, data: user });
168+
});
169+
```
170+
171+
### 自动文档生成
91172

92-
app.listen(3000, function () {
93-
console.log('erest-demo listening started');
173+
```typescript
174+
// 生成多种格式的文档
175+
api.docs.generateDocs({
176+
swagger: './docs/swagger.json',
177+
markdown: './docs/api.md',
178+
postman: './docs/postman.json',
179+
axios: './sdk/api-client.js',
94180
});
95181
```

biome.json

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"$schema": "https://biomejs.dev/schemas/2.1.2/schema.json",
3+
"vcs": {
4+
"enabled": false,
5+
"clientKind": "git",
6+
"useIgnoreFile": false
7+
},
8+
"files": {
9+
"ignoreUnknown": false,
10+
"includes": ["src/**/*.ts", "src/**/*.js"]
11+
},
12+
"formatter": {
13+
"enabled": true,
14+
"indentStyle": "space",
15+
"indentWidth": 2,
16+
"lineWidth": 120
17+
},
18+
"linter": {
19+
"enabled": true,
20+
"rules": {
21+
"recommended": true
22+
}
23+
},
24+
"javascript": {
25+
"formatter": {
26+
"quoteStyle": "double",
27+
"trailingCommas": "es5"
28+
}
29+
},
30+
"assist": {
31+
"enabled": true,
32+
"actions": {
33+
"source": {
34+
"organizeImports": "on"
35+
}
36+
}
37+
}
38+
}

docs/assets/hierarchy.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/assets/highlight.css

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
:root {
2-
--light-hl-0: #795E26;
3-
--dark-hl-0: #DCDCAA;
4-
--light-hl-1: #000000;
5-
--dark-hl-1: #D4D4D4;
6-
--light-hl-2: #A31515;
7-
--dark-hl-2: #CE9178;
8-
--light-hl-3: #0000FF;
9-
--dark-hl-3: #569CD6;
10-
--light-hl-4: #008000;
11-
--dark-hl-4: #6A9955;
12-
--light-hl-5: #0070C1;
13-
--dark-hl-5: #4FC1FF;
2+
--light-hl-0: #008000;
3+
--dark-hl-0: #6A9955;
4+
--light-hl-1: #795E26;
5+
--dark-hl-1: #DCDCAA;
6+
--light-hl-2: #000000;
7+
--dark-hl-2: #D4D4D4;
8+
--light-hl-3: #A31515;
9+
--dark-hl-3: #CE9178;
10+
--light-hl-4: #0000FF;
11+
--dark-hl-4: #569CD6;
12+
--light-hl-5: #AF00DB;
13+
--dark-hl-5: #C586C0;
1414
--light-hl-6: #001080;
1515
--dark-hl-6: #9CDCFE;
16-
--light-hl-7: #098658;
17-
--dark-hl-7: #B5CEA8;
16+
--light-hl-7: #0070C1;
17+
--dark-hl-7: #4FC1FF;
18+
--light-hl-8: #098658;
19+
--dark-hl-8: #B5CEA8;
1820
--light-code-background: #FFFFFF;
1921
--dark-code-background: #1E1E1E;
2022
}
@@ -28,6 +30,7 @@
2830
--hl-5: var(--light-hl-5);
2931
--hl-6: var(--light-hl-6);
3032
--hl-7: var(--light-hl-7);
33+
--hl-8: var(--light-hl-8);
3134
--code-background: var(--light-code-background);
3235
} }
3336

@@ -40,6 +43,7 @@
4043
--hl-5: var(--dark-hl-5);
4144
--hl-6: var(--dark-hl-6);
4245
--hl-7: var(--dark-hl-7);
46+
--hl-8: var(--dark-hl-8);
4347
--code-background: var(--dark-code-background);
4448
} }
4549

@@ -52,6 +56,7 @@
5256
--hl-5: var(--light-hl-5);
5357
--hl-6: var(--light-hl-6);
5458
--hl-7: var(--light-hl-7);
59+
--hl-8: var(--light-hl-8);
5560
--code-background: var(--light-code-background);
5661
}
5762

@@ -64,6 +69,7 @@
6469
--hl-5: var(--dark-hl-5);
6570
--hl-6: var(--dark-hl-6);
6671
--hl-7: var(--dark-hl-7);
72+
--hl-8: var(--dark-hl-8);
6773
--code-background: var(--dark-code-background);
6874
}
6975

@@ -75,4 +81,5 @@
7581
.hl-5 { color: var(--hl-5); }
7682
.hl-6 { color: var(--hl-6); }
7783
.hl-7 { color: var(--hl-7); }
84+
.hl-8 { color: var(--hl-8); }
7885
pre, code { background: var(--code-background); }

0 commit comments

Comments
 (0)