@valkyriestudios/utils 12.36.0 → 12.37.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.
@@ -15,7 +15,7 @@ function mapFnAsMap(arr, fn, opts) {
15
15
  if (Object.prototype.toString.call(el) !== '[object Object]')
16
16
  continue;
17
17
  const hash = fn(el);
18
- if (Number.isFinite(hash) || (typeof hash === 'string' && hash.trim().length)) {
18
+ if (Number.isFinite(hash) || (typeof hash === 'string' && hash.length > 0)) {
19
19
  const transformed = TRANSFORM_FN ? TRANSFORM_FN(el) : el;
20
20
  map.set(hash, MERGE && map.has(hash) ? (0, merge_1.merge)(map.get(hash), transformed, { union: true }) : transformed);
21
21
  }
package/date/format.js CHANGED
@@ -17,10 +17,6 @@ try {
17
17
  }
18
18
  catch {
19
19
  }
20
- finally {
21
- if (typeof DEFAULT_TZ !== 'string')
22
- DEFAULT_TZ = 'UTC';
23
- }
24
20
  const ESCAPE_RGX = /\[[\s\S]+?]/g;
25
21
  const intl_formatters = new LRU_1.default({ max_size: 100 });
26
22
  const spec_cache = new LRU_1.default({ max_size: 100 });
@@ -218,9 +214,10 @@ format.getLocale = function () {
218
214
  return DEFAULT_LOCALE;
219
215
  };
220
216
  format.setLocale = function (locale) {
221
- if (typeof locale !== 'string' || !locale.trim().length)
217
+ const normalized = typeof locale === 'string' ? locale.trim() : false;
218
+ if (!normalized)
222
219
  throw new Error('format/setLocale: locale should be a string');
223
- DEFAULT_LOCALE = locale.trim();
220
+ DEFAULT_LOCALE = normalized;
224
221
  };
225
222
  format.getZone = function () {
226
223
  return DEFAULT_TZ;
package/date/isFormat.js CHANGED
@@ -93,7 +93,7 @@ function compileSpec(spec, is_chunk = false) {
93
93
  }
94
94
  function isDateFormat(input, spec) {
95
95
  if (typeof input !== 'string')
96
- throw new TypeError('isDateFormat: input must be a string');
96
+ return false;
97
97
  if (typeof spec !== 'string')
98
98
  throw new TypeError('isDateFormat: spec must be a string');
99
99
  const { tokens, rgx } = compileSpec(SPEC_ALIASES[spec] || spec);
@@ -11,6 +11,10 @@ type ToObjectConfig = {
11
11
  * Whether or not we should normalize booleans, defaults to true if not set
12
12
  */
13
13
  normalize_bool?: boolean;
14
+ /**
15
+ * Whether or not we should normalize null, defaults to true if not set
16
+ */
17
+ normalize_null?: boolean;
14
18
  /**
15
19
  * Whether or not we should normalize dates, defaults to true if not set
16
20
  */
@@ -10,22 +10,30 @@ function assign(acc, rawkey, value, single) {
10
10
  const keys_len = keys.length;
11
11
  for (let i = 0; i < keys_len; i++) {
12
12
  const key = keys[i];
13
- if (i < (keys_len - 1)) {
14
- const n_key = Array.isArray(cursor) ? Number(key) : key;
15
- if (!cursor[n_key])
16
- cursor[n_key] = Number.isInteger(+keys[i + 1]) ? [] : {};
17
- cursor = cursor[n_key];
18
- }
19
- else if (!(key in cursor) || single.has(key)) {
20
- cursor[key] = value;
21
- }
22
- else {
23
- const cursor_val = cursor[key];
24
- if (Array.isArray(cursor_val)) {
25
- cursor_val.push(value);
26
- }
27
- else {
28
- cursor[key] = [cursor_val, value];
13
+ switch (key) {
14
+ case '__proto__':
15
+ case 'constructor':
16
+ case 'prototype':
17
+ return;
18
+ default: {
19
+ if (i < (keys_len - 1)) {
20
+ const n_key = Array.isArray(cursor) ? Number(key) : key;
21
+ if (!cursor[n_key])
22
+ cursor[n_key] = Number.isInteger(+keys[i + 1]) ? [] : {};
23
+ cursor = cursor[n_key];
24
+ }
25
+ else if (!(key in cursor) || (single && single.has(key))) {
26
+ cursor[key] = value;
27
+ }
28
+ else {
29
+ const cursor_val = cursor[key];
30
+ if (Array.isArray(cursor_val)) {
31
+ cursor_val.push(value);
32
+ }
33
+ else {
34
+ cursor[key] = [cursor_val, value];
35
+ }
36
+ }
29
37
  }
30
38
  }
31
39
  }
@@ -33,38 +41,52 @@ function assign(acc, rawkey, value, single) {
33
41
  function toObject(form, config) {
34
42
  if (!(form instanceof FormData))
35
43
  throw new Error('formdata/toObject: Value is not an instance of FormData');
36
- const set = config?.raw === true ? true : new Set(Array.isArray(config?.raw) ? config?.raw : []);
37
- const single = new Set(Array.isArray(config?.single) ? config.single : []);
44
+ const set = config?.raw === true ? null : new Set(Array.isArray(config?.raw) ? config?.raw : []);
45
+ const set_guard = !!(set && set.size > 0);
46
+ const single = Array.isArray(config?.single) ? new Set(config.single) : null;
38
47
  const nBool = config?.normalize_bool !== false;
48
+ const nNull = config?.normalize_null !== false;
39
49
  const nDate = config?.normalize_date !== false;
40
50
  const nNumber = config?.normalize_number !== false;
41
51
  const acc = {};
42
- form.forEach((value, key) => {
43
- if (set !== true && value !== '' && typeof value === 'string' && !set.has(key)) {
44
- if (nBool) {
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;
52
+ if (set === null) {
53
+ form.forEach((value, key) => assign(acc, key, value, single));
54
+ }
55
+ else {
56
+ form.forEach((value, key) => {
57
+ if (set_guard && set.has(key))
58
+ return assign(acc, key, value, single);
59
+ switch (value) {
60
+ case 'true':
61
+ case 'TRUE':
62
+ case 'True':
63
+ assign(acc, key, nBool ? true : value, single);
64
+ break;
65
+ case 'false':
66
+ case 'FALSE':
67
+ case 'False':
68
+ assign(acc, key, nBool ? false : value, single);
69
+ break;
70
+ case 'null':
71
+ case 'NULL':
72
+ case 'Null':
73
+ assign(acc, key, nNull ? null : value, single);
74
+ break;
75
+ default: {
76
+ if (typeof value === 'string' && value.length) {
77
+ if (nNumber) {
78
+ const nVal = Number(value);
79
+ if (!isNaN(nVal))
80
+ return assign(acc, key, nVal, single);
81
+ }
82
+ if (nDate &&
83
+ (0, isFormat_1.isDateFormat)(value, 'ISO'))
84
+ return assign(acc, key, new Date(value), single);
85
+ }
86
+ assign(acc, key, value, single);
56
87
  }
57
88
  }
58
- if (nNumber) {
59
- const nVal = Number(value);
60
- if (!isNaN(nVal))
61
- return assign(acc, key, nVal, single);
62
- }
63
- if (nDate &&
64
- (0, isFormat_1.isDateFormat)(value, 'ISO'))
65
- return assign(acc, key, new Date(value), single);
66
- }
67
- assign(acc, key, value, single);
68
- });
89
+ });
90
+ }
69
91
  return acc;
70
92
  }
package/index.d.ts CHANGED
@@ -284,6 +284,7 @@ declare module "formdata/toObject" {
284
284
  raw?: string[] | true;
285
285
  single?: string[];
286
286
  normalize_bool?: boolean;
287
+ normalize_null?: boolean;
287
288
  normalize_date?: boolean;
288
289
  normalize_number?: boolean;
289
290
  };
package/object/pick.js CHANGED
@@ -21,12 +21,12 @@ function pick(obj, keys) {
21
21
  const parts_len = parts.length;
22
22
  let cursor = map;
23
23
  for (let y = 0; y < parts_len - 1; y++) {
24
- const part = parts[y].trim();
24
+ const part = parts[y];
25
25
  if (!(part in cursor))
26
26
  cursor[part] = {};
27
27
  cursor = cursor[part];
28
28
  }
29
- cursor[parts[parts_len - 1].trim()] = val;
29
+ cursor[parts[parts_len - 1]] = val;
30
30
  }
31
31
  else if (key in obj) {
32
32
  map[key] = obj[key];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@valkyriestudios/utils",
3
- "version": "12.36.0",
3
+ "version": "12.37.0",
4
4
  "description": "A collection of single-function utilities for common tasks",
5
5
  "author": {
6
6
  "name": "Peter Vermeulen",
@@ -1168,11 +1168,11 @@
1168
1168
  }
1169
1169
  },
1170
1170
  "devDependencies": {
1171
- "@types/node": "^22.15.16",
1171
+ "@types/node": "^22.15.18",
1172
1172
  "esbuild-register": "^3.6.0",
1173
- "eslint": "^9.26.0",
1173
+ "eslint": "^9.27.0",
1174
1174
  "nyc": "^17.1.0",
1175
1175
  "typescript": "^5.8.3",
1176
- "typescript-eslint": "^8.32.0"
1176
+ "typescript-eslint": "^8.32.1"
1177
1177
  }
1178
1178
  }
@@ -6,7 +6,7 @@ const round_1 = require("../number/round");
6
6
  const DEFAULT_UNITS = ['', 'k', 'm', 'b', 't', 'q'];
7
7
  function humanizeNumber(val, options = {}) {
8
8
  const DELIM = typeof options?.delim === 'string' ? options.delim : ',';
9
- const SEPARATOR = typeof options?.separator === 'string' && options.separator.trim().length ? options.separator : '.';
9
+ const SEPARATOR = typeof options?.separator === 'string' && options.separator.length ? options.separator : '.';
10
10
  const PRECISION = Number.isInteger(options?.precision) && options.precision >= 0 ? options.precision : 2;
11
11
  const DIVIDER = Number.isInteger(options?.divider) && options.divider >= 2 ? options.divider : 1000;
12
12
  const REAL = options?.real === true;
@@ -15,7 +15,7 @@ function humanizeNumber(val, options = {}) {
15
15
  : options?.units === false
16
16
  ? false
17
17
  : DEFAULT_UNITS;
18
- let normalized = typeof val === 'string' ? parseFloat(val.trim()) : val;
18
+ let normalized = typeof val === 'string' ? parseFloat(val) : val;
19
19
  if (!Number.isFinite(normalized) || normalized === 0)
20
20
  return UNITS ? '0' + UNITS[0] : '0';
21
21
  if (REAL)
@@ -5,5 +5,19 @@ exports.default = isNotEmptyString;
5
5
  function isNotEmptyString(val, trimmed = true) {
6
6
  if (typeof val !== 'string')
7
7
  return false;
8
- return (trimmed === true ? val.trim() : val).length > 0;
8
+ if (trimmed) {
9
+ for (let i = 0; i < val.length; i++) {
10
+ switch (val[i]) {
11
+ case ' ':
12
+ case '\t':
13
+ case '\n':
14
+ case '\r':
15
+ break;
16
+ default:
17
+ return true;
18
+ }
19
+ }
20
+ return false;
21
+ }
22
+ return val.length > 0;
9
23
  }
package/string/shorten.js CHANGED
@@ -17,5 +17,5 @@ function shorten(val, length, postfix = '...', truncate_words = true) {
17
17
  while (end && sanitized[end] !== ' ' && sanitized[end - 1] !== ' ') {
18
18
  end--;
19
19
  }
20
- return sanitized.substring(0, end).trim() + postfix;
20
+ return sanitized.substring(0, end).trimEnd() + postfix;
21
21
  }