@alextheman/utility 5.13.1 → 5.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +302 -237
- package/dist/index.d.cts +207 -160
- package/dist/index.d.ts +206 -159
- package/dist/index.js +302 -238
- package/dist/internal/index.cjs +342 -43
- package/dist/internal/index.d.cts +36 -18
- package/dist/internal/index.d.ts +36 -18
- package/dist/internal/index.js +342 -43
- package/dist/node/index.cjs +31 -2
- package/dist/node/index.js +31 -2
- package/dist/v6/index.cjs +31 -4
- package/dist/v6/index.d.cts +40 -32
- package/dist/v6/index.d.ts +40 -32
- package/dist/v6/index.js +32 -4
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -109,6 +109,21 @@ var CodeError = class CodeError extends Error {
|
|
|
109
109
|
throw error;
|
|
110
110
|
}
|
|
111
111
|
/**
|
|
112
|
+
* Check a `CodeError` against its error code
|
|
113
|
+
*
|
|
114
|
+
* This will also automatically narrow down the type of the input to be `CodeError`, with its error code properly typed if this function returns true.
|
|
115
|
+
*
|
|
116
|
+
* @template ErrorCode The type of the error code
|
|
117
|
+
*
|
|
118
|
+
* @param input - The input to check.
|
|
119
|
+
* @param code - The expected code of the resulting error.
|
|
120
|
+
*
|
|
121
|
+
* @returns `true` if the error code matches the expected code, and `false` otherwise. The type of the input will also be narrowed down to CodeError, and its code will be narrowed to the expected code's type if the function returns `true`.
|
|
122
|
+
*/
|
|
123
|
+
static checkWithCode(input, code) {
|
|
124
|
+
return this.check(input) && input.code === code;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
112
127
|
* Gets the thrown `CodeError` from a given function if one was thrown, and re-throws any other errors, or throws a default `CodeError` if no error thrown.
|
|
113
128
|
*
|
|
114
129
|
* @param errorFunction - The function expected to throw the error.
|
|
@@ -164,11 +179,10 @@ var DataError$1 = class DataError$1 extends CodeError {
|
|
|
164
179
|
* @param message - A human-readable error message (e.g. The data provided is invalid).
|
|
165
180
|
* @param options - Extra options to pass to super Error constructor.
|
|
166
181
|
*/
|
|
167
|
-
constructor(data, code
|
|
182
|
+
constructor(data, code, message = "The data provided is invalid", options) {
|
|
168
183
|
super(code, message, options);
|
|
169
184
|
if (Error.captureStackTrace) Error.captureStackTrace(this, new.target);
|
|
170
185
|
this.name = new.target.name;
|
|
171
|
-
this.code = code;
|
|
172
186
|
this.data = data;
|
|
173
187
|
Object.defineProperty(this, "message", { enumerable: true });
|
|
174
188
|
Object.setPrototypeOf(this, new.target.prototype);
|
|
@@ -185,6 +199,21 @@ var DataError$1 = class DataError$1 extends CodeError {
|
|
|
185
199
|
return typeof input === "object" && input !== null && "message" in input && typeof input.message === "string" && "code" in input && typeof input.code === "string" && "data" in input;
|
|
186
200
|
}
|
|
187
201
|
/**
|
|
202
|
+
* Check a `DataError` against its error code
|
|
203
|
+
*
|
|
204
|
+
* This will also automatically narrow down the type of the input to be `DataError`, with its error code properly typed if this function returns true.
|
|
205
|
+
*
|
|
206
|
+
* @template ErrorCode The type of the error code
|
|
207
|
+
*
|
|
208
|
+
* @param input - The input to check.
|
|
209
|
+
* @param code - The expected code of the resulting error.
|
|
210
|
+
*
|
|
211
|
+
* @returns `true` if the error code matches the expected code, and `false` otherwise. The type of the input will also be narrowed down to `DataError`, and its code will be narrowed to the expected code's type if the function returns `true`.
|
|
212
|
+
*/
|
|
213
|
+
static checkWithCode(input, code) {
|
|
214
|
+
return this.check(input) && input.code === code;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
188
217
|
* 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.
|
|
189
218
|
*
|
|
190
219
|
* @param errorFunction - The function expected to throw the error.
|
|
@@ -869,7 +898,217 @@ function parseBoolean(inputString) {
|
|
|
869
898
|
return normalisedString === "true";
|
|
870
899
|
}
|
|
871
900
|
//#endregion
|
|
872
|
-
//#region src/root/
|
|
901
|
+
//#region src/root/types/APIError.ts
|
|
902
|
+
const httpErrorCodeLookup = {
|
|
903
|
+
400: "BAD_REQUEST",
|
|
904
|
+
401: "UNAUTHORISED",
|
|
905
|
+
403: "FORBIDDEN",
|
|
906
|
+
404: "NOT_FOUND",
|
|
907
|
+
418: "I_AM_A_TEAPOT",
|
|
908
|
+
500: "INTERNAL_SERVER_ERROR"
|
|
909
|
+
};
|
|
910
|
+
/**
|
|
911
|
+
* Represents common errors you may get from a HTTP API request.
|
|
912
|
+
*
|
|
913
|
+
* @category Types
|
|
914
|
+
*/
|
|
915
|
+
var APIError = class APIError extends Error {
|
|
916
|
+
status;
|
|
917
|
+
/**
|
|
918
|
+
* @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.
|
|
919
|
+
* @param message - An error message to display alongside the status code.
|
|
920
|
+
* @param options - Extra options to be passed to super Error constructor.
|
|
921
|
+
*/
|
|
922
|
+
constructor(status = 500, message, options) {
|
|
923
|
+
super(message, options);
|
|
924
|
+
this.status = status;
|
|
925
|
+
if (message) this.message = message;
|
|
926
|
+
else this.message = httpErrorCodeLookup[this.status] ?? "API_ERROR";
|
|
927
|
+
Object.defineProperty(this, "message", { enumerable: true });
|
|
928
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
929
|
+
}
|
|
930
|
+
/**
|
|
931
|
+
* Checks whether the given input may have been caused by an APIError.
|
|
932
|
+
*
|
|
933
|
+
* @param input - The input to check.
|
|
934
|
+
*
|
|
935
|
+
* @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`.
|
|
936
|
+
*/
|
|
937
|
+
static check(input) {
|
|
938
|
+
if (input instanceof APIError) return true;
|
|
939
|
+
const data = input;
|
|
940
|
+
return typeof data === "object" && data !== null && typeof data?.status === "number" && typeof data?.message === "string";
|
|
941
|
+
}
|
|
942
|
+
};
|
|
943
|
+
//#endregion
|
|
944
|
+
//#region src/root/types/VersionNumber.ts
|
|
945
|
+
/**
|
|
946
|
+
* Represents a software version number, considered to be made up of a major, minor, and patch part.
|
|
947
|
+
*
|
|
948
|
+
* @category Types
|
|
949
|
+
*/
|
|
950
|
+
var VersionNumber = class VersionNumber {
|
|
951
|
+
static NON_NEGATIVE_TUPLE_ERROR = "Input array must be a tuple of three non-negative integers.";
|
|
952
|
+
/** The major number. Increments when a feature is removed or changed in a way that is not backwards-compatible with the previous release. */
|
|
953
|
+
major = 0;
|
|
954
|
+
/** The minor number. Increments when a new feature is added/deprecated and is expected to be backwards-compatible with the previous release. */
|
|
955
|
+
minor = 0;
|
|
956
|
+
/** The patch number. Increments when the next release is fixing a bug or doing a small refactor that should not be noticeable in practice. */
|
|
957
|
+
patch = 0;
|
|
958
|
+
/**
|
|
959
|
+
* @param input - The input to create a new instance of `VersionNumber` from.
|
|
960
|
+
*/
|
|
961
|
+
constructor(input) {
|
|
962
|
+
if (input instanceof VersionNumber) {
|
|
963
|
+
this.major = input.major;
|
|
964
|
+
this.minor = input.minor;
|
|
965
|
+
this.patch = input.patch;
|
|
966
|
+
} else if (typeof input === "string") {
|
|
967
|
+
if (!VERSION_NUMBER_REGEX.test(input)) throw new DataError$1({ input }, "INVALID_VERSION", `"${input}" is not a valid version number. Version numbers must be of the format "X.Y.Z" or "vX.Y.Z", where X, Y, and Z are non-negative integers.`);
|
|
968
|
+
const [major, minor, patch] = VersionNumber.formatString(input, { omitPrefix: true }).split(".").map((number) => {
|
|
969
|
+
return parseIntStrict(number);
|
|
970
|
+
});
|
|
971
|
+
this.major = major;
|
|
972
|
+
this.minor = minor;
|
|
973
|
+
this.patch = patch;
|
|
974
|
+
} else if (Array.isArray(input)) {
|
|
975
|
+
if (input.length !== 3) throw new DataError$1({ input }, "INVALID_LENGTH", VersionNumber.NON_NEGATIVE_TUPLE_ERROR);
|
|
976
|
+
const [major, minor, patch] = input.map((number) => {
|
|
977
|
+
const parsedInteger = parseIntStrict(number?.toString());
|
|
978
|
+
if (parsedInteger < 0) throw new DataError$1({ input }, "NEGATIVE_INPUTS", VersionNumber.NON_NEGATIVE_TUPLE_ERROR);
|
|
979
|
+
return parsedInteger;
|
|
980
|
+
});
|
|
981
|
+
this.major = major;
|
|
982
|
+
this.minor = minor;
|
|
983
|
+
this.patch = patch;
|
|
984
|
+
} else throw new DataError$1({ input }, "INVALID_INPUT", normaliseIndents`
|
|
985
|
+
The provided input can not be parsed into a valid version number.
|
|
986
|
+
Expected either a string of format X.Y.Z or vX.Y.Z, a tuple of three numbers, or another \`VersionNumber\` instance.
|
|
987
|
+
`);
|
|
988
|
+
}
|
|
989
|
+
/**
|
|
990
|
+
* Gets the current version type of the current instance of `VersionNumber`.
|
|
991
|
+
*
|
|
992
|
+
* @returns Either `"major"`, `"minor"`, or `"patch"`, depending on the version type.
|
|
993
|
+
*/
|
|
994
|
+
get type() {
|
|
995
|
+
if (this.minor === 0 && this.patch === 0) return VersionType.MAJOR;
|
|
996
|
+
if (this.patch === 0) return VersionType.MINOR;
|
|
997
|
+
return VersionType.PATCH;
|
|
998
|
+
}
|
|
999
|
+
static formatString(input, options) {
|
|
1000
|
+
if (options?.omitPrefix) return input.startsWith("v") ? input.slice(1) : input;
|
|
1001
|
+
return input.startsWith("v") ? input : `v${input}`;
|
|
1002
|
+
}
|
|
1003
|
+
/**
|
|
1004
|
+
* Checks if the provided version numbers have the exact same major, minor, and patch numbers.
|
|
1005
|
+
*
|
|
1006
|
+
* @param firstVersion - The first version number to compare.
|
|
1007
|
+
* @param secondVersion - The second version number to compare.
|
|
1008
|
+
*
|
|
1009
|
+
* @returns `true` if the provided version numbers have exactly the same major, minor, and patch numbers, and returns `false` otherwise.
|
|
1010
|
+
*/
|
|
1011
|
+
static isEqual(firstVersion, secondVersion) {
|
|
1012
|
+
return firstVersion.major === secondVersion.major && firstVersion.minor === secondVersion.minor && firstVersion.patch === secondVersion.patch;
|
|
1013
|
+
}
|
|
1014
|
+
/**
|
|
1015
|
+
* Get a formatted string representation of the current version number
|
|
1016
|
+
*
|
|
1017
|
+
* @param options - Options to apply to the string formatting.
|
|
1018
|
+
*
|
|
1019
|
+
* @returns A formatted string representation of the current version number with the options applied.
|
|
1020
|
+
*/
|
|
1021
|
+
format(options) {
|
|
1022
|
+
let baseOutput = `${this.major}`;
|
|
1023
|
+
if (!options?.omitMinor) {
|
|
1024
|
+
baseOutput += `.${this.minor}`;
|
|
1025
|
+
if (!options?.omitPatch) baseOutput += `.${this.patch}`;
|
|
1026
|
+
}
|
|
1027
|
+
return VersionNumber.formatString(baseOutput, { omitPrefix: options?.omitPrefix });
|
|
1028
|
+
}
|
|
1029
|
+
/**
|
|
1030
|
+
* Increments the current version number by the given increment type, returning the result as a new reference in memory.
|
|
1031
|
+
*
|
|
1032
|
+
* @param incrementType - The type of increment. Can be one of the following:
|
|
1033
|
+
* - `"major"`: Change the major version `v1.2.3` → `v2.0.0`
|
|
1034
|
+
* - `"minor"`: Change the minor version `v1.2.3` → `v1.3.0`
|
|
1035
|
+
* - `"patch"`: Change the patch version `v1.2.3` → `v1.2.4`
|
|
1036
|
+
* @param incrementAmount - The amount to increment by (defaults to 1).
|
|
1037
|
+
*
|
|
1038
|
+
* @returns A new instance of `VersionNumber` with the increment applied.
|
|
1039
|
+
*/
|
|
1040
|
+
increment(incrementType, incrementAmount = 1) {
|
|
1041
|
+
const incrementBy = parseIntStrict(String(incrementAmount));
|
|
1042
|
+
const calculatedRawVersion = {
|
|
1043
|
+
major: [
|
|
1044
|
+
this.major + incrementBy,
|
|
1045
|
+
0,
|
|
1046
|
+
0
|
|
1047
|
+
],
|
|
1048
|
+
minor: [
|
|
1049
|
+
this.major,
|
|
1050
|
+
this.minor + incrementBy,
|
|
1051
|
+
0
|
|
1052
|
+
],
|
|
1053
|
+
patch: [
|
|
1054
|
+
this.major,
|
|
1055
|
+
this.minor,
|
|
1056
|
+
this.patch + incrementBy
|
|
1057
|
+
]
|
|
1058
|
+
}[incrementType];
|
|
1059
|
+
try {
|
|
1060
|
+
return new VersionNumber(calculatedRawVersion);
|
|
1061
|
+
} catch (error) {
|
|
1062
|
+
if (DataError$1.check(error) && error.code === "NEGATIVE_INPUTS") throw new DataError$1({
|
|
1063
|
+
currentVersion: this.toString(),
|
|
1064
|
+
calculatedRawVersion: `v${calculatedRawVersion.join(".")}`,
|
|
1065
|
+
incrementAmount
|
|
1066
|
+
}, "NEGATIVE_VERSION", "Cannot apply this increment amount as it would lead to a negative version number.");
|
|
1067
|
+
else throw error;
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
/**
|
|
1071
|
+
* Ensures that the VersionNumber behaves correctly when attempted to be coerced to a string.
|
|
1072
|
+
*
|
|
1073
|
+
* @param hint - Not used as of now, but generally used to help with numeric coercion, I think (which we most likely do not need for version numbers).
|
|
1074
|
+
*
|
|
1075
|
+
* @returns A stringified representation of the current version number, prefixed with `v`.
|
|
1076
|
+
*/
|
|
1077
|
+
[Symbol.toPrimitive](hint) {
|
|
1078
|
+
if (hint === "number") throw new DataError$1({ thisVersion: this.toString() }, "INVALID_COERCION", "VersionNumber cannot be coerced to a number type.");
|
|
1079
|
+
return this.toString();
|
|
1080
|
+
}
|
|
1081
|
+
/**
|
|
1082
|
+
* Ensures that the VersionNumber behaves correctly when attempted to be converted to JSON.
|
|
1083
|
+
*
|
|
1084
|
+
* @returns A stringified representation of the current version number, prefixed with `v`.
|
|
1085
|
+
*/
|
|
1086
|
+
toJSON() {
|
|
1087
|
+
return this.toString();
|
|
1088
|
+
}
|
|
1089
|
+
/**
|
|
1090
|
+
* Get a string representation of the current version number.
|
|
1091
|
+
*
|
|
1092
|
+
* @returns A stringified representation of the current version number with the prefix.
|
|
1093
|
+
*/
|
|
1094
|
+
toString() {
|
|
1095
|
+
const rawString = `${this.major}.${this.minor}.${this.patch}`;
|
|
1096
|
+
return VersionNumber.formatString(rawString, { omitPrefix: false });
|
|
1097
|
+
}
|
|
1098
|
+
};
|
|
1099
|
+
const zodVersionNumber = z$1.union([
|
|
1100
|
+
z$1.string(),
|
|
1101
|
+
z$1.tuple([
|
|
1102
|
+
z$1.number(),
|
|
1103
|
+
z$1.number(),
|
|
1104
|
+
z$1.number()
|
|
1105
|
+
]),
|
|
1106
|
+
z$1.instanceof(VersionNumber)
|
|
1107
|
+
]).transform((rawVersionNumber) => {
|
|
1108
|
+
return new VersionNumber(rawVersionNumber);
|
|
1109
|
+
});
|
|
1110
|
+
//#endregion
|
|
1111
|
+
//#region src/root/zod/_parseZodSchema.ts
|
|
873
1112
|
function _parseZodSchema(parsedResult, input, onError) {
|
|
874
1113
|
if (!parsedResult.success) {
|
|
875
1114
|
if (onError) {
|
|
@@ -893,7 +1132,7 @@ function _parseZodSchema(parsedResult, input, onError) {
|
|
|
893
1132
|
return parsedResult.data;
|
|
894
1133
|
}
|
|
895
1134
|
//#endregion
|
|
896
|
-
//#region src/root/
|
|
1135
|
+
//#region src/root/zod/parseZodSchema.ts
|
|
897
1136
|
/**
|
|
898
1137
|
* An alternative function to zodSchema.parse() that can be used to strictly parse Zod schemas.
|
|
899
1138
|
*
|
|
@@ -901,6 +1140,8 @@ function _parseZodSchema(parsedResult, input, onError) {
|
|
|
901
1140
|
*
|
|
902
1141
|
* @category Parsers
|
|
903
1142
|
*
|
|
1143
|
+
* @deprecated Please use `az.with(schema).parse(input)` instead.
|
|
1144
|
+
*
|
|
904
1145
|
* @template SchemaType - The Zod schema type.
|
|
905
1146
|
* @template ErrorType - The type of error to throw on invalid data.
|
|
906
1147
|
*
|
|
@@ -916,6 +1157,60 @@ function parseZodSchema(schema, input, onError) {
|
|
|
916
1157
|
return _parseZodSchema(schema.safeParse(input), input, onError);
|
|
917
1158
|
}
|
|
918
1159
|
//#endregion
|
|
1160
|
+
//#region src/root/zod/parseZodSchemaAsync.ts
|
|
1161
|
+
/**
|
|
1162
|
+
* An alternative function to zodSchema.parseAsync() that can be used to strictly parse asynchronous Zod schemas.
|
|
1163
|
+
*
|
|
1164
|
+
* @category Parsers
|
|
1165
|
+
*
|
|
1166
|
+
* @deprecated Please use `az.with(schema).parseAsync(input)` instead.
|
|
1167
|
+
*
|
|
1168
|
+
* @template SchemaType - The Zod schema type.
|
|
1169
|
+
* @template ErrorType - The type of error to throw on invalid data.
|
|
1170
|
+
*
|
|
1171
|
+
* @param schema - The Zod schema to use in parsing.
|
|
1172
|
+
* @param input - The data to parse.
|
|
1173
|
+
* @param onError - A custom error to throw on invalid data (defaults to `DataError`). May either be the error itself, or a function that returns the error or nothing. If nothing is returned, the default error is thrown instead.
|
|
1174
|
+
*
|
|
1175
|
+
* @throws {DataError} If the given data cannot be parsed according to the schema.
|
|
1176
|
+
*
|
|
1177
|
+
* @returns The parsed data from the Zod schema.
|
|
1178
|
+
*/
|
|
1179
|
+
async function parseZodSchemaAsync(schema, input, onError) {
|
|
1180
|
+
return _parseZodSchema(await schema.safeParseAsync(input), input, onError);
|
|
1181
|
+
}
|
|
1182
|
+
//#endregion
|
|
1183
|
+
//#region src/root/zod/zodFieldWrapper.ts
|
|
1184
|
+
function zodFieldWrapper(schema) {
|
|
1185
|
+
return z$1.string().trim().transform((value) => {
|
|
1186
|
+
return value === "" ? null : value;
|
|
1187
|
+
}).pipe(schema);
|
|
1188
|
+
}
|
|
1189
|
+
//#endregion
|
|
1190
|
+
//#region src/root/zod/az.ts
|
|
1191
|
+
const az = {
|
|
1192
|
+
field: zodFieldWrapper,
|
|
1193
|
+
fieldNumber: () => {
|
|
1194
|
+
return z$1.coerce.number();
|
|
1195
|
+
},
|
|
1196
|
+
versionNumber: () => {
|
|
1197
|
+
return zodVersionNumber;
|
|
1198
|
+
},
|
|
1199
|
+
fieldDate: () => {
|
|
1200
|
+
return z$1.coerce.date();
|
|
1201
|
+
},
|
|
1202
|
+
with: (schema) => {
|
|
1203
|
+
return {
|
|
1204
|
+
parse: (input, error) => {
|
|
1205
|
+
return parseZodSchema(schema, input, error);
|
|
1206
|
+
},
|
|
1207
|
+
parseAsync: async (input, error) => {
|
|
1208
|
+
return await parseZodSchemaAsync(schema, input, error);
|
|
1209
|
+
}
|
|
1210
|
+
};
|
|
1211
|
+
}
|
|
1212
|
+
};
|
|
1213
|
+
//#endregion
|
|
919
1214
|
//#region src/root/functions/parsers/parseEnv.ts
|
|
920
1215
|
/**
|
|
921
1216
|
* Represents the three common development environments.
|
|
@@ -939,7 +1234,7 @@ const Env = {
|
|
|
939
1234
|
* @returns The specified environment if allowed.
|
|
940
1235
|
*/
|
|
941
1236
|
function parseEnv(input) {
|
|
942
|
-
return
|
|
1237
|
+
return az.with(z.enum(Env)).parse(input, new DataError$1({ input }, "INVALID_ENV", "The provided environment type must be one of `test | development | production`"));
|
|
943
1238
|
}
|
|
944
1239
|
//#endregion
|
|
945
1240
|
//#region src/root/functions/parsers/parseFormData.ts
|
|
@@ -1005,28 +1300,7 @@ const VersionType = {
|
|
|
1005
1300
|
* @returns The given version type if allowed.
|
|
1006
1301
|
*/
|
|
1007
1302
|
function parseVersionType(input) {
|
|
1008
|
-
return
|
|
1009
|
-
}
|
|
1010
|
-
//#endregion
|
|
1011
|
-
//#region src/root/functions/parsers/zod/parseZodSchemaAsync.ts
|
|
1012
|
-
/**
|
|
1013
|
-
* An alternative function to zodSchema.parseAsync() that can be used to strictly parse asynchronous Zod schemas.
|
|
1014
|
-
*
|
|
1015
|
-
* @category Parsers
|
|
1016
|
-
*
|
|
1017
|
-
* @template SchemaType - The Zod schema type.
|
|
1018
|
-
* @template ErrorType - The type of error to throw on invalid data.
|
|
1019
|
-
*
|
|
1020
|
-
* @param schema - The Zod schema to use in parsing.
|
|
1021
|
-
* @param input - The data to parse.
|
|
1022
|
-
* @param onError - A custom error to throw on invalid data (defaults to `DataError`). May either be the error itself, or a function that returns the error or nothing. If nothing is returned, the default error is thrown instead.
|
|
1023
|
-
*
|
|
1024
|
-
* @throws {DataError} If the given data cannot be parsed according to the schema.
|
|
1025
|
-
*
|
|
1026
|
-
* @returns The parsed data from the Zod schema.
|
|
1027
|
-
*/
|
|
1028
|
-
async function parseZodSchemaAsync(schema, input, onError) {
|
|
1029
|
-
return _parseZodSchema(await schema.safeParseAsync(input), input, onError);
|
|
1303
|
+
return az.with(z$1.enum(VersionType)).parse(input, new DataError$1({ input }, "INVALID_VERSION_TYPE", "The provided version type must be one of `major | minor | patch`"));
|
|
1030
1304
|
}
|
|
1031
1305
|
//#endregion
|
|
1032
1306
|
//#region src/root/functions/recursive/deepCopy.ts
|
|
@@ -1532,214 +1806,4 @@ var DataError = class DataError extends Error {
|
|
|
1532
1806
|
}
|
|
1533
1807
|
};
|
|
1534
1808
|
//#endregion
|
|
1535
|
-
|
|
1536
|
-
const httpErrorCodeLookup = {
|
|
1537
|
-
400: "BAD_REQUEST",
|
|
1538
|
-
401: "UNAUTHORISED",
|
|
1539
|
-
403: "FORBIDDEN",
|
|
1540
|
-
404: "NOT_FOUND",
|
|
1541
|
-
418: "I_AM_A_TEAPOT",
|
|
1542
|
-
500: "INTERNAL_SERVER_ERROR"
|
|
1543
|
-
};
|
|
1544
|
-
/**
|
|
1545
|
-
* Represents common errors you may get from a HTTP API request.
|
|
1546
|
-
*
|
|
1547
|
-
* @category Types
|
|
1548
|
-
*/
|
|
1549
|
-
var APIError = class APIError extends Error {
|
|
1550
|
-
status;
|
|
1551
|
-
/**
|
|
1552
|
-
* @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.
|
|
1553
|
-
* @param message - An error message to display alongside the status code.
|
|
1554
|
-
* @param options - Extra options to be passed to super Error constructor.
|
|
1555
|
-
*/
|
|
1556
|
-
constructor(status = 500, message, options) {
|
|
1557
|
-
super(message, options);
|
|
1558
|
-
this.status = status;
|
|
1559
|
-
if (message) this.message = message;
|
|
1560
|
-
else this.message = httpErrorCodeLookup[this.status] ?? "API_ERROR";
|
|
1561
|
-
Object.defineProperty(this, "message", { enumerable: true });
|
|
1562
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
1563
|
-
}
|
|
1564
|
-
/**
|
|
1565
|
-
* Checks whether the given input may have been caused by an APIError.
|
|
1566
|
-
*
|
|
1567
|
-
* @param input - The input to check.
|
|
1568
|
-
*
|
|
1569
|
-
* @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`.
|
|
1570
|
-
*/
|
|
1571
|
-
static check(input) {
|
|
1572
|
-
if (input instanceof APIError) return true;
|
|
1573
|
-
const data = input;
|
|
1574
|
-
return typeof data === "object" && data !== null && typeof data?.status === "number" && typeof data?.message === "string";
|
|
1575
|
-
}
|
|
1576
|
-
};
|
|
1577
|
-
//#endregion
|
|
1578
|
-
//#region src/root/types/VersionNumber.ts
|
|
1579
|
-
/**
|
|
1580
|
-
* Represents a software version number, considered to be made up of a major, minor, and patch part.
|
|
1581
|
-
*
|
|
1582
|
-
* @category Types
|
|
1583
|
-
*/
|
|
1584
|
-
var VersionNumber = class VersionNumber {
|
|
1585
|
-
static NON_NEGATIVE_TUPLE_ERROR = "Input array must be a tuple of three non-negative integers.";
|
|
1586
|
-
/** The major number. Increments when a feature is removed or changed in a way that is not backwards-compatible with the previous release. */
|
|
1587
|
-
major = 0;
|
|
1588
|
-
/** The minor number. Increments when a new feature is added/deprecated and is expected to be backwards-compatible with the previous release. */
|
|
1589
|
-
minor = 0;
|
|
1590
|
-
/** The patch number. Increments when the next release is fixing a bug or doing a small refactor that should not be noticeable in practice. */
|
|
1591
|
-
patch = 0;
|
|
1592
|
-
/**
|
|
1593
|
-
* @param input - The input to create a new instance of `VersionNumber` from.
|
|
1594
|
-
*/
|
|
1595
|
-
constructor(input) {
|
|
1596
|
-
if (input instanceof VersionNumber) {
|
|
1597
|
-
this.major = input.major;
|
|
1598
|
-
this.minor = input.minor;
|
|
1599
|
-
this.patch = input.patch;
|
|
1600
|
-
} else if (typeof input === "string") {
|
|
1601
|
-
if (!VERSION_NUMBER_REGEX.test(input)) throw new DataError$1({ input }, "INVALID_VERSION", `"${input}" is not a valid version number. Version numbers must be of the format "X.Y.Z" or "vX.Y.Z", where X, Y, and Z are non-negative integers.`);
|
|
1602
|
-
const [major, minor, patch] = VersionNumber.formatString(input, { omitPrefix: true }).split(".").map((number) => {
|
|
1603
|
-
return parseIntStrict(number);
|
|
1604
|
-
});
|
|
1605
|
-
this.major = major;
|
|
1606
|
-
this.minor = minor;
|
|
1607
|
-
this.patch = patch;
|
|
1608
|
-
} else if (Array.isArray(input)) {
|
|
1609
|
-
if (input.length !== 3) throw new DataError$1({ input }, "INVALID_LENGTH", VersionNumber.NON_NEGATIVE_TUPLE_ERROR);
|
|
1610
|
-
const [major, minor, patch] = input.map((number) => {
|
|
1611
|
-
const parsedInteger = parseIntStrict(number?.toString());
|
|
1612
|
-
if (parsedInteger < 0) throw new DataError$1({ input }, "NEGATIVE_INPUTS", VersionNumber.NON_NEGATIVE_TUPLE_ERROR);
|
|
1613
|
-
return parsedInteger;
|
|
1614
|
-
});
|
|
1615
|
-
this.major = major;
|
|
1616
|
-
this.minor = minor;
|
|
1617
|
-
this.patch = patch;
|
|
1618
|
-
} else throw new DataError$1({ input }, "INVALID_INPUT", normaliseIndents`
|
|
1619
|
-
The provided input can not be parsed into a valid version number.
|
|
1620
|
-
Expected either a string of format X.Y.Z or vX.Y.Z, a tuple of three numbers, or another \`VersionNumber\` instance.
|
|
1621
|
-
`);
|
|
1622
|
-
}
|
|
1623
|
-
/**
|
|
1624
|
-
* Gets the current version type of the current instance of `VersionNumber`.
|
|
1625
|
-
*
|
|
1626
|
-
* @returns Either `"major"`, `"minor"`, or `"patch"`, depending on the version type.
|
|
1627
|
-
*/
|
|
1628
|
-
get type() {
|
|
1629
|
-
if (this.minor === 0 && this.patch === 0) return VersionType.MAJOR;
|
|
1630
|
-
if (this.patch === 0) return VersionType.MINOR;
|
|
1631
|
-
return VersionType.PATCH;
|
|
1632
|
-
}
|
|
1633
|
-
static formatString(input, options) {
|
|
1634
|
-
if (options?.omitPrefix) return input.startsWith("v") ? input.slice(1) : input;
|
|
1635
|
-
return input.startsWith("v") ? input : `v${input}`;
|
|
1636
|
-
}
|
|
1637
|
-
/**
|
|
1638
|
-
* Checks if the provided version numbers have the exact same major, minor, and patch numbers.
|
|
1639
|
-
*
|
|
1640
|
-
* @param firstVersion - The first version number to compare.
|
|
1641
|
-
* @param secondVersion - The second version number to compare.
|
|
1642
|
-
*
|
|
1643
|
-
* @returns `true` if the provided version numbers have exactly the same major, minor, and patch numbers, and returns `false` otherwise.
|
|
1644
|
-
*/
|
|
1645
|
-
static isEqual(firstVersion, secondVersion) {
|
|
1646
|
-
return firstVersion.major === secondVersion.major && firstVersion.minor === secondVersion.minor && firstVersion.patch === secondVersion.patch;
|
|
1647
|
-
}
|
|
1648
|
-
/**
|
|
1649
|
-
* Get a formatted string representation of the current version number
|
|
1650
|
-
*
|
|
1651
|
-
* @param options - Options to apply to the string formatting.
|
|
1652
|
-
*
|
|
1653
|
-
* @returns A formatted string representation of the current version number with the options applied.
|
|
1654
|
-
*/
|
|
1655
|
-
format(options) {
|
|
1656
|
-
let baseOutput = `${this.major}`;
|
|
1657
|
-
if (!options?.omitMinor) {
|
|
1658
|
-
baseOutput += `.${this.minor}`;
|
|
1659
|
-
if (!options?.omitPatch) baseOutput += `.${this.patch}`;
|
|
1660
|
-
}
|
|
1661
|
-
return VersionNumber.formatString(baseOutput, { omitPrefix: options?.omitPrefix });
|
|
1662
|
-
}
|
|
1663
|
-
/**
|
|
1664
|
-
* Increments the current version number by the given increment type, returning the result as a new reference in memory.
|
|
1665
|
-
*
|
|
1666
|
-
* @param incrementType - The type of increment. Can be one of the following:
|
|
1667
|
-
* - `"major"`: Change the major version `v1.2.3` → `v2.0.0`
|
|
1668
|
-
* - `"minor"`: Change the minor version `v1.2.3` → `v1.3.0`
|
|
1669
|
-
* - `"patch"`: Change the patch version `v1.2.3` → `v1.2.4`
|
|
1670
|
-
* @param incrementAmount - The amount to increment by (defaults to 1).
|
|
1671
|
-
*
|
|
1672
|
-
* @returns A new instance of `VersionNumber` with the increment applied.
|
|
1673
|
-
*/
|
|
1674
|
-
increment(incrementType, incrementAmount = 1) {
|
|
1675
|
-
const incrementBy = parseIntStrict(String(incrementAmount));
|
|
1676
|
-
const calculatedRawVersion = {
|
|
1677
|
-
major: [
|
|
1678
|
-
this.major + incrementBy,
|
|
1679
|
-
0,
|
|
1680
|
-
0
|
|
1681
|
-
],
|
|
1682
|
-
minor: [
|
|
1683
|
-
this.major,
|
|
1684
|
-
this.minor + incrementBy,
|
|
1685
|
-
0
|
|
1686
|
-
],
|
|
1687
|
-
patch: [
|
|
1688
|
-
this.major,
|
|
1689
|
-
this.minor,
|
|
1690
|
-
this.patch + incrementBy
|
|
1691
|
-
]
|
|
1692
|
-
}[incrementType];
|
|
1693
|
-
try {
|
|
1694
|
-
return new VersionNumber(calculatedRawVersion);
|
|
1695
|
-
} catch (error) {
|
|
1696
|
-
if (DataError$1.check(error) && error.code === "NEGATIVE_INPUTS") throw new DataError$1({
|
|
1697
|
-
currentVersion: this.toString(),
|
|
1698
|
-
calculatedRawVersion: `v${calculatedRawVersion.join(".")}`,
|
|
1699
|
-
incrementAmount
|
|
1700
|
-
}, "NEGATIVE_VERSION", "Cannot apply this increment amount as it would lead to a negative version number.");
|
|
1701
|
-
else throw error;
|
|
1702
|
-
}
|
|
1703
|
-
}
|
|
1704
|
-
/**
|
|
1705
|
-
* Ensures that the VersionNumber behaves correctly when attempted to be coerced to a string.
|
|
1706
|
-
*
|
|
1707
|
-
* @param hint - Not used as of now, but generally used to help with numeric coercion, I think (which we most likely do not need for version numbers).
|
|
1708
|
-
*
|
|
1709
|
-
* @returns A stringified representation of the current version number, prefixed with `v`.
|
|
1710
|
-
*/
|
|
1711
|
-
[Symbol.toPrimitive](hint) {
|
|
1712
|
-
if (hint === "number") throw new DataError$1({ thisVersion: this.toString() }, "INVALID_COERCION", "VersionNumber cannot be coerced to a number type.");
|
|
1713
|
-
return this.toString();
|
|
1714
|
-
}
|
|
1715
|
-
/**
|
|
1716
|
-
* Ensures that the VersionNumber behaves correctly when attempted to be converted to JSON.
|
|
1717
|
-
*
|
|
1718
|
-
* @returns A stringified representation of the current version number, prefixed with `v`.
|
|
1719
|
-
*/
|
|
1720
|
-
toJSON() {
|
|
1721
|
-
return this.toString();
|
|
1722
|
-
}
|
|
1723
|
-
/**
|
|
1724
|
-
* Get a string representation of the current version number.
|
|
1725
|
-
*
|
|
1726
|
-
* @returns A stringified representation of the current version number with the prefix.
|
|
1727
|
-
*/
|
|
1728
|
-
toString() {
|
|
1729
|
-
const rawString = `${this.major}.${this.minor}.${this.patch}`;
|
|
1730
|
-
return VersionNumber.formatString(rawString, { omitPrefix: false });
|
|
1731
|
-
}
|
|
1732
|
-
};
|
|
1733
|
-
const zodVersionNumber = z$1.union([
|
|
1734
|
-
z$1.string(),
|
|
1735
|
-
z$1.tuple([
|
|
1736
|
-
z$1.number(),
|
|
1737
|
-
z$1.number(),
|
|
1738
|
-
z$1.number()
|
|
1739
|
-
]),
|
|
1740
|
-
z$1.instanceof(VersionNumber)
|
|
1741
|
-
]).transform((rawVersionNumber) => {
|
|
1742
|
-
return new VersionNumber(rawVersionNumber);
|
|
1743
|
-
});
|
|
1744
|
-
//#endregion
|
|
1745
|
-
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, 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 };
|
|
1809
|
+
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, 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 };
|