feature-toggle-api 4.1.1 → 5.0.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 (50) hide show
  1. package/README.md +14 -16
  2. package/dist/feature-toggle.js +227 -385
  3. package/dist/feature-toggle.js.map +1 -0
  4. package/dist/featureToggle.d.ts +3 -0
  5. package/dist/html-plugin.js +42 -0
  6. package/dist/html-plugin.js.map +1 -0
  7. package/dist/index.d.ts +5 -0
  8. package/dist/plugins/htmlplugin/plugin-html.d.ts +15 -0
  9. package/dist/plugins/urlplugin/plugin-url.d.ts +14 -0
  10. package/{src/types.ts → dist/types.d.ts} +44 -64
  11. package/dist/url-plugin.js +40 -0
  12. package/dist/url-plugin.js.map +1 -0
  13. package/dist/vite.config.d.ts +2 -0
  14. package/package.json +26 -11
  15. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -35
  16. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -17
  17. package/dist/feature-toggle.d.ts +0 -130
  18. package/dist/feature-toggle.min.cjs +0 -2
  19. package/dist/feature-toggle.min.cjs.map +0 -1
  20. package/dist/feature-toggle.min.js +0 -2
  21. package/dist/feature-toggle.min.js.map +0 -1
  22. package/dist/feature-toggle.umd.min.js +0 -2
  23. package/dist/feature-toggle.umd.min.js.map +0 -1
  24. package/dist/html-plugin.umd.min.js +0 -2
  25. package/dist/html-plugin.umd.min.js.map +0 -1
  26. package/dist/url-plugin.umd.min.js +0 -2
  27. package/dist/url-plugin.umd.min.js.map +0 -1
  28. package/docs/_config.yml +0 -1
  29. package/docs/example-intro.html +0 -75
  30. package/docs/example-setup.html +0 -55
  31. package/docs/example-visibility-basic.html +0 -144
  32. package/docs/readme.md +0 -628
  33. package/docs/vue-feature-toggle.min.js +0 -902
  34. package/examples/01_basic_esmodule.js +0 -10
  35. package/examples/02_basic_cjsmodule.cjs +0 -6
  36. package/examples/03_basic_scripttag.html +0 -24
  37. package/examples/04_example-htmlplugin.html +0 -35
  38. package/examples/05_example-urlplugin.html +0 -25
  39. package/examples/06_withListener.html +0 -21
  40. package/rollup.config.js +0 -107
  41. package/src/featureToggle.ts +0 -352
  42. package/src/index.ts +0 -13
  43. package/src/plugins/htmlplugin/plugin-html.ts +0 -83
  44. package/src/plugins/htmlplugin/readme.md +0 -221
  45. package/src/plugins/urlplugin/plugin-url.ts +0 -90
  46. package/src/plugins/urlplugin/readme.md +0 -92
  47. package/tests/featuretoggle.test.ts +0 -450
  48. package/tests/polyfills.ts +0 -20
  49. package/tsconfig.cjs.json +0 -12
  50. package/tsconfig.json +0 -12
@@ -1,10 +0,0 @@
1
-
2
-
3
- import { useFeatureToggle } from "feature-toggle-api";
4
-
5
- const feature = useFeatureToggle({
6
- a:true,
7
- });
8
-
9
- console.log(feature.isVisible('a')); //true
10
- console.log(feature.isVisible('c')); //false
@@ -1,6 +0,0 @@
1
- const {useFeatureToggle} = require("feature-toggle-api/dist/feature-toggle.cjs");
2
-
3
- const feature = useFeatureToggle({a:true, b:false});
4
-
5
- console.log(feature.isVisible('a'));
6
- console.log(feature.isVisible('c'));
@@ -1,24 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <title>Basic Feature-Toggle-API-Test</title>
6
- <script src="../dist/feature-toggle.umd.min.js"></script>
7
- </head>
8
- <body>
9
- <div class="feature1" style="border:1px solid lightgray;padding:1em;margin:1em;">This is text from feature1</div>
10
- <div class="feature2" style="border:1px solid lightgray;padding:1em;margin:1em;">This is text from feature2</div>
11
- <script>
12
- //useFeatureToggle is a global defined by the script
13
- var api = useFeatureToggle({
14
- feature1: true
15
- });
16
- var feature1Visible = api.isVisible('feature1');
17
- var feature2Visible = api.isVisible('feature2');
18
-
19
- //here we could also use jquery,...
20
- if(!feature1Visible) document.querySelector(".feature1").style.display = 'none';
21
- if(!feature2Visible) document.querySelector(".feature2").style.display = 'none';
22
- </script>
23
- </body>
24
- </html>
@@ -1,35 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <title>HTML-Plugin Test</title>
6
- <script src="../dist/feature-toggle.umd.min.js"></script>
7
- <script src="../dist/html-plugin.umd.min.js"></script>
8
- </head>
9
- <body>
10
- <div id="app">
11
- <!-- The name property is required -->
12
- <feature name="feature1">This is "Feature1"</feature>
13
- <feature name="featureh1" tag="h1">This feature is rendered with a h1-tag as root-Element, not a div.</feature>
14
- <!-- The variant property is optional and can be any string -->
15
- <feature name="feature2">This is "Feature2"</feature>
16
- <feature name="feature2" variant="new">This is "Feature2" with variant "new"</feature>
17
- <feature name="feature2" variant="old">This "Feature2" with variant "old"</feature>
18
- <feature name="feature2" variant="grumpfel">This "Feature2" with variant "grumpfel"</feature>
19
-
20
- <feature name="feature3" variant="old" data='["a",2]'>This "Feature3" with variant "old" has some Data.</feature>
21
- <feature name="feature3" variant="new" data='{"text":"grumpfel"}'>This "Feature3" with variant "old" has some Data. </feature>
22
- </div>
23
- <script>
24
- var api = featuretoggleapi({
25
- "feature2#new": true,
26
- "feature2#grumpfel": true,
27
- "featureh1": true,
28
- _plugins: [htmlplugin()]
29
- });
30
- api.visibility("feature3",function(rule){
31
- return rule.data.text == 'grumpfel';
32
- })
33
- </script>
34
- </body>
35
- </html>
@@ -1,25 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <title>HTML-Plugin Test</title>
6
- <script src="../dist/feature-toggle.umd.min.js"></script>
7
- <script src="../dist/url-plugin.umd.min.js"></script>
8
- </head>
9
- <body>
10
- <div>
11
- Add a parameter "&feature1=true" ore "&feature2=true" to the url and see, how the visibility of these elements changes.
12
- </div>
13
- <div class="feature1" style="border:1px solid lightgray;padding:1em;margin:1em;display:none;">This is text from feature1</div>
14
- <div class="feature2" style="border:1px solid lightgray;padding:1em;margin:1em;display:none;">This is text from feature2</div>
15
- <script>
16
- var api = featuretoggleapi({
17
- _plugins: [urlplugin({prefix:'_'})]
18
- });
19
- api.on('visibilityrule', function (rule) {
20
- var featureVisible = api.isVisible(rule.name);
21
- if(featureVisible) document.querySelector("."+rule.name).style.display = 'block';
22
- });
23
- </script>
24
- </body>
25
- </html>
@@ -1,21 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <title>Listener Feature-Toggle-API-Test</title>
6
- <script src="../dist/feature-toggle.umd.min.js"></script>
7
- </head>
8
- <body>
9
- <div class="feature1" style="border:1px solid lightgray;padding:1em;margin:1em;">This is text from feature1</div>
10
- <div class="feature2" style="border:1px solid lightgray;padding:1em;margin:1em;">This is text from feature2</div>
11
- <script>
12
- var api = featuretoggleapi({
13
- feature1: true
14
- });
15
- api.on('visibilityrule', function (rule) {
16
- var featureVisible = api.isVisible(rule.name);
17
- if(!featureVisible) document.querySelector("."+rule.name).style.display = 'none';
18
- });
19
- </script>
20
- </body>
21
- </html>
package/rollup.config.js DELETED
@@ -1,107 +0,0 @@
1
- import { defineConfig } from 'rollup';
2
- import typescript from '@rollup/plugin-typescript'; // Für die JS-Bundles
3
- import dts from 'rollup-plugin-dts';
4
- import terser from '@rollup/plugin-terser';
5
-
6
- export default defineConfig([{
7
- input: "src/index.ts",
8
- output: [
9
- {
10
- file: 'dist/feature-toggle.js',
11
- format: 'es',
12
- },
13
- ],
14
- plugins: [
15
- typescript({
16
- tsconfig: './tsconfig.json', // Verwende deine tsconfig.json
17
- }),
18
- ]
19
- },{
20
- input: "src/index.ts",
21
- output: [
22
- {
23
- sourcemap:true,
24
- file: 'dist/feature-toggle.min.js',
25
- format: 'es',
26
- },
27
- ],
28
- plugins: [
29
- typescript({
30
- tsconfig: './tsconfig.json', // Verwende deine tsconfig.json
31
- }),
32
- terser()
33
- ]
34
- },
35
- {
36
- input: "src/index.ts",
37
- output: [
38
- {
39
- sourcemap: true,
40
- file: 'dist/feature-toggle.min.cjs',
41
- format: 'cjs'
42
- },
43
- ],
44
- plugins: [
45
- typescript({
46
- tsconfig: './tsconfig.cjs.json'
47
- }),
48
- terser()
49
- ]
50
- },{
51
- input: "src/featureToggle.ts",
52
- output: [
53
- {
54
- sourcemap: true,
55
- file: 'dist/feature-toggle.umd.min.js',
56
- format: 'umd',
57
- name: 'useFeatureToggle'
58
- },
59
- ],
60
- plugins: [
61
- typescript({
62
- tsconfig: './tsconfig.json'
63
- }),
64
- terser(),
65
- ]
66
- },{
67
- input: "src/plugins/htmlplugin/plugin-html.ts",
68
- output: [
69
- {
70
- sourcemap: true,
71
- file: 'dist/html-plugin.umd.min.js',
72
- format: 'umd',
73
- name: 'featureToggleHtmlPlugin'
74
- },
75
- ],
76
- plugins: [
77
- typescript({
78
- tsconfig: './tsconfig.json'
79
- }),
80
- terser(),
81
- ]
82
- },{
83
- input: "src/plugins/urlplugin/plugin-url.ts",
84
- output: [
85
- {
86
- sourcemap: true,
87
- file: 'dist/url-plugin.umd.min.js',
88
- format: 'umd',
89
- name: 'featureToggleURLPlugin'
90
- },
91
- ],
92
- plugins: [
93
- typescript({
94
- tsconfig: './tsconfig.json'
95
- }),
96
- terser(),
97
- ]
98
- },{
99
- input: 'src/index.ts',
100
- output: {
101
- file: 'dist/feature-toggle.d.ts',
102
- format: 'esm',
103
- },
104
- plugins: [
105
- dts(),
106
- ],
107
- },]);
@@ -1,352 +0,0 @@
1
- import { EventType, FeatureToggleApi, FeatureToggleConfig, OnEvent } from "./types";
2
-
3
- function parseToFn(fnOrBool: boolean | ((param?: any) => boolean)) {
4
- if (typeof fnOrBool == 'boolean')
5
- return function () { return fnOrBool };
6
-
7
- return fnOrBool;
8
- }
9
-
10
- function getKey(name: string, variant?: string): string {
11
- var _name = name.toLowerCase();
12
- if (variant && typeof variant == 'string') {
13
- _name += "#" + variant.toLowerCase();
14
- }
15
-
16
- return _name;
17
- }
18
-
19
- function initVisibilities(visibilities: FeatureToggleConfig = {}) {
20
- const returnVisibilities = {};
21
- Object.keys(visibilities).forEach(key => {
22
- if (key.startsWith('_') || key.startsWith('$'))
23
- return;
24
- returnVisibilities[getKey(key)] = parseToFn(visibilities[key]);
25
- });
26
- return returnVisibilities;
27
- }
28
-
29
- function useFeatureToggle(config: FeatureToggleConfig = {}): FeatureToggleApi {
30
-
31
- const globals = {
32
- datas: {},
33
- listeners: {},
34
- visibilities: initVisibilities(config),
35
- showLogs: false,
36
- usedPlugins: [],
37
- }
38
-
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
-
48
- const allPlugins = [...(config.$plugins||[]),...(config._plugins||[])];
49
- if(config._plugins){
50
- console.log('useFeatureToggle({_plugins:[]}): Key _plugins is deprecated. Use $plugins instead. This attribute will be removed in one of the next major versions.');
51
- }
52
-
53
-
54
- if (allPlugins.length) {
55
- allPlugins.forEach(plugin => {
56
- if (typeof plugin !== 'function')
57
- throw new Error('featuretoggleapi()-constructor: config.plugins needs functions as entries, not ' + typeof plugin + '.');
58
-
59
- api.addPlugin(plugin);
60
- });
61
- }
62
-
63
- triggerEvent('init');
64
- }
65
-
66
- function triggerEvent(eventtype: EventType, param?: any) {
67
- (globals.listeners[eventtype] || []).forEach(listener => {
68
- listener(param);
69
- });
70
- }
71
-
72
- const log = function (message) {
73
- if (!globals.showLogs)
74
- return;
75
-
76
- //Nur Browser können Syntaxhighlighting die anderen geben die Nachricht einfach aus und schneiden
77
- //die styletags raus
78
- if (typeof window === 'undefined') {
79
- const loggedMessage = message.replace(/<b>/g, "");
80
- console.log(loggedMessage);
81
- return;
82
- }
83
-
84
- var hasBoldTag = message.indexOf('<b>') != -1;
85
- var hasVisibleKeyword = message.indexOf('visible') != -1;
86
- var hasHiddenKeyword = message.indexOf('hidden') != -1;
87
-
88
- var _message = message.replace('visible', '%cvisible');
89
- _message = _message.replace('hidden', '%chidden');
90
-
91
- if (hasVisibleKeyword)
92
- console.log(_message, "color:green;font-weight:bold;");
93
- else if (hasHiddenKeyword)
94
- console.log(_message, "color:red;font-weight:bold;");
95
- else if (hasBoldTag) {
96
- _message = _message.replace('<b>', '%c');
97
- var parts = [_message, 'font-weight:bold;']
98
- console.log.apply(null, parts);
99
- }
100
- else
101
- console.log(message);
102
- }
103
-
104
- const logAndReturn = function (returnValue, message) {
105
- log(message);
106
- log('');
107
- return returnValue;
108
- }
109
-
110
- const getVisibility = function (visibilityFn, functionname, name, variant, data) {
111
- if (visibilityFn == null)
112
- return undefined;
113
-
114
- var calculatedVisibility = visibilityFn({ name: name, variant: variant, data: data });
115
-
116
- if (typeof calculatedVisibility == 'boolean') {
117
- return calculatedVisibility;
118
- }
119
-
120
- return logAndReturn(false, `The ${functionname} returns ${calculatedVisibility}. => Please return true or false. This result (and all non-boolean results) will return false.`);
121
- }
122
-
123
- function parseKey(key: string): OnEvent {
124
- const parts = key.split('#');
125
- return {
126
- name: parts[0],
127
- variant: parts.length > 1 ? parts[1] : undefined,
128
- data: globals.datas[key],
129
- }
130
- }
131
-
132
- /*
133
- the following calls are possible:
134
- visibility(name,result);
135
- visibility(name,variant,result);
136
- visibility(name,variant,data,result);
137
-
138
- =>
139
- param1: name
140
- param2: result || variant
141
- param3: result || data
142
- param4: result
143
- */
144
- function visibilityFnParams(param1, param2, param3, param4) {
145
- //name must always be set
146
- if (param1 == undefined)
147
- throw new Error('feature.visibility(): 1st parameter name must be defined');
148
-
149
- if (arguments.length == 1)
150
- throw new Error('feature.visibility(): 2nd parameter name must be a boolean or function, but is empty');
151
-
152
- let name = param1, variant = null, data = null, result = null;
153
- if (param3 == undefined && param4 == undefined) {
154
- result = param2;
155
- }
156
- else if (param4 == undefined) {
157
- variant = param2;
158
- result = param3;
159
- }
160
- else {
161
- variant = param2;
162
- data = param3;
163
- result = param4;
164
- }
165
-
166
- return {
167
- name,
168
- variant,
169
- data,
170
- result
171
- }
172
- }
173
-
174
- function getEvent(name: string, variant: string, data?, result?: any) {
175
-
176
- let event;
177
-
178
- event = { name, variant, data };
179
-
180
- event.key = getKey(event.name, event.variant);
181
-
182
- if (result == null)
183
- return event;
184
-
185
- event.visibilityFunction = parseToFn(result);
186
- event.result = event.visibilityFunction({
187
- name: event.name,
188
- variant: event.variant,
189
- data: event.data || {},
190
- _internalCall: true,
191
- description: 'When attaching a function, the result must be calculated internally. You can filter this out with the _internalCall:true -Flag.'
192
- })
193
- return event;
194
- }
195
-
196
-
197
-
198
- function isActive(name: string, variant?: string, data?: any): boolean {
199
- const visibilities = globals.visibilities;
200
-
201
- log(`\nCheck Visibility of <b>Feature "${name}", variant "${variant == undefined ? '' : variant}"${data ? " with data " + JSON.stringify(data) : ""}.`);
202
- if (name == undefined)
203
- throw new Error('The attribute "name" is required for tag <feature></feature>. Example: <feature name="aname"></feature>');
204
-
205
- var requiredFn = visibilities['_required'];
206
- var requiredFnExists = visibilities['_required'] != null;
207
- var requiredFnResult = getVisibility(requiredFn, 'requiredVisibility', name, variant, data);
208
-
209
- var visibilityFnKey = getKey(name, variant);
210
- var visibilityFn = visibilities[visibilityFnKey];
211
- var visibilityFnExists = visibilities[visibilityFnKey] != null;
212
- var visibilityFnResult = getVisibility(visibilityFn, 'visibility function', name, variant, data);
213
-
214
- var variantExists = variant != null;
215
- var visibilityOnlyNameFnKey = getKey(name, null);
216
- var visibilityOnlyNameFn = visibilities[visibilityOnlyNameFnKey];
217
- var visibilityOnlyNameFnExists = visibilities[visibilityOnlyNameFnKey] != null;
218
- var visibilityOnlyNameFnResult = getVisibility(visibilityOnlyNameFn, 'visibility function (only name)', name, variant, data);
219
-
220
- var defaultFn = visibilities['_default'];
221
- var defaultFnExists = visibilities['_default'] != null;
222
- var defaultFnResult = getVisibility(defaultFn, 'defaultVisibility', name, variant, data);
223
-
224
- if (!requiredFnExists)
225
- log("No requiredVisibility rule specified for this feature.");
226
- else if (requiredFnExists && requiredFnResult === true)
227
- log("The requiredVisibility rule returns true. This feature will be shown when no other rule rejects it.")
228
- else if (requiredFnExists && requiredFnResult === false)
229
- return logAndReturn(false, "The requiredVisibility rule returns false. This feature will be hidden.");
230
-
231
- if (visibilityFnExists)
232
- return logAndReturn(visibilityFnResult, `The visibility rule returns ${visibilityFnResult}. This feature will be ${visibilityFnResult ? 'visible' : 'hidden'}.`);
233
- log('No visibility rule found matching name and variant.');
234
-
235
- if (variantExists && typeof visibilityOnlyNameFnResult == 'boolean')
236
- return logAndReturn(visibilityOnlyNameFnResult, `Found a visibility rule for name ${name} without variants. The rule returns ${visibilityOnlyNameFnResult}. => This feature will be ${visibilityOnlyNameFnResult ? 'visible' : 'hidden'}.`);
237
- else if (variantExists)
238
- log(`No rules found for name ${name} without variants.`)
239
-
240
-
241
- if (defaultFnExists)
242
- return logAndReturn(defaultFnResult, `Found a defaultVisibility rule. The rule returns ${defaultFnResult}. => This feature will be ${defaultFnResult ? 'visible' : 'hidden'}.`);
243
- log(`No default rule found.`)
244
-
245
- if (requiredFnExists)
246
- return logAndReturn(true, `Only the requiredVisibility rule was found. This returned true. => This feature will be visible.`);
247
-
248
- return logAndReturn(false, 'No rules were found. This feature will be hidden.');
249
- }
250
-
251
- const api: FeatureToggleApi = {
252
- name: 'feature-toggle-api',
253
- setData: function (nameParam, variantOrDataParam, dataParam?): void {
254
- if (nameParam == undefined)
255
- throw new Error('setData(): The name must of the feature must be defined, but ist undefined');
256
-
257
- const variant = (dataParam != undefined ? variantOrDataParam : undefined) as string;
258
- const data = dataParam || variantOrDataParam;
259
-
260
- const event = getEvent(nameParam, variant, data);
261
-
262
- globals.datas[event.key] = event.data;
263
-
264
- triggerEvent('visibilityrule', event);
265
- },
266
- on(eventtype: EventType, fn, config?) {
267
- globals.listeners[eventtype] = globals.listeners[eventtype] || [];
268
- globals.listeners[eventtype].push(fn);
269
-
270
- triggerEvent('registerEvent', {
271
- type: eventtype
272
- })
273
- if (config != undefined && config.ignorePreviousRules)
274
- return;
275
-
276
-
277
- Object.keys(globals.visibilities).forEach(key => {
278
- const event = parseKey(key);
279
- const rule = globals.visibilities[key];
280
- event.result = rule(event);
281
- fn(event);
282
- });
283
- },
284
- trigger: triggerEvent,
285
- showLogs: function (showLogs?: boolean): void {
286
- globals.showLogs = showLogs == undefined ? true : showLogs;
287
- },
288
- isVisible(name,variant,data){
289
- console.log('featureToggle.isVisible is deprecated. use featureToggle.isActive instead. This function will be removed in one of the next major versions.');
290
- return isActive(name,variant,data);
291
- },
292
- isActive,
293
- /**
294
- the following function calls are possible:
295
- visibility(name,result);
296
- visibility(name,variant,result);
297
- visibility(name,variant,data,result);
298
- */
299
- setFlag(name, resultOrVariant, resultOrData?, result?) {
300
- const params = visibilityFnParams(name, resultOrVariant, resultOrData, result);
301
- const event = getEvent(params.name, params.variant, params.data, params.result);
302
-
303
- globals.visibilities[event.key] = event.visibilityFunction;
304
- globals.datas[event.key] = event.data;
305
- triggerEvent('visibilityrule', event);
306
- },
307
- visibility: function (name, resultOrVariant, resultOrData?, result?) {
308
- console.log('featureToggle.visibility is deprecated. use featureToggle.setVisibility instead. This function will be removed in one of the next major versions.');
309
-
310
- api.setFlag(name, resultOrVariant, resultOrData, result);
311
- },
312
- requiredVisibility: function (fn) {
313
- console.log('featureToggle.requiredVisibility is deprecated. use featureToggle.setRequiredFlag instead. This function will be removed in one of the next major versions.');
314
-
315
- api.setRequiredFlag(fn);
316
- },
317
- defaultVisibility: function (fn) {
318
- console.log('featureToggle.requiredVisibility is deprecated. use featureToggle.setRequiredFlag instead. This function will be removed in one of the next major versions.');
319
-
320
- api.setDefaultFlag(fn);
321
- },
322
- setRequiredFlag(fn) {
323
- if (typeof fn != "function")
324
- throw new Error('feature.setRequiredFlag(): 1st parameter must be a function, but is ' + typeof fn);
325
-
326
- globals.visibilities['_required'] = parseToFn(fn);
327
- },
328
- setDefaultFlag(fn) {
329
- if (typeof fn != "function")
330
- throw new Error('feature.defaultVisibility(): 1st parameter must be a function, but is ' + typeof fn);
331
-
332
- globals.visibilities['_default'] = parseToFn(fn);
333
- },
334
- addPlugin: function (plugin) {
335
- if (globals.usedPlugins.includes(plugin))
336
- return;
337
-
338
- const newPlugin = plugin(api);
339
-
340
- for(let _key of Object.keys(newPlugin)){
341
- api[_key] = newPlugin[_key];
342
- }
343
-
344
- globals.usedPlugins.push(plugin);
345
- },
346
- };
347
- init(api);
348
-
349
- return api;
350
- }
351
-
352
- export default useFeatureToggle;
package/src/index.ts DELETED
@@ -1,13 +0,0 @@
1
- import { urlPlugin } from "./plugins/urlplugin/plugin-url"
2
- import { htmlPlugin } from "./plugins/htmlplugin/plugin-html"
3
- import useFeatureToggle from "./featureToggle"
4
- import type {
5
- FeatureFlag, FeatureFlagKey, FeatureToggleApi, FeatureToggleApiBase, FeatureToggleConfig, FirstCharOfFeatureFlagKey, OnConfiguration, EventType, OnEvent
6
- } from './types';
7
-
8
- export {
9
- useFeatureToggle,
10
- urlPlugin,
11
- htmlPlugin,
12
- FeatureFlag, FeatureFlagKey, FeatureToggleApi, FeatureToggleApiBase, FeatureToggleConfig, FirstCharOfFeatureFlagKey, OnConfiguration, EventType, OnEvent
13
- }
@@ -1,83 +0,0 @@
1
- type Display = 'block' | 'inline-block' | 'inline' | 'flex' | 'inline-flex' | 'grid' | 'inline-grid';
2
-
3
- interface HtmlPluginConfig {
4
- renderedTag?: string,
5
- featureTagName?: string,
6
- tagAttributeName?: string,
7
- nameAttributeName?:string,
8
- variantAttributeName?: string,
9
- dataAttributeName?: string,
10
- displayAttributeName?: string,
11
- defaultDisplay?: Display,
12
- }
13
-
14
- /*
15
- creates a tag that is shown / hidden, depending on the visibility rules.
16
- if not configured dynamically, it looks like this:
17
- <feature name="featurename" variant="variantname" data="data">content </feature>
18
-
19
- Parameter: (config)
20
- - config.featureTagName: name of the tag. Default: "feature"
21
- - nameAttributeName: Name of the Name-Attribute: default: "name"
22
- - variantAttributeName: Name of the Variant-Attribute: default: "variant"
23
- */
24
- const defaultparams :HtmlPluginConfig = {
25
- renderedTag: 'div',
26
- featureTagName: 'feature',
27
- tagAttributeName: 'tag',
28
- nameAttributeName:'name',
29
- variantAttributeName: 'variant',
30
- dataAttributeName: 'data',
31
- displayAttributeName: 'display',
32
- defaultDisplay: 'block',
33
- }
34
- function parseDataAttribute(attrAsString){
35
- try{
36
- return JSON.parse(attrAsString);
37
- }
38
- catch(e)
39
- {
40
- if(!isNaN(parseFloat(attrAsString)))
41
- return parseFloat(attrAsString);
42
-
43
- return attrAsString;
44
- }
45
- }
46
-
47
- function htmlPlugin(config :HtmlPluginConfig = {}) {
48
- config = Object.assign({},defaultparams,config);
49
-
50
- function renderFeatureTag(elem:HTMLElement,isVisible){
51
- const tagname = elem.getAttribute(config.tagAttributeName) || config.renderedTag;
52
- const attributes = Array.from(elem.attributes);
53
- let attributesAsString = "";
54
- attributes.forEach(attr => {
55
- attributesAsString += ` ${attr.nodeName}="${attr.nodeValue.replace(/"/g,"&quot;")}"`;
56
- });
57
- const display = isVisible ? (elem.getAttribute(config.displayAttributeName) || config.defaultDisplay) : 'none';
58
- elem.outerHTML = `<${tagname} style="display:${display}" _feature="true" ${attributesAsString}>${elem.innerHTML}</${tagname}>`;
59
- }
60
- return function (api) {
61
- var renderedTags :NodeListOf<HTMLElement> = window.document.querySelectorAll(config.featureTagName);
62
- renderedTags.forEach(tag => { renderFeatureTag(tag,false) });
63
-
64
- api.on('visibilityrule', function (event) {
65
- var selector = `[_feature][${config.nameAttributeName}="${event.name}"]`;
66
- if (event.variant) selector += `[${config.variantAttributeName}="${event.variant}"]`;
67
- var elements :NodeListOf<HTMLElement> = document.querySelectorAll(selector);
68
- elements.forEach(elem => {
69
- const dataAsString = elem.getAttribute(config.dataAttributeName);
70
- const data = parseDataAttribute(dataAsString);
71
-
72
- const isVisible = api.isVisible(event.name,event.variant,data);
73
- renderFeatureTag(elem, isVisible);
74
- });
75
- })
76
-
77
- return { name: 'htmlplugin' };
78
- }
79
- }
80
-
81
- export {
82
- htmlPlugin
83
- }