codehooks-js 1.1.9 → 1.1.11
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 +1 -1
- package/crudlify/index.mjs +17 -13
- package/package.json +1 -1
- package/webserver.mjs +26 -17
package/README.md
CHANGED
package/crudlify/index.mjs
CHANGED
|
@@ -22,10 +22,14 @@ let _eventHooks = null;
|
|
|
22
22
|
* @param {object} options - Options
|
|
23
23
|
* @returns {EventHooks} Hooks for REST operations
|
|
24
24
|
*/
|
|
25
|
-
export default async function crudlify(app, schema = {}, options = { schema: "yup", query: "q2m" }) {
|
|
25
|
+
export default async function crudlify(app, schema = {}, options = { schema: "yup", query: "q2m", prefix: "" }) {
|
|
26
26
|
console.log('Init crudlify', schema, options)
|
|
27
27
|
_schema = schema;
|
|
28
28
|
_opt = options;
|
|
29
|
+
if (_opt.prefix === undefined || _opt.prefix === '/') {
|
|
30
|
+
_opt.prefix = '';
|
|
31
|
+
}
|
|
32
|
+
|
|
29
33
|
try {
|
|
30
34
|
// the DB variable is present when running as a codehooks.io app
|
|
31
35
|
Datastore = DB;
|
|
@@ -79,14 +83,14 @@ export default async function crudlify(app, schema = {}, options = { schema: "yu
|
|
|
79
83
|
|
|
80
84
|
console.debug('Apply routes to app');
|
|
81
85
|
// App API routes
|
|
82
|
-
app.post('/:collection', createFunc);
|
|
83
|
-
app.get('/:collection', readManyFunc);
|
|
84
|
-
app.get('/:collection/:ID', readOneFunc);
|
|
85
|
-
app.put('/:collection/:ID', updateFunc);
|
|
86
|
-
app.patch('/:collection/_byquery', patchManyFunc);
|
|
87
|
-
app.patch('/:collection/:ID', patchFunc);
|
|
88
|
-
app.delete('/:collection/_byquery', deleteManyFunc);
|
|
89
|
-
app.delete('/:collection/:ID', deleteFunc);
|
|
86
|
+
app.post(_opt.prefix+'/:collection', createFunc);
|
|
87
|
+
app.get(_opt.prefix+'/:collection', readManyFunc);
|
|
88
|
+
app.get(_opt.prefix+'/:collection/:ID', readOneFunc);
|
|
89
|
+
app.put(_opt.prefix+'/:collection/:ID', updateFunc);
|
|
90
|
+
app.patch(_opt.prefix+'/:collection/_byquery', patchManyFunc);
|
|
91
|
+
app.patch(_opt.prefix+'/:collection/:ID', patchFunc);
|
|
92
|
+
app.delete(_opt.prefix+'/:collection/_byquery', deleteManyFunc);
|
|
93
|
+
app.delete(_opt.prefix+'/:collection/:ID', deleteFunc);
|
|
90
94
|
_eventHooks = new EventHooks();
|
|
91
95
|
console.debug('Return event hooks');
|
|
92
96
|
return _eventHooks;
|
|
@@ -163,8 +167,7 @@ async function readManyFunc(req, res) {
|
|
|
163
167
|
console.log(req.headers['x-real-ip'], req.method, req.originalUrl);
|
|
164
168
|
|
|
165
169
|
const conn = await Datastore.open();
|
|
166
|
-
|
|
167
|
-
return (await conn.getMany(collection, mongoQuery)).json(res);
|
|
170
|
+
return (await conn.getMany(collection, mongoQuery.filter, mongoQuery)).json(res);
|
|
168
171
|
} catch (ex) {
|
|
169
172
|
console.error(ex.message);
|
|
170
173
|
res.status(400).send(ex.message);
|
|
@@ -262,7 +265,8 @@ async function patchManyFunc(req, res) {
|
|
|
262
265
|
console.log(req.headers['x-real-ip'], req.method, req.originalUrl);
|
|
263
266
|
const conn = await Datastore.open();
|
|
264
267
|
await _eventHooks.fireBefore(collection, 'PATCH', document);
|
|
265
|
-
|
|
268
|
+
// coll, query, doc, option
|
|
269
|
+
const result = await conn.updateMany(collection, mongoQuery.filter, document, mongoQuery);
|
|
266
270
|
await _eventHooks.fireAfter(collection, 'PATCH', result);
|
|
267
271
|
res.json(result);
|
|
268
272
|
} catch (e) {
|
|
@@ -302,7 +306,7 @@ async function deleteManyFunc(req, res) {
|
|
|
302
306
|
console.log(req.headers['x-real-ip'], req.method, req.originalUrl);
|
|
303
307
|
const mongoQuery = _query(req.query, req.headers);
|
|
304
308
|
const conn = await Datastore.open();
|
|
305
|
-
const result = await conn.removeMany(collection, mongoQuery);
|
|
309
|
+
const result = await conn.removeMany(collection, mongoQuery.filter, mongoQuery);
|
|
306
310
|
res.json(result);
|
|
307
311
|
} catch (e) {
|
|
308
312
|
res
|
package/package.json
CHANGED
package/webserver.mjs
CHANGED
|
@@ -14,46 +14,55 @@ function promisify(cb, fn) {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
const defaultOptions = { route: '/', default: "index.html", directory: "/" };
|
|
17
|
+
const defaultOptions = { route: '/public', default: "index.html", directory: "/" };
|
|
18
18
|
|
|
19
19
|
export function serveStatic(options, app, filestore) {
|
|
20
20
|
if (!options) {
|
|
21
21
|
options = defaultOptions;
|
|
22
22
|
}
|
|
23
|
-
let baseRoute = '
|
|
23
|
+
let baseRoute = '';
|
|
24
24
|
if (options.route && options.route !== undefined && options.route !== '/') {
|
|
25
|
-
baseRoute = options.route
|
|
25
|
+
baseRoute = options.route;
|
|
26
26
|
}
|
|
27
|
-
|
|
27
|
+
// match path and file
|
|
28
|
+
const regex = new RegExp(`^${baseRoute}(\/[\\w\/_-]*|[\\w\/_-]+\/)?([\\w.-]+)?(\\?[\\w=&%-]+)?$`);
|
|
29
|
+
// create public access for static files
|
|
28
30
|
app.auth(regex, (req, res, next) => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return res.status(404).send('Nothing here that matches ' + req.apiPath)
|
|
34
|
-
}
|
|
31
|
+
let filePath = decodeURIComponent(req.apiPath);
|
|
32
|
+
|
|
33
|
+
if (filePath == options.route) {
|
|
34
|
+
filePath = '/' + (options.default !== undefined ? options.default : 'index.html');
|
|
35
35
|
}
|
|
36
|
-
|
|
36
|
+
const type = mime.getType(filePath)
|
|
37
|
+
if (!type) {
|
|
38
|
+
next(`Static server: ${filePath} is not a valid file name`)
|
|
39
|
+
} else {
|
|
40
|
+
// ok to grant public access to file
|
|
41
|
+
next()
|
|
42
|
+
}
|
|
37
43
|
})
|
|
38
44
|
|
|
39
45
|
app.get(regex, async (req, res) => {
|
|
40
|
-
//console.log('apiPath', req.apiPath, options)
|
|
41
46
|
let filePath = decodeURIComponent(req.apiPath);
|
|
42
|
-
//console.log('apiPath', req.apiPath, options, filePath)
|
|
43
47
|
try {
|
|
44
|
-
|
|
48
|
+
// serve root '' or '/'
|
|
49
|
+
if (filePath == options.route) {
|
|
45
50
|
filePath = '/' + (options.default !== undefined ? options.default : 'index.html');
|
|
46
51
|
}
|
|
47
|
-
//
|
|
52
|
+
// remove route from file path
|
|
48
53
|
if (options.route && options.route !== undefined && options.route !== '/') {
|
|
49
54
|
filePath = filePath.replace(options.route, '');
|
|
50
55
|
}
|
|
51
|
-
//
|
|
56
|
+
// add directory filesystem path
|
|
52
57
|
if (options.directory && options.directory !== undefined && options.directory !== '/') {
|
|
53
58
|
filePath = options.directory + filePath;
|
|
54
59
|
}
|
|
60
|
+
// serve index.html for empty sub routes '/a/b/'
|
|
61
|
+
if(filePath.endsWith('/')) {
|
|
62
|
+
filePath += (options.default !== undefined ? options.default : 'index.html')
|
|
63
|
+
}
|
|
55
64
|
|
|
56
|
-
//
|
|
65
|
+
// get mime type
|
|
57
66
|
const type = mime.getType(filePath)
|
|
58
67
|
console.debug('Serve file', filePath, type)
|
|
59
68
|
const filestream = await filestore.getReadStream(filePath);
|