csv42
Advanced tools
Comparing version 3.0.2 to 3.0.3
@@ -10,3 +10,7 @@ "use strict"; | ||
* Stringify an array with a path in a JSON path like 'items[3].name' | ||
* Note that we allow all characters in a property name, like "item with spaces[3].name" | ||
* Note that we allow all characters in a property name, like 'item with spaces[3].name' | ||
* Property names containing a special character like a dot . are escaped inside a string | ||
* like 'object.["prop with ."]'. | ||
* Double quotes inside a string are escaped by a backslash character, | ||
* like 'object.["prop with \" double quotes"]' | ||
*/ | ||
@@ -16,8 +20,12 @@ function stringifyPath(path) { | ||
return typeof p === 'number' ? '[' + p + ']' : /[.\[\]]/.test(p) || p === '' // match any character . or [ or ] and handle an empty string | ||
? '["' + p + '"]' : (index > 0 ? '.' : '') + p; | ||
? '["' + escapeQuote(p) + '"]' : (index > 0 ? '.' : '') + p; | ||
}).join(''); | ||
} | ||
function escapeQuote(prop) { | ||
return prop.replace(/"/g, '\\"'); | ||
} | ||
/** | ||
* Parse a JSON path like 'items[3].name' into a Path | ||
* Parse a JSON path like 'items[3].name' into a Path. | ||
* See also function `stringifyPath`. | ||
*/ | ||
@@ -37,3 +45,3 @@ function parsePath(pathStr) { | ||
return c === '"'; | ||
})); | ||
}, true)); | ||
eatCharacter('"'); | ||
@@ -55,7 +63,15 @@ } else { | ||
function parseProp(isEnd) { | ||
var start = i; | ||
var unescape = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; | ||
var prop = ''; | ||
while (i < pathStr.length && !isEnd(pathStr[i])) { | ||
i++; | ||
if (unescape && pathStr[i] === '\\' && pathStr[i + 1] === '"') { | ||
// escaped double quote | ||
prop += '"'; | ||
i += 2; | ||
} else { | ||
prop += pathStr[i]; | ||
i++; | ||
} | ||
} | ||
return pathStr.substring(start, i); | ||
return prop; | ||
} | ||
@@ -62,0 +78,0 @@ function eatCharacter(char) { |
/** | ||
* Stringify an array with a path in a JSON path like 'items[3].name' | ||
* Note that we allow all characters in a property name, like "item with spaces[3].name" | ||
* Note that we allow all characters in a property name, like 'item with spaces[3].name' | ||
* Property names containing a special character like a dot . are escaped inside a string | ||
* like 'object.["prop with ."]'. | ||
* Double quotes inside a string are escaped by a backslash character, | ||
* like 'object.["prop with \" double quotes"]' | ||
*/ | ||
@@ -8,8 +12,12 @@ export function stringifyPath(path) { | ||
return typeof p === 'number' ? '[' + p + ']' : /[.\[\]]/.test(p) || p === '' // match any character . or [ or ] and handle an empty string | ||
? '["' + p + '"]' : (index > 0 ? '.' : '') + p; | ||
? '["' + escapeQuote(p) + '"]' : (index > 0 ? '.' : '') + p; | ||
}).join(''); | ||
} | ||
function escapeQuote(prop) { | ||
return prop.replace(/"/g, '\\"'); | ||
} | ||
/** | ||
* Parse a JSON path like 'items[3].name' into a Path | ||
* Parse a JSON path like 'items[3].name' into a Path. | ||
* See also function `stringifyPath`. | ||
*/ | ||
@@ -27,3 +35,3 @@ export function parsePath(pathStr) { | ||
i++; | ||
path.push(parseProp(c => c === '"')); | ||
path.push(parseProp(c => c === '"', true)); | ||
eatCharacter('"'); | ||
@@ -41,7 +49,15 @@ } else { | ||
function parseProp(isEnd) { | ||
const start = i; | ||
let unescape = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; | ||
let prop = ''; | ||
while (i < pathStr.length && !isEnd(pathStr[i])) { | ||
i++; | ||
if (unescape && pathStr[i] === '\\' && pathStr[i + 1] === '"') { | ||
// escaped double quote | ||
prop += '"'; | ||
i += 2; | ||
} else { | ||
prop += pathStr[i]; | ||
i++; | ||
} | ||
} | ||
return pathStr.substring(start, i); | ||
return prop; | ||
} | ||
@@ -48,0 +64,0 @@ function eatCharacter(char) { |
import { Path } from './types.js'; | ||
/** | ||
* Stringify an array with a path in a JSON path like 'items[3].name' | ||
* Note that we allow all characters in a property name, like "item with spaces[3].name" | ||
* Note that we allow all characters in a property name, like 'item with spaces[3].name' | ||
* Property names containing a special character like a dot . are escaped inside a string | ||
* like 'object.["prop with ."]'. | ||
* Double quotes inside a string are escaped by a backslash character, | ||
* like 'object.["prop with \" double quotes"]' | ||
*/ | ||
export declare function stringifyPath(path: Path): string; | ||
/** | ||
* Parse a JSON path like 'items[3].name' into a Path | ||
* Parse a JSON path like 'items[3].name' into a Path. | ||
* See also function `stringifyPath`. | ||
*/ | ||
export declare function parsePath(pathStr: string): Path; | ||
//# sourceMappingURL=path.d.ts.map |
@@ -45,3 +45,7 @@ (function (global, factory) { | ||
* Stringify an array with a path in a JSON path like 'items[3].name' | ||
* Note that we allow all characters in a property name, like "item with spaces[3].name" | ||
* Note that we allow all characters in a property name, like 'item with spaces[3].name' | ||
* Property names containing a special character like a dot . are escaped inside a string | ||
* like 'object.["prop with ."]'. | ||
* Double quotes inside a string are escaped by a backslash character, | ||
* like 'object.["prop with \" double quotes"]' | ||
*/ | ||
@@ -51,8 +55,12 @@ function stringifyPath(path) { | ||
return typeof p === 'number' ? '[' + p + ']' : /[.\[\]]/.test(p) || p === '' // match any character . or [ or ] and handle an empty string | ||
? '["' + p + '"]' : (index > 0 ? '.' : '') + p; | ||
? '["' + escapeQuote(p) + '"]' : (index > 0 ? '.' : '') + p; | ||
}).join(''); | ||
} | ||
function escapeQuote(prop) { | ||
return prop.replace(/"/g, '\\"'); | ||
} | ||
/** | ||
* Parse a JSON path like 'items[3].name' into a Path | ||
* Parse a JSON path like 'items[3].name' into a Path. | ||
* See also function `stringifyPath`. | ||
*/ | ||
@@ -70,3 +78,3 @@ function parsePath(pathStr) { | ||
i++; | ||
path.push(parseProp(c => c === '"')); | ||
path.push(parseProp(c => c === '"', true)); | ||
eatCharacter('"'); | ||
@@ -84,7 +92,15 @@ } else { | ||
function parseProp(isEnd) { | ||
const start = i; | ||
let unescape = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; | ||
let prop = ''; | ||
while (i < pathStr.length && !isEnd(pathStr[i])) { | ||
i++; | ||
if (unescape && pathStr[i] === '\\' && pathStr[i + 1] === '"') { | ||
// escaped double quote | ||
prop += '"'; | ||
i += 2; | ||
} else { | ||
prop += pathStr[i]; | ||
i++; | ||
} | ||
} | ||
return pathStr.substring(start, i); | ||
return prop; | ||
} | ||
@@ -91,0 +107,0 @@ function eatCharacter(char) { |
@@ -1,1 +0,1 @@ | ||
!function(n,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((n="undefined"!=typeof globalThis?globalThis:n||self).csv42={})}(this,function(n){"use strict";function r(n,e){let t=n,r=0;for(;r<e.length&&void 0!==t;)t=t?.[e[r]],r++;return t}function d(n,e,t){let r=n;var o=e.length-1;let i=0;for(;i<o;){var u=e[i];void 0===r[u]&&("number"==typeof e[i+1]?r[u]=[]:r[u]={}),r=r[u],i++}return r[e[o]]=t,n}function c(n){return"object"==typeof n&&null!==n&&n.constructor===Object}function t(n){return n.map((n,e)=>"number"==typeof n?"["+n+"]":/[.\[\]]/.test(n)||""===n?'["'+n+'"]':(0<e?".":"")+n).join("")}function p(t){var n,e,r=[];let o=0;for(;o<t.length;)"."===t[o]&&o++,"["===t[o]?(o++,'"'===t[o]?(o++,r.push(i(n=>'"'===n)),u('"')):(n=i(n=>"]"===n),e=Number(n),r.push(isNaN(e)?n:e)),u("]")):r.push(i(n=>"."===n||"["===n));function i(n){for(var e=o;o<t.length&&!n(t[o]);)o++;return t.substring(e,o)}function u(n){if(t[o]!==n)throw new SyntaxError(`Invalid JSON path: ${n} expected at position `+o);o++}return r}function l(n,e){return o(n,e).map(n=>({name:t(n),getValue:function(e){if(1!==e.length)return n=>r(n,e);{const t=e[0];return n=>n[t]}}(n)}))}const i=Symbol();function o(n,e){const t={};n.forEach(n=>{e(n)||c(n)?function n(e,t,r){for(const o in e){const i=e[o],u=t[o]||(t[o]=Array.isArray(i)?[]:{});r(i)?n(i,u,r):f(i,u)}}(n,t,e):f(n,t)});n=[];return function t(n,r,o){if(!0===n[i]||null===n[i]&&u(n))o.push(r);else if(Array.isArray(n))n.forEach((n,e)=>t(n,r.concat(e),o));else if(c(n))for(const e in n)t(n[e],r.concat(e),o)}(t,[],n),n}function f(n,e){void 0===e[i]&&(e[i]=null!=n||null)}function u(n){return 0===Object.keys(n).length}function s(n){const r=new RegExp("["+n+'"\r\n]'),o=/"/g;return function n(e){var t;return"string"==typeof e?(t=e,r.test(t)||0===t.length?`"${t.replaceAll(o,'""')}"`:t):"number"==typeof e||"boolean"==typeof e?e+"":null==e?"":n(JSON.stringify(e))}}function g(n){if(0===n.length)return null;var e,n=y(n);if("-"<=n[0]&&n[0]<="9")return e=Number(n),isNaN(e)?n:e;if("true"===n)return!0;if("false"===n)return!1;if("null"===n)return null;if("{"===n[0]||"["===n[0])try{return JSON.parse(n)}catch(n){}return n}const e=/""/g;function y(n){return'"'===n[0]?n.substring(1,n.length-1).replaceAll(e,'"'):n}function m(n){if(1!==n.length)throw new Error(`Invalid delimiter: must be a single character but is "${n}"`);return n}function v(n,e){return A(n,e)||b(n,e)}function A(n,e){return n.charCodeAt(e)===a}function b(n,e){return n.charCodeAt(e)===h&&n.charCodeAt(e+1)===a}const a=10,h=13;n.collectNestedPaths=o,n.createFormatValue=s,n.csv2json=function(r,n){const o=!1!==n?.header,i=m(n?.delimiter||",").charCodeAt(0),u=34;var e=n?.parseValue||g,t=[];let f=0;var a,c=function(){const t=[];s((n,e)=>{t.push(o?String(n):"Field "+e)},y),o||(f=0);return t}();const l=n?.fields?function(n,e){var t,r=[];for(t of e){var o=void 0!==t.index?t.index:n.indexOf(t.name);if(-1===o)throw new Error(`Field "${t.name}" not found in the csv data`);if(r[o])throw new Error("Duplicate field for index "+o);r[o]=t}return r}(c,Array.isArray(n?.fields)?n?.fields:n?.fields(c)):(a=!1!==n?.nested,c.map(t=>{const r=p(t),o=r[0];return{name:t,setValue:0!==r.length&&a?1===r.length?(n,e)=>n[o]=e:(n,e)=>d(n,r,e):(n,e)=>n[t]=e}}));for(;f<r.length;){const h={};s((n,e)=>{l[e]?.setValue(h,n)},e),t.push(h)}return t;function s(n,e){let t=0;for(;f<r.length&&!v(r,f);)n(function(n){var e=f;if(r.charCodeAt(f)===u){do{for(f++;r.charCodeAt(f)===u&&r.charCodeAt(f+1)===u;)f+=2}while(f<r.length&&r.charCodeAt(f)!==u);if(r.charCodeAt(f)!==u)throw new Error('Unexpected end: end quote " missing');f++}else for(;f<r.length&&r.charCodeAt(f)!==i&&!v(r,f);)f++;return n(r.substring(e,f))}(e),t),t++,r.charCodeAt(f)===i&&f++;A(r,f)?f++:b(r,f)&&(f+=2)}},n.getIn=r,n.isObject=c,n.isObjectOrArray=function(n){return c(n)||Array.isArray(n)},n.json2csv=function(e,n){var t=!1!==n?.header;const r=m(n?.delimiter||",");var o=function(n){if(v(n,0))return n;throw new Error('Invalid EOL character: choose "\\n" or "\\r\\n"')}(n?.eol||"\r\n"),i="function"==typeof n?.flatten?n?.flatten:!1===n?.flatten?()=>!1:c;const u=n?.fields?Array.isArray(n?.fields)?n?.fields:n?.fields(e):l(e,i),f=n?.formatValue||s(r);let a="";t&&(a+=u.map(n=>f(n.name)).join(r)+o);for(let n=0;n<e.length;n++)a+=function(e){return u.map(n=>f(n.getValue(e))).join(r)}(e[n])+o;return a},n.parsePath=p,n.parseValue=g,n.setIn=d,n.stringifyPath=t,n.unescapeValue=y}); | ||
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).csv42={})}(this,function(e){"use strict";function r(e,n){let t=e,r=0;for(;r<n.length&&void 0!==t;)t=t?.[n[r]],r++;return t}function d(e,n,t){let r=e;var o=n.length-1;let i=0;for(;i<o;){var u=n[i];void 0===r[u]&&("number"==typeof n[i+1]?r[u]=[]:r[u]={}),r=r[u],i++}return r[n[o]]=t,e}function c(e){return"object"==typeof e&&null!==e&&e.constructor===Object}function t(e){return e.map((e,n)=>"number"==typeof e?"["+e+"]":/[.\[\]]/.test(e)||""===e?'["'+e.replace(/"/g,'\\"')+'"]':(0<n?".":"")+e).join("")}function p(o){var e,n,t=[];let i=0;for(;i<o.length;)"."===o[i]&&i++,"["===o[i]?(i++,'"'===o[i]?(i++,t.push(r(e=>'"'===e,!0)),u('"')):(e=r(e=>"]"===e),n=Number(e),t.push(isNaN(n)?e:n)),u("]")):t.push(r(e=>"."===e||"["===e));function r(e,n){var t=1<arguments.length&&void 0!==n&&n;let r="";for(;i<o.length&&!e(o[i]);)t&&"\\"===o[i]&&'"'===o[i+1]?(r+='"',i+=2):(r+=o[i],i++);return r}function u(e){if(o[i]!==e)throw new SyntaxError(`Invalid JSON path: ${e} expected at position `+i);i++}return t}function l(e,n){return o(e,n).map(e=>({name:t(e),getValue:function(n){if(1!==n.length)return e=>r(e,n);{const t=n[0];return e=>e[t]}}(e)}))}const i=Symbol();function o(e,n){const t={};e.forEach(e=>{n(e)||c(e)?function e(n,t,r){for(const o in n){const i=n[o],u=t[o]||(t[o]=Array.isArray(i)?[]:{});r(i)?e(i,u,r):f(i,u)}}(e,t,n):f(e,t)});e=[];return function t(e,r,o){if(!0===e[i]||null===e[i]&&u(e))o.push(r);else if(Array.isArray(e))e.forEach((e,n)=>t(e,r.concat(n),o));else if(c(e))for(const n in e)t(e[n],r.concat(n),o)}(t,[],e),e}function f(e,n){void 0===n[i]&&(n[i]=null!=e||null)}function u(e){return 0===Object.keys(e).length}function s(e){const r=new RegExp("["+e+'"\r\n]'),o=/"/g;return function e(n){var t;return"string"==typeof n?(t=n,r.test(t)||0===t.length?`"${t.replaceAll(o,'""')}"`:t):"number"==typeof n||"boolean"==typeof n?n+"":null==n?"":e(JSON.stringify(n))}}function g(e){if(0===e.length)return null;var n,e=y(e);if("-"<=e[0]&&e[0]<="9")return n=Number(e),isNaN(n)?e:n;if("true"===e)return!0;if("false"===e)return!1;if("null"===e)return null;if("{"===e[0]||"["===e[0])try{return JSON.parse(e)}catch(e){}return e}const n=/""/g;function y(e){return'"'===e[0]?e.substring(1,e.length-1).replaceAll(n,'"'):e}function m(e){if(1!==e.length)throw new Error(`Invalid delimiter: must be a single character but is "${e}"`);return e}function v(e,n){return A(e,n)||b(e,n)}function A(e,n){return e.charCodeAt(n)===a}function b(e,n){return e.charCodeAt(n)===h&&e.charCodeAt(n+1)===a}const a=10,h=13;e.collectNestedPaths=o,e.createFormatValue=s,e.csv2json=function(r,e){const o=!1!==e?.header,i=m(e?.delimiter||",").charCodeAt(0),u=34;var n=e?.parseValue||g,t=[];let f=0;var a,c=function(){const t=[];s((e,n)=>{t.push(o?String(e):"Field "+n)},y),o||(f=0);return t}();const l=e?.fields?function(e,n){var t,r=[];for(t of n){var o=void 0!==t.index?t.index:e.indexOf(t.name);if(-1===o)throw new Error(`Field "${t.name}" not found in the csv data`);if(r[o])throw new Error("Duplicate field for index "+o);r[o]=t}return r}(c,Array.isArray(e?.fields)?e?.fields:e?.fields(c)):(a=!1!==e?.nested,c.map(t=>{const r=p(t),o=r[0];return{name:t,setValue:0!==r.length&&a?1===r.length?(e,n)=>e[o]=n:(e,n)=>d(e,r,n):(e,n)=>e[t]=n}}));for(;f<r.length;){const h={};s((e,n)=>{l[n]?.setValue(h,e)},n),t.push(h)}return t;function s(e,n){let t=0;for(;f<r.length&&!v(r,f);)e(function(e){var n=f;if(r.charCodeAt(f)===u){do{for(f++;r.charCodeAt(f)===u&&r.charCodeAt(f+1)===u;)f+=2}while(f<r.length&&r.charCodeAt(f)!==u);if(r.charCodeAt(f)!==u)throw new Error('Unexpected end: end quote " missing');f++}else for(;f<r.length&&r.charCodeAt(f)!==i&&!v(r,f);)f++;return e(r.substring(n,f))}(n),t),t++,r.charCodeAt(f)===i&&f++;A(r,f)?f++:b(r,f)&&(f+=2)}},e.getIn=r,e.isObject=c,e.isObjectOrArray=function(e){return c(e)||Array.isArray(e)},e.json2csv=function(n,e){var t=!1!==e?.header;const r=m(e?.delimiter||",");var o=function(e){if(v(e,0))return e;throw new Error('Invalid EOL character: choose "\\n" or "\\r\\n"')}(e?.eol||"\r\n"),i="function"==typeof e?.flatten?e?.flatten:!1===e?.flatten?()=>!1:c;const u=e?.fields?Array.isArray(e?.fields)?e?.fields:e?.fields(n):l(n,i),f=e?.formatValue||s(r);let a="";t&&(a+=u.map(e=>f(e.name)).join(r)+o);for(let e=0;e<n.length;e++)a+=function(n){return u.map(e=>f(e.getValue(n))).join(r)}(n[e])+o;return a},e.parsePath=p,e.parseValue=g,e.setIn=d,e.stringifyPath=t,e.unescapeValue=y}); |
{ | ||
"name": "csv42", | ||
"version": "3.0.2", | ||
"version": "3.0.3", | ||
"description": "A small and fast CSV parser with support for nested JSON", | ||
@@ -5,0 +5,0 @@ "repository": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
190415
1476