paljs / prisma-tools

Prisma tools to help you generate CRUD system for GraphQL servers
https://paljs.com
MIT License
683 stars 54 forks source link

TypeError: Cannot convert undefined or null to object #160

Closed unlight closed 3 years ago

unlight commented 3 years ago

image

Evaluates to

Object.keys(undefined)

Info object

{ "fieldName": "articles", "fieldNodes": [ { "kind": "Field", "alias": { "kind": "Name", "value": "articles", "loc": { "start": 19, "end": 27 } }, "name": { "kind": "Name", "value": "articles", "loc": { "start": 29, "end": 37 } }, "arguments": [ { "kind": "Argument", "name": { "kind": "Name", "value": "where", "loc": { "start": 38, "end": 43 } }, "value": { "kind": "ObjectValue", "fields": [], "loc": { "start": 45, "end": 47 } }, "loc": { "start": 38, "end": 47 } }, { "kind": "Argument", "name": { "kind": "Name", "value": "orderBy", "loc": { "start": 49, "end": 56 } }, "value": { "kind": "ObjectValue", "fields": [ { "kind": "ObjectField", "name": { "kind": "Name", "value": "id", "loc": { "start": 59, "end": 61 } }, "value": { "kind": "EnumValue", "value": "desc", "loc": { "start": 63, "end": 67 } }, "loc": { "start": 59, "end": 67 } } ], "loc": { "start": 58, "end": 68 } }, "loc": { "start": 49, "end": 68 } } ], "directives": [], "selectionSet": { "kind": "SelectionSet", "selections": [ { "kind": "FragmentSpread", "name": { "kind": "Name", "value": "articleFields", "loc": { "start": 79, "end": 92 } }, "directives": [], "loc": { "start": 76, "end": 92 } } ], "loc": { "start": 70, "end": 96 } }, "loc": { "start": 19, "end": 96 } } ], "returnType": "[Article!]!", "parentType": "Query", "path": { "key": "articles", "typename": "Query" }, "schema": { "__validationErrors": [], "extensionASTNodes": [], "_queryType": "Query", "_mutationType": "Mutation", "_directives": [ "@include", "@skip", "@deprecated", "@specifiedBy" ], "_typeMap": { "User": "User", "ID": "ID", "String": "String", "Boolean": "Boolean", "Comment": "Comment", "Article": "Article", "Int": "Int", "Tag": "Tag", "Query": "Query", "ArticleWhereInput": "ArticleWhereInput", "StringFilter": "StringFilter", "TagListRelationFilter": "TagListRelationFilter", "TagWhereInput": "TagWhereInput", "ArticleListRelationFilter": "ArticleListRelationFilter", "DateTimeFilter": "DateTimeFilter", "IntFilter": "IntFilter", "UserWhereInput": "UserWhereInput", "UserListRelationFilter": "UserListRelationFilter", "CommentListRelationFilter": "CommentListRelationFilter", "CommentWhereInput": "CommentWhereInput", "ArticleOrderByInput": "ArticleOrderByInput", "SortOrder": "SortOrder", "ArticleWhereUniqueInput": "ArticleWhereUniqueInput", "ArticleDistinctFieldEnum": "ArticleDistinctFieldEnum", "UserWhereUniqueInput": "UserWhereUniqueInput", "Mutation": "Mutation", "ArticleCreateInput": "ArticleCreateInput", "ArticleUpdateInput": "ArticleUpdateInput", "CreateCommentInput": "CreateCommentInput", "CommentWhereUniqueInput": "CommentWhereUniqueInput", "UserCreateInput": "UserCreateInput", "UserUpdateInput": "UserUpdateInput", "UserLoginInput": "UserLoginInput", "__Schema": "__Schema", "__Type": "__Type", "__TypeKind": "__TypeKind", "__Field": "__Field", "__InputValue": "__InputValue", "__EnumValue": "__EnumValue", "__Directive": "__Directive", "__DirectiveLocation": "__DirectiveLocation" }, "_subTypeMap": {}, "_implementationsMap": {}, "_extensionsEnabled": true }, "fragments": { "articleFields": { "kind": "FragmentDefinition", "name": { "kind": "Name", "value": "articleFields", "loc": { "start": 151, "end": 164 } }, "typeCondition": { "kind": "NamedType", "name": { "kind": "Name", "value": "Article", "loc": { "start": 168, "end": 175 } }, "loc": { "start": 168, "end": 175 } }, "directives": [], "selectionSet": { "kind": "SelectionSet", "selections": [ { "kind": "Field", "name": { "kind": "Name", "value": "slug", "loc": { "start": 180, "end": 184 } }, "arguments": [], "directives": [], "loc": { "start": 180, "end": 184 } }, { "kind": "Field", "name": { "kind": "Name", "value": "title", "loc": { "start": 187, "end": 192 } }, "arguments": [], "directives": [], "loc": { "start": 187, "end": 192 } }, { "kind": "Field", "name": { "kind": "Name", "value": "description", "loc": { "start": 195, "end": 206 } }, "arguments": [], "directives": [], "loc": { "start": 195, "end": 206 } }, { "kind": "Field", "name": { "kind": "Name", "value": "body", "loc": { "start": 209, "end": 213 } }, "arguments": [], "directives": [], "loc": { "start": 209, "end": 213 } }, { "kind": "Field", "name": { "kind": "Name", "value": "tags", "loc": { "start": 216, "end": 220 } }, "arguments": [], "directives": [], "selectionSet": { "kind": "SelectionSet", "selections": [ { "kind": "Field", "name": { "kind": "Name", "value": "name", "loc": { "start": 227, "end": 231 } }, "arguments": [], "directives": [], "loc": { "start": 227, "end": 231 } } ], "loc": { "start": 221, "end": 235 } }, "loc": { "start": 216, "end": 235 } }, { "kind": "Field", "name": { "kind": "Name", "value": "createdAt", "loc": { "start": 238, "end": 247 } }, "arguments": [], "directives": [], "loc": { "start": 238, "end": 247 } }, { "kind": "Field", "name": { "kind": "Name", "value": "updatedAt", "loc": { "start": 250, "end": 259 } }, "arguments": [], "directives": [], "loc": { "start": 250, "end": 259 } }, { "kind": "Field", "name": { "kind": "Name", "value": "favorited", "loc": { "start": 262, "end": 271 } }, "arguments": [], "directives": [], "loc": { "start": 262, "end": 271 } }, { "kind": "Field", "name": { "kind": "Name", "value": "favoritesCount", "loc": { "start": 274, "end": 288 } }, "arguments": [], "directives": [], "loc": { "start": 274, "end": 288 } }, { "kind": "Field", "name": { "kind": "Name", "value": "author", "loc": { "start": 291, "end": 297 } }, "arguments": [], "directives": [], "selectionSet": { "kind": "SelectionSet", "selections": [ { "kind": "FragmentSpread", "name": { "kind": "Name", "value": "userFields", "loc": { "start": 307, "end": 317 } }, "directives": [], "loc": { "start": 304, "end": 317 } }, { "kind": "Field", "name": { "kind": "Name", "value": "following", "loc": { "start": 322, "end": 331 } }, "arguments": [], "directives": [], "loc": { "start": 322, "end": 331 } } ], "loc": { "start": 298, "end": 335 } }, "loc": { "start": 291, "end": 335 } } ], "loc": { "start": 176, "end": 337 } }, "loc": { "start": 142, "end": 337 } }, "userFields": { "kind": "FragmentDefinition", "name": { "kind": "Name", "value": "userFields", "loc": { "start": 348, "end": 358 } }, "typeCondition": { "kind": "NamedType", "name": { "kind": "Name", "value": "User", "loc": { "start": 362, "end": 366 } }, "loc": { "start": 362, "end": 366 } }, "directives": [], "selectionSet": { "kind": "SelectionSet", "selections": [ { "kind": "Field", "alias": { "kind": "Name", "value": "username", "loc": { "start": 371, "end": 379 } }, "name": { "kind": "Name", "value": "name", "loc": { "start": 381, "end": 385 } }, "arguments": [], "directives": [], "loc": { "start": 371, "end": 385 } }, { "kind": "Field", "name": { "kind": "Name", "value": "email", "loc": { "start": 388, "end": 393 } }, "arguments": [], "directives": [], "loc": { "start": 388, "end": 393 } }, { "kind": "Field", "name": { "kind": "Name", "value": "bio", "loc": { "start": 396, "end": 399 } }, "arguments": [], "directives": [], "loc": { "start": 396, "end": 399 } }, { "kind": "Field", "name": { "kind": "Name", "value": "image", "loc": { "start": 402, "end": 407 } }, "arguments": [], "directives": [], "loc": { "start": 402, "end": 407 } } ], "loc": { "start": 367, "end": 409 } }, "loc": { "start": 339, "end": 409 } } }, "operation": { "kind": "OperationDefinition", "operation": "query", "name": { "kind": "Name", "value": "articles", "loc": { "start": 6, "end": 14 } }, "variableDefinitions": [], "directives": [], "selectionSet": { "kind": "SelectionSet", "selections": [ { "kind": "Field", "alias": { "kind": "Name", "value": "articles", "loc": { "start": 19, "end": 27 } }, "name": { "kind": "Name", "value": "articles", "loc": { "start": 29, "end": 37 } }, "arguments": [ { "kind": "Argument", "name": { "kind": "Name", "value": "where", "loc": { "start": 38, "end": 43 } }, "value": { "kind": "ObjectValue", "fields": [], "loc": { "start": 45, "end": 47 } }, "loc": { "start": 38, "end": 47 } }, { "kind": "Argument", "name": { "kind": "Name", "value": "orderBy", "loc": { "start": 49, "end": 56 } }, "value": { "kind": "ObjectValue", "fields": [ { "kind": "ObjectField", "name": { "kind": "Name", "value": "id", "loc": { "start": 59, "end": 61 } }, "value": { "kind": "EnumValue", "value": "desc", "loc": { "start": 63, "end": 67 } }, "loc": { "start": 59, "end": 67 } } ], "loc": { "start": 58, "end": 68 } }, "loc": { "start": 49, "end": 68 } } ], "directives": [], "selectionSet": { "kind": "SelectionSet", "selections": [ { "kind": "FragmentSpread", "name": { "kind": "Name", "value": "articleFields", "loc": { "start": 79, "end": 92 } }, "directives": [], "loc": { "start": 76, "end": 92 } } ], "loc": { "start": 70, "end": 96 } }, "loc": { "start": 19, "end": 96 } }, { "kind": "Field", "alias": { "kind": "Name", "value": "articlesCount", "loc": { "start": 99, "end": 112 } }, "name": { "kind": "Name", "value": "countArticles", "loc": { "start": 114, "end": 127 } }, "arguments": [ { "kind": "Argument", "name": { "kind": "Name", "value": "where", "loc": { "start": 128, "end": 133 } }, "value": { "kind": "ObjectValue", "fields": [], "loc": { "start": 135, "end": 137 } }, "loc": { "start": 128, "end": 137 } } ], "directives": [], "loc": { "start": 99, "end": 138 } } ], "loc": { "start": 15, "end": 140 } }, "loc": { "start": 0, "end": 140 } }, "variableValues": {}, "cacheControl": { "cacheHint": { "maxAge": 0 } } }
AhmedElywa commented 3 years ago

Can you give me your frontend requested fields, please?

unlight commented 3 years ago
query articles {
  articles: articles(where: {}, orderBy: { id: desc }) {
    ...articleFields
  }
  articlesCount: countArticles(where: {})
}

fragment articleFields on Article {
  slug
  title
  description
  body
  tags {
    name
  }
  createdAt
  updatedAt
  favorited
  favoritesCount
  author {
    ...userFields
    following
  }
}

fragment userFields on User {
  username: name
  email
  bio
  image
}
AhmedElywa commented 3 years ago

Can you upgrade to the last version 2.8.4 and check again?

unlight commented 3 years ago

Checked with 2.8.4 still same error. I just realized that bug is probably wrongly. Part of schema:

model User {
// ...
userId String @id
following   User[]   @relation("UserFollows", references: [userId])
}

following is array of users

I do not need this behavior (expose this field to graphql schema), and override this by NestJS decorator ResolveField

    @ResolveField(() => Boolean)
    async following(
        @Parent() user: User,
        @CurrentUser() currentUser?: PassportUserFields,
    ): Promise<boolean> {
        // implementation
    }

Then I found piece of code

var client = require('@prisma/client');
require('@prisma/client/runtime');
//...
_proto.model = function model(name) {
    var _this$dataModel;

    return (_this$dataModel = this.dataModel) === null || _this$dataModel === void 0 ? void 0 : _this$dataModel.models.find(function (item) {
      return item.name === name || PrismaSelect.getModelMap(item.documentation, name);
    });
  };

Looks like select some how depend on generated dmmf of prisma client.

Which is looks weird for me.

AhmedElywa commented 3 years ago

You can't do it like this. My plugin converts GraphQL fields to be Prisma Select objects. So now my plugin will deal with the following field as a User object. Please, you can use another name for your field, not in. Your model.

unlight commented 3 years ago

I do not understand why it is necessary. Can you explain why plugin relies on dmmf? This is the old implementation https://github.com/frandiox/graphql-info-transformer/blob/master/index.js of similar behavior (only graphql info ast is used).

AhmedElywa commented 3 years ago

Because if you added in your graphql type any fields, not in your prisma model and I added them to select object, this will break your prisma query I must filter your fields coming from Info and just give you what you can send to a Prisma select object