codehooks-js 1.1.9 → 1.1.10
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 +13 -9
- 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;
|
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);
|