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 CHANGED
@@ -36,7 +36,7 @@ app.get('/myroute', async (req, res) => {
36
36
  app.static({directory: "/static"})
37
37
 
38
38
  // CRUD REST API for any collection
39
- app.crudlify()
39
+ app.crudlify({}, {prefix: "/"})
40
40
 
41
41
  // return app to serverless runtime engine
42
42
  export default app.init()
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codehooks-js",
3
- "version": "1.1.9",
3
+ "version": "1.1.10",
4
4
  "type": "module",
5
5
  "description": "Codehooks.io official library - provides express.JS like syntax",
6
6
  "main": "index.js",
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
- const regex = new RegExp(`^\\${baseRoute}(([\\w\\s.-]|%[0-9a-fA-F]{2})+\\/)*([\\w\\s.-]|%[0-9a-fA-F]{2})+(\\.(css|html|htm|js|ts|jpeg|jpg|png|svg))?$|^\\/$`);
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
- //console.log('Auth', req.apiPath, options.route)
30
- if (options.route && options.route !== undefined && options.route !== '/') {
31
- if (!req.apiPath.startsWith(options.route)) {
32
- console.error('Not serving', req.apiPath)
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
- next()
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
- if (filePath == '/') {
48
+ // serve root '' or '/'
49
+ if (filePath == options.route) {
45
50
  filePath = '/' + (options.default !== undefined ? options.default : 'index.html');
46
51
  }
47
- //console.log('f1', filePath)
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
- //console.log('f2', filePath)
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
- //console.log('f3', filePath)
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);