npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

daddy

v1.3.0

Published

Simple, powerful and fun permission checks for Javascript

Downloads

35

Readme

Daddy

Simple, powerful and fun permission checks for Javascript.

NPM Version Coverage Status GitHub license

Installation

$ npm install daddy

Usage

ECMAScript 6 version is the default:


import Daddy from 'daddy';

For ECMAScript 5 compatibility, use the distributed commonJS build.


var Daddy = require('daddy/es5');

Daddy uses the native ES6 Promise spec by default. You can use any Promises/A+ compliant implementation though, by setting it with setPromiseImplementation();


var d       = new Daddy(),
    Promise = require('bluebird');

d.setPromiseImplementation(Promise);
// now daddy uses bluebird when returning async results from daddy.when

A common use case:


function getCurrentUser() {
  return {
    name: 'Teemu',
    role: 'admin'
  };
}

function ensureAdmin(user) {
  return (user.role === 'admin')
    ? true
    : 'Must be admin';
}

//
// Daddy instance, not mad
var dad = new Daddy();

//
// set current user as the default parameter for checks
dad.defineParamsGetter(getCurrentUser);

//
// The permission to do stuff requires admin
dad.permission('doStuff', ensureAdmin);

dad.check('doStuff').granted === true;
dad.check('doUnknownAction').granted === true; // because dad is not mad

And preferably do checks async:

  
dad.when('illegalAction').catch(function(rejection) {
  // rejection.granted === false;
  // rejection.reason === 'Whatever was returned from the failing handler';
});

API

new Daddy(mad)

| Param | Type | Description | :-------- | :------ | :------- | mad | Boolean | If set to true, will deny all unknown permissions.

Daddy.permission(pattern *, handler *, ...)

| Param | Type | Description | :-------- | :------ | :------- | pattern | String|RegExp | A unique pattern, throws on dupes. | handler | function | A handler function that gets called on Daddy.check. Supports multiple handlers.

Use RegExp for useful catch-many permissions or namespacing:


// for example, allow only admins to do remove actions. 
// Eg. 'removePost','removeComment'.
daddy.permission(/^remove/, ensureAdmin);

// or
// require a registered user to crud comments. 
// Eg. 'Comment','viewComment','createComment'...
daddy.permission(/Comment$/, ensureRegistered);

Daddy.defineParamsGetter(fn *)

| Param | Type | :-------- | :------ | fn | Function

Register a param getter function in a daddy instance. It set, will head its' return value in params passed to check. This is especially useful for user authorization when you know for sure that the current user is always needed in checks.

Daddy.check(name *, param, ...)

| Param | Type | Description | :-------- | :------ | :------- | name | String | The permission name to be matched against. | param | any | Optional parameters to be passed to permission layer handlers.

Performs a synchronous check returning a result object:

{
  granted: Boolean, // did it pass?
  reason: any // the value returned from the failing handler
}

Calls each handler in each satisfying permission layer, passing in the result of paramsGetter, if set, and passed param(s) as arguments. Short circuits as soon as any of the handlers return false.

Layer lookups are cached, so subsequent calls with the same name are quaranteed to be as fast as accessing an array by a known index.

Daddy.check(name *, param, ...)

Identical to Daddy.check but:

Performs an asynchronous check returning a promise that resolves or rejects with the result object.

Daddy uses ECMAScript 6 Promises by default. You can change the implementation with:

Daddy.setPromiseImplementation(Promise)

For example:


var d       = new Daddy(),
    Promise = require('bluebird');

d.setPromiseImplementation(Promise);
// now daddy uses bluebird when returning async results from daddy.when

More examples

You may want to namespace permissions:


var daddy = new Daddy();

daddy
  .permission(/^core:/           , ensureRegistered)
  .permission(/^core:utils:/     , ensureDeveloper)
  .permission(/^core:utils:api/  , ensureAdmin);

Or go crazy:


var player  = { name: 'Teemu', type: 'player' },
    enemy   = { name: 'T Rex', type: 'dinosaur' },
    // dad is mad
    permissionManager = new Daddy(true);

//
// Only dinosaurs are allowed to eat anything
permissionManager.permission(/^eat/, function(x) {
  return (x.type === 'dinosaur')
    ? true
    : 'Only dinosaurs are allowed to eat anything';
});

//
// But for some reason cars can only be interacted with by a player
permissionManager.permission(/Car$/, function(x) {
  return (x.type === 'player')
    ? true
    : 'Only players can interact with cars';
});

permissionManager.check('eatBuilding', enemy).granted === true;
permissionManager.check('eatStuff', enemy).granted === true

permissionManager.check('eatCar', enemy);
// -> { granted: false, reason: 'Only players can interact with cars' }

permissionManager.check('eatCar', player); // eat false -> false
// -> { granted: false, reason: 'Only dinosaurs are allowed to eat anything' }
// 
permissionManager.check('driveCar', player).granted === true;

permissionManager.check('idle', player);
// dad is mad
// -> { granted: false, reason: 'No permission layers matched.'}

Contributions

Clone and install deps

$ npm install

Build

$ npm run build

Test

$ npm run test

License

MIT