@splendidlabz/utils 1.7.0 → 1.8.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @splendidlabz/utils
2
2
 
3
+ ## 1.8.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Build
8
+
9
+ ## 1.8.0
10
+
11
+ ### Minor Changes
12
+
13
+ - Several updates
14
+
3
15
  ## 1.7.0
4
16
 
5
17
  ### Minor Changes
@@ -30,7 +30,7 @@ module.exports = __toCommonJS(font_size_exports);
30
30
  // src/lib/numbers/index.js
31
31
  function splitUnit(string) {
32
32
  if (typeof string === "number") return [string, null];
33
- const regex = /(-?\d*\.?\d+)([a-z]+)/i;
33
+ const regex = /(-?\d*\.?\d+)\s*([a-z]+)/i;
34
34
  const match = string.match(regex);
35
35
  if (match) return [parseFloat(match[1]), match[2]];
36
36
  return [parseFloat(string), null];
@@ -338,7 +338,7 @@ function nativeMasonrySupport(node) {
338
338
  // src/lib/numbers/index.js
339
339
  function splitUnit(string) {
340
340
  if (typeof string === "number") return [string, null];
341
- const regex = /(-?\d*\.?\d+)([a-z]+)/i;
341
+ const regex = /(-?\d*\.?\d+)\s*([a-z]+)/i;
342
342
  const match = string.match(regex);
343
343
  if (match) return [parseFloat(match[1]), match[2]];
344
344
  return [parseFloat(string), null];
@@ -122,7 +122,7 @@ var MONTHS = [
122
122
  // src/lib/numbers/index.js
123
123
  function splitUnit(string) {
124
124
  if (typeof string === "number") return [string, null];
125
- const regex = /(-?\d*\.?\d+)([a-z]+)/i;
125
+ const regex = /(-?\d*\.?\d+)\s*([a-z]+)/i;
126
126
  const match = string.match(regex);
127
127
  if (match) return [parseFloat(match[1]), match[2]];
128
128
  return [parseFloat(string), null];
@@ -140,10 +140,12 @@ function ms(arg) {
140
140
  if (unit === "hours") return getTimeInMs(value, "hours");
141
141
  if (unit === "m") return getTimeInMs(value, "minutes");
142
142
  if (unit === "min") return getTimeInMs(value, "minutes");
143
+ if (unit === "mins") return getTimeInMs(value, "minutes");
143
144
  if (unit === "minute") return getTimeInMs(value, "minutes");
144
145
  if (unit === "minutes") return getTimeInMs(value, "minutes");
145
146
  if (unit === "s") return getTimeInMs(value, "seconds");
146
147
  if (unit === "sec") return getTimeInMs(value, "seconds");
148
+ if (unit === "secs") return getTimeInMs(value, "seconds");
147
149
  if (unit === "second") return getTimeInMs(value, "seconds");
148
150
  if (unit === "seconds") return getTimeInMs(value, "seconds");
149
151
  return value;
@@ -33,7 +33,7 @@ module.exports = __toCommonJS(time_exports);
33
33
  // src/lib/numbers/index.js
34
34
  function splitUnit(string) {
35
35
  if (typeof string === "number") return [string, null];
36
- const regex = /(-?\d*\.?\d+)([a-z]+)/i;
36
+ const regex = /(-?\d*\.?\d+)\s*([a-z]+)/i;
37
37
  const match = string.match(regex);
38
38
  if (match) return [parseFloat(match[1]), match[2]];
39
39
  return [parseFloat(string), null];
@@ -51,10 +51,12 @@ function ms(arg) {
51
51
  if (unit === "hours") return getTimeInMs(value, "hours");
52
52
  if (unit === "m") return getTimeInMs(value, "minutes");
53
53
  if (unit === "min") return getTimeInMs(value, "minutes");
54
+ if (unit === "mins") return getTimeInMs(value, "minutes");
54
55
  if (unit === "minute") return getTimeInMs(value, "minutes");
55
56
  if (unit === "minutes") return getTimeInMs(value, "minutes");
56
57
  if (unit === "s") return getTimeInMs(value, "seconds");
57
58
  if (unit === "sec") return getTimeInMs(value, "seconds");
59
+ if (unit === "secs") return getTimeInMs(value, "seconds");
58
60
  if (unit === "second") return getTimeInMs(value, "seconds");
59
61
  if (unit === "seconds") return getTimeInMs(value, "seconds");
60
62
  return value;
@@ -35,6 +35,7 @@ __export(lib_exports, {
35
35
  RouteManager: () => RouteManager,
36
36
  camelCaseKeys: () => camelCaseKeys,
37
37
  compose: () => compose,
38
+ concatMix: () => concatMix,
38
39
  createMix: () => createMix,
39
40
  createSSE: () => createSSE,
40
41
  curry: () => curry,
@@ -369,7 +370,7 @@ function toRadians(angle) {
369
370
  // src/lib/numbers/index.js
370
371
  function splitUnit(string) {
371
372
  if (typeof string === "number") return [string, null];
372
- const regex = /(-?\d*\.?\d+)([a-z]+)/i;
373
+ const regex = /(-?\d*\.?\d+)\s*([a-z]+)/i;
373
374
  const match = string.match(regex);
374
375
  if (match) return [parseFloat(match[1]), match[2]];
375
376
  return [parseFloat(string), null];
@@ -387,10 +388,12 @@ function ms(arg) {
387
388
  if (unit === "hours") return getTimeInMs(value, "hours");
388
389
  if (unit === "m") return getTimeInMs(value, "minutes");
389
390
  if (unit === "min") return getTimeInMs(value, "minutes");
391
+ if (unit === "mins") return getTimeInMs(value, "minutes");
390
392
  if (unit === "minute") return getTimeInMs(value, "minutes");
391
393
  if (unit === "minutes") return getTimeInMs(value, "minutes");
392
394
  if (unit === "s") return getTimeInMs(value, "seconds");
393
395
  if (unit === "sec") return getTimeInMs(value, "seconds");
396
+ if (unit === "secs") return getTimeInMs(value, "seconds");
394
397
  if (unit === "second") return getTimeInMs(value, "seconds");
395
398
  if (unit === "seconds") return getTimeInMs(value, "seconds");
396
399
  return value;
@@ -720,8 +723,9 @@ function notEqual(a, b) {
720
723
  }
721
724
 
722
725
  // src/lib/objects/mix/mix.js
723
- var DEFAULT_OPTIONS = { array: "concat" };
726
+ var DEFAULT_OPTIONS = { array: "replace" };
724
727
  var mix = createMix();
728
+ var concatMix = createMix({ array: "concat" });
725
729
  function createMix(userOptions = {}) {
726
730
  const options = { ...DEFAULT_OPTIONS, ...userOptions };
727
731
  function _mix(...sources) {
@@ -1061,6 +1065,7 @@ function getSymbolValue(object, description) {
1061
1065
  RouteManager,
1062
1066
  camelCaseKeys,
1063
1067
  compose,
1068
+ concatMix,
1064
1069
  createMix,
1065
1070
  createSSE,
1066
1071
  curry,
@@ -36,7 +36,7 @@ function toRadians(angle) {
36
36
  // src/lib/numbers/index.js
37
37
  function splitUnit(string) {
38
38
  if (typeof string === "number") return [string, null];
39
- const regex = /(-?\d*\.?\d+)([a-z]+)/i;
39
+ const regex = /(-?\d*\.?\d+)\s*([a-z]+)/i;
40
40
  const match = string.match(regex);
41
41
  if (match) return [parseFloat(match[1]), match[2]];
42
42
  return [parseFloat(string), null];
@@ -49,8 +49,9 @@ function curry(fn) {
49
49
  }
50
50
 
51
51
  // src/lib/objects/mix/mix.js
52
- var DEFAULT_OPTIONS = { array: "concat" };
52
+ var DEFAULT_OPTIONS = { array: "replace" };
53
53
  var mix = createMix();
54
+ var concatMix = createMix({ array: "concat" });
54
55
  function createMix(userOptions = {}) {
55
56
  const options = { ...DEFAULT_OPTIONS, ...userOptions };
56
57
  function _mix(...sources) {
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  var objects_exports = {};
31
31
  __export(objects_exports, {
32
32
  camelCaseKeys: () => camelCaseKeys,
33
+ concatMix: () => concatMix,
33
34
  createMix: () => createMix,
34
35
  extendObject: () => extendObject,
35
36
  flattenObject: () => flattenObject,
@@ -147,8 +148,9 @@ function pipe(...fns) {
147
148
  }
148
149
 
149
150
  // src/lib/objects/mix/mix.js
150
- var DEFAULT_OPTIONS = { array: "concat" };
151
+ var DEFAULT_OPTIONS = { array: "replace" };
151
152
  var mix = createMix();
153
+ var concatMix = createMix({ array: "concat" });
152
154
  function createMix(userOptions = {}) {
153
155
  const options = { ...DEFAULT_OPTIONS, ...userOptions };
154
156
  function _mix(...sources) {
@@ -354,6 +356,7 @@ function splitObject(obj, keys) {
354
356
  // Annotate the CommonJS export names for ESM import in node:
355
357
  0 && (module.exports = {
356
358
  camelCaseKeys,
359
+ concatMix,
357
360
  createMix,
358
361
  extendObject,
359
362
  flattenObject,
@@ -19,12 +19,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  // src/lib/objects/mix/mix.js
20
20
  var mix_exports = {};
21
21
  __export(mix_exports, {
22
+ concatMix: () => concatMix,
22
23
  createMix: () => createMix,
23
24
  mix: () => mix
24
25
  });
25
26
  module.exports = __toCommonJS(mix_exports);
26
- var DEFAULT_OPTIONS = { array: "concat" };
27
+ var DEFAULT_OPTIONS = { array: "replace" };
27
28
  var mix = createMix();
29
+ var concatMix = createMix({ array: "concat" });
28
30
  function createMix(userOptions = {}) {
29
31
  const options = { ...DEFAULT_OPTIONS, ...userOptions };
30
32
  function _mix(...sources) {
@@ -107,6 +109,7 @@ function objectType(value) {
107
109
  }
108
110
  // Annotate the CommonJS export names for ESM import in node:
109
111
  0 && (module.exports = {
112
+ concatMix,
110
113
  createMix,
111
114
  mix
112
115
  });
@@ -37,7 +37,7 @@ __export(file_cache_exports, {
37
37
  });
38
38
  module.exports = __toCommonJS(file_cache_exports);
39
39
  var import_promises = __toESM(require("fs/promises"), 1);
40
- var import_glob_promise = __toESM(require("glob-promise"), 1);
40
+ var import_glob = require("glob");
41
41
  var import_node_path = __toESM(require("path"), 1);
42
42
 
43
43
  // src/lib/objects/nested-property.js
@@ -164,11 +164,11 @@ async function fileCache({ dir, file }) {
164
164
  async function getLastModifiedTime(globPath) {
165
165
  let files;
166
166
  if (typeof globPath === "string") {
167
- files = await (0, import_glob_promise.default)(removeFirstSlash(globPath));
167
+ files = await (0, import_glob.glob)(removeFirstSlash(globPath));
168
168
  }
169
169
  if (Array.isArray(globPath)) {
170
170
  const a = await Promise.all(
171
- globPath.map((path2) => (0, import_glob_promise.default)(removeFirstSlash(path2)))
171
+ globPath.map((path2) => (0, import_glob.glob)(removeFirstSlash(path2)))
172
172
  );
173
173
  files = a.flat();
174
174
  }
@@ -63,7 +63,7 @@ function dirname(url) {
63
63
 
64
64
  // src/node/file-cache.js
65
65
  var import_promises = __toESM(require("fs/promises"), 1);
66
- var import_glob_promise = __toESM(require("glob-promise"), 1);
66
+ var import_glob = require("glob");
67
67
  var import_node_path2 = __toESM(require("path"), 1);
68
68
 
69
69
  // src/lib/objects/nested-property.js
@@ -190,11 +190,11 @@ async function fileCache({ dir, file }) {
190
190
  async function getLastModifiedTime(globPath) {
191
191
  let files;
192
192
  if (typeof globPath === "string") {
193
- files = await (0, import_glob_promise.default)(removeFirstSlash(globPath));
193
+ files = await (0, import_glob.glob)(removeFirstSlash(globPath));
194
194
  }
195
195
  if (Array.isArray(globPath)) {
196
196
  const a = await Promise.all(
197
- globPath.map((path3) => (0, import_glob_promise.default)(removeFirstSlash(path3)))
197
+ globPath.map((path3) => (0, import_glob.glob)(removeFirstSlash(path3)))
198
198
  );
199
199
  files = a.flat();
200
200
  }
@@ -1,7 +1,7 @@
1
1
  // src/lib/numbers/index.js
2
2
  function splitUnit(string) {
3
3
  if (typeof string === "number") return [string, null];
4
- const regex = /(-?\d*\.?\d+)([a-z]+)/i;
4
+ const regex = /(-?\d*\.?\d+)\s*([a-z]+)/i;
5
5
  const match = string.match(regex);
6
6
  if (match) return [parseFloat(match[1]), match[2]];
7
7
  return [parseFloat(string), null];
@@ -242,7 +242,7 @@ function nativeMasonrySupport(node) {
242
242
  // src/lib/numbers/index.js
243
243
  function splitUnit(string) {
244
244
  if (typeof string === "number") return [string, null];
245
- const regex = /(-?\d*\.?\d+)([a-z]+)/i;
245
+ const regex = /(-?\d*\.?\d+)\s*([a-z]+)/i;
246
246
  const match = string.match(regex);
247
247
  if (match) return [parseFloat(match[1]), match[2]];
248
248
  return [parseFloat(string), null];
@@ -88,7 +88,7 @@ var MONTHS = [
88
88
  // src/lib/numbers/index.js
89
89
  function splitUnit(string) {
90
90
  if (typeof string === "number") return [string, null];
91
- const regex = /(-?\d*\.?\d+)([a-z]+)/i;
91
+ const regex = /(-?\d*\.?\d+)\s*([a-z]+)/i;
92
92
  const match = string.match(regex);
93
93
  if (match) return [parseFloat(match[1]), match[2]];
94
94
  return [parseFloat(string), null];
@@ -106,10 +106,12 @@ function ms(arg) {
106
106
  if (unit === "hours") return getTimeInMs(value, "hours");
107
107
  if (unit === "m") return getTimeInMs(value, "minutes");
108
108
  if (unit === "min") return getTimeInMs(value, "minutes");
109
+ if (unit === "mins") return getTimeInMs(value, "minutes");
109
110
  if (unit === "minute") return getTimeInMs(value, "minutes");
110
111
  if (unit === "minutes") return getTimeInMs(value, "minutes");
111
112
  if (unit === "s") return getTimeInMs(value, "seconds");
112
113
  if (unit === "sec") return getTimeInMs(value, "seconds");
114
+ if (unit === "secs") return getTimeInMs(value, "seconds");
113
115
  if (unit === "second") return getTimeInMs(value, "seconds");
114
116
  if (unit === "seconds") return getTimeInMs(value, "seconds");
115
117
  return value;
@@ -1,7 +1,7 @@
1
1
  // src/lib/numbers/index.js
2
2
  function splitUnit(string) {
3
3
  if (typeof string === "number") return [string, null];
4
- const regex = /(-?\d*\.?\d+)([a-z]+)/i;
4
+ const regex = /(-?\d*\.?\d+)\s*([a-z]+)/i;
5
5
  const match = string.match(regex);
6
6
  if (match) return [parseFloat(match[1]), match[2]];
7
7
  return [parseFloat(string), null];
@@ -19,10 +19,12 @@ function ms(arg) {
19
19
  if (unit === "hours") return getTimeInMs(value, "hours");
20
20
  if (unit === "m") return getTimeInMs(value, "minutes");
21
21
  if (unit === "min") return getTimeInMs(value, "minutes");
22
+ if (unit === "mins") return getTimeInMs(value, "minutes");
22
23
  if (unit === "minute") return getTimeInMs(value, "minutes");
23
24
  if (unit === "minutes") return getTimeInMs(value, "minutes");
24
25
  if (unit === "s") return getTimeInMs(value, "seconds");
25
26
  if (unit === "sec") return getTimeInMs(value, "seconds");
27
+ if (unit === "secs") return getTimeInMs(value, "seconds");
26
28
  if (unit === "second") return getTimeInMs(value, "seconds");
27
29
  if (unit === "seconds") return getTimeInMs(value, "seconds");
28
30
  return value;
@@ -252,7 +252,7 @@ function toRadians(angle) {
252
252
  // src/lib/numbers/index.js
253
253
  function splitUnit(string) {
254
254
  if (typeof string === "number") return [string, null];
255
- const regex = /(-?\d*\.?\d+)([a-z]+)/i;
255
+ const regex = /(-?\d*\.?\d+)\s*([a-z]+)/i;
256
256
  const match = string.match(regex);
257
257
  if (match) return [parseFloat(match[1]), match[2]];
258
258
  return [parseFloat(string), null];
@@ -270,10 +270,12 @@ function ms(arg) {
270
270
  if (unit === "hours") return getTimeInMs(value, "hours");
271
271
  if (unit === "m") return getTimeInMs(value, "minutes");
272
272
  if (unit === "min") return getTimeInMs(value, "minutes");
273
+ if (unit === "mins") return getTimeInMs(value, "minutes");
273
274
  if (unit === "minute") return getTimeInMs(value, "minutes");
274
275
  if (unit === "minutes") return getTimeInMs(value, "minutes");
275
276
  if (unit === "s") return getTimeInMs(value, "seconds");
276
277
  if (unit === "sec") return getTimeInMs(value, "seconds");
278
+ if (unit === "secs") return getTimeInMs(value, "seconds");
277
279
  if (unit === "second") return getTimeInMs(value, "seconds");
278
280
  if (unit === "seconds") return getTimeInMs(value, "seconds");
279
281
  return value;
@@ -603,8 +605,9 @@ function notEqual(a, b) {
603
605
  }
604
606
 
605
607
  // src/lib/objects/mix/mix.js
606
- var DEFAULT_OPTIONS = { array: "concat" };
608
+ var DEFAULT_OPTIONS = { array: "replace" };
607
609
  var mix = createMix();
610
+ var concatMix = createMix({ array: "concat" });
608
611
  function createMix(userOptions = {}) {
609
612
  const options = { ...DEFAULT_OPTIONS, ...userOptions };
610
613
  function _mix(...sources) {
@@ -943,6 +946,7 @@ export {
943
946
  RouteManager,
944
947
  camelCaseKeys,
945
948
  compose,
949
+ concatMix,
946
950
  createMix,
947
951
  createSSE,
948
952
  curry,
@@ -9,7 +9,7 @@ function toRadians(angle) {
9
9
  // src/lib/numbers/index.js
10
10
  function splitUnit(string) {
11
11
  if (typeof string === "number") return [string, null];
12
- const regex = /(-?\d*\.?\d+)([a-z]+)/i;
12
+ const regex = /(-?\d*\.?\d+)\s*([a-z]+)/i;
13
13
  const match = string.match(regex);
14
14
  if (match) return [parseFloat(match[1]), match[2]];
15
15
  return [parseFloat(string), null];
@@ -24,8 +24,9 @@ function curry(fn) {
24
24
  }
25
25
 
26
26
  // src/lib/objects/mix/mix.js
27
- var DEFAULT_OPTIONS = { array: "concat" };
27
+ var DEFAULT_OPTIONS = { array: "replace" };
28
28
  var mix = createMix();
29
+ var concatMix = createMix({ array: "concat" });
29
30
  function createMix(userOptions = {}) {
30
31
  const options = { ...DEFAULT_OPTIONS, ...userOptions };
31
32
  function _mix(...sources) {
@@ -94,8 +94,9 @@ function pipe(...fns) {
94
94
  }
95
95
 
96
96
  // src/lib/objects/mix/mix.js
97
- var DEFAULT_OPTIONS = { array: "concat" };
97
+ var DEFAULT_OPTIONS = { array: "replace" };
98
98
  var mix = createMix();
99
+ var concatMix = createMix({ array: "concat" });
99
100
  function createMix(userOptions = {}) {
100
101
  const options = { ...DEFAULT_OPTIONS, ...userOptions };
101
102
  function _mix(...sources) {
@@ -300,6 +301,7 @@ function splitObject(obj, keys) {
300
301
  }
301
302
  export {
302
303
  camelCaseKeys,
304
+ concatMix,
303
305
  createMix,
304
306
  extendObject,
305
307
  flattenObject,
@@ -1,6 +1,7 @@
1
1
  // src/lib/objects/mix/mix.js
2
- var DEFAULT_OPTIONS = { array: "concat" };
2
+ var DEFAULT_OPTIONS = { array: "replace" };
3
3
  var mix = createMix();
4
+ var concatMix = createMix({ array: "concat" });
4
5
  function createMix(userOptions = {}) {
5
6
  const options = { ...DEFAULT_OPTIONS, ...userOptions };
6
7
  function _mix(...sources) {
@@ -82,6 +83,7 @@ function objectType(value) {
82
83
  return Object.prototype.toString.call(value);
83
84
  }
84
85
  export {
86
+ concatMix,
85
87
  createMix,
86
88
  mix
87
89
  };
@@ -1,6 +1,6 @@
1
1
  // src/node/file-cache.js
2
2
  import fs from "fs/promises";
3
- import glob from "glob-promise";
3
+ import { glob } from "glob";
4
4
  import path from "path";
5
5
 
6
6
  // src/lib/objects/nested-property.js
@@ -17,7 +17,7 @@ function dirname(url) {
17
17
 
18
18
  // src/node/file-cache.js
19
19
  import fs from "fs/promises";
20
- import glob from "glob-promise";
20
+ import { glob } from "glob";
21
21
  import path2 from "path";
22
22
 
23
23
  // src/lib/objects/nested-property.js
@@ -25,7 +25,7 @@ export { extendObject } from './objects/extend.cjs';
25
25
  export { flattenObject } from './objects/flatten.cjs';
26
26
  export { parseJSON } from './objects/json.cjs';
27
27
  export { objectForEach, objectMap } from './objects/loop.cjs';
28
- export { createMix, mix } from './objects/mix/mix.cjs';
28
+ export { concatMix, createMix, mix } from './objects/mix/mix.cjs';
29
29
  export { getNestedProperty, getNestedProperty2, getNestedValue } from './objects/nested-property.cjs';
30
30
  export { normalizeObject } from './objects/normalize-object.cjs';
31
31
  export { omitEmpty } from './objects/omit-empty.cjs';
@@ -1,6 +1,6 @@
1
1
  declare function extendObject(object: any): {
2
2
  orig: any;
3
- extended: {};
3
+ extended: any;
4
4
  };
5
5
 
6
6
  export { extendObject };
@@ -5,7 +5,7 @@ export { extendObject } from './extend.cjs';
5
5
  export { flattenObject } from './flatten.cjs';
6
6
  export { parseJSON } from './json.cjs';
7
7
  export { objectForEach, objectMap } from './loop.cjs';
8
- export { createMix, mix } from './mix/mix.cjs';
8
+ export { concatMix, createMix, mix } from './mix/mix.cjs';
9
9
  export { getNestedProperty, getNestedProperty2, getNestedValue } from './nested-property.cjs';
10
10
  export { normalizeObject } from './normalize-object.cjs';
11
11
  export { omitEmpty } from './omit-empty.cjs';
@@ -1,4 +1,44 @@
1
- declare function createMix(userOptions?: {}): (...sources: any[]) => {};
2
- declare function mix(...sources: any[]): {};
1
+ /**
2
+ * Creates a customized mix function with specific options for array handling.
3
+ *
4
+ * @param {Object} [userOptions={}] - Configuration options for the mix function.
5
+ * @param {('replace'|'concat')} [userOptions.array='replace'] - How to handle array merging:
6
+ * - 'replace': Arrays from later sources completely replace arrays from earlier sources
7
+ * - 'concat': Arrays are concatenated together
8
+ * @return {Function} A mix function configured with the provided options.
9
+ *
10
+ * @example
11
+ * // Create mix function that concatenates arrays
12
+ * const concatMix = createMix({ array: 'concat' })
13
+ * const obj1 = { items: [1, 2] }
14
+ * const obj2 = { items: [3, 4] }
15
+ * const result = concatMix(obj1, obj2)
16
+ * // Returns: { items: [1, 2, 3, 4] }
17
+ *
18
+ * @example
19
+ * // Create mix function that replaces arrays (default behavior)
20
+ * const replaceMix = createMix({ array: 'replace' })
21
+ * const obj1 = { items: [1, 2] }
22
+ * const obj2 = { items: [3, 4] }
23
+ * const result = replaceMix(obj1, obj2)
24
+ * // Returns: { items: [3, 4] }
25
+ */
26
+ declare function createMix(userOptions?: {
27
+ array?: ("replace" | "concat");
28
+ }): Function;
29
+ /**
30
+ * Deep merges multiple objects into a new object with intelligent handling of arrays and nested objects.
31
+ *
32
+ * @param {...Object} sources - Objects to merge. Null and undefined values are skipped.
33
+ * @return {Object} A new object containing the merged properties from all sources.
34
+ *
35
+ * @example
36
+ * const obj1 = { a: 1, b: { x: 10 } }
37
+ * const obj2 = { b: { y: 20 }, c: 3 }
38
+ * const result = mix(obj1, obj2)
39
+ * // Returns: { a: 1, b: { x: 10, y: 20 }, c: 3 }
40
+ */
41
+ declare const mix: Function;
42
+ declare const concatMix: Function;
3
43
 
4
- export { createMix, mix };
44
+ export { concatMix, createMix, mix };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@splendidlabz/utils",
3
- "version": "1.7.0",
3
+ "version": "1.8.1",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -53,7 +53,7 @@
53
53
  "dependencies": {
54
54
  "deep-eql": "^5.0.2",
55
55
  "dompurify": "^3.2.4",
56
- "glob-promise": "^6.0.7",
56
+ "glob": "^11.0.0",
57
57
  "marked": "^15.0.7",
58
58
  "marked-gfm-heading-id": "^4.1.1",
59
59
  "marked-mangle": "^1.1.10",
@@ -63,7 +63,6 @@
63
63
  },
64
64
  "devDependencies": {
65
65
  "@splendidlabz/eslint-config": "2.1.0",
66
- "glob": "^11.0.0",
67
66
  "jsdom": "^26.0.0",
68
67
  "np": "^10.2.0",
69
68
  "tsup": "^8.0.0",
@@ -16,10 +16,12 @@ export function ms(arg) {
16
16
  if (unit === 'hours') return getTimeInMs(value, 'hours')
17
17
  if (unit === 'm') return getTimeInMs(value, 'minutes')
18
18
  if (unit === 'min') return getTimeInMs(value, 'minutes')
19
+ if (unit === 'mins') return getTimeInMs(value, 'minutes')
19
20
  if (unit === 'minute') return getTimeInMs(value, 'minutes')
20
21
  if (unit === 'minutes') return getTimeInMs(value, 'minutes')
21
22
  if (unit === 's') return getTimeInMs(value, 'seconds')
22
23
  if (unit === 'sec') return getTimeInMs(value, 'seconds')
24
+ if (unit === 'secs') return getTimeInMs(value, 'seconds')
23
25
  if (unit === 'second') return getTimeInMs(value, 'seconds')
24
26
  if (unit === 'seconds') return getTimeInMs(value, 'seconds')
25
27
 
@@ -4,7 +4,7 @@ export function splitUnit(string) {
4
4
  // If there are no units, return the number straight.
5
5
  if (typeof string === 'number') return [string, null]
6
6
 
7
- const regex = /(-?\d*\.?\d+)([a-z]+)/i
7
+ const regex = /(-?\d*\.?\d+)\s*([a-z]+)/i
8
8
  const match = string.match(regex)
9
9
 
10
10
  if (match) return [parseFloat(match[1]), match[2]]
@@ -0,0 +1,45 @@
1
+ import { describe, expect, test } from 'vitest'
2
+ import { splitUnit } from './index.js'
3
+
4
+ describe('splitUnit', () => {
5
+ test('handles number input', () => {
6
+ const result = splitUnit(42)
7
+ expect(result).toEqual([42, null])
8
+ })
9
+
10
+ test('handles unitless string numbers', () => {
11
+ const result = splitUnit('100')
12
+ expect(result).toEqual([100, null])
13
+ })
14
+
15
+ test('handles "3hours" without space', () => {
16
+ const result = splitUnit('3hours')
17
+ expect(result).toEqual([3, 'hours'])
18
+ })
19
+
20
+ test('handles "2rem" CSS unit', () => {
21
+ const result = splitUnit('2rem')
22
+ expect(result).toEqual([2, 'rem'])
23
+ })
24
+
25
+ test('handles decimal values', () => {
26
+ const result = splitUnit('1.5em')
27
+ expect(result).toEqual([1.5, 'em'])
28
+ })
29
+
30
+ test('handles negative values', () => {
31
+ const result = splitUnit('-10px')
32
+ expect(result).toEqual([-10, 'px'])
33
+ })
34
+
35
+ // Tests with spaces
36
+ test('handles values with spaces', () => {
37
+ const result = splitUnit('30 days')
38
+ expect(result).toEqual([30, 'days'])
39
+ })
40
+
41
+ test('handles values with many spaces between number and unit', () => {
42
+ const result = splitUnit('10 em')
43
+ expect(result).toEqual([10, 'em'])
44
+ })
45
+ })
@@ -1,7 +1,45 @@
1
- const DEFAULT_OPTIONS = { array: 'concat' }
2
-
1
+ const DEFAULT_OPTIONS = { array: 'replace' } // Can be concat or replace
2
+
3
+ /**
4
+ * Deep merges multiple objects into a new object with intelligent handling of arrays and nested objects.
5
+ *
6
+ * @param {...Object} sources - Objects to merge. Null and undefined values are skipped.
7
+ * @return {Object} A new object containing the merged properties from all sources.
8
+ *
9
+ * @example
10
+ * const obj1 = { a: 1, b: { x: 10 } }
11
+ * const obj2 = { b: { y: 20 }, c: 3 }
12
+ * const result = mix(obj1, obj2)
13
+ * // Returns: { a: 1, b: { x: 10, y: 20 }, c: 3 }
14
+ */
3
15
  export const mix = createMix()
4
-
16
+ export const concatMix = createMix({ array: 'concat' })
17
+
18
+ /**
19
+ * Creates a customized mix function with specific options for array handling.
20
+ *
21
+ * @param {Object} [userOptions={}] - Configuration options for the mix function.
22
+ * @param {('replace'|'concat')} [userOptions.array='replace'] - How to handle array merging:
23
+ * - 'replace': Arrays from later sources completely replace arrays from earlier sources
24
+ * - 'concat': Arrays are concatenated together
25
+ * @return {Function} A mix function configured with the provided options.
26
+ *
27
+ * @example
28
+ * // Create mix function that concatenates arrays
29
+ * const concatMix = createMix({ array: 'concat' })
30
+ * const obj1 = { items: [1, 2] }
31
+ * const obj2 = { items: [3, 4] }
32
+ * const result = concatMix(obj1, obj2)
33
+ * // Returns: { items: [1, 2, 3, 4] }
34
+ *
35
+ * @example
36
+ * // Create mix function that replaces arrays (default behavior)
37
+ * const replaceMix = createMix({ array: 'replace' })
38
+ * const obj1 = { items: [1, 2] }
39
+ * const obj2 = { items: [3, 4] }
40
+ * const result = replaceMix(obj1, obj2)
41
+ * // Returns: { items: [3, 4] }
42
+ */
5
43
  export function createMix(userOptions = {}) {
6
44
  const options = { ...DEFAULT_OPTIONS, ...userOptions }
7
45
 
@@ -18,6 +56,15 @@ export function createMix(userOptions = {}) {
18
56
  return _mix
19
57
  }
20
58
 
59
+ /**
60
+ * Recursively merges properties from input object into output object.
61
+ * Handles property descriptors, prevents prototype pollution, and deep clones values.
62
+ *
63
+ * @param {Object} output - The target object to merge properties into.
64
+ * @param {Object} input - The source object to merge properties from.
65
+ * @param {Object} options - Merge options including array handling strategy.
66
+ * @property {('replace'|'concat')} options.array - How to handle array merging.
67
+ */
21
68
  function merge(output, input, options) {
22
69
  const props = Object.keys(input)
23
70
 
@@ -63,7 +110,18 @@ function merge(output, input, options) {
63
110
  }
64
111
  }
65
112
 
66
- // Creates a deep clone for each value
113
+ /**
114
+ * Creates a deep clone of a property descriptor value.
115
+ * Handles arrays, objects, dates, maps, sets, and other types appropriately.
116
+ *
117
+ * @param {*} value - The value to clone.
118
+ * @return {*} A deep clone of the input value.
119
+ * @property {Array} value - Cloned recursively with all elements deep cloned.
120
+ * @property {Object} value - Cloned with all properties and descriptors preserved.
121
+ * @property {Date} value - Cloned as new Date with same time value.
122
+ * @property {Map} value - Cloned with all entries deep cloned.
123
+ * @property {Set} value - Cloned with all entries deep cloned.
124
+ */
67
125
  function cloneDescriptorValue(value) {
68
126
  // Arrays
69
127
  if (objectType(value) === '[object Array]') {
@@ -116,6 +174,18 @@ function cloneDescriptorValue(value) {
116
174
  return value
117
175
  }
118
176
 
177
+ /**
178
+ * Returns the precise object type of a value using Object.prototype.toString.
179
+ *
180
+ * @param {*} value - The value to get the type of.
181
+ * @return {string} The object type string (e.g., '[object Array]', '[object Object]', '[object Date]').
182
+ *
183
+ * @example
184
+ * objectType([]) // '[object Array]'
185
+ * objectType({}) // '[object Object]'
186
+ * objectType(new Date()) // '[object Date]'
187
+ * objectType(null) // '[object Null]'
188
+ */
119
189
  function objectType(value) {
120
190
  return Object.prototype.toString.call(value)
121
191
  }
@@ -1,6 +1,6 @@
1
1
  import { expect, it } from 'vitest'
2
2
 
3
- import { createMix, mix } from './mix.js'
3
+ import { concatMix, createMix, mix } from './mix.js'
4
4
 
5
5
  it('Merge objects', () => {
6
6
  const one = { one: 'one', overwrite: 'nope' }
@@ -176,7 +176,8 @@ it('Double objects with nested same array', () => {
176
176
 
177
177
  const three = mix(one, two)
178
178
  expect(typeof three.array.push).toBe('function')
179
- expect(three.array).toHaveLength(6)
179
+ expect(three.array).toHaveLength(3)
180
+ expect(three.array).toEqual([4, 5, 6])
180
181
  })
181
182
 
182
183
  it('Objects in Arrays', () => {
@@ -217,6 +218,54 @@ it('Deep nested arrays', () => {
217
218
  expect(two.array[1]).not.toBe(three.array[1])
218
219
  })
219
220
 
221
+ it('concatMix: concatenates arrays', () => {
222
+ const one = {
223
+ array: [1, 2, 3],
224
+ }
225
+ const two = {
226
+ array: [4, 5, 6],
227
+ }
228
+
229
+ const three = concatMix(one, two)
230
+ expect(typeof three.array.push).toBe('function')
231
+ expect(three.array).toHaveLength(6)
232
+ expect(three.array).toEqual([1, 2, 3, 4, 5, 6])
233
+ })
234
+
235
+ it('concatMix: empty array concat', () => {
236
+ const one = {}
237
+ const two = { array: [1, 2, 3] }
238
+ const three = concatMix(one, two)
239
+
240
+ expect(three).toEqual(two)
241
+ expect(typeof three.array.push).toBe('function')
242
+ expect(three.array).toHaveLength(3)
243
+
244
+ // Prevent mutation
245
+ three.array.push(4)
246
+ expect(two.array).toHaveLength(3)
247
+ expect(three.array).toHaveLength(4)
248
+ })
249
+
250
+ it('concatMix: nested objects with concatenated arrays', () => {
251
+ const one = {
252
+ nested: {
253
+ items: [1, 2],
254
+ other: 'value1',
255
+ },
256
+ }
257
+ const two = {
258
+ nested: {
259
+ items: [3, 4],
260
+ other: 'value2',
261
+ },
262
+ }
263
+
264
+ const three = concatMix(one, two)
265
+ expect(three.nested.items).toEqual([1, 2, 3, 4])
266
+ expect(three.nested.other).toBe('value2')
267
+ })
268
+
220
269
  it('Functions (cannot be cloned)', () => {
221
270
  const one = {}
222
271
  const two = {
@@ -1,5 +1,5 @@
1
1
  import fs from 'fs/promises'
2
- import glob from 'glob-promise'
2
+ import { glob } from 'glob'
3
3
  import path from 'node:path'
4
4
  import { sort } from '../lib/arrays/index.js'
5
5