@ztimson/utils 0.23.15 → 0.23.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/csv.d.ts +9 -2
- package/dist/index.cjs +39 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +39 -21
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/csv.d.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse a CSV string into an array of objects
|
|
3
|
+
*
|
|
4
|
+
* @param csv String with CSV
|
|
5
|
+
* @param hasHeaders First line of CSV contains headers
|
|
6
|
+
* @return {T[]} Array of parsed objects
|
|
7
|
+
*/
|
|
1
8
|
export declare function fromCsv<T = any>(csv: string, hasHeaders?: boolean): T[];
|
|
2
9
|
/**
|
|
3
|
-
* Convert an
|
|
10
|
+
* Convert an array of objects to a CSV string
|
|
4
11
|
*
|
|
5
12
|
* @param {any[]} target Array of objects to create CSV from
|
|
6
13
|
* @param {boolean} flatten Should nested object be flattened or treated as values
|
|
7
14
|
* @return {string} CSV string
|
|
8
15
|
*/
|
|
9
|
-
export declare function toCsv(target: any
|
|
16
|
+
export declare function toCsv(target: any, flatten?: boolean): string;
|
package/dist/index.cjs
CHANGED
|
@@ -688,26 +688,40 @@ ${opts.message || this.desc}`;
|
|
|
688
688
|
return /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/.test(email);
|
|
689
689
|
}
|
|
690
690
|
function fromCsv(csv, hasHeaders = true) {
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
const
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
}
|
|
707
|
-
return columns;
|
|
691
|
+
function parseLine(line) {
|
|
692
|
+
const columns = [];
|
|
693
|
+
let current = "", inQuotes2 = false;
|
|
694
|
+
for (let i = 0; i < line.length; i++) {
|
|
695
|
+
const char = line[i];
|
|
696
|
+
const nextChar = line[i + 1];
|
|
697
|
+
if (char === '"') {
|
|
698
|
+
if (inQuotes2 && nextChar === '"') {
|
|
699
|
+
current += '"';
|
|
700
|
+
i++;
|
|
701
|
+
} else inQuotes2 = !inQuotes2;
|
|
702
|
+
} else if (char === "," && !inQuotes2) {
|
|
703
|
+
columns.push(current);
|
|
704
|
+
current = "";
|
|
705
|
+
} else current += char;
|
|
708
706
|
}
|
|
707
|
+
columns.push(current);
|
|
708
|
+
return columns.map((col) => col.replace(/^"|"$/g, "").replace(/""/g, '"'));
|
|
709
|
+
}
|
|
710
|
+
const rows2 = [];
|
|
711
|
+
let currentRow = "", inQuotes = false;
|
|
712
|
+
for (const char of csv) {
|
|
713
|
+
if (char === '"') inQuotes = !inQuotes;
|
|
714
|
+
if (char === "\n" && !inQuotes) {
|
|
715
|
+
rows2.push(currentRow);
|
|
716
|
+
currentRow = "";
|
|
717
|
+
} else currentRow += char;
|
|
718
|
+
}
|
|
719
|
+
if (currentRow) rows2.push(currentRow);
|
|
720
|
+
let headers = hasHeaders ? rows2.splice(0, 1)[0] : null;
|
|
721
|
+
if (headers) headers = headers.match(/(?:[^,"']+|"(?:[^"]|"")*"|'(?:[^']|'')*')+/g);
|
|
722
|
+
return rows2.map((r2) => {
|
|
709
723
|
const props = parseLine(r2);
|
|
710
|
-
const h = headers || Array(props.length).fill(null).map((
|
|
724
|
+
const h = headers || Array(props.length).fill(null).map((_, i) => {
|
|
711
725
|
let letter = "";
|
|
712
726
|
const first = i / 26;
|
|
713
727
|
if (first > 1) letter += LETTER_LIST[Math.floor(first - 1)];
|
|
@@ -721,12 +735,16 @@ ${opts.message || this.desc}`;
|
|
|
721
735
|
});
|
|
722
736
|
}
|
|
723
737
|
function toCsv(target, flatten = true) {
|
|
724
|
-
const
|
|
738
|
+
const t = makeArray(target);
|
|
739
|
+
const headers = new ASet(t.reduce((acc, row) => [...acc, ...Object.keys(flatten ? flattenObj(row) : row)], []));
|
|
725
740
|
return [
|
|
726
741
|
headers.join(","),
|
|
727
|
-
...
|
|
742
|
+
...t.map((row) => headers.map((h) => {
|
|
728
743
|
const value2 = dotNotation(row, h);
|
|
729
|
-
|
|
744
|
+
if (value2 == null) return "";
|
|
745
|
+
if (typeof value2 == "object") return `"${JSONSanitize(value2).replaceAll('"', '""')}"`;
|
|
746
|
+
if (typeof value2 == "string" && /[\n"]/g.test(value2)) return `"${value2.replaceAll('"', '""')}"`;
|
|
747
|
+
return value2;
|
|
730
748
|
}).join(","))
|
|
731
749
|
].join("\n");
|
|
732
750
|
}
|