lambda-live-debugger 1.10.5 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cloudFormation.d.ts
CHANGED
|
@@ -12,10 +12,11 @@ declare function getCloudFormationStackTemplate(stackName: string, awsConfigurat
|
|
|
12
12
|
* @param awsConfiguration
|
|
13
13
|
* @returns
|
|
14
14
|
*/
|
|
15
|
-
declare function getLambdasInStack(stackName: string, awsConfiguration: AwsConfiguration): Promise<Array<{
|
|
15
|
+
declare function getLambdasInStack(stackName: string, awsConfiguration: AwsConfiguration, stackLogicalId?: string): Promise<Array<{
|
|
16
16
|
lambdaName: string;
|
|
17
17
|
logicalId: string;
|
|
18
18
|
stackName: string;
|
|
19
|
+
stackLogicalId: string;
|
|
19
20
|
}>>;
|
|
20
21
|
export declare const CloudFormation: {
|
|
21
22
|
getCloudFormationStackTemplate: typeof getCloudFormationStackTemplate;
|
package/dist/cloudFormation.mjs
CHANGED
|
@@ -108,7 +108,7 @@ async function getCloudFormationResources(stackName, awsConfiguration) {
|
|
|
108
108
|
* @param awsConfiguration
|
|
109
109
|
* @returns
|
|
110
110
|
*/
|
|
111
|
-
async function getLambdasInStack(stackName, awsConfiguration) {
|
|
111
|
+
async function getLambdasInStack(stackName, awsConfiguration, stackLogicalId) {
|
|
112
112
|
const response = await getCloudFormationResources(stackName, awsConfiguration);
|
|
113
113
|
const lambdaResources = response?.filter((resource) => resource.ResourceType === 'AWS::Lambda::Function');
|
|
114
114
|
const nestedStacks = response?.filter((resource) => resource.ResourceType === 'AWS::CloudFormation::Stack');
|
|
@@ -117,12 +117,13 @@ async function getLambdasInStack(stackName, awsConfiguration) {
|
|
|
117
117
|
lambdaName: resource.PhysicalResourceId,
|
|
118
118
|
logicalId: resource.LogicalResourceId,
|
|
119
119
|
stackName: stackName,
|
|
120
|
+
stackLogicalId: stackLogicalId ?? stackName,
|
|
120
121
|
};
|
|
121
122
|
}) ?? [];
|
|
122
123
|
const lambdasInNestedStacks = await Promise.all((nestedStacks ?? []).map(async (nestedStack) => {
|
|
123
124
|
if (!nestedStack.PhysicalResourceId)
|
|
124
125
|
return [];
|
|
125
|
-
const lambdasInNestedStack = await getLambdasInStack(nestedStack.PhysicalResourceId, awsConfiguration);
|
|
126
|
+
const lambdasInNestedStack = await getLambdasInStack(nestedStack.PhysicalResourceId, awsConfiguration, nestedStack.LogicalResourceId);
|
|
126
127
|
return lambdasInNestedStack;
|
|
127
128
|
}));
|
|
128
129
|
const flattenedLambdasInNestedStacks = lambdasInNestedStacks.flat();
|
|
Binary file
|
|
@@ -26,5 +26,11 @@ export declare class SamFramework implements IFramework {
|
|
|
26
26
|
* @returns Lambda functions
|
|
27
27
|
*/
|
|
28
28
|
getLambdas(config: LldConfigBase): Promise<LambdaResource[]>;
|
|
29
|
+
/**
|
|
30
|
+
* Recursively parse templates to find all Lambda functions, including nested stacks
|
|
31
|
+
* @param templatePath The path to the CloudFormation/SAM template file
|
|
32
|
+
* @param stackName The name of the stack this template belongs to (for nested stacks)
|
|
33
|
+
*/
|
|
34
|
+
private parseLambdasFromTemplate;
|
|
29
35
|
}
|
|
30
36
|
export declare const samFramework: SamFramework;
|
|
@@ -83,43 +83,32 @@ export class SamFramework {
|
|
|
83
83
|
if (!stackName) {
|
|
84
84
|
throw new Error(`Stack name not found in ${samConfigFile}`);
|
|
85
85
|
}
|
|
86
|
-
const
|
|
87
|
-
const template = yaml.parse(samTemplateContent);
|
|
88
|
-
const lambdas = [];
|
|
89
|
-
// get all resources of type AWS::Serverless::Function
|
|
90
|
-
for (const resourceName in template.Resources) {
|
|
91
|
-
const resource = template.Resources[resourceName];
|
|
92
|
-
if (resource.Type === 'AWS::Serverless::Function') {
|
|
93
|
-
lambdas.push({
|
|
94
|
-
Name: resourceName,
|
|
95
|
-
...resource,
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
}
|
|
86
|
+
const lambdas = await this.parseLambdasFromTemplate(samTemplateFile, stackName);
|
|
99
87
|
const lambdasDiscovered = [];
|
|
100
88
|
Logger.verbose(`[SAM] Found Lambdas`, JSON.stringify(lambdas, null, 2));
|
|
101
89
|
const lambdasInStack = await CloudFormation.getLambdasInStack(stackName, awsConfiguration);
|
|
102
90
|
Logger.verbose(`[SAM] Found Lambdas in stack ${stackName}:`, JSON.stringify(lambdasInStack, null, 2));
|
|
103
91
|
// get tags for each Lambda
|
|
104
92
|
for (const func of lambdas) {
|
|
105
|
-
const handlerFull = path.join(func.
|
|
93
|
+
const handlerFull = path.join(func.codeUri ?? '', func.handler);
|
|
106
94
|
const handlerParts = handlerFull.split('.');
|
|
107
95
|
const handler = handlerParts[1];
|
|
108
|
-
const functionName = lambdasInStack.find((lambda) => lambda.logicalId === func.
|
|
96
|
+
const functionName = lambdasInStack.find((lambda) => lambda.logicalId === func.name &&
|
|
97
|
+
lambda.stackLogicalId === func.stackLogicalId)?.lambdaName;
|
|
109
98
|
if (!functionName) {
|
|
110
|
-
throw new Error(`Function name not found for function: ${func.
|
|
99
|
+
throw new Error(`Function name not found for function: ${func.name}`);
|
|
111
100
|
}
|
|
112
101
|
let esBuildOptions = undefined;
|
|
113
102
|
let codePath;
|
|
114
|
-
if (func.
|
|
115
|
-
if (func.
|
|
116
|
-
codePath = path.join(func.
|
|
103
|
+
if (func.buildMethod?.toLowerCase() === 'esbuild') {
|
|
104
|
+
if (func.entryPoints && func.entryPoints.length > 0) {
|
|
105
|
+
codePath = path.join(func.codeUri ?? '', func.entryPoints[0]);
|
|
117
106
|
}
|
|
118
107
|
esBuildOptions = {
|
|
119
|
-
external: func.
|
|
120
|
-
minify: func.
|
|
121
|
-
format: func.
|
|
122
|
-
target: func.
|
|
108
|
+
external: func.external,
|
|
109
|
+
minify: func.minify,
|
|
110
|
+
format: func.format,
|
|
111
|
+
target: func.target,
|
|
123
112
|
};
|
|
124
113
|
}
|
|
125
114
|
if (!codePath) {
|
|
@@ -164,5 +153,58 @@ export class SamFramework {
|
|
|
164
153
|
}
|
|
165
154
|
return lambdasDiscovered;
|
|
166
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* Recursively parse templates to find all Lambda functions, including nested stacks
|
|
158
|
+
* @param templatePath The path to the CloudFormation/SAM template file
|
|
159
|
+
* @param stackName The name of the stack this template belongs to (for nested stacks)
|
|
160
|
+
*/
|
|
161
|
+
async parseLambdasFromTemplate(templatePath, stackName) {
|
|
162
|
+
const resolvedTemplatePath = path.resolve(templatePath);
|
|
163
|
+
const templateDir = path.dirname(resolvedTemplatePath);
|
|
164
|
+
let template;
|
|
165
|
+
try {
|
|
166
|
+
const templateContent = await fs.readFile(resolvedTemplatePath, 'utf-8');
|
|
167
|
+
template = yaml.parse(templateContent);
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
Logger.warn(`[SAM] Could not read or parse template at ${templatePath}: ${err.message}`);
|
|
171
|
+
return [];
|
|
172
|
+
}
|
|
173
|
+
if (!template.Resources) {
|
|
174
|
+
return [];
|
|
175
|
+
}
|
|
176
|
+
const lambdas = [];
|
|
177
|
+
for (const resourceName in template.Resources) {
|
|
178
|
+
const resource = template.Resources[resourceName];
|
|
179
|
+
// Check if it's a Lambda function
|
|
180
|
+
if (resource.Type === 'AWS::Serverless::Function') {
|
|
181
|
+
lambdas.push({
|
|
182
|
+
templatePath,
|
|
183
|
+
name: resourceName,
|
|
184
|
+
codeUri: resource.Properties?.CodeUri,
|
|
185
|
+
handler: resource.Properties?.Handler,
|
|
186
|
+
buildMethod: resource.Metadata?.BuildMethod,
|
|
187
|
+
entryPoints: resource.Metadata?.BuildProperties?.EntryPoints,
|
|
188
|
+
external: resource.Metadata?.BuildProperties?.External,
|
|
189
|
+
minify: resource.Metadata?.BuildProperties?.Minify,
|
|
190
|
+
format: resource.Metadata?.BuildProperties?.Format,
|
|
191
|
+
target: resource.Metadata?.BuildProperties?.Target,
|
|
192
|
+
stackLogicalId: stackName,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
// Check if it's a nested stack
|
|
196
|
+
else if (resource.Type === 'AWS::Serverless::Application' ||
|
|
197
|
+
resource.Type === 'AWS::CloudFormation::Stack') {
|
|
198
|
+
const nestedTemplateLocation = resource.Properties?.Location ?? resource.Properties?.TemplateURL;
|
|
199
|
+
if (nestedTemplateLocation) {
|
|
200
|
+
const nestedTemplatePath = path.resolve(templateDir, nestedTemplateLocation);
|
|
201
|
+
const nestedLambdas = await this.parseLambdasFromTemplate(nestedTemplatePath, resourceName);
|
|
202
|
+
lambdas.push(...nestedLambdas);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
Logger.verbose(JSON.stringify(lambdas, null, 2));
|
|
207
|
+
return lambdas;
|
|
208
|
+
}
|
|
167
209
|
}
|
|
168
210
|
export const samFramework = new SamFramework();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lambda-live-debugger",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Debug Lambda functions locally like it is running in the cloud",
|
|
6
6
|
"repository": {
|
|
@@ -70,6 +70,8 @@
|
|
|
70
70
|
"test-osls-esbuild-esm-observable": "npm run build && RUN_TEST_FROM_CLI=true OBSERVABLE_MODE=true vitest run test/osls-esbuild-esm.test.ts",
|
|
71
71
|
"test-sam-basic": "npm run build && RUN_TEST_FROM_CLI=true vitest run test/sam-basic.test.ts",
|
|
72
72
|
"test-sam-basic-observable": "npm run build && RUN_TEST_FROM_CLI=true OBSERVABLE_MODE=true vitest run test/sam-basic.test.ts",
|
|
73
|
+
"test-sam-nested": "npm run build && RUN_TEST_FROM_CLI=true vitest run test/sam-nested.test.ts",
|
|
74
|
+
"test-sam-nested-observable": "npm run build && RUN_TEST_FROM_CLI=true OBSERVABLE_MODE=true vitest run test/sam-nested.test.ts",
|
|
73
75
|
"test-sam-alt": "npm run build && RUN_TEST_FROM_CLI=true vitest run test/sam-alt.test.ts",
|
|
74
76
|
"test-sam-alt-observable": "npm run build && RUN_TEST_FROM_CLI=true OBSERVABLE_MODE=true vitest run test/sam-alt.test.ts",
|
|
75
77
|
"test-terraform-basic": "npm run build && RUN_TEST_FROM_CLI=true vitest run test/terraform-basic.test.ts",
|
|
@@ -161,6 +163,7 @@
|
|
|
161
163
|
"test/osls-esbuild",
|
|
162
164
|
"test/osls-esbuild-cjs",
|
|
163
165
|
"test/sam-basic",
|
|
166
|
+
"test/sam-nested",
|
|
164
167
|
"test/sam-alt",
|
|
165
168
|
"test/terraform-basic",
|
|
166
169
|
"test/opentofu-basic"
|