diff --git a/.github/workflows/common-test.yml b/.github/workflows/common-test.yml index adf87e6b..a3feafa7 100644 --- a/.github/workflows/common-test.yml +++ b/.github/workflows/common-test.yml @@ -380,6 +380,56 @@ jobs: - name: Test - observability mode run: OBSERVABLE_MODE=true npx vitest --retry 2 test/osls-basic.test.ts + test-osls-nested: + runs-on: ubuntu-latest + concurrency: + group: test-osls-nested + steps: + - uses: actions/checkout@v4 + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.node_version }} + registry-url: 'https://registry.npmjs.org' + - name: Install dependencies + run: | + node prepareForTest.js osls-nested + npm i + - name: Download build artifact + uses: actions/download-artifact@v4 + if: ${{ inputs.mode == 'build' }} + with: + name: dist + path: dist + - name: Install lambda-live-debugger globally + if: ${{ inputs.mode == 'global' }} + run: | + npm i lambda-live-debugger@${{ inputs.version || 'latest' }} -g + npm i osls -g + working-directory: test + - name: Install lambda-live-debugger locally + if: ${{ inputs.mode == 'local' }} + run: | + npm i lambda-live-debugger@${{ inputs.version || 'latest' }} + working-directory: test + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: eu-west-1 + role-to-assume: ${{ secrets.AWS_ROLE }} + role-session-name: GitHubActions + - name: Destroy + run: npm run destroy + working-directory: test/osls-nested + continue-on-error: true + - name: Deploy + run: npm run deploy + working-directory: test/osls-nested + - name: Test + run: npx vitest --retry 2 test/osls-nested.test.ts + - name: Test - observability mode + run: OBSERVABLE_MODE=true npx vitest --retry 2 test/osls-nested.test.ts + test-osls-esbuild-cjs: runs-on: ubuntu-latest concurrency: diff --git a/.vscode/launch.json b/.vscode/launch.json index 5841916a..67ac43de 100755 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -170,6 +170,26 @@ "type": "node", "cwd": "${workspaceRoot}/test/osls-basic" }, + { + "name": "LLDebugger - OSLS nested", + "program": "${workspaceRoot}/node_modules/tsx/dist/cli.mjs", + "args": ["../../src/lldebugger.ts", "--stage=test"], + "request": "launch", + "skipFiles": ["/**"], + "console": "integratedTerminal", + "type": "node", + "cwd": "${workspaceRoot}/test/osls-nested" + }, + { + "name": "LLDebugger - OSLS nested - observability", + "program": "${workspaceRoot}/node_modules/tsx/dist/cli.mjs", + "args": ["../../src/lldebugger.ts", "--stage=test", "-o"], + "request": "launch", + "skipFiles": ["/**"], + "console": "integratedTerminal", + "type": "node", + "cwd": "${workspaceRoot}/test/osls-nested" + }, { "name": "LLDebugger - OSLS EsBuild CJS", "program": "${workspaceRoot}/node_modules/tsx/dist/cli.mjs", diff --git a/package-lock.json b/package-lock.json index 56cfc2ef..e25edabe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,6 +39,7 @@ "test/sls-esbuild", "test/sls-esbuild-cjs", "test/osls-basic", + "test/osls-nested", "test/osls-esbuild", "test/osls-esbuild-cjs", "test/sam-basic", @@ -38902,6 +38903,10 @@ "resolved": "test/osls-esbuild-cjs", "link": true }, + "node_modules/osls-nested": { + "resolved": "test/osls-nested", + "link": true + }, "node_modules/osls/node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -41100,6 +41105,27 @@ "node": ">=6" } }, + "node_modules/serverless-nested-stack": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/serverless-nested-stack/-/serverless-nested-stack-0.0.7.tgz", + "integrity": "sha512-H+faSrjHD3sL9xQI8LBJs6ZIlYClFKlBKlcln5CZ2ul0KkBfkabzeEplzE8ooNQSgBPoH7OxuvzaZBFWfCtkbA==", + "dev": true, + "license": "ISC", + "dependencies": { + "bluebird": "^3.5.0", + "filesize": "^3.5.10" + } + }, + "node_modules/serverless-nested-stack/node_modules/filesize": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz", + "integrity": "sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/serverless/node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -46303,6 +46329,17 @@ "serverless-esbuild": "^1.56.0" } }, + "test/osls-nested": { + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@aws-sdk/client-sts": "^3.936.0" + }, + "devDependencies": { + "osls": "^3.59.3", + "serverless-nested-stack": "^0.0.7" + } + }, "test/sam-alt": { "version": "0.0.1", "dependencies": { diff --git a/package.json b/package.json index 7fe9752d..b0734d96 100755 --- a/package.json +++ b/package.json @@ -64,6 +64,8 @@ "test-sls-esbuild-esm-observable": "npm run build && RUN_TEST_FROM_CLI=true OBSERVABLE_MODE=true vitest run test/sls-esbuild-esm.test.ts", "test-osls-basic": "npm run build && RUN_TEST_FROM_CLI=true vitest run test/osls-basic.test.ts", "test-osls-basic-observable": "npm run build && RUN_TEST_FROM_CLI=true OBSERVABLE_MODE=true vitest run test/osls-basic.test.ts", + "test-osls-nested": "npm run build && RUN_TEST_FROM_CLI=true vitest run test/osls-nested.test.ts", + "test-osls-nested-observable": "npm run build && RUN_TEST_FROM_CLI=true OBSERVABLE_MODE=true vitest run test/osls-nested.test.ts", "test-osls-esbuild-cjs": "npm run build && RUN_TEST_FROM_CLI=true vitest run test/osls-esbuild-cjs.test.ts", "test-osls-esbuild-cjs-observable": "npm run build && RUN_TEST_FROM_CLI=true OBSERVABLE_MODE=true vitest run test/osls-esbuild-cjs.test.ts", "test-osls-esbuild-esm": "npm run build && RUN_TEST_FROM_CLI=true vitest run test/osls-esbuild-esm.test.ts", @@ -160,6 +162,7 @@ "test/sls-esbuild", "test/sls-esbuild-cjs", "test/osls-basic", + "test/osls-nested", "test/osls-esbuild", "test/osls-esbuild-cjs", "test/sam-basic", diff --git a/src/frameworks/slsFramework.ts b/src/frameworks/slsFramework.ts index 1d559f77..0b9b751e 100755 --- a/src/frameworks/slsFramework.ts +++ b/src/frameworks/slsFramework.ts @@ -182,60 +182,173 @@ export class SlsFramework implements IFramework { config, ); + // Get functions from main configuration const lambdas = serverless.service.functions; Logger.verbose(`[SLS] Found Lambdas:`, JSON.stringify(lambdas, null, 2)); + // Process main stack functions for (const func in lambdas) { - const lambda = lambdas[func] as Serverless.FunctionDefinitionHandler; - const handlerFull = lambda.handler; - const handlerParts = handlerFull.split('.'); - const handler = handlerParts[1]; - - const possibleCodePaths = [ - `${handlerParts[0]}.ts`, - `${handlerParts[0]}.js`, - `${handlerParts[0]}.cjs`, - `${handlerParts[0]}.mjs`, - ]; - let codePath: string | undefined; - for (const cp of possibleCodePaths) { - try { - await fs.access(cp, constants.F_OK); - codePath = cp; - break; - } catch { - // ignore, file not found - } - } + const lambdaResource = await this.processFunction( + func, + lambdas[func] as Serverless.FunctionDefinitionHandler, + esBuildOptions, + ); + lambdasDiscovered.push(lambdaResource); + } - if (!codePath) { - throw new Error(`Code path not found for handler: ${handlerFull}`); + // Check for nested stacks (serverless-nested-stack plugin) + const nestedStacks = (serverless.service as any).nestedStacks; + if (nestedStacks) { + Logger.verbose( + `[SLS] Found nested stacks configuration:`, + JSON.stringify(nestedStacks, null, 2), + ); + + const nestedLambdas = await this.parseNestedStacks( + nestedStacks, + esBuildOptions, + ); + lambdasDiscovered.push(...nestedLambdas); + } + + return lambdasDiscovered; + } + + /** + * Process a single Lambda function + */ + private async processFunction( + funcName: string, + lambda: Serverless.FunctionDefinitionHandler, + esBuildOptions: EsBuildOptions | undefined, + ): Promise { + const handlerFull = lambda.handler; + const handlerParts = handlerFull.split('.'); + const handler = handlerParts[1]; + + const possibleCodePaths = [ + `${handlerParts[0]}.ts`, + `${handlerParts[0]}.js`, + `${handlerParts[0]}.cjs`, + `${handlerParts[0]}.mjs`, + ]; + let codePath: string | undefined; + for (const cp of possibleCodePaths) { + try { + await fs.access(cp, constants.F_OK); + codePath = cp; + break; + } catch { + // ignore, file not found } + } - const functionName = lambda.name; - if (!functionName) { - throw new Error(`Function name not found for handler: ${handlerFull}`); + if (!codePath) { + throw new Error(`Code path not found for handler: ${handlerFull}`); + } + + const functionName = lambda.name; + if (!functionName) { + throw new Error(`Function name not found for handler: ${handlerFull}`); + } + + const packageJsonPath = await findPackageJson(codePath); + Logger.verbose(`[SLS] package.json path: ${packageJsonPath}`); + + const lambdaResource: LambdaResource = { + functionName, + codePath, + handler, + packageJsonPath, + esBuildOptions, + metadata: { + framework: 'sls', + }, + }; + + return lambdaResource; + } + + /** + * Parse nested stacks recursively + */ + private async parseNestedStacks( + nestedStacks: any, + esBuildOptions: EsBuildOptions | undefined, + currentDir: string = process.cwd(), + ): Promise { + const lambdas: LambdaResource[] = []; + + for (const stackName in nestedStacks) { + const stackConfig = nestedStacks[stackName]; + const templatePath = stackConfig.template; + + if (!templatePath) { + Logger.verbose( + `[SLS] Nested stack ${stackName} has no template property`, + ); + continue; } - const packageJsonPath = await findPackageJson(codePath); - Logger.verbose(`[SLS] package.json path: ${packageJsonPath}`); + const resolvedTemplatePath = path.resolve(currentDir, templatePath); + Logger.verbose( + `[SLS] Parsing nested stack ${stackName}: ${resolvedTemplatePath}`, + ); - const lambdaResource: LambdaResource = { - functionName, - codePath, - handler, - packageJsonPath, - esBuildOptions, - metadata: { - framework: 'sls', - }, - }; + try { + const templateContent = await fs.readFile( + resolvedTemplatePath, + 'utf-8', + ); + const yaml = await import('yaml'); + const nestedConfig = yaml.parse(templateContent); + + // Process functions in nested stack + if (nestedConfig.functions) { + Logger.verbose( + `[SLS] Found functions in nested stack ${stackName}:`, + JSON.stringify(nestedConfig.functions, null, 2), + ); + + for (const funcName in nestedConfig.functions) { + const func = nestedConfig.functions[funcName]; + const lambdaResource = await this.processFunction( + funcName, + func as Serverless.FunctionDefinitionHandler, + esBuildOptions, + ); + lambdas.push(lambdaResource); + } + } - lambdasDiscovered.push(lambdaResource); + // Recursively process nested stacks within this stack + if (nestedConfig.nestedStacks) { + Logger.verbose( + `[SLS] Found nested stacks within ${stackName}:`, + JSON.stringify(nestedConfig.nestedStacks, null, 2), + ); + + const templateDir = path.dirname(resolvedTemplatePath); + const deeperNestedLambdas = await this.parseNestedStacks( + nestedConfig.nestedStacks, + esBuildOptions, + templateDir, + ); + lambdas.push(...deeperNestedLambdas); + } + } catch (err: any) { + Logger.warn( + `[SLS] Could not parse nested stack at ${resolvedTemplatePath}: ${err.message}`, + ); + } } - return lambdasDiscovered; + Logger.verbose( + `[SLS] Finished parsing nested stacks, found ${lambdas.length} Lambda function(s)${lambdas.length > 0 ? `:\n${lambdas.map((l) => ` - ${l.functionName}`).join('\n')}` : ''}`, + ); + + return lambdas; } // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/test/osls-basic/nested-nested-stack.yml b/test/osls-basic/nested-nested-stack.yml new file mode 100644 index 00000000..75ceb0be --- /dev/null +++ b/test/osls-basic/nested-nested-stack.yml @@ -0,0 +1,14 @@ +service: lls-osls-basic-nested-nested +frameworkVersion: '3' + +provider: + name: aws + runtime: nodejs22.x + region: eu-west-1 + +functions: + testJsCommonJsNested: + handler: services/testJsCommonJs/lambda.lambdaHandler + + testJsEsModuleNested: + handler: services/testJsEsModule/lambda.lambdaHandler diff --git a/test/osls-basic/nested-stack-sam.yml b/test/osls-basic/nested-stack-sam.yml new file mode 100644 index 00000000..e69de29b diff --git a/test/osls-basic/nested-stack.yml b/test/osls-basic/nested-stack.yml new file mode 100644 index 00000000..053300d3 --- /dev/null +++ b/test/osls-basic/nested-stack.yml @@ -0,0 +1,18 @@ +service: lls-osls-basic-nested +frameworkVersion: '3' + +provider: + name: aws + runtime: nodejs22.x + region: eu-west-1 + +functions: + testJsCommonJsFromNestedStack: + handler: services/testJsCommonJs/lambda.lambdaHandler + + testJsEsModuleFromNestedStack: + handler: services/testJsEsModule/lambda.lambdaHandler + +nestedStacks: + NestedNestedStack: + template: nested-nested-stack.yml diff --git a/test/osls-nested.test.ts b/test/osls-nested.test.ts new file mode 100644 index 00000000..ec680e87 --- /dev/null +++ b/test/osls-nested.test.ts @@ -0,0 +1,123 @@ +import { expect, test, describe, beforeAll, afterAll } from 'vitest'; +import { ChildProcess } from 'child_process'; +import { startDebugger } from './utils/startDebugger.js'; +import { expectInfraRemoved } from './utils/expectInfraRemoved.js'; +import { expectInfraDeployed } from './utils/expectInfraDeployed.js'; +import { removeInfra } from './utils/removeInfra.js'; +import { exec } from 'child_process'; +import { promisify } from 'util'; +import { callLambda } from './utils/callLambda.js'; +import { getSamplePayload } from './utils/getSamplePayload.js'; +import { validateLocalResponse } from './utils/validateLocalResponse.js'; +import { getTestProjectFolder } from './utils/getTestProjectFolder.js'; + +export const execAsync = promisify(exec); + +const observableMode = process.env.OBSERVABLE_MODE === 'true'; + +describe('osls-nested', async () => { + const folder = await getTestProjectFolder('osls-nested'); + let lldProcess: ChildProcess | undefined; + + beforeAll(async () => { + if (process.env.CI === 'true' || process.env.RUN_TEST_FROM_CLI === 'true') { + lldProcess = await startDebugger(folder, ['--stage=test']); + } + }); + + afterAll(async () => { + // stop the debugger + lldProcess?.kill(); + }); + + test('check infra', async () => { + const lambdaName = 'lls-osls-nested-test-testJsCommonJs'; + await expectInfraDeployed(lambdaName); + }); + + test('call Lambda - testJsCommonJs', async () => { + const lambdaName = 'lls-osls-nested-test-testJsCommonJs'; + + const payload = getSamplePayload(lambdaName); + const response = await callLambda(lambdaName, payload); + + expect(response.inputEvent).toEqual(payload); + expect(response.runningLocally).toEqual(!observableMode); + if (observableMode) { + await validateLocalResponse(lambdaName, payload); + } + }); + + test('call Lambda - testJsEsModule', async () => { + const lambdaName = 'lls-osls-nested-test-testJsEsModule'; + + const payload = getSamplePayload(lambdaName); + const response = await callLambda(lambdaName, payload); + + expect(response.inputEvent).toEqual(payload); + expect(response.runningLocally).toEqual(!observableMode); + if (observableMode) { + await validateLocalResponse(lambdaName, payload); + } + }); + + test('call Lambda - testJsCommonJsFromNestedStack', async () => { + const lambdaName = 'lls-osls-nested-test-testJsCommonJsFromNestedStack'; + + const payload = getSamplePayload(lambdaName); + const response = await callLambda(lambdaName, payload); + + expect(response.inputEvent).toEqual(payload); + expect(response.runningLocally).toEqual(!observableMode); + if (observableMode) { + await validateLocalResponse(lambdaName, payload); + } + }); + + test('call Lambda - testJsEsModuleFromNestedStack', async () => { + const lambdaName = 'lls-osls-nested-test-testJsEsModuleFromNestedStack'; + + const payload = getSamplePayload(lambdaName); + const response = await callLambda(lambdaName, payload); + + expect(response.inputEvent).toEqual(payload); + expect(response.runningLocally).toEqual(!observableMode); + if (observableMode) { + await validateLocalResponse(lambdaName, payload); + } + }); + + test('call Lambda - testJsCommonJsNested', async () => { + const lambdaName = 'lls-osls-nested-test-testJsCommonJsNested'; + + const payload = getSamplePayload(lambdaName); + const response = await callLambda(lambdaName, payload); + + expect(response.inputEvent).toEqual(payload); + expect(response.runningLocally).toEqual(!observableMode); + if (observableMode) { + await validateLocalResponse(lambdaName, payload); + } + }); + + test('call Lambda - testJsEsModuleNested', async () => { + const lambdaName = 'lls-osls-nested-test-testJsEsModuleNested'; + + const payload = getSamplePayload(lambdaName); + const response = await callLambda(lambdaName, payload); + + expect(response.inputEvent).toEqual(payload); + expect(response.runningLocally).toEqual(!observableMode); + if (observableMode) { + await validateLocalResponse(lambdaName, payload); + } + }); + + test('remove infra', async () => { + if (process.env.CI === 'true' || process.env.RUN_TEST_FROM_CLI === 'true') { + await removeInfra(lldProcess, folder, ['--stage=test']); + const lambdaName = 'lls-osls-nested-test-testJsCommonJs'; + await expectInfraRemoved(lambdaName); + } + }); +}); diff --git a/test/osls-nested/.gitignore b/test/osls-nested/.gitignore new file mode 100644 index 00000000..2b48c8bd --- /dev/null +++ b/test/osls-nested/.gitignore @@ -0,0 +1,6 @@ +# package directories +node_modules +jspm_packages + +# Serverless directories +.serverless \ No newline at end of file diff --git a/test/osls-nested/functions1.yml b/test/osls-nested/functions1.yml new file mode 100644 index 00000000..7226b5a0 --- /dev/null +++ b/test/osls-nested/functions1.yml @@ -0,0 +1,2 @@ +testJsEsModule: + handler: services/testJsEsModule/lambda.lambdaHandler diff --git a/test/osls-nested/functions2.yml b/test/osls-nested/functions2.yml new file mode 100644 index 00000000..52f57d79 --- /dev/null +++ b/test/osls-nested/functions2.yml @@ -0,0 +1,2 @@ +testJsCommonJs: + handler: services/testJsCommonJs/lambda.lambdaHandler diff --git a/test/osls-nested/nested-nested-stack.yml b/test/osls-nested/nested-nested-stack.yml new file mode 100644 index 00000000..10a372bf --- /dev/null +++ b/test/osls-nested/nested-nested-stack.yml @@ -0,0 +1,14 @@ +service: lls-osls-nested-nested-nested +frameworkVersion: '3' + +provider: + name: aws + runtime: nodejs22.x + region: eu-west-1 + +functions: + testJsCommonJsNested: + handler: services/testJsCommonJs/lambda.lambdaHandler + + testJsEsModuleNested: + handler: services/testJsEsModule/lambda.lambdaHandler diff --git a/test/osls-nested/nested-stack.yml b/test/osls-nested/nested-stack.yml new file mode 100644 index 00000000..db6dfec1 --- /dev/null +++ b/test/osls-nested/nested-stack.yml @@ -0,0 +1,18 @@ +service: lls-osls-nested-nested +frameworkVersion: '3' + +provider: + name: aws + runtime: nodejs22.x + region: eu-west-1 + +functions: + testJsCommonJsFromNestedStack: + handler: services/testJsCommonJs/lambda.lambdaHandler + + testJsEsModuleFromNestedStack: + handler: services/testJsEsModule/lambda.lambdaHandler + +nestedStacks: + NestedNestedStack: + template: nested-nested-stack.yml diff --git a/test/osls-nested/package.json b/test/osls-nested/package.json new file mode 100644 index 00000000..5c3e4c11 --- /dev/null +++ b/test/osls-nested/package.json @@ -0,0 +1,20 @@ +{ + "name": "osls-nested", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "deploy": "serverless deploy --stage=test", + "destroy": "serverless remove --stage=test" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "osls": "^3.59.3", + "serverless-nested-stack": "^0.0.7" + }, + "dependencies": { + "@aws-sdk/client-sts": "^3.936.0" + } +} diff --git a/test/osls-nested/serverless.yml b/test/osls-nested/serverless.yml new file mode 100644 index 00000000..da6432ed --- /dev/null +++ b/test/osls-nested/serverless.yml @@ -0,0 +1,18 @@ +service: lls-osls-nested +frameworkVersion: '3' + +provider: + name: aws + runtime: nodejs22.x + region: eu-west-1 + +plugins: + - serverless-nested-stack + +functions: + - ${file(./functions1.yml)} + - ${file(./functions2.yml)} + +nestedStacks: + NestedStack: + template: nested-stack.yml diff --git a/test/osls-nested/services/testJsCommonJs/lambda.js b/test/osls-nested/services/testJsCommonJs/lambda.js new file mode 100755 index 00000000..4e37462d --- /dev/null +++ b/test/osls-nested/services/testJsCommonJs/lambda.js @@ -0,0 +1,40 @@ +const { STSClient, GetCallerIdentityCommand } = require('@aws-sdk/client-sts'); + +const stsClient = new STSClient({}); + +const lambdaHandler = async (event, context) => { + // Check context + const remainingTime = context.getRemainingTimeInMillis(); + if (remainingTime === undefined) { + throw new Error('Remaining time is undefined'); + } + + // check if SDK works + const command = new GetCallerIdentityCommand({}); + const identity = await stsClient.send(command); + + const response = { + inputEvent: event, + accountId: identity.Account, + runningLocally: process.env.IS_LOCAL === 'true', + }; + + if (process.env.IS_LOCAL === 'true') { + const fs = require('fs'); + const path = require('path'); + const filePath = path.join( + '..', + 'local_lambda_responses', + `${context.functionName}.json`, + ); + + fs.writeFileSync(filePath, JSON.stringify(response, null, 2)); + } + + return response; +}; + +// Export the lambda handler if needed, e.g., for unit testing +module.exports = { + lambdaHandler, +}; diff --git a/test/osls-nested/services/testJsCommonJs/package.json b/test/osls-nested/services/testJsCommonJs/package.json new file mode 100644 index 00000000..65630a5e --- /dev/null +++ b/test/osls-nested/services/testJsCommonJs/package.json @@ -0,0 +1,8 @@ +{ + "name": "sls-basic-test-js-commonjs", + "version": "1.0.0", + "type": "commonjs", + "dependencies": { + "@aws-sdk/client-sts": "^3.936.0" + } +} diff --git a/test/osls-nested/services/testJsEsModule/lambda.js b/test/osls-nested/services/testJsEsModule/lambda.js new file mode 100755 index 00000000..e3508208 --- /dev/null +++ b/test/osls-nested/services/testJsEsModule/lambda.js @@ -0,0 +1,35 @@ +import { STSClient, GetCallerIdentityCommand } from '@aws-sdk/client-sts'; + +const stsClient = new STSClient({}); + +export const lambdaHandler = async (event, context) => { + // check context + const remainingTime = context.getRemainingTimeInMillis(); + if (remainingTime === undefined) { + throw new Error('Remaining time is undefined'); + } + + // check SDK works + const command = new GetCallerIdentityCommand({}); + const identity = await stsClient.send(command); + + const response = { + inputEvent: event, + accountId: identity.Account, + runningLocally: process.env.IS_LOCAL === 'true', + }; + + if (process.env.IS_LOCAL === 'true') { + const fs = await import('fs'); + const path = await import('path'); + const filePath = path.join( + '..', + 'local_lambda_responses', + `${context.functionName}.json`, + ); + + fs.writeFileSync(filePath, JSON.stringify(response, null, 2)); + } + + return response; +}; diff --git a/test/osls-nested/services/testJsEsModule/package.json b/test/osls-nested/services/testJsEsModule/package.json new file mode 100644 index 00000000..fe50b411 --- /dev/null +++ b/test/osls-nested/services/testJsEsModule/package.json @@ -0,0 +1,8 @@ +{ + "name": "sls-basic-test-js-esmodule", + "version": "1.0.0", + "type": "module", + "dependencies": { + "@aws-sdk/client-sts": "^3.936.0" + } +}