moderndash 2.1.3 → 2.2.0

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/README.md CHANGED
@@ -63,7 +63,7 @@ npm install moderndash
63
63
 
64
64
  ## 🚀 Performance
65
65
 
66
- ModernDash aims to outperform Lodash and deliver lightning-fast utility functions. Performance is not an afterthought, but a top priority. You can expect ModernDash to match or even exceed the performance of Lodash in most benchmarks, ensuring that your project stays speedy and efficient.
66
+ ModernDash aims to outperform Lodash and deliver lightning-fast utility functions. Performance is not an afterthought, but a top priority. You can expect ModernDash to exceed or at least match the performance of Lodash in most benchmarks, ensuring that your project stays speedy and efficient.
67
67
 
68
68
  **[[ Benchmark Results](https://github.com/Maggi64/moderndash/blob/main/benchmark/RESULTS.md) ]**
69
69
 
@@ -84,4 +84,4 @@ To [type-fest](https://github.com/sindresorhus/type-fest) for providing some val
84
84
 
85
85
  ## 🧰 Contribute
86
86
 
87
- Check the [contribute](https://github.com/Maggi64/moderndash/blob/main/CONTRIBUTE.md) section!
87
+ Check the [contribute](https://github.com/Maggi64/moderndash/blob/main/CONTRIBUTE.md) section!
package/dist/index.cjs CHANGED
@@ -38,6 +38,7 @@ __export(src_exports, {
38
38
  dropWhile: () => dropWhile,
39
39
  escapeHtml: () => escapeHtml,
40
40
  escapeRegExp: () => escapeRegExp,
41
+ flatKeys: () => flatKeys,
41
42
  group: () => group,
42
43
  hash: () => hash,
43
44
  intersection: () => intersection,
@@ -83,8 +84,8 @@ __export(src_exports, {
83
84
  module.exports = __toCommonJS(src_exports);
84
85
 
85
86
  // src/array/chunk.ts
86
- function chunk(array, size) {
87
- const intSize = Math.trunc(size);
87
+ function chunk(array, chunkSize) {
88
+ const intSize = Math.trunc(chunkSize);
88
89
  if (array.length === 0 || intSize < 1) {
89
90
  return [];
90
91
  }
@@ -200,12 +201,10 @@ function intersection(arrayOrCompFn, ...arrays) {
200
201
 
201
202
  // src/array/range.ts
202
203
  function* range(start, end, step = 1) {
203
- if (start > end) {
204
+ if (start > end)
204
205
  throw new Error("The start of the range must be less than or equal to the end.");
205
- }
206
- if (step <= 0) {
206
+ if (step <= 0)
207
207
  throw new Error("The step must be greater than 0.");
208
- }
209
208
  for (let i = start; i <= end; i += step) {
210
209
  yield i;
211
210
  }
@@ -488,6 +487,29 @@ function isPlainObject(value) {
488
487
  return value?.constructor === Object;
489
488
  }
490
489
 
490
+ // src/object/flatKeys.ts
491
+ function flatKeys(obj) {
492
+ const result = {};
493
+ function addToResult(prefix, value) {
494
+ if (isPlainObject(value)) {
495
+ const flatObj = flatKeys(value);
496
+ for (const [flatKey, flatValue] of Object.entries(flatObj)) {
497
+ result[`${prefix}.${flatKey}`] = flatValue;
498
+ }
499
+ } else if (Array.isArray(value)) {
500
+ for (const [index, element] of value.entries()) {
501
+ addToResult(`${prefix}[${index}]`, element);
502
+ }
503
+ } else {
504
+ result[prefix] = value;
505
+ }
506
+ }
507
+ for (const [key, value] of Object.entries(obj)) {
508
+ addToResult(key, value);
509
+ }
510
+ return result;
511
+ }
512
+
491
513
  // src/object/merge.ts
492
514
  function merge(target, ...sources) {
493
515
  const targetCopy = { ...target };
@@ -516,18 +538,28 @@ function omit(object, keysToOmit) {
516
538
  }
517
539
 
518
540
  // src/object/set.ts
541
+ var validPathRegex = /^(?:[^.[\]]+(?:\[\d+])*(?:\.|\[\d+]))+(?:[^.[\]]+(?:\[\d+])*)+$/;
542
+ var pathSplitRegex = /\.|(?=\[)/g;
543
+ var matchBracketsRegex = /[[\]]/g;
519
544
  function set(obj, path, value) {
520
- const pathParts = path.split(/[.[\]]/g).filter((x) => Boolean(x.trim()));
545
+ if (!validPathRegex.test(path))
546
+ throw new Error("Invalid path, look at the examples for the correct format.");
547
+ const pathParts = path.split(pathSplitRegex);
521
548
  let currentObj = obj;
522
549
  for (let index = 0; index < pathParts.length; index++) {
523
- const key = pathParts[index];
550
+ const key = pathParts[index].replace(matchBracketsRegex, "");
524
551
  if (index === pathParts.length - 1) {
525
552
  currentObj[key] = value;
526
553
  break;
527
554
  }
528
- const nextIsNumber = !Number.isNaN(Number.parseInt(pathParts[index + 1]));
529
- if (currentObj[key] === void 0)
530
- currentObj[key] = nextIsNumber ? [] : {};
555
+ const nextElemIn = pathParts[index + 1].startsWith("[") ? "array" : "object";
556
+ if (currentObj[key] === void 0) {
557
+ currentObj[key] = nextElemIn === "array" ? [] : {};
558
+ } else if (nextElemIn === "array" && !Array.isArray(currentObj[key])) {
559
+ currentObj[key] = [];
560
+ } else if (nextElemIn === "object" && !isPlainObject(currentObj[key])) {
561
+ currentObj[key] = {};
562
+ }
531
563
  currentObj = currentObj[key];
532
564
  }
533
565
  return obj;
@@ -684,17 +716,18 @@ async function tryCatch(promise) {
684
716
  }
685
717
 
686
718
  // src/string/splitWords.ts
719
+ var splitWordsRegex = new RegExp(
720
+ "[^\\dA-Za-z]|(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])"
721
+ // lookahead for an uppercase letter followed by a lowercase letter
722
+ );
687
723
  function splitWords(str) {
688
- const regex = new RegExp(
689
- "[^\\dA-Za-z]|(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])"
690
- // lookahead for an uppercase letter followed by a lowercase letter
691
- );
692
- return str.split(regex).filter(Boolean);
724
+ return str.split(splitWordsRegex).filter(Boolean);
693
725
  }
694
726
 
695
727
  // src/string/deburr.ts
728
+ var accentControlRegex = /[\u0300-\u036F]/g;
696
729
  function deburr(str) {
697
- return str.normalize("NFD").replace(/[\u0300-\u036F]/g, "");
730
+ return str.normalize("NFD").replace(accentControlRegex, "");
698
731
  }
699
732
 
700
733
  // src/string/camelCase.ts
@@ -716,20 +749,22 @@ function capitalize(str) {
716
749
  }
717
750
 
718
751
  // src/string/escapeHtml.ts
752
+ var charRegex = /["&'<>]/g;
753
+ var escapeChars = /* @__PURE__ */ new Map([
754
+ ["&", "&amp;"],
755
+ ["<", "&lt;"],
756
+ [">", "&gt;"],
757
+ ["'", "&#39;"],
758
+ ['"', "&quot;"]
759
+ ]);
719
760
  function escapeHtml(str) {
720
- const escapeChars = {
721
- "&": "&amp;",
722
- "<": "&lt;",
723
- ">": "&gt;",
724
- "'": "&#39;",
725
- '"': "&quot;"
726
- };
727
- return str.replace(/["&'<>]/g, (char) => escapeChars[char]);
761
+ return str.replace(charRegex, (char) => escapeChars.get(char));
728
762
  }
729
763
 
730
764
  // src/string/escapeRegExp.ts
765
+ var escapleCharsRegex = /[$()*+.?[\\\]^{|}]/g;
731
766
  function escapeRegExp(str) {
732
- return str.replace(/[$()*+.?[\\\]^{|}]/g, "\\$&");
767
+ return str.replace(escapleCharsRegex, "\\$&");
733
768
  }
734
769
 
735
770
  // src/string/kebabCase.ts
@@ -780,15 +815,16 @@ function titleCase(str) {
780
815
  }
781
816
 
782
817
  // src/string/unescapeHtml.ts
818
+ var htmlEntitiesRegex = /&(?:amp|lt|gt|quot|#39);/g;
819
+ var entityMap = /* @__PURE__ */ new Map([
820
+ ["&amp;", "&"],
821
+ ["&lt;", "<"],
822
+ ["&gt;", ">"],
823
+ ["&quot;", '"'],
824
+ ["&#39;", "'"]
825
+ ]);
783
826
  function unescapeHtml(str) {
784
- const entityMap = {
785
- "&amp;": "&",
786
- "&lt;": "<",
787
- "&gt;": ">",
788
- "&quot;": '"',
789
- "&#39;": "'"
790
- };
791
- return str.replace(/&(?:amp|lt|gt|quot|#(0+)?39);/g, (entity) => entityMap[entity]);
827
+ return str.replace(htmlEntitiesRegex, (entity) => entityMap.get(entity));
792
828
  }
793
829
 
794
830
  // src/validate/isEmpty.ts
@@ -878,6 +914,7 @@ function isUrl(str) {
878
914
  dropWhile,
879
915
  escapeHtml,
880
916
  escapeRegExp,
917
+ flatKeys,
881
918
  group,
882
919
  hash,
883
920
  intersection,