@hyphen/sdk 1.0.1 → 1.0.3

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,4 +1,4 @@
1
- ![Hyphen AI](logo.svg)
1
+ ![Hyphen AI](https://github.com/Hyphen/nodejs-sdk/raw/main/logo.svg)
2
2
 
3
3
  [![tests](https://github.com/Hyphen/nodejs-sdk/actions/workflows/tests.yaml/badge.svg)](https://github.com/Hyphen/nodejs-sdk/actions/workflows/tests.yaml)
4
4
  [![npm](https://img.shields.io/npm/v/@hyphen/sdk)](https://www.npmjs.com/package/@hyphen/sdk)
@@ -9,6 +9,19 @@
9
9
 
10
10
  The Hyphen Node.js SDK is a JavaScript library that allows developers to easily integrate Hyphen's feature flagging and experimentation capabilities into their Node.js applications. With this SDK, you can manage feature flags more effectively, enabling you to control the rollout of new features and conduct A/B testing with ease.
11
11
 
12
+ # Table of Contents
13
+ - [Hyphen Node.js SDK](#hyphen-nodejs-sdk)
14
+ - [Installation](#installation)
15
+ - [Basic Usage](#basic-usage)
16
+ - [Toggle](#toggle)
17
+ - [Toggle Options](#toggle-options)
18
+ - [Toggle API](#toggle-api)
19
+ - [Toggle Hooks](#toggle-hooks)
20
+ - [Toggle Error Handling](#toggle-error-handling)
21
+ - [Contributing](#contributing)
22
+ - [Testing Your Changes](#testing-your-changes)
23
+ - [License and Copyright](#license-and-copyright)
24
+
12
25
  # Installation
13
26
 
14
27
  To install the Hyphen Node.js SDK, you can use npm or yarn. Run the following command in your terminal:
@@ -17,7 +30,7 @@ To install the Hyphen Node.js SDK, you can use npm or yarn. Run the following co
17
30
  npm install @hyphen/sdk
18
31
  ```
19
32
 
20
- # Usage
33
+ # Basic Usage
21
34
 
22
35
  There are many ways to use the Hyphen Node.js SDK. Because of this we have created examples for each of the different ways in each secton of the documentation.
23
36
 
@@ -26,9 +39,9 @@ There are many ways to use the Hyphen Node.js SDK. Because of this we have creat
26
39
  [Toggle](https://hyphen.ai/toggle) is our feature flag service that allows you to control the rollout of new features to your users. You can access your feature flags using the `Toggle` class.
27
40
 
28
41
  ```javascript
29
- import { Toggle, Context } from '@hyphen/sdk';
42
+ import { Toggle, ToggleContext } from '@hyphen/sdk';
30
43
 
31
- const context: Context = {
44
+ const context: ToggleContext = {
32
45
  targetingKey: 'user-123',
33
46
  ipAddress: '203.0.113.42',
34
47
  customAttributes: {
@@ -61,9 +74,9 @@ console.log('Boolean toggle value:', result); // true
61
74
  if you want to set the context you can do it like this:
62
75
 
63
76
  ```javascript
64
- import { Toggle, Context } from '@hyphen/sdk';
77
+ import { Toggle, ToggleContext } from '@hyphen/sdk';
65
78
 
66
- const context: Context = {
79
+ const context: ToggleContext = {
67
80
  targetingKey: 'user-123',
68
81
  ipAddress: '203.0.113.42',
69
82
  customAttributes: {
@@ -97,9 +110,9 @@ console.log('Boolean toggle value:', result); // true
97
110
  if you would like to override the context for a single request you can do it like this:
98
111
 
99
112
  ```javascript
100
- import { Toggle, Context } from '@hyphen/sdk';
113
+ import { Toggle, ToggleContext } from '@hyphen/sdk';
101
114
 
102
- const context: Context = {
115
+ const context: ToggleContext = {
103
116
  targetingKey: 'user-123',
104
117
  ipAddress: '203.0.113.42',
105
118
  customAttributes: {
@@ -122,7 +135,7 @@ const toggleOptions = {
122
135
  context: context,
123
136
  };
124
137
 
125
- const overrideContext: Context = {
138
+ const overrideContext: ToggleContext = {
126
139
  targetingKey: 'user-123',
127
140
  ipAddress: '203.0.113.42',
128
141
  customAttributes: {
@@ -153,19 +166,19 @@ console.log('Boolean toggle value:', result); // true
153
166
  | *publicApiKey* | ` string` | The public API key for your Hyphen project. You can find this in the Hyphen dashboard. |
154
167
  | *applicationId* | `string` | The application ID for your Hyphen project. You can find this in the Hyphen dashboard. |
155
168
  | *environment?* | `string` | The environment for your Hyphen project such as `production`. Default uses `process.env.NODE_ENV` |
156
- | *context?* | `Context` | The context object that contains the user and custom attributes. This is optional. |
169
+ | *context?* | `ToggleContext` | The context object that contains the user and custom attributes. This is optional. |
157
170
  | *cache?* | `{ ttl: number}` | Whether to use the cache or not. |
158
171
 
159
172
  ## Toggle API
160
173
 
161
174
  | Method | Parameters | Description |
162
175
  |----------------|----------------|----------------|
163
- | *setContext* | `context: Context` | Set the context for the toggle. This is optional. |
164
- | *get<Type>* | `key: string, defaultValue: T, options?: { context?: Context }` | Get the value of a toggle. This is a generic method that can be used to get any type from toggle. |
165
- | *getBoolean* | `key: string, defaultValue: boolean, options?: { context?: Context }` | Get the value of a boolean toggle. |
166
- | *getNumber* | `key: string, defaultValue: number, options?: { context?: Context }` | Get the value of a number toggle. |
167
- | *getString* | `key: string, defaultValue: string, options?: { context?: Context }` | Get the value of a string toggle. |
168
- | *getObject<Type>* | `key: string, defaultValue: any, options?: { context?: Context }` | Get the value of a object toggle. |
176
+ | *setContext* | `context: ToggleContext` | Set the context for the toggle. This is optional. |
177
+ | *get<Type>* | `key: string, defaultValue: T, options?: ToggleRequestOptions` | Get the value of a toggle. This is a generic method that can be used to get any type from toggle. |
178
+ | *getBoolean* | `key: string, defaultValue: boolean, options?: ToggleRequestOptions` | Get the value of a boolean toggle. |
179
+ | *getNumber* | `key: string, defaultValue: number, options?: ToggleRequestOptions` | Get the value of a number toggle. |
180
+ | *getString* | `key: string, defaultValue: string, options?: ToggleRequestOptions` | Get the value of a string toggle. |
181
+ | *getObject<Type>* | `key: string, defaultValue: any, options?: ToggleRequestOptions` | Get the value of a object toggle. |
169
182
 
170
183
  ## Toggle Hooks
171
184
 
@@ -184,9 +197,9 @@ The following hooks are available for Toggle:
184
197
  You can use the hooks to modify the request or the response. For example, you can use the `beforeGetBoolean` hook to log the request before it is sent to the server.
185
198
 
186
199
  ```javascript
187
- import { Toggle, ToggleHooks, Context } from '@hyphen/sdk';
200
+ import { Toggle, ToggleHooks, ToggleContext } from '@hyphen/sdk';
188
201
 
189
- const context: Context = {
202
+ const context: ToggleContext = {
190
203
  targetingKey: 'user-123',
191
204
  ipAddress: '203.0.113.42',
192
205
  customAttributes: {
@@ -220,6 +233,84 @@ const result = await toggle.getBoolean('hyphen-sdk-boolean', false);
220
233
  console.log('Boolean toggle value:', result); // true
221
234
  ```
222
235
 
236
+ ## Toggle Error Handling
237
+
238
+ The SDK provides a way to handle errors that occur during the toggle request. You can use the `.on` method to handle errors globally.
239
+
240
+ ```javascript
241
+ import { Toggle, ToggleContext } from '@hyphen/sdk';
242
+
243
+ const context: ToggleContext = {
244
+ targetingKey: 'user-123',
245
+ ipAddress: '203.0.113.42',
246
+ customAttributes: {
247
+ subscriptionLevel: 'premium',
248
+ region: 'us-east',
249
+ },
250
+ user: {
251
+ id: 'user-123',
252
+ email: 'john.doe@example.com',
253
+ name: 'John Doe',
254
+ customAttributes: {
255
+ role: 'admin',
256
+ },
257
+ },
258
+ };
259
+
260
+ const toggleOptions = {
261
+ publicApiKey: 'your_public_api_key',
262
+ applicationId: 'your_application_id',
263
+ context: context,
264
+ };
265
+
266
+ const toggle = new Toggle(toggleOptions);
267
+ toggle.on('error', (error) => {
268
+ console.error('Error fetching toggle:', error);
269
+ });
270
+
271
+ const result = await toggle.getBoolean('hyphen-sdk-boolean', false);
272
+ console.log('Boolean toggle value:', result); // true
273
+ ```
274
+
275
+ If you would like to have the errors thrown you can use the `throwErrors` option in the constructor:
276
+
277
+ ```javascript
278
+ import { Toggle, ToggleContext } from '@hyphen/sdk';
279
+
280
+ const context: ToggleContext = {
281
+ targetingKey: 'user-123',
282
+ ipAddress: '203.0.113.42',
283
+ customAttributes: {
284
+ subscriptionLevel: 'premium',
285
+ region: 'us-east',
286
+ },
287
+ user: {
288
+ id: 'user-123',
289
+ email: 'john.doe@example.com',
290
+ name: 'John Doe',
291
+ customAttributes: {
292
+ role: 'admin',
293
+ },
294
+ },
295
+ };
296
+
297
+ const toggleOptions = {
298
+ publicApiKey: 'your_public_api_key',
299
+ applicationId: 'your_application_id',
300
+ context: context,
301
+ throwErrors: true,
302
+ };
303
+
304
+ const toggle = new Toggle(toggleOptions);
305
+
306
+ try {
307
+ const result = await toggle.getBoolean('hyphen-sdk-boolean', false);
308
+ console.log('Boolean toggle value:', result); // true
309
+ } catch (error) {
310
+ console.error('Error fetching toggle:', error);
311
+ }
312
+ ```
313
+
223
314
  # Contributing
224
315
 
225
316
  We welcome contributions to the Hyphen Node.js SDK! If you have an idea for a new feature, bug fix, or improvement, please follow these steps:
package/dist/index.cjs ADDED
@@ -0,0 +1,243 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+
31
+ // src/index.ts
32
+ var index_exports = {};
33
+ __export(index_exports, {
34
+ Toggle: () => Toggle,
35
+ ToggleHooks: () => ToggleHooks
36
+ });
37
+ module.exports = __toCommonJS(index_exports);
38
+
39
+ // src/toggle.ts
40
+ var import_node_process = __toESM(require("process"), 1);
41
+ var import_hookified = require("hookified");
42
+ var import_server_sdk = require("@openfeature/server-sdk");
43
+ var import_openfeature_server_provider = require("@hyphen/openfeature-server-provider");
44
+ var ToggleHooks = /* @__PURE__ */ function(ToggleHooks2) {
45
+ ToggleHooks2["beforeGetBoolean"] = "beforeGetBoolean";
46
+ ToggleHooks2["afterGetBoolean"] = "afterGetBoolean";
47
+ ToggleHooks2["beforeGetString"] = "beforeGetString";
48
+ ToggleHooks2["afterGetString"] = "afterGetString";
49
+ ToggleHooks2["beforeGetNumber"] = "beforeGetNumber";
50
+ ToggleHooks2["afterGetNumber"] = "afterGetNumber";
51
+ ToggleHooks2["beforeGetObject"] = "beforeGetObject";
52
+ ToggleHooks2["afterGetObject"] = "afterGetObject";
53
+ return ToggleHooks2;
54
+ }({});
55
+ var Toggle = class extends import_hookified.Hookified {
56
+ static {
57
+ __name(this, "Toggle");
58
+ }
59
+ _applicationId;
60
+ _publicKey;
61
+ _environment;
62
+ _client;
63
+ _context;
64
+ _throwErrors = false;
65
+ constructor(options) {
66
+ super();
67
+ this._applicationId = options.applicationId;
68
+ this._publicKey = options.publicKey;
69
+ this._environment = options.environment ?? import_node_process.default.env.NODE_ENV ?? "development";
70
+ this._context = options.context;
71
+ this._throwErrors = options.throwErrors ?? false;
72
+ }
73
+ get applicationId() {
74
+ return this._applicationId;
75
+ }
76
+ set applicationId(value) {
77
+ this._applicationId = value;
78
+ }
79
+ get publicKey() {
80
+ return this._publicKey;
81
+ }
82
+ set publicKey(value) {
83
+ this._publicKey = value;
84
+ }
85
+ get environment() {
86
+ return this._environment;
87
+ }
88
+ set environment(value) {
89
+ this._environment = value;
90
+ }
91
+ get throwErrors() {
92
+ return this._throwErrors;
93
+ }
94
+ set throwErrors(value) {
95
+ this._throwErrors = value;
96
+ }
97
+ get context() {
98
+ return this._context;
99
+ }
100
+ set context(value) {
101
+ this._context = value;
102
+ }
103
+ setContext(context) {
104
+ this._context = context;
105
+ this._client = void 0;
106
+ }
107
+ async getClient() {
108
+ if (!this._client) {
109
+ const options = {
110
+ application: this._applicationId,
111
+ environment: this._environment
112
+ };
113
+ await import_server_sdk.OpenFeature.setProviderAndWait(new import_openfeature_server_provider.HyphenProvider(this._publicKey, options));
114
+ this._client = import_server_sdk.OpenFeature.getClient(this._context);
115
+ }
116
+ return this._client;
117
+ }
118
+ async get(key, defaultValue, options) {
119
+ switch (typeof defaultValue) {
120
+ case "boolean": {
121
+ return this.getBoolean(key, defaultValue, options);
122
+ }
123
+ case "string": {
124
+ return this.getString(key, defaultValue, options);
125
+ }
126
+ case "number": {
127
+ return this.getNumber(key, defaultValue, options);
128
+ }
129
+ default: {
130
+ return this.getObject(key, defaultValue, options);
131
+ }
132
+ }
133
+ }
134
+ async getBoolean(key, defaultValue, options) {
135
+ try {
136
+ const data = {
137
+ key,
138
+ defaultValue,
139
+ options
140
+ };
141
+ await this.hook("beforeGetBoolean", data);
142
+ const client = await this.getClient();
143
+ const result = await client.getBooleanValue(data.key, data.defaultValue, data.options?.context);
144
+ const resultData = {
145
+ key,
146
+ defaultValue,
147
+ options,
148
+ result
149
+ };
150
+ await this.hook("afterGetBoolean", resultData);
151
+ return resultData.result;
152
+ } catch (error) {
153
+ this.emit("error", error);
154
+ if (this._throwErrors) {
155
+ throw error;
156
+ }
157
+ }
158
+ return defaultValue;
159
+ }
160
+ async getString(key, defaultValue, options) {
161
+ try {
162
+ const data = {
163
+ key,
164
+ defaultValue,
165
+ options
166
+ };
167
+ await this.hook("beforeGetString", data);
168
+ const client = await this.getClient();
169
+ const result = await client.getStringValue(data.key, data.defaultValue, data.options?.context);
170
+ const resultData = {
171
+ key,
172
+ defaultValue,
173
+ options,
174
+ result
175
+ };
176
+ await this.hook("afterGetString", resultData);
177
+ return resultData.result;
178
+ } catch (error) {
179
+ this.emit("error", error);
180
+ if (this._throwErrors) {
181
+ throw error;
182
+ }
183
+ }
184
+ return defaultValue;
185
+ }
186
+ async getNumber(key, defaultValue, options) {
187
+ try {
188
+ const data = {
189
+ key,
190
+ defaultValue,
191
+ options
192
+ };
193
+ await this.hook("beforeGetNumber", data);
194
+ const client = await this.getClient();
195
+ const result = await client.getNumberValue(data.key, data.defaultValue, data.options?.context);
196
+ const resultData = {
197
+ key,
198
+ defaultValue,
199
+ options,
200
+ result
201
+ };
202
+ await this.hook("afterGetNumber", resultData);
203
+ return resultData.result;
204
+ } catch (error) {
205
+ this.emit("error", error);
206
+ if (this._throwErrors) {
207
+ throw error;
208
+ }
209
+ }
210
+ return defaultValue;
211
+ }
212
+ async getObject(key, defaultValue, options) {
213
+ try {
214
+ const data = {
215
+ key,
216
+ defaultValue,
217
+ options
218
+ };
219
+ await this.hook("beforeGetObject", data);
220
+ const client = await this.getClient();
221
+ const result = await client.getObjectValue(key, defaultValue, data.options?.context);
222
+ const resultData = {
223
+ key,
224
+ defaultValue,
225
+ options,
226
+ result
227
+ };
228
+ await this.hook("afterGetObject", resultData);
229
+ return resultData.result;
230
+ } catch (error) {
231
+ this.emit("error", error);
232
+ if (this._throwErrors) {
233
+ throw error;
234
+ }
235
+ }
236
+ return defaultValue;
237
+ }
238
+ };
239
+ // Annotate the CommonJS export names for ESM import in node:
240
+ 0 && (module.exports = {
241
+ Toggle,
242
+ ToggleHooks
243
+ });
@@ -0,0 +1,81 @@
1
+ import { Hookified } from 'hookified';
2
+ import { EvaluationContext, Client } from '@openfeature/server-sdk';
3
+
4
+ type ToggleContext = EvaluationContext;
5
+ declare enum ToggleHooks {
6
+ beforeGetBoolean = "beforeGetBoolean",
7
+ afterGetBoolean = "afterGetBoolean",
8
+ beforeGetString = "beforeGetString",
9
+ afterGetString = "afterGetString",
10
+ beforeGetNumber = "beforeGetNumber",
11
+ afterGetNumber = "afterGetNumber",
12
+ beforeGetObject = "beforeGetObject",
13
+ afterGetObject = "afterGetObject"
14
+ }
15
+ type ToggleOptions = {
16
+ /**
17
+ * Your application name
18
+ * @type {string}
19
+ */
20
+ applicationId: string;
21
+ /**
22
+ * Your Hyphen API key
23
+ * @type {string}
24
+ */
25
+ publicKey: string;
26
+ /**
27
+ * Your environment name such as development, production. Default is what is set at NODE_ENV
28
+ * @type {string}
29
+ * @example production
30
+ */
31
+ environment?: string;
32
+ /**
33
+ * The context to use for evaluating feature flags
34
+ * @type {ToggleContext}
35
+ */
36
+ context?: ToggleContext;
37
+ caching?: {
38
+ /**
39
+ * The time in seconds to cache the feature flag values
40
+ * @type {number} - this is in milliseconds
41
+ */
42
+ ttl?: number;
43
+ };
44
+ /**
45
+ * Throw errors in addition to emitting them
46
+ * @type {boolean}
47
+ * @default false
48
+ */
49
+ throwErrors?: boolean;
50
+ };
51
+ type ToggleRequestOptions = {
52
+ context?: ToggleContext;
53
+ };
54
+ declare class Toggle extends Hookified {
55
+ private _applicationId;
56
+ private _publicKey;
57
+ private _environment;
58
+ private _client;
59
+ private _context;
60
+ private _throwErrors;
61
+ constructor(options: ToggleOptions);
62
+ get applicationId(): string;
63
+ set applicationId(value: string);
64
+ get publicKey(): string;
65
+ set publicKey(value: string);
66
+ get environment(): string;
67
+ set environment(value: string);
68
+ get throwErrors(): boolean;
69
+ set throwErrors(value: boolean);
70
+ get context(): ToggleContext | undefined;
71
+ set context(value: ToggleContext | undefined);
72
+ setContext(context: ToggleContext): void;
73
+ getClient(): Promise<Client>;
74
+ get<T>(key: string, defaultValue: T, options?: ToggleRequestOptions): Promise<T>;
75
+ getBoolean(key: string, defaultValue: boolean, options?: ToggleRequestOptions): Promise<boolean>;
76
+ getString(key: string, defaultValue: string, options?: ToggleRequestOptions): Promise<string>;
77
+ getNumber(key: string, defaultValue: number, options?: ToggleRequestOptions): Promise<number>;
78
+ getObject<T>(key: string, defaultValue: T, options?: ToggleRequestOptions): Promise<T>;
79
+ }
80
+
81
+ export { Toggle, type ToggleContext, ToggleHooks, type ToggleOptions, type ToggleRequestOptions };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,17 @@
1
1
  import { Hookified } from 'hookified';
2
2
  import { EvaluationContext, Client } from '@openfeature/server-sdk';
3
3
 
4
- type Context = EvaluationContext;
4
+ type ToggleContext = EvaluationContext;
5
+ declare enum ToggleHooks {
6
+ beforeGetBoolean = "beforeGetBoolean",
7
+ afterGetBoolean = "afterGetBoolean",
8
+ beforeGetString = "beforeGetString",
9
+ afterGetString = "afterGetString",
10
+ beforeGetNumber = "beforeGetNumber",
11
+ afterGetNumber = "afterGetNumber",
12
+ beforeGetObject = "beforeGetObject",
13
+ afterGetObject = "afterGetObject"
14
+ }
5
15
  type ToggleOptions = {
6
16
  /**
7
17
  * Your application name
@@ -21,9 +31,9 @@ type ToggleOptions = {
21
31
  environment?: string;
22
32
  /**
23
33
  * The context to use for evaluating feature flags
24
- * @type {Context}
34
+ * @type {ToggleContext}
25
35
  */
26
- context?: Context;
36
+ context?: ToggleContext;
27
37
  caching?: {
28
38
  /**
29
39
  * The time in seconds to cache the feature flag values
@@ -31,9 +41,15 @@ type ToggleOptions = {
31
41
  */
32
42
  ttl?: number;
33
43
  };
44
+ /**
45
+ * Throw errors in addition to emitting them
46
+ * @type {boolean}
47
+ * @default false
48
+ */
49
+ throwErrors?: boolean;
34
50
  };
35
51
  type ToggleRequestOptions = {
36
- context?: Context;
52
+ context?: ToggleContext;
37
53
  };
38
54
  declare class Toggle extends Hookified {
39
55
  private _applicationId;
@@ -41,6 +57,7 @@ declare class Toggle extends Hookified {
41
57
  private _environment;
42
58
  private _client;
43
59
  private _context;
60
+ private _throwErrors;
44
61
  constructor(options: ToggleOptions);
45
62
  get applicationId(): string;
46
63
  set applicationId(value: string);
@@ -48,7 +65,11 @@ declare class Toggle extends Hookified {
48
65
  set publicKey(value: string);
49
66
  get environment(): string;
50
67
  set environment(value: string);
51
- setContext(context: Context): void;
68
+ get throwErrors(): boolean;
69
+ set throwErrors(value: boolean);
70
+ get context(): ToggleContext | undefined;
71
+ set context(value: ToggleContext | undefined);
72
+ setContext(context: ToggleContext): void;
52
73
  getClient(): Promise<Client>;
53
74
  get<T>(key: string, defaultValue: T, options?: ToggleRequestOptions): Promise<T>;
54
75
  getBoolean(key: string, defaultValue: boolean, options?: ToggleRequestOptions): Promise<boolean>;
@@ -57,4 +78,4 @@ declare class Toggle extends Hookified {
57
78
  getObject<T>(key: string, defaultValue: T, options?: ToggleRequestOptions): Promise<T>;
58
79
  }
59
80
 
60
- export { Toggle };
81
+ export { Toggle, type ToggleContext, ToggleHooks, type ToggleOptions, type ToggleRequestOptions };
package/dist/index.js CHANGED
@@ -6,6 +6,17 @@ import process from "node:process";
6
6
  import { Hookified } from "hookified";
7
7
  import { OpenFeature } from "@openfeature/server-sdk";
8
8
  import { HyphenProvider } from "@hyphen/openfeature-server-provider";
9
+ var ToggleHooks = /* @__PURE__ */ function(ToggleHooks2) {
10
+ ToggleHooks2["beforeGetBoolean"] = "beforeGetBoolean";
11
+ ToggleHooks2["afterGetBoolean"] = "afterGetBoolean";
12
+ ToggleHooks2["beforeGetString"] = "beforeGetString";
13
+ ToggleHooks2["afterGetString"] = "afterGetString";
14
+ ToggleHooks2["beforeGetNumber"] = "beforeGetNumber";
15
+ ToggleHooks2["afterGetNumber"] = "afterGetNumber";
16
+ ToggleHooks2["beforeGetObject"] = "beforeGetObject";
17
+ ToggleHooks2["afterGetObject"] = "afterGetObject";
18
+ return ToggleHooks2;
19
+ }({});
9
20
  var Toggle = class extends Hookified {
10
21
  static {
11
22
  __name(this, "Toggle");
@@ -15,12 +26,14 @@ var Toggle = class extends Hookified {
15
26
  _environment;
16
27
  _client;
17
28
  _context;
29
+ _throwErrors = false;
18
30
  constructor(options) {
19
31
  super();
20
32
  this._applicationId = options.applicationId;
21
33
  this._publicKey = options.publicKey;
22
34
  this._environment = options.environment ?? process.env.NODE_ENV ?? "development";
23
35
  this._context = options.context;
36
+ this._throwErrors = options.throwErrors ?? false;
24
37
  }
25
38
  get applicationId() {
26
39
  return this._applicationId;
@@ -40,6 +53,18 @@ var Toggle = class extends Hookified {
40
53
  set environment(value) {
41
54
  this._environment = value;
42
55
  }
56
+ get throwErrors() {
57
+ return this._throwErrors;
58
+ }
59
+ set throwErrors(value) {
60
+ this._throwErrors = value;
61
+ }
62
+ get context() {
63
+ return this._context;
64
+ }
65
+ set context(value) {
66
+ this._context = value;
67
+ }
43
68
  setContext(context) {
44
69
  this._context = context;
45
70
  this._client = void 0;
@@ -72,78 +97,111 @@ var Toggle = class extends Hookified {
72
97
  }
73
98
  }
74
99
  async getBoolean(key, defaultValue, options) {
75
- const data = {
76
- key,
77
- defaultValue,
78
- options
79
- };
80
- await this.hook("beforeGetBoolean", data);
81
- const client = await this.getClient();
82
- const result = await client.getBooleanValue(data.key, data.defaultValue, data.options?.context);
83
- const resultData = {
84
- key,
85
- defaultValue,
86
- options,
87
- result
88
- };
89
- await this.hook("afterGetBoolean", resultData);
90
- return resultData.result;
100
+ try {
101
+ const data = {
102
+ key,
103
+ defaultValue,
104
+ options
105
+ };
106
+ await this.hook("beforeGetBoolean", data);
107
+ const client = await this.getClient();
108
+ const result = await client.getBooleanValue(data.key, data.defaultValue, data.options?.context);
109
+ const resultData = {
110
+ key,
111
+ defaultValue,
112
+ options,
113
+ result
114
+ };
115
+ await this.hook("afterGetBoolean", resultData);
116
+ return resultData.result;
117
+ } catch (error) {
118
+ this.emit("error", error);
119
+ if (this._throwErrors) {
120
+ throw error;
121
+ }
122
+ }
123
+ return defaultValue;
91
124
  }
92
125
  async getString(key, defaultValue, options) {
93
- const data = {
94
- key,
95
- defaultValue,
96
- options
97
- };
98
- await this.hook("beforeGetString", data);
99
- const client = await this.getClient();
100
- const result = await client.getStringValue(data.key, data.defaultValue, data.options?.context);
101
- const resultData = {
102
- key,
103
- defaultValue,
104
- options,
105
- result
106
- };
107
- await this.hook("afterGetString", resultData);
108
- return resultData.result;
126
+ try {
127
+ const data = {
128
+ key,
129
+ defaultValue,
130
+ options
131
+ };
132
+ await this.hook("beforeGetString", data);
133
+ const client = await this.getClient();
134
+ const result = await client.getStringValue(data.key, data.defaultValue, data.options?.context);
135
+ const resultData = {
136
+ key,
137
+ defaultValue,
138
+ options,
139
+ result
140
+ };
141
+ await this.hook("afterGetString", resultData);
142
+ return resultData.result;
143
+ } catch (error) {
144
+ this.emit("error", error);
145
+ if (this._throwErrors) {
146
+ throw error;
147
+ }
148
+ }
149
+ return defaultValue;
109
150
  }
110
151
  async getNumber(key, defaultValue, options) {
111
- const data = {
112
- key,
113
- defaultValue,
114
- options
115
- };
116
- await this.hook("beforeGetNumber", data);
117
- const client = await this.getClient();
118
- const result = await client.getNumberValue(data.key, data.defaultValue, data.options?.context);
119
- const resultData = {
120
- key,
121
- defaultValue,
122
- options,
123
- result
124
- };
125
- await this.hook("afterGetNumber", resultData);
126
- return resultData.result;
152
+ try {
153
+ const data = {
154
+ key,
155
+ defaultValue,
156
+ options
157
+ };
158
+ await this.hook("beforeGetNumber", data);
159
+ const client = await this.getClient();
160
+ const result = await client.getNumberValue(data.key, data.defaultValue, data.options?.context);
161
+ const resultData = {
162
+ key,
163
+ defaultValue,
164
+ options,
165
+ result
166
+ };
167
+ await this.hook("afterGetNumber", resultData);
168
+ return resultData.result;
169
+ } catch (error) {
170
+ this.emit("error", error);
171
+ if (this._throwErrors) {
172
+ throw error;
173
+ }
174
+ }
175
+ return defaultValue;
127
176
  }
128
177
  async getObject(key, defaultValue, options) {
129
- const data = {
130
- key,
131
- defaultValue,
132
- options
133
- };
134
- await this.hook("beforeGetObject", data);
135
- const client = await this.getClient();
136
- const result = await client.getObjectValue(key, defaultValue, data.options?.context);
137
- const resultData = {
138
- key,
139
- defaultValue,
140
- options,
141
- result
142
- };
143
- await this.hook("afterGetObject", resultData);
144
- return resultData.result;
178
+ try {
179
+ const data = {
180
+ key,
181
+ defaultValue,
182
+ options
183
+ };
184
+ await this.hook("beforeGetObject", data);
185
+ const client = await this.getClient();
186
+ const result = await client.getObjectValue(key, defaultValue, data.options?.context);
187
+ const resultData = {
188
+ key,
189
+ defaultValue,
190
+ options,
191
+ result
192
+ };
193
+ await this.hook("afterGetObject", resultData);
194
+ return resultData.result;
195
+ } catch (error) {
196
+ this.emit("error", error);
197
+ if (this._throwErrors) {
198
+ throw error;
199
+ }
200
+ }
201
+ return defaultValue;
145
202
  }
146
203
  };
147
204
  export {
148
- Toggle
205
+ Toggle,
206
+ ToggleHooks
149
207
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyphen/sdk",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Hyphen SDK for Node.js",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -12,6 +12,13 @@
12
12
  }
13
13
  },
14
14
  "types": "dist/node/index.d.ts",
15
+ "scripts": {
16
+ "test": "xo --fix && vitest run --coverage",
17
+ "test:ci": "xo && vitest run --coverage",
18
+ "build": "rimraf ./dist && tsup src/index.ts --format esm,cjs --dts --clean",
19
+ "clean": "rimraf ./dist",
20
+ "prepublishOnly": "rimraf ./dist && tsup src/index.ts --format esm,cjs --dts --clean"
21
+ },
15
22
  "keywords": [
16
23
  "hyphen",
17
24
  "sdk",
@@ -41,11 +48,5 @@
41
48
  "@openfeature/server-sdk": "^1.18.0",
42
49
  "dotenv": "^16.5.0",
43
50
  "hookified": "^1.9.0"
44
- },
45
- "scripts": {
46
- "test": "xo --fix && vitest run --coverage",
47
- "test:ci": "xo && vitest run --coverage",
48
- "build": "rimraf ./dist && tsup src/index.ts --format esm,cjs --dts --clean",
49
- "clean": "rimraf ./dist"
50
51
  }
51
- }
52
+ }