Skip to content

Commit

Permalink
Refactor to avoid duplicate handler parsing and improve middleware bu…
Browse files Browse the repository at this point in the history
…ilders
  • Loading branch information
juanjoDiaz committed Mar 7, 2019
1 parent b220538 commit 08fa271
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 179 deletions.
13 changes: 10 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,15 @@ class Middleware {
.concat(fn.handler)
.concat(this.middlewareOpts.pos)
.map((handler) => {
if (typeof handler === 'string') return { then: handler };
if (handler.then || handler.catch) return handler;
if (handler.then && handler.catch) {
return {
then: parseHandler(handler.then),
catch: parseHandler(handler.catch),
};
}
if (handler.then) return { then: parseHandler(handler.then) };
if (handler.catch) return { catch: parseHandler(handler.catch) };
if (typeof handler === 'string') return { then: parseHandler(handler) };

throw new Error(`Invalid handler: ${JSON.stringify(handler)}`);
});
Expand Down Expand Up @@ -135,7 +142,7 @@ class Middleware {
const getNodeType = (handler) => {
if (handler === undefined) return false;

const { module } = parseHandler(handler);
const { module } = handler;

if (fs.existsSync(`${module}.js`) || fs.existsSync(`${module}.jsx`)) return 'js';
if (fs.existsSync(`${module}.ts`) || fs.existsSync(`${module}.tsx`)) return 'ts';
Expand Down
66 changes: 43 additions & 23 deletions src/javascript.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,61 @@
*
* @param {Array<string>} handlers - handlers to be run as middleware
*
* @fulfil {} — Middleware handler created
* @reject {Error} Middleware error
*
* @return {Promise}
* @return {string} Javascript middleware handler
* */
function createJSMiddlewareHandler(handlers, pathToRoot = '.') {
function createJSMiddlewareHandler(handlers, pathToRoot) {
const handlersInfo = handlers
.reduce((modules, handler) => {
if (handler.then && handler.catch) {
const { name, module } = handler.then;
const { name: name2, module: module2 } = handler.catch;
return { ...modules, [module]: name, [module2]: name2 };
}
if (handler.then) {
const { name, module } = handler.then;
return { ...modules, [module]: name };
}

const { name, module } = handler.catch;
return { ...modules, [module]: name };
}, {});

const imports = Object.keys(handlersInfo)
.map(handler => `const ${handlersInfo[handler]} = require('${pathToRoot}/${handler}');`).join('\n');

const promiseChain = handlers.map((handler) => {
if (handler.then && handler.catch) {
const { name, fn } = handler.then;
const { name: name2, fn: fn2 } = handler.catch;
return ` .then(wrappedHandler(${name}.${fn}.bind(${name})))
.catch(wrappedHandler(${name2}.${fn2}.bind(${name2})))`;
}

if (handler.then) {
const { name, fn } = handler.then;
return ` .then(wrappedHandler(${name}.${fn}.bind(${name})))`;
}

const { name, fn } = handler.catch;
return ` .catch(wrappedHandler(${name}.${fn}.bind(${name})))`;
}).join('\n');

return `'use strict';
const handlers = ${JSON.stringify(handlers)};
${imports}
module.exports.handler = async (event, context) => {
let end = false;
context.end = () => end = true;
const wrappedHandler = handler => prev => {
if (end) return prev;
context.prev = prev;
const [module, fn] = handler.split(/\\.(?=[^\\.]+$)/);
return require(\`${pathToRoot}/\${module}\`)[fn](event, context);
return handler(event, context);
};
return handlers
.reduce((promise, handler) => {
if (typeof handler === 'object') {
if (handler.then && handler.catch) {
return promise
.then(wrappedHandler(handler.then))
.catch(wrappedHandler(handler.catch));
}
if (handler.then) return promise.then(wrappedHandler(handler.then));
if (handler.catch) return promise.catch(wrappedHandler(handler.catch));
throw new Error(\`Unkownw handler: \${JSON.stringify(handler)}\`);
}
return promise.then(wrappedHandler(handler));
}, Promise.resolve());
return Promise.resolve()
${promiseChain};
};`;
}

Expand Down
49 changes: 24 additions & 25 deletions src/typescript.js
Original file line number Diff line number Diff line change
@@ -1,52 +1,45 @@
const { parseHandler } = require('./utils');

/**
* @description Create TypeScript middleware handler
*
* @param {Array<string>} handlers - handlers to be run as middleware
*
* @fulfil {} — Middleware handler created
* @reject {Error} Middleware error
*
* @return {Promise}
*np
* @return {string} TypeScript Middleware handler
* */
function createTSMiddlewareHandler(handlers, pathToRoot = '.') {
function createTSMiddlewareHandler(handlers, pathToRoot) {
const handlersInfo = handlers
.reduce((modules, handler) => {
if (handler.then && handler.catch) {
const { name, module } = parseHandler(handler.then);
const { name: name2, module: module2 } = parseHandler(handler.catch);
const { name, module } = handler.then;
const { name: name2, module: module2 } = handler.catch;
return { ...modules, [module]: name, [module2]: name2 };
}
if (handler.then) {
const { name, module } = parseHandler(handler.then);
const { name, module } = handler.then;
return { ...modules, [module]: name };
}

const { name, module } = parseHandler(handler.catch);
const { name, module } = handler.catch;
return { ...modules, [module]: name };
}, {});

const imports = Object.keys(handlersInfo)
.map(handler => `import * as ${handlersInfo[handler]} from '${pathToRoot}/${handler}'`).join('\n');

const wrapHandler = (handler) => {
const { name, fn } = parseHandler(handler);
return `prev => {
if (end) return prev;
context.prev = prev;
return ${name}.${fn}(event, context, () => { throw new Error('Callback can\\'t be used in middlewares.'); });
}`;
};
.map(handler => `import * as ${handlersInfo[handler]} from '${pathToRoot}/${handler}';`).join('\n');

const promiseChain = handlers.map((handler) => {
if (handler.then && handler.catch) {
return ` .then(${wrapHandler(handler.then)})\n .catch(${wrapHandler(handler.catch)})`;
const { name, fn } = handler.then;
const { name: name2, fn: fn2 } = handler.catch;
return ` .then(wrappedHandler(${name}.${fn}.bind(${name})))
.catch(wrappedHandler(${name2}.${fn2}.bind(${name2})))`;
}

if (handler.then) return ` .then(${wrapHandler(handler.then)})`;
if (handler.then) {
const { name, fn } = handler.then;
return ` .then(wrappedHandler(${name}.${fn}.bind(${name})))`;
}

return ` .catch(${wrapHandler(handler.catch)})`;
const { name, fn } = handler.catch;
return ` .catch(wrappedHandler(${name}.${fn}.bind(${name})))`;
}).join('\n');

return `'use strict';
Expand All @@ -57,6 +50,12 @@ export async function handler(event, context) {
let end = false;
context.end = () => end = true;
const wrappedHandler = handler => prev => {
if (end) return prev;
context.prev = prev;
return handler(event, context);
};
return Promise.resolve()
${promiseChain};
};`;
Expand Down
Loading

0 comments on commit 08fa271

Please sign in to comment.