npm package: @reliance/feature-flags
Description: A package for determining feature flag status based on environment variables or flag objects.
Author: info@reliancehealth.com
Latest version: 0.1.2

# Feature Flag Management Documentation

## Overview
This module provides a framework for managing feature flags in a JavaScript application. It allows you to define feature flags as predicate functions that return boolean values, enabling conditional behavior based on the flags.

## Functions

### `isFeatureEnabled(feature, params = {})`

**Description:**

Checks if a feature is enabled by evaluating its corresponding predicate function. If the function returns a boolean value, that value is used to determine the feature's state. If the function does not return a boolean or throws an error, the function defaults to `false`. Additionally, it checks for an environment variable with the feature name, which can override the predicate.

**Parameters:**

- `feature` (string): The name of the feature to check.
- `params` (object, optional): Parameters to pass to the feature's predicate function.

**Returns:**

- `boolean`: `true` if the feature is enabled, `false` otherwise.

**Usage Example:**

```javascript
const { isFeatureEnabled } = require("./isFeatureEnabled");

const isEnabled = isFeatureEnabled("newDashboard", { userId: 12345 });
if (isEnabled) {
  // Enable the new dashboard feature
}
```

**Notes:**

- If the predicate function for the feature does not return a boolean value, a warning is logged, and the function defaults to returning `false`.
- If the feature is not defined as a predicate, the function will check the corresponding environment variable (e.g., `process.env.newDashboard`).

---

### `setFeature(featureDefinitions)`

**Description:**

Registers a set of feature flags, each associated with a predicate function. The predicates should return boolean values, determining whether the corresponding feature is enabled or not.

**Parameters:**

- `featureDefinitions` (object): An object where each key is a feature name and each value is a predicate function.

**Throws:**

- `PredicateNotAFunctionError`: Thrown if any value in `featureDefinitions` is not a function.
- `InvalidFeatureDefinition`: Thrown if `featureDefinitions` is not an object or is `null`.

**Usage Example:**

```javascript
const { setFeature } = require("./setFeature");

setFeature({
  newDashboard: ({ userId }) => userId === 12345,
  betaFeature: () => Math.random() > 0.5,
});
```

**Notes:**

- Ensure that all predicate functions return a boolean value.
- This function should be called during the application startup to register all necessary feature flags.

---

## Error Classes

### `PredicateNotAFunctionError`

**Description:**

An error thrown when a feature definition is attempted with a non-function predicate. This ensures that only valid functions are used to define feature flags.

**Usage Example:**

```javascript
throw new PredicateNotAFunctionError(featureName);
```

**Notes:**

- The error message will include the name of the feature that caused the error.

---

### `InvalidFeatureDefinition`

**Description:**

An error thrown when the `setFeature` function is called with an invalid `featureDefinitions` object. This ensures that the input to `setFeature` is always a valid object.

**Usage Example:**

```javascript
throw new InvalidFeatureDefinition();
```

**Notes:**

- This error is thrown if `featureDefinitions` is not an object or is `null`.

---

## Environmental Variables

### Environment Variable Override

- The `isFeatureEnabled` function can also check for environment variables to determine if a feature is enabled. If the environment variable matches the feature name and is set to `"true"`, the feature is considered enabled.

**Example:**

```bash
export newDashboard=true
```

In this case, calling `isFeatureEnabled("newDashboard")` will return `true` regardless of the predicate function.

---

## Summary

The `isFeatureEnabled` and `setFeature` functions provide a flexible and robust way to manage feature flags in your application. By defining features as predicate functions, you can control which features are enabled based on complex logic while maintaining a fallback to environment variables for simple overrides. The error handling ensures that invalid feature definitions are caught early, preventing runtime issues.

---