@valkyriestudios/utils 12.31.1 → 12.32.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/date/isFormat.js CHANGED
@@ -92,12 +92,10 @@ function compileSpec(spec, is_chunk = false) {
92
92
  return cached;
93
93
  }
94
94
  function isDateFormat(input, spec) {
95
- if (typeof input !== 'string' || input.trim().length === 0) {
96
- throw new TypeError('isDateFormat: input must be a non-empty string');
97
- }
98
- if (typeof spec !== 'string') {
95
+ if (typeof input !== 'string')
96
+ throw new TypeError('isDateFormat: input must be a string');
97
+ if (typeof spec !== 'string')
99
98
  throw new TypeError('isDateFormat: spec must be a string');
100
- }
101
99
  const { tokens, rgx } = compileSpec(SPEC_ALIASES[spec] || spec);
102
100
  if (!tokens.length)
103
101
  return false;
@@ -3,19 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.toObject = toObject;
4
4
  exports.default = toObject;
5
5
  const isFormat_1 = require("../date/isFormat");
6
- const RGX_CLOSE = /\]/g;
7
- const RGX_DIGIT = /^\d+$/;
8
- function assignValue(acc, rawkey, value, single) {
6
+ const RGX_TOKENS = /[^.[\]]+/g;
7
+ function assign(acc, rawkey, value, single) {
9
8
  let cursor = acc;
10
- const keys = rawkey.replace(RGX_CLOSE, '').split(/\[|\./);
9
+ const keys = rawkey.match(RGX_TOKENS);
11
10
  const keys_len = keys.length;
12
11
  for (let i = 0; i < keys_len; i++) {
13
12
  const key = keys[i];
14
13
  if (i < (keys_len - 1)) {
15
14
  const n_key = Array.isArray(cursor) ? Number(key) : key;
16
- if (!cursor[n_key]) {
17
- cursor[n_key] = RGX_DIGIT.test(keys[i + 1]) ? [] : {};
18
- }
15
+ if (!cursor[n_key])
16
+ cursor[n_key] = Number.isInteger(+keys[i + 1]) ? [] : {};
19
17
  cursor = cursor[n_key];
20
18
  }
21
19
  else if (!(key in cursor) || single.has(key)) {
@@ -42,31 +40,31 @@ function toObject(form, config) {
42
40
  const nNumber = config?.normalize_number !== false;
43
41
  const acc = {};
44
42
  form.forEach((value, key) => {
45
- if (set !== true && typeof value === 'string' && value !== '' && !set.has(key)) {
43
+ if (set !== true && value !== '' && typeof value === 'string' && !set.has(key)) {
46
44
  if (nBool) {
47
- const lower = value.toLowerCase();
48
- if (lower === 'true') {
49
- assignValue(acc, key, true, single);
50
- return;
51
- }
52
- else if (lower === 'false') {
53
- assignValue(acc, key, false, single);
54
- return;
45
+ switch (value) {
46
+ case 'true':
47
+ case 'TRUE':
48
+ case 'True':
49
+ return assign(acc, key, true, single);
50
+ case 'false':
51
+ case 'FALSE':
52
+ case 'False':
53
+ return assign(acc, key, false, single);
54
+ default:
55
+ break;
55
56
  }
56
57
  }
57
58
  if (nNumber) {
58
59
  const nVal = Number(value);
59
- if (!isNaN(nVal)) {
60
- assignValue(acc, key, nVal, single);
61
- return;
62
- }
63
- }
64
- if (nDate && (0, isFormat_1.isDateFormat)(value, 'ISO')) {
65
- assignValue(acc, key, new Date(value), single);
66
- return;
60
+ if (!isNaN(nVal))
61
+ return assign(acc, key, nVal, single);
67
62
  }
63
+ if (nDate &&
64
+ (0, isFormat_1.isDateFormat)(value, 'ISO'))
65
+ return assign(acc, key, new Date(value), single);
68
66
  }
69
- assignValue(acc, key, value, single);
67
+ assign(acc, key, value, single);
70
68
  });
71
69
  return acc;
72
70
  }
package/index.d.ts CHANGED
@@ -38,10 +38,25 @@ declare module "array/join" {
38
38
  export { join, join as default };
39
39
  }
40
40
  declare module "object/merge" {
41
- type MergeOptions = {
42
- union?: boolean;
41
+ type Merge<T, U> = {
42
+ [K in keyof T | keyof U]: K extends keyof U ? U[K] : K extends keyof T ? T[K] : never;
43
43
  };
44
- function merge(target: Record<string, any>, source?: Record<string, any> | Record<string, any>[], opts?: MergeOptions): Record<string, any>;
44
+ type MergeNonUnion<T, U> = {
45
+ [K in keyof T]: K extends keyof U ? U[K] : T[K];
46
+ };
47
+ type MergeArray<T, U extends Record<string, unknown>[], Union extends boolean> = U extends [infer Head, ...infer Tail] ? Head extends Record<string, unknown> ? Tail extends Record<string, unknown>[] ? MergeArray<Union extends true ? Merge<T, Head> : MergeNonUnion<T, Head>, Tail, Union> : Union extends true ? Merge<T, Head> : MergeNonUnion<T, Head> : T : T;
48
+ function merge<T extends Record<string, unknown>, U extends Record<string, unknown>>(target: T, source: U, opts: {
49
+ union: true;
50
+ }): Merge<T, U>;
51
+ function merge<T extends Record<string, unknown>, U extends Record<string, unknown>>(target: T, source: U, opts?: {
52
+ union?: false;
53
+ }): MergeNonUnion<T, U>;
54
+ function merge<T extends Record<string, unknown>, U extends Record<string, unknown>[]>(target: T, sources: [...U], opts: {
55
+ union: true;
56
+ }): MergeArray<T, U, true>;
57
+ function merge<T extends Record<string, unknown>, U extends Record<string, unknown>[]>(target: T, sources: [...U], opts?: {
58
+ union?: false;
59
+ }): MergeArray<T, U, false>;
45
60
  export { merge, merge as default };
46
61
  }
47
62
  declare module "array/mapFn" {
package/object/merge.d.ts CHANGED
@@ -1,17 +1,31 @@
1
- type MergeOptions = {
2
- /**
3
- * Defaults to false, when passed as true it ensures all keys from both objects
4
- * are available in the merged object
5
- */
6
- union?: boolean;
1
+ /**
2
+ * For union true: for every key in T or U, use U’s type if available; otherwise T’s.
3
+ */
4
+ type Merge<T, U> = {
5
+ [K in keyof T | keyof U]: K extends keyof U ? U[K] : K extends keyof T ? T[K] : never;
6
+ };
7
+ /**
8
+ * For union false: only keys in T are retained; if U has a key, override its type.
9
+ */
10
+ type MergeNonUnion<T, U> = {
11
+ [K in keyof T]: K extends keyof U ? U[K] : T[K];
7
12
  };
8
13
  /**
9
- * Deep merge two objects together while ensuring nested objects also get merged,
10
- * take note: this does not merge onto passed objects by reference but instead
11
- * returns a new object
12
- *
13
- * @param {Record<string,any>} target - Base Object
14
- * @param {Record<string,any>|Record<string,any>[]} source - (default={}) Object to merge onto base object
14
+ * Recursively merge an array of source objects.
15
+ * For each element in the array, apply Merge (if union is true)
16
+ * or MergeNonUnion (if union is false).
15
17
  */
16
- declare function merge(target: Record<string, any>, source?: Record<string, any> | Record<string, any>[], opts?: MergeOptions): Record<string, any>;
18
+ type MergeArray<T, U extends Record<string, unknown>[], Union extends boolean> = U extends [infer Head, ...infer Tail] ? Head extends Record<string, unknown> ? Tail extends Record<string, unknown>[] ? MergeArray<Union extends true ? Merge<T, Head> : MergeNonUnion<T, Head>, Tail, Union> : Union extends true ? Merge<T, Head> : MergeNonUnion<T, Head> : T : T;
19
+ declare function merge<T extends Record<string, unknown>, U extends Record<string, unknown>>(target: T, source: U, opts: {
20
+ union: true;
21
+ }): Merge<T, U>;
22
+ declare function merge<T extends Record<string, unknown>, U extends Record<string, unknown>>(target: T, source: U, opts?: {
23
+ union?: false;
24
+ }): MergeNonUnion<T, U>;
25
+ declare function merge<T extends Record<string, unknown>, U extends Record<string, unknown>[]>(target: T, sources: [...U], opts: {
26
+ union: true;
27
+ }): MergeArray<T, U, true>;
28
+ declare function merge<T extends Record<string, unknown>, U extends Record<string, unknown>[]>(target: T, sources: [...U], opts?: {
29
+ union?: false;
30
+ }): MergeArray<T, U, false>;
17
31
  export { merge, merge as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@valkyriestudios/utils",
3
- "version": "12.31.1",
3
+ "version": "12.32.0",
4
4
  "description": "A collection of single-function utilities for common tasks",
5
5
  "author": {
6
6
  "name": "Peter Vermeulen",
@@ -1108,11 +1108,11 @@
1108
1108
  }
1109
1109
  },
1110
1110
  "devDependencies": {
1111
- "@types/node": "^22.13.1",
1111
+ "@types/node": "^22.13.5",
1112
1112
  "esbuild-register": "^3.6.0",
1113
- "eslint": "^9.19.0",
1113
+ "eslint": "^9.21.0",
1114
1114
  "nyc": "^17.1.0",
1115
1115
  "typescript": "^5.7.3",
1116
- "typescript-eslint": "^8.23.0"
1116
+ "typescript-eslint": "^8.25.0"
1117
1117
  }
1118
1118
  }