diff --git a/packages/constructs/edge-api/src/dev-edge-api.ts b/packages/constructs/edge-api/src/dev-edge-api.ts index 84f86ab..afa8b39 100644 --- a/packages/constructs/edge-api/src/dev-edge-api.ts +++ b/packages/constructs/edge-api/src/dev-edge-api.ts @@ -46,10 +46,10 @@ export class DevEdgeAPI extends Construct { }, }) - this.addEndpoint({ - ...props.defaultEndpoint, - pathPattern: '/*', - } as Endpoint) + if (props.defaultEndpoint.pathPattern !== '/*') { + throw new Error('defaultEndpoint pathPattern is not "/*"') + } + this.addEndpoint(props.defaultEndpoint) } private generateParameterMapping( @@ -129,8 +129,7 @@ export class DevEdgeAPI extends Construct { methods, }) } - } - if (endpointIsLambdaEndpoint(endpoint)) { + } else if (endpointIsLambdaEndpoint(endpoint)) { const { pathPattern, lambdaFunction } = endpoint const methods = endpoint.methods ?? [HttpMethod.ANY] this.api.addRoutes({ @@ -140,8 +139,7 @@ export class DevEdgeAPI extends Construct { }), methods, }) - } - if (endpointIsFrontendEndpoint(endpoint)) { + } else if (endpointIsFrontendEndpoint(endpoint)) { const { pathPattern, bucket } = endpoint const integration = new HttpLambdaIntegration(pathPattern + '-integration', this.getRedirector(), { parameterMapping: this.generateParameterMapping({ destination: bucket.bucketWebsiteUrl }), @@ -164,8 +162,7 @@ export class DevEdgeAPI extends Construct { ), methods: [HttpMethod.GET], }) - } - if (endpointIsRedirectionEndpoint(endpoint)) { + } else if (endpointIsRedirectionEndpoint(endpoint)) { const { pathPattern, destination } = endpoint const integration = new HttpLambdaIntegration(pathPattern + '-integration', this.getRedirector(), { parameterMapping: this.generateParameterMapping({ destination: this.pickDestination(destination) }), @@ -183,6 +180,8 @@ export class DevEdgeAPI extends Construct { methods: [HttpMethod.GET], }) } + } else { + throw new Error('unhandled endpoint type: ' + typeof endpoint + ' - ' + JSON.stringify(endpoint)) } } } diff --git a/packages/constructs/edge-api/src/types.ts b/packages/constructs/edge-api/src/types.ts index 955fb19..a3357e3 100644 --- a/packages/constructs/edge-api/src/types.ts +++ b/packages/constructs/edge-api/src/types.ts @@ -214,7 +214,7 @@ export interface EdgeAPIProps { readonly devMode?: boolean readonly domains: string[] readonly certificate: ICertificate - readonly defaultEndpoint: IBaseEndpoint + readonly defaultEndpoint: Endpoint readonly webAclId?: string readonly defaultResponseHeaderOverrides?: ResponseHeaderOverrides } diff --git a/packages/constructs/edge-api/tests/construct.test.ts b/packages/constructs/edge-api/tests/construct.test.ts index 53734ec..61dbddf 100644 --- a/packages/constructs/edge-api/tests/construct.test.ts +++ b/packages/constructs/edge-api/tests/construct.test.ts @@ -1,13 +1,19 @@ import { Template } from 'aws-cdk-lib/assertions' import * as cdk from 'aws-cdk-lib' -import { EdgeAPI } from '../src' +import { + EdgeAPI, + EdgeAPIProps, + FrontendEndpoint, + HttpMethod, + LambdaEndpoint, + RedirectionEndpoint, + ProxyEndpoint, + EdgeAPILambda, +} from '../src' import { Certificate } from 'aws-cdk-lib/aws-certificatemanager' -import { EdgeAPIProps, FrontendEndpoint, HttpMethod, LambdaEndpoint } from '../src/types' import { Bucket } from 'aws-cdk-lib/aws-s3' -import { EdgeAPILambda } from '../src/edge-api-lambda' import { Code, Runtime } from 'aws-cdk-lib/aws-lambda' import { CloudFrontRequest, CloudFrontRequestEvent } from 'aws-lambda' -import { ProxyEndpoint } from '../dist' const testGeneratedLambda = async (code: string, req: CloudFrontRequestEvent): Promise => { const handler = eval(`${code} handler`) @@ -27,9 +33,10 @@ const synth = (region: string = 'us-east-1', props: Partial = {}) const api = new EdgeAPI(stack, 'api', { certificate, domains: ['example.org'], - defaultEndpoint: { + defaultEndpoint: new ProxyEndpoint({ destination: 'example.com', - }, + pathPattern: '/*', + }), ...props, }) const template = () => Template.fromStack(stack) @@ -61,9 +68,10 @@ describe('edge-api', () => { new EdgeAPI(stack, 'api', { certificate, domains: ['example.org'], - defaultEndpoint: { + defaultEndpoint: new ProxyEndpoint({ destination: 'example.com', - }, + pathPattern: '/*', + }), }), ).toThrowError('stack region must be explicitly specified') }) @@ -82,9 +90,10 @@ describe('edge-api', () => { new EdgeAPI(stack, 'api', { certificate, domains: ['example.org'], - defaultEndpoint: { + defaultEndpoint: new ProxyEndpoint({ destination: 'example.com', - }, + pathPattern: '/*', + }), }), ).toThrowError('deploying non-devMode EdgeAPI to a region other than us-east-1 is not yet supported, sorry') }) @@ -600,26 +609,28 @@ describe('edge-api', () => { idpProviderName: 'b', }, } - api.addEndpoint({ - pathPattern: '/google', - destination, - customMiddlewares: [ - // @ts-expect-error - (req, mapping) => { - if (req.uri === '/authorize' || req.uri === '/login') { - if (typeof mapping !== 'string') { - const ip = `identity_provider=${mapping.idpProviderName}` - if (req.querystring.length) { - req.querystring = `${ip}&${req.querystring}` - } else { - req.querystring = ip + api.addEndpoint( + new ProxyEndpoint({ + pathPattern: '/google', + destination, + customMiddlewares: [ + // @ts-expect-error + (req, mapping) => { + if (req.uri === '/authorize' || req.uri === '/login') { + if (typeof mapping !== 'string') { + const ip = `identity_provider=${mapping.idpProviderName}` + if (req.querystring.length) { + req.querystring = `${ip}&${req.querystring}` + } else { + req.querystring = ip + } } + req.uri = '/oauth2/authorize' } - req.uri = '/oauth2/authorize' - } - }, - ], - }) + }, + ], + }), + ) const result = template() result.hasResourceProperties('AWS::CloudFront::Distribution', { DistributionConfig: { @@ -706,11 +717,13 @@ describe('edge-api', () => { test('add a redirection endpoint', () => { const { api, template } = synth('us-east-1', {}) - api.addEndpoint({ - pathPattern: '/redirect-me', - destination: 'google.com', - redirect: true, - }) + api.addEndpoint( + new RedirectionEndpoint({ + pathPattern: '/redirect-me', + destination: 'google.com', + redirect: true, + }), + ) const result = template() result.hasResourceProperties('AWS::CloudFront::Distribution', { @@ -916,10 +929,11 @@ describe('edge-api', () => { test('add a redirection endpoint - root', () => { const { template } = synth('us-east-1', { devMode: true, - defaultEndpoint: { + defaultEndpoint: new RedirectionEndpoint({ redirect: true, destination: 'google.com', - }, + pathPattern: '/*', + }), }) const result = template() result.hasResourceProperties('AWS::ApiGatewayV2::Route', { @@ -1058,11 +1072,13 @@ describe('edge-api', () => { }) test('add a redirect endpoint', () => { const { api, template } = synth('us-east-1', { devMode: true }) - api.addEndpoint({ - pathPattern: '/redirect-me', - destination: 'google.com', - redirect: true, - }) + api.addEndpoint( + new RedirectionEndpoint({ + pathPattern: '/redirect-me', + destination: 'google.com', + redirect: true, + }), + ) const result = template() result.hasResourceProperties('AWS::ApiGatewayV2::Route', { ApiId: {