jgloo 2.0.0 → 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 +277 -267
- package/LICENSE +21 -21
- package/README.md +242 -242
- package/cli.mjs +19 -17
- package/jgloo.d.ts +1 -1
- package/jgloo.mjs +27 -27
- package/mock/api/example.mjs +7 -0
- package/package.json +2 -2
- package/rest.mjs +92 -92
- package/server.mjs +101 -101
package/rest.mjs
CHANGED
|
@@ -1,93 +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
|
-
}
|
|
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
93
|
}
|
package/server.mjs
CHANGED
|
@@ -1,101 +1,101 @@
|
|
|
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
|
-
const app = express();
|
|
11
|
-
const params = process.argv.slice(2);
|
|
12
|
-
const root = join(process.cwd(), params[0]);
|
|
13
|
-
const port = params[1];
|
|
14
|
-
const staticUrl = params[2];
|
|
15
|
-
|
|
16
|
-
const apiPath =
|
|
17
|
-
const middlewarePath =
|
|
18
|
-
const staticPath =
|
|
19
|
-
|
|
20
|
-
if (!existsSync(root)) {
|
|
21
|
-
console.error(`The root folder "${root}" doesn't exist.`);
|
|
22
|
-
process.exit(2);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (!port) {
|
|
26
|
-
console.error(`You must provide the port parameter.`);
|
|
27
|
-
process.exit(2);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Utility to deep load files
|
|
31
|
-
const walk = (entry, level = 1) => {
|
|
32
|
-
let list = [];
|
|
33
|
-
const items = readdirSync(entry);
|
|
34
|
-
|
|
35
|
-
items.forEach(item => {
|
|
36
|
-
const subEntry = join(entry, item);
|
|
37
|
-
|
|
38
|
-
lstatSync(subEntry).isDirectory() && level < 10
|
|
39
|
-
? list = list.concat(walk(subEntry, level + 1))
|
|
40
|
-
: list.push(subEntry);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
return list;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
// Config
|
|
47
|
-
app.use(cors());
|
|
48
|
-
app.use(bodyParser.json());
|
|
49
|
-
app.use(multer({ dest: staticPath }).any());
|
|
50
|
-
|
|
51
|
-
// Add middlewares
|
|
52
|
-
if (existsSync(middlewarePath)) {
|
|
53
|
-
const middlewareQueue = walk(middlewarePath)
|
|
54
|
-
.filter(file => file.endsWith('js'))
|
|
55
|
-
.map(file => import(file));
|
|
56
|
-
|
|
57
|
-
const middlewareFiles = await Promise.all(middlewareQueue);
|
|
58
|
-
middlewareFiles.forEach(m => app.use(m.default));
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Add the static folder
|
|
62
|
-
if (existsSync(staticPath)) {
|
|
63
|
-
app.use(`/${staticUrl}`, express.static(staticPath));
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Add API
|
|
67
|
-
if (!existsSync(apiPath)) {
|
|
68
|
-
console.error(`No "api" folder found in the folder "${root}".`);
|
|
69
|
-
process.exit(2);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const apiQueue = walk(apiPath)
|
|
73
|
-
.filter(file => file.endsWith('js'))
|
|
74
|
-
.map(file => import(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));
|
|
78
|
-
|
|
79
|
-
if (!api.length) {
|
|
80
|
-
console.error(`No API file defined. Create one.`);
|
|
81
|
-
process.exit(2);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
api.forEach(config => {
|
|
85
|
-
// Add the API delay, if it is provided
|
|
86
|
-
const middleware = config.delay
|
|
87
|
-
? getDelayMiddleware(config.delay)
|
|
88
|
-
: (_, __, next) => next();
|
|
89
|
-
|
|
90
|
-
if (config.method === 'resource') {
|
|
91
|
-
// ReST resource
|
|
92
|
-
configureResource(app, config, middleware);
|
|
93
|
-
} else {
|
|
94
|
-
// Custom endpoint
|
|
95
|
-
app[config.method](config.path, middleware, config.callback);
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
const message = `jgloo builded on the ice shelf "${root}" and the port ${port}.`;
|
|
100
|
-
app.listen(port, () => console.log('\x1b[36m', message));
|
|
101
|
-
|
|
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
|
+
const app = express();
|
|
11
|
+
const params = process.argv.slice(2);
|
|
12
|
+
const root = join(process.cwd(), params[0]);
|
|
13
|
+
const port = params[1];
|
|
14
|
+
const staticUrl = params[2];
|
|
15
|
+
|
|
16
|
+
const apiPath = join(root, 'api');
|
|
17
|
+
const middlewarePath = join(root, 'middlewares');
|
|
18
|
+
const staticPath = join(root, 'static');
|
|
19
|
+
|
|
20
|
+
if (!existsSync(root)) {
|
|
21
|
+
console.error(`The root folder "${root}" doesn't exist.`);
|
|
22
|
+
process.exit(2);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!port) {
|
|
26
|
+
console.error(`You must provide the port parameter.`);
|
|
27
|
+
process.exit(2);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Utility to deep load files
|
|
31
|
+
const walk = (entry, level = 1) => {
|
|
32
|
+
let list = [];
|
|
33
|
+
const items = readdirSync(entry);
|
|
34
|
+
|
|
35
|
+
items.forEach(item => {
|
|
36
|
+
const subEntry = join(entry, item);
|
|
37
|
+
|
|
38
|
+
lstatSync(subEntry).isDirectory() && level < 10
|
|
39
|
+
? list = list.concat(walk(subEntry, level + 1))
|
|
40
|
+
: list.push(subEntry);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
return list;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Config
|
|
47
|
+
app.use(cors());
|
|
48
|
+
app.use(bodyParser.json());
|
|
49
|
+
app.use(multer({ dest: staticPath }).any());
|
|
50
|
+
|
|
51
|
+
// Add middlewares
|
|
52
|
+
if (existsSync(middlewarePath)) {
|
|
53
|
+
const middlewareQueue = walk(middlewarePath)
|
|
54
|
+
.filter(file => file.endsWith('js'))
|
|
55
|
+
.map(file => import(`file://${file}`));
|
|
56
|
+
|
|
57
|
+
const middlewareFiles = await Promise.all(middlewareQueue);
|
|
58
|
+
middlewareFiles.forEach(m => app.use(m.default));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Add the static folder
|
|
62
|
+
if (existsSync(staticPath)) {
|
|
63
|
+
app.use(`/${staticUrl}`, express.static(staticPath));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Add API
|
|
67
|
+
if (!existsSync(apiPath)) {
|
|
68
|
+
console.error(`No "api" folder found in the folder "${root}".`);
|
|
69
|
+
process.exit(2);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const apiQueue = walk(apiPath)
|
|
73
|
+
.filter(file => file.endsWith('js'))
|
|
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));
|
|
78
|
+
|
|
79
|
+
if (!api.length) {
|
|
80
|
+
console.error(`No API file defined. Create one.`);
|
|
81
|
+
process.exit(2);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
api.forEach(config => {
|
|
85
|
+
// Add the API delay, if it is provided
|
|
86
|
+
const middleware = config.delay
|
|
87
|
+
? getDelayMiddleware(config.delay)
|
|
88
|
+
: (_, __, next) => next();
|
|
89
|
+
|
|
90
|
+
if (config.method === 'resource') {
|
|
91
|
+
// ReST resource
|
|
92
|
+
configureResource(app, config, middleware);
|
|
93
|
+
} else {
|
|
94
|
+
// Custom endpoint
|
|
95
|
+
app[config.method](config.path, middleware, config.callback);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const message = `jgloo builded on the ice shelf "${root}" and the port ${port}.`;
|
|
100
|
+
app.listen(port, () => console.log('\x1b[36m', message));
|
|
101
|
+
|