Skip to content

Commit 8bb278e

Browse files
committed
fix: defaultsAsNonNull option now skips isSingleNested mongoose schemas (because such sub-schemas break the "recursive default value assignation" behavior)
see #358 closes #358
1 parent c18e675 commit 8bb278e

File tree

3 files changed

+54
-0
lines changed

3 files changed

+54
-0
lines changed
+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { composeMongoose } from '../../index';
2+
import { mongoose } from '../../__mocks__/mongooseCommon';
3+
4+
// mongoose.set('debug', true);
5+
6+
const WithSubSchema = new mongoose.Schema({
7+
subDocument: new mongoose.Schema({
8+
field: { type: String, default: 'Hey' },
9+
}),
10+
});
11+
12+
const WithoutSubSchema = new mongoose.Schema({
13+
subDocument: {
14+
field: { type: String, default: 'Hey' },
15+
},
16+
});
17+
18+
const WithSubModel = mongoose.model('WithSubModel', WithSubSchema);
19+
const WithoutSubModel = mongoose.model('WithoutSubModel', WithoutSubSchema);
20+
21+
describe('defaultsAsNonNull falsely reports non-nullability for subdocuments that have a Schema - issue #358', () => {
22+
it('with sub schema', async () => {
23+
const WithSubTC = composeMongoose(WithSubModel, { defaultsAsNonNull: true });
24+
25+
// sub-Schema breaks the "recursive default value assignation" behavior
26+
const data = new WithSubModel().subDocument;
27+
expect(data).toEqual(undefined);
28+
29+
// so field should not be non-null
30+
expect(WithSubTC.getFieldTypeName('subDocument')).toBe('WithSubModelSubDocument');
31+
});
32+
33+
it('as nested fields', async () => {
34+
const WithoutSubTC = composeMongoose(WithoutSubModel, { defaultsAsNonNull: true });
35+
36+
const data = new WithoutSubModel().subDocument;
37+
expect(data).toEqual({ field: 'Hey' });
38+
39+
// should be non-null!
40+
expect(WithoutSubTC.getFieldTypeName('subDocument')).toBe('WithoutSubModelSubDocument!');
41+
});
42+
});

src/composeMongoose.ts

+6
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,12 @@ function makeFieldsNonNullWithDefaultValues(
163163
const fc = tc.getField(fieldName);
164164
// traverse nested Object types
165165
if (fc.type instanceof ObjectTypeComposer) {
166+
if (fc.extensions?.isSingleNestedMongooseSchema) {
167+
// sub-Schema breaks the "recursive default value assignation" behavior
168+
// @see https://github.com/graphql-compose/graphql-compose-mongoose/issues/358
169+
return;
170+
}
171+
166172
makeFieldsNonNullWithDefaultValues(fc.type);
167173
if (fc.type.getExtension('hasFieldsWithDefaultValue')) {
168174
tc.makeFieldNonNull(fieldName);

src/fieldsConverter.ts

+6
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,12 @@ export function convertModelToGraphQL<TDoc extends Document, TContext>(
189189
description: _getFieldDescription(mongooseField),
190190
};
191191

192+
if (mongooseField?.schema && (mongooseField as any)?.$isSingleNested) {
193+
graphqlFields[fieldName].extensions = {
194+
isSingleNestedMongooseSchema: true,
195+
};
196+
}
197+
192198
if (mongooseField?.defaultValue !== null && mongooseField?.defaultValue !== undefined) {
193199
if (!graphqlFields[fieldName].extensions) graphqlFields[fieldName].extensions = {};
194200
(graphqlFields as any)[fieldName].extensions.defaultValue = mongooseField?.defaultValue;

0 commit comments

Comments
 (0)