You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
2.4 KiB
103 lines
2.4 KiB
/** |
|
* Inject raw response, so we can know if middleware has responsed. |
|
*/ |
|
function makeInjectedResponse(koaCtx, /*markHandled,*/ whenEnded) { |
|
let res = koaCtx.res; |
|
|
|
res.on('close', whenEnded).on('finish', whenEnded); |
|
|
|
let dummyRes = Object.create(res); |
|
[ |
|
'setHeader', |
|
'writeHead', |
|
'write', |
|
'end' |
|
].forEach(name => { |
|
dummyRes[name] = function (...args) { |
|
res[name](...args); |
|
// koa2.0 initial assign statusCode to 404, reset to 200 |
|
if (res.statusCode === 404) { |
|
res.statusCode = 200; |
|
} |
|
// markHandled(); |
|
} |
|
}); |
|
[ |
|
'statusCode', |
|
'statusMessage' |
|
].forEach(name => { |
|
dummyRes.__defineSetter__(name, function (value) { |
|
res[name] = value; |
|
// markHandled(); |
|
}) |
|
}) |
|
|
|
return dummyRes; |
|
} |
|
|
|
/** |
|
* The middleware function does include the `next` callback so only resolve |
|
* the Promise when it's called. If it's never called, the middleware stack |
|
* completion will stall |
|
*/ |
|
function handler(ctx, connectMiddleware) { |
|
return new Promise((resolve, reject) => { |
|
// let hasHandled = false; |
|
// (req, res) |
|
let args = [ |
|
ctx.req, |
|
makeInjectedResponse( |
|
ctx, |
|
// () => { |
|
// // hasHandled = true; |
|
// }, |
|
() => { |
|
resolve(false); |
|
}) |
|
]; |
|
let assumeSync = true |
|
// (req, res, next) or (err, req, res, next) |
|
if (connectMiddleware.length >= 3) { |
|
args.push(err => { |
|
if (err) reject(err) |
|
else resolve(true) |
|
}) |
|
assumeSync = false |
|
} |
|
// (err, req, res, next) |
|
if (connectMiddleware.length >= 4) { |
|
args.unshift(null); |
|
} |
|
connectMiddleware(...args) |
|
/** |
|
* If the middleware function does not declare receiving the `next` callback |
|
* assume that it's synchronous. |
|
*/ |
|
if (assumeSync /*&& !hasHandled*/) { |
|
resolve(true) |
|
} |
|
}) |
|
} |
|
|
|
/** |
|
* Returns a Koa middleware function that varies its async logic based on if the |
|
* given middleware function declares at least 3 parameters, i.e. includes |
|
* the `next` callback function |
|
*/ |
|
function koaConnect(connectMiddleware) { |
|
return async (ctx, next) => { |
|
ctx.respond = false; |
|
try { |
|
let goNext = await handler(ctx, connectMiddleware) |
|
if (goNext) { |
|
ctx.respond = true; |
|
return next(); |
|
} |
|
} catch (err) { |
|
ctx.respond = true; |
|
throw err; |
|
}; |
|
} |
|
} |
|
|
|
export = koaConnect |