@hyphen/sdk 1.12.1 → 1.13.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/dist/index.cjs CHANGED
@@ -101,15 +101,15 @@ var import_node_buffer = require("buffer");
101
101
  var import_node_process2 = __toESM(require("process"), 1);
102
102
 
103
103
  // src/base-service.ts
104
- var import_axios = __toESM(require("axios"), 1);
104
+ var import_net = require("@cacheable/net");
105
105
  var import_cacheable = require("cacheable");
106
106
  var import_hookified = require("hookified");
107
107
  var import_pino = __toESM(require("pino"), 1);
108
- var ErrorMessages = /* @__PURE__ */ function(ErrorMessages2) {
108
+ var ErrorMessages = /* @__PURE__ */ (function(ErrorMessages2) {
109
109
  ErrorMessages2["API_KEY_REQUIRED"] = "API key is required. Please provide it via options or set the HYPHEN_API_KEY environment variable.";
110
110
  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.";
111
111
  return ErrorMessages2;
112
- }({});
112
+ })({});
113
113
  var BaseService = class extends import_hookified.Hookified {
114
114
  static {
115
115
  __name(this, "BaseService");
@@ -117,11 +117,16 @@ var BaseService = class extends import_hookified.Hookified {
117
117
  _log = (0, import_pino.default)();
118
118
  _cache = new import_cacheable.Cacheable();
119
119
  _throwErrors = false;
120
+ _net;
120
121
  constructor(options) {
121
122
  super(options);
122
123
  if (options && options.throwErrors !== void 0) {
123
124
  this._throwErrors = options.throwErrors;
124
125
  }
126
+ this._net = new import_net.CacheableNet({
127
+ cache: this._cache,
128
+ useHttpCache: false
129
+ });
125
130
  }
126
131
  get log() {
127
132
  return this._log;
@@ -134,6 +139,7 @@ var BaseService = class extends import_hookified.Hookified {
134
139
  }
135
140
  set cache(value) {
136
141
  this._cache = value;
142
+ this._net.cache = value;
137
143
  }
138
144
  get throwErrors() {
139
145
  return this._throwErrors;
@@ -157,22 +163,103 @@ var BaseService = class extends import_hookified.Hookified {
157
163
  this.emit("info", message, ...args);
158
164
  }
159
165
  async get(url, config2) {
160
- return import_axios.default.get(url, config2);
166
+ let finalUrl = url;
167
+ if (config2?.params) {
168
+ const params = new URLSearchParams(config2.params);
169
+ finalUrl = `${url}?${params.toString()}`;
170
+ }
171
+ const { params: _, ...fetchConfig } = config2 || {};
172
+ const response = await this._net.get(finalUrl, fetchConfig);
173
+ return {
174
+ data: response.data,
175
+ status: response.response.status,
176
+ statusText: response.response.statusText,
177
+ headers: response.response.headers,
178
+ config: config2,
179
+ request: void 0
180
+ };
161
181
  }
162
182
  async post(url, data, config2) {
163
- return import_axios.default.post(url, data, config2);
183
+ const response = await this._net.post(url, data, config2);
184
+ return {
185
+ data: response.data,
186
+ status: response.response.status,
187
+ statusText: response.response.statusText,
188
+ headers: response.response.headers,
189
+ config: config2,
190
+ request: void 0
191
+ };
164
192
  }
165
193
  async put(url, data, config2) {
166
- return import_axios.default.put(url, data, config2);
194
+ const requestInit = {
195
+ ...config2,
196
+ method: "PUT",
197
+ body: typeof data === "string" ? data : JSON.stringify(data),
198
+ headers: {
199
+ "Content-Type": "application/json",
200
+ ...config2?.headers
201
+ }
202
+ };
203
+ const response = await this._net.fetch(url, requestInit);
204
+ const responseData = await response.json();
205
+ return {
206
+ data: responseData,
207
+ status: response.status,
208
+ statusText: response.statusText,
209
+ headers: response.headers,
210
+ config: config2,
211
+ request: void 0
212
+ };
167
213
  }
168
214
  async delete(url, config2) {
169
- if (config2?.headers) {
170
- delete config2.headers["content-type"];
215
+ const headers = {
216
+ ...config2?.headers
217
+ };
218
+ if (headers) {
219
+ delete headers["content-type"];
171
220
  }
172
- return import_axios.default.delete(url, config2);
221
+ const { data: configData, ...restConfig } = config2 || {};
222
+ let body;
223
+ if (configData) {
224
+ body = typeof configData === "string" ? configData : JSON.stringify(configData);
225
+ if (!headers["content-type"] && !headers["Content-Type"]) {
226
+ headers["content-type"] = "application/json";
227
+ }
228
+ }
229
+ const response = await this._net.fetch(url, {
230
+ ...restConfig,
231
+ headers,
232
+ body,
233
+ method: "DELETE"
234
+ });
235
+ let data;
236
+ if (response.status !== 204) {
237
+ const text = await response.text();
238
+ try {
239
+ data = text ? JSON.parse(text) : void 0;
240
+ } catch {
241
+ data = text;
242
+ }
243
+ }
244
+ return {
245
+ data,
246
+ status: response.status,
247
+ statusText: response.statusText,
248
+ headers: response.headers,
249
+ config: config2,
250
+ request: void 0
251
+ };
173
252
  }
174
253
  async patch(url, data, config2) {
175
- return import_axios.default.patch(url, data, config2);
254
+ const response = await this._net.patch(url, data, config2);
255
+ return {
256
+ data: response.data,
257
+ status: response.response.status,
258
+ statusText: response.response.statusText,
259
+ headers: response.response.headers,
260
+ config: config2,
261
+ request: void 0
262
+ };
176
263
  }
177
264
  createHeaders(apiKey) {
178
265
  const headers = {
@@ -695,8 +782,10 @@ var import_openfeature_server_provider = require("@hyphen/openfeature-server-pro
695
782
  var import_server_sdk = require("@openfeature/server-sdk");
696
783
  var import_dotenv2 = __toESM(require("dotenv"), 1);
697
784
  var import_hookified2 = require("hookified");
698
- import_dotenv2.default.config();
699
- var ToggleHooks = /* @__PURE__ */ function(ToggleHooks2) {
785
+ import_dotenv2.default.config({
786
+ quiet: true
787
+ });
788
+ var ToggleHooks = /* @__PURE__ */ (function(ToggleHooks2) {
700
789
  ToggleHooks2["beforeGetBoolean"] = "beforeGetBoolean";
701
790
  ToggleHooks2["afterGetBoolean"] = "afterGetBoolean";
702
791
  ToggleHooks2["beforeGetString"] = "beforeGetString";
@@ -706,7 +795,7 @@ var ToggleHooks = /* @__PURE__ */ function(ToggleHooks2) {
706
795
  ToggleHooks2["beforeGetObject"] = "beforeGetObject";
707
796
  ToggleHooks2["afterGetObject"] = "afterGetObject";
708
797
  return ToggleHooks2;
709
- }({});
798
+ })({});
710
799
  var Toggle = class extends import_hookified2.Hookified {
711
800
  static {
712
801
  __name(this, "Toggle");
package/dist/index.d.cts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { HookifiedOptions, Hookified } from 'hookified';
2
- import * as axios from 'axios';
3
- import { AxiosRequestConfig } from 'axios';
2
+ import { FetchRequestInit } from '@cacheable/net';
4
3
  import { Cacheable } from 'cacheable';
5
4
  import pino from 'pino';
6
5
  import { EvaluationContext, Client } from '@openfeature/server-sdk';
@@ -23,6 +22,14 @@ declare function env(options?: EnvOptions): void;
23
22
  declare const loadEnv: typeof env;
24
23
  type LoadEnvOptions = EnvOptions;
25
24
 
25
+ interface HttpResponse<T = any> {
26
+ data: T;
27
+ status: number;
28
+ statusText: string;
29
+ headers: any;
30
+ config: any;
31
+ request?: any;
32
+ }
26
33
  type BaseServiceOptions = {
27
34
  throwErrors?: boolean;
28
35
  } & HookifiedOptions;
@@ -30,6 +37,7 @@ declare class BaseService extends Hookified {
30
37
  private _log;
31
38
  private _cache;
32
39
  private _throwErrors;
40
+ private _net;
33
41
  constructor(options?: BaseServiceOptions);
34
42
  get log(): pino.Logger;
35
43
  set log(value: pino.Logger);
@@ -40,11 +48,15 @@ declare class BaseService extends Hookified {
40
48
  error(message: string, ...args: any[]): void;
41
49
  warn(message: string, ...args: any[]): void;
42
50
  info(message: string, ...args: any[]): void;
43
- get<T>(url: string, config?: AxiosRequestConfig): Promise<axios.AxiosResponse<T, any>>;
44
- post<T>(url: string, data: any, config?: AxiosRequestConfig): Promise<axios.AxiosResponse<T, any>>;
45
- put<T>(url: string, data: any, config?: AxiosRequestConfig): Promise<axios.AxiosResponse<T, any>>;
46
- delete<T>(url: string, config?: AxiosRequestConfig): Promise<axios.AxiosResponse<T, any>>;
47
- patch<T>(url: string, data: any, config?: AxiosRequestConfig): Promise<axios.AxiosResponse<T, any>>;
51
+ get<T>(url: string, config?: FetchRequestInit & {
52
+ params?: any;
53
+ }): Promise<HttpResponse<T>>;
54
+ post<T>(url: string, data: any, config?: FetchRequestInit): Promise<HttpResponse<T>>;
55
+ put<T>(url: string, data: any, config?: FetchRequestInit): Promise<HttpResponse<T>>;
56
+ delete<T>(url: string, config?: FetchRequestInit & {
57
+ data?: any;
58
+ }): Promise<HttpResponse<T>>;
59
+ patch<T>(url: string, data: any, config?: FetchRequestInit): Promise<HttpResponse<T>>;
48
60
  createHeaders(apiKey?: string): Record<string, string>;
49
61
  }
50
62
 
package/dist/index.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { HookifiedOptions, Hookified } from 'hookified';
2
- import * as axios from 'axios';
3
- import { AxiosRequestConfig } from 'axios';
2
+ import { FetchRequestInit } from '@cacheable/net';
4
3
  import { Cacheable } from 'cacheable';
5
4
  import pino from 'pino';
6
5
  import { EvaluationContext, Client } from '@openfeature/server-sdk';
@@ -23,6 +22,14 @@ declare function env(options?: EnvOptions): void;
23
22
  declare const loadEnv: typeof env;
24
23
  type LoadEnvOptions = EnvOptions;
25
24
 
25
+ interface HttpResponse<T = any> {
26
+ data: T;
27
+ status: number;
28
+ statusText: string;
29
+ headers: any;
30
+ config: any;
31
+ request?: any;
32
+ }
26
33
  type BaseServiceOptions = {
27
34
  throwErrors?: boolean;
28
35
  } & HookifiedOptions;
@@ -30,6 +37,7 @@ declare class BaseService extends Hookified {
30
37
  private _log;
31
38
  private _cache;
32
39
  private _throwErrors;
40
+ private _net;
33
41
  constructor(options?: BaseServiceOptions);
34
42
  get log(): pino.Logger;
35
43
  set log(value: pino.Logger);
@@ -40,11 +48,15 @@ declare class BaseService extends Hookified {
40
48
  error(message: string, ...args: any[]): void;
41
49
  warn(message: string, ...args: any[]): void;
42
50
  info(message: string, ...args: any[]): void;
43
- get<T>(url: string, config?: AxiosRequestConfig): Promise<axios.AxiosResponse<T, any>>;
44
- post<T>(url: string, data: any, config?: AxiosRequestConfig): Promise<axios.AxiosResponse<T, any>>;
45
- put<T>(url: string, data: any, config?: AxiosRequestConfig): Promise<axios.AxiosResponse<T, any>>;
46
- delete<T>(url: string, config?: AxiosRequestConfig): Promise<axios.AxiosResponse<T, any>>;
47
- patch<T>(url: string, data: any, config?: AxiosRequestConfig): Promise<axios.AxiosResponse<T, any>>;
51
+ get<T>(url: string, config?: FetchRequestInit & {
52
+ params?: any;
53
+ }): Promise<HttpResponse<T>>;
54
+ post<T>(url: string, data: any, config?: FetchRequestInit): Promise<HttpResponse<T>>;
55
+ put<T>(url: string, data: any, config?: FetchRequestInit): Promise<HttpResponse<T>>;
56
+ delete<T>(url: string, config?: FetchRequestInit & {
57
+ data?: any;
58
+ }): Promise<HttpResponse<T>>;
59
+ patch<T>(url: string, data: any, config?: FetchRequestInit): Promise<HttpResponse<T>>;
48
60
  createHeaders(apiKey?: string): Record<string, string>;
49
61
  }
50
62
 
package/dist/index.js CHANGED
@@ -63,15 +63,15 @@ import { Buffer as Buffer2 } from "buffer";
63
63
  import process2 from "process";
64
64
 
65
65
  // src/base-service.ts
66
- import axios from "axios";
66
+ import { CacheableNet } from "@cacheable/net";
67
67
  import { Cacheable } from "cacheable";
68
68
  import { Hookified } from "hookified";
69
69
  import pino from "pino";
70
- var ErrorMessages = /* @__PURE__ */ function(ErrorMessages2) {
70
+ var ErrorMessages = /* @__PURE__ */ (function(ErrorMessages2) {
71
71
  ErrorMessages2["API_KEY_REQUIRED"] = "API key is required. Please provide it via options or set the HYPHEN_API_KEY environment variable.";
72
72
  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.";
73
73
  return ErrorMessages2;
74
- }({});
74
+ })({});
75
75
  var BaseService = class extends Hookified {
76
76
  static {
77
77
  __name(this, "BaseService");
@@ -79,11 +79,16 @@ var BaseService = class extends Hookified {
79
79
  _log = pino();
80
80
  _cache = new Cacheable();
81
81
  _throwErrors = false;
82
+ _net;
82
83
  constructor(options) {
83
84
  super(options);
84
85
  if (options && options.throwErrors !== void 0) {
85
86
  this._throwErrors = options.throwErrors;
86
87
  }
88
+ this._net = new CacheableNet({
89
+ cache: this._cache,
90
+ useHttpCache: false
91
+ });
87
92
  }
88
93
  get log() {
89
94
  return this._log;
@@ -96,6 +101,7 @@ var BaseService = class extends Hookified {
96
101
  }
97
102
  set cache(value) {
98
103
  this._cache = value;
104
+ this._net.cache = value;
99
105
  }
100
106
  get throwErrors() {
101
107
  return this._throwErrors;
@@ -119,22 +125,103 @@ var BaseService = class extends Hookified {
119
125
  this.emit("info", message, ...args);
120
126
  }
121
127
  async get(url, config2) {
122
- return axios.get(url, config2);
128
+ let finalUrl = url;
129
+ if (config2?.params) {
130
+ const params = new URLSearchParams(config2.params);
131
+ finalUrl = `${url}?${params.toString()}`;
132
+ }
133
+ const { params: _, ...fetchConfig } = config2 || {};
134
+ const response = await this._net.get(finalUrl, fetchConfig);
135
+ return {
136
+ data: response.data,
137
+ status: response.response.status,
138
+ statusText: response.response.statusText,
139
+ headers: response.response.headers,
140
+ config: config2,
141
+ request: void 0
142
+ };
123
143
  }
124
144
  async post(url, data, config2) {
125
- return axios.post(url, data, config2);
145
+ const response = await this._net.post(url, data, config2);
146
+ return {
147
+ data: response.data,
148
+ status: response.response.status,
149
+ statusText: response.response.statusText,
150
+ headers: response.response.headers,
151
+ config: config2,
152
+ request: void 0
153
+ };
126
154
  }
127
155
  async put(url, data, config2) {
128
- return axios.put(url, data, config2);
156
+ const requestInit = {
157
+ ...config2,
158
+ method: "PUT",
159
+ body: typeof data === "string" ? data : JSON.stringify(data),
160
+ headers: {
161
+ "Content-Type": "application/json",
162
+ ...config2?.headers
163
+ }
164
+ };
165
+ const response = await this._net.fetch(url, requestInit);
166
+ const responseData = await response.json();
167
+ return {
168
+ data: responseData,
169
+ status: response.status,
170
+ statusText: response.statusText,
171
+ headers: response.headers,
172
+ config: config2,
173
+ request: void 0
174
+ };
129
175
  }
130
176
  async delete(url, config2) {
131
- if (config2?.headers) {
132
- delete config2.headers["content-type"];
177
+ const headers = {
178
+ ...config2?.headers
179
+ };
180
+ if (headers) {
181
+ delete headers["content-type"];
133
182
  }
134
- return axios.delete(url, config2);
183
+ const { data: configData, ...restConfig } = config2 || {};
184
+ let body;
185
+ if (configData) {
186
+ body = typeof configData === "string" ? configData : JSON.stringify(configData);
187
+ if (!headers["content-type"] && !headers["Content-Type"]) {
188
+ headers["content-type"] = "application/json";
189
+ }
190
+ }
191
+ const response = await this._net.fetch(url, {
192
+ ...restConfig,
193
+ headers,
194
+ body,
195
+ method: "DELETE"
196
+ });
197
+ let data;
198
+ if (response.status !== 204) {
199
+ const text = await response.text();
200
+ try {
201
+ data = text ? JSON.parse(text) : void 0;
202
+ } catch {
203
+ data = text;
204
+ }
205
+ }
206
+ return {
207
+ data,
208
+ status: response.status,
209
+ statusText: response.statusText,
210
+ headers: response.headers,
211
+ config: config2,
212
+ request: void 0
213
+ };
135
214
  }
136
215
  async patch(url, data, config2) {
137
- return axios.patch(url, data, config2);
216
+ const response = await this._net.patch(url, data, config2);
217
+ return {
218
+ data: response.data,
219
+ status: response.response.status,
220
+ statusText: response.response.statusText,
221
+ headers: response.response.headers,
222
+ config: config2,
223
+ request: void 0
224
+ };
138
225
  }
139
226
  createHeaders(apiKey) {
140
227
  const headers = {
@@ -657,8 +744,10 @@ import { HyphenProvider } from "@hyphen/openfeature-server-provider";
657
744
  import { OpenFeature } from "@openfeature/server-sdk";
658
745
  import dotenv from "dotenv";
659
746
  import { Hookified as Hookified2 } from "hookified";
660
- dotenv.config();
661
- var ToggleHooks = /* @__PURE__ */ function(ToggleHooks2) {
747
+ dotenv.config({
748
+ quiet: true
749
+ });
750
+ var ToggleHooks = /* @__PURE__ */ (function(ToggleHooks2) {
662
751
  ToggleHooks2["beforeGetBoolean"] = "beforeGetBoolean";
663
752
  ToggleHooks2["afterGetBoolean"] = "afterGetBoolean";
664
753
  ToggleHooks2["beforeGetString"] = "beforeGetString";
@@ -668,7 +757,7 @@ var ToggleHooks = /* @__PURE__ */ function(ToggleHooks2) {
668
757
  ToggleHooks2["beforeGetObject"] = "beforeGetObject";
669
758
  ToggleHooks2["afterGetObject"] = "afterGetObject";
670
759
  return ToggleHooks2;
671
- }({});
760
+ })({});
672
761
  var Toggle = class extends Hookified2 {
673
762
  static {
674
763
  __name(this, "Toggle");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyphen/sdk",
3
- "version": "1.12.1",
3
+ "version": "1.13.0",
4
4
  "description": "Hyphen SDK for Node.js",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -13,8 +13,9 @@
13
13
  },
14
14
  "types": "dist/index.d.ts",
15
15
  "scripts": {
16
- "test": "biome check --write && vitest run --coverage",
17
- "test:ci": "biome check && vitest run --coverage",
16
+ "lint": "biome check --write --error-on-warnings",
17
+ "test": "pnpm lint && vitest run --coverage",
18
+ "test:ci": "biome check --error-on-warnings && vitest run --coverage",
18
19
  "build": "rimraf ./dist && tsup src/index.ts --format esm,cjs --dts --clean",
19
20
  "clean": "rimraf ./dist pnpm-lock.yaml node_modules coverage",
20
21
  "prepublishOnly": "rimraf ./dist && tsup src/index.ts --format esm,cjs --dts --clean"
@@ -29,9 +30,9 @@
29
30
  "author": "Team Hyphen <hello@hyphen.ai>",
30
31
  "license": "MIT",
31
32
  "devDependencies": {
32
- "@biomejs/biome": "^2.1.4",
33
- "@swc/core": "^1.13.3",
34
- "@types/node": "^24.2.1",
33
+ "@biomejs/biome": "^2.2.4",
34
+ "@swc/core": "^1.13.20",
35
+ "@types/node": "^24.5.2",
35
36
  "@vitest/coverage-v8": "^3.2.4",
36
37
  "rimraf": "^6.0.1",
37
38
  "tsd": "^0.33.0",
@@ -44,13 +45,14 @@
44
45
  "LICENSE"
45
46
  ],
46
47
  "dependencies": {
47
- "@faker-js/faker": "^9.9.0",
48
+ "@cacheable/net": "^1.0.2",
49
+ "@faker-js/faker": "^10.0.0",
48
50
  "@hyphen/openfeature-server-provider": "^1.0.7",
49
- "@openfeature/server-sdk": "^1.18.0",
50
- "axios": "^1.11.0",
51
- "cacheable": "^1.10.3",
52
- "dotenv": "^17.2.1",
53
- "hookified": "^1.11.0",
54
- "pino": "^9.8.0"
51
+ "@openfeature/core": "^1.9.0",
52
+ "@openfeature/server-sdk": "^1.19.0",
53
+ "cacheable": "^2.0.2",
54
+ "dotenv": "^17.2.2",
55
+ "hookified": "^1.12.1",
56
+ "pino": "^9.11.0"
55
57
  }
56
58
  }