Skip to content

Commit 118bd7e

Browse files
fix: Custom framework implementation
1 parent 41287f6 commit 118bd7e

File tree

7 files changed

+196
-65
lines changed

7 files changed

+196
-65
lines changed

README.md

Lines changed: 96 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -146,15 +146,6 @@ export default {
146146

147147
The setting are the same as for CLI parameters.
148148

149-
### Custom framework implementation and adjustment
150-
151-
```typescript
152-
getLambdas: async (foundLambdas) => {
153-
//you can customize the list of lambdas here or create your own
154-
//return foundLambdas;
155-
},
156-
```
157-
158149
### Debugging
159150

160151
You might want to configure your development tool for debugging. The wizard automatically configures for VsCode in `.vscode/launch.json`. Here is an example:
@@ -221,6 +212,101 @@ Only the basic setup is supported. Check the [test case](https://github.com/Serv
221212

222213
I am not a Terraform developer, so I only know the basics. Please provide a sample project so I can build better support.
223214

215+
### Custom framework implementation and adjustment
216+
217+
Configuration file `lldebugger.config.ts` enables you to modify the list of Lambdas, change the code path, esBuild configuration, or provide your own list of Lambdas, thereby supporting support **any framework**. For this to work, install Lambda Live Debugger locally in the project.
218+
219+
```typescript
220+
getLambdas: async (foundLambdas, config) => {
221+
//you can customize the list of lambdas here or create your own
222+
return foundLambdas;
223+
},
224+
```
225+
226+
**Filter list of functions:**
227+
228+
```typescript
229+
getLambdas: async (foundLambdas, config) => {
230+
return foundLambdas?.filter((l) =>
231+
l.functionName.includes("myfunction"),
232+
);
233+
},
234+
```
235+
236+
**Modify code path:**\
237+
For example, when the framework has only a list of JavaScript files, but you transpiled them from TypeScript with your own solution.
238+
239+
```typescript
240+
getLambdas: async (foundLambdas, config) => {
241+
if (foundLambdas) {
242+
for (const lambda of foundLambdas) {
243+
lambda.codePath = lambda.codePath
244+
.replace("/dist/", "/src/")
245+
.replace(".js", ".ts");
246+
}
247+
}
248+
},
249+
```
250+
251+
**Modfiy esBuild configuration:**
252+
253+
```typescript
254+
import { type EsBuildOptions, type LldConfigTs } from "lambda-live-debugger";
255+
256+
export default {
257+
...
258+
getLambdas: async (foundLambdas, config) => {
259+
if (foundLambdas) {
260+
for (const lambda of foundLambdas) {
261+
lambda.esBuildOptions = {
262+
target: "node14",
263+
};
264+
}
265+
}
266+
},
267+
} satisfies LldConfigTs;
268+
```
269+
270+
**Provide your own list of Lambdas and support any framework**:
271+
272+
```typescript
273+
export default {
274+
//framework: <-- you do not need this line
275+
...
276+
getLambdas: async (foundLambdas, config) => {
277+
return [
278+
{
279+
// function name as deployed on AWS
280+
functionName: "mystack-myfunction",
281+
codePath: "/src/myLambda.ts",
282+
},
283+
];
284+
},
285+
} satisfies LldConfigTs;
286+
```
287+
288+
**Modify existing framework support:**
289+
290+
```typescript
291+
import { CdkFramework, type LldConfigBase, type LldConfigTs } from "lambda-live-debugger";
292+
293+
class MyCdkFramework extends CdkFramework {
294+
override getCdkContext(
295+
cdkConfigPath: string,
296+
config: LldConfigBase,
297+
) {
298+
// your implementation
299+
}
300+
}
301+
302+
export default {
303+
...
304+
getLambdas: async (foundLambdas, config) => {
305+
return new MyCdkFramework().getLambdas(config);
306+
}
307+
} satisfies LldConfigTs;s
308+
```
309+
224310
## Know issues
225311

226312
Check the [GitHub issues](https://github.com/ServerlessLife/lambda-live-debugger/issues).
@@ -235,7 +321,7 @@ Check the [GitHub issues](https://github.com/ServerlessLife/lambda-live-debugger
235321
- Use descriptive titles with prefixes like "bug:", "help:", "feature:", or "discussion:".
236322
- Enable verbose logging and provide the full log.
237323
- Describe your setup in detail, or better yet, provide a sample project.
238-
- Specify exact framework version (CDK, SLS, SAM ...) and exact version of Lambda Live Debugger version.
324+
- Specify the exact framework version (CDK, SLS, SAM ...) and the exact Lambda Live Debugger version.
239325

240326
## Authors:
241327

src/configuration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ async function discoverLambdas() {
142142
}
143143

144144
if (config.getLambdas) {
145-
lambdasListNew = await config.getLambdas(lambdasListNew);
145+
lambdasListNew = await config.getLambdas(lambdasListNew, config);
146146
}
147147

148148
if (!lambdasListNew) {

src/frameworks/cdkFramework.ts

Lines changed: 89 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import { LldConfigBase } from "../types/lldConfig.js";
1111
import { Logger } from "../logger.js";
1212
import { Worker } from "node:worker_threads";
1313
import { getModuleDirname, getProjectDirname } from "../getDirname.js";
14-
import { Configuration } from "../configuration.js";
1514
import { findNpmPath } from "../utils/findNpmPath.js";
15+
import { type BundlingOptions } from "aws-cdk-lib/aws-lambda-nodejs";
1616

1717
/**
1818
* Support for AWS CDK framework
@@ -315,14 +315,89 @@ export class CdkFramework implements IFramework {
315315
);
316316
Logger.verbose(`[CDK] aws-cdk-lib path: ${awsCdkLibPath}`);
317317

318+
const lambdas = await this.runCdkCodeAndReturnLambdas({
319+
config,
320+
awsCdkLibPath,
321+
compileCodeFile: compileOutput,
322+
});
323+
324+
const list = await Promise.all(
325+
lambdas.map(async (lambda) => {
326+
// handler slit into file and file name
327+
const handlerSplit = lambda.handler.split(".");
328+
329+
const handler = handlerSplit.pop();
330+
const filename = handlerSplit[0];
331+
332+
let codePath = lambda.codePath;
333+
334+
if (!codePath) {
335+
const codePathJs = lambda.code?.path
336+
? path.join(lambda.code.path, `${filename}.js`)
337+
: undefined;
338+
const codePathCjs = lambda.code?.path
339+
? path.join(lambda.code.path, `${filename}.cjs`)
340+
: undefined;
341+
const codePathMjs = lambda.code?.path
342+
? path.join(lambda.code.path, `${filename}.mjs`)
343+
: undefined;
344+
345+
// get the first file that exists
346+
codePath = [codePathJs, codePathCjs, codePathMjs]
347+
.filter((c) => c)
348+
.find((file) =>
349+
fs
350+
.access(file as string)
351+
.then(() => true)
352+
.catch(() => false),
353+
);
354+
355+
if (!codePath) {
356+
throw new Error(
357+
`Code file not found for Lambda function ${lambda.code.path}`,
358+
);
359+
}
360+
}
361+
362+
const packageJsonPath = await findPackageJson(codePath);
363+
Logger.verbose(`[CDK] package.json path: ${packageJsonPath}`);
364+
365+
return {
366+
cdkPath: lambda.cdkPath,
367+
stackName: lambda.stackName,
368+
packageJsonPath,
369+
codePath,
370+
handler,
371+
bundling: lambda.bundling,
372+
};
373+
}),
374+
);
375+
376+
return list;
377+
}
378+
379+
/**
380+
* Run CDK code in a node thread worker and return the Lambda functions
381+
* @param param0
382+
* @returns
383+
*/
384+
protected async runCdkCodeAndReturnLambdas({
385+
config,
386+
awsCdkLibPath,
387+
compileCodeFile,
388+
}: {
389+
config: LldConfigBase;
390+
awsCdkLibPath: string | undefined;
391+
compileCodeFile: string;
392+
}) {
318393
const lambdas: any[] = await new Promise((resolve, reject) => {
319394
const worker = new Worker(
320395
path.resolve(
321396
path.join(getModuleDirname(), "frameworks/cdkFrameworkWorker.mjs"),
322397
),
323398
{
324399
workerData: {
325-
verbose: Configuration.config.verbose,
400+
verbose: config.verbose,
326401
awsCdkLibPath,
327402
projectDirname: getProjectDirname(),
328403
moduleDirname: getModuleDirname(),
@@ -350,7 +425,7 @@ export class CdkFramework implements IFramework {
350425
});
351426

352427
worker.postMessage({
353-
compileOutput,
428+
compileOutput: compileCodeFile,
354429
});
355430
});
356431

@@ -359,51 +434,17 @@ export class CdkFramework implements IFramework {
359434
JSON.stringify(lambdas, null, 2),
360435
);
361436

362-
const list = await Promise.all(
363-
lambdas.map(async (lambda: any) => {
364-
// handler slit into file and file name
365-
const handlerSplit = lambda.handler.split(".");
366-
367-
const handler = handlerSplit.pop();
368-
const filename = handlerSplit[0];
369-
370-
let codePath = lambda.codePath;
371-
372-
if (!codePath) {
373-
const codePathJs = path.join(lambda.code.path, `${filename}.js`);
374-
const codePathCjs = path.join(lambda.code.path, `${filename}.cjs`);
375-
const codePathMjs = path.join(lambda.code.path, `${filename}.mjs`);
376-
377-
// get the first file that exists
378-
codePath = [codePathJs, codePathCjs, codePathMjs].find((file) =>
379-
fs
380-
.access(file)
381-
.then(() => true)
382-
.catch(() => false),
383-
);
384-
385-
if (!codePath) {
386-
throw new Error(
387-
`Code file not found for Lambda function ${lambda.code.path}`,
388-
);
389-
}
390-
}
391-
392-
const packageJsonPath = await findPackageJson(codePath);
393-
Logger.verbose(`[CDK] package.json path: ${packageJsonPath}`);
394-
395-
return {
396-
cdkPath: lambda.cdkPath,
397-
stackName: lambda.stackName,
398-
packageJsonPath,
399-
codePath,
400-
handler,
401-
bundling: lambda.bundling,
402-
};
403-
}),
404-
);
405-
406-
return list;
437+
return lambdas as {
438+
cdkPath: string;
439+
stackName: string;
440+
codePath?: string;
441+
code: {
442+
path?: string;
443+
};
444+
handler: string;
445+
packageJsonPath: string;
446+
bundling: BundlingOptions;
447+
}[];
407448
}
408449

409450
/**

src/frameworks/terraformFramework.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { promisify } from "util";
88
import ts from "typescript";
99
import { IFramework } from "./iFrameworks.js";
1010
import { Logger } from "../logger.js";
11+
import { LldConfigBase } from "../types/lldConfig.js";
1112

1213
export const execAsync = promisify(exec);
1314

@@ -57,10 +58,11 @@ export class TerraformFramework implements IFramework {
5758

5859
/**
5960
* Get Lambda functions
60-
* @param config Configuration
61+
* @param _config Configuration
6162
* @returns Lambda functions
6263
*/
63-
public async getLambdas(): Promise<LambdaResource[]> {
64+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
65+
public async getLambdas(config: LldConfigBase): Promise<LambdaResource[]> {
6466
const state = await this.readTerraformState();
6567
const lambdas = this.extractLambdaInfo(state);
6668

src/index.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
// Types exposed to the project, mainly used in lldebugger.config.ts configuraiton file
2-
export { type LldConfigTs } from "./types/lldConfig.js";
2+
export { type LldConfigTs, type LldConfigBase } from "./types/lldConfig.js";
33
export type {
44
EsBuildOptions,
55
BundlingType,
6-
LambdaResource as LambdaResource,
6+
LambdaResource,
77
} from "./types/resourcesDiscovery.js";
88
export { CdkFramework } from "./frameworks/cdkFramework.js";
99
export { SlsFramework } from "./frameworks/slsFramework.js";
1010
export { SamFramework } from "./frameworks/samFramework.js";
1111
export { TerraformFramework } from "./frameworks/terraformFramework.js";
12-
export type { IFramework } from "./frameworks/iFrameworks.js";
12+
export { type IFramework } from "./frameworks/iFrameworks.js";
13+
export { type AwsConfiguration } from "./types/awsConfiguration.js";

src/types/lldConfig.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export type LldConfigBase = {
4949
*/
5050
getLambdas?: (
5151
foundFunctions?: LambdaResource[],
52+
config?: LldConfigBase,
5253
) => Promise<LambdaResource[] | undefined>;
5354

5455
/**

test/cdk-config/lldebugger.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export default {
66
context: ["e=1", "e=2", "e=3", "e=4"],
77
observable: false,
88
verbose: false,
9-
//getLambdas: async (foundLambdas) => {
9+
//getLambdas: async (foundLambdas, config) => {
1010
// you can customize the list of lambdas here or create your own
1111
// return foundLambdas;
1212
//},

0 commit comments

Comments
 (0)