@5minds/node-red-contrib-processcube 1.16.1-develop-136f5e-mh90amev → 1.16.1-feature-5e019f-mhojvcvu

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.
@@ -3,10 +3,10 @@ module.exports = function (RED) {
3
3
  RED.nodes.createNode(this, config);
4
4
  var node = this;
5
5
 
6
- node.on('input', function (msg) {
6
+ node.on('input', function (msg) {
7
7
  const flowNodeInstanceId = msg.flowNodeInstanceId;
8
8
  const etw_input_node_id = msg.etw_input_node_id;
9
-
9
+
10
10
  if (!etw_input_node_id) {
11
11
  node.error('Error: The message did not contain the required etw_input_node_id.');
12
12
  } else {
@@ -24,7 +24,7 @@ module.exports = function (RED) {
24
24
  if (msgError.code) {
25
25
  errorCode = msgError.code;
26
26
  errorMessage = msgError.message;
27
- }
27
+ }
28
28
  } else if (msg.errorCode) {
29
29
  errorCode = msg.errorCode;
30
30
  errorMessage = msg.errorMessage;
@@ -0,0 +1,123 @@
1
+ <script type="text/javascript">
2
+ RED.nodes.registerType('externaltask-inject', {
3
+ category: 'ProcessCube',
4
+ color: '#02AFD6',
5
+ defaults: {
6
+ name: { value: '' },
7
+ payloadType: { value: 'json' },
8
+ payload: { value: '{}' },
9
+ taskType: { value: 'json' },
10
+ task: { value: '{}' }
11
+ },
12
+ inputs: 0,
13
+ outputs: 1,
14
+ icon: 'inject.svg',
15
+ label: function () {
16
+ return this.name || 'externaltask-inject';
17
+ },
18
+ button: {
19
+ onclick: function() {
20
+ var node = this;
21
+
22
+ $.ajax({
23
+ type: "POST",
24
+ url: "externaltask-inject/trigger/" + node.id,
25
+ success: function(resp) {
26
+ RED.notify("Message injected", "success");
27
+ },
28
+ error: function(xhr, status, err) {
29
+ RED.notify("Error injecting message: " + err, "error");
30
+ }
31
+ });
32
+ }
33
+ },
34
+ oneditprepare: function () {
35
+ // Initialize the typed input for payload
36
+ $('#node-input-payload').typedInput({
37
+ default: 'json',
38
+ types: ['str', 'num', 'bool', 'json', 'jsonata', 'flow', 'global']
39
+ });
40
+ // Restore the saved type for payload from hidden input
41
+ var payloadType = $('#node-input-payloadType').val();
42
+ if (payloadType) {
43
+ $('#node-input-payload').typedInput('type', payloadType);
44
+ }
45
+
46
+ // Initialize the typed input for task
47
+ $('#node-input-task').typedInput({
48
+ default: 'json',
49
+ types: ['str', 'num', 'bool', 'json', 'jsonata', 'flow', 'global']
50
+ });
51
+ // Restore the saved type for task from hidden input
52
+ var taskType = $('#node-input-taskType').val();
53
+ if (taskType) {
54
+ $('#node-input-task').typedInput('type', taskType);
55
+ }
56
+ },
57
+ oneditsave: function () {
58
+ var payloadValue = $('#node-input-payload').typedInput('value');
59
+ var payloadType = $('#node-input-payload').typedInput('type');
60
+ this.payload = payloadValue;
61
+ this.payloadType = payloadType;
62
+ // Persist type to hidden input field
63
+ $('#node-input-payloadType').val(payloadType);
64
+
65
+ var taskValue = $('#node-input-task').typedInput('value');
66
+ var taskType = $('#node-input-task').typedInput('type');
67
+ this.task = taskValue;
68
+ this.taskType = taskType;
69
+ // Persist type to hidden input field
70
+ $('#node-input-taskType').val(taskType);
71
+ }
72
+ });
73
+ </script>
74
+
75
+ <script type="text/html" data-template-name="externaltask-inject">
76
+ <div class="form-row">
77
+ <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
78
+ <input type="text" id="node-input-name" placeholder="Name" />
79
+ </div>
80
+ <div class="form-row">
81
+ <label for="node-input-payload">msg.payload</label>
82
+ <input type="hidden" id="node-input-payloadType">
83
+ <input type="text" id="node-input-payload" style="width: 70%;">
84
+ </div>
85
+ <div class="form-row">
86
+ <label for="node-input-task">msg.task</label>
87
+ <input type="hidden" id="node-input-taskType">
88
+ <input type="text" id="node-input-task" style="width: 70%;">
89
+ </div>
90
+ </script>
91
+
92
+ <script type="text/markdown" data-help-name="externaltask-inject">
93
+ A lightweight alternative to the standard Node-RED inject node for testing external task workflows. Use this node to inject test messages directly into an external task workflow without needing a real external task from the ProcessCube engine.
94
+
95
+ This node is ideal for small-scale testing and debugging of external task workflows. For larger-scale testing with test cases or CI/CD integration, use the **externaltask-testing** node instead.
96
+
97
+ ## Features
98
+
99
+ - Injects messages with configurable payload and task metadata
100
+ - Automatically generates `flowNodeInstanceId` and `processInstanceId` if not provided
101
+ - Sets required fields for compatibility with externaltask-output and externaltask-error nodes
102
+ - Supports multiple value types (JSON, string, number, boolean, JSONata, flow/global context)
103
+
104
+ ## Configs
105
+
106
+ : name (string) : The name of the node
107
+ : payload (string | {}) : The payload to inject into the workflow
108
+ : task (string | {}) : The task object to inject
109
+
110
+ ## Outputs
111
+
112
+ : payload (string | {}) : The injected payload with metadata (flowNodeInstanceId, processInstanceId, task)
113
+ : task (object) : The injected task object
114
+ : flowNodeInstanceId (string) : Unique identifier for the external task
115
+ : processInstanceId (string) : Reference to the process instance
116
+ : etw_input_node_id (string) : Reference to the injecting node
117
+ : etw_started_at (string) : ISO timestamp of when the task was injected
118
+
119
+ ## References
120
+
121
+ - [The ProcessCube&copy; Developer Network](https://processcube.io) - All documentation for the ProcessCube&copy; platform
122
+ - [ProcessCube&copy; LowCode Integration](https://processcube.io/docs/node-red) - LowCode integration in ProcessCube&copy;
123
+ </script>
@@ -0,0 +1,98 @@
1
+ const { v4: uuidv4 } = require('uuid');
2
+ const EventEmitter = require('node:events');
3
+
4
+ module.exports = function (RED) {
5
+ function ExternalTaskInject(config) {
6
+ RED.nodes.createNode(this, config);
7
+ var node = this;
8
+ node.config = config;
9
+ node.eventEmitter = new EventEmitter();
10
+
11
+ node.on('input', function (msg, send, done) {
12
+ msg.flowNodeInstanceId = msg.flowNodeInstanceId ?? uuidv4();
13
+ msg.processInstanceId = msg.processInstanceId ?? uuidv4();
14
+
15
+ if (!msg.task) {
16
+ // Use configured task if available, otherwise create default
17
+ if (config.task) {
18
+ msg.task = config.task;
19
+ } else {
20
+ msg.task = {
21
+ flowNodeInstanceId: msg.flowNodeInstanceId,
22
+ processInstanceId: msg.processInstanceId,
23
+ task: {}
24
+ }
25
+ }
26
+ }
27
+ msg.etw_started_at = new Date().toISOString();
28
+ msg.etw_input_node_id = node.id;
29
+
30
+ send(msg);
31
+ if (done) done();
32
+ });
33
+
34
+ }
35
+
36
+ RED.nodes.registerType('externaltask-inject', ExternalTaskInject);
37
+
38
+ // Helper function to parse typed values
39
+ function parseTypedValue(value, type) {
40
+ switch(type) {
41
+ case 'str':
42
+ return value || '';
43
+ case 'num':
44
+ return Number(value) || 0;
45
+ case 'bool':
46
+ return value === 'true' || value === true;
47
+ case 'json':
48
+ try {
49
+ return JSON.parse(value || '{}');
50
+ } catch(parseErr) {
51
+ console.error("Invalid JSON: " + parseErr.message);
52
+ return {};
53
+ }
54
+ case 'jsonata':
55
+ // JSONata expressions would need to be evaluated in Node-RED context
56
+ // For now, treat as string
57
+ return value || '';
58
+ case 'flow':
59
+ case 'global':
60
+ // These are context references - store as string for now
61
+ return value || '';
62
+ default:
63
+ return value || '';
64
+ }
65
+ }
66
+
67
+ // HTTP endpoint to handle button clicks
68
+ RED.httpAdmin.post('/externaltask-inject/trigger/:id', function(req, res) {
69
+ var node = RED.nodes.getNode(req.params.id);
70
+ if (node !== null && typeof node !== 'undefined') {
71
+ try {
72
+ var payloadValue = node.config.payload;
73
+ var payloadType = node.config.payloadType || 'json';
74
+ var payloadData = parseTypedValue(payloadValue, payloadType);
75
+
76
+ var taskValue = node.config.task;
77
+ var taskType = node.config.taskType || 'json';
78
+ var taskData = parseTypedValue(taskValue, taskType);
79
+
80
+ // Create a message with the configured payload and task
81
+ var msg = {
82
+ payload: payloadData,
83
+ task: taskData,
84
+ _msgid: uuidv4()
85
+ };
86
+
87
+ // Trigger the node's input handler with the configured message
88
+ node.receive(msg);
89
+ res.sendStatus(200);
90
+ } catch(err) {
91
+ res.sendStatus(500);
92
+ node.error("Error injecting message: " + err.message);
93
+ }
94
+ } else {
95
+ res.sendStatus(404);
96
+ }
97
+ });
98
+ };
@@ -29,15 +29,15 @@ module.exports = function (RED) {
29
29
  }
30
30
 
31
31
  if (!options['lockDuration'] && (process.env.NODE_RED_ETW_LOCK_DURATION || process.env.NODERED_ETW_LOCK_DURATION)) {
32
- options['lockDuration'] = parseInt(process.env.NODE_RED_ETW_LOCK_DURATION) || parseInt(process.env.NODERED_ETW_LOCK_DURATION) || undefined;
32
+ options['lockDuration'] = parseInt(process.env.NODE_RED_ETW_LOCK_DURATION || process.env.NODERED_ETW_LOCK_DURATION) || undefined;
33
33
  }
34
34
 
35
35
  if (!options['longpollingTimeout']) {
36
- options['longpollingTimeout'] = parseInt(process.env.NODE_RED_ETW_LONGPOLLING_TIMEOUT) || parseInt(process.env.NODERED_ETW_LONGPOLLING_TIMEOUT) || undefined;
36
+ options['longpollingTimeout'] = parseInt(process.env.NODE_RED_ETW_LONGPOLLING_TIMEOUT || process.env.NODERED_ETW_LONGPOLLING_TIMEOUT) || undefined;
37
37
  }
38
38
 
39
39
  if (!options['idleTimeout']) {
40
- options['idleTimeout'] = parseInt(process.env.NODE_RED_ETW_IDLE_TIMEOUT) || parseInt(process.env.NODERED_ETW_IDLE_TIMEOUT) || undefined;
40
+ options['idleTimeout'] = parseInt(process.env.NODE_RED_ETW_IDLE_TIMEOUT || process.env.NODERED_ETW_IDLE_TIMEOUT) || undefined;
41
41
  }
42
42
 
43
43
  node._subscribed = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@5minds/node-red-contrib-processcube",
3
- "version": "1.16.1-develop-136f5e-mh90amev",
3
+ "version": "1.16.1-feature-5e019f-mhojvcvu",
4
4
  "license": "MIT",
5
5
  "description": "Node-RED nodes for ProcessCube",
6
6
  "scripts": {
@@ -39,6 +39,7 @@
39
39
  "DataobjectInstanceQuery": "dataobject-instance-query.js",
40
40
  "EndEventFinishedListener": "endevent-finished-listener.js",
41
41
  "externaltaskInput": "externaltask-input.js",
42
+ "externaltaskInject": "externaltask-inject.js",
42
43
  "externaltaskOutput": "externaltask-output.js",
43
44
  "externaltaskError": "externaltask-error.js",
44
45
  "externaltaskEventListener": "externaltask-event-listener.js",