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

prisma-generator-pothos-codegen

v0.7.1

Published

A prisma generator that generate input types for Pothos. And optionally generate all crud.

Downloads

1,788

Readme

Prisma Generator Pothos Codegen

Group 1

A prisma generator plugin that auto-generates Pothos GraphQL input types and crud operations (all queries and mutations).

Easily convert a prisma schema into a full graphql CRUD API.

On prisma generate we create:

  • All input types for Create, Find, Update, Sort and Delete operations (to be used as args in fields).
  • (Optional): Create all Objects, Queries and Mutations base files (to create customizable resolvers).
  • (Optional): Execute all these base files without customization to create a default CRUD.

Table of Contents

Getting Started

Install

Using yarn

yarn add -D prisma-generator-pothos-codegen

or using npm

npm install --save-dev prisma-generator-pothos-codegen

Peer dependencies

The package has been developed and tested up to the following peer dependencies (see updated example):

"@pothos/core": "^3.41.0",
"@pothos/plugin-prisma": "^3.65.0",
"@prisma/client": "^5.15.1",
"prisma": "^5.15.1",

Using higher versions may break something. In these cases, please open a new issue.

Set Up

Add the generator to your schema.prisma

generator client {
  provider = "prisma-client-js"
}

generator pothos {
  provider = "prisma-pothos-types"
}

generator pothosCrud {
  provider = "prisma-generator-pothos-codegen"
  generatorConfigPath = "./pothos.config.js"
  // You may also set the `generatorConfigPath` via the `POTHOS_CRUD_CONFIG_PATH` environment variable.
  // The environment variable will override the path hardcoded here.
}

/// This is a user!
model User {
  /// This is an id!
  id  String  @id
}

Add scalar types to the builder

import { Scalars } from 'prisma-generator-pothos-codegen';
import { Prisma } from '.prisma/client';

export const builder = new SchemaBuilder<{
  // ... Context, plugins? ...
  PrismaTypes: PrismaTypes; // required for @pothos/plugin-prisma integration (which is required)
  Scalars: Scalars<Prisma.Decimal, Prisma.InputJsonValue | null, Prisma.InputJsonValue>; // required to define correct types for created scalars.
}>({
  // Other builder config
});

Create a configuration file (optional)

// ./pothos.config.js

/** @type {import('prisma-generator-pothos-codegen').Config} */
module.exports = {
  inputs: {
    outputFilePath: './src/graphql/__generated__/inputs.ts',
  },
  crud: {
    outputDir: './src/graphql/__generated__/',
    inputsImporter: `import * as Inputs from '@graphql/__generated__/inputs';`,
    resolverImports: `import prisma from '@lib/prisma';`,
    prismaCaller: 'prisma',
  },
  global: {
  },
};
{
  /** Input type generation config */
  inputs?: {
    /** Create simpler inputs for easier customization and ~65% less generated code. Default: `false` */
    simple?: boolean;
    /** How to import the Prisma namespace. Default: `"import { Prisma } from '.prisma/client';"` */
    prismaImporter?: string;
    /** Path to generate the inputs file to from project root. Default: `'./generated/inputs.ts'` */
    outputFilePath?: string;
    /** List of excluded scalars from generated output */
    excludeScalars?: string[];
    /** A function to replace generated source. Combined with global replacer config */
    replacer?: Replacer<'inputs'>;
    /** Map all Prisma fields with "@id" attribute to Graphql "ID" Scalar.
     *
     * ATTENTION: Mapping non String requires a conversion inside resolver, once GraphQl ID Input are coerced to String by definition. Default: false */
    mapIdFieldsToGraphqlId?: false | 'WhereUniqueInputs';
  };
  /** CRUD generation config */
  crud?: {
    /** Disable generaton of crud. Default: `false` */
    disabled?: boolean;
    /** How to import the inputs. Default `"import * as Inputs from '../inputs';"` */
    inputsImporter?: string;
    /** How to import the Prisma namespace at the objects.ts file. Default `"import { Prisma } from '.prisma/client';"`. Please use "resolverImports" to import prismaClient at resolvers. */
    prismaImporter?: string;
    /** How to call the prisma client. Default `'_context.prisma'` */
    prismaCaller?: string;
    /** Any additional imports you might want to add to the resolvers (e.g. your prisma client). Default: `''` */
    resolverImports?: string;
    /** Directory to generate crud code into from project root. Default: `'./generated'` */
    outputDir?: string;
    /** A function to replace generated source. Combined with global replacer config */
    replacer?: Replacer<'crud'>;
    /** A boolean to enable/disable generation of `autocrud.ts` which can be imported in schema root to auto generate all crud objects, queries and mutations. Default: `true` */
    generateAutocrud?: boolean;
    /** An array of parts of resolver names to be excluded from generation. Ie: ["User"] Default: [] */
    excludeResolversContain?: string[];
    /** An array of resolver names to be excluded from generation. Ie: ["upsertOneComment"] Default: [] */
    excludeResolversExact?: string[];
    /** An array of parts of resolver names to be included from generation (to bypass exclude contain). Ie: if exclude ["User"], include ["UserReputation"] Default: [] */
    includeResolversContain?: string[];
    /** An array of resolver names to be included from generation (to bypass exclude contain). Ie: if exclude ["User"], include ["UserReputation"] Default: [] */
    includeResolversExact?: string[];
    /** Caution: This delete the whole folder (Only use if the folder only has auto generated contents). A boolean to delete output dir before generate. Default: False */
    deleteOutputDirBeforeGenerate?: boolean;
    /** Export all crud queries/mutations/objects in objects.ts at root dir. Default: true */
    exportEverythingInObjectsDotTs?: boolean;
    /** Map all Prisma fields with "@id" attribute to Graphql "ID" Scalar. Default: 'Objects' */
    mapIdFieldsToGraphqlId?: false | 'Objects';
    /** Change the generated variables from object.base.ts from something like `UserName` to `User_Name`. This avoids generated duplicated names in some cases. See [issue #58](https://github.com/Cauen/prisma-generator-pothos-codegen/issues/58). Default: false */
    underscoreBetweenObjectVariableNames?: false | 'Objects';
  };
  /** Global config */
  global?: {
    /** A function to replace generated source */
    replacer?: Replacer;
    /** Location of builder to replace in all files. Relative to package root. ie: './src/schema/builder'. Default: './builder' */
    builderLocation?: string;
    /** Run function before generate */
    beforeGenerate?: (dmmf: DMMF.Document) => void;
    /** Run function after generate */
    afterGenerate?: (dmmf: DMMF.Document) => void;
  };
}

Run the generator

yarn prisma generate

or

npx prisma generate

Usage

Inputs

You can use @Pothos.omit() function calls in your prisma schema field descriptions to control which fields are used in the generated input types.

  • @Pothos.omit() Omits the field from all inputs
  • @Pothos.omit(create) Omits field from the create input
  • @Pothos.omit(orderBy, where, update) Omits field from the orderBy, where, and update inputs, but not the create input

The available options are create, update, where, and orderBy.

model User {
  /// @Pothos.omit(create, update)
  id        String   @id @default(uuid())
  email     String
  /// @Pothos.omit()
  password  String
}

You can also augment/derive new inputs from the generated inputs.ts file.

// ./src/graphql/User/inputs.ts

import { Prisma } from '@prisma/client';
// Import generated input fields definition
import { UserUpdateInputFields } from '@/graphql/__generated__/inputs';

// Note: you can't use `builder.inputType` to generate this new input
export const UserUpdateInputCustom = builder
  .inputRef<Prisma.UserUpdateInput & { customArg: string }>('UserUpdateInputCustom')
  .implement({
    fields: (t) => ({
      ...UserUpdateInputFields(t),
      customArg: t.field({ required: true, type: 'String' }),
    }),
  });

Objects

// ./src/graphql/User/object.ts

import { UserObject } from '@/graphql/__generated__/User';
import { builder } from '@/graphql/builder'; // Pothos schema builder

// Use the Object export to accept all default generated query code
builder.prismaObject('User', UserObject);

// Or modify it as you wish
builder.prismaObject('User', {
  ...UserObject,
  fields: (t) => {
    // Type-safely omit and rename fields
    const { password: _password, email: emailAddress, ...fields } = UserObject.fields(t);
    const sessionsField = UserSessionsFieldObject(t);

    return {
      ...fields,
      // Renamed field
      emailAddress,
      // Edit and extend field
      sessions: t.relation('sessions', {
        ...sessionsField,
        args: { ...sessionsField.args, customArg: t.arg({ type: 'String', required: false }) },
        authScopes: { admin: true },
      }),
      // Add custom fields
      customField: t.field({ type: 'String', resolve: () => 'Hello world!' }),
    };
  },
});

Queries and Mutations

// ./src/graphql/User/query.ts

import { findManyUserQuery, findManyUserQueryObject } from '@/graphql/__generated__/User';
import { builder } from '@/graphql/builder'; // Pothos schema builder

// Use the Query exports to accept all default generated query code
builder.queryFields(findManyUserQuery);

// Use the QueryObject exports to override or add to the generated code
builder.queryFields((t) => {
  const field = findManyUserQueryObject(t);
  return {
    findManyUser: t.prismaField({
      // Inherit all the generated properties
      ...field,

      // Modify the args and use custom arg in a custom resolver
      args: { ...field.args, customArg: t.arg({ type: 'String', required: false }) },
      resolve: async (query, root, args, context, info) => {
        const { customArg } = args;
        console.log(customArg);
        return field.resolve(query, root, args, context, info);
      },

      // Add an custom extension
      authScopes: { admin: true },
    }),
  };
});

Auto define all objects, queries and mutations (crud operations)

First, make sure that options.crud.generateAutocrud isn't set to false

// ./src/schema/index.ts (import autocrud.ts)
import {
  generateAllCrud,
  generateAllObjects,
  generateAllQueries,
  generateAllMutations
} from '@/graphql/__generated__/autocrud.ts',
import { builder } from '@/graphql/builder'; // Pothos schema builder

// (option 1) generate all objects, queries and mutations
generateAllCrud()

// (option 2) or create them separately
generateAllObjects()
generateAllQueries()
generateAllMutations()

// (option 3) or limit crud generation
generateAllObjects({ include: ["User", "Profile", 'Comment'] })
generateAllQueries({ exclude: ["Comment"] })
generateAllMutations({ exclude: ["User"] })

// Defining schema roots
builder.queryType({});
builder.mutationType({});

export const schema = builder.toSchema({});

Generated queries:

  • count
  • findFirst
  • findMany
  • findUnique

Generated mutations:

  • createMany
  • createOne
  • deleteMany
  • deleteOne
  • updateMany
  • updateOne
  • upsertOne

Examples

Check for the example for a running sample

image

Disclosures

Models with only relations

  • We create a custom scalar NEVER that avoids this error: Input Object type FollowUpdateManyMutationInput must define one or more fields. from Graphql. if you have models that are relations-only. Like N-N fields without no relation fields or id-only models, we set field _ of some operations to this scalar. If you fill this fake property, the operation will result in a error.

BigInt rename

  • As BigInt is reserved, we export Bigint for the BigInt scalar.