Skip to content

Commit cf07c8e

Browse files
committed
chore(templates): update templates for dynamic node generation
1 parent 46b1e82 commit cf07c8e

8 files changed

Lines changed: 93 additions & 1 deletion

File tree

packages/node-red-builder/src/cli/utils.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ export function getTemplatesDir() {
3838
return path.resolve(import.meta.dir, '../../templates');
3939
}
4040

41+
/**
42+
* Escapes a string for use in a regular expression.
43+
*
44+
* @param {string} string
45+
* @returns {string}
46+
*/
47+
function escapeRegExp(string) {
48+
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
49+
}
50+
4151
/**
4252
* Copies a template file to a destination with variable replacements.
4353
*
@@ -59,7 +69,11 @@ export async function copyTemplate(srcRelativePath, destRelativePath, replacemen
5969
let content = await fs.readFile(srcPath, 'utf8');
6070

6171
for (const [key, value] of Object.entries(replacements)) {
62-
content = content.replace(new RegExp(key, 'g'), value);
72+
if (value === '') {
73+
const regex = new RegExp(`^.*${escapeRegExp(key)}.*(\\r?\\n|$)`, 'gm');
74+
content = content.replace(regex, '');
75+
} else
76+
content = content.replace(new RegExp(escapeRegExp(key), 'g'), value);
6377
}
6478

6579
await fs.writeFile(destPath, content, 'utf8');
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"__NODE_NAME__": {
3+
"label": {
4+
"name": "Name",
5+
"host": "Host",
6+
"port": "Port"
7+
},
8+
"placeholder": {
9+
"name": "My Config"
10+
}
11+
}
12+
}

packages/node-red-builder/templates/src/locales/en-US/node.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"__NODE_NAME__": {
33
"label": {
44
"name": "Name",
5+
"config": "Config",
56
"action": "Action",
67
"topic": "Topic"
78
},
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { BaseConfigNode, registerNode } from 'node-red-builder';
2+
/** @import { Node, NodeAPI, NodeDef } from 'node-red' */
3+
4+
/**
5+
* @typedef {object} __NODE_CLASS__Props
6+
* @property {string} name
7+
* @property {string} host
8+
* @property {number} port
9+
*/
10+
11+
/** @typedef {NodeDef & __NODE_CLASS__Props} __NODE_CLASS__Config */
12+
13+
/** @extends {BaseConfigNode<__NODE_CLASS__Config>} */
14+
export class __NODE_CLASS__ extends BaseConfigNode {
15+
/**
16+
* @param {Node} node
17+
* @param {__NODE_CLASS__Config} config
18+
* @param {NodeAPI} RED
19+
*/
20+
constructor(node, config, RED) {
21+
super(node, config, RED);
22+
}
23+
}
24+
25+
export default (/** @type {NodeAPI} */ RED) => registerNode(RED, '__PREFIX__-__NODE_NAME__', __NODE_CLASS__);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<div class="form-row">
2+
<label for="node-config-input-name">
3+
<i class="fa fa-tag"></i>
4+
<span data-i18n="__NODE_NAME__.label.name"></span>
5+
</label>
6+
<input type="text" id="node-config-input-name" data-i18n="[placeholder]__NODE_NAME__.placeholder.name" />
7+
</div>
8+
<div class="form-row">
9+
<label for="node-config-input-host">
10+
<i class="fa fa-globe"></i>
11+
<span data-i18n="__NODE_NAME__.label.host"></span>
12+
</label>
13+
<input type="text" id="node-config-input-host" placeholder="localhost" />
14+
</div>
15+
<div class="form-row">
16+
<label for="node-config-input-port">
17+
<i class="fa fa-random"></i>
18+
<span data-i18n="__NODE_NAME__.label.port"></span>
19+
</label>
20+
<input type="text" id="node-config-input-port" placeholder="8080" />
21+
</div>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/** @import { EditorRED } from 'node-red' */
2+
/** @import { EditorDefaults } from 'node-red-builder/ui' */
3+
/** @import { __NODE_CLASS__ } from './runtime.js' */
4+
5+
let /** @type {EditorRED} */ RED = /** @type {any} */ (window).RED;
6+
7+
RED.nodes.registerType('__PREFIX__-__NODE_NAME__', {
8+
category: 'config',
9+
/** @type {EditorDefaults<__NODE_CLASS__['config']>} */ defaults: {
10+
name: { value: '' },
11+
host: { value: 'localhost', required: true },
12+
port: { value: 8080, required: true, validate: RED.validators.number() }
13+
},
14+
label: function () {
15+
return this.name || '__NODE_NAME__';
16+
}
17+
});

packages/node-red-builder/templates/src/nodes/node/template.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
</label>
66
<input type="text" id="node-input-name" data-i18n="[placeholder]__NODE_NAME__.placeholder.name" />
77
</div>
8+
<!-- __CONFIG_ROW__ -->
89
<div class="form-row">
910
<label for="node-input-action">
1011
<i class="fa fa-tasks"></i>

packages/node-red-builder/templates/src/nodes/node/ui.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ let /** @type {EditorRED} */ RED = /** @type {any} */ (window).RED;
99
RED.nodes.registerType('__PREFIX__-__NODE_NAME__', {
1010
category: '__PREFIX__',
1111
/** @type {EditorDefaults<__NODE_CLASS__['props']>} */ defaults: {
12+
// __CONFIG_ENTRY__
1213
name: { value: '' },
1314
action: { value: ACTION.APPLY },
1415
actionType: { value: 'action' },

0 commit comments

Comments
 (0)