GithubHelp home page GithubHelp logo

graphql-schema-typescript's People

Contributors

adamxklarna avatar alecdwm avatar baseonmars avatar chrisae avatar dangcuuson avatar dependabot[bot] avatar deser avatar igorrmotta avatar ingusskaistkalns avatar mattcfilbert avatar monvillalon avatar rasmusfaber avatar tony avatar useless-stuff avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

graphql-schema-typescript's Issues

TResult type idea

Hi,
I am trying out the push the types in resolvers to the limit with new options :-).

In my use case TParent is usually needed to retype to the model types (as often some additional fields that are not exposed via graphql are being used), but that still looks very good as it can be nicely defined per graphql type, like this :

  type Study {
    _id: ObjectId!
    ready: Bool!
    studyDescription: StudyDescription!
    referringPhysicians: [ReferringPhysician]! 
  }


const studyResolvers: GQLStudyTypeResolver<MStudy> = {
  referringPhysicians(study, {}, ctx) {
    return loadReferringPhysicianByIds(ctx, study.referringPhysicianIds);
  },
  studyDescription(study, {}, ctx) {
    if (!study.studyDescriptionId) {
      return null;
    }
    return loadStudyDescriptionById(ctx, study.studyDescriptionId);
  },
};

But thinking about following improvement that I believe could make the result type significantly more useful, don't know how difficult be to add that in.

In this example smartTResult type requires that resolver which is returning GQLStudy would have return all fields (_id, read, studyDescription and referringPhysicians), but in fact since Study type has own resolvers for referringPhysicians and studyDescription ideally it should not require these fields (make them optional) when resolving Study type and require only _id and ready.

That would require to not just look at what type is being returned, but also look into the resolvers if there are some field resolvers.

What do you think, does it make sense?

There can be only one type named "Date".

Hi! I'm trying to convert Gitlab graphql schema using this CLI.

Here is the output:

npx graphql-schema-typescript generate-ts .     
Message:  null
Error:  Error: Unknown type "ID".
[](url)
Unknown type "ID".

There can be only one type named "Date".

There can be only one type named "User".

Field "User.email" can only be defined once.

Field "User.username" can only be defined once.

Could you please have a look at this file and to tell what's wrong with it? OR may be there is an error in the parser.

schema.zip

Methods not included when using 'extend'

Firstly, thanks for this tool. It's been really great to have my resolvers strongly typed with minimal effort. I've recently been trying out a new modular pattern which has led me to a problem.

Problem

When I use extend to break up my type definitions I don't see the extended values in the type.

Example

Prior to splitting the modules out I have a TypeScript type that accurately describes the resolvers for Query.

type Dog {
  imageUrl: String!
}

type Query {
  dogs(limit: Int): [Dog!]
}
export interface GQLQueryTypeResolver<TParent = undefined> {
  dogs?: QueryToDogsResolver<TParent>;
}

But as I want to add more to the schema I look to add something like:

type Cat {
  imageUrl: String!
}

type Query {
  cats(breed: String!, limit: Int): [Cat!]
}

Which of-course isn't valid, as I've now defined Query twice.

To keep the code nice and clean I give the Query a base definition, and use extend in the seperate modules:

type Query {
  _empty: String
}
extend type Query {...

However, now the Query definition shows only _empty and not the extended values:

export interface GQLQueryTypeResolver<TParent = undefined> {
  _empty?: QueryTo_emptyResolver<TParent>;
}

Ideal

Ideally I want to see something like below. Is this possible? If not is there a reason the extended types shouldn't be concatenated together?
If it's not currently possible, and it's not a terrible idea would you be open to a PR?

export interface GQLQueryTypeResolver<TParent = undefined> {
  _empty?: QueryTo_emptyResolver<TParent>;
  cats?: QueryToCatsResolver<TParent>;
  dogs?: QueryToDogsResolver<TParent>;
}

Fails with wrong error when graphql file has syntax error

When trying to generate typescript code from an invalid graphql file:

$ graphql-schema-typescript generate-ts generate-ts src/chema.graphql
Message:  null
Error:  { GraphQLError: Syntax Error: Cannot parse the unexpected character "/".
    at syntaxError (/Users/ldiqual/Siteline/siteline/node_modules/graphql/error/syntaxError.js:15:10)
    at readToken (/Users/ldiqual/Siteline/siteline/node_modules/graphql/language/lexer.js:270:38)
    at Object.lookahead (/Users/ldiqual/Siteline/siteline/node_modules/graphql/language/lexer.js:54:43)
    at Object.advanceLexer [as advance] (/Users/ldiqual/Siteline/siteline/node_modules/graphql/language/lexer.js:44:33)
    at Parser.expectToken (/Users/ldiqual/Siteline/siteline/node_modules/graphql/language/parser.js:1398:19)
    at Parser.many (/Users/ldiqual/Siteline/siteline/node_modules/graphql/language/parser.js:1514:10)
    at Parser.parseDocument (/Users/ldiqual/Siteline/siteline/node_modules/graphql/language/parser.js:111:25)
    at parse (/Users/ldiqual/Siteline/siteline/node_modules/graphql/language/parser.js:36:17)
    at Object.buildSchema (/Users/ldiqual/Siteline/siteline/node_modules/graphql/utilities/buildASTSchema.js:462:43)
    at Object.<anonymous> (/Users/ldiqual/Siteline/siteline/node_modules/graphql-schema-typescript/lib/index.js:98:42)
  message: 'Syntax Error: Cannot parse the unexpected character "/".',
  locations: [ { line: 1, column: 1 } ] }

What happens is that https://github.com/dangcuuson/graphql-schema-typescript/blob/master/src/index.ts#L53 parses the schema file from a path, and it throws because there's a syntax error, but then the error is silenced and the code tries to parse the actual path string, which results in the error above.

Please add support of graphql schema as string type

Right now its only support input as GraphQLSchema or path of schema but in some cases like where we using graphql-import then in this case it throws an error. It should be nice to have an option to pass schema as string.
For example :
const { generateTypeScriptTypes } = require("graphql-schema-typescript"); generateTypeScriptTypes("type Query{ hello: string }", path);

option to set nullable properties to `property?: string | null`

I'm using TypeORM and in my entities, I got properties which are defined as property?: string | null so its type is string | null | undefined. This creates conflicts with the types I get from the generated types of nullable properties from my graphql schema.

Maybe we can add an option to define nullable properties to property?: string | null instead of the normal property?: string.

Add option for prepending timestamp to generated file

I love this tool! ๐Ÿ˜ It was exactly what I looked for. Thanks so much!

It would be cool though with an option (or even as a default) to have a timestamp added to the top of the generated types .ts file, in order to quickly diff the version at a glance.

Something like:

import { GraphQLResolveInfo } from 'graphql';

/**
 * This file is auto-generated by graphql-schema-typescript
 * Please note that any changes in this file may be overwritten
 *
 * Generated at 2018-07-20T23:01:01
 */

/* tslint:disable */ 
/*******************************
 *                             
 *          TYPE DEFS          
 *                             
 *******************************/

Let me know if I can provide a PR for this.

CLI doesn't take the folderName argument.

I'm following the graphql-schema-typescript generate-ts --help. It says

graphql-schema-typescript generate-ts <folderPath>

But CLI doesn't take the folderName argument.

$ npx graphql-schema-typescript generate-ts graphql
Message:  null
Error:  GraphQLError: Syntax Error: Unexpected Name "gql"

I tried ./graphql or full-path, but nothing changes.

Apollo Federation Support

This tool looks incredibly helpful, however I'm running into a blocker thats stopping me being able to use unfortunately.

My Schema is distributed using Apollo's Managed Federation, which essentially means the schema may or may not have some types explicitly defined. For example I may have a schema like:

extend type User @key(fields: "id") {
  id: ID! @external
}
type Product {
  id: ID!
  name: String!
  created_by: User!
}

In this case, User is stubbed out and resolved by a different service, and when attempting to generate types, I get the following

Error: Unknown type "User".

Cannot extend type "Mutation" because it is not defined.

Cannot extend type "Query" because it is not defined.

Cannot extend type "User" because it is not defined.

I think a resolution to this would be to essentially not require a "base" definition of a type (User in this case). Though of course this would affect non-federated schema's, so making it a config option would be needed.

The other issue that arises is the directives used (key & external in this example), as these aren't defined either by each service.

Apollo's schema for directives is the following:

scalar _Any
scalar _FieldSet

# a union of all types that use the @key directive
union _Entity

type _Service {
  sdl: String
}

extend type Query {
  _entities(representations: [_Any!]!): [_Entity]!
  _service: _Service!
}

directive @external on FIELD_DEFINITION
directive @requires(fields: _FieldSet!) on FIELD_DEFINITION
directive @provides(fields: _FieldSet!) on FIELD_DEFINITION
directive @key(fields: _FieldSet!) on OBJECT | INTERFACE

# this is an optional directive discussed below
directive @extends on OBJECT | INTERFACE

Currently I am just prepending this to my schema at the time of generation, but it would be nice if the federation config option prepended this itself perhaps

Share repo / npm to make publishing easier?

@dangcuuson

Thank you for the project!

In terms of keeping this package up to date, Are you open to sharing NPM and repo to more maintainers to make it easier to catch up graphql releases and maintain? What do you think? Are you open to making an organization?

If so I'm interested (and maybe others). I am currently publishing to an a forked organizational package in the mean time.

Support more recent versions of `graphql`

Please look into supporting more recent versions of graphql. For example, it wouldn't work with version 14.0.0 and above in the path, and I spent a couple hours diagnosing this and #45. Thanks.

Resolving Union Types

First of all, thank you for this awesome library! It has been so much easier to get up and running with TypeScript and GraphQL.

I have in a situation, where I need to resolve a union type property in my schema:

type UnitEvent {
  id: String!
  details: UnitEventDetails
}

union UnitEventDetails = DamageReportEvent | CanErrorEvent

type DamageReportEvent {
  damageReportId: String
}

type CanErrorEvent {
  canErrorId: String
}

In my 'UnitEventResolver` I have the following:

const unitEventResolver: GQLUnitEventTypeResolver<IUnitEventApiResponse> = {
  id: parent => {
    return parent.eventId;
  },
  details: parent => {
    return parent;
  }
};

export default unitEventResolver;

Then in my UnitEventDetailsResolver I have:

const unitEventDetailsResolver: GQLUnitEventDetailsTypeResolver = (
  parent: IUnitEventApiResponse
) => {
  switch (parent.type) {
    case 1:
      return "DamageReportEvent";
    case 7:
      return "CanErrorEvent";
  }
};

export default unitEventDetailsResolver;

And finally in my CanErrorEventResolver:

const canErrorEventResolver: GQLCanErrorEventTypeResolver<
  IUnitEventApiResponse
> = {
  canErrorId: parent => {
    return parent.data.canErrorId;
  }
};

export default canErrorEventResolver;

However, I am getting this message:

"message": "Abstract type UnitEventDetails must resolve to an Object type at runtime for field UnitEvent.details with value { [REDACTED], type: 7, [REDACTED] }, received "undefined". Either the UnitEventDetails type should provide a "resolveType" function or each possible type should provide an "isTypeOf" function."

I am also getting this in the console:

Type "UnitEventDetails" is missing a "__resolveType" resolver. Pass false into "resolverValidationOptions.requireResolversForResolveType" to disable this warning.

I have tried messing around with the types, but unable to make it work?

Can you point me in a direction to solve this?

Thanks!

typed resolvers

Hi, this is great project, exactly what I was looking for!

As you say in readme, resolver result is any at this moment and can be explicitly defined in resolvers. I am wondering what was the reason to leave results as any? Are you considering to have option that would also type the results of resolvers?

Graphql 15: Syntax Error: Unexpected Name "folder_name"

I'm trying to generate my types with yarn graphql-schema-typescript generate-ts graphql and getting this error:

Message:  null
Error:  GraphQLError [Object]: Syntax Error: Unexpected Name "graphql".
    at syntaxError (/Users/sam/vytal/partner_app/node_modules/graphql/error/syntaxError.js:15:10)
    at Parser.unexpected (/Users/sam/vytal/partner_app/node_modules/graphql/language/parser.js:1482:41)
    at Parser.parseDefinition (/Users/sam/vytal/partner_app/node_modules/graphql/language/parser.js:155:16)
    at Parser.many (/Users/sam/vytal/partner_app/node_modules/graphql/language/parser.js:1537:26)
    at Parser.parseDocument (/Users/sam/vytal/partner_app/node_modules/graphql/language/parser.js:109:25)
    at parse (/Users/sam/vytal/partner_app/node_modules/graphql/language/parser.js:36:17)
    at Object.buildSchema (/Users/sam/vytal/partner_app/node_modules/graphql/utilities/buildASTSchema.js:116:36)
    at Object.<anonymous> (/Users/sam/vytal/partner_app/node_modules/graphql-schema-typescript/lib/index.js:94:42)
    at step (/Users/sam/vytal/partner_app/node_modules/graphql-schema-typescript/lib/index.js:40:23)
    at Object.throw (/Users/sam/vytal/partner_app/node_modules/graphql-schema-typescript/lib/index.js:21:53) {
  locations: [ { line: 1, column: 1 } ]
}

My gql config is located in graphql/graphql.config
My project is using graphql: 15.3.0, node: 14.12.0

I have a very similar setup in another project that uses graphql: 14.7.0, and there everything works fine. When I use 14.7.0 in this project, ts type generation also works fine. So there must be some breaking changes in 14->15 that graphql-schema-typescript is not handling yet.

Any idea how to fix this without reverting my entire project back to graphql 14?

Unable to see Typescript suggestions to resolver returns when `asyncResult` is set to `true`

When I set asyncResult option to true, the return type of the resolvers are set to TResult | Promise<TResult> as indicated in the docs, but when I use Ctrl + Space to see suggestions in my resolver returns, it does not give me field suggestions for the TResult. However, when I change all of the resolver return types from TResult | Promise<TResult> to Promise<TResult>, I am already able to see field suggestions. Can we add an option to set resolver return types to Promise<TResult> only? Will it produce undesired side effects?

I'm not sure if it's because of my typescript configuration or not, and I'm still new in Typescript.
I'm using VS Code as my editor.

Getting GraphQLError: Syntax Error: Cannot parse the unexpected character

When running graphql-schema-typescript generate-ts ./src/datamodel/testSchema.graphql --output ./src/datamodel/testSchema.d.ts from my package.json script:

"generate:schema": "graphql-schema-typescript generate-ts ./src/datamodel/testSchema.graphql --output ./src/datamodel/testSchema.d.ts"

I get the following error:

$ graphql-schema-typescript generate-ts ./src/datamodel/testSchema.graphql --output ./src/datamodel/testSchema.d.ts
Message:  null
Error:  GraphQLError: Syntax Error: Cannot parse the unexpected character ".".
    at syntaxError (/root/ziina/monorepo/graphqlserver/node_modules/graphql/error/syntaxError.js:15:10)
    at readToken (/root/ziina/monorepo/graphqlserver/node_modules/graphql/language/lexer.js:270:38)
    at Object.lookahead (/root/ziina/monorepo/graphqlserver/node_modules/graphql/language/lexer.js:54:43)
    at Object.advanceLexer [as advance] (/root/ziina/monorepo/graphqlserver/node_modules/graphql/language/lexer.js:44:33)
    at Parser.expectToken (/root/ziina/monorepo/graphqlserver/node_modules/graphql/language/parser.js:1399:19)
    at Parser.many (/root/ziina/monorepo/graphqlserver/node_modules/graphql/language/parser.js:1514:10)
    at Parser.parseDocument (/root/ziina/monorepo/graphqlserver/node_modules/graphql/language/parser.js:111:25)
    at parse (/root/ziina/monorepo/graphqlserver/node_modules/graphql/language/parser.js:36:17)
    at Object.buildSchema (/root/ziina/monorepo/graphqlserver/node_modules/graphql/utilities/buildASTSchema.js:462:43)
    at Object.<anonymous> (/root/ziina/monorepo/graphqlserver/node_modules/graphql-schema-typescript/lib/index.js:94:42) {
  message: 'Syntax Error: Cannot parse the unexpected character ".".',
  locations: [ { line: 1, column: 1 } ]
}
error Command failed with exit code 1.

I've tried with escaping double quotes, single quotes, etc.
I've also tried to use the testSchema.graphql from the __tests__ to no avail.

Seems like a parse issue with the directory paths?

Expected Behavior when there are no possibleTypes

How is this library supposed to behave when there are no in possibleTypes, e.g. on an interface that extends nothing?

File detail.graphql

schema {
  query: Query
}

type Query {
  getDetail: Detail
}

interface Detail {
  name: String!
  value: Float
}

File output.d.ts

// lots of lines omitted...

export interface DetailTypeResolver<TParent = any> {
  (parent: TParent, context: any, info: GraphQLResolveInfo):  | Promise<>; // <--- notice empty return type and no Promise return type
}

Debugger after evaluating const introspectResult = await getIntrospectResult(); here shows no possibleTypes (empty array):
image

My question is what is the intended output or if this is a bug, what is the expected output?

[feat request] "Non-Optional Resolver Functions" option

Hi, first thanks for your work! It's really useful.

I was developing a class implementing the QueryResolvers interface, but one of the things I wanted was to make sure that all resolvers are implemented, to make sure that if some mutation/query is added, the corresponding resolver is there. Does it makes sense?

class MyResolvers implements QueryResolvers.Resolvers {
//no error because the resolvers are optional
}
export namespace QueryResolvers {
  export interface Resolvers {
    getSomething?: getSomethingResolver;
  }
}

Hopefully it makes sense and it's easy to implement :)
Thanks again!

CLI not working on mac

./node_modules/.bin/graphql-schema-typescript generate-ts --help
env: node\r: No such file or directory

node is installed ofc. Issue with line endings?

Need help on GraphQL Union Resolver

Hi,
I have defined a Schema with union. However the resolved is throwing the following run time error:

I have attached the schema.js and index.js text. Please help me in rectifying the resolver of the union type.

schema.js

import { buildSchema } from 'graphql';

const schema = buildSchema(`

union AgendaItem = StudyGroup | Workout

type StudyGroup {
    name: String!
}

type Workout {
    subject: String
}

type Query {
    agenda: [AgendaItem!]
 }

index.js

import express from 'express';
import graphqlHTTP from 'express-graphql';
import schema from './schema';

const app = express();

app.get('/', (req,res) => {
res.send('Graph QL is amazing!');
});

// Custom Functions

function responseToQuery(obj){
return [
{"name": "Rudra"},
{"name": "Ram"}
]
}

const root = { agenda: (obj) => responseToQuery(obj) };

app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue: root,
graphiql: true,
}));

app.listen(9090, () => console.log('Running server on port localhost:9090/graphql'));

ERROR

"errors": [
{
"message": "Abstract type AgendaItem must resolve to an Object type at runtime for field Query.agenda with value { name: "Rudra" }, received "undefined". Either the AgendaItem type should provide a "resolveType" function or each possible type should provide an "isTypeOf" function.",

Types is overwriting instead merging

Hi,

I using grahpQL Modules and all my schema.graphql are separeted in modules.
My problem is:
I have one type in one module, after this, i declare this type again injecting other property.
But when i generat the interfase only the last type is considered.
Example

In Doctor Module:
type Doctor {
id: ID!
name: String!
birth: String
}

In Specialty Module:
type Doctor {
specialties: [Specialty]
}

Bu when i generate interfaces:
export interface GQLDoctor {
specialties?: Array<GQLSpecialty | null>;
}

I use this function to merge schemas:

const genSchema = async () => {
	const schemas: GraphQLSchema[] = [];
	const folders = readdirSync(join(__dirname, "../modules")).filter(f => !f.includes("."));

	folders.forEach(folder => {
		const typeDefs = importSchema(join(__dirname, ../modules/${folder}/schema.graphql`));
		schemas.push(makeExecutableSchema({ typeDefs }));
	});
	await generateTypeScriptTypes(
		mergeSchemas({ schemas }),
		join(__dirname, "../types/schemas.d.ts")
	);
};

Support for Graphql-js 16

Hello, seems that library is incompatible with graphql-js 6

node node_modules/.bin/graphql-schema-typescript generate-ts schema.graphql --output app/javascript/graphqlSchema.ts
Message:  null
Error:  Error: Expected undefined to be a GraphQL schema. 
    at assertSchema (.../node_modules/graphql/type/schema.js:35:11)
    at validateSchema (.../node_modules/graphql/type/validate.js:34:28)
    at graphqlImpl (.../node_modules/graphql/graphql.js:52:64)
    at .../node_modules/graphql/graphql.js:21:43
    at new Promise (<anonymous>)
    at Object.graphql (.../node_modules/graphql/graphql.js:21:10)
    at .../node_modules/graphql-schema-typescript/lib/utils.js:58:52
    at step (.../node_modules/graphql-schema-typescript/lib/utils.js:33:23)
    at Object.next (.../wasteapp/node_modules/graphql-schema-typescript/lib/utils.js:14:53)
    at .../node_modules/graphql-schema-typescript/lib/utils.js:8:71

can this support generating enum with given values?

GraphQL allows enum with allow values in resolvers
https://www.apollographql.com/docs/apollo-server/schema/schema/#internal-values-advanced

but this is generating always the enum's literal string value, is there anyway can support given values?

https://blog.logrocket.com/what-you-need-to-know-about-graphql-enums/

to make GraphQL

enum AuthType {
 GOOGLE =  'google-auth',
 GITHUB =  'github-auth',
 OUTLOOK = 'outlook-auth',
}

to generate TypeScript

export const enum AuthType {
 GOOGLE =  'google-auth',
 GITHUB =  'github-auth',
 OUTLOOK = 'outlook-auth',
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.