@featureflare/sdk-js 0.0.5-beta.186 → 0.0.5
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 +0 -18
- package/dist/index.cjs +2 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +0 -5
- package/dist/index.d.ts +0 -5
- package/dist/index.js +2 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -35,7 +35,6 @@ The SDK automatically reads from environment variables if `sdkKey` is not provid
|
|
|
35
35
|
|
|
36
36
|
- `FEATUREFLARE_CLIENT_KEY` - Client SDK key (for browser/mobile)
|
|
37
37
|
- `FEATUREFLARE_SERVER_KEY` - Server SDK key (for backend)
|
|
38
|
-
- `FEATUREFLARE_ENV_KEY` - Expected environment key binding (`development`, `staging`, `production`, etc.)
|
|
39
38
|
|
|
40
39
|
```typescript
|
|
41
40
|
// In Node.js, this will use FEATUREFLARE_CLIENT_KEY or FEATUREFLARE_SERVER_KEY from env
|
|
@@ -95,8 +94,6 @@ new FeatureFlareClient(options?: FeatureFlareClientOptions)
|
|
|
95
94
|
- `projectKey?: string` - Legacy: project key (requires `envKey`). Not recommended.
|
|
96
95
|
- `envKey?: string` - Environment key (default: `'production'`). Only used with `projectKey`.
|
|
97
96
|
|
|
98
|
-
When using `sdkKey`, `envKey` is sent as an expected environment binding. The API rejects requests if the key's actual environment does not match `envKey`.
|
|
99
|
-
|
|
100
97
|
#### Methods
|
|
101
98
|
|
|
102
99
|
##### `bool(flagKey: string, user: FeatureFlareUserPayload, defaultValue?: boolean): Promise<boolean>`
|
|
@@ -115,21 +112,6 @@ Returns `Promise<boolean>` - The flag value for the user.
|
|
|
115
112
|
const enabled = await featureflare.bool('new-nav', { id: 'user-123' }, false);
|
|
116
113
|
```
|
|
117
114
|
|
|
118
|
-
##### `flags(user: FeatureFlareUserPayload, defaultValue?: boolean): Promise<Record<string, boolean>>`
|
|
119
|
-
|
|
120
|
-
Fetches all boolean flags for the provided user.
|
|
121
|
-
|
|
122
|
-
- `user`: User payload with `id` or `key` (required)
|
|
123
|
-
- `defaultValue`: Default value to apply for missing/offline evaluations (default: `false`)
|
|
124
|
-
|
|
125
|
-
Returns `Promise<Record<string, boolean>>` - A map of `flagKey -> value`.
|
|
126
|
-
|
|
127
|
-
**Example:**
|
|
128
|
-
|
|
129
|
-
```typescript
|
|
130
|
-
const allFlags = await featureflare.flags({ id: 'user-123' }, false);
|
|
131
|
-
```
|
|
132
|
-
|
|
133
115
|
## Error Handling
|
|
134
116
|
|
|
135
117
|
If the API request fails (network error, non-2xx status), the SDK returns the `defaultValue`. Network errors (DNS, timeout, connection refused) will throw; wrap calls in `try/catch` if you want to handle them.
|
package/dist/index.cjs
CHANGED
|
@@ -15,12 +15,6 @@ function getApiBaseUrl(explicit) {
|
|
|
15
15
|
if (fromEnv) return fromEnv;
|
|
16
16
|
return DEFAULT_FEATUREFLARE_API_BASE_URL;
|
|
17
17
|
}
|
|
18
|
-
function getEnvKeyFromEnv() {
|
|
19
|
-
if (typeof process !== "undefined" && process.env) {
|
|
20
|
-
return process.env.FEATUREFLARE_ENV_KEY?.trim() || process.env.SHIPIT_ENV_KEY?.trim() || null;
|
|
21
|
-
}
|
|
22
|
-
return null;
|
|
23
|
-
}
|
|
24
18
|
function getSdkKeyFromEnv() {
|
|
25
19
|
if (typeof process !== "undefined" && process.env) {
|
|
26
20
|
return process.env.FEATUREFLARE_CLIENT_KEY?.trim() || process.env.FEATUREFLARE_SERVER_KEY?.trim() || process.env.SHIPIT_CLIENT_KEY?.trim() || process.env.SHIPIT_SERVER_KEY?.trim() || null;
|
|
@@ -32,14 +26,11 @@ var FeatureFlareClient = class {
|
|
|
32
26
|
sdkKey;
|
|
33
27
|
projectKey;
|
|
34
28
|
envKey;
|
|
35
|
-
expectedEnvKey;
|
|
36
29
|
constructor(options = {}) {
|
|
37
30
|
this.apiBaseUrl = getApiBaseUrl(options.apiBaseUrl).replace(/\/$/, "");
|
|
38
31
|
this.sdkKey = options.sdkKey?.trim() || getSdkKeyFromEnv();
|
|
39
32
|
this.projectKey = options.projectKey?.trim() ? options.projectKey.trim() : null;
|
|
40
|
-
|
|
41
|
-
this.envKey = resolvedEnvKey;
|
|
42
|
-
this.expectedEnvKey = resolvedEnvKey;
|
|
33
|
+
this.envKey = options.envKey ?? "production";
|
|
43
34
|
if (!this.sdkKey && !this.projectKey) {
|
|
44
35
|
throw new Error(
|
|
45
36
|
"FeatureFlareClient requires either sdkKey (recommended) or projectKey (legacy). Set FEATUREFLARE_CLIENT_KEY or FEATUREFLARE_SERVER_KEY env var, or pass sdkKey in options."
|
|
@@ -68,8 +59,7 @@ var FeatureFlareClient = class {
|
|
|
68
59
|
body: JSON.stringify({
|
|
69
60
|
flagKey,
|
|
70
61
|
user: normalizedUser,
|
|
71
|
-
defaultValue
|
|
72
|
-
expectedEnvKey: this.expectedEnvKey ?? void 0
|
|
62
|
+
defaultValue
|
|
73
63
|
})
|
|
74
64
|
}) : await fetch(`${this.apiBaseUrl}/api/v1/eval`, {
|
|
75
65
|
method: "POST",
|
|
@@ -86,33 +76,6 @@ var FeatureFlareClient = class {
|
|
|
86
76
|
const json = await res.json();
|
|
87
77
|
return json.value;
|
|
88
78
|
}
|
|
89
|
-
async flags(user, defaultValue = false) {
|
|
90
|
-
if (!this.sdkKey) {
|
|
91
|
-
throw new Error("FeatureFlareClient.flags requires sdkKey. Legacy projectKey mode does not support listing all flags.");
|
|
92
|
-
}
|
|
93
|
-
const normalizedUser = this.normalizeUser(user);
|
|
94
|
-
const res = await fetch(`${this.apiBaseUrl}/api/v1/sdk/flags`, {
|
|
95
|
-
method: "POST",
|
|
96
|
-
headers: {
|
|
97
|
-
"content-type": "application/json",
|
|
98
|
-
"x-featureflare-sdk-key": this.sdkKey
|
|
99
|
-
},
|
|
100
|
-
body: JSON.stringify({
|
|
101
|
-
user: normalizedUser,
|
|
102
|
-
defaultValue,
|
|
103
|
-
expectedEnvKey: this.expectedEnvKey ?? void 0
|
|
104
|
-
})
|
|
105
|
-
});
|
|
106
|
-
if (!res.ok) return [];
|
|
107
|
-
const json = await res.json();
|
|
108
|
-
if (Array.isArray(json.flags)) {
|
|
109
|
-
return json.flags.filter(
|
|
110
|
-
(entry) => !!entry && typeof entry.key === "string" && typeof entry.value === "boolean"
|
|
111
|
-
).map((entry) => ({ key: entry.key, value: entry.value }));
|
|
112
|
-
}
|
|
113
|
-
const values = json.values ?? {};
|
|
114
|
-
return Object.entries(values).map(([key, value]) => ({ key, value: Boolean(value) }));
|
|
115
|
-
}
|
|
116
79
|
};
|
|
117
80
|
|
|
118
81
|
exports.FeatureFlareClient = FeatureFlareClient;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;AAsBA,IAAM,iCAAA,GACJ,qDAAA;AAEF,SAAS,oBAAA,GAAsC;AAC7C,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,CAAQ,GAAA,EAAK;AACjD,IAAA,OACE,OAAA,CAAQ,IAAI,yBAAA,EAA2B,IAAA,MACvC,OAAA,CAAQ,GAAA,CAAI,mBAAA,EAAqB,IAAA,EAAK,IACtC,IAAA;AAAA,EAEJ;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,cAAc,QAAA,EAA2B;AAChD,EAAA,MAAM,WAAA,GAAc,UAAU,IAAA,EAAK;AACnC,EAAA,IAAI,aAAa,OAAO,WAAA;AAExB,EAAA,MAAM,UAAU,oBAAA,EAAqB;AACrC,EAAA,IAAI,SAAS,OAAO,OAAA;AAEpB,EAAA,OAAO,iCAAA;AACT;AASA,SAAS,gBAAA,GAAkC;AACzC,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,CAAQ,GAAA,EAAK;AACjD,IAAA,OACE,
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["export type FeatureFlareUserPayload = {\n /** Unique user identifier (preferred). */\n id?: string;\n /** Legacy alias for id. */\n key?: string;\n email?: string;\n name?: string;\n country?: string;\n /** Queryable attributes. */\n meta?: Record<string, string | number | boolean | null>;\n /** Legacy alias for meta. */\n custom?: Record<string, string | number | boolean | null>;\n};\n\ntype FeatureFlareUser = {\n key: string;\n email?: string;\n name?: string;\n country?: string;\n custom?: Record<string, string | number | boolean | null>;\n};\n\nconst DEFAULT_FEATUREFLARE_API_BASE_URL =\n 'https://shipit-api-392444455847.us-central1.run.app';\n\nfunction getApiBaseUrlFromEnv(): string | null {\n if (typeof process !== 'undefined' && process.env) {\n return (\n process.env.FEATUREFLARE_API_BASE_URL?.trim() ||\n process.env.SHIPIT_API_BASE_URL?.trim() ||\n null\n );\n }\n return null;\n}\n\nfunction getApiBaseUrl(explicit?: string): string {\n const fromOptions = explicit?.trim();\n if (fromOptions) return fromOptions;\n\n const fromEnv = getApiBaseUrlFromEnv();\n if (fromEnv) return fromEnv;\n\n return DEFAULT_FEATUREFLARE_API_BASE_URL;\n}\n\nexport type FeatureFlareClientOptions = {\n apiBaseUrl?: string;\n sdkKey?: string;\n projectKey?: string;\n envKey?: string;\n};\n\nfunction getSdkKeyFromEnv(): string | null {\n if (typeof process !== 'undefined' && process.env) {\n return (\n process.env.FEATUREFLARE_CLIENT_KEY?.trim() ||\n process.env.FEATUREFLARE_SERVER_KEY?.trim() ||\n process.env.SHIPIT_CLIENT_KEY?.trim() ||\n process.env.SHIPIT_SERVER_KEY?.trim() ||\n null\n );\n }\n return null;\n}\n\nexport class FeatureFlareClient {\n private readonly apiBaseUrl: string;\n private readonly sdkKey: string | null;\n private readonly projectKey: string | null;\n private readonly envKey: string;\n\n constructor(options: FeatureFlareClientOptions = {}) {\n this.apiBaseUrl = getApiBaseUrl(options.apiBaseUrl).replace(/\\/$/, '');\n this.sdkKey = options.sdkKey?.trim() || getSdkKeyFromEnv();\n this.projectKey = options.projectKey?.trim() ? options.projectKey.trim() : null;\n this.envKey = options.envKey ?? 'production';\n\n if (!this.sdkKey && !this.projectKey) {\n throw new Error(\n 'FeatureFlareClient requires either sdkKey (recommended) or projectKey (legacy). Set FEATUREFLARE_CLIENT_KEY or FEATUREFLARE_SERVER_KEY env var, or pass sdkKey in options.'\n );\n }\n }\n\n private normalizeUser(input: FeatureFlareUserPayload): FeatureFlareUser {\n const key = (input.id ?? input.key ?? '').trim();\n if (!key) throw new Error('FeatureFlareClient requires user.id (or legacy user.key).');\n return {\n key,\n email: input.email,\n name: input.name,\n country: input.country,\n custom: input.meta ?? input.custom\n };\n }\n\n async bool(flagKey: string, user: FeatureFlareUserPayload, defaultValue = false): Promise<boolean> {\n const normalizedUser = this.normalizeUser(user);\n const res = this.sdkKey\n ? await fetch(`${this.apiBaseUrl}/api/v1/sdk/eval`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-featureflare-sdk-key': this.sdkKey\n },\n body: JSON.stringify({\n flagKey,\n user: normalizedUser,\n defaultValue\n })\n })\n : await fetch(`${this.apiBaseUrl}/api/v1/eval`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n projectKey: this.projectKey,\n envKey: this.envKey,\n flagKey,\n user: normalizedUser,\n defaultValue\n })\n });\n\n if (!res.ok) return defaultValue;\n const json = (await res.json()) as { value: boolean };\n return json.value;\n }\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -22,14 +22,9 @@ declare class FeatureFlareClient {
|
|
|
22
22
|
private readonly sdkKey;
|
|
23
23
|
private readonly projectKey;
|
|
24
24
|
private readonly envKey;
|
|
25
|
-
private readonly expectedEnvKey;
|
|
26
25
|
constructor(options?: FeatureFlareClientOptions);
|
|
27
26
|
private normalizeUser;
|
|
28
27
|
bool(flagKey: string, user: FeatureFlareUserPayload, defaultValue?: boolean): Promise<boolean>;
|
|
29
|
-
flags(user: FeatureFlareUserPayload, defaultValue?: boolean): Promise<Array<{
|
|
30
|
-
key: string;
|
|
31
|
-
value: boolean;
|
|
32
|
-
}>>;
|
|
33
28
|
}
|
|
34
29
|
|
|
35
30
|
export { FeatureFlareClient, type FeatureFlareClientOptions, type FeatureFlareUserPayload };
|
package/dist/index.d.ts
CHANGED
|
@@ -22,14 +22,9 @@ declare class FeatureFlareClient {
|
|
|
22
22
|
private readonly sdkKey;
|
|
23
23
|
private readonly projectKey;
|
|
24
24
|
private readonly envKey;
|
|
25
|
-
private readonly expectedEnvKey;
|
|
26
25
|
constructor(options?: FeatureFlareClientOptions);
|
|
27
26
|
private normalizeUser;
|
|
28
27
|
bool(flagKey: string, user: FeatureFlareUserPayload, defaultValue?: boolean): Promise<boolean>;
|
|
29
|
-
flags(user: FeatureFlareUserPayload, defaultValue?: boolean): Promise<Array<{
|
|
30
|
-
key: string;
|
|
31
|
-
value: boolean;
|
|
32
|
-
}>>;
|
|
33
28
|
}
|
|
34
29
|
|
|
35
30
|
export { FeatureFlareClient, type FeatureFlareClientOptions, type FeatureFlareUserPayload };
|
package/dist/index.js
CHANGED
|
@@ -13,12 +13,6 @@ function getApiBaseUrl(explicit) {
|
|
|
13
13
|
if (fromEnv) return fromEnv;
|
|
14
14
|
return DEFAULT_FEATUREFLARE_API_BASE_URL;
|
|
15
15
|
}
|
|
16
|
-
function getEnvKeyFromEnv() {
|
|
17
|
-
if (typeof process !== "undefined" && process.env) {
|
|
18
|
-
return process.env.FEATUREFLARE_ENV_KEY?.trim() || process.env.SHIPIT_ENV_KEY?.trim() || null;
|
|
19
|
-
}
|
|
20
|
-
return null;
|
|
21
|
-
}
|
|
22
16
|
function getSdkKeyFromEnv() {
|
|
23
17
|
if (typeof process !== "undefined" && process.env) {
|
|
24
18
|
return process.env.FEATUREFLARE_CLIENT_KEY?.trim() || process.env.FEATUREFLARE_SERVER_KEY?.trim() || process.env.SHIPIT_CLIENT_KEY?.trim() || process.env.SHIPIT_SERVER_KEY?.trim() || null;
|
|
@@ -30,14 +24,11 @@ var FeatureFlareClient = class {
|
|
|
30
24
|
sdkKey;
|
|
31
25
|
projectKey;
|
|
32
26
|
envKey;
|
|
33
|
-
expectedEnvKey;
|
|
34
27
|
constructor(options = {}) {
|
|
35
28
|
this.apiBaseUrl = getApiBaseUrl(options.apiBaseUrl).replace(/\/$/, "");
|
|
36
29
|
this.sdkKey = options.sdkKey?.trim() || getSdkKeyFromEnv();
|
|
37
30
|
this.projectKey = options.projectKey?.trim() ? options.projectKey.trim() : null;
|
|
38
|
-
|
|
39
|
-
this.envKey = resolvedEnvKey;
|
|
40
|
-
this.expectedEnvKey = resolvedEnvKey;
|
|
31
|
+
this.envKey = options.envKey ?? "production";
|
|
41
32
|
if (!this.sdkKey && !this.projectKey) {
|
|
42
33
|
throw new Error(
|
|
43
34
|
"FeatureFlareClient requires either sdkKey (recommended) or projectKey (legacy). Set FEATUREFLARE_CLIENT_KEY or FEATUREFLARE_SERVER_KEY env var, or pass sdkKey in options."
|
|
@@ -66,8 +57,7 @@ var FeatureFlareClient = class {
|
|
|
66
57
|
body: JSON.stringify({
|
|
67
58
|
flagKey,
|
|
68
59
|
user: normalizedUser,
|
|
69
|
-
defaultValue
|
|
70
|
-
expectedEnvKey: this.expectedEnvKey ?? void 0
|
|
60
|
+
defaultValue
|
|
71
61
|
})
|
|
72
62
|
}) : await fetch(`${this.apiBaseUrl}/api/v1/eval`, {
|
|
73
63
|
method: "POST",
|
|
@@ -84,33 +74,6 @@ var FeatureFlareClient = class {
|
|
|
84
74
|
const json = await res.json();
|
|
85
75
|
return json.value;
|
|
86
76
|
}
|
|
87
|
-
async flags(user, defaultValue = false) {
|
|
88
|
-
if (!this.sdkKey) {
|
|
89
|
-
throw new Error("FeatureFlareClient.flags requires sdkKey. Legacy projectKey mode does not support listing all flags.");
|
|
90
|
-
}
|
|
91
|
-
const normalizedUser = this.normalizeUser(user);
|
|
92
|
-
const res = await fetch(`${this.apiBaseUrl}/api/v1/sdk/flags`, {
|
|
93
|
-
method: "POST",
|
|
94
|
-
headers: {
|
|
95
|
-
"content-type": "application/json",
|
|
96
|
-
"x-featureflare-sdk-key": this.sdkKey
|
|
97
|
-
},
|
|
98
|
-
body: JSON.stringify({
|
|
99
|
-
user: normalizedUser,
|
|
100
|
-
defaultValue,
|
|
101
|
-
expectedEnvKey: this.expectedEnvKey ?? void 0
|
|
102
|
-
})
|
|
103
|
-
});
|
|
104
|
-
if (!res.ok) return [];
|
|
105
|
-
const json = await res.json();
|
|
106
|
-
if (Array.isArray(json.flags)) {
|
|
107
|
-
return json.flags.filter(
|
|
108
|
-
(entry) => !!entry && typeof entry.key === "string" && typeof entry.value === "boolean"
|
|
109
|
-
).map((entry) => ({ key: entry.key, value: entry.value }));
|
|
110
|
-
}
|
|
111
|
-
const values = json.values ?? {};
|
|
112
|
-
return Object.entries(values).map(([key, value]) => ({ key, value: Boolean(value) }));
|
|
113
|
-
}
|
|
114
77
|
};
|
|
115
78
|
|
|
116
79
|
export { FeatureFlareClient };
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";AAsBA,IAAM,iCAAA,GACJ,qDAAA;AAEF,SAAS,oBAAA,GAAsC;AAC7C,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,CAAQ,GAAA,EAAK;AACjD,IAAA,OACE,OAAA,CAAQ,IAAI,yBAAA,EAA2B,IAAA,MACvC,OAAA,CAAQ,GAAA,CAAI,mBAAA,EAAqB,IAAA,EAAK,IACtC,IAAA;AAAA,EAEJ;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,cAAc,QAAA,EAA2B;AAChD,EAAA,MAAM,WAAA,GAAc,UAAU,IAAA,EAAK;AACnC,EAAA,IAAI,aAAa,OAAO,WAAA;AAExB,EAAA,MAAM,UAAU,oBAAA,EAAqB;AACrC,EAAA,IAAI,SAAS,OAAO,OAAA;AAEpB,EAAA,OAAO,iCAAA;AACT;AASA,SAAS,gBAAA,GAAkC;AACzC,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,CAAQ,GAAA,EAAK;AACjD,IAAA,OACE,
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export type FeatureFlareUserPayload = {\n /** Unique user identifier (preferred). */\n id?: string;\n /** Legacy alias for id. */\n key?: string;\n email?: string;\n name?: string;\n country?: string;\n /** Queryable attributes. */\n meta?: Record<string, string | number | boolean | null>;\n /** Legacy alias for meta. */\n custom?: Record<string, string | number | boolean | null>;\n};\n\ntype FeatureFlareUser = {\n key: string;\n email?: string;\n name?: string;\n country?: string;\n custom?: Record<string, string | number | boolean | null>;\n};\n\nconst DEFAULT_FEATUREFLARE_API_BASE_URL =\n 'https://shipit-api-392444455847.us-central1.run.app';\n\nfunction getApiBaseUrlFromEnv(): string | null {\n if (typeof process !== 'undefined' && process.env) {\n return (\n process.env.FEATUREFLARE_API_BASE_URL?.trim() ||\n process.env.SHIPIT_API_BASE_URL?.trim() ||\n null\n );\n }\n return null;\n}\n\nfunction getApiBaseUrl(explicit?: string): string {\n const fromOptions = explicit?.trim();\n if (fromOptions) return fromOptions;\n\n const fromEnv = getApiBaseUrlFromEnv();\n if (fromEnv) return fromEnv;\n\n return DEFAULT_FEATUREFLARE_API_BASE_URL;\n}\n\nexport type FeatureFlareClientOptions = {\n apiBaseUrl?: string;\n sdkKey?: string;\n projectKey?: string;\n envKey?: string;\n};\n\nfunction getSdkKeyFromEnv(): string | null {\n if (typeof process !== 'undefined' && process.env) {\n return (\n process.env.FEATUREFLARE_CLIENT_KEY?.trim() ||\n process.env.FEATUREFLARE_SERVER_KEY?.trim() ||\n process.env.SHIPIT_CLIENT_KEY?.trim() ||\n process.env.SHIPIT_SERVER_KEY?.trim() ||\n null\n );\n }\n return null;\n}\n\nexport class FeatureFlareClient {\n private readonly apiBaseUrl: string;\n private readonly sdkKey: string | null;\n private readonly projectKey: string | null;\n private readonly envKey: string;\n\n constructor(options: FeatureFlareClientOptions = {}) {\n this.apiBaseUrl = getApiBaseUrl(options.apiBaseUrl).replace(/\\/$/, '');\n this.sdkKey = options.sdkKey?.trim() || getSdkKeyFromEnv();\n this.projectKey = options.projectKey?.trim() ? options.projectKey.trim() : null;\n this.envKey = options.envKey ?? 'production';\n\n if (!this.sdkKey && !this.projectKey) {\n throw new Error(\n 'FeatureFlareClient requires either sdkKey (recommended) or projectKey (legacy). Set FEATUREFLARE_CLIENT_KEY or FEATUREFLARE_SERVER_KEY env var, or pass sdkKey in options.'\n );\n }\n }\n\n private normalizeUser(input: FeatureFlareUserPayload): FeatureFlareUser {\n const key = (input.id ?? input.key ?? '').trim();\n if (!key) throw new Error('FeatureFlareClient requires user.id (or legacy user.key).');\n return {\n key,\n email: input.email,\n name: input.name,\n country: input.country,\n custom: input.meta ?? input.custom\n };\n }\n\n async bool(flagKey: string, user: FeatureFlareUserPayload, defaultValue = false): Promise<boolean> {\n const normalizedUser = this.normalizeUser(user);\n const res = this.sdkKey\n ? await fetch(`${this.apiBaseUrl}/api/v1/sdk/eval`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-featureflare-sdk-key': this.sdkKey\n },\n body: JSON.stringify({\n flagKey,\n user: normalizedUser,\n defaultValue\n })\n })\n : await fetch(`${this.apiBaseUrl}/api/v1/eval`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n projectKey: this.projectKey,\n envKey: this.envKey,\n flagKey,\n user: normalizedUser,\n defaultValue\n })\n });\n\n if (!res.ok) return defaultValue;\n const json = (await res.json()) as { value: boolean };\n return json.value;\n }\n}\n"]}
|