Nexus

Auto generate CRUD system from your schema.prisma file.

CONTENT

Example Usage

For more information about Prisma look at they Docs

schema.prisma

datasource postgresql {
  url      = env("DATABASE_URL")
  provider = "postgresql"
}
generator client {
  provider = "prisma-client-js"
}
model User {
  id        Int      @id @default(autoincrement())
  createdAt DateTime @default(now())
  email     String   @unique
  name      String?
  role      Role     @default(USER)
  posts     Post[]
}
model Post {
  id         Int        @id @default(autoincrement())
  createdAt  DateTime   @default(now())
  updatedAt  DateTime   @updatedAt
  published  Boolean    @default(false)
  title      String
  author     User?      @relation(fields:  [authorId], references: [id])
  authorId   Int?
}
enum Role {
  USER
  ADMIN
}

After build your schema.prisma file all you need to run

> prisma generate
> pal g

For more information about pal g command configurations click here

Output

Each model will have folder contain 11 files:

NOTE: You can customize all this files and add your logic code inside it just */type.ts will rewrite on it.

  • User model
    • User/mutations/createOne.ts
    • User/mutations/deleteOne.ts
    • User/mutations/updateOne.ts
    • User/mutations/upsertOne.ts
    • User/mutations/deleteMany.ts
    • User/mutations/updateMany.ts
    • User/queries/findCount.ts
    • User/queries/findCount.ts
    • User/queries/findMany.ts
    • User/queries/aggregate.ts
    • User/type.ts
  • Post model
    • Post/mutations/createOne.ts
    • Post/mutations/deleteOne.ts
    • Post/mutations/updateOne.ts
    • Post/mutations/upsertOne.ts
    • Post/mutations/deleteMany.ts
    • Post/mutations/updateMany.ts
    • Post/queries/findCount.ts
    • Post/queries/findMany.ts
    • Post/queries/findUnique.ts
    • Post/queries/aggregate.ts
    • Post/type.ts

To understand this code structure please look to Nexus Docs

type.ts

import { objectType } from 'nexus'

export const User = objectType({
  nonNullDefaults: {
    output: true,
    input: false,
  },
  name: 'User',
  definition(t) {
    t.int('id')
    t.field('createdAt', { type: 'DateTime' })
    t.string('email')
    t.nullable.string('name')
    t.field('role', { type: 'Role' })
    t.list.field('posts', {
      type: 'Post',
      args: {
        where: 'PostWhereInput',
        orderBy: 'PostOrderByInput',
        cursor: 'PostWhereUniqueInput',
        take: 'Int',
        skip: 'Int',
        distinct: 'PostScalarFieldEnum',
      },
      resolve(root: any) {
        return root.posts
      },
    })
  },
})

queries

    import { queryField, nonNull } from 'nexus'
    
    export const UserFindUniqueQuery = queryField('findUniqueUser', {
      type: 'User',
      args: {
        where: nonNull('UserWhereUniqueInput'),
      },
      resolve(_parent, { where }, { prisma, select }) {
        return prisma.user.findUnique({
          where,
          ...select,
        })
      },
    })

    mutations

      import { mutationField, nonNull } from 'nexus'
      
      export const UserCreateOneMutation = mutationField('createOneUser', {
        type: nonNull('User'),
        args: {
          data: nonNull('UserCreateInput'),
        },
        resolve(_parent, { data }, { prisma, select }) {
          return prisma.user.create({
            data,
            ...select,
          })
        },
      })

      Add paljs plugin

      This plugin adds three parts

      • PrismaSelect plugin to convert info: GraphQLResolveInfo to select object accepted by prisma client and add to context
      • Admin settings queries and mutations getSchema, updateField, updateModel
      • All models inputs type
        • UserWhereInput
        • UserWhereUniqueInput
        • UserOrderByInput
        • UserCreateInput
        • UserUpdateInput
        • UserUpdateManyMutationInput

      for include admin settings queries you need to pass in plugin settings

      paljs({
        excludeFields: ['password'],
        filterInputs: (input) => input.fields.filter((field) => field.name !== 'passowrd'),
      });
      
      type options = {
        // this options will pass to PrismaSelect class as second arg. https://paljs.com/plugins/select#constructor
        prismaSelectOptions?: {
          defaultFields?: {
            [key: string]:
                    | { [key: string]: boolean }
                    | ((select: any) => { [key: string]: boolean });
          };
          dmmf?: DMMF.Document[];
        };
        // by default adminSchemaPath is `adminSettings.json` you can change it
        adminSchemaPath?: string;
        // include Prisma Admin schema query and mutations
        includeAdmin?: boolean;
        // send custom dmmf if you have custom generated client path for generate input types
        dmmf?: DMMF.Document[];
        // take an array of field names to exclude from any input type
        excludeFields?: string[];
        // take a function and the input object as arg and return array of fields you want to generate
        filterInputs?: (input: DMMF.InputType) => DMMF.SchemaArg[];
        // by default when we create update inputs you will set data like {username: {set: "Ahmed"}} by making this option true you will be able to use it like {username: "Ahmed"} without set.
        // but you will also lose these options for number fields
        // increment: x: Adds x to the current value
        // decrement: x: Subtracts x from the current value
        // multiply: x: Multiplies the current value by x
        // divide: x: Divides the current value by x
        // set: x: Sets the value to x (equivalent to data: { age: 18 })
        doNotUseFieldUpdateOperationsInput?: boolean;
      }

      Install

      Version Downloads/week License

      yarn add @paljs/nexus
      or
      npm i @paljs/nexus
      import { makeSchema } from '@nexus/schema';
      import * as types from './graphql';
      import { paljs } from '@paljs/nexus';
      
      export const schema = makeSchema({
        types,
        plugins: [paljs()],
        outputs: {
          schema: __dirname + '/generated/schema.graphql',
          typegen: __dirname + '/generated/nexus.ts',
        },
        typegenAutoConfig: {
          sources: [
            {
              source: '@prisma/client',
              alias: 'prisma',
            },
            {
              source: require.resolve('./context'),
              alias: 'Context',
            },
          ],
          contextType: 'Context.Context',
        },
      });

      Use

      import { queryField, nonNull } from 'nexus'
      
      export const UserFindUniqueQuery = queryField('findUniqueUser', {
        type: 'User',
        args: {
          where: nonNull('UserWhereUniqueInput'),
        },
        resolve(_parent, { where }, { prisma, select }) {
          return prisma.user.findUnique({
            where,
            ...select,
          })
        },
      })