@hyphen/sdk 1.11.0 → 1.12.1

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.js CHANGED
@@ -1,503 +1,530 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
3
 
4
- // src/toggle.ts
4
+ // src/env.ts
5
+ import fs from "fs";
6
+ import path from "path";
5
7
  import process from "process";
8
+ import { config } from "dotenv";
9
+ function env(options) {
10
+ const local = options?.local ?? true;
11
+ const currentWorkingDirectory = options?.path ?? process.cwd();
12
+ const envPath = path.resolve(currentWorkingDirectory, ".env");
13
+ if (fs.existsSync(envPath)) {
14
+ config({
15
+ path: envPath,
16
+ quiet: true,
17
+ debug: false
18
+ });
19
+ }
20
+ if (local) {
21
+ const localEnvPath = path.resolve(currentWorkingDirectory, ".env.local");
22
+ if (fs.existsSync(localEnvPath)) {
23
+ config({
24
+ path: localEnvPath,
25
+ override: true,
26
+ quiet: true,
27
+ debug: false
28
+ });
29
+ }
30
+ }
31
+ const environment = options?.environment ?? process.env.NODE_ENV;
32
+ if (environment) {
33
+ const envSpecificPath = path.resolve(currentWorkingDirectory, `.env.${environment}`);
34
+ if (fs.existsSync(envSpecificPath)) {
35
+ config({
36
+ path: envSpecificPath,
37
+ override: true,
38
+ quiet: true,
39
+ debug: false
40
+ });
41
+ }
42
+ if (local) {
43
+ const envLocalPath = path.resolve(currentWorkingDirectory, `.env.${environment}.local`);
44
+ if (fs.existsSync(envLocalPath)) {
45
+ config({
46
+ path: envLocalPath,
47
+ override: true,
48
+ quiet: true,
49
+ debug: false
50
+ });
51
+ }
52
+ }
53
+ }
54
+ }
55
+ __name(env, "env");
56
+ var loadEnv = env;
57
+
58
+ // src/hyphen.ts
59
+ import { Hookified as Hookified3 } from "hookified";
60
+
61
+ // src/link.ts
62
+ import { Buffer as Buffer2 } from "buffer";
63
+ import process2 from "process";
64
+
65
+ // src/base-service.ts
66
+ import axios from "axios";
67
+ import { Cacheable } from "cacheable";
6
68
  import { Hookified } from "hookified";
7
- import dotenv from "dotenv";
8
- import { OpenFeature } from "@openfeature/server-sdk";
9
- import { HyphenProvider } from "@hyphen/openfeature-server-provider";
10
- dotenv.config();
11
- var ToggleHooks = /* @__PURE__ */ function(ToggleHooks2) {
12
- ToggleHooks2["beforeGetBoolean"] = "beforeGetBoolean";
13
- ToggleHooks2["afterGetBoolean"] = "afterGetBoolean";
14
- ToggleHooks2["beforeGetString"] = "beforeGetString";
15
- ToggleHooks2["afterGetString"] = "afterGetString";
16
- ToggleHooks2["beforeGetNumber"] = "beforeGetNumber";
17
- ToggleHooks2["afterGetNumber"] = "afterGetNumber";
18
- ToggleHooks2["beforeGetObject"] = "beforeGetObject";
19
- ToggleHooks2["afterGetObject"] = "afterGetObject";
20
- return ToggleHooks2;
69
+ import pino from "pino";
70
+ var ErrorMessages = /* @__PURE__ */ function(ErrorMessages2) {
71
+ ErrorMessages2["API_KEY_REQUIRED"] = "API key is required. Please provide it via options or set the HYPHEN_API_KEY environment variable.";
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
+ return ErrorMessages2;
21
74
  }({});
22
- var Toggle = class extends Hookified {
75
+ var BaseService = class extends Hookified {
23
76
  static {
24
- __name(this, "Toggle");
77
+ __name(this, "BaseService");
25
78
  }
26
- _applicationId = process.env.HYPHEN_APPLICATION_ID;
27
- _publicApiKey = process.env.HYPHEN_PUBLIC_API_KEY;
28
- _environment;
29
- _client;
30
- _context;
79
+ _log = pino();
80
+ _cache = new Cacheable();
31
81
  _throwErrors = false;
32
- _uris;
33
- _caching;
34
- /*
35
- * Create a new Toggle instance. This will create a new client and set the options.
36
- * @param {ToggleOptions}
37
- */
38
82
  constructor(options) {
39
- super();
40
- this._throwErrors = options?.throwErrors ?? false;
41
- this._applicationId = options?.applicationId;
42
- if (options?.publicApiKey) {
43
- this.setPublicApiKey(options.publicApiKey);
83
+ super(options);
84
+ if (options && options.throwErrors !== void 0) {
85
+ this._throwErrors = options.throwErrors;
44
86
  }
45
- this._environment = options?.environment ?? process.env.NODE_ENV ?? "development";
46
- this._context = options?.context;
47
- this._uris = options?.uris;
48
- this._caching = options?.caching;
49
- }
50
- /**
51
- * Get the application ID
52
- * @returns {string | undefined}
53
- */
54
- get applicationId() {
55
- return this._applicationId;
56
- }
57
- /**
58
- * Set the application ID
59
- * @param {string | undefined} value
60
- */
61
- set applicationId(value) {
62
- this._applicationId = value;
63
87
  }
64
- /**
65
- * Get the public API key
66
- * @returns {string}
67
- */
68
- get publicApiKey() {
69
- return this._publicApiKey;
88
+ get log() {
89
+ return this._log;
70
90
  }
71
- /**
72
- * Set the public API key
73
- * @param {string} value
74
- */
75
- set publicApiKey(value) {
76
- if (!value) {
77
- this._publicApiKey = void 0;
78
- this._client = void 0;
79
- return;
80
- }
81
- this.setPublicApiKey(value);
91
+ set log(value) {
92
+ this._log = value;
82
93
  }
83
- /**
84
- * Get the environment
85
- * @returns {string}
86
- */
87
- get environment() {
88
- return this._environment;
94
+ get cache() {
95
+ return this._cache;
89
96
  }
90
- /**
91
- * Set the environment
92
- * @param {string} value
93
- */
94
- set environment(value) {
95
- this._environment = value;
97
+ set cache(value) {
98
+ this._cache = value;
96
99
  }
97
- /**
98
- * Get the throwErrors. If true, errors will be thrown in addition to being emitted.
99
- * @returns {boolean}
100
- */
101
100
  get throwErrors() {
102
101
  return this._throwErrors;
103
102
  }
104
- /**
105
- * Set the throwErrors. If true, errors will be thrown in addition to being emitted.
106
- * @param {boolean} value
107
- */
108
103
  set throwErrors(value) {
109
104
  this._throwErrors = value;
110
105
  }
111
- /**
112
- * Get the current context. This is the default context used. You can override this at the get function level.
113
- * @returns {ToggleContext}
114
- */
115
- get context() {
116
- return this._context;
106
+ error(message, ...args) {
107
+ this._log.error(message, ...args);
108
+ this.emit("error", message, ...args);
109
+ if (this.throwErrors) {
110
+ throw new Error(message);
111
+ }
117
112
  }
118
- /**
119
- * Set the context. This is the default context used. You can override this at the get function level.
120
- * @param {ToggleContext} value
121
- */
122
- set context(value) {
123
- this._context = value;
113
+ warn(message, ...args) {
114
+ this._log.warn(message, ...args);
115
+ this.emit("warn", message, ...args);
116
+ }
117
+ info(message, ...args) {
118
+ this._log.info(message, ...args);
119
+ this.emit("info", message, ...args);
120
+ }
121
+ async get(url, config2) {
122
+ return axios.get(url, config2);
123
+ }
124
+ async post(url, data, config2) {
125
+ return axios.post(url, data, config2);
126
+ }
127
+ async put(url, data, config2) {
128
+ return axios.put(url, data, config2);
129
+ }
130
+ async delete(url, config2) {
131
+ if (config2?.headers) {
132
+ delete config2.headers["content-type"];
133
+ }
134
+ return axios.delete(url, config2);
135
+ }
136
+ async patch(url, data, config2) {
137
+ return axios.patch(url, data, config2);
138
+ }
139
+ createHeaders(apiKey) {
140
+ const headers = {
141
+ "content-type": "application/json",
142
+ accept: "application/json"
143
+ };
144
+ if (apiKey) {
145
+ headers["x-api-key"] = apiKey;
146
+ }
147
+ return headers;
148
+ }
149
+ };
150
+
151
+ // src/link.ts
152
+ env();
153
+ var defaultLinkUris = [
154
+ "https://api.hyphen.ai/api/organizations/{organizationId}/link/codes/"
155
+ ];
156
+ var Link = class extends BaseService {
157
+ static {
158
+ __name(this, "Link");
159
+ }
160
+ _uris = defaultLinkUris;
161
+ _organizationId;
162
+ _apiKey;
163
+ constructor(options) {
164
+ super(options);
165
+ this._uris = options?.uris ?? defaultLinkUris;
166
+ this._organizationId = options?.organizationId;
167
+ if (options?.apiKey) {
168
+ this.setApiKey(options.apiKey);
169
+ }
170
+ if (!this._apiKey && process2.env.HYPHEN_API_KEY) {
171
+ this.setApiKey(process2.env.HYPHEN_API_KEY);
172
+ }
173
+ if (!this._organizationId && process2.env.HYPHEN_ORGANIZATION_ID) {
174
+ this._organizationId = process2.env.HYPHEN_ORGANIZATION_ID;
175
+ }
124
176
  }
125
177
  /**
126
- * Get the URIs. This is used to override the default URIs for testing or if you are using a self-hosted version.
127
- * @returns {Array<string>}
178
+ * Get the URIs for the link service. The default is `["https://api.hyphen.ai/api/organizations/{organizationId}/link/codes/"]`.
179
+ * @returns {string[]} The URIs for the link service.
128
180
  */
129
181
  get uris() {
130
182
  return this._uris;
131
183
  }
132
184
  /**
133
- * Set the URIs. This is used to override the default URIs for testing or if you are using a self-hosted version.
134
- * @param {Array<string>} value
185
+ * Set the URIs for the link service. The default is `["https://api.hyphen.ai/api/organizations/{organizationId}/link/codes/"]`.
186
+ * @param {string[]} uris - The URIs to set.
135
187
  */
136
- set uris(value) {
137
- this._uris = value;
188
+ set uris(uris) {
189
+ this._uris = uris;
138
190
  }
139
191
  /**
140
- * Get the caching options.
141
- * @returns {ToggleCachingOptions | undefined}
192
+ * Get the organization ID for the link service. This is required to access the link service.
193
+ * @returns {string | undefined} The organization ID.
142
194
  */
143
- get caching() {
144
- return this._caching;
195
+ get organizationId() {
196
+ return this._organizationId;
145
197
  }
146
198
  /**
147
- * Set the caching options.
148
- * @param {ToggleCachingOptions | undefined} value
199
+ * Set the organization ID for the link service. This is required to access the link service.
200
+ * @param {string | undefined} organizationId - The organization ID to set.
149
201
  */
150
- set caching(value) {
151
- this._caching = value;
202
+ set organizationId(organizationId) {
203
+ this._organizationId = organizationId;
152
204
  }
153
205
  /**
154
- * This is a helper function to set the public API key. It will check if the key starts with public_ and set it. If it
155
- * does set it will also set the client to undefined to force a new one to be created. If it does not,
156
- * it will emit an error and console warning and not set the key. Used by the constructor and publicApiKey setter.
157
- * @param key
158
- * @returns
206
+ * Get the API key for the link service. This is required to access the link service.
207
+ * @returns {string | undefined} The API key.
159
208
  */
160
- setPublicApiKey(key) {
161
- if (!key.startsWith("public_")) {
162
- this.emit("error", new Error("Public API key should start with public_"));
163
- if (process.env.NODE_ENV !== "production") {
164
- console.error("Public API key should start with public_");
165
- }
166
- return;
167
- }
168
- this._publicApiKey = key;
169
- this._client = void 0;
209
+ get apiKey() {
210
+ return this._apiKey;
170
211
  }
171
212
  /**
172
- * Set the context. This is the default context used. You can override this at the get function level.
173
- * @param {ToggleContext} context
213
+ * Set the API key for the link service. This is required to access the link service.
214
+ * @param {string | undefined} apiKey - The API key to set.
174
215
  */
175
- setContext(context) {
176
- this._context = context;
177
- this._client = void 0;
216
+ set apiKey(apiKey) {
217
+ this.setApiKey(apiKey);
178
218
  }
179
219
  /**
180
- * Helper function to get the client. This will create a new client if one does not exist. It will also set the
181
- * application ID, environment, and URIs if they are not set. This is used by the get function to get the client.
182
- * This is normally only used internally.
183
- * @returns {Promise<Client>}
220
+ * Set the API key for the link service. If the API key starts with 'public_', an error is thrown.
221
+ * This is to ensure that the API key is not a public key, which should not be used for authenticated requests.
222
+ * @param {string} apiKey
184
223
  */
185
- async getClient() {
186
- if (!this._client) {
187
- if (this._applicationId === void 0 || this._applicationId.length === 0) {
188
- const errorMessage = "Application ID is not set. You must set it before using the client or have the HYPHEN_APPLICATION_ID environment variable set.";
189
- this.emit("error", new Error(errorMessage));
190
- if (this._throwErrors) {
191
- throw new Error(errorMessage);
192
- }
193
- }
194
- const options = {
195
- application: this._applicationId,
196
- environment: this._environment,
197
- horizonUrls: this._uris,
198
- cache: this._caching
199
- };
200
- if (this._publicApiKey && this._publicApiKey.length > 0) {
201
- await OpenFeature.setProviderAndWait(new HyphenProvider(this._publicApiKey, options));
202
- } else {
203
- this.emit("error", new Error("Public API key is not set. You must set it before using the client or have the HYPHEN_PUBLIC_API_KEY environment variable set."));
204
- if (this._throwErrors) {
205
- throw new Error("Public API key is not set");
206
- }
207
- }
208
- this._client = OpenFeature.getClient(this._context);
224
+ setApiKey(apiKey) {
225
+ if (apiKey?.startsWith("public_")) {
226
+ throw new Error('API key cannot start with "public_"');
209
227
  }
210
- return this._client;
211
- }
212
- /**
213
- * This is the main function to get a feature flag value. It will check the type of the default value and call the
214
- * appropriate function. It will also set the context if it is not set.
215
- * @param {string} key - The key of the feature flag
216
- * @param {T} defaultValue - The default value to return if the feature flag is not set or does not evaluate.
217
- * @param {ToggleRequestOptions} options - The options to use for the request. This can be used to override the context.
218
- * @returns {Promise<T>}
219
- */
220
- async get(key, defaultValue, options) {
221
- switch (typeof defaultValue) {
222
- case "boolean": {
223
- return this.getBoolean(key, defaultValue, options);
224
- }
225
- case "string": {
226
- return this.getString(key, defaultValue, options);
227
- }
228
- case "number": {
229
- return this.getNumber(key, defaultValue, options);
230
- }
231
- default: {
232
- return this.getObject(key, defaultValue, options);
233
- }
228
+ if (apiKey) {
229
+ this._apiKey = apiKey;
234
230
  }
235
231
  }
236
232
  /**
237
- * Get a boolean value from the feature flag. This will check the type of the default value and call the
238
- * appropriate function. It will also set the context if it is not set.
239
- * @param {string} key - The key of the feature flag
240
- * @param {boolean} defaultValue - The default value to return if the feature flag is not set or does not evaluate.
241
- * @param {ToggleRequestOptions} options - The options to use for the request. This can be used to override the context.
242
- * @returns {Promise<boolean>} - The value of the feature flag
233
+ * Get the URI for a specific organization and code. This is used internally to construct the URI for the link service.
234
+ * @param {string} organizationId The ID of the organization.
235
+ * @param {string} code The code to include in the URI.
236
+ * @returns {string} The constructed URI.
243
237
  */
244
- async getBoolean(key, defaultValue, options) {
245
- try {
246
- const data = {
247
- key,
248
- defaultValue,
249
- options
250
- };
251
- await this.hook("beforeGetBoolean", data);
252
- const client = await this.getClient();
253
- const result = await client.getBooleanValue(data.key, data.defaultValue, data.options?.context);
254
- const resultData = {
255
- key,
256
- defaultValue,
257
- options,
258
- result
259
- };
260
- await this.hook("afterGetBoolean", resultData);
261
- return resultData.result;
262
- } catch (error) {
263
- this.emit("error", error);
264
- if (this._throwErrors) {
265
- throw error;
266
- }
238
+ getUri(organizationId, prefix1, prefix2, prefix3) {
239
+ if (!organizationId) {
240
+ throw new Error("Organization ID is required to get the URI.");
267
241
  }
268
- return defaultValue;
242
+ let url = this._uris[0].replace("{organizationId}", organizationId);
243
+ if (prefix1) {
244
+ url = url.endsWith("/") ? `${url}${prefix1}/` : `${url}/${prefix1}`;
245
+ }
246
+ if (prefix2) {
247
+ url = url.endsWith("/") ? `${url}${prefix2}/` : `${url}/${prefix2}`;
248
+ }
249
+ if (prefix3) {
250
+ url = url.endsWith("/") ? `${url}${prefix3}/` : `${url}/${prefix3}`;
251
+ }
252
+ if (url.endsWith("/")) {
253
+ url = url.slice(0, -1);
254
+ }
255
+ return url;
269
256
  }
270
257
  /**
271
- * Get a string value from the feature flag.
272
- * @param {string} key - The key of the feature flag
273
- * @param {string} defaultValue - The default value to return if the feature flag is not set or does not evaluate.
274
- * @param {ToggleRequestOptions} options - The options to use for the request. This can be used to override the context.
275
- * @returns {Promise<string>} - The value of the feature flag
258
+ * Create a short code for a long URL.
259
+ * @param {string} longUrl The long URL to shorten.
260
+ * @param {string} domain The domain to use for the short code.
261
+ * @param {CreateShortCodeOptions} options Optional parameters for creating the short code.
262
+ * @returns {Promise<CreateShortCodeResponse>} A promise that resolves to the created short code details.
276
263
  */
277
- async getString(key, defaultValue, options) {
278
- try {
279
- const data = {
280
- key,
281
- defaultValue,
282
- options
283
- };
284
- await this.hook("beforeGetString", data);
285
- const client = await this.getClient();
286
- const result = await client.getStringValue(data.key, data.defaultValue, data.options?.context);
287
- const resultData = {
288
- key,
289
- defaultValue,
290
- options,
291
- result
292
- };
293
- await this.hook("afterGetString", resultData);
294
- return resultData.result;
295
- } catch (error) {
296
- this.emit("error", error);
297
- if (this._throwErrors) {
298
- throw error;
299
- }
264
+ async createShortCode(longUrl, domain, options) {
265
+ if (!this._organizationId) {
266
+ throw new Error("Organization ID is required to create a short code.");
300
267
  }
301
- return defaultValue;
302
- }
303
- async getNumber(key, defaultValue, options) {
304
- try {
305
- const data = {
306
- key,
307
- defaultValue,
308
- options
309
- };
310
- await this.hook("beforeGetNumber", data);
311
- const client = await this.getClient();
312
- const result = await client.getNumberValue(data.key, data.defaultValue, data.options?.context);
313
- const resultData = {
314
- key,
315
- defaultValue,
316
- options,
317
- result
318
- };
319
- await this.hook("afterGetNumber", resultData);
320
- return resultData.result;
321
- } catch (error) {
322
- this.emit("error", error);
323
- if (this._throwErrors) {
324
- throw error;
325
- }
268
+ const url = this.getUri(this._organizationId);
269
+ const body = {
270
+ long_url: longUrl,
271
+ domain,
272
+ code: options?.code,
273
+ title: options?.title,
274
+ tags: options?.tags
275
+ };
276
+ const headers = this.createHeaders(this._apiKey);
277
+ const response = await this.post(url, body, {
278
+ headers
279
+ });
280
+ if (response.status === 201) {
281
+ return response.data;
326
282
  }
327
- return defaultValue;
283
+ throw new Error(`Failed to create short code: ${response.statusText}`);
328
284
  }
329
285
  /**
330
- * Get an object value from the feature flag. This will check the type of the default value and call the
331
- * appropriate function. It will also set the context if it is not set.
332
- * @param {string} key - The key of the feature flag
333
- * @param {T} defaultValue - The default value to return if the feature flag is not set or does not evaluate.
334
- * @param {ToggleRequestOptions} options - The options to use for the request. This can be used to override the context.
335
- * @returns {Promise<T>} - The value of the feature flag
286
+ * Get a short code by its code.
287
+ * @param {string} code The short code to retrieve. Example: 'code_686bed403c3991bd676bba4d'
288
+ * @returns {Promise<GetShortCodeResponse>} A promise that resolves to the short code details.
336
289
  */
337
- async getObject(key, defaultValue, options) {
338
- try {
339
- const data = {
340
- key,
341
- defaultValue,
342
- options
343
- };
344
- await this.hook("beforeGetObject", data);
345
- const client = await this.getClient();
346
- const result = await client.getObjectValue(key, defaultValue, data.options?.context);
347
- const resultData = {
348
- key,
349
- defaultValue,
350
- options,
351
- result
352
- };
353
- await this.hook("afterGetObject", resultData);
354
- return resultData.result;
355
- } catch (error) {
356
- this.emit("error", error);
357
- if (this._throwErrors) {
358
- throw error;
359
- }
290
+ async getShortCode(code) {
291
+ if (!this._organizationId) {
292
+ throw new Error("Organization ID is required to get a short code.");
360
293
  }
361
- return defaultValue;
362
- }
363
- };
364
-
365
- // src/env.ts
366
- import process2 from "process";
367
- import fs from "fs";
368
- import path from "path";
369
- import { config } from "dotenv";
370
- function loadEnv(options) {
371
- const local = options?.local ?? true;
372
- const currentWorkingDirectory = options?.path ?? process2.cwd();
373
- const envPath = path.resolve(currentWorkingDirectory, ".env");
374
- if (fs.existsSync(envPath)) {
375
- config({
376
- path: envPath
294
+ const url = this.getUri(this._organizationId, code);
295
+ const headers = this.createHeaders(this._apiKey);
296
+ const response = await this.get(url, {
297
+ headers
377
298
  });
378
- }
379
- if (local) {
380
- const localEnvPath = path.resolve(currentWorkingDirectory, ".env.local");
381
- if (fs.existsSync(localEnvPath)) {
382
- config({
383
- path: localEnvPath,
384
- override: true
385
- });
299
+ if (response.status === 200) {
300
+ return response.data;
386
301
  }
302
+ throw new Error(`Failed to get short code: ${response.statusText}`);
387
303
  }
388
- const environment = options?.environment ?? process2.env.NODE_ENV;
389
- if (environment) {
390
- const envSpecificPath = path.resolve(currentWorkingDirectory, `.env.${environment}`);
391
- if (fs.existsSync(envSpecificPath)) {
392
- config({
393
- path: envSpecificPath,
394
- override: true
395
- });
304
+ /**
305
+ * Get all short codes for the organization.
306
+ * @param {string} titleSearch Optional search term to filter short codes by title.
307
+ * @param {string[]} tags Optional tags to filter short codes.
308
+ * @param {number} pageNumber The page number to retrieve. Default is 1.
309
+ * @param {number} pageSize The number of short codes per page. Default is 100.
310
+ * @returns {Promise<GetShortCodesResponse>} A promise that resolves to the list of short codes.
311
+ */
312
+ async getShortCodes(titleSearch, tags, pageNumber = 1, pageSize = 100) {
313
+ if (!this._organizationId) {
314
+ throw new Error("Organization ID is required to get short codes.");
396
315
  }
397
- if (local) {
398
- const envLocalPath = path.resolve(currentWorkingDirectory, `.env.${environment}.local`);
399
- if (fs.existsSync(envLocalPath)) {
400
- config({
401
- path: envLocalPath,
402
- override: true
403
- });
404
- }
316
+ const url = this.getUri(this._organizationId);
317
+ const headers = this.createHeaders(this._apiKey);
318
+ const parameters = {};
319
+ if (titleSearch) {
320
+ parameters.title = titleSearch;
405
321
  }
406
- }
407
- }
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;
322
+ if (tags && tags.length > 0) {
323
+ parameters.tags = tags.join(",");
437
324
  }
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);
325
+ parameters.pageNum = pageNumber.toString();
326
+ parameters.pageSize = pageSize.toString();
327
+ const response = await this.get(url, {
328
+ headers,
329
+ params: parameters
330
+ });
331
+ if (response.status === 200) {
332
+ return response.data;
462
333
  }
334
+ throw new Error(`Failed to get short codes: ${response.statusText}`);
463
335
  }
464
- warn(message, ...args) {
465
- this._log.warn(message, ...args);
466
- this.emit("warn", message, ...args);
336
+ /**
337
+ * Get all tags associated with the organization's short codes.
338
+ * @returns {Promise<string[]>} A promise that resolves to an array of tags.
339
+ */
340
+ async getTags() {
341
+ if (!this._organizationId) {
342
+ throw new Error("Organization ID is required to get tags.");
343
+ }
344
+ const url = this.getUri(this._organizationId, "tags");
345
+ const headers = this.createHeaders(this._apiKey);
346
+ const response = await this.get(url, {
347
+ headers
348
+ });
349
+ if (response.status === 200) {
350
+ return response.data;
351
+ }
352
+ throw new Error(`Failed to get tags: ${response.statusText}`);
467
353
  }
468
- info(message, ...args) {
469
- this._log.info(message, ...args);
470
- this.emit("info", message, ...args);
354
+ /**
355
+ * Get statistics for a specific short code.
356
+ * @param code The short code to retrieve statistics for.
357
+ * @returns {Promise<GetCodeStatsResponse>} A promise that resolves to the code statistics.
358
+ */
359
+ async getCodeStats(code, startDate, endDate) {
360
+ if (!this._organizationId) {
361
+ throw new Error("Organization ID is required to get code stats.");
362
+ }
363
+ const url = this.getUri(this._organizationId, code, "stats");
364
+ const headers = this.createHeaders(this._apiKey);
365
+ const parameters = {
366
+ startDate: startDate.toISOString(),
367
+ endDate: endDate.toISOString()
368
+ };
369
+ const response = await this.get(url, {
370
+ headers,
371
+ params: parameters
372
+ });
373
+ if (response.status === 200) {
374
+ return response.data;
375
+ }
376
+ throw new Error(`Failed to get code stats: ${response.statusText}`);
471
377
  }
472
- async get(url, config2) {
473
- return axios.get(url, config2);
378
+ /**
379
+ * Update a short code.
380
+ * @param {string} code The short code to update. Example: 'code_686bed403c3991bd676bba4d'
381
+ * @param {UpdateShortCodeOptions} options The options to update the short code with.
382
+ * @returns {Promise<UpdateShortCodeResponse>} A promise that resolves to the updated short code details.
383
+ */
384
+ async updateShortCode(code, options) {
385
+ if (!this._organizationId) {
386
+ throw new Error("Organization ID is required to update a short code.");
387
+ }
388
+ const url = this.getUri(this._organizationId, code);
389
+ const headers = this.createHeaders(this._apiKey);
390
+ const response = await this.patch(url, options, {
391
+ headers
392
+ });
393
+ if (response.status === 200) {
394
+ return response.data;
395
+ }
396
+ throw new Error(`Failed to update short code: ${response.statusText}`);
474
397
  }
475
- async post(url, data, config2) {
476
- return axios.post(url, data, config2);
398
+ /**
399
+ * Delete a short code.
400
+ * @param {string} code The short code to delete. Example: 'code_686bed403c3991bd676bba4d'
401
+ * @returns {Promise<boolean>} A promise that resolves to true if the short code was deleted successfully, or false if it was not.
402
+ */
403
+ async deleteShortCode(code) {
404
+ if (!this._organizationId) {
405
+ throw new Error("Organization ID is required to delete a short code.");
406
+ }
407
+ const url = this.getUri(this._organizationId, code);
408
+ const headers = this.createHeaders(this._apiKey);
409
+ const response = await this.delete(url, {
410
+ headers
411
+ });
412
+ if (response.status === 204) {
413
+ return true;
414
+ }
415
+ throw new Error(`Failed to delete short code: ${response.statusText}`);
477
416
  }
478
- async put(url, data, config2) {
479
- return axios.put(url, data, config2);
417
+ /**
418
+ * Create a QR code for a specific short code.
419
+ * @param {string} code The short code to create a QR code for.
420
+ * @param {CreateQrCodeOptions} options The options for creating the QR code.
421
+ * @returns {Promise<CreateQrCodeResponse>} A promise that resolves to the created QR code details.
422
+ */
423
+ async createQrCode(code, options) {
424
+ if (!this._organizationId) {
425
+ throw new Error("Organization ID is required to create a QR code.");
426
+ }
427
+ const url = this.getUri(this._organizationId, code, "qrs");
428
+ const headers = this.createHeaders(this._apiKey);
429
+ const body = {
430
+ title: options?.title,
431
+ backgroundColor: options?.backgroundColor,
432
+ color: options?.color,
433
+ size: options?.size,
434
+ logo: options?.logo
435
+ };
436
+ const response = await this.post(url, body, {
437
+ headers
438
+ });
439
+ if (response.status === 201) {
440
+ const result = response.data;
441
+ if (result.qrCode) {
442
+ const buffer = Buffer2.from(result.qrCode, "base64");
443
+ result.qrCodeBytes = new Uint16Array(buffer);
444
+ }
445
+ return result;
446
+ }
447
+ throw new Error(`Failed to create QR code: ${response.statusText}`);
480
448
  }
481
- async delete(url, config2) {
482
- return axios.delete(url, config2);
449
+ /**
450
+ * Get a QR code by its ID.
451
+ * @param code The short code associated with the QR code.
452
+ * @param qr The ID of the QR code to retrieve.
453
+ * @returns The details of the requested QR code.
454
+ */
455
+ async getQrCode(code, qr) {
456
+ if (!this._organizationId) {
457
+ throw new Error("Organization ID is required to get a QR code.");
458
+ }
459
+ const url = this.getUri(this._organizationId, code, "qrs", qr);
460
+ const headers = this.createHeaders(this._apiKey);
461
+ const response = await this.get(url, {
462
+ headers
463
+ });
464
+ if (response.status === 200) {
465
+ const result = response.data;
466
+ if (result.qrCode) {
467
+ const buffer = Buffer2.from(result.qrCode, "base64");
468
+ result.qrCodeBytes = new Uint16Array(buffer);
469
+ }
470
+ return result;
471
+ }
472
+ throw new Error(`Failed to get QR code: ${response.statusText}`);
483
473
  }
484
- async patch(url, data, config2) {
485
- return axios.patch(url, data, config2);
474
+ async getQrCodes(code, pageNumber, pageSize) {
475
+ if (!this._organizationId) {
476
+ throw new Error("Organization ID is required to get QR codes.");
477
+ }
478
+ const url = this.getUri(this._organizationId, code, "qrs");
479
+ const headers = this.createHeaders(this._apiKey);
480
+ const parameters = {};
481
+ if (pageNumber) {
482
+ parameters.pageNum = pageNumber.toString();
483
+ }
484
+ if (pageSize) {
485
+ parameters.pageSize = pageSize.toString();
486
+ }
487
+ const response = await this.get(url, {
488
+ headers,
489
+ params: parameters
490
+ });
491
+ if (response.status === 200) {
492
+ const result = response.data;
493
+ for (const qrCode of result.data) {
494
+ if (qrCode.qrCode) {
495
+ const buffer = Buffer2.from(qrCode.qrCode, "base64");
496
+ qrCode.qrCodeBytes = new Uint16Array(buffer);
497
+ }
498
+ }
499
+ return result;
500
+ }
501
+ throw new Error(`Failed to get QR codes: ${response.statusText}`);
486
502
  }
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;
503
+ /**
504
+ * Delete a QR code by its ID.
505
+ * @param {string} code The short code associated with the QR code.
506
+ * @param {string} qr The ID of the QR code to delete.
507
+ * @returns {Promise<boolean>} A promise that resolves to true if the QR code was deleted successfully, or false if it was not.
508
+ */
509
+ async deleteQrCode(code, qr) {
510
+ if (!this._organizationId) {
511
+ throw new Error("Organization ID is required to delete a QR code.");
494
512
  }
495
- return headers;
513
+ const url = this.getUri(this._organizationId, code, "qrs", qr);
514
+ const headers = this.createHeaders(this._apiKey);
515
+ const response = await this.delete(url, {
516
+ headers
517
+ });
518
+ if (response.status === 204) {
519
+ return true;
520
+ }
521
+ throw new Error(`Failed to delete QR code: ${response.statusText}`);
496
522
  }
497
523
  };
498
524
 
499
525
  // src/net-info.ts
500
- loadEnv();
526
+ import process3 from "process";
527
+ env();
501
528
  var NetInfo = class extends BaseService {
502
529
  static {
503
530
  __name(this, "NetInfo");
@@ -518,31 +545,31 @@ var NetInfo = class extends BaseService {
518
545
  }
519
546
  }
520
547
  /**
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
- */
548
+ * Gets or sets the API key for authentication.
549
+ * If not set, it will try to use the `HYPHEN_API_KEY` environment variable.
550
+ * @type {string | undefined}
551
+ */
525
552
  get apiKey() {
526
553
  return this._apiKey;
527
554
  }
528
555
  /**
529
- * Sets the API key for authentication.
530
- * @param {string | undefined} value - The API key to set.
531
- */
556
+ * Sets the API key for authentication.
557
+ * @param {string | undefined} value - The API key to set.
558
+ */
532
559
  set apiKey(value) {
533
560
  this.setApiKey(value);
534
561
  }
535
562
  /**
536
- * Gets or sets the base URI for the API.
537
- * @type {string}
538
- */
563
+ * Gets or sets the base URI for the API.
564
+ * @type {string}
565
+ */
539
566
  get baseUri() {
540
567
  return this._baseUri;
541
568
  }
542
569
  /**
543
- * Sets the base URI for the API.
544
- * @param {string} value - The base URI to set.
545
- */
570
+ * Sets the base URI for the API.
571
+ * @param {string} value - The base URI to set.
572
+ */
546
573
  set baseUri(value) {
547
574
  this._baseUri = value;
548
575
  }
@@ -554,10 +581,10 @@ var NetInfo = class extends BaseService {
554
581
  this._apiKey = value;
555
582
  }
556
583
  /**
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
- */
584
+ * Fetches GeoIP information for a given IP address.
585
+ * @param {string} ip - The IP address to fetch GeoIP information for.
586
+ * @returns {Promise<ipInfo | ipInfoError>} - A promise that resolves to the ip information or an error.
587
+ */
561
588
  async getIpInfo(ip) {
562
589
  try {
563
590
  if (!this._apiKey) {
@@ -624,188 +651,364 @@ var NetInfo = class extends BaseService {
624
651
  }
625
652
  };
626
653
 
627
- // src/link.ts
654
+ // src/toggle.ts
628
655
  import process4 from "process";
629
- loadEnv();
630
- var defaultLinkUris = [
631
- "https://api.hyphen.ai/api/organizations/{organizationId}/link/codes/"
632
- ];
633
- var Link = class extends BaseService {
656
+ import { HyphenProvider } from "@hyphen/openfeature-server-provider";
657
+ import { OpenFeature } from "@openfeature/server-sdk";
658
+ import dotenv from "dotenv";
659
+ import { Hookified as Hookified2 } from "hookified";
660
+ dotenv.config();
661
+ var ToggleHooks = /* @__PURE__ */ function(ToggleHooks2) {
662
+ ToggleHooks2["beforeGetBoolean"] = "beforeGetBoolean";
663
+ ToggleHooks2["afterGetBoolean"] = "afterGetBoolean";
664
+ ToggleHooks2["beforeGetString"] = "beforeGetString";
665
+ ToggleHooks2["afterGetString"] = "afterGetString";
666
+ ToggleHooks2["beforeGetNumber"] = "beforeGetNumber";
667
+ ToggleHooks2["afterGetNumber"] = "afterGetNumber";
668
+ ToggleHooks2["beforeGetObject"] = "beforeGetObject";
669
+ ToggleHooks2["afterGetObject"] = "afterGetObject";
670
+ return ToggleHooks2;
671
+ }({});
672
+ var Toggle = class extends Hookified2 {
634
673
  static {
635
- __name(this, "Link");
674
+ __name(this, "Toggle");
636
675
  }
637
- _uris = defaultLinkUris;
638
- _organizationId;
639
- _apiKey;
676
+ _applicationId = process4.env.HYPHEN_APPLICATION_ID;
677
+ _publicApiKey = process4.env.HYPHEN_PUBLIC_API_KEY;
678
+ _environment;
679
+ _client;
680
+ _context;
681
+ _throwErrors = false;
682
+ _uris;
683
+ _caching;
684
+ /*
685
+ * Create a new Toggle instance. This will create a new client and set the options.
686
+ * @param {ToggleOptions}
687
+ */
640
688
  constructor(options) {
641
- super(options);
642
- this._uris = options?.uris ?? defaultLinkUris;
643
- this._organizationId = options?.organizationId;
644
- if (options?.apiKey) {
645
- this.setApiKey(options.apiKey);
646
- }
647
- if (!this._apiKey && process4.env.HYPHEN_API_KEY) {
648
- this.setApiKey(process4.env.HYPHEN_API_KEY);
689
+ super();
690
+ this._throwErrors = options?.throwErrors ?? false;
691
+ this._applicationId = options?.applicationId;
692
+ if (options?.publicApiKey) {
693
+ this.setPublicApiKey(options.publicApiKey);
649
694
  }
650
- if (!this._organizationId && process4.env.HYPHEN_ORGANIZATION_ID) {
651
- this._organizationId = process4.env.HYPHEN_ORGANIZATION_ID;
695
+ this._environment = options?.environment ?? process4.env.NODE_ENV ?? "development";
696
+ this._context = options?.context;
697
+ this._uris = options?.uris;
698
+ this._caching = options?.caching;
699
+ }
700
+ /**
701
+ * Get the application ID
702
+ * @returns {string | undefined}
703
+ */
704
+ get applicationId() {
705
+ return this._applicationId;
706
+ }
707
+ /**
708
+ * Set the application ID
709
+ * @param {string | undefined} value
710
+ */
711
+ set applicationId(value) {
712
+ this._applicationId = value;
713
+ }
714
+ /**
715
+ * Get the public API key
716
+ * @returns {string}
717
+ */
718
+ get publicApiKey() {
719
+ return this._publicApiKey;
720
+ }
721
+ /**
722
+ * Set the public API key
723
+ * @param {string} value
724
+ */
725
+ set publicApiKey(value) {
726
+ if (!value) {
727
+ this._publicApiKey = void 0;
728
+ this._client = void 0;
729
+ return;
652
730
  }
731
+ this.setPublicApiKey(value);
653
732
  }
654
733
  /**
655
- * Get the URIs for the link service. The default is `["https://api.hyphen.ai/api/organizations/{organizationId}/link/codes/"]`.
656
- * @returns {string[]} The URIs for the link service.
734
+ * Get the environment
735
+ * @returns {string}
736
+ */
737
+ get environment() {
738
+ return this._environment;
739
+ }
740
+ /**
741
+ * Set the environment
742
+ * @param {string} value
743
+ */
744
+ set environment(value) {
745
+ this._environment = value;
746
+ }
747
+ /**
748
+ * Get the throwErrors. If true, errors will be thrown in addition to being emitted.
749
+ * @returns {boolean}
750
+ */
751
+ get throwErrors() {
752
+ return this._throwErrors;
753
+ }
754
+ /**
755
+ * Set the throwErrors. If true, errors will be thrown in addition to being emitted.
756
+ * @param {boolean} value
757
+ */
758
+ set throwErrors(value) {
759
+ this._throwErrors = value;
760
+ }
761
+ /**
762
+ * Get the current context. This is the default context used. You can override this at the get function level.
763
+ * @returns {ToggleContext}
764
+ */
765
+ get context() {
766
+ return this._context;
767
+ }
768
+ /**
769
+ * Set the context. This is the default context used. You can override this at the get function level.
770
+ * @param {ToggleContext} value
771
+ */
772
+ set context(value) {
773
+ this._context = value;
774
+ }
775
+ /**
776
+ * Get the URIs. This is used to override the default URIs for testing or if you are using a self-hosted version.
777
+ * @returns {Array<string>}
657
778
  */
658
779
  get uris() {
659
780
  return this._uris;
660
781
  }
661
782
  /**
662
- * Set the URIs for the link service. The default is `["https://api.hyphen.ai/api/organizations/{organizationId}/link/codes/"]`.
663
- * @param {string[]} uris - The URIs to set.
783
+ * Set the URIs. This is used to override the default URIs for testing or if you are using a self-hosted version.
784
+ * @param {Array<string>} value
664
785
  */
665
- set uris(uris) {
666
- this._uris = uris;
786
+ set uris(value) {
787
+ this._uris = value;
667
788
  }
668
789
  /**
669
- * Get the organization ID for the link service. This is required to access the link service.
670
- * @returns {string | undefined} The organization ID.
790
+ * Get the caching options.
791
+ * @returns {ToggleCachingOptions | undefined}
671
792
  */
672
- get organizationId() {
673
- return this._organizationId;
793
+ get caching() {
794
+ return this._caching;
674
795
  }
675
796
  /**
676
- * Set the organization ID for the link service. This is required to access the link service.
677
- * @param {string | undefined} organizationId - The organization ID to set.
797
+ * Set the caching options.
798
+ * @param {ToggleCachingOptions | undefined} value
678
799
  */
679
- set organizationId(organizationId) {
680
- this._organizationId = organizationId;
800
+ set caching(value) {
801
+ this._caching = value;
681
802
  }
682
803
  /**
683
- * Get the API key for the link service. This is required to access the link service.
684
- * @returns {string | undefined} The API key.
804
+ * This is a helper function to set the public API key. It will check if the key starts with public_ and set it. If it
805
+ * does set it will also set the client to undefined to force a new one to be created. If it does not,
806
+ * it will emit an error and console warning and not set the key. Used by the constructor and publicApiKey setter.
807
+ * @param key
808
+ * @returns
685
809
  */
686
- get apiKey() {
687
- return this._apiKey;
810
+ setPublicApiKey(key) {
811
+ if (!key.startsWith("public_")) {
812
+ this.emit("error", new Error("Public API key should start with public_"));
813
+ if (process4.env.NODE_ENV !== "production") {
814
+ console.error("Public API key should start with public_");
815
+ }
816
+ return;
817
+ }
818
+ this._publicApiKey = key;
819
+ this._client = void 0;
688
820
  }
689
821
  /**
690
- * Set the API key for the link service. This is required to access the link service.
691
- * @param {string | undefined} apiKey - The API key to set.
822
+ * Set the context. This is the default context used. You can override this at the get function level.
823
+ * @param {ToggleContext} context
692
824
  */
693
- set apiKey(apiKey) {
694
- this.setApiKey(apiKey);
825
+ setContext(context) {
826
+ this._context = context;
827
+ this._client = void 0;
695
828
  }
696
829
  /**
697
- * Set the API key for the link service. If the API key starts with 'public_', an error is thrown.
698
- * This is to ensure that the API key is not a public key, which should not be used for authenticated requests.
699
- * @param {string} apiKey
830
+ * Helper function to get the client. This will create a new client if one does not exist. It will also set the
831
+ * application ID, environment, and URIs if they are not set. This is used by the get function to get the client.
832
+ * This is normally only used internally.
833
+ * @returns {Promise<Client>}
700
834
  */
701
- setApiKey(apiKey) {
702
- if (apiKey?.startsWith("public_")) {
703
- throw new Error('API key cannot start with "public_"');
704
- }
705
- if (apiKey) {
706
- this._apiKey = apiKey;
835
+ async getClient() {
836
+ if (!this._client) {
837
+ if (this._applicationId === void 0 || this._applicationId.length === 0) {
838
+ const errorMessage = "Application ID is not set. You must set it before using the client or have the HYPHEN_APPLICATION_ID environment variable set.";
839
+ this.emit("error", new Error(errorMessage));
840
+ if (this._throwErrors) {
841
+ throw new Error(errorMessage);
842
+ }
843
+ }
844
+ const options = {
845
+ application: this._applicationId,
846
+ environment: this._environment,
847
+ horizonUrls: this._uris,
848
+ cache: this._caching
849
+ };
850
+ if (this._publicApiKey && this._publicApiKey.length > 0) {
851
+ await OpenFeature.setProviderAndWait(new HyphenProvider(this._publicApiKey, options));
852
+ } else {
853
+ this.emit("error", new Error("Public API key is not set. You must set it before using the client or have the HYPHEN_PUBLIC_API_KEY environment variable set."));
854
+ if (this._throwErrors) {
855
+ throw new Error("Public API key is not set");
856
+ }
857
+ }
858
+ this._client = OpenFeature.getClient(this._context);
707
859
  }
860
+ return this._client;
708
861
  }
709
862
  /**
710
- * Get the URI for a specific organization and code. This is used internally to construct the URI for the link service.
711
- * @param {string} organizationId The ID of the organization.
712
- * @param {string} code The code to include in the URI.
713
- * @returns {string} The constructed URI.
863
+ * This is the main function to get a feature flag value. It will check the type of the default value and call the
864
+ * appropriate function. It will also set the context if it is not set.
865
+ * @param {string} key - The key of the feature flag
866
+ * @param {T} defaultValue - The default value to return if the feature flag is not set or does not evaluate.
867
+ * @param {ToggleRequestOptions} options - The options to use for the request. This can be used to override the context.
868
+ * @returns {Promise<T>}
714
869
  */
715
- getUri(organizationId, code) {
716
- if (!organizationId) {
717
- throw new Error("Organization ID is required to get the URI.");
718
- }
719
- let url = this._uris[0].replace("{organizationId}", organizationId);
720
- if (code) {
721
- url = url.endsWith("/") ? `${url}${code}/` : `${url}/${code}/`;
870
+ async get(key, defaultValue, options) {
871
+ switch (typeof defaultValue) {
872
+ case "boolean": {
873
+ return this.getBoolean(key, defaultValue, options);
874
+ }
875
+ case "string": {
876
+ return this.getString(key, defaultValue, options);
877
+ }
878
+ case "number": {
879
+ return this.getNumber(key, defaultValue, options);
880
+ }
881
+ default: {
882
+ return this.getObject(key, defaultValue, options);
883
+ }
722
884
  }
723
- return url;
724
885
  }
725
- async createShortCode(longUrl, domain, options) {
726
- if (!this._organizationId) {
727
- throw new Error("Organization ID is required to create a short code.");
728
- }
729
- const url = this.getUri(this._organizationId);
730
- const body = {
731
- // eslint-disable-next-line @typescript-eslint/naming-convention
732
- long_url: longUrl,
733
- domain,
734
- code: options?.code,
735
- title: options?.title,
736
- tags: options?.tags
737
- };
738
- const headers = this.createHeaders(this._apiKey);
739
- const response = await this.post(url, body, {
740
- headers
741
- });
742
- if (response.status === 201) {
743
- return response.data;
886
+ /**
887
+ * Get a boolean value from the feature flag. This will check the type of the default value and call the
888
+ * appropriate function. It will also set the context if it is not set.
889
+ * @param {string} key - The key of the feature flag
890
+ * @param {boolean} defaultValue - The default value to return if the feature flag is not set or does not evaluate.
891
+ * @param {ToggleRequestOptions} options - The options to use for the request. This can be used to override the context.
892
+ * @returns {Promise<boolean>} - The value of the feature flag
893
+ */
894
+ async getBoolean(key, defaultValue, options) {
895
+ try {
896
+ const data = {
897
+ key,
898
+ defaultValue,
899
+ options
900
+ };
901
+ await this.hook("beforeGetBoolean", data);
902
+ const client = await this.getClient();
903
+ const result = await client.getBooleanValue(data.key, data.defaultValue, data.options?.context);
904
+ const resultData = {
905
+ key,
906
+ defaultValue,
907
+ options,
908
+ result
909
+ };
910
+ await this.hook("afterGetBoolean", resultData);
911
+ return resultData.result;
912
+ } catch (error) {
913
+ this.emit("error", error);
914
+ if (this._throwErrors) {
915
+ throw error;
916
+ }
744
917
  }
745
- throw new Error(`Failed to create short code: ${response.statusText}`);
918
+ return defaultValue;
746
919
  }
747
920
  /**
748
- * Get a short code by its code.
749
- * @param {string} code The short code to retrieve. Example: 'code_686bed403c3991bd676bba4d'
750
- * @returns {Promise<GetShortCodeResponse>} A promise that resolves to the short code details.
921
+ * Get a string value from the feature flag.
922
+ * @param {string} key - The key of the feature flag
923
+ * @param {string} defaultValue - The default value to return if the feature flag is not set or does not evaluate.
924
+ * @param {ToggleRequestOptions} options - The options to use for the request. This can be used to override the context.
925
+ * @returns {Promise<string>} - The value of the feature flag
751
926
  */
752
- async getShortCode(code) {
753
- if (!this._organizationId) {
754
- throw new Error("Organization ID is required to get a short code.");
755
- }
756
- const url = this.getUri(this._organizationId, code);
757
- const headers = this.createHeaders(this._apiKey);
758
- const response = await this.get(url, {
759
- headers
760
- });
761
- if (response.status === 200) {
762
- return response.data;
927
+ async getString(key, defaultValue, options) {
928
+ try {
929
+ const data = {
930
+ key,
931
+ defaultValue,
932
+ options
933
+ };
934
+ await this.hook("beforeGetString", data);
935
+ const client = await this.getClient();
936
+ const result = await client.getStringValue(data.key, data.defaultValue, data.options?.context);
937
+ const resultData = {
938
+ key,
939
+ defaultValue,
940
+ options,
941
+ result
942
+ };
943
+ await this.hook("afterGetString", resultData);
944
+ return resultData.result;
945
+ } catch (error) {
946
+ this.emit("error", error);
947
+ if (this._throwErrors) {
948
+ throw error;
949
+ }
763
950
  }
764
- throw new Error(`Failed to get short code: ${response.statusText}`);
951
+ return defaultValue;
765
952
  }
766
- async getShortCodes(titleSearch, tags, pageNumber = 1, pageSize = 100) {
767
- if (!this._organizationId) {
768
- throw new Error("Organization ID is required to get short codes.");
769
- }
770
- const url = this.getUri(this._organizationId);
771
- const headers = this.createHeaders(this._apiKey);
772
- const parameters = {};
773
- if (titleSearch) {
774
- parameters.title = titleSearch;
775
- }
776
- if (tags && tags.length > 0) {
777
- parameters.tags = tags.join(",");
778
- }
779
- parameters.pageNum = pageNumber.toString();
780
- parameters.pageSize = pageSize.toString();
781
- const response = await this.get(url, {
782
- headers,
783
- params: parameters
784
- });
785
- if (response.status === 200) {
786
- return response.data;
953
+ async getNumber(key, defaultValue, options) {
954
+ try {
955
+ const data = {
956
+ key,
957
+ defaultValue,
958
+ options
959
+ };
960
+ await this.hook("beforeGetNumber", data);
961
+ const client = await this.getClient();
962
+ const result = await client.getNumberValue(data.key, data.defaultValue, data.options?.context);
963
+ const resultData = {
964
+ key,
965
+ defaultValue,
966
+ options,
967
+ result
968
+ };
969
+ await this.hook("afterGetNumber", resultData);
970
+ return resultData.result;
971
+ } catch (error) {
972
+ this.emit("error", error);
973
+ if (this._throwErrors) {
974
+ throw error;
975
+ }
787
976
  }
788
- throw new Error(`Failed to get short codes: ${response.statusText}`);
977
+ return defaultValue;
789
978
  }
790
979
  /**
791
- * Delete a short code.
792
- * @param {string} code The short code to delete. Example: 'code_686bed403c3991bd676bba4d'
793
- * @returns {Promise<boolean>} A promise that resolves to true if the short code was deleted successfully, or false if it was not.
980
+ * Get an object value from the feature flag. This will check the type of the default value and call the
981
+ * appropriate function. It will also set the context if it is not set.
982
+ * @param {string} key - The key of the feature flag
983
+ * @param {T} defaultValue - The default value to return if the feature flag is not set or does not evaluate.
984
+ * @param {ToggleRequestOptions} options - The options to use for the request. This can be used to override the context.
985
+ * @returns {Promise<T>} - The value of the feature flag
794
986
  */
795
- async deleteShortCode(code) {
796
- if (!this._organizationId) {
797
- throw new Error("Organization ID is required to delete a short code.");
798
- }
799
- const url = this.getUri(this._organizationId, code);
800
- const headers = this.createHeaders(this._apiKey);
801
- delete headers["content-type"];
802
- const response = await this.delete(url, {
803
- headers
804
- });
805
- if (response.status === 204) {
806
- return true;
987
+ async getObject(key, defaultValue, options) {
988
+ try {
989
+ const data = {
990
+ key,
991
+ defaultValue,
992
+ options
993
+ };
994
+ await this.hook("beforeGetObject", data);
995
+ const client = await this.getClient();
996
+ const result = await client.getObjectValue(key, defaultValue, data.options?.context);
997
+ const resultData = {
998
+ key,
999
+ defaultValue,
1000
+ options,
1001
+ result
1002
+ };
1003
+ await this.hook("afterGetObject", resultData);
1004
+ return resultData.result;
1005
+ } catch (error) {
1006
+ this.emit("error", error);
1007
+ if (this._throwErrors) {
1008
+ throw error;
1009
+ }
807
1010
  }
808
- throw new Error(`Failed to delete short code: ${response.statusText}`);
1011
+ return defaultValue;
809
1012
  }
810
1013
  };
811
1014
 
@@ -930,5 +1133,6 @@ export {
930
1133
  Hyphen,
931
1134
  Toggle,
932
1135
  ToggleHooks,
1136
+ env,
933
1137
  loadEnv
934
1138
  };