@sectester/core 0.35.3 → 0.36.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.
Files changed (82) hide show
  1. package/README.md +54 -67
  2. package/package.json +3 -6
  3. package/src/DefaultProjects.d.ts +7 -0
  4. package/src/DefaultProjects.js +28 -0
  5. package/src/DefaultProjects.js.map +1 -0
  6. package/src/Projects.d.ts +8 -0
  7. package/src/Projects.js +5 -0
  8. package/src/Projects.js.map +1 -0
  9. package/src/api/ApiClient.d.ts +4 -0
  10. package/src/api/ApiClient.js +5 -0
  11. package/src/api/ApiClient.js.map +1 -0
  12. package/src/api/FetchApiClient.d.ts +21 -0
  13. package/src/api/FetchApiClient.js +95 -0
  14. package/src/api/FetchApiClient.js.map +1 -0
  15. package/src/api/RateLimiter.d.ts +16 -0
  16. package/src/api/RateLimiter.js +72 -0
  17. package/src/api/RateLimiter.js.map +1 -0
  18. package/src/api/RetryHandler.d.ts +22 -0
  19. package/src/api/RetryHandler.js +74 -0
  20. package/src/api/RetryHandler.js.map +1 -0
  21. package/src/api/index.d.ts +4 -0
  22. package/src/api/index.js +8 -0
  23. package/src/api/index.js.map +1 -0
  24. package/src/configuration/Configuration.d.ts +10 -8
  25. package/src/configuration/Configuration.js +55 -19
  26. package/src/configuration/Configuration.js.map +1 -1
  27. package/src/exceptions/ApiError.d.ts +5 -0
  28. package/src/exceptions/ApiError.js +12 -0
  29. package/src/exceptions/ApiError.js.map +1 -0
  30. package/src/exceptions/RateLimitError.d.ts +5 -0
  31. package/src/exceptions/RateLimitError.js +12 -0
  32. package/src/exceptions/RateLimitError.js.map +1 -0
  33. package/src/exceptions/index.d.ts +2 -1
  34. package/src/exceptions/index.js +2 -1
  35. package/src/exceptions/index.js.map +1 -1
  36. package/src/index.d.ts +4 -3
  37. package/src/index.js +4 -4
  38. package/src/index.js.map +1 -1
  39. package/src/register.js +7 -17
  40. package/src/register.js.map +1 -1
  41. package/src/utils/index.d.ts +0 -2
  42. package/src/utils/index.js +0 -2
  43. package/src/utils/index.js.map +1 -1
  44. package/src/commands/Command.d.ts +0 -14
  45. package/src/commands/Command.js +0 -23
  46. package/src/commands/Command.js.map +0 -1
  47. package/src/commands/CommandDispatcher.d.ts +0 -5
  48. package/src/commands/CommandDispatcher.js +0 -5
  49. package/src/commands/CommandDispatcher.js.map +0 -1
  50. package/src/commands/HttpRequest.d.ts +0 -19
  51. package/src/commands/HttpRequest.js +0 -20
  52. package/src/commands/HttpRequest.js.map +0 -1
  53. package/src/commands/Message.d.ts +0 -7
  54. package/src/commands/Message.js +0 -15
  55. package/src/commands/Message.js.map +0 -1
  56. package/src/commands/RetryStartegy.d.ts +0 -4
  57. package/src/commands/RetryStartegy.js +0 -5
  58. package/src/commands/RetryStartegy.js.map +0 -1
  59. package/src/commands/index.d.ts +0 -5
  60. package/src/commands/index.js +0 -9
  61. package/src/commands/index.js.map +0 -1
  62. package/src/dispatchers/ExponentialBackoffRetryStrategy.d.ts +0 -13
  63. package/src/dispatchers/ExponentialBackoffRetryStrategy.js +0 -65
  64. package/src/dispatchers/ExponentialBackoffRetryStrategy.js.map +0 -1
  65. package/src/dispatchers/HttpCommandDispatcher.d.ts +0 -14
  66. package/src/dispatchers/HttpCommandDispatcher.js +0 -95
  67. package/src/dispatchers/HttpCommandDispatcher.js.map +0 -1
  68. package/src/dispatchers/HttpCommandDispatcherConfig.d.ts +0 -12
  69. package/src/dispatchers/HttpCommandDispatcherConfig.js +0 -5
  70. package/src/dispatchers/HttpCommandDispatcherConfig.js.map +0 -1
  71. package/src/dispatchers/index.d.ts +0 -3
  72. package/src/dispatchers/index.js +0 -7
  73. package/src/dispatchers/index.js.map +0 -1
  74. package/src/exceptions/HttpCommandError.d.ts +0 -9
  75. package/src/exceptions/HttpCommandError.js +0 -17
  76. package/src/exceptions/HttpCommandError.js.map +0 -1
  77. package/src/utils/delay.d.ts +0 -1
  78. package/src/utils/delay.js +0 -7
  79. package/src/utils/delay.js.map +0 -1
  80. package/src/utils/get-type-name.d.ts +0 -6
  81. package/src/utils/get-type-name.js +0 -11
  82. package/src/utils/get-type-name.js.map +0 -1
package/README.md CHANGED
@@ -23,7 +23,8 @@ First, you need to generate a new instance of `Configuration`.
23
23
  import { Configuration } from '@sectester/core';
24
24
 
25
25
  const config = new Configuration({
26
- hostname: 'app.neuralegion.com',
26
+ hostname: 'app.brightsec.com',
27
+ projectId: 'your project ID',
27
28
  credentials: {
28
29
  token: 'your API key'
29
30
  }
@@ -43,6 +44,7 @@ Configuration can be customized using the following options:
43
44
  ```ts
44
45
  export interface ConfigurationOptions {
45
46
  hostname: string;
47
+ projectId: string;
46
48
  credentials?: Credentials;
47
49
  logLevel?: LogLevel;
48
50
  credentialProviders?: CredentialProvider[];
@@ -68,10 +70,31 @@ Set the application name (domain name), that is used to establish connection wit
68
70
  import { Configuration } from '@sectester/core';
69
71
 
70
72
  const config = new Configuration({
71
- hostname: 'app.neuralegion.com'
73
+ hostname: 'app.brightsec.com'
72
74
  });
73
75
  ```
74
76
 
77
+ #### projectId
78
+
79
+ - type: `string`
80
+
81
+ Set ID of the project you want to work with.
82
+
83
+ ```ts
84
+ import { Configuration } from '@sectester/core';
85
+
86
+ const config = new Configuration({
87
+ // ...
88
+ projectId: 'your project ID'
89
+ });
90
+ ```
91
+
92
+ > [!TIP]
93
+ > The project ID can be found in the URL of the project page. For example, in the URL `https://app.brightsec.com/projects/1234`, the project ID is `1234`. We recommend using the dedicated project ID for each application.
94
+
95
+ > [!WARNING]
96
+ > If you omit the `projectId` parameter, we will use the default project ID. This is not recommended ecpesially if you have multiple projects.
97
+
75
98
  #### logLevel
76
99
 
77
100
  - type: `LogLevel`
@@ -128,78 +151,42 @@ const config = new Configuration({
128
151
  });
129
152
  ```
130
153
 
131
- ### Messages
132
-
133
- Message is used for syncing state between SDK, application and/or external services.
134
- This functionality is done by sending messages outside using a concrete implementation of `Dispatcher`.
154
+ ### ApiClient
135
155
 
136
- Depending on the type of derived class from the `Message`, it might be addressed to only one consumer or have typically multiple consumers as well.
137
- When a message is sent to multiple consumers, the appropriate event handler in each consumer handles the message.
138
-
139
- The `Message` is a data-holding class, but it implements a [Visitor pattern](https://en.wikipedia.org/wiki/Visitor_pattern#:~:text=In%20object%2Doriented%20programming%20and,structures%20without%20modifying%20the%20structures.)
140
- to allow clients to perform operations on it using a visitor class (see `Dispatcher`) without modifying the source.
141
-
142
- For instance, you can dispatch a message in a way that is more approach you or convenient from the client's perspective.
156
+ The `ApiClient` interface and its implementation `FetchApiClient` provide a robust way to handle HTTP requests with built-in retry logic, rate limiting, and error handling.
143
157
 
144
158
  ```ts
145
- import { CommandDispatcher, Command } from '@sectester/core';
146
- import { container } from 'tsyringe';
159
+ import { FetchApiClient } from '@sectester/core';
147
160
 
148
- const dispatcher = container.resolve(CommandDispatcher);
149
-
150
- interface Payload {
151
- status: 'connected' | 'disconnected';
152
- }
153
-
154
- class Ping extends Command<Payload, undefined> {
155
- constructor(payload: Payload) {
156
- super(payload);
157
- }
158
- }
159
-
160
- // using a visitor pattern
161
- await new Ping({ status: 'connected' }).execute(dispatcher);
162
-
163
- // or directly
164
- await dispatcher.execute(new Ping({ status: 'disconnected' }));
165
- ```
166
-
167
- Each message have a correlation ID to ensure atomicity. The regular UUID is used, but you might also want to consider other options.
168
-
169
- ### Request-response
170
-
171
- The request-response message (aka `Command`) style is useful when you need to exchange messages between various external services.
172
- Using `Command` you can easily ensure that the service has actually received the message and sent a response back.
173
-
174
- To create an instance of `Command` use the abstract class as follows:
175
-
176
- ```ts
177
- import { Command } from '@sectester/core';
178
-
179
- interface RequestOptions {
180
- url: string;
181
- method: 'GET' | 'POST' | 'PUT' | 'DELETE';
182
- headers?: Record<string, string>;
183
- body?: string;
184
- }
161
+ const client = new FetchApiClient({
162
+ baseUrl: 'https://app.neuralegion.com',
163
+ apiKey: 'your-api-key',
164
+ timeout: 5000 // optional, defaults to 5000ms
165
+ });
185
166
 
186
- class Request<R = unknown> extends Command<RequestOptions, R> {
187
- constructor(options: RequestOptions) {
188
- super(options);
189
- }
190
- }
167
+ // Make a request
168
+ const response = await client.request('/api/v1/scans');
191
169
  ```
192
170
 
193
- To adjust its behavior you can use next options:
194
-
195
- | Option | Description |
196
- | :------------- | -------------------------------------------------------------------------------------------- |
197
- | `payload` | Message that we want to transmit to the remote service. |
198
- | `expectReply` | Indicates whether to wait for a reply. By default `true`. |
199
- | `ttl` | Period of time that command should be handled before being discarded. By default `10000` ms. |
200
- | `type` | The name of a command. By default, it is the name of specific class. |
201
- | `corelationId` | Used to ensure atomicity. By default, random UUID. |
202
- | `createdAt` | The exact date and time the command was created. |
171
+ The `FetchApiClient` includes the following features:
172
+
173
+ - Automatic retry for idempotent requests (GET, HEAD, PUT, DELETE, OPTIONS, TRACE)
174
+ - Rate limiting handling with automatic retry based on 'Retry-After' header
175
+ - Configurable timeout
176
+ - API key authentication
177
+ - Automatic handling of redirects (status 409)
178
+ - JSON content type by default
179
+
180
+ The client can be configured using the following options:
181
+
182
+ | Option | Type | Default | Description |
183
+ | ------------ | -------------------------------------------- | ------------------------------------------------------------ | --------------------------------------- |
184
+ | baseUrl | string | - | Base URL for all API requests |
185
+ | apiKey | string | - | API key for authentication |
186
+ | apiKeyPrefix | string | 'Api-Key' | Prefix used in the Authorization header |
187
+ | timeout | number | 5000 | Request timeout in milliseconds |
188
+ | userAgent | string | sectester-js/<version> | User agent string |
189
+ | retry | [RetryOptions](./src/api/RetryHandler.ts#L5) | See [FetchApiClient.ts](./src/api/FetchApiClient.ts#L32-L35) | Retry options for the client |
203
190
 
204
191
  ## License
205
192
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sectester/core",
3
- "version": "0.35.3",
3
+ "version": "0.36.1",
4
4
  "description": "The core package can be used to obtain a config including credentials from different sources, and provide a simplified abstraction to handle events and commands.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,18 +33,15 @@
33
33
  "brightsec"
34
34
  ],
35
35
  "secTester": {
36
- "name": "sectester-js",
37
- "repeaterVersion": "10.0.0"
36
+ "name": "sectester-js"
38
37
  },
39
38
  "dependencies": {
40
- "axios": "^1.7.7",
41
- "axios-rate-limit": "^1.4.0",
42
39
  "chalk": "^4.1.2",
43
40
  "form-data": "^4.0.0",
44
41
  "reflect-metadata": "^0.2.2",
45
42
  "tslib": "~2.6.3",
46
43
  "tsyringe": "^4.8.0",
47
- "uuid": "^10.0.0"
44
+ "undici-types": "5.26.5"
48
45
  },
49
46
  "types": "./src/index.d.ts",
50
47
  "main": "./src/index.js",
@@ -0,0 +1,7 @@
1
+ import { Project, Projects } from './Projects';
2
+ import { ApiClient } from './api';
3
+ export declare class DefaultProjects implements Projects {
4
+ private readonly client;
5
+ constructor(client: ApiClient);
6
+ getDefaultProject(): Promise<Project>;
7
+ }
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DefaultProjects = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const api_1 = require("./api");
6
+ const tsyringe_1 = require("tsyringe");
7
+ let DefaultProjects = class DefaultProjects {
8
+ constructor(client) {
9
+ this.client = client;
10
+ }
11
+ async getDefaultProject() {
12
+ const filters = new URLSearchParams();
13
+ filters.set('predefined', true.toString());
14
+ const response = await this.client.request(`/api/v2/projects?${filters.toString()}`);
15
+ const { items: [project] } = (await response.json());
16
+ if (!project) {
17
+ throw new Error('No default project found');
18
+ }
19
+ return project;
20
+ }
21
+ };
22
+ exports.DefaultProjects = DefaultProjects;
23
+ exports.DefaultProjects = DefaultProjects = tslib_1.__decorate([
24
+ (0, tsyringe_1.injectable)(),
25
+ tslib_1.__param(0, (0, tsyringe_1.inject)(api_1.ApiClient)),
26
+ tslib_1.__metadata("design:paramtypes", [Object])
27
+ ], DefaultProjects);
28
+ //# sourceMappingURL=DefaultProjects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DefaultProjects.js","sourceRoot":"","sources":["../../../../packages/core/src/DefaultProjects.ts"],"names":[],"mappings":";;;;AACA,+BAAkC;AAClC,uCAA8C;AAGvC,IAAM,eAAe,GAArB,MAAM,eAAe;IAC1B,YAAgD,MAAiB;QAAjB,WAAM,GAAN,MAAM,CAAW;IAAG,CAAC;IAE9D,KAAK,CAAC,iBAAiB;QAC5B,MAAM,OAAO,GAAG,IAAI,eAAe,EAAE,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CACxC,oBAAoB,OAAO,CAAC,QAAQ,EAAE,EAAE,CACzC,CAAC;QACF,MAAM,EACJ,KAAK,EAAE,CAAC,OAAO,CAAC,EACjB,GAAyB,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAyB,CAAC;QAE1E,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF,CAAA;AAnBY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,qBAAU,GAAE;IAEE,mBAAA,IAAA,iBAAM,EAAC,eAAS,CAAC,CAAA;;GADnB,eAAe,CAmB3B"}
@@ -0,0 +1,8 @@
1
+ export interface Project {
2
+ id: string;
3
+ name: string;
4
+ }
5
+ export interface Projects {
6
+ getDefaultProject(): Promise<Project>;
7
+ }
8
+ export declare const Projects: unique symbol;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Projects = void 0;
4
+ exports.Projects = Symbol('Projects');
5
+ //# sourceMappingURL=Projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Projects.js","sourceRoot":"","sources":["../../../../packages/core/src/Projects.ts"],"names":[],"mappings":";;;AASa,QAAA,QAAQ,GAAkB,MAAM,CAAC,UAAU,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ export interface ApiClient {
2
+ request(path: string, options?: RequestInit): Promise<Response>;
3
+ }
4
+ export declare const ApiClient: unique symbol;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ApiClient = void 0;
4
+ exports.ApiClient = Symbol('ApiClient');
5
+ //# sourceMappingURL=ApiClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ApiClient.js","sourceRoot":"","sources":["../../../../../packages/core/src/api/ApiClient.ts"],"names":[],"mappings":";;;AAIa,QAAA,SAAS,GAAkB,MAAM,CAAC,WAAW,CAAC,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { ApiClient } from './ApiClient';
2
+ import { RetryConfig } from './RetryHandler';
3
+ export interface ApiConfig {
4
+ baseUrl: string;
5
+ apiKey: string;
6
+ apiKeyPrefix?: string;
7
+ timeout?: number;
8
+ userAgent?: string;
9
+ retry?: Partial<RetryConfig>;
10
+ }
11
+ export declare class FetchApiClient implements ApiClient {
12
+ private readonly config;
13
+ private static readonly IDEMPOTENT_METHODS;
14
+ private readonly retryHandler;
15
+ private readonly rateLimiter;
16
+ constructor(config: ApiConfig);
17
+ request(path: string, options?: RequestInit): Promise<Response>;
18
+ private makeRequest;
19
+ private handleResponse;
20
+ private createHeaders;
21
+ }
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FetchApiClient = void 0;
4
+ const ApiError_1 = require("../exceptions/ApiError");
5
+ const RateLimitError_1 = require("../exceptions/RateLimitError");
6
+ const RateLimiter_1 = require("./RateLimiter");
7
+ const RetryHandler_1 = require("./RetryHandler");
8
+ const node_util_1 = require("node:util");
9
+ const node_crypto_1 = require("node:crypto");
10
+ class FetchApiClient {
11
+ constructor(config) {
12
+ this.config = config;
13
+ this.rateLimiter = new RateLimiter_1.RateLimiter();
14
+ this.retryHandler = new RetryHandler_1.RetryHandler({
15
+ maxRetries: 3,
16
+ baseDelay: 1000,
17
+ maxDelay: 30000,
18
+ jitterFactor: 0.3,
19
+ ...config.retry
20
+ });
21
+ }
22
+ request(path, options) {
23
+ var _a;
24
+ const url = new URL(path, this.config.baseUrl);
25
+ const requestOptions = {
26
+ redirect: 'follow',
27
+ keepalive: true,
28
+ ...options,
29
+ headers: this.createHeaders(options === null || options === void 0 ? void 0 : options.headers),
30
+ method: ((_a = options === null || options === void 0 ? void 0 : options.method) !== null && _a !== void 0 ? _a : 'GET').toUpperCase()
31
+ };
32
+ const idempotent = FetchApiClient.IDEMPOTENT_METHODS.has(requestOptions.method);
33
+ return this.retryHandler.executeWithRetry(() => this.makeRequest(url, requestOptions), {
34
+ idempotent,
35
+ signal: requestOptions.signal
36
+ });
37
+ }
38
+ async makeRequest(url, options) {
39
+ var _a, _b;
40
+ const signal = (_a = options === null || options === void 0 ? void 0 : options.signal) !== null && _a !== void 0 ? _a : AbortSignal.timeout((_b = this.config.timeout) !== null && _b !== void 0 ? _b : 10000);
41
+ const response = await fetch(url, {
42
+ ...options,
43
+ signal
44
+ });
45
+ return this.handleResponse(response);
46
+ }
47
+ // eslint-disable-next-line complexity
48
+ async handleResponse(response) {
49
+ var _a;
50
+ if (!response.ok) {
51
+ if (response.status === 409 && response.headers.has('location')) {
52
+ const locationPath = response.headers.get('location');
53
+ // eslint-disable-next-line max-depth
54
+ if (locationPath) {
55
+ // Handle both absolute and relative URLs
56
+ const locationUrl = new URL(locationPath, this.config.baseUrl);
57
+ return this.request(locationUrl.toString());
58
+ }
59
+ }
60
+ const rateLimitInfo = this.rateLimiter.extractRateLimitInfo(response);
61
+ const contentType = response.headers.get('content-type');
62
+ const mimeType = contentType ? new node_util_1.MIMEType(contentType) : undefined;
63
+ const responseBody = (mimeType === null || mimeType === void 0 ? void 0 : mimeType.type) === 'text' ? await response.clone().text() : undefined;
64
+ if (response.status === 429) {
65
+ const retryAfter = parseInt((_a = response.headers.get('retry-after')) !== null && _a !== void 0 ? _a : rateLimitInfo.reset.toString(), 10);
66
+ throw new RateLimitError_1.RateLimitError(response, retryAfter, responseBody);
67
+ }
68
+ throw new ApiError_1.ApiError(response, responseBody);
69
+ }
70
+ return response;
71
+ }
72
+ createHeaders(headersInit = {}) {
73
+ var _a;
74
+ const headers = new Headers({
75
+ ...headersInit,
76
+ 'idempotency-key': (0, node_crypto_1.randomUUID)(),
77
+ ...(this.config.userAgent ? { 'user-agent': this.config.userAgent } : {})
78
+ });
79
+ if (this.config.apiKey) {
80
+ const prefix = (_a = this.config.apiKeyPrefix) !== null && _a !== void 0 ? _a : 'Api-Key';
81
+ headers.set('authorization', `${prefix} ${this.config.apiKey}`);
82
+ }
83
+ return headers;
84
+ }
85
+ }
86
+ exports.FetchApiClient = FetchApiClient;
87
+ FetchApiClient.IDEMPOTENT_METHODS = new Set([
88
+ 'GET',
89
+ 'HEAD',
90
+ 'PUT',
91
+ 'DELETE',
92
+ 'OPTIONS',
93
+ 'TRACE'
94
+ ]);
95
+ //# sourceMappingURL=FetchApiClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FetchApiClient.js","sourceRoot":"","sources":["../../../../../packages/core/src/api/FetchApiClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export interface RateLimitPolicy {
2
+ limit: number;
3
+ window: number;
4
+ type: string;
5
+ }
6
+ export interface RateLimitInfo {
7
+ limit: number;
8
+ remaining: number;
9
+ reset: number;
10
+ policy?: RateLimitPolicy;
11
+ }
12
+ export declare class RateLimiter {
13
+ extractRateLimitInfo(response: Response): RateLimitInfo;
14
+ parseRateLimitHeader(header: string | null): Partial<RateLimitInfo>;
15
+ parsePolicyHeader(header: string | null): RateLimitPolicy | undefined;
16
+ }
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RateLimiter = void 0;
4
+ class RateLimiter {
5
+ extractRateLimitInfo(response) {
6
+ var _a, _b, _c;
7
+ const rateLimitHeader = response.headers.get('ratelimit');
8
+ const policyHeader = response.headers.get('ratelimit-policy');
9
+ const rateLimit = this.parseRateLimitHeader(rateLimitHeader);
10
+ const policy = this.parsePolicyHeader(policyHeader);
11
+ return {
12
+ policy,
13
+ limit: (_a = rateLimit.limit) !== null && _a !== void 0 ? _a : 0,
14
+ remaining: (_b = rateLimit.remaining) !== null && _b !== void 0 ? _b : 0,
15
+ reset: (_c = rateLimit.reset) !== null && _c !== void 0 ? _c : 0
16
+ };
17
+ }
18
+ parseRateLimitHeader(header) {
19
+ if (!header)
20
+ return {};
21
+ const parts = header.split(',');
22
+ const result = {};
23
+ parts.forEach(part => {
24
+ const [key, value] = part.split('=');
25
+ switch (key) {
26
+ case 'limit':
27
+ result.limit = parseInt(value, 10);
28
+ break;
29
+ case 'remaining':
30
+ result.remaining = parseInt(value, 10);
31
+ break;
32
+ case 'reset':
33
+ result.reset = parseInt(value, 10);
34
+ break;
35
+ }
36
+ });
37
+ return result;
38
+ }
39
+ parsePolicyHeader(header) {
40
+ if (!header)
41
+ return undefined;
42
+ const parts = header.split(';');
43
+ if (parts.length < 3)
44
+ return undefined;
45
+ const result = {
46
+ limit: 0,
47
+ window: 0,
48
+ type: ''
49
+ };
50
+ const [limit, ...rest] = parts;
51
+ result.limit = parseInt(limit, 10);
52
+ rest.forEach(part => {
53
+ const [key, value] = part
54
+ .split('=', 2)
55
+ .map(s => s.trim());
56
+ switch (key) {
57
+ case 'window':
58
+ result.window = parseInt(value, 10);
59
+ break;
60
+ case 'type':
61
+ result.type = value;
62
+ break;
63
+ }
64
+ });
65
+ if (result.limit && result.window && result.type) {
66
+ return result;
67
+ }
68
+ return undefined;
69
+ }
70
+ }
71
+ exports.RateLimiter = RateLimiter;
72
+ //# sourceMappingURL=RateLimiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RateLimiter.js","sourceRoot":"","sources":["../../../../../packages/core/src/api/RateLimiter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export interface RetryConfig {
2
+ maxRetries: number;
3
+ baseDelay: number;
4
+ maxDelay: number;
5
+ jitterFactor: number;
6
+ }
7
+ export interface RetryOptions {
8
+ idempotent?: boolean;
9
+ signal?: AbortSignal;
10
+ }
11
+ export declare class RetryHandler {
12
+ private readonly config;
13
+ private static readonly RETRIABLE_STATUS_CODES;
14
+ constructor(config: RetryConfig);
15
+ executeWithRetry<T>(operation: () => Promise<T>, options?: RetryOptions): Promise<T>;
16
+ private handleRetryableError;
17
+ private isEligibleForRetry;
18
+ private isRetryableError;
19
+ private isNetworkError;
20
+ private isTimeoutError;
21
+ private calculateBackoff;
22
+ }
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RetryHandler = void 0;
4
+ const ApiError_1 = require("../exceptions/ApiError");
5
+ const RateLimitError_1 = require("../exceptions/RateLimitError");
6
+ const promises_1 = require("node:timers/promises");
7
+ class RetryHandler {
8
+ constructor(config) {
9
+ this.config = config;
10
+ }
11
+ async executeWithRetry(operation, options = {}) {
12
+ const { idempotent = true, signal } = options;
13
+ let attempt = 0;
14
+ for (;;) {
15
+ // Check if the operation has been aborted
16
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
17
+ throw signal.reason;
18
+ }
19
+ try {
20
+ return await operation();
21
+ }
22
+ catch (error) {
23
+ // eslint-disable-next-line max-depth
24
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
25
+ throw error;
26
+ }
27
+ await this.handleRetryableError(error, attempt, idempotent, signal);
28
+ attempt++;
29
+ }
30
+ }
31
+ }
32
+ async handleRetryableError(error, attempt, idempotent, signal) {
33
+ if (attempt >= this.config.maxRetries) {
34
+ throw error;
35
+ }
36
+ if (!this.isEligibleForRetry(error, idempotent)) {
37
+ throw error;
38
+ }
39
+ const delay = error instanceof RateLimitError_1.RateLimitError
40
+ ? error.retryAfter * 1000
41
+ : this.calculateBackoff(attempt);
42
+ await (0, promises_1.setTimeout)(delay, undefined, { signal });
43
+ }
44
+ isEligibleForRetry(error, idempotent) {
45
+ return ((this.isRetryableError(error) && idempotent) ||
46
+ this.isNetworkError(error) ||
47
+ error instanceof RateLimitError_1.RateLimitError);
48
+ }
49
+ isRetryableError(error) {
50
+ // Don't retry if the operation was deliberately aborted
51
+ if (error instanceof DOMException && error.name === 'AbortError') {
52
+ return false;
53
+ }
54
+ return ((error instanceof ApiError_1.ApiError &&
55
+ RetryHandler.RETRIABLE_STATUS_CODES.has(error.response.status)) ||
56
+ this.isTimeoutError(error));
57
+ }
58
+ isNetworkError(error) {
59
+ return (error instanceof TypeError &&
60
+ (error.message.includes('fetch failed') ||
61
+ error.message.includes('terminated')));
62
+ }
63
+ isTimeoutError(error) {
64
+ return error instanceof DOMException && error.name === 'TimeoutError';
65
+ }
66
+ calculateBackoff(attempt) {
67
+ const delay = Math.min(this.config.maxDelay, this.config.baseDelay * Math.pow(2, attempt));
68
+ const jitter = delay * this.config.jitterFactor * Math.random();
69
+ return delay + jitter;
70
+ }
71
+ }
72
+ exports.RetryHandler = RetryHandler;
73
+ RetryHandler.RETRIABLE_STATUS_CODES = new Set([408, 409, 429, 500, 502, 503, 504]);
74
+ //# sourceMappingURL=RetryHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RetryHandler.js","sourceRoot":"","sources":["../../../../../packages/core/src/api/RetryHandler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * from './FetchApiClient';
2
+ export * from './RateLimiter';
3
+ export * from './RetryHandler';
4
+ export * from './ApiClient';
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./FetchApiClient"), exports);
5
+ tslib_1.__exportStar(require("./RateLimiter"), exports);
6
+ tslib_1.__exportStar(require("./RetryHandler"), exports);
7
+ tslib_1.__exportStar(require("./ApiClient"), exports);
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/core/src/api/index.ts"],"names":[],"mappings":";;;AAAA,2DAAiC;AACjC,wDAA8B;AAC9B,yDAA+B;AAC/B,sDAA4B"}