Skip to content

Instantly share code, notes, and snippets.

@tlrobinson
Created October 6, 2016 17:55
Show Gist options
  • Save tlrobinson/616530708c9b6290a91c435959acbf1c to your computer and use it in GitHub Desktop.
Save tlrobinson/616530708c9b6290a91c435959acbf1c to your computer and use it in GitHub Desktop.
import chain from "./promise-chain-decorator";
class Bar {
baz() {
return "baz";
}
}
class Foo {
@chain(Bar)
async bar() { // returns Promise<Bar>
await new Bar;
}
}
let foo = new Foo();
foo.bar().baz().then(console.log);
export default function chain(Klass) {
let proxies = getAllMethodNames(Klass).map(name =>
[name, function(...args) { return this.then(object => object[name](...args)); }]
);
return function (target, name, descriptor) {
const original = descriptor.value;
descriptor.value = function (...args) {
const promise = original.apply(this, args);
for (const [name, fn] of proxies) {
if (promise[name] === undefined) {
promise[name] = fn;
}
}
return promise;
}
}
}
function getAllMethodNames(Klass) {
let methods = {};
function getMethods(K) {
if (!K.prototype) {
return;
}
for (let method of Object.getOwnPropertyNames(K.prototype)) {
if (typeof K.prototype[method] === "function" && method !== "constructor" && !method.startsWith("_")) {
methods[method] = true;
}
}
getMethods(Object.getPrototypeOf(K));
}
getMethods(Klass);
return Object.keys(methods);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment