jgloo 1.4.0 → 1.6.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/CHANGELOG.md CHANGED
@@ -1,3 +1,43 @@
1
+ <a name="1.6.0"></a>
2
+
3
+ ## [1.6.0](https://github.com/zosma180/jgloo/compare/1.5.2...1.6.0) (2022-02-20)
4
+
5
+ ### Features
6
+
7
+ - Added the optional "delay" property to the configuration
8
+
9
+ ---
10
+
11
+ <a name="1.5.2"></a>
12
+
13
+ ## [1.5.2](https://github.com/zosma180/jgloo/compare/1.5.1...1.5.2) (2021-02-21)
14
+
15
+ ### Bug Fixes
16
+
17
+ - Fixed the folder path with space characters
18
+
19
+ ---
20
+
21
+ <a name="1.5.1"></a>
22
+
23
+ ## [1.5.1](https://github.com/zosma180/jgloo/compare/1.5.0...1.5.1) (2021-02-17)
24
+
25
+ ### Bug Fixes
26
+
27
+ - Fixed the folder path for Windows environment
28
+
29
+ ---
30
+
31
+ <a name="1.5.0"></a>
32
+
33
+ ## [1.5.0](https://github.com/zosma180/jgloo/compare/1.4.0...1.5.0) (2021-01-25)
34
+
35
+ ### Features
36
+
37
+ - Added the optional "not" property to the default ReST API configuration
38
+
39
+ ---
40
+
1
41
  <a name="1.4.0"></a>
2
42
 
3
43
  ## [1.4.0](https://github.com/zosma180/jgloo/compare/1.3.0...1.4.0) (2020-06-30)
package/README.md CHANGED
@@ -16,7 +16,7 @@ This project is based on the Node framework Express. The highlights are:
16
16
 
17
17
  - Create a ReST API with two rows of code
18
18
  - Create custom API easily
19
- - Create custom middleware easily (i.e. auth check)
19
+ - Create custom middleware easily (e.g. auth check)
20
20
  - Store data in accessible JSON files
21
21
  - Reload the live changes of your mocks automatically (thanks to nodemon package)
22
22
  - Expose a dedicated folder for the static files (images, assets etc...)
@@ -27,11 +27,11 @@ This project is based on the Node framework Express. The highlights are:
27
27
  ## Installation
28
28
 
29
29
  ```bash
30
- npm i -g jgloo
30
+ npm i -D jgloo
31
31
  ```
32
32
 
33
33
  After the installation create a folder "mock" in your project root (you can use another path and folder name if you want).
34
- The **only requirement** is to create a subfolder "api" in your chosen path (i.e. "mock/api").
34
+ The **only requirement** is to create a subfolder "api" in your chosen path (e.g. "mock/api").
35
35
  Now you are ready to [create your first API](#create-a-simple-api).
36
36
 
37
37
  ---
@@ -45,6 +45,7 @@ Now you are ready to [create your first API](#create-a-simple-api).
45
45
  - [Where data are stored](#where-data-are-stored)
46
46
  - [Expose the static files](#expose-the-static-files)
47
47
  - [Handle requests with file uploads](#handle-requests-with-file-uploads)
48
+ - [Simulate network delay](#simulate-network-delay)
48
49
  - [Run the server](#run-the-server)
49
50
 
50
51
  ---
@@ -53,7 +54,7 @@ Now you are ready to [create your first API](#create-a-simple-api).
53
54
 
54
55
  To setup your first API create a new file "hello.js" in the "api" folder. The name of the file does not matter. Then insert the following snippet:
55
56
 
56
- ```typescript
57
+ ```javascript
57
58
  module.exports = {
58
59
  path: '/hello',
59
60
  method: 'get',
@@ -72,7 +73,7 @@ You are ready to [run the server](#run-the-server) now.
72
73
 
73
74
  To setup a ReST API, you have to create a new file in the "api" folder with the name you prefer and the following snippet:
74
75
 
75
- ```typescript
76
+ ```javascript
76
77
  module.exports = {
77
78
  path: '/user',
78
79
  method: 'resource',
@@ -88,6 +89,17 @@ With these few rows of code will be created 6 routes:
88
89
  - PATCH /user/:id : allow to merge an existent user data with the request body values and return it as response;
89
90
  - DELETE /user/:id : allow to delete an existent user and return the deleted id.
90
91
 
92
+ If you want to skip any of the previous routes, you can add the "not" property:
93
+
94
+ ```javascript
95
+ module.exports = {
96
+ path: '/user',
97
+ method: 'resource',
98
+ not: ['LIST']
99
+ };
100
+ ```
101
+ The available values of the "not" property are ['LIST', 'READ', 'CREATE', 'UPDATE', 'PATCH', 'DELETE']
102
+
91
103
  ---
92
104
 
93
105
  ### Create a custom ReST API
@@ -95,7 +107,7 @@ With these few rows of code will be created 6 routes:
95
107
  If you need to control the logic of your resources, you can create a custom API that read and/or write the data in the JSON database.
96
108
  To achieve it create a new file in the "api" folder with the name you prefer and the following snippet:
97
109
 
98
- ```typescript
110
+ ```javascript
99
111
  const { getResource, setResource } = require('jgloo');
100
112
 
101
113
  module.exports = {
@@ -125,10 +137,10 @@ module.exports = {
125
137
 
126
138
  ### Create a middleware
127
139
 
128
- To add a middleware, you have to create a folder "middlewares" in your chosen root path (i.e. "mock/middlewares").
140
+ To add a middleware, you have to create a folder "middlewares" in your chosen root path (e.g. "mock/middlewares").
129
141
  Then create a new file inside with the name you prefer and the following sample snippet:
130
142
 
131
- ```typescript
143
+ ```javascript
132
144
  module.exports = (req, res, next) => {
133
145
  const isAuthorized = req.get('Authorization') === 'my-token';
134
146
  isAuthorized ? next() : res.sendStatus(401);
@@ -141,11 +153,11 @@ This sample code check for all routes if the "Authorization" header is set and i
141
153
 
142
154
  ### Where data are stored
143
155
 
144
- The resources are stored in JSON files placed in the subfolder "db" of your chosen root path (i.e. "mock/db").
145
- The [default ReST API](#create-a-default-rest-api) store the JSON file with the name generated by resource path replacing the slashes with the minus sign (i.e. "/auth/user" will be stored as "auth-user.json").
156
+ The resources are stored in JSON files placed in the subfolder "db" of your chosen root path (e.g. "mock/db").
157
+ The [default ReST API](#create-a-default-rest-api) store the JSON file with the name generated by resource path replacing the slashes with the minus sign (e.g. "/auth/user" will be stored as "auth-user.json").
146
158
  If you want to specify the file name of the resources, you can set it as the "name" property of the API:
147
159
 
148
- ```typescript
160
+ ```javascript
149
161
  module.exports = {
150
162
  path: '/my/long/path',
151
163
  method: 'resource',
@@ -159,7 +171,7 @@ With this code, the JSON file will be stored as "user.json".
159
171
 
160
172
  ### Expose the static files
161
173
 
162
- To expose any static files you have to create the subfolder "static" in your chosen root path (i.e. "mock/static") and put all the resources inside it.
174
+ To expose any static files you have to create the subfolder "static" in your chosen root path (e.g. "mock/static") and put all the resources inside it.
163
175
  The static content is reachable by "http://localhost:3000/static/...". That's it.
164
176
 
165
177
  ---
@@ -172,24 +184,37 @@ It's recommended to add the `static` folder in the `.gitignore` file.
172
184
 
173
185
  ---
174
186
 
187
+ ### Simulate network delay
188
+
189
+ If you want to simulate a network delay, you can add the `delay` property to your API configuration:
190
+
191
+ ```javascript
192
+ module.exports = {
193
+ ...
194
+ delay: 3 // Seconds
195
+ };
196
+ ```
197
+
198
+ ---
199
+
175
200
  ### Run the server
176
201
 
177
202
  To run the server execute the following command in your project root:
178
203
 
179
204
  ```shell
180
- jgloo
205
+ npx jgloo
181
206
  ```
182
207
 
183
208
  The full optional parameters are:
184
209
 
185
210
  ```shell
186
- jgloo -f [FOLDER] -p [PORT] -s [STATIC_URL]
211
+ npx jgloo -f [FOLDER] -p [PORT] -s [STATIC_URL]
187
212
  ```
188
213
 
189
214
  For example:
190
215
 
191
216
  ```shell
192
- jgloo -f 'mock' -p 3000 -s 'static'
217
+ npx jgloo -f 'mock' -p 3000 -s 'static'
193
218
  ```
194
219
 
195
220
  - "**-f**" or "**--folder**": the folder where your mocks are placed. It's optional, by default it's the folder "mock".
package/cli CHANGED
@@ -6,13 +6,13 @@ const { exec } = require('child_process');
6
6
  const minimist = require('minimist');
7
7
 
8
8
  const params = minimist(process.argv.slice(2));
9
- const folder = path.join(process.env.PWD, params.f || params.folder || 'mock');
9
+ const folder = path.join(process.cwd(), params.f || params.folder || 'mock');
10
10
  const port = params.p || params.port || 3000;
11
11
  const staticUrl = params.s || params.static || 'static';
12
12
  const server = `${__dirname}/server.js`;
13
13
 
14
14
  const child = exec(
15
- `nodemon --watch ${folder} --ignore "db/*.json" "${server}" "${folder}" "${port}" "${staticUrl}"`
15
+ `nodemon --watch "${folder}" --ignore "db/*.json" "${server}" "${folder}" "${port}" "${staticUrl}"`
16
16
  );
17
17
 
18
18
  child.stdout.on('data', (data) => console.log(String(data)));
package/jgloo.js CHANGED
@@ -20,5 +20,11 @@ module.exports = {
20
20
  if (!existsSync(db)) { mkdirSync(db); }
21
21
  const path = `${db}/${name}.json`;
22
22
  writeFileSync(path, JSON.stringify(value), 'utf8');
23
- }
23
+ },
24
+
25
+ getDelayMiddleware: (delay) => {
26
+ return (_, __, next) => {
27
+ setTimeout(() => next(), delay * 1000);
28
+ };
29
+ },
24
30
  }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "jgloo",
3
- "version": "1.4.0",
3
+ "version": "1.6.0",
4
4
  "description": "The coldest mock server.",
5
- "homepage": "https://github.com/zosma180/jgloo",
5
+ "homepage": "https://github.com/zosma180/jgloo#readme",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/zosma180/jgloo.git"
@@ -12,7 +12,7 @@
12
12
  "deploy": "npm-deploy . ."
13
13
  },
14
14
  "bin": {
15
- "jgloo": "./cli"
15
+ "jgloo": "cli"
16
16
  },
17
17
  "keywords": [
18
18
  "jgloo",
@@ -30,6 +30,6 @@
30
30
  "express": "^4.17.1",
31
31
  "minimist": "^1.2.5",
32
32
  "multer": "^1.4.2",
33
- "nodemon": "^2.0.2"
33
+ "nodemon": "^2.0.4"
34
34
  }
35
35
  }
package/rest.js CHANGED
@@ -5,78 +5,91 @@ module.exports = {
5
5
  configureResource: (app, config) => {
6
6
  const fallback = config.path.split('/').filter(Boolean).join('-');
7
7
  const resourceName = config.name || fallback;
8
+ const skips = config.not || [];
8
9
 
9
10
  // List
10
- app.get(config.path, (req, res) => {
11
- const resource = getResource(resourceName) || [];
12
- res.json(resource);
13
- });
11
+ if (skips.includes('LIST') === false) {
12
+ app.get(config.path, (req, res) => {
13
+ const resource = getResource(resourceName) || [];
14
+ res.json(resource);
15
+ });
16
+ }
14
17
 
15
18
  // Read
16
- app.get(`${config.path}/:id`, (req, res) => {
17
- const id = Number(req.params.id);
19
+ if (skips.includes('READ') === false) {
20
+ app.get(`${config.path}/:id`, (req, res) => {
21
+ const id = Number(req.params.id);
18
22
 
19
- const resource = getResource(resourceName) || [];
20
- const model = resource.find(r => r.id === id);
21
- if (!model) { return res.sendStatus(404); }
23
+ const resource = getResource(resourceName) || [];
24
+ const model = resource.find(r => r.id === id);
25
+ if (!model) { return res.sendStatus(404); }
22
26
 
23
- res.json(model);
24
- });
27
+ res.json(model);
28
+ });
29
+ }
25
30
 
26
31
  // Create
27
- app.post(config.path, (req, res) => {
28
- const resource = getResource(resourceName) || [];
29
- const model = req.body;
32
+ if (skips.includes('CREATE') === false) {
33
+ app.post(config.path, (req, res) => {
34
+ const resource = getResource(resourceName) || [];
35
+ const model = req.body;
30
36
 
31
- model.id = Date.now();
32
- resource.push(model);
33
- setResource(resourceName, resource);
37
+ model.id = Date.now();
38
+ resource.push(model);
39
+ setResource(resourceName, resource);
34
40
 
35
- res.json(model);
36
- });
41
+ res.json(model);
42
+ });
43
+ }
37
44
 
38
45
  // Update
39
- app.put(`${config.path}/:id`, (req, res) => {
40
- const id = Number(req.params.id);
46
+ if (skips.includes('UPDATE') === false) {
47
+ app.put(`${config.path}/:id`, (req, res) => {
48
+ const id = Number(req.params.id);
41
49
 
42
- const resource = getResource(resourceName) || [];
43
- const index = resource.findIndex(r => r.id === id);
44
- if (index === -1) { return res.sendStatus(404); }
50
+ const resource = getResource(resourceName) || [];
51
+ const index = resource.findIndex(r => r.id === id);
52
+ if (index === -1) { return res.sendStatus(404); }
45
53
 
46
- resource[index] = req.body;
47
- resource[index].id = id;
48
- setResource(resourceName, resource);
54
+ resource[index] = req.body;
55
+ resource[index].id = id;
56
+ setResource(resourceName, resource);
49
57
 
50
- res.json(resource[index]);
51
- });
58
+ res.json(resource[index]);
59
+ });
60
+ }
52
61
 
53
62
  // Patch
54
- app.patch(`${config.path}/:id`, (req, res) => {
55
- const id = Number(req.params.id);
63
+ if (skips.includes('PATCH') === false) {
64
+ app.patch(`${config.path}/:id`, (req, res) => {
65
+ const id = Number(req.params.id);
56
66
 
57
- const resource = getResource(resourceName) || [];
58
- const index = resource.findIndex(r => r.id === id);
59
- if (index === -1) { return res.sendStatus(404); }
67
+ const resource = getResource(resourceName) || [];
68
+ const index = resource.findIndex(r => r.id === id);
69
+ if (index === -1) { return res.sendStatus(404); }
60
70
 
61
- resource[index] = { ...resource[index], ...req.body };
62
- resource[index].id = id;
63
- setResource(resourceName, resource);
71
+ resource[index] = { ...resource[index], ...req.body };
72
+ resource[index].id = id;
73
+ setResource(resourceName, resource);
64
74
 
65
- res.json(resource[index]);
66
- });
75
+ res.json(resource[index]);
76
+ });
77
+ }
67
78
 
68
79
  // Delete
69
- app.delete(`${config.path}/:id`, (req, res) => {
70
- const id = Number(req.params.id);
80
+ if (skips.includes('DELETE') === false) {
81
+ app.delete(`${config.path}/:id`, (req, res) => {
82
+ const id = Number(req.params.id);
71
83
 
72
- let resource = getResource(resourceName) || [];
73
- const index = resource.findIndex(r => r.id === id);
74
- if (index === -1) { return res.sendStatus(404); }
84
+ let resource = getResource(resourceName) || [];
85
+ const index = resource.findIndex(r => r.id === id);
86
+ if (index === -1) { return res.sendStatus(404); }
75
87
 
76
- resource = resource.filter(r => r.id !== id);
77
- setResource(resourceName, resource);
88
+ resource = resource.filter(r => r.id !== id);
89
+ setResource(resourceName, resource);
78
90
 
79
- res.json(id);
80
- });
91
+ res.json(id);
92
+ });
93
+ }
81
94
  }
82
95
  }
package/server.js CHANGED
@@ -6,6 +6,7 @@ const bodyParser = require('body-parser');
6
6
  const multer = require('multer');
7
7
 
8
8
  const { configureResource } = require(path.join(__dirname, 'rest'));
9
+ const { getDelayMiddleware } = require(path.join(__dirname, 'jgloo'));
9
10
  const app = express();
10
11
  const params = process.argv.slice(2);
11
12
  const root = params[0];
@@ -57,6 +58,11 @@ if (!api.length) {
57
58
  api.forEach((file) => {
58
59
  const config = require(path.join(apiPath, file));
59
60
 
61
+ // Add the API delay, if it is provided
62
+ if (config.delay) {
63
+ app.use(config.path, getDelayMiddleware(config.delay));
64
+ }
65
+
60
66
  if (config.method === 'resource') {
61
67
  // ReST resource
62
68
  configureResource(app, config);