Skip to content

Commit

Permalink
more complete middy middlewares with upgraded typing
Browse files Browse the repository at this point in the history
  • Loading branch information
antoinewg committed Feb 13, 2024
1 parent aa24d91 commit 767861d
Show file tree
Hide file tree
Showing 10 changed files with 376 additions and 51 deletions.
67 changes: 63 additions & 4 deletions packages/helpers/middify.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,66 @@
import middy from "@middy/core";
import middy, { MiddyfiedHandler } from "@middy/core";
import middyJsonBodyParser from "@middy/http-json-body-parser";
import type { Handler } from "aws-lambda";
import cors from "@middy/http-cors";
import validator from "@middy/validator";
import { transpileSchema } from "@middy/validator/transpile";
import httpErrorHandler from "@middy/http-error-handler";
import httpEventNormalizer from "@middy/http-event-normalizer";

export const middyfy = <TEvent, TResult>(handler: Handler<TEvent, TResult>) => {
return middy<TEvent, TResult>(handler).use(middyJsonBodyParser());
import type {
APIGatewayProxyEvent as ProxyEvent,
APIGatewayProxyResult,
Context,
Handler as AWSHandler,
} from "aws-lambda";
import type { FromSchema } from "json-schema-to-ts";

// Taken from https://github.com/middyjs/middy/issues/316#issuecomment-1013351805
// Event is an APIGatewayProxyEvent with a typed body, pathParameters and queryStringParameters which depends on http-json-body-parser & json-schema-to-ts
// queryStringParameters and multiValueQueryStringParameters is non-nullable as we use http-event-normalizer
export interface Event<
TBody extends Record<string, unknown> | null,
TPathParameters extends Record<string, unknown> | null,
TQueryStringParameters extends Record<string, unknown> | null
> extends Omit<
ProxyEvent,
"body" | "pathParameters" | "queryStringParameters"
> {
body: TBody extends Record<string, unknown> ? FromSchema<TBody> : null;
pathParameters: TPathParameters extends Record<string, unknown>
? FromSchema<TPathParameters>
: null;
queryStringParameters: TQueryStringParameters extends Record<string, unknown>
? FromSchema<TQueryStringParameters>
: null;
multiValueQueryStringParameters: NonNullable<
ProxyEvent["multiValueQueryStringParameters"]
>;
}

// We are making use of http-response-serializer
interface Result extends Omit<APIGatewayProxyResult, "body"> {
body: string | Record<string, unknown>;
}

// Handler type which gives us proper types on our event based on TBody and TPathParameters which are JSON schemas
export type CustomHandler<
TBody extends Record<string, unknown> | null = null,
TPathParameters extends Record<string, unknown> | null = null,
TQueryStringParameters extends Record<string, unknown> | null = null
> = AWSHandler<Event<TBody, TPathParameters, TQueryStringParameters>, Result>;

// TODO: find a way to remove the couple of `any` here. Validation and typing are still working though
export const middyfy = (
handler: any,
schema: Record<string, unknown> | null = null
): MiddyfiedHandler<Event<never, never, never>, Result, Error, Context> => {
const wrapper: any = middy(handler)
.use(middyJsonBodyParser())
.use(httpEventNormalizer());

if (schema) {
wrapper.use(validator({ eventSchema: transpileSchema(schema) }));
}

return wrapper.use(cors()).use(httpErrorHandler({}));
};
6 changes: 5 additions & 1 deletion packages/helpers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@
},
"dependencies": {
"@middy/core": "^5.2.4",
"@middy/http-cors": "^5.2.4",
"@middy/http-error-handler": "^5.2.4",
"@middy/http-event-normalizer": "^5.2.4",
"@middy/http-json-body-parser": "^5.2.4",
"@middy/util": "^5.2.4",
"@middy/http-json-body-parser": "^5.2.4"
"@middy/validator": "^5.2.4"
},
"devDependencies": {
"@types/aws-lambda": "^8.10.133",
Expand Down
16 changes: 0 additions & 16 deletions packages/helpers/response.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,3 @@
import type {
APIGatewayProxyEvent,
APIGatewayProxyResult,
Handler,
} from "aws-lambda";
import type { FromSchema } from "json-schema-to-ts";

export type ValidatedAPIGatewayProxyEvent<S extends object> = Omit<
APIGatewayProxyEvent,
"body"
> & { body: FromSchema<S> };
export type ValidatedEventAPIGatewayProxyEvent<S extends object> = Handler<
ValidatedAPIGatewayProxyEvent<S>,
APIGatewayProxyResult
>;

export const formatJSONResponse = (response: Record<string, unknown>) => {
return {
statusCode: 200,
Expand Down
Loading

0 comments on commit 767861d

Please sign in to comment.