json-api-mocker 1.0.3 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
package/CONFIG.ch.md ADDED
@@ -0,0 +1,305 @@
1
+ # JSON API Mocker 配置指南
2
+
3
+ 本文档将帮助你理解和编写 `data.json` 配置文件。
4
+
5
+ ## 配置文件结构
6
+
7
+ ```json
8
+ {
9
+ "server": {
10
+ "port": 8080,
11
+ "baseProxy": "/api"
12
+ },
13
+ "routes": []
14
+ }
15
+ ```
16
+
17
+ ## 配置项详解
18
+
19
+ ### 1. 服务器配置 (server)
20
+
21
+ | 字段 | 类型 | 必填 | 默认值 | 说明 |
22
+ |------|------|------|--------|------|
23
+ | port | number | 否 | 8080 | 服务器端口号 |
24
+ | baseProxy | string | 否 | "/api" | API 的基础路径 |
25
+
26
+ ### 2. 路由配置 (routes)
27
+
28
+ routes 是一个数组,每个元素都是一个路由配置对象:
29
+
30
+ ```json
31
+ {
32
+ "path": "/users",
33
+ "methods": {
34
+ "get": {},
35
+ "post": {},
36
+ "put": {},
37
+ "delete": {}
38
+ }
39
+ }
40
+ ```
41
+
42
+ #### 2.1 路由基础配置
43
+
44
+ | 字段 | 类型 | 必填 | 说明 |
45
+ |------|------|------|------|
46
+ | path | string | 是 | 路由路径,支持参数如 `/users/:id` |
47
+ | methods | object | 是 | HTTP 方法配置对象 |
48
+
49
+ #### 2.2 方法配置 (methods)
50
+
51
+ 每个 HTTP 方法可以包含以下配置:
52
+
53
+ | 字段 | 类型 | 必填 | 说明 |
54
+ |------|------|------|------|
55
+ | type | string | 否 | 响应类型:"array" 或 "object" |
56
+ | response | any | 否 | 静态响应数据 |
57
+ | mock | object | 否 | Mock.js 配置 |
58
+ | pagination | object | 否 | 分页配置 |
59
+ | requestSchema | object | 否 | 请求体验证模式 |
60
+
61
+ ### 3. Mock 数据配置 (mock)
62
+
63
+ ```json
64
+ {
65
+ "mock": {
66
+ "enabled": true,
67
+ "total": 100,
68
+ "template": {
69
+ "id|+1": 1,
70
+ "name": "@cname",
71
+ "email": "@email"
72
+ }
73
+ }
74
+ }
75
+ ```
76
+
77
+ | 字段 | 类型 | 必填 | 说明 |
78
+ |------|------|------|------|
79
+ | enabled | boolean | 是 | 是否启用 mock 数据 |
80
+ | total | number | 是 | 生成数据的总条数 |
81
+ | template | object | 是 | Mock.js 的数据模板 |
82
+
83
+ ### 4. 分页配置 (pagination)
84
+
85
+ ```json
86
+ {
87
+ "pagination": {
88
+ "enabled": true,
89
+ "pageSize": 10
90
+ }
91
+ }
92
+ ```
93
+
94
+ | 字段 | 类型 | 必填 | 默认值 | 说明 |
95
+ |------|------|------|--------|------|
96
+ | enabled | boolean | 否 | false | 是否启用分页 |
97
+ | pageSize | number | 否 | 10 | 每页数据条数 |
98
+
99
+ ### 5. 请求验证配置 (requestSchema)
100
+
101
+ ```json
102
+ {
103
+ "requestSchema": {
104
+ "name": "string",
105
+ "age": "number",
106
+ "email": "string"
107
+ }
108
+ }
109
+ ```
110
+
111
+ ## Mock.js 模板使用说明
112
+
113
+ ### 常用模板示例
114
+
115
+ - `@cname` - 生成中文姓名
116
+ - `@name` - 生成英文姓名
117
+ - `@email` - 生成邮箱地址
118
+ - `@datetime` - 生成日期时间
119
+ - `@image` - 生成图片链接
120
+ - `@city` - 生成城市名
121
+ - `@id` - 生成随机 ID
122
+ - `@guid` - 生成 GUID
123
+ - `@ctitle` - 生成中文标题
124
+ - `@cparagraph` - 生成中文段落
125
+ - `|+1` - 自增数字
126
+
127
+ ## 完整配置示例
128
+
129
+ ### 1. 用户管理接口
130
+
131
+ ```json
132
+ {
133
+ "server": {
134
+ "port": 8080,
135
+ "baseProxy": "/api"
136
+ },
137
+ "routes": [
138
+ {
139
+ "path": "/users",
140
+ "methods": {
141
+ "get": {
142
+ "type": "array",
143
+ "mock": {
144
+ "enabled": true,
145
+ "total": 100,
146
+ "template": {
147
+ "id|+1": 1,
148
+ "name": "@cname",
149
+ "age|18-60": 1,
150
+ "email": "@email",
151
+ "address": "@city(true)"
152
+ }
153
+ },
154
+ "pagination": {
155
+ "enabled": true,
156
+ "pageSize": 10
157
+ }
158
+ },
159
+ "post": {
160
+ "requestSchema": {
161
+ "name": "string",
162
+ "age": "number",
163
+ "email": "string"
164
+ },
165
+ "response": {
166
+ "success": true,
167
+ "message": "创建成功"
168
+ }
169
+ }
170
+ }
171
+ }
172
+ ]
173
+ }
174
+ ```
175
+
176
+ ### 2. 文章管理接口(带嵌套数据)
177
+
178
+ ```json
179
+ {
180
+ "path": "/articles",
181
+ "methods": {
182
+ "get": {
183
+ "type": "array",
184
+ "mock": {
185
+ "enabled": true,
186
+ "total": 50,
187
+ "template": {
188
+ "id|+1": 1,
189
+ "title": "@ctitle",
190
+ "content": "@cparagraph",
191
+ "author": {
192
+ "id|+1": 100,
193
+ "name": "@cname",
194
+ "avatar": "@image('100x100')"
195
+ },
196
+ "comments|0-10": [{
197
+ "id|+1": 1,
198
+ "content": "@csentence",
199
+ "user": "@cname",
200
+ "createTime": "@datetime"
201
+ }]
202
+ }
203
+ }
204
+ }
205
+ }
206
+ }
207
+ ```
208
+
209
+ ## 使用技巧
210
+
211
+ ### 1. 动态路由参数
212
+ ```json
213
+ {
214
+ "path": "/users/:id/posts",
215
+ "methods": {
216
+ "get": {
217
+ "type": "array",
218
+ "mock": {
219
+ "enabled": true,
220
+ "total": 10,
221
+ "template": {
222
+ "id|+1": 1,
223
+ "title": "@ctitle",
224
+ "content": "@cparagraph"
225
+ }
226
+ }
227
+ }
228
+ }
229
+ }
230
+ ```
231
+
232
+ ### 2. 分页查询
233
+ ```bash
234
+ # 获取第二页,每页10条数据
235
+ curl http://localhost:8080/api/users?page=2&pageSize=10
236
+ ```
237
+
238
+ ### 3. 数据范围生成
239
+ ```json
240
+ {
241
+ "template": {
242
+ "age|18-60": 1, // 生成18-60之间的数字
243
+ "score|1-100.1": 1, // 生成1-100之间的浮点数,保留1位小数
244
+ "items|1-5": ["item"] // 生成1-5个重复项
245
+ }
246
+ }
247
+ ```
248
+
249
+ ## 注意事项
250
+
251
+ 1. **路径参数**
252
+ - 动态路由参数使用 `:参数名` 格式
253
+ - 例如:`/users/:id/posts/:postId`
254
+
255
+ 2. **Mock 数据**
256
+ - `enabled` 为 `true` 时才会生成 mock 数据
257
+ - `template` 中可以使用所有 Mock.js 支持的语法
258
+
259
+ 3. **分页**
260
+ - 启用分页后,可通过 `?page=1&pageSize=10` 访问分页数据
261
+ - 响应头会包含 `X-Total-Count` 表示总数据量
262
+
263
+ 4. **数据持久化**
264
+ - POST、PUT、DELETE 操作会自动保存到 data.json 文件
265
+ - 重启服务器后数据仍然保留
266
+
267
+ ## 最佳实践
268
+
269
+ 1. **合理使用 Mock 数据**
270
+ ```json
271
+ {
272
+ "mock": {
273
+ "enabled": true,
274
+ "total": 100,
275
+ "template": {
276
+ // 使用自增ID避免重复
277
+ "id|+1": 1,
278
+ // 使用合适的数据类型
279
+ "age|18-60": 1
280
+ }
281
+ }
282
+ }
283
+ ```
284
+
285
+ 2. **适当的分页配置**
286
+ ```json
287
+ {
288
+ "pagination": {
289
+ "enabled": true,
290
+ "pageSize": 10 // 根据数据量设置合适的页大小
291
+ }
292
+ }
293
+ ```
294
+
295
+ 3. **请求验证**
296
+ ```json
297
+ {
298
+ "requestSchema": {
299
+ // 确保必要的字段都有类型验证
300
+ "name": "string",
301
+ "age": "number",
302
+ "email": "string"
303
+ }
304
+ }
305
+ ```
package/CONFIG.md ADDED
@@ -0,0 +1,271 @@
1
+ # JSON API Mocker Configuration Guide
2
+
3
+ A comprehensive guide to help you understand and write the `data.json` configuration file.
4
+
5
+ ## Configuration Structure
6
+
7
+ ```json
8
+ {
9
+ "server": {
10
+ "port": 8080,
11
+ "baseProxy": "/api"
12
+ },
13
+ "routes": []
14
+ }
15
+ ```
16
+
17
+ ## Configuration Details
18
+
19
+ ### 1. Server Configuration (server)
20
+
21
+ | Field | Type | Required | Default | Description |
22
+ |-------|------|----------|---------|-------------|
23
+ | port | number | No | 8080 | Server port number |
24
+ | baseProxy | string | No | "/api" | Base path for all APIs |
25
+
26
+ ### 2. Routes Configuration (routes)
27
+
28
+ Routes is an array where each element is a route configuration object:
29
+
30
+ ```json
31
+ {
32
+ "path": "/users",
33
+ "methods": {
34
+ "get": {},
35
+ "post": {},
36
+ "put": {},
37
+ "delete": {}
38
+ }
39
+ }
40
+ ```
41
+
42
+ #### 2.1 Route Basic Configuration
43
+
44
+ | Field | Type | Required | Description |
45
+ |-------|------|----------|-------------|
46
+ | path | string | Yes | Route path, supports parameters like `/users/:id` |
47
+ | methods | object | Yes | HTTP methods configuration object |
48
+
49
+ #### 2.2 Method Configuration (methods)
50
+
51
+ Each HTTP method can include the following configurations:
52
+
53
+ | Field | Type | Required | Description |
54
+ |-------|------|----------|-------------|
55
+ | type | string | No | Response type: "array" or "object" |
56
+ | response | any | No | Static response data |
57
+ | mock | object | No | Mock.js configuration |
58
+ | pagination | object | No | Pagination configuration |
59
+ | requestSchema | object | No | Request body validation schema |
60
+
61
+ ### 3. Mock Data Configuration (mock)
62
+
63
+ ```json
64
+ {
65
+ "mock": {
66
+ "enabled": true,
67
+ "total": 100,
68
+ "template": {
69
+ "id|+1": 1,
70
+ "name": "@name",
71
+ "email": "@email"
72
+ }
73
+ }
74
+ }
75
+ ```
76
+
77
+ | Field | Type | Required | Description |
78
+ |-------|------|----------|-------------|
79
+ | enabled | boolean | Yes | Enable/disable mock data |
80
+ | total | number | Yes | Total number of records to generate |
81
+ | template | object | Yes | Mock.js data template |
82
+
83
+ ### 4. Pagination Configuration (pagination)
84
+
85
+ ```json
86
+ {
87
+ "pagination": {
88
+ "enabled": true,
89
+ "pageSize": 10
90
+ }
91
+ }
92
+ ```
93
+
94
+ | Field | Type | Required | Default | Description |
95
+ |-------|------|----------|---------|-------------|
96
+ | enabled | boolean | No | false | Enable/disable pagination |
97
+ | pageSize | number | No | 10 | Number of items per page |
98
+
99
+ ### 5. Request Validation Configuration (requestSchema)
100
+
101
+ ```json
102
+ {
103
+ "requestSchema": {
104
+ "name": "string",
105
+ "age": "number",
106
+ "email": "string"
107
+ }
108
+ }
109
+ ```
110
+
111
+ ## Complete Configuration Examples
112
+
113
+ ### 1. Basic User CRUD API
114
+
115
+ ```json
116
+ {
117
+ "server": {
118
+ "port": 8080,
119
+ "baseProxy": "/api"
120
+ },
121
+ "routes": [
122
+ {
123
+ "path": "/users",
124
+ "methods": {
125
+ "get": {
126
+ "type": "array",
127
+ "mock": {
128
+ "enabled": true,
129
+ "total": 100,
130
+ "template": {
131
+ "id|+1": 1,
132
+ "name": "@name",
133
+ "age|18-60": 1,
134
+ "email": "@email",
135
+ "address": "@city"
136
+ }
137
+ },
138
+ "pagination": {
139
+ "enabled": true,
140
+ "pageSize": 10
141
+ }
142
+ },
143
+ "post": {
144
+ "requestSchema": {
145
+ "name": "string",
146
+ "age": "number",
147
+ "email": "string"
148
+ },
149
+ "response": {
150
+ "success": true,
151
+ "message": "Created successfully"
152
+ }
153
+ }
154
+ }
155
+ }
156
+ ]
157
+ }
158
+ ```
159
+
160
+ ### 2. Articles API with Nested Data
161
+
162
+ ```json
163
+ {
164
+ "path": "/articles",
165
+ "methods": {
166
+ "get": {
167
+ "type": "array",
168
+ "mock": {
169
+ "enabled": true,
170
+ "total": 50,
171
+ "template": {
172
+ "id|+1": 1,
173
+ "title": "@title",
174
+ "content": "@paragraph",
175
+ "author": {
176
+ "id|+1": 100,
177
+ "name": "@name",
178
+ "avatar": "@image('100x100')"
179
+ },
180
+ "comments|0-10": [{
181
+ "id|+1": 1,
182
+ "content": "@sentence",
183
+ "user": "@name",
184
+ "createTime": "@datetime"
185
+ }]
186
+ }
187
+ }
188
+ }
189
+ }
190
+ }
191
+ ```
192
+
193
+ ### 3. Dynamic Route Parameters Example
194
+
195
+ ```json
196
+ {
197
+ "path": "/users/:id/posts",
198
+ "methods": {
199
+ "get": {
200
+ "type": "array",
201
+ "mock": {
202
+ "enabled": true,
203
+ "total": 10,
204
+ "template": {
205
+ "id|+1": 1,
206
+ "title": "@title",
207
+ "content": "@paragraph"
208
+ }
209
+ }
210
+ }
211
+ }
212
+ }
213
+ ```
214
+
215
+ ## Important Notes
216
+
217
+ 1. **Route Parameters**
218
+ - Dynamic route parameters use `:paramName` format
219
+ - Example: `/users/:id/posts/:postId`
220
+
221
+ 2. **Mock Data**
222
+ - Mock data generation only works when `enabled` is `true`
223
+ - `template` supports all Mock.js syntax
224
+
225
+ 3. **Pagination**
226
+ - When enabled, use `?page=1&pageSize=10` to access paginated data
227
+ - Response headers include `X-Total-Count` for total count
228
+
229
+ 4. **Data Persistence**
230
+ - POST, PUT, DELETE operations automatically save to data.json
231
+ - Data persists after server restart
232
+
233
+ ## Best Practices
234
+
235
+ 1. **Effective Use of Mock Data**
236
+ ```json
237
+ {
238
+ "mock": {
239
+ "enabled": true,
240
+ "total": 100,
241
+ "template": {
242
+ // Use auto-increment for IDs
243
+ "id|+1": 1,
244
+ // Use appropriate data types
245
+ "age|18-60": 1
246
+ }
247
+ }
248
+ }
249
+ ```
250
+
251
+ 2. **Proper Pagination Settings**
252
+ ```json
253
+ {
254
+ "pagination": {
255
+ "enabled": true,
256
+ "pageSize": 10 // Set appropriate page size based on data volume
257
+ }
258
+ }
259
+ ```
260
+
261
+ 3. **Request Validation**
262
+ ```json
263
+ {
264
+ "requestSchema": {
265
+ // Ensure all required fields have type validation
266
+ "name": "string",
267
+ "age": "number",
268
+ "email": "string"
269
+ }
270
+ }
271
+ ```
package/README.ch.md CHANGED
@@ -3,11 +3,12 @@
3
3
  一个轻量级且灵活的 Mock 服务器,通过 JSON 配置快速创建 RESTful API。
4
4
 
5
5
  <p align="center">
6
- <img src="https://img.shields.io/npm/v/json-mock-server" alt="npm 版本" />
7
- <img src="https://img.shields.io/npm/l/json-mock-server" alt="许可证" />
8
- <img src="https://img.shields.io/npm/dt/json-mock-server" alt="下载量" />
6
+ <img src="https://img.shields.io/npm/v/json-api-mocker" alt="npm version" />
7
+ <img src="https://img.shields.io/npm/l/json-api-mocker" alt="license" />
8
+ <img src="https://img.shields.io/npm/dt/json-api-mocker" alt="downloads" />
9
9
  </p>
10
10
 
11
+
11
12
  ## ✨ 特性
12
13
 
13
14
  - 🚀 通过 JSON 配置快速搭建
@@ -15,6 +16,7 @@
15
16
  - 📝 自动数据持久化
16
17
  - 🔍 内置分页支持
17
18
  - 🛠 可自定义响应结构
19
+ - 💡 集成 Mock.js 实现强大的数据模拟
18
20
  - 💡 TypeScript 支持
19
21
 
20
22
  ## 📦 安装
@@ -152,6 +154,105 @@ Mock 服务器已启动:
152
154
  }
153
155
  ```
154
156
 
157
+ ### Mock.js 集成
158
+
159
+ 你可以使用 Mock.js 模板来生成动态数据:
160
+
161
+ ```json
162
+ {
163
+ "path": "/users",
164
+ "methods": {
165
+ "get": {
166
+ "type": "array",
167
+ "mock": {
168
+ "enabled": true,
169
+ "total": 200,
170
+ "template": {
171
+ "id|+1": 1,
172
+ "name": "@cname",
173
+ "email": "@email",
174
+ "age|18-60": 1,
175
+ "address": "@city(true)",
176
+ "avatar": "@image('200x200')",
177
+ "createTime": "@datetime"
178
+ }
179
+ },
180
+ "pagination": {
181
+ "enabled": true,
182
+ "pageSize": 10
183
+ }
184
+ }
185
+ }
186
+ }
187
+ ```
188
+
189
+ #### 可用的 Mock.js 模板
190
+
191
+ - `@cname` - 生成中文姓名
192
+ - `@name` - 生成英文姓名
193
+ - `@email` - 生成邮箱地址
194
+ - `@datetime` - 生成日期时间
195
+ - `@image` - 生成图片链接
196
+ - `@city` - 生成城市名
197
+ - `@id` - 生成随机 ID
198
+ - `@guid` - 生成 GUID
199
+ - `@title` - 生成标题
200
+ - `@paragraph` - 生成段落
201
+ - `|+1` - 自增数字
202
+
203
+ 更多 Mock.js 模板请访问 [Mock.js 文档](http://mockjs.com/examples.html)
204
+
205
+ #### Mock.js 使用示例
206
+
207
+ 1. 生成用户列表:
208
+ ```json
209
+ {
210
+ "mock": {
211
+ "enabled": true,
212
+ "total": 100,
213
+ "template": {
214
+ "id|+1": 1,
215
+ "name": "@cname",
216
+ "email": "@email"
217
+ }
218
+ }
219
+ }
220
+ ```
221
+
222
+ 2. 生成文章列表:
223
+ ```json
224
+ {
225
+ "mock": {
226
+ "enabled": true,
227
+ "total": 50,
228
+ "template": {
229
+ "id|+1": 1,
230
+ "title": "@ctitle",
231
+ "content": "@cparagraph",
232
+ "author": "@cname",
233
+ "publishDate": "@datetime"
234
+ }
235
+ }
236
+ }
237
+ ```
238
+
239
+ 3. 生成商品列表:
240
+ ```json
241
+ {
242
+ "mock": {
243
+ "enabled": true,
244
+ "total": 30,
245
+ "template": {
246
+ "id|+1": 1,
247
+ "name": "@ctitle(3, 5)",
248
+ "price|100-1000.2": 1,
249
+ "category": "@pick(['电子产品', '图书', '服装'])",
250
+ "image": "@image('200x200', '#50B347', '#FFF', 'Mock.js')"
251
+ }
252
+ }
253
+ }
254
+ ```
255
+
155
256
  ## 🎯 API 示例
156
257
 
157
258
  ### 基本的 CRUD 操作
package/README.md CHANGED
@@ -15,6 +15,7 @@ A lightweight and flexible mock server that uses JSON configuration to quickly c
15
15
  - 📝 Automatic data persistence
16
16
  - 🔍 Built-in pagination support
17
17
  - 🛠 Customizable response schemas
18
+ - 💡 Integration with Mock.js for powerful data mocking
18
19
  - 💡 TypeScript support
19
20
 
20
21
  ## 📦 Installation
@@ -152,6 +153,104 @@ Each route can support multiple HTTP methods:
152
153
  }
153
154
  ```
154
155
 
156
+ ### Mock.js Integration
157
+
158
+ You can use Mock.js templates to generate dynamic data:
159
+
160
+ ```json
161
+ {
162
+ "path": "/users",
163
+ "methods": {
164
+ "get": {
165
+ "type": "array",
166
+ "mock": {
167
+ "enabled": true,
168
+ "total": 200,
169
+ "template": {
170
+ "id|+1": 1,
171
+ "name": "@name",
172
+ "email": "@email",
173
+ "age|18-60": 1,
174
+ "address": "@city(true)",
175
+ "avatar": "@image('200x200')",
176
+ "createTime": "@datetime"
177
+ }
178
+ },
179
+ "pagination": {
180
+ "enabled": true,
181
+ "pageSize": 10
182
+ }
183
+ }
184
+ }
185
+ }
186
+ ```
187
+
188
+ #### Available Mock.js Templates
189
+
190
+ - `@name` - Generate random name
191
+ - `@email` - Generate random email
192
+ - `@datetime` - Generate random datetime
193
+ - `@image` - Generate random image URL
194
+ - `@city` - Generate random city name
195
+ - `@id` - Generate random ID
196
+ - `@guid` - Generate GUID
197
+ - `@title` - Generate random title
198
+ - `@paragraph` - Generate random paragraph
199
+ - `|+1` - Auto increment number
200
+
201
+ For more Mock.js templates, visit [Mock.js Documentation](http://mockjs.com/examples.html)
202
+
203
+ #### Examples with Mock.js
204
+
205
+ 1. Generate user list with random data:
206
+ ```json
207
+ {
208
+ "mock": {
209
+ "enabled": true,
210
+ "total": 100,
211
+ "template": {
212
+ "id|+1": 1,
213
+ "name": "@name",
214
+ "email": "@email"
215
+ }
216
+ }
217
+ }
218
+ ```
219
+
220
+ 2. Generate article list with random content:
221
+ ```json
222
+ {
223
+ "mock": {
224
+ "enabled": true,
225
+ "total": 50,
226
+ "template": {
227
+ "id|+1": 1,
228
+ "title": "@title",
229
+ "content": "@paragraph",
230
+ "author": "@name",
231
+ "publishDate": "@datetime"
232
+ }
233
+ }
234
+ }
235
+ ```
236
+
237
+ 3. Generate product list with random prices:
238
+ ```json
239
+ {
240
+ "mock": {
241
+ "enabled": true,
242
+ "total": 30,
243
+ "template": {
244
+ "id|+1": 1,
245
+ "name": "@title(3, 5)",
246
+ "price|100-1000.2": 1,
247
+ "category": "@pick(['Electronics', 'Books', 'Clothing'])",
248
+ "image": "@image('200x200', '#50B347', '#FFF', 'Mock.js')"
249
+ }
250
+ }
251
+ }
252
+ ```
253
+
155
254
  ## 🎯 API Examples
156
255
 
157
256
  ### Basic CRUD Operations
package/dist/server.d.ts CHANGED
@@ -5,14 +5,9 @@ export declare class MockServer {
5
5
  private configPath;
6
6
  constructor(config: Config, configPath?: string);
7
7
  private setupMiddleware;
8
+ private generateMockData;
9
+ private handleRequest;
8
10
  private setupRoutes;
9
- private saveConfig;
10
- private findUserById;
11
- private getNextUserId;
12
11
  private createRoute;
13
- private handleRequest;
14
- private handlePostRequest;
15
- private handlePutRequest;
16
- private handleDeleteRequest;
17
12
  start(): void;
18
13
  }
package/dist/server.js CHANGED
@@ -4,15 +4,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.MockServer = void 0;
7
+ const mockjs_1 = __importDefault(require("mockjs"));
7
8
  const express_1 = __importDefault(require("express"));
8
9
  const cors_1 = __importDefault(require("cors"));
9
- const fs_1 = __importDefault(require("fs"));
10
- const path_1 = __importDefault(require("path"));
11
10
  class MockServer {
12
11
  constructor(config, configPath = 'data.json') {
13
12
  this.app = (0, express_1.default)();
14
13
  this.config = config;
15
- this.configPath = path_1.default.resolve(process.cwd(), configPath);
14
+ this.configPath = configPath;
16
15
  this.setupMiddleware();
17
16
  this.setupRoutes();
18
17
  }
@@ -20,6 +19,43 @@ class MockServer {
20
19
  this.app.use((0, cors_1.default)());
21
20
  this.app.use(express_1.default.json());
22
21
  }
22
+ generateMockData(config) {
23
+ try {
24
+ if (config.mock?.enabled && config.mock.template) {
25
+ const { total, template } = config.mock;
26
+ return mockjs_1.default.mock({
27
+ [`data|${total}`]: [template]
28
+ }).data;
29
+ }
30
+ return config.response;
31
+ }
32
+ catch (error) {
33
+ console.error('生成 Mock 数据时出错:', error);
34
+ return config.response;
35
+ }
36
+ }
37
+ handleRequest(config) {
38
+ return (req, res) => {
39
+ try {
40
+ console.log(`收到请求: ${req.method} ${req.url}`);
41
+ let responseData = this.generateMockData(config);
42
+ if (config.pagination?.enabled && Array.isArray(responseData)) {
43
+ const page = parseInt(req.query.page) || 1;
44
+ const pageSize = parseInt(req.query.pageSize) || config.pagination.pageSize;
45
+ const startIndex = (page - 1) * pageSize;
46
+ const endIndex = startIndex + pageSize;
47
+ const paginatedData = responseData.slice(startIndex, endIndex);
48
+ res.header('X-Total-Count', responseData.length.toString());
49
+ responseData = paginatedData;
50
+ }
51
+ res.json(responseData);
52
+ }
53
+ catch (error) {
54
+ console.error('处理请求时出错:', error);
55
+ res.status(500).json({ error: '服务器内部错误' });
56
+ }
57
+ };
58
+ }
23
59
  setupRoutes() {
24
60
  this.config.routes.forEach((route) => {
25
61
  Object.entries(route.methods).forEach(([method, methodConfig]) => {
@@ -27,28 +63,6 @@ class MockServer {
27
63
  });
28
64
  });
29
65
  }
30
- saveConfig() {
31
- fs_1.default.writeFileSync(this.configPath, JSON.stringify(this.config, null, 2), 'utf-8');
32
- }
33
- findUserById(id) {
34
- const usersRoute = this.config.routes.find(route => route.path === '/users');
35
- if (!usersRoute)
36
- return null;
37
- const getMethod = usersRoute.methods.get;
38
- if (!getMethod || !Array.isArray(getMethod.response))
39
- return null;
40
- return getMethod.response.find(user => user.id === id);
41
- }
42
- getNextUserId() {
43
- const usersRoute = this.config.routes.find(route => route.path === '/users');
44
- if (!usersRoute)
45
- return 1;
46
- const getMethod = usersRoute.methods.get;
47
- if (!getMethod || !Array.isArray(getMethod.response))
48
- return 1;
49
- const maxId = Math.max(...getMethod.response.map(user => user.id));
50
- return maxId + 1;
51
- }
52
66
  createRoute(path, method, config) {
53
67
  const fullPath = `${this.config.server.baseProxy}${path}`;
54
68
  console.log(`创建路由: ${method.toUpperCase()} ${fullPath}`);
@@ -57,87 +71,16 @@ class MockServer {
57
71
  this.app.get(fullPath, this.handleRequest(config));
58
72
  break;
59
73
  case 'post':
60
- this.app.post(fullPath, this.handlePostRequest(config));
74
+ this.app.post(fullPath, this.handleRequest(config));
61
75
  break;
62
76
  case 'put':
63
- this.app.put(`${fullPath}/:id`, this.handlePutRequest(config));
77
+ this.app.put(`${fullPath}/:id`, this.handleRequest(config));
64
78
  break;
65
79
  case 'delete':
66
- this.app.delete(`${fullPath}/:id`, this.handleDeleteRequest(config));
80
+ this.app.delete(`${fullPath}/:id`, this.handleRequest(config));
67
81
  break;
68
82
  }
69
83
  }
70
- handleRequest(config) {
71
- return (req, res) => {
72
- console.log(`收到请求: ${req.method} ${req.url}`);
73
- if (config.pagination?.enabled && config.type === 'array') {
74
- const page = parseInt(req.query.page) || 1;
75
- const pageSize = parseInt(req.query.pageSize) || config.pagination.pageSize;
76
- const startIndex = (page - 1) * pageSize;
77
- const endIndex = startIndex + pageSize;
78
- const data = config.response.slice(startIndex, endIndex);
79
- res.header('X-Total-Count', config.pagination.totalCount.toString());
80
- res.json(data);
81
- }
82
- else {
83
- res.json(config.response);
84
- }
85
- };
86
- }
87
- handlePostRequest(config) {
88
- return (req, res) => {
89
- console.log(`收到创建请求: ${req.url}`, req.body);
90
- const usersRoute = this.config.routes.find(route => route.path === '/users');
91
- if (!usersRoute) {
92
- return res.status(404).json({ error: '路由未找到' });
93
- }
94
- const getMethod = usersRoute.methods.get;
95
- if (!getMethod || !Array.isArray(getMethod.response)) {
96
- return res.status(500).json({ error: '数据格式错误' });
97
- }
98
- const newUser = {
99
- id: this.getNextUserId(),
100
- ...req.body
101
- };
102
- getMethod.response.push(newUser);
103
- this.saveConfig();
104
- res.status(201).json(newUser);
105
- };
106
- }
107
- handlePutRequest(config) {
108
- return (req, res) => {
109
- const userId = parseInt(req.params.id);
110
- console.log(`收到更新请求: ${req.url}`, req.body);
111
- const user = this.findUserById(userId);
112
- if (!user) {
113
- return res.status(404).json({ error: '用户未找到' });
114
- }
115
- Object.assign(user, req.body);
116
- this.saveConfig();
117
- res.json(user);
118
- };
119
- }
120
- handleDeleteRequest(config) {
121
- return (req, res) => {
122
- const userId = parseInt(req.params.id);
123
- console.log(`收到删除请求: ${req.url}`);
124
- const usersRoute = this.config.routes.find(route => route.path === '/users');
125
- if (!usersRoute) {
126
- return res.status(404).json({ error: '路由未找到' });
127
- }
128
- const getMethod = usersRoute.methods.get;
129
- if (!getMethod || !Array.isArray(getMethod.response)) {
130
- return res.status(500).json({ error: '数据格式错误' });
131
- }
132
- const userIndex = getMethod.response.findIndex(user => user.id === userId);
133
- if (userIndex === -1) {
134
- return res.status(404).json({ error: '用户未找到' });
135
- }
136
- getMethod.response.splice(userIndex, 1);
137
- this.saveConfig();
138
- res.json({ success: true, message: '删除成功' });
139
- };
140
- }
141
84
  start() {
142
85
  this.app.listen(this.config.server.port, () => {
143
86
  console.log(`Mock 服务器已启动:`);
package/dist/types.d.ts CHANGED
@@ -7,12 +7,17 @@ export interface PaginationConfig {
7
7
  pageSize: number;
8
8
  totalCount: number;
9
9
  }
10
+ export interface MockConfig {
11
+ enabled: boolean;
12
+ total: number;
13
+ template: Record<string, any>;
14
+ }
10
15
  export interface MethodConfig {
11
16
  type?: 'array' | 'object';
17
+ response?: any;
18
+ mock?: MockConfig;
12
19
  pagination?: PaginationConfig;
13
- response: any;
14
20
  requestSchema?: Record<string, string>;
15
- params?: string[];
16
21
  }
17
22
  export interface RouteConfig {
18
23
  path: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "json-api-mocker",
3
- "version": "1.0.3",
3
+ "version": "1.2.0",
4
4
  "description": "一个基于 JSON 配置的 Mock 服务器",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -10,7 +10,9 @@
10
10
  "files": [
11
11
  "dist",
12
12
  "README.md",
13
- "README.ch.md"
13
+ "README.ch.md",
14
+ "CONFIG.md",
15
+ "CONFIG.ch.md"
14
16
  ],
15
17
  "scripts": {
16
18
  "dev": "nodemon",
@@ -41,12 +43,14 @@
41
43
  "homepage": "https://github.com/Selteve/json-api-mocker#readme",
42
44
  "dependencies": {
43
45
  "cors": "^2.8.5",
44
- "express": "^4.17.1"
46
+ "express": "^4.17.1",
47
+ "mockjs": "^1.1.0"
45
48
  },
46
49
  "devDependencies": {
47
50
  "@types/cors": "^2.8.13",
48
51
  "@types/express": "^4.17.13",
49
52
  "@types/jest": "^27.5.2",
53
+ "@types/mockjs": "^1.0.10",
50
54
  "@types/node": "^16.18.0",
51
55
  "jest": "^27.5.1",
52
56
  "nodemon": "^2.0.22",