UNPKG

lambda-live-debugger

Version:

Debug Lambda functions locally like it is running in the cloud

119 lines (118 loc) 4.02 kB
import { AwsCredentials } from './awsCredentials.mjs'; import { Logger } from './logger.mjs'; import * as yaml from 'yaml'; let cloudFormationClient; /** * Get CloudFormation stack template * @param stackName * @param awsConfiguration * @returns */ async function getCloudFormationStackTemplate(stackName, awsConfiguration) { const { GetTemplateCommand } = await import('@aws-sdk/client-cloudformation'); const command = new GetTemplateCommand({ StackName: stackName }); const cloudFormationClient = await getCloudFormationClient(awsConfiguration); try { const response = await cloudFormationClient.send(command); if (!response.TemplateBody) { throw new Error(`No template found for stack ${stackName}`); } let cfTemplate; try { cfTemplate = JSON.parse(response.TemplateBody); } catch (parseError) { if (parseError.message.includes('is not valid JSON')) { // If the template is not JSON, try parsing it as YAML cfTemplate = yaml.parse(response.TemplateBody); } else { throw parseError; } } return cfTemplate; } catch (error) { if (error.name === 'ValidationError') { Logger.error(`Stack ${stackName} not found. Try specifying a region. Error: ${error.message}`, error); return undefined; } else { throw error; } } } /** * Get CloudFormation client * @param awsConfiguration * @returns */ async function getCloudFormationClient(awsConfiguration) { if (!cloudFormationClient) { const { CloudFormationClient } = await import('@aws-sdk/client-cloudformation'); cloudFormationClient = new CloudFormationClient({ region: awsConfiguration.region, credentials: AwsCredentials.getCredentialsProvider(awsConfiguration), }); } return cloudFormationClient; } /** * Get CloudFormation resources * @param stackName * @param awsConfiguration * @returns */ async function getCloudFormationResources(stackName, awsConfiguration) { // temporary disable console.error because SAM framework outputs useless errors const originalConsoleError = console.error; console.error = function () { }; const { ListStackResourcesCommand } = await import('@aws-sdk/client-cloudformation'); console.error = originalConsoleError; const cloudFormationClient = await getCloudFormationClient(awsConfiguration); try { let nextToken = undefined; const items = []; do { const command = new ListStackResourcesCommand({ StackName: stackName, NextToken: nextToken, }); const response = await cloudFormationClient.send(command); if (response.StackResourceSummaries) { items.push(...response.StackResourceSummaries); } nextToken = response.NextToken; } while (nextToken); return items; } catch (error) { if (error.name === 'ValidationError') { Logger.error(`Stack ${stackName} not found. Try specifying a region. Error: ${error.message}`, error); return undefined; } else { throw error; } } } /** * Get Lambdas in stack * @param stackName * @param awsConfiguration * @returns */ async function getLambdasInStack(stackName, awsConfiguration) { const response = await getCloudFormationResources(stackName, awsConfiguration); const lambdaResources = response?.filter((resource) => resource.ResourceType === 'AWS::Lambda::Function'); return (lambdaResources?.map((resource) => { return { lambdaName: resource.PhysicalResourceId, logicalId: resource.LogicalResourceId, }; }) ?? []); } export const CloudFormation = { getCloudFormationStackTemplate, getLambdasInStack, };