reddit/node-flags

Name: node-flags

Owner: Reddit

Description: :feet:

Created: 2016-02-04 18:53:13.0

Updated: 2018-04-02 22:00:42.0

Pushed: 2016-06-21 18:18:40.0

Homepage: null

Size: 22

Language: JavaScript

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

flags

A simple feature flagging library.

100 lines of code, no dependencies. Written in ES6+.

Build Status

flags lets you quickly switch features on or off based on a context. This is useful to test features for specific users (such as flagging on new functionality in a web application by reading the response context), dark-launching code, and a/b testing.

mport it!
rt Flags from '@r/flags';

et up your experiment config!
t config = {
ggedoutSearch: { loggedin: false },
dDesign: false,
wListingStyle: { users: ['ajacksified'] },


t feature = new Flags(config);

dd rules!
ure.addRule('loggedin', function(val) { return this.loggedin === val; });
ure.addRule('users', function(names) { return names.includes(this.username); });

et whatever blob of data you'll use to determine your experiment truthiness
t userData = {
ggedin: true,
ername: 'ajacksified',


or ease of use, build a context-bound flags instance. (Alternatively, you
ould call `feature.on(rule, context)` instead.)
t featureContext = feature.withContext(userData);

uild your UI with a Flags context bound to userdata!

alse (loggedin is true, but the config wants false)
featureContext.enabled('loggedoutSearch')) {
archControl = <LoggedOutSearch />;
nsole.log('show the logged out search');


alse (the config says it's always false)
featureContext.enabled('oldDesign')) {
yout = <OldLayout />;


rue (the username is in the users array)
featureContext.enabled('newListingStyle')) {
sting = <Listing2 />;


et the list of enabled featues:
t enabled = featureContext.allEnabled();
> ['newListingStyle'];


r disabled:
t disabled = featureContext.allDisabled();
> ['loggedoutSearch', 'oldDesign'];
Rules and Configuration

flags configuration and rules are very simple:

Of note: if a rule is defined in configuration but it is not implemented, it is assumed to be false.

Three special “pseudo-rules” implement boolean operators: and, or, and not, so that rules may stay simple and general and be combined in useful ways. For example:

t config = {
iend: {
and: [
  { or: [ { type: 'cyborg' }, { type: 'human' } ] },
  { not: { role: 'supervillain' } }
]


You can also parse large objects to handle things such as environment variables. To do so, you should have configuration in the format feature_name. feature_ will be stripped from the key and lowercased:

rt Flags from flags;

t config = Flags.parseConfig({
mething: 'wut',
ature_flippers: { names: ['bob', 'jane'] }


> { flippers: { names: ['bob', 'jane'] } };

You can supply your own function, too, and customize both key and value. In this example, we'll expect things to start with f_ instead of feature_.

rt Flags from flags;

t config = Flags.parseConfig({
mething: 'wut',
flippers: { names: ['bob', 'jane'] }
unction(key, val) {
 (key.indexOf('f_') === -1) { return; }
turn { key: key.slice(2), val: val };


> { flippers: { names: ['bob', 'jane'] } };

You can also retrieve a list of all currently enabled or disabled rules for a given context by calling feature.allEnabled or feature.allDisabled. These can be called with a context passed in, or else will use a bound context.

Sometimes, for testing, it's nice to clone an instance that doesn't use the original rules and configuration by reference. You can call flagsinstance.clone() to return a new flags instance with shallow copies of the config, rules, and context.

Development

flags is an ES6 library. Take a look at the .babelrc file to see what presets we're using. To import it in ES5, use var Flags = require ('@r/flags').default;.

To get started:

flags is MIT licensed. copyright 2016 reddit. See LICENSE for more info.


This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.