360-mock-server 1.1.0 β 1.2.0
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 +188 -111
- package/lib/server.js +134 -2
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -1,190 +1,267 @@
|
|
|
1
1
|
# π 360 Mock Server
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**360 Mock Server** is a zero-configuration mock REST API designed for frontend developers.
|
|
4
|
+
It allows you to instantly create and manage RESTful APIs **without building a backend**, making it ideal for frontend development, testing, demos, and rapid prototyping.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
Now with **Faker.js integration** for automatic fake data generation!
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## β¨ Why 360 Mock Server?
|
|
10
|
+
|
|
11
|
+
* No backend setup required
|
|
12
|
+
* Works instantly with **any endpoint**
|
|
13
|
+
* **Auto-generate fake data** with Faker.js
|
|
14
|
+
* Interactive CLI + REST API
|
|
15
|
+
* Persistent JSON-based storage
|
|
16
|
+
* Ideal for React, React Native, Vue, Angular, Redux apps
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
## π¦ Installation
|
|
20
|
+
|
|
21
|
+
Install globally using npm:
|
|
6
22
|
|
|
7
23
|
```bash
|
|
8
|
-
# Global installation (recommended)
|
|
9
24
|
npm install -g 360-mock-server
|
|
25
|
+
```
|
|
10
26
|
|
|
11
|
-
|
|
27
|
+
Or run directly using `npx` (recommended):
|
|
28
|
+
|
|
29
|
+
```bash
|
|
12
30
|
npx 360-mock-server
|
|
13
31
|
```
|
|
14
32
|
|
|
15
|
-
|
|
33
|
+
|
|
34
|
+
## β‘ Quick Start
|
|
16
35
|
|
|
17
36
|
```bash
|
|
18
|
-
# Just run one command - that's it!
|
|
19
37
|
npx 360-mock-server
|
|
20
38
|
```
|
|
21
39
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
2. β
Start the server on port 3000
|
|
25
|
-
3. β
Open interactive mode for easy API requests
|
|
40
|
+
Thatβs it! π
|
|
41
|
+
The mock server will start at:
|
|
26
42
|
|
|
27
|
-
|
|
43
|
+
```
|
|
44
|
+
http://localhost:3000
|
|
45
|
+
```
|
|
28
46
|
|
|
29
|
-
## Interactive Mode (Recommended!)
|
|
30
47
|
|
|
31
|
-
|
|
48
|
+
## π§ Interactive CLI Mode
|
|
32
49
|
|
|
33
|
-
|
|
50
|
+
Once the server starts, you can interact with it directly from the terminal:
|
|
51
|
+
|
|
52
|
+
```text
|
|
34
53
|
360-mock> POST /users {"name": "Ali", "email": "ali@test.com"}
|
|
35
|
-
π€ POST /users
|
|
36
54
|
β
Status: 201
|
|
37
|
-
{
|
|
55
|
+
{"id": 1737745200000, "name": "Ali", "email": "ali@test.com"}
|
|
38
56
|
|
|
39
57
|
360-mock> GET /users
|
|
40
|
-
π€ GET /users
|
|
41
58
|
β
Status: 200
|
|
42
|
-
[{
|
|
59
|
+
[{"id": 1737745200000, "name": "Ali", "email": "ali@test.com"}]
|
|
43
60
|
|
|
44
|
-
360-mock>
|
|
45
|
-
|
|
46
|
-
360-mock> DELETE /users/1234567890
|
|
47
|
-
360-mock> exit
|
|
61
|
+
360-mock> DELETE /users/1737745200000
|
|
62
|
+
β
Status: 200
|
|
48
63
|
```
|
|
49
64
|
|
|
50
|
-
### Interactive Commands
|
|
51
65
|
|
|
52
|
-
|
|
53
|
-
|---------|---------|
|
|
54
|
-
| GET | `GET /users` |
|
|
55
|
-
| POST | `POST /users {"name": "Ali"}` |
|
|
56
|
-
| PUT | `PUT /users/123 {"name": "Updated"}` |
|
|
57
|
-
| PATCH | `PATCH /users/123 {"email": "new@test.com"}` |
|
|
58
|
-
| DELETE | `DELETE /users/123` |
|
|
59
|
-
| list | Show all resources |
|
|
60
|
-
| clear | Clear screen |
|
|
61
|
-
| help | Show help |
|
|
62
|
-
| exit | Exit |
|
|
66
|
+
## π CLI Commands (Interactive Mode)
|
|
63
67
|
|
|
64
|
-
|
|
68
|
+
| Command | Description |
|
|
69
|
+
| -------------------------------------- | ---------------------------- |
|
|
70
|
+
| `GET /users` | Fetch all users |
|
|
71
|
+
| `GET /users/123` | Fetch user by ID |
|
|
72
|
+
| `POST /users {"name":"Ali"}` | Create a new user |
|
|
73
|
+
| `PUT /users/123 {"name":"New"}` | Replace entire resource |
|
|
74
|
+
| `PATCH /users/123 {"email":"x@y.com"}` | Update specific fields |
|
|
75
|
+
| `DELETE /users/123` | Delete resource |
|
|
76
|
+
| `list` | Show all available resources |
|
|
77
|
+
| `clear` | Clear terminal screen |
|
|
78
|
+
| `help` | Show help |
|
|
79
|
+
| `exit` | Exit interactive mode |
|
|
65
80
|
|
|
66
|
-
##
|
|
81
|
+
## π§ͺ Using with Postman / REST Clients
|
|
67
82
|
|
|
68
|
-
|
|
69
|
-
|---------|-------------|
|
|
70
|
-
| `360-mock` | Start server + interactive mode |
|
|
71
|
-
| `360-mock start` | Start server only |
|
|
72
|
-
| `360-mock init` | Create mock-data.json |
|
|
73
|
-
| `360-mock list` | Show available resources |
|
|
74
|
-
| `360-mock reset` | Clear all data |
|
|
83
|
+
**Base URL**
|
|
75
84
|
|
|
76
|
-
|
|
85
|
+
```
|
|
86
|
+
http://localhost:3000
|
|
87
|
+
```
|
|
77
88
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
89
|
+
### Example Endpoints
|
|
90
|
+
|
|
91
|
+
| Method | Endpoint | Body |
|
|
92
|
+
| ------ | ------------ | ----------------------------- |
|
|
93
|
+
| GET | `/users` | β |
|
|
94
|
+
| GET | `/users/123` | β |
|
|
95
|
+
| POST | `/users` | `{ "name": "Ali" }` |
|
|
96
|
+
| PUT | `/users/123` | `{ "name": "Updated" }` |
|
|
97
|
+
| PATCH | `/users/123` | `{ "email": "new@test.com" }` |
|
|
98
|
+
| DELETE | `/users/123` | β |
|
|
99
|
+
|
|
100
|
+
**Required Headers**
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
Content-Type: application/json
|
|
83
104
|
```
|
|
84
105
|
|
|
85
|
-
---
|
|
86
106
|
|
|
87
|
-
##
|
|
107
|
+
## π² Auto-Generate Fake Data with Faker.js
|
|
88
108
|
|
|
89
|
-
|
|
109
|
+
Generate realistic fake data instantly! Just send a POST request with `fields` array:
|
|
90
110
|
|
|
91
|
-
|
|
111
|
+
### Generate 10 Users (default count)
|
|
92
112
|
|
|
93
113
|
```bash
|
|
94
|
-
# These all work without configuration:
|
|
95
114
|
POST /users
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
115
|
+
{
|
|
116
|
+
"fields": ["name", "email", "avatar", "phone"]
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Generate 50 Products with custom count
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
POST /products
|
|
124
|
+
{
|
|
125
|
+
"fields": ["productName", "price", "category", "description", "image"],
|
|
126
|
+
"count": 50
|
|
127
|
+
}
|
|
99
128
|
```
|
|
100
129
|
|
|
101
|
-
###
|
|
130
|
+
### Available Faker Fields
|
|
102
131
|
|
|
103
|
-
|
|
|
104
|
-
|
|
105
|
-
|
|
|
106
|
-
|
|
|
107
|
-
|
|
|
108
|
-
|
|
|
109
|
-
|
|
|
110
|
-
|
|
|
111
|
-
|
|
|
132
|
+
| Category | Fields |
|
|
133
|
+
| ----------- | ---------------------------------------------------------------------- |
|
|
134
|
+
| **Person** | `name`, `firstName`, `lastName`, `username`, `email`, `phone`, `avatar`, `bio`, `jobTitle`, `gender` |
|
|
135
|
+
| **Location**| `address`, `city`, `state`, `country`, `zipCode`, `latitude`, `longitude` |
|
|
136
|
+
| **Company** | `company`, `companyName`, `department` |
|
|
137
|
+
| **Internet**| `website`, `url`, `ip`, `password` |
|
|
138
|
+
| **Content** | `title`, `description`, `body`, `text`, `sentence`, `paragraph`, `slug`|
|
|
139
|
+
| **Commerce**| `price`, `product`, `productName`, `productDescription`, `category` |
|
|
140
|
+
| **Images** | `image`, `imageUrl` |
|
|
141
|
+
| **Dates** | `date`, `pastDate`, `futureDate`, `birthDate` |
|
|
142
|
+
| **Numbers** | `number`, `age`, `rating`, `quantity` |
|
|
143
|
+
| **Boolean** | `boolean`, `isActive`, `isVerified` |
|
|
144
|
+
| **Misc** | `uuid`, `color`, `word`, `words` |
|
|
112
145
|
|
|
113
|
-
###
|
|
146
|
+
### Get All Available Fields
|
|
114
147
|
|
|
115
148
|
```bash
|
|
116
|
-
GET /
|
|
117
|
-
GET /users?_sort=name # Sort by field
|
|
118
|
-
GET /users?_order=desc # Sort order
|
|
119
|
-
GET /users?_limit=10&_page=2 # Pagination
|
|
149
|
+
GET /faker/fields
|
|
120
150
|
```
|
|
121
151
|
|
|
122
|
-
|
|
152
|
+
> **Note:** If your POST body contains a `fields` array, it generates fake data. Otherwise, it creates a single item with your provided key-value pairs.
|
|
123
153
|
|
|
124
|
-
## Frontend Examples
|
|
125
154
|
|
|
126
|
-
|
|
155
|
+
## π Frontend Integration Examples
|
|
156
|
+
|
|
157
|
+
<details open>
|
|
158
|
+
<summary><strong>Fetch API</strong></summary>
|
|
127
159
|
|
|
128
160
|
```javascript
|
|
129
|
-
|
|
130
|
-
|
|
161
|
+
const API = 'http://localhost:3000';
|
|
162
|
+
|
|
163
|
+
// CREATE
|
|
164
|
+
await fetch(`${API}/users`, {
|
|
131
165
|
method: 'POST',
|
|
132
166
|
headers: { 'Content-Type': 'application/json' },
|
|
133
167
|
body: JSON.stringify({ name: 'Ali', email: 'ali@test.com' })
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
// Read all
|
|
137
|
-
const users = await fetch('http://localhost:3000/users').then(r => r.json());
|
|
168
|
+
});
|
|
138
169
|
|
|
139
|
-
//
|
|
140
|
-
const
|
|
170
|
+
// READ
|
|
171
|
+
const users = await fetch(`${API}/users`).then(res => res.json());
|
|
141
172
|
|
|
142
|
-
//
|
|
143
|
-
await fetch(
|
|
173
|
+
// UPDATE
|
|
174
|
+
await fetch(`${API}/users/123`, {
|
|
144
175
|
method: 'PATCH',
|
|
145
176
|
headers: { 'Content-Type': 'application/json' },
|
|
146
|
-
body: JSON.stringify({ name: '
|
|
177
|
+
body: JSON.stringify({ name: 'Updated' })
|
|
147
178
|
});
|
|
148
179
|
|
|
149
|
-
//
|
|
150
|
-
await fetch(
|
|
180
|
+
// DELETE
|
|
181
|
+
await fetch(`${API}/users/123`, { method: 'DELETE' });
|
|
151
182
|
```
|
|
152
183
|
|
|
153
|
-
|
|
184
|
+
</details>
|
|
185
|
+
|
|
186
|
+
<details>
|
|
187
|
+
<summary><strong>Axios</strong></summary>
|
|
154
188
|
|
|
155
189
|
```javascript
|
|
156
190
|
import axios from 'axios';
|
|
157
|
-
const api = axios.create({ baseURL: 'http://localhost:3000' });
|
|
158
191
|
|
|
159
|
-
|
|
160
|
-
|
|
192
|
+
const API = 'http://localhost:3000';
|
|
193
|
+
|
|
194
|
+
// CREATE
|
|
195
|
+
await axios.post(`${API}/users`, {
|
|
196
|
+
name: 'Ali',
|
|
197
|
+
email: 'ali@test.com'
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// READ
|
|
201
|
+
const { data: users } = await axios.get(`${API}/users`);
|
|
202
|
+
|
|
203
|
+
// UPDATE
|
|
204
|
+
await axios.patch(`${API}/users/123`, {
|
|
205
|
+
name: 'Updated'
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
// DELETE
|
|
209
|
+
await axios.delete(`${API}/users/123`);
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
</details>
|
|
161
213
|
|
|
162
|
-
// Read
|
|
163
|
-
const { data: users } = await api.get('/users');
|
|
164
214
|
|
|
165
|
-
|
|
166
|
-
await api.patch(`/users/${id}`, { name: 'Updated' });
|
|
215
|
+
## βοΈ CLI Options
|
|
167
216
|
|
|
168
|
-
|
|
169
|
-
|
|
217
|
+
| Option | Description | Default |
|
|
218
|
+
| -------- | -------------- | ---------------- |
|
|
219
|
+
| `--port` | Server port | `3000` |
|
|
220
|
+
| `--file` | Data file name | `mock-data.json` |
|
|
221
|
+
|
|
222
|
+
### Examples
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
npx 360-mock-server --port 4000
|
|
226
|
+
npx 360-mock-server --file db.json
|
|
170
227
|
```
|
|
171
228
|
|
|
172
|
-
---
|
|
173
229
|
|
|
174
|
-
##
|
|
230
|
+
## π Additional Commands
|
|
231
|
+
|
|
232
|
+
| Command | Description |
|
|
233
|
+
| ---------------- | --------------------------------------- |
|
|
234
|
+
| `360-mock start` | Start server only (no interactive mode) |
|
|
235
|
+
| `360-mock init` | Create an empty data file |
|
|
236
|
+
| `360-mock list` | List all resources |
|
|
237
|
+
| `360-mock reset` | Clear all stored data |
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
## π Features
|
|
241
|
+
|
|
242
|
+
* β
Zero-config setup
|
|
243
|
+
* β
Supports **any REST endpoint**
|
|
244
|
+
* β
Full CRUD operations
|
|
245
|
+
* β
**Auto-generate fake data** with Faker.js
|
|
246
|
+
* β
Auto-generated unique IDs
|
|
247
|
+
* β
Automatic timestamps (`createdAt`, `updatedAt`)
|
|
248
|
+
* β
Persistent JSON storage
|
|
249
|
+
* β
CORS enabled
|
|
250
|
+
* β
Works with Postman & frontend apps
|
|
251
|
+
* β
Perfect for mock APIs & demos
|
|
175
252
|
|
|
176
|
-
- β
**Zero config** - Works out of the box
|
|
177
|
-
- β
**Any endpoint** - Auto-creates resources
|
|
178
|
-
- β
**Full CRUD** - GET, POST, PUT, PATCH, DELETE
|
|
179
|
-
- β
**Filtering** - Query parameter support
|
|
180
|
-
- β
**Sorting** - `?_sort=field&_order=desc`
|
|
181
|
-
- β
**Pagination** - `?_limit=10&_page=1`
|
|
182
|
-
- β
**Auto IDs** - Generated automatically
|
|
183
|
-
- β
**Timestamps** - createdAt, updatedAt
|
|
184
|
-
- β
**CORS enabled** - Works with any frontend
|
|
185
253
|
|
|
186
|
-
|
|
254
|
+
## πΎ Data Storage
|
|
187
255
|
|
|
188
|
-
|
|
256
|
+
All data is stored locally in:
|
|
257
|
+
|
|
258
|
+
```
|
|
259
|
+
mock-data.json
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
This file is automatically created and updated in your project directory.
|
|
263
|
+
|
|
264
|
+
## π License
|
|
189
265
|
|
|
190
266
|
MIT Β© [zahidrahimoon](https://github.com/zahidrahimoon)
|
|
267
|
+
|
package/lib/server.js
CHANGED
|
@@ -2,6 +2,7 @@ const express = require("express");
|
|
|
2
2
|
const fs = require("fs");
|
|
3
3
|
const path = require("path");
|
|
4
4
|
const cors = require("cors");
|
|
5
|
+
const { faker } = require("@faker-js/faker");
|
|
5
6
|
|
|
6
7
|
const app = express();
|
|
7
8
|
const PORT = process.env.PORT || 3000;
|
|
@@ -46,6 +47,99 @@ app.use((req, res, next) => {
|
|
|
46
47
|
next();
|
|
47
48
|
});
|
|
48
49
|
|
|
50
|
+
// Faker field mappings for automatic data generation
|
|
51
|
+
const fakerFieldMap = {
|
|
52
|
+
// Person
|
|
53
|
+
name: () => faker.person.fullName(),
|
|
54
|
+
firstName: () => faker.person.firstName(),
|
|
55
|
+
lastName: () => faker.person.lastName(),
|
|
56
|
+
username: () => faker.internet.username(),
|
|
57
|
+
email: () => faker.internet.email(),
|
|
58
|
+
phone: () => faker.phone.number(),
|
|
59
|
+
avatar: () => faker.image.avatar(),
|
|
60
|
+
bio: () => faker.person.bio(),
|
|
61
|
+
jobTitle: () => faker.person.jobTitle(),
|
|
62
|
+
gender: () => faker.person.sex(),
|
|
63
|
+
|
|
64
|
+
// Location
|
|
65
|
+
address: () => faker.location.streetAddress(),
|
|
66
|
+
city: () => faker.location.city(),
|
|
67
|
+
state: () => faker.location.state(),
|
|
68
|
+
country: () => faker.location.country(),
|
|
69
|
+
zipCode: () => faker.location.zipCode(),
|
|
70
|
+
latitude: () => faker.location.latitude(),
|
|
71
|
+
longitude: () => faker.location.longitude(),
|
|
72
|
+
|
|
73
|
+
// Company
|
|
74
|
+
company: () => faker.company.name(),
|
|
75
|
+
companyName: () => faker.company.name(),
|
|
76
|
+
department: () => faker.commerce.department(),
|
|
77
|
+
|
|
78
|
+
// Internet
|
|
79
|
+
website: () => faker.internet.url(),
|
|
80
|
+
url: () => faker.internet.url(),
|
|
81
|
+
ip: () => faker.internet.ip(),
|
|
82
|
+
password: () => faker.internet.password(),
|
|
83
|
+
|
|
84
|
+
// Content
|
|
85
|
+
title: () => faker.lorem.sentence(),
|
|
86
|
+
description: () => faker.lorem.paragraph(),
|
|
87
|
+
body: () => faker.lorem.paragraphs(3),
|
|
88
|
+
text: () => faker.lorem.text(),
|
|
89
|
+
sentence: () => faker.lorem.sentence(),
|
|
90
|
+
paragraph: () => faker.lorem.paragraph(),
|
|
91
|
+
slug: () => faker.lorem.slug(),
|
|
92
|
+
|
|
93
|
+
// Commerce
|
|
94
|
+
price: () => parseFloat(faker.commerce.price()),
|
|
95
|
+
product: () => faker.commerce.productName(),
|
|
96
|
+
productName: () => faker.commerce.productName(),
|
|
97
|
+
productDescription: () => faker.commerce.productDescription(),
|
|
98
|
+
category: () => faker.commerce.department(),
|
|
99
|
+
|
|
100
|
+
// Images
|
|
101
|
+
image: () => faker.image.url(),
|
|
102
|
+
imageUrl: () => faker.image.url(),
|
|
103
|
+
|
|
104
|
+
// Date/Time
|
|
105
|
+
date: () => faker.date.recent().toISOString(),
|
|
106
|
+
pastDate: () => faker.date.past().toISOString(),
|
|
107
|
+
futureDate: () => faker.date.future().toISOString(),
|
|
108
|
+
birthDate: () => faker.date.birthdate().toISOString(),
|
|
109
|
+
|
|
110
|
+
// Numbers
|
|
111
|
+
number: () => faker.number.int({ min: 1, max: 1000 }),
|
|
112
|
+
age: () => faker.number.int({ min: 18, max: 80 }),
|
|
113
|
+
rating: () => faker.number.int({ min: 1, max: 5 }),
|
|
114
|
+
quantity: () => faker.number.int({ min: 1, max: 100 }),
|
|
115
|
+
|
|
116
|
+
// Boolean
|
|
117
|
+
boolean: () => faker.datatype.boolean(),
|
|
118
|
+
isActive: () => faker.datatype.boolean(),
|
|
119
|
+
isVerified: () => faker.datatype.boolean(),
|
|
120
|
+
|
|
121
|
+
// Misc
|
|
122
|
+
uuid: () => faker.string.uuid(),
|
|
123
|
+
color: () => faker.color.human(),
|
|
124
|
+
word: () => faker.word.noun(),
|
|
125
|
+
words: () => faker.word.words(3),
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// Get available faker fields
|
|
129
|
+
app.get("/faker/fields", (req, res) => {
|
|
130
|
+
res.json({
|
|
131
|
+
message: "Available faker fields for auto-generation",
|
|
132
|
+
fields: Object.keys(fakerFieldMap),
|
|
133
|
+
usage: {
|
|
134
|
+
endpoint: "POST /:resource",
|
|
135
|
+
example: {
|
|
136
|
+
fields: ["name", "email", "avatar"],
|
|
137
|
+
count: 20
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
49
143
|
app.get("/", (req, res) => {
|
|
50
144
|
const data = readData();
|
|
51
145
|
const resources = Object.keys(data).filter(k => !k.startsWith("_"));
|
|
@@ -56,10 +150,11 @@ app.get("/", (req, res) => {
|
|
|
56
150
|
endpoints: {
|
|
57
151
|
"GET /:resource": "Get all items",
|
|
58
152
|
"GET /:resource/:id": "Get single item",
|
|
59
|
-
"POST /:resource": "Create new item",
|
|
153
|
+
"POST /:resource": "Create new item OR generate fake data with { fields: [...], count: N }",
|
|
60
154
|
"PUT /:resource/:id": "Replace item",
|
|
61
155
|
"PATCH /:resource/:id": "Update item",
|
|
62
|
-
"DELETE /:resource/:id": "Delete item"
|
|
156
|
+
"DELETE /:resource/:id": "Delete item",
|
|
157
|
+
"GET /faker/fields": "List available faker fields"
|
|
63
158
|
}
|
|
64
159
|
});
|
|
65
160
|
});
|
|
@@ -127,6 +222,43 @@ app.post("/:resource", (req, res) => {
|
|
|
127
222
|
data[resource] = [];
|
|
128
223
|
console.log(` π Created new resource: ${resource}`);
|
|
129
224
|
}
|
|
225
|
+
|
|
226
|
+
// Check if this is a faker request (has 'fields' array)
|
|
227
|
+
if (Array.isArray(req.body.fields) && req.body.fields.length > 0) {
|
|
228
|
+
const { fields, count = 10 } = req.body;
|
|
229
|
+
|
|
230
|
+
const generatedItems = [];
|
|
231
|
+
for (let i = 0; i < count; i++) {
|
|
232
|
+
const item = {
|
|
233
|
+
id: faker.string.uuid(),
|
|
234
|
+
createdAt: new Date().toISOString()
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
fields.forEach(field => {
|
|
238
|
+
if (fakerFieldMap[field]) {
|
|
239
|
+
item[field] = fakerFieldMap[field]();
|
|
240
|
+
} else {
|
|
241
|
+
// Default to random words if field not mapped
|
|
242
|
+
item[field] = faker.word.words(2);
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
data[resource].push(item);
|
|
247
|
+
generatedItems.push(item);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
writeData(data);
|
|
251
|
+
console.log(` β
Generated ${count} fake ${resource}`);
|
|
252
|
+
|
|
253
|
+
return res.status(201).json({
|
|
254
|
+
message: `Successfully generated ${count} ${resource}`,
|
|
255
|
+
count: count,
|
|
256
|
+
sample: generatedItems.slice(0, 3),
|
|
257
|
+
total: data[resource].length
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Normal POST - create single item with provided key-value pairs
|
|
130
262
|
const newId = req.body.id || Date.now();
|
|
131
263
|
if (data[resource].some(item => String(item.id) === String(newId))) {
|
|
132
264
|
return res.status(409).json({
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "360-mock-server",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "π Zero-config dynamic mock REST API server for frontend developers",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "π Zero-config dynamic mock REST API server with Faker.js auto-generation for frontend developers",
|
|
5
5
|
"main": "lib/server.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"360-mock": "./bin/cli.js"
|
|
@@ -17,11 +17,13 @@
|
|
|
17
17
|
"server",
|
|
18
18
|
"json",
|
|
19
19
|
"fake",
|
|
20
|
+
"faker",
|
|
20
21
|
"backend",
|
|
21
22
|
"frontend",
|
|
22
23
|
"development",
|
|
23
24
|
"testing",
|
|
24
|
-
"crud"
|
|
25
|
+
"crud",
|
|
26
|
+
"auto-generate"
|
|
25
27
|
],
|
|
26
28
|
"author": "zahidrahimoon",
|
|
27
29
|
"license": "MIT",
|
|
@@ -42,6 +44,7 @@
|
|
|
42
44
|
"node": ">=14.0.0"
|
|
43
45
|
},
|
|
44
46
|
"dependencies": {
|
|
47
|
+
"@faker-js/faker": "^10.2.0",
|
|
45
48
|
"commander": "^11.1.0",
|
|
46
49
|
"cors": "^2.8.5",
|
|
47
50
|
"express": "^4.18.2"
|