All files / types/backend validation.ts

0% Statements 0/0
0% Branches 1/1
0% Functions 1/1
0% Lines 0/0

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47                                                                                             
type ExactValues<V, key> = key extends 'array'
  ? V extends any[] // eslint-disable-line @typescript-eslint/no-explicit-any
    ? readonly V[number][]
    : readonly V[]
  : readonly V[];
 
type PossibleTypes = 'string' | 'number' | 'boolean' | 'array' | 'null';
 
type BaseTypeValidation<V, type> = {
  regex?: RegExp;
  exact?: ExactValues<V, type>;
};
export type ArrayTypeValidations<V> = BaseTypeValidation<V, 'array'> & {
  items?: V extends Array<unknown> ? Validator<V[number]> : never;
};
 
type SpecificTypeValidations<V> = Pick<
  ({
    [type in Exclude<PossibleTypes, 'array' | 'object'>]: BaseTypeValidation<V, type>;
  } & {
    array: ArrayTypeValidations<V>;
  }),
  {
    string: V extends string ? 'string' : never;
    number: V extends number ? 'number' : never;
    boolean: V extends boolean ? 'boolean' : never;
    array: V extends Array<unknown> ? 'array' : never;
    null: V extends null ? 'null' : never;
  }[PossibleTypes]
> & {
  [key in PossibleTypes]?: {
    regex?: RegExp;
    exact?: ExactValues<V, key>;
  };
};
export type Validator<T> = {
  [key in keyof Required<T>]: {
    required: undefined extends T[key] ? false : true;
    parse?: (v: string) => T[key];
    types: SpecificTypeValidations<T[key]>;
  };
};
 
export type OrNull<T extends object> = {
  [key in keyof T]: T[key] | null;
};