diff --git a/doc/general-config.md b/doc/general-config.md index ff6a19d2..8cb91965 100644 --- a/doc/general-config.md +++ b/doc/general-config.md @@ -44,7 +44,8 @@ appSync: - `dataSources`: See [DataSources](dataSources.md) - `resolvers`: See [Resolvers](resolvers.md) - `pipelineFunctions`: See [Pipeline functions](pipeline-functions.md) -- `substitutions`: See [Substitutions](substitutions.md) +- `substitutions`: See [Substitutions](substitutions.md). Deprecated: Use environment variables. +- `environment`: A list of environment variables for the API. See [Official Documentation](https://docs.aws.amazon.com/appsync/latest/devguide/environmental-variables.html) - `caching`: See [Cacing](caching.md) - `waf`: See [Web Application Firefall](WAF.md) - `logging`: See [Logging](#Logging) diff --git a/doc/resolvers.md b/doc/resolvers.md index 7e3d7146..48de245b 100644 --- a/doc/resolvers.md +++ b/doc/resolvers.md @@ -29,7 +29,7 @@ appSync: - `code`: The path of the JavaScript resolver handler file, relative to `serverless.yml`. If not specified, a [minimalistic default](#javascript-vs-vtl) is used. - `request`: The path to the VTL request mapping template file, relative to `serverless.yml`. - `response`: The path to the VTL response mapping template file, relative to `serverless.yml`. -- `substitutions`: See [Variable Substitutions](substitutions.md) +- `substitutions`: See [Variable Substitutions](substitutions.md). Deprecated: Use [environment variables](./general-config.md) instead. - `caching`: [See below](#Caching) - `sync`: [See SyncConfig](syncConfig.md) diff --git a/doc/substitutions.md b/doc/substitutions.md index 794953ba..f43bc53d 100644 --- a/doc/substitutions.md +++ b/doc/substitutions.md @@ -1,3 +1,5 @@ +> ⚠️ Substitutions are deprecated. Use [Environment Variables](./general-config.md) instead. + # Substitutions `Substitutions` is a feature that allows you to replace some variables in your VTL mapping templates or JS resolvers with dynamic values. @@ -30,27 +32,29 @@ appSync:
VTL mapping template - ```vtl - { - "version" : "2018-05-29", - "operation" : "BatchPutItem", - "tables" : { - "${postsTable}": [...] - } - } - ``` +```vtl +{ + "version" : "2018-05-29", + "operation" : "BatchPutItem", + "tables" : { + "${postsTable}": [...] + } +} +``` +
JS Resolvers - - ```js - const tableName = '#postsTable#'; - return { - operation: "BatchGetItem", - tables: { - [tableName]: { keys }, - }, - }; - ``` + +```js +const tableName = '#postsTable#'; +return { + operation: 'BatchGetItem', + tables: { + [tableName]: { keys }, + }, +}; +``` +
diff --git a/src/__tests__/__snapshots__/api.test.ts.snap b/src/__tests__/__snapshots__/api.test.ts.snap index 37d43140..000e5ce5 100644 --- a/src/__tests__/__snapshots__/api.test.ts.snap +++ b/src/__tests__/__snapshots__/api.test.ts.snap @@ -20,6 +20,7 @@ Object { }, ], "AuthenticationType": "API_KEY", + "EnvironmentVariables": undefined, "Name": "MyApi", "Tags": Array [ Object { @@ -47,6 +48,7 @@ Object { "GraphQlApi": Object { "Properties": Object { "AuthenticationType": "AWS_LAMBDA", + "EnvironmentVariables": undefined, "LambdaAuthorizerConfig": Object { "AuthorizerResultTtlInSeconds": undefined, "AuthorizerUri": Object { diff --git a/src/__tests__/api.test.ts b/src/__tests__/api.test.ts index 56ea77f0..87405c9d 100644 --- a/src/__tests__/api.test.ts +++ b/src/__tests__/api.test.ts @@ -15,6 +15,7 @@ describe('Api', () => { "GraphQlApi": Object { "Properties": Object { "AuthenticationType": "API_KEY", + "EnvironmentVariables": undefined, "Name": "MyApi", "Tags": Array [ Object { @@ -42,6 +43,7 @@ describe('Api', () => { "GraphQlApi": Object { "Properties": Object { "AuthenticationType": "API_KEY", + "EnvironmentVariables": undefined, "Name": "MyApi", "Tags": Array [ Object { @@ -72,6 +74,7 @@ describe('Api', () => { "GraphQlApi": Object { "Properties": Object { "AuthenticationType": "API_KEY", + "EnvironmentVariables": undefined, "IntrospectionConfig": "DISABLED", "Name": "MyApi", "QueryDepthLimit": 10, @@ -90,6 +93,44 @@ describe('Api', () => { `); }); + it('should compile the Api Resource with Environments', () => { + const api = new Api( + given.appSyncConfig({ + environment: { + TABLE_NAME: 'MyTable', + OTHER_TABLE: { + Ref: 'OtherTable', + }, + }, + }), + plugin, + ); + expect(api.compileEndpoint()).toMatchInlineSnapshot(` + Object { + "GraphQlApi": Object { + "Properties": Object { + "AuthenticationType": "API_KEY", + "EnvironmentVariables": Object { + "OTHER_TABLE": Object { + "Ref": "OtherTable", + }, + "TABLE_NAME": "MyTable", + }, + "Name": "MyApi", + "Tags": Array [ + Object { + "Key": "stage", + "Value": "Dev", + }, + ], + "XrayEnabled": false, + }, + "Type": "AWS::AppSync::GraphQLApi", + }, + } + `); + }); + it('should compile the Api Resource with logs enabled', () => { const api = new Api( given.appSyncConfig({ @@ -106,6 +147,7 @@ describe('Api', () => { "GraphQlApi": Object { "Properties": Object { "AuthenticationType": "API_KEY", + "EnvironmentVariables": undefined, "LogConfig": Object { "CloudWatchLogsRoleArn": Object { "Fn::GetAtt": Array [ @@ -215,6 +257,7 @@ describe('Api', () => { }, ], "AuthenticationType": "AMAZON_COGNITO_USER_POOLS", + "EnvironmentVariables": undefined, "Name": "MyApi", "Tags": Array [ Object { diff --git a/src/__tests__/validation/__snapshots__/base.test.ts.snap b/src/__tests__/validation/__snapshots__/base.test.ts.snap index 5ee850ed..b2b9d274 100644 --- a/src/__tests__/validation/__snapshots__/base.test.ts.snap +++ b/src/__tests__/validation/__snapshots__/base.test.ts.snap @@ -60,6 +60,7 @@ exports[`Valdiation should validate 1`] = ` /introspection: must be boolean /queryDepthLimit: must be integer /resolverCountLimit: must be integer +/environment: must be a valid environment definition /esbuild: must be an esbuild config object or false" `; diff --git a/src/__tests__/validation/base.test.ts b/src/__tests__/validation/base.test.ts index e4d1f789..5824bc2d 100644 --- a/src/__tests__/validation/base.test.ts +++ b/src/__tests__/validation/base.test.ts @@ -12,6 +12,10 @@ describe('Valdiation', () => { queryDepthLimit: 10, resolverCountLimit: 10, xrayEnabled: true, + environment: { + MY_TABLE: 'my-table', + MY_OTHER_TABLE: { Ref: 'MyOtherTable' }, + }, tags: { foo: 'bar', }, @@ -32,6 +36,7 @@ describe('Valdiation', () => { xrayEnabled: 'BAR', unknownPorp: 'foo', esbuild: 'bad', + environment: 'Bad', }); }).toThrowErrorMatchingSnapshot(); diff --git a/src/resources/Api.ts b/src/resources/Api.ts index 4a451b0a..92a9663a 100644 --- a/src/resources/Api.ts +++ b/src/resources/Api.ts @@ -76,6 +76,7 @@ export class Api { Name: this.config.name, XrayEnabled: this.config.xrayEnabled || false, Tags: this.getTagsConfig(), + EnvironmentVariables: this.config.environment, }, }; diff --git a/src/types/common.ts b/src/types/common.ts index b2815632..cc8157b9 100644 --- a/src/types/common.ts +++ b/src/types/common.ts @@ -128,6 +128,7 @@ export type SyncConfig = { } & LambdaConfig; export type Substitutions = Record; +export type EnvironmentVariables = Record; export type DsDynamoDBConfig = { type: 'AMAZON_DYNAMODB'; diff --git a/src/types/index.ts b/src/types/index.ts index 8105630b..e52f8388 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -15,6 +15,7 @@ import { DsOpenSearchConfig, DsRelationalDbConfig, SyncConfig, + EnvironmentVariables, } from './common'; export * from './common'; @@ -33,6 +34,7 @@ export type AppSyncConfig = { | Record[] | Record; substitutions?: Substitutions; + environment?: EnvironmentVariables; xrayEnabled?: boolean; logging?: LoggingConfig; caching?: CachingConfig; diff --git a/src/types/plugin.ts b/src/types/plugin.ts index c6f70166..0b8bf8f0 100644 --- a/src/types/plugin.ts +++ b/src/types/plugin.ts @@ -15,6 +15,7 @@ import { DsEventBridgeConfig, DsNone, Substitutions, + EnvironmentVariables, } from './common'; export * from './common'; @@ -29,6 +30,7 @@ export type AppSyncConfig = { resolvers: Record; pipelineFunctions: Record; substitutions?: Substitutions; + environment?: EnvironmentVariables; xrayEnabled?: boolean; logging?: LoggingConfig; caching?: CachingConfig; diff --git a/src/validation.ts b/src/validation.ts index 447787e0..4cc292e0 100644 --- a/src/validation.ts +++ b/src/validation.ts @@ -255,6 +255,14 @@ export const appSyncSchema = { required: [], errorMessage: 'must be a valid substitutions definition', }, + environment: { + type: 'object', + additionalProperties: { + $ref: '#/definitions/stringOrIntrinsicFunction', + }, + required: [], + errorMessage: 'must be a valid environment definition', + }, dataSource: { if: { type: 'object' }, then: { $ref: '#/definitions/dataSourceConfig' }, @@ -687,6 +695,7 @@ export const appSyncSchema = { queryDepthLimit: { type: 'integer', minimum: 1, maximum: 75 }, resolverCountLimit: { type: 'integer', minimum: 1, maximum: 1000 }, substitutions: { $ref: '#/definitions/substitutions' }, + environment: { $ref: '#/definitions/environment' }, waf: { type: 'object', properties: {