@alextheman/utility 5.1.3 → 5.2.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
@@ -134,6 +134,17 @@ var DataError = class DataError extends Error {
134
134
  Object.defineProperty(this, "message", { enumerable: true });
135
135
  Object.setPrototypeOf(this, new.target.prototype);
136
136
  }
137
+ static checkCaughtError(error, options) {
138
+ if (DataError.check(error)) {
139
+ if (options?.expectedCode && error.code !== options.expectedCode) throw new Error(normaliseIndents`The error code on the thrown error does not match the expected error code.
140
+
141
+ Expected: ${options.expectedCode}
142
+ Received: ${error.code}
143
+ `, { cause: error });
144
+ return error;
145
+ }
146
+ throw error;
147
+ }
137
148
  /**
138
149
  * Checks whether the given input may have been caused by a DataError.
139
150
  *
@@ -146,6 +157,44 @@ var DataError = class DataError extends Error {
146
157
  const data = input;
147
158
  return typeof data === "object" && data !== null && typeof data.message === "string" && typeof data.code === "string" && "data" in data;
148
159
  }
160
+ /**
161
+ * Gets the thrown `DataError` from a given function if one was thrown, and re-throws any other errors, or throws a default `DataError` if no error thrown.
162
+ *
163
+ * @param errorFunction - The function expected to throw the error.
164
+ * @param options - Extra options to apply.
165
+ *
166
+ * @throws {Error} Any other errors thrown by the `errorFunction` that are not a `DataError`.
167
+ * @throws {Error} If no `DataError` was thrown by the `errorFunction`
168
+ *
169
+ * @returns The `DataError` that was thrown by the `errorFunction`
170
+ */
171
+ static expectError(errorFunction, options) {
172
+ try {
173
+ errorFunction();
174
+ } catch (error) {
175
+ return DataError.checkCaughtError(error, options);
176
+ }
177
+ throw new Error("Expected a DataError to be thrown but none was thrown");
178
+ }
179
+ /**
180
+ * Gets the thrown `DataError` from a given asynchronous function if one was thrown, and re-throws any other errors, or throws a default `DataError` if no error thrown.
181
+ *
182
+ * @param errorFunction - The function expected to throw the error.
183
+ * @param options - Extra options to apply.
184
+ *
185
+ * @throws {Error} Any other errors thrown by the `errorFunction` that are not a `DataError`.
186
+ * @throws {Error} If no `DataError` was thrown by the `errorFunction`
187
+ *
188
+ * @returns The `DataError` that was thrown by the `errorFunction`
189
+ */
190
+ static async expectErrorAsync(errorFunction, options) {
191
+ try {
192
+ await errorFunction();
193
+ } catch (error) {
194
+ return DataError.checkCaughtError(error, options);
195
+ }
196
+ throw new Error("Expected a DataError to be thrown but none was thrown");
197
+ }
149
198
  };
150
199
 
151
200
  //#endregion
@@ -400,19 +449,27 @@ function randomiseArray(array) {
400
449
  * @param stop - The number to stop at (exclusive).
401
450
  * @param step - The step size between numbers, defaulting to 1.
402
451
  *
403
- * @throws {Error} If `step` is `0`.
404
- * @throws {Error} If `step` direction does not match the order of `start` and `stop`.
452
+ * @throws {DataError} If `step` is `0`.
453
+ * @throws {DataError} If `step` direction does not match the order of `start` and `stop`.
405
454
  *
406
455
  * @returns An array of numbers satisfying the range provided.
407
456
  */
408
457
  function range(start, stop, step = 1) {
409
458
  const numbers = [];
410
- if (step === 0) throw new Error("ZERO_STEP_SIZE_NOT_ALLOWED");
459
+ if (step === 0) throw new DataError({ step }, "ZERO_STEP_SIZE", "Step size cannot be zero.");
411
460
  else if (step > 0) {
412
- if (start > stop) throw new Error("INVALID_BOUNDARIES");
461
+ if (start > stop) throw new DataError({
462
+ start,
463
+ stop,
464
+ step
465
+ }, "INVALID_BOUNDARIES", "The starting value cannot be bigger than the final value if step is positive");
413
466
  for (let i = start; i < stop; i += step) numbers.push(i);
414
467
  } else if (step < 0) {
415
- if (start < stop) throw new Error("INVALID_BOUNDARIES");
468
+ if (start < stop) throw new DataError({
469
+ start,
470
+ stop,
471
+ step
472
+ }, "INVALID_BOUNDARIES", "The final value cannot be bigger than the starting value if step is negative");
416
473
  for (let i = start; i > stop; i += step) numbers.push(i);
417
474
  }
418
475
  return numbers;
@@ -583,25 +640,6 @@ function isMonthlyMultiple(firstDate, secondDate) {
583
640
  return firstDate.getDate() === secondDate.getDate();
584
641
  }
585
642
 
586
- //#endregion
587
- //#region src/internal/getDependenciesFromGroup.ts
588
- /**
589
- * Get the dependencies from a given dependency group in `package.json`.
590
- *
591
- * @category Miscellaneous
592
- *
593
- * @param packageInfo - The data coming from `package.json`.
594
- * @param dependencyGroup - The group to get dependency information about (can be `dependencies` or `devDependencies`).
595
- *
596
- * @returns A record consisting of the package names and version ranges from the given dependency group.
597
- */
598
- function getDependenciesFromGroup(packageInfo, dependencyGroup) {
599
- return {
600
- dependencies: parseZodSchema(z.record(z.string(), z.string()), packageInfo.dependencies ?? {}),
601
- devDependencies: parseZodSchema(z.record(z.string(), z.string()), packageInfo.devDependencies ?? {})
602
- }[dependencyGroup];
603
- }
604
-
605
643
  //#endregion
606
644
  //#region src/root/functions/miscellaneous/convertFileToBase64.ts
607
645
  /**
@@ -611,7 +649,7 @@ function getDependenciesFromGroup(packageInfo, dependencyGroup) {
611
649
  *
612
650
  * @param file - The file to convert.
613
651
  *
614
- * @throws {Error} If the file reader gives an error.
652
+ * @throws {Error | DataError} If the file reader gives an error.
615
653
  *
616
654
  * @returns A promise that resolves to the encoded base 64 string.
617
655
  */
@@ -621,7 +659,7 @@ function convertFileToBase64(file) {
621
659
  reader.readAsDataURL(file);
622
660
  reader.onload = () => {
623
661
  if (reader.result === null) {
624
- reject(/* @__PURE__ */ new Error("FILE_CONVERSION_ERROR"));
662
+ reject(new DataError({ result: reader.result }, "FILE_CONVERSION_ERROR", "Could not convert the given file."));
625
663
  return;
626
664
  }
627
665
  resolve(reader.result);
@@ -637,6 +675,9 @@ function convertFileToBase64(file) {
637
675
  function getNullableResolutionStrategy(key, strategy) {
638
676
  return (typeof strategy === "object" ? strategy[key] : strategy) ?? "empty";
639
677
  }
678
+ function isPrimitive(item) {
679
+ return typeof item === "string" || typeof item === "number" || typeof item === "boolean";
680
+ }
640
681
  /**
641
682
  * Creates FormData from a given object, resolving non-string types as appropriate.
642
683
  *
@@ -663,7 +704,7 @@ function createFormData(data, options = {
663
704
  formData.append(String(key), JSON.stringify(value));
664
705
  break;
665
706
  case "omit": break;
666
- default: throw new TypeError("SLOPPY_PURE_JAVASCRIPT_USER_ERROR");
707
+ default: throw resolutionStrategy;
667
708
  }
668
709
  }
669
710
  function resolveNullables(key, value, options) {
@@ -686,10 +727,10 @@ function createFormData(data, options = {
686
727
  if (Array.isArray(value)) {
687
728
  if (value.some((item) => {
688
729
  return item instanceof Blob;
689
- }) && (options.arrayResolution === "stringify" || typeof options.arrayResolution === "object" && options.arrayResolution[key] === "stringify")) throw new TypeError("CANNOT_STRINGIFY_BLOB");
730
+ }) && (options.arrayResolution === "stringify" || typeof options.arrayResolution === "object" && options.arrayResolution[key] === "stringify")) throw new DataError({ value }, "CANNOT_STRINGIFY_BLOB", "Files/blobs cannot be stringified. Please change the resolution option for this item to \"multiple\" instead.");
690
731
  if (options.arrayResolution === "multiple" || typeof options.arrayResolution === "object" && options.arrayResolution[key] === "multiple") {
691
732
  for (const item of value) {
692
- if ((typeof item === "object" || !item) && !(item instanceof Blob)) throw new TypeError("NON_PRIMITIVE_ARRAY_ITEMS_FOUND");
733
+ if (!isPrimitive(item) && !(item instanceof Blob)) throw new DataError({ item }, "NON_PRIMITIVE_ARRAY_ITEMS_FOUND", "Cannot directly add non-primitive data to FormData. Please change the resolution option for this item to \"stringify\" instead.");
693
734
  if (item instanceof Blob) formData.append(String(key), item);
694
735
  else formData.append(String(key), String(item));
695
736
  }
@@ -1431,12 +1472,12 @@ async function encryptWithKey(publicKey, plaintextValue) {
1431
1472
  *
1432
1473
  * @param stringToAppendTo - The string to append a semicolon to.
1433
1474
  *
1434
- * @throws {Error} If the string contains multiple lines.
1475
+ * @throws {DataError} If the string contains multiple lines.
1435
1476
  *
1436
1477
  * @returns A string with the semicolon appended.
1437
1478
  */
1438
1479
  function appendSemicolon(stringToAppendTo) {
1439
- if (stringToAppendTo.includes("\n")) throw new Error("MULTIPLE_LINE_ERROR");
1480
+ if (stringToAppendTo.includes("\n")) throw new DataError({ stringToAppendTo }, "MULTIPLE_LINE_ERROR", "Cannot append semicolon to multi-line string.");
1440
1481
  const stringWithNoTrailingWhitespace = stringToAppendTo.trimEnd();
1441
1482
  if (stringWithNoTrailingWhitespace === "") return "";
1442
1483
  return stringWithNoTrailingWhitespace[stringWithNoTrailingWhitespace.length - 1] === ";" ? stringWithNoTrailingWhitespace : `${stringWithNoTrailingWhitespace};`;
@@ -1488,34 +1529,35 @@ function camelToKebab(string, options = { preserveConsecutiveCapitals: true }) {
1488
1529
  *
1489
1530
  * @category String Helpers
1490
1531
  *
1491
- * @param string - The string to convert.
1532
+ * @param input - The string to convert.
1492
1533
  * @param options - Options to apply to the conversion.
1493
1534
  *
1494
1535
  * @returns The string converted to camelCase.
1495
1536
  */
1496
- function kebabToCamel(string, options) {
1497
- if (string !== string.toLowerCase()) throw new Error("INVALID_KEBAB_CASE_INPUT");
1498
- if (string.startsWith("-") || string.endsWith("-") || string.includes("--")) throw new Error("INVALID_KEBAB_CASE_INPUT");
1537
+ function kebabToCamel(input, options) {
1538
+ if (input !== input.toLowerCase()) throw new DataError({ input }, "UPPERCASE_INPUT", "Kebab-case must be purely lowercase.");
1539
+ if (input.startsWith("-") || input.endsWith("-")) throw new DataError({ input }, "TRAILING_DASHES", "Dashes at the start and/or end are not allowed.");
1540
+ if (input.includes("--")) throw new DataError({ input }, "CONSECUTIVE_DASHES", "Consecutive dashes are not allowed.");
1499
1541
  let outputString = "";
1500
1542
  let skip = false;
1501
- for (const stringIndex in [...string]) {
1543
+ for (const stringIndex in [...input]) {
1502
1544
  if (skip) {
1503
1545
  skip = false;
1504
1546
  continue;
1505
1547
  }
1506
1548
  const index = parseIntStrict(stringIndex);
1507
1549
  if (index === 0 && options?.startWithUpper) {
1508
- outputString += string[index].toUpperCase();
1550
+ outputString += input[index].toUpperCase();
1509
1551
  continue;
1510
1552
  }
1511
- if (index === string.length - 1) {
1512
- outputString += string[index];
1553
+ if (index === input.length - 1) {
1554
+ outputString += input[index];
1513
1555
  break;
1514
1556
  }
1515
- if (string[index] === "-" && /^[a-zA-Z]+$/.test(string[index + 1])) {
1516
- outputString += string[index + 1].toUpperCase();
1557
+ if (input[index] === "-" && /^[a-zA-Z]+$/.test(input[index + 1])) {
1558
+ outputString += input[index + 1].toUpperCase();
1517
1559
  skip = true;
1518
- } else outputString += string[index];
1560
+ } else outputString += input[index];
1519
1561
  }
1520
1562
  return outputString;
1521
1563
  }
@@ -1537,4 +1579,4 @@ function truncate(stringToTruncate, maxLength = 5) {
1537
1579
  }
1538
1580
 
1539
1581
  //#endregion
1540
- export { APIError, DataError, Env, FILE_PATH_REGEX, NAMESPACE_EXPORT_REGEX, VERSION_NUMBER_REGEX, VersionNumber, VersionType, addDaysToDate, appendSemicolon, camelToKebab, convertFileToBase64, createFormData, createTemplateStringsArray, deepCopy, deepFreeze, encryptWithKey, fillArray, formatDateAndTime, getDependenciesFromGroup, getRandomNumber, getRecordKeys, getStringsAndInterpolations, httpErrorCodeLookup, interpolate, interpolateObjects, isAnniversary, isLeapYear, isMonthlyMultiple, isOrdered, isSameDate, isTemplateStringsArray, kebabToCamel, normaliseIndents, normalizeIndents, omitProperties, paralleliseArrays, parseBoolean, parseEnv, parseFormData, parseIntStrict, parseVersionType, parseZodSchema, parseZodSchemaAsync, randomiseArray, range, removeDuplicates, removeUndefinedFromObject, sayHello, stringListToArray, stringifyDotenv, truncate, wait, zodVersionNumber };
1582
+ export { APIError, DataError, Env, FILE_PATH_REGEX, NAMESPACE_EXPORT_REGEX, VERSION_NUMBER_REGEX, VersionNumber, VersionType, addDaysToDate, appendSemicolon, camelToKebab, convertFileToBase64, createFormData, createTemplateStringsArray, deepCopy, deepFreeze, encryptWithKey, fillArray, formatDateAndTime, getRandomNumber, getRecordKeys, getStringsAndInterpolations, httpErrorCodeLookup, interpolate, interpolateObjects, isAnniversary, isLeapYear, isMonthlyMultiple, isOrdered, isSameDate, isTemplateStringsArray, kebabToCamel, normaliseIndents, normalizeIndents, omitProperties, paralleliseArrays, parseBoolean, parseEnv, parseFormData, parseIntStrict, parseVersionType, parseZodSchema, parseZodSchemaAsync, randomiseArray, range, removeDuplicates, removeUndefinedFromObject, sayHello, stringListToArray, stringifyDotenv, truncate, wait, zodVersionNumber };
@@ -118,6 +118,17 @@ var DataError = class DataError extends Error {
118
118
  Object.defineProperty(this, "message", { enumerable: true });
119
119
  Object.setPrototypeOf(this, new.target.prototype);
120
120
  }
121
+ static checkCaughtError(error, options) {
122
+ if (DataError.check(error)) {
123
+ if (options?.expectedCode && error.code !== options.expectedCode) throw new Error(normaliseIndents`The error code on the thrown error does not match the expected error code.
124
+
125
+ Expected: ${options.expectedCode}
126
+ Received: ${error.code}
127
+ `, { cause: error });
128
+ return error;
129
+ }
130
+ throw error;
131
+ }
121
132
  /**
122
133
  * Checks whether the given input may have been caused by a DataError.
123
134
  *
@@ -130,6 +141,44 @@ var DataError = class DataError extends Error {
130
141
  const data = input;
131
142
  return typeof data === "object" && data !== null && typeof data.message === "string" && typeof data.code === "string" && "data" in data;
132
143
  }
144
+ /**
145
+ * Gets the thrown `DataError` from a given function if one was thrown, and re-throws any other errors, or throws a default `DataError` if no error thrown.
146
+ *
147
+ * @param errorFunction - The function expected to throw the error.
148
+ * @param options - Extra options to apply.
149
+ *
150
+ * @throws {Error} Any other errors thrown by the `errorFunction` that are not a `DataError`.
151
+ * @throws {Error} If no `DataError` was thrown by the `errorFunction`
152
+ *
153
+ * @returns The `DataError` that was thrown by the `errorFunction`
154
+ */
155
+ static expectError(errorFunction, options) {
156
+ try {
157
+ errorFunction();
158
+ } catch (error) {
159
+ return DataError.checkCaughtError(error, options);
160
+ }
161
+ throw new Error("Expected a DataError to be thrown but none was thrown");
162
+ }
163
+ /**
164
+ * Gets the thrown `DataError` from a given asynchronous function if one was thrown, and re-throws any other errors, or throws a default `DataError` if no error thrown.
165
+ *
166
+ * @param errorFunction - The function expected to throw the error.
167
+ * @param options - Extra options to apply.
168
+ *
169
+ * @throws {Error} Any other errors thrown by the `errorFunction` that are not a `DataError`.
170
+ * @throws {Error} If no `DataError` was thrown by the `errorFunction`
171
+ *
172
+ * @returns The `DataError` that was thrown by the `errorFunction`
173
+ */
174
+ static async expectErrorAsync(errorFunction, options) {
175
+ try {
176
+ await errorFunction();
177
+ } catch (error) {
178
+ return DataError.checkCaughtError(error, options);
179
+ }
180
+ throw new Error("Expected a DataError to be thrown but none was thrown");
181
+ }
133
182
  };
134
183
 
135
184
  //#endregion
@@ -1,18 +1,5 @@
1
1
  import { ExecaMethod } from "execa";
2
2
 
3
- //#region src/internal/getDependenciesFromGroup.d.ts
4
- /**
5
- * Get the dependencies from a given dependency group in `package.json`.
6
- *
7
- * @category Miscellaneous
8
- *
9
- * @param packageInfo - The data coming from `package.json`.
10
- * @param dependencyGroup - The group to get dependency information about (can be `dependencies` or `devDependencies`).
11
- *
12
- * @returns A record consisting of the package names and version ranges from the given dependency group.
13
- */
14
- declare function getDependenciesFromGroup(packageInfo: Record<string, unknown>, dependencyGroup: DependencyGroup): Record<string, string>;
15
- //#endregion
16
3
  //#region src/root/types/RecordKey.d.ts
17
4
  /**
18
5
  * Represents the native Record's possible key type.
@@ -22,6 +9,9 @@ declare function getDependenciesFromGroup(packageInfo: Record<string, unknown>,
22
9
  type RecordKey = string | number | symbol;
23
10
  //#endregion
24
11
  //#region src/root/types/DataError.d.ts
12
+ interface ExpectErrorOptions {
13
+ expectedCode?: string;
14
+ }
25
15
  /**
26
16
  * Represents errors you may get that may've been caused by a specific piece of data.
27
17
  *
@@ -39,6 +29,7 @@ declare class DataError<DataType extends Record<RecordKey, unknown> = Record<Rec
39
29
  * @param options - Extra options to pass to super Error constructor.
40
30
  */
41
31
  constructor(data: DataType, code?: string, message?: string, options?: ErrorOptions);
32
+ private static checkCaughtError;
42
33
  /**
43
34
  * Checks whether the given input may have been caused by a DataError.
44
35
  *
@@ -47,6 +38,30 @@ declare class DataError<DataType extends Record<RecordKey, unknown> = Record<Rec
47
38
  * @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`.
48
39
  */
49
40
  static check<DataType extends Record<RecordKey, unknown> = Record<RecordKey, unknown>>(input: unknown): input is DataError<DataType>;
41
+ /**
42
+ * Gets the thrown `DataError` from a given function if one was thrown, and re-throws any other errors, or throws a default `DataError` if no error thrown.
43
+ *
44
+ * @param errorFunction - The function expected to throw the error.
45
+ * @param options - Extra options to apply.
46
+ *
47
+ * @throws {Error} Any other errors thrown by the `errorFunction` that are not a `DataError`.
48
+ * @throws {Error} If no `DataError` was thrown by the `errorFunction`
49
+ *
50
+ * @returns The `DataError` that was thrown by the `errorFunction`
51
+ */
52
+ static expectError(errorFunction: () => unknown, options?: ExpectErrorOptions): DataError;
53
+ /**
54
+ * Gets the thrown `DataError` from a given asynchronous function if one was thrown, and re-throws any other errors, or throws a default `DataError` if no error thrown.
55
+ *
56
+ * @param errorFunction - The function expected to throw the error.
57
+ * @param options - Extra options to apply.
58
+ *
59
+ * @throws {Error} Any other errors thrown by the `errorFunction` that are not a `DataError`.
60
+ * @throws {Error} If no `DataError` was thrown by the `errorFunction`
61
+ *
62
+ * @returns The `DataError` that was thrown by the `errorFunction`
63
+ */
64
+ static expectErrorAsync(errorFunction: () => Promise<unknown>, options?: ExpectErrorOptions): Promise<DataError>;
50
65
  }
51
66
  //#endregion
52
67
  //#region src/root/types/CreateEnumType.d.ts
@@ -79,6 +94,19 @@ declare const DependencyGroup: {
79
94
  };
80
95
  type DependencyGroup = CreateEnumType<typeof DependencyGroup>;
81
96
  //#endregion
97
+ //#region src/internal/getDependenciesFromGroup.d.ts
98
+ /**
99
+ * Get the dependencies from a given dependency group in `package.json`.
100
+ *
101
+ * @category Miscellaneous
102
+ *
103
+ * @param packageInfo - The data coming from `package.json`.
104
+ * @param dependencyGroup - The group to get dependency information about (can be `dependencies` or `devDependencies`).
105
+ *
106
+ * @returns A record consisting of the package names and version ranges from the given dependency group.
107
+ */
108
+ declare function getDependenciesFromGroup(packageInfo: Record<string, unknown>, dependencyGroup: DependencyGroup): Record<string, string>;
109
+ //#endregion
82
110
  //#region src/internal/getExpectedTgzName.d.ts
83
111
  declare function getExpectedTgzName(packagePath: string, packageManager: string): Promise<string>;
84
112
  //#endregion
@@ -1,19 +1,6 @@
1
1
  import z from "zod";
2
2
  import { ExecaMethod } from "execa";
3
3
 
4
- //#region src/internal/getDependenciesFromGroup.d.ts
5
- /**
6
- * Get the dependencies from a given dependency group in `package.json`.
7
- *
8
- * @category Miscellaneous
9
- *
10
- * @param packageInfo - The data coming from `package.json`.
11
- * @param dependencyGroup - The group to get dependency information about (can be `dependencies` or `devDependencies`).
12
- *
13
- * @returns A record consisting of the package names and version ranges from the given dependency group.
14
- */
15
- declare function getDependenciesFromGroup(packageInfo: Record<string, unknown>, dependencyGroup: DependencyGroup): Record<string, string>;
16
- //#endregion
17
4
  //#region src/root/types/RecordKey.d.ts
18
5
  /**
19
6
  * Represents the native Record's possible key type.
@@ -23,6 +10,9 @@ declare function getDependenciesFromGroup(packageInfo: Record<string, unknown>,
23
10
  type RecordKey = string | number | symbol;
24
11
  //#endregion
25
12
  //#region src/root/types/DataError.d.ts
13
+ interface ExpectErrorOptions {
14
+ expectedCode?: string;
15
+ }
26
16
  /**
27
17
  * Represents errors you may get that may've been caused by a specific piece of data.
28
18
  *
@@ -40,6 +30,7 @@ declare class DataError<DataType extends Record<RecordKey, unknown> = Record<Rec
40
30
  * @param options - Extra options to pass to super Error constructor.
41
31
  */
42
32
  constructor(data: DataType, code?: string, message?: string, options?: ErrorOptions);
33
+ private static checkCaughtError;
43
34
  /**
44
35
  * Checks whether the given input may have been caused by a DataError.
45
36
  *
@@ -48,6 +39,30 @@ declare class DataError<DataType extends Record<RecordKey, unknown> = Record<Rec
48
39
  * @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`.
49
40
  */
50
41
  static check<DataType extends Record<RecordKey, unknown> = Record<RecordKey, unknown>>(input: unknown): input is DataError<DataType>;
42
+ /**
43
+ * Gets the thrown `DataError` from a given function if one was thrown, and re-throws any other errors, or throws a default `DataError` if no error thrown.
44
+ *
45
+ * @param errorFunction - The function expected to throw the error.
46
+ * @param options - Extra options to apply.
47
+ *
48
+ * @throws {Error} Any other errors thrown by the `errorFunction` that are not a `DataError`.
49
+ * @throws {Error} If no `DataError` was thrown by the `errorFunction`
50
+ *
51
+ * @returns The `DataError` that was thrown by the `errorFunction`
52
+ */
53
+ static expectError(errorFunction: () => unknown, options?: ExpectErrorOptions): DataError;
54
+ /**
55
+ * Gets the thrown `DataError` from a given asynchronous function if one was thrown, and re-throws any other errors, or throws a default `DataError` if no error thrown.
56
+ *
57
+ * @param errorFunction - The function expected to throw the error.
58
+ * @param options - Extra options to apply.
59
+ *
60
+ * @throws {Error} Any other errors thrown by the `errorFunction` that are not a `DataError`.
61
+ * @throws {Error} If no `DataError` was thrown by the `errorFunction`
62
+ *
63
+ * @returns The `DataError` that was thrown by the `errorFunction`
64
+ */
65
+ static expectErrorAsync(errorFunction: () => Promise<unknown>, options?: ExpectErrorOptions): Promise<DataError>;
51
66
  }
52
67
  //#endregion
53
68
  //#region src/root/types/CreateEnumType.d.ts
@@ -80,6 +95,19 @@ declare const DependencyGroup: {
80
95
  };
81
96
  type DependencyGroup = CreateEnumType<typeof DependencyGroup>;
82
97
  //#endregion
98
+ //#region src/internal/getDependenciesFromGroup.d.ts
99
+ /**
100
+ * Get the dependencies from a given dependency group in `package.json`.
101
+ *
102
+ * @category Miscellaneous
103
+ *
104
+ * @param packageInfo - The data coming from `package.json`.
105
+ * @param dependencyGroup - The group to get dependency information about (can be `dependencies` or `devDependencies`).
106
+ *
107
+ * @returns A record consisting of the package names and version ranges from the given dependency group.
108
+ */
109
+ declare function getDependenciesFromGroup(packageInfo: Record<string, unknown>, dependencyGroup: DependencyGroup): Record<string, string>;
110
+ //#endregion
83
111
  //#region src/internal/getExpectedTgzName.d.ts
84
112
  declare function getExpectedTgzName(packagePath: string, packageManager: string): Promise<string>;
85
113
  //#endregion
@@ -88,6 +88,17 @@ var DataError = class DataError extends Error {
88
88
  Object.defineProperty(this, "message", { enumerable: true });
89
89
  Object.setPrototypeOf(this, new.target.prototype);
90
90
  }
91
+ static checkCaughtError(error, options) {
92
+ if (DataError.check(error)) {
93
+ if (options?.expectedCode && error.code !== options.expectedCode) throw new Error(normaliseIndents`The error code on the thrown error does not match the expected error code.
94
+
95
+ Expected: ${options.expectedCode}
96
+ Received: ${error.code}
97
+ `, { cause: error });
98
+ return error;
99
+ }
100
+ throw error;
101
+ }
91
102
  /**
92
103
  * Checks whether the given input may have been caused by a DataError.
93
104
  *
@@ -100,6 +111,44 @@ var DataError = class DataError extends Error {
100
111
  const data = input;
101
112
  return typeof data === "object" && data !== null && typeof data.message === "string" && typeof data.code === "string" && "data" in data;
102
113
  }
114
+ /**
115
+ * Gets the thrown `DataError` from a given function if one was thrown, and re-throws any other errors, or throws a default `DataError` if no error thrown.
116
+ *
117
+ * @param errorFunction - The function expected to throw the error.
118
+ * @param options - Extra options to apply.
119
+ *
120
+ * @throws {Error} Any other errors thrown by the `errorFunction` that are not a `DataError`.
121
+ * @throws {Error} If no `DataError` was thrown by the `errorFunction`
122
+ *
123
+ * @returns The `DataError` that was thrown by the `errorFunction`
124
+ */
125
+ static expectError(errorFunction, options) {
126
+ try {
127
+ errorFunction();
128
+ } catch (error) {
129
+ return DataError.checkCaughtError(error, options);
130
+ }
131
+ throw new Error("Expected a DataError to be thrown but none was thrown");
132
+ }
133
+ /**
134
+ * Gets the thrown `DataError` from a given asynchronous function if one was thrown, and re-throws any other errors, or throws a default `DataError` if no error thrown.
135
+ *
136
+ * @param errorFunction - The function expected to throw the error.
137
+ * @param options - Extra options to apply.
138
+ *
139
+ * @throws {Error} Any other errors thrown by the `errorFunction` that are not a `DataError`.
140
+ * @throws {Error} If no `DataError` was thrown by the `errorFunction`
141
+ *
142
+ * @returns The `DataError` that was thrown by the `errorFunction`
143
+ */
144
+ static async expectErrorAsync(errorFunction, options) {
145
+ try {
146
+ await errorFunction();
147
+ } catch (error) {
148
+ return DataError.checkCaughtError(error, options);
149
+ }
150
+ throw new Error("Expected a DataError to be thrown but none was thrown");
151
+ }
103
152
  };
104
153
 
105
154
  //#endregion