feature-toggle-api 3.4.2 → 4.1.0

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.
Files changed (36) hide show
  1. package/README.md +129 -103
  2. package/dist/feature-toggle.d.ts +134 -0
  3. package/{src/index.js → dist/feature-toggle.js} +193 -114
  4. package/dist/feature-toggle.min.cjs +2 -0
  5. package/dist/feature-toggle.min.cjs.map +1 -0
  6. package/dist/feature-toggle.min.js +2 -0
  7. package/dist/feature-toggle.min.js.map +1 -0
  8. package/dist/feature-toggle.umd.min.js +2 -0
  9. package/dist/feature-toggle.umd.min.js.map +1 -0
  10. package/dist/html-plugin.umd.min.js +2 -0
  11. package/dist/html-plugin.umd.min.js.map +1 -0
  12. package/dist/url-plugin.umd.min.js +2 -0
  13. package/dist/url-plugin.umd.min.js.map +1 -0
  14. package/examples/01_basic_esmodule.js +10 -0
  15. package/examples/02_basic_cjsmodule.cjs +6 -0
  16. package/examples/{basic.html → 03_basic_scripttag.html} +3 -2
  17. package/examples/{example-htmlplugin.html → 04_example-htmlplugin.html} +2 -2
  18. package/examples/{example-urlplugin.html → 05_example-urlplugin.html} +2 -2
  19. package/examples/{withListener.html → 06_withListener.html} +1 -1
  20. package/package.json +32 -43
  21. package/rollup.config.js +107 -0
  22. package/src/featureToggle.ts +466 -0
  23. package/src/index.ts +10 -0
  24. package/src/plugins/htmlplugin/{plugin-html.js → plugin-html.ts} +22 -10
  25. package/src/plugins/urlplugin/{plugin-url.js → plugin-url.ts} +36 -10
  26. package/tests/featuretoggle.test.ts +450 -0
  27. package/tests/polyfills.ts +20 -0
  28. package/tsconfig.cjs.json +12 -0
  29. package/tsconfig.json +12 -0
  30. package/feature-toggle-api.js +0 -243
  31. package/feature-toggle-api.min.js +0 -1
  32. package/feature-toggle-api.module.js +0 -243
  33. package/spec/support/index.spec.js +0 -378
  34. package/spec/support/jasmine.json +0 -11
  35. package/spec/support/polyfills.js +0 -6
  36. package/src/index.cjs.js +0 -8
@@ -1,72 +1,176 @@
1
+ function useWindowMock() {
2
+ return {
3
+ isMocked: true,
4
+ decodeURIComponent: function (param1) {
5
+ return param1;
6
+ }
7
+ };
8
+ }
9
+ function parseValue(value) {
10
+ if (value === 'true')
11
+ return true;
12
+ return false;
13
+ }
14
+ function getParams(url, window) {
15
+ var params = {};
16
+ if (!url)
17
+ return [];
18
+ var urlparts = url.split("?");
19
+ //no params available for url
20
+ if (urlparts.length < 2)
21
+ return [];
22
+ const parts = urlparts[1].split('&');
23
+ parts.forEach(function (part) {
24
+ var pair = part.split('=');
25
+ pair[0] = window.decodeURIComponent(pair[0]);
26
+ pair[1] = parseValue(window.decodeURIComponent(pair[1]));
27
+ params[pair[0]] = (pair[1] !== 'undefined') ?
28
+ pair[1] : true;
29
+ });
30
+ return params;
31
+ }
32
+ function urlPlugin(config = {}) {
33
+ let _window;
34
+ if (config.useMockedWindow)
35
+ _window = useWindowMock();
36
+ else
37
+ _window = window;
38
+ config = Object.assign({}, {
39
+ url: _window.isMocked ? "" : _window.location.href,
40
+ prefix: ""
41
+ }, config);
42
+ return function (api) {
43
+ api.url = config.url;
44
+ const urlparams = getParams(config.url, _window);
45
+ const prefix = config.prefix;
46
+ Object.keys(urlparams).forEach(key => {
47
+ if (!key.startsWith(prefix))
48
+ return;
49
+ const keyWithoutPrefix = key.replace(prefix, "");
50
+ api.visibility(keyWithoutPrefix, urlparams[key]);
51
+ });
52
+ return { name: 'urlplugin' };
53
+ };
54
+ }
1
55
 
2
- const parseToFn = function (fnOrBool) {
3
- if (typeof fnOrBool == 'boolean')
4
- return function () { return fnOrBool };
56
+ /*
57
+ creates a tag that is shown / hidden, depending on the visibility rules.
58
+ if not configured dynamically, it looks like this:
59
+ <feature name="featurename" variant="variantname" data="data">content </feature>
60
+
61
+ Parameter: (config)
62
+ - config.featureTagName: name of the tag. Default: "feature"
63
+ - nameAttributeName: Name of the Name-Attribute: default: "name"
64
+ - variantAttributeName: Name of the Variant-Attribute: default: "variant"
65
+ */
66
+ const defaultparams = {
67
+ renderedTag: 'div',
68
+ featureTagName: 'feature',
69
+ tagAttributeName: 'tag',
70
+ nameAttributeName: 'name',
71
+ variantAttributeName: 'variant',
72
+ dataAttributeName: 'data',
73
+ displayAttributeName: 'display',
74
+ defaultDisplay: 'block',
75
+ };
76
+ function parseDataAttribute(attrAsString) {
77
+ try {
78
+ return JSON.parse(attrAsString);
79
+ }
80
+ catch (e) {
81
+ if (!isNaN(parseFloat(attrAsString)))
82
+ return parseFloat(attrAsString);
83
+ return attrAsString;
84
+ }
85
+ }
86
+ function htmlPlugin(config = {}) {
87
+ config = Object.assign({}, defaultparams, config);
88
+ function renderFeatureTag(elem, isVisible) {
89
+ const tagname = elem.getAttribute(config.tagAttributeName) || config.renderedTag;
90
+ const attributes = Array.from(elem.attributes);
91
+ let attributesAsString = "";
92
+ attributes.forEach(attr => {
93
+ attributesAsString += ` ${attr.nodeName}="${attr.nodeValue.replace(/"/g, "&quot;")}"`;
94
+ });
95
+ const display = isVisible ? (elem.getAttribute(config.displayAttributeName) || config.defaultDisplay) : 'none';
96
+ elem.outerHTML = `<${tagname} style="display:${display}" _feature="true" ${attributesAsString}>${elem.innerHTML}</${tagname}>`;
97
+ }
98
+ return function (api) {
99
+ var renderedTags = window.document.querySelectorAll(config.featureTagName);
100
+ renderedTags.forEach(tag => { renderFeatureTag(tag, false); });
101
+ api.on('visibilityrule', function (event) {
102
+ var selector = `[_feature][${config.nameAttributeName}="${event.name}"]`;
103
+ if (event.variant)
104
+ selector += `[${config.variantAttributeName}="${event.variant}"]`;
105
+ var elements = document.querySelectorAll(selector);
106
+ elements.forEach(elem => {
107
+ const dataAsString = elem.getAttribute(config.dataAttributeName);
108
+ const data = parseDataAttribute(dataAsString);
109
+ const isVisible = api.isVisible(event.name, event.variant, data);
110
+ renderFeatureTag(elem, isVisible);
111
+ });
112
+ });
113
+ return { name: 'htmlplugin' };
114
+ };
115
+ }
5
116
 
117
+ function parseToFn(fnOrBool) {
118
+ if (typeof fnOrBool == 'boolean')
119
+ return function () { return fnOrBool; };
6
120
  return fnOrBool;
7
121
  }
8
-
9
- const getKey = function (name, variant) {
122
+ function getKey(name, variant) {
10
123
  var _name = name.toLowerCase();
11
- if (typeof variant == 'string') {
124
+ if (variant && typeof variant == 'string') {
12
125
  _name += "#" + variant.toLowerCase();
13
126
  }
14
-
15
127
  return _name;
16
128
  }
17
-
18
129
  function initVisibilities(visibilities = {}) {
19
130
  const returnVisibilities = {};
20
131
  Object.keys(visibilities).forEach(key => {
21
- if(key.startsWith('_'))
132
+ if (key.startsWith('_') || key.startsWith('$'))
22
133
  return;
23
134
  returnVisibilities[getKey(key)] = parseToFn(visibilities[key]);
24
135
  });
25
136
  return returnVisibilities;
26
137
  }
27
-
28
- export default function featuretoggleapi(config={}) {
29
-
138
+ function useFeatureToggle(config = {}) {
30
139
  const globals = {
31
140
  datas: {},
32
141
  listeners: {},
33
142
  visibilities: initVisibilities(config),
34
143
  showLogs: false,
35
144
  usedPlugins: [],
36
- }
37
-
38
- function init(api){
39
- if(config._plugins)
40
- {
41
- if(!Array.isArray(config._plugins))
42
- throw new Error('featuretoggleapi()-constructor: config.plugins must be an array.');
43
-
44
- config._plugins.forEach(plugin =>{
45
- if(typeof plugin !== 'function')
145
+ };
146
+ function init(api) {
147
+ if (config.$default) {
148
+ api.setDefaultFlag(config.$default);
149
+ }
150
+ if (config.$required) {
151
+ api.setRequiredFlag(config.$required);
152
+ }
153
+ const allPlugins = [...(config.$plugins || []), ...(config._plugins || [])];
154
+ if (config._plugins) {
155
+ console.log('useFeatureToggle({_plugins:[]}): Key _plugins is deprecated. Use $plugins instead. This attribute will be removed in one of the next major versions.');
156
+ }
157
+ if (allPlugins.length) {
158
+ allPlugins.forEach(plugin => {
159
+ if (typeof plugin !== 'function')
46
160
  throw new Error('featuretoggleapi()-constructor: config.plugins needs functions as entries, not ' + typeof plugin + '.');
47
-
48
- addPlugin(plugin,api);
161
+ api.addPlugin(plugin);
49
162
  });
50
163
  }
51
-
52
164
  triggerEvent('init');
53
165
  }
54
-
55
- function addPlugin(plugin,api)
56
- {
57
- plugin(api);
58
- }
59
-
60
- function triggerEvent(eventtype,param) {
166
+ function triggerEvent(eventtype, param) {
61
167
  (globals.listeners[eventtype] || []).forEach(listener => {
62
168
  listener(param);
63
169
  });
64
170
  }
65
-
66
171
  const log = function (message) {
67
172
  if (!globals.showLogs)
68
173
  return;
69
-
70
174
  //Nur Browser können Syntaxhighlighting die anderen geben die Nachricht einfach aus und schneiden
71
175
  //die styletags raus
72
176
  if (typeof window === 'undefined') {
@@ -74,55 +178,45 @@ export default function featuretoggleapi(config={}) {
74
178
  console.log(loggedMessage);
75
179
  return;
76
180
  }
77
-
78
181
  var hasBoldTag = message.indexOf('<b>') != -1;
79
182
  var hasVisibleKeyword = message.indexOf('visible') != -1;
80
183
  var hasHiddenKeyword = message.indexOf('hidden') != -1;
81
-
82
184
  var _message = message.replace('visible', '%cvisible');
83
185
  _message = _message.replace('hidden', '%chidden');
84
-
85
186
  if (hasVisibleKeyword)
86
187
  console.log(_message, "color:green;font-weight:bold;");
87
188
  else if (hasHiddenKeyword)
88
189
  console.log(_message, "color:red;font-weight:bold;");
89
190
  else if (hasBoldTag) {
90
191
  _message = _message.replace('<b>', '%c');
91
- var parts = [_message, 'font-weight:bold;']
192
+ var parts = [_message, 'font-weight:bold;'];
92
193
  console.log.apply(null, parts);
93
194
  }
94
195
  else
95
196
  console.log(message);
96
- }
97
-
197
+ };
98
198
  const logAndReturn = function (returnValue, message) {
99
199
  log(message);
100
200
  log('');
101
201
  return returnValue;
102
- }
103
-
202
+ };
104
203
  const getVisibility = function (visibilityFn, functionname, name, variant, data) {
105
204
  if (visibilityFn == null)
106
205
  return undefined;
107
-
108
206
  var calculatedVisibility = visibilityFn({ name: name, variant: variant, data: data });
109
-
110
207
  if (typeof calculatedVisibility == 'boolean') {
111
208
  return calculatedVisibility;
112
209
  }
113
-
114
210
  return logAndReturn(false, `The ${functionname} returns ${calculatedVisibility}. => Please return true or false. This result (and all non-boolean results) will return false.`);
115
- }
116
-
211
+ };
117
212
  function parseKey(key) {
118
213
  const parts = key.split('#');
119
214
  return {
120
215
  name: parts[0],
121
216
  variant: parts.length > 1 ? parts[1] : undefined,
122
217
  data: globals.datas[key],
123
- }
218
+ };
124
219
  }
125
-
126
220
  /*
127
221
  the following calls are possible:
128
222
  visibility(name,result);
@@ -139,10 +233,8 @@ export default function featuretoggleapi(config={}) {
139
233
  //name must always be set
140
234
  if (param1 == undefined)
141
235
  throw new Error('feature.visibility(): 1st parameter name must be defined');
142
-
143
236
  if (arguments.length == 1)
144
237
  throw new Error('feature.visibility(): 2nd parameter name must be a boolean or function, but is empty');
145
-
146
238
  let name = param1, variant = null, data = null, result = null;
147
239
  if (param3 == undefined && param4 == undefined) {
148
240
  result = param2;
@@ -156,119 +248,89 @@ export default function featuretoggleapi(config={}) {
156
248
  data = param3;
157
249
  result = param4;
158
250
  }
159
-
160
251
  return {
161
252
  name,
162
253
  variant,
163
254
  data,
164
255
  result
165
- }
256
+ };
166
257
  }
167
-
168
258
  function getEvent(name, variant, data, result) {
169
-
170
259
  let event;
171
-
172
- event = { name: name, variant: variant, data: data };
173
-
260
+ event = { name, variant, data };
174
261
  event.key = getKey(event.name, event.variant);
175
-
176
262
  if (result == null)
177
263
  return event;
178
-
179
264
  event.visibilityFunction = parseToFn(result);
180
- event.result = event.visibilityFunction({
181
- name: event.name,
182
- variant: event.variant,
183
- data: event.data || {},
265
+ event.result = event.visibilityFunction({
266
+ name: event.name,
267
+ variant: event.variant,
268
+ data: event.data || {},
184
269
  _internalCall: true,
185
- description: 'When attaching a function, the result must be calculated internally. You can filter this out with the _internalCall:true -Flag.'
186
- })
270
+ description: 'When attaching a function, the result must be calculated internally. You can filter this out with the _internalCall:true -Flag.'
271
+ });
187
272
  return event;
188
273
  }
189
-
190
-
191
-
192
- function isVisible(name, variant, data) {
274
+ function isActive(name, variant, data) {
193
275
  const visibilities = globals.visibilities;
194
-
195
276
  log(`\nCheck Visibility of <b>Feature "${name}", variant "${variant == undefined ? '' : variant}"${data ? " with data " + JSON.stringify(data) : ""}.`);
196
277
  if (name == undefined)
197
278
  throw new Error('The attribute "name" is required for tag <feature></feature>. Example: <feature name="aname"></feature>');
198
-
199
279
  var requiredFn = visibilities['_required'];
200
280
  var requiredFnExists = visibilities['_required'] != null;
201
281
  var requiredFnResult = getVisibility(requiredFn, 'requiredVisibility', name, variant, data);
202
-
203
282
  var visibilityFnKey = getKey(name, variant);
204
283
  var visibilityFn = visibilities[visibilityFnKey];
205
284
  var visibilityFnExists = visibilities[visibilityFnKey] != null;
206
285
  var visibilityFnResult = getVisibility(visibilityFn, 'visibility function', name, variant, data);
207
-
208
286
  var variantExists = variant != null;
209
287
  var visibilityOnlyNameFnKey = getKey(name, null);
210
288
  var visibilityOnlyNameFn = visibilities[visibilityOnlyNameFnKey];
211
- var visibilityOnlyNameFnExists = visibilities[visibilityOnlyNameFnKey] != null;
212
289
  var visibilityOnlyNameFnResult = getVisibility(visibilityOnlyNameFn, 'visibility function (only name)', name, variant, data);
213
-
214
290
  var defaultFn = visibilities['_default'];
215
291
  var defaultFnExists = visibilities['_default'] != null;
216
292
  var defaultFnResult = getVisibility(defaultFn, 'defaultVisibility', name, variant, data);
217
-
218
293
  if (!requiredFnExists)
219
294
  log("No requiredVisibility rule specified for this feature.");
220
295
  else if (requiredFnExists && requiredFnResult === true)
221
- log("The requiredVisibility rule returns true. This feature will be shown when no other rule rejects it.")
296
+ log("The requiredVisibility rule returns true. This feature will be shown when no other rule rejects it.");
222
297
  else if (requiredFnExists && requiredFnResult === false)
223
298
  return logAndReturn(false, "The requiredVisibility rule returns false. This feature will be hidden.");
224
-
225
299
  if (visibilityFnExists)
226
300
  return logAndReturn(visibilityFnResult, `The visibility rule returns ${visibilityFnResult}. This feature will be ${visibilityFnResult ? 'visible' : 'hidden'}.`);
227
301
  log('No visibility rule found matching name and variant.');
228
-
229
302
  if (variantExists && typeof visibilityOnlyNameFnResult == 'boolean')
230
303
  return logAndReturn(visibilityOnlyNameFnResult, `Found a visibility rule for name ${name} without variants. The rule returns ${visibilityOnlyNameFnResult}. => This feature will be ${visibilityOnlyNameFnResult ? 'visible' : 'hidden'}.`);
231
304
  else if (variantExists)
232
- log(`No rules found for name ${name} without variants.`)
233
-
234
-
305
+ log(`No rules found for name ${name} without variants.`);
235
306
  if (defaultFnExists)
236
307
  return logAndReturn(defaultFnResult, `Found a defaultVisibility rule. The rule returns ${defaultFnResult}. => This feature will be ${defaultFnResult ? 'visible' : 'hidden'}.`);
237
- log(`No default rule found.`)
238
-
308
+ log(`No default rule found.`);
239
309
  if (requiredFnExists)
240
310
  return logAndReturn(true, `Only the requiredVisibility rule was found. This returned true. => This feature will be visible.`);
241
-
242
311
  return logAndReturn(false, 'No rules were found. This feature will be hidden.');
243
312
  }
244
-
245
313
  const api = {
246
314
  name: 'feature-toggle-api',
247
315
  setData: function (nameParam, variantOrDataParam, dataParam) {
248
316
  if (nameParam == undefined)
249
317
  throw new Error('setData(): The name must of the feature must be defined, but ist undefined');
250
-
251
- const variant = dataParam != undefined ? variantOrDataParam : undefined;
318
+ const variant = (dataParam != undefined ? variantOrDataParam : undefined);
252
319
  const data = dataParam || variantOrDataParam;
253
-
254
320
  const event = getEvent(nameParam, variant, data);
255
-
256
321
  globals.datas[event.key] = event.data;
257
-
258
- triggerEvent('visibilityrule',event);
322
+ triggerEvent('visibilityrule', event);
259
323
  },
260
- on: function (eventtype, fn, config) {
324
+ on(eventtype, fn, config) {
261
325
  globals.listeners[eventtype] = globals.listeners[eventtype] || [];
262
326
  globals.listeners[eventtype].push(fn);
263
-
264
- triggerEvent('registerEvent',{
327
+ triggerEvent('registerEvent', {
265
328
  type: eventtype
266
- })
329
+ });
267
330
  if (config != undefined && config.ignorePreviousRules)
268
331
  return;
269
-
270
332
  Object.keys(globals.visibilities).forEach(key => {
271
- const event = parseKey(key, globals);
333
+ const event = parseKey(key);
272
334
  const rule = globals.visibilities[key];
273
335
  event.result = rule(event);
274
336
  fn(event);
@@ -278,41 +340,58 @@ export default function featuretoggleapi(config={}) {
278
340
  showLogs: function (showLogs) {
279
341
  globals.showLogs = showLogs == undefined ? true : showLogs;
280
342
  },
281
- isVisible,
282
- /*
343
+ isVisible(name, variant, data) {
344
+ console.log('featureToggle.isVisible is deprecated. use featureToggle.isActive instead. This function will be removed in one of the next major versions.');
345
+ return isActive(name, variant, data);
346
+ },
347
+ isActive,
348
+ /**
283
349
  the following function calls are possible:
284
350
  visibility(name,result);
285
351
  visibility(name,variant,result);
286
352
  visibility(name,variant,data,result);
287
- */
288
- visibility: function (param1, param2, param3, param4) {
289
- const params = visibilityFnParams(param1, param2, param3, param4);
353
+ */
354
+ setFlag(name, resultOrVariant, resultOrData, result) {
355
+ const params = visibilityFnParams(name, resultOrVariant, resultOrData, result);
290
356
  const event = getEvent(params.name, params.variant, params.data, params.result);
291
-
292
357
  globals.visibilities[event.key] = event.visibilityFunction;
293
358
  globals.datas[event.key] = event.data;
294
- triggerEvent('visibilityrule',event);
359
+ triggerEvent('visibilityrule', event);
360
+ },
361
+ visibility: function (name, resultOrVariant, resultOrData, result) {
362
+ console.log('featureToggle.visibility is deprecated. use featureToggle.setVisibility instead. This function will be removed in one of the next major versions.');
363
+ api.setFlag(name, resultOrVariant, resultOrData, result);
295
364
  },
296
365
  requiredVisibility: function (fn) {
366
+ console.log('featureToggle.requiredVisibility is deprecated. use featureToggle.setRequiredFlag instead. This function will be removed in one of the next major versions.');
367
+ api.setRequiredFlag(fn);
368
+ },
369
+ defaultVisibility: function (fn) {
370
+ console.log('featureToggle.requiredVisibility is deprecated. use featureToggle.setRequiredFlag instead. This function will be removed in one of the next major versions.');
371
+ api.setDefaultFlag(fn);
372
+ },
373
+ setRequiredFlag(fn) {
297
374
  if (typeof fn != "function")
298
- throw new Error('feature.requiredVisibility(): 1st parameter must be a function, but is ' + typeof fn);
299
-
375
+ throw new Error('feature.setRequiredFlag(): 1st parameter must be a function, but is ' + typeof fn);
300
376
  globals.visibilities['_required'] = parseToFn(fn);
301
377
  },
302
- defaultVisibility: function (fn) {
378
+ setDefaultFlag(fn) {
303
379
  if (typeof fn != "function")
304
380
  throw new Error('feature.defaultVisibility(): 1st parameter must be a function, but is ' + typeof fn);
305
-
306
381
  globals.visibilities['_default'] = parseToFn(fn);
307
382
  },
308
- addPlugin: function(plugin){
309
- if(globals.usedPlugins.includes(plugin))
383
+ addPlugin: function (plugin) {
384
+ if (globals.usedPlugins.includes(plugin))
310
385
  return;
311
-
312
- addPlugin(plugin,api);
386
+ const newPlugin = plugin(api);
387
+ for (let _key of Object.keys(newPlugin)) {
388
+ api[_key] = newPlugin[_key];
389
+ }
313
390
  globals.usedPlugins.push(plugin);
314
391
  },
315
392
  };
316
393
  init(api);
317
394
  return api;
318
395
  }
396
+
397
+ export { htmlPlugin, urlPlugin, useFeatureToggle };
@@ -0,0 +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,"&quot;")}"`}));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
+ //# sourceMappingURL=feature-toggle.min.cjs.map
@@ -0,0 +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,\"&quot;\")}\"`;\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) => Partial<FeatureToggleApi>;\n\ntype EventType = 'visibilityrule' | 'init' | 'registerEvent' | string;\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}`;\ntype FeatureFlag = boolean | ((rule:Rule) => boolean);\ninterface FeatureToggleConfig {\n [key: FeatureFlagKey]: FeatureFlag,\n $plugins?: Plugin[]\n /**\n * @deprecated Use key`$plugins` instead.\n */\n _plugins?: Plugin[]\n\n /**\n * This rule will always run before the main rule. \n * If it returns false, the main rules will be skipped and false is returned\n */\n $required?: FeatureFlag\n\n /**\n * This rule will always run after the main rule. \n * If the main rule returns false, the result of the default rule will be taken.s\n */\n $default?: FeatureFlag\n}\n\ninterface Rule {\n name: string,\n variant: string,\n data: any,\n _internalCall?: true,\n description?: string\n}\n\ninterface FeatureToggleApiBase {\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: EventType, fn: (event: OnEvent) => void, config?: OnConfiguration): void;\n trigger(eventtype: EventType, 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\ntype FeatureToggleApi = FeatureToggleApiBase & Record<string, any>;\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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"}
@@ -0,0 +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,"&quot;")}"`}));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
+ //# sourceMappingURL=feature-toggle.min.js.map