From 12253e23b5aa610cd0cacca8beeecc387ca3551e Mon Sep 17 00:00:00 2001 From: Steve-Mcl Date: Thu, 10 Jun 2021 21:18:29 +0100 Subject: [PATCH 1/9] Add setReadOnly support --- .../editor-client/src/js/ui/editors/code-editors/monaco.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js index 2decabc52..92311cd09 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js @@ -990,6 +990,10 @@ RED.editor.codeEditor.monaco = (function() { _executeEdits(this,[op]); } + ed.setReadOnly = function setReadOnly(readOnly) { + ed.updateOptions({ readOnly: readOnly }) + } + ed.session.replace = function replace(range, text) { var op = { range: range, text: text, forceMoveMarkers: true }; _executeEdits(this,[op]); From 7d24e5b2796ff85783aa4d6799cd5f598908b165 Mon Sep 17 00:00:00 2001 From: Steve-Mcl Date: Fri, 11 Jun 2021 08:01:38 +0100 Subject: [PATCH 2/9] node.status snippet enums for fill and shape --- .../editor-client/src/js/ui/editors/code-editors/monaco.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js index 92311cd09..9b95c7178 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js @@ -563,7 +563,7 @@ RED.editor.codeEditor.monaco = (function() { createMonacoCompletionItem("node.send", 'node.send(${1:msg});','async send a msg to the next node',range), createMonacoCompletionItem("node.send (multiple)", 'var ${1:msg1} = {payload:${2:1}};\nvar ${3:msg2} = {payload:${4:2}};\nnode.send([[${1:msg1}, ${3:msg2}]]);','send 1 or more messages out of 1 output',range), createMonacoCompletionItem("node.send (multiple outputs)", 'var ${1:msg1} = {payload:${2:1}};\nvar ${3:msg2} = {payload:${4:2}};\nnode.send([${1:msg1}, ${3:msg2}]);','send more than 1 message out of multiple outputs',range), - createMonacoCompletionItem("node.status", 'node.status({fill:"${1:red}",shape:"${2:ring}",text:"${3:error}"});','Set the status icon and text underneath the function node',range), + createMonacoCompletionItem("node.status", 'node.status({fill:"${1|red,green,yellow,blue,grey|}",shape:"${2|ring,dot|}",text:"${3:message}"});','Set the status icon and text underneath the function node',range), createMonacoCompletionItem("get (node context)", 'context.get("${1:name}");','Get a value from node context',range), createMonacoCompletionItem("set (node context)", 'context.set("${1:name}", ${1:value});','Set a value in node context',range), createMonacoCompletionItem("get (flow context)", 'flow.get("${1:name}");','Get a value from flow context',range), From aa6ec60c3479a850ca2d921d0cd33c22db9b16b7 Mon Sep 17 00:00:00 2001 From: Steve-Mcl Date: Fri, 11 Jun 2021 18:44:37 +0100 Subject: [PATCH 3/9] fix up issues with function node types - node.status add overload - remove examples as they dont render correctly - correct Number and Object types to number and object --- .../src/types/node-red/func.d.ts | 37 ++++++------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/types/node-red/func.d.ts b/packages/node_modules/@node-red/editor-client/src/types/node-red/func.d.ts index ab120318e..3c3ee7849 100644 --- a/packages/node_modules/@node-red/editor-client/src/types/node-red/func.d.ts +++ b/packages/node_modules/@node-red/editor-client/src/types/node-red/func.d.ts @@ -27,7 +27,7 @@ interface NodeStatus { /** The shape property can be: ring or dot */ shape?: string, /** The text to display */ - text?: string + text?: string|boolean|number } declare class node { @@ -35,48 +35,33 @@ declare class node { * Send 1 or more messages asynchronously * @param {object | object[]} msg The msg object * @param {Boolean} [clone=true] Flag to indicate the `msg` should be cloned. Default = `true` - * @example Send 1 msg to output 1 - * ```javascript - * node.send({ payload: "a" }); - * ``` - * @example Send 2 msg to 2 outputs - * ```javascript - * node.send([{ payload: "output1" }, { payload: "output2" }]); - * ``` - * @example Send 3 msg to output 1 - * ```javascript - * node.send([[{ payload: 1 }, { payload: 2 }, { payload: 3 }]]); - * ``` * @see node-red documentation [writing-functions: sending messages asynchronously](https://nodered.org/docs/user-guide/writing-functions#sending-messages-asynchronously) */ - static send(msg:object, clone?:Boolean); + static send(msg:object|object[], clone?:Boolean): void; /** Inform runtime this instance has completed its operation */ static done(); /** Send an error to the console and debug side bar. Include `msg` in the 2nd parameter to trigger the catch node. */ static error(err:string|Error, msg?:object); /** Log a warn message to the console and debug sidebar */ - static warn(warning:string|Object); + static warn(warning:string|object); /** Log an info message to the console (not sent to sidebar)' */ - static log(info:string|Object); - /** Set the status icon and text underneath the node. + static log(info:string|object); + /** Sets the status icon and text underneath the node. * @param {NodeStatus} status - The status object `{fill, shape, text}` - * @example clear node status - * ```javascript - * node.status({}); - * ``` - * @example set node status to red ring with text - * ```javascript - * node.status({fill:"red",shape:"ring",text:"error"}) - * ``` * @see node-red documentation [writing-functions: adding-status](https://nodered.org/docs/user-guide/writing-functions#adding-status) */ static status(status:NodeStatus); + /** Sets the status text underneath the node. + * @param {string} status - The status to display + * @see node-red documentation [writing-functions: adding-status](https://nodered.org/docs/user-guide/writing-functions#adding-status) + */ + static status(status:string|boolean|number); /** the id of this node */ public readonly id:string; /** the name of this node */ public readonly name:string; /** the number of outputs of this node */ - public readonly outputCount:Number; + public readonly outputCount:number; } declare class context { /** Get a value from context */ From 46d17c331481fac0787a57c3a7eaf7978291b7ff Mon Sep 17 00:00:00 2001 From: Steve-Mcl Date: Tue, 15 Jun 2021 21:01:33 +0100 Subject: [PATCH 4/9] update code comments --- .../node_modules/@node-red/editor-client/src/js/ui/editor.js | 1 - .../editor-client/src/js/ui/editors/code-editors/monaco.js | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js index 98b3dd450..2aea8adac 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js @@ -2776,7 +2776,6 @@ var buildingEditDialog = false; $("#node-dialog-cancel").trigger("click"); $("#node-config-dialog-cancel").trigger("click"); }); - //console.log("packages/node_modules/@node-red/editor-client/src/js/ui/editor.js ? init()") //TODO: Remove RED.editor.codeEditor.init(); }, edit: showEditDialog, diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js index 9b95c7178..3c221df4e 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js @@ -25,6 +25,7 @@ function .selection.getRange(); property .session //the editor object function .session.insert = function(position, text) + function .setReadOnly(readOnly) property .renderer = {}; function .renderer.updateFull() function setMode(mode, cb) From a9cf34ab56f0c9707605502c06afa147d58f1202 Mon Sep 17 00:00:00 2001 From: Steve-Mcl Date: Tue, 15 Jun 2021 21:02:30 +0100 Subject: [PATCH 5/9] prevent IE script error - even though monaco does not work in EI, scripts must not fail to load --- .../editor-client/src/js/ui/editors/code-editors/monaco.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js index 3c221df4e..6d31ecd59 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js @@ -121,7 +121,7 @@ RED.editor.codeEditor.monaco = (function() { const def = modulesCache[libPath]; if( def ) { if(!preloadOnly) { - loadedLibs.JS[libModule] = monaco.languages.typescript.javascriptDefaults.addExtraLib(def, `file://types/${libPackage}/${libModule}/index.d.ts`); + loadedLibs.JS[libModule] = monaco.languages.typescript.javascriptDefaults.addExtraLib(def, "file://types/" + libPackage + "/" + libModule + "/index.d.ts"); } if(cb) { setTimeout(function() { @@ -134,7 +134,7 @@ RED.editor.codeEditor.monaco = (function() { .done(function(data) { modulesCache[libPath] = data; if(!preloadOnly) { - loadedLibs.JS[libModule] = monaco.languages.typescript.javascriptDefaults.addExtraLib(data, `file://types/${libPackage}/${libModule}/index.d.ts`); + loadedLibs.JS[libModule] = monaco.languages.typescript.javascriptDefaults.addExtraLib(data, "file://types/" + libPackage + "/" + libModule + "/index.d.ts"); } if(cb) { cb(null, _module) } }) @@ -882,7 +882,8 @@ RED.editor.codeEditor.monaco = (function() { if(!extraModuleLibs || extraModuleLibs.length == 0) { loadedLibs.JS[id] = monaco.languages.typescript.javascriptDefaults.addExtraLib(" ", file); } else { - var loadList = [...extraModuleLibs]; + var loadList = []; + Array.prototype.push.apply(loadList, extraModuleLibs);//Use this instead of spread operator to prevent IE syntax error var loadExtraModules = {}; for (let index = 0; index < extraModuleLibs.length; index++) { const lib = extraModuleLibs[index]; From 1a73a271028bbee6eee2cd8d60deb0f8d250d911 Mon Sep 17 00:00:00 2001 From: Steve-Mcl Date: Tue, 15 Jun 2021 23:15:54 +0100 Subject: [PATCH 6/9] add diagnosticCodesToIgnore 2345 - handles issue with Intl.DateTimeFormat when `options` is a variable --- .../editor-client/src/js/ui/editors/code-editors/monaco.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js index 6d31ecd59..1ed109c5d 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js @@ -667,6 +667,7 @@ RED.editor.codeEditor.monaco = (function() { 2307, //Cannot find module 'xxx' or its corresponding type declarations 2322, //Type 'unknown' is not assignable to type 'string' 2339, //property does not exist on + 2345, //Argument of type xxx is not assignable to parameter of type 'DateTimeFormatOptions' 7043, //i forget what this one is, 80001, //Convert to ES6 module 80004, //JSDoc types may be moved to TypeScript types. From c90850264424ba7216ee96022205a6eda7eb4298 Mon Sep 17 00:00:00 2001 From: Steve-Mcl Date: Wed, 16 Jun 2021 22:36:00 +0100 Subject: [PATCH 7/9] add 2 ace compatible functions - clearSelection - blocky node - selectAll - obvious addition --- .../src/js/ui/editors/code-editors/monaco.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js index 1ed109c5d..d793595f8 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js @@ -31,6 +31,8 @@ function setMode(mode, cb) function getRange(); function replace(range, text) + function selectAll + function clearSelection function getSelectedText() function destroy() function resize() @@ -1013,11 +1015,20 @@ RED.editor.codeEditor.monaco = (function() { } } + ed.selectAll = function selectAll() { + const range = ed.getModel().getFullModelRange(); + ed.setSelection(range); + } + + ed.clearSelection = function clearSelection() { + ed.setPosition({column:1,lineNumber:1}); + } + ed.getSelectedText = function getSelectedText() { return ed.getModel().getValueInRange(ed.getSelection()); } - ed.insertSnippet = function editer_insertSnippet(s) { + ed.insertSnippet = function insertSnippet(s) { //https://github.com/microsoft/monaco-editor/issues/1112#issuecomment-429580604 //no great way of triggering snippets! let contribution = ed.getContribution("snippetController2"); From 0a8f7085f3c2a4d15dcf06b98854b182f7f0734e Mon Sep 17 00:00:00 2001 From: Steve-Mcl Date: Thu, 17 Jun 2021 08:44:44 +0100 Subject: [PATCH 8/9] allow static private field to have initializer --- .../editor-client/src/js/ui/editors/code-editors/monaco.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js index d793595f8..b2680d0c5 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js @@ -648,6 +648,7 @@ RED.editor.codeEditor.monaco = (function() { strictPropertyInitialization: true, strictFunctionTypes: true, strictBindCallApply: true, + useDefineForClassFields: true,//permit class static fields with private name to have initializer moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs, module: monaco.languages.typescript.ModuleKind.CommonJS, typeRoots: ["types"], From 3f27dc89d8de478acb3ecd3882d5addfb1086304 Mon Sep 17 00:00:00 2001 From: Steve-Mcl Date: Wed, 23 Jun 2021 22:27:13 +0100 Subject: [PATCH 9/9] Add overloads for context/flow/global set/get/keys --- .../src/types/node-red/func.d.ts | 207 ++++++++++++++++-- 1 file changed, 190 insertions(+), 17 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/types/node-red/func.d.ts b/packages/node_modules/@node-red/editor-client/src/types/node-red/func.d.ts index 3c3ee7849..f2a1364c0 100644 --- a/packages/node_modules/@node-red/editor-client/src/types/node-red/func.d.ts +++ b/packages/node_modules/@node-red/editor-client/src/types/node-red/func.d.ts @@ -64,28 +64,201 @@ declare class node { public readonly outputCount:number; } declare class context { - /** Get a value from context */ - static get(name:string, store?:string); - /** Store a value in context */ - static set(name:string, value:any, store?:string); + /** + * Get one or multiple values from context (synchronous). + * @param name - Name of context variable + */ + static get(name: string | string[]); + /** + * Get one or multiple values from context (asynchronous). + * @param name - Name (or array of names) to get from context + * @param {function} callback - (optional) Callback function (`(err,value) => {}`) + */ + static get(name: string | string[], callback: Function); + /** + * Get one or multiple values from context (synchronous). + * @param name - Name (or array of names) to get from context + * @param store - Name of context store + */ + static get(name: string | string[], store: string); + /** + * Get one or multiple values from context (asynchronous). + * @param name - Name (or array of names) to get from context + * @param store - Name of context store + * @param {function} callback - (optional) Callback function (`(err,value) => {}`) + */ + static get(name: string | string[], store: string, callback: Function); + + + /** + * Set one or multiple values in context (synchronous). + * @param name - Name (or array of names) to set in context + * @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed. + */ + static set(name: string | string[], value?: any | any[]); + /** + * Set one or multiple values in context (asynchronous). + * @param name - Name (or array of names) to set in context + * @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed. + * @param callback - (optional) Callback function (`(err) => {}`) + */ + static set(name: string | string[], value?: any | any[], callback?: Function); + /** + * Set one or multiple values in context (synchronous). + * @param name - Name (or array of names) to set in context + * @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed. + * @param store - (optional) Name of context store + */ + static set(name: string | string[], value?: any | any[], store?: string); + /** + * Set one or multiple values in context (asynchronous). + * @param name - Name (or array of names) to set in context + * @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed. + * @param store - (optional) Name of context store + * @param callback - (optional) Callback function (`(err) => {}`) + */ + static set(name: string | string[], value?: any | any[], store?: string, callback?: Function); + /** Get an array of the keys in the context store */ - static keys(store?:string):Array ; + static keys(): Array; + /** Get an array of the keys in the context store */ + static keys(store: string): Array; + /** Get an array of the keys in the context store */ + static keys(callback: Function); + /** Get an array of the keys in the context store */ + static keys(store: string, callback: Function); } declare class flow { - /** Get a value from flow context */ - static get(name:string, store?:string); - /** Store a value in flow context */ - static set(name:string, value:any, store?:string); - /** Get an array of the keys in the flow context store */ - static keys(store?:string):Array ; + /** + * Get one or multiple values from context (synchronous). + * @param name - Name of context variable + */ + static get(name: string | string[]); + /** + * Get one or multiple values from context (asynchronous). + * @param name - Name (or array of names) to get from context + * @param {function} callback - (optional) Callback function (`(err,value) => {}`) + */ + static get(name: string | string[], callback: Function); + /** + * Get one or multiple values from context (synchronous). + * @param name - Name (or array of names) to get from context + * @param store - Name of context store + */ + static get(name: string | string[], store: string); + /** + * Get one or multiple values from context (asynchronous). + * @param name - Name (or array of names) to get from context + * @param store - Name of context store + * @param {function} callback - (optional) Callback function (`(err,value) => {}`) + */ + static get(name: string | string[], store: string, callback: Function); + + + /** + * Set one or multiple values in context (synchronous). + * @param name - Name (or array of names) to set in context + * @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed. + */ + static set(name: string | string[], value?: any | any[]); + /** + * Set one or multiple values in context (asynchronous). + * @param name - Name (or array of names) to set in context + * @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed. + * @param callback - (optional) Callback function (`(err) => {}`) + */ + static set(name: string | string[], value?: any | any[], callback?: Function); + /** + * Set one or multiple values in context (synchronous). + * @param name - Name (or array of names) to set in context + * @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed. + * @param store - (optional) Name of context store + */ + static set(name: string | string[], value?: any | any[], store?: string); + /** + * Set one or multiple values in context (asynchronous). + * @param name - Name (or array of names) to set in context + * @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed. + * @param store - (optional) Name of context store + * @param callback - (optional) Callback function (`(err) => {}`) + */ + static set(name: string | string[], value?: any | any[], store?: string, callback?: Function); + + /** Get an array of the keys in the context store */ + static keys(): Array; + /** Get an array of the keys in the context store */ + static keys(store: string): Array; + /** Get an array of the keys in the context store */ + static keys(callback: Function); + /** Get an array of the keys in the context store */ + static keys(store: string, callback: Function); } + +// @ts-ignore declare class global { - /** Get a value from global context */ - static get(name:string, store?:string); - /** Store a value in global context */ - static set(name:string, value:any, store?:string); - /** Get an array of the keys in the global context store */ - static keys(store?:string):Array ; + /** + * Get one or multiple values from context (synchronous). + * @param name - Name of context variable + */ + static get(name: string | string[]); + /** + * Get one or multiple values from context (asynchronous). + * @param name - Name (or array of names) to get from context + * @param {function} callback - (optional) Callback function (`(err,value) => {}`) + */ + static get(name: string | string[], callback: Function); + /** + * Get one or multiple values from context (synchronous). + * @param name - Name (or array of names) to get from context + * @param store - Name of context store + */ + static get(name: string | string[], store: string); + /** + * Get one or multiple values from context (asynchronous). + * @param name - Name (or array of names) to get from context + * @param store - Name of context store + * @param {function} callback - (optional) Callback function (`(err,value) => {}`) + */ + static get(name: string | string[], store: string, callback: Function); + + + /** + * Set one or multiple values in context (synchronous). + * @param name - Name (or array of names) to set in context + * @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed. + */ + static set(name: string | string[], value?: any | any[]); + /** + * Set one or multiple values in context (asynchronous). + * @param name - Name (or array of names) to set in context + * @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed. + * @param callback - (optional) Callback function (`(err) => {}`) + */ + static set(name: string | string[], value?: any | any[], callback?: Function); + /** + * Set one or multiple values in context (synchronous). + * @param name - Name (or array of names) to set in context + * @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed. + * @param store - (optional) Name of context store + */ + static set(name: string | string[], value?: any | any[], store?: string); + /** + * Set one or multiple values in context (asynchronous). + * @param name - Name (or array of names) to set in context + * @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed. + * @param store - (optional) Name of context store + * @param callback - (optional) Callback function (`(err) => {}`) + */ + static set(name: string | string[], value?: any | any[], store?: string, callback?: Function); + + /** Get an array of the keys in the context store */ + static keys(): Array; + /** Get an array of the keys in the context store */ + static keys(store: string): Array; + /** Get an array of the keys in the context store */ + static keys(callback: Function); + /** Get an array of the keys in the context store */ + static keys(store: string, callback: Function); } declare class env { /** Get an environment variable value */