This package is highly experimental and not recommended for production use
The plugin adds new helpers for creating prisma compatible input types. It is NOT required to use the normal prisma plugin.
To use this plugin, you will need to enable prismaUtils option in the generator in your schema.prisma:
generator pothos {
provider = "prisma-pothos-types"
// Enable prismaUtils feature
prismaUtils = true
}
Once this is enabled, you can add the plugin to your schema along with the normal prisma plugin:
import SchemaBuilder from '@pothos/core';
import { PrismaClient } from '@prisma/client';
import type PrismaTypes from '@pothos/plugin-prisma/generated';
import PrismaPlugin from '@pothos/plugin-prisma';
import PrismaUtils from '@pothos/plugin-prisma-utils';
export const prisma = new PrismaClient({});
export default new SchemaBuilder<{
Scalars: {
DateTime: {
Input: Date;
Output: Date;
};
};
PrismaTypes: PrismaTypes;
}>({
plugins: [PrismaPlugin, PrismaUtils],
prisma: {
client: prisma,
},
});
Currently this plugin is focused on making it easier to define prisma compatible input types that take advantage of the types defined in your Prisma schema.
The goal is not to generate all input types automatically, but rather to provide building blocks so that writing your own helpers or code-generators becomes a lot easier. There are far too many tradeoffs and choices to be made when designing input types for queries that one solution won't work for everyone.
This plugin will eventually provide more helpers and examples that should allow anyone to quickly set something up to automatically creates all their input types (and eventually other crud operations).
const StringFilter = builder.prismaFilter('String', {
ops: ['contains', 'equals', 'startsWith', 'not'],
});
export const IDFilter = builder.prismaFilter('Int', {
ops: ['equals', 'not'],
});
builder.enumType(MyEnum, { name: 'MyEnum' });
const MyEnumFilter = builder.prismaFilter(MyEnum, {
ops: ['not', 'equals'],
});
const UserWhere = builder.prismaWhere('User', {
fields: {
id: IDFilter,
},
});
const PostFilter = builder.prismaWhere('Post', {
fields: (t) => ({
// You can use either filters
id: IDFilter,
// or scalar types to only support equality
title: 'String',
createdAt: 'DateTime',
// Relations are supported by referencing other scalars
author: UserFilter,
// use t.field to provide other field options
authorId: t.field({ type: IDFilter, description: 'filter by author id' }),
}),
});
export const StringListFilter = builder.prismaScalarListFilter('String', {
name: 'StringListFilter',
ops: ['has', 'hasSome', 'hasEvery', 'isEmpty', 'equals'],
});
const UserListFilter = builder.prismaListFilter(UserWhere, {
ops: ['every', 'some', 'none'],
});
const UserOrderBy = builder.prismaOrderBy('User', {
fields: {
name: true,
},
});
export const PostOrderBy = builder.prismaOrderBy('Post', {
fields: () => ({
id: true,
title: true,
createdAt: true,
author: UserOrderBy,
}),
});
You can use builder.prismaCreate
to create input types for create mutations.
To get these types to work correctly for circular references, it is recommended to add explicit type annotations, but for simple types that do not have circular references the explicit types can be omitted.
import { InputObjectRef } from '@pothos/core';
import { Prisma } from '@prisma/client';
export const UserCreate: InputObjectRef<Prisma.UserCreateInput> = builder.prismaCreate('User', {
name: 'UserCreate',
fields: () => ({
// scalars
id: 'Int',
email: 'String',
name: 'String',
// inputs for relations need to be defined separately as shown below
profile: UserCreateProfile,
// create fields for list relations are defined just like normal relations.
// Pothos will automatically handle making the inputs lists
posts: UserCreatePosts,
}),
});
export const UserCreateProfile = builder.prismaCreateRelation('User', 'profile', {
fields: () => ({
// created with builder.prismaCreate as shown above for User
create: ProfileCreateWithoutUser,
// created with builder.prismaWhere
connect: ProfileUniqueFilter,
}),
});
export const UserCreatePosts = builder.prismaCreateRelation('User', 'posts', {
fields: () => ({
// created with builder.prismaCreate as shown above for User
create: PostCreateWithoutAuthor,
// created with builder.prismaWhere
connect: PostUniqueFilter,
}),
});
You can use builder.prismaUpdate
to Update input types for update mutations.
To get these types to work correctly for circular references, it is recommended to add explicit type annotations, but for simple types that do not have circular references the explicit types can be omitted.
export const UserUpdate: InputObjectRef<Prisma.Prisma.UserUpdateInput> = builder.prismaUpdate(
'User',
{
name: 'UserUpdate',
fields: () => ({
id: 'Int',
email: 'String',
name: 'String',
// inputs for relations need to be defined separately as shown below
profile: UserUpdateProfile,
posts: UserUpdatePosts,
}),
},
);
export const UserUpdateProfile = builder.prismaUpdateRelation('User', 'profile', {
fields: () => ({
// created with builder.prismaCreate
create: ProfileCreateWithoutUser,
// created with builder.prismaUpdate
update: ProfileUpdateWithoutUser,
// created with builder.prismaWhereUnique
connect: ProfileUniqueFilter,
}),
});
export const UserUpdatePosts = builder.prismaUpdateRelation('User', 'posts', {
fields: () => ({
// Not all update methods need to be defined
// created with builder.prismaCreate
create: PostCreateWithoutAuthor,
// created with builder.prismaWhereUnique
set: PostUniqueFilter,
// created with builder.prismaWhereUnique
disconnect: PostUniqueFilter,
delete: PostUniqueFilter,
connect: PostUniqueFilter,
update: {
// created with builder.prismaWhereUnique
where: PostUniqueFilter,
// created with builder.prismaUpdate
data: PostUpdateWithoutAuthor,
},
updateMany: {
// created with builder.prismaWhere
where: PostWithoutAuthorFilter,
// created with builder.prismaUpdate
data: PostUpdateWithoutAuthor,
},
// created with builder.prismaWhere
deleteMany: PostWithoutAuthorFilter,
}),
});
Manually defining all the different input types shown above for a large number of tables can become very repetitive. These utilities are designed to be building blocks for generators or utility functions, so that you don't need to hand write these types yourself.
Pothos does not currently ship an official generator for prisma types, but there are a couple of example generators that can be copied and modified to suite your needs. These are intentionally somewhat limited in functionality and not written to be easily exported because they will be updated with breaking changes as these utilities are developed further. They are only intended as building blocks for you to build you own generators.
There are 2 main approaches:
You can find an example static generator here
This generator will generate a file with input types for every table in your schema as shown here
These generated types can be used in your schema as shown here
You can find an example dynamic generator here
This generator exports a class that can be used to dynamically create input types for your builder as shown here