diff --git a/docs/tutorials/graphql-typegraphql.md b/docs/tutorials/graphql-typegraphql.md index 2b80af30119..07cb28f29e4 100644 --- a/docs/tutorials/graphql-typegraphql.md +++ b/docs/tutorials/graphql-typegraphql.md @@ -47,22 +47,18 @@ import "@tsed/typegraphql"; import "./resolvers/index"; // barrel file with all resolvers @Configuration({ - typegraphql: { + apollo: { server1: { // GraphQL server configuration + // See options descriptions on https://www.apollographql.com/docs/apollo-server/api/apollo-server.html path: "/", - playground: true, // enable playground GraphQL IDE. Set false to use Apollo Studio + playground: true // enable playground GraphQL IDE. Set false to use Apollo Studio // resolvers?: (Function | string)[]; // dataSources?: Function; // server?: (config: Config) => ApolloServer; - // Apollo Server options - // See options descriptions on https://www.apollographql.com/docs/apollo-server/api/apollo-server.html - serverConfig: { - plugins: [] - } - + // plugins: [] // middlewareOptions?: ServerRegistration; // type-graphql diff --git a/docs/tutorials/graphql-ws.md b/docs/tutorials/graphql-ws.md index 633662c3bff..922def2ee3d 100644 --- a/docs/tutorials/graphql-ws.md +++ b/docs/tutorials/graphql-ws.md @@ -43,7 +43,7 @@ yarn add @tsed/graphql-ws graphql-ws import {Configuration} from "@tsed/common"; import "@tsed/platform-express"; import "@tsed/apollo"; -import "@tsed/graphql-ws"; +import "@tsed/graphql-ws"; // auto import plugin for @tsed/apollo import {join} from "path"; @Configuration({ @@ -82,122 +82,49 @@ import {join} from "path"; export class Server {} ``` -## Register plugins +## The PubSub class -You can register plugins with the `plugins` property. The plugins are executed in the order of declaration. - -```typescript -import {Configuration} from "@tsed/common"; -import "@tsed/platform-express"; -import "@tsed/apollo"; -import {join} from "path"; - -@Configuration({ - apollo: { - server1: { - plugins: [] // Apollo plugins - } - } -}) -export class Server {} -``` - -But if you need to register and access to the injector, you can use the `$alterApolloServerPlugins` hook. For example, -you can register the `graphql-ws` necessary to support the `subscription` feature of GraphQL like this: - -```typescript -import {Constant, Inject, InjectorService, Module} from "@tsed/di"; -import {useServer} from "graphql-ws/lib/use/ws"; -import Http from "http"; -import Https from "https"; -import {WebSocketServer} from "ws"; -import {GraphQLWSOptions} from "./GraphQLWSOptions"; - -@Module() -export class GraphQLWSModule { - @Constant("graphqlWs", {}) - private settings: GraphQLWSOptions; - - @Inject(Http.Server) - private httpServer: Http.Server | null; - - @Inject(Https.Server) - private httpsServer: Https.Server | null; - - @Inject() - private injector: InjectorService; - - createWSServer(settings: GraphQLWSOptions) { - const wsServer = new WebSocketServer({ - ...(this.settings.wsServerOptions || {}), - ...settings.wsServerOptions, - server: this.httpsServer || this.httpServer!, - path: settings.path - }); - - return useServer( - { - ...(this.settings.wsUseServerOptions || {}), - ...settings.wsUseServerOptions, - schema: settings.schema - }, - wsServer - ); - } +::: warning +The PubSub class is not recommended for production environments, because it's an in-memory event system that only supports a single server instance. After you get subscriptions working in development, we strongly recommend switching it out for a different subclass of the abstract [PubSubEngine](https://github.com/apollographql/graphql-subscriptions/blob/master/src/pubsub-engine.ts) +class. Recommended subclasses are listed in [Production PubSub libraries](https://www.apollographql.com/docs/apollo-server/data/subscriptions/#production-pubsub-libraries). +::: - async $alterApolloServerPlugins(plugins: any[], settings: GraphQLWSOptions) { - const wsServer = await this.createWSServer(settings); +You can use the publish-subscribe (pub/sub) model to track events that update active subscriptions. +The graphql-subscriptions library provides the PubSub class as a basic in-memory event bus to help you get started: - this.injector.logger.info(`Create GraphQL WS server on: ${settings.path}`); +To use the graphql-subscriptions package, first install it like so: - return plugins.concat({ - serverWillStart() { - return { - async drainServer() { - await wsServer.dispose(); - } - }; - } - } as any); - } -} +```shell +npm install graphql-subscriptions ``` -::: tip Note -Ts.ED provide a `@tsed/graphql-ws` package to support the `subscription` feature of GraphQL. See [here](https://tsed.io/api/graphql-ws.html) for more details. -::: - -## Nexus - -### Installation +A `PubSub` instance enables your server code to both `publish` events to a particular label and listen for events associated with a particular label. +We can create a `PubSub` instance like so: - - - -```bash -npm install --save @tsed/apollo @apollo/server nexus graphql -npm install --save-dev apollo-server-testing -``` +```typescript +import {PubSub} from "graphql-subscriptions"; +import {registerProvider} from "@tsed/di"; - - +export const pubsub = new PubSub(); +export const PubSubProvider = Symbol.for("PubSubProvider"); +export type PubSubProvider = PubSub; -```bash -npm install --save @tsed/apollo graphql nexus @apollo/server @as-integration/koa -npm install --save-dev apollo-server-testing +registerProvider({provide: PubSub, useValue: pubsub}); ``` - - +Depending on the schema resolver (nexus, type-graphql, etc.), you can use the `pubsub` instance to publish events and subscribe to them in your resolvers. -Now, we can configure the Ts.ED server by importing `@tsed/apollo` in your Server: +::: warning +To use the subscription feature with TypeGraphQL, you have to give pubsub instance to the buildSchemaOptions: ```typescript import {Configuration} from "@tsed/common"; import "@tsed/platform-express"; import "@tsed/apollo"; -import {schema} from "./schema"; +import "@tsed/typegraphql"; +import "@tsed/graphql-ws"; // auto import plugin for @tsed/apollo import {join} from "path"; +import {pubsub} from "./pubsub/pubsub"; @Configuration({ apollo: { @@ -205,210 +132,84 @@ import {join} from "path"; // GraphQL server configuration path: "/", playground: true, // enable playground GraphQL IDE. Set false to use Apollo Studio - schema, - plugins: [] // Apollo plugins - - // Give custom server instance - // server?: (config: Config) => ApolloServer; - - // ApolloServer options - // ... - // See options descriptions on https://www.apollographql.com/docs/apollo-server/api/apollo-server.html + plugins: [], // Apollo plugins + buildSchemaOptions: { + pubsub + } + } + }, + graphqlWs: { + // global options + wsServerOptions: { + // See options descriptions on + }, + wsUseServerOptions: { + // See options descriptions on } } }) export class Server {} ``` -Then create `schema/index.ts`: - -```typescript -import {makeSchema} from "nexus"; -import {join} from "path"; - -export const schema = makeSchema({ - types: [], // 1 - outputs: { - typegen: join(process.cwd(), "..", "..", "nexus-typegen.ts"), // 2 - schema: join(process.cwd(), "..", "..", "schema.graphql") // 3 - } -}); -``` - -## TypeGraphQL - -### Installation - -To begin, install the `@tsed/typegraphql` package: - - - - -```bash -npm install --save @tsed/typegraphql @apollo/server graphql type-graphql @apollo/datasource-rest -npm install --save-dev apollo-server-testing -``` - - - - -```bash -npm install --save @tsed/typegraphql @apollo/server graphql type-graphql @as-integration/koa @apollo/datasource-rest -npm install --save-dev apollo-server-testing -``` - - - - -Now, we can configure the Ts.ED server by importing `@tsed/typegraphql` in your Server: - - - - -<<< @/tutorials/snippets/graphql/server-configuration.ts - - - - - - - - - -### Types - -We want to get the equivalent of this type described in SDL: - -``` -type Recipe { - id: ID! - title: String! - description: String - creationDate: Date! - ingredients: [String!]! -} -``` - -So we create the Recipe class with all properties and types: +Here is a simple example of how to use the `pubsub` instance in a resolver using the `type-graphql` library: ```typescript -class Recipe { - id: string; - title: string; - description?: string; - creationDate: Date; - ingredients: string[]; -} -``` - -Then we decorate the class and its properties with decorators: +import {InjectContext, PlatformContext} from "@tsed/common"; +import {Inject} from "@tsed/di"; +import {ResolverController} from "@tsed/typegraphql"; +import {Arg, Mutation, Query, Root, Subscription} from "type-graphql"; +import {RecipeService} from "../../services/RecipeService"; +import {PubSubProvider} from "../pubsub/pubsub.js"; +import {Recipe, RecipeNotification} from "./Recipe"; +import {RecipeNotFoundError} from "./RecipeNotFoundError"; + +@ResolverController((_of) => Recipe) +export class RecipeResolver { + @InjectContext() + private $ctx: PlatformContext; -<<< @/tutorials/snippets/graphql/recipe-type.ts + @Inject() + private recipeService: RecipeService; -The detailed rules for when to use nullable, array and others are described -in [fields and types docs](https://typegraphql.com/docs/types-and-fields.html). + @Inject(PubSubProvider) + private pubSub: PubSubProvider; -### Resolvers + @Query((returns) => Recipe) + async recipe(@Arg("id") id: string) { + const recipe = await this.recipeService.findById(id); -After that we want to create typical crud queries and mutation. To do that we create the resolver (controller) class -that will have injected RecipeService in the constructor: + if (recipe === undefined) { + throw new RecipeNotFoundError(id); + } -<<< @/tutorials/snippets/graphql/resolver-service.ts + return recipe; + } -#### Multiple GraphQL server + @Query((returns) => [Recipe], {description: "Get all the recipes from around the world "}) + recipes(): Promise { + this.$ctx.set("test", "test"); + return this.recipeService.findAll({}); + } -If you register multiple GraphQL servers, you must specify the server id in the `@ResolverController` decorator. + @Mutation((returns) => Recipe) + async addRecipe(@Arg("title") title: string, @Arg("description") description: string) { + const payload = await this.recipeService.create({title, description}); + const notification = new RecipeNotification(payload); -```typescript -@ResolverController(Recipe, {id: "server1"}) -``` + this.pubSub.publish("NOTIFICATIONS", notification); -Another solution is to not use `@ResolverController` (use `@Resolver` from TypeGraphQL), and declare explicitly the resolver in the server configuration: + return payload; + } -```typescript -@Configuration({ - graphql: { - server1: { - resolvers: { - RecipeResolver - } - }, - server2: { - resolvers: { - OtherResolver - } - } + @Subscription(() => RecipeNotification, { + topics: "RECIPE_ADDED" + }) + newRecipe(@Root() payload: Recipe): RecipeNotification { + return {...payload, date: new Date()}; } -}) +} ``` -### Data Source - -Data source is one of the Apollo server features which can be used as option for your Resolver or Query. Ts.ED provides -a @@DataSourceService@@ decorator to declare a DataSource which will be injected to the Apollo server context. - -<<< @/tutorials/snippets/graphql/datasource-service.ts - -Then you can retrieve your data source through the context in your resolver like that: - -<<< @/tutorials/snippets/graphql/resolver-data-source.ts - -## Get Server instance - -ApolloService (or TypeGraphQLService) lets you to retrieve an instance of ApolloServer. - -<<< @/tutorials/snippets/graphql/get-server-instance.ts - -For more information about ApolloServer, look at its -documentation [here](https://www.apollographql.com/docs/apollo-server/api/apollo-server.html); - -## Testing - -Here is an example to create a test server based on TypeGraphQL and run a query: - -::: tip - -The unit example is also available to test any Apollo Server! -::: - - - - -<<< @/tutorials/snippets/graphql/testing.jest.ts - - - - -<<< @/tutorials/snippets/graphql/testing.mocha.ts - - - - -<<< @/tutorials/snippets/graphql/resolver-service.ts - - - - -<<< @/tutorials/snippets/graphql/recipes-service.ts - - - - -<<< @/tutorials/snippets/graphql/recipe-type.ts - - - - -<<< @/tutorials/snippets/graphql/recipe-args.ts - - - - ## Author diff --git a/packages/graphql/apollo/package.json b/packages/graphql/apollo/package.json index 7a5373289b7..00eb6cb2b36 100644 --- a/packages/graphql/apollo/package.json +++ b/packages/graphql/apollo/package.json @@ -34,8 +34,7 @@ "apollo-datasource-http": "0.21.0", "apollo-server-testing": "2.25.3", "eslint": "^8.57.0", - "graphql": "15.8.0", - "graphql-scalar": "0.1.0", + "graphql": "16.8.2", "jest": "^29.7.0", "typescript": "5.4.5" }, @@ -47,6 +46,6 @@ "@tsed/core": "7.72.0", "@tsed/di": "7.72.0", "@tsed/logger": ">=6.7.5", - "graphql": ">15.0.0" + "graphql": ">16.0.0" } } diff --git a/packages/graphql/apollo/src/ApolloModule.ts b/packages/graphql/apollo/src/ApolloModule.ts index 1e4241fb786..1436f7a9d5e 100644 --- a/packages/graphql/apollo/src/ApolloModule.ts +++ b/packages/graphql/apollo/src/ApolloModule.ts @@ -41,7 +41,7 @@ export class ApolloModule implements OnRoutesInit, AfterListen { const displayLog = (key: string, path: string) => { const url = typeof host.port === "number" ? `${host.protocol}://${host.address}:${host.port}` : ""; - this.logger.info(`[${key}] Apollo server is available on ${url}${path.replace(/^\//, "")}`); + this.logger.info(`[${key}] Apollo server is available on ${url}/${path.replace(/^\//, "")}`); }; const {settings} = this; diff --git a/packages/graphql/typegraphql/jest.config.js b/packages/graphql/typegraphql/jest.config.js index c7e2192722f..98e1ff61825 100644 --- a/packages/graphql/typegraphql/jest.config.js +++ b/packages/graphql/typegraphql/jest.config.js @@ -11,10 +11,10 @@ module.exports = { }, coverageThreshold: { global: { - statements: 96.92, + statements: 96.89, branches: 66.6, functions: 87.5, - lines: 96.92 + lines: 96.89 } } }; diff --git a/packages/graphql/typegraphql/package.json b/packages/graphql/typegraphql/package.json index 1382611e103..e3e2e330899 100644 --- a/packages/graphql/typegraphql/package.json +++ b/packages/graphql/typegraphql/package.json @@ -25,6 +25,7 @@ "tslib": "2.6.1" }, "devDependencies": { + "@graphql-yoga/subscription": "5.0.0", "@tsed/barrels": "workspace:*", "@tsed/common": "workspace:*", "@tsed/core": "workspace:*", @@ -34,16 +35,18 @@ "class-validator": "~0.14.1", "cross-env": "^7.0.3", "eslint": "^8.57.0", - "graphql": "15.8.0", + "graphql": "16.8.2", "graphql-passport": "^0.6.8", + "graphql-scalars": "1.23.0", "jest": "^29.7.0", "ts-node": "10.9.2", - "type-graphql": "1.1.1" + "type-graphql": ">=2.0.0-rc.2" }, "peerDependencies": { "@apollo/datasource-rest": ">=6.2.2", "class-validator": ">=0.13.1", - "graphql": ">=15.0.0", - "type-graphql": ">=2.0.0-rc.1" + "graphql": ">=16.0.0", + "graphql-scalars": ">=1.23.0", + "type-graphql": ">=2.0.0-rc.2" } } diff --git a/packages/graphql/typegraphql/src/decorators/resolver.ts b/packages/graphql/typegraphql/src/decorators/resolver.ts index 8e32f394155..8ef885f2815 100644 --- a/packages/graphql/typegraphql/src/decorators/resolver.ts +++ b/packages/graphql/typegraphql/src/decorators/resolver.ts @@ -1,16 +1,15 @@ import {StoreSet, useDecorators} from "@tsed/core"; import {Injectable} from "@tsed/di"; import {ClassType, Resolver} from "type-graphql"; -import {AbstractClassOptions, ClassTypeResolver} from "type-graphql/dist/decorators/types"; import {RESOLVERS_PROVIDERS} from "../constants/constants.js"; -export interface ResolverControllerOptions extends AbstractClassOptions { +export interface ResolverControllerOptions { id?: string; } -export function ResolverController(path?: string): ClassDecorator; -export function ResolverController(options: ResolverControllerOptions): ClassDecorator; -export function ResolverController(typeFunc: ClassTypeResolver, options?: ResolverControllerOptions): ClassDecorator; +export function ResolverController(): ClassDecorator; +export function ResolverController(path: string): ClassDecorator; +export function ResolverController(typeFunc: (of?: void) => ClassType | Function, options?: ResolverControllerOptions): ClassDecorator; export function ResolverController(objectType: ClassType, options?: ResolverControllerOptions): ClassDecorator; export function ResolverController(...args: any[]): ClassDecorator { let id = undefined; diff --git a/packages/graphql/typegraphql/test/app/Server.ts b/packages/graphql/typegraphql/test/app/Server.ts index ac6654e4920..10fe5fc4d2f 100644 --- a/packages/graphql/typegraphql/test/app/Server.ts +++ b/packages/graphql/typegraphql/test/app/Server.ts @@ -7,13 +7,14 @@ import "@tsed/typegraphql"; import * as fs from "fs"; import {buildContext} from "graphql-passport"; import {resolve} from "path"; -import {HelloController} from "./controllers/HelloController.js"; -import {User} from "./graphql/auth/User.js"; +import {HelloController} from "./controllers/HelloController"; +import {User} from "./graphql/auth/User"; import "./graphql/index"; -import {AuthResolver} from "./graphql/index.js"; +import {AuthResolver} from "./graphql/index"; import "./protocols/GraphQLProtocol"; import "./services/RecipeService"; import "./services/UsersRepository"; +import {pubSub} from "./graphql/pubsub/pubsub"; const rootDir = __dirname; // automatically replaced by import.meta.dirname on build @@ -37,7 +38,8 @@ const rootDir = __dirname; // automatically replaced by import.meta.dirname on b path: "/api/graphql", resolvers: [AuthResolver], buildSchemaOptions: { - emitSchemaFile: resolve(rootDir, "../resources/schema.gql") + emitSchemaFile: resolve(rootDir, "../resources/schema.gql"), + pubSub } } }, diff --git a/packages/graphql/typegraphql/test/app/graphql/auth/AuthResolver.ts b/packages/graphql/typegraphql/test/app/graphql/auth/AuthResolver.ts index 366d3cd23fe..53b78bbdf50 100644 --- a/packages/graphql/typegraphql/test/app/graphql/auth/AuthResolver.ts +++ b/packages/graphql/typegraphql/test/app/graphql/auth/AuthResolver.ts @@ -1,6 +1,6 @@ import {PassportContext} from "graphql-passport"; import {Arg, Ctx, Mutation, Query, Resolver} from "type-graphql"; -import {User} from "./User.js"; +import {User} from "./User"; export interface GQLContext extends PassportContext {} diff --git a/packages/graphql/typegraphql/test/app/graphql/index.ts b/packages/graphql/typegraphql/test/app/graphql/index.ts index 1a2efbd3e1e..718b4af4fd0 100644 --- a/packages/graphql/typegraphql/test/app/graphql/index.ts +++ b/packages/graphql/typegraphql/test/app/graphql/index.ts @@ -1,6 +1,6 @@ -export * from "./auth/AuthResolver.js"; -export * from "./auth/User.js"; -export * from "./datasources/MyDataSource.js"; -export * from "./recipes/Recipe.js"; -export * from "./recipes/RecipeResolver.js"; -export * from "./recipes/RecipeNotFoundError.js"; +export * from "./auth/AuthResolver"; +export * from "./auth/User"; +export * from "./datasources/MyDataSource"; +export * from "./recipes/Recipe"; +export * from "./recipes/RecipeResolver"; +export * from "./recipes/RecipeNotFoundError"; diff --git a/packages/graphql/typegraphql/test/app/graphql/pubsub/pubsub.ts b/packages/graphql/typegraphql/test/app/graphql/pubsub/pubsub.ts new file mode 100644 index 00000000000..f431692e421 --- /dev/null +++ b/packages/graphql/typegraphql/test/app/graphql/pubsub/pubsub.ts @@ -0,0 +1,15 @@ +import {createPubSub} from "@graphql-yoga/subscription"; +import {registerProvider} from "@tsed/common"; +import {RecipeNotification} from "../recipes/Recipe"; + +export const pubSub = createPubSub<{ + NOTIFICATIONS: [RecipeNotification]; +}>(); + +export const PubSubProvider = Symbol.for("PubSubProvider"); +export type PubSubProvider = typeof pubSub; + +registerProvider({ + provide: PubSubProvider, + useValue: pubSub +}); diff --git a/packages/graphql/typegraphql/test/app/graphql/recipes/RecipeResolver.ts b/packages/graphql/typegraphql/test/app/graphql/recipes/RecipeResolver.ts index 095bdad683d..2cc5b3d00e1 100644 --- a/packages/graphql/typegraphql/test/app/graphql/recipes/RecipeResolver.ts +++ b/packages/graphql/typegraphql/test/app/graphql/recipes/RecipeResolver.ts @@ -1,10 +1,11 @@ import {InjectContext, PlatformContext} from "@tsed/common"; import {Inject} from "@tsed/di"; import {ResolverController} from "@tsed/typegraphql"; -import {Arg, Mutation, Publisher, PubSub, Query, Root, Subscription} from "type-graphql"; -import {RecipeService} from "../../services/RecipeService.js"; -import {Recipe, RecipeNotification} from "./Recipe.js"; -import {RecipeNotFoundError} from "./RecipeNotFoundError.js"; +import {Arg, Mutation, Query, Root, Subscription} from "type-graphql"; +import {RecipeService} from "../../services/RecipeService"; +import {PubSubProvider} from "../pubsub/pubsub.js"; +import {Recipe, RecipeNotification} from "./Recipe"; +import {RecipeNotFoundError} from "./RecipeNotFoundError"; @ResolverController((_of) => Recipe) export class RecipeResolver { @@ -14,6 +15,9 @@ export class RecipeResolver { @Inject() private recipeService: RecipeService; + @Inject(PubSubProvider) + private pubSub: PubSubProvider; + @Query((returns) => Recipe) async recipe(@Arg("id") id: string) { const recipe = await this.recipeService.findById(id); @@ -32,13 +36,11 @@ export class RecipeResolver { } @Mutation((returns) => Recipe) - async addRecipe( - @Arg("title") title: string, - @Arg("description") description: string, - @PubSub("NOTIFICATIONS") publish: Publisher - ) { + async addRecipe(@Arg("title") title: string, @Arg("description") description: string) { const payload = await this.recipeService.create({title, description}); - await publish(payload); + const notification = new RecipeNotification(payload); + + this.pubSub.publish("NOTIFICATIONS", notification); return payload; } diff --git a/packages/graphql/typegraphql/test/app/index.express.ts b/packages/graphql/typegraphql/test/app/index.express.ts index b10c5bdd06d..829493459a1 100644 --- a/packages/graphql/typegraphql/test/app/index.express.ts +++ b/packages/graphql/typegraphql/test/app/index.express.ts @@ -1,6 +1,6 @@ import {$log} from "@tsed/common"; import {PlatformExpress} from "@tsed/platform-express"; -import {Server} from "./Server.js"; +import {Server} from "./Server"; if (process.env.NODE_ENV !== "test") { async function bootstrap() { diff --git a/packages/graphql/typegraphql/test/app/protocols/GraphQLProtocol.ts b/packages/graphql/typegraphql/test/app/protocols/GraphQLProtocol.ts index 0f0a5264d26..bb75289e863 100644 --- a/packages/graphql/typegraphql/test/app/protocols/GraphQLProtocol.ts +++ b/packages/graphql/typegraphql/test/app/protocols/GraphQLProtocol.ts @@ -2,7 +2,7 @@ import {Inject, Req} from "@tsed/common"; import {Unauthorized} from "@tsed/exceptions"; import {Arg, OnVerify, Protocol} from "@tsed/passport"; import {GraphQLLocalStrategy} from "graphql-passport"; -import {UsersRepository} from "../services/UsersRepository.js"; +import {UsersRepository} from "../services/UsersRepository"; @Protocol({ name: "graphql-local", diff --git a/packages/graphql/typegraphql/test/app/services/RecipeService.ts b/packages/graphql/typegraphql/test/app/services/RecipeService.ts index 956232b995a..692576e3474 100644 --- a/packages/graphql/typegraphql/test/app/services/RecipeService.ts +++ b/packages/graphql/typegraphql/test/app/services/RecipeService.ts @@ -1,5 +1,5 @@ import {Service} from "@tsed/common"; -import {Recipe} from "../graphql/recipes/Recipe.js"; +import {Recipe} from "../graphql/recipes/Recipe"; @Service() export class RecipeService { diff --git a/packages/graphql/typegraphql/test/app/services/UsersRepository.ts b/packages/graphql/typegraphql/test/app/services/UsersRepository.ts index 3e8f0ecfbd2..d9c3c93fcc2 100644 --- a/packages/graphql/typegraphql/test/app/services/UsersRepository.ts +++ b/packages/graphql/typegraphql/test/app/services/UsersRepository.ts @@ -1,7 +1,7 @@ import {Adapter, InjectAdapter} from "@tsed/adapters"; import {Injectable} from "@tsed/di"; import {deserialize} from "@tsed/json-mapper"; -import {User} from "../graphql/auth/User.js"; +import {User} from "../graphql/auth/User"; @Injectable() export class UsersRepository { diff --git a/packages/graphql/typegraphql/test/resources/schema.gql b/packages/graphql/typegraphql/test/resources/schema.gql index f195019f5df..eb1a2683b53 100644 --- a/packages/graphql/typegraphql/test/resources/schema.gql +++ b/packages/graphql/typegraphql/test/resources/schema.gql @@ -4,9 +4,9 @@ # ----------------------------------------------- """ -The javascript `Date` as string. Type represents date and time as the ISO Date string. +A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar.This scalar is serialized to a string in ISO 8601 format and parsed from a string in ISO 8601 format. """ -scalar DateTime +scalar DateTimeISO type Mutation { addRecipe(description: String!, title: String!): Recipe! @@ -23,7 +23,7 @@ type Query { """Object representing cooking recipe""" type Recipe { - creationDate: DateTime! + creationDate: DateTimeISO! description: String id: ID! ingredients: [String!]! @@ -31,8 +31,8 @@ type Recipe { } type RecipeNotification { - creationDate: DateTime! - date: DateTime! + creationDate: DateTimeISO! + date: DateTimeISO! description: String id: ID! ingredients: [String!]! @@ -49,4 +49,4 @@ type User { emailVerified: Boolean! id: ID! password: String! -} +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 987afdc0ed1..93581d600d0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3455,6 +3455,28 @@ __metadata: languageName: node linkType: hard +"@graphql-yoga/subscription@npm:5.0.0, @graphql-yoga/subscription@npm:^5.0.0": + version: 5.0.0 + resolution: "@graphql-yoga/subscription@npm:5.0.0" + dependencies: + "@graphql-yoga/typed-event-target": "npm:^3.0.0" + "@repeaterjs/repeater": "npm:^3.0.4" + "@whatwg-node/events": "npm:^0.1.0" + tslib: "npm:^2.5.2" + checksum: 10/98dc97351b56a26a54d509a507432893298c0e004bc6161cce8d237351d0f65777af3c9ce268e1620860d22e4567469d4d93ee3adcc50d8cf24d924759546d20 + languageName: node + linkType: hard + +"@graphql-yoga/typed-event-target@npm:^3.0.0": + version: 3.0.0 + resolution: "@graphql-yoga/typed-event-target@npm:3.0.0" + dependencies: + "@repeaterjs/repeater": "npm:^3.0.4" + tslib: "npm:^2.5.2" + checksum: 10/0101e71658b519e935bcfc439f9a9db401d2ac17cacfa893a5cb15de947f1962ea84c3ebc89a88dc91f7f1030a758595c20903fa1d3b685c854723688f3a4a08 + languageName: node + linkType: hard + "@grpc/grpc-js@npm:~1.7.3": version: 1.7.3 resolution: "@grpc/grpc-js@npm:1.7.3" @@ -5257,6 +5279,13 @@ __metadata: languageName: node linkType: hard +"@repeaterjs/repeater@npm:^3.0.4": + version: 3.0.6 + resolution: "@repeaterjs/repeater@npm:3.0.6" + checksum: 10/25698e822847b776006428f31e2d31fbcb4faccf30c1c8d68d6e1308e58b49afb08764d1dd15536ddd67775cd01fd6c2fb22f039c05a71865448fbcfb2246af2 + languageName: node + linkType: hard + "@rollup/rollup-android-arm-eabi@npm:4.9.6": version: 4.9.6 resolution: "@rollup/rollup-android-arm-eabi@npm:4.9.6" @@ -6663,8 +6692,7 @@ __metadata: apollo-datasource-http: "npm:0.21.0" apollo-server-testing: "npm:2.25.3" eslint: "npm:^8.57.0" - graphql: "npm:15.8.0" - graphql-scalar: "npm:0.1.0" + graphql: "npm:16.8.2" jest: "npm:^29.7.0" tslib: "npm:2.6.1" typescript: "npm:5.4.5" @@ -6676,7 +6704,7 @@ __metadata: "@tsed/core": 7.72.0 "@tsed/di": 7.72.0 "@tsed/logger": ">=6.7.5" - graphql: ">15.0.0" + graphql: ">16.0.0" languageName: unknown linkType: soft @@ -8312,6 +8340,7 @@ __metadata: version: 0.0.0-use.local resolution: "@tsed/typegraphql@workspace:packages/graphql/typegraphql" dependencies: + "@graphql-yoga/subscription": "npm:5.0.0" "@tsed/apollo": "workspace:*" "@tsed/barrels": "workspace:*" "@tsed/common": "workspace:*" @@ -8322,17 +8351,19 @@ __metadata: class-validator: "npm:~0.14.1" cross-env: "npm:^7.0.3" eslint: "npm:^8.57.0" - graphql: "npm:15.8.0" + graphql: "npm:16.8.2" graphql-passport: "npm:^0.6.8" + graphql-scalars: "npm:1.23.0" jest: "npm:^29.7.0" ts-node: "npm:10.9.2" tslib: "npm:2.6.1" - type-graphql: "npm:1.1.1" + type-graphql: "npm:>=2.0.0-rc.2" peerDependencies: "@apollo/datasource-rest": ">=6.2.2" class-validator: ">=0.13.1" - graphql: ">=15.0.0" - type-graphql: ">=2.0.0-rc.1" + graphql: ">=16.0.0" + graphql-scalars: ">=1.23.0" + type-graphql: ">=2.0.0-rc.2" languageName: unknown linkType: soft @@ -8809,16 +8840,6 @@ __metadata: languageName: node linkType: hard -"@types/glob@npm:^7.1.3": - version: 7.2.0 - resolution: "@types/glob@npm:7.2.0" - dependencies: - "@types/minimatch": "npm:*" - "@types/node": "npm:*" - checksum: 10/6ae717fedfdfdad25f3d5a568323926c64f52ef35897bcac8aca8e19bc50c0bd84630bbd063e5d52078b2137d8e7d3c26eabebd1a2f03ff350fff8a91e79fc19 - languageName: node - linkType: hard - "@types/globby@npm:9.1.0": version: 9.1.0 resolution: "@types/globby@npm:9.1.0" @@ -9166,7 +9187,7 @@ __metadata: languageName: node linkType: hard -"@types/minimatch@npm:*, @types/minimatch@npm:^3.0.3": +"@types/minimatch@npm:^3.0.3": version: 3.0.5 resolution: "@types/minimatch@npm:3.0.5" checksum: 10/c41d136f67231c3131cf1d4ca0b06687f4a322918a3a5adddc87ce90ed9dbd175a3610adee36b106ae68c0b92c637c35e02b58c8a56c424f71d30993ea220b92 @@ -9377,20 +9398,13 @@ __metadata: languageName: node linkType: hard -"@types/semver@npm:^7.3.12, @types/semver@npm:^7.5.8": +"@types/semver@npm:^7.3.12, @types/semver@npm:^7.5.6, @types/semver@npm:^7.5.8": version: 7.5.8 resolution: "@types/semver@npm:7.5.8" checksum: 10/3496808818ddb36deabfe4974fd343a78101fa242c4690044ccdc3b95dcf8785b494f5d628f2f47f38a702f8db9c53c67f47d7818f2be1b79f2efb09692e1178 languageName: node linkType: hard -"@types/semver@npm:^7.3.3": - version: 7.3.9 - resolution: "@types/semver@npm:7.3.9" - checksum: 10/872d9689bed8bba950b9ad9ba4a61e9770f13d5dde93ab50db6aa7474593c5b50c766c95f1e0b31f75f06da5322fb217668b5b749f1759008ea6018e62082293 - languageName: node - linkType: hard - "@types/send@npm:*": version: 0.17.4 resolution: "@types/send@npm:0.17.4" @@ -9946,6 +9960,13 @@ __metadata: languageName: node linkType: hard +"@whatwg-node/events@npm:^0.1.0": + version: 0.1.1 + resolution: "@whatwg-node/events@npm:0.1.1" + checksum: 10/3a356ca23522190201e27446cfd7ebf1cf96815ddb9d1ba5da0a00bbe6c1d28b4094862104411101fbedd47c758b25fe3683033f6a3e80933029efd664c33567 + languageName: node + linkType: hard + "@wry/equality@npm:^0.1.2": version: 0.1.11 resolution: "@wry/equality@npm:0.1.11" @@ -16937,37 +16958,25 @@ __metadata: languageName: node linkType: hard -"graphql-query-complexity@npm:^0.7.0": - version: 0.7.2 - resolution: "graphql-query-complexity@npm:0.7.2" +"graphql-query-complexity@npm:^0.12.0": + version: 0.12.0 + resolution: "graphql-query-complexity@npm:0.12.0" dependencies: lodash.get: "npm:^4.4.2" peerDependencies: - graphql: ^0.13.0 || ^14.0.0 || ^15.0.0 - checksum: 10/b90aaf42fb8fbf128bb5998b0ab51fc3303727a2df4a35ea1ffd7694d940b5f04b543de8fa96549f98406f37b04a49cf5b9f82c8896af500b629f6585d27fb9f - languageName: node - linkType: hard - -"graphql-scalar@npm:0.1.0": - version: 0.1.0 - resolution: "graphql-scalar@npm:0.1.0" - dependencies: - tsdef: "npm:^0.0.14" - peerDependencies: - graphql: "*" - tslib: ^1.10.0 - checksum: 10/3d2339b3dd1a291b02d92bc3825649048432d2d8e25c9193753c89329a4e26ba1aea9b415562d988e5dcd824713ebade3085603f465cc36a9b8676660707f342 + graphql: ^14.6.0 || ^15.0.0 || ^16.0.0 + checksum: 10/4c91af56d02a54d9981b4a5004703c61de920b91245d9883707b70a244cfe5ecc1c75b322979d639ef86841c46e601a1fe48b2c3b4e06d0733876fb9cb9cb9a3 languageName: node linkType: hard -"graphql-subscriptions@npm:^1.1.0": - version: 1.2.1 - resolution: "graphql-subscriptions@npm:1.2.1" +"graphql-scalars@npm:1.23.0": + version: 1.23.0 + resolution: "graphql-scalars@npm:1.23.0" dependencies: - iterall: "npm:^1.3.0" + tslib: "npm:^2.5.0" peerDependencies: - graphql: ^0.10.5 || ^0.11.3 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 - checksum: 10/6dfc0bf278b595c7d99b577e05902d18cd0e56c8c060892ccba7651ff1a49218c7cdd5a8e811fcb9071b98492d238609ba6f326129f5cb0f5433c993671e2d14 + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + checksum: 10/6faa5dea621b708b485cb8c5047098c3daf7c092c8f1f53b87ff6999ef0b28553e5c904ddc01da54141685fcd5798672c4cf997d9738a04dd4e60529450ab707 languageName: node linkType: hard @@ -17013,7 +17022,14 @@ __metadata: languageName: node linkType: hard -"graphql@npm:15.8.0, graphql@npm:^15.5.3": +"graphql@npm:16.8.2": + version: 16.8.2 + resolution: "graphql@npm:16.8.2" + checksum: 10/d74aa1f28a0bbc1c7e60aeb7e4e199e0818ed7169b97bd4d4e86cf345d5645615a9ccb33a11f1ab5e145fdd91d432b3aa475836d3bc5f9647e6103c8854e7e99 + languageName: node + linkType: hard + +"graphql@npm:^15.5.3": version: 15.8.0 resolution: "graphql@npm:15.8.0" checksum: 10/f8d830287a9028d6779b59c437e0ade63a713b47521b02b60316df1761b805b1a7ce03be88053d224b7f78f5d1d1a786d287ab229cd158b42ebeea9e86daaba5 @@ -18977,7 +18993,7 @@ __metadata: languageName: node linkType: hard -"iterall@npm:^1.1.3, iterall@npm:^1.2.1, iterall@npm:^1.3.0": +"iterall@npm:^1.1.3, iterall@npm:^1.2.1": version: 1.3.0 resolution: "iterall@npm:1.3.0" checksum: 10/700c3e9ae194a00b66dc8dcb449195f84add4e64afaf7ed624177e19565393f9bddd34d621ea70c8eceab87a8536fc0e45bb1c9d1ea7c710d41ed0c3d937b19f @@ -28393,13 +28409,6 @@ __metadata: languageName: node linkType: hard -"tsdef@npm:^0.0.14": - version: 0.0.14 - resolution: "tsdef@npm:0.0.14" - checksum: 10/426db840b57d0d0f2ee0ab5af82e5357e31cdec7fa95530c151699f3e2ee9db40aedb6a15f755071fb786de785c154748df01a125b56efaa99ea19227bf89df2 - languageName: node - linkType: hard - "tslib@npm:2.3.1": version: 2.3.1 resolution: "tslib@npm:2.3.1" @@ -28414,7 +28423,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:2.6.2, tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.5.0, tslib@npm:^2.6.1, tslib@npm:^2.6.2": +"tslib@npm:2.6.2, tslib@npm:^2.0.0, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.5.0, tslib@npm:^2.6.1, tslib@npm:^2.6.2": version: 2.6.2 resolution: "tslib@npm:2.6.2" checksum: 10/bd26c22d36736513980091a1e356378e8b662ded04204453d353a7f34a4c21ed0afc59b5f90719d4ba756e581a162ecbf93118dc9c6be5acf70aa309188166ca @@ -28428,6 +28437,13 @@ __metadata: languageName: node linkType: hard +"tslib@npm:^2.5.2": + version: 2.6.3 + resolution: "tslib@npm:2.6.3" + checksum: 10/52109bb681f8133a2e58142f11a50e05476de4f075ca906d13b596ae5f7f12d30c482feb0bff167ae01cfc84c5803e575a307d47938999246f5a49d174fc558c + languageName: node + linkType: hard + "tsscmp@npm:1.0.6": version: 1.0.6 resolution: "tsscmp@npm:1.0.6" @@ -28633,22 +28649,24 @@ __metadata: languageName: node linkType: hard -"type-graphql@npm:1.1.1": - version: 1.1.1 - resolution: "type-graphql@npm:1.1.1" +"type-graphql@npm:>=2.0.0-rc.2": + version: 2.0.0-rc.2 + resolution: "type-graphql@npm:2.0.0-rc.2" dependencies: - "@types/glob": "npm:^7.1.3" + "@graphql-yoga/subscription": "npm:^5.0.0" "@types/node": "npm:*" - "@types/semver": "npm:^7.3.3" - glob: "npm:^7.1.6" - graphql-query-complexity: "npm:^0.7.0" - graphql-subscriptions: "npm:^1.1.0" - semver: "npm:^7.3.2" - tslib: "npm:^2.0.1" + "@types/semver": "npm:^7.5.6" + graphql-query-complexity: "npm:^0.12.0" + semver: "npm:^7.5.4" + tslib: "npm:^2.6.2" peerDependencies: - class-validator: ">=0.12.0" - graphql: ^15.3.0 - checksum: 10/587536d9e94075273c60dc52f335869c297b966e188d76395eba62ee2992fc7630be5b33c0b034ef1e3cbaf54d77f32e3a0a664de16f6972c87a179c5409abf5 + class-validator: ">=0.14.0" + graphql: ^16.8.1 + graphql-scalars: ^1.23.0 + peerDependenciesMeta: + class-validator: + optional: true + checksum: 10/846a4e6d0a1d2e8bab6a74dfaa55e0813d3e55023b4ace1477159b77135b6dd0bcb55245609a8b279bdae0eb1cbd094aa522fd82851fc09a058b65c330b24c76 languageName: node linkType: hard