@alextheman/utility 3.5.10 → 3.7.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
@@ -1,20 +1,10 @@
1
- import path from "path";
2
1
  import z, { z as z$1 } from "zod";
2
+ import path from "path";
3
3
 
4
4
  //#region src/constants/NAMESPACE_EXPORT_REGEX.ts
5
5
  const NAMESPACE_EXPORT_REGEX = "export\\s+\\*\\s+from";
6
6
  var NAMESPACE_EXPORT_REGEX_default = NAMESPACE_EXPORT_REGEX;
7
7
 
8
- //#endregion
9
- //#region src/functions/appendSemicolon.ts
10
- function appendSemicolon(stringToAppendTo) {
11
- if (stringToAppendTo.includes("\n")) throw new Error("MULTIPLE_LINE_ERROR");
12
- const stringWithNoTrailingWhitespace = stringToAppendTo.trimEnd();
13
- if (stringWithNoTrailingWhitespace === "") return "";
14
- return stringWithNoTrailingWhitespace[stringWithNoTrailingWhitespace.length - 1] === ";" ? stringWithNoTrailingWhitespace : `${stringWithNoTrailingWhitespace};`;
15
- }
16
- var appendSemicolon_default = appendSemicolon;
17
-
18
8
  //#endregion
19
9
  //#region src/functions/arrayHelpers/fillArray.ts
20
10
  /**
@@ -67,7 +57,17 @@ var paralleliseArrays_default = paralleliseArrays;
67
57
  //#endregion
68
58
  //#region src/functions/parsers/parseIntStrict.ts
69
59
  const IntegerParsingError = /* @__PURE__ */ new TypeError("INTEGER_PARSING_ERROR");
70
- function parseIntStrict(...[string, radix]) {
60
+ /**
61
+ * Converts a string to an integer and throws an error if it cannot be converted.
62
+ *
63
+ * @param string — A string to convert into a number.
64
+ * @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.
65
+ *
66
+ * @throws {TypeError} If the provided string cannot safely be converted to an integer.
67
+ *
68
+ * @returns The integer parsed from the input string.
69
+ */
70
+ function parseIntStrict(string, radix) {
71
71
  const trimmedString = string.trim();
72
72
  if (!(radix && radix > 10 && radix <= 36 ? new RegExp(`^[+-]?[0-9a-${String.fromCharCode(87 + radix - 1)}]+$`, "i") : /^[+-]?\d+$/).test(trimmedString)) throw IntegerParsingError;
73
73
  if (radix && radix < 10 && [...trimmedString].some((character) => {
@@ -80,7 +80,15 @@ function parseIntStrict(...[string, radix]) {
80
80
  var parseIntStrict_default = parseIntStrict;
81
81
 
82
82
  //#endregion
83
- //#region src/functions/getRandomNumber.ts
83
+ //#region src/functions/miscellaneous/getRandomNumber.ts
84
+ /**
85
+ * Gets a random number between the given bounds.
86
+ *
87
+ * @param lowerBound - The lowest number that can be chosen.
88
+ * @param upperBound - The highest number that can be chosen.
89
+ *
90
+ * @returns A random number between the provided lower bound and upper bound.
91
+ */
84
92
  function getRandomNumber(lowerBound, upperBound) {
85
93
  const parsedLowerBound = parseIntStrict_default(`${lowerBound}`);
86
94
  const parsedUpperBound = parseIntStrict_default(`${upperBound}`);
@@ -115,8 +123,8 @@ var randomiseArray_default = randomiseArray;
115
123
  /**
116
124
  * Creates an array of numbers within a given range.
117
125
  *
118
- * The range is inclusive of `start` and exclusive of `stop`.
119
- * The sign of `step` must match the direction of the range.
126
+ * - The range is inclusive of `start` and exclusive of `stop`.
127
+ * - The sign of `step` must match the direction of the range.
120
128
  *
121
129
  * @param start - The number to start at (inclusive).
122
130
  * @param stop - The number to stop at (exclusive).
@@ -142,96 +150,22 @@ function range(start, stop, step = 1) {
142
150
  var range_default = range;
143
151
 
144
152
  //#endregion
145
- //#region src/functions/camelToKebab.ts
146
- function camelToKebab(string) {
147
- return string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").toLowerCase();
148
- }
149
- var camelToKebab_default = camelToKebab;
150
-
151
- //#endregion
152
- //#region src/functions/convertFileToBase64.ts
153
- function convertFileToBase64(file) {
154
- return new Promise((resolve, reject) => {
155
- const reader = new FileReader();
156
- reader.readAsDataURL(file);
157
- reader.onload = () => {
158
- if (reader.result === null) {
159
- reject(/* @__PURE__ */ new Error("FILE_CONVERSION_ERROR"));
160
- return;
161
- }
162
- resolve(reader.result);
163
- };
164
- reader.onerror = () => {
165
- reject(/* @__PURE__ */ new Error("FILE_READER_ERROR"));
166
- };
167
- });
168
- }
169
- var convertFileToBase64_default = convertFileToBase64;
170
-
171
- //#endregion
172
- //#region src/functions/createFormData.ts
173
- function getNullableResolutionStrategy(key, strategy) {
174
- return (typeof strategy === "object" ? strategy[key] : strategy) ?? "empty";
175
- }
176
- function createFormData(data, options = {
177
- arrayResolution: "stringify",
178
- nullableResolution: "empty"
179
- }) {
180
- const formData = new FormData();
181
- function resolveNullablesByStrategy(key, value, resolutionStrategy) {
182
- switch (resolutionStrategy) {
183
- case "empty":
184
- formData.append(String(key), "");
185
- break;
186
- case "stringify":
187
- formData.append(String(key), JSON.stringify(value));
188
- break;
189
- case "omit": break;
190
- default: throw new TypeError("SLOPPY_PURE_JAVASCRIPT_USER_ERROR");
191
- }
192
- }
193
- function resolveNullables(key, value, options$1) {
194
- if (options$1.nullableResolution) {
195
- resolveNullablesByStrategy(key, value, getNullableResolutionStrategy(key, options$1.nullableResolution));
196
- return;
197
- }
198
- if (options$1.undefinedResolution || options$1.nullResolution) {
199
- if (data[key] === void 0 && options$1.undefinedResolution) {
200
- resolveNullablesByStrategy(key, value, getNullableResolutionStrategy(key, options$1.undefinedResolution));
201
- return;
202
- }
203
- if (data[key] === null && options$1.nullResolution) resolveNullablesByStrategy(key, value, getNullableResolutionStrategy(key, options$1.nullResolution));
204
- }
205
- }
206
- const entries = Object.entries(data);
207
- for (const [key, value] of entries) if (value instanceof Blob) formData.append(String(key), value);
208
- else if (value === void 0 || value === null) resolveNullables(key, value, options);
209
- else if (typeof value === "object") {
210
- if (Array.isArray(value)) {
211
- if (value.some((item) => {
212
- return item instanceof Blob;
213
- }) && (options.arrayResolution === "stringify" || typeof options.arrayResolution === "object" && options.arrayResolution[key] === "stringify")) throw new TypeError("CANNOT_STRINGIFY_BLOB");
214
- if (options.arrayResolution === "multiple" || typeof options.arrayResolution === "object" && options.arrayResolution[key] === "multiple") {
215
- for (const item of value) {
216
- if ((typeof item === "object" || !item) && !(item instanceof Blob)) throw new TypeError("NON_PRIMITIVE_ARRAY_ITEMS_FOUND");
217
- if (item instanceof Blob) formData.append(String(key), item);
218
- else formData.append(String(key), String(item));
219
- }
220
- continue;
221
- }
222
- }
223
- formData.append(String(key), JSON.stringify(value));
224
- } else formData.append(String(key), String(value));
225
- return formData;
226
- }
227
- var createFormData_default = createFormData;
228
-
229
- //#endregion
230
- //#region src/functions/createTemplateStringsArray.ts
231
- function createTemplateStringsArray(strings) {
232
- return Object.assign([...strings], { raw: [...strings] });
153
+ //#region src/functions/arrayHelpers/removeDuplicates.ts
154
+ /**
155
+ * Removes duplicate values from an array.
156
+ *
157
+ * @template ItemType - The type of the array items.
158
+ *
159
+ * @param array - The array to remove duplicates from.
160
+ *
161
+ * @returns A new array with a different reference in memory, with the duplicates removed.
162
+ */
163
+ function removeDuplicates(array) {
164
+ const outputArray = [];
165
+ for (const item of array) if (!outputArray.includes(item)) outputArray.push(item);
166
+ return outputArray;
233
167
  }
234
- var createTemplateStringsArray_default = createTemplateStringsArray;
168
+ var removeDuplicates_default = removeDuplicates;
235
169
 
236
170
  //#endregion
237
171
  //#region src/functions/date/addDaysToDate.ts
@@ -374,43 +308,111 @@ function isMonthlyMultiple(firstDate, secondDate) {
374
308
  var isMonthlyMultiple_default = isMonthlyMultiple;
375
309
 
376
310
  //#endregion
377
- //#region src/functions/deepCopy.ts
378
- function callDeepCopy(input) {
379
- return typeof input === "object" && input !== null ? deepCopy(input) : input;
380
- }
381
- function deepCopy(object) {
382
- if (Array.isArray(object)) return object.map((item) => {
383
- return callDeepCopy(item);
311
+ //#region src/functions/miscellaneous/convertFileToBase64.ts
312
+ /**
313
+ * Asynchronously converts a file to a base 64 string
314
+ *
315
+ * @param file - The file to convert.
316
+ *
317
+ * @throws {Error} If the file reader gives an error.
318
+ *
319
+ * @returns A promise that resolves to the encoded base 64 string.
320
+ */
321
+ function convertFileToBase64(file) {
322
+ return new Promise((resolve, reject) => {
323
+ const reader = new FileReader();
324
+ reader.readAsDataURL(file);
325
+ reader.onload = () => {
326
+ if (reader.result === null) {
327
+ reject(/* @__PURE__ */ new Error("FILE_CONVERSION_ERROR"));
328
+ return;
329
+ }
330
+ resolve(reader.result);
331
+ };
332
+ reader.onerror = () => {
333
+ reject(/* @__PURE__ */ new Error("FILE_READER_ERROR"));
334
+ };
384
335
  });
385
- const clonedObject = { ...object };
386
- for (const key in clonedObject) {
387
- const value = clonedObject[key];
388
- clonedObject[key] = callDeepCopy(value);
389
- }
390
- return clonedObject;
391
336
  }
392
- var deepCopy_default = deepCopy;
337
+ var convertFileToBase64_default = convertFileToBase64;
393
338
 
394
339
  //#endregion
395
- //#region src/functions/deepFreeze.ts
396
- function deepFreeze(object) {
397
- for (const value of Object.values(object)) {
398
- if (typeof value === "function") continue;
399
- if (value && typeof value === "object") deepFreeze(value);
400
- }
401
- return Object.freeze(object);
340
+ //#region src/functions/miscellaneous/createFormData.ts
341
+ function getNullableResolutionStrategy(key, strategy) {
342
+ return (typeof strategy === "object" ? strategy[key] : strategy) ?? "empty";
402
343
  }
403
- var deepFreeze_default = deepFreeze;
404
-
405
- //#endregion
406
- //#region src/functions/getRecordKeys.ts
407
- function getRecordKeys(record) {
408
- return Object.keys(record);
344
+ /**
345
+ * Creates FormData from a given object, resolving non-string types as appropriate.
346
+ *
347
+ * @template DataType - The type of the given data.
348
+ *
349
+ * @param data - The data to create FormData from.
350
+ * @param options - Options to apply to the conversion.
351
+ *
352
+ * @returns A FormData object with the data applied.
353
+ */
354
+ function createFormData(data, options = {
355
+ arrayResolution: "stringify",
356
+ nullableResolution: "empty"
357
+ }) {
358
+ const formData = new FormData();
359
+ function resolveNullablesByStrategy(key, value, resolutionStrategy) {
360
+ switch (resolutionStrategy) {
361
+ case "empty":
362
+ formData.append(String(key), "");
363
+ break;
364
+ case "stringify":
365
+ formData.append(String(key), JSON.stringify(value));
366
+ break;
367
+ case "omit": break;
368
+ default: throw new TypeError("SLOPPY_PURE_JAVASCRIPT_USER_ERROR");
369
+ }
370
+ }
371
+ function resolveNullables(key, value, options$1) {
372
+ if (options$1.nullableResolution) {
373
+ resolveNullablesByStrategy(key, value, getNullableResolutionStrategy(key, options$1.nullableResolution));
374
+ return;
375
+ }
376
+ if (options$1.undefinedResolution || options$1.nullResolution) {
377
+ if (data[key] === void 0 && options$1.undefinedResolution) {
378
+ resolveNullablesByStrategy(key, value, getNullableResolutionStrategy(key, options$1.undefinedResolution));
379
+ return;
380
+ }
381
+ if (data[key] === null && options$1.nullResolution) resolveNullablesByStrategy(key, value, getNullableResolutionStrategy(key, options$1.nullResolution));
382
+ }
383
+ }
384
+ const entries = Object.entries(data);
385
+ for (const [key, value] of entries) if (value instanceof Blob) formData.append(String(key), value);
386
+ else if (value === void 0 || value === null) resolveNullables(key, value, options);
387
+ else if (typeof value === "object") {
388
+ if (Array.isArray(value)) {
389
+ if (value.some((item) => {
390
+ return item instanceof Blob;
391
+ }) && (options.arrayResolution === "stringify" || typeof options.arrayResolution === "object" && options.arrayResolution[key] === "stringify")) throw new TypeError("CANNOT_STRINGIFY_BLOB");
392
+ if (options.arrayResolution === "multiple" || typeof options.arrayResolution === "object" && options.arrayResolution[key] === "multiple") {
393
+ for (const item of value) {
394
+ if ((typeof item === "object" || !item) && !(item instanceof Blob)) throw new TypeError("NON_PRIMITIVE_ARRAY_ITEMS_FOUND");
395
+ if (item instanceof Blob) formData.append(String(key), item);
396
+ else formData.append(String(key), String(item));
397
+ }
398
+ continue;
399
+ }
400
+ }
401
+ formData.append(String(key), JSON.stringify(value));
402
+ } else formData.append(String(key), String(value));
403
+ return formData;
409
404
  }
410
- var getRecordKeys_default = getRecordKeys;
405
+ var createFormData_default = createFormData;
411
406
 
412
407
  //#endregion
413
- //#region src/functions/isOrdered.ts
408
+ //#region src/functions/miscellaneous/isOrdered.ts
409
+ /**
410
+ * Checks to see if the given array is sorted in ascending order.
411
+ *
412
+ * @param array - The array to check.
413
+ *
414
+ * @returns `true` if the array is sorted in ascending order, and `false` otherwise.
415
+ */
414
416
  function isOrdered(array) {
415
417
  const newArray = [...array];
416
418
  newArray.sort();
@@ -420,47 +422,73 @@ function isOrdered(array) {
420
422
  var isOrdered_default = isOrdered;
421
423
 
422
424
  //#endregion
423
- //#region src/functions/kebabToCamel.ts
424
- function kebabToCamel(string, options) {
425
- if (string !== string.toLowerCase()) throw new Error("INVALID_KEBAB_CASE_INPUT");
426
- if (string.startsWith("-") || string.endsWith("-") || string.includes("--")) throw new Error("INVALID_KEBAB_CASE_INPUT");
427
- let outputString = "";
428
- let skip = false;
429
- for (const stringIndex in [...string]) {
430
- if (skip) {
431
- skip = false;
432
- continue;
433
- }
434
- const index = parseIntStrict_default(stringIndex);
435
- if (index === 0 && options?.startWithUpper) {
436
- outputString += string[index].toUpperCase();
437
- continue;
438
- }
439
- if (index === string.length - 1) {
440
- outputString += string[index];
441
- break;
442
- }
443
- if (string[index] === "-" && /^[a-zA-Z]+$/.test(string[index + 1])) {
444
- outputString += string[index + 1].toUpperCase();
445
- skip = true;
446
- } else outputString += string[index];
447
- }
448
- return outputString;
449
- }
450
- var kebabToCamel_default = kebabToCamel;
451
-
452
- //#endregion
453
- //#region src/functions/normalizeImportPath.ts
454
- function normalizeImportPath(importPath) {
455
- const normalizedPath = path.posix.normalize(importPath);
456
- if (importPath.startsWith("./") && !normalizedPath.startsWith("./")) return `./${normalizedPath}`;
457
- return normalizedPath;
458
- }
459
- const normaliseImportPath = normalizeImportPath;
460
- var normalizeImportPath_default = normalizeImportPath;
425
+ //#region src/functions/miscellaneous/stringListToArray.ts
426
+ /**
427
+ * Converts a stringly-typed list to a proper array.
428
+ *
429
+ * @param stringList - The stringly-typed list to convert.
430
+ * @param options - The options to apply to the conversion.
431
+ * @param options.separator - What each item in the list is separated by.
432
+ * @param options.trimWhitespace - An option to trim any extra whitespace.
433
+ *
434
+ * @returns A new array with each item being an item from the given list.
435
+ */
436
+ function stringListToArray(stringList, { separator = ",", trimWhitespace = true } = {}) {
437
+ if (trimWhitespace && stringList.trim() === "") return [];
438
+ const arrayList = stringList.split(separator ?? "");
439
+ return trimWhitespace ? arrayList.map((item) => {
440
+ return item.trim();
441
+ }) : arrayList;
442
+ }
443
+ var stringListToArray_default = stringListToArray;
444
+
445
+ //#endregion
446
+ //#region src/functions/miscellaneous/wait.ts
447
+ /**
448
+ * Waits for the given number of seconds
449
+ *
450
+ * @param seconds - The number of seconds to wait.
451
+ *
452
+ * @returns A Promise that resolves after the given number of seconds.
453
+ */
454
+ function wait(seconds) {
455
+ return new Promise((resolve, _) => {
456
+ setTimeout(() => {
457
+ resolve();
458
+ }, seconds * 1e3);
459
+ });
460
+ }
461
+ var wait_default = wait;
462
+
463
+ //#endregion
464
+ //#region src/functions/objectHelpers/getRecordKeys.ts
465
+ /**
466
+ * Gets the keys from a given record object, properly typed to be an array of the key of the input object's type.
467
+ *
468
+ * @template InputRecordType - The type of the input object.
469
+ *
470
+ * @param record - The record to get the keys from.
471
+ *
472
+ * @returns An array with all the keys of the input object in string form, but properly typed as `keyof InputRecordType`.
473
+ */
474
+ function getRecordKeys(record) {
475
+ return Object.keys(record);
476
+ }
477
+ var getRecordKeys_default = getRecordKeys;
461
478
 
462
479
  //#endregion
463
- //#region src/functions/omitProperties.ts
480
+ //#region src/functions/objectHelpers/omitProperties.ts
481
+ /**
482
+ * Omits properties from a given object.
483
+ *
484
+ * @template ObjectType - The type of the input object.
485
+ * @template KeysToOmit - A type representing the keys to omit from the object.
486
+ *
487
+ * @param object - The object to omit properties from.
488
+ * @param keysToOmit - The keys to omit from the object. Can either be a single string to omit one, or an array to omit multiple.
489
+ *
490
+ * @returns An object with a new reference in memory, with the properties omitted.
491
+ */
464
492
  function omitProperties(object, keysToOmit) {
465
493
  const outputObject = { ...object };
466
494
  (Array.isArray(keysToOmit) ? keysToOmit : [keysToOmit]).forEach((key) => {
@@ -472,6 +500,15 @@ var omitProperties_default = omitProperties;
472
500
 
473
501
  //#endregion
474
502
  //#region src/functions/parsers/parseBoolean.ts
503
+ /**
504
+ * Takes a stringly-typed boolean and converts it to an actual boolean type.
505
+ *
506
+ * @param inputString - The string to parse.
507
+ *
508
+ * @throws {TypeError} If the string is not either `true` or `false` (case insensitive).
509
+ *
510
+ * @returns The string parsed as an actual boolean.
511
+ */
475
512
  function parseBoolean(inputString) {
476
513
  const normalisedString = inputString.toLowerCase();
477
514
  if (!["true", "false"].includes(normalisedString)) throw new TypeError("INVALID_BOOLEAN_STRING");
@@ -481,8 +518,39 @@ function parseBoolean(inputString) {
481
518
  const stringToBoolean = parseBoolean;
482
519
  var parseBoolean_default = parseBoolean;
483
520
 
521
+ //#endregion
522
+ //#region src/functions/parsers/parseEnv.ts
523
+ const envSchema = z$1.enum([
524
+ "test",
525
+ "development",
526
+ "production"
527
+ ]);
528
+ /**
529
+ * Parses the input and verifies it matches one of the environments allowed by the Env types ("test" | "development" | "production").
530
+ *
531
+ * @param data - The data to parse.
532
+ *
533
+ * @throws {ZodError} If the data does not match one of the environments allowed by the Env types ("test" | "development" | "production").
534
+ *
535
+ * @returns The specified environment if allowed.
536
+ */
537
+ function parseEnv(data) {
538
+ return envSchema.parse(data);
539
+ }
540
+ var parseEnv_default = parseEnv;
541
+
484
542
  //#endregion
485
543
  //#region src/functions/parsers/parseFormData.ts
544
+ /**
545
+ * Returns an object given FormData and an optional data parser function to call on the resulting object.
546
+ *
547
+ * @template DataType - The type of the resulting object when called from the dataParser.
548
+ *
549
+ * @param formData - The FormData to parse.
550
+ * @param dataParser - An optional parser to call on the object before it gets returned.
551
+ *
552
+ * @returns A parsed object based on the contents of the input formData and the result of parsing with the data parser if provided.
553
+ */
486
554
  function parseFormData(formData, dataParser) {
487
555
  const object = {};
488
556
  formData.forEach((value, key) => {
@@ -503,8 +571,14 @@ const httpErrorCodeLookup = {
503
571
  418: "I_AM_A_TEAPOT",
504
572
  500: "INTERNAL_SERVER_ERROR"
505
573
  };
574
+ /** Represents common errors you may get from a HTTP API request. */
506
575
  var APIError = class extends Error {
507
576
  status;
577
+ /**
578
+ * @param status - A HTTP status code. Can be any number, but numbers between 400 and 600 are encouraged to fit with HTTP status code conventions.
579
+ * @param message - An error message to display alongside the status code.
580
+ * @param options - Extra options to be passed to super Error constructor.
581
+ */
508
582
  constructor(status = 500, message, options) {
509
583
  super(message, options);
510
584
  this.status = status;
@@ -513,6 +587,13 @@ var APIError = class extends Error {
513
587
  Object.defineProperty(this, "message", { enumerable: true });
514
588
  Object.setPrototypeOf(this, new.target.prototype);
515
589
  }
590
+ /**
591
+ * Checks whether the given input may have been caused by an APIError.
592
+ *
593
+ * @param input - The input to check.
594
+ *
595
+ * @returns `true` if the input is an APIError, and `false` otherwise. The type of the input will also be narrowed down to APIError if `true`.
596
+ */
516
597
  static check(input) {
517
598
  const data = input;
518
599
  return typeof data === "object" && data !== null && typeof data?.status === "number" && typeof data?.message === "string";
@@ -522,6 +603,7 @@ var APIError_default = APIError;
522
603
 
523
604
  //#endregion
524
605
  //#region src/types/DataError.ts
606
+ /** Represents errors you may get that may've been caused by a specific piece of data. */
525
607
  var DataError = class extends Error {
526
608
  data;
527
609
  code;
@@ -540,6 +622,13 @@ var DataError = class extends Error {
540
622
  Object.defineProperty(this, "message", { enumerable: true });
541
623
  Object.setPrototypeOf(this, new.target.prototype);
542
624
  }
625
+ /**
626
+ * Checks whether the given input may have been caused by a DataError.
627
+ *
628
+ * @param input - The input to check.
629
+ *
630
+ * @returns `true` if the input is a DataError, and `false` otherwise. The type of the input will also be narrowed down to DataError if `true`.
631
+ */
543
632
  static check(input) {
544
633
  const data = input;
545
634
  return typeof data === "object" && data !== null && typeof data.message === "string" && typeof data.code === "string" && "data" in data;
@@ -550,26 +639,16 @@ var DataError_default = DataError;
550
639
  //#endregion
551
640
  //#region src/types/Email.ts
552
641
  const emailSchema = z.email().brand();
642
+ /** @deprecated Please use `z.email().parse() from Zod instead.`*/
553
643
  function parseEmail(data) {
554
644
  return emailSchema.parse(data);
555
645
  }
556
646
  var Email_default = parseEmail;
557
647
 
558
- //#endregion
559
- //#region src/types/Env.ts
560
- const envSchema = z$1.enum([
561
- "test",
562
- "development",
563
- "production"
564
- ]);
565
- function parseEnv(data = "development") {
566
- return envSchema.parse(data);
567
- }
568
- var Env_default = parseEnv;
569
-
570
648
  //#endregion
571
649
  //#region src/types/UUID.ts
572
650
  const uuidSchema = z.uuid().brand();
651
+ /** @deprecated Please use `z.uuid().parse() from Zod instead.`*/
573
652
  function parseUUID(UUID) {
574
653
  return uuidSchema.parse(UUID);
575
654
  }
@@ -577,6 +656,20 @@ var UUID_default = parseUUID;
577
656
 
578
657
  //#endregion
579
658
  //#region src/functions/parsers/parseZodSchema.ts
659
+ /**
660
+ * An alternative function to zodSchema.parse() that can be used to strictly parse Zod schemas.
661
+ *
662
+ * @template Output - The Zod output type.
663
+ * @template Input - The Zod input type.
664
+ * @template Internals - The Zod internal types based on the output and input types.
665
+ *
666
+ * @param schema - The Zod schema to use in parsing.
667
+ * @param data - The data to parse.
668
+ *
669
+ * @throws {DataError} If the given data cannot be parsed according to the schema.
670
+ *
671
+ * @returns The parsed data from the Zod schema.
672
+ */
580
673
  function parseZodSchema(schema, data) {
581
674
  const parsedResult = schema.safeParse(data);
582
675
  if (!parsedResult.success) throw new DataError_default(data);
@@ -585,27 +678,207 @@ function parseZodSchema(schema, data) {
585
678
  var parseZodSchema_default = parseZodSchema;
586
679
 
587
680
  //#endregion
588
- //#region src/functions/removeDuplicates.ts
589
- function removeDuplicates(array) {
590
- const outputArray = [];
591
- for (const item of array) if (!outputArray.includes(item)) outputArray.push(item);
592
- return outputArray;
681
+ //#region src/functions/recursive/deepCopy.ts
682
+ function callDeepCopy(input) {
683
+ return typeof input === "object" && input !== null ? deepCopy(input) : input;
593
684
  }
594
- var removeDuplicates_default = removeDuplicates;
685
+ /**
686
+ * Deeply copies an object or array such that all child objects/arrays are also copied.
687
+ *
688
+ * @template ObjectType - The type of the input object.
689
+ *
690
+ * @param object - The object to copy. May also be an array.
691
+ *
692
+ * @returns An identical object with a new reference in memory.
693
+ */
694
+ function deepCopy(object) {
695
+ if (Array.isArray(object)) return object.map((item) => {
696
+ return callDeepCopy(item);
697
+ });
698
+ const clonedObject = { ...object };
699
+ for (const key in clonedObject) {
700
+ const value = clonedObject[key];
701
+ clonedObject[key] = callDeepCopy(value);
702
+ }
703
+ return clonedObject;
704
+ }
705
+ var deepCopy_default = deepCopy;
595
706
 
596
707
  //#endregion
597
- //#region src/functions/stringListToArray.ts
598
- function stringListToArray(stringList, { separator = ",", trimWhitespace = true } = {}) {
599
- if (trimWhitespace && stringList.trim() === "") return [];
600
- const arrayList = stringList.split(separator ?? "");
601
- return trimWhitespace ? arrayList.map((item) => {
602
- return item.trim();
603
- }) : arrayList;
708
+ //#region src/functions/recursive/deepFreeze.ts
709
+ /**
710
+ * Deeply freezes an object or array such that all child objects/arrays are also frozen.
711
+ *
712
+ * Note that this will also freeze the input itself as well.
713
+ * If the intent is to create a newly frozen object with a different reference in memory, pass your object through deepCopy first before passing to deepFreeze.
714
+ *
715
+ * @template ObjectType - The type of the input object.
716
+ *
717
+ * @param object - The object to freeze. May also be an array.
718
+ *
719
+ * @returns The input object completely frozen.
720
+ */
721
+ function deepFreeze(object) {
722
+ for (const value of Object.values(object)) {
723
+ if (typeof value === "function") continue;
724
+ if (value && typeof value === "object") deepFreeze(value);
725
+ }
726
+ return Object.freeze(object);
604
727
  }
605
- var stringListToArray_default = stringListToArray;
728
+ var deepFreeze_default = deepFreeze;
729
+
730
+ //#endregion
731
+ //#region src/functions/stringHelpers/appendSemicolon.ts
732
+ /**
733
+ * Appends a semicolon to the end of a string, trimming where necessary first.
734
+ *
735
+ * @param stringToAppendTo - The string to append a semicolon to.
736
+ *
737
+ * @throws {Error} If the string contains multiple lines.
738
+ *
739
+ * @returns A string with the semicolon appended.
740
+ */
741
+ function appendSemicolon(stringToAppendTo) {
742
+ if (stringToAppendTo.includes("\n")) throw new Error("MULTIPLE_LINE_ERROR");
743
+ const stringWithNoTrailingWhitespace = stringToAppendTo.trimEnd();
744
+ if (stringWithNoTrailingWhitespace === "") return "";
745
+ return stringWithNoTrailingWhitespace[stringWithNoTrailingWhitespace.length - 1] === ";" ? stringWithNoTrailingWhitespace : `${stringWithNoTrailingWhitespace};`;
746
+ }
747
+ var appendSemicolon_default = appendSemicolon;
748
+
749
+ //#endregion
750
+ //#region src/functions/stringHelpers/camelToKebab.ts
751
+ /**
752
+ * Converts a string from camelCase to kebab-case
753
+ *
754
+ * @param string - The string to convert.
755
+ *
756
+ * @returns The string converted to kebab-case.
757
+ */
758
+ function camelToKebab(string) {
759
+ return string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").toLowerCase();
760
+ }
761
+ var camelToKebab_default = camelToKebab;
762
+
763
+ //#endregion
764
+ //#region src/functions/stringHelpers/kebabToCamel.ts
765
+ /**
766
+ * Converts a string from kebab-case to camelCase
767
+ *
768
+ * @param string - The string to convert.
769
+ * @param options - Options to apply to the conversion.
770
+ *
771
+ * @returns The string converted to camelCase.
772
+ */
773
+ function kebabToCamel(string, options) {
774
+ if (string !== string.toLowerCase()) throw new Error("INVALID_KEBAB_CASE_INPUT");
775
+ if (string.startsWith("-") || string.endsWith("-") || string.includes("--")) throw new Error("INVALID_KEBAB_CASE_INPUT");
776
+ let outputString = "";
777
+ let skip = false;
778
+ for (const stringIndex in [...string]) {
779
+ if (skip) {
780
+ skip = false;
781
+ continue;
782
+ }
783
+ const index = parseIntStrict_default(stringIndex);
784
+ if (index === 0 && options?.startWithUpper) {
785
+ outputString += string[index].toUpperCase();
786
+ continue;
787
+ }
788
+ if (index === string.length - 1) {
789
+ outputString += string[index];
790
+ break;
791
+ }
792
+ if (string[index] === "-" && /^[a-zA-Z]+$/.test(string[index + 1])) {
793
+ outputString += string[index + 1].toUpperCase();
794
+ skip = true;
795
+ } else outputString += string[index];
796
+ }
797
+ return outputString;
798
+ }
799
+ var kebabToCamel_default = kebabToCamel;
800
+
801
+ //#endregion
802
+ //#region src/functions/stringHelpers/normalizeImportPath.ts
803
+ /**
804
+ * Normalizes an import path meant for use in an import statement in JavaScript.
805
+ *
806
+ * When multiple slashes are found, they're replaced by a single one; when the path contains a trailing slash, it is preserved. On Windows backslashes are used. If the path is a zero-length string, '.' is returned, representing the current working directory.
807
+ *
808
+ * If the path starts with ./, it is preserved (unlike what would happen with path.posix.normalize() normally).
809
+ *
810
+ * Helpful for custom linter rules that need to check (or fix) import paths.
811
+ *
812
+ * @param importPath - The import path to normalize.
813
+ *
814
+ * @returns The import path normalized.
815
+ */
816
+ function normalizeImportPath(importPath) {
817
+ const normalizedPath = path.posix.normalize(importPath);
818
+ if (importPath.startsWith("./") && !normalizedPath.startsWith("./")) return `./${normalizedPath}`;
819
+ return normalizedPath;
820
+ }
821
+ /**
822
+ * Normalises an import path meant for use in an import statement in JavaScript.
823
+ *
824
+ * When multiple slashes are found, they're replaced by a single one; when the path contains a trailing slash, it is preserved. On Windows backslashes are used. If the path is a zero-length string, '.' is returned, representing the current working directory.
825
+ *
826
+ * If the path starts with ./, it is preserved (unlike what would happen with path.posix.normalize() normally).
827
+ *
828
+ * Helpful for custom linter rules that need to check (or fix) import paths.
829
+ *
830
+ * @param importPath - The import path to normalise.
831
+ *
832
+ * @returns The import path normalised.
833
+ */
834
+ const normaliseImportPath = normalizeImportPath;
835
+ var normalizeImportPath_default = normalizeImportPath;
836
+
837
+ //#endregion
838
+ //#region src/functions/stringHelpers/truncate.ts
839
+ /**
840
+ * Truncates a string and appends `...` to the end of it
841
+ *
842
+ * @param stringToTruncate - The string to truncate.
843
+ * @param maxLength - The length at which to start truncating. Note that this does not include the `...` part that would be appended.
844
+ *
845
+ * @returns A new string that has been truncated based on the length provided.
846
+ */
847
+ function truncate(stringToTruncate, maxLength = 5) {
848
+ return stringToTruncate.length > maxLength ? `${stringToTruncate.slice(0, maxLength)}...` : stringToTruncate;
849
+ }
850
+ var truncate_default = truncate;
851
+
852
+ //#endregion
853
+ //#region src/functions/taggedTemplate/createTemplateStringsArray.ts
854
+ /**
855
+ * Creates a template strings array given a regular array of strings
856
+ *
857
+ * @param strings - The array of strings.
858
+ *
859
+ * @returns A template strings array that can be passed as the first argument of any tagged template function.
860
+ */
861
+ function createTemplateStringsArray(strings) {
862
+ return deepFreeze_default(Object.assign([...strings], { raw: [...strings] }));
863
+ }
864
+ var createTemplateStringsArray_default = createTemplateStringsArray;
606
865
 
607
866
  //#endregion
608
867
  //#region src/functions/taggedTemplate/interpolate.ts
868
+ /**
869
+ * Returns the result of interpolating a template string when given the strings and interpolations separately.
870
+ *
871
+ * You can pass a template string directly by doing:
872
+ *
873
+ * interpolate`Template string here`.
874
+ *
875
+ * In this case, it will be functionally the same as if you just wrote the template string by itself.
876
+ *
877
+ * @param strings - The strings from the template to process.
878
+ * @param interpolations - An array of all interpolations from the template.
879
+ *
880
+ * @returns A new string with the strings and interpolations from the template applied.
881
+ */
609
882
  function interpolate(strings, ...interpolations) {
610
883
  let result = "";
611
884
  for (const [string, interpolation = ""] of paralleliseArrays_default(strings, interpolations)) result += string + interpolation;
@@ -615,11 +888,23 @@ var interpolate_default = interpolate;
615
888
 
616
889
  //#endregion
617
890
  //#region src/functions/taggedTemplate/interpolateObjects.ts
618
- function interpolateObjects(strings, ...values) {
891
+ /**
892
+ * Returns the result of interpolating a template string, also stringifying objects.
893
+ *
894
+ * You can pass a template string directly by doing:
895
+ *
896
+ * interpolateObjects`Template string here ${{ my: "object" }}`.
897
+ *
898
+ * @param strings - The strings from the template to process.
899
+ * @param interpolations - An array of all interpolations from the template.
900
+ *
901
+ * @returns A new string with the strings and interpolations from the template applied, with objects stringified.
902
+ */
903
+ function interpolateObjects(strings, ...interpolations) {
619
904
  let result = "";
620
905
  for (let i = 0; i < strings.length; i++) {
621
906
  result += strings[i];
622
- if (i !== strings.length - 1) result += values[i] && typeof values[i] === "object" ? JSON.stringify(values[i]) : values[i];
907
+ if (i !== strings.length - 1) result += interpolations[i] && typeof interpolations[i] === "object" ? JSON.stringify(interpolations[i]) : interpolations[i];
623
908
  }
624
909
  return result;
625
910
  }
@@ -651,6 +936,26 @@ function reduceLines$1(lines, { preserveTabs = true }) {
651
936
  }, tabSize).join("") : "") + line.trimStart();
652
937
  }).join("\n");
653
938
  }
939
+ /**
940
+ * Applies any options if provided, then removes any extraneous indents from a multi-line template string.
941
+ *
942
+ * You can pass a template string directly by doing:
943
+ *
944
+ * normaliseIndents`Template string here
945
+ * with a new line
946
+ * and another new line`.
947
+ *
948
+ * You may also pass the options first, then invoke the resulting function with a template string:
949
+ *
950
+ * normaliseIndents({ preserveTabs: false })`Template string here
951
+ * with a new line
952
+ * and another new line`.
953
+ *
954
+ * @param first - The strings from the template to process, or the options to apply.
955
+ * @param args - An array of all interpolations from the template.
956
+ *
957
+ * @returns An additional function to invoke, or a new string with the strings and interpolations from the template applied, and extraneous indents removed.
958
+ */
654
959
  function normaliseIndents(first, ...args) {
655
960
  if (typeof first === "object" && first !== null && !Array.isArray(first)) {
656
961
  const options$1 = first;
@@ -662,6 +967,26 @@ function normaliseIndents(first, ...args) {
662
967
  const options = typeof args[args.length - 1] === "object" && !Array.isArray(args[args.length - 1]) ? args.pop() : {};
663
968
  return reduceLines$1(interpolate_default(strings, ...[...args]).split("\n"), options);
664
969
  }
970
+ /**
971
+ * Applies any options if provided, then removes any extraneous indents from a multi-line template string.
972
+ *
973
+ * You can pass a template string directly by doing:
974
+ *
975
+ * normalizeIndents`Template string here
976
+ * with a new line
977
+ * and another new line`.
978
+ *
979
+ * You may also pass the options first, then invoke the resulting function with a template string:
980
+ *
981
+ * normalizeIndents({ preserveTabs: false })`Template string here
982
+ * with a new line
983
+ * and another new line`.
984
+ *
985
+ * @param first - The strings from the template to process, or the options to apply.
986
+ * @param args - An array of all interpolations from the template.
987
+ *
988
+ * @returns An additional function to invoke, or a new string with the strings and interpolations from the template applied, and extraneous indents removed.
989
+ */
665
990
  const normalizeIndents = normaliseIndents;
666
991
  var normaliseIndents_default = normaliseIndents;
667
992
 
@@ -705,22 +1030,4 @@ function removeIndents(first, ...args) {
705
1030
  var removeIndents_default = removeIndents;
706
1031
 
707
1032
  //#endregion
708
- //#region src/functions/truncate.ts
709
- function truncate(stringToTruncate, maxLength = 5) {
710
- return stringToTruncate.length > maxLength ? `${stringToTruncate.slice(0, maxLength)}...` : stringToTruncate;
711
- }
712
- var truncate_default = truncate;
713
-
714
- //#endregion
715
- //#region src/functions/wait.ts
716
- function wait(seconds) {
717
- return new Promise((resolve, _) => {
718
- setTimeout(() => {
719
- resolve();
720
- }, seconds * 1e3);
721
- });
722
- }
723
- var wait_default = wait;
724
-
725
- //#endregion
726
- export { APIError_default as APIError, DataError_default as DataError, NAMESPACE_EXPORT_REGEX_default as NAMESPACE_EXPORT_REGEX, addDaysToDate_default as addDaysToDate, appendSemicolon_default as appendSemicolon, camelToKebab_default as camelToKebab, convertFileToBase64_default as convertFileToBase64, createFormData_default as createFormData, createTemplateStringsArray_default as createTemplateStringsArray, deepCopy_default as deepCopy, deepFreeze_default as deepFreeze, fillArray_default as fillArray, formatDateAndTime_default as formatDateAndTime, getRandomNumber_default as getRandomNumber, getRecordKeys_default as getRecordKeys, httpErrorCodeLookup, interpolate_default as interpolate, interpolateObjects_default as interpolateObjects, isAnniversary_default as isAnniversary, isLeapYear_default as isLeapYear, isMonthlyMultiple_default as isMonthlyMultiple, isOrdered_default as isOrdered, isSameDate_default as isSameDate, kebabToCamel_default as kebabToCamel, normaliseImportPath, normaliseIndents_default as normaliseIndents, normalizeImportPath_default as normalizeImportPath, normalizeIndents, omitProperties_default as omitProperties, paralleliseArrays_default as paralleliseArrays, parseBoolean_default as parseBoolean, Email_default as parseEmail, Env_default as parseEnv, parseFormData_default as parseFormData, parseIntStrict_default as parseIntStrict, UUID_default as parseUUID, parseZodSchema_default as parseZodSchema, randomiseArray_default as randomiseArray, range_default as range, removeDuplicates_default as removeDuplicates, removeIndents_default as removeIndents, stringListToArray_default as stringListToArray, stringToBoolean, truncate_default as truncate, wait_default as wait };
1033
+ export { APIError_default as APIError, DataError_default as DataError, NAMESPACE_EXPORT_REGEX_default as NAMESPACE_EXPORT_REGEX, addDaysToDate_default as addDaysToDate, appendSemicolon_default as appendSemicolon, camelToKebab_default as camelToKebab, convertFileToBase64_default as convertFileToBase64, createFormData_default as createFormData, createTemplateStringsArray_default as createTemplateStringsArray, deepCopy_default as deepCopy, deepFreeze_default as deepFreeze, fillArray_default as fillArray, formatDateAndTime_default as formatDateAndTime, getRandomNumber_default as getRandomNumber, getRecordKeys_default as getRecordKeys, httpErrorCodeLookup, interpolate_default as interpolate, interpolateObjects_default as interpolateObjects, isAnniversary_default as isAnniversary, isLeapYear_default as isLeapYear, isMonthlyMultiple_default as isMonthlyMultiple, isOrdered_default as isOrdered, isSameDate_default as isSameDate, kebabToCamel_default as kebabToCamel, normaliseImportPath, normaliseIndents_default as normaliseIndents, normalizeImportPath_default as normalizeImportPath, normalizeIndents, omitProperties_default as omitProperties, paralleliseArrays_default as paralleliseArrays, parseBoolean_default as parseBoolean, Email_default as parseEmail, parseEnv_default as parseEnv, parseFormData_default as parseFormData, parseIntStrict_default as parseIntStrict, UUID_default as parseUUID, parseZodSchema_default as parseZodSchema, randomiseArray_default as randomiseArray, range_default as range, removeDuplicates_default as removeDuplicates, removeIndents_default as removeIndents, stringListToArray_default as stringListToArray, stringToBoolean, truncate_default as truncate, wait_default as wait };