paljs / prisma-tools

Prisma tools to help you generate CRUD system for GraphQL servers
https://paljs.com
MIT License
684 stars 54 forks source link

Question about generated update input types from SDLInputs() #136

Closed pakatagoh closed 3 years ago

pakatagoh commented 3 years ago

Hi!

My team and I are currently upgrading from prisma1 to prisma2. We are making use of pal g to help generate graphql type definitions to replace the ones generated previously by prisma1.

We are having issues with the generated UpdateInput graphql input types

A example model in our schema.prisma file below:

model Project {
  id                 String            @id @default(cuid())
  projectName        String
  projectDescription String
  shortDescription   String

paljs generated below

type Mutation {
  # example update mutation
  updateOneProject(where: ProjectWhereUniqueInput!, data: ProjectUpdateInput!): Project!
}

input ProjectUpdateInput {
  id: StringFieldUpdateOperationsInput
  projectName: StringFieldUpdateOperationsInput
  projectDescription: StringFieldUpdateOperationsInput
  shortDescription: StringFieldUpdateOperationsInput
}

input StringFieldUpdateOperationsInput {
  set: String
}

# other definitions...

prisma1 generated below:

input ProjectUpdateInput {
  projectName: String
  projectDescription: String
  shortDescription: String
}

using the graphql types by paljs, we are now required to always use a set even for scalar or enum types.

But the prisma2 typescript definitions do allow for writing either just the string to update or with the help of a nested set property

prisma2 typescript definition from .prisma/client/index.d.ts below:

export type ProjectUpdateInput = {
  id?: string | StringFieldUpdateOperationsInput
  projectName?: string | StringFieldUpdateOperationsInput
  projectDescription?: string | StringFieldUpdateOperationsInput
  shortDescription?: string | StringFieldUpdateOperationsInput
}

export type StringFieldUpdateOperationsInput = {
  set?: string
}

so this requires us to change lots of update mutations that weren't using set on the frontend.

Just wondering if there is a way to add a config to not use xxxxFieldUpdateOperationsInput by default?

Maybe you could also shed some light as to why xxxxFieldUpdateOperationsInput was chosen when generating sdlInputs. That'll be awesome.

Our current workaround is making a change to the source sdlInputs.ts file to detect if the type includes FieldUpdateOperationsInput

export const getInputType = (field: DMMF.SchemaArg) => {
  let index: number = 0;

  // new code below
  if (field.inputTypes.length > 1 && field.inputTypes[1].type.includes('FieldUpdateOperationsInput') ) {
    index = 0;
    return field.inputTypes[index]
  }
  // new code above

  if (field.inputTypes.length > 1 && field.inputTypes[1].kind === 'object') {
    index = 1;
  }
  return field.inputTypes[index];
};

Thank you!

our pal.js config below if you're wondering about it

module.exports = {
  backend: {
    generator: 'sdl',
    output: 'gql/src/typedefs',
};
AhmedElywa commented 3 years ago

Why we use Object not string type? Because the Number fields have many options like:

from prisma release notes https://github.com/prisma/prisma/releases/tag/2.6.0

We are introducing five atomic operations for Int and Float 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 })

And Also for Json fields must with set

In the end, I can add an option for you to pass into SDLInputs() function

pakatagoh commented 3 years ago

Thanks for info!

and yes if there could be some kind of flag in the paljs config that we could use together with generator:'sdl' so that sdlInputs() will not choose the types that require setand it'll be more "prisma1-friendly"

I guess it could look something like the following?

// pal.js config
module.exports = {
  backend: {
    generator: 'sdl',
    output: 'gql/src/typedefs',
    doNotuseFieldUpdateOperationsInput: true // defaults to false.  This is just a suggestion. I'm not sure what would be a good name or a good place to indicate this flag
};

Will probably have to indicate in the documentation that this will not generate graphql type defs that support prisma2.6 and above.

AhmedElywa commented 3 years ago

Can you tell me if you using my generator with Javascript or Typescript?

pakatagoh commented 3 years ago

Can you tell me if you using my generator with Javascript or Typescript?

we are using typescript 👍🏻