@alextheman/utility 5.19.2 → 5.20.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.js CHANGED
@@ -91,7 +91,7 @@ var CodeError = class CodeError extends Error {
91
91
  */
92
92
  static check(input) {
93
93
  if (input instanceof CodeError) return true;
94
- return typeof input === "object" && input !== null && "message" in input && typeof input.message === "string" && "code" in input && typeof input.code === "string";
94
+ return containsKeys(input, ["message", "code"]) && typeof input.message === "string" && typeof input.code === "string";
95
95
  }
96
96
  static checkCaughtError(error, options) {
97
97
  if (this.check(error)) {
@@ -204,7 +204,11 @@ var DataError$1 = class DataError$1 extends CodeError {
204
204
  */
205
205
  static check(input) {
206
206
  if (input instanceof DataError$1) return true;
207
- 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;
207
+ return containsKeys(input, [
208
+ "data",
209
+ "code",
210
+ "message"
211
+ ]) && typeof input.message === "string" && typeof input.code === "string" && isNonNullableObject(input.data);
208
212
  }
209
213
  /**
210
214
  * Check a `DataError` against its error code
@@ -301,6 +305,107 @@ function range(start, stop, step = 1) {
301
305
  return numbers;
302
306
  }
303
307
  //#endregion
308
+ //#region src/root/functions/typeAssertions/assertNotNull.ts
309
+ /**
310
+ * Asserts that a given input is not `null`, and throws a DataError if it does.
311
+ *
312
+ * If no error is thrown from this, the input type gets narrowed down to not include `null`.
313
+ *
314
+ * @category Type Assertions
315
+ *
316
+ * @template InputType The type of the input.
317
+ *
318
+ * @param input - The input to assert against
319
+ *
320
+ * @throws {DataError} If the input is `null`.
321
+ */
322
+ function assertNotNull(input) {
323
+ if (input === null) throw new DataError$1({ input }, "NULL_INPUT", "Expected the input not to be null");
324
+ }
325
+ //#endregion
326
+ //#region src/root/functions/typeAssertions/assertNotNullable.ts
327
+ /**
328
+ * Asserts that a given input is not `undefined` or `null`, and throws a DataError if it does.
329
+ *
330
+ * If no error is thrown from this, the input type gets narrowed down to not include `undefined` or `null`.
331
+ *
332
+ * @category Type Assertions
333
+ *
334
+ * @template InputType The type of the input.
335
+ *
336
+ * @param input - The input to assert against.
337
+ *
338
+ * @throws {DataError} If the input is `undefined` or `null`.
339
+ */
340
+ function assertNotNullable(input) {
341
+ if (input === null || input === void 0) throw new DataError$1({ input }, "NULLABLE_INPUT", "Expected the input not to be undefined or null");
342
+ }
343
+ //#endregion
344
+ //#region src/root/functions/typeAssertions/assertNotUndefined.ts
345
+ /**
346
+ * Asserts that a given input is not `undefined`, and throws a DataError if it does.
347
+ *
348
+ * If no error is thrown from this, the input type gets narrowed down to not include `undefined`.
349
+ *
350
+ * @category Type Assertions
351
+ *
352
+ * @template InputType The type of the input.
353
+ *
354
+ * @param input - The input to assert against.
355
+ *
356
+ * @throws {DataError} If the input is `undefined`.
357
+ */
358
+ function assertNotUndefined(input) {
359
+ if (input === void 0) throw new DataError$1({ input }, "UNDEFINED_INPUT", "Expected the input not to be undefined");
360
+ }
361
+ //#endregion
362
+ //#region src/root/functions/typeAssertions/isNonNullableObject.ts
363
+ /**
364
+ * Determines if the given input is a non-nullable object, narrowing the type down as such if it is
365
+ *
366
+ * @category Type Assertions
367
+ *
368
+ * @param input - The input to check
369
+ *
370
+ * @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.
371
+ */
372
+ function isNonNullableObject(input) {
373
+ return typeof input === "object" && input !== null;
374
+ }
375
+ //#endregion
376
+ //#region src/root/functions/typeAssertions/objectContainsKeys.ts
377
+ /**
378
+ * Determines if the given object contains all of the keys provided.
379
+ *
380
+ * @category Type Assertions
381
+ *
382
+ * @param input - The input object to check.
383
+ * @param keys - The keys expected to be in the input object.
384
+ *
385
+ * @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.
386
+ */
387
+ function objectContainsKeys(input, keys) {
388
+ const expectedKeys = Array.isArray(keys) ? keys : [keys];
389
+ if (expectedKeys.length === 0) return false;
390
+ for (const key of expectedKeys) if (!(key in input)) return false;
391
+ return true;
392
+ }
393
+ //#endregion
394
+ //#region src/root/functions/typeAssertions/containsKeys.ts
395
+ /**
396
+ * Determines if the given input is a non-nullable object, and if that object contains all of the keys provided.
397
+ *
398
+ * @category Type Assertions
399
+ *
400
+ * @param input - The input to check.
401
+ * @param keys - The keys expected to be in the input if it's an object.
402
+ *
403
+ * @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.
404
+ */
405
+ function containsKeys(input, keys) {
406
+ return isNonNullableObject(input) && objectContainsKeys(input, keys);
407
+ }
408
+ //#endregion
304
409
  //#region src/root/functions/arrayHelpers/fillArray.ts
305
410
  /**
306
411
  * Creates a new array where each element is the result of the provided callback.
@@ -328,7 +433,7 @@ function fillArray(callback, length = 1, options) {
328
433
  return callback(index);
329
434
  });
330
435
  if (outputArray.some((item) => {
331
- return item instanceof Promise || typeof item === "object" && item !== null && "then" in item && typeof item.then === "function";
436
+ return item instanceof Promise || containsKeys(item, "then") && typeof item.then === "function";
332
437
  })) return Promise.all(outputArray);
333
438
  return outputArray;
334
439
  }
@@ -629,7 +734,7 @@ function convertFileToBase64(file) {
629
734
  //#endregion
630
735
  //#region src/root/functions/miscellaneous/createFormData.ts
631
736
  function getNullableResolutionStrategy(key, strategy) {
632
- return (typeof strategy === "object" ? strategy[key] : strategy) ?? "empty";
737
+ return (isNonNullableObject(strategy) ? strategy[key] : strategy) ?? "empty";
633
738
  }
634
739
  function isPrimitive(item) {
635
740
  return typeof item === "string" || typeof item === "number" || typeof item === "boolean";
@@ -1330,7 +1435,7 @@ function parseVersionType(input) {
1330
1435
  //#endregion
1331
1436
  //#region src/root/functions/recursive/deepCopy.ts
1332
1437
  function callDeepCopy(input) {
1333
- return typeof input === "object" && input !== null ? deepCopy(input) : input;
1438
+ return isNonNullableObject(input) ? deepCopy(input) : input;
1334
1439
  }
1335
1440
  /**
1336
1441
  * Deeply copies an object or array such that all child objects/arrays are also copied.
@@ -1649,7 +1754,7 @@ function interpolateObjects(strings, ...interpolations) {
1649
1754
  * @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`.
1650
1755
  */
1651
1756
  function isTemplateStringsArray(input) {
1652
- return typeof input === "object" && input !== null && "raw" in input;
1757
+ return containsKeys(input, "raw");
1653
1758
  }
1654
1759
  //#endregion
1655
1760
  //#region src/root/functions/taggedTemplate/normaliseIndents.ts
@@ -1704,7 +1809,7 @@ function reduceLines(lines, { preserveTabs = true }) {
1704
1809
  * @returns An additional function to invoke, or a new string with the strings and interpolations from the template applied, and extraneous indents removed.
1705
1810
  */
1706
1811
  function normaliseIndents(first, ...args) {
1707
- if (typeof first === "object" && first !== null && !Array.isArray(first)) {
1812
+ if (isNonNullableObject(first) && !Array.isArray(first)) {
1708
1813
  const options = first;
1709
1814
  return (strings, ...interpolations) => {
1710
1815
  return normaliseIndents(strings, ...interpolations, options);
@@ -1831,52 +1936,4 @@ var DataError = class DataError extends Error {
1831
1936
  }
1832
1937
  };
1833
1938
  //#endregion
1834
- //#region src/root/errors/assertNotNull.ts
1835
- /**
1836
- * Asserts that a given input is not `null`, and throws a DataError if it does.
1837
- *
1838
- * If no error is thrown from this, the input type gets narrowed down to not include `null`.
1839
- *
1840
- * @template InputType The type of the input.
1841
- *
1842
- * @param input - The input to assert against
1843
- *
1844
- * @throws {DataError} If the input is `null`.
1845
- */
1846
- function assertNotNull(input) {
1847
- if (input === null) throw new DataError$1({ input }, "NULL_INPUT", "Expected the input not to be null");
1848
- }
1849
- //#endregion
1850
- //#region src/root/errors/assertNotNullable.ts
1851
- /**
1852
- * Asserts that a given input is not `undefined` or `null`, and throws a DataError if it does.
1853
- *
1854
- * If no error is thrown from this, the input type gets narrowed down to not include `undefined` or `null`.
1855
- *
1856
- * @template InputType The type of the input.
1857
- *
1858
- * @param input - The input to assert against.
1859
- *
1860
- * @throws {DataError} If the input is `undefined` or `null`.
1861
- */
1862
- function assertNotNullable(input) {
1863
- if (input === null || input === void 0) throw new DataError$1({ input }, "NULLABLE_INPUT", "Expected the input not to be undefined or null");
1864
- }
1865
- //#endregion
1866
- //#region src/root/errors/assertNotUndefined.ts
1867
- /**
1868
- * Asserts that a given input is not `undefined`, and throws a DataError if it does.
1869
- *
1870
- * If no error is thrown from this, the input type gets narrowed down to not include `undefined`.
1871
- *
1872
- * @template InputType The type of the input.
1873
- *
1874
- * @param input - The input to assert against.
1875
- *
1876
- * @throws {DataError} If the input is `undefined`.
1877
- */
1878
- function assertNotUndefined(input) {
1879
- if (input === void 0) throw new DataError$1({ input }, "UNDEFINED_INPUT", "Expected the input not to be undefined");
1880
- }
1881
- //#endregion
1882
- export { APIError, DataError, Env, FILE_PATH_PATTERN, FILE_PATH_REGEX, ONE_DAY_IN_MILLISECONDS, UUID_PATTERN, UUID_REGEX, VERSION_NUMBER_PATTERN, VERSION_NUMBER_REGEX, VersionNumber, VersionType, addDaysToDate, appendSemicolon, assertNotNull, assertNotNullable, assertNotUndefined, az, calculateMonthlyDifference, camelToKebab, convertFileToBase64, createFormData, createTemplateStringsArray, deepCopy, deepFreeze, escapeRegexPattern, fillArray, formatDateAndTime, getRandomNumber, getRecordKeys, getStringsAndInterpolations, httpErrorCodeLookup, interpolate, interpolateObjects, isAnniversary, isLeapYear, isMonthlyMultiple, isOrdered, isSameDate, isTemplateStringsArray, kebabToCamel, normaliseIndents, normalizeIndents, omitProperties, paralleliseArrays, parseBoolean, parseEnv, parseFormData, parseIntStrict, parseUUID, parseVersionType, parseZodSchema, parseZodSchemaAsync, randomiseArray, range, removeDuplicates, removeUndefinedFromObject, sayHello, stringListToArray, stringifyDotenv, toTitleCase, truncate, wait, zodVersionNumber };
1939
+ export { APIError, DataError, Env, FILE_PATH_PATTERN, FILE_PATH_REGEX, ONE_DAY_IN_MILLISECONDS, UUID_PATTERN, UUID_REGEX, VERSION_NUMBER_PATTERN, VERSION_NUMBER_REGEX, VersionNumber, VersionType, addDaysToDate, appendSemicolon, assertNotNull, assertNotNullable, assertNotUndefined, az, calculateMonthlyDifference, camelToKebab, containsKeys, convertFileToBase64, createFormData, createTemplateStringsArray, deepCopy, deepFreeze, escapeRegexPattern, fillArray, formatDateAndTime, getRandomNumber, getRecordKeys, getStringsAndInterpolations, httpErrorCodeLookup, interpolate, interpolateObjects, isAnniversary, isLeapYear, isMonthlyMultiple, isNonNullableObject, isOrdered, isSameDate, isTemplateStringsArray, kebabToCamel, normaliseIndents, normalizeIndents, objectContainsKeys, omitProperties, paralleliseArrays, parseBoolean, parseEnv, parseFormData, parseIntStrict, parseUUID, parseVersionType, parseZodSchema, parseZodSchemaAsync, randomiseArray, range, removeDuplicates, removeUndefinedFromObject, sayHello, stringListToArray, stringifyDotenv, toTitleCase, truncate, wait, zodVersionNumber };
@@ -69,7 +69,7 @@ var CodeError = class CodeError extends Error {
69
69
  */
70
70
  static check(input) {
71
71
  if (input instanceof CodeError) return true;
72
- return typeof input === "object" && input !== null && "message" in input && typeof input.message === "string" && "code" in input && typeof input.code === "string";
72
+ return containsKeys(input, ["message", "code"]) && typeof input.message === "string" && typeof input.code === "string";
73
73
  }
74
74
  static checkCaughtError(error, options) {
75
75
  if (this.check(error)) {
@@ -182,7 +182,11 @@ var DataError = class DataError extends CodeError {
182
182
  */
183
183
  static check(input) {
184
184
  if (input instanceof DataError) return true;
185
- 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;
185
+ return containsKeys(input, [
186
+ "data",
187
+ "code",
188
+ "message"
189
+ ]) && typeof input.message === "string" && typeof input.code === "string" && isNonNullableObject(input.data);
186
190
  }
187
191
  /**
188
192
  * Check a `DataError` against its error code
@@ -240,6 +244,49 @@ var DataError = class DataError extends CodeError {
240
244
  }
241
245
  };
242
246
  //#endregion
247
+ //#region src/root/functions/parsers/parseIntStrict.ts
248
+ /**
249
+ * Converts a string to an integer and throws an error if it cannot be converted.
250
+ *
251
+ * @category Parsers
252
+ *
253
+ * @param string - A string to convert into a number.
254
+ * @param radix - A value between 2 and 36 that specifies the base of the number in string. If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal. All other strings are considered decimal.
255
+ *
256
+ * @throws {DataError} If the provided string cannot safely be converted to an integer.
257
+ *
258
+ * @returns The integer parsed from the input string.
259
+ */
260
+ function parseIntStrict(string, radix) {
261
+ const trimmedString = string.trim();
262
+ const maxAllowedAlphabeticalCharacter = radix && radix > 10 && radix <= 36 ? String.fromCharCode(87 + radix - 1) : void 0;
263
+ if (!(radix && radix > 10 && radix <= 36 ? new RegExp(`^[+-]?[0-9a-${maxAllowedAlphabeticalCharacter}]+$`, "i") : /^[+-]?\d+$/).test(trimmedString)) throw new DataError(radix ? {
264
+ string,
265
+ radix
266
+ } : { string }, "INTEGER_PARSING_ERROR", `Only numeric values${radix && radix > 10 && radix <= 36 ? ` or character${radix !== 11 ? "s" : ""} A${radix !== 11 ? `-${maxAllowedAlphabeticalCharacter?.toUpperCase()} ` : " "}` : " "}are allowed.`);
267
+ if (radix && radix < 10 && [...trimmedString.replace(/^[+-]/, "")].some((character) => {
268
+ return parseInt(character) >= radix;
269
+ })) throw new DataError({
270
+ string,
271
+ radix
272
+ }, "INTEGER_PARSING_ERROR", "Value contains one or more digits outside of the range of the given radix.");
273
+ const parseIntResult = parseInt(trimmedString, radix);
274
+ if (isNaN(parseIntResult)) throw new DataError({ string }, "INTEGER_PARSING_ERROR", "Value is not a valid integer.");
275
+ return parseIntResult;
276
+ }
277
+ //#endregion
278
+ //#region src/root/functions/parsers/parseVersionType.ts
279
+ /**
280
+ * Represents the three common software version types.
281
+ *
282
+ * @category Types
283
+ */
284
+ const VersionType = {
285
+ MAJOR: "major",
286
+ MINOR: "minor",
287
+ PATCH: "patch"
288
+ };
289
+ //#endregion
243
290
  //#region src/root/functions/arrayHelpers/range.ts
244
291
  /**
245
292
  * Creates an array of numbers within a given range.
@@ -279,6 +326,53 @@ function range(start, stop, step = 1) {
279
326
  return numbers;
280
327
  }
281
328
  //#endregion
329
+ //#region src/root/functions/typeAssertions/isNonNullableObject.ts
330
+ /**
331
+ * Determines if the given input is a non-nullable object, narrowing the type down as such if it is
332
+ *
333
+ * @category Type Assertions
334
+ *
335
+ * @param input - The input to check
336
+ *
337
+ * @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.
338
+ */
339
+ function isNonNullableObject(input) {
340
+ return typeof input === "object" && input !== null;
341
+ }
342
+ //#endregion
343
+ //#region src/root/functions/typeAssertions/objectContainsKeys.ts
344
+ /**
345
+ * Determines if the given object contains all of the keys provided.
346
+ *
347
+ * @category Type Assertions
348
+ *
349
+ * @param input - The input object to check.
350
+ * @param keys - The keys expected to be in the input object.
351
+ *
352
+ * @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.
353
+ */
354
+ function objectContainsKeys(input, keys) {
355
+ const expectedKeys = Array.isArray(keys) ? keys : [keys];
356
+ if (expectedKeys.length === 0) return false;
357
+ for (const key of expectedKeys) if (!(key in input)) return false;
358
+ return true;
359
+ }
360
+ //#endregion
361
+ //#region src/root/functions/typeAssertions/containsKeys.ts
362
+ /**
363
+ * Determines if the given input is a non-nullable object, and if that object contains all of the keys provided.
364
+ *
365
+ * @category Type Assertions
366
+ *
367
+ * @param input - The input to check.
368
+ * @param keys - The keys expected to be in the input if it's an object.
369
+ *
370
+ * @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.
371
+ */
372
+ function containsKeys(input, keys) {
373
+ return isNonNullableObject(input) && objectContainsKeys(input, keys);
374
+ }
375
+ //#endregion
282
376
  //#region src/root/functions/arrayHelpers/fillArray.ts
283
377
  /**
284
378
  * Creates a new array where each element is the result of the provided callback.
@@ -306,7 +400,7 @@ function fillArray(callback, length = 1, options) {
306
400
  return callback(index);
307
401
  });
308
402
  if (outputArray.some((item) => {
309
- return item instanceof Promise || typeof item === "object" && item !== null && "then" in item && typeof item.then === "function";
403
+ return item instanceof Promise || containsKeys(item, "then") && typeof item.then === "function";
310
404
  })) return Promise.all(outputArray);
311
405
  return outputArray;
312
406
  }
@@ -334,49 +428,6 @@ function paralleliseArrays(firstArray, secondArray) {
334
428
  return outputArray;
335
429
  }
336
430
  //#endregion
337
- //#region src/root/functions/parsers/parseIntStrict.ts
338
- /**
339
- * Converts a string to an integer and throws an error if it cannot be converted.
340
- *
341
- * @category Parsers
342
- *
343
- * @param string - A string to convert into a number.
344
- * @param radix - A value between 2 and 36 that specifies the base of the number in string. If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal. All other strings are considered decimal.
345
- *
346
- * @throws {DataError} If the provided string cannot safely be converted to an integer.
347
- *
348
- * @returns The integer parsed from the input string.
349
- */
350
- function parseIntStrict(string, radix) {
351
- const trimmedString = string.trim();
352
- const maxAllowedAlphabeticalCharacter = radix && radix > 10 && radix <= 36 ? String.fromCharCode(87 + radix - 1) : void 0;
353
- if (!(radix && radix > 10 && radix <= 36 ? new RegExp(`^[+-]?[0-9a-${maxAllowedAlphabeticalCharacter}]+$`, "i") : /^[+-]?\d+$/).test(trimmedString)) throw new DataError(radix ? {
354
- string,
355
- radix
356
- } : { string }, "INTEGER_PARSING_ERROR", `Only numeric values${radix && radix > 10 && radix <= 36 ? ` or character${radix !== 11 ? "s" : ""} A${radix !== 11 ? `-${maxAllowedAlphabeticalCharacter?.toUpperCase()} ` : " "}` : " "}are allowed.`);
357
- if (radix && radix < 10 && [...trimmedString.replace(/^[+-]/, "")].some((character) => {
358
- return parseInt(character) >= radix;
359
- })) throw new DataError({
360
- string,
361
- radix
362
- }, "INTEGER_PARSING_ERROR", "Value contains one or more digits outside of the range of the given radix.");
363
- const parseIntResult = parseInt(trimmedString, radix);
364
- if (isNaN(parseIntResult)) throw new DataError({ string }, "INTEGER_PARSING_ERROR", "Value is not a valid integer.");
365
- return parseIntResult;
366
- }
367
- //#endregion
368
- //#region src/root/functions/parsers/parseVersionType.ts
369
- /**
370
- * Represents the three common software version types.
371
- *
372
- * @category Types
373
- */
374
- const VersionType = {
375
- MAJOR: "major",
376
- MINOR: "minor",
377
- PATCH: "patch"
378
- };
379
- //#endregion
380
431
  //#region src/root/functions/taggedTemplate/interpolate.ts
381
432
  /**
382
433
  * Returns the result of interpolating a template string when given the strings and interpolations separately.
@@ -456,7 +507,7 @@ function reduceLines(lines, { preserveTabs = true }) {
456
507
  * @returns An additional function to invoke, or a new string with the strings and interpolations from the template applied, and extraneous indents removed.
457
508
  */
458
509
  function normaliseIndents(first, ...args) {
459
- if (typeof first === "object" && first !== null && !Array.isArray(first)) {
510
+ if (isNonNullableObject(first) && !Array.isArray(first)) {
460
511
  const options = first;
461
512
  return (strings, ...interpolations) => {
462
513
  return normaliseIndents(strings, ...interpolations, options);
@@ -44,7 +44,7 @@ var CodeError = class CodeError extends Error {
44
44
  */
45
45
  static check(input) {
46
46
  if (input instanceof CodeError) return true;
47
- return typeof input === "object" && input !== null && "message" in input && typeof input.message === "string" && "code" in input && typeof input.code === "string";
47
+ return containsKeys(input, ["message", "code"]) && typeof input.message === "string" && typeof input.code === "string";
48
48
  }
49
49
  static checkCaughtError(error, options) {
50
50
  if (this.check(error)) {
@@ -157,7 +157,11 @@ var DataError = class DataError extends CodeError {
157
157
  */
158
158
  static check(input) {
159
159
  if (input instanceof DataError) return true;
160
- 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;
160
+ return containsKeys(input, [
161
+ "data",
162
+ "code",
163
+ "message"
164
+ ]) && typeof input.message === "string" && typeof input.code === "string" && isNonNullableObject(input.data);
161
165
  }
162
166
  /**
163
167
  * Check a `DataError` against its error code
@@ -215,6 +219,49 @@ var DataError = class DataError extends CodeError {
215
219
  }
216
220
  };
217
221
  //#endregion
222
+ //#region src/root/functions/parsers/parseIntStrict.ts
223
+ /**
224
+ * Converts a string to an integer and throws an error if it cannot be converted.
225
+ *
226
+ * @category Parsers
227
+ *
228
+ * @param string - A string to convert into a number.
229
+ * @param radix - A value between 2 and 36 that specifies the base of the number in string. If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal. All other strings are considered decimal.
230
+ *
231
+ * @throws {DataError} If the provided string cannot safely be converted to an integer.
232
+ *
233
+ * @returns The integer parsed from the input string.
234
+ */
235
+ function parseIntStrict(string, radix) {
236
+ const trimmedString = string.trim();
237
+ const maxAllowedAlphabeticalCharacter = radix && radix > 10 && radix <= 36 ? String.fromCharCode(87 + radix - 1) : void 0;
238
+ if (!(radix && radix > 10 && radix <= 36 ? new RegExp(`^[+-]?[0-9a-${maxAllowedAlphabeticalCharacter}]+$`, "i") : /^[+-]?\d+$/).test(trimmedString)) throw new DataError(radix ? {
239
+ string,
240
+ radix
241
+ } : { string }, "INTEGER_PARSING_ERROR", `Only numeric values${radix && radix > 10 && radix <= 36 ? ` or character${radix !== 11 ? "s" : ""} A${radix !== 11 ? `-${maxAllowedAlphabeticalCharacter?.toUpperCase()} ` : " "}` : " "}are allowed.`);
242
+ if (radix && radix < 10 && [...trimmedString.replace(/^[+-]/, "")].some((character) => {
243
+ return parseInt(character) >= radix;
244
+ })) throw new DataError({
245
+ string,
246
+ radix
247
+ }, "INTEGER_PARSING_ERROR", "Value contains one or more digits outside of the range of the given radix.");
248
+ const parseIntResult = parseInt(trimmedString, radix);
249
+ if (isNaN(parseIntResult)) throw new DataError({ string }, "INTEGER_PARSING_ERROR", "Value is not a valid integer.");
250
+ return parseIntResult;
251
+ }
252
+ //#endregion
253
+ //#region src/root/functions/parsers/parseVersionType.ts
254
+ /**
255
+ * Represents the three common software version types.
256
+ *
257
+ * @category Types
258
+ */
259
+ const VersionType = {
260
+ MAJOR: "major",
261
+ MINOR: "minor",
262
+ PATCH: "patch"
263
+ };
264
+ //#endregion
218
265
  //#region src/root/functions/arrayHelpers/range.ts
219
266
  /**
220
267
  * Creates an array of numbers within a given range.
@@ -254,6 +301,53 @@ function range(start, stop, step = 1) {
254
301
  return numbers;
255
302
  }
256
303
  //#endregion
304
+ //#region src/root/functions/typeAssertions/isNonNullableObject.ts
305
+ /**
306
+ * Determines if the given input is a non-nullable object, narrowing the type down as such if it is
307
+ *
308
+ * @category Type Assertions
309
+ *
310
+ * @param input - The input to check
311
+ *
312
+ * @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.
313
+ */
314
+ function isNonNullableObject(input) {
315
+ return typeof input === "object" && input !== null;
316
+ }
317
+ //#endregion
318
+ //#region src/root/functions/typeAssertions/objectContainsKeys.ts
319
+ /**
320
+ * Determines if the given object contains all of the keys provided.
321
+ *
322
+ * @category Type Assertions
323
+ *
324
+ * @param input - The input object to check.
325
+ * @param keys - The keys expected to be in the input object.
326
+ *
327
+ * @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.
328
+ */
329
+ function objectContainsKeys(input, keys) {
330
+ const expectedKeys = Array.isArray(keys) ? keys : [keys];
331
+ if (expectedKeys.length === 0) return false;
332
+ for (const key of expectedKeys) if (!(key in input)) return false;
333
+ return true;
334
+ }
335
+ //#endregion
336
+ //#region src/root/functions/typeAssertions/containsKeys.ts
337
+ /**
338
+ * Determines if the given input is a non-nullable object, and if that object contains all of the keys provided.
339
+ *
340
+ * @category Type Assertions
341
+ *
342
+ * @param input - The input to check.
343
+ * @param keys - The keys expected to be in the input if it's an object.
344
+ *
345
+ * @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.
346
+ */
347
+ function containsKeys(input, keys) {
348
+ return isNonNullableObject(input) && objectContainsKeys(input, keys);
349
+ }
350
+ //#endregion
257
351
  //#region src/root/functions/arrayHelpers/fillArray.ts
258
352
  /**
259
353
  * Creates a new array where each element is the result of the provided callback.
@@ -281,7 +375,7 @@ function fillArray(callback, length = 1, options) {
281
375
  return callback(index);
282
376
  });
283
377
  if (outputArray.some((item) => {
284
- return item instanceof Promise || typeof item === "object" && item !== null && "then" in item && typeof item.then === "function";
378
+ return item instanceof Promise || containsKeys(item, "then") && typeof item.then === "function";
285
379
  })) return Promise.all(outputArray);
286
380
  return outputArray;
287
381
  }
@@ -309,49 +403,6 @@ function paralleliseArrays(firstArray, secondArray) {
309
403
  return outputArray;
310
404
  }
311
405
  //#endregion
312
- //#region src/root/functions/parsers/parseIntStrict.ts
313
- /**
314
- * Converts a string to an integer and throws an error if it cannot be converted.
315
- *
316
- * @category Parsers
317
- *
318
- * @param string - A string to convert into a number.
319
- * @param radix - A value between 2 and 36 that specifies the base of the number in string. If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal. All other strings are considered decimal.
320
- *
321
- * @throws {DataError} If the provided string cannot safely be converted to an integer.
322
- *
323
- * @returns The integer parsed from the input string.
324
- */
325
- function parseIntStrict(string, radix) {
326
- const trimmedString = string.trim();
327
- const maxAllowedAlphabeticalCharacter = radix && radix > 10 && radix <= 36 ? String.fromCharCode(87 + radix - 1) : void 0;
328
- if (!(radix && radix > 10 && radix <= 36 ? new RegExp(`^[+-]?[0-9a-${maxAllowedAlphabeticalCharacter}]+$`, "i") : /^[+-]?\d+$/).test(trimmedString)) throw new DataError(radix ? {
329
- string,
330
- radix
331
- } : { string }, "INTEGER_PARSING_ERROR", `Only numeric values${radix && radix > 10 && radix <= 36 ? ` or character${radix !== 11 ? "s" : ""} A${radix !== 11 ? `-${maxAllowedAlphabeticalCharacter?.toUpperCase()} ` : " "}` : " "}are allowed.`);
332
- if (radix && radix < 10 && [...trimmedString.replace(/^[+-]/, "")].some((character) => {
333
- return parseInt(character) >= radix;
334
- })) throw new DataError({
335
- string,
336
- radix
337
- }, "INTEGER_PARSING_ERROR", "Value contains one or more digits outside of the range of the given radix.");
338
- const parseIntResult = parseInt(trimmedString, radix);
339
- if (isNaN(parseIntResult)) throw new DataError({ string }, "INTEGER_PARSING_ERROR", "Value is not a valid integer.");
340
- return parseIntResult;
341
- }
342
- //#endregion
343
- //#region src/root/functions/parsers/parseVersionType.ts
344
- /**
345
- * Represents the three common software version types.
346
- *
347
- * @category Types
348
- */
349
- const VersionType = {
350
- MAJOR: "major",
351
- MINOR: "minor",
352
- PATCH: "patch"
353
- };
354
- //#endregion
355
406
  //#region src/root/functions/taggedTemplate/interpolate.ts
356
407
  /**
357
408
  * Returns the result of interpolating a template string when given the strings and interpolations separately.
@@ -431,7 +482,7 @@ function reduceLines(lines, { preserveTabs = true }) {
431
482
  * @returns An additional function to invoke, or a new string with the strings and interpolations from the template applied, and extraneous indents removed.
432
483
  */
433
484
  function normaliseIndents(first, ...args) {
434
- if (typeof first === "object" && first !== null && !Array.isArray(first)) {
485
+ if (isNonNullableObject(first) && !Array.isArray(first)) {
435
486
  const options = first;
436
487
  return (strings, ...interpolations) => {
437
488
  return normaliseIndents(strings, ...interpolations, options);