Merge branch 'dev' into debug-node-with-jsonata

This commit is contained in:
Hiroyasu Nishiyama
2018-12-08 17:43:29 +09:00
55 changed files with 751 additions and 1095 deletions

View File

@@ -57,7 +57,7 @@ module.exports = {
}
runtimeAPI.nodes.getIcon(opts).then(function(data) {
if (data) {
var contentType = mime.lookup(icon);
var contentType = mime.getType(icon);
res.set("Content-Type", contentType);
res.send(data);
} else {

View File

@@ -100,5 +100,5 @@ module.exports = {
auth: {
needsPermission: auth.needsPermission
},
get adminApp() { return adminApp; }
get httpAdmin() { return adminApp; }
};

View File

@@ -1,6 +1,6 @@
{
"name": "@node-red/editor-api",
"version": "0.20.0-alpha.0",
"version": "0.20.0-beta.2",
"license": "Apache-2.0",
"main": "./lib/index.js",
"repository": {
@@ -8,21 +8,25 @@
"url": "https://github.com/node-red/node-red.git"
},
"contributors": [
{ "name": "Nick O'Leary" },
{ "name": "Dave Conway-Jones"}
{
"name": "Nick O'Leary"
},
{
"name": "Dave Conway-Jones"
}
],
"dependencies": {
"@node-red/util": "*",
"@node-red/editor-client": "*",
"@node-red/util": "0.20.0-beta.2",
"@node-red/editor-client": "0.20.0-beta.2",
"bcryptjs": "2.4.3",
"body-parser": "1.18.3",
"clone": "2.1.2",
"cors": "2.8.4",
"cors": "2.8.5",
"express-session": "1.15.6",
"express": "4.16.4",
"memorystore": "1.6.0",
"mime": "1.4.1",
"mustache": "2.3.2",
"mime": "2.4.0",
"mustache": "3.0.1",
"oauth2orize": "1.11.0",
"passport-http-bearer": "1.0.1",
"passport-oauth2-client-password": "0.1.2",

View File

@@ -1,14 +1,18 @@
{
"name": "@node-red/editor-client",
"version": "0.20.0-alpha.0",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "https://github.com/node-red/node-red.git"
},
"contributors": [
{ "name": "Nick O'Leary" },
{ "name": "Dave Conway-Jones"}
],
"main": "./lib/index.js"
"name": "@node-red/editor-client",
"version": "0.20.0-beta.2",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "https://github.com/node-red/node-red.git"
},
"contributors": [
{
"name": "Nick O'Leary"
},
{
"name": "Dave Conway-Jones"
}
],
"main": "./lib/index.js"
}

View File

@@ -865,7 +865,7 @@ RED.editor = (function() {
var inputPlaceholder = node._def.inputLabels?RED._("editor.defaultLabel"):RED._("editor.noDefaultLabel");
var outputPlaceholder = node._def.outputLabels?RED._("editor.defaultLabel"):RED._("editor.noDefaultLabel");
$('<div class="form-row"><span style="margin-left: 10px;" data-i18n="editor.labelInputs"></span><div id="node-label-form-inputs"></div></div>').appendTo(dialogForm);
$('<div class="form-row"><span style="margin-left: 50px;" data-i18n="editor.labelInputs"></span><div id="node-label-form-inputs"></div></div>').appendTo(dialogForm);
var inputsDiv = $("#node-label-form-inputs");
if (inputCount > 0) {
for (i=0;i<inputCount;i++) {
@@ -874,7 +874,7 @@ RED.editor = (function() {
} else {
buildLabelRow().appendTo(inputsDiv);
}
$('<div class="form-row"><span style="margin-left: 10px;" data-i18n="editor.labelOutputs"></span><div id="node-label-form-outputs"></div></div>').appendTo(dialogForm);
$('<div class="form-row"><span style="margin-left: 50px;" data-i18n="editor.labelOutputs"></span><div id="node-label-form-outputs"></div></div>').appendTo(dialogForm);
var outputsDiv = $("#node-label-form-outputs");
if (outputCount > 0) {
for (i=0;i<outputCount;i++) {

View File

@@ -16,6 +16,10 @@
RED.notifications = (function() {
/*
If RED.notifications.hide is set to true, all notifications will be hidden.
This is to help with UI testing in certain cases and not intended for the
end-user.
// Example usage for a modal dialog with buttons
var myNotification = RED.notify("This is the message to display",{
modal: true,
@@ -108,7 +112,9 @@ RED.notifications = (function() {
$("#notifications").append(n);
$(n).slideDown(300);
if (!RED.notifications.hide) {
$(n).slideDown(300);
}
n.close = (function() {
var nn = n;
return function() {
@@ -123,9 +129,13 @@ RED.notifications = (function() {
notificationButtonWrapper.hide();
}
}
$(nn).slideUp(300, function() {
if (!RED.notifications.hide) {
$(nn).slideUp(300, function() {
nn.parentNode.removeChild(nn);
});
} else {
nn.parentNode.removeChild(nn);
});
}
if (options.modal) {
$("#full-shade").hide();
}
@@ -138,7 +148,9 @@ RED.notifications = (function() {
return
}
nn.hidden = true;
$(nn).slideUp(300);
if (!RED.notifications.hide) {
$(nn).slideUp(300);
}
}
})();
n.showNotification = (function() {
@@ -148,7 +160,9 @@ RED.notifications = (function() {
return
}
nn.hidden = false;
$(nn).slideDown(300);
if (!RED.notifications.hide) {
$(nn).slideDown(300);
}
}
})();

View File

@@ -789,7 +789,11 @@ RED.utils = (function() {
return RED.settings.apiRootUrl+"icons/"+iconPath.module+"/"+iconPath.file;
}
} else {
if (def.category === 'subflows') {
// This could be a non-core node trying to use a core icon.
iconPath.module = 'node-red';
if (isIconExists(iconPath)) {
return RED.settings.apiRootUrl+"icons/"+iconPath.module+"/"+iconPath.file;
} else if (def.category === 'subflows') {
return RED.settings.apiRootUrl+"icons/node-red/subflow.png";
} else {
return RED.settings.apiRootUrl+"icons/node-red/arrow-in.png";

View File

@@ -343,7 +343,7 @@
top: -3000px;
}
.node-label-form-row {
margin: 5px 0;
margin: 5px 0 0 50px;
label {
margin-right: 20px;
text-align: right;

View File

@@ -1,37 +0,0 @@
<script type="text/x-red" data-template-name="sentiment">
<div class="form-row">
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="node-red:common.label.property"></span></label>
<input type="text" id="node-input-property" style="width:70%;"/>
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
</div>
</script>
<script type="text/javascript">
RED.nodes.registerType('sentiment',{
category: 'analysis-function',
color:"#E6E0F8",
defaults: {
name: {value:""},
property: {value:"payload",required:true}
},
inputs:1,
outputs:1,
icon: "arrow-in.png",
label: function() {
return this.name||"sentiment";
},
labelStyle: function() {
return this.name?"node_label_italic":"";
},
oneditprepare: function() {
if (this.property === undefined) {
$("#node-input-property").val("payload");
}
$("#node-input-property").typedInput({default:'msg',types:['msg']});
}
});
</script>

View File

@@ -1,23 +0,0 @@
module.exports = function(RED) {
"use strict";
var sentiment = require('sentiment');
function SentimentNode(n) {
RED.nodes.createNode(this,n);
this.property = n.property||"payload";
var node = this;
this.on("input", function(msg) {
var value = RED.util.getMessageProperty(msg,node.property);
if (value !== undefined) {
sentiment(value, msg.overrides || null, function (err, result) {
msg.sentiment = result;
node.send(msg);
});
}
else { node.send(msg); } // If no matching property - just pass it on.
});
}
RED.nodes.registerType("sentiment",SentimentNode);
}

View File

@@ -2,10 +2,10 @@
<script type="text/x-red" data-template-name="template">
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
<div style="display: inline-block; width: calc(100% - 105px)"><input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"></div>
</div>
<div class="form-row">
<label for="node-input-field"><i class="fa fa-edit"></i> <span data-i18n="template.label.property"></span></label>
<label for="node-input-field"><i class="fa fa-ellipsis-h"></i> <span data-i18n="template.label.property"></span></label>
<input type="text" id="node-input-field" placeholder="payload" style="width:250px;">
<input type="hidden" id="node-input-fieldType">
</div>

View File

@@ -131,8 +131,16 @@ module.exports = function(RED) {
if (msg.hasOwnProperty('followRedirects')) {
opts.followRedirect = msg.followRedirects;
}
var redirectList = [];
if (!opts.hasOwnProperty('followRedirect') || opts.followRedirect) {
opts.followRedirect = function(res) {
var redirectInfo = {
location: res.headers.location,
};
if (res.headers.hasOwnProperty('set-cookie')) {
redirectInfo.cookies = extractCookies(res.headers['set-cookie']);
}
redirectList.push(redirectInfo);
if (this.headers.cookie) {
delete this.headers.cookie;
}
@@ -256,17 +264,10 @@ module.exports = function(RED) {
msg.headers = res.headers;
msg.responseUrl = res.request.uri.href;
msg.payload = body;
msg.redirectList = redirectList;
if (msg.headers.hasOwnProperty('set-cookie')) {
msg.responseCookies = {};
msg.headers['set-cookie'].forEach(function(c) {
var parsedCookie = cookie.parse(c);
var eq_idx = c.indexOf('=');
var key = c.substr(0, eq_idx).trim()
parsedCookie.value = parsedCookie[key];
delete parsedCookie[key];
msg.responseCookies[key] = parsedCookie;
});
msg.responseCookies = extractCookies(msg.headers['set-cookie']);
}
msg.headers['x-node-red-request-node'] = hashSum(msg.headers);
// msg.url = url; // revert when warning above finally removed
@@ -299,6 +300,19 @@ module.exports = function(RED) {
this.on("close",function() {
node.status({});
});
function extractCookies(setCookie) {
var cookies = {};
setCookie.forEach(function(c) {
var parsedCookie = cookie.parse(c);
var eq_idx = c.indexOf('=');
var key = c.substr(0, eq_idx).trim()
parsedCookie.value = parsedCookie[key];
delete parsedCookie[key];
cookies[key] = parsedCookie;
});
return cookies;
}
}
RED.nodes.registerType("http request",HTTPRequest,{

View File

@@ -20,7 +20,7 @@
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
</div>
<div class="form-row">
<label data-i18n="switch.label.property"></label>
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="switch.label.property"></span></label>
<input type="text" id="node-input-property" style="width: 70%"/>
<input type="hidden" id="node-input-outputs"/>
</div>

View File

@@ -1,51 +0,0 @@
<script type="text/x-red" data-template-name="tail">
<div class="form-row">
<label for="node-input-filename"><i class="fa fa-file"></i> <span data-i18n="tail.label.filename"></span></label>
<input id="node-input-filename" type="text">
</div>
<div class="form-row">
<label for="node-input-filetype"><i class="fa fa-file-text-o"></i> <span data-i18n="tail.label.type"></span></label>
<select type="text" id="node-input-filetype">
<option value="text" data-i18n="tail.action.text"></option>
<option value="binary" data-i18n="tail.action.binary"></option>
</select>
</div>
<div class="form-row" id="node-tail-split">
<label>&nbsp;</label>
<input type="checkbox" id="node-input-split" placeholder="Name" style="display: inline-block; width: auto; vertical-align: top;">
<label for="node-input-split" style="width: 70%;"><span data-i18n="tail.label.splitlines"></span></label>
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
</div>
</script>
<script type="text/javascript">
RED.nodes.registerType('tail',{
category: 'storage-input',
defaults: {
name: {value:""},
filetype: {value:"text"},
split: {value:false},
filename: {value:"",required:true}
},
color:"BurlyWood",
inputs:0,
outputs:1,
icon: "file.png",
label: function() {
return this.name||this.filename||this._("tail.tail");
},
labelStyle: function() {
return this.name?"node_label_italic":"";
},
oneditprepare: function() {
$("#node-input-filetype").on("change",function() {
if (this.value === "text") { $("#node-tail-split").show(); }
else { $("#node-tail-split").hide(); }
});
}
});
</script>

View File

@@ -1,75 +0,0 @@
/**
* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
module.exports = function(RED) {
"use strict";
var spawn = require('child_process').spawn;
var plat = require('os').platform();
if (plat.match(/^win/)) {
throw RED._("tail.errors.windowsnotsupport");
}
function TailNode(n) {
RED.nodes.createNode(this,n);
this.filename = n.filename;
this.filetype = n.filetype || "text";
this.split = n.split || false;
var node = this;
var err = "";
// TODO: rewrite to use node-tail
var tail = spawn("tail", ["-F", "-n", "0", this.filename]);
tail.stdout.on("data", function (data) {
var msg = { topic:node.filename };
if (node.filetype === "text") {
if (node.split) {
// TODO: allow customisation of the line break - as we do elsewhere
var strings = data.toString().split("\n");
for (var s in strings) {
//TODO: should we really filter blanks? Is that expected?
if (strings[s] !== "") {
node.send({
topic: node.filename,
payload: strings[s]
});
}
}
}
else {
msg.payload = data.toString();
node.send(msg);
}
}
else {
msg.payload = data;
node.send(msg);
}
});
tail.stderr.on("data", function(data) {
node.error(data.toString());
});
this.on("close", function() {
/* istanbul ignore else */
if (tail) { tail.kill(); }
});
}
RED.nodes.registerType("tail",TailNode);
}

View File

@@ -1,35 +0,0 @@
<!--
Copyright JS Foundation and other contributors, http://js.foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<script type="text/x-red" data-help-name="sentiment">
<p>Analyses the chosen property, default <code>payload</code>, and adds a <code>sentiment</code> object.</p>
<h3>Outputs</h3>
<dl class="message-properties">
<dt>sentiment <span class="property-type">object</span></dt>
<dd>contains the resulting AFINN-111 sentiment.</dd>
<dt>sentiment.score <span class="property-type">number</span></dt>
<dd>the sentiment score.</dd>
</dl>
<h3>Inputs</h3>
<dl class="message-properties">
<dt>overrides <span class="property-type">object</span></dt>
<dd>an object of word score overrides can be supplied - <code>{ word:score,... }</code>.</dd>
</dl>
<h3>Details</h3>
<p>A score greater than zero is positive and less than zero is negative.</p>
<p>The score typically ranges from -5 to +5, but can go higher and lower.</p>
<p>See <a href="https://github.com/thisandagain/sentiment/blob/master/README.md" target="_blank">the Sentiment docs here</a>.</p>
</script>

View File

@@ -53,6 +53,8 @@
Otherwise, the url of the original request.</dd>
<dt>responseCookies <span class="property-type">object</span></dt>
<dd>If the response includes cookies, this propery is an object of name/value pairs for each cookie.</dd>
<dt>redirectList <span class="property-type">array</span></dt>
<dd>If the request was redirected one or more times, the accumulated information will be added to this property. `location` is the next redirect destination. `cookies` is the cookies returned from the redirect source.</dd>
</dl>
<h3>Details</h3>
<p>When configured within the node, the URL property can contain <a href="http://mustache.github.io/mustache.5.html" target="_blank">mustache-style</a> tags. These allow the

View File

@@ -206,7 +206,7 @@
"template": "template",
"label": {
"template": "Template",
"property": "Set property",
"property": "Property",
"format": "Syntax Highlight",
"syntax": "Format",
"output": "Output as",
@@ -827,21 +827,6 @@
"pythoncommandnotfound": "nrpgio python command not running"
}
},
"tail": {
"tail": "tail",
"label": {
"filename": "Filename",
"type": "File type",
"splitlines": "Split lines on \\n?"
},
"action": {
"text": "Text - returns String",
"binary": "Binary - returns Buffer"
},
"errors": {
"windowsnotsupport": "Not currently supported on Windows."
}
},
"file": {
"label": {
"filename": "Filename",

View File

@@ -1,25 +0,0 @@
<!--
Copyright JS Foundation and other contributors, http://js.foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<script type="text/x-red" data-help-name="tail">
<p>Tails (watches for things to be added) to the configured file. (Linux/Mac ONLY)</p>
<p>This will not work on Windows filesystems, as it relies on the <b>tail -F</b> command.</p>
<h3>Outputs</h3>
<ul>
<li>Text (UTF-8) files will be returned as strings.</li>
<li>Binary files will be returned as Buffer objects.</li>
</ul>
</script>

View File

@@ -1,35 +0,0 @@
<!--
Copyright JS Foundation and other contributors, http://js.foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<script type="text/x-red" data-help-name="sentiment">
<p>指定したプロパティ(デフォルトは<code>payload</code>)<code>sentiment</code></p>
<h3>出力</h3>
<dl class="message-properties">
<dt>sentiment <span class="property-type">オブジェクト</span></dt>
<dd>AFINN-111による感情分析の結果</dd>
<dt>sentiment.score <span class="property-type">数値</span></dt>
<dd>感情分析スコア</dd>
</dl>
<h3>入力</h3>
<dl class="message-properties">
<dt>overrides <span class="property-type">オブジェクト</span></dt>
<dd>単語スコアの上書きをするためのオブジェクト - <code>{ word:score,... }</code></dd>
</dl>
<h3>詳細</h3>
<p>ゼロ以上のスコアはポジティブゼロ以下はネガティブを意味します</p>
<p>スコアの範囲は通常-5から+5ですがより大きかったり小さかったりすることもあります</p>
<p>詳細は<a href="https://github.com/thisandagain/sentiment/blob/master/README.md" target="_blank">the Sentiment docs here</a></p>
</script>

View File

@@ -46,6 +46,8 @@
<dd>リクエストの処理時にリダイレクトが発生した場合このプロパティが最後にリダイレクトされたURLを表しますリダイレクトが起こらなかった場合最初リクエストのURLを表します</dd>
<dt>responseCookies <span class="property-type">オブジェクト</span></dt>
<dd>レスポンスがクッキーを含む場合このプロパティは各クッキーの名前/値を含むオブジェクトを表します</dd>
<dt>redirectList <span class="property-type">配列</span></dt>
<dd>リクエストが一回以上リダイレクトされた場合はこのプロパティに情報が蓄積されます`location`リダイレクト先を示します`cookies`リダイレクト元から返されたクッキー情報です</dd>
</dl>
<h3>詳細</h3>
<p>ードの設定でurlプロパティを指定する場合<a href="http://mustache.github.io/mustache.5.html" target="_blank">mustache形式</a>のタグを含めることができます。これにより、URLを入力メッセージの値から構成することができます。例えば、urlが<code>example.com/{{{topic}}}</code><code>msg.topic</code>{{{...}}}使/&mustache</p>

View File

@@ -206,7 +206,7 @@
"template": "template",
"label": {
"template": "テンプレート",
"property": "設定先",
"property": "プロパティ",
"format": "構文",
"syntax": "形式",
"output": "出力形式",
@@ -825,21 +825,6 @@
"pythoncommandnotfound": "nrpgio python コマンドが実行されていません"
}
},
"tail": {
"tail": "tail",
"label": {
"filename": "ファイル名",
"type": "ファイル形式",
"splitlines": "改行でメッセージを分割"
},
"action": {
"text": "文字列",
"binary": "バイナリバッファ"
},
"errors": {
"windowsnotsupport": "現在Windows上での動作は対応していません"
}
},
"file": {
"label": {
"filename": "ファイル名",

View File

@@ -1,25 +0,0 @@
<!--
Copyright JS Foundation and other contributors, http://js.foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<script type="text/x-red" data-help-name="tail">
<p>設定したファイルの末尾を出力(追加されたデータを監視)します(Linux/Macのみ)</p>
<p>このノードは<b>tail -F</b>Windows</p>
<h3>出力</h3>
<ul>
<li>(UTF-8形式の)テキストファイルは文字列を返却</li>
<li>バイナルファイルはバッファオブジェクトを返却</li>
</ul>
</script>

View File

@@ -196,7 +196,7 @@
"template": {
"label": {
"template": "模版",
"property": "设定属性",
"property": "属性",
"format": "语法高亮",
"syntax": "格式",
"output": "输出为",
@@ -784,20 +784,6 @@
"pythoncommandnotfound": "nrpgio python命令未处于运行状态"
}
},
"tail": {
"label": {
"filename": "文件名",
"type": "文件类型",
"splitlines": "以\\n来拆分行?"
},
"action": {
"text": "文本 - 返回字符串",
"binary": "二进制 - 返回Buffer"
},
"errors": {
"windowsnotsupport": "Windows目前不支持."
}
},
"file": {
"label": {
"filename": "文件名",

View File

@@ -1,34 +1,38 @@
{
"name": "@node-red/nodes",
"version": "0.20.0-alpha.0",
"version": "0.20.0-beta.2",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "https://github.com/node-red/node-red.git"
},
"contributors": [
{ "name": "Nick O'Leary" },
{ "name": "Dave Conway-Jones"}
{
"name": "Nick O'Leary"
},
{
"name": "Dave Conway-Jones"
}
],
"dependencies": {
"ajv": "6.5.4",
"ajv": "6.6.1",
"body-parser": "1.18.3",
"cheerio": "0.22.0",
"cookie-parser": "1.4.3",
"cookie": "0.3.1",
"cors": "2.8.4",
"cron": "1.5.0",
"denque": "1.3.0",
"fs-extra": "5.0.0",
"cors": "2.8.5",
"cron": "1.5.1",
"denque": "1.4.0",
"fs-extra": "7.0.1",
"fs.notify": "0.0.4",
"hash-sum": "1.0.2",
"https-proxy-agent": "2.2.1",
"is-utf8": "0.2.1",
"js-yaml": "3.12.0",
"media-typer": "0.3.0",
"media-typer": "1.0.1",
"mqtt": "2.18.8",
"multer": "1.4.1",
"mustache": "2.3.2",
"mustache": "3.0.1",
"on-headers": "1.0.1",
"raw-body": "2.3.3",
"request": "2.88.0",

View File

@@ -13,33 +13,44 @@
* See the License for the specific language governing permissions and
* limitations under the License.
**/
/*
* This provides a list of node types that have at one time been included with
* the core of Node-RED but have since moved out to their own module.
*
* If a user has a flow that depends on one of these types and they do not have
* the new module installed, this will help them identify the missing module.
*/
var nodes = {
"irc in": {module:"node-red-node-irc"},
"irc out": {module:"node-red-node-irc"},
"irc-server": {module:"node-red-node-irc"},
"arduino in": {module:"node-red-node-arduino"},
"arduino out": {module:"node-red-node-arduino"},
"arduino-board": {module:"node-red-node-arduino"},
"redis out": {module:"node-red-node-redis"},
"mongodb": {module:"node-red-node-mongodb"},
"mongodb out": {module:"node-red-node-mongodb"},
"serial in": {module:"node-red-node-serialport"},
"serial out": {module:"node-red-node-serialport"},
"serial-port": {module:"node-red-node-serialport"},
"twitter-credentials": {module:"node-red-node-twitter"},
"twitter in": {module:"node-red-node-twitter"},
"twitter out": {module:"node-red-node-twitter"},
"e-mail": {module:"node-red-node-email"},
"e-mail in": {module:"node-red-node-email"},
"feedparse": {module:"node-red-node-feedparser"}
"feedparse": {module:"node-red-node-feedparser"},
"sentiment": {module:"node-red-node-sentiment"},
"tail": {module:"node-red-node-tail"}
}
module.exports = {

View File

@@ -235,12 +235,17 @@ function checkPrereq() {
return Promise.resolve();
} else {
return new Promise(resolve => {
child_process.execFile(npmCommand,['-v'],function(err) {
child_process.execFile(npmCommand,['-v'],function(err,stdout) {
if (err) {
log.info(log._("server.palette-editor.npm-not-found"));
paletteEditorEnabled = false;
} else {
paletteEditorEnabled = true;
if (parseInt(stdout.split(".")[0]) < 3) {
log.info(log._("server.palette-editor.npm-too-old"));
paletteEditorEnabled = false;
} else {
paletteEditorEnabled = true;
}
}
resolve();
});

View File

@@ -21,8 +21,8 @@ var semver = require("semver");
var localfilesystem = require("./localfilesystem");
var registry = require("./registry");
var i18n = require("@node-red/util").i18n; // TODO: separate module
var registryUtil = require("./util")
var i18n = require("@node-red/util").i18n;
var settings;
var runtime;
@@ -31,6 +31,7 @@ function init(_runtime) {
runtime = _runtime;
settings = runtime.settings;
localfilesystem.init(runtime);
registryUtil.init(runtime);
}
function load(defaultNodesDir,disableNodePathScan) {
@@ -44,92 +45,6 @@ function load(defaultNodesDir,disableNodePathScan) {
return loadNodeFiles(nodeFiles);
}
function copyObjectProperties(src,dst,copyList,blockList) {
if (!src) {
return;
}
if (copyList && !blockList) {
copyList.forEach(function(i) {
if (src.hasOwnProperty(i)) {
var propDescriptor = Object.getOwnPropertyDescriptor(src,i);
Object.defineProperty(dst,i,propDescriptor);
}
});
} else if (!copyList && blockList) {
for (var i in src) {
if (src.hasOwnProperty(i) && blockList.indexOf(i) === -1) {
var propDescriptor = Object.getOwnPropertyDescriptor(src,i);
Object.defineProperty(dst,i,propDescriptor);
}
}
}
}
function requireModule(name) {
var moduleInfo = registry.getModuleInfo(name);
if (moduleInfo && moduleInfo.path) {
var relPath = path.relative(__dirname, moduleInfo.path);
return require(relPath);
} else {
var err = new Error(`Cannot find module '${name}'`);
err.code = "MODULE_NOT_FOUND";
throw err;
}
}
function createNodeApi(node) {
var red = {
nodes: {},
log: {},
settings: {},
events: runtime.events,
util: runtime.util,
version: runtime.version,
require: requireModule,
comms: {
publish: function(topic,data,retain) {
runtime.events.emit("comms",{
topic: topic,
data: data,
retain: retain
})
}
},
library: {
register: function(type) {
return runtime.library.register(node.id,type);
}
},
httpNode: runtime.nodeApp,
server: runtime.server
}
copyObjectProperties(runtime.nodes,red.nodes,["createNode","getNode","eachNode","addCredentials","getCredentials","deleteCredentials" ]);
red.nodes.registerType = function(type,constructor,opts) {
runtime.nodes.registerType(node.id,type,constructor,opts);
}
copyObjectProperties(runtime.log,red.log,null,["init"]);
copyObjectProperties(runtime.settings,red.settings,null,["init","load","reset"]);
if (runtime.adminApi) {
red.auth = runtime.adminApi.auth;
red.httpAdmin = runtime.adminApi.adminApp;
} else {
//TODO: runtime.adminApi is always stubbed if not enabled, so this block
// is unused - but may be needed for the unit tests
red.auth = {
needsPermission: function() {}
};
// TODO: stub out httpAdmin/httpNode/server
}
red["_"] = function() {
var args = Array.prototype.slice.call(arguments, 0);
if (args[0].indexOf(":") === -1) {
args[0] = node.namespace+":"+args[0];
}
return i18n._.apply(null,args);
}
return red;
}
function loadNodeFiles(nodeFiles) {
var promises = [];
var nodes = [];
@@ -332,7 +247,7 @@ function loadNodeSet(node) {
var r = require(node.file);
if (typeof r === "function") {
var red = createNodeApi(node);
var red = registryUtil.createNodeApi(node);
var promise = r(red);
if (promise != null && typeof promise.then === "function") {
loadPromise = promise.then(function() {

View File

@@ -0,0 +1,110 @@
/**
* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
var i18n = require("@node-red/util").i18n;
var runtime;
function copyObjectProperties(src,dst,copyList,blockList) {
if (!src) {
return;
}
if (copyList && !blockList) {
copyList.forEach(function(i) {
if (src.hasOwnProperty(i)) {
var propDescriptor = Object.getOwnPropertyDescriptor(src,i);
Object.defineProperty(dst,i,propDescriptor);
}
});
} else if (!copyList && blockList) {
for (var i in src) {
if (src.hasOwnProperty(i) && blockList.indexOf(i) === -1) {
var propDescriptor = Object.getOwnPropertyDescriptor(src,i);
Object.defineProperty(dst,i,propDescriptor);
}
}
}
}
function requireModule(name) {
var moduleInfo = registry.getModuleInfo(name);
if (moduleInfo && moduleInfo.path) {
var relPath = path.relative(__dirname, moduleInfo.path);
return require(relPath);
} else {
var err = new Error(`Cannot find module '${name}'`);
err.code = "MODULE_NOT_FOUND";
throw err;
}
}
function createNodeApi(node) {
var red = {
nodes: {},
log: {},
settings: {},
events: runtime.events,
util: runtime.util,
version: runtime.version,
require: requireModule,
comms: {
publish: function(topic,data,retain) {
runtime.events.emit("comms",{
topic: topic,
data: data,
retain: retain
})
}
},
library: {
register: function(type) {
return runtime.library.register(node.id,type);
}
},
httpNode: runtime.nodeApp,
httpAdmin: runtime.adminApp,
server: runtime.server
}
copyObjectProperties(runtime.nodes,red.nodes,["createNode","getNode","eachNode","addCredentials","getCredentials","deleteCredentials" ]);
red.nodes.registerType = function(type,constructor,opts) {
runtime.nodes.registerType(node.id,type,constructor,opts);
}
copyObjectProperties(runtime.log,red.log,null,["init"]);
copyObjectProperties(runtime.settings,red.settings,null,["init","load","reset"]);
if (runtime.adminApi) {
red.auth = runtime.adminApi.auth;
} else {
//TODO: runtime.adminApi is always stubbed if not enabled, so this block
// is unused - but may be needed for the unit tests
red.auth = {
needsPermission: function(v) { return function(req,res,next) {next()} }
};
// TODO: stub out httpAdmin/httpNode/server
}
red["_"] = function() {
var args = Array.prototype.slice.call(arguments, 0);
if (args[0].indexOf(":") === -1) {
args[0] = node.namespace+":"+args[0];
}
return i18n._.apply(null,args);
}
return red;
}
module.exports = {
init: function(_runtime) {
runtime = _runtime;
},
createNodeApi: createNodeApi
}

View File

@@ -1,6 +1,6 @@
{
"name": "@node-red/registry",
"version": "0.20.0-alpha.0",
"version": "0.20.0-beta.2",
"license": "Apache-2.0",
"main": "./lib/index.js",
"repository": {
@@ -8,11 +8,15 @@
"url": "https://github.com/node-red/node-red.git"
},
"contributors": [
{ "name": "Nick O'Leary" },
{ "name": "Dave Conway-Jones"}
{
"name": "Nick O'Leary"
},
{
"name": "Dave Conway-Jones"
}
],
"dependencies": {
"@node-red/util": "*",
"@node-red/util": "0.20.0-beta.2",
"semver": "5.6.0",
"uglify-js": "3.4.9",
"when": "3.7.8"

View File

@@ -1,4 +1,4 @@
/**
/*!
* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,6 +14,30 @@
* limitations under the License.
**/
var events = require("events");
var events = require("events");
module.exports = new events.EventEmitter();
module.exports = new events.EventEmitter();
/**
* Runtime events emitter
* @mixin @node-red/runtime_events
*/
/**
* Register an event listener for a runtime event
* @name on
* @function
* @memberof @node-red/runtime_events
* @param {String} eventName - the name of the event to listen to
* @param {Function} listener - the callback function for the event
*/
/**
* Emit an event to all of its registered listeners
* @name emit
* @function
* @memberof @node-red/runtime_events
* @param {String} eventName - the name of the event to emit
* @param {any} ...args - the arguments to pass in the event
* @return {Boolean} - whether the event had listeners or not
*/

View File

@@ -53,6 +53,7 @@ var adminApi = {
}
var nodeApp;
var adminApp;
var server;
@@ -64,12 +65,13 @@ var server;
* better abstracted.
* @memberof @node-red/runtime
*/
function init(userSettings,httpServer,_adminApi) {
function init(userSettings,httpServer,_adminApi,__util) {
server = httpServer;
userSettings.version = getVersion();
settings.init(userSettings);
nodeApp = express();
adminApp = express();
if (_adminApi) {
adminApi = _adminApi;
@@ -78,6 +80,13 @@ function init(userSettings,httpServer,_adminApi) {
library.init(runtime);
externalAPI.init(runtime);
exec.init(runtime);
if (__util) {
log = __util.log;
i18n = __util.i18n;
} else {
log = redUtil.log;
i18n = redUtil.i18n;
}
}
var version;
@@ -103,7 +112,6 @@ function getVersion() {
* @memberof @node-red/runtime
*/
function start() {
return i18n.registerMessageCatalog("runtime",path.resolve(path.join(__dirname,"..","locales")),"runtime.json")
.then(function() { return storage.init(runtime)})
.then(function() { return settings.load(storage)})
@@ -269,6 +277,7 @@ var runtime = {
exec: exec,
util: require("@node-red/util").util,
get adminApi() { return adminApi },
get adminApp() { return adminApp },
get nodeApp() { return nodeApp },
get server() { return server },
isStarted: function() {
@@ -346,8 +355,12 @@ module.exports = {
storage: storage,
events: events,
util: require("@node-red/util").util,
get httpNode() { return nodeApp },
get server() { return server }
get httpAdmin() { return adminApp },
get server() { return server },
"_": runtime
}

View File

@@ -13,7 +13,8 @@
"loading": "Loading palette nodes",
"palette-editor": {
"disabled": "Palette editor disabled : user settings",
"npm-not-found": "Palette editor disabled : npm command not found"
"npm-not-found": "Palette editor disabled : npm command not found",
"npm-too-old": "Palette editor disabled : npm version too old. Requires npm >= 3.x"
},
"errors": "Failed to register __count__ node type",
"errors_plural": "Failed to register __count__ node types",

View File

@@ -1,6 +1,6 @@
{
"name": "@node-red/runtime",
"version": "0.20.0-alpha.0",
"version": "0.20.0-beta.2",
"license": "Apache-2.0",
"main": "./lib/index.js",
"repository": {
@@ -8,15 +8,19 @@
"url": "https://github.com/node-red/node-red.git"
},
"contributors": [
{ "name": "Nick O'Leary" },
{ "name": "Dave Conway-Jones"}
{
"name": "Nick O'Leary"
},
{
"name": "Dave Conway-Jones"
}
],
"dependencies": {
"@node-red/registry": "*",
"@node-red/util": "*",
"@node-red/registry": "0.20.0-beta.2",
"@node-red/util": "0.20.0-beta.2",
"clone": "2.1.2",
"express": "4.16.4",
"fs-extra": "5.0.0",
"fs-extra": "7.0.1",
"json-stringify-safe": "5.0.1",
"when": "3.7.8"
}

View File

@@ -1,4 +1,4 @@
/**
/*!
* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,17 +14,20 @@
* limitations under the License.
**/
/**
* @module @node-red/util
*/
const log = require("./lib/log");
const i18n = require("./lib/i18n");
const util = require("./lib/util");
/**
* This module provides common utilities for the Node-RED runtime and editor
*
* @namespace @node-red/util
*/
module.exports = {
/**
* Initialise the module with the runtime settings
* @param {Object} settings
* @memberof @node-red/util
*/
init: function(settings) {
log.init(settings);
@@ -33,19 +36,22 @@ module.exports = {
/**
* Logging utilities
* @see module:@node-red/util.module:log
* @mixes @node-red/util_log
* @memberof @node-red/util
*/
log: log,
/**
* Internationalization utilities
* @see module:@node-red/util.module:i18n
* @mixes @node-red/util_i18n
* @memberof @node-red/util
*/
i18n: i18n,
/**
* General utilities
* @see module:@node-red/util.module:util
* @mixes @node-red/util_util
* @memberof @node-red/util
*/
util: util,
}

View File

@@ -15,10 +15,10 @@
* @ignore
**/
/**
* @module i18n
* @memberof module:@node-red/util
*/
/**
* Internationalization utilities
* @mixin @node-red/util_i18n
*/
var i18n = require("i18next");
@@ -34,7 +34,7 @@ var initPromise;
/**
* Register multiple message catalogs with i18n.
* @memberof module:@node-red/util.module:i18n
* @memberof @node-red/util_i18n
*/
function registerMessageCatalogs(catalogs) {
var promises = catalogs.map(function(catalog) {
@@ -45,7 +45,7 @@ function registerMessageCatalogs(catalogs) {
/**
* Register a message catalog with i18n.
* @memberof module:@node-red/util.module:i18n
* @memberof @node-red/util_i18n
*/
function registerMessageCatalog(namespace,dir,file) {
return initPromise.then(function() {
@@ -146,7 +146,7 @@ function init() {
* Gets a message catalog.
* @name catalog
* @function
* @memberof module:@node-red/util.module:i18n
* @memberof @node-red/util_i18n
*/
function getCatalog(namespace,lang) {
var result = null;
@@ -182,7 +182,7 @@ var obj = module.exports = {
* Perform a message catalog lookup.
* @name _
* @function
* @memberof module:@node-red/util.module:i18n
* @memberof @node-red/util_i18n
*/
obj['_'] = function() {
//var opts = {};

View File

@@ -16,8 +16,8 @@
**/
/**
* @module log
* @memberof module:@node-red/util
* Logging utilities
* @mixin @node-red/util_log
*/
var util = require("util");
@@ -128,14 +128,16 @@ var log = module.exports = {
},
/**
* Add a log handler function.
* Add a log handler function
* @memberof @node-red/util_log
*/
addHandler: function(func) {
logHandlers.push(func);
},
/**
* Remove a log handler function.
* Remove a log handler function
* @memberof @node-red/util_log
*/
removeHandler: function(func) {
var index = logHandlers.indexOf(func);
@@ -145,7 +147,8 @@ var log = module.exports = {
},
/**
* Log a message object.
* Log a message object
* @memberof @node-red/util_log
*/
log: function(msg) {
msg.timestamp = Date.now();
@@ -155,42 +158,48 @@ var log = module.exports = {
},
/**
* Log a message at INFO level.
* Log a message at INFO level
* @memberof @node-red/util_log
*/
info: function(msg) {
log.log({level:log.INFO,msg:msg});
},
/**
* Log a message at WARN level.
* Log a message at WARN level
* @memberof @node-red/util_log
*/
warn: function(msg) {
log.log({level:log.WARN,msg:msg});
},
/**
* Log a message at ERROR level.
* Log a message at ERROR level
* @memberof @node-red/util_log
*/
error: function(msg) {
log.log({level:log.ERROR,msg:msg});
},
/**
* Log a message at TRACE level.
* Log a message at TRACE level
* @memberof @node-red/util_log
*/
trace: function(msg) {
log.log({level:log.TRACE,msg:msg});
},
/**
* Log a message at DEBUG level.
* Log a message at DEBUG level
* @memberof @node-red/util_log
*/
debug: function(msg) {
log.log({level:log.DEBUG,msg:msg});
},
/**
* Log a metric event.
* Check if metrics are enabled
* @memberof @node-red/util_log
*/
metric: function() {
return metricsEnabled;
@@ -198,6 +207,7 @@ var log = module.exports = {
/**
* Log an audit event.
* @memberof @node-red/util_log
*/
audit: function(msg,req) {
msg.level = log.AUDIT;
@@ -214,6 +224,6 @@ var log = module.exports = {
* Perform a message catalog lookup.
* @name _
* @function
* @memberof module:@node-red/util.module:log
* @memberof @node-red/util_log
*/
log["_"] = i18n._;

View File

@@ -15,10 +15,9 @@
* @ignore
**/
/**
* @module util
* @memberof module:@node-red/util
*/
/**
* @mixin @node-red/util_util
*/
const clone = require("clone");
@@ -29,7 +28,7 @@ const util = require("util");
/**
* Generates a psuedo-unique-random id.
* @return {String} a random-ish id
* @memberof module:@node-red/util.module:util
* @memberof @node-red/util_util
*/
function generateId() {
return (1+Math.random()*4294967295).toString(16);
@@ -41,7 +40,7 @@ function generateId() {
*
* @param {any} o - the property to convert to a String
* @return {String} the stringified version
* @memberof module:@node-red/util.module:util
* @memberof @node-red/util_util
*/
function ensureString(o) {
if (Buffer.isBuffer(o)) {
@@ -60,7 +59,7 @@ function ensureString(o) {
*
* @param {any} o - the property to convert to a Buffer
* @return {String} the Buffer version
* @memberof module:@node-red/util.module:util
* @memberof @node-red/util_util
*/
function ensureBuffer(o) {
if (Buffer.isBuffer(o)) {
@@ -79,7 +78,7 @@ function ensureBuffer(o) {
*
* @param {any} msg - the message object to clone
* @return {Object} the cloned message
* @memberof module:@node-red/util.module:util
* @memberof @node-red/util_util
*/
function cloneMessage(msg) {
// Temporary fix for #97
@@ -106,7 +105,7 @@ function cloneMessage(msg) {
* @param {any} obj1
* @param {any} obj2
* @return {boolean} whether the two objects are the same
* @memberof module:@node-red/util.module:util
* @memberof @node-red/util_util
*/
function compareObjects(obj1,obj2) {
var i;
@@ -189,7 +188,7 @@ function createError(code, message) {
*
* @param {String} str - the property expression
* @return {Array} the normalised expression
* @memberof module:@node-red/util.module:util
* @memberof @node-red/util_util
*/
function normalisePropertyExpression(str) {
// This must be kept in sync with validatePropertyExpression
@@ -304,7 +303,7 @@ function normalisePropertyExpression(str) {
* @param {Object} msg - the message object
* @param {String} str - the property expression
* @return {any} the message property, or undefined if it does not exist
* @memberof module:@node-red/util.module:util
* @memberof @node-red/util_util
*/
function getMessageProperty(msg,expr) {
if (expr.indexOf('msg.')===0) {
@@ -319,7 +318,7 @@ function getMessageProperty(msg,expr) {
* @param {Object} msg - the object
* @param {String} str - the property expression
* @return {any} the object property, or undefined if it does not exist
* @memberof module:@node-red/util.module:util
* @memberof @node-red/util_util
*/
function getObjectProperty(msg,expr) {
var result = null;
@@ -342,7 +341,7 @@ function getObjectProperty(msg,expr) {
* @param {String} prop - the property expression
* @param {any} value - the value to set
* @param {boolean} createMissing - whether to create missing parent properties
* @memberof module:@node-red/util.module:util
* @memberof @node-red/util_util
*/
function setMessageProperty(msg,prop,value,createMissing) {
if (prop.indexOf('msg.')===0) {
@@ -358,7 +357,7 @@ function setMessageProperty(msg,prop,value,createMissing) {
* @param {String} prop - the property expression
* @param {any} value - the value to set
* @param {boolean} createMissing - whether to create missing parent properties
* @memberof module:@node-red/util.module:util
* @memberof @node-red/util_util
*/
function setObjectProperty(msg,prop,value,createMissing) {
if (typeof createMissing === 'undefined') {
@@ -422,7 +421,7 @@ function setObjectProperty(msg,prop,value,createMissing) {
* will return `Hello Joe!`.
* @param {String} value - the string to parse
* @return {String} The parsed string
* @memberof module:@node-red/util.module:util
* @memberof @node-red/util_util
*/
function evaluateEnvProperty(value) {
if (/^\${[^}]+}$/.test(value)) {
@@ -450,7 +449,7 @@ function evaluateEnvProperty(value) {
*
* @param {String} value - the context property string to parse
* @return {Object} The parsed property
* @memberof module:@node-red/util.module:util
* @memberof @node-red/util_util
*/
function parseContextStore(key) {
var parts = {};
@@ -474,7 +473,7 @@ function parseContextStore(key) {
* @param {Object} msg - the message object to evaluate against
* @param {Function} callback - (optional) called when the property is evaluated
* @return {any} The evaluted property, if no `callback` is provided
* @memberof module:@node-red/util.module:util
* @memberof @node-red/util_util
*/
function evaluateNodeProperty(value, type, node, msg, callback) {
var result = value;
@@ -531,7 +530,7 @@ function evaluateNodeProperty(value, type, node, msg, callback) {
* @param {String} value - the JSONata expression
* @param {Node} node - the node evaluating the property
* @return {Object} The JSONata expression that can be evaluated
* @memberof module:@node-red/util.module:util
* @memberof @node-red/util_util
*/
function prepareJSONataExpression(value,node) {
var expr = jsonata(value);
@@ -559,7 +558,7 @@ function prepareJSONataExpression(value,node) {
* @param {Object} msg - the message object to evaluate against
* @param {Function} callback - (optional) called when the expression is evaluated
* @return {any} If no callback was provided, the result of the expression
* @memberof module:@node-red/util.module:util
* @memberof @node-red/util_util
*/
function evaluateJSONataExpression(expr,msg,callback) {
var context = msg;
@@ -604,7 +603,7 @@ function evaluateJSONataExpression(expr,msg,callback) {
*
* @param {String} name - the node type
* @return {String} The normalised name
* @memberof module:@node-red/util.module:util
* @memberof @node-red/util_util
*/
function normaliseNodeTypeName(name) {
var result = name.replace(/[^a-zA-Z0-9]/g, " ");
@@ -628,7 +627,7 @@ function normaliseNodeTypeName(name) {
* @param {Object} msg
* @param {Object} opts
* @return {Object} the encoded object
* @memberof module:@node-red/util.module:util
* @memberof @node-red/util_util
*/
function encodeObject(msg,opts) {
var debuglength = 1000;

View File

@@ -1,18 +1,22 @@
{
"name": "@node-red/util",
"version": "0.20.0-alpha.0",
"version": "0.20.0-beta.2",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "https://github.com/node-red/node-red.git"
},
"contributors": [
{ "name": "Nick O'Leary" },
{ "name": "Dave Conway-Jones"}
{
"name": "Nick O'Leary"
},
{
"name": "Dave Conway-Jones"
}
],
"dependencies": {
"clone": "2.1.2",
"i18next": "11.6.0",
"i18next": "12.1.0",
"json-stringify-safe": "5.0.1",
"jsonata": "1.5.4",
"when": "3.7.8"

View File

@@ -0,0 +1 @@
CHANGELOG.md

View File

@@ -9,11 +9,6 @@ A visual tool for wiring the Internet of Things.
![Node-RED: A visual tool for wiring the Internet of Things](http://nodered.org/images/node-red-screenshot.png)
### Repository Structure
This is a [monorepo](https://en.wikipedia.org/wiki/Monorepo) containing the source
code for all of the Node-RED component modules.
## Quick Start
Check out http://nodered.org/docs/getting-started/ for full instructions on getting
@@ -31,24 +26,7 @@ For further help, or general discussion, please use the [Node-RED Forum](https:/
## Developers
If you want to run the latest code from git, here's how to get started:
1. Clone the code:
git clone https://github.com/node-red/node-red.git
cd node-red
2. Install the node-red dependencies
npm install
3. Build the code
npm run build
4. Run
npm start
The main Node-RED modules are maintained as a monorepo on [GitHub](https://github.com/node-red/node-red).
## Contributing

View File

@@ -63,8 +63,13 @@ module.exports = {
}
redUtil.init(userSettings);
if (userSettings.httpAdminRoot !== false) {
// Initialise the runtime
runtime.init(userSettings,httpServer,api);
// Initialise the editor-api
api.init(userSettings,httpServer,runtime.storage,runtime);
// Attach the runtime admin app to the api admin app
api.httpAdmin.use(runtime.httpAdmin);
apiEnabled = true;
server = httpServer;
} else {
@@ -103,19 +108,46 @@ module.exports = {
})
},
/**
* Logging utilities
* @see @node-red/util_log
* @memberof node-red
*/
log: redUtil.log,
/**
* General utilities
* @see @node-red/util_util
* @memberof node-red
*/
util: redUtil.util,
get nodes() { console.log("Deprecated use of RED.nodes - refer to API documentation on RED.runtime.nodes"); return runtime._.nodes },
get settings() { console.log("Deprecated use of RED.settings - refer to API documentation on RED.runtime.settings"); return runtime._.settings },
get version() { console.log("Deprecated use of RED.version - refer to API documentation on RED.runtime.version"); return runtime._.version },
get events() { console.log("Deprecated use of RED.events - refer to API documentation on RED.runtime.events"); return runtime.events },
get nodes() { return runtime._.nodes },
/**
* Runtime events emitter
* @see @node-red/runtime_events
* @memberof node-red
*/
events: runtime.events,
get settings() { return runtime._.settings },
/**
* Get the version of the runtime
* @return {String} - the runtime version
* @function
* @memberof node-red
*/
get version() { return runtime._.version },
/**
* The express application for the Editor Admin API
* @memberof node-red
*/
get httpAdmin() { return api.adminApp },
get httpAdmin() { return api.httpAdmin },
/**
* The express application for HTTP Nodes

View File

@@ -1,6 +1,6 @@
{
"name": "node-red",
"version": "0.20.0-alpha.0",
"version": "0.20.0-beta.2",
"description": "A visual tool for wiring the Internet of Things",
"homepage": "http://nodered.org",
"license": "Apache-2.0",
@@ -17,8 +17,12 @@
"node-red-pi": "bin/node-red-pi"
},
"contributors": [
{ "name": "Nick O'Leary" },
{ "name": "Dave Conway-Jones"}
{
"name": "Nick O'Leary"
},
{
"name": "Dave Conway-Jones"
}
],
"keywords": [
"editor",
@@ -27,17 +31,19 @@
"flow"
],
"dependencies": {
"@node-red/editor-api": "0.20.0-alpha.0",
"@node-red/runtime": "0.20.0-alpha.0",
"@node-red/util": "0.20.0-alpha.0",
"@node-red/nodes": "0.20.0-alpha.0",
"@node-red/editor-api": "0.20.0-beta.2",
"@node-red/runtime": "0.20.0-beta.2",
"@node-red/util": "0.20.0-beta.2",
"@node-red/nodes": "0.20.0-beta.2",
"basic-auth": "2.0.1",
"bcryptjs": "2.4.3",
"express": "4.16.4",
"fs-extra": "5.0.0",
"node-red-node-email": "0.1.*",
"node-red-node-feedparser": "^0.1.12",
"fs-extra": "7.0.1",
"node-red-node-email": "1.0.*",
"node-red-node-feedparser": "^0.1.14",
"node-red-node-rbe": "0.2.*",
"node-red-node-sentiment": "^0.1.0",
"node-red-node-tail": "^0.0.1",
"node-red-node-twitter": "^1.1.0",
"nopt": "4.0.1",
"semver": "5.6.0"