From e91f5fa8bccd4a6ed1a0e2230c8f445244529c98 Mon Sep 17 00:00:00 2001 From: Patryk Milewski Date: Thu, 30 Apr 2026 15:17:03 +0200 Subject: [PATCH] fix(schema): allow @canonical, @hidden, @renamed on FIELD_DEFINITION The bundled directive declarations restricted @canonical, @hidden, and @renamed to OBJECT only, causing local SDL validation to reject schemas that apply them to fields. AWS's Merged API spec and best-practices documentation explicitly support FIELD_DEFINITION usage, e.g.: rating: Int @canonical authorId: ID! @hidden getMessage(id: ID!): Message @renamed Widen the location set to OBJECT | FIELD_DEFINITION. Note: AWS's @renamed directive also takes a `to: String!` argument (e.g. `@renamed(to: "newName")`). Adding it to this stub would break existing users who write `@renamed` without an argument, so it is left out of this change. See PR description for details. Refs: https://aws.amazon.com/blogs/mobile/aws-appsync-merged-apis-best-practices-part-2-schema-composition/ --- .../schemas/merge-directives/schema.graphql | 20 +++++++++++++++++++ src/__tests__/schema.test.ts | 12 +++++++++++ src/resources/Schema.ts | 6 +++--- 3 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 src/__tests__/fixtures/schemas/merge-directives/schema.graphql diff --git a/src/__tests__/fixtures/schemas/merge-directives/schema.graphql b/src/__tests__/fixtures/schemas/merge-directives/schema.graphql new file mode 100644 index 00000000..01450f41 --- /dev/null +++ b/src/__tests__/fixtures/schemas/merge-directives/schema.graphql @@ -0,0 +1,20 @@ +type Query { + getUser(id: ID!): User! @canonical + internalUser(id: ID!): User! @hidden + legacyUser(id: ID!): User! @renamed +} + +type User @canonical { + id: ID! + name: String! @canonical + email: String! @hidden + oldField: String @renamed +} + +type Post @hidden { + id: ID! +} + +type Comment @renamed { + id: ID! +} diff --git a/src/__tests__/schema.test.ts b/src/__tests__/schema.test.ts index deae80fe..5f7d58c3 100644 --- a/src/__tests__/schema.test.ts +++ b/src/__tests__/schema.test.ts @@ -153,6 +153,18 @@ describe('schema', () => { `); }); + it('should accept merged-API directives on OBJECT and FIELD_DEFINITION', () => { + const api = new Api( + given.appSyncConfig({ + schema: [ + 'src/__tests__/fixtures/schemas/merge-directives/schema.graphql', + ], + }), + plugin, + ); + expect(() => api.compileSchema()).not.toThrow(); + }); + it('should return single files schemas as-is', () => { const api = new Api(given.appSyncConfig(), plugin); const schema = new Schema(api, [ diff --git a/src/resources/Schema.ts b/src/resources/Schema.ts index e4a24ebe..2dbb88ec 100644 --- a/src/resources/Schema.ts +++ b/src/resources/Schema.ts @@ -18,9 +18,9 @@ directive @aws_cognito_user_pools( cognito_groups: [String] ) on FIELD_DEFINITION | OBJECT directive @aws_subscribe(mutations: [String]) on FIELD_DEFINITION -directive @canonical on OBJECT -directive @hidden on OBJECT -directive @renamed on OBJECT +directive @canonical on OBJECT | FIELD_DEFINITION +directive @hidden on OBJECT | FIELD_DEFINITION +directive @renamed on OBJECT | FIELD_DEFINITION scalar AWSDate scalar AWSTime scalar AWSDateTime