Skip to content

Commit a9ea050

Browse files
authored
fix(amplify-codegen): fix name for many to many join table fields (#303)
1 parent 3395490 commit a9ea050

File tree

2 files changed

+53
-7
lines changed

2 files changed

+53
-7
lines changed

packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-visitor.test.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,9 @@ describe('AppSyncModelVisitor', () => {
339339
);
340340
visit(ast, { leave: visitor });
341341
visitor.generate();
342-
const projectTeamIdField = visitor.models.Project.fields.find(field => { return field.name === 'projectTeamId'; });
342+
const projectTeamIdField = visitor.models.Project.fields.find(field => {
343+
return field.name === 'projectTeamId';
344+
});
343345
expect(projectTeamIdField).toBeDefined();
344346
expect(projectTeamIdField.isNullable).toBeTruthy();
345347
});
@@ -664,6 +666,7 @@ describe('AppSyncModelVisitor', () => {
664666
let simpleManyToManySchema;
665667
let simpleManyModelMap;
666668
let transformedSimpleManyModelMap;
669+
let manyToManyModelNameSchema;
667670

668671
beforeEach(() => {
669672
simpleManyToManySchema = /* GraphQL */ `
@@ -678,6 +681,16 @@ describe('AppSyncModelVisitor', () => {
678681
}
679682
`;
680683

684+
manyToManyModelNameSchema = /* GraphQL */ `
685+
type ModelA @model {
686+
models: [ModelB] @manyToMany(relationName: "Models")
687+
}
688+
689+
type ModelB @model {
690+
models: [ModelA] @manyToMany(relationName: "Models")
691+
}
692+
`;
693+
681694
simpleManyModelMap = {
682695
Human: {
683696
name: 'Human',
@@ -832,5 +845,36 @@ describe('AppSyncModelVisitor', () => {
832845
expect(visitor.models.Animal.fields[2].directives[0].arguments.fields[0]).toEqual('id');
833846
expect(visitor.models.Animal.fields[2].directives[0].arguments.indexName).toEqual('byAnimal');
834847
});
848+
849+
it('Should correctly field names for many to many join table', () => {
850+
const visitor = createAndGeneratePipelinedTransformerVisitor(manyToManyModelNameSchema);
851+
852+
expect(visitor.models.ModelA.fields.length).toEqual(4);
853+
expect(visitor.models.ModelA.fields[1].directives[0].name).toEqual('hasMany');
854+
expect(visitor.models.ModelA.fields[1].directives[0].arguments.fields.length).toEqual(1);
855+
expect(visitor.models.ModelA.fields[1].directives[0].arguments.fields[0]).toEqual('id');
856+
expect(visitor.models.ModelA.fields[1].directives[0].arguments.indexName).toEqual('byModelA');
857+
858+
expect(visitor.models.Models).toBeDefined();
859+
expect(visitor.models.Models.fields.length).toEqual(5);
860+
861+
const modelA = visitor.models.Models.fields.find(f => f.name === 'modelA');
862+
expect(modelA).toBeDefined();
863+
expect(modelA.directives[0].name).toEqual('belongsTo');
864+
expect(modelA.directives[0].arguments.fields.length).toEqual(1);
865+
expect(modelA.directives[0].arguments.fields[0]).toEqual('modelAID');
866+
867+
const modelB = visitor.models.Models.fields.find(f => f.name === 'modelB');
868+
expect(modelB).toBeDefined();
869+
expect(modelB.directives[0].name).toEqual('belongsTo');
870+
expect(modelB.directives[0].arguments.fields.length).toEqual(1);
871+
expect(modelB.directives[0].arguments.fields[0]).toEqual('modelBID');
872+
873+
expect(visitor.models.ModelB.fields.length).toEqual(4);
874+
expect(visitor.models.ModelB.fields[1].directives[0].name).toEqual('hasMany');
875+
expect(visitor.models.ModelB.fields[1].directives[0].arguments.fields.length).toEqual(1);
876+
expect(visitor.models.ModelB.fields[1].directives[0].arguments.fields[0]).toEqual('id');
877+
expect(visitor.models.ModelB.fields[1].directives[0].arguments.indexName).toEqual('byModelB');
878+
});
835879
});
836880
});

packages/appsync-modelgen-plugin/src/visitors/appsync-visitor.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
ParsedConfig,
77
RawConfig,
88
} from '@graphql-codegen/visitor-plugin-common';
9-
import { constantCase, pascalCase } from 'change-case';
9+
import { camelCase, constantCase, pascalCase } from 'change-case';
1010
import { plural } from 'pluralize';
1111
import crypto from 'crypto';
1212
import {
@@ -553,8 +553,8 @@ export class AppSyncModelVisitor<
553553
secondField: CodeGenField,
554554
relationName: string,
555555
) {
556-
const firstModelKeyFieldName = `${firstModel.name.toLowerCase()}ID`;
557-
const secondModelKeyFieldName = `${secondModel.name.toLowerCase()}ID`;
556+
const firstModelKeyFieldName = `${camelCase(firstModel.name)}ID`;
557+
const secondModelKeyFieldName = `${camelCase(secondModel.name)}ID`;
558558
let intermediateModel: CodeGenModel = {
559559
name: relationName,
560560
type: 'model',
@@ -585,14 +585,14 @@ export class AppSyncModelVisitor<
585585
type: firstModel.name,
586586
isNullable: false,
587587
isList: false,
588-
name: firstModel.name.toLowerCase(),
588+
name: camelCase(firstModel.name),
589589
directives: [{ name: 'belongsTo', arguments: { fields: [firstModelKeyFieldName] } }],
590590
},
591591
{
592592
type: secondModel.name,
593593
isNullable: false,
594594
isList: false,
595-
name: secondModel.name.toLowerCase(),
595+
name: camelCase(secondModel.name),
596596
directives: [{ name: 'belongsTo', arguments: { fields: [secondModelKeyFieldName] } }],
597597
},
598598
],
@@ -708,7 +708,9 @@ export class AppSyncModelVisitor<
708708
const connectionInfo = field.connectionInfo;
709709
if (modelTypes.includes(fieldType) && connectionInfo === undefined) {
710710
printWarning(
711-
`Model ${model.name} has field ${field.name} of type ${field.type} but its not connected. Add the appropriate ${field.isList ? '@hasMany' : '@hasOne'}/@belongsTo directive if you want to connect them.`,
711+
`Model ${model.name} has field ${field.name} of type ${field.type} but its not connected. Add the appropriate ${
712+
field.isList ? '@hasMany' : '@hasOne'
713+
}/@belongsTo directive if you want to connect them.`,
712714
);
713715
return false;
714716
}

0 commit comments

Comments
 (0)