import { UnprocessableEntityException } from '@nestjs/common';
import { Either, left, mapLeft, right } from 'fp-ts/lib/Either';
import { pipe } from 'fp-ts/lib/function';
import { fromEither, TaskEither } from 'fp-ts/lib/TaskEither';
import { ValidationError } from 'io-ts';
import { RuntypeBase } from 'runtypes/lib/runtype';
/**
* Decode, in TaskEither scope using io-ts.
* In fact, io-ts:
* - works synchronously (`Task` and not `TaskEither`)
* - returns `Errors` as left which is typically `Error[]`
* In order to use it more easily, this small helper makes the mandatory conversion
*
* @param validator : an io-ts validator
*/
export const validateWith =
(validator: RuntypeBase, dataKind: string) =>
(data: Input): TaskEither => {
return pipe(
data,
checkEither(validator.check),
mapLeft(() => new UnprocessableEntityException(`The data ${dataKind} is invalid`, `invalid-${dataKind}`)),
fromEither,
);
};
const checkEither =
(check: (value: any) => D) =>
(value: any): Either => {
try {
const checkedValue = check(value);
return right(checkedValue);
} catch (error) {
return left(error);
}
};