MichalLytek / typegraphql-prisma

Prisma generator to emit TypeGraphQL types and CRUD resolvers from your Prisma schema
https://prisma.typegraphql.com
MIT License
885 stars 114 forks source link

Update scalar list error with set #463

Open naccio8 opened 1 month ago

naccio8 commented 1 month ago

Bug description

I nees to update a scalar list nested into object on mongodb. The generated script made this query

import { PrismaClient as PrismaMongo } from "../prisma/generated/mongo";
const prismaMongo = new PrismaMongo();
prismaMongo.ready.update({
  "where": {
    "id": 1494260
  },
  "data": {
    "appointment": {
      "set": {
        "fascia_oraria": {
          "set": [
            "07:00",
            "18:00"
          ]
        }
      }
    }
  }
}).then((data) => {
  console.log('success',data);
} ).catch((error) => {
  console.log('error',error);
});

and generate this error

Failed to convert 'Object([("set", List([String("07:00"), String("18:00")]))])' to 'String

It work if I remove "set" in fascia_oraria and give the array directly:

"fascia_oraria": [
    "07:00",
    "18:00"
  ]

but the original query that was made by typegraphql-prisma required in graphql schema the second set and if I remove it the query failed in graphql. The problem is that if the object to set is nested in another it should not require the second set.

How to reproduce

run the script

Expected behavior

No response

Prisma information

prisma.schema

generator client {
  provider           = "prisma-client-js"
  output             = "../generated/mongo"
  emitTranspiledCode = "true"
}

generator typegraphql {
  provider               = "typegraphql-prisma"
  output                 = "../generated/mongo-ts"
  customPrismaImportPath = "../mongo"
  contextPrismaKey       = "mongo"
  simpleResolvers        = "true"
}

datasource db {
  provider = "mongodb"
  url      = env("MONGODB_CONN")
}

type Appointment {
  fascia_oraria String[]
}

model ready {
  id                Int                    @id @map("_id")
  appointment       Appointment?
}

test.ts

import { PrismaClient as PrismaMongo } from "../prisma/generated/mongo";
const prismaMongo = new PrismaMongo();
prismaMongo.ready.update({
  "where": {
    "id": 1494260
  },
  "data": {
    "appointment": {
      "set": {
        "fascia_oraria": {
          "set": [
            "07:00",
            "18:00"
          ]
        }
      }
    }
  }
}).then((data) => {
  console.log('success',data);
} ).catch((error) => {
  console.log('error',error);
});

Environment & setup

Prisma Version

{
"dependencies": {
    "@prisma/client": "^5.18.0",
  },
  "devDependencies": {
    "@types/node": "^20.12.10",
    "prisma": "^5.18.0",
    "typegraphql-prisma": "^0.28.0",
    "typescript": "^5.4.5"
  }
}
naccio8 commented 1 month ago

I temporarily fixed it with a prisma extension

import { Prisma } from '@prisma/client'
function removeNestedSet(obj: any): any {
  if (typeof obj !== 'object' || obj === null) {
    return obj;
  }

  if (Array.isArray(obj)) {
    return obj.map(removeNestedSet);
  }

  const result: any = {};
  for (const [key, value] of Object.entries(obj)) {
    if (typeof value === 'object' && value !== null) {
      if ('set' in value && Object.keys(value).length === 1) {
        result[key] = removeNestedSet(value.set);
      } else {
        result[key] = removeNestedSet(value);
      }
    } else {
      result[key] = value;
    }
  }
  return result;
}

export const removeNestedSetExtension = Prisma.defineExtension((client) => {
  return client.$extends({
    query: {
      $allModels: {
        async $allOperations({ args, query }) {
          const cleanedArgs = removeNestedSet(args);
          return query(cleanedArgs);
        },
      },
    },
  });
});

const prismaMongo = new PrismaMongo().$extends(removeNestedSetExtension);