feature-toggle-api 4.0.0 → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +15 -8
- package/dist/feature-toggle.d.ts +21 -11
- package/dist/feature-toggle.js +12 -3
- package/dist/feature-toggle.min.cjs +1 -1
- package/dist/feature-toggle.min.cjs.map +1 -1
- package/dist/feature-toggle.min.js +1 -1
- package/dist/feature-toggle.min.js.map +1 -1
- package/dist/feature-toggle.umd.min.js +1 -1
- package/dist/feature-toggle.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/src/featureToggle.ts +18 -105
- package/src/index.ts +5 -2
- package/src/types.ts +117 -0
- package/tests/featuretoggle.test.ts +46 -3
- package/gulpfile.js +0 -65
- package/plugin-html.js +0 -1
- package/plugin-url.js +0 -1
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -138,14 +138,16 @@ api.setFlag('feature4','new',false);
|
|
|
138
138
|
api.setFlag('feature4','new',"some custom data",false);
|
|
139
139
|
```
|
|
140
140
|
|
|
141
|
-
Important: A visibilityrule
|
|
141
|
+
Important: A visibilityrule must not start with an underscore or $. Both is reserved. Attributes starting with an it are reserved for configuration settings.
|
|
142
142
|
```javascript
|
|
143
143
|
//This api has already initialized some visiblity rules:
|
|
144
144
|
var api = useFeatureToggle({
|
|
145
145
|
feature1: true, //visibilityrule feature1 -> true
|
|
146
146
|
plugins: true, //visibilityrule plugins -> true
|
|
147
|
-
_feature1: true, //_ is reserved for configuration -> this attribute does nothing
|
|
148
|
-
_plugins: [], //_ is reserved for configuration -> add plugins
|
|
147
|
+
_feature1: true, //_ is reserved for configuration (deprecated)-> this attribute does nothing
|
|
148
|
+
_plugins: [], //_ is reserved for configuration -> add plugins (deprecated). use $plugins instead
|
|
149
|
+
|
|
150
|
+
$plugins: [], //$ is reserved for configuration -> add plugins
|
|
149
151
|
});
|
|
150
152
|
```
|
|
151
153
|
|
|
@@ -372,7 +374,10 @@ Calling addPlugin() prevents you from from adding a plugin multiple times, so if
|
|
|
372
374
|
```javascript
|
|
373
375
|
function customFunctionPlugin(api){
|
|
374
376
|
//adds function customFunction to your api
|
|
375
|
-
|
|
377
|
+
|
|
378
|
+
return {
|
|
379
|
+
customFunction(){console.log('custom function created')}
|
|
380
|
+
}
|
|
376
381
|
}
|
|
377
382
|
|
|
378
383
|
//1st option: via constructor
|
|
@@ -391,13 +396,15 @@ Here's the way, how to add parameters to your plugin
|
|
|
391
396
|
{
|
|
392
397
|
return function (api){
|
|
393
398
|
//adds function customFunction to your api
|
|
394
|
-
|
|
399
|
+
return {
|
|
400
|
+
customFunction = function(){console.log('Hello ' + param1)}
|
|
401
|
+
}
|
|
395
402
|
}
|
|
396
403
|
}
|
|
397
404
|
|
|
398
405
|
//1st option: via constructor
|
|
399
406
|
//Important: don't forget the _ in the property _plugins!!!
|
|
400
|
-
const api = useFeatureToggle({
|
|
407
|
+
const api = useFeatureToggle({$plugins:[pluginWithParams('Peter')]});
|
|
401
408
|
|
|
402
409
|
//2nd option: via function
|
|
403
410
|
api.addPlugin(pluginWithParams('Peter'));
|
|
@@ -447,8 +454,8 @@ var api = useFeatureToggle({
|
|
|
447
454
|
})
|
|
448
455
|
```
|
|
449
456
|
|
|
450
|
-
###
|
|
451
|
-
Adds a
|
|
457
|
+
### Flag
|
|
458
|
+
Adds a Flag.
|
|
452
459
|
|
|
453
460
|
Parameters:
|
|
454
461
|
- name: name of the feature; required; type string
|
package/dist/feature-toggle.d.ts
CHANGED
|
@@ -30,26 +30,34 @@ declare function htmlPlugin(config?: HtmlPluginConfig): (api: any) => {
|
|
|
30
30
|
interface OnConfiguration {
|
|
31
31
|
ignorePreviousRules: boolean;
|
|
32
32
|
}
|
|
33
|
-
type Plugin = (api: any) =>
|
|
33
|
+
type Plugin = (api: any) => Partial<FeatureToggleApi>;
|
|
34
|
+
type EventType = 'visibilityrule' | 'init' | 'registerEvent' | string;
|
|
34
35
|
interface OnEvent {
|
|
35
36
|
name: string;
|
|
36
37
|
variant: string;
|
|
37
38
|
data: any;
|
|
38
39
|
result?: boolean;
|
|
39
40
|
}
|
|
40
|
-
|
|
41
|
-
type FirstCharOfFeatureFlagKey = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' |
|
|
42
|
-
'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';
|
|
43
|
-
|
|
41
|
+
type FirstCharOfFeatureFlagKey = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';
|
|
44
42
|
type FeatureFlagKey = `${FirstCharOfFeatureFlagKey}${string}`;
|
|
45
|
-
|
|
43
|
+
type FeatureFlag = boolean | ((rule: Rule) => boolean);
|
|
46
44
|
interface FeatureToggleConfig {
|
|
47
|
-
[key: FeatureFlagKey]:
|
|
45
|
+
[key: FeatureFlagKey]: FeatureFlag;
|
|
48
46
|
$plugins?: Plugin[];
|
|
49
47
|
/**
|
|
50
48
|
* @deprecated Use key`$plugins` instead.
|
|
51
49
|
*/
|
|
52
50
|
_plugins?: Plugin[];
|
|
51
|
+
/**
|
|
52
|
+
* This rule will always run before the main rule.
|
|
53
|
+
* If it returns false, the main rules will be skipped and false is returned
|
|
54
|
+
*/
|
|
55
|
+
$required?: FeatureFlag;
|
|
56
|
+
/**
|
|
57
|
+
* This rule will always run after the main rule.
|
|
58
|
+
* If the main rule returns false, the result of the default rule will be taken.s
|
|
59
|
+
*/
|
|
60
|
+
$default?: FeatureFlag;
|
|
53
61
|
}
|
|
54
62
|
interface Rule {
|
|
55
63
|
name: string;
|
|
@@ -58,15 +66,15 @@ interface Rule {
|
|
|
58
66
|
_internalCall?: true;
|
|
59
67
|
description?: string;
|
|
60
68
|
}
|
|
61
|
-
interface
|
|
69
|
+
interface FeatureToggleApiBase {
|
|
62
70
|
name: string;
|
|
63
71
|
setData(name: string, dataParam?: any): void;
|
|
64
72
|
setData(name: string, variant: string, dataParam?: any): void;
|
|
65
73
|
setData(nameParam: string, variantOrDataParam: string | {
|
|
66
74
|
[key: string]: any;
|
|
67
75
|
}, dataParam?: any): void;
|
|
68
|
-
on(eventType:
|
|
69
|
-
trigger(eventtype:
|
|
76
|
+
on(eventType: EventType, fn: (event: OnEvent) => void, config?: OnConfiguration): void;
|
|
77
|
+
trigger(eventtype: EventType, param?: any): any;
|
|
70
78
|
showLogs(showLogs?: boolean): void;
|
|
71
79
|
/**
|
|
72
80
|
* @deprecated Use `featureToggle.isActive` instead.
|
|
@@ -115,6 +123,8 @@ interface FeatureToggleApi {
|
|
|
115
123
|
setDefaultFlag(fn: boolean | ((result: Rule) => boolean)): void;
|
|
116
124
|
addPlugin(plugin: Plugin): any;
|
|
117
125
|
}
|
|
126
|
+
type FeatureToggleApi = FeatureToggleApiBase & Record<string, any>;
|
|
127
|
+
|
|
118
128
|
declare function useFeatureToggle(config?: FeatureToggleConfig): FeatureToggleApi;
|
|
119
129
|
|
|
120
|
-
export { htmlPlugin, urlPlugin, useFeatureToggle };
|
|
130
|
+
export { type EventType, type FeatureFlag, type FeatureFlagKey, type FeatureToggleApi, type FeatureToggleApiBase, type FeatureToggleConfig, type FirstCharOfFeatureFlagKey, type OnConfiguration, type OnEvent, htmlPlugin, urlPlugin, useFeatureToggle };
|
package/dist/feature-toggle.js
CHANGED
|
@@ -144,6 +144,12 @@ function useFeatureToggle(config = {}) {
|
|
|
144
144
|
usedPlugins: [],
|
|
145
145
|
};
|
|
146
146
|
function init(api) {
|
|
147
|
+
if (config.$default) {
|
|
148
|
+
api.setDefaultFlag(config.$default);
|
|
149
|
+
}
|
|
150
|
+
if (config.$required) {
|
|
151
|
+
api.setRequiredFlag(config.$required);
|
|
152
|
+
}
|
|
147
153
|
const allPlugins = [...(config.$plugins || []), ...(config._plugins || [])];
|
|
148
154
|
if (config._plugins) {
|
|
149
155
|
console.log('useFeatureToggle({_plugins:[]}): Key _plugins is deprecated. Use $plugins instead. This attribute will be removed in one of the next major versions.');
|
|
@@ -152,7 +158,7 @@ function useFeatureToggle(config = {}) {
|
|
|
152
158
|
allPlugins.forEach(plugin => {
|
|
153
159
|
if (typeof plugin !== 'function')
|
|
154
160
|
throw new Error('featuretoggleapi()-constructor: config.plugins needs functions as entries, not ' + typeof plugin + '.');
|
|
155
|
-
plugin
|
|
161
|
+
api.addPlugin(plugin);
|
|
156
162
|
});
|
|
157
163
|
}
|
|
158
164
|
triggerEvent('init');
|
|
@@ -315,7 +321,7 @@ function useFeatureToggle(config = {}) {
|
|
|
315
321
|
globals.datas[event.key] = event.data;
|
|
316
322
|
triggerEvent('visibilityrule', event);
|
|
317
323
|
},
|
|
318
|
-
on
|
|
324
|
+
on(eventtype, fn, config) {
|
|
319
325
|
globals.listeners[eventtype] = globals.listeners[eventtype] || [];
|
|
320
326
|
globals.listeners[eventtype].push(fn);
|
|
321
327
|
triggerEvent('registerEvent', {
|
|
@@ -377,7 +383,10 @@ function useFeatureToggle(config = {}) {
|
|
|
377
383
|
addPlugin: function (plugin) {
|
|
378
384
|
if (globals.usedPlugins.includes(plugin))
|
|
379
385
|
return;
|
|
380
|
-
plugin(api);
|
|
386
|
+
const newPlugin = plugin(api);
|
|
387
|
+
for (let _key of Object.keys(newPlugin)) {
|
|
388
|
+
api[_key] = newPlugin[_key];
|
|
389
|
+
}
|
|
381
390
|
globals.usedPlugins.push(plugin);
|
|
382
391
|
},
|
|
383
392
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";const e={renderedTag:"div",featureTagName:"feature",tagAttributeName:"tag",nameAttributeName:"name",variantAttributeName:"variant",dataAttributeName:"data",displayAttributeName:"display",defaultDisplay:"block"};function t(e){return"boolean"==typeof e?function(){return e}:e}function i(e,t){var i=e.toLowerCase();return t&&"string"==typeof t&&(i+="#"+t.toLowerCase()),i}function n(e={}){const n={};return Object.keys(e).forEach((r=>{r.startsWith("_")||r.startsWith("$")||(n[i(r)]=t(e[r]))})),n}exports.htmlPlugin=function(t={}){function i(e,i){const n=e.getAttribute(t.tagAttributeName)||t.renderedTag,r=Array.from(e.attributes);let l="";r.forEach((e=>{l+=` ${e.nodeName}="${e.nodeValue.replace(/"/g,""")}"`}));const a=i?e.getAttribute(t.displayAttributeName)||t.defaultDisplay:"none";e.outerHTML=`<${n} style="display:${a}" _feature="true" ${l}>${e.innerHTML}</${n}>`}return t=Object.assign({},e,t),function(e){return window.document.querySelectorAll(t.featureTagName).forEach((e=>{i(e,!1)})),e.on("visibilityrule",(function(n){var r=`[_feature][${t.nameAttributeName}="${n.name}"]`;n.variant&&(r+=`[${t.variantAttributeName}="${n.variant}"]`),document.querySelectorAll(r).forEach((r=>{const l=function(e){try{return JSON.parse(e)}catch(t){return isNaN(parseFloat(e))?e:parseFloat(e)}}(r.getAttribute(t.dataAttributeName));i(r,e.isVisible(n.name,n.variant,l))}))})),{name:"htmlplugin"}}},exports.urlPlugin=function(e={}){let t;return t=e.useMockedWindow?{isMocked:!0,decodeURIComponent:function(e){return e}}:window,e=Object.assign({},{url:t.isMocked?"":t.location.href,prefix:""},e),function(i){i.url=e.url;const n=function(e,t){var i={};if(!e)return[];var n=e.split("?");return n.length<2?[]:(n[1].split("&").forEach((function(e){var n=e.split("=");n[0]=t.decodeURIComponent(n[0]),n[1]="true"===t.decodeURIComponent(n[1]),i[n[0]]="undefined"===n[1]||n[1]})),i)}(e.url,t),r=e.prefix;return Object.keys(n).forEach((e=>{if(!e.startsWith(r))return;const t=e.replace(r,"");i.visibility(t,n[e])})),{name:"urlplugin"}}},exports.useFeatureToggle=function(e={}){const r={datas:{},listeners:{},visibilities:n(e),showLogs:!1,usedPlugins:[]};function l(e,t){(r.listeners[e]||[]).forEach((e=>{e(t)}))}const a=function(e){if(r.showLogs)if("undefined"!=typeof window){var t=-1!=e.indexOf("<b>"),i=-1!=e.indexOf("visible"),n=-1!=e.indexOf("hidden"),l=e.replace("visible","%cvisible");if(l=l.replace("hidden","%chidden"),i)console.log(l,"color:green;font-weight:bold;");else if(n)console.log(l,"color:red;font-weight:bold;");else if(t){var a=[l=l.replace("<b>","%c"),"font-weight:bold;"];console.log.apply(null,a)}else console.log(e)}else{const t=e.replace(/<b>/g,"");console.log(t)}},u=function(e,t){return a(t),a(""),e},s=function(e,t,i,n,r){if(null!=e){var l=e({name:i,variant:n,data:r});return"boolean"==typeof l?l:u(!1,`The ${t} returns ${l}. => Please return true or false. This result (and all non-boolean results) will return false.`)}};function o(e,n,r,l){let a;return a={name:e,variant:n,data:r},a.key=i(a.name,a.variant),null==l||(a.visibilityFunction=t(l),a.result=a.visibilityFunction({name:a.name,variant:a.variant,data:a.data||{},_internalCall:!0,description:"When attaching a function, the result must be calculated internally. You can filter this out with the _internalCall:true -Flag."})),a}function f(e,t,n){const l=r.visibilities;if(a(`\nCheck Visibility of <b>Feature "${e}", variant "${null==t?"":t}"${n?" with data "+JSON.stringify(n):""}.`),null==e)throw new Error('The attribute "name" is required for tag <feature></feature>. Example: <feature name="aname"></feature>');var o=l._required,f=null!=l._required,d=s(o,"requiredVisibility",e,t,n),c=i(e,t),b=l[c],g=null!=l[c],h=s(b,"visibility function",e,t,n),v=null!=t,m=l[i(e,null)],
|
|
1
|
+
"use strict";const e={renderedTag:"div",featureTagName:"feature",tagAttributeName:"tag",nameAttributeName:"name",variantAttributeName:"variant",dataAttributeName:"data",displayAttributeName:"display",defaultDisplay:"block"};function t(e){return"boolean"==typeof e?function(){return e}:e}function i(e,t){var i=e.toLowerCase();return t&&"string"==typeof t&&(i+="#"+t.toLowerCase()),i}function n(e={}){const n={};return Object.keys(e).forEach((r=>{r.startsWith("_")||r.startsWith("$")||(n[i(r)]=t(e[r]))})),n}exports.htmlPlugin=function(t={}){function i(e,i){const n=e.getAttribute(t.tagAttributeName)||t.renderedTag,r=Array.from(e.attributes);let l="";r.forEach((e=>{l+=` ${e.nodeName}="${e.nodeValue.replace(/"/g,""")}"`}));const a=i?e.getAttribute(t.displayAttributeName)||t.defaultDisplay:"none";e.outerHTML=`<${n} style="display:${a}" _feature="true" ${l}>${e.innerHTML}</${n}>`}return t=Object.assign({},e,t),function(e){return window.document.querySelectorAll(t.featureTagName).forEach((e=>{i(e,!1)})),e.on("visibilityrule",(function(n){var r=`[_feature][${t.nameAttributeName}="${n.name}"]`;n.variant&&(r+=`[${t.variantAttributeName}="${n.variant}"]`),document.querySelectorAll(r).forEach((r=>{const l=function(e){try{return JSON.parse(e)}catch(t){return isNaN(parseFloat(e))?e:parseFloat(e)}}(r.getAttribute(t.dataAttributeName));i(r,e.isVisible(n.name,n.variant,l))}))})),{name:"htmlplugin"}}},exports.urlPlugin=function(e={}){let t;return t=e.useMockedWindow?{isMocked:!0,decodeURIComponent:function(e){return e}}:window,e=Object.assign({},{url:t.isMocked?"":t.location.href,prefix:""},e),function(i){i.url=e.url;const n=function(e,t){var i={};if(!e)return[];var n=e.split("?");return n.length<2?[]:(n[1].split("&").forEach((function(e){var n=e.split("=");n[0]=t.decodeURIComponent(n[0]),n[1]="true"===t.decodeURIComponent(n[1]),i[n[0]]="undefined"===n[1]||n[1]})),i)}(e.url,t),r=e.prefix;return Object.keys(n).forEach((e=>{if(!e.startsWith(r))return;const t=e.replace(r,"");i.visibility(t,n[e])})),{name:"urlplugin"}}},exports.useFeatureToggle=function(e={}){const r={datas:{},listeners:{},visibilities:n(e),showLogs:!1,usedPlugins:[]};function l(e,t){(r.listeners[e]||[]).forEach((e=>{e(t)}))}const a=function(e){if(r.showLogs)if("undefined"!=typeof window){var t=-1!=e.indexOf("<b>"),i=-1!=e.indexOf("visible"),n=-1!=e.indexOf("hidden"),l=e.replace("visible","%cvisible");if(l=l.replace("hidden","%chidden"),i)console.log(l,"color:green;font-weight:bold;");else if(n)console.log(l,"color:red;font-weight:bold;");else if(t){var a=[l=l.replace("<b>","%c"),"font-weight:bold;"];console.log.apply(null,a)}else console.log(e)}else{const t=e.replace(/<b>/g,"");console.log(t)}},u=function(e,t){return a(t),a(""),e},s=function(e,t,i,n,r){if(null!=e){var l=e({name:i,variant:n,data:r});return"boolean"==typeof l?l:u(!1,`The ${t} returns ${l}. => Please return true or false. This result (and all non-boolean results) will return false.`)}};function o(e,n,r,l){let a;return a={name:e,variant:n,data:r},a.key=i(a.name,a.variant),null==l||(a.visibilityFunction=t(l),a.result=a.visibilityFunction({name:a.name,variant:a.variant,data:a.data||{},_internalCall:!0,description:"When attaching a function, the result must be calculated internally. You can filter this out with the _internalCall:true -Flag."})),a}function f(e,t,n){const l=r.visibilities;if(a(`\nCheck Visibility of <b>Feature "${e}", variant "${null==t?"":t}"${n?" with data "+JSON.stringify(n):""}.`),null==e)throw new Error('The attribute "name" is required for tag <feature></feature>. Example: <feature name="aname"></feature>');var o=l._required,f=null!=l._required,d=s(o,"requiredVisibility",e,t,n),c=i(e,t),b=l[c],g=null!=l[c],h=s(b,"visibility function",e,t,n),v=null!=t,m=l[i(e,null)],y=s(m,"visibility function (only name)",e,t,n),p=l._default,w=null!=l._default,T=s(p,"defaultVisibility",e,t,n);if(f){if(f&&!0===d)a("The requiredVisibility rule returns true. This feature will be shown when no other rule rejects it.");else if(f&&!1===d)return u(!1,"The requiredVisibility rule returns false. This feature will be hidden.")}else a("No requiredVisibility rule specified for this feature.");return g?u(h,`The visibility rule returns ${h}. This feature will be ${h?"visible":"hidden"}.`):(a("No visibility rule found matching name and variant."),v&&"boolean"==typeof y?u(y,`Found a visibility rule for name ${e} without variants. The rule returns ${y}. => This feature will be ${y?"visible":"hidden"}.`):(v&&a(`No rules found for name ${e} without variants.`),w?u(T,`Found a defaultVisibility rule. The rule returns ${T}. => This feature will be ${T?"visible":"hidden"}.`):(a("No default rule found."),f?u(!0,"Only the requiredVisibility rule was found. This returned true. => This feature will be visible."):u(!1,"No rules were found. This feature will be hidden."))))}const d={name:"feature-toggle-api",setData:function(e,t,i){if(null==e)throw new Error("setData(): The name must of the feature must be defined, but ist undefined");const n=o(e,null!=i?t:void 0,i||t);r.datas[n.key]=n.data,l("visibilityrule",n)},on(e,t,i){r.listeners[e]=r.listeners[e]||[],r.listeners[e].push(t),l("registerEvent",{type:e}),null!=i&&i.ignorePreviousRules||Object.keys(r.visibilities).forEach((e=>{const i=function(e){const t=e.split("#");return{name:t[0],variant:t.length>1?t[1]:void 0,data:r.datas[e]}}(e),n=r.visibilities[e];i.result=n(i),t(i)}))},trigger:l,showLogs:function(e){r.showLogs=null==e||e},isVisible:(e,t,i)=>(console.log("featureToggle.isVisible is deprecated. use featureToggle.isActive instead. This function will be removed in one of the next major versions."),f(e,t,i)),isActive:f,setFlag(e,t,i,n){const a=function(e,t,i,n){if(null==e)throw new Error("feature.visibility(): 1st parameter name must be defined");if(1==arguments.length)throw new Error("feature.visibility(): 2nd parameter name must be a boolean or function, but is empty");let r=null,l=null,a=null;return null==i&&null==n?a=t:null==n?(r=t,a=i):(r=t,l=i,a=n),{name:e,variant:r,data:l,result:a}}(e,t,i,n),u=o(a.name,a.variant,a.data,a.result);r.visibilities[u.key]=u.visibilityFunction,r.datas[u.key]=u.data,l("visibilityrule",u)},visibility:function(e,t,i,n){console.log("featureToggle.visibility is deprecated. use featureToggle.setVisibility instead. This function will be removed in one of the next major versions."),d.setFlag(e,t,i,n)},requiredVisibility:function(e){console.log("featureToggle.requiredVisibility is deprecated. use featureToggle.setRequiredFlag instead. This function will be removed in one of the next major versions."),d.setRequiredFlag(e)},defaultVisibility:function(e){console.log("featureToggle.requiredVisibility is deprecated. use featureToggle.setRequiredFlag instead. This function will be removed in one of the next major versions."),d.setDefaultFlag(e)},setRequiredFlag(e){if("function"!=typeof e)throw new Error("feature.setRequiredFlag(): 1st parameter must be a function, but is "+typeof e);r.visibilities._required=t(e)},setDefaultFlag(e){if("function"!=typeof e)throw new Error("feature.defaultVisibility(): 1st parameter must be a function, but is "+typeof e);r.visibilities._default=t(e)},addPlugin:function(e){if(r.usedPlugins.includes(e))return;const t=e(d);for(let e of Object.keys(t))d[e]=t[e];r.usedPlugins.push(e)}};return function(t){e.$default&&t.setDefaultFlag(e.$default),e.$required&&t.setRequiredFlag(e.$required);const i=[...e.$plugins||[],...e._plugins||[]];e._plugins&&console.log("useFeatureToggle({_plugins:[]}): Key _plugins is deprecated. Use $plugins instead. This attribute will be removed in one of the next major versions."),i.length&&i.forEach((e=>{if("function"!=typeof e)throw new Error("featuretoggleapi()-constructor: config.plugins needs functions as entries, not "+typeof e+".");t.addPlugin(e)})),l("init")}(d),d};
|
|
2
2
|
//# sourceMappingURL=feature-toggle.min.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-toggle.min.cjs","sources":["../src/plugins/htmlplugin/plugin-html.ts","../src/featureToggle.ts","../src/plugins/urlplugin/plugin-url.ts"],"sourcesContent":["type Display = 'block' | 'inline-block' | 'inline' | 'flex' | 'inline-flex' | 'grid' | 'inline-grid';\n\ninterface HtmlPluginConfig {\n renderedTag?: string,\n featureTagName?: string,\n tagAttributeName?: string,\n nameAttributeName?:string,\n variantAttributeName?: string,\n dataAttributeName?: string,\n displayAttributeName?: string,\n defaultDisplay?: Display,\n}\n\n/*\n creates a tag that is shown / hidden, depending on the visibility rules.\n if not configured dynamically, it looks like this:\n <feature name=\"featurename\" variant=\"variantname\" data=\"data\">content </feature>\n\n Parameter: (config)\n - config.featureTagName: name of the tag. Default: \"feature\"\n - nameAttributeName: Name of the Name-Attribute: default: \"name\"\n - variantAttributeName: Name of the Variant-Attribute: default: \"variant\"\n*/\nconst defaultparams :HtmlPluginConfig = {\n renderedTag: 'div',\n featureTagName: 'feature',\n tagAttributeName: 'tag',\n nameAttributeName:'name',\n variantAttributeName: 'variant',\n dataAttributeName: 'data',\n displayAttributeName: 'display',\n defaultDisplay: 'block',\n}\nfunction parseDataAttribute(attrAsString){\n try{\n return JSON.parse(attrAsString);\n }\n catch(e)\n {\n if(!isNaN(parseFloat(attrAsString)))\n return parseFloat(attrAsString);\n \n return attrAsString;\n }\n}\n\nfunction htmlPlugin(config :HtmlPluginConfig = {}) {\n config = Object.assign({},defaultparams,config);\n\n function renderFeatureTag(elem:HTMLElement,isVisible){\n const tagname = elem.getAttribute(config.tagAttributeName) || config.renderedTag;\n const attributes = Array.from(elem.attributes);\n let attributesAsString = \"\";\n attributes.forEach(attr => {\n attributesAsString += ` ${attr.nodeName}=\"${attr.nodeValue.replace(/\"/g,\""\")}\"`;\n });\n const display = isVisible ? (elem.getAttribute(config.displayAttributeName) || config.defaultDisplay) : 'none';\n elem.outerHTML = `<${tagname} style=\"display:${display}\" _feature=\"true\" ${attributesAsString}>${elem.innerHTML}</${tagname}>`;\n } \n return function (api) {\n var renderedTags :NodeListOf<HTMLElement> = window.document.querySelectorAll(config.featureTagName);\n renderedTags.forEach(tag => { renderFeatureTag(tag,false) });\n\n api.on('visibilityrule', function (event) {\n var selector = `[_feature][${config.nameAttributeName}=\"${event.name}\"]`;\n if (event.variant) selector += `[${config.variantAttributeName}=\"${event.variant}\"]`;\n var elements :NodeListOf<HTMLElement> = document.querySelectorAll(selector);\n elements.forEach(elem => { \n const dataAsString = elem.getAttribute(config.dataAttributeName);\n const data = parseDataAttribute(dataAsString);\n \n const isVisible = api.isVisible(event.name,event.variant,data);\n renderFeatureTag(elem, isVisible);\n });\n })\n\n return { name: 'htmlplugin' };\n }\n}\n\nexport {\n htmlPlugin\n}","interface OnConfiguration {\n ignorePreviousRules: boolean\n}\ntype Plugin = (api) => void;\n\ninterface OnEvent {\n name: string,\n variant: string,\n data: any,\n result?: boolean\n}\n\ntype FirstCharOfFeatureFlagKey = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' |\n 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';\n \ntype FeatureFlagKey = `${FirstCharOfFeatureFlagKey}${string}`;\n\ninterface FeatureToggleConfig {\n [key: FeatureFlagKey]: boolean | (() => boolean),\n $plugins?: Plugin[]\n /**\n * @deprecated Use key`$plugins` instead.\n */\n _plugins?: Plugin[]\n}\n\ninterface Rule {\n name: string,\n variant: string,\n data: any,\n _internalCall?: true,\n description?: string\n}\n\ninterface FeatureToggleApi {\n name: string,\n setData(name: string, dataParam?: any): void;\n setData(name: string, variant: string, dataParam?: any): void,\n setData(nameParam: string, variantOrDataParam: string | { [key: string]: any },\n dataParam?: any): void;\n\n on(eventType: string, fn: (event: OnEvent) => void, config?: OnConfiguration): void;\n trigger(eventtype: string, param?: any);\n showLogs(showLogs?: boolean): void\n\n /**\n * @deprecated Use `featureToggle.isActive` instead.\n */\n isVisible(name: string, variant?: string, data?: any): boolean\n\n isActive(name: string, variant?: string, data?: any): boolean\n\n /**\n * @deprecated Use `featureToggle.setFlag` instead.\n */\n visibility(name: string, result: boolean | ((rule: Rule) => boolean)): void,\n /**\n * @deprecated Use `featureToggle.setFlag` instead.\n */\n visibility(name: string, variant: string | null, result: boolean | ((rule: Rule) => boolean)): void\n /**\n * @deprecated Use `featureToggle.setFlag` instead.\n */\n visibility(name: string, variant: string | null, data: any, result: boolean | ((rule: Rule) => boolean)): void,\n /**\n * @deprecated Use `featureToggle.setFlag` instead.\n */\n visibility(name: string, resultOrVariant: string | null | boolean | ((rule: Rule) => boolean), resultOrData?: any, result?: boolean | (() => boolean)): void\n\n setFlag(name: string, result: boolean | ((rule: Rule) => boolean)): void,\n setFlag(name: string, variant: string | null, result: boolean | ((rule: Rule) => boolean)): void,\n setFlag(name: string, variant: string | null, data: any, result: boolean | ((rule: Rule) => boolean)): void,\n setFlag(name: string, resultOrVariant: string | null | boolean | ((rule: Rule) => boolean), resultOrData?: any, result?: boolean | (() => boolean)): void\n\n /**\n * @deprecated Use `featureToggle.setRequiredFlag` instead.\n */\n requiredVisibility(fn: boolean | ((result: Rule) => boolean)): void\n\n /**\n * @deprecated Use `featureToggle.setDefaultFlag` instead.\n */\n defaultVisibility(fn: boolean | ((result: Rule) => boolean)): void\n\n /**\n * This rule will run first and only if it is true, the feature.setFlag() - rules apply.\n * In other words: if the required-rule returns false, all feature.setFlag-rules return false - regardless of its normal result.\n * @param fn \n */\n setRequiredFlag(fn: boolean | ((result: Rule) => boolean)): void\n\n /**\n * This is the default-rule and will be overwritten by feature.setFlag() - rules.\n * In other words: If feature.setFlag == false, the result of the defaultRule applies.\n * @param fn DefaultRule\n */\n setDefaultFlag(fn: boolean | ((result: Rule) => boolean)): void\n\n addPlugin(plugin: Plugin)\n}\n\nfunction parseToFn(fnOrBool: boolean | ((param?: any) => boolean)) {\n if (typeof fnOrBool == 'boolean')\n return function () { return fnOrBool };\n\n return fnOrBool;\n}\n\nfunction getKey(name: string, variant?: string): string {\n var _name = name.toLowerCase();\n if (variant && typeof variant == 'string') {\n _name += \"#\" + variant.toLowerCase();\n }\n\n return _name;\n}\n\nfunction initVisibilities(visibilities: FeatureToggleConfig = {}) {\n const returnVisibilities = {};\n Object.keys(visibilities).forEach(key => {\n if (key.startsWith('_') || key.startsWith('$'))\n return;\n returnVisibilities[getKey(key)] = parseToFn(visibilities[key]);\n });\n return returnVisibilities;\n}\n\nfunction useFeatureToggle(config: FeatureToggleConfig = {}): FeatureToggleApi {\n\n const globals = {\n datas: {},\n listeners: {},\n visibilities: initVisibilities(config),\n showLogs: false,\n usedPlugins: [],\n }\n\n function init(api) {\n const allPlugins = [...(config.$plugins||[]),...(config._plugins||[])];\n if(config._plugins){\n console.log('useFeatureToggle({_plugins:[]}): Key _plugins is deprecated. Use $plugins instead. This attribute will be removed in one of the next major versions.');\n }\n\n\n if (allPlugins.length) {\n allPlugins.forEach(plugin => {\n if (typeof plugin !== 'function')\n throw new Error('featuretoggleapi()-constructor: config.plugins needs functions as entries, not ' + typeof plugin + '.');\n\n plugin(api);\n });\n }\n\n triggerEvent('init');\n }\n\n function triggerEvent(eventtype: string, param?: any) {\n (globals.listeners[eventtype] || []).forEach(listener => {\n listener(param);\n });\n }\n\n const log = function (message) {\n if (!globals.showLogs)\n return;\n\n //Nur Browser können Syntaxhighlighting die anderen geben die Nachricht einfach aus und schneiden\n //die styletags raus\n if (typeof window === 'undefined') {\n const loggedMessage = message.replace(/<b>/g, \"\");\n console.log(loggedMessage);\n return;\n }\n\n var hasBoldTag = message.indexOf('<b>') != -1;\n var hasVisibleKeyword = message.indexOf('visible') != -1;\n var hasHiddenKeyword = message.indexOf('hidden') != -1;\n\n var _message = message.replace('visible', '%cvisible');\n _message = _message.replace('hidden', '%chidden');\n\n if (hasVisibleKeyword)\n console.log(_message, \"color:green;font-weight:bold;\");\n else if (hasHiddenKeyword)\n console.log(_message, \"color:red;font-weight:bold;\");\n else if (hasBoldTag) {\n _message = _message.replace('<b>', '%c');\n var parts = [_message, 'font-weight:bold;']\n console.log.apply(null, parts);\n }\n else\n console.log(message);\n }\n\n const logAndReturn = function (returnValue, message) {\n log(message);\n log('');\n return returnValue;\n }\n\n const getVisibility = function (visibilityFn, functionname, name, variant, data) {\n if (visibilityFn == null)\n return undefined;\n\n var calculatedVisibility = visibilityFn({ name: name, variant: variant, data: data });\n\n if (typeof calculatedVisibility == 'boolean') {\n return calculatedVisibility;\n }\n\n return logAndReturn(false, `The ${functionname} returns ${calculatedVisibility}. => Please return true or false. This result (and all non-boolean results) will return false.`);\n }\n\n function parseKey(key: string): OnEvent {\n const parts = key.split('#');\n return {\n name: parts[0],\n variant: parts.length > 1 ? parts[1] : undefined,\n data: globals.datas[key],\n }\n }\n\n /*\n the following calls are possible:\n visibility(name,result);\n visibility(name,variant,result);\n visibility(name,variant,data,result);\n \n =>\n param1: name\n param2: result || variant\n param3: result || data\n param4: result\n */\n function visibilityFnParams(param1, param2, param3, param4) {\n //name must always be set\n if (param1 == undefined)\n throw new Error('feature.visibility(): 1st parameter name must be defined');\n\n if (arguments.length == 1)\n throw new Error('feature.visibility(): 2nd parameter name must be a boolean or function, but is empty');\n\n let name = param1, variant = null, data = null, result = null;\n if (param3 == undefined && param4 == undefined) {\n result = param2;\n }\n else if (param4 == undefined) {\n variant = param2;\n result = param3;\n }\n else {\n variant = param2;\n data = param3;\n result = param4;\n }\n\n return {\n name,\n variant,\n data,\n result\n }\n }\n\n function getEvent(name: string, variant: string, data?, result?: any) {\n\n let event;\n\n event = { name, variant, data };\n\n event.key = getKey(event.name, event.variant);\n\n if (result == null)\n return event;\n\n event.visibilityFunction = parseToFn(result);\n event.result = event.visibilityFunction({\n name: event.name,\n variant: event.variant,\n data: event.data || {},\n _internalCall: true,\n description: 'When attaching a function, the result must be calculated internally. You can filter this out with the _internalCall:true -Flag.'\n })\n return event;\n }\n\n\n\n function isActive(name: string, variant?: string, data?: any): boolean {\n const visibilities = globals.visibilities;\n\n log(`\\nCheck Visibility of <b>Feature \"${name}\", variant \"${variant == undefined ? '' : variant}\"${data ? \" with data \" + JSON.stringify(data) : \"\"}.`);\n if (name == undefined)\n throw new Error('The attribute \"name\" is required for tag <feature></feature>. Example: <feature name=\"aname\"></feature>');\n\n var requiredFn = visibilities['_required'];\n var requiredFnExists = visibilities['_required'] != null;\n var requiredFnResult = getVisibility(requiredFn, 'requiredVisibility', name, variant, data);\n\n var visibilityFnKey = getKey(name, variant);\n var visibilityFn = visibilities[visibilityFnKey];\n var visibilityFnExists = visibilities[visibilityFnKey] != null;\n var visibilityFnResult = getVisibility(visibilityFn, 'visibility function', name, variant, data);\n\n var variantExists = variant != null;\n var visibilityOnlyNameFnKey = getKey(name, null);\n var visibilityOnlyNameFn = visibilities[visibilityOnlyNameFnKey];\n var visibilityOnlyNameFnExists = visibilities[visibilityOnlyNameFnKey] != null;\n var visibilityOnlyNameFnResult = getVisibility(visibilityOnlyNameFn, 'visibility function (only name)', name, variant, data);\n\n var defaultFn = visibilities['_default'];\n var defaultFnExists = visibilities['_default'] != null;\n var defaultFnResult = getVisibility(defaultFn, 'defaultVisibility', name, variant, data);\n\n if (!requiredFnExists)\n log(\"No requiredVisibility rule specified for this feature.\");\n else if (requiredFnExists && requiredFnResult === true)\n log(\"The requiredVisibility rule returns true. This feature will be shown when no other rule rejects it.\")\n else if (requiredFnExists && requiredFnResult === false)\n return logAndReturn(false, \"The requiredVisibility rule returns false. This feature will be hidden.\");\n\n if (visibilityFnExists)\n return logAndReturn(visibilityFnResult, `The visibility rule returns ${visibilityFnResult}. This feature will be ${visibilityFnResult ? 'visible' : 'hidden'}.`);\n log('No visibility rule found matching name and variant.');\n\n if (variantExists && typeof visibilityOnlyNameFnResult == 'boolean')\n return logAndReturn(visibilityOnlyNameFnResult, `Found a visibility rule for name ${name} without variants. The rule returns ${visibilityOnlyNameFnResult}. => This feature will be ${visibilityOnlyNameFnResult ? 'visible' : 'hidden'}.`);\n else if (variantExists)\n log(`No rules found for name ${name} without variants.`)\n\n\n if (defaultFnExists)\n return logAndReturn(defaultFnResult, `Found a defaultVisibility rule. The rule returns ${defaultFnResult}. => This feature will be ${defaultFnResult ? 'visible' : 'hidden'}.`);\n log(`No default rule found.`)\n\n if (requiredFnExists)\n return logAndReturn(true, `Only the requiredVisibility rule was found. This returned true. => This feature will be visible.`);\n\n return logAndReturn(false, 'No rules were found. This feature will be hidden.');\n }\n\n const api: FeatureToggleApi = {\n name: 'feature-toggle-api',\n setData: function (nameParam, variantOrDataParam, dataParam?): void {\n if (nameParam == undefined)\n throw new Error('setData(): The name must of the feature must be defined, but ist undefined');\n\n const variant = (dataParam != undefined ? variantOrDataParam : undefined) as string;\n const data = dataParam || variantOrDataParam;\n\n const event = getEvent(nameParam, variant, data);\n\n globals.datas[event.key] = event.data;\n\n triggerEvent('visibilityrule', event);\n },\n on: function (eventtype: string, fn, config?) {\n globals.listeners[eventtype] = globals.listeners[eventtype] || [];\n globals.listeners[eventtype].push(fn);\n\n triggerEvent('registerEvent', {\n type: eventtype\n })\n if (config != undefined && config.ignorePreviousRules)\n return;\n\n \n Object.keys(globals.visibilities).forEach(key => {\n const event = parseKey(key);\n const rule = globals.visibilities[key];\n event.result = rule(event);\n fn(event);\n });\n },\n trigger: triggerEvent,\n showLogs: function (showLogs?: boolean): void {\n globals.showLogs = showLogs == undefined ? true : showLogs;\n },\n isVisible(name,variant,data){\n console.log('featureToggle.isVisible is deprecated. use featureToggle.isActive instead. This function will be removed in one of the next major versions.');\n return isActive(name,variant,data);\n },\n isActive,\n /**\n the following function calls are possible:\n visibility(name,result);\n visibility(name,variant,result);\n visibility(name,variant,data,result);\n */\n setFlag(name, resultOrVariant, resultOrData?, result?) {\n const params = visibilityFnParams(name, resultOrVariant, resultOrData, result);\n const event = getEvent(params.name, params.variant, params.data, params.result);\n\n globals.visibilities[event.key] = event.visibilityFunction;\n globals.datas[event.key] = event.data;\n triggerEvent('visibilityrule', event);\n },\n visibility: function (name, resultOrVariant, resultOrData?, result?) {\n console.log('featureToggle.visibility is deprecated. use featureToggle.setVisibility instead. This function will be removed in one of the next major versions.');\n\n api.setFlag(name, resultOrVariant, resultOrData, result);\n },\n requiredVisibility: function (fn) {\n console.log('featureToggle.requiredVisibility is deprecated. use featureToggle.setRequiredFlag instead. This function will be removed in one of the next major versions.');\n\n api.setRequiredFlag(fn);\n },\n defaultVisibility: function (fn) {\n console.log('featureToggle.requiredVisibility is deprecated. use featureToggle.setRequiredFlag instead. This function will be removed in one of the next major versions.');\n\n api.setDefaultFlag(fn);\n },\n setRequiredFlag(fn) {\n if (typeof fn != \"function\")\n throw new Error('feature.setRequiredFlag(): 1st parameter must be a function, but is ' + typeof fn);\n\n globals.visibilities['_required'] = parseToFn(fn);\n },\n setDefaultFlag(fn) {\n if (typeof fn != \"function\")\n throw new Error('feature.defaultVisibility(): 1st parameter must be a function, but is ' + typeof fn);\n\n globals.visibilities['_default'] = parseToFn(fn);\n },\n addPlugin: function (plugin) {\n if (globals.usedPlugins.includes(plugin))\n return;\n\n plugin(api);\n\n globals.usedPlugins.push(plugin);\n },\n };\n init(api);\n\n return api;\n}\n\nexport default useFeatureToggle;","interface URLPluginConfig{\n useMockedWindow?: boolean,\n url?: string,\n prefix?: string\n\n}\n\nfunction useWindowMock(){\n return {\n isMocked: true,\n decodeURIComponent:function(param1){\n return param1;\n }\n }\n}\n\ndeclare global {\n interface Window {\n isMocked: boolean\n }\n }\n\n declare var window: Window;\n\nfunction parseValue(value){\n if(value === 'true')\n return true;\n return false;\n}\n\nfunction getParams(url,window) {\n var params = {};\n if (!url) \n return [];\n \n var urlparts = url.split(\"?\");\n\n //no params available for url\n if(urlparts.length < 2)\n return [];\n\n const parts = urlparts[1].split('&');\n\n parts.forEach(function (part) {\n var pair = part.split('=');\n pair[0] = window.decodeURIComponent(pair[0]);\n pair[1] = parseValue(window.decodeURIComponent(pair[1]));\n params[pair[0]] = (pair[1] !== 'undefined') ?\n pair[1] : true;\n });\n\n return params;\n }\n\n function urlPlugin(config: URLPluginConfig={}) {\n let _window;\n\n if(config.useMockedWindow)\n _window = useWindowMock();\n else\n _window = window;\n \n config = Object.assign({},{\n url: _window.isMocked ? \"\" : _window.location.href,\n prefix: \"\"\n },config);\n\n \n\n return function(api){\n api.url = config.url;\n const urlparams = getParams(config.url,_window);\n const prefix = config.prefix;\n\n Object.keys(urlparams).forEach(key => {\n if(!key.startsWith(prefix))\n return;\n \n const keyWithoutPrefix = key.replace(prefix,\"\");\n api.visibility(keyWithoutPrefix,urlparams[key]);\n });\n\n return {name: 'urlplugin'};\n }\n\n}\n\nexport {\n urlPlugin\n}"],"names":["defaultparams","renderedTag","featureTagName","tagAttributeName","nameAttributeName","variantAttributeName","dataAttributeName","displayAttributeName","defaultDisplay","parseToFn","fnOrBool","getKey","name","variant","_name","toLowerCase","initVisibilities","visibilities","returnVisibilities","Object","keys","forEach","key","startsWith","config","renderFeatureTag","elem","isVisible","tagname","getAttribute","attributes","Array","from","attributesAsString","attr","nodeName","nodeValue","replace","display","outerHTML","innerHTML","assign","api","window","document","querySelectorAll","tag","on","event","selector","data","attrAsString","JSON","parse","e","isNaN","parseFloat","parseDataAttribute","_window","useMockedWindow","isMocked","decodeURIComponent","param1","url","location","href","prefix","urlparams","params","urlparts","split","length","part","pair","getParams","keyWithoutPrefix","visibility","globals","datas","listeners","showLogs","usedPlugins","triggerEvent","eventtype","param","listener","log","message","hasBoldTag","indexOf","hasVisibleKeyword","hasHiddenKeyword","_message","console","parts","apply","loggedMessage","logAndReturn","returnValue","getVisibility","visibilityFn","functionname","calculatedVisibility","getEvent","result","visibilityFunction","_internalCall","description","isActive","undefined","stringify","Error","requiredFn","requiredFnExists","requiredFnResult","visibilityFnKey","visibilityFnExists","visibilityFnResult","variantExists","visibilityOnlyNameFn","visibilityOnlyNameFnResult","defaultFn","defaultFnExists","defaultFnResult","setData","nameParam","variantOrDataParam","dataParam","fn","push","type","ignorePreviousRules","parseKey","rule","trigger","setFlag","resultOrVariant","resultOrData","param2","param3","param4","arguments","visibilityFnParams","requiredVisibility","setRequiredFlag","defaultVisibility","setDefaultFlag","addPlugin","plugin","includes","allPlugins","$plugins","_plugins","init"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"feature-toggle.min.cjs","sources":["../src/plugins/htmlplugin/plugin-html.ts","../src/featureToggle.ts","../src/plugins/urlplugin/plugin-url.ts"],"sourcesContent":["type Display = 'block' | 'inline-block' | 'inline' | 'flex' | 'inline-flex' | 'grid' | 'inline-grid';\n\ninterface HtmlPluginConfig {\n renderedTag?: string,\n featureTagName?: string,\n tagAttributeName?: string,\n nameAttributeName?:string,\n variantAttributeName?: string,\n dataAttributeName?: string,\n displayAttributeName?: string,\n defaultDisplay?: Display,\n}\n\n/*\n creates a tag that is shown / hidden, depending on the visibility rules.\n if not configured dynamically, it looks like this:\n <feature name=\"featurename\" variant=\"variantname\" data=\"data\">content </feature>\n\n Parameter: (config)\n - config.featureTagName: name of the tag. Default: \"feature\"\n - nameAttributeName: Name of the Name-Attribute: default: \"name\"\n - variantAttributeName: Name of the Variant-Attribute: default: \"variant\"\n*/\nconst defaultparams :HtmlPluginConfig = {\n renderedTag: 'div',\n featureTagName: 'feature',\n tagAttributeName: 'tag',\n nameAttributeName:'name',\n variantAttributeName: 'variant',\n dataAttributeName: 'data',\n displayAttributeName: 'display',\n defaultDisplay: 'block',\n}\nfunction parseDataAttribute(attrAsString){\n try{\n return JSON.parse(attrAsString);\n }\n catch(e)\n {\n if(!isNaN(parseFloat(attrAsString)))\n return parseFloat(attrAsString);\n \n return attrAsString;\n }\n}\n\nfunction htmlPlugin(config :HtmlPluginConfig = {}) {\n config = Object.assign({},defaultparams,config);\n\n function renderFeatureTag(elem:HTMLElement,isVisible){\n const tagname = elem.getAttribute(config.tagAttributeName) || config.renderedTag;\n const attributes = Array.from(elem.attributes);\n let attributesAsString = \"\";\n attributes.forEach(attr => {\n attributesAsString += ` ${attr.nodeName}=\"${attr.nodeValue.replace(/\"/g,\""\")}\"`;\n });\n const display = isVisible ? (elem.getAttribute(config.displayAttributeName) || config.defaultDisplay) : 'none';\n elem.outerHTML = `<${tagname} style=\"display:${display}\" _feature=\"true\" ${attributesAsString}>${elem.innerHTML}</${tagname}>`;\n } \n return function (api) {\n var renderedTags :NodeListOf<HTMLElement> = window.document.querySelectorAll(config.featureTagName);\n renderedTags.forEach(tag => { renderFeatureTag(tag,false) });\n\n api.on('visibilityrule', function (event) {\n var selector = `[_feature][${config.nameAttributeName}=\"${event.name}\"]`;\n if (event.variant) selector += `[${config.variantAttributeName}=\"${event.variant}\"]`;\n var elements :NodeListOf<HTMLElement> = document.querySelectorAll(selector);\n elements.forEach(elem => { \n const dataAsString = elem.getAttribute(config.dataAttributeName);\n const data = parseDataAttribute(dataAsString);\n \n const isVisible = api.isVisible(event.name,event.variant,data);\n renderFeatureTag(elem, isVisible);\n });\n })\n\n return { name: 'htmlplugin' };\n }\n}\n\nexport {\n htmlPlugin\n}","import { EventType, FeatureToggleApi, FeatureToggleConfig, OnEvent } from \"./types\";\n\nfunction parseToFn(fnOrBool: boolean | ((param?: any) => boolean)) {\n if (typeof fnOrBool == 'boolean')\n return function () { return fnOrBool };\n\n return fnOrBool;\n}\n\nfunction getKey(name: string, variant?: string): string {\n var _name = name.toLowerCase();\n if (variant && typeof variant == 'string') {\n _name += \"#\" + variant.toLowerCase();\n }\n\n return _name;\n}\n\nfunction initVisibilities(visibilities: FeatureToggleConfig = {}) {\n const returnVisibilities = {};\n Object.keys(visibilities).forEach(key => {\n if (key.startsWith('_') || key.startsWith('$'))\n return;\n returnVisibilities[getKey(key)] = parseToFn(visibilities[key]);\n });\n return returnVisibilities;\n}\n\nfunction useFeatureToggle(config: FeatureToggleConfig = {}): FeatureToggleApi {\n\n const globals = {\n datas: {},\n listeners: {},\n visibilities: initVisibilities(config),\n showLogs: false,\n usedPlugins: [],\n }\n\n function init(api: FeatureToggleApi) {\n if(config.$default){\n api.setDefaultFlag(config.$default);\n }\n\n if(config.$required){\n api.setRequiredFlag(config.$required);\n }\n\n const allPlugins = [...(config.$plugins||[]),...(config._plugins||[])];\n if(config._plugins){\n console.log('useFeatureToggle({_plugins:[]}): Key _plugins is deprecated. Use $plugins instead. This attribute will be removed in one of the next major versions.');\n }\n\n\n if (allPlugins.length) {\n allPlugins.forEach(plugin => {\n if (typeof plugin !== 'function')\n throw new Error('featuretoggleapi()-constructor: config.plugins needs functions as entries, not ' + typeof plugin + '.');\n\n api.addPlugin(plugin);\n });\n }\n\n triggerEvent('init');\n }\n\n function triggerEvent(eventtype: EventType, param?: any) {\n (globals.listeners[eventtype] || []).forEach(listener => {\n listener(param);\n });\n }\n\n const log = function (message) {\n if (!globals.showLogs)\n return;\n\n //Nur Browser können Syntaxhighlighting die anderen geben die Nachricht einfach aus und schneiden\n //die styletags raus\n if (typeof window === 'undefined') {\n const loggedMessage = message.replace(/<b>/g, \"\");\n console.log(loggedMessage);\n return;\n }\n\n var hasBoldTag = message.indexOf('<b>') != -1;\n var hasVisibleKeyword = message.indexOf('visible') != -1;\n var hasHiddenKeyword = message.indexOf('hidden') != -1;\n\n var _message = message.replace('visible', '%cvisible');\n _message = _message.replace('hidden', '%chidden');\n\n if (hasVisibleKeyword)\n console.log(_message, \"color:green;font-weight:bold;\");\n else if (hasHiddenKeyword)\n console.log(_message, \"color:red;font-weight:bold;\");\n else if (hasBoldTag) {\n _message = _message.replace('<b>', '%c');\n var parts = [_message, 'font-weight:bold;']\n console.log.apply(null, parts);\n }\n else\n console.log(message);\n }\n\n const logAndReturn = function (returnValue, message) {\n log(message);\n log('');\n return returnValue;\n }\n\n const getVisibility = function (visibilityFn, functionname, name, variant, data) {\n if (visibilityFn == null)\n return undefined;\n\n var calculatedVisibility = visibilityFn({ name: name, variant: variant, data: data });\n\n if (typeof calculatedVisibility == 'boolean') {\n return calculatedVisibility;\n }\n\n return logAndReturn(false, `The ${functionname} returns ${calculatedVisibility}. => Please return true or false. This result (and all non-boolean results) will return false.`);\n }\n\n function parseKey(key: string): OnEvent {\n const parts = key.split('#');\n return {\n name: parts[0],\n variant: parts.length > 1 ? parts[1] : undefined,\n data: globals.datas[key],\n }\n }\n\n /*\n the following calls are possible:\n visibility(name,result);\n visibility(name,variant,result);\n visibility(name,variant,data,result);\n \n =>\n param1: name\n param2: result || variant\n param3: result || data\n param4: result\n */\n function visibilityFnParams(param1, param2, param3, param4) {\n //name must always be set\n if (param1 == undefined)\n throw new Error('feature.visibility(): 1st parameter name must be defined');\n\n if (arguments.length == 1)\n throw new Error('feature.visibility(): 2nd parameter name must be a boolean or function, but is empty');\n\n let name = param1, variant = null, data = null, result = null;\n if (param3 == undefined && param4 == undefined) {\n result = param2;\n }\n else if (param4 == undefined) {\n variant = param2;\n result = param3;\n }\n else {\n variant = param2;\n data = param3;\n result = param4;\n }\n\n return {\n name,\n variant,\n data,\n result\n }\n }\n\n function getEvent(name: string, variant: string, data?, result?: any) {\n\n let event;\n\n event = { name, variant, data };\n\n event.key = getKey(event.name, event.variant);\n\n if (result == null)\n return event;\n\n event.visibilityFunction = parseToFn(result);\n event.result = event.visibilityFunction({\n name: event.name,\n variant: event.variant,\n data: event.data || {},\n _internalCall: true,\n description: 'When attaching a function, the result must be calculated internally. You can filter this out with the _internalCall:true -Flag.'\n })\n return event;\n }\n\n\n\n function isActive(name: string, variant?: string, data?: any): boolean {\n const visibilities = globals.visibilities;\n\n log(`\\nCheck Visibility of <b>Feature \"${name}\", variant \"${variant == undefined ? '' : variant}\"${data ? \" with data \" + JSON.stringify(data) : \"\"}.`);\n if (name == undefined)\n throw new Error('The attribute \"name\" is required for tag <feature></feature>. Example: <feature name=\"aname\"></feature>');\n\n var requiredFn = visibilities['_required'];\n var requiredFnExists = visibilities['_required'] != null;\n var requiredFnResult = getVisibility(requiredFn, 'requiredVisibility', name, variant, data);\n\n var visibilityFnKey = getKey(name, variant);\n var visibilityFn = visibilities[visibilityFnKey];\n var visibilityFnExists = visibilities[visibilityFnKey] != null;\n var visibilityFnResult = getVisibility(visibilityFn, 'visibility function', name, variant, data);\n\n var variantExists = variant != null;\n var visibilityOnlyNameFnKey = getKey(name, null);\n var visibilityOnlyNameFn = visibilities[visibilityOnlyNameFnKey];\n var visibilityOnlyNameFnExists = visibilities[visibilityOnlyNameFnKey] != null;\n var visibilityOnlyNameFnResult = getVisibility(visibilityOnlyNameFn, 'visibility function (only name)', name, variant, data);\n\n var defaultFn = visibilities['_default'];\n var defaultFnExists = visibilities['_default'] != null;\n var defaultFnResult = getVisibility(defaultFn, 'defaultVisibility', name, variant, data);\n\n if (!requiredFnExists)\n log(\"No requiredVisibility rule specified for this feature.\");\n else if (requiredFnExists && requiredFnResult === true)\n log(\"The requiredVisibility rule returns true. This feature will be shown when no other rule rejects it.\")\n else if (requiredFnExists && requiredFnResult === false)\n return logAndReturn(false, \"The requiredVisibility rule returns false. This feature will be hidden.\");\n\n if (visibilityFnExists)\n return logAndReturn(visibilityFnResult, `The visibility rule returns ${visibilityFnResult}. This feature will be ${visibilityFnResult ? 'visible' : 'hidden'}.`);\n log('No visibility rule found matching name and variant.');\n\n if (variantExists && typeof visibilityOnlyNameFnResult == 'boolean')\n return logAndReturn(visibilityOnlyNameFnResult, `Found a visibility rule for name ${name} without variants. The rule returns ${visibilityOnlyNameFnResult}. => This feature will be ${visibilityOnlyNameFnResult ? 'visible' : 'hidden'}.`);\n else if (variantExists)\n log(`No rules found for name ${name} without variants.`)\n\n\n if (defaultFnExists)\n return logAndReturn(defaultFnResult, `Found a defaultVisibility rule. The rule returns ${defaultFnResult}. => This feature will be ${defaultFnResult ? 'visible' : 'hidden'}.`);\n log(`No default rule found.`)\n\n if (requiredFnExists)\n return logAndReturn(true, `Only the requiredVisibility rule was found. This returned true. => This feature will be visible.`);\n\n return logAndReturn(false, 'No rules were found. This feature will be hidden.');\n }\n\n const api: FeatureToggleApi = {\n name: 'feature-toggle-api',\n setData: function (nameParam, variantOrDataParam, dataParam?): void {\n if (nameParam == undefined)\n throw new Error('setData(): The name must of the feature must be defined, but ist undefined');\n\n const variant = (dataParam != undefined ? variantOrDataParam : undefined) as string;\n const data = dataParam || variantOrDataParam;\n\n const event = getEvent(nameParam, variant, data);\n\n globals.datas[event.key] = event.data;\n\n triggerEvent('visibilityrule', event);\n },\n on(eventtype: EventType, fn, config?) {\n globals.listeners[eventtype] = globals.listeners[eventtype] || [];\n globals.listeners[eventtype].push(fn);\n\n triggerEvent('registerEvent', {\n type: eventtype\n })\n if (config != undefined && config.ignorePreviousRules)\n return;\n\n \n Object.keys(globals.visibilities).forEach(key => {\n const event = parseKey(key);\n const rule = globals.visibilities[key];\n event.result = rule(event);\n fn(event);\n });\n },\n trigger: triggerEvent,\n showLogs: function (showLogs?: boolean): void {\n globals.showLogs = showLogs == undefined ? true : showLogs;\n },\n isVisible(name,variant,data){\n console.log('featureToggle.isVisible is deprecated. use featureToggle.isActive instead. This function will be removed in one of the next major versions.');\n return isActive(name,variant,data);\n },\n isActive,\n /**\n the following function calls are possible:\n visibility(name,result);\n visibility(name,variant,result);\n visibility(name,variant,data,result);\n */\n setFlag(name, resultOrVariant, resultOrData?, result?) {\n const params = visibilityFnParams(name, resultOrVariant, resultOrData, result);\n const event = getEvent(params.name, params.variant, params.data, params.result);\n\n globals.visibilities[event.key] = event.visibilityFunction;\n globals.datas[event.key] = event.data;\n triggerEvent('visibilityrule', event);\n },\n visibility: function (name, resultOrVariant, resultOrData?, result?) {\n console.log('featureToggle.visibility is deprecated. use featureToggle.setVisibility instead. This function will be removed in one of the next major versions.');\n\n api.setFlag(name, resultOrVariant, resultOrData, result);\n },\n requiredVisibility: function (fn) {\n console.log('featureToggle.requiredVisibility is deprecated. use featureToggle.setRequiredFlag instead. This function will be removed in one of the next major versions.');\n\n api.setRequiredFlag(fn);\n },\n defaultVisibility: function (fn) {\n console.log('featureToggle.requiredVisibility is deprecated. use featureToggle.setRequiredFlag instead. This function will be removed in one of the next major versions.');\n\n api.setDefaultFlag(fn);\n },\n setRequiredFlag(fn) {\n if (typeof fn != \"function\")\n throw new Error('feature.setRequiredFlag(): 1st parameter must be a function, but is ' + typeof fn);\n\n globals.visibilities['_required'] = parseToFn(fn);\n },\n setDefaultFlag(fn) {\n if (typeof fn != \"function\")\n throw new Error('feature.defaultVisibility(): 1st parameter must be a function, but is ' + typeof fn);\n\n globals.visibilities['_default'] = parseToFn(fn);\n },\n addPlugin: function (plugin) {\n if (globals.usedPlugins.includes(plugin))\n return;\n\n const newPlugin = plugin(api);\n\n for(let _key of Object.keys(newPlugin)){\n api[_key] = newPlugin[_key];\n }\n\n globals.usedPlugins.push(plugin);\n },\n };\n init(api);\n\n return api;\n}\n\nexport default useFeatureToggle;","interface URLPluginConfig{\n useMockedWindow?: boolean,\n url?: string,\n prefix?: string\n\n}\n\nfunction useWindowMock(){\n return {\n isMocked: true,\n decodeURIComponent:function(param1){\n return param1;\n }\n }\n}\n\ndeclare global {\n interface Window {\n isMocked: boolean\n }\n }\n\n declare var window: Window;\n\nfunction parseValue(value){\n if(value === 'true')\n return true;\n return false;\n}\n\nfunction getParams(url,window) {\n var params = {};\n if (!url) \n return [];\n \n var urlparts = url.split(\"?\");\n\n //no params available for url\n if(urlparts.length < 2)\n return [];\n\n const parts = urlparts[1].split('&');\n\n parts.forEach(function (part) {\n var pair = part.split('=');\n pair[0] = window.decodeURIComponent(pair[0]);\n pair[1] = parseValue(window.decodeURIComponent(pair[1]));\n params[pair[0]] = (pair[1] !== 'undefined') ?\n pair[1] : true;\n });\n\n return params;\n }\n\n function urlPlugin(config: URLPluginConfig={}) {\n let _window;\n\n if(config.useMockedWindow)\n _window = useWindowMock();\n else\n _window = window;\n \n config = Object.assign({},{\n url: _window.isMocked ? \"\" : _window.location.href,\n prefix: \"\"\n },config);\n\n \n\n return function(api){\n api.url = config.url;\n const urlparams = getParams(config.url,_window);\n const prefix = config.prefix;\n\n Object.keys(urlparams).forEach(key => {\n if(!key.startsWith(prefix))\n return;\n \n const keyWithoutPrefix = key.replace(prefix,\"\");\n api.visibility(keyWithoutPrefix,urlparams[key]);\n });\n\n return {name: 'urlplugin'};\n }\n\n}\n\nexport {\n urlPlugin\n}"],"names":["defaultparams","renderedTag","featureTagName","tagAttributeName","nameAttributeName","variantAttributeName","dataAttributeName","displayAttributeName","defaultDisplay","parseToFn","fnOrBool","getKey","name","variant","_name","toLowerCase","initVisibilities","visibilities","returnVisibilities","Object","keys","forEach","key","startsWith","config","renderFeatureTag","elem","isVisible","tagname","getAttribute","attributes","Array","from","attributesAsString","attr","nodeName","nodeValue","replace","display","outerHTML","innerHTML","assign","api","window","document","querySelectorAll","tag","on","event","selector","data","attrAsString","JSON","parse","e","isNaN","parseFloat","parseDataAttribute","_window","useMockedWindow","isMocked","decodeURIComponent","param1","url","location","href","prefix","urlparams","params","urlparts","split","length","part","pair","getParams","keyWithoutPrefix","visibility","globals","datas","listeners","showLogs","usedPlugins","triggerEvent","eventtype","param","listener","log","message","hasBoldTag","indexOf","hasVisibleKeyword","hasHiddenKeyword","_message","console","parts","apply","loggedMessage","logAndReturn","returnValue","getVisibility","visibilityFn","functionname","calculatedVisibility","getEvent","result","visibilityFunction","_internalCall","description","isActive","undefined","stringify","Error","requiredFn","requiredFnExists","requiredFnResult","visibilityFnKey","visibilityFnExists","visibilityFnResult","variantExists","visibilityOnlyNameFn","visibilityOnlyNameFnResult","defaultFn","defaultFnExists","defaultFnResult","setData","nameParam","variantOrDataParam","dataParam","fn","push","type","ignorePreviousRules","parseKey","rule","trigger","setFlag","resultOrVariant","resultOrData","param2","param3","param4","arguments","visibilityFnParams","requiredVisibility","setRequiredFlag","defaultVisibility","setDefaultFlag","addPlugin","plugin","includes","newPlugin","_key","$default","$required","allPlugins","$plugins","_plugins","init"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function e(e={}){let t;return t=e.useMockedWindow?{isMocked:!0,decodeURIComponent:function(e){return e}}:window,e=Object.assign({},{url:t.isMocked?"":t.location.href,prefix:""},e),function(i){i.url=e.url;const n=function(e,t){var i={};if(!e)return[];var n=e.split("?");return n.length<2?[]:(n[1].split("&").forEach((function(e){var n=e.split("=");n[0]=t.decodeURIComponent(n[0]),n[1]="true"===t.decodeURIComponent(n[1]),i[n[0]]="undefined"===n[1]||n[1]})),i)}(e.url,t),r=e.prefix;return Object.keys(n).forEach((e=>{if(!e.startsWith(r))return;const t=e.replace(r,"");i.visibility(t,n[e])})),{name:"urlplugin"}}}const t={renderedTag:"div",featureTagName:"feature",tagAttributeName:"tag",nameAttributeName:"name",variantAttributeName:"variant",dataAttributeName:"data",displayAttributeName:"display",defaultDisplay:"block"};function i(e={}){function i(t,i){const n=t.getAttribute(e.tagAttributeName)||e.renderedTag,r=Array.from(t.attributes);let l="";r.forEach((e=>{l+=` ${e.nodeName}="${e.nodeValue.replace(/"/g,""")}"`}));const a=i?t.getAttribute(e.displayAttributeName)||e.defaultDisplay:"none";t.outerHTML=`<${n} style="display:${a}" _feature="true" ${l}>${t.innerHTML}</${n}>`}return e=Object.assign({},t,e),function(t){return window.document.querySelectorAll(e.featureTagName).forEach((e=>{i(e,!1)})),t.on("visibilityrule",(function(n){var r=`[_feature][${e.nameAttributeName}="${n.name}"]`;n.variant&&(r+=`[${e.variantAttributeName}="${n.variant}"]`),document.querySelectorAll(r).forEach((r=>{const l=function(e){try{return JSON.parse(e)}catch(t){return isNaN(parseFloat(e))?e:parseFloat(e)}}(r.getAttribute(e.dataAttributeName));i(r,t.isVisible(n.name,n.variant,l))}))})),{name:"htmlplugin"}}}function n(e){return"boolean"==typeof e?function(){return e}:e}function r(e,t){var i=e.toLowerCase();return t&&"string"==typeof t&&(i+="#"+t.toLowerCase()),i}function l(e={}){const t={};return Object.keys(e).forEach((i=>{i.startsWith("_")||i.startsWith("$")||(t[r(i)]=n(e[i]))})),t}function a(e={}){const t={datas:{},listeners:{},visibilities:l(e),showLogs:!1,usedPlugins:[]};function i(e,i){(t.listeners[e]||[]).forEach((e=>{e(i)}))}const a=function(e){if(t.showLogs)if("undefined"!=typeof window){var i=-1!=e.indexOf("<b>"),n=-1!=e.indexOf("visible"),r=-1!=e.indexOf("hidden"),l=e.replace("visible","%cvisible");if(l=l.replace("hidden","%chidden"),n)console.log(l,"color:green;font-weight:bold;");else if(r)console.log(l,"color:red;font-weight:bold;");else if(i){var a=[l=l.replace("<b>","%c"),"font-weight:bold;"];console.log.apply(null,a)}else console.log(e)}else{const t=e.replace(/<b>/g,"");console.log(t)}},u=function(e,t){return a(t),a(""),e},s=function(e,t,i,n,r){if(null!=e){var l=e({name:i,variant:n,data:r});return"boolean"==typeof l?l:u(!1,`The ${t} returns ${l}. => Please return true or false. This result (and all non-boolean results) will return false.`)}};function o(e,t,i,l){let a;return a={name:e,variant:t,data:i},a.key=r(a.name,a.variant),null==l||(a.visibilityFunction=n(l),a.result=a.visibilityFunction({name:a.name,variant:a.variant,data:a.data||{},_internalCall:!0,description:"When attaching a function, the result must be calculated internally. You can filter this out with the _internalCall:true -Flag."})),a}function f(e,i,n){const l=t.visibilities;if(a(`\nCheck Visibility of <b>Feature "${e}", variant "${null==i?"":i}"${n?" with data "+JSON.stringify(n):""}.`),null==e)throw new Error('The attribute "name" is required for tag <feature></feature>. Example: <feature name="aname"></feature>');var o=l._required,f=null!=l._required,d=s(o,"requiredVisibility",e,i,n),c=r(e,i),b=l[c],g=null!=l[c],h=s(b,"visibility function",e,i,n),v=null!=i,m=l[r(e,null)],y=s(m,"visibility function (only name)",e,i,n),p=l._default,w=null!=l._default,T=s(p,"defaultVisibility",e,i,n);if(f){if(f&&!0===d)a("The requiredVisibility rule returns true. This feature will be shown when no other rule rejects it.");else if(f&&!1===d)return u(!1,"The requiredVisibility rule returns false. This feature will be hidden.")}else a("No requiredVisibility rule specified for this feature.");return g?u(h,`The visibility rule returns ${h}. This feature will be ${h?"visible":"hidden"}.`):(a("No visibility rule found matching name and variant."),v&&"boolean"==typeof y?u(y,`Found a visibility rule for name ${e} without variants. The rule returns ${y}. => This feature will be ${y?"visible":"hidden"}.`):(v&&a(`No rules found for name ${e} without variants.`),w?u(T,`Found a defaultVisibility rule. The rule returns ${T}. => This feature will be ${T?"visible":"hidden"}.`):(a("No default rule found."),f?u(!0,"Only the requiredVisibility rule was found. This returned true. => This feature will be visible."):u(!1,"No rules were found. This feature will be hidden."))))}const d={name:"feature-toggle-api",setData:function(e,n,r){if(null==e)throw new Error("setData(): The name must of the feature must be defined, but ist undefined");const l=o(e,null!=r?n:void 0,r||n);t.datas[l.key]=l.data,i("visibilityrule",l)},on
|
|
1
|
+
function e(e={}){let t;return t=e.useMockedWindow?{isMocked:!0,decodeURIComponent:function(e){return e}}:window,e=Object.assign({},{url:t.isMocked?"":t.location.href,prefix:""},e),function(i){i.url=e.url;const n=function(e,t){var i={};if(!e)return[];var n=e.split("?");return n.length<2?[]:(n[1].split("&").forEach((function(e){var n=e.split("=");n[0]=t.decodeURIComponent(n[0]),n[1]="true"===t.decodeURIComponent(n[1]),i[n[0]]="undefined"===n[1]||n[1]})),i)}(e.url,t),r=e.prefix;return Object.keys(n).forEach((e=>{if(!e.startsWith(r))return;const t=e.replace(r,"");i.visibility(t,n[e])})),{name:"urlplugin"}}}const t={renderedTag:"div",featureTagName:"feature",tagAttributeName:"tag",nameAttributeName:"name",variantAttributeName:"variant",dataAttributeName:"data",displayAttributeName:"display",defaultDisplay:"block"};function i(e={}){function i(t,i){const n=t.getAttribute(e.tagAttributeName)||e.renderedTag,r=Array.from(t.attributes);let l="";r.forEach((e=>{l+=` ${e.nodeName}="${e.nodeValue.replace(/"/g,""")}"`}));const a=i?t.getAttribute(e.displayAttributeName)||e.defaultDisplay:"none";t.outerHTML=`<${n} style="display:${a}" _feature="true" ${l}>${t.innerHTML}</${n}>`}return e=Object.assign({},t,e),function(t){return window.document.querySelectorAll(e.featureTagName).forEach((e=>{i(e,!1)})),t.on("visibilityrule",(function(n){var r=`[_feature][${e.nameAttributeName}="${n.name}"]`;n.variant&&(r+=`[${e.variantAttributeName}="${n.variant}"]`),document.querySelectorAll(r).forEach((r=>{const l=function(e){try{return JSON.parse(e)}catch(t){return isNaN(parseFloat(e))?e:parseFloat(e)}}(r.getAttribute(e.dataAttributeName));i(r,t.isVisible(n.name,n.variant,l))}))})),{name:"htmlplugin"}}}function n(e){return"boolean"==typeof e?function(){return e}:e}function r(e,t){var i=e.toLowerCase();return t&&"string"==typeof t&&(i+="#"+t.toLowerCase()),i}function l(e={}){const t={};return Object.keys(e).forEach((i=>{i.startsWith("_")||i.startsWith("$")||(t[r(i)]=n(e[i]))})),t}function a(e={}){const t={datas:{},listeners:{},visibilities:l(e),showLogs:!1,usedPlugins:[]};function i(e,i){(t.listeners[e]||[]).forEach((e=>{e(i)}))}const a=function(e){if(t.showLogs)if("undefined"!=typeof window){var i=-1!=e.indexOf("<b>"),n=-1!=e.indexOf("visible"),r=-1!=e.indexOf("hidden"),l=e.replace("visible","%cvisible");if(l=l.replace("hidden","%chidden"),n)console.log(l,"color:green;font-weight:bold;");else if(r)console.log(l,"color:red;font-weight:bold;");else if(i){var a=[l=l.replace("<b>","%c"),"font-weight:bold;"];console.log.apply(null,a)}else console.log(e)}else{const t=e.replace(/<b>/g,"");console.log(t)}},u=function(e,t){return a(t),a(""),e},s=function(e,t,i,n,r){if(null!=e){var l=e({name:i,variant:n,data:r});return"boolean"==typeof l?l:u(!1,`The ${t} returns ${l}. => Please return true or false. This result (and all non-boolean results) will return false.`)}};function o(e,t,i,l){let a;return a={name:e,variant:t,data:i},a.key=r(a.name,a.variant),null==l||(a.visibilityFunction=n(l),a.result=a.visibilityFunction({name:a.name,variant:a.variant,data:a.data||{},_internalCall:!0,description:"When attaching a function, the result must be calculated internally. You can filter this out with the _internalCall:true -Flag."})),a}function f(e,i,n){const l=t.visibilities;if(a(`\nCheck Visibility of <b>Feature "${e}", variant "${null==i?"":i}"${n?" with data "+JSON.stringify(n):""}.`),null==e)throw new Error('The attribute "name" is required for tag <feature></feature>. Example: <feature name="aname"></feature>');var o=l._required,f=null!=l._required,d=s(o,"requiredVisibility",e,i,n),c=r(e,i),b=l[c],g=null!=l[c],h=s(b,"visibility function",e,i,n),v=null!=i,m=l[r(e,null)],y=s(m,"visibility function (only name)",e,i,n),p=l._default,w=null!=l._default,T=s(p,"defaultVisibility",e,i,n);if(f){if(f&&!0===d)a("The requiredVisibility rule returns true. This feature will be shown when no other rule rejects it.");else if(f&&!1===d)return u(!1,"The requiredVisibility rule returns false. This feature will be hidden.")}else a("No requiredVisibility rule specified for this feature.");return g?u(h,`The visibility rule returns ${h}. This feature will be ${h?"visible":"hidden"}.`):(a("No visibility rule found matching name and variant."),v&&"boolean"==typeof y?u(y,`Found a visibility rule for name ${e} without variants. The rule returns ${y}. => This feature will be ${y?"visible":"hidden"}.`):(v&&a(`No rules found for name ${e} without variants.`),w?u(T,`Found a defaultVisibility rule. The rule returns ${T}. => This feature will be ${T?"visible":"hidden"}.`):(a("No default rule found."),f?u(!0,"Only the requiredVisibility rule was found. This returned true. => This feature will be visible."):u(!1,"No rules were found. This feature will be hidden."))))}const d={name:"feature-toggle-api",setData:function(e,n,r){if(null==e)throw new Error("setData(): The name must of the feature must be defined, but ist undefined");const l=o(e,null!=r?n:void 0,r||n);t.datas[l.key]=l.data,i("visibilityrule",l)},on(e,n,r){t.listeners[e]=t.listeners[e]||[],t.listeners[e].push(n),i("registerEvent",{type:e}),null!=r&&r.ignorePreviousRules||Object.keys(t.visibilities).forEach((e=>{const i=function(e){const i=e.split("#");return{name:i[0],variant:i.length>1?i[1]:void 0,data:t.datas[e]}}(e),r=t.visibilities[e];i.result=r(i),n(i)}))},trigger:i,showLogs:function(e){t.showLogs=null==e||e},isVisible:(e,t,i)=>(console.log("featureToggle.isVisible is deprecated. use featureToggle.isActive instead. This function will be removed in one of the next major versions."),f(e,t,i)),isActive:f,setFlag(e,n,r,l){const a=function(e,t,i,n){if(null==e)throw new Error("feature.visibility(): 1st parameter name must be defined");if(1==arguments.length)throw new Error("feature.visibility(): 2nd parameter name must be a boolean or function, but is empty");let r=null,l=null,a=null;return null==i&&null==n?a=t:null==n?(r=t,a=i):(r=t,l=i,a=n),{name:e,variant:r,data:l,result:a}}(e,n,r,l),u=o(a.name,a.variant,a.data,a.result);t.visibilities[u.key]=u.visibilityFunction,t.datas[u.key]=u.data,i("visibilityrule",u)},visibility:function(e,t,i,n){console.log("featureToggle.visibility is deprecated. use featureToggle.setVisibility instead. This function will be removed in one of the next major versions."),d.setFlag(e,t,i,n)},requiredVisibility:function(e){console.log("featureToggle.requiredVisibility is deprecated. use featureToggle.setRequiredFlag instead. This function will be removed in one of the next major versions."),d.setRequiredFlag(e)},defaultVisibility:function(e){console.log("featureToggle.requiredVisibility is deprecated. use featureToggle.setRequiredFlag instead. This function will be removed in one of the next major versions."),d.setDefaultFlag(e)},setRequiredFlag(e){if("function"!=typeof e)throw new Error("feature.setRequiredFlag(): 1st parameter must be a function, but is "+typeof e);t.visibilities._required=n(e)},setDefaultFlag(e){if("function"!=typeof e)throw new Error("feature.defaultVisibility(): 1st parameter must be a function, but is "+typeof e);t.visibilities._default=n(e)},addPlugin:function(e){if(t.usedPlugins.includes(e))return;const i=e(d);for(let e of Object.keys(i))d[e]=i[e];t.usedPlugins.push(e)}};return function(t){e.$default&&t.setDefaultFlag(e.$default),e.$required&&t.setRequiredFlag(e.$required);const n=[...e.$plugins||[],...e._plugins||[]];e._plugins&&console.log("useFeatureToggle({_plugins:[]}): Key _plugins is deprecated. Use $plugins instead. This attribute will be removed in one of the next major versions."),n.length&&n.forEach((e=>{if("function"!=typeof e)throw new Error("featuretoggleapi()-constructor: config.plugins needs functions as entries, not "+typeof e+".");t.addPlugin(e)})),i("init")}(d),d}export{i as htmlPlugin,e as urlPlugin,a as useFeatureToggle};
|
|
2
2
|
//# sourceMappingURL=feature-toggle.min.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-toggle.min.js","sources":["../src/plugins/urlplugin/plugin-url.ts","../src/plugins/htmlplugin/plugin-html.ts","../src/featureToggle.ts"],"sourcesContent":["interface URLPluginConfig{\n useMockedWindow?: boolean,\n url?: string,\n prefix?: string\n\n}\n\nfunction useWindowMock(){\n return {\n isMocked: true,\n decodeURIComponent:function(param1){\n return param1;\n }\n }\n}\n\ndeclare global {\n interface Window {\n isMocked: boolean\n }\n }\n\n declare var window: Window;\n\nfunction parseValue(value){\n if(value === 'true')\n return true;\n return false;\n}\n\nfunction getParams(url,window) {\n var params = {};\n if (!url) \n return [];\n \n var urlparts = url.split(\"?\");\n\n //no params available for url\n if(urlparts.length < 2)\n return [];\n\n const parts = urlparts[1].split('&');\n\n parts.forEach(function (part) {\n var pair = part.split('=');\n pair[0] = window.decodeURIComponent(pair[0]);\n pair[1] = parseValue(window.decodeURIComponent(pair[1]));\n params[pair[0]] = (pair[1] !== 'undefined') ?\n pair[1] : true;\n });\n\n return params;\n }\n\n function urlPlugin(config: URLPluginConfig={}) {\n let _window;\n\n if(config.useMockedWindow)\n _window = useWindowMock();\n else\n _window = window;\n \n config = Object.assign({},{\n url: _window.isMocked ? \"\" : _window.location.href,\n prefix: \"\"\n },config);\n\n \n\n return function(api){\n api.url = config.url;\n const urlparams = getParams(config.url,_window);\n const prefix = config.prefix;\n\n Object.keys(urlparams).forEach(key => {\n if(!key.startsWith(prefix))\n return;\n \n const keyWithoutPrefix = key.replace(prefix,\"\");\n api.visibility(keyWithoutPrefix,urlparams[key]);\n });\n\n return {name: 'urlplugin'};\n }\n\n}\n\nexport {\n urlPlugin\n}","type Display = 'block' | 'inline-block' | 'inline' | 'flex' | 'inline-flex' | 'grid' | 'inline-grid';\n\ninterface HtmlPluginConfig {\n renderedTag?: string,\n featureTagName?: string,\n tagAttributeName?: string,\n nameAttributeName?:string,\n variantAttributeName?: string,\n dataAttributeName?: string,\n displayAttributeName?: string,\n defaultDisplay?: Display,\n}\n\n/*\n creates a tag that is shown / hidden, depending on the visibility rules.\n if not configured dynamically, it looks like this:\n <feature name=\"featurename\" variant=\"variantname\" data=\"data\">content </feature>\n\n Parameter: (config)\n - config.featureTagName: name of the tag. Default: \"feature\"\n - nameAttributeName: Name of the Name-Attribute: default: \"name\"\n - variantAttributeName: Name of the Variant-Attribute: default: \"variant\"\n*/\nconst defaultparams :HtmlPluginConfig = {\n renderedTag: 'div',\n featureTagName: 'feature',\n tagAttributeName: 'tag',\n nameAttributeName:'name',\n variantAttributeName: 'variant',\n dataAttributeName: 'data',\n displayAttributeName: 'display',\n defaultDisplay: 'block',\n}\nfunction parseDataAttribute(attrAsString){\n try{\n return JSON.parse(attrAsString);\n }\n catch(e)\n {\n if(!isNaN(parseFloat(attrAsString)))\n return parseFloat(attrAsString);\n \n return attrAsString;\n }\n}\n\nfunction htmlPlugin(config :HtmlPluginConfig = {}) {\n config = Object.assign({},defaultparams,config);\n\n function renderFeatureTag(elem:HTMLElement,isVisible){\n const tagname = elem.getAttribute(config.tagAttributeName) || config.renderedTag;\n const attributes = Array.from(elem.attributes);\n let attributesAsString = \"\";\n attributes.forEach(attr => {\n attributesAsString += ` ${attr.nodeName}=\"${attr.nodeValue.replace(/\"/g,\""\")}\"`;\n });\n const display = isVisible ? (elem.getAttribute(config.displayAttributeName) || config.defaultDisplay) : 'none';\n elem.outerHTML = `<${tagname} style=\"display:${display}\" _feature=\"true\" ${attributesAsString}>${elem.innerHTML}</${tagname}>`;\n } \n return function (api) {\n var renderedTags :NodeListOf<HTMLElement> = window.document.querySelectorAll(config.featureTagName);\n renderedTags.forEach(tag => { renderFeatureTag(tag,false) });\n\n api.on('visibilityrule', function (event) {\n var selector = `[_feature][${config.nameAttributeName}=\"${event.name}\"]`;\n if (event.variant) selector += `[${config.variantAttributeName}=\"${event.variant}\"]`;\n var elements :NodeListOf<HTMLElement> = document.querySelectorAll(selector);\n elements.forEach(elem => { \n const dataAsString = elem.getAttribute(config.dataAttributeName);\n const data = parseDataAttribute(dataAsString);\n \n const isVisible = api.isVisible(event.name,event.variant,data);\n renderFeatureTag(elem, isVisible);\n });\n })\n\n return { name: 'htmlplugin' };\n }\n}\n\nexport {\n htmlPlugin\n}","interface OnConfiguration {\n ignorePreviousRules: boolean\n}\ntype Plugin = (api) => void;\n\ninterface OnEvent {\n name: string,\n variant: string,\n data: any,\n result?: boolean\n}\n\ntype FirstCharOfFeatureFlagKey = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' |\n 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';\n \ntype FeatureFlagKey = `${FirstCharOfFeatureFlagKey}${string}`;\n\ninterface FeatureToggleConfig {\n [key: FeatureFlagKey]: boolean | (() => boolean),\n $plugins?: Plugin[]\n /**\n * @deprecated Use key`$plugins` instead.\n */\n _plugins?: Plugin[]\n}\n\ninterface Rule {\n name: string,\n variant: string,\n data: any,\n _internalCall?: true,\n description?: string\n}\n\ninterface FeatureToggleApi {\n name: string,\n setData(name: string, dataParam?: any): void;\n setData(name: string, variant: string, dataParam?: any): void,\n setData(nameParam: string, variantOrDataParam: string | { [key: string]: any },\n dataParam?: any): void;\n\n on(eventType: string, fn: (event: OnEvent) => void, config?: OnConfiguration): void;\n trigger(eventtype: string, param?: any);\n showLogs(showLogs?: boolean): void\n\n /**\n * @deprecated Use `featureToggle.isActive` instead.\n */\n isVisible(name: string, variant?: string, data?: any): boolean\n\n isActive(name: string, variant?: string, data?: any): boolean\n\n /**\n * @deprecated Use `featureToggle.setFlag` instead.\n */\n visibility(name: string, result: boolean | ((rule: Rule) => boolean)): void,\n /**\n * @deprecated Use `featureToggle.setFlag` instead.\n */\n visibility(name: string, variant: string | null, result: boolean | ((rule: Rule) => boolean)): void\n /**\n * @deprecated Use `featureToggle.setFlag` instead.\n */\n visibility(name: string, variant: string | null, data: any, result: boolean | ((rule: Rule) => boolean)): void,\n /**\n * @deprecated Use `featureToggle.setFlag` instead.\n */\n visibility(name: string, resultOrVariant: string | null | boolean | ((rule: Rule) => boolean), resultOrData?: any, result?: boolean | (() => boolean)): void\n\n setFlag(name: string, result: boolean | ((rule: Rule) => boolean)): void,\n setFlag(name: string, variant: string | null, result: boolean | ((rule: Rule) => boolean)): void,\n setFlag(name: string, variant: string | null, data: any, result: boolean | ((rule: Rule) => boolean)): void,\n setFlag(name: string, resultOrVariant: string | null | boolean | ((rule: Rule) => boolean), resultOrData?: any, result?: boolean | (() => boolean)): void\n\n /**\n * @deprecated Use `featureToggle.setRequiredFlag` instead.\n */\n requiredVisibility(fn: boolean | ((result: Rule) => boolean)): void\n\n /**\n * @deprecated Use `featureToggle.setDefaultFlag` instead.\n */\n defaultVisibility(fn: boolean | ((result: Rule) => boolean)): void\n\n /**\n * This rule will run first and only if it is true, the feature.setFlag() - rules apply.\n * In other words: if the required-rule returns false, all feature.setFlag-rules return false - regardless of its normal result.\n * @param fn \n */\n setRequiredFlag(fn: boolean | ((result: Rule) => boolean)): void\n\n /**\n * This is the default-rule and will be overwritten by feature.setFlag() - rules.\n * In other words: If feature.setFlag == false, the result of the defaultRule applies.\n * @param fn DefaultRule\n */\n setDefaultFlag(fn: boolean | ((result: Rule) => boolean)): void\n\n addPlugin(plugin: Plugin)\n}\n\nfunction parseToFn(fnOrBool: boolean | ((param?: any) => boolean)) {\n if (typeof fnOrBool == 'boolean')\n return function () { return fnOrBool };\n\n return fnOrBool;\n}\n\nfunction getKey(name: string, variant?: string): string {\n var _name = name.toLowerCase();\n if (variant && typeof variant == 'string') {\n _name += \"#\" + variant.toLowerCase();\n }\n\n return _name;\n}\n\nfunction initVisibilities(visibilities: FeatureToggleConfig = {}) {\n const returnVisibilities = {};\n Object.keys(visibilities).forEach(key => {\n if (key.startsWith('_') || key.startsWith('$'))\n return;\n returnVisibilities[getKey(key)] = parseToFn(visibilities[key]);\n });\n return returnVisibilities;\n}\n\nfunction useFeatureToggle(config: FeatureToggleConfig = {}): FeatureToggleApi {\n\n const globals = {\n datas: {},\n listeners: {},\n visibilities: initVisibilities(config),\n showLogs: false,\n usedPlugins: [],\n }\n\n function init(api) {\n const allPlugins = [...(config.$plugins||[]),...(config._plugins||[])];\n if(config._plugins){\n console.log('useFeatureToggle({_plugins:[]}): Key _plugins is deprecated. Use $plugins instead. This attribute will be removed in one of the next major versions.');\n }\n\n\n if (allPlugins.length) {\n allPlugins.forEach(plugin => {\n if (typeof plugin !== 'function')\n throw new Error('featuretoggleapi()-constructor: config.plugins needs functions as entries, not ' + typeof plugin + '.');\n\n plugin(api);\n });\n }\n\n triggerEvent('init');\n }\n\n function triggerEvent(eventtype: string, param?: any) {\n (globals.listeners[eventtype] || []).forEach(listener => {\n listener(param);\n });\n }\n\n const log = function (message) {\n if (!globals.showLogs)\n return;\n\n //Nur Browser können Syntaxhighlighting die anderen geben die Nachricht einfach aus und schneiden\n //die styletags raus\n if (typeof window === 'undefined') {\n const loggedMessage = message.replace(/<b>/g, \"\");\n console.log(loggedMessage);\n return;\n }\n\n var hasBoldTag = message.indexOf('<b>') != -1;\n var hasVisibleKeyword = message.indexOf('visible') != -1;\n var hasHiddenKeyword = message.indexOf('hidden') != -1;\n\n var _message = message.replace('visible', '%cvisible');\n _message = _message.replace('hidden', '%chidden');\n\n if (hasVisibleKeyword)\n console.log(_message, \"color:green;font-weight:bold;\");\n else if (hasHiddenKeyword)\n console.log(_message, \"color:red;font-weight:bold;\");\n else if (hasBoldTag) {\n _message = _message.replace('<b>', '%c');\n var parts = [_message, 'font-weight:bold;']\n console.log.apply(null, parts);\n }\n else\n console.log(message);\n }\n\n const logAndReturn = function (returnValue, message) {\n log(message);\n log('');\n return returnValue;\n }\n\n const getVisibility = function (visibilityFn, functionname, name, variant, data) {\n if (visibilityFn == null)\n return undefined;\n\n var calculatedVisibility = visibilityFn({ name: name, variant: variant, data: data });\n\n if (typeof calculatedVisibility == 'boolean') {\n return calculatedVisibility;\n }\n\n return logAndReturn(false, `The ${functionname} returns ${calculatedVisibility}. => Please return true or false. This result (and all non-boolean results) will return false.`);\n }\n\n function parseKey(key: string): OnEvent {\n const parts = key.split('#');\n return {\n name: parts[0],\n variant: parts.length > 1 ? parts[1] : undefined,\n data: globals.datas[key],\n }\n }\n\n /*\n the following calls are possible:\n visibility(name,result);\n visibility(name,variant,result);\n visibility(name,variant,data,result);\n \n =>\n param1: name\n param2: result || variant\n param3: result || data\n param4: result\n */\n function visibilityFnParams(param1, param2, param3, param4) {\n //name must always be set\n if (param1 == undefined)\n throw new Error('feature.visibility(): 1st parameter name must be defined');\n\n if (arguments.length == 1)\n throw new Error('feature.visibility(): 2nd parameter name must be a boolean or function, but is empty');\n\n let name = param1, variant = null, data = null, result = null;\n if (param3 == undefined && param4 == undefined) {\n result = param2;\n }\n else if (param4 == undefined) {\n variant = param2;\n result = param3;\n }\n else {\n variant = param2;\n data = param3;\n result = param4;\n }\n\n return {\n name,\n variant,\n data,\n result\n }\n }\n\n function getEvent(name: string, variant: string, data?, result?: any) {\n\n let event;\n\n event = { name, variant, data };\n\n event.key = getKey(event.name, event.variant);\n\n if (result == null)\n return event;\n\n event.visibilityFunction = parseToFn(result);\n event.result = event.visibilityFunction({\n name: event.name,\n variant: event.variant,\n data: event.data || {},\n _internalCall: true,\n description: 'When attaching a function, the result must be calculated internally. You can filter this out with the _internalCall:true -Flag.'\n })\n return event;\n }\n\n\n\n function isActive(name: string, variant?: string, data?: any): boolean {\n const visibilities = globals.visibilities;\n\n log(`\\nCheck Visibility of <b>Feature \"${name}\", variant \"${variant == undefined ? '' : variant}\"${data ? \" with data \" + JSON.stringify(data) : \"\"}.`);\n if (name == undefined)\n throw new Error('The attribute \"name\" is required for tag <feature></feature>. Example: <feature name=\"aname\"></feature>');\n\n var requiredFn = visibilities['_required'];\n var requiredFnExists = visibilities['_required'] != null;\n var requiredFnResult = getVisibility(requiredFn, 'requiredVisibility', name, variant, data);\n\n var visibilityFnKey = getKey(name, variant);\n var visibilityFn = visibilities[visibilityFnKey];\n var visibilityFnExists = visibilities[visibilityFnKey] != null;\n var visibilityFnResult = getVisibility(visibilityFn, 'visibility function', name, variant, data);\n\n var variantExists = variant != null;\n var visibilityOnlyNameFnKey = getKey(name, null);\n var visibilityOnlyNameFn = visibilities[visibilityOnlyNameFnKey];\n var visibilityOnlyNameFnExists = visibilities[visibilityOnlyNameFnKey] != null;\n var visibilityOnlyNameFnResult = getVisibility(visibilityOnlyNameFn, 'visibility function (only name)', name, variant, data);\n\n var defaultFn = visibilities['_default'];\n var defaultFnExists = visibilities['_default'] != null;\n var defaultFnResult = getVisibility(defaultFn, 'defaultVisibility', name, variant, data);\n\n if (!requiredFnExists)\n log(\"No requiredVisibility rule specified for this feature.\");\n else if (requiredFnExists && requiredFnResult === true)\n log(\"The requiredVisibility rule returns true. This feature will be shown when no other rule rejects it.\")\n else if (requiredFnExists && requiredFnResult === false)\n return logAndReturn(false, \"The requiredVisibility rule returns false. This feature will be hidden.\");\n\n if (visibilityFnExists)\n return logAndReturn(visibilityFnResult, `The visibility rule returns ${visibilityFnResult}. This feature will be ${visibilityFnResult ? 'visible' : 'hidden'}.`);\n log('No visibility rule found matching name and variant.');\n\n if (variantExists && typeof visibilityOnlyNameFnResult == 'boolean')\n return logAndReturn(visibilityOnlyNameFnResult, `Found a visibility rule for name ${name} without variants. The rule returns ${visibilityOnlyNameFnResult}. => This feature will be ${visibilityOnlyNameFnResult ? 'visible' : 'hidden'}.`);\n else if (variantExists)\n log(`No rules found for name ${name} without variants.`)\n\n\n if (defaultFnExists)\n return logAndReturn(defaultFnResult, `Found a defaultVisibility rule. The rule returns ${defaultFnResult}. => This feature will be ${defaultFnResult ? 'visible' : 'hidden'}.`);\n log(`No default rule found.`)\n\n if (requiredFnExists)\n return logAndReturn(true, `Only the requiredVisibility rule was found. This returned true. => This feature will be visible.`);\n\n return logAndReturn(false, 'No rules were found. This feature will be hidden.');\n }\n\n const api: FeatureToggleApi = {\n name: 'feature-toggle-api',\n setData: function (nameParam, variantOrDataParam, dataParam?): void {\n if (nameParam == undefined)\n throw new Error('setData(): The name must of the feature must be defined, but ist undefined');\n\n const variant = (dataParam != undefined ? variantOrDataParam : undefined) as string;\n const data = dataParam || variantOrDataParam;\n\n const event = getEvent(nameParam, variant, data);\n\n globals.datas[event.key] = event.data;\n\n triggerEvent('visibilityrule', event);\n },\n on: function (eventtype: string, fn, config?) {\n globals.listeners[eventtype] = globals.listeners[eventtype] || [];\n globals.listeners[eventtype].push(fn);\n\n triggerEvent('registerEvent', {\n type: eventtype\n })\n if (config != undefined && config.ignorePreviousRules)\n return;\n\n \n Object.keys(globals.visibilities).forEach(key => {\n const event = parseKey(key);\n const rule = globals.visibilities[key];\n event.result = rule(event);\n fn(event);\n });\n },\n trigger: triggerEvent,\n showLogs: function (showLogs?: boolean): void {\n globals.showLogs = showLogs == undefined ? true : showLogs;\n },\n isVisible(name,variant,data){\n console.log('featureToggle.isVisible is deprecated. use featureToggle.isActive instead. This function will be removed in one of the next major versions.');\n return isActive(name,variant,data);\n },\n isActive,\n /**\n the following function calls are possible:\n visibility(name,result);\n visibility(name,variant,result);\n visibility(name,variant,data,result);\n */\n setFlag(name, resultOrVariant, resultOrData?, result?) {\n const params = visibilityFnParams(name, resultOrVariant, resultOrData, result);\n const event = getEvent(params.name, params.variant, params.data, params.result);\n\n globals.visibilities[event.key] = event.visibilityFunction;\n globals.datas[event.key] = event.data;\n triggerEvent('visibilityrule', event);\n },\n visibility: function (name, resultOrVariant, resultOrData?, result?) {\n console.log('featureToggle.visibility is deprecated. use featureToggle.setVisibility instead. This function will be removed in one of the next major versions.');\n\n api.setFlag(name, resultOrVariant, resultOrData, result);\n },\n requiredVisibility: function (fn) {\n console.log('featureToggle.requiredVisibility is deprecated. use featureToggle.setRequiredFlag instead. This function will be removed in one of the next major versions.');\n\n api.setRequiredFlag(fn);\n },\n defaultVisibility: function (fn) {\n console.log('featureToggle.requiredVisibility is deprecated. use featureToggle.setRequiredFlag instead. This function will be removed in one of the next major versions.');\n\n api.setDefaultFlag(fn);\n },\n setRequiredFlag(fn) {\n if (typeof fn != \"function\")\n throw new Error('feature.setRequiredFlag(): 1st parameter must be a function, but is ' + typeof fn);\n\n globals.visibilities['_required'] = parseToFn(fn);\n },\n setDefaultFlag(fn) {\n if (typeof fn != \"function\")\n throw new Error('feature.defaultVisibility(): 1st parameter must be a function, but is ' + typeof fn);\n\n globals.visibilities['_default'] = parseToFn(fn);\n },\n addPlugin: function (plugin) {\n if (globals.usedPlugins.includes(plugin))\n return;\n\n plugin(api);\n\n globals.usedPlugins.push(plugin);\n },\n };\n init(api);\n\n return api;\n}\n\nexport default useFeatureToggle;"],"names":["urlPlugin","config","_window","useMockedWindow","isMocked","decodeURIComponent","param1","window","Object","assign","url","location","href","prefix","api","urlparams","params","urlparts","split","length","forEach","part","pair","getParams","keys","key","startsWith","keyWithoutPrefix","replace","visibility","name","defaultparams","renderedTag","featureTagName","tagAttributeName","nameAttributeName","variantAttributeName","dataAttributeName","displayAttributeName","defaultDisplay","htmlPlugin","renderFeatureTag","elem","isVisible","tagname","getAttribute","attributes","Array","from","attributesAsString","attr","nodeName","nodeValue","display","outerHTML","innerHTML","document","querySelectorAll","tag","on","event","selector","variant","data","attrAsString","JSON","parse","e","isNaN","parseFloat","parseDataAttribute","parseToFn","fnOrBool","getKey","_name","toLowerCase","initVisibilities","visibilities","returnVisibilities","useFeatureToggle","globals","datas","listeners","showLogs","usedPlugins","triggerEvent","eventtype","param","listener","log","message","hasBoldTag","indexOf","hasVisibleKeyword","hasHiddenKeyword","_message","console","parts","apply","loggedMessage","logAndReturn","returnValue","getVisibility","visibilityFn","functionname","calculatedVisibility","getEvent","result","visibilityFunction","_internalCall","description","isActive","undefined","stringify","Error","requiredFn","requiredFnExists","requiredFnResult","visibilityFnKey","visibilityFnExists","visibilityFnResult","variantExists","visibilityOnlyNameFn","visibilityOnlyNameFnResult","defaultFn","defaultFnExists","defaultFnResult","setData","nameParam","variantOrDataParam","dataParam","fn","push","type","ignorePreviousRules","parseKey","rule","trigger","setFlag","resultOrVariant","resultOrData","param2","param3","param4","arguments","visibilityFnParams","requiredVisibility","setRequiredFlag","defaultVisibility","setDefaultFlag","addPlugin","plugin","includes","allPlugins","$plugins","_plugins","init"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"feature-toggle.min.js","sources":["../src/plugins/urlplugin/plugin-url.ts","../src/plugins/htmlplugin/plugin-html.ts","../src/featureToggle.ts"],"sourcesContent":["interface URLPluginConfig{\n useMockedWindow?: boolean,\n url?: string,\n prefix?: string\n\n}\n\nfunction useWindowMock(){\n return {\n isMocked: true,\n decodeURIComponent:function(param1){\n return param1;\n }\n }\n}\n\ndeclare global {\n interface Window {\n isMocked: boolean\n }\n }\n\n declare var window: Window;\n\nfunction parseValue(value){\n if(value === 'true')\n return true;\n return false;\n}\n\nfunction getParams(url,window) {\n var params = {};\n if (!url) \n return [];\n \n var urlparts = url.split(\"?\");\n\n //no params available for url\n if(urlparts.length < 2)\n return [];\n\n const parts = urlparts[1].split('&');\n\n parts.forEach(function (part) {\n var pair = part.split('=');\n pair[0] = window.decodeURIComponent(pair[0]);\n pair[1] = parseValue(window.decodeURIComponent(pair[1]));\n params[pair[0]] = (pair[1] !== 'undefined') ?\n pair[1] : true;\n });\n\n return params;\n }\n\n function urlPlugin(config: URLPluginConfig={}) {\n let _window;\n\n if(config.useMockedWindow)\n _window = useWindowMock();\n else\n _window = window;\n \n config = Object.assign({},{\n url: _window.isMocked ? \"\" : _window.location.href,\n prefix: \"\"\n },config);\n\n \n\n return function(api){\n api.url = config.url;\n const urlparams = getParams(config.url,_window);\n const prefix = config.prefix;\n\n Object.keys(urlparams).forEach(key => {\n if(!key.startsWith(prefix))\n return;\n \n const keyWithoutPrefix = key.replace(prefix,\"\");\n api.visibility(keyWithoutPrefix,urlparams[key]);\n });\n\n return {name: 'urlplugin'};\n }\n\n}\n\nexport {\n urlPlugin\n}","type Display = 'block' | 'inline-block' | 'inline' | 'flex' | 'inline-flex' | 'grid' | 'inline-grid';\n\ninterface HtmlPluginConfig {\n renderedTag?: string,\n featureTagName?: string,\n tagAttributeName?: string,\n nameAttributeName?:string,\n variantAttributeName?: string,\n dataAttributeName?: string,\n displayAttributeName?: string,\n defaultDisplay?: Display,\n}\n\n/*\n creates a tag that is shown / hidden, depending on the visibility rules.\n if not configured dynamically, it looks like this:\n <feature name=\"featurename\" variant=\"variantname\" data=\"data\">content </feature>\n\n Parameter: (config)\n - config.featureTagName: name of the tag. Default: \"feature\"\n - nameAttributeName: Name of the Name-Attribute: default: \"name\"\n - variantAttributeName: Name of the Variant-Attribute: default: \"variant\"\n*/\nconst defaultparams :HtmlPluginConfig = {\n renderedTag: 'div',\n featureTagName: 'feature',\n tagAttributeName: 'tag',\n nameAttributeName:'name',\n variantAttributeName: 'variant',\n dataAttributeName: 'data',\n displayAttributeName: 'display',\n defaultDisplay: 'block',\n}\nfunction parseDataAttribute(attrAsString){\n try{\n return JSON.parse(attrAsString);\n }\n catch(e)\n {\n if(!isNaN(parseFloat(attrAsString)))\n return parseFloat(attrAsString);\n \n return attrAsString;\n }\n}\n\nfunction htmlPlugin(config :HtmlPluginConfig = {}) {\n config = Object.assign({},defaultparams,config);\n\n function renderFeatureTag(elem:HTMLElement,isVisible){\n const tagname = elem.getAttribute(config.tagAttributeName) || config.renderedTag;\n const attributes = Array.from(elem.attributes);\n let attributesAsString = \"\";\n attributes.forEach(attr => {\n attributesAsString += ` ${attr.nodeName}=\"${attr.nodeValue.replace(/\"/g,\""\")}\"`;\n });\n const display = isVisible ? (elem.getAttribute(config.displayAttributeName) || config.defaultDisplay) : 'none';\n elem.outerHTML = `<${tagname} style=\"display:${display}\" _feature=\"true\" ${attributesAsString}>${elem.innerHTML}</${tagname}>`;\n } \n return function (api) {\n var renderedTags :NodeListOf<HTMLElement> = window.document.querySelectorAll(config.featureTagName);\n renderedTags.forEach(tag => { renderFeatureTag(tag,false) });\n\n api.on('visibilityrule', function (event) {\n var selector = `[_feature][${config.nameAttributeName}=\"${event.name}\"]`;\n if (event.variant) selector += `[${config.variantAttributeName}=\"${event.variant}\"]`;\n var elements :NodeListOf<HTMLElement> = document.querySelectorAll(selector);\n elements.forEach(elem => { \n const dataAsString = elem.getAttribute(config.dataAttributeName);\n const data = parseDataAttribute(dataAsString);\n \n const isVisible = api.isVisible(event.name,event.variant,data);\n renderFeatureTag(elem, isVisible);\n });\n })\n\n return { name: 'htmlplugin' };\n }\n}\n\nexport {\n htmlPlugin\n}","import { EventType, FeatureToggleApi, FeatureToggleConfig, OnEvent } from \"./types\";\n\nfunction parseToFn(fnOrBool: boolean | ((param?: any) => boolean)) {\n if (typeof fnOrBool == 'boolean')\n return function () { return fnOrBool };\n\n return fnOrBool;\n}\n\nfunction getKey(name: string, variant?: string): string {\n var _name = name.toLowerCase();\n if (variant && typeof variant == 'string') {\n _name += \"#\" + variant.toLowerCase();\n }\n\n return _name;\n}\n\nfunction initVisibilities(visibilities: FeatureToggleConfig = {}) {\n const returnVisibilities = {};\n Object.keys(visibilities).forEach(key => {\n if (key.startsWith('_') || key.startsWith('$'))\n return;\n returnVisibilities[getKey(key)] = parseToFn(visibilities[key]);\n });\n return returnVisibilities;\n}\n\nfunction useFeatureToggle(config: FeatureToggleConfig = {}): FeatureToggleApi {\n\n const globals = {\n datas: {},\n listeners: {},\n visibilities: initVisibilities(config),\n showLogs: false,\n usedPlugins: [],\n }\n\n function init(api: FeatureToggleApi) {\n if(config.$default){\n api.setDefaultFlag(config.$default);\n }\n\n if(config.$required){\n api.setRequiredFlag(config.$required);\n }\n\n const allPlugins = [...(config.$plugins||[]),...(config._plugins||[])];\n if(config._plugins){\n console.log('useFeatureToggle({_plugins:[]}): Key _plugins is deprecated. Use $plugins instead. This attribute will be removed in one of the next major versions.');\n }\n\n\n if (allPlugins.length) {\n allPlugins.forEach(plugin => {\n if (typeof plugin !== 'function')\n throw new Error('featuretoggleapi()-constructor: config.plugins needs functions as entries, not ' + typeof plugin + '.');\n\n api.addPlugin(plugin);\n });\n }\n\n triggerEvent('init');\n }\n\n function triggerEvent(eventtype: EventType, param?: any) {\n (globals.listeners[eventtype] || []).forEach(listener => {\n listener(param);\n });\n }\n\n const log = function (message) {\n if (!globals.showLogs)\n return;\n\n //Nur Browser können Syntaxhighlighting die anderen geben die Nachricht einfach aus und schneiden\n //die styletags raus\n if (typeof window === 'undefined') {\n const loggedMessage = message.replace(/<b>/g, \"\");\n console.log(loggedMessage);\n return;\n }\n\n var hasBoldTag = message.indexOf('<b>') != -1;\n var hasVisibleKeyword = message.indexOf('visible') != -1;\n var hasHiddenKeyword = message.indexOf('hidden') != -1;\n\n var _message = message.replace('visible', '%cvisible');\n _message = _message.replace('hidden', '%chidden');\n\n if (hasVisibleKeyword)\n console.log(_message, \"color:green;font-weight:bold;\");\n else if (hasHiddenKeyword)\n console.log(_message, \"color:red;font-weight:bold;\");\n else if (hasBoldTag) {\n _message = _message.replace('<b>', '%c');\n var parts = [_message, 'font-weight:bold;']\n console.log.apply(null, parts);\n }\n else\n console.log(message);\n }\n\n const logAndReturn = function (returnValue, message) {\n log(message);\n log('');\n return returnValue;\n }\n\n const getVisibility = function (visibilityFn, functionname, name, variant, data) {\n if (visibilityFn == null)\n return undefined;\n\n var calculatedVisibility = visibilityFn({ name: name, variant: variant, data: data });\n\n if (typeof calculatedVisibility == 'boolean') {\n return calculatedVisibility;\n }\n\n return logAndReturn(false, `The ${functionname} returns ${calculatedVisibility}. => Please return true or false. This result (and all non-boolean results) will return false.`);\n }\n\n function parseKey(key: string): OnEvent {\n const parts = key.split('#');\n return {\n name: parts[0],\n variant: parts.length > 1 ? parts[1] : undefined,\n data: globals.datas[key],\n }\n }\n\n /*\n the following calls are possible:\n visibility(name,result);\n visibility(name,variant,result);\n visibility(name,variant,data,result);\n \n =>\n param1: name\n param2: result || variant\n param3: result || data\n param4: result\n */\n function visibilityFnParams(param1, param2, param3, param4) {\n //name must always be set\n if (param1 == undefined)\n throw new Error('feature.visibility(): 1st parameter name must be defined');\n\n if (arguments.length == 1)\n throw new Error('feature.visibility(): 2nd parameter name must be a boolean or function, but is empty');\n\n let name = param1, variant = null, data = null, result = null;\n if (param3 == undefined && param4 == undefined) {\n result = param2;\n }\n else if (param4 == undefined) {\n variant = param2;\n result = param3;\n }\n else {\n variant = param2;\n data = param3;\n result = param4;\n }\n\n return {\n name,\n variant,\n data,\n result\n }\n }\n\n function getEvent(name: string, variant: string, data?, result?: any) {\n\n let event;\n\n event = { name, variant, data };\n\n event.key = getKey(event.name, event.variant);\n\n if (result == null)\n return event;\n\n event.visibilityFunction = parseToFn(result);\n event.result = event.visibilityFunction({\n name: event.name,\n variant: event.variant,\n data: event.data || {},\n _internalCall: true,\n description: 'When attaching a function, the result must be calculated internally. You can filter this out with the _internalCall:true -Flag.'\n })\n return event;\n }\n\n\n\n function isActive(name: string, variant?: string, data?: any): boolean {\n const visibilities = globals.visibilities;\n\n log(`\\nCheck Visibility of <b>Feature \"${name}\", variant \"${variant == undefined ? '' : variant}\"${data ? \" with data \" + JSON.stringify(data) : \"\"}.`);\n if (name == undefined)\n throw new Error('The attribute \"name\" is required for tag <feature></feature>. Example: <feature name=\"aname\"></feature>');\n\n var requiredFn = visibilities['_required'];\n var requiredFnExists = visibilities['_required'] != null;\n var requiredFnResult = getVisibility(requiredFn, 'requiredVisibility', name, variant, data);\n\n var visibilityFnKey = getKey(name, variant);\n var visibilityFn = visibilities[visibilityFnKey];\n var visibilityFnExists = visibilities[visibilityFnKey] != null;\n var visibilityFnResult = getVisibility(visibilityFn, 'visibility function', name, variant, data);\n\n var variantExists = variant != null;\n var visibilityOnlyNameFnKey = getKey(name, null);\n var visibilityOnlyNameFn = visibilities[visibilityOnlyNameFnKey];\n var visibilityOnlyNameFnExists = visibilities[visibilityOnlyNameFnKey] != null;\n var visibilityOnlyNameFnResult = getVisibility(visibilityOnlyNameFn, 'visibility function (only name)', name, variant, data);\n\n var defaultFn = visibilities['_default'];\n var defaultFnExists = visibilities['_default'] != null;\n var defaultFnResult = getVisibility(defaultFn, 'defaultVisibility', name, variant, data);\n\n if (!requiredFnExists)\n log(\"No requiredVisibility rule specified for this feature.\");\n else if (requiredFnExists && requiredFnResult === true)\n log(\"The requiredVisibility rule returns true. This feature will be shown when no other rule rejects it.\")\n else if (requiredFnExists && requiredFnResult === false)\n return logAndReturn(false, \"The requiredVisibility rule returns false. This feature will be hidden.\");\n\n if (visibilityFnExists)\n return logAndReturn(visibilityFnResult, `The visibility rule returns ${visibilityFnResult}. This feature will be ${visibilityFnResult ? 'visible' : 'hidden'}.`);\n log('No visibility rule found matching name and variant.');\n\n if (variantExists && typeof visibilityOnlyNameFnResult == 'boolean')\n return logAndReturn(visibilityOnlyNameFnResult, `Found a visibility rule for name ${name} without variants. The rule returns ${visibilityOnlyNameFnResult}. => This feature will be ${visibilityOnlyNameFnResult ? 'visible' : 'hidden'}.`);\n else if (variantExists)\n log(`No rules found for name ${name} without variants.`)\n\n\n if (defaultFnExists)\n return logAndReturn(defaultFnResult, `Found a defaultVisibility rule. The rule returns ${defaultFnResult}. => This feature will be ${defaultFnResult ? 'visible' : 'hidden'}.`);\n log(`No default rule found.`)\n\n if (requiredFnExists)\n return logAndReturn(true, `Only the requiredVisibility rule was found. This returned true. => This feature will be visible.`);\n\n return logAndReturn(false, 'No rules were found. This feature will be hidden.');\n }\n\n const api: FeatureToggleApi = {\n name: 'feature-toggle-api',\n setData: function (nameParam, variantOrDataParam, dataParam?): void {\n if (nameParam == undefined)\n throw new Error('setData(): The name must of the feature must be defined, but ist undefined');\n\n const variant = (dataParam != undefined ? variantOrDataParam : undefined) as string;\n const data = dataParam || variantOrDataParam;\n\n const event = getEvent(nameParam, variant, data);\n\n globals.datas[event.key] = event.data;\n\n triggerEvent('visibilityrule', event);\n },\n on(eventtype: EventType, fn, config?) {\n globals.listeners[eventtype] = globals.listeners[eventtype] || [];\n globals.listeners[eventtype].push(fn);\n\n triggerEvent('registerEvent', {\n type: eventtype\n })\n if (config != undefined && config.ignorePreviousRules)\n return;\n\n \n Object.keys(globals.visibilities).forEach(key => {\n const event = parseKey(key);\n const rule = globals.visibilities[key];\n event.result = rule(event);\n fn(event);\n });\n },\n trigger: triggerEvent,\n showLogs: function (showLogs?: boolean): void {\n globals.showLogs = showLogs == undefined ? true : showLogs;\n },\n isVisible(name,variant,data){\n console.log('featureToggle.isVisible is deprecated. use featureToggle.isActive instead. This function will be removed in one of the next major versions.');\n return isActive(name,variant,data);\n },\n isActive,\n /**\n the following function calls are possible:\n visibility(name,result);\n visibility(name,variant,result);\n visibility(name,variant,data,result);\n */\n setFlag(name, resultOrVariant, resultOrData?, result?) {\n const params = visibilityFnParams(name, resultOrVariant, resultOrData, result);\n const event = getEvent(params.name, params.variant, params.data, params.result);\n\n globals.visibilities[event.key] = event.visibilityFunction;\n globals.datas[event.key] = event.data;\n triggerEvent('visibilityrule', event);\n },\n visibility: function (name, resultOrVariant, resultOrData?, result?) {\n console.log('featureToggle.visibility is deprecated. use featureToggle.setVisibility instead. This function will be removed in one of the next major versions.');\n\n api.setFlag(name, resultOrVariant, resultOrData, result);\n },\n requiredVisibility: function (fn) {\n console.log('featureToggle.requiredVisibility is deprecated. use featureToggle.setRequiredFlag instead. This function will be removed in one of the next major versions.');\n\n api.setRequiredFlag(fn);\n },\n defaultVisibility: function (fn) {\n console.log('featureToggle.requiredVisibility is deprecated. use featureToggle.setRequiredFlag instead. This function will be removed in one of the next major versions.');\n\n api.setDefaultFlag(fn);\n },\n setRequiredFlag(fn) {\n if (typeof fn != \"function\")\n throw new Error('feature.setRequiredFlag(): 1st parameter must be a function, but is ' + typeof fn);\n\n globals.visibilities['_required'] = parseToFn(fn);\n },\n setDefaultFlag(fn) {\n if (typeof fn != \"function\")\n throw new Error('feature.defaultVisibility(): 1st parameter must be a function, but is ' + typeof fn);\n\n globals.visibilities['_default'] = parseToFn(fn);\n },\n addPlugin: function (plugin) {\n if (globals.usedPlugins.includes(plugin))\n return;\n\n const newPlugin = plugin(api);\n\n for(let _key of Object.keys(newPlugin)){\n api[_key] = newPlugin[_key];\n }\n\n globals.usedPlugins.push(plugin);\n },\n };\n init(api);\n\n return api;\n}\n\nexport default useFeatureToggle;"],"names":["urlPlugin","config","_window","useMockedWindow","isMocked","decodeURIComponent","param1","window","Object","assign","url","location","href","prefix","api","urlparams","params","urlparts","split","length","forEach","part","pair","getParams","keys","key","startsWith","keyWithoutPrefix","replace","visibility","name","defaultparams","renderedTag","featureTagName","tagAttributeName","nameAttributeName","variantAttributeName","dataAttributeName","displayAttributeName","defaultDisplay","htmlPlugin","renderFeatureTag","elem","isVisible","tagname","getAttribute","attributes","Array","from","attributesAsString","attr","nodeName","nodeValue","display","outerHTML","innerHTML","document","querySelectorAll","tag","on","event","selector","variant","data","attrAsString","JSON","parse","e","isNaN","parseFloat","parseDataAttribute","parseToFn","fnOrBool","getKey","_name","toLowerCase","initVisibilities","visibilities","returnVisibilities","useFeatureToggle","globals","datas","listeners","showLogs","usedPlugins","triggerEvent","eventtype","param","listener","log","message","hasBoldTag","indexOf","hasVisibleKeyword","hasHiddenKeyword","_message","console","parts","apply","loggedMessage","logAndReturn","returnValue","getVisibility","visibilityFn","functionname","calculatedVisibility","getEvent","result","visibilityFunction","_internalCall","description","isActive","undefined","stringify","Error","requiredFn","requiredFnExists","requiredFnResult","visibilityFnKey","visibilityFnExists","visibilityFnResult","variantExists","visibilityOnlyNameFn","visibilityOnlyNameFnResult","defaultFn","defaultFnExists","defaultFnResult","setData","nameParam","variantOrDataParam","dataParam","fn","push","type","ignorePreviousRules","parseKey","rule","trigger","setFlag","resultOrVariant","resultOrData","param2","param3","param4","arguments","visibilityFnParams","requiredVisibility","setRequiredFlag","defaultVisibility","setDefaultFlag","addPlugin","plugin","includes","newPlugin","_key","$default","$required","allPlugins","$plugins","_plugins","init"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(e,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i():"function"==typeof define&&define.amd?define(i):(e="undefined"!=typeof globalThis?globalThis:e||self).useFeatureToggle=i()}(this,(function(){"use strict";function e(e){return"boolean"==typeof e?function(){return e}:e}function i(e,i){var t=e.toLowerCase();return i&&"string"==typeof i&&(t+="#"+i.toLowerCase()),t}function t(t={}){const n={};return Object.keys(t).forEach((l=>{l.startsWith("_")||l.startsWith("$")||(n[i(l)]=e(t[l]))})),n}return function(n={}){const l={datas:{},listeners:{},visibilities:t(n),showLogs:!1,usedPlugins:[]};function r(e,i){(l.listeners[e]||[]).forEach((e=>{e(i)}))}const s=function(e){if(l.showLogs)if("undefined"!=typeof window){var i=-1!=e.indexOf("<b>"),t=-1!=e.indexOf("visible"),n=-1!=e.indexOf("hidden"),r=e.replace("visible","%cvisible");if(r=r.replace("hidden","%chidden"),t)console.log(r,"color:green;font-weight:bold;");else if(n)console.log(r,"color:red;font-weight:bold;");else if(i){var s=[r=r.replace("<b>","%c"),"font-weight:bold;"];console.log.apply(null,s)}else console.log(e)}else{const i=e.replace(/<b>/g,"");console.log(i)}},o=function(e,i){return s(i),s(""),e},u=function(e,i,t,n,l){if(null!=e){var r=e({name:t,variant:n,data:l});return"boolean"==typeof r?r:o(!1,`The ${i} returns ${r}. => Please return true or false. This result (and all non-boolean results) will return false.`)}};function a(t,n,l,r){let s;return s={name:t,variant:n,data:l},s.key=i(s.name,s.variant),null==r||(s.visibilityFunction=e(r),s.result=s.visibilityFunction({name:s.name,variant:s.variant,data:s.data||{},_internalCall:!0,description:"When attaching a function, the result must be calculated internally. You can filter this out with the _internalCall:true -Flag."})),s}function f(e,t,n){const r=l.visibilities;if(s(`\nCheck Visibility of <b>Feature "${e}", variant "${null==t?"":t}"${n?" with data "+JSON.stringify(n):""}.`),null==e)throw new Error('The attribute "name" is required for tag <feature></feature>. Example: <feature name="aname"></feature>');var a=r._required,f=null!=r._required,d=u(a,"requiredVisibility",e,t,n),c=i(e,t),b=r[c],
|
|
1
|
+
!function(e,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i():"function"==typeof define&&define.amd?define(i):(e="undefined"!=typeof globalThis?globalThis:e||self).useFeatureToggle=i()}(this,(function(){"use strict";function e(e){return"boolean"==typeof e?function(){return e}:e}function i(e,i){var t=e.toLowerCase();return i&&"string"==typeof i&&(t+="#"+i.toLowerCase()),t}function t(t={}){const n={};return Object.keys(t).forEach((l=>{l.startsWith("_")||l.startsWith("$")||(n[i(l)]=e(t[l]))})),n}return function(n={}){const l={datas:{},listeners:{},visibilities:t(n),showLogs:!1,usedPlugins:[]};function r(e,i){(l.listeners[e]||[]).forEach((e=>{e(i)}))}const s=function(e){if(l.showLogs)if("undefined"!=typeof window){var i=-1!=e.indexOf("<b>"),t=-1!=e.indexOf("visible"),n=-1!=e.indexOf("hidden"),r=e.replace("visible","%cvisible");if(r=r.replace("hidden","%chidden"),t)console.log(r,"color:green;font-weight:bold;");else if(n)console.log(r,"color:red;font-weight:bold;");else if(i){var s=[r=r.replace("<b>","%c"),"font-weight:bold;"];console.log.apply(null,s)}else console.log(e)}else{const i=e.replace(/<b>/g,"");console.log(i)}},o=function(e,i){return s(i),s(""),e},u=function(e,i,t,n,l){if(null!=e){var r=e({name:t,variant:n,data:l});return"boolean"==typeof r?r:o(!1,`The ${i} returns ${r}. => Please return true or false. This result (and all non-boolean results) will return false.`)}};function a(t,n,l,r){let s;return s={name:t,variant:n,data:l},s.key=i(s.name,s.variant),null==r||(s.visibilityFunction=e(r),s.result=s.visibilityFunction({name:s.name,variant:s.variant,data:s.data||{},_internalCall:!0,description:"When attaching a function, the result must be calculated internally. You can filter this out with the _internalCall:true -Flag."})),s}function f(e,t,n){const r=l.visibilities;if(s(`\nCheck Visibility of <b>Feature "${e}", variant "${null==t?"":t}"${n?" with data "+JSON.stringify(n):""}.`),null==e)throw new Error('The attribute "name" is required for tag <feature></feature>. Example: <feature name="aname"></feature>');var a=r._required,f=null!=r._required,d=u(a,"requiredVisibility",e,t,n),c=i(e,t),b=r[c],g=null!=r[c],h=u(b,"visibility function",e,t,n),v=null!=t,y=r[i(e,null)],p=u(y,"visibility function (only name)",e,t,n),m=r._default,w=null!=r._default,T=u(m,"defaultVisibility",e,t,n);if(f){if(f&&!0===d)s("The requiredVisibility rule returns true. This feature will be shown when no other rule rejects it.");else if(f&&!1===d)return o(!1,"The requiredVisibility rule returns false. This feature will be hidden.")}else s("No requiredVisibility rule specified for this feature.");return g?o(h,`The visibility rule returns ${h}. This feature will be ${h?"visible":"hidden"}.`):(s("No visibility rule found matching name and variant."),v&&"boolean"==typeof p?o(p,`Found a visibility rule for name ${e} without variants. The rule returns ${p}. => This feature will be ${p?"visible":"hidden"}.`):(v&&s(`No rules found for name ${e} without variants.`),w?o(T,`Found a defaultVisibility rule. The rule returns ${T}. => This feature will be ${T?"visible":"hidden"}.`):(s("No default rule found."),f?o(!0,"Only the requiredVisibility rule was found. This returned true. => This feature will be visible."):o(!1,"No rules were found. This feature will be hidden."))))}const d={name:"feature-toggle-api",setData:function(e,i,t){if(null==e)throw new Error("setData(): The name must of the feature must be defined, but ist undefined");const n=a(e,null!=t?i:void 0,t||i);l.datas[n.key]=n.data,r("visibilityrule",n)},on(e,i,t){l.listeners[e]=l.listeners[e]||[],l.listeners[e].push(i),r("registerEvent",{type:e}),null!=t&&t.ignorePreviousRules||Object.keys(l.visibilities).forEach((e=>{const t=function(e){const i=e.split("#");return{name:i[0],variant:i.length>1?i[1]:void 0,data:l.datas[e]}}(e),n=l.visibilities[e];t.result=n(t),i(t)}))},trigger:r,showLogs:function(e){l.showLogs=null==e||e},isVisible:(e,i,t)=>(console.log("featureToggle.isVisible is deprecated. use featureToggle.isActive instead. This function will be removed in one of the next major versions."),f(e,i,t)),isActive:f,setFlag(e,i,t,n){const s=function(e,i,t,n){if(null==e)throw new Error("feature.visibility(): 1st parameter name must be defined");if(1==arguments.length)throw new Error("feature.visibility(): 2nd parameter name must be a boolean or function, but is empty");let l=null,r=null,s=null;return null==t&&null==n?s=i:null==n?(l=i,s=t):(l=i,r=t,s=n),{name:e,variant:l,data:r,result:s}}(e,i,t,n),o=a(s.name,s.variant,s.data,s.result);l.visibilities[o.key]=o.visibilityFunction,l.datas[o.key]=o.data,r("visibilityrule",o)},visibility:function(e,i,t,n){console.log("featureToggle.visibility is deprecated. use featureToggle.setVisibility instead. This function will be removed in one of the next major versions."),d.setFlag(e,i,t,n)},requiredVisibility:function(e){console.log("featureToggle.requiredVisibility is deprecated. use featureToggle.setRequiredFlag instead. This function will be removed in one of the next major versions."),d.setRequiredFlag(e)},defaultVisibility:function(e){console.log("featureToggle.requiredVisibility is deprecated. use featureToggle.setRequiredFlag instead. This function will be removed in one of the next major versions."),d.setDefaultFlag(e)},setRequiredFlag(i){if("function"!=typeof i)throw new Error("feature.setRequiredFlag(): 1st parameter must be a function, but is "+typeof i);l.visibilities._required=e(i)},setDefaultFlag(i){if("function"!=typeof i)throw new Error("feature.defaultVisibility(): 1st parameter must be a function, but is "+typeof i);l.visibilities._default=e(i)},addPlugin:function(e){if(l.usedPlugins.includes(e))return;const i=e(d);for(let e of Object.keys(i))d[e]=i[e];l.usedPlugins.push(e)}};return function(e){n.$default&&e.setDefaultFlag(n.$default),n.$required&&e.setRequiredFlag(n.$required);const i=[...n.$plugins||[],...n._plugins||[]];n._plugins&&console.log("useFeatureToggle({_plugins:[]}): Key _plugins is deprecated. Use $plugins instead. This attribute will be removed in one of the next major versions."),i.length&&i.forEach((i=>{if("function"!=typeof i)throw new Error("featuretoggleapi()-constructor: config.plugins needs functions as entries, not "+typeof i+".");e.addPlugin(i)})),r("init")}(d),d}}));
|
|
2
2
|
//# sourceMappingURL=feature-toggle.umd.min.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-toggle.umd.min.js","sources":["../src/featureToggle.ts"],"sourcesContent":["interface OnConfiguration {\n ignorePreviousRules: boolean\n}\ntype Plugin = (api) => void;\n\ninterface OnEvent {\n name: string,\n variant: string,\n data: any,\n result?: boolean\n}\n\ntype FirstCharOfFeatureFlagKey = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' |\n 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';\n \ntype FeatureFlagKey = `${FirstCharOfFeatureFlagKey}${string}`;\n\ninterface FeatureToggleConfig {\n [key: FeatureFlagKey]: boolean | (() => boolean),\n $plugins?: Plugin[]\n /**\n * @deprecated Use key`$plugins` instead.\n */\n _plugins?: Plugin[]\n}\n\ninterface Rule {\n name: string,\n variant: string,\n data: any,\n _internalCall?: true,\n description?: string\n}\n\ninterface FeatureToggleApi {\n name: string,\n setData(name: string, dataParam?: any): void;\n setData(name: string, variant: string, dataParam?: any): void,\n setData(nameParam: string, variantOrDataParam: string | { [key: string]: any },\n dataParam?: any): void;\n\n on(eventType: string, fn: (event: OnEvent) => void, config?: OnConfiguration): void;\n trigger(eventtype: string, param?: any);\n showLogs(showLogs?: boolean): void\n\n /**\n * @deprecated Use `featureToggle.isActive` instead.\n */\n isVisible(name: string, variant?: string, data?: any): boolean\n\n isActive(name: string, variant?: string, data?: any): boolean\n\n /**\n * @deprecated Use `featureToggle.setFlag` instead.\n */\n visibility(name: string, result: boolean | ((rule: Rule) => boolean)): void,\n /**\n * @deprecated Use `featureToggle.setFlag` instead.\n */\n visibility(name: string, variant: string | null, result: boolean | ((rule: Rule) => boolean)): void\n /**\n * @deprecated Use `featureToggle.setFlag` instead.\n */\n visibility(name: string, variant: string | null, data: any, result: boolean | ((rule: Rule) => boolean)): void,\n /**\n * @deprecated Use `featureToggle.setFlag` instead.\n */\n visibility(name: string, resultOrVariant: string | null | boolean | ((rule: Rule) => boolean), resultOrData?: any, result?: boolean | (() => boolean)): void\n\n setFlag(name: string, result: boolean | ((rule: Rule) => boolean)): void,\n setFlag(name: string, variant: string | null, result: boolean | ((rule: Rule) => boolean)): void,\n setFlag(name: string, variant: string | null, data: any, result: boolean | ((rule: Rule) => boolean)): void,\n setFlag(name: string, resultOrVariant: string | null | boolean | ((rule: Rule) => boolean), resultOrData?: any, result?: boolean | (() => boolean)): void\n\n /**\n * @deprecated Use `featureToggle.setRequiredFlag` instead.\n */\n requiredVisibility(fn: boolean | ((result: Rule) => boolean)): void\n\n /**\n * @deprecated Use `featureToggle.setDefaultFlag` instead.\n */\n defaultVisibility(fn: boolean | ((result: Rule) => boolean)): void\n\n /**\n * This rule will run first and only if it is true, the feature.setFlag() - rules apply.\n * In other words: if the required-rule returns false, all feature.setFlag-rules return false - regardless of its normal result.\n * @param fn \n */\n setRequiredFlag(fn: boolean | ((result: Rule) => boolean)): void\n\n /**\n * This is the default-rule and will be overwritten by feature.setFlag() - rules.\n * In other words: If feature.setFlag == false, the result of the defaultRule applies.\n * @param fn DefaultRule\n */\n setDefaultFlag(fn: boolean | ((result: Rule) => boolean)): void\n\n addPlugin(plugin: Plugin)\n}\n\nfunction parseToFn(fnOrBool: boolean | ((param?: any) => boolean)) {\n if (typeof fnOrBool == 'boolean')\n return function () { return fnOrBool };\n\n return fnOrBool;\n}\n\nfunction getKey(name: string, variant?: string): string {\n var _name = name.toLowerCase();\n if (variant && typeof variant == 'string') {\n _name += \"#\" + variant.toLowerCase();\n }\n\n return _name;\n}\n\nfunction initVisibilities(visibilities: FeatureToggleConfig = {}) {\n const returnVisibilities = {};\n Object.keys(visibilities).forEach(key => {\n if (key.startsWith('_') || key.startsWith('$'))\n return;\n returnVisibilities[getKey(key)] = parseToFn(visibilities[key]);\n });\n return returnVisibilities;\n}\n\nfunction useFeatureToggle(config: FeatureToggleConfig = {}): FeatureToggleApi {\n\n const globals = {\n datas: {},\n listeners: {},\n visibilities: initVisibilities(config),\n showLogs: false,\n usedPlugins: [],\n }\n\n function init(api) {\n const allPlugins = [...(config.$plugins||[]),...(config._plugins||[])];\n if(config._plugins){\n console.log('useFeatureToggle({_plugins:[]}): Key _plugins is deprecated. Use $plugins instead. This attribute will be removed in one of the next major versions.');\n }\n\n\n if (allPlugins.length) {\n allPlugins.forEach(plugin => {\n if (typeof plugin !== 'function')\n throw new Error('featuretoggleapi()-constructor: config.plugins needs functions as entries, not ' + typeof plugin + '.');\n\n plugin(api);\n });\n }\n\n triggerEvent('init');\n }\n\n function triggerEvent(eventtype: string, param?: any) {\n (globals.listeners[eventtype] || []).forEach(listener => {\n listener(param);\n });\n }\n\n const log = function (message) {\n if (!globals.showLogs)\n return;\n\n //Nur Browser können Syntaxhighlighting die anderen geben die Nachricht einfach aus und schneiden\n //die styletags raus\n if (typeof window === 'undefined') {\n const loggedMessage = message.replace(/<b>/g, \"\");\n console.log(loggedMessage);\n return;\n }\n\n var hasBoldTag = message.indexOf('<b>') != -1;\n var hasVisibleKeyword = message.indexOf('visible') != -1;\n var hasHiddenKeyword = message.indexOf('hidden') != -1;\n\n var _message = message.replace('visible', '%cvisible');\n _message = _message.replace('hidden', '%chidden');\n\n if (hasVisibleKeyword)\n console.log(_message, \"color:green;font-weight:bold;\");\n else if (hasHiddenKeyword)\n console.log(_message, \"color:red;font-weight:bold;\");\n else if (hasBoldTag) {\n _message = _message.replace('<b>', '%c');\n var parts = [_message, 'font-weight:bold;']\n console.log.apply(null, parts);\n }\n else\n console.log(message);\n }\n\n const logAndReturn = function (returnValue, message) {\n log(message);\n log('');\n return returnValue;\n }\n\n const getVisibility = function (visibilityFn, functionname, name, variant, data) {\n if (visibilityFn == null)\n return undefined;\n\n var calculatedVisibility = visibilityFn({ name: name, variant: variant, data: data });\n\n if (typeof calculatedVisibility == 'boolean') {\n return calculatedVisibility;\n }\n\n return logAndReturn(false, `The ${functionname} returns ${calculatedVisibility}. => Please return true or false. This result (and all non-boolean results) will return false.`);\n }\n\n function parseKey(key: string): OnEvent {\n const parts = key.split('#');\n return {\n name: parts[0],\n variant: parts.length > 1 ? parts[1] : undefined,\n data: globals.datas[key],\n }\n }\n\n /*\n the following calls are possible:\n visibility(name,result);\n visibility(name,variant,result);\n visibility(name,variant,data,result);\n \n =>\n param1: name\n param2: result || variant\n param3: result || data\n param4: result\n */\n function visibilityFnParams(param1, param2, param3, param4) {\n //name must always be set\n if (param1 == undefined)\n throw new Error('feature.visibility(): 1st parameter name must be defined');\n\n if (arguments.length == 1)\n throw new Error('feature.visibility(): 2nd parameter name must be a boolean or function, but is empty');\n\n let name = param1, variant = null, data = null, result = null;\n if (param3 == undefined && param4 == undefined) {\n result = param2;\n }\n else if (param4 == undefined) {\n variant = param2;\n result = param3;\n }\n else {\n variant = param2;\n data = param3;\n result = param4;\n }\n\n return {\n name,\n variant,\n data,\n result\n }\n }\n\n function getEvent(name: string, variant: string, data?, result?: any) {\n\n let event;\n\n event = { name, variant, data };\n\n event.key = getKey(event.name, event.variant);\n\n if (result == null)\n return event;\n\n event.visibilityFunction = parseToFn(result);\n event.result = event.visibilityFunction({\n name: event.name,\n variant: event.variant,\n data: event.data || {},\n _internalCall: true,\n description: 'When attaching a function, the result must be calculated internally. You can filter this out with the _internalCall:true -Flag.'\n })\n return event;\n }\n\n\n\n function isActive(name: string, variant?: string, data?: any): boolean {\n const visibilities = globals.visibilities;\n\n log(`\\nCheck Visibility of <b>Feature \"${name}\", variant \"${variant == undefined ? '' : variant}\"${data ? \" with data \" + JSON.stringify(data) : \"\"}.`);\n if (name == undefined)\n throw new Error('The attribute \"name\" is required for tag <feature></feature>. Example: <feature name=\"aname\"></feature>');\n\n var requiredFn = visibilities['_required'];\n var requiredFnExists = visibilities['_required'] != null;\n var requiredFnResult = getVisibility(requiredFn, 'requiredVisibility', name, variant, data);\n\n var visibilityFnKey = getKey(name, variant);\n var visibilityFn = visibilities[visibilityFnKey];\n var visibilityFnExists = visibilities[visibilityFnKey] != null;\n var visibilityFnResult = getVisibility(visibilityFn, 'visibility function', name, variant, data);\n\n var variantExists = variant != null;\n var visibilityOnlyNameFnKey = getKey(name, null);\n var visibilityOnlyNameFn = visibilities[visibilityOnlyNameFnKey];\n var visibilityOnlyNameFnExists = visibilities[visibilityOnlyNameFnKey] != null;\n var visibilityOnlyNameFnResult = getVisibility(visibilityOnlyNameFn, 'visibility function (only name)', name, variant, data);\n\n var defaultFn = visibilities['_default'];\n var defaultFnExists = visibilities['_default'] != null;\n var defaultFnResult = getVisibility(defaultFn, 'defaultVisibility', name, variant, data);\n\n if (!requiredFnExists)\n log(\"No requiredVisibility rule specified for this feature.\");\n else if (requiredFnExists && requiredFnResult === true)\n log(\"The requiredVisibility rule returns true. This feature will be shown when no other rule rejects it.\")\n else if (requiredFnExists && requiredFnResult === false)\n return logAndReturn(false, \"The requiredVisibility rule returns false. This feature will be hidden.\");\n\n if (visibilityFnExists)\n return logAndReturn(visibilityFnResult, `The visibility rule returns ${visibilityFnResult}. This feature will be ${visibilityFnResult ? 'visible' : 'hidden'}.`);\n log('No visibility rule found matching name and variant.');\n\n if (variantExists && typeof visibilityOnlyNameFnResult == 'boolean')\n return logAndReturn(visibilityOnlyNameFnResult, `Found a visibility rule for name ${name} without variants. The rule returns ${visibilityOnlyNameFnResult}. => This feature will be ${visibilityOnlyNameFnResult ? 'visible' : 'hidden'}.`);\n else if (variantExists)\n log(`No rules found for name ${name} without variants.`)\n\n\n if (defaultFnExists)\n return logAndReturn(defaultFnResult, `Found a defaultVisibility rule. The rule returns ${defaultFnResult}. => This feature will be ${defaultFnResult ? 'visible' : 'hidden'}.`);\n log(`No default rule found.`)\n\n if (requiredFnExists)\n return logAndReturn(true, `Only the requiredVisibility rule was found. This returned true. => This feature will be visible.`);\n\n return logAndReturn(false, 'No rules were found. This feature will be hidden.');\n }\n\n const api: FeatureToggleApi = {\n name: 'feature-toggle-api',\n setData: function (nameParam, variantOrDataParam, dataParam?): void {\n if (nameParam == undefined)\n throw new Error('setData(): The name must of the feature must be defined, but ist undefined');\n\n const variant = (dataParam != undefined ? variantOrDataParam : undefined) as string;\n const data = dataParam || variantOrDataParam;\n\n const event = getEvent(nameParam, variant, data);\n\n globals.datas[event.key] = event.data;\n\n triggerEvent('visibilityrule', event);\n },\n on: function (eventtype: string, fn, config?) {\n globals.listeners[eventtype] = globals.listeners[eventtype] || [];\n globals.listeners[eventtype].push(fn);\n\n triggerEvent('registerEvent', {\n type: eventtype\n })\n if (config != undefined && config.ignorePreviousRules)\n return;\n\n \n Object.keys(globals.visibilities).forEach(key => {\n const event = parseKey(key);\n const rule = globals.visibilities[key];\n event.result = rule(event);\n fn(event);\n });\n },\n trigger: triggerEvent,\n showLogs: function (showLogs?: boolean): void {\n globals.showLogs = showLogs == undefined ? true : showLogs;\n },\n isVisible(name,variant,data){\n console.log('featureToggle.isVisible is deprecated. use featureToggle.isActive instead. This function will be removed in one of the next major versions.');\n return isActive(name,variant,data);\n },\n isActive,\n /**\n the following function calls are possible:\n visibility(name,result);\n visibility(name,variant,result);\n visibility(name,variant,data,result);\n */\n setFlag(name, resultOrVariant, resultOrData?, result?) {\n const params = visibilityFnParams(name, resultOrVariant, resultOrData, result);\n const event = getEvent(params.name, params.variant, params.data, params.result);\n\n globals.visibilities[event.key] = event.visibilityFunction;\n globals.datas[event.key] = event.data;\n triggerEvent('visibilityrule', event);\n },\n visibility: function (name, resultOrVariant, resultOrData?, result?) {\n console.log('featureToggle.visibility is deprecated. use featureToggle.setVisibility instead. This function will be removed in one of the next major versions.');\n\n api.setFlag(name, resultOrVariant, resultOrData, result);\n },\n requiredVisibility: function (fn) {\n console.log('featureToggle.requiredVisibility is deprecated. use featureToggle.setRequiredFlag instead. This function will be removed in one of the next major versions.');\n\n api.setRequiredFlag(fn);\n },\n defaultVisibility: function (fn) {\n console.log('featureToggle.requiredVisibility is deprecated. use featureToggle.setRequiredFlag instead. This function will be removed in one of the next major versions.');\n\n api.setDefaultFlag(fn);\n },\n setRequiredFlag(fn) {\n if (typeof fn != \"function\")\n throw new Error('feature.setRequiredFlag(): 1st parameter must be a function, but is ' + typeof fn);\n\n globals.visibilities['_required'] = parseToFn(fn);\n },\n setDefaultFlag(fn) {\n if (typeof fn != \"function\")\n throw new Error('feature.defaultVisibility(): 1st parameter must be a function, but is ' + typeof fn);\n\n globals.visibilities['_default'] = parseToFn(fn);\n },\n addPlugin: function (plugin) {\n if (globals.usedPlugins.includes(plugin))\n return;\n\n plugin(api);\n\n globals.usedPlugins.push(plugin);\n },\n };\n init(api);\n\n return api;\n}\n\nexport default useFeatureToggle;"],"names":["parseToFn","fnOrBool","getKey","name","variant","_name","toLowerCase","initVisibilities","visibilities","returnVisibilities","Object","keys","forEach","key","startsWith","config","globals","datas","listeners","showLogs","usedPlugins","triggerEvent","eventtype","param","listener","log","message","window","hasBoldTag","indexOf","hasVisibleKeyword","hasHiddenKeyword","_message","replace","console","parts","apply","loggedMessage","logAndReturn","returnValue","getVisibility","visibilityFn","functionname","data","calculatedVisibility","getEvent","result","event","visibilityFunction","_internalCall","description","isActive","undefined","JSON","stringify","Error","requiredFn","requiredFnExists","requiredFnResult","visibilityFnKey","visibilityFnExists","visibilityFnResult","variantExists","visibilityOnlyNameFn","visibilityOnlyNameFnResult","defaultFn","defaultFnExists","defaultFnResult","api","setData","nameParam","variantOrDataParam","dataParam","on","fn","push","type","ignorePreviousRules","split","length","parseKey","rule","trigger","isVisible","setFlag","resultOrVariant","resultOrData","params","param1","param2","param3","param4","arguments","visibilityFnParams","visibility","requiredVisibility","setRequiredFlag","defaultVisibility","setDefaultFlag","addPlugin","plugin","includes","allPlugins","$plugins","_plugins","init"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"feature-toggle.umd.min.js","sources":["../src/featureToggle.ts"],"sourcesContent":["import { EventType, FeatureToggleApi, FeatureToggleConfig, OnEvent } from \"./types\";\n\nfunction parseToFn(fnOrBool: boolean | ((param?: any) => boolean)) {\n if (typeof fnOrBool == 'boolean')\n return function () { return fnOrBool };\n\n return fnOrBool;\n}\n\nfunction getKey(name: string, variant?: string): string {\n var _name = name.toLowerCase();\n if (variant && typeof variant == 'string') {\n _name += \"#\" + variant.toLowerCase();\n }\n\n return _name;\n}\n\nfunction initVisibilities(visibilities: FeatureToggleConfig = {}) {\n const returnVisibilities = {};\n Object.keys(visibilities).forEach(key => {\n if (key.startsWith('_') || key.startsWith('$'))\n return;\n returnVisibilities[getKey(key)] = parseToFn(visibilities[key]);\n });\n return returnVisibilities;\n}\n\nfunction useFeatureToggle(config: FeatureToggleConfig = {}): FeatureToggleApi {\n\n const globals = {\n datas: {},\n listeners: {},\n visibilities: initVisibilities(config),\n showLogs: false,\n usedPlugins: [],\n }\n\n function init(api: FeatureToggleApi) {\n if(config.$default){\n api.setDefaultFlag(config.$default);\n }\n\n if(config.$required){\n api.setRequiredFlag(config.$required);\n }\n\n const allPlugins = [...(config.$plugins||[]),...(config._plugins||[])];\n if(config._plugins){\n console.log('useFeatureToggle({_plugins:[]}): Key _plugins is deprecated. Use $plugins instead. This attribute will be removed in one of the next major versions.');\n }\n\n\n if (allPlugins.length) {\n allPlugins.forEach(plugin => {\n if (typeof plugin !== 'function')\n throw new Error('featuretoggleapi()-constructor: config.plugins needs functions as entries, not ' + typeof plugin + '.');\n\n api.addPlugin(plugin);\n });\n }\n\n triggerEvent('init');\n }\n\n function triggerEvent(eventtype: EventType, param?: any) {\n (globals.listeners[eventtype] || []).forEach(listener => {\n listener(param);\n });\n }\n\n const log = function (message) {\n if (!globals.showLogs)\n return;\n\n //Nur Browser können Syntaxhighlighting die anderen geben die Nachricht einfach aus und schneiden\n //die styletags raus\n if (typeof window === 'undefined') {\n const loggedMessage = message.replace(/<b>/g, \"\");\n console.log(loggedMessage);\n return;\n }\n\n var hasBoldTag = message.indexOf('<b>') != -1;\n var hasVisibleKeyword = message.indexOf('visible') != -1;\n var hasHiddenKeyword = message.indexOf('hidden') != -1;\n\n var _message = message.replace('visible', '%cvisible');\n _message = _message.replace('hidden', '%chidden');\n\n if (hasVisibleKeyword)\n console.log(_message, \"color:green;font-weight:bold;\");\n else if (hasHiddenKeyword)\n console.log(_message, \"color:red;font-weight:bold;\");\n else if (hasBoldTag) {\n _message = _message.replace('<b>', '%c');\n var parts = [_message, 'font-weight:bold;']\n console.log.apply(null, parts);\n }\n else\n console.log(message);\n }\n\n const logAndReturn = function (returnValue, message) {\n log(message);\n log('');\n return returnValue;\n }\n\n const getVisibility = function (visibilityFn, functionname, name, variant, data) {\n if (visibilityFn == null)\n return undefined;\n\n var calculatedVisibility = visibilityFn({ name: name, variant: variant, data: data });\n\n if (typeof calculatedVisibility == 'boolean') {\n return calculatedVisibility;\n }\n\n return logAndReturn(false, `The ${functionname} returns ${calculatedVisibility}. => Please return true or false. This result (and all non-boolean results) will return false.`);\n }\n\n function parseKey(key: string): OnEvent {\n const parts = key.split('#');\n return {\n name: parts[0],\n variant: parts.length > 1 ? parts[1] : undefined,\n data: globals.datas[key],\n }\n }\n\n /*\n the following calls are possible:\n visibility(name,result);\n visibility(name,variant,result);\n visibility(name,variant,data,result);\n \n =>\n param1: name\n param2: result || variant\n param3: result || data\n param4: result\n */\n function visibilityFnParams(param1, param2, param3, param4) {\n //name must always be set\n if (param1 == undefined)\n throw new Error('feature.visibility(): 1st parameter name must be defined');\n\n if (arguments.length == 1)\n throw new Error('feature.visibility(): 2nd parameter name must be a boolean or function, but is empty');\n\n let name = param1, variant = null, data = null, result = null;\n if (param3 == undefined && param4 == undefined) {\n result = param2;\n }\n else if (param4 == undefined) {\n variant = param2;\n result = param3;\n }\n else {\n variant = param2;\n data = param3;\n result = param4;\n }\n\n return {\n name,\n variant,\n data,\n result\n }\n }\n\n function getEvent(name: string, variant: string, data?, result?: any) {\n\n let event;\n\n event = { name, variant, data };\n\n event.key = getKey(event.name, event.variant);\n\n if (result == null)\n return event;\n\n event.visibilityFunction = parseToFn(result);\n event.result = event.visibilityFunction({\n name: event.name,\n variant: event.variant,\n data: event.data || {},\n _internalCall: true,\n description: 'When attaching a function, the result must be calculated internally. You can filter this out with the _internalCall:true -Flag.'\n })\n return event;\n }\n\n\n\n function isActive(name: string, variant?: string, data?: any): boolean {\n const visibilities = globals.visibilities;\n\n log(`\\nCheck Visibility of <b>Feature \"${name}\", variant \"${variant == undefined ? '' : variant}\"${data ? \" with data \" + JSON.stringify(data) : \"\"}.`);\n if (name == undefined)\n throw new Error('The attribute \"name\" is required for tag <feature></feature>. Example: <feature name=\"aname\"></feature>');\n\n var requiredFn = visibilities['_required'];\n var requiredFnExists = visibilities['_required'] != null;\n var requiredFnResult = getVisibility(requiredFn, 'requiredVisibility', name, variant, data);\n\n var visibilityFnKey = getKey(name, variant);\n var visibilityFn = visibilities[visibilityFnKey];\n var visibilityFnExists = visibilities[visibilityFnKey] != null;\n var visibilityFnResult = getVisibility(visibilityFn, 'visibility function', name, variant, data);\n\n var variantExists = variant != null;\n var visibilityOnlyNameFnKey = getKey(name, null);\n var visibilityOnlyNameFn = visibilities[visibilityOnlyNameFnKey];\n var visibilityOnlyNameFnExists = visibilities[visibilityOnlyNameFnKey] != null;\n var visibilityOnlyNameFnResult = getVisibility(visibilityOnlyNameFn, 'visibility function (only name)', name, variant, data);\n\n var defaultFn = visibilities['_default'];\n var defaultFnExists = visibilities['_default'] != null;\n var defaultFnResult = getVisibility(defaultFn, 'defaultVisibility', name, variant, data);\n\n if (!requiredFnExists)\n log(\"No requiredVisibility rule specified for this feature.\");\n else if (requiredFnExists && requiredFnResult === true)\n log(\"The requiredVisibility rule returns true. This feature will be shown when no other rule rejects it.\")\n else if (requiredFnExists && requiredFnResult === false)\n return logAndReturn(false, \"The requiredVisibility rule returns false. This feature will be hidden.\");\n\n if (visibilityFnExists)\n return logAndReturn(visibilityFnResult, `The visibility rule returns ${visibilityFnResult}. This feature will be ${visibilityFnResult ? 'visible' : 'hidden'}.`);\n log('No visibility rule found matching name and variant.');\n\n if (variantExists && typeof visibilityOnlyNameFnResult == 'boolean')\n return logAndReturn(visibilityOnlyNameFnResult, `Found a visibility rule for name ${name} without variants. The rule returns ${visibilityOnlyNameFnResult}. => This feature will be ${visibilityOnlyNameFnResult ? 'visible' : 'hidden'}.`);\n else if (variantExists)\n log(`No rules found for name ${name} without variants.`)\n\n\n if (defaultFnExists)\n return logAndReturn(defaultFnResult, `Found a defaultVisibility rule. The rule returns ${defaultFnResult}. => This feature will be ${defaultFnResult ? 'visible' : 'hidden'}.`);\n log(`No default rule found.`)\n\n if (requiredFnExists)\n return logAndReturn(true, `Only the requiredVisibility rule was found. This returned true. => This feature will be visible.`);\n\n return logAndReturn(false, 'No rules were found. This feature will be hidden.');\n }\n\n const api: FeatureToggleApi = {\n name: 'feature-toggle-api',\n setData: function (nameParam, variantOrDataParam, dataParam?): void {\n if (nameParam == undefined)\n throw new Error('setData(): The name must of the feature must be defined, but ist undefined');\n\n const variant = (dataParam != undefined ? variantOrDataParam : undefined) as string;\n const data = dataParam || variantOrDataParam;\n\n const event = getEvent(nameParam, variant, data);\n\n globals.datas[event.key] = event.data;\n\n triggerEvent('visibilityrule', event);\n },\n on(eventtype: EventType, fn, config?) {\n globals.listeners[eventtype] = globals.listeners[eventtype] || [];\n globals.listeners[eventtype].push(fn);\n\n triggerEvent('registerEvent', {\n type: eventtype\n })\n if (config != undefined && config.ignorePreviousRules)\n return;\n\n \n Object.keys(globals.visibilities).forEach(key => {\n const event = parseKey(key);\n const rule = globals.visibilities[key];\n event.result = rule(event);\n fn(event);\n });\n },\n trigger: triggerEvent,\n showLogs: function (showLogs?: boolean): void {\n globals.showLogs = showLogs == undefined ? true : showLogs;\n },\n isVisible(name,variant,data){\n console.log('featureToggle.isVisible is deprecated. use featureToggle.isActive instead. This function will be removed in one of the next major versions.');\n return isActive(name,variant,data);\n },\n isActive,\n /**\n the following function calls are possible:\n visibility(name,result);\n visibility(name,variant,result);\n visibility(name,variant,data,result);\n */\n setFlag(name, resultOrVariant, resultOrData?, result?) {\n const params = visibilityFnParams(name, resultOrVariant, resultOrData, result);\n const event = getEvent(params.name, params.variant, params.data, params.result);\n\n globals.visibilities[event.key] = event.visibilityFunction;\n globals.datas[event.key] = event.data;\n triggerEvent('visibilityrule', event);\n },\n visibility: function (name, resultOrVariant, resultOrData?, result?) {\n console.log('featureToggle.visibility is deprecated. use featureToggle.setVisibility instead. This function will be removed in one of the next major versions.');\n\n api.setFlag(name, resultOrVariant, resultOrData, result);\n },\n requiredVisibility: function (fn) {\n console.log('featureToggle.requiredVisibility is deprecated. use featureToggle.setRequiredFlag instead. This function will be removed in one of the next major versions.');\n\n api.setRequiredFlag(fn);\n },\n defaultVisibility: function (fn) {\n console.log('featureToggle.requiredVisibility is deprecated. use featureToggle.setRequiredFlag instead. This function will be removed in one of the next major versions.');\n\n api.setDefaultFlag(fn);\n },\n setRequiredFlag(fn) {\n if (typeof fn != \"function\")\n throw new Error('feature.setRequiredFlag(): 1st parameter must be a function, but is ' + typeof fn);\n\n globals.visibilities['_required'] = parseToFn(fn);\n },\n setDefaultFlag(fn) {\n if (typeof fn != \"function\")\n throw new Error('feature.defaultVisibility(): 1st parameter must be a function, but is ' + typeof fn);\n\n globals.visibilities['_default'] = parseToFn(fn);\n },\n addPlugin: function (plugin) {\n if (globals.usedPlugins.includes(plugin))\n return;\n\n const newPlugin = plugin(api);\n\n for(let _key of Object.keys(newPlugin)){\n api[_key] = newPlugin[_key];\n }\n\n globals.usedPlugins.push(plugin);\n },\n };\n init(api);\n\n return api;\n}\n\nexport default useFeatureToggle;"],"names":["parseToFn","fnOrBool","getKey","name","variant","_name","toLowerCase","initVisibilities","visibilities","returnVisibilities","Object","keys","forEach","key","startsWith","config","globals","datas","listeners","showLogs","usedPlugins","triggerEvent","eventtype","param","listener","log","message","window","hasBoldTag","indexOf","hasVisibleKeyword","hasHiddenKeyword","_message","replace","console","parts","apply","loggedMessage","logAndReturn","returnValue","getVisibility","visibilityFn","functionname","data","calculatedVisibility","getEvent","result","event","visibilityFunction","_internalCall","description","isActive","undefined","JSON","stringify","Error","requiredFn","requiredFnExists","requiredFnResult","visibilityFnKey","visibilityFnExists","visibilityFnResult","variantExists","visibilityOnlyNameFn","visibilityOnlyNameFnResult","defaultFn","defaultFnExists","defaultFnResult","api","setData","nameParam","variantOrDataParam","dataParam","on","fn","push","type","ignorePreviousRules","split","length","parseKey","rule","trigger","isVisible","setFlag","resultOrVariant","resultOrData","params","param1","param2","param3","param4","arguments","visibilityFnParams","visibility","requiredVisibility","setRequiredFlag","defaultVisibility","setDefaultFlag","addPlugin","plugin","includes","newPlugin","_key","$default","$required","allPlugins","$plugins","_plugins","init"],"mappings":"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"}
|
package/package.json
CHANGED
package/src/featureToggle.ts
CHANGED
|
@@ -1,103 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
ignorePreviousRules: boolean
|
|
3
|
-
}
|
|
4
|
-
type Plugin = (api) => void;
|
|
5
|
-
|
|
6
|
-
interface OnEvent {
|
|
7
|
-
name: string,
|
|
8
|
-
variant: string,
|
|
9
|
-
data: any,
|
|
10
|
-
result?: boolean
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
type FirstCharOfFeatureFlagKey = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' |
|
|
14
|
-
'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';
|
|
15
|
-
|
|
16
|
-
type FeatureFlagKey = `${FirstCharOfFeatureFlagKey}${string}`;
|
|
17
|
-
|
|
18
|
-
interface FeatureToggleConfig {
|
|
19
|
-
[key: FeatureFlagKey]: boolean | (() => boolean),
|
|
20
|
-
$plugins?: Plugin[]
|
|
21
|
-
/**
|
|
22
|
-
* @deprecated Use key`$plugins` instead.
|
|
23
|
-
*/
|
|
24
|
-
_plugins?: Plugin[]
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
interface Rule {
|
|
28
|
-
name: string,
|
|
29
|
-
variant: string,
|
|
30
|
-
data: any,
|
|
31
|
-
_internalCall?: true,
|
|
32
|
-
description?: string
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
interface FeatureToggleApi {
|
|
36
|
-
name: string,
|
|
37
|
-
setData(name: string, dataParam?: any): void;
|
|
38
|
-
setData(name: string, variant: string, dataParam?: any): void,
|
|
39
|
-
setData(nameParam: string, variantOrDataParam: string | { [key: string]: any },
|
|
40
|
-
dataParam?: any): void;
|
|
41
|
-
|
|
42
|
-
on(eventType: string, fn: (event: OnEvent) => void, config?: OnConfiguration): void;
|
|
43
|
-
trigger(eventtype: string, param?: any);
|
|
44
|
-
showLogs(showLogs?: boolean): void
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* @deprecated Use `featureToggle.isActive` instead.
|
|
48
|
-
*/
|
|
49
|
-
isVisible(name: string, variant?: string, data?: any): boolean
|
|
50
|
-
|
|
51
|
-
isActive(name: string, variant?: string, data?: any): boolean
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* @deprecated Use `featureToggle.setFlag` instead.
|
|
55
|
-
*/
|
|
56
|
-
visibility(name: string, result: boolean | ((rule: Rule) => boolean)): void,
|
|
57
|
-
/**
|
|
58
|
-
* @deprecated Use `featureToggle.setFlag` instead.
|
|
59
|
-
*/
|
|
60
|
-
visibility(name: string, variant: string | null, result: boolean | ((rule: Rule) => boolean)): void
|
|
61
|
-
/**
|
|
62
|
-
* @deprecated Use `featureToggle.setFlag` instead.
|
|
63
|
-
*/
|
|
64
|
-
visibility(name: string, variant: string | null, data: any, result: boolean | ((rule: Rule) => boolean)): void,
|
|
65
|
-
/**
|
|
66
|
-
* @deprecated Use `featureToggle.setFlag` instead.
|
|
67
|
-
*/
|
|
68
|
-
visibility(name: string, resultOrVariant: string | null | boolean | ((rule: Rule) => boolean), resultOrData?: any, result?: boolean | (() => boolean)): void
|
|
69
|
-
|
|
70
|
-
setFlag(name: string, result: boolean | ((rule: Rule) => boolean)): void,
|
|
71
|
-
setFlag(name: string, variant: string | null, result: boolean | ((rule: Rule) => boolean)): void,
|
|
72
|
-
setFlag(name: string, variant: string | null, data: any, result: boolean | ((rule: Rule) => boolean)): void,
|
|
73
|
-
setFlag(name: string, resultOrVariant: string | null | boolean | ((rule: Rule) => boolean), resultOrData?: any, result?: boolean | (() => boolean)): void
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* @deprecated Use `featureToggle.setRequiredFlag` instead.
|
|
77
|
-
*/
|
|
78
|
-
requiredVisibility(fn: boolean | ((result: Rule) => boolean)): void
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* @deprecated Use `featureToggle.setDefaultFlag` instead.
|
|
82
|
-
*/
|
|
83
|
-
defaultVisibility(fn: boolean | ((result: Rule) => boolean)): void
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* This rule will run first and only if it is true, the feature.setFlag() - rules apply.
|
|
87
|
-
* In other words: if the required-rule returns false, all feature.setFlag-rules return false - regardless of its normal result.
|
|
88
|
-
* @param fn
|
|
89
|
-
*/
|
|
90
|
-
setRequiredFlag(fn: boolean | ((result: Rule) => boolean)): void
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* This is the default-rule and will be overwritten by feature.setFlag() - rules.
|
|
94
|
-
* In other words: If feature.setFlag == false, the result of the defaultRule applies.
|
|
95
|
-
* @param fn DefaultRule
|
|
96
|
-
*/
|
|
97
|
-
setDefaultFlag(fn: boolean | ((result: Rule) => boolean)): void
|
|
98
|
-
|
|
99
|
-
addPlugin(plugin: Plugin)
|
|
100
|
-
}
|
|
1
|
+
import { EventType, FeatureToggleApi, FeatureToggleConfig, OnEvent } from "./types";
|
|
101
2
|
|
|
102
3
|
function parseToFn(fnOrBool: boolean | ((param?: any) => boolean)) {
|
|
103
4
|
if (typeof fnOrBool == 'boolean')
|
|
@@ -135,7 +36,15 @@ function useFeatureToggle(config: FeatureToggleConfig = {}): FeatureToggleApi {
|
|
|
135
36
|
usedPlugins: [],
|
|
136
37
|
}
|
|
137
38
|
|
|
138
|
-
function init(api) {
|
|
39
|
+
function init(api: FeatureToggleApi) {
|
|
40
|
+
if(config.$default){
|
|
41
|
+
api.setDefaultFlag(config.$default);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if(config.$required){
|
|
45
|
+
api.setRequiredFlag(config.$required);
|
|
46
|
+
}
|
|
47
|
+
|
|
139
48
|
const allPlugins = [...(config.$plugins||[]),...(config._plugins||[])];
|
|
140
49
|
if(config._plugins){
|
|
141
50
|
console.log('useFeatureToggle({_plugins:[]}): Key _plugins is deprecated. Use $plugins instead. This attribute will be removed in one of the next major versions.');
|
|
@@ -147,14 +56,14 @@ function useFeatureToggle(config: FeatureToggleConfig = {}): FeatureToggleApi {
|
|
|
147
56
|
if (typeof plugin !== 'function')
|
|
148
57
|
throw new Error('featuretoggleapi()-constructor: config.plugins needs functions as entries, not ' + typeof plugin + '.');
|
|
149
58
|
|
|
150
|
-
plugin
|
|
59
|
+
api.addPlugin(plugin);
|
|
151
60
|
});
|
|
152
61
|
}
|
|
153
62
|
|
|
154
63
|
triggerEvent('init');
|
|
155
64
|
}
|
|
156
65
|
|
|
157
|
-
function triggerEvent(eventtype:
|
|
66
|
+
function triggerEvent(eventtype: EventType, param?: any) {
|
|
158
67
|
(globals.listeners[eventtype] || []).forEach(listener => {
|
|
159
68
|
listener(param);
|
|
160
69
|
});
|
|
@@ -354,7 +263,7 @@ function useFeatureToggle(config: FeatureToggleConfig = {}): FeatureToggleApi {
|
|
|
354
263
|
|
|
355
264
|
triggerEvent('visibilityrule', event);
|
|
356
265
|
},
|
|
357
|
-
on
|
|
266
|
+
on(eventtype: EventType, fn, config?) {
|
|
358
267
|
globals.listeners[eventtype] = globals.listeners[eventtype] || [];
|
|
359
268
|
globals.listeners[eventtype].push(fn);
|
|
360
269
|
|
|
@@ -426,7 +335,11 @@ function useFeatureToggle(config: FeatureToggleConfig = {}): FeatureToggleApi {
|
|
|
426
335
|
if (globals.usedPlugins.includes(plugin))
|
|
427
336
|
return;
|
|
428
337
|
|
|
429
|
-
plugin(api);
|
|
338
|
+
const newPlugin = plugin(api);
|
|
339
|
+
|
|
340
|
+
for(let _key of Object.keys(newPlugin)){
|
|
341
|
+
api[_key] = newPlugin[_key];
|
|
342
|
+
}
|
|
430
343
|
|
|
431
344
|
globals.usedPlugins.push(plugin);
|
|
432
345
|
},
|
package/src/index.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { urlPlugin } from "./plugins/urlplugin/plugin-url"
|
|
2
2
|
import { htmlPlugin } from "./plugins/htmlplugin/plugin-html"
|
|
3
3
|
import useFeatureToggle from "./featureToggle"
|
|
4
|
-
|
|
4
|
+
import type {
|
|
5
|
+
FeatureFlag, FeatureFlagKey, FeatureToggleApi, FeatureToggleApiBase, FeatureToggleConfig, FirstCharOfFeatureFlagKey, OnConfiguration, EventType, OnEvent
|
|
6
|
+
} from './types';
|
|
5
7
|
|
|
6
8
|
export {
|
|
7
9
|
useFeatureToggle,
|
|
8
10
|
urlPlugin,
|
|
9
|
-
htmlPlugin
|
|
11
|
+
htmlPlugin,
|
|
12
|
+
FeatureFlag, FeatureFlagKey, FeatureToggleApi, FeatureToggleApiBase, FeatureToggleConfig, FirstCharOfFeatureFlagKey, OnConfiguration, EventType, OnEvent
|
|
10
13
|
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
export interface OnConfiguration {
|
|
2
|
+
ignorePreviousRules: boolean
|
|
3
|
+
}
|
|
4
|
+
export type Plugin = (api) => Partial<FeatureToggleApi>;
|
|
5
|
+
|
|
6
|
+
export type EventType = 'visibilityrule' | 'init' | 'registerEvent' | string;
|
|
7
|
+
export interface OnEvent {
|
|
8
|
+
name: string,
|
|
9
|
+
variant: string,
|
|
10
|
+
data: any,
|
|
11
|
+
result?: boolean
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type FirstCharOfFeatureFlagKey = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' |
|
|
15
|
+
'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';
|
|
16
|
+
|
|
17
|
+
export type FeatureFlagKey = `${FirstCharOfFeatureFlagKey}${string}`;
|
|
18
|
+
export type FeatureFlag = boolean | ((rule:Rule) => boolean);
|
|
19
|
+
export interface FeatureToggleConfig {
|
|
20
|
+
[key: FeatureFlagKey]: FeatureFlag,
|
|
21
|
+
$plugins?: Plugin[]
|
|
22
|
+
/**
|
|
23
|
+
* @deprecated Use key`$plugins` instead.
|
|
24
|
+
*/
|
|
25
|
+
_plugins?: Plugin[]
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* This rule will always run before the main rule.
|
|
29
|
+
* If it returns false, the main rules will be skipped and false is returned
|
|
30
|
+
*/
|
|
31
|
+
$required?: FeatureFlag
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* This rule will always run after the main rule.
|
|
35
|
+
* If the main rule returns false, the result of the default rule will be taken.s
|
|
36
|
+
*/
|
|
37
|
+
$default?: FeatureFlag
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface Rule {
|
|
41
|
+
name: string,
|
|
42
|
+
variant: string,
|
|
43
|
+
data: any,
|
|
44
|
+
_internalCall?: true,
|
|
45
|
+
description?: string
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface FeatureToggleApiBase {
|
|
49
|
+
name: string,
|
|
50
|
+
setData(name: string, dataParam?: any): void;
|
|
51
|
+
setData(name: string, variant: string, dataParam?: any): void,
|
|
52
|
+
setData(nameParam: string, variantOrDataParam: string | { [key: string]: any },
|
|
53
|
+
dataParam?: any): void;
|
|
54
|
+
|
|
55
|
+
on(eventType: EventType, fn: (event: OnEvent) => void, config?: OnConfiguration): void;
|
|
56
|
+
trigger(eventtype: EventType, param?: any);
|
|
57
|
+
showLogs(showLogs?: boolean): void
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @deprecated Use `featureToggle.isActive` instead.
|
|
61
|
+
*/
|
|
62
|
+
isVisible(name: string, variant?: string, data?: any): boolean
|
|
63
|
+
|
|
64
|
+
isActive(name: string, variant?: string, data?: any): boolean
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @deprecated Use `featureToggle.setFlag` instead.
|
|
68
|
+
*/
|
|
69
|
+
visibility(name: string, result: boolean | ((rule: Rule) => boolean)): void,
|
|
70
|
+
/**
|
|
71
|
+
* @deprecated Use `featureToggle.setFlag` instead.
|
|
72
|
+
*/
|
|
73
|
+
visibility(name: string, variant: string | null, result: boolean | ((rule: Rule) => boolean)): void
|
|
74
|
+
/**
|
|
75
|
+
* @deprecated Use `featureToggle.setFlag` instead.
|
|
76
|
+
*/
|
|
77
|
+
visibility(name: string, variant: string | null, data: any, result: boolean | ((rule: Rule) => boolean)): void,
|
|
78
|
+
/**
|
|
79
|
+
* @deprecated Use `featureToggle.setFlag` instead.
|
|
80
|
+
*/
|
|
81
|
+
visibility(name: string, resultOrVariant: string | null | boolean | ((rule: Rule) => boolean), resultOrData?: any, result?: boolean | (() => boolean)): void
|
|
82
|
+
|
|
83
|
+
setFlag(name: string, result: boolean | ((rule: Rule) => boolean)): void,
|
|
84
|
+
setFlag(name: string, variant: string | null, result: boolean | ((rule: Rule) => boolean)): void,
|
|
85
|
+
setFlag(name: string, variant: string | null, data: any, result: boolean | ((rule: Rule) => boolean)): void,
|
|
86
|
+
setFlag(name: string, resultOrVariant: string | null | boolean | ((rule: Rule) => boolean), resultOrData?: any, result?: boolean | (() => boolean)): void
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @deprecated Use `featureToggle.setRequiredFlag` instead.
|
|
90
|
+
*/
|
|
91
|
+
requiredVisibility(fn: boolean | ((result: Rule) => boolean)): void
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @deprecated Use `featureToggle.setDefaultFlag` instead.
|
|
95
|
+
*/
|
|
96
|
+
defaultVisibility(fn: boolean | ((result: Rule) => boolean)): void
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* This rule will run first and only if it is true, the feature.setFlag() - rules apply.
|
|
100
|
+
* In other words: if the required-rule returns false, all feature.setFlag-rules return false - regardless of its normal result.
|
|
101
|
+
* @param fn
|
|
102
|
+
*/
|
|
103
|
+
setRequiredFlag(fn: boolean | ((result: Rule) => boolean)): void
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* This is the default-rule and will be overwritten by feature.setFlag() - rules.
|
|
107
|
+
* In other words: If feature.setFlag == false, the result of the defaultRule applies.
|
|
108
|
+
* @param fn DefaultRule
|
|
109
|
+
*/
|
|
110
|
+
setDefaultFlag(fn: boolean | ((result: Rule) => boolean)): void
|
|
111
|
+
|
|
112
|
+
addPlugin(plugin: Plugin)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export type FeatureToggleApi = FeatureToggleApiBase & Record<string, any>;
|
|
116
|
+
|
|
117
|
+
export function abc(){}
|
|
@@ -139,6 +139,16 @@ describe("Default Visibility", function() {
|
|
|
139
139
|
const visibility = legacyApi.isActive('featureNotExists');
|
|
140
140
|
assert.strictEqual(visibility,true);
|
|
141
141
|
});
|
|
142
|
+
it("should return true if feature is passed by parameter", function() {
|
|
143
|
+
const apiByConstructor = useFeatureToggle({
|
|
144
|
+
$default:(result)=>{
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
const visibility = apiByConstructor.isActive('featureNotExists');
|
|
149
|
+
assert.strictEqual(visibility,true);
|
|
150
|
+
});
|
|
151
|
+
|
|
142
152
|
it("should return true if feature does not exist", function() {
|
|
143
153
|
const visibility = api.isActive('featureNotExists');
|
|
144
154
|
assert.strictEqual(visibility,true);
|
|
@@ -196,6 +206,28 @@ describe("Required Flag", function() {
|
|
|
196
206
|
assert.strictEqual(visibility,false);
|
|
197
207
|
});
|
|
198
208
|
|
|
209
|
+
it("should return true if required rule is passed by the constructor", function() {
|
|
210
|
+
const apiByConstructor = useFeatureToggle({
|
|
211
|
+
$required:(result)=>{
|
|
212
|
+
return result.variant == "valid";
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
apiByConstructor.setFlag('featureTrue','valid',true);
|
|
216
|
+
const visibility = apiByConstructor.isActive('featureTrue', 'valid');
|
|
217
|
+
assert.strictEqual(visibility,true);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
it("should return true if required rule and featureFlagis passed by the constructor", function() {
|
|
221
|
+
const apiByConstructor = useFeatureToggle({
|
|
222
|
+
"featureTrue:valid": true,
|
|
223
|
+
$required:(result)=>{
|
|
224
|
+
return result.variant == "valid";
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
const visibility = apiByConstructor.isActive('featureTrue', 'valid');
|
|
228
|
+
assert.strictEqual(visibility,true);
|
|
229
|
+
});
|
|
230
|
+
|
|
199
231
|
it("should return true if required rule matches and visibiltiyrule", function() {
|
|
200
232
|
api.setFlag('featureTrue', true);
|
|
201
233
|
const visibility = api.isActive('featureTrue', 'valid');
|
|
@@ -307,7 +339,9 @@ describe("Plugins", function() {
|
|
|
307
339
|
|
|
308
340
|
it("should be possible with legacy-key _plugins", function() {
|
|
309
341
|
function newPlugin(api) {
|
|
310
|
-
|
|
342
|
+
return {
|
|
343
|
+
newplugin: true
|
|
344
|
+
}
|
|
311
345
|
}
|
|
312
346
|
|
|
313
347
|
var api = useFeatureToggle({
|
|
@@ -318,7 +352,10 @@ describe("Plugins", function() {
|
|
|
318
352
|
|
|
319
353
|
it("should add attribute 'newplugin' to the api", function() {
|
|
320
354
|
function newPlugin(api) {
|
|
321
|
-
|
|
355
|
+
|
|
356
|
+
return {
|
|
357
|
+
newplugin: true
|
|
358
|
+
}
|
|
322
359
|
}
|
|
323
360
|
|
|
324
361
|
var api = useFeatureToggle();
|
|
@@ -328,7 +365,9 @@ describe("Plugins", function() {
|
|
|
328
365
|
|
|
329
366
|
it("should add plugins via attribute constructor config", function() {
|
|
330
367
|
function newPlugin(api) {
|
|
331
|
-
|
|
368
|
+
return {
|
|
369
|
+
newplugin: true
|
|
370
|
+
}
|
|
332
371
|
}
|
|
333
372
|
|
|
334
373
|
var api = useFeatureToggle({ $plugins: [newPlugin] });
|
|
@@ -343,6 +382,7 @@ describe("Plugins", function() {
|
|
|
343
382
|
|
|
344
383
|
function countPlugin(api) {
|
|
345
384
|
api.count += 1;
|
|
385
|
+
return {}
|
|
346
386
|
}
|
|
347
387
|
|
|
348
388
|
api.addPlugin(countPlugin);
|
|
@@ -355,6 +395,9 @@ describe("Plugins", function() {
|
|
|
355
395
|
api.on('init', function() {
|
|
356
396
|
api.initTriggered = true;
|
|
357
397
|
})
|
|
398
|
+
return {
|
|
399
|
+
initTriggered: false
|
|
400
|
+
}
|
|
358
401
|
}
|
|
359
402
|
|
|
360
403
|
var api = useFeatureToggle({ $plugins: [newPlugin] });
|
package/gulpfile.js
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
const { series, src, dest } = require('gulp');
|
|
2
|
-
const concat = require('gulp-concat');
|
|
3
|
-
const uglify = require('gulp-uglify');
|
|
4
|
-
const babel = require('gulp-babel');
|
|
5
|
-
const rollup = require('gulp-rollup');
|
|
6
|
-
|
|
7
|
-
function build_module() {
|
|
8
|
-
return src('src/index.js')
|
|
9
|
-
.pipe(rollup({
|
|
10
|
-
// any option supported by Rollup can be set here.
|
|
11
|
-
input: './src/index.js',
|
|
12
|
-
output: {
|
|
13
|
-
format: 'cjs'
|
|
14
|
-
}
|
|
15
|
-
}))
|
|
16
|
-
.pipe(babel({
|
|
17
|
-
presets: ["@babel/preset-env"]
|
|
18
|
-
}))
|
|
19
|
-
.pipe(concat('feature-toggle-api.module.js'))
|
|
20
|
-
.pipe(dest('./'));
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
function build_raw() {
|
|
24
|
-
return src('src/*.js')
|
|
25
|
-
.pipe(rollup({
|
|
26
|
-
// any option supported by Rollup can be set here.
|
|
27
|
-
input: './src/index.cjs.js',
|
|
28
|
-
output: {
|
|
29
|
-
format: 'cjs'
|
|
30
|
-
}
|
|
31
|
-
}))
|
|
32
|
-
.pipe(babel({
|
|
33
|
-
presets: ["@babel/preset-env"]
|
|
34
|
-
}))
|
|
35
|
-
.pipe(concat('feature-toggle-api.js'))
|
|
36
|
-
.pipe(dest('./'));
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
function build_min() {
|
|
40
|
-
return src('src/*.js')
|
|
41
|
-
.pipe(rollup({
|
|
42
|
-
// any option supported by Rollup can be set here.
|
|
43
|
-
input: './src/index.cjs.js',
|
|
44
|
-
output: {
|
|
45
|
-
format: 'cjs'
|
|
46
|
-
}
|
|
47
|
-
}))
|
|
48
|
-
.pipe(babel({
|
|
49
|
-
presets: ["@babel/preset-env"]
|
|
50
|
-
}))
|
|
51
|
-
.pipe(uglify())
|
|
52
|
-
.pipe(concat('feature-toggle-api.min.js'))
|
|
53
|
-
.pipe(dest('./'));
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
function build_plugins() {
|
|
57
|
-
return src(['src/plugins/htmlplugin/plugin-html.js', 'src/plugins/urlplugin/plugin-url.js'])
|
|
58
|
-
.pipe(babel({
|
|
59
|
-
presets: ["@babel/preset-env"]
|
|
60
|
-
}))
|
|
61
|
-
.pipe(uglify())
|
|
62
|
-
.pipe(dest('./'));
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
exports.build = series(build_raw, build_min, build_plugins, build_module);
|
package/plugin-html.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";var defaultparams={renderedTag:"div",featureTagName:"feature",tagAttributeName:"tag",nameAttributeName:"name",variantAttributeName:"variant",dataAttributeName:"data",displayAttributeName:"display",defaultDisplay:"block"};function parseDataAttribute(a){try{return JSON.parse(a)}catch(t){if(!isNaN(parseFloat(a)))return parseFloat(a);return a}}function htmlplugin(){var u=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};u=Object.assign({},defaultparams,u);function o(t,a){var e=t.getAttribute(u.tagAttributeName)||u.renderedTag;var r=Array.from(t.attributes);var n="";r.forEach(function(t){n+=" ".concat(t.nodeName,'="').concat(t.nodeValue.replace(/"/g,"""),'"')});var i=a?t.getAttribute(u.displayAttributeName)||u.defaultDisplay:"none";t.outerHTML="<".concat(e,' style="display:').concat(i,'" _feature="true" ').concat(n,">").concat(t.innerHTML,"</").concat(e,">")}return function(i){var t=window.document.querySelectorAll(u.featureTagName);t.forEach(function(t){o(t,false)});i.on("visibilityrule",function(n){var t="[_feature][".concat(u.nameAttributeName,'="').concat(n.name,'"]');if(n.variant)t+="[".concat(u.variantAttributeName,'="').concat(n.variant,'"]');var a=document.querySelectorAll(t);a.forEach(function(t){var a=t.getAttribute(u.dataAttributeName);var e=parseDataAttribute(a);var r=i.isVisible(n.name,n.variant,e);o(t,r)})});return{name:"htmlplugin"}}}if(typeof window!=="undefined")window.htmlplugin=htmlplugin;if(typeof module!=="undefined")module.exports=htmlplugin;
|
package/plugin-url.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";function parseValue(e){if(e==="true")return true;return false}function getParams(e,r){var i={};if(!e)return[];var n=e.split("?");if(n.length<2)return[];var u=n[1].split("&");u.forEach(function(e){var n=e.split("=");n[0]=r.decodeURIComponent(n[0]);n[1]=parseValue(r.decodeURIComponent(n[1]));i[n[0]]=n[1]!=="undefined"?n[1]:true});return i}function urlplugin(){var e=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};if(e.window)window=e.window;e=Object.assign({},{url:window.isMocked?"":window.location.href,prefix:""},e);return function(r){r.url=e.url;var i=getParams(e.url,window);var u=e.prefix;Object.keys(i).forEach(function(e){if(!e.startsWith(u))return;var n=e.replace(u,"");r.visibility(n,i[e])});return{name:"urlplugin"}}}if(typeof window!=="undefined")window.urlplugin=urlplugin;if(typeof module!=="undefined")module.exports=urlplugin;
|