mirror of https://github.com/node-red/node-red.git
Provide intellisense support for node.linkcall in monaco
parent
92e5594811
commit
72cdf3f1a0
|
|
@ -55,6 +55,7 @@ RED.editor.codeEditor.monaco = (function() {
|
|||
const type = "monaco";
|
||||
const monacoThemes = ["vs","vs-dark","hc-black"]; //TODO: consider setting hc-black autmatically based on acessability?
|
||||
let userSelectedTheme;
|
||||
let tsFuncData; //used to cache the original func.d.ts data for later use when updating linkcall targets
|
||||
|
||||
//TODO: get from externalModules.js For now this is enough for feature parity with ACE (and then some).
|
||||
const knownModules = {
|
||||
|
|
@ -143,6 +144,9 @@ RED.editor.codeEditor.monaco = (function() {
|
|||
var typePath = "types/" + libPath;
|
||||
$.get(typePath)
|
||||
.done(function(data) {
|
||||
if (libPath === "node-red/func.d.ts") {
|
||||
tsFuncData = data; //cache the original func.d.ts data for later use when updating linkcall targets
|
||||
}
|
||||
modulesCache[libPath] = data;
|
||||
if(!preloadOnly) {
|
||||
loadedLibs.JS[libModule] = monaco.languages.typescript.javascriptDefaults.addExtraLib(data, "file://types/" + libPackage + "/" + libModule + "/index.d.ts");
|
||||
|
|
@ -924,6 +928,62 @@ RED.editor.codeEditor.monaco = (function() {
|
|||
//check if extraLibs are to be loaded (e.g. fs or os)
|
||||
refreshModuleLibs(editorOptions.extraLibs)
|
||||
|
||||
// update func.d.ts definitions for up-to-date link-in target names in the node.linkcall() definition
|
||||
if (tsFuncData && options.node && options.node.type === 'function') {
|
||||
const getUpdatedLinkcallDefs = () => {
|
||||
const linkInNodes = RED.nodes.filterNodes({type:'link in'})
|
||||
const viableLinkTargets = []
|
||||
for (const target of linkInNodes) {
|
||||
// links on same flow/subflow as caller node are valid targets
|
||||
// however links inside a (different) subflow are not valid targets.
|
||||
if (target.z === options.node.z || !RED.nodes.subflow(target.z)) {
|
||||
viableLinkTargets.push(target)
|
||||
}
|
||||
}
|
||||
const targetsByName = [...new Set(viableLinkTargets.map(node => node.name || '').filter(name => name.length > 0))].map(s => JSON.stringify(s));
|
||||
const targetsById = [...new Set(viableLinkTargets.map(node => node.id))].map(s => JSON.stringify(s));
|
||||
const targets = [...targetsByName, ...targetsById].filter(s => s && s.length > 0).join("|") || 'string';
|
||||
return `
|
||||
// #region:linkcall
|
||||
/**
|
||||
* Utility function to call, a reusable flow defined as a subroutine (link-in ~ <nodes> ~ link-out).
|
||||
* When the \`linkcall\` function resolves, it returns the \`msg\` object returned by the link-out
|
||||
* (return) node of the subroutine.
|
||||
*
|
||||
* @param {string} target - the name or ID of the target link-in subroutine to call
|
||||
* @param {Object} msg - the message object to pass to the subroutine
|
||||
* @param {Object} [options] - call options
|
||||
* @param {number} [options.timeout=5000] - the maximum time to wait for a response (default: 5000ms)
|
||||
* @return {Promise<Object>} - resolves with the returned message
|
||||
*
|
||||
* @example Call "greeting-person" subroutine by name:
|
||||
* \`\`\`javascript
|
||||
* msg.payload = "Joe Bloggs";
|
||||
* const resultMsg = await node.linkcall("greeting-person", msg, {timeout: 10000});
|
||||
* msg.payload = resultMsg.payload; // payload = "Hello Joe Bloggs"
|
||||
* return msg; // return updated msg
|
||||
* \`\`\`
|
||||
*
|
||||
* @example Call "greeting-person" subroutine by node id:
|
||||
* \`\`\`javascript
|
||||
* msg.payload = "John Doe";
|
||||
* const result = await node.linkcall("a1b2c3d4e5f6", msg); // result.payload will be "Hello John Doe"
|
||||
* return result; // return new result object
|
||||
* \`\`\`
|
||||
*/
|
||||
static linkcall(target: ${targets}, msg: object, options?: { timeout?: number; [key: string]: any }): Promise<object>;
|
||||
// #endregion:linkcall
|
||||
`
|
||||
}
|
||||
const newDefs = getUpdatedLinkcallDefs();
|
||||
data = tsFuncData.replace(/\/\/ #region:linkcall[\s\S]*?\/\/ #endregion:linkcall/g, newDefs);
|
||||
if (loadedLibs.JS.func) {
|
||||
loadedLibs.JS.func.dispose();
|
||||
loadedLibs.JS.func = null;
|
||||
}
|
||||
loadedLibs.JS.func = monaco.languages.typescript.javascriptDefaults.addExtraLib(data, 'file://types/node-red/func/index.d.ts');
|
||||
}
|
||||
|
||||
function refreshModuleLibs(extraModuleLibs) {
|
||||
var defs = [];
|
||||
var imports = [];
|
||||
|
|
|
|||
|
|
@ -483,9 +483,15 @@
|
|||
}
|
||||
});
|
||||
|
||||
var buildEditor = function(id, stateId, focus, value, defaultValue, extraLibs, offset) {
|
||||
var editor = RED.editor.createEditor({
|
||||
const buildEditor = function(id, node, focus, value, defaultValue, extraLibs, offset) {
|
||||
const stateId = `${node.id}/${id}`;
|
||||
const editor = RED.editor.createEditor({
|
||||
id: id,
|
||||
node: {
|
||||
id: node.id,
|
||||
type: node.type,
|
||||
z: node.z
|
||||
},
|
||||
mode: 'ace/mode/nrjavascript',
|
||||
value: value || defaultValue || "",
|
||||
stateId: stateId,
|
||||
|
|
@ -512,9 +518,9 @@
|
|||
editor.__stateId = stateId;
|
||||
return editor;
|
||||
}
|
||||
this.initEditor = buildEditor('node-input-init-editor', this.id + "/" + "initEditor", false, $("#node-input-initialize").val(), RED._("node-red:function.text.initialize"), undefined, 0);
|
||||
this.editor = buildEditor('node-input-func-editor', this.id + "/" + "editor", true, $("#node-input-func").val(), undefined, that.libs || [], undefined, -1);
|
||||
this.finalizeEditor = buildEditor('node-input-finalize-editor', this.id + "/" + "finalizeEditor", false, $("#node-input-finalize").val(), RED._("node-red:function.text.finalize"), undefined, 0);
|
||||
this.initEditor = buildEditor('node-input-init-editor', this, false, $("#node-input-initialize").val(), RED._("node-red:function.text.initialize"), undefined, 0);
|
||||
this.editor = buildEditor('node-input-func-editor', this, true, $("#node-input-func").val(), undefined, that.libs || [], undefined, -1);
|
||||
this.finalizeEditor = buildEditor('node-input-finalize-editor', this, false, $("#node-input-finalize").val(), RED._("node-red:function.text.finalize"), undefined, 0);
|
||||
|
||||
RED.library.create({
|
||||
url:"functions", // where to get the data from
|
||||
|
|
|
|||
Loading…
Reference in New Issue