Skip to content

Commit bca0a49

Browse files
feat: support only .mjs extension for node18+ lambdas (#3680)
feat: support only .mjs for node18+ lambdas By default when a nodejs lambda was created, the default file would be .js, but now with node 18 the default file is .mjs Solution: Only support .mjs files for node18+ lambdas Signed-off-by: Nikolas Komonen <[email protected]>
1 parent 661b0d6 commit bca0a49

File tree

5 files changed

+70
-11
lines changed

5 files changed

+70
-11
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "Feature",
3+
"description": "Lambda \"Download\" action now expects \".mjs\" extension for Node18+ lambdas"
4+
}

src/lambda/models/samLambdaRuntime.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,20 @@ export const nodeJsRuntimes: ImmutableSet<Runtime> = ImmutableSet<Runtime>([
3434
'nodejs14.x',
3535
'nodejs12.x',
3636
])
37+
export function getNodeMajorVersion(version?: string): number | undefined {
38+
if (!version) {
39+
return undefined
40+
}
41+
42+
const match = version.match(/^nodejs(\d+)\./)
43+
44+
if (match) {
45+
return Number(match[1])
46+
} else {
47+
return undefined
48+
}
49+
}
50+
3751
export const pythonRuntimes: ImmutableSet<Runtime> = ImmutableSet<Runtime>([
3852
'python3.10',
3953
'python3.9',

src/lambda/utils.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { CloudFormation, Lambda } from 'aws-sdk'
1111
import * as vscode from 'vscode'
1212
import { CloudFormationClient } from '../shared/clients/cloudFormationClient'
1313
import { LambdaClient } from '../shared/clients/lambdaClient'
14-
import { getFamily, RuntimeFamily } from './models/samLambdaRuntime'
14+
import { getFamily, getNodeMajorVersion, RuntimeFamily } from './models/samLambdaRuntime'
1515
import { getLogger } from '../shared/logger'
1616
import { ResourceFetcher } from '../shared/resourcefetcher/resourcefetcher'
1717
import { CompositeResourceFetcher } from '../shared/resourcefetcher/compositeResourceFetcher'
@@ -64,9 +64,16 @@ export function getLambdaDetails(configuration: Lambda.FunctionConfiguration): {
6464
case RuntimeFamily.Python:
6565
runtimeExtension = 'py'
6666
break
67-
case RuntimeFamily.NodeJS:
68-
runtimeExtension = 'js'
67+
case RuntimeFamily.NodeJS: {
68+
const nodeVersion = getNodeMajorVersion(configuration.Runtime)
69+
if (nodeVersion && nodeVersion >= 18) {
70+
// node18+ defaults to using the .mjs extension
71+
runtimeExtension = 'mjs'
72+
} else {
73+
runtimeExtension = 'js'
74+
}
6975
break
76+
}
7077
default:
7178
throw new Error(`Toolkit does not currently support imports for runtime: ${configuration.Runtime}`)
7279
}

src/test/lambda/models/samLambdaRuntime.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import {
1313
RuntimeFamily,
1414
samImageLambdaRuntimes,
1515
samLambdaCreatableRuntimes,
16+
getNodeMajorVersion,
17+
nodeJsRuntimes,
1618
} from '../../../lambda/models/samLambdaRuntime'
1719

1820
describe('compareSamLambdaRuntime', async function () {
@@ -123,3 +125,30 @@ describe('runtimes', function () {
123125
])
124126
})
125127
})
128+
129+
describe('getNodeMajorVersion()', () => {
130+
it('returns 12 on "nodejs12.x"', () => {
131+
const version = getNodeMajorVersion('nodejs12.x')
132+
assert.strictEqual(version, 12)
133+
})
134+
135+
it('returns 18 on "nodejs18.x"', () => {
136+
const version = getNodeMajorVersion('nodejs18.x')
137+
assert.strictEqual(version, 18)
138+
})
139+
140+
it('returns undefined on invalid input', () => {
141+
const version = getNodeMajorVersion('python12.x')
142+
assert.strictEqual(version, undefined)
143+
})
144+
145+
describe('extracts a version from existing runtimes', function () {
146+
nodeJsRuntimes.forEach(versionString => {
147+
it(`extracts from runtime: "${versionString}"`, () => {
148+
const version = getNodeMajorVersion(versionString)
149+
assert(version !== undefined)
150+
assert(0 < version && version < 999)
151+
})
152+
})
153+
})
154+
})

src/test/lambda/utils.test.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,23 @@ describe('lambda utils', async function () {
2121
Runtime: 'nodejs12.x',
2222
Handler: 'asdf/jkl/app.lambda_handler',
2323
})
24+
const node18ModuleParsedName = getLambdaDetails({
25+
Runtime: 'nodejs18.x',
26+
Handler: 'asdf/jkl/app.lambda_handler',
27+
})
2428
const PyNestedParsedName = getLambdaDetails({
2529
Runtime: 'python3.8',
2630
Handler: 'asdf/jkl/app.lambda_handler',
2731
})
28-
assert(jsNonNestedParsedName.fileName, 'app.js')
29-
assert(pyNonNestedParsedName.fileName, 'app.py')
30-
assert(jsNestedParsedName.fileName, 'asdf/jkl/app.js')
31-
assert(PyNestedParsedName.fileName, 'asdf/jkl/app.py')
32-
assert(jsNonNestedParsedName.functionName, 'lambda_handler')
33-
assert(pyNonNestedParsedName.functionName, 'lambda_handler')
34-
assert(jsNestedParsedName.functionName, 'lambda_handler')
35-
assert(PyNestedParsedName.functionName, 'lambda_handler')
32+
assert.strictEqual(jsNonNestedParsedName.fileName, 'app.js')
33+
assert.strictEqual(pyNonNestedParsedName.fileName, 'app.py')
34+
assert.strictEqual(jsNestedParsedName.fileName, 'asdf/jkl/app.js')
35+
assert.strictEqual(node18ModuleParsedName.fileName, 'asdf/jkl/app.mjs')
36+
assert.strictEqual(PyNestedParsedName.fileName, 'asdf/jkl/app.py')
37+
assert.strictEqual(jsNonNestedParsedName.functionName, 'lambda_handler')
38+
assert.strictEqual(pyNonNestedParsedName.functionName, 'lambda_handler')
39+
assert.strictEqual(jsNestedParsedName.functionName, 'lambda_handler')
40+
assert.strictEqual(PyNestedParsedName.functionName, 'lambda_handler')
3641
})
3742

3843
it('throws if the handler is not a supported runtime', async function () {

0 commit comments

Comments
 (0)