Skip to content

Instantly share code, notes, and snippets.

@michaelficarra
Created November 15, 2018 22:16
Show Gist options
  • Save michaelficarra/415941f94ed2249b5322d077aeaa6f96 to your computer and use it in GitHub Desktop.
Save michaelficarra/415941f94ed2249b5322d077aeaa6f96 to your computer and use it in GitHub Desktop.
capabilities
const safeApply = Date.call.bind(Date.apply);
const randomName = () => Math.random().toString(36).slice(2).toLowerCase();
class RevokedCapabilityException extends Error {}
class Capability {
constructor(behaviour, { name = randomName() } = {}) {
this.behaviour = behaviour;
this.name = Object.freeze([].concat(name));
}
run({ this: _this = null, arguments: args = [] } = {}) {
return safeApply(this.behaviour, _this, args);
}
blame() {
return this.name;
}
delegate({ name = randomName() } = {}) {
let revoked = false;
let self = this;
return {
revoke: () => {
revoked = true;
},
capability: new Capability(function() {
if (revoked) throw new RevokedCapabilityException();
return self.run({ this: this, arguments });
}, {
name: [].concat(self.name, [name]),
}),
};
}
}
module.exports = { Capability };
let Capability = require('./').Capability
let consoleCapability = new Capability((...args) => { console.log(...args); });
consoleCapability.run({ arguments: ["test", "capability"] });
let { revoke, capability: delegate } = consoleCapability.delegate();
delegate.run({ arguments: ["test", "delegate"] });
revoke();
try {
delegate.run({ arguments: ["test", "revocation"] });
} catch(e) {
console.log("revocation works");
}
consoleCapability.run({ arguments: ["test", "capability", "again"] });
console.log(delegate.blame());
console.log(consoleCapability.blame());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment