@alextheman/utility 5.19.2 → 5.21.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/dist/index.cjs CHANGED
@@ -115,7 +115,7 @@ var CodeError = class CodeError extends Error {
115
115
  */
116
116
  static check(input) {
117
117
  if (input instanceof CodeError) return true;
118
- return typeof input === "object" && input !== null && "message" in input && typeof input.message === "string" && "code" in input && typeof input.code === "string";
118
+ return containsKeys(input, ["message", "code"]) && typeof input.message === "string" && typeof input.code === "string";
119
119
  }
120
120
  static checkCaughtError(error, options) {
121
121
  if (this.check(error)) {
@@ -228,7 +228,11 @@ var DataError$1 = class DataError$1 extends CodeError {
228
228
  */
229
229
  static check(input) {
230
230
  if (input instanceof DataError$1) return true;
231
- return typeof input === "object" && input !== null && "message" in input && typeof input.message === "string" && "code" in input && typeof input.code === "string" && "data" in input && typeof input.data === "object" && input.data !== null;
231
+ return containsKeys(input, [
232
+ "data",
233
+ "code",
234
+ "message"
235
+ ]) && typeof input.message === "string" && typeof input.code === "string" && isNonNullableObject(input.data);
232
236
  }
233
237
  /**
234
238
  * Check a `DataError` against its error code
@@ -325,6 +329,107 @@ function range(start, stop, step = 1) {
325
329
  return numbers;
326
330
  }
327
331
  //#endregion
332
+ //#region src/root/functions/typeAssertions/assertNotNull.ts
333
+ /**
334
+ * Asserts that a given input is not `null`, and throws a DataError if it does.
335
+ *
336
+ * If no error is thrown from this, the input type gets narrowed down to not include `null`.
337
+ *
338
+ * @category Type Assertions
339
+ *
340
+ * @template InputType The type of the input.
341
+ *
342
+ * @param input - The input to assert against
343
+ *
344
+ * @throws {DataError} If the input is `null`.
345
+ */
346
+ function assertNotNull(input) {
347
+ if (input === null) throw new DataError$1({ input }, "NULL_INPUT", "Expected the input not to be null");
348
+ }
349
+ //#endregion
350
+ //#region src/root/functions/typeAssertions/assertNotNullable.ts
351
+ /**
352
+ * Asserts that a given input is not `undefined` or `null`, and throws a DataError if it does.
353
+ *
354
+ * If no error is thrown from this, the input type gets narrowed down to not include `undefined` or `null`.
355
+ *
356
+ * @category Type Assertions
357
+ *
358
+ * @template InputType The type of the input.
359
+ *
360
+ * @param input - The input to assert against.
361
+ *
362
+ * @throws {DataError} If the input is `undefined` or `null`.
363
+ */
364
+ function assertNotNullable(input) {
365
+ if (input === null || input === void 0) throw new DataError$1({ input }, "NULLABLE_INPUT", "Expected the input not to be undefined or null");
366
+ }
367
+ //#endregion
368
+ //#region src/root/functions/typeAssertions/assertNotUndefined.ts
369
+ /**
370
+ * Asserts that a given input is not `undefined`, and throws a DataError if it does.
371
+ *
372
+ * If no error is thrown from this, the input type gets narrowed down to not include `undefined`.
373
+ *
374
+ * @category Type Assertions
375
+ *
376
+ * @template InputType The type of the input.
377
+ *
378
+ * @param input - The input to assert against.
379
+ *
380
+ * @throws {DataError} If the input is `undefined`.
381
+ */
382
+ function assertNotUndefined(input) {
383
+ if (input === void 0) throw new DataError$1({ input }, "UNDEFINED_INPUT", "Expected the input not to be undefined");
384
+ }
385
+ //#endregion
386
+ //#region src/root/functions/typeAssertions/isNonNullableObject.ts
387
+ /**
388
+ * Determines if the given input is a non-nullable object, narrowing the type down as such if it is
389
+ *
390
+ * @category Type Assertions
391
+ *
392
+ * @param input - The input to check
393
+ *
394
+ * @returns `true` if the input is a non-nullable object, and `false` otherwise. The input type will also be narrowed down to be a non-nullable object.
395
+ */
396
+ function isNonNullableObject(input) {
397
+ return typeof input === "object" && input !== null;
398
+ }
399
+ //#endregion
400
+ //#region src/root/functions/typeAssertions/objectContainsKeys.ts
401
+ /**
402
+ * Determines if the given object contains all of the keys provided.
403
+ *
404
+ * @category Type Assertions
405
+ *
406
+ * @param input - The input object to check.
407
+ * @param keys - The keys expected to be in the input object.
408
+ *
409
+ * @returns `true` if the input object contains all provided keys, and `false` otherwise. The input type will also be narrowed down to be a record with the provided keys with an unknown value type.
410
+ */
411
+ function objectContainsKeys(input, keys) {
412
+ const expectedKeys = Array.isArray(keys) ? keys : [keys];
413
+ if (expectedKeys.length === 0) return false;
414
+ for (const key of expectedKeys) if (!(key in input)) return false;
415
+ return true;
416
+ }
417
+ //#endregion
418
+ //#region src/root/functions/typeAssertions/containsKeys.ts
419
+ /**
420
+ * Determines if the given input is a non-nullable object, and if that object contains all of the keys provided.
421
+ *
422
+ * @category Type Assertions
423
+ *
424
+ * @param input - The input to check.
425
+ * @param keys - The keys expected to be in the input if it's an object.
426
+ *
427
+ * @returns `true` if the input is an object containing all provided keys, and `false` otherwise. The input type will also be narrowed down to be a record with the provided keys, each with an unknown value type.
428
+ */
429
+ function containsKeys(input, keys) {
430
+ return isNonNullableObject(input) && objectContainsKeys(input, keys);
431
+ }
432
+ //#endregion
328
433
  //#region src/root/functions/arrayHelpers/fillArray.ts
329
434
  /**
330
435
  * Creates a new array where each element is the result of the provided callback.
@@ -352,7 +457,7 @@ function fillArray(callback, length = 1, options) {
352
457
  return callback(index);
353
458
  });
354
459
  if (outputArray.some((item) => {
355
- return item instanceof Promise || typeof item === "object" && item !== null && "then" in item && typeof item.then === "function";
460
+ return item instanceof Promise || containsKeys(item, "then") && typeof item.then === "function";
356
461
  })) return Promise.all(outputArray);
357
462
  return outputArray;
358
463
  }
@@ -653,7 +758,7 @@ function convertFileToBase64(file) {
653
758
  //#endregion
654
759
  //#region src/root/functions/miscellaneous/createFormData.ts
655
760
  function getNullableResolutionStrategy(key, strategy) {
656
- return (typeof strategy === "object" ? strategy[key] : strategy) ?? "empty";
761
+ return (isNonNullableObject(strategy) ? strategy[key] : strategy) ?? "empty";
657
762
  }
658
763
  function isPrimitive(item) {
659
764
  return typeof item === "string" || typeof item === "number" || typeof item === "boolean";
@@ -722,6 +827,20 @@ function createFormData(data, options = {
722
827
  return formData;
723
828
  }
724
829
  //#endregion
830
+ //#region src/root/functions/miscellaneous/identity.ts
831
+ /**
832
+ * Gives back the original input.
833
+ *
834
+ * @template InputType - The input type.
835
+ *
836
+ * @param input - The input value.
837
+ *
838
+ * @returns The original input value.
839
+ */
840
+ function identity(input) {
841
+ return input;
842
+ }
843
+ //#endregion
725
844
  //#region src/root/functions/miscellaneous/isOrdered.ts
726
845
  /**
727
846
  * Checks to see if the given array is sorted in ascending order.
@@ -852,6 +971,33 @@ I'll commit to you!
852
971
  `;
853
972
  }
854
973
  //#endregion
974
+ //#region src/root/functions/miscellaneous/sortBy.ts
975
+ /**
976
+ * Provides a function to pass to the `sort` or `toSorted` methods on arrays, which will allow those methods to sort the items by the chosen value in the chosen direction.
977
+ *
978
+ * @template ItemType - The type of each array item.
979
+ * @template SortValue - The type of the value to sort by.
980
+ *
981
+ * @param selector - A function that takes the item and returns the value to sort by.
982
+ * @param direction - The sort direction.
983
+ *
984
+ * @returns A function to pass into the `.sort()` or `.toSorted()` methods on arrays.
985
+ */
986
+ function sortBy(selector, direction = "asc") {
987
+ return (first, second) => {
988
+ const firstValue = selector(first);
989
+ const secondValue = selector(second);
990
+ if (firstValue instanceof Date && secondValue instanceof Date) {
991
+ const firstTime = firstValue.getTime();
992
+ const secondTime = secondValue.getTime();
993
+ return direction === "asc" ? firstTime - secondTime : secondTime - firstTime;
994
+ }
995
+ if (firstValue < secondValue) return direction === "asc" ? -1 : 1;
996
+ if (firstValue > secondValue) return direction === "asc" ? 1 : -1;
997
+ return 0;
998
+ };
999
+ }
1000
+ //#endregion
855
1001
  //#region src/root/functions/miscellaneous/stringifyDotenv.ts
856
1002
  /**
857
1003
  * Converts an object into a string in .env file format.
@@ -996,6 +1142,12 @@ function parseBoolean(inputString) {
996
1142
  return normalisedString === "true";
997
1143
  }
998
1144
  //#endregion
1145
+ //#region src/root/types/SortDirection.ts
1146
+ const SortDirection = {
1147
+ DESC: "desc",
1148
+ ASC: "asc"
1149
+ };
1150
+ //#endregion
999
1151
  //#region src/root/types/VersionNumber.ts
1000
1152
  /**
1001
1153
  * Represents a software version number, considered to be made up of a major, minor, and patch part.
@@ -1354,7 +1506,7 @@ function parseVersionType(input) {
1354
1506
  //#endregion
1355
1507
  //#region src/root/functions/recursive/deepCopy.ts
1356
1508
  function callDeepCopy(input) {
1357
- return typeof input === "object" && input !== null ? deepCopy(input) : input;
1509
+ return isNonNullableObject(input) ? deepCopy(input) : input;
1358
1510
  }
1359
1511
  /**
1360
1512
  * Deeply copies an object or array such that all child objects/arrays are also copied.
@@ -1673,7 +1825,7 @@ function interpolateObjects(strings, ...interpolations) {
1673
1825
  * @returns `true` if the input is a valid `TemplateStringsArray`, and false otherwise. The type of the input will also be narrowed down to `TemplateStringsArray` if `true`.
1674
1826
  */
1675
1827
  function isTemplateStringsArray(input) {
1676
- return typeof input === "object" && input !== null && "raw" in input;
1828
+ return containsKeys(input, "raw");
1677
1829
  }
1678
1830
  //#endregion
1679
1831
  //#region src/root/functions/taggedTemplate/normaliseIndents.ts
@@ -1728,7 +1880,7 @@ function reduceLines(lines, { preserveTabs = true }) {
1728
1880
  * @returns An additional function to invoke, or a new string with the strings and interpolations from the template applied, and extraneous indents removed.
1729
1881
  */
1730
1882
  function normaliseIndents(first, ...args) {
1731
- if (typeof first === "object" && first !== null && !Array.isArray(first)) {
1883
+ if (isNonNullableObject(first) && !Array.isArray(first)) {
1732
1884
  const options = first;
1733
1885
  return (strings, ...interpolations) => {
1734
1886
  return normaliseIndents(strings, ...interpolations, options);
@@ -1855,60 +2007,13 @@ var DataError = class DataError extends Error {
1855
2007
  }
1856
2008
  };
1857
2009
  //#endregion
1858
- //#region src/root/errors/assertNotNull.ts
1859
- /**
1860
- * Asserts that a given input is not `null`, and throws a DataError if it does.
1861
- *
1862
- * If no error is thrown from this, the input type gets narrowed down to not include `null`.
1863
- *
1864
- * @template InputType The type of the input.
1865
- *
1866
- * @param input - The input to assert against
1867
- *
1868
- * @throws {DataError} If the input is `null`.
1869
- */
1870
- function assertNotNull(input) {
1871
- if (input === null) throw new DataError$1({ input }, "NULL_INPUT", "Expected the input not to be null");
1872
- }
1873
- //#endregion
1874
- //#region src/root/errors/assertNotNullable.ts
1875
- /**
1876
- * Asserts that a given input is not `undefined` or `null`, and throws a DataError if it does.
1877
- *
1878
- * If no error is thrown from this, the input type gets narrowed down to not include `undefined` or `null`.
1879
- *
1880
- * @template InputType The type of the input.
1881
- *
1882
- * @param input - The input to assert against.
1883
- *
1884
- * @throws {DataError} If the input is `undefined` or `null`.
1885
- */
1886
- function assertNotNullable(input) {
1887
- if (input === null || input === void 0) throw new DataError$1({ input }, "NULLABLE_INPUT", "Expected the input not to be undefined or null");
1888
- }
1889
- //#endregion
1890
- //#region src/root/errors/assertNotUndefined.ts
1891
- /**
1892
- * Asserts that a given input is not `undefined`, and throws a DataError if it does.
1893
- *
1894
- * If no error is thrown from this, the input type gets narrowed down to not include `undefined`.
1895
- *
1896
- * @template InputType The type of the input.
1897
- *
1898
- * @param input - The input to assert against.
1899
- *
1900
- * @throws {DataError} If the input is `undefined`.
1901
- */
1902
- function assertNotUndefined(input) {
1903
- if (input === void 0) throw new DataError$1({ input }, "UNDEFINED_INPUT", "Expected the input not to be undefined");
1904
- }
1905
- //#endregion
1906
2010
  exports.APIError = APIError;
1907
2011
  exports.DataError = DataError;
1908
2012
  exports.Env = Env;
1909
2013
  exports.FILE_PATH_PATTERN = FILE_PATH_PATTERN;
1910
2014
  exports.FILE_PATH_REGEX = FILE_PATH_REGEX;
1911
2015
  exports.ONE_DAY_IN_MILLISECONDS = ONE_DAY_IN_MILLISECONDS;
2016
+ exports.SortDirection = SortDirection;
1912
2017
  exports.UUID_PATTERN = UUID_PATTERN;
1913
2018
  exports.UUID_REGEX = UUID_REGEX;
1914
2019
  exports.VERSION_NUMBER_PATTERN = VERSION_NUMBER_PATTERN;
@@ -1923,6 +2028,7 @@ exports.assertNotUndefined = assertNotUndefined;
1923
2028
  exports.az = az;
1924
2029
  exports.calculateMonthlyDifference = calculateMonthlyDifference;
1925
2030
  exports.camelToKebab = camelToKebab;
2031
+ exports.containsKeys = containsKeys;
1926
2032
  exports.convertFileToBase64 = convertFileToBase64;
1927
2033
  exports.createFormData = createFormData;
1928
2034
  exports.createTemplateStringsArray = createTemplateStringsArray;
@@ -1935,17 +2041,20 @@ exports.getRandomNumber = getRandomNumber;
1935
2041
  exports.getRecordKeys = getRecordKeys;
1936
2042
  exports.getStringsAndInterpolations = getStringsAndInterpolations;
1937
2043
  exports.httpErrorCodeLookup = httpErrorCodeLookup;
2044
+ exports.identity = identity;
1938
2045
  exports.interpolate = interpolate;
1939
2046
  exports.interpolateObjects = interpolateObjects;
1940
2047
  exports.isAnniversary = isAnniversary;
1941
2048
  exports.isLeapYear = isLeapYear;
1942
2049
  exports.isMonthlyMultiple = isMonthlyMultiple;
2050
+ exports.isNonNullableObject = isNonNullableObject;
1943
2051
  exports.isOrdered = isOrdered;
1944
2052
  exports.isSameDate = isSameDate;
1945
2053
  exports.isTemplateStringsArray = isTemplateStringsArray;
1946
2054
  exports.kebabToCamel = kebabToCamel;
1947
2055
  exports.normaliseIndents = normaliseIndents;
1948
2056
  exports.normalizeIndents = normalizeIndents;
2057
+ exports.objectContainsKeys = objectContainsKeys;
1949
2058
  exports.omitProperties = omitProperties;
1950
2059
  exports.paralleliseArrays = paralleliseArrays;
1951
2060
  exports.parseBoolean = parseBoolean;
@@ -1961,6 +2070,7 @@ exports.range = range;
1961
2070
  exports.removeDuplicates = removeDuplicates;
1962
2071
  exports.removeUndefinedFromObject = removeUndefinedFromObject;
1963
2072
  exports.sayHello = sayHello;
2073
+ exports.sortBy = sortBy;
1964
2074
  exports.stringListToArray = stringListToArray;
1965
2075
  exports.stringifyDotenv = stringifyDotenv;
1966
2076
  exports.toTitleCase = toTitleCase;