@hyphen/sdk 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -3
- package/dist/index.cjs +282 -0
- package/dist/index.d.cts +122 -2
- package/dist/index.d.ts +122 -2
- package/dist/index.js +281 -0
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ The Hyphen Node.js SDK is a JavaScript library that allows developers to easily
|
|
|
11
11
|
|
|
12
12
|
# Table of Contents
|
|
13
13
|
- [Installation](#installation)
|
|
14
|
-
- [Basic Usage](#basic-usage)
|
|
14
|
+
- [Basic Usage with Hyphen](#basic-usage-with-hyphen)
|
|
15
15
|
- [Toggle](#toggle)
|
|
16
16
|
- [Toggle Options](#toggle-options)
|
|
17
17
|
- [Toggle API](#toggle-api)
|
|
@@ -35,9 +35,93 @@ To install the Hyphen Node.js SDK, you can use npm or yarn. Run the following co
|
|
|
35
35
|
npm install @hyphen/sdk
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
# Basic Usage
|
|
38
|
+
# Basic Usage with Hyphen
|
|
39
39
|
|
|
40
|
-
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.
|
|
40
|
+
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. To get started, you can create an instance of the `Hyphen` class and use its methods to interact with the various services.
|
|
41
|
+
|
|
42
|
+
```javascript
|
|
43
|
+
import { Hyphen } from '@hyphen/sdk';
|
|
44
|
+
|
|
45
|
+
const hyphen = new Hyphen({
|
|
46
|
+
publicApiKey: 'your_public_api_key',
|
|
47
|
+
applicationId: 'your_application_id',
|
|
48
|
+
});
|
|
49
|
+
const result = await hyphen.toggle.getBoolean('hyphen-sdk-boolean', false);
|
|
50
|
+
console.log('Boolean toggle value:', result); // true
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
You can also use `netInfo` to access the network information service.
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
import { Hyphen, ToggleContext } from '@hyphen/sdk';
|
|
57
|
+
|
|
58
|
+
const context: ToggleContext = {
|
|
59
|
+
targetingKey: 'user-123',
|
|
60
|
+
ipAddress: '203.0.113.42',
|
|
61
|
+
customAttributes: {
|
|
62
|
+
subscriptionLevel: 'premium',
|
|
63
|
+
region: 'us-east',
|
|
64
|
+
},
|
|
65
|
+
user: {
|
|
66
|
+
id: 'user-123',
|
|
67
|
+
email: 'john.doe@example.com',
|
|
68
|
+
name: 'John Doe',
|
|
69
|
+
customAttributes: {
|
|
70
|
+
role: 'admin',
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const hyphen = new Hyphen({
|
|
76
|
+
publicApiKey: 'your_public_api_key',
|
|
77
|
+
toggle: {
|
|
78
|
+
applicationId: 'your_application_id',
|
|
79
|
+
context: context,
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
const result = await hyphen.toggle.getBoolean('hyphen-sdk-boolean', false);
|
|
83
|
+
console.log('Boolean toggle value:', result); // true
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
You can also use `netInfo` to access the network information service.
|
|
87
|
+
|
|
88
|
+
```javascript
|
|
89
|
+
import { Hyphen } from '@hyphen/sdk';
|
|
90
|
+
|
|
91
|
+
const hyphen = new Hyphen({
|
|
92
|
+
apiKey: 'your_api_key',
|
|
93
|
+
});
|
|
94
|
+
const result = await hyphen.netInfo.getIpInfo('8.8.8.8');
|
|
95
|
+
console.log('Geo IP information:', result);
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
If you need to set the `apiKey` or `publicApiKey` after initializing `Hyphen` you can do so and it will cascade the setting to the individual services:
|
|
99
|
+
|
|
100
|
+
```javascript
|
|
101
|
+
import { Hyphen } from '@hyphen/sdk';
|
|
102
|
+
|
|
103
|
+
const hyphen = new Hyphen();
|
|
104
|
+
hyphen.apiKey = 'your_api_key';
|
|
105
|
+
const result = await hyphen.netInfo.getIpInfo('8.8.8.8');
|
|
106
|
+
console.log('Geo IP information:', result);
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Finally, `error`, `warn`, and `info` emitters are enabled from each of the services and you can access them by doing the following example with `error`:
|
|
110
|
+
|
|
111
|
+
```javascript
|
|
112
|
+
import { Hyphen } from '@hyphen/sdk';
|
|
113
|
+
|
|
114
|
+
const hyphen = new Hyphen({ apiKey: 'your_api_key'});
|
|
115
|
+
|
|
116
|
+
hyphen.on('error', (error) => {
|
|
117
|
+
console.log(error);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const result = await hyphen.netInfo.getIpInfo('8.8.8.8');
|
|
121
|
+
console.log('Geo IP information:', result);
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The rest of the examples for each service show you accessing the service instance directly.
|
|
41
125
|
|
|
42
126
|
# Toggle
|
|
43
127
|
|
package/dist/index.cjs
CHANGED
|
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
// src/index.ts
|
|
32
32
|
var index_exports = {};
|
|
33
33
|
__export(index_exports, {
|
|
34
|
+
Hyphen: () => Hyphen,
|
|
34
35
|
Toggle: () => Toggle,
|
|
35
36
|
ToggleHooks: () => ToggleHooks,
|
|
36
37
|
loadEnv: () => loadEnv
|
|
@@ -442,8 +443,289 @@ function loadEnv(options) {
|
|
|
442
443
|
}
|
|
443
444
|
}
|
|
444
445
|
__name(loadEnv, "loadEnv");
|
|
446
|
+
|
|
447
|
+
// src/hyphen.ts
|
|
448
|
+
var import_hookified3 = require("hookified");
|
|
449
|
+
|
|
450
|
+
// src/net-info.ts
|
|
451
|
+
var import_node_process3 = __toESM(require("process"), 1);
|
|
452
|
+
|
|
453
|
+
// src/base-service.ts
|
|
454
|
+
var import_hookified2 = require("hookified");
|
|
455
|
+
var import_cacheable = require("cacheable");
|
|
456
|
+
var import_axios = __toESM(require("axios"), 1);
|
|
457
|
+
var import_pino = __toESM(require("pino"), 1);
|
|
458
|
+
var ErrorMessages = /* @__PURE__ */ function(ErrorMessages2) {
|
|
459
|
+
ErrorMessages2["API_KEY_REQUIRED"] = "API key is required. Please provide it via options or set the HYPHEN_API_KEY environment variable.";
|
|
460
|
+
ErrorMessages2["PUBLIC_API_KEY_SHOULD_NOT_BE_USED"] = "The provided API key is a public API key. Please provide a valid non public API key for authentication.";
|
|
461
|
+
return ErrorMessages2;
|
|
462
|
+
}({});
|
|
463
|
+
var BaseService = class extends import_hookified2.Hookified {
|
|
464
|
+
static {
|
|
465
|
+
__name(this, "BaseService");
|
|
466
|
+
}
|
|
467
|
+
_log = (0, import_pino.default)();
|
|
468
|
+
_cache = new import_cacheable.Cacheable();
|
|
469
|
+
_throwErrors = false;
|
|
470
|
+
constructor(options) {
|
|
471
|
+
super(options);
|
|
472
|
+
if (options && options.throwErrors !== void 0) {
|
|
473
|
+
this._throwErrors = options.throwErrors;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
get log() {
|
|
477
|
+
return this._log;
|
|
478
|
+
}
|
|
479
|
+
set log(value) {
|
|
480
|
+
this._log = value;
|
|
481
|
+
}
|
|
482
|
+
get cache() {
|
|
483
|
+
return this._cache;
|
|
484
|
+
}
|
|
485
|
+
set cache(value) {
|
|
486
|
+
this._cache = value;
|
|
487
|
+
}
|
|
488
|
+
get throwErrors() {
|
|
489
|
+
return this._throwErrors;
|
|
490
|
+
}
|
|
491
|
+
set throwErrors(value) {
|
|
492
|
+
this._throwErrors = value;
|
|
493
|
+
}
|
|
494
|
+
error(message, ...args) {
|
|
495
|
+
this._log.error(message, ...args);
|
|
496
|
+
this.emit("error", message, ...args);
|
|
497
|
+
if (this.throwErrors) {
|
|
498
|
+
throw new Error(message);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
warn(message, ...args) {
|
|
502
|
+
this._log.warn(message, ...args);
|
|
503
|
+
this.emit("warn", message, ...args);
|
|
504
|
+
}
|
|
505
|
+
info(message, ...args) {
|
|
506
|
+
this._log.info(message, ...args);
|
|
507
|
+
this.emit("info", message, ...args);
|
|
508
|
+
}
|
|
509
|
+
async get(url, config2) {
|
|
510
|
+
return import_axios.default.get(url, config2);
|
|
511
|
+
}
|
|
512
|
+
async post(url, data, config2) {
|
|
513
|
+
return import_axios.default.post(url, data, config2);
|
|
514
|
+
}
|
|
515
|
+
async put(url, data, config2) {
|
|
516
|
+
return import_axios.default.put(url, data, config2);
|
|
517
|
+
}
|
|
518
|
+
async delete(url, config2) {
|
|
519
|
+
return import_axios.default.delete(url, config2);
|
|
520
|
+
}
|
|
521
|
+
async patch(url, data, config2) {
|
|
522
|
+
return import_axios.default.patch(url, data, config2);
|
|
523
|
+
}
|
|
524
|
+
createHeaders(apiKey) {
|
|
525
|
+
const headers = {
|
|
526
|
+
"content-type": "application/json",
|
|
527
|
+
accept: "application/json"
|
|
528
|
+
};
|
|
529
|
+
if (apiKey) {
|
|
530
|
+
headers["x-api-key"] = apiKey;
|
|
531
|
+
}
|
|
532
|
+
return headers;
|
|
533
|
+
}
|
|
534
|
+
};
|
|
535
|
+
|
|
536
|
+
// src/net-info.ts
|
|
537
|
+
loadEnv();
|
|
538
|
+
var NetInfo = class extends BaseService {
|
|
539
|
+
static {
|
|
540
|
+
__name(this, "NetInfo");
|
|
541
|
+
}
|
|
542
|
+
_apiKey;
|
|
543
|
+
_baseUri = "https://net.info";
|
|
544
|
+
constructor(options) {
|
|
545
|
+
super(options);
|
|
546
|
+
if (options?.baseUri) {
|
|
547
|
+
this._baseUri = options.baseUri;
|
|
548
|
+
}
|
|
549
|
+
this.setApiKey(options?.apiKey);
|
|
550
|
+
if (!this._apiKey && import_node_process3.default.env.HYPHEN_API_KEY) {
|
|
551
|
+
this.setApiKey(import_node_process3.default.env.HYPHEN_API_KEY);
|
|
552
|
+
}
|
|
553
|
+
if (!this._apiKey) {
|
|
554
|
+
this.error(ErrorMessages.API_KEY_REQUIRED);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Gets or sets the API key for authentication.
|
|
559
|
+
* If not set, it will try to use the `HYPHEN_API_KEY` environment variable.
|
|
560
|
+
* @type {string | undefined}
|
|
561
|
+
*/
|
|
562
|
+
get apiKey() {
|
|
563
|
+
return this._apiKey;
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Sets the API key for authentication.
|
|
567
|
+
* @param {string | undefined} value - The API key to set.
|
|
568
|
+
*/
|
|
569
|
+
set apiKey(value) {
|
|
570
|
+
this.setApiKey(value);
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Gets or sets the base URI for the API.
|
|
574
|
+
* @type {string}
|
|
575
|
+
*/
|
|
576
|
+
get baseUri() {
|
|
577
|
+
return this._baseUri;
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Sets the base URI for the API.
|
|
581
|
+
* @param {string} value - The base URI to set.
|
|
582
|
+
*/
|
|
583
|
+
set baseUri(value) {
|
|
584
|
+
this._baseUri = value;
|
|
585
|
+
}
|
|
586
|
+
setApiKey(value) {
|
|
587
|
+
if (value?.startsWith("public_")) {
|
|
588
|
+
this.error(ErrorMessages.PUBLIC_API_KEY_SHOULD_NOT_BE_USED);
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
this._apiKey = value;
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Fetches GeoIP information for a given IP address.
|
|
595
|
+
* @param {string} ip - The IP address to fetch GeoIP information for.
|
|
596
|
+
* @returns {Promise<ipInfo | ipInfoError>} - A promise that resolves to the ip information or an error.
|
|
597
|
+
*/
|
|
598
|
+
async getIpInfo(ip) {
|
|
599
|
+
try {
|
|
600
|
+
if (!this._apiKey) {
|
|
601
|
+
throw new Error(ErrorMessages.API_KEY_REQUIRED);
|
|
602
|
+
}
|
|
603
|
+
const url = `${this._baseUri}/ip/${ip}`;
|
|
604
|
+
const headers = this.createHeaders(this._apiKey);
|
|
605
|
+
const response = await this.get(url, {
|
|
606
|
+
headers
|
|
607
|
+
});
|
|
608
|
+
if (response.status !== 200) {
|
|
609
|
+
const errorResult = {
|
|
610
|
+
ip,
|
|
611
|
+
type: "error",
|
|
612
|
+
errorMessage: `Failed to fetch ip info: ${response.statusText}`
|
|
613
|
+
};
|
|
614
|
+
return errorResult;
|
|
615
|
+
}
|
|
616
|
+
return response.data;
|
|
617
|
+
} catch (error) {
|
|
618
|
+
this.error(`Failed to fetch ip info: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
619
|
+
const errorResult = {
|
|
620
|
+
ip,
|
|
621
|
+
type: "error",
|
|
622
|
+
errorMessage: error instanceof Error ? error.message : "Unknown error"
|
|
623
|
+
};
|
|
624
|
+
return errorResult;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
async getIpInfos(ips) {
|
|
628
|
+
if (!Array.isArray(ips) || ips.length === 0) {
|
|
629
|
+
this.error("The provided IPs array is invalid. It should be a non-empty array of strings.");
|
|
630
|
+
return [];
|
|
631
|
+
}
|
|
632
|
+
const errorResults = [];
|
|
633
|
+
try {
|
|
634
|
+
if (!this._apiKey) {
|
|
635
|
+
throw new Error(ErrorMessages.API_KEY_REQUIRED);
|
|
636
|
+
}
|
|
637
|
+
const url = `${this._baseUri}/ip`;
|
|
638
|
+
const headers = this.createHeaders(this._apiKey);
|
|
639
|
+
const response = await this.post(url, ips, {
|
|
640
|
+
headers
|
|
641
|
+
});
|
|
642
|
+
if (response.status !== 200) {
|
|
643
|
+
errorResults.push({
|
|
644
|
+
ip: "",
|
|
645
|
+
type: "error",
|
|
646
|
+
errorMessage: `Failed to fetch ip infos: ${response.statusText}`
|
|
647
|
+
});
|
|
648
|
+
return errorResults;
|
|
649
|
+
}
|
|
650
|
+
const responseData = response?.data;
|
|
651
|
+
return responseData.data;
|
|
652
|
+
} catch (error) {
|
|
653
|
+
this.error(`Failed to fetch ip infos: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
654
|
+
errorResults.push({
|
|
655
|
+
ip: "",
|
|
656
|
+
type: "error",
|
|
657
|
+
errorMessage: error instanceof Error ? error.message : "Unknown error"
|
|
658
|
+
});
|
|
659
|
+
return errorResults;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
};
|
|
663
|
+
|
|
664
|
+
// src/hyphen.ts
|
|
665
|
+
var Hyphen = class extends import_hookified3.Hookified {
|
|
666
|
+
static {
|
|
667
|
+
__name(this, "Hyphen");
|
|
668
|
+
}
|
|
669
|
+
_netInfo;
|
|
670
|
+
_toggle;
|
|
671
|
+
_publicApiKey;
|
|
672
|
+
_apiKey;
|
|
673
|
+
constructor(options) {
|
|
674
|
+
super(options);
|
|
675
|
+
const toggleOptions = options?.toggle ?? {};
|
|
676
|
+
const netInfoOptions = options?.netInfo ?? {};
|
|
677
|
+
if (options?.publicApiKey) {
|
|
678
|
+
this._publicApiKey = options.publicApiKey;
|
|
679
|
+
toggleOptions.publicApiKey = options.publicApiKey;
|
|
680
|
+
}
|
|
681
|
+
if (options?.apiKey) {
|
|
682
|
+
this._apiKey = options.apiKey;
|
|
683
|
+
netInfoOptions.apiKey = options.apiKey;
|
|
684
|
+
}
|
|
685
|
+
if (options?.throwErrors !== void 0) {
|
|
686
|
+
toggleOptions.throwErrors = options.throwErrors;
|
|
687
|
+
netInfoOptions.throwErrors = options.throwErrors;
|
|
688
|
+
}
|
|
689
|
+
this._netInfo = new NetInfo(netInfoOptions);
|
|
690
|
+
this._netInfo.on("error", (message, ...args) => this.emit("error", message, ...args));
|
|
691
|
+
this._netInfo.on("info", (message, ...args) => this.emit("info", message, ...args));
|
|
692
|
+
this._netInfo.on("warn", (message, ...args) => this.emit("warn", message, ...args));
|
|
693
|
+
this._toggle = new Toggle(toggleOptions);
|
|
694
|
+
this._toggle.on("error", (message, ...args) => this.emit("error", message, ...args));
|
|
695
|
+
this._toggle.on("info", (message, ...args) => this.emit("info", message, ...args));
|
|
696
|
+
this._toggle.on("warn", (message, ...args) => this.emit("warn", message, ...args));
|
|
697
|
+
}
|
|
698
|
+
get netInfo() {
|
|
699
|
+
return this._netInfo;
|
|
700
|
+
}
|
|
701
|
+
get toggle() {
|
|
702
|
+
return this._toggle;
|
|
703
|
+
}
|
|
704
|
+
get publicApiKey() {
|
|
705
|
+
return this._publicApiKey;
|
|
706
|
+
}
|
|
707
|
+
set publicApiKey(value) {
|
|
708
|
+
this._publicApiKey = value;
|
|
709
|
+
this._toggle.publicApiKey = value;
|
|
710
|
+
}
|
|
711
|
+
get apiKey() {
|
|
712
|
+
return this._apiKey;
|
|
713
|
+
}
|
|
714
|
+
set apiKey(value) {
|
|
715
|
+
this._apiKey = value;
|
|
716
|
+
this._netInfo.apiKey = value;
|
|
717
|
+
}
|
|
718
|
+
get throwErrors() {
|
|
719
|
+
return this._netInfo.throwErrors && this._toggle.throwErrors;
|
|
720
|
+
}
|
|
721
|
+
set throwErrors(value) {
|
|
722
|
+
this._netInfo.throwErrors = value;
|
|
723
|
+
this._toggle.throwErrors = value;
|
|
724
|
+
}
|
|
725
|
+
};
|
|
445
726
|
// Annotate the CommonJS export names for ESM import in node:
|
|
446
727
|
0 && (module.exports = {
|
|
728
|
+
Hyphen,
|
|
447
729
|
Toggle,
|
|
448
730
|
ToggleHooks,
|
|
449
731
|
loadEnv
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import { Hookified } from 'hookified';
|
|
1
|
+
import { Hookified, HookifiedOptions } from 'hookified';
|
|
2
2
|
import { EvaluationContext, Client } from '@openfeature/server-sdk';
|
|
3
|
+
import * as axios from 'axios';
|
|
4
|
+
import { AxiosRequestConfig } from 'axios';
|
|
5
|
+
import { Cacheable } from 'cacheable';
|
|
6
|
+
import pino from 'pino';
|
|
3
7
|
|
|
4
8
|
type ToggleContext = EvaluationContext;
|
|
5
9
|
declare enum ToggleHooks {
|
|
@@ -218,4 +222,120 @@ type LoadEnvOptions = {
|
|
|
218
222
|
*/
|
|
219
223
|
declare function loadEnv(options?: LoadEnvOptions): void;
|
|
220
224
|
|
|
221
|
-
|
|
225
|
+
type BaseServiceOptions = {
|
|
226
|
+
throwErrors?: boolean;
|
|
227
|
+
} & HookifiedOptions;
|
|
228
|
+
declare class BaseService extends Hookified {
|
|
229
|
+
private _log;
|
|
230
|
+
private _cache;
|
|
231
|
+
private _throwErrors;
|
|
232
|
+
constructor(options?: BaseServiceOptions);
|
|
233
|
+
get log(): pino.Logger;
|
|
234
|
+
set log(value: pino.Logger);
|
|
235
|
+
get cache(): Cacheable;
|
|
236
|
+
set cache(value: Cacheable);
|
|
237
|
+
get throwErrors(): boolean;
|
|
238
|
+
set throwErrors(value: boolean);
|
|
239
|
+
error(message: string, ...args: any[]): void;
|
|
240
|
+
warn(message: string, ...args: any[]): void;
|
|
241
|
+
info(message: string, ...args: any[]): void;
|
|
242
|
+
get<T>(url: string, config?: AxiosRequestConfig): Promise<axios.AxiosResponse<T, any>>;
|
|
243
|
+
post<T>(url: string, data: any, config?: AxiosRequestConfig): Promise<axios.AxiosResponse<T, any>>;
|
|
244
|
+
put<T>(url: string, data: any, config?: AxiosRequestConfig): Promise<axios.AxiosResponse<T, any>>;
|
|
245
|
+
delete<T>(url: string, config?: AxiosRequestConfig): Promise<axios.AxiosResponse<T, any>>;
|
|
246
|
+
patch<T>(url: string, data: any, config?: AxiosRequestConfig): Promise<axios.AxiosResponse<T, any>>;
|
|
247
|
+
createHeaders(apiKey?: string): Record<string, string>;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
type NetInfoOptions = {
|
|
251
|
+
/**
|
|
252
|
+
* API key for authentication. If this is not provided it will try to use `HYPHEN_API_KEY` environment variable.
|
|
253
|
+
* @type {string} - The API key for authentication. This is not the public API key.
|
|
254
|
+
* @default undefined
|
|
255
|
+
*/
|
|
256
|
+
apiKey?: string;
|
|
257
|
+
/**
|
|
258
|
+
* Base URI for the API. If not provided, it will use the default Hyphen API base URI.
|
|
259
|
+
* @type {string} - The base URI for the API.
|
|
260
|
+
* @default 'https://net.info'
|
|
261
|
+
*/
|
|
262
|
+
baseUri?: string;
|
|
263
|
+
} & BaseServiceOptions;
|
|
264
|
+
type ipInfo = {
|
|
265
|
+
ip: string;
|
|
266
|
+
type: string;
|
|
267
|
+
location: {
|
|
268
|
+
country: string;
|
|
269
|
+
region: string;
|
|
270
|
+
city: string;
|
|
271
|
+
lat: number;
|
|
272
|
+
lng: number;
|
|
273
|
+
postalCode: string;
|
|
274
|
+
timezone: string;
|
|
275
|
+
geonameId: number;
|
|
276
|
+
};
|
|
277
|
+
};
|
|
278
|
+
type ipInfoError = {
|
|
279
|
+
ip: string;
|
|
280
|
+
type: string;
|
|
281
|
+
errorMessage: string;
|
|
282
|
+
};
|
|
283
|
+
declare class NetInfo extends BaseService {
|
|
284
|
+
private _apiKey;
|
|
285
|
+
private _baseUri;
|
|
286
|
+
constructor(options?: NetInfoOptions);
|
|
287
|
+
/**
|
|
288
|
+
* Gets or sets the API key for authentication.
|
|
289
|
+
* If not set, it will try to use the `HYPHEN_API_KEY` environment variable.
|
|
290
|
+
* @type {string | undefined}
|
|
291
|
+
*/
|
|
292
|
+
get apiKey(): string | undefined;
|
|
293
|
+
/**
|
|
294
|
+
* Sets the API key for authentication.
|
|
295
|
+
* @param {string | undefined} value - The API key to set.
|
|
296
|
+
*/
|
|
297
|
+
set apiKey(value: string | undefined);
|
|
298
|
+
/**
|
|
299
|
+
* Gets or sets the base URI for the API.
|
|
300
|
+
* @type {string}
|
|
301
|
+
*/
|
|
302
|
+
get baseUri(): string;
|
|
303
|
+
/**
|
|
304
|
+
* Sets the base URI for the API.
|
|
305
|
+
* @param {string} value - The base URI to set.
|
|
306
|
+
*/
|
|
307
|
+
set baseUri(value: string);
|
|
308
|
+
setApiKey(value: string | undefined): void;
|
|
309
|
+
/**
|
|
310
|
+
* Fetches GeoIP information for a given IP address.
|
|
311
|
+
* @param {string} ip - The IP address to fetch GeoIP information for.
|
|
312
|
+
* @returns {Promise<ipInfo | ipInfoError>} - A promise that resolves to the ip information or an error.
|
|
313
|
+
*/
|
|
314
|
+
getIpInfo(ip: string): Promise<ipInfo | ipInfoError>;
|
|
315
|
+
getIpInfos(ips: string[]): Promise<Array<ipInfo | ipInfoError>>;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
type HyphenOptions = {
|
|
319
|
+
publicApiKey?: string;
|
|
320
|
+
apiKey?: string;
|
|
321
|
+
throwErrors?: boolean;
|
|
322
|
+
toggle?: Omit<ToggleOptions, 'apiKey' | 'publicApiKey' | 'throwErrors'>;
|
|
323
|
+
netInfo?: Omit<NetInfoOptions, 'apiKey' | 'publicApiKey' | 'throwErrors'>;
|
|
324
|
+
} & HookifiedOptions;
|
|
325
|
+
declare class Hyphen extends Hookified {
|
|
326
|
+
private readonly _netInfo;
|
|
327
|
+
private readonly _toggle;
|
|
328
|
+
private _publicApiKey?;
|
|
329
|
+
private _apiKey?;
|
|
330
|
+
constructor(options?: HyphenOptions);
|
|
331
|
+
get netInfo(): NetInfo;
|
|
332
|
+
get toggle(): Toggle;
|
|
333
|
+
get publicApiKey(): string | undefined;
|
|
334
|
+
set publicApiKey(value: string | undefined);
|
|
335
|
+
get apiKey(): string | undefined;
|
|
336
|
+
set apiKey(value: string | undefined);
|
|
337
|
+
get throwErrors(): boolean;
|
|
338
|
+
set throwErrors(value: boolean);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export { Hyphen, type HyphenOptions, Toggle, type ToggleCachingOptions, type ToggleContext, type ToggleGetOptions, ToggleHooks, type ToggleOptions, loadEnv };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import { Hookified } from 'hookified';
|
|
1
|
+
import { Hookified, HookifiedOptions } from 'hookified';
|
|
2
2
|
import { EvaluationContext, Client } from '@openfeature/server-sdk';
|
|
3
|
+
import * as axios from 'axios';
|
|
4
|
+
import { AxiosRequestConfig } from 'axios';
|
|
5
|
+
import { Cacheable } from 'cacheable';
|
|
6
|
+
import pino from 'pino';
|
|
3
7
|
|
|
4
8
|
type ToggleContext = EvaluationContext;
|
|
5
9
|
declare enum ToggleHooks {
|
|
@@ -218,4 +222,120 @@ type LoadEnvOptions = {
|
|
|
218
222
|
*/
|
|
219
223
|
declare function loadEnv(options?: LoadEnvOptions): void;
|
|
220
224
|
|
|
221
|
-
|
|
225
|
+
type BaseServiceOptions = {
|
|
226
|
+
throwErrors?: boolean;
|
|
227
|
+
} & HookifiedOptions;
|
|
228
|
+
declare class BaseService extends Hookified {
|
|
229
|
+
private _log;
|
|
230
|
+
private _cache;
|
|
231
|
+
private _throwErrors;
|
|
232
|
+
constructor(options?: BaseServiceOptions);
|
|
233
|
+
get log(): pino.Logger;
|
|
234
|
+
set log(value: pino.Logger);
|
|
235
|
+
get cache(): Cacheable;
|
|
236
|
+
set cache(value: Cacheable);
|
|
237
|
+
get throwErrors(): boolean;
|
|
238
|
+
set throwErrors(value: boolean);
|
|
239
|
+
error(message: string, ...args: any[]): void;
|
|
240
|
+
warn(message: string, ...args: any[]): void;
|
|
241
|
+
info(message: string, ...args: any[]): void;
|
|
242
|
+
get<T>(url: string, config?: AxiosRequestConfig): Promise<axios.AxiosResponse<T, any>>;
|
|
243
|
+
post<T>(url: string, data: any, config?: AxiosRequestConfig): Promise<axios.AxiosResponse<T, any>>;
|
|
244
|
+
put<T>(url: string, data: any, config?: AxiosRequestConfig): Promise<axios.AxiosResponse<T, any>>;
|
|
245
|
+
delete<T>(url: string, config?: AxiosRequestConfig): Promise<axios.AxiosResponse<T, any>>;
|
|
246
|
+
patch<T>(url: string, data: any, config?: AxiosRequestConfig): Promise<axios.AxiosResponse<T, any>>;
|
|
247
|
+
createHeaders(apiKey?: string): Record<string, string>;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
type NetInfoOptions = {
|
|
251
|
+
/**
|
|
252
|
+
* API key for authentication. If this is not provided it will try to use `HYPHEN_API_KEY` environment variable.
|
|
253
|
+
* @type {string} - The API key for authentication. This is not the public API key.
|
|
254
|
+
* @default undefined
|
|
255
|
+
*/
|
|
256
|
+
apiKey?: string;
|
|
257
|
+
/**
|
|
258
|
+
* Base URI for the API. If not provided, it will use the default Hyphen API base URI.
|
|
259
|
+
* @type {string} - The base URI for the API.
|
|
260
|
+
* @default 'https://net.info'
|
|
261
|
+
*/
|
|
262
|
+
baseUri?: string;
|
|
263
|
+
} & BaseServiceOptions;
|
|
264
|
+
type ipInfo = {
|
|
265
|
+
ip: string;
|
|
266
|
+
type: string;
|
|
267
|
+
location: {
|
|
268
|
+
country: string;
|
|
269
|
+
region: string;
|
|
270
|
+
city: string;
|
|
271
|
+
lat: number;
|
|
272
|
+
lng: number;
|
|
273
|
+
postalCode: string;
|
|
274
|
+
timezone: string;
|
|
275
|
+
geonameId: number;
|
|
276
|
+
};
|
|
277
|
+
};
|
|
278
|
+
type ipInfoError = {
|
|
279
|
+
ip: string;
|
|
280
|
+
type: string;
|
|
281
|
+
errorMessage: string;
|
|
282
|
+
};
|
|
283
|
+
declare class NetInfo extends BaseService {
|
|
284
|
+
private _apiKey;
|
|
285
|
+
private _baseUri;
|
|
286
|
+
constructor(options?: NetInfoOptions);
|
|
287
|
+
/**
|
|
288
|
+
* Gets or sets the API key for authentication.
|
|
289
|
+
* If not set, it will try to use the `HYPHEN_API_KEY` environment variable.
|
|
290
|
+
* @type {string | undefined}
|
|
291
|
+
*/
|
|
292
|
+
get apiKey(): string | undefined;
|
|
293
|
+
/**
|
|
294
|
+
* Sets the API key for authentication.
|
|
295
|
+
* @param {string | undefined} value - The API key to set.
|
|
296
|
+
*/
|
|
297
|
+
set apiKey(value: string | undefined);
|
|
298
|
+
/**
|
|
299
|
+
* Gets or sets the base URI for the API.
|
|
300
|
+
* @type {string}
|
|
301
|
+
*/
|
|
302
|
+
get baseUri(): string;
|
|
303
|
+
/**
|
|
304
|
+
* Sets the base URI for the API.
|
|
305
|
+
* @param {string} value - The base URI to set.
|
|
306
|
+
*/
|
|
307
|
+
set baseUri(value: string);
|
|
308
|
+
setApiKey(value: string | undefined): void;
|
|
309
|
+
/**
|
|
310
|
+
* Fetches GeoIP information for a given IP address.
|
|
311
|
+
* @param {string} ip - The IP address to fetch GeoIP information for.
|
|
312
|
+
* @returns {Promise<ipInfo | ipInfoError>} - A promise that resolves to the ip information or an error.
|
|
313
|
+
*/
|
|
314
|
+
getIpInfo(ip: string): Promise<ipInfo | ipInfoError>;
|
|
315
|
+
getIpInfos(ips: string[]): Promise<Array<ipInfo | ipInfoError>>;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
type HyphenOptions = {
|
|
319
|
+
publicApiKey?: string;
|
|
320
|
+
apiKey?: string;
|
|
321
|
+
throwErrors?: boolean;
|
|
322
|
+
toggle?: Omit<ToggleOptions, 'apiKey' | 'publicApiKey' | 'throwErrors'>;
|
|
323
|
+
netInfo?: Omit<NetInfoOptions, 'apiKey' | 'publicApiKey' | 'throwErrors'>;
|
|
324
|
+
} & HookifiedOptions;
|
|
325
|
+
declare class Hyphen extends Hookified {
|
|
326
|
+
private readonly _netInfo;
|
|
327
|
+
private readonly _toggle;
|
|
328
|
+
private _publicApiKey?;
|
|
329
|
+
private _apiKey?;
|
|
330
|
+
constructor(options?: HyphenOptions);
|
|
331
|
+
get netInfo(): NetInfo;
|
|
332
|
+
get toggle(): Toggle;
|
|
333
|
+
get publicApiKey(): string | undefined;
|
|
334
|
+
set publicApiKey(value: string | undefined);
|
|
335
|
+
get apiKey(): string | undefined;
|
|
336
|
+
set apiKey(value: string | undefined);
|
|
337
|
+
get throwErrors(): boolean;
|
|
338
|
+
set throwErrors(value: boolean);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export { Hyphen, type HyphenOptions, Toggle, type ToggleCachingOptions, type ToggleContext, type ToggleGetOptions, ToggleHooks, type ToggleOptions, loadEnv };
|
package/dist/index.js
CHANGED
|
@@ -406,7 +406,288 @@ function loadEnv(options) {
|
|
|
406
406
|
}
|
|
407
407
|
}
|
|
408
408
|
__name(loadEnv, "loadEnv");
|
|
409
|
+
|
|
410
|
+
// src/hyphen.ts
|
|
411
|
+
import { Hookified as Hookified3 } from "hookified";
|
|
412
|
+
|
|
413
|
+
// src/net-info.ts
|
|
414
|
+
import process3 from "process";
|
|
415
|
+
|
|
416
|
+
// src/base-service.ts
|
|
417
|
+
import { Hookified as Hookified2 } from "hookified";
|
|
418
|
+
import { Cacheable } from "cacheable";
|
|
419
|
+
import axios from "axios";
|
|
420
|
+
import pino from "pino";
|
|
421
|
+
var ErrorMessages = /* @__PURE__ */ function(ErrorMessages2) {
|
|
422
|
+
ErrorMessages2["API_KEY_REQUIRED"] = "API key is required. Please provide it via options or set the HYPHEN_API_KEY environment variable.";
|
|
423
|
+
ErrorMessages2["PUBLIC_API_KEY_SHOULD_NOT_BE_USED"] = "The provided API key is a public API key. Please provide a valid non public API key for authentication.";
|
|
424
|
+
return ErrorMessages2;
|
|
425
|
+
}({});
|
|
426
|
+
var BaseService = class extends Hookified2 {
|
|
427
|
+
static {
|
|
428
|
+
__name(this, "BaseService");
|
|
429
|
+
}
|
|
430
|
+
_log = pino();
|
|
431
|
+
_cache = new Cacheable();
|
|
432
|
+
_throwErrors = false;
|
|
433
|
+
constructor(options) {
|
|
434
|
+
super(options);
|
|
435
|
+
if (options && options.throwErrors !== void 0) {
|
|
436
|
+
this._throwErrors = options.throwErrors;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
get log() {
|
|
440
|
+
return this._log;
|
|
441
|
+
}
|
|
442
|
+
set log(value) {
|
|
443
|
+
this._log = value;
|
|
444
|
+
}
|
|
445
|
+
get cache() {
|
|
446
|
+
return this._cache;
|
|
447
|
+
}
|
|
448
|
+
set cache(value) {
|
|
449
|
+
this._cache = value;
|
|
450
|
+
}
|
|
451
|
+
get throwErrors() {
|
|
452
|
+
return this._throwErrors;
|
|
453
|
+
}
|
|
454
|
+
set throwErrors(value) {
|
|
455
|
+
this._throwErrors = value;
|
|
456
|
+
}
|
|
457
|
+
error(message, ...args) {
|
|
458
|
+
this._log.error(message, ...args);
|
|
459
|
+
this.emit("error", message, ...args);
|
|
460
|
+
if (this.throwErrors) {
|
|
461
|
+
throw new Error(message);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
warn(message, ...args) {
|
|
465
|
+
this._log.warn(message, ...args);
|
|
466
|
+
this.emit("warn", message, ...args);
|
|
467
|
+
}
|
|
468
|
+
info(message, ...args) {
|
|
469
|
+
this._log.info(message, ...args);
|
|
470
|
+
this.emit("info", message, ...args);
|
|
471
|
+
}
|
|
472
|
+
async get(url, config2) {
|
|
473
|
+
return axios.get(url, config2);
|
|
474
|
+
}
|
|
475
|
+
async post(url, data, config2) {
|
|
476
|
+
return axios.post(url, data, config2);
|
|
477
|
+
}
|
|
478
|
+
async put(url, data, config2) {
|
|
479
|
+
return axios.put(url, data, config2);
|
|
480
|
+
}
|
|
481
|
+
async delete(url, config2) {
|
|
482
|
+
return axios.delete(url, config2);
|
|
483
|
+
}
|
|
484
|
+
async patch(url, data, config2) {
|
|
485
|
+
return axios.patch(url, data, config2);
|
|
486
|
+
}
|
|
487
|
+
createHeaders(apiKey) {
|
|
488
|
+
const headers = {
|
|
489
|
+
"content-type": "application/json",
|
|
490
|
+
accept: "application/json"
|
|
491
|
+
};
|
|
492
|
+
if (apiKey) {
|
|
493
|
+
headers["x-api-key"] = apiKey;
|
|
494
|
+
}
|
|
495
|
+
return headers;
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
// src/net-info.ts
|
|
500
|
+
loadEnv();
|
|
501
|
+
var NetInfo = class extends BaseService {
|
|
502
|
+
static {
|
|
503
|
+
__name(this, "NetInfo");
|
|
504
|
+
}
|
|
505
|
+
_apiKey;
|
|
506
|
+
_baseUri = "https://net.info";
|
|
507
|
+
constructor(options) {
|
|
508
|
+
super(options);
|
|
509
|
+
if (options?.baseUri) {
|
|
510
|
+
this._baseUri = options.baseUri;
|
|
511
|
+
}
|
|
512
|
+
this.setApiKey(options?.apiKey);
|
|
513
|
+
if (!this._apiKey && process3.env.HYPHEN_API_KEY) {
|
|
514
|
+
this.setApiKey(process3.env.HYPHEN_API_KEY);
|
|
515
|
+
}
|
|
516
|
+
if (!this._apiKey) {
|
|
517
|
+
this.error(ErrorMessages.API_KEY_REQUIRED);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Gets or sets the API key for authentication.
|
|
522
|
+
* If not set, it will try to use the `HYPHEN_API_KEY` environment variable.
|
|
523
|
+
* @type {string | undefined}
|
|
524
|
+
*/
|
|
525
|
+
get apiKey() {
|
|
526
|
+
return this._apiKey;
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Sets the API key for authentication.
|
|
530
|
+
* @param {string | undefined} value - The API key to set.
|
|
531
|
+
*/
|
|
532
|
+
set apiKey(value) {
|
|
533
|
+
this.setApiKey(value);
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Gets or sets the base URI for the API.
|
|
537
|
+
* @type {string}
|
|
538
|
+
*/
|
|
539
|
+
get baseUri() {
|
|
540
|
+
return this._baseUri;
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Sets the base URI for the API.
|
|
544
|
+
* @param {string} value - The base URI to set.
|
|
545
|
+
*/
|
|
546
|
+
set baseUri(value) {
|
|
547
|
+
this._baseUri = value;
|
|
548
|
+
}
|
|
549
|
+
setApiKey(value) {
|
|
550
|
+
if (value?.startsWith("public_")) {
|
|
551
|
+
this.error(ErrorMessages.PUBLIC_API_KEY_SHOULD_NOT_BE_USED);
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
this._apiKey = value;
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Fetches GeoIP information for a given IP address.
|
|
558
|
+
* @param {string} ip - The IP address to fetch GeoIP information for.
|
|
559
|
+
* @returns {Promise<ipInfo | ipInfoError>} - A promise that resolves to the ip information or an error.
|
|
560
|
+
*/
|
|
561
|
+
async getIpInfo(ip) {
|
|
562
|
+
try {
|
|
563
|
+
if (!this._apiKey) {
|
|
564
|
+
throw new Error(ErrorMessages.API_KEY_REQUIRED);
|
|
565
|
+
}
|
|
566
|
+
const url = `${this._baseUri}/ip/${ip}`;
|
|
567
|
+
const headers = this.createHeaders(this._apiKey);
|
|
568
|
+
const response = await this.get(url, {
|
|
569
|
+
headers
|
|
570
|
+
});
|
|
571
|
+
if (response.status !== 200) {
|
|
572
|
+
const errorResult = {
|
|
573
|
+
ip,
|
|
574
|
+
type: "error",
|
|
575
|
+
errorMessage: `Failed to fetch ip info: ${response.statusText}`
|
|
576
|
+
};
|
|
577
|
+
return errorResult;
|
|
578
|
+
}
|
|
579
|
+
return response.data;
|
|
580
|
+
} catch (error) {
|
|
581
|
+
this.error(`Failed to fetch ip info: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
582
|
+
const errorResult = {
|
|
583
|
+
ip,
|
|
584
|
+
type: "error",
|
|
585
|
+
errorMessage: error instanceof Error ? error.message : "Unknown error"
|
|
586
|
+
};
|
|
587
|
+
return errorResult;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
async getIpInfos(ips) {
|
|
591
|
+
if (!Array.isArray(ips) || ips.length === 0) {
|
|
592
|
+
this.error("The provided IPs array is invalid. It should be a non-empty array of strings.");
|
|
593
|
+
return [];
|
|
594
|
+
}
|
|
595
|
+
const errorResults = [];
|
|
596
|
+
try {
|
|
597
|
+
if (!this._apiKey) {
|
|
598
|
+
throw new Error(ErrorMessages.API_KEY_REQUIRED);
|
|
599
|
+
}
|
|
600
|
+
const url = `${this._baseUri}/ip`;
|
|
601
|
+
const headers = this.createHeaders(this._apiKey);
|
|
602
|
+
const response = await this.post(url, ips, {
|
|
603
|
+
headers
|
|
604
|
+
});
|
|
605
|
+
if (response.status !== 200) {
|
|
606
|
+
errorResults.push({
|
|
607
|
+
ip: "",
|
|
608
|
+
type: "error",
|
|
609
|
+
errorMessage: `Failed to fetch ip infos: ${response.statusText}`
|
|
610
|
+
});
|
|
611
|
+
return errorResults;
|
|
612
|
+
}
|
|
613
|
+
const responseData = response?.data;
|
|
614
|
+
return responseData.data;
|
|
615
|
+
} catch (error) {
|
|
616
|
+
this.error(`Failed to fetch ip infos: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
617
|
+
errorResults.push({
|
|
618
|
+
ip: "",
|
|
619
|
+
type: "error",
|
|
620
|
+
errorMessage: error instanceof Error ? error.message : "Unknown error"
|
|
621
|
+
});
|
|
622
|
+
return errorResults;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
};
|
|
626
|
+
|
|
627
|
+
// src/hyphen.ts
|
|
628
|
+
var Hyphen = class extends Hookified3 {
|
|
629
|
+
static {
|
|
630
|
+
__name(this, "Hyphen");
|
|
631
|
+
}
|
|
632
|
+
_netInfo;
|
|
633
|
+
_toggle;
|
|
634
|
+
_publicApiKey;
|
|
635
|
+
_apiKey;
|
|
636
|
+
constructor(options) {
|
|
637
|
+
super(options);
|
|
638
|
+
const toggleOptions = options?.toggle ?? {};
|
|
639
|
+
const netInfoOptions = options?.netInfo ?? {};
|
|
640
|
+
if (options?.publicApiKey) {
|
|
641
|
+
this._publicApiKey = options.publicApiKey;
|
|
642
|
+
toggleOptions.publicApiKey = options.publicApiKey;
|
|
643
|
+
}
|
|
644
|
+
if (options?.apiKey) {
|
|
645
|
+
this._apiKey = options.apiKey;
|
|
646
|
+
netInfoOptions.apiKey = options.apiKey;
|
|
647
|
+
}
|
|
648
|
+
if (options?.throwErrors !== void 0) {
|
|
649
|
+
toggleOptions.throwErrors = options.throwErrors;
|
|
650
|
+
netInfoOptions.throwErrors = options.throwErrors;
|
|
651
|
+
}
|
|
652
|
+
this._netInfo = new NetInfo(netInfoOptions);
|
|
653
|
+
this._netInfo.on("error", (message, ...args) => this.emit("error", message, ...args));
|
|
654
|
+
this._netInfo.on("info", (message, ...args) => this.emit("info", message, ...args));
|
|
655
|
+
this._netInfo.on("warn", (message, ...args) => this.emit("warn", message, ...args));
|
|
656
|
+
this._toggle = new Toggle(toggleOptions);
|
|
657
|
+
this._toggle.on("error", (message, ...args) => this.emit("error", message, ...args));
|
|
658
|
+
this._toggle.on("info", (message, ...args) => this.emit("info", message, ...args));
|
|
659
|
+
this._toggle.on("warn", (message, ...args) => this.emit("warn", message, ...args));
|
|
660
|
+
}
|
|
661
|
+
get netInfo() {
|
|
662
|
+
return this._netInfo;
|
|
663
|
+
}
|
|
664
|
+
get toggle() {
|
|
665
|
+
return this._toggle;
|
|
666
|
+
}
|
|
667
|
+
get publicApiKey() {
|
|
668
|
+
return this._publicApiKey;
|
|
669
|
+
}
|
|
670
|
+
set publicApiKey(value) {
|
|
671
|
+
this._publicApiKey = value;
|
|
672
|
+
this._toggle.publicApiKey = value;
|
|
673
|
+
}
|
|
674
|
+
get apiKey() {
|
|
675
|
+
return this._apiKey;
|
|
676
|
+
}
|
|
677
|
+
set apiKey(value) {
|
|
678
|
+
this._apiKey = value;
|
|
679
|
+
this._netInfo.apiKey = value;
|
|
680
|
+
}
|
|
681
|
+
get throwErrors() {
|
|
682
|
+
return this._netInfo.throwErrors && this._toggle.throwErrors;
|
|
683
|
+
}
|
|
684
|
+
set throwErrors(value) {
|
|
685
|
+
this._netInfo.throwErrors = value;
|
|
686
|
+
this._toggle.throwErrors = value;
|
|
687
|
+
}
|
|
688
|
+
};
|
|
409
689
|
export {
|
|
690
|
+
Hyphen,
|
|
410
691
|
Toggle,
|
|
411
692
|
ToggleHooks,
|
|
412
693
|
loadEnv
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyphen/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "Hyphen SDK for Node.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -29,15 +29,15 @@
|
|
|
29
29
|
"author": "Team Hyphen <hello@hyphen.ai>",
|
|
30
30
|
"license": "MIT",
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@swc/core": "^1.
|
|
33
|
-
"@types/node": "^
|
|
34
|
-
"@vitest/coverage-v8": "^3.
|
|
32
|
+
"@swc/core": "^1.12.9",
|
|
33
|
+
"@types/node": "^24.0.10",
|
|
34
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
35
35
|
"rimraf": "^6.0.1",
|
|
36
36
|
"tsd": "^0.32.0",
|
|
37
37
|
"tsup": "^8.5.0",
|
|
38
38
|
"typescript": "^5.8.3",
|
|
39
|
-
"vitest": "^3.
|
|
40
|
-
"xo": "^1.1.
|
|
39
|
+
"vitest": "^3.2.4",
|
|
40
|
+
"xo": "^1.1.1"
|
|
41
41
|
},
|
|
42
42
|
"files": [
|
|
43
43
|
"dist",
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
"@hyphen/openfeature-server-provider": "^1.0.7",
|
|
48
48
|
"@openfeature/server-sdk": "^1.18.0",
|
|
49
49
|
"axios": "^1.10.0",
|
|
50
|
-
"cacheable": "^1.10.
|
|
51
|
-
"dotenv": "^
|
|
52
|
-
"hookified": "^1.
|
|
50
|
+
"cacheable": "^1.10.1",
|
|
51
|
+
"dotenv": "^17.0.1",
|
|
52
|
+
"hookified": "^1.10.0",
|
|
53
53
|
"pino": "^9.7.0"
|
|
54
54
|
}
|
|
55
55
|
}
|