Create GraphQL schema and resolvers with TypeScript, using classes and decorators!

Overview

logo

TypeGraphQL

npm version Build Status codecov dependencies open collective install size

Create GraphQL schema and resolvers with TypeScript, using classes and decorators!

https://typegraphql.com/

Introduction

TypeGraphQL makes developing GraphQL APIs an enjoyable process, i.e. by defining the schema using only classes and a bit of decorator magic.

So, to create types like object type or input type, we use a kind of DTO classes. For example, to declare Recipe type we simply create a class and annotate it with decorators:

@ObjectType()
class Recipe {
  @Field(type => ID)
  id: string;

  @Field()
  title: string;

  @Field(type => [Rate])
  ratings: Rate[];

  @Field({ nullable: true })
  averageRating?: number;
}

And we get the corresponding part of the schema in SDL:

type Recipe {
  id: ID!
  title: String!
  ratings: [Rate!]!
  averageRating: Float
}

Then we can create queries, mutations and field resolvers. For this purpose we use controller-like classes that are called "resolvers" by convention. We can also use awesome features like dependency injection and auth guards:

@Resolver(Recipe)
class RecipeResolver {
  // dependency injection
  constructor(private recipeService: RecipeService) {}

  @Query(returns => [Recipe])
  recipes() {
    return this.recipeService.findAll();
  }

  @Mutation()
  @Authorized(Roles.Admin) // auth guard
  removeRecipe(@Arg("id") id: string): boolean {
    return this.recipeService.removeById(id);
  }

  @FieldResolver()
  averageRating(@Root() recipe: Recipe) {
    return recipe.ratings.reduce((a, b) => a + b, 0) / recipe.ratings.length;
  }
}

And in this simple way we get this part of the schema in SDL:

type Query {
  recipes: [Recipe!]!
}

type Mutation {
  removeRecipe(id: String!): Boolean!
}

Motivation

We all know that GraphQL is great and solves many problems we have with REST APIs, like overfetching and underfetching. But developing a GraphQL API in Node.js with TypeScript is sometimes a bit of a pain. Why? Let's take a look at the steps we usually have to take.

First, we create all the GraphQL types in schema.gql using SDL. Then we create our data models using ORM classes, which represent our db entities. Then we start to write resolvers for our queries, mutations and fields, but this forces us to first create TS interfaces for all arguments, inputs, and even object types.

Only then can we actually implement the resolvers using weird generic signatures and manually performing common tasks, like validation, authorization and loading dependencies:

export const getRecipesResolver: GraphQLFieldResolver<void, Context, GetRecipesArgs> = async (
  _,
  args,
  ctx,
) => {
  // common tasks repeatable for almost every resolver
  const repository = TypeORM.getRepository(Recipe);
  const auth = Container.get(AuthService);
  await joi.validate(getRecipesSchema, args);
  if (!auth.check(ctx.user)) {
    throw new NotAuthorizedError();
  }

  // our business logic, e.g.:
  return repository.find({ skip: args.offset, take: args.limit });
};

The biggest problem is redundancy in our codebase, which makes it difficult to keep things in sync. To add a new field to our entity, we have to jump through all the files - modify an entity class, the schema, as well as the interface. The same goes for inputs or arguments. It's easy to forget to update one piece or make a mistake with a single type. Also, what if we've made a typo in field name? The rename feature (F2) won't work correctly.

Tools like GraphQL Code Generator or graphqlgen only solve the first part - they generate the corresponding interfaces (and resolvers skeletons) for our GraphQL schema but they don't fix the schema <--> models redundancy and developer experience (F2 rename won't work, you have to remember about the codegen watch task in background, etc.), as well as common tasks like validation, authorization, etc.

TypeGraphQL comes to address these issues, based on experience from a few years of developing GraphQL APIs in TypeScript. The main idea is to have only one source of truth by defining the schema using classes and some help from decorators. Additional features like dependency injection, validation and auth guards help with common tasks that normally we would have to handle ourselves.

Documentation

The documentation, installation guide, detailed description of the API and all of its features is available on the website.

Getting started

A full getting started guide with a simple walkthrough (tutorial) can be found at getting started docs.

Video tutorial

If you prefer video tutorials, you can watch Ben Awad's TypeGraphQL video series on YouTube.

Examples

You can also check the examples folder in this repository for more examples of usage: simple fields resolvers, DI Container support, TypeORM integration, automatic validation, etc.

The Tests folder might also give you some tips how to get various things done.

The future

The currently released version is a stable 1.0.0 release. It is well tested (95% coverage, 428 test cases) and has most of the planned features already implemented. Plenty of companies and independent developers are using it in production with success.

However, there are also plans for a lot more features like better TypeORM, Prisma and dataloader integration, custom decorators and metadata annotations support - the full list of ideas is available on the GitHub repo. You can also keep track of development's progress on project board.

If you have any interesting feature requests, feel free to open an issue on GitHub so we can discuss that!

Support

TypeGraphQL is an MIT-licensed open source project. This framework is a result of the tremendous amount of work - sleepless nights, busy evenings and weekends.

It doesn't have a large company that sits behind - its ongoing development is possible only thanks to the support by the community.

Gold Sponsors 🏆

BlueReceipt ECAD Labs

Please ask your company to support this open source project by becoming a gold sponsor and getting a premium technical support from our core contributors.

Silver Sponsors 🥈

Gorrion Software House Mr Yum

Bronze Sponsors 🥉

Live Graphic Systems LifeX Aps SwissMentor

Become a Sponsor

Members 💪

Backers ☕

Want to help?

Want to file a bug, contribute some code, or improve documentation? Great! Please read our guidelines for contributing and then check out one of our help wanted issues.

Comments
  • Directives support with `@Directive` decorator

    Directives support with `@Directive` decorator

    I was toying with federation support and going about it the manual way.

    Here's the issue I also posted on apollo-server https://github.com/apollographql/apollo-server/issues/2965

    This doesn't work but if you look at the test, it shows the federated schema.

    I sort of am clueless on how to support directives so it'd be cool if someone could chime in on this.

    I was mocking the test case from the federation-demo's reviews service. Ideally we can have a fully functional replica.

    /cc @JacksonKearl

    Enhancement :new: Community :family_man_girl: 
    opened by j 87
  • Getting

    Getting "Schema must contain uniquely named types but contains multiple types named" for a single type

    Hello, I have the following schema:

    @ObjectType()
    class Action {
      @Field(type => Skill, { nullable: true })
      skill?: Skill;
    }
    
    @ObjectType()
    export class ActionResult {
      @Field(type => [Action])
      actions!: Action[];
      @Field({ nullable: true })
      count?: number
    }
    
    @ObjectType()
    export class Skill {}
    
    @Resolver(Action)
    export class ActionResolver  extends BaseResolver {
      @Query(returns => ActionResult)
      async actions (@Args() args: ActionArgs, @Info() info){
    
      }
    
      @FieldResolver()
      async skill(@Root() action: Action) {
      }
    }
    
    @Resolver(Skill)
    export class SkillResolver extends BaseResolver {
      @Query(returns => [Skill])
      async allSkills (){
    
      }
    }
    
    

    From this I generate a schema like this:

      return buildSchema({
        resolvers: [ActionResolver, SkillResolver],
        emitSchemaFile: { path: 'schema.graphql' },
      })
    

    And I get the error:

    UnhandledPromiseRejectionWarning: Error: Schema must contain uniquely named types but contains multiple types named "Skill".
    
    Question :grey_question: Solved :heavy_check_mark: 
    opened by gotenxds 45
  • Integration with typegoose

    Integration with typegoose

    Hey @19majkel94 I am trying to use typegoose with type-graphql. Following are the relevant code snippets from my user.model.ts, user.service.ts and user.resolver.ts files. user.model.ts

    @ObjectType()
    @pre<User>('save', async function () {
      var user = this;
      if (user.isModified('password')) {
        user.password = await bcrypt.hash(user.password, SALT_WORK_FACTOR)
      }
    })
    export class User extends Typegoose {
      @Field(() => ID)
      _id: string;
      
      @Field(() => Date)
      createdAt: Date;
    
      @Field(() => Date)
      updatedAt: Date;
    
      @prop({ required: true })
      @Field(() => String, { nullable: false })
      firstName: string;
    
    
      @prop({ required: true })
      @Field(() => String, { nullable: false })
      lastName: string;
    
      @Field(() => String, { nullable: false })
      @prop({ required: true })
      email: string;
    
      @prop({ required: true })
      password: string;
    }
    
    export const UserModel = new User().getModelForClass(User, { schemaOptions: { timestamps: true } });
    

    user.service.ts

    import { UserModel, User } from '../models/user.model';
    
    export const getUserById = async (userId: string): Promise<User> => {
      const user: User = await UserModel.findOne({ _id: userId });
      if (!user) {
        throw new UserInputError(`User with userId ${userId} not found`);
      }
      user.password = null;
      delete user.password;
      return user;
    };
    

    user.resolver.ts

    import { User } from '../models/user.model';
    import { getUserById } from '../services/user.service';
    
    @Resolver(() => User)
    export class UserResolver {
      @Query(() => User, { nullable: false })
      @UseMiddleware(Auth)
      async user(@Arg('_id') _id: string, @Ctx() context: Context): Promise<User> {
        return getUserById( _id);
      }
     }
    

    Whenever I try to fire the user resolver I get the following error

    {
      "data": null,
      "errors": [
        {
          "message": "Expected value of type \"User\" but got: { _id: 5b530bec3b461c03cef31a53,\n  firstName: 'Danny',\n  lastName: 'Paul',\n  email: '[email protected]',\n  password: null,\n  createdAt: 2018-07-21T10:33:26.763Z,\n  updatedAt: 2018-07-21T10:33:26.763Z,\n  __v: 0 }.",
          "locations": [
            {
              "line": 9,
              "column": 3
            }
          ],
          "path": [
            "user"
          ],
          "extensions": {
            "code": "INTERNAL_SERVER_ERROR",
            "exception": {
              "message": "Expected value of type \"User\" but got: { _id: 5b530bec3b461c03cef31a53,\n  firstName: 'Danny',\n  lastName: 'Paul',\n  email: '[email protected]',\n  password: null,\n  createdAt: 2018-07-21T10:33:26.763Z,\n  updatedAt: 2018-07-21T10:33:26.763Z,\n  __v: 0 }.",
              "locations": [
                {
                  "line": 9,
                  "column": 3
                }
              ],
              "stacktrace": [
                "GraphQLError: Expected value of type \"User\" but got: { _id: 5b530bec3b461c03cef31a53,",
                "  firstName: 'Danny',",
                "  lastName: 'Paul',",
                "  email: '[email protected]',",
                "  password: null,",
                "  createdAt: 2018-07-21T10:33:26.763Z,",
                "  updatedAt: 2018-07-21T10:33:26.763Z,",
                "  __v: 0 }.",
                "    at invalidReturnTypeError (/usr/src/app/node_modules/graphql/execution/execute.js:766:10)",
                "    at completeObjectValue (/usr/src/app/node_modules/graphql/execution/execute.js:758:13)",
                "    at completeValue (/usr/src/app/node_modules/graphql/execution/execute.js:660:12)",
                "    at completeValue (/usr/src/app/node_modules/graphql/execution/execute.js:629:21)",
                "    at /usr/src/app/node_modules/graphql/execution/execute.js:617:14",
                "    at process._tickCallback (internal/process/next_tick.js:68:7)"
              ]
            }
          }
        }
      ]
    }
    

    My package versions are as follows: apollo-server: 2.0.0 apollo-server-express: 2.0.0 mongoose: 5.2.4 type-graphql: 0.12.3 typegoose: 5.2.1

    I am sorry I had to post this issue in github and not gitter because of the size of my code.

    Question :grey_question: Solved :heavy_check_mark: 
    opened by danpaugo 45
  • Cannot use GraphQLSchema from another module or realm

    Cannot use GraphQLSchema from another module or realm

    Describe the bug I installed express-graphql and typed-graphql, then I defined my entities and built the schema, when I pass the Schema to express-graphql and added it to my express app. As soon as I open grahpiql in my browser and run a query I get the error:

    
    {
      "errors": [
        {
          "message": "Cannot use GraphQLSchema \"[object Object]\" from another module or realm.\n\nEnsure that there is only one instance of \"graphql\" in the node_modules\ndirectory. If different versions of \"graphql\" are the dependencies of other\nrelied on modules, use \"resolutions\" to ensure only one version is installed.\n\nhttps://yarnpkg.com/en/docs/selective-version-resolutions\n\nDuplicate \"graphql\" modules cannot be used at the same time since different\nversions may have different capabilities and behavior. The data from one\nversion used in the function from another could produce confusing and\nspurious results."
        }
      ]
    }
    

    Enviorment (please complete the following information):

    • OS: Ubuntu 18.04
    • Node 10.9.0
    • Package version 0.13.1
    • TypeScript version 3.0.1
    Question :grey_question: Community :family_man_girl: Discussion :speech_balloon: Solved :heavy_check_mark: 
    opened by lal12 29
  • Using this in a serverless environment (e.g. apollo-lambda-server)

    Using this in a serverless environment (e.g. apollo-lambda-server)

    How would I use this library in a lambda execution model?

    I tried to implement it as follows, but on the second (and subsequent) calls to the endpoint, I get an error which states:

    Schema must contain unique named types but contains multiple types named "Person"

    I assume that this is because the schema is being re-built on every request, and therefore creating duplicated types?

    handler.ts

    import 'reflect-metadata';
    
    import { graphqlLambda } from 'apollo-server-lambda';
    import { buildSchema } from 'type-graphql';
    
    import { PeopleController } from './controllers/people/peopleController';
    
    export async function graphqlHandler(event, context, callback) {
        function callbackWithHeaders(error, output) {
            output.headers['Access-Control-Allow-Origin'] = '*';
            callback(error, output);
        }
    
        const schema = await buildSchema({
            resolvers: [PeopleController]
        });
    
        const handler = graphqlLambda({ schema: schema });
        return handler(event, context, callbackWithHeaders);
    }
    

    person.ts:

    import { ID, Field, ObjectType } from 'type-graphql';
    
    @ObjectType()
    export class Person {
        @Field() name: string;
        @Field() creationDate: Date;
    }
    

    peopleController.ts

    import { Arg, Query, Resolver } from 'type-graphql';
    import { Person } from './person';
    
    @Resolver()
    export class PeopleController {
        items: Person[] = [
            {
                name: 'darbio',
                creationDate: new Date()
            }
        ];
    
        @Query(returns => [Person], { description: 'Get all the people' })
        async people(): Promise<Person[]> {
            return await this.items;
        }
    }
    
    Question :grey_question: Solved :heavy_check_mark: 
    opened by darbio 29
  • Support for client side resolvers (apollo-link-state)

    Support for client side resolvers (apollo-link-state)

    Does type-graphql support client side resolvers for use with apollo-link-state? (https://blog.apollographql.com/the-future-of-state-management-dd410864cae2, https://hackernoon.com/storing-local-state-in-react-with-apollo-link-state-738f6ca45569)

    Enhancement :new: Community :family_man_girl: Solved :heavy_check_mark: 
    opened by tonyxiao 26
  • Nested input types are not deserialized into class instances

    Nested input types are not deserialized into class instances

    Describe the bug When having nested input types only the top-most class gets transformed into it's instance. Any nested objects remains plain javascript objects.

    To Reproduce

    @InputType()
    class NestedTestInputType {
      @Field()
      foo: number
    }
    
    @InputType()
    class TestInputType {
      @Field()
      nested: NestedTestInputType
    }
    
    @Service()
    @Resolver(of => /* ... */)
    export class TestResolver {
       @Query(returns => [String])
      async test(@Arg('filter') filter: TestInputType) {
        assert(filter instanceof TestInputType, 'Filter must be instance of TestInputType') // <-- OK
        assert(
          filter.nested instanceof NestedTestInputType,
          'Filter#nested must be instance of NestedInputType',
        ) // <-- FAILS
        return []
      }
    }
    

    Expected behavior Nested input types should be deserialized into instances of their classes recursively.

    Enviorment (please complete the following information):

    Bug :bug: Community :family_man_girl: Solved :heavy_check_mark: 
    opened by adam-stanek 25
  • Resolver inheritance/extending

    Resolver inheritance/extending

    The project I'm working on right now has a lot of super-similar CRUD-alike resolvers, and amount of copy-paste is huge. I've come up with something like this:

    export type ResourceRepositoryServiceClass<
      TService extends ResourceRepositoryService<TEntity, TId, TContent>,
      TEntity = {},
      TId = {},
      TContent = {}
    > = Function & { prototype: TService }
    
    export interface DtoClassType<TDto extends Dto<TDto, TObject>, TObject = {}> {
      new (): TDto
    }
    
    export function ResourceResolver<
      TDto extends Dto<TDto, TObject>,
      TContentDto extends Dto<TContentDto, TContentObject>,
      TService extends ResourceRepositoryService<TEntity, TId, TContent>,
      TEntity = {},
      TId = {},
      TContent = {},
      TObject = {},
      TContentObject = {}
    > (
      resourceType: Resource,
      resourceServiceIdentifier: ResourceRepositoryServiceClass<TService>,
      dtoClass: DtoClassType<TDto>,
      contentDtoClass: DtoClassType<TContentDto>
    ) {
      const resourceNameUpper = upperFirst(camelCase(resourceType))
    
      abstract class ResourceResolver<
        TResolver
      > {
        protected readonly packDto = Dto.pack.bind(dtoClass)
        protected readonly unpackDto = Dto.unpack.bind(dtoClass)
        protected readonly packContentDto = Dto.pack.bind(contentDtoClass)
        protected readonly unpackContentDto = Dto.unpack.bind(contentDtoClass)
    
        constructor (
          @inject(resourceServiceIdentifier) protected readonly resourceService: TService
        ) {}
    
        @Mutation(returns => dtoClass)
        @Authorized(Permissions.canCreate(resourceType))
        async [`create${resourceNameUpper}`] (
          @Arg('data', type => contentDtoClass) data: TContentDto
        ): Promise<TDto> {
          const resource = await this.resourceService.create(this.unpackContentDto(data))
          return this.packDto(resource)
        }
      }
    
      return ResourceResolver
    }
    
    @injectable()
    @Resolver(of => ThingDto)
    export default class ThingResolver extends ResourceResolver(
      Resource.Thing,
      ThingService,
      ThingDto,
      ThingContentDto
    )<ThingResolver> {
      constructor (
        @inject(ThingService) thingService: ThingService
      ) {
        super(thingService)
      }
    
      // Here goes any resource-specific thing
    }
    

    Yet the approach won't work, since @Mutation gets a ResourceResolver as target, that can not be resolved via DI.

    What are your thoughts on making this approach possible? Options I see so far:

    • Resolver should support something like "extends" to override the target of inherited annotations?
    Enhancement :new: Community :family_man_girl: Solved :heavy_check_mark: 
    opened by alexey-pelykh 24
  • Decorator allowing field metadata annotations

    Decorator allowing field metadata annotations

    It is generally useful to be able to annotate fields with custom metadata for use by middleware and validators. See: #77 and #36 (my personal use case)

    Since there currently isn't support for directives in GraphQL-js, an alternative might be for TypeGraphQL to add a new decorator that annotates the fiend config object passed into the GraphQLObjectType constructor with additional user-defined metadata fields.

    I'd imagine the API looking something like this:

    @ObjectType()
    class MyObjectType {
      @Metadata({ isUseful: false })
      @Field()
      myAnnotatedField() {
        return "12"
      }
    }
    

    This relatively simple change would make it possible to write middleware libraries wrapping tools such as graphql-query-complexity.

    Owner note: Read more about how to implement here: https://github.com/19majkel94/type-graphql/issues/124#issuecomment-426935908

    Enhancement :new: Community :family_man_girl: Solved :heavy_check_mark: 
    opened by chrisdevereux 23
  • Towards release 1.0

    Towards release 1.0

    Today, I released the first Release Candidate version of major 1.0.0 🎉 https://www.npmjs.com/package/type-graphql/v/1.0.0-rc.1 It is also distributed as a new major version on the default latest tag.

    This release contains a lot of breaking changes, so please read the release notes carefully 👀 https://github.com/MichalLytek/type-graphql/releases/tag/v1.0.0-rc.1

    The 1.0.0 milestone is finished in 97% - it contains of 87 closed issues! 😵 https://github.com/MichalLytek/type-graphql/milestone/3 The work that has to be also done before final release is to write the announcement post about the 1.0.0 release, after 2 years of developing TypeGraphQL ☺️

    Feel free to update your apps and let me know how the new version works for you and what improvements you would like to see in the upcoming 1.0.0 release!

    And don't forget to support the project as its ongoing development is possible only thanks to the support by the community ❤️

    Especially if you are using it commercially - just to ensure that the project which your product relies on is actively maintained and improved 💪

    Community :family_man_girl: Solved :heavy_check_mark: 
    opened by MichalLytek 22
  • Generic argument validation error is thrown with no indication of the field that is causing it

    Generic argument validation error is thrown with no indication of the field that is causing it

    Describe the bug Given an InputType field with validation

    @InputType()
    export class CatalogInput implements Partial<Catalog> {
      @Field()
      id: number;
      @MaxLength(1000)
      @Field({ nullable: true })
      description?: string;
    }
    

    and a mutation

    @Mutation(returns => CatalogUpdateResult)
    updateCatalog(
      @Arg("catalog", () => CatalogInput, { validate: true })
      catalog: CatalogInput
    ): CatalogUpdateResult {
      return { catalog };
    }
    

    when I try to sent mutation to the server with a value exceeding the limit, then I get a very generic error that does not indicate which field caused it, the locations array is empty:

    {
      "errors": [
        {
          "message": "Argument Validation Error",
          "locations": [
            {
              "line": 2,
              "column": 3
            }
          ],
          "path": [
            "updateCatalog"
          ],
          "extensions": {
            "code": "INTERNAL_SERVER_ERROR",
            "exception": {
              "errors": [
                {
                  "message": "Argument Validation Error",
                  "locations": [],
                  "path": [
                    "updateCatalog"
                  ]
                }
              ],
     ...
    

    Expected behavior I would expected to have the information about what caused the failure, i.e. the location array containing the information.

    Enviorment (please complete the following information):

    • OS: Windows
    • Node 10.15.3
    • Package version 0.17.1
    • TypeScript version 3.3.3333

    Thanks, Karel

    Question :grey_question: Solved :heavy_check_mark: 
    opened by kfrajtak 22
  • internal(refactor): improving maintainability for V2 release

    internal(refactor): improving maintainability for V2 release

    This PR starts a series of iterations for improving the maintainability of the project and trying not to create too many conflicts with new-major-release branch. Note that this PR is not ready to be merged (as written before) because the code style must be applied to the new code present in new-major-release branch and not the master since it can create too many conflicts. Should fix #1106 and create a base for a better coding experience! What has been changed:

    1. Updated husky configuration to reflect new version.
    2. Updated lint-staged configuration (replacing TSLint with ESLint) and moved to a proper configuration file.
    3. Updated VS Code settings settings.json to include formatOnSave and defaultFormatter (prettier).
    4. Added VS Code extensions.json which includes a list of recommended extensions to install for improving experience while coding in VS Code (help new contributors with their first contribution).
    5. Updated benchmarks to match ESLint code style.
    6. Moved publish-website.sh to scripts directory. publish-website.sh is POSIX-compliant. scripts include a __commons.sh file (sourced by publish-website.sh) with utility functions (e.g., logger) and more.
    7. Replaced TSLint with ESLint. This has been long awaited! The configuration file must be changed to reflect what @MichalLytek desiders (currently is based on Airbnb code style).
    8. Added markdownlint: A Node.js style checker and lint tool for Markdown/CommonMark files.
    9. Added ShellCheck: A shell script static analysis tool. FUTURE: Add action-shellcheck in CI.
    10. Added CSpell: A Spell Checker for Code! to check for typo(s) and spell checking errors.
    11. Updated Jest configuration file to match ts-jest. Moreover, type checking and hints in the configuration file
    12. Added more scripts in package.json for checking and fixing errors.

    @MichalLytek Let me know what you think and what you want to change/update/add/delete.


    PS: Do we really need Gulp?

    Community :family_man_girl: Internal :house: 
    opened by carlocorradini 6
  • Should able to use TypeGraphQL with Tsyringe

    Should able to use TypeGraphQL with Tsyringe

    Describe the issue I have a project using DI with tsyringe and i should to add graphql using type-graphql, but in documentation is only listed the TypeDI as a dependency injection lib

    Are you able to make a PR that fix this? If is possible to use Tsyringe, plesse add some example in doc's

    Additional context N/A

    Question :grey_question: Community :family_man_girl: 
    opened by leandroluk 3
  • Validation issues on version 2.0.0-beta.1 with @apollo-server@4.3.0

    Validation issues on version 2.0.0-beta.1 with @[email protected]

    Describe the Bug I'm using type-graphql v2.0.0-beta.1 together with @[email protected]. (As mentioned here type-graphql v1.1.1 doesn't work fine with apollo-server v4) There are some issues related to validation:

    1. I'm not able to call a mutation passing correct variables in the body, it leads to Argument Validation Error in the response. The issue seems to be related to "forbidUnknownValues" option in the class-validator library, at least setting it to false allows to avoid the error.

    2. The"validationErrors" field is always missing in the ArgumentValidationError response (even if I set forbidUnknownValues to false, add some validator like MaxLength and pass incorrect value - "validationErrors" will be missing in the response JSON)

    To Reproduce Here is the code:

    import "reflect-metadata";
    import { ApolloServer } from "@apollo/server";
    import express from "express";
    import { expressMiddleware } from "@apollo/server/express4"
    import cors from "cors";
    import http from "http";
    import { ApolloServerPluginDrainHttpServer } from "@apollo/server/plugin/drainHttpServer";
    import bodyParser from "body-parser";
    import { buildSchema } from "type-graphql";
    import { Arg, Mutation, Query, Resolver } from "type-graphql";
    import { ObjectType, Field, ID, InputType } from "type-graphql";
    
    @ObjectType()
    export class User {
        @Field(() => ID)
        id: string;
    
        @Field()
        email: string;
    
        @Field({nullable: true})
        firstName?: string;
    
        @Field({nullable: true})
        lastName?: string;
    }
    
    @InputType()
    export class AddUserInput {
        @Field()
        email: string;
    
        @Field({nullable: true})
        firstName?: string;
    
        @Field({nullable: true})
        lastName?: string;
    }
    
    @Resolver(User)
    export class UserResolver {
        users: User[] = [];
    
        @Query(() => [User], { name: "users" })
        getAll(): User[] {
            return this.users;
        }
    
        @Mutation(() => User, { name: "addUser" })
        add(@Arg("user") userInput: AddUserInput): User {
            const user = new User();
            Object.assign(user, userInput);
            user.id = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString();
            this.users.push(user);
            return user;
        }
    }
    
    const bootstrap = async () => {
        const app = express();
        const httpServer = http.createServer(app);
    
        const schema = await buildSchema({
            resolvers: [UserResolver],
            //validate: {
            //    forbidUnknownValues: false  !!! Only works with this setting
            //}
        });
    
        const apolloServer = new ApolloServer({
            schema,
            plugins: [ApolloServerPluginDrainHttpServer({ httpServer })]
        });
    
        await apolloServer.start();
    
        app.use(
            cors(),
            bodyParser.json(),
            expressMiddleware(apolloServer)
        );
    
        const port = 4000;
        httpServer.listen( {port }, () => {
            console.log(`Server started at http://localhost:${port}`);
        });
    }
    
    bootstrap();
    

    Here is my package.json:

    {
      "name": "graphql_api",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "dev": "ts-node-dev --respawn src/index.ts",
        "prebuild": "rimraf build",
        "build": "tsc && copyfiles package.json build",
        "start": "node index.js"
      },
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "@types/cors": "^2.8.13",
        "@types/graphql": "^14.5.0",
        "@types/node": "^18.11.14",
        "copyfiles": "^2.4.1",
        "rimraf": "^3.0.2",
        "ts-node-dev": "^2.0.0",
        "typescript": "^4.9.4"
      },
      "dependencies": {
        "@apollo/server": "^4.3.0",
        "body-parser": "^1.20.1",
        "class-validator": "^0.14.0",
        "cors": "^2.8.5",
        "express": "^4.18.2",
        "graphql": "^16.6.0",
        "reflect-metadata": "^0.1.13",
        "type-graphql": "^2.0.0-beta.1"
      }
    }
    

    And this is the Mutation I'm trying to call:

    mutation Mutation($user: AddUserInput!) {
      addUser(user: $user) {
        id
        email
        firstName
        lastName
      }
    }
    

    Variables:

    {
      "user": {
        "email": "[email protected]",
        "firstName": "John",
        "lastName": "Smith"
      }
    }
    

    The error response I get:

    {
        "errors": [
            {
                "message": "Argument Validation Error",
                "locations": [
                    {
                        "line": 1,
                        "column": 43
                    }
                ],
                "path": [
                    "addUser"
                ],
                "extensions": {
                    "code": "INTERNAL_SERVER_ERROR",
                    "stacktrace": [
                        "Error: Argument Validation Error",
                        "    at validateArg (D:\\Temp\\TypeGraphQL_Issue\\node_modules\\type-graphql\\dist\\resolvers\\validate-arg.js:55:15)",
                        "    at processTicksAndRejections (internal/process/task_queues.js:93:5)",
                        "    at async Promise.all (index 0)"
                    ]
                }
            }
        ],
        "data": null
    }
    

    Environment (please complete the following information):

    • OS: Windows 10
    • Node v14.15.3
    • Package version 2.0.0-beta.1
    • TypeScript version 4.9.4
    • Apollo server version: 4.3.0
    Question :grey_question: 
    opened by YMSpektor 13
  • Error: Subscription field must return Async Iterable. Received: undefined.

    Error: Subscription field must return Async Iterable. Received: undefined.

    Describe the Bug Error after subscription client.

    To Reproduce

    /// server
    import { ApolloServer } from 'apollo-server-express';
    import express from 'express';
    import { useServer } from 'graphql-ws/lib/use/ws';
    import { createServer } from 'http';
    import { WebSocketServer } from 'ws';
    /// ...
    
      const app = express();
      const httpServer = createServer(app);
      const wsServer = new WebSocketServer({
        server: httpServer,
        path: '/',
      })
    
      const schema = buildFederatedSchema({ orphanedTypes, resolvers, pubSub })
      const serverCleanup = useServer({ schema }, wsServer);
      const server = new ApolloServer({ schema });
      
      await server.start();
      server.applyMiddleware({ app, path: '/' });
      httpServer.listen({ port }, ... );
    
    
    /// resolver
    import { withFilter } from 'graphql-subscriptions';
    import {
      Resolver,
      Root,
      Args,
      Subscription,
    } from 'type-graphql';
    /// ...
    
    @Resolver()
    export class SubscriptionResolver {
      @Subscription(() => Notification, {
        subscribe: withFilter(
          () => pubSub.asyncIterator(topics),
          (root, args) => {
            return args.type === root.type;
          },
        ),
    
        // subscribe() {
        //   return pubSub.asyncIterator(topics);
        // },
    
        // topics,
        // topics: ({ args }) => args.type,
        
        // filter: ({ args, payload }) => {
        //   return args.type === payload.type;
        // },
      })
      notifications(@Root() payload: NotificationPayload, @Args() args: NotificationArgs) {
        return {
          type: args.typeNotify,
          date: payload.date,
          meta: payload?.meta,
        };
      }
    

    Expected Behavior After execution of subscription operation on Studio ApolloGraphql sandbox, i expect to connect to the socket, and receive messages on the emission of events. But get the error subscribe

    Logs

    ...
    🚀 Query endpoint ready at http://localhost:3008/
    🚀 Subscriptions ready at ws://localhost:3008/
    Internal error occurred during message handling. Please check your implementation. Error: Subscription field must return Async Iterable. Received: undefined.
        at createSourceEventStream (/***/node_modules/graphql/execution/subscribe.js:165:13)
        at processTicksAndRejections (node:internal/process/task_queues:96:5)
        at async subscribe (/***/node_modules/graphql/execution/subscribe.js:67:26)
        at async onMessage (/***/node_modules/graphql-ws/lib/server.js:191:51)
        at async WebSocket.<anonymous> (/***/node_modules/graphql-ws/lib/use/ws.js:83:21)
    

    Environment (please complete the following information):

    • Package version - v1.2.0-rc.1
    • OS: MacOS Monteray
    • Node - 16.17.0
    • TypeScript version - 4.7.4
    • npm - v1.2.0-rc.1

    Additional Context Add any other context about the problem here.

    Community :family_man_girl: Need More Info :man_shrugging: 
    opened by V1os 18
  • GraphQLISODateTime scalar does not throw error on bad input values

    GraphQLISODateTime scalar does not throw error on bad input values

    Describe the Bug The conversion function assumes that new Date("some garbage") will throw an exception for bad input values on the Date constructor. When given bad inputs the Date object will just return Invalid Date which is still a Date object, and not throw.

    To Reproduce Create an input object with a field which is type Date Pass in in invalid date string for that fields value The field get set to null

    Expected Behavior Throws the error here https://github.com/MichalLytek/type-graphql/blob/3137ab532fbe6742d06f938d95eefddee1eea435/src/scalars/isodate.ts#L7 back to the caller.

    Environment (please complete the following information):

    • OS: Linux
    • Node 16.17
    • Package version 1.2.0-rc1
    • TypeScript version 4.7

    Additional Context I've replaced the provided GraphQLISODateTime with my own copy of it and have modified the conversion function like so to fix this for us.

    function convertStringToDate(dateString: string) {
      const value = new Date(dateString);
      if (value instanceof Date && !isNaN(value.valueOf())) {
        return value;
      }
      throw new Error("Provided date string is invalid and cannot be parsed");
    }
    
    Bug :bug: Enhancement :new: Help Wanted :sos: Good First Issue :wave: Community :family_man_girl: 
    opened by brycepolly 3
Releases(v1.2.0-rc.1)
  • v1.2.0-rc.1(Oct 6, 2021)

    Features

    • Breaking Change: AuthChecker type is now "function or class" - update to AuthCheckerFn if the function form is needed in the code
    • support class-based auth checker, which allows for dependency injection
    • allow defining directives for interface types and theirs fields, with inheritance for object types fields (#744)
    • allow deprecating input fields and args (#794)
    • support disabling inferring default values (#793)
    • support readonly arrays for roles of @Authorized decorator (#935)
    • add sync version of buildTypeDefsAndResolvers function (#803)

    Fixes

    • Breaking Change: properly emit types nullability when defaultValue is provided and remove ConflictingDefaultWithNullableError error (#751)
    • allow defining extension on field resolver level for fields also defined as a property of the class (#776)
    • fix throwing error when schema with dynamic default value was built again (#787)
    • fix converting inputs with fields of nested array type (#801)
    • disable broken exposing input types fields under a changed name via @Field({ name: "..." })

    Others

    • Breaking Change: update graphql-js peer dependency to ^15.5.0
    Source code(tar.gz)
    Source code(zip)
  • v1.1.1(Nov 4, 2020)

    Fixes

    • fix crashing when of union's or interface type's resolveType function returns undefined or null (#731)
    • fix crashing when no reflected type available for fields with params decorators (#724)
    • fix not registering object types implementing interface type when interface type is used as object type field type (#736)
    • properly transform nested array of input type classes (#737)
    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Oct 12, 2020)

    Features

    • allow passing custom validation function as validate option to buildSchema
    • support defining deprecation reason and description of enum members (#714)

    Fixes

    • Breaking Change: throw error when wrong type of value provided as arg or input for GraphQLISODateTime and GraphQLTimestamp scalars
    • don't include in schema the fields declared as @FieldResolver when that resolvers classes aren't provided in resolvers array
    • fix grammar in CannotDetermineGraphQLTypeError error message
    • properly inherit extensions from parent class and its fields
    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Aug 19, 2020)

    Features

    • Breaking Change: emit in schema only types actually used by provided resolvers classes (#415)
    • Breaking Change: update graphql-js peer dependency to ^15.3.0
    • Breaking Change: update graphql-query-complexity dependency to ^0.7.0 and drop support for fieldConfigEstimator (use fieldExtensionsEstimator instead)
    • Breaking Change: introduce sortedSchema option in PrintSchemaOptions and emit sorted schema file by default
    • Breaking Change: make class-validator a peer dependency of version >=0.12.0 that needs to be installed manually (#366)
    • Breaking Change: remove CannotDetermineTypeError and make other error messages more detailed and specific
    • Breaking Change: remove legacy array inference - now explicit array syntax ([Item]) is required
    • update TypeResolver interface to match with GraphQLTypeResolver from graphql-js
    • add basic support for directives with @Directive() decorator (#369)
    • add possibility to tune up the performance and disable auth & middlewares stack for simple field resolvers (#479)
    • optimize resolvers execution paths to speed up a lot basic scenarios (#488)
    • add @Extensions decorator for putting metadata into GraphQL types config (#521)
    • add support for defining arguments and implementing resolvers for interface types fields (#579)
    • add { autoRegisterImplementations: false } option to prevent automatic emitting in schema all the object types that implements used interface type (#595)
    • allow interfaces to implement other interfaces (#602)
    • expose createResolversMap utility that generates apollo-like resolvers object
    • support IoC containers which .get() method returns a Promise of resolver instance
    • update deps to newest major versions (tslib, graphql-query-complexity)

    Fixes

    • Breaking Change: stop returning null for GraphQLTimestamp and GraphQLISODateTime scalars when returned value is not a Date instance - now it throws explicit error instead
    • Breaking Change: fix transforming and validating nested inputs and arrays (#462)
    • refactor union types function syntax handling to prevent possible errors with circular refs
    • remove duplicated entries for resolver classes that use inheritance (#499)
    • fix using name option on interface fields (#567)
    • fix not calling authChecker during subscribe phase for subscriptions (#578)
    • fix using shared union type in multiple schemas
    • fix using shared interface type in multiple schemas
    • fix calling field resolver without providing resolver class to buildSchema
    • fix generated TS union type for union type of object type classes extending themselves (#587)
    • fix using shared union and interface types in multiple schemas when resolveType is used
    • properly inherit directives while extending @InputType or @ObjectType classes (#626)
    • skip transforming empty array items into input classes

    Others

    • Breaking Change: change build config to ES2018 - drop support for Node.js < 10.3
    • Breaking Change: remove deprecated DepreciationOptions interface
    • Breaking Change: remove deprecated direct array syntax for declaring union types
    Source code(tar.gz)
    Source code(zip)
  • v1.0.0-rc.3(Jun 29, 2020)

    Features

    • Breaking Change: remove legacy array inference - now explicit array syntax ([Item]) is required
    • Breaking Change: update graphql-js peer dependency to ^15.1.0
    • update deps to newest major versions (tslib, graphql-query-complexity)
    Source code(tar.gz)
    Source code(zip)
  • v1.0.0-rc.2(May 19, 2020)

    Features

    • expose createResolversMap utility that generates apollo-like resolvers object
    • support IoC containers which .get() method returns a Promise of resolver instance

    Fixes

    • properly inherit directives while extending @InputType or @ObjectType classes (#626)
    • skip transforming empty array items into input classes
    Source code(tar.gz)
    Source code(zip)
  • v1.0.0-rc.1(May 3, 2020)

    Features

    • Breaking Change: emit in schema only types actually used by provided resolvers classes (#415)
    • Breaking Change: update graphql-js peer dependency to ^15.0.0
    • Breaking Change: update graphql-query-complexity dependency to ^0.5.0 and drop support for fieldConfigEstimator (use fieldExtensionsEstimator instead)
    • Breaking Change: introduce sortedSchema option in PrintSchemaOptions and emit sorted schema file by default
    • Breaking Change: make class-validator a peer dependency of version >=0.12.0 that needs to be installed manually (#366)
    • Breaking Change: remove CannotDetermineTypeError and make other error messages more detailed and specific
    • update TypeResolver interface to match with GraphQLTypeResolver from graphql-js
    • add basic support for directives with @Directive() decorator (#369)
    • add possibility to tune up the performance and disable auth & middlewares stack for simple field resolvers (#479)
    • optimize resolvers execution paths to speed up a lot basic scenarios (#488)
    • add @Extensions decorator for putting metadata into GraphQL types config (#521)
    • add support for defining arguments and implementing resolvers for interface types fields (#579)
    • add { autoRegisterImplementations: false } option to prevent automatic emitting in schema all the object types that implements used interface type (#595)
    • allow interfaces to implement other interfaces (#602)

    Fixes

    • Breaking Change: stop returning null for GraphQLTimestamp and GraphQLISODateTime scalars when returned value is not a Date instance - now it throws explicit error instead
    • refactor union types function syntax handling to prevent possible errors with circular refs
    • fix transforming and validating nested inputs and arrays (#462)
    • remove duplicated entries for resolver classes that use inheritance (#499)
    • fix using name option on interface fields (#567)
    • fix not calling authChecker during subscribe phase for subscriptions (#578)
    • fix using shared union type in multiple schemas
    • fix using shared interface type in multiple schemas
    • fix calling field resolver without providing resolver class to buildSchema
    • fix generated TS union type for union type of object type classes extending themselves (#587)
    • fix using shared union and interface types in multiple schemas when resolveType is used

    Others

    • Breaking Change: change build config to ES2018 - drop support for Node.js < 10.3
    • Breaking Change: remove deprecated DepreciationOptions interface
    • Breaking Change: remove deprecated direct array syntax for declaring union types
    Source code(tar.gz)
    Source code(zip)
  • v0.17.6(Dec 21, 2019)

  • v0.17.5(Aug 18, 2019)

    Features

    • rename DepreciationOptions interface to DeprecationOptions and deprecate the old one
    • update deps to newest minor versions (tslib, semver, graphql-query-complexity and glob)
    • support nested array types (@Field(type => [[Int]])) (#393)
    • deprecate the direct array syntax for union types

    Fixes

    • fix errors on circular refs in union types (#364) by adding the function syntax (() => TClassTypes)
    Source code(tar.gz)
    Source code(zip)
  • v0.17.4(May 12, 2019)

    Features

    • add support for creating custom parameter decorators (#329)
    • allow to provide custom subscribe function in @Subscription decorator (#328)
    Source code(tar.gz)
    Source code(zip)
  • v0.17.3(May 6, 2019)

    Features

    • update packages semver to ^6.0.0 and graphql-subscriptions to ^1.1.0

    Fixes

    • fix broken compatibility with newer @types/graphql due to using removed private types (e.g. MaybePromise) (#320)
    Source code(tar.gz)
    Source code(zip)
  • v0.17.2(Apr 23, 2019)

    Features

    • add support for defining resolveType function for interfaces and unions (#319)
    • add support for setting default nullability for fields and return types (#297)
    • add skipCheck option in buildSchema to disable checking the correctness of a schema
    • add postinstall script for printing info on console about supporting the project

    Fixes

    • fix generating plain resolvers for queries and mutations (compatibility with Apollo client state)
    Source code(tar.gz)
    Source code(zip)
  • v0.17.1(Mar 30, 2019)

    Features

    • add support for emitting schema file in not existing directory (#269)
    • drop support for Node.js v6 (end of LTS in April 2019)

    Fixes

    • fix typings discovery support for WebStorm (#276)
    • allow for returning plain objects when using ObjectTypes that implements InterfaceTypes or extends other classes (#160)
    Source code(tar.gz)
    Source code(zip)
  • v0.17.0(Mar 4, 2019)

    Features

    • Breaking Change: make graphql-js packages a peer dependencies, bump graphql to ^14.1.1 and @types/graphql to ^14.0.7 (#239)
    • Breaking Change: remove useContainer function and allow to register container by buildSchema options (#241)
    • Breaking Change: change the default PrintSchemaOptions option commentDescriptions to false (no more # comments in SDL)
    • add support for passing PrintSchemaOptions in buildSchema.emitSchemaFile (e.g. commentDescriptions: true to restore previous behavior)
    • add buildTypeDefsAndResolvers utils function for generating apollo-like typeDefs and resolvers pair (#233)
    • add support for generic types (#255)

    Fixes

    • Breaking Change: remove the formatArgumentValidationError helper as it's not compatible and not needed in new Apollo Server (#258)
    • fix calling return type getter function @Field(type => Foo) before finishing module evaluation (allow for extending circular classes using require)
    • fix nullifying other custom method decorators - call the method on target instance, not the stored reference to original function (#247)
    • fix throwing error when extending non args class in the @ArgsType() class
    • prevent unnecessary conversion of an object that is already an instance of the requested type (avoid constructor side-effects)
    Source code(tar.gz)
    Source code(zip)
  • v0.16.0(Dec 22, 2018)

    Features

    • add support for default values in schema (#203)
    • add support for lists with nullable items (#211)

    Fixes

    • fix browser shim (compatibility with polyfills for decorator support)
    Source code(tar.gz)
    Source code(zip)
  • v0.15.0(Oct 17, 2018)

    Features

    • Breaking Change: upgrade graphql to ^14.0.2, graphql-subscriptions to ^1.0.0 and @types/graphql to ^14.0.2
    • update all other dependencies
    • drop support for Node.js v9
    • add capability to emit the schema definition file (*.gql) as a buildSchema option
    • add emitSchemaDefinitionFile helper function for emitting the schema SDL
    Source code(tar.gz)
    Source code(zip)
  • v0.14.0(Sep 8, 2018)

    Features

    • Breaking Change: change ClassType type and export it in package index
    • Breaking Change: refactor generic createUnionType to remove the 10 types limit (note: requires TypeScript >=3.0.1)
    • add support for subscribing to dynamic topics - based on args/ctx/root (#137)
    • add support for query complexity analysis - integration with graphql-query-complexity (#139)
    Source code(tar.gz)
    Source code(zip)
  • v0.13.1(Aug 14, 2018)

  • v0.13.0(Aug 7, 2018)

    Features

    • make class-validator a virtual peer dependency and update it to newest 0.9.1 version
    • add support for creating scoped containers (#113)
    Source code(tar.gz)
    Source code(zip)
  • v0.12.3(Jul 10, 2018)

    Features

    • add reflect-metadata checks and informative error if no polyfill provided
    • update @types/graphql to latest version (^0.13.3)

    Fixes

    • fix throwing error when of => objectType wasn't provided in abstract resolver class
    • fix calling Object.assign with boolean arguments (#111)
    Source code(tar.gz)
    Source code(zip)
  • v0.12.2(Jun 23, 2018)

    Features

    • add support for using type classes in browser (configure webpack to use decorators shim)

    Fixes

    • fix swallowing false argument value (#101)
    Source code(tar.gz)
    Source code(zip)
  • v0.12.1(Jun 6, 2018)

  • v0.12.0(Jun 1, 2018)

    Features

    • Breaking Change: remove deprecated ActionData and FilterActionData interfaces
    • add support for resolver classes inheritance
    • add name decorator option for @Field and @FieldResolver decorators that allows to set the schema name different than the property name
    Source code(tar.gz)
    Source code(zip)
  • v0.11.3(May 16, 2018)

  • v0.11.2(Apr 29, 2018)

    Features

    • attach MetadataStorage to global scope (support multiple packages/modules)
    • rename and deprecate ActionData and FilterActionData interfaces to ResolverData and ResolverFilterData
    Source code(tar.gz)
    Source code(zip)
  • v0.11.1(Apr 24, 2018)

    Features

    • add support for returning null instead of throwing authorization error (authMode property of buildSchema config)
    • add support for generating object type field in schema from method with @FieldResolver

    Fixes

    • fix bug when converting object scalars to target class instance (#65)
    Source code(tar.gz)
    Source code(zip)
  • v0.11.0(Apr 24, 2018)

    Features

    • add support for creating and attaching middlewares, guards and interceptors to fields and resolvers
    • Breaking Change: remove deprecated decorators with GraphQL prefix and { array: true } type option
    Source code(tar.gz)
    Source code(zip)
  • v0.10.0(Apr 15, 2018)

    Features

    • add buildSchemaSync function to build the schema synchronously (unsafe! without additional errors checks)
    • update package dependencies
    • Breaking Change: update @types/graphql to 0.13.0

    Fixes

    • decorator option validate is now merged with buildSchema's validate config instead of overwriting it
    Source code(tar.gz)
    Source code(zip)
  • v0.9.1(Apr 3, 2018)

  • v0.9.0(Apr 1, 2018)

    Features

    • add support for GraphQL subscriptions using graphql-subscriptions
    • update package dependencies
    • deprecate { array: true } type option
    Source code(tar.gz)
    Source code(zip)
Owner
Michał Lytek
Full-stack developer with a tendency to perfectionism. GraphQL and TypeScript evangelist, Node.js and React enthusiast. Author of the TypeGraphQL framework.
Michał Lytek
A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications on top of TypeScript & JavaScript (ES6, ES7, ES8) 🚀

A progressive Node.js framework for building efficient and scalable server-side applications. Description Nest is a framework for building efficient,

nestjs 53.2k Dec 31, 2022
Marble.js - functional reactive Node.js framework for building server-side applications, based on TypeScript and RxJS.

Functional reactive Node.js framework for building server-side applications, based on TypeScript and RxJS. Ecosystem Name Description @marblejs/core F

Marble.js 2.1k Dec 16, 2022
Use full ES2015+ features to develop Node.js applications, Support TypeScript.

ThinkJS Use full ES2015+ features to develop Node.js applications, Support TypeScript. 简体中文文档 Installation npm install -g think-cli Create Application

ThinkJS 5.3k Dec 30, 2022
Cross-platform project template using Electron and Angular with the Phaser game engine. Project has Flexbox integrated for easy and responsive organization of components around the Phaser canvas.

Coher3nTS Project This is an Angular project template with Phaser nested inside, set up to run with Electron. Cross-Platform & Responsive The template

Tim B 18 Dec 17, 2022
Catberry is an isomorphic framework for building universal front-end apps using components, Flux architecture and progressive rendering.

Catberry What the cat is that? Catberry was developed to help create "isomorphic/Universal" Web applications. Long story short, isomorphic/universal a

Catberry.js 801 Dec 20, 2022
Expressive middleware for node.js using ES2017 async functions

Expressive HTTP middleware framework for node.js to make web applications and APIs more enjoyable to write. Koa's middleware stack flows in a stack-li

Koa.js 33.5k Jan 4, 2023
🍔 A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 🌈

Midway - 一个面向未来的云端一体 Node.js 框架 English | 简体中文 ?? 欢迎观看 Midway Serverless 2.0 发布会回放: https://www.bilibili.com/video/BV17A411T7Md 《Midway Serverless 发布

Midway.js 6.3k Jan 8, 2023
🥚 Born to build better enterprise frameworks and apps with Node.js & Koa

Features Built-in Process Management Plugin System Framework Customization Lots of plugins Quickstart Follow the commands listed below. $ mkdir showca

egg 18.3k Dec 29, 2022
Fast and low overhead web framework, for Node.js

An efficient server implies a lower cost of the infrastructure, a better responsiveness under load and happy users. How can you efficiently handle the

Fastify 26k Jan 2, 2023
🚀 The Node.js Framework highly focused on developer ergonomics, stability and confidence

Sponsored by FOSS United is a non-profit foundation that aims at promoting and strengthening the Free and Open Source Software (FOSS) ecosystem in Ind

AdonisJS Framework 13.4k Dec 31, 2022
MVC framework making it easy to write realtime, collaborative applications that run in both Node.js and browsers

Derby The Derby MVC framework makes it easy to write realtime, collaborative applications that run in both Node.js and browsers. Derby includes a powe

DerbyJS 4.7k Dec 23, 2022
Actionhero is a realtime multi-transport nodejs API Server with integrated cluster capabilities and delayed tasks

Actionhero The reusable, scalable, and quick node.js API server for stateless and stateful applications NPM | Web Site | Latest Docs | GitHub | Slack

Actionhero 2.3k Jan 4, 2023
:seedling: Next-Gen AI-Assisted Isomorphic Application Engine for Embedded, Console, Mobile, Server and Desktop

lychee.js Mono Repository Important Notes to follow through Installation Quirks: The lycheejs-engine Repository needs to be installed to the path /opt

Cookie Engineer 791 Dec 31, 2022
Easily add filtering, sorting, and pagination to your Node.js REST API through your old friend: the query string!

QueryQL QueryQL makes it easy to add filtering, sorting, and pagination to your Node.js REST API through your old friend: the query string! Read our i

Truepic 99 Dec 27, 2022
A template project for building high-performance, portable, and safe serverless functions in Vercel.

Tutorial | Demo for image processing | Demo for tensorflow This is a Next.js project bootstrapped with create-next-app. This project is aimed to demon

Second State 63 Dec 8, 2022
Learn GraphQL by building a blogging engine. Create resolvers, write schemas, write queries, design the database, test and also deploy.

GraphQL Blog graphqlblog.com Learn GraphQL by building a blogging engine. Create resolvers, write schemas, write queries, design the database, test an

GraphQLApps 6 Aug 17, 2022
just a graphql example created by typescript + fastify + mikro-orm(postgresql) + mercurius(graphql adaptor) + type-graphql

fastify-mikro-orm-mercurius-graphql-example A MikroORM boilerplate for GraphQL made with Fastify, Mercurius, Typescript using TypeGraphQL ?? Packages

Vigen 10 Aug 28, 2022
🤖 Tailwind CSS assistant helps you to edit classes (includes JIT & ignores purge), toggle breakpoint classes on an element and view current breakpoint

Tailwind CSS Assistant See it in action on this example website ?? ✅ Small JavaScript package that helps you work with Tailwind CSS by... Showing you

Mark Mead 30 Dec 28, 2022
The fastest JSON schema Validator. Supports JSON Schema draft-04/06/07/2019-09/2020-12 and JSON Type Definition (RFC8927)

Ajv JSON schema validator The fastest JSON validator for Node.js and browser. Supports JSON Schema draft-06/07/2019-09/2020-12 (draft-04 is supported

Ajv JSON schema validator 12k Jan 4, 2023
A simple CLI to generate a starter schema for keystone-6 from a pre-existing prisma schema.

Prisma2Keystone A tool for converting prisma schema to keystone schema typescript This is a proof of concept. More work is needed Usage npx prisma2key

Brook Mezgebu 17 Dec 17, 2022