graphql-compose-mongoose icon indicating copy to clipboard operation
graphql-compose-mongoose copied to clipboard

Inconsistency with mongoose custom types

Open Zleub opened this issue 2 years ago • 0 comments

Hello !

Before all, i've been fiddling with this library for a few months now, thank you for putting work into it ! That's a really nice idea.

I've noticed a small issue with how mongoose is handling types on their side : a mongoose path can be either declared as a reference to the subschema directly or as the name of the custom type (if registered in mongoose beforehand)

This leads to compose-mongoose not being able to pick up a custom type and typing it as JSON.

Here a example you can run, the main thing to notice being the declaration of UserProfile and Article schemas :

import mongoose, { Schema } from 'mongoose';
import { schemaComposer } from 'graphql-compose'; // get the default schemaComposer or your created schemaComposer
import { convertSchemaToGraphQL } from 'graphql-compose-mongoose';
import { composeMongoose } from 'graphql-compose-mongoose';

// the embedded schema
const ImageDataStructure = new Schema({
  url: String,
  dimensions : {
    width: Number,
    height: Number
  }
}, { _id: false });

// A class declaration of a schemaType so mongoose is pleased
class IMG extends mongoose.SchemaType {
    constructor(key: string, options: any) {
      super(key, options, 'ImageDataStructure');
    }

    cast(val: any) { return val; }
  }
  
/* @ts-ignore */
mongoose.SchemaTypes["ImageDataStructure"] = IMG

const UserProfile = new Schema({
  fullName: String,
  personalImage: ImageDataStructure
});

const Article = new Schema({
  title: String,
  heroImage: "ImageDataStructure"
});

convertSchemaToGraphQL(ImageDataStructure, 'ImageDataStructure', schemaComposer); // Force this type on this mongoose schema

const UserProfileModel = mongoose.model('UserProfile', UserProfile);
const ArticleModel = mongoose.model('Article', Article);

const UserProfileTC = composeMongoose(UserProfileModel);
const ArticleTC = composeMongoose(ArticleModel);

schemaComposer.Query.addFields({
    userById: UserProfileTC.mongooseResolvers.findById(),
    articleById: ArticleTC.mongooseResolvers.findById(),
})

schemaComposer.buildSchema()
console.log( schemaComposer.toSDL() )

Which lead to the following output (truncated) :

type Article {
  title: String
  heroImage: JSON
  _id: MongoID!
}

type ImageDataStructure {
  url: String
  dimensions: ImageDataStructureDimensions
}

type ImageDataStructureDimensions {
  width: Float
  height: Float
}

type UserProfile {
  fullName: String
  personalImage: ImageDataStructure
  _id: MongoID!
}

UserProfile.personalImage is correct (as a ImageDataStructure) while Article.heroImage is typed as JSON.

Did i miss something to get this to work properly ?

Have a good day !

Zleub avatar Jul 11 '22 16:07 Zleub