node-red-contrib-typescript 1.0.3 → 1.0.5

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/helper.js CHANGED
@@ -217,6 +217,7 @@ function createScript(node, iniOpt, code) {
217
217
  var iniText = `
218
218
  (async function(__send__) {
219
219
  node.status({});
220
+ node.log(undefined);
220
221
  ${ts.transpile(code)}
221
222
  })();`;
222
223
  return new vm.Script(iniText, iniOpt);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-typescript",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "",
5
5
  "author": "kezziny",
6
6
  "license": "ISC",
@@ -64,7 +64,14 @@ module.exports = function(RED) {
64
64
  target = target.substring(1);
65
65
  }
66
66
  if (target.startsWith("./")) {
67
- target = path + target.substring(2);
67
+ if (node.config.name.indexOf("/") !== -1) {
68
+ let count = node.config.name.lastIndexOf("/") + 1;
69
+ let pathSuffix = node.config.name.substring(0, count);
70
+ target = path + pathSuffix + target.substring(2);
71
+ }
72
+ else {
73
+ target = path + target.substring(2);
74
+ }
68
75
  }
69
76
  if (target.endsWith(".pkg")) {
70
77
  target = target.substring(0, target.length - 4) + "/index";
@@ -115,8 +122,14 @@ module.exports = function(RED) {
115
122
  target = target.substring(1);
116
123
  }
117
124
  if (target.startsWith("./")) {
118
- target = path + target.substring(2);
119
- }
125
+ if (node.config.name.indexOf("/") !== -1) {
126
+ let count = node.config.name.lastIndexOf("/") + 1;
127
+ let pathSuffix = node.config.name.substring(0, count);
128
+ target = path + pathSuffix + target.substring(2);
129
+ }
130
+ else {
131
+ target = path + target.substring(2);
132
+ } }
120
133
  if (target.endsWith(".pkg")) {
121
134
  target = target.substring(0, target.length - 4) + "/index";
122
135
  }
@@ -164,4 +177,4 @@ module.exports = function(RED) {
164
177
  });
165
178
  }
166
179
  RED.nodes.registerType("typescript", TypescriptInstance);
167
- }
180
+ }
@@ -1 +0,0 @@
1
-
@@ -1,230 +0,0 @@
1
- var ts = require("./typescript.js");
2
- var util = require("util");
3
- var vm = require("vm");
4
-
5
- function sendResults(node,send,_msgid,msgs,cloneFirstMessage) {
6
- if (msgs == null) {
7
- return;
8
- } else if (!util.isArray(msgs)) {
9
- msgs = [msgs];
10
- }
11
- var msgCount = 0;
12
- for (var m=0; m<msgs.length; m++) {
13
- if (msgs[m]) {
14
- if (!util.isArray(msgs[m])) {
15
- msgs[m] = [msgs[m]];
16
- }
17
- for (var n=0; n < msgs[m].length; n++) {
18
- var msg = msgs[m][n];
19
- if (msg !== null && msg !== undefined) {
20
- if (typeof msg === 'object' && !Buffer.isBuffer(msg) && !util.isArray(msg)) {
21
- if (msgCount === 0 && cloneFirstMessage !== false) {
22
- msgs[m][n] = RED.util.cloneMessage(msgs[m][n]);
23
- msg = msgs[m][n];
24
- }
25
- msg._msgid = _msgid;
26
- msgCount++;
27
- } else {
28
- var type = typeof msg;
29
- if (type === 'object') {
30
- type = Buffer.isBuffer(msg)?'Buffer':(util.isArray(msg)?'Array':'Date');
31
- }
32
- node.error(RED._("function.error.non-message-returned",{ type: type }));
33
- }
34
- }
35
- }
36
- }
37
- }
38
- if (msgCount>0) {
39
- send(msgs);
40
- }
41
- }
42
-
43
- function createVMOpt(node, kind) {
44
- var opt = {
45
- filename: 'Function node'+kind+':'+node.id+(node.name?' ['+node.name+']':''), // filename for stack traces
46
- displayErrors: true
47
- // Using the following options causes node 4/6 to not include the line number
48
- // in the stack output. So don't use them.
49
- // lineOffset: -11, // line number offset to be used for stack traces
50
- // columnOffset: 0, // column number offset to be used for stack traces
51
- };
52
- return opt;
53
- }
54
-
55
- function sendDataToClient2(RED, node, data) {
56
- try {
57
- RED.comms.publish(
58
- "typescript-log-" + node.id,
59
- {
60
- id: node.id,
61
- data: data
62
- },
63
- true
64
- );
65
- }
66
- catch (e) {
67
- console.log(e);
68
- }
69
- }
70
-
71
- function createSandbox(RED, node) {
72
- node.outstandingTimers = [];
73
- node.outstandingIntervals = [];
74
-
75
- var sandbox = {
76
- exports: {},
77
- console:console,
78
- util:util,
79
- Buffer:Buffer,
80
- Date: Date,
81
- RED: {
82
- util: RED.util
83
- },
84
- node: {
85
- id: node.id,
86
- name: node.name,
87
- path: node._path,
88
- outputCount: node.outputs,
89
- log: (data) => sendDataToClient2(RED, node, data),
90
- error: function() {
91
- node.error.apply(node, arguments);
92
- },
93
- warn: function() {
94
- node.warn.apply(node, arguments);
95
- },
96
- debug: function() {
97
- node.debug.apply(node, arguments);
98
- },
99
- trace: function() {
100
- node.trace.apply(node, arguments);
101
- },
102
- send: function(send, id, msgs, cloneMsg) {
103
- sendResults(node, send, id, msgs, cloneMsg);
104
- },
105
- on: function() {
106
- node.on.apply(node, arguments);
107
- },
108
- status: function() {
109
- node.status.apply(node, arguments);
110
- },
111
- send: function(msg) {
112
- node.send(msg);
113
- }
114
- },
115
- context: {
116
- set: function() {
117
- node.context().set.apply(node,arguments);
118
- },
119
- get: function() {
120
- return node.context().get.apply(node,arguments);
121
- },
122
- keys: function() {
123
- return node.context().keys.apply(node,arguments);
124
- },
125
- get global() {
126
- return node.context().global;
127
- },
128
- get flow() {
129
- return node.context().flow;
130
- }
131
- },
132
- flow: {
133
- set: function() {
134
- node.context().flow.set.apply(node,arguments);
135
- },
136
- get: function() {
137
- return node.context().flow.get.apply(node,arguments);
138
- },
139
- keys: function() {
140
- return node.context().flow.keys.apply(node,arguments);
141
- }
142
- },
143
- global: {
144
- set: function() {
145
- node.context().global.set.apply(node,arguments);
146
- },
147
- get: function() {
148
- return node.context().global.get.apply(node,arguments);
149
- },
150
- keys: function() {
151
- return node.context().global.keys.apply(node,arguments);
152
- }
153
- },
154
- env: {
155
- get: function(envVar) {
156
- return RED.util.getSetting(node, envVar);
157
- }
158
- },
159
- setTimeout: function () {
160
- var func = arguments[0];
161
- var timerId;
162
- arguments[0] = function() {
163
- sandbox.clearTimeout(timerId);
164
- try {
165
- func.apply(node,arguments);
166
- } catch(err) {
167
- node.error(err,{});
168
- }
169
- };
170
- timerId = setTimeout.apply(node,arguments);
171
- node.outstandingTimers.push(timerId);
172
- return timerId;
173
- },
174
- clearTimeout: function(id) {
175
- clearTimeout(id);
176
- var index = node.outstandingTimers.indexOf(id);
177
- if (index > -1) {
178
- node.outstandingTimers.splice(index,1);
179
- }
180
- },
181
- setInterval: function() {
182
- var func = arguments[0];
183
- var timerId;
184
- arguments[0] = function() {
185
- try {
186
- func.apply(node,arguments);
187
- } catch(err) {
188
- node.error(err,{});
189
- }
190
- };
191
- timerId = setInterval.apply(node,arguments);
192
- node.outstandingIntervals.push(timerId);
193
- return timerId;
194
- },
195
- clearInterval: function(id) {
196
- clearInterval(id);
197
- var index = node.outstandingIntervals.indexOf(id);
198
- if (index > -1) {
199
- node.outstandingIntervals.splice(index,1);
200
- }
201
- }
202
- };
203
- if (util.hasOwnProperty('promisify')) {
204
- sandbox.setTimeout[util.promisify.custom] = function(after, value) {
205
- return new Promise(function(resolve, reject) {
206
- sandbox.setTimeout(function(){ resolve(value); }, after);
207
- });
208
- };
209
- sandbox.promisify = util.promisify;
210
- }
211
-
212
- return sandbox;
213
- }
214
-
215
- function createScript(node, iniOpt, code) {
216
- //console.log(ts.transpile(code));
217
- var iniText = `
218
- (async function(__send__) {
219
- node.status({});
220
- ${ts.transpile(code)}
221
- })();`;
222
- return new vm.Script(iniText, iniOpt);
223
- }
224
-
225
- module.exports = {
226
- createSandbox: createSandbox,
227
- createScript: createScript,
228
- createVMOpt: createVMOpt,
229
- transpile: ts.transpile
230
- };
@@ -1,12 +0,0 @@
1
- {
2
- "name": "node-red-contrib-typescript",
3
- "version": "1.0.1",
4
- "description": "",
5
- "author": "kezziny",
6
- "license": "ISC",
7
- "node-red" : {
8
- "nodes": {
9
- "instance": "src/instance/instance.js"
10
- }
11
- }
12
- }
@@ -1,271 +0,0 @@
1
- <script type="text/javascript">
2
- var typescriptRenderLog = function (id, data, node) {
3
- let $chart = document.getElementById("data-view-output-chart-" + id);
4
- if (!$chart) {
5
- const $container = document.getElementById(id)
6
- if (!$container) { return }
7
- const text = document.createElementNS("http://www.w3.org/2000/svg", 'text')
8
- text.setAttribute('id', `data-view-output-text-${id}`)
9
- text.setAttribute('x', `0`)
10
- text.setAttribute('y', `45`)
11
- text.setAttribute('text-anchor', `start`)
12
- $container.insertBefore(text, $container.lastChild.nextSibling);
13
- // Creat group
14
- const group = document.createElementNS("http://www.w3.org/2000/svg", 'g');
15
- group.setAttribute('id', `data-view-output-chart-${id}`);
16
- group.setAttribute('innerHTML', `data-view-output-chart-${id}`);
17
- $container.insertBefore(group, $container.lastChild.nextSibling);
18
- $chart = $container
19
- }
20
-
21
- let $text = document.getElementById(`data-view-output-text-${id}`);
22
- $text.textContent = ''
23
- let x = ``
24
- if (data === undefined) {
25
- x = "";
26
- } else if (typeof data == `object`) {
27
- x = JSON.stringify(data, null, ' ')
28
- } else {
29
- x = data + ''
30
- }
31
- var
32
- lines = x.split('\n'),
33
- tn,
34
- ts
35
-
36
- lines.forEach(function (value, index) {
37
- let countSpace = value.length - value.trim().length
38
- tn = document.createTextNode(value);
39
- ts = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
40
- ts.setAttribute('dy', "1.2em");
41
- ts.setAttribute('x', (countSpace * 10) + 10);
42
- ts.setAttribute('text-anchor', 'start');
43
- ts.setAttribute('fill', '#555');
44
- ts.setAttribute('stroke', 'transparent');
45
- ts.setAttribute('font-size', `11`)
46
- ts.appendChild(tn);
47
- $text.append(ts);
48
- });
49
- }
50
-
51
- function typescriptLogSubscriptionHandler(event, data) {
52
- console.log(data);
53
- if (data.hasOwnProperty("data")) {
54
- let node = RED.nodes.node(data.id);
55
- typescriptRenderLog(data.id, data.data, node);
56
- }
57
- }
58
-
59
- class TSEditor {
60
- constructor(node, path) {
61
- this.node = node;
62
-
63
- const mainModel = monaco.editor.createModel(
64
- node.code || "",
65
- 'typescript',
66
- window.monaco.Uri.parse('file://' + path)
67
- );
68
-
69
- this.editor = RED.editor.createEditor({
70
- id: "node-input-example-editor",
71
- mode: 'ace/mode/typescript',
72
- value: node.code || "",
73
- theme: "vs-dark",
74
- focus: true,
75
- model: mainModel,
76
- });
77
-
78
- window.monaco.editor.getModels()[0].dispose();
79
-
80
- window.monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
81
- "paths": {
82
- "/*": [
83
- "file:///*"
84
- ],
85
- "#*": [
86
- "file:///lib/*"
87
- ]
88
- },
89
- experimentalDecorators: true,
90
- moduleResolution: window.monaco.languages.typescript.ModuleResolutionKind.NodeJs,
91
- allowNonTsExtensions: true,
92
- module: monaco.languages.typescript.ModuleKind.ESNext,
93
- target: monaco.languages.typescript.ScriptTarget.ESNext
94
- });
95
- }
96
-
97
- recalculateGlobal(subflowId) {
98
- let nodes = [];
99
- let subflowNodes = [];
100
- let workspaces = [];
101
- let subflows = [];
102
-
103
- RED.nodes.eachWorkspace(item => workspaces.push(item));
104
- RED.nodes.eachSubflow(item => subflows.push(item));
105
- RED.nodes.eachNode(item => {
106
- if (item.type === "typescript")
107
- nodes.push(item);
108
- if (item.type.startsWith("subflow:"))
109
- subflowNodes.push(item);
110
- });
111
-
112
- function resolveFlow(id) {
113
- let imports = {};
114
- nodes
115
- .filter(node => node.z === id)
116
- .forEach(node => {
117
- imports[`/${encodeURIComponent(node.name)}.ts`] = node.code;
118
- });
119
- subflowNodes
120
- .filter(node => node.z === id)
121
- .forEach(node => {
122
- let subImports = resolveFlow(node.type.split(":")[1]);
123
- for (let key in subImports) {
124
- imports[`/${encodeURIComponent(node.name)}${key}`] = subImports[key];
125
- }
126
- });
127
- return imports;
128
- }
129
-
130
-
131
- let imports = {};
132
- workspaces.forEach(workspace => {
133
- let subImports = resolveFlow(workspace.id);
134
- for (let key in subImports) {
135
- if (key.indexOf("//") === -1)
136
- imports[`/${encodeURIComponent(workspace.label)}${key}`] = subImports[key];
137
- }
138
- });
139
-
140
- if (subflowId) {
141
- let subflow = subflows.find(s => s.id === subflowId);
142
- let subImports = resolveFlow(subflowId);
143
- for (let key in subImports) {
144
- if (key.indexOf("//") === -1)
145
- imports[`/subflow${key}`] = subImports[key];
146
- }
147
- }
148
-
149
- for (let key in imports) {
150
- window.monaco.languages.typescript.typescriptDefaults.addExtraLib(imports[key], "file://" + key);
151
- }
152
-
153
- window.monaco.languages.typescript.typescriptDefaults.addExtraLib(`
154
- let node = {
155
- error: (msg:any) => {},
156
- send: (msg:any) => {},
157
- on: (topic:"close"|"input", callback:any) => {},
158
- status: (status:{fill?:"red"|"yellow"|"green"|"blue"|"grey", shape?:"dot"|"ring", text?:string}) => {},
159
- log: (data:any) => {}
160
- };
161
- let flow = {
162
- get: (topic:string):any => {};
163
- set: (topic:string, value:any) => {};
164
- };
165
- let global = {
166
- get: (topic:string):any => {};
167
- set: (topic:string, value:any) => {};
168
- };
169
- let context = {
170
- get: (topic:string):any => {};
171
- set: (topic:string, value:any) => {};
172
- };
173
- let env = {
174
- get: (topic:string):any => {};
175
- set: (topic:string, value:any) => {};
176
- };
177
- `, 'global.d.ts'
178
- );
179
- }
180
-
181
- getCode() {
182
- return this.editor.getValue();
183
- }
184
-
185
- destroy() {
186
- this.editor.destroy();
187
- }
188
- }
189
- </script>
190
- <script type="text/javascript">
191
- RED.nodes.registerType('typescript',{
192
- category: 'function',
193
- color: '#3178c6',
194
- defaults: {
195
- name: {value:""},
196
- outputs:{value:1},
197
- code: {value:""},
198
- },
199
- inputs:1,
200
- outputs:1,
201
- icon: "function.svg",
202
- label: function () {
203
- RED.comms.unsubscribe('typescript-log-' + this.id, typescriptLogSubscriptionHandler);
204
- RED.comms.subscribe('typescript-log-' + this.id, typescriptLogSubscriptionHandler);
205
- return this.name || "typescript";
206
- },
207
- oneditprepare: function() {
208
- let path = "/__editor__.tsx";
209
-
210
- let workspaces = [];
211
- let subflows = [];
212
-
213
- RED.nodes.eachWorkspace(item => workspaces.push(item));
214
- RED.nodes.eachSubflow(item => subflows.push(item));
215
-
216
- let target = this;
217
- if (workspaces.some(wf => wf.id === target.z)) {
218
- target = workspaces.find(wf => wf.id === target.z);
219
- path = `/${target.label}${path}`;
220
- } else if (subflows.some(wf => wf.id === target.z)) {
221
- target = subflows.find(wf => wf.id === target.z);
222
- path = `/subflow${path}`;
223
- }
224
-
225
- this.view = {
226
- editor: new TSEditor(this, path),
227
- };
228
-
229
- this.view.editor.recalculateGlobal(path.startsWith("/subflow") ? this.z : null);
230
-
231
- $( "#node-input-outputs" ).spinner({
232
- min: 0,
233
- max: 500,
234
- change: function(event, ui) {
235
- var value = parseInt(this.value);
236
- value = isNaN(value) ? 1 : value;
237
- value = Math.max(value, parseInt($(this).attr("aria-valuemin")));
238
- value = Math.min(value, parseInt($(this).attr("aria-valuemax")));
239
- if (value !== this.value) { $(this).spinner("value", value); }
240
- }
241
- });
242
- },
243
- oneditsave: function() {
244
- this.code = this.view.editor.getCode();
245
- this.view.editor.destroy();
246
- delete this.view;
247
- },
248
- oneditcancel: function() {
249
- this.view.editor.destroy();
250
- delete this.view;
251
- }
252
- });
253
- </script>
254
-
255
- <script type="text/html" data-template-name="typescript">
256
- <div class="form-row">
257
- <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
258
- <input type="text" id="node-input-name" placeholder="Name">
259
- </div>
260
-
261
- <div class="form-row">
262
- <label for="node-input-outputs"><i class="fa fa-random"></i> <span data-i18n="function.label.outputs"></span></label>
263
- <input id="node-input-outputs" style="width: 60px;" value="1">
264
- </div>
265
-
266
- <div style="height: calc(100% - 68px); min-height:250px; width: 800px" class="node-text-editor" id="node-input-example-editor"></div>
267
- </script>
268
-
269
- <script type="text/html" data-help-name="typescript">
270
- <p>A simple node that converts the message payloads into all lower-case characters</p>
271
- </script>