From 74ef24aa9826d178970293bfbf9e8169674c4a3c Mon Sep 17 00:00:00 2001 From: Phillip Manwaring Date: Tue, 3 Oct 2023 15:27:39 -0400 Subject: [PATCH 1/3] add support for overriding the API logical id --- src/__tests__/api.test.ts | 30 ++++++++++++++++++++++++++++++ src/resources/Api.ts | 2 +- src/resources/Naming.ts | 4 ++-- src/types/plugin.ts | 1 + 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/__tests__/api.test.ts b/src/__tests__/api.test.ts index c8389f11..eb7a8bc2 100644 --- a/src/__tests__/api.test.ts +++ b/src/__tests__/api.test.ts @@ -30,6 +30,36 @@ describe('Api', () => { `); }); + describe('logicalId', () => { + const logicalIdOverride = 'Customlogicalid'; + it('should override the logical ID if provided', () => { + const api = new Api( + given.appSyncConfig({ + logicalId: logicalIdOverride, + }), + plugin, + ); + expect(api.compileEndpoint()).toMatchInlineSnapshot(` + Object { + "${logicalIdOverride}": Object { + "Properties": Object { + "AuthenticationType": "API_KEY", + "Name": "MyApi", + "Tags": Array [ + Object { + "Key": "stage", + "Value": "Dev", + }, + ], + "XrayEnabled": false, + }, + "Type": "AWS::AppSync::GraphQLApi", + }, + } + `); + }); + }); + it('should compile the Api Resource for a private endpoint', () => { const api = new Api( given.appSyncConfig({ diff --git a/src/resources/Api.ts b/src/resources/Api.ts index 95e41923..08ffbea9 100644 --- a/src/resources/Api.ts +++ b/src/resources/Api.ts @@ -68,7 +68,7 @@ export class Api { } compileEndpoint(): CfnResources { - const logicalId = this.naming.getApiLogicalId(); + const logicalId = this.naming.getApiLogicalId(this.config.logicalId); const endpointResource: CfnResource = { Type: 'AWS::AppSync::GraphQLApi', diff --git a/src/resources/Naming.ts b/src/resources/Naming.ts index d3b3cacb..781367fa 100644 --- a/src/resources/Naming.ts +++ b/src/resources/Naming.ts @@ -15,8 +15,8 @@ export class Naming { return this.getCfnName(name); } - getApiLogicalId() { - return this.getLogicalId(`GraphQlApi`); + getApiLogicalId(logicalIdOverride?: string) { + return this.getLogicalId(logicalIdOverride || `GraphQlApi`); } getSchemaLogicalId() { diff --git a/src/types/plugin.ts b/src/types/plugin.ts index ea56c8b5..372fa3e7 100644 --- a/src/types/plugin.ts +++ b/src/types/plugin.ts @@ -2,6 +2,7 @@ import { CfnWafRuleStatement, IntrinsicFunction } from './cloudFormation'; export type AppSyncConfig = { name: string; + logicalId?: string; schema: string[]; authentication: Auth; additionalAuthentications: Auth[]; From 967d75456b424309e500f5cf286ca3d02cd0d084 Mon Sep 17 00:00:00 2001 From: Phillip Manwaring Date: Tue, 3 Oct 2023 15:29:57 -0400 Subject: [PATCH 2/3] update docs with logicalid --- doc/general-config.md | 1 + src/types/plugin.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/general-config.md b/doc/general-config.md index e91972d3..4bd4a3e7 100644 --- a/doc/general-config.md +++ b/doc/general-config.md @@ -48,6 +48,7 @@ appSync: - `caching`: See [Cacing](caching.md) - `waf`: See [Web Application Firefall](WAF.md) - `logging`: See [Logging](#Logging) +- `logicalId`: Optional string. Used to override the generated CloudFormation Logical ID for the `AWS::AppSync::GraphQLApi` resource - `xrayEnabled`: Boolean. Enable or disable X-Ray tracing. - `visibility`: Optional. `GLOBAL` or `PRIVATE`. **Changing this value requires the replacement of the API.** - `tags`: A key-value pair for tagging this AppSync API diff --git a/src/types/plugin.ts b/src/types/plugin.ts index 372fa3e7..a4e8189c 100644 --- a/src/types/plugin.ts +++ b/src/types/plugin.ts @@ -2,7 +2,6 @@ import { CfnWafRuleStatement, IntrinsicFunction } from './cloudFormation'; export type AppSyncConfig = { name: string; - logicalId?: string; schema: string[]; authentication: Auth; additionalAuthentications: Auth[]; @@ -13,6 +12,7 @@ export type AppSyncConfig = { pipelineFunctions: Record; substitutions?: Substitutions; xrayEnabled?: boolean; + logicalId?: string; logging?: LoggingConfig; caching?: CachingConfig; waf?: WafConfig; From 4d271b723a3d4c8ca232dbe94fad30246e6b1afb Mon Sep 17 00:00:00 2001 From: Phillip Manwaring Date: Wed, 4 Oct 2023 16:54:13 -0400 Subject: [PATCH 3/3] switch LogicalId parameter to LogicalIdPrefix --- doc/general-config.md | 2 +- src/__tests__/api.test.ts | 6 +++--- src/index.ts | 2 +- src/resources/Api.ts | 4 ++-- src/resources/Naming.ts | 14 ++++++++------ src/types/plugin.ts | 2 +- src/validation.ts | 1 + 7 files changed, 17 insertions(+), 14 deletions(-) diff --git a/doc/general-config.md b/doc/general-config.md index 4bd4a3e7..9ef60380 100644 --- a/doc/general-config.md +++ b/doc/general-config.md @@ -48,7 +48,7 @@ appSync: - `caching`: See [Cacing](caching.md) - `waf`: See [Web Application Firefall](WAF.md) - `logging`: See [Logging](#Logging) -- `logicalId`: Optional string. Used to override the generated CloudFormation Logical ID for the `AWS::AppSync::GraphQLApi` resource +- `logicalIdPrefix`: Optional string. Used to prefix the generated CloudFormation Logical ID for the `AWS::AppSync::GraphQLApi` and related resources - `xrayEnabled`: Boolean. Enable or disable X-Ray tracing. - `visibility`: Optional. `GLOBAL` or `PRIVATE`. **Changing this value requires the replacement of the API.** - `tags`: A key-value pair for tagging this AppSync API diff --git a/src/__tests__/api.test.ts b/src/__tests__/api.test.ts index eb7a8bc2..84fd6600 100644 --- a/src/__tests__/api.test.ts +++ b/src/__tests__/api.test.ts @@ -31,17 +31,17 @@ describe('Api', () => { }); describe('logicalId', () => { - const logicalIdOverride = 'Customlogicalid'; + const logicalIdPrefix = 'Logicalidprefix'; it('should override the logical ID if provided', () => { const api = new Api( given.appSyncConfig({ - logicalId: logicalIdOverride, + logicalIdPrefix, }), plugin, ); expect(api.compileEndpoint()).toMatchInlineSnapshot(` Object { - "${logicalIdOverride}": Object { + "${logicalIdPrefix}GraphQlApi": Object { "Properties": Object { "AuthenticationType": "API_KEY", "Name": "MyApi", diff --git a/src/index.ts b/src/index.ts index 6d93c2ea..c9b4b7c5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -958,7 +958,7 @@ class ServerlessAppsyncPlugin { } } const config = getAppSyncConfig(appSync); - this.naming = new Naming(appSync.name); + this.naming = new Naming(config); this.api = new Api(config, this); } diff --git a/src/resources/Api.ts b/src/resources/Api.ts index 08ffbea9..eadb0184 100644 --- a/src/resources/Api.ts +++ b/src/resources/Api.ts @@ -34,7 +34,7 @@ export class Api { public config: AppSyncConfig, public plugin: ServerlessAppsyncPlugin, ) { - this.naming = new Naming(this.config.name); + this.naming = new Naming(this.config); } compile() { @@ -68,7 +68,7 @@ export class Api { } compileEndpoint(): CfnResources { - const logicalId = this.naming.getApiLogicalId(this.config.logicalId); + const logicalId = this.naming.getApiLogicalId(); const endpointResource: CfnResource = { Type: 'AWS::AppSync::GraphQLApi', diff --git a/src/resources/Naming.ts b/src/resources/Naming.ts index 781367fa..9b18057f 100644 --- a/src/resources/Naming.ts +++ b/src/resources/Naming.ts @@ -1,22 +1,24 @@ import { + AppSyncConfig, DataSourceConfig, PipelineFunctionConfig, ResolverConfig, } from '../types/plugin'; export class Naming { - constructor(private apiName: string) {} + constructor(private config: AppSyncConfig) {} getCfnName(name: string) { return name.replace(/[^a-zA-Z0-9]/g, ''); } getLogicalId(name: string): string { - return this.getCfnName(name); + const logicalIdPrefix = this.config.logicalIdPrefix || ''; + return this.getCfnName(`${logicalIdPrefix}${name}`); } - getApiLogicalId(logicalIdOverride?: string) { - return this.getLogicalId(logicalIdOverride || `GraphQlApi`); + getApiLogicalId() { + return this.getLogicalId(`GraphQlApi`); } getSchemaLogicalId() { @@ -66,7 +68,7 @@ export class Naming { // Warning: breaking change. // api name added getDataSourceLogicalId(name: string) { - return `GraphQlDs${this.getLogicalId(name)}`; + return this.getLogicalId(`GraphQlDs${name}`); } getDataSourceRoleLogicalId(name: string) { @@ -104,6 +106,6 @@ export class Naming { } getAuthenticationEmbeddedLamdbaName() { - return `${this.apiName}Authorizer`; + return `${this.config.name}Authorizer`; } } diff --git a/src/types/plugin.ts b/src/types/plugin.ts index a4e8189c..1b528a11 100644 --- a/src/types/plugin.ts +++ b/src/types/plugin.ts @@ -12,7 +12,7 @@ export type AppSyncConfig = { pipelineFunctions: Record; substitutions?: Substitutions; xrayEnabled?: boolean; - logicalId?: string; + logicalIdPrefix?: string; logging?: LoggingConfig; caching?: CachingConfig; waf?: WafConfig; diff --git a/src/validation.ts b/src/validation.ts index a1870492..0e770fc8 100644 --- a/src/validation.ts +++ b/src/validation.ts @@ -677,6 +677,7 @@ export const appSyncSchema = { 'when using CloudFormation, you must provide either certificateArn or hostedZoneId.', }, }, + logicalIdPrefix: { type: 'string' }, xrayEnabled: { type: 'boolean' }, visibility: { type: 'string',