jgloo 1.9.4 → 2.0.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/CHANGELOG.md CHANGED
@@ -1,3 +1,25 @@
1
+ <a name="2.0.1"></a>
2
+
3
+ ## [2.0.1](https://github.com/zosma180/jgloo/compare/2.0.0...2.0.1) (2025-05-09)
4
+
5
+ ### Fixes
6
+
7
+ - Fixed the internal module imports on Windows.
8
+
9
+ ---
10
+
11
+ <a name="2.0.0"></a>
12
+
13
+ ## [2.0.0](https://github.com/zosma180/jgloo/compare/1.9.4...2.0.0) (2024-12-11)
14
+
15
+ ### Features
16
+
17
+ - Converted the codebase to ES module style.
18
+
19
+ **WARNING**: starting from this version, the CommonJS api are nomore supported.
20
+
21
+ ---
22
+
1
23
  <a name="1.9.4"></a>
2
24
 
3
25
  ## [1.9.4](https://github.com/zosma180/jgloo/compare/1.9.3...1.9.4) (2024-03-30)
package/README.md CHANGED
@@ -56,7 +56,7 @@ Now you are ready to [create your first API](#create-a-simple-api).
56
56
  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:
57
57
 
58
58
  ```javascript
59
- module.exports = {
59
+ export default {
60
60
  path: '/hello',
61
61
  method: 'get',
62
62
  callback: (req, res) => {
@@ -75,7 +75,7 @@ You are ready to [run the server](#run-the-server) now.
75
75
  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:
76
76
 
77
77
  ```javascript
78
- module.exports = {
78
+ export default {
79
79
  path: '/user',
80
80
  method: 'resource',
81
81
  };
@@ -93,7 +93,7 @@ With these few rows of code will be created 6 routes:
93
93
  If you want to skip any of the previous routes, you can add the "not" property:
94
94
 
95
95
  ```javascript
96
- module.exports = {
96
+ export default {
97
97
  path: '/user',
98
98
  method: 'resource',
99
99
  not: ['LIST']
@@ -109,9 +109,9 @@ If you need to control the logic of your resources, you can create a custom API
109
109
  To achieve it create a new file in the "api" folder with the name you prefer and the following snippet:
110
110
 
111
111
  ```javascript
112
- const { getResource, setResource } = require('jgloo');
112
+ import { getResource, setResource } from 'jgloo';
113
113
 
114
- module.exports = {
114
+ export default {
115
115
  path: '/user',
116
116
  method: 'post',
117
117
  callback: (req, res) => {
@@ -142,7 +142,7 @@ To add a middleware, you have to create a folder "middlewares" in your chosen ro
142
142
  Then create a new file inside with the name you prefer and the following sample snippet:
143
143
 
144
144
  ```javascript
145
- module.exports = (req, res, next) => {
145
+ export default function(req, res, next) {
146
146
  const isAuthorized = req.get('Authorization') === 'my-token';
147
147
  isAuthorized ? next() : res.sendStatus(401);
148
148
  };
@@ -159,7 +159,7 @@ The [default ReST API](#create-a-default-rest-api) store the JSON file with the
159
159
  If you want to specify the file name of the resources, you can set it as the "name" property of the API:
160
160
 
161
161
  ```javascript
162
- module.exports = {
162
+ export default {
163
163
  path: '/my/long/path',
164
164
  method: 'resource',
165
165
  name: 'user',
@@ -190,7 +190,7 @@ It's recommended to add the `static` folder in the `.gitignore` file.
190
190
  If you want to simulate a network delay, you can add the `delay` property to your API configuration:
191
191
 
192
192
  ```javascript
193
- module.exports = {
193
+ export default {
194
194
  ...
195
195
  delay: 3 // Seconds
196
196
  };
@@ -207,7 +207,7 @@ If you have a scenario where two or more paths have conflicting values, e.g.:
207
207
  you can add the `priority` property to your API configuration:
208
208
 
209
209
  ```javascript
210
- module.exports = {
210
+ export default {
211
211
  ...
212
212
  priority: 2
213
213
  };
package/cli.mjs ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+
3
+ 'use strict';'use strict';
4
+ import { execSync } from 'child_process';
5
+ import minimist from 'minimist';
6
+ import { dirname, join } from 'path';
7
+ import { fileURLToPath } from 'url';
8
+
9
+ const pkg = dirname(fileURLToPath(import.meta.url));
10
+ const params = minimist(process.argv.slice(2));
11
+ const folder = params.f || params.folder || 'mock';
12
+ const port = params.p || params.port || 3000;
13
+ const staticUrl = params.s || params.static || 'static';
14
+
15
+ const db = join('db', '*.json');
16
+ const nodemon = `npx nodemon --ignore "${db}"`;
17
+ const entrypoint = join(pkg, 'server.mjs')
18
+ const target = `"${entrypoint}" "${folder}" "${port}" "${staticUrl}"`;
19
+ execSync(`${nodemon} --watch "${folder}" ${target}`, { stdio: 'inherit' });
package/jgloo.mjs ADDED
@@ -0,0 +1,28 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
2
+
3
+ const params = process.argv.slice(2);
4
+ const db = `${params[0]}/db`;
5
+
6
+ export const getResource = name => {
7
+ const path = `${db}/${name}.json`;
8
+ if (!existsSync(path)) { return null; }
9
+ const file = readFileSync(path);
10
+
11
+ try {
12
+ return JSON.parse(file);
13
+ } catch (error) {
14
+ throw new Error(`${file}.json is an invalid JSON.`);
15
+ }
16
+ }
17
+
18
+ export const setResource = (name, value) => {
19
+ if (!existsSync(db)) { mkdirSync(db); }
20
+ const path = `${db}/${name}.json`;
21
+ writeFileSync(path, JSON.stringify(value), 'utf8');
22
+ };
23
+
24
+ export const getDelayMiddleware = delay => {
25
+ return (_, __, next) => {
26
+ setTimeout(next, delay * 1000);
27
+ };
28
+ }
@@ -0,0 +1,7 @@
1
+ export default {
2
+ path: '/hello',
3
+ method: 'get',
4
+ callback: (req, res) => {
5
+ res.json({ message: 'Hello World!' });
6
+ },
7
+ };
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "jgloo",
3
- "version": "1.9.4",
3
+ "version": "2.0.1",
4
4
  "description": "The coldest mock server.",
5
5
  "homepage": "https://github.com/zosma180/jgloo",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/zosma180/jgloo.git"
9
9
  },
10
- "main": "jgloo.js",
10
+ "main": "jgloo.mjs",
11
11
  "scripts": {
12
- "start": "./cli",
13
- "deploy": "npm-deploy . ."
12
+ "start": "node cli.mjs",
13
+ "deploy": "npm-deploy.mjs . ."
14
14
  },
15
15
  "bin": {
16
- "jgloo": "cli"
16
+ "jgloo": "cli.mjs"
17
17
  },
18
18
  "keywords": [
19
19
  "jgloo",
package/rest.mjs ADDED
@@ -0,0 +1,93 @@
1
+ import path from 'path';
2
+ import { getResource, setResource } from './jgloo.mjs';
3
+
4
+ export const configureResource = (app, config, middleware) => {
5
+ const fallback = config.path.split('/').filter(Boolean).join('-');
6
+ const resourceName = config.name || fallback;
7
+ const skips = config.not || [];
8
+
9
+ // List
10
+ if (skips.includes('LIST') === false) {
11
+ app.get(config.path, middleware, (req, res) => {
12
+ const resource = getResource(resourceName) || [];
13
+ res.json(resource);
14
+ });
15
+ }
16
+
17
+ // Read
18
+ if (skips.includes('READ') === false) {
19
+ app.get(`${config.path}/:id`, middleware, (req, res) => {
20
+ const id = Number(req.params.id);
21
+
22
+ const resource = getResource(resourceName) || [];
23
+ const model = resource.find(r => r.id === id);
24
+ if (!model) { return res.sendStatus(404); }
25
+
26
+ res.json(model);
27
+ });
28
+ }
29
+
30
+ // Create
31
+ if (skips.includes('CREATE') === false) {
32
+ app.post(config.path, middleware, (req, res) => {
33
+ const resource = getResource(resourceName) || [];
34
+ const model = req.body;
35
+
36
+ model.id = Date.now();
37
+ resource.push(model);
38
+ setResource(resourceName, resource);
39
+
40
+ res.json(model);
41
+ });
42
+ }
43
+
44
+ // Update
45
+ if (skips.includes('UPDATE') === false) {
46
+ app.put(`${config.path}/:id`, middleware, (req, res) => {
47
+ const id = Number(req.params.id);
48
+
49
+ const resource = getResource(resourceName) || [];
50
+ const index = resource.findIndex(r => r.id === id);
51
+ if (index === -1) { return res.sendStatus(404); }
52
+
53
+ resource[index] = req.body;
54
+ resource[index].id = id;
55
+ setResource(resourceName, resource);
56
+
57
+ res.json(resource[index]);
58
+ });
59
+ }
60
+
61
+ // Patch
62
+ if (skips.includes('PATCH') === false) {
63
+ app.patch(`${config.path}/:id`, middleware, (req, res) => {
64
+ const id = Number(req.params.id);
65
+
66
+ const resource = getResource(resourceName) || [];
67
+ const index = resource.findIndex(r => r.id === id);
68
+ if (index === -1) { return res.sendStatus(404); }
69
+
70
+ resource[index] = { ...resource[index], ...req.body };
71
+ resource[index].id = id;
72
+ setResource(resourceName, resource);
73
+
74
+ res.json(resource[index]);
75
+ });
76
+ }
77
+
78
+ // Delete
79
+ if (skips.includes('DELETE') === false) {
80
+ app.delete(`${config.path}/:id`, middleware, (req, res) => {
81
+ const id = Number(req.params.id);
82
+
83
+ let resource = getResource(resourceName) || [];
84
+ const index = resource.findIndex(r => r.id === id);
85
+ if (index === -1) { return res.sendStatus(404); }
86
+
87
+ resource = resource.filter(r => r.id !== id);
88
+ setResource(resourceName, resource);
89
+
90
+ res.json(id);
91
+ });
92
+ }
93
+ }
@@ -1,21 +1,21 @@
1
- const { join } = require('path');
2
- const { existsSync, readdirSync, lstatSync } = require('fs');
3
- const express = require('express');
4
- const cors = require('cors');
5
- const bodyParser = require('body-parser');
6
- const multer = require('multer');
7
-
8
- const { configureResource } = require(join(__dirname, 'rest'));
9
- const { getDelayMiddleware } = require(join(__dirname, 'jgloo'));
1
+ import { join } from 'path';
2
+ import { existsSync, readdirSync, lstatSync } from 'fs';
3
+ import express from 'express';
4
+ import cors from 'cors';
5
+ import bodyParser from 'body-parser';
6
+ import multer from 'multer';
7
+ import { configureResource } from './rest.mjs';
8
+ import { getDelayMiddleware } from './jgloo.mjs';
9
+
10
10
  const app = express();
11
11
  const params = process.argv.slice(2);
12
12
  const root = join(process.cwd(), params[0]);
13
13
  const port = params[1];
14
14
  const staticUrl = params[2];
15
15
 
16
- const apiPath = `${root}/api`;
17
- const middlewarePath = `${root}/middlewares`;
18
- const staticPath = `${root}/static`;
16
+ const apiPath = join(root, 'api');
17
+ const middlewarePath = join(root, 'middlewares');
18
+ const staticPath = join(root, 'static');
19
19
 
20
20
  if (!existsSync(root)) {
21
21
  console.error(`The root folder "${root}" doesn't exist.`);
@@ -50,12 +50,12 @@ app.use(multer({ dest: staticPath }).any());
50
50
 
51
51
  // Add middlewares
52
52
  if (existsSync(middlewarePath)) {
53
- walk(middlewarePath)
53
+ const middlewareQueue = walk(middlewarePath)
54
54
  .filter(file => file.endsWith('js'))
55
- .forEach(file => {
56
- const middleware = require(file);
57
- app.use(middleware);
58
- });
55
+ .map(file => import(`file://${file}`));
56
+
57
+ const middlewareFiles = await Promise.all(middlewareQueue);
58
+ middlewareFiles.forEach(m => app.use(m.default));
59
59
  }
60
60
 
61
61
  // Add the static folder
@@ -69,10 +69,12 @@ if (!existsSync(apiPath)) {
69
69
  process.exit(2);
70
70
  }
71
71
 
72
- const api = walk(apiPath)
72
+ const apiQueue = walk(apiPath)
73
73
  .filter(file => file.endsWith('js'))
74
- .map(file => require(file))
75
- .sort((a, b) => (b.priority || 0) - (a.priority || 0));
74
+ .map(file => import(`file://${file}`));
75
+
76
+ const apiFiles = await Promise.all(apiQueue);
77
+ const api = apiFiles.map(f => f.default).sort((a, b) => (b.priority || 0) - (a.priority || 0));
76
78
 
77
79
  if (!api.length) {
78
80
  console.error(`No API file defined. Create one.`);
@@ -87,7 +89,7 @@ api.forEach(config => {
87
89
 
88
90
  if (config.method === 'resource') {
89
91
  // ReST resource
90
- configureResource(app, config);
92
+ configureResource(app, config, middleware);
91
93
  } else {
92
94
  // Custom endpoint
93
95
  app[config.method](config.path, middleware, config.callback);
package/cli DELETED
@@ -1,19 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- 'use strict';
4
- const { exec } = require('child_process');
5
- const minimist = require('minimist');
6
-
7
- const params = minimist(process.argv.slice(2));
8
- const folder = params.f || params.folder || 'mock';
9
- const port = params.p || params.port || 3000;
10
- const staticUrl = params.s || params.static || 'static';
11
- const server = `${__dirname}/server.js`;
12
-
13
- const child = exec(
14
- `nodemon --watch "${folder}" --ignore "db/*.json" "${server}" "${folder}" "${port}" "${staticUrl}"`
15
- );
16
-
17
- child.stdout.on('data', (data) => console.log(String(data)));
18
- child.stderr.on('data', (data) => console.error(String(data)));
19
- child.on('close', (code) => process.exit(code));
package/jgloo.js DELETED
@@ -1,30 +0,0 @@
1
- const { existsSync, mkdirSync, readFileSync, writeFileSync } = require('fs');
2
-
3
- const params = process.argv.slice(2);
4
- const db = `${params[0]}/db`;
5
-
6
- module.exports = {
7
- getResource: name => {
8
- const path = `${db}/${name}.json`;
9
- if (!existsSync(path)) { return null; }
10
- const file = readFileSync(path);
11
-
12
- try {
13
- return JSON.parse(file);
14
- } catch (error) {
15
- throw new Error(`${file}.json is an invalid JSON.`);
16
- }
17
- },
18
-
19
- setResource: (name, value) => {
20
- if (!existsSync(db)) { mkdirSync(db); }
21
- const path = `${db}/${name}.json`;
22
- writeFileSync(path, JSON.stringify(value), 'utf8');
23
- },
24
-
25
- getDelayMiddleware: (delay) => {
26
- return (_, __, next) => {
27
- setTimeout(next, delay * 1000);
28
- };
29
- },
30
- }
package/rest.js DELETED
@@ -1,95 +0,0 @@
1
- const path = require('path');
2
- const { getResource, setResource } = require(path.join(__dirname, 'jgloo'));
3
-
4
- module.exports = {
5
- configureResource: (app, config, middleware) => {
6
- const fallback = config.path.split('/').filter(Boolean).join('-');
7
- const resourceName = config.name || fallback;
8
- const skips = config.not || [];
9
-
10
- // List
11
- if (skips.includes('LIST') === false) {
12
- app.get(config.path, middleware, (req, res) => {
13
- const resource = getResource(resourceName) || [];
14
- res.json(resource);
15
- });
16
- }
17
-
18
- // Read
19
- if (skips.includes('READ') === false) {
20
- app.get(`${config.path}/:id`, middleware, (req, res) => {
21
- const id = Number(req.params.id);
22
-
23
- const resource = getResource(resourceName) || [];
24
- const model = resource.find(r => r.id === id);
25
- if (!model) { return res.sendStatus(404); }
26
-
27
- res.json(model);
28
- });
29
- }
30
-
31
- // Create
32
- if (skips.includes('CREATE') === false) {
33
- app.post(config.path, middleware, (req, res) => {
34
- const resource = getResource(resourceName) || [];
35
- const model = req.body;
36
-
37
- model.id = Date.now();
38
- resource.push(model);
39
- setResource(resourceName, resource);
40
-
41
- res.json(model);
42
- });
43
- }
44
-
45
- // Update
46
- if (skips.includes('UPDATE') === false) {
47
- app.put(`${config.path}/:id`, middleware, (req, res) => {
48
- const id = Number(req.params.id);
49
-
50
- const resource = getResource(resourceName) || [];
51
- const index = resource.findIndex(r => r.id === id);
52
- if (index === -1) { return res.sendStatus(404); }
53
-
54
- resource[index] = req.body;
55
- resource[index].id = id;
56
- setResource(resourceName, resource);
57
-
58
- res.json(resource[index]);
59
- });
60
- }
61
-
62
- // Patch
63
- if (skips.includes('PATCH') === false) {
64
- app.patch(`${config.path}/:id`, middleware, (req, res) => {
65
- const id = Number(req.params.id);
66
-
67
- const resource = getResource(resourceName) || [];
68
- const index = resource.findIndex(r => r.id === id);
69
- if (index === -1) { return res.sendStatus(404); }
70
-
71
- resource[index] = { ...resource[index], ...req.body };
72
- resource[index].id = id;
73
- setResource(resourceName, resource);
74
-
75
- res.json(resource[index]);
76
- });
77
- }
78
-
79
- // Delete
80
- if (skips.includes('DELETE') === false) {
81
- app.delete(`${config.path}/:id`, middleware, (req, res) => {
82
- const id = Number(req.params.id);
83
-
84
- let resource = getResource(resourceName) || [];
85
- const index = resource.findIndex(r => r.id === id);
86
- if (index === -1) { return res.sendStatus(404); }
87
-
88
- resource = resource.filter(r => r.id !== id);
89
- setResource(resourceName, resource);
90
-
91
- res.json(id);
92
- });
93
- }
94
- }
95
- }