mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Update CSV node to support Property In/Out
This commit is contained in:
parent
2621a3a628
commit
4874e64387
@ -1,5 +1,13 @@
|
||||
|
||||
<script type="text/html" data-template-name="csv">
|
||||
<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>
|
||||
<div class="form-row">
|
||||
<label for="node-input-property"><i class="fa fa-sign-in"></i> <span data-i18n="common.label.propertyIn"></span></label>
|
||||
<input type="text" id="node-input-property" style="width:70%;"/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-temp"><i class="fa fa-list"></i> <span data-i18n="csv.label.columns"></span></label>
|
||||
<input type="text" id="node-input-temp" data-i18n="[placeholder]csv.placeholder.columns">
|
||||
@ -32,8 +40,8 @@
|
||||
</div>
|
||||
</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">
|
||||
<label for="node-input-propertyOut"><i class="fa fa-sign-out"></i> <span data-i18n="common.label.propertyOut"></span></label>
|
||||
<input type="text" id="node-input-propertyOut" style="width:70%;"/>
|
||||
</div>
|
||||
<hr align="middle"/>
|
||||
<div class="form-row">
|
||||
@ -102,7 +110,13 @@
|
||||
skip: {value:"0"},
|
||||
strings: {value:true},
|
||||
include_empty_strings: {value:""},
|
||||
include_null_values: {value:""}
|
||||
include_null_values: {value:""},
|
||||
property: {value:"payload",required:true,
|
||||
validate: RED.validators.typedInput({ type: 'msg', allowUndefined: true }),
|
||||
label:RED._("node-red:common.label.propertyIn")},
|
||||
propertyOut: {value:"payload",required:true,
|
||||
validate: RED.validators.typedInput({ type: 'msg', allowUndefined: true}),
|
||||
label:RED._("node-red:common.label.propertyOut")}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:1,
|
||||
|
@ -26,6 +26,9 @@ module.exports = function(RED) {
|
||||
|
||||
node.status({}) // clear status
|
||||
|
||||
node.property = n.property||"payload";
|
||||
node.propertyOut = n.propertyOut||node.property;
|
||||
|
||||
if (legacyMode) {
|
||||
this.template = (n.temp || "");
|
||||
this.sep = (n.sep || ',').replace(/\\t/g,"\t").replace(/\\n/g,"\n").replace(/\\r/g,"\r");
|
||||
@ -66,43 +69,44 @@ module.exports = function(RED) {
|
||||
if (msg.hasOwnProperty("reset")) {
|
||||
node.hdrSent = false;
|
||||
}
|
||||
if (msg.hasOwnProperty("payload")) {
|
||||
if (typeof msg.payload == "object") { // convert object to CSV string
|
||||
if (msg.hasOwnProperty(node.property)) {
|
||||
let inputData = RED.util.getMessageProperty(msg, node.property)
|
||||
if (typeof inputData == "object") { // convert object to CSV string
|
||||
try {
|
||||
if (!(notemplate && (msg.hasOwnProperty("parts") && msg.parts.hasOwnProperty("index") && msg.parts.index > 0))) {
|
||||
template = clean(node.template);
|
||||
}
|
||||
const ou = [];
|
||||
if (!Array.isArray(msg.payload)) { msg.payload = [ msg.payload ]; }
|
||||
if (!Array.isArray(inputData)) { inputData = [ inputData ]; }
|
||||
if (node.hdrout !== "none" && node.hdrSent === false) {
|
||||
if ((template.length === 1) && (template[0] === '')) {
|
||||
if (msg.hasOwnProperty("columns")) {
|
||||
template = clean(msg.columns || "",",");
|
||||
}
|
||||
else {
|
||||
template = Object.keys(msg.payload[0]);
|
||||
template = Object.keys(inputData[0]);
|
||||
}
|
||||
}
|
||||
ou.push(template.map(v => v.indexOf(node.sep)!==-1 ? '"'+v+'"' : v).join(node.sep));
|
||||
if (node.hdrout === "once") { node.hdrSent = true; }
|
||||
}
|
||||
for (var s = 0; s < msg.payload.length; s++) {
|
||||
if ((Array.isArray(msg.payload[s])) || (typeof msg.payload[s] !== "object")) {
|
||||
if (typeof msg.payload[s] !== "object") { msg.payload = [ msg.payload ]; }
|
||||
for (var t = 0; t < msg.payload[s].length; t++) {
|
||||
if (msg.payload[s][t] === undefined) { msg.payload[s][t] = ""; }
|
||||
if (msg.payload[s][t].toString().indexOf(node.quo) !== -1) { // add double quotes if any quotes
|
||||
msg.payload[s][t] = msg.payload[s][t].toString().replace(/"/g, '""');
|
||||
msg.payload[s][t] = node.quo + msg.payload[s][t].toString() + node.quo;
|
||||
for (var s = 0; s < inputData.length; s++) {
|
||||
if ((Array.isArray(inputData[s])) || (typeof inputData[s] !== "object")) {
|
||||
if (typeof inputData[s] !== "object") { inputData = [ inputData ]; }
|
||||
for (var t = 0; t < inputData[s].length; t++) {
|
||||
if (inputData[s][t] === undefined) { inputData[s][t] = ""; }
|
||||
if (inputData[s][t].toString().indexOf(node.quo) !== -1) { // add double quotes if any quotes
|
||||
inputData[s][t] = inputData[s][t].toString().replace(/"/g, '""');
|
||||
inputData[s][t] = node.quo + inputData[s][t].toString() + node.quo;
|
||||
}
|
||||
else if (msg.payload[s][t].toString().indexOf(node.sep) !== -1) { // add quotes if any "commas"
|
||||
msg.payload[s][t] = node.quo + msg.payload[s][t].toString() + node.quo;
|
||||
else if (inputData[s][t].toString().indexOf(node.sep) !== -1) { // add quotes if any "commas"
|
||||
inputData[s][t] = node.quo + inputData[s][t].toString() + node.quo;
|
||||
}
|
||||
else if (msg.payload[s][t].toString().indexOf("\n") !== -1) { // add quotes if any "\n"
|
||||
msg.payload[s][t] = node.quo + msg.payload[s][t].toString() + node.quo;
|
||||
else if (inputData[s][t].toString().indexOf("\n") !== -1) { // add quotes if any "\n"
|
||||
inputData[s][t] = node.quo + inputData[s][t].toString() + node.quo;
|
||||
}
|
||||
}
|
||||
ou.push(msg.payload[s].join(node.sep));
|
||||
ou.push(inputData[s].join(node.sep));
|
||||
}
|
||||
else {
|
||||
if ((template.length === 1) && (template[0] === '') && (msg.hasOwnProperty("columns"))) {
|
||||
@ -115,16 +119,16 @@ module.exports = function(RED) {
|
||||
tmpwarn = false;
|
||||
}
|
||||
const row = [];
|
||||
for (var p in msg.payload[0]) {
|
||||
for (var p in inputData[0]) {
|
||||
/* istanbul ignore else */
|
||||
if (msg.payload[s].hasOwnProperty(p)) {
|
||||
if (inputData[s].hasOwnProperty(p)) {
|
||||
/* istanbul ignore else */
|
||||
if (typeof msg.payload[s][p] !== "object") {
|
||||
if (typeof inputData[s][p] !== "object") {
|
||||
// Fix to honour include null values flag
|
||||
//if (typeof msg.payload[s][p] !== "object" || (node.include_null_values === true && msg.payload[s][p] === null)) {
|
||||
//if (typeof inputData[s][p] !== "object" || (node.include_null_values === true && inputData[s][p] === null)) {
|
||||
var q = "";
|
||||
if (msg.payload[s][p] !== undefined) {
|
||||
q += msg.payload[s][p];
|
||||
if (inputData[s][p] !== undefined) {
|
||||
q += inputData[s][p];
|
||||
}
|
||||
if (q.indexOf(node.quo) !== -1) { // add double quotes if any quotes
|
||||
q = q.replace(/"/g, '""');
|
||||
@ -149,7 +153,7 @@ module.exports = function(RED) {
|
||||
var tt = template[t];
|
||||
if (template[t].indexOf('"') >=0 ) { tt = "'"+tt+"'"; }
|
||||
else { tt = '"'+tt+'"'; }
|
||||
var p = RED.util.getMessageProperty(msg,'payload["'+s+'"]['+tt+']');
|
||||
var p = RED.util.getMessageProperty(msg, node.property + '["'+s+'"]['+tt+']');
|
||||
/* istanbul ignore else */
|
||||
if (p === undefined) { p = ""; }
|
||||
// fix to honour include null values flag
|
||||
@ -170,16 +174,17 @@ module.exports = function(RED) {
|
||||
}
|
||||
}
|
||||
// join lines, don't forget to add the last new line
|
||||
msg.payload = ou.join(node.ret) + node.ret;
|
||||
inputData = ou.join(node.ret) + node.ret;
|
||||
RED.util.setMessageProperty(msg, node.propertyOut, inputData)
|
||||
msg.columns = template.map(v => v.indexOf(',')!==-1 ? '"'+v+'"' : v).join(',');
|
||||
if (msg.payload !== '') {
|
||||
if (inputData !== '') {
|
||||
send(msg);
|
||||
}
|
||||
done();
|
||||
}
|
||||
catch(e) { done(e); }
|
||||
}
|
||||
else if (typeof msg.payload == "string") { // convert CSV string to object
|
||||
else if (typeof inputData == "string") { // convert CSV string to object
|
||||
try {
|
||||
var f = true; // flag to indicate if inside or outside a pair of quotes true = outside.
|
||||
var j = 0; // pointer into array of template items
|
||||
@ -188,7 +193,7 @@ module.exports = function(RED) {
|
||||
var a = []; // output array is needed for multiline option
|
||||
var first = true; // is this the first line
|
||||
var last = false;
|
||||
var line = msg.payload;
|
||||
var line = inputData;
|
||||
var linecount = 0;
|
||||
var tmp = "";
|
||||
var has_parts = msg.hasOwnProperty("parts");
|
||||
@ -282,13 +287,13 @@ module.exports = function(RED) {
|
||||
}
|
||||
|
||||
if (node.multi !== "one") {
|
||||
msg.payload = a;
|
||||
inputData = a;
|
||||
if (has_parts && nocr <= 1) {
|
||||
if (JSON.stringify(o) !== "{}") {
|
||||
node.store.push(o);
|
||||
}
|
||||
if (msg.parts.index + 1 === msg.parts.count) {
|
||||
msg.payload = node.store;
|
||||
inputData = node.store;
|
||||
msg.columns = template.map(v => v.indexOf(',')!==-1 ? '"'+v+'"' : v).filter(v => v).join(',');
|
||||
delete msg.parts;
|
||||
send(msg);
|
||||
@ -305,7 +310,7 @@ module.exports = function(RED) {
|
||||
for (var i = 0; i < len; i++) {
|
||||
var newMessage = RED.util.cloneMessage(msg);
|
||||
newMessage.columns = template.map(v => v.indexOf(',')!==-1 ? '"'+v+'"' : v).filter(v => v).join(',');
|
||||
newMessage.payload = a[i];
|
||||
RED.util.setMessageProperty(newMessage, node.propertyOut, a[i])
|
||||
if (!has_parts) {
|
||||
newMessage.parts = {
|
||||
id: msg._msgid,
|
||||
@ -411,8 +416,8 @@ module.exports = function(RED) {
|
||||
if (msg.hasOwnProperty("reset")) {
|
||||
node.hdrSent = false
|
||||
}
|
||||
if (msg.hasOwnProperty("payload")) {
|
||||
let inputData = msg.payload
|
||||
if (msg.hasOwnProperty(node.property)) {
|
||||
let inputData = RED.util.getMessageProperty(msg, node.property)
|
||||
if (typeof inputData == "object") { // convert object to CSV string
|
||||
try {
|
||||
// first determine the payload kind. Array or objects? Array of primitives? Array of arrays? Just an object?
|
||||
@ -517,9 +522,10 @@ module.exports = function(RED) {
|
||||
}
|
||||
|
||||
// join lines, don't forget to add the last new line
|
||||
msg.payload = stringBuilder.join(node.ret) + node.ret
|
||||
const result = stringBuilder.join(node.ret) + node.ret
|
||||
RED.util.setMessageProperty(msg, node.propertyOut, result)
|
||||
msg.columns = templateArrayToColumnString(template)
|
||||
if (msg.payload !== '') { send(msg) }
|
||||
if (result !== '') { send(msg) }
|
||||
done()
|
||||
}
|
||||
catch (e) {
|
||||
@ -614,7 +620,7 @@ module.exports = function(RED) {
|
||||
node.store.push(...data)
|
||||
}
|
||||
if (msg.parts.index + 1 === msg.parts.count) {
|
||||
msg.payload = node.store
|
||||
RED.util.setMessageProperty(msg, node.propertyOut, node.store)
|
||||
msg.columns = csvParseResult.header
|
||||
// msg._mode = 'RFC4180 mode'
|
||||
delete msg.parts
|
||||
@ -625,7 +631,7 @@ module.exports = function(RED) {
|
||||
else {
|
||||
msg.columns = csvParseResult.header
|
||||
// msg._mode = 'RFC4180 mode'
|
||||
msg.payload = data
|
||||
RED.util.setMessageProperty(msg, node.propertyOut, data)
|
||||
send(msg); // finally send the array
|
||||
}
|
||||
}
|
||||
@ -634,7 +640,7 @@ module.exports = function(RED) {
|
||||
for (let row = 0; row < len; row++) {
|
||||
const newMessage = RED.util.cloneMessage(msg)
|
||||
newMessage.columns = csvParseResult.header
|
||||
newMessage.payload = data[row]
|
||||
RED.util.setMessageProperty(newMessage, node.propertyOut, data[row])
|
||||
if (!has_parts) {
|
||||
newMessage.parts = {
|
||||
id: msg._msgid,
|
||||
|
Loading…
x
Reference in New Issue
Block a user