-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathevaluateFlags.ts
93 lines (80 loc) · 2.62 KB
/
evaluateFlags.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import type { ClientFeaturesResponse, Context } from "unleash-client";
import type { IToggle } from "unleash-proxy-client";
import { ToggleEngine } from "./core/engine";
/**
* Turn server-side feature flags definitions (state from Unleash)
* into a list of toggles that can be used with a client-side SDK
*/
export const evaluateFlags = (
definitions: ClientFeaturesResponse,
context: Context = {}
): {
toggles: IToggle[];
} => {
let engine: ToggleEngine;
try {
engine = new ToggleEngine(definitions);
} catch (error) {
console.error(
"Unleash: Failed to evaluate flags from provided definitions",
error
);
return { toggles: [] };
}
const defaultContext: Context = {
currentTime: new Date(),
appName:
process.env.UNLEASH_APP_NAME || process.env.NEXT_PUBLIC_UNLEASH_APP_NAME,
};
const contextWithDefaults = {
...defaultContext,
...context,
};
const features = definitions?.features?.map((feature) => {
const variant = engine.getValue(feature.name, contextWithDefaults);
return {
name: feature.name,
enabled: Boolean(variant),
impressionData: Boolean(feature.impressionData),
variant: variant || { enabled: false, name: "disabled" },
dependencies: feature.dependencies,
};
});
const toggles = features
.filter((feature) => {
if (feature.enabled === false) return false;
if (!feature?.dependencies?.length) return true;
return feature.dependencies.every((dependency) => {
const parentToggle = features.find(
(toggle) => toggle.name === dependency.feature
);
if (!parentToggle)
console.warn(
`Unleash: \`${feature.name}\` has unresolved dependency \`${dependency.feature}\`.`
);
if (parentToggle?.dependencies?.length) {
console.warn(
`Unleash: \`${feature.name}\` cannot depend on \`${dependency.feature}\` which also has dependencies.`
);
return false;
}
if (parentToggle?.enabled && dependency.enabled === false) return false;
if (!parentToggle?.enabled && dependency.enabled !== false)
return false;
if (
dependency.variants?.length &&
(!parentToggle?.variant.name ||
!dependency.variants.includes(parentToggle.variant.name))
)
return false;
return true;
});
})
.map((feature) => ({
name: feature.name,
enabled: feature.enabled,
variant: { ...feature.variant, feature_enabled: feature.enabled },
impressionData: feature.impressionData,
}));
return { toggles };
};