1

我是函数式编程的新手,所以很多事情对我来说仍然不清楚。我正在尝试使用 fp-ts 编写我的 graphql 服务器,但我遇到了用户授权问题。我期待这样的授权:验证用户数据->检查他是否存在->加密他的密码->创建用户。所以这在类型中看起来像: Either<string, data> -> TaskEither<string, User> -> Either<string, data> -> TaskEither<string, User> 我不知道真正的谁正确链接它而不会出现类型错误,并且如果已经获得 Left(string),则可以忽略管道中的项目。

这是我的数据库代码:

import { pipe } from 'fp-ts/lib/function';
import { tryCatchK as encase } from 'fp-ts/lib/TaskEither';

export const findUser = (email: string) =>
  encase(
    () =>
      prisma.user.findOne({
        where: {
          email,
        },
      }),
    (rejection) => String(rejection),
  );

export const createUser = (data: UserCreation) =>
  encase(
    () => prisma.user.create({ data }),
    (rejection) => String(rejection),
  );

这是我的验证码:

import { sequenceT } from 'fp-ts/lib/Apply';
import { chain, fold } from 'fp-ts/lib/TaskEither';
import { getSemigroup, NonEmptyArray } from 'fp-ts/lib/NonEmptyArray';
import { getValidation, Either, mapLeft, map } from 'fp-ts/lib/Either';

const encrypt = (data: string) => hashSync(data);

const checkForDuplicate = (data: UserCreation) => findUser(data.email);

function lift<L, A>(
  check: (a: A) => Either<L, A>,
): (a: A) => Either<NonEmptyArray<L>, A> {
  return (a) =>
    pipe(
      check(a),
      mapLeft((b) => [b]),
    );
}

export const signUp = (data: UserCreation) =>
  pipe(
    sequenceT(getValidation(getSemigroup<any>()))(
      lift(validateSignUpData)(data),
      chain(checkForDuplicate),
    ),
    map(() => data),
  );
4

0 回答 0