Skip to content

Commit 2be5c34

Browse files
Merge pull request #292 from aws-amplify/master
fix: filter related model fields by type when resolving connection #290
2 parents 4aad9e5 + 91c390b commit 2be5c34

File tree

2 files changed

+92
-23
lines changed

2 files changed

+92
-23
lines changed

packages/appsync-modelgen-plugin/src/__tests__/utils/process-connections.test.ts

Lines changed: 81 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ describe('process connection', () => {
126126
expect(connectionInfo.kind).toEqual(CodeGenConnectionType.HAS_ONE);
127127
expect(connectionInfo.associatedWith).toEqual(modelMap.License.fields[0]);
128128
expect(connectionInfo.isConnectingFieldAutoCreated).toEqual(true);
129-
expect(connectionInfo.targetName).toEqual("personLicenseId");
129+
expect(connectionInfo.targetName).toEqual('personLicenseId');
130130
});
131131

132132
it('should return BELONGS_TO License.person field', () => {
@@ -500,11 +500,11 @@ describe('process connection', () => {
500500
type Post @model {
501501
comments: [Comment] @hasMany(fields: ["id"])
502502
}
503-
503+
504504
type Comment @model {
505505
postID: ID! @primaryKey(sortKeyFields: ["content"])
506506
content: String!
507-
post: Post @belongsTo(fields:["postID"])
507+
post: Post @belongsTo(fields: ["postID"])
508508
}
509509
`;
510510

@@ -533,7 +533,7 @@ describe('process connection', () => {
533533
isNullable: false,
534534
isList: false,
535535
name: 'chargerID',
536-
directives: []
536+
directives: [],
537537
},
538538
{
539539
type: 'PowerSource',
@@ -599,7 +599,7 @@ describe('process connection', () => {
599599
isNullable: false,
600600
isList: false,
601601
name: 'id',
602-
directives: []
602+
directives: [],
603603
},
604604
{
605605
type: 'Float',
@@ -644,7 +644,7 @@ describe('process connection', () => {
644644
isNullable: false,
645645
isList: false,
646646
name: 'postID',
647-
directives: [{name: 'primaryKey', arguments: { sortKeyFields: ['content'] } }],
647+
directives: [{ name: 'primaryKey', arguments: { sortKeyFields: ['content'] } }],
648648
},
649649
{
650650
type: 'String',
@@ -710,7 +710,7 @@ describe('process connection', () => {
710710
isNullable: false,
711711
isList: false,
712712
name: 'postID',
713-
directives: [{name: 'index', arguments: { name: 'byPost', sortKeyFields: ['content'] }}],
713+
directives: [{ name: 'index', arguments: { name: 'byPost', sortKeyFields: ['content'] } }],
714714
},
715715
{
716716
type: 'String',
@@ -727,7 +727,7 @@ describe('process connection', () => {
727727
describe('Has many comparison', () => {
728728
it('should support connection with @primaryKey on BELONGS_TO side', () => {
729729
const postField = v2ModelMap.Comment.fields[2];
730-
const connectionInfo = (processConnectionsV2(postField, v2ModelMap.Post, v2ModelMap) as any) as CodeGenFieldConnectionBelongsTo;
730+
const connectionInfo = (processConnectionsV2(postField, v2ModelMap.Comment, v2ModelMap) as any) as CodeGenFieldConnectionBelongsTo;
731731
expect(connectionInfo).toBeDefined();
732732
expect(connectionInfo.kind).toEqual(CodeGenConnectionType.BELONGS_TO);
733733
expect(connectionInfo.targetName).toEqual(v2ModelMap.Comment.fields[0].name);
@@ -736,7 +736,7 @@ describe('process connection', () => {
736736

737737
it('should support connection with @primaryKey on HAS_MANY side', () => {
738738
const commentsField = v2ModelMap.Post.fields[0];
739-
const connectionInfo = (processConnectionsV2(commentsField, v2ModelMap.Comment, v2ModelMap) as any) as CodeGenFieldConnectionHasMany;
739+
const connectionInfo = (processConnectionsV2(commentsField, v2ModelMap.Post, v2ModelMap) as any) as CodeGenFieldConnectionHasMany;
740740
expect(connectionInfo).toBeDefined();
741741
expect(connectionInfo.kind).toEqual(CodeGenConnectionType.HAS_MANY);
742742
expect(connectionInfo.connectedModel).toEqual(v2ModelMap.Comment);
@@ -745,7 +745,11 @@ describe('process connection', () => {
745745

746746
it('Should support connection with @index on BELONGS_TO side', () => {
747747
const commentsField = v2IndexModelMap.Post.fields[2];
748-
const connectionInfo = (processConnectionsV2(commentsField, v2IndexModelMap.Comment, v2IndexModelMap) as any) as CodeGenFieldConnectionHasMany;
748+
const connectionInfo = (processConnectionsV2(
749+
commentsField,
750+
v2IndexModelMap.Post,
751+
v2IndexModelMap,
752+
) as any) as CodeGenFieldConnectionHasMany;
749753
expect(connectionInfo).toBeDefined();
750754
expect(connectionInfo.kind).toEqual(CodeGenConnectionType.HAS_MANY);
751755
expect(connectionInfo.connectedModel).toEqual(v2IndexModelMap.Comment);
@@ -756,21 +760,85 @@ describe('process connection', () => {
756760
describe('Has one testing', () => {
757761
it('Should support @hasOne with no explicit primary key', () => {
758762
const powerSourceField = hasOneNoFieldsModelMap.BatteryCharger.fields[0];
759-
const connectionInfo = (processConnectionsV2(powerSourceField, hasOneNoFieldsModelMap.PowerSource, hasOneNoFieldsModelMap)) as CodeGenFieldConnectionHasOne;
763+
const connectionInfo = processConnectionsV2(
764+
powerSourceField,
765+
hasOneNoFieldsModelMap.BatteryCharger,
766+
hasOneNoFieldsModelMap,
767+
) as CodeGenFieldConnectionHasOne;
760768
expect(connectionInfo).toBeDefined();
761769
expect(connectionInfo.kind).toEqual(CodeGenConnectionType.HAS_ONE);
762770
expect(connectionInfo.connectedModel).toEqual(hasOneNoFieldsModelMap.PowerSource);
763771
expect(connectionInfo.isConnectingFieldAutoCreated).toEqual(true);
764772
});
765773
it('Should support @hasOne with an explicit primary key', () => {
766774
const powerSourceField = hasOneWithFieldsModelMap.BatteryCharger.fields[1];
767-
const connectionInfo = (processConnectionsV2(powerSourceField, hasOneWithFieldsModelMap.PowerSource, hasOneWithFieldsModelMap)) as CodeGenFieldConnectionHasOne;
775+
const connectionInfo = processConnectionsV2(
776+
powerSourceField,
777+
hasOneWithFieldsModelMap.BatteryCharger,
778+
hasOneWithFieldsModelMap,
779+
) as CodeGenFieldConnectionHasOne;
768780
expect(connectionInfo).toBeDefined();
769781
expect(connectionInfo.kind).toEqual(CodeGenConnectionType.HAS_ONE);
770782
expect(connectionInfo.connectedModel).toEqual(hasOneWithFieldsModelMap.PowerSource);
771783
expect(connectionInfo.isConnectingFieldAutoCreated).toEqual(false);
772784
});
785+
it('disambiguates multiple connection directives in related type based on field type', () => {
786+
const modelMap: CodeGenModelMap = {
787+
Post: {
788+
name: 'Post',
789+
type: 'model',
790+
directives: [],
791+
fields: [
792+
{
793+
type: 'Comment',
794+
isNullable: true,
795+
isList: false,
796+
name: 'comment',
797+
directives: [{ name: 'hasOne', arguments: {} }],
798+
},
799+
],
800+
},
801+
Comment: {
802+
name: 'Comment',
803+
type: 'model',
804+
directives: [],
805+
fields: [
806+
{
807+
type: 'id',
808+
isNullable: false,
809+
isList: false,
810+
name: 'id',
811+
directives: [],
812+
},
813+
{
814+
type: 'Like',
815+
isNullable: true,
816+
isList: true,
817+
name: 'likes',
818+
directives: [{ name: 'hasMany', arguments: { indexName: 'byComment', fields: ['id'] } }],
819+
},
820+
],
821+
},
822+
Like: {
823+
name: 'Like',
824+
type: 'model',
825+
directives: [],
826+
fields: [
827+
{
828+
type: 'string',
829+
isNullable: true,
830+
isList: false,
831+
name: 'likeString',
832+
directives: [],
833+
},
834+
],
835+
},
836+
};
837+
const connectionInfo = processConnectionsV2(modelMap.Post.fields[0], modelMap.Post, modelMap);
838+
expect(connectionInfo.kind).toEqual(CodeGenConnectionType.HAS_ONE);
839+
console.log(connectionInfo);
840+
expect((connectionInfo as CodeGenFieldConnectionHasOne).associatedWith.name).toEqual('id');
841+
});
773842
});
774-
775843
});
776844
});

packages/appsync-modelgen-plugin/src/utils/process-connections-v2.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,23 +52,24 @@ export function getConnectedFieldV2(
5252
: DEFAULT_HASH_KEY_FIELD;
5353

5454
// Find a field on the other side which connected by a @connection and has the same fields[0] as indexName field
55-
const otherSideConnectedField = connectedModel.fields.find(f => {
56-
return f.directives.find(d => {
57-
return (
58-
(d.name === 'belongsTo' || d.name === 'hasOne' || d.name === 'hasMany') &&
59-
d.arguments.fields &&
60-
d.arguments.fields[0] === connectedFieldName
61-
);
62-
});
63-
});
55+
const otherSideConnectedField = connectedModel.fields
56+
.filter(f => f.type === model.name)
57+
.find(f =>
58+
f.directives.find(
59+
d =>
60+
(d.name === 'belongsTo' || d.name === 'hasOne' || d.name === 'hasMany') &&
61+
d.arguments.fields &&
62+
d.arguments.fields[0] === connectedFieldName,
63+
),
64+
);
6465
if (otherSideConnectedField) {
6566
return otherSideConnectedField;
6667
}
6768
// If there are no field with @connection with indexName then try to find a field that has same name as connection name
6869
const connectedField = connectedModel.fields.find(f => f.name === connectedFieldName);
6970

7071
if (!connectedField) {
71-
throw new Error(`Can not find key field ${connectedFieldName} in ${connectedModel}`);
72+
throw new Error(`Can not find key field ${connectedFieldName} in ${connectedModel.name}`);
7273
}
7374
return connectedField;
7475
}

0 commit comments

Comments
 (0)