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.1 to 5.0.0-alpha.2

369

index.js

@@ -1,209 +0,176 @@

/* global awslambda */
import { Readable } from 'node:stream'
import { pipeline } from 'node:stream/promises'
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: () => {
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 ?? {}
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;
}
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
}
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 ?? {}
};
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);
}
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]
}
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
// 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
];
}
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, onErrorMiddlewares, plugin)
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) {
// Save error that wasn't handled
e.originalError = request.error
request.error = e
throw request.error
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, onErrorMiddlewares, plugin);
} catch (e) {
// Save error that wasn't handled
e.originalError = request.error;
request.error = e;
throw request.error;
}
// Catch if onError stack hasn't handled the error
if (typeof request.response === 'undefined') throw request.error;
} finally{
await plugin.requestEnd?.(request);
}
// 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
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.1",
"version": "5.0.0-alpha.2",
"description": "🛵 The stylish Node.js middleware engine for AWS Lambda (core package)",

@@ -5,0 +5,0 @@ "type": "module",

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