Socket
Socket
Sign inDemoInstall

csv42

Package Overview
Dependencies
0
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.0.0 to 3.0.0

2

lib/cjs/csv2json.js

@@ -13,3 +13,3 @@ "use strict";

var delimiter = (0, _validate.validateDelimiter)((options === null || options === void 0 ? void 0 : options.delimiter) || ',').charCodeAt(0);
var quote = '"'.charCodeAt(0);
var quote = 0x22; // char code of "
var parse = (options === null || options === void 0 ? void 0 : options.parseValue) || _value.parseValue;

@@ -16,0 +16,0 @@ var json = [];

@@ -15,4 +15,4 @@ "use strict";

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function collectFields(records, flatten, flattenArray) {
return collectNestedPaths(records, flatten, flattenArray).map(function (path) {
function collectFields(records, flatten) {
return collectNestedPaths(records, flatten).map(function (path) {
return {

@@ -76,9 +76,6 @@ name: (0, _path.stringifyPath)(path),

var leaf = Symbol();
function collectNestedPaths(array, flatten, flattenArray) {
var recurse = flatten ? flattenArray ? _object.isObjectOrArray : _object.isObject : function () {
return false;
};
function collectNestedPaths(array, recurse) {
var merged = {};
array.forEach(function (item) {
if ((0, _object.isObjectOrArray)(item)) {
if (recurse(item) || (0, _object.isObject)(item)) {
_mergeObject(item, merged, recurse);

@@ -98,8 +95,8 @@ } else {

for (var key in object) {
var _value = object[key];
var valueMerged = merged[key] || (merged[key] = Array.isArray(_value) ? [] : {});
if (recurse(_value)) {
_mergeObject(_value, valueMerged, recurse);
var value = object[key];
var valueMerged = merged[key] || (merged[key] = Array.isArray(value) ? [] : {});
if (recurse(value)) {
_mergeObject(value, valueMerged, recurse);
} else {
_mergeValue(_value, valueMerged);
_mergeValue(value, valueMerged);
}

@@ -126,3 +123,3 @@ }

});
} else if ((0, _object.isObjectOrArray)(object)) {
} else if ((0, _object.isObject)(object)) {
for (var key in object) {

@@ -129,0 +126,0 @@ _collectPaths(object[key], parentPath.concat(key), paths);

@@ -16,3 +16,5 @@ "use strict";

getIn: true,
setIn: true
setIn: true,
isObject: true,
isObjectOrArray: true
};

@@ -43,2 +45,14 @@ Object.defineProperty(exports, "collectNestedPaths", {

});
Object.defineProperty(exports, "isObject", {
enumerable: true,
get: function get() {
return _object.isObject;
}
});
Object.defineProperty(exports, "isObjectOrArray", {
enumerable: true,
get: function get() {
return _object.isObjectOrArray;
}
});
Object.defineProperty(exports, "json2csv", {

@@ -45,0 +59,0 @@ enumerable: true,

@@ -10,2 +10,3 @@ "use strict";

var _validate = require("./validate.js");
var _object = require("./object.js");
function json2csv(json, options) {

@@ -15,3 +16,6 @@ var header = (options === null || options === void 0 ? void 0 : options.header) !== false; // true when not specified

var eol = (0, _validate.validateEOL)((options === null || options === void 0 ? void 0 : options.eol) || '\r\n');
var fields = options !== null && options !== void 0 && options.fields ? Array.isArray(options === null || options === void 0 ? void 0 : options.fields) ? options === null || options === void 0 ? void 0 : options.fields : options === null || options === void 0 ? void 0 : options.fields(json) : (0, _fields.collectFields)(json, (options === null || options === void 0 ? void 0 : options.flatten) !== false, (options === null || options === void 0 ? void 0 : options.flattenArray) === true);
var flatten = typeof (options === null || options === void 0 ? void 0 : options.flatten) === 'function' ? options === null || options === void 0 ? void 0 : options.flatten : (options === null || options === void 0 ? void 0 : options.flatten) === false ? function () {
return false;
} : _object.isObject; // options?.flatten is true or undefined
var fields = options !== null && options !== void 0 && options.fields ? Array.isArray(options === null || options === void 0 ? void 0 : options.fields) ? options === null || options === void 0 ? void 0 : options.fields : options === null || options === void 0 ? void 0 : options.fields(json) : (0, _fields.collectFields)(json, flatten);
var formatValue = (options === null || options === void 0 ? void 0 : options.formatValue) || (0, _value.createFormatValue)(delimiter);

@@ -18,0 +22,0 @@ var output = '';

@@ -40,8 +40,9 @@ "use strict";

}
function isObjectOrArray(value) {
return _typeof(value) === 'object' && value !== null;
}
function isObject(value) {
return _typeof(value) === 'object' && value !== null && value.constructor === Object; // do not match on classes or Array
}
function isObjectOrArray(value) {
return isObject(value) || Array.isArray(value);
}
//# sourceMappingURL=object.js.map

@@ -13,5 +13,6 @@ "use strict";

var controlCharactersRegex = new RegExp('[' + delimiter + '"\r\n]');
var quoteRegex = /"/g;
function formatString(value) {
var needToEscape = controlCharactersRegex.test(value) || value.length === 0;
return needToEscape ? '"' + value.replaceAll('"', '""') + '"' : value;
return needToEscape ? "\"".concat(value.replaceAll(quoteRegex, '""'), "\"") : value;
}

@@ -23,3 +24,3 @@ return function formatValue(value) {

if (typeof value === 'number' || typeof value === 'boolean') {
return String(value);
return value + '';
}

@@ -35,3 +36,3 @@ if (value === undefined || value === null) {

function parseValue(value) {
if (value === '') {
if (value.length === 0) {
return null;

@@ -41,9 +42,10 @@ }

}
var escapedQuoteRegex = /""/g;
function unescapeValue(value) {
return value[0] === '"' ? value.substring(1, value.length - 1).replaceAll('""', '"') : value;
return value[0] === '"' ? value.substring(1, value.length - 1).replaceAll(escapedQuoteRegex, '"') : value;
}
function parseUnescapedValue(value) {
var number = Number(value);
if (!isNaN(number) && !isNaN(parseFloat(value))) {
return number;
if (value[0] >= '0' && value[0] <= '9') {
var number = Number(value);
return !isNaN(number) ? number : value;
}

@@ -50,0 +52,0 @@ if (value === 'true') {

@@ -7,3 +7,3 @@ import { parseValue, unescapeValue } from './value.js';

const delimiter = validateDelimiter(options?.delimiter || ',').charCodeAt(0);
const quote = '"'.charCodeAt(0);
const quote = 0x22; // char code of "
const parse = options?.parseValue || parseValue;

@@ -10,0 +10,0 @@ const json = [];

@@ -1,5 +0,5 @@

import { getIn, isObject, isObjectOrArray, setIn } from './object.js';
import { getIn, isObject, setIn } from './object.js';
import { parsePath, stringifyPath } from './path.js';
export function collectFields(records, flatten, flattenArray) {
return collectNestedPaths(records, flatten, flattenArray).map(path => ({
export function collectFields(records, flatten) {
return collectNestedPaths(records, flatten).map(path => ({
name: stringifyPath(path),

@@ -46,7 +46,6 @@ getValue: createGetValue(path)

const leaf = Symbol();
export function collectNestedPaths(array, flatten, flattenArray) {
const recurse = flatten ? flattenArray ? isObjectOrArray : isObject : () => false;
export function collectNestedPaths(array, recurse) {
const merged = {};
array.forEach(item => {
if (isObjectOrArray(item)) {
if (recurse(item) || isObject(item)) {
_mergeObject(item, merged, recurse);

@@ -91,3 +90,3 @@ } else {

object.forEach((item, index) => _collectPaths(item, parentPath.concat(index), paths));
} else if (isObjectOrArray(object)) {
} else if (isObject(object)) {
for (const key in object) {

@@ -94,0 +93,0 @@ _collectPaths(object[key], parentPath.concat(key), paths);

@@ -6,4 +6,4 @@ export { json2csv } from './json2csv.js';

export { parsePath, stringifyPath } from './path.js';
export { getIn, setIn } from './object.js';
export { getIn, setIn, isObject, isObjectOrArray } from './object.js';
export * from './types.js';
//# sourceMappingURL=index.js.map
import { collectFields } from './fields.js';
import { createFormatValue } from './value.js';
import { validateDelimiter, validateEOL } from './validate.js';
import { isObject } from './object.js';
export function json2csv(json, options) {

@@ -8,3 +9,4 @@ const header = options?.header !== false; // true when not specified

const eol = validateEOL(options?.eol || '\r\n');
const fields = options?.fields ? Array.isArray(options?.fields) ? options?.fields : options?.fields(json) : collectFields(json, options?.flatten !== false, options?.flattenArray === true);
const flatten = typeof options?.flatten === 'function' ? options?.flatten : options?.flatten === false ? () => false : isObject; // options?.flatten is true or undefined
const fields = options?.fields ? Array.isArray(options?.fields) ? options?.fields : options?.fields(json) : collectFields(json, flatten);
const formatValue = options?.formatValue || createFormatValue(delimiter);

@@ -11,0 +13,0 @@ let output = '';

@@ -29,8 +29,9 @@ export function getIn(object, path) {

}
export function isObjectOrArray(value) {
return typeof value === 'object' && value !== null;
}
export function isObject(value) {
return typeof value === 'object' && value !== null && value.constructor === Object; // do not match on classes or Array
}
export function isObjectOrArray(value) {
return isObject(value) || Array.isArray(value);
}
//# sourceMappingURL=object.js.map

@@ -5,5 +5,6 @@ export function createFormatValue(delimiter) {

const controlCharactersRegex = new RegExp('[' + delimiter + '"\r\n]');
const quoteRegex = /"/g;
function formatString(value) {
const needToEscape = controlCharactersRegex.test(value) || value.length === 0;
return needToEscape ? '"' + value.replaceAll('"', '""') + '"' : value;
return needToEscape ? `"${value.replaceAll(quoteRegex, '""')}"` : value;
}

@@ -15,3 +16,3 @@ return function formatValue(value) {

if (typeof value === 'number' || typeof value === 'boolean') {
return String(value);
return value + '';
}

@@ -27,3 +28,3 @@ if (value === undefined || value === null) {

export function parseValue(value) {
if (value === '') {
if (value.length === 0) {
return null;

@@ -33,9 +34,10 @@ }

}
const escapedQuoteRegex = /""/g;
export function unescapeValue(value) {
return value[0] === '"' ? value.substring(1, value.length - 1).replaceAll('""', '"') : value;
return value[0] === '"' ? value.substring(1, value.length - 1).replaceAll(escapedQuoteRegex, '"') : value;
}
function parseUnescapedValue(value) {
const number = Number(value);
if (!isNaN(number) && !isNaN(parseFloat(value))) {
return number;
if (value[0] >= '0' && value[0] <= '9') {
const number = Number(value);
return !isNaN(number) ? number : value;
}

@@ -42,0 +44,0 @@ if (value === 'true') {

@@ -1,3 +0,3 @@

import { CsvField, JsonField, NestedObject, Path } from './types.js';
export declare function collectFields(records: NestedObject[], flatten: boolean, flattenArray: boolean): CsvField[];
import { CsvField, FlattenCallback, JsonField, NestedObject, Path } from './types.js';
export declare function collectFields(records: NestedObject[], flatten: FlattenCallback): CsvField[];
export declare function toFields(names: string[], nested: boolean): JsonField[];

@@ -12,3 +12,3 @@ /**

export declare function mapFields(fieldNames: string[], fields: JsonField[]): (JsonField | undefined)[];
export declare function collectNestedPaths(array: NestedObject[], flatten: boolean, flattenArray: boolean): Path[];
export declare function collectNestedPaths(array: NestedObject[], recurse: FlattenCallback): Path[];
//# sourceMappingURL=fields.d.ts.map

@@ -6,4 +6,4 @@ export { json2csv } from './json2csv.js';

export { parsePath, stringifyPath } from './path.js';
export { getIn, setIn } from './object.js';
export { getIn, setIn, isObject, isObjectOrArray } from './object.js';
export * from './types.js';
//# sourceMappingURL=index.d.ts.map
import { NestedObject, Path } from './types';
export declare function getIn(object: NestedObject, path: Path): unknown;
export declare function setIn(object: NestedObject, path: Path, value: unknown): NestedObject;
export declare function isObject(value: unknown): boolean;
export declare function isObjectOrArray(value: unknown): boolean;
export declare function isObject(value: unknown): boolean;
//# sourceMappingURL=object.d.ts.map

@@ -7,2 +7,3 @@ export type Path = (string | number)[];

export type ValueParser = (value: string) => unknown;
export type FlattenCallback = (value: unknown) => boolean;
export interface CsvField {

@@ -27,4 +28,3 @@ name: string;

eol?: '\r\n' | '\n';
flatten?: boolean;
flattenArray?: boolean;
flatten?: boolean | FlattenCallback;
fields?: CsvField[] | CsvFieldsParser;

@@ -31,0 +31,0 @@ formatValue?: ValueFormatter;

@@ -35,5 +35,2 @@ (function (global, factory) {

}
function isObjectOrArray(value) {
return typeof value === 'object' && value !== null;
}
function isObject(value) {

@@ -43,2 +40,6 @@ return typeof value === 'object' && value !== null && value.constructor === Object; // do not match on classes or Array

function isObjectOrArray(value) {
return isObject(value) || Array.isArray(value);
}
/**

@@ -97,4 +98,4 @@ * Stringify an array with a path in a JSON path like 'items[3].name'

function collectFields(records, flatten, flattenArray) {
return collectNestedPaths(records, flatten, flattenArray).map(path => ({
function collectFields(records, flatten) {
return collectNestedPaths(records, flatten).map(path => ({
name: stringifyPath(path),

@@ -141,7 +142,6 @@ getValue: createGetValue(path)

const leaf = Symbol();
function collectNestedPaths(array, flatten, flattenArray) {
const recurse = flatten ? flattenArray ? isObjectOrArray : isObject : () => false;
function collectNestedPaths(array, recurse) {
const merged = {};
array.forEach(item => {
if (isObjectOrArray(item)) {
if (recurse(item) || isObject(item)) {
_mergeObject(item, merged, recurse);

@@ -186,3 +186,3 @@ } else {

object.forEach((item, index) => _collectPaths(item, parentPath.concat(index), paths));
} else if (isObjectOrArray(object)) {
} else if (isObject(object)) {
for (const key in object) {

@@ -213,5 +213,6 @@ _collectPaths(object[key], parentPath.concat(key), paths);

const controlCharactersRegex = new RegExp('[' + delimiter + '"\r\n]');
const quoteRegex = /"/g;
function formatString(value) {
const needToEscape = controlCharactersRegex.test(value) || value.length === 0;
return needToEscape ? '"' + value.replaceAll('"', '""') + '"' : value;
return needToEscape ? `"${value.replaceAll(quoteRegex, '""')}"` : value;
}

@@ -223,3 +224,3 @@ return function formatValue(value) {

if (typeof value === 'number' || typeof value === 'boolean') {
return String(value);
return value + '';
}

@@ -235,3 +236,3 @@ if (value === undefined || value === null) {

function parseValue(value) {
if (value === '') {
if (value.length === 0) {
return null;

@@ -241,9 +242,10 @@ }

}
const escapedQuoteRegex = /""/g;
function unescapeValue(value) {
return value[0] === '"' ? value.substring(1, value.length - 1).replaceAll('""', '"') : value;
return value[0] === '"' ? value.substring(1, value.length - 1).replaceAll(escapedQuoteRegex, '"') : value;
}
function parseUnescapedValue(value) {
const number = Number(value);
if (!isNaN(number) && !isNaN(parseFloat(value))) {
return number;
if (value[0] >= '0' && value[0] <= '9') {
const number = Number(value);
return !isNaN(number) ? number : value;
}

@@ -293,3 +295,4 @@ if (value === 'true') {

const eol = validateEOL(options?.eol || '\r\n');
const fields = options?.fields ? Array.isArray(options?.fields) ? options?.fields : options?.fields(json) : collectFields(json, options?.flatten !== false, options?.flattenArray === true);
const flatten = typeof options?.flatten === 'function' ? options?.flatten : options?.flatten === false ? () => false : isObject; // options?.flatten is true or undefined
const fields = options?.fields ? Array.isArray(options?.fields) ? options?.fields : options?.fields(json) : collectFields(json, flatten);
const formatValue = options?.formatValue || createFormatValue(delimiter);

@@ -315,3 +318,3 @@ let output = '';

const delimiter = validateDelimiter(options?.delimiter || ',').charCodeAt(0);
const quote = '"'.charCodeAt(0);
const quote = 0x22; // char code of "
const parse = options?.parseValue || parseValue;

@@ -392,2 +395,4 @@ const json = [];

exports.getIn = getIn;
exports.isObject = isObject;
exports.isObjectOrArray = isObjectOrArray;
exports.json2csv = json2csv;

@@ -394,0 +399,0 @@ exports.parsePath = parsePath;

@@ -1,1 +0,1 @@

!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 h(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 i(e){return"object"==typeof e&&null!==e}function u(e){return"object"==typeof e&&null!==e&&e.constructor===Object}function o(e){return e.map((e,n)=>"number"==typeof e?"["+e+"]":/[.\[\]]/.test(e)||""===e?'["'+e+'"]':(0<n?".":"")+e).join("")}function p(t){var e,n,r=[];let o=0;for(;o<t.length;)"."===t[o]&&o++,"["===t[o]?(o++,'"'===t[o]?(o++,r.push(i(e=>'"'===e)),u('"')):(e=i(e=>"]"===e),n=Number(e),r.push(isNaN(n)?e:n)),u("]")):r.push(i(e=>"."===e||"["===e));function i(e){for(var n=o;o<t.length&&!e(t[o]);)o++;return t.substring(n,o)}function u(e){if(t[o]!==e)throw new SyntaxError(`Invalid JSON path: ${e} expected at position `+o);o++}return r}function f(e,n,t){return l(e,n,t).map(e=>({name:o(e),getValue:function(n){if(1!==n.length)return e=>r(e,n);{const t=n[0];return e=>e[t]}}(e)}))}const a=Symbol();function l(e,n,t){const r=n?t?i:u:()=>!1,o={};e.forEach(e=>{i(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):c(i,u)}}(e,o,r):c(e,o)});n=[];return function t(e,r,o){if(!0===e[a]||null===e[a]&&s(e))o.push(r);else if(Array.isArray(e))e.forEach((e,n)=>t(e,r.concat(n),o));else if(i(e))for(const n in e)t(e[n],r.concat(n),o)}(o,[],n),n}function c(e,n){void 0===n[a]&&(n[a]=null!=e||null)}function s(e){return 0===Object.keys(e).length}function d(e){const r=new RegExp("["+e+'"\r\n]');return function e(n){var t;return"string"==typeof n?(t=n,r.test(t)||0===t.length?'"'+t.replaceAll('"','""')+'"':t):"number"==typeof n||"boolean"==typeof n?String(n):null==n?"":e(JSON.stringify(n))}}function g(e){return""===e?null:(e=m(e),n=Number(e),isNaN(n)||isNaN(parseFloat(e))?"true"===e||"false"!==e&&("null"!==e?"{"!==e[0]&&"["!==e[0]?e:JSON.parse(e):null):n);var n}function m(e){return'"'===e[0]?e.substring(1,e.length-1).replaceAll('""','"'):e}function y(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)===t}function b(e,n){return e.charCodeAt(n)===w&&e.charCodeAt(n+1)===t}const t=10,w=13;e.collectNestedPaths=l,e.createFormatValue=d,e.csv2json=function(r,e){const o=!1!==e?.header,i=y(e?.delimiter||",").charCodeAt(0),u='"'.charCodeAt(0);var n=e?.parseValue||g,t=[];let a=0;var f,l=function(){const t=[];s((e,n)=>{t.push(o?String(e):"Field "+n)},m),o||(a=0);return t}();const c=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}(l,Array.isArray(e?.fields)?e?.fields:e?.fields(l)):(f=!1!==e?.nested,l.map(t=>{const r=p(t),o=r[0];return{name:t,setValue:0!==r.length&&f?1===r.length?(e,n)=>e[o]=n:(e,n)=>h(e,r,n):(e,n)=>e[t]=n}}));for(;a<r.length;){const d={};s((e,n)=>{c[n]?.setValue(d,e)},n),t.push(d)}return t;function s(e,n){let t=0;for(;a<r.length&&!v(r,a);)e(function(e){var n=a;if(r.charCodeAt(a)===u){do{for(a++;r.charCodeAt(a)===u&&r.charCodeAt(a+1)===u;)a+=2}while(a<r.length&&r.charCodeAt(a)!==u);if(r.charCodeAt(a)!==u)throw new Error('Unexpected end: end quote " missing');a++}else for(;a<r.length&&r.charCodeAt(a)!==i&&!v(r,a);)a++;return e(r.substring(n,a))}(n),t),t++,r.charCodeAt(a)===i&&a++;A(r,a)?a++:b(r,a)&&(a+=2)}},e.getIn=r,e.json2csv=function(n,e){var t=!1!==e?.header;const r=y(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");const i=e?.fields?Array.isArray(e?.fields)?e?.fields:e?.fields(n):f(n,!1!==e?.flatten,!0===e?.flattenArray),u=e?.formatValue||d(r);let a="";t&&(a+=i.map(e=>u(e.name)).join(r)+o);for(let e=0;e<n.length;e++)a+=function(n){return i.map(e=>u(e.getValue(n))).join(r)}(n[e])+o;return a},e.parsePath=p,e.parseValue=g,e.setIn=h,e.stringifyPath=o,e.unescapeValue=m});
!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 h(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):a(i,u)}}(n,t,e):a(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 a(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){var e;return 0===n.length?null:"0"<=(n=y(n))[0]&&n[0]<="9"?(e=Number(n),isNaN(e)?n:e):"true"===n||"false"!==n&&("null"!==n?"{"!==n[0]&&"["!==n[0]?n:JSON.parse(n):null)}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)===f}function b(n,e){return n.charCodeAt(e)===d&&n.charCodeAt(e+1)===f}const f=10,d=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 a=0;var f,c=function(){const t=[];s((n,e)=>{t.push(o?String(n):"Field "+e)},y),o||(a=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)):(f=!1!==n?.nested,c.map(t=>{const r=p(t),o=r[0];return{name:t,setValue:0!==r.length&&f?1===r.length?(n,e)=>n[o]=e:(n,e)=>h(n,r,e):(n,e)=>n[t]=e}}));for(;a<r.length;){const d={};s((n,e)=>{l[e]?.setValue(d,n)},e),t.push(d)}return t;function s(n,e){let t=0;for(;a<r.length&&!v(r,a);)n(function(n){var e=a;if(r.charCodeAt(a)===u){do{for(a++;r.charCodeAt(a)===u&&r.charCodeAt(a+1)===u;)a+=2}while(a<r.length&&r.charCodeAt(a)!==u);if(r.charCodeAt(a)!==u)throw new Error('Unexpected end: end quote " missing');a++}else for(;a<r.length&&r.charCodeAt(a)!==i&&!v(r,a);)a++;return n(r.substring(e,a))}(e),t),t++,r.charCodeAt(a)===i&&a++;A(r,a)?a++:b(r,a)&&(a+=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),a=n?.formatValue||s(r);let f="";t&&(f+=u.map(n=>a(n.name)).join(r)+o);for(let n=0;n<e.length;n++)f+=function(e){return u.map(n=>a(n.getValue(e))).join(r)}(e[n])+o;return f},n.parsePath=p,n.parseValue=g,n.setIn=h,n.stringifyPath=t,n.unescapeValue=y});
{
"name": "csv42",
"version": "2.0.0",
"version": "3.0.0",
"description": "A small and fast CSV parser with support for nested JSON",

@@ -70,3 +70,3 @@ "repository": {

"@commitlint/config-conventional": "17.4.4",
"@vitest/coverage-c8": "0.28.5",
"@vitest/coverage-c8": "0.29.2",
"cpy-cli": "4.2.0",

@@ -81,4 +81,4 @@ "csv-spectrum": "1.0.0",

"uglify-js": "3.17.4",
"vite": "4.1.3",
"vitest": "0.28.5"
"vite": "4.1.4",
"vitest": "0.29.2"
},

@@ -85,0 +85,0 @@ "files": [

@@ -128,11 +128,10 @@ # csv42

| Option | Type | Description |
| -------------- | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `header` | `boolean` | If true, a header will be created as first line of the CSV. |
| `delimiter` | `string` | Default delimiter is `,`. A delimiter must be a single character. |
| `eol` | `\r\n` or `\n` | End of line, can be `\r\n` (default) or `\n`. |
| `flatten` | `boolean` | If `true` (default), nested objects will be flattened in multiple CSV columns. When `false`, nested objects will be serialized as JSON in a single CSV field. See also option `flattenArray`. The option `flatten` is not applicable when `fields` is defined. |
| `flattenArray` | `boolean` | If `true`, each item in a nested array will be expanded in a separate column. When `false` (default), arrays will be serialized into a single column. Only applicable when `flatten` is `true`. |
| `fields` | `CsvField[]` or `CsvFieldsParser` | A list with fields to be put into the CSV file. This allows specifying the order of the fields and which fields to include/excluded. |
| `formatValue` | `ValueFormatter` | Function used to change any type of value into a serialized string for the CSV. The build in formatter will only enclose values in quotes when necessary, and will stringify nested JSON objects. |
| Option | Type | Description |
| ------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `header` | `boolean` | If true, a header will be created as first line of the CSV. |
| `delimiter` | `string` | Default delimiter is `,`. A delimiter must be a single character. |
| `eol` | `\r\n` or `\n` | End of line, can be `\r\n` (default) or `\n`. |
| `flatten` | `boolean` or `(value: unknown) => boolean` | If `true` (default), plain, nested objects will be flattened in multiple CSV columns, and arrays and classes will be serialized in a single field. When `false`, nested objects will be serialized as JSON in a single CSV field. This behavior can be customized by providing your own callback function for `flatten`. For example, to flatten objects and arrays, you can use `json2csv(json, { flatten: isObjectOrArray })`, and to flatten a specific class, you can use `json2csv(json, { flatten: value => isObject(value) \|\| isCustomClass(value) })`. The option `flatten`is not applicable when`fields` is defined. |
| `fields` | `CsvField[]` or `CsvFieldsParser` | A list with fields to be put into the CSV file. This allows specifying the order of the fields and which fields to include/excluded. |
| `formatValue` | `ValueFormatter` | Function used to change any type of value into a serialized string for the CSV. The build in formatter will only enclose values in quotes when necessary, and will stringify nested JSON objects. |

@@ -171,12 +170,14 @@ A simple example of a `ValueFormatter` is the following. This formatter will enclose every value in quotes:

| Function | Description |
| ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `createFormatValue(delimiter: string): (value: unknown) => string` | Create a function that can format (stringify) a value into a valid CSV value, escaping the value when needed. This function is used as default for the option `formatValue`. |
| `parseValue(value: string): unknown` | Parse a string into a value, parse numbers into a number, etc. This is the function used by default for the option `parseValue`. |
| `unescapeValue(value: string) : string` | Unescape an escaped value like `"hello ""Joe"""` into the string `hello "Joe"`. |
| `collectNestedPaths(records: NestedObject[], recurse: boolean): Path[]` | Loop over the data and collect all nested paths. This can be used to generate a list with fields. |
| `parsePath(pathStr: string): Path` | Parse a path like `'items[3].name'` |
| `stringifyPath(path: Path): string` | Stringify a path into a string like `'items[3].name'` |
| `getIn(object: NestedObject, path: Path): unknown` | Get a nested property from an object |
| `setIn(object: NestedObject, path: Path, value: unknown): NestedObject` | Set a nested property in an object |
| Function | Description |
| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `createFormatValue(delimiter: string): (value: unknown) => string` | Create a function that can format (stringify) a value into a valid CSV value, escaping the value when needed. This function is used as default for the option `formatValue`. |
| `parseValue(value: string): unknown` | Parse a string into a value, parse numbers into a number, etc. This is the function used by default for the option `parseValue`. |
| `unescapeValue(value: string) : string` | Unescape an escaped value like `"hello ""Joe"""` into the string `hello "Joe"`. |
| `collectNestedPaths(records: NestedObject[], recurse: boolean): Path[]` | Loop over the data and collect all nested paths. This can be used to generate a list with fields. |
| `parsePath(pathStr: string): Path` | Parse a path like `'items[3].name'` |
| `stringifyPath(path: Path): string` | Stringify a path into a string like `'items[3].name'` |
| `getIn(object: NestedObject, path: Path): unknown` | Get a nested property from an object |
| `setIn(object: NestedObject, path: Path, value: unknown): NestedObject` | Set a nested property in an object |
| `isObject(value: unknown): boolean` | Returns true when `value` is a plain JavaScript object, and returns false for primitive values, arrays, and classes. Can be used as callback function for the option `flatten`. |
| `isObjectOrArray(value: unknown): boolean` | Returns true when `value` is a plain JavaScript object or array, and returns false for primitive values and classes. Can be used as callback function for the option `flatten`. |

@@ -183,0 +184,0 @@ ## Alternatives

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

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

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

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

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc