Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"eslint-plugin-prettier": "^2.6.2",
"flow-bin": "^0.80.0",
"graphql": "14.0.0",
"graphql-compose": "^5.0.2",
"graphql-compose": "^5.2.0",
"graphql-compose-connection": ">=4.0.0",
"graphql-compose-pagination": ">=4.0.0",
"jest": "^23.5.0",
Expand All @@ -72,6 +72,8 @@
"rimraf": "^2.6.2",
"semantic-release": "^15.9.12",
"tslint": "^5.11.0",
"tslint-config-prettier": "^1.15.0",
"tslint-plugin-prettier": "^1.3.0",
"typescript": "^3.0.3"
},
"config": {
Expand All @@ -97,7 +99,7 @@
"coverage": "jest --coverage --maxWorkers 4",
"lint": "npm run eslint && npm run tslint",
"eslint": "eslint --ext .js ./src",
"tslint": "tslint -p . \"src/**/*.d.ts\"",
"tslint": "tslint -p .",
"tscheck": "tsc",
"flow": "./node_modules/.bin/flow",
"test": "npm run coverage && npm run lint && npm run flow && npm run tscheck",
Expand Down
53 changes: 53 additions & 0 deletions src/__tests__/typedefs/composeWithMongoose.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { model, Schema } from 'mongoose';
import { composeWithMongoose } from '../../composeWithMongoose';
import { FindManyArgs } from '../..';
import { Context, IPost, IUser, IUserModel } from './mock-typedefs';

const UserModel = model<IUser, IUserModel>('User', new Schema({}));
const PostModel = model('Post', new Schema({}));

const UserTC = composeWithMongoose<IUser, Context>(UserModel);

// if one doesn't pass `any` as source, then we will eventually get `Document`
// as source which to an extend is not as open as `any`.
// the `Document` type was set internally by mongoose typedefs.
const PostTC = composeWithMongoose<any>(PostModel);

UserTC.addFields({
newField: {
// test Thunk
type: 'Int',
resolve: (source, args, context) => {
source.name = 'GQC';
// source.name = 44;
context.auth = 'auth';
// context.auth = 44;
},
},
});

PostTC.addFields({
newField: {
// test Thunk
type: 'Int',
resolve: (source, args, context) => {
source.name = 'GQC';
source.name = 44;
context.auth = 'auth';
context.auth = 44;
},
},
});

PostTC.getResolver('findMany').wrapResolve<any, FindManyArgs<IPost>>(
next => rp => {
if (rp.source && rp.args) {
rp.args.limit = 50;
// fix this to display only Post fields.
// Avoid Document fields
rp.args.filter.title = 'New Title';
// rp.args.filter.title = 5;
// rp.args.limit = 'limit';
}
},
);
96 changes: 96 additions & 0 deletions src/__tests__/typedefs/composeWithMongooseDiscriminators.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { model, Schema } from 'mongoose';
import { composeWithMongooseDiscriminators } from '../../composeWithMongooseDiscriminators';
import {
Context,
EnumCharacterType,
ICharacter,
ICharacterModel,
IDroid,
IPerson,
} from './mock-typedefs';

const CharacterModel = model<ICharacter, ICharacterModel>(
'Character',
new Schema({}),
);

const PersonModel = CharacterModel.discriminator<IPerson>(
EnumCharacterType.Person,
new Schema({}),
);
const DroidModel = CharacterModel.discriminator<IDroid>(
EnumCharacterType.Droid,
new Schema({}),
);

const CharacterTC = composeWithMongooseDiscriminators<ICharacter, Context>(
CharacterModel,
{
reorderFields: true,
},
);

const PersonTC = CharacterTC.discriminator(PersonModel);
const DroidTC = CharacterTC.discriminator(DroidModel);

CharacterTC.getResolver<ICharacter, { arg1: string; arg2: number }>(
'findOne',
).wrapResolve(next => rp => {
if (rp.source && rp.args) {
rp.args.arg1 = 'string';
rp.args.arg2 = 888;
}
});

CharacterTC.addFields({
newField: {
// test Thunk
type: 'Int',
resolve: (source, args, context) => {
source.name = 'GQC';
// source.name = 44;
context.auth = 'auth';
// context.auth = 44;
},
},
});

PersonTC.addFields({
newField: {
// test Thunk
type: 'Int',
resolve: (source, args, context) => {
source.name = 'GQC';
// source.name = 44;
source.dob = 51225545;
// source.dob = 'string';
context.auth = 'auth';
// context.auth = 44;
},
},
});

DroidTC.addFields({
newField: {
// test Thunk
type: 'Int',
resolve: (source, args, context) => {
source.name = 'GQC';
// source.name = 44;
source.makeDate = new Date();
// source.makeDate = 55566156;
context.auth = 'auth';
// context.auth = 44;
},
},
});

// Testing a scenario where we use no types
const Char = model('Char', new Schema({}));
const Per = Char.discriminator('Per', new Schema({}));

// by default, from mongoose types, sources are `Document`.
// it is good to explicitly override `Document` to `any`
// then since we did not pass a context, our context results to `any`
const CharTC = composeWithMongooseDiscriminators<any>(Char);
const PerTC = CharTC.discriminator<any>(Per);
54 changes: 54 additions & 0 deletions src/__tests__/typedefs/mock-typedefs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Document, Model } from 'mongoose';

export interface Context {
uid: string;
profileUrl: string;
auth: string;
}

export interface IUser extends Document {
name: string;
age: number;
gender: 'male' | 'female' | 'ladyboy';
skills: string[];
}

export interface IUserModel extends Model<IUser> {
statics1: string;
}

export interface IPost extends Document {
title: string;
body: string;
comments: Array<{ by: string; text: string }>;
}

export enum EnumCharacterType {
Person = 'Person',
Droid = 'Droid',
}

export interface ICharacter extends Document {
name: string;
type: EnumCharacterType;
kind: string;
friends: string[];
appearsIn: string[];
}

// if static functions exist
export interface ICharacterModel extends Model<ICharacter> {
getCharactersFriends(id: string): ICharacter[];
}

export interface IPerson extends ICharacter {
dob: number;
starShips: string[];
totalCredits: number;
}

export interface IDroid extends ICharacter {
makeDate: Date;
modelNumber: number;
primaryFunction: string[];
}
15 changes: 9 additions & 6 deletions src/composeWithMongoose.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import {
} from './resolvers/helpers';
import { PaginationResolverOpts } from './resolvers/pagination';

export type TypeConverterOpts = {
schemaComposer?: SchemaComposer<any>;
export type TypeConverterOpts<TContext = any> = {
schemaComposer?: SchemaComposer<TContext>;
name?: string;
description?: string;
fields?: {
Expand Down Expand Up @@ -111,10 +111,13 @@ export type TypeConverterResolversOpts = {
pagination?: PaginationResolverOpts | false;
};

export function composeWithMongoose(
model: Model<any>,
opts?: TypeConverterOpts,
): TypeComposer<any>;
export function composeWithMongoose<
TModel extends Document = any,
TContext = any
>(
model: Model<TModel>,
opts?: TypeConverterOpts<TContext>,
): TypeComposer<TModel, TContext>;

export function prepareFields(
tc: TypeComposer<any>,
Expand Down
17 changes: 12 additions & 5 deletions src/composeWithMongooseDiscriminators.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { TypeComposerClass } from 'graphql-compose';
import { Model } from 'mongoose';
import { Document, Model } from 'mongoose';
import {
DiscriminatorOptions,
DiscriminatorTypeComposer,
} from './discriminators';

export function composeWithMongooseDiscriminators(
baseModel: Model<any>,
opts?: { [opts: string]: any }): TypeComposerClass<any>;
export function composeWithMongooseDiscriminators<
TBaseModel extends Document = any,
TContext = any
>(
baseModel: Model<TBaseModel>,
opts?: DiscriminatorOptions<TContext>,
): DiscriminatorTypeComposer<TBaseModel, TContext>;
Loading