mas-server 3.0.42 → 4.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +408 -7
- package/dist/getApp/apiHandler.d.ts +42 -0
- package/dist/getApp/apiHandler.d.ts.map +1 -0
- package/dist/getApp/config.d.ts +22 -0
- package/dist/getApp/config.d.ts.map +1 -0
- package/dist/getApp/docTransform.d.ts +41 -0
- package/dist/getApp/docTransform.d.ts.map +1 -0
- package/dist/getApp/fsRoutes.d.ts +17 -0
- package/dist/getApp/fsRoutes.d.ts.map +1 -0
- package/dist/getApp/getApp.d.ts +11 -0
- package/dist/getApp/getApp.d.ts.map +1 -0
- package/dist/getApp/logs.d.ts +29 -0
- package/dist/getApp/logs.d.ts.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -121
- package/dist/middleware/openCors.d.ts +9 -0
- package/dist/middleware/openCors.d.ts.map +1 -0
- package/dist/type.d.ts +183 -0
- package/dist/type.d.ts.map +1 -0
- package/dist/utils/mas-encrypt.min.d.ts +6 -0
- package/dist/utils/mas-encrypt.min.d.ts.map +1 -0
- package/dist/utils/quickSend.d.ts +8 -0
- package/dist/utils/quickSend.d.ts.map +1 -0
- package/dist/utils/tokenUtils.d.ts +54 -0
- package/dist/utils/tokenUtils.d.ts.map +1 -0
- package/dist/utils/typeFromValidFormat.d.ts +81 -0
- package/dist/utils/typeFromValidFormat.d.ts.map +1 -0
- package/dist/utils/validType.d.ts +17 -0
- package/dist/utils/validType.d.ts.map +1 -0
- package/package.json +43 -46
- package/.temp/.keep +0 -0
- package/.temp/getRouteByApiSrc.ts +0 -55
- package/.temp/merge/a.ts +0 -4
- package/.temp/merge/as.ts +0 -1
- package/.temp/merge/b.ts +0 -3
- package/.temp/merge/i.js +0 -103
- package/.temp/merge/logs/.keep +0 -0
- package/.temp/merge/test.ts +0 -2
- package/.temp/merge/validType copy.ts +0 -149
- package/.temp/merge/validType.ts +0 -98
- package/.temp/merge/validTypeOptimize.ts +0 -98
- package/.temp/updateRouter.ts +0 -46
- package/.vscode/settings.json +0 -3
- package/beforebuild.js +0 -9
- package/dist/state.js +0 -4
- package/dist/typings/index.js +0 -2
- package/dist/utils/apiLimit.js +0 -20
- package/dist/utils/createRouter.js +0 -81
- package/dist/utils/getRouterInfo.js +0 -56
- package/dist/utils/logs.js +0 -58
- package/dist/utils/mas-encrypt.min.js +0 -1
- package/dist/utils/masUtils.js +0 -10
- package/dist/utils/meaToken.js +0 -57
- package/dist/utils/printLog.js +0 -12
- package/dist/utils/quickSend.js +0 -37
- package/dist/utils/readApi.js +0 -60
- package/dist/utils/validRouteData.js +0 -37
- package/dist/utils/validToken.js +0 -24
- package/dist/utils/validType.js +0 -84
- package/src/index.ts +0 -98
- package/src/state.ts +0 -1
- package/src/typings/index.ts +0 -113
- package/src/utils/apiLimit.ts +0 -15
- package/src/utils/createRouter.ts +0 -34
- package/src/utils/getRouterInfo.ts +0 -49
- package/src/utils/logs.ts +0 -21
- package/src/utils/mas-encrypt.min.js +0 -1
- package/src/utils/masUtils.ts +0 -7
- package/src/utils/meaToken.ts +0 -56
- package/src/utils/printLog.ts +0 -12
- package/src/utils/quickSend.ts +0 -25
- package/src/utils/readApi.ts +0 -28
- package/src/utils/validRouteData.ts +0 -45
- package/src/utils/validToken.ts +0 -22
- package/src/utils/validType.ts +0 -81
- package/test/apiTemplate/curd/del.ts +0 -9
- package/test/apiTemplate/curd/get.ts +0 -9
- package/test/apiTemplate/curd/set.ts +0 -9
- package/test/apiTemplate/defaultApi.ts +0 -8
- package/test/config/serverConfig/config.ts +0 -29
- package/test/config/sqlConfig/createSqlFormData.ts +0 -13
- package/test/logs/.keep +0 -0
- package/test/main.ts +0 -29
- package/test/scripts/beforeCreated.ts +0 -28
- package/test/scripts/createApiFile.ts +0 -26
- package/test/scripts/createApis.ts +0 -61
- package/test/scripts/createSqlForm.ts +0 -5
- package/test/scripts/getSqlFormType.ts +0 -23
- package/test/scripts/run.ts +0 -4
- package/test/src/api/example/ArrValid.ts +0 -11
- package/test/src/api/example/per.ts +0 -34
- package/test/src/api/example/tip.ts +0 -7
- package/test/src/api/example/validReqData.ts +0 -82
- package/test/src/api/index.ts +0 -9
- package/test/src/apiDoc.ts +0 -34
- package/test/src/debug.ts +0 -5
- package/test/src/masState.ts +0 -4
- package/test/src/sqlform.json +0 -1
- package/test/test.ts +0 -1
- package/tsconfig-build.json +0 -20
- package/tsconfig.json +0 -21
- package/tsconfigschema.json +0 -1263
package/README.md
CHANGED
|
@@ -1,7 +1,408 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
# mas-server
|
|
2
|
+
|
|
3
|
+
一行代码,实现约定式路由,自带常用业务功能,开箱即用,让你的express飞起来
|
|
4
|
+
|
|
5
|
+
## ✨ 特性
|
|
6
|
+
|
|
7
|
+
- 🚀 **约定式路由** - 自动扫描 API 文件,根据文件路径生成路由
|
|
8
|
+
- 🔒 **权限管理** - 基于 JWT Token 的权限验证系统
|
|
9
|
+
- 📝 **类型安全** - 通过 `requestFormat` 和 `responseFormat` 实现类型推导和运行时校验
|
|
10
|
+
- 📊 **日志管理** - 支持访问日志(控制台和文件),可记录请求/响应体
|
|
11
|
+
- 🎯 **统一响应格式** - 提供 `res.reply()` 等便捷方法
|
|
12
|
+
- 🌐 **CORS 支持** - 可配置的跨域支持
|
|
13
|
+
- 📁 **静态文件服务** - 支持静态文件目录
|
|
14
|
+
- 📖 **API 文档** - 自动生成 API 文档(通过 `/debug/docs` 访问)
|
|
15
|
+
|
|
16
|
+
## 📦 安装
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install mas-server
|
|
20
|
+
# 或
|
|
21
|
+
bun add mas-server
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## 🚀 快速开始
|
|
25
|
+
|
|
26
|
+
### 1. 编写 API
|
|
27
|
+
|
|
28
|
+
创建 `src/apis/user/login.ts`:
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import type { MasConfig, MasHandler } from 'mas-server';
|
|
32
|
+
|
|
33
|
+
export const config: MasConfig = {
|
|
34
|
+
requestFormat: { username: String, password: String },
|
|
35
|
+
responseFormat: { token: String },
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const handler: MasHandler<typeof config> = async (req, res) => {
|
|
39
|
+
res.reply({ token: 'xxx' });
|
|
40
|
+
};
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 2. 启动服务
|
|
44
|
+
|
|
45
|
+
创建 `main.ts`:
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
import { getApp } from 'mas-server';
|
|
49
|
+
import { fileURLToPath } from 'url';
|
|
50
|
+
import path from 'path';
|
|
51
|
+
|
|
52
|
+
(await getApp(path.dirname(fileURLToPath(import.meta.url)))).listen(8087);
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
运行:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
bun run main.ts
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
就这么简单!访问 `http://localhost:8087/api/user/login` 即可。
|
|
62
|
+
|
|
63
|
+
## 📚 核心功能
|
|
64
|
+
|
|
65
|
+
### 约定式路由
|
|
66
|
+
|
|
67
|
+
框架会自动扫描 `src/apis` 或 `apis` 目录下的 `.ts`/`.js` 文件,根据文件路径生成路由:
|
|
68
|
+
|
|
69
|
+
- `src/apis/index.ts` → `/api/`
|
|
70
|
+
- `src/apis/user/index.ts` → `/api/user`
|
|
71
|
+
- `src/apis/user/login.ts` → `/api/user/login`
|
|
72
|
+
- `src/apis/user/profile.ts` → `/api/user/profile`
|
|
73
|
+
|
|
74
|
+
所有路由都会自动添加 `/api` 前缀。
|
|
75
|
+
|
|
76
|
+
### 类型安全
|
|
77
|
+
|
|
78
|
+
通过 `requestFormat` 和 `responseFormat` 定义请求和响应的数据结构,框架会:
|
|
79
|
+
|
|
80
|
+
1. **类型推导** - 自动推导 `req.body` 和 `res.reply()` 的类型
|
|
81
|
+
2. **运行时校验** - 自动校验请求参数格式,不符合格式的请求会返回 400 错误
|
|
82
|
+
|
|
83
|
+
#### 支持的类型
|
|
84
|
+
|
|
85
|
+
- **基础类型**:`String`、`Number`、`Boolean`、`Object`
|
|
86
|
+
- **可选字段**:
|
|
87
|
+
- `_String` - 可选字符串(`'?'`)
|
|
88
|
+
- `_Number` - 可选数字(`-1`)
|
|
89
|
+
- **数组**:`[String]`、`[Number]`、`[{...}]`
|
|
90
|
+
- **嵌套对象**:`{ key: String, nested: { ... } }`
|
|
91
|
+
|
|
92
|
+
#### 示例
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
const requestFormat = {
|
|
96
|
+
name: String, // 必填字符串
|
|
97
|
+
age: _Number, // 可选数字
|
|
98
|
+
email: _String, // 可选字符串
|
|
99
|
+
tags: [String], // 字符串数组
|
|
100
|
+
address: {
|
|
101
|
+
// 嵌套对象
|
|
102
|
+
city: String,
|
|
103
|
+
zipCode: _String,
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const config: MasConfig<typeof requestFormat> = {
|
|
108
|
+
requestFormat,
|
|
109
|
+
strict: false, // strict=true 时不允许多余字段
|
|
110
|
+
};
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Token 验证
|
|
114
|
+
|
|
115
|
+
框架提供了完整的 JWT Token 系统:
|
|
116
|
+
|
|
117
|
+
#### 创建 Token
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
import { createToken } from 'mas-server';
|
|
121
|
+
|
|
122
|
+
const token = createToken(
|
|
123
|
+
{
|
|
124
|
+
data: { userId: 123, username: 'admin' },
|
|
125
|
+
time: 3600, // 过期时间(秒),0 表示永不过期
|
|
126
|
+
permission: ['admin', 'user'], // 权限列表
|
|
127
|
+
},
|
|
128
|
+
'your-secret-key'
|
|
129
|
+
);
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
#### 验证 Token
|
|
133
|
+
|
|
134
|
+
在接口配置中启用 token 验证:
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
export const config: MasConfig = {
|
|
138
|
+
token: true, // 启用 token 验证
|
|
139
|
+
permission: ['admin'], // 需要的权限(只要有一个即可)
|
|
140
|
+
};
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Token 可以通过以下方式传递:
|
|
144
|
+
|
|
145
|
+
- Header: `token: xxx`
|
|
146
|
+
- Query: `?token=xxx`
|
|
147
|
+
- Body: `{ token: 'xxx' }`
|
|
148
|
+
|
|
149
|
+
#### 在接口中获取 Token 数据
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
export const handler: MasHandler = async (req, res) => {
|
|
153
|
+
const tokenData = (req as any).tokenData;
|
|
154
|
+
// tokenData.data 包含创建 token 时传入的 data
|
|
155
|
+
// tokenData._permission 包含权限列表
|
|
156
|
+
// tokenData._masTime 包含过期时间戳
|
|
157
|
+
};
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### 统一响应格式
|
|
161
|
+
|
|
162
|
+
框架提供了 `res.reply()` 方法,统一返回格式:
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// 成功响应
|
|
166
|
+
res.reply(data, 1, 200, '操作成功');
|
|
167
|
+
|
|
168
|
+
// 失败响应
|
|
169
|
+
res.reply(null, 0, 400, '参数错误');
|
|
170
|
+
|
|
171
|
+
// 简化写法(自动判断 status)
|
|
172
|
+
res.reply(data); // data 存在时 status=1,否则 status=0
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
响应格式:
|
|
176
|
+
|
|
177
|
+
```json
|
|
178
|
+
{
|
|
179
|
+
"status": 1,
|
|
180
|
+
"code": 200,
|
|
181
|
+
"msg": "操作成功",
|
|
182
|
+
"data": { ... }
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### 日志管理
|
|
187
|
+
|
|
188
|
+
框架支持两种日志:
|
|
189
|
+
|
|
190
|
+
1. **控制台日志** - 开发时使用,实时打印访问日志
|
|
191
|
+
2. **文件日志** - 生产环境使用,按天滚动,单文件最大 50MB
|
|
192
|
+
|
|
193
|
+
#### 配置示例
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
const app = await getApp(__dirname, {
|
|
197
|
+
logs: {
|
|
198
|
+
open: true, // 是否开启文件日志
|
|
199
|
+
debug: true, // 是否开启控制台日志
|
|
200
|
+
logPath: './logs', // 日志文件目录
|
|
201
|
+
logRequestBody: true, // 是否记录请求体
|
|
202
|
+
logResponseBody: true, // 是否记录响应体
|
|
203
|
+
maxBodyLength: 2000, // body 最大记录长度
|
|
204
|
+
redactKeys: ['password', 'token'], // 需要打码的字段
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### CORS 配置
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
const app = await getApp(__dirname, {
|
|
213
|
+
openCors: true,
|
|
214
|
+
corsUrl: [
|
|
215
|
+
'http://localhost:3000',
|
|
216
|
+
'https://example.com',
|
|
217
|
+
'*.example.com', // 支持通配符
|
|
218
|
+
],
|
|
219
|
+
});
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### 静态文件服务
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
const app = await getApp(__dirname, {
|
|
226
|
+
staticPath: './public', // 静态文件目录
|
|
227
|
+
staticUrl: '/public', // 访问路径前缀
|
|
228
|
+
});
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
访问:`http://localhost:8087/public/file.txt`
|
|
232
|
+
|
|
233
|
+
### API 文档
|
|
234
|
+
|
|
235
|
+
框架会自动生成 API 文档,访问 `/debug/docs` 即可查看所有接口的配置和文档信息。
|
|
236
|
+
|
|
237
|
+
可以通过配置关闭:
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
const app = await getApp(__dirname, {
|
|
241
|
+
exposeApiDocs: false, // 关闭 API 文档
|
|
242
|
+
});
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### 接口配置选项
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
export const config: MasConfig = {
|
|
249
|
+
name: '接口名称', // 接口名称(用于文档)
|
|
250
|
+
methods: 'post', // HTTP 方法:'get' | 'post' | 'all'
|
|
251
|
+
contentType: 'application/json', // Content-Type 校验
|
|
252
|
+
strict: false, // 严格模式(不允许多余字段)
|
|
253
|
+
header: { // Header 参数校验
|
|
254
|
+
'X-Custom-Header': String,
|
|
255
|
+
},
|
|
256
|
+
requestFormat: { ... }, // 请求体格式
|
|
257
|
+
responseFormat: { ... }, // 响应体格式
|
|
258
|
+
token: true, // 是否需要 token
|
|
259
|
+
permission: ['admin'], // 需要的权限
|
|
260
|
+
};
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### 兜底接口
|
|
264
|
+
|
|
265
|
+
可以配置一个默认接口,当所有路由都不匹配时调用:
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
const app = await getApp(__dirname, {
|
|
269
|
+
defalutApiPath: path.join(__dirname, 'src/apis/fallback.ts'),
|
|
270
|
+
});
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
如果不配置,404 请求会返回:
|
|
274
|
+
|
|
275
|
+
```json
|
|
276
|
+
{
|
|
277
|
+
"status": 0,
|
|
278
|
+
"code": 404,
|
|
279
|
+
"msg": "Not Found",
|
|
280
|
+
"data": null
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## 🔧 完整配置选项
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
interface MasAppConfig {
|
|
288
|
+
// 日志配置
|
|
289
|
+
logs: {
|
|
290
|
+
open: boolean; // 是否记录日志
|
|
291
|
+
debug: boolean; // 是否打印访问日志
|
|
292
|
+
logPath?: string; // 日志路径,默认 logs/
|
|
293
|
+
logRequestBody?: boolean; // 是否记录请求体,默认 true
|
|
294
|
+
logResponseBody?: boolean; // 是否记录响应体,默认 true
|
|
295
|
+
maxBodyLength?: number; // body 最大记录长度,默认 2000
|
|
296
|
+
redactKeys?: string[]; // 需要打码的字段名,默认 []
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
// Token 配置
|
|
300
|
+
token: {
|
|
301
|
+
open: boolean; // 是否使用 token
|
|
302
|
+
pwd: string; // token 密钥
|
|
303
|
+
headerParams: string; // 参数名,默认 'token'
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
// 路径配置
|
|
307
|
+
apisPath?: string; // 接口路径,默认 src/apis 或 apis/
|
|
308
|
+
defalutApiPath?: string; // 兜底接口文件路径
|
|
309
|
+
|
|
310
|
+
// 其他配置
|
|
311
|
+
projectName?: string; // 项目名称,默认 'mas-app'
|
|
312
|
+
openCors?: boolean; // 是否允许跨域,默认 false
|
|
313
|
+
corsUrl?: string[]; // 跨域允许的地址
|
|
314
|
+
staticPath?: string; // 静态文件目录路径,默认 public/
|
|
315
|
+
staticUrl?: string; // 静态资源访问路径前缀,默认 /public
|
|
316
|
+
exposeApiDocs?: boolean; // 是否暴露接口文档,默认 true
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## 📖 更多示例
|
|
321
|
+
|
|
322
|
+
### 带 Header 校验的接口
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
const header = {
|
|
326
|
+
'X-API-Key': String,
|
|
327
|
+
'X-Version': Number,
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
export const config: MasConfig<
|
|
331
|
+
typeof requestFormat,
|
|
332
|
+
typeof responseFormat,
|
|
333
|
+
typeof header
|
|
334
|
+
> = {
|
|
335
|
+
header,
|
|
336
|
+
// ...
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
export const handler: MasHandler<typeof config> = async (req, res) => {
|
|
340
|
+
// Header 已自动校验,可以直接使用
|
|
341
|
+
const apiKey = req.headers['x-api-key'];
|
|
342
|
+
// ...
|
|
343
|
+
};
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### API 文档示例
|
|
347
|
+
|
|
348
|
+
创建 `src/apisDoc/user/login.ts`:
|
|
349
|
+
|
|
350
|
+
```typescript
|
|
351
|
+
import type { ApisDoc } from 'mas-server';
|
|
352
|
+
|
|
353
|
+
export default {
|
|
354
|
+
header: {
|
|
355
|
+
example: { token: 'xxx' },
|
|
356
|
+
desc: [{ name: 'token', desc: '用户 token' }],
|
|
357
|
+
},
|
|
358
|
+
request: {
|
|
359
|
+
example: {
|
|
360
|
+
username: 'admin',
|
|
361
|
+
password: '123456',
|
|
362
|
+
},
|
|
363
|
+
desc: [
|
|
364
|
+
{ name: 'username', desc: '用户名' },
|
|
365
|
+
{ name: 'password', desc: '密码' },
|
|
366
|
+
],
|
|
367
|
+
},
|
|
368
|
+
response: {
|
|
369
|
+
example: {
|
|
370
|
+
token: 'xxx',
|
|
371
|
+
userId: 123,
|
|
372
|
+
},
|
|
373
|
+
desc: [
|
|
374
|
+
{ name: 'token', desc: '登录 token' },
|
|
375
|
+
{ name: 'userId', desc: '用户 ID' },
|
|
376
|
+
],
|
|
377
|
+
},
|
|
378
|
+
} satisfies ApisDoc;
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
在接口文件中引入:
|
|
382
|
+
|
|
383
|
+
```typescript
|
|
384
|
+
import doc from '../apisDoc/user/login';
|
|
385
|
+
|
|
386
|
+
export const doc = doc;
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
## 🛠️ 开发
|
|
390
|
+
|
|
391
|
+
```bash
|
|
392
|
+
# 构建
|
|
393
|
+
bun run build
|
|
394
|
+
|
|
395
|
+
# 开发模式(监听文件变化)
|
|
396
|
+
bun run testServer
|
|
397
|
+
|
|
398
|
+
# 调试
|
|
399
|
+
bun run debug
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
## 📄 License
|
|
403
|
+
|
|
404
|
+
MIT
|
|
405
|
+
|
|
406
|
+
## 🤝 贡献
|
|
407
|
+
|
|
408
|
+
欢迎提交 Issue 和 Pull Request!
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { GetRequestFormat, MasAppConfig, MasConfig, MasHandler } from '../type';
|
|
2
|
+
import express from 'express';
|
|
3
|
+
export type LoadedApiModule = {
|
|
4
|
+
config?: MasConfig;
|
|
5
|
+
handler?: MasHandler<any>;
|
|
6
|
+
doc?: any;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* 将 `req.query` 规范化为可用于 `validType` 的纯对象:
|
|
10
|
+
* - 仅接受 string/string[]
|
|
11
|
+
* - 其它类型(object/number/boolean 等)直接判定为非法
|
|
12
|
+
*
|
|
13
|
+
* @param query - express req.query
|
|
14
|
+
*/
|
|
15
|
+
export declare function normalizeGetQuery(query: unknown): {
|
|
16
|
+
ok: true;
|
|
17
|
+
value: Record<string, string>;
|
|
18
|
+
} | {
|
|
19
|
+
ok: false;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* 判断 GET 请求的 requestFormat 是否满足约束:
|
|
23
|
+
* - 必须是扁平对象:`Record<string, String | '?'>`
|
|
24
|
+
* - 不允许数组/嵌套对象/Number/Boolean/Object/-1
|
|
25
|
+
*
|
|
26
|
+
* @param format - requestFormat
|
|
27
|
+
*/
|
|
28
|
+
export declare function isGetOnlyStringFormat(format: unknown): format is GetRequestFormat;
|
|
29
|
+
/**
|
|
30
|
+
* 根据已加载的 API 模块创建路由处理器,并在调用前做:
|
|
31
|
+
* - method 校验
|
|
32
|
+
* - content-type 校验(仅在配置了 `contentType` 且存在 body 时)
|
|
33
|
+
* - header 校验
|
|
34
|
+
* - token 校验 + permission 校验
|
|
35
|
+
* - requestFormat 校验
|
|
36
|
+
*
|
|
37
|
+
* @param filePath - API 文件路径(仅用于错误信息)
|
|
38
|
+
* @param mod - 已加载的 API 模块
|
|
39
|
+
* @param appConfig - 应用配置(用于 token 相关逻辑)
|
|
40
|
+
*/
|
|
41
|
+
export declare function createApiHandler(filePath: string, mod: LoadedApiModule, appConfig: MasAppConfig): express.RequestHandler;
|
|
42
|
+
//# sourceMappingURL=apiHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiHandler.d.ts","sourceRoot":"","sources":["../../src/getApp/apiHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACZ,SAAS,EACT,UAAU,EACX,MAAM,SAAS,CAAC;AACjB,OAAO,OAAO,MAAM,SAAS,CAAC;AAK9B,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,OAAO,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC;IAC1B,GAAG,CAAC,EAAE,GAAG,CAAC;CACX,CAAC;AA0BF;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,GACb;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CAU7D;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,OAAO,GACd,MAAM,IAAI,gBAAgB,CAO5B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,eAAe,EACpB,SAAS,EAAE,YAAY,GACtB,OAAO,CAAC,cAAc,CA2HxB"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { MasAppConfig } from '../type';
|
|
2
|
+
/**
|
|
3
|
+
* 默认应用配置(会在 getApp 内根据 dirname 补全路径字段)。
|
|
4
|
+
*/
|
|
5
|
+
export declare const defaultConfig: MasAppConfig;
|
|
6
|
+
/**
|
|
7
|
+
* 深度合并 `MasAppConfig`(仅处理一层嵌套的 `logs/token`,避免浅合并误覆盖)。
|
|
8
|
+
*
|
|
9
|
+
* @param base - 默认配置
|
|
10
|
+
* @param override - 用户配置
|
|
11
|
+
*/
|
|
12
|
+
export declare function mergeAppConfig(base: MasAppConfig, override?: MasAppConfig): MasAppConfig;
|
|
13
|
+
/**
|
|
14
|
+
* 根据传入的 dirname 自动探测 apis 目录(兼容 `src/apis` 与 `apis` 两种结构)。
|
|
15
|
+
*
|
|
16
|
+
* @param dirname - 项目根目录
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolveApisPaths(dirname: string): {
|
|
19
|
+
apisPath: string;
|
|
20
|
+
defalutApiPath: string;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/getApp/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAI5C;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,YAa3B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,YAAY,EAClB,QAAQ,CAAC,EAAE,YAAY,GACtB,YAAY,CAQd;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB,CAkBA"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { MasConfig } from '../type';
|
|
2
|
+
type AnyRecord = Record<string, any>;
|
|
3
|
+
/**
|
|
4
|
+
* 将 ValidFormat(包含构造器/函数)转换成可 JSON 序列化的结构:
|
|
5
|
+
* - String/Number/... -> "String" / "Number" ...
|
|
6
|
+
* - { a: String } -> { a: "String" }
|
|
7
|
+
* - [String] -> ["String"]
|
|
8
|
+
*
|
|
9
|
+
* @param format - ValidFormat
|
|
10
|
+
*/
|
|
11
|
+
export declare function serializeValidFormat(format: unknown): any;
|
|
12
|
+
type DescItem = {
|
|
13
|
+
name: string;
|
|
14
|
+
desc: string;
|
|
15
|
+
type?: any;
|
|
16
|
+
};
|
|
17
|
+
type SectionDocView = {
|
|
18
|
+
example: AnyRecord;
|
|
19
|
+
desc: DescItem[];
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* 生成 debug docs 用的 config 视图(把 requestFormat/responseFormat/header 转成可 JSON 序列化结构)。
|
|
23
|
+
*
|
|
24
|
+
* @param config - API config
|
|
25
|
+
*/
|
|
26
|
+
export declare function serializeMasConfigForDoc(config: MasConfig | undefined): any;
|
|
27
|
+
/**
|
|
28
|
+
* 生成 debug docs 用的 doc 视图:
|
|
29
|
+
* - 若用户提供 doc,则补齐 desc.type(从格式里推导)
|
|
30
|
+
* - 若没提供 doc,则从格式生成 example + desc
|
|
31
|
+
*
|
|
32
|
+
* @param config - API config
|
|
33
|
+
* @param doc - API doc(模块导出)
|
|
34
|
+
*/
|
|
35
|
+
export declare function buildApiDocForDebug(config: MasConfig | undefined, doc: any): {
|
|
36
|
+
header: SectionDocView | undefined;
|
|
37
|
+
request: SectionDocView | undefined;
|
|
38
|
+
response: SectionDocView | undefined;
|
|
39
|
+
};
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=docTransform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docTransform.d.ts","sourceRoot":"","sources":["../../src/getApp/docTransform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGzC,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAErC;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,GAAG,GAAG,CAqBzD;AA6CD,KAAK,QAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,GAAG,CAAA;CAAE,CAAC;AAqE3D,KAAK,cAAc,GAAG;IACpB,OAAO,EAAE,SAAS,CAAC;IACnB,IAAI,EAAE,QAAQ,EAAE,CAAC;CAClB,CAAC;AAyCF;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,GAAG,CAY3E;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,EAAE,GAAG,EAAE,GAAG;;;;EAM1E"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 同步遍历目录,收集 `.ts/.js` API 文件路径(排除 `.d.ts`)。
|
|
3
|
+
*
|
|
4
|
+
* @param dir - apis 根目录
|
|
5
|
+
*/
|
|
6
|
+
export declare function walkApiFilesSync(dir: string): string[];
|
|
7
|
+
/**
|
|
8
|
+
* 将 api 文件路径映射为路由路径:
|
|
9
|
+
* - `apis/index.ts` -> `/`
|
|
10
|
+
* - `apis/user/index.ts` -> `/user`
|
|
11
|
+
* - `apis/user/login.ts` -> `/user/login`
|
|
12
|
+
*
|
|
13
|
+
* @param apisRoot - apis 根目录
|
|
14
|
+
* @param filePath - API 文件路径
|
|
15
|
+
*/
|
|
16
|
+
export declare function toRoutePath(apisRoot: string, filePath: string): string;
|
|
17
|
+
//# sourceMappingURL=fsRoutes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fsRoutes.d.ts","sourceRoot":"","sources":["../../src/getApp/fsRoutes.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAwBtD;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQtE"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Express } from 'express';
|
|
2
|
+
import type { MasAppConfig } from '../type';
|
|
3
|
+
/**
|
|
4
|
+
* 创建 MAS Express 应用并挂载约定式路由。
|
|
5
|
+
*
|
|
6
|
+
* @param dirname - 项目根目录(默认会在其中探测 `src/apis` 或 `apis`)
|
|
7
|
+
* @param config - 应用配置(会与默认配置合并)
|
|
8
|
+
* @param beforeMounted - 在框架挂载中间件/路由前的回调(可用于注册自定义中间件)
|
|
9
|
+
*/
|
|
10
|
+
export declare function getApp(dirname: string, config?: MasAppConfig, beforeMounted?: (_app: Express) => void): Promise<import("express-serve-static-core").Express>;
|
|
11
|
+
//# sourceMappingURL=getApp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getApp.d.ts","sourceRoot":"","sources":["../../src/getApp/getApp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,KAAK,EAAE,YAAY,EAAa,MAAM,SAAS,CAAC;AAavD;;;;;;GAMG;AACH,wBAAsB,MAAM,CAC1B,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,YAAY,EACrB,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,wDAmIxC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Express } from 'express';
|
|
2
|
+
export type AccessLogOptions = {
|
|
3
|
+
/** 是否记录请求体 */
|
|
4
|
+
logRequestBody?: boolean;
|
|
5
|
+
/** 是否记录响应体 */
|
|
6
|
+
logResponseBody?: boolean;
|
|
7
|
+
/** body 最大记录长度,默认 2000 */
|
|
8
|
+
maxBodyLength?: number;
|
|
9
|
+
/** 需要打码/移除的字段名,默认 ['password','pwd','token'] */
|
|
10
|
+
redactKeys?: string[];
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* 控制台打印访问日志(打印 morgan 那一行)。
|
|
14
|
+
*
|
|
15
|
+
* @param app - express app
|
|
16
|
+
* @param options - 额外配置(是否记录入参/出参等)
|
|
17
|
+
*/
|
|
18
|
+
export declare function attachConsoleLogs(app: Express, options?: AccessLogOptions): void;
|
|
19
|
+
/**
|
|
20
|
+
* 挂载 access log(落盘),实现与 `.backup/src/utils/logs.ts` 一致的策略:
|
|
21
|
+
* - morgan combined
|
|
22
|
+
* - rotating-file-stream:按天滚动 + 单文件 50MB
|
|
23
|
+
*
|
|
24
|
+
* @param app - express app
|
|
25
|
+
* @param dir - 日志目录
|
|
26
|
+
* @param options - 额外配置(是否记录入参/出参等)
|
|
27
|
+
*/
|
|
28
|
+
export default function attachLogs(app: Express, dir: string, options?: AccessLogOptions): void;
|
|
29
|
+
//# sourceMappingURL=logs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/getApp/logs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAMvC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,cAAc;IACd,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc;IACd,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,0BAA0B;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC;AAyIF;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,OAAO,EACZ,OAAO,GAAE,gBAAqB,QAe/B;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,OAAO,UAAU,UAAU,CAChC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,gBAAqB,QAoB/B"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type * from './type';
|
|
2
|
+
export { getApp } from './getApp/getApp';
|
|
3
|
+
export { validToken, createToken, decode, encode } from './utils/tokenUtils';
|
|
4
|
+
export { _Number, _String, type TypeFromValidFormat, type ValidFormat, } from './utils/typeFromValidFormat';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,mBAAmB,QAAQ,CAAC;AAG5B,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAGzC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAG7E,OAAO,EACL,OAAO,EACP,OAAO,EACP,KAAK,mBAAmB,EACxB,KAAK,WAAW,GACjB,MAAM,6BAA6B,CAAC"}
|