我是函数式编程的新手,所以很多事情对我来说仍然不清楚。我正在尝试使用 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),
);