{"_id":"@bluealba/pae-feature-flags","_rev":"5-a9df3be49ed41d533be88cf662c73d3c","name":"@bluealba/pae-feature-flags","dist-tags":{"latest":"1.0.0-feature-initial-feature-flags-poc-1238"},"versions":{"1.0.0-feature-initial-feature-flags-poc-1233":{"name":"@bluealba/pae-feature-flags","version":"1.0.0-feature-initial-feature-flags-poc-1233","keywords":["feature-flags","feature-toggles","nestjs","react"],"author":{"name":"Blue Alba"},"license":"PolyForm-Noncommercial-1.0.0","_id":"@bluealba/pae-feature-flags@1.0.0-feature-initial-feature-flags-poc-1233","maintainers":[{"name":"bluealba","email":"npm@bluealba.com"}],"dist":{"shasum":"f637f6ba8211659dab6990b22a5f94ebb9d7b790","tarball":"https://registry.npmjs.org/@bluealba/pae-feature-flags/-/pae-feature-flags-1.0.0-feature-initial-feature-flags-poc-1233.tgz","fileCount":50,"integrity":"sha512-ragCxmfuB/2jfURBLge6YtPj1CFfQZYB1JlJViUMD8hkpJs9eF8HdpZxv+jmZbcpJ/CPtVP3hSUaYS75tGmfTQ==","signatures":[{"sig":"MEQCIAx1YJYJbByyQnFBU9o8SXLslnG+m6gEmKaNfYymQoZYAiB5LtgtPCIMNnpBq/0uUHUJ8NlW/+iVD2EvBg09A3IUmQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":79751},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"f0f151a14785cd441689a34b0c66878714fa1c9e","scripts":{"test":"jest --passWithNoTests","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist","prebuild":"npm run clean","test:watch":"jest --watch"},"_npmUser":{"name":"bluealba","email":"npm@bluealba.com"},"_npmVersion":"10.8.2","description":"Feature flags client library for Blue Alba Platform","directories":{},"_nodeVersion":"20.19.6","dependencies":{},"publishConfig":{"access":"public","@bluealba:registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.0","@types/react":"^18.3.1","@testing-library/react":"^16.0.1"},"peerDependencies":{"react":"^18.3.1"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pae-feature-flags_1.0.0-feature-initial-feature-flags-poc-1233_1768583182805_0.20397277694681049","host":"s3://npm-registry-packages-npm-production"}},"1.0.0-feature-initial-feature-flags-poc-1234":{"name":"@bluealba/pae-feature-flags","version":"1.0.0-feature-initial-feature-flags-poc-1234","keywords":["feature-flags","feature-toggles","nestjs","react"],"author":{"name":"Blue Alba"},"license":"PolyForm-Noncommercial-1.0.0","_id":"@bluealba/pae-feature-flags@1.0.0-feature-initial-feature-flags-poc-1234","maintainers":[{"name":"bluealba","email":"npm@bluealba.com"}],"dist":{"shasum":"d6fa25e65ee4e775759613782043276867871226","tarball":"https://registry.npmjs.org/@bluealba/pae-feature-flags/-/pae-feature-flags-1.0.0-feature-initial-feature-flags-poc-1234.tgz","fileCount":50,"integrity":"sha512-yK+NdGnib/KKhFQuGWEIbfZsnpyFsL3LfnE345VdxIJsfyPMMoQxailPOOe9XGhN5mL7/NO564oCPR8PSm9BdA==","signatures":[{"sig":"MEUCIQCu3KG5YysIqflXJtEqicxBi6+0+2UmVSoXl2b9pS91tAIgFip+YdgGc/4ethrCvZAnz9ExYFvZ9JJz6ctgYMyhzJ8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":79751},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"eff630d8c0e07b162529453e80afd376f0cfd5d8","scripts":{"test":"jest --passWithNoTests","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist","prebuild":"npm run clean","test:watch":"jest --watch"},"_npmUser":{"name":"bluealba","email":"npm@bluealba.com"},"_npmVersion":"10.8.2","description":"Feature flags client library for Blue Alba Platform","directories":{},"_nodeVersion":"20.19.6","dependencies":{},"publishConfig":{"access":"public","@bluealba:registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.0","@types/react":"^18.3.1","@testing-library/react":"^16.0.1"},"peerDependencies":{"react":"^18.3.1"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pae-feature-flags_1.0.0-feature-initial-feature-flags-poc-1234_1768584143651_0.9456395474380812","host":"s3://npm-registry-packages-npm-production"}},"1.0.0-feature-initial-feature-flags-poc-1235":{"name":"@bluealba/pae-feature-flags","version":"1.0.0-feature-initial-feature-flags-poc-1235","keywords":["feature-flags","feature-toggles","nestjs","react"],"author":{"name":"Blue Alba"},"license":"PolyForm-Noncommercial-1.0.0","_id":"@bluealba/pae-feature-flags@1.0.0-feature-initial-feature-flags-poc-1235","maintainers":[{"name":"bluealba","email":"npm@bluealba.com"}],"dist":{"shasum":"93a2416972f3167dbfa25d24b9bf0d048b16e1f7","tarball":"https://registry.npmjs.org/@bluealba/pae-feature-flags/-/pae-feature-flags-1.0.0-feature-initial-feature-flags-poc-1235.tgz","fileCount":50,"integrity":"sha512-b/XUd/FMcVCdd1vCIQR7S1+sLpvAmGblAUYUajkAZRPpycXF/xc99wOHD29DnJJZuvUSht/VIjoK4lOJEQx9dw==","signatures":[{"sig":"MEYCIQD1M9Td8MwMu8OYYRyyptJ1szLQxE9ya7dM4pidnIKkAQIhAOlgNqzLtkU6maMbquv5mPAByHrfvF+UDy3G4Gqds5qc","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":79751},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"1e6ad312b933f5ab389ced1d6e4d6e080d6d2d69","scripts":{"test":"jest --passWithNoTests","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist","prebuild":"npm run clean","test:watch":"jest --watch"},"_npmUser":{"name":"bluealba","email":"npm@bluealba.com"},"_npmVersion":"10.8.2","description":"Feature flags client library for Blue Alba Platform","directories":{},"_nodeVersion":"20.19.6","dependencies":{},"publishConfig":{"access":"public","@bluealba:registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.0","@types/react":"^18.3.1","@testing-library/react":"^16.0.1"},"peerDependencies":{"react":"^18.3.1"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pae-feature-flags_1.0.0-feature-initial-feature-flags-poc-1235_1768585938024_0.4569821536188008","host":"s3://npm-registry-packages-npm-production"}},"1.0.0-feature-initial-feature-flags-poc-1237":{"name":"@bluealba/pae-feature-flags","version":"1.0.0-feature-initial-feature-flags-poc-1237","keywords":["feature-flags","feature-toggles","nestjs","react"],"author":{"name":"Blue Alba"},"license":"PolyForm-Noncommercial-1.0.0","_id":"@bluealba/pae-feature-flags@1.0.0-feature-initial-feature-flags-poc-1237","maintainers":[{"name":"bluealba","email":"npm@bluealba.com"}],"dist":{"shasum":"61ef6f85f1aac8030043b905072ef6eb9652e52e","tarball":"https://registry.npmjs.org/@bluealba/pae-feature-flags/-/pae-feature-flags-1.0.0-feature-initial-feature-flags-poc-1237.tgz","fileCount":50,"integrity":"sha512-AoemxlRlujUqJYxxXY+F5JG/hP3Np9s0nhKabxKq/5cd0U1XbY+lQBvHmljRnPykTXUpKs4g/HRMzVqfMS4GrQ==","signatures":[{"sig":"MEQCIGQVt+o5EO+tmHZfbsaNzX2EqKE3+pwNUT+4g2Cqy5w2AiA2d7gMBIDbC5OLI/2kPta4U8risVG8mMMAvGHiPBhuSg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":79751},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"cb5b9a133000851dc28f8a88bb604ce35b402580","scripts":{"test":"jest --passWithNoTests","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist","prebuild":"npm run clean","test:watch":"jest --watch"},"_npmUser":{"name":"bluealba","email":"npm@bluealba.com"},"_npmVersion":"10.8.2","description":"Feature flags client library for Blue Alba Platform","directories":{},"_nodeVersion":"20.19.6","dependencies":{},"publishConfig":{"access":"public","@bluealba:registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.0","@types/react":"^18.3.1","@testing-library/react":"^16.0.1"},"peerDependencies":{"react":"^18.3.1"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pae-feature-flags_1.0.0-feature-initial-feature-flags-poc-1237_1768654712771_0.7508599253308934","host":"s3://npm-registry-packages-npm-production"}},"1.0.0-feature-initial-feature-flags-poc-1238":{"name":"@bluealba/pae-feature-flags","version":"1.0.0-feature-initial-feature-flags-poc-1238","description":"Feature flags client library for Blue Alba Platform","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc -p tsconfig.build.json","clean":"rm -rf dist","prebuild":"npm run clean","test":"jest --passWithNoTests","test:watch":"jest --watch"},"keywords":["feature-flags","feature-toggles","nestjs","react"],"author":{"name":"Blue Alba"},"license":"PolyForm-Noncommercial-1.0.0","dependencies":{},"peerDependencies":{"react":"^18.3.1"},"peerDependenciesMeta":{"react":{"optional":true}},"devDependencies":{"@types/react":"^18.3.1","@testing-library/react":"^16.0.1","typescript":"^5.8.0"},"publishConfig":{"@bluealba:registry":"https://registry.npmjs.org/","access":"public"},"_id":"@bluealba/pae-feature-flags@1.0.0-feature-initial-feature-flags-poc-1238","gitHead":"427998ddba5ffe7efd5d16c71441a7d099688e0c","_nodeVersion":"20.19.6","_npmVersion":"10.8.2","dist":{"integrity":"sha512-vc5jRmjxj5TTi9zhxHJgwqw1DpKSscgu4bF6n1uZh8vHGM6siKtpujl5Zff34gXyGTnWnldI11sQStrX6JcrNw==","shasum":"16be1d0f2d2a4c3fc63108b97416cfa0111248fb","tarball":"https://registry.npmjs.org/@bluealba/pae-feature-flags/-/pae-feature-flags-1.0.0-feature-initial-feature-flags-poc-1238.tgz","fileCount":50,"unpackedSize":79751,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIBa6fh0TlBZtWaI/4Nrl1cRB34Vnd1IMIQR/EvxoPzRRAiBc7P1GUwg3M8LZagn8DoaWHqBMwdY1ZpzAhjixhuMg0g=="}]},"_npmUser":{"name":"bluealba","email":"npm@bluealba.com"},"directories":{},"maintainers":[{"name":"bluealba","email":"npm@bluealba.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pae-feature-flags_1.0.0-feature-initial-feature-flags-poc-1238_1768819573452_0.452068367129427"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-16T17:06:22.715Z","modified":"2026-01-19T10:46:13.729Z","1.0.0-feature-initial-feature-flags-poc-1233":"2026-01-16T17:06:22.959Z","1.0.0-feature-initial-feature-flags-poc-1234":"2026-01-16T17:22:23.815Z","1.0.0-feature-initial-feature-flags-poc-1235":"2026-01-16T17:52:18.172Z","1.0.0-feature-initial-feature-flags-poc-1237":"2026-01-17T12:58:32.918Z","1.0.0-feature-initial-feature-flags-poc-1238":"2026-01-19T10:46:13.599Z"},"author":{"name":"Blue Alba"},"license":"PolyForm-Noncommercial-1.0.0","keywords":["feature-flags","feature-toggles","nestjs","react"],"description":"Feature flags client library for Blue Alba Platform","maintainers":[{"name":"bluealba","email":"npm@bluealba.com"}],"readme":"# @bluealba/pae-feature-flags\n\nFeature flags client library for Blue Alba Platform.\n\n## Installation\n\n```bash\nnpm install @bluealba/pae-feature-flags\n```\n\n## NestJS Usage\n\n### 1. Import the Module\n\n```typescript\nimport { Module } from '@nestjs/common';\nimport { FeatureFlagsModule } from '@bluealba/pae-feature-flags';\n\n@Module({\n  imports: [\n    FeatureFlagsModule.forRoot('http://gateway:3000'),\n    // Or with full configuration\n    FeatureFlagsModule.forRoot({\n      gatewayUrl: 'http://gateway:3000',\n      timeout: 5000,\n      maxRedirects: 5,\n    }),\n  ],\n})\nexport class MyServiceModule {}\n```\n\n### 2. Use the Client\n\n```typescript\nimport { Injectable } from '@nestjs/common';\nimport { FeatureFlagsClient } from '@bluealba/pae-feature-flags';\n\n@Injectable()\nexport class MyService {\n  constructor(private readonly featureFlagsClient: FeatureFlagsClient) {}\n\n  async doSomething() {\n    // Check if a feature is enabled\n    const isEnabled = await this.featureFlagsClient.isEnabled('my-feature');\n    \n    if (isEnabled) {\n      // New implementation\n    } else {\n      // Old implementation\n    }\n    \n    // Get variant for A/B testing\n    const variant = await this.featureFlagsClient.getVariant('ab-test', {\n      userId: '123',\n      tenantId: 'tenant-1',\n    });\n    \n    if (variant?.name === 'variant-a') {\n      // Variant A logic\n    } else if (variant?.name === 'variant-b') {\n      // Variant B logic\n    }\n    \n    // Evaluate multiple flags at once (more efficient)\n    const results = await this.featureFlagsClient.evaluateFlags(\n      ['feature-a', 'feature-b', 'ab-test'],\n      { userId: '123' }\n    );\n    \n    const featureAEnabled = results.get('feature-a')?.enabled ?? false;\n  }\n}\n```\n\n## React Usage\n\n### 1. Setup the Provider\n\nWrap your application with the `FeatureFlagsProvider`:\n\n```tsx\nimport { FeatureFlagsProvider } from '@bluealba/pae-feature-flags';\n\nfunction App() {\n  return (\n    <FeatureFlagsProvider\n      gatewayUrl=\"/api\"\n      prefetchFlags={['new-ui', 'beta-feature']}\n      refreshInterval={60000}\n    >\n      <YourApp />\n    </FeatureFlagsProvider>\n  );\n}\n```\n\n#### Provider Props\n\n- `gatewayUrl` (string, optional): Base URL for the gateway API. Default: `''`\n- `prefetchFlags` (string[], optional): Array of flag names to prefetch on mount\n- `refreshInterval` (number, optional): Interval in milliseconds for automatic refresh\n- `children` (ReactNode): Child components\n\n### 2. Use Feature Flags in Components\n\n#### Simple Boolean Check with `useFeatureFlag`\n\n```tsx\nimport { useFeatureFlag } from '@bluealba/pae-feature-flags';\n\nfunction MyComponent() {\n  const isNewUIEnabled = useFeatureFlag('new-ui', false);\n\n  return isNewUIEnabled ? <NewUI /> : <OldUI />;\n}\n```\n\n#### Conditional Rendering with `FeatureFlagGuard`\n\n```tsx\nimport { FeatureFlagGuard } from '@bluealba/pae-feature-flags';\n\nfunction MyComponent() {\n  return (\n    <>\n      {/* Show feature if enabled */}\n      <FeatureFlagGuard flag=\"beta-feature\">\n        <BetaFeature />\n      </FeatureFlagGuard>\n\n      {/* Show feature if enabled, fallback if disabled */}\n      <FeatureFlagGuard flag=\"new-ui\" fallback={<OldUI />}>\n        <NewUI />\n      </FeatureFlagGuard>\n\n      {/* Inverted logic - show if disabled */}\n      <FeatureFlagGuard flag=\"maintenance-mode\" invert>\n        <MainApp />\n      </FeatureFlagGuard>\n    </>\n  );\n}\n```\n\n#### Multivariant Flags with `useVariant`\n\nFor A/B testing and feature variants:\n\n```tsx\nimport { useVariant } from '@bluealba/pae-feature-flags';\n\nfunction CheckoutFlow() {\n  const { variant, payload, isLoading } = useVariant('checkout-flow');\n\n  if (isLoading) {\n    return <Spinner />;\n  }\n\n  if (variant === 'new-checkout') {\n    return <NewCheckout config={payload} />;\n  }\n\n  if (variant === 'express-checkout') {\n    return <ExpressCheckout config={payload} />;\n  }\n\n  return <DefaultCheckout />;\n}\n```\n\n#### Access Full Context with `useFeatureFlags`\n\n```tsx\nimport { useFeatureFlags } from '@bluealba/pae-feature-flags';\n\nfunction FlagsDebugPanel() {\n  const { flags, variants, isLoading, error, refresh } = useFeatureFlags();\n\n  const handleRefresh = async () => {\n    await refresh();\n  };\n\n  return (\n    <div>\n      <button onClick={handleRefresh} disabled={isLoading}>\n        Refresh Flags\n      </button>\n      {error && <div>Error: {error.message}</div>}\n      <div>Total flags loaded: {flags.size}</div>\n      <ul>\n        {Array.from(flags.entries()).map(([name, enabled]) => (\n          <li key={name}>\n            {name}: {enabled ? 'enabled' : 'disabled'}\n          </li>\n        ))}\n      </ul>\n    </div>\n  );\n}\n```\n\n### React Best Practices\n\n1. **Prefetch Common Flags**: Add frequently used flags to `prefetchFlags` for better performance\n2. **Use FeatureFlagGuard**: Cleaner than inline conditions for simple toggles\n3. **Handle Loading States**: Always handle `isLoading` when using `useVariant`\n4. **Provide Defaults**: Always provide default values to `useFeatureFlag`\n5. **Minimize Refresh**: Don't set refresh intervals too low to avoid network overhead\n\n## API Reference\n\n### FeatureFlagsClient\n\n#### `isEnabled(flagName, defaultValue?, context?): Promise<boolean>`\n\nEvaluates if a feature flag is enabled.\n\n- `flagName`: Name of the feature flag\n- `defaultValue`: Default value if evaluation fails (default: false)\n- `context`: Optional evaluation context (userId, tenantId, customProperties)\n\n#### `getVariant(flagName, context?): Promise<{name: string, payload: any} | null>`\n\nGets the variant for a multivariant feature flag.\n\n- `flagName`: Name of the feature flag\n- `context`: Optional evaluation context\n\n#### `evaluateFlags(flagNames, context?): Promise<Map<string, FlagEvaluationResult>>`\n\nEvaluates multiple feature flags in a single request.\n\n- `flagNames`: Array of feature flag names\n- `context`: Optional evaluation context\n\n## License\n\nPolyForm-Noncommercial-1.0.0\n","readmeFilename":"README.md"}