From 5667c3a30c77c52329679c96cc272aa40672d1e4 Mon Sep 17 00:00:00 2001 From: Peter Vaiciulis Date: Wed, 11 Sep 2024 12:54:37 -0700 Subject: [PATCH 1/6] test(graphql-default-value-transformer): fix snapshot The expected behavior here is that "stringValue" should not be required after @default is applied --- .../amplify-grapphql-default-value-transformer.test.ts.snap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/amplify-graphql-default-value-transformer/src/__tests__/__snapshots__/amplify-grapphql-default-value-transformer.test.ts.snap b/packages/amplify-graphql-default-value-transformer/src/__tests__/__snapshots__/amplify-grapphql-default-value-transformer.test.ts.snap index 320a27b4e9..d94e2aabac 100644 --- a/packages/amplify-graphql-default-value-transformer/src/__tests__/__snapshots__/amplify-grapphql-default-value-transformer.test.ts.snap +++ b/packages/amplify-graphql-default-value-transformer/src/__tests__/__snapshots__/amplify-grapphql-default-value-transformer.test.ts.snap @@ -189,7 +189,7 @@ input ModelTestConditionInput { input CreateTestInput { id: ID - stringValue: String! + stringValue: String } input UpdateTestInput { From 4853cef922af0a027fefc7f48532e8e9ca7bba61 Mon Sep 17 00:00:00 2001 From: Peter Vaiciulis Date: Wed, 11 Sep 2024 12:56:37 -0700 Subject: [PATCH 2/6] fix(graphql-default-value-transformer): modify inputObjects on the ctx --- .../src/graphql-default-value-transformer.ts | 1 + 1 file changed, 1 insertion(+) 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 15c76e22a5..5802deada6 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 @@ -123,6 +123,7 @@ export class DefaultValueTransformer extends TransformerPluginBase { const input = InputObjectDefinitionWrapper.fromObject(name, config.object, ctx.inputDocument); const fieldWrapper = input.fields.find((f) => f.name === config.field.name.value); fieldWrapper?.makeNullable(); + ctx.output.updateInput(input.serialize()); } } }; From a753e8014d95441632c8d201daaf41b7b3352412 Mon Sep 17 00:00:00 2001 From: Peter Vaiciulis Date: Wed, 11 Sep 2024 21:42:03 -0700 Subject: [PATCH 3/6] test(graphql-default-value-transformer): @default is not to be used on primaryKey fields --- ...grapphql-default-value-transformer.test.ts | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) 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 344b350d5f..cac1fc9092 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 @@ -217,6 +217,38 @@ describe('DefaultValueModelTransformer:', () => { ).toThrow('Default value "text" is not a valid AWSIPAddress.'); }); + it('throws if @default is used on an implicit primaryKey', () => { + const schema = ` + type Test @model { + id: ID! @default(value: "ID: 80361") + stringValue: String! + } + `; + + expect(() => + testTransform({ + schema, + transformers: [new ModelTransformer(), new DefaultValueTransformer()], + }), + ).toThrow('The @default directive may not be applied to primaryKey fields.'); + }); + + it('throws if @default is used on an explicit primaryKey', () => { + const schema = ` + type Test @model { + id: ID! @default(value: "ID: 80361") @primaryKey + stringValue: String! + } + `; + + expect(() => + testTransform({ + schema, + transformers: [new ModelTransformer(), new DefaultValueTransformer(), new PrimaryKeyTransformer()], + }), + ).toThrow('The @default directive may not be applied to primaryKey fields.'); + }); + it('should validate enum values', async () => { const inputSchema = ` type Post @model { From 5faa1f65a3f5c1139b9f04f463b4d1f06b2118c7 Mon Sep 17 00:00:00 2001 From: Peter Vaiciulis Date: Thu, 12 Sep 2024 09:38:44 -0700 Subject: [PATCH 4/6] fix(graphql-default-value-transformer): @default may not be applied to primary key fields --- .../src/graphql-default-value-transformer.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) 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 5802deada6..41a0e8855b 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 @@ -72,10 +72,21 @@ const validateDefaultValueType = (ctx: TransformerSchemaVisitStepContextProvider } }; +const validateNotPrimaryKey = (field: FieldDefinitionNode): void => { + const isPrimaryKeyField = + field.directives!.find((dir) => dir.name.value === 'primaryKey') || + (getBaseType(field.type) === 'ID' && field.type.kind === Kind.NON_NULL_TYPE && field.name.value === 'id'); + + if (isPrimaryKeyField) { + throw new InvalidDirectiveError('The @default directive may not be applied to primaryKey fields.'); + } +}; + const validate = (ctx: TransformerSchemaVisitStepContextProvider, config: DefaultValueDirectiveConfiguration): void => { validateModelDirective(config); validateFieldType(ctx, config.field.type); validateDirectiveArguments(config.directive); + validateNotPrimaryKey(config.field); // Validate the default values only for the DynamoDB datasource. // For SQL, the database determines and sets the default value. We will not validate the value in transformers. From de7cc9e4d251c08aee3c4743bc1e6f6a1829d292 Mon Sep 17 00:00:00 2001 From: Peter Vaiciulis Date: Sun, 15 Sep 2024 21:42:49 -0700 Subject: [PATCH 5/6] test(graphql-default-value-transformer): @default cannot be used on composite key members --- ...fy-grapphql-default-value-transformer.test.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) 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 cac1fc9092..8e76bf9a07 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 @@ -249,6 +249,22 @@ describe('DefaultValueModelTransformer:', () => { ).toThrow('The @default directive may not be applied to primaryKey fields.'); }); + it('throws if @default is used on a composite key member', () => { + const schema = ` + type Project @model { + projectId: ID! @primaryKey(sortKeyFields: ["name"]) + name: String! @default(value: "Mustapha Mond") + } + `; + + expect(() => + testTransform({ + schema, + transformers: [new ModelTransformer(), new DefaultValueTransformer(), new PrimaryKeyTransformer()], + }), + ).toThrow('The @default directive may not be applied to composite key member fields.'); + }); + it('should validate enum values', async () => { const inputSchema = ` type Post @model { From e00975fad60a2e153263c0d132b491ccda88947c Mon Sep 17 00:00:00 2001 From: Peter Vaiciulis Date: Sun, 15 Sep 2024 22:09:31 -0700 Subject: [PATCH 6/6] fix(graphql-default-value-transformer): @default cannot be used on composite key members --- .../package.json | 3 ++- .../src/graphql-default-value-transformer.ts | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/amplify-graphql-default-value-transformer/package.json b/packages/amplify-graphql-default-value-transformer/package.json index 32bf38253d..9839b40476 100644 --- a/packages/amplify-graphql-default-value-transformer/package.json +++ b/packages/amplify-graphql-default-value-transformer/package.json @@ -75,7 +75,8 @@ "src/**/*.ts" ], "coveragePathIgnorePatterns": [ - "/__tests__/" + "/__tests__/", + "types.ts" ], "snapshotFormat": { "escapeString": true, 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 41a0e8855b..01fd4b424f 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 @@ -20,6 +20,7 @@ import { FieldDefinitionNode, InterfaceTypeDefinitionNode, Kind, + ListValueNode, ObjectTypeDefinitionNode, StringValueNode, TypeNode, @@ -82,11 +83,24 @@ const validateNotPrimaryKey = (field: FieldDefinitionNode): void => { } }; +const validateNotCompositeKeyMember = (config: DefaultValueDirectiveConfiguration): void => { + const objectDirectives = config.object.fields?.flatMap((f) => f.directives); + const primaryKeyDirective = objectDirectives?.find((dir) => dir?.name.value === 'primaryKey'); + if (primaryKeyDirective) { + const sortKeyFields = primaryKeyDirective.arguments?.find((arg) => arg.name.value === 'sortKeyFields')?.value as ListValueNode; + const sortKeys = sortKeyFields?.values as StringValueNode[]; + if (sortKeys?.some((sortKey) => sortKey.value === config.field.name.value)) { + throw new InvalidDirectiveError('The @default directive may not be applied to composite key member fields.'); + } + } +}; + const validate = (ctx: TransformerSchemaVisitStepContextProvider, config: DefaultValueDirectiveConfiguration): void => { validateModelDirective(config); validateFieldType(ctx, config.field.type); validateDirectiveArguments(config.directive); validateNotPrimaryKey(config.field); + validateNotCompositeKeyMember(config); // Validate the default values only for the DynamoDB datasource. // For SQL, the database determines and sets the default value. We will not validate the value in transformers.