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
version0.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.