Ensure node.sep is honoured when generating CSV

This commit is contained in:
Nick O'Leary 2024-12-05 16:00:54 +00:00
parent 84a2fbed2e
commit e4fdf24545
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
2 changed files with 11 additions and 11 deletions

View File

@ -171,7 +171,7 @@ module.exports = function(RED) {
} }
// join lines, don't forget to add the last new line // join lines, don't forget to add the last new line
msg.payload = ou.join(node.ret) + node.ret; msg.payload = ou.join(node.ret) + node.ret;
msg.columns = template.map(v => v.indexOf(',')!==-1 ? '"'+v+'"' : v).join(','); msg.columns = template.map(v => v.indexOf(node.sep)!==-1 ? '"'+v+'"' : v).join(node.sep);
if (msg.payload !== '') { if (msg.payload !== '') {
send(msg); send(msg);
} }
@ -289,14 +289,14 @@ 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 = template.map(v => v.indexOf(',')!==-1 ? '"'+v+'"' : v).filter(v => v).join(','); msg.columns = template.map(v => v.indexOf(node.sep)!==-1 ? '"'+v+'"' : v).filter(v => v).join(node.sep);
delete msg.parts; delete msg.parts;
send(msg); send(msg);
node.store = []; node.store = [];
} }
} }
else { else {
msg.columns = template.map(v => v.indexOf(',')!==-1 ? '"'+v+'"' : v).filter(v => v).join(','); msg.columns = template.map(v => v.indexOf(node.sep)!==-1 ? '"'+v+'"' : v).filter(v => v).join(node.sep);
send(msg); // finally send the array send(msg); // finally send the array
} }
} }
@ -304,7 +304,7 @@ module.exports = function(RED) {
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 = template.map(v => v.indexOf(',')!==-1 ? '"'+v+'"' : v).filter(v => v).join(','); newMessage.columns = template.map(v => v.indexOf(node.sep)!==-1 ? '"'+v+'"' : v).filter(v => v).join(node.sep);
newMessage.payload = a[i]; newMessage.payload = a[i];
if (!has_parts) { if (!has_parts) {
newMessage.parts = { newMessage.parts = {
@ -367,7 +367,7 @@ module.exports = function(RED) {
const sendHeadersAlways = node.hdrout === "all" const sendHeadersAlways = node.hdrout === "all"
const sendHeaders = !dontSendHeaders && (sendHeadersOnce || sendHeadersAlways) const sendHeaders = !dontSendHeaders && (sendHeadersOnce || sendHeadersAlways)
const quoteables = [node.sep, node.quo, "\n", "\r"] const quoteables = [node.sep, node.quo, "\n", "\r"]
const templateQuoteables = [',', '"', "\n", "\r"] const templateQuoteables = [node.sep, '"', "\n", "\r"]
let badTemplateWarnOnce = true let badTemplateWarnOnce = true
const columnStringToTemplateArray = function (col, sep) { const columnStringToTemplateArray = function (col, sep) {
@ -378,9 +378,9 @@ module.exports = function(RED) {
} }
const templateArrayToColumnString = function (template, keepEmptyColumns) { const templateArrayToColumnString = function (template, keepEmptyColumns) {
// NOTE: enforce strict column template parsing in RFC4180 mode // NOTE: enforce strict column template parsing in RFC4180 mode
const parsed = csv.parse('', {headers: template, headersOnly:true, separator: ',', quote: node.quo, outputStyle: 'array', strict: true }) const parsed = csv.parse('', {headers: template, headersOnly:true, separator: node.sep, quote: node.quo, outputStyle: 'array', strict: true })
return keepEmptyColumns return keepEmptyColumns
? parsed.headers.map(e => addQuotes(e || '', { separator: ',', quoteables: templateQuoteables})) ? parsed.headers.map(e => addQuotes(e || '', { separator: node.sep, quoteables: templateQuoteables})).join(node.sep)
: parsed.header // exclues empty columns : parsed.header // exclues empty columns
// TODO: resolve inconsistency between CSV->JSON and JSON->CSV // TODO: resolve inconsistency between CSV->JSON and JSON->CSV
// CSV->JSON: empty columns are excluded // CSV->JSON: empty columns are excluded
@ -441,7 +441,7 @@ module.exports = function(RED) {
if (sendHeaders && node.hdrSent === false) { if (sendHeaders && node.hdrSent === false) {
if (hasTemplate(template) === false) { if (hasTemplate(template) === false) {
if (msg.hasOwnProperty("columns")) { if (msg.hasOwnProperty("columns")) {
template = columnStringToTemplateArray(msg.columns || "", ",") || [''] template = columnStringToTemplateArray(msg.columns || "", node.sep) || ['']
} }
else { else {
template = Object.keys(inputData[0]) || [''] template = Object.keys(inputData[0]) || ['']
@ -475,7 +475,7 @@ module.exports = function(RED) {
} else { } else {
/*** row is an object ***/ /*** row is an object ***/
if (hasTemplate(template) === false && (msg.hasOwnProperty("columns"))) { if (hasTemplate(template) === false && (msg.hasOwnProperty("columns"))) {
template = columnStringToTemplateArray(msg.columns || "", ",") template = columnStringToTemplateArray(msg.columns || "", node.sep)
} }
if (hasTemplate(template) === false) { if (hasTemplate(template) === false) {
/*** row is an object but we still don't have a template ***/ /*** row is an object but we still don't have a template ***/

View File

@ -200,9 +200,9 @@ function parse(csvIn, parseOptions) {
if (!headers[i]) { if (!headers[i]) {
continue continue
} }
quotedHeaders.push(quoteCell(headers[i], { quote, separator: ',' })) quotedHeaders.push(quoteCell(headers[i], { quote, separator }))
} }
finalResult.header = quotedHeaders.join(',') // always quote headers and join with comma finalResult.header = quotedHeaders.join(separator) // always quote headers and join with comma
// output is an array of arrays [[],[],[]] // output is an array of arrays [[],[],[]]
if (ouputArrays || headersOnly) { if (ouputArrays || headersOnly) {