featuredrop 1.2.0 → 1.3.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 (84) hide show
  1. package/README.md +171 -0
  2. package/dist/admin.cjs +212 -0
  3. package/dist/admin.cjs.map +1 -0
  4. package/dist/admin.d.cts +176 -0
  5. package/dist/admin.d.ts +176 -0
  6. package/dist/admin.js +207 -0
  7. package/dist/admin.js.map +1 -0
  8. package/dist/angular.cjs +13 -3
  9. package/dist/angular.cjs.map +1 -1
  10. package/dist/angular.d.cts +4 -0
  11. package/dist/angular.d.ts +4 -0
  12. package/dist/angular.js +13 -3
  13. package/dist/angular.js.map +1 -1
  14. package/dist/bridges.cjs +401 -0
  15. package/dist/bridges.cjs.map +1 -0
  16. package/dist/bridges.d.cts +194 -0
  17. package/dist/bridges.d.ts +194 -0
  18. package/dist/bridges.js +394 -0
  19. package/dist/bridges.js.map +1 -0
  20. package/dist/ci.cjs +328 -0
  21. package/dist/ci.cjs.map +1 -0
  22. package/dist/ci.d.cts +176 -0
  23. package/dist/ci.d.ts +176 -0
  24. package/dist/ci.js +324 -0
  25. package/dist/ci.js.map +1 -0
  26. package/dist/featuredrop.cjs +139 -18
  27. package/dist/featuredrop.cjs.map +1 -1
  28. package/dist/flags.cjs +51 -0
  29. package/dist/flags.cjs.map +1 -0
  30. package/dist/flags.d.cts +48 -0
  31. package/dist/flags.d.ts +48 -0
  32. package/dist/flags.js +47 -0
  33. package/dist/flags.js.map +1 -0
  34. package/dist/index.cjs +2583 -665
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.d.cts +743 -206
  37. package/dist/index.d.ts +743 -206
  38. package/dist/index.js +2552 -666
  39. package/dist/index.js.map +1 -1
  40. package/dist/preact.cjs +710 -209
  41. package/dist/preact.cjs.map +1 -1
  42. package/dist/preact.d.cts +67 -120
  43. package/dist/preact.d.ts +67 -120
  44. package/dist/preact.js +696 -195
  45. package/dist/preact.js.map +1 -1
  46. package/dist/react.cjs +710 -209
  47. package/dist/react.cjs.map +1 -1
  48. package/dist/react.d.cts +67 -120
  49. package/dist/react.d.ts +67 -120
  50. package/dist/react.js +696 -195
  51. package/dist/react.js.map +1 -1
  52. package/dist/schema.cjs +78 -1
  53. package/dist/schema.cjs.map +1 -1
  54. package/dist/schema.d.cts +142 -0
  55. package/dist/schema.d.ts +142 -0
  56. package/dist/schema.js +78 -1
  57. package/dist/schema.js.map +1 -1
  58. package/dist/solid.cjs +13 -3
  59. package/dist/solid.cjs.map +1 -1
  60. package/dist/solid.d.cts +4 -0
  61. package/dist/solid.d.ts +4 -0
  62. package/dist/solid.js +13 -3
  63. package/dist/solid.js.map +1 -1
  64. package/dist/svelte.cjs +13 -3
  65. package/dist/svelte.cjs.map +1 -1
  66. package/dist/svelte.js +13 -3
  67. package/dist/svelte.js.map +1 -1
  68. package/dist/testing.cjs +136 -15
  69. package/dist/testing.cjs.map +1 -1
  70. package/dist/testing.d.cts +22 -0
  71. package/dist/testing.d.ts +22 -0
  72. package/dist/testing.js +136 -15
  73. package/dist/testing.js.map +1 -1
  74. package/dist/vue.cjs +13 -3
  75. package/dist/vue.cjs.map +1 -1
  76. package/dist/vue.js +13 -3
  77. package/dist/vue.js.map +1 -1
  78. package/dist/web-components.cjs +14 -4
  79. package/dist/web-components.cjs.map +1 -1
  80. package/dist/web-components.d.cts +4 -0
  81. package/dist/web-components.d.ts +4 -0
  82. package/dist/web-components.js +14 -4
  83. package/dist/web-components.js.map +1 -1
  84. package/package.json +59 -1
package/dist/flags.cjs ADDED
@@ -0,0 +1,51 @@
1
+ 'use strict';
2
+
3
+ // src/flags.ts
4
+ function createFlagBridge(options) {
5
+ return {
6
+ isEnabled: (flagKey, userContext) => {
7
+ if (!flagKey) return false;
8
+ return options.isEnabled(flagKey, userContext);
9
+ }
10
+ };
11
+ }
12
+ var LaunchDarklyBridge = class {
13
+ client;
14
+ options;
15
+ constructor(client, options = {}) {
16
+ this.client = client;
17
+ this.options = options;
18
+ }
19
+ isEnabled(flagKey, userContext) {
20
+ const defaultUser = {
21
+ key: userContext?.traits?.id ?? userContext?.role ?? "anonymous",
22
+ custom: {
23
+ plan: userContext?.plan,
24
+ role: userContext?.role,
25
+ region: userContext?.region,
26
+ ...userContext?.traits ?? {}
27
+ }
28
+ };
29
+ const user = this.options.userResolver ? this.options.userResolver(userContext) : defaultUser;
30
+ return this.client.variation(flagKey, user, this.options.defaultValue ?? false);
31
+ }
32
+ };
33
+ var PostHogBridge = class {
34
+ client;
35
+ options;
36
+ constructor(client, options = {}) {
37
+ this.client = client;
38
+ this.options = options;
39
+ }
40
+ isEnabled(flagKey, userContext) {
41
+ const distinctId = this.options.distinctIdResolver ? this.options.distinctIdResolver(userContext) : typeof userContext?.traits?.id === "string" ? userContext.traits.id : void 0;
42
+ const groups = this.options.groupsResolver ? this.options.groupsResolver(userContext) : void 0;
43
+ return this.client.isFeatureEnabled(flagKey, distinctId, groups, userContext?.traits);
44
+ }
45
+ };
46
+
47
+ exports.LaunchDarklyBridge = LaunchDarklyBridge;
48
+ exports.PostHogBridge = PostHogBridge;
49
+ exports.createFlagBridge = createFlagBridge;
50
+ //# sourceMappingURL=flags.cjs.map
51
+ //# sourceMappingURL=flags.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/flags.ts"],"names":[],"mappings":";;;AAMO,SAAS,iBAAiB,OAAA,EAAqD;AACpF,EAAA,OAAO;AAAA,IACL,SAAA,EAAW,CAAC,OAAA,EAAiB,WAAA,KAA8B;AACzD,MAAA,IAAI,CAAC,SAAS,OAAO,KAAA;AACrB,MAAA,OAAO,OAAA,CAAQ,SAAA,CAAU,OAAA,EAAS,WAAW,CAAA;AAAA,IAC/C;AAAA,GACF;AACF;AAWO,IAAM,qBAAN,MAAsD;AAAA,EAC1C,MAAA;AAAA,EACA,OAAA;AAAA,EAEjB,WAAA,CAAY,MAAA,EAAgC,OAAA,GAAqC,EAAC,EAAG;AACnF,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AAAA,EAEA,SAAA,CAAU,SAAiB,WAAA,EAAoC;AAC7D,IAAA,MAAM,WAAA,GAAc;AAAA,MAClB,GAAA,EAAK,WAAA,EAAa,MAAA,EAAQ,EAAA,IAAM,aAAa,IAAA,IAAQ,WAAA;AAAA,MACrD,MAAA,EAAQ;AAAA,QACN,MAAM,WAAA,EAAa,IAAA;AAAA,QACnB,MAAM,WAAA,EAAa,IAAA;AAAA,QACnB,QAAQ,WAAA,EAAa,MAAA;AAAA,QACrB,GAAI,WAAA,EAAa,MAAA,IAAU;AAAC;AAC9B,KACF;AACA,IAAA,MAAM,IAAA,GAAO,KAAK,OAAA,CAAQ,YAAA,GAAe,KAAK,OAAA,CAAQ,YAAA,CAAa,WAAW,CAAA,GAAI,WAAA;AAClF,IAAA,OAAO,IAAA,CAAK,OAAO,SAAA,CAAU,OAAA,EAAS,MAAM,IAAA,CAAK,OAAA,CAAQ,gBAAgB,KAAK,CAAA;AAAA,EAChF;AACF;AAgBO,IAAM,gBAAN,MAAiD;AAAA,EACrC,MAAA;AAAA,EACA,OAAA;AAAA,EAEjB,WAAA,CAAY,MAAA,EAA2B,OAAA,GAAgC,EAAC,EAAG;AACzE,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AAAA,EAEA,SAAA,CAAU,SAAiB,WAAA,EAAoC;AAC7D,IAAA,MAAM,aAAa,IAAA,CAAK,OAAA,CAAQ,kBAAA,GAC5B,IAAA,CAAK,QAAQ,kBAAA,CAAmB,WAAW,CAAA,GAC1C,OAAO,aAAa,MAAA,EAAQ,EAAA,KAAO,QAAA,GAAW,WAAA,CAAY,OAAO,EAAA,GAAK,MAAA;AAC3E,IAAA,MAAM,MAAA,GAAS,KAAK,OAAA,CAAQ,cAAA,GACxB,KAAK,OAAA,CAAQ,cAAA,CAAe,WAAW,CAAA,GACvC,MAAA;AACJ,IAAA,OAAO,KAAK,MAAA,CAAO,gBAAA,CAAiB,SAAS,UAAA,EAAY,MAAA,EAAQ,aAAa,MAAM,CAAA;AAAA,EACtF;AACF","file":"flags.cjs","sourcesContent":["import type { FeatureFlagBridge, UserContext } from \"./types\";\n\nexport interface CreateFlagBridgeOptions {\n isEnabled: (flagKey: string, userContext?: UserContext) => boolean;\n}\n\nexport function createFlagBridge(options: CreateFlagBridgeOptions): FeatureFlagBridge {\n return {\n isEnabled: (flagKey: string, userContext?: UserContext) => {\n if (!flagKey) return false;\n return options.isEnabled(flagKey, userContext);\n },\n };\n}\n\nexport interface LaunchDarklyClientLike {\n variation: (flagKey: string, user: Record<string, unknown>, defaultValue: boolean) => boolean;\n}\n\nexport interface LaunchDarklyBridgeOptions {\n userResolver?: (userContext?: UserContext) => Record<string, unknown>;\n defaultValue?: boolean;\n}\n\nexport class LaunchDarklyBridge implements FeatureFlagBridge {\n private readonly client: LaunchDarklyClientLike;\n private readonly options: LaunchDarklyBridgeOptions;\n\n constructor(client: LaunchDarklyClientLike, options: LaunchDarklyBridgeOptions = {}) {\n this.client = client;\n this.options = options;\n }\n\n isEnabled(flagKey: string, userContext?: UserContext): boolean {\n const defaultUser = {\n key: userContext?.traits?.id ?? userContext?.role ?? \"anonymous\",\n custom: {\n plan: userContext?.plan,\n role: userContext?.role,\n region: userContext?.region,\n ...(userContext?.traits ?? {}),\n },\n };\n const user = this.options.userResolver ? this.options.userResolver(userContext) : defaultUser;\n return this.client.variation(flagKey, user, this.options.defaultValue ?? false);\n }\n}\n\nexport interface PostHogClientLike {\n isFeatureEnabled: (\n flagKey: string,\n distinctId?: string,\n groups?: Record<string, string>,\n personProperties?: Record<string, unknown>,\n ) => boolean;\n}\n\nexport interface PostHogBridgeOptions {\n distinctIdResolver?: (userContext?: UserContext) => string | undefined;\n groupsResolver?: (userContext?: UserContext) => Record<string, string> | undefined;\n}\n\nexport class PostHogBridge implements FeatureFlagBridge {\n private readonly client: PostHogClientLike;\n private readonly options: PostHogBridgeOptions;\n\n constructor(client: PostHogClientLike, options: PostHogBridgeOptions = {}) {\n this.client = client;\n this.options = options;\n }\n\n isEnabled(flagKey: string, userContext?: UserContext): boolean {\n const distinctId = this.options.distinctIdResolver\n ? this.options.distinctIdResolver(userContext)\n : (typeof userContext?.traits?.id === \"string\" ? userContext.traits.id : undefined);\n const groups = this.options.groupsResolver\n ? this.options.groupsResolver(userContext)\n : undefined;\n return this.client.isFeatureEnabled(flagKey, distinctId, groups, userContext?.traits);\n }\n}\n"]}
@@ -0,0 +1,48 @@
1
+ /** User context for audience targeting */
2
+ interface UserContext {
3
+ /** Current user's plan (e.g. "pro", "free") */
4
+ plan?: string;
5
+ /** Current user's role (e.g. "admin", "viewer") */
6
+ role?: string;
7
+ /** Current user's region (e.g. "us", "eu") */
8
+ region?: string;
9
+ /** Arbitrary traits for custom matching logic */
10
+ traits?: Record<string, unknown>;
11
+ }
12
+ /** Feature flag resolver interface for gating announcement visibility */
13
+ interface FeatureFlagBridge {
14
+ isEnabled: (flagKey: string, userContext?: UserContext) => boolean;
15
+ }
16
+
17
+ interface CreateFlagBridgeOptions {
18
+ isEnabled: (flagKey: string, userContext?: UserContext) => boolean;
19
+ }
20
+ declare function createFlagBridge(options: CreateFlagBridgeOptions): FeatureFlagBridge;
21
+ interface LaunchDarklyClientLike {
22
+ variation: (flagKey: string, user: Record<string, unknown>, defaultValue: boolean) => boolean;
23
+ }
24
+ interface LaunchDarklyBridgeOptions {
25
+ userResolver?: (userContext?: UserContext) => Record<string, unknown>;
26
+ defaultValue?: boolean;
27
+ }
28
+ declare class LaunchDarklyBridge implements FeatureFlagBridge {
29
+ private readonly client;
30
+ private readonly options;
31
+ constructor(client: LaunchDarklyClientLike, options?: LaunchDarklyBridgeOptions);
32
+ isEnabled(flagKey: string, userContext?: UserContext): boolean;
33
+ }
34
+ interface PostHogClientLike {
35
+ isFeatureEnabled: (flagKey: string, distinctId?: string, groups?: Record<string, string>, personProperties?: Record<string, unknown>) => boolean;
36
+ }
37
+ interface PostHogBridgeOptions {
38
+ distinctIdResolver?: (userContext?: UserContext) => string | undefined;
39
+ groupsResolver?: (userContext?: UserContext) => Record<string, string> | undefined;
40
+ }
41
+ declare class PostHogBridge implements FeatureFlagBridge {
42
+ private readonly client;
43
+ private readonly options;
44
+ constructor(client: PostHogClientLike, options?: PostHogBridgeOptions);
45
+ isEnabled(flagKey: string, userContext?: UserContext): boolean;
46
+ }
47
+
48
+ export { type CreateFlagBridgeOptions, LaunchDarklyBridge, type LaunchDarklyBridgeOptions, type LaunchDarklyClientLike, PostHogBridge, type PostHogBridgeOptions, type PostHogClientLike, createFlagBridge };
@@ -0,0 +1,48 @@
1
+ /** User context for audience targeting */
2
+ interface UserContext {
3
+ /** Current user's plan (e.g. "pro", "free") */
4
+ plan?: string;
5
+ /** Current user's role (e.g. "admin", "viewer") */
6
+ role?: string;
7
+ /** Current user's region (e.g. "us", "eu") */
8
+ region?: string;
9
+ /** Arbitrary traits for custom matching logic */
10
+ traits?: Record<string, unknown>;
11
+ }
12
+ /** Feature flag resolver interface for gating announcement visibility */
13
+ interface FeatureFlagBridge {
14
+ isEnabled: (flagKey: string, userContext?: UserContext) => boolean;
15
+ }
16
+
17
+ interface CreateFlagBridgeOptions {
18
+ isEnabled: (flagKey: string, userContext?: UserContext) => boolean;
19
+ }
20
+ declare function createFlagBridge(options: CreateFlagBridgeOptions): FeatureFlagBridge;
21
+ interface LaunchDarklyClientLike {
22
+ variation: (flagKey: string, user: Record<string, unknown>, defaultValue: boolean) => boolean;
23
+ }
24
+ interface LaunchDarklyBridgeOptions {
25
+ userResolver?: (userContext?: UserContext) => Record<string, unknown>;
26
+ defaultValue?: boolean;
27
+ }
28
+ declare class LaunchDarklyBridge implements FeatureFlagBridge {
29
+ private readonly client;
30
+ private readonly options;
31
+ constructor(client: LaunchDarklyClientLike, options?: LaunchDarklyBridgeOptions);
32
+ isEnabled(flagKey: string, userContext?: UserContext): boolean;
33
+ }
34
+ interface PostHogClientLike {
35
+ isFeatureEnabled: (flagKey: string, distinctId?: string, groups?: Record<string, string>, personProperties?: Record<string, unknown>) => boolean;
36
+ }
37
+ interface PostHogBridgeOptions {
38
+ distinctIdResolver?: (userContext?: UserContext) => string | undefined;
39
+ groupsResolver?: (userContext?: UserContext) => Record<string, string> | undefined;
40
+ }
41
+ declare class PostHogBridge implements FeatureFlagBridge {
42
+ private readonly client;
43
+ private readonly options;
44
+ constructor(client: PostHogClientLike, options?: PostHogBridgeOptions);
45
+ isEnabled(flagKey: string, userContext?: UserContext): boolean;
46
+ }
47
+
48
+ export { type CreateFlagBridgeOptions, LaunchDarklyBridge, type LaunchDarklyBridgeOptions, type LaunchDarklyClientLike, PostHogBridge, type PostHogBridgeOptions, type PostHogClientLike, createFlagBridge };
package/dist/flags.js ADDED
@@ -0,0 +1,47 @@
1
+ // src/flags.ts
2
+ function createFlagBridge(options) {
3
+ return {
4
+ isEnabled: (flagKey, userContext) => {
5
+ if (!flagKey) return false;
6
+ return options.isEnabled(flagKey, userContext);
7
+ }
8
+ };
9
+ }
10
+ var LaunchDarklyBridge = class {
11
+ client;
12
+ options;
13
+ constructor(client, options = {}) {
14
+ this.client = client;
15
+ this.options = options;
16
+ }
17
+ isEnabled(flagKey, userContext) {
18
+ const defaultUser = {
19
+ key: userContext?.traits?.id ?? userContext?.role ?? "anonymous",
20
+ custom: {
21
+ plan: userContext?.plan,
22
+ role: userContext?.role,
23
+ region: userContext?.region,
24
+ ...userContext?.traits ?? {}
25
+ }
26
+ };
27
+ const user = this.options.userResolver ? this.options.userResolver(userContext) : defaultUser;
28
+ return this.client.variation(flagKey, user, this.options.defaultValue ?? false);
29
+ }
30
+ };
31
+ var PostHogBridge = class {
32
+ client;
33
+ options;
34
+ constructor(client, options = {}) {
35
+ this.client = client;
36
+ this.options = options;
37
+ }
38
+ isEnabled(flagKey, userContext) {
39
+ const distinctId = this.options.distinctIdResolver ? this.options.distinctIdResolver(userContext) : typeof userContext?.traits?.id === "string" ? userContext.traits.id : void 0;
40
+ const groups = this.options.groupsResolver ? this.options.groupsResolver(userContext) : void 0;
41
+ return this.client.isFeatureEnabled(flagKey, distinctId, groups, userContext?.traits);
42
+ }
43
+ };
44
+
45
+ export { LaunchDarklyBridge, PostHogBridge, createFlagBridge };
46
+ //# sourceMappingURL=flags.js.map
47
+ //# sourceMappingURL=flags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/flags.ts"],"names":[],"mappings":";AAMO,SAAS,iBAAiB,OAAA,EAAqD;AACpF,EAAA,OAAO;AAAA,IACL,SAAA,EAAW,CAAC,OAAA,EAAiB,WAAA,KAA8B;AACzD,MAAA,IAAI,CAAC,SAAS,OAAO,KAAA;AACrB,MAAA,OAAO,OAAA,CAAQ,SAAA,CAAU,OAAA,EAAS,WAAW,CAAA;AAAA,IAC/C;AAAA,GACF;AACF;AAWO,IAAM,qBAAN,MAAsD;AAAA,EAC1C,MAAA;AAAA,EACA,OAAA;AAAA,EAEjB,WAAA,CAAY,MAAA,EAAgC,OAAA,GAAqC,EAAC,EAAG;AACnF,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AAAA,EAEA,SAAA,CAAU,SAAiB,WAAA,EAAoC;AAC7D,IAAA,MAAM,WAAA,GAAc;AAAA,MAClB,GAAA,EAAK,WAAA,EAAa,MAAA,EAAQ,EAAA,IAAM,aAAa,IAAA,IAAQ,WAAA;AAAA,MACrD,MAAA,EAAQ;AAAA,QACN,MAAM,WAAA,EAAa,IAAA;AAAA,QACnB,MAAM,WAAA,EAAa,IAAA;AAAA,QACnB,QAAQ,WAAA,EAAa,MAAA;AAAA,QACrB,GAAI,WAAA,EAAa,MAAA,IAAU;AAAC;AAC9B,KACF;AACA,IAAA,MAAM,IAAA,GAAO,KAAK,OAAA,CAAQ,YAAA,GAAe,KAAK,OAAA,CAAQ,YAAA,CAAa,WAAW,CAAA,GAAI,WAAA;AAClF,IAAA,OAAO,IAAA,CAAK,OAAO,SAAA,CAAU,OAAA,EAAS,MAAM,IAAA,CAAK,OAAA,CAAQ,gBAAgB,KAAK,CAAA;AAAA,EAChF;AACF;AAgBO,IAAM,gBAAN,MAAiD;AAAA,EACrC,MAAA;AAAA,EACA,OAAA;AAAA,EAEjB,WAAA,CAAY,MAAA,EAA2B,OAAA,GAAgC,EAAC,EAAG;AACzE,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AAAA,EAEA,SAAA,CAAU,SAAiB,WAAA,EAAoC;AAC7D,IAAA,MAAM,aAAa,IAAA,CAAK,OAAA,CAAQ,kBAAA,GAC5B,IAAA,CAAK,QAAQ,kBAAA,CAAmB,WAAW,CAAA,GAC1C,OAAO,aAAa,MAAA,EAAQ,EAAA,KAAO,QAAA,GAAW,WAAA,CAAY,OAAO,EAAA,GAAK,MAAA;AAC3E,IAAA,MAAM,MAAA,GAAS,KAAK,OAAA,CAAQ,cAAA,GACxB,KAAK,OAAA,CAAQ,cAAA,CAAe,WAAW,CAAA,GACvC,MAAA;AACJ,IAAA,OAAO,KAAK,MAAA,CAAO,gBAAA,CAAiB,SAAS,UAAA,EAAY,MAAA,EAAQ,aAAa,MAAM,CAAA;AAAA,EACtF;AACF","file":"flags.js","sourcesContent":["import type { FeatureFlagBridge, UserContext } from \"./types\";\n\nexport interface CreateFlagBridgeOptions {\n isEnabled: (flagKey: string, userContext?: UserContext) => boolean;\n}\n\nexport function createFlagBridge(options: CreateFlagBridgeOptions): FeatureFlagBridge {\n return {\n isEnabled: (flagKey: string, userContext?: UserContext) => {\n if (!flagKey) return false;\n return options.isEnabled(flagKey, userContext);\n },\n };\n}\n\nexport interface LaunchDarklyClientLike {\n variation: (flagKey: string, user: Record<string, unknown>, defaultValue: boolean) => boolean;\n}\n\nexport interface LaunchDarklyBridgeOptions {\n userResolver?: (userContext?: UserContext) => Record<string, unknown>;\n defaultValue?: boolean;\n}\n\nexport class LaunchDarklyBridge implements FeatureFlagBridge {\n private readonly client: LaunchDarklyClientLike;\n private readonly options: LaunchDarklyBridgeOptions;\n\n constructor(client: LaunchDarklyClientLike, options: LaunchDarklyBridgeOptions = {}) {\n this.client = client;\n this.options = options;\n }\n\n isEnabled(flagKey: string, userContext?: UserContext): boolean {\n const defaultUser = {\n key: userContext?.traits?.id ?? userContext?.role ?? \"anonymous\",\n custom: {\n plan: userContext?.plan,\n role: userContext?.role,\n region: userContext?.region,\n ...(userContext?.traits ?? {}),\n },\n };\n const user = this.options.userResolver ? this.options.userResolver(userContext) : defaultUser;\n return this.client.variation(flagKey, user, this.options.defaultValue ?? false);\n }\n}\n\nexport interface PostHogClientLike {\n isFeatureEnabled: (\n flagKey: string,\n distinctId?: string,\n groups?: Record<string, string>,\n personProperties?: Record<string, unknown>,\n ) => boolean;\n}\n\nexport interface PostHogBridgeOptions {\n distinctIdResolver?: (userContext?: UserContext) => string | undefined;\n groupsResolver?: (userContext?: UserContext) => Record<string, string> | undefined;\n}\n\nexport class PostHogBridge implements FeatureFlagBridge {\n private readonly client: PostHogClientLike;\n private readonly options: PostHogBridgeOptions;\n\n constructor(client: PostHogClientLike, options: PostHogBridgeOptions = {}) {\n this.client = client;\n this.options = options;\n }\n\n isEnabled(flagKey: string, userContext?: UserContext): boolean {\n const distinctId = this.options.distinctIdResolver\n ? this.options.distinctIdResolver(userContext)\n : (typeof userContext?.traits?.id === \"string\" ? userContext.traits.id : undefined);\n const groups = this.options.groupsResolver\n ? this.options.groupsResolver(userContext)\n : undefined;\n return this.client.isFeatureEnabled(flagKey, distinctId, groups, userContext?.traits);\n }\n}\n"]}