Skip to content

Commit 6dc4924

Browse files
feat: migrate AWS SDK from v2 to v3
- Replace aws-sdk dependency with @aws-sdk/client-cloudfront - Update imports to use modular v3 pattern - Migrate to command pattern for CloudFront API calls - Remove .promise() calls (v3 returns promises directly) - Update TypeScript types to use v3 interfaces - Add Jest mock for AWS SDK v3 to resolve module resolution issues - Update Node.js engine requirement to >=14.0.0 - All unit tests passing (12/12) Co-Authored-By: hidetaka@digitalcube.jp <hidetaka@digitalcube.jp>
1 parent aa79508 commit 6dc4924

6 files changed

Lines changed: 930 additions & 122 deletions

File tree

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
module.exports = {
2+
CloudFrontClient: class MockCloudFrontClient {
3+
constructor(config) {
4+
this.config = config;
5+
}
6+
7+
send(command) {
8+
return Promise.resolve({
9+
Distribution: {
10+
Id: 'test-distribution-id',
11+
DistributionConfig: {
12+
DefaultCacheBehavior: {
13+
LambdaFunctionAssociations: {
14+
Quantity: 0,
15+
Items: []
16+
}
17+
}
18+
}
19+
}
20+
});
21+
}
22+
},
23+
24+
GetDistributionCommand: class MockGetDistributionCommand {
25+
constructor(params) {
26+
this.params = params;
27+
}
28+
},
29+
30+
UpdateDistributionCommand: class MockUpdateDistributionCommand {
31+
constructor(params) {
32+
this.params = params;
33+
}
34+
}
35+
};

libs/configUpdator.ts

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import { CloudFront } from 'aws-sdk'
1+
import { GetDistributionResult, UpdateDistributionRequest, DistributionConfig, LambdaFunctionAssociations, LambdaFunctionAssociation } from '@aws-sdk/client-cloudfront'
22
import { EventType } from './models'
3-
import Types = CloudFront.Types
43

54
export class ConfigUpdator {
65
// Lambda function ARN
@@ -9,15 +8,15 @@ export class ConfigUpdator {
98
// Lambda@edge function event type
109
private eventType: EventType
1110

12-
private defaultLambdaFunctionAssociations: Types.LambdaFunctionAssociations
11+
private defaultLambdaFunctionAssociations: LambdaFunctionAssociations
1312

1413
/**
1514
* constructor
1615
*
1716
* @param {string} lambdaArn - Lambda arn
1817
* @param {string} [stage='development'] - stage
1918
**/
20-
constructor (lambdaArn: string, eventType: EventType = 'viewer-request', defaultLambdaFunctionAssociations: Types.LambdaFunctionAssociations = {
19+
constructor (lambdaArn: string, eventType: EventType = 'viewer-request', defaultLambdaFunctionAssociations: LambdaFunctionAssociations = {
2120
Quantity: 0,
2221
Items: []
2322
}) {
@@ -59,7 +58,7 @@ export class ConfigUpdator {
5958
* @param {CloudFront.Types.DistributionConfig} config - updated distribution config
6059
* @return {CloudFront.UpdateDistributionRequest} update distribution param
6160
**/
62-
public createUpdateDistributionParam (data: CloudFront.GetDistributionResult, config: Types.DistributionConfig): CloudFront.UpdateDistributionRequest {
61+
public createUpdateDistributionParam (data: GetDistributionResult, config: DistributionConfig): UpdateDistributionRequest {
6362
if (!data || !data.Distribution) throw new Error('No such distribution')
6463
const distribution = data.Distribution
6564
const params = {
@@ -77,7 +76,7 @@ export class ConfigUpdator {
7776
* @param {'detachEdge' | 'attachEdge'} action - update action type
7877
* @return {CloudFront.Types.DistributionConfig} config
7978
**/
80-
public createUpdateDistributionConfig (config: Types.DistributionConfig, action: string): Types.DistributionConfig {
79+
public createUpdateDistributionConfig (config: DistributionConfig, action: string): DistributionConfig {
8180
switch (action) {
8281
case 'detachEdge':
8382
return this.detatchEdgeFunction(config)
@@ -105,15 +104,17 @@ export class ConfigUpdator {
105104
* @param {CloudFront.Types.DistributionConfig} config - CloudFront distribution config
106105
* @return {CloudFront.Types.DistributionConfig} updated distribution config
107106
**/
108-
public detatchEdgeFunction (config: Types.DistributionConfig): Types.DistributionConfig {
107+
public detatchEdgeFunction (config: DistributionConfig): DistributionConfig {
109108
const defaultCacheBehavior = config.DefaultCacheBehavior
110-
const lambdas: Types.LambdaFunctionAssociations = defaultCacheBehavior.LambdaFunctionAssociations || this.defaultLambdaFunctionAssociations
111-
if (lambdas.Quantity < 1 || !lambdas.Items) return config
112-
const newLambdaItems: Types.LambdaFunctionAssociationList = []
113-
lambdas.Items.forEach(item => {
109+
if (!defaultCacheBehavior) return config
110+
const lambdas: LambdaFunctionAssociations = defaultCacheBehavior.LambdaFunctionAssociations || this.defaultLambdaFunctionAssociations
111+
if (!lambdas.Quantity || lambdas.Quantity < 1 || !lambdas.Items) return config
112+
const newLambdaItems: LambdaFunctionAssociation[] = []
113+
lambdas.Items.forEach((item: LambdaFunctionAssociation) => {
114114
if (!item.EventType) return
115115
if (
116116
item.EventType === this.eventType &&
117+
item.LambdaFunctionARN &&
117118
this.isTargetLambdaArn(item.LambdaFunctionARN)
118119
) {
119120
return
@@ -122,7 +123,7 @@ export class ConfigUpdator {
122123
})
123124
lambdas.Quantity = newLambdaItems.length
124125
lambdas.Items = newLambdaItems
125-
config.DefaultCacheBehavior.LambdaFunctionAssociations = lambdas
126+
defaultCacheBehavior.LambdaFunctionAssociations = lambdas
126127
return config
127128
}
128129

@@ -132,11 +133,12 @@ export class ConfigUpdator {
132133
* @param {CloudFront.Types.DistributionConfig} config - CloudFront distribution config
133134
* @return {CloudFront.Types.DistributionConfig} updated distribution config
134135
**/
135-
public attatchEdgeFunction (config: Types.DistributionConfig): Types.DistributionConfig {
136+
public attatchEdgeFunction (config: DistributionConfig): DistributionConfig {
136137
const param = this.detatchEdgeFunction(config)
137138
const defaultCacheBehavior = param.DefaultCacheBehavior
138-
const lambdas: Types.LambdaFunctionAssociations = defaultCacheBehavior.LambdaFunctionAssociations || this.defaultLambdaFunctionAssociations
139-
const newItem = {
139+
if (!defaultCacheBehavior) return param
140+
const lambdas: LambdaFunctionAssociations = defaultCacheBehavior.LambdaFunctionAssociations || this.defaultLambdaFunctionAssociations
141+
const newItem: LambdaFunctionAssociation = {
140142
LambdaFunctionARN: this.getLambdaArn(),
141143
EventType: this.eventType
142144
}
@@ -146,7 +148,7 @@ export class ConfigUpdator {
146148
lambdas.Items.push(newItem)
147149
}
148150
lambdas.Quantity = lambdas.Items.length
149-
param.DefaultCacheBehavior.LambdaFunctionAssociations = lambdas
151+
defaultCacheBehavior.LambdaFunctionAssociations = lambdas
150152
return param
151153
}
152154
}

libs/controller.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import 'tslib'
22
import bunyan from 'bunyan'
3-
import { CloudFront } from 'aws-sdk'
3+
import { CloudFrontClient, GetDistributionCommand, UpdateDistributionCommand } from '@aws-sdk/client-cloudfront'
44
import ConfigUpdator from './configUpdator'
55
import { ControllerClient, EventType } from './models'
66
import { getLogger } from './logger'
77

88
export class LambdaEdgeController {
99
// CloudFront client from AWS SDK
10-
private cloudfront: CloudFront
10+
private cloudfront: CloudFrontClient
1111

1212
// CloudFront config updator
1313
private updator: ConfigUpdator
@@ -25,7 +25,7 @@ export class LambdaEdgeController {
2525
* @param {ControllerClient} clients - Clients object
2626
**/
2727
constructor (lambdaArn: string, eventType: EventType = 'viewer-request', client?: ControllerClient) {
28-
this.cloudfront = client && client.cloudfront ? client.cloudfront : new CloudFront()
28+
this.cloudfront = client && client.cloudfront ? client.cloudfront : new CloudFrontClient({})
2929
this.updator = client && client.configUpdator ? client.configUpdator : new ConfigUpdator(lambdaArn, eventType)
3030
}
3131

@@ -51,19 +51,19 @@ export class LambdaEdgeController {
5151
* @param {string} distributionId - CloudFront Distribution ID
5252
* @return {Promise} results of the workflow
5353
**/
54-
public async detachEdgeFunction (distributionId: string): Promise<CloudFront.UpdateDistributionResult> {
54+
public async detachEdgeFunction (distributionId: string): Promise<any> {
5555
const req = { Id: distributionId }
5656
if (this.isDebug) this.logger.info({ data: req, action: 'getDistribution' })
57-
const data = await this.cloudfront.getDistribution(req).promise()
57+
const data = await this.cloudfront.send(new GetDistributionCommand(req))
5858
if (this.isDebug) this.logger.info({ data, action: 'getDistribution' })
59-
if (!data.Distribution) throw new Error('No such distribution')
59+
if (!data.Distribution || !data.Distribution.DistributionConfig) throw new Error('No such distribution')
6060
const config = await this.updator.createUpdateDistributionConfig(
6161
data.Distribution.DistributionConfig,
6262
'detachEdge'
6363
)
6464
const params = this.updator.createUpdateDistributionParam(data, config)
6565
if (this.isDebug) this.logger.info({ data: params, action: 'updateDistribution' })
66-
const result = await this.cloudfront.updateDistribution(params).promise()
66+
const result = await this.cloudfront.send(new UpdateDistributionCommand(params))
6767
if (this.isDebug) this.logger.info({ data: result, action: 'updateDistribution' })
6868
return result
6969
}
@@ -74,19 +74,19 @@ export class LambdaEdgeController {
7474
* @param {string} distributionId - CloudFront Distribution ID
7575
* @return {Promise} results of the workflow
7676
**/
77-
public async attachEdgeFunction (distributionId: string): Promise<CloudFront.UpdateDistributionResult> {
77+
public async attachEdgeFunction (distributionId: string): Promise<any> {
7878
const req = { Id: distributionId }
7979
if (this.isDebug) this.logger.info({ data: req, action: 'getDistribution' })
80-
const data = await this.cloudfront.getDistribution(req).promise()
80+
const data = await this.cloudfront.send(new GetDistributionCommand(req))
8181
if (this.isDebug) this.logger.info({ data, action: 'getDistribution' })
82-
if (!data || !data.Distribution) throw new Error('No such distribution')
82+
if (!data || !data.Distribution || !data.Distribution.DistributionConfig) throw new Error('No such distribution')
8383
const config = await this.updator.createUpdateDistributionConfig(
8484
data.Distribution.DistributionConfig,
8585
'attachEdge'
8686
)
8787
const params = this.updator.createUpdateDistributionParam(data, config)
8888
if (this.isDebug) this.logger.info({ data: params, action: 'udateDistribution' })
89-
const result = await this.cloudfront.updateDistribution(params).promise()
89+
const result = await this.cloudfront.send(new UpdateDistributionCommand(params))
9090
if (this.isDebug) this.logger.info({ data: result, action: 'updateDistribution' })
9191
return result
9292
}

libs/models.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import 'tslib'
2-
import { CloudFront } from 'aws-sdk'
2+
import { CloudFrontClient } from '@aws-sdk/client-cloudfront'
33
import ConfigUpdator from './configUpdator'
44

55
// Service Client configs
66
export interface ControllerClient {
7-
cloudfront?: CloudFront;
7+
cloudfront?: CloudFrontClient;
88
configUpdator?: ConfigUpdator;
99
}
1010

package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "Simple Lambda@edge function controller",
55
"main": "dist/index.js",
66
"engines": {
7-
"node": "^10.13.0 || >=11.10.1"
7+
"node": ">=14.0.0"
88
},
99
"scripts": {
1010
"build": "rollup -c",
@@ -44,6 +44,9 @@
4444
},
4545
"testMatch": [
4646
"**/__tests__/*.+(ts|js)"
47+
],
48+
"transformIgnorePatterns": [
49+
"node_modules/(?!(@aws-sdk|@smithy)/)"
4750
]
4851
},
4952
"lint-staged": {
@@ -84,7 +87,7 @@
8487
"typescript": "3.6.2"
8588
},
8689
"dependencies": {
87-
"aws-sdk": "^2.1003.0",
90+
"@aws-sdk/client-cloudfront": "^3.0.0",
8891
"bunyan": "^1.8.12",
8992
"bunyan-format": "^0.2.1"
9093
}

0 commit comments

Comments
 (0)