-
-
Notifications
You must be signed in to change notification settings - Fork 205
Expand file tree
/
Copy pathFeatureGate.js
More file actions
147 lines (135 loc) · 5.3 KB
/
Copy pathFeatureGate.js
File metadata and controls
147 lines (135 loc) · 5.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
* GNU AGPL-3.0 License
*
* Copyright (c) 2021 - present core.ai . All rights reserved.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
* for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://opensource.org/licenses/AGPL-3.0.
*
*/
/*global less */
// jshint ignore: start
// @INCLUDE_IN_API_DOCS
/**
* FeatureGate defines util methods for enabling or disabling features in development based on a flag in local storage.
* A global `window.FeatureGate` object is made available in phoenix that can be called anytime after AppStart.
*
* ## Usage
* For Eg. You may have an extensions in development that colors phoenix in red. But you are working on a new feature
* that makes other colors available, but not yet ready for use. So put the extension behind a named feature gate
* so that only people who want to test the extension will be able to use it.
*
* ### creating a feature gate
* @example
* ```js
* // within extensions
* const FeatureGate = brackets.getModule("utils/FeatureGate"); // replace with `require` for core modules.
* const FEATURE_NEW_COLORS = 'myExtension.newColors';
* FeatureGate.registerFeatureGate(FEATURE_NEW_COLORS, false); // false is the default value
* ```
*
* ### checking if a feature is gated
* Once the feature is registered, use the below code to check if the feature can be safely enabled. For Eg., if
* you want to enable fancy colors based on the example above:
*
* @example
* ```js
* if(FeatureGate.isFeatureEnabled(FEATURE_NEW_COLORS)){
* // do fancy colors here
* }
* ```
* ### Enabling features for testing
* 1. Open developer tools > local storage
* 2. Add a new key with the key you have specified for the feature gate.
* In the above Eg., the key is `myExtension.newColors`
* 3. set the value in local storage to `enabled` to enable the feature or anything else to disable.
* @module utils/FeatureGate
*/
define(function (require, exports, module) {
/**
* Feature gate registered
*
* @const
* @type {string}
*/
const FEATURE_REGISTERED = "featureGateRegistered";
const ENABLED = 'enabled';
const DISABLED = 'disabled';
let EventDispatcher = require("utils/EventDispatcher");
let _FeatureGateMap = {};
/**
* Registers a named feature with the default enabled state.
* To register a feature gate with name `myExtension.newColors`
* const FEATURE_NEW_COLORS = 'myExtension.newColors';
* FeatureGate.registerFeatureGate(FEATURE_NEW_COLORS, false); // false is the default value here
*
* @param {string} featureName
* @param {boolean} enabledDefault
* @type {function}
*/
function registerFeatureGate(featureName, enabledDefault) {
if(typeof enabledDefault !== "boolean"){
console.warn(`Feature gate ${featureName} ignoring invalid default value: ${enabledDefault}`);
return;
}
_FeatureGateMap[featureName] = enabledDefault;
exports.trigger(FEATURE_REGISTERED, featureName, enabledDefault);
}
/**
* Returns an array of all named registered feature gates.
*
* @return {string[]} list of registered features
* @type {function}
*/
function getAllRegisteredFeatures() {
return Object.keys(_FeatureGateMap);
}
/**
* Returns true is an featureGate is enabled either by default or overridden by the user using local storage.
* To check if the feature `myExtension.newColors` is enabled
* const FEATURE_NEW_COLORS = 'myExtension.newColors';
* if(FeatureGate.isFeatureEnabled(FEATURE_NEW_COLORS)){
* // do fancy colors here
* }
*
* @param {string} featureName
* @return {boolean}
* @type {function}
*/
function isFeatureEnabled(featureName) {
let userOverRide = PhStore.getItem(`FeatureGate-${featureName}`);
if(userOverRide === ENABLED){
return true;
} else if(userOverRide === DISABLED){
return false;
}
return _FeatureGateMap[featureName] === true;
}
/**
* Sets the enabled state of a specific feature in the application.
*
* @param {string} featureName - The name of the feature to be modified.
* @param {boolean} isEnabled - A boolean flag indicating whether the feature should be enabled (true) or disabled (false).
*/
function setFeatureEnabled(featureName, isEnabled) {
PhStore.setItem(`FeatureGate-${featureName}`, isEnabled ? ENABLED : DISABLED);
}
EventDispatcher.makeEventDispatcher(exports);
// Public API
exports.registerFeatureGate = registerFeatureGate;
exports.getAllRegisteredFeatures = getAllRegisteredFeatures;
exports.isFeatureEnabled = isFeatureEnabled;
exports.setFeatureEnabled = setFeatureEnabled;
// Events
exports.FEATURE_REGISTERED = FEATURE_REGISTERED;
});