@theotherwillembotha/node-red-plugincore 0.0.52 → 0.0.53

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 CHANGED
@@ -179,6 +179,7 @@ Templates bundle reusable UI fragments that compose into any node's editor panel
179
179
  | `TimerMetricTemplate` | Timer config node reference |
180
180
  | `WebhookTemplate` | Webhook server reference, path, auth, and reverse proxy config |
181
181
  | `UIHelperTemplate` | Global `PluginCore.dialog()` and `PluginCore.table()` UI factories (see below) |
182
+ | `ScriptEditorTemplate` | Global `PluginCore.createScriptEditor()` factory for Monaco-based script editors (see below) |
182
183
  | `SettingsTemplate` | General settings section |
183
184
  | `BasicTemplate` | Base styles shared by all nodes |
184
185
 
@@ -265,6 +266,58 @@ $container.append($table);
265
266
  | `plugincore-status-enabled` | Green | Enabled / active state |
266
267
  | `plugincore-status-disabled` | Red | Disabled / inactive state |
267
268
 
269
+ #### `PluginCore.createScriptEditor(elementId, template, initialValue)`
270
+
271
+ Including `ScriptEditorTemplate` in a node's `templates` list injects a Monaco-based script editor factory into the Node-RED editor page. It wraps the async Monaco initialisation boilerplate into a single call and returns a `{ getValue(), dispose() }` handle.
272
+
273
+ ```javascript
274
+ // In onIncludeEditPrepare:
275
+ let scriptTemplate = `
276
+ interface Message { [key: string]: any; }
277
+ async function(msg: Message) {
278
+ \${script}
279
+ }
280
+ `;
281
+
282
+ node.scriptEditor = PluginCore.createScriptEditor(
283
+ 'node-input-script-editor', // DOM id of the container element
284
+ scriptTemplate, // TypeScript context template
285
+ node.script || 'return true;' // initial value
286
+ );
287
+
288
+ // In onIncludeEditSave:
289
+ node.script = node.scriptEditor.getValue();
290
+ delete node.scriptEditor;
291
+
292
+ // In IncludeEditCancel:
293
+ node.scriptEditor.dispose();
294
+ delete node.scriptEditor;
295
+ ```
296
+
297
+ The `template` string provides the TypeScript context that the Monaco language service uses for diagnostics, completions, and hover info. Use `\${script}` as the placeholder for the user's code. The user only sees their code — the surrounding context is invisible to them but informs type checking.
298
+
299
+ **Returns:** `{ getValue(): string, dispose(): void }`
300
+
301
+ ---
302
+
303
+ > **Note — Handlebars escaping in node HTML files**
304
+ >
305
+ > Node HTML files (`.html` template files) are processed by Handlebars during the build. This means any `{{ }}` syntax in the HTML — including in JavaScript comments or JSDoc — will be interpreted as a Handlebars expression and produce unexpected output or an error.
306
+ >
307
+ > Escape curly braces with a backslash wherever they appear literally in the file:
308
+ >
309
+ > ```javascript
310
+ > // Wrong — Handlebars will try to evaluate this:
311
+ > // @returns {{ getValue(): string }}
312
+ >
313
+ > // Correct — escaped so Handlebars passes it through:
314
+ > // @returns \{{ getValue(): string \}}
315
+ > ```
316
+ >
317
+ > This applies anywhere in the HTML file: `<script>` blocks, inline styles, markdown documentation sections, and comments.
318
+
319
+ ---
320
+
268
321
  ### Registering nodes for generation
269
322
 
270
323
  Create a `GenerateNodes.ts` at the root of your `src/` directory. This is the composition root — register every service, template, and node, then call `.generate()` to emit the two Node-RED entry files (`Nodes.js` and `Plugins.js`).
@@ -24,6 +24,7 @@ new index_js_1.NodeGenerator("./src/core/")
24
24
  .registerTemplate(index_js_1.TimerMetricTemplate)
25
25
  .registerTemplate(index_js_2.WebhookTemplate)
26
26
  .registerTemplate(index_js_1.UIHelperTemplate)
27
+ .registerTemplate(index_js_1.ScriptEditorTemplate)
27
28
  // nodes
28
29
  .registerNode(DelegatedConfigReferenceNode_js_1.DelegatedConfigReferenceNode)
29
30
  .registerNode(index_js_1.ConsoleLoggerConfigNode)
@@ -0,0 +1,5 @@
1
+ import { Template, TemplateDescriptor } from "../../NodeConstructor";
2
+ export declare class ScriptEditorTemplate extends Template {
3
+ static getTemplateDescriptor(): TemplateDescriptor;
4
+ }
5
+ //# sourceMappingURL=ScriptEditorTemplate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScriptEditorTemplate.d.ts","sourceRoot":"","sources":["../../../../src/core/ui/template/ScriptEditorTemplate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAGpE,qBAAa,oBAAqB,SAAQ,QAAQ;WAEhC,qBAAqB,IAAI,kBAAkB;CAQ5D"}
@@ -0,0 +1,50 @@
1
+
2
+ <div template-section="onIncludeOnce">
3
+
4
+ <script src="resources/@theotherwillembotha/node-red-plugincore/editorLanguageExtension.js"></script>
5
+
6
+ <script type="text/javascript">
7
+
8
+ window.PluginCore = window.PluginCore || {};
9
+
10
+ /**
11
+ * PluginCore.createScriptEditor(elementId, template, initialValue)
12
+ *
13
+ * Creates a Monaco editor instance with TypeScript-aware diagnostics,
14
+ * completions, and hover info scoped to the provided type template.
15
+ *
16
+ * @param {string} elementId - DOM id of the container element.
17
+ * @param {string} template - TypeScript template string. Use `${script}`
18
+ * as the placeholder for the user's code.
19
+ * @param {string} initialValue - The starting content of the editor.
20
+ * @returns \{{ getValue(): string, dispose(): void \}}
21
+ */
22
+ PluginCore.createScriptEditor = function(elementId, template, initialValue) {
23
+ var editorInstance = null;
24
+ var currentValue = initialValue || '';
25
+
26
+ ScriptEditorLanguageManager.createLanguage(monaco, template).then(function(language) {
27
+ editorInstance = monaco.editor.create(document.getElementById(elementId), {
28
+ value: currentValue,
29
+ language: language.getName(),
30
+ automaticLayout: true,
31
+ wordBasedSuggestions: 'currentDocument',
32
+ });
33
+ });
34
+
35
+ return {
36
+ getValue: function() {
37
+ return editorInstance ? editorInstance.getValue() : currentValue;
38
+ },
39
+ dispose: function() {
40
+ if (editorInstance) {
41
+ editorInstance.dispose();
42
+ editorInstance = null;
43
+ }
44
+ }
45
+ };
46
+ };
47
+
48
+ </script>
49
+
50
+ </div>
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ScriptEditorTemplate = void 0;
4
+ const NodeConstructor_1 = require("../../NodeConstructor");
5
+ const NodeGenerator_1 = require("../../NodeGenerator");
6
+ class ScriptEditorTemplate extends NodeConstructor_1.Template {
7
+ static getTemplateDescriptor() {
8
+ return new NodeConstructor_1.TemplateDescriptor("script-editor", ScriptEditorTemplate, NodeGenerator_1.SourceUtility.getSourcePath("/build/", "/src/") + "ScriptEditorTemplate.html", []);
9
+ }
10
+ }
11
+ exports.ScriptEditorTemplate = ScriptEditorTemplate;
package/build/index.d.ts CHANGED
@@ -18,6 +18,7 @@ export * from "./core/metrics/template/TimerMetricTemplate";
18
18
  export * from "./core/tagging/service/NodeTypeService";
19
19
  export * from "./core/tagging/NodeDescriptionDecorator";
20
20
  export * from "./core/ui/template/UIHelperTemplate";
21
+ export * from "./core/ui/template/ScriptEditorTemplate";
21
22
  export * from "./core/other/node/DelegatedConfigReferenceNode";
22
23
  export * from "./core/other/service/InputService";
23
24
  export * from "./core/other/service/SettingsService";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AAGxD,cAAc,uCAAuC,CAAC;AACtD,cAAc,yCAAyC,CAAC;AACxD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,uCAAuC,CAAC;AACtD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,6CAA6C,CAAC;AAG5D,cAAc,wCAAwC,CAAC;AACvD,cAAc,yCAAyC,CAAC;AAGxD,cAAc,qCAAqC,CAAC;AAGpD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,mCAAmC,CAAC;AAClD,cAAc,sCAAsC,CAAC;AACrD,cAAc,qCAAqC,CAAC;AACpD,cAAc,wCAAwC,CAAC;AAGvD,cAAc,yCAAyC,CAAC;AACxD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,6CAA6C,CAAC;AAG5D,cAAc,gDAAgD,CAAC;AAG/D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AAGxD,cAAc,uCAAuC,CAAC;AACtD,cAAc,yCAAyC,CAAC;AACxD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,uCAAuC,CAAC;AACtD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,6CAA6C,CAAC;AAG5D,cAAc,wCAAwC,CAAC;AACvD,cAAc,yCAAyC,CAAC;AAGxD,cAAc,qCAAqC,CAAC;AACpD,cAAc,yCAAyC,CAAC;AAGxD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,mCAAmC,CAAC;AAClD,cAAc,sCAAsC,CAAC;AACrD,cAAc,qCAAqC,CAAC;AACpD,cAAc,wCAAwC,CAAC;AAGvD,cAAc,yCAAyC,CAAC;AACxD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,6CAA6C,CAAC;AAG5D,cAAc,gDAAgD,CAAC;AAG/D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC"}
package/build/index.js CHANGED
@@ -38,6 +38,7 @@ __exportStar(require("./core/tagging/service/NodeTypeService"), exports);
38
38
  __exportStar(require("./core/tagging/NodeDescriptionDecorator"), exports);
39
39
  // UI
40
40
  __exportStar(require("./core/ui/template/UIHelperTemplate"), exports);
41
+ __exportStar(require("./core/ui/template/ScriptEditorTemplate"), exports);
41
42
  // OTHER
42
43
  __exportStar(require("./core/other/node/DelegatedConfigReferenceNode"), exports);
43
44
  __exportStar(require("./core/other/service/InputService"), exports);
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=editorLanguageExtension.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editorLanguageExtension.d.ts","sourceRoot":"","sources":["../../src/resources/editorLanguageExtension.ts"],"names":[],"mappings":""}