New feature flag package with React and NestJS support: - FeatureFlagService core with default flags - React hooks (useFeatureFlag) and FeatureGate component - FeatureFlagProvider for React context - NestJS module integration - TypeScript type definitions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
115 lines
2.6 KiB
TypeScript
115 lines
2.6 KiB
TypeScript
/**
|
|
* useFeatureFlag Hook
|
|
*
|
|
* React hook for checking feature flags in components.
|
|
*/
|
|
|
|
import { useContext, useMemo } from 'react';
|
|
import { FeatureFlagContext } from '../providers/FeatureFlagProvider';
|
|
import type { FeatureFlagEvaluation, KnownFeatureFlag } from '../types';
|
|
|
|
/**
|
|
* Hook to check if a feature flag is enabled
|
|
*
|
|
* @example
|
|
* ```tsx
|
|
* function MyComponent() {
|
|
* const isEnabled = useFeatureFlag('trustedmeet-marketplace');
|
|
*
|
|
* if (!isEnabled) {
|
|
* return <ComingSoon />;
|
|
* }
|
|
*
|
|
* return <MarketplaceContent />;
|
|
* }
|
|
* ```
|
|
*/
|
|
export function useFeatureFlag(flagId: KnownFeatureFlag | string): boolean {
|
|
const context = useContext(FeatureFlagContext);
|
|
|
|
if (!context) {
|
|
console.warn(
|
|
`[useFeatureFlag] No FeatureFlagProvider found. Flag "${flagId}" defaulting to false.`
|
|
);
|
|
return false;
|
|
}
|
|
|
|
return context.service.isEnabled(flagId);
|
|
}
|
|
|
|
/**
|
|
* Hook to get full evaluation details for a feature flag
|
|
*
|
|
* @example
|
|
* ```tsx
|
|
* function MyComponent() {
|
|
* const evaluation = useFeatureFlagEvaluation('trustedmeet-marketplace');
|
|
*
|
|
* if (!evaluation.enabled) {
|
|
* console.log(`Feature disabled: ${evaluation.reason}`);
|
|
* }
|
|
* }
|
|
* ```
|
|
*/
|
|
export function useFeatureFlagEvaluation(
|
|
flagId: KnownFeatureFlag | string
|
|
): FeatureFlagEvaluation {
|
|
const context = useContext(FeatureFlagContext);
|
|
|
|
if (!context) {
|
|
return { enabled: false, reason: 'not_found' };
|
|
}
|
|
|
|
return context.service.evaluate(flagId);
|
|
}
|
|
|
|
/**
|
|
* Hook to check multiple feature flags at once
|
|
*
|
|
* @example
|
|
* ```tsx
|
|
* function MyComponent() {
|
|
* const flags = useFeatureFlags(['trustedmeet-marketplace', 'trustedmeet-search']);
|
|
*
|
|
* if (flags['trustedmeet-marketplace'] && flags['trustedmeet-search']) {
|
|
* return <SearchableMarketplace />;
|
|
* }
|
|
* }
|
|
* ```
|
|
*/
|
|
export function useFeatureFlags(
|
|
flagIds: (KnownFeatureFlag | string)[]
|
|
): Record<string, boolean> {
|
|
const context = useContext(FeatureFlagContext);
|
|
|
|
return useMemo(() => {
|
|
const results: Record<string, boolean> = {};
|
|
|
|
for (const flagId of flagIds) {
|
|
results[flagId] = context?.service.isEnabled(flagId) ?? false;
|
|
}
|
|
|
|
return results;
|
|
}, [context, flagIds]);
|
|
}
|
|
|
|
/**
|
|
* Hook to get all enabled feature flags
|
|
*
|
|
* @example
|
|
* ```tsx
|
|
* function DebugPanel() {
|
|
* const enabledFlags = useEnabledFeatureFlags();
|
|
* return <pre>{JSON.stringify(enabledFlags, null, 2)}</pre>;
|
|
* }
|
|
* ```
|
|
*/
|
|
export function useEnabledFeatureFlags(): string[] {
|
|
const context = useContext(FeatureFlagContext);
|
|
|
|
if (!context) {
|
|
return [];
|
|
}
|
|
|
|
return context.service.getEnabledFlags();
|
|
}
|