@hyphen/sdk 1.0.0 → 1.0.2
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 +108 -17
- package/dist/index.cjs +243 -0
- package/dist/index.d.cts +81 -0
- package/dist/index.d.ts +27 -6
- package/dist/index.js +123 -65
- package/logo.svg +59 -0
- package/package.json +11 -9
package/README.md
CHANGED
|
@@ -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,
|
|
42
|
+
import { Toggle, ToggleContext } from '@hyphen/sdk';
|
|
30
43
|
|
|
31
|
-
const 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,
|
|
77
|
+
import { Toggle, ToggleContext } from '@hyphen/sdk';
|
|
65
78
|
|
|
66
|
-
const 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,
|
|
113
|
+
import { Toggle, ToggleContext } from '@hyphen/sdk';
|
|
101
114
|
|
|
102
|
-
const 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:
|
|
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?* | `
|
|
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:
|
|
164
|
-
| *get<Type>* | `key: string, defaultValue: T, options?:
|
|
165
|
-
| *getBoolean* | `key: string, defaultValue: boolean, options?:
|
|
166
|
-
| *getNumber* | `key: string, defaultValue: number, options?:
|
|
167
|
-
| *getString* | `key: string, defaultValue: string, options?:
|
|
168
|
-
| *getObject<Type>* | `key: string, defaultValue: any, options?:
|
|
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,
|
|
200
|
+
import { Toggle, ToggleHooks, ToggleContext } from '@hyphen/sdk';
|
|
188
201
|
|
|
189
|
-
const 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
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -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
|
|
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 {
|
|
34
|
+
* @type {ToggleContext}
|
|
25
35
|
*/
|
|
26
|
-
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?:
|
|
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
|
-
|
|
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
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
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
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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/logo.svg
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 500 500">
|
|
3
|
+
<!-- Generator: Adobe Illustrator 29.5.0, SVG Export Plug-In . SVG Version: 2.1.0 Build 137) -->
|
|
4
|
+
<defs>
|
|
5
|
+
<style>
|
|
6
|
+
.st0 {
|
|
7
|
+
fill: url(#linear-gradient2);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.st1 {
|
|
11
|
+
fill: url(#linear-gradient1);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.st2 {
|
|
15
|
+
fill: url(#linear-gradient3);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.st3 {
|
|
19
|
+
fill: url(#linear-gradient);
|
|
20
|
+
}
|
|
21
|
+
</style>
|
|
22
|
+
<linearGradient id="linear-gradient" x1="144.47" y1="67.13" x2="648.76" y2="358.29" gradientTransform="translate(0 502) scale(1 -1)" gradientUnits="userSpaceOnUse">
|
|
23
|
+
<stop offset="0" stop-color="#fa0a64"/>
|
|
24
|
+
<stop offset=".11" stop-color="#fa135f"/>
|
|
25
|
+
<stop offset=".28" stop-color="#fb2b52"/>
|
|
26
|
+
<stop offset=".49" stop-color="#fc533e"/>
|
|
27
|
+
<stop offset=".75" stop-color="#fd8a21"/>
|
|
28
|
+
<stop offset="1" stop-color="#ffc800"/>
|
|
29
|
+
</linearGradient>
|
|
30
|
+
<linearGradient id="linear-gradient1" x1="-8270.41" y1="3296.5" x2="-8270.41" y2="2915.75" gradientTransform="translate(-8012.49 -2856.7) rotate(-180) scale(1 -1)" gradientUnits="userSpaceOnUse">
|
|
31
|
+
<stop offset="0" stop-color="#ffc800"/>
|
|
32
|
+
<stop offset=".11" stop-color="#ffbf05"/>
|
|
33
|
+
<stop offset=".28" stop-color="#fea712"/>
|
|
34
|
+
<stop offset=".49" stop-color="#fd7f26"/>
|
|
35
|
+
<stop offset=".75" stop-color="#fc4843"/>
|
|
36
|
+
<stop offset="1" stop-color="#fa0a64"/>
|
|
37
|
+
</linearGradient>
|
|
38
|
+
<linearGradient id="linear-gradient2" x1="-6709.98" y1="2836.03" x2="-6205.33" y2="3127.38" gradientTransform="translate(-6354.31 -2771.03) rotate(-180) scale(1 -1)" gradientUnits="userSpaceOnUse">
|
|
39
|
+
<stop offset="0" stop-color="#fa0a64"/>
|
|
40
|
+
<stop offset=".11" stop-color="#fa135f"/>
|
|
41
|
+
<stop offset=".28" stop-color="#fb2b52"/>
|
|
42
|
+
<stop offset=".49" stop-color="#fc533e"/>
|
|
43
|
+
<stop offset=".75" stop-color="#fd8a21"/>
|
|
44
|
+
<stop offset="1" stop-color="#ffc800"/>
|
|
45
|
+
</linearGradient>
|
|
46
|
+
<linearGradient id="linear-gradient3" x1="-1416.15" y1="527.47" x2="-1416.15" y2="146.72" gradientTransform="translate(1658.18 587.67) scale(1 -1)" gradientUnits="userSpaceOnUse">
|
|
47
|
+
<stop offset="0" stop-color="#ffc800"/>
|
|
48
|
+
<stop offset=".11" stop-color="#ffbf05"/>
|
|
49
|
+
<stop offset=".28" stop-color="#fea712"/>
|
|
50
|
+
<stop offset=".49" stop-color="#fd7f26"/>
|
|
51
|
+
<stop offset=".75" stop-color="#fc4843"/>
|
|
52
|
+
<stop offset="1" stop-color="#fa0a64"/>
|
|
53
|
+
</linearGradient>
|
|
54
|
+
</defs>
|
|
55
|
+
<path class="st3" d="M391.88,172.03c-7.88,11.76-154.27,267.33-154.27,267.33l93.12,1.76c20.49,0,34.78-8.82,43.05-23.16l96.72-167.55s-37.23-65.68-45.41-78.39c-8.18-12.72-24.94-12.38-33.21,0Z"/>
|
|
56
|
+
<path class="st1" d="M330.64,441.18c20.49,0,34.78-8.82,43.05-23.16l2.57-4.46c-6.38,10.58-16.83,22.93-31.15,1.27-10.44-15.87-95.24-164.85-95.24-164.85l-110.32,191.2h191.07Z"/>
|
|
57
|
+
<path class="st0" d="M108.04,327.97c7.88-11.8,154.48-267.53,154.48-267.53l-93.24-1.62c-20.49,0-34.78,8.82-43.05,23.16L29.5,249.47s37.14,65.84,45.33,78.5,24.94,12.38,33.21,0Z"/>
|
|
58
|
+
<path class="st2" d="M169.27,58.82c-20.49,0-34.78,8.82-43.05,23.16l-2.57,4.46c6.38-10.58,16.83-22.93,31.15-1.27,10.44,15.87,95.24,164.85,95.24,164.85l110.39-191.18-191.14-.02Z"/>
|
|
59
|
+
</svg>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyphen/sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
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",
|
|
@@ -34,18 +41,13 @@
|
|
|
34
41
|
},
|
|
35
42
|
"files": [
|
|
36
43
|
"dist",
|
|
37
|
-
"LICENSE"
|
|
44
|
+
"LICENSE",
|
|
45
|
+
"logo.svg"
|
|
38
46
|
],
|
|
39
47
|
"dependencies": {
|
|
40
48
|
"@hyphen/openfeature-server-provider": "^1.0.7",
|
|
41
49
|
"@openfeature/server-sdk": "^1.18.0",
|
|
42
50
|
"dotenv": "^16.5.0",
|
|
43
51
|
"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
52
|
}
|
|
51
|
-
}
|
|
53
|
+
}
|