mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Merge branch 'dev' into mqtt5
This commit is contained in:
commit
ab4a9e72d4
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@ -1,5 +1,6 @@
|
|||||||
name: PublishDockerImage
|
name: PublishDockerImage
|
||||||
|
env:
|
||||||
|
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
|
||||||
on:
|
on:
|
||||||
release:
|
release:
|
||||||
types: [published]
|
types: [published]
|
||||||
@ -27,9 +28,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
node-version: '12'
|
node-version: '12'
|
||||||
- run: node ./node-red/.github/scripts/update-node-red-docker.js
|
- run: node ./node-red/.github/scripts/update-node-red-docker.js
|
||||||
with:
|
|
||||||
env:
|
|
||||||
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
|
|
||||||
- name: Create Docker Pull Request
|
- name: Create Docker Pull Request
|
||||||
uses: peter-evans/create-pull-request@v2
|
uses: peter-evans/create-pull-request@v2
|
||||||
with:
|
with:
|
||||||
|
@ -11,5 +11,11 @@ matrix:
|
|||||||
before_script:
|
before_script:
|
||||||
- npm install -g coveralls
|
- npm install -g coveralls
|
||||||
- node_js: "12"
|
- node_js: "12"
|
||||||
|
script:
|
||||||
|
- ./node_modules/.bin/grunt no-coverage
|
||||||
- node_js: "10"
|
- node_js: "10"
|
||||||
|
script:
|
||||||
|
- ./node_modules/.bin/grunt no-coverage
|
||||||
- node_js: "8"
|
- node_js: "8"
|
||||||
|
script:
|
||||||
|
- ./node_modules/.bin/grunt no-coverage
|
||||||
|
2
API.md
2
API.md
@ -10,6 +10,6 @@ Module | Description
|
|||||||
[@node-red/editor-api](@node-red_editor-api.html) | an Express application that serves the Node-RED editor and provides the Admin HTTP API
|
[@node-red/editor-api](@node-red_editor-api.html) | an Express application that serves the Node-RED editor and provides the Admin HTTP API
|
||||||
[@node-red/runtime](@node-red_runtime.html) | the core runtime of Node-RED
|
[@node-red/runtime](@node-red_runtime.html) | the core runtime of Node-RED
|
||||||
[@node-red/util](@node-red_util.html) | common utilities for the Node-RED runtime and editor modules
|
[@node-red/util](@node-red_util.html) | common utilities for the Node-RED runtime and editor modules
|
||||||
@node-red/registry | the internal node registry
|
[@node-red/registry](@node-red_registry.html) | the internal node registry
|
||||||
@node-red/nodes | the default set of core nodes
|
@node-red/nodes | the default set of core nodes
|
||||||
@node-red/editor-client | the client-side resources of the Node-RED editor application
|
@node-red/editor-client | the client-side resources of the Node-RED editor application
|
||||||
|
62
CHANGELOG.md
62
CHANGELOG.md
@ -1,3 +1,65 @@
|
|||||||
|
### 1.2.8: Maintenance Release
|
||||||
|
|
||||||
|
Editor
|
||||||
|
|
||||||
|
- Ensure subflow help is picked up for palette tooltip Fixes #2834
|
||||||
|
- Improve Ru locale (#2826) @alexk111
|
||||||
|
- Fix scrollbars (#2825) @alexk111
|
||||||
|
|
||||||
|
Runtime
|
||||||
|
|
||||||
|
- Restrict project file access to inside the project directory
|
||||||
|
- Validate user-provided language parameter before passing to i18n
|
||||||
|
- Fix grunt release mkdir issue on Node.js 14 (#2827) @alexk111
|
||||||
|
- Prevent crash when coreNodesDir is empty (#2831) @hardillb
|
||||||
|
|
||||||
|
Nodes
|
||||||
|
|
||||||
|
- Batch node: Fixing minor typo in node's documentation (#2848) @matthiasradde
|
||||||
|
- Split node: Handle out of order messages as long as one of the messages has msg.parts.count set to the proper value (#2748) @s4ke
|
||||||
|
|
||||||
|
### 1.2.7: Maintenance Release
|
||||||
|
|
||||||
|
Editor
|
||||||
|
|
||||||
|
- Ensure subflow-scoped config nodes do not get moved on import Fixes #2789
|
||||||
|
- Allow TypedInput to be disabled (#2752) @bartbutenaers
|
||||||
|
- Allow userMenu to be explicitly enabled (#2805) @tfmf
|
||||||
|
- Improvements to DE translation (#2192) @ketzu
|
||||||
|
|
||||||
|
|
||||||
|
Runtime
|
||||||
|
|
||||||
|
- Handle `undefined` error passed to node.error (#2781) @johnwang71
|
||||||
|
- Disable nyc coverage reporting on older node versions
|
||||||
|
- Improve Editor API unit test coverage (#2777) @aaronmyatt
|
||||||
|
|
||||||
|
|
||||||
|
Nodes
|
||||||
|
|
||||||
|
- Trigger: ensure timestamp option sends .now() at point of sending
|
||||||
|
|
||||||
|
|
||||||
|
### 1.2.6: Maintenance Release
|
||||||
|
|
||||||
|
|
||||||
|
Editor
|
||||||
|
|
||||||
|
- Update Japanese translations for 1.2.5 (#2764) @kazuhitoyokoi
|
||||||
|
- Library: properly handle symlinked folders (#2768) @natcl
|
||||||
|
|
||||||
|
Runtime
|
||||||
|
|
||||||
|
- Support Windows paths when installing tarball by path name Fixes #2769
|
||||||
|
- Fix unsecure command usage in GH Action
|
||||||
|
|
||||||
|
Nodes
|
||||||
|
|
||||||
|
- Update MQTT to latest to fix Node 8 URL breakage
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 1.2.5: Maintenance Release
|
### 1.2.5: Maintenance Release
|
||||||
|
|
||||||
Editor
|
Editor
|
||||||
|
@ -142,6 +142,7 @@ module.exports = function(grunt) {
|
|||||||
"packages/node_modules/@node-red/editor-client/src/js/text/bidi.js",
|
"packages/node_modules/@node-red/editor-client/src/js/text/bidi.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/text/format.js",
|
"packages/node_modules/@node-red/editor-client/src/js/text/format.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/state.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/state.js",
|
||||||
|
"packages/node_modules/@node-red/editor-client/src/js/plugins.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/nodes.js",
|
"packages/node_modules/@node-red/editor-client/src/js/nodes.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/font-awesome.js",
|
"packages/node_modules/@node-red/editor-client/src/js/font-awesome.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/history.js",
|
"packages/node_modules/@node-red/editor-client/src/js/history.js",
|
||||||
@ -461,7 +462,8 @@ module.exports = function(grunt) {
|
|||||||
'packages/node_modules/@node-red/runtime/lib/hooks.js',
|
'packages/node_modules/@node-red/runtime/lib/hooks.js',
|
||||||
'packages/node_modules/@node-red/util/**/*.js',
|
'packages/node_modules/@node-red/util/**/*.js',
|
||||||
'packages/node_modules/@node-red/editor-api/lib/index.js',
|
'packages/node_modules/@node-red/editor-api/lib/index.js',
|
||||||
'packages/node_modules/@node-red/editor-api/lib/auth/index.js'
|
'packages/node_modules/@node-red/editor-api/lib/auth/index.js',
|
||||||
|
'packages/node_modules/@node-red/registry/lib/index.js'
|
||||||
],
|
],
|
||||||
options: {
|
options: {
|
||||||
destination: 'docs',
|
destination: 'docs',
|
||||||
@ -623,6 +625,11 @@ module.exports = function(grunt) {
|
|||||||
'Builds editor content then runs code style checks and unit tests on all components',
|
'Builds editor content then runs code style checks and unit tests on all components',
|
||||||
['build','verifyPackageDependencies','jshint:editor','nyc:all']);
|
['build','verifyPackageDependencies','jshint:editor','nyc:all']);
|
||||||
|
|
||||||
|
grunt.registerTask('no-coverage',
|
||||||
|
'Builds editor content then runs code style checks and unit tests on all components without code coverage',
|
||||||
|
['build','verifyPackageDependencies','jshint:editor','simplemocha:all']);
|
||||||
|
|
||||||
|
|
||||||
grunt.registerTask('test-core',
|
grunt.registerTask('test-core',
|
||||||
'Runs code style check and unit tests on core runtime code',
|
'Runs code style check and unit tests on core runtime code',
|
||||||
['build','nyc:core']);
|
['build','nyc:core']);
|
||||||
|
21
package.json
21
package.json
@ -27,7 +27,7 @@
|
|||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ajv": "6.12.6",
|
"ajv": "6.12.6",
|
||||||
"async-mutex": "0.2.4",
|
"async-mutex": "0.2.6",
|
||||||
"basic-auth": "2.0.1",
|
"basic-auth": "2.0.1",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"body-parser": "1.19.0",
|
"body-parser": "1.19.0",
|
||||||
@ -38,7 +38,7 @@
|
|||||||
"cookie-parser": "1.4.5",
|
"cookie-parser": "1.4.5",
|
||||||
"cors": "2.8.5",
|
"cors": "2.8.5",
|
||||||
"cron": "1.7.2",
|
"cron": "1.7.2",
|
||||||
"denque": "1.4.1",
|
"denque": "1.5.0",
|
||||||
"express": "4.17.1",
|
"express": "4.17.1",
|
||||||
"express-session": "1.17.1",
|
"express-session": "1.17.1",
|
||||||
"fs-extra": "8.1.0",
|
"fs-extra": "8.1.0",
|
||||||
@ -54,11 +54,11 @@
|
|||||||
"lodash.clonedeep": "^4.5.0",
|
"lodash.clonedeep": "^4.5.0",
|
||||||
"media-typer": "1.1.0",
|
"media-typer": "1.1.0",
|
||||||
"memorystore": "1.6.4",
|
"memorystore": "1.6.4",
|
||||||
"mime": "2.4.6",
|
"mime": "2.4.7",
|
||||||
"moment-timezone": "0.5.32",
|
"moment-timezone": "0.5.32",
|
||||||
"mqtt": "4.2.5",
|
"mqtt": "4.2.6",
|
||||||
"multer": "1.4.2",
|
"multer": "1.4.2",
|
||||||
"mustache": "4.0.1",
|
"mustache": "4.1.0",
|
||||||
"node-red-admin": "^0.2.6",
|
"node-red-admin": "^0.2.6",
|
||||||
"node-red-node-rbe": "^0.2.9",
|
"node-red-node-rbe": "^0.2.9",
|
||||||
"node-red-node-sentiment": "^0.1.6",
|
"node-red-node-sentiment": "^0.1.6",
|
||||||
@ -73,8 +73,7 @@
|
|||||||
"request": "2.88.0",
|
"request": "2.88.0",
|
||||||
"semver": "6.3.0",
|
"semver": "6.3.0",
|
||||||
"tar": "6.0.5",
|
"tar": "6.0.5",
|
||||||
"uglify-js": "3.11.6",
|
"uglify-js": "3.12.4",
|
||||||
"when": "3.7.8",
|
|
||||||
"ws": "6.2.1",
|
"ws": "6.2.1",
|
||||||
"xml2js": "0.4.23"
|
"xml2js": "0.4.23"
|
||||||
},
|
},
|
||||||
@ -82,7 +81,7 @@
|
|||||||
"bcrypt": "3.0.8"
|
"bcrypt": "3.0.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"dompurify": "2.2.2",
|
"dompurify": "2.2.6",
|
||||||
"grunt": "1.3.0",
|
"grunt": "1.3.0",
|
||||||
"grunt-chmod": "~1.1.1",
|
"grunt-chmod": "~1.1.1",
|
||||||
"grunt-cli": "~1.3.2",
|
"grunt-cli": "~1.3.2",
|
||||||
@ -97,17 +96,17 @@
|
|||||||
"grunt-jsdoc": "2.4.1",
|
"grunt-jsdoc": "2.4.1",
|
||||||
"grunt-jsdoc-to-markdown": "5.0.0",
|
"grunt-jsdoc-to-markdown": "5.0.0",
|
||||||
"grunt-jsonlint": "2.1.3",
|
"grunt-jsonlint": "2.1.3",
|
||||||
"grunt-mkdir": "~1.0.0",
|
"grunt-mkdir": "~1.1.0",
|
||||||
"grunt-npm-command": "~0.1.2",
|
"grunt-npm-command": "~0.1.2",
|
||||||
"grunt-sass": "~3.1.0",
|
"grunt-sass": "~3.1.0",
|
||||||
"grunt-simple-mocha": "~0.4.1",
|
"grunt-simple-mocha": "~0.4.1",
|
||||||
"grunt-simple-nyc": "^3.0.1",
|
"grunt-simple-nyc": "^3.0.1",
|
||||||
"http-proxy": "1.18.1",
|
"http-proxy": "1.18.1",
|
||||||
"jsdoc-nr-template": "github:node-red/jsdoc-nr-template",
|
"jsdoc-nr-template": "github:node-red/jsdoc-nr-template",
|
||||||
"marked": "1.2.4",
|
"marked": "1.2.7",
|
||||||
"minami": "1.2.3",
|
"minami": "1.2.3",
|
||||||
"mocha": "^5.2.0",
|
"mocha": "^5.2.0",
|
||||||
"node-red-node-test-helper": "^0.2.5",
|
"node-red-node-test-helper": "^0.2.6",
|
||||||
"node-sass": "^4.14.1",
|
"node-sass": "^4.14.1",
|
||||||
"nodemon": "2.0.6",
|
"nodemon": "2.0.6",
|
||||||
"should": "13.2.3",
|
"should": "13.2.3",
|
||||||
|
@ -22,6 +22,7 @@ var flow = require("./flow");
|
|||||||
var context = require("./context");
|
var context = require("./context");
|
||||||
var auth = require("../auth");
|
var auth = require("../auth");
|
||||||
var info = require("./settings");
|
var info = require("./settings");
|
||||||
|
var plugins = require("./plugins");
|
||||||
|
|
||||||
var apiUtil = require("../util");
|
var apiUtil = require("../util");
|
||||||
|
|
||||||
@ -32,6 +33,7 @@ module.exports = {
|
|||||||
nodes.init(runtimeAPI);
|
nodes.init(runtimeAPI);
|
||||||
context.init(runtimeAPI);
|
context.init(runtimeAPI);
|
||||||
info.init(settings,runtimeAPI);
|
info.init(settings,runtimeAPI);
|
||||||
|
plugins.init(runtimeAPI);
|
||||||
|
|
||||||
var needsPermission = auth.needsPermission;
|
var needsPermission = auth.needsPermission;
|
||||||
|
|
||||||
@ -50,12 +52,14 @@ module.exports = {
|
|||||||
// Nodes
|
// Nodes
|
||||||
adminApp.get("/nodes",needsPermission("nodes.read"),nodes.getAll,apiUtil.errorHandler);
|
adminApp.get("/nodes",needsPermission("nodes.read"),nodes.getAll,apiUtil.errorHandler);
|
||||||
|
|
||||||
if (!settings.editorTheme || !settings.editorTheme.palette || settings.editorTheme.palette.upload !== false) {
|
if (!settings.externalModules || !settings.externalModules.palette || settings.externalModules.palette.allowInstall !== false) {
|
||||||
const multer = require('multer');
|
if (!settings.externalModules || !settings.externalModules.palette || settings.externalModules.palette.allowUpload !== false) {
|
||||||
const upload = multer({ storage: multer.memoryStorage() });
|
const multer = require('multer');
|
||||||
adminApp.post("/nodes",needsPermission("nodes.write"),upload.single("tarball"),nodes.post,apiUtil.errorHandler);
|
const upload = multer({ storage: multer.memoryStorage() });
|
||||||
} else {
|
adminApp.post("/nodes",needsPermission("nodes.write"),upload.single("tarball"),nodes.post,apiUtil.errorHandler);
|
||||||
adminApp.post("/nodes",needsPermission("nodes.write"),nodes.post,apiUtil.errorHandler);
|
} else {
|
||||||
|
adminApp.post("/nodes",needsPermission("nodes.write"),nodes.post,apiUtil.errorHandler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
adminApp.get(/^\/nodes\/messages/,needsPermission("nodes.read"),nodes.getModuleCatalogs,apiUtil.errorHandler);
|
adminApp.get(/^\/nodes\/messages/,needsPermission("nodes.read"),nodes.getModuleCatalogs,apiUtil.errorHandler);
|
||||||
adminApp.get(/^\/nodes\/((@[^\/]+\/)?[^\/]+\/[^\/]+)\/messages/,needsPermission("nodes.read"),nodes.getModuleCatalog,apiUtil.errorHandler);
|
adminApp.get(/^\/nodes\/((@[^\/]+\/)?[^\/]+\/[^\/]+)\/messages/,needsPermission("nodes.read"),nodes.getModuleCatalog,apiUtil.errorHandler);
|
||||||
@ -78,6 +82,10 @@ module.exports = {
|
|||||||
|
|
||||||
adminApp.get("/settings",needsPermission("settings.read"),info.runtimeSettings,apiUtil.errorHandler);
|
adminApp.get("/settings",needsPermission("settings.read"),info.runtimeSettings,apiUtil.errorHandler);
|
||||||
|
|
||||||
|
// Plugins
|
||||||
|
adminApp.get("/plugins", needsPermission("plugins.read"), plugins.getAll, apiUtil.errorHandler);
|
||||||
|
adminApp.get("/plugins/messages", needsPermission("plugins.read"), plugins.getCatalogs, apiUtil.errorHandler);
|
||||||
|
|
||||||
return adminApp;
|
return adminApp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,7 @@ module.exports = {
|
|||||||
runtimeAPI.nodes.addModule(opts).then(function(info) {
|
runtimeAPI.nodes.addModule(opts).then(function(info) {
|
||||||
res.json(info);
|
res.json(info);
|
||||||
}).catch(function(err) {
|
}).catch(function(err) {
|
||||||
|
console.log(err.stack);
|
||||||
apiUtils.rejectHandler(req,res,err);
|
apiUtils.rejectHandler(req,res,err);
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
46
packages/node_modules/@node-red/editor-api/lib/admin/plugins.js
vendored
Normal file
46
packages/node_modules/@node-red/editor-api/lib/admin/plugins.js
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
var apiUtils = require("../util");
|
||||||
|
|
||||||
|
var runtimeAPI;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
init: function(_runtimeAPI) {
|
||||||
|
runtimeAPI = _runtimeAPI;
|
||||||
|
},
|
||||||
|
getAll: function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
req: apiUtils.getRequestLogObject(req)
|
||||||
|
}
|
||||||
|
if (req.get("accept") == "application/json") {
|
||||||
|
runtimeAPI.plugins.getPluginList(opts).then(function(list) {
|
||||||
|
res.json(list);
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
opts.lang = apiUtils.determineLangFromHeaders(req.acceptsLanguages());
|
||||||
|
if (/[^a-z\-\*]/i.test(opts.lang)) {
|
||||||
|
res.json({});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
runtimeAPI.plugins.getPluginConfigs(opts).then(function(configs) {
|
||||||
|
res.send(configs);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getCatalogs: function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
lang: req.query.lng,
|
||||||
|
req: apiUtils.getRequestLogObject(req)
|
||||||
|
}
|
||||||
|
if (/[^a-z\-\*]/i.test(opts.lang)) {
|
||||||
|
res.json({});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
runtimeAPI.plugins.getPluginCatalogs(opts).then(function(result) {
|
||||||
|
res.json(result);
|
||||||
|
}).catch(function(err) {
|
||||||
|
console.log(err.stack);
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
@ -76,7 +76,7 @@ module.exports = {
|
|||||||
editorApp.get("/icons/:scope/:module/:icon",ui.icon);
|
editorApp.get("/icons/:scope/:module/:icon",ui.icon);
|
||||||
|
|
||||||
var theme = require("./theme");
|
var theme = require("./theme");
|
||||||
theme.init(settings);
|
theme.init(settings, runtimeAPI);
|
||||||
editorApp.use("/theme",theme.app());
|
editorApp.use("/theme",theme.app());
|
||||||
editorApp.use("/",ui.editorResources);
|
editorApp.use("/",ui.editorResources);
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
var apiUtils = require("../util");
|
var apiUtils = require("../util");
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var fspath = require('path');
|
var fspath = require('path');
|
||||||
var when = require('when');
|
|
||||||
|
|
||||||
var runtimeAPI;
|
var runtimeAPI;
|
||||||
|
|
||||||
|
@ -39,9 +39,12 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
get: function(req,res) {
|
get: function(req,res) {
|
||||||
var namespace = req.params[0];
|
var namespace = req.params[0];
|
||||||
var lngs = req.query.lng;
|
|
||||||
namespace = namespace.replace(/\.json$/,"");
|
namespace = namespace.replace(/\.json$/,"");
|
||||||
var lang = req.query.lng || i18n.defaultLang; //apiUtil.determineLangFromHeaders(req.acceptsLanguages() || []);
|
var lang = req.query.lng || i18n.defaultLang; //apiUtil.determineLangFromHeaders(req.acceptsLanguages() || []);
|
||||||
|
if (/[^a-z\-\*]/i.test(lang)) {
|
||||||
|
res.json({});
|
||||||
|
return;
|
||||||
|
}
|
||||||
var prevLang = i18n.i.language;
|
var prevLang = i18n.i.language;
|
||||||
// Trigger a load from disk of the language if it is not the default
|
// Trigger a load from disk of the language if it is not the default
|
||||||
i18n.i.changeLanguage(lang, function(){
|
i18n.i.changeLanguage(lang, function(){
|
||||||
|
@ -41,6 +41,10 @@ var theme = null;
|
|||||||
var themeContext = clone(defaultContext);
|
var themeContext = clone(defaultContext);
|
||||||
var themeSettings = null;
|
var themeSettings = null;
|
||||||
|
|
||||||
|
var activeTheme = null;
|
||||||
|
var activeThemeInitialised = false;
|
||||||
|
|
||||||
|
var runtimeAPI;
|
||||||
var themeApp;
|
var themeApp;
|
||||||
|
|
||||||
function serveFile(app,baseUrl,file) {
|
function serveFile(app,baseUrl,file) {
|
||||||
@ -58,7 +62,7 @@ function serveFile(app,baseUrl,file) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function serveFilesFromTheme(themeValue, themeApp, directory) {
|
function serveFilesFromTheme(themeValue, themeApp, directory, baseDirectory) {
|
||||||
var result = [];
|
var result = [];
|
||||||
if (themeValue) {
|
if (themeValue) {
|
||||||
var array = themeValue;
|
var array = themeValue;
|
||||||
@ -67,7 +71,14 @@ function serveFilesFromTheme(themeValue, themeApp, directory) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (var i=0;i<array.length;i++) {
|
for (var i=0;i<array.length;i++) {
|
||||||
var url = serveFile(themeApp,directory,array[i]);
|
let fullPath = array[i];
|
||||||
|
if (baseDirectory) {
|
||||||
|
fullPath = path.resolve(baseDirectory,array[i]);
|
||||||
|
if (fullPath.indexOf(baseDirectory) !== 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var url = serveFile(themeApp,directory,fullPath);
|
||||||
if (url) {
|
if (url) {
|
||||||
result.push(url);
|
result.push(url);
|
||||||
}
|
}
|
||||||
@ -77,10 +88,12 @@ function serveFilesFromTheme(themeValue, themeApp, directory) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init: function(settings) {
|
init: function(settings, _runtimeAPI) {
|
||||||
|
runtimeAPI = _runtimeAPI;
|
||||||
themeContext = clone(defaultContext);
|
themeContext = clone(defaultContext);
|
||||||
themeSettings = null;
|
themeSettings = null;
|
||||||
theme = settings.editorTheme || {};
|
theme = settings.editorTheme || {};
|
||||||
|
activeTheme = theme.theme;
|
||||||
},
|
},
|
||||||
|
|
||||||
app: function() {
|
app: function() {
|
||||||
@ -169,7 +182,9 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
themeApp.get("/", function(req,res) {
|
themeApp.get("/", async function(req,res) {
|
||||||
|
const themePluginList = await runtimeAPI.plugins.getPluginsByType({type:"node-red-theme"});
|
||||||
|
themeContext.themes = themePluginList.map(theme => theme.id);
|
||||||
res.json(themeContext);
|
res.json(themeContext);
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -185,10 +200,38 @@ module.exports = {
|
|||||||
themeSettings.projects = theme.projects;
|
themeSettings.projects = theme.projects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (theme.theme) {
|
||||||
|
themeSettings.theme = theme.theme;
|
||||||
|
}
|
||||||
return themeApp;
|
return themeApp;
|
||||||
},
|
},
|
||||||
context: function() {
|
context: async function() {
|
||||||
|
if (activeTheme && !activeThemeInitialised) {
|
||||||
|
const themePlugin = await runtimeAPI.plugins.getPlugin({
|
||||||
|
id:activeTheme
|
||||||
|
});
|
||||||
|
if (themePlugin) {
|
||||||
|
if (themePlugin.css) {
|
||||||
|
const cssFiles = serveFilesFromTheme(
|
||||||
|
themePlugin.css,
|
||||||
|
themeApp,
|
||||||
|
"/css/",
|
||||||
|
themePlugin.path
|
||||||
|
);
|
||||||
|
themeContext.page.css = cssFiles.concat(themeContext.page.css || [])
|
||||||
|
}
|
||||||
|
if (themePlugin.scripts) {
|
||||||
|
const scriptFiles = serveFilesFromTheme(
|
||||||
|
themePlugin.scripts,
|
||||||
|
themeApp,
|
||||||
|
"/scripts/",
|
||||||
|
themePlugin.path
|
||||||
|
)
|
||||||
|
themeContext.page.scripts = scriptFiles.concat(themeContext.page.scripts || [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
activeThemeInitialised = true;
|
||||||
|
}
|
||||||
return themeContext;
|
return themeContext;
|
||||||
},
|
},
|
||||||
settings: function() {
|
settings: function() {
|
||||||
|
@ -68,8 +68,8 @@ module.exports = {
|
|||||||
apiUtils.rejectHandler(req,res,err);
|
apiUtils.rejectHandler(req,res,err);
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
editor: function(req,res) {
|
editor: async function(req,res) {
|
||||||
res.send(Mustache.render(editorTemplate,theme.context()));
|
res.send(Mustache.render(editorTemplate,await theme.context()));
|
||||||
},
|
},
|
||||||
editorResources: express.static(path.join(editorClientDir,'public'))
|
editorResources: express.static(path.join(editorClientDir,'public'))
|
||||||
};
|
};
|
||||||
|
@ -28,7 +28,6 @@ var express = require("express");
|
|||||||
var bodyParser = require("body-parser");
|
var bodyParser = require("body-parser");
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
var passport = require('passport');
|
var passport = require('passport');
|
||||||
var when = require('when');
|
|
||||||
var cors = require('cors');
|
var cors = require('cors');
|
||||||
|
|
||||||
var auth = require("./auth");
|
var auth = require("./auth");
|
||||||
@ -60,8 +59,8 @@ function init(settings,_server,storage,runtimeAPI) {
|
|||||||
adminApp.use(corsHandler);
|
adminApp.use(corsHandler);
|
||||||
|
|
||||||
if (settings.httpAdminMiddleware) {
|
if (settings.httpAdminMiddleware) {
|
||||||
if (typeof settings.httpAdminMiddleware === "function") {
|
if (typeof settings.httpAdminMiddleware === "function" || Array.isArray(settings.httpAdminMiddleware)) {
|
||||||
adminApp.use(settings.httpAdminMiddleware)
|
adminApp.use(settings.httpAdminMiddleware);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,11 +110,9 @@ function init(settings,_server,storage,runtimeAPI) {
|
|||||||
* @return {Promise} resolves when the application is ready to handle requests
|
* @return {Promise} resolves when the application is ready to handle requests
|
||||||
* @memberof @node-red/editor-api
|
* @memberof @node-red/editor-api
|
||||||
*/
|
*/
|
||||||
function start() {
|
async function start() {
|
||||||
if (editor) {
|
if (editor) {
|
||||||
return editor.start();
|
return editor.start();
|
||||||
} else {
|
|
||||||
return when.resolve();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,11 +121,10 @@ function start() {
|
|||||||
* @return {Promise} resolves when the application is stopped
|
* @return {Promise} resolves when the application is stopped
|
||||||
* @memberof @node-red/editor-api
|
* @memberof @node-red/editor-api
|
||||||
*/
|
*/
|
||||||
function stop() {
|
async function stop() {
|
||||||
if (editor) {
|
if (editor) {
|
||||||
editor.stop();
|
editor.stop();
|
||||||
}
|
}
|
||||||
return when.resolve();
|
|
||||||
}
|
}
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init: init,
|
init: init,
|
||||||
|
@ -25,14 +25,13 @@
|
|||||||
"express-session": "1.17.1",
|
"express-session": "1.17.1",
|
||||||
"express": "4.17.1",
|
"express": "4.17.1",
|
||||||
"memorystore": "1.6.4",
|
"memorystore": "1.6.4",
|
||||||
"mime": "2.4.6",
|
"mime": "2.4.7",
|
||||||
"multer": "1.4.2",
|
"multer": "1.4.2",
|
||||||
"mustache": "4.0.1",
|
"mustache": "4.1.0",
|
||||||
"oauth2orize": "1.11.0",
|
"oauth2orize": "1.11.0",
|
||||||
"passport-http-bearer": "1.0.1",
|
"passport-http-bearer": "1.0.1",
|
||||||
"passport-oauth2-client-password": "0.1.2",
|
"passport-oauth2-client-password": "0.1.2",
|
||||||
"passport": "0.4.1",
|
"passport": "0.4.1",
|
||||||
"when": "3.7.8",
|
|
||||||
"ws": "6.2.1"
|
"ws": "6.2.1"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
"label" : {
|
"label" : {
|
||||||
"view" : {
|
"view" : {
|
||||||
"view" : "Ansicht",
|
"view" : "Ansicht",
|
||||||
"grid" : "Gitter",
|
"grid" : "Raster",
|
||||||
"showGrid" : "Raster anzeigen",
|
"showGrid" : "Raster anzeigen",
|
||||||
"snapGrid" : "Am Raster ausrichten",
|
"snapGrid" : "Am Raster ausrichten",
|
||||||
"gridSize" : "Rastergröße",
|
"gridSize" : "Rastergröße",
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"event": {
|
"event": {
|
||||||
|
"loadPlugins": "Loading Plugins",
|
||||||
"loadPalette": "Loading Palette",
|
"loadPalette": "Loading Palette",
|
||||||
"loadNodeCatalogs": "Loading Node catalogs",
|
"loadNodeCatalogs": "Loading Node catalogs",
|
||||||
"loadNodes": "Loading Nodes __count__",
|
"loadNodes": "Loading Nodes __count__",
|
||||||
@ -337,8 +338,21 @@
|
|||||||
"output": "outputs:",
|
"output": "outputs:",
|
||||||
"status": "status node",
|
"status": "status node",
|
||||||
"deleteSubflow": "delete subflow",
|
"deleteSubflow": "delete subflow",
|
||||||
|
"confirmDelete": "Are you sure you want to delete this subflow?",
|
||||||
"info": "Description",
|
"info": "Description",
|
||||||
"category": "Category",
|
"category": "Category",
|
||||||
|
"module": "Module",
|
||||||
|
"license": "License",
|
||||||
|
"licenseNone": "none",
|
||||||
|
"licenseOther": "Other",
|
||||||
|
"type": "Node Type",
|
||||||
|
"version": "Version",
|
||||||
|
"versionPlaceholder": "x.y.z",
|
||||||
|
"keys": "Keywords",
|
||||||
|
"keysPlaceholder": "Comma-separated keywords",
|
||||||
|
"author": "Author",
|
||||||
|
"authorPlaceholder": "Your Name <email@example.com>",
|
||||||
|
"desc": "Description",
|
||||||
"env": {
|
"env": {
|
||||||
"restore": "Restore to subflow default",
|
"restore": "Restore to subflow default",
|
||||||
"remove": "Remove environment variable"
|
"remove": "Remove environment variable"
|
||||||
@ -385,6 +399,7 @@
|
|||||||
"icon": "Icon",
|
"icon": "Icon",
|
||||||
"inputType": "Input type",
|
"inputType": "Input type",
|
||||||
"selectType": "select types...",
|
"selectType": "select types...",
|
||||||
|
"loadCredentials": "Loading node credentials",
|
||||||
"inputs" : {
|
"inputs" : {
|
||||||
"input": "input",
|
"input": "input",
|
||||||
"select": "select",
|
"select": "select",
|
||||||
@ -419,7 +434,8 @@
|
|||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"scopeChange": "Changing the scope will make it unavailable to nodes in other flows that use it",
|
"scopeChange": "Changing the scope will make it unavailable to nodes in other flows that use it",
|
||||||
"invalidProperties": "Invalid properties:"
|
"invalidProperties": "Invalid properties:",
|
||||||
|
"credentialLoadFailed": "Failed to load node credentials"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"keyboard": {
|
"keyboard": {
|
||||||
@ -1079,6 +1095,7 @@
|
|||||||
"editor-tab": {
|
"editor-tab": {
|
||||||
"properties": "Properties",
|
"properties": "Properties",
|
||||||
"envProperties": "Environment Variables",
|
"envProperties": "Environment Variables",
|
||||||
|
"module": "Module Properties",
|
||||||
"description": "Description",
|
"description": "Description",
|
||||||
"appearance": "Appearance",
|
"appearance": "Appearance",
|
||||||
"preview": "UI Preview",
|
"preview": "UI Preview",
|
||||||
|
@ -243,19 +243,19 @@
|
|||||||
"args": "array, function",
|
"args": "array, function",
|
||||||
"desc": "Returns the one and only value in the `array` parameter that satisfies the `function` predicate (i.e. the `function` returns Boolean `true` when passed the value). Throws an exception if the number of matching values is not exactly one.\n\nThe function should be supplied in the following signature: `function(value [, index [, array]])` where value is each input of the array, index is the position of that value and the whole array is passed as the third argument"
|
"desc": "Returns the one and only value in the `array` parameter that satisfies the `function` predicate (i.e. the `function` returns Boolean `true` when passed the value). Throws an exception if the number of matching values is not exactly one.\n\nThe function should be supplied in the following signature: `function(value [, index [, array]])` where value is each input of the array, index is the position of that value and the whole array is passed as the third argument"
|
||||||
},
|
},
|
||||||
"$encodeUrl": {
|
"$encodeUrlComponent": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "Encodes a Uniform Resource Locator (URL) component by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character.\n\nExample: `$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`"
|
"desc": "Encodes a Uniform Resource Locator (URL) component by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character.\n\nExample: `$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`"
|
||||||
},
|
},
|
||||||
"$encodeUrlComponent": {
|
"$encodeUrl": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "Encodes a Uniform Resource Locator (URL) by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character. \n\nExample: `$encodeUrl(\"https://mozilla.org/?x=шеллы\")` => `\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\"`"
|
"desc": "Encodes a Uniform Resource Locator (URL) by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character. \n\nExample: `$encodeUrl(\"https://mozilla.org/?x=шеллы\")` => `\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\"`"
|
||||||
},
|
},
|
||||||
"$decodeUrl": {
|
"$decodeUrlComponent": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "Decodes a Uniform Resource Locator (URL) component previously created by encodeUrlComponent. \n\nExample: `$decodeUrlComponent(\"%3Fx%3Dtest\")` => `\"?x=test\"`"
|
"desc": "Decodes a Uniform Resource Locator (URL) component previously created by encodeUrlComponent. \n\nExample: `$decodeUrlComponent(\"%3Fx%3Dtest\")` => `\"?x=test\"`"
|
||||||
},
|
},
|
||||||
"$decodeUrlComponent": {
|
"$decodeUrl": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "Decodes a Uniform Resource Locator (URL) previously created by encodeUrl. \n\nExample: `$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")` => `\"https://mozilla.org/?x=шеллы\"`"
|
"desc": "Decodes a Uniform Resource Locator (URL) previously created by encodeUrl. \n\nExample: `$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")` => `\"https://mozilla.org/?x=шеллы\"`"
|
||||||
},
|
},
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"event": {
|
"event": {
|
||||||
|
"loadPlugins": "プラグインを読み込み中",
|
||||||
"loadPalette": "パレットを読み込み中",
|
"loadPalette": "パレットを読み込み中",
|
||||||
"loadNodeCatalogs": "ノードカタログを読み込み中",
|
"loadNodeCatalogs": "ノードカタログを読み込み中",
|
||||||
"loadNodes": "ノードを読み込み中 __count__",
|
"loadNodes": "ノードを読み込み中 __count__",
|
||||||
@ -85,7 +86,7 @@
|
|||||||
"userSettings": "ユーザ設定",
|
"userSettings": "ユーザ設定",
|
||||||
"nodes": "ノード",
|
"nodes": "ノード",
|
||||||
"displayStatus": "ノードのステータスを表示",
|
"displayStatus": "ノードのステータスを表示",
|
||||||
"displayConfig": "ノードの設定",
|
"displayConfig": "設定ノード",
|
||||||
"import": "読み込み",
|
"import": "読み込み",
|
||||||
"export": "書き出し",
|
"export": "書き出し",
|
||||||
"search": "ノードを検索",
|
"search": "ノードを検索",
|
||||||
@ -203,8 +204,8 @@
|
|||||||
"replacedNodes_plural": "置換された __count__ 個のノード",
|
"replacedNodes_plural": "置換された __count__ 個のノード",
|
||||||
"pasteNodes": "JSON形式のフローデータを貼り付け",
|
"pasteNodes": "JSON形式のフローデータを貼り付け",
|
||||||
"selectFile": "読み込むファイルを選択",
|
"selectFile": "読み込むファイルを選択",
|
||||||
"importNodes": "フローをクリップボードから読み込み",
|
"importNodes": "フローを読み込み",
|
||||||
"exportNodes": "フローをクリップボードへ書き出し",
|
"exportNodes": "フローを書き出し",
|
||||||
"download": "ダウンロード",
|
"download": "ダウンロード",
|
||||||
"importUnrecognised": "認識できない型が読み込まれました:",
|
"importUnrecognised": "認識できない型が読み込まれました:",
|
||||||
"importUnrecognised_plural": "認識できない型が読み込まれました:",
|
"importUnrecognised_plural": "認識できない型が読み込まれました:",
|
||||||
@ -266,7 +267,7 @@
|
|||||||
"successfulDeploy": "デプロイが成功しました",
|
"successfulDeploy": "デプロイが成功しました",
|
||||||
"successfulRestart": "フローの再起動が成功しました",
|
"successfulRestart": "フローの再起動が成功しました",
|
||||||
"deployFailed": "デプロイが失敗しました: __message__",
|
"deployFailed": "デプロイが失敗しました: __message__",
|
||||||
"unusedConfigNodes": "使われていない「ノードの設定」があります。",
|
"unusedConfigNodes": "使われていない設定ノードがあります。",
|
||||||
"unusedConfigNodesLink": "設定を参照する",
|
"unusedConfigNodesLink": "設定を参照する",
|
||||||
"errors": {
|
"errors": {
|
||||||
"noResponse": "サーバの応答がありません"
|
"noResponse": "サーバの応答がありません"
|
||||||
@ -337,8 +338,21 @@
|
|||||||
"output": "出力:",
|
"output": "出力:",
|
||||||
"status": "ステータスノード",
|
"status": "ステータスノード",
|
||||||
"deleteSubflow": "サブフローを削除",
|
"deleteSubflow": "サブフローを削除",
|
||||||
|
"confirmDelete": "このサブフローを削除しても良いですか?",
|
||||||
"info": "詳細",
|
"info": "詳細",
|
||||||
"category": "カテゴリ",
|
"category": "カテゴリ",
|
||||||
|
"module": "モジュール",
|
||||||
|
"license": "ライセンス",
|
||||||
|
"licenseNone": "なし",
|
||||||
|
"licenseOther": "その他",
|
||||||
|
"type": "ノードの型",
|
||||||
|
"version": "バージョン",
|
||||||
|
"versionPlaceholder": "x.y.z",
|
||||||
|
"keys": "キーワード",
|
||||||
|
"keysPlaceholder": "カンマ区切りのキーワード",
|
||||||
|
"author": "作者",
|
||||||
|
"authorPlaceholder": "名前 <email@example.com>",
|
||||||
|
"desc": "説明",
|
||||||
"env": {
|
"env": {
|
||||||
"restore": "デフォルト値に戻す",
|
"restore": "デフォルト値に戻す",
|
||||||
"remove": "環境変数を削除"
|
"remove": "環境変数を削除"
|
||||||
@ -362,9 +376,9 @@
|
|||||||
"configDelete": "削除",
|
"configDelete": "削除",
|
||||||
"nodesUse": "__count__ 個のノードが、この設定を使用しています",
|
"nodesUse": "__count__ 個のノードが、この設定を使用しています",
|
||||||
"nodesUse_plural": "__count__ 個のノードが、この設定を使用しています",
|
"nodesUse_plural": "__count__ 個のノードが、この設定を使用しています",
|
||||||
"addNewConfig": "新規に __type__ ノードの設定を追加",
|
"addNewConfig": "新規に __type__ 設定ノードを追加",
|
||||||
"editNode": "__type__ ノードを編集",
|
"editNode": "__type__ ノードを編集",
|
||||||
"editConfig": "__type__ ノードの設定を編集",
|
"editConfig": "__type__ 設定ノードを編集",
|
||||||
"addNewType": "新規に __type__ を追加...",
|
"addNewType": "新規に __type__ を追加...",
|
||||||
"nodeProperties": "プロパティ",
|
"nodeProperties": "プロパティ",
|
||||||
"label": "ラベル",
|
"label": "ラベル",
|
||||||
@ -385,6 +399,7 @@
|
|||||||
"icon": "記号",
|
"icon": "記号",
|
||||||
"inputType": "入力形式",
|
"inputType": "入力形式",
|
||||||
"selectType": "形式選択...",
|
"selectType": "形式選択...",
|
||||||
|
"loadCredentials": "ノードの認証情報を読み込み中",
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"input": "入力",
|
"input": "入力",
|
||||||
"select": "メニュー",
|
"select": "メニュー",
|
||||||
@ -419,7 +434,8 @@
|
|||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"scopeChange": "スコープの変更は、他のフローで使われているノードを無効にします",
|
"scopeChange": "スコープの変更は、他のフローで使われているノードを無効にします",
|
||||||
"invalidProperties": "プロパティが不正です:"
|
"invalidProperties": "プロパティが不正です:",
|
||||||
|
"credentialLoadFailed": "ノードの認証情報の読み込みに失敗"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"keyboard": {
|
"keyboard": {
|
||||||
@ -637,8 +653,8 @@
|
|||||||
"noHelp": "ヘルプのトピックが未選択"
|
"noHelp": "ヘルプのトピックが未選択"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"name": "ノードの設定を表示",
|
"name": "設定ノードを表示",
|
||||||
"label": "ノードの設定",
|
"label": "設定ノード",
|
||||||
"global": "全てのフロー上",
|
"global": "全てのフロー上",
|
||||||
"none": "なし",
|
"none": "なし",
|
||||||
"subflows": "サブフロー",
|
"subflows": "サブフロー",
|
||||||
@ -1079,6 +1095,7 @@
|
|||||||
"editor-tab": {
|
"editor-tab": {
|
||||||
"properties": "プロパティ",
|
"properties": "プロパティ",
|
||||||
"envProperties": "環境変数",
|
"envProperties": "環境変数",
|
||||||
|
"module": "モジュールプロパティ",
|
||||||
"description": "説明",
|
"description": "説明",
|
||||||
"appearance": "外観",
|
"appearance": "外観",
|
||||||
"preview": "UIプレビュー",
|
"preview": "UIプレビュー",
|
||||||
@ -1089,6 +1106,7 @@
|
|||||||
"en-US": "英語",
|
"en-US": "英語",
|
||||||
"ja": "日本語",
|
"ja": "日本語",
|
||||||
"ko": "韓国語",
|
"ko": "韓国語",
|
||||||
|
"ru": "ロシア語",
|
||||||
"zh-CN": "中国語(簡体)",
|
"zh-CN": "中国語(簡体)",
|
||||||
"zh-TW": "中国語(繁体)"
|
"zh-TW": "中国語(繁体)"
|
||||||
}
|
}
|
||||||
|
@ -243,19 +243,19 @@
|
|||||||
"args": "array, function",
|
"args": "array, function",
|
||||||
"desc": "`array`の要素のうち、条件判定関数`function`を満たす(`function`に与えた場合に真偽値`true`を返す)要素が1つのみである場合、それを返します。マッチする要素が1つのみでない場合、例外を送出します。\n\n指定する関数は`function(value [, index [, array]])`というシグネチャでなければなりません。ここで、`value`は`array`の要素値、`index`は要素の添字、第三引数には配列全体を渡します。"
|
"desc": "`array`の要素のうち、条件判定関数`function`を満たす(`function`に与えた場合に真偽値`true`を返す)要素が1つのみである場合、それを返します。マッチする要素が1つのみでない場合、例外を送出します。\n\n指定する関数は`function(value [, index [, array]])`というシグネチャでなければなりません。ここで、`value`は`array`の要素値、`index`は要素の添字、第三引数には配列全体を渡します。"
|
||||||
},
|
},
|
||||||
"$encodeUrl": {
|
"$encodeUrlComponent": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "Uniform Resource Locator (URL)を構成する文字を1、2、3、もしくは、4文字エスケープシーケンスのUTF-8文字エンコーディングで置換します。\n\n例: `$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`"
|
"desc": "Uniform Resource Locator (URL)を構成する文字を1、2、3、もしくは、4文字エスケープシーケンスのUTF-8文字エンコーディングで置換します。\n\n例: `$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`"
|
||||||
},
|
},
|
||||||
"$encodeUrlComponent": {
|
"$encodeUrl": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "Uniform Resource Locator (URL)要素を構成する文字を1、2、3、もしくは、4文字エスケープシーケンスのUTF-8文字エンコーディングで置換します。\n\n例: `$encodeUrl(\"https://mozilla.org/?x=шеллы\")` => `\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\"`"
|
"desc": "Uniform Resource Locator (URL)要素を構成する文字を1、2、3、もしくは、4文字エスケープシーケンスのUTF-8文字エンコーディングで置換します。\n\n例: `$encodeUrl(\"https://mozilla.org/?x=шеллы\")` => `\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\"`"
|
||||||
},
|
},
|
||||||
"$decodeUrl": {
|
"$decodeUrlComponent": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "encodeUrlComponentで置換したUniform Resource Locator (URL)をデコードします。\n\n例: `$decodeUrlComponent(\"%3Fx%3Dtest\")` => `\"?x=test\"`"
|
"desc": "encodeUrlComponentで置換したUniform Resource Locator (URL)をデコードします。\n\n例: `$decodeUrlComponent(\"%3Fx%3Dtest\")` => `\"?x=test\"`"
|
||||||
},
|
},
|
||||||
"$decodeUrlComponent": {
|
"$decodeUrl": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "encodeUrlで置換したUniform Resource Locator (URL)要素をデコードします。 \n\n例: `$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")` => `\"https://mozilla.org/?x=шеллы\"`"
|
"desc": "encodeUrlで置換したUniform Resource Locator (URL)要素をデコードします。 \n\n例: `$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")` => `\"https://mozilla.org/?x=шеллы\"`"
|
||||||
},
|
},
|
||||||
|
@ -246,8 +246,8 @@
|
|||||||
"import": {
|
"import": {
|
||||||
"import": "Импортировать в",
|
"import": "Импортировать в",
|
||||||
"importSelected": "Импортировать выбранные",
|
"importSelected": "Импортировать выбранные",
|
||||||
"importCopy": "Импортировать копию",
|
"importCopy": "Импортировать копии",
|
||||||
"viewNodes": "Посмотреть узлы...",
|
"viewNodes": "Показать узлы...",
|
||||||
"newFlow": "новый поток",
|
"newFlow": "новый поток",
|
||||||
"replace": "заменить",
|
"replace": "заменить",
|
||||||
"errors": {
|
"errors": {
|
||||||
@ -257,7 +257,7 @@
|
|||||||
"missingType": "Недопустимый поток - у элемента __index__ отсутствует свойство 'type'"
|
"missingType": "Недопустимый поток - у элемента __index__ отсутствует свойство 'type'"
|
||||||
},
|
},
|
||||||
"conflictNotification1": "Некоторые импортируемые Вами узлы уже существуют в рабочей области.",
|
"conflictNotification1": "Некоторые импортируемые Вами узлы уже существуют в рабочей области.",
|
||||||
"conflictNotification2": "Выберите, какие узлы импортировать и следует ли заменить существующие узлы или импортировать их копию."
|
"conflictNotification2": "Выберите, какие узлы импортировать и следует ли заменить ими существующие узлы или импортировать их копии."
|
||||||
},
|
},
|
||||||
"copyMessagePath": "Путь скопирован",
|
"copyMessagePath": "Путь скопирован",
|
||||||
"copyMessageValue": "Значение скопировано",
|
"copyMessageValue": "Значение скопировано",
|
||||||
@ -373,12 +373,12 @@
|
|||||||
"configAdd": "Добавить",
|
"configAdd": "Добавить",
|
||||||
"configUpdate": "Обновить",
|
"configUpdate": "Обновить",
|
||||||
"configDelete": "Удалить",
|
"configDelete": "Удалить",
|
||||||
"nodesUse": "__count__ узел использует эту конфигурацию",
|
"nodesUse": "__count__ узел использует этот конфиг",
|
||||||
"nodesUse_plural_2": "__count__ узла используют эту конфигурацию",
|
"nodesUse_plural_2": "__count__ узла используют этот конфиг",
|
||||||
"nodesUse_plural_5": "__count__ узлов используют эту конфигурацию",
|
"nodesUse_plural_5": "__count__ узлов используют этот конфиг",
|
||||||
"addNewConfig": "Добавить новый конфигурационный узел __type__",
|
"addNewConfig": "Добавить новый конфиг узел __type__",
|
||||||
"editNode": "Изменить узел __type__",
|
"editNode": "Изменить узел __type__",
|
||||||
"editConfig": "Изменить конфигурационный узел __type__",
|
"editConfig": "Изменить конфиг узел __type__",
|
||||||
"addNewType": "Добавить новый __type__...",
|
"addNewType": "Добавить новый __type__...",
|
||||||
"nodeProperties": "свойства узла",
|
"nodeProperties": "свойства узла",
|
||||||
"label": "Метка",
|
"label": "Метка",
|
||||||
@ -615,7 +615,7 @@
|
|||||||
"info": {
|
"info": {
|
||||||
"name": "Информация",
|
"name": "Информация",
|
||||||
"tabName": "Имя",
|
"tabName": "Имя",
|
||||||
"label": "сведения",
|
"label": "инфо",
|
||||||
"node": "Узел",
|
"node": "Узел",
|
||||||
"type": "Тип",
|
"type": "Тип",
|
||||||
"group": "Группа",
|
"group": "Группа",
|
||||||
@ -648,8 +648,8 @@
|
|||||||
"showTips":"Вы можете открыть советы из панели настроек",
|
"showTips":"Вы можете открыть советы из панели настроек",
|
||||||
"outline": "Структура",
|
"outline": "Структура",
|
||||||
"empty": "пусто",
|
"empty": "пусто",
|
||||||
"globalConfig": "Узлы глобальной конфигурации",
|
"globalConfig": "Глобальные конфиг узлы",
|
||||||
"triggerAction": "Запустить действие",
|
"triggerAction": "Вызвать действие",
|
||||||
"find": "Найти в рабочей области",
|
"find": "Найти в рабочей области",
|
||||||
"search": {
|
"search": {
|
||||||
"configNodes": "Узлы конфигурации",
|
"configNodes": "Узлы конфигурации",
|
||||||
@ -671,8 +671,8 @@
|
|||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"name": "Узлы конфигураций",
|
"name": "Узлы конфигураций",
|
||||||
"label": "конфигурация",
|
"label": "конфиг",
|
||||||
"global": "На всех потока",
|
"global": "На всех потоках",
|
||||||
"none": "нет",
|
"none": "нет",
|
||||||
"subflows": "подпотоки",
|
"subflows": "подпотоки",
|
||||||
"flows": "потоки",
|
"flows": "потоки",
|
||||||
@ -690,8 +690,8 @@
|
|||||||
"none": "ничего не выбрано",
|
"none": "ничего не выбрано",
|
||||||
"refresh": "обновите, чтобы загрузить",
|
"refresh": "обновите, чтобы загрузить",
|
||||||
"empty": "пусто",
|
"empty": "пусто",
|
||||||
"node": "Узел",
|
"node": "Узловой",
|
||||||
"flow": "Поток",
|
"flow": "Потоковый",
|
||||||
"global": "Глобальный",
|
"global": "Глобальный",
|
||||||
"deleteConfirm": "Вы уверены, что хотите удалить этот элемент?",
|
"deleteConfirm": "Вы уверены, что хотите удалить этот элемент?",
|
||||||
"autoRefresh": "Обновить при изменении выбора",
|
"autoRefresh": "Обновить при изменении выбора",
|
||||||
@ -877,7 +877,7 @@
|
|||||||
"bool": "логический тип",
|
"bool": "логический тип",
|
||||||
"json": "JSON",
|
"json": "JSON",
|
||||||
"bin": "буфер",
|
"bin": "буфер",
|
||||||
"date": "отметка времени",
|
"date": "метка времени",
|
||||||
"jsonata": "выражение",
|
"jsonata": "выражение",
|
||||||
"env": "переменная среды",
|
"env": "переменная среды",
|
||||||
"cred": "учетные данные"
|
"cred": "учетные данные"
|
||||||
|
@ -243,19 +243,19 @@
|
|||||||
"args": "array, function",
|
"args": "array, function",
|
||||||
"desc": "Возвращает одно-единственное значение из массива `array`, которое удовлетворяет предикату `function` (то есть когда `function` возвращает логическое `true` при передаче значения). Выдает исключение, если число подходящих значений не одно.\n\nФункция должна соответствовать следующей сигнатуре: `function(value [, index [, array]])` где value - элемент массива, index - позиция этого значения, а весь массив передается в качестве третьего аргумента"
|
"desc": "Возвращает одно-единственное значение из массива `array`, которое удовлетворяет предикату `function` (то есть когда `function` возвращает логическое `true` при передаче значения). Выдает исключение, если число подходящих значений не одно.\n\nФункция должна соответствовать следующей сигнатуре: `function(value [, index [, array]])` где value - элемент массива, index - позиция этого значения, а весь массив передается в качестве третьего аргумента"
|
||||||
},
|
},
|
||||||
"$encodeUrl": {
|
"$encodeUrlComponent": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "Кодирует компонент Uniform Resource Locator (URL), заменяя каждый экземпляр определенных символов одной, двумя, тремя или четырьмя escape-последовательностями, представляющими кодировку UTF-8 символа.\n\nПример: `$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`"
|
"desc": "Кодирует компонент Uniform Resource Locator (URL), заменяя каждый экземпляр определенных символов одной, двумя, тремя или четырьмя escape-последовательностями, представляющими кодировку UTF-8 символа.\n\nПример: `$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`"
|
||||||
},
|
},
|
||||||
"$encodeUrlComponent": {
|
"$encodeUrl": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "Кодирует Uniform Resource Locator (URL), заменяя каждый экземпляр определенных символов одной, двумя, тремя или четырьмя escape-последовательностями, представляющими кодировку UTF-8 символа.\n\nПример: `$encodeUrl(\"https://mozilla.org/?x=шеллы\")` => `\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\"`"
|
"desc": "Кодирует Uniform Resource Locator (URL), заменяя каждый экземпляр определенных символов одной, двумя, тремя или четырьмя escape-последовательностями, представляющими кодировку UTF-8 символа.\n\nПример: `$encodeUrl(\"https://mozilla.org/?x=шеллы\")` => `\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\"`"
|
||||||
},
|
},
|
||||||
"$decodeUrl": {
|
"$decodeUrlComponent": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "Декодирует компонент Uniform Resource Locator (URL), ранее созданный с помощью encodeUrlComponent.\n\nПример: `$decodeUrlComponent(\"%3Fx%3Dtest\")` => `\"?x=test\"`"
|
"desc": "Декодирует компонент Uniform Resource Locator (URL), ранее созданный с помощью encodeUrlComponent.\n\nПример: `$decodeUrlComponent(\"%3Fx%3Dtest\")` => `\"?x=test\"`"
|
||||||
},
|
},
|
||||||
"$decodeUrlComponent": {
|
"$decodeUrl": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "Декодирует компонент Uniform Resource Locator (URL), ранее созданный с помощью encodeUrl. \n\nПример: `$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")` => `\"https://mozilla.org/?x=шеллы\"`"
|
"desc": "Декодирует компонент Uniform Resource Locator (URL), ранее созданный с помощью encodeUrl. \n\nПример: `$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")` => `\"https://mozilla.org/?x=шеллы\"`"
|
||||||
},
|
},
|
||||||
|
@ -243,19 +243,19 @@
|
|||||||
"args": "array, function",
|
"args": "array, function",
|
||||||
"desc": "返回满足参数function谓语的array参数中的唯一值 (比如:传递值时,函数返回布尔值“true”)。如果匹配值的数量不唯一时,则抛出异常。\n\n应在以下签名中提供函数: `function(value [,index [,array []]])` 其中value是数组的每个输入,index是该值的位置,整个数组作为第三个参数传递。"
|
"desc": "返回满足参数function谓语的array参数中的唯一值 (比如:传递值时,函数返回布尔值“true”)。如果匹配值的数量不唯一时,则抛出异常。\n\n应在以下签名中提供函数: `function(value [,index [,array []]])` 其中value是数组的每个输入,index是该值的位置,整个数组作为第三个参数传递。"
|
||||||
},
|
},
|
||||||
"$encodeUrl": {
|
"$encodeUrlComponent": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "通过用表示字符的UTF-8编码的一个,两个,三个或四个转义序列替换某些字符的每个实例,对统一资源定位符(URL)组件进行编码。\n\n示例: `$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`"
|
"desc": "通过用表示字符的UTF-8编码的一个,两个,三个或四个转义序列替换某些字符的每个实例,对统一资源定位符(URL)组件进行编码。\n\n示例: `$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`"
|
||||||
},
|
},
|
||||||
"$encodeUrlComponent": {
|
"$encodeUrl": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "通过用表示字符的UTF-8编码的一个,两个,三个或四个转义序列替换某些字符的每个实例,对统一资源定位符(URL)进行编码。\n\n示例: `$encodeUrl(\"https://mozilla.org/?x=шеллы\")` => `\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\"`"
|
"desc": "通过用表示字符的UTF-8编码的一个,两个,三个或四个转义序列替换某些字符的每个实例,对统一资源定位符(URL)进行编码。\n\n示例: `$encodeUrl(\"https://mozilla.org/?x=шеллы\")` => `\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\"`"
|
||||||
},
|
},
|
||||||
"$decodeUrl": {
|
"$decodeUrlComponent": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "解码以前由encodeUrlComponent创建的统一资源定位器(URL)组件。 \n\n示例: `$decodeUrlComponent(\"%3Fx%3Dtest\")` => `\"?x=test\"`"
|
"desc": "解码以前由encodeUrlComponent创建的统一资源定位器(URL)组件。 \n\n示例: `$decodeUrlComponent(\"%3Fx%3Dtest\")` => `\"?x=test\"`"
|
||||||
},
|
},
|
||||||
"$decodeUrlComponent": {
|
"$decodeUrl": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "解码先前由encodeUrl创建的统一资源定位符(URL)。 \n\n示例: `$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")` => `\"https://mozilla.org/?x=шеллы\"`"
|
"desc": "解码先前由encodeUrl创建的统一资源定位符(URL)。 \n\n示例: `$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")` => `\"https://mozilla.org/?x=шеллы\"`"
|
||||||
},
|
},
|
||||||
|
@ -243,19 +243,19 @@
|
|||||||
"args": "array, function",
|
"args": "array, function",
|
||||||
"desc": "返回滿足參數function謂語的array參數中的唯一值 (比如:傳遞值時,函數返回布林值“true”)。如果匹配值的數量不唯一時,則拋出異常。\n\n應在以下簽名中提供函數:`function(value [,index [,array []]])`其中value是數組的每個輸入,index是該值的位置,整個數組作為第三個參數傳遞。"
|
"desc": "返回滿足參數function謂語的array參數中的唯一值 (比如:傳遞值時,函數返回布林值“true”)。如果匹配值的數量不唯一時,則拋出異常。\n\n應在以下簽名中提供函數:`function(value [,index [,array []]])`其中value是數組的每個輸入,index是該值的位置,整個數組作為第三個參數傳遞。"
|
||||||
},
|
},
|
||||||
"$encodeUrl": {
|
"$encodeUrlComponent": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "通過用表示字符的UTF-8編碼的一個,兩個,三個或四個轉義序列替換某些字符的每個實例,對統一資源定位符(URL)組件進行編碼。\n\n示例:`$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`"
|
"desc": "通過用表示字符的UTF-8編碼的一個,兩個,三個或四個轉義序列替換某些字符的每個實例,對統一資源定位符(URL)組件進行編碼。\n\n示例:`$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`"
|
||||||
},
|
},
|
||||||
"$encodeUrlComponent": {
|
"$encodeUrl": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "通過用表示字符的UTF-8編碼的一個,兩個,三個或四個轉義序列替換某些字符的每個實例,對統一資源定位符(URL)進行編碼。\n\n示例: `$encodeUrl(\"https://mozilla.org/?x=шеллы\")` => `\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\"`"
|
"desc": "通過用表示字符的UTF-8編碼的一個,兩個,三個或四個轉義序列替換某些字符的每個實例,對統一資源定位符(URL)進行編碼。\n\n示例: `$encodeUrl(\"https://mozilla.org/?x=шеллы\")` => `\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\"`"
|
||||||
},
|
},
|
||||||
"$decodeUrl": {
|
"$decodeUrlComponent": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "解碼以前由encodeUrlComponent創建的統一資源定位器(URL)組件。 \n\n示例: `$decodeUrlComponent(\"%3Fx%3Dtest\")` => `\"?x=test\"`"
|
"desc": "解碼以前由encodeUrlComponent創建的統一資源定位器(URL)組件。 \n\n示例: `$decodeUrlComponent(\"%3Fx%3Dtest\")` => `\"?x=test\"`"
|
||||||
},
|
},
|
||||||
"$decodeUrlComponent": {
|
"$decodeUrl": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "解碼先前由encodeUrl創建的統一資源定位符(URL)。 \n\n示例: `$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")` => `\"https://mozilla.org/?x=шеллы\"`"
|
"desc": "解碼先前由encodeUrl創建的統一資源定位符(URL)。 \n\n示例: `$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")` => `\"https://mozilla.org/?x=шеллы\"`"
|
||||||
},
|
},
|
||||||
|
@ -343,17 +343,29 @@ RED.history = (function() {
|
|||||||
if (ev.changes.hasOwnProperty(i)) {
|
if (ev.changes.hasOwnProperty(i)) {
|
||||||
inverseEv.changes[i] = ev.node[i];
|
inverseEv.changes[i] = ev.node[i];
|
||||||
if (ev.node._def.defaults && ev.node._def.defaults[i] && ev.node._def.defaults[i].type) {
|
if (ev.node._def.defaults && ev.node._def.defaults[i] && ev.node._def.defaults[i].type) {
|
||||||
// This is a config node property
|
// This property is a reference to another node or nodes.
|
||||||
var currentConfigNode = RED.nodes.node(ev.node[i]);
|
var nodeList = ev.node[i];
|
||||||
if (currentConfigNode) {
|
if (!Array.isArray(nodeList)) {
|
||||||
currentConfigNode.users.splice(currentConfigNode.users.indexOf(ev.node),1);
|
nodeList = [nodeList];
|
||||||
RED.events.emit("nodes:change",currentConfigNode);
|
|
||||||
}
|
}
|
||||||
var newConfigNode = RED.nodes.node(ev.changes[i]);
|
nodeList.forEach(function(id) {
|
||||||
if (newConfigNode) {
|
var currentConfigNode = RED.nodes.node(id);
|
||||||
newConfigNode.users.push(ev.node);
|
if (currentConfigNode && currentConfigNode._def.category === "config") {
|
||||||
RED.events.emit("nodes:change",newConfigNode);
|
currentConfigNode.users.splice(currentConfigNode.users.indexOf(ev.node),1);
|
||||||
|
RED.events.emit("nodes:change",currentConfigNode);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
nodeList = ev.changes[i];
|
||||||
|
if (!Array.isArray(nodeList)) {
|
||||||
|
nodeList = [nodeList];
|
||||||
}
|
}
|
||||||
|
nodeList.forEach(function(id) {
|
||||||
|
var newConfigNode = RED.nodes.node(id);
|
||||||
|
if (newConfigNode && newConfigNode._def.category === "config") {
|
||||||
|
newConfigNode.users.push(ev.node);
|
||||||
|
RED.events.emit("nodes:change",newConfigNode);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
ev.node[i] = ev.changes[i];
|
ev.node[i] = ev.changes[i];
|
||||||
}
|
}
|
||||||
|
@ -108,6 +108,31 @@ RED.i18n = (function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
loadPluginCatalogs: function(done) {
|
||||||
|
var languageList = i18n.functions.toLanguages(localStorage.getItem("editor-language")||i18n.detectLanguage());
|
||||||
|
var toLoad = languageList.length;
|
||||||
|
|
||||||
|
languageList.forEach(function(lang) {
|
||||||
|
$.ajax({
|
||||||
|
headers: {
|
||||||
|
"Accept":"application/json"
|
||||||
|
},
|
||||||
|
cache: false,
|
||||||
|
url: apiRootUrl+'plugins/messages?lng='+lang,
|
||||||
|
success: function(data) {
|
||||||
|
var namespaces = Object.keys(data);
|
||||||
|
namespaces.forEach(function(ns) {
|
||||||
|
i18n.addResourceBundle(lang,ns,data[ns]);
|
||||||
|
});
|
||||||
|
toLoad--;
|
||||||
|
if (toLoad === 0) {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
@ -164,6 +164,21 @@ RED.nodes = (function() {
|
|||||||
|
|
||||||
// TODO: too tightly coupled into palette UI
|
// TODO: too tightly coupled into palette UI
|
||||||
}
|
}
|
||||||
|
if (def.defaults) {
|
||||||
|
for (var d in def.defaults) {
|
||||||
|
if (def.defaults.hasOwnProperty(d)) {
|
||||||
|
if (def.defaults[d].type) {
|
||||||
|
try {
|
||||||
|
def.defaults[d]._type = parseNodePropertyTypeString(def.defaults[d].type)
|
||||||
|
} catch(err) {
|
||||||
|
console.warn(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
RED.events.emit("registry:node-type-added",nt);
|
RED.events.emit("registry:node-type-added",nt);
|
||||||
},
|
},
|
||||||
removeNodeType: function(nt) {
|
removeNodeType: function(nt) {
|
||||||
@ -193,6 +208,59 @@ RED.nodes = (function() {
|
|||||||
return (1+Math.random()*4294967295).toString(16);
|
return (1+Math.random()*4294967295).toString(16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseNodePropertyTypeString(typeString) {
|
||||||
|
typeString = typeString.trim();
|
||||||
|
var c;
|
||||||
|
var pos = 0;
|
||||||
|
var isArray = /\[\]$/.test(typeString);
|
||||||
|
if (isArray) {
|
||||||
|
typeString = typeString.substring(0,typeString.length-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
var l = typeString.length;
|
||||||
|
var inBrackets = false;
|
||||||
|
var inToken = false;
|
||||||
|
var currentToken = "";
|
||||||
|
var types = [];
|
||||||
|
while (pos < l) {
|
||||||
|
c = typeString[pos];
|
||||||
|
if (inToken) {
|
||||||
|
if (c === "|") {
|
||||||
|
types.push(currentToken.trim())
|
||||||
|
currentToken = "";
|
||||||
|
inToken = false;
|
||||||
|
} else if (c === ")") {
|
||||||
|
types.push(currentToken.trim())
|
||||||
|
currentToken = "";
|
||||||
|
inBrackets = false;
|
||||||
|
inToken = false;
|
||||||
|
} else {
|
||||||
|
currentToken += c;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (c === "(") {
|
||||||
|
if (inBrackets) {
|
||||||
|
throw new Error("Invalid character '"+c+"' at position "+pos)
|
||||||
|
}
|
||||||
|
inBrackets = true;
|
||||||
|
} else if (c !== " ") {
|
||||||
|
inToken = true;
|
||||||
|
currentToken = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
currentToken = currentToken.trim();
|
||||||
|
if (currentToken.length > 0) {
|
||||||
|
types.push(currentToken)
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
types: types,
|
||||||
|
array: isArray
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function addNode(n) {
|
function addNode(n) {
|
||||||
if (n.type.indexOf("subflow") !== 0) {
|
if (n.type.indexOf("subflow") !== 0) {
|
||||||
n["_"] = n._def._;
|
n["_"] = n._def._;
|
||||||
@ -670,6 +738,7 @@ RED.nodes = (function() {
|
|||||||
node.in = [];
|
node.in = [];
|
||||||
node.out = [];
|
node.out = [];
|
||||||
node.env = n.env;
|
node.env = n.env;
|
||||||
|
node.meta = n.meta;
|
||||||
|
|
||||||
if (exportCreds) {
|
if (exportCreds) {
|
||||||
var credentialSet = {};
|
var credentialSet = {};
|
||||||
@ -780,6 +849,12 @@ RED.nodes = (function() {
|
|||||||
subflowSet.push(n);
|
subflowSet.push(n);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
RED.nodes.eachConfig(function(n) {
|
||||||
|
if (n.z == subflowId) {
|
||||||
|
subflowSet.push(n);
|
||||||
|
exportedConfigNodes[n.id] = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
var exportableSubflow = createExportableNodeSet(subflowSet, exportedIds, exportedSubflows, exportedConfigNodes);
|
var exportableSubflow = createExportableNodeSet(subflowSet, exportedIds, exportedSubflows, exportedConfigNodes);
|
||||||
nns = exportableSubflow.concat(nns);
|
nns = exportableSubflow.concat(nns);
|
||||||
}
|
}
|
||||||
@ -787,16 +862,29 @@ RED.nodes = (function() {
|
|||||||
if (node.type !== "subflow") {
|
if (node.type !== "subflow") {
|
||||||
var convertedNode = RED.nodes.convertNode(node);
|
var convertedNode = RED.nodes.convertNode(node);
|
||||||
for (var d in node._def.defaults) {
|
for (var d in node._def.defaults) {
|
||||||
if (node._def.defaults[d].type && node[d] in configNodes) {
|
if (node._def.defaults[d].type) {
|
||||||
var confNode = configNodes[node[d]];
|
var nodeList = node[d];
|
||||||
var exportable = registry.getNodeType(node._def.defaults[d].type).exportable;
|
if (!Array.isArray(nodeList)) {
|
||||||
if ((exportable == null || exportable)) {
|
nodeList = [nodeList];
|
||||||
if (!(node[d] in exportedConfigNodes)) {
|
}
|
||||||
exportedConfigNodes[node[d]] = true;
|
nodeList = nodeList.filter(function(id) {
|
||||||
set.push(confNode);
|
if (id in configNodes) {
|
||||||
|
var confNode = configNodes[id];
|
||||||
|
if (confNode._def.exportable !== false) {
|
||||||
|
if (!(id in exportedConfigNodes)) {
|
||||||
|
exportedConfigNodes[id] = true;
|
||||||
|
set.push(confNode);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
if (nodeList.length === 0) {
|
||||||
|
convertedNode[d] = Array.isArray(node[d])?[]:""
|
||||||
} else {
|
} else {
|
||||||
convertedNode[d] = "";
|
convertedNode[d] = Array.isArray(node[d])?nodeList:nodeList[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1360,7 +1448,7 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (n.z && !workspaces[n.z]) {
|
if (n.z && !workspaces[n.z] && !subflow_map[n.z]) {
|
||||||
n.z = activeWorkspace;
|
n.z = activeWorkspace;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1587,15 +1675,6 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: make this a part of the node definition so it doesn't have to
|
|
||||||
// be hardcoded here
|
|
||||||
var nodeTypeArrayReferences = {
|
|
||||||
"catch":"scope",
|
|
||||||
"status":"scope",
|
|
||||||
"complete": "scope",
|
|
||||||
"link in":"links",
|
|
||||||
"link out":"links"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remap all wires and config node references
|
// Remap all wires and config node references
|
||||||
for (i=0;i<new_nodes.length;i++) {
|
for (i=0;i<new_nodes.length;i++) {
|
||||||
@ -1624,19 +1703,24 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
for (var d3 in n._def.defaults) {
|
for (var d3 in n._def.defaults) {
|
||||||
if (n._def.defaults.hasOwnProperty(d3)) {
|
if (n._def.defaults.hasOwnProperty(d3)) {
|
||||||
if (n._def.defaults[d3].type && node_map[n[d3]]) {
|
if (n._def.defaults[d3].type) {
|
||||||
configNode = node_map[n[d3]];
|
var nodeList = n[d3];
|
||||||
n[d3] = configNode.id;
|
if (!Array.isArray(nodeList)) {
|
||||||
if (configNode.users.indexOf(n) === -1) {
|
nodeList = [nodeList];
|
||||||
configNode.users.push(n);
|
|
||||||
}
|
}
|
||||||
} else if (nodeTypeArrayReferences.hasOwnProperty(n.type) && nodeTypeArrayReferences[n.type] === d3 && n[d3] !== undefined && n[d3] !== null) {
|
nodeList = nodeList.map(function(id) {
|
||||||
for (var j = 0;j<n[d3].length;j++) {
|
var node = node_map[id];
|
||||||
if (node_map[n[d3][j]]) {
|
if (node) {
|
||||||
n[d3][j] = node_map[n[d3][j]].id;
|
if (node._def.category === 'config') {
|
||||||
|
if (node.users.indexOf(n) === -1) {
|
||||||
|
node.users.push(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node.id;
|
||||||
}
|
}
|
||||||
}
|
return id;
|
||||||
|
})
|
||||||
|
n[d3] = Array.isArray(n[d3])?nodeList:nodeList[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1920,6 +2004,18 @@ RED.nodes = (function() {
|
|||||||
RED.events.emit("groups:remove",group);
|
RED.events.emit("groups:remove",group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getNodeHelp(type) {
|
||||||
|
var helpContent = "";
|
||||||
|
var helpElement = $("script[data-help-name='"+type+"']");
|
||||||
|
if (helpElement) {
|
||||||
|
helpContent = helpElement.html();
|
||||||
|
var helpType = helpElement.attr("type");
|
||||||
|
if (helpType === "text/markdown") {
|
||||||
|
helpContent = RED.utils.renderMarkdown(helpContent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return helpContent;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
init: function() {
|
init: function() {
|
||||||
@ -1999,6 +2095,7 @@ RED.nodes = (function() {
|
|||||||
|
|
||||||
registerType: registry.registerNodeType,
|
registerType: registry.registerNodeType,
|
||||||
getType: registry.getNodeType,
|
getType: registry.getNodeType,
|
||||||
|
getNodeHelp: getNodeHelp,
|
||||||
convertNode: convertNode,
|
convertNode: convertNode,
|
||||||
|
|
||||||
add: addNode,
|
add: addNode,
|
||||||
|
46
packages/node_modules/@node-red/editor-client/src/js/plugins.js
vendored
Normal file
46
packages/node_modules/@node-red/editor-client/src/js/plugins.js
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
RED.plugins = (function() {
|
||||||
|
var plugins = {};
|
||||||
|
var pluginsByType = {};
|
||||||
|
|
||||||
|
function registerPlugin(id,definition) {
|
||||||
|
plugins[id] = definition;
|
||||||
|
if (definition.type) {
|
||||||
|
pluginsByType[definition.type] = pluginsByType[definition.type] || [];
|
||||||
|
pluginsByType[definition.type].push(definition);
|
||||||
|
}
|
||||||
|
if (RED._loadingModule) {
|
||||||
|
definition.module = RED._loadingModule;
|
||||||
|
definition["_"] = function() {
|
||||||
|
var args = Array.prototype.slice.call(arguments);
|
||||||
|
var originalKey = args[0];
|
||||||
|
if (!/:/.test(args[0])) {
|
||||||
|
args[0] = definition.module+":"+args[0];
|
||||||
|
}
|
||||||
|
var result = RED._.apply(null,args);
|
||||||
|
if (result === args[0]) {
|
||||||
|
return originalKey;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
definition["_"] = RED["_"]
|
||||||
|
}
|
||||||
|
if (definition.onadd && typeof definition.onadd === 'function') {
|
||||||
|
definition.onadd();
|
||||||
|
}
|
||||||
|
RED.events.emit("registry:plugin-added",id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPlugin(id) {
|
||||||
|
return plugins[id]
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPluginsByType(type) {
|
||||||
|
return pluginsByType[type] || [];
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
registerPlugin: registerPlugin,
|
||||||
|
getPlugin: getPlugin,
|
||||||
|
getPluginsByType: getPluginsByType
|
||||||
|
}
|
||||||
|
})();
|
@ -52,6 +52,5 @@
|
|||||||
Set.prototype = _Set.prototype;
|
Set.prototype = _Set.prototype;
|
||||||
Set.prototype.constructor = Set;
|
Set.prototype.constructor = Set;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
@ -15,19 +15,65 @@
|
|||||||
**/
|
**/
|
||||||
var RED = (function() {
|
var RED = (function() {
|
||||||
|
|
||||||
function appendNodeConfig(nodeConfig,done) {
|
|
||||||
|
function loadPluginList() {
|
||||||
|
loader.reportProgress(RED._("event.loadPlugins"), 10)
|
||||||
|
$.ajax({
|
||||||
|
headers: {
|
||||||
|
"Accept":"application/json"
|
||||||
|
},
|
||||||
|
cache: false,
|
||||||
|
url: 'plugins',
|
||||||
|
success: function(data) {
|
||||||
|
loader.reportProgress(RED._("event.loadPlugins"), 13)
|
||||||
|
RED.i18n.loadPluginCatalogs(function() {
|
||||||
|
loadPlugins(function() {
|
||||||
|
loadNodeList();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function loadPlugins(done) {
|
||||||
|
loader.reportProgress(RED._("event.loadPlugins",{count:""}), 17)
|
||||||
|
var lang = localStorage.getItem("editor-language")||i18n.detectLanguage();
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
headers: {
|
||||||
|
"Accept":"text/html",
|
||||||
|
"Accept-Language": lang
|
||||||
|
},
|
||||||
|
cache: false,
|
||||||
|
url: 'plugins',
|
||||||
|
success: function(data) {
|
||||||
|
var configs = data.trim().split(/(?=<!-- --- \[red-plugin:\S+\] --- -->)/);
|
||||||
|
var totalCount = configs.length;
|
||||||
|
var stepConfig = function() {
|
||||||
|
// loader.reportProgress(RED._("event.loadNodes",{count:(totalCount-configs.length)+"/"+totalCount}), 30 + ((totalCount-configs.length)/totalCount)*40 )
|
||||||
|
if (configs.length === 0) {
|
||||||
|
done();
|
||||||
|
} else {
|
||||||
|
var config = configs.shift();
|
||||||
|
appendPluginConfig(config,stepConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stepConfig();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendConfig(config, moduleIdMatch, targetContainer, done) {
|
||||||
done = done || function(){};
|
done = done || function(){};
|
||||||
var m = /<!-- --- \[red-module:(\S+)\] --- -->/.exec(nodeConfig.trim());
|
|
||||||
var moduleId;
|
var moduleId;
|
||||||
if (m) {
|
if (moduleIdMatch) {
|
||||||
moduleId = m[1];
|
moduleId = moduleIdMatch[1];
|
||||||
|
RED._loadingModule = moduleId;
|
||||||
} else {
|
} else {
|
||||||
moduleId = "unknown";
|
moduleId = "unknown";
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
var hasDeferred = false;
|
var hasDeferred = false;
|
||||||
|
var nodeConfigEls = $("<div>"+config+"</div>");
|
||||||
var nodeConfigEls = $("<div>"+nodeConfig+"</div>");
|
|
||||||
var scripts = nodeConfigEls.find("script");
|
var scripts = nodeConfigEls.find("script");
|
||||||
var scriptCount = scripts.length;
|
var scriptCount = scripts.length;
|
||||||
scripts.each(function(i,el) {
|
scripts.each(function(i,el) {
|
||||||
@ -38,14 +84,15 @@ var RED = (function() {
|
|||||||
newScript.onload = function() {
|
newScript.onload = function() {
|
||||||
scriptCount--;
|
scriptCount--;
|
||||||
if (scriptCount === 0) {
|
if (scriptCount === 0) {
|
||||||
$("#red-ui-editor-node-configs").append(nodeConfigEls);
|
$(targetContainer).append(nodeConfigEls);
|
||||||
|
delete RED._loadingModule;
|
||||||
done()
|
done()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($(el).attr('type') === "module") {
|
if ($(el).attr('type') === "module") {
|
||||||
newScript.type = "module";
|
newScript.type = "module";
|
||||||
}
|
}
|
||||||
$("#red-ui-editor-node-configs").append(newScript);
|
$(targetContainer).append(newScript);
|
||||||
newScript.src = RED.settings.apiRootUrl+srcUrl;
|
newScript.src = RED.settings.apiRootUrl+srcUrl;
|
||||||
hasDeferred = true;
|
hasDeferred = true;
|
||||||
} else {
|
} else {
|
||||||
@ -61,7 +108,8 @@ var RED = (function() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (!hasDeferred) {
|
if (!hasDeferred) {
|
||||||
$("#red-ui-editor-node-configs").append(nodeConfigEls);
|
$(targetContainer).append(nodeConfigEls);
|
||||||
|
delete RED._loadingModule;
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
@ -70,9 +118,27 @@ var RED = (function() {
|
|||||||
timeout: 10000
|
timeout: 10000
|
||||||
});
|
});
|
||||||
console.log("["+moduleId+"] "+err.toString());
|
console.log("["+moduleId+"] "+err.toString());
|
||||||
|
delete RED._loadingModule;
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function appendPluginConfig(pluginConfig,done) {
|
||||||
|
appendConfig(
|
||||||
|
pluginConfig,
|
||||||
|
/<!-- --- \[red-plugin:(\S+)\] --- -->/.exec(pluginConfig.trim()),
|
||||||
|
"#red-ui-editor-plugin-configs",
|
||||||
|
done
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendNodeConfig(nodeConfig,done) {
|
||||||
|
appendConfig(
|
||||||
|
nodeConfig,
|
||||||
|
/<!-- --- \[red-module:(\S+)\] --- -->/.exec(nodeConfig.trim()),
|
||||||
|
"#red-ui-editor-node-configs",
|
||||||
|
done
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function loadNodeList() {
|
function loadNodeList() {
|
||||||
loader.reportProgress(RED._("event.loadPalette"), 20)
|
loader.reportProgress(RED._("event.loadPalette"), 20)
|
||||||
@ -186,6 +252,7 @@ var RED = (function() {
|
|||||||
RED.workspaces.show(currentHash.substring(6));
|
RED.workspaces.show(currentHash.substring(6));
|
||||||
}
|
}
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
|
console.warn(err);
|
||||||
RED.notify(
|
RED.notify(
|
||||||
RED._("event.importError", {message: err.message}),
|
RED._("event.importError", {message: err.message}),
|
||||||
{
|
{
|
||||||
@ -269,7 +336,7 @@ var RED = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
// } else if (RED.settings.theme('palette.editable') !== false) {
|
// } else if (RED.settings.get('externalModules.palette.allowInstall', true) !== false) {
|
||||||
} else {
|
} else {
|
||||||
options.buttons = [
|
options.buttons = [
|
||||||
{
|
{
|
||||||
@ -509,7 +576,7 @@ var RED = (function() {
|
|||||||
]});
|
]});
|
||||||
|
|
||||||
menuOptions.push(null);
|
menuOptions.push(null);
|
||||||
if (RED.settings.theme('palette.editable') !== false) {
|
if (RED.settings.get('externalModules.palette.allowInstall', true) !== false) {
|
||||||
menuOptions.push({id:"menu-item-edit-palette",label:RED._("menu.label.editPalette"),onselect:"core:manage-palette"});
|
menuOptions.push({id:"menu-item-edit-palette",label:RED._("menu.label.editPalette"),onselect:"core:manage-palette"});
|
||||||
menuOptions.push(null);
|
menuOptions.push(null);
|
||||||
}
|
}
|
||||||
@ -544,7 +611,7 @@ var RED = (function() {
|
|||||||
RED.palette.init();
|
RED.palette.init();
|
||||||
RED.eventLog.init();
|
RED.eventLog.init();
|
||||||
|
|
||||||
if (RED.settings.theme('palette.editable') !== false) {
|
if (RED.settings.get('externalModules.palette.allowInstall', true) !== false) {
|
||||||
RED.palette.editor.init();
|
RED.palette.editor.init();
|
||||||
} else {
|
} else {
|
||||||
console.log("Palette editor disabled");
|
console.log("Palette editor disabled");
|
||||||
@ -579,7 +646,7 @@ var RED = (function() {
|
|||||||
|
|
||||||
RED.actions.add("core:show-about", showAbout);
|
RED.actions.add("core:show-about", showAbout);
|
||||||
|
|
||||||
loadNodeList();
|
loadPluginList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -595,6 +662,7 @@ var RED = (function() {
|
|||||||
'<div id="red-ui-sidebar"></div>'+
|
'<div id="red-ui-sidebar"></div>'+
|
||||||
'<div id="red-ui-sidebar-separator"></div>'+
|
'<div id="red-ui-sidebar-separator"></div>'+
|
||||||
'</div>').appendTo(options.target);
|
'</div>').appendTo(options.target);
|
||||||
|
$('<div id="red-ui-editor-plugin-configs"></div>').appendTo(options.target);
|
||||||
$('<div id="red-ui-editor-node-configs"></div>').appendTo(options.target);
|
$('<div id="red-ui-editor-node-configs"></div>').appendTo(options.target);
|
||||||
$('<div id="red-ui-full-shade" class="hide"></div>').appendTo(options.target);
|
$('<div id="red-ui-full-shade" class="hide"></div>').appendTo(options.target);
|
||||||
|
|
||||||
@ -613,9 +681,12 @@ var RED = (function() {
|
|||||||
$('<span>').html(theme.header.title).appendTo(logo);
|
$('<span>').html(theme.header.title).appendTo(logo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (theme.themes) {
|
||||||
|
knownThemes = theme.themes;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
var knownThemes = null;
|
||||||
var initialised = false;
|
var initialised = false;
|
||||||
|
|
||||||
function init(options) {
|
function init(options) {
|
||||||
@ -635,7 +706,13 @@ var RED = (function() {
|
|||||||
buildEditor(options);
|
buildEditor(options);
|
||||||
|
|
||||||
RED.i18n.init(options, function() {
|
RED.i18n.init(options, function() {
|
||||||
RED.settings.init(options, loadEditor);
|
RED.settings.init(options, function() {
|
||||||
|
if (knownThemes) {
|
||||||
|
RED.settings.editorTheme = RED.settings.editorTheme || {};
|
||||||
|
RED.settings.editorTheme.themes = knownThemes;
|
||||||
|
}
|
||||||
|
loadEditor();
|
||||||
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,12 +57,11 @@ RED.settings = (function () {
|
|||||||
return JSON.parse(localStorage.getItem(key));
|
return JSON.parse(localStorage.getItem(key));
|
||||||
} else {
|
} else {
|
||||||
var v;
|
var v;
|
||||||
try {
|
try { v = RED.utils.getMessageProperty(userSettings,key); } catch(err) {}
|
||||||
v = RED.utils.getMessageProperty(userSettings,key);
|
if (v === undefined) {
|
||||||
if (v === undefined) {
|
try { v = RED.utils.getMessageProperty(RED.settings,key); } catch(err) {}
|
||||||
v = defaultIfUndefined;
|
}
|
||||||
}
|
if (v === undefined) {
|
||||||
} catch(err) {
|
|
||||||
v = defaultIfUndefined;
|
v = defaultIfUndefined;
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
|
@ -30,6 +30,27 @@ RED.clipboard = (function() {
|
|||||||
|
|
||||||
var pendingImportConfig;
|
var pendingImportConfig;
|
||||||
|
|
||||||
|
|
||||||
|
function downloadData(file, data) {
|
||||||
|
if (window.navigator.msSaveBlob) {
|
||||||
|
// IE11 workaround
|
||||||
|
// IE does not support data uri scheme for downloading data
|
||||||
|
var blob = new Blob([data], {
|
||||||
|
type: "data:text/plain;charset=utf-8"
|
||||||
|
});
|
||||||
|
navigator.msSaveBlob(blob, file);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var element = document.createElement('a');
|
||||||
|
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(data));
|
||||||
|
element.setAttribute('download', file);
|
||||||
|
element.style.display = 'none';
|
||||||
|
document.body.appendChild(element);
|
||||||
|
element.click();
|
||||||
|
document.body.removeChild(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function setupDialogs() {
|
function setupDialogs() {
|
||||||
dialog = $('<div id="red-ui-clipboard-dialog" class="hide"><form class="dialog-form form-horizontal"></form></div>')
|
dialog = $('<div id="red-ui-clipboard-dialog" class="hide"><form class="dialog-form form-horizontal"></form></div>')
|
||||||
.appendTo("#red-ui-editor")
|
.appendTo("#red-ui-editor")
|
||||||
@ -56,13 +77,8 @@ RED.clipboard = (function() {
|
|||||||
class: "primary",
|
class: "primary",
|
||||||
text: RED._("clipboard.download"),
|
text: RED._("clipboard.download"),
|
||||||
click: function() {
|
click: function() {
|
||||||
var element = document.createElement('a');
|
var data = $("#red-ui-clipboard-dialog-export-text").val();
|
||||||
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent($("#red-ui-clipboard-dialog-export-text").val()));
|
downloadData("flows.json", data);
|
||||||
element.setAttribute('download', "flows.json");
|
|
||||||
element.style.display = 'none';
|
|
||||||
document.body.appendChild(element);
|
|
||||||
element.click();
|
|
||||||
document.body.removeChild(element);
|
|
||||||
$( this ).dialog( "close" );
|
$( this ).dialog( "close" );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -72,9 +88,7 @@ RED.clipboard = (function() {
|
|||||||
text: RED._("clipboard.export.copy"),
|
text: RED._("clipboard.export.copy"),
|
||||||
click: function() {
|
click: function() {
|
||||||
if (activeTab === "red-ui-clipboard-dialog-export-tab-clipboard") {
|
if (activeTab === "red-ui-clipboard-dialog-export-tab-clipboard") {
|
||||||
$("#red-ui-clipboard-dialog-export-text").select();
|
copyText($("#red-ui-clipboard-dialog-export-text").val());
|
||||||
document.execCommand("copy");
|
|
||||||
document.getSelection().removeAllRanges();
|
|
||||||
RED.notify(RED._("clipboard.nodesExported"),{id:"clipboard"});
|
RED.notify(RED._("clipboard.nodesExported"),{id:"clipboard"});
|
||||||
$( this ).dialog( "close" );
|
$( this ).dialog( "close" );
|
||||||
} else {
|
} else {
|
||||||
@ -222,14 +236,22 @@ RED.clipboard = (function() {
|
|||||||
'</div>'+
|
'</div>'+
|
||||||
'<div id="red-ui-clipboard-dialog-export-tabs-content" class="red-ui-clipboard-dialog-tabs-content">'+
|
'<div id="red-ui-clipboard-dialog-export-tabs-content" class="red-ui-clipboard-dialog-tabs-content">'+
|
||||||
'<div id="red-ui-clipboard-dialog-export-tab-clipboard" class="red-ui-clipboard-dialog-tab-clipboard">'+
|
'<div id="red-ui-clipboard-dialog-export-tab-clipboard" class="red-ui-clipboard-dialog-tab-clipboard">'+
|
||||||
'<div class="form-row" style="height:calc(100% - 30px)">'+
|
'<div id="red-ui-clipboard-dialog-export-tab-clipboard-tab-bar">'+
|
||||||
'<textarea readonly id="red-ui-clipboard-dialog-export-text"></textarea>'+
|
'<ul id="red-ui-clipboard-dialog-export-tab-clipboard-tabs"></ul>'+
|
||||||
'</div>'+
|
'</div>'+
|
||||||
'<div class="form-row" style="text-align: right;">'+
|
'<div class="red-ui-clipboard-dialog-export-tab-clipboard-tab" id="red-ui-clipboard-dialog-export-tab-clipboard-preview">'+
|
||||||
'<span id="red-ui-clipboard-dialog-export-fmt-group" class="button-group">'+
|
'<div id="red-ui-clipboard-dialog-export-tab-clipboard-preview-list"></div>'+
|
||||||
'<a id="red-ui-clipboard-dialog-export-fmt-mini" class="red-ui-button red-ui-button-small toggle" href="#" data-i18n="clipboard.export.compact"></a>'+
|
'</div>'+
|
||||||
'<a id="red-ui-clipboard-dialog-export-fmt-full" class="red-ui-button red-ui-button-small toggle" href="#" data-i18n="clipboard.export.formatted"></a>'+
|
'<div class="red-ui-clipboard-dialog-export-tab-clipboard-tab" id="red-ui-clipboard-dialog-export-tab-clipboard-json">'+
|
||||||
'</span>'+
|
'<div class="form-row" style="height:calc(100% - 40px)">'+
|
||||||
|
'<textarea readonly id="red-ui-clipboard-dialog-export-text"></textarea>'+
|
||||||
|
'</div>'+
|
||||||
|
'<div class="form-row" style="text-align: right;">'+
|
||||||
|
'<span id="red-ui-clipboard-dialog-export-fmt-group" class="button-group">'+
|
||||||
|
'<a id="red-ui-clipboard-dialog-export-fmt-mini" class="red-ui-button red-ui-button-small toggle" href="#" data-i18n="clipboard.export.compact"></a>'+
|
||||||
|
'<a id="red-ui-clipboard-dialog-export-fmt-full" class="red-ui-button red-ui-button-small toggle" href="#" data-i18n="clipboard.export.formatted"></a>'+
|
||||||
|
'</span>'+
|
||||||
|
'</div>'+
|
||||||
'</div>'+
|
'</div>'+
|
||||||
'</div>'+
|
'</div>'+
|
||||||
'<div id="red-ui-clipboard-dialog-export-tab-library" class="red-ui-clipboard-dialog-tab-library">'+
|
'<div id="red-ui-clipboard-dialog-export-tab-library" class="red-ui-clipboard-dialog-tab-library">'+
|
||||||
@ -592,6 +614,30 @@ RED.clipboard = (function() {
|
|||||||
})
|
})
|
||||||
loadFlowLibrary(libraryBrowser,"local",RED._("library.types.local"));
|
loadFlowLibrary(libraryBrowser,"local",RED._("library.types.local"));
|
||||||
|
|
||||||
|
var clipboardTabs = RED.tabs.create({
|
||||||
|
id: "red-ui-clipboard-dialog-export-tab-clipboard-tabs",
|
||||||
|
onchange: function(tab) {
|
||||||
|
$(".red-ui-clipboard-dialog-export-tab-clipboard-tab").hide();
|
||||||
|
$("#" + tab.id).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
clipboardTabs.addTab({
|
||||||
|
id: "red-ui-clipboard-dialog-export-tab-clipboard-preview",
|
||||||
|
label: RED._("clipboard.exportNodes")
|
||||||
|
});
|
||||||
|
|
||||||
|
clipboardTabs.addTab({
|
||||||
|
id: "red-ui-clipboard-dialog-export-tab-clipboard-json",
|
||||||
|
label: RED._("editor.types.json")
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var previewList = $("#red-ui-clipboard-dialog-export-tab-clipboard-preview-list").css({position:"absolute",top:0,right:0,bottom:0,left:0}).treeList({
|
||||||
|
data: []
|
||||||
|
})
|
||||||
|
refreshExportPreview();
|
||||||
|
|
||||||
$("#red-ui-clipboard-dialog-tab-library-name").val("flows.json").select();
|
$("#red-ui-clipboard-dialog-tab-library-name").val("flows.json").select();
|
||||||
|
|
||||||
dialogContainer.i18n();
|
dialogContainer.i18n();
|
||||||
@ -630,10 +676,10 @@ RED.clipboard = (function() {
|
|||||||
}
|
}
|
||||||
$(this).parent().children().removeClass('selected');
|
$(this).parent().children().removeClass('selected');
|
||||||
$(this).addClass('selected');
|
$(this).addClass('selected');
|
||||||
var type = $(this).attr('id');
|
var type = $(this).attr('id').substring("red-ui-clipboard-dialog-export-rng-".length);
|
||||||
var flow = "";
|
var flow = "";
|
||||||
var nodes = null;
|
var nodes = null;
|
||||||
if (type === 'red-ui-clipboard-dialog-export-rng-selected') {
|
if (type === 'selected') {
|
||||||
var selection = RED.workspaces.selection();
|
var selection = RED.workspaces.selection();
|
||||||
if (selection.length > 0) {
|
if (selection.length > 0) {
|
||||||
nodes = [];
|
nodes = [];
|
||||||
@ -647,14 +693,14 @@ RED.clipboard = (function() {
|
|||||||
}
|
}
|
||||||
// Don't include the subflow meta-port nodes in the exported selection
|
// Don't include the subflow meta-port nodes in the exported selection
|
||||||
nodes = RED.nodes.createExportableNodeSet(nodes.filter(function(n) { return n.type !== 'subflow'}));
|
nodes = RED.nodes.createExportableNodeSet(nodes.filter(function(n) { return n.type !== 'subflow'}));
|
||||||
} else if (type === 'red-ui-clipboard-dialog-export-rng-flow') {
|
} else if (type === 'flow') {
|
||||||
var activeWorkspace = RED.workspaces.active();
|
var activeWorkspace = RED.workspaces.active();
|
||||||
nodes = RED.nodes.groups(activeWorkspace);
|
nodes = RED.nodes.groups(activeWorkspace);
|
||||||
nodes = nodes.concat(RED.nodes.filterNodes({z:activeWorkspace}));
|
nodes = nodes.concat(RED.nodes.filterNodes({z:activeWorkspace}));
|
||||||
var parentNode = RED.nodes.workspace(activeWorkspace)||RED.nodes.subflow(activeWorkspace);
|
var parentNode = RED.nodes.workspace(activeWorkspace)||RED.nodes.subflow(activeWorkspace);
|
||||||
nodes.unshift(parentNode);
|
nodes.unshift(parentNode);
|
||||||
nodes = RED.nodes.createExportableNodeSet(nodes);
|
nodes = RED.nodes.createExportableNodeSet(nodes);
|
||||||
} else if (type === 'red-ui-clipboard-dialog-export-rng-full') {
|
} else if (type === 'full') {
|
||||||
nodes = RED.nodes.createCompleteNodeSet(false);
|
nodes = RED.nodes.createCompleteNodeSet(false);
|
||||||
}
|
}
|
||||||
if (nodes !== null) {
|
if (nodes !== null) {
|
||||||
@ -670,8 +716,10 @@ RED.clipboard = (function() {
|
|||||||
$("#red-ui-clipboard-dialog-export").addClass('disabled');
|
$("#red-ui-clipboard-dialog-export").addClass('disabled');
|
||||||
}
|
}
|
||||||
$("#red-ui-clipboard-dialog-export-text").val(flow);
|
$("#red-ui-clipboard-dialog-export-text").val(flow);
|
||||||
setTimeout(function() { $("#red-ui-clipboard-dialog-export-text").scrollTop(0); },50);
|
setTimeout(function() {
|
||||||
$("#red-ui-clipboard-dialog-export-text").trigger("focus");
|
$("#red-ui-clipboard-dialog-export-text").scrollTop(0);
|
||||||
|
refreshExportPreview(type);
|
||||||
|
},50);
|
||||||
})
|
})
|
||||||
|
|
||||||
$("#red-ui-clipboard-dialog-ok").hide();
|
$("#red-ui-clipboard-dialog-ok").hide();
|
||||||
@ -717,6 +765,93 @@ RED.clipboard = (function() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function refreshExportPreview(type) {
|
||||||
|
|
||||||
|
var flowData = $("#red-ui-clipboard-dialog-export-text").val() || "[]";
|
||||||
|
var flow = JSON.parse(flowData);
|
||||||
|
var flows = {};
|
||||||
|
var subflows = {};
|
||||||
|
var nodes = [];
|
||||||
|
var nodesByZ = {};
|
||||||
|
|
||||||
|
var treeFlows = [];
|
||||||
|
var treeSubflows = [];
|
||||||
|
|
||||||
|
flow.forEach(function(node) {
|
||||||
|
if (node.type === "tab") {
|
||||||
|
flows[node.id] = {
|
||||||
|
element: getFlowLabel(node,false),
|
||||||
|
deferBuild: type !== "flow",
|
||||||
|
expanded: type === "flow",
|
||||||
|
children: []
|
||||||
|
};
|
||||||
|
treeFlows.push(flows[node.id])
|
||||||
|
} else if (node.type === "subflow") {
|
||||||
|
subflows[node.id] = {
|
||||||
|
element: getNodeLabel(node,false),
|
||||||
|
deferBuild: true,
|
||||||
|
children: []
|
||||||
|
};
|
||||||
|
treeSubflows.push(subflows[node.id])
|
||||||
|
} else {
|
||||||
|
nodes.push(node);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var globalNodes = [];
|
||||||
|
var parentlessNodes = [];
|
||||||
|
|
||||||
|
nodes.forEach(function(node) {
|
||||||
|
var treeNode = {
|
||||||
|
element: getNodeLabel(node, false, false)
|
||||||
|
};
|
||||||
|
if (node.z) {
|
||||||
|
if (!flows[node.z] && !subflows[node.z]) {
|
||||||
|
parentlessNodes.push(treeNode)
|
||||||
|
} else if (flows[node.z]) {
|
||||||
|
flows[node.z].children.push(treeNode)
|
||||||
|
} else if (subflows[node.z]) {
|
||||||
|
subflows[node.z].children.push(treeNode)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
globalNodes.push(treeNode);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var treeData = [];
|
||||||
|
|
||||||
|
if (parentlessNodes.length > 0) {
|
||||||
|
treeData = treeData.concat(parentlessNodes);
|
||||||
|
}
|
||||||
|
if (type === "flow") {
|
||||||
|
treeData = treeData.concat(treeFlows);
|
||||||
|
} else if (treeFlows.length > 0) {
|
||||||
|
treeData.push({
|
||||||
|
label: RED._("menu.label.flows"),
|
||||||
|
deferBuild: treeFlows.length > 20,
|
||||||
|
expanded: treeFlows.length <= 20,
|
||||||
|
children: treeFlows
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (treeSubflows.length > 0) {
|
||||||
|
treeData.push({
|
||||||
|
label: RED._("menu.label.subflows"),
|
||||||
|
deferBuild: treeSubflows.length > 10,
|
||||||
|
expanded: treeSubflows.length <= 10,
|
||||||
|
children: treeSubflows
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (globalNodes.length > 0) {
|
||||||
|
treeData.push({
|
||||||
|
label: RED._("sidebar.info.globalConfig"),
|
||||||
|
deferBuild: globalNodes.length > 10,
|
||||||
|
expanded: globalNodes.length <= 10,
|
||||||
|
children: globalNodes
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#red-ui-clipboard-dialog-export-tab-clipboard-preview-list").treeList('data',treeData);
|
||||||
|
}
|
||||||
|
|
||||||
function loadFlowLibrary(browser,library,label) {
|
function loadFlowLibrary(browser,library,label) {
|
||||||
// if (includeExamples) {
|
// if (includeExamples) {
|
||||||
// listing.push({
|
// listing.push({
|
||||||
@ -756,6 +891,7 @@ RED.clipboard = (function() {
|
|||||||
}
|
}
|
||||||
function copyText(value,element,msg) {
|
function copyText(value,element,msg) {
|
||||||
var truncated = false;
|
var truncated = false;
|
||||||
|
var currentFocus = document.activeElement;
|
||||||
if (typeof value !== "string" ) {
|
if (typeof value !== "string" ) {
|
||||||
value = JSON.stringify(value, function(key,value) {
|
value = JSON.stringify(value, function(key,value) {
|
||||||
if (value !== null && typeof value === 'object') {
|
if (value !== null && typeof value === 'object') {
|
||||||
@ -787,7 +923,7 @@ RED.clipboard = (function() {
|
|||||||
if (truncated) {
|
if (truncated) {
|
||||||
msg += "_truncated";
|
msg += "_truncated";
|
||||||
}
|
}
|
||||||
$("#red-ui-clipboard-hidden").val(value).select();
|
$("#red-ui-clipboard-hidden").val(value).focus().select();
|
||||||
var result = document.execCommand("copy");
|
var result = document.execCommand("copy");
|
||||||
if (result && element) {
|
if (result && element) {
|
||||||
var popover = RED.popover.create({
|
var popover = RED.popover.create({
|
||||||
@ -801,6 +937,10 @@ RED.clipboard = (function() {
|
|||||||
},1000);
|
},1000);
|
||||||
popover.open();
|
popover.open();
|
||||||
}
|
}
|
||||||
|
$("#red-ui-clipboard-hidden").val("");
|
||||||
|
if (currentFocus) {
|
||||||
|
$(currentFocus).focus();
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1103,7 +1243,7 @@ RED.clipboard = (function() {
|
|||||||
init: function() {
|
init: function() {
|
||||||
setupDialogs();
|
setupDialogs();
|
||||||
|
|
||||||
$('<input type="text" id="red-ui-clipboard-hidden" tabIndex="-1">').appendTo("#red-ui-editor");
|
$('<textarea type="text" id="red-ui-clipboard-hidden" tabIndex="-1">').appendTo("#red-ui-editor");
|
||||||
|
|
||||||
RED.actions.add("core:show-export-dialog",showExportNodes);
|
RED.actions.add("core:show-export-dialog",showExportNodes);
|
||||||
RED.actions.add("core:show-import-dialog",showImportNodes);
|
RED.actions.add("core:show-import-dialog",showImportNodes);
|
||||||
|
@ -965,6 +965,18 @@
|
|||||||
},
|
},
|
||||||
hide: function() {
|
hide: function() {
|
||||||
this.uiSelect.hide();
|
this.uiSelect.hide();
|
||||||
|
},
|
||||||
|
disable: function(val) {
|
||||||
|
if(val === true) {
|
||||||
|
this.uiSelect.attr("disabled", "disabled");
|
||||||
|
} else if (val === false) {
|
||||||
|
this.uiSelect.attr("disabled", null); //remove attr
|
||||||
|
} else {
|
||||||
|
this.uiSelect.attr("disabled", val); //user value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
disabled: function() {
|
||||||
|
return this.uiSelect.attr("disabled");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
@ -414,18 +414,20 @@ RED.editor = (function() {
|
|||||||
for (var cred in credDefinition) {
|
for (var cred in credDefinition) {
|
||||||
if (credDefinition.hasOwnProperty(cred)) {
|
if (credDefinition.hasOwnProperty(cred)) {
|
||||||
var input = $("#" + prefix + '-' + cred);
|
var input = $("#" + prefix + '-' + cred);
|
||||||
var value = input.val();
|
if (input.length > 0) {
|
||||||
if (credDefinition[cred].type == 'password') {
|
var value = input.val();
|
||||||
node.credentials['has_' + cred] = (value !== "");
|
if (credDefinition[cred].type == 'password') {
|
||||||
if (value == '__PWRD__') {
|
node.credentials['has_' + cred] = (value !== "");
|
||||||
continue;
|
if (value == '__PWRD__') {
|
||||||
}
|
continue;
|
||||||
changed = true;
|
}
|
||||||
|
changed = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
node.credentials[cred] = value;
|
node.credentials[cred] = value;
|
||||||
if (value != node.credentials._[cred]) {
|
if (value != node.credentials._[cred]) {
|
||||||
changed = true;
|
changed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -442,16 +444,18 @@ RED.editor = (function() {
|
|||||||
for (var d in definition.defaults) {
|
for (var d in definition.defaults) {
|
||||||
if (definition.defaults.hasOwnProperty(d)) {
|
if (definition.defaults.hasOwnProperty(d)) {
|
||||||
if (definition.defaults[d].type) {
|
if (definition.defaults[d].type) {
|
||||||
var configTypeDef = RED.nodes.getType(definition.defaults[d].type);
|
if (!definition.defaults[d]._type.array) {
|
||||||
if (configTypeDef) {
|
var configTypeDef = RED.nodes.getType(definition.defaults[d].type);
|
||||||
if (configTypeDef.exclusive) {
|
if (configTypeDef && configTypeDef.category === 'config') {
|
||||||
prepareConfigNodeButton(node,d,definition.defaults[d].type,prefix);
|
if (configTypeDef.exclusive) {
|
||||||
|
prepareConfigNodeButton(node,d,definition.defaults[d].type,prefix);
|
||||||
|
} else {
|
||||||
|
prepareConfigNodeSelect(node,d,definition.defaults[d].type,prefix);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
prepareConfigNodeSelect(node,d,definition.defaults[d].type,prefix);
|
console.log("Unknown type:", definition.defaults[d].type);
|
||||||
|
preparePropertyEditor(node,d,prefix,definition.defaults);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
console.log("Unknown type:", definition.defaults[d].type);
|
|
||||||
preparePropertyEditor(node,d,prefix,definition.defaults);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
preparePropertyEditor(node,d,prefix,definition.defaults);
|
preparePropertyEditor(node,d,prefix,definition.defaults);
|
||||||
@ -465,6 +469,7 @@ RED.editor = (function() {
|
|||||||
definition.oneditprepare.call(node);
|
definition.oneditprepare.call(node);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.log("oneditprepare",node.id,node.type,err.toString());
|
console.log("oneditprepare",node.id,node.type,err.toString());
|
||||||
|
console.log(err.stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Now invoke any change handlers added to the fields - passing true
|
// Now invoke any change handlers added to the fields - passing true
|
||||||
@ -491,11 +496,13 @@ RED.editor = (function() {
|
|||||||
populateCredentialsInputs(node, definition.credentials, node.credentials, prefix);
|
populateCredentialsInputs(node, definition.credentials, node.credentials, prefix);
|
||||||
completePrepare();
|
completePrepare();
|
||||||
} else {
|
} else {
|
||||||
$.getJSON(getCredentialsURL(node.type, node.id), function (data) {
|
getNodeCredentials(node.type, node.id, function(data) {
|
||||||
node.credentials = data;
|
if (data) {
|
||||||
node.credentials._ = $.extend(true,{},data);
|
node.credentials = data;
|
||||||
if (!/^subflow:/.test(definition.type)) {
|
node.credentials._ = $.extend(true,{},data);
|
||||||
populateCredentialsInputs(node, definition.credentials, node.credentials, prefix);
|
if (!/^subflow:/.test(definition.type)) {
|
||||||
|
populateCredentialsInputs(node, definition.credentials, node.credentials, prefix);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
completePrepare();
|
completePrepare();
|
||||||
});
|
});
|
||||||
@ -1083,8 +1090,11 @@ RED.editor = (function() {
|
|||||||
node.infoEditor = nodeInfoEditor;
|
node.infoEditor = nodeInfoEditor;
|
||||||
return nodeInfoEditor;
|
return nodeInfoEditor;
|
||||||
}
|
}
|
||||||
|
var buildingEditDialog = false;
|
||||||
|
|
||||||
function showEditDialog(node, defaultTab) {
|
function showEditDialog(node, defaultTab) {
|
||||||
|
if (buildingEditDialog) { return }
|
||||||
|
buildingEditDialog = true;
|
||||||
var editing_node = node;
|
var editing_node = node;
|
||||||
var isDefaultIcon;
|
var isDefaultIcon;
|
||||||
var defaultIcon;
|
var defaultIcon;
|
||||||
@ -1192,7 +1202,7 @@ RED.editor = (function() {
|
|||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.log("oneditsave",editing_node.id,editing_node.type,err.toString());
|
console.warn("oneditsave",editing_node.id,editing_node.type,err.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (d in editing_node._def.defaults) {
|
for (d in editing_node._def.defaults) {
|
||||||
@ -1609,6 +1619,7 @@ RED.editor = (function() {
|
|||||||
if (defaultTab) {
|
if (defaultTab) {
|
||||||
editorTabs.activateTab(defaultTab);
|
editorTabs.activateTab(defaultTab);
|
||||||
}
|
}
|
||||||
|
buildingEditDialog = false;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -1660,6 +1671,8 @@ RED.editor = (function() {
|
|||||||
* prefix - the input prefix of the parent property
|
* prefix - the input prefix of the parent property
|
||||||
*/
|
*/
|
||||||
function showEditConfigNodeDialog(name,type,id,prefix) {
|
function showEditConfigNodeDialog(name,type,id,prefix) {
|
||||||
|
if (buildingEditDialog) { return }
|
||||||
|
buildingEditDialog = true;
|
||||||
var adding = (id == "_ADD_");
|
var adding = (id == "_ADD_");
|
||||||
var node_def = RED.nodes.getType(type);
|
var node_def = RED.nodes.getType(type);
|
||||||
var editing_config_node = RED.nodes.node(id);
|
var editing_config_node = RED.nodes.node(id);
|
||||||
@ -1823,6 +1836,7 @@ RED.editor = (function() {
|
|||||||
trayBody.i18n();
|
trayBody.i18n();
|
||||||
trayFooter.i18n();
|
trayFooter.i18n();
|
||||||
finishedBuilding = true;
|
finishedBuilding = true;
|
||||||
|
buildingEditDialog = false;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -1890,7 +1904,7 @@ RED.editor = (function() {
|
|||||||
try {
|
try {
|
||||||
configTypeDef.oneditsave.call(editing_config_node);
|
configTypeDef.oneditsave.call(editing_config_node);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.log("oneditsave",editing_config_node.id,editing_config_node.type,err.toString());
|
console.warn("oneditsave",editing_config_node.id,editing_config_node.type,err.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2146,6 +2160,8 @@ RED.editor = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function showEditSubflowDialog(subflow) {
|
function showEditSubflowDialog(subflow) {
|
||||||
|
if (buildingEditDialog) { return }
|
||||||
|
buildingEditDialog = true;
|
||||||
var editing_node = subflow;
|
var editing_node = subflow;
|
||||||
editStack.push(subflow);
|
editStack.push(subflow);
|
||||||
RED.view.state(RED.state.EDITING);
|
RED.view.state(RED.state.EDITING);
|
||||||
@ -2250,6 +2266,14 @@ RED.editor = (function() {
|
|||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var newMeta = RED.subflow.exportSubflowModuleProperties(editing_node);
|
||||||
|
|
||||||
|
if (!isSameObj(editing_node.meta,newMeta)) {
|
||||||
|
changes.meta = editing_node.meta;
|
||||||
|
editing_node.meta = newMeta;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
var wasChanged = editing_node.changed;
|
var wasChanged = editing_node.changed;
|
||||||
editing_node.changed = true;
|
editing_node.changed = true;
|
||||||
@ -2356,6 +2380,16 @@ RED.editor = (function() {
|
|||||||
};
|
};
|
||||||
editorTabs.addTab(nodePropertiesTab);
|
editorTabs.addTab(nodePropertiesTab);
|
||||||
|
|
||||||
|
var moduleTab = {
|
||||||
|
id: "editor-tab-module",
|
||||||
|
label: RED._("editor-tab.module"),
|
||||||
|
name: RED._("editor-tab.module"),
|
||||||
|
content: $('<div>', {class:"red-ui-tray-content"}).appendTo(editorContent).hide(),
|
||||||
|
iconClass: "fa fa-cube",
|
||||||
|
};
|
||||||
|
editorTabs.addTab(moduleTab);
|
||||||
|
RED.subflow.buildModuleForm(moduleTab.content, editing_node);
|
||||||
|
|
||||||
var descriptionTab = {
|
var descriptionTab = {
|
||||||
id: "editor-tab-description",
|
id: "editor-tab-description",
|
||||||
label: RED._("editor-tab.description"),
|
label: RED._("editor-tab.description"),
|
||||||
@ -2384,15 +2418,17 @@ RED.editor = (function() {
|
|||||||
|
|
||||||
buildEditForm(nodePropertiesTab.content,"dialog-form","subflow-template", undefined, editing_node);
|
buildEditForm(nodePropertiesTab.content,"dialog-form","subflow-template", undefined, editing_node);
|
||||||
trayBody.i18n();
|
trayBody.i18n();
|
||||||
|
getNodeCredentials("subflow", subflow.id, function(data) {
|
||||||
$.getJSON(getCredentialsURL("subflow", subflow.id), function (data) {
|
if (data) {
|
||||||
subflow.credentials = data;
|
subflow.credentials = data;
|
||||||
subflow.credentials._ = $.extend(true,{},data);
|
subflow.credentials._ = $.extend(true,{},data);
|
||||||
|
}
|
||||||
$("#subflow-input-name").val(subflow.name);
|
$("#subflow-input-name").val(subflow.name);
|
||||||
RED.text.bidi.prepareInput($("#subflow-input-name"));
|
RED.text.bidi.prepareInput($("#subflow-input-name"));
|
||||||
|
|
||||||
finishedBuilding = true;
|
finishedBuilding = true;
|
||||||
|
buildingEditDialog = false;
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -2413,7 +2449,39 @@ RED.editor = (function() {
|
|||||||
RED.tray.show(trayOptions);
|
RED.tray.show(trayOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getNodeCredentials(type, id, done) {
|
||||||
|
var timeoutNotification;
|
||||||
|
var intialTimeout = setTimeout(function() {
|
||||||
|
timeoutNotification = RED.notify($('<p data-i18n="[prepend]editor.loadCredentials"> <img src="red/images/spin.svg"/></p>').i18n(),{fixed: true})
|
||||||
|
},800);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: getCredentialsURL(type,id),
|
||||||
|
dataType: 'json',
|
||||||
|
success: function(data) {
|
||||||
|
if (timeoutNotification) {
|
||||||
|
timeoutNotification.close();
|
||||||
|
timeoutNotification = null;
|
||||||
|
}
|
||||||
|
clearTimeout(intialTimeout);
|
||||||
|
done(data);
|
||||||
|
},
|
||||||
|
error: function(jqXHR,status,error) {
|
||||||
|
if (timeoutNotification) {
|
||||||
|
timeoutNotification.close();
|
||||||
|
timeoutNotification = null;
|
||||||
|
}
|
||||||
|
clearTimeout(intialTimeout);
|
||||||
|
RED.notify(RED._("editor.errors.credentialLoadFailed"),"error")
|
||||||
|
done(null);
|
||||||
|
},
|
||||||
|
timeout: 30000,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function showEditGroupDialog(group) {
|
function showEditGroupDialog(group) {
|
||||||
|
if (buildingEditDialog) { return }
|
||||||
|
buildingEditDialog = true;
|
||||||
var editing_node = group;
|
var editing_node = group;
|
||||||
editStack.push(group);
|
editStack.push(group);
|
||||||
RED.view.state(RED.state.EDITING);
|
RED.view.state(RED.state.EDITING);
|
||||||
@ -2457,7 +2525,7 @@ RED.editor = (function() {
|
|||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.log("oneditsave",editing_node.id,editing_node.type,err.toString());
|
console.warn("oneditsave",editing_node.id,editing_node.type,err.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (d in editing_node._def.defaults) {
|
for (d in editing_node._def.defaults) {
|
||||||
@ -2637,6 +2705,7 @@ RED.editor = (function() {
|
|||||||
prepareEditDialog(group,group._def,"node-input", function() {
|
prepareEditDialog(group,group._def,"node-input", function() {
|
||||||
trayBody.i18n();
|
trayBody.i18n();
|
||||||
finishedBuilding = true;
|
finishedBuilding = true;
|
||||||
|
buildingEditDialog = false;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -329,21 +329,26 @@ RED.palette.editor = (function() {
|
|||||||
catalogueLoadStatus.push(err||v);
|
catalogueLoadStatus.push(err||v);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
if (v.modules) {
|
if (v.modules) {
|
||||||
v.modules.forEach(function(m) {
|
var a = false;
|
||||||
loadedIndex[m.id] = m;
|
v.modules = v.modules.filter(function(m) {
|
||||||
m.index = [m.id];
|
if (checkModuleAllowed(m.id,m.version,installAllowList,installDenyList)) {
|
||||||
if (m.keywords) {
|
loadedIndex[m.id] = m;
|
||||||
m.index = m.index.concat(m.keywords);
|
m.index = [m.id];
|
||||||
|
if (m.keywords) {
|
||||||
|
m.index = m.index.concat(m.keywords);
|
||||||
|
}
|
||||||
|
if (m.types) {
|
||||||
|
m.index = m.index.concat(m.types);
|
||||||
|
}
|
||||||
|
if (m.updated_at) {
|
||||||
|
m.timestamp = new Date(m.updated_at).getTime();
|
||||||
|
} else {
|
||||||
|
m.timestamp = 0;
|
||||||
|
}
|
||||||
|
m.index = m.index.join(",").toLowerCase();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (m.types) {
|
return false;
|
||||||
m.index = m.index.concat(m.types);
|
|
||||||
}
|
|
||||||
if (m.updated_at) {
|
|
||||||
m.timestamp = new Date(m.updated_at).getTime();
|
|
||||||
} else {
|
|
||||||
m.timestamp = 0;
|
|
||||||
}
|
|
||||||
m.index = m.index.join(",").toLowerCase();
|
|
||||||
})
|
})
|
||||||
loadedList = loadedList.concat(v.modules);
|
loadedList = loadedList.concat(v.modules);
|
||||||
}
|
}
|
||||||
@ -437,11 +442,84 @@ RED.palette.editor = (function() {
|
|||||||
return -1 * (A.info.timestamp-B.info.timestamp);
|
return -1 * (A.info.timestamp-B.info.timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var installAllowList = ['*'];
|
||||||
|
var installDenyList = [];
|
||||||
|
|
||||||
|
function parseModuleList(list) {
|
||||||
|
list = list || ["*"];
|
||||||
|
return list.map(function(rule) {
|
||||||
|
var m = /^(.+?)(?:@(.*))?$/.exec(rule);
|
||||||
|
var wildcardPos = m[1].indexOf("*");
|
||||||
|
wildcardPos = wildcardPos===-1?Infinity:wildcardPos;
|
||||||
|
|
||||||
|
return {
|
||||||
|
module: new RegExp("^"+m[1].replace(/\*/g,".*")+"$"),
|
||||||
|
version: m[2],
|
||||||
|
wildcardPos: wildcardPos
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkAgainstList(module,version,list) {
|
||||||
|
for (var i=0;i<list.length;i++) {
|
||||||
|
var rule = list[i];
|
||||||
|
if (rule.module.test(module)) {
|
||||||
|
// Without a full semver library in the editor,
|
||||||
|
// we skip the version check.
|
||||||
|
// Not ideal - but will get caught in the runtime
|
||||||
|
// if the user tries to install.
|
||||||
|
return rule;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkModuleAllowed(module,version,allowList,denyList) {
|
||||||
|
if (!allowList && !denyList) {
|
||||||
|
// Default to allow
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (allowList.length === 0 && denyList.length === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var allowedRule = checkAgainstList(module,version,allowList);
|
||||||
|
var deniedRule = checkAgainstList(module,version,denyList);
|
||||||
|
// console.log("A",allowedRule)
|
||||||
|
// console.log("D",deniedRule)
|
||||||
|
|
||||||
|
if (allowedRule && !deniedRule) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!allowedRule && deniedRule) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!allowedRule && !deniedRule) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (allowedRule.wildcardPos !== deniedRule.wildcardPos) {
|
||||||
|
return allowedRule.wildcardPos > deniedRule.wildcardPos
|
||||||
|
} else {
|
||||||
|
// First wildcard in same position.
|
||||||
|
// Go with the longer matching rule. This isn't going to be 100%
|
||||||
|
// right, but we are deep into edge cases at this point.
|
||||||
|
return allowedRule.module.toString().length > deniedRule.module.toString().length
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
if (RED.settings.theme('palette.editable') === false) {
|
if (RED.settings.get('externalModules.palette.allowInstall', true) === false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var settingsAllowList = RED.settings.get("externalModules.palette.allowList")
|
||||||
|
var settingsDenyList = RED.settings.get("externalModules.palette.denyList")
|
||||||
|
if (settingsAllowList || settingsDenyList) {
|
||||||
|
installAllowList = settingsAllowList;
|
||||||
|
installDenyList = settingsDenyList
|
||||||
|
}
|
||||||
|
installAllowList = parseModuleList(installAllowList);
|
||||||
|
installDenyList = parseModuleList(installDenyList);
|
||||||
|
|
||||||
createSettingsPane();
|
createSettingsPane();
|
||||||
|
|
||||||
RED.userSettings.add({
|
RED.userSettings.add({
|
||||||
@ -880,7 +958,7 @@ RED.palette.editor = (function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (RED.settings.theme('palette.upload') !== false) {
|
if (RED.settings.get('externalModules.palette.allowUpload', true) !== false) {
|
||||||
var uploadSpan = $('<span class="button-group">').prependTo(toolBar);
|
var uploadSpan = $('<span class="button-group">').prependTo(toolBar);
|
||||||
var uploadButton = $('<button type="button" class="red-ui-sidebar-header-button red-ui-palette-editor-upload-button"><label><i class="fa fa-upload"></i><form id="red-ui-palette-editor-upload-form" enctype="multipart/form-data"><input name="tarball" type="file" accept=".tgz"></label></button>').appendTo(uploadSpan);
|
var uploadButton = $('<button type="button" class="red-ui-sidebar-header-button red-ui-palette-editor-upload-button"><label><i class="fa fa-upload"></i><form id="red-ui-palette-editor-upload-form" enctype="multipart/form-data"><input name="tarball" type="file" accept=".tgz"></label></button>').appendTo(uploadSpan);
|
||||||
|
|
||||||
@ -962,7 +1040,7 @@ RED.palette.editor = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function update(entry,version,url,container,done) {
|
function update(entry,version,url,container,done) {
|
||||||
if (RED.settings.theme('palette.editable') === false) {
|
if (RED.settings.get('externalModules.palette.allowInstall', true) === false) {
|
||||||
done(new Error('Palette not editable'));
|
done(new Error('Palette not editable'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1021,7 +1099,7 @@ RED.palette.editor = (function() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
function remove(entry,container,done) {
|
function remove(entry,container,done) {
|
||||||
if (RED.settings.theme('palette.editable') === false) {
|
if (RED.settings.get('externalModules.palette.allowInstall', true) === false) {
|
||||||
done(new Error('Palette not editable'));
|
done(new Error('Palette not editable'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1078,7 +1156,7 @@ RED.palette.editor = (function() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
function install(entry,container,done) {
|
function install(entry,container,done) {
|
||||||
if (RED.settings.theme('palette.editable') === false) {
|
if (RED.settings.get('externalModules.palette.allowInstall', true) === false) {
|
||||||
done(new Error('Palette not editable'));
|
done(new Error('Palette not editable'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -97,13 +97,18 @@ RED.palette = (function() {
|
|||||||
label = RED.utils.sanitize(label);
|
label = RED.utils.sanitize(label);
|
||||||
|
|
||||||
|
|
||||||
var words = label.split(/[ -]/);
|
var words = label.split(/([ -]|\\n )/);
|
||||||
|
|
||||||
var displayLines = [];
|
var displayLines = [];
|
||||||
|
|
||||||
var currentLine = "";
|
var currentLine = "";
|
||||||
for (var i=0;i<words.length;i++) {
|
for (var i=0;i<words.length;i++) {
|
||||||
var word = words[i];
|
var word = words[i];
|
||||||
|
if (word === "\\n ") {
|
||||||
|
displayLines.push(currentLine);
|
||||||
|
currentLine = "";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
var sep = (i == 0) ? "" : " ";
|
var sep = (i == 0) ? "" : " ";
|
||||||
var newWidth = RED.view.calculateTextWidth(currentLine+sep+word, "red-ui-palette-label");
|
var newWidth = RED.view.calculateTextWidth(currentLine+sep+word, "red-ui-palette-label");
|
||||||
if (newWidth < nodeWidth) {
|
if (newWidth < nodeWidth) {
|
||||||
@ -147,7 +152,7 @@ RED.palette = (function() {
|
|||||||
var popOverContent;
|
var popOverContent;
|
||||||
try {
|
try {
|
||||||
var l = "<p><b>"+RED.text.bidi.enforceTextDirectionWithUCC(label)+"</b></p>";
|
var l = "<p><b>"+RED.text.bidi.enforceTextDirectionWithUCC(label)+"</b></p>";
|
||||||
popOverContent = $('<div></div>').append($(l+(info?info:$("script[data-help-name='"+type+"']").html()||"<p>"+RED._("palette.noInfo")+"</p>").trim())
|
popOverContent = $('<div></div>').append($(l+(info?info:RED.nodes.getNodeHelp(type)||"<p>"+RED._("palette.noInfo")+"</p>").trim())
|
||||||
.filter(function(n) {
|
.filter(function(n) {
|
||||||
return (this.nodeType == 1 && this.nodeName == "P") || (this.nodeType == 3 && this.textContent.trim().length > 0)
|
return (this.nodeType == 1 && this.nodeName == "P") || (this.nodeType == 3 && this.textContent.trim().length > 0)
|
||||||
}).slice(0,2));
|
}).slice(0,2));
|
||||||
@ -165,7 +170,16 @@ RED.palette = (function() {
|
|||||||
metaData = typeInfo.set.module+" : ";
|
metaData = typeInfo.set.module+" : ";
|
||||||
}
|
}
|
||||||
metaData += type;
|
metaData += type;
|
||||||
$('<button type="button" onclick="RED.sidebar.help.show(\''+type+'\'); return false;" class="red-ui-button red-ui-button-small" style="float: right"><i class="fa fa-book"></i></button>').appendTo(popOverContent)
|
|
||||||
|
if (/^subflow:/.test(type)) {
|
||||||
|
$('<button type="button" onclick="RED.workspaces.show(\''+type.substring(8).replace(/'/g,"\\'")+'\'); return false;" class="red-ui-button red-ui-button-small" style="float: right; margin-left: 5px;"><i class="fa fa-pencil"></i></button>').appendTo(popOverContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
var safeType = type.replace(/'/g,"\\'");
|
||||||
|
|
||||||
|
$('<button type="button" onclick="RED.search.show(\'type:'+safeType+'\'); return false;" class="red-ui-button red-ui-button-small" style="float: right; margin-left: 5px;"><i class="fa fa-search"></i></button>').appendTo(popOverContent)
|
||||||
|
$('<button type="button" onclick="RED.sidebar.help.show(\''+safeType+'\'); return false;" class="red-ui-button red-ui-button-small" style="float: right; margin-left: 5px;"><i class="fa fa-book"></i></button>').appendTo(popOverContent)
|
||||||
|
|
||||||
$('<p>',{style:"font-size: 0.8em"}).text(metaData).appendTo(popOverContent);
|
$('<p>',{style:"font-size: 0.8em"}).text(metaData).appendTo(popOverContent);
|
||||||
}
|
}
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
@ -264,27 +278,6 @@ RED.palette = (function() {
|
|||||||
|
|
||||||
d.data('popover',popover);
|
d.data('popover',popover);
|
||||||
|
|
||||||
// $(d).popover({
|
|
||||||
// title:d.type,
|
|
||||||
// placement:"right",
|
|
||||||
// trigger: "hover",
|
|
||||||
// delay: { show: 750, hide: 50 },
|
|
||||||
// html: true,
|
|
||||||
// container:'body'
|
|
||||||
// });
|
|
||||||
// d.on("click", function() {
|
|
||||||
// RED.view.focus();
|
|
||||||
// var helpText;
|
|
||||||
// if (nt.indexOf("subflow:") === 0) {
|
|
||||||
// helpText = RED.utils.renderMarkdown(RED.nodes.subflow(nt.substring(8)).info||"")||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
|
||||||
// } else {
|
|
||||||
// helpText = $("script[data-help-name='"+d.attr("data-palette-type")+"']").html()||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
|
||||||
// }
|
|
||||||
// // Don't look too closely. RED.sidebar.info.set will set the 'Description'
|
|
||||||
// // section of the sidebar. Pass in the title of the Help section so it looks
|
|
||||||
// // right.
|
|
||||||
// RED.sidebar.type.show(helpText,RED._("sidebar.info.nodeHelp"));
|
|
||||||
// });
|
|
||||||
var chart = $("#red-ui-workspace-chart");
|
var chart = $("#red-ui-workspace-chart");
|
||||||
var chartSVG = $("#red-ui-workspace-chart>svg").get(0);
|
var chartSVG = $("#red-ui-workspace-chart>svg").get(0);
|
||||||
var activeSpliceLink;
|
var activeSpliceLink;
|
||||||
@ -417,7 +410,8 @@ RED.palette = (function() {
|
|||||||
RED.workspaces.show(nt.substring(8));
|
RED.workspaces.show(nt.substring(8));
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
});
|
});
|
||||||
nodeInfo = RED.utils.renderMarkdown(def.info||"");
|
var subflow = RED.nodes.subflow(nt.substring(8));
|
||||||
|
nodeInfo = RED.utils.renderMarkdown(subflow.info||"");
|
||||||
}
|
}
|
||||||
setLabel(nt,d,label,nodeInfo);
|
setLabel(nt,d,label,nodeInfo);
|
||||||
|
|
||||||
|
@ -465,7 +465,7 @@ RED.projects.settings = (function() {
|
|||||||
metaRow = $('<div class="red-ui-palette-module-meta"></div>').appendTo(headerRow);
|
metaRow = $('<div class="red-ui-palette-module-meta"></div>').appendTo(headerRow);
|
||||||
var buttons = $('<div class="red-ui-palette-module-button-group"></div>').appendTo(metaRow);
|
var buttons = $('<div class="red-ui-palette-module-button-group"></div>').appendTo(metaRow);
|
||||||
if (RED.user.hasPermission("projects.write")) {
|
if (RED.user.hasPermission("projects.write")) {
|
||||||
if (!entry.installed && RED.settings.theme('palette.editable') !== false) {
|
if (!entry.installed && RED.settings.get('externalModules.palette.allowInstall', true) !== false) {
|
||||||
$('<a href="#" class="red-ui-button red-ui-button-small">' + RED._("sidebar.project.projectSettings.install") + '</a>').appendTo(buttons)
|
$('<a href="#" class="red-ui-button red-ui-button-small">' + RED._("sidebar.project.projectSettings.install") + '</a>').appendTo(buttons)
|
||||||
.on("click", function(evt) {
|
.on("click", function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
|
@ -43,9 +43,11 @@ RED.projects.userSettings = (function() {
|
|||||||
|
|
||||||
function createWorkflowSection(pane) {
|
function createWorkflowSection(pane) {
|
||||||
|
|
||||||
|
var defaultWorkflowMode = RED.settings.theme("projects.workflow.mode","manual");
|
||||||
|
|
||||||
var currentGitSettings = RED.settings.get('git') || {};
|
var currentGitSettings = RED.settings.get('git') || {};
|
||||||
currentGitSettings.workflow = currentGitSettings.workflow || {};
|
currentGitSettings.workflow = currentGitSettings.workflow || {};
|
||||||
currentGitSettings.workflow.mode = currentGitSettings.workflow.mode || "manual";
|
currentGitSettings.workflow.mode = currentGitSettings.workflow.mode || defaultWorkflowMode;
|
||||||
|
|
||||||
var title = $('<h3></h3>').text(RED._("editor:sidebar.project.userSettings.workflow")).appendTo(pane);
|
var title = $('<h3></h3>').text(RED._("editor:sidebar.project.userSettings.workflow")).appendTo(pane);
|
||||||
|
|
||||||
|
@ -294,7 +294,10 @@ RED.sidebar.versionControl = (function() {
|
|||||||
// TODO: this is a full refresh of the files - should be able to
|
// TODO: this is a full refresh of the files - should be able to
|
||||||
// just do an incremental refresh
|
// just do an incremental refresh
|
||||||
|
|
||||||
var workflowMode = ((RED.settings.get('git') || {}).workflow || {}).mode || "manual";
|
// Get the default workflow mode from theme settings
|
||||||
|
var defaultWorkflowMode = RED.settings.theme("projects.workflow.mode","manual");
|
||||||
|
// Check for the user-defined choice of mode
|
||||||
|
var workflowMode = ((RED.settings.get('git') || {}).workflow || {}).mode || defaultWorkflowMode;
|
||||||
if (workflowMode === 'auto') {
|
if (workflowMode === 'auto') {
|
||||||
refresh(true);
|
refresh(true);
|
||||||
} else {
|
} else {
|
||||||
|
@ -47,6 +47,37 @@ RED.subflow = (function() {
|
|||||||
'</div>'+
|
'</div>'+
|
||||||
'</script>';
|
'</script>';
|
||||||
|
|
||||||
|
var _subflowModulePaneTemplate = '<form class="dialog-form form-horizontal" autocomplete="off">'+
|
||||||
|
'<div class="form-row">'+
|
||||||
|
'<label for="subflow-input-module-module" data-i18n="[append]editor:subflow.module"><i class="fa fa-cube"></i> </label>'+
|
||||||
|
'<input style="width: calc(100% - 110px)" type="text" id="subflow-input-module-module" data-i18n="[placeholder]common.label.name">'+
|
||||||
|
'</div>'+
|
||||||
|
'<div class="form-row">'+
|
||||||
|
'<label for="subflow-input-module-type" data-i18n="[append]editor:subflow.type"> </label>'+
|
||||||
|
'<input style="width: calc(100% - 110px)" type="text" id="subflow-input-module-type">'+
|
||||||
|
'</div>'+
|
||||||
|
'<div class="form-row">'+
|
||||||
|
'<label for="subflow-input-module-version" data-i18n="[append]editor:subflow.version"></label>'+
|
||||||
|
'<input style="width: calc(100% - 110px)" type="text" id="subflow-input-module-version" data-i18n="[placeholder]editor:subflow.versionPlaceholder">'+
|
||||||
|
'</div>'+
|
||||||
|
'<div class="form-row">'+
|
||||||
|
'<label for="subflow-input-module-desc" data-i18n="[append]editor:subflow.desc"></label>'+
|
||||||
|
'<input style="width: calc(100% - 110px)" type="text" id="subflow-input-module-desc">'+
|
||||||
|
'</div>'+
|
||||||
|
'<div class="form-row">'+
|
||||||
|
'<label for="subflow-input-module-license" data-i18n="[append]editor:subflow.license"></label>'+
|
||||||
|
'<input style="width: calc(100% - 110px)" type="text" id="subflow-input-module-license">'+
|
||||||
|
'</div>'+
|
||||||
|
'<div class="form-row">'+
|
||||||
|
'<label for="subflow-input-module-author" data-i18n="[append]editor:subflow.author"></label>'+
|
||||||
|
'<input style="width: calc(100% - 110px)" type="text" id="subflow-input-module-author" data-i18n="[placeholder]editor:subflow.authorPlaceholder">'+
|
||||||
|
'</div>'+
|
||||||
|
'<div class="form-row">'+
|
||||||
|
'<label for="subflow-input-module-keywords" data-i18n="[append]editor:subflow.keys"></label>'+
|
||||||
|
'<input style="width: calc(100% - 110px)" type="text" id="subflow-input-module-keywords" data-i18n="[placeholder]editor:subflow.keysPlaceholder">'+
|
||||||
|
'</div>'+
|
||||||
|
'</form>';
|
||||||
|
|
||||||
function findAvailableSubflowIOPosition(subflow,isInput) {
|
function findAvailableSubflowIOPosition(subflow,isInput) {
|
||||||
var pos = {x:50,y:30};
|
var pos = {x:50,y:30};
|
||||||
if (!isInput) {
|
if (!isInput) {
|
||||||
@ -433,12 +464,43 @@ RED.subflow = (function() {
|
|||||||
|
|
||||||
$("#red-ui-subflow-delete").on("click", function(event) {
|
$("#red-ui-subflow-delete").on("click", function(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
var startDirty = RED.nodes.dirty();
|
var subflow = RED.nodes.subflow(RED.workspaces.active());
|
||||||
var historyEvent = removeSubflow(RED.workspaces.active());
|
if (subflow.instances.length > 0) {
|
||||||
historyEvent.t = 'delete';
|
var msg = $('<div>')
|
||||||
historyEvent.dirty = startDirty;
|
$('<p>').text(RED._("subflow.subflowInstances",{count: subflow.instances.length})).appendTo(msg);
|
||||||
|
$('<p>').text(RED._("subflow.confirmDelete")).appendTo(msg);
|
||||||
|
var confirmDeleteNotification = RED.notify(msg, {
|
||||||
|
modal: true,
|
||||||
|
fixed: true,
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
text: RED._('common.label.cancel'),
|
||||||
|
click: function() {
|
||||||
|
confirmDeleteNotification.close();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: RED._('workspace.confirmDelete'),
|
||||||
|
class: "primary",
|
||||||
|
click: function() {
|
||||||
|
confirmDeleteNotification.close();
|
||||||
|
completeDelete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
RED.history.push(historyEvent);
|
return;
|
||||||
|
} else {
|
||||||
|
completeDelete();
|
||||||
|
}
|
||||||
|
function completeDelete() {
|
||||||
|
var startDirty = RED.nodes.dirty();
|
||||||
|
var historyEvent = removeSubflow(RED.workspaces.active());
|
||||||
|
historyEvent.t = 'delete';
|
||||||
|
historyEvent.dirty = startDirty;
|
||||||
|
RED.history.push(historyEvent);
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -993,6 +1055,7 @@ RED.subflow = (function() {
|
|||||||
icon: "",
|
icon: "",
|
||||||
type: "cred"
|
type: "cred"
|
||||||
}
|
}
|
||||||
|
opt.ui.type = "cred";
|
||||||
} else {
|
} else {
|
||||||
opt.ui = opt.ui || {
|
opt.ui = opt.ui || {
|
||||||
icon: "",
|
icon: "",
|
||||||
@ -1488,6 +1551,7 @@ RED.subflow = (function() {
|
|||||||
var locale = RED.i18n.lang();
|
var locale = RED.i18n.lang();
|
||||||
var labelText = lookupLabel(labels, labels["en-US"]||tenv.name, locale);
|
var labelText = lookupLabel(labels, labels["en-US"]||tenv.name, locale);
|
||||||
var label = $('<label>').appendTo(row);
|
var label = $('<label>').appendTo(row);
|
||||||
|
$('<span> </span>').appendTo(row);
|
||||||
var labelContainer = $('<span></span>').appendTo(label);
|
var labelContainer = $('<span></span>').appendTo(label);
|
||||||
if (ui.icon) {
|
if (ui.icon) {
|
||||||
var newPath = RED.utils.separateIconPath(ui.icon);
|
var newPath = RED.utils.separateIconPath(ui.icon);
|
||||||
@ -1723,22 +1787,54 @@ RED.subflow = (function() {
|
|||||||
parentEnv[env.name] = item;
|
parentEnv[env.name] = item;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
if (node.env) {
|
||||||
|
for (var i = 0; i < node.env.length; i++) {
|
||||||
if (node.env) {
|
var env = node.env[i];
|
||||||
for (var i = 0; i < node.env.length; i++) {
|
if (parentEnv.hasOwnProperty(env.name)) {
|
||||||
var env = node.env[i];
|
parentEnv[env.name].type = env.type;
|
||||||
if (parentEnv.hasOwnProperty(env.name)) {
|
parentEnv[env.name].value = env.value;
|
||||||
parentEnv[env.name].type = env.type;
|
} else {
|
||||||
parentEnv[env.name].value = env.value;
|
// envList.push({
|
||||||
} else {
|
// name: env.name,
|
||||||
// envList.push({
|
// type: env.type,
|
||||||
// name: env.name,
|
// value: env.value,
|
||||||
// type: env.type,
|
// });
|
||||||
// value: env.value,
|
}
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (node._def.subflowModule) {
|
||||||
|
var keys = Object.keys(node._def.defaults);
|
||||||
|
keys.forEach(function(name) {
|
||||||
|
if (name !== 'name') {
|
||||||
|
var prop = node._def.defaults[name];
|
||||||
|
var nodeProp = node[name];
|
||||||
|
var nodePropType;
|
||||||
|
var nodePropValue = nodeProp;
|
||||||
|
if (prop.ui && prop.ui.type === "cred") {
|
||||||
|
nodePropType = "cred";
|
||||||
|
} else {
|
||||||
|
switch(typeof nodeProp) {
|
||||||
|
case "string": nodePropType = "str"; break;
|
||||||
|
case "number": nodePropType = "num"; break;
|
||||||
|
case "boolean": nodePropType = "bool"; nodePropValue = nodeProp?"true":"false"; break;
|
||||||
|
default:
|
||||||
|
nodePropType = nodeProp.type;
|
||||||
|
nodePropValue = nodeProp.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var item = {
|
||||||
|
name: name,
|
||||||
|
type: nodePropType,
|
||||||
|
value: nodePropValue,
|
||||||
|
parent: {
|
||||||
|
type: prop.type,
|
||||||
|
value: prop.value
|
||||||
|
},
|
||||||
|
ui: $.extend(true,{},prop.ui)
|
||||||
|
}
|
||||||
|
envList.push(item);
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return envList;
|
return envList;
|
||||||
}
|
}
|
||||||
@ -1859,6 +1955,126 @@ RED.subflow = (function() {
|
|||||||
buildPropertiesList(list, node);
|
buildPropertiesList(list, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setupInputValidation(input,validator) {
|
||||||
|
var errorTip;
|
||||||
|
var validateTimeout;
|
||||||
|
|
||||||
|
var validateFunction = function() {
|
||||||
|
if (validateTimeout) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
validateTimeout = setTimeout(function() {
|
||||||
|
var error = validator(input.val());
|
||||||
|
// if (!error && errorTip) {
|
||||||
|
// errorTip.close();
|
||||||
|
// errorTip = null;
|
||||||
|
// } else if (error && !errorTip) {
|
||||||
|
// errorTip = RED.popover.create({
|
||||||
|
// tooltip: true,
|
||||||
|
// target:input,
|
||||||
|
// size: "small",
|
||||||
|
// direction: "bottom",
|
||||||
|
// content: error,
|
||||||
|
// }).open();
|
||||||
|
// }
|
||||||
|
input.toggleClass("input-error",!!error);
|
||||||
|
validateTimeout = null;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
input.on("change keyup paste", validateFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildModuleForm(container, node) {
|
||||||
|
$(_subflowModulePaneTemplate).appendTo(container);
|
||||||
|
var moduleProps = node.meta || {};
|
||||||
|
[
|
||||||
|
'module',
|
||||||
|
'type',
|
||||||
|
'version',
|
||||||
|
'author',
|
||||||
|
'desc',
|
||||||
|
'keywords',
|
||||||
|
'license'
|
||||||
|
].forEach(function(property) {
|
||||||
|
$("#subflow-input-module-"+property).val(moduleProps[property]||"")
|
||||||
|
})
|
||||||
|
$("#subflow-input-module-type").attr("placeholder",node.id);
|
||||||
|
|
||||||
|
setupInputValidation($("#subflow-input-module-module"), function(newValue) {
|
||||||
|
newValue = newValue.trim();
|
||||||
|
var isValid = newValue.length < 215;
|
||||||
|
isValid = isValid && !/^[._]/.test(newValue);
|
||||||
|
isValid = isValid && !/[A-Z]/.test(newValue);
|
||||||
|
if (newValue !== encodeURIComponent(newValue)) {
|
||||||
|
var m = /^@([^\/]+)\/([^\/]+)$/.exec(newValue);
|
||||||
|
if (m) {
|
||||||
|
isValid = isValid && (m[1] === encodeURIComponent(m[1]) && m[2] === encodeURIComponent(m[2]))
|
||||||
|
} else {
|
||||||
|
isValid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isValid?"":"Invalid module name"
|
||||||
|
})
|
||||||
|
setupInputValidation($("#subflow-input-module-version"), function(newValue) {
|
||||||
|
newValue = newValue.trim();
|
||||||
|
var isValid = newValue === "" ||
|
||||||
|
/^(\d|[1-9]\d*)\.(\d|[1-9]\d*)\.(\d|[1-9]\d*)(-(0|[1-9A-Za-z-][0-9A-Za-z-]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*)(\.(0|[1-9A-Za-z-][0-9A-Za-z-]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*))*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$/.test(newValue);
|
||||||
|
return isValid?"":"Invalid version number"
|
||||||
|
})
|
||||||
|
|
||||||
|
var licenses = ["none", "Apache-2.0", "BSD-3-Clause", "BSD-2-Clause", "GPL-2.0", "GPL-3.0", "MIT", "MPL-2.0", "CDDL-1.0", "EPL-2.0"];
|
||||||
|
var typedLicenses = {
|
||||||
|
types: licenses.map(function(l) {
|
||||||
|
return {
|
||||||
|
value: l,
|
||||||
|
label: l === "none" ? RED._("editor:subflow.licenseNone") : l,
|
||||||
|
hasValue: false
|
||||||
|
};
|
||||||
|
})
|
||||||
|
}
|
||||||
|
typedLicenses.types.push({
|
||||||
|
value:"_custom_", label:RED._("editor:subflow.licenseOther"), icon:"red/images/typedInput/az.svg"
|
||||||
|
})
|
||||||
|
if (!moduleProps.license) {
|
||||||
|
typedLicenses.default = "none";
|
||||||
|
} else if (licenses.indexOf(moduleProps.license) > -1) {
|
||||||
|
typedLicenses.default = moduleProps.license;
|
||||||
|
} else {
|
||||||
|
typedLicenses.default = "_custom_";
|
||||||
|
}
|
||||||
|
$("#subflow-input-module-license").typedInput(typedLicenses)
|
||||||
|
}
|
||||||
|
|
||||||
|
function exportSubflowModuleProperties(node) {
|
||||||
|
var value;
|
||||||
|
var moduleProps = {};
|
||||||
|
[
|
||||||
|
'module',
|
||||||
|
'type',
|
||||||
|
'version',
|
||||||
|
'author',
|
||||||
|
'desc',
|
||||||
|
'keywords'
|
||||||
|
].forEach(function(property) {
|
||||||
|
value = $("#subflow-input-module-"+property).val().trim();
|
||||||
|
if (value) {
|
||||||
|
moduleProps[property] = value;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
var selectedLicenseType = $("#subflow-input-module-license").typedInput("type");
|
||||||
|
|
||||||
|
if (selectedLicenseType === '_custom_') {
|
||||||
|
value = $("#subflow-input-module-license").val();
|
||||||
|
if (value) {
|
||||||
|
moduleProps.license = value;
|
||||||
|
}
|
||||||
|
} else if (selectedLicenseType !== "none") {
|
||||||
|
moduleProps.license = selectedLicenseType;
|
||||||
|
}
|
||||||
|
return moduleProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
init: init,
|
init: init,
|
||||||
createSubflow: createSubflow,
|
createSubflow: createSubflow,
|
||||||
@ -1872,9 +2088,11 @@ RED.subflow = (function() {
|
|||||||
|
|
||||||
buildEditForm: buildEditForm,
|
buildEditForm: buildEditForm,
|
||||||
buildPropertiesForm: buildPropertiesForm,
|
buildPropertiesForm: buildPropertiesForm,
|
||||||
|
buildModuleForm: buildModuleForm,
|
||||||
|
|
||||||
exportSubflowTemplateEnv: exportEnvList,
|
exportSubflowTemplateEnv: exportEnvList,
|
||||||
exportSubflowInstanceEnv: exportSubflowInstanceEnv
|
exportSubflowInstanceEnv: exportSubflowInstanceEnv,
|
||||||
|
exportSubflowModuleProperties: exportSubflowModuleProperties
|
||||||
|
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
@ -247,7 +247,7 @@ RED.sidebar.help = (function() {
|
|||||||
helpText = (RED.utils.renderMarkdown(subflowNode.info||"")||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>'));
|
helpText = (RED.utils.renderMarkdown(subflowNode.info||"")||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>'));
|
||||||
title = subflowNode.name || nodeType;
|
title = subflowNode.name || nodeType;
|
||||||
} else {
|
} else {
|
||||||
helpText = $("script[data-help-name='"+nodeType+"']").html()||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
helpText = RED.nodes.getNodeHelp(nodeType)||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
||||||
title = nodeType;
|
title = nodeType;
|
||||||
}
|
}
|
||||||
setInfoText(title, helpText, helpSection);
|
setInfoText(title, helpText, helpSection);
|
||||||
|
@ -119,34 +119,17 @@ RED.sidebar.info.outliner = (function() {
|
|||||||
return div;
|
return div;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSubflowLabel(n) {
|
|
||||||
|
|
||||||
var div = $('<div>',{class:"red-ui-info-outline-item"});
|
|
||||||
RED.utils.createNodeIcon(n).appendTo(div);
|
|
||||||
var contentDiv = $('<div>',{class:"red-ui-search-result-description"}).appendTo(div);
|
|
||||||
var labelText = getNodeLabelText(n);
|
|
||||||
var label = $('<div>',{class:"red-ui-search-result-node-label red-ui-info-outline-item-label"}).appendTo(contentDiv);
|
|
||||||
if (labelText) {
|
|
||||||
label.text(labelText)
|
|
||||||
} else {
|
|
||||||
label.html(" ")
|
|
||||||
}
|
|
||||||
|
|
||||||
addControls(n, div);
|
|
||||||
|
|
||||||
return div;
|
|
||||||
|
|
||||||
|
|
||||||
// var div = $('<div>',{class:"red-ui-info-outline-item red-ui-info-outline-item-flow"});
|
|
||||||
// var contentDiv = $('<div>',{class:"red-ui-search-result-description red-ui-info-outline-item-label"}).appendTo(div);
|
|
||||||
// contentDiv.text(n.name || n.id);
|
|
||||||
// addControls(n, div);
|
|
||||||
// return div;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addControls(n,div) {
|
function addControls(n,div) {
|
||||||
var controls = $('<div>',{class:"red-ui-info-outline-item-controls red-ui-info-outline-item-hover-controls"}).appendTo(div);
|
var controls = $('<div>',{class:"red-ui-info-outline-item-controls red-ui-info-outline-item-hover-controls"}).appendTo(div);
|
||||||
|
|
||||||
|
if (n.type === "subflow") {
|
||||||
|
var subflowInstanceBadge = $('<button type="button" class="red-ui-info-outline-item-control-users red-ui-button red-ui-button-small"><i class="fa fa-toggle-right"></i></button>').text(n.instances.length).appendTo(controls).on("click",function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
|
RED.search.show("type:subflow:"+n.id);
|
||||||
|
})
|
||||||
|
// RED.popover.tooltip(userCountBadge,function() { return RED._('editor.nodesUse',{count:n.users.length})});
|
||||||
|
}
|
||||||
if (n._def.category === "config" && n.type !== "group") {
|
if (n._def.category === "config" && n.type !== "group") {
|
||||||
var userCountBadge = $('<button type="button" class="red-ui-info-outline-item-control-users red-ui-button red-ui-button-small"><i class="fa fa-toggle-right"></i></button>').text(n.users.length).appendTo(controls).on("click",function(evt) {
|
var userCountBadge = $('<button type="button" class="red-ui-info-outline-item-control-users red-ui-button red-ui-button-small"><i class="fa fa-toggle-right"></i></button>').text(n.users.length).appendTo(controls).on("click",function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
@ -169,7 +152,7 @@ RED.sidebar.info.outliner = (function() {
|
|||||||
// evt.stopPropagation();
|
// evt.stopPropagation();
|
||||||
// RED.view.reveal(n.id);
|
// RED.view.reveal(n.id);
|
||||||
// })
|
// })
|
||||||
if (n.type !== 'group' && n.type !== 'subflow') {
|
if (n.type !== 'subflow') {
|
||||||
var toggleButton = $('<button type="button" class="red-ui-info-outline-item-control-disable red-ui-button red-ui-button-small"><i class="fa fa-circle-thin"></i><i class="fa fa-ban"></i></button>').appendTo(controls).on("click",function(evt) {
|
var toggleButton = $('<button type="button" class="red-ui-info-outline-item-control-disable red-ui-button red-ui-button-small"><i class="fa fa-circle-thin"></i><i class="fa fa-ban"></i></button>').appendTo(controls).on("click",function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
evt.stopPropagation();
|
evt.stopPropagation();
|
||||||
@ -179,6 +162,46 @@ RED.sidebar.info.outliner = (function() {
|
|||||||
} else {
|
} else {
|
||||||
RED.workspaces.disable(n.id)
|
RED.workspaces.disable(n.id)
|
||||||
}
|
}
|
||||||
|
} else if (n.type === 'group') {
|
||||||
|
var groupNodes = RED.group.getNodes(n,true);
|
||||||
|
var groupHistoryEvent = {
|
||||||
|
t:'multi',
|
||||||
|
events:[],
|
||||||
|
dirty: RED.nodes.dirty()
|
||||||
|
}
|
||||||
|
var targetState;
|
||||||
|
groupNodes.forEach(function(n) {
|
||||||
|
if (n.type !== 'group') {
|
||||||
|
if (targetState === undefined) {
|
||||||
|
targetState = !n.d;
|
||||||
|
}
|
||||||
|
var state = !!n.d;
|
||||||
|
if (state !== targetState) {
|
||||||
|
var historyEvent = {
|
||||||
|
t: "edit",
|
||||||
|
node: n,
|
||||||
|
changed: n.changed,
|
||||||
|
changes: {
|
||||||
|
d: n.d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (n.d) {
|
||||||
|
delete n.d;
|
||||||
|
} else {
|
||||||
|
n.d = true;
|
||||||
|
}
|
||||||
|
n.dirty = true;
|
||||||
|
n.changed = true;
|
||||||
|
RED.events.emit("nodes:change",n);
|
||||||
|
groupHistoryEvent.events.push(historyEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (groupHistoryEvent.events.length > 0) {
|
||||||
|
RED.history.push(groupHistoryEvent);
|
||||||
|
RED.nodes.dirty(true)
|
||||||
|
RED.view.redraw();
|
||||||
|
}
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
// TODO: this ought to be a utility function in RED.nodes
|
// TODO: this ought to be a utility function in RED.nodes
|
||||||
var historyEvent = {
|
var historyEvent = {
|
||||||
@ -198,11 +221,15 @@ RED.sidebar.info.outliner = (function() {
|
|||||||
n.dirty = true;
|
n.dirty = true;
|
||||||
n.changed = true;
|
n.changed = true;
|
||||||
RED.events.emit("nodes:change",n);
|
RED.events.emit("nodes:change",n);
|
||||||
|
RED.history.push(historyEvent);
|
||||||
RED.nodes.dirty(true)
|
RED.nodes.dirty(true)
|
||||||
RED.view.redraw();
|
RED.view.redraw();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
RED.popover.tooltip(toggleButton,function() {
|
RED.popover.tooltip(toggleButton,function() {
|
||||||
|
if (n.type === "group") {
|
||||||
|
return RED._("common.label.enable")+" / "+RED._("common.label.disable")
|
||||||
|
}
|
||||||
return RED._("common.label."+(((n.type==='tab' && n.disabled) || (n.type!=='tab' && n.d))?"enable":"disable"));
|
return RED._("common.label."+(((n.type==='tab' && n.disabled) || (n.type!=='tab' && n.d))?"enable":"disable"));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -486,6 +513,13 @@ RED.sidebar.info.outliner = (function() {
|
|||||||
existingObject.treeList.remove();
|
existingObject.treeList.remove();
|
||||||
delete objects[n.id]
|
delete objects[n.id]
|
||||||
|
|
||||||
|
if (/^subflow:/.test(n.type)) {
|
||||||
|
var sfType = n.type.substring(8);
|
||||||
|
if (objects[sfType]) {
|
||||||
|
objects[sfType].element.find(".red-ui-info-outline-item-control-users").text(RED.nodes.subflow(sfType).instances.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If this is a group being removed, it may have an empty item
|
// If this is a group being removed, it may have an empty item
|
||||||
if (empties[n.id]) {
|
if (empties[n.id]) {
|
||||||
delete empties[n.id];
|
delete empties[n.id];
|
||||||
@ -587,6 +621,12 @@ RED.sidebar.info.outliner = (function() {
|
|||||||
configNodeTypes[parent].types[n.type].treeList.addChild(objects[n.id]);
|
configNodeTypes[parent].types[n.type].treeList.addChild(objects[n.id]);
|
||||||
}
|
}
|
||||||
objects[n.id].element.toggleClass("red-ui-info-outline-item-disabled", !!n.d)
|
objects[n.id].element.toggleClass("red-ui-info-outline-item-disabled", !!n.d)
|
||||||
|
if (/^subflow:/.test(n.type)) {
|
||||||
|
var sfType = n.type.substring(8);
|
||||||
|
if (objects[sfType]) {
|
||||||
|
objects[sfType].element.find(".red-ui-info-outline-item-control-users").text(RED.nodes.subflow(sfType).instances.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
updateSearch();
|
updateSearch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,7 +338,7 @@ RED.sidebar.info = (function() {
|
|||||||
count++;
|
count++;
|
||||||
propRow = $('<tr class="red-ui-help-info-property-row'+(expandedSections.property?"":" hide")+'"><td></td><td></td></tr>').appendTo(tableBody);
|
propRow = $('<tr class="red-ui-help-info-property-row'+(expandedSections.property?"":" hide")+'"><td></td><td></td></tr>').appendTo(tableBody);
|
||||||
$(propRow.children()[0]).text(n);
|
$(propRow.children()[0]).text(n);
|
||||||
if (defaults[n].type) {
|
if (defaults[n].type && !defaults[n]._type.array) {
|
||||||
var configNode = RED.nodes.node(val);
|
var configNode = RED.nodes.node(val);
|
||||||
if (!configNode) {
|
if (!configNode) {
|
||||||
RED.utils.createObjectElement(undefined).appendTo(propRow.children()[1]);
|
RED.utils.createObjectElement(undefined).appendTo(propRow.children()[1]);
|
||||||
@ -382,21 +382,14 @@ RED.sidebar.info = (function() {
|
|||||||
var category = subflowNode.category||"subflows";
|
var category = subflowNode.category||"subflows";
|
||||||
$(propRow.children()[1]).text(RED._("palette.label."+category,{defaultValue:category}))
|
$(propRow.children()[1]).text(RED._("palette.label."+category,{defaultValue:category}))
|
||||||
$('<tr class="node-info-subflow-row"><td>'+RED._("sidebar.info.instances")+"</td><td>"+subflowUserCount+'</td></tr>').appendTo(tableBody);
|
$('<tr class="node-info-subflow-row"><td>'+RED._("sidebar.info.instances")+"</td><td>"+subflowUserCount+'</td></tr>').appendTo(tableBody);
|
||||||
|
if (subflowNode.meta) {
|
||||||
|
propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("subflow.module")+'</td><td></td></tr>').appendTo(tableBody);
|
||||||
|
$(propRow.children()[1]).text(subflowNode.meta.module||"")
|
||||||
|
propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("subflow.version")+'</td><td></td></tr>').appendTo(tableBody);
|
||||||
|
$(propRow.children()[1]).text(subflowNode.meta.version||"")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// var helpText = "";
|
|
||||||
// if (node.type === "tab" || node.type === "subflow") {
|
|
||||||
// } else {
|
|
||||||
// if (subflowNode && node.type !== "subflow") {
|
|
||||||
// // Selected a subflow instance node.
|
|
||||||
// // - The subflow template info goes into help
|
|
||||||
// helpText = (RED.utils.renderMarkdown(subflowNode.info||"")||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>'));
|
|
||||||
// } else {
|
|
||||||
// helpText = $("script[data-help-name='"+node.type+"']").html()||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
|
||||||
// }
|
|
||||||
// setInfoText(helpText, helpSection.content);
|
|
||||||
// }
|
|
||||||
|
|
||||||
var infoText = "";
|
var infoText = "";
|
||||||
|
|
||||||
if (node._def && node._def.info) {
|
if (node._def && node._def.info) {
|
||||||
@ -409,23 +402,6 @@ RED.sidebar.info = (function() {
|
|||||||
}
|
}
|
||||||
var infoSectionContainer = $("<div>").css("padding","0 6px 6px").appendTo(propertiesPanelContent)
|
var infoSectionContainer = $("<div>").css("padding","0 6px 6px").appendTo(propertiesPanelContent)
|
||||||
|
|
||||||
// var editInfo = $('<button class="red-ui-button red-ui-button-small" style="float: right"><i class="fa fa-file-text-o"></button>').appendTo(infoSectionContainer).on("click", function(evt) {
|
|
||||||
// //.text(RED._("sidebar.info.editDescription"))
|
|
||||||
// evt.preventDefault();
|
|
||||||
// evt.stopPropagation();
|
|
||||||
// if (node.type === 'tab') {
|
|
||||||
//
|
|
||||||
// } else if (node.type === 'subflow') {
|
|
||||||
//
|
|
||||||
// } else if (node.type === 'group') {
|
|
||||||
//
|
|
||||||
// } else if (node._def.category !== 'config') {
|
|
||||||
// RED.editor.edit(node,"editor-tab-description");
|
|
||||||
// } else {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
|
|
||||||
setInfoText(infoText, infoSectionContainer);
|
setInfoText(infoText, infoSectionContainer);
|
||||||
|
|
||||||
$(".red-ui-sidebar-info-stack").scrollTop(0);
|
$(".red-ui-sidebar-info-stack").scrollTop(0);
|
||||||
|
@ -109,13 +109,19 @@ RED.userSettings = (function() {
|
|||||||
function compText(a, b) {
|
function compText(a, b) {
|
||||||
return a.text.localeCompare(b.text);
|
return a.text.localeCompare(b.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewSettings = [
|
var viewSettings = [
|
||||||
{
|
{
|
||||||
options: [
|
options: [
|
||||||
{setting:"editor-language",local: true, label:"menu.label.view.language",options:function(done){ done([{val:'',text:RED._('menu.label.view.browserDefault')}].concat(RED.settings.theme("languages").map(localeToName).sort(compText))) }},
|
{setting:"editor-language",local: true, label:"menu.label.view.language",options:function(done){ done([{val:'',text:RED._('menu.label.view.browserDefault')}].concat(RED.settings.theme("languages").map(localeToName).sort(compText))) }},
|
||||||
]
|
]
|
||||||
},{
|
},
|
||||||
|
// {
|
||||||
|
// options: [
|
||||||
|
// {setting:"theme", label:"Theme",options:function(done){ done([{val:'',text:'default'}].concat(RED.settings.theme("themes"))) }},
|
||||||
|
// ]
|
||||||
|
// },
|
||||||
|
{
|
||||||
title: "menu.label.view.grid",
|
title: "menu.label.view.grid",
|
||||||
options: [
|
options: [
|
||||||
{setting:"view-show-grid",oldSetting:"menu-menu-item-view-show-grid",label:"menu.label.view.showGrid", default: true, toggle:true,onchange:"core:toggle-show-grid"},
|
{setting:"view-show-grid",oldSetting:"menu-menu-item-view-show-grid",label:"menu.label.view.showGrid", default: true, toggle:true,onchange:"core:toggle-show-grid"},
|
||||||
|
@ -615,18 +615,25 @@ RED.utils = (function() {
|
|||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalisePropertyExpression(str) {
|
function createError(code, message) {
|
||||||
|
var e = new Error(message);
|
||||||
|
e.code = code;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalisePropertyExpression(str,msg) {
|
||||||
// This must be kept in sync with validatePropertyExpression
|
// This must be kept in sync with validatePropertyExpression
|
||||||
// in editor/js/ui/utils.js
|
// in editor/js/ui/utils.js
|
||||||
|
|
||||||
var length = str.length;
|
var length = str.length;
|
||||||
if (length === 0) {
|
if (length === 0) {
|
||||||
throw new Error("Invalid property expression: zero-length");
|
throw createError("INVALID_EXPR","Invalid property expression: zero-length");
|
||||||
}
|
}
|
||||||
var parts = [];
|
var parts = [];
|
||||||
var start = 0;
|
var start = 0;
|
||||||
var inString = false;
|
var inString = false;
|
||||||
var inBox = false;
|
var inBox = false;
|
||||||
|
var boxExpression = false;
|
||||||
var quoteChar;
|
var quoteChar;
|
||||||
var v;
|
var v;
|
||||||
for (var i=0;i<length;i++) {
|
for (var i=0;i<length;i++) {
|
||||||
@ -634,14 +641,14 @@ RED.utils = (function() {
|
|||||||
if (!inString) {
|
if (!inString) {
|
||||||
if (c === "'" || c === '"') {
|
if (c === "'" || c === '"') {
|
||||||
if (i != start) {
|
if (i != start) {
|
||||||
throw new Error("Invalid property expression: unexpected "+c+" at position "+i);
|
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+c+" at position "+i);
|
||||||
}
|
}
|
||||||
inString = true;
|
inString = true;
|
||||||
quoteChar = c;
|
quoteChar = c;
|
||||||
start = i+1;
|
start = i+1;
|
||||||
} else if (c === '.') {
|
} else if (c === '.') {
|
||||||
if (i===0) {
|
if (i===0) {
|
||||||
throw new Error("Invalid property expression: unexpected . at position 0");
|
throw createError("INVALID_EXPR","Invalid property expression: unexpected . at position 0");
|
||||||
}
|
}
|
||||||
if (start != i) {
|
if (start != i) {
|
||||||
v = str.substring(start,i);
|
v = str.substring(start,i);
|
||||||
@ -652,57 +659,99 @@ RED.utils = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i===length-1) {
|
if (i===length-1) {
|
||||||
throw new Error("Invalid property expression: unterminated expression");
|
throw createError("INVALID_EXPR","Invalid property expression: unterminated expression");
|
||||||
}
|
}
|
||||||
// Next char is first char of an identifier: a-z 0-9 $ _
|
// Next char is first char of an identifier: a-z 0-9 $ _
|
||||||
if (!/[a-z0-9\$\_]/i.test(str[i+1])) {
|
if (!/[a-z0-9\$\_]/i.test(str[i+1])) {
|
||||||
throw new Error("Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1));
|
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1));
|
||||||
}
|
}
|
||||||
start = i+1;
|
start = i+1;
|
||||||
} else if (c === '[') {
|
} else if (c === '[') {
|
||||||
if (i === 0) {
|
if (i === 0) {
|
||||||
throw new Error("Invalid property expression: unexpected "+c+" at position "+i);
|
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+c+" at position "+i);
|
||||||
}
|
}
|
||||||
if (start != i) {
|
if (start != i) {
|
||||||
parts.push(str.substring(start,i));
|
parts.push(str.substring(start,i));
|
||||||
}
|
}
|
||||||
if (i===length-1) {
|
if (i===length-1) {
|
||||||
throw new Error("Invalid property expression: unterminated expression");
|
throw createError("INVALID_EXPR","Invalid property expression: unterminated expression");
|
||||||
}
|
}
|
||||||
// Next char is either a quote or a number
|
// Start of a new expression. If it starts with msg it is a nested expression
|
||||||
if (!/["'\d]/.test(str[i+1])) {
|
// Need to scan ahead to find the closing bracket
|
||||||
throw new Error("Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1));
|
if (/^msg[.\[]/.test(str.substring(i+1))) {
|
||||||
|
var depth = 1;
|
||||||
|
var inLocalString = false;
|
||||||
|
var localStringQuote;
|
||||||
|
for (var j=i+1;j<length;j++) {
|
||||||
|
if (/["']/.test(str[j])) {
|
||||||
|
if (inLocalString) {
|
||||||
|
if (str[j] === localStringQuote) {
|
||||||
|
inLocalString = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
inLocalString = true;
|
||||||
|
localStringQuote = str[j]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (str[j] === '[') {
|
||||||
|
depth++;
|
||||||
|
} else if (str[j] === ']') {
|
||||||
|
depth--;
|
||||||
|
}
|
||||||
|
if (depth === 0) {
|
||||||
|
try {
|
||||||
|
if (msg) {
|
||||||
|
parts.push(getMessageProperty(msg, str.substring(i+1,j)))
|
||||||
|
} else {
|
||||||
|
parts.push(normalisePropertyExpression(str.substring(i+1,j), msg));
|
||||||
|
}
|
||||||
|
inBox = false;
|
||||||
|
i = j;
|
||||||
|
start = j+1;
|
||||||
|
break;
|
||||||
|
} catch(err) {
|
||||||
|
throw createError("INVALID_EXPR","Invalid expression started at position "+(i+1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (depth > 0) {
|
||||||
|
throw createError("INVALID_EXPR","Invalid property expression: unmatched '[' at position "+i);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
} else if (!/["'\d]/.test(str[i+1])) {
|
||||||
|
// Next char is either a quote or a number
|
||||||
|
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1));
|
||||||
}
|
}
|
||||||
start = i+1;
|
start = i+1;
|
||||||
inBox = true;
|
inBox = true;
|
||||||
} else if (c === ']') {
|
} else if (c === ']') {
|
||||||
if (!inBox) {
|
if (!inBox) {
|
||||||
throw new Error("Invalid property expression: unexpected "+c+" at position "+i);
|
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+c+" at position "+i);
|
||||||
}
|
}
|
||||||
if (start != i) {
|
if (start != i) {
|
||||||
v = str.substring(start,i);
|
v = str.substring(start,i);
|
||||||
if (/^\d+$/.test(v)) {
|
if (/^\d+$/.test(v)) {
|
||||||
parts.push(parseInt(v));
|
parts.push(parseInt(v));
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Invalid property expression: unexpected array expression at position "+start);
|
throw createError("INVALID_EXPR","Invalid property expression: unexpected array expression at position "+start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
start = i+1;
|
start = i+1;
|
||||||
inBox = false;
|
inBox = false;
|
||||||
} else if (c === ' ') {
|
} else if (c === ' ') {
|
||||||
throw new Error("Invalid property expression: unexpected ' ' at position "+i);
|
throw createError("INVALID_EXPR","Invalid property expression: unexpected ' ' at position "+i);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (c === quoteChar) {
|
if (c === quoteChar) {
|
||||||
if (i-start === 0) {
|
if (i-start === 0) {
|
||||||
throw new Error("Invalid property expression: zero-length string at position "+start);
|
throw createError("INVALID_EXPR","Invalid property expression: zero-length string at position "+start);
|
||||||
}
|
}
|
||||||
parts.push(str.substring(start,i));
|
parts.push(str.substring(start,i));
|
||||||
// If inBox, next char must be a ]. Otherwise it may be [ or .
|
// If inBox, next char must be a ]. Otherwise it may be [ or .
|
||||||
if (inBox && !/\]/.test(str[i+1])) {
|
if (inBox && !/\]/.test(str[i+1])) {
|
||||||
throw new Error("Invalid property expression: unexpected array expression at position "+start);
|
throw createError("INVALID_EXPR","Invalid property expression: unexpected array expression at position "+start);
|
||||||
} else if (!inBox && i+1!==length && !/[\[\.]/.test(str[i+1])) {
|
} else if (!inBox && i+1!==length && !/[\[\.]/.test(str[i+1])) {
|
||||||
throw new Error("Invalid property expression: unexpected "+str[i+1]+" expression at position "+(i+1));
|
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+str[i+1]+" expression at position "+(i+1));
|
||||||
}
|
}
|
||||||
start = i+1;
|
start = i+1;
|
||||||
inString = false;
|
inString = false;
|
||||||
@ -711,7 +760,7 @@ RED.utils = (function() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
if (inBox || inString) {
|
if (inBox || inString) {
|
||||||
throw new Error("Invalid property expression: unterminated expression");
|
throw new createError("INVALID_EXPR","Invalid property expression: unterminated expression");
|
||||||
}
|
}
|
||||||
if (start < length) {
|
if (start < length) {
|
||||||
parts.push(str.substring(start));
|
parts.push(str.substring(start));
|
||||||
|
@ -2276,7 +2276,7 @@ RED.view = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function calculateTextWidth(str, className) {
|
function calculateTextWidth(str, className) {
|
||||||
var result=convertLineBreakCharacter(str);
|
var result = convertLineBreakCharacter(str);
|
||||||
var width = 0;
|
var width = 0;
|
||||||
for (var i=0;i<result.length;i++) {
|
for (var i=0;i<result.length;i++) {
|
||||||
var calculateTextW=calculateTextDimensions(result[i],className)[0];
|
var calculateTextW=calculateTextDimensions(result[i],className)[0];
|
||||||
|
@ -219,7 +219,7 @@ RED.user = (function() {
|
|||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
if (RED.settings.user) {
|
if (RED.settings.user) {
|
||||||
if (!RED.settings.editorTheme || !RED.settings.editorTheme.hasOwnProperty("userMenu")) {
|
if (!RED.settings.editorTheme || !RED.settings.editorTheme.hasOwnProperty("userMenu") || RED.settings.editorTheme.userMenu) {
|
||||||
|
|
||||||
var userMenu = $('<li><a id="red-ui-header-button-user" class="button hide" href="#"></a></li>')
|
var userMenu = $('<li><a id="red-ui-header-button-user" class="button hide" href="#"></a></li>')
|
||||||
.prependTo(".red-ui-header-toolbar");
|
.prependTo(".red-ui-header-toolbar");
|
||||||
|
@ -15,6 +15,9 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
|
|
||||||
|
body {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.red-ui-editor {
|
.red-ui-editor {
|
||||||
font-size: $primary-font-size;
|
font-size: $primary-font-size;
|
||||||
|
@ -765,6 +765,10 @@ button.red-ui-toggleButton.toggle {
|
|||||||
width: calc(100% - 10px);
|
width: calc(100% - 10px);
|
||||||
padding-left: 3px;
|
padding-left: 3px;
|
||||||
}
|
}
|
||||||
|
select {
|
||||||
|
padding: 0 3px;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
.placeholder-input {
|
.placeholder-input {
|
||||||
span:first-child {
|
span:first-child {
|
||||||
display:inline-block;
|
display:inline-block;
|
||||||
|
@ -139,6 +139,9 @@
|
|||||||
stroke-width: 2;
|
stroke-width: 2;
|
||||||
}
|
}
|
||||||
.red-ui-flow-node-icon-group {
|
.red-ui-flow-node-icon-group {
|
||||||
|
text {
|
||||||
|
@include disable-selection;
|
||||||
|
}
|
||||||
.fa-lg {
|
.fa-lg {
|
||||||
@include disable-selection;
|
@include disable-selection;
|
||||||
stroke: none;
|
stroke: none;
|
||||||
|
@ -29,8 +29,30 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.red-ui-clipboard-dialog-tab-clipboard {
|
|
||||||
|
#red-ui-clipboard-dialog-export-tab-clipboard-preview {
|
||||||
|
.red-ui-treeList-container,.red-ui-editableList-border {
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#red-ui-clipboard-dialog-export-tab-clipboard-json {
|
||||||
|
padding: 10px 10px 0;
|
||||||
|
}
|
||||||
|
#red-ui-clipboard-dialog-import-tab-clipboard {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
}
|
||||||
|
.red-ui-clipboard-dialog-export-tab-clipboard-tab {
|
||||||
|
position: absolute;
|
||||||
|
top: 40px;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red-ui-clipboard-dialog-tab-clipboard {
|
||||||
|
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
resize: none;
|
resize: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -131,10 +131,10 @@
|
|||||||
width: 120px;
|
width: 120px;
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
position: relative;
|
position: relative;
|
||||||
&:not(.red-ui-palette-node-config):first-child {
|
&:not(.red-ui-palette-node-config):not(.red-ui-palette-node-small):first-child {
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
}
|
}
|
||||||
&:not(.red-ui-palette-node-config):last-child {
|
&:not(.red-ui-palette-node-config):not(.red-ui-palette-node-small):first-child {
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -326,7 +326,7 @@ div.red-ui-info-table {
|
|||||||
border-bottom: 1px solid $secondary-border-color;
|
border-bottom: 1px solid $secondary-border-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.red-ui-info-outline,.red-ui-sidebar-help-toc, #red-ui-clipboard-dialog-import-conflicts-list {
|
.red-ui-info-outline,.red-ui-sidebar-help-toc, #red-ui-clipboard-dialog-import-conflicts-list, #red-ui-clipboard-dialog-export-tab-clipboard-preview {
|
||||||
.red-ui-info-outline-item {
|
.red-ui-info-outline-item {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@ -26,6 +26,14 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
overflow:visible;
|
overflow:visible;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
&[disabled] {
|
||||||
|
input, button {
|
||||||
|
background: $secondary-background-inactive;
|
||||||
|
pointer-events: none;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.red-ui-typedInput-input-wrap {
|
.red-ui-typedInput-input-wrap {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
color:"#c0edc0",
|
color:"#c0edc0",
|
||||||
defaults: {
|
defaults: {
|
||||||
name: {value:""},
|
name: {value:""},
|
||||||
scope: {value:[]},
|
scope: {value:[], type:"*[]"},
|
||||||
uncaught: {value:false}
|
uncaught: {value:false}
|
||||||
},
|
},
|
||||||
inputs:0,
|
inputs:0,
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
color:"#e49191",
|
color:"#e49191",
|
||||||
defaults: {
|
defaults: {
|
||||||
name: {value:""},
|
name: {value:""},
|
||||||
scope: {value:null},
|
scope: {value:null, type:"*[]"},
|
||||||
uncaught: {value:false}
|
uncaught: {value:false}
|
||||||
},
|
},
|
||||||
inputs:0,
|
inputs:0,
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
color:"#94c1d0",
|
color:"#94c1d0",
|
||||||
defaults: {
|
defaults: {
|
||||||
name: {value:""},
|
name: {value:""},
|
||||||
scope: {value:null}
|
scope: {value:null, type:"*[]"}
|
||||||
},
|
},
|
||||||
inputs:0,
|
inputs:0,
|
||||||
outputs:1,
|
outputs:1,
|
||||||
|
@ -187,7 +187,7 @@
|
|||||||
color:"#ddd",//"#87D8CF",
|
color:"#ddd",//"#87D8CF",
|
||||||
defaults: {
|
defaults: {
|
||||||
name: {value:""},
|
name: {value:""},
|
||||||
links: { value: [] }
|
links: { value: [], type:"link out[]" }
|
||||||
},
|
},
|
||||||
inputs:0,
|
inputs:0,
|
||||||
outputs:1,
|
outputs:1,
|
||||||
@ -216,7 +216,7 @@
|
|||||||
color:"#ddd",//"#87D8CF",
|
color:"#ddd",//"#87D8CF",
|
||||||
defaults: {
|
defaults: {
|
||||||
name: {value:""},
|
name: {value:""},
|
||||||
links: { value: []}
|
links: { value: [], type:"link in[]"}
|
||||||
},
|
},
|
||||||
align:"right",
|
align:"right",
|
||||||
inputs:1,
|
inputs:1,
|
||||||
|
@ -168,6 +168,10 @@ module.exports = function(RED) {
|
|||||||
return getFromValueType(RED.util.getMessageProperty(msg,rule.from),done);
|
return getFromValueType(RED.util.getMessageProperty(msg,rule.from),done);
|
||||||
} else if (rule.fromt === 'flow' || rule.fromt === 'global') {
|
} else if (rule.fromt === 'flow' || rule.fromt === 'global') {
|
||||||
var contextKey = RED.util.parseContextStore(rule.from);
|
var contextKey = RED.util.parseContextStore(rule.from);
|
||||||
|
if (/\[msg\./.test(context.key)) {
|
||||||
|
// The key has a nest msg. reference to evaluate first
|
||||||
|
context.key = RED.util.normalisePropertyExpression(contextKey.key,msg,true);
|
||||||
|
}
|
||||||
node.context()[rule.fromt].get(contextKey.key, contextKey.store, (err,fromValue) => {
|
node.context()[rule.fromt].get(contextKey.key, contextKey.store, (err,fromValue) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
done(err)
|
done(err)
|
||||||
@ -243,6 +247,10 @@ module.exports = function(RED) {
|
|||||||
return done(undefined,msg);
|
return done(undefined,msg);
|
||||||
} else if (rule.pt === 'flow' || rule.pt === 'global') {
|
} else if (rule.pt === 'flow' || rule.pt === 'global') {
|
||||||
var contextKey = RED.util.parseContextStore(property);
|
var contextKey = RED.util.parseContextStore(property);
|
||||||
|
if (/\[msg/.test(contextKey.key)) {
|
||||||
|
// The key has a nest msg. reference to evaluate first
|
||||||
|
contextKey.key = RED.util.normalisePropertyExpression(contextKey.key, msg, true)
|
||||||
|
}
|
||||||
var target = node.context()[rule.pt];
|
var target = node.context()[rule.pt];
|
||||||
var callback = err => {
|
var callback = err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -80,10 +80,10 @@ module.exports = function(RED) {
|
|||||||
this.drop = n.drop;
|
this.drop = n.drop;
|
||||||
var node = this;
|
var node = this;
|
||||||
|
|
||||||
function ourTimeout(handler, delay) {
|
function ourTimeout(handler, delay, clearHandler) {
|
||||||
var toutID = setTimeout(handler, delay);
|
var toutID = setTimeout(handler, delay);
|
||||||
return {
|
return {
|
||||||
clear: function() { clearTimeout(toutID); },
|
clear: function() { clearTimeout(toutID); clearHandler(); },
|
||||||
trigger: function() { clearTimeout(toutID); return handler(); }
|
trigger: function() { clearTimeout(toutID); return handler(); }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -113,14 +113,15 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (node.pauseType === "delay") {
|
if (node.pauseType === "delay") {
|
||||||
node.on("input", function(msg) {
|
node.on("input", function(msg, send, done) {
|
||||||
if (msg.hasOwnProperty("flush")) { flushDelayList(); }
|
if (msg.hasOwnProperty("flush")) { flushDelayList(); done(); }
|
||||||
else {
|
else {
|
||||||
var id = ourTimeout(function() {
|
var id = ourTimeout(function() {
|
||||||
node.idList.splice(node.idList.indexOf(id),1);
|
node.idList.splice(node.idList.indexOf(id),1);
|
||||||
if (node.idList.length === 0) { node.status({}); }
|
if (node.idList.length === 0) { node.status({}); }
|
||||||
node.send(msg);
|
send(msg);
|
||||||
}, node.timeout);
|
done();
|
||||||
|
}, node.timeout, () => done());
|
||||||
node.idList.push(id);
|
node.idList.push(id);
|
||||||
if ((node.timeout > 1000) && (node.idList.length !== 0)) {
|
if ((node.timeout > 1000) && (node.idList.length !== 0)) {
|
||||||
node.status({fill:"blue",shape:"dot",text:" "});
|
node.status({fill:"blue",shape:"dot",text:" "});
|
||||||
@ -131,7 +132,7 @@ module.exports = function(RED) {
|
|||||||
node.on("close", function() { clearDelayList(); });
|
node.on("close", function() { clearDelayList(); });
|
||||||
}
|
}
|
||||||
else if (node.pauseType === "delayv") {
|
else if (node.pauseType === "delayv") {
|
||||||
node.on("input", function(msg) {
|
node.on("input", function(msg, send, done) {
|
||||||
var delayvar = Number(node.timeout);
|
var delayvar = Number(node.timeout);
|
||||||
if (msg.hasOwnProperty("delay") && !isNaN(parseFloat(msg.delay))) {
|
if (msg.hasOwnProperty("delay") && !isNaN(parseFloat(msg.delay))) {
|
||||||
delayvar = parseFloat(msg.delay);
|
delayvar = parseFloat(msg.delay);
|
||||||
@ -140,8 +141,9 @@ module.exports = function(RED) {
|
|||||||
var id = ourTimeout(function() {
|
var id = ourTimeout(function() {
|
||||||
node.idList.splice(node.idList.indexOf(id),1);
|
node.idList.splice(node.idList.indexOf(id),1);
|
||||||
if (node.idList.length === 0) { node.status({}); }
|
if (node.idList.length === 0) { node.status({}); }
|
||||||
node.send(msg);
|
send(msg);
|
||||||
}, delayvar);
|
done();
|
||||||
|
}, delayvar, () => done());
|
||||||
node.idList.push(id);
|
node.idList.push(id);
|
||||||
if ((delayvar >= 0) && (node.idList.length !== 0)) {
|
if ((delayvar >= 0) && (node.idList.length !== 0)) {
|
||||||
node.status({fill:"blue",shape:"dot",text:delayvar/1000+"s"});
|
node.status({fill:"blue",shape:"dot",text:delayvar/1000+"s"});
|
||||||
@ -152,7 +154,7 @@ module.exports = function(RED) {
|
|||||||
node.on("close", function() { clearDelayList(); });
|
node.on("close", function() { clearDelayList(); });
|
||||||
}
|
}
|
||||||
else if (node.pauseType === "rate") {
|
else if (node.pauseType === "rate") {
|
||||||
node.on("input", function(msg) {
|
node.on("input", function(msg, send, done) {
|
||||||
if (msg.hasOwnProperty("reset")) {
|
if (msg.hasOwnProperty("reset")) {
|
||||||
if (node.intervalID !== -1 ) {
|
if (node.intervalID !== -1 ) {
|
||||||
clearInterval(node.intervalID);
|
clearInterval(node.intervalID);
|
||||||
@ -161,17 +163,18 @@ module.exports = function(RED) {
|
|||||||
delete node.lastSent;
|
delete node.lastSent;
|
||||||
node.buffer = [];
|
node.buffer = [];
|
||||||
node.status({text:"reset"});
|
node.status({text:"reset"});
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!node.drop) {
|
if (!node.drop) {
|
||||||
var m = RED.util.cloneMessage(msg);
|
var m = RED.util.cloneMessage(msg);
|
||||||
delete m.flush;
|
delete m.flush;
|
||||||
if (node.intervalID !== -1) {
|
if (node.intervalID !== -1) {
|
||||||
node.buffer.push(m);
|
node.buffer.push({msg: m, send: send, done: done});
|
||||||
node.reportDepth();
|
node.reportDepth();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
node.send(m);
|
send(m);
|
||||||
node.reportDepth();
|
node.reportDepth();
|
||||||
node.intervalID = setInterval(function() {
|
node.intervalID = setInterval(function() {
|
||||||
if (node.buffer.length === 0) {
|
if (node.buffer.length === 0) {
|
||||||
@ -179,16 +182,22 @@ module.exports = function(RED) {
|
|||||||
node.intervalID = -1;
|
node.intervalID = -1;
|
||||||
}
|
}
|
||||||
if (node.buffer.length > 0) {
|
if (node.buffer.length > 0) {
|
||||||
node.send(node.buffer.shift());
|
const msgInfo = node.buffer.shift();
|
||||||
|
msgInfo.send(msgInfo.msg);
|
||||||
|
msgInfo.done();
|
||||||
}
|
}
|
||||||
node.reportDepth();
|
node.reportDepth();
|
||||||
}, node.rate);
|
}, node.rate);
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
if (msg.hasOwnProperty("flush")) {
|
if (msg.hasOwnProperty("flush")) {
|
||||||
while (node.buffer.length > 0) {
|
while (node.buffer.length > 0) {
|
||||||
node.send(node.buffer.shift());
|
const msgInfo = node.buffer.shift();
|
||||||
|
msgInfo.send(msgInfo.msg);
|
||||||
|
msgInfo.done();
|
||||||
}
|
}
|
||||||
node.status({});
|
node.status({});
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -198,17 +207,19 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
if (!node.lastSent) { // ensuring that we always send the first message
|
if (!node.lastSent) { // ensuring that we always send the first message
|
||||||
node.lastSent = process.hrtime();
|
node.lastSent = process.hrtime();
|
||||||
node.send(msg);
|
send(msg);
|
||||||
}
|
}
|
||||||
else if ( ( (timeSinceLast[0] * SECONDS_TO_NANOS) + timeSinceLast[1] ) > (node.rate * MILLIS_TO_NANOS) ) {
|
else if ( ( (timeSinceLast[0] * SECONDS_TO_NANOS) + timeSinceLast[1] ) > (node.rate * MILLIS_TO_NANOS) ) {
|
||||||
node.lastSent = process.hrtime();
|
node.lastSent = process.hrtime();
|
||||||
node.send(msg);
|
send(msg);
|
||||||
}
|
}
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
node.on("close", function() {
|
node.on("close", function() {
|
||||||
clearInterval(node.intervalID);
|
clearInterval(node.intervalID);
|
||||||
clearTimeout(node.busy);
|
clearTimeout(node.busy);
|
||||||
|
node.buffer.forEach((msgInfo) => msgInfo.done());
|
||||||
node.buffer = [];
|
node.buffer = [];
|
||||||
node.status({});
|
node.status({});
|
||||||
});
|
});
|
||||||
@ -217,57 +228,75 @@ module.exports = function(RED) {
|
|||||||
node.intervalID = setInterval(function() {
|
node.intervalID = setInterval(function() {
|
||||||
if (node.pauseType === "queue") {
|
if (node.pauseType === "queue") {
|
||||||
if (node.buffer.length > 0) {
|
if (node.buffer.length > 0) {
|
||||||
node.send(node.buffer.shift()); // send the first on the queue
|
const msgInfo = node.buffer.shift();
|
||||||
|
msgInfo.send(msgInfo.msg); // send the first on the queue
|
||||||
|
msgInfo.done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
while (node.buffer.length > 0) { // send the whole queue
|
while (node.buffer.length > 0) { // send the whole queue
|
||||||
node.send(node.buffer.shift());
|
const msgInfo = node.buffer.shift();
|
||||||
|
msgInfo.send(msgInfo.msg);
|
||||||
|
msgInfo.done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.reportDepth();
|
node.reportDepth();
|
||||||
},node.rate);
|
},node.rate);
|
||||||
|
|
||||||
var hit;
|
var hit;
|
||||||
node.on("input", function(msg) {
|
node.on("input", function(msg, send, done) {
|
||||||
if (!msg.hasOwnProperty("topic")) { msg.topic = "_none_"; }
|
if (!msg.hasOwnProperty("topic")) { msg.topic = "_none_"; }
|
||||||
hit = false;
|
hit = false;
|
||||||
for (var b in node.buffer) { // check if already in queue
|
for (var b in node.buffer) { // check if already in queue
|
||||||
if (msg.topic === node.buffer[b].topic) {
|
if (msg.topic === node.buffer[b].msg.topic) {
|
||||||
node.buffer[b] = msg; // if so - replace existing entry
|
node.buffer[b].done();
|
||||||
|
node.buffer[b] = {msg, send, done}; // if so - replace existing entry
|
||||||
hit = true;
|
hit = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!hit) {
|
if (!hit) {
|
||||||
node.buffer.push(msg); // if not add to end of queue
|
node.buffer.push({msg, send, done}); // if not add to end of queue
|
||||||
node.reportDepth();
|
node.reportDepth();
|
||||||
}
|
}
|
||||||
if (msg.hasOwnProperty("reset")) {
|
if (msg.hasOwnProperty("reset")) {
|
||||||
|
while (node.buffer.length > 0) {
|
||||||
|
const msgInfo = node.buffer.shift();
|
||||||
|
msgInfo.done();
|
||||||
|
}
|
||||||
node.buffer = [];
|
node.buffer = [];
|
||||||
node.status({text:"reset"});
|
node.status({text:"reset"});
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
if (msg.hasOwnProperty("flush")) {
|
if (msg.hasOwnProperty("flush")) {
|
||||||
while (node.buffer.length > 0) {
|
while (node.buffer.length > 0) {
|
||||||
node.send(node.buffer.shift());
|
const msgInfo = node.buffer.shift();
|
||||||
|
msgInfo.send(msgInfo.msg);
|
||||||
|
msgInfo.done();
|
||||||
}
|
}
|
||||||
node.status({});
|
node.status({});
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
node.on("close", function() {
|
node.on("close", function() {
|
||||||
clearInterval(node.intervalID);
|
clearInterval(node.intervalID);
|
||||||
|
while (node.buffer.length > 0) {
|
||||||
|
const msgInfo = node.buffer.shift();
|
||||||
|
msgInfo.done();
|
||||||
|
}
|
||||||
node.buffer = [];
|
node.buffer = [];
|
||||||
node.status({});
|
node.status({});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (node.pauseType === "random") {
|
else if (node.pauseType === "random") {
|
||||||
node.on("input", function(msg) {
|
node.on("input", function(msg, send, done) {
|
||||||
var wait = node.randomFirst + (node.diff * Math.random());
|
var wait = node.randomFirst + (node.diff * Math.random());
|
||||||
var id = ourTimeout(function() {
|
var id = ourTimeout(function() {
|
||||||
node.idList.splice(node.idList.indexOf(id),1);
|
node.idList.splice(node.idList.indexOf(id),1);
|
||||||
node.send(msg);
|
send(msg);
|
||||||
node.status({});
|
node.status({});
|
||||||
}, wait);
|
done();
|
||||||
|
}, wait, () => done());
|
||||||
node.idList.push(id);
|
node.idList.push(id);
|
||||||
if ((node.timeout >= 1000) && (node.idList.length !== 0)) {
|
if ((node.timeout >= 1000) && (node.idList.length !== 0)) {
|
||||||
node.status({fill:"blue",shape:"dot",text:parseInt(wait/10)/100+"s"});
|
node.status({fill:"blue",shape:"dot",text:parseInt(wait/10)/100+"s"});
|
||||||
|
@ -82,10 +82,10 @@ module.exports = function(RED) {
|
|||||||
var npay = {};
|
var npay = {};
|
||||||
var pendingMessages = [];
|
var pendingMessages = [];
|
||||||
var activeMessagePromise = null;
|
var activeMessagePromise = null;
|
||||||
var processMessageQueue = function(msg) {
|
var processMessageQueue = function(msgInfo) {
|
||||||
if (msg) {
|
if (msgInfo) {
|
||||||
// A new message has arrived - add it to the message queue
|
// A new message has arrived - add it to the message queue
|
||||||
pendingMessages.push(msg);
|
pendingMessages.push(msgInfo);
|
||||||
if (activeMessagePromise !== null) {
|
if (activeMessagePromise !== null) {
|
||||||
// The node is currently processing a message, so do nothing
|
// The node is currently processing a message, so do nothing
|
||||||
// more with this message
|
// more with this message
|
||||||
@ -101,17 +101,17 @@ module.exports = function(RED) {
|
|||||||
|
|
||||||
// There are more messages to process. Get the next message and
|
// There are more messages to process. Get the next message and
|
||||||
// start processing it. Recurse back in to check for any more
|
// start processing it. Recurse back in to check for any more
|
||||||
var nextMsg = pendingMessages.shift();
|
var nextMsgInfo = pendingMessages.shift();
|
||||||
activeMessagePromise = processMessage(nextMsg)
|
activeMessagePromise = processMessage(nextMsgInfo)
|
||||||
.then(processMessageQueue)
|
.then(processMessageQueue)
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
node.error(err,nextMsg);
|
nextMsgInfo.done(err);
|
||||||
return processMessageQueue();
|
return processMessageQueue();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.on('input', function(msg) {
|
this.on('input', function(msg, send, done) {
|
||||||
processMessageQueue(msg);
|
processMessageQueue({msg, send, done});
|
||||||
});
|
});
|
||||||
|
|
||||||
var stat = function() {
|
var stat = function() {
|
||||||
@ -121,7 +121,8 @@ module.exports = function(RED) {
|
|||||||
else return {fill:"blue",shape:"dot",text:l};
|
else return {fill:"blue",shape:"dot",text:l};
|
||||||
}
|
}
|
||||||
|
|
||||||
var processMessage = function(msg) {
|
var processMessage = function(msgInfo) {
|
||||||
|
let msg = msgInfo.msg;
|
||||||
var topic = RED.util.getMessageProperty(msg,node.topic) || "_none";
|
var topic = RED.util.getMessageProperty(msg,node.topic) || "_none";
|
||||||
var promise;
|
var promise;
|
||||||
var delayDuration = node.duration;
|
var delayDuration = node.duration;
|
||||||
@ -179,7 +180,10 @@ module.exports = function(RED) {
|
|||||||
/* istanbul ignore else */
|
/* istanbul ignore else */
|
||||||
if (node.op1type !== "nul") {
|
if (node.op1type !== "nul") {
|
||||||
var msg2 = RED.util.cloneMessage(msg);
|
var msg2 = RED.util.cloneMessage(msg);
|
||||||
node.topics[topic].tout = setInterval(function() { node.send(RED.util.cloneMessage(msg2)); }, delayDuration);
|
node.topics[topic].tout = setInterval(function() {
|
||||||
|
if (node.op1type === "date") { msg2.payload = Date.now(); }
|
||||||
|
msgInfo.send(RED.util.cloneMessage(msg2));
|
||||||
|
}, delayDuration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -203,14 +207,15 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
promise.then(() => {
|
promise.then(() => {
|
||||||
if (node.op2type === "payl") {
|
if (node.op2type === "payl") {
|
||||||
if (node.second === true) { node.send([null,npay[topic]]); }
|
if (node.second === true) { msgInfo.send([null,npay[topic]]); }
|
||||||
else { node.send(npay[topic]); }
|
else { msgInfo.send(npay[topic]); }
|
||||||
delete npay[topic];
|
delete npay[topic];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
msg2.payload = node.topics[topic].m2;
|
msg2.payload = node.topics[topic].m2;
|
||||||
if (node.second === true) { node.send([null,msg2]); }
|
if (node.op2type === "date") { msg2.payload = Date.now(); }
|
||||||
else { node.send(msg2); }
|
if (node.second === true) { msgInfo.send([null,msg2]); }
|
||||||
|
else { msgInfo.send(msg2); }
|
||||||
}
|
}
|
||||||
delete node.topics[topic];
|
delete node.topics[topic];
|
||||||
node.status(stat());
|
node.status(stat());
|
||||||
@ -225,8 +230,9 @@ module.exports = function(RED) {
|
|||||||
}, delayDuration);
|
}, delayDuration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
msgInfo.done();
|
||||||
node.status(stat());
|
node.status(stat());
|
||||||
if (node.op1type !== "nul") { node.send(RED.util.cloneMessage(msg)); }
|
if (node.op1type !== "nul") { msgInfo.send(RED.util.cloneMessage(msg)); }
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -262,8 +268,8 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
delete node.topics[topic];
|
delete node.topics[topic];
|
||||||
node.status(stat());
|
node.status(stat());
|
||||||
if (node.second === true) { node.send([null,msg2]); }
|
if (node.second === true) { msgInfo.send([null,msg2]); }
|
||||||
else { node.send(msg2); }
|
else { msgInfo.send(msg2); }
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
node.error(err);
|
node.error(err);
|
||||||
});
|
});
|
||||||
@ -273,6 +279,7 @@ module.exports = function(RED) {
|
|||||||
// if (node.op2type === "payl") {node.topics[topic].m2 = RED.util.cloneMessage(msg.payload); }
|
// if (node.op2type === "payl") {node.topics[topic].m2 = RED.util.cloneMessage(msg.payload); }
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
msgInfo.done();
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
this.on("close", function() {
|
this.on("close", function() {
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
color:"darksalmon",
|
color:"darksalmon",
|
||||||
defaults: {
|
defaults: {
|
||||||
command: {value:""},
|
command: {value:""},
|
||||||
addpay: {value:true},
|
addpay: {value:false},
|
||||||
append: {value:""},
|
append: {value:""},
|
||||||
useSpawn: {value:"false"},
|
useSpawn: {value:"false"},
|
||||||
timer: {value:""},
|
timer: {value:""},
|
||||||
|
@ -31,12 +31,12 @@ module.exports = function(RED) {
|
|||||||
this.timer = Number(n.timer || 0)*1000;
|
this.timer = Number(n.timer || 0)*1000;
|
||||||
this.activeProcesses = {};
|
this.activeProcesses = {};
|
||||||
this.oldrc = (n.oldrc || false).toString();
|
this.oldrc = (n.oldrc || false).toString();
|
||||||
this.execOpt = {encoding:'binary', maxBuffer:10000000};
|
this.execOpt = {encoding:'binary', maxBuffer:RED.settings.execMaxBufferSize||10000000};
|
||||||
var node = this;
|
var node = this;
|
||||||
|
|
||||||
if (process.platform === 'linux' && fs.existsSync('/bin/bash')) { node.execOpt.shell = '/bin/bash'; }
|
if (process.platform === 'linux' && fs.existsSync('/bin/bash')) { node.execOpt.shell = '/bin/bash'; }
|
||||||
|
|
||||||
var cleanup = function(p) {
|
var cleanup = function(p) {
|
||||||
node.activeProcesses[p].kill();
|
node.activeProcesses[p].kill();
|
||||||
//node.status({fill:"red",shape:"dot",text:"timeout"});
|
//node.status({fill:"red",shape:"dot",text:"timeout"});
|
||||||
//node.error("Exec node timeout");
|
//node.error("Exec node timeout");
|
||||||
|
@ -210,7 +210,7 @@ module.exports = function(RED) {
|
|||||||
var httpMiddleware = function(req,res,next) { next(); }
|
var httpMiddleware = function(req,res,next) { next(); }
|
||||||
|
|
||||||
if (RED.settings.httpNodeMiddleware) {
|
if (RED.settings.httpNodeMiddleware) {
|
||||||
if (typeof RED.settings.httpNodeMiddleware === "function") {
|
if (typeof RED.settings.httpNodeMiddleware === "function" || Array.isArray(RED.settings.httpNodeMiddleware)) {
|
||||||
httpMiddleware = RED.settings.httpNodeMiddleware;
|
httpMiddleware = RED.settings.httpNodeMiddleware;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,6 +235,7 @@
|
|||||||
oneditprepare: function() {
|
oneditprepare: function() {
|
||||||
var previous = null;
|
var previous = null;
|
||||||
$("#node-input-out").on('focus', function () { previous = this.value; }).on("change", function() {
|
$("#node-input-out").on('focus', function () { previous = this.value; }).on("change", function() {
|
||||||
|
$("#node-input-splitc").show();
|
||||||
if (previous === null) { previous = $("#node-input-out").val(); }
|
if (previous === null) { previous = $("#node-input-out").val(); }
|
||||||
if ($("#node-input-out").val() == "char") {
|
if ($("#node-input-out").val() == "char") {
|
||||||
if (previous != "char") { $("#node-input-splitc").val("\\n"); }
|
if (previous != "char") { $("#node-input-splitc").val("\\n"); }
|
||||||
@ -247,6 +248,7 @@
|
|||||||
else if ($("#node-input-out").val() == "immed") {
|
else if ($("#node-input-out").val() == "immed") {
|
||||||
if (previous != "immed") { $("#node-input-splitc").val(" "); }
|
if (previous != "immed") { $("#node-input-splitc").val(" "); }
|
||||||
$("#node-units").text("");
|
$("#node-units").text("");
|
||||||
|
$("#node-input-splitc").hide();
|
||||||
}
|
}
|
||||||
else if ($("#node-input-out").val() == "count") {
|
else if ($("#node-input-out").val() == "count") {
|
||||||
if (previous != "count") { $("#node-input-splitc").val("12"); }
|
if (previous != "count") { $("#node-input-splitc").val("12"); }
|
||||||
@ -255,6 +257,7 @@
|
|||||||
else {
|
else {
|
||||||
if (previous != "sit") { $("#node-input-splitc").val(" "); }
|
if (previous != "sit") { $("#node-input-splitc").val(" "); }
|
||||||
$("#node-units").text("");
|
$("#node-units").text("");
|
||||||
|
$("#node-input-splitc").hide();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ module.exports = function(RED) {
|
|||||||
"use strict";
|
"use strict";
|
||||||
function CSVNode(n) {
|
function CSVNode(n) {
|
||||||
RED.nodes.createNode(this,n);
|
RED.nodes.createNode(this,n);
|
||||||
this.template = (n.temp || "").split(",");
|
this.template = (n.temp || "");
|
||||||
this.sep = (n.sep || ',').replace("\\t","\t").replace("\\n","\n").replace("\\r","\r");
|
this.sep = (n.sep || ',').replace("\\t","\t").replace("\\n","\n").replace("\\r","\r");
|
||||||
this.quo = '"';
|
this.quo = '"';
|
||||||
this.ret = (n.ret || "\n").replace("\\n","\n").replace("\\r","\r");
|
this.ret = (n.ret || "\n").replace("\\n","\n").replace("\\r","\r");
|
||||||
@ -38,16 +38,12 @@ module.exports = function(RED) {
|
|||||||
if (this.hdrout === true) { this.hdrout = "all"; }
|
if (this.hdrout === true) { this.hdrout = "all"; }
|
||||||
var tmpwarn = true;
|
var tmpwarn = true;
|
||||||
var node = this;
|
var node = this;
|
||||||
|
var re = new RegExp(',(?=(?:(?:[^"]*"){2})*[^"]*$)','g');
|
||||||
|
|
||||||
// pass in an array of column names to be trimed, de-quoted and retrimed
|
// pass in an array of column names to be trimed, de-quoted and retrimed
|
||||||
var clean = function(col) {
|
var clean = function(col) {
|
||||||
for (var t = 0; t < col.length; t++) {
|
col = col.trim().split(re) || [""];
|
||||||
col[t] = col[t].trim(); // remove leading and trailing whitespace
|
col = col.map(x => x.replace(/"/g,'').trim());
|
||||||
if (col[t].charAt(0) === '"' && col[t].charAt(col[t].length -1) === '"') {
|
|
||||||
// remove leading and trailing quotes (if they exist) - and remove whitepace again.
|
|
||||||
col[t] = col[t].substr(1,col[t].length -2).trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((col.length === 1) && (col[0] === "")) { node.goodtmpl = false; }
|
if ((col.length === 1) && (col[0] === "")) { node.goodtmpl = false; }
|
||||||
else { node.goodtmpl = true; }
|
else { node.goodtmpl = true; }
|
||||||
return col;
|
return col;
|
||||||
@ -55,7 +51,7 @@ module.exports = function(RED) {
|
|||||||
node.template = clean(node.template);
|
node.template = clean(node.template);
|
||||||
node.hdrSent = false;
|
node.hdrSent = false;
|
||||||
|
|
||||||
this.on("input", function(msg) {
|
this.on("input", function(msg, send, done) {
|
||||||
if (msg.hasOwnProperty("reset")) {
|
if (msg.hasOwnProperty("reset")) {
|
||||||
node.hdrSent = false;
|
node.hdrSent = false;
|
||||||
}
|
}
|
||||||
@ -67,13 +63,14 @@ module.exports = function(RED) {
|
|||||||
if (node.hdrout !== "none" && node.hdrSent === false) {
|
if (node.hdrout !== "none" && node.hdrSent === false) {
|
||||||
if ((node.template.length === 1) && (node.template[0] === '')) {
|
if ((node.template.length === 1) && (node.template[0] === '')) {
|
||||||
if (msg.hasOwnProperty("columns")) {
|
if (msg.hasOwnProperty("columns")) {
|
||||||
node.template = clean((msg.columns || "").split(","));
|
node.template = clean(msg.columns || "");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
node.template = Object.keys(msg.payload[0]);
|
node.template = Object.keys(msg.payload[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ou += node.template.join(node.sep) + node.ret;
|
// ou += node.template.join(node.sep) + node.ret;
|
||||||
|
ou += node.template.map(v => v.indexOf(node.sep)!==-1 ? '"'+v+'"' : v).join(node.sep) + node.ret;
|
||||||
if (node.hdrout === "once") { node.hdrSent = true; }
|
if (node.hdrout === "once") { node.hdrSent = true; }
|
||||||
}
|
}
|
||||||
for (var s = 0; s < msg.payload.length; s++) {
|
for (var s = 0; s < msg.payload.length; s++) {
|
||||||
@ -93,7 +90,7 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ((node.template.length === 1) && (node.template[0] === '') && (msg.hasOwnProperty("columns"))) {
|
if ((node.template.length === 1) && (node.template[0] === '') && (msg.hasOwnProperty("columns"))) {
|
||||||
node.template = clean((msg.columns || "").split(","));
|
node.template = clean(msg.columns || "")//.split(","));
|
||||||
}
|
}
|
||||||
if ((node.template.length === 1) && (node.template[0] === '')) {
|
if ((node.template.length === 1) && (node.template[0] === '')) {
|
||||||
/* istanbul ignore else */
|
/* istanbul ignore else */
|
||||||
@ -144,10 +141,11 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
msg.payload = ou;
|
msg.payload = ou;
|
||||||
msg.columns = node.template.join(',');
|
msg.columns = node.template.map(v => v.indexOf(',')!==-1 ? '"'+v+'"' : v).join(',');
|
||||||
if (msg.payload !== '') { node.send(msg); }
|
if (msg.payload !== '') { send(msg); }
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
catch(e) { node.error(e,msg); }
|
catch(e) { done(e); }
|
||||||
}
|
}
|
||||||
else if (typeof msg.payload == "string") { // convert CSV string to object
|
else if (typeof msg.payload == "string") { // convert CSV string to object
|
||||||
try {
|
try {
|
||||||
@ -178,7 +176,7 @@ module.exports = function(RED) {
|
|||||||
if ((node.hdrin === true) && first) { // if the template is in the first line
|
if ((node.hdrin === true) && first) { // if the template is in the first line
|
||||||
if ((line[i] === "\n")||(line[i] === "\r")||(line.length - i === 1)) { // look for first line break
|
if ((line[i] === "\n")||(line[i] === "\r")||(line.length - i === 1)) { // look for first line break
|
||||||
if (line.length - i === 1) { tmp += line[i]; }
|
if (line.length - i === 1) { tmp += line[i]; }
|
||||||
node.template = clean(tmp.split(node.sep));
|
node.template = clean(tmp);
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
else { tmp += line[i]; }
|
else { tmp += line[i]; }
|
||||||
@ -254,22 +252,22 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
if (msg.parts.index + 1 === msg.parts.count) {
|
if (msg.parts.index + 1 === msg.parts.count) {
|
||||||
msg.payload = node.store;
|
msg.payload = node.store;
|
||||||
msg.columns = node.template.filter(val => val).join(',');
|
msg.columns = node.template.map(v => v.indexOf(',')!==-1 ? '"'+v+'"' : v).filter(v => v).join(',');
|
||||||
delete msg.parts;
|
delete msg.parts;
|
||||||
node.send(msg);
|
send(msg);
|
||||||
node.store = [];
|
node.store = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
msg.columns = node.template.filter(val => val).join(',');
|
msg.columns = node.template.map(v => v.indexOf(',')!==-1 ? '"'+v+'"' : v).filter(v => v).join(',');
|
||||||
node.send(msg); // finally send the array
|
send(msg); // finally send the array
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var len = a.length;
|
var len = a.length;
|
||||||
for (var i = 0; i < len; i++) {
|
for (var i = 0; i < len; i++) {
|
||||||
var newMessage = RED.util.cloneMessage(msg);
|
var newMessage = RED.util.cloneMessage(msg);
|
||||||
newMessage.columns = node.template.filter(val => val).join(',');
|
newMessage.columns = node.template.map(v => v.indexOf(',')!==-1 ? '"'+v+'"' : v).filter(v => v).join(',');
|
||||||
newMessage.payload = a[i];
|
newMessage.payload = a[i];
|
||||||
if (!has_parts) {
|
if (!has_parts) {
|
||||||
newMessage.parts = {
|
newMessage.parts = {
|
||||||
@ -286,19 +284,21 @@ module.exports = function(RED) {
|
|||||||
newMessage.parts.count -= 1;
|
newMessage.parts.count -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.send(newMessage);
|
send(newMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.linecount = 0;
|
node.linecount = 0;
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
catch(e) { node.error(e,msg); }
|
catch(e) { done(e); }
|
||||||
}
|
}
|
||||||
else { node.warn(RED._("csv.errors.csv_js")); }
|
else { node.warn(RED._("csv.errors.csv_js")); done(); }
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!msg.hasOwnProperty("reset")) {
|
if (!msg.hasOwnProperty("reset")) {
|
||||||
node.send(msg); // If no payload and not reset - just pass it on.
|
send(msg); // If no payload and not reset - just pass it on.
|
||||||
}
|
}
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -17,18 +17,18 @@
|
|||||||
module.exports = function(RED) {
|
module.exports = function(RED) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
function sendArray(node,msg,array) {
|
function sendArray(node,msg,array,send) {
|
||||||
for (var i = 0; i < array.length-1; i++) {
|
for (var i = 0; i < array.length-1; i++) {
|
||||||
msg.payload = array[i];
|
msg.payload = array[i];
|
||||||
msg.parts.index = node.c++;
|
msg.parts.index = node.c++;
|
||||||
if (node.stream !== true) { msg.parts.count = array.length; }
|
if (node.stream !== true) { msg.parts.count = array.length; }
|
||||||
node.send(RED.util.cloneMessage(msg));
|
send(RED.util.cloneMessage(msg));
|
||||||
}
|
}
|
||||||
if (node.stream !== true) {
|
if (node.stream !== true) {
|
||||||
msg.payload = array[i];
|
msg.payload = array[i];
|
||||||
msg.parts.index = node.c++;
|
msg.parts.index = node.c++;
|
||||||
msg.parts.count = array.length;
|
msg.parts.count = array.length;
|
||||||
node.send(RED.util.cloneMessage(msg));
|
send(RED.util.cloneMessage(msg));
|
||||||
node.c = 0;
|
node.c = 0;
|
||||||
}
|
}
|
||||||
else { node.remainder = array[i]; }
|
else { node.remainder = array[i]; }
|
||||||
@ -67,7 +67,8 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
node.c = 0;
|
node.c = 0;
|
||||||
node.buffer = Buffer.from([]);
|
node.buffer = Buffer.from([]);
|
||||||
this.on("input", function(msg) {
|
node.pendingDones = [];
|
||||||
|
this.on("input", function(msg, send, done) {
|
||||||
if (msg.hasOwnProperty("payload")) {
|
if (msg.hasOwnProperty("payload")) {
|
||||||
if (msg.hasOwnProperty("parts")) { msg.parts = { parts:msg.parts }; } // push existing parts to a stack
|
if (msg.hasOwnProperty("parts")) { msg.parts = { parts:msg.parts }; } // push existing parts to a stack
|
||||||
else { msg.parts = {}; }
|
else { msg.parts = {}; }
|
||||||
@ -93,14 +94,23 @@ module.exports = function(RED) {
|
|||||||
msg.payload = data.substring(pos,pos+node.splt);
|
msg.payload = data.substring(pos,pos+node.splt);
|
||||||
msg.parts.index = node.c++;
|
msg.parts.index = node.c++;
|
||||||
pos += node.splt;
|
pos += node.splt;
|
||||||
node.send(RED.util.cloneMessage(msg));
|
send(RED.util.cloneMessage(msg));
|
||||||
|
}
|
||||||
|
if (count > 1) {
|
||||||
|
node.pendingDones.forEach(d => d());
|
||||||
|
node.pendingDones = [];
|
||||||
}
|
}
|
||||||
node.remainder = data.substring(pos);
|
node.remainder = data.substring(pos);
|
||||||
if ((node.stream !== true) || (node.remainder.length === node.splt)) {
|
if ((node.stream !== true) || (node.remainder.length === node.splt)) {
|
||||||
msg.payload = node.remainder;
|
msg.payload = node.remainder;
|
||||||
msg.parts.index = node.c++;
|
msg.parts.index = node.c++;
|
||||||
node.send(RED.util.cloneMessage(msg));
|
send(RED.util.cloneMessage(msg));
|
||||||
|
node.pendingDones.forEach(d => d());
|
||||||
|
node.pendingDones = [];
|
||||||
|
done();
|
||||||
node.remainder = "";
|
node.remainder = "";
|
||||||
|
} else {
|
||||||
|
node.pendingDones.push(done);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -115,7 +125,8 @@ module.exports = function(RED) {
|
|||||||
a = msg.payload.split(node.splt);
|
a = msg.payload.split(node.splt);
|
||||||
msg.parts.ch = node.splt; // pass the split char to other end for rejoin
|
msg.parts.ch = node.splt; // pass the split char to other end for rejoin
|
||||||
}
|
}
|
||||||
sendArray(node,msg,a);
|
sendArray(node,msg,a,send);
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Array.isArray(msg.payload)) { // then split array into messages
|
else if (Array.isArray(msg.payload)) { // then split array into messages
|
||||||
@ -135,8 +146,9 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
msg.parts.index = i;
|
msg.parts.index = i;
|
||||||
pos += node.arraySplt;
|
pos += node.arraySplt;
|
||||||
node.send(RED.util.cloneMessage(msg));
|
send(RED.util.cloneMessage(msg));
|
||||||
}
|
}
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
else if ((typeof msg.payload === "object") && !Buffer.isBuffer(msg.payload)) {
|
else if ((typeof msg.payload === "object") && !Buffer.isBuffer(msg.payload)) {
|
||||||
var j = 0;
|
var j = 0;
|
||||||
@ -152,10 +164,11 @@ module.exports = function(RED) {
|
|||||||
msg.parts.key = p;
|
msg.parts.key = p;
|
||||||
msg.parts.index = j;
|
msg.parts.index = j;
|
||||||
msg.parts.count = l;
|
msg.parts.count = l;
|
||||||
node.send(RED.util.cloneMessage(msg));
|
send(RED.util.cloneMessage(msg));
|
||||||
j += 1;
|
j += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
else if (Buffer.isBuffer(msg.payload)) {
|
else if (Buffer.isBuffer(msg.payload)) {
|
||||||
var len = node.buffer.length + msg.payload.length;
|
var len = node.buffer.length + msg.payload.length;
|
||||||
@ -176,14 +189,23 @@ module.exports = function(RED) {
|
|||||||
msg.payload = buff.slice(pos,pos+node.splt);
|
msg.payload = buff.slice(pos,pos+node.splt);
|
||||||
msg.parts.index = node.c++;
|
msg.parts.index = node.c++;
|
||||||
pos += node.splt;
|
pos += node.splt;
|
||||||
node.send(RED.util.cloneMessage(msg));
|
send(RED.util.cloneMessage(msg));
|
||||||
|
}
|
||||||
|
if (count > 1) {
|
||||||
|
node.pendingDones.forEach(d => d());
|
||||||
|
node.pendingDones = [];
|
||||||
}
|
}
|
||||||
node.buffer = buff.slice(pos);
|
node.buffer = buff.slice(pos);
|
||||||
if ((node.stream !== true) || (node.buffer.length === node.splt)) {
|
if ((node.stream !== true) || (node.buffer.length === node.splt)) {
|
||||||
msg.payload = node.buffer;
|
msg.payload = node.buffer;
|
||||||
msg.parts.index = node.c++;
|
msg.parts.index = node.c++;
|
||||||
node.send(RED.util.cloneMessage(msg));
|
send(RED.util.cloneMessage(msg));
|
||||||
|
node.pendingDones.forEach(d => d());
|
||||||
|
node.pendingDones = [];
|
||||||
|
done();
|
||||||
node.buffer = Buffer.from([]);
|
node.buffer = Buffer.from([]);
|
||||||
|
} else {
|
||||||
|
node.pendingDones.push(done);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -210,23 +232,34 @@ module.exports = function(RED) {
|
|||||||
while (pos > -1) {
|
while (pos > -1) {
|
||||||
msg.payload = buff.slice(p,pos);
|
msg.payload = buff.slice(p,pos);
|
||||||
msg.parts.index = node.c++;
|
msg.parts.index = node.c++;
|
||||||
node.send(RED.util.cloneMessage(msg));
|
send(RED.util.cloneMessage(msg));
|
||||||
i++;
|
i++;
|
||||||
p = pos+node.splt.length;
|
p = pos+node.splt.length;
|
||||||
pos = buff.indexOf(node.splt,p);
|
pos = buff.indexOf(node.splt,p);
|
||||||
}
|
}
|
||||||
|
if (count > 1) {
|
||||||
|
node.pendingDones.forEach(d => d());
|
||||||
|
node.pendingDones = [];
|
||||||
|
}
|
||||||
if ((node.stream !== true) && (p < buff.length)) {
|
if ((node.stream !== true) && (p < buff.length)) {
|
||||||
msg.payload = buff.slice(p,buff.length);
|
msg.payload = buff.slice(p,buff.length);
|
||||||
msg.parts.index = node.c++;
|
msg.parts.index = node.c++;
|
||||||
msg.parts.count = node.c++;
|
msg.parts.count = node.c++;
|
||||||
node.send(RED.util.cloneMessage(msg));
|
send(RED.util.cloneMessage(msg));
|
||||||
|
node.pendingDones.forEach(d => d());
|
||||||
|
node.pendingDones = [];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
node.buffer = buff.slice(p,buff.length);
|
node.buffer = buff.slice(p,buff.length);
|
||||||
|
node.pendingDones.push(done);
|
||||||
|
}
|
||||||
|
if (node.buffer.length == 0) {
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else { // otherwise drop the message.
|
||||||
//else { } // otherwise drop the message.
|
done();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -264,16 +297,16 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function reduceMessageGroup(node,msgs,exp,fixup,count,accumulator,done) {
|
function reduceMessageGroup(node,msgInfos,exp,fixup,count,accumulator,done) {
|
||||||
var msg = msgs.shift();
|
var msgInfo = msgInfos.shift();
|
||||||
exp.assign("I", msg.parts.index);
|
exp.assign("I", msgInfo.msg.parts.index);
|
||||||
exp.assign("N", count);
|
exp.assign("N", count);
|
||||||
exp.assign("A", accumulator);
|
exp.assign("A", accumulator);
|
||||||
RED.util.evaluateJSONataExpression(exp, msg, (err,result) => {
|
RED.util.evaluateJSONataExpression(exp, msgInfo.msg, (err,result) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return done(err);
|
return done(err);
|
||||||
}
|
}
|
||||||
if (msgs.length === 0) {
|
if (msgInfos.length === 0) {
|
||||||
if (fixup) {
|
if (fixup) {
|
||||||
fixup.assign("N", count);
|
fixup.assign("N", count);
|
||||||
fixup.assign("A", result);
|
fixup.assign("A", result);
|
||||||
@ -281,39 +314,43 @@ module.exports = function(RED) {
|
|||||||
if (err) {
|
if (err) {
|
||||||
return done(err);
|
return done(err);
|
||||||
}
|
}
|
||||||
node.send({payload: result});
|
msgInfo.send({payload: result});
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
node.send({payload: result});
|
msgInfo.send({payload: result});
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reduceMessageGroup(node,msgs,exp,fixup,count,result,done);
|
reduceMessageGroup(node,msgInfos,exp,fixup,count,result,done);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function reduceAndSendGroup(node, group, done) {
|
function reduceAndSendGroup(node, group, done) {
|
||||||
var is_right = node.reduce_right;
|
var is_right = node.reduce_right;
|
||||||
var flag = is_right ? -1 : 1;
|
var flag = is_right ? -1 : 1;
|
||||||
var msgs = group.msgs;
|
var msgInfos = group.msgs;
|
||||||
|
const preservedMsgInfos = [...msgInfos];
|
||||||
try {
|
try {
|
||||||
RED.util.evaluateNodeProperty(node.exp_init, node.exp_init_type, node, {}, (err,accum) => {
|
RED.util.evaluateNodeProperty(node.exp_init, node.exp_init_type, node, {}, (err,accum) => {
|
||||||
var reduceExpression = node.reduceExpression;
|
var reduceExpression = node.reduceExpression;
|
||||||
var fixupExpression = node.fixupExpression;
|
var fixupExpression = node.fixupExpression;
|
||||||
var count = group.count;
|
var count = group.count;
|
||||||
msgs.sort(function(x,y) {
|
msgInfos.sort(function(x,y) {
|
||||||
var ix = x.parts.index;
|
var ix = x.msg.parts.index;
|
||||||
var iy = y.parts.index;
|
var iy = y.msg.parts.index;
|
||||||
if (ix < iy) {return -flag;}
|
if (ix < iy) {return -flag;}
|
||||||
if (ix > iy) {return flag;}
|
if (ix > iy) {return flag;}
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
reduceMessageGroup(node, msgs,reduceExpression,fixupExpression,count,accum,(err,result) => {
|
reduceMessageGroup(node, msgInfos,reduceExpression,fixupExpression,count,accum,(err,result) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
preservedMsgInfos.pop(); // omit last message to emit error message
|
||||||
|
preservedMsgInfos.forEach(mInfo => mInfo.done());
|
||||||
done(err);
|
done(err);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
preservedMsgInfos.forEach(mInfo => mInfo.done());
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -323,7 +360,8 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function reduceMessage(node, msg, done) {
|
function reduceMessage(node, msgInfo, done) {
|
||||||
|
let msg = msgInfo.msg;
|
||||||
if (msg.hasOwnProperty('parts')) {
|
if (msg.hasOwnProperty('parts')) {
|
||||||
var parts = msg.parts;
|
var parts = msg.parts;
|
||||||
var pending = node.pending;
|
var pending = node.pending;
|
||||||
@ -344,7 +382,7 @@ module.exports = function(RED) {
|
|||||||
if (parts.hasOwnProperty('count') && (group.count === undefined)) {
|
if (parts.hasOwnProperty('count') && (group.count === undefined)) {
|
||||||
group.count = parts.count;
|
group.count = parts.count;
|
||||||
}
|
}
|
||||||
msgs.push(msg);
|
msgs.push(msgInfo);
|
||||||
pending_count++;
|
pending_count++;
|
||||||
var completeProcess = function(err) {
|
var completeProcess = function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -353,6 +391,13 @@ module.exports = function(RED) {
|
|||||||
node.pending_count = pending_count;
|
node.pending_count = pending_count;
|
||||||
var max_msgs = maxKeptMsgsCount(node);
|
var max_msgs = maxKeptMsgsCount(node);
|
||||||
if ((max_msgs > 0) && (pending_count > max_msgs)) {
|
if ((max_msgs > 0) && (pending_count > max_msgs)) {
|
||||||
|
Object.values(node.pending).forEach(group => {
|
||||||
|
group.msgs.forEach(mInfo => {
|
||||||
|
if (mInfo.msg._msgid !== msgInfo.msg._msgid) {
|
||||||
|
mInfo.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
node.pending = {};
|
node.pending = {};
|
||||||
node.pending_count = 0;
|
node.pending_count = 0;
|
||||||
done(RED._("join.too-many"));
|
done(RED._("join.too-many"));
|
||||||
@ -368,7 +413,8 @@ module.exports = function(RED) {
|
|||||||
completeProcess();
|
completeProcess();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
node.send(msg);
|
msgInfo.send(msg);
|
||||||
|
msgInfo.done();
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -480,7 +526,9 @@ module.exports = function(RED) {
|
|||||||
delete group.msg.parts;
|
delete group.msg.parts;
|
||||||
}
|
}
|
||||||
delete group.msg.complete;
|
delete group.msg.complete;
|
||||||
node.send(RED.util.cloneMessage(group.msg));
|
group.send(RED.util.cloneMessage(group.msg));
|
||||||
|
group.dones.forEach(f => f());
|
||||||
|
group.dones = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
var pendingMessages = [];
|
var pendingMessages = [];
|
||||||
@ -489,10 +537,10 @@ module.exports = function(RED) {
|
|||||||
// groups may overlap and cause unexpected results. The use of JSONata
|
// groups may overlap and cause unexpected results. The use of JSONata
|
||||||
// means some async processing *might* occur if flow/global context is
|
// means some async processing *might* occur if flow/global context is
|
||||||
// accessed.
|
// accessed.
|
||||||
var processReduceMessageQueue = function(msg) {
|
var processReduceMessageQueue = function(msgInfo) {
|
||||||
if (msg) {
|
if (msgInfo) {
|
||||||
// A new message has arrived - add it to the message queue
|
// A new message has arrived - add it to the message queue
|
||||||
pendingMessages.push(msg);
|
pendingMessages.push(msgInfo);
|
||||||
if (activeMessage !== null) {
|
if (activeMessage !== null) {
|
||||||
// The node is currently processing a message, so do nothing
|
// The node is currently processing a message, so do nothing
|
||||||
// more with this message
|
// more with this message
|
||||||
@ -508,22 +556,23 @@ module.exports = function(RED) {
|
|||||||
|
|
||||||
// There are more messages to process. Get the next message and
|
// There are more messages to process. Get the next message and
|
||||||
// start processing it. Recurse back in to check for any more
|
// start processing it. Recurse back in to check for any more
|
||||||
var nextMsg = pendingMessages.shift();
|
var nextMsgInfo = pendingMessages.shift();
|
||||||
activeMessage = true;
|
activeMessage = true;
|
||||||
reduceMessage(node, nextMsg, err => {
|
reduceMessage(node, nextMsgInfo, err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
node.error(err,nextMsg);
|
nextMsgInfo.done(err);//.error(err,nextMsg);
|
||||||
}
|
}
|
||||||
activeMessage = null;
|
activeMessage = null;
|
||||||
processReduceMessageQueue();
|
processReduceMessageQueue();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
this.on("input", function(msg) {
|
this.on("input", function(msg, send, done) {
|
||||||
try {
|
try {
|
||||||
var property;
|
var property;
|
||||||
if (node.mode === 'auto' && (!msg.hasOwnProperty("parts")||!msg.parts.hasOwnProperty("id"))) {
|
if (node.mode === 'auto' && (!msg.hasOwnProperty("parts")||!msg.parts.hasOwnProperty("id"))) {
|
||||||
node.warn("Message missing msg.parts property - cannot join in 'auto' mode")
|
node.warn("Message missing msg.parts property - cannot join in 'auto' mode")
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -535,6 +584,7 @@ module.exports = function(RED) {
|
|||||||
property = RED.util.getMessageProperty(msg,node.property);
|
property = RED.util.getMessageProperty(msg,node.property);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
node.warn("Message property "+node.property+" not found");
|
node.warn("Message property "+node.property+" not found");
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -557,7 +607,7 @@ module.exports = function(RED) {
|
|||||||
propertyIndex = msg.parts.index;
|
propertyIndex = msg.parts.index;
|
||||||
}
|
}
|
||||||
else if (node.mode === 'reduce') {
|
else if (node.mode === 'reduce') {
|
||||||
return processReduceMessageQueue(msg);
|
return processReduceMessageQueue({msg, send, done});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Use the node configuration to identify all of the group information
|
// Use the node configuration to identify all of the group information
|
||||||
@ -578,9 +628,11 @@ module.exports = function(RED) {
|
|||||||
if (inflight[partId].timeout) {
|
if (inflight[partId].timeout) {
|
||||||
clearTimeout(inflight[partId].timeout);
|
clearTimeout(inflight[partId].timeout);
|
||||||
}
|
}
|
||||||
|
inflight[partId].dones.forEach(f => f());
|
||||||
delete inflight[partId]
|
delete inflight[partId]
|
||||||
}
|
}
|
||||||
return
|
done();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((payloadType === 'object') && (propertyKey === null || propertyKey === undefined || propertyKey === "")) {
|
if ((payloadType === 'object') && (propertyKey === null || propertyKey === undefined || propertyKey === "")) {
|
||||||
@ -591,6 +643,7 @@ module.exports = function(RED) {
|
|||||||
if (msg.hasOwnProperty('complete')) {
|
if (msg.hasOwnProperty('complete')) {
|
||||||
if (inflight[partId]) {
|
if (inflight[partId]) {
|
||||||
inflight[partId].msg.complete = msg.complete;
|
inflight[partId].msg.complete = msg.complete;
|
||||||
|
inflight[partId].send = send;
|
||||||
completeSend(partId);
|
completeSend(partId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -598,6 +651,7 @@ module.exports = function(RED) {
|
|||||||
node.warn("Message missing key property 'msg."+node.key+"' - cannot add to object")
|
node.warn("Message missing key property 'msg."+node.key+"' - cannot add to object")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -608,7 +662,9 @@ module.exports = function(RED) {
|
|||||||
payload:{},
|
payload:{},
|
||||||
targetCount:targetCount,
|
targetCount:targetCount,
|
||||||
type:"object",
|
type:"object",
|
||||||
msg:RED.util.cloneMessage(msg)
|
msg:RED.util.cloneMessage(msg),
|
||||||
|
send: send,
|
||||||
|
dones: []
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -617,7 +673,9 @@ module.exports = function(RED) {
|
|||||||
payload:[],
|
payload:[],
|
||||||
targetCount:targetCount,
|
targetCount:targetCount,
|
||||||
type:payloadType,
|
type:payloadType,
|
||||||
msg:RED.util.cloneMessage(msg)
|
msg:RED.util.cloneMessage(msg),
|
||||||
|
send: send,
|
||||||
|
dones: []
|
||||||
};
|
};
|
||||||
if (payloadType === 'string') {
|
if (payloadType === 'string') {
|
||||||
inflight[partId].joinChar = joinChar;
|
inflight[partId].joinChar = joinChar;
|
||||||
@ -634,6 +692,7 @@ module.exports = function(RED) {
|
|||||||
}, node.timer)
|
}, node.timer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
inflight[partId].dones.push(done);
|
||||||
|
|
||||||
var group = inflight[partId];
|
var group = inflight[partId];
|
||||||
if (payloadType === 'buffer') {
|
if (payloadType === 'buffer') {
|
||||||
@ -642,7 +701,7 @@ module.exports = function(RED) {
|
|||||||
inflight[partId].bufferLen += property.length;
|
inflight[partId].bufferLen += property.length;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
node.error(RED._("join.errors.invalid-type",{error:(typeof property)}),msg);
|
done(RED._("join.errors.invalid-type",{error:(typeof property)}));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -676,13 +735,18 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
group.msg = Object.assign(group.msg, msg);
|
group.msg = Object.assign(group.msg, msg);
|
||||||
|
group.send = send;
|
||||||
var tcnt = group.targetCount;
|
var tcnt = group.targetCount;
|
||||||
if (msg.hasOwnProperty("parts")) { tcnt = group.targetCount || msg.parts.count; }
|
if (msg.hasOwnProperty("parts")) {
|
||||||
|
tcnt = group.targetCount || msg.parts.count;
|
||||||
|
group.targetCount = tcnt;
|
||||||
|
}
|
||||||
if ((tcnt > 0 && group.currentCount >= tcnt) || msg.hasOwnProperty('complete')) {
|
if ((tcnt > 0 && group.currentCount >= tcnt) || msg.hasOwnProperty('complete')) {
|
||||||
completeSend(partId);
|
completeSend(partId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(err) {
|
catch(err) {
|
||||||
|
done(err);
|
||||||
console.log(err.stack);
|
console.log(err.stack);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -691,9 +755,11 @@ module.exports = function(RED) {
|
|||||||
for (var i in inflight) {
|
for (var i in inflight) {
|
||||||
if (inflight.hasOwnProperty(i)) {
|
if (inflight.hasOwnProperty(i)) {
|
||||||
clearTimeout(inflight[i].timeout);
|
clearTimeout(inflight[i].timeout);
|
||||||
|
inflight[i].dones.forEach(d => d());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
RED.nodes.registerType("join",JoinNode);
|
RED.nodes.registerType("join",JoinNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,16 +81,16 @@ module.exports = function(RED) {
|
|||||||
|
|
||||||
function sortMessageGroup(group) {
|
function sortMessageGroup(group) {
|
||||||
var promise;
|
var promise;
|
||||||
var msgs = group.msgs;
|
var msgInfos = group.msgInfos;
|
||||||
if (key_is_exp) {
|
if (key_is_exp) {
|
||||||
var evaluatedDataPromises = msgs.map(msg => {
|
var evaluatedDataPromises = msgInfos.map(mInfo => {
|
||||||
return new Promise((resolve,reject) => {
|
return new Promise((resolve,reject) => {
|
||||||
RED.util.evaluateJSONataExpression(key_exp, msg, (err, result) => {
|
RED.util.evaluateJSONataExpression(key_exp, mInfo.msg, (err, result) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(RED._("sort.invalid-exp",{message:err.toString()}));
|
reject(RED._("sort.invalid-exp",{message:err.toString()}));
|
||||||
} else {
|
} else {
|
||||||
resolve({
|
resolve({
|
||||||
item: msg,
|
item: mInfo,
|
||||||
sortValue: result
|
sortValue: result
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -106,20 +106,21 @@ module.exports = function(RED) {
|
|||||||
var key = function(msg) {
|
var key = function(msg) {
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
var comp = generateComparisonFunction(msg => RED.util.getMessageProperty(msg, key_prop));
|
var comp = generateComparisonFunction(mInfo => RED.util.getMessageProperty(mInfo.msg, key_prop));
|
||||||
try {
|
try {
|
||||||
msgs.sort(comp);
|
msgInfos.sort(comp);
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
return; // not send when error
|
return; // not send when error
|
||||||
}
|
}
|
||||||
promise = Promise.resolve(msgs);
|
promise = Promise.resolve(msgInfos);
|
||||||
}
|
}
|
||||||
return promise.then(msgs => {
|
return promise.then(msgInfos => {
|
||||||
for (var i = 0; i < msgs.length; i++) {
|
for (let i = 0; i < msgInfos.length; i++) {
|
||||||
var msg = msgs[i];
|
const msg = msgInfos[i].msg;
|
||||||
msg.parts.index = i;
|
msg.parts.index = i;
|
||||||
node.send(msg);
|
msgInfos[i].send(msg);
|
||||||
|
msgInfos[i].done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -181,65 +182,79 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(oldest !== undefined) {
|
if(oldest !== undefined) {
|
||||||
|
oldest.msgInfos[oldest.msgInfos.length - 1].done(RED._("sort.too-many"));
|
||||||
|
for (let i = 0; i < oldest.msgInfos.length - 1; i++) {
|
||||||
|
oldest.msgInfos[i].done();
|
||||||
|
}
|
||||||
delete pending[oldest_key];
|
delete pending[oldest_key];
|
||||||
return oldest.msgs.length;
|
return oldest.msgInfos.length;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function processMessage(msg) {
|
function processMessage(msgInfo) {
|
||||||
|
const msg = msgInfo.msg;
|
||||||
if (target_is_prop) {
|
if (target_is_prop) {
|
||||||
sortMessageProperty(msg).then(send => {
|
sortMessageProperty(msg).then(send => {
|
||||||
if (send) {
|
if (send) {
|
||||||
node.send(msg);
|
msgInfo.send(msg);
|
||||||
}
|
}
|
||||||
|
msgInfo.done();
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
node.error(err,msg);
|
msgInfo.done(err);
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var parts = msg.parts;
|
var parts = msg.parts;
|
||||||
if (!parts || !parts.hasOwnProperty("id") || !parts.hasOwnProperty("index")) {
|
if (!parts || !parts.hasOwnProperty("id") || !parts.hasOwnProperty("index")) {
|
||||||
|
msgInfo.done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var gid = parts.id;
|
var gid = parts.id;
|
||||||
if (!pending.hasOwnProperty(gid)) {
|
if (!pending.hasOwnProperty(gid)) {
|
||||||
pending[gid] = {
|
pending[gid] = {
|
||||||
count: undefined,
|
count: undefined,
|
||||||
msgs: [],
|
msgInfos: [],
|
||||||
seq_no: pending_id++
|
seq_no: pending_id++
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
var group = pending[gid];
|
var group = pending[gid];
|
||||||
var msgs = group.msgs;
|
var msgInfos = group.msgInfos;
|
||||||
msgs.push(msg);
|
msgInfos.push(msgInfo);
|
||||||
if (parts.hasOwnProperty("count")) {
|
if (parts.hasOwnProperty("count")) {
|
||||||
group.count = parts.count;
|
group.count = parts.count;
|
||||||
}
|
}
|
||||||
pending_count++;
|
pending_count++;
|
||||||
if (group.count === msgs.length) {
|
if (group.count === msgInfos.length) {
|
||||||
delete pending[gid]
|
delete pending[gid]
|
||||||
sortMessageGroup(group).catch(err => {
|
sortMessageGroup(group).catch(err => {
|
||||||
node.error(err,msg);
|
// throw an error for last message, and just call done() for remaining messages
|
||||||
|
msgInfos[msgInfos.length-1].done(err);
|
||||||
|
for (let i = 0; i < msgInfos.length - 1; i++) {
|
||||||
|
msgInfos[i].done()
|
||||||
|
};
|
||||||
});
|
});
|
||||||
pending_count -= msgs.length;
|
pending_count -= msgInfos.length;
|
||||||
} else {
|
} else {
|
||||||
var max_msgs = max_kept_msgs_count(node);
|
var max_msgs = max_kept_msgs_count(node);
|
||||||
if ((max_msgs > 0) && (pending_count > max_msgs)) {
|
if ((max_msgs > 0) && (pending_count > max_msgs)) {
|
||||||
pending_count -= removeOldestPending();
|
pending_count -= removeOldestPending();
|
||||||
node.error(RED._("sort.too-many"), msg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.on("input", function(msg) {
|
this.on("input", function(msg, send, done) {
|
||||||
processMessage(msg);
|
processMessage({msg, send, done});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.on("close", function() {
|
this.on("close", function() {
|
||||||
for(var key in pending) {
|
for(var key in pending) {
|
||||||
if (pending.hasOwnProperty(key)) {
|
if (pending.hasOwnProperty(key)) {
|
||||||
node.log(RED._("sort.clear"), pending[key].msgs[0]);
|
node.log(RED._("sort.clear"), pending[key].msgInfos[0]);
|
||||||
|
const group = pending[key];
|
||||||
|
group.msgInfos.forEach(mInfo => {
|
||||||
|
mInfo.done();
|
||||||
|
});
|
||||||
delete pending[key];
|
delete pending[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,11 +32,11 @@ module.exports = function(RED) {
|
|||||||
return _max_kept_msgs_count;
|
return _max_kept_msgs_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
function send_msgs(node, msgs, clone_msg) {
|
function send_msgs(node, msgInfos, clone_msg) {
|
||||||
var count = msgs.length;
|
var count = msgInfos.length;
|
||||||
var msg_id = msgs[0]._msgid;
|
var msg_id = msgInfos[0].msg._msgid;
|
||||||
for (var i = 0; i < count; i++) {
|
for (var i = 0; i < count; i++) {
|
||||||
var msg = clone_msg ? RED.util.cloneMessage(msgs[i]) : msgs[i];
|
var msg = clone_msg ? RED.util.cloneMessage(msgInfos[i].msg) : msgInfos[i].msg;
|
||||||
if (!msg.hasOwnProperty("parts")) {
|
if (!msg.hasOwnProperty("parts")) {
|
||||||
msg.parts = {};
|
msg.parts = {};
|
||||||
}
|
}
|
||||||
@ -44,14 +44,16 @@ module.exports = function(RED) {
|
|||||||
parts.id = msg_id;
|
parts.id = msg_id;
|
||||||
parts.index = i;
|
parts.index = i;
|
||||||
parts.count = count;
|
parts.count = count;
|
||||||
node.send(msg);
|
msgInfos[i].send(msg);
|
||||||
|
//msgInfos[i].done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function send_interval(node, allow_empty_seq) {
|
function send_interval(node, allow_empty_seq) {
|
||||||
let msgs = node.pending;
|
let msgInfos = node.pending;
|
||||||
if (msgs.length > 0) {
|
if (msgInfos.length > 0) {
|
||||||
send_msgs(node, msgs, false);
|
send_msgs(node, msgInfos, false);
|
||||||
|
msgInfos.forEach(e => e.done());
|
||||||
node.pending = [];
|
node.pending = [];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -108,19 +110,20 @@ module.exports = function(RED) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var msgs = [];
|
var msgInfos = [];
|
||||||
for (var topic of topics) {
|
for (var topic of topics) {
|
||||||
var t_msgs = get_msgs_of_topic(pending, topic);
|
var t_msgInfos = get_msgs_of_topic(pending, topic);
|
||||||
msgs = msgs.concat(t_msgs);
|
msgInfos = msgInfos.concat(t_msgInfos);
|
||||||
}
|
}
|
||||||
for (var topic of topics) {
|
for (var topic of topics) {
|
||||||
remove_topic(pending, topic);
|
remove_topic(pending, topic);
|
||||||
}
|
}
|
||||||
send_msgs(node, msgs, true);
|
send_msgs(node, msgInfos, true);
|
||||||
node.pending_count -= msgs.length;
|
msgInfos.forEach(e => e.done() );
|
||||||
|
node.pending_count -= msgInfos.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_to_topic_group(pending, topic, gid, msg) {
|
function add_to_topic_group(pending, topic, gid, msgInfo) {
|
||||||
if (!pending.hasOwnProperty(topic)) {
|
if (!pending.hasOwnProperty(topic)) {
|
||||||
pending[topic] = { groups: {}, gids: [] };
|
pending[topic] = { groups: {}, gids: [] };
|
||||||
}
|
}
|
||||||
@ -132,32 +135,43 @@ module.exports = function(RED) {
|
|||||||
gids.push(gid);
|
gids.push(gid);
|
||||||
}
|
}
|
||||||
var group = groups[gid];
|
var group = groups[gid];
|
||||||
group.msgs.push(msg);
|
group.msgs.push(msgInfo);
|
||||||
if ((group.count === undefined) &&
|
if ((group.count === undefined) &&
|
||||||
msg.parts.hasOwnProperty('count')) {
|
msgInfo.msg.parts.hasOwnProperty('count')) {
|
||||||
group.count = msg.parts.count;
|
group.count = msgInfo.msg.parts.count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function concat_msg(node, msg) {
|
function concat_msg(node, msg, send, done) {
|
||||||
var topic = msg.topic;
|
var topic = msg.topic;
|
||||||
if(node.topics.indexOf(topic) >= 0) {
|
if(node.topics.indexOf(topic) >= 0) {
|
||||||
if (!msg.hasOwnProperty("parts") ||
|
if (!msg.hasOwnProperty("parts") ||
|
||||||
!msg.parts.hasOwnProperty("id") ||
|
!msg.parts.hasOwnProperty("id") ||
|
||||||
!msg.parts.hasOwnProperty("index") ||
|
!msg.parts.hasOwnProperty("index") ||
|
||||||
!msg.parts.hasOwnProperty("count")) {
|
!msg.parts.hasOwnProperty("count")) {
|
||||||
node.error(RED._("batch.no-parts"), msg);
|
done(RED._("batch.no-parts"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var gid = msg.parts.id;
|
var gid = msg.parts.id;
|
||||||
var pending = node.pending;
|
var pending = node.pending;
|
||||||
add_to_topic_group(pending, topic, gid, msg);
|
add_to_topic_group(pending, topic, gid, {msg, send, done});
|
||||||
node.pending_count++;
|
node.pending_count++;
|
||||||
var max_msgs = max_kept_msgs_count(node);
|
var max_msgs = max_kept_msgs_count(node);
|
||||||
if ((max_msgs > 0) && (node.pending_count > max_msgs)) {
|
if ((max_msgs > 0) && (node.pending_count > max_msgs)) {
|
||||||
|
Object.values(node.pending).forEach(p_topic => {
|
||||||
|
Object.values(p_topic.groups).forEach(group => {
|
||||||
|
group.msgs.forEach(msgInfo => {
|
||||||
|
if (msgInfo.msg.id === msg.id) {
|
||||||
|
// the message that caused the overflow
|
||||||
|
msgInfo.done(RED._("batch.too-many"));
|
||||||
|
} else {
|
||||||
|
msgInfo.done();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
});
|
||||||
node.pending = {};
|
node.pending = {};
|
||||||
node.pending_count = 0;
|
node.pending_count = 0;
|
||||||
node.error(RED._("batch.too-many"), msg);
|
|
||||||
}
|
}
|
||||||
try_concat(node, pending);
|
try_concat(node, pending);
|
||||||
}
|
}
|
||||||
@ -178,29 +192,37 @@ module.exports = function(RED) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
node.pending = [];
|
node.pending = [];
|
||||||
this.on("input", function(msg) {
|
this.on("input", function(msg, send, done) {
|
||||||
if (msg.hasOwnProperty("reset")) {
|
if (msg.hasOwnProperty("reset")) {
|
||||||
|
node.pending.forEach(e => e.done());
|
||||||
node.pending = [];
|
node.pending = [];
|
||||||
node.pending_count = 0;
|
node.pending_count = 0;
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var queue = node.pending;
|
var queue = node.pending;
|
||||||
queue.push(msg);
|
queue.push({msg, send, done});
|
||||||
node.pending_count++;
|
node.pending_count++;
|
||||||
if (queue.length === count) {
|
if (queue.length === count) {
|
||||||
send_msgs(node, queue, is_overlap);
|
send_msgs(node, queue, is_overlap);
|
||||||
|
for (let i = 0; i < queue.length-overlap; i++) {
|
||||||
|
queue[i].done();
|
||||||
|
}
|
||||||
node.pending =
|
node.pending =
|
||||||
(overlap === 0) ? [] : queue.slice(-overlap);
|
(overlap === 0) ? [] : queue.slice(-overlap);
|
||||||
node.pending_count = 0;
|
node.pending_count = 0;
|
||||||
}
|
}
|
||||||
var max_msgs = max_kept_msgs_count(node);
|
var max_msgs = max_kept_msgs_count(node);
|
||||||
if ((max_msgs > 0) && (node.pending_count > max_msgs)) {
|
if ((max_msgs > 0) && (node.pending_count > max_msgs)) {
|
||||||
|
let lastMInfo = node.pending.pop();
|
||||||
|
lastMInfo.done(RED._("batch.too-many"));
|
||||||
|
node.pending.forEach(e => e.done());
|
||||||
node.pending = [];
|
node.pending = [];
|
||||||
node.pending_count = 0;
|
node.pending_count = 0;
|
||||||
node.error(RED._("batch.too-many"), msg);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.on("close", function() {
|
this.on("close", function() {
|
||||||
|
node.pending.forEach(e=> e.done());
|
||||||
node.pending_count = 0;
|
node.pending_count = 0;
|
||||||
node.pending = [];
|
node.pending = [];
|
||||||
});
|
});
|
||||||
@ -217,31 +239,36 @@ module.exports = function(RED) {
|
|||||||
if (interval > 0) {
|
if (interval > 0) {
|
||||||
timer = setInterval(msgHandler, interval);
|
timer = setInterval(msgHandler, interval);
|
||||||
}
|
}
|
||||||
this.on("input", function(msg) {
|
this.on("input", function(msg, send, done) {
|
||||||
if (msg.hasOwnProperty("reset")) {
|
if (msg.hasOwnProperty("reset")) {
|
||||||
if (timer !== undefined) {
|
if (timer !== undefined) {
|
||||||
clearInterval(timer);
|
clearInterval(timer);
|
||||||
}
|
}
|
||||||
|
node.pending.forEach(e => e.done());
|
||||||
node.pending = [];
|
node.pending = [];
|
||||||
node.pending_count = 0;
|
node.pending_count = 0;
|
||||||
|
done();
|
||||||
if (interval > 0) {
|
if (interval > 0) {
|
||||||
timer = setInterval(msgHandler, interval);
|
timer = setInterval(msgHandler, interval);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
node.pending.push(msg);
|
node.pending.push({msg, send, done});
|
||||||
node.pending_count++;
|
node.pending_count++;
|
||||||
var max_msgs = max_kept_msgs_count(node);
|
var max_msgs = max_kept_msgs_count(node);
|
||||||
if ((max_msgs > 0) && (node.pending_count > max_msgs)) {
|
if ((max_msgs > 0) && (node.pending_count > max_msgs)) {
|
||||||
|
let lastMInfo = node.pending.pop();
|
||||||
|
lastMInfo.done(RED._("batch.too-many"));
|
||||||
|
node.pending.forEach(e => e.done());
|
||||||
node.pending = [];
|
node.pending = [];
|
||||||
node.pending_count = 0;
|
node.pending_count = 0;
|
||||||
node.error(RED._("batch.too-many"), msg);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.on("close", function() {
|
this.on("close", function() {
|
||||||
if (timer !== undefined) {
|
if (timer !== undefined) {
|
||||||
clearInterval(timer);
|
clearInterval(timer);
|
||||||
}
|
}
|
||||||
|
node.pending.forEach(e => e.done());
|
||||||
node.pending = [];
|
node.pending = [];
|
||||||
node.pending_count = 0;
|
node.pending_count = 0;
|
||||||
});
|
});
|
||||||
@ -251,15 +278,26 @@ module.exports = function(RED) {
|
|||||||
return x.topic;
|
return x.topic;
|
||||||
});
|
});
|
||||||
node.pending = {};
|
node.pending = {};
|
||||||
this.on("input", function(msg) {
|
this.on("input", function(msg, send, done) {
|
||||||
if (msg.hasOwnProperty("reset")) {
|
if (msg.hasOwnProperty("reset")) {
|
||||||
|
Object.values(node.pending).forEach(p_topic => {
|
||||||
|
Object.values(p_topic.groups).forEach(group => {
|
||||||
|
group.msgs.forEach(e => e.done());
|
||||||
|
});
|
||||||
|
});
|
||||||
node.pending = {};
|
node.pending = {};
|
||||||
node.pending_count = 0;
|
node.pending_count = 0;
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
concat_msg(node, msg);
|
concat_msg(node, msg, send, done);
|
||||||
});
|
});
|
||||||
this.on("close", function() {
|
this.on("close", function() {
|
||||||
|
Object.values(node.pending).forEach(p_topic => {
|
||||||
|
Object.values(p_topic.groups).forEach(group => {
|
||||||
|
group.msgs.forEach(e => e.done());
|
||||||
|
});
|
||||||
|
});
|
||||||
node.pending = {};
|
node.pending = {};
|
||||||
node.pending_count = 0;
|
node.pending_count = 0;
|
||||||
});
|
});
|
||||||
|
@ -0,0 +1,99 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "330f4888.cccb28",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 260,
|
||||||
|
"y": 180,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"ed11f8d6.5e3c88"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a0288b44.71d488",
|
||||||
|
"type": "csv",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"sep": ",",
|
||||||
|
"hdrin": "",
|
||||||
|
"hdrout": "none",
|
||||||
|
"multi": "one",
|
||||||
|
"ret": "\\n",
|
||||||
|
"temp": "",
|
||||||
|
"skip": "0",
|
||||||
|
"strings": true,
|
||||||
|
"include_empty_strings": "",
|
||||||
|
"include_null_values": "",
|
||||||
|
"x": 600,
|
||||||
|
"y": 180,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"369cbe42.4af9f2"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ed11f8d6.5e3c88",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "CSV data",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "text",
|
||||||
|
"syntax": "mustache",
|
||||||
|
"template": "Apple,100,Canada\nOrange,120,USA\nBanana,80,Philippines",
|
||||||
|
"output": "str",
|
||||||
|
"x": 430,
|
||||||
|
"y": 180,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"a0288b44.71d488"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "369cbe42.4af9f2",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 780,
|
||||||
|
"y": 180,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "783cfaa6.52fbe4",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Parse CSV with default column name as messages",
|
||||||
|
"info": "CSV node can parse input CSV data.\nParsed CSV record can be sent as a message sequence.\nEach message payload points to an object with `col`*N* as a key and CSV value as a value.\n",
|
||||||
|
"x": 330,
|
||||||
|
"y": 120,
|
||||||
|
"wires": []
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,99 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "98c9d44d.4457b8",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 260,
|
||||||
|
"y": 360,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"65476517.3d760c"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "76df98f7.0dcd08",
|
||||||
|
"type": "csv",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"sep": ",",
|
||||||
|
"hdrin": "",
|
||||||
|
"hdrout": "none",
|
||||||
|
"multi": "mult",
|
||||||
|
"ret": "\\n",
|
||||||
|
"temp": "",
|
||||||
|
"skip": "0",
|
||||||
|
"strings": true,
|
||||||
|
"include_empty_strings": "",
|
||||||
|
"include_null_values": "",
|
||||||
|
"x": 600,
|
||||||
|
"y": 360,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"557979e0.e6b588"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "65476517.3d760c",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "CSV data",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "text",
|
||||||
|
"syntax": "mustache",
|
||||||
|
"template": "Apple,100,Canada\nOrange,120,USA\nBanana,80,Philippines",
|
||||||
|
"output": "str",
|
||||||
|
"x": 430,
|
||||||
|
"y": 360,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"76df98f7.0dcd08"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "557979e0.e6b588",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 780,
|
||||||
|
"y": 360,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "187f4ab3.4c9ab5",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Parse CSV with default column name as array",
|
||||||
|
"info": "CSV node can send a single message with array of parsed CSV records.\nEach element of the array consists of objects with key-value pair.",
|
||||||
|
"x": 320,
|
||||||
|
"y": 300,
|
||||||
|
"wires": []
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,99 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "1216e95b.1b1e87",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 260,
|
||||||
|
"y": 560,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"e41ffbbc.de2ed8"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "286828bc.9233c8",
|
||||||
|
"type": "csv",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"sep": ",",
|
||||||
|
"hdrin": "",
|
||||||
|
"hdrout": "none",
|
||||||
|
"multi": "one",
|
||||||
|
"ret": "\\n",
|
||||||
|
"temp": "kind,price,origin",
|
||||||
|
"skip": "0",
|
||||||
|
"strings": true,
|
||||||
|
"include_empty_strings": "",
|
||||||
|
"include_null_values": "",
|
||||||
|
"x": 600,
|
||||||
|
"y": 560,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"9d8218c.5550ee8"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "e41ffbbc.de2ed8",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "CSV data",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "text",
|
||||||
|
"syntax": "mustache",
|
||||||
|
"template": "Apple,100,Canada\nOrange,120,USA\nBanana,80,Philippines",
|
||||||
|
"output": "str",
|
||||||
|
"x": 430,
|
||||||
|
"y": 560,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"286828bc.9233c8"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "9d8218c.5550ee8",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 780,
|
||||||
|
"y": 560,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "aaa1ee8f.21e2c",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Parse CSV with specified column name as messages",
|
||||||
|
"info": "CSV node can specify column name of parsed objects in its settings panel.",
|
||||||
|
"x": 340,
|
||||||
|
"y": 500,
|
||||||
|
"wires": []
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,99 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "24093558.0315aa",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 260,
|
||||||
|
"y": 740,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"80abaee1.5fa7f"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d4d2ca3f.1d9488",
|
||||||
|
"type": "csv",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"sep": ",",
|
||||||
|
"hdrin": true,
|
||||||
|
"hdrout": "none",
|
||||||
|
"multi": "one",
|
||||||
|
"ret": "\\n",
|
||||||
|
"temp": "",
|
||||||
|
"skip": "0",
|
||||||
|
"strings": true,
|
||||||
|
"include_empty_strings": "",
|
||||||
|
"include_null_values": "",
|
||||||
|
"x": 600,
|
||||||
|
"y": 740,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"b52791c3.08967"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "80abaee1.5fa7f",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "CSV data",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "text",
|
||||||
|
"syntax": "mustache",
|
||||||
|
"template": "kind,price,origin\nApple,100,Canada\nOrange,120,USA\nBanana,80,Philippines",
|
||||||
|
"output": "str",
|
||||||
|
"x": 430,
|
||||||
|
"y": 740,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"d4d2ca3f.1d9488"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "b52791c3.08967",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 780,
|
||||||
|
"y": 740,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "85091361.85644",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Parse CSV with column name in first row as messages",
|
||||||
|
"info": "CSV node can use first row of input CSV text as a column name of each record object.\n",
|
||||||
|
"x": 340,
|
||||||
|
"y": 680,
|
||||||
|
"wires": []
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,99 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "9e93169c.b763a8",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Convert JavaScript object to CSV",
|
||||||
|
"info": "CSV node can convert a JavaScript object to CSV text.\nEach object contains key-value pair of specified properties.\n",
|
||||||
|
"x": 270,
|
||||||
|
"y": 860,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8ca41fee.3303d",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 260,
|
||||||
|
"y": 920,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"c466905b.e8c61"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "65146d20.d78204",
|
||||||
|
"type": "csv",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"sep": ",",
|
||||||
|
"hdrin": false,
|
||||||
|
"hdrout": "none",
|
||||||
|
"multi": "one",
|
||||||
|
"ret": "\\n",
|
||||||
|
"temp": "kind,price",
|
||||||
|
"skip": "0",
|
||||||
|
"strings": true,
|
||||||
|
"include_empty_strings": "",
|
||||||
|
"include_null_values": "",
|
||||||
|
"x": 600,
|
||||||
|
"y": 920,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"92e99e67.a37d8"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "c466905b.e8c61",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "JS object",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "json",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "{\n \"kind\": \"Apple\",\n \"price\": 100,\n \"origin\": \"Canada\"\n}",
|
||||||
|
"output": "json",
|
||||||
|
"x": 430,
|
||||||
|
"y": 920,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"65146d20.d78204"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "92e99e67.a37d8",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 780,
|
||||||
|
"y": 920,
|
||||||
|
"wires": []
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,99 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "e89019c5.70ae78",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Convert array of JavaScript objects to CSV",
|
||||||
|
"info": "CSV node can convert an array of JavaScript objects to multi-line CSV text.",
|
||||||
|
"x": 300,
|
||||||
|
"y": 1020,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "bd0d82ed.7b28",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 260,
|
||||||
|
"y": 1080,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"1d857b8d.3a4014"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "66a37667.16ebd8",
|
||||||
|
"type": "csv",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"sep": ",",
|
||||||
|
"hdrin": false,
|
||||||
|
"hdrout": "none",
|
||||||
|
"multi": "one",
|
||||||
|
"ret": "\\n",
|
||||||
|
"temp": "kind,price",
|
||||||
|
"skip": "0",
|
||||||
|
"strings": true,
|
||||||
|
"include_empty_strings": "",
|
||||||
|
"include_null_values": "",
|
||||||
|
"x": 600,
|
||||||
|
"y": 1080,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"859725fd.dc93d8"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "1d857b8d.3a4014",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "JS object",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "json",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "[\n {\n \"kind\": \"Apple\",\n \"price\": 100,\n \"origin\": \"Canada\"\n },\n {\n \"kind\": \"Orange\",\n \"price\": 120,\n \"origin\": \"USA\"\n },\n {\n \"kind\": \"Banana\",\n \"price\": 80,\n \"origin\": \"Philippines\"\n }\n]",
|
||||||
|
"output": "json",
|
||||||
|
"x": 430,
|
||||||
|
"y": 1080,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"66a37667.16ebd8"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "859725fd.dc93d8",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 780,
|
||||||
|
"y": 1080,
|
||||||
|
"wires": []
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,99 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "2ebdd51e.c5d17a",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Convert array of JavaScript objects to CSV with column name header",
|
||||||
|
"info": "CSV node can convert an array of JavaScript objects to multi-line CSV text with column name header at first line.",
|
||||||
|
"x": 390,
|
||||||
|
"y": 1200,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2b4d538d.ada07c",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 260,
|
||||||
|
"y": 1260,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"3e5c9e8.5065b62"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "db02c7be.0984e8",
|
||||||
|
"type": "csv",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"sep": ",",
|
||||||
|
"hdrin": false,
|
||||||
|
"hdrout": "all",
|
||||||
|
"multi": "one",
|
||||||
|
"ret": "\\n",
|
||||||
|
"temp": "kind,price",
|
||||||
|
"skip": "0",
|
||||||
|
"strings": true,
|
||||||
|
"include_empty_strings": "",
|
||||||
|
"include_null_values": "",
|
||||||
|
"x": 600,
|
||||||
|
"y": 1260,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"61f8b772.ddb1f8"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3e5c9e8.5065b62",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "JS object",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "json",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "[\n {\n \"kind\": \"Apple\",\n \"price\": 100,\n \"origin\": \"Canada\"\n },\n {\n \"kind\": \"Orange\",\n \"price\": 120,\n \"origin\": \"USA\"\n },\n {\n \"kind\": \"Banana\",\n \"price\": 80,\n \"origin\": \"Philippines\"\n }\n]",
|
||||||
|
"output": "json",
|
||||||
|
"x": 430,
|
||||||
|
"y": 1260,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"db02c7be.0984e8"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "61f8b772.ddb1f8",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 780,
|
||||||
|
"y": 1260,
|
||||||
|
"wires": []
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,99 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "2ebdd51e.c5d17a",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Convert array of JavaScript objects to CSV with column name header",
|
||||||
|
"info": "CSV node can convert an array of JavaScript objects to multi-line CSV text with column name header at first line.",
|
||||||
|
"x": 390,
|
||||||
|
"y": 1200,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2b4d538d.ada07c",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 260,
|
||||||
|
"y": 1260,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"3e5c9e8.5065b62"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "db02c7be.0984e8",
|
||||||
|
"type": "csv",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"sep": ",",
|
||||||
|
"hdrin": false,
|
||||||
|
"hdrout": "all",
|
||||||
|
"multi": "one",
|
||||||
|
"ret": "\\n",
|
||||||
|
"temp": "kind,price",
|
||||||
|
"skip": "0",
|
||||||
|
"strings": true,
|
||||||
|
"include_empty_strings": "",
|
||||||
|
"include_null_values": "",
|
||||||
|
"x": 600,
|
||||||
|
"y": 1260,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"61f8b772.ddb1f8"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3e5c9e8.5065b62",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "JS object",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "json",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "[\n {\n \"kind\": \"Apple\",\n \"price\": 100,\n \"origin\": \"Canada\"\n },\n {\n \"kind\": \"Orange\",\n \"price\": 120,\n \"origin\": \"USA\"\n },\n {\n \"kind\": \"Banana\",\n \"price\": 80,\n \"origin\": \"Philippines\"\n }\n]",
|
||||||
|
"output": "json",
|
||||||
|
"x": 430,
|
||||||
|
"y": 1260,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"db02c7be.0984e8"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "61f8b772.ddb1f8",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 780,
|
||||||
|
"y": 1260,
|
||||||
|
"wires": []
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,200 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "1ae28939.9f5fc7",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Send column name when reset property set",
|
||||||
|
"info": "CSV node can send column names at first or `reset` property exists in input message.",
|
||||||
|
"x": 310,
|
||||||
|
"y": 1540,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "c16ad95b.4f9ac8",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Apple",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 250,
|
||||||
|
"y": 1600,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"7f7bfc72.aed104"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "870620b9.95343",
|
||||||
|
"type": "csv",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"sep": ",",
|
||||||
|
"hdrin": false,
|
||||||
|
"hdrout": "once",
|
||||||
|
"multi": "one",
|
||||||
|
"ret": "\\n",
|
||||||
|
"temp": "kind,price",
|
||||||
|
"skip": "0",
|
||||||
|
"strings": true,
|
||||||
|
"include_empty_strings": "",
|
||||||
|
"include_null_values": "",
|
||||||
|
"x": 650,
|
||||||
|
"y": 1720,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"d960de42.619c7"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "7f7bfc72.aed104",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "JS object",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "json",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "{\n \"kind\": \"Apple\",\n \"price\": 100,\n \"origin\": \"Canada\"\n}",
|
||||||
|
"output": "json",
|
||||||
|
"x": 470,
|
||||||
|
"y": 1600,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"870620b9.95343"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d960de42.619c7",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 830,
|
||||||
|
"y": 1720,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6f8296e.f95ca68",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Orange",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 250,
|
||||||
|
"y": 1660,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"c37d0dfa.ec1ab"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "c37d0dfa.ec1ab",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "JS object",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "json",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "{\n \"kind\": \"Orange\",\n \"price\": 120,\n \"origin\": \"USA\"\n}\n",
|
||||||
|
"output": "json",
|
||||||
|
"x": 470,
|
||||||
|
"y": 1660,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"870620b9.95343"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "35209fe2.16926",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Banana & reset",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "reset",
|
||||||
|
"v": "",
|
||||||
|
"vt": "date"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 280,
|
||||||
|
"y": 1720,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"afd4e6b3.624a28"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "afd4e6b3.624a28",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "JS object",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "json",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "{\n \"kind\": \"Banana\",\n \"price\": 80,\n \"origin\": \"Philippines\"\n}",
|
||||||
|
"output": "json",
|
||||||
|
"x": 470,
|
||||||
|
"y": 1720,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"870620b9.95343"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,150 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "195c168c.44f149",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 260,
|
||||||
|
"y": 1900,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"b270564c.171908"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8ec8cf9e.103fa",
|
||||||
|
"type": "csv",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"sep": ",",
|
||||||
|
"hdrin": true,
|
||||||
|
"hdrout": "none",
|
||||||
|
"multi": "one",
|
||||||
|
"ret": "\\n",
|
||||||
|
"temp": "",
|
||||||
|
"skip": "0",
|
||||||
|
"strings": true,
|
||||||
|
"include_empty_strings": "",
|
||||||
|
"include_null_values": "",
|
||||||
|
"x": 600,
|
||||||
|
"y": 1900,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"5c5254a8.bc562c"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "b270564c.171908",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "CSV data",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "text",
|
||||||
|
"syntax": "mustache",
|
||||||
|
"template": "kind,price,origin\nApple,100,Canada\nOrange,120,USA\nBanana,80,Philippines",
|
||||||
|
"output": "str",
|
||||||
|
"x": 430,
|
||||||
|
"y": 1900,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"8ec8cf9e.103fa"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "1c7be442.6a4bdc",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 1090,
|
||||||
|
"y": 1900,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d3da7cfb.cf596",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Join parsed CSV message sequence using join node",
|
||||||
|
"info": "Parset CSV message sequence can be joined by join node.",
|
||||||
|
"x": 330,
|
||||||
|
"y": 1840,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a07c9e26.c84fd",
|
||||||
|
"type": "csv",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"sep": ",",
|
||||||
|
"hdrin": "",
|
||||||
|
"hdrout": "none",
|
||||||
|
"multi": "one",
|
||||||
|
"ret": "\\n",
|
||||||
|
"temp": "kind,price",
|
||||||
|
"skip": "0",
|
||||||
|
"strings": true,
|
||||||
|
"include_empty_strings": "",
|
||||||
|
"include_null_values": "",
|
||||||
|
"x": 910,
|
||||||
|
"y": 1900,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"1c7be442.6a4bdc"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5c5254a8.bc562c",
|
||||||
|
"type": "join",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"mode": "auto",
|
||||||
|
"build": "string",
|
||||||
|
"property": "payload",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"key": "topic",
|
||||||
|
"joiner": "\\n",
|
||||||
|
"joinerType": "str",
|
||||||
|
"accumulate": false,
|
||||||
|
"timeout": "",
|
||||||
|
"count": "",
|
||||||
|
"reduceRight": false,
|
||||||
|
"reduceExp": "",
|
||||||
|
"reduceInit": "",
|
||||||
|
"reduceInitType": "",
|
||||||
|
"reduceFixup": "",
|
||||||
|
"x": 750,
|
||||||
|
"y": 1900,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"a07c9e26.c84fd"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,94 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "8c5224a6.201b88",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 220,
|
||||||
|
"y": 180,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"d6c67e51.0d709"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d6c67e51.0d709",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "HTML text",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "handlebars",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "<html>\n <head>\n <title>List of Fruits</title>\n </head>\n <body>\n <ul>\n <li class=\"Item\">Apple</li>\n <li class=\"Item\">Orange</li>\n <li class=\"Item\">Banana</li>\n </ul>\n </body>\n</html>\n",
|
||||||
|
"output": "str",
|
||||||
|
"x": 390,
|
||||||
|
"y": 180,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"599a1155.61a5c"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "b0d5cd89.338df",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Extract array of HTML element by CSS selector",
|
||||||
|
"info": "HTML node can be used to extract elements in HTML document as an array using CSS selector.",
|
||||||
|
"x": 280,
|
||||||
|
"y": 120,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "599a1155.61a5c",
|
||||||
|
"type": "html",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"property": "payload",
|
||||||
|
"outproperty": "payload",
|
||||||
|
"tag": ".Item",
|
||||||
|
"ret": "html",
|
||||||
|
"as": "single",
|
||||||
|
"x": 550,
|
||||||
|
"y": 180,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"942b23d1.cce09"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "942b23d1.cce09",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 710,
|
||||||
|
"y": 180,
|
||||||
|
"wires": []
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,94 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "a44973e8.6319b",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 220,
|
||||||
|
"y": 360,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"de1b012e.96ec3"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "de1b012e.96ec3",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "HTML text",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "handlebars",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "<html>\n <head>\n <title>List of Fruits</title>\n </head>\n <body>\n <ul>\n <li class=\"Item\">Apple</li>\n <li class=\"Item\">Orange</li>\n <li class=\"Item\">Banana</li>\n </ul>\n </body>\n</html>\n",
|
||||||
|
"output": "str",
|
||||||
|
"x": 390,
|
||||||
|
"y": 360,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"cee70712.6f3538"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "99e32bc7.c8e508",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Extract sequence of HTML element by CSS selector",
|
||||||
|
"info": "HTML node can be used to extract elements in HTML document as a messege sequence using CSS selector.",
|
||||||
|
"x": 290,
|
||||||
|
"y": 300,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "cee70712.6f3538",
|
||||||
|
"type": "html",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"property": "payload",
|
||||||
|
"outproperty": "payload",
|
||||||
|
"tag": ".Item",
|
||||||
|
"ret": "html",
|
||||||
|
"as": "multi",
|
||||||
|
"x": 550,
|
||||||
|
"y": 360,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"17f25482.d4b56b"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "17f25482.d4b56b",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 710,
|
||||||
|
"y": 360,
|
||||||
|
"wires": []
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,121 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "653ce9aa.b6a1c8",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 220,
|
||||||
|
"y": 560,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"52a16f7f.447d8"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "52a16f7f.447d8",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "HTML text",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "handlebars",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "<html>\n <head>\n <title>List of Fruits</title>\n </head>\n <body>\n <ul>\n <li class=\"Item\">Apple</li>\n <li class=\"Item\">Orange</li>\n <li class=\"Item\">Banana</li>\n </ul>\n </body>\n</html>\n",
|
||||||
|
"output": "str",
|
||||||
|
"x": 390,
|
||||||
|
"y": 560,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"a52319c3.89b008"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8bc35379.31d99",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Extract array of HTML element by CSS selector specified in message",
|
||||||
|
"info": "CSS selector for HTML node can be specified by `select` property of input message.",
|
||||||
|
"x": 350,
|
||||||
|
"y": 500,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "9c49de8a.bad25",
|
||||||
|
"type": "html",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"property": "payload",
|
||||||
|
"outproperty": "payload",
|
||||||
|
"tag": "",
|
||||||
|
"ret": "html",
|
||||||
|
"as": "single",
|
||||||
|
"x": 730,
|
||||||
|
"y": 560,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"d4f4b987.278a68"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d4f4b987.278a68",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 890,
|
||||||
|
"y": 560,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a52319c3.89b008",
|
||||||
|
"type": "change",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "set",
|
||||||
|
"p": "select",
|
||||||
|
"pt": "msg",
|
||||||
|
"to": ".Item",
|
||||||
|
"tot": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"action": "",
|
||||||
|
"property": "",
|
||||||
|
"from": "",
|
||||||
|
"to": "",
|
||||||
|
"reg": false,
|
||||||
|
"x": 560,
|
||||||
|
"y": 560,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"9c49de8a.bad25"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,122 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "66cff4ee.f2761c",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 220,
|
||||||
|
"y": 760,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"2baaf6bf.0a02ca"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2baaf6bf.0a02ca",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "HTML text",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "handlebars",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "<html>\n <head>\n <title>List of Fruits</title>\n </head>\n <body>\n <ul>\n <li class=\"Item\">Apple</li>\n <li class=\"Item\">Orange</li>\n <li class=\"Item\">Banana</li>\n </ul>\n </body>\n</html>\n",
|
||||||
|
"output": "str",
|
||||||
|
"x": 390,
|
||||||
|
"y": 760,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"bbb22e6b.0fa25"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a57d35d0.8aa538",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Join extracted sequence of HTML element using join node",
|
||||||
|
"info": "Message sequence extracted by HTML node can be combined using join node.",
|
||||||
|
"x": 310,
|
||||||
|
"y": 700,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "bbb22e6b.0fa25",
|
||||||
|
"type": "html",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"property": "payload",
|
||||||
|
"outproperty": "payload",
|
||||||
|
"tag": ".Item",
|
||||||
|
"ret": "html",
|
||||||
|
"as": "multi",
|
||||||
|
"x": 550,
|
||||||
|
"y": 760,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"bd01ca4.966ad38"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4d2616a8.84de88",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 850,
|
||||||
|
"y": 760,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "bd01ca4.966ad38",
|
||||||
|
"type": "join",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"mode": "custom",
|
||||||
|
"build": "string",
|
||||||
|
"property": "payload",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"key": "topic",
|
||||||
|
"joiner": ",",
|
||||||
|
"joinerType": "str",
|
||||||
|
"accumulate": false,
|
||||||
|
"timeout": "",
|
||||||
|
"count": "",
|
||||||
|
"reduceRight": false,
|
||||||
|
"reduceExp": "",
|
||||||
|
"reduceInit": "",
|
||||||
|
"reduceInitType": "",
|
||||||
|
"reduceFixup": "",
|
||||||
|
"x": 690,
|
||||||
|
"y": 760,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"4d2616a8.84de88"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,92 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "9976e95d.2f8398",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 240,
|
||||||
|
"y": 180,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"d94fc083.49d87"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6684abb1.8eb454",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Convert JSON string to JS object",
|
||||||
|
"info": "JSON node can convert JSON string to JavaScript object.",
|
||||||
|
"x": 250,
|
||||||
|
"y": 120,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d94fc083.49d87",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "JSON string",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "json",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "{\n \"kind\": \"Apple\",\n \"price\": 100,\n \"origin\": \"Canada\"\n}",
|
||||||
|
"output": "str",
|
||||||
|
"x": 410,
|
||||||
|
"y": 180,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"1a3dc54a.78598b"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8950a55d.023988",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 730,
|
||||||
|
"y": 180,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "1a3dc54a.78598b",
|
||||||
|
"type": "json",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"property": "payload",
|
||||||
|
"action": "",
|
||||||
|
"pretty": false,
|
||||||
|
"x": 570,
|
||||||
|
"y": 180,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"8950a55d.023988"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,92 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "cb13761f.56c328",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 240,
|
||||||
|
"y": 380,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"c607642a.78c3c8"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "180b1e22.0074e2",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Convert JS object to JSON string",
|
||||||
|
"info": "JSON node can convert JavaScript object to JSON string.",
|
||||||
|
"x": 250,
|
||||||
|
"y": 320,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "c607642a.78c3c8",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "JS object",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "json",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "{\n \"kind\": \"Apple\",\n \"price\": 100,\n \"origin\": \"Canada\"\n}",
|
||||||
|
"output": "json",
|
||||||
|
"x": 400,
|
||||||
|
"y": 380,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"bf309844.fa12e8"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5b6b130b.72a14c",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 730,
|
||||||
|
"y": 380,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "bf309844.fa12e8",
|
||||||
|
"type": "json",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"property": "payload",
|
||||||
|
"action": "",
|
||||||
|
"pretty": false,
|
||||||
|
"x": 570,
|
||||||
|
"y": 380,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"5b6b130b.72a14c"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
160
packages/node_modules/@node-red/nodes/examples/parser/json/03 - Validate input JSON string.json
vendored
Normal file
160
packages/node_modules/@node-red/nodes/examples/parser/json/03 - Validate input JSON string.json
vendored
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "2b18621b.e2670e",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "OK",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 230,
|
||||||
|
"y": 580,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"5986faee.aef954"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "59acf99.9a92308",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Validate input JSON string",
|
||||||
|
"info": "JSON node can validate input JSON string using [JSON schema](https://json-schema.org/) when converting to JavaScript object.",
|
||||||
|
"x": 230,
|
||||||
|
"y": 520,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5986faee.aef954",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "JSON string",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "json",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "{\n \"kind\": \"Apple\",\n \"price\": 100,\n \"origin\": \"Canada\"\n}",
|
||||||
|
"output": "str",
|
||||||
|
"x": 410,
|
||||||
|
"y": 580,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"f8a67c6d.4f1f1"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ca27c92c.ad7cb8",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "payload",
|
||||||
|
"targetType": "msg",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 910,
|
||||||
|
"y": 580,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2fad9978.ea1916",
|
||||||
|
"type": "json",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"property": "payload",
|
||||||
|
"action": "",
|
||||||
|
"pretty": false,
|
||||||
|
"x": 750,
|
||||||
|
"y": 580,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"ca27c92c.ad7cb8"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "f8a67c6d.4f1f1",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Schema",
|
||||||
|
"field": "schema",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "json",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "{\n \"type\": \"object\",\n \"properties\": {\n \"kind\": {\n \"type\": \"string\"\n },\n \"price\": {\n \"type\": \"number\"\n },\n \"origin\": {\n \"type\": \"string\"\n }\n }\n}",
|
||||||
|
"output": "json",
|
||||||
|
"x": 590,
|
||||||
|
"y": 580,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"2fad9978.ea1916"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8337e847.ac18d8",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "NG",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 230,
|
||||||
|
"y": 660,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"fa14d8bf.1ac938"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "fa14d8bf.1ac938",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "JSON string",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "json",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "{\n \"kind\": \"Apple\",\n \"price\": \"100\",\n \"origin\": \"Canada\"\n}",
|
||||||
|
"output": "str",
|
||||||
|
"x": 410,
|
||||||
|
"y": 660,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"f8a67c6d.4f1f1"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,92 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "82f1bd0b.43474",
|
||||||
|
"type": "xml",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"property": "payload",
|
||||||
|
"attr": "",
|
||||||
|
"chr": "",
|
||||||
|
"x": 530,
|
||||||
|
"y": 180,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"1cd4ad02.9a5423"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "84222b92.d65d18",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 200,
|
||||||
|
"y": 180,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"cdd1c154.3a655"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "7b014430.dfd94c",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Convert JavaScript object to XML",
|
||||||
|
"info": "XML node can convert JavaScript object to XML string.",
|
||||||
|
"x": 240,
|
||||||
|
"y": 120,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "1cd4ad02.9a5423",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 690,
|
||||||
|
"y": 180,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "cdd1c154.3a655",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "JS object",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "json",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "{\n \"kind\": \"Apple\",\n \"price\": 100,\n \"origin\": \"Canada\"\n}",
|
||||||
|
"output": "json",
|
||||||
|
"x": 360,
|
||||||
|
"y": 180,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"82f1bd0b.43474"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,92 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "93e423a9.a407d",
|
||||||
|
"type": "xml",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"property": "payload",
|
||||||
|
"attr": "",
|
||||||
|
"chr": "",
|
||||||
|
"x": 530,
|
||||||
|
"y": 360,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"2d0dde7e.a50082"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ba1dab90.8d1da8",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 200,
|
||||||
|
"y": 360,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"16617f26.14ced1"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a9f97b00.57d658",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Convert XML to JavaScript object",
|
||||||
|
"info": "XML node can convert XML string to JavaScript object.",
|
||||||
|
"x": 240,
|
||||||
|
"y": 300,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2d0dde7e.a50082",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 690,
|
||||||
|
"y": 360,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "16617f26.14ced1",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "XML string",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "html",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<fruit id=\"100\">\n <kind>Apple</kind>\n <price>100</price>\n <origin>Canada</origin>\n</fruit>",
|
||||||
|
"output": "str",
|
||||||
|
"x": 370,
|
||||||
|
"y": 360,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"93e423a9.a407d"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,119 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "581bd648.636628",
|
||||||
|
"type": "xml",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"property": "payload",
|
||||||
|
"attr": "",
|
||||||
|
"chr": "",
|
||||||
|
"x": 710,
|
||||||
|
"y": 540,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"b74237dc.1e5028"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d0899f9b.f1ac6",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 200,
|
||||||
|
"y": 540,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"f04ffb9a.68edb8"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8a214c05.dc61f",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Control conversion using options property",
|
||||||
|
"info": "XML node can control conversion by setting `options` property (defined by [xml2js](https://github.com/Leonidas-from-XIV/node-xml2js/blob/master/README.md#options)) in input message.",
|
||||||
|
"x": 260,
|
||||||
|
"y": 480,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "b74237dc.1e5028",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 870,
|
||||||
|
"y": 540,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "f04ffb9a.68edb8",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "XML string",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "html",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<fruit id=\"100\">\n <kind>Apple</kind>\n <price>100</price>\n <origin>Canada</origin>\n</fruit>",
|
||||||
|
"output": "str",
|
||||||
|
"x": 370,
|
||||||
|
"y": 540,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"fedf79.5889c088"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "fedf79.5889c088",
|
||||||
|
"type": "change",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "set options",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "set",
|
||||||
|
"p": "options",
|
||||||
|
"pt": "msg",
|
||||||
|
"to": "{\"explicitArray\":false}",
|
||||||
|
"tot": "json"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"action": "",
|
||||||
|
"property": "",
|
||||||
|
"from": "",
|
||||||
|
"to": "",
|
||||||
|
"reg": false,
|
||||||
|
"x": 550,
|
||||||
|
"y": 540,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"581bd648.636628"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,90 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "84222b92.d65d18",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 200,
|
||||||
|
"y": 180,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"cdd1c154.3a655"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "7b014430.dfd94c",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Convert JavaScript object to YAML",
|
||||||
|
"info": "YAML node can convert JavaScript object to YAML string.",
|
||||||
|
"x": 240,
|
||||||
|
"y": 120,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "1cd4ad02.9a5423",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 670,
|
||||||
|
"y": 180,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "cdd1c154.3a655",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "JS object",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "json",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "{\n \"fruits\" : {\n \"kind\": \"Apple\",\n \"price\": 100,\n \"origin\": \"Canada\"\n }\n}",
|
||||||
|
"output": "json",
|
||||||
|
"x": 360,
|
||||||
|
"y": 180,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"aaf0100b.16628"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "aaf0100b.16628",
|
||||||
|
"type": "yaml",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"property": "payload",
|
||||||
|
"name": "",
|
||||||
|
"x": 510,
|
||||||
|
"y": 180,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"1cd4ad02.9a5423"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,90 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "ba1dab90.8d1da8",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 200,
|
||||||
|
"y": 360,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"16617f26.14ced1"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a9f97b00.57d658",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Convert YAML to JavaScript object",
|
||||||
|
"info": "YAML node can convert YAML string to JavaScript object.",
|
||||||
|
"x": 240,
|
||||||
|
"y": 300,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2d0dde7e.a50082",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 690,
|
||||||
|
"y": 360,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "16617f26.14ced1",
|
||||||
|
"type": "template",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "YAML string",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "yaml",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "fruits:\n kind: Apple\n price: 100\n origin: Canada",
|
||||||
|
"output": "str",
|
||||||
|
"x": 370,
|
||||||
|
"y": 360,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"e2e4f862.f9d7d8"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "e2e4f862.f9d7d8",
|
||||||
|
"type": "yaml",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"property": "payload",
|
||||||
|
"name": "",
|
||||||
|
"x": 530,
|
||||||
|
"y": 360,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"2d0dde7e.a50082"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
113
packages/node_modules/@node-red/nodes/examples/storage/file-in/01 - Read string from a file.json
vendored
Normal file
113
packages/node_modules/@node-red/nodes/examples/storage/file-in/01 - Read string from a file.json
vendored
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "84222b92.d65d18",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "Hello, World!",
|
||||||
|
"payloadType": "str",
|
||||||
|
"x": 230,
|
||||||
|
"y": 220,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"b4b9f603.739598"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "7b014430.dfd94c",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "Write string to a file, then read from the file",
|
||||||
|
"info": "File-in node can read string from a file.",
|
||||||
|
"x": 260,
|
||||||
|
"y": 140,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "b4b9f603.739598",
|
||||||
|
"type": "file",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "",
|
||||||
|
"filename": "/tmp/hello.txt",
|
||||||
|
"appendNewline": true,
|
||||||
|
"createDir": false,
|
||||||
|
"overwriteFile": "true",
|
||||||
|
"encoding": "none",
|
||||||
|
"x": 420,
|
||||||
|
"y": 220,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"6dc01cac.5c4bf4"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2587adb9.7e60f2",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 810,
|
||||||
|
"y": 220,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6dc01cac.5c4bf4",
|
||||||
|
"type": "file in",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "",
|
||||||
|
"filename": "/tmp/hello.txt",
|
||||||
|
"format": "utf8",
|
||||||
|
"chunk": false,
|
||||||
|
"sendError": false,
|
||||||
|
"encoding": "none",
|
||||||
|
"x": 620,
|
||||||
|
"y": 220,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"2587adb9.7e60f2"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "f4b4309a.3b78a",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "↑read result from file",
|
||||||
|
"info": "",
|
||||||
|
"x": 630,
|
||||||
|
"y": 260,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "672d3693.3cabd8",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "↓write to /tmp/hello.txt",
|
||||||
|
"info": "",
|
||||||
|
"x": 440,
|
||||||
|
"y": 180,
|
||||||
|
"wires": []
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,113 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "8997398f.c5d628",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "😀",
|
||||||
|
"payloadType": "str",
|
||||||
|
"x": 210,
|
||||||
|
"y": 480,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"56e32d23.050f44"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4e598e65.1799d",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "Read data in specified encoding",
|
||||||
|
"info": "File-in node can specify encoding of data read from a file.",
|
||||||
|
"x": 230,
|
||||||
|
"y": 400,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "56e32d23.050f44",
|
||||||
|
"type": "file",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "",
|
||||||
|
"filename": "/tmp/hello.txt",
|
||||||
|
"appendNewline": true,
|
||||||
|
"createDir": false,
|
||||||
|
"overwriteFile": "true",
|
||||||
|
"encoding": "none",
|
||||||
|
"x": 380,
|
||||||
|
"y": 480,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"38fa0579.f2cd8a"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d28c8994.99c0a8",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 770,
|
||||||
|
"y": 480,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "38fa0579.f2cd8a",
|
||||||
|
"type": "file in",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "",
|
||||||
|
"filename": "/tmp/hello.txt",
|
||||||
|
"format": "utf8",
|
||||||
|
"chunk": false,
|
||||||
|
"sendError": false,
|
||||||
|
"encoding": "base64",
|
||||||
|
"x": 580,
|
||||||
|
"y": 480,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"d28c8994.99c0a8"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "fa22ca20.ae4528",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "↑read data from file as base64 string",
|
||||||
|
"info": "",
|
||||||
|
"x": 640,
|
||||||
|
"y": 520,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "148e25ad.98891a",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "↓write to /tmp/hello.txt",
|
||||||
|
"info": "",
|
||||||
|
"x": 400,
|
||||||
|
"y": 440,
|
||||||
|
"wires": []
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,132 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "6a0b1d03.d4cee4",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 220,
|
||||||
|
"y": 740,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"d4b00cb7.a5a23"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "f17ea1d1.8ecc3",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "Read data breaking lines into individual messages",
|
||||||
|
"info": "File-in node can break read text into messages with individual lines",
|
||||||
|
"x": 290,
|
||||||
|
"y": 660,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "99ae7806.1d6428",
|
||||||
|
"type": "file",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "",
|
||||||
|
"filename": "/tmp/hello.txt",
|
||||||
|
"appendNewline": true,
|
||||||
|
"createDir": false,
|
||||||
|
"overwriteFile": "true",
|
||||||
|
"encoding": "none",
|
||||||
|
"x": 540,
|
||||||
|
"y": 740,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"70d7892f.d27db8"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "7ed8282c.92b338",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 810,
|
||||||
|
"y": 800,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "70d7892f.d27db8",
|
||||||
|
"type": "file in",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "",
|
||||||
|
"filename": "/tmp/hello.txt",
|
||||||
|
"format": "lines",
|
||||||
|
"chunk": false,
|
||||||
|
"sendError": false,
|
||||||
|
"encoding": "none",
|
||||||
|
"x": 620,
|
||||||
|
"y": 800,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"7ed8282c.92b338"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "c1b7e05.1d94b2",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "↑read data from file breaking lines into messages",
|
||||||
|
"info": "",
|
||||||
|
"x": 720,
|
||||||
|
"y": 840,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a5f647b2.cf27a8",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "↓write to /tmp/hello.txt",
|
||||||
|
"info": "",
|
||||||
|
"x": 560,
|
||||||
|
"y": 700,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d4b00cb7.a5a23",
|
||||||
|
"type": "template",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "data",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "handlebars",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "one\ntwo\nthree!",
|
||||||
|
"output": "str",
|
||||||
|
"x": 370,
|
||||||
|
"y": 740,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"99ae7806.1d6428"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
201
packages/node_modules/@node-red/nodes/examples/storage/file-in/04 - Create a message stream.json
vendored
Normal file
201
packages/node_modules/@node-red/nodes/examples/storage/file-in/04 - Create a message stream.json
vendored
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "bdd57acc.2edc48",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 220,
|
||||||
|
"y": 1040,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"7a069b01.0c2324"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "1fd12220.33953e",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "Creating a message stream from lines of data",
|
||||||
|
"info": "File-in node can break read text into messages with individual lines. The messages creates a stream of messages.",
|
||||||
|
"x": 270,
|
||||||
|
"y": 960,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ab6eb213.2a08d",
|
||||||
|
"type": "file",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "",
|
||||||
|
"filename": "/tmp/hello.txt",
|
||||||
|
"appendNewline": true,
|
||||||
|
"createDir": false,
|
||||||
|
"overwriteFile": "true",
|
||||||
|
"encoding": "none",
|
||||||
|
"x": 540,
|
||||||
|
"y": 1040,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"b7ed49b0.649fb8"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "c48d8ae0.9ff3a8",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 810,
|
||||||
|
"y": 1140,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "b7ed49b0.649fb8",
|
||||||
|
"type": "file in",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "",
|
||||||
|
"filename": "/tmp/hello.txt",
|
||||||
|
"format": "lines",
|
||||||
|
"chunk": false,
|
||||||
|
"sendError": false,
|
||||||
|
"encoding": "none",
|
||||||
|
"x": 280,
|
||||||
|
"y": 1140,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"83073ebe.fcce4"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3c33e69f.6a04ba",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "↑read data from file breaking lines into messages",
|
||||||
|
"info": "",
|
||||||
|
"x": 380,
|
||||||
|
"y": 1180,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3598bf7d.5712a",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "↓write to /tmp/hello.txt",
|
||||||
|
"info": "",
|
||||||
|
"x": 560,
|
||||||
|
"y": 1000,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "7a069b01.0c2324",
|
||||||
|
"type": "template",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "data",
|
||||||
|
"field": "payload",
|
||||||
|
"fieldType": "msg",
|
||||||
|
"format": "handlebars",
|
||||||
|
"syntax": "plain",
|
||||||
|
"template": "Apple\nBanana\nGrape\nOrange",
|
||||||
|
"output": "str",
|
||||||
|
"x": 370,
|
||||||
|
"y": 1040,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"ab6eb213.2a08d"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8d4ed1d0.821fe",
|
||||||
|
"type": "join",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "",
|
||||||
|
"mode": "auto",
|
||||||
|
"build": "string",
|
||||||
|
"property": "payload",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"key": "topic",
|
||||||
|
"joiner": "\\n",
|
||||||
|
"joinerType": "str",
|
||||||
|
"accumulate": "false",
|
||||||
|
"timeout": "",
|
||||||
|
"count": "",
|
||||||
|
"reduceRight": false,
|
||||||
|
"x": 630,
|
||||||
|
"y": 1140,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"c48d8ae0.9ff3a8"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "83073ebe.fcce4",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "< D",
|
||||||
|
"property": "payload",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "lt",
|
||||||
|
"v": "D",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": true,
|
||||||
|
"outputs": 1,
|
||||||
|
"x": 470,
|
||||||
|
"y": 1140,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"8d4ed1d0.821fe"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2088e195.f7aebe",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "↓filter data before \"D\"",
|
||||||
|
"info": "",
|
||||||
|
"x": 520,
|
||||||
|
"y": 1100,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "b848cdc7.61e06",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "194a3e4f.a92772",
|
||||||
|
"name": "↑join to single string",
|
||||||
|
"info": "",
|
||||||
|
"x": 670,
|
||||||
|
"y": 1180,
|
||||||
|
"wires": []
|
||||||
|
}
|
||||||
|
]
|
113
packages/node_modules/@node-red/nodes/examples/storage/file/01 - Write string to a file.json
vendored
Normal file
113
packages/node_modules/@node-red/nodes/examples/storage/file/01 - Write string to a file.json
vendored
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "84222b92.d65d18",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "Hello, World!",
|
||||||
|
"payloadType": "str",
|
||||||
|
"x": 230,
|
||||||
|
"y": 200,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"b4b9f603.739598"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "7b014430.dfd94c",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Write string to a file, then read from the file",
|
||||||
|
"info": "File node can write string to a file.",
|
||||||
|
"x": 260,
|
||||||
|
"y": 120,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "b4b9f603.739598",
|
||||||
|
"type": "file",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"filename": "/tmp/hello.txt",
|
||||||
|
"appendNewline": true,
|
||||||
|
"createDir": false,
|
||||||
|
"overwriteFile": "true",
|
||||||
|
"encoding": "none",
|
||||||
|
"x": 420,
|
||||||
|
"y": 200,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"6dc01cac.5c4bf4"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2587adb9.7e60f2",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 810,
|
||||||
|
"y": 200,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6dc01cac.5c4bf4",
|
||||||
|
"type": "file in",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"filename": "/tmp/hello.txt",
|
||||||
|
"format": "utf8",
|
||||||
|
"chunk": false,
|
||||||
|
"sendError": false,
|
||||||
|
"encoding": "none",
|
||||||
|
"x": 620,
|
||||||
|
"y": 200,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"2587adb9.7e60f2"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "f4b4309a.3b78a",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "↑read result from file",
|
||||||
|
"info": "",
|
||||||
|
"x": 630,
|
||||||
|
"y": 240,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "672d3693.3cabd8",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "↓write to /tmp/hello.txt",
|
||||||
|
"info": "",
|
||||||
|
"x": 440,
|
||||||
|
"y": 160,
|
||||||
|
"wires": []
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,118 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "704479e1.399388",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "filename",
|
||||||
|
"v": "/tmp/hello.txt",
|
||||||
|
"vt": "str"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "Hello, World!",
|
||||||
|
"payloadType": "str",
|
||||||
|
"x": 230,
|
||||||
|
"y": 400,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"402f3b7e.988014"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8e876a75.e9beb8",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Write string to a file specied by filename property, the read from the file",
|
||||||
|
"info": "File node can target file using `filename` property.",
|
||||||
|
"x": 350,
|
||||||
|
"y": 320,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "402f3b7e.988014",
|
||||||
|
"type": "file",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"filename": "",
|
||||||
|
"appendNewline": true,
|
||||||
|
"createDir": false,
|
||||||
|
"overwriteFile": "true",
|
||||||
|
"encoding": "none",
|
||||||
|
"x": 390,
|
||||||
|
"y": 400,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"26e077d6.bbcd98"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "97b6b6b2.a54b38",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 770,
|
||||||
|
"y": 400,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "26e077d6.bbcd98",
|
||||||
|
"type": "file in",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"filename": "/tmp/hello.txt",
|
||||||
|
"format": "utf8",
|
||||||
|
"chunk": false,
|
||||||
|
"sendError": false,
|
||||||
|
"encoding": "none",
|
||||||
|
"x": 580,
|
||||||
|
"y": 400,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"97b6b6b2.a54b38"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "85062297.da79",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "↑read result from file",
|
||||||
|
"info": "",
|
||||||
|
"x": 590,
|
||||||
|
"y": 440,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "7316c4fc.b1dcdc",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "↓write to file specified by filename property",
|
||||||
|
"info": "",
|
||||||
|
"x": 500,
|
||||||
|
"y": 360,
|
||||||
|
"wires": []
|
||||||
|
}
|
||||||
|
]
|
85
packages/node_modules/@node-red/nodes/examples/storage/file/03 - Delete a file.json
vendored
Normal file
85
packages/node_modules/@node-red/nodes/examples/storage/file/03 - Delete a file.json
vendored
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "4ac00fb0.d5f52",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "",
|
||||||
|
"payloadType": "date",
|
||||||
|
"x": 220,
|
||||||
|
"y": 600,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"542cc2f4.92857c"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "671f8295.0e6f6c",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Delete a file",
|
||||||
|
"info": "File node can delete a file.",
|
||||||
|
"x": 170,
|
||||||
|
"y": 540,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "542cc2f4.92857c",
|
||||||
|
"type": "file",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"filename": "/tmp/hello.txt",
|
||||||
|
"appendNewline": true,
|
||||||
|
"createDir": false,
|
||||||
|
"overwriteFile": "delete",
|
||||||
|
"encoding": "none",
|
||||||
|
"x": 420,
|
||||||
|
"y": 600,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"a24da523.5babe8"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a24da523.5babe8",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 630,
|
||||||
|
"y": 600,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "51157051.2f62",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "↓delete a file",
|
||||||
|
"info": "",
|
||||||
|
"x": 390,
|
||||||
|
"y": 560,
|
||||||
|
"wires": []
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,113 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "e4ef1f5e.7cd82",
|
||||||
|
"type": "inject",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"p": "payload"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p": "topic",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repeat": "",
|
||||||
|
"crontab": "",
|
||||||
|
"once": false,
|
||||||
|
"onceDelay": 0.1,
|
||||||
|
"topic": "",
|
||||||
|
"payload": "8J+YgA==",
|
||||||
|
"payloadType": "str",
|
||||||
|
"x": 220,
|
||||||
|
"y": 820,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"72b37cc8.177054"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "f5997af4.5a9298",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "Specify encoding of written data",
|
||||||
|
"info": "File node can specify encoding of data.",
|
||||||
|
"x": 230,
|
||||||
|
"y": 740,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "72b37cc8.177054",
|
||||||
|
"type": "file",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"filename": "/tmp/hello.txt",
|
||||||
|
"appendNewline": true,
|
||||||
|
"createDir": false,
|
||||||
|
"overwriteFile": "true",
|
||||||
|
"encoding": "base64",
|
||||||
|
"x": 400,
|
||||||
|
"y": 820,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"2da33ec.f45cac2"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2e814354.278c8c",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 790,
|
||||||
|
"y": 820,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2da33ec.f45cac2",
|
||||||
|
"type": "file in",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "",
|
||||||
|
"filename": "/tmp/hello.txt",
|
||||||
|
"format": "utf8",
|
||||||
|
"chunk": false,
|
||||||
|
"sendError": false,
|
||||||
|
"encoding": "none",
|
||||||
|
"x": 600,
|
||||||
|
"y": 820,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"2e814354.278c8c"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ec754c99.84bfd",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "↓write string with base64 encoding",
|
||||||
|
"info": "",
|
||||||
|
"x": 460,
|
||||||
|
"y": 780,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3e6704ff.4ce25c",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "4b63452d.672afc",
|
||||||
|
"name": "↑read result from file",
|
||||||
|
"info": "",
|
||||||
|
"x": 610,
|
||||||
|
"y": 860,
|
||||||
|
"wires": []
|
||||||
|
}
|
||||||
|
]
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user