UNPKG

apiful

Version:

Extensible, typed API tooling

88 lines (87 loc) 2.48 kB
//#region src/utils/validator.ts const validatorSymbol = Symbol.for("apiful.validator"); var TypeValidationError = class extends Error { value; cause; constructor({ value, cause }) { super(`Type validation failed with value: ${JSON.stringify(value)}\nError message: ${getErrorMessage(cause)}`); this.value = value; this.cause = cause; } }; /** * Create a validator. * * @param validate A validation function for the schema. */ function validator(validate) { return { [validatorSymbol]: true, validate }; } /** * Validates the types of an unknown object using a schema and * return a strongly-typed object. * * @template T - The type of the object to validate. * @param {string} options.value - The object to validate. * @param {Validator<T>} options.schema - The schema to use for validating the JSON. * @returns {T} - The typed object. */ function validateTypes({ value, schema: inputSchema }) { const result = safeValidateTypes({ value, schema: inputSchema }); if (!result.success) throw new TypeValidationError({ value, cause: result.error }); return result.value; } /** * Safely validates the types of an unknown object using a schema and * return a strongly-typed object. * * @template T - The type of the object to validate. * @param {string} options.value - The JSON object to validate. * @param {Validator<T>} options.schema - The schema to use for validating the JSON. * @returns An object with either a `success` flag and the parsed and typed data, or a `success` flag and an error object. */ function safeValidateTypes({ value, schema }) { try { if (schema.validate == null) return { success: true, value }; const result = schema.validate(value); if (result.success) return result; return { success: false, error: new TypeValidationError({ value, cause: result.error }) }; } catch (error) { return { success: false, error: new TypeValidationError({ value, cause: error }) }; } } function isValidator(value) { return typeof value === "object" && value !== null && validatorSymbol in value && value[validatorSymbol] === true && "validate" in value; } function getErrorMessage(error) { if (error == null) return "Unknown error"; if (typeof error === "string") return error; if (error instanceof Error) return error.message; return JSON.stringify(error); } //#endregion export { TypeValidationError, isValidator, safeValidateTypes, validateTypes, validator, validatorSymbol };