From 39a0e5c6c16b6a900dfcdd1e19befc70626972b1 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 01/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 27 +++++++++++++++++++ .../src/graphql-model-transformer.ts | 22 ++++++++++----- .../src/graphql-types/mutation.ts | 16 +++++++---- .../src/wrappers/object-definition-wrapper.ts | 19 +++++++++---- ...aphql-searchable-transformer.tests.ts.snap | 4 +-- yarn.lock | 8 ------ 6 files changed, 70 insertions(+), 26 deletions(-) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 4b20ee9cdc6..2763423a6ac 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -368,4 +368,31 @@ describe('ModelTransformer: ', () => { const commentInputIDField = getFieldOnInputType(commentInputObject!, 'id'); verifyMatchingTypes(commentObjectIDField.type, commentInputIDField.type); }); + + it('should support enum as a field', () => { + const validSchema = ` + enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } + type Test @model { + status: Status! + lastStatus: Status! + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const createTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); + + const updateTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + }); }); diff --git a/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts b/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts index f7106e58fe7..ca4391b87f4 100644 --- a/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts +++ b/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts @@ -722,10 +722,10 @@ export class ModelTransformer extends TransformerModelBase implements Transforme const knownModels = this.typesWithModelDirective; let conditionInput: InputObjectTypeDefinitionNode; if ([MutationFieldType.CREATE, MutationFieldType.DELETE, MutationFieldType.UPDATE].includes(operation.type as MutationFieldType)) { - const condtionTypeName = toPascalCase(['Model', type.name.value, 'ConditionInput']); + const conditionTypeName = toPascalCase(['Model', type.name.value, 'ConditionInput']); const filterInputs = createEnumModelFilters(ctx, type); - conditionInput = makeMutationConditionInput(ctx, condtionTypeName, type); + conditionInput = makeMutationConditionInput(ctx, conditionTypeName, type); filterInputs.push(conditionInput); for (let input of filterInputs) { const conditionInputName = input.name.value; @@ -756,7 +756,12 @@ export class ModelTransformer extends TransformerModelBase implements Transforme return []; case MutationFieldType.CREATE: - const createInputField = makeCreateInputField(type, this.modelDirectiveConfig.get(type.name.value)!, knownModels); + const createInputField = makeCreateInputField( + type, + this.modelDirectiveConfig.get(type.name.value)!, + knownModels, + ctx.inputDocument, + ); const createInputTypeName = createInputField.name.value; if (!ctx.output.getType(createInputField.name.value)) { ctx.output.addInput(createInputField); @@ -778,7 +783,12 @@ export class ModelTransformer extends TransformerModelBase implements Transforme ]; case MutationFieldType.UPDATE: - const updateInputField = makeUpdateInputField(type, this.modelDirectiveConfig.get(type.name.value)!, knownModels); + const updateInputField = makeUpdateInputField( + type, + this.modelDirectiveConfig.get(type.name.value)!, + knownModels, + ctx.inputDocument, + ); const updateInputTypeName = updateInputField.name.value; if (!ctx.output.getType(updateInputField.name.value)) { ctx.output.addInput(updateInputField); @@ -795,7 +805,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme break; default: - throw new Error('Unkown operation type'); + throw new Error('Unknown operation type'); } return []; }; @@ -840,7 +850,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme if (def && def.kind == 'ObjectTypeDefinition' && !this.isModelField(def.name.value)) { const name = this.getNonModelInputObjectName(def.name.value); if (!ctx.output.getType(name)) { - const inputObj = InputObjectDefinitionWrapper.fromObject(name, def); + const inputObj = InputObjectDefinitionWrapper.fromObject(name, def, ctx.inputDocument); ctx.output.addInput(inputObj.serialize()); } } diff --git a/packages/amplify-graphql-model-transformer/src/graphql-types/mutation.ts b/packages/amplify-graphql-model-transformer/src/graphql-types/mutation.ts index 04a4a780214..4e9a5828fa2 100644 --- a/packages/amplify-graphql-model-transformer/src/graphql-types/mutation.ts +++ b/packages/amplify-graphql-model-transformer/src/graphql-types/mutation.ts @@ -1,5 +1,5 @@ import { TransformerTransformSchemaStepContextProvider } from '@aws-amplify/graphql-transformer-interfaces'; -import { ObjectTypeDefinitionNode, InputObjectTypeDefinitionNode } from 'graphql'; +import { ObjectTypeDefinitionNode, InputObjectTypeDefinitionNode, DocumentNode } from 'graphql'; import { ModelResourceIDs, toPascalCase } from 'graphql-transformer-common'; import { ModelDirectiveConfiguration } from '../graphql-model-transformer'; import { ObjectDefinitionWrapper, InputObjectDefinitionWrapper, InputFieldWrapper } from '../wrappers/object-definition-wrapper'; @@ -15,6 +15,7 @@ export const makeUpdateInputField = ( obj: ObjectTypeDefinitionNode, modelDirectiveConfig: ModelDirectiveConfiguration, knownModelTypes: Set, + document: DocumentNode, ): InputObjectTypeDefinitionNode => { // sync related things const objectWrapped = new ObjectDefinitionWrapper(obj); @@ -32,10 +33,12 @@ export const makeUpdateInputField = ( return field.getTypeName(); }); - const input = InputObjectDefinitionWrapper.fromObject(name, { + const objectTypeDefinition: ObjectTypeDefinitionNode = { ...obj, fields: obj.fields?.filter(f => !fieldsToRemove.includes(f.name.value)), - }); + }; + + const input = InputObjectDefinitionWrapper.fromObject(name, objectTypeDefinition, document); // make all the fields optional input.fields.forEach(f => f.makeNullable()); @@ -84,6 +87,7 @@ export const makeCreateInputField = ( obj: ObjectTypeDefinitionNode, modelDirectiveConfig: ModelDirectiveConfiguration, knownModelTypes: Set, + document: DocumentNode, ): InputObjectTypeDefinitionNode => { // sync related things const objectWrapped = new ObjectDefinitionWrapper(obj); @@ -102,10 +106,12 @@ export const makeCreateInputField = ( return field.getTypeName(); }); - const input = InputObjectDefinitionWrapper.fromObject(name, { + const objectTypeDefinition: ObjectTypeDefinitionNode = { ...obj, fields: obj.fields?.filter(f => !fieldsToRemove.includes(f.name.value)), - }); + }; + + const input = InputObjectDefinitionWrapper.fromObject(name, objectTypeDefinition, document); // Add id field and make it optional if (!hasIdField) { diff --git a/packages/amplify-graphql-model-transformer/src/wrappers/object-definition-wrapper.ts b/packages/amplify-graphql-model-transformer/src/wrappers/object-definition-wrapper.ts index b8077e85ee6..bb2caff0122 100644 --- a/packages/amplify-graphql-model-transformer/src/wrappers/object-definition-wrapper.ts +++ b/packages/amplify-graphql-model-transformer/src/wrappers/object-definition-wrapper.ts @@ -17,8 +17,17 @@ import { NamedTypeNode, EnumTypeDefinitionNode, Kind, + DocumentNode, } from 'graphql'; -import { DEFAULT_SCALARS, getBaseType, isScalar, ModelResourceIDs, unwrapNonNull, withNamedNodeNamed } from 'graphql-transformer-common'; +import { + DEFAULT_SCALARS, + getBaseType, + isEnum, + isScalar, + ModelResourceIDs, + unwrapNonNull, + withNamedNodeNamed, +} from 'graphql-transformer-common'; import { merge } from 'lodash'; // Todo: to be moved to core later. context.output.getObject would return wrapper type so its easier to manipulate @@ -181,7 +190,7 @@ export class InputFieldWrapper extends GenericFieldWrapper { }; }; - static fromField = (name: string, field: FieldDefinitionNode): InputFieldWrapper => { + static fromField = (name: string, field: FieldDefinitionNode, document: DocumentNode): InputFieldWrapper => { const autoGeneratableFieldsWithType: Record = { id: ['ID'], createdAt: ['AWSDateTime', 'String'], @@ -199,7 +208,7 @@ export class InputFieldWrapper extends GenericFieldWrapper { type = unwrapNonNull(field.type); } else { type = - isScalar(field.type) || getBaseType(field.type) === Kind.ENUM_TYPE_DEFINITION + isScalar(field.type) || isEnum(field.type, document) ? field.type : withNamedNodeNamed(field.type, ModelResourceIDs.NonModelInputObjectName(getBaseType(field.type))); } @@ -415,7 +424,7 @@ export class InputObjectDefinitionWrapper { return wrappedObj; }; - static fromObject = (name: string, def: ObjectTypeDefinitionNode): InputObjectDefinitionWrapper => { + static fromObject = (name: string, def: ObjectTypeDefinitionNode, document: DocumentNode): InputObjectDefinitionWrapper => { const inputObj: InputObjectTypeDefinitionNode = { kind: 'InputObjectTypeDefinition', name: { kind: 'Name', value: name }, @@ -425,7 +434,7 @@ export class InputObjectDefinitionWrapper { const wrappedInput = new InputObjectDefinitionWrapper(inputObj); for (let f of def.fields || []) { - const wrappedField = InputFieldWrapper.fromField(f.name.value, f); + const wrappedField = InputFieldWrapper.fromField(f.name.value, f, document); wrappedInput.fields.push(wrappedField); } return wrappedInput; diff --git a/packages/amplify-graphql-searchable-transformer/src/__tests__/__snapshots__/amplify-graphql-searchable-transformer.tests.ts.snap b/packages/amplify-graphql-searchable-transformer/src/__tests__/__snapshots__/amplify-graphql-searchable-transformer.tests.ts.snap index 976a98ba7a6..40828bcb609 100644 --- a/packages/amplify-graphql-searchable-transformer/src/__tests__/__snapshots__/amplify-graphql-searchable-transformer.tests.ts.snap +++ b/packages/amplify-graphql-searchable-transformer/src/__tests__/__snapshots__/amplify-graphql-searchable-transformer.tests.ts.snap @@ -268,7 +268,7 @@ input CreateEmployeeInput { id: ID firstName: String! lastName: String! - type: EmploymentTypeInput! + type: EmploymentType! } type Mutation { @@ -281,7 +281,7 @@ input UpdateEmployeeInput { id: ID! firstName: String lastName: String - type: EmploymentTypeInput + type: EmploymentType } input DeleteEmployeeInput { diff --git a/yarn.lock b/yarn.lock index 030790cef7d..1fefef31cdc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9892,14 +9892,6 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" - integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - change-case@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/change-case/-/change-case-3.1.0.tgz#0e611b7edc9952df2e8513b27b42de72647dd17e" From acd11b3fb61e6f95e97613eb949f27b3fd2d43a6 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 13:06:28 -0400 Subject: [PATCH 02/63] fix(graphql-model-transformer): implemented support for nested non model fields --- .../src/__tests__/model-transformer.test.ts | 56 +++++++++++++++++++ .../src/graphql-model-transformer.ts | 1 + yarn.lock | 8 --- 3 files changed, 57 insertions(+), 8 deletions(-) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 4b20ee9cdc6..48554b45249 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -10,6 +10,7 @@ import { getFieldOnObjectType, getInputType, getObjectType, + verifyInputCount, verifyMatchingTypes, } from './test-utils/helpers'; @@ -368,4 +369,59 @@ describe('ModelTransformer: ', () => { const commentInputIDField = getFieldOnInputType(commentInputObject!, 'id'); verifyMatchingTypes(commentObjectIDField.type, commentInputIDField.type); }); + + it('should support non-model types and enums', () => { + const validSchema = ` + type Post @model { + id: ID! + title: String! + createdAt: String + updatedAt: String + metadata: [PostMetadata!]! + appearsIn: [Episode]! + } + type PostMetadata { + tags: Tag + } + type Tag { + published: Boolean + metadata: PostMetadata + } + enum Episode { + NEWHOPE + EMPIRE + JEDI + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + + const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); + expect(postMetaDataInputType).toBeDefined(); + const tagInputType = getInputType(parsed, 'TagInput'); + expect(tagInputType).toBeDefined(); + expectFieldsOnInputType(tagInputType!, ['metadata']); + const createPostInputType = getInputType(parsed, 'CreatePostInput'); + expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); + const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); + expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); + + const postModelObject = getObjectType(parsed, 'Post'); + const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); + const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); + // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" + // in the generated CreatePostInput type - its types should be the same as in the Post @model type + verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); + + expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); + }); }); diff --git a/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts b/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts index f7106e58fe7..ed633e5b378 100644 --- a/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts +++ b/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts @@ -842,6 +842,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme if (!ctx.output.getType(name)) { const inputObj = InputObjectDefinitionWrapper.fromObject(name, def); ctx.output.addInput(inputObj.serialize()); + this.createNonModelInputs(ctx, def); } } } diff --git a/yarn.lock b/yarn.lock index 030790cef7d..1fefef31cdc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9892,14 +9892,6 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" - integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - change-case@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/change-case/-/change-case-3.1.0.tgz#0e611b7edc9952df2e8513b27b42de72647dd17e" From ab58a003e98f6069a2ad364b1ddc7103d79274ac Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 13:06:28 -0400 Subject: [PATCH 03/63] fix(graphql-model-transformer): implemented support for nested non model fields --- .../src/__tests__/model-transformer.test.ts | 56 +++++++++++++++++++ .../src/graphql-model-transformer.ts | 1 + 2 files changed, 57 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index f373df72e2a..ccdb16a8f29 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -10,6 +10,7 @@ import { getFieldOnObjectType, getInputType, getObjectType, + verifyInputCount, verifyMatchingTypes, } from './test-utils/helpers'; @@ -438,4 +439,59 @@ describe('ModelTransformer: ', () => { const updateTestInput = getInputType(parsed, 'CreateTestInput'); expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); }); + + it('should support non-model types and enums', () => { + const validSchema = ` + type Post @model { + id: ID! + title: String! + createdAt: String + updatedAt: String + metadata: [PostMetadata!]! + appearsIn: [Episode]! + } + type PostMetadata { + tags: Tag + } + type Tag { + published: Boolean + metadata: PostMetadata + } + enum Episode { + NEWHOPE + EMPIRE + JEDI + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + + const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); + expect(postMetaDataInputType).toBeDefined(); + const tagInputType = getInputType(parsed, 'TagInput'); + expect(tagInputType).toBeDefined(); + expectFieldsOnInputType(tagInputType!, ['metadata']); + const createPostInputType = getInputType(parsed, 'CreatePostInput'); + expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); + const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); + expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); + + const postModelObject = getObjectType(parsed, 'Post'); + const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); + const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); + // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" + // in the generated CreatePostInput type - its types should be the same as in the Post @model type + verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); + + expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); + }); }); diff --git a/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts b/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts index fb3d7740892..9f0c436de49 100644 --- a/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts +++ b/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts @@ -864,6 +864,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme if (!ctx.output.getType(name)) { const inputObj = InputObjectDefinitionWrapper.fromObject(name, def, ctx.inputDocument); ctx.output.addInput(inputObj.serialize()); + this.createNonModelInputs(ctx, def); } } } From 2c929b969879252506fdb76954111b5b2cc38973 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 04/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index ccdb16a8f29..f5beb9136a6 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -494,4 +494,31 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); + + it('should support enum as a field', () => { + const validSchema = ` + enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } + type Test @model { + status: Status! + lastStatus: Status! + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const createTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); + + const updateTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + }); }); From 381dce7669bc6588938327cb9cc7109ad79b952f Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 13:06:28 -0400 Subject: [PATCH 05/63] fix(graphql-model-transformer): implemented support for nested non model fields --- .../src/__tests__/model-transformer.test.ts | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index f5beb9136a6..5448f513dd7 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -521,4 +521,59 @@ describe('ModelTransformer: ', () => { const updateTestInput = getInputType(parsed, 'CreateTestInput'); expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); }); + + it('should support non-model types and enums', () => { + const validSchema = ` + type Post @model { + id: ID! + title: String! + createdAt: String + updatedAt: String + metadata: [PostMetadata!]! + appearsIn: [Episode]! + } + type PostMetadata { + tags: Tag + } + type Tag { + published: Boolean + metadata: PostMetadata + } + enum Episode { + NEWHOPE + EMPIRE + JEDI + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + + const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); + expect(postMetaDataInputType).toBeDefined(); + const tagInputType = getInputType(parsed, 'TagInput'); + expect(tagInputType).toBeDefined(); + expectFieldsOnInputType(tagInputType!, ['metadata']); + const createPostInputType = getInputType(parsed, 'CreatePostInput'); + expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); + const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); + expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); + + const postModelObject = getObjectType(parsed, 'Post'); + const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); + const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); + // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" + // in the generated CreatePostInput type - its types should be the same as in the Post @model type + verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); + + expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); + }); }); From af162244de59c6ea2630a6506c873593bf76510a Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 06/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 5448f513dd7..32be212c6e4 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -576,4 +576,31 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); + + it('should support enum as a field', () => { + const validSchema = ` + enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } + type Test @model { + status: Status! + lastStatus: Status! + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const createTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); + + const updateTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + }); }); From 5d0efd5a242dbded5385f4b335b946d1a3bac16f Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 13:06:28 -0400 Subject: [PATCH 07/63] fix(graphql-model-transformer): implemented support for nested non model fields --- .../src/__tests__/model-transformer.test.ts | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 32be212c6e4..9c1dc89ec6c 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -603,4 +603,59 @@ describe('ModelTransformer: ', () => { const updateTestInput = getInputType(parsed, 'CreateTestInput'); expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); }); + + it('should support non-model types and enums', () => { + const validSchema = ` + type Post @model { + id: ID! + title: String! + createdAt: String + updatedAt: String + metadata: [PostMetadata!]! + appearsIn: [Episode]! + } + type PostMetadata { + tags: Tag + } + type Tag { + published: Boolean + metadata: PostMetadata + } + enum Episode { + NEWHOPE + EMPIRE + JEDI + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + + const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); + expect(postMetaDataInputType).toBeDefined(); + const tagInputType = getInputType(parsed, 'TagInput'); + expect(tagInputType).toBeDefined(); + expectFieldsOnInputType(tagInputType!, ['metadata']); + const createPostInputType = getInputType(parsed, 'CreatePostInput'); + expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); + const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); + expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); + + const postModelObject = getObjectType(parsed, 'Post'); + const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); + const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); + // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" + // in the generated CreatePostInput type - its types should be the same as in the Post @model type + verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); + + expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); + }); }); From 06eb29621a83bd130178ebedfff2a2e1aab4dd00 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 08/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 9c1dc89ec6c..316e2bed07b 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -658,4 +658,31 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); + + it('should support enum as a field', () => { + const validSchema = ` + enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } + type Test @model { + status: Status! + lastStatus: Status! + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const createTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); + + const updateTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + }); }); From 6290533eb064a103e728aa57ba05d0995ef4e29c Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 13:06:28 -0400 Subject: [PATCH 09/63] fix(graphql-model-transformer): implemented support for nested non model fields --- .../src/__tests__/model-transformer.test.ts | 56 +++++++++++++++++++ .../src/graphql-model-transformer.ts | 1 + 2 files changed, 57 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index f373df72e2a..ccdb16a8f29 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -10,6 +10,7 @@ import { getFieldOnObjectType, getInputType, getObjectType, + verifyInputCount, verifyMatchingTypes, } from './test-utils/helpers'; @@ -438,4 +439,59 @@ describe('ModelTransformer: ', () => { const updateTestInput = getInputType(parsed, 'CreateTestInput'); expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); }); + + it('should support non-model types and enums', () => { + const validSchema = ` + type Post @model { + id: ID! + title: String! + createdAt: String + updatedAt: String + metadata: [PostMetadata!]! + appearsIn: [Episode]! + } + type PostMetadata { + tags: Tag + } + type Tag { + published: Boolean + metadata: PostMetadata + } + enum Episode { + NEWHOPE + EMPIRE + JEDI + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + + const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); + expect(postMetaDataInputType).toBeDefined(); + const tagInputType = getInputType(parsed, 'TagInput'); + expect(tagInputType).toBeDefined(); + expectFieldsOnInputType(tagInputType!, ['metadata']); + const createPostInputType = getInputType(parsed, 'CreatePostInput'); + expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); + const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); + expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); + + const postModelObject = getObjectType(parsed, 'Post'); + const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); + const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); + // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" + // in the generated CreatePostInput type - its types should be the same as in the Post @model type + verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); + + expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); + }); }); diff --git a/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts b/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts index fb3d7740892..9f0c436de49 100644 --- a/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts +++ b/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts @@ -864,6 +864,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme if (!ctx.output.getType(name)) { const inputObj = InputObjectDefinitionWrapper.fromObject(name, def, ctx.inputDocument); ctx.output.addInput(inputObj.serialize()); + this.createNonModelInputs(ctx, def); } } } From 83b139464a4627516ba5b1f4f8f55e840eb2313c Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 10/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index ccdb16a8f29..f5beb9136a6 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -494,4 +494,31 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); + + it('should support enum as a field', () => { + const validSchema = ` + enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } + type Test @model { + status: Status! + lastStatus: Status! + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const createTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); + + const updateTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + }); }); From f5aa8a8980b29ea5425049fb116c040a374f3488 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 13:06:28 -0400 Subject: [PATCH 11/63] fix(graphql-model-transformer): implemented support for nested non model fields --- .../src/__tests__/model-transformer.test.ts | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index f5beb9136a6..5448f513dd7 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -521,4 +521,59 @@ describe('ModelTransformer: ', () => { const updateTestInput = getInputType(parsed, 'CreateTestInput'); expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); }); + + it('should support non-model types and enums', () => { + const validSchema = ` + type Post @model { + id: ID! + title: String! + createdAt: String + updatedAt: String + metadata: [PostMetadata!]! + appearsIn: [Episode]! + } + type PostMetadata { + tags: Tag + } + type Tag { + published: Boolean + metadata: PostMetadata + } + enum Episode { + NEWHOPE + EMPIRE + JEDI + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + + const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); + expect(postMetaDataInputType).toBeDefined(); + const tagInputType = getInputType(parsed, 'TagInput'); + expect(tagInputType).toBeDefined(); + expectFieldsOnInputType(tagInputType!, ['metadata']); + const createPostInputType = getInputType(parsed, 'CreatePostInput'); + expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); + const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); + expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); + + const postModelObject = getObjectType(parsed, 'Post'); + const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); + const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); + // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" + // in the generated CreatePostInput type - its types should be the same as in the Post @model type + verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); + + expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); + }); }); From 511ea1875d7775cf14baf5895a6f76b05700bbd4 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 12/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 5448f513dd7..32be212c6e4 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -576,4 +576,31 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); + + it('should support enum as a field', () => { + const validSchema = ` + enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } + type Test @model { + status: Status! + lastStatus: Status! + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const createTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); + + const updateTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + }); }); From 817e0b5aeed5bc913efbf475d9d2e7bb4c5148a9 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 13:06:28 -0400 Subject: [PATCH 13/63] fix(graphql-model-transformer): implemented support for nested non model fields --- .../src/__tests__/model-transformer.test.ts | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 32be212c6e4..9c1dc89ec6c 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -603,4 +603,59 @@ describe('ModelTransformer: ', () => { const updateTestInput = getInputType(parsed, 'CreateTestInput'); expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); }); + + it('should support non-model types and enums', () => { + const validSchema = ` + type Post @model { + id: ID! + title: String! + createdAt: String + updatedAt: String + metadata: [PostMetadata!]! + appearsIn: [Episode]! + } + type PostMetadata { + tags: Tag + } + type Tag { + published: Boolean + metadata: PostMetadata + } + enum Episode { + NEWHOPE + EMPIRE + JEDI + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + + const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); + expect(postMetaDataInputType).toBeDefined(); + const tagInputType = getInputType(parsed, 'TagInput'); + expect(tagInputType).toBeDefined(); + expectFieldsOnInputType(tagInputType!, ['metadata']); + const createPostInputType = getInputType(parsed, 'CreatePostInput'); + expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); + const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); + expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); + + const postModelObject = getObjectType(parsed, 'Post'); + const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); + const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); + // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" + // in the generated CreatePostInput type - its types should be the same as in the Post @model type + verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); + + expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); + }); }); From cea378b01cfd52194f90b04217fb11b9ad89a9fe Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 14/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 9c1dc89ec6c..316e2bed07b 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -658,4 +658,31 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); + + it('should support enum as a field', () => { + const validSchema = ` + enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } + type Test @model { + status: Status! + lastStatus: Status! + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const createTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); + + const updateTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + }); }); From be66578d16cb3c02a2e76d9d291001fe74c1b257 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 13:06:28 -0400 Subject: [PATCH 15/63] fix(graphql-model-transformer): implemented support for nested non model fields --- .../src/__tests__/model-transformer.test.ts | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 316e2bed07b..8e8571f27ba 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -685,4 +685,59 @@ describe('ModelTransformer: ', () => { const updateTestInput = getInputType(parsed, 'CreateTestInput'); expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); }); + + it('should support non-model types and enums', () => { + const validSchema = ` + type Post @model { + id: ID! + title: String! + createdAt: String + updatedAt: String + metadata: [PostMetadata!]! + appearsIn: [Episode]! + } + type PostMetadata { + tags: Tag + } + type Tag { + published: Boolean + metadata: PostMetadata + } + enum Episode { + NEWHOPE + EMPIRE + JEDI + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + + const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); + expect(postMetaDataInputType).toBeDefined(); + const tagInputType = getInputType(parsed, 'TagInput'); + expect(tagInputType).toBeDefined(); + expectFieldsOnInputType(tagInputType!, ['metadata']); + const createPostInputType = getInputType(parsed, 'CreatePostInput'); + expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); + const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); + expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); + + const postModelObject = getObjectType(parsed, 'Post'); + const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); + const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); + // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" + // in the generated CreatePostInput type - its types should be the same as in the Post @model type + verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); + + expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); + }); }); From e3e6f15771b535004ae55e3b5b6a050346d9c136 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 16/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 8e8571f27ba..7e946cb28e3 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -740,4 +740,31 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); + + it('should support enum as a field', () => { + const validSchema = ` + enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } + type Test @model { + status: Status! + lastStatus: Status! + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const createTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); + + const updateTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + }); }); From cacdda526e5a49e587a2cd6a0e6582e9530ebb27 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Mon, 9 Aug 2021 12:06:27 -0400 Subject: [PATCH 17/63] chore(graphql-model-transformer): added validateModelSchema to unit test --- .../src/__tests__/model-transformer.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index ccdb16a8f29..7dbe8704e84 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -473,6 +473,7 @@ describe('ModelTransformer: ', () => { const definition = out.schema; expect(definition).toBeDefined(); const parsed = parse(definition); + validateModelSchema(parsed); const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); expect(postMetaDataInputType).toBeDefined(); From 59f2ee5643153575b1d3c107fa9410ada5d0b56c Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 13:06:28 -0400 Subject: [PATCH 18/63] fix(graphql-model-transformer): implemented support for nested non model fields --- .../src/__tests__/model-transformer.test.ts | 273 ------------------ 1 file changed, 273 deletions(-) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 7e946cb28e3..ccdb16a8f29 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -494,277 +494,4 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); - - it('should support enum as a field', () => { - const validSchema = ` - enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } - type Test @model { - status: Status! - lastStatus: Status! - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - validateModelSchema(parsed); - - const createTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); - - const updateTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); - }); - - it('should support non-model types and enums', () => { - const validSchema = ` - type Post @model { - id: ID! - title: String! - createdAt: String - updatedAt: String - metadata: [PostMetadata!]! - appearsIn: [Episode]! - } - type PostMetadata { - tags: Tag - } - type Tag { - published: Boolean - metadata: PostMetadata - } - enum Episode { - NEWHOPE - EMPIRE - JEDI - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - - const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); - expect(postMetaDataInputType).toBeDefined(); - const tagInputType = getInputType(parsed, 'TagInput'); - expect(tagInputType).toBeDefined(); - expectFieldsOnInputType(tagInputType!, ['metadata']); - const createPostInputType = getInputType(parsed, 'CreatePostInput'); - expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); - const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); - expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); - - const postModelObject = getObjectType(parsed, 'Post'); - const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); - const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); - // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" - // in the generated CreatePostInput type - its types should be the same as in the Post @model type - verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); - - expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); - }); - - it('should support enum as a field', () => { - const validSchema = ` - enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } - type Test @model { - status: Status! - lastStatus: Status! - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - validateModelSchema(parsed); - - const createTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); - - const updateTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); - }); - - it('should support non-model types and enums', () => { - const validSchema = ` - type Post @model { - id: ID! - title: String! - createdAt: String - updatedAt: String - metadata: [PostMetadata!]! - appearsIn: [Episode]! - } - type PostMetadata { - tags: Tag - } - type Tag { - published: Boolean - metadata: PostMetadata - } - enum Episode { - NEWHOPE - EMPIRE - JEDI - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - - const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); - expect(postMetaDataInputType).toBeDefined(); - const tagInputType = getInputType(parsed, 'TagInput'); - expect(tagInputType).toBeDefined(); - expectFieldsOnInputType(tagInputType!, ['metadata']); - const createPostInputType = getInputType(parsed, 'CreatePostInput'); - expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); - const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); - expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); - - const postModelObject = getObjectType(parsed, 'Post'); - const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); - const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); - // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" - // in the generated CreatePostInput type - its types should be the same as in the Post @model type - verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); - - expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); - }); - - it('should support enum as a field', () => { - const validSchema = ` - enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } - type Test @model { - status: Status! - lastStatus: Status! - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - validateModelSchema(parsed); - - const createTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); - - const updateTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); - }); - - it('should support non-model types and enums', () => { - const validSchema = ` - type Post @model { - id: ID! - title: String! - createdAt: String - updatedAt: String - metadata: [PostMetadata!]! - appearsIn: [Episode]! - } - type PostMetadata { - tags: Tag - } - type Tag { - published: Boolean - metadata: PostMetadata - } - enum Episode { - NEWHOPE - EMPIRE - JEDI - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - - const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); - expect(postMetaDataInputType).toBeDefined(); - const tagInputType = getInputType(parsed, 'TagInput'); - expect(tagInputType).toBeDefined(); - expectFieldsOnInputType(tagInputType!, ['metadata']); - const createPostInputType = getInputType(parsed, 'CreatePostInput'); - expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); - const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); - expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); - - const postModelObject = getObjectType(parsed, 'Post'); - const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); - const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); - // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" - // in the generated CreatePostInput type - its types should be the same as in the Post @model type - verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); - - expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); - }); - - it('should support enum as a field', () => { - const validSchema = ` - enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } - type Test @model { - status: Status! - lastStatus: Status! - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - validateModelSchema(parsed); - - const createTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); - - const updateTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); - }); }); From e1ab79661f3211ea3704f959b8477839dded7a76 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 19/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index ccdb16a8f29..f5beb9136a6 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -494,4 +494,31 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); + + it('should support enum as a field', () => { + const validSchema = ` + enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } + type Test @model { + status: Status! + lastStatus: Status! + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const createTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); + + const updateTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + }); }); From 2932fbb78b948232c43ed309e79872d2e0f9ea87 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 13:06:28 -0400 Subject: [PATCH 20/63] fix(graphql-model-transformer): implemented support for nested non model fields --- .../src/__tests__/model-transformer.test.ts | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index f5beb9136a6..5448f513dd7 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -521,4 +521,59 @@ describe('ModelTransformer: ', () => { const updateTestInput = getInputType(parsed, 'CreateTestInput'); expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); }); + + it('should support non-model types and enums', () => { + const validSchema = ` + type Post @model { + id: ID! + title: String! + createdAt: String + updatedAt: String + metadata: [PostMetadata!]! + appearsIn: [Episode]! + } + type PostMetadata { + tags: Tag + } + type Tag { + published: Boolean + metadata: PostMetadata + } + enum Episode { + NEWHOPE + EMPIRE + JEDI + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + + const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); + expect(postMetaDataInputType).toBeDefined(); + const tagInputType = getInputType(parsed, 'TagInput'); + expect(tagInputType).toBeDefined(); + expectFieldsOnInputType(tagInputType!, ['metadata']); + const createPostInputType = getInputType(parsed, 'CreatePostInput'); + expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); + const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); + expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); + + const postModelObject = getObjectType(parsed, 'Post'); + const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); + const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); + // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" + // in the generated CreatePostInput type - its types should be the same as in the Post @model type + verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); + + expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); + }); }); From 0780838433f7ee3de950e5627ee66b8c7028eaf7 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 21/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 5448f513dd7..32be212c6e4 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -576,4 +576,31 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); + + it('should support enum as a field', () => { + const validSchema = ` + enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } + type Test @model { + status: Status! + lastStatus: Status! + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const createTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); + + const updateTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + }); }); From 5351aeb0f87dd526641b701ce8592f058ab62796 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 13:06:28 -0400 Subject: [PATCH 22/63] fix(graphql-model-transformer): implemented support for nested non model fields --- .../src/__tests__/model-transformer.test.ts | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 32be212c6e4..9c1dc89ec6c 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -603,4 +603,59 @@ describe('ModelTransformer: ', () => { const updateTestInput = getInputType(parsed, 'CreateTestInput'); expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); }); + + it('should support non-model types and enums', () => { + const validSchema = ` + type Post @model { + id: ID! + title: String! + createdAt: String + updatedAt: String + metadata: [PostMetadata!]! + appearsIn: [Episode]! + } + type PostMetadata { + tags: Tag + } + type Tag { + published: Boolean + metadata: PostMetadata + } + enum Episode { + NEWHOPE + EMPIRE + JEDI + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + + const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); + expect(postMetaDataInputType).toBeDefined(); + const tagInputType = getInputType(parsed, 'TagInput'); + expect(tagInputType).toBeDefined(); + expectFieldsOnInputType(tagInputType!, ['metadata']); + const createPostInputType = getInputType(parsed, 'CreatePostInput'); + expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); + const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); + expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); + + const postModelObject = getObjectType(parsed, 'Post'); + const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); + const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); + // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" + // in the generated CreatePostInput type - its types should be the same as in the Post @model type + verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); + + expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); + }); }); From d44a306c070142941b4a3fb196ebe38b109898ef Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 23/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 9c1dc89ec6c..316e2bed07b 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -658,4 +658,31 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); + + it('should support enum as a field', () => { + const validSchema = ` + enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } + type Test @model { + status: Status! + lastStatus: Status! + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const createTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); + + const updateTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + }); }); From af6693249b9eb2e76e4ea4c11c464660ccbf6c13 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 13:06:28 -0400 Subject: [PATCH 24/63] fix(graphql-model-transformer): implemented support for nested non model fields --- .../src/__tests__/model-transformer.test.ts | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 316e2bed07b..8e8571f27ba 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -685,4 +685,59 @@ describe('ModelTransformer: ', () => { const updateTestInput = getInputType(parsed, 'CreateTestInput'); expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); }); + + it('should support non-model types and enums', () => { + const validSchema = ` + type Post @model { + id: ID! + title: String! + createdAt: String + updatedAt: String + metadata: [PostMetadata!]! + appearsIn: [Episode]! + } + type PostMetadata { + tags: Tag + } + type Tag { + published: Boolean + metadata: PostMetadata + } + enum Episode { + NEWHOPE + EMPIRE + JEDI + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + + const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); + expect(postMetaDataInputType).toBeDefined(); + const tagInputType = getInputType(parsed, 'TagInput'); + expect(tagInputType).toBeDefined(); + expectFieldsOnInputType(tagInputType!, ['metadata']); + const createPostInputType = getInputType(parsed, 'CreatePostInput'); + expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); + const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); + expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); + + const postModelObject = getObjectType(parsed, 'Post'); + const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); + const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); + // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" + // in the generated CreatePostInput type - its types should be the same as in the Post @model type + verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); + + expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); + }); }); From 9a819809f8961f24cecc70cb5a2d146a1bbd8406 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 25/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 8e8571f27ba..7e946cb28e3 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -740,4 +740,31 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); + + it('should support enum as a field', () => { + const validSchema = ` + enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } + type Test @model { + status: Status! + lastStatus: Status! + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const createTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); + + const updateTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + }); }); From 36e36864120e100fb36c73cbfb4afbb20dbf0dfc Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Mon, 9 Aug 2021 12:06:27 -0400 Subject: [PATCH 26/63] chore(graphql-model-transformer): added validateModelSchema to unit test --- .../src/__tests__/model-transformer.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 7e946cb28e3..7e7c4ebdc46 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -473,6 +473,7 @@ describe('ModelTransformer: ', () => { const definition = out.schema; expect(definition).toBeDefined(); const parsed = parse(definition); + validateModelSchema(parsed); const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); expect(postMetaDataInputType).toBeDefined(); From faeb1a03b625ce20cb6f11c92e3ef5ae6656189f Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Mon, 9 Aug 2021 12:14:33 -0400 Subject: [PATCH 27/63] chore(graphql-model-transformer): added validateModelSchema to unit test --- .../src/__tests__/model-transformer.test.ts | 167 +----------------- 1 file changed, 1 insertion(+), 166 deletions(-) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 7e7c4ebdc46..e3a6155e4fe 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -440,62 +440,6 @@ describe('ModelTransformer: ', () => { expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); }); - it('should support non-model types and enums', () => { - const validSchema = ` - type Post @model { - id: ID! - title: String! - createdAt: String - updatedAt: String - metadata: [PostMetadata!]! - appearsIn: [Episode]! - } - type PostMetadata { - tags: Tag - } - type Tag { - published: Boolean - metadata: PostMetadata - } - enum Episode { - NEWHOPE - EMPIRE - JEDI - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - validateModelSchema(parsed); - - const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); - expect(postMetaDataInputType).toBeDefined(); - const tagInputType = getInputType(parsed, 'TagInput'); - expect(tagInputType).toBeDefined(); - expectFieldsOnInputType(tagInputType!, ['metadata']); - const createPostInputType = getInputType(parsed, 'CreatePostInput'); - expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); - const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); - expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); - - const postModelObject = getObjectType(parsed, 'Post'); - const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); - const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); - // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" - // in the generated CreatePostInput type - its types should be the same as in the Post @model type - verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); - - expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); - }); - it('should support enum as a field', () => { const validSchema = ` enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } @@ -523,61 +467,6 @@ describe('ModelTransformer: ', () => { expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); }); - it('should support non-model types and enums', () => { - const validSchema = ` - type Post @model { - id: ID! - title: String! - createdAt: String - updatedAt: String - metadata: [PostMetadata!]! - appearsIn: [Episode]! - } - type PostMetadata { - tags: Tag - } - type Tag { - published: Boolean - metadata: PostMetadata - } - enum Episode { - NEWHOPE - EMPIRE - JEDI - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - - const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); - expect(postMetaDataInputType).toBeDefined(); - const tagInputType = getInputType(parsed, 'TagInput'); - expect(tagInputType).toBeDefined(); - expectFieldsOnInputType(tagInputType!, ['metadata']); - const createPostInputType = getInputType(parsed, 'CreatePostInput'); - expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); - const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); - expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); - - const postModelObject = getObjectType(parsed, 'Post'); - const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); - const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); - // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" - // in the generated CreatePostInput type - its types should be the same as in the Post @model type - verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); - - expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); - }); - it('should support enum as a field', () => { const validSchema = ` enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } @@ -605,61 +494,6 @@ describe('ModelTransformer: ', () => { expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); }); - it('should support non-model types and enums', () => { - const validSchema = ` - type Post @model { - id: ID! - title: String! - createdAt: String - updatedAt: String - metadata: [PostMetadata!]! - appearsIn: [Episode]! - } - type PostMetadata { - tags: Tag - } - type Tag { - published: Boolean - metadata: PostMetadata - } - enum Episode { - NEWHOPE - EMPIRE - JEDI - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - - const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); - expect(postMetaDataInputType).toBeDefined(); - const tagInputType = getInputType(parsed, 'TagInput'); - expect(tagInputType).toBeDefined(); - expectFieldsOnInputType(tagInputType!, ['metadata']); - const createPostInputType = getInputType(parsed, 'CreatePostInput'); - expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); - const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); - expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); - - const postModelObject = getObjectType(parsed, 'Post'); - const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); - const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); - // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" - // in the generated CreatePostInput type - its types should be the same as in the Post @model type - verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); - - expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); - }); - it('should support enum as a field', () => { const validSchema = ` enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } @@ -720,6 +554,7 @@ describe('ModelTransformer: ', () => { const definition = out.schema; expect(definition).toBeDefined(); const parsed = parse(definition); + validateModelSchema(parsed); const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); expect(postMetaDataInputType).toBeDefined(); From d7b587186b3919105d282bee354f42ed1b421419 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 13:06:28 -0400 Subject: [PATCH 28/63] fix(graphql-model-transformer): implemented support for nested non model fields --- .../src/__tests__/model-transformer.test.ts | 109 ------------------ 1 file changed, 109 deletions(-) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index e3a6155e4fe..4dacc13e8ac 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -440,87 +440,6 @@ describe('ModelTransformer: ', () => { expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); }); - it('should support enum as a field', () => { - const validSchema = ` - enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } - type Test @model { - status: Status! - lastStatus: Status! - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - validateModelSchema(parsed); - - const createTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); - - const updateTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); - }); - - it('should support enum as a field', () => { - const validSchema = ` - enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } - type Test @model { - status: Status! - lastStatus: Status! - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - validateModelSchema(parsed); - - const createTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); - - const updateTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); - }); - - it('should support enum as a field', () => { - const validSchema = ` - enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } - type Test @model { - status: Status! - lastStatus: Status! - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - validateModelSchema(parsed); - - const createTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); - - const updateTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); - }); - it('should support non-model types and enums', () => { const validSchema = ` type Post @model { @@ -555,7 +474,6 @@ describe('ModelTransformer: ', () => { expect(definition).toBeDefined(); const parsed = parse(definition); validateModelSchema(parsed); - const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); expect(postMetaDataInputType).toBeDefined(); const tagInputType = getInputType(parsed, 'TagInput'); @@ -576,31 +494,4 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); - - it('should support enum as a field', () => { - const validSchema = ` - enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } - type Test @model { - status: Status! - lastStatus: Status! - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - validateModelSchema(parsed); - - const createTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); - - const updateTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); - }); }); From 8869c6fa0356411f26df0e176c317498ee58fab8 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 29/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 4dacc13e8ac..e4823b51b30 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -494,4 +494,31 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); + + it('should support enum as a field', () => { + const validSchema = ` + enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } + type Test @model { + status: Status! + lastStatus: Status! + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const createTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); + + const updateTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + }); }); From 425573d064ba11498bd95ff4b5de830f7d15b5fb Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 13:06:28 -0400 Subject: [PATCH 30/63] fix(graphql-model-transformer): implemented support for nested non model fields --- .../src/__tests__/model-transformer.test.ts | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index e4823b51b30..d889057fc82 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -521,4 +521,59 @@ describe('ModelTransformer: ', () => { const updateTestInput = getInputType(parsed, 'CreateTestInput'); expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); }); + + it('should support non-model types and enums', () => { + const validSchema = ` + type Post @model { + id: ID! + title: String! + createdAt: String + updatedAt: String + metadata: [PostMetadata!]! + appearsIn: [Episode]! + } + type PostMetadata { + tags: Tag + } + type Tag { + published: Boolean + metadata: PostMetadata + } + enum Episode { + NEWHOPE + EMPIRE + JEDI + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + + const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); + expect(postMetaDataInputType).toBeDefined(); + const tagInputType = getInputType(parsed, 'TagInput'); + expect(tagInputType).toBeDefined(); + expectFieldsOnInputType(tagInputType!, ['metadata']); + const createPostInputType = getInputType(parsed, 'CreatePostInput'); + expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); + const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); + expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); + + const postModelObject = getObjectType(parsed, 'Post'); + const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); + const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); + // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" + // in the generated CreatePostInput type - its types should be the same as in the Post @model type + verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); + + expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); + }); }); From 1bcede30d9949a9394cb4caebcc6ec5b8e2965bb Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 31/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index d889057fc82..5e90b3b65a2 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -576,4 +576,31 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); + + it('should support enum as a field', () => { + const validSchema = ` + enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } + type Test @model { + status: Status! + lastStatus: Status! + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const createTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); + + const updateTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + }); }); From a7668e3c0066f813292b262646e27a699ef3fca5 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 13:06:28 -0400 Subject: [PATCH 32/63] fix(graphql-model-transformer): implemented support for nested non model fields --- .../src/__tests__/model-transformer.test.ts | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 5e90b3b65a2..122f551ed51 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -603,4 +603,59 @@ describe('ModelTransformer: ', () => { const updateTestInput = getInputType(parsed, 'CreateTestInput'); expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); }); + + it('should support non-model types and enums', () => { + const validSchema = ` + type Post @model { + id: ID! + title: String! + createdAt: String + updatedAt: String + metadata: [PostMetadata!]! + appearsIn: [Episode]! + } + type PostMetadata { + tags: Tag + } + type Tag { + published: Boolean + metadata: PostMetadata + } + enum Episode { + NEWHOPE + EMPIRE + JEDI + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + + const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); + expect(postMetaDataInputType).toBeDefined(); + const tagInputType = getInputType(parsed, 'TagInput'); + expect(tagInputType).toBeDefined(); + expectFieldsOnInputType(tagInputType!, ['metadata']); + const createPostInputType = getInputType(parsed, 'CreatePostInput'); + expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); + const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); + expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); + + const postModelObject = getObjectType(parsed, 'Post'); + const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); + const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); + // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" + // in the generated CreatePostInput type - its types should be the same as in the Post @model type + verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); + + expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); + }); }); From d1dc974887103cc01653f4116d451d25f014755e Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 33/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 122f551ed51..ad7ba2524c9 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -658,4 +658,31 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); + + it('should support enum as a field', () => { + const validSchema = ` + enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } + type Test @model { + status: Status! + lastStatus: Status! + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const createTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); + + const updateTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + }); }); From 2f7f88d19bca00e5ec2ddbfdd6b6e8c6884b141a Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 13:06:28 -0400 Subject: [PATCH 34/63] fix(graphql-model-transformer): implemented support for nested non model fields --- .../src/__tests__/model-transformer.test.ts | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index ad7ba2524c9..2ae8c8577b4 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -685,4 +685,59 @@ describe('ModelTransformer: ', () => { const updateTestInput = getInputType(parsed, 'CreateTestInput'); expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); }); + + it('should support non-model types and enums', () => { + const validSchema = ` + type Post @model { + id: ID! + title: String! + createdAt: String + updatedAt: String + metadata: [PostMetadata!]! + appearsIn: [Episode]! + } + type PostMetadata { + tags: Tag + } + type Tag { + published: Boolean + metadata: PostMetadata + } + enum Episode { + NEWHOPE + EMPIRE + JEDI + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + + const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); + expect(postMetaDataInputType).toBeDefined(); + const tagInputType = getInputType(parsed, 'TagInput'); + expect(tagInputType).toBeDefined(); + expectFieldsOnInputType(tagInputType!, ['metadata']); + const createPostInputType = getInputType(parsed, 'CreatePostInput'); + expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); + const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); + expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); + + const postModelObject = getObjectType(parsed, 'Post'); + const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); + const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); + // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" + // in the generated CreatePostInput type - its types should be the same as in the Post @model type + verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); + + expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); + }); }); From d771e98fbad5a46acc66ffa6154e199338acb478 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 35/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 2ae8c8577b4..be8eab6b775 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -740,4 +740,31 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); + + it('should support enum as a field', () => { + const validSchema = ` + enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } + type Test @model { + status: Status! + lastStatus: Status! + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const createTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); + + const updateTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + }); }); From a35d4455ad6235da4f92fb2076dbd4d86f18f659 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Mon, 9 Aug 2021 12:06:27 -0400 Subject: [PATCH 36/63] chore(graphql-model-transformer): added validateModelSchema to unit test --- .../src/__tests__/model-transformer.test.ts | 217 ------------------ 1 file changed, 217 deletions(-) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index be8eab6b775..329e4caacd0 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -474,87 +474,6 @@ describe('ModelTransformer: ', () => { expect(definition).toBeDefined(); const parsed = parse(definition); validateModelSchema(parsed); - const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); - expect(postMetaDataInputType).toBeDefined(); - const tagInputType = getInputType(parsed, 'TagInput'); - expect(tagInputType).toBeDefined(); - expectFieldsOnInputType(tagInputType!, ['metadata']); - const createPostInputType = getInputType(parsed, 'CreatePostInput'); - expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); - const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); - expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); - - const postModelObject = getObjectType(parsed, 'Post'); - const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); - const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); - // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" - // in the generated CreatePostInput type - its types should be the same as in the Post @model type - verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); - - expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); - }); - - it('should support enum as a field', () => { - const validSchema = ` - enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } - type Test @model { - status: Status! - lastStatus: Status! - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - validateModelSchema(parsed); - - const createTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); - - const updateTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); - }); - - it('should support non-model types and enums', () => { - const validSchema = ` - type Post @model { - id: ID! - title: String! - createdAt: String - updatedAt: String - metadata: [PostMetadata!]! - appearsIn: [Episode]! - } - type PostMetadata { - tags: Tag - } - type Tag { - published: Boolean - metadata: PostMetadata - } - enum Episode { - NEWHOPE - EMPIRE - JEDI - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); expect(postMetaDataInputType).toBeDefined(); @@ -577,33 +496,6 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); - it('should support enum as a field', () => { - const validSchema = ` - enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } - type Test @model { - status: Status! - lastStatus: Status! - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - validateModelSchema(parsed); - - const createTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); - - const updateTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); - }); - it('should support non-model types and enums', () => { const validSchema = ` type Post @model { @@ -658,113 +550,4 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); - - it('should support enum as a field', () => { - const validSchema = ` - enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } - type Test @model { - status: Status! - lastStatus: Status! - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - validateModelSchema(parsed); - - const createTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); - - const updateTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); - }); - - it('should support non-model types and enums', () => { - const validSchema = ` - type Post @model { - id: ID! - title: String! - createdAt: String - updatedAt: String - metadata: [PostMetadata!]! - appearsIn: [Episode]! - } - type PostMetadata { - tags: Tag - } - type Tag { - published: Boolean - metadata: PostMetadata - } - enum Episode { - NEWHOPE - EMPIRE - JEDI - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - - const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); - expect(postMetaDataInputType).toBeDefined(); - const tagInputType = getInputType(parsed, 'TagInput'); - expect(tagInputType).toBeDefined(); - expectFieldsOnInputType(tagInputType!, ['metadata']); - const createPostInputType = getInputType(parsed, 'CreatePostInput'); - expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); - const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); - expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); - - const postModelObject = getObjectType(parsed, 'Post'); - const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); - const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); - // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" - // in the generated CreatePostInput type - its types should be the same as in the Post @model type - verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); - - expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); - }); - - it('should support enum as a field', () => { - const validSchema = ` - enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } - type Test @model { - status: Status! - lastStatus: Status! - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - validateModelSchema(parsed); - - const createTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); - - const updateTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); - }); }); From 384a63a3f00699142aeac1806da8e98bc051109b Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Mon, 9 Aug 2021 13:30:05 -0400 Subject: [PATCH 37/63] chore(graphql-model-transformer): fixed merge conflicts --- .../src/__tests__/model-transformer.test.ts | 55 ------------------- 1 file changed, 55 deletions(-) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 329e4caacd0..7dbe8704e84 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -495,59 +495,4 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); - - it('should support non-model types and enums', () => { - const validSchema = ` - type Post @model { - id: ID! - title: String! - createdAt: String - updatedAt: String - metadata: [PostMetadata!]! - appearsIn: [Episode]! - } - type PostMetadata { - tags: Tag - } - type Tag { - published: Boolean - metadata: PostMetadata - } - enum Episode { - NEWHOPE - EMPIRE - JEDI - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - - const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); - expect(postMetaDataInputType).toBeDefined(); - const tagInputType = getInputType(parsed, 'TagInput'); - expect(tagInputType).toBeDefined(); - expectFieldsOnInputType(tagInputType!, ['metadata']); - const createPostInputType = getInputType(parsed, 'CreatePostInput'); - expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); - const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); - expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); - - const postModelObject = getObjectType(parsed, 'Post'); - const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); - const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); - // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" - // in the generated CreatePostInput type - its types should be the same as in the Post @model type - verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); - - expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); - }); }); From 2c38380226067d1530a9c71fe7b689e9c57c7295 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Mon, 9 Aug 2021 20:18:50 -0400 Subject: [PATCH 38/63] fix(graphql-model-transformer): fixed @model transformer advanced subscriptions --- .../src/__tests__/container-hosting.test.ts | 2 +- ...ify-graphql-index-transformer.test.ts.snap | 456 ------------------ ...aphql-primary-key-transformer.test.ts.snap | 162 ------- .../src/schema.ts | 14 +- .../src/__tests__/model-transformer.test.ts | 156 +++++- .../src/graphql-model-transformer.ts | 225 +++++---- .../src/graphql-types/common.ts | 19 +- .../src/wrappers/object-definition-wrapper.ts | 2 +- ...aphql-searchable-transformer.tests.ts.snap | 206 ++++---- 9 files changed, 392 insertions(+), 850 deletions(-) diff --git a/packages/amplify-e2e-tests/src/__tests__/container-hosting.test.ts b/packages/amplify-e2e-tests/src/__tests__/container-hosting.test.ts index e8ad99f0974..7b8a95dc23e 100644 --- a/packages/amplify-e2e-tests/src/__tests__/container-hosting.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/container-hosting.test.ts @@ -21,7 +21,7 @@ describe('amplify add hosting - container', () => { await initJSProjectWithProfile(projRoot, {}); await amplifyConfigureProject({ cwd: projRoot, - enableContainers: true + enableContainers: true, }); // TODO: This needs attention. Need to force circle ci to run this test in us-east-1 // await addDevContainerHosting(projRoot); diff --git a/packages/amplify-graphql-index-transformer/src/__tests__/__snapshots__/amplify-graphql-index-transformer.test.ts.snap b/packages/amplify-graphql-index-transformer/src/__tests__/__snapshots__/amplify-graphql-index-transformer.test.ts.snap index ae7eade0bc7..b7414b70b56 100644 --- a/packages/amplify-graphql-index-transformer/src/__tests__/__snapshots__/amplify-graphql-index-transformer.test.ts.snap +++ b/packages/amplify-graphql-index-transformer/src/__tests__/__snapshots__/amplify-graphql-index-transformer.test.ts.snap @@ -645,33 +645,6 @@ $util.toJson($QueryRequest)", $util.error($ctx.error.message, $ctx.error.type) #end $util.toJson($ctx.result)", - "Subscription.onCreateTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onCreateTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onDeleteTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onDeleteTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onUpdateTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onUpdateTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", } `; @@ -1242,33 +1215,6 @@ $util.toJson($ListRequest) $util.toJson($ctx.result) #end ## [End] Get ResponseTemplate. **", - "Subscription.onCreateTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onCreateTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onDeleteTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onDeleteTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onUpdateTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onUpdateTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", } `; @@ -1955,33 +1901,6 @@ $util.toJson($QueryRequest)", $util.error($ctx.error.message, $ctx.error.type) #end $util.toJson($ctx.result)", - "Subscription.onCreateTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onCreateTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onDeleteTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onDeleteTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onUpdateTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onUpdateTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", } `; @@ -2924,33 +2843,6 @@ $util.toJson($QueryRequest)", $util.error($ctx.error.message, $ctx.error.type) #end $util.toJson($ctx.result)", - "Subscription.onCreateTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onCreateTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onDeleteTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onDeleteTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onUpdateTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onUpdateTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", } `; @@ -4023,178 +3915,6 @@ $util.toJson($UpdateItem) #else $util.toJson($ctx.result) #end -## [End] Get ResponseTemplate. **", - "Mutation.updateContentCategory.init.1.req.vtl": "## [Start] Initialization default values. ** -$util.qr($ctx.stash.put(\\"defaultValues\\", $util.defaultIfNull($ctx.stash.defaultValues, {}))) -#set( $updatedAt = $util.time.nowISO8601() ) -$util.qr($ctx.stash.defaultValues.put(\\"updatedAt\\", $updatedAt)) -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Initialization default values. **", - "Mutation.updateContentCategory.postAuth.1.req.vtl": "## [Start] Merge default values and inputs. ** -#set( $mergedValues = $util.defaultIfNull($ctx.stash.defaultValues, {}) ) -$util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) -## [End] Merge default values and inputs. ** -## [Start] Validate update mutation for @index 'ContentByCategory'. ** -#set( $hasSeenSomeKeyArg = false ) -#set( $keyFieldNames = [\\"type\\", \\"language\\", \\"datetime\\"] ) -#foreach( $keyFieldName in $keyFieldNames ) -#if( $ctx.args.input.containsKey(\\"$keyFieldName\\") ) #set( $hasSeenSomeKeyArg = true ) #end -#end -#foreach( $keyFieldName in $keyFieldNames ) - #if( $hasSeenSomeKeyArg && !$ctx.args.input.containsKey(\\"$keyFieldName\\") ) - $util.error(\\"When updating any part of the composite sort key for @index 'ContentByCategory', you must provide all fields for the key. Missing key: '$keyFieldName'.\\") - #end -#end -## [End] Validate update mutation for @index 'ContentByCategory'. ** -#if( $util.isNull($ctx.stash.metadata.dynamodbNameOverrideMap) ) - $util.qr($ctx.stash.metadata.put(\\"dynamodbNameOverrideMap\\", { - \\"type#language#datetime\\": \\"typeLanguageDatetime\\" -})) -#else - $util.qr($ctx.stash.metadata.dynamodbNameOverrideMap.put(\\"type#language#datetime\\", \\"typeLanguageDatetime\\")) -#end -#if( $hasSeenSomeKeyArg ) - $util.qr($ctx.args.input.put(\\"type#language#datetime\\",\\"\${mergedValues.type}#\${mergedValues.language}#\${mergedValues.datetime}\\")) -#end -{}", - "Mutation.updateContentCategory.req.vtl": "## [Start] Mutation Update resolver. ** -## Set the default values to put request ** -#set( $mergedValues = $util.defaultIfNull($ctx.stash.defaultValues, {}) ) -## copy the values from input ** -$util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) -## set the typename ** -## Initialize the vars for creating ddb expression ** -#set( $expNames = {} ) -#set( $expValues = {} ) -#set( $expSet = {} ) -#set( $expAdd = {} ) -#set( $expRemove = [] ) -#if( $ctx.stash.metadata.modelObjectKey ) - #set( $Key = $ctx.stash.metadata.modelObjectKey ) -#else - #set( $Key = { - \\"id\\": $util.dynamodb.toDynamoDB($ctx.args.input.id) -} ) -#end -## Model key ** -#if( $ctx.stash.metadata.modelObjectKey ) - #set( $keyFields = [] ) - #foreach( $entry in $ctx.stash.metadata.modelObjectKey.entrySet() ) - $util.qr($keyFields.add(\\"$entry.key\\")) - #end -#else - #set( $keyFields = [\\"id\\"] ) -#end -#foreach( $entry in $util.map.copyAndRemoveAllKeys($mergedValues, $keyFields).entrySet() ) - #if( !$util.isNull($ctx.stash.metadata.dynamodbNameOverrideMap) && $ctx.stash.metadata.dynamodbNameOverrideMap.containsKey(\\"$entry.key\\") ) - #set( $entryKeyAttributeName = $ctx.stash.metadata.dynamodbNameOverrideMap.get(\\"$entry.key\\") ) - #else - #set( $entryKeyAttributeName = $entry.key ) - #end - #if( $util.isNull($entry.value) ) - #set( $discard = $expRemove.add(\\"#$entryKeyAttributeName\\") ) - $util.qr($expNames.put(\\"#$entryKeyAttributeName\\", \\"$entry.key\\")) - #else - $util.qr($expSet.put(\\"#$entryKeyAttributeName\\", \\":$entryKeyAttributeName\\")) - $util.qr($expNames.put(\\"#$entryKeyAttributeName\\", \\"$entry.key\\")) - $util.qr($expValues.put(\\":$entryKeyAttributeName\\", $util.dynamodb.toDynamoDB($entry.value))) - #end -#end -#set( $expression = \\"\\" ) -#if( !$expSet.isEmpty() ) - #set( $expression = \\"SET\\" ) - #foreach( $entry in $expSet.entrySet() ) - #set( $expression = \\"$expression $entry.key = $entry.value\\" ) - #if( $foreach.hasNext() ) - #set( $expression = \\"$expression,\\" ) - #end - #end -#end -#if( !$expAdd.isEmpty() ) - #set( $expression = \\"$expression ADD\\" ) - #foreach( $entry in $expAdd.entrySet() ) - #set( $expression = \\"$expression $entry.key $entry.value\\" ) - #if( $foreach.hasNext() ) - #set( $expression = \\"$expression,\\" ) - #end - #end -#end -#if( !$expRemove.isEmpty() ) - #set( $expression = \\"$expression REMOVE\\" ) - #foreach( $entry in $expRemove ) - #set( $expression = \\"$expression $entry\\" ) - #if( $foreach.hasNext() ) - #set( $expression = \\"$expression,\\" ) - #end - #end -#end -#set( $update = {} ) -$util.qr($update.put(\\"expression\\", \\"$expression\\")) -#if( !$expNames.isEmpty() ) - $util.qr($update.put(\\"expressionNames\\", $expNames)) -#end -#if( !$expValues.isEmpty() ) - $util.qr($update.put(\\"expressionValues\\", $expValues)) -#end -## Begin - key condition ** -#if( $ctx.stash.metadata.modelObjectKey ) - #set( $keyConditionExpr = {} ) - #set( $keyConditionExprNames = {} ) - #foreach( $entry in $ctx.stash.metadata.modelObjectKey.entrySet() ) - $util.qr($keyConditionExpr.put(\\"keyCondition$velocityCount\\", { - \\"attributeExists\\": true -})) - $util.qr($keyConditionExprNames.put(\\"#keyCondition$velocityCount\\", \\"$entry.key\\")) - #end - $util.qr($ctx.stash.conditions.add($keyConditionExpr)) -#else - $util.qr($ctx.stash.conditions.add({ - \\"id\\": { - \\"attributeExists\\": true - } -})) -#end -## End - key condition ** -#if( $context.args.condition ) - $util.qr($ctx.stash.conditions.add($context.args.condition)) -#end -## Start condition block ** -#if( $ctx.stash.conditions && $ctx.stash.conditions.size() != 0 ) - #set( $mergedConditions = { - \\"and\\": $ctx.stash.conditions -} ) - #set( $Conditions = $util.parseJson($util.transform.toDynamoDBConditionExpression($mergedConditions)) ) - #if( $Conditions.expressionValues && $Conditions.expressionValues.size() == 0 ) - #set( $Conditions = { - \\"expression\\": $Conditions.expression, - \\"expressionNames\\": $Conditions.expressionNames -} ) - #end - ## End condition block ** -#end -#set( $UpdateItem = { - \\"version\\": \\"2018-05-29\\", - \\"operation\\": \\"UpdateItem\\", - \\"key\\": $Key, - \\"update\\": $update -} ) -#if( $Conditions ) - #if( $keyConditionExprNames ) - $util.qr($Conditions.expressionNames.putAll($keyConditionExprNames)) - #end - $util.qr($UpdateItem.put(\\"condition\\", $Conditions)) -#end -$util.toJson($UpdateItem) -## [End] Mutation Update resolver. **", - "Mutation.updateContentCategory.res.vtl": "## [Start] Get ResponseTemplate. ** -#if( $ctx.error ) - $util.error($ctx.error.message, $ctx.error.type) -#else - $util.toJson($ctx.result) -#end ## [End] Get ResponseTemplate. **", "Mutation.updateItem.init.1.req.vtl": "## [Start] Initialization default values. ** $util.qr($ctx.stash.put(\\"defaultValues\\", $util.defaultIfNull($ctx.stash.defaultValues, {}))) @@ -5515,47 +5235,6 @@ $util.toJson($ListRequest) #else $util.toJson($ctx.result) #end -## [End] Get ResponseTemplate. **", - "Query.listTodos.req.vtl": "## [Start] List Request. ** -#set( $limit = $util.defaultIfNull($context.args.limit, 100) ) -#set( $ListRequest = { - \\"version\\": \\"2018-05-29\\", - \\"limit\\": $limit -} ) -#if( $context.args.nextToken ) - #set( $ListRequest.nextToken = $context.args.nextToken ) -#end -#if( $context.args.filter ) - #set( $filterExpression = $util.parseJson($util.transform.toDynamoDBFilterExpression($ctx.args.filter)) ) - #if( !$util.isNullOrBlank($filterExpression.expression) ) - #if( $filterEpression.expressionValues.size() == 0 ) - $util.qr($filterEpression.remove(\\"expressionValues\\")) - #end - #set( $ListRequest.filter = $filterExpression ) - #end -#end -#if( !$util.isNull($ctx.stash.modelQueryExpression) && !$util.isNullOrEmpty($ctx.stash.modelQueryExpression.expression) ) - $util.qr($ListRequest.put(\\"operation\\", \\"Query\\")) - $util.qr($ListRequest.put(\\"query\\", $ctx.stash.modelQueryExpression)) - #if( !$util.isNull($ctx.args.sortDirection) && $ctx.args.sortDirection == \\"DESC\\" ) - #set( $ListRequest.scanIndexForward = false ) - #else - #set( $ListRequest.scanIndexForward = true ) - #end -#else - $util.qr($ListRequest.put(\\"operation\\", \\"Scan\\")) -#end -#if( !$util.isNull($ctx.stash.metadata.index) ) - #set( $ListRequest.IndexName = $ctx.stash.metadata.index ) -#end -$util.toJson($ListRequest) -## [End] List Request. **", - "Query.listTodos.res.vtl": "## [Start] Get ResponseTemplate. ** -#if( $ctx.error ) - $util.error($ctx.error.message, $ctx.error.type) -#else - $util.toJson($ctx.result) -#end ## [End] Get ResponseTemplate. **", "Query.testsByCategory.req.vtl": "## [Start] Set query expression for key ** #set( $modelQueryExpression = {} ) @@ -5751,140 +5430,5 @@ $util.toJson($QueryRequest)", $util.error($ctx.error.message, $ctx.error.type) #end $util.toJson($ctx.result)", - "Subscription.onCreateBlog.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onCreateBlog.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onCreateContentCategory.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onCreateContentCategory.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onCreateItem.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onCreateItem.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onCreateTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onCreateTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onCreateTodo.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onCreateTodo.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onDeleteBlog.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onDeleteBlog.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onDeleteContentCategory.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onDeleteContentCategory.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onDeleteItem.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onDeleteItem.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onDeleteTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onDeleteTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onDeleteTodo.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onDeleteTodo.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onUpdateBlog.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onUpdateBlog.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onUpdateContentCategory.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onUpdateContentCategory.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onUpdateItem.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onUpdateItem.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onUpdateTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onUpdateTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onUpdateTodo.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onUpdateTodo.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", } `; diff --git a/packages/amplify-graphql-index-transformer/src/__tests__/__snapshots__/amplify-graphql-primary-key-transformer.test.ts.snap b/packages/amplify-graphql-index-transformer/src/__tests__/__snapshots__/amplify-graphql-primary-key-transformer.test.ts.snap index 934de3cdc18..327c5ae5eca 100644 --- a/packages/amplify-graphql-index-transformer/src/__tests__/__snapshots__/amplify-graphql-primary-key-transformer.test.ts.snap +++ b/packages/amplify-graphql-index-transformer/src/__tests__/__snapshots__/amplify-graphql-primary-key-transformer.test.ts.snap @@ -540,33 +540,6 @@ $util.toJson($ListRequest) $util.toJson($ctx.result) #end ## [End] Get ResponseTemplate. **", - "Subscription.onCreateTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onCreateTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onDeleteTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onDeleteTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onUpdateTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onUpdateTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", } `; @@ -1050,33 +1023,6 @@ $util.toJson($ListRequest) $util.toJson($ctx.result) #end ## [End] Get ResponseTemplate. **", - "Subscription.onCreateTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onCreateTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onDeleteTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onDeleteTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onUpdateTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onUpdateTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", } `; @@ -1513,33 +1459,6 @@ $util.toJson($ListRequest) $util.toJson($ctx.result) #end ## [End] Get ResponseTemplate. **", - "Subscription.onCreateTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onCreateTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onDeleteTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onDeleteTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onUpdateTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onUpdateTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", } `; @@ -2023,33 +1942,6 @@ $util.toJson($ListRequest) $util.toJson($ctx.result) #end ## [End] Get ResponseTemplate. **", - "Subscription.onCreateTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onCreateTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onDeleteTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onDeleteTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onUpdateTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onUpdateTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", } `; @@ -2967,33 +2859,6 @@ $util.toJson($ListRequest) $util.toJson($ctx.result) #end ## [End] Get ResponseTemplate. **", - "Subscription.onCreateTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onCreateTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onDeleteTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onDeleteTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onUpdateTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onUpdateTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", } `; @@ -3908,32 +3773,5 @@ $util.toJson($ListRequest) $util.toJson($ctx.result) #end ## [End] Get ResponseTemplate. **", - "Subscription.onCreateTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onCreateTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onDeleteTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onDeleteTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onUpdateTest.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onUpdateTest.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", } `; diff --git a/packages/amplify-graphql-index-transformer/src/schema.ts b/packages/amplify-graphql-index-transformer/src/schema.ts index 5d3c9e82b61..5af9e0005bf 100644 --- a/packages/amplify-graphql-index-transformer/src/schema.ts +++ b/packages/amplify-graphql-index-transformer/src/schema.ts @@ -380,7 +380,6 @@ function generateFilterInputs(config: IndexDirectiveConfiguration, ctx: Transfor function makeModelXFilterInputObject(config: IndexDirectiveConfiguration, ctx: TransformerContextProvider): InputObjectTypeDefinitionNode { const { object } = config; const name = ModelResourceIDs.ModelFilterInputTypeName(object.name.value); - const supportsConditions = true; const fields = object .fields!.filter((field: FieldDefinitionNode) => { const fieldType = ctx.output.getType(getBaseType(field.type)); @@ -389,13 +388,14 @@ function makeModelXFilterInputObject(config: IndexDirectiveConfiguration, ctx: T }) .map((field: FieldDefinitionNode) => { const baseType = getBaseType(field.type); - const fieldType = ctx.output.getType(baseType); const isList = isListType(field.type); - const isEnumType = fieldType && fieldType.kind === Kind.ENUM_TYPE_DEFINITION; - const filterTypeName = - isEnumType && isList - ? ModelResourceIDs.ModelFilterListInputTypeName(baseType, !supportsConditions) - : ModelResourceIDs.ModelScalarFilterInputTypeName(baseType, !supportsConditions); + let filterTypeName = baseType; + + if (isScalar(field.type) || isList) { + filterTypeName = isList + ? ModelResourceIDs.ModelFilterListInputTypeName(baseType, true) + : ModelResourceIDs.ModelScalarFilterInputTypeName(baseType, true); + } return { kind: Kind.INPUT_VALUE_DEFINITION, diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 7dbe8704e84..dc951348cee 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -1,6 +1,6 @@ import { ModelTransformer } from '@aws-amplify/graphql-model-transformer'; import { GraphQLTransform, validateModelSchema } from '@aws-amplify/graphql-transformer-core'; -import { InputObjectTypeDefinitionNode, InputValueDefinitionNode, NamedTypeNode, parse } from 'graphql'; +import { InputObjectTypeDefinitionNode, InputValueDefinitionNode, ListValueNode, NamedTypeNode, parse } from 'graphql'; import { getBaseType } from 'graphql-transformer-common'; import { doNotExpectFields, @@ -495,4 +495,158 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); + + it('should generate only create mutation', () => { + const validSchema = `type Post @model(mutations: { create: "customCreatePost" }) { + id: ID! + title: String! + createdAt: String + updatedAt: String + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const mutationType = getObjectType(parsed, 'Mutation'); + expect(mutationType).toBeDefined(); + expectFields(mutationType!, ['customCreatePost']); + doNotExpectFields(mutationType!, ['updatePost']); + }); + + it('support schema with multiple model directives', () => { + const validSchema = ` + type Post @model { + id: ID! + title: String! + createdAt: String + updatedAt: String + } + + type User @model { + id: ID! + name: String! + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const queryType = getObjectType(parsed, 'Query'); + expect(queryType).toBeDefined(); + expectFields(queryType!, ['listPosts']); + expectFields(queryType!, ['listUsers']); + + const stringInputType = getInputType(parsed, 'ModelStringFilterInput'); + expect(stringInputType).toBeDefined(); + const booleanInputType = getInputType(parsed, 'ModelBooleanFilterInput'); + expect(booleanInputType).toBeDefined(); + const intInputType = getInputType(parsed, 'ModelIntFilterInput'); + expect(intInputType).toBeDefined(); + const floatInputType = getInputType(parsed, 'ModelFloatFilterInput'); + expect(floatInputType).toBeDefined(); + const idInputType = getInputType(parsed, 'ModelIDFilterInput'); + expect(idInputType).toBeDefined(); + const postInputType = getInputType(parsed, 'ModelPostFilterInput'); + expect(postInputType).toBeDefined(); + const userInputType = getInputType(parsed, 'ModelUserFilterInput'); + expect(userInputType).toBeDefined(); + + expect(verifyInputCount(parsed, 'ModelStringFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelBooleanFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelIntFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelFloatFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelIDFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelPostFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelUserFilterInput', 1)).toBeTruthy(); + }); + + it('it should generate filter inputs', () => { + const validSchema = ` + type Post @model { + id: ID! + title: String! + createdAt: String + updatedAt: String + }`; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const queryType = getObjectType(parsed, 'Query'); + expect(queryType).toBeDefined(); + expectFields(queryType!, ['listPosts']); + + const connectionType = getObjectType(parsed, 'ModelPostConnection'); + expect(connectionType).toBeDefined(); + + expect(verifyInputCount(parsed, 'ModelStringFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelBooleanFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelIntFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelFloatFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelIDFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelPostFilterInput', 1)).toBeTruthy(); + }); + + it('should support advanced subscriptions', () => { + const validSchema = `type Post @model(subscriptions: { + onCreate: ["onFeedUpdated", "onCreatePost"], + onUpdate: ["onFeedUpdated"], + onDelete: ["onFeedUpdated"] + }) { + id: ID! + title: String! + createdAt: String + updatedAt: String + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const subscriptionType = getObjectType(parsed, 'Subscription'); + expect(subscriptionType).toBeDefined(); + expectFields(subscriptionType!, ['onFeedUpdated', 'onCreatePost']); + const subField = subscriptionType!.fields!.find(f => f.name.value === 'onFeedUpdated'); + expect(subField!.directives!.length).toEqual(1); + expect(subField!.directives![0].name!.value).toEqual('aws_subscribe'); + const mutationsList = subField!.directives![0].arguments!.find(a => a.name.value === 'mutations')!.value as ListValueNode; + const mutList = mutationsList.values.map((v: any) => v.value); + expect(mutList.length).toEqual(3); + expect(mutList).toContain('createPost'); + expect(mutList).toContain('updatePost'); + expect(mutList).toContain('deletePost'); + }); }); diff --git a/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts b/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts index 9f0c436de49..6f9d64e5bbf 100644 --- a/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts +++ b/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts @@ -12,10 +12,18 @@ import { TransformerPrepareStepContextProvider, TransformerResolverProvider, TransformerSchemaVisitStepContextProvider, + TransformerValidationStepContextProvider, } from '@aws-amplify/graphql-transformer-interfaces'; import { AttributeType, CfnTable, ITable, StreamViewType, Table, TableEncryption } from '@aws-cdk/aws-dynamodb'; import * as cdk from '@aws-cdk/core'; -import { DirectiveNode, InputObjectTypeDefinitionNode, InputValueDefinitionNode, ObjectTypeDefinitionNode } from 'graphql'; +import { Stack } from '@aws-cdk/core'; +import { + DirectiveNode, + FieldDefinitionNode, + InputObjectTypeDefinitionNode, + InputValueDefinitionNode, + ObjectTypeDefinitionNode, +} from 'graphql'; import { getBaseType, isScalar, @@ -79,9 +87,9 @@ export type ModelDirectiveConfiguration = { delete: OptionalAndNullable; } | null; subscriptions: { - onCreate: OptionalAndNullable; - onUpdate: OptionalAndNullable; - onDelete: OptionalAndNullable; + onCreate: OptionalAndNullable[]; + onUpdate: OptionalAndNullable[]; + onDelete: OptionalAndNullable[]; level: Partial; } | null; timestamps: OptionalAndNullable<{ @@ -163,9 +171,9 @@ export class ModelTransformer extends TransformerModelBase implements Transforme }, subscriptions: { level: SubscriptionLevel.public, - onCreate: toCamelCase(['onCreate', typeName]), - onDelete: toCamelCase(['onDelete', typeName]), - onUpdate: toCamelCase(['onUpdate', typeName]), + onCreate: [toCamelCase(['onCreate', typeName])], + onDelete: [toCamelCase(['onDelete', typeName])], + onUpdate: [toCamelCase(['onUpdate', typeName])], }, timestamps: { createdAt: 'createdAt', @@ -218,39 +226,8 @@ export class ModelTransformer extends TransformerModelBase implements Transforme ctx.output.addMutationFields([field]); } - const getMutationName = ( - subscriptionType: SubscriptionFieldType, - mutationMap: Set<{ - fieldName: string; - typeName: string; - type: MutationFieldType; - }>, - ): string => { - const mutationToSubscriptionTypeMap = { - [SubscriptionFieldType.ON_CREATE]: MutationFieldType.CREATE, - [SubscriptionFieldType.ON_UPDATE]: MutationFieldType.UPDATE, - [SubscriptionFieldType.ON_DELETE]: MutationFieldType.DELETE, - }; - const mutation = Array.from(mutationMap).find(m => m.type == mutationToSubscriptionTypeMap[subscriptionType]); - if (mutation) { - return mutation.fieldName; - } - throw new Error('Unknown Subscription type'); - }; - - const subscriptionsFields = this.getSubscriptionFieldNames(ctx, def!); - for (const subscriptionsField of subscriptionsFields) { - const args = this.getInputs(ctx, def!, { - fieldName: subscriptionsField.fieldName, - typeName: subscriptionsField.typeName, - type: subscriptionsField.type, - }); - const mutationName = getMutationName(subscriptionsField.type, mutationFields); - // Todo use directive wrapper to build the directrive node - const directive = makeDirective('aws_subscribe', [makeArgument('mutations', makeValueNode([mutationName]))]); - const field = makeField(subscriptionsField.fieldName, args, makeNamedType(def!.name.value), [directive]); - ctx.output.addSubscriptionFields([field]); - } + const subscriptionsFields = this.createSubscriptionFields(ctx, def!); + ctx.output.addSubscriptionFields(subscriptionsFields); // Update the field with auto generatable Fields this.addAutoGeneratableFields(ctx, type); @@ -370,7 +347,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme resolver = this.generateSyncResolver(context, def!, query.typeName, query.fieldName); break; default: - throw new Error('Unkown query field type'); + throw new Error('Unknown query field type'); } resolver.mapToStack(stack); @@ -391,31 +368,11 @@ export class ModelTransformer extends TransformerModelBase implements Transforme resolver = this.generateUpdateResolver(context, def!, mutation.typeName, mutation.fieldName); break; default: - throw new Error('Unkown query field type'); + throw new Error('Unknown query field type'); } resolver.mapToStack(stack); context.resolvers.addResolver(mutation.typeName, mutation.fieldName, resolver); } - - const subscriptionsFields = this.getSubscriptionFieldNames(context, def!); - for (let subscription of subscriptionsFields.values()) { - let resolver; - switch (subscription.type) { - case SubscriptionFieldType.ON_CREATE: - resolver = this.generateOnCreateResolver(context, def!, subscription.typeName, subscription.fieldName); - break; - case SubscriptionFieldType.ON_DELETE: - resolver = this.generateOnDeleteResolver(context, def!, subscription.typeName, subscription.fieldName); - break; - case SubscriptionFieldType.ON_UPDATE: - resolver = this.generateOnUpdateResolver(context, def!, subscription.typeName, subscription.fieldName); - break; - default: - throw new Error('Unkown query field type'); - } - resolver.mapToStack(stack); - context.resolvers.addResolver(subscription.typeName, subscription.fieldName, resolver); - } } }; @@ -616,7 +573,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme // Todo: get fields names from the directives const typeName = type.name.value; const modelDirectiveConfig = this.modelDirectiveConfig.get(typeName); - const getMuationType = (type: string): MutationFieldType => { + const getMutationType = (type: string): MutationFieldType => { switch (type) { case 'create': return MutationFieldType.CREATE; @@ -625,7 +582,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme case 'delete': return MutationFieldType.DELETE; default: - throw new Error('Unknow mutation type'); + throw new Error('Unknown mutation type'); } }; @@ -635,7 +592,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme fieldNames.add({ typeName: 'Mutation', fieldName: mutationName, - type: getMuationType(mutationType), + type: getMutationType(mutationType), }); } } @@ -643,6 +600,56 @@ export class ModelTransformer extends TransformerModelBase implements Transforme return fieldNames; }; + getMutationName = ( + subscriptionType: SubscriptionFieldType, + mutationMap: Set<{ + fieldName: string; + typeName: string; + type: MutationFieldType; + }>, + ): string => { + const mutationToSubscriptionTypeMap = { + [SubscriptionFieldType.ON_CREATE]: MutationFieldType.CREATE, + [SubscriptionFieldType.ON_UPDATE]: MutationFieldType.UPDATE, + [SubscriptionFieldType.ON_DELETE]: MutationFieldType.DELETE, + }; + const mutation = Array.from(mutationMap).find(m => m.type == mutationToSubscriptionTypeMap[subscriptionType]); + if (mutation) { + return mutation.fieldName; + } + throw new Error('Unknown Subscription type'); + }; + + createSubscriptionFields = (ctx: TransformerTransformSchemaStepContextProvider, def: ObjectTypeDefinitionNode): FieldDefinitionNode[] => { + const subscriptionToMutationsMap = this.getSubscriptionToMutationsReverseMap(ctx, def); + const mutationFields = this.getMutationFieldNames(ctx, def!); + + const subscriptionFields: FieldDefinitionNode[] = []; + for (const subscriptionFieldName of Object.keys(subscriptionToMutationsMap)) { + const maps = subscriptionToMutationsMap[subscriptionFieldName]; + + const args: InputValueDefinitionNode[] = []; + maps.map(it => + args.concat( + this.getInputs(ctx, def!, { + fieldName: it.fieldName, + typeName: it.typeName, + type: it.type, + }), + ), + ); + + const mutationNames = maps.map(it => this.getMutationName(it.type, mutationFields)); + + // Todo use directive wrapper to build the directive node + const directive = makeDirective('aws_subscribe', [makeArgument('mutations', makeValueNode(mutationNames))]); + const field = makeField(subscriptionFieldName, args, makeNamedType(def!.name.value), [directive]); + subscriptionFields.push(field); + } + + return subscriptionFields; + }; + getSubscriptionFieldNames = ( ctx: TransformerTransformSchemaStepContextProvider, type: ObjectTypeDefinitionNode, @@ -660,28 +667,36 @@ export class ModelTransformer extends TransformerModelBase implements Transforme const modelDirectiveConfig = this.modelDirectiveConfig.get(type.name.value); if (modelDirectiveConfig?.subscriptions?.level !== SubscriptionLevel.off) { if (modelDirectiveConfig?.subscriptions?.onCreate && modelDirectiveConfig.mutations?.create) { - fields.add({ - typeName: 'Subscription', - fieldName: modelDirectiveConfig.subscriptions.onCreate!, - type: SubscriptionFieldType.ON_CREATE, - }); + for (const fieldName of modelDirectiveConfig.subscriptions.onCreate) { + fields.add({ + typeName: 'Subscription', + fieldName: fieldName, + type: SubscriptionFieldType.ON_CREATE, + }); + } } + if (modelDirectiveConfig?.subscriptions?.onUpdate && modelDirectiveConfig.mutations?.update) { - fields.add({ - typeName: 'Subscription', - fieldName: modelDirectiveConfig.subscriptions.onUpdate!, - type: SubscriptionFieldType.ON_UPDATE, - }); + for (const fieldName of modelDirectiveConfig.subscriptions.onUpdate) { + fields.add({ + typeName: 'Subscription', + fieldName: fieldName, + type: SubscriptionFieldType.ON_UPDATE, + }); + } } if (modelDirectiveConfig?.subscriptions?.onDelete && modelDirectiveConfig.mutations?.delete) { - fields.add({ - typeName: 'Subscription', - fieldName: modelDirectiveConfig.subscriptions.onDelete!, - type: SubscriptionFieldType.ON_DELETE, - }); + for (const fieldName of modelDirectiveConfig.subscriptions.onDelete) { + fields.add({ + typeName: 'Subscription', + fieldName: fieldName, + type: SubscriptionFieldType.ON_DELETE, + }); + } } } + return fields; }; @@ -893,20 +908,48 @@ export class ModelTransformer extends TransformerModelBase implements Transforme const idField = FieldWrapper.create('id', 'ID'); typeWrapper.addField(idField); } + + const timestamps = []; + if (modelDirectiveConfig?.timestamps) { - for (let [, fieldName] of Object.entries(modelDirectiveConfig?.timestamps)) - if (fieldName) { - if (typeWrapper.hasField(fieldName)) { - const createdAtField = typeWrapper.getField(fieldName); - if (!['String', 'AWSDateTime'].includes(createdAtField.getTypeName())) { - console.warn(`type ${name}.${fieldName} is not of String or AWSDateTime. Auto population is not supported`); - } - } else { - const createdAtField = FieldWrapper.create(fieldName, 'AWSDateTime'); - typeWrapper.addField(createdAtField); - } + if (modelDirectiveConfig.timestamps.createdAt !== null) { + timestamps.push(modelDirectiveConfig.timestamps.createdAt ?? 'createdAt'); + } + + if (modelDirectiveConfig.timestamps.updatedAt !== null) { + timestamps.push(modelDirectiveConfig.timestamps.updatedAt ?? 'updatedAt'); + } + } + + for (let fieldName of timestamps) { + if (typeWrapper.hasField(fieldName)) { + const field = typeWrapper.getField(fieldName); + if (!['String', 'AWSDateTime'].includes(field.getTypeName())) { + console.warn(`type ${name}.${fieldName} is not of String or AWSDateTime. Auto population is not supported`); } + } else { + const field = FieldWrapper.create(fieldName, 'AWSDateTime'); + typeWrapper.addField(field); + } } + ctx.output.updateObject(typeWrapper.serialize()); }; + + private getSubscriptionToMutationsReverseMap = ( + ctx: TransformerValidationStepContextProvider, + def: ObjectTypeDefinitionNode, + ): { [subField: string]: { fieldName: string; typeName: string; type: SubscriptionFieldType }[] } => { + const subscriptionToMutationsMap: { [subField: string]: { fieldName: string; typeName: string; type: SubscriptionFieldType }[] } = {}; + const subscriptionFieldNames = this.getSubscriptionFieldNames(ctx, def); + + for (const subscriptionFieldName of subscriptionFieldNames) { + if (!subscriptionToMutationsMap[subscriptionFieldName.fieldName]) { + subscriptionToMutationsMap[subscriptionFieldName.fieldName] = []; + } + subscriptionToMutationsMap[subscriptionFieldName.fieldName].push(subscriptionFieldName); + } + + return subscriptionToMutationsMap; + }; } diff --git a/packages/amplify-graphql-model-transformer/src/graphql-types/common.ts b/packages/amplify-graphql-model-transformer/src/graphql-types/common.ts index 6c769ef597c..2b31ab209c0 100644 --- a/packages/amplify-graphql-model-transformer/src/graphql-types/common.ts +++ b/packages/amplify-graphql-model-transformer/src/graphql-types/common.ts @@ -13,6 +13,7 @@ import { makeField, makeNamedType, makeValueNode, + ModelResourceIDs, toPascalCase, } from 'graphql-transformer-common'; import { @@ -52,11 +53,14 @@ export const makeConditionFilterInput = ( for (let field of wrappedObject.fields) { const fieldType = ctx.output.getType(field.getTypeName()); const isEnumType = fieldType && fieldType.kind === 'EnumTypeDefinition'; - if (field.isScalar() || isEnumType) { - const fieldTypeName = field.getTypeName(); - const nameOverride = DEFAULT_SCALARS[fieldTypeName] || fieldTypeName; - const conditionTypeName = isEnumType && field.isList() ? `Model${nameOverride}ListInput` : `Model${nameOverride}Input`; - const inputField = InputFieldWrapper.create(field.name, conditionTypeName, true); + if (field.isScalar() || field.isList()) { + const conditionTypeName = field.isList() + ? ModelResourceIDs.ModelFilterListInputTypeName(field.getTypeName(), true) + : ModelResourceIDs.ModelFilterScalarInputTypeName(field.getTypeName(), true); + const inputField = InputFieldWrapper.create(field.name, conditionTypeName, true, field.isList()); + input.addField(inputField); + } else if (isEnumType) { + const inputField = InputFieldWrapper.create(field.name, field.getTypeName(), true, field.isList()); input.addField(inputField); } } @@ -76,7 +80,7 @@ export const makeConditionFilterInput = ( export const addModelConditionInputs = (ctx: TransformerTransformSchemaStepContextProvider): void => { const conditionsInput: TypeDefinitionNode[] = ['String', 'Int', 'Float', 'Boolean', 'ID'].map(scalarName => - makeModelScalarFilterInputObject(scalarName, true), + makeModelScalarFilterInputObject(scalarName, false), ); conditionsInput.push(makeAttributeTypeEnum()); conditionsInput.push(makeSizeInputType()); @@ -90,7 +94,7 @@ export const addModelConditionInputs = (ctx: TransformerTransformSchemaStepConte /** * - * @param typeName Name of the scarlar type + * @param typeName Name of the scalar type * @param includeFilter add filter suffix to input */ export function generateModelScalarFilterInputName(typeName: string, includeFilter: boolean): string { @@ -100,6 +104,7 @@ export function generateModelScalarFilterInputName(typeName: string, includeFilt } return `Model${typeName}${includeFilter ? 'Filter' : ''}Input`; } + export const createEnumModelFilters = ( ctx: TransformerTransformSchemaStepContextProvider, type: ObjectTypeDefinitionNode, diff --git a/packages/amplify-graphql-model-transformer/src/wrappers/object-definition-wrapper.ts b/packages/amplify-graphql-model-transformer/src/wrappers/object-definition-wrapper.ts index bb2caff0122..eab474c1c95 100644 --- a/packages/amplify-graphql-model-transformer/src/wrappers/object-definition-wrapper.ts +++ b/packages/amplify-graphql-model-transformer/src/wrappers/object-definition-wrapper.ts @@ -73,7 +73,7 @@ export class DirectiveWrapper { }), {}, ); - return merge(defaultValue, argValues); + return Object.assign(defaultValue, argValues); }; } diff --git a/packages/amplify-graphql-searchable-transformer/src/__tests__/__snapshots__/amplify-graphql-searchable-transformer.tests.ts.snap b/packages/amplify-graphql-searchable-transformer/src/__tests__/__snapshots__/amplify-graphql-searchable-transformer.tests.ts.snap index 58afb0422cc..e689aa3a264 100644 --- a/packages/amplify-graphql-searchable-transformer/src/__tests__/__snapshots__/amplify-graphql-searchable-transformer.tests.ts.snap +++ b/packages/amplify-graphql-searchable-transformer/src/__tests__/__snapshots__/amplify-graphql-searchable-transformer.tests.ts.snap @@ -148,7 +148,7 @@ type Query { listEmployees(filter: ModelEmployeeFilterInput, limit: Int, nextToken: String): ModelEmployeeConnection } -input ModelStringInput { +input ModelStringFilterInput { ne: String eq: String le: String @@ -164,7 +164,7 @@ input ModelStringInput { size: ModelSizeInput } -input ModelIntInput { +input ModelIntFilterInput { ne: Int eq: Int le: Int @@ -176,7 +176,7 @@ input ModelIntInput { attributeType: ModelAttributeTypes } -input ModelFloatInput { +input ModelFloatFilterInput { ne: Float eq: Float le: Float @@ -188,14 +188,14 @@ input ModelFloatInput { attributeType: ModelAttributeTypes } -input ModelBooleanInput { +input ModelBooleanFilterInput { ne: Boolean eq: Boolean attributeExists: Boolean attributeType: ModelAttributeTypes } -input ModelIDInput { +input ModelIDFilterInput { ne: ID eq: ID le: ID @@ -240,10 +240,10 @@ type ModelEmployeeConnection { } input ModelEmployeeFilterInput { - id: ModelIDInput - firstName: ModelStringInput - lastName: ModelStringInput - type: ModelEmploymentTypeInput + id: ModelIDFilterInput + firstName: ModelStringFilterInput + lastName: ModelStringFilterInput + type: EmploymentType and: [ModelEmployeeFilterInput] or: [ModelEmployeeFilterInput] not: ModelEmployeeFilterInput @@ -255,10 +255,10 @@ input ModelEmploymentTypeInput { } input ModelEmployeeConditionInput { - id: ModelIDInput - firstName: ModelStringInput - lastName: ModelStringInput - type: ModelEmploymentTypeInput + id: ModelIDFilterInput + firstName: ModelStringFilterInput + lastName: ModelStringFilterInput + type: EmploymentType and: [ModelEmployeeConditionInput] or: [ModelEmployeeConditionInput] not: ModelEmployeeConditionInput @@ -439,7 +439,7 @@ type Query { listPosts(filter: ModelPostFilterInput, limit: Int, nextToken: String): ModelPostConnection } -input ModelStringInput { +input ModelStringFilterInput { ne: String eq: String le: String @@ -455,7 +455,7 @@ input ModelStringInput { size: ModelSizeInput } -input ModelIntInput { +input ModelIntFilterInput { ne: Int eq: Int le: Int @@ -467,7 +467,7 @@ input ModelIntInput { attributeType: ModelAttributeTypes } -input ModelFloatInput { +input ModelFloatFilterInput { ne: Float eq: Float le: Float @@ -479,14 +479,14 @@ input ModelFloatInput { attributeType: ModelAttributeTypes } -input ModelBooleanInput { +input ModelBooleanFilterInput { ne: Boolean eq: Boolean attributeExists: Boolean attributeType: ModelAttributeTypes } -input ModelIDInput { +input ModelIDFilterInput { ne: ID eq: ID le: ID @@ -531,20 +531,20 @@ type ModelPostConnection { } input ModelPostFilterInput { - id: ModelIDInput - title: ModelStringInput - createdAt: ModelStringInput - updatedAt: ModelStringInput + id: ModelIDFilterInput + title: ModelStringFilterInput + createdAt: ModelStringFilterInput + updatedAt: ModelStringFilterInput and: [ModelPostFilterInput] or: [ModelPostFilterInput] not: ModelPostFilterInput } input ModelPostConditionInput { - id: ModelIDInput - title: ModelStringInput - createdAt: ModelStringInput - updatedAt: ModelStringInput + id: ModelIDFilterInput + title: ModelStringFilterInput + createdAt: ModelStringFilterInput + updatedAt: ModelStringFilterInput and: [ModelPostConditionInput] or: [ModelPostConditionInput] not: ModelPostConditionInput @@ -1051,33 +1051,6 @@ $util.toJson({ \\"nextToken\\": $nextToken, \\"aggregateItems\\": $aggregateValues })", - "Subscription.onCreatePost.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onCreatePost.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onDeletePost.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onDeletePost.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", - "Subscription.onUpdatePost.req.vtl": "## [Start] Subscription Request template. ** -$util.toJson({ - \\"version\\": \\"2018-05-29\\", - \\"payload\\": {} -}) -## [End] Subscription Request template. **", - "Subscription.onUpdatePost.res.vtl": "## [Start] Subscription Resonse template. ** -$util.toJson(null) -## [End] Subscription Resonse template. **", } `; @@ -1264,7 +1237,7 @@ type SearchableUserConnection { aggregateItems: [SearchableAggregateResult] } -input ModelStringInput { +input ModelStringFilterInput { ne: String eq: String le: String @@ -1280,7 +1253,7 @@ input ModelStringInput { size: ModelSizeInput } -input ModelIntInput { +input ModelIntFilterInput { ne: Int eq: Int le: Int @@ -1292,7 +1265,7 @@ input ModelIntInput { attributeType: ModelAttributeTypes } -input ModelFloatInput { +input ModelFloatFilterInput { ne: Float eq: Float le: Float @@ -1304,14 +1277,14 @@ input ModelFloatInput { attributeType: ModelAttributeTypes } -input ModelBooleanInput { +input ModelBooleanFilterInput { ne: Boolean eq: Boolean attributeExists: Boolean attributeType: ModelAttributeTypes } -input ModelIDInput { +input ModelIDFilterInput { ne: ID eq: ID le: ID @@ -1356,20 +1329,20 @@ type ModelPostConnection { } input ModelPostFilterInput { - id: ModelIDInput - title: ModelStringInput - createdAt: ModelStringInput - updatedAt: ModelStringInput + id: ModelIDFilterInput + title: ModelStringFilterInput + createdAt: ModelStringFilterInput + updatedAt: ModelStringFilterInput and: [ModelPostFilterInput] or: [ModelPostFilterInput] not: ModelPostFilterInput } input ModelPostConditionInput { - id: ModelIDInput - title: ModelStringInput - createdAt: ModelStringInput - updatedAt: ModelStringInput + id: ModelIDFilterInput + title: ModelStringFilterInput + createdAt: ModelStringFilterInput + updatedAt: ModelStringFilterInput and: [ModelPostConditionInput] or: [ModelPostConditionInput] not: ModelPostConditionInput @@ -1417,16 +1390,16 @@ type ModelUserConnection { } input ModelUserFilterInput { - id: ModelIDInput - name: ModelStringInput + id: ModelIDFilterInput + name: ModelStringFilterInput and: [ModelUserFilterInput] or: [ModelUserFilterInput] not: ModelUserFilterInput } input ModelUserConditionInput { - id: ModelIDInput - name: ModelStringInput + id: ModelIDFilterInput + name: ModelStringFilterInput and: [ModelUserConditionInput] or: [ModelUserConditionInput] not: ModelUserConditionInput @@ -1591,7 +1564,7 @@ type Query { listPosts(filter: ModelPostFilterInput, limit: Int, nextToken: String): ModelPostConnection } -input ModelStringInput { +input ModelStringFilterInput { ne: String eq: String le: String @@ -1607,7 +1580,7 @@ input ModelStringInput { size: ModelSizeInput } -input ModelIntInput { +input ModelIntFilterInput { ne: Int eq: Int le: Int @@ -1619,7 +1592,7 @@ input ModelIntInput { attributeType: ModelAttributeTypes } -input ModelFloatInput { +input ModelFloatFilterInput { ne: Float eq: Float le: Float @@ -1631,14 +1604,14 @@ input ModelFloatInput { attributeType: ModelAttributeTypes } -input ModelBooleanInput { +input ModelBooleanFilterInput { ne: Boolean eq: Boolean attributeExists: Boolean attributeType: ModelAttributeTypes } -input ModelIDInput { +input ModelIDFilterInput { ne: ID eq: ID le: ID @@ -1683,20 +1656,20 @@ type ModelPostConnection { } input ModelPostFilterInput { - id: ModelIDInput - title: ModelStringInput - createdAt: ModelStringInput - updatedAt: ModelStringInput + id: ModelIDFilterInput + title: ModelStringFilterInput + createdAt: ModelStringFilterInput + updatedAt: ModelStringFilterInput and: [ModelPostFilterInput] or: [ModelPostFilterInput] not: ModelPostFilterInput } input ModelPostConditionInput { - id: ModelIDInput - title: ModelStringInput - createdAt: ModelStringInput - updatedAt: ModelStringInput + id: ModelIDFilterInput + title: ModelStringFilterInput + createdAt: ModelStringFilterInput + updatedAt: ModelStringFilterInput and: [ModelPostConditionInput] or: [ModelPostConditionInput] not: ModelPostConditionInput @@ -1711,25 +1684,10 @@ input CreatePostInput { type Mutation { customCreatePost(input: CreatePostInput!, condition: ModelPostConditionInput): Post - updatePost(input: UpdatePostInput!, condition: ModelPostConditionInput): Post - deletePost(input: DeletePostInput!, condition: ModelPostConditionInput): Post -} - -input UpdatePostInput { - id: ID! - title: String - createdAt: String - updatedAt: String -} - -input DeletePostInput { - id: ID! } type Subscription { onCreatePost: Post @aws_subscribe(mutations: [\\"customCreatePost\\"]) - onUpdatePost: Post @aws_subscribe(mutations: [\\"updatePost\\"]) - onDeletePost: Post @aws_subscribe(mutations: [\\"deletePost\\"]) } " @@ -1877,7 +1835,7 @@ type Query { listPosts(filter: ModelPostFilterInput, limit: Int, nextToken: String): ModelPostConnection } -input ModelStringInput { +input ModelStringFilterInput { ne: String eq: String le: String @@ -1893,7 +1851,7 @@ input ModelStringInput { size: ModelSizeInput } -input ModelIntInput { +input ModelIntFilterInput { ne: Int eq: Int le: Int @@ -1905,7 +1863,7 @@ input ModelIntInput { attributeType: ModelAttributeTypes } -input ModelFloatInput { +input ModelFloatFilterInput { ne: Float eq: Float le: Float @@ -1917,14 +1875,14 @@ input ModelFloatInput { attributeType: ModelAttributeTypes } -input ModelBooleanInput { +input ModelBooleanFilterInput { ne: Boolean eq: Boolean attributeExists: Boolean attributeType: ModelAttributeTypes } -input ModelIDInput { +input ModelIDFilterInput { ne: ID eq: ID le: ID @@ -1969,20 +1927,20 @@ type ModelPostConnection { } input ModelPostFilterInput { - id: ModelIDInput - title: ModelStringInput - createdAt: ModelStringInput - updatedAt: ModelStringInput + id: ModelIDFilterInput + title: ModelStringFilterInput + createdAt: ModelStringFilterInput + updatedAt: ModelStringFilterInput and: [ModelPostFilterInput] or: [ModelPostFilterInput] not: ModelPostFilterInput } input ModelPostConditionInput { - id: ModelIDInput - title: ModelStringInput - createdAt: ModelStringInput - updatedAt: ModelStringInput + id: ModelIDFilterInput + title: ModelStringFilterInput + createdAt: ModelStringFilterInput + updatedAt: ModelStringFilterInput and: [ModelPostConditionInput] or: [ModelPostConditionInput] not: ModelPostConditionInput @@ -2163,7 +2121,7 @@ type Query { listPosts(filter: ModelPostFilterInput, limit: Int, nextToken: String): ModelPostConnection } -input ModelStringInput { +input ModelStringFilterInput { ne: String eq: String le: String @@ -2179,7 +2137,7 @@ input ModelStringInput { size: ModelSizeInput } -input ModelIntInput { +input ModelIntFilterInput { ne: Int eq: Int le: Int @@ -2191,7 +2149,7 @@ input ModelIntInput { attributeType: ModelAttributeTypes } -input ModelFloatInput { +input ModelFloatFilterInput { ne: Float eq: Float le: Float @@ -2203,14 +2161,14 @@ input ModelFloatInput { attributeType: ModelAttributeTypes } -input ModelBooleanInput { +input ModelBooleanFilterInput { ne: Boolean eq: Boolean attributeExists: Boolean attributeType: ModelAttributeTypes } -input ModelIDInput { +input ModelIDFilterInput { ne: ID eq: ID le: ID @@ -2255,20 +2213,20 @@ type ModelPostConnection { } input ModelPostFilterInput { - id: ModelIDInput - title: ModelStringInput - createdAt: ModelStringInput - updatedAt: ModelStringInput + id: ModelIDFilterInput + title: ModelStringFilterInput + createdAt: ModelStringFilterInput + updatedAt: ModelStringFilterInput and: [ModelPostFilterInput] or: [ModelPostFilterInput] not: ModelPostFilterInput } input ModelPostConditionInput { - id: ModelIDInput - title: ModelStringInput - createdAt: ModelStringInput - updatedAt: ModelStringInput + id: ModelIDFilterInput + title: ModelStringFilterInput + createdAt: ModelStringFilterInput + updatedAt: ModelStringFilterInput and: [ModelPostConditionInput] or: [ModelPostConditionInput] not: ModelPostConditionInput From ffe9cb09c0ea6d6f461558c59a95e4f6cc3fff3f Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Tue, 10 Aug 2021 11:53:21 -0400 Subject: [PATCH 39/63] chore(graphql-model-transformer): organized imports --- .../src/graphql-model-transformer.ts | 3 +-- .../src/wrappers/object-definition-wrapper.ts | 17 ++++++++--------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts b/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts index 6f9d64e5bbf..cc7c434b47f 100644 --- a/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts +++ b/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts @@ -6,17 +6,16 @@ import { MutationFieldType, QueryFieldType, SubscriptionFieldType, - TransformerTransformSchemaStepContextProvider, TransformerContextProvider, TransformerModelProvider, TransformerPrepareStepContextProvider, TransformerResolverProvider, TransformerSchemaVisitStepContextProvider, + TransformerTransformSchemaStepContextProvider, TransformerValidationStepContextProvider, } from '@aws-amplify/graphql-transformer-interfaces'; import { AttributeType, CfnTable, ITable, StreamViewType, Table, TableEncryption } from '@aws-cdk/aws-dynamodb'; import * as cdk from '@aws-cdk/core'; -import { Stack } from '@aws-cdk/core'; import { DirectiveNode, FieldDefinitionNode, diff --git a/packages/amplify-graphql-model-transformer/src/wrappers/object-definition-wrapper.ts b/packages/amplify-graphql-model-transformer/src/wrappers/object-definition-wrapper.ts index eab474c1c95..a3b11c3b603 100644 --- a/packages/amplify-graphql-model-transformer/src/wrappers/object-definition-wrapper.ts +++ b/packages/amplify-graphql-model-transformer/src/wrappers/object-definition-wrapper.ts @@ -1,23 +1,23 @@ import { ArgumentNode, DirectiveNode, + DocumentNode, + EnumTypeDefinitionNode, FieldDefinitionNode, + InputObjectTypeDefinitionNode, InputValueDefinitionNode, isListType, + Kind, + ListTypeNode, + Location, + NamedTypeNode, NameNode, + NonNullTypeNode, ObjectTypeDefinitionNode, StringValueNode, TypeNode, valueFromASTUntyped, ValueNode, - Location, - NonNullTypeNode, - ListTypeNode, - InputObjectTypeDefinitionNode, - NamedTypeNode, - EnumTypeDefinitionNode, - Kind, - DocumentNode, } from 'graphql'; import { DEFAULT_SCALARS, @@ -29,7 +29,6 @@ import { withNamedNodeNamed, } from 'graphql-transformer-common'; -import { merge } from 'lodash'; // Todo: to be moved to core later. context.output.getObject would return wrapper type so its easier to manipulate // objects From 2a6d56bd0aea937266ed43d5f19e1323a677e627 Mon Sep 17 00:00:00 2001 From: Christopher Sundersingh <83315412+sundersc@users.noreply.github.com> Date: Wed, 4 Aug 2021 11:40:51 -0700 Subject: [PATCH 40/63] fix(container-hosting): e2e test fix (#7889) --- .../amplify-e2e-tests/src/__tests__/container-hosting.test.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/amplify-e2e-tests/src/__tests__/container-hosting.test.ts b/packages/amplify-e2e-tests/src/__tests__/container-hosting.test.ts index 7b8a95dc23e..516ab0cdcdf 100644 --- a/packages/amplify-e2e-tests/src/__tests__/container-hosting.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/container-hosting.test.ts @@ -3,7 +3,6 @@ import { createNewProjectDir, deleteProject, deleteProjectDir, - enableContainerHosting, getBackendAmplifyMeta, initJSProjectWithProfile, removeHosting, @@ -23,8 +22,7 @@ describe('amplify add hosting - container', () => { cwd: projRoot, enableContainers: true, }); - // TODO: This needs attention. Need to force circle ci to run this test in us-east-1 - // await addDevContainerHosting(projRoot); + await addDevContainerHosting(projRoot); }); afterAll(async () => { From b78f385ba258ca1740a6a1d97bff23c30a227ccb Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 17:03:34 -0400 Subject: [PATCH 41/63] fix(graphql-model-transformer): fixed @model scalar types model filter input generation --- .../src/__tests__/model-transformer.test.ts | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index dc951348cee..9e62f49d4e7 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -649,4 +649,59 @@ describe('ModelTransformer: ', () => { expect(mutList).toContain('updatePost'); expect(mutList).toContain('deletePost'); }); + + it('support schema with multiple model directives', () => { + const validSchema = ` + type Post @model { + id: ID! + title: String! + createdAt: String + updatedAt: String + } + + type User @model { + id: ID! + name: String! + } + `; + + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + const queryType = getObjectType(parsed, 'Query'); + expect(queryType).toBeDefined(); + expectFields(queryType!, ['listPosts']); + expectFields(queryType!, ['listUsers']); + + const stringInputType = getInputType(parsed, 'ModelStringFilterInput'); + expect(stringInputType).toBeDefined(); + const booleanInputType = getInputType(parsed, 'ModelBooleanFilterInput'); + expect(booleanInputType).toBeDefined(); + const intInputType = getInputType(parsed, 'ModelIntFilterInput'); + expect(intInputType).toBeDefined(); + const floatInputType = getInputType(parsed, 'ModelFloatFilterInput'); + expect(floatInputType).toBeDefined(); + const idInputType = getInputType(parsed, 'ModelIDFilterInput'); + expect(idInputType).toBeDefined(); + const postInputType = getInputType(parsed, 'ModelPostFilterInput'); + expect(postInputType).toBeDefined(); + const userInputType = getInputType(parsed, 'ModelUserFilterInput'); + expect(userInputType).toBeDefined(); + + expect(verifyInputCount(parsed, 'ModelStringFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelBooleanFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelIntFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelFloatFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelIDFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelPostFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelUserFilterInput', 1)).toBeTruthy(); + }); }); From 97106612ba5d2c8725dfd450cdc541a92cc07b11 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 42/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 9e62f49d4e7..7f126f5ab61 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -704,4 +704,31 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'ModelPostFilterInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'ModelUserFilterInput', 1)).toBeTruthy(); }); + + it('should support enum as a field', () => { + const validSchema = ` + enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } + type Test @model { + status: Status! + lastStatus: Status! + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const createTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); + + const updateTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + }); }); From cacaada2032a1a621c74cea56295cb1067ce7ab7 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 17:03:34 -0400 Subject: [PATCH 43/63] fix(graphql-model-transformer): fixed @model scalar types model filter input generation --- .../src/__tests__/model-transformer.test.ts | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 7f126f5ab61..f7831ce21e9 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -664,12 +664,10 @@ describe('ModelTransformer: ', () => { name: String! } `; - const transformer = new GraphQLTransform({ transformers: [new ModelTransformer()], featureFlags, }); - const out = transformer.transform(validSchema); expect(out).toBeDefined(); @@ -704,31 +702,4 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'ModelPostFilterInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'ModelUserFilterInput', 1)).toBeTruthy(); }); - - it('should support enum as a field', () => { - const validSchema = ` - enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } - type Test @model { - status: Status! - lastStatus: Status! - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - validateModelSchema(parsed); - - const createTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); - - const updateTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); - }); }); From ca8144858fa6355350dd64a30eae8b22523d8774 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 13:06:28 -0400 Subject: [PATCH 44/63] fix(graphql-model-transformer): implemented support for nested non model fields --- .../src/__tests__/model-transformer.test.ts | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index f7831ce21e9..6352d7ab850 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -702,4 +702,59 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'ModelPostFilterInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'ModelUserFilterInput', 1)).toBeTruthy(); }); + + it('should support non-model types and enums', () => { + const validSchema = ` + type Post @model { + id: ID! + title: String! + createdAt: String + updatedAt: String + metadata: [PostMetadata!]! + appearsIn: [Episode]! + } + type PostMetadata { + tags: Tag + } + type Tag { + published: Boolean + metadata: PostMetadata + } + enum Episode { + NEWHOPE + EMPIRE + JEDI + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + + const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); + expect(postMetaDataInputType).toBeDefined(); + const tagInputType = getInputType(parsed, 'TagInput'); + expect(tagInputType).toBeDefined(); + expectFieldsOnInputType(tagInputType!, ['metadata']); + const createPostInputType = getInputType(parsed, 'CreatePostInput'); + expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); + const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); + expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); + + const postModelObject = getObjectType(parsed, 'Post'); + const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); + const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); + // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" + // in the generated CreatePostInput type - its types should be the same as in the Post @model type + verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); + + expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); + }); }); From 7bf91e4292c90b3c61e2f4019d0a6ffab63f4795 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 45/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 6352d7ab850..d7a8daf1b5f 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -757,4 +757,32 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); + + it('should support enum as a field', () => { + const validSchema = ` + enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } + type Test @model { + status: Status! + lastStatus: Status! + } + `; + + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const createTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); + + const updateTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + }); }); From 62f37b0a619bcc36dde823947d3f83da40aec0c5 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 17:03:34 -0400 Subject: [PATCH 46/63] fix(graphql-model-transformer): fixed @model scalar types model filter input generation --- .../src/__tests__/model-transformer.test.ts | 57 ++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index d7a8daf1b5f..7790f3a8048 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -757,7 +757,7 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); - + it('should support enum as a field', () => { const validSchema = ` enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } @@ -785,4 +785,59 @@ describe('ModelTransformer: ', () => { const updateTestInput = getInputType(parsed, 'CreateTestInput'); expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); }); + + it('support schema with multiple model directives', () => { + const validSchema = ` + type Post @model { + id: ID! + title: String! + createdAt: String + updatedAt: String + } + + type User @model { + id: ID! + name: String! + } + `; + + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + const queryType = getObjectType(parsed, 'Query'); + expect(queryType).toBeDefined(); + expectFields(queryType!, ['listPosts']); + expectFields(queryType!, ['listUsers']); + + const stringInputType = getInputType(parsed, 'ModelStringFilterInput'); + expect(stringInputType).toBeDefined(); + const booleanInputType = getInputType(parsed, 'ModelBooleanFilterInput'); + expect(booleanInputType).toBeDefined(); + const intInputType = getInputType(parsed, 'ModelIntFilterInput'); + expect(intInputType).toBeDefined(); + const floatInputType = getInputType(parsed, 'ModelFloatFilterInput'); + expect(floatInputType).toBeDefined(); + const idInputType = getInputType(parsed, 'ModelIDFilterInput'); + expect(idInputType).toBeDefined(); + const postInputType = getInputType(parsed, 'ModelPostFilterInput'); + expect(postInputType).toBeDefined(); + const userInputType = getInputType(parsed, 'ModelUserFilterInput'); + expect(userInputType).toBeDefined(); + + expect(verifyInputCount(parsed, 'ModelStringFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelBooleanFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelIntFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelFloatFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelIDFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelPostFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelUserFilterInput', 1)).toBeTruthy(); + }); }); From e9d50334e5279e9e6c18d82a21bc20882c599da2 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 47/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 7790f3a8048..0bcf67d9699 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -840,4 +840,31 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'ModelPostFilterInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'ModelUserFilterInput', 1)).toBeTruthy(); }); + + it('should support enum as a field', () => { + const validSchema = ` + enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } + type Test @model { + status: Status! + lastStatus: Status! + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const createTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); + + const updateTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + }); }); From 18d24f6fddce50b36270358236508bf095906519 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 17:03:34 -0400 Subject: [PATCH 48/63] fix(graphql-model-transformer): fixed @model scalar types model filter input generation --- .../src/__tests__/model-transformer.test.ts | 58 +------------------ 1 file changed, 1 insertion(+), 57 deletions(-) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 0bcf67d9699..b06b3364442 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -737,6 +737,7 @@ describe('ModelTransformer: ', () => { expect(definition).toBeDefined(); const parsed = parse(definition); + const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); expect(postMetaDataInputType).toBeDefined(); const tagInputType = getInputType(parsed, 'TagInput'); @@ -758,34 +759,6 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); - it('should support enum as a field', () => { - const validSchema = ` - enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } - type Test @model { - status: Status! - lastStatus: Status! - } - `; - - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - validateModelSchema(parsed); - - const createTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); - - const updateTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); - }); - it('support schema with multiple model directives', () => { const validSchema = ` type Post @model { @@ -800,12 +773,10 @@ describe('ModelTransformer: ', () => { name: String! } `; - const transformer = new GraphQLTransform({ transformers: [new ModelTransformer()], featureFlags, }); - const out = transformer.transform(validSchema); expect(out).toBeDefined(); @@ -840,31 +811,4 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'ModelPostFilterInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'ModelUserFilterInput', 1)).toBeTruthy(); }); - - it('should support enum as a field', () => { - const validSchema = ` - enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } - type Test @model { - status: Status! - lastStatus: Status! - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - validateModelSchema(parsed); - - const createTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); - - const updateTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); - }); }); From 30039abd65b7abe97ae1e0af439fbdae10802ab3 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 13:06:28 -0400 Subject: [PATCH 49/63] fix(graphql-model-transformer): implemented support for nested non model fields --- .../src/__tests__/model-transformer.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index b06b3364442..f657532a5a1 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -783,6 +783,8 @@ describe('ModelTransformer: ', () => { const definition = out.schema; expect(definition).toBeDefined(); const parsed = parse(definition); + validateModelSchema(parsed); + const queryType = getObjectType(parsed, 'Query'); expect(queryType).toBeDefined(); expectFields(queryType!, ['listPosts']); From 40d696f9bb48fd6fdf1394f8efbd047e35bb575c Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 50/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index f657532a5a1..1395fdfe58f 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -777,6 +777,7 @@ describe('ModelTransformer: ', () => { transformers: [new ModelTransformer()], featureFlags, }); + const out = transformer.transform(validSchema); expect(out).toBeDefined(); @@ -784,7 +785,7 @@ describe('ModelTransformer: ', () => { expect(definition).toBeDefined(); const parsed = parse(definition); validateModelSchema(parsed); - + const queryType = getObjectType(parsed, 'Query'); expect(queryType).toBeDefined(); expectFields(queryType!, ['listPosts']); From 00a6d5b339a14a84fb1f5101d69759461b43803b Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 13:06:28 -0400 Subject: [PATCH 51/63] fix(graphql-model-transformer): implemented support for nested non model fields --- .../src/__tests__/model-transformer.test.ts | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 1395fdfe58f..fcf1c0549db 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -814,4 +814,59 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'ModelPostFilterInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'ModelUserFilterInput', 1)).toBeTruthy(); }); + + it('should support non-model types and enums', () => { + const validSchema = ` + type Post @model { + id: ID! + title: String! + createdAt: String + updatedAt: String + metadata: [PostMetadata!]! + appearsIn: [Episode]! + } + type PostMetadata { + tags: Tag + } + type Tag { + published: Boolean + metadata: PostMetadata + } + enum Episode { + NEWHOPE + EMPIRE + JEDI + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + + const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); + expect(postMetaDataInputType).toBeDefined(); + const tagInputType = getInputType(parsed, 'TagInput'); + expect(tagInputType).toBeDefined(); + expectFieldsOnInputType(tagInputType!, ['metadata']); + const createPostInputType = getInputType(parsed, 'CreatePostInput'); + expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); + const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); + expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); + + const postModelObject = getObjectType(parsed, 'Post'); + const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); + const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); + // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" + // in the generated CreatePostInput type - its types should be the same as in the Post @model type + verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); + + expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); + }); }); From 341e78e275fcb8ae0176ec5ad6291afd7bce5ad9 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 52/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index fcf1c0549db..a4ad0ca6b30 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -534,6 +534,7 @@ describe('ModelTransformer: ', () => { type User @model { id: ID! name: String! + } `; const transformer = new GraphQLTransform({ From c4422395b4f24c23507873bd6def6fa230016c33 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Mon, 9 Aug 2021 12:14:33 -0400 Subject: [PATCH 53/63] chore(graphql-model-transformer): added validateModelSchema to unit test --- .../src/__tests__/model-transformer.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index a4ad0ca6b30..0b4ee369ef0 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -737,7 +737,6 @@ describe('ModelTransformer: ', () => { const definition = out.schema; expect(definition).toBeDefined(); const parsed = parse(definition); - const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); expect(postMetaDataInputType).toBeDefined(); @@ -850,6 +849,8 @@ describe('ModelTransformer: ', () => { expect(definition).toBeDefined(); const parsed = parse(definition); + validateModelSchema(parsed); + const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); expect(postMetaDataInputType).toBeDefined(); const tagInputType = getInputType(parsed, 'TagInput'); From 397865d4dcc22e4da31424b66de9399ff23d2e9f Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 54/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 0b4ee369ef0..c03ad57aaef 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -871,4 +871,32 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); + + it('should support enum as a field', () => { + const validSchema = ` + enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } + type Test @model { + status: Status! + lastStatus: Status! + } + `; + + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const createTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); + + const updateTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + }); }); From d5032d63ab1efe32ab8e9f93bcfc98cd3562bdcc Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 17:03:34 -0400 Subject: [PATCH 55/63] fix(graphql-model-transformer): fixed @model scalar types model filter input generation --- .../src/__tests__/model-transformer.test.ts | 57 ++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index c03ad57aaef..202fd47af70 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -871,7 +871,7 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); - + it('should support enum as a field', () => { const validSchema = ` enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } @@ -899,4 +899,59 @@ describe('ModelTransformer: ', () => { const updateTestInput = getInputType(parsed, 'CreateTestInput'); expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); }); + + it('support schema with multiple model directives', () => { + const validSchema = ` + type Post @model { + id: ID! + title: String! + createdAt: String + updatedAt: String + } + + type User @model { + id: ID! + name: String! + } + `; + + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + const queryType = getObjectType(parsed, 'Query'); + expect(queryType).toBeDefined(); + expectFields(queryType!, ['listPosts']); + expectFields(queryType!, ['listUsers']); + + const stringInputType = getInputType(parsed, 'ModelStringFilterInput'); + expect(stringInputType).toBeDefined(); + const booleanInputType = getInputType(parsed, 'ModelBooleanFilterInput'); + expect(booleanInputType).toBeDefined(); + const intInputType = getInputType(parsed, 'ModelIntFilterInput'); + expect(intInputType).toBeDefined(); + const floatInputType = getInputType(parsed, 'ModelFloatFilterInput'); + expect(floatInputType).toBeDefined(); + const idInputType = getInputType(parsed, 'ModelIDFilterInput'); + expect(idInputType).toBeDefined(); + const postInputType = getInputType(parsed, 'ModelPostFilterInput'); + expect(postInputType).toBeDefined(); + const userInputType = getInputType(parsed, 'ModelUserFilterInput'); + expect(userInputType).toBeDefined(); + + expect(verifyInputCount(parsed, 'ModelStringFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelBooleanFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelIntFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelFloatFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelIDFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelPostFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelUserFilterInput', 1)).toBeTruthy(); + }); }); From 8668dbf6fecf2d30684a781e9a1cce55664def60 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:41:02 -0400 Subject: [PATCH 56/63] fix(graphql-model-transformer): fixed input type field generation for enum types --- .../src/__tests__/model-transformer.test.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 202fd47af70..1b766b0165c 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -954,4 +954,31 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'ModelPostFilterInput', 1)).toBeTruthy(); expect(verifyInputCount(parsed, 'ModelUserFilterInput', 1)).toBeTruthy(); }); + + it('should support enum as a field', () => { + const validSchema = ` + enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } + type Test @model { + status: Status! + lastStatus: Status! + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const createTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); + + const updateTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + }); }); From 5643c941ade70089abe5dcf4c41c2aa402f64328 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 17:03:34 -0400 Subject: [PATCH 57/63] fix(graphql-model-transformer): fixed @model scalar types model filter input generation --- .../src/__tests__/model-transformer.test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 1b766b0165c..1a9adfb7c51 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -914,12 +914,10 @@ describe('ModelTransformer: ', () => { name: String! } `; - const transformer = new GraphQLTransform({ transformers: [new ModelTransformer()], featureFlags, }); - const out = transformer.transform(validSchema); expect(out).toBeDefined(); From e87fef769856f2c9dd456e2b6720c0d94126f0a2 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Mon, 9 Aug 2021 15:25:55 -0400 Subject: [PATCH 58/63] chore(graphql-model-transformer): fixed merge conflicts --- .../amplify-e2e-tests/src/__tests__/container-hosting.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/amplify-e2e-tests/src/__tests__/container-hosting.test.ts b/packages/amplify-e2e-tests/src/__tests__/container-hosting.test.ts index 516ab0cdcdf..7b8a95dc23e 100644 --- a/packages/amplify-e2e-tests/src/__tests__/container-hosting.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/container-hosting.test.ts @@ -3,6 +3,7 @@ import { createNewProjectDir, deleteProject, deleteProjectDir, + enableContainerHosting, getBackendAmplifyMeta, initJSProjectWithProfile, removeHosting, @@ -22,7 +23,8 @@ describe('amplify add hosting - container', () => { cwd: projRoot, enableContainers: true, }); - await addDevContainerHosting(projRoot); + // TODO: This needs attention. Need to force circle ci to run this test in us-east-1 + // await addDevContainerHosting(projRoot); }); afterAll(async () => { From aca0cde0679ad64bbe4d43cd52e7a59711038010 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Mon, 9 Aug 2021 12:06:27 -0400 Subject: [PATCH 59/63] chore(graphql-model-transformer): added validateModelSchema to unit test --- .../src/__tests__/model-transformer.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 1a9adfb7c51..1af75bbcf63 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -530,7 +530,7 @@ describe('ModelTransformer: ', () => { createdAt: String updatedAt: String } - + type User @model { id: ID! name: String! From 08c38eb9423202846b38901eba00e21387161e9d Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Wed, 4 Aug 2021 13:06:28 -0400 Subject: [PATCH 60/63] fix(graphql-model-transformer): implemented support for nested non model fields --- .../src/__tests__/model-transformer.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 1af75bbcf63..f6f4c7bfa18 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -850,7 +850,6 @@ describe('ModelTransformer: ', () => { const parsed = parse(definition); validateModelSchema(parsed); - const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); expect(postMetaDataInputType).toBeDefined(); const tagInputType = getInputType(parsed, 'TagInput'); From ce9b391f56b7af986f067ed653c8c772e1812d9d Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Mon, 9 Aug 2021 12:06:27 -0400 Subject: [PATCH 61/63] chore(graphql-model-transformer): added validateModelSchema to unit test --- .../src/__tests__/model-transformer.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index f6f4c7bfa18..1af75bbcf63 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -850,6 +850,7 @@ describe('ModelTransformer: ', () => { const parsed = parse(definition); validateModelSchema(parsed); + const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); expect(postMetaDataInputType).toBeDefined(); const tagInputType = getInputType(parsed, 'TagInput'); From fd180e00ea4d77ff36a77532f7fecf585645df9a Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Mon, 9 Aug 2021 20:18:50 -0400 Subject: [PATCH 62/63] fix(graphql-model-transformer): fixed @model transformer advanced subscriptions --- .../src/__tests__/model-transformer.test.ts | 93 ++++++++++++++----- 1 file changed, 69 insertions(+), 24 deletions(-) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 1af75bbcf63..87f297a0f0d 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -872,15 +872,14 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); - it('should support enum as a field', () => { - const validSchema = ` - enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } - type Test @model { - status: Status! - lastStatus: Status! + it('should generate only create mutation', () => { + const validSchema = `type Post @model(mutations: { create: "customCreatePost" }) { + id: ID! + title: String! + createdAt: String + updatedAt: String } `; - const transformer = new GraphQLTransform({ transformers: [new ModelTransformer()], featureFlags, @@ -893,11 +892,10 @@ describe('ModelTransformer: ', () => { const parsed = parse(definition); validateModelSchema(parsed); - const createTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); - - const updateTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + const mutationType = getObjectType(parsed, 'Mutation'); + expect(mutationType).toBeDefined(); + expectFields(mutationType!, ['customCreatePost']); + doNotExpectFields(mutationType!, ['updatePost']); }); it('support schema with multiple model directives', () => { @@ -924,6 +922,8 @@ describe('ModelTransformer: ', () => { const definition = out.schema; expect(definition).toBeDefined(); const parsed = parse(definition); + validateModelSchema(parsed); + const queryType = getObjectType(parsed, 'Query'); expect(queryType).toBeDefined(); expectFields(queryType!, ['listPosts']); @@ -953,30 +953,75 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'ModelUserFilterInput', 1)).toBeTruthy(); }); - it('should support enum as a field', () => { + it('it should generate filter inputs', () => { const validSchema = ` - enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } - type Test @model { - status: Status! - lastStatus: Status! - } - `; + type Post @model { + id: ID! + title: String! + createdAt: String + updatedAt: String + }`; const transformer = new GraphQLTransform({ transformers: [new ModelTransformer()], featureFlags, }); - const out = transformer.transform(validSchema); expect(out).toBeDefined(); + const definition = out.schema; expect(definition).toBeDefined(); const parsed = parse(definition); validateModelSchema(parsed); - const createTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); + const queryType = getObjectType(parsed, 'Query'); + expect(queryType).toBeDefined(); + expectFields(queryType!, ['listPosts']); - const updateTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); + const connectionType = getObjectType(parsed, 'ModelPostConnection'); + expect(connectionType).toBeDefined(); + + expect(verifyInputCount(parsed, 'ModelStringFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelBooleanFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelIntFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelFloatFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelIDFilterInput', 1)).toBeTruthy(); + expect(verifyInputCount(parsed, 'ModelPostFilterInput', 1)).toBeTruthy(); + }); + + it('should support advanced subscriptions', () => { + const validSchema = `type Post @model(subscriptions: { + onCreate: ["onFeedUpdated", "onCreatePost"], + onUpdate: ["onFeedUpdated"], + onDelete: ["onFeedUpdated"] + }) { + id: ID! + title: String! + createdAt: String + updatedAt: String + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer()], + featureFlags, + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const definition = out.schema; + expect(definition).toBeDefined(); + const parsed = parse(definition); + validateModelSchema(parsed); + + const subscriptionType = getObjectType(parsed, 'Subscription'); + expect(subscriptionType).toBeDefined(); + expectFields(subscriptionType!, ['onFeedUpdated', 'onCreatePost']); + const subField = subscriptionType!.fields!.find(f => f.name.value === 'onFeedUpdated'); + expect(subField!.directives!.length).toEqual(1); + expect(subField!.directives![0].name!.value).toEqual('aws_subscribe'); + const mutationsList = subField!.directives![0].arguments!.find(a => a.name.value === 'mutations')!.value as ListValueNode; + const mutList = mutationsList.values.map((v: any) => v.value); + expect(mutList.length).toEqual(3); + expect(mutList).toContain('createPost'); + expect(mutList).toContain('updatePost'); + expect(mutList).toContain('deletePost'); }); }); From 8bdf900026f896c3afbeb6f4081d5e2eadbdbf89 Mon Sep 17 00:00:00 2001 From: lazpavel <85319655+lazpavel@users.noreply.github.com> Date: Tue, 10 Aug 2021 12:54:42 -0400 Subject: [PATCH 63/63] fix(graphql-model-transformer): fixed @model transformer advanced subscriptions --- .../src/__tests__/model-transformer.test.ts | 394 +----------------- 1 file changed, 10 insertions(+), 384 deletions(-) diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts index 87f297a0f0d..e16b304aff8 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/model-transformer.test.ts @@ -413,89 +413,6 @@ describe('ModelTransformer: ', () => { expect(result.pipelineFunctions['Mutation.createPost.req.vtl']).toMatchSnapshot(); }); - it('should support enum as a field', () => { - const validSchema = ` - enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } - type Test @model { - status: Status! - lastStatus: Status! - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - validateModelSchema(parsed); - - const createTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); - - const updateTestInput = getInputType(parsed, 'CreateTestInput'); - expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); - }); - - it('should support non-model types and enums', () => { - const validSchema = ` - type Post @model { - id: ID! - title: String! - createdAt: String - updatedAt: String - metadata: [PostMetadata!]! - appearsIn: [Episode]! - } - type PostMetadata { - tags: Tag - } - type Tag { - published: Boolean - metadata: PostMetadata - } - enum Episode { - NEWHOPE - EMPIRE - JEDI - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - validateModelSchema(parsed); - - const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); - expect(postMetaDataInputType).toBeDefined(); - const tagInputType = getInputType(parsed, 'TagInput'); - expect(tagInputType).toBeDefined(); - expectFieldsOnInputType(tagInputType!, ['metadata']); - const createPostInputType = getInputType(parsed, 'CreatePostInput'); - expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); - const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); - expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); - - const postModelObject = getObjectType(parsed, 'Post'); - const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); - const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); - // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" - // in the generated CreatePostInput type - its types should be the same as in the Post @model type - verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); - - expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); - }); - it('should generate only create mutation', () => { const validSchema = `type Post @model(mutations: { create: "customCreatePost" }) { id: ID! @@ -530,11 +447,10 @@ describe('ModelTransformer: ', () => { createdAt: String updatedAt: String } - + type User @model { id: ID! name: String! - } `; const transformer = new GraphQLTransform({ @@ -579,198 +495,12 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'ModelUserFilterInput', 1)).toBeTruthy(); }); - it('it should generate filter inputs', () => { - const validSchema = ` - type Post @model { - id: ID! - title: String! - createdAt: String - updatedAt: String - }`; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - validateModelSchema(parsed); - - const queryType = getObjectType(parsed, 'Query'); - expect(queryType).toBeDefined(); - expectFields(queryType!, ['listPosts']); - - const connectionType = getObjectType(parsed, 'ModelPostConnection'); - expect(connectionType).toBeDefined(); - - expect(verifyInputCount(parsed, 'ModelStringFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelBooleanFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelIntFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelFloatFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelIDFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelPostFilterInput', 1)).toBeTruthy(); - }); - - it('should support advanced subscriptions', () => { - const validSchema = `type Post @model(subscriptions: { - onCreate: ["onFeedUpdated", "onCreatePost"], - onUpdate: ["onFeedUpdated"], - onDelete: ["onFeedUpdated"] - }) { - id: ID! - title: String! - createdAt: String - updatedAt: String - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - validateModelSchema(parsed); - - const subscriptionType = getObjectType(parsed, 'Subscription'); - expect(subscriptionType).toBeDefined(); - expectFields(subscriptionType!, ['onFeedUpdated', 'onCreatePost']); - const subField = subscriptionType!.fields!.find(f => f.name.value === 'onFeedUpdated'); - expect(subField!.directives!.length).toEqual(1); - expect(subField!.directives![0].name!.value).toEqual('aws_subscribe'); - const mutationsList = subField!.directives![0].arguments!.find(a => a.name.value === 'mutations')!.value as ListValueNode; - const mutList = mutationsList.values.map((v: any) => v.value); - expect(mutList.length).toEqual(3); - expect(mutList).toContain('createPost'); - expect(mutList).toContain('updatePost'); - expect(mutList).toContain('deletePost'); - }); - - it('support schema with multiple model directives', () => { - const validSchema = ` - type Post @model { - id: ID! - title: String! - createdAt: String - updatedAt: String - } - - type User @model { - id: ID! - name: String! - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - const queryType = getObjectType(parsed, 'Query'); - expect(queryType).toBeDefined(); - expectFields(queryType!, ['listPosts']); - expectFields(queryType!, ['listUsers']); - - const stringInputType = getInputType(parsed, 'ModelStringFilterInput'); - expect(stringInputType).toBeDefined(); - const booleanInputType = getInputType(parsed, 'ModelBooleanFilterInput'); - expect(booleanInputType).toBeDefined(); - const intInputType = getInputType(parsed, 'ModelIntFilterInput'); - expect(intInputType).toBeDefined(); - const floatInputType = getInputType(parsed, 'ModelFloatFilterInput'); - expect(floatInputType).toBeDefined(); - const idInputType = getInputType(parsed, 'ModelIDFilterInput'); - expect(idInputType).toBeDefined(); - const postInputType = getInputType(parsed, 'ModelPostFilterInput'); - expect(postInputType).toBeDefined(); - const userInputType = getInputType(parsed, 'ModelUserFilterInput'); - expect(userInputType).toBeDefined(); - - expect(verifyInputCount(parsed, 'ModelStringFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelBooleanFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelIntFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelFloatFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelIDFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelPostFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelUserFilterInput', 1)).toBeTruthy(); - }); - - it('should support non-model types and enums', () => { - const validSchema = ` - type Post @model { - id: ID! - title: String! - createdAt: String - updatedAt: String - metadata: [PostMetadata!]! - appearsIn: [Episode]! - } - type PostMetadata { - tags: Tag - } - type Tag { - published: Boolean - metadata: PostMetadata - } - enum Episode { - NEWHOPE - EMPIRE - JEDI - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - - const postMetaDataInputType = getInputType(parsed, 'PostMetadataInput'); - expect(postMetaDataInputType).toBeDefined(); - const tagInputType = getInputType(parsed, 'TagInput'); - expect(tagInputType).toBeDefined(); - expectFieldsOnInputType(tagInputType!, ['metadata']); - const createPostInputType = getInputType(parsed, 'CreatePostInput'); - expectFieldsOnInputType(createPostInputType!, ['metadata', 'appearsIn']); - const updatePostInputType = getInputType(parsed, 'UpdatePostInput'); - expectFieldsOnInputType(updatePostInputType!, ['metadata', 'appearsIn']); - - const postModelObject = getObjectType(parsed, 'Post'); - const postMetaDataInputField = getFieldOnInputType(createPostInputType!, 'metadata'); - const postMetaDataField = getFieldOnObjectType(postModelObject!, 'metadata'); - // this checks that the non-model type was properly "unwrapped", renamed, and "rewrapped" - // in the generated CreatePostInput type - its types should be the same as in the Post @model type - verifyMatchingTypes(postMetaDataInputField.type, postMetaDataField.type); - - expect(verifyInputCount(parsed, 'PostMetadataInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); - }); - - it('support schema with multiple model directives', () => { + it('should support enum as a field', () => { const validSchema = ` - type Post @model { - id: ID! - title: String! - createdAt: String - updatedAt: String - } - - type User @model { - id: ID! - name: String! + enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN } + type Test @model { + status: Status! + lastStatus: Status! } `; const transformer = new GraphQLTransform({ @@ -780,39 +510,16 @@ describe('ModelTransformer: ', () => { const out = transformer.transform(validSchema); expect(out).toBeDefined(); - const definition = out.schema; expect(definition).toBeDefined(); const parsed = parse(definition); validateModelSchema(parsed); - const queryType = getObjectType(parsed, 'Query'); - expect(queryType).toBeDefined(); - expectFields(queryType!, ['listPosts']); - expectFields(queryType!, ['listUsers']); - - const stringInputType = getInputType(parsed, 'ModelStringFilterInput'); - expect(stringInputType).toBeDefined(); - const booleanInputType = getInputType(parsed, 'ModelBooleanFilterInput'); - expect(booleanInputType).toBeDefined(); - const intInputType = getInputType(parsed, 'ModelIntFilterInput'); - expect(intInputType).toBeDefined(); - const floatInputType = getInputType(parsed, 'ModelFloatFilterInput'); - expect(floatInputType).toBeDefined(); - const idInputType = getInputType(parsed, 'ModelIDFilterInput'); - expect(idInputType).toBeDefined(); - const postInputType = getInputType(parsed, 'ModelPostFilterInput'); - expect(postInputType).toBeDefined(); - const userInputType = getInputType(parsed, 'ModelUserFilterInput'); - expect(userInputType).toBeDefined(); + const createTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']); - expect(verifyInputCount(parsed, 'ModelStringFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelBooleanFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelIntFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelFloatFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelIDFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelPostFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelUserFilterInput', 1)).toBeTruthy(); + const updateTestInput = getInputType(parsed, 'CreateTestInput'); + expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']); }); it('should support non-model types and enums', () => { @@ -872,87 +579,6 @@ describe('ModelTransformer: ', () => { expect(verifyInputCount(parsed, 'TagInput', 1)).toBeTruthy(); }); - it('should generate only create mutation', () => { - const validSchema = `type Post @model(mutations: { create: "customCreatePost" }) { - id: ID! - title: String! - createdAt: String - updatedAt: String - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - validateModelSchema(parsed); - - const mutationType = getObjectType(parsed, 'Mutation'); - expect(mutationType).toBeDefined(); - expectFields(mutationType!, ['customCreatePost']); - doNotExpectFields(mutationType!, ['updatePost']); - }); - - it('support schema with multiple model directives', () => { - const validSchema = ` - type Post @model { - id: ID! - title: String! - createdAt: String - updatedAt: String - } - - type User @model { - id: ID! - name: String! - } - `; - const transformer = new GraphQLTransform({ - transformers: [new ModelTransformer()], - featureFlags, - }); - const out = transformer.transform(validSchema); - expect(out).toBeDefined(); - - const definition = out.schema; - expect(definition).toBeDefined(); - const parsed = parse(definition); - validateModelSchema(parsed); - - const queryType = getObjectType(parsed, 'Query'); - expect(queryType).toBeDefined(); - expectFields(queryType!, ['listPosts']); - expectFields(queryType!, ['listUsers']); - - const stringInputType = getInputType(parsed, 'ModelStringFilterInput'); - expect(stringInputType).toBeDefined(); - const booleanInputType = getInputType(parsed, 'ModelBooleanFilterInput'); - expect(booleanInputType).toBeDefined(); - const intInputType = getInputType(parsed, 'ModelIntFilterInput'); - expect(intInputType).toBeDefined(); - const floatInputType = getInputType(parsed, 'ModelFloatFilterInput'); - expect(floatInputType).toBeDefined(); - const idInputType = getInputType(parsed, 'ModelIDFilterInput'); - expect(idInputType).toBeDefined(); - const postInputType = getInputType(parsed, 'ModelPostFilterInput'); - expect(postInputType).toBeDefined(); - const userInputType = getInputType(parsed, 'ModelUserFilterInput'); - expect(userInputType).toBeDefined(); - - expect(verifyInputCount(parsed, 'ModelStringFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelBooleanFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelIntFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelFloatFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelIDFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelPostFilterInput', 1)).toBeTruthy(); - expect(verifyInputCount(parsed, 'ModelUserFilterInput', 1)).toBeTruthy(); - }); - it('it should generate filter inputs', () => { const validSchema = ` type Post @model {