GithubHelp home page GithubHelp logo

michallytek / typegraphql-prisma Goto Github PK

View Code? Open in Web Editor NEW
861.0 20.0 104.0 252.9 MB

Prisma generator to emit TypeGraphQL types and CRUD resolvers from your Prisma schema

Home Page: https://prisma.typegraphql.com

License: MIT License

TypeScript 97.04% JavaScript 2.07% Shell 0.12% CSS 0.78%
prisma graphql typegraphql type-graphql generator crud prisma-generator

typegraphql-prisma's People

Contributors

0xflotus avatar ahabhgk avatar beeman avatar carlocorradini avatar christiandavis avatar jmfury avatar kirillsbarsukov avatar mateuszitelli avatar michallytek avatar re9inee avatar samuelnittala avatar vanduc1102 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

typegraphql-prisma's Issues

Problem with type conflicts when using doc lines to change field names

I'm running into an issue with type conflicts when using doc lines in schema.prisma to change field names, where it looks like the type that prisma returns from create/find/etc doesn't match up with the type that is generated by typegraphql-prisma.
I am using typegraphql-prisma 0.8.0, prisma-cli 2.8.1 and prisma client 2.8.1
Here is my schema.prisma (I removed the unrelated models for brevity)

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

generator typegraphql {
  provider = "typegraphql-prisma"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}


model Course {
  id            Int            @id @default(autoincrement())
  title         String
  subject       String
  headline      String
  intro         String
  /// @TypeGraphQL.field(name: "creatorId")
  creator_id    Int
  createdAt     DateTime       @default(now()) @map("created_at")
  updatedAt     DateTime       @default(now()) @updatedAt @map("updated_at")
  creator       User           @relation(fields: [creator_id], references: [id])
  enrolledUsers CoursesUsers[]
  lessons       Lesson[]

  @@map("course")
}

model CoursesUsers {
  /// @TypeGraphQL.field(name: "courseId")
  course_id Int
  /// @TypeGraphQL.field(name: "userId")
  user_id   Int
  course    Course @relation(fields: [course_id], references: [id])
  user      User   @relation(fields: [user_id], references: [id])

  @@id([course_id, user_id])
  @@map("courses_users")
}

model User {
  id              Int            @id @default(autoincrement())
  username        String         @unique
  email           String         @unique
  /// @TypeGraphQL.omit(output: true)
  password        String?
  googleId        String?        @map("google_id")
  facebookId      String?        @map("facebook_id")
  createdAt       DateTime       @default(now()) @map("created_at")
  updatedAt       DateTime       @default(now()) @updatedAt @map("updated_at")
  createdCourses  Course[]
  enrolledCourses CoursesUsers[]
  lessons         Lesson[]
  notes           Note[]

  @@map("user")
}

And here is where I am trying to use the generated type but am running into a conflict (the service is just a function called by a controller which is the actual resolver)

import { User, Course } from "@generated/type-graphql";
import { PrismaClient } from "@prisma/client";

export const createCourseService = async (
  prisma: PrismaClient,
  createCourseInput: CreateCourseInput,
  userId: number
): Promise<Course> => {
  let err, newCourse: Course | undefined, foundUser;
  const { course, user } = prisma;

  [err, foundUser] = await to(user.findOne({ where: { id: userId } }));
  if (err) throw new Error(err.message);
  if (!foundUser)
    throw new AuthenticationError("Could not find user to create course");

  [err, newCourse] = await to(
    course.create({
      data: {
        ...createCourseInput,
        creator: {
          connect: { id: userId },
        },
      },
    })
  );
  if (err) throw new Error(err.message);
  if (!newCourse) {
    throw new ApolloError("Internal server error. Could not create newCourse");
  }

  return newCourse;
};

So my error message says: Type 'import("c:/Users/Joel/Documents/webprojects/serious/Smarterish/code/server/node_modules/.prisma/client/index").Course | undefined' is not assignable to type 'import("c:/Users/Joel/Documents/webprojects/serious/Smarterish/code/server/node_modules/@generated/type-graphql/models/Course").Course | undefined'.
Property 'creatorId' is missing in type 'import("c:/Users/Joel/Documents/webprojects/serious/Smarterish/code/server/node_modules/.prisma/client/index").Course' but required in type 'import("c:/Users/Joel/Documents/webprojects/serious/Smarterish/code/server/node_modules/@generated/type-graphql/models/Course").Course'.

I'm not sure if it's an actual issue or if I should mark the return type as Prisma.Course rather than Course from typegraphql or what.

Error message: ApolloServer context parameter

When prisma is not returned as part of the context callback in the ApolloServer constructor, a generic "cannot get x of type undefined" is returned whenever a graphql query is run. This is documented in the README, however, a more helpful error message could go a long way here. I lost a fair amount of time debugging this issue until I found the relevant documentation.

Essentially, check if prisma exists on the context object, and if it doesn't, throw a more helpful error.

Treat @id fields in schema as ID type in GraphQL

I have a schema that is using @id @default(cuid()) as ID column, but TypeGraphQL is setting this field as a String, not as a ID.

Is there any way to tell TypeGraphQL to set the id field type of the prisma schema to the ID Type?

How to write tests on resolvers

I'd like to write unit tests for resolvers in an app that uses this package. I've been following the guidance of this issue on writing tests:

MichalLytek/type-graphql#231 (comment)

Does this model also work in an environment with Prisma? What extra steps are necessary to be able to test custom resolvers, if any? Would they be the same as if we were testing TypeGraphQL resolvers without Prisma?

Tackle the circular imports without needing to use `commonjs`

Fantastic work on transpiling @MichalLytek.
I was thinking about how we could tackle the circular imports without needing to use commonjs on everything.
I was wondering if bundling all the transpiled code into a single file would be possible 🤔
Bundling would also reduce the size if only by removing all the import statements which in turn may reduce write time to disk as there is less to write and it is all in only a few files rather then what could be up to hundreds.

If we can reduce generation times that would be great as then we could also improve testing speed.

Originally posted by @wSedlacek in #1 (comment)

Error: Generator at node ./node_modules/typegraphql-prisma/generator.js could not start

Happens because generator.js resides in
./node_modules/typegraphql-prisma/lib/generator.js not in
./node_modules/typegraphql-prisma/generator.js

package.json:

"@prisma/cli": "^2.10.1",
"@prisma/client": "^2.10.1",
"typegraphql-prisma": "^0.8.3"

output:

Error: Generator at node ./node_modules/typegraphql-prisma/generator.js could not start:

internal/modules/cjs/loader.js:968
  throw err;
  ^
Error: Cannot find module '/path/to/project/node_modules/typegraphql-prisma/generator.js'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:965:15)
    at Function.Module._load (internal/modules/cjs/loader.js:841:27)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47 {
  code: 'MODULE_NOT_FOUND',
  requireStack: []
}

Use within the web browser completely? a question, not an issue

Hello, this is a question, not an issue.

I would like to use all of this, typeorm and this project all within the browser, without a nodejs server.

Having established that I can use typeorm from within the browser with the database within the browser and run an example code which does that, then I want to use this tool typegraphql-prisma to generate the files and then from prisma and do graphql queries.

I've tried to embed ApolloServer within the web browser using webpack but failed to do so, it seems to use too many nodejs dependencies which will not work in the browser via webpack.

So the question is, can you give any advice how I could go about getting all of this to work within the web browser? Being able to store state within the database within the web browser and applying GraphQL queries on that is my goal.

could I run a graphql query using typegraphql in the browser using the outputs of this prisma typegraphql project? I mean using the files outputted from the prisma

Error: Unrecognized scalar type: Bytes

Hello, i'm using the Prisma/cli and prisma/client version 2.12.1. i'm using these because i hava Bytea fields in psql and the introspection convert it to Bytes.
This scalar type isn't an option on helpers.js file.
Could you tell me what can i fix it.
Thanks in advance.

Many to Many Relations resolver seems to confuse field order

I have this model (simplified version):

model User {
  id                String      @id @default(cuid())
  name              String
  memberOfProjects  UsersOnProjects[]
  ownsProjects      Project[]
}

model Project {
  id            String      @id @default(cuid())
  owner         User        @relation(fields: [ownerId], references: [id])
  ownerId       String
  members       UsersOnProjects[]
}

model UsersOnProjects {
  project       Project     @relation(fields: [projectId], references: [id])
  projectId     String
  user          User        @relation(fields: [userId], references: [id])
  userId        String
  createdAt     DateTime    @default(now())

  @@id([userId, projectId])
}

After the typegraphql generation I have this relations resolver:

import * as TypeGraphQL from "type-graphql";
import { Project } from "../../../models/Project";
import { User } from "../../../models/User";
import { UsersOnProjects } from "../../../models/UsersOnProjects";

@TypeGraphQL.Resolver(_of => UsersOnProjects)
export class UsersOnProjectsRelationsResolver {
  @TypeGraphQL.FieldResolver(_type => Project, {
    nullable: false
  })
  async project(@TypeGraphQL.Root() usersOnProjects: UsersOnProjects, @TypeGraphQL.Ctx() ctx: any): Promise<Project> {
    return ctx.prisma.usersOnProjects.findUnique({
      where: {
        projectId_userId: {
          projectId: usersOnProjects.projectId,
          userId: usersOnProjects.userId,
        },
      },
    }).project({});
  }

  @TypeGraphQL.FieldResolver(_type => User, {
    nullable: false
  })
  async user(@TypeGraphQL.Root() usersOnProjects: UsersOnProjects, @TypeGraphQL.Ctx() ctx: any): Promise<User> {
    return ctx.prisma.usersOnProjects.findUnique({
      where: {
        projectId_userId: {
          projectId: usersOnProjects.projectId,
          userId: usersOnProjects.userId,
        },
      },
    }).user({});
  }
}

Then I am trying to query this:

query project($id: String!) {
    project(where: {id: $id}) {
        id
        createdAt
        members(where: {projectId: {equals: $id}}) {
            user {
                name
                id
            }
        }
        content
    }
}

But apollo returns an error:

{
  where: {
    projectId_userId: {
    ~~~~~~~~~~~~~~~~
      projectId: 'somerandomid',
      userId: 'anotherrandomid'
    }
  },
  select: {
    user: {}
  }
}

Unknown arg `projectId_userId` in where.projectId_userId for type UsersOnProjectsWhereUniqueInput. Did you mean `userId_projectId`? Available args:
type UsersOnProjectsWhereUniqueInput {
  userId_projectId?: UsersOnProjectsUserIdProjectIdCompoundUniqueInput
}

Changing the queried field in the generated relations resolver accordingly to userId_projectId instead of projectId_userId fixes the issue, but of course after regeneration the error pops up again.

I am not quite sure why it has to be a specific order, but I guess the generator has to be fixed to swap the order of the fields in the relation.

Env var to bypass Prisma version validation

We are writing an E2E test with dev version of Prisma and typegraphql-prisma. The goal is to detect any breaking changes from Prisma's end in typegraphql-prisma as early as possible.

Today this is not possible because validation returns

Error: Looks like you use an incorrect version of the Prisma packages: "2.12.0-dev.8". Please ensure that you have installed a version that meets 'typegraphql-prisma' requirement: "~2.11.0".

It would be great to have an env var like VALIDATE_PRISMA_VERSION=<boolean> to bypass this check.

"UpdateManyMutationInput" empty for a joining table

I have a simple app with the following Prisma schema:

model TodoViewTodo {
  id          Int      @id @default(autoincrement())
  todo        Int
  todoView    Int
  placeholder String?
  Todo        Todo     @relation(fields: [todo], references: [id])
  TodoView    TodoView @relation(fields: [todoView], references: [id])
}

model Todo {
  id           Int            @id @default(autoincrement())
  text         String
  done         Boolean?
  user         Int
  User         User           @relation(fields: [user], references: [id])
  TodoViewTodo TodoViewTodo[]
}

model TodoView {
  id           Int            @id @default(autoincrement())
  label        String
  order        String?
  color        String
  TodoViewTodo TodoViewTodo[]
}

When I generate a schema using typegraphql-prisma resolvers and buildSchema I get an empty input:

input TodoViewTodoUpdateManyMutationInput

which causes all GraphQL operations to fail due to an invalid schema.

I had to add the placeholder field for this input not to be empty, which is not ideal.

Errors about accessing inputs before initialization

Originally posted by @J718 in #1 (comment)

"type-graphql": "^1.0.0",
typegraphql-prisma": "^0.6.1",

I keep getting errors about accessing inputs before initialization and wanted to get your input. The error is as follows:

ReferenceError: Cannot access 'BankAccountWhereInput' before initialization
    at Module.BankAccountWhereInput (C:\Users\jacob\OneDrive\Documents\GitHub\tictactoe\.next\server\pages\api\graphql.js:11490:113)
    at Module../src/prisma/generated/type-graphql/resolvers/inputs/BankAccountListRelationFilter.ts (C:\Users\jacob\OneDrive\Documents\GitHub\tictactoe\.next\server\pages\api\graphql.js:10345:110)
    at __webpack_require__ (C:\Users\jacob\OneDrive\Documents\GitHub\tictactoe\.next\server\pages\api\graphql.js:23:31)     
    at Module../src/prisma/generated/type-graphql/resolvers/inputs/BankConnectionWhereInput.ts (C:\Users\jacob\OneDrive\Documents\GitHub\tictactoe\.next\server\pages\api\graphql.js:13159:95)
    at __webpack_require__ (C:\Users\jacob\OneDrive\Documents\GitHub\tictactoe\.next\server\pages\api\graphql.js:23:31)     
    at Module../src/prisma/generated/type-graphql/resolvers/inputs/BankAccountWhereInput.ts (C:\Users\jacob\OneDrive\Documents\GitHub\tictactoe\.next\server\pages\api\graphql.js:11499:90)
    at __webpack_require__ (C:\Users\jacob\OneDrive\Documents\GitHub\tictactoe\.next\server\pages\api\graphql.js:23:31)     
    at Module../src/prisma/generated/type-graphql/resolvers/crud/BankAccount/args/AggregateBankAccountArgs.ts (C:\Users\jacob\OneDrive\Documents\GitHub\tictactoe\.next\server\pages\api\graphql.js:3695:87)
    at __webpack_require__ (C:\Users\jacob\OneDrive\Documents\GitHub\tictactoe\.next\server\pages\api\graphql.js:23:31)     
    at Module../src/prisma/generated/type-graphql/resolvers/crud/BankAccount/BankAccountCrudResolver.ts (C:\Users\jacob\OneDrive\Documents\GitHub\tictactoe\.next\server\pages\api\graphql.js:3208:88)

I have the following schema.prisma file.

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

generator typegraphql {
  provider = "node ../node_modules/typegraphql-prisma/generator.js"
  output   = "../prisma/generated/type-graphql"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model Account {
  id                 Int       @default(autoincrement()) @id
  compoundId         String    @unique @map(name: "compound_id")
  userId             Int       @map(name: "user_id")
  providerType       String    @map(name: "provider_type")
  providerId         String    @map(name: "provider_id")
  providerAccountId  String    @map(name: "provider_account_id")
  refreshToken       String?   @map(name: "refresh_token")
  accessToken        String?   @map(name: "access_token")
  accessTokenExpires DateTime? @map(name: "access_token_expires")
  createdAt          DateTime  @default(now()) @map(name: "created_at")
  updatedAt          DateTime  @default(now()) @map(name: "updated_at")

  @@index([providerAccountId], name: "providerAccountId")
  @@index([providerId], name: "providerId")
  @@index([userId], name: "userId")

  @@map(name: "accounts")
}



model BankAccount {
  account_id        String         @id
  bankConnectionId  Int            @map(name: "bank_connection_id")
  balancesAvailable Float            @map(name: "balances_available")
  balancesCurrent   Float            @map(name: "balances_current")
  isoCurrencyCode   String         @map(name: "iso_currency_code")
  name              String
  officialName      String         @map(name: "official_name")
  subtype           String
  type              String
  bankConnection    BankConnection @relation(fields: [bankConnectionId], references: [id])

  @@map(name: "bank_account")

}

model BankConnection {
  id          Int           @default(autoincrement()) @id
  user        User          @relation(fields: [userId], references: [id])
  userId      Int           @map(name: "user_id")
  itemId      String        @map(name: "item_id")
  accessToken String        @map(name: "access_token")
  bankAccounts BankAccount[]


  @@map(name: "bank_connection")

}
model Session {
  id           Int      @default(autoincrement()) @id
  userId       Int      @map(name: "user_id")
  expires      DateTime
  sessionToken String   @unique @map(name: "session_token")
  accessToken  String   @unique @map(name: "access_token")
  createdAt    DateTime @default(now()) @map(name: "created_at")
  updatedAt    DateTime @default(now()) @map(name: "updated_at")
  user         User     @relation(fields: [userId], references: [id])


  @@map(name: "sessions")
}

model User {
  id              Int              @default(autoincrement()) @id
  name            String?
  email           String?          @unique
  emailVerified   DateTime?        @map(name: "email_verified")
  image           String?
  createdAt       DateTime         @default(now()) @map(name: "created_at")
  updatedAt       DateTime         @default(now()) @map(name: "updated_at")
  bankConnections BankConnection[]
  sessions        Session[]


  @@map(name: "users")
}

model VerificationRequest {
  id         Int      @default(autoincrement()) @id
  identifier String
  token      String   @unique
  expires    DateTime
  createdAt  DateTime @default(now()) @map(name: "created_at")
  updatedAt  DateTime @default(now()) @map(name: "updated_at")

  @@map(name: "verification_requests")
}

Here is my build schema command

    const schema = await buildSchema({
      // resolvers: [CreateLinkTokenResolver, UserCrudResolver, GameCrudResolver, UserRelationsResolver, GameRelationsResolver],
      resolvers: [LinkTokenResolver, UserRelationsResolver ],
      authChecker: customAuthChecker,
      validate: false,
    })

[0.8.4] Error when generating code

Describe the Bug
Yesterday I downgraded prisma from 2.11.0 to 2.10.2 to be able to use with your marvellous library. This morning I have seen your update to 0.8.4 and I have upgrade my prisma version to 2.11.0 again and update yours. And when I try to generate the code it throws this error. Object.fromEntries is not a function

To Reproduce

  prisma generate

Environment variables loaded from D:\project\prisma\.env
Prisma schema loaded from prisma\schema.prisma
Error: 
✔ Generated Prisma Client (version: 2.11.0) to .\node_modules\@prisma\client in 188ms

TypeError: Object.fromEntries is not a function
    at Object.generateEnhanceMap (D:\project\node_modules\typegraphql-prisma\lib\generator\enhance.js:20:63)
    at Object.generateCode [as default] (D:\project\node_modules\typegraphql-prisma\lib\generator\generate-code.js:158:15)
    at Object.generate [as onGenerate] (D:\project\node_modules\typegraphql-prisma\lib\cli\prisma-generator.js:32:34)

Environment (please complete the following information):

  • OS: Windows
  • Node: 10.19.0
  • Package version: 0.8.4
  • TypeScript version: 4.0.5
  • @prisma/cli & @prisma/client: 2.11.0

Thanks for all your work!

Should Prisma list fields be nullable?

When having a Prisma schema like this:

model Plan {
  zipCodes String[]
}

And then generate the corresponding types with [email protected] it generates the following model:

@TypeGraphQL.ObjectType({
  isAbstract: true,
  description: undefined,
  simpleResolvers: undefined,
})
export class Plan {
  @TypeGraphQL.Field(_type => [String], {
    nullable: true,
    description: undefined,
  })
  zipCodes?: string[] | null;
}

But since list field types cannot be set as optional in Prisma, shouldn't the resulting model be like this?

@TypeGraphQL.ObjectType({
  isAbstract: true,
  description: undefined,
  simpleResolvers: undefined,
})
export class Plan {
  @TypeGraphQL.Field(_type => [String], {
    nullable: false,
    description: undefined,
  })
  zipCodes!: string[];
}

This is a simple example to illustrate the situation we are experiencing with lists/arrays

Using:

Adding custom scalars

It would be useful if there would be a way to map certain primitive field scalars from certain types of the prisma schema to custom graphql scalars for example with graphql-scalars to have an even stricter type system which also reduces the need for class-validator since the validation takes place directly at the resolver level. It would be really nice to have this feature to have more control over the schema generation.

Example:

type definition of Person in prisma.schema with the primitive type String:

model Person {
  email String
}

type definition of Person in schema.graphql with a custom scalar EmailAddrress:

type Person {
  email: EmailAddress
}

generated type definition of Person as a typegraphql object type with custom scalar resolver:

import { EmailAddressResolver } from 'graphql-scalars';

@ObjectType()
export class Person {
  @Field(() => EmailAddressResolver)
  email!: string;
}

Compatibility issues between typegraphql and prisma enum types

I have a property status (ENUM) which seems to cause compatibility issues, so I'm required to use Prisma Client's model instead of the one generated by type-graphql. Do you know what this might be?

image

If I use the CatalogModel then it works fine, but when I use the one generated by type-graphql, I get the above issue.
image

Originally posted by @jsefiani in #1 (comment)

Getting error when running prisma generate on docker build command

Thank you for the amazing library. When running prisma generate inside docker build command, I am getting below error. Though, prisma client is able to generate the code but not typegraphql-prisma.

> prisma generate


Prisma schema loaded from prisma/schema.prisma
Error:
TypeError: Cannot read property 'datamodel' of undefined
    at Object.generateCode [as default] (/home/app/node_modules/typegraphql-prisma/lib/generator/generate-code.js:37:29)
    at Object.generate [as onGenerate] (/home/app/node_modules/typegraphql-prisma/lib/cli/prisma-generator.js:32:34)
    at async LineStream.<anonymous> (/home/app/node_modules/@prisma/generator-helper/dist/generatorHandler.js:13:32)


✔ Generated Prisma Client (version: 2.11.0) to ./node_modules/@prisma/client in 277ms

Here is my Dockerfile.

FROM node:lts AS base

WORKDIR /home/app

COPY package*.json ./

RUN npm install

COPY src src
COPY prisma prisma
COPY tsconfig.json tsconfig.json

RUN npm run generate:prisma

Here is my schema.prisma file header.

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator typegraphql {
  provider           = "typegraphql-prisma"
  useOriginalMapping = true
}

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

Relation fields not available in qieries' selection

I have a simple app with the following Prisma schema:

model TodoViewTodo {
  id          Int      @id @default(autoincrement())
  todo        Int
  todoView    Int
  placeholder String?
  Todo        Todo     @relation(fields: [todo], references: [id])
  TodoView    TodoView @relation(fields: [todoView], references: [id])
}

model Todo {
  id           Int            @id @default(autoincrement())
  text         String
  done         Boolean?
  user         Int
  User         User           @relation(fields: [user], references: [id])
  TodoViewTodo TodoViewTodo[]
}

model TodoView {
  id           Int            @id @default(autoincrement())
  label        String
  order        String?
  color        String
  TodoViewTodo TodoViewTodo[]
}

There should be a way to get those relational fields, like:

query {
    todoViews {
      id
      TodoViewTodo {
        id
      }
    }
}

It is possible to filter the result using relational fields:

query {
  todoViews(
    where: {
      TodoViewTodo: { every: { Todo: { is: { done: { equals: true } } } } }
    }
  ) {
    id
  }
}

so I think it would be only consistent if it was possible to select those fields too.

Code-first approach using classes with decorators as a single source of truth

From #1 (comment):

And in the near feature - when Prisma SDK will be ready - the typegraphql-prisma integration will also allow to use a code-first approach to build a schema.prisma and GraphQL schema at once, using classes with decorators as a single source of truth. Stay tuned! 💪

Are we there yet? Is the Prisma SDK ready? If not, what exactly is missing?

Recently I've been chatting with @divyenduz and he asked to open issue(s) about this in Prisma repo(s), so the Prisma team would have them in mind.

Error while generating for big Prisma schema

I'm trying the generator with a large prisma schema (3200 lines).
Getting this RangeError: Maximum call stack size exceeded.

prisma generate runs in 1s without the typegraphql generator.

image

ApplyModelEhanceMap doesn't apply decorators on moleculerjs

Steps to reproduce

  1. Create a moleculerjs typescript project.
  2. Create a Service with the contents below
  3. Run with npm run dev

Note

Start the server with ts-node and everything works normally.

Is there any thing that ApplyModelEhanceMap relies on?
The function to apply decorators to resolvers works fine.

import "reflect-metadata";

import {
	resolvers,
	applyModelsEnhanceMap,
	ModelsEnhanceMap,
} from "@generated/type-graphql";
import { buildSchema } from "type-graphql";

import { ApolloServer } from "apollo-server";
import { PrismaClient } from "@prisma/client";

import { Authorized, AuthChecker } from "type-graphql";

const modelsEnhanceMap: ModelsEnhanceMap = {
	User: {
		fields: {
			firstName: [Authorized(["ADMIN"])],
		},
	},
};

const customAuthChecker: AuthChecker<Context> = (
	{ root, args, context, info },
	roles
) => {
	throw ""; // Never Executed
	return false; // or false if access is denied
};
applyModelsEnhanceMap(modelsEnhanceMap);

interface Context {
	prisma: PrismaClient;
}

async function main() {
	const prisma = new PrismaClient();
	await prisma.$connect();
	const schema = await buildSchema({
		resolvers: resolvers,
		authChecker: customAuthChecker,
		authMode: "error",
		validate: true,
	});
	const server = new ApolloServer({
		schema,
		playground: true,
		context: (): Context => ({ prisma }),
	});
	const { port } = await server.listen(4000);
	console.log(`GraphQL is listening on ${port}!`);
}

export = {
	name: "api2",

	mixins: [],

	async started() {
		try {
			await main();
		} catch (e) {
			console.error(e);
		}
	},
};

// Uncomment and execute the file with ts-node, everything works normally. 

// (async () => {
// 	try {
// 		await main();
// 	} catch (e) {
// 		console.error(e);
// 	}
// })();

Discussion about Prisma 2 integration

This issue was transferred from the main repo. Be aware that some links in this discussion might be outdated.

I am thrilled to present the first preview of the upcoming TypeGraphQL & Prisma Framework integration 🎉

integration logo

You can install it right now - it's distributed as a package typegraphql-prisma on NPM:
https://www.npmjs.com/package/typegraphql-prisma

All the docs (in readme), examples and the source code of the integration are located on the prisma branch of this repo (in the future it will be moved into a master branch when I finish converting the project to a monorepo):
https://github.com/MichalLytek/type-graphql/tree/prisma

Currently released version 0.x is just a preview - it lacks some customization option, like picking/omitting fields of object types to expose in the schema, as well as picking CRUD methods and exposed args. However, the base functionality is working well, so I strongly encourage you to give it a try and play with it.

Any feedback about the developers experience, bug reports or ideas about new features or enhancements are very welcome. However, during the preview I would ask to use the dedicated Gitter room if you have any questions:
https://gitter.im/type-graphql/prisma2
If you have a bug report, feel free to add comments only in this issue, not to create a new issues, as I don't want to pollute the repo for now 😉

And in the near feature - when Prisma SDK will be ready - the typegraphql-prisma integration will also allow to use a code-first approach to build a schema.prisma and GraphQL schema at once, using classes with decorators as a single source of truth. Stay tuned! 💪

Union Resolvers feature idea

I had an idea for another possible feature.
Union Resolvers. Adding /// @TypeGraphql.Union = result to two models will generate an additional set of findOne/findMany revolvers of a union type of each model that is in that union.

An example may look like this.

/// @TypeGraphql.Union = product
model Movie {
  id        Int     @id @default(autoincrement())
  title     String
  length    Int
  actors    Actor[]
}

/// @TypeGraphql.Union = product
model Book {
  id        Int     @id @default(autoincrement())
  title     String
  pages     Int   
}

model Actor {
  id        Int     @id @default(autoincrement())
  name      String
}

Which would generate this type and the resolvers for it.

export const Product = createUnionType({
  name: 'Product',
  types: () => [Movie, Book],
});

The Prisma code for this may look something like this.

const movies = await prisma.movies.findMany(args).then((movies: Movie[]) => plainToClass(Movie, movies));
const books = await prisma.books.findMany(args).then((books: Book[]) => plainToClass(Book, books));
return [...movies, ...books].sort(byArgs(args));

The difficult part would be defining the orderBy and where arguments as you would need to determine what fields were shared between the two (or more) models and use those to generate the arguments.
Additionally sorting will likely have some additional overhead but it would be cool to be able to do something like this.

{
  products {
    ... on Book {
      title
      pages
    }
    ... on Movie {
      title
      length
    }
  }
}

Originally posted by @wSedlacek in #1 (comment)

Not able to overwrite the type of a resolved field

Package versions:

  • typegraphql-prisma: 0.8.2
  • @prisma/client: 2.8.1

Description:
I created the following many-to-many relationship in my PostgreSQL database using Prisma:

image

When I query the products, I also want to query its categories. To make this possible I created the following field resolver that returns the type CategoriesConnection:

image

When inspecting my schema using the GraphQL playground, I see that the type of categories is not overwritten by the type that I provided, it remains [Category!] (was automatically provided by Prisma):

image

Does my explanation make sense? If not I would be happy to provide you with more details.

Nullable string changed behavior

Trying to upgrade from Prisma 2.5.1 to a newer version for quite a while with no luck so versions drifted already.
Now trying to upgrade:

From:

"@prisma/cli": "^2.5.1",
"@prisma/client": "^2.5.1",
"typegraphql-prisma": "^0.5.0"

Where this (barebone version of the) code was generated:

class UpdateInput {
  text?: string | undefined;
}

And this intuitive code used to work:

const data: UpdateInput = {
  text: 'some text'
};
const text = data.text;

To:

"@prisma/cli": "^2.11.0",
"@prisma/client": "^2.11.0",
"typegraphql-prisma": "^0.8.4"

Where the generated code got modified to:

class NullableStringFieldUpdateOperationsInput {
  set?: string | undefined;
}

class UpdateInput {
  text?: NullableStringFieldUpdateOperationsInput | undefined;
}

And this code doesn't work anymore:

const data: UpdateInput = {
  text: 'some text'
};
const text = data.text;

My question:

Is it correct that at this point the code should be written in this less-intuitive way:

const data: UpdateInput = {
  field: { set: 'some text' }
};
const text = data.text?.toString();

Or am I missing something and there's a way to use it intuitively?

  • This is a non-trivial change and I'd like to verify that our code base won't break.

Import all generated code

Hi! After trying to adopt Prisma 2 and migrate my last few years of work to it I was little tired. Prisma 1 was really handy. Today I found this project and it is life saver. Michal excellent work!! Thank you!
My question is maybe the word of lazy dev but I is there a way to import all generated code into schema builder.
...import * as typegraphql from "./prisma/generated/type-graphql";`

...

async function main() {
  const schema = await buildSchema({
    resolvers: [
      typegraphql.resolvers      
    ],
    emitSchemaFile: path.resolve(__dirname, "./generated-schema.graphql"),
    validate: false,
  });

`
I could write anothe index.ts and export all the resolvers, but I guess that this could generated too?
Thank you again for your work!

Use Typegraphql's useMiddleware() function?

How can I implement authorization scope for different users? In plain typegraphql a simple useMiddleware function could solve it but is there a way to implement the same using typegraphql-prisma while still having the same query/mutation structure?

Empty Input Type for many to many relationship join tables

After excecute npx prisma generate we have some Input Types that's are empty, so, when i tried to run the nest app i have the following Error:

[Nest] 4976   - 2020-10-16 12:59:05   [ExceptionHandler] Some errors occurred while generating GraphQL schema:
  Input Object type Sgp_ch_turnos_agenteUpdateManyDataInput must define one or more fields.

that's my auto generated file:

import * as TypeGraphQL from "type-graphql";
import GraphQLJSON from "graphql-type-json";
import { JsonValue, InputJsonValue } from "@prisma/client";

@TypeGraphQL.InputType({
  isAbstract: true,
  description: undefined,
})
export class Sgp_ch_turnos_agenteUpdateManyDataInput {
}

Add more field decorator options inside the prisma schema

It would be awesome to have a bit more control over how the CRUD resolvers are generated. For example there could be more options to the field decorator to include authorization like so:

model User {
  id     Int     @default(autoincrement()) @id
  /// @TypeGraphQL.field(name: "emailAddress")
  email  String  @unique
  /// @TypeGraphQL.field(authorized: ["User", "Admin"])
  posts  Post[]
}

Is this something you consider as a feature? I think this would greatly increase development speed.

Complexity plugin support

@MichalLytek I have been playing around with the code base and have been testing two new features that might be nice in typegraphql-prisma.

  • Complexity plugin support
  • Default value for take (required to properly determine complexity)

Together these can prevent memory overflow high CPU utilization by limiting how complex queries can be which is extremely useful when you have large databases.

Originally posted by @wSedlacek in #1 (comment)

Authorization of generated relation resolvers

I've been searching and trying different approaches but can't find a way to apply authorization decorator to a relation resolver in a list operations, for example if I have the following schema:

model Book {
  id       Int
  author   Author @relation(fields: [authorId], references: [id])
  authorId Int
}

model Author {
  id    Int
  books Book[]
}

typegraphql-prisma would then generate the resolvers/crud/Book/BookCrudResolver.ts file which would contain a list resolver as follows:

@TypeGraphQL.Query(_returns => [Book], {
  nullable: false
})
async books(@TypeGraphQL.Ctx() ctx: any, @TypeGraphQL.Args() args: FindManyBookArgs): Promise<Book[]> {
  return ctx.prisma.book.findMany(args);
}

And a single entry resolver like this:

@TypeGraphQL.Query(_returns => Book, {
  nullable: true
})
async book(@TypeGraphQL.Ctx() ctx: any, @TypeGraphQL.Args() args: FindUniqueBookArgs): Promise<Book | null> {
  return ctx.prisma.book.findUnique(args);
}

And for the relationship with the User there would be another file at resolvers/relations/Book/BookRelationsResolver.ts which would contain a field resolver for the stablished one-to-many relationship with User like this:

@TypeGraphQL.FieldResolver(_type => Author, {
  nullable: false
})
async author(@TypeGraphQL.Root() book: Book, @TypeGraphQL.Ctx() ctx: any): Promise<Author> {
  return ctx.prisma.book.findUnique({
    where: {
      id: book.id,
    },
  }).author({});
}

Now for the authorization part I have tried the following decorator mapping:

const modelsEnhanceMap: ModelsEnhanceMap = {
  Book: {
    fields: {
      author: [Authorized()],
    }
  }
}

And it works fine for the single entry resolver book but it doesn't work for the list resolver books.

My questions is how to also apply the authorization to the listing? I suspect this might be a bug as it works in one side but not the other.

Using latest versions of typegraphql, typegraphql-prisma and prisma

update to prisma 2.9.0

The 2.8.1 prism has a problem that they solved in 2.9.0

/usr/bin/node[329084]: ../src/node_http_parser_impl.h:529:static void node::{anonymous}::Parser::Initialize(const v8::FunctionCallbackInfov8::Value&): Assertion `args[3]->IsInt32()' failed.

update your package so that you can use it

many to many table requires additional field

Describe the Bug
I have tables post | posttag | tag and code generated by prisma.
posttag table fields are postId, tagId. Its ok when I add any additional field.

node_modules\graphql\type\validate.js:69
throw new Error(errors.map(function (error) {
^
Error: Input Object type PosttagUpdateManyMutationInput must define one or more fields.

Environment (please complete the following information):

  • OS: Win 10
  • Node 15
  • Package version [e.g. 0.12.2] (please check if the bug still exist in newest release)
  • TypeScript version 4.1.3
  • types/graphql": "^14.5.0",

Problems getting the playground running with Nest.js

I am trying to set up this package together with the nest-js package using a more modular approach than the provided example:

/// app.module.ts
interface Context {
  prisma: PrismaClient;
}

const prisma = new PrismaClient();

@Module({
  imports: [
    TypeGraphQLModule.forRoot({
      validate: false,
      dateScalarMode: "timestamp",
      playground: true,
      introspection: true,
      path: "/",
      emitSchemaFile: true,
      context: (): Context => ({ prisma })
    })
  ],
  controllers: [AppController],
  providers: [
    // Models
    User,
    Project,
    // Relations
    UserRelationsResolver,
    ProjectRelationsResolver,
    // Crud
    UserCrudResolver,
    ProjectCrudResolver,
    // Custom
  ]
})
export class AppModule {
}
// main.ts
async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter());
  await app.listen(4000);
}

bootstrap();

Everything starts up fine and the graphql endpoint works as expected, but opening localhost:4000 in the browser doesn't open the playground. Is there something missing?

Hang when using yarn 2

When I use yarn 2 to run basic example, it just hang in:

Prisma Schema loaded from prisma\schema.prisma

to reproduce:

  1. Clone basic-1 example
  2. remove package-lock.json
  3. install yarn and run yarn set version berry
  4. run yarn on that directory
  5. run yarn prisma generate

prisma will hang generating typegraphql-prisma, but when I comment generator typegraphql it runs fine.

Add custom decorators on top of prisma schema resolvers

Is there a way to add custom decorators on top of prisma schema resolvers? e.g. I want for some crud operations to be available to certain roles of users. What is the approach I should use?

Originally posted by @reflash in #1 (comment)

How do I add authentication or the @Authorized detective for generated resolves? If no is there a workaround?

Originally posted by @zifahm in #1 (comment)

Currently securing a graphql api using the first-class Authorized decorator and a custom authenticator hooked into Auth0.

In the current workflow there is a lot of copy-pasting on creation and changes in order to decorate the generated resolvers that are to be secure using the decorator.
As a feature suggestion, I think it would greatly reduce this manual process by adding a custom Prisma schema decorator on the model level for the CRUD operations, or wherever this would be technically feasible to do.

Originally posted by @MichaelHindley in #1 (comment)

TypeError: Cannot read property 'output' of undefined

We are writing a E2E test for typegraphql-prisma generator. I ran into the following issue while doing that

Error: Error: 
TypeError: Cannot read property 'output' of undefined
    at Object.generate [as onGenerate] (/Users/divyendusingh/Documents/prisma/e2e-tests/community-generators/typegraphql-prisma/node_modules/typegraphql-prisma/lib/cli/prisma-generator.js:14:100)

To Reproduce

  1. package.json
{
  "name": "typegraphql-prisma",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "devDependencies": {
    "@prisma/cli": "2.11.0",
    "typegraphql-prisma": "0.8.4"
  },
  "dependencies": {
    "@prisma/client": "2.11.0"
  }
}

  1. schema.prisma
generator typegraphql {
    provider = "typegraphql-prisma"
    output   = "./generated/typegraphql-prisma"
}

model User {
    id    String  @id @default(cuid())
    email String  @unique
    name  String?
}
  1. yarn; yarn prisma generate

Reproduction repo: https://github.com/divyendu-test/typegraphql-generator-issue

File '.../args.index.ts' is not a module

I've noticed that after generation I get empty relations/args.index.ts file. It causes some bugs when compiling my ts project to js.

Screenshots:
image

image

Error:

src/generated/typegraphql-prisma/resolvers/relations/index.ts:2:15 - error TS2306: File '.../src/generated/typegraphql-prisma/resolvers/relations/args.index.ts' is not a module.

2 export * from "./args.index";

Dependency versions:
[email protected]
@prisma/[email protected]
@prisma/[email protected]

RFC: Implementation of a plugin system based in schema.prisma as the configuration driver

Problem

Software projects usually have the 90% / 10% problem, where the 90% of the project usually are CRUD systems and the other 10% business logic.

The integration between TypeGraphQL and Prisma provided by the package typegraph-prisma provides a code generation system that based in the schema from prisma.schema emits a CRUD system in top of TypeGraphQL, having a single source of truth where Prisma is the main driver of the CRUD metadata and TypeGraphQL implements the surface API that interops with it.

So, now we have our first 90% of the project automatically generated with just the adition of Prisma + TypeGraphQL code generator, lets speak about that other 10%.

In this 10%, 9% of the code will be to provide business rules to the CRUD, as resources needs usually validation and authorization to be compliant with the business rules.

So, users of this library needs to implement in top of the basic CRUD provided by TypeGraphQL that 9% of the code required to follow the business rules.

This proposal tries to create a way of creating solutions for that 9% of the code and abstract it to the schema.prisma as a series of features that would let the user have all the CRUD + rules generated as code from a single source of truth, so all the CRUD abstractions would get generated behind the scenes and only that final 1% of the business logic would need to be created, mantained and updated by the user.

To start working in that 9%, a way to extend TypeGraphQL code generation would be needed, and to not limitate users to opinioned validation and authorization it would need to be contained in to separate, importable packages, hence this RFC for a plugin system.

Current state

  • Rejected.
  • Abandoned, working on a new system as we found that code generation at our required scale was really inneficient for the cold start (Almost a minute for 49 tables).

Proposers

Proposer Github Organization
Fox Salva @SrZorro Intricom Resources SL
Bernat Vadell @bernatvadell Intricom Resources SL
Álvaro López @zifiul Intricom Resources SL
Ian Ensenyat @densenyat Intricom Resources SL

Detail

Currently typegraph-prisma uses two ways of extending the default CRUD behaviour, one that its used only internaly by TypeGraphQL that the consumers of this library can't extend currently, and another that its decorator based, but in the current state only lets decorate the resolvers, so its not specific enough to have complete control of the CRUD resources, works for stuff like Authorized or not for this resource, but doesn't leave much space for let's say this field should be validated and if its not an email stop the user request with a validation error.

Proposed solution

Example of a posible solution that given this plugin system, a plugin called typegraph-prisma-plugin-class-validator adds validation to the CRUD.

schema.prisma

generator typegraphql {
  provider        = "node ../src/cli/dev.ts"
  output          = "../prisma/generated/type-graphql"
  plugins         = ["typegraph-prisma-plugin-class-validator"]
}

model User {
  id          Int     @id @default(autoincrement())
  /// @Validator.IsEmail()
  email       String  @unique
  /// @Validator.MaxLength(30)
  /// @TypeGraphQL.field(name: "firstName")
  name        String?
  /// @Validator.Min(value: 18, message: "You must be atleast $constraint1 years old")
  age         Int
}

Generated code at models/User.ts from previous schema.prisma

import * as TypeGraphQL from "type-graphql";
import GraphQLJSON from "graphql-type-json";
import { JsonValue, InputJsonValue } from "../../../client";
import * as ClassValidator from "class-validator";

@TypeGraphQL.InputType({
  isAbstract: true,
  description: undefined,
})
export class UserCreateInput {
  @ClassValidator.IsEmail()
  @TypeGraphQL.Field(_type => String, {
    nullable: false,
    description: undefined
  })
  email!: string;

  name?: string | undefined;

  @ClassValidator.Min(18, {message: "You must be atleast $constraint1 years old"})
  @TypeGraphQL.Field(_type => TypeGraphQL.Int, {
    nullable: false,
    description: undefined
  })
  age!: number;
  
  @ClassValidator.MaxLength(30)
  @TypeGraphQL.Field(_type => String, {
    nullable: true,
    description: undefined
  })
  get firstName() {
    return this.name;
  }

  set firstName(name: string | undefined) {
    this.name = name;
  }
}

RFC current-future

schema.prisma plugin usage

Because schema.prisma gets modified by prisma instrospect we need a way to add our stuff to it without lossing our changes. Prisma doesn't touch comments while doing introspection of the DB, so we can exploit this feature for this plugin system and at the same time behing completly transparent to what does prisma underneath.

Features and rules

Basic comment

//

Lets start with the basics,
Plain prisma comments would be leaved as it is, they would be comments that appear only in schema.prisma.

From Prisma schema documentation:

// comment: This comment is for the reader's clarity and is not present in the abstract syntax tree (AST) of the schema file.

schema.prisma

// This is a basic plain comment

Abstract syntax tree (AST) comment

///

From Prisma schema documentation:

/// comment: These comments will show up in the abstract syntax tree (AST) of the schema file, either as descriptions to AST nodes or as free-floating comments. Tools can then use these comments to provide additional information.

Example of posible usage an expected output:

schema.prisma

/// This comment will appear in the generated code at the model class
model user {
  /// This comment will appear in the generated code at the 'id' field
  id          Int     @id @default(autoincrement())
}

@generated/models/User.ts

import * as TypeGraphQL from "type-graphql";

/* This comment will appear in the generated code at the model class */
@TypeGraphQL.ObjectType({
  description: "This comment will appear in the generated code",
})
export class User {
  /* This comment will appear in the generated code at the 'id' field */
  @TypeGraphQL.Field(_type => TypeGraphQL.Int, {
    nullable: false,
    description: "This comment will appear in the generated code at the 'id' field",
  })
  id!: number;
}

AST comment attributes

For future posible compatiblity with Prisma as a plugin system with first-class citizen support, we could use the same concepts used by Prisma Attributes with some minor changes to work with the limitations of having to start them with an AST comment.

If something is not overriden by this spec, its expected to be implemented following the default Prisma attributes spec.

Namespaces

Plugins need to register a namespace for them to use, so all AST comment attributes would need to follow a schema like this:

Examples:

/// @Namespace.method
/// @TypeGraphQL.field(name: "firstName")
/// @Validator.IsEmail
/// @Validator.MaxLength(30)
/// @Validator.Min(value: 18, message: "You must be atleast $constraint1 years old")

Field Attributes

Prisma Attributes defines this as field attributes:

Field attributes are marked by an @ prefix placed at the end of the field definition. You can have as many field attributes as you want and they may also span multiple lines

Given the AST comments limitations, for our case they can appear in top of the field and at the end of the field.

Block attributes

Prisma Attributes defines this as block attributes:

Field attributes are marked by an @@ prefix placed anywhere inside the block. You can have as many block attributes as you want and they may also span multiple lines

Given the AST comments limitations, for our case they can appear only in top of the model block.

Motivations

Currently typegraph-prisma uses two ways of extending the default CRUD behaviour, one that its used only internaly by TypeGraphQL that the consumers of this library can't extend currently, and another that its decorator based, but in the current state only lets decorate the resolvers, so its not specific enough to have complete control of the CRUD resources and implement plugins in top of it, works for stuff like Authorized or not for this resource, but doesn't leave much space for let's say this field should be validated and if its not an email stop the user request.

With special doc lines

Currently they are used in this features of the library:

Uses the schema.prisma as the single source of truth to extend the CRUD behaviour, but in the current state this can only be extended by adding glue code inside the library, so if let's say a consumer of the library wants to add class-validator to his CRUD it would need to do a fork of the project and hack his way arround to extend the doc anotations to add stuff like:

model User {
  id          Int     @id @default(autoincrement())
  /// @Validator.IsEmail()
  email       String  @unique
  /// @Validator.MaxLength(length: 30)
  name        String?
  /// @Validator.Min(value: 18, message: "You must be atleast $constraint1 years old")
  age         Int
}

Runtime added decorators

Implemented via:

Additional decorators for Prisma schema resolvers

Currently this is the only way for library consumers to extend the CRUD behaviour, in the current state it only lets consumers to add decorators to CRUD resolver methods.

Advantages and disadvantages

DRY

schema.prisma extension system

Everything would be located in the same config file (schema.prisma), no need to maintain multiple config files to configure the DB schema + CRUD behaviour, one with prisma + TypeGraphQL and other's with validation, auth etc, that would introduce one of the problems that prisma tries to eliminate at the ORM level, this proposal tries to solve all the burden for the 90% of the code that usually is for the CRUD's sake, and would let the consumer with only a master schema.prisma to handle that 90% of code for them, and only implement the reimaining 10% for the bussiness specific logic without lossing control over the CRUD bussiness integration, but at the same time the CRUD would not be in the way of the bussiness custom logic.

This would let with a quick look at the schema.prisma see everything related to the CRUD. And moving all CRUD related behaviour and configuration to the same step would remove the syncronization problem introduced by clasic ORM's (See Drawbacks of ORMs, point 2, by prisma), if multiple config files exist at multiple stages that would introduce the syncronization problem where your schema.prisma changed, now you have to go to all your configs that work on top of that result to handle the schema changes downstream.

Code coverage & analysis

An implementation working on top of schema.prisma could be also handled at some basic level from within the runtime capabilities of the runtime added decorators if functionality is added to add decorators for fields, but this way the posible plugins for this system would be limited to mostly decorators and would lose customization over the generated CRUD at a code level.

Having that 90% of the code be generated with all the required structure to handle the bussiness integration would open the option to get code coverage to all the CRUD + bussiness rules, this way bussiness problems like wanting to enforce that all the exposed CRUD have Auth guards, or that all fields have some form of validation could be resolved with current code coverage tools in the market.

Debugging & ejecting

Let's say you want to add a new decorator to some models, let's imagine that a plugin system working on top of runtime added decorators exists. You add the config options to the required files, start your project and... Its not working, wellcome to debugging madness, you have a config file with your wanted configuration, some code for your decorators but somewhere in the black box there had been a problem. You have a CRUD + TypeGraphQL generated code, a black box that adds your stuff in memory and then your app code, have fun going step by step with the debugger until you catch the problem between the generated code and your code.

Now, lets imagine the other case, you are working in your special decorator, you add the plugin to the list of plugins to be loaded by typegraphql-prisma, add the corresponding doc lines to schema.prisma and generate code... The generator finishes, you try your app with the new decorated CRUD, and its not working? Wellcome to debugging land! But now you have complete control over the generated code and even better, you can see exactly what is happening in the generated code, a quick look at the generated code would get a quick answer about why its not working, making your changes to the generated code and then implementing them back to your plugin, because at the end of the day its not more than code for your eyes to see and the plugin is just writing it for you in an automated, predictable way.

This also lets the user with the option to eject from the typegraphql-prisma generator, if somehow it has a really weird bussiness case where that 90% of code would need to be manually modified at any point the user can stop using the generator, all the code is there for him to be modified as he wish, included the business rules.

can we support baisc type in update?

for example, this is generated update args

export declare class AccountSecretUpdateWithoutUserInput { id?: IntFieldUpdateOperationsInput | undefined; phone?: NullableStringFieldUpdateOperationsInput | undefined; }
when we use this to update , we must write
{ phone: { set: $phone } }

can we support this in mutation(update):
`
export declare class AccountSecretUpdateWithoutUserInput {
id?: IntFieldUpdateOperationsInput | number | undefined;
phone?: NullableStringFieldUpdateOperationsInput | string | undefined;
}

{ phone: $phone }
`

multiple identical compound unique fields with different types not generating multiple types

I've got 2 models with the following structure, both use the same unique field mapping on type and token, but use different enum types. There is only 1 type generated for these compounded fields (or the other is overridden), but it's causing typescript to complain when querying via the compounded unique fields since the types are incorrect.

model Token {
  id         String    @id @default(cuid())
  type       TokenType
  token      String
  created_at DateTime  @default(now())
  updated_at DateTime  @updatedAt

  @@unique([type, token])
}

model UserCredential {
  id         String         @id @default(cuid())
  type       CredentialType
  token      String         @unique
  created_at DateTime       @default(now())
  updated_at DateTime       @updatedAt

  user    User   @relation(fields: [user_id], references: [id])
  user_id String

  @@unique([type, token])
}

Generated Type

  export type TypeTokenCompoundUniqueInput = {
    type: CredentialType
    token: string
  }

Authorization on generated resolvers

First off, I love this library and how seamlessly it works with Prisma!

I'm finding myself needing to basically re-implement resolvers that have been generated with npx prisma generate because I need to add some additional Authorization to them. The TypeGraphQL documentation lists how I could go about adding authorization on custom resolvers, but is there a way to do it for resolers that TypeGraphQL-Prisma generates? Otherwise, I'd need to basically reimplement resolvers for things that I want to restrict access to.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.