codehooks-js 1.2.14 → 1.2.16

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.
@@ -52,15 +52,19 @@ export default async function crudlify(app, schema = {}, options = { schema: "yu
52
52
  // schema provider other than Yup?
53
53
  for (const property in schema) {
54
54
  //console.log(`${property}: ${schema[property].toString()}`);
55
- if (schema[property] !== undefined) {
56
- if (schema[property].parse) {
57
- _opt.schema = 'zod';
58
- } else if (schema[property].properties) {
59
- _opt.schema = 'json-schema';
55
+ try {
56
+ if (schema[property] !== undefined) {
57
+ if (schema[property].parse) {
58
+ _opt.schema = 'zod';
59
+ } else if (schema[property].properties) {
60
+ _opt.schema = 'json-schema';
61
+ }
62
+ } else {
63
+ console.error(`${property} is undefined`)
64
+ //schema[property] = null;
60
65
  }
61
- } else {
62
- console.error(`${property} is undefined`)
63
- //schema[property] = null;
66
+ } catch (error) {
67
+ console.error("Unknown schema validator", error.message)
64
68
  }
65
69
  }
66
70
 
@@ -137,7 +141,7 @@ async function createFunc(req, res) {
137
141
  }
138
142
  }
139
143
  } else {
140
- if (Object.keys(_schema).length === 0) {
144
+ if (_schema[collection] === null || Object.keys(_schema).length === 0) {
141
145
  console.debug("data", collection, document)
142
146
  // insert any collection name no schema definitions, anything goes
143
147
  try {
@@ -150,7 +154,7 @@ async function createFunc(req, res) {
150
154
  res.status(400).send(ex);
151
155
  }
152
156
  } else {
153
- console.error('schema for' ,collection, 'is not valid:', _schema[collection])
157
+ console.error('schema for' ,collection, 'is not found:', _schema[collection])
154
158
  return res.status(400).json({ "error": `Collection schema not found: ${collection}` });
155
159
  }
156
160
 
@@ -4,9 +4,9 @@ export const validate = (schema, document) => {
4
4
 
5
5
  return new Promise(async (resolve, reject) => {
6
6
  debug('Validate Yup', document)
7
- if (schema == null) {
7
+ if (schema === null || (schema && !schema.validate)) {
8
8
  debug('Null validator')
9
- resolve(document)
9
+ return resolve(document)
10
10
  }
11
11
  try {
12
12
  const valid = await schema.validate(document);
@@ -27,7 +27,7 @@ export const validate = (schema, document) => {
27
27
 
28
28
  export const cast = (schema, document) => {
29
29
  debug('Cast', document, schema)
30
- return schema.cast(document)
30
+ return schema.cast ? schema.cast(document) : document;
31
31
  }
32
32
 
33
33
  export const prepare = (schemas) => {
package/index.js CHANGED
@@ -1,9 +1,6 @@
1
1
  import {agg} from './aggregation/index.mjs';
2
2
  import {crudlify as crud} from './crudlify/index.mjs';
3
3
  import {serveStatic as ws, render as renderView} from './webserver.mjs';
4
- let cronjob = null;
5
- let coderun = null;
6
-
7
4
 
8
5
  function createRoute(str) {
9
6
  if(str instanceof RegExp) {
@@ -119,7 +116,7 @@ class Codehooks {
119
116
  })
120
117
  }
121
118
 
122
- init = (...hook) => {
119
+ init = (hook) => {
123
120
  const manifest = {
124
121
  workerhooks: this.workers,
125
122
  routehooks: this.routes,
@@ -127,7 +124,6 @@ class Codehooks {
127
124
  jobhooks: this.jobs,
128
125
  authhooks: this.auths,
129
126
  globalhooks: this.appmiddleware,
130
- useExpress: this.useExpress,
131
127
  settings: this.settings,
132
128
  realtime: this.realtime,
133
129
  app: this
@@ -140,56 +136,6 @@ class Codehooks {
140
136
  // alias
141
137
  start = this.init;
142
138
 
143
- useExpress = async (express, options) => {
144
- cronjob = import("./cronjob.mjs")
145
- coderun = import('./coderunner.mjs')
146
- const { datastore, space = '/dev' } = options;
147
- await datastore.connect();
148
- this.setDatastore(datastore);
149
-
150
- for (let key in this.auths) {
151
- const func = this.auth[key];
152
- console.error('Auth middleware not implemented:', key)
153
- }
154
-
155
- for (let key in this.appmiddleware) {
156
- const func = this.appmiddleware[key];
157
- if (func.path) {
158
- express.use(`${space}${func.path}`, func.func);
159
- } else {
160
- express.use(func);
161
- }
162
- }
163
-
164
- for (let key in this.routes) {
165
- const func = this.routes[key];
166
- const [method, route] = key.split(' ');
167
- switch (method) {
168
- case 'GET': express.get(`${space}${route}`, ...func); break;
169
- case 'PUT': express.put(`${space}${route}`, ...func); break;
170
- case 'POST': express.post(`${space}${route}`, ...func); break;
171
- case 'PATCH': express.patch(`${space}${route}`, ...func); break;
172
- case 'DELETE': express.delete(`${space}${route}`, ...func); break;
173
- case '*': express.all(`${space}${route}`, ...func); break;
174
- }
175
- }
176
-
177
- // apply jobs
178
- for (let key in this.jobs) {
179
- const func = this.jobs[key];
180
- const cron = key;
181
- cronjob(cron, func);
182
- }
183
-
184
- // apply queue workers
185
- for (let key in this.queues) {
186
- const func = this.queues[key];
187
- const topic = key;
188
- //console.debug('Apply queue', topic, func);
189
- this.datastore.setQueue(topic, func);
190
- }
191
- }
192
-
193
139
  setDatastore = (ds) => {
194
140
  this.datastore = ds;
195
141
  this.listeners.forEach(observer => observer(this))
@@ -205,9 +151,11 @@ class Codehooks {
205
151
  }
206
152
  }
207
153
  }
154
+
208
155
  addListener = (observer) => {
209
156
  this.listeners.push(observer);
210
157
  }
158
+
211
159
  static getInstance() {
212
160
  if (!this.instance) {
213
161
  this.instance = new Codehooks();
@@ -239,7 +187,6 @@ export const aggregation = agg;
239
187
  export const crudlify = crud;
240
188
  export const coho = _coho;
241
189
  export const app = _coho;
242
- export const coderunner = coderun;
243
190
 
244
191
  export const realtime = {
245
192
  createChannel: (path, ...hook) => {
package/package.json CHANGED
@@ -1,14 +1,12 @@
1
1
  {
2
2
  "name": "codehooks-js",
3
- "version": "1.2.14",
3
+ "version": "1.2.16",
4
4
  "type": "module",
5
5
  "description": "Codehooks.io official library - provides express.JS like syntax",
6
6
  "main": "index.js",
7
7
  "types": "./types",
8
8
  "files": [
9
9
  "index.js",
10
- "coderunner.mjs",
11
- "cronjob.mjs",
12
10
  "./aggregation/index.mjs",
13
11
  "./webserver.mjs",
14
12
  "./crudlify/index.mjs",
package/types/index.d.ts CHANGED
@@ -262,6 +262,34 @@ export type NoSQLAPI = {
262
262
  * - Remove multiple data objects in a collection in the current Datastore
263
263
  */
264
264
  removeMany: (query: object) => Promise<object>;
265
+ /**
266
+ * Validate database colletion data agains JSON-Schema
267
+ * @param schema JSON-schema
268
+ * @returns Promise with result
269
+ */
270
+ createSchema: (schema: object) => Promise<object>;
271
+ /**
272
+ * Validate database colletion data agains JSON-Schema
273
+ * @param schema JSON-schema
274
+ * @returns Promise with result
275
+ */
276
+ setSchema: (schema: object) => Promise<object>;
277
+ /**
278
+ * Remove JSON-schema for database collection
279
+ * @param collection string
280
+ * @returns Promise with result
281
+ */
282
+ removeSchema: () => Promise<object>;
283
+ /**
284
+ * Get JSON-schema for database collection
285
+ * @returns Promise with result
286
+ */
287
+ getSchema: () => Promise<object>;
288
+ /**
289
+ * Count database collection items
290
+ * @returns Promise result
291
+ */
292
+ count: () => Promise<object>;
265
293
  };
266
294
  /**
267
295
  * Database API
@@ -400,6 +428,37 @@ export type DatastoreAPI = {
400
428
  topic: string,
401
429
  options?: object
402
430
  ) => Promise<object>;
431
+ /**
432
+ * Validate database colletion data agains JSON-Schema
433
+ * @param collection string
434
+ * @param schema JSON-schema
435
+ * @returns Promise with result
436
+ */
437
+ createSchema: (collection: string, schema: object) => Promise<object>;
438
+ /**
439
+ * Validate database colletion data agains JSON-Schema
440
+ * @param collection string
441
+ * @param schema JSON-schema
442
+ * @returns Promise with result
443
+ */
444
+ setSchema: (collection: string, schema: object) => Promise<object>;
445
+ /**
446
+ * Remove JSON-schema for database collection
447
+ * @param collection string
448
+ * @returns Promise with result
449
+ */
450
+ removeSchema: (collection: string) => Promise<object>;
451
+ /**
452
+ * Get JSON-schema for database collection
453
+ * @param collection string
454
+ * @returns Promise with result
455
+ */
456
+ getSchema: (collection: string) => Promise<object>;
457
+ /**
458
+ * Count database collection items
459
+ * @returns Promise result
460
+ */
461
+ count: (collection: string) => Promise<object>;
403
462
  };
404
463
  /**
405
464
  * Persistent NoSql and Kev-Value datastore
@@ -476,26 +535,40 @@ export type httpResponse = {
476
535
  end: (data: string | object | void) => void;
477
536
  /**
478
537
  * - Send text|JSON data to client and end request
538
+ * @example
539
+ * res.end()
540
+ * res.status(404).end()
479
541
  */
480
542
  send: (data: string | object) => void;
481
543
  /**
482
544
  * - End request and send JSON data to client
545
+ * @example
546
+ * res.json({ user: 'tobi' })
547
+ * res.status(500).json({ error: 'message' })
483
548
  */
484
549
  json: (document: object) => any;
485
550
  /**
486
551
  * - Write stream data to the client response.
487
552
  * - Content-type must be set before any write operations
488
553
  * - set optional type to 'buffer' for binary write operations
554
+ * @example
555
+ * res.set('content-type', 'text/plain')
556
+ * res.write('line one')
557
+ * res.write('\n')
558
+ * res.write('line two')
559
+ * res.end()
489
560
  */
490
561
  write: (data: any, type?: string) => any;
491
562
  /**
492
563
  * - Set a response header value,
493
- * - e.g. res.set('Content-Type', 'text/html; charset=UTF-8');
564
+ * @example
565
+ * res.set('Content-Type', 'text/html; charset=UTF-8');
494
566
  */
495
567
  set: (header: string, value: string) => any;
496
568
  /**
497
569
  * - Set multiple response header values,
498
- * - e.g. res.headers({'Content-Type': 'text/html; charset=UTF-8','X-myheader': '123456890'});
570
+ * @example
571
+ * res.headers({'Content-Type': 'text/html; charset=UTF-8','X-myheader': '123456890'});
499
572
  */
500
573
  headers: (headers: object) => any;
501
574
  /**
@@ -513,14 +586,26 @@ export type httpResponse = {
513
586
  removeHeader: (header: string) => any;
514
587
  /**
515
588
  * - Return a HTTP response status code for a client request,
516
- * - e.g. res.status(401);
589
+ * @example
590
+ * res.status(401).end();
517
591
  */
518
592
  status: (code: number) => any;
519
593
  /**
520
594
  * - Render template with object data
521
- * - example: res.render('services', {title: "Services page"})
595
+ * @example
596
+ * res.render('services', {title: "Services page"})
522
597
  */
523
598
  render: (template: string, context: object) => void;
599
+ /**
600
+ * - Sets the response header to redirect client request
601
+ * @param statusCode - optional, set to 302 by default
602
+ * @param url
603
+ * @returns
604
+ * @example
605
+ * res.redirect('/assets/login.html'); // default status 302, Temporary
606
+ * res.redirect(301, '/home/correct.html'); // status code 301, Permanently
607
+ */
608
+ redirect: (statusCode: number | string, url?: string) => void;
524
609
  };
525
610
 
526
611
  export type nextFunction = (error?: string) => void;
@@ -785,7 +870,7 @@ declare class Codehooks {
785
870
  ) => void;
786
871
  /**
787
872
  * Add application worker function
788
- * @param {string} name a unique worker name
873
+ * @param {object} name a unique worker name or JSON configuration
789
874
  * @param {...function(httpRequest, httpResponse, function(string):void)} hook - callback function(s) with parameters (req, res, [next])
790
875
  * @example
791
876
  * app.worker('myworker', (data, job) => {
@@ -794,9 +879,16 @@ declare class Codehooks {
794
879
  * // do stuff with payload data
795
880
  * job.end()
796
881
  *})
882
+ * @example
883
+ * app.worker({name: 'myworker', workers: 5}, (data, job) => {
884
+ * const {body:{payload}} = data
885
+ * //console.debug('worker payload data', payload)
886
+ * // do stuff with payload data
887
+ * job.end()
888
+ *})
797
889
  */
798
890
  worker: (
799
- name: string,
891
+ name: string | object,
800
892
  ...hook: ((
801
893
  request: httpRequest,
802
894
  response: httpResponse,
@@ -840,7 +932,16 @@ declare class Codehooks {
840
932
 
841
933
  /**
842
934
  * Serve static file content from a source code diretory
843
- * @param {Object} options - {route: "/", default: "index.html", directory: "/static"}
935
+ * @param {Object} options -
936
+ * - options.route - API route to serve assets
937
+ * - options.directory - path to directory with assets/files
938
+ * - options.default - default file name if root is /
939
+ @param {...function(httpRequest, httpResponse, function(string):void)} hook - Optional middleware functions to be applied before resource is served
940
+ * @example
941
+ * app.static({route:'/static', directory: '/assets'}, (req, res, next) => {
942
+ * console.log("Serving a static resource", req.path);
943
+ * next();
944
+ * })
844
945
  * @returns void
845
946
  */
846
947
  static: (options: any,
package/coderunner.mjs DELETED
@@ -1,22 +0,0 @@
1
- export default function execAll(funcarr, context, callfuncs, nextfunc) {
2
- const runOne = (pos) => {
3
- (async function () {
4
- try {
5
- if (funcarr[pos] !== null && funcarr[pos] !== undefined) {
6
- await funcarr[pos](context, callfuncs, (nextparam) => {
7
- if (nextparam && nextfunc) {
8
- return nextfunc(nextparam)
9
- }
10
- runOne(pos + 1);
11
- });
12
- } else {
13
- if (nextfunc) nextfunc();
14
- }
15
- } catch (ex) {
16
- console.error("Unhandled Codehook function exception:", ex || ex, funcarr, pos);
17
- callfuncs.end("Unhandled Codehook exception:" + ex.message || ex);
18
- }
19
- })();
20
- }
21
- runOne(0);
22
- }
package/cronjob.mjs DELETED
@@ -1,36 +0,0 @@
1
- import crontab from 'node-cron';
2
- import cronparser from 'cron-parser';
3
- import execAll from './coderunner.mjs';
4
- const debug = console.debug;
5
-
6
-
7
- export default function run(cronexpr, theFunc) {
8
- //return console.log('Not implemented in standalone version')
9
- try {
10
- // verify cron expression
11
- cronparser.parseExpression(cronexpr);
12
- const newtimer = crontab.schedule(cronexpr, async () => {
13
- const theContext = {
14
- end: function (output) {
15
- if (output) console.log(output);
16
- return this;
17
- }
18
- };
19
- debug('tick', cronexpr, theFunc);
20
- try {
21
- if (Array.isArray(theFunc)) {
22
- await execAll(theFunc, {}, theContext);
23
- } else {
24
- await theFunc({}, theContext);
25
- }
26
- } catch (ex) {
27
- console.log("Cron err", ex.message)
28
- }
29
- });
30
- } catch (ex) {
31
- console.error("Something is fishy with the cron expression", `'${cronexpr}'`)
32
- if (argv.debug) console.error(ex.message)
33
- debug(ex)
34
- process.exit(1)
35
- }
36
- }