@bluealba/pae-feature-flags 1.0.0-feature-initial-feature-flags-poc-1233

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 +239 -0
  2. package/dist/core/index.d.ts +5 -0
  3. package/dist/core/index.d.ts.map +1 -0
  4. package/dist/core/index.js +21 -0
  5. package/dist/core/index.js.map +1 -0
  6. package/dist/core/types.d.ts +63 -0
  7. package/dist/core/types.d.ts.map +1 -0
  8. package/dist/core/types.js +16 -0
  9. package/dist/core/types.js.map +1 -0
  10. package/dist/index.d.ts +54 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +73 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/nestjs/FeatureFlagsClient.d.ts +99 -0
  15. package/dist/nestjs/FeatureFlagsClient.d.ts.map +1 -0
  16. package/dist/nestjs/FeatureFlagsClient.js +173 -0
  17. package/dist/nestjs/FeatureFlagsClient.js.map +1 -0
  18. package/dist/nestjs/FeatureFlagsModule.d.ts +79 -0
  19. package/dist/nestjs/FeatureFlagsModule.d.ts.map +1 -0
  20. package/dist/nestjs/FeatureFlagsModule.js +98 -0
  21. package/dist/nestjs/FeatureFlagsModule.js.map +1 -0
  22. package/dist/nestjs/index.d.ts +20 -0
  23. package/dist/nestjs/index.d.ts.map +1 -0
  24. package/dist/nestjs/index.js +36 -0
  25. package/dist/nestjs/index.js.map +1 -0
  26. package/dist/react/FeatureFlagGuard.d.ts +60 -0
  27. package/dist/react/FeatureFlagGuard.d.ts.map +1 -0
  28. package/dist/react/FeatureFlagGuard.js +48 -0
  29. package/dist/react/FeatureFlagGuard.js.map +1 -0
  30. package/dist/react/FeatureFlagsProvider.d.ts +102 -0
  31. package/dist/react/FeatureFlagsProvider.d.ts.map +1 -0
  32. package/dist/react/FeatureFlagsProvider.js +194 -0
  33. package/dist/react/FeatureFlagsProvider.js.map +1 -0
  34. package/dist/react/index.d.ts +10 -0
  35. package/dist/react/index.d.ts.map +1 -0
  36. package/dist/react/index.js +19 -0
  37. package/dist/react/index.js.map +1 -0
  38. package/dist/react/useFeatureFlag.d.ts +26 -0
  39. package/dist/react/useFeatureFlag.d.ts.map +1 -0
  40. package/dist/react/useFeatureFlag.js +91 -0
  41. package/dist/react/useFeatureFlag.js.map +1 -0
  42. package/dist/react/useFeatureFlags.d.ts +38 -0
  43. package/dist/react/useFeatureFlags.d.ts.map +1 -0
  44. package/dist/react/useFeatureFlags.js +49 -0
  45. package/dist/react/useFeatureFlags.js.map +1 -0
  46. package/dist/react/useVariant.d.ts +48 -0
  47. package/dist/react/useVariant.d.ts.map +1 -0
  48. package/dist/react/useVariant.js +108 -0
  49. package/dist/react/useVariant.js.map +1 -0
  50. package/package.json +43 -0
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var FeatureFlagsClient_1;
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.FeatureFlagsClient = void 0;
17
+ const common_1 = require("@nestjs/common");
18
+ const axios_1 = require("@nestjs/axios");
19
+ const rxjs_1 = require("rxjs");
20
+ /**
21
+ * Client for consuming feature flags from the gateway service
22
+ *
23
+ * This service provides methods to evaluate feature flags by calling
24
+ * the gateway API endpoints. It handles errors gracefully by returning
25
+ * default values when the API is unavailable or returns errors.
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * @Injectable()
30
+ * export class MyService {
31
+ * constructor(private readonly featureFlagsClient: FeatureFlagsClient) {}
32
+ *
33
+ * async doSomething() {
34
+ * const isEnabled = await this.featureFlagsClient.isEnabled('my-feature');
35
+ * if (isEnabled) {
36
+ * // New implementation
37
+ * }
38
+ * }
39
+ * }
40
+ * ```
41
+ */
42
+ let FeatureFlagsClient = FeatureFlagsClient_1 = class FeatureFlagsClient {
43
+ constructor(gatewayUrl, httpService) {
44
+ this.gatewayUrl = gatewayUrl;
45
+ this.httpService = httpService;
46
+ this.logger = new common_1.Logger(FeatureFlagsClient_1.name);
47
+ }
48
+ /**
49
+ * Evaluates if a feature flag is enabled
50
+ *
51
+ * @param flagName - The name of the feature flag to evaluate
52
+ * @param defaultValue - The default value to return if evaluation fails (default: false)
53
+ * @param context - Optional evaluation context (user, tenant, custom properties)
54
+ * @returns Promise resolving to true if flag is enabled, false otherwise
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * const isEnabled = await client.isEnabled('new-dashboard', false, {
59
+ * userId: '123',
60
+ * tenantId: 'tenant-1'
61
+ * });
62
+ * ```
63
+ */
64
+ async isEnabled(flagName, defaultValue = false, context) {
65
+ try {
66
+ const url = `${this.gatewayUrl}/feature-flags/${flagName}`;
67
+ const response = await (0, rxjs_1.firstValueFrom)(this.httpService.get(url, {
68
+ params: context ? { context: JSON.stringify(context) } : undefined,
69
+ }));
70
+ return response.data.enabled;
71
+ }
72
+ catch (error) {
73
+ const errorMessage = error instanceof Error ? error.message : String(error);
74
+ this.logger.error(`Failed to evaluate flag "${flagName}": ${errorMessage}. Returning default value: ${defaultValue}`);
75
+ return defaultValue;
76
+ }
77
+ }
78
+ /**
79
+ * Gets the variant for a multivariant feature flag
80
+ *
81
+ * @param flagName - The name of the feature flag
82
+ * @param context - Optional evaluation context
83
+ * @returns Promise resolving to variant object with name and payload, or null if no variant
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * const variant = await client.getVariant('ab-test', {
88
+ * userId: '123'
89
+ * });
90
+ *
91
+ * if (variant?.name === 'variant-a') {
92
+ * // Variant A logic
93
+ * } else if (variant?.name === 'variant-b') {
94
+ * // Variant B logic
95
+ * }
96
+ * ```
97
+ */
98
+ async getVariant(flagName, context) {
99
+ try {
100
+ const url = `${this.gatewayUrl}/feature-flags/${flagName}/variant`;
101
+ const response = await (0, rxjs_1.firstValueFrom)(this.httpService.get(url, {
102
+ params: context ? { context: JSON.stringify(context) } : undefined,
103
+ }));
104
+ if (response.data.variant) {
105
+ return {
106
+ name: response.data.variant,
107
+ payload: response.data.payload,
108
+ };
109
+ }
110
+ return null;
111
+ }
112
+ catch (error) {
113
+ const errorMessage = error instanceof Error ? error.message : String(error);
114
+ this.logger.error(`Failed to get variant for flag "${flagName}": ${errorMessage}. Returning null`);
115
+ return null;
116
+ }
117
+ }
118
+ /**
119
+ * Evaluates multiple feature flags in a single request
120
+ *
121
+ * This method is more efficient than calling isEnabled multiple times
122
+ * as it reduces the number of HTTP requests.
123
+ *
124
+ * @param flagNames - Array of feature flag names to evaluate
125
+ * @param context - Optional evaluation context
126
+ * @returns Promise resolving to a Map of flag names to evaluation results
127
+ *
128
+ * @example
129
+ * ```typescript
130
+ * const results = await client.evaluateFlags(
131
+ * ['feature-a', 'feature-b', 'ab-test'],
132
+ * { userId: '123', tenantId: 'tenant-1' }
133
+ * );
134
+ *
135
+ * const featureAEnabled = results.get('feature-a')?.enabled ?? false;
136
+ * const abTestVariant = results.get('ab-test')?.variant;
137
+ * ```
138
+ */
139
+ async evaluateFlags(flagNames, context) {
140
+ try {
141
+ const url = `${this.gatewayUrl}/feature-flags/evaluate`;
142
+ const response = await (0, rxjs_1.firstValueFrom)(this.httpService.post(url, {
143
+ flagNames,
144
+ context,
145
+ }));
146
+ // Convert the response object to a Map
147
+ const resultMap = new Map();
148
+ Object.entries(response.data.flags).forEach(([name, result]) => {
149
+ resultMap.set(name, result);
150
+ });
151
+ return resultMap;
152
+ }
153
+ catch (error) {
154
+ const errorMessage = error instanceof Error ? error.message : String(error);
155
+ this.logger.error(`Failed to evaluate flags in bulk: ${errorMessage}. Returning empty map`);
156
+ return new Map();
157
+ }
158
+ }
159
+ /**
160
+ * Gets the configured gateway URL
161
+ * Useful for debugging and logging purposes
162
+ */
163
+ getGatewayUrl() {
164
+ return this.gatewayUrl;
165
+ }
166
+ };
167
+ exports.FeatureFlagsClient = FeatureFlagsClient;
168
+ exports.FeatureFlagsClient = FeatureFlagsClient = FeatureFlagsClient_1 = __decorate([
169
+ (0, common_1.Injectable)(),
170
+ __param(0, (0, common_1.Inject)('GATEWAY_URL')),
171
+ __metadata("design:paramtypes", [String, axios_1.HttpService])
172
+ ], FeatureFlagsClient);
173
+ //# sourceMappingURL=FeatureFlagsClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FeatureFlagsClient.js","sourceRoot":"","sources":["../../src/nestjs/FeatureFlagsClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ import { DynamicModule } from '@nestjs/common';
2
+ /**
3
+ * Configuration options for the FeatureFlagsModule
4
+ */
5
+ export interface FeatureFlagsModuleConfig {
6
+ /**
7
+ * The base URL of the gateway service
8
+ * @example 'http://localhost:3000' or 'https://gateway.example.com'
9
+ */
10
+ gatewayUrl: string;
11
+ /**
12
+ * Optional timeout in milliseconds for HTTP requests
13
+ * @default 5000
14
+ */
15
+ timeout?: number;
16
+ /**
17
+ * Optional maximum number of redirects to follow
18
+ * @default 5
19
+ */
20
+ maxRedirects?: number;
21
+ }
22
+ /**
23
+ * NestJS module for feature flags client
24
+ *
25
+ * This module provides the FeatureFlagsClient service to consume
26
+ * feature flags from the gateway service.
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * @Module({
31
+ * imports: [
32
+ * FeatureFlagsModule.forRoot({
33
+ * gatewayUrl: 'http://localhost:3000',
34
+ * timeout: 5000
35
+ * }),
36
+ * ],
37
+ * providers: [MyService],
38
+ * })
39
+ * export class MyServiceModule {}
40
+ * ```
41
+ */
42
+ export declare class FeatureFlagsModule {
43
+ /**
44
+ * Register the FeatureFlagsModule with configuration
45
+ *
46
+ * Supports two call signatures:
47
+ * - `forRoot(gatewayUrl: string)` - Simple URL configuration
48
+ * - `forRoot(config: FeatureFlagsModuleConfig)` - Full configuration object
49
+ *
50
+ * @param configOrUrl - Either a gateway URL string or full configuration object
51
+ * @returns A configured DynamicModule
52
+ *
53
+ * @example Simple usage with URL
54
+ * ```typescript
55
+ * @Module({
56
+ * imports: [
57
+ * FeatureFlagsModule.forRoot('http://localhost:3000'),
58
+ * ],
59
+ * })
60
+ * export class MyModule {}
61
+ * ```
62
+ *
63
+ * @example Advanced usage with config
64
+ * ```typescript
65
+ * @Module({
66
+ * imports: [
67
+ * FeatureFlagsModule.forRoot({
68
+ * gatewayUrl: 'http://localhost:3000',
69
+ * timeout: 5000,
70
+ * maxRedirects: 5,
71
+ * }),
72
+ * ],
73
+ * })
74
+ * export class MyModule {}
75
+ * ```
76
+ */
77
+ static forRoot(configOrUrl: string | FeatureFlagsModuleConfig): DynamicModule;
78
+ }
79
+ //# sourceMappingURL=FeatureFlagsModule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FeatureFlagsModule.d.ts","sourceRoot":"","sources":["../../src/nestjs/FeatureFlagsModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,MAAM,gBAAgB,CAAC;AAIvD;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBACa,kBAAkB;IAC7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,wBAAwB,GAAG,aAAa;CA2B9E"}
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var FeatureFlagsModule_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.FeatureFlagsModule = void 0;
11
+ const common_1 = require("@nestjs/common");
12
+ const axios_1 = require("@nestjs/axios");
13
+ const FeatureFlagsClient_1 = require("./FeatureFlagsClient");
14
+ /**
15
+ * NestJS module for feature flags client
16
+ *
17
+ * This module provides the FeatureFlagsClient service to consume
18
+ * feature flags from the gateway service.
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * @Module({
23
+ * imports: [
24
+ * FeatureFlagsModule.forRoot({
25
+ * gatewayUrl: 'http://localhost:3000',
26
+ * timeout: 5000
27
+ * }),
28
+ * ],
29
+ * providers: [MyService],
30
+ * })
31
+ * export class MyServiceModule {}
32
+ * ```
33
+ */
34
+ let FeatureFlagsModule = FeatureFlagsModule_1 = class FeatureFlagsModule {
35
+ /**
36
+ * Register the FeatureFlagsModule with configuration
37
+ *
38
+ * Supports two call signatures:
39
+ * - `forRoot(gatewayUrl: string)` - Simple URL configuration
40
+ * - `forRoot(config: FeatureFlagsModuleConfig)` - Full configuration object
41
+ *
42
+ * @param configOrUrl - Either a gateway URL string or full configuration object
43
+ * @returns A configured DynamicModule
44
+ *
45
+ * @example Simple usage with URL
46
+ * ```typescript
47
+ * @Module({
48
+ * imports: [
49
+ * FeatureFlagsModule.forRoot('http://localhost:3000'),
50
+ * ],
51
+ * })
52
+ * export class MyModule {}
53
+ * ```
54
+ *
55
+ * @example Advanced usage with config
56
+ * ```typescript
57
+ * @Module({
58
+ * imports: [
59
+ * FeatureFlagsModule.forRoot({
60
+ * gatewayUrl: 'http://localhost:3000',
61
+ * timeout: 5000,
62
+ * maxRedirects: 5,
63
+ * }),
64
+ * ],
65
+ * })
66
+ * export class MyModule {}
67
+ * ```
68
+ */
69
+ static forRoot(configOrUrl) {
70
+ // Handle both string URL and config object
71
+ const config = typeof configOrUrl === 'string'
72
+ ? { gatewayUrl: configOrUrl }
73
+ : configOrUrl;
74
+ const { gatewayUrl, timeout = 5000, maxRedirects = 5 } = config;
75
+ return {
76
+ module: FeatureFlagsModule_1,
77
+ imports: [
78
+ axios_1.HttpModule.register({
79
+ timeout,
80
+ maxRedirects,
81
+ }),
82
+ ],
83
+ providers: [
84
+ {
85
+ provide: 'GATEWAY_URL',
86
+ useValue: gatewayUrl,
87
+ },
88
+ FeatureFlagsClient_1.FeatureFlagsClient,
89
+ ],
90
+ exports: [FeatureFlagsClient_1.FeatureFlagsClient],
91
+ };
92
+ }
93
+ };
94
+ exports.FeatureFlagsModule = FeatureFlagsModule;
95
+ exports.FeatureFlagsModule = FeatureFlagsModule = FeatureFlagsModule_1 = __decorate([
96
+ (0, common_1.Module)({})
97
+ ], FeatureFlagsModule);
98
+ //# sourceMappingURL=FeatureFlagsModule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FeatureFlagsModule.js","sourceRoot":"","sources":["../../src/nestjs/FeatureFlagsModule.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAuD;AACvD,yCAA2C;AAC3C,6DAA0D;AAyB1D;;;;;;;;;;;;;;;;;;;GAmBG;AAEI,IAAM,kBAAkB,0BAAxB,MAAM,kBAAkB;IAC7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,MAAM,CAAC,OAAO,CAAC,WAA8C;QAC3D,2CAA2C;QAC3C,MAAM,MAAM,GACV,OAAO,WAAW,KAAK,QAAQ;YAC7B,CAAC,CAAC,EAAE,UAAU,EAAE,WAAW,EAAE;YAC7B,CAAC,CAAC,WAAW,CAAC;QAElB,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,IAAI,EAAE,YAAY,GAAG,CAAC,EAAE,GAAG,MAAM,CAAC;QAEhE,OAAO;YACL,MAAM,EAAE,oBAAkB;YAC1B,OAAO,EAAE;gBACP,kBAAU,CAAC,QAAQ,CAAC;oBAClB,OAAO;oBACP,YAAY;iBACb,CAAC;aACH;YACD,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,aAAa;oBACtB,QAAQ,EAAE,UAAU;iBACrB;gBACD,uCAAkB;aACnB;YACD,OAAO,EAAE,CAAC,uCAAkB,CAAC;SAC9B,CAAC;IACJ,CAAC;CACF,CAAA;AA9DY,gDAAkB;6BAAlB,kBAAkB;IAD9B,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,kBAAkB,CA8D9B"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * NestJS client for feature flags
3
+ *
4
+ * This module provides a client to consume feature flags from the gateway service.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { FeatureFlagsModule, FeatureFlagsClient } from '@bluealba/pae-feature-flags/nestjs';
9
+ *
10
+ * @Module({
11
+ * imports: [
12
+ * FeatureFlagsModule.forRoot('http://gateway:3000'),
13
+ * ],
14
+ * })
15
+ * export class MyModule {}
16
+ * ```
17
+ */
18
+ export * from './FeatureFlagsClient';
19
+ export * from './FeatureFlagsModule';
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nestjs/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ /**
18
+ * NestJS client for feature flags
19
+ *
20
+ * This module provides a client to consume feature flags from the gateway service.
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * import { FeatureFlagsModule, FeatureFlagsClient } from '@bluealba/pae-feature-flags/nestjs';
25
+ *
26
+ * @Module({
27
+ * imports: [
28
+ * FeatureFlagsModule.forRoot('http://gateway:3000'),
29
+ * ],
30
+ * })
31
+ * export class MyModule {}
32
+ * ```
33
+ */
34
+ __exportStar(require("./FeatureFlagsClient"), exports);
35
+ __exportStar(require("./FeatureFlagsModule"), exports);
36
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/nestjs/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,uDAAqC;AACrC,uDAAqC"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * FeatureFlagGuard Component
3
+ *
4
+ * A React component for conditional rendering based on feature flag state.
5
+ * This component uses the useFeatureFlag hook internally to evaluate the flag
6
+ * and renders either the children (if flag is enabled) or a fallback (if disabled).
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * // Show feature if enabled, hide if disabled
11
+ * <FeatureFlagGuard flag="beta-feature">
12
+ * <BetaFeature />
13
+ * </FeatureFlagGuard>
14
+ *
15
+ * // Show feature if enabled, show fallback if disabled
16
+ * <FeatureFlagGuard flag="new-ui" fallback={<OldUI />}>
17
+ * <NewUI />
18
+ * </FeatureFlagGuard>
19
+ *
20
+ * // Inverted logic - show if disabled
21
+ * <FeatureFlagGuard flag="maintenance-mode" invert>
22
+ * <MainApp />
23
+ * </FeatureFlagGuard>
24
+ * ```
25
+ */
26
+ import { type FC, type ReactNode } from 'react';
27
+ /**
28
+ * Props for the FeatureFlagGuard component
29
+ */
30
+ export interface FeatureFlagGuardProps {
31
+ /**
32
+ * Name of the feature flag to check
33
+ */
34
+ flag: string;
35
+ /**
36
+ * Content to render when the flag is enabled (or disabled if inverted)
37
+ */
38
+ children: ReactNode;
39
+ /**
40
+ * Optional content to render when the flag is disabled (or enabled if inverted)
41
+ * If not provided, nothing will be rendered when the flag is disabled
42
+ */
43
+ fallback?: ReactNode;
44
+ /**
45
+ * Whether to invert the logic
46
+ * If true, children are shown when flag is disabled, fallback when enabled
47
+ * @default false
48
+ */
49
+ invert?: boolean;
50
+ /**
51
+ * Base URL for the gateway API
52
+ * @default ''
53
+ */
54
+ gatewayUrl?: string;
55
+ }
56
+ /**
57
+ * Component for conditional rendering based on feature flags
58
+ */
59
+ export declare const FeatureFlagGuard: FC<FeatureFlagGuardProps>;
60
+ //# sourceMappingURL=FeatureFlagGuard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FeatureFlagGuard.d.ts","sourceRoot":"","sources":["../../src/react/FeatureFlagGuard.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAc,EAAE,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,EAAE,CAAC,qBAAqB,CAiBtD,CAAC"}
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ /**
3
+ * FeatureFlagGuard Component
4
+ *
5
+ * A React component for conditional rendering based on feature flag state.
6
+ * This component uses the useFeatureFlag hook internally to evaluate the flag
7
+ * and renders either the children (if flag is enabled) or a fallback (if disabled).
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * // Show feature if enabled, hide if disabled
12
+ * <FeatureFlagGuard flag="beta-feature">
13
+ * <BetaFeature />
14
+ * </FeatureFlagGuard>
15
+ *
16
+ * // Show feature if enabled, show fallback if disabled
17
+ * <FeatureFlagGuard flag="new-ui" fallback={<OldUI />}>
18
+ * <NewUI />
19
+ * </FeatureFlagGuard>
20
+ *
21
+ * // Inverted logic - show if disabled
22
+ * <FeatureFlagGuard flag="maintenance-mode" invert>
23
+ * <MainApp />
24
+ * </FeatureFlagGuard>
25
+ * ```
26
+ */
27
+ var __importDefault = (this && this.__importDefault) || function (mod) {
28
+ return (mod && mod.__esModule) ? mod : { "default": mod };
29
+ };
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ exports.FeatureFlagGuard = void 0;
32
+ const react_1 = __importDefault(require("react"));
33
+ const useFeatureFlag_1 = require("./useFeatureFlag");
34
+ /**
35
+ * Component for conditional rendering based on feature flags
36
+ */
37
+ const FeatureFlagGuard = ({ flag, children, fallback = null, invert = false, gatewayUrl = '', }) => {
38
+ const isEnabled = (0, useFeatureFlag_1.useFeatureFlag)(flag, false, gatewayUrl);
39
+ // Determine whether to show children based on flag state and invert setting
40
+ const shouldShowChildren = invert ? !isEnabled : isEnabled;
41
+ if (shouldShowChildren) {
42
+ return react_1.default.createElement(react_1.default.Fragment, null, children);
43
+ }
44
+ return react_1.default.createElement(react_1.default.Fragment, null, fallback);
45
+ };
46
+ exports.FeatureFlagGuard = FeatureFlagGuard;
47
+ exports.FeatureFlagGuard.displayName = 'FeatureFlagGuard';
48
+ //# sourceMappingURL=FeatureFlagGuard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FeatureFlagGuard.js","sourceRoot":"","sources":["../../src/react/FeatureFlagGuard.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;;;;;;AAEH,kDAAuD;AACvD,qDAAkD;AAgClD;;GAEG;AACI,MAAM,gBAAgB,GAA8B,CAAC,EAC1D,IAAI,EACJ,QAAQ,EACR,QAAQ,GAAG,IAAI,EACf,MAAM,GAAG,KAAK,EACd,UAAU,GAAG,EAAE,GAChB,EAAE,EAAE;IACH,MAAM,SAAS,GAAG,IAAA,+BAAc,EAAC,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IAE1D,4EAA4E;IAC5E,MAAM,kBAAkB,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IAE3D,IAAI,kBAAkB,EAAE,CAAC;QACvB,OAAO,8DAAG,QAAQ,CAAI,CAAC;IACzB,CAAC;IAED,OAAO,8DAAG,QAAQ,CAAI,CAAC;AACzB,CAAC,CAAC;AAjBW,QAAA,gBAAgB,oBAiB3B;AAEF,wBAAgB,CAAC,WAAW,GAAG,kBAAkB,CAAC"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * FeatureFlagsProvider
3
+ *
4
+ * A React Context provider that manages feature flag state with prefetching and caching capabilities.
5
+ * This provider should wrap your application or a section of it to provide feature flag access to child components.
6
+ *
7
+ * Features:
8
+ * - Prefetches specified flags on mount
9
+ * - Optional automatic refresh at configurable intervals
10
+ * - Caches flag values for efficient access
11
+ * - Provides both boolean flags and multivariant flags
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * <FeatureFlagsProvider
16
+ * gatewayUrl="/api"
17
+ * prefetchFlags={['new-ui', 'beta-feature']}
18
+ * refreshInterval={60000}
19
+ * >
20
+ * <App />
21
+ * </FeatureFlagsProvider>
22
+ * ```
23
+ */
24
+ import React, { type ReactNode } from 'react';
25
+ /**
26
+ * Shape of the feature flags context
27
+ */
28
+ export interface FeatureFlagsContextValue {
29
+ /**
30
+ * Map of flag names to their boolean enabled state
31
+ */
32
+ flags: Map<string, boolean>;
33
+ /**
34
+ * Map of flag names to their variant data
35
+ */
36
+ variants: Map<string, {
37
+ variant: string | null;
38
+ payload: unknown;
39
+ }>;
40
+ /**
41
+ * Whether the initial prefetch is in progress
42
+ */
43
+ isLoading: boolean;
44
+ /**
45
+ * Any error that occurred during flag fetching
46
+ */
47
+ error: Error | null;
48
+ /**
49
+ * Check if a cached flag is enabled
50
+ * @param flagName - Name of the flag to check
51
+ * @param defaultValue - Default value if flag is not in cache (default: false)
52
+ * @returns Whether the flag is enabled
53
+ */
54
+ checkFlag: (flagName: string, defaultValue?: boolean) => boolean;
55
+ /**
56
+ * Get a cached variant value
57
+ * @param flagName - Name of the flag
58
+ * @returns Variant data or null if not in cache
59
+ */
60
+ getVariant: (flagName: string) => {
61
+ variant: string | null;
62
+ payload: unknown;
63
+ } | null;
64
+ /**
65
+ * Manually refresh all prefetched flags
66
+ * @returns Promise that resolves when refresh is complete
67
+ */
68
+ refresh: () => Promise<void>;
69
+ }
70
+ /**
71
+ * Props for the FeatureFlagsProvider component
72
+ */
73
+ export interface FeatureFlagsProviderProps {
74
+ /**
75
+ * Base URL for the gateway API
76
+ * @default ''
77
+ */
78
+ gatewayUrl?: string;
79
+ /**
80
+ * Array of flag names to prefetch on mount and refresh
81
+ * These flags will be eagerly loaded and cached
82
+ */
83
+ prefetchFlags?: string[];
84
+ /**
85
+ * Interval in milliseconds for automatic refresh
86
+ * If not provided, automatic refresh is disabled
87
+ */
88
+ refreshInterval?: number;
89
+ /**
90
+ * Child components that will have access to the feature flags context
91
+ */
92
+ children: ReactNode;
93
+ }
94
+ /**
95
+ * React Context for feature flags
96
+ */
97
+ export declare const FeatureFlagsContext: React.Context<FeatureFlagsContextValue>;
98
+ /**
99
+ * Provider component for feature flags
100
+ */
101
+ export declare const FeatureFlagsProvider: React.FC<FeatureFlagsProviderProps>;
102
+ //# sourceMappingURL=FeatureFlagsProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FeatureFlagsProvider.d.ts","sourceRoot":"","sources":["../../src/react/FeatureFlagsProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,EAA4D,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGxG;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5B;;OAEG;IACH,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACpE;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB;;;;;OAKG;IACH,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC;IACjE;;;;OAIG;IACH,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK;QAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACtF;;;OAGG;IACH,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAeD;;GAEG;AACH,eAAO,MAAM,mBAAmB,yCAA+D,CAAC;AAEhG;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAwIpE,CAAC"}