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-nestjs-graphql-crud

v2.5.5

Published

generates basic graphql crud classes for @nestjs/graphql

Downloads

16

Readme

prisma-generator-nestjs-graphql-crud

This prisma generator will create all the @nestjs/graphql classes you'll need for basic CRUD operations; based on your prisma schema. It includes dataloader to prevent the infamous n+1 problem in graphql.

npm i prisma-generator-nestjs-graphql-crud

Getting Started

  1. Inside your prisma schema add the following:
generator nestJsGraphQlCrud {
  provider = "prisma-generator-nestjs-graphql-crud"
}

Options:

| Feature | Description | Default | Example | |------------------|----------------------------------------------|-----------------------------------|------------------------------| | excludes | prisma model names to exclude from generator | | excludes = ["Ignore"] | | includeMutations | include mutation resolvers | | includeMutations = "true" | | output | cwd relative path for the output | node_modules/@generated/graphql | output = "./example/src" |

  1. Configure your Graphql Service In NestJs

The generated code relies on the context object for graphql to contain a reference to the prisma client. See the use of useFactory in the GraphQLModule below.

PrismaModule and PrismaService are generated; if you want your own custom implementation, use this doc as a guide.

* generated code is compatible with @nestjs/mercurius, @nestjs/apollo and @graphql-yoga/nestjs

import {
  DataLoaderService,
  PrismaModule,
  prismaProviders,
  PrismaService
} from '@generated/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRootAsync<ApolloDriverConfig>({
      driver: ApolloDriver,
      inject: [DataLoaderService, PrismaService],
      useFactory: (loaders: DataLoaderService, prisma: PrismaService) => ({
        autoSchemaFile: 'schema.gql',
        context: (req: FastifyRequest, res: FastifyReply) => {
          return {
            loaders: loaders.create(),
            prisma,
            req,
            res
          };
        },
        graphiql: true
      })
    }),
    PrismaModule.forRoot({
      isGlobal: true
    })
  ],
  providers: [...prismaProviders]
})
export class AppModule {
}

Prisma Features

| Feature | Available | Notes | |------------|-----------|---------------------------------------------------------------------| | create | ✅ | | | createMany | ✅ | | | delete | ✅ | | | deleteMany | ✅ | | | findUnique | ✅ | by primary key or composite keys | | findMany | ✅ | pagination included (skip/take only for now) | | filters | ✅ | gt,gte,lt,lte,notIn,in,not, etc. (DateTime, Int, String supported) | | orderBy | ✅ | | | update | ✅ | | | updateMany | ✅ | |

The following are the various filters and generated resolvers. Note the table name is Upper-CamelCased; e.g. user_session would become UserSession.


Resolvers

All the following are based on the example project found here.


create

Create a new entity. Here's an example:

mutation {
    createTodo(title: "Next Todo", userId: 1) {
        id
        title
        userId
    }
}

This would return the following:

{
  "data": {
    "createTodo": {
      "id": 6,
      "title": "Next Todo",
      "userId": 1
    }
  }
}

createMany

Create multiple new entities. Here's an example:

mutation {
    createManyTodo([{"title": "Another Todo", "userId": 1}, {"title": "Final Todo", "userId": 2}]) {
        id
        title
        userId
    }
}

This would return the following:

{
  "data": {
    "createManyTodo": [
      {
        "id": 7,
        "title": "Another Todo",
        "userId": 1
      },
      {
        "id": 8,
        "title": "Final Todo",
        "userId": 2
      }
    ]
  }
}

delete

Delete an entity. Here's an example:

mutation {
    deleteTodo(id: 1) {
        id
        title
        userId
    }
}

This would return the following:

{
  "data": {
    "deleteTodo": {
      "id": 1,
      "title": "First Todo",
      "userId": 1
    }
  }
}

deleteMany

Delete multiple entities. Here's an example:

mutation {
    deleteManyTodo(userId: 1) {
        id
        title
        userId
    }
}

This returns the list of deleted todos:

{
  "data": {
    "deleteManyTodo": [
      {
        "id": 1,
        "title": "First Todo",
        "userId": 1
      },
      {
        "id": 2,
        "title": "Second Todo",
        "userId": 1
      }
    ]
  }
}

findFirst

Find first should be used when you want to query and find a single row without using any of the unique keys for filters; this means that any filters you use for a findMany can be used here. Here's an example:

query {
    findFirstTodo(title: "That Todo") {
        id
        title
        userId
    }
}

This would return the following:

{
  "data": {
    "findFirstTodo": {
      "id": 1,
      "title": "That Todo",
      "userId": 1
    }
  }
}

findMany

Find many is used to return either filtered or unfiltered rows from a table, and can optionally provide skip (offset) and take (limit) as parameters to control pagination. Here's an example:

query {
    findManyTodo(skip: 0, take: 5) {
        id
        title
        userId
    }
}

This would return the following:

{
  "data": {
    "findManyTodo": [
      {
        "id": 1,
        "title": "Todo 1",
        "userId": 1
      },
      {
        "id": 2,
        "title": "Todo 2",
        "userId": 1
      },
      {
        "id": 3,
        "title": "Todo 3",
        "userId": 1
      },
      {
        "id": 4,
        "title": "Todo 4",
        "userId": 2
      },
      {
        "id": 5,
        "title": "Todo 5",
        "userId": 2
      }
    ]
  }
}

findUnique

Find unique should be used when you want to query against a primary key or composite key. Here's an example:

query {
    findUniqueTodo(id: 1) {
        id
        title
        userId
    }
}

This would return the following:

{
  "data": {
    "findUniqueTodo": {
      "id": 1,
      "title": "Todo 1",
      "userId": 1
    }
  }
}

update

Updates a single entity. Here's an example:

mutation {
    updateTodo(data: {"title": "First Todo", "userId": 2}, where: {"id": 1}) {
        id
        title
        userId
    }
}

This would return the following:

{
  "data": {
    "updateTodo": {
      "id": 1,
      "title": "First Todo",
      "userId": 2
    }
  }
}

updateMany

Updates a single entity. Here's an example:

mutation {
    updateManyTodo(data: {"userId": 2}, where: {"userId": 1}) {
        id
        title
        userId
    }
}

This would return the following:

{
  "data": {
    "updateManyTodo": [
      {
        "id": 1,
        "title": "First Todo",
        "userId": 2
      },
      {
        "id": 2,
        "title": "Second Todo",
        "userId": 2
      }
    ]
  }
}

Filters

The following filters are available are:


DateFilter

| Type | Supported | |------------|-----------| | findFirst | ✅ | | findMany | ✅ | | findUnique | ❌ |

Options

| Type | Description | Example | |------|----------------------------------------------------------------------|-------------------| | gt | where the column value is greater than the given {value} | gt: "2022-01-10" | | gte | where the column value is greater than or equal to the given {value} | gte:"2022-01-10" | | lt | where the column value is less than the given {value} | lt: "2022-01-10" | | lte | where the column value is less than or equal to the given {value} | lte:"2022-01-10" | | not | where the column value is not equal to the given {value} | not: "2022-01-10" |

Example:

query {
    findManyTodo(createdAt: { gt: "2022-01-10", lt: "2023-01-10" }) {
        id
        title
    }
}

NumberFilter

| Type | Supported | |------------|-----------| | findFirst | ✅ | | findMany | ✅ | | findUnique | ❌ |

Options

| Type | Description | Example | |------|----------------------------------------------------------------------|---------| | gt | where the column value is greater than the given {value} | gt: 1 | | gte | where the column value is greater than or equal to the given {value} | gte: 1 | | lt | where the column value is less than the given {value} | lt: 1 | | lte | where the column value is less than or equal to the given {value} | lte: 1 | | not | where the column value is not equal to the given {value} | not: 1 |

Example:

query {
    findManyTodo(userId: { gt: 1, lt: 2 }) {
        id
        title
        userId
    }
}

OrderBy

| Type | Supported | |------------|-----------| | findFirst | ✅ | | findMany | ✅ | | findUnique | ❌ |

Example:

query {
    findManyTodo(skip: 0, take: 5, orderBy: {title: "desc"}) {
        id
        title
    }
}

StringFilter

| Type | Supported | |------------|-----------| | findFirst | ✅ | | findMany | ✅ | | findUnique | ❌ |

Options

| Type | Description | Example | |------------|---------------------------------------------------------------------------|-------------------------| | contains | where the column contains the given {value} | contains: "Robert" | | endsWith | where the column value ends with the {value} | endsWith: "ert" | | in | where the column contains a value matching the array of {values}s | in: ["Robert", "Rob"] | | not | where the column value does not not equal the {value} | not: "Matt" | | notIn | where the column does not contain a value matching the array of {values}s | notIn: ["robb", "Robb"] | | startsWith | where the column value starts with the {value} | startsWith: "Rob" |

*all are case-insensitive

Example:

query {
    findManyTodo(title: { contains: "First" }) {
        id
        title
    }
}

Skip (offset)

| Type | Supported | |------------|-----------| | findFirst | ❌ | | findMany | ✅ | | findUnique | ❌ |

Example:

query {
    findManyTodo(skip: 0) {
        id
        title
    }
}

Take (limit)

| Type | Supported | |------------|-----------| | findFirst | ❌ | | findMany | ✅ | | findUnique | ❌ |

Example:

query {
    findManyTodo(take: 10) {
        id
        title
    }
}

Graphql Features

| Feature | Available | Notes | |----------------|-----------|------------------------------------------| | FieldResolvers | ✅ | both up and down relationships supported | | Mutations | ✅ | | | Query | ✅ | | | Resolvers | ✅ | |


Example

See a generated example here; note, when the output is in a node_modules directory, it will automatically transpile cjs and mjs versions.


Road Map

  • authentication guard integration
  • cursor-based pagination
  • expand gt, gte, lt, lte, notIn, in, not "where" filtering to types other than DateTime, Int, and String

TODO

  • fix orderBy ArgTypes casting to Prisma.{Model}FindManyArgs['orderBy']
  • fix data ArgTypes casting to Prisma.{Model}CreateArgs['data']
  • fix where ArgTypes casting to Prisma.{Model}FindManyArgs['where']