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.
- package/crudlify/index.mjs +14 -10
- package/crudlify/lib/schema/yup/index.mjs +3 -3
- package/index.js +3 -56
- package/package.json +1 -3
- package/types/index.d.ts +108 -7
- package/coderunner.mjs +0 -22
- package/cronjob.mjs +0 -36
package/crudlify/index.mjs
CHANGED
|
@@ -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
|
-
|
|
56
|
-
if (schema[property]
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
}
|
|
62
|
-
console.error(
|
|
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
|
|
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
|
|
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 = (
|
|
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.
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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 {
|
|
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 -
|
|
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
|
-
}
|