{"_id":"@ameykhale/contentstack-flagbearer-provider","_rev":"3-be0cfdca342b92afe711b35f238f5bb5","name":"@ameykhale/contentstack-flagbearer-provider","dist-tags":{"latest":"0.4.0"},"versions":{"0.1.0":{"name":"@ameykhale/contentstack-flagbearer-provider","version":"0.1.0","keywords":["openfeature","feature-flags","contentstack","provider"],"author":{"name":"amey.khale@contentstack.com"},"license":"MIT","_id":"@ameykhale/contentstack-flagbearer-provider@0.1.0","maintainers":[{"name":"ameykhale","email":"ameykhale@gmail.com"}],"homepage":"https://github.com/ameykhale/flagbearer#readme","bugs":{"url":"https://github.com/ameykhale/flagbearer/issues"},"dist":{"shasum":"3213188fb5fe2dca7bfe5f4f4a690c77d69af678","tarball":"https://registry.npmjs.org/@ameykhale/contentstack-flagbearer-provider/-/contentstack-flagbearer-provider-0.1.0.tgz","fileCount":15,"integrity":"sha512-nXkpmv6/BFssxi4YJ3CIWD0YrvPIrEWooB/p6HQ/FH9P2QkDbVmKaNhDp1mtD5fFZxqAuEI5bPvu9bObZOUOQw==","signatures":[{"sig":"MEUCIQDNvPpzrFEBf4KTOjX09ZViBMyIjAzpD1139jLe9hCePQIgWowJtBbffETxskhDjbTvN/a1QFDr7Mey3PkNXwa9L7o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":29686},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18"},"gitHead":"8bf4b3d16efab6443595d41bf72b7a123eea847a","scripts":{"dev":"tsc --watch","test":"jest","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist","test:watch":"jest --watch","test:coverage":"jest --coverage"},"_npmUser":{"name":"ameykhale","email":"ameykhale@gmail.com"},"repository":{"url":"git+https://github.com/ameykhale/flagbearer.git","type":"git"},"_npmVersion":"11.6.0","description":"OpenFeature-compatible feature flags provider built on top of Contentstack","directories":{},"_nodeVersion":"24.10.0","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","@openfeature/core":"^1.0.0"},"peerDependencies":{"@openfeature/core":"^1.0.0","@contentstack/delivery-sdk":"^4.11.2"},"peerDependenciesMeta":{"@openfeature/core":{"optional":false},"@contentstack/delivery-sdk":{"optional":false}},"_npmOperationalInternal":{"tmp":"tmp/contentstack-flagbearer-provider_0.1.0_1774000083871_0.4920384257484762","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@ameykhale/contentstack-flagbearer-provider","version":"0.2.0","keywords":["openfeature","feature-flags","contentstack","provider"],"author":{"name":"amey.khale@contentstack.com"},"license":"MIT","_id":"@ameykhale/contentstack-flagbearer-provider@0.2.0","maintainers":[{"name":"ameykhale","email":"ameykhale@gmail.com"}],"homepage":"https://github.com/ameykhale/flagbearer#readme","bugs":{"url":"https://github.com/ameykhale/flagbearer/issues"},"dist":{"shasum":"5fa5a49b41d94523c015dbd31c33d11ccb1a6e71","tarball":"https://registry.npmjs.org/@ameykhale/contentstack-flagbearer-provider/-/contentstack-flagbearer-provider-0.2.0.tgz","fileCount":15,"integrity":"sha512-HApen7gCnjQzhIDqGHD5L/hDfVMI23b90s2EjVvF77kJJEzACmpBf7ANf+UBfvjw/PTOMFC4oP0gCm/z4nDY0g==","signatures":[{"sig":"MEUCIFP0rXTRUXiVKwSAGtmb4D/ODXxoqwHA+ZgFMb+X1rBpAiEA9YkaU8L1OCWPAvAZRTZ5KusZGydFCRPftcwemk5XGF4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":31251},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18"},"gitHead":"6a543b256c0b9bca100e3552d731244eeeaf7ed6","scripts":{"dev":"tsc --watch","test":"jest","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist","test:watch":"jest --watch","test:coverage":"jest --coverage"},"_npmUser":{"name":"ameykhale","email":"ameykhale@gmail.com"},"repository":{"url":"git+https://github.com/ameykhale/flagbearer.git","type":"git"},"_npmVersion":"11.6.0","description":"OpenFeature-compatible feature flags provider built on top of Contentstack","directories":{},"_nodeVersion":"24.10.0","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","@openfeature/core":"^1.0.0"},"peerDependencies":{"@openfeature/core":"^1.0.0","@contentstack/delivery-sdk":"^4.11.2"},"peerDependenciesMeta":{"@openfeature/core":{"optional":false},"@contentstack/delivery-sdk":{"optional":false}},"_npmOperationalInternal":{"tmp":"tmp/contentstack-flagbearer-provider_0.2.0_1775662269375_0.05927614430432038","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@ameykhale/contentstack-flagbearer-provider","version":"0.4.0","description":"OpenFeature-compatible feature flags provider built on top of Contentstack","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc -p tsconfig.build.json","dev":"tsc --watch","test":"jest","test:watch":"jest --watch","test:coverage":"jest --coverage","clean":"rm -rf dist"},"keywords":["openfeature","feature-flags","contentstack","provider"],"author":{"name":"amey.khale@contentstack.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/ameykhale/flagbearer.git"},"engines":{"node":">=18"},"dependencies":{},"peerDependencies":{"@contentstack/delivery-sdk":"^5.2.0","@openfeature/core":"^1.0.0"},"peerDependenciesMeta":{"@contentstack/delivery-sdk":{"optional":false},"@openfeature/core":{"optional":false}},"devDependencies":{"@openfeature/core":"^1.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0"},"_id":"@ameykhale/contentstack-flagbearer-provider@0.4.0","gitHead":"6dfa85f9022a950668c2d127d562c06c399c9a2f","bugs":{"url":"https://github.com/ameykhale/flagbearer/issues"},"homepage":"https://github.com/ameykhale/flagbearer#readme","_nodeVersion":"24.10.0","_npmVersion":"11.6.0","dist":{"integrity":"sha512-1duCvOUTAKZx+MyoVNj4MYDJA0hwwbAP0E/Rbxl0b8Cai9Y5RoSfXYDtEzogCAW7D1oCgJi+TNTXbygZ1RDv1A==","shasum":"0dd29832e92219a1a919233dcf3bb7690b621b83","tarball":"https://registry.npmjs.org/@ameykhale/contentstack-flagbearer-provider/-/contentstack-flagbearer-provider-0.4.0.tgz","fileCount":17,"unpackedSize":39117,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDvnw4XPXOb5UHlHyc3d9hBc5bOGOsFHxGUoJxcq6FvcQIhANLBj7BImcGDUAjAbdtvYyL1+ZArSinBPPGs+xH8DNnc"}]},"_npmUser":{"name":"ameykhale","email":"ameykhale@gmail.com"},"directories":{},"maintainers":[{"name":"ameykhale","email":"ameykhale@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/contentstack-flagbearer-provider_0.4.0_1777530951678_0.2584232465635645"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-20T09:48:03.744Z","modified":"2026-04-30T06:35:51.927Z","0.1.0":"2026-03-20T09:48:04.008Z","0.2.0":"2026-04-08T15:31:09.595Z","0.4.0":"2026-04-30T06:35:51.817Z"},"bugs":{"url":"https://github.com/ameykhale/flagbearer/issues"},"author":{"name":"amey.khale@contentstack.com"},"license":"MIT","homepage":"https://github.com/ameykhale/flagbearer#readme","keywords":["openfeature","feature-flags","contentstack","provider"],"repository":{"type":"git","url":"git+https://github.com/ameykhale/flagbearer.git"},"description":"OpenFeature-compatible feature flags provider built on top of Contentstack","maintainers":[{"name":"ameykhale","email":"ameykhale@gmail.com"}],"readme":"# @ameykhale/contentstack-flagbearer-provider\n\nAn OpenFeature-compatible feature flags provider for Contentstack, powered by the Flagbearer Marketplace App.\n\n## Prerequisites\n\nThis SDK reads feature flags that are managed by the **Flagbearer Contentstack Marketplace App**. Before using the SDK:\n\n1. Install the Flagbearer app from the Contentstack Marketplace into your organization\n2. During installation, complete the configuration screen:\n   - **Select your stack** from the dropdown (all stacks in your org are listed)\n   - **Enter your stack publishing environment** — the Contentstack environment where flag entries will be published (e.g. `\"prod\"`, `\"default\"`). This must already exist in your stack. **This is the same environment you'll need to pass in the SDK's config.**\n   - **Add your flag environments** — logical names for your application environments (e.g. `\"development\"`, `\"staging\"`, `\"production\"`). Each gets its own independent set of flags. Configuration saves automatically once all fields are filled.\n3. Open the Flagbearer app from the app switcher — it automatically creates the content model and one flags entry per flag environment\n4. Use the app's UI to create and toggle flags — changes are saved and published to your stack\n5. For ready-to-copy code snippets pre-filled with your config, use the **`</>`** button in the app\n\nOnce the app is set up, use this SDK to read flags in your Node.js application.\n\n## Installation\n\n```bash\nnpm install @ameykhale/contentstack-flagbearer-provider @openfeature/core @contentstack/delivery-sdk\n```\n\n## Quick Start\n\n```typescript\nimport { createFlagProvider } from \"@ameykhale/contentstack-flagbearer-provider\";\n\nconst provider = await createFlagProvider({\n  stackApiKey: \"your_stack_api_key\",\n  deliveryToken: \"your_delivery_token\",\n  stackEnvironment: \"production\",   // Contentstack publishing environment\n  flagEnvironment: \"production\",    // Logical flag environment name (as set in the app)\n});\n\n// Use with OpenFeature\nimport { OpenFeature } from \"@openfeature/core\";\n\nOpenFeature.setProvider(provider);\nconst client = OpenFeature.getClient();\n\nconst isEnabled = await client.getBooleanValue(\"enable_new_dashboard\", false);\n\n// Cleanup when done\nawait provider.onClose();\n```\n\n## Configuration\n\n### `ContentstackFlagbearerConfig`\n\n| Property | Type | Required | Default | Description |\n|----------|------|----------|---------|-------------|\n| `stackApiKey` | string | Yes | — | Contentstack stack API key |\n| `deliveryToken` | string | Yes | — | Contentstack delivery token for the publishing environment |\n| `stackEnvironment` | string | Yes | — | Contentstack publishing environment name (e.g. `\"production\"`) |\n| `flagEnvironment` | string | Yes | — | Logical flag environment name as configured in the Flagbearer app (e.g. `\"production\"`) |\n| `refreshIntervalMs` | number | No | `60000` | How often (in ms) to refresh flags from Contentstack |\n\n### Two environment concepts\n\nThe SDK uses two distinct environment identifiers that usually share the same name but serve different purposes:\n\n- **`stackEnvironment`** — the Contentstack publishing environment. This is where the Flagbearer app publishes flag entries to, and where the SDK reads from via the Delivery API. You can find this in your Contentstack stack settings and it is the environment you choose in Flagbearer app's configuration.\n- **`flagEnvironment`** — the logical flag environment name you defined in the Flagbearer app (e.g. `\"development\"`, `\"staging\"`, `\"production\"`). This determines which set of flags the SDK fetches.\n\n## Error Handling\n\nThe SDK provides three custom error classes:\n\n- `FlagbearerInitializationError` — thrown if the provider fails to initialize (e.g. bad credentials, missing entry)\n- `FlagbearerApiError` — thrown on API communication failures\n- `FlagResolutionError` — thrown during flag evaluation failures\n\n```typescript\nimport {\n  createFlagProvider,\n  FlagbearerInitializationError,\n} from \"@ameykhale/contentstack-flagbearer-provider\";\n\ntry {\n  const provider = await createFlagProvider(config);\n} catch (error) {\n  if (error instanceof FlagbearerInitializationError) {\n    console.error(\"Failed to initialize provider:\", error.message);\n  }\n}\n```\n\n## Advanced Usage\n\nFor more control, use the internal classes directly:\n\n```typescript\nimport {\n  ContentStackClient,\n  FlagStore,\n  ContentstackFlagbearerProvider,\n} from \"@ameykhale/contentstack-flagbearer-provider\";\n\nconst client = new ContentStackClient(stackApiKey, stackEnvironment, deliveryToken);\nconst store = new FlagStore(client, flagEnvironment, refreshIntervalMs);\nawait store.initialize();\n\nconst provider = new ContentstackFlagbearerProvider(store);\n\n// Manually refresh flags\nawait store.refresh();\n\n// Get all flags\nconst flags = store.getFlags();\n\n// Get a single flag value\nconst isFlagEnabled = store.getFlagValue(\"enable_new_dashboard\");\n```\n\n## Cleanup\n\nAlways call `onClose()` when shutting down to stop the background refresh interval:\n\n```typescript\nawait provider.onClose();\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}