@ztimson/utils 0.23.15 → 0.23.16
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 +28 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +28 -19
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -684,24 +684,29 @@ function validateEmail(email) {
|
|
|
684
684
|
return /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/.test(email);
|
|
685
685
|
}
|
|
686
686
|
function fromCsv(csv, hasHeaders = true) {
|
|
687
|
-
|
|
687
|
+
function parseLine(line) {
|
|
688
|
+
const columns = [];
|
|
689
|
+
let current = "", inQuotes = false;
|
|
690
|
+
for (let i = 0; i < line.length; i++) {
|
|
691
|
+
const char = line[i];
|
|
692
|
+
const nextChar = line[i + 1];
|
|
693
|
+
if (char === '"') {
|
|
694
|
+
if (inQuotes && nextChar === '"') {
|
|
695
|
+
current += '"';
|
|
696
|
+
i++;
|
|
697
|
+
} else inQuotes = !inQuotes;
|
|
698
|
+
} else if (char === "," && !inQuotes) {
|
|
699
|
+
columns.push(current);
|
|
700
|
+
current = "";
|
|
701
|
+
} else current += char;
|
|
702
|
+
}
|
|
703
|
+
columns.push(current);
|
|
704
|
+
return columns.map((col) => col.replace(/^"|"$/g, "").replace(/""/g, '"'));
|
|
705
|
+
}
|
|
706
|
+
const row = csv.split(/\r?\n/);
|
|
688
707
|
let headers = hasHeaders ? row.splice(0, 1)[0] : null;
|
|
689
|
-
if (headers) headers = headers.match(/(?:[^,"']+|"[^"]*"|'[^']*')+/g);
|
|
708
|
+
if (headers) headers = headers.match(/(?:[^,"']+|"(?:[^"]|"")*"|'(?:[^']|'')*')+/g);
|
|
690
709
|
return row.map((r2) => {
|
|
691
|
-
function parseLine(line) {
|
|
692
|
-
const parts = line.split(","), columns = [];
|
|
693
|
-
let quoted = false;
|
|
694
|
-
for (const p2 of parts) {
|
|
695
|
-
if (quoted) columns[columns.length - 1] = columns.at(-1) + "," + p2;
|
|
696
|
-
else columns.push(p2);
|
|
697
|
-
if (/[^"]"$/g.test(p2)) {
|
|
698
|
-
quoted = false;
|
|
699
|
-
} else if (/^"[^"]/g.test(p2)) {
|
|
700
|
-
quoted = true;
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
return columns;
|
|
704
|
-
}
|
|
705
710
|
const props = parseLine(r2);
|
|
706
711
|
const h = headers || Array(props.length).fill(null).map((r22, i) => {
|
|
707
712
|
let letter = "";
|
|
@@ -717,12 +722,16 @@ function fromCsv(csv, hasHeaders = true) {
|
|
|
717
722
|
});
|
|
718
723
|
}
|
|
719
724
|
function toCsv(target, flatten = true) {
|
|
720
|
-
const
|
|
725
|
+
const t = makeArray(target);
|
|
726
|
+
const headers = new ASet(t.reduce((acc, row) => [...acc, ...Object.keys(flatten ? flattenObj(row) : row)], []));
|
|
721
727
|
return [
|
|
722
728
|
headers.join(","),
|
|
723
|
-
...
|
|
729
|
+
...t.map((row) => headers.map((h) => {
|
|
724
730
|
const value2 = dotNotation(row, h);
|
|
725
|
-
|
|
731
|
+
if (value2 == null) return "";
|
|
732
|
+
if (typeof value2 == "object") return `"${JSONSanitize(value2).replaceAll("`", '""')}"`;
|
|
733
|
+
if (typeof value2 == "string" && /[\n"]/g.test(value2)) return `"${value2.replaceAll('"', '""')}"`;
|
|
734
|
+
return value2;
|
|
726
735
|
}).join(","))
|
|
727
736
|
].join("\n");
|
|
728
737
|
}
|