Exploring the capabilities of Prisma ORM has led me to experiment with creating models and generating the PrismaClient. Initially, I thought it would be possible to utilize the generated types for variables and response types, but that doesn't seem to be the case.
...
model Invite {
id Int @id @default(autoincrement())
gender Gender
firstName String @map("first_name")
lastName String @map("last_name")
language Language
email String @unique
token String @unique
roleId Int @map("role_id")
role Role @relation(fields: [roleId], references: [id])
organisationId Int @map("organisation_id")
organisation Organisation @relation(fields: [organisationId], references: [id])
updatedAt DateTime @updatedAt @map("updated_at")
createdAt DateTime @default(now()) @map("created_at")
@@map("invites")
}
...
The Invite model above includes relationships with the organisation and role models. In an invite service file, I'm preparing all the necessary input to create a new invite.
import { Request, Response, NextFunction } from 'express';
import roleRepository from '../repositories/role.repository';
import organisationRepository from '../repositories/organisation.repository';
import generateToken from '../utils/helpers/generateToken';
import inviteRepository from '../repositories/invite.repository';
const createInvite = async (req: Request, res: Response) => {
const { body } = await validateInput(req);
const { gender, firstName, lastName, email, language, roleId, organisationId } = body;
const role = roleRepository.findRoleById(roleId);
if (!role) {
throw new Error('Role does not exist');
}
const organisation = organisationRepository.findOrganisationById(organisationId);
if (!organisation) {
throw new Error('Organisation does not exist');
}
const token = generateToken();
const invite = inviteRepository.createInvite({
gender,
firstName,
lastName,
email,
language,
role: role,
organisation: organisation,
token,
});
await mailService.sendInviteEmail(invite);
res.status(201).json({
message: 'Invite created successfully',
});
};
Within the createInvite
function in the inviteRepository
file, I attempt to use a generated Prisma type called InviteCreateInput
.
const createInvite = async (inviteData: Prisma.InviteCreateInput): Promise<Invite> => {
return db.invite.create({
data: {
gender: inviteData.gender,
firstName: inviteData.firstName,
lastName: inviteData.lastName,
language: inviteData.language,
email: inviteData.email,
token: inviteData.token,
role: {
connect: {
id: inviteData.role
}
},
organisation: {
connect: {
id: inviteData.organisation,
}
}
},
});
};
Prisma suggests using this 'safe' Input approach, however, the InviteCreateInput
type structure is not fitting for my needs.
export type InviteCreateInput = {
gender: Gender
firstName: string
lastName: string
language: string
email: string
token: string
updatedAt?: Date | string
createdAt?: Date | string
role: RoleCreateNestedOneWithoutInviteInput
organisation: OrganisationCreateNestedOneWithoutInvitesInput
}
The
RoleCreateNestedOneWithoutInviteInput
looks like this:
export type RoleCreateNestedOneWithoutInviteInput = {
create?: XOR<RoleCreateWithoutInviteInput, RoleUncheckedCreateWithoutInviteInput>
connectOrCreate?: RoleCreateOrConnectWithoutInviteInput
connect?: RoleWhereUniqueInput
}
Considering the limitations of the Prisma generated types, I question whether to continue using them as function parameter types or to create custom types instead.