@sinch/sdk-client 0.0.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.
Files changed (116) hide show
  1. package/README.md +109 -0
  2. package/dist/api/api-client-options-helper.d.ts +0 -0
  3. package/dist/api/api-client-options-helper.js +39 -0
  4. package/dist/api/api-client-options-helper.js.map +1 -0
  5. package/dist/api/api-client-options.d.ts +28 -0
  6. package/dist/api/api-client-options.js +3 -0
  7. package/dist/api/api-client-options.js.map +1 -0
  8. package/dist/api/api-client.d.ts +104 -0
  9. package/dist/api/api-client.js +119 -0
  10. package/dist/api/api-client.js.map +1 -0
  11. package/dist/api/api-errors.d.ts +50 -0
  12. package/dist/api/api-errors.js +51 -0
  13. package/dist/api/api-errors.js.map +1 -0
  14. package/dist/api/api-interface.d.ts +8 -0
  15. package/dist/api/api-interface.js +3 -0
  16. package/dist/api/api-interface.js.map +1 -0
  17. package/dist/api/index.d.ts +4 -0
  18. package/dist/api/index.js +22 -0
  19. package/dist/api/index.js.map +1 -0
  20. package/dist/client/api-client-helpers.d.ts +5 -0
  21. package/dist/client/api-client-helpers.js +47 -0
  22. package/dist/client/api-client-helpers.js.map +1 -0
  23. package/dist/client/api-client-pagination-helper.d.ts +15 -0
  24. package/dist/client/api-client-pagination-helper.js +180 -0
  25. package/dist/client/api-client-pagination-helper.js.map +1 -0
  26. package/dist/client/api-fetch-client.d.ts +19 -0
  27. package/dist/client/api-fetch-client.js +129 -0
  28. package/dist/client/api-fetch-client.js.map +1 -0
  29. package/dist/client/index.d.ts +2 -0
  30. package/dist/client/index.js +19 -0
  31. package/dist/client/index.js.map +1 -0
  32. package/dist/domain/domain-interface.d.ts +38 -0
  33. package/dist/domain/domain-interface.js +38 -0
  34. package/dist/domain/domain-interface.js.map +1 -0
  35. package/dist/domain/index.d.ts +1 -0
  36. package/dist/domain/index.js +18 -0
  37. package/dist/domain/index.js.map +1 -0
  38. package/dist/getVersion.d.ts +1 -0
  39. package/dist/getVersion.js +6 -0
  40. package/dist/getVersion.js.map +1 -0
  41. package/dist/index.d.ts +5 -0
  42. package/dist/index.js +22 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/plugins/additional-headers/additional-headers.request.d.ts +11 -0
  45. package/dist/plugins/additional-headers/additional-headers.request.js +21 -0
  46. package/dist/plugins/additional-headers/additional-headers.request.js.map +1 -0
  47. package/dist/plugins/additional-headers/index.d.ts +1 -0
  48. package/dist/plugins/additional-headers/index.js +18 -0
  49. package/dist/plugins/additional-headers/index.js.map +1 -0
  50. package/dist/plugins/api-token/api-token.request.d.ts +6 -0
  51. package/dist/plugins/api-token/api-token.request.js +18 -0
  52. package/dist/plugins/api-token/api-token.request.js.map +1 -0
  53. package/dist/plugins/api-token/index.d.ts +1 -0
  54. package/dist/plugins/api-token/index.js +18 -0
  55. package/dist/plugins/api-token/index.js.map +1 -0
  56. package/dist/plugins/basicAuthentication/basic-authentication.request.d.ts +7 -0
  57. package/dist/plugins/basicAuthentication/basic-authentication.request.js +21 -0
  58. package/dist/plugins/basicAuthentication/basic-authentication.request.js.map +1 -0
  59. package/dist/plugins/basicAuthentication/index.d.ts +1 -0
  60. package/dist/plugins/basicAuthentication/index.js +18 -0
  61. package/dist/plugins/basicAuthentication/index.js.map +1 -0
  62. package/dist/plugins/core/index.d.ts +3 -0
  63. package/dist/plugins/core/index.js +20 -0
  64. package/dist/plugins/core/index.js.map +1 -0
  65. package/dist/plugins/core/plugin.d.ts +14 -0
  66. package/dist/plugins/core/plugin.js +3 -0
  67. package/dist/plugins/core/plugin.js.map +1 -0
  68. package/dist/plugins/core/request-plugin.d.ts +26 -0
  69. package/dist/plugins/core/request-plugin.js +3 -0
  70. package/dist/plugins/core/request-plugin.js.map +1 -0
  71. package/dist/plugins/core/response-plugin.d.ts +33 -0
  72. package/dist/plugins/core/response-plugin.js +3 -0
  73. package/dist/plugins/core/response-plugin.js.map +1 -0
  74. package/dist/plugins/exception/exception.response.d.ts +14 -0
  75. package/dist/plugins/exception/exception.response.js +57 -0
  76. package/dist/plugins/exception/exception.response.js.map +1 -0
  77. package/dist/plugins/exception/index.d.ts +1 -0
  78. package/dist/plugins/exception/index.js +18 -0
  79. package/dist/plugins/exception/index.js.map +1 -0
  80. package/dist/plugins/index.d.ts +8 -0
  81. package/dist/plugins/index.js +25 -0
  82. package/dist/plugins/index.js.map +1 -0
  83. package/dist/plugins/oauth2/index.d.ts +2 -0
  84. package/dist/plugins/oauth2/index.js +19 -0
  85. package/dist/plugins/oauth2/index.js.map +1 -0
  86. package/dist/plugins/oauth2/oauth2-api.d.ts +15 -0
  87. package/dist/plugins/oauth2/oauth2-api.js +26 -0
  88. package/dist/plugins/oauth2/oauth2-api.js.map +1 -0
  89. package/dist/plugins/oauth2/oauth2-token.request.d.ts +15 -0
  90. package/dist/plugins/oauth2/oauth2-token.request.js +76 -0
  91. package/dist/plugins/oauth2/oauth2-token.request.js.map +1 -0
  92. package/dist/plugins/signing/index.d.ts +1 -0
  93. package/dist/plugins/signing/index.js +18 -0
  94. package/dist/plugins/signing/index.js.map +1 -0
  95. package/dist/plugins/signing/signing.request.d.ts +10 -0
  96. package/dist/plugins/signing/signing.request.js +70 -0
  97. package/dist/plugins/signing/signing.request.js.map +1 -0
  98. package/dist/plugins/version/index.d.ts +1 -0
  99. package/dist/plugins/version/index.js +18 -0
  100. package/dist/plugins/version/index.js.map +1 -0
  101. package/dist/plugins/version/version.request.d.ts +4 -0
  102. package/dist/plugins/version/version.request.js +45 -0
  103. package/dist/plugins/version/version.request.js.map +1 -0
  104. package/dist/plugins/x-timestamp/index.d.ts +1 -0
  105. package/dist/plugins/x-timestamp/index.js +18 -0
  106. package/dist/plugins/x-timestamp/index.js.map +1 -0
  107. package/dist/plugins/x-timestamp/x-timestamp.request.d.ts +4 -0
  108. package/dist/plugins/x-timestamp/x-timestamp.request.js +15 -0
  109. package/dist/plugins/x-timestamp/x-timestamp.request.js.map +1 -0
  110. package/dist/utils/index.d.ts +1 -0
  111. package/dist/utils/index.js +18 -0
  112. package/dist/utils/index.js.map +1 -0
  113. package/dist/utils/text-to-hex.d.ts +1 -0
  114. package/dist/utils/text-to-hex.js +13 -0
  115. package/dist/utils/text-to-hex.js.map +1 -0
  116. package/package.json +42 -0
package/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # Sinch Http Client for Node.js
2
+
3
+ This package contains the HTTP client used by the Sinch SDK client. It uses the `fetch` library to send requests. There are 3 folders in this package:
4
+ - api: it defines the interface for an `Api`, an `ApiClient` and for `ApiClientOptions`.
5
+ - client: it contains the `fetch` implementation for the `ApiClient`. This implementation handles the refresh of the JWT for the APIs which support this authentication method.
6
+ - plugins: calling an API can be seen as a straighforward operation as it's "just" about sending an HTTP request to a server and reading the response. And this is was the `ApiClient` does. However, all APIs don't behave the same and this is why we have introduced the request and response plugins:
7
+ - request plugins will modify the request: for the moment, they are all about adding some headers (for authentication, for tracking the SDK usage).
8
+ - response plugins will modify the response, e.g.: response content is checked and transformed into an exception if the content is empty.
9
+
10
+ <span style="color:red; font-weight:bold">Warning:</span>
11
+ **This SDK is currently available for preview purposes only. It should not be used in production environments.**
12
+
13
+ ## Architecture
14
+ TODO: schema
15
+
16
+ ## Installation
17
+
18
+ ### With NPM
19
+
20
+ ```bash
21
+ npm install @sinch/sdk-client
22
+ ```
23
+
24
+ ### With Yarn
25
+
26
+ ```bash
27
+ yarn add @sinch/sdk-client
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ In this section, we'll see how to implement the `Api` interface and how to use the `ApiFetchClient` to call the API endpoint.
33
+
34
+ ### Api interface
35
+
36
+ ```typescript
37
+ export class MyExampleApi implements Api {
38
+ public readonly apiName = 'MyExampleApi';
39
+ public readonly client: ApiClient;
40
+
41
+ constructor(apiClient: ApiClient) {
42
+ this.client = apiClient;
43
+ }
44
+
45
+ public async myApiOperation(): Promise<Response> {
46
+ // Define the API endpoint
47
+ const url = `${this.client.apiClientOptions.basePath}/myDomain`;
48
+ // Build the request options: you can use the method 'prepareOptions' from the apiClient
49
+ // that will apply the request plugins onto the default built options
50
+ const requestOptions: RequestOptions = await this.client.prepareOptions(...);
51
+ // Send the request and apply the response plugins
52
+ return this.client.processCall<Response>({
53
+ url,
54
+ requestOptions,
55
+ apiName: this.apiName,
56
+ });
57
+ }
58
+ }
59
+ ```
60
+
61
+ ### ApiFetchClient instantiation
62
+ ```typescript
63
+ const apiClientOptions: ApiClientOptions = {
64
+ basePath: 'https://my-example-api-server.com',
65
+ requestPlugins: [
66
+ // Add here the plugins that will be executed before the request is sent
67
+ ],
68
+ responsePlugins: [
69
+ // Add here the plugins that will be executed after the response is received and parsed
70
+ ]
71
+ }
72
+
73
+ // Instantiate the API Client
74
+ const apiClient = new ApiFetchClient(apiClientOptions);
75
+ ```
76
+
77
+ ### API class instantiation
78
+
79
+ ```typescript
80
+ // Once the API Client is intantiated, it can be given as a parameter to your API
81
+ const myApi = new MyExampleApi(apiClient);
82
+
83
+ // The API operations can now be invoked
84
+ const myResponse = await myApi.myApiOperation();
85
+ ```
86
+
87
+
88
+ ## Plugins
89
+
90
+ ### Request plugins
91
+
92
+ | Plugin name | Description |
93
+ |----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
94
+ | additional-headers | Adds multiple headers to a request. |
95
+ | api-token | Used for the SMS API with `servicePlanId`. It adds an `Authorization` header with the value of the API token as a `Bearer`. |
96
+ | basic-authentication | Alternative to the `oauth2` plugin: less secure and to be used for prototyping only. It adds an `Authorization` header to the request to perform a `Basic` authentication. |
97
+ | oauth2 | Used by all the APIs that supports the `projectId` authentication scheme. If no token is available, it will make a query to the Sinch authentication server to get a new one, valid for 1 hour. Once a token is available, it will add a `Authorization` header to the request with the value fo the token as `Bearer`. |
98
+ | signing | Used by the `Verification` and `Voice` APIs: it adds an `Authorization` header containing the signature of the request. |
99
+ | version | Add a `user-agent` header containing information such as the SDK version and the Node.js process version.<br>**Added by default to the ApiFetchClient** |
100
+ | x-timestamp | Add the current date in ISO format in the `x-timesstamp` header (used by the `signing` plugin). |
101
+
102
+ ### Response plugins
103
+
104
+ | Plugin name | Description |
105
+ |-------------|-----------------------------------------------------------------------------------------------------------------------------------------------|
106
+ | exception | Check the response content and converts it into an error if empty or if the status is not `ok`.<br>**Added by default to the ApiFetchClient** |
107
+
108
+ ## Contact
109
+ Developer Experience team: [devexp@sinch.com](mailto:devexp@sinch.com)
File without changes
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ // import { ApiTokenRequest, Oauth2TokenRequest, SigningRequest, XTimestampRequest } from '../plugins';
3
+ // // import { ApiClientOptions } from './api-client-options';
4
+ //
5
+ // export const buildApiClientOptionsForProjectId = (
6
+ // projectId: string,
7
+ // keyId: string,
8
+ // keySecret: string,
9
+ // ) => {
10
+ // return {
11
+ // projectId,
12
+ // requestPlugins: [new Oauth2TokenRequest(keyId, keySecret)],
13
+ // useServicePlanId: false,
14
+ // };
15
+ // };
16
+ //
17
+ // export const buildApiClientOptionForServicePlanId = (
18
+ // servicePlanId: string,
19
+ // apiToken: string,
20
+ // ) => {
21
+ // return {
22
+ // projectId: servicePlanId,
23
+ // requestPlugins: [new ApiTokenRequest(apiToken)],
24
+ // useServicePlanId: true,
25
+ // };
26
+ // };
27
+ //
28
+ // export const buildApiClientOptionForApplication = (
29
+ // applicationKey: string,
30
+ // applicationSecret: string,
31
+ // ) => {
32
+ // return {
33
+ // requestPlugins: [
34
+ // new XTimestampRequest(),
35
+ // new SigningRequest(applicationKey, applicationSecret),
36
+ // ],
37
+ // };
38
+ // };
39
+ //# sourceMappingURL=api-client-options-helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client-options-helper.js","sourceRoot":"","sources":["../../src/api/api-client-options-helper.ts"],"names":[],"mappings":";AAAA,uGAAuG;AACvG,8DAA8D;AAC9D,EAAE;AACF,qDAAqD;AACrD,uBAAuB;AACvB,mBAAmB;AACnB,uBAAuB;AACvB,SAAS;AACT,aAAa;AACb,iBAAiB;AACjB,kEAAkE;AAClE,+BAA+B;AAC/B,OAAO;AACP,KAAK;AACL,EAAE;AACF,yDAAyD;AACzD,2BAA2B;AAC3B,sBAAsB;AACtB,SAAS;AACT,aAAa;AACb,gCAAgC;AAChC,uDAAuD;AACvD,8BAA8B;AAC9B,OAAO;AACP,KAAK;AACL,EAAE;AACF,sDAAsD;AACtD,4BAA4B;AAC5B,+BAA+B;AAC/B,SAAS;AACT,aAAa;AACb,wBAAwB;AACxB,iCAAiC;AACjC,+DAA+D;AAC/D,SAAS;AACT,OAAO;AACP,KAAK"}
@@ -0,0 +1,28 @@
1
+ import { RequestPlugin, ResponsePlugin } from '../plugins';
2
+ interface BaseApiClientOptions {
3
+ /**
4
+ * ID of the umbrella project containing the access keys
5
+ * Found on your <a href=\"https://dashboard.sinch.com/settings/project-management\" target=\"_blank\">Sinch Customer Dashboard</a>.
6
+ */
7
+ projectId: string;
8
+ /** Base path of the API server */
9
+ basePath: string;
10
+ /**
11
+ * List of plugins to apply to the request before calling the API
12
+ * @default [new Oauth2RequestPlugin()]
13
+ */
14
+ requestPlugins: RequestPlugin[];
15
+ /**
16
+ * List of plugins to apply to the response of the API call
17
+ * @default [new ExceptionResponse()]
18
+ */
19
+ responsePlugins: ResponsePlugin<any>[];
20
+ /** Some APIs have not been migrated fully to the 'projectId' structure and use another URL for their authentication
21
+ * This flag indicates the API is not using the 'projectId'
22
+ * @default false
23
+ */
24
+ useServicePlanId?: boolean;
25
+ }
26
+ export interface ApiClientOptions extends Partial<BaseApiClientOptions> {
27
+ }
28
+ export {};
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=api-client-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client-options.js","sourceRoot":"","sources":["../../src/api/api-client-options.ts"],"names":[],"mappings":""}
@@ -0,0 +1,104 @@
1
+ import { RequestBody, RequestOptions } from '../plugins';
2
+ import { ApiClientOptions } from './api-client-options';
3
+ export declare enum PaginationEnum {
4
+ NONE = 0,
5
+ TOKEN = 1,
6
+ PAGE = 2
7
+ }
8
+ export interface ApiListPromise<T> extends Promise<PageResult<T>>, AsyncIterableIterator<T> {
9
+ }
10
+ export type PageResult<T> = {
11
+ data: Array<T>;
12
+ hasNextPage: boolean;
13
+ nextPageValue: string;
14
+ nextPage: () => ApiListPromise<T>;
15
+ };
16
+ export type AutoPaginationMethods<T> = {
17
+ next: () => Promise<IteratorResult<T>>;
18
+ return: () => void;
19
+ [Symbol.asyncIterator]: () => AutoPaginationMethods<T>;
20
+ };
21
+ export interface ApiCallParameters {
22
+ url: string;
23
+ requestOptions: RequestOptions;
24
+ apiName: string;
25
+ operationId: string;
26
+ circuitBreaker?: number;
27
+ }
28
+ export interface ApiCallParametersWithPagination extends ApiCallParameters {
29
+ pagination: PaginationEnum;
30
+ dataKey: string;
31
+ requestOptionsPromise?: Promise<RequestOptions>;
32
+ }
33
+ export interface PaginatedApiProperties {
34
+ /** Type of pagination: can be TOKEN or PAGE */
35
+ pagination: PaginationEnum;
36
+ /** Name of the API - for logging purposes */
37
+ apiName: string;
38
+ /** Operation identifier - for logging purposes */
39
+ operationId: string;
40
+ /** Name of the property holding the array of paginated data */
41
+ dataKey: string;
42
+ }
43
+ /**
44
+ * API Client used to call the server
45
+ */
46
+ export declare class ApiClient {
47
+ /** Options for the API */
48
+ apiClientOptions: ApiClientOptions;
49
+ constructor(options: ApiClientOptions);
50
+ /**
51
+ * Returns a map containing the query parameters based on the provided data and names.
52
+ *
53
+ * @param {Object} data - The data object from which to extract query parameters.
54
+ * @param {Array.<string>} names - An array of keys (property names) to extract from the data object.
55
+ * @return {Object} A map containing the extracted query parameters.
56
+ */
57
+ extractQueryParams<T extends {
58
+ [key: string]: any;
59
+ }>(data: T, names: (keyof T)[]): {
60
+ [p in keyof T]: string;
61
+ };
62
+ /**
63
+ * Asynchronously prepares options for an HTTP request.
64
+ *
65
+ * @param {string} url - The URL for the HTTP request.
66
+ * @param {string} method - The HTTP method for the request (e.g., 'GET', 'POST').
67
+ * @param {Object.<string, (string | undefined)>} queryParams - An object representing query parameters.
68
+ * @param {Object.<string, (string | undefined)>} headers - An object representing headers.
69
+ * @param {RequestBody} [body] - The request body, if applicable.
70
+ * @param {string} [path] - An optional path for the request.
71
+ * @return {Promise<RequestOptions>} A promise that resolves to the prepared options for the HTTP request.
72
+ */
73
+ prepareOptions(url: string, method: string, queryParams: {
74
+ [key: string]: string | undefined;
75
+ }, headers: {
76
+ [key: string]: string | undefined;
77
+ }, body?: RequestBody, path?: string): Promise<RequestOptions>;
78
+ /**
79
+ * Prepares the url to be called by appending query parameters.
80
+ *
81
+ * @param {string} url - The base url to be used.
82
+ * @param {Object.<string, string|undefined>} queryParameters - Key-value pair with the parameters. If the value is undefined, the key is dropped.
83
+ * @return {string} The prepared URL as a string.
84
+ */
85
+ prepareUrl(url: string, queryParameters?: {
86
+ [key: string]: string | undefined;
87
+ }): string;
88
+ /**
89
+ * Process HTTP call
90
+ * @abstract
91
+ * @template T
92
+ * @param {ApiCallParameters} _httpCallParameters - Parameters for the HTTP call.
93
+ * @return {Promise<T>} A promise that resolves to the result of the HTTP call.
94
+ */
95
+ processCall<T>(_httpCallParameters: ApiCallParameters): Promise<T>;
96
+ /**
97
+ * Process HTTP call
98
+ * @abstract
99
+ * @template T
100
+ * @param {ApiCallParametersWithPagination} _httpCallParameters - Parameters for the HTTP call.
101
+ * @return {Promise<T>} A promise that resolves to the result of the HTTP call.
102
+ */
103
+ processCallWithPagination<T>(_httpCallParameters: ApiCallParametersWithPagination): Promise<PageResult<T>>;
104
+ }
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ApiClient = exports.PaginationEnum = void 0;
4
+ const node_fetch_1 = require("node-fetch");
5
+ var PaginationEnum;
6
+ (function (PaginationEnum) {
7
+ PaginationEnum[PaginationEnum["NONE"] = 0] = "NONE";
8
+ PaginationEnum[PaginationEnum["TOKEN"] = 1] = "TOKEN";
9
+ PaginationEnum[PaginationEnum["PAGE"] = 2] = "PAGE";
10
+ })(PaginationEnum || (exports.PaginationEnum = PaginationEnum = {}));
11
+ /**
12
+ * API Client used to call the server
13
+ */
14
+ class ApiClient {
15
+ constructor(options) {
16
+ this.apiClientOptions = options;
17
+ }
18
+ /**
19
+ * Returns a map containing the query parameters based on the provided data and names.
20
+ *
21
+ * @param {Object} data - The data object from which to extract query parameters.
22
+ * @param {Array.<string>} names - An array of keys (property names) to extract from the data object.
23
+ * @return {Object} A map containing the extracted query parameters.
24
+ */
25
+ extractQueryParams(data, names) {
26
+ return names
27
+ .filter((name) => typeof data[name] !== 'undefined' && data[name] !== null)
28
+ .reduce((acc, name) => {
29
+ const prop = data[name];
30
+ acc[name] = typeof prop.toJSON === 'function'
31
+ ? prop.toJSON()
32
+ : Array.isArray(prop) ? prop.join(';') : prop.toString();
33
+ return acc;
34
+ }, {});
35
+ }
36
+ /**
37
+ * Asynchronously prepares options for an HTTP request.
38
+ *
39
+ * @param {string} url - The URL for the HTTP request.
40
+ * @param {string} method - The HTTP method for the request (e.g., 'GET', 'POST').
41
+ * @param {Object.<string, (string | undefined)>} queryParams - An object representing query parameters.
42
+ * @param {Object.<string, (string | undefined)>} headers - An object representing headers.
43
+ * @param {RequestBody} [body] - The request body, if applicable.
44
+ * @param {string} [path] - An optional path for the request.
45
+ * @return {Promise<RequestOptions>} A promise that resolves to the prepared options for the HTTP request.
46
+ */
47
+ async prepareOptions(url, method, queryParams, headers, body, path) {
48
+ const options = {
49
+ method,
50
+ headers: new node_fetch_1.Headers(filterUndefinedValues(headers)),
51
+ body,
52
+ queryParams: filterUndefinedValues(queryParams),
53
+ basePath: url,
54
+ path,
55
+ };
56
+ let opts = options;
57
+ if (this.apiClientOptions.requestPlugins) {
58
+ for (const plugin of this.apiClientOptions.requestPlugins) {
59
+ opts = await plugin.load().transform(opts);
60
+ }
61
+ }
62
+ return opts;
63
+ }
64
+ ;
65
+ /**
66
+ * Prepares the url to be called by appending query parameters.
67
+ *
68
+ * @param {string} url - The base url to be used.
69
+ * @param {Object.<string, string|undefined>} queryParameters - Key-value pair with the parameters. If the value is undefined, the key is dropped.
70
+ * @return {string} The prepared URL as a string.
71
+ */
72
+ prepareUrl(url, queryParameters = {}) {
73
+ const queryPart = Object.keys(queryParameters)
74
+ .filter((name) => typeof queryParameters[name] !== 'undefined')
75
+ .map((name) => `${name}=${queryParameters[name]}`)
76
+ .join('&');
77
+ const paramsPrefix = url.indexOf('?') > -1 ? '&' : '?';
78
+ return url + (!queryPart ? '' : paramsPrefix + queryPart);
79
+ }
80
+ /**
81
+ * Process HTTP call
82
+ * @abstract
83
+ * @template T
84
+ * @param {ApiCallParameters} _httpCallParameters - Parameters for the HTTP call.
85
+ * @return {Promise<T>} A promise that resolves to the result of the HTTP call.
86
+ */
87
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
88
+ processCall(_httpCallParameters) {
89
+ throw new Error('Abstract method must be implemented');
90
+ }
91
+ /**
92
+ * Process HTTP call
93
+ * @abstract
94
+ * @template T
95
+ * @param {ApiCallParametersWithPagination} _httpCallParameters - Parameters for the HTTP call.
96
+ * @return {Promise<T>} A promise that resolves to the result of the HTTP call.
97
+ */
98
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
99
+ processCallWithPagination(_httpCallParameters) {
100
+ throw new Error('Abstract method must be implemented');
101
+ }
102
+ }
103
+ exports.ApiClient = ApiClient;
104
+ // ----- INTERNAL ------ \\
105
+ /**
106
+ * Returns a filtered JSON object, removing all the undefined values.
107
+ *
108
+ * @param {Object.<string, string|undefined>} object - The JSON object to filter.
109
+ * @return {Object.<string, string>} An object without undefined values.
110
+ */
111
+ function filterUndefinedValues(object) {
112
+ return Object.keys(object)
113
+ .filter((objectKey) => typeof object[objectKey] !== 'undefined')
114
+ .reduce((acc, objectKey) => {
115
+ acc[objectKey] = object[objectKey];
116
+ return acc;
117
+ }, {});
118
+ }
119
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/api/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Generic error context
3
+ */
4
+ export interface ErrorContext {
5
+ /** Api name */
6
+ apiName?: string;
7
+ /** Operation ID */
8
+ operationId?: string;
9
+ /** Base URL */
10
+ url?: string;
11
+ /** Origin domain initiating the call */
12
+ origin?: string | null;
13
+ }
14
+ /**
15
+ * Generic error class
16
+ */
17
+ export declare class GenericError extends Error {
18
+ constructor(message: string, errorContext: ErrorContext);
19
+ private static formatUrl;
20
+ }
21
+ /**
22
+ * Request failed error class
23
+ */
24
+ export declare class RequestFailedError<T> extends GenericError {
25
+ /**
26
+ * Request status code
27
+ */
28
+ statusCode: number;
29
+ /**
30
+ * Data decoded from the response body
31
+ */
32
+ data?: T;
33
+ constructor(message: string, statusCode: number, errorContext: ErrorContext, data?: T);
34
+ }
35
+ /**
36
+ * Empty response error class
37
+ */
38
+ export declare class EmptyResponseError<T> extends GenericError {
39
+ /**
40
+ * Data decoded from the response body
41
+ */
42
+ data?: T;
43
+ constructor(message: string, errorContext: ErrorContext, data?: T);
44
+ }
45
+ /**
46
+ * Response parse error class
47
+ */
48
+ export declare class ResponseJSONParseError extends RequestFailedError<string> {
49
+ constructor(message: string, httpStatus: number, errorContext: ErrorContext, bodyContent?: string);
50
+ }
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ResponseJSONParseError = exports.EmptyResponseError = exports.RequestFailedError = exports.GenericError = void 0;
4
+ /**
5
+ * Generic error class
6
+ */
7
+ class GenericError extends Error {
8
+ constructor(message, errorContext) {
9
+ const baseUrl = GenericError.formatUrl(errorContext.url);
10
+ const origin = GenericError.formatUrl(errorContext.origin);
11
+ super(`[SDK] [apiName: ${errorContext.apiName || 'unknown'}]
12
+ [operationId: ${errorContext.operationId || 'unknown'}]
13
+ [baseUrl: ${baseUrl}] [origin: ${origin}] [errorType: SDK] ${message}`);
14
+ }
15
+ static formatUrl(url) {
16
+ const httpRegexp = /^https?:\/\//;
17
+ return url ? url.replace(httpRegexp, '') : 'unknown';
18
+ }
19
+ }
20
+ exports.GenericError = GenericError;
21
+ /**
22
+ * Request failed error class
23
+ */
24
+ class RequestFailedError extends GenericError {
25
+ constructor(message, statusCode, errorContext, data) {
26
+ super(`[status: ${statusCode}] ${message}`, errorContext);
27
+ this.statusCode = statusCode;
28
+ this.data = data;
29
+ }
30
+ }
31
+ exports.RequestFailedError = RequestFailedError;
32
+ /**
33
+ * Empty response error class
34
+ */
35
+ class EmptyResponseError extends GenericError {
36
+ constructor(message, errorContext, data) {
37
+ super(`[Empty response] ${message}`, errorContext);
38
+ this.data = data;
39
+ }
40
+ }
41
+ exports.EmptyResponseError = EmptyResponseError;
42
+ /**
43
+ * Response parse error class
44
+ */
45
+ class ResponseJSONParseError extends RequestFailedError {
46
+ constructor(message, httpStatus, errorContext, bodyContent) {
47
+ super(`[Response JSON parse error] ${message}`, httpStatus, errorContext, bodyContent);
48
+ }
49
+ }
50
+ exports.ResponseJSONParseError = ResponseJSONParseError;
51
+ //# sourceMappingURL=api-errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-errors.js","sourceRoot":"","sources":["../../src/api/api-errors.ts"],"names":[],"mappings":";;;AAcA;;GAEG;AACH,MAAa,YAAa,SAAQ,KAAK;IACrC,YAAY,OAAe,EAAE,YAA0B;QACrD,MAAM,OAAO,GAAG,YAAY,CAAC,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QACzD,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAC3D,KAAK,CACH,mBAAmB,YAAY,CAAC,OAAO,IAAI,SAAS;wBAClC,YAAY,CAAC,WAAW,IAAI,SAAS;oBACzC,OAAO,cAAc,MAAM,sBAAsB,OAAO,EAAE,CACzE,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,SAAS,CAAC,GAA8B;QACrD,MAAM,UAAU,GAAG,cAAc,CAAC;QAClC,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvD,CAAC;CAEF;AAhBD,oCAgBC;AAED;;GAEG;AACH,MAAa,kBAAsB,SAAQ,YAAY;IAWrD,YACE,OAAe,EACf,UAAkB,EAClB,YAA0B,EAC1B,IAAQ;QAER,KAAK,CAAC,YAAY,UAAU,KAAK,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;QAC1D,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AArBD,gDAqBC;AAED;;GAEG;AACH,MAAa,kBAAsB,SAAQ,YAAY;IAMrD,YAAY,OAAe,EAAE,YAA0B,EAAE,IAAQ;QAC/D,KAAK,CAAC,oBAAoB,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAVD,gDAUC;AAED;;GAEG;AACH,MAAa,sBAAuB,SAAQ,kBAA0B;IACpE,YACE,OAAe,EACf,UAAkB,EAClB,YAA0B,EAC1B,WAAoB;QAEpB,KAAK,CACH,+BAA+B,OAAO,EAAE,EACxC,UAAU,EACV,YAAY,EACZ,WAAW,CACZ,CAAC;IACJ,CAAC;CACF;AAdD,wDAcC"}
@@ -0,0 +1,8 @@
1
+ import { ApiClient } from './api-client';
2
+ /** API interface */
3
+ export interface Api {
4
+ /** API name */
5
+ apiName: string;
6
+ /** API Client used to process the calls to the API */
7
+ client?: ApiClient;
8
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=api-interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-interface.js","sourceRoot":"","sources":["../../src/api/api-interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ export * from './api-client-options';
2
+ export * from './api-client';
3
+ export * from './api-errors';
4
+ export * from './api-interface';
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./api-client-options"), exports);
18
+ // export * from './api-client-options-helper';
19
+ __exportStar(require("./api-client"), exports);
20
+ __exportStar(require("./api-errors"), exports);
21
+ __exportStar(require("./api-interface"), exports);
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,uDAAqC;AACrC,+CAA+C;AAC/C,+CAA6B;AAC7B,+CAA6B;AAC7B,kDAAgC"}
@@ -0,0 +1,5 @@
1
+ import { RequestOptions, RequestPlugin } from '../plugins';
2
+ import { ApiCallParameters, ApiCallParametersWithPagination, ErrorContext } from '../api';
3
+ export declare const manageExpiredToken: (apiCallParameters: ApiCallParameters | ApiCallParametersWithPagination, errorContext: ErrorContext, requestPlugins: RequestPlugin[] | undefined, requestOptions: RequestOptions, callback: (props: any) => Promise<any>) => Promise<any>;
4
+ export declare function buildErrorContext(apiCallParameters: ApiCallParameters, origin: string | null): ErrorContext;
5
+ export declare function invalidateAndRegenerateJwt(requestPlugins: RequestPlugin[] | undefined, options: RequestOptions, errorContext: ErrorContext): Promise<RequestOptions>;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.invalidateAndRegenerateJwt = exports.buildErrorContext = exports.manageExpiredToken = void 0;
4
+ const plugins_1 = require("../plugins");
5
+ const api_1 = require("../api");
6
+ const manageExpiredToken = async (apiCallParameters, errorContext, requestPlugins, requestOptions, callback) => {
7
+ // Use the circuitBreaker variable to try to regenerate a valid JWT only 3 times
8
+ if (!apiCallParameters.circuitBreaker) {
9
+ apiCallParameters.circuitBreaker = 1;
10
+ }
11
+ else {
12
+ apiCallParameters.circuitBreaker++;
13
+ // Check the circuitBreaker value: if greater than 3, then we stop and throw
14
+ if (apiCallParameters.circuitBreaker >= 3) {
15
+ throw new api_1.GenericError('Tried to generate a new JWT with no success', errorContext);
16
+ }
17
+ }
18
+ const optionsWithNewJwt = await invalidateAndRegenerateJwt(requestPlugins, requestOptions, errorContext);
19
+ const newApiCallParameters = {
20
+ ...apiCallParameters,
21
+ requestOptions: optionsWithNewJwt,
22
+ };
23
+ return callback(newApiCallParameters);
24
+ };
25
+ exports.manageExpiredToken = manageExpiredToken;
26
+ function buildErrorContext(apiCallParameters, origin) {
27
+ return {
28
+ apiName: apiCallParameters.apiName,
29
+ operationId: apiCallParameters.operationId,
30
+ url: apiCallParameters.url,
31
+ origin,
32
+ };
33
+ }
34
+ exports.buildErrorContext = buildErrorContext;
35
+ async function invalidateAndRegenerateJwt(requestPlugins, options, errorContext) {
36
+ const oauth2Plugin = requestPlugins?.find((plugin) => plugin instanceof plugins_1.Oauth2TokenRequest);
37
+ if (oauth2Plugin) {
38
+ oauth2Plugin.invalidateToken();
39
+ return oauth2Plugin.load().transform(options);
40
+ }
41
+ else {
42
+ const errorMessage = 'Trying to invalidate an expired JWT while the Oauth2Token plugin is not registered to the API client';
43
+ throw new api_1.GenericError(errorMessage, errorContext);
44
+ }
45
+ }
46
+ exports.invalidateAndRegenerateJwt = invalidateAndRegenerateJwt;
47
+ //# sourceMappingURL=api-client-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client-helpers.js","sourceRoot":"","sources":["../../src/client/api-client-helpers.ts"],"names":[],"mappings":";;;AAAA,wCAIoB;AACpB,gCAAwG;AAEjG,MAAM,kBAAkB,GAAG,KAAK,EACrC,iBAAsE,EACtE,YAA0B,EAC1B,cAA2C,EAC3C,cAA8B,EAC9B,QAAsC,EACtC,EAAE;IACF,gFAAgF;IAChF,IAAI,CAAC,iBAAiB,CAAC,cAAc,EAAE,CAAC;QACtC,iBAAiB,CAAC,cAAc,GAAG,CAAC,CAAC;IACvC,CAAC;SAAM,CAAC;QACN,iBAAiB,CAAC,cAAc,EAAE,CAAC;QACnC,4EAA4E;QAC5E,IAAI,iBAAiB,CAAC,cAAc,IAAI,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,kBAAY,CACpB,6CAA6C,EAC7C,YAAY,CACb,CAAC;QACJ,CAAC;IACH,CAAC;IACD,MAAM,iBAAiB,GAAG,MAAM,0BAA0B,CAAC,cAAc,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;IACzG,MAAM,oBAAoB,GAAG;QAC3B,GAAG,iBAAiB;QACpB,cAAc,EAAE,iBAAiB;KAClC,CAAC;IACF,OAAO,QAAQ,CAAC,oBAAoB,CAAC,CAAC;AACxC,CAAC,CAAC;AA1BW,QAAA,kBAAkB,sBA0B7B;AAEF,SAAgB,iBAAiB,CAC/B,iBAAoC,EACpC,MAAqB;IAErB,OAAO;QACL,OAAO,EAAE,iBAAiB,CAAC,OAAO;QAClC,WAAW,EAAE,iBAAiB,CAAC,WAAW;QAC1C,GAAG,EAAE,iBAAiB,CAAC,GAAG;QAC1B,MAAM;KACP,CAAC;AACJ,CAAC;AAVD,8CAUC;AAEM,KAAK,UAAU,0BAA0B,CAC9C,cAA2C,EAC3C,OAAuB,EACvB,YAA0B;IAE1B,MAAM,YAAY,GAAG,cAAc,EAAE,IAAI,CACvC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,YAAY,4BAAkB,CAC3B,CAAC;IACxB,IAAI,YAAY,EAAE,CAAC;QACjB,YAAY,CAAC,eAAe,EAAE,CAAC;QAC/B,OAAO,YAAY,CAAC,IAAI,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC;SAAM,CAAC;QACN,MAAM,YAAY,GACd,sGAAsG,CAAC;QAC3G,MAAM,IAAI,kBAAY,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAhBD,gEAgBC"}