@zudojs/feature-flags 0.0.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.
Files changed (127) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +40 -0
  3. package/dist/evaluator/evaluator.core.d.ts +20 -0
  4. package/dist/evaluator/evaluator.core.d.ts.map +1 -0
  5. package/dist/evaluator/evaluator.core.js +86 -0
  6. package/dist/evaluator/evaluator.core.js.map +1 -0
  7. package/dist/evaluator/evaluatorAttribute.d.ts +26 -0
  8. package/dist/evaluator/evaluatorAttribute.d.ts.map +1 -0
  9. package/dist/evaluator/evaluatorAttribute.js +84 -0
  10. package/dist/evaluator/evaluatorAttribute.js.map +1 -0
  11. package/dist/evaluator/evaluatorRule.core.d.ts +29 -0
  12. package/dist/evaluator/evaluatorRule.core.d.ts.map +1 -0
  13. package/dist/evaluator/evaluatorRule.core.js +73 -0
  14. package/dist/evaluator/evaluatorRule.core.js.map +1 -0
  15. package/dist/evaluator/index.d.ts +10 -0
  16. package/dist/evaluator/index.d.ts.map +1 -0
  17. package/dist/evaluator/index.js +9 -0
  18. package/dist/evaluator/index.js.map +1 -0
  19. package/dist/featureFlagErrors/featureFlagError.base.d.ts +24 -0
  20. package/dist/featureFlagErrors/featureFlagError.base.d.ts.map +1 -0
  21. package/dist/featureFlagErrors/featureFlagError.base.js +24 -0
  22. package/dist/featureFlagErrors/featureFlagError.base.js.map +1 -0
  23. package/dist/featureFlagErrors/featureFlagError.types.d.ts +38 -0
  24. package/dist/featureFlagErrors/featureFlagError.types.d.ts.map +1 -0
  25. package/dist/featureFlagErrors/featureFlagError.types.js +79 -0
  26. package/dist/featureFlagErrors/featureFlagError.types.js.map +1 -0
  27. package/dist/featureFlagErrors/index.d.ts +9 -0
  28. package/dist/featureFlagErrors/index.d.ts.map +1 -0
  29. package/dist/featureFlagErrors/index.js +8 -0
  30. package/dist/featureFlagErrors/index.js.map +1 -0
  31. package/dist/featureFlagTypes/featureFlag.interface.d.ts +50 -0
  32. package/dist/featureFlagTypes/featureFlag.interface.d.ts.map +1 -0
  33. package/dist/featureFlagTypes/featureFlag.interface.js +9 -0
  34. package/dist/featureFlagTypes/featureFlag.interface.js.map +1 -0
  35. package/dist/featureFlagTypes/featureFlagContext.d.ts +21 -0
  36. package/dist/featureFlagTypes/featureFlagContext.d.ts.map +1 -0
  37. package/dist/featureFlagTypes/featureFlagContext.js +9 -0
  38. package/dist/featureFlagTypes/featureFlagContext.js.map +1 -0
  39. package/dist/featureFlagTypes/featureFlagEvaluation.d.ts +26 -0
  40. package/dist/featureFlagTypes/featureFlagEvaluation.d.ts.map +1 -0
  41. package/dist/featureFlagTypes/featureFlagEvaluation.js +9 -0
  42. package/dist/featureFlagTypes/featureFlagEvaluation.js.map +1 -0
  43. package/dist/featureFlagTypes/featureFlagProvider.d.ts +24 -0
  44. package/dist/featureFlagTypes/featureFlagProvider.d.ts.map +1 -0
  45. package/dist/featureFlagTypes/featureFlagProvider.js +9 -0
  46. package/dist/featureFlagTypes/featureFlagProvider.js.map +1 -0
  47. package/dist/featureFlagTypes/featureFlagRule/featureFlagRule.type.d.ts +60 -0
  48. package/dist/featureFlagTypes/featureFlagRule/featureFlagRule.type.d.ts.map +1 -0
  49. package/dist/featureFlagTypes/featureFlagRule/featureFlagRule.type.js +9 -0
  50. package/dist/featureFlagTypes/featureFlagRule/featureFlagRule.type.js.map +1 -0
  51. package/dist/featureFlagTypes/featureFlagRule/featureFlagValue.type.d.ts +14 -0
  52. package/dist/featureFlagTypes/featureFlagRule/featureFlagValue.type.d.ts.map +1 -0
  53. package/dist/featureFlagTypes/featureFlagRule/featureFlagValue.type.js +9 -0
  54. package/dist/featureFlagTypes/featureFlagRule/featureFlagValue.type.js.map +1 -0
  55. package/dist/featureFlagTypes/featureFlagRule/index.d.ts +8 -0
  56. package/dist/featureFlagTypes/featureFlagRule/index.d.ts.map +1 -0
  57. package/dist/featureFlagTypes/featureFlagRule/index.js +8 -0
  58. package/dist/featureFlagTypes/featureFlagRule/index.js.map +1 -0
  59. package/dist/featureFlagTypes/index.d.ts +9 -0
  60. package/dist/featureFlagTypes/index.d.ts.map +1 -0
  61. package/dist/featureFlagTypes/index.js +5 -0
  62. package/dist/featureFlagTypes/index.js.map +1 -0
  63. package/dist/featureFlags/featureFlags.core.d.ts +37 -0
  64. package/dist/featureFlags/featureFlags.core.d.ts.map +1 -0
  65. package/dist/featureFlags/featureFlags.core.js +101 -0
  66. package/dist/featureFlags/featureFlags.core.js.map +1 -0
  67. package/dist/featureFlags/featureFlags.resolve.d.ts +21 -0
  68. package/dist/featureFlags/featureFlags.resolve.d.ts.map +1 -0
  69. package/dist/featureFlags/featureFlags.resolve.js +44 -0
  70. package/dist/featureFlags/featureFlags.resolve.js.map +1 -0
  71. package/dist/featureFlags/index.d.ts +8 -0
  72. package/dist/featureFlags/index.d.ts.map +1 -0
  73. package/dist/featureFlags/index.js +7 -0
  74. package/dist/featureFlags/index.js.map +1 -0
  75. package/dist/index.d.ts +29 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +29 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/provider/index.d.ts +12 -0
  80. package/dist/provider/index.d.ts.map +1 -0
  81. package/dist/provider/index.js +10 -0
  82. package/dist/provider/index.js.map +1 -0
  83. package/dist/provider/providerCached.core.d.ts +22 -0
  84. package/dist/provider/providerCached.core.d.ts.map +1 -0
  85. package/dist/provider/providerCached.core.js +45 -0
  86. package/dist/provider/providerCached.core.js.map +1 -0
  87. package/dist/provider/providerComposite.core.d.ts +19 -0
  88. package/dist/provider/providerComposite.core.d.ts.map +1 -0
  89. package/dist/provider/providerComposite.core.js +48 -0
  90. package/dist/provider/providerComposite.core.js.map +1 -0
  91. package/dist/provider/providerEnvironment.core.d.ts +25 -0
  92. package/dist/provider/providerEnvironment.core.d.ts.map +1 -0
  93. package/dist/provider/providerEnvironment.core.js +63 -0
  94. package/dist/provider/providerEnvironment.core.js.map +1 -0
  95. package/dist/provider/providerMemory.core.d.ts +17 -0
  96. package/dist/provider/providerMemory.core.d.ts.map +1 -0
  97. package/dist/provider/providerMemory.core.js +36 -0
  98. package/dist/provider/providerMemory.core.js.map +1 -0
  99. package/dist/registry/index.d.ts +8 -0
  100. package/dist/registry/index.d.ts.map +1 -0
  101. package/dist/registry/index.js +7 -0
  102. package/dist/registry/index.js.map +1 -0
  103. package/dist/registry/registry.core.d.ts +35 -0
  104. package/dist/registry/registry.core.d.ts.map +1 -0
  105. package/dist/registry/registry.core.js +47 -0
  106. package/dist/registry/registry.core.js.map +1 -0
  107. package/dist/rollout/index.d.ts +8 -0
  108. package/dist/rollout/index.d.ts.map +1 -0
  109. package/dist/rollout/index.js +8 -0
  110. package/dist/rollout/index.js.map +1 -0
  111. package/dist/rollout/rolloutBucketing.d.ts +27 -0
  112. package/dist/rollout/rolloutBucketing.d.ts.map +1 -0
  113. package/dist/rollout/rolloutBucketing.js +42 -0
  114. package/dist/rollout/rolloutBucketing.js.map +1 -0
  115. package/dist/rollout/rolloutHashing.d.ts +15 -0
  116. package/dist/rollout/rolloutHashing.d.ts.map +1 -0
  117. package/dist/rollout/rolloutHashing.js +26 -0
  118. package/dist/rollout/rolloutHashing.js.map +1 -0
  119. package/dist/utils/index.d.ts +7 -0
  120. package/dist/utils/index.d.ts.map +1 -0
  121. package/dist/utils/index.js +7 -0
  122. package/dist/utils/index.js.map +1 -0
  123. package/dist/utils/utils.helper.d.ts +15 -0
  124. package/dist/utils/utils.helper.d.ts.map +1 -0
  125. package/dist/utils/utils.helper.js +27 -0
  126. package/dist/utils/utils.helper.js.map +1 -0
  127. package/package.json +49 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Zudojs Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # @zudojs/feature-flags
2
+
3
+ Feature flag system with deterministic rollouts, rule engine, providers, variants, snapshots, and evaluation context.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @zudojs/feature-flags
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { createFeatureFlags } from "@zudojs/feature-flags";
15
+
16
+ const flags = createFeatureFlags({
17
+ rules: [
18
+ { key: "new-ui", rollout: 0.1 },
19
+ { key: "beta-feature", users: ["user-123"] },
20
+ ],
21
+ });
22
+
23
+ const enabled = await flags.isEnabled("new-ui", { userId: "user-456" });
24
+ ```
25
+
26
+ ## Features
27
+
28
+ - Percentage rollouts
29
+ - User and segment targeting
30
+ - A/B testing variants
31
+ - Rule engine with AND/OR logic
32
+ - Snapshot export for client-side flags
33
+ - Evaluation context
34
+
35
+ ## Use Cases
36
+
37
+ - Gradual feature rollouts
38
+ - A/B testing
39
+ - Kill switches
40
+ - Beta feature access
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Feature flag evaluator.
3
+ *
4
+ * Runs rules in order against a context and produces a structured evaluation result.
5
+ *
6
+ * @module evaluator/evaluator
7
+ */
8
+ import type { FeatureFlag } from "../featureFlagTypes/featureFlag.interface.js";
9
+ import type { FeatureFlagContext } from "../featureFlagTypes/featureFlagContext.js";
10
+ import type { FeatureFlagValue } from "../featureFlagTypes/featureFlagRule/featureFlagValue.type.js";
11
+ import type { FeatureFlagEvaluation } from "../featureFlagTypes/featureFlagEvaluation.js";
12
+ /**
13
+ * Evaluate a feature flag against a context.
14
+ *
15
+ * @param flag - The feature flag definition.
16
+ * @param context - The evaluation context.
17
+ * @returns A structured evaluation result.
18
+ */
19
+ export declare function evaluateFlag<TValue extends FeatureFlagValue = FeatureFlagValue>(flag: FeatureFlag, context?: FeatureFlagContext): FeatureFlagEvaluation<TValue>;
20
+ //# sourceMappingURL=evaluator.core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluator.core.d.ts","sourceRoot":"","sources":["../../src/evaluator/evaluator.core.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8CAA8C,CAAC;AAChF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AACpF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8DAA8D,CAAC;AACrG,OAAO,KAAK,EACV,qBAAqB,EAEtB,MAAM,8CAA8C,CAAC;AAGtD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,MAAM,SAAS,gBAAgB,GAAG,gBAAgB,EAElD,IAAI,EAAE,WAAW,EACjB,OAAO,GAAE,kBAAuB,GAC/B,qBAAqB,CAAC,MAAM,CAAC,CA8E/B"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Feature flag evaluator.
3
+ *
4
+ * Runs rules in order against a context and produces a structured evaluation result.
5
+ *
6
+ * @module evaluator/evaluator
7
+ */
8
+ import { evaluateRule } from "./evaluatorRule.core.js";
9
+ /**
10
+ * Evaluate a feature flag against a context.
11
+ *
12
+ * @param flag - The feature flag definition.
13
+ * @param context - The evaluation context.
14
+ * @returns A structured evaluation result.
15
+ */
16
+ export function evaluateFlag(flag, context = {}) {
17
+ if (!flag.enabled) {
18
+ return {
19
+ key: flag.key,
20
+ value: flag.defaultValue,
21
+ reason: "disabled",
22
+ defaulted: true,
23
+ };
24
+ }
25
+ if (flag.state === "archived" || flag.state === "draft") {
26
+ return {
27
+ key: flag.key,
28
+ value: flag.defaultValue,
29
+ reason: flag.state === "archived" ? "expired" : "disabled",
30
+ defaulted: true,
31
+ };
32
+ }
33
+ if (flag.metadata?.expiresAt && flag.metadata.expiresAt < new Date()) {
34
+ return {
35
+ key: flag.key,
36
+ value: flag.defaultValue,
37
+ reason: "expired",
38
+ defaulted: true,
39
+ };
40
+ }
41
+ if (flag.dependencies && flag.dependencies.length > 0) {
42
+ return {
43
+ key: flag.key,
44
+ value: flag.defaultValue,
45
+ reason: "dependency_disabled",
46
+ matchedRule: undefined,
47
+ defaulted: true,
48
+ };
49
+ }
50
+ if (!flag.rules || flag.rules.length === 0) {
51
+ return {
52
+ key: flag.key,
53
+ value: flag.defaultValue,
54
+ reason: "default",
55
+ defaulted: true,
56
+ };
57
+ }
58
+ for (let i = 0; i < flag.rules.length; i++) {
59
+ const rule = flag.rules[i];
60
+ const result = evaluateRule(rule, context, flag.key);
61
+ if (result.matched) {
62
+ const reason = rule.type === "percentage"
63
+ ? "percentage_rollout"
64
+ : rule.type === "variant"
65
+ ? "variant_assignment"
66
+ : rule.type === "static"
67
+ ? "static"
68
+ : "rule_match";
69
+ return {
70
+ key: flag.key,
71
+ value: (result.value ?? flag.defaultValue),
72
+ reason,
73
+ matchedRule: i,
74
+ variant: result.variant,
75
+ defaulted: false,
76
+ };
77
+ }
78
+ }
79
+ return {
80
+ key: flag.key,
81
+ value: flag.defaultValue,
82
+ reason: "default",
83
+ defaulted: true,
84
+ };
85
+ }
86
+ //# sourceMappingURL=evaluator.core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluator.core.js","sourceRoot":"","sources":["../../src/evaluator/evaluator.core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Attribute matching for feature flag targeting rules.
3
+ *
4
+ * Supports dot-notation traversal for nested attributes and all comparison operators.
5
+ *
6
+ * @module evaluator/evaluatorAttribute
7
+ */
8
+ import type { FeatureFlagOperator } from "../featureFlagTypes/featureFlagRule/featureFlagRule.type.js";
9
+ /**
10
+ * Safely resolve a dot-notation path from an object.
11
+ *
12
+ * @param obj - The object to traverse.
13
+ * @param path - Dot-separated path (e.g. "user.country").
14
+ * @returns The value at the path, or undefined.
15
+ */
16
+ export declare function resolvePath(obj: unknown, path: string): unknown;
17
+ /**
18
+ * Evaluate an attribute rule against a context value.
19
+ *
20
+ * @param actual - The actual value from context.
21
+ * @param operator - The comparison operator.
22
+ * @param expected - The expected value from the rule.
23
+ * @returns Whether the condition matches.
24
+ */
25
+ export declare function matchAttribute(actual: unknown, operator: FeatureFlagOperator, expected: unknown): boolean;
26
+ //# sourceMappingURL=evaluatorAttribute.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluatorAttribute.d.ts","sourceRoot":"","sources":["../../src/evaluator/evaluatorAttribute.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6DAA6D,CAAC;AAEvG;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAgB/D;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,mBAAmB,EAC7B,QAAQ,EAAE,OAAO,GAChB,OAAO,CA4ET"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Attribute matching for feature flag targeting rules.
3
+ *
4
+ * Supports dot-notation traversal for nested attributes and all comparison operators.
5
+ *
6
+ * @module evaluator/evaluatorAttribute
7
+ */
8
+ /**
9
+ * Safely resolve a dot-notation path from an object.
10
+ *
11
+ * @param obj - The object to traverse.
12
+ * @param path - Dot-separated path (e.g. "user.country").
13
+ * @returns The value at the path, or undefined.
14
+ */
15
+ export function resolvePath(obj, path) {
16
+ const parts = path.split(".");
17
+ let current = obj;
18
+ for (const part of parts) {
19
+ if (current === null ||
20
+ current === undefined ||
21
+ typeof current !== "object") {
22
+ return undefined;
23
+ }
24
+ current = current[part];
25
+ }
26
+ return current;
27
+ }
28
+ /**
29
+ * Evaluate an attribute rule against a context value.
30
+ *
31
+ * @param actual - The actual value from context.
32
+ * @param operator - The comparison operator.
33
+ * @param expected - The expected value from the rule.
34
+ * @returns Whether the condition matches.
35
+ */
36
+ export function matchAttribute(actual, operator, expected) {
37
+ switch (operator) {
38
+ case "equals":
39
+ return actual === expected;
40
+ case "not_equals":
41
+ return actual !== expected;
42
+ case "contains":
43
+ return (typeof actual === "string" &&
44
+ typeof expected === "string" &&
45
+ actual.includes(expected));
46
+ case "starts_with":
47
+ return (typeof actual === "string" &&
48
+ typeof expected === "string" &&
49
+ actual.startsWith(expected));
50
+ case "ends_with":
51
+ return (typeof actual === "string" &&
52
+ typeof expected === "string" &&
53
+ actual.endsWith(expected));
54
+ case "in":
55
+ return Array.isArray(expected) && expected.includes(actual);
56
+ case "not_in":
57
+ return Array.isArray(expected) && !expected.includes(actual);
58
+ case "greater_than":
59
+ return (typeof actual === "number" &&
60
+ typeof expected === "number" &&
61
+ actual > expected);
62
+ case "greater_than_or_equal":
63
+ return (typeof actual === "number" &&
64
+ typeof expected === "number" &&
65
+ actual >= expected);
66
+ case "less_than":
67
+ return (typeof actual === "number" &&
68
+ typeof expected === "number" &&
69
+ actual < expected);
70
+ case "less_than_or_equal":
71
+ return (typeof actual === "number" &&
72
+ typeof expected === "number" &&
73
+ actual <= expected);
74
+ case "exists":
75
+ return actual !== undefined && actual !== null;
76
+ case "matches":
77
+ return (typeof actual === "string" &&
78
+ typeof expected === "string" &&
79
+ new RegExp(expected).test(actual));
80
+ default:
81
+ return false;
82
+ }
83
+ }
84
+ //# sourceMappingURL=evaluatorAttribute.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluatorAttribute.js","sourceRoot":"","sources":["../../src/evaluator/evaluatorAttribute.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,GAAY,EAAE,IAAY;IACpD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,OAAO,GAAY,GAAG,CAAC;IAE3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IACE,OAAO,KAAK,IAAI;YAChB,OAAO,KAAK,SAAS;YACrB,OAAO,OAAO,KAAK,QAAQ,EAC3B,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,GAAI,OAAmC,CAAC,IAAI,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAe,EACf,QAA6B,EAC7B,QAAiB;IAEjB,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,QAAQ;YACX,OAAO,MAAM,KAAK,QAAQ,CAAC;QAE7B,KAAK,YAAY;YACf,OAAO,MAAM,KAAK,QAAQ,CAAC;QAE7B,KAAK,UAAU;YACb,OAAO,CACL,OAAO,MAAM,KAAK,QAAQ;gBAC1B,OAAO,QAAQ,KAAK,QAAQ;gBAC5B,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAC1B,CAAC;QAEJ,KAAK,aAAa;YAChB,OAAO,CACL,OAAO,MAAM,KAAK,QAAQ;gBAC1B,OAAO,QAAQ,KAAK,QAAQ;gBAC5B,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAC5B,CAAC;QAEJ,KAAK,WAAW;YACd,OAAO,CACL,OAAO,MAAM,KAAK,QAAQ;gBAC1B,OAAO,QAAQ,KAAK,QAAQ;gBAC5B,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAC1B,CAAC;QAEJ,KAAK,IAAI;YACP,OAAO,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAE9D,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAE/D,KAAK,cAAc;YACjB,OAAO,CACL,OAAO,MAAM,KAAK,QAAQ;gBAC1B,OAAO,QAAQ,KAAK,QAAQ;gBAC5B,MAAM,GAAG,QAAQ,CAClB,CAAC;QAEJ,KAAK,uBAAuB;YAC1B,OAAO,CACL,OAAO,MAAM,KAAK,QAAQ;gBAC1B,OAAO,QAAQ,KAAK,QAAQ;gBAC5B,MAAM,IAAI,QAAQ,CACnB,CAAC;QAEJ,KAAK,WAAW;YACd,OAAO,CACL,OAAO,MAAM,KAAK,QAAQ;gBAC1B,OAAO,QAAQ,KAAK,QAAQ;gBAC5B,MAAM,GAAG,QAAQ,CAClB,CAAC;QAEJ,KAAK,oBAAoB;YACvB,OAAO,CACL,OAAO,MAAM,KAAK,QAAQ;gBAC1B,OAAO,QAAQ,KAAK,QAAQ;gBAC5B,MAAM,IAAI,QAAQ,CACnB,CAAC;QAEJ,KAAK,QAAQ;YACX,OAAO,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI,CAAC;QAEjD,KAAK,SAAS;YACZ,OAAO,CACL,OAAO,MAAM,KAAK,QAAQ;gBAC1B,OAAO,QAAQ,KAAK,QAAQ;gBAC5B,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAClC,CAAC;QAEJ;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Rule evaluator for feature flags.
3
+ *
4
+ * Evaluates a single rule against an evaluation context.
5
+ *
6
+ * @module evaluator/evaluatorRule
7
+ */
8
+ import type { FeatureFlagRule } from "../featureFlagTypes/featureFlagRule/featureFlagRule.type.js";
9
+ import type { FeatureFlagContext } from "../featureFlagTypes/featureFlagContext.js";
10
+ import type { FeatureFlagValue } from "../featureFlagTypes/featureFlagRule/featureFlagValue.type.js";
11
+ /** Result of evaluating a single rule. */
12
+ export interface RuleEvaluationResult {
13
+ /** Whether the rule matched. */
14
+ readonly matched: boolean;
15
+ /** The value to return if matched. */
16
+ readonly value?: FeatureFlagValue;
17
+ /** The variant key if a variant rule matched. */
18
+ readonly variant?: string;
19
+ }
20
+ /**
21
+ * Evaluate a single feature flag rule against a context.
22
+ *
23
+ * @param rule - The rule to evaluate.
24
+ * @param context - The evaluation context.
25
+ * @param flagKey - The flag key (used for percentage bucketing).
26
+ * @returns The evaluation result.
27
+ */
28
+ export declare function evaluateRule(rule: FeatureFlagRule, context: FeatureFlagContext, flagKey: string): RuleEvaluationResult;
29
+ //# sourceMappingURL=evaluatorRule.core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluatorRule.core.d.ts","sourceRoot":"","sources":["../../src/evaluator/evaluatorRule.core.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6DAA6D,CAAC;AACnG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AACpF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8DAA8D,CAAC;AAIrG,0CAA0C;AAC1C,MAAM,WAAW,oBAAoB;IACnC,gCAAgC;IAChC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,sCAAsC;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IAClC,iDAAiD;IACjD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,MAAM,GACd,oBAAoB,CAkEtB"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Rule evaluator for feature flags.
3
+ *
4
+ * Evaluates a single rule against an evaluation context.
5
+ *
6
+ * @module evaluator/evaluatorRule
7
+ */
8
+ import { isInRollout } from "../rollout/rolloutBucketing.js";
9
+ import { matchAttribute, resolvePath } from "./evaluatorAttribute.js";
10
+ /**
11
+ * Evaluate a single feature flag rule against a context.
12
+ *
13
+ * @param rule - The rule to evaluate.
14
+ * @param context - The evaluation context.
15
+ * @param flagKey - The flag key (used for percentage bucketing).
16
+ * @returns The evaluation result.
17
+ */
18
+ export function evaluateRule(rule, context, flagKey) {
19
+ switch (rule.type) {
20
+ case "static":
21
+ return { matched: true, value: rule.value };
22
+ case "user": {
23
+ if (!context.userId)
24
+ return { matched: false };
25
+ const matched = rule.users.includes(context.userId);
26
+ return { matched, value: matched ? rule.value : undefined };
27
+ }
28
+ case "tenant": {
29
+ if (!context.tenantId)
30
+ return { matched: false };
31
+ const matched = rule.tenants.includes(context.tenantId);
32
+ return { matched, value: matched ? rule.value : undefined };
33
+ }
34
+ case "attribute": {
35
+ let actual = resolvePath(context, rule.attribute);
36
+ if (actual === undefined && context.attributes) {
37
+ actual = resolvePath(context.attributes, rule.attribute);
38
+ }
39
+ const matched = matchAttribute(actual, rule.operator, rule.value);
40
+ return { matched, value: matched ? true : undefined };
41
+ }
42
+ case "percentage": {
43
+ const subject = context.userId ?? context.tenantId ?? context.sessionId ?? "anonymous";
44
+ const matched = isInRollout(flagKey, subject, rule.percentage);
45
+ return { matched, value: matched ? rule.value : undefined };
46
+ }
47
+ case "schedule": {
48
+ const now = Date.now();
49
+ const start = new Date(rule.startAt).getTime();
50
+ const end = new Date(rule.endAt).getTime();
51
+ const matched = now >= start && now <= end;
52
+ return { matched, value: matched ? rule.value : undefined };
53
+ }
54
+ case "variant": {
55
+ const subject = context.userId ?? context.tenantId ?? context.sessionId ?? "anonymous";
56
+ const totalWeight = rule.variants.reduce((sum, v) => sum + v.weight, 0);
57
+ if (totalWeight <= 0)
58
+ return { matched: false };
59
+ const bucket = isInRollout(flagKey, subject, 100) ? 99 : 0;
60
+ let cumulative = 0;
61
+ for (const variant of rule.variants) {
62
+ cumulative += (variant.weight / totalWeight) * 100;
63
+ if (bucket < cumulative) {
64
+ return { matched: true, value: variant.key, variant: variant.key };
65
+ }
66
+ }
67
+ return { matched: false };
68
+ }
69
+ default:
70
+ return { matched: false };
71
+ }
72
+ }
73
+ //# sourceMappingURL=evaluatorRule.core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluatorRule.core.js","sourceRoot":"","sources":["../../src/evaluator/evaluatorRule.core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Feature flag evaluation engine.
3
+ *
4
+ * @module evaluator
5
+ */
6
+ export { resolvePath, matchAttribute } from "./evaluatorAttribute.js";
7
+ export { evaluateRule } from "./evaluatorRule.core.js";
8
+ export type { RuleEvaluationResult } from "./evaluatorRule.core.js";
9
+ export { evaluateFlag } from "./evaluator.core.js";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/evaluator/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,YAAY,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Feature flag evaluation engine.
3
+ *
4
+ * @module evaluator
5
+ */
6
+ export { resolvePath, matchAttribute } from "./evaluatorAttribute.js";
7
+ export { evaluateRule } from "./evaluatorRule.core.js";
8
+ export { evaluateFlag } from "./evaluator.core.js";
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/evaluator/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Base error class for feature flag errors.
3
+ *
4
+ * @module featureFlagErrors/featureFlagError.base
5
+ */
6
+ import { ApplicationError, ErrorCode } from "@zudojs/errors";
7
+ import type { ErrorCategory, ErrorSeverity, ErrorMetadata } from "@zudojs/errors";
8
+ /** Options for creating a feature flag error. */
9
+ export interface FeatureFlagErrorOptions {
10
+ readonly code?: ErrorCode;
11
+ readonly category?: ErrorCategory;
12
+ readonly severity?: ErrorSeverity;
13
+ readonly cause?: unknown;
14
+ readonly metadata?: ErrorMetadata;
15
+ readonly expose?: boolean;
16
+ }
17
+ /**
18
+ * Base class for all feature flag errors.
19
+ * Extends ApplicationError from @zudojs/errors.
20
+ */
21
+ export declare class FeatureFlagError extends ApplicationError {
22
+ constructor(message: string, options?: FeatureFlagErrorOptions);
23
+ }
24
+ //# sourceMappingURL=featureFlagError.base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"featureFlagError.base.d.ts","sourceRoot":"","sources":["../../src/featureFlagErrors/featureFlagError.base.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACd,MAAM,gBAAgB,CAAC;AAExB,iDAAiD;AACjD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,gBAAgB;IACpD,YAAmB,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,uBAA4B,EAUxE;CACF"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Base error class for feature flag errors.
3
+ *
4
+ * @module featureFlagErrors/featureFlagError.base
5
+ */
6
+ import { ApplicationError, ErrorCode } from "@zudojs/errors";
7
+ /**
8
+ * Base class for all feature flag errors.
9
+ * Extends ApplicationError from @zudojs/errors.
10
+ */
11
+ export class FeatureFlagError extends ApplicationError {
12
+ constructor(message, options = {}) {
13
+ super(message, {
14
+ code: options.code ?? ErrorCode.UNKNOWN,
15
+ category: options.category,
16
+ severity: options.severity,
17
+ cause: options.cause,
18
+ metadata: options.metadata,
19
+ expose: options.expose ?? false,
20
+ });
21
+ this.name = "FeatureFlagError";
22
+ }
23
+ }
24
+ //# sourceMappingURL=featureFlagError.base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"featureFlagError.base.js","sourceRoot":"","sources":["../../src/featureFlagErrors/featureFlagError.base.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAiB7D;;;GAGG;AACH,MAAM,OAAO,gBAAiB,SAAQ,gBAAgB;IACpD,YAAmB,OAAe,EAAE,OAAO,GAA4B,EAAE;QACvE,KAAK,CAAC,OAAO,EAAE;YACb,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC,OAAO;YACvC,QAAQ,EAAE,OAAO,CAAC,QAAqC;YACvD,QAAQ,EAAE,OAAO,CAAC,QAAqC;YACvD,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK;SAChC,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Specific feature flag error types.
3
+ *
4
+ * @module featureFlagErrors/featureFlagError.types
5
+ */
6
+ import { FeatureFlagError } from "./featureFlagError.base.js";
7
+ /** Thrown when a requested feature flag does not exist. */
8
+ export declare class FeatureFlagNotFoundError extends FeatureFlagError {
9
+ constructor(key: string);
10
+ }
11
+ /** Thrown when a feature flag provider fails. */
12
+ export declare class FeatureFlagProviderError extends FeatureFlagError {
13
+ constructor(message: string, options?: {
14
+ readonly cause?: unknown;
15
+ readonly provider?: string;
16
+ });
17
+ }
18
+ /** Thrown when flag evaluation encounters an error. */
19
+ export declare class FeatureFlagEvaluationError extends FeatureFlagError {
20
+ constructor(key: string, reason: string);
21
+ }
22
+ /** Thrown when a flag rule is invalid. */
23
+ export declare class FeatureFlagRuleError extends FeatureFlagError {
24
+ constructor(key: string, reason: string);
25
+ }
26
+ /** Thrown when flag dependencies form a cycle. */
27
+ export declare class FeatureFlagDependencyError extends FeatureFlagError {
28
+ constructor(chain: readonly string[]);
29
+ }
30
+ /** Thrown when flag configuration is invalid. */
31
+ export declare class FeatureFlagConfigurationError extends FeatureFlagError {
32
+ constructor(message: string);
33
+ }
34
+ /** Thrown when a flag value has an unexpected type. */
35
+ export declare class FeatureFlagTypeError extends FeatureFlagError {
36
+ constructor(key: string, expected: string, actual: string);
37
+ }
38
+ //# sourceMappingURL=featureFlagError.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"featureFlagError.types.d.ts","sourceRoot":"","sources":["../../src/featureFlagErrors/featureFlagError.types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAE9D,2DAA2D;AAC3D,qBAAa,wBAAyB,SAAQ,gBAAgB;IAC5D,YAAmB,GAAG,EAAE,MAAM,EAO7B;CACF;AAED,iDAAiD;AACjD,qBAAa,wBAAyB,SAAQ,gBAAgB;IAC5D,YACE,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,EAQnE;CACF;AAED,uDAAuD;AACvD,qBAAa,0BAA2B,SAAQ,gBAAgB;IAC9D,YAAmB,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAM7C;CACF;AAED,0CAA0C;AAC1C,qBAAa,oBAAqB,SAAQ,gBAAgB;IACxD,YAAmB,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAM7C;CACF;AAED,kDAAkD;AAClD,qBAAa,0BAA2B,SAAQ,gBAAgB;IAC9D,YAAmB,KAAK,EAAE,SAAS,MAAM,EAAE,EAM1C;CACF;AAED,iDAAiD;AACjD,qBAAa,6BAA8B,SAAQ,gBAAgB;IACjE,YAAmB,OAAO,EAAE,MAAM,EAKjC;CACF;AAED,uDAAuD;AACvD,qBAAa,oBAAqB,SAAQ,gBAAgB;IACxD,YAAmB,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAM/D;CACF"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Specific feature flag error types.
3
+ *
4
+ * @module featureFlagErrors/featureFlagError.types
5
+ */
6
+ import { ErrorCode } from "@zudojs/errors";
7
+ import { FeatureFlagError } from "./featureFlagError.base.js";
8
+ /** Thrown when a requested feature flag does not exist. */
9
+ export class FeatureFlagNotFoundError extends FeatureFlagError {
10
+ constructor(key) {
11
+ super(`Feature flag not found: "${key}".`, {
12
+ code: ErrorCode.FEATURE_FLAG_NOT_FOUND,
13
+ expose: true,
14
+ metadata: { key },
15
+ });
16
+ this.name = "FeatureFlagNotFoundError";
17
+ }
18
+ }
19
+ /** Thrown when a feature flag provider fails. */
20
+ export class FeatureFlagProviderError extends FeatureFlagError {
21
+ constructor(message, options) {
22
+ super(message, {
23
+ code: ErrorCode.FEATURE_FLAG_PROVIDER,
24
+ cause: options?.cause,
25
+ metadata: options?.provider ? { provider: options.provider } : undefined,
26
+ });
27
+ this.name = "FeatureFlagProviderError";
28
+ }
29
+ }
30
+ /** Thrown when flag evaluation encounters an error. */
31
+ export class FeatureFlagEvaluationError extends FeatureFlagError {
32
+ constructor(key, reason) {
33
+ super(`Evaluation failed for flag "${key}": ${reason}.`, {
34
+ code: ErrorCode.FEATURE_FLAG_EVALUATION,
35
+ metadata: { key, reason },
36
+ });
37
+ this.name = "FeatureFlagEvaluationError";
38
+ }
39
+ }
40
+ /** Thrown when a flag rule is invalid. */
41
+ export class FeatureFlagRuleError extends FeatureFlagError {
42
+ constructor(key, reason) {
43
+ super(`Invalid rule for flag "${key}": ${reason}.`, {
44
+ code: ErrorCode.FEATURE_FLAG_RULE,
45
+ metadata: { key, reason },
46
+ });
47
+ this.name = "FeatureFlagRuleError";
48
+ }
49
+ }
50
+ /** Thrown when flag dependencies form a cycle. */
51
+ export class FeatureFlagDependencyError extends FeatureFlagError {
52
+ constructor(chain) {
53
+ super(`Feature flag dependency cycle detected: ${chain.join(" → ")}.`, {
54
+ code: ErrorCode.FEATURE_FLAG_DEPENDENCY,
55
+ metadata: { chain },
56
+ });
57
+ this.name = "FeatureFlagDependencyError";
58
+ }
59
+ }
60
+ /** Thrown when flag configuration is invalid. */
61
+ export class FeatureFlagConfigurationError extends FeatureFlagError {
62
+ constructor(message) {
63
+ super(message, {
64
+ code: ErrorCode.FEATURE_FLAG_CONFIGURATION,
65
+ });
66
+ this.name = "FeatureFlagConfigurationError";
67
+ }
68
+ }
69
+ /** Thrown when a flag value has an unexpected type. */
70
+ export class FeatureFlagTypeError extends FeatureFlagError {
71
+ constructor(key, expected, actual) {
72
+ super(`Flag "${key}" expected ${expected} but got ${actual}.`, {
73
+ code: ErrorCode.FEATURE_FLAG_TYPE,
74
+ metadata: { key, expected, actual },
75
+ });
76
+ this.name = "FeatureFlagTypeError";
77
+ }
78
+ }
79
+ //# sourceMappingURL=featureFlagError.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"featureFlagError.types.js","sourceRoot":"","sources":["../../src/featureFlagErrors/featureFlagError.types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAE9D,2DAA2D;AAC3D,MAAM,OAAO,wBAAyB,SAAQ,gBAAgB;IAC5D,YAAmB,GAAW;QAC5B,KAAK,CAAC,4BAA4B,GAAG,IAAI,EAAE;YACzC,IAAI,EAAE,SAAS,CAAC,sBAAsB;YACtC,MAAM,EAAE,IAAI;YACZ,QAAQ,EAAE,EAAE,GAAG,EAAE;SAClB,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;IACzC,CAAC;CACF;AAED,iDAAiD;AACjD,MAAM,OAAO,wBAAyB,SAAQ,gBAAgB;IAC5D,YACE,OAAe,EACf,OAAkE;QAElE,KAAK,CAAC,OAAO,EAAE;YACb,IAAI,EAAE,SAAS,CAAC,qBAAqB;YACrC,KAAK,EAAE,OAAO,EAAE,KAAK;YACrB,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS;SACzE,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;IACzC,CAAC;CACF;AAED,uDAAuD;AACvD,MAAM,OAAO,0BAA2B,SAAQ,gBAAgB;IAC9D,YAAmB,GAAW,EAAE,MAAc;QAC5C,KAAK,CAAC,+BAA+B,GAAG,MAAM,MAAM,GAAG,EAAE;YACvD,IAAI,EAAE,SAAS,CAAC,uBAAuB;YACvC,QAAQ,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE;SAC1B,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;IAC3C,CAAC;CACF;AAED,0CAA0C;AAC1C,MAAM,OAAO,oBAAqB,SAAQ,gBAAgB;IACxD,YAAmB,GAAW,EAAE,MAAc;QAC5C,KAAK,CAAC,0BAA0B,GAAG,MAAM,MAAM,GAAG,EAAE;YAClD,IAAI,EAAE,SAAS,CAAC,iBAAiB;YACjC,QAAQ,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE;SAC1B,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED,kDAAkD;AAClD,MAAM,OAAO,0BAA2B,SAAQ,gBAAgB;IAC9D,YAAmB,KAAwB;QACzC,KAAK,CAAC,2CAA2C,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;YACrE,IAAI,EAAE,SAAS,CAAC,uBAAuB;YACvC,QAAQ,EAAE,EAAE,KAAK,EAAE;SACpB,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;IAC3C,CAAC;CACF;AAED,iDAAiD;AACjD,MAAM,OAAO,6BAA8B,SAAQ,gBAAgB;IACjE,YAAmB,OAAe;QAChC,KAAK,CAAC,OAAO,EAAE;YACb,IAAI,EAAE,SAAS,CAAC,0BAA0B;SAC3C,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,+BAA+B,CAAC;IAC9C,CAAC;CACF;AAED,uDAAuD;AACvD,MAAM,OAAO,oBAAqB,SAAQ,gBAAgB;IACxD,YAAmB,GAAW,EAAE,QAAgB,EAAE,MAAc;QAC9D,KAAK,CAAC,SAAS,GAAG,cAAc,QAAQ,YAAY,MAAM,GAAG,EAAE;YAC7D,IAAI,EAAE,SAAS,CAAC,iBAAiB;YACjC,QAAQ,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE;SACpC,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Feature flag error classes.
3
+ *
4
+ * @module featureFlagErrors
5
+ */
6
+ export { FeatureFlagError } from "./featureFlagError.base.js";
7
+ export type { FeatureFlagErrorOptions } from "./featureFlagError.base.js";
8
+ export { FeatureFlagNotFoundError, FeatureFlagProviderError, FeatureFlagEvaluationError, FeatureFlagRuleError, FeatureFlagDependencyError, FeatureFlagConfigurationError, FeatureFlagTypeError, } from "./featureFlagError.types.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/featureFlagErrors/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,YAAY,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAE1E,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,0BAA0B,EAC1B,oBAAoB,EACpB,0BAA0B,EAC1B,6BAA6B,EAC7B,oBAAoB,GACrB,MAAM,6BAA6B,CAAC"}