@featureflare/sdk-js 0.0.5-beta.188 → 0.0.6

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @featureflare/sdk-js
2
2
 
3
- JavaScript/TypeScript SDK for FeatureFlare feature flags.
3
+ JavaScript/TypeScript SDK for ShipIt feature flags.
4
4
 
5
5
  ## Installation
6
6
 
@@ -17,15 +17,15 @@ yarn add @featureflare/sdk-js
17
17
  ### Basic Example
18
18
 
19
19
  ```typescript
20
- import { FeatureFlareClient } from '@featureflare/sdk-js';
20
+ import { ShipItClient } from '@featureflare/sdk-js';
21
21
 
22
22
  // SDK automatically uses production API URL
23
- // Set FEATUREFLARE_CLIENT_KEY or FEATUREFLARE_SERVER_KEY env var, or pass sdkKey explicitly
24
- const featureflare = new FeatureFlareClient({
23
+ // Set SHIPIT_CLIENT_KEY or SHIPIT_SERVER_KEY env var, or pass sdkKey explicitly
24
+ const shipit = new ShipItClient({
25
25
  sdkKey: 'your-sdk-key-here'
26
26
  });
27
27
 
28
- const enabled = await featureflare.bool('new-nav', { id: 'user-123' }, false);
28
+ const enabled = await shipit.bool('new-nav', { id: 'user-123' }, false);
29
29
  console.log(enabled);
30
30
  ```
31
31
 
@@ -33,38 +33,29 @@ console.log(enabled);
33
33
 
34
34
  The SDK automatically reads from environment variables if `sdkKey` is not provided:
35
35
 
36
- - `FEATUREFLARE_CLIENT_KEY` - Client SDK key (for browser/mobile)
37
- - `FEATUREFLARE_SERVER_KEY` - Server SDK key (for backend)
38
- - `FEATUREFLARE_ENV_KEY` - Expected environment key binding (`development`, `staging`, `production`, etc.)
36
+ - `SHIPIT_CLIENT_KEY` - Client SDK key (for browser/mobile)
37
+ - `SHIPIT_SERVER_KEY` - Server SDK key (for backend)
39
38
 
40
39
  ```typescript
41
- // In Node.js, this will use FEATUREFLARE_CLIENT_KEY or FEATUREFLARE_SERVER_KEY from env
42
- const featureflare = new FeatureFlareClient();
40
+ // In Node.js, this will use SHIPIT_CLIENT_KEY or SHIPIT_SERVER_KEY from env
41
+ const shipit = new ShipItClient();
43
42
  ```
44
43
 
45
44
  ### API Base URL
46
45
 
47
46
  The SDK automatically determines the API base URL:
48
47
 
49
- - **`options.apiBaseUrl`**: Highest priority if provided.
50
- - **Environment variables**: `FEATUREFLARE_API_BASE_URL`, then `SHIPIT_API_BASE_URL`.
51
- - **Default fallback (all runtimes)**: `https://shipit-api-392444455847.us-central1.run.app`.
48
+ - **Browser**: Uses `window.location.origin` (assumes API is on same origin)
49
+ - **Node.js**: Uses the production ShipIt API endpoint
52
50
 
53
- Example override:
54
-
55
- ```typescript
56
- const featureflare = new FeatureFlareClient({
57
- apiBaseUrl: 'https://flags.your-company.com',
58
- sdkKey: 'featureflare_cli_...'
59
- });
60
- ```
51
+ The API URL cannot be overridden.
61
52
 
62
53
  ### User Payload
63
54
 
64
55
  ```typescript
65
- import { FeatureFlareClient, type FeatureFlareUserPayload } from '@featureflare/sdk-js';
56
+ import { ShipItClient, type ShipItUserPayload } from '@featureflare/sdk-js';
66
57
 
67
- const user: FeatureFlareUserPayload = {
58
+ const user: ShipItUserPayload = {
68
59
  id: 'user-123', // Required: unique user identifier
69
60
  email: 'user@example.com',
70
61
  name: 'John Doe',
@@ -75,31 +66,28 @@ const user: FeatureFlareUserPayload = {
75
66
  }
76
67
  };
77
68
 
78
- const enabled = await featureflare.bool('feature-flag', user, false);
69
+ const enabled = await shipit.bool('feature-flag', user, false);
79
70
  ```
80
71
 
81
72
  ## API Reference
82
73
 
83
- ### `FeatureFlareClient`
74
+ ### `ShipItClient`
84
75
 
85
76
  #### Constructor
86
77
 
87
78
  ```typescript
88
- new FeatureFlareClient(options?: FeatureFlareClientOptions)
79
+ new ShipItClient(options?: ShipItClientOptions)
89
80
  ```
90
81
 
91
82
  **Options:**
92
83
 
93
- - `apiBaseUrl?: string` - Explicit FeatureFlare API base URL.
94
- - `sdkKey?: string` - SDK key (client or server). If not provided, reads from `FEATUREFLARE_CLIENT_KEY` or `FEATUREFLARE_SERVER_KEY` env vars.
84
+ - `sdkKey?: string` - SDK key (client or server). If not provided, reads from `SHIPIT_CLIENT_KEY` or `SHIPIT_SERVER_KEY` env vars.
95
85
  - `projectKey?: string` - Legacy: project key (requires `envKey`). Not recommended.
96
86
  - `envKey?: string` - Environment key (default: `'production'`). Only used with `projectKey`.
97
87
 
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
88
  #### Methods
101
89
 
102
- ##### `bool(flagKey: string, user: FeatureFlareUserPayload, defaultValue?: boolean): Promise<boolean>`
90
+ ##### `bool(flagKey: string, user: ShipItUserPayload, defaultValue?: boolean): Promise<boolean>`
103
91
 
104
92
  Evaluates a boolean feature flag for a user.
105
93
 
@@ -112,22 +100,7 @@ Returns `Promise<boolean>` - The flag value for the user.
112
100
  **Example:**
113
101
 
114
102
  ```typescript
115
- const enabled = await featureflare.bool('new-nav', { id: 'user-123' }, false);
116
- ```
117
-
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);
103
+ const enabled = await shipit.bool('new-nav', { id: 'user-123' }, false);
131
104
  ```
132
105
 
133
106
  ## Error Handling
@@ -136,7 +109,7 @@ If the API request fails (network error, non-2xx status), the SDK returns the `d
136
109
 
137
110
  ```typescript
138
111
  try {
139
- const enabled = await featureflare.bool('flag', user, false);
112
+ const enabled = await shipit.bool('flag', user, false);
140
113
  } catch (error) {
141
114
  // Handle network errors
142
115
  console.error('Failed to evaluate flag:', error);
@@ -150,7 +123,7 @@ Each environment has two SDK keys:
150
123
  - **Server key**: Secret. Use only in trusted server environments.
151
124
  - **Client key**: Not a secret. Intended for browser/mobile SDKs.
152
125
 
153
- Get your SDK keys from your FeatureFlare Console → Environments.
126
+ Get your SDK keys from your ShipIt Console → Environments.
154
127
 
155
128
  ## License
156
129
 
package/dist/index.cjs CHANGED
@@ -1,54 +1,35 @@
1
1
  'use strict';
2
2
 
3
3
  // src/index.ts
4
- var DEFAULT_FEATUREFLARE_API_BASE_URL = "https://shipit-api-392444455847.us-central1.run.app";
5
- function getApiBaseUrlFromEnv() {
6
- if (typeof process !== "undefined" && process.env) {
7
- return process.env.FEATUREFLARE_API_BASE_URL?.trim() || process.env.SHIPIT_API_BASE_URL?.trim() || null;
4
+ function getApiBaseUrl() {
5
+ if (typeof window !== "undefined" && typeof window.location !== "undefined") {
6
+ return window.location.origin;
8
7
  }
9
- return null;
10
- }
11
- function getApiBaseUrl(explicit) {
12
- const fromOptions = explicit?.trim();
13
- if (fromOptions) return fromOptions;
14
- const fromEnv = getApiBaseUrlFromEnv();
15
- if (fromEnv) return fromEnv;
16
- return DEFAULT_FEATUREFLARE_API_BASE_URL;
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;
8
+ return "https://shipit-api-246728836834.us-central1.run.app";
23
9
  }
24
10
  function getSdkKeyFromEnv() {
25
11
  if (typeof process !== "undefined" && process.env) {
26
- 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;
12
+ return process.env.SHIPIT_CLIENT_KEY?.trim() || process.env.SHIPIT_SERVER_KEY?.trim() || null;
27
13
  }
28
14
  return null;
29
15
  }
30
- var FeatureFlareClient = class {
16
+ var ShipItClient = class {
31
17
  apiBaseUrl;
32
18
  sdkKey;
33
19
  projectKey;
34
20
  envKey;
35
- expectedEnvKey;
36
21
  constructor(options = {}) {
37
- this.apiBaseUrl = getApiBaseUrl(options.apiBaseUrl).replace(/\/$/, "");
22
+ this.apiBaseUrl = getApiBaseUrl().replace(/\/$/, "");
38
23
  this.sdkKey = options.sdkKey?.trim() || getSdkKeyFromEnv();
39
24
  this.projectKey = options.projectKey?.trim() ? options.projectKey.trim() : null;
40
- const resolvedEnvKey = options.envKey?.trim() || getEnvKeyFromEnv() || "production";
41
- this.envKey = resolvedEnvKey;
42
- this.expectedEnvKey = resolvedEnvKey;
25
+ this.envKey = options.envKey ?? "production";
43
26
  if (!this.sdkKey && !this.projectKey) {
44
- throw new Error(
45
- "FeatureFlareClient requires either sdkKey (recommended) or projectKey (legacy). Set FEATUREFLARE_CLIENT_KEY or FEATUREFLARE_SERVER_KEY env var, or pass sdkKey in options."
46
- );
27
+ throw new Error("ShipItClient requires either sdkKey (recommended) or projectKey (legacy). Set SHIPIT_CLIENT_KEY or SHIPIT_SERVER_KEY env var, or pass sdkKey in options.");
47
28
  }
48
29
  }
49
30
  normalizeUser(input) {
50
31
  const key = (input.id ?? input.key ?? "").trim();
51
- if (!key) throw new Error("FeatureFlareClient requires user.id (or legacy user.key).");
32
+ if (!key) throw new Error("ShipItClient requires user.id (or legacy user.key).");
52
33
  return {
53
34
  key,
54
35
  email: input.email,
@@ -68,8 +49,7 @@ var FeatureFlareClient = class {
68
49
  body: JSON.stringify({
69
50
  flagKey,
70
51
  user: normalizedUser,
71
- defaultValue,
72
- expectedEnvKey: this.expectedEnvKey ?? void 0
52
+ defaultValue
73
53
  })
74
54
  }) : await fetch(`${this.apiBaseUrl}/api/v1/eval`, {
75
55
  method: "POST",
@@ -86,35 +66,8 @@ var FeatureFlareClient = class {
86
66
  const json = await res.json();
87
67
  return json.value;
88
68
  }
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
69
  };
117
70
 
118
- exports.FeatureFlareClient = FeatureFlareClient;
71
+ exports.ShipItClient = ShipItClient;
119
72
  //# sourceMappingURL=index.cjs.map
120
73
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
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 getEnvKeyFromEnv(): string | null {\n if (typeof process !== 'undefined' && process.env) {\n return (\n process.env.FEATUREFLARE_ENV_KEY?.trim() ||\n process.env.SHIPIT_ENV_KEY?.trim() ||\n null\n );\n }\n return null;\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 private readonly expectedEnvKey: string | null;\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 const resolvedEnvKey = options.envKey?.trim() || getEnvKeyFromEnv() || 'production';\n this.envKey = resolvedEnvKey;\n this.expectedEnvKey = resolvedEnvKey;\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 expectedEnvKey: this.expectedEnvKey ?? undefined\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 async flags(user: FeatureFlareUserPayload, defaultValue = false): Promise<Array<{ key: string; value: boolean }>> {\n if (!this.sdkKey) {\n throw new Error('FeatureFlareClient.flags requires sdkKey. Legacy projectKey mode does not support listing all flags.');\n }\n\n const normalizedUser = this.normalizeUser(user);\n const res = await fetch(`${this.apiBaseUrl}/api/v1/sdk/flags`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-featureflare-sdk-key': this.sdkKey\n },\n body: JSON.stringify({\n user: normalizedUser,\n defaultValue,\n expectedEnvKey: this.expectedEnvKey ?? undefined\n })\n });\n\n if (!res.ok) return [];\n const json = (await res.json()) as {\n flags?: Array<{ key: string; value: boolean }>;\n values?: Record<string, boolean>;\n };\n\n if (Array.isArray(json.flags)) {\n return json.flags\n .filter((entry): entry is { key: string; value: boolean } =>\n !!entry && typeof entry.key === 'string' && typeof entry.value === 'boolean'\n )\n .map((entry) => ({ key: entry.key, value: entry.value }));\n }\n\n const values = json.values ?? {};\n return Object.entries(values).map(([key, value]) => ({ key, value: Boolean(value) }));\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["export type ShipItUserPayload = {\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 ShipItUser = {\n key: string;\n email?: string;\n name?: string;\n country?: string;\n custom?: Record<string, string | number | boolean | null>;\n};\n\nfunction getApiBaseUrl(): string {\n // Browser: use current origin (assumes API is on same origin)\n if (typeof window !== 'undefined' && typeof (window as any).location !== 'undefined') {\n return (window as any).location.origin;\n }\n // Node.js: always use production API\n return 'https://shipit-api-246728836834.us-central1.run.app';\n}\n\nexport type ShipItClientOptions = {\n sdkKey?: string;\n projectKey?: string;\n envKey?: string;\n};\n\nfunction getSdkKeyFromEnv(): string | null {\n if (typeof process !== 'undefined' && process.env) {\n return process.env.SHIPIT_CLIENT_KEY?.trim() || process.env.SHIPIT_SERVER_KEY?.trim() || null;\n }\n return null;\n}\n\nexport class ShipItClient {\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: ShipItClientOptions = {}) {\n this.apiBaseUrl = getApiBaseUrl().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('ShipItClient requires either sdkKey (recommended) or projectKey (legacy). Set SHIPIT_CLIENT_KEY or SHIPIT_SERVER_KEY env var, or pass sdkKey in options.');\n }\n }\n\n private normalizeUser(input: ShipItUserPayload): ShipItUser {\n const key = (input.id ?? input.key ?? '').trim();\n if (!key) throw new Error('ShipItClient 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: ShipItUserPayload, 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
@@ -1,4 +1,4 @@
1
- type FeatureFlareUserPayload = {
1
+ type ShipItUserPayload = {
2
2
  /** Unique user identifier (preferred). */
3
3
  id?: string;
4
4
  /** Legacy alias for id. */
@@ -11,25 +11,19 @@ type FeatureFlareUserPayload = {
11
11
  /** Legacy alias for meta. */
12
12
  custom?: Record<string, string | number | boolean | null>;
13
13
  };
14
- type FeatureFlareClientOptions = {
15
- apiBaseUrl?: string;
14
+ type ShipItClientOptions = {
16
15
  sdkKey?: string;
17
16
  projectKey?: string;
18
17
  envKey?: string;
19
18
  };
20
- declare class FeatureFlareClient {
19
+ declare class ShipItClient {
21
20
  private readonly apiBaseUrl;
22
21
  private readonly sdkKey;
23
22
  private readonly projectKey;
24
23
  private readonly envKey;
25
- private readonly expectedEnvKey;
26
- constructor(options?: FeatureFlareClientOptions);
24
+ constructor(options?: ShipItClientOptions);
27
25
  private normalizeUser;
28
- bool(flagKey: string, user: FeatureFlareUserPayload, defaultValue?: boolean): Promise<boolean>;
29
- flags(user: FeatureFlareUserPayload, defaultValue?: boolean): Promise<Array<{
30
- key: string;
31
- value: boolean;
32
- }>>;
26
+ bool(flagKey: string, user: ShipItUserPayload, defaultValue?: boolean): Promise<boolean>;
33
27
  }
34
28
 
35
- export { FeatureFlareClient, type FeatureFlareClientOptions, type FeatureFlareUserPayload };
29
+ export { ShipItClient, type ShipItClientOptions, type ShipItUserPayload };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- type FeatureFlareUserPayload = {
1
+ type ShipItUserPayload = {
2
2
  /** Unique user identifier (preferred). */
3
3
  id?: string;
4
4
  /** Legacy alias for id. */
@@ -11,25 +11,19 @@ type FeatureFlareUserPayload = {
11
11
  /** Legacy alias for meta. */
12
12
  custom?: Record<string, string | number | boolean | null>;
13
13
  };
14
- type FeatureFlareClientOptions = {
15
- apiBaseUrl?: string;
14
+ type ShipItClientOptions = {
16
15
  sdkKey?: string;
17
16
  projectKey?: string;
18
17
  envKey?: string;
19
18
  };
20
- declare class FeatureFlareClient {
19
+ declare class ShipItClient {
21
20
  private readonly apiBaseUrl;
22
21
  private readonly sdkKey;
23
22
  private readonly projectKey;
24
23
  private readonly envKey;
25
- private readonly expectedEnvKey;
26
- constructor(options?: FeatureFlareClientOptions);
24
+ constructor(options?: ShipItClientOptions);
27
25
  private normalizeUser;
28
- bool(flagKey: string, user: FeatureFlareUserPayload, defaultValue?: boolean): Promise<boolean>;
29
- flags(user: FeatureFlareUserPayload, defaultValue?: boolean): Promise<Array<{
30
- key: string;
31
- value: boolean;
32
- }>>;
26
+ bool(flagKey: string, user: ShipItUserPayload, defaultValue?: boolean): Promise<boolean>;
33
27
  }
34
28
 
35
- export { FeatureFlareClient, type FeatureFlareClientOptions, type FeatureFlareUserPayload };
29
+ export { ShipItClient, type ShipItClientOptions, type ShipItUserPayload };
package/dist/index.js CHANGED
@@ -1,52 +1,33 @@
1
1
  // src/index.ts
2
- var DEFAULT_FEATUREFLARE_API_BASE_URL = "https://shipit-api-392444455847.us-central1.run.app";
3
- function getApiBaseUrlFromEnv() {
4
- if (typeof process !== "undefined" && process.env) {
5
- return process.env.FEATUREFLARE_API_BASE_URL?.trim() || process.env.SHIPIT_API_BASE_URL?.trim() || null;
2
+ function getApiBaseUrl() {
3
+ if (typeof window !== "undefined" && typeof window.location !== "undefined") {
4
+ return window.location.origin;
6
5
  }
7
- return null;
8
- }
9
- function getApiBaseUrl(explicit) {
10
- const fromOptions = explicit?.trim();
11
- if (fromOptions) return fromOptions;
12
- const fromEnv = getApiBaseUrlFromEnv();
13
- if (fromEnv) return fromEnv;
14
- return DEFAULT_FEATUREFLARE_API_BASE_URL;
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;
6
+ return "https://shipit-api-246728836834.us-central1.run.app";
21
7
  }
22
8
  function getSdkKeyFromEnv() {
23
9
  if (typeof process !== "undefined" && process.env) {
24
- 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;
10
+ return process.env.SHIPIT_CLIENT_KEY?.trim() || process.env.SHIPIT_SERVER_KEY?.trim() || null;
25
11
  }
26
12
  return null;
27
13
  }
28
- var FeatureFlareClient = class {
14
+ var ShipItClient = class {
29
15
  apiBaseUrl;
30
16
  sdkKey;
31
17
  projectKey;
32
18
  envKey;
33
- expectedEnvKey;
34
19
  constructor(options = {}) {
35
- this.apiBaseUrl = getApiBaseUrl(options.apiBaseUrl).replace(/\/$/, "");
20
+ this.apiBaseUrl = getApiBaseUrl().replace(/\/$/, "");
36
21
  this.sdkKey = options.sdkKey?.trim() || getSdkKeyFromEnv();
37
22
  this.projectKey = options.projectKey?.trim() ? options.projectKey.trim() : null;
38
- const resolvedEnvKey = options.envKey?.trim() || getEnvKeyFromEnv() || "production";
39
- this.envKey = resolvedEnvKey;
40
- this.expectedEnvKey = resolvedEnvKey;
23
+ this.envKey = options.envKey ?? "production";
41
24
  if (!this.sdkKey && !this.projectKey) {
42
- throw new Error(
43
- "FeatureFlareClient requires either sdkKey (recommended) or projectKey (legacy). Set FEATUREFLARE_CLIENT_KEY or FEATUREFLARE_SERVER_KEY env var, or pass sdkKey in options."
44
- );
25
+ throw new Error("ShipItClient requires either sdkKey (recommended) or projectKey (legacy). Set SHIPIT_CLIENT_KEY or SHIPIT_SERVER_KEY env var, or pass sdkKey in options.");
45
26
  }
46
27
  }
47
28
  normalizeUser(input) {
48
29
  const key = (input.id ?? input.key ?? "").trim();
49
- if (!key) throw new Error("FeatureFlareClient requires user.id (or legacy user.key).");
30
+ if (!key) throw new Error("ShipItClient requires user.id (or legacy user.key).");
50
31
  return {
51
32
  key,
52
33
  email: input.email,
@@ -66,8 +47,7 @@ var FeatureFlareClient = class {
66
47
  body: JSON.stringify({
67
48
  flagKey,
68
49
  user: normalizedUser,
69
- defaultValue,
70
- expectedEnvKey: this.expectedEnvKey ?? void 0
50
+ defaultValue
71
51
  })
72
52
  }) : await fetch(`${this.apiBaseUrl}/api/v1/eval`, {
73
53
  method: "POST",
@@ -84,35 +64,8 @@ var FeatureFlareClient = class {
84
64
  const json = await res.json();
85
65
  return json.value;
86
66
  }
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
67
  };
115
68
 
116
- export { FeatureFlareClient };
69
+ export { ShipItClient };
117
70
  //# sourceMappingURL=index.js.map
118
71
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
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 getEnvKeyFromEnv(): string | null {\n if (typeof process !== 'undefined' && process.env) {\n return (\n process.env.FEATUREFLARE_ENV_KEY?.trim() ||\n process.env.SHIPIT_ENV_KEY?.trim() ||\n null\n );\n }\n return null;\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 private readonly expectedEnvKey: string | null;\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 const resolvedEnvKey = options.envKey?.trim() || getEnvKeyFromEnv() || 'production';\n this.envKey = resolvedEnvKey;\n this.expectedEnvKey = resolvedEnvKey;\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 expectedEnvKey: this.expectedEnvKey ?? undefined\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 async flags(user: FeatureFlareUserPayload, defaultValue = false): Promise<Array<{ key: string; value: boolean }>> {\n if (!this.sdkKey) {\n throw new Error('FeatureFlareClient.flags requires sdkKey. Legacy projectKey mode does not support listing all flags.');\n }\n\n const normalizedUser = this.normalizeUser(user);\n const res = await fetch(`${this.apiBaseUrl}/api/v1/sdk/flags`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-featureflare-sdk-key': this.sdkKey\n },\n body: JSON.stringify({\n user: normalizedUser,\n defaultValue,\n expectedEnvKey: this.expectedEnvKey ?? undefined\n })\n });\n\n if (!res.ok) return [];\n const json = (await res.json()) as {\n flags?: Array<{ key: string; value: boolean }>;\n values?: Record<string, boolean>;\n };\n\n if (Array.isArray(json.flags)) {\n return json.flags\n .filter((entry): entry is { key: string; value: boolean } =>\n !!entry && typeof entry.key === 'string' && typeof entry.value === 'boolean'\n )\n .map((entry) => ({ key: entry.key, value: entry.value }));\n }\n\n const values = json.values ?? {};\n return Object.entries(values).map(([key, value]) => ({ key, value: Boolean(value) }));\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export type ShipItUserPayload = {\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 ShipItUser = {\n key: string;\n email?: string;\n name?: string;\n country?: string;\n custom?: Record<string, string | number | boolean | null>;\n};\n\nfunction getApiBaseUrl(): string {\n // Browser: use current origin (assumes API is on same origin)\n if (typeof window !== 'undefined' && typeof (window as any).location !== 'undefined') {\n return (window as any).location.origin;\n }\n // Node.js: always use production API\n return 'https://shipit-api-246728836834.us-central1.run.app';\n}\n\nexport type ShipItClientOptions = {\n sdkKey?: string;\n projectKey?: string;\n envKey?: string;\n};\n\nfunction getSdkKeyFromEnv(): string | null {\n if (typeof process !== 'undefined' && process.env) {\n return process.env.SHIPIT_CLIENT_KEY?.trim() || process.env.SHIPIT_SERVER_KEY?.trim() || null;\n }\n return null;\n}\n\nexport class ShipItClient {\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: ShipItClientOptions = {}) {\n this.apiBaseUrl = getApiBaseUrl().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('ShipItClient requires either sdkKey (recommended) or projectKey (legacy). Set SHIPIT_CLIENT_KEY or SHIPIT_SERVER_KEY env var, or pass sdkKey in options.');\n }\n }\n\n private normalizeUser(input: ShipItUserPayload): ShipItUser {\n const key = (input.id ?? input.key ?? '').trim();\n if (!key) throw new Error('ShipItClient 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: ShipItUserPayload, 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@featureflare/sdk-js",
3
- "version": "0.0.5-beta.188",
3
+ "version": "0.0.6",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"