@hyphen/sdk 1.8.0 → 1.10.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 +137 -10
- package/dist/index.cjs +464 -0
- package/dist/index.d.cts +294 -2
- package/dist/index.d.ts +294 -2
- package/dist/index.js +463 -0
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -11,8 +11,8 @@ 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)
|
|
15
|
-
- [Toggle](#toggle)
|
|
14
|
+
- [Basic Usage with Hyphen](#basic-usage-with-hyphen)
|
|
15
|
+
- [Toggle - Feature Flag Service](#toggle---feature-flag-service)
|
|
16
16
|
- [Toggle Options](#toggle-options)
|
|
17
17
|
- [Toggle API](#toggle-api)
|
|
18
18
|
- [Toggle Hooks](#toggle-hooks)
|
|
@@ -20,9 +20,10 @@ The Hyphen Node.js SDK is a JavaScript library that allows developers to easily
|
|
|
20
20
|
- [Toggle Caching](#toggle-caching)
|
|
21
21
|
- [Toggle Environment Variables](#toggle-environment-variables)
|
|
22
22
|
- [Toggle Self-Hosted](#toggle-self-hosted)
|
|
23
|
-
- [ENV](#env)
|
|
23
|
+
- [ENV - Secret Management Service](#env---secret-management-service)
|
|
24
24
|
- [Loading Environment Variables](#loading-environment-variables)
|
|
25
|
-
- [Net Info](#net-info)
|
|
25
|
+
- [Net Info - Geo Information Service](#net-info---geo-information-service)
|
|
26
|
+
- [Link - Short Code Service](#link---short-code-service)
|
|
26
27
|
- [Contributing](#contributing)
|
|
27
28
|
- [Testing Your Changes](#testing-your-changes)
|
|
28
29
|
- [License and Copyright](#license-and-copyright)
|
|
@@ -35,11 +36,95 @@ To install the Hyphen Node.js SDK, you can use npm or yarn. Run the following co
|
|
|
35
36
|
npm install @hyphen/sdk
|
|
36
37
|
```
|
|
37
38
|
|
|
38
|
-
# Basic Usage
|
|
39
|
+
# Basic Usage with Hyphen
|
|
39
40
|
|
|
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.
|
|
41
|
+
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
|
|
|
42
|
-
|
|
43
|
+
```javascript
|
|
44
|
+
import { Hyphen } from '@hyphen/sdk';
|
|
45
|
+
|
|
46
|
+
const hyphen = new Hyphen({
|
|
47
|
+
publicApiKey: 'your_public_api_key',
|
|
48
|
+
applicationId: 'your_application_id',
|
|
49
|
+
});
|
|
50
|
+
const result = await hyphen.toggle.getBoolean('hyphen-sdk-boolean', false);
|
|
51
|
+
console.log('Boolean toggle value:', result); // true
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
You can also use `netInfo` to access the network information service.
|
|
55
|
+
|
|
56
|
+
```javascript
|
|
57
|
+
import { Hyphen, ToggleContext } from '@hyphen/sdk';
|
|
58
|
+
|
|
59
|
+
const context: ToggleContext = {
|
|
60
|
+
targetingKey: 'user-123',
|
|
61
|
+
ipAddress: '203.0.113.42',
|
|
62
|
+
customAttributes: {
|
|
63
|
+
subscriptionLevel: 'premium',
|
|
64
|
+
region: 'us-east',
|
|
65
|
+
},
|
|
66
|
+
user: {
|
|
67
|
+
id: 'user-123',
|
|
68
|
+
email: 'john.doe@example.com',
|
|
69
|
+
name: 'John Doe',
|
|
70
|
+
customAttributes: {
|
|
71
|
+
role: 'admin',
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const hyphen = new Hyphen({
|
|
77
|
+
publicApiKey: 'your_public_api_key',
|
|
78
|
+
toggle: {
|
|
79
|
+
applicationId: 'your_application_id',
|
|
80
|
+
context: context,
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
const result = await hyphen.toggle.getBoolean('hyphen-sdk-boolean', false);
|
|
84
|
+
console.log('Boolean toggle value:', result); // true
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
You can also use `netInfo` to access the network information service.
|
|
88
|
+
|
|
89
|
+
```javascript
|
|
90
|
+
import { Hyphen } from '@hyphen/sdk';
|
|
91
|
+
|
|
92
|
+
const hyphen = new Hyphen({
|
|
93
|
+
apiKey: 'your_api_key',
|
|
94
|
+
});
|
|
95
|
+
const result = await hyphen.netInfo.getIpInfo('8.8.8.8');
|
|
96
|
+
console.log('Geo IP information:', result);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
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:
|
|
100
|
+
|
|
101
|
+
```javascript
|
|
102
|
+
import { Hyphen } from '@hyphen/sdk';
|
|
103
|
+
|
|
104
|
+
const hyphen = new Hyphen();
|
|
105
|
+
hyphen.apiKey = 'your_api_key';
|
|
106
|
+
const result = await hyphen.netInfo.getIpInfo('8.8.8.8');
|
|
107
|
+
console.log('Geo IP information:', result);
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
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`:
|
|
111
|
+
|
|
112
|
+
```javascript
|
|
113
|
+
import { Hyphen } from '@hyphen/sdk';
|
|
114
|
+
|
|
115
|
+
const hyphen = new Hyphen({ apiKey: 'your_api_key'});
|
|
116
|
+
|
|
117
|
+
hyphen.on('error', (error) => {
|
|
118
|
+
console.log(error);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const result = await hyphen.netInfo.getIpInfo('8.8.8.8');
|
|
122
|
+
console.log('Geo IP information:', result);
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The rest of the examples for each service show you accessing the service instance directly.
|
|
126
|
+
|
|
127
|
+
# Toggle - Feature Flag Service
|
|
43
128
|
|
|
44
129
|
[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.
|
|
45
130
|
|
|
@@ -487,7 +572,7 @@ const result = await toggle.getBoolean('hyphen-sdk-boolean', false);
|
|
|
487
572
|
console.log('Boolean toggle value:', result); // true
|
|
488
573
|
```
|
|
489
574
|
|
|
490
|
-
# ENV
|
|
575
|
+
# ENV - Secret Management Service
|
|
491
576
|
|
|
492
577
|
Hyphens secret management service known as [ENV](https://hyphen.ai/env) allows you to manage your environment variables in a secure way. The Hyphen Node.js SDK provides a simple way to access your environment variables.
|
|
493
578
|
|
|
@@ -532,7 +617,7 @@ import { loadEnv } from '@hyphen/sdk';
|
|
|
532
617
|
loadEnv({ local: false });
|
|
533
618
|
```
|
|
534
619
|
|
|
535
|
-
# Net Info
|
|
620
|
+
# Net Info - Geo Information Service
|
|
536
621
|
|
|
537
622
|
The Hyphen Node.js SDK also provides a `NetInfo` class that allows you to fetch geo information about an IP address. This can be useful for debugging or logging purposes. You can read more about it:
|
|
538
623
|
|
|
@@ -566,6 +651,38 @@ console.log('IP Infos:', ipInfos);
|
|
|
566
651
|
|
|
567
652
|
You can also set the API key using the `HYPHEN_API_KEY` environment variable. This is useful for keeping your API key secure and not hardcoding it in your code.
|
|
568
653
|
|
|
654
|
+
# Link - Short Code Service
|
|
655
|
+
|
|
656
|
+
The Hyphen Node.js SDK also provides a `Link` class that allows you to create and manage short codes. This can be useful for generating short links for your application. Here is an example of creating a short code:
|
|
657
|
+
|
|
658
|
+
```javascript
|
|
659
|
+
import { Link } from '@hyphen/sdk';
|
|
660
|
+
const link = new Link({
|
|
661
|
+
organizationId: 'your_organization_id',
|
|
662
|
+
apiKey: 'your_api_key',
|
|
663
|
+
});
|
|
664
|
+
const longUrl = 'https://hyphen.ai';
|
|
665
|
+
const domain = 'test.h4n.link';
|
|
666
|
+
const options = {
|
|
667
|
+
tags: ['sdk-test', 'unit-test'],
|
|
668
|
+
};
|
|
669
|
+
const response = await link.createShortCode(longUrl, domain, options);
|
|
670
|
+
console.log('Short Code Response:', response);
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
if you want to delete a short code you can do it like this:
|
|
674
|
+
|
|
675
|
+
```javascript
|
|
676
|
+
import { Link } from '@hyphen/sdk';
|
|
677
|
+
const link = new Link({
|
|
678
|
+
organizationId: 'your_organization_id',
|
|
679
|
+
apiKey: 'your_api_key',
|
|
680
|
+
});
|
|
681
|
+
const code = 'code_1234567890'; // It is the code identifier for the short code you want to delete
|
|
682
|
+
const response = await link.deleteShortCode(code);
|
|
683
|
+
console.log('Delete Short Code Response:', response);
|
|
684
|
+
```
|
|
685
|
+
|
|
569
686
|
# Contributing
|
|
570
687
|
|
|
571
688
|
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:
|
|
@@ -606,9 +723,19 @@ Once you have created the project, added the toggles, and created your applicati
|
|
|
606
723
|
HYPHEN_PUBLIC_API_KEY=your_public_api_key
|
|
607
724
|
HYPHEN_API_KEY=your_api_key
|
|
608
725
|
HYPHEN_APPLICATION_ID=your_project_id
|
|
726
|
+
HYPHEN_LINK_DOMAIN=your_link_domain
|
|
727
|
+
HYPHEN_ORGANIZATION_ID=your_organization_id
|
|
609
728
|
```
|
|
610
729
|
|
|
611
|
-
|
|
730
|
+
A bit more information about the environment variables:
|
|
731
|
+
|
|
732
|
+
| Variable | Example Value | Description |
|
|
733
|
+
|----------------|----------------|----------------|
|
|
734
|
+
| *HYPHEN_PUBLIC_API_KEY* | `public_api_key` | The public API key for your Hyphen project. You can find this in the Hyphen dashboard. |
|
|
735
|
+
| *HYPHEN_API_KEY* | `api_key` | The API key for your Hyphen project. You can find this in the Hyphen dashboard. |
|
|
736
|
+
| *HYPHEN_APPLICATION_ID* | `application_id` | The application ID for your Hyphen project. You can find this in the Hyphen dashboard. |
|
|
737
|
+
| *HYPHEN_LINK_DOMAIN* | `test.h4n.link` | The domain for the Link service. This is used for generating links. |
|
|
738
|
+
| *HYPHEN_ORGANIZATION_ID* | `org_668575c0e169cde974a5c76a` | | The organization ID for your Hyphen project. This is used for the Link service. |
|
|
612
739
|
|
|
613
740
|
Then run the tests with the following command:
|
|
614
741
|
|
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,471 @@ 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/link.ts
|
|
665
|
+
var import_node_process4 = __toESM(require("process"), 1);
|
|
666
|
+
loadEnv();
|
|
667
|
+
var defaultLinkUris = [
|
|
668
|
+
"https://api.hyphen.ai/api/organizations/{organizationId}/link/codes/"
|
|
669
|
+
];
|
|
670
|
+
var Link = class extends BaseService {
|
|
671
|
+
static {
|
|
672
|
+
__name(this, "Link");
|
|
673
|
+
}
|
|
674
|
+
_uris = defaultLinkUris;
|
|
675
|
+
_organizationId;
|
|
676
|
+
_apiKey;
|
|
677
|
+
constructor(options) {
|
|
678
|
+
super(options);
|
|
679
|
+
this._uris = options?.uris ?? defaultLinkUris;
|
|
680
|
+
this._organizationId = options?.organizationId;
|
|
681
|
+
if (options?.apiKey) {
|
|
682
|
+
this.setApiKey(options.apiKey);
|
|
683
|
+
}
|
|
684
|
+
if (!this._apiKey && import_node_process4.default.env.HYPHEN_API_KEY) {
|
|
685
|
+
this.setApiKey(import_node_process4.default.env.HYPHEN_API_KEY);
|
|
686
|
+
}
|
|
687
|
+
if (!this._organizationId && import_node_process4.default.env.HYPHEN_ORGANIZATION_ID) {
|
|
688
|
+
this._organizationId = import_node_process4.default.env.HYPHEN_ORGANIZATION_ID;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
/**
|
|
692
|
+
* Get the URIs for the link service. The default is `["https://api.hyphen.ai/api/organizations/{organizationId}/link/codes/"]`.
|
|
693
|
+
* @returns {string[]} The URIs for the link service.
|
|
694
|
+
*/
|
|
695
|
+
get uris() {
|
|
696
|
+
return this._uris;
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* Set the URIs for the link service. The default is `["https://api.hyphen.ai/api/organizations/{organizationId}/link/codes/"]`.
|
|
700
|
+
* @param {string[]} uris - The URIs to set.
|
|
701
|
+
*/
|
|
702
|
+
set uris(uris) {
|
|
703
|
+
this._uris = uris;
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* Get the organization ID for the link service. This is required to access the link service.
|
|
707
|
+
* @returns {string | undefined} The organization ID.
|
|
708
|
+
*/
|
|
709
|
+
get organizationId() {
|
|
710
|
+
return this._organizationId;
|
|
711
|
+
}
|
|
712
|
+
/**
|
|
713
|
+
* Set the organization ID for the link service. This is required to access the link service.
|
|
714
|
+
* @param {string | undefined} organizationId - The organization ID to set.
|
|
715
|
+
*/
|
|
716
|
+
set organizationId(organizationId) {
|
|
717
|
+
this._organizationId = organizationId;
|
|
718
|
+
}
|
|
719
|
+
/**
|
|
720
|
+
* Get the API key for the link service. This is required to access the link service.
|
|
721
|
+
* @returns {string | undefined} The API key.
|
|
722
|
+
*/
|
|
723
|
+
get apiKey() {
|
|
724
|
+
return this._apiKey;
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
727
|
+
* Set the API key for the link service. This is required to access the link service.
|
|
728
|
+
* @param {string | undefined} apiKey - The API key to set.
|
|
729
|
+
*/
|
|
730
|
+
set apiKey(apiKey) {
|
|
731
|
+
this.setApiKey(apiKey);
|
|
732
|
+
}
|
|
733
|
+
/**
|
|
734
|
+
* Set the API key for the link service. If the API key starts with 'public_', an error is thrown.
|
|
735
|
+
* This is to ensure that the API key is not a public key, which should not be used for authenticated requests.
|
|
736
|
+
* @param {string} apiKey
|
|
737
|
+
*/
|
|
738
|
+
setApiKey(apiKey) {
|
|
739
|
+
if (apiKey?.startsWith("public_")) {
|
|
740
|
+
throw new Error('API key cannot start with "public_"');
|
|
741
|
+
}
|
|
742
|
+
if (apiKey) {
|
|
743
|
+
this._apiKey = apiKey;
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
async createShortCode(longUrl, domain, options) {
|
|
747
|
+
if (!this._organizationId) {
|
|
748
|
+
throw new Error("Organization ID is required to create a short code.");
|
|
749
|
+
}
|
|
750
|
+
const url = this._uris[0].replace("{organizationId}", this._organizationId);
|
|
751
|
+
const body = {
|
|
752
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
753
|
+
long_url: longUrl,
|
|
754
|
+
domain,
|
|
755
|
+
code: options?.code,
|
|
756
|
+
title: options?.title,
|
|
757
|
+
tags: options?.tags
|
|
758
|
+
};
|
|
759
|
+
const headers = this.createHeaders(this._apiKey);
|
|
760
|
+
const response = await this.post(url, body, {
|
|
761
|
+
headers
|
|
762
|
+
});
|
|
763
|
+
if (response.status === 201) {
|
|
764
|
+
return response.data;
|
|
765
|
+
}
|
|
766
|
+
throw new Error(`Failed to create short code: ${response.statusText}`);
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* Delete a short code.
|
|
770
|
+
* @param {string} code The short code to delete. Example: 'code_686bed403c3991bd676bba4d'
|
|
771
|
+
* @returns {Promise<boolean>} A promise that resolves to true if the short code was deleted successfully, or false if it was not.
|
|
772
|
+
*/
|
|
773
|
+
async deleteShortCode(code) {
|
|
774
|
+
if (!this._organizationId) {
|
|
775
|
+
throw new Error("Organization ID is required to delete a short code.");
|
|
776
|
+
}
|
|
777
|
+
let url = this._uris[0].replace("{organizationId}", this._organizationId);
|
|
778
|
+
url = url.endsWith("/") ? `${url}${code}/` : `${url}/${code}/`;
|
|
779
|
+
const headers = this.createHeaders(this._apiKey);
|
|
780
|
+
delete headers["content-type"];
|
|
781
|
+
const response = await this.delete(url, {
|
|
782
|
+
headers
|
|
783
|
+
});
|
|
784
|
+
if (response.status === 204) {
|
|
785
|
+
return true;
|
|
786
|
+
}
|
|
787
|
+
throw new Error(`Failed to delete short code: ${response.statusText}`);
|
|
788
|
+
}
|
|
789
|
+
};
|
|
790
|
+
|
|
791
|
+
// src/hyphen.ts
|
|
792
|
+
var Hyphen = class extends import_hookified3.Hookified {
|
|
793
|
+
static {
|
|
794
|
+
__name(this, "Hyphen");
|
|
795
|
+
}
|
|
796
|
+
_netInfo;
|
|
797
|
+
_toggle;
|
|
798
|
+
_link;
|
|
799
|
+
_publicApiKey;
|
|
800
|
+
_apiKey;
|
|
801
|
+
constructor(options) {
|
|
802
|
+
super(options);
|
|
803
|
+
const toggleOptions = options?.toggle ?? {};
|
|
804
|
+
const netInfoOptions = options?.netInfo ?? {};
|
|
805
|
+
const linkOptions = options?.link ?? {};
|
|
806
|
+
if (options?.publicApiKey) {
|
|
807
|
+
this._publicApiKey = options.publicApiKey;
|
|
808
|
+
toggleOptions.publicApiKey = options.publicApiKey;
|
|
809
|
+
}
|
|
810
|
+
if (options?.apiKey) {
|
|
811
|
+
this._apiKey = options.apiKey;
|
|
812
|
+
netInfoOptions.apiKey = options.apiKey;
|
|
813
|
+
linkOptions.apiKey = options.apiKey;
|
|
814
|
+
}
|
|
815
|
+
if (options?.throwErrors !== void 0) {
|
|
816
|
+
toggleOptions.throwErrors = options.throwErrors;
|
|
817
|
+
netInfoOptions.throwErrors = options.throwErrors;
|
|
818
|
+
linkOptions.throwErrors = options.throwErrors;
|
|
819
|
+
}
|
|
820
|
+
this._netInfo = new NetInfo(netInfoOptions);
|
|
821
|
+
this._netInfo.on("error", (message, ...args) => this.emit("error", message, ...args));
|
|
822
|
+
this._netInfo.on("info", (message, ...args) => this.emit("info", message, ...args));
|
|
823
|
+
this._netInfo.on("warn", (message, ...args) => this.emit("warn", message, ...args));
|
|
824
|
+
this._toggle = new Toggle(toggleOptions);
|
|
825
|
+
this._toggle.on("error", (message, ...args) => this.emit("error", message, ...args));
|
|
826
|
+
this._toggle.on("info", (message, ...args) => this.emit("info", message, ...args));
|
|
827
|
+
this._toggle.on("warn", (message, ...args) => this.emit("warn", message, ...args));
|
|
828
|
+
this._link = new Link(linkOptions);
|
|
829
|
+
this._link.on("error", (message, ...args) => this.emit("error", message, ...args));
|
|
830
|
+
this._link.on("info", (message, ...args) => this.emit("info", message, ...args));
|
|
831
|
+
this._link.on("warn", (message, ...args) => this.emit("warn", message, ...args));
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* Get the NetInfo service instance.
|
|
835
|
+
* @returns {NetInfo} The NetInfo service instance.
|
|
836
|
+
*/
|
|
837
|
+
get netInfo() {
|
|
838
|
+
return this._netInfo;
|
|
839
|
+
}
|
|
840
|
+
/**
|
|
841
|
+
* Get the Toggle service instance.
|
|
842
|
+
* @returns {Toggle} The Toggle service instance.
|
|
843
|
+
*/
|
|
844
|
+
get toggle() {
|
|
845
|
+
return this._toggle;
|
|
846
|
+
}
|
|
847
|
+
/**
|
|
848
|
+
* Get the Link service instance.
|
|
849
|
+
* @returns {Link} The Link service instance.
|
|
850
|
+
*/
|
|
851
|
+
get link() {
|
|
852
|
+
return this._link;
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
855
|
+
* Get the public API key for the Hyphen service.
|
|
856
|
+
* This is used for public endpoints that do not require authentication.
|
|
857
|
+
* @returns {string | undefined} The public API key.
|
|
858
|
+
*/
|
|
859
|
+
get publicApiKey() {
|
|
860
|
+
return this._publicApiKey;
|
|
861
|
+
}
|
|
862
|
+
/**
|
|
863
|
+
* Set the public API key for the Hyphen service. If set, this will also update the underlying services.
|
|
864
|
+
* This is used for public endpoints that do not require authentication such as the Toggle service.
|
|
865
|
+
* @param {string | undefined} value - The public API key to set.
|
|
866
|
+
*/
|
|
867
|
+
set publicApiKey(value) {
|
|
868
|
+
this._publicApiKey = value;
|
|
869
|
+
this._toggle.publicApiKey = value;
|
|
870
|
+
}
|
|
871
|
+
/**
|
|
872
|
+
* Get the API key for the Hyphen service.
|
|
873
|
+
* This is used for authenticated endpoints that require an API key such as the NetInfo and Link services.
|
|
874
|
+
* @returns {string | undefined} The API key.
|
|
875
|
+
*/
|
|
876
|
+
get apiKey() {
|
|
877
|
+
return this._apiKey;
|
|
878
|
+
}
|
|
879
|
+
/**
|
|
880
|
+
* Set the API key for the Hyphen service. If set, this will also update the underlying services.
|
|
881
|
+
* This is used for authenticated endpoints that require an API key such as the NetInfo and Link services.
|
|
882
|
+
* @param {string | undefined} value - The API key to set.
|
|
883
|
+
*/
|
|
884
|
+
set apiKey(value) {
|
|
885
|
+
this._apiKey = value;
|
|
886
|
+
this._netInfo.apiKey = value;
|
|
887
|
+
this._link.apiKey = value;
|
|
888
|
+
}
|
|
889
|
+
/**
|
|
890
|
+
* Get whether to throw errors or not.
|
|
891
|
+
* If set to true, errors will be thrown instead of logged.
|
|
892
|
+
* @returns {boolean} Whether to throw errors or not.
|
|
893
|
+
*/
|
|
894
|
+
get throwErrors() {
|
|
895
|
+
return this._netInfo.throwErrors && this._toggle.throwErrors && this._link.throwErrors;
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
898
|
+
* Set whether to throw errors or not. If set to true, errors will be thrown instead of logged.
|
|
899
|
+
* This will update the underlying services as well.
|
|
900
|
+
* @param {boolean} value - Whether to throw errors or not.
|
|
901
|
+
*/
|
|
902
|
+
set throwErrors(value) {
|
|
903
|
+
this._netInfo.throwErrors = value;
|
|
904
|
+
this._toggle.throwErrors = value;
|
|
905
|
+
this._link.throwErrors = value;
|
|
906
|
+
}
|
|
907
|
+
};
|
|
445
908
|
// Annotate the CommonJS export names for ESM import in node:
|
|
446
909
|
0 && (module.exports = {
|
|
910
|
+
Hyphen,
|
|
447
911
|
Toggle,
|
|
448
912
|
ToggleHooks,
|
|
449
913
|
loadEnv
|