@palmares/schemas
Version:
This defines a default schema definition for validation of data, it abstract popular schema validation libraries like zod, yup, valibot and others"
101 lines • 6.43 kB
TypeScript
import type { ValidatorTypes } from './types';
import type { ErrorCodes } from '../adapter/types';
import type { Schema } from '../schema/schema';
import type { ValidationFallbackCallbackReturnType, ValidationFallbackCallbackType, ValidationFallbackReturnType } from '../schema/types';
/**
* Okay, so what is this? This is a validator class, it represents a Node on a linked list. The linked list
* has lower priority validators on the end of the list and higher priority validators on the start of the
* list. Maybe in the future we can change that to a binary tree, but for now this is enough.
*
* Why did we choose this approach? Because what i was doing was that i saw myself repeating the same code 3
* times on the schema in order to make the validation work. Each validator had a different return type, i
* didn't like that. I wanted to add more power and control on the validator, not on the schema. So i created
* this class. So pretty much, over here and on each validator we can define the type it is. It can actually
* be three: `low`, `medium` and `high`. The `low` validators are the ones that are going to be executed last,
* The `high` validators are the ones that are going to be executed first. High validators validate if the value
* is null or undefined, if it allows that. It can stop the execution of the other validators if it wants to.
*
* Example: Let's say that the value is null, if the value is null, is there a reason to check if it's a number?
* No, right? So the high validator can stop the execution of the other validators.
* Same as before, if the value is not a number, is there a reason to check if it's value is greater than the
* `max` allowed 10? No, right? So the medium validator can stop the execution of the other validators.
*
* That's what this solve, it's a better approach than repeating the same code 3 times on the schema. It's also
* more powerful, because if we need to add any extra priorities we can do that easily without changing the schema.
*/
export declare class Validator {
protected $$type: string;
child?: Validator;
parent?: Validator;
fallbackNamesAdded: Set<unknown>;
priority: number;
fallbacks: ((value: any, path: (string | number)[], options: Parameters<Schema['__transformToAdapter']>[0]) => Promise<{
parsed: any;
errors: {
isValid: boolean;
code: ErrorCodes;
message: string;
path: (string | number)[];
}[];
preventChildValidation?: boolean;
}>)[];
constructor(type: ValidatorTypes);
/**
* We create all of the validators on the schema in order, i actually didn't want to go on that route but i
* found it easier to do so.
*
* The logic here is simple, if it's not the same priority we will walk on the linked list until we find
* a validator that matches the priority we are expecting. If we can't walk anymore, we create the next
* priority validator and append it to the linked list. Be aware that it's a double linked list, so we
* can walk both ways, from the end to the start and from the start to the end.
* So you don't really need to start from the root, the linked list can start from anywhere and it will
* find it's way through.
*
* I know there are better ways to do this instead of walking through the linked list, but like i explained
* before, this is enough for now.
*
* If the priority is higher than the current priority saved on the schema, we should substitute the
* rootValidator on the schema with the new one.
*
* @param schema - The schema that we are working on right now, all fallbacks are tied to that specific schema.
* @param type - The type of the fallback that we are adding.
* @param fallback - The fallback function that we are adding.
* @param childOrParent - If we are adding a fallback to the child or to the parent.
* @param options - The options that we are passing to the fallback.
*/
private checkAppendOrCreate;
addFallback(schema: Schema, type: ValidatorTypes, fallbackName: string, fallback: ValidationFallbackCallbackType, options?: Parameters<(typeof Validator)['createAndAppendFallback']>[2]): void;
/**
* Validates the value against all of the fallbacks, the fallbacks are executed in order, from the highest
* priority to the lowest priority. A validator can stop the execution of the other validators if it feels
* like so. Like on the example of a value being null or undefined.
*
* @param errorsAsHashedSet - This is a set that contains all of the errors that we already found, this is
* used to avoid duplicated errors.
* @param path - The path that we are validating right now.
* @param parseResult - The result of the parsing, it contains the parsed value and the errors that we found.
* @param options - The options that we are passing to the fallback.
*/
validate(errorsAsHashedSet: Set<string>, path: ValidationFallbackCallbackReturnType['errors'][number]['path'], parseResult: {
errors: undefined | ValidationFallbackCallbackReturnType['errors'];
parsed: any;
}, options: Parameters<Schema['__transformToAdapter']>[0]): Promise<ValidationFallbackCallbackReturnType>;
/**
* This static method takes care of everything for you. This means that you should only call this method
* for appending new fallbacks, it takes care of creating the root validator and making sure that the
* rootValidator on the schema is the highest priority one.
*
* @param schema - The schema that we are working on right now, all fallbacks are tied to that specific
* schema. We automatically define the rootValidator on the schema so you don't need to worry about that.
* @param fallback - The fallback that we are adding. This is an object that contains the type of the
* fallback and the callback that we are adding.
* @param options - The options that we are passing to the fallback. Options like `at` and `removeCurrent`
* are passed to the `addFallback` method.
*/
static createAndAppendFallback(schema: Schema<any, any>, fallback: ValidationFallbackReturnType, options?: {
at?: number;
removeCurrent?: boolean;
}): Validator;
toString(ident?: number): string;
}
//# sourceMappingURL=utils.d.ts.map