Skip to content

Commit 7e3de3d

Browse files
committed
refactor: get rid of getRecordIdFn(); add test helper functions testOperation() & testFieldConfig()
BREAKING CHANGE: if you use `ObjectTypeComposer.setRecordIdFn()` for customization `recordId` in mutations payload then you will need use resolvers config options, eg. `createOne(model, tc, { recordIdFn: (doc, context) => source.uid })`. closes #262
1 parent dd9a243 commit 7e3de3d

22 files changed

+222
-42
lines changed

src/composeWithMongoose.ts

-2
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,6 @@ export function composeWithMongoose<TDoc extends Document, TContext = any>(
7070
prepareFields(tc, opts.fields);
7171
}
7272

73-
tc.setRecordIdFn((source) => (source ? `${(source as any)._id}` : ''));
74-
7573
createInputType(tc, opts.inputType);
7674

7775
if (!{}.hasOwnProperty.call(opts, 'resolvers') || opts.resolvers !== false) {

src/discriminators/DiscriminatorTypeComposer.ts

-11
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
ObjectTypeComposer,
55
InterfaceTypeComposer,
66
ObjectTypeComposerRelationOpts,
7-
ObjectTypeComposerGetRecordIdFn,
87
ObjectTypeComposerFieldConfigDefinition,
98
ObjectTypeComposerFieldConfigMapDefinition,
109
ObjectTypeComposerFieldConfigAsObjectDefinition,
@@ -363,14 +362,4 @@ export class DiscriminatorTypeComposer<TSource, TContext> extends ObjectTypeComp
363362

364363
return this;
365364
}
366-
367-
setRecordIdFn(fn: ObjectTypeComposerGetRecordIdFn<any, any>): this {
368-
super.setRecordIdFn(fn);
369-
370-
for (const childTC of this.childTCs) {
371-
childTC.setRecordIdFn(fn);
372-
}
373-
374-
return this;
375-
}
376365
}

src/resolvers/__tests__/createOne-test.ts

+19-11
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import createOne from '../createOne';
66
import { convertModelToGraphQL } from '../../fieldsConverter';
77
import GraphQLMongoID from '../../types/MongoID';
88
import { ExtendedResolveParams } from '..';
9+
import { testFieldConfig } from '../../utils/testHelpers';
910

1011
beforeAll(() => UserModel.base.createConnection());
1112
afterAll(() => UserModel.base.disconnect());
@@ -56,11 +57,13 @@ describe('createOne() ->', () => {
5657
);
5758
});
5859

59-
it('should return payload.recordId', async () => {
60-
const result = await createOne(UserModel, UserTC).resolve({
61-
args: {
62-
record: { name: 'newName', contacts: { email: 'mail' } },
63-
},
60+
it('should return payload.recordId when it requested', async () => {
61+
const result = await testFieldConfig({
62+
field: createOne(UserModel, UserTC),
63+
args: { record: { name: 'newName', contacts: { email: 'mail' } } },
64+
selection: `{
65+
recordId
66+
}`,
6467
});
6568
expect(result.recordId).toBeTruthy();
6669
});
@@ -86,13 +89,18 @@ describe('createOne() ->', () => {
8689
expect(doc.n).toBe(checkedName);
8790
});
8891

89-
it('should return payload.record', async () => {
90-
const result = await createOne(UserModel, UserTC).resolve({
91-
args: {
92-
record: { name: 'NewUser', contacts: { email: 'mail' } },
93-
},
92+
it('should return payload.record when it requested', async () => {
93+
const result = await testFieldConfig({
94+
field: createOne(UserModel, UserTC),
95+
args: { record: { name: 'NewUser', contacts: { email: 'mail' } } },
96+
selection: `{
97+
record {
98+
_id
99+
}
100+
recordId
101+
}`,
94102
});
95-
expect(result.record.id).toBe(result.recordId);
103+
expect(result.record._id).toBe(result.recordId);
96104
});
97105

98106
it('should return resolver runtime error in payload.error', async () => {

src/resolvers/__tests__/removeById-test.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import removeById from '../removeById';
77
import GraphQLMongoID from '../../types/MongoID';
88
import { convertModelToGraphQL } from '../../fieldsConverter';
99
import { ExtendedResolveParams } from '..';
10+
import { testFieldConfig } from '../../utils/testHelpers';
1011

1112
beforeAll(() => UserModel.base.createConnection());
1213
afterAll(() => UserModel.base.disconnect());
@@ -63,11 +64,13 @@ describe('removeById() ->', () => {
6364
await expect(result).rejects.toThrow('User.removeById resolver requires args._id value');
6465
});
6566

66-
it('should return payload.recordId', async () => {
67-
const result = await removeById(UserModel, UserTC).resolve({
68-
args: {
69-
_id: user.id,
70-
},
67+
it('should return payload.recordId when it requested', async () => {
68+
const result = await testFieldConfig({
69+
field: removeById(UserModel, UserTC),
70+
args: { _id: user.id },
71+
selection: `{
72+
recordId
73+
}`,
7174
});
7275
expect(result.recordId).toBe(user.id);
7376
});

src/resolvers/__tests__/removeOne-test.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import removeOne from '../removeOne';
66
import GraphQLMongoID from '../../types/MongoID';
77
import { convertModelToGraphQL } from '../../fieldsConverter';
88
import { ExtendedResolveParams } from '..';
9+
import { testFieldConfig } from '../../utils/testHelpers';
910

1011
beforeAll(() => UserModel.base.createConnection());
1112
afterAll(() => UserModel.base.disconnect());
@@ -94,8 +95,12 @@ describe('removeOne() ->', () => {
9495
});
9596

9697
it('should return payload.recordId if record existed in db', async () => {
97-
const result = await removeOne(UserModel, UserTC).resolve({
98+
const result = await testFieldConfig({
99+
field: removeOne(UserModel, UserTC),
98100
args: { filter: { _id: user1.id } },
101+
selection: `{
102+
recordId
103+
}`,
99104
});
100105
expect(result.recordId).toBe(user1.id);
101106
});

src/resolvers/__tests__/updateById-test.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import updateById from '../updateById';
77
import GraphQLMongoID from '../../types/MongoID';
88
import { convertModelToGraphQL } from '../../fieldsConverter';
99
import { ExtendedResolveParams } from '..';
10+
import { testFieldConfig } from '../../utils/testHelpers';
1011

1112
beforeAll(() => UserModel.base.createConnection());
1213
afterAll(() => UserModel.base.disconnect());
@@ -80,11 +81,15 @@ describe('updateById() ->', () => {
8081
});
8182

8283
it('should return payload.recordId', async () => {
83-
const result = await updateById(UserModel, UserTC).resolve({
84+
const result = await testFieldConfig({
85+
field: updateById(UserModel, UserTC),
8486
args: {
8587
_id: user1.id,
8688
record: { name: 'some name' },
8789
},
90+
selection: `{
91+
recordId
92+
}`,
8893
});
8994
expect(result.recordId).toBe(user1.id);
9095
});

src/resolvers/__tests__/updateOne-test.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import updateOne from '../updateOne';
77
import GraphQLMongoID from '../../types/MongoID';
88
import { convertModelToGraphQL } from '../../fieldsConverter';
99
import { ExtendedResolveParams } from '..';
10+
import { testFieldConfig } from '../../utils/testHelpers';
1011

1112
beforeAll(() => UserModel.base.createConnection());
1213
afterAll(() => UserModel.base.disconnect());
@@ -96,9 +97,13 @@ describe('updateOne() ->', () => {
9697
);
9798
});
9899

99-
it('should return payload.recordId', async () => {
100-
const result = await updateOne(UserModel, UserTC).resolve({
101-
args: { filter: { _id: user1.id } },
100+
it('should return payload.recordId when it requested', async () => {
101+
const result = await testFieldConfig({
102+
field: updateOne(UserModel, UserTC),
103+
args: { filter: { _id: user1.id }, record: {} },
104+
selection: `{
105+
recordId
106+
}`,
102107
});
103108
expect(result.recordId).toBe(user1.id);
104109
});

src/resolvers/count.ts

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type { ExtendedResolveParams } from './index';
1111
import { beforeQueryHelper } from './helpers/beforeQueryHelper';
1212

1313
export interface CountResolverOpts {
14+
/** Customize input-type for `filter` argument. If `false` then arg will be removed. */
1415
filter?: FilterHelperArgsOpts | false;
1516
}
1617

src/resolvers/createMany.ts

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { addErrorCatcherField } from './helpers/errorCatcher';
55
import { validateManyAndThrow } from './helpers/validate';
66

77
export interface CreateManyResolverOpts {
8+
/** Customize input-type for `records` argument. */
89
records?: RecordHelperArgsOpts | false;
910
}
1011

src/resolvers/createOne.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ import { addErrorCatcherField } from './helpers/errorCatcher';
66
import { validateAndThrow } from './helpers/validate';
77

88
export interface CreateOneResolverOpts {
9+
/** Customize input-type for `record` argument. */
910
record?: RecordHelperArgsOpts | false;
11+
/** Customize payload.recordId field. By default: `doc._id`. */
12+
recordIdFn?: (doc: any, context: any) => any;
1013
}
1114

1215
export default function createOne<TSource = any, TContext = any, TDoc extends Document = any>(
@@ -41,6 +44,11 @@ export default function createOne<TSource = any, TContext = any, TDoc extends Do
4144
recordId: {
4245
type: 'MongoID',
4346
description: 'Created document ID',
47+
resolve: (source, _, context) => {
48+
const doc = source?.record;
49+
if (!doc) return;
50+
return opts?.recordIdFn ? opts.recordIdFn(doc, context) : doc?._id;
51+
},
4452
},
4553
record: {
4654
type: tc,
@@ -81,9 +89,9 @@ export default function createOne<TSource = any, TContext = any, TDoc extends Do
8189

8290
await validateAndThrow(doc);
8391
await doc.save({ validateBeforeSave: false });
92+
8493
return {
8594
record: doc,
86-
recordId: tc.getRecordIdFn()(doc as any),
8795
};
8896
}) as any,
8997
});

src/resolvers/findMany.ts

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import type { ExtendedResolveParams } from './index';
2020
import { beforeQueryHelper } from './helpers/beforeQueryHelper';
2121

2222
export interface FindManyResolverOpts {
23+
/** Customize input-type for `filter` argument. If `false` then arg will be removed. */
2324
filter?: FilterHelperArgsOpts | false;
2425
sort?: SortHelperArgsOpts | false;
2526
limit?: LimitHelperArgsOpts | false;

src/resolvers/findManyLean.ts

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import type { ExtendedResolveParams } from './index';
2222
import { beforeQueryHelperLean } from './helpers/beforeQueryHelper';
2323

2424
export interface FindManyLeanResolverOpts {
25+
/** Customize input-type for `filter` argument. If `false` then arg will be removed. */
2526
filter?: FilterHelperArgsOpts | false;
2627
sort?: SortHelperArgsOpts | false;
2728
limit?: LimitHelperArgsOpts | false;

src/resolvers/findOne.ts

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import type { ExtendedResolveParams } from './index';
1717
import { beforeQueryHelper } from './helpers/beforeQueryHelper';
1818

1919
export interface FindOneResolverOpts {
20+
/** Customize input-type for `filter` argument. If `false` then arg will be removed. */
2021
filter?: FilterHelperArgsOpts | false;
2122
sort?: SortHelperArgsOpts | false;
2223
skip?: false;

src/resolvers/findOneLean.ts

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import type { ExtendedResolveParams } from './index';
1919
import { beforeQueryHelperLean } from './helpers/beforeQueryHelper';
2020

2121
export interface FindOneLeanResolverOpts {
22+
/** Customize input-type for `filter` argument. If `false` then arg will be removed. */
2223
filter?: FilterHelperArgsOpts | false;
2324
sort?: SortHelperArgsOpts | false;
2425
skip?: false;

src/resolvers/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import createOne, { CreateOneResolverOpts } from './createOne';
1414
import updateById, { UpdateByIdResolverOpts } from './updateById';
1515
import updateMany, { UpdateManyResolverOpts } from './updateMany';
1616
import updateOne, { UpdateOneResolverOpts } from './updateOne';
17-
import removeById from './removeById';
17+
import removeById, { RemoveByIdResolverOpts } from './removeById';
1818
import removeMany, { RemoveManyResolverOpts } from './removeMany';
1919
import removeOne, { RemoveOneResolverOpts } from './removeOne';
2020
import dataLoader from './dataLoader';
@@ -43,7 +43,7 @@ export type AllResolversOpts = {
4343
updateById?: false | UpdateByIdResolverOpts;
4444
updateOne?: false | UpdateOneResolverOpts;
4545
updateMany?: false | UpdateManyResolverOpts;
46-
removeById?: false;
46+
removeById?: false | RemoveByIdResolverOpts;
4747
removeOne?: false | RemoveOneResolverOpts;
4848
removeMany?: false | RemoveManyResolverOpts;
4949
connection?: false | ConnectionOpts<any>;

src/resolvers/removeById.ts

+12-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,15 @@ import type { ExtendedResolveParams } from './index';
55
import { addErrorCatcherField } from './helpers/errorCatcher';
66
import { ArgsMap } from './helpers';
77

8+
export interface RemoveByIdResolverOpts {
9+
/** Customize payload.recordId field. By default: `doc._id`. */
10+
recordIdFn?: (doc: any, context: any) => any;
11+
}
12+
813
export default function removeById<TSource = any, TContext = any, TDoc extends Document = any>(
914
model: Model<TDoc>,
10-
tc: ObjectTypeComposer<TDoc, TContext>
15+
tc: ObjectTypeComposer<TDoc, TContext>,
16+
opts?: RemoveByIdResolverOpts
1117
): Resolver<TSource, TContext, ArgsMap, TDoc> {
1218
if (!model || !model.modelName || !model.schema) {
1319
throw new Error('First arg for Resolver removeById() should be instance of Mongoose Model.');
@@ -27,6 +33,11 @@ export default function removeById<TSource = any, TContext = any, TDoc extends D
2733
recordId: {
2834
type: 'MongoID',
2935
description: 'Removed document ID',
36+
resolve: (source, _, context) => {
37+
const doc = source?.record;
38+
if (!doc) return;
39+
return opts?.recordIdFn ? opts.recordIdFn(doc, context) : doc?._id;
40+
},
3041
},
3142
record: {
3243
type: tc,
@@ -66,7 +77,6 @@ export default function removeById<TSource = any, TContext = any, TDoc extends D
6677

6778
return {
6879
record: doc,
69-
recordId: tc.getRecordIdFn()(doc as any),
7080
};
7181
}
7282

src/resolvers/removeMany.ts

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { beforeQueryHelper } from './helpers/beforeQueryHelper';
1212
import { addErrorCatcherField } from './helpers/errorCatcher';
1313

1414
export interface RemoveManyResolverOpts {
15+
/** Customize input-type for `filter` argument. If `false` then arg will be removed. */
1516
filter?: FilterHelperArgsOpts | false;
1617
}
1718

src/resolvers/removeOne.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@ import type { ExtendedResolveParams } from './index';
1212
import { addErrorCatcherField } from './helpers/errorCatcher';
1313

1414
export interface RemoveOneResolverOpts {
15+
/** Customize input-type for `filter` argument. If `false` then arg will be removed. */
1516
filter?: FilterHelperArgsOpts | false;
1617
sort?: SortHelperArgsOpts | false;
18+
/** Customize payload.recordId field. By default: `doc._id`. */
19+
recordIdFn?: (doc: any, context: any) => any;
1720
}
1821

1922
export default function removeOne<TSource = any, TContext = any, TDoc extends Document = any>(
@@ -39,6 +42,11 @@ export default function removeOne<TSource = any, TContext = any, TDoc extends Do
3942
recordId: {
4043
type: 'MongoID',
4144
description: 'Removed document ID',
45+
resolve: (source, _, context) => {
46+
const doc = source?.record;
47+
if (!doc) return;
48+
return opts?.recordIdFn ? opts.recordIdFn(doc, context) : doc?._id;
49+
},
4250
},
4351
record: {
4452
type: tc,
@@ -93,7 +101,6 @@ export default function removeOne<TSource = any, TContext = any, TDoc extends Do
93101

94102
return {
95103
record: doc,
96-
recordId: tc.getRecordIdFn()(doc),
97104
};
98105
}
99106

src/resolvers/updateById.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ import { validateAndThrow } from './helpers/validate';
88
import { ArgsMap } from './helpers';
99

1010
export interface UpdateByIdResolverOpts {
11+
/** Customize input-type for `record` argument. */
1112
record?: RecordHelperArgsOpts | false;
13+
/** Customize payload.recordId field. By default: `doc._id`. */
14+
recordIdFn?: (doc: any, context: any) => any;
1215
}
1316

1417
export default function updateById<TSource = any, TContext = any, TDoc extends Document = any>(
@@ -34,6 +37,11 @@ export default function updateById<TSource = any, TContext = any, TDoc extends D
3437
recordId: {
3538
type: 'MongoID',
3639
description: 'Updated document ID',
40+
resolve: (source, _, context) => {
41+
const doc = source?.record;
42+
if (!doc) return;
43+
return opts?.recordIdFn ? opts.recordIdFn(doc, context) : doc?._id;
44+
},
3745
},
3846
record: {
3947
type: tc,
@@ -105,7 +113,6 @@ export default function updateById<TSource = any, TContext = any, TDoc extends D
105113

106114
return {
107115
record: doc,
108-
recordId: tc.getRecordIdFn()(doc as any),
109116
};
110117
}) as any,
111118
});

0 commit comments

Comments
 (0)