npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@pothos/plugin-prisma-utils

v1.2.0

Published

A Pothos plugin containing utility functions for building prisma inputs

Downloads

20,909

Readme

Prisma utils for Pothos

The plugin adds new helpers for creating prisma compatible input types. It is NOT required to use the normal prisma plugin.

Setup

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,
  },
});

What can you do with this plugin

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).

What is supported so far

Creating filter types for scalars and enums

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'],
});

Creating filters for Prisma objects (compatible with a "where" clause)

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' }),
  }),
});

Creating list filters for scalars

export const StringListFilter = builder.prismaScalarListFilter('String', {
  name: 'StringListFilter',
  ops: ['has', 'hasSome', 'hasEvery', 'isEmpty', 'equals'],
});

Creating list filters for Prisma objects

const UserListFilter = builder.prismaListFilter(UserWhere, {
  ops: ['every', 'some', 'none'],
});

Creating OrderBy input types

const UserOrderBy = builder.prismaOrderBy('User', {
  fields: {
    name: true,
  },
});

export const PostOrderBy = builder.prismaOrderBy('Post', {
  fields: () => ({
    id: true,
    title: true,
    createdAt: true,
    author: UserOrderBy,
  }),
});

Inputs for create mutations

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,
  }),
});

Inputs for update mutations

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.prismaCreateMany
    createMany: {
      skipDuplicates: 'Boolean',
      data: PostCreateManyWithoutAuthor,
    },
    // 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,
  }),
});

Atomic Int Update operations

const IntUpdate = builder.prismaIntAtomicUpdate();
// or with options
const IntUpdate = builder.prismaIntAtomicUpdate({
  name: 'IntUpdate',
  ops: ['increment', 'decrement'],
});

export const PostUpdate = builder.prismaUpdate('Post', {
  name: 'PostUpdate',
  fields: () => ({
    title: 'String',
    views: IntUpdate,
  }),
});

Generators

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:

  1. Static Generation: Types are generated and written as a typescript file which can be imported from as part of your schema
  2. Dynamic Generation: Types are generated dynamically at runtime through helpers imported from your App

Static generator

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

Dynamic generator

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