Skip to content

Commit

Permalink
feat(core): free inactive Lambda resources
Browse files Browse the repository at this point in the history
  • Loading branch information
Inqnuam committed Mar 24, 2023
1 parent b09701c commit 1149f12
Show file tree
Hide file tree
Showing 25 changed files with 492 additions and 183 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ yarn-error.log
**/.DS_Store
/express
/router.d.ts
/router.js
/router.js
TODO.md
2 changes: 0 additions & 2 deletions TODO.md

This file was deleted.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "serverless-aws-lambda",
"version": "4.4.0",
"description": "AWS Application Load Balancer and API Gateway - Lambda dev tool for Serverless. Allows Express synthax in handlers. Supports packaging, local invoking and offline real ALB and APG lambda server mocking.",
"version": "4.4.1",
"description": "AWS Application Load Balancer and API Gateway - Lambda dev tool for Serverless. Allows Express synthax in handlers. Supports packaging, local invoking and offline ALB, APG, S3, SNS, SQS, DynamoDB Stream server mocking.",
"author": "Inqnuam",
"license": "MIT",
"homepage": "https://github.com/inqnuam/serverless-aws-lambda",
Expand Down
59 changes: 30 additions & 29 deletions resources/esbuild.md

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions resources/sqs.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

### Description

Plugin for serverless-aws-lambda to trigger locally your sqs event defined lambdas automatically.
Plugin for serverless-aws-lambda to trigger locally your sqs event defined lambdas automatically.
Local Queues are created based on your serverless.yml.
To define default and/or override Queue attributes see [Plugin configs](../src/plugins/sqs/types.ts).
To define default and/or override Queue attributes see [Plugin configs](../src/plugins/sqs/types.ts).
Currently FIFO queues are considered as Standart.

### Installation

Expand All @@ -22,7 +23,7 @@ module.exports = defineConfig({

### Supported Requests

supports both AWS SDK and CLI requests.
supports both AWS SDK, CLI and raw low-level API requests.

✅ supported
🌕 planned
Expand All @@ -36,7 +37,7 @@ supports both AWS SDK and CLI requests.
- ✅ DeleteMessageBatch
- ✅ DeleteQueue
- 🌕 GetQueueAttributes
- 🌕 GetQueueUrl
- GetQueueUrl
- 🌕 ListDeadLetterSourceQueues
- ✅ ListQueues
- ✅ ListQueueTags
Expand Down
4 changes: 1 addition & 3 deletions src/defineConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export interface ClientConfigParams {
isPackaging: boolean;
setEnv: (lambdaName: string, key: string, value: string) => void;
stage: string;
port: number;
esbuild: PluginBuild["esbuild"];
config: Config;
options: Options;
Expand Down Expand Up @@ -118,7 +117,7 @@ function defineConfig(options: Options) {
}
return async function config(
this: ClientConfigParams,
{ stop, lambdas, isDeploying, isPackaging, setEnv, stage, port, esbuild, serverless, resources }: ClientConfigParams
{ stop, lambdas, isDeploying, isPackaging, setEnv, stage, esbuild, serverless, resources }: ClientConfigParams
): Promise<Omit<Config, "config" | "options">> {
let config: Config = {
esbuild: options.esbuild ?? {},
Expand All @@ -136,7 +135,6 @@ function defineConfig(options: Options) {
isPackaging,
setEnv,
stage,
port,
esbuild,
serverless,
options,
Expand Down
6 changes: 1 addition & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ class ServerlessAwsLambda extends Daemon {
serverless: Serverless;
options: any;
pluginConfig: any;
tsconfig: any;
commands: any;
hooks: any;
esBuildConfig: any;
Expand Down Expand Up @@ -277,10 +276,8 @@ class ServerlessAwsLambda extends Daemon {
try {
if (this.customBuildCallback) {
await this.customBuildCallback(result, true);
await this.load(this.#lambdas);
} else {
await this.load(this.#lambdas);
}
await this.load(this.#lambdas);
} catch (error) {
console.error(error);
}
Expand Down Expand Up @@ -485,7 +482,6 @@ class ServerlessAwsLambda extends Daemon {
setEnv: (n: string, k: string, v: string) => {
this.setEnv(n, k, v);
},
port: ServerlessAwsLambda.PORT,
stage: this.options.stage ?? this.serverless.service.provider.stage ?? "dev",
esbuild: esbuild,
serverless: this.serverless,
Expand Down
6 changes: 5 additions & 1 deletion src/lambda/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ const getMiddleware = (controllers: (RouteController | RouteMiddleware | Functio
return controllers[0];
}
};
const isProd = process.env.NODE_ENV == "production";
const { IS_LOCAL, NODE_ENV } = process.env;
const isProd = NODE_ENV == "production";

class Route extends Function {
controllers: (RouteController | RouteMiddleware | Function)[] = [];
Expand Down Expand Up @@ -70,6 +71,9 @@ class Route extends Function {
if (foundErrorHandler) {
await foundErrorHandler(error, req, res, next);
} else {
if (IS_LOCAL) {
console.log(error);
}
resolve({ statusCode: 500, body: "Internal Server Error" });
}
} catch (err) {
Expand Down
48 changes: 46 additions & 2 deletions src/lib/esbuild/mergeEsbuildConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,58 @@ export const mergeEsbuildConfig = (esBuildConfig: BuildOptions, customEsBuildCon
esBuildConfig.external!.push(...customEsBuildConfig.external);
}

if (typeof customEsBuildConfig.sourcemap == "boolean") {
if ("sourcemap" in customEsBuildConfig) {
esBuildConfig.sourcemap = customEsBuildConfig.sourcemap;
}

if (typeof customEsBuildConfig.sourceRoot == "string") {
esBuildConfig.sourceRoot = customEsBuildConfig.sourceRoot;
}

if ("sourcesContent" in customEsBuildConfig) {
esBuildConfig.sourcesContent = customEsBuildConfig.sourcesContent;
}

if (typeof customEsBuildConfig.minify == "boolean") {
esBuildConfig.minify = customEsBuildConfig.minify;
}

if (typeof customEsBuildConfig.minifyWhitespace == "boolean") {
esBuildConfig.minifyWhitespace = customEsBuildConfig.minifyWhitespace;
}

if (typeof customEsBuildConfig.minifyIdentifiers == "boolean") {
esBuildConfig.minifyIdentifiers = customEsBuildConfig.minifyIdentifiers;
}

if (typeof customEsBuildConfig.minifySyntax == "boolean") {
esBuildConfig.minifySyntax = customEsBuildConfig.minifySyntax;
}

if (typeof customEsBuildConfig.jsx == "string") {
esBuildConfig.jsx = customEsBuildConfig.jsx;
}

if (typeof customEsBuildConfig.jsxFactory == "string") {
esBuildConfig.jsxFactory = customEsBuildConfig.jsxFactory;
}

if (typeof customEsBuildConfig.jsxFragment == "string") {
esBuildConfig.jsxFragment = customEsBuildConfig.jsxFragment;
}

if (typeof customEsBuildConfig.jsxImportSource == "string") {
esBuildConfig.jsxImportSource = customEsBuildConfig.jsxImportSource;
}

if ("jsxDev" in customEsBuildConfig) {
esBuildConfig.jsxDev = customEsBuildConfig.jsxDev;
}

if ("jsxSideEffects" in customEsBuildConfig) {
esBuildConfig.jsxSideEffects = customEsBuildConfig.jsxSideEffects;
}

if (typeof customEsBuildConfig.outdir == "string") {
esBuildConfig.outdir = customEsBuildConfig.outdir;
}
Expand All @@ -25,7 +69,7 @@ export const mergeEsbuildConfig = (esBuildConfig: BuildOptions, customEsBuildCon
esBuildConfig.outbase = customEsBuildConfig.outbase;
}

if (typeof customEsBuildConfig.target == "string") {
if (typeof customEsBuildConfig.target == "string" || Array.isArray(customEsBuildConfig.target)) {
esBuildConfig.target = customEsBuildConfig.target;
}

Expand Down
48 changes: 46 additions & 2 deletions src/lib/esbuild/parseCustomEsbuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,58 @@ export const parseCustomEsbuild = (customConfig: BuildOptions) => {
customEsBuild.external = customConfig.external;
}

if (typeof customConfig.sourcemap == "boolean") {
if ("sourcemap" in customConfig) {
customEsBuild.sourcemap = customConfig.sourcemap;
}

if (typeof customConfig.sourceRoot == "string") {
customEsBuild.sourceRoot = customConfig.sourceRoot;
}

if ("sourcesContent" in customConfig) {
customEsBuild.sourcesContent = customConfig.sourcesContent;
}

if (typeof customConfig.minify == "boolean") {
customEsBuild.minify = customConfig.minify;
}

if (typeof customConfig.minifyWhitespace == "boolean") {
customEsBuild.minifyWhitespace = customConfig.minifyWhitespace;
}

if (typeof customConfig.minifyIdentifiers == "boolean") {
customEsBuild.minifyIdentifiers = customConfig.minifyIdentifiers;
}

if (typeof customConfig.minifySyntax == "boolean") {
customEsBuild.minifySyntax = customConfig.minifySyntax;
}

if (typeof customConfig.jsx == "string") {
customEsBuild.jsx = customConfig.jsx;
}

if (typeof customConfig.jsxFactory == "string") {
customEsBuild.jsxFactory = customConfig.jsxFactory;
}

if (typeof customConfig.jsxFragment == "string") {
customEsBuild.jsxFragment = customConfig.jsxFragment;
}

if (typeof customConfig.jsxImportSource == "string") {
customEsBuild.jsxImportSource = customConfig.jsxImportSource;
}

if ("jsxDev" in customConfig) {
customEsBuild.jsxDev = customConfig.jsxDev;
}

if ("jsxSideEffects" in customConfig) {
customEsBuild.jsxSideEffects = customConfig.jsxSideEffects;
}

if (typeof customConfig.outdir == "string") {
customEsBuild.outdir = customConfig.outdir;
}
Expand All @@ -26,7 +70,7 @@ export const parseCustomEsbuild = (customConfig: BuildOptions) => {
customEsBuild.outbase = customConfig.outbase;
}

if (typeof customConfig.target == "string") {
if (typeof customConfig.target == "string" || Array.isArray(customConfig.target)) {
customEsBuild.target = customConfig.target;
}

Expand Down
17 changes: 16 additions & 1 deletion src/lib/parseEvents/ddbStream.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
import { log } from "../utils/colorize";
import { parseDestination } from "./index";
import type { IDestination } from "./index";

export interface IDdbEvent {
TableName: string;
StreamEnabled: boolean;
StreamViewType?: string;
batchSize?: number;
batchWindow?: number;
maximumRecordAgeInSeconds?: number;
maximumRetryAttempts?: number;
bisectBatchOnFunctionError?: boolean;
functionResponseType?: string;
filterPatterns?: any;
onFailure?: IDestination;
}

enum StreamProps {
batchSize = 100,
Expand Down Expand Up @@ -50,7 +65,7 @@ const getStreamTableInfoFromTableName = (ddbStreamTables: any, tableName: string

return foundInfo ?? {};
};
export const parseDdbStreamDefinitions = (Outputs: any, resources: any, event: any) => {
export const parseDdbStreamDefinitions = (Outputs: any, resources: any, event: any): IDdbEvent | undefined => {
if (!event || Object.keys(event)[0] !== "stream" || (event.stream.type && event.stream.type != "dynamodb")) {
return;
}
Expand Down
23 changes: 22 additions & 1 deletion src/lib/parseEvents/endpoints.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
import { HttpMethod } from "../server/handlers";
import { LambdaEndpoint } from "../runtime/lambdaMock";

export interface LambdaEndpoint {
kind: "alb" | "apg";
paths: string[];
methods: HttpMethod[];
async?: boolean;
multiValueHeaders?: boolean;
version?: 1 | 2;
header?: {
name: string;
values: string[];
};
query?: {
[key: string]: string;
};
}
export const parseEndpoints = (event: any): LambdaEndpoint | null => {
const supportedEvents = ["http", "httpApi", "alb"];

Expand Down Expand Up @@ -29,6 +43,13 @@ export const parseEndpoints = (event: any): LambdaEndpoint | null => {
if (event.alb.multiValueHeaders) {
parsendEvent.multiValueHeaders = true;
}
if (event.alb.conditions.header) {
parsendEvent.header = event.alb.conditions.header;
}

if (event.alb.conditions.query) {
parsendEvent.query = event.alb.conditions.query;
}
} else if (event.http || event.httpApi) {
if (event.http) {
parsendEvent.version = 1;
Expand Down
8 changes: 5 additions & 3 deletions src/lib/parseEvents/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { IDestination } from "../runtime/lambdaMock";
import { LambdaEndpoint } from "../runtime/lambdaMock";
import type { LambdaEndpoint } from "./endpoints";
import { parseEndpoints } from "./endpoints";
import { parseSns } from "./sns";
import { parseDdbStreamDefinitions } from "./ddbStream";
Expand All @@ -9,7 +8,10 @@ import { parseSqs } from "./sqs";

const supportedServices: IDestination["kind"][] = ["lambda", "sns", "sqs"];
type arn = [string, string, IDestination["kind"], string, string, string, string];

export interface IDestination {
kind: "lambda" | "sns" | "sqs";
name: string;
}
export const parseEvents = (events: any[], Outputs: any, resources: any) => {
const endpoints: LambdaEndpoint[] = [];
const sns: any[] = [];
Expand Down
8 changes: 6 additions & 2 deletions src/lib/parseEvents/s3.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { log } from "../utils/colorize";

export const parseS3 = (event: any) => {
export interface IS3Event {
bucket: string;
type: [string, string];
rules?: any[];
}
export const parseS3 = (event: any): IS3Event | undefined => {
if (!event || !event.s3) {
return;
}
Expand Down
12 changes: 10 additions & 2 deletions src/lib/parseEvents/sns.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { log } from "../utils/colorize";

export interface ISnsEvent {
name: string;
arn?: string;
topicName?: string;
displayName?: string;
filterScope?: "MessageAttributes" | "MessageBody";
filter?: any;
redrivePolicy?: string;
}
const onlySqsAllowed = "SNS redrivePolicy destination could only be a SQS service";

const parseTopicNameFromObject = (resources: any, Outputs: any, obj: any) => {
Expand Down Expand Up @@ -32,7 +40,7 @@ const parseTopicNameFromObject = (resources: any, Outputs: any, obj: any) => {
}
};

export const parseSns = (Outputs: any, resources: any, event: any) => {
export const parseSns = (Outputs: any, resources: any, event: any): ISnsEvent | undefined => {
if (!event.sns) {
return;
}
Expand Down
Loading

0 comments on commit 1149f12

Please sign in to comment.