Last active
April 25, 2023 20:28
-
-
Save borgoat/718f1650cf6fe7f6fcb6c56a2e783e96 to your computer and use it in GitHub Desktop.
CDK Construct to find pre-bundled Lambda function - heavily inspired by CDK lambda-nodejs package
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import * as lambda from 'aws-cdk-lib/aws-lambda'; | |
| import type { CallSite } from 'aws-cdk-lib/aws-lambda-nodejs/lib/util'; | |
| import { Construct } from 'constructs'; | |
| import fs from 'fs'; | |
| import path from 'path'; | |
| import process from 'process'; | |
| export interface BundledLambdaFunctionProps extends lambda.FunctionOptions { | |
| /** | |
| * The name of the exported handler in the entry file. | |
| * | |
| * The handler is prefixed with `index.` unless the specified handler value contains a `.`, | |
| * in which case it is used as-is. | |
| * | |
| * @default handler | |
| */ | |
| readonly handler?: string; | |
| /** | |
| * The runtime environment. Only runtimes of the Node.js family are | |
| * supported. | |
| * | |
| * @default Runtime.NODEJS_18_X | |
| */ | |
| readonly runtime?: lambda.Runtime; | |
| } | |
| /** | |
| * Inspired to CDK's lambda-nodejs but for pre-bundled code. | |
| * | |
| * @see https://github.com/aws/aws-cdk/blob/v2.70.0/packages/@aws-cdk/aws-lambda-nodejs/lib/function.ts | |
| */ | |
| export class BundledLambdaFunction extends lambda.Function { | |
| constructor(scope: Construct, id: string, props: BundledLambdaFunctionProps) { | |
| if (props.runtime && props.runtime.family !== lambda.RuntimeFamily.NODEJS) { | |
| throw new Error('Only `NODEJS` runtimes are supported.'); | |
| } | |
| const entry = path.resolve(findEntry(id)); | |
| const runtime = props.runtime ?? lambda.Runtime.NODEJS_18_X; | |
| const handler = props.handler ?? 'index.handler'; | |
| const code = lambda.Code.fromAsset(entry); | |
| super(scope, id, { | |
| ...props, | |
| runtime, | |
| code, | |
| handler, | |
| }); | |
| } | |
| } | |
| /** | |
| * Searches for pre-bundled handler file | |
| */ | |
| function findEntry(id: string): string { | |
| // CDK is launcehd from here - the monorepo root | |
| const rootDir = process.cwd(); | |
| // The file where the Lambda Construct was created from | |
| const definingFile = path.parse(findDefiningFile()); | |
| const relativeDirectory = path.relative(rootDir, definingFile.dir); | |
| // Should be the path to the actual Lambda directory, bundled | |
| const bundledLambdaDirectory = path.join( | |
| rootDir, | |
| 'dist', | |
| 'lambda', | |
| relativeDirectory, | |
| `${definingFile.name}.${id}`, | |
| ); | |
| if (!fs.existsSync(bundledLambdaDirectory)) { | |
| throw new Error(`Cannot find handler directory ${bundledLambdaDirectory}`); | |
| } | |
| return bundledLambdaDirectory; | |
| } | |
| /** | |
| * Finds the name of the file where the `BundledLambdaFunction` is defined | |
| */ | |
| function findDefiningFile(): string { | |
| let definingIndex; | |
| const sites = callsites(); | |
| for (const [index, site] of sites.entries()) { | |
| if (site.getFunctionName() === 'BundledLambdaFunction') { | |
| // The next site is the site where the BundledLambdaFunction was created | |
| definingIndex = index + 1; | |
| break; | |
| } | |
| } | |
| if (!definingIndex || !sites[definingIndex]) { | |
| throw new Error('Cannot find defining file.'); | |
| } | |
| return sites[definingIndex].getFileName(); | |
| } | |
| function callsites(): CallSite[] { | |
| const _prepareStackTrace = Error.prepareStackTrace; | |
| Error.prepareStackTrace = (_, stack) => stack; | |
| const stack = new Error().stack?.slice(1); | |
| Error.prepareStackTrace = _prepareStackTrace; | |
| return stack as unknown as CallSite[]; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "name": "core-cloud", | |
| "$schema": "../../../node_modules/nx/schemas/project-schema.json", | |
| "sourceRoot": "libs/core/cloud/src", | |
| "projectType": "library", | |
| "targets": { | |
| "lambda": { | |
| "executor": "@nrwl/esbuild:esbuild", | |
| "outputs": ["{options.outputPath}"], | |
| "options": { | |
| "main": "libs/core/cloud/src/index.ts", | |
| "tsConfig": "libs/core/cloud/tsconfig.lib.json", | |
| "outputPath": "dist/lambda/libs/core/cloud/src", | |
| "skipTypeCheck": true, | |
| "minify": true, | |
| "sourcemap": true, | |
| "bundle": true, | |
| "target": "node18", | |
| "format": ["cjs"], | |
| "esbuildOptions": { | |
| "outExtension": { | |
| ".js": ".js" | |
| } | |
| }, | |
| "additionalEntryPoints": [ | |
| "libs/core/cloud/src/lib/cloud-front.set-cookies.fn/index.ts", | |
| "libs/core/cloud/src/lib/cloud-front.signing-key-rotation.fn/index.ts", | |
| "libs/core/cloud/src/lib/data-neo4j.invoke.fn/index.ts", | |
| "libs/core/cloud/src/lib/identity-management.custom-message.fn/index.ts", | |
| "libs/core/cloud/src/lib/identity-management.post-confirmation.fn/index.ts", | |
| "libs/core/cloud/src/lib/identity-management.pre-sign-up.fn/index.ts" | |
| ] | |
| } | |
| } | |
| }, | |
| "tags": [] | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment