@hyphen/sdk 1.11.0 → 1.12.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 CHANGED
@@ -25,9 +25,15 @@ The Hyphen Node.js SDK is a JavaScript library that allows developers to easily
25
25
  - [Net Info - Geo Information Service](#net-info---geo-information-service)
26
26
  - [Link - Short Code Service](#link---short-code-service)
27
27
  - [Creating a Short Code](#creating-a-short-code)
28
+ - [Updating a Short Code](#updating-a-short-code)
28
29
  - [Getting a Short Code](#getting-a-short-code)
29
30
  - [Getting Short Codes](#getting-short-codes)
31
+ - [Getting all Organization Tags](#getting-all-organization-tags)
32
+ - [Getting Short Code Stats](#getting-short-code-stats)
30
33
  - [Deleting a Short Code](#deleting-a-short-code)
34
+ - [Creating a QR Code from a Short Code](#creating-a-qr-code-from-a-short-code)
35
+ - [Get QR Codes for a Short Code](#get-qr-codes-for-a-short-code)
36
+ - [Deleting a QR Code](#deleting-a-qr-code)
31
37
  - [Contributing](#contributing)
32
38
  - [Testing Your Changes](#testing-your-changes)
33
39
  - [License and Copyright](#license-and-copyright)
@@ -581,44 +587,44 @@ console.log('Boolean toggle value:', result); // true
581
587
  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.
582
588
 
583
589
  ## Loading Environment Variables
584
- To load your environment variables, you can use the `loadEnv` function from the SDK. This function will automatically load your environment variables from the `.env` file and then override them with the environment based environment file if it exists (ex: `.env.development`). This is useful for managing different environments such as development, staging, and production.
590
+ To load your environment variables, you can use the `env()` function from the SDK. This function will automatically load your environment variables from the `.env` file and then override them with the environment based environment file if it exists (ex: `.env.development`). This is useful for managing different environments such as development, staging, and production.
585
591
 
586
592
  The following override path is:
587
593
  ```
588
594
  .env -> .env.local -> .env.<environment> -> .env.<environment>.local
589
595
  ```
590
596
 
591
- Here is an example of how to use the `loadEnv` function:
597
+ Here is an example of how to use the `env()` function:
592
598
 
593
599
  ```javascript
594
- import { loadEnv } from '@hyphen/sdk';
600
+ import { env } from '@hyphen/sdk';
595
601
 
596
602
  //load your default environment variables and envrionment variables
597
- loadEnv();
603
+ env();
598
604
  ```
599
605
 
600
606
  If your environment variables are not stored in the root of your project you can specify the path to your `.env` file:
601
607
 
602
608
  ```javascript
603
- import { loadEnv } from '@hyphen/sdk';
609
+ import { env } from '@hyphen/sdk';
604
610
  //load your default environment variables and envrionment variables
605
- loadEnv({ path: '/path/to/your/env/files/' });
611
+ env({ path: '/path/to/your/env/files/' });
606
612
  ```
607
613
 
608
614
  You can also specify the environment variables to load by passing an array of variable names:
609
615
 
610
616
  ```javascript
611
- import { loadEnv } from '@hyphen/sdk';
617
+ import { env } from '@hyphen/sdk';
612
618
  //load your default environment variables and envrionment variables
613
- loadEnv({ environment: 'development' });
619
+ env({ environment: 'development' });
614
620
  ```
615
621
 
616
622
  if you want to turn off the local environment variables you can do it like this:
617
623
 
618
624
  ```javascript
619
- import { loadEnv } from '@hyphen/sdk';
625
+ import { env } from '@hyphen/sdk';
620
626
  //load your default environment variables and envrionment variables
621
- loadEnv({ local: false });
627
+ env({ local: false });
622
628
  ```
623
629
 
624
630
  # Net Info - Geo Information Service
@@ -681,6 +687,27 @@ const response = await link.createShortCode(longUrl, domain, options);
681
687
  console.log('Short Code Response:', response);
682
688
  ```
683
689
 
690
+ ## Updating a Short Code
691
+ To update a short code, you can use the `updateShortCode` method:
692
+
693
+ ```javascript
694
+ import { Link } from '@hyphen/sdk';
695
+ const link = new Link({
696
+ organizationId: 'your_organization_id',
697
+ apiKey: 'your_api_key',
698
+ });
699
+ const code = 'code_1234567890'; // It is the code identifier for the short code you want to update
700
+ const longUrl = 'https://hyphen.ai/updated';
701
+ const options = {
702
+ title: 'Updated Short Code',
703
+ tags: ['sdk-test', 'unit-test'],
704
+ long_url: longUrl,
705
+ };
706
+
707
+ const updateResponse = await link.updateShortCode(code, options);
708
+ console.log('Update Short Code Response:', updateResponse);
709
+ ```
710
+
684
711
  ## Getting a Short Code
685
712
  To get a short code, you can use the `getShortCode` method:
686
713
 
@@ -710,6 +737,37 @@ const response = await link.getShortCodes(title, tags);
710
737
  console.log('Get Short Codes Response:', response);
711
738
  ```
712
739
 
740
+ ## Getting all Organization Tags
741
+
742
+ To get all tags for your organization, you can use the `getTags` method:
743
+
744
+ ```javascript
745
+ import { Link } from '@hyphen/sdk';
746
+ const link = new Link({
747
+ organizationId: 'your_organization_id',
748
+ apiKey: 'your_api_key',
749
+ });
750
+ const response = await link.getTags();
751
+ console.log('Get Tags Response:', response);
752
+ ```
753
+
754
+ ## Get Short Code Stats
755
+
756
+ To get the stats for a short code, you can use the `getShortCodeStats` method:
757
+
758
+ ```javascript
759
+ import { Link } from '@hyphen/sdk';
760
+ const link = new Link({
761
+ organizationId: 'your_organization_id',
762
+ apiKey: 'your_api_key',
763
+ });
764
+ const code = 'code_1234567890'; // It is the code identifier for the short code
765
+ const startDate = new Date('2023-01-01'); // Optional start date for the stats
766
+ const endDate = new Date('2023-12-31'); // Optional end date for the stats
767
+ const response = await link.getShortCodeStats(code, startDate, endDate);
768
+ console.log('Get Short Code Stats Response:', response);
769
+ ```
770
+
713
771
  ## Deleting a Short Code
714
772
  if you want to delete a short code you can do it like this:
715
773
 
@@ -724,6 +782,100 @@ const response = await link.deleteShortCode(code);
724
782
  console.log('Delete Short Code Response:', response);
725
783
  ```
726
784
 
785
+ ## Creating a QR Code from a Short Code
786
+
787
+ To create a QR code from a short code, you can use the `createQrCode` method:
788
+
789
+ ```javascript
790
+ import { Link } from '@hyphen/sdk';
791
+ const link = new Link({
792
+ organizationId: 'your_organization_id',
793
+ apiKey: 'your_api_key',
794
+ });
795
+ const code = 'code_1234567890'; // It is the code identifier for the short code you want to create a QR code for
796
+ const response = await link.createQrCode(code);
797
+ console.log('Create QR Code Response:', response);
798
+ ```
799
+
800
+ There are options that you can pass in to the `createQrCode` method to customize the QR code:
801
+
802
+ ```typescript
803
+ export type CreateQrCodeOptions = {
804
+ /**
805
+ * The title of the QR code. This is used for display purposes.
806
+ * @default undefined
807
+ */
808
+ title?: string;
809
+ /**
810
+ * The background color of the QR code. This is a hex color code.
811
+ * @default '#ffffff'
812
+ */
813
+ backgroundColor?: string;
814
+ /**
815
+ * The color of the QR code. This is a hex color code.
816
+ * @default '#000000'
817
+ */
818
+ color?: string;
819
+ /**
820
+ * The size of the QR code. This can be 'small', 'medium', or 'large'.
821
+ * @default QrSize.MEDIUM
822
+ */
823
+ size?: QrSize;
824
+ /**
825
+ * The logo to include in the QR code. This should be a base64 encoded string.
826
+ * @default undefined
827
+ */
828
+ logo?: string;
829
+ };
830
+ ```
831
+
832
+ ## Get a QR Code By Id
833
+
834
+ To get a specific QR code by its ID, you can use the `getQrCode` method:
835
+
836
+ ```javascript
837
+ import { Link } from '@hyphen/sdk';
838
+ const link = new Link({
839
+ organizationId: 'your_organization_id',
840
+ apiKey: 'your_api_key',
841
+ });
842
+ const code = 'code_1234567890'; // It is the code identifier for the short code
843
+ const qr = 'qr_1234567890'; // It is the ID of the QR code you want to retrieve
844
+ const response = await link.getQrCode(code, qr);
845
+ console.log('Get QR Code Response:', response);
846
+ ```
847
+
848
+ ## Get QR Codes for a Short Code
849
+
850
+ To get all QR codes for a short code, you can use the `getQrCodes` method:
851
+
852
+ ```javascript
853
+ import { Link } from '@hyphen/sdk';
854
+ const link = new Link({
855
+ organizationId: 'your_organization_id',
856
+ apiKey: 'your_api_key',
857
+ });
858
+ const code = 'code_1234567890'; // It is the code identifier for the short code
859
+ const response = await link.getQrCodes(code);
860
+ console.log('Get QR Codes Response:', response);
861
+ ```
862
+
863
+ ## Deleting a QR Code
864
+
865
+ To delete a QR code, you can use the `deleteQrCode` method:
866
+
867
+ ```javascript
868
+ import { Link } from '@hyphen/sdk';
869
+ const link = new Link({
870
+ organizationId: 'your_organization_id',
871
+ apiKey: 'your_api_key',
872
+ });
873
+ const code = 'code_1234567890'; // It is the code identifier for the short code
874
+ const qr = 'qr_1234567890'; // It is the ID of the QR code you want to delete
875
+ const response = await link.deleteQrCode(code, qr);
876
+ console.log('Delete QR Code Response:', response);
877
+ ```
878
+
727
879
  # Contributing
728
880
 
729
881
  We welcome contributions to the Hyphen Node.js SDK! If you have an idea for a new feature, bug fix, or improvement, please follow these steps:
package/dist/index.cjs CHANGED
@@ -34,6 +34,7 @@ __export(index_exports, {
34
34
  Hyphen: () => Hyphen,
35
35
  Toggle: () => Toggle,
36
36
  ToggleHooks: () => ToggleHooks,
37
+ env: () => env,
37
38
  loadEnv: () => loadEnv
38
39
  });
39
40
  module.exports = __toCommonJS(index_exports);
@@ -404,7 +405,7 @@ var import_node_process2 = __toESM(require("process"), 1);
404
405
  var import_node_fs = __toESM(require("fs"), 1);
405
406
  var import_node_path = __toESM(require("path"), 1);
406
407
  var import_dotenv2 = require("dotenv");
407
- function loadEnv(options) {
408
+ function env(options) {
408
409
  const local = options?.local ?? true;
409
410
  const currentWorkingDirectory = options?.path ?? import_node_process2.default.cwd();
410
411
  const envPath = import_node_path.default.resolve(currentWorkingDirectory, ".env");
@@ -442,7 +443,8 @@ function loadEnv(options) {
442
443
  }
443
444
  }
444
445
  }
445
- __name(loadEnv, "loadEnv");
446
+ __name(env, "env");
447
+ var loadEnv = env;
446
448
 
447
449
  // src/hyphen.ts
448
450
  var import_hookified3 = require("hookified");
@@ -516,6 +518,9 @@ var BaseService = class extends import_hookified2.Hookified {
516
518
  return import_axios.default.put(url, data, config2);
517
519
  }
518
520
  async delete(url, config2) {
521
+ if (config2 && config2.headers) {
522
+ delete config2.headers["content-type"];
523
+ }
519
524
  return import_axios.default.delete(url, config2);
520
525
  }
521
526
  async patch(url, data, config2) {
@@ -534,7 +539,7 @@ var BaseService = class extends import_hookified2.Hookified {
534
539
  };
535
540
 
536
541
  // src/net-info.ts
537
- loadEnv();
542
+ env();
538
543
  var NetInfo = class extends BaseService {
539
544
  static {
540
545
  __name(this, "NetInfo");
@@ -663,7 +668,8 @@ var NetInfo = class extends BaseService {
663
668
 
664
669
  // src/link.ts
665
670
  var import_node_process4 = __toESM(require("process"), 1);
666
- loadEnv();
671
+ var import_node_buffer = require("buffer");
672
+ env();
667
673
  var defaultLinkUris = [
668
674
  "https://api.hyphen.ai/api/organizations/{organizationId}/link/codes/"
669
675
  ];
@@ -749,16 +755,32 @@ var Link = class extends BaseService {
749
755
  * @param {string} code The code to include in the URI.
750
756
  * @returns {string} The constructed URI.
751
757
  */
752
- getUri(organizationId, code) {
758
+ getUri(organizationId, prefix1, prefix2, prefix3) {
753
759
  if (!organizationId) {
754
760
  throw new Error("Organization ID is required to get the URI.");
755
761
  }
756
762
  let url = this._uris[0].replace("{organizationId}", organizationId);
757
- if (code) {
758
- url = url.endsWith("/") ? `${url}${code}/` : `${url}/${code}/`;
763
+ if (prefix1) {
764
+ url = url.endsWith("/") ? `${url}${prefix1}/` : `${url}/${prefix1}`;
765
+ }
766
+ if (prefix2) {
767
+ url = url.endsWith("/") ? `${url}${prefix2}/` : `${url}/${prefix2}`;
768
+ }
769
+ if (prefix3) {
770
+ url = url.endsWith("/") ? `${url}${prefix3}/` : `${url}/${prefix3}`;
771
+ }
772
+ if (url.endsWith("/")) {
773
+ url = url.slice(0, -1);
759
774
  }
760
775
  return url;
761
776
  }
777
+ /**
778
+ * Create a short code for a long URL.
779
+ * @param {string} longUrl The long URL to shorten.
780
+ * @param {string} domain The domain to use for the short code.
781
+ * @param {CreateShortCodeOptions} options Optional parameters for creating the short code.
782
+ * @returns {Promise<CreateShortCodeResponse>} A promise that resolves to the created short code details.
783
+ */
762
784
  async createShortCode(longUrl, domain, options) {
763
785
  if (!this._organizationId) {
764
786
  throw new Error("Organization ID is required to create a short code.");
@@ -800,6 +822,14 @@ var Link = class extends BaseService {
800
822
  }
801
823
  throw new Error(`Failed to get short code: ${response.statusText}`);
802
824
  }
825
+ /**
826
+ * Get all short codes for the organization.
827
+ * @param {string} titleSearch Optional search term to filter short codes by title.
828
+ * @param {string[]} tags Optional tags to filter short codes.
829
+ * @param {number} pageNumber The page number to retrieve. Default is 1.
830
+ * @param {number} pageSize The number of short codes per page. Default is 100.
831
+ * @returns {Promise<GetShortCodesResponse>} A promise that resolves to the list of short codes.
832
+ */
803
833
  async getShortCodes(titleSearch, tags, pageNumber = 1, pageSize = 100) {
804
834
  if (!this._organizationId) {
805
835
  throw new Error("Organization ID is required to get short codes.");
@@ -825,6 +855,68 @@ var Link = class extends BaseService {
825
855
  throw new Error(`Failed to get short codes: ${response.statusText}`);
826
856
  }
827
857
  /**
858
+ * Get all tags associated with the organization's short codes.
859
+ * @returns {Promise<string[]>} A promise that resolves to an array of tags.
860
+ */
861
+ async getTags() {
862
+ if (!this._organizationId) {
863
+ throw new Error("Organization ID is required to get tags.");
864
+ }
865
+ const url = this.getUri(this._organizationId, "tags");
866
+ const headers = this.createHeaders(this._apiKey);
867
+ const response = await this.get(url, {
868
+ headers
869
+ });
870
+ if (response.status === 200) {
871
+ return response.data;
872
+ }
873
+ throw new Error(`Failed to get tags: ${response.statusText}`);
874
+ }
875
+ /**
876
+ * Get statistics for a specific short code.
877
+ * @param code The short code to retrieve statistics for.
878
+ * @returns {Promise<GetCodeStatsResponse>} A promise that resolves to the code statistics.
879
+ */
880
+ async getCodeStats(code, startDate, endDate) {
881
+ if (!this._organizationId) {
882
+ throw new Error("Organization ID is required to get code stats.");
883
+ }
884
+ const url = this.getUri(this._organizationId, code, "stats");
885
+ const headers = this.createHeaders(this._apiKey);
886
+ const parameters = {
887
+ startDate: startDate.toISOString(),
888
+ endDate: endDate.toISOString()
889
+ };
890
+ const response = await this.get(url, {
891
+ headers,
892
+ params: parameters
893
+ });
894
+ if (response.status === 200) {
895
+ return response.data;
896
+ }
897
+ throw new Error(`Failed to get code stats: ${response.statusText}`);
898
+ }
899
+ /**
900
+ * Update a short code.
901
+ * @param {string} code The short code to update. Example: 'code_686bed403c3991bd676bba4d'
902
+ * @param {UpdateShortCodeOptions} options The options to update the short code with.
903
+ * @returns {Promise<UpdateShortCodeResponse>} A promise that resolves to the updated short code details.
904
+ */
905
+ async updateShortCode(code, options) {
906
+ if (!this._organizationId) {
907
+ throw new Error("Organization ID is required to update a short code.");
908
+ }
909
+ const url = this.getUri(this._organizationId, code);
910
+ const headers = this.createHeaders(this._apiKey);
911
+ const response = await this.patch(url, options, {
912
+ headers
913
+ });
914
+ if (response.status === 200) {
915
+ return response.data;
916
+ }
917
+ throw new Error(`Failed to update short code: ${response.statusText}`);
918
+ }
919
+ /**
828
920
  * Delete a short code.
829
921
  * @param {string} code The short code to delete. Example: 'code_686bed403c3991bd676bba4d'
830
922
  * @returns {Promise<boolean>} A promise that resolves to true if the short code was deleted successfully, or false if it was not.
@@ -835,7 +927,6 @@ var Link = class extends BaseService {
835
927
  }
836
928
  const url = this.getUri(this._organizationId, code);
837
929
  const headers = this.createHeaders(this._apiKey);
838
- delete headers["content-type"];
839
930
  const response = await this.delete(url, {
840
931
  headers
841
932
  });
@@ -844,6 +935,112 @@ var Link = class extends BaseService {
844
935
  }
845
936
  throw new Error(`Failed to delete short code: ${response.statusText}`);
846
937
  }
938
+ /**
939
+ * Create a QR code for a specific short code.
940
+ * @param {string} code The short code to create a QR code for.
941
+ * @param {CreateQrCodeOptions} options The options for creating the QR code.
942
+ * @returns {Promise<CreateQrCodeResponse>} A promise that resolves to the created QR code details.
943
+ */
944
+ async createQrCode(code, options) {
945
+ if (!this._organizationId) {
946
+ throw new Error("Organization ID is required to create a QR code.");
947
+ }
948
+ const url = this.getUri(this._organizationId, code, "qrs");
949
+ const headers = this.createHeaders(this._apiKey);
950
+ const body = {
951
+ title: options?.title,
952
+ backgroundColor: options?.backgroundColor,
953
+ color: options?.color,
954
+ size: options?.size,
955
+ logo: options?.logo
956
+ };
957
+ const response = await this.post(url, body, {
958
+ headers
959
+ });
960
+ if (response.status === 201) {
961
+ const result = response.data;
962
+ if (result.qrCode) {
963
+ const buffer = import_node_buffer.Buffer.from(result.qrCode, "base64");
964
+ result.qrCodeBytes = new Uint16Array(buffer);
965
+ }
966
+ return result;
967
+ }
968
+ throw new Error(`Failed to create QR code: ${response.statusText}`);
969
+ }
970
+ /**
971
+ * Get a QR code by its ID.
972
+ * @param code The short code associated with the QR code.
973
+ * @param qr The ID of the QR code to retrieve.
974
+ * @returns The details of the requested QR code.
975
+ */
976
+ async getQrCode(code, qr) {
977
+ if (!this._organizationId) {
978
+ throw new Error("Organization ID is required to get a QR code.");
979
+ }
980
+ const url = this.getUri(this._organizationId, code, "qrs", qr);
981
+ const headers = this.createHeaders(this._apiKey);
982
+ const response = await this.get(url, {
983
+ headers
984
+ });
985
+ if (response.status === 200) {
986
+ const result = response.data;
987
+ if (result.qrCode) {
988
+ const buffer = import_node_buffer.Buffer.from(result.qrCode, "base64");
989
+ result.qrCodeBytes = new Uint16Array(buffer);
990
+ }
991
+ return result;
992
+ }
993
+ throw new Error(`Failed to get QR code: ${response.statusText}`);
994
+ }
995
+ async getQrCodes(code, pageNumber, pageSize) {
996
+ if (!this._organizationId) {
997
+ throw new Error("Organization ID is required to get QR codes.");
998
+ }
999
+ const url = this.getUri(this._organizationId, code, "qrs");
1000
+ const headers = this.createHeaders(this._apiKey);
1001
+ const parameters = {};
1002
+ if (pageNumber) {
1003
+ parameters.pageNum = pageNumber.toString();
1004
+ }
1005
+ if (pageSize) {
1006
+ parameters.pageSize = pageSize.toString();
1007
+ }
1008
+ const response = await this.get(url, {
1009
+ headers,
1010
+ params: parameters
1011
+ });
1012
+ if (response.status === 200) {
1013
+ const result = response.data;
1014
+ for (const qrCode of result.data) {
1015
+ if (qrCode.qrCode) {
1016
+ const buffer = import_node_buffer.Buffer.from(qrCode.qrCode, "base64");
1017
+ qrCode.qrCodeBytes = new Uint16Array(buffer);
1018
+ }
1019
+ }
1020
+ return result;
1021
+ }
1022
+ throw new Error(`Failed to get QR codes: ${response.statusText}`);
1023
+ }
1024
+ /**
1025
+ * Delete a QR code by its ID.
1026
+ * @param {string} code The short code associated with the QR code.
1027
+ * @param {string} qr The ID of the QR code to delete.
1028
+ * @returns {Promise<boolean>} A promise that resolves to true if the QR code was deleted successfully, or false if it was not.
1029
+ */
1030
+ async deleteQrCode(code, qr) {
1031
+ if (!this._organizationId) {
1032
+ throw new Error("Organization ID is required to delete a QR code.");
1033
+ }
1034
+ const url = this.getUri(this._organizationId, code, "qrs", qr);
1035
+ const headers = this.createHeaders(this._apiKey);
1036
+ const response = await this.delete(url, {
1037
+ headers
1038
+ });
1039
+ if (response.status === 204) {
1040
+ return true;
1041
+ }
1042
+ throw new Error(`Failed to delete QR code: ${response.statusText}`);
1043
+ }
847
1044
  };
848
1045
 
849
1046
  // src/hyphen.ts
@@ -968,5 +1165,6 @@ var Hyphen = class extends import_hookified3.Hookified {
968
1165
  Hyphen,
969
1166
  Toggle,
970
1167
  ToggleHooks,
1168
+ env,
971
1169
  loadEnv
972
1170
  });
package/dist/index.d.cts CHANGED
@@ -206,7 +206,7 @@ declare class Toggle extends Hookified {
206
206
  getObject<T>(key: string, defaultValue: T, options?: ToggleGetOptions): Promise<T>;
207
207
  }
208
208
 
209
- type LoadEnvOptions = {
209
+ type EnvOptions = {
210
210
  path?: string;
211
211
  environment?: string;
212
212
  local?: boolean;
@@ -214,13 +214,15 @@ type LoadEnvOptions = {
214
214
  /**
215
215
  * @description Helper function to load your environment variables based on your default .env file
216
216
  * and the current environment.
217
- * @param {LoadEnvOptions} [options] - Options to customize the loading of environment variables.
217
+ * @param {EnvOptions} [options] - Options to customize the loading of environment variables.
218
218
  * @returns {void}
219
219
  * @example
220
- * import { loadEnv } from '@hyphen/sdk';
221
- * loadEnv();
220
+ * import { env } from '@hyphen/sdk';
221
+ * env();
222
222
  */
223
- declare function loadEnv(options?: LoadEnvOptions): void;
223
+ declare function env(options?: EnvOptions): void;
224
+ declare const loadEnv: typeof env;
225
+ type LoadEnvOptions = EnvOptions;
224
226
 
225
227
  type BaseServiceOptions = {
226
228
  throwErrors?: boolean;
@@ -315,6 +317,41 @@ declare class NetInfo extends BaseService {
315
317
  getIpInfos(ips: string[]): Promise<Array<ipInfo | ipInfoError>>;
316
318
  }
317
319
 
320
+ type ClickByDay = {
321
+ date: string;
322
+ total: number;
323
+ unique: number;
324
+ };
325
+ type Clicks = {
326
+ total: number;
327
+ unique: number;
328
+ byDay: ClickByDay[];
329
+ };
330
+ type Referral = {
331
+ url: string;
332
+ total: number;
333
+ };
334
+ type Browser = {
335
+ name: string;
336
+ total: number;
337
+ };
338
+ type Device = {
339
+ name: string;
340
+ total: number;
341
+ };
342
+ type Location = {
343
+ country: string;
344
+ total: number;
345
+ unique: number;
346
+ };
347
+ type GetCodeStatsResponse = {
348
+ clicks: Clicks;
349
+ referrals: Referral[];
350
+ browsers: Browser[];
351
+ devices: Device[];
352
+ locations: Location[];
353
+ };
354
+
318
355
  type CreateShortCodeOptions = {
319
356
  /**
320
357
  * The short code used for this link. If not provided, a random code will be generated.
@@ -345,6 +382,24 @@ type CreateShortCodeResponse = {
345
382
  name: string;
346
383
  };
347
384
  };
385
+ type UpdateShortCodeResponse = CreateShortCodeResponse;
386
+ type UpdateShortCodeOptions = {
387
+ /**
388
+ * The long URL that the short code will redirect to.
389
+ * @default undefined
390
+ */
391
+ long_url?: string;
392
+ /**
393
+ * The title of the link. This is used for display purposes.
394
+ * @default undefined
395
+ */
396
+ title?: string;
397
+ /**
398
+ * The tags associated with the link. This is used for categorization purposes.
399
+ * @default undefined
400
+ */
401
+ tags?: string[];
402
+ };
348
403
  type GetShortCodesResponse = {
349
404
  total: number;
350
405
  pageNum: number;
@@ -352,6 +407,51 @@ type GetShortCodesResponse = {
352
407
  data: GetShortCodeResponse[];
353
408
  };
354
409
  type GetShortCodeResponse = CreateShortCodeResponse;
410
+ declare enum QrSize {
411
+ SMALL = "small",
412
+ MEDIUM = "medium",
413
+ LARGE = "large"
414
+ }
415
+ type CreateQrCodeOptions = {
416
+ /**
417
+ * The title of the QR code. This is used for display purposes.
418
+ * @default undefined
419
+ */
420
+ title?: string;
421
+ /**
422
+ * The background color of the QR code. This is a hex color code.
423
+ * @default '#ffffff'
424
+ */
425
+ backgroundColor?: string;
426
+ /**
427
+ * The color of the QR code. This is a hex color code.
428
+ * @default '#000000'
429
+ */
430
+ color?: string;
431
+ /**
432
+ * The size of the QR code. This can be 'small', 'medium', or 'large'.
433
+ * @default QrSize.MEDIUM
434
+ */
435
+ size?: QrSize;
436
+ /**
437
+ * The logo to include in the QR code. This should be a base64 encoded string.
438
+ * @default undefined
439
+ */
440
+ logo?: string;
441
+ };
442
+ type CreateQrCodeResponse = {
443
+ id: string;
444
+ title?: string;
445
+ qrCode: string;
446
+ qrCodeBytes: Uint16Array;
447
+ qrLink: string;
448
+ };
449
+ type GetQrCodesResponse = {
450
+ total: number;
451
+ pageNum: number;
452
+ pageSize: number;
453
+ data: CreateQrCodeResponse[];
454
+ };
355
455
  type LinkOptions = {
356
456
  /**
357
457
  * The URIs to access the link service.
@@ -415,7 +515,14 @@ declare class Link extends BaseService {
415
515
  * @param {string} code The code to include in the URI.
416
516
  * @returns {string} The constructed URI.
417
517
  */
418
- getUri(organizationId: string, code?: string): string;
518
+ getUri(organizationId: string, prefix1?: string, prefix2?: string, prefix3?: string): string;
519
+ /**
520
+ * Create a short code for a long URL.
521
+ * @param {string} longUrl The long URL to shorten.
522
+ * @param {string} domain The domain to use for the short code.
523
+ * @param {CreateShortCodeOptions} options Optional parameters for creating the short code.
524
+ * @returns {Promise<CreateShortCodeResponse>} A promise that resolves to the created short code details.
525
+ */
419
526
  createShortCode(longUrl: string, domain: string, options?: CreateShortCodeOptions): Promise<CreateShortCodeResponse>;
420
527
  /**
421
528
  * Get a short code by its code.
@@ -423,13 +530,61 @@ declare class Link extends BaseService {
423
530
  * @returns {Promise<GetShortCodeResponse>} A promise that resolves to the short code details.
424
531
  */
425
532
  getShortCode(code: string): Promise<GetShortCodeResponse>;
533
+ /**
534
+ * Get all short codes for the organization.
535
+ * @param {string} titleSearch Optional search term to filter short codes by title.
536
+ * @param {string[]} tags Optional tags to filter short codes.
537
+ * @param {number} pageNumber The page number to retrieve. Default is 1.
538
+ * @param {number} pageSize The number of short codes per page. Default is 100.
539
+ * @returns {Promise<GetShortCodesResponse>} A promise that resolves to the list of short codes.
540
+ */
426
541
  getShortCodes(titleSearch: string, tags?: string[], pageNumber?: number, pageSize?: number): Promise<GetShortCodesResponse>;
542
+ /**
543
+ * Get all tags associated with the organization's short codes.
544
+ * @returns {Promise<string[]>} A promise that resolves to an array of tags.
545
+ */
546
+ getTags(): Promise<string[]>;
547
+ /**
548
+ * Get statistics for a specific short code.
549
+ * @param code The short code to retrieve statistics for.
550
+ * @returns {Promise<GetCodeStatsResponse>} A promise that resolves to the code statistics.
551
+ */
552
+ getCodeStats(code: string, startDate: Date, endDate: Date): Promise<GetCodeStatsResponse>;
553
+ /**
554
+ * Update a short code.
555
+ * @param {string} code The short code to update. Example: 'code_686bed403c3991bd676bba4d'
556
+ * @param {UpdateShortCodeOptions} options The options to update the short code with.
557
+ * @returns {Promise<UpdateShortCodeResponse>} A promise that resolves to the updated short code details.
558
+ */
559
+ updateShortCode(code: string, options: UpdateShortCodeOptions): Promise<UpdateShortCodeResponse>;
427
560
  /**
428
561
  * Delete a short code.
429
562
  * @param {string} code The short code to delete. Example: 'code_686bed403c3991bd676bba4d'
430
563
  * @returns {Promise<boolean>} A promise that resolves to true if the short code was deleted successfully, or false if it was not.
431
564
  */
432
565
  deleteShortCode(code: string): Promise<boolean>;
566
+ /**
567
+ * Create a QR code for a specific short code.
568
+ * @param {string} code The short code to create a QR code for.
569
+ * @param {CreateQrCodeOptions} options The options for creating the QR code.
570
+ * @returns {Promise<CreateQrCodeResponse>} A promise that resolves to the created QR code details.
571
+ */
572
+ createQrCode(code: string, options?: CreateQrCodeOptions): Promise<CreateQrCodeResponse>;
573
+ /**
574
+ * Get a QR code by its ID.
575
+ * @param code The short code associated with the QR code.
576
+ * @param qr The ID of the QR code to retrieve.
577
+ * @returns The details of the requested QR code.
578
+ */
579
+ getQrCode(code: string, qr: string): Promise<CreateQrCodeResponse>;
580
+ getQrCodes(code: string, pageNumber?: number, pageSize?: number): Promise<GetQrCodesResponse>;
581
+ /**
582
+ * Delete a QR code by its ID.
583
+ * @param {string} code The short code associated with the QR code.
584
+ * @param {string} qr The ID of the QR code to delete.
585
+ * @returns {Promise<boolean>} A promise that resolves to true if the QR code was deleted successfully, or false if it was not.
586
+ */
587
+ deleteQrCode(code: string, qr: string): Promise<boolean>;
433
588
  }
434
589
 
435
590
  type HyphenOptions = {
@@ -531,4 +686,4 @@ declare class Hyphen extends Hookified {
531
686
  set throwErrors(value: boolean);
532
687
  }
533
688
 
534
- export { Hyphen, type HyphenOptions, Toggle, type ToggleCachingOptions, type ToggleContext, type ToggleGetOptions, ToggleHooks, type ToggleOptions, loadEnv };
689
+ export { type EnvOptions, Hyphen, type HyphenOptions, type LoadEnvOptions, Toggle, type ToggleCachingOptions, type ToggleContext, type ToggleGetOptions, ToggleHooks, type ToggleOptions, env, loadEnv };
package/dist/index.d.ts CHANGED
@@ -206,7 +206,7 @@ declare class Toggle extends Hookified {
206
206
  getObject<T>(key: string, defaultValue: T, options?: ToggleGetOptions): Promise<T>;
207
207
  }
208
208
 
209
- type LoadEnvOptions = {
209
+ type EnvOptions = {
210
210
  path?: string;
211
211
  environment?: string;
212
212
  local?: boolean;
@@ -214,13 +214,15 @@ type LoadEnvOptions = {
214
214
  /**
215
215
  * @description Helper function to load your environment variables based on your default .env file
216
216
  * and the current environment.
217
- * @param {LoadEnvOptions} [options] - Options to customize the loading of environment variables.
217
+ * @param {EnvOptions} [options] - Options to customize the loading of environment variables.
218
218
  * @returns {void}
219
219
  * @example
220
- * import { loadEnv } from '@hyphen/sdk';
221
- * loadEnv();
220
+ * import { env } from '@hyphen/sdk';
221
+ * env();
222
222
  */
223
- declare function loadEnv(options?: LoadEnvOptions): void;
223
+ declare function env(options?: EnvOptions): void;
224
+ declare const loadEnv: typeof env;
225
+ type LoadEnvOptions = EnvOptions;
224
226
 
225
227
  type BaseServiceOptions = {
226
228
  throwErrors?: boolean;
@@ -315,6 +317,41 @@ declare class NetInfo extends BaseService {
315
317
  getIpInfos(ips: string[]): Promise<Array<ipInfo | ipInfoError>>;
316
318
  }
317
319
 
320
+ type ClickByDay = {
321
+ date: string;
322
+ total: number;
323
+ unique: number;
324
+ };
325
+ type Clicks = {
326
+ total: number;
327
+ unique: number;
328
+ byDay: ClickByDay[];
329
+ };
330
+ type Referral = {
331
+ url: string;
332
+ total: number;
333
+ };
334
+ type Browser = {
335
+ name: string;
336
+ total: number;
337
+ };
338
+ type Device = {
339
+ name: string;
340
+ total: number;
341
+ };
342
+ type Location = {
343
+ country: string;
344
+ total: number;
345
+ unique: number;
346
+ };
347
+ type GetCodeStatsResponse = {
348
+ clicks: Clicks;
349
+ referrals: Referral[];
350
+ browsers: Browser[];
351
+ devices: Device[];
352
+ locations: Location[];
353
+ };
354
+
318
355
  type CreateShortCodeOptions = {
319
356
  /**
320
357
  * The short code used for this link. If not provided, a random code will be generated.
@@ -345,6 +382,24 @@ type CreateShortCodeResponse = {
345
382
  name: string;
346
383
  };
347
384
  };
385
+ type UpdateShortCodeResponse = CreateShortCodeResponse;
386
+ type UpdateShortCodeOptions = {
387
+ /**
388
+ * The long URL that the short code will redirect to.
389
+ * @default undefined
390
+ */
391
+ long_url?: string;
392
+ /**
393
+ * The title of the link. This is used for display purposes.
394
+ * @default undefined
395
+ */
396
+ title?: string;
397
+ /**
398
+ * The tags associated with the link. This is used for categorization purposes.
399
+ * @default undefined
400
+ */
401
+ tags?: string[];
402
+ };
348
403
  type GetShortCodesResponse = {
349
404
  total: number;
350
405
  pageNum: number;
@@ -352,6 +407,51 @@ type GetShortCodesResponse = {
352
407
  data: GetShortCodeResponse[];
353
408
  };
354
409
  type GetShortCodeResponse = CreateShortCodeResponse;
410
+ declare enum QrSize {
411
+ SMALL = "small",
412
+ MEDIUM = "medium",
413
+ LARGE = "large"
414
+ }
415
+ type CreateQrCodeOptions = {
416
+ /**
417
+ * The title of the QR code. This is used for display purposes.
418
+ * @default undefined
419
+ */
420
+ title?: string;
421
+ /**
422
+ * The background color of the QR code. This is a hex color code.
423
+ * @default '#ffffff'
424
+ */
425
+ backgroundColor?: string;
426
+ /**
427
+ * The color of the QR code. This is a hex color code.
428
+ * @default '#000000'
429
+ */
430
+ color?: string;
431
+ /**
432
+ * The size of the QR code. This can be 'small', 'medium', or 'large'.
433
+ * @default QrSize.MEDIUM
434
+ */
435
+ size?: QrSize;
436
+ /**
437
+ * The logo to include in the QR code. This should be a base64 encoded string.
438
+ * @default undefined
439
+ */
440
+ logo?: string;
441
+ };
442
+ type CreateQrCodeResponse = {
443
+ id: string;
444
+ title?: string;
445
+ qrCode: string;
446
+ qrCodeBytes: Uint16Array;
447
+ qrLink: string;
448
+ };
449
+ type GetQrCodesResponse = {
450
+ total: number;
451
+ pageNum: number;
452
+ pageSize: number;
453
+ data: CreateQrCodeResponse[];
454
+ };
355
455
  type LinkOptions = {
356
456
  /**
357
457
  * The URIs to access the link service.
@@ -415,7 +515,14 @@ declare class Link extends BaseService {
415
515
  * @param {string} code The code to include in the URI.
416
516
  * @returns {string} The constructed URI.
417
517
  */
418
- getUri(organizationId: string, code?: string): string;
518
+ getUri(organizationId: string, prefix1?: string, prefix2?: string, prefix3?: string): string;
519
+ /**
520
+ * Create a short code for a long URL.
521
+ * @param {string} longUrl The long URL to shorten.
522
+ * @param {string} domain The domain to use for the short code.
523
+ * @param {CreateShortCodeOptions} options Optional parameters for creating the short code.
524
+ * @returns {Promise<CreateShortCodeResponse>} A promise that resolves to the created short code details.
525
+ */
419
526
  createShortCode(longUrl: string, domain: string, options?: CreateShortCodeOptions): Promise<CreateShortCodeResponse>;
420
527
  /**
421
528
  * Get a short code by its code.
@@ -423,13 +530,61 @@ declare class Link extends BaseService {
423
530
  * @returns {Promise<GetShortCodeResponse>} A promise that resolves to the short code details.
424
531
  */
425
532
  getShortCode(code: string): Promise<GetShortCodeResponse>;
533
+ /**
534
+ * Get all short codes for the organization.
535
+ * @param {string} titleSearch Optional search term to filter short codes by title.
536
+ * @param {string[]} tags Optional tags to filter short codes.
537
+ * @param {number} pageNumber The page number to retrieve. Default is 1.
538
+ * @param {number} pageSize The number of short codes per page. Default is 100.
539
+ * @returns {Promise<GetShortCodesResponse>} A promise that resolves to the list of short codes.
540
+ */
426
541
  getShortCodes(titleSearch: string, tags?: string[], pageNumber?: number, pageSize?: number): Promise<GetShortCodesResponse>;
542
+ /**
543
+ * Get all tags associated with the organization's short codes.
544
+ * @returns {Promise<string[]>} A promise that resolves to an array of tags.
545
+ */
546
+ getTags(): Promise<string[]>;
547
+ /**
548
+ * Get statistics for a specific short code.
549
+ * @param code The short code to retrieve statistics for.
550
+ * @returns {Promise<GetCodeStatsResponse>} A promise that resolves to the code statistics.
551
+ */
552
+ getCodeStats(code: string, startDate: Date, endDate: Date): Promise<GetCodeStatsResponse>;
553
+ /**
554
+ * Update a short code.
555
+ * @param {string} code The short code to update. Example: 'code_686bed403c3991bd676bba4d'
556
+ * @param {UpdateShortCodeOptions} options The options to update the short code with.
557
+ * @returns {Promise<UpdateShortCodeResponse>} A promise that resolves to the updated short code details.
558
+ */
559
+ updateShortCode(code: string, options: UpdateShortCodeOptions): Promise<UpdateShortCodeResponse>;
427
560
  /**
428
561
  * Delete a short code.
429
562
  * @param {string} code The short code to delete. Example: 'code_686bed403c3991bd676bba4d'
430
563
  * @returns {Promise<boolean>} A promise that resolves to true if the short code was deleted successfully, or false if it was not.
431
564
  */
432
565
  deleteShortCode(code: string): Promise<boolean>;
566
+ /**
567
+ * Create a QR code for a specific short code.
568
+ * @param {string} code The short code to create a QR code for.
569
+ * @param {CreateQrCodeOptions} options The options for creating the QR code.
570
+ * @returns {Promise<CreateQrCodeResponse>} A promise that resolves to the created QR code details.
571
+ */
572
+ createQrCode(code: string, options?: CreateQrCodeOptions): Promise<CreateQrCodeResponse>;
573
+ /**
574
+ * Get a QR code by its ID.
575
+ * @param code The short code associated with the QR code.
576
+ * @param qr The ID of the QR code to retrieve.
577
+ * @returns The details of the requested QR code.
578
+ */
579
+ getQrCode(code: string, qr: string): Promise<CreateQrCodeResponse>;
580
+ getQrCodes(code: string, pageNumber?: number, pageSize?: number): Promise<GetQrCodesResponse>;
581
+ /**
582
+ * Delete a QR code by its ID.
583
+ * @param {string} code The short code associated with the QR code.
584
+ * @param {string} qr The ID of the QR code to delete.
585
+ * @returns {Promise<boolean>} A promise that resolves to true if the QR code was deleted successfully, or false if it was not.
586
+ */
587
+ deleteQrCode(code: string, qr: string): Promise<boolean>;
433
588
  }
434
589
 
435
590
  type HyphenOptions = {
@@ -531,4 +686,4 @@ declare class Hyphen extends Hookified {
531
686
  set throwErrors(value: boolean);
532
687
  }
533
688
 
534
- export { Hyphen, type HyphenOptions, Toggle, type ToggleCachingOptions, type ToggleContext, type ToggleGetOptions, ToggleHooks, type ToggleOptions, loadEnv };
689
+ export { type EnvOptions, Hyphen, type HyphenOptions, type LoadEnvOptions, Toggle, type ToggleCachingOptions, type ToggleContext, type ToggleGetOptions, ToggleHooks, type ToggleOptions, env, loadEnv };
package/dist/index.js CHANGED
@@ -367,7 +367,7 @@ import process2 from "process";
367
367
  import fs from "fs";
368
368
  import path from "path";
369
369
  import { config } from "dotenv";
370
- function loadEnv(options) {
370
+ function env(options) {
371
371
  const local = options?.local ?? true;
372
372
  const currentWorkingDirectory = options?.path ?? process2.cwd();
373
373
  const envPath = path.resolve(currentWorkingDirectory, ".env");
@@ -405,7 +405,8 @@ function loadEnv(options) {
405
405
  }
406
406
  }
407
407
  }
408
- __name(loadEnv, "loadEnv");
408
+ __name(env, "env");
409
+ var loadEnv = env;
409
410
 
410
411
  // src/hyphen.ts
411
412
  import { Hookified as Hookified3 } from "hookified";
@@ -479,6 +480,9 @@ var BaseService = class extends Hookified2 {
479
480
  return axios.put(url, data, config2);
480
481
  }
481
482
  async delete(url, config2) {
483
+ if (config2 && config2.headers) {
484
+ delete config2.headers["content-type"];
485
+ }
482
486
  return axios.delete(url, config2);
483
487
  }
484
488
  async patch(url, data, config2) {
@@ -497,7 +501,7 @@ var BaseService = class extends Hookified2 {
497
501
  };
498
502
 
499
503
  // src/net-info.ts
500
- loadEnv();
504
+ env();
501
505
  var NetInfo = class extends BaseService {
502
506
  static {
503
507
  __name(this, "NetInfo");
@@ -626,7 +630,8 @@ var NetInfo = class extends BaseService {
626
630
 
627
631
  // src/link.ts
628
632
  import process4 from "process";
629
- loadEnv();
633
+ import { Buffer as Buffer2 } from "buffer";
634
+ env();
630
635
  var defaultLinkUris = [
631
636
  "https://api.hyphen.ai/api/organizations/{organizationId}/link/codes/"
632
637
  ];
@@ -712,16 +717,32 @@ var Link = class extends BaseService {
712
717
  * @param {string} code The code to include in the URI.
713
718
  * @returns {string} The constructed URI.
714
719
  */
715
- getUri(organizationId, code) {
720
+ getUri(organizationId, prefix1, prefix2, prefix3) {
716
721
  if (!organizationId) {
717
722
  throw new Error("Organization ID is required to get the URI.");
718
723
  }
719
724
  let url = this._uris[0].replace("{organizationId}", organizationId);
720
- if (code) {
721
- url = url.endsWith("/") ? `${url}${code}/` : `${url}/${code}/`;
725
+ if (prefix1) {
726
+ url = url.endsWith("/") ? `${url}${prefix1}/` : `${url}/${prefix1}`;
727
+ }
728
+ if (prefix2) {
729
+ url = url.endsWith("/") ? `${url}${prefix2}/` : `${url}/${prefix2}`;
730
+ }
731
+ if (prefix3) {
732
+ url = url.endsWith("/") ? `${url}${prefix3}/` : `${url}/${prefix3}`;
733
+ }
734
+ if (url.endsWith("/")) {
735
+ url = url.slice(0, -1);
722
736
  }
723
737
  return url;
724
738
  }
739
+ /**
740
+ * Create a short code for a long URL.
741
+ * @param {string} longUrl The long URL to shorten.
742
+ * @param {string} domain The domain to use for the short code.
743
+ * @param {CreateShortCodeOptions} options Optional parameters for creating the short code.
744
+ * @returns {Promise<CreateShortCodeResponse>} A promise that resolves to the created short code details.
745
+ */
725
746
  async createShortCode(longUrl, domain, options) {
726
747
  if (!this._organizationId) {
727
748
  throw new Error("Organization ID is required to create a short code.");
@@ -763,6 +784,14 @@ var Link = class extends BaseService {
763
784
  }
764
785
  throw new Error(`Failed to get short code: ${response.statusText}`);
765
786
  }
787
+ /**
788
+ * Get all short codes for the organization.
789
+ * @param {string} titleSearch Optional search term to filter short codes by title.
790
+ * @param {string[]} tags Optional tags to filter short codes.
791
+ * @param {number} pageNumber The page number to retrieve. Default is 1.
792
+ * @param {number} pageSize The number of short codes per page. Default is 100.
793
+ * @returns {Promise<GetShortCodesResponse>} A promise that resolves to the list of short codes.
794
+ */
766
795
  async getShortCodes(titleSearch, tags, pageNumber = 1, pageSize = 100) {
767
796
  if (!this._organizationId) {
768
797
  throw new Error("Organization ID is required to get short codes.");
@@ -788,6 +817,68 @@ var Link = class extends BaseService {
788
817
  throw new Error(`Failed to get short codes: ${response.statusText}`);
789
818
  }
790
819
  /**
820
+ * Get all tags associated with the organization's short codes.
821
+ * @returns {Promise<string[]>} A promise that resolves to an array of tags.
822
+ */
823
+ async getTags() {
824
+ if (!this._organizationId) {
825
+ throw new Error("Organization ID is required to get tags.");
826
+ }
827
+ const url = this.getUri(this._organizationId, "tags");
828
+ const headers = this.createHeaders(this._apiKey);
829
+ const response = await this.get(url, {
830
+ headers
831
+ });
832
+ if (response.status === 200) {
833
+ return response.data;
834
+ }
835
+ throw new Error(`Failed to get tags: ${response.statusText}`);
836
+ }
837
+ /**
838
+ * Get statistics for a specific short code.
839
+ * @param code The short code to retrieve statistics for.
840
+ * @returns {Promise<GetCodeStatsResponse>} A promise that resolves to the code statistics.
841
+ */
842
+ async getCodeStats(code, startDate, endDate) {
843
+ if (!this._organizationId) {
844
+ throw new Error("Organization ID is required to get code stats.");
845
+ }
846
+ const url = this.getUri(this._organizationId, code, "stats");
847
+ const headers = this.createHeaders(this._apiKey);
848
+ const parameters = {
849
+ startDate: startDate.toISOString(),
850
+ endDate: endDate.toISOString()
851
+ };
852
+ const response = await this.get(url, {
853
+ headers,
854
+ params: parameters
855
+ });
856
+ if (response.status === 200) {
857
+ return response.data;
858
+ }
859
+ throw new Error(`Failed to get code stats: ${response.statusText}`);
860
+ }
861
+ /**
862
+ * Update a short code.
863
+ * @param {string} code The short code to update. Example: 'code_686bed403c3991bd676bba4d'
864
+ * @param {UpdateShortCodeOptions} options The options to update the short code with.
865
+ * @returns {Promise<UpdateShortCodeResponse>} A promise that resolves to the updated short code details.
866
+ */
867
+ async updateShortCode(code, options) {
868
+ if (!this._organizationId) {
869
+ throw new Error("Organization ID is required to update a short code.");
870
+ }
871
+ const url = this.getUri(this._organizationId, code);
872
+ const headers = this.createHeaders(this._apiKey);
873
+ const response = await this.patch(url, options, {
874
+ headers
875
+ });
876
+ if (response.status === 200) {
877
+ return response.data;
878
+ }
879
+ throw new Error(`Failed to update short code: ${response.statusText}`);
880
+ }
881
+ /**
791
882
  * Delete a short code.
792
883
  * @param {string} code The short code to delete. Example: 'code_686bed403c3991bd676bba4d'
793
884
  * @returns {Promise<boolean>} A promise that resolves to true if the short code was deleted successfully, or false if it was not.
@@ -798,7 +889,6 @@ var Link = class extends BaseService {
798
889
  }
799
890
  const url = this.getUri(this._organizationId, code);
800
891
  const headers = this.createHeaders(this._apiKey);
801
- delete headers["content-type"];
802
892
  const response = await this.delete(url, {
803
893
  headers
804
894
  });
@@ -807,6 +897,112 @@ var Link = class extends BaseService {
807
897
  }
808
898
  throw new Error(`Failed to delete short code: ${response.statusText}`);
809
899
  }
900
+ /**
901
+ * Create a QR code for a specific short code.
902
+ * @param {string} code The short code to create a QR code for.
903
+ * @param {CreateQrCodeOptions} options The options for creating the QR code.
904
+ * @returns {Promise<CreateQrCodeResponse>} A promise that resolves to the created QR code details.
905
+ */
906
+ async createQrCode(code, options) {
907
+ if (!this._organizationId) {
908
+ throw new Error("Organization ID is required to create a QR code.");
909
+ }
910
+ const url = this.getUri(this._organizationId, code, "qrs");
911
+ const headers = this.createHeaders(this._apiKey);
912
+ const body = {
913
+ title: options?.title,
914
+ backgroundColor: options?.backgroundColor,
915
+ color: options?.color,
916
+ size: options?.size,
917
+ logo: options?.logo
918
+ };
919
+ const response = await this.post(url, body, {
920
+ headers
921
+ });
922
+ if (response.status === 201) {
923
+ const result = response.data;
924
+ if (result.qrCode) {
925
+ const buffer = Buffer2.from(result.qrCode, "base64");
926
+ result.qrCodeBytes = new Uint16Array(buffer);
927
+ }
928
+ return result;
929
+ }
930
+ throw new Error(`Failed to create QR code: ${response.statusText}`);
931
+ }
932
+ /**
933
+ * Get a QR code by its ID.
934
+ * @param code The short code associated with the QR code.
935
+ * @param qr The ID of the QR code to retrieve.
936
+ * @returns The details of the requested QR code.
937
+ */
938
+ async getQrCode(code, qr) {
939
+ if (!this._organizationId) {
940
+ throw new Error("Organization ID is required to get a QR code.");
941
+ }
942
+ const url = this.getUri(this._organizationId, code, "qrs", qr);
943
+ const headers = this.createHeaders(this._apiKey);
944
+ const response = await this.get(url, {
945
+ headers
946
+ });
947
+ if (response.status === 200) {
948
+ const result = response.data;
949
+ if (result.qrCode) {
950
+ const buffer = Buffer2.from(result.qrCode, "base64");
951
+ result.qrCodeBytes = new Uint16Array(buffer);
952
+ }
953
+ return result;
954
+ }
955
+ throw new Error(`Failed to get QR code: ${response.statusText}`);
956
+ }
957
+ async getQrCodes(code, pageNumber, pageSize) {
958
+ if (!this._organizationId) {
959
+ throw new Error("Organization ID is required to get QR codes.");
960
+ }
961
+ const url = this.getUri(this._organizationId, code, "qrs");
962
+ const headers = this.createHeaders(this._apiKey);
963
+ const parameters = {};
964
+ if (pageNumber) {
965
+ parameters.pageNum = pageNumber.toString();
966
+ }
967
+ if (pageSize) {
968
+ parameters.pageSize = pageSize.toString();
969
+ }
970
+ const response = await this.get(url, {
971
+ headers,
972
+ params: parameters
973
+ });
974
+ if (response.status === 200) {
975
+ const result = response.data;
976
+ for (const qrCode of result.data) {
977
+ if (qrCode.qrCode) {
978
+ const buffer = Buffer2.from(qrCode.qrCode, "base64");
979
+ qrCode.qrCodeBytes = new Uint16Array(buffer);
980
+ }
981
+ }
982
+ return result;
983
+ }
984
+ throw new Error(`Failed to get QR codes: ${response.statusText}`);
985
+ }
986
+ /**
987
+ * Delete a QR code by its ID.
988
+ * @param {string} code The short code associated with the QR code.
989
+ * @param {string} qr The ID of the QR code to delete.
990
+ * @returns {Promise<boolean>} A promise that resolves to true if the QR code was deleted successfully, or false if it was not.
991
+ */
992
+ async deleteQrCode(code, qr) {
993
+ if (!this._organizationId) {
994
+ throw new Error("Organization ID is required to delete a QR code.");
995
+ }
996
+ const url = this.getUri(this._organizationId, code, "qrs", qr);
997
+ const headers = this.createHeaders(this._apiKey);
998
+ const response = await this.delete(url, {
999
+ headers
1000
+ });
1001
+ if (response.status === 204) {
1002
+ return true;
1003
+ }
1004
+ throw new Error(`Failed to delete QR code: ${response.statusText}`);
1005
+ }
810
1006
  };
811
1007
 
812
1008
  // src/hyphen.ts
@@ -930,5 +1126,6 @@ export {
930
1126
  Hyphen,
931
1127
  Toggle,
932
1128
  ToggleHooks,
1129
+ env,
933
1130
  loadEnv
934
1131
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyphen/sdk",
3
- "version": "1.11.0",
3
+ "version": "1.12.0",
4
4
  "description": "Hyphen SDK for Node.js",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -12,6 +12,13 @@
12
12
  }
13
13
  },
14
14
  "types": "dist/index.d.ts",
15
+ "scripts": {
16
+ "test": "xo --fix && vitest run --coverage",
17
+ "test:ci": "xo && vitest run --coverage",
18
+ "build": "rimraf ./dist && tsup src/index.ts --format esm,cjs --dts --clean",
19
+ "clean": "rimraf ./dist pnpm-lock.yaml node_modules coverage",
20
+ "prepublishOnly": "rimraf ./dist && tsup src/index.ts --format esm,cjs --dts --clean"
21
+ },
15
22
  "keywords": [
16
23
  "hyphen",
17
24
  "sdk",
@@ -22,15 +29,15 @@
22
29
  "author": "Team Hyphen <hello@hyphen.ai>",
23
30
  "license": "MIT",
24
31
  "devDependencies": {
25
- "@swc/core": "^1.12.9",
26
- "@types/node": "^24.0.10",
32
+ "@swc/core": "^1.13.2",
33
+ "@types/node": "^24.1.0",
27
34
  "@vitest/coverage-v8": "^3.2.4",
28
35
  "rimraf": "^6.0.1",
29
36
  "tsd": "^0.32.0",
30
37
  "tsup": "^8.5.0",
31
38
  "typescript": "^5.8.3",
32
39
  "vitest": "^3.2.4",
33
- "xo": "^1.1.1"
40
+ "xo": "^1.2.1"
34
41
  },
35
42
  "files": [
36
43
  "dist",
@@ -40,16 +47,10 @@
40
47
  "@faker-js/faker": "^9.9.0",
41
48
  "@hyphen/openfeature-server-provider": "^1.0.7",
42
49
  "@openfeature/server-sdk": "^1.18.0",
43
- "axios": "^1.10.0",
44
- "cacheable": "^1.10.1",
45
- "dotenv": "^17.0.1",
50
+ "axios": "^1.11.0",
51
+ "cacheable": "^1.10.3",
52
+ "dotenv": "^17.2.1",
46
53
  "hookified": "^1.10.0",
47
54
  "pino": "^9.7.0"
48
- },
49
- "scripts": {
50
- "test": "xo --fix && vitest run --coverage",
51
- "test:ci": "xo && vitest run --coverage",
52
- "build": "rimraf ./dist && tsup src/index.ts --format esm,cjs --dts --clean",
53
- "clean": "rimraf ./dist pnpm-lock.yaml node_modules coverage"
54
55
  }
55
- }
56
+ }