Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@middy/core

Package Overview
Dependencies
Maintainers
3
Versions
225
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@middy/core - npm Package Compare versions

Comparing version 5.0.0-alpha.0 to 5.0.0-alpha.1

151

index.d.ts

@@ -9,3 +9,5 @@ import {

declare type PluginHookWithMiddlewareName = (middlewareName: string) => void
declare type PluginHookPromise = (request: Request) => Promise<unknown> | unknown
declare type PluginHookPromise = (
request: Request
) => Promise<unknown> | unknown

@@ -23,5 +25,12 @@ interface PluginObject {

requestEnd?: PluginHookPromise
streamifyResponse?: Boolean
}
export interface Request<TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> {
export interface Request<
TEvent = any,
TResult = any,
TErr = Error,
TContext extends LambdaContext = LambdaContext,
TInternal extends Record<string, unknown> = {}
> {
event: TEvent

@@ -31,13 +40,23 @@ context: TContext

error: TErr | null
internal: {
[key: string]: any
}
internal: TInternal
}
declare type MiddlewareFn<TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> = (request: Request<TEvent, TResult, TErr, TContext>) => any
declare type MiddlewareFn<
TEvent = any,
TResult = any,
TErr = Error,
TContext extends LambdaContext = LambdaContext,
TInternal extends Record<string, unknown> = {}
> = (request: Request<TEvent, TResult, TErr, TContext, TInternal>) => any
export interface MiddlewareObj<TEvent = unknown, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> {
before?: MiddlewareFn<TEvent, TResult, TErr, TContext>
after?: MiddlewareFn<TEvent, TResult, TErr, TContext>
onError?: MiddlewareFn<TEvent, TResult, TErr, TContext>
export interface MiddlewareObj<
TEvent = unknown,
TResult = any,
TErr = Error,
TContext extends LambdaContext = LambdaContext,
TInternal extends Record<string, unknown> = {}
> {
before?: MiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
after?: MiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
onError?: MiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
}

@@ -47,29 +66,88 @@

// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
type MiddyInputHandler<TEvent, TResult, TContext extends LambdaContext = LambdaContext> = (event: TEvent, context: TContext, callback: LambdaCallback<TResult>) => void | Promise<TResult>
type MiddyInputPromiseHandler<TEvent, TResult, TContext extends LambdaContext = LambdaContext> = (event: TEvent, context: TContext,) => Promise<TResult>
type MiddyInputHandler<
TEvent,
TResult,
TContext extends LambdaContext = LambdaContext
> = (
event: TEvent,
context: TContext,
callback: LambdaCallback<TResult>
) => // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
void | Promise<TResult> | TResult
type MiddyInputPromiseHandler<
TEvent,
TResult,
TContext extends LambdaContext = LambdaContext
> = (event: TEvent, context: TContext) => Promise<TResult>
export interface MiddyfiedHandler<TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> extends MiddyInputHandler<TEvent, TResult, TContext>,
export interface MiddyfiedHandler<
TEvent = any,
TResult = any,
TErr = Error,
TContext extends LambdaContext = LambdaContext,
TInternal extends Record<string, unknown> = {}
> extends MiddyInputHandler<TEvent, TResult, TContext>,
MiddyInputPromiseHandler<TEvent, TResult, TContext> {
use: UseFn<TEvent, TResult, TErr, TContext>
before: AttachMiddlewareFn<TEvent, TResult, TErr, TContext>
after: AttachMiddlewareFn<TEvent, TResult, TErr, TContext>
onError: AttachMiddlewareFn<TEvent, TResult, TErr, TContext>
handler: <TAdditional>(handler: MiddlewareHandler<LambdaHandler<TEvent & TAdditional, TResult>, TContext>) => MiddyfiedHandler<TEvent, TResult, TErr, TContext>
use: UseFn<TEvent, TResult, TErr, TContext, TInternal>
before: AttachMiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
after: AttachMiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
onError: AttachMiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
handler: <TAdditional>(
handler: MiddlewareHandler<
LambdaHandler<TEvent & TAdditional, TResult>,
TContext
>
) => MiddyfiedHandler<TEvent, TResult, TErr, TContext, TInternal>
}
declare type AttachMiddlewareFn<TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> =
(middleware: MiddlewareFn<TEvent, TResult, TErr, TContext>) => MiddyfiedHandler<TEvent, TResult, TErr, TContext>
declare type AttachMiddlewareFn<
TEvent = any,
TResult = any,
TErr = Error,
TContext extends LambdaContext = LambdaContext,
TInternal extends Record<string, unknown> = {}
> = (
middleware: MiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
) => MiddyfiedHandler<TEvent, TResult, TErr, TContext, TInternal>
declare type AttachMiddlewareObj<TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> =
(middleware: MiddlewareObj<TEvent, TResult, TErr, TContext>) => MiddyfiedHandler<TEvent, TResult, TErr, TContext>
declare type AttachMiddlewareObj<
TEvent = any,
TResult = any,
TErr = Error,
TContext extends LambdaContext = LambdaContext,
TInternal extends Record<string, unknown> = {}
> = (
middleware: MiddlewareObj<TEvent, TResult, TErr, TContext, TInternal>
) => MiddyfiedHandler<TEvent, TResult, TErr, TContext, TInternal>
declare type UseFn<TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> =
<TMiddleware extends MiddlewareObj<any, any, Error, any>>(middlewares: TMiddleware | TMiddleware[]) => TMiddleware extends MiddlewareObj<infer TMiddlewareEvent, any, Error, infer TMiddlewareContext>
? MiddyfiedHandler<TMiddlewareEvent & TEvent, TResult, TErr, TMiddlewareContext & TContext> // always true
: never
declare type UseFn<
TEvent = any,
TResult = any,
TErr = Error,
TContext extends LambdaContext = LambdaContext,
TInternal extends Record<string, unknown> = {}
> = <TMiddleware extends MiddlewareObj<any, any, Error, any, any>>(
middlewares: TMiddleware | TMiddleware[]
) => TMiddleware extends MiddlewareObj<
infer TMiddlewareEvent,
any,
Error,
infer TMiddlewareContext,
infer TMiddlewareInternal
>
? MiddyfiedHandler<
TMiddlewareEvent & TEvent,
TResult,
TErr,
TMiddlewareContext & TContext,
TMiddlewareInternal & TInternal
> // always true
: never
declare type MiddlewareHandler<THandler extends LambdaHandler<any, any>, TContext extends LambdaContext = LambdaContext> =
THandler extends LambdaHandler<infer TEvent, infer TResult> // always true
? MiddyInputHandler<TEvent, TResult, TContext>
: never
declare type MiddlewareHandler<
THandler extends LambdaHandler<any, any>,
TContext extends LambdaContext = LambdaContext
> = THandler extends LambdaHandler<infer TEvent, infer TResult> // always true
? MiddyInputHandler<TEvent, TResult, TContext>
: never

@@ -81,3 +159,14 @@ /**

*/
declare function middy<TEvent = unknown, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> (handler?: MiddlewareHandler<LambdaHandler<TEvent, TResult>, TContext>, plugin?: PluginObject): MiddyfiedHandler<TEvent, TResult, TErr, TContext>
declare function middy<
TEvent = unknown,
TResult = any,
TErr = Error,
TContext extends LambdaContext = LambdaContext,
TInternal extends Record<string, unknown> = {}
> (
handler?:
| MiddlewareHandler<LambdaHandler<TEvent, TResult>, TContext>
| PluginObject,
plugin?: PluginObject
): MiddyfiedHandler<TEvent, TResult, TErr, TContext, TInternal>

@@ -84,0 +173,0 @@ declare namespace middy {

@@ -1,128 +0,209 @@

import { setTimeout } from 'node:timers/promises';
const defaultLambdaHandler = ()=>{};
/* global awslambda */
import { Readable } from 'node:stream'
import { pipeline } from 'node:stream/promises'
import { setTimeout } from 'node:timers/promises'
const defaultLambdaHandler = () => {}
const defaultPlugin = {
timeoutEarlyInMillis: 5,
timeoutEarlyResponse: ()=>{
throw new Error('Timeout');
timeoutEarlyInMillis: 5,
timeoutEarlyResponse: () => {
const err = new Error('[AbortError]: The operation was aborted.', {
cause: { package: '@middy/core' }
})
err.name = 'TimeoutError'
throw err
},
streamifyResponse: false // Deprecate need for this when AWS provides a flag for when it's looking for it
}
const middy = (lambdaHandler = defaultLambdaHandler, plugin = {}) => {
// Allow base handler to be set using .handler()
if (typeof lambdaHandler !== 'function') {
plugin = lambdaHandler
lambdaHandler = defaultLambdaHandler
}
plugin = { ...defaultPlugin, ...plugin }
plugin.timeoutEarly = plugin.timeoutEarlyInMillis > 0
plugin.beforePrefetch?.()
const beforeMiddlewares = []
const afterMiddlewares = []
const onErrorMiddlewares = []
const middyHandler = (event = {}, context = {}) => {
plugin.requestStart?.()
const request = {
event,
context,
response: undefined,
error: undefined,
internal: plugin.internal ?? {}
}
};
const middy = (lambdaHandler = defaultLambdaHandler, plugin = {})=>{
if (typeof lambdaHandler !== 'function') {
plugin = lambdaHandler;
lambdaHandler = defaultLambdaHandler;
return runRequest(
request,
[...beforeMiddlewares],
lambdaHandler,
[...afterMiddlewares],
[...onErrorMiddlewares],
plugin
)
}
const middy = plugin.streamifyResponse
? awslambda.streamifyResponse(async (event, responseStream, context) => {
const handlerResponse = await middyHandler(event, context)
let handlerBody = handlerResponse
if (handlerResponse.statusCode) {
handlerBody = handlerResponse.body ?? ''
responseStream = awslambda.HttpResponseStream.from(
responseStream,
handlerResponse
)
}
// Source @datastream/core (MIT)
let handlerStream
if (handlerBody._readableState) {
handlerStream = handlerBody
} else if (typeof handlerBody === 'string') {
function * iterator (input) {
const size = 16384 // 16 * 1024 // Node.js default
let position = 0
const length = input.length
while (position < length) {
yield input.substring(position, position + size)
position += size
}
}
handlerStream = Readable.from(iterator(handlerBody))
}
if (!handlerStream) {
throw new Error('handler response not a ReadableStream')
}
await pipeline(handlerStream, responseStream)
})
: middyHandler
middy.use = (middlewares) => {
if (!Array.isArray(middlewares)) {
middlewares = [middlewares]
}
plugin = {
...defaultPlugin,
...plugin
};
plugin.timeoutEarly = plugin.timeoutEarlyInMillis > 0;
plugin.beforePrefetch?.();
const beforeMiddlewares = [];
const afterMiddlewares = [];
const onErrorMiddlewares = [];
const middy = (event = {}, context = {})=>{
plugin.requestStart?.();
const request = {
event,
context,
response: undefined,
error: undefined,
internal: plugin.internal ?? {}
};
return runRequest(request, [
...beforeMiddlewares
], lambdaHandler, [
...afterMiddlewares
], [
...onErrorMiddlewares
], plugin);
};
middy.use = (middlewares)=>{
if (!Array.isArray(middlewares)) {
middlewares = [
middlewares
];
}
for (const middleware of middlewares){
const { before , after , onError } = middleware;
if (!before && !after && !onError) {
throw new Error('Middleware must be an object containing at least one key among "before", "after", "onError"');
}
if (before) middy.before(before);
if (after) middy.after(after);
if (onError) middy.onError(onError);
}
return middy;
};
middy.before = (beforeMiddleware)=>{
beforeMiddlewares.push(beforeMiddleware);
return middy;
};
middy.after = (afterMiddleware)=>{
afterMiddlewares.unshift(afterMiddleware);
return middy;
};
middy.onError = (onErrorMiddleware)=>{
onErrorMiddlewares.unshift(onErrorMiddleware);
return middy;
};
middy.handler = (replaceLambdaHandler)=>{
lambdaHandler = replaceLambdaHandler;
return middy;
};
return middy;
};
const runRequest = async (request, beforeMiddlewares, lambdaHandler, afterMiddlewares, onErrorMiddlewares, plugin)=>{
let timeoutAbort;
const timeoutEarly = plugin.timeoutEarly && request.context.getRemainingTimeInMillis;
for (const middleware of middlewares) {
const { before, after, onError } = middleware
if (!before && !after && !onError) {
throw new Error(
'Middleware must be an object containing at least one key among "before", "after", "onError"'
)
}
if (before) middy.before(before)
if (after) middy.after(after)
if (onError) middy.onError(onError)
}
return middy
}
// Inline Middlewares
middy.before = (beforeMiddleware) => {
beforeMiddlewares.push(beforeMiddleware)
return middy
}
middy.after = (afterMiddleware) => {
afterMiddlewares.unshift(afterMiddleware)
return middy
}
middy.onError = (onErrorMiddleware) => {
onErrorMiddlewares.unshift(onErrorMiddleware)
return middy
}
middy.handler = (replaceLambdaHandler) => {
lambdaHandler = replaceLambdaHandler
return middy
}
return middy
}
const runRequest = async (
request,
beforeMiddlewares,
lambdaHandler,
afterMiddlewares,
onErrorMiddlewares,
plugin
) => {
let timeoutAbort
const timeoutEarly =
plugin.timeoutEarly && request.context.getRemainingTimeInMillis // disable when AWS context missing (tests, containers)
try {
await runMiddlewares(request, beforeMiddlewares, plugin)
// Check if before stack hasn't exit early
if (typeof request.response === 'undefined') {
plugin.beforeHandler?.()
const handlerAbort = new AbortController()
if (timeoutEarly) timeoutAbort = new AbortController()
request.response = await Promise.race([
lambdaHandler(request.event, request.context, {
signal: handlerAbort.signal
}),
timeoutEarly
? setTimeout(
request.context.getRemainingTimeInMillis() -
plugin.timeoutEarlyInMillis,
undefined,
{ signal: timeoutAbort.signal }
).then(() => {
handlerAbort.abort()
return plugin.timeoutEarlyResponse()
})
: Promise.race([])
])
timeoutAbort?.abort() // lambdaHandler may not be a promise
plugin.afterHandler?.()
await runMiddlewares(request, afterMiddlewares, plugin)
}
} catch (e) {
timeoutAbort?.abort() // timeout should be aborted on errors
// Reset response changes made by after stack before error thrown
request.response = undefined
request.error = e
try {
await runMiddlewares(request, beforeMiddlewares, plugin);
if (typeof request.response === 'undefined') {
plugin.beforeHandler?.();
const handlerAbort = new AbortController();
if (timeoutEarly) timeoutAbort = new AbortController();
request.response = await Promise.race([
lambdaHandler(request.event, request.context, {
signal: handlerAbort.signal
}),
timeoutEarly ? setTimeout(request.context.getRemainingTimeInMillis() - plugin.timeoutEarlyInMillis, undefined, {
signal: timeoutAbort.signal
}).then(()=>{
handlerAbort.abort();
return plugin.timeoutEarlyResponse();
}) : Promise.race([])
]);
timeoutAbort?.abort();
plugin.afterHandler?.();
await runMiddlewares(request, afterMiddlewares, plugin);
}
await runMiddlewares(request, onErrorMiddlewares, plugin)
} catch (e) {
timeoutAbort?.abort();
request.response = undefined;
request.error = e;
try {
await runMiddlewares(request, onErrorMiddlewares, plugin);
} catch (e) {
e.originalError = request.error;
request.error = e;
throw request.error;
}
if (typeof request.response === 'undefined') throw request.error;
} finally{
await plugin.requestEnd?.(request);
// Save error that wasn't handled
e.originalError = request.error
request.error = e
throw request.error
}
return request.response;
};
const runMiddlewares = async (request, middlewares, plugin)=>{
for (const nextMiddleware of middlewares){
plugin.beforeMiddleware?.(nextMiddleware.name);
const res = await nextMiddleware(request);
plugin.afterMiddleware?.(nextMiddleware.name);
if (typeof res !== 'undefined') {
request.response = res;
return;
}
// Catch if onError stack hasn't handled the error
if (typeof request.response === 'undefined') throw request.error
} finally {
await plugin.requestEnd?.(request)
}
return request.response
}
const runMiddlewares = async (request, middlewares, plugin) => {
for (const nextMiddleware of middlewares) {
plugin.beforeMiddleware?.(nextMiddleware.name)
const res = await nextMiddleware(request)
plugin.afterMiddleware?.(nextMiddleware.name)
// short circuit chaining and respond early
if (typeof res !== 'undefined') {
request.response = res
return
}
};
export default middy;
}
}
export default middy
{
"name": "@middy/core",
"version": "5.0.0-alpha.0",
"version": "5.0.0-alpha.1",
"description": "🛵 The stylish Node.js middleware engine for AWS Lambda (core package)",

@@ -13,3 +13,2 @@ "type": "module",

},
"main": "./index.cjs",
"module": "./index.js",

@@ -21,6 +20,2 @@ "exports": {

"default": "./index.js"
},
"require": {
"types": "./index.d.ts",
"default": "./index.cjs"
}

@@ -32,3 +27,2 @@ }

"index.js",
"index.cjs",
"index.d.ts"

@@ -69,5 +63,8 @@ ],

"@types/aws-lambda": "^8.10.76",
"@types/node": "^18.0.0"
"@types/node": "^20.0.0"
},
"gitHead": "08c35e3dba9efdad0b86666ce206ce302cc65d07"
"gitHead": "ebce8d5df8783077fa49ba62ee9be20e8486a7f1",
"dependencies": {
"@datastream/core": "0.0.35"
}
}

@@ -22,4 +22,5 @@ <div align="center">

</a>
<a href="https://lgtm.com/projects/g/middyjs/middy/context:javascript">
<img src="https://img.shields.io/lgtm/grade/javascript/g/middyjs/middy.svg?logo=lgtm&logoWidth=18" alt="Language grade: JavaScript" style="max-width:100%;">
<a href="https://github.com/middyjs/middy/actions/workflows/sast.yml">
<img src="https://github.com/middyjs/middy/actions/workflows/sast.yml/badge.svg
?branch=main&event=push" alt="CodeQL" style="max-width:100%;">
</a>

@@ -26,0 +27,0 @@ <a href="https://bestpractices.coreinfrastructure.org/projects/5280">

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc