lambda-live-debugger 0.0.110 → 0.0.112

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/README.md CHANGED
@@ -146,15 +146,6 @@ export default {
146
146
 
147
147
  The setting are the same as for CLI parameters.
148
148
 
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
-
158
149
  ### Debugging
159
150
 
160
151
  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
221
212
 
222
213
  I am not a Terraform developer, so I only know the basics. Please provide a sample project so I can build better support.
223
214
 
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
+
224
310
  ## Know issues
225
311
 
226
312
  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
235
321
  - Use descriptive titles with prefixes like "bug:", "help:", "feature:", or "discussion:".
236
322
  - Enable verbose logging and provide the full log.
237
323
  - 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.
239
325
 
240
326
  ## Authors:
241
327
 
@@ -118,7 +118,7 @@ async function discoverLambdas() {
118
118
  noFramework = true;
119
119
  }
120
120
  if (config.getLambdas) {
121
- lambdasListNew = await config.getLambdas(lambdasListNew);
121
+ lambdasListNew = await config.getLambdas(lambdasListNew, config);
122
122
  }
123
123
  if (!lambdasListNew) {
124
124
  if (noFramework) {
Binary file
@@ -2,6 +2,7 @@ import { LambdaResource } from "../types/resourcesDiscovery.js";
2
2
  import { IFramework } from "./iFrameworks.js";
3
3
  import { AwsConfiguration } from "../types/awsConfiguration.js";
4
4
  import { LldConfigBase } from "../types/lldConfig.js";
5
+ import { type BundlingOptions } from "aws-cdk-lib/aws-lambda-nodejs";
5
6
  /**
6
7
  * Support for AWS CDK framework
7
8
  */
@@ -38,12 +39,32 @@ export declare class CdkFramework implements IFramework {
38
39
  * @returns
39
40
  */
40
41
  protected getLambdasDataFromCdkByCompilingAndRunning(cdkConfigPath: string, config: LldConfigBase): Promise<{
41
- cdkPath: any;
42
- stackName: any;
42
+ cdkPath: string;
43
+ stackName: string;
43
44
  packageJsonPath: string | undefined;
44
- codePath: any;
45
- handler: any;
46
- bundling: any;
45
+ codePath: string;
46
+ handler: string | undefined;
47
+ bundling: BundlingOptions;
48
+ }[]>;
49
+ /**
50
+ * Run CDK code in a node thread worker and return the Lambda functions
51
+ * @param param0
52
+ * @returns
53
+ */
54
+ protected runCdkCodeAndReturnLambdas({ config, awsCdkLibPath, compileCodeFile, }: {
55
+ config: LldConfigBase;
56
+ awsCdkLibPath: string | undefined;
57
+ compileCodeFile: string;
58
+ }): Promise<{
59
+ cdkPath: string;
60
+ stackName: string;
61
+ codePath?: string | undefined;
62
+ code: {
63
+ path?: string;
64
+ };
65
+ handler: string;
66
+ packageJsonPath: string;
67
+ bundling: BundlingOptions;
47
68
  }[]>;
48
69
  /**
49
70
  * Get CDK context
@@ -8,7 +8,6 @@ import { CloudFormation } from "../cloudFormation.mjs";
8
8
  import { Logger } from "../logger.mjs";
9
9
  import { Worker } from "node:worker_threads";
10
10
  import { getModuleDirname, getProjectDirname } from "../getDirname.mjs";
11
- import { Configuration } from "../configuration.mjs";
12
11
  import { findNpmPath } from "../utils/findNpmPath.mjs";
13
12
  /**
14
13
  * Support for AWS CDK framework
@@ -219,32 +218,11 @@ export class CdkFramework {
219
218
  Logger.verbose(`[CDK] Context:`, JSON.stringify(CDK_CONTEXT_JSON, null, 2));
220
219
  const awsCdkLibPath = await findNpmPath(path.join(getProjectDirname(), config.subfolder ?? "/"), "aws-cdk-lib");
221
220
  Logger.verbose(`[CDK] aws-cdk-lib path: ${awsCdkLibPath}`);
222
- const lambdas = await new Promise((resolve, reject) => {
223
- const worker = new Worker(path.resolve(path.join(getModuleDirname(), "frameworks/cdkFrameworkWorker.mjs")), {
224
- workerData: {
225
- verbose: Configuration.config.verbose,
226
- awsCdkLibPath,
227
- },
228
- });
229
- worker.on("message", async (message) => {
230
- resolve(message);
231
- await worker.terminate();
232
- });
233
- worker.on("error", (error) => {
234
- reject(new Error(`Error running CDK code in worker: ${error.message}`, {
235
- cause: error,
236
- }));
237
- });
238
- worker.on("exit", (code) => {
239
- if (code !== 0) {
240
- reject(new Error(`CDK worker stopped with exit code ${code}`));
241
- }
242
- });
243
- worker.postMessage({
244
- compileOutput,
245
- });
221
+ const lambdas = await this.runCdkCodeAndReturnLambdas({
222
+ config,
223
+ awsCdkLibPath,
224
+ compileCodeFile: compileOutput,
246
225
  });
247
- Logger.verbose(`[CDK] Found the following Lambda functions in the CDK code:`, JSON.stringify(lambdas, null, 2));
248
226
  const list = await Promise.all(lambdas.map(async (lambda) => {
249
227
  // handler slit into file and file name
250
228
  const handlerSplit = lambda.handler.split(".");
@@ -252,11 +230,19 @@ export class CdkFramework {
252
230
  const filename = handlerSplit[0];
253
231
  let codePath = lambda.codePath;
254
232
  if (!codePath) {
255
- const codePathJs = path.join(lambda.code.path, `${filename}.js`);
256
- const codePathCjs = path.join(lambda.code.path, `${filename}.cjs`);
257
- const codePathMjs = path.join(lambda.code.path, `${filename}.mjs`);
258
- // get the first file that exists
259
- codePath = [codePathJs, codePathCjs, codePathMjs].find((file) => fs
233
+ const codePathJs = lambda.code?.path
234
+ ? path.join(lambda.code.path, `${filename}.js`)
235
+ : undefined;
236
+ const codePathCjs = lambda.code?.path
237
+ ? path.join(lambda.code.path, `${filename}.cjs`)
238
+ : undefined;
239
+ const codePathMjs = lambda.code?.path
240
+ ? path.join(lambda.code.path, `${filename}.mjs`)
241
+ : undefined;
242
+ // get the first file that exists
243
+ codePath = [codePathJs, codePathCjs, codePathMjs]
244
+ .filter((c) => c)
245
+ .find((file) => fs
260
246
  .access(file)
261
247
  .then(() => true)
262
248
  .catch(() => false));
@@ -277,6 +263,42 @@ export class CdkFramework {
277
263
  }));
278
264
  return list;
279
265
  }
266
+ /**
267
+ * Run CDK code in a node thread worker and return the Lambda functions
268
+ * @param param0
269
+ * @returns
270
+ */
271
+ async runCdkCodeAndReturnLambdas({ config, awsCdkLibPath, compileCodeFile, }) {
272
+ const lambdas = await new Promise((resolve, reject) => {
273
+ const worker = new Worker(path.resolve(path.join(getModuleDirname(), "frameworks/cdkFrameworkWorker.mjs")), {
274
+ workerData: {
275
+ verbose: config.verbose,
276
+ awsCdkLibPath,
277
+ projectDirname: getProjectDirname(),
278
+ moduleDirname: getModuleDirname(),
279
+ },
280
+ });
281
+ worker.on("message", async (message) => {
282
+ resolve(message);
283
+ await worker.terminate();
284
+ });
285
+ worker.on("error", (error) => {
286
+ reject(new Error(`Error running CDK code in worker: ${error.message}`, {
287
+ cause: error,
288
+ }));
289
+ });
290
+ worker.on("exit", (code) => {
291
+ if (code !== 0) {
292
+ reject(new Error(`CDK worker stopped with exit code ${code}`));
293
+ }
294
+ });
295
+ worker.postMessage({
296
+ compileOutput: compileCodeFile,
297
+ });
298
+ });
299
+ Logger.verbose(`[CDK] Found the following Lambda functions in the CDK code:`, JSON.stringify(lambdas, null, 2));
300
+ return lambdas;
301
+ }
280
302
  /**
281
303
  * Get CDK context
282
304
  * @param cdkConfigPath
@@ -1,10 +1,7 @@
1
+ // @ts-nocheck
1
2
  import { createRequire as topLevelCreateRequire } from "module";
2
3
  const require = topLevelCreateRequire(import.meta.url);
3
4
  import path from "path";
4
- import { fileURLToPath } from "node:url";
5
- const __filename = fileURLToPath(import.meta.url);
6
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
7
- const __dirname = path.dirname(__filename);
8
5
 
9
6
  import { workerData, parentPort } from "node:worker_threads";
10
7
  import fs from "fs/promises";
@@ -12,6 +9,9 @@ import fs from "fs/promises";
12
9
  import { Logger } from "../logger.mjs";
13
10
 
14
11
  Logger.setVerbose(workerData.verbose);
12
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
13
+ const __dirname = path.resolve(path.join(workerData.projectDirname, "/x/x"));
14
+
15
15
  Logger.verbose(`[CDK] [Worker] Started`);
16
16
 
17
17
  parentPort.on("message", async (data) => {
@@ -2,6 +2,7 @@
2
2
  import { LambdaResource } from "../types/resourcesDiscovery.js";
3
3
  import { exec } from "child_process";
4
4
  import { IFramework } from "./iFrameworks.js";
5
+ import { LldConfigBase } from "../types/lldConfig.js";
5
6
  export declare const execAsync: typeof exec.__promisify__;
6
7
  interface TerraformState {
7
8
  resources: Array<{
@@ -31,10 +32,10 @@ export declare class TerraformFramework implements IFramework {
31
32
  canHandle(): Promise<boolean>;
32
33
  /**
33
34
  * Get Lambda functions
34
- * @param config Configuration
35
+ * @param _config Configuration
35
36
  * @returns Lambda functions
36
37
  */
37
- getLambdas(): Promise<LambdaResource[]>;
38
+ getLambdas(config: LldConfigBase): Promise<LambdaResource[]>;
38
39
  protected extractLambdaInfo(state: TerraformState): {
39
40
  functionName: string;
40
41
  sourceDir?: string | undefined;
@@ -32,10 +32,11 @@ export class TerraformFramework {
32
32
  }
33
33
  /**
34
34
  * Get Lambda functions
35
- * @param config Configuration
35
+ * @param _config Configuration
36
36
  * @returns Lambda functions
37
37
  */
38
- async getLambdas() {
38
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
39
+ async getLambdas(config) {
39
40
  const state = await this.readTerraformState();
40
41
  const lambdas = this.extractLambdaInfo(state);
41
42
  Logger.verbose("[Terraform] Found Lambdas:", JSON.stringify(lambdas, null, 2));
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
- export { type LldConfigTs } from "./types/lldConfig.js";
2
- export type { EsBuildOptions, BundlingType, LambdaResource as LambdaResource, } from "./types/resourcesDiscovery.js";
1
+ export { type LldConfigTs, type LldConfigBase } from "./types/lldConfig.js";
2
+ export type { EsBuildOptions, BundlingType, LambdaResource, } from "./types/resourcesDiscovery.js";
3
3
  export { CdkFramework } from "./frameworks/cdkFramework.js";
4
4
  export { SlsFramework } from "./frameworks/slsFramework.js";
5
5
  export { SamFramework } from "./frameworks/samFramework.js";
6
6
  export { TerraformFramework } from "./frameworks/terraformFramework.js";
7
- export type { IFramework } from "./frameworks/iFrameworks.js";
7
+ export { type IFramework } from "./frameworks/iFrameworks.js";
8
+ export { type AwsConfiguration } from "./types/awsConfiguration.js";
@@ -21,7 +21,7 @@ import { LambdaConnection } from "./lambdaConnection.mjs";
21
21
  */
22
22
  async function run() {
23
23
  const version = await getVersion();
24
- Logger.log(`Welcome to Lambda Live Debugger version ${version}.`);
24
+ Logger.log(`Welcome to Lambda Live Debugger 🐞 version ${version}.`);
25
25
  Logger.log("To keep the project moving forward, please fill out the feedback form at https://forms.gle/v6ekZtuB45Rv3EyW9. Your input is greatly appreciated!");
26
26
  await Configuration.readConfig();
27
27
  Logger.setVerbose(Configuration.config.verbose === true);
@@ -39,8 +39,7 @@ async function run() {
39
39
  if (!Configuration.config.start && !Configuration.config.remove) {
40
40
  return;
41
41
  }
42
- Logger.log(`Starting the debugger
43
- ${Configuration.config.observable
42
+ Logger.log(`Starting the debugger ${Configuration.config.observable
44
43
  ? "in observable mode"
45
44
  : `(ID ${Configuration.config.debuggerId})`}
46
45
  ...`);
@@ -43,7 +43,7 @@ export type LldConfigBase = {
43
43
  /**
44
44
  * Resources discovery function
45
45
  */
46
- getLambdas?: (foundFunctions?: LambdaResource[]) => Promise<LambdaResource[] | undefined>;
46
+ getLambdas?: (foundFunctions?: LambdaResource[], config?: LldConfigBase) => Promise<LambdaResource[] | undefined>;
47
47
  /**
48
48
  * Monorepo subfolder
49
49
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lambda-live-debugger",
3
- "version": "0.0.110",
3
+ "version": "0.0.112",
4
4
  "type": "module",
5
5
  "description": "Debug Lambda functions locally like it is running in the cloud",
6
6
  "repository": {