MichalLytek / typegraphql-prisma

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

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

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error: Schema must contain uniquely named types but contains multiple types named "JSON"

valerii15298 opened this issue · comments

Describe the Bug
In project which uses ES Modules we cannot use JSONResolver from graphql-scalars package because of the error:
Error: Schema must contain uniquely named types but contains multiple types named "JSON"

To Reproduce
Here is a very small repro repository
Also check please commonjs branch on the repo where it is working using commonjs instead of esm.

Code from repo for quick look
index.ts:

import "reflect-metadata";
import { buildSchema, FieldResolver, Resolver } from "type-graphql";
import path from "path";
import { Prisma } from "@prisma/client";

import { resolvers, User } from "@generated/type-graphql";
import { JSONResolver } from "graphql-scalars";

import * as url from "url";
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));

@Resolver((_of) => User)
class CustomResolver {
  @FieldResolver((_type) => JSONResolver, {
    nullable: true,
  })
  async data(): Promise<Prisma.JsonValue[]> {
    return ["1", "2", "3"];
  }
}

buildSchema({
  resolvers: [...resolvers, CustomResolver],
  emitSchemaFile: path.resolve(__dirname, "./generated-schema.graphql"),
  validate: false,
});

schema.prisma:

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

generator typegraphql {
  provider = "typegraphql-prisma"
}

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

model User {
  id   Int  @id
  json Json
}

Expected Behavior
Emiting schema should work the same way as it works when using commonjs(look above for branch where it works)

Logs

> ts-node --esm --transpile-only ./index.ts

C:\Users\valer\OneDrive\Desktop\projects\testrepo\node_modules\.pnpm\graphql@15.8.0\node_modules\graphql\type\schema.js:194
        throw new Error("Schema must contain uniquely named types but contains multiple types named \"".concat(typeName, "\"."));    
              ^
Error: Schema must contain uniquely named types but contains multiple types named "JSON".
    at new GraphQLSchema (C:\Users\valer\OneDrive\Desktop\projects\testrepo\node_modules\.pnpm\graphql@15.8.0\node_modules\graphql\type\schema.js:194:15)
    at Function.generateFromMetadataSync (C:\Users\valer\OneDrive\Desktop\projects\testrepo\node_modules\.pnpm\type-graphql@1.1.1_yxlhq5elwzdhphazhcbwh6wmlq\node_modules\type-graphql\dist\schema\schema-generator.js:31:32)
    at Function.generateFromMetadata (C:\Users\valer\OneDrive\Desktop\projects\testrepo\node_modules\.pnpm\type-graphql@1.1.1_yxlhq5elwzdhphazhcbwh6wmlq\node_modules\type-graphql\dist\schema\schema-generator.js:16:29)
    at buildSchema (C:\Users\valer\OneDrive\Desktop\projects\testrepo\node_modules\.pnpm\type-graphql@1.1.1_yxlhq5elwzdhphazhcbwh6wmlq\node_modules\type-graphql\dist\utils\buildSchema.js:10:61)
    at file:///C:/Users/valer/OneDrive/Desktop/projects/testrepo/index.ts:22:1
    at ModuleJob.run (node:internal/modules/esm/module_job:193:25)
 ELIFECYCLE  Command failed with exit code 1.
 ELIFECYCLE  Command failed with exit code 1.

Environment (please complete the following information):

  • OS: Windows 11
  • Node 19.7.0
  • typegraphql-prisma version 0.24.4
  • Prisma version 4.11.0
  • TypeScript version 4.9.4

It's because of graphql-scalars being distributes as multi-target package, containing both esm and cjs code.
Since they live in different folders, node thinks they are different packages, thus importing them twice - once by TypeGraphQL-Prisma in generated code, second by your main graphql server project code.

Does your solution fixe the problem?
#370 (comment)

Wow. Thanks, that is really reasonable.
If you check the reproduction repo(package.json) you can see that I am already using my solution. And it does not fix the problem. Generated files use commonjs version of graphql-scalars and my code uses esm version as you said.
But at least now I understand why it is working like that.
I have an idea to import commonjs version of graphql-scalars in my esm code so it most likely will solve the problem.
But anyway i just give up to move my codebase to ESM. Seems nest.js world is not quite ready for it yet: nestjs/nest#8736
I will just use dynamic import for esm only packages for my project. This ESM stuff brings more headaches then it solves, seems for me. Maybe you agree on that @MichalLytek . Also adding .js extension everywhere not very beautiful.
Thank you very much @MichalLytek
Should I leave this issue open?

I will close this and open a one to properly support esm modules for generated resolvers (package.json, .js in paths, compile target, etc.)

@MichalLytek in case it will be helpful the idea of importing commonjs version of graphql-scalars really did work:
instead of

import { JSONResolver } from "graphql-scalars";

just use

import Module from "node:module";
const require = Module.createRequire(import.meta.url);
const { JSONResolver } = require("graphql-scalars");

And everything will work as expected.
Here is commit to the reproduction repository:
valerii15298/typegraphql-prisma-esm@a132407

still facing this issue

@mayur-2345 what exactly is the problem? Can you describe more precise or create new issue?

Doesn't suggested above workaround(using require in esm project) work for you?

  const schema = await tq.buildSchema({
    resolvers: [...resolvers, ...customResolvers.resolvers],
    skipCheck: false,
  });

it is failing over here

@mayur-2345 i suggest you include more description.
Did you read my question?
Do you use graphql-scalars? If so then how do you import it?

Btw, creating new issue with zero description doesn't make any sense... In order for someone to help, you need to include as much related information as possible, ideally creating reproduction on separate repo or in StackBlitz

https://stackblitz.com/edit/stackblitz-starters-iemvfw?file=index.ts

I have just replicated a quick demo on how we use it in our solution.
you can see the package.json and main index.ts file

graphql-scalars is present in not present package.json

it gives error on line number 71

@mayur-2345 by StackBlitz example I meant minimal reproducible example, not one file that contains also lot of unrelated/unneeded stuff

Issue was I was importing

import GraphQLJSON from 'graphql-type-json';

it should be

import { GraphQLJSON } from 'graphql-scalars';

updating thread so that others don't face the same issue I was facing.