-
-
Notifications
You must be signed in to change notification settings - Fork 94
/
findById.ts
73 lines (66 loc) · 2.58 KB
/
findById.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import { toInputType } from 'graphql-compose';
import type { Resolver, ObjectTypeComposer, InterfaceTypeComposer } from 'graphql-compose';
import type { Model, Document } from 'mongoose';
import {
projectionHelper,
prepareNestedAliases,
prepareAliasesReverse,
replaceAliases,
} from './helpers';
import type { ExtendedResolveParams } from './index';
import { beforeQueryHelper, beforeQueryHelperLean } from './helpers/beforeQueryHelper';
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface FindByIdResolverOpts {
/**
* Enabling the lean option tells Mongoose to skip instantiating
* a full Mongoose document and just give you the plain JavaScript objects.
* Documents are much heavier than vanilla JavaScript objects,
* because they have a lot of internal state for change tracking.
* The downside of enabling lean is that lean docs don't have:
* Default values
* Getters and setters
* Virtuals
* Read more about `lean`: https://mongoosejs.com/docs/tutorials/lean.html
*/
lean?: boolean;
}
type TArgs = {
_id: any;
};
export function findById<TSource = any, TContext = any, TDoc extends Document = any>(
model: Model<TDoc>,
tc: ObjectTypeComposer<TDoc, TContext> | InterfaceTypeComposer<TDoc, TContext>,
opts?: FindByIdResolverOpts
): Resolver<TSource, TContext, TArgs, TDoc> {
if (!model || !model.modelName || !model.schema) {
throw new Error('First arg for Resolver findById() should be instance of Mongoose Model.');
}
if (!tc || tc.constructor.name !== 'ObjectTypeComposer') {
throw new Error('Second arg for Resolver findById() should be instance of ObjectTypeComposer.');
}
const aliases = prepareNestedAliases(model.schema);
const aliasesReverse = prepareAliasesReverse(model.schema);
return tc.schemaComposer.createResolver<TSource, TArgs>({
type: tc,
name: 'findById',
kind: 'query',
args: {
_id: tc.hasField('_id') ? toInputType(tc.getFieldTC('_id')).NonNull : 'MongoID',
},
resolve: (async (resolveParams: ExtendedResolveParams<TDoc>) => {
const args = resolveParams.args || {};
if (args._id) {
resolveParams.query = model.findById(args._id);
resolveParams.model = model;
projectionHelper(resolveParams, aliases);
if (opts?.lean) {
const result = await beforeQueryHelperLean(resolveParams);
return result && aliasesReverse ? replaceAliases(result, aliasesReverse) : result;
} else {
return beforeQueryHelper(resolveParams);
}
}
return Promise.resolve(null);
}) as any,
});
}