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

nodecaf

Package Overview
Dependencies
Maintainers
1
Versions
80
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nodecaf - npm Package Compare versions

Comparing version 0.12.5 to 0.13.0-rc1

lib/types.js

160

lib/api.js

@@ -10,3 +10,3 @@ const assert = require('assert');

function pathToRegexp(path){
let r = { params: [] };
const r = { params: [] };
let regexp = '';

@@ -41,20 +41,6 @@

function buildStack(context, chain){
chain.length > 1 &&
context.log.warn('Building routes with multiple functions is deprecated. '
+ 'This behavior is going to be dropped on v0.13.0. Use `call` instead.');
let nextHandler = null;
return chain.reverse().map(h => {
assert(typeof h == 'function',
new TypeError('Invalid route option \'' + typeof h + '\''));
h = normalizeHandler(h.bind(context));
h.next = nextHandler;
return nextHandler = h;
}).reverse();
}
function matchRoute(method, path, params){
// this => API
let route = method + ' ' + path;
const route = method + ' ' + path;
if(route in this.static)

@@ -64,4 +50,4 @@ return this.static[route];

if(this.dynamic[method])
for(let r of this.dynamic[method]){
let match = r.regexp.exec(path);
for(const r of this.dynamic[method]){
const match = r.regexp.exec(path);
if(match){

@@ -76,18 +62,2 @@ r.params.forEach( (p, i) => params[p] = match[i + 1]);

function runHandler(input, handler, done){
if(input.res.stackAborted)
return;
input.next = handler.next
? () => {
input.log.warn('`next()` is deprecated. '
+ 'This parameter will be dropped on v0.13.0. Use `call` instead.');
return runHandler(input, handler.next, done)
}
: () => done();
handler(input).catch(err => handleError(err, input.res));
}
function parseSignedCookies(cconf, input){

@@ -97,4 +67,4 @@ if(!cconf?.secret)

for(let key in input.cookies){
var val = cookieSignature.unsign(input.cookies[key], cconf?.secret);
for(const key in input.cookies){
const val = cookieSignature.unsign(input.cookies[key], cconf?.secret);
if(val){

@@ -107,20 +77,2 @@ input.signedCookies[key] = val;

function fork(input, func){
// this => app
this.log.warn('`fork` is deprecated. This method will be dropped on v0.13.0.');
return new Promise((resolve, reject) => {
func = normalizeHandler(func.bind(this));
func({ ...input, next: resolve }).catch(reject);
});
}
function buildHook(hookName, ...chain){
chain.length > 1 &&
this.context.log.warn('`pre()` and `pos()` hooks are deprecated. '
+ 'Those methods will be dropped on v0.13.0. Use `call` instead.');
let stack = buildStack(this.context, chain);
this[hookName] = stack[0];
stack.slice(-1)[0].tail = true;
}
module.exports = class API {

@@ -136,3 +88,3 @@

// Generate HTTP verb shortcut route methods
let proxy = METHODS.reduce( (o, m) =>
const proxy = METHODS.reduce( (o, m) =>
({ ...o, [m.toLowerCase()]: this.addEndpoint.bind(this, m.toLowerCase()) }), {});

@@ -143,28 +95,25 @@

proxy.all = (...chain) => {
proxy.all = handler => {
assert(!this.fallbackRoute, new Error('Route for \'ALL\' is already defined'));
assert(chain.length > 0, new Error('Route is empty at \'ALL\''));
let stack = buildStack(this.context, chain);
stack.slice(-1)[0].tail = true;
this.fallbackRoute = stack[0];
assert(typeof handler == 'function',
new TypeError(`'ALL' handler must be a function. Found '${typeof handler}'`));
this.fallbackRoute = normalizeHandler(handler.bind(this.context));
};
proxy.pre = buildHook.bind(this, 'preHook');
proxy.pos = buildHook.bind(this, 'posHook');
spec.call(context, proxy);
spec?.call(context, proxy);
}
addEndpoint(method, path, ...chain){
addEndpoint(method, path, handler){
let m = method.toUpperCase();
let route = m + ' ' + path;
const m = method.toUpperCase();
const route = m + ' ' + path;
let dup = route in this.routes;
const dup = route in this.routes;
assert(!dup, new Error('Route for \'' + route + '\' is already defined'));
assert(chain.length > 0, new Error('Route is empty at \'' + path + '\''));
let stack = buildStack(this.context, chain);
assert(typeof handler == 'function',
new TypeError(`'${route}' handler must be a function. Found '${typeof handler}'`));
stack.slice(-1)[0].tail = true;
const nmHandler = normalizeHandler(handler.bind(this.context));

@@ -174,10 +123,10 @@ this.routes[route] = true;

if(path.indexOf('/:') < 0 && path.indexOf('*') < 0)
return this.static[route] = stack[0];
return this.static[route] = nmHandler;
this.dynamic[m] = this.dynamic[m] || [];
let { regexp, params } = pathToRegexp(path);
this.dynamic[m].push({ regexp, handler: stack[0], params });
const { regexp, params } = pathToRegexp(path);
this.dynamic[m].push({ regexp, handler: nmHandler, params });
}
async trigger(method, path, input = {}){
async trigger(method, path, input){
method = method.toUpperCase();

@@ -188,45 +137,22 @@ const params = {};

const flash = new Proxy({}, {
get() {
app.log.warn('`flash` is deprecated. '
+ 'This parameter will be dropped on v0.13.0.');
return Reflect.get(...arguments);
},
set(){
app.log.warn('`flash` is deprecated. '
+ 'This parameter will be dropped on v0.13.0.');
return Reflect.set(...arguments);
}
});
input = {
...app.global, conf: app.conf, flash, cookies: {}, headers: {},
query: {}, ...input, params, log: app.log, signedCookies: {},
method, path
...app.global, conf: app.conf, cookies: {}, headers: {},
query: {}, ...input, params, log: app.log, signedCookies: {}, method,
path
};
input.fork = fork.bind(app, input);
input.call = (fn, ...args) => fn.call(app, input, ...args);
let origReq = input.req || {};
input.req = new Proxy({
method, path, host: origReq.host, 'user-agent': origReq['user-agent']
}, {
get() {
app.log.warn('`req` is deprecated. '
+ 'This parameter will be dropped on v0.13.0.');
return Reflect.get(...arguments);
}
});
app.log.debug({
method: method, path,
host: origReq.host,
agent: origReq['user-agent'],
const reqInfo = {
method, path,
host: input.headers?.host,
agent: input.headers?.['user-agent'],
type: 'request',
msg: 'Received ' + method + ' request to ' + path
});
};
let res = input.res = new Response(input);
app.log.debug(reqInfo);
const res = input.res = new Response(input, reqInfo);
const handler = matchRoute.call(this, method, path, params);

@@ -239,4 +165,4 @@

input.body = new RequestBody(input, origReq);
if(app._autoParseBody)
input.body = new RequestBody(input);
if(app._autoParseBody && !input.websocket)
try{

@@ -247,3 +173,3 @@ input.body = await input.body.parse();

res.status(400).end();
app.log.warn({ req: res.req, err, type: 'request' });
app.log.warn({ ...reqInfo, err });
return res.ended;

@@ -254,10 +180,4 @@ }

this.preHook && await new Promise(done => runHandler(input, this.preHook, done));
handler(input).catch(err => handleError(err, input));
const warn = () => app.log.warn({ type: 'route' },
'next() was called when the chain is finished');
runHandler(input, handler, this.posHook
? () => runHandler(input, this.posHook, warn) : warn);
return res.ended;

@@ -264,0 +184,0 @@ }

const contentType = require('content-type');
const { getDataTypeFromContentType, parseBuffer } = require('./types');
const FALLBACK_CONTENT_TYPE = { type: 'text/plain', parameters: { charset: 'utf-8' } };
function parseContentType(headers){
try{
var ct = contentType.parse(headers['content-type']);
}
catch(err){
ct = FALLBACK_CONTENT_TYPE;
}
ct.textCharset = ct.parameters.charset || 'utf-8';
ct.originalCharset = ct.parameters.charset;
return ct;
}
function readStream(){
var complete, buffer = [];
this.req.on('data', chunk => buffer.push(chunk));
this.stream.on('data', chunk => buffer.push(chunk));
this.req.on('close', () => {
this.stream.on('close', () => {
buffer = null;
this.req.removeAllListeners('aborted');
this.req.removeAllListeners('data');
this.req.removeAllListeners('end');
this.req.removeAllListeners('error');
this.req.removeAllListeners('close');
this.stream.removeAllListeners('aborted');
this.stream.removeAllListeners('data');
this.stream.removeAllListeners('end');
this.stream.removeAllListeners('error');
this.stream.removeAllListeners('close');
});

@@ -36,6 +20,6 @@

this.req.on('aborted', () =>
this.req.emit('error', new Error('Request aborted by the client')));
this.stream.on('aborted', () =>
this.stream.emit('error', new Error('Request aborted by the client')));
this.req.on('end', () => {
this.stream.on('end', () => {
!complete && resolve(Buffer.concat(buffer));

@@ -45,3 +29,3 @@ complete = true;

this.req.on('error', err => {
this.stream.on('error', err => {
!complete && reject(err);

@@ -55,5 +39,2 @@ complete = true;

if(!this.res.res)
return this.origBody;
let out = await readStream.call(this);

@@ -69,7 +50,8 @@

constructor({ res, headers, body }, stream){
Object.assign(this, parseContentType(headers));
this.req = stream;
constructor({ res, headers, body }){
const t = getDataTypeFromContentType(headers['content-type']);
this.type = t.type;
this.charset = t.charset;
this.stream = body;
this.res = res;
this.origBody = body;
this.length = headers['content-length'];

@@ -82,33 +64,22 @@ }

async text(){
this.res.badType(!this.originalCharset && this.type.slice(0, 4) != 'text');
return await read.call(this, raw => raw.toString(this.textCharset));
text(){
this.res.badType(!this.charset && this.type != 'text');
return read.call(this, raw => raw.toString(this.charset));
}
async urlencoded(){
this.res.badType(this.type != 'application/x-www-form-urlencoded');
return await read.call(this, raw =>
Object.fromEntries(new URLSearchParams(raw.toString(this.textCharset)).entries()));
json(){
this.res.badType(this.type != 'json');
return read.call(this, raw => JSON.parse(raw.toString(this.charset)));
}
async json(){
this.res.badType(this.type.slice(-4) != 'json');
return await read.call(this, raw =>
JSON.parse(raw.toString(this.textCharset)));
urlencoded(){
this.res.badType(this.type != 'urlencoded');
return read.call(this, raw =>
Object.fromEntries(new URLSearchParams(raw.toString(this.charset)).entries()));
}
parse(){
if(this.type.slice(-4) == 'json')
return this.json();
if(this.type == 'application/x-www-form-urlencoded')
return this.urlencoded();
if(this.originalCharset || this.type.slice(0, 4) == 'text')
return this.text();
return this.raw();
return read.call(this, raw => parseBuffer(raw, this.type, this.charset));
}
}

@@ -25,3 +25,3 @@

// and from res.error() when calling it with an error
function handleError(err, res){
function handleError(err, { method, path, res, log, headers }){
res.failed = true;

@@ -37,4 +37,3 @@

res.log.error({ method: res.req.method, path: res.req.path,
headers: res.req.headers, type: 'route', err: res.err });
log.error({ method, path, headers, type: 'route', err: res.err });

@@ -41,0 +40,0 @@ if(!res.finished)

const cookie = require('cookie');
const { buildWebSocketServer } = require('./ws');
const normalizePath = p => (p.slice(-1) == '/' ? p.slice(0, -1) : p) || '/';

@@ -12,6 +13,6 @@

let [ path, query ] = req.url.split('?');
const [ path, query ] = req.url.split('?');
await this._api.trigger(req.method, normalizePath(path), {
req, res, headers: req.headers,
body: req, res, headers: req.headers,
query: Object.fromEntries(new URLSearchParams(query).entries()),

@@ -25,3 +26,3 @@ cookies: cookie.parse(req.headers.cookie || '')

async startServer(){
let handler = handleRequest.bind(this);
const handler = handleRequest.bind(this);
this._server = this._serverBuilder(this).on('request', handler);

@@ -31,4 +32,7 @@ await new Promise(done => this._server.listen(this.conf.port, done));

'%s v%s is ready on port %s', this._name, this._version, this.conf.port);
if(this._websocket)
this._wss = buildWebSocketServer(this);
}
}

@@ -91,3 +91,3 @@ import { Server } from 'http';

class RequestBody {
req: Request
stream: Request
raw(): Promise<Buffer | unknown>

@@ -97,3 +97,3 @@ text(): Promise<string>

json(): Promise<unknown>
parse(): Promise<Buffer | string | Record<string, string> | unknown>
parse(): Promise<unknown>
}

@@ -116,19 +116,4 @@

res: Response,
/**
* Object containing some request info
* @deprecated This property is going to be removed on v0.13.0.
*/
req: {
method: string,
path: string,
'user-agent'?: string,
host?: string
},
/** Call `fn` with the request handler args as the first parameter and spreading `args`. */
call: <T>(fn: (input: RouteHandlerArgs, ...args: unknown[]) => T, ...args: unknown[]) => T
/**
* Run an express middleware `fn` and returns a `Promise` resolving when `next` is called, or rejecting in case of exceptions
* @deprecated This property is going to be removed on v0.13.0.
*/
fork: (fn: RouteHandler) => Promise<void>,
/** The current app configuration. */

@@ -141,13 +126,3 @@ conf: ConfObject,

/** Object containing params parsed from URL segments as key-values. */
params: Record<string, string>,
/**
* Run next function in the handler chain
* @deprecated This method is going to be removed on v0.13.0.
*/
next: <T>(fn: (input: RouteHandlerArgs, ...args: unknown[]) => T, ...args: unknown[]) => T,
/**
* Object where you can store values to be persisted across the middleware chain
* @deprecated This property is going to be removed on v0.13.0.
*/
flash: Record<string, string>
params: Record<string, string>
} & Record<string, unknown>;

@@ -163,15 +138,2 @@

del: (path: string, handler: RouteHandler) => void,
/**
* Set a function to be run before all route handler
* @deprecated This method is going to be removed on v0.13.0.
*/
pre: (handler: RouteHandler) => void,
/**
* Set a function to be run after all route handlers
* @deprecated This method is going to be removed on v0.13.0.
*/
pos: (handler: RouteHandler) => void,
all: (handler: RouteHandler) => void

@@ -195,9 +157,4 @@ }

autoParseBody?: boolean,
/** A function tthat returns a custom HTTP server to be used by the app */
server?: (args: Nodecaf) => Server,
/**
* When set change api building to happen on every `app.start()`
* @deprecated This option is going to be removed on v0.13.0.
*/
alwaysRebuildAPI: boolean
/** A function that returns a custom HTTP server to be used by the app */
server?: (args: Nodecaf) => Server
}

@@ -204,0 +161,0 @@ }

@@ -10,6 +10,5 @@ const

const API = require('./api');
const { Readable, Writable } = require('stream');
const { getDataTypeFromContentType, getContentTypeFromDataType, parseBuffer } = require('./types');
const noop = function(){};
noop.noop = true;
function findPkgInfo(){

@@ -33,18 +32,19 @@ try{

this._apiSpec = opts.api || noop;
this._startup = opts.startup || noop;
this._shutdown = opts.shutdown || noop;
this._serverBuilder = opts.server || (() => http.createServer());
this._websocket = opts.websocket;
this._apiSpec = opts.api;
this._startup = opts.startup;
this._shutdown = opts.shutdown;
this._serverBuilder = opts.server ?? (() => http.createServer());
let { name, version } = findPkgInfo();
this._name = opts.name || name;
this._version = opts.version || version;
const { name, version } = findPkgInfo();
this._name = opts.name ?? name;
this._version = opts.version ?? version;
assert(typeof this._apiSpec == 'function',
assert(!opts.api || typeof this._apiSpec == 'function',
new TypeError('API builder must be a function'));
assert(typeof this._startup == 'function',
assert(!opts.startup || typeof this._startup == 'function',
new TypeError('Startup handler must be a function'));
assert(typeof this._shutdown == 'function',
assert(!opts.shutdown || typeof this._shutdown == 'function',
new TypeError('Shutdown handler must be a function'));

@@ -61,6 +61,4 @@

this._autoParseBody = opts.autoParseBody || false;
this._autoParseBody = opts.autoParseBody ?? false;
this._alwaysRebuildAPI = opts.alwaysRebuildAPI || false;
this.call = (fn, ...args) => fn.call(this, { ...this.global, ...this }, ...args);

@@ -73,12 +71,7 @@

opts.alwaysRebuildAPI &&
this.log.warn('`alwaysRebuildAPI` is deprecated. '
+ 'This parameter will be dropped on v0.13.0.');
if(!this._alwaysRebuildAPI)
this._api = new API(this, this._apiSpec);
this._api = new API(this, this._apiSpec);
}
setup(objectOrPath){
this.conf = confort(this.conf, objectOrPath || {});
setup(objectOrPath = {}){
this.conf = confort(this.conf, objectOrPath);
this._cors = cors(this.conf.cors);

@@ -105,6 +98,3 @@

if(this._alwaysRebuildAPI)
this._api = new API(this, this._apiSpec);
if(!this._startup.noop)
if(this._startup)
this.log.debug({ type: 'app' }, 'Starting up %s...', this._name);

@@ -114,7 +104,7 @@

try{
await this._startup(this);
await this._startup?.(this);
}
catch(err){
this.state = 'stuck';
await this.stop().catch(() => {});
await this.stop().catch(Function.prototype);
throw err;

@@ -140,2 +130,5 @@ }

if(this._wss)
this._wss.close();
if(this._server)

@@ -146,3 +139,3 @@ var actualHTTPClose = new Promise(done => this._server.close(done));

try{
await this._shutdown(this);
await this._shutdown?.(this);
}

@@ -162,4 +155,38 @@ catch(err){

trigger(method, path, input){
return this._api.trigger(method, path, input);
async trigger(method, path, input = {}){
if(input.body && !(input.body instanceof Readable)){
const ob = input.body;
const oh = input.headers ?? {};
input = { ...input };
const type = getContentTypeFromDataType(ob);
if(ob instanceof Buffer)
input.body = Readable.from(ob);
else if(typeof ob == 'object')
input.body = Readable.from(Buffer.from(JSON.stringify(ob)));
else
input.body = Readable.from(Buffer.from(String(ob)));
if(!oh['content-type'] && !oh['Content-Type'] && type)
input.headers = { ...oh, 'content-type': type };
}
const chunks = [];
input.res = new Writable({
write: function(chunk, _encoding, next) {
chunks.push(chunk);
next();
}
});
const r = await this._api.trigger(method, path, input);
if(chunks.length > 0){
const ct = r.headers?.['content-type'] ?? r.headers?.['Content-Type'];
const { type, charset } = getDataTypeFromContentType(ct);
r.body = parseBuffer(Buffer.concat(chunks), type, charset);
}
return r;
}

@@ -166,0 +193,0 @@

@@ -6,7 +6,7 @@ const { sign } = require('cookie-signature');

const { HTTPError, handleError } = require('./error');
const { getContentTypeFromDataType } = require('./types');
const SHORT_CONTENT_TYPES = {
'text': 'text/plain',
'json': 'application/json',
'binary': 'application/octet-stream'
'json': 'application/json'
};

@@ -26,7 +26,6 @@

constructor({ res, req, log, conf }){
this.conf = conf;
this.res = res;
this.log = log;
this.req = req;
constructor(input, reqInfo){
this.reqInfo = reqInfo;
this.resStream = input.res;
this.input = input;
this.ended = new Promise((resolve, reject) => {

@@ -38,3 +37,3 @@ this.resolve = resolve;

this.statusCode = 200;
for(let name in ASSERTS)
for(const name in ASSERTS)
this[name] = this.assert.bind(this, ASSERTS[name]);

@@ -44,9 +43,3 @@ }

write(chunk){
this.res && this.res.write(chunk);
if(!this.body)
this.body = chunk;
else if(this.body instanceof Buffer)
this.body = Buffer.concat([ this.body, chunk ]);
else
this.body += String(chunk);
this.resStream.write(chunk);
}

@@ -56,13 +49,10 @@

body && this.write(body);
this.res && this.res.end();
this.resStream.end();
this.log.debug({
path: this.req.path,
method: this.req.method,
host: this.req.host,
agent: this.req['user-agent'],
this.input.log.debug({
...this.reqInfo,
status: this.statusCode,
level: this.statusCode > 499 ? 'warn' : 'debug',
type: 'response',
msg: 'Sent ' + this.statusCode + ' response to ' + this.req.method + ' ' + this.req.path
msg: 'Sent ' + this.statusCode + ' response to ' + this.reqInfo.method + ' ' + this.reqInfo.path
});

@@ -74,3 +64,3 @@

headers: this.headers,
body: this.body
body: this.resStream
});

@@ -84,18 +74,12 @@ }

if(!Number.isInteger(status))
return handleError(status, this);
return handleError(status, this.input);
this.status(status);
let type = 'text';
const type = getContentTypeFromDataType(message);
if(typeof message == 'string')
message = format(message, ...args);
else if(message instanceof Buffer)
type = 'binary';
else if(message && typeof message == 'object'){
type = 'json';
else if(type == 'application/json')
message = JSON.stringify(message);
}
else if(message == null)
type = null;
else
else if(type == 'text/plain')
message = String(message);

@@ -117,3 +101,3 @@

set(k, v){
this.res && this.res.setHeader(k, v);
this.resStream.setHeader?.(k, v);
this.headers[k] = v;

@@ -124,3 +108,3 @@ return this;

append(k, v){
let prev = this.headers[k];
const prev = this.headers[k];
prev && (v = Array.isArray(prev)

@@ -133,3 +117,3 @@ ? prev.concat(v)

status(s){
this.res && (this.res.statusCode = s);
this.resStream.statusCode = s;
this.statusCode = s;

@@ -168,7 +152,7 @@ return this;

if(value && opts.signed && !this.conf.cookie?.secret)
if(value && opts.signed && !this.input.conf.cookie?.secret)
throw new Error('Trying to sign cookies when secret is not defined');
if(opts.signed && value)
value = sign(value, this.conf.cookie.secret);
value = sign(value, this.input.conf.cookie.secret);

@@ -175,0 +159,0 @@ if('maxAge' in opts) {

{
"name": "nodecaf",
"version": "0.12.5",
"version": "0.13.0-rc1",
"description": "Nodecaf is a light framework for developing RESTful Apps in a quick and convenient manner.",

@@ -42,3 +42,2 @@ "main": "lib/main.js",

"confort": "^0.2.0",
"content-type": "^1.0.4",
"cookie": "^0.4.1",

@@ -50,5 +49,5 @@ "cookie-signature": "^1.1.0",

"devDependencies": {
"muhb": "^3.0.6",
"muhb": "^3.1.0",
"toml": "^3.0.0"
}
}

@@ -157,4 +157,3 @@ # [Nodecaf](https://gitlab.com/GCSBOSS/nodecaf)

## Manual
Formerly based on Express, Nodecaf preserves the same interface for defining routes
through middleware chains. Check out how to use all the awesome goodies Nodecaf introduces.
Formerly based on Express, Nodecaf has a simpler approach to defining routes, offloading much of the complexity to the already existing code partitioning idioms (i.e. functions). Check out how to use all the awesome goodies Nodecaf introduces.

@@ -168,3 +167,3 @@ ### Handler Args

```js
function({ req, res, next, query, params, body, flash, conf, log, headers, call }){
function({ method, path, res, query, params, body, conf, log, headers, call }){
// Do your stuff.

@@ -176,9 +175,5 @@ }

- `req`, `res`, `next`: The good old parameters used regularly in middleware-like frameworks.
- `method`, `path`, `query`, `parameters`, `body`, `headers`: Shortcuts to the homonymous properties of `req`.
They contain respectively the HTTP method, request URL path, query string, the URL parameters, and the request
body data.
- `flash`: Is an object where you can store arbitrary values. Keys inserted in this
object are preserved for the lifetime of a request and can be accessed in all
handlers of a route chain.
- `res`: An object containing the functions to send a response to the client.
- `path`, `method`, `query`, `params`, `body`, `headers`: Properties of the request.
They contain respectively the requested path, HTTP method, query string, the URL parameters, and the request body data.
- `conf`: This object contains the entire

@@ -277,3 +272,2 @@ [application configuration data](#settings-file).

| route | error | An error happened inside a route and was not caught |
| route | warn | next() used after stack has ended |
| crash | fatal | An error happened that crashed the server process |

@@ -309,12 +303,10 @@ | request | debug | A request has arrived |

```js
get('/my/thing',
function({ res, next }){
res.send('My regular function works!');
next();
},
async function({ res }){
await myAsyncThing();
res.end('My async function works too!');s
}
);
get('/my/thing', function({ res }){
res.end('My regular function works!');
});
get('/my/other/thing', async function({ res }){
await myAsyncThing();
res.end('My async function works too!');s
});
```

@@ -333,4 +325,3 @@

To support the callback error pattern, use the `res.error()` function arg. This
function will stop the middleware chain from being executed any further.
To support the callback error pattern, use the `res.error()` function arg.

@@ -484,2 +475,1 @@ ```js

| `opts.shouldParseBody` | Boolean | Wether supported request body types should be parsed | `true` |
| `opts.alwaysRebuildAPI` | Boolean | Wether the API should be rebuilt dynamically for every start or setup operation | `false` |

Sorry, the diff of this file is not supported yet

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