@ocubist/error-alchemy
Version:
A powerful Node.js error-handling-framework with custom error types for easy debugging, enhanced error management, strong zod-support and useful quality-of-life-functionality for asserting and validating values.
98 lines (87 loc) • 3.17 kB
text/typescript
import { useErrorAlchemy } from "../../../crafting/useErrorAlchemy/useErrorAlchemy";
const { craftMysticError } = useErrorAlchemy("errorAlchemy", "assertNotEmpty");
/**
* Type for AssertNotEmptyFailedError.
*/
export type AssertNotEmptyFailedError = InstanceType<
ReturnType<typeof craftMysticError>
>;
/**
* Type for AssertNotEmptyMaxSmallerThanMinError.
*/
export type AssertNotEmptyMaxSmallerThanMinError = InstanceType<
ReturnType<typeof craftMysticError>
>;
export const AssertNotEmptyFailedError = craftMysticError({
name: "AssertNotEmptyFailedError",
severity: "critical",
errorCode: "DATA_INTEGRITY_VIOLATION",
cause: "The value was found to be empty, but a non-empty value was expected.",
});
export const AssertNotEmptyMaxSmallerThanMinError = craftMysticError({
name: "AssertNotEmptyMaxSmallerThanMinError",
severity: "critical",
errorCode: "RUNTIME_ERROR",
cause: "The max-length must be at least as big as the min-value",
});
export type AssertNotEmptyValueType =
| string
| any[]
| ArrayBufferView
| Set<unknown>
| Map<unknown, unknown>
| Buffer
| Record<string, unknown>;
/**
* Asserts that a given value is not empty.
* @param {T} value - The value to be checked for non-emptiness.
* @param {number} [min=1] - The minimum acceptable length or size.
* @param {number} [max] - The maximum acceptable length or size.
* @throws {AssertNotEmptyFailedError} If the value is empty.
* @throws {AssertNotEmptyMaxSmallerThanMinError} If the max length is smaller than the min length.
*/
export function assertNotEmpty<T extends AssertNotEmptyValueType>(
value: T,
min: number = 1,
max?: number
): asserts value is NonNullable<T> {
if (max && max < min) {
throw new AssertNotEmptyMaxSmallerThanMinError({
message: `Properties invalid: Max '${max}' was smaller than min '${min}'`,
payload: { min, max, value, type: typeof value },
});
}
let length: number = 0;
if (value === null || value === undefined) {
throw new AssertNotEmptyFailedError({
message: "Value was either null or undefined.",
payload: { type: typeof value, actualValue: value },
});
} else if (
typeof value === "string" ||
Array.isArray(value) ||
ArrayBuffer.isView(value)
) {
length = (value as unknown as { length: number }).length;
} else if (
typeof value === "object" &&
(value instanceof Set || value instanceof Map)
) {
length = (value as Set<unknown> | Map<unknown, unknown>).size;
} else if (typeof value === "object" && Buffer.isBuffer(value)) {
length = (value as Buffer).length;
} else if (typeof value === "object") {
length = Object.keys(value).length;
}
if (length < min) {
throw new AssertNotEmptyFailedError({
message: `Value-length '${length}' was below the given min-value of '${min}'.`,
payload: { type: typeof value, actualValue: value, min, max },
});
} else if (max && length > max) {
throw new AssertNotEmptyFailedError({
message: `Value-length '${length}' was above the given max-value of '${max}'.`,
payload: { type: typeof value, actualValue: value, min, max },
});
}
}