@valkyriestudios/utils 11.7.0 → 12.0.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
@@ -155,7 +155,7 @@ shuffle(arr);
155
155
  // [4, 6, 3, 2, 5, 1]
156
156
  ```
157
157
 
158
- - **sort(val:Array[object], by:String|Function, dir:Enum(asc,desc), options:Object)**
158
+ - **sort(val:Array[object], by:string|Function, dir:Enum(asc,desc), options:Object)**
159
159
  Sort an array of objects, uses an implementation of [Tony Hoare's quicksort](https://cs.stanford.edu/people/eroberts/courses/soco/projects/2008-09/tony-hoare/quicksort.html)
160
160
 
161
161
  ```js
@@ -279,7 +279,7 @@ isDate(new Date('December 17, 1995 03:24:00'); // TRUE
279
279
  isDate('December 17, 1995 03:24:00'); // FALSE
280
280
  ```
281
281
 
282
- - **diff(val_a:Date, val_b:Date, key:String)**
282
+ - **diff(val_a:Date, val_b:Date, key:string)**
283
283
  Take two incoming dates and return the difference between them in a certain unit. Possible key options(week,day,hour,minute,second,millisecond).
284
284
 
285
285
  Note: Does not touch the passed date objects, if no key is passed will default to millisecond
@@ -292,6 +292,51 @@ diff(new Date("2022-10-05T13:12:11+02:00"), new Date("2022-10-05T17:43:09.344+06
292
292
  diff(new Date("2022-10-05T13:12:11+02:00"), new Date("2022-10-05T17:43:09.344+06:00"), 'millisecond'); // -1858344
293
293
  diff(new Date("2022-11-05T13:12:11+06:00"), new Date("2022-10-05T13:25:43.898+02:00")); // 2663187102
294
294
  ```
295
+ - **format(val:Date, spec:string, locale?:string, zone?:string):string**
296
+ Format a date according to a spec/locale and zone
297
+
298
+ Note: The locale is by default set to 'en-US'
299
+
300
+ Note: The zone is by default detected as the zone of the client
301
+
302
+ Available tokens for usage in spec:
303
+ | Token | Description | Example |
304
+ |:---------|:--------------------------|:---------------|
305
+ | `YYYY` | Full Year | 2021 |
306
+ | `Q` | Quarters of the year | 1 2 3 4 |
307
+ | `MMMM` | Month in full | January February ... November December |
308
+ | `MMM` | Month as 3 char | Jan Feb ... Nov Dec |
309
+ | `MM` | Month as 2 char | 01 02 .. 11 12 |
310
+ | `M` | Month as pure digit | 1 2 .. 11 12 |
311
+ | `DD` | Day of month as 2 char | 01 02 .. 30 31 |
312
+ | `D` | Day of month as 1 char | 1 2 .. 30 31 |
313
+ | `dddd` | Day of week as 3 char | Sun Mon ... Fri Sat |
314
+ | `ddd` | Day of week in full | Sunday Monday ... Saturday |
315
+ | `HH` | Hours as 2-char | 00 01 .. 22 23 |
316
+ | `H` | Hours as pure digit | 0 1 .. 22 23 |
317
+ | `hh` | Hours in 12 hour time as 2 char | 01 02 ... 11 12 |
318
+ | `h` | Hours in 12 hour time as pure digit | 1 2 ... 11 12 |
319
+ | `mm` | Minutes as 2-char | 00 01 .. 58 59 |
320
+ | `m` | Minutes as pure digit | 0 1 .. 58 59 |
321
+ | `ss` | Seconds as 2-char | 00 01 .. 58 59 |
322
+ | `s` | Seconds as pure digit | 0 1 .. 58 59 |
323
+ | `SSS` | Milliseconds as 3-digit | 000 001 ... 998 999 |
324
+ | `A` | Uppercase AM/PM | AM ... PM |
325
+ | `a` | Lowercase AM/PM | am ... pm |
326
+
327
+ ```js
328
+ format(new Date('2023-01-10T14:30:00Z'), '[Today is] dddd, MMMM D, YYYY [at] h:mm A', 'en', 'Europe/Brussels');
329
+ // 'Today is Tuesday, January 10, 2023 at 2:30 PM'
330
+
331
+ format(new Date('2022-07-14T16:40:30Z'), 'dddd, [Year] Q Q M D [à] hh:mm A [string]', 'fr', 'Asia/Singapore');
332
+ // 'vendredi, Year 3 3 7 15 à 12:40 AM string'
333
+
334
+ format(new Date('2022-07-14T16:40:30Z'), 'YYYY-MM-DD', 'fr', 'Asia/Singapore');
335
+ // 2022-07-15
336
+
337
+ format(new Date('2022-07-14T16:40:30Z'), 'YYYY-MM-DD', 'fr', 'Europe/Brussels');
338
+ // 2022-07-14
339
+ ```
295
340
 
296
341
  - **toUTC(val:Date)**
297
342
  Takes the passed date object and returns a new date object set for utc
@@ -305,7 +350,7 @@ Returns the current unix timestamp in seconds
305
350
  - **nowUnixMs()**
306
351
  Returns the current unix timestamp in milliseconds
307
352
 
308
- - **startOfUTC(val:Date, key:String)**
353
+ - **startOfUTC(val:Date, key:string)**
309
354
  Take the incoming date and return a date set to the start of passed key. Possible key options(year,quarter,month,week,week_sun,week_mon,week_tue,week_wed,week_thu,week_fri,week_sat,day,hour,minute,second).
310
355
 
311
356
  Note: Does not touch the date object passed
@@ -325,7 +370,7 @@ startOfUTC(new Date("2023-05-04T12:04:27+02:00"), 'minute'); // new Date("2023-0
325
370
  startOfUTC(new Date("2023-05-04T12:04:27.043+02:00"), 'second'); // new Date("2023-05-04T10:04:27.000Z")
326
371
  ```
327
372
 
328
- - **endOfUTC(val:Date, key:String)**
373
+ - **endOfUTC(val:Date, key:string)**
329
374
  Take the incoming date and return a date set to the end of passed key. Possible key options(year,quarter,month,week,week_sun,week_mon,week_tue,week_wed,week_thu,week_fri,week_sat,day,hour,minute,second).
330
375
 
331
376
  Note: Does not touch the date object passed
@@ -349,7 +394,7 @@ endOfUTC(new Date("2023-05-04T12:04:27+02:00"), 'minute'); // new Date("2023-05-
349
394
  endOfUTC(new Date("2023-05-04T12:04:27.043+02:00"), 'second'); // new Date("2023-05-04T10:04:27.999Z")
350
395
  ```
351
396
 
352
- - **addUTC(val:Date, amount:integer, key:String)**
397
+ - **addUTC(val:Date, amount:integer, key:string)**
353
398
  Take the incoming date and add a certain amount of the passed key. Possible key options(year,years,month,months,day,days,hour,hours,minute,minutes,second,seconds,millisecond,milliseconds).
354
399
 
355
400
  Note: Does not touch the date object passed
package/array/dedupe.js CHANGED
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const fnv1A_1 = require("../hash/fnv1A");
4
4
  function dedupe(val) {
5
- if (!Array.isArray(val) || val.length === 0)
5
+ if (!Array.isArray(val) || !val.length)
6
6
  return [];
7
7
  const set = new Set();
8
8
  const acc = [];
package/array/join.js CHANGED
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const round_1 = require("../number/round");
4
4
  function join(val, opts = {}) {
5
- if (!Array.isArray(val) || val.length === 0)
5
+ if (!Array.isArray(val) || !val.length)
6
6
  return '';
7
7
  const OPTS = {
8
8
  delim: ' ',
@@ -12,7 +12,7 @@ function join(val, opts = {}) {
12
12
  };
13
13
  const filtered = [];
14
14
  for (const el of val) {
15
- if (typeof el === 'string' && el.trim().length > 0) {
15
+ if (typeof el === 'string' && el.trim().length) {
16
16
  filtered.push(OPTS.valtrim === true ? el.trim() : el);
17
17
  }
18
18
  else if (Number.isFinite(el)) {
package/array/mapFn.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  function mapFn(arr, fn, opts = {}) {
4
- if ((!Array.isArray(arr) || arr.length === 0) ||
4
+ if ((!Array.isArray(arr) || !arr.length) ||
5
5
  typeof fn !== 'function')
6
6
  return {};
7
7
  const OPTS = {
@@ -14,7 +14,7 @@ function mapFn(arr, fn, opts = {}) {
14
14
  if (Object.prototype.toString.call(el) !== '[object Object]')
15
15
  continue;
16
16
  hash = fn(el);
17
- if (!Number.isFinite(hash) && !(typeof hash === 'string' && hash.trim().length > 0))
17
+ if (!Number.isFinite(hash) && !(typeof hash === 'string' && hash.trim().length))
18
18
  continue;
19
19
  hash = `${hash}`;
20
20
  if (OPTS.merge === true && map.hasOwnProperty(hash)) {
package/array/mapKey.js CHANGED
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  function mapKey(arr, key, opts = {}) {
4
- if ((!Array.isArray(arr) || arr.length === 0) ||
4
+ if ((!Array.isArray(arr) || !arr.length) ||
5
5
  typeof key !== 'string')
6
6
  return {};
7
7
  const key_s = key.trim();
8
- if (key_s.length === 0)
8
+ if (!key_s.length)
9
9
  return {};
10
10
  const OPTS = {
11
11
  merge: false,
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const round_1 = require("../number/round");
4
4
  function mapPrimitive(arr, opts = {}) {
5
- if (!Array.isArray(arr) || arr.length === 0)
5
+ if (!Array.isArray(arr) || !arr.length)
6
6
  return {};
7
7
  const OPTS = {
8
8
  valtrim: false,
@@ -12,7 +12,7 @@ function mapPrimitive(arr, opts = {}) {
12
12
  };
13
13
  const map = {};
14
14
  for (const el of arr) {
15
- if (typeof el === 'string' && el.trim().length > 0) {
15
+ if (typeof el === 'string' && el.trim().length) {
16
16
  map[el.trim()] = OPTS.valtrim ? el.trim() : el;
17
17
  }
18
18
  else if (typeof el === 'number' && Number.isFinite(el)) {
package/array/shuffle.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  function shuffle(arr) {
4
- if (!Array.isArray(arr) || arr.length === 0)
4
+ if (!Array.isArray(arr) || !arr.length)
5
5
  return;
6
6
  for (let i = arr.length - 1; i > 0; i--) {
7
7
  const j = Math.floor(Math.random() * (i + 1));
package/array/sort.js CHANGED
@@ -30,7 +30,7 @@ function quickSort(arr, start_ix = 0, end_ix = arr.length - 1) {
30
30
  return arr;
31
31
  }
32
32
  function sort(arr, by, dir = 'asc', opts = {}) {
33
- if (!Array.isArray(arr) || arr.length === 0)
33
+ if (!Array.isArray(arr) || !arr.length)
34
34
  return [];
35
35
  if (dir !== 'asc' && dir !== 'desc')
36
36
  throw new Error('Direction should be either asc or desc');
@@ -46,7 +46,7 @@ function sort(arr, by, dir = 'asc', opts = {}) {
46
46
  const nokey_arr = [];
47
47
  if (typeof by === 'string') {
48
48
  const by_s = by.trim();
49
- if (by_s.length === 0)
49
+ if (!by_s.length)
50
50
  throw new Error('Sort by as string should contain content');
51
51
  for (const el of arr) {
52
52
  if (!OPTS.filter_fn(el))
package/date/addUTC.d.ts CHANGED
@@ -7,4 +7,4 @@
7
7
  *
8
8
  * @returns New date with provided amount of key added
9
9
  */
10
- export default function addUTC(val: Date, amount?: number, key?: 'years' | 'year' | 'months' | 'month' | 'days' | 'day' | 'hours' | 'hour' | 'minutes' | 'minute' | 'seconds' | 'second' | 'milliseconds' | 'millisecond'): Date;
10
+ export default function addUTC(val: Date, amt?: number, key?: 'years' | 'year' | 'months' | 'month' | 'days' | 'day' | 'hours' | 'hour' | 'minutes' | 'minute' | 'seconds' | 'second' | 'milliseconds' | 'millisecond'): Date;
package/date/addUTC.js CHANGED
@@ -1,52 +1,44 @@
1
1
  'use strict';
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const is_1 = require("./is");
4
- function addUTC(val, amount = 0, key = 'millisecond') {
4
+ function addUTC(val, amt = 0, key = 'millisecond') {
5
5
  if (!(0, is_1.default)(val))
6
6
  throw new TypeError('addUTC requires a date object');
7
- if (!Number.isInteger(amount))
7
+ if (!Number.isInteger(amt))
8
8
  throw new TypeError('Amount needs to be an integer');
9
9
  if (typeof key !== 'string')
10
10
  throw new TypeError('Key needs to be a string with content');
11
- const copy = new Date(Date.UTC(val.getUTCFullYear(), val.getUTCMonth(), val.getUTCDate(), val.getUTCHours(), val.getUTCMinutes(), val.getUTCSeconds(), val.getUTCMilliseconds()));
11
+ const year = val.getUTCFullYear();
12
+ const month = val.getUTCMonth();
13
+ const date = val.getUTCDate();
14
+ const hour = val.getUTCHours();
15
+ const min = val.getUTCMinutes();
16
+ const sec = val.getUTCSeconds();
17
+ const ms = val.getUTCMilliseconds();
12
18
  switch (key) {
13
19
  case 'years':
14
- case 'year': {
15
- copy.setUTCFullYear(copy.getUTCFullYear() + amount);
16
- return copy;
17
- }
20
+ case 'year':
21
+ return new Date(Date.UTC(year + amt, month, date, hour, min, sec, ms));
18
22
  case 'months':
19
- case 'month': {
20
- copy.setUTCMonth(copy.getUTCMonth() + amount);
21
- return copy;
22
- }
23
+ case 'month':
24
+ return new Date(Date.UTC(year, month + amt, date, hour, min, sec, ms));
23
25
  case 'days':
24
- case 'day': {
25
- copy.setUTCDate(copy.getUTCDate() + amount);
26
- return copy;
27
- }
26
+ case 'day':
27
+ return new Date(Date.UTC(year, month, date + amt, hour, min, sec, ms));
28
28
  case 'hours':
29
- case 'hour': {
30
- copy.setUTCHours(copy.getUTCHours() + amount);
31
- return copy;
32
- }
29
+ case 'hour':
30
+ return new Date(Date.UTC(year, month, date, hour + amt, min, sec, ms));
33
31
  case 'minutes':
34
- case 'minute': {
35
- copy.setUTCMinutes(copy.getUTCMinutes() + amount);
36
- return copy;
37
- }
32
+ case 'minute':
33
+ return new Date(Date.UTC(year, month, date, hour, min + amt, sec, ms));
38
34
  case 'seconds':
39
- case 'second': {
40
- copy.setUTCSeconds(copy.getUTCSeconds() + amount);
41
- return copy;
42
- }
35
+ case 'second':
36
+ return new Date(Date.UTC(year, month, date, hour, min, sec + amt, ms));
43
37
  case 'milliseconds':
44
- case 'millisecond': {
45
- copy.setUTCMilliseconds(copy.getUTCMilliseconds() + amount);
46
- return copy;
47
- }
38
+ case 'millisecond':
39
+ return new Date(Date.UTC(year, month, date, hour, min, sec, ms + amt));
48
40
  default:
49
- return copy;
41
+ return new Date(Date.UTC(year, month, date, hour, min, sec, ms));
50
42
  }
51
43
  }
52
44
  exports.default = addUTC;
package/date/diff.js CHANGED
@@ -29,8 +29,6 @@ function diff(val_a, val_b, key = 'millisecond') {
29
29
  case 'second':
30
30
  case 'seconds':
31
31
  return diff_in_ms / SECOND_IN_MILLISECONDS;
32
- case 'millisecond':
33
- case 'milliseconds':
34
32
  default:
35
33
  return diff_in_ms;
36
34
  }
package/date/endOfUTC.js CHANGED
@@ -1,16 +1,16 @@
1
1
  'use strict';
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const is_1 = require("./is");
4
- const WEEK_END = {
5
- week: 0,
6
- week_sun: 6,
7
- week_mon: 0,
8
- week_tue: 1,
9
- week_wed: 2,
10
- week_thu: 3,
11
- week_fri: 4,
12
- week_sat: 5,
13
- };
4
+ const WEEK_END = new Map([
5
+ ['week', 0],
6
+ ['week_sun', 6],
7
+ ['week_mon', 0],
8
+ ['week_tue', 1],
9
+ ['week_wed', 2],
10
+ ['week_thu', 3],
11
+ ['week_fri', 4],
12
+ ['week_sat', 5],
13
+ ]);
14
14
  function endOfUTC(val, key = 'millisecond') {
15
15
  if (!(0, is_1.default)(val))
16
16
  throw new TypeError('endOfUTC requires a date object');
@@ -20,7 +20,8 @@ function endOfUTC(val, key = 'millisecond') {
20
20
  case 'year':
21
21
  return new Date(Date.UTC(val.getUTCFullYear(), 11, 31, 23, 59, 59, 999));
22
22
  case 'quarter': {
23
- return new Date(Date.UTC(val.getUTCFullYear(), (val.getUTCMonth() - (val.getUTCMonth() % 3)) + 3, 0, 23, 59, 59, 999));
23
+ const UTC_MONTH = val.getUTCMonth();
24
+ return new Date(Date.UTC(val.getUTCFullYear(), (UTC_MONTH - (UTC_MONTH % 3)) + 3, 0, 23, 59, 59, 999));
24
25
  }
25
26
  case 'month':
26
27
  return new Date(Date.UTC(val.getUTCFullYear(), val.getUTCMonth() + 1, 0, 23, 59, 59, 999));
@@ -33,7 +34,7 @@ function endOfUTC(val, key = 'millisecond') {
33
34
  case 'week_fri':
34
35
  case 'week_sat': {
35
36
  const UTC_DAY = val.getUTCDay();
36
- const UTC_EOD = WEEK_END[key];
37
+ const UTC_EOD = WEEK_END.get(key);
37
38
  return new Date(Date.UTC(val.getUTCFullYear(), val.getUTCMonth(), val.getUTCDate() + (UTC_DAY <= UTC_EOD ? UTC_EOD - UTC_DAY : (7 - UTC_DAY) + UTC_EOD), 23, 59, 59, 999));
38
39
  }
39
40
  case 'day':
@@ -44,7 +45,6 @@ function endOfUTC(val, key = 'millisecond') {
44
45
  return new Date(Date.UTC(val.getUTCFullYear(), val.getUTCMonth(), val.getUTCDate(), val.getUTCHours(), val.getUTCMinutes(), 59, 999));
45
46
  case 'second':
46
47
  return new Date(Date.UTC(val.getUTCFullYear(), val.getUTCMonth(), val.getUTCDate(), val.getUTCHours(), val.getUTCMinutes(), val.getUTCSeconds(), 999));
47
- case 'millisecond':
48
48
  default:
49
49
  return new Date(Date.UTC(val.getUTCFullYear(), val.getUTCMonth(), val.getUTCDate(), val.getUTCHours(), val.getUTCMinutes(), val.getUTCSeconds(), val.getUTCMilliseconds()));
50
50
  }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Formats the provided date according to a specific spec
3
+ *
4
+ * @param {Date} val - Date to format
5
+ * @param {string} spec - Spec to format the date to
6
+ * @param {string} locale - Locale to format the date in (only used in certain tokens such as dddd and MMMM)
7
+ * @param {string} zone - (default=current timezone) Pass the timezone to convert into. If not passed no conversion will happen
8
+ * @returns {string} Formatted date as string
9
+ * @throws {TypeError} When provided invalid payload
10
+ */
11
+ export default function format(val: Date, spec: string, locale?: string, zone?: string): string;
package/date/format.js ADDED
@@ -0,0 +1,125 @@
1
+ 'use strict';
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const is_1 = require("./is");
4
+ const DEFAULT_LOCALE = 'en-US';
5
+ let DEFAULT_TZ = 'UTC';
6
+ try {
7
+ DEFAULT_TZ = Intl.DateTimeFormat().resolvedOptions().timeZone;
8
+ }
9
+ catch (err) {
10
+ }
11
+ finally {
12
+ if (typeof DEFAULT_TZ !== 'string')
13
+ DEFAULT_TZ = 'UTC';
14
+ }
15
+ const escape_rgx = /\[[\s\S]+?]/g;
16
+ const intl_formatters = new Map();
17
+ const spec_cache = new Map();
18
+ const zone_offset_cache = new Map();
19
+ function DOY(d) {
20
+ return Math.floor((d - new Date(d.getFullYear(), 0, 0)) / 86400000);
21
+ }
22
+ function toZone(date, zone) {
23
+ const ckey = `${zone}:${date.getUTCFullYear()}${DOY(date)}`;
24
+ if (zone_offset_cache.has(ckey))
25
+ return new Date(date.getTime() + zone_offset_cache.get(ckey));
26
+ const client_time = date.getTime();
27
+ let zone_time = false;
28
+ try {
29
+ zone_time = new Date(date.toLocaleString(DEFAULT_LOCALE, { timeZone: zone })).getTime();
30
+ }
31
+ catch (err) {
32
+ }
33
+ if (!Number.isInteger(zone_time))
34
+ throw new Error(`format: Invalid zone passed - ${zone}`);
35
+ const offset = zone_time - client_time;
36
+ zone_offset_cache.set(ckey, offset);
37
+ return new Date(date.getTime() + offset);
38
+ }
39
+ function runIntl(loc, token, props, val) {
40
+ const hash = `${loc}:${token}`;
41
+ if (intl_formatters.has(hash))
42
+ return intl_formatters.get(hash).format(val);
43
+ try {
44
+ const instance = new Intl.DateTimeFormat(loc, props);
45
+ intl_formatters.set(hash, instance);
46
+ return instance.format(val);
47
+ }
48
+ catch (err) {
49
+ throw new Error(`format: Failed to run conversion for ${token} with locale ${loc}`);
50
+ }
51
+ }
52
+ const Tokens = [
53
+ ['YYYY', d => d.getFullYear()],
54
+ ['Q', d => Math.floor((d.getMonth() + 3) / 3)],
55
+ ['MMMM', (d, loc) => runIntl(loc, 'MMMM', { month: 'long' }, d)],
56
+ ['MMM', (d, loc) => runIntl(loc, 'MMM', { month: 'short' }, d)],
57
+ ['MM', d => `${d.getMonth() + 1}`.padStart(2, '0')],
58
+ ['M', d => d.getMonth() + 1],
59
+ ['DD', d => `${d.getDate()}`.padStart(2, '0')],
60
+ ['D', d => d.getDate()],
61
+ ['dddd', (d, loc) => runIntl(loc, 'dddd', { weekday: 'long' }, d)],
62
+ ['ddd', (d, loc) => runIntl(loc, 'ddd', { weekday: 'short' }, d)],
63
+ ['HH', d => `${d.getHours()}`.padStart(2, '0')],
64
+ ['H', d => d.getHours()],
65
+ ['hh', d => `${((d.getHours() + 11) % 12) + 1}`.padStart(2, '0')],
66
+ ['h', d => ((d.getHours() + 11) % 12) + 1],
67
+ ['mm', d => `${d.getMinutes()}`.padStart(2, '0')],
68
+ ['m', d => d.getMinutes()],
69
+ ['ss', d => `${d.getSeconds()}`.padStart(2, '0')],
70
+ ['s', d => d.getSeconds()],
71
+ ['SSS', d => `${d.getMilliseconds()}`.padStart(3, '0')],
72
+ ['A', d => d.getHours() < 12 ? 'AM' : 'PM'],
73
+ ['a', d => d.getHours() < 12 ? 'am' : 'pm'],
74
+ ]
75
+ .sort((a, b) => a[0].length > b[0].length ? -1 : 1)
76
+ .map((el) => [el[0], new RegExp(el[0], 'g'), el[1]]);
77
+ function getSpecChain(spec) {
78
+ if (spec_cache.has(spec))
79
+ return spec_cache.get(spec);
80
+ const spec_chain = [];
81
+ let cursor;
82
+ for (let i = 0; i < Tokens.length; i++) {
83
+ cursor = Tokens[i];
84
+ if (spec.indexOf(cursor[0]) < 0)
85
+ continue;
86
+ spec_chain.push(cursor);
87
+ }
88
+ if (spec_chain.length === 0)
89
+ return false;
90
+ spec_cache.set(spec, spec_chain);
91
+ return spec_chain;
92
+ }
93
+ function format(val, spec, locale = DEFAULT_LOCALE, zone = DEFAULT_TZ) {
94
+ if (!(0, is_1.default)(val))
95
+ throw new TypeError('format: val must be a Date');
96
+ if (typeof spec !== 'string' || !spec.trim().length)
97
+ throw new TypeError('format: spec must be a non-empty string');
98
+ if (typeof locale !== 'string' || !locale.trim().length)
99
+ throw new TypeError('format: locale must be a non-empty string');
100
+ if (typeof zone !== 'string' || !zone.trim().length)
101
+ throw new TypeError('format: zone must be a non-empty string');
102
+ let formatted_string = spec;
103
+ const escaped_acc = [];
104
+ if (formatted_string.indexOf('[') >= 0) {
105
+ formatted_string = formatted_string.replace(escape_rgx, match => {
106
+ const escape_token = `$R${escaped_acc.length}$`;
107
+ escaped_acc.push([escape_token, match.replace('[', '').replace(']', '')]);
108
+ return escape_token;
109
+ });
110
+ }
111
+ const spec_chain = getSpecChain(formatted_string);
112
+ if (!spec_chain)
113
+ return val.toISOString();
114
+ const d = toZone(val, zone);
115
+ for (const el of spec_chain) {
116
+ formatted_string = formatted_string.replace(el[1], el[2](d, locale));
117
+ }
118
+ if (escaped_acc.length) {
119
+ for (const escape_token of escaped_acc) {
120
+ formatted_string = formatted_string.replace(escape_token[0], escape_token[1]);
121
+ }
122
+ }
123
+ return formatted_string;
124
+ }
125
+ exports.default = format;
package/date/is.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  function isDate(val) {
4
- return Object.prototype.toString.call(val) === '[object Date]' && !isNaN(val);
4
+ return val instanceof Date && !isNaN(val);
5
5
  }
6
6
  exports.default = isDate;
@@ -1,16 +1,16 @@
1
1
  'use strict';
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const is_1 = require("./is");
4
- const WEEK_START = {
5
- week: 1,
6
- week_sun: 0,
7
- week_mon: 1,
8
- week_tue: 2,
9
- week_wed: 3,
10
- week_thu: 4,
11
- week_fri: 5,
12
- week_sat: 6,
13
- };
4
+ const WEEK_START = new Map([
5
+ ['week', 1],
6
+ ['week_sun', 0],
7
+ ['week_mon', 1],
8
+ ['week_tue', 2],
9
+ ['week_wed', 3],
10
+ ['week_thu', 4],
11
+ ['week_fri', 5],
12
+ ['week_sat', 6],
13
+ ]);
14
14
  function startOfUTC(val, key = 'millisecond') {
15
15
  if (!(0, is_1.default)(val))
16
16
  throw new TypeError('startOfUTC requires a date object');
@@ -20,7 +20,8 @@ function startOfUTC(val, key = 'millisecond') {
20
20
  case 'year':
21
21
  return new Date(Date.UTC(val.getUTCFullYear(), 0, 1, 0, 0, 0, 0));
22
22
  case 'quarter': {
23
- return new Date(Date.UTC(val.getUTCFullYear(), val.getUTCMonth() - (val.getUTCMonth() % 3), 1, 0, 0, 0, 0));
23
+ const UTC_MONTH = val.getUTCMonth();
24
+ return new Date(Date.UTC(val.getUTCFullYear(), UTC_MONTH - (UTC_MONTH % 3), 1, 0, 0, 0, 0));
24
25
  }
25
26
  case 'month':
26
27
  return new Date(Date.UTC(val.getUTCFullYear(), val.getUTCMonth(), 1, 0, 0, 0, 0));
@@ -33,7 +34,7 @@ function startOfUTC(val, key = 'millisecond') {
33
34
  case 'week_fri':
34
35
  case 'week_sat': {
35
36
  const UTC_DAY = val.getUTCDay();
36
- const UTC_SOD = WEEK_START[key];
37
+ const UTC_SOD = WEEK_START.get(key);
37
38
  return new Date(Date.UTC(val.getUTCFullYear(), val.getUTCMonth(), val.getUTCDate() - (UTC_DAY < UTC_SOD ? (7 - UTC_SOD) + UTC_DAY : UTC_DAY - UTC_SOD), 0, 0, 0, 0));
38
39
  }
39
40
  case 'day':
@@ -44,7 +45,6 @@ function startOfUTC(val, key = 'millisecond') {
44
45
  return new Date(Date.UTC(val.getUTCFullYear(), val.getUTCMonth(), val.getUTCDate(), val.getUTCHours(), val.getUTCMinutes(), 0, 0));
45
46
  case 'second':
46
47
  return new Date(Date.UTC(val.getUTCFullYear(), val.getUTCMonth(), val.getUTCDate(), val.getUTCHours(), val.getUTCMinutes(), val.getUTCSeconds(), 0));
47
- case 'millisecond':
48
48
  default:
49
49
  return new Date(Date.UTC(val.getUTCFullYear(), val.getUTCMonth(), val.getUTCDate(), val.getUTCHours(), val.getUTCMinutes(), val.getUTCSeconds(), val.getUTCMilliseconds()));
50
50
  }
package/deep/get.js CHANGED
@@ -7,19 +7,19 @@ function deepGet(obj, path, get_parent = false) {
7
7
  if (typeof path !== 'string')
8
8
  throw new TypeError('No path was given');
9
9
  const path_s = path.trim();
10
- if (path_s.length === 0)
10
+ if (!path_s.length)
11
11
  throw new TypeError('No path was given');
12
12
  const parts = path_s
13
13
  .replace(/\[/g, '.')
14
14
  .replace(/(\.){2,}/g, '.')
15
15
  .replace(/(^\.|\.$|\])/g, '')
16
16
  .split('.');
17
- if (parts.length === 0 || (parts.length === 1 && get_parent))
17
+ if (!parts.length || (parts.length === 1 && get_parent))
18
18
  return obj;
19
19
  if (get_parent)
20
20
  parts.pop();
21
21
  let cursor = obj;
22
- while (parts.length > 0) {
22
+ while (parts.length) {
23
23
  if (Array.isArray(cursor)) {
24
24
  const ix = parseInt(parts.shift());
25
25
  if (!Number.isInteger(ix) || ix < 0 || ix > (cursor.length - 1))
@@ -33,7 +33,7 @@ function deepGet(obj, path, get_parent = false) {
33
33
  cursor = cursor[key];
34
34
  }
35
35
  if ((!Array.isArray(cursor) && Object.prototype.toString.call(cursor) !== '[object Object]') &&
36
- parts.length > 0)
36
+ parts.length)
37
37
  return undefined;
38
38
  }
39
39
  return cursor;
package/deep/set.js CHANGED
@@ -9,7 +9,7 @@ function deepSet(obj, path, value, define = false) {
9
9
  if (/__proto__|constructor|prototype/.test(path))
10
10
  throw new TypeError('Malicious path provided');
11
11
  const path_s = path.trim();
12
- if (path_s.length === 0)
12
+ if (!path_s.length)
13
13
  throw new TypeError('No path was given');
14
14
  const parts = path_s
15
15
  .replace(/\[/g, '.')
package/equal.js CHANGED
@@ -23,21 +23,17 @@ function isObjectEqual(a, b) {
23
23
  return true;
24
24
  }
25
25
  function equal(a, b) {
26
- if (a instanceof Date &&
27
- b instanceof Date)
28
- return a.valueOf() === b.valueOf();
29
- if (Object.prototype.toString.call(a) === '[object RegExp]' &&
30
- Object.prototype.toString.call(b) === '[object RegExp]')
31
- return String(a) === String(b);
32
- if (Array.isArray(a) &&
33
- Array.isArray(b))
34
- return isArrayEqual(a, b);
35
- if (Object.prototype.toString.call(a) === '[object Object]' &&
36
- Object.prototype.toString.call(b) === '[object Object]')
37
- return isObjectEqual(a, b);
38
- if ((0, isNumericalNaN_1.default)(a)) {
39
- return (0, isNumericalNaN_1.default)(b);
26
+ if (a instanceof Date)
27
+ return b instanceof Date && a.valueOf() === b.valueOf();
28
+ if (a instanceof RegExp)
29
+ return b instanceof RegExp && String(a) === String(b);
30
+ if (Array.isArray(a))
31
+ return Array.isArray(b) && isArrayEqual(a, b);
32
+ if (Object.prototype.toString.call(a) === '[object Object]') {
33
+ return Object.prototype.toString.call(b) === '[object Object]' && isObjectEqual(a, b);
40
34
  }
35
+ if ((0, isNumericalNaN_1.default)(a))
36
+ return (0, isNumericalNaN_1.default)(b);
41
37
  return a === b;
42
38
  }
43
39
  exports.default = equal;
package/hash/fnv1A.js CHANGED
@@ -18,7 +18,7 @@ function fnv1A(data, offset = FNV_32) {
18
18
  else if (Array.isArray(data) || Object.prototype.toString.call(data) === '[object Object]') {
19
19
  sanitized = JSON.stringify(data);
20
20
  }
21
- else if (Object.prototype.toString.call(data) === '[object RegExp]') {
21
+ else if (data instanceof RegExp) {
22
22
  sanitized = data.toString();
23
23
  }
24
24
  else if (data instanceof Date) {
package/index.d.ts CHANGED
@@ -232,7 +232,7 @@ declare module "caching/memoize" {
232
232
  export default function memoize(fn: Function, resolver?: Function): Function;
233
233
  }
234
234
  declare module "date/addUTC" {
235
- export default function addUTC(val: Date, amount?: number, key?: 'years' | 'year' | 'months' | 'month' | 'days' | 'day' | 'hours' | 'hour' | 'minutes' | 'minute' | 'seconds' | 'second' | 'milliseconds' | 'millisecond'): Date;
235
+ export default function addUTC(val: Date, amt?: number, key?: 'years' | 'year' | 'months' | 'month' | 'days' | 'day' | 'hours' | 'hour' | 'minutes' | 'minute' | 'seconds' | 'second' | 'milliseconds' | 'millisecond'): Date;
236
236
  }
237
237
  declare module "date/diff" {
238
238
  export default function diff(val_a: Date, val_b: Date, key?: 'week' | 'weeks' | 'day' | 'days' | 'hour' | 'hours' | 'minute' | 'minutes' | 'second' | 'seconds' | 'millisecond' | 'milliseconds'): number;
@@ -240,6 +240,9 @@ declare module "date/diff" {
240
240
  declare module "date/endOfUTC" {
241
241
  export default function endOfUTC(val: Date, key?: 'year' | 'quarter' | 'month' | 'week' | 'week_sun' | 'week_mon' | 'week_tue' | 'week_wed' | 'week_thu' | 'week_fri' | 'week_sat' | 'day' | 'hour' | 'minute' | 'second' | 'millisecond'): Date;
242
242
  }
243
+ declare module "date/format" {
244
+ export default function format(val: Date, spec: string, locale?: string, zone?: string): string;
245
+ }
243
246
  declare module "date/nowUnix" {
244
247
  export default function nowUnix(): number;
245
248
  }
package/object/pick.js CHANGED
@@ -5,7 +5,7 @@ const set_1 = require("../deep/set");
5
5
  function pick(obj, keys) {
6
6
  if (Object.prototype.toString.call(obj) !== '[object Object]' ||
7
7
  !Array.isArray(keys) ||
8
- keys.length === 0)
8
+ !keys.length)
9
9
  throw new TypeError('Please pass an object to pick from and a keys array');
10
10
  const map = {};
11
11
  let val;
@@ -14,7 +14,7 @@ function pick(obj, keys) {
14
14
  if (typeof key !== 'string')
15
15
  continue;
16
16
  sanitized = key.trim();
17
- if (sanitized.length === 0)
17
+ if (!sanitized.length)
18
18
  continue;
19
19
  if (/(\.|\[)/g.test(sanitized)) {
20
20
  val = (0, get_1.default)(obj, sanitized);
package/package.json CHANGED
@@ -1 +1 @@
1
- { "name": "@valkyriestudios/utils", "version": "11.7.0", "description": "A collection of single-function utilities for common tasks", "author": { "name": "Peter Vermeulen", "email": "contact@valkyriestudios.be", "url": "www.valkyriestudios.be" }, "keywords": [ "utility", "library", "javascript", "js", "node", "bun" ], "license": "MIT", "repository": { "type": "git", "url": "git+https://github.com/ValkyrieStudios/utils.git" }, "bugs": { "url": "https://github.com/ValkyrieStudios/utils/issues" }, "homepage": "https://github.com/ValkyrieStudios/utils#readme", "types": "index.d.ts" }
1
+ { "name": "@valkyriestudios/utils", "version": "12.0.0", "description": "A collection of single-function utilities for common tasks", "author": { "name": "Peter Vermeulen", "email": "contact@valkyriestudios.be", "url": "www.valkyriestudios.be" }, "keywords": [ "utility", "library", "javascript", "js", "node", "bun" ], "license": "MIT", "repository": { "type": "git", "url": "git+https://github.com/ValkyrieStudios/utils.git" }, "bugs": { "url": "https://github.com/ValkyrieStudios/utils/issues" }, "homepage": "https://github.com/ValkyrieStudios/utils#readme", "types": "index.d.ts" }
package/regexp/is.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  function isRegExp(val) {
4
- return Object.prototype.toString.call(val) === '[object RegExp]';
4
+ return val instanceof RegExp;
5
5
  }
6
6
  exports.default = isRegExp;
@@ -8,13 +8,13 @@ function humanizeBytes(val, options = {}) {
8
8
  delim: has_opts && typeof options.delim === 'string'
9
9
  ? options.delim
10
10
  : ',',
11
- separator: has_opts && typeof options.separator === 'string' && options.separator.trim().length > 0
11
+ separator: has_opts && typeof options.separator === 'string' && options.separator.trim().length
12
12
  ? options.separator
13
13
  : '.',
14
14
  precision: has_opts && Number.isInteger(options.precision) && options.precision >= 0
15
15
  ? options.precision
16
16
  : 2,
17
- units: has_opts && Array.isArray(options.units) && options.units.length > 0
17
+ units: has_opts && Array.isArray(options.units) && options.units.length
18
18
  ? options.units.filter(el => (0, isNotEmpty_1.default)(el))
19
19
  : [' bytes', ' KB', ' MB', ' GB', ' TB', ' PB', ' EB', ' ZB', ' YB'],
20
20
  divider: 1024,
@@ -9,13 +9,13 @@ function humanizeNumber(val, options = {}) {
9
9
  delim: has_opts && typeof options.delim === 'string'
10
10
  ? options.delim
11
11
  : ',',
12
- separator: has_opts && typeof options.separator === 'string' && options.separator.trim().length > 0
12
+ separator: has_opts && typeof options.separator === 'string' && options.separator.trim().length
13
13
  ? options.separator
14
14
  : '.',
15
15
  precision: has_opts && Number.isInteger(options.precision) && options.precision >= 0
16
16
  ? options.precision
17
17
  : 2,
18
- units: has_opts && ((Array.isArray(options.units) && options.units.length > 0) || options.units === false)
18
+ units: has_opts && ((Array.isArray(options.units) && options.units.length) || options.units === false)
19
19
  ? options.units ? options.units.filter(is_2.default) : false
20
20
  : ['', 'k', 'm', 'b', 't', 'q'],
21
21
  divider: has_opts && Number.isInteger(options.divider) && options.divider > 1
@@ -33,18 +33,15 @@ function humanizeNumber(val, options = {}) {
33
33
  normalized = typeof val === 'string' ? parseFloat(val) : Number.isFinite(val) ? val : 0;
34
34
  }
35
35
  if (!Number.isFinite(normalized) || normalized === 0) {
36
- return `0${Array.isArray(OPTS.units) && OPTS.units.length > 0 ? OPTS.units[0] : ''}`;
36
+ return `0${Array.isArray(OPTS.units) && OPTS.units.length ? OPTS.units[0] : ''}`;
37
37
  }
38
38
  const sign = normalized < 0 ? '-' : '';
39
39
  normalized = Math.abs(normalized);
40
40
  let postfix = '';
41
- if (Array.isArray(OPTS.units) && OPTS.units.length > 0) {
41
+ if (Array.isArray(OPTS.units) && OPTS.units.length) {
42
42
  let unit_ix = 0;
43
- while (normalized >= OPTS.divider) {
44
- unit_ix++;
45
- normalized = normalized / OPTS.divider;
46
- if (unit_ix === OPTS.units.length - 1)
47
- break;
43
+ for (unit_ix; normalized >= OPTS.divider && unit_ix < OPTS.units.length - 1; unit_ix++) {
44
+ normalized /= OPTS.divider;
48
45
  }
49
46
  postfix = OPTS.units[unit_ix];
50
47
  }