codehooks-js 1.3.12 → 1.3.14
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 +2 -3
- package/index.js +6 -2
- package/package.json +2 -3
- package/types/index.d.ts +7 -0
- package/webserver.mjs +29 -1
- package/workflow/engine.mjs +15 -13
- package/types/cronjob.d.mts +0 -2
- package/types/cronjob.d.mts.map +0 -1
package/README.md
CHANGED
|
@@ -317,6 +317,5 @@ await conn.set('key', 'value', { ttl: 3600000 }); // 1 hour TTL
|
|
|
317
317
|
5. **Real-time communication** via Server-Sent Events
|
|
318
318
|
6. **Workflow engine** for complex step-based applications
|
|
319
319
|
7. **Auto-generated CRUD APIs** with schema validation
|
|
320
|
-
8. **
|
|
321
|
-
9. **
|
|
322
|
-
10. **Datastore** with MongoDB-like query syntax, key-value operations, and queue management
|
|
320
|
+
8. **Datastore** with MongoDB-like query syntax, key-value operations, and queue management
|
|
321
|
+
9. **Security & Authentication** with JWKS support and custom auth middleware for secure API endpoints
|
package/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {agg} from './aggregation/index.mjs';
|
|
2
2
|
import {crudlify as crud} from './crudlify/index.mjs';
|
|
3
|
-
import {serveStatic as ws, render as renderView} from './webserver.mjs';
|
|
3
|
+
import {serveStatic as ws, render as renderView, internalFetch} from './webserver.mjs';
|
|
4
4
|
import Workflow from './workflow/engine.mjs';
|
|
5
5
|
|
|
6
6
|
function createRoute(str) {
|
|
@@ -116,9 +116,13 @@ class Codehooks {
|
|
|
116
116
|
res.status(200).json({...data});
|
|
117
117
|
})
|
|
118
118
|
}
|
|
119
|
+
|
|
120
|
+
internalFetch = (url, options = {}) => {
|
|
121
|
+
return internalFetch(url, options);
|
|
122
|
+
}
|
|
119
123
|
|
|
120
124
|
createWorkflow = (name, description, steps, options={}) => {
|
|
121
|
-
const wf = new Workflow(name, description, steps, options);
|
|
125
|
+
const wf = new Workflow(name, description, steps, options, Codehooks.getInstance());
|
|
122
126
|
wf.register(this);
|
|
123
127
|
return wf;
|
|
124
128
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codehooks-js",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.14",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Codehooks.io official library - provides express.JS like syntax",
|
|
6
6
|
"main": "index.js",
|
|
@@ -43,10 +43,9 @@
|
|
|
43
43
|
"mongodb"
|
|
44
44
|
],
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"cron-parser": "^4.7.1",
|
|
47
46
|
"lodash": "^4.17.21",
|
|
48
47
|
"mime": "^3.0.0",
|
|
49
|
-
"node-
|
|
48
|
+
"node-fetch": "^2.6.1"
|
|
50
49
|
},
|
|
51
50
|
"devDependencies": {
|
|
52
51
|
"@types/mime": "^3.0.4",
|
package/types/index.d.ts
CHANGED
|
@@ -1048,6 +1048,13 @@ export class Codehooks {
|
|
|
1048
1048
|
* @returns Promise with the registered workflow name
|
|
1049
1049
|
*/
|
|
1050
1050
|
registerWorkflow: (name: string, description: string, steps: WorkflowDefinition) => Promise<string>;
|
|
1051
|
+
/**
|
|
1052
|
+
* Fetch data from another Codehooks API
|
|
1053
|
+
* @param url - URL to fetch from, e.g. http://myapi-ffee.codehooks.io/dev/api/myroute
|
|
1054
|
+
* @param options - Fetch options
|
|
1055
|
+
* @returns Promise with the fetched data
|
|
1056
|
+
*/
|
|
1057
|
+
internalFetch: (url: string, options?: any) => Promise<any>;
|
|
1051
1058
|
}
|
|
1052
1059
|
declare const _coho: Codehooks;
|
|
1053
1060
|
|
package/webserver.mjs
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import mime from 'mime';
|
|
2
|
+
import fetch from 'node-fetch';
|
|
3
|
+
import { URL } from 'url';
|
|
2
4
|
|
|
3
5
|
// old and new style support
|
|
4
6
|
function promisify(cb, fn) {
|
|
@@ -222,4 +224,30 @@ async function handlebars(viewFile, data, settings, cb) {
|
|
|
222
224
|
console.error('Handle bars engine error:', err)
|
|
223
225
|
cb(err);
|
|
224
226
|
}
|
|
225
|
-
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Generic fetch wrapper that routes through apigateway-service
|
|
230
|
+
export const internalFetch = (url, options = {}) => {
|
|
231
|
+
// Parse the original URL to extract domain and path
|
|
232
|
+
|
|
233
|
+
const urlObj = new URL(url);
|
|
234
|
+
const originalHost = urlObj.host;
|
|
235
|
+
const pathAndQuery = urlObj.pathname + urlObj.search;
|
|
236
|
+
|
|
237
|
+
// Replace domain with apigateway-service
|
|
238
|
+
const proxyUrl = `http://apigateway-service:8888${pathAndQuery}`;
|
|
239
|
+
|
|
240
|
+
// Merge headers with original host
|
|
241
|
+
const headers = {
|
|
242
|
+
...options.headers,
|
|
243
|
+
'host': originalHost
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
// Create new options with updated headers
|
|
247
|
+
const newOptions = {
|
|
248
|
+
...options,
|
|
249
|
+
headers
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
return fetch(proxyUrl, newOptions);
|
|
253
|
+
};
|
package/workflow/engine.mjs
CHANGED
|
@@ -5,6 +5,7 @@ The engine manages step transitions, state persistence, and event handling for w
|
|
|
5
5
|
|
|
6
6
|
import { EventEmitter } from 'events';
|
|
7
7
|
|
|
8
|
+
|
|
8
9
|
/**
|
|
9
10
|
* Workflow class that manages step-based workflows
|
|
10
11
|
* @extends EventEmitter
|
|
@@ -32,7 +33,7 @@ class Workflow extends EventEmitter {
|
|
|
32
33
|
* @param {Object} definition - Object containing step definitions
|
|
33
34
|
* @param {Object} options - Optional configuration options
|
|
34
35
|
*/
|
|
35
|
-
constructor(name, description, definition, options = {}) {
|
|
36
|
+
constructor(name, description, definition, options = {}, app) {
|
|
36
37
|
super();
|
|
37
38
|
this.#definitions = new Map();
|
|
38
39
|
this.#name = name;
|
|
@@ -227,7 +228,7 @@ class Workflow extends EventEmitter {
|
|
|
227
228
|
async handleNextStep(stepsName, nextStep, newState, instanceId, options) {
|
|
228
229
|
|
|
229
230
|
// open the connection to the database
|
|
230
|
-
const connection = await
|
|
231
|
+
const connection = await DB.open();
|
|
231
232
|
|
|
232
233
|
// Handle single next step
|
|
233
234
|
this.emit('stepStarted', { workflowName: stepsName, step: nextStep, state: newState, instanceId });
|
|
@@ -439,7 +440,8 @@ class Workflow extends EventEmitter {
|
|
|
439
440
|
//res.end();
|
|
440
441
|
} catch (error) {
|
|
441
442
|
const { stepsName, goto, state, instanceId, options } = req.body.payload;
|
|
442
|
-
|
|
443
|
+
console.debug('DB in workflow 1', DB);
|
|
444
|
+
const connection = await DB.open();
|
|
443
445
|
await connection.updateOne(this.#collectionName,
|
|
444
446
|
{ _id: instanceId },
|
|
445
447
|
{ $set: { lastError: error, updatedAt: new Date().toISOString() } });
|
|
@@ -489,8 +491,8 @@ class Workflow extends EventEmitter {
|
|
|
489
491
|
reject(new Error('No start step defined in workflow'));
|
|
490
492
|
return;
|
|
491
493
|
}
|
|
492
|
-
|
|
493
|
-
const connection = await
|
|
494
|
+
console.debug('DB in workflow', DB);
|
|
495
|
+
const connection = await DB.open();
|
|
494
496
|
// Create a new workflow state in the database
|
|
495
497
|
const newState = await connection.insertOne(this.#collectionName,
|
|
496
498
|
{ ...initialState, nextStep: firstStepName, createdAt: new Date().toISOString(), workflowName: this.#name, stepCount: { } });
|
|
@@ -518,7 +520,7 @@ class Workflow extends EventEmitter {
|
|
|
518
520
|
*/
|
|
519
521
|
async updateState(instanceId, state, options={continue: true}) {
|
|
520
522
|
this.emit('stepsStateUpdating', { name: this.#name, instanceId, state });
|
|
521
|
-
const connection = await
|
|
523
|
+
const connection = await DB.open();
|
|
522
524
|
return new Promise(async (resolve, reject) => {
|
|
523
525
|
const doc = await connection.updateOne(this.#collectionName,
|
|
524
526
|
{ _id: instanceId },
|
|
@@ -537,7 +539,7 @@ class Workflow extends EventEmitter {
|
|
|
537
539
|
* @returns {Promise<void>}
|
|
538
540
|
*/
|
|
539
541
|
async setState(instanceId, { _id, state }) {
|
|
540
|
-
const connection = await
|
|
542
|
+
const connection = await DB.open();
|
|
541
543
|
await connection.replaceOne(this.#collectionName, { _id: _id }, { ...state });
|
|
542
544
|
}
|
|
543
545
|
|
|
@@ -548,7 +550,7 @@ class Workflow extends EventEmitter {
|
|
|
548
550
|
* @throws {Error} If steps instance not found
|
|
549
551
|
*/
|
|
550
552
|
async continue(instanceId, reset=false) {
|
|
551
|
-
const connection = await
|
|
553
|
+
const connection = await DB.open();
|
|
552
554
|
const state = await connection.findOne(this.#collectionName, { _id: instanceId });
|
|
553
555
|
if (!state) {
|
|
554
556
|
throw new Error(`No steps found with instanceId: ${instanceId}`);
|
|
@@ -586,7 +588,7 @@ class Workflow extends EventEmitter {
|
|
|
586
588
|
* @returns {Promise<Array<{qId: string}>>} Array of results containing queue IDs for continued workflows
|
|
587
589
|
*/
|
|
588
590
|
async continueAllTimedOut() {
|
|
589
|
-
const db = await
|
|
591
|
+
const db = await DB.open();
|
|
590
592
|
const timedOutWorkflows = await db.collection(this.#collectionName).find({nextStep: {$ne: null}}).toArray();
|
|
591
593
|
const now = new Date();
|
|
592
594
|
const results = [];
|
|
@@ -611,7 +613,7 @@ class Workflow extends EventEmitter {
|
|
|
611
613
|
*/
|
|
612
614
|
async getStepsStatus(id) {
|
|
613
615
|
return new Promise(async (resolve, reject) => {
|
|
614
|
-
const connection = await
|
|
616
|
+
const connection = await DB.open();
|
|
615
617
|
const state = await connection.findOne(this.#collectionName, { _id: id });
|
|
616
618
|
resolve(state);
|
|
617
619
|
});
|
|
@@ -624,7 +626,7 @@ class Workflow extends EventEmitter {
|
|
|
624
626
|
*/
|
|
625
627
|
async getInstances(filter) {
|
|
626
628
|
return new Promise(async (resolve, reject) => {
|
|
627
|
-
const connection = await
|
|
629
|
+
const connection = await DB.open();
|
|
628
630
|
const states = await connection.find(this.#collectionName, filter).toArray();
|
|
629
631
|
console.debug('listSteps', this.#collectionName, filter, states.length);
|
|
630
632
|
resolve(states);
|
|
@@ -639,7 +641,7 @@ class Workflow extends EventEmitter {
|
|
|
639
641
|
async cancelSteps(id) {
|
|
640
642
|
this.emit('cancelled', { id });
|
|
641
643
|
return new Promise(async (resolve, reject) => {
|
|
642
|
-
const connection = await
|
|
644
|
+
const connection = await DB.open();
|
|
643
645
|
const state = await connection.updateOne(this.#collectionName,
|
|
644
646
|
{ _id: id },
|
|
645
647
|
{ $set: { status: 'cancelled' } });
|
|
@@ -713,7 +715,7 @@ class Workflow extends EventEmitter {
|
|
|
713
715
|
* @returns {Promise<Array<Object>>} Array of workflow instances with timed out steps
|
|
714
716
|
*/
|
|
715
717
|
async findTimedOutSteps(filter = {}) {
|
|
716
|
-
const db = await
|
|
718
|
+
const db = await DB.open();
|
|
717
719
|
const workflows = await db.getMany(this.#collectionName, {"nextStep": {$ne: null}}).toArray();
|
|
718
720
|
if (workflows.length > 0) {
|
|
719
721
|
console.debug('TimedOutSteps', workflows.length);
|
package/types/cronjob.d.mts
DELETED
package/types/cronjob.d.mts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cronjob.d.mts","sourceRoot":"","sources":["../cronjob.mjs"],"names":[],"mappings":"AAMA,+DA6BC"}
|