@kontent-ai/core-sdk 10.12.5 → 10.12.6

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.
@@ -1,23 +1,23 @@
1
- import { ISDKInfo } from '../models';
2
-
3
- import { IHeader } from '../http/http.models';
4
-
5
- export class HeaderHelper {
6
-
7
- /**
8
- * Header name for SDK usage
9
- */
10
- private readonly sdkVersionHeader: string = 'X-KC-SDKID';
11
-
12
- /**
13
- * Header identifying SDK type & version for internal purposes of Kontent.ai
14
- */
15
- getSdkIdHeader(info: ISDKInfo): IHeader {
16
- return {
17
- header: this.sdkVersionHeader,
18
- value: `${info.host};${info.name};${info.version}`
19
- };
20
- }
21
- }
22
-
23
- export const headerHelper = new HeaderHelper();
1
+ import { ISDKInfo } from '../models';
2
+
3
+ import { IHeader } from '../http/http.models';
4
+
5
+ export class HeaderHelper {
6
+
7
+ /**
8
+ * Header name for SDK usage
9
+ */
10
+ private readonly sdkVersionHeader: string = 'X-KC-SDKID';
11
+
12
+ /**
13
+ * Header identifying SDK type & version for internal purposes of Kontent.ai
14
+ */
15
+ getSdkIdHeader(info: ISDKInfo): IHeader {
16
+ return {
17
+ header: this.sdkVersionHeader,
18
+ value: `${info.host};${info.name};${info.version}`
19
+ };
20
+ }
21
+ }
22
+
23
+ export const headerHelper = new HeaderHelper();
@@ -1,15 +1,15 @@
1
- import { AxiosResponse } from 'axios';
2
- import { IHeader } from '../http/http.models';
3
-
4
- export function extractHeadersFromAxiosResponse(response: AxiosResponse): IHeader[] {
5
- const headers: IHeader[] = [];
6
-
7
- for (const headerKey of Object.keys(response.headers)) {
8
- headers.push({
9
- header: headerKey,
10
- value: response.headers[headerKey]
11
- });
12
- }
13
-
14
- return headers;
15
- }
1
+ import { AxiosResponse } from 'axios';
2
+ import { IHeader } from '../http/http.models';
3
+
4
+ export function extractHeadersFromAxiosResponse(response: AxiosResponse): IHeader[] {
5
+ const headers: IHeader[] = [];
6
+
7
+ for (const headerKey of Object.keys(response.headers)) {
8
+ headers.push({
9
+ header: headerKey,
10
+ value: response.headers[headerKey]
11
+ });
12
+ }
13
+
14
+ return headers;
15
+ }
@@ -1,4 +1,4 @@
1
- export * from './url.helper';
2
- export * from './header.helper';
3
- export * from './retry-helper';
4
- export * from './headers-helper';
1
+ export * from './url.helper';
2
+ export * from './header.helper';
3
+ export * from './retry-helper';
4
+ export * from './headers-helper';
@@ -1,204 +1,204 @@
1
- import { AxiosError } from 'axios';
2
-
3
- import { extractHeadersFromAxiosResponse } from './headers-helper';
4
- import { IHeader, IRetryStrategyOptions } from '../http/http.models';
5
-
6
- export class RetryHelper {
7
- public readonly requestCancelledMessagePrefix: string = 'Request cancelled';
8
- public readonly retryAfterHeaderName: string = 'Retry-After';
9
- public readonly defaultRetryStatusCodes: number[] = [408, 429, 500, 502, 503, 504];
10
- public readonly defaultRetryStrategy = {
11
- addJitter: true,
12
- deltaBackoffMs: 1000, // 1 sec
13
- maxAttempts: 5,
14
- canRetryError: (error: any) => this.canRetryErrorDefault(error)
15
- };
16
-
17
- getRetryErrorResult(data: {
18
- retryAttempt: number;
19
- error: any;
20
- retryStrategy: IRetryStrategyOptions;
21
- }): {
22
- retryInMs: number;
23
- canRetry: boolean;
24
- maxRetries: number;
25
- } {
26
- if (data.error && data.error.message) {
27
- if ((<string>data.error.message).startsWith(this.requestCancelledMessagePrefix)) {
28
- // request was cancelled by user, do not retry it
29
- return {
30
- canRetry: false,
31
- retryInMs: 0,
32
- maxRetries: 0
33
- };
34
- }
35
- }
36
-
37
- const canRetryError: boolean = data.retryStrategy.canRetryError
38
- ? data.retryStrategy.canRetryError(data.error)
39
- : this.defaultRetryStrategy.canRetryError(data.error);
40
-
41
- if (!canRetryError) {
42
- // request cannot be retried
43
- return {
44
- canRetry: false,
45
- retryInMs: 0,
46
- maxRetries: 0
47
- };
48
- }
49
-
50
- const maxRetries: number = (data.retryStrategy.maxAttempts ?? this.defaultRetryStrategy.maxAttempts);
51
-
52
- const maxRetriesReached: boolean =
53
- data.retryAttempt >= maxRetries;
54
-
55
- if (maxRetriesReached) {
56
- // request cannot be retried anymore due to maximum attempts
57
- return {
58
- canRetry: false,
59
- retryInMs: 0,
60
- maxRetries: maxRetries
61
- };
62
- }
63
- // get wait time
64
- const retryResult: number | undefined = this.tryGetRetryAfterInMsFromError(data.error);
65
-
66
- if (retryResult) {
67
- // retry after header was provided
68
- return {
69
- canRetry: true,
70
- retryInMs: retryResult,
71
- maxRetries: maxRetries
72
- };
73
- }
74
-
75
- // wait time was not provided in header
76
- const waitTimeMs = this.getNextWaitTimeMs(
77
- data.retryStrategy.addJitter ?? this.defaultRetryStrategy.addJitter,
78
- data.retryStrategy.deltaBackoffMs ?? this.defaultRetryStrategy.deltaBackoffMs,
79
- data.retryAttempt
80
- );
81
-
82
- return {
83
- canRetry: true,
84
- retryInMs: waitTimeMs,
85
- maxRetries: maxRetries
86
- };
87
- }
88
-
89
- getRetryStrategyFromStrategyOptions(retryOptions?: IRetryStrategyOptions): IRetryStrategyOptions {
90
- if (!retryOptions) {
91
- return this.defaultRetryStrategy;
92
- }
93
-
94
- return retryOptions;
95
- }
96
-
97
- canRetryInTime(
98
- startTime: Date,
99
- maxCumulativeWaitTimeMs: number
100
- ): {
101
- canRetry: boolean;
102
- differenceInMs: number;
103
- } {
104
- const start = startTime.getTime();
105
- const now = new Date().getTime();
106
-
107
- const differenceInMs = now - start;
108
-
109
- return {
110
- canRetry: differenceInMs < maxCumulativeWaitTimeMs,
111
- differenceInMs: differenceInMs
112
- };
113
- }
114
-
115
- private getNextWaitTimeMs(addJitter: boolean, deltaBackoffMs: number, retryAttempts: number): number {
116
- if (!addJitter) {
117
- return deltaBackoffMs * Math.pow(2, retryAttempts);
118
- }
119
-
120
- const from: number = 0.8 * deltaBackoffMs;
121
- const to: number = 1.2 * deltaBackoffMs * Math.pow(2, retryAttempts);
122
-
123
- return this.randomNumberFromInterval(from, to);
124
- }
125
-
126
- private canRetryErrorDefault(error: any): boolean {
127
- const axiosError = this.tryGetAxiosError(error);
128
-
129
- if (!axiosError) {
130
- // by default non-axios errors are not retried
131
- return false;
132
- }
133
-
134
- const statusCode: number = this.getStatusCodeFromError(error);
135
- const canRetryStatusCode: boolean = this.canRetryStatusCode(statusCode, this.defaultRetryStatusCodes);
136
-
137
- if (canRetryStatusCode) {
138
- return true;
139
- }
140
-
141
- return false;
142
- }
143
-
144
- private tryGetRetryAfterInMsFromError(error: any): number | undefined {
145
- const axiosError = this.tryGetAxiosError(error);
146
-
147
- if (!axiosError || !axiosError.response) {
148
- return undefined;
149
- }
150
-
151
- const headers: IHeader[] = extractHeadersFromAxiosResponse(axiosError.response);
152
-
153
- const retryValueHeader = headers.find(
154
- (m) => m.header.toLowerCase() === this.retryAfterHeaderName.toLowerCase()
155
- );
156
- if (!retryValueHeader) {
157
- return undefined;
158
- }
159
-
160
- const retryInSeconds = +retryValueHeader.value;
161
-
162
- return retryInSeconds * 1000;
163
- }
164
-
165
- private canRetryStatusCode(statusCode: number, useRetryForResponseCodes: number[]): boolean {
166
- return useRetryForResponseCodes.includes(statusCode);
167
- }
168
-
169
- private getStatusCodeFromError(error: any): number {
170
- const axiosError = this.tryGetAxiosError(error);
171
-
172
- if (!axiosError || !axiosError.response) {
173
- return 0;
174
- }
175
-
176
- return axiosError.response.status;
177
- }
178
-
179
- private tryGetAxiosError(error: any): AxiosError | undefined {
180
- if (!error) {
181
- return undefined;
182
- }
183
-
184
- if (error.isAxiosError) {
185
- return error as AxiosError;
186
- }
187
-
188
- const originalError = error.originalError;
189
- if (originalError && originalError.isAxiosError) {
190
- return originalError as AxiosError;
191
- }
192
-
193
- return undefined;
194
- }
195
-
196
- /**
197
- * min and max included
198
- */
199
- private randomNumberFromInterval(min: number, max: number): number {
200
- return Math.floor(Math.random() * (max - min + 1) + min);
201
- }
202
- }
203
-
204
- export const retryHelper = new RetryHelper();
1
+ import { AxiosError } from 'axios';
2
+
3
+ import { extractHeadersFromAxiosResponse } from './headers-helper';
4
+ import { IHeader, IRetryStrategyOptions } from '../http/http.models';
5
+
6
+ export class RetryHelper {
7
+ public readonly requestCancelledMessagePrefix: string = 'Request cancelled';
8
+ public readonly retryAfterHeaderName: string = 'Retry-After';
9
+ public readonly defaultRetryStatusCodes: number[] = [408, 429, 500, 502, 503, 504];
10
+ public readonly defaultRetryStrategy = {
11
+ addJitter: true,
12
+ deltaBackoffMs: 1000, // 1 sec
13
+ maxAttempts: 5,
14
+ canRetryError: (error: any) => this.canRetryErrorDefault(error)
15
+ };
16
+
17
+ getRetryErrorResult(data: {
18
+ retryAttempt: number;
19
+ error: any;
20
+ retryStrategy: IRetryStrategyOptions;
21
+ }): {
22
+ retryInMs: number;
23
+ canRetry: boolean;
24
+ maxRetries: number;
25
+ } {
26
+ if (data.error && data.error.message) {
27
+ if ((<string>data.error.message).startsWith(this.requestCancelledMessagePrefix)) {
28
+ // request was cancelled by user, do not retry it
29
+ return {
30
+ canRetry: false,
31
+ retryInMs: 0,
32
+ maxRetries: 0
33
+ };
34
+ }
35
+ }
36
+
37
+ const canRetryError: boolean = data.retryStrategy.canRetryError
38
+ ? data.retryStrategy.canRetryError(data.error)
39
+ : this.defaultRetryStrategy.canRetryError(data.error);
40
+
41
+ if (!canRetryError) {
42
+ // request cannot be retried
43
+ return {
44
+ canRetry: false,
45
+ retryInMs: 0,
46
+ maxRetries: 0
47
+ };
48
+ }
49
+
50
+ const maxRetries: number = (data.retryStrategy.maxAttempts ?? this.defaultRetryStrategy.maxAttempts);
51
+
52
+ const maxRetriesReached: boolean =
53
+ data.retryAttempt >= maxRetries;
54
+
55
+ if (maxRetriesReached) {
56
+ // request cannot be retried anymore due to maximum attempts
57
+ return {
58
+ canRetry: false,
59
+ retryInMs: 0,
60
+ maxRetries: maxRetries
61
+ };
62
+ }
63
+ // get wait time
64
+ const retryResult: number | undefined = this.tryGetRetryAfterInMsFromError(data.error);
65
+
66
+ if (retryResult) {
67
+ // retry after header was provided
68
+ return {
69
+ canRetry: true,
70
+ retryInMs: retryResult,
71
+ maxRetries: maxRetries
72
+ };
73
+ }
74
+
75
+ // wait time was not provided in header
76
+ const waitTimeMs = this.getNextWaitTimeMs(
77
+ data.retryStrategy.addJitter ?? this.defaultRetryStrategy.addJitter,
78
+ data.retryStrategy.deltaBackoffMs ?? this.defaultRetryStrategy.deltaBackoffMs,
79
+ data.retryAttempt
80
+ );
81
+
82
+ return {
83
+ canRetry: true,
84
+ retryInMs: waitTimeMs,
85
+ maxRetries: maxRetries
86
+ };
87
+ }
88
+
89
+ getRetryStrategyFromStrategyOptions(retryOptions?: IRetryStrategyOptions): IRetryStrategyOptions {
90
+ if (!retryOptions) {
91
+ return this.defaultRetryStrategy;
92
+ }
93
+
94
+ return retryOptions;
95
+ }
96
+
97
+ canRetryInTime(
98
+ startTime: Date,
99
+ maxCumulativeWaitTimeMs: number
100
+ ): {
101
+ canRetry: boolean;
102
+ differenceInMs: number;
103
+ } {
104
+ const start = startTime.getTime();
105
+ const now = new Date().getTime();
106
+
107
+ const differenceInMs = now - start;
108
+
109
+ return {
110
+ canRetry: differenceInMs < maxCumulativeWaitTimeMs,
111
+ differenceInMs: differenceInMs
112
+ };
113
+ }
114
+
115
+ private getNextWaitTimeMs(addJitter: boolean, deltaBackoffMs: number, retryAttempts: number): number {
116
+ if (!addJitter) {
117
+ return deltaBackoffMs * Math.pow(2, retryAttempts);
118
+ }
119
+
120
+ const from: number = 0.8 * deltaBackoffMs;
121
+ const to: number = 1.2 * deltaBackoffMs * Math.pow(2, retryAttempts);
122
+
123
+ return this.randomNumberFromInterval(from, to);
124
+ }
125
+
126
+ private canRetryErrorDefault(error: any): boolean {
127
+ const axiosError = this.tryGetAxiosError(error);
128
+
129
+ if (!axiosError) {
130
+ // by default non-axios errors are not retried
131
+ return false;
132
+ }
133
+
134
+ const statusCode: number = this.getStatusCodeFromError(error);
135
+ const canRetryStatusCode: boolean = this.canRetryStatusCode(statusCode, this.defaultRetryStatusCodes);
136
+
137
+ if (canRetryStatusCode) {
138
+ return true;
139
+ }
140
+
141
+ return false;
142
+ }
143
+
144
+ private tryGetRetryAfterInMsFromError(error: any): number | undefined {
145
+ const axiosError = this.tryGetAxiosError(error);
146
+
147
+ if (!axiosError || !axiosError.response) {
148
+ return undefined;
149
+ }
150
+
151
+ const headers: IHeader[] = extractHeadersFromAxiosResponse(axiosError.response);
152
+
153
+ const retryValueHeader = headers.find(
154
+ (m) => m.header.toLowerCase() === this.retryAfterHeaderName.toLowerCase()
155
+ );
156
+ if (!retryValueHeader) {
157
+ return undefined;
158
+ }
159
+
160
+ const retryInSeconds = +retryValueHeader.value;
161
+
162
+ return retryInSeconds * 1000;
163
+ }
164
+
165
+ private canRetryStatusCode(statusCode: number, useRetryForResponseCodes: number[]): boolean {
166
+ return useRetryForResponseCodes.includes(statusCode);
167
+ }
168
+
169
+ private getStatusCodeFromError(error: any): number {
170
+ const axiosError = this.tryGetAxiosError(error);
171
+
172
+ if (!axiosError || !axiosError.response) {
173
+ return 0;
174
+ }
175
+
176
+ return axiosError.response.status;
177
+ }
178
+
179
+ private tryGetAxiosError(error: any): AxiosError | undefined {
180
+ if (!error) {
181
+ return undefined;
182
+ }
183
+
184
+ if (error.isAxiosError) {
185
+ return error as AxiosError;
186
+ }
187
+
188
+ const originalError = error.originalError;
189
+ if (originalError && originalError.isAxiosError) {
190
+ return originalError as AxiosError;
191
+ }
192
+
193
+ return undefined;
194
+ }
195
+
196
+ /**
197
+ * min and max included
198
+ */
199
+ private randomNumberFromInterval(min: number, max: number): number {
200
+ return Math.floor(Math.random() * (max - min + 1) + min);
201
+ }
202
+ }
203
+
204
+ export const retryHelper = new RetryHelper();
@@ -1,26 +1,26 @@
1
- import { IQueryParameter } from '../models';
2
-
3
- export class UrlHelper {
4
-
5
- /**
6
- * Adds query parameters to given url
7
- * @param url Url to which options will be added
8
- * @param options Query parameters to add
9
- */
10
- addOptionsToUrl(url: string, options?: IQueryParameter[]): string {
11
- if (options) {
12
- options.forEach(filter => {
13
- if (url.indexOf('?') > -1) {
14
- url += '&';
15
- } else {
16
- url += '?';
17
- }
18
-
19
- url += filter.getParam();
20
- });
21
- }
22
- return url;
23
- }
24
- }
25
-
26
- export const urlHelper = new UrlHelper();
1
+ import { IQueryParameter } from '../models';
2
+
3
+ export class UrlHelper {
4
+
5
+ /**
6
+ * Adds query parameters to given url
7
+ * @param url Url to which options will be added
8
+ * @param options Query parameters to add
9
+ */
10
+ addOptionsToUrl(url: string, options?: IQueryParameter[]): string {
11
+ if (options) {
12
+ options.forEach(filter => {
13
+ if (url.indexOf('?') > -1) {
14
+ url += '&';
15
+ } else {
16
+ url += '?';
17
+ }
18
+
19
+ url += filter.getParam();
20
+ });
21
+ }
22
+ return url;
23
+ }
24
+ }
25
+
26
+ export const urlHelper = new UrlHelper();
@@ -1,21 +1,21 @@
1
- export class HttpDebugger {
2
- /*
3
- Called when http request is started
4
- */
5
- debugStartHttpRequest(): void {
6
- }
7
-
8
- /*
9
- Called when http request is resolved
10
- */
11
- debugSuccessHttpRequest(): void {
12
- }
13
-
14
- /*
15
- Called when http request is being retried
16
- */
17
- debugRetryHttpRequest(): void {
18
- }
19
- }
20
-
21
- export const httpDebugger = new HttpDebugger();
1
+ export class HttpDebugger {
2
+ /*
3
+ Called when http request is started
4
+ */
5
+ debugStartHttpRequest(): void {
6
+ }
7
+
8
+ /*
9
+ Called when http request is resolved
10
+ */
11
+ debugSuccessHttpRequest(): void {
12
+ }
13
+
14
+ /*
15
+ Called when http request is being retried
16
+ */
17
+ debugRetryHttpRequest(): void {
18
+ }
19
+ }
20
+
21
+ export const httpDebugger = new HttpDebugger();