@flagify/node 1.0.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.
- package/README.md +246 -0
- package/dist/index.d.mts +275 -0
- package/dist/index.d.ts +275 -0
- package/dist/index.js +360 -0
- package/dist/index.mjs +332 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://flagify.dev">
|
|
3
|
+
<picture>
|
|
4
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://flagify.dev/logo-white.svg" />
|
|
5
|
+
<source media="(prefers-color-scheme: light)" srcset="https://flagify.dev/logo-color.svg" />
|
|
6
|
+
<img alt="Flagify" src="https://flagify.dev/logo-color.svg" width="280" />
|
|
7
|
+
</picture>
|
|
8
|
+
</a>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<strong>Feature flags for modern teams</strong>
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
<p align="center">
|
|
16
|
+
<a href="https://www.npmjs.com/package/@flagify/node"><img src="https://img.shields.io/npm/v/@flagify/node.svg?style=flat-square&color=0D80F9" alt="npm version" /></a>
|
|
17
|
+
<a href="https://www.npmjs.com/package/@flagify/node"><img src="https://img.shields.io/npm/dm/@flagify/node.svg?style=flat-square&color=0D80F9" alt="npm downloads" /></a>
|
|
18
|
+
<a href="https://github.com/flagifyhq/node-sdk/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/@flagify/node.svg?style=flat-square&color=0D80F9" alt="license" /></a>
|
|
19
|
+
<a href="https://github.com/flagifyhq/node-sdk"><img src="https://img.shields.io/github/stars/flagifyhq/node-sdk?style=flat-square&color=0D80F9" alt="github stars" /></a>
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
<p align="center">
|
|
23
|
+
<a href="https://flagify.dev/docs">Documentation</a> ·
|
|
24
|
+
<a href="https://flagify.dev/docs/sdks/node">SDK Reference</a> ·
|
|
25
|
+
<a href="https://github.com/flagifyhq/node-sdk/issues">Issues</a> ·
|
|
26
|
+
<a href="https://flagify.dev">Website</a>
|
|
27
|
+
</p>
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Overview
|
|
32
|
+
|
|
33
|
+
`@flagify/node` is the official Node.js SDK for [Flagify](https://flagify.dev). TypeScript-first, with in-memory caching and sub-millisecond flag evaluation.
|
|
34
|
+
|
|
35
|
+
- **TypeScript-first** -- Full type safety with generics support
|
|
36
|
+
- **In-memory cache** -- Sub-millisecond evaluations after initial sync
|
|
37
|
+
- **Stale-while-revalidate** -- Serves cached values while refreshing in the background
|
|
38
|
+
- **Lightweight** -- Zero runtime dependencies (except `dotenv`)
|
|
39
|
+
- **Isomorphic** -- ESM and CommonJS output
|
|
40
|
+
|
|
41
|
+
## Table of contents
|
|
42
|
+
|
|
43
|
+
- [Installation](#installation)
|
|
44
|
+
- [Quick start](#quick-start)
|
|
45
|
+
- [Configuration](#configuration)
|
|
46
|
+
- [API reference](#api-reference)
|
|
47
|
+
- [How it works](#how-it-works)
|
|
48
|
+
- [Environment variables](#environment-variables)
|
|
49
|
+
- [Contributing](#contributing)
|
|
50
|
+
- [License](#license)
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# pnpm
|
|
56
|
+
pnpm add @flagify/node
|
|
57
|
+
|
|
58
|
+
# npm
|
|
59
|
+
npm install @flagify/node
|
|
60
|
+
|
|
61
|
+
# yarn
|
|
62
|
+
yarn add @flagify/node
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Quick start
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { Flagify } from '@flagify/node'
|
|
69
|
+
|
|
70
|
+
const flagify = new Flagify({
|
|
71
|
+
projectKey: 'proj_xxx',
|
|
72
|
+
publicKey: 'pk_xxx',
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
// Boolean flag
|
|
76
|
+
if (flagify.isEnabled('new-checkout')) {
|
|
77
|
+
showNewCheckout()
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Typed value
|
|
81
|
+
const limit = flagify.getValue<number>('rate-limit')
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Configuration
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
import { Flagify } from '@flagify/node'
|
|
88
|
+
|
|
89
|
+
const flagify = new Flagify({
|
|
90
|
+
// Required
|
|
91
|
+
projectKey: 'proj_xxx',
|
|
92
|
+
publicKey: 'pk_xxx',
|
|
93
|
+
|
|
94
|
+
// Optional -- server-side only, never expose in client bundles
|
|
95
|
+
secretKey: 'sk_xxx',
|
|
96
|
+
|
|
97
|
+
options: {
|
|
98
|
+
// Custom API endpoint (defaults to https://api.flagify.dev)
|
|
99
|
+
apiUrl: 'https://api.flagify.dev',
|
|
100
|
+
|
|
101
|
+
// Cache TTL in ms (default: 5 minutes)
|
|
102
|
+
staleTimeMs: 300_000,
|
|
103
|
+
|
|
104
|
+
// Real-time updates via SSE (coming soon)
|
|
105
|
+
realtime: false,
|
|
106
|
+
|
|
107
|
+
// User context for targeting rules
|
|
108
|
+
user: {
|
|
109
|
+
id: 'user_123',
|
|
110
|
+
email: 'mario@example.com',
|
|
111
|
+
role: 'admin',
|
|
112
|
+
group: 'engineering',
|
|
113
|
+
geolocation: {
|
|
114
|
+
country: 'US',
|
|
115
|
+
region: 'CA',
|
|
116
|
+
city: 'San Francisco',
|
|
117
|
+
},
|
|
118
|
+
// Custom attributes
|
|
119
|
+
plan: 'enterprise',
|
|
120
|
+
companySize: 50,
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
})
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Configuration options
|
|
127
|
+
|
|
128
|
+
| Option | Type | Required | Default | Description |
|
|
129
|
+
|--------|------|----------|---------|-------------|
|
|
130
|
+
| `projectKey` | `string` | Yes | -- | Project identifier from your Flagify workspace |
|
|
131
|
+
| `publicKey` | `string` | Yes | -- | Client-safe publishable API key |
|
|
132
|
+
| `secretKey` | `string` | No | -- | Server-side secret key |
|
|
133
|
+
| `options.apiUrl` | `string` | No | `https://api.flagify.dev` | Custom API base URL |
|
|
134
|
+
| `options.staleTimeMs` | `number` | No | `300000` | Cache staleness threshold in ms |
|
|
135
|
+
| `options.realtime` | `boolean` | No | `false` | Enable real-time SSE updates |
|
|
136
|
+
| `options.user` | `FlagifyUser` | No | -- | User context for targeting |
|
|
137
|
+
|
|
138
|
+
## API reference
|
|
139
|
+
|
|
140
|
+
### `new Flagify(config: FlagifyOptions)`
|
|
141
|
+
|
|
142
|
+
Creates a new Flagify client. Immediately fetches all flags and populates the local cache.
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
const flagify = new Flagify({
|
|
146
|
+
projectKey: 'proj_xxx',
|
|
147
|
+
publicKey: 'pk_xxx',
|
|
148
|
+
})
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
### `flagify.isEnabled(flagKey: string): boolean`
|
|
154
|
+
|
|
155
|
+
Evaluates a boolean feature flag.
|
|
156
|
+
|
|
157
|
+
Returns `false` when:
|
|
158
|
+
- The flag does not exist
|
|
159
|
+
- The flag is disabled
|
|
160
|
+
- The flag type is not `boolean`
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
if (flagify.isEnabled('dark-mode')) {
|
|
164
|
+
applyDarkTheme()
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
### `flagify.getValue<T>(flagKey: string): T`
|
|
171
|
+
|
|
172
|
+
Returns the resolved value of a feature flag with TypeScript generics.
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
// String variant
|
|
176
|
+
const variant = flagify.getValue<string>('checkout-flow')
|
|
177
|
+
|
|
178
|
+
// Number
|
|
179
|
+
const limit = flagify.getValue<number>('rate-limit')
|
|
180
|
+
|
|
181
|
+
// JSON object
|
|
182
|
+
const config = flagify.getValue<{ maxRetries: number; timeout: number }>('api-config')
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## How it works
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
Init Evaluate Stale?
|
|
189
|
+
---- -------- ------
|
|
190
|
+
GET /v1/flags --> Read from cache --> Background refetch
|
|
191
|
+
Cache all flags Sub-ms response GET /v1/flags/:key
|
|
192
|
+
Return stale value immediately
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
1. On initialization, the client syncs all flags from `GET /v1/flags`
|
|
196
|
+
2. All evaluations read from the in-memory `Map` cache -- sub-millisecond
|
|
197
|
+
3. When a flag exceeds `staleTimeMs`, the stale value is returned immediately while a background `GET /v1/flags/:key` refreshes the cache
|
|
198
|
+
4. If the API is unreachable, the client falls back to cached defaults
|
|
199
|
+
|
|
200
|
+
## Environment variables
|
|
201
|
+
|
|
202
|
+
| Variable | Description |
|
|
203
|
+
|----------|-------------|
|
|
204
|
+
| `FLAGIFY_API_URL` | Override the default API base URL |
|
|
205
|
+
|
|
206
|
+
## Types
|
|
207
|
+
|
|
208
|
+
All types are exported for convenience:
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
import type {
|
|
212
|
+
FlagifyOptions,
|
|
213
|
+
FlagifyUser,
|
|
214
|
+
FlagifyFlaggy,
|
|
215
|
+
IFlagifyClient,
|
|
216
|
+
} from '@flagify/node'
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Contributing
|
|
220
|
+
|
|
221
|
+
We welcome contributions. Please open an issue first to discuss what you'd like to change.
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
# Clone
|
|
225
|
+
git clone https://github.com/flagifyhq/node-sdk.git
|
|
226
|
+
cd node-sdk
|
|
227
|
+
|
|
228
|
+
# Install
|
|
229
|
+
pnpm install
|
|
230
|
+
|
|
231
|
+
# Development
|
|
232
|
+
pnpm run dev
|
|
233
|
+
|
|
234
|
+
# Build
|
|
235
|
+
pnpm run build
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## License
|
|
239
|
+
|
|
240
|
+
MIT -- see [LICENSE](./LICENSE) for details.
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
<p align="center">
|
|
245
|
+
<sub>Built with care by the <a href="https://flagify.dev">Flagify</a> team</sub>
|
|
246
|
+
</p>
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a user context object used for feature flag targeting.
|
|
3
|
+
*
|
|
4
|
+
* You can define standard properties like `id`, `email`, `role`, and `group`,
|
|
5
|
+
* as well as any number of custom attributes for segmentation purposes.
|
|
6
|
+
*/
|
|
7
|
+
interface FlagifyUser {
|
|
8
|
+
/**
|
|
9
|
+
* Unique identifier for the user.
|
|
10
|
+
* This is typically required for targeting, experimentation, or auditing.
|
|
11
|
+
*/
|
|
12
|
+
id: string;
|
|
13
|
+
/**
|
|
14
|
+
* Optional email address of the user.
|
|
15
|
+
*/
|
|
16
|
+
email?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Optional role or access level of the user (e.g., "admin", "editor", "viewer").
|
|
19
|
+
*/
|
|
20
|
+
role?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Optional group or organization to which the user belongs.
|
|
23
|
+
*/
|
|
24
|
+
group?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Optional geolocation details used for region-based targeting.
|
|
27
|
+
*/
|
|
28
|
+
geolocation?: {
|
|
29
|
+
/**
|
|
30
|
+
* ISO country code (e.g., "US", "MX", "DE").
|
|
31
|
+
*/
|
|
32
|
+
country?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Optional region or state within the country.
|
|
35
|
+
*/
|
|
36
|
+
region?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Optional city or locality.
|
|
39
|
+
*/
|
|
40
|
+
city?: string;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Any other custom attributes for advanced targeting rules.
|
|
44
|
+
*/
|
|
45
|
+
[key: string]: unknown;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Configuration options required to initialize the Flagify client.
|
|
50
|
+
*/
|
|
51
|
+
interface FlagifyOptions {
|
|
52
|
+
/**
|
|
53
|
+
* The key identifying the project within your Flagify workspace.
|
|
54
|
+
*/
|
|
55
|
+
projectKey: string;
|
|
56
|
+
/**
|
|
57
|
+
* Public API key used to identify the client or application.
|
|
58
|
+
* This is safe to expose in client-side environments (e.g., browser, mobile).
|
|
59
|
+
*/
|
|
60
|
+
publicKey: string;
|
|
61
|
+
/**
|
|
62
|
+
* Optional private key for secure server-side communication.
|
|
63
|
+
* Never expose this in frontend environments.
|
|
64
|
+
*/
|
|
65
|
+
secretKey?: string;
|
|
66
|
+
/**
|
|
67
|
+
* Additional optional configuration for advanced use cases.
|
|
68
|
+
*/
|
|
69
|
+
options?: {
|
|
70
|
+
/**
|
|
71
|
+
* Contextual user data for targeting rules and segmentation.
|
|
72
|
+
* You may provide built-in fields like `id`, `email`, `role`, or custom traits.
|
|
73
|
+
*/
|
|
74
|
+
user?: FlagifyUser;
|
|
75
|
+
/**
|
|
76
|
+
* Custom base URL for the Flagify API (e.g., for self-hosted instances or testing).
|
|
77
|
+
* Defaults to "https://api.flagify.app" if not provided.
|
|
78
|
+
*/
|
|
79
|
+
apiUrl?: string;
|
|
80
|
+
/**
|
|
81
|
+
* Optional cache stale time in milliseconds for local flag resolution.
|
|
82
|
+
* Defaults to 5 minutes.
|
|
83
|
+
*/
|
|
84
|
+
staleTimeMs?: number;
|
|
85
|
+
/**
|
|
86
|
+
* Enables real-time flag updates via Server-Sent Events.
|
|
87
|
+
*/
|
|
88
|
+
realtime?: boolean;
|
|
89
|
+
/**
|
|
90
|
+
* Interval in milliseconds to periodically re-sync all flags.
|
|
91
|
+
* Useful as a fallback when realtime is unavailable.
|
|
92
|
+
* Example: 30000 (every 30 seconds).
|
|
93
|
+
*/
|
|
94
|
+
pollIntervalMs?: number;
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
interface FlagifyHttpClient {
|
|
99
|
+
get<T = unknown>(path: string): Promise<T>;
|
|
100
|
+
post<T = unknown, B = unknown>(path: string, body: B): Promise<T>;
|
|
101
|
+
baseUrl: string;
|
|
102
|
+
headers: Record<string, string>;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
interface RealtimeEvents {
|
|
106
|
+
onFlagChange: (event: FlagChangeEvent) => void;
|
|
107
|
+
onConnected: () => void;
|
|
108
|
+
onReconnected: () => void;
|
|
109
|
+
onError: (error: Error) => void;
|
|
110
|
+
}
|
|
111
|
+
interface FlagChangeEvent {
|
|
112
|
+
environmentId: string;
|
|
113
|
+
flagKey: string;
|
|
114
|
+
action: "updated" | "created" | "archived";
|
|
115
|
+
}
|
|
116
|
+
declare class RealtimeListener {
|
|
117
|
+
private readonly httpClient;
|
|
118
|
+
private readonly events;
|
|
119
|
+
private controller;
|
|
120
|
+
private reconnectAttempts;
|
|
121
|
+
private reconnectTimer;
|
|
122
|
+
private hasConnectedBefore;
|
|
123
|
+
constructor(httpClient: FlagifyHttpClient, events: RealtimeEvents);
|
|
124
|
+
connect(): void;
|
|
125
|
+
disconnect(): void;
|
|
126
|
+
private stream;
|
|
127
|
+
private parseSSEFrame;
|
|
128
|
+
private scheduleReconnect;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Interface defining the core methods for the Flaggy client.
|
|
133
|
+
*/
|
|
134
|
+
interface IFlagifyClient {
|
|
135
|
+
/**
|
|
136
|
+
* Retrieves the resolved value of a feature flag.
|
|
137
|
+
* Falls back to defaultValue if evaluation fails or flag is not found.
|
|
138
|
+
*
|
|
139
|
+
* @param flagKey - The key of the feature flag to retrieve.
|
|
140
|
+
* @returns The resolved value of the feature flag.
|
|
141
|
+
*/
|
|
142
|
+
getValue<T>(flagKey: string, fallback: T): T;
|
|
143
|
+
/**
|
|
144
|
+
* Checks if a boolean feature flag is enabled.
|
|
145
|
+
* Returns false if flag is not found or default is false.
|
|
146
|
+
*
|
|
147
|
+
* @param flagKey - The key of the feature flag to check.
|
|
148
|
+
* @returns True if the flag is enabled, false otherwise.
|
|
149
|
+
*/
|
|
150
|
+
isEnabled(flagKey: string): boolean;
|
|
151
|
+
/**
|
|
152
|
+
* Returns the variant key with the highest weight for a multivariate flag.
|
|
153
|
+
* Returns fallback if the flag is missing, disabled, or has no variants.
|
|
154
|
+
*
|
|
155
|
+
* @param flagKey - The key of the feature flag.
|
|
156
|
+
* @param fallback - The default variant key.
|
|
157
|
+
* @returns The winning variant key.
|
|
158
|
+
*/
|
|
159
|
+
getVariant(flagKey: string, fallback: string): string;
|
|
160
|
+
/**
|
|
161
|
+
* Evaluates a flag with user context for targeting rules.
|
|
162
|
+
* Calls the API's evaluate endpoint directly (not cached).
|
|
163
|
+
*/
|
|
164
|
+
evaluate(flagKey: string, user: FlagifyUser): Promise<EvaluateResult>;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
interface EvaluateResult {
|
|
168
|
+
key: string;
|
|
169
|
+
value: unknown;
|
|
170
|
+
reason: "targeting_rule" | "rollout" | "default" | "disabled";
|
|
171
|
+
}
|
|
172
|
+
declare class Flagify implements IFlagifyClient {
|
|
173
|
+
private readonly config;
|
|
174
|
+
private flagCache;
|
|
175
|
+
private httpClient;
|
|
176
|
+
private realtime;
|
|
177
|
+
private readyPromise;
|
|
178
|
+
private pollTimer;
|
|
179
|
+
/** Called when a flag changes via SSE. Useful for triggering React re-renders. */
|
|
180
|
+
onFlagChange: ((event: FlagChangeEvent) => void) | null;
|
|
181
|
+
constructor(config: FlagifyOptions);
|
|
182
|
+
/** Resolves when the initial flag sync is complete. */
|
|
183
|
+
ready(): Promise<void>;
|
|
184
|
+
getValue<T>(flagKey: string, fallback: T): T;
|
|
185
|
+
isEnabled(flagKey: string): boolean;
|
|
186
|
+
getVariant(flagKey: string, fallback: string): string;
|
|
187
|
+
evaluate(flagKey: string, user: FlagifyUser): Promise<EvaluateResult>;
|
|
188
|
+
/**
|
|
189
|
+
* Disconnects the realtime listener and cleans up resources.
|
|
190
|
+
*/
|
|
191
|
+
destroy(): void;
|
|
192
|
+
private isStale;
|
|
193
|
+
private refetchFlag;
|
|
194
|
+
private syncFlags;
|
|
195
|
+
private evaluateWithUser;
|
|
196
|
+
private validateConfig;
|
|
197
|
+
private setupPolling;
|
|
198
|
+
private setupRealtimeListener;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Represents a feature flag within the Flagify system.
|
|
203
|
+
*/
|
|
204
|
+
interface FlagifyFlaggy {
|
|
205
|
+
/**
|
|
206
|
+
* Unique identifier for the flag (e.g., "new-dashboard").
|
|
207
|
+
*/
|
|
208
|
+
key: string;
|
|
209
|
+
/**
|
|
210
|
+
* Human-readable name of the flag.
|
|
211
|
+
*/
|
|
212
|
+
name: string;
|
|
213
|
+
/**
|
|
214
|
+
* The current value of the flag, which can be a boolean, string, number, or JSON object.
|
|
215
|
+
* This is the value that will be returned when the flag is evaluated.
|
|
216
|
+
*/
|
|
217
|
+
value: boolean | string | number | Record<string, unknown>;
|
|
218
|
+
/**
|
|
219
|
+
* Detailed description of the flag's purpose.
|
|
220
|
+
*/
|
|
221
|
+
description?: string;
|
|
222
|
+
/**
|
|
223
|
+
* Data type of the flag's value (e.g., "boolean", "string", "number", "json").
|
|
224
|
+
*/
|
|
225
|
+
type: 'boolean' | 'string' | 'number' | 'json';
|
|
226
|
+
/**
|
|
227
|
+
* Default value returned when the flag is enabled but no targeting rules match.
|
|
228
|
+
*/
|
|
229
|
+
defaultValue: boolean | string | number | Record<string, unknown>;
|
|
230
|
+
/**
|
|
231
|
+
* Value returned when the flag is disabled (enabled = false).
|
|
232
|
+
*/
|
|
233
|
+
offValue: boolean | string | number | Record<string, unknown>;
|
|
234
|
+
/**
|
|
235
|
+
* Indicates whether the flag is currently active.
|
|
236
|
+
*/
|
|
237
|
+
enabled: boolean;
|
|
238
|
+
/**
|
|
239
|
+
* Optional rollout percentage (0 to 100) for gradual feature releases.
|
|
240
|
+
*/
|
|
241
|
+
rolloutPercentage?: number;
|
|
242
|
+
/**
|
|
243
|
+
* Optional targeting rules for user segmentation.
|
|
244
|
+
*/
|
|
245
|
+
targetingRules?: Array<{
|
|
246
|
+
priority: number;
|
|
247
|
+
segmentId?: string;
|
|
248
|
+
valueOverride?: unknown;
|
|
249
|
+
rolloutPercentage?: number;
|
|
250
|
+
enabled: boolean;
|
|
251
|
+
conditions?: Array<{
|
|
252
|
+
attribute: string;
|
|
253
|
+
operator: 'equals' | 'not_equals' | 'contains' | 'not_contains' | 'starts_with' | 'ends_with' | 'in' | 'not_in' | 'gt' | 'lt';
|
|
254
|
+
value: unknown;
|
|
255
|
+
}>;
|
|
256
|
+
}>;
|
|
257
|
+
/**
|
|
258
|
+
* Optional multivariate variants for A/B testing.
|
|
259
|
+
*/
|
|
260
|
+
variants?: Array<{
|
|
261
|
+
key: string;
|
|
262
|
+
value: boolean | string | number | Record<string, unknown>;
|
|
263
|
+
weight: number;
|
|
264
|
+
}>;
|
|
265
|
+
/**
|
|
266
|
+
* Timestamp of when the flag was created.
|
|
267
|
+
*/
|
|
268
|
+
createdAt: string;
|
|
269
|
+
/**
|
|
270
|
+
* Timestamp of the last update to the flag.
|
|
271
|
+
*/
|
|
272
|
+
updatedAt: string;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export { type EvaluateResult, type FlagChangeEvent, Flagify, type FlagifyFlaggy, type FlagifyOptions, type FlagifyUser, type IFlagifyClient, type RealtimeEvents, RealtimeListener };
|