@ztimson/utils 0.23.14 → 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/index.mjs CHANGED
@@ -539,6 +539,14 @@ const LETTER_LIST = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
539
539
  const NUMBER_LIST = "0123456789";
540
540
  const SYMBOL_LIST = "~`!@#$%^&*()_-+={[}]|\\:;\"'<,>.?/";
541
541
  const CHAR_LIST = LETTER_LIST + LETTER_LIST.toLowerCase() + NUMBER_LIST + SYMBOL_LIST;
542
+ function camelCase(text) {
543
+ if (!text) return "";
544
+ text = text.replaceAll(/^[0-9]+/g, "").replaceAll(/[^a-zA-Z0-9]+(\w?)/g, (...args) => {
545
+ var _a;
546
+ return ((_a = args[1]) == null ? void 0 : _a.toUpperCase()) || "";
547
+ });
548
+ return text[0].toLowerCase() + text.slice(1);
549
+ }
542
550
  function formatBytes(bytes, decimals = 2) {
543
551
  if (bytes === 0) return "0 Bytes";
544
552
  const k = 1024;
@@ -676,24 +684,29 @@ function validateEmail(email) {
676
684
  return /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/.test(email);
677
685
  }
678
686
  function fromCsv(csv, hasHeaders = true) {
679
- const row = csv.split("\n");
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/);
680
707
  let headers = hasHeaders ? row.splice(0, 1)[0] : null;
681
- if (headers) headers = headers.match(/(?:[^,"']+|"[^"]*"|'[^']*')+/g);
708
+ if (headers) headers = headers.match(/(?:[^,"']+|"(?:[^"]|"")*"|'(?:[^']|'')*')+/g);
682
709
  return row.map((r2) => {
683
- function parseLine(line) {
684
- const parts = line.split(","), columns = [];
685
- let quoted = false;
686
- for (const p2 of parts) {
687
- if (quoted) columns[columns.length - 1] = columns.at(-1) + "," + p2;
688
- else columns.push(p2);
689
- if (/[^"]"$/g.test(p2)) {
690
- quoted = false;
691
- } else if (/^"[^"]/g.test(p2)) {
692
- quoted = true;
693
- }
694
- }
695
- return columns;
696
- }
697
710
  const props = parseLine(r2);
698
711
  const h = headers || Array(props.length).fill(null).map((r22, i) => {
699
712
  let letter = "";
@@ -709,12 +722,16 @@ function fromCsv(csv, hasHeaders = true) {
709
722
  });
710
723
  }
711
724
  function toCsv(target, flatten = true) {
712
- const headers = new ASet(target.reduce((acc, row) => [...acc, ...Object.keys(flatten ? flattenObj(row) : row)], []));
725
+ const t = makeArray(target);
726
+ const headers = new ASet(t.reduce((acc, row) => [...acc, ...Object.keys(flatten ? flattenObj(row) : row)], []));
713
727
  return [
714
728
  headers.join(","),
715
- ...target.map((row) => headers.map((h) => {
729
+ ...t.map((row) => headers.map((h) => {
716
730
  const value2 = dotNotation(row, h);
717
- return typeof value2 == "object" && value2 != null ? '"' + JSONSanitize(value2).replaceAll('"', '""') + '"' : value2;
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;
718
735
  }).join(","))
719
736
  ].join("\n");
720
737
  }
@@ -1698,6 +1715,7 @@ export {
1698
1715
  adjustedInterval,
1699
1716
  arrayDiff,
1700
1717
  blackOrWhite,
1718
+ camelCase,
1701
1719
  caseInsensitiveSort,
1702
1720
  clean,
1703
1721
  dec2Frac,