From 8cd3b26d24a5553104267ce8f597d7d4701246f0 Mon Sep 17 00:00:00 2001 From: Christopher Sundersingh Date: Mon, 18 Sep 2023 13:08:16 -0700 Subject: [PATCH] fix(graphql): disable default value validation for rds --- ...grapphql-default-value-transformer.test.ts | 31 ++++++++++++++++++- .../src/graphql-default-value-transformer.ts | 21 ++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/packages/amplify-graphql-default-value-transformer/src/__tests__/amplify-grapphql-default-value-transformer.test.ts b/packages/amplify-graphql-default-value-transformer/src/__tests__/amplify-grapphql-default-value-transformer.test.ts index c2cf443a93..3079ce0f27 100644 --- a/packages/amplify-graphql-default-value-transformer/src/__tests__/amplify-grapphql-default-value-transformer.test.ts +++ b/packages/amplify-graphql-default-value-transformer/src/__tests__/amplify-grapphql-default-value-transformer.test.ts @@ -1,5 +1,5 @@ import { ModelTransformer } from '@aws-amplify/graphql-model-transformer'; -import { validateModelSchema } from '@aws-amplify/graphql-transformer-core'; +import { DatasourceType, validateModelSchema } from '@aws-amplify/graphql-transformer-core'; import { parse } from 'graphql'; import { testTransform } from '@aws-amplify/graphql-transformer-test-utils'; import { DefaultValueTransformer } from '..'; @@ -311,4 +311,33 @@ describe('DefaultValueModelTransformer:', () => { const schema = parse(out.schema); validateModelSchema(schema); }); + + it('default value type should not be validated for rds datasource', async () => { + const validSchema = ` + type Note @model { + id: ID! + content: String! + createdAt: AWSDateTime @default(value: "CURRENT_TIMESTAMP") + } + `; + + const modelToDatasourceMap = new Map(); + modelToDatasourceMap.set('Note', { + dbType: 'MySQL', + provisionDB: false, + }); + const out = testTransform({ + schema: validSchema, + transformers: [new ModelTransformer(), new DefaultValueTransformer()], + modelToDatasourceMap, + }); + expect(out).toBeDefined(); + + validateModelSchema(parse(out.schema)); + expect(out.stacks).toBeDefined(); + expect(out.stacks.RdsApiStack).toBeDefined(); + expect(out.stacks.RdsApiStack.Resources).toBeDefined(); + expect(out.resolvers['Mutation.createNote.init.1.req.vtl']).toBeDefined(); + expect(out.resolvers['Mutation.createNote.init.2.req.vtl']).toBeUndefined(); + }); }); diff --git a/packages/amplify-graphql-default-value-transformer/src/graphql-default-value-transformer.ts b/packages/amplify-graphql-default-value-transformer/src/graphql-default-value-transformer.ts index 488de18ef7..c4536f8dc0 100644 --- a/packages/amplify-graphql-default-value-transformer/src/graphql-default-value-transformer.ts +++ b/packages/amplify-graphql-default-value-transformer/src/graphql-default-value-transformer.ts @@ -1,4 +1,5 @@ import { + DDB_DB_TYPE, DirectiveWrapper, generateGetArgumentsInput, InputObjectDefinitionWrapper, @@ -79,7 +80,18 @@ const validate = (ctx: TransformerSchemaVisitStepContextProvider, config: Defaul validateModelDirective(config); validateFieldType(ctx, config.field.type); validateDirectiveArguments(config.directive); - validateDefaultValueType(ctx, config); + + // Validate the default values only for the DynamoDB datasource. + // For RDS, the database determines and sets the default value. We will not validate the value in transformers. + const isDynamoDB = isDynamoDBDatasource(ctx, config.object.name.value); + if (isDynamoDB) { + validateDefaultValueType(ctx, config); + } +}; + +const isDynamoDBDatasource = (ctx: TransformerSchemaVisitStepContextProvider, modelName: string): boolean => { + const isDynamoDB = (ctx.modelToDatasourceMap.get(modelName)?.dbType ?? DDB_DB_TYPE) === DDB_DB_TYPE; + return isDynamoDB; }; export class DefaultValueTransformer extends TransformerPluginBase { @@ -128,6 +140,13 @@ export class DefaultValueTransformer extends TransformerPluginBase { const context = ctx as TransformerContextProvider; for (const typeName of this.directiveMap.keys()) { + + // Set the default value only for DDB datasource. For RDS, the database will set the value. + const isDynamoDB = isDynamoDBDatasource(ctx, typeName); + if (!isDynamoDB) { + continue; + } + const snippets: string[] = []; for (const config of this.directiveMap.get(typeName)!) { const fieldName = config.field.name.value;